diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-06-21 15:42:30 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-06-21 15:42:30 -0400 |
commit | 7d2a47aab2a511c87a96238977e04e6378969d45 (patch) | |
tree | e3765af6d4b292d8f3c013a5962324eab683a931 /drivers/net/wireless/iwlegacy | |
parent | fedaf4ffc224a194e2d13a3ec2abe5df0bc94258 (diff) | |
parent | b887664d882ee4f6a67e0bf05e5f141d32fcc067 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts:
net/wireless/nl80211.c
Diffstat (limited to 'drivers/net/wireless/iwlegacy')
-rw-r--r-- | drivers/net/wireless/iwlegacy/3945-mac.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/3945.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/4965-mac.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/common.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/common.h | 41 |
5 files changed, 88 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index dce5e8f030b2..9581d07a4242 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c | |||
@@ -3727,7 +3727,8 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3727 | * 5. Setup HW Constants | 3727 | * 5. Setup HW Constants |
3728 | * ********************/ | 3728 | * ********************/ |
3729 | /* Device-specific setup */ | 3729 | /* Device-specific setup */ |
3730 | if (il3945_hw_set_hw_params(il)) { | 3730 | err = il3945_hw_set_hw_params(il); |
3731 | if (err) { | ||
3731 | IL_ERR("failed to set hw settings\n"); | 3732 | IL_ERR("failed to set hw settings\n"); |
3732 | goto out_eeprom_free; | 3733 | goto out_eeprom_free; |
3733 | } | 3734 | } |
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index dc1e6da9976a..c092033945cc 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c | |||
@@ -331,6 +331,19 @@ il3945_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) | |||
331 | return; | 331 | return; |
332 | } | 332 | } |
333 | 333 | ||
334 | /* | ||
335 | * Firmware will not transmit frame on passive channel, if it not yet | ||
336 | * received some valid frame on that channel. When this error happen | ||
337 | * we have to wait until firmware will unblock itself i.e. when we | ||
338 | * note received beacon or other frame. We unblock queues in | ||
339 | * il3945_pass_packet_to_mac80211 or in il_mac_bss_info_changed. | ||
340 | */ | ||
341 | if (unlikely((status & TX_STATUS_MSK) == TX_STATUS_FAIL_PASSIVE_NO_RX) && | ||
342 | il->iw_mode == NL80211_IFTYPE_STATION) { | ||
343 | il_stop_queues_by_reason(il, IL_STOP_REASON_PASSIVE); | ||
344 | D_INFO("Stopped queues - RX waiting on passive channel\n"); | ||
345 | } | ||
346 | |||
334 | txq->time_stamp = jiffies; | 347 | txq->time_stamp = jiffies; |
335 | info = IEEE80211_SKB_CB(txq->skbs[txq->q.read_ptr]); | 348 | info = IEEE80211_SKB_CB(txq->skbs[txq->q.read_ptr]); |
336 | ieee80211_tx_info_clear_status(info); | 349 | ieee80211_tx_info_clear_status(info); |
@@ -488,6 +501,11 @@ il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb, | |||
488 | return; | 501 | return; |
489 | } | 502 | } |
490 | 503 | ||
504 | if (unlikely(test_bit(IL_STOP_REASON_PASSIVE, &il->stop_reason))) { | ||
505 | il_wake_queues_by_reason(il, IL_STOP_REASON_PASSIVE); | ||
506 | D_INFO("Woke queues - frame received on passive channel\n"); | ||
507 | } | ||
508 | |||
491 | skb = dev_alloc_skb(128); | 509 | skb = dev_alloc_skb(128); |
492 | if (!skb) { | 510 | if (!skb) { |
493 | IL_ERR("dev_alloc_skb failed\n"); | 511 | IL_ERR("dev_alloc_skb failed\n"); |
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 3c4899b7c1ab..b9b2bb51e605 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c | |||
@@ -588,6 +588,11 @@ il4965_pass_packet_to_mac80211(struct il_priv *il, struct ieee80211_hdr *hdr, | |||
588 | return; | 588 | return; |
589 | } | 589 | } |
590 | 590 | ||
591 | if (unlikely(test_bit(IL_STOP_REASON_PASSIVE, &il->stop_reason))) { | ||
592 | il_wake_queues_by_reason(il, IL_STOP_REASON_PASSIVE); | ||
593 | D_INFO("Woke queues - frame received on passive channel\n"); | ||
594 | } | ||
595 | |||
591 | /* In case of HW accelerated crypto and bad decryption, drop */ | 596 | /* In case of HW accelerated crypto and bad decryption, drop */ |
592 | if (!il->cfg->mod_params->sw_crypto && | 597 | if (!il->cfg->mod_params->sw_crypto && |
593 | il_set_decrypted_flag(il, hdr, ampdu_status, stats)) | 598 | il_set_decrypted_flag(il, hdr, ampdu_status, stats)) |
@@ -2806,6 +2811,19 @@ il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) | |||
2806 | return; | 2811 | return; |
2807 | } | 2812 | } |
2808 | 2813 | ||
2814 | /* | ||
2815 | * Firmware will not transmit frame on passive channel, if it not yet | ||
2816 | * received some valid frame on that channel. When this error happen | ||
2817 | * we have to wait until firmware will unblock itself i.e. when we | ||
2818 | * note received beacon or other frame. We unblock queues in | ||
2819 | * il4965_pass_packet_to_mac80211 or in il_mac_bss_info_changed. | ||
2820 | */ | ||
2821 | if (unlikely((status & TX_STATUS_MSK) == TX_STATUS_FAIL_PASSIVE_NO_RX) && | ||
2822 | il->iw_mode == NL80211_IFTYPE_STATION) { | ||
2823 | il_stop_queues_by_reason(il, IL_STOP_REASON_PASSIVE); | ||
2824 | D_INFO("Stopped queues - RX waiting on passive channel\n"); | ||
2825 | } | ||
2826 | |||
2809 | spin_lock_irqsave(&il->sta_lock, flags); | 2827 | spin_lock_irqsave(&il->sta_lock, flags); |
2810 | if (txq->sched_retry) { | 2828 | if (txq->sched_retry) { |
2811 | const u32 scd_ssn = il4965_get_scd_ssn(tx_resp); | 2829 | const u32 scd_ssn = il4965_get_scd_ssn(tx_resp); |
@@ -5741,7 +5759,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length) | |||
5741 | hw->flags = | 5759 | hw->flags = |
5742 | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION | | 5760 | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION | |
5743 | IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC | IEEE80211_HW_SPECTRUM_MGMT | | 5761 | IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC | IEEE80211_HW_SPECTRUM_MGMT | |
5744 | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | 5762 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS | |
5763 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | ||
5745 | if (il->cfg->sku & IL_SKU_N) | 5764 | if (il->cfg->sku & IL_SKU_N) |
5746 | hw->flags |= | 5765 | hw->flags |= |
5747 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | 5766 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | |
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index e9a3cbc409ae..3195aad440dd 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c | |||
@@ -5307,6 +5307,17 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
5307 | D_MAC80211("BSSID %pM\n", bss_conf->bssid); | 5307 | D_MAC80211("BSSID %pM\n", bss_conf->bssid); |
5308 | 5308 | ||
5309 | /* | 5309 | /* |
5310 | * On passive channel we wait with blocked queues to see if | ||
5311 | * there is traffic on that channel. If no frame will be | ||
5312 | * received (what is very unlikely since scan detects AP on | ||
5313 | * that channel, but theoretically possible), mac80211 associate | ||
5314 | * procedure will time out and mac80211 will call us with NULL | ||
5315 | * bssid. We have to unblock queues on such condition. | ||
5316 | */ | ||
5317 | if (is_zero_ether_addr(bss_conf->bssid)) | ||
5318 | il_wake_queues_by_reason(il, IL_STOP_REASON_PASSIVE); | ||
5319 | |||
5320 | /* | ||
5310 | * If there is currently a HW scan going on in the background, | 5321 | * If there is currently a HW scan going on in the background, |
5311 | * then we need to cancel it, otherwise sometimes we are not | 5322 | * then we need to cancel it, otherwise sometimes we are not |
5312 | * able to authenticate (FIXME: why ?) | 5323 | * able to authenticate (FIXME: why ?) |
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 4caaf52986a4..83f8ed8a5528 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h | |||
@@ -1299,6 +1299,8 @@ struct il_priv { | |||
1299 | /* queue refcounts */ | 1299 | /* queue refcounts */ |
1300 | #define IL_MAX_HW_QUEUES 32 | 1300 | #define IL_MAX_HW_QUEUES 32 |
1301 | unsigned long queue_stopped[BITS_TO_LONGS(IL_MAX_HW_QUEUES)]; | 1301 | unsigned long queue_stopped[BITS_TO_LONGS(IL_MAX_HW_QUEUES)]; |
1302 | #define IL_STOP_REASON_PASSIVE 0 | ||
1303 | unsigned long stop_reason; | ||
1302 | /* for each AC */ | 1304 | /* for each AC */ |
1303 | atomic_t queue_stop_count[4]; | 1305 | atomic_t queue_stop_count[4]; |
1304 | 1306 | ||
@@ -2257,6 +2259,19 @@ il_set_swq_id(struct il_tx_queue *txq, u8 ac, u8 hwq) | |||
2257 | } | 2259 | } |
2258 | 2260 | ||
2259 | static inline void | 2261 | static inline void |
2262 | _il_wake_queue(struct il_priv *il, u8 ac) | ||
2263 | { | ||
2264 | if (atomic_dec_return(&il->queue_stop_count[ac]) <= 0) | ||
2265 | ieee80211_wake_queue(il->hw, ac); | ||
2266 | } | ||
2267 | |||
2268 | static inline void | ||
2269 | _il_stop_queue(struct il_priv *il, u8 ac) | ||
2270 | { | ||
2271 | if (atomic_inc_return(&il->queue_stop_count[ac]) > 0) | ||
2272 | ieee80211_stop_queue(il->hw, ac); | ||
2273 | } | ||
2274 | static inline void | ||
2260 | il_wake_queue(struct il_priv *il, struct il_tx_queue *txq) | 2275 | il_wake_queue(struct il_priv *il, struct il_tx_queue *txq) |
2261 | { | 2276 | { |
2262 | u8 queue = txq->swq_id; | 2277 | u8 queue = txq->swq_id; |
@@ -2264,8 +2279,7 @@ il_wake_queue(struct il_priv *il, struct il_tx_queue *txq) | |||
2264 | u8 hwq = (queue >> 2) & 0x1f; | 2279 | u8 hwq = (queue >> 2) & 0x1f; |
2265 | 2280 | ||
2266 | if (test_and_clear_bit(hwq, il->queue_stopped)) | 2281 | if (test_and_clear_bit(hwq, il->queue_stopped)) |
2267 | if (atomic_dec_return(&il->queue_stop_count[ac]) <= 0) | 2282 | _il_wake_queue(il, ac); |
2268 | ieee80211_wake_queue(il->hw, ac); | ||
2269 | } | 2283 | } |
2270 | 2284 | ||
2271 | static inline void | 2285 | static inline void |
@@ -2276,8 +2290,27 @@ il_stop_queue(struct il_priv *il, struct il_tx_queue *txq) | |||
2276 | u8 hwq = (queue >> 2) & 0x1f; | 2290 | u8 hwq = (queue >> 2) & 0x1f; |
2277 | 2291 | ||
2278 | if (!test_and_set_bit(hwq, il->queue_stopped)) | 2292 | if (!test_and_set_bit(hwq, il->queue_stopped)) |
2279 | if (atomic_inc_return(&il->queue_stop_count[ac]) > 0) | 2293 | _il_stop_queue(il, ac); |
2280 | ieee80211_stop_queue(il->hw, ac); | 2294 | } |
2295 | |||
2296 | static inline void | ||
2297 | il_wake_queues_by_reason(struct il_priv *il, int reason) | ||
2298 | { | ||
2299 | u8 ac; | ||
2300 | |||
2301 | if (test_and_clear_bit(reason, &il->stop_reason)) | ||
2302 | for (ac = 0; ac < 4; ac++) | ||
2303 | _il_wake_queue(il, ac); | ||
2304 | } | ||
2305 | |||
2306 | static inline void | ||
2307 | il_stop_queues_by_reason(struct il_priv *il, int reason) | ||
2308 | { | ||
2309 | u8 ac; | ||
2310 | |||
2311 | if (!test_and_set_bit(reason, &il->stop_reason)) | ||
2312 | for (ac = 0; ac < 4; ac++) | ||
2313 | _il_stop_queue(il, ac); | ||
2281 | } | 2314 | } |
2282 | 2315 | ||
2283 | #ifdef ieee80211_stop_queue | 2316 | #ifdef ieee80211_stop_queue |