diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2015-03-12 08:38:26 -0400 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2015-03-12 08:38:26 -0400 |
commit | 208d271a3f5388672b3d7ec141e975abd84ab3da (patch) | |
tree | 6a181c31d00e896338b758ebda01226597953b1e | |
parent | e111e9685790ccd9acce5de51fa7ed6b9ae8a746 (diff) | |
parent | 060b4460c47143440e77e6721f68ef756674d207 (diff) |
Merge branch 'iwlwifi-fixes' into iwlwifi-next
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/mac80211.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/coex.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mac80211.c | 38 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/scan.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/time-event.c | 11 |
6 files changed, 59 insertions, 26 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 47e64e8b9517..cceb026e0793 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -1114,16 +1114,17 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
1114 | scd_queues &= ~(BIT(IWL_IPAN_CMD_QUEUE_NUM) | | 1114 | scd_queues &= ~(BIT(IWL_IPAN_CMD_QUEUE_NUM) | |
1115 | BIT(IWL_DEFAULT_CMD_QUEUE_NUM)); | 1115 | BIT(IWL_DEFAULT_CMD_QUEUE_NUM)); |
1116 | 1116 | ||
1117 | if (vif) | 1117 | if (drop) { |
1118 | scd_queues &= ~BIT(vif->hw_queue[IEEE80211_AC_VO]); | 1118 | IWL_DEBUG_TX_QUEUES(priv, "Flushing SCD queues: 0x%x\n", |
1119 | 1119 | scd_queues); | |
1120 | IWL_DEBUG_TX_QUEUES(priv, "Flushing SCD queues: 0x%x\n", scd_queues); | 1120 | if (iwlagn_txfifo_flush(priv, scd_queues)) { |
1121 | if (iwlagn_txfifo_flush(priv, scd_queues)) { | 1121 | IWL_ERR(priv, "flush request fail\n"); |
1122 | IWL_ERR(priv, "flush request fail\n"); | 1122 | goto done; |
1123 | goto done; | 1123 | } |
1124 | } | 1124 | } |
1125 | |||
1125 | IWL_DEBUG_TX_QUEUES(priv, "wait transmit/flush all frames\n"); | 1126 | IWL_DEBUG_TX_QUEUES(priv, "wait transmit/flush all frames\n"); |
1126 | iwl_trans_wait_tx_queue_empty(priv->trans, 0xffffffff); | 1127 | iwl_trans_wait_tx_queue_empty(priv->trans, scd_queues); |
1127 | done: | 1128 | done: |
1128 | mutex_unlock(&priv->mutex); | 1129 | mutex_unlock(&priv->mutex); |
1129 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1130 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c index c7358a9d5b71..770b0e2a9b46 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex.c | |||
@@ -579,7 +579,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, | |||
579 | if (!vif->bss_conf.assoc) | 579 | if (!vif->bss_conf.assoc) |
580 | smps_mode = IEEE80211_SMPS_AUTOMATIC; | 580 | smps_mode = IEEE80211_SMPS_AUTOMATIC; |
581 | 581 | ||
582 | if (IWL_COEX_IS_RRC_ON(mvm->last_bt_notif.ttc_rrc_status, | 582 | if (mvmvif->phy_ctxt && |
583 | IWL_COEX_IS_RRC_ON(mvm->last_bt_notif.ttc_rrc_status, | ||
583 | mvmvif->phy_ctxt->id)) | 584 | mvmvif->phy_ctxt->id)) |
584 | smps_mode = IEEE80211_SMPS_AUTOMATIC; | 585 | smps_mode = IEEE80211_SMPS_AUTOMATIC; |
585 | 586 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c index 897dd5330b0d..4f303639147b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | |||
@@ -891,7 +891,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, | |||
891 | if (!vif->bss_conf.assoc) | 891 | if (!vif->bss_conf.assoc) |
892 | smps_mode = IEEE80211_SMPS_AUTOMATIC; | 892 | smps_mode = IEEE80211_SMPS_AUTOMATIC; |
893 | 893 | ||
894 | if (data->notif->rrc_enabled & BIT(mvmvif->phy_ctxt->id)) | 894 | if (mvmvif->phy_ctxt && |
895 | data->notif->rrc_enabled & BIT(mvmvif->phy_ctxt->id)) | ||
895 | smps_mode = IEEE80211_SMPS_AUTOMATIC; | 896 | smps_mode = IEEE80211_SMPS_AUTOMATIC; |
896 | 897 | ||
897 | IWL_DEBUG_COEX(data->mvm, | 898 | IWL_DEBUG_COEX(data->mvm, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 6b3f4d0284a7..302c8cc50f25 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -510,7 +510,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
510 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 510 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
511 | &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ]; | 511 | &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ]; |
512 | 512 | ||
513 | if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_BEAMFORMER) | 513 | if ((mvm->fw->ucode_capa.capa[0] & |
514 | IWL_UCODE_TLV_CAPA_BEAMFORMER) && | ||
515 | (mvm->fw->ucode_capa.api[0] & | ||
516 | IWL_UCODE_TLV_API_LQ_SS_PARAMS)) | ||
514 | hw->wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap.cap |= | 517 | hw->wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap.cap |= |
515 | IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; | 518 | IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; |
516 | } | 519 | } |
@@ -2385,7 +2388,19 @@ static void iwl_mvm_mac_cancel_hw_scan(struct ieee80211_hw *hw, | |||
2385 | 2388 | ||
2386 | mutex_lock(&mvm->mutex); | 2389 | mutex_lock(&mvm->mutex); |
2387 | 2390 | ||
2388 | iwl_mvm_cancel_scan(mvm); | 2391 | /* Due to a race condition, it's possible that mac80211 asks |
2392 | * us to stop a hw_scan when it's already stopped. This can | ||
2393 | * happen, for instance, if we stopped the scan ourselves, | ||
2394 | * called ieee80211_scan_completed() and the userspace called | ||
2395 | * cancel scan scan before ieee80211_scan_work() could run. | ||
2396 | * To handle that, simply return if the scan is not running. | ||
2397 | */ | ||
2398 | /* FIXME: for now, we ignore this race for UMAC scans, since | ||
2399 | * they don't set the scan_status. | ||
2400 | */ | ||
2401 | if ((mvm->scan_status == IWL_MVM_SCAN_OS) || | ||
2402 | (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN)) | ||
2403 | iwl_mvm_cancel_scan(mvm); | ||
2389 | 2404 | ||
2390 | mutex_unlock(&mvm->mutex); | 2405 | mutex_unlock(&mvm->mutex); |
2391 | } | 2406 | } |
@@ -2743,12 +2758,29 @@ static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw, | |||
2743 | int ret; | 2758 | int ret; |
2744 | 2759 | ||
2745 | mutex_lock(&mvm->mutex); | 2760 | mutex_lock(&mvm->mutex); |
2761 | |||
2762 | /* Due to a race condition, it's possible that mac80211 asks | ||
2763 | * us to stop a sched_scan when it's already stopped. This | ||
2764 | * can happen, for instance, if we stopped the scan ourselves, | ||
2765 | * called ieee80211_sched_scan_stopped() and the userspace called | ||
2766 | * stop sched scan scan before ieee80211_sched_scan_stopped_work() | ||
2767 | * could run. To handle this, simply return if the scan is | ||
2768 | * not running. | ||
2769 | */ | ||
2770 | /* FIXME: for now, we ignore this race for UMAC scans, since | ||
2771 | * they don't set the scan_status. | ||
2772 | */ | ||
2773 | if (mvm->scan_status != IWL_MVM_SCAN_SCHED && | ||
2774 | !(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN)) { | ||
2775 | mutex_unlock(&mvm->mutex); | ||
2776 | return 0; | ||
2777 | } | ||
2778 | |||
2746 | ret = iwl_mvm_scan_offload_stop(mvm, false); | 2779 | ret = iwl_mvm_scan_offload_stop(mvm, false); |
2747 | mutex_unlock(&mvm->mutex); | 2780 | mutex_unlock(&mvm->mutex); |
2748 | iwl_mvm_wait_for_async_handlers(mvm); | 2781 | iwl_mvm_wait_for_async_handlers(mvm); |
2749 | 2782 | ||
2750 | return ret; | 2783 | return ret; |
2751 | |||
2752 | } | 2784 | } |
2753 | 2785 | ||
2754 | static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, | 2786 | static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index f0946b5dd7c8..a75bb150ea27 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
@@ -587,8 +587,10 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) | |||
587 | if (mvm->scan_status == IWL_MVM_SCAN_NONE) | 587 | if (mvm->scan_status == IWL_MVM_SCAN_NONE) |
588 | return 0; | 588 | return 0; |
589 | 589 | ||
590 | if (iwl_mvm_is_radio_killed(mvm)) | 590 | if (iwl_mvm_is_radio_killed(mvm)) { |
591 | ret = 0; | ||
591 | goto out; | 592 | goto out; |
593 | } | ||
592 | 594 | ||
593 | iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done, | 595 | iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done, |
594 | scan_done_notif, | 596 | scan_done_notif, |
@@ -600,16 +602,14 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) | |||
600 | IWL_DEBUG_SCAN(mvm, "Send stop %sscan failed %d\n", | 602 | IWL_DEBUG_SCAN(mvm, "Send stop %sscan failed %d\n", |
601 | sched ? "offloaded " : "", ret); | 603 | sched ? "offloaded " : "", ret); |
602 | iwl_remove_notification(&mvm->notif_wait, &wait_scan_done); | 604 | iwl_remove_notification(&mvm->notif_wait, &wait_scan_done); |
603 | return ret; | 605 | goto out; |
604 | } | 606 | } |
605 | 607 | ||
606 | IWL_DEBUG_SCAN(mvm, "Successfully sent stop %sscan\n", | 608 | IWL_DEBUG_SCAN(mvm, "Successfully sent stop %sscan\n", |
607 | sched ? "offloaded " : ""); | 609 | sched ? "offloaded " : ""); |
608 | 610 | ||
609 | ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_done, 1 * HZ); | 611 | ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_done, 1 * HZ); |
610 | if (ret) | 612 | out: |
611 | return ret; | ||
612 | |||
613 | /* | 613 | /* |
614 | * Clear the scan status so the next scan requests will succeed. This | 614 | * Clear the scan status so the next scan requests will succeed. This |
615 | * also ensures the Rx handler doesn't do anything, as the scan was | 615 | * also ensures the Rx handler doesn't do anything, as the scan was |
@@ -619,7 +619,6 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) | |||
619 | if (mvm->scan_status == IWL_MVM_SCAN_OS) | 619 | if (mvm->scan_status == IWL_MVM_SCAN_OS) |
620 | iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); | 620 | iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); |
621 | 621 | ||
622 | out: | ||
623 | mvm->scan_status = IWL_MVM_SCAN_NONE; | 622 | mvm->scan_status = IWL_MVM_SCAN_NONE; |
624 | 623 | ||
625 | if (notify) { | 624 | if (notify) { |
@@ -629,7 +628,7 @@ out: | |||
629 | ieee80211_scan_completed(mvm->hw, true); | 628 | ieee80211_scan_completed(mvm->hw, true); |
630 | } | 629 | } |
631 | 630 | ||
632 | return 0; | 631 | return ret; |
633 | } | 632 | } |
634 | 633 | ||
635 | static void iwl_mvm_unified_scan_fill_tx_cmd(struct iwl_mvm *mvm, | 634 | static void iwl_mvm_unified_scan_fill_tx_cmd(struct iwl_mvm *mvm, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 1dbfcc43d82c..8d179ab67cc2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c | |||
@@ -197,6 +197,8 @@ iwl_mvm_te_handle_notify_csa(struct iwl_mvm *mvm, | |||
197 | struct iwl_time_event_notif *notif) | 197 | struct iwl_time_event_notif *notif) |
198 | { | 198 | { |
199 | if (!le32_to_cpu(notif->status)) { | 199 | if (!le32_to_cpu(notif->status)) { |
200 | if (te_data->vif->type == NL80211_IFTYPE_STATION) | ||
201 | ieee80211_connection_loss(te_data->vif); | ||
200 | IWL_DEBUG_TE(mvm, "CSA time event failed to start\n"); | 202 | IWL_DEBUG_TE(mvm, "CSA time event failed to start\n"); |
201 | iwl_mvm_te_clear_data(mvm, te_data); | 203 | iwl_mvm_te_clear_data(mvm, te_data); |
202 | return; | 204 | return; |
@@ -756,8 +758,7 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm) | |||
756 | * request | 758 | * request |
757 | */ | 759 | */ |
758 | list_for_each_entry(te_data, &mvm->time_event_list, list) { | 760 | list_for_each_entry(te_data, &mvm->time_event_list, list) { |
759 | if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE && | 761 | if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) { |
760 | te_data->running) { | ||
761 | mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); | 762 | mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); |
762 | is_p2p = true; | 763 | is_p2p = true; |
763 | goto remove_te; | 764 | goto remove_te; |
@@ -772,10 +773,8 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm) | |||
772 | * request | 773 | * request |
773 | */ | 774 | */ |
774 | list_for_each_entry(te_data, &mvm->aux_roc_te_list, list) { | 775 | list_for_each_entry(te_data, &mvm->aux_roc_te_list, list) { |
775 | if (te_data->running) { | 776 | mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); |
776 | mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); | 777 | goto remove_te; |
777 | goto remove_te; | ||
778 | } | ||
779 | } | 778 | } |
780 | 779 | ||
781 | remove_te: | 780 | remove_te: |