static int __mt7601u_dma_fw(struct mt7601u_dev *dev, const struct mt7601u_dma_buf *dma_buf, const void *data, u32 len, u32 dst_addr) { DECLARE_COMPLETION_ONSTACK(cmpl); struct mt7601u_dma_buf buf = *dma_buf; /* we need to fake length */ __le32 reg; u32 val; int ret; reg = cpu_to_le32(MT76_SET(MT_TXD_INFO_TYPE, DMA_PACKET) | MT76_SET(MT_TXD_INFO_D_PORT, CPU_TX_PORT) | MT76_SET(MT_TXD_INFO_LEN, len)); memcpy(buf.buf, ®, sizeof(reg)); memcpy(buf.buf + sizeof(reg), data, len); memset(buf.buf + sizeof(reg) + len, 0, 8); ret = mt7601u_vendor_single_wr(dev, MT_VEND_WRITE_FCE, MT_FCE_DMA_ADDR, dst_addr); if (ret) return ret; len = roundup(len, 4); ret = mt7601u_vendor_single_wr(dev, MT_VEND_WRITE_FCE, MT_FCE_DMA_LEN, len << 16); if (ret) return ret; buf.len = MT_DMA_HDR_LEN + len + 4; ret = mt7601u_usb_submit_buf(dev, USB_DIR_OUT, MT_EP_OUT_INBAND_CMD, &buf, GFP_KERNEL, mt7601u_complete_urb, &cmpl); if (ret) return ret; if (!wait_for_completion_timeout(&cmpl, msecs_to_jiffies(1000))) { dev_err(dev->dev, "Error: firmware upload timed out\n"); usb_kill_urb(buf.urb); return -ETIMEDOUT; } if (mt7601u_urb_has_error(buf.urb)) { dev_err(dev->dev, "Error: firmware upload urb failed:%d\n", buf.urb->status); return buf.urb->status; } val = mt7601u_rr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX); val++; mt7601u_wr(dev, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX, val); return 0; }
void mt7601u_wr(struct mt7601u_dev *dev, u32 offset, u32 val) { WARN_ONCE(offset > USHRT_MAX, "write high off:%08x", offset); mt7601u_vendor_single_wr(dev, MT_VEND_WRITE, offset, val); trace_reg_write(dev, offset, val); }