Exemplo n.º 1
0
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;
    }
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
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);
}