Commit 5d7b045b73f4ce9fe53eb1b4fc219e141d0fdc6a
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge tag 'wireless-drivers-for-davem-2015-01-20' of git://git.kernel.org/pub/sc…
…m/linux/kernel/git/kvalo/wireless-drivers ath9k: * fix an IRQ storm caused by commit 872b5d814f99 iwlwifi: * A fix for scan that fixes a firmware assertion * A fix that improves roaming behavior. Same fix has been tested for a while in iwldvm. This is a bit of a work around, but the real fix should be in mac80211 and will come later. * A fix for BARs that avoids a WARNING. * one fix for rfkill while scheduled scan is running. Linus's system hit this issue. WiFi would be unavailable after this has happpened because of bad state in cfg80211. Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 6 changed files Side-by-side Diff
drivers/net/wireless/ath/ath9k/main.c
... | ... | @@ -285,6 +285,7 @@ |
285 | 285 | |
286 | 286 | __ath_cancel_work(sc); |
287 | 287 | |
288 | + disable_irq(sc->irq); | |
288 | 289 | tasklet_disable(&sc->intr_tq); |
289 | 290 | tasklet_disable(&sc->bcon_tasklet); |
290 | 291 | spin_lock_bh(&sc->sc_pcu_lock); |
... | ... | @@ -331,6 +332,7 @@ |
331 | 332 | r = -EIO; |
332 | 333 | |
333 | 334 | out: |
335 | + enable_irq(sc->irq); | |
334 | 336 | spin_unlock_bh(&sc->sc_pcu_lock); |
335 | 337 | tasklet_enable(&sc->bcon_tasklet); |
336 | 338 | tasklet_enable(&sc->intr_tq); |
... | ... | @@ -512,9 +514,6 @@ |
512 | 514 | if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags)) |
513 | 515 | return IRQ_NONE; |
514 | 516 | |
515 | - if (!AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags)) | |
516 | - return IRQ_NONE; | |
517 | - | |
518 | 517 | /* shared irq, not for us */ |
519 | 518 | if (!ath9k_hw_intrpend(ah)) |
520 | 519 | return IRQ_NONE; |
... | ... | @@ -529,7 +528,7 @@ |
529 | 528 | ath9k_debug_sync_cause(sc, sync_cause); |
530 | 529 | status &= ah->imask; /* discard unasked-for bits */ |
531 | 530 | |
532 | - if (AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags)) | |
531 | + if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) | |
533 | 532 | return IRQ_HANDLED; |
534 | 533 | |
535 | 534 | /* |
drivers/net/wireless/iwlwifi/iwl-fw-file.h
... | ... | @@ -246,6 +246,7 @@ |
246 | 246 | * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command, |
247 | 247 | * regardless of the band or the number of the probes. FW will calculate |
248 | 248 | * the actual dwell time. |
249 | + * @IWL_UCODE_TLV_API_SINGLE_SCAN_EBS: EBS is supported for single scans too. | |
249 | 250 | */ |
250 | 251 | enum iwl_ucode_tlv_api { |
251 | 252 | IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), |
... | ... | @@ -257,6 +258,7 @@ |
257 | 258 | IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), |
258 | 259 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), |
259 | 260 | IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13), |
261 | + IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16), | |
260 | 262 | }; |
261 | 263 | |
262 | 264 | /** |
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
... | ... | @@ -653,8 +653,11 @@ |
653 | 653 | }; |
654 | 654 | |
655 | 655 | /* iwl_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S |
656 | - * @flags: enum iwl_scan_channel_flgs | |
657 | - * @non_ebs_ratio: how many regular scan iteration before EBS | |
656 | + * @flags: enum iwl_scan_channel_flags | |
657 | + * @non_ebs_ratio: defines the ratio of number of scan iterations where EBS is | |
658 | + * involved. | |
659 | + * 1 - EBS is disabled. | |
660 | + * 2 - every second scan will be full scan(and so on). | |
658 | 661 | */ |
659 | 662 | struct iwl_scan_channel_opt { |
660 | 663 | __le16 flags; |
drivers/net/wireless/iwlwifi/mvm/mac80211.c
... | ... | @@ -3343,18 +3343,16 @@ |
3343 | 3343 | msk |= mvmsta->tfd_queue_msk; |
3344 | 3344 | } |
3345 | 3345 | |
3346 | - if (drop) { | |
3347 | - if (iwl_mvm_flush_tx_path(mvm, msk, true)) | |
3348 | - IWL_ERR(mvm, "flush request fail\n"); | |
3349 | - mutex_unlock(&mvm->mutex); | |
3350 | - } else { | |
3351 | - mutex_unlock(&mvm->mutex); | |
3346 | + msk &= ~BIT(vif->hw_queue[IEEE80211_AC_VO]); | |
3352 | 3347 | |
3353 | - /* this can take a while, and we may need/want other operations | |
3354 | - * to succeed while doing this, so do it without the mutex held | |
3355 | - */ | |
3356 | - iwl_trans_wait_tx_queue_empty(mvm->trans, msk); | |
3357 | - } | |
3348 | + if (iwl_mvm_flush_tx_path(mvm, msk, true)) | |
3349 | + IWL_ERR(mvm, "flush request fail\n"); | |
3350 | + mutex_unlock(&mvm->mutex); | |
3351 | + | |
3352 | + /* this can take a while, and we may need/want other operations | |
3353 | + * to succeed while doing this, so do it without the mutex held | |
3354 | + */ | |
3355 | + iwl_trans_wait_tx_queue_empty(mvm->trans, msk); | |
3358 | 3356 | } |
3359 | 3357 | |
3360 | 3358 | const struct ieee80211_ops iwl_mvm_hw_ops = { |
drivers/net/wireless/iwlwifi/mvm/scan.c
... | ... | @@ -72,6 +72,8 @@ |
72 | 72 | |
73 | 73 | #define IWL_PLCP_QUIET_THRESH 1 |
74 | 74 | #define IWL_ACTIVE_QUIET_TIME 10 |
75 | +#define IWL_DENSE_EBS_SCAN_RATIO 5 | |
76 | +#define IWL_SPARSE_EBS_SCAN_RATIO 1 | |
75 | 77 | |
76 | 78 | struct iwl_mvm_scan_params { |
77 | 79 | u32 max_out_time; |
... | ... | @@ -1105,6 +1107,12 @@ |
1105 | 1107 | return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN, |
1106 | 1108 | notify); |
1107 | 1109 | |
1110 | + if (mvm->scan_status == IWL_MVM_SCAN_NONE) | |
1111 | + return 0; | |
1112 | + | |
1113 | + if (iwl_mvm_is_radio_killed(mvm)) | |
1114 | + goto out; | |
1115 | + | |
1108 | 1116 | if (mvm->scan_status != IWL_MVM_SCAN_SCHED && |
1109 | 1117 | (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) || |
1110 | 1118 | mvm->scan_status != IWL_MVM_SCAN_OS)) { |
... | ... | @@ -1141,6 +1149,7 @@ |
1141 | 1149 | if (mvm->scan_status == IWL_MVM_SCAN_OS) |
1142 | 1150 | iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); |
1143 | 1151 | |
1152 | +out: | |
1144 | 1153 | mvm->scan_status = IWL_MVM_SCAN_NONE; |
1145 | 1154 | |
1146 | 1155 | if (notify) { |
... | ... | @@ -1297,18 +1306,6 @@ |
1297 | 1306 | cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); |
1298 | 1307 | cmd->iter_num = cpu_to_le32(1); |
1299 | 1308 | |
1300 | - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT && | |
1301 | - mvm->last_ebs_successful) { | |
1302 | - cmd->channel_opt[0].flags = | |
1303 | - cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | |
1304 | - IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | |
1305 | - IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | |
1306 | - cmd->channel_opt[1].flags = | |
1307 | - cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | |
1308 | - IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | |
1309 | - IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | |
1310 | - } | |
1311 | - | |
1312 | 1309 | if (iwl_mvm_rrm_scan_needed(mvm)) |
1313 | 1310 | cmd->scan_flags |= |
1314 | 1311 | cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED); |
... | ... | @@ -1383,6 +1380,22 @@ |
1383 | 1380 | cmd->schedule[1].iterations = 0; |
1384 | 1381 | cmd->schedule[1].full_scan_mul = 0; |
1385 | 1382 | |
1383 | + if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS && | |
1384 | + mvm->last_ebs_successful) { | |
1385 | + cmd->channel_opt[0].flags = | |
1386 | + cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | |
1387 | + IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | |
1388 | + IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | |
1389 | + cmd->channel_opt[0].non_ebs_ratio = | |
1390 | + cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO); | |
1391 | + cmd->channel_opt[1].flags = | |
1392 | + cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | |
1393 | + IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | |
1394 | + IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | |
1395 | + cmd->channel_opt[1].non_ebs_ratio = | |
1396 | + cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO); | |
1397 | + } | |
1398 | + | |
1386 | 1399 | for (i = 1; i <= req->req.n_ssids; i++) |
1387 | 1400 | ssid_bitmap |= BIT(i); |
1388 | 1401 | |
... | ... | @@ -1482,6 +1495,22 @@ |
1482 | 1495 | cmd->schedule[1].delay = cpu_to_le16(req->interval / MSEC_PER_SEC); |
1483 | 1496 | cmd->schedule[1].iterations = 0xff; |
1484 | 1497 | cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER; |
1498 | + | |
1499 | + if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT && | |
1500 | + mvm->last_ebs_successful) { | |
1501 | + cmd->channel_opt[0].flags = | |
1502 | + cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | |
1503 | + IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | |
1504 | + IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | |
1505 | + cmd->channel_opt[0].non_ebs_ratio = | |
1506 | + cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO); | |
1507 | + cmd->channel_opt[1].flags = | |
1508 | + cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | |
1509 | + IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | |
1510 | + IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | |
1511 | + cmd->channel_opt[1].non_ebs_ratio = | |
1512 | + cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO); | |
1513 | + } | |
1485 | 1514 | |
1486 | 1515 | iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels, |
1487 | 1516 | ssid_bitmap, cmd); |
drivers/net/wireless/iwlwifi/mvm/tx.c
... | ... | @@ -90,8 +90,6 @@ |
90 | 90 | |
91 | 91 | if (ieee80211_is_probe_resp(fc)) |
92 | 92 | tx_flags |= TX_CMD_FLG_TSF; |
93 | - else if (ieee80211_is_back_req(fc)) | |
94 | - tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR; | |
95 | 93 | |
96 | 94 | if (ieee80211_has_morefrags(fc)) |
97 | 95 | tx_flags |= TX_CMD_FLG_MORE_FRAG; |
... | ... | @@ -100,6 +98,15 @@ |
100 | 98 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
101 | 99 | tx_cmd->tid_tspec = qc[0] & 0xf; |
102 | 100 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL; |
101 | + } else if (ieee80211_is_back_req(fc)) { | |
102 | + struct ieee80211_bar *bar = (void *)skb->data; | |
103 | + u16 control = le16_to_cpu(bar->control); | |
104 | + | |
105 | + tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR; | |
106 | + tx_cmd->tid_tspec = (control & | |
107 | + IEEE80211_BAR_CTRL_TID_INFO_MASK) >> | |
108 | + IEEE80211_BAR_CTRL_TID_INFO_SHIFT; | |
109 | + WARN_ON_ONCE(tx_cmd->tid_tspec >= IWL_MAX_TID_COUNT); | |
103 | 110 | } else { |
104 | 111 | tx_cmd->tid_tspec = IWL_TID_NON_QOS; |
105 | 112 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) |