aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlegacy
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-06-21 15:42:30 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-06-21 15:42:30 -0400
commit7d2a47aab2a511c87a96238977e04e6378969d45 (patch)
treee3765af6d4b292d8f3c013a5962324eab683a931 /drivers/net/wireless/iwlegacy
parentfedaf4ffc224a194e2d13a3ec2abe5df0bc94258 (diff)
parentb887664d882ee4f6a67e0bf05e5f141d32fcc067 (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.c3
-rw-r--r--drivers/net/wireless/iwlegacy/3945.c18
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c21
-rw-r--r--drivers/net/wireless/iwlegacy/common.c11
-rw-r--r--drivers/net/wireless/iwlegacy/common.h41
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
2259static inline void 2261static 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
2268static 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}
2274static inline void
2260il_wake_queue(struct il_priv *il, struct il_tx_queue *txq) 2275il_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
2271static inline void 2285static 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
2296static inline void
2297il_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
2306static inline void
2307il_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