diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2010-08-06 20:45:38 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-08-16 15:26:41 -0400 |
commit | 7e613e1666d59b5364f7918b3427bf328ac5f9ca (patch) | |
tree | 147a7175901e86129dbe442095816da0f8eb7969 /drivers/net/wireless/rt2x00/rt2x00dev.c | |
parent | c17512d846a4b063c8d3e708d82c0664d9c7182e (diff) | |
download | blackbird-op-linux-7e613e1666d59b5364f7918b3427bf328ac5f9ca.tar.gz blackbird-op-linux-7e613e1666d59b5364f7918b3427bf328ac5f9ca.zip |
rt2x00: Move USB tx/rx done handling to workqueue
Move all TX and RX completion handling into a work structure,
which is handeled on the mac80211 workqueue. This simplifies
the code in rt2x00lib since it no longer needs to check if the
device is USB or PCI to decide which mac80211 function should be used.
In the watchdog some changes are needed since it can no longer rely
on the TX completion function to be run while looping through the
entries. (Both functions now work on the same workqueue, so this
would deadlock). So the watchdog now waits for the URB to return,
and handle the TX status report directly.
As a side-effect, the debugfs entry for the RX queue now correctly
displays the positions of the INDEX and INDEX_DONE counters. This
also implies that it is not possible to perform checks like queue_empty()
and queue_full() on the RX queue.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00dev.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 35 |
1 files changed, 12 insertions, 23 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 585e8166f22a..94621bd4fb9b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1,5 +1,6 @@ /* - Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> + Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> + Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com> <http://rt2x00.serialmonkey.com> This program is free software; you can redistribute it and/or modify @@ -383,15 +384,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, * send the status report back. */ if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) - /* - * Only PCI and SOC devices process the tx status in process - * context. Hence use ieee80211_tx_status for PCI and SOC - * devices and stick to ieee80211_tx_status_irqsafe for USB. - */ - if (rt2x00_is_usb(rt2x00dev)) - ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); - else - ieee80211_tx_status(rt2x00dev->hw, entry->skb); + ieee80211_tx_status(rt2x00dev->hw, entry->skb); else dev_kfree_skb_any(entry->skb); @@ -403,7 +396,6 @@ void rt2x00lib_txdone(struct queue_entry *entry, rt2x00dev->ops->lib->clear_entry(entry); - clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); /* @@ -463,6 +455,10 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; unsigned int header_length; int rate_idx; + + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + goto submit_entry; + /* * Allocate a new sk_buffer. If no new buffer available, drop the * received frame and reuse the existing buffer. @@ -540,26 +536,17 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, */ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status)); - - /* - * Currently only PCI and SOC devices handle rx interrupts in process - * context. Hence, use ieee80211_rx_irqsafe for USB and ieee80211_rx_ni - * for PCI and SOC devices. - */ - if (rt2x00_is_usb(rt2x00dev)) - ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb); - else - ieee80211_rx_ni(rt2x00dev->hw, entry->skb); + ieee80211_rx_ni(rt2x00dev->hw, entry->skb); /* * Replace the skb with the freshly allocated one. */ entry->skb = skb; - entry->flags = 0; +submit_entry: rt2x00dev->ops->lib->clear_entry(entry); - rt2x00queue_index_inc(entry->queue, Q_INDEX); + rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); } EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); @@ -1017,6 +1004,8 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) * Stop all work. */ cancel_work_sync(&rt2x00dev->intf_work); + cancel_work_sync(&rt2x00dev->rxdone_work); + cancel_work_sync(&rt2x00dev->txdone_work); /* * Uninitialize device. |