diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/mac80211.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mac80211.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index f19baf0dea6b..785c782b166f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -153,7 +153,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
153 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS | | 153 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS | |
154 | IEEE80211_HW_AMPDU_AGGREGATION | | 154 | IEEE80211_HW_AMPDU_AGGREGATION | |
155 | IEEE80211_HW_TIMING_BEACON_ONLY | | 155 | IEEE80211_HW_TIMING_BEACON_ONLY | |
156 | IEEE80211_HW_CONNECTION_MONITOR; | 156 | IEEE80211_HW_CONNECTION_MONITOR | |
157 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | ||
158 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | ||
157 | 159 | ||
158 | hw->queues = IWL_MVM_FIRST_AGG_QUEUE; | 160 | hw->queues = IWL_MVM_FIRST_AGG_QUEUE; |
159 | hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; | 161 | hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; |
@@ -552,6 +554,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
552 | goto out_release; | 554 | goto out_release; |
553 | } | 555 | } |
554 | 556 | ||
557 | iwl_mvm_vif_dbgfs_register(mvm, vif); | ||
555 | goto out_unlock; | 558 | goto out_unlock; |
556 | } | 559 | } |
557 | 560 | ||
@@ -567,7 +570,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
567 | 570 | ||
568 | /* beacon filtering */ | 571 | /* beacon filtering */ |
569 | if (!mvm->bf_allowed_vif && | 572 | if (!mvm->bf_allowed_vif && |
570 | vif->type == NL80211_IFTYPE_STATION && !vif->p2p){ | 573 | vif->type == NL80211_IFTYPE_STATION && !vif->p2p && |
574 | mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BF_UPDATED){ | ||
571 | mvm->bf_allowed_vif = mvmvif; | 575 | mvm->bf_allowed_vif = mvmvif; |
572 | vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; | 576 | vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; |
573 | } | 577 | } |
@@ -719,6 +723,20 @@ out_release: | |||
719 | mutex_unlock(&mvm->mutex); | 723 | mutex_unlock(&mvm->mutex); |
720 | } | 724 | } |
721 | 725 | ||
726 | static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
727 | s8 tx_power) | ||
728 | { | ||
729 | /* FW is in charge of regulatory enforcement */ | ||
730 | struct iwl_reduce_tx_power_cmd reduce_txpwr_cmd = { | ||
731 | .mac_context_id = iwl_mvm_vif_from_mac80211(vif)->id, | ||
732 | .pwr_restriction = cpu_to_le16(tx_power), | ||
733 | }; | ||
734 | |||
735 | return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, CMD_SYNC, | ||
736 | sizeof(reduce_txpwr_cmd), | ||
737 | &reduce_txpwr_cmd); | ||
738 | } | ||
739 | |||
722 | static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed) | 740 | static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed) |
723 | { | 741 | { |
724 | return 0; | 742 | return 0; |
@@ -766,7 +784,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
766 | IWL_ERR(mvm, "failed to update quotas\n"); | 784 | IWL_ERR(mvm, "failed to update quotas\n"); |
767 | return; | 785 | return; |
768 | } | 786 | } |
769 | iwl_mvm_bt_coex_vif_assoc(mvm, vif); | ||
770 | iwl_mvm_configure_mcast_filter(mvm, vif); | 787 | iwl_mvm_configure_mcast_filter(mvm, vif); |
771 | } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { | 788 | } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { |
772 | /* remove AP station now that the MAC is unassoc */ | 789 | /* remove AP station now that the MAC is unassoc */ |
@@ -779,9 +796,15 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
779 | if (ret) | 796 | if (ret) |
780 | IWL_ERR(mvm, "failed to update quotas\n"); | 797 | IWL_ERR(mvm, "failed to update quotas\n"); |
781 | } | 798 | } |
782 | ret = iwl_mvm_power_update_mode(mvm, vif); | 799 | if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD)) { |
783 | if (ret) | 800 | /* Workaround for FW bug, otherwise FW disables device |
784 | IWL_ERR(mvm, "failed to update power mode\n"); | 801 | * power save upon disassociation |
802 | */ | ||
803 | ret = iwl_mvm_power_update_mode(mvm, vif); | ||
804 | if (ret) | ||
805 | IWL_ERR(mvm, "failed to update power mode\n"); | ||
806 | } | ||
807 | iwl_mvm_bt_coex_vif_assoc(mvm, vif); | ||
785 | } else if (changes & BSS_CHANGED_BEACON_INFO) { | 808 | } else if (changes & BSS_CHANGED_BEACON_INFO) { |
786 | /* | 809 | /* |
787 | * We received a beacon _after_ association so | 810 | * We received a beacon _after_ association so |
@@ -794,6 +817,11 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
794 | if (ret) | 817 | if (ret) |
795 | IWL_ERR(mvm, "failed to update power mode\n"); | 818 | IWL_ERR(mvm, "failed to update power mode\n"); |
796 | } | 819 | } |
820 | if (changes & BSS_CHANGED_TXPOWER) { | ||
821 | IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d\n", | ||
822 | bss_conf->txpower); | ||
823 | iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower); | ||
824 | } | ||
797 | } | 825 | } |
798 | 826 | ||
799 | static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | 827 | static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |