Commit 5d7b045b73f4ce9fe53eb1b4fc219e141d0fdc6a

Authored by David S. Miller

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)