diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-07-08 11:03:36 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-07-08 11:03:36 -0400 |
commit | 204d1641d200709c759d8c269458cbc7de378c40 (patch) | |
tree | ce88690b4422078883f1651537ccd1f5d8ed7258 /drivers/net/wireless/rt2x00 | |
parent | 31817df025e24559a01d33ddd68bd11b21bf9d7b (diff) | |
parent | 5f0dd296a01c8173fcc05a8b262a1168ae90bc74 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800pci.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00crypto.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00lib.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 14 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 108 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 1 |
13 files changed, 94 insertions, 52 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 937f9e8bf05f..76bcc3547976 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1723,6 +1723,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { | |||
1723 | .set_antenna = rt2x00mac_set_antenna, | 1723 | .set_antenna = rt2x00mac_set_antenna, |
1724 | .get_antenna = rt2x00mac_get_antenna, | 1724 | .get_antenna = rt2x00mac_get_antenna, |
1725 | .get_ringparam = rt2x00mac_get_ringparam, | 1725 | .get_ringparam = rt2x00mac_get_ringparam, |
1726 | .tx_frames_pending = rt2x00mac_tx_frames_pending, | ||
1726 | }; | 1727 | }; |
1727 | 1728 | ||
1728 | static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | 1729 | static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index d27d7b8ba3b6..c288d951c034 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -2016,6 +2016,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { | |||
2016 | .set_antenna = rt2x00mac_set_antenna, | 2016 | .set_antenna = rt2x00mac_set_antenna, |
2017 | .get_antenna = rt2x00mac_get_antenna, | 2017 | .get_antenna = rt2x00mac_get_antenna, |
2018 | .get_ringparam = rt2x00mac_get_ringparam, | 2018 | .get_ringparam = rt2x00mac_get_ringparam, |
2019 | .tx_frames_pending = rt2x00mac_tx_frames_pending, | ||
2019 | }; | 2020 | }; |
2020 | 2021 | ||
2021 | static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | 2022 | static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 15237c275486..53c5f878f61d 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1827,6 +1827,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { | |||
1827 | .set_antenna = rt2x00mac_set_antenna, | 1827 | .set_antenna = rt2x00mac_set_antenna, |
1828 | .get_antenna = rt2x00mac_get_antenna, | 1828 | .get_antenna = rt2x00mac_get_antenna, |
1829 | .get_ringparam = rt2x00mac_get_ringparam, | 1829 | .get_ringparam = rt2x00mac_get_ringparam, |
1830 | .tx_frames_pending = rt2x00mac_tx_frames_pending, | ||
1830 | }; | 1831 | }; |
1831 | 1832 | ||
1832 | static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | 1833 | static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 9ccc53733bae..ebc17ad61dec 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -1031,6 +1031,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = { | |||
1031 | .flush = rt2x00mac_flush, | 1031 | .flush = rt2x00mac_flush, |
1032 | .get_survey = rt2800_get_survey, | 1032 | .get_survey = rt2800_get_survey, |
1033 | .get_ringparam = rt2x00mac_get_ringparam, | 1033 | .get_ringparam = rt2x00mac_get_ringparam, |
1034 | .tx_frames_pending = rt2x00mac_tx_frames_pending, | ||
1034 | }; | 1035 | }; |
1035 | 1036 | ||
1036 | static const struct rt2800_ops rt2800pci_rt2800_ops = { | 1037 | static const struct rt2800_ops rt2800pci_rt2800_ops = { |
@@ -1160,6 +1161,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { | |||
1160 | #endif | 1161 | #endif |
1161 | #ifdef CONFIG_RT2800PCI_RT53XX | 1162 | #ifdef CONFIG_RT2800PCI_RT53XX |
1162 | { PCI_DEVICE(0x1814, 0x5390) }, | 1163 | { PCI_DEVICE(0x1814, 0x5390) }, |
1164 | { PCI_DEVICE(0x1814, 0x539f) }, | ||
1163 | #endif | 1165 | #endif |
1164 | { 0, } | 1166 | { 0, } |
1165 | }; | 1167 | }; |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6e9229830a29..59e77797c0fa 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -757,6 +757,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = { | |||
757 | .flush = rt2x00mac_flush, | 757 | .flush = rt2x00mac_flush, |
758 | .get_survey = rt2800_get_survey, | 758 | .get_survey = rt2800_get_survey, |
759 | .get_ringparam = rt2x00mac_get_ringparam, | 759 | .get_ringparam = rt2x00mac_get_ringparam, |
760 | .tx_frames_pending = rt2x00mac_tx_frames_pending, | ||
760 | }; | 761 | }; |
761 | 762 | ||
762 | static const struct rt2800_ops rt2800usb_rt2800_ops = { | 763 | static const struct rt2800_ops rt2800usb_rt2800_ops = { |
@@ -1020,6 +1021,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1020 | { USB_DEVICE(0x0df6, 0x0048) }, | 1021 | { USB_DEVICE(0x0df6, 0x0048) }, |
1021 | { USB_DEVICE(0x0df6, 0x0051) }, | 1022 | { USB_DEVICE(0x0df6, 0x0051) }, |
1022 | { USB_DEVICE(0x0df6, 0x005f) }, | 1023 | { USB_DEVICE(0x0df6, 0x005f) }, |
1024 | { USB_DEVICE(0x0df6, 0x0060) }, | ||
1023 | /* SMC */ | 1025 | /* SMC */ |
1024 | { USB_DEVICE(0x083a, 0x6618) }, | 1026 | { USB_DEVICE(0x083a, 0x6618) }, |
1025 | { USB_DEVICE(0x083a, 0x7511) }, | 1027 | { USB_DEVICE(0x083a, 0x7511) }, |
@@ -1076,6 +1078,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1076 | { USB_DEVICE(0x148f, 0x3572) }, | 1078 | { USB_DEVICE(0x148f, 0x3572) }, |
1077 | /* Sitecom */ | 1079 | /* Sitecom */ |
1078 | { USB_DEVICE(0x0df6, 0x0041) }, | 1080 | { USB_DEVICE(0x0df6, 0x0041) }, |
1081 | { USB_DEVICE(0x0df6, 0x0062) }, | ||
1079 | /* Toshiba */ | 1082 | /* Toshiba */ |
1080 | { USB_DEVICE(0x0930, 0x0a07) }, | 1083 | { USB_DEVICE(0x0930, 0x0a07) }, |
1081 | /* Zinwell */ | 1084 | /* Zinwell */ |
@@ -1174,8 +1177,6 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1174 | { USB_DEVICE(0x0df6, 0x004a) }, | 1177 | { USB_DEVICE(0x0df6, 0x004a) }, |
1175 | { USB_DEVICE(0x0df6, 0x004d) }, | 1178 | { USB_DEVICE(0x0df6, 0x004d) }, |
1176 | { USB_DEVICE(0x0df6, 0x0053) }, | 1179 | { USB_DEVICE(0x0df6, 0x0053) }, |
1177 | { USB_DEVICE(0x0df6, 0x0060) }, | ||
1178 | { USB_DEVICE(0x0df6, 0x0062) }, | ||
1179 | /* SMC */ | 1180 | /* SMC */ |
1180 | { USB_DEVICE(0x083a, 0xa512) }, | 1181 | { USB_DEVICE(0x083a, 0xa512) }, |
1181 | { USB_DEVICE(0x083a, 0xc522) }, | 1182 | { USB_DEVICE(0x083a, 0xc522) }, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 4efaf886fb89..f82bfeb79ebb 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -1277,6 +1277,7 @@ int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); | |||
1277 | int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); | 1277 | int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); |
1278 | void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, | 1278 | void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, |
1279 | u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); | 1279 | u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); |
1280 | bool rt2x00mac_tx_frames_pending(struct ieee80211_hw *hw); | ||
1280 | 1281 | ||
1281 | /* | 1282 | /* |
1282 | * Driver allocation handlers. | 1283 | * Driver allocation handlers. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index 1bb9d46077ff..1ca4c7ffc189 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c | |||
@@ -45,11 +45,11 @@ enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key) | |||
45 | } | 45 | } |
46 | } | 46 | } |
47 | 47 | ||
48 | void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | 48 | void rt2x00crypto_create_tx_descriptor(struct rt2x00_dev *rt2x00dev, |
49 | struct sk_buff *skb, | ||
49 | struct txentry_desc *txdesc) | 50 | struct txentry_desc *txdesc) |
50 | { | 51 | { |
51 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 52 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
52 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | ||
53 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; | 53 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; |
54 | 54 | ||
55 | if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags) || !hw_key) | 55 | if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags) || !hw_key) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 322cc4f3de5d..15cdc7e57fc4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -336,7 +336,8 @@ static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, | |||
336 | */ | 336 | */ |
337 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | 337 | #ifdef CONFIG_RT2X00_LIB_CRYPTO |
338 | enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key); | 338 | enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key); |
339 | void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | 339 | void rt2x00crypto_create_tx_descriptor(struct rt2x00_dev *rt2x00dev, |
340 | struct sk_buff *skb, | ||
340 | struct txentry_desc *txdesc); | 341 | struct txentry_desc *txdesc); |
341 | unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, | 342 | unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, |
342 | struct sk_buff *skb); | 343 | struct sk_buff *skb); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 93bec140e598..8efab3983528 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -818,3 +818,17 @@ void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, | |||
818 | *rx_max = rt2x00dev->rx->limit; | 818 | *rx_max = rt2x00dev->rx->limit; |
819 | } | 819 | } |
820 | EXPORT_SYMBOL_GPL(rt2x00mac_get_ringparam); | 820 | EXPORT_SYMBOL_GPL(rt2x00mac_get_ringparam); |
821 | |||
822 | bool rt2x00mac_tx_frames_pending(struct ieee80211_hw *hw) | ||
823 | { | ||
824 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
825 | struct data_queue *queue; | ||
826 | |||
827 | tx_queue_for_each(rt2x00dev, queue) { | ||
828 | if (!rt2x00queue_empty(queue)) | ||
829 | return true; | ||
830 | } | ||
831 | |||
832 | return false; | ||
833 | } | ||
834 | EXPORT_SYMBOL_GPL(rt2x00mac_tx_frames_pending); | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index c7fc9def6bcf..29edb9fbe6f1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -200,11 +200,12 @@ void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) | |||
200 | skb_pull(skb, l2pad); | 200 | skb_pull(skb, l2pad); |
201 | } | 201 | } |
202 | 202 | ||
203 | static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, | 203 | static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev, |
204 | struct sk_buff *skb, | ||
204 | struct txentry_desc *txdesc) | 205 | struct txentry_desc *txdesc) |
205 | { | 206 | { |
206 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 207 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
207 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | 208 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
208 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | 209 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); |
209 | 210 | ||
210 | if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) | 211 | if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) |
@@ -212,7 +213,7 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, | |||
212 | 213 | ||
213 | __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); | 214 | __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); |
214 | 215 | ||
215 | if (!test_bit(REQUIRE_SW_SEQNO, &entry->queue->rt2x00dev->cap_flags)) | 216 | if (!test_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags)) |
216 | return; | 217 | return; |
217 | 218 | ||
218 | /* | 219 | /* |
@@ -237,12 +238,12 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, | |||
237 | 238 | ||
238 | } | 239 | } |
239 | 240 | ||
240 | static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, | 241 | static void rt2x00queue_create_tx_descriptor_plcp(struct rt2x00_dev *rt2x00dev, |
242 | struct sk_buff *skb, | ||
241 | struct txentry_desc *txdesc, | 243 | struct txentry_desc *txdesc, |
242 | const struct rt2x00_rate *hwrate) | 244 | const struct rt2x00_rate *hwrate) |
243 | { | 245 | { |
244 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 246 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
245 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | ||
246 | struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; | 247 | struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; |
247 | unsigned int data_length; | 248 | unsigned int data_length; |
248 | unsigned int duration; | 249 | unsigned int duration; |
@@ -259,8 +260,8 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, | |||
259 | txdesc->u.plcp.ifs = IFS_SIFS; | 260 | txdesc->u.plcp.ifs = IFS_SIFS; |
260 | 261 | ||
261 | /* Data length + CRC + Crypto overhead (IV/EIV/ICV/MIC) */ | 262 | /* Data length + CRC + Crypto overhead (IV/EIV/ICV/MIC) */ |
262 | data_length = entry->skb->len + 4; | 263 | data_length = skb->len + 4; |
263 | data_length += rt2x00crypto_tx_overhead(rt2x00dev, entry->skb); | 264 | data_length += rt2x00crypto_tx_overhead(rt2x00dev, skb); |
264 | 265 | ||
265 | /* | 266 | /* |
266 | * PLCP setup | 267 | * PLCP setup |
@@ -301,13 +302,14 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, | |||
301 | } | 302 | } |
302 | } | 303 | } |
303 | 304 | ||
304 | static void rt2x00queue_create_tx_descriptor_ht(struct queue_entry *entry, | 305 | static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev, |
306 | struct sk_buff *skb, | ||
305 | struct txentry_desc *txdesc, | 307 | struct txentry_desc *txdesc, |
306 | const struct rt2x00_rate *hwrate) | 308 | const struct rt2x00_rate *hwrate) |
307 | { | 309 | { |
308 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 310 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
309 | struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; | 311 | struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; |
310 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | 312 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
311 | 313 | ||
312 | if (tx_info->control.sta) | 314 | if (tx_info->control.sta) |
313 | txdesc->u.ht.mpdu_density = | 315 | txdesc->u.ht.mpdu_density = |
@@ -380,12 +382,12 @@ static void rt2x00queue_create_tx_descriptor_ht(struct queue_entry *entry, | |||
380 | txdesc->u.ht.txop = TXOP_HTTXOP; | 382 | txdesc->u.ht.txop = TXOP_HTTXOP; |
381 | } | 383 | } |
382 | 384 | ||
383 | static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | 385 | static void rt2x00queue_create_tx_descriptor(struct rt2x00_dev *rt2x00dev, |
386 | struct sk_buff *skb, | ||
384 | struct txentry_desc *txdesc) | 387 | struct txentry_desc *txdesc) |
385 | { | 388 | { |
386 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 389 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
387 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 390 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
388 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | ||
389 | struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; | 391 | struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; |
390 | struct ieee80211_rate *rate; | 392 | struct ieee80211_rate *rate; |
391 | const struct rt2x00_rate *hwrate = NULL; | 393 | const struct rt2x00_rate *hwrate = NULL; |
@@ -395,8 +397,8 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
395 | /* | 397 | /* |
396 | * Header and frame information. | 398 | * Header and frame information. |
397 | */ | 399 | */ |
398 | txdesc->length = entry->skb->len; | 400 | txdesc->length = skb->len; |
399 | txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb); | 401 | txdesc->header_length = ieee80211_get_hdrlen_from_skb(skb); |
400 | 402 | ||
401 | /* | 403 | /* |
402 | * Check whether this frame is to be acked. | 404 | * Check whether this frame is to be acked. |
@@ -471,13 +473,15 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
471 | /* | 473 | /* |
472 | * Apply TX descriptor handling by components | 474 | * Apply TX descriptor handling by components |
473 | */ | 475 | */ |
474 | rt2x00crypto_create_tx_descriptor(entry, txdesc); | 476 | rt2x00crypto_create_tx_descriptor(rt2x00dev, skb, txdesc); |
475 | rt2x00queue_create_tx_descriptor_seq(entry, txdesc); | 477 | rt2x00queue_create_tx_descriptor_seq(rt2x00dev, skb, txdesc); |
476 | 478 | ||
477 | if (test_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags)) | 479 | if (test_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags)) |
478 | rt2x00queue_create_tx_descriptor_ht(entry, txdesc, hwrate); | 480 | rt2x00queue_create_tx_descriptor_ht(rt2x00dev, skb, txdesc, |
481 | hwrate); | ||
479 | else | 482 | else |
480 | rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); | 483 | rt2x00queue_create_tx_descriptor_plcp(rt2x00dev, skb, txdesc, |
484 | hwrate); | ||
481 | } | 485 | } |
482 | 486 | ||
483 | static int rt2x00queue_write_tx_data(struct queue_entry *entry, | 487 | static int rt2x00queue_write_tx_data(struct queue_entry *entry, |
@@ -555,33 +559,18 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
555 | bool local) | 559 | bool local) |
556 | { | 560 | { |
557 | struct ieee80211_tx_info *tx_info; | 561 | struct ieee80211_tx_info *tx_info; |
558 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); | 562 | struct queue_entry *entry; |
559 | struct txentry_desc txdesc; | 563 | struct txentry_desc txdesc; |
560 | struct skb_frame_desc *skbdesc; | 564 | struct skb_frame_desc *skbdesc; |
561 | u8 rate_idx, rate_flags; | 565 | u8 rate_idx, rate_flags; |
562 | 566 | int ret = 0; | |
563 | if (unlikely(rt2x00queue_full(queue))) { | ||
564 | ERROR(queue->rt2x00dev, | ||
565 | "Dropping frame due to full tx queue %d.\n", queue->qid); | ||
566 | return -ENOBUFS; | ||
567 | } | ||
568 | |||
569 | if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, | ||
570 | &entry->flags))) { | ||
571 | ERROR(queue->rt2x00dev, | ||
572 | "Arrived at non-free entry in the non-full queue %d.\n" | ||
573 | "Please file bug report to %s.\n", | ||
574 | queue->qid, DRV_PROJECT); | ||
575 | return -EINVAL; | ||
576 | } | ||
577 | 567 | ||
578 | /* | 568 | /* |
579 | * Copy all TX descriptor information into txdesc, | 569 | * Copy all TX descriptor information into txdesc, |
580 | * after that we are free to use the skb->cb array | 570 | * after that we are free to use the skb->cb array |
581 | * for our information. | 571 | * for our information. |
582 | */ | 572 | */ |
583 | entry->skb = skb; | 573 | rt2x00queue_create_tx_descriptor(queue->rt2x00dev, skb, &txdesc); |
584 | rt2x00queue_create_tx_descriptor(entry, &txdesc); | ||
585 | 574 | ||
586 | /* | 575 | /* |
587 | * All information is retrieved from the skb->cb array, | 576 | * All information is retrieved from the skb->cb array, |
@@ -593,7 +582,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
593 | rate_flags = tx_info->control.rates[0].flags; | 582 | rate_flags = tx_info->control.rates[0].flags; |
594 | skbdesc = get_skb_frame_desc(skb); | 583 | skbdesc = get_skb_frame_desc(skb); |
595 | memset(skbdesc, 0, sizeof(*skbdesc)); | 584 | memset(skbdesc, 0, sizeof(*skbdesc)); |
596 | skbdesc->entry = entry; | ||
597 | skbdesc->tx_rate_idx = rate_idx; | 585 | skbdesc->tx_rate_idx = rate_idx; |
598 | skbdesc->tx_rate_flags = rate_flags; | 586 | skbdesc->tx_rate_flags = rate_flags; |
599 | 587 | ||
@@ -622,9 +610,33 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
622 | * for PCI devices. | 610 | * for PCI devices. |
623 | */ | 611 | */ |
624 | if (test_bit(REQUIRE_L2PAD, &queue->rt2x00dev->cap_flags)) | 612 | if (test_bit(REQUIRE_L2PAD, &queue->rt2x00dev->cap_flags)) |
625 | rt2x00queue_insert_l2pad(entry->skb, txdesc.header_length); | 613 | rt2x00queue_insert_l2pad(skb, txdesc.header_length); |
626 | else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) | 614 | else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) |
627 | rt2x00queue_align_frame(entry->skb); | 615 | rt2x00queue_align_frame(skb); |
616 | |||
617 | spin_lock(&queue->tx_lock); | ||
618 | |||
619 | if (unlikely(rt2x00queue_full(queue))) { | ||
620 | ERROR(queue->rt2x00dev, | ||
621 | "Dropping frame due to full tx queue %d.\n", queue->qid); | ||
622 | ret = -ENOBUFS; | ||
623 | goto out; | ||
624 | } | ||
625 | |||
626 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
627 | |||
628 | if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, | ||
629 | &entry->flags))) { | ||
630 | ERROR(queue->rt2x00dev, | ||
631 | "Arrived at non-free entry in the non-full queue %d.\n" | ||
632 | "Please file bug report to %s.\n", | ||
633 | queue->qid, DRV_PROJECT); | ||
634 | ret = -EINVAL; | ||
635 | goto out; | ||
636 | } | ||
637 | |||
638 | skbdesc->entry = entry; | ||
639 | entry->skb = skb; | ||
628 | 640 | ||
629 | /* | 641 | /* |
630 | * It could be possible that the queue was corrupted and this | 642 | * It could be possible that the queue was corrupted and this |
@@ -634,7 +646,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
634 | if (unlikely(rt2x00queue_write_tx_data(entry, &txdesc))) { | 646 | if (unlikely(rt2x00queue_write_tx_data(entry, &txdesc))) { |
635 | clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | 647 | clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
636 | entry->skb = NULL; | 648 | entry->skb = NULL; |
637 | return -EIO; | 649 | ret = -EIO; |
650 | goto out; | ||
638 | } | 651 | } |
639 | 652 | ||
640 | set_bit(ENTRY_DATA_PENDING, &entry->flags); | 653 | set_bit(ENTRY_DATA_PENDING, &entry->flags); |
@@ -643,7 +656,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
643 | rt2x00queue_write_tx_descriptor(entry, &txdesc); | 656 | rt2x00queue_write_tx_descriptor(entry, &txdesc); |
644 | rt2x00queue_kick_tx_queue(queue, &txdesc); | 657 | rt2x00queue_kick_tx_queue(queue, &txdesc); |
645 | 658 | ||
646 | return 0; | 659 | out: |
660 | spin_unlock(&queue->tx_lock); | ||
661 | return ret; | ||
647 | } | 662 | } |
648 | 663 | ||
649 | int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev, | 664 | int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev, |
@@ -697,7 +712,7 @@ int rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev, | |||
697 | * after that we are free to use the skb->cb array | 712 | * after that we are free to use the skb->cb array |
698 | * for our information. | 713 | * for our information. |
699 | */ | 714 | */ |
700 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | 715 | rt2x00queue_create_tx_descriptor(rt2x00dev, intf->beacon->skb, &txdesc); |
701 | 716 | ||
702 | /* | 717 | /* |
703 | * Fill in skb descriptor | 718 | * Fill in skb descriptor |
@@ -1184,6 +1199,7 @@ static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, | |||
1184 | struct data_queue *queue, enum data_queue_qid qid) | 1199 | struct data_queue *queue, enum data_queue_qid qid) |
1185 | { | 1200 | { |
1186 | mutex_init(&queue->status_lock); | 1201 | mutex_init(&queue->status_lock); |
1202 | spin_lock_init(&queue->tx_lock); | ||
1187 | spin_lock_init(&queue->index_lock); | 1203 | spin_lock_init(&queue->index_lock); |
1188 | 1204 | ||
1189 | queue->rt2x00dev = rt2x00dev; | 1205 | queue->rt2x00dev = rt2x00dev; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 590047499e3c..f2100f4ddcff 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -432,6 +432,7 @@ enum data_queue_flags { | |||
432 | * @flags: Entry flags, see &enum queue_entry_flags. | 432 | * @flags: Entry flags, see &enum queue_entry_flags. |
433 | * @status_lock: The mutex for protecting the start/stop/flush | 433 | * @status_lock: The mutex for protecting the start/stop/flush |
434 | * handling on this queue. | 434 | * handling on this queue. |
435 | * @tx_lock: Spinlock to serialize tx operations on this queue. | ||
435 | * @index_lock: Spinlock to protect index handling. Whenever @index, @index_done or | 436 | * @index_lock: Spinlock to protect index handling. Whenever @index, @index_done or |
436 | * @index_crypt needs to be changed this lock should be grabbed to prevent | 437 | * @index_crypt needs to be changed this lock should be grabbed to prevent |
437 | * index corruption due to concurrency. | 438 | * index corruption due to concurrency. |
@@ -458,6 +459,7 @@ struct data_queue { | |||
458 | unsigned long flags; | 459 | unsigned long flags; |
459 | 460 | ||
460 | struct mutex status_lock; | 461 | struct mutex status_lock; |
462 | spinlock_t tx_lock; | ||
461 | spinlock_t index_lock; | 463 | spinlock_t index_lock; |
462 | 464 | ||
463 | unsigned int count; | 465 | unsigned int count; |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 9d35ec16a3a5..53110b83bf6e 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -2982,6 +2982,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { | |||
2982 | .set_antenna = rt2x00mac_set_antenna, | 2982 | .set_antenna = rt2x00mac_set_antenna, |
2983 | .get_antenna = rt2x00mac_get_antenna, | 2983 | .get_antenna = rt2x00mac_get_antenna, |
2984 | .get_ringparam = rt2x00mac_get_ringparam, | 2984 | .get_ringparam = rt2x00mac_get_ringparam, |
2985 | .tx_frames_pending = rt2x00mac_tx_frames_pending, | ||
2985 | }; | 2986 | }; |
2986 | 2987 | ||
2987 | static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | 2988 | static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index ad20953cbf05..6a93939f44e8 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -2314,6 +2314,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { | |||
2314 | .set_antenna = rt2x00mac_set_antenna, | 2314 | .set_antenna = rt2x00mac_set_antenna, |
2315 | .get_antenna = rt2x00mac_get_antenna, | 2315 | .get_antenna = rt2x00mac_get_antenna, |
2316 | .get_ringparam = rt2x00mac_get_ringparam, | 2316 | .get_ringparam = rt2x00mac_get_ringparam, |
2317 | .tx_frames_pending = rt2x00mac_tx_frames_pending, | ||
2317 | }; | 2318 | }; |
2318 | 2319 | ||
2319 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | 2320 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { |