diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00dev.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 469 |
1 files changed, 318 insertions, 151 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 585e8166f22a..939821b4af2f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> | 2 | Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> |
3 | Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com> | ||
3 | <http://rt2x00.serialmonkey.com> | 4 | <http://rt2x00.serialmonkey.com> |
4 | 5 | ||
5 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
@@ -26,6 +27,7 @@ | |||
26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 28 | #include <linux/module.h> |
28 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/log2.h> | ||
29 | 31 | ||
30 | #include "rt2x00.h" | 32 | #include "rt2x00.h" |
31 | #include "rt2x00lib.h" | 33 | #include "rt2x00lib.h" |
@@ -65,20 +67,17 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
65 | set_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags); | 67 | set_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags); |
66 | 68 | ||
67 | /* | 69 | /* |
68 | * Enable RX. | 70 | * Enable queues. |
69 | */ | 71 | */ |
70 | rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); | 72 | rt2x00queue_start_queues(rt2x00dev); |
73 | rt2x00link_start_tuner(rt2x00dev); | ||
74 | rt2x00link_start_agc(rt2x00dev); | ||
71 | 75 | ||
72 | /* | 76 | /* |
73 | * Start watchdog monitoring. | 77 | * Start watchdog monitoring. |
74 | */ | 78 | */ |
75 | rt2x00link_start_watchdog(rt2x00dev); | 79 | rt2x00link_start_watchdog(rt2x00dev); |
76 | 80 | ||
77 | /* | ||
78 | * Start the TX queues. | ||
79 | */ | ||
80 | ieee80211_wake_queues(rt2x00dev->hw); | ||
81 | |||
82 | return 0; | 81 | return 0; |
83 | } | 82 | } |
84 | 83 | ||
@@ -88,20 +87,17 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
88 | return; | 87 | return; |
89 | 88 | ||
90 | /* | 89 | /* |
91 | * Stop the TX queues in mac80211. | ||
92 | */ | ||
93 | ieee80211_stop_queues(rt2x00dev->hw); | ||
94 | rt2x00queue_stop_queues(rt2x00dev); | ||
95 | |||
96 | /* | ||
97 | * Stop watchdog monitoring. | 90 | * Stop watchdog monitoring. |
98 | */ | 91 | */ |
99 | rt2x00link_stop_watchdog(rt2x00dev); | 92 | rt2x00link_stop_watchdog(rt2x00dev); |
100 | 93 | ||
101 | /* | 94 | /* |
102 | * Disable RX. | 95 | * Stop all queues |
103 | */ | 96 | */ |
104 | rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); | 97 | rt2x00link_stop_agc(rt2x00dev); |
98 | rt2x00link_stop_tuner(rt2x00dev); | ||
99 | rt2x00queue_stop_queues(rt2x00dev); | ||
100 | rt2x00queue_flush_queues(rt2x00dev, true); | ||
105 | 101 | ||
106 | /* | 102 | /* |
107 | * Disable radio. | 103 | * Disable radio. |
@@ -112,41 +108,11 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
112 | rt2x00leds_led_radio(rt2x00dev, false); | 108 | rt2x00leds_led_radio(rt2x00dev, false); |
113 | } | 109 | } |
114 | 110 | ||
115 | void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state) | ||
116 | { | ||
117 | /* | ||
118 | * When we are disabling the RX, we should also stop the link tuner. | ||
119 | */ | ||
120 | if (state == STATE_RADIO_RX_OFF) | ||
121 | rt2x00link_stop_tuner(rt2x00dev); | ||
122 | |||
123 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); | ||
124 | |||
125 | /* | ||
126 | * When we are enabling the RX, we should also start the link tuner. | ||
127 | */ | ||
128 | if (state == STATE_RADIO_RX_ON) | ||
129 | rt2x00link_start_tuner(rt2x00dev); | ||
130 | } | ||
131 | |||
132 | static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | 111 | static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, |
133 | struct ieee80211_vif *vif) | 112 | struct ieee80211_vif *vif) |
134 | { | 113 | { |
135 | struct rt2x00_dev *rt2x00dev = data; | 114 | struct rt2x00_dev *rt2x00dev = data; |
136 | struct rt2x00_intf *intf = vif_to_intf(vif); | 115 | struct rt2x00_intf *intf = vif_to_intf(vif); |
137 | int delayed_flags; | ||
138 | |||
139 | /* | ||
140 | * Copy all data we need during this action under the protection | ||
141 | * of a spinlock. Otherwise race conditions might occur which results | ||
142 | * into an invalid configuration. | ||
143 | */ | ||
144 | spin_lock(&intf->lock); | ||
145 | |||
146 | delayed_flags = intf->delayed_flags; | ||
147 | intf->delayed_flags = 0; | ||
148 | |||
149 | spin_unlock(&intf->lock); | ||
150 | 116 | ||
151 | /* | 117 | /* |
152 | * It is possible the radio was disabled while the work had been | 118 | * It is possible the radio was disabled while the work had been |
@@ -157,8 +123,8 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | |||
157 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | 123 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
158 | return; | 124 | return; |
159 | 125 | ||
160 | if (delayed_flags & DELAYED_UPDATE_BEACON) | 126 | if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) |
161 | rt2x00queue_update_beacon(rt2x00dev, vif, true); | 127 | rt2x00queue_update_beacon(rt2x00dev, vif); |
162 | } | 128 | } |
163 | 129 | ||
164 | static void rt2x00lib_intf_scheduled(struct work_struct *work) | 130 | static void rt2x00lib_intf_scheduled(struct work_struct *work) |
@@ -175,6 +141,19 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work) | |||
175 | rt2x00dev); | 141 | rt2x00dev); |
176 | } | 142 | } |
177 | 143 | ||
144 | static void rt2x00lib_autowakeup(struct work_struct *work) | ||
145 | { | ||
146 | struct rt2x00_dev *rt2x00dev = | ||
147 | container_of(work, struct rt2x00_dev, autowakeup_work.work); | ||
148 | |||
149 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) | ||
150 | return; | ||
151 | |||
152 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) | ||
153 | ERROR(rt2x00dev, "Device failed to wakeup.\n"); | ||
154 | clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); | ||
155 | } | ||
156 | |||
178 | /* | 157 | /* |
179 | * Interrupt context handlers. | 158 | * Interrupt context handlers. |
180 | */ | 159 | */ |
@@ -211,7 +190,13 @@ static void rt2x00lib_beaconupdate_iter(void *data, u8 *mac, | |||
211 | vif->type != NL80211_IFTYPE_WDS) | 190 | vif->type != NL80211_IFTYPE_WDS) |
212 | return; | 191 | return; |
213 | 192 | ||
214 | rt2x00queue_update_beacon(rt2x00dev, vif, true); | 193 | /* |
194 | * Update the beacon without locking. This is safe on PCI devices | ||
195 | * as they only update the beacon periodically here. This should | ||
196 | * never be called for USB devices. | ||
197 | */ | ||
198 | WARN_ON(rt2x00_is_usb(rt2x00dev)); | ||
199 | rt2x00queue_update_beacon_locked(rt2x00dev, vif); | ||
215 | } | 200 | } |
216 | 201 | ||
217 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | 202 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) |
@@ -220,21 +205,21 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
220 | return; | 205 | return; |
221 | 206 | ||
222 | /* send buffered bc/mc frames out for every bssid */ | 207 | /* send buffered bc/mc frames out for every bssid */ |
223 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | 208 | ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, |
224 | rt2x00lib_bc_buffer_iter, | 209 | rt2x00lib_bc_buffer_iter, |
225 | rt2x00dev); | 210 | rt2x00dev); |
226 | /* | 211 | /* |
227 | * Devices with pre tbtt interrupt don't need to update the beacon | 212 | * Devices with pre tbtt interrupt don't need to update the beacon |
228 | * here as they will fetch the next beacon directly prior to | 213 | * here as they will fetch the next beacon directly prior to |
229 | * transmission. | 214 | * transmission. |
230 | */ | 215 | */ |
231 | if (test_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags)) | 216 | if (test_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags)) |
232 | return; | 217 | return; |
233 | 218 | ||
234 | /* fetch next beacon */ | 219 | /* fetch next beacon */ |
235 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | 220 | ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, |
236 | rt2x00lib_beaconupdate_iter, | 221 | rt2x00lib_beaconupdate_iter, |
237 | rt2x00dev); | 222 | rt2x00dev); |
238 | } | 223 | } |
239 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | 224 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); |
240 | 225 | ||
@@ -244,29 +229,42 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev) | |||
244 | return; | 229 | return; |
245 | 230 | ||
246 | /* fetch next beacon */ | 231 | /* fetch next beacon */ |
247 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | 232 | ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, |
248 | rt2x00lib_beaconupdate_iter, | 233 | rt2x00lib_beaconupdate_iter, |
249 | rt2x00dev); | 234 | rt2x00dev); |
250 | } | 235 | } |
251 | EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); | 236 | EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); |
252 | 237 | ||
238 | void rt2x00lib_dmastart(struct queue_entry *entry) | ||
239 | { | ||
240 | set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | ||
241 | rt2x00queue_index_inc(entry, Q_INDEX); | ||
242 | } | ||
243 | EXPORT_SYMBOL_GPL(rt2x00lib_dmastart); | ||
244 | |||
245 | void rt2x00lib_dmadone(struct queue_entry *entry) | ||
246 | { | ||
247 | set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags); | ||
248 | clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | ||
249 | rt2x00queue_index_inc(entry, Q_INDEX_DMA_DONE); | ||
250 | } | ||
251 | EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); | ||
252 | |||
253 | void rt2x00lib_txdone(struct queue_entry *entry, | 253 | void rt2x00lib_txdone(struct queue_entry *entry, |
254 | struct txdone_entry_desc *txdesc) | 254 | struct txdone_entry_desc *txdesc) |
255 | { | 255 | { |
256 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 256 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
257 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 257 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); |
258 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 258 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
259 | enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); | 259 | unsigned int header_length, i; |
260 | unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb); | ||
261 | u8 rate_idx, rate_flags, retry_rates; | 260 | u8 rate_idx, rate_flags, retry_rates; |
262 | u8 skbdesc_flags = skbdesc->flags; | 261 | u8 skbdesc_flags = skbdesc->flags; |
263 | unsigned int i; | ||
264 | bool success; | 262 | bool success; |
265 | 263 | ||
266 | /* | 264 | /* |
267 | * Unmap the skb. | 265 | * Unmap the skb. |
268 | */ | 266 | */ |
269 | rt2x00queue_unmap_skb(rt2x00dev, entry->skb); | 267 | rt2x00queue_unmap_skb(entry); |
270 | 268 | ||
271 | /* | 269 | /* |
272 | * Remove the extra tx headroom from the skb. | 270 | * Remove the extra tx headroom from the skb. |
@@ -279,9 +277,14 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
279 | skbdesc->flags &= ~SKBDESC_DESC_IN_SKB; | 277 | skbdesc->flags &= ~SKBDESC_DESC_IN_SKB; |
280 | 278 | ||
281 | /* | 279 | /* |
280 | * Determine the length of 802.11 header. | ||
281 | */ | ||
282 | header_length = ieee80211_get_hdrlen_from_skb(entry->skb); | ||
283 | |||
284 | /* | ||
282 | * Remove L2 padding which was added during | 285 | * Remove L2 padding which was added during |
283 | */ | 286 | */ |
284 | if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) | 287 | if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags)) |
285 | rt2x00queue_remove_l2pad(entry->skb, header_length); | 288 | rt2x00queue_remove_l2pad(entry->skb, header_length); |
286 | 289 | ||
287 | /* | 290 | /* |
@@ -290,7 +293,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
290 | * mac80211 will expect the same data to be present it the | 293 | * mac80211 will expect the same data to be present it the |
291 | * frame as it was passed to us. | 294 | * frame as it was passed to us. |
292 | */ | 295 | */ |
293 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) | 296 | if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) |
294 | rt2x00crypto_tx_insert_iv(entry->skb, header_length); | 297 | rt2x00crypto_tx_insert_iv(entry->skb, header_length); |
295 | 298 | ||
296 | /* | 299 | /* |
@@ -363,10 +366,14 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
363 | * which would allow the rc algorithm to better decide on | 366 | * which would allow the rc algorithm to better decide on |
364 | * which rates are suitable. | 367 | * which rates are suitable. |
365 | */ | 368 | */ |
366 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | 369 | if (test_bit(TXDONE_AMPDU, &txdesc->flags) || |
370 | tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
367 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU; | 371 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU; |
368 | tx_info->status.ampdu_len = 1; | 372 | tx_info->status.ampdu_len = 1; |
369 | tx_info->status.ampdu_ack_len = success ? 1 : 0; | 373 | tx_info->status.ampdu_ack_len = success ? 1 : 0; |
374 | |||
375 | if (!success) | ||
376 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | ||
370 | } | 377 | } |
371 | 378 | ||
372 | if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { | 379 | if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { |
@@ -382,17 +389,12 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
382 | * through a mac80211 library call (RTS/CTS) then we should not | 389 | * through a mac80211 library call (RTS/CTS) then we should not |
383 | * send the status report back. | 390 | * send the status report back. |
384 | */ | 391 | */ |
385 | if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) | 392 | if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) { |
386 | /* | 393 | if (test_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags)) |
387 | * Only PCI and SOC devices process the tx status in process | ||
388 | * context. Hence use ieee80211_tx_status for PCI and SOC | ||
389 | * devices and stick to ieee80211_tx_status_irqsafe for USB. | ||
390 | */ | ||
391 | if (rt2x00_is_usb(rt2x00dev)) | ||
392 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); | ||
393 | else | ||
394 | ieee80211_tx_status(rt2x00dev->hw, entry->skb); | 394 | ieee80211_tx_status(rt2x00dev->hw, entry->skb); |
395 | else | 395 | else |
396 | ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb); | ||
397 | } else | ||
396 | dev_kfree_skb_any(entry->skb); | 398 | dev_kfree_skb_any(entry->skb); |
397 | 399 | ||
398 | /* | 400 | /* |
@@ -403,8 +405,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
403 | 405 | ||
404 | rt2x00dev->ops->lib->clear_entry(entry); | 406 | rt2x00dev->ops->lib->clear_entry(entry); |
405 | 407 | ||
406 | clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | 408 | rt2x00queue_index_inc(entry, Q_INDEX_DONE); |
407 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); | ||
408 | 409 | ||
409 | /* | 410 | /* |
410 | * If the data queue was below the threshold before the txdone | 411 | * If the data queue was below the threshold before the txdone |
@@ -412,69 +413,168 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
412 | * is reenabled when the txdone handler has finished. | 413 | * is reenabled when the txdone handler has finished. |
413 | */ | 414 | */ |
414 | if (!rt2x00queue_threshold(entry->queue)) | 415 | if (!rt2x00queue_threshold(entry->queue)) |
415 | ieee80211_wake_queue(rt2x00dev->hw, qid); | 416 | rt2x00queue_unpause_queue(entry->queue); |
416 | } | 417 | } |
417 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | 418 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); |
418 | 419 | ||
420 | void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status) | ||
421 | { | ||
422 | struct txdone_entry_desc txdesc; | ||
423 | |||
424 | txdesc.flags = 0; | ||
425 | __set_bit(status, &txdesc.flags); | ||
426 | txdesc.retry = 0; | ||
427 | |||
428 | rt2x00lib_txdone(entry, &txdesc); | ||
429 | } | ||
430 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone_noinfo); | ||
431 | |||
432 | static u8 *rt2x00lib_find_ie(u8 *data, unsigned int len, u8 ie) | ||
433 | { | ||
434 | struct ieee80211_mgmt *mgmt = (void *)data; | ||
435 | u8 *pos, *end; | ||
436 | |||
437 | pos = (u8 *)mgmt->u.beacon.variable; | ||
438 | end = data + len; | ||
439 | while (pos < end) { | ||
440 | if (pos + 2 + pos[1] > end) | ||
441 | return NULL; | ||
442 | |||
443 | if (pos[0] == ie) | ||
444 | return pos; | ||
445 | |||
446 | pos += 2 + pos[1]; | ||
447 | } | ||
448 | |||
449 | return NULL; | ||
450 | } | ||
451 | |||
452 | static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev, | ||
453 | struct sk_buff *skb, | ||
454 | struct rxdone_entry_desc *rxdesc) | ||
455 | { | ||
456 | struct ieee80211_hdr *hdr = (void *) skb->data; | ||
457 | struct ieee80211_tim_ie *tim_ie; | ||
458 | u8 *tim; | ||
459 | u8 tim_len; | ||
460 | bool cam; | ||
461 | |||
462 | /* If this is not a beacon, or if mac80211 has no powersaving | ||
463 | * configured, or if the device is already in powersaving mode | ||
464 | * we can exit now. */ | ||
465 | if (likely(!ieee80211_is_beacon(hdr->frame_control) || | ||
466 | !(rt2x00dev->hw->conf.flags & IEEE80211_CONF_PS))) | ||
467 | return; | ||
468 | |||
469 | /* min. beacon length + FCS_LEN */ | ||
470 | if (skb->len <= 40 + FCS_LEN) | ||
471 | return; | ||
472 | |||
473 | /* and only beacons from the associated BSSID, please */ | ||
474 | if (!(rxdesc->dev_flags & RXDONE_MY_BSS) || | ||
475 | !rt2x00dev->aid) | ||
476 | return; | ||
477 | |||
478 | rt2x00dev->last_beacon = jiffies; | ||
479 | |||
480 | tim = rt2x00lib_find_ie(skb->data, skb->len - FCS_LEN, WLAN_EID_TIM); | ||
481 | if (!tim) | ||
482 | return; | ||
483 | |||
484 | if (tim[1] < sizeof(*tim_ie)) | ||
485 | return; | ||
486 | |||
487 | tim_len = tim[1]; | ||
488 | tim_ie = (struct ieee80211_tim_ie *) &tim[2]; | ||
489 | |||
490 | /* Check whenever the PHY can be turned off again. */ | ||
491 | |||
492 | /* 1. What about buffered unicast traffic for our AID? */ | ||
493 | cam = ieee80211_check_tim(tim_ie, tim_len, rt2x00dev->aid); | ||
494 | |||
495 | /* 2. Maybe the AP wants to send multicast/broadcast data? */ | ||
496 | cam |= (tim_ie->bitmap_ctrl & 0x01); | ||
497 | |||
498 | if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) | ||
499 | rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, | ||
500 | IEEE80211_CONF_CHANGE_PS); | ||
501 | } | ||
502 | |||
419 | static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, | 503 | static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, |
420 | struct rxdone_entry_desc *rxdesc) | 504 | struct rxdone_entry_desc *rxdesc) |
421 | { | 505 | { |
422 | struct ieee80211_supported_band *sband; | 506 | struct ieee80211_supported_band *sband; |
423 | const struct rt2x00_rate *rate; | 507 | const struct rt2x00_rate *rate; |
424 | unsigned int i; | 508 | unsigned int i; |
425 | int signal; | 509 | int signal = rxdesc->signal; |
426 | int type; | 510 | int type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK); |
427 | |||
428 | /* | ||
429 | * For non-HT rates the MCS value needs to contain the | ||
430 | * actually used rate modulation (CCK or OFDM). | ||
431 | */ | ||
432 | if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS) | ||
433 | signal = RATE_MCS(rxdesc->rate_mode, rxdesc->signal); | ||
434 | else | ||
435 | signal = rxdesc->signal; | ||
436 | 511 | ||
437 | type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK); | 512 | switch (rxdesc->rate_mode) { |
438 | 513 | case RATE_MODE_CCK: | |
439 | sband = &rt2x00dev->bands[rt2x00dev->curr_band]; | 514 | case RATE_MODE_OFDM: |
440 | for (i = 0; i < sband->n_bitrates; i++) { | 515 | /* |
441 | rate = rt2x00_get_rate(sband->bitrates[i].hw_value); | 516 | * For non-HT rates the MCS value needs to contain the |
442 | 517 | * actually used rate modulation (CCK or OFDM). | |
443 | if (((type == RXDONE_SIGNAL_PLCP) && | 518 | */ |
444 | (rate->plcp == signal)) || | 519 | if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS) |
445 | ((type == RXDONE_SIGNAL_BITRATE) && | 520 | signal = RATE_MCS(rxdesc->rate_mode, signal); |
446 | (rate->bitrate == signal)) || | 521 | |
447 | ((type == RXDONE_SIGNAL_MCS) && | 522 | sband = &rt2x00dev->bands[rt2x00dev->curr_band]; |
448 | (rate->mcs == signal))) { | 523 | for (i = 0; i < sband->n_bitrates; i++) { |
449 | return i; | 524 | rate = rt2x00_get_rate(sband->bitrates[i].hw_value); |
525 | if (((type == RXDONE_SIGNAL_PLCP) && | ||
526 | (rate->plcp == signal)) || | ||
527 | ((type == RXDONE_SIGNAL_BITRATE) && | ||
528 | (rate->bitrate == signal)) || | ||
529 | ((type == RXDONE_SIGNAL_MCS) && | ||
530 | (rate->mcs == signal))) { | ||
531 | return i; | ||
532 | } | ||
450 | } | 533 | } |
534 | break; | ||
535 | case RATE_MODE_HT_MIX: | ||
536 | case RATE_MODE_HT_GREENFIELD: | ||
537 | if (signal >= 0 && signal <= 76) | ||
538 | return signal; | ||
539 | break; | ||
540 | default: | ||
541 | break; | ||
451 | } | 542 | } |
452 | 543 | ||
453 | WARNING(rt2x00dev, "Frame received with unrecognized signal, " | 544 | WARNING(rt2x00dev, "Frame received with unrecognized signal, " |
454 | "signal=0x%.4x, type=%d.\n", signal, type); | 545 | "mode=0x%.4x, signal=0x%.4x, type=%d.\n", |
546 | rxdesc->rate_mode, signal, type); | ||
455 | return 0; | 547 | return 0; |
456 | } | 548 | } |
457 | 549 | ||
458 | void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, | 550 | void rt2x00lib_rxdone(struct queue_entry *entry) |
459 | struct queue_entry *entry) | ||
460 | { | 551 | { |
552 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
461 | struct rxdone_entry_desc rxdesc; | 553 | struct rxdone_entry_desc rxdesc; |
462 | struct sk_buff *skb; | 554 | struct sk_buff *skb; |
463 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; | 555 | struct ieee80211_rx_status *rx_status; |
464 | unsigned int header_length; | 556 | unsigned int header_length; |
465 | int rate_idx; | 557 | int rate_idx; |
558 | |||
559 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || | ||
560 | !test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
561 | goto submit_entry; | ||
562 | |||
563 | if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) | ||
564 | goto submit_entry; | ||
565 | |||
466 | /* | 566 | /* |
467 | * Allocate a new sk_buffer. If no new buffer available, drop the | 567 | * Allocate a new sk_buffer. If no new buffer available, drop the |
468 | * received frame and reuse the existing buffer. | 568 | * received frame and reuse the existing buffer. |
469 | */ | 569 | */ |
470 | skb = rt2x00queue_alloc_rxskb(rt2x00dev, entry); | 570 | skb = rt2x00queue_alloc_rxskb(entry); |
471 | if (!skb) | 571 | if (!skb) |
472 | return; | 572 | goto submit_entry; |
473 | 573 | ||
474 | /* | 574 | /* |
475 | * Unmap the skb. | 575 | * Unmap the skb. |
476 | */ | 576 | */ |
477 | rt2x00queue_unmap_skb(rt2x00dev, entry->skb); | 577 | rt2x00queue_unmap_skb(entry); |
478 | 578 | ||
479 | /* | 579 | /* |
480 | * Extract the RXD details. | 580 | * Extract the RXD details. |
@@ -502,64 +602,57 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, | |||
502 | (rxdesc.size > header_length) && | 602 | (rxdesc.size > header_length) && |
503 | (rxdesc.dev_flags & RXDONE_L2PAD)) | 603 | (rxdesc.dev_flags & RXDONE_L2PAD)) |
504 | rt2x00queue_remove_l2pad(entry->skb, header_length); | 604 | rt2x00queue_remove_l2pad(entry->skb, header_length); |
505 | else | ||
506 | rt2x00queue_align_payload(entry->skb, header_length); | ||
507 | 605 | ||
508 | /* Trim buffer to correct size */ | 606 | /* Trim buffer to correct size */ |
509 | skb_trim(entry->skb, rxdesc.size); | 607 | skb_trim(entry->skb, rxdesc.size); |
510 | 608 | ||
511 | /* | 609 | /* |
512 | * Check if the frame was received using HT. In that case, | 610 | * Translate the signal to the correct bitrate index. |
513 | * the rate is the MCS index and should be passed to mac80211 | ||
514 | * directly. Otherwise we need to translate the signal to | ||
515 | * the correct bitrate index. | ||
516 | */ | 611 | */ |
517 | if (rxdesc.rate_mode == RATE_MODE_CCK || | 612 | rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc); |
518 | rxdesc.rate_mode == RATE_MODE_OFDM) { | 613 | if (rxdesc.rate_mode == RATE_MODE_HT_MIX || |
519 | rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc); | 614 | rxdesc.rate_mode == RATE_MODE_HT_GREENFIELD) |
520 | } else { | ||
521 | rxdesc.flags |= RX_FLAG_HT; | 615 | rxdesc.flags |= RX_FLAG_HT; |
522 | rate_idx = rxdesc.signal; | 616 | |
523 | } | 617 | /* |
618 | * Check if this is a beacon, and more frames have been | ||
619 | * buffered while we were in powersaving mode. | ||
620 | */ | ||
621 | rt2x00lib_rxdone_check_ps(rt2x00dev, entry->skb, &rxdesc); | ||
524 | 622 | ||
525 | /* | 623 | /* |
526 | * Update extra components | 624 | * Update extra components |
527 | */ | 625 | */ |
528 | rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc); | 626 | rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc); |
529 | rt2x00debug_update_crypto(rt2x00dev, &rxdesc); | 627 | rt2x00debug_update_crypto(rt2x00dev, &rxdesc); |
628 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); | ||
530 | 629 | ||
630 | /* | ||
631 | * Initialize RX status information, and send frame | ||
632 | * to mac80211. | ||
633 | */ | ||
634 | rx_status = IEEE80211_SKB_RXCB(entry->skb); | ||
531 | rx_status->mactime = rxdesc.timestamp; | 635 | rx_status->mactime = rxdesc.timestamp; |
636 | rx_status->band = rt2x00dev->curr_band; | ||
637 | rx_status->freq = rt2x00dev->curr_freq; | ||
532 | rx_status->rate_idx = rate_idx; | 638 | rx_status->rate_idx = rate_idx; |
533 | rx_status->signal = rxdesc.rssi; | 639 | rx_status->signal = rxdesc.rssi; |
534 | rx_status->flag = rxdesc.flags; | 640 | rx_status->flag = rxdesc.flags; |
535 | rx_status->antenna = rt2x00dev->link.ant.active.rx; | 641 | rx_status->antenna = rt2x00dev->link.ant.active.rx; |
536 | 642 | ||
537 | /* | 643 | ieee80211_rx_ni(rt2x00dev->hw, entry->skb); |
538 | * Send frame to mac80211 & debugfs. | ||
539 | * mac80211 will clean up the skb structure. | ||
540 | */ | ||
541 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); | ||
542 | memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status)); | ||
543 | |||
544 | /* | ||
545 | * Currently only PCI and SOC devices handle rx interrupts in process | ||
546 | * context. Hence, use ieee80211_rx_irqsafe for USB and ieee80211_rx_ni | ||
547 | * for PCI and SOC devices. | ||
548 | */ | ||
549 | if (rt2x00_is_usb(rt2x00dev)) | ||
550 | ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb); | ||
551 | else | ||
552 | ieee80211_rx_ni(rt2x00dev->hw, entry->skb); | ||
553 | 644 | ||
554 | /* | 645 | /* |
555 | * Replace the skb with the freshly allocated one. | 646 | * Replace the skb with the freshly allocated one. |
556 | */ | 647 | */ |
557 | entry->skb = skb; | 648 | entry->skb = skb; |
558 | entry->flags = 0; | ||
559 | |||
560 | rt2x00dev->ops->lib->clear_entry(entry); | ||
561 | 649 | ||
562 | rt2x00queue_index_inc(entry->queue, Q_INDEX); | 650 | submit_entry: |
651 | entry->flags = 0; | ||
652 | rt2x00queue_index_inc(entry, Q_INDEX_DONE); | ||
653 | if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && | ||
654 | test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
655 | rt2x00dev->ops->lib->clear_entry(entry); | ||
563 | } | 656 | } |
564 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); | 657 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); |
565 | 658 | ||
@@ -657,7 +750,10 @@ static void rt2x00lib_channel(struct ieee80211_channel *entry, | |||
657 | const int channel, const int tx_power, | 750 | const int channel, const int tx_power, |
658 | const int value) | 751 | const int value) |
659 | { | 752 | { |
660 | entry->center_freq = ieee80211_channel_to_frequency(channel); | 753 | /* XXX: this assumption about the band is wrong for 802.11j */ |
754 | entry->band = channel <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | ||
755 | entry->center_freq = ieee80211_channel_to_frequency(channel, | ||
756 | entry->band); | ||
661 | entry->hw_value = value; | 757 | entry->hw_value = value; |
662 | entry->max_power = tx_power; | 758 | entry->max_power = tx_power; |
663 | entry->max_antenna_gain = 0xff; | 759 | entry->max_antenna_gain = 0xff; |
@@ -668,7 +764,7 @@ static void rt2x00lib_rate(struct ieee80211_rate *entry, | |||
668 | { | 764 | { |
669 | entry->flags = 0; | 765 | entry->flags = 0; |
670 | entry->bitrate = rate->bitrate; | 766 | entry->bitrate = rate->bitrate; |
671 | entry->hw_value =index; | 767 | entry->hw_value = index; |
672 | entry->hw_value_short = index; | 768 | entry->hw_value_short = index; |
673 | 769 | ||
674 | if (rate->flags & DEV_RATE_SHORT_PREAMBLE) | 770 | if (rate->flags & DEV_RATE_SHORT_PREAMBLE) |
@@ -710,7 +806,7 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | |||
710 | for (i = 0; i < spec->num_channels; i++) { | 806 | for (i = 0; i < spec->num_channels; i++) { |
711 | rt2x00lib_channel(&channels[i], | 807 | rt2x00lib_channel(&channels[i], |
712 | spec->channels[i].channel, | 808 | spec->channels[i].channel, |
713 | spec->channels_info[i].tx_power1, i); | 809 | spec->channels_info[i].max_power, i); |
714 | } | 810 | } |
715 | 811 | ||
716 | /* | 812 | /* |
@@ -800,12 +896,55 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
800 | /* | 896 | /* |
801 | * Take TX headroom required for alignment into account. | 897 | * Take TX headroom required for alignment into account. |
802 | */ | 898 | */ |
803 | if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) | 899 | if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags)) |
804 | rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE; | 900 | rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE; |
805 | else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) | 901 | else if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) |
806 | rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; | 902 | rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; |
807 | 903 | ||
808 | /* | 904 | /* |
905 | * Allocate tx status FIFO for driver use. | ||
906 | */ | ||
907 | if (test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags)) { | ||
908 | /* | ||
909 | * Allocate the txstatus fifo. In the worst case the tx | ||
910 | * status fifo has to hold the tx status of all entries | ||
911 | * in all tx queues. Hence, calculate the kfifo size as | ||
912 | * tx_queues * entry_num and round up to the nearest | ||
913 | * power of 2. | ||
914 | */ | ||
915 | int kfifo_size = | ||
916 | roundup_pow_of_two(rt2x00dev->ops->tx_queues * | ||
917 | rt2x00dev->ops->tx->entry_num * | ||
918 | sizeof(u32)); | ||
919 | |||
920 | status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size, | ||
921 | GFP_KERNEL); | ||
922 | if (status) | ||
923 | return status; | ||
924 | } | ||
925 | |||
926 | /* | ||
927 | * Initialize tasklets if used by the driver. Tasklets are | ||
928 | * disabled until the interrupts are turned on. The driver | ||
929 | * has to handle that. | ||
930 | */ | ||
931 | #define RT2X00_TASKLET_INIT(taskletname) \ | ||
932 | if (rt2x00dev->ops->lib->taskletname) { \ | ||
933 | tasklet_init(&rt2x00dev->taskletname, \ | ||
934 | rt2x00dev->ops->lib->taskletname, \ | ||
935 | (unsigned long)rt2x00dev); \ | ||
936 | tasklet_disable(&rt2x00dev->taskletname); \ | ||
937 | } | ||
938 | |||
939 | RT2X00_TASKLET_INIT(txstatus_tasklet); | ||
940 | RT2X00_TASKLET_INIT(pretbtt_tasklet); | ||
941 | RT2X00_TASKLET_INIT(tbtt_tasklet); | ||
942 | RT2X00_TASKLET_INIT(rxdone_tasklet); | ||
943 | RT2X00_TASKLET_INIT(autowake_tasklet); | ||
944 | |||
945 | #undef RT2X00_TASKLET_INIT | ||
946 | |||
947 | /* | ||
809 | * Register HW. | 948 | * Register HW. |
810 | */ | 949 | */ |
811 | status = ieee80211_register_hw(rt2x00dev->hw); | 950 | status = ieee80211_register_hw(rt2x00dev->hw); |
@@ -902,10 +1041,8 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) | |||
902 | 1041 | ||
903 | /* Enable the radio */ | 1042 | /* Enable the radio */ |
904 | retval = rt2x00lib_enable_radio(rt2x00dev); | 1043 | retval = rt2x00lib_enable_radio(rt2x00dev); |
905 | if (retval) { | 1044 | if (retval) |
906 | rt2x00queue_uninitialize(rt2x00dev); | ||
907 | return retval; | 1045 | return retval; |
908 | } | ||
909 | 1046 | ||
910 | set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags); | 1047 | set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags); |
911 | 1048 | ||
@@ -935,6 +1072,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
935 | { | 1072 | { |
936 | int retval = -ENOMEM; | 1073 | int retval = -ENOMEM; |
937 | 1074 | ||
1075 | spin_lock_init(&rt2x00dev->irqmask_lock); | ||
938 | mutex_init(&rt2x00dev->csr_mutex); | 1076 | mutex_init(&rt2x00dev->csr_mutex); |
939 | 1077 | ||
940 | set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); | 1078 | set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); |
@@ -959,9 +1097,17 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
959 | BIT(NL80211_IFTYPE_WDS); | 1097 | BIT(NL80211_IFTYPE_WDS); |
960 | 1098 | ||
961 | /* | 1099 | /* |
962 | * Initialize configuration work. | 1100 | * Initialize work. |
963 | */ | 1101 | */ |
1102 | rt2x00dev->workqueue = | ||
1103 | alloc_ordered_workqueue(wiphy_name(rt2x00dev->hw->wiphy), 0); | ||
1104 | if (!rt2x00dev->workqueue) { | ||
1105 | retval = -ENOMEM; | ||
1106 | goto exit; | ||
1107 | } | ||
1108 | |||
964 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); | 1109 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); |
1110 | INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); | ||
965 | 1111 | ||
966 | /* | 1112 | /* |
967 | * Let the driver probe the device to detect the capabilities. | 1113 | * Let the driver probe the device to detect the capabilities. |
@@ -1017,6 +1163,27 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1017 | * Stop all work. | 1163 | * Stop all work. |
1018 | */ | 1164 | */ |
1019 | cancel_work_sync(&rt2x00dev->intf_work); | 1165 | cancel_work_sync(&rt2x00dev->intf_work); |
1166 | cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); | ||
1167 | if (rt2x00_is_usb(rt2x00dev)) { | ||
1168 | del_timer_sync(&rt2x00dev->txstatus_timer); | ||
1169 | cancel_work_sync(&rt2x00dev->rxdone_work); | ||
1170 | cancel_work_sync(&rt2x00dev->txdone_work); | ||
1171 | } | ||
1172 | destroy_workqueue(rt2x00dev->workqueue); | ||
1173 | |||
1174 | /* | ||
1175 | * Free the tx status fifo. | ||
1176 | */ | ||
1177 | kfifo_free(&rt2x00dev->txstatus_fifo); | ||
1178 | |||
1179 | /* | ||
1180 | * Kill the tx status tasklet. | ||
1181 | */ | ||
1182 | tasklet_kill(&rt2x00dev->txstatus_tasklet); | ||
1183 | tasklet_kill(&rt2x00dev->pretbtt_tasklet); | ||
1184 | tasklet_kill(&rt2x00dev->tbtt_tasklet); | ||
1185 | tasklet_kill(&rt2x00dev->rxdone_tasklet); | ||
1186 | tasklet_kill(&rt2x00dev->autowake_tasklet); | ||
1020 | 1187 | ||
1021 | /* | 1188 | /* |
1022 | * Uninitialize device. | 1189 | * Uninitialize device. |