int mt7601u_usb_submit_buf(struct mt7601u_dev *dev, int dir, int ep_idx, struct mt7601u_dma_buf *buf, gfp_t gfp, usb_complete_t complete_fn, void *context) { struct usb_device *usb_dev = mt7601u_to_usb_dev(dev); unsigned pipe; int ret; if (dir == USB_DIR_IN) pipe = usb_rcvbulkpipe(usb_dev, dev->in_eps[ep_idx]); else pipe = usb_sndbulkpipe(usb_dev, dev->out_eps[ep_idx]); usb_fill_bulk_urb(buf->urb, usb_dev, pipe, buf->buf, buf->len, complete_fn, context); buf->urb->transfer_dma = buf->dma; buf->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; trace_mt_submit_urb(dev, buf->urb); ret = usb_submit_urb(buf->urb, gfp); if (ret) dev_err(dev->dev, "Error: submit URB dir:%d ep:%d failed:%d\n", dir, ep_idx, ret); return ret; }
static int __mt7601u_vendor_request(struct mt7601u_dev *dev, const u8 req, const u8 direction, const u16 val, const u16 offset, void *buf, const size_t buflen) { int i, ret; struct usb_device *usb_dev = mt7601u_to_usb_dev(dev); const u8 req_type = direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE; const unsigned int pipe = (direction == USB_DIR_IN) ? usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0); for (i = 0; i < MT_VEND_REQ_MAX_RETRY; i++) { ret = usb_control_msg(usb_dev, pipe, req, req_type, val, offset, buf, buflen, MT_VEND_REQ_TOUT_MS); trace_mt_vend_req(dev, pipe, req, req_type, val, offset, buf, buflen, ret); if (ret >= 0 || ret == -ENODEV) return ret; msleep(5); } dev_err(dev->dev, "Vendor request req:%02x off:x%04x failed:%d\n", req, offset, ret); return ret; }
void mt7601u_usb_free_buf(struct mt7601u_dev *dev, struct mt7601u_dma_buf *buf) { struct usb_device *usb_dev = mt7601u_to_usb_dev(dev); usb_free_coherent(usb_dev, buf->len, buf->buf, buf->dma); usb_free_urb(buf->urb); }
bool mt7601u_usb_alloc_buf(struct mt7601u_dev *dev, size_t len, struct mt7601u_dma_buf *buf) { struct usb_device *usb_dev = mt7601u_to_usb_dev(dev); buf->len = len; buf->urb = usb_alloc_urb(0, GFP_KERNEL); buf->buf = usb_alloc_coherent(usb_dev, buf->len, GFP_KERNEL, &buf->dma); return !buf->urb || !buf->buf; }
static int mt7601u_dma_submit_tx(struct mt7601u_dev *dev, struct sk_buff *skb, u8 ep) { struct usb_device *usb_dev = mt7601u_to_usb_dev(dev); unsigned snd_pipe = usb_sndbulkpipe(usb_dev, dev->out_eps[ep]); struct mt7601u_dma_buf_tx *e; struct mt7601u_tx_queue *q = &dev->tx_q[ep]; unsigned long flags; int ret; spin_lock_irqsave(&dev->tx_lock, flags); if (WARN_ON(q->entries <= q->used)) { ret = -ENOSPC; goto out; } e = &q->e[q->end]; e->skb = skb; usb_fill_bulk_urb(e->urb, usb_dev, snd_pipe, skb->data, skb->len, mt7601u_complete_tx, q); ret = usb_submit_urb(e->urb, GFP_ATOMIC); if (ret) { /* Special-handle ENODEV from TX urb submission because it will * often be the first ENODEV we see after device is removed. */ if (ret == -ENODEV) set_bit(MT7601U_STATE_REMOVED, &dev->state); else dev_err(dev->dev, "Error: TX urb submit failed:%d\n", ret); goto out; } q->end = (q->end + 1) % q->entries; q->used++; if (q->used >= q->entries) ieee80211_stop_queue(dev->hw, skb_get_queue_mapping(skb)); out: spin_unlock_irqrestore(&dev->tx_lock, flags); return ret; }
static int mt7601u_mcu_msg_send(struct mt7601u_dev *dev, struct sk_buff *skb, enum mcu_cmd cmd, bool wait_resp) { struct usb_device *usb_dev = mt7601u_to_usb_dev(dev); unsigned cmd_pipe = usb_sndbulkpipe(usb_dev, dev->out_eps[MT_EP_OUT_INBAND_CMD]); int sent, ret; u8 seq = 0; if (test_bit(MT7601U_STATE_REMOVED, &dev->state)) return 0; mutex_lock(&dev->mcu.mutex); if (wait_resp) while (!seq) seq = ++dev->mcu.msg_seq & 0xf; mt7601u_dma_skb_wrap_cmd(skb, seq, cmd); if (dev->mcu.resp_cmpl.done) dev_err(dev->dev, "Error: MCU response pre-completed!\n"); trace_mt_mcu_msg_send_cs(dev, skb, wait_resp); trace_mt_submit_urb_sync(dev, cmd_pipe, skb->len); ret = usb_bulk_msg(usb_dev, cmd_pipe, skb->data, skb->len, &sent, 500); if (ret) { dev_err(dev->dev, "Error: send MCU cmd failed:%d\n", ret); goto out; } if (sent != skb->len) dev_err(dev->dev, "Error: %s sent != skb->len\n", __func__); if (wait_resp) ret = mt7601u_mcu_wait_resp(dev, seq); out: mutex_unlock(&dev->mcu.mutex); consume_skb(skb); return ret; }
static int mt7601u_submit_rx_buf(struct mt7601u_dev *dev, struct mt7601u_dma_buf_rx *e, gfp_t gfp) { struct usb_device *usb_dev = mt7601u_to_usb_dev(dev); u8 *buf = page_address(e->p); unsigned pipe; int ret; pipe = usb_rcvbulkpipe(usb_dev, dev->in_eps[MT_EP_IN_PKT_RX]); usb_fill_bulk_urb(e->urb, usb_dev, pipe, buf, MT_RX_URB_SIZE, mt7601u_complete_rx, dev); trace_mt_submit_urb(dev, e->urb); ret = usb_submit_urb(e->urb, gfp); if (ret) dev_err(dev->dev, "Error: submit RX URB failed:%d\n", ret); return ret; }