void rt2x00usb_kick_queue(struct data_queue *queue) { switch (queue->qid) { case QID_AC_VO: case QID_AC_VI: case QID_AC_BE: case QID_AC_BK: if (!rt2x00queue_empty(queue)) rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL, rt2x00usb_kick_tx_entry); break; case QID_RX: if (!rt2x00queue_full(queue)) rt2x00queue_for_each_entry(queue, Q_INDEX, Q_INDEX_DONE, NULL, rt2x00usb_kick_rx_entry); break; default: break; } }
int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, struct data_queue *queue, struct sk_buff *skb, struct ieee80211_tx_control *control) { struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); struct queue_entry_priv_usb_tx *priv_tx = entry->priv_data; struct skb_frame_desc *skbdesc; u32 length; if (rt2x00queue_full(queue)) return -EINVAL; if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { ERROR(rt2x00dev, "Arrived at non-free entry in the non-full queue %d.\n" "Please file bug report to %s.\n", control->queue, DRV_PROJECT); return -EINVAL; } /* * Add the descriptor in front of the skb. */ skb_push(skb, queue->desc_size); memset(skb->data, 0, queue->desc_size); /* * Fill in skb descriptor */ skbdesc = get_skb_frame_desc(skb); skbdesc->data = skb->data + queue->desc_size; skbdesc->data_len = skb->len - queue->desc_size; skbdesc->desc = skb->data; skbdesc->desc_len = queue->desc_size; skbdesc->entry = entry; memcpy(&priv_tx->control, control, sizeof(priv_tx->control)); rt2x00lib_write_tx_desc(rt2x00dev, skb, control); /* * USB devices cannot blindly pass the skb->len as the * length of the data to usb_fill_bulk_urb. Pass the skb * to the driver to determine what the length should be. */ length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, skb); /* * Initialize URB and send the frame to the device. */ __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); usb_fill_bulk_urb(priv_tx->urb, usb_dev, usb_sndbulkpipe(usb_dev, 1), skb->data, length, rt2x00usb_interrupt_txdone, entry); usb_submit_urb(priv_tx->urb, GFP_ATOMIC); rt2x00queue_index_inc(queue, Q_INDEX); return 0; }
/* * TX data handlers. */ static void rt2x00usb_interrupt_txdone(struct urb *urb) { struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct queue_entry_priv_usb_tx *priv_tx = entry->priv_data; struct txdone_entry_desc txdesc; __le32 *txd = (__le32 *)entry->skb->data; u32 word; if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; rt2x00_desc_read(txd, 0, &word); /* * Remove the descriptor data from the buffer. */ skb_pull(entry->skb, entry->queue->desc_size); /* * Obtain the status about this packet. */ txdesc.status = !urb->status ? TX_SUCCESS : TX_FAIL_RETRY; txdesc.retry = 0; txdesc.control = &priv_tx->control; rt2x00lib_txdone(entry, &txdesc); /* * Make this entry available for reuse. */ entry->flags = 0; rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); /* * If the data queue was full before the txdone handler * we must make sure the packet queue in the mac80211 stack * is reenabled when the txdone handler has finished. */ if (!rt2x00queue_full(entry->queue)) ieee80211_wake_queue(rt2x00dev->hw, priv_tx->control.queue); }