diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-04-10 14:10:24 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-04-10 14:10:24 -0400 |
commit | d72c728210fa803a21203360c0f40b32972d795a (patch) | |
tree | 95189c1a9181e3317dea2a139f390f5013e921a2 /drivers/net | |
parent | 655d8e2328a6ef6b6b514609a4c1e33508d3a1da (diff) | |
parent | 2d055afdcada4bd8b510e9d2a8566fbded3c9696 (diff) |
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
Diffstat (limited to 'drivers/net')
22 files changed, 678 insertions, 219 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index 019d433900ef..e575b9b0cda8 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h | |||
@@ -73,6 +73,8 @@ | |||
73 | /* AUX (TX during scan dwell) queue */ | 73 | /* AUX (TX during scan dwell) queue */ |
74 | #define IWL_AUX_QUEUE 10 | 74 | #define IWL_AUX_QUEUE 10 |
75 | 75 | ||
76 | #define IWL_INVALID_STATION 255 | ||
77 | |||
76 | /* device operations */ | 78 | /* device operations */ |
77 | extern struct iwl_lib_ops iwl1000_lib; | 79 | extern struct iwl_lib_ops iwl1000_lib; |
78 | extern struct iwl_lib_ops iwl2000_lib; | 80 | extern struct iwl_lib_ops iwl2000_lib; |
@@ -176,7 +178,7 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr); | |||
176 | /* lib */ | 178 | /* lib */ |
177 | int iwlagn_send_tx_power(struct iwl_priv *priv); | 179 | int iwlagn_send_tx_power(struct iwl_priv *priv); |
178 | void iwlagn_temperature(struct iwl_priv *priv); | 180 | void iwlagn_temperature(struct iwl_priv *priv); |
179 | int iwlagn_txfifo_flush(struct iwl_priv *priv); | 181 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u32 scd_q_msk); |
180 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv); | 182 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv); |
181 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); | 183 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); |
182 | int iwl_send_statistics_request(struct iwl_priv *priv, | 184 | int iwl_send_statistics_request(struct iwl_priv *priv, |
@@ -210,6 +212,8 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
210 | struct ieee80211_sta *sta, u16 tid, u8 buf_size); | 212 | struct ieee80211_sta *sta, u16 tid, u8 buf_size); |
211 | int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | 213 | int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, |
212 | struct ieee80211_sta *sta, u16 tid); | 214 | struct ieee80211_sta *sta, u16 tid); |
215 | int iwlagn_tx_agg_flush(struct iwl_priv *priv, struct ieee80211_vif *vif, | ||
216 | struct ieee80211_sta *sta, u16 tid); | ||
213 | int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | 217 | int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, |
214 | struct iwl_rx_cmd_buffer *rxb, | 218 | struct iwl_rx_cmd_buffer *rxb, |
215 | struct iwl_device_cmd *cmd); | 219 | struct iwl_device_cmd *cmd); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 87c006c9c573..54f553380aa8 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c | |||
@@ -136,7 +136,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, | |||
136 | * 1. acquire mutex before calling | 136 | * 1. acquire mutex before calling |
137 | * 2. make sure rf is on and not in exit state | 137 | * 2. make sure rf is on and not in exit state |
138 | */ | 138 | */ |
139 | int iwlagn_txfifo_flush(struct iwl_priv *priv) | 139 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u32 scd_q_msk) |
140 | { | 140 | { |
141 | struct iwl_txfifo_flush_cmd flush_cmd; | 141 | struct iwl_txfifo_flush_cmd flush_cmd; |
142 | struct iwl_host_cmd cmd = { | 142 | struct iwl_host_cmd cmd = { |
@@ -162,6 +162,9 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv) | |||
162 | if (priv->nvm_data->sku_cap_11n_enable) | 162 | if (priv->nvm_data->sku_cap_11n_enable) |
163 | flush_cmd.queue_control |= IWL_AGG_TX_QUEUE_MSK; | 163 | flush_cmd.queue_control |= IWL_AGG_TX_QUEUE_MSK; |
164 | 164 | ||
165 | if (scd_q_msk) | ||
166 | flush_cmd.queue_control = cpu_to_le32(scd_q_msk); | ||
167 | |||
165 | IWL_DEBUG_INFO(priv, "queue control: 0x%x\n", | 168 | IWL_DEBUG_INFO(priv, "queue control: 0x%x\n", |
166 | flush_cmd.queue_control); | 169 | flush_cmd.queue_control); |
167 | flush_cmd.flush_control = cpu_to_le16(IWL_DROP_ALL); | 170 | flush_cmd.flush_control = cpu_to_le16(IWL_DROP_ALL); |
@@ -173,7 +176,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv) | |||
173 | { | 176 | { |
174 | mutex_lock(&priv->mutex); | 177 | mutex_lock(&priv->mutex); |
175 | ieee80211_stop_queues(priv->hw); | 178 | ieee80211_stop_queues(priv->hw); |
176 | if (iwlagn_txfifo_flush(priv)) { | 179 | if (iwlagn_txfifo_flush(priv, 0)) { |
177 | IWL_ERR(priv, "flush request fail\n"); | 180 | IWL_ERR(priv, "flush request fail\n"); |
178 | goto done; | 181 | goto done; |
179 | } | 182 | } |
@@ -1084,7 +1087,14 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) | |||
1084 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 1087 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
1085 | struct iwlagn_wowlan_kek_kck_material_cmd kek_kck_cmd; | 1088 | struct iwlagn_wowlan_kek_kck_material_cmd kek_kck_cmd; |
1086 | struct iwlagn_wowlan_tkip_params_cmd tkip_cmd = {}; | 1089 | struct iwlagn_wowlan_tkip_params_cmd tkip_cmd = {}; |
1087 | struct iwlagn_d3_config_cmd d3_cfg_cmd = {}; | 1090 | struct iwlagn_d3_config_cmd d3_cfg_cmd = { |
1091 | /* | ||
1092 | * Program the minimum sleep time to 10 seconds, as many | ||
1093 | * platforms have issues processing a wakeup signal while | ||
1094 | * still being in the process of suspending. | ||
1095 | */ | ||
1096 | .min_sleep_time = cpu_to_le32(10 * 1000 * 1000), | ||
1097 | }; | ||
1088 | struct wowlan_key_data key_data = { | 1098 | struct wowlan_key_data key_data = { |
1089 | .ctx = ctx, | 1099 | .ctx = ctx, |
1090 | .bssid = ctx->active.bssid_addr, | 1100 | .bssid = ctx->active.bssid_addr, |
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index a7294fa4d7e5..fc3879804622 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -777,9 +777,12 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
777 | IWL_DEBUG_HT(priv, "start Tx\n"); | 777 | IWL_DEBUG_HT(priv, "start Tx\n"); |
778 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); | 778 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); |
779 | break; | 779 | break; |
780 | case IEEE80211_AMPDU_TX_STOP_CONT: | ||
781 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | 780 | case IEEE80211_AMPDU_TX_STOP_FLUSH: |
782 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | 781 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: |
782 | IWL_DEBUG_HT(priv, "Flush Tx\n"); | ||
783 | ret = iwlagn_tx_agg_flush(priv, vif, sta, tid); | ||
784 | break; | ||
785 | case IEEE80211_AMPDU_TX_STOP_CONT: | ||
783 | IWL_DEBUG_HT(priv, "stop Tx\n"); | 786 | IWL_DEBUG_HT(priv, "stop Tx\n"); |
784 | ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); | 787 | ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); |
785 | if ((ret == 0) && (priv->agg_tids_count > 0)) { | 788 | if ((ret == 0) && (priv->agg_tids_count > 0)) { |
@@ -1122,7 +1125,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) | |||
1122 | */ | 1125 | */ |
1123 | if (drop) { | 1126 | if (drop) { |
1124 | IWL_DEBUG_MAC80211(priv, "send flush command\n"); | 1127 | IWL_DEBUG_MAC80211(priv, "send flush command\n"); |
1125 | if (iwlagn_txfifo_flush(priv)) { | 1128 | if (iwlagn_txfifo_flush(priv, 0)) { |
1126 | IWL_ERR(priv, "flush request fail\n"); | 1129 | IWL_ERR(priv, "flush request fail\n"); |
1127 | goto done; | 1130 | goto done; |
1128 | } | 1131 | } |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 70b7f68c4958..a900aaf47790 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -674,6 +674,51 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
674 | return ret; | 674 | return ret; |
675 | } | 675 | } |
676 | 676 | ||
677 | int iwlagn_tx_agg_flush(struct iwl_priv *priv, struct ieee80211_vif *vif, | ||
678 | struct ieee80211_sta *sta, u16 tid) | ||
679 | { | ||
680 | struct iwl_tid_data *tid_data; | ||
681 | enum iwl_agg_state agg_state; | ||
682 | int sta_id, txq_id; | ||
683 | sta_id = iwl_sta_id(sta); | ||
684 | |||
685 | /* | ||
686 | * First set the agg state to OFF to avoid calling | ||
687 | * ieee80211_stop_tx_ba_cb in iwlagn_check_ratid_empty. | ||
688 | */ | ||
689 | spin_lock_bh(&priv->sta_lock); | ||
690 | |||
691 | tid_data = &priv->tid_data[sta_id][tid]; | ||
692 | txq_id = tid_data->agg.txq_id; | ||
693 | agg_state = tid_data->agg.state; | ||
694 | IWL_DEBUG_TX_QUEUES(priv, "Flush AGG: sta %d tid %d q %d state %d\n", | ||
695 | sta_id, tid, txq_id, tid_data->agg.state); | ||
696 | |||
697 | tid_data->agg.state = IWL_AGG_OFF; | ||
698 | |||
699 | spin_unlock_bh(&priv->sta_lock); | ||
700 | |||
701 | if (iwlagn_txfifo_flush(priv, BIT(txq_id))) | ||
702 | IWL_ERR(priv, "Couldn't flush the AGG queue\n"); | ||
703 | |||
704 | if (test_bit(txq_id, priv->agg_q_alloc)) { | ||
705 | /* | ||
706 | * If the transport didn't know that we wanted to start | ||
707 | * agreggation, don't tell it that we want to stop them. | ||
708 | * This can happen when we don't get the addBA response on | ||
709 | * time, or we hadn't time to drain the AC queues. | ||
710 | */ | ||
711 | if (agg_state == IWL_AGG_ON) | ||
712 | iwl_trans_txq_disable(priv->trans, txq_id); | ||
713 | else | ||
714 | IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", | ||
715 | agg_state); | ||
716 | iwlagn_dealloc_agg_txq(priv, txq_id); | ||
717 | } | ||
718 | |||
719 | return 0; | ||
720 | } | ||
721 | |||
677 | int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, | 722 | int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, |
678 | struct ieee80211_sta *sta, u16 tid, u8 buf_size) | 723 | struct ieee80211_sta *sta, u16 tid, u8 buf_size) |
679 | { | 724 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 498300577ac0..39aad9893e0b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -912,8 +912,6 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) | |||
912 | } | 912 | } |
913 | } | 913 | } |
914 | 914 | ||
915 | IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version); | ||
916 | |||
917 | /* | 915 | /* |
918 | * In mvm uCode there is no difference between data and instructions | 916 | * In mvm uCode there is no difference between data and instructions |
919 | * sections. | 917 | * sections. |
@@ -970,6 +968,9 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) | |||
970 | else | 968 | else |
971 | op = &iwlwifi_opmode_table[DVM_OP_MODE]; | 969 | op = &iwlwifi_opmode_table[DVM_OP_MODE]; |
972 | 970 | ||
971 | IWL_INFO(drv, "loaded firmware version %s op_mode %s\n", | ||
972 | drv->fw.fw_version, op->name); | ||
973 | |||
973 | /* add this device to the list of devices using this op_mode */ | 974 | /* add this device to the list of devices using this op_mode */ |
974 | list_add_tail(&drv->list, &op->drv); | 975 | list_add_tail(&drv->list, &op->drv); |
975 | 976 | ||
@@ -997,8 +998,13 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) | |||
997 | * else from proceeding if the module fails to load | 998 | * else from proceeding if the module fails to load |
998 | * or hangs loading. | 999 | * or hangs loading. |
999 | */ | 1000 | */ |
1000 | if (load_module) | 1001 | if (load_module) { |
1001 | request_module("%s", op->name); | 1002 | err = request_module("%s", op->name); |
1003 | if (err) | ||
1004 | IWL_ERR(drv, | ||
1005 | "failed to load module %s (error %d), is dynamic loading enabled?\n", | ||
1006 | op->name, err); | ||
1007 | } | ||
1002 | return; | 1008 | return; |
1003 | 1009 | ||
1004 | try_again: | 1010 | try_again: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 7f9c254292a8..7a13790b5bfe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -305,7 +305,6 @@ static inline void iwl_free_rxb(struct iwl_rx_cmd_buffer *r) | |||
305 | * currently supports | 305 | * currently supports |
306 | */ | 306 | */ |
307 | #define IWL_MAX_HW_QUEUES 32 | 307 | #define IWL_MAX_HW_QUEUES 32 |
308 | #define IWL_INVALID_STATION 255 | ||
309 | #define IWL_MAX_TID_COUNT 8 | 308 | #define IWL_MAX_TID_COUNT 8 |
310 | #define IWL_FRAME_LIMIT 64 | 309 | #define IWL_FRAME_LIMIT 64 |
311 | 310 | ||
@@ -682,7 +681,7 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, | |||
682 | static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, | 681 | static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, |
683 | int fifo) | 682 | int fifo) |
684 | { | 683 | { |
685 | iwl_trans_txq_enable(trans, queue, fifo, IWL_INVALID_STATION, | 684 | iwl_trans_txq_enable(trans, queue, fifo, -1, |
686 | IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0); | 685 | IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0); |
687 | } | 686 | } |
688 | 687 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 1700232aa166..810bfa5f6de0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c | |||
@@ -61,6 +61,8 @@ | |||
61 | * | 61 | * |
62 | *****************************************************************************/ | 62 | *****************************************************************************/ |
63 | 63 | ||
64 | #include <net/mac80211.h> | ||
65 | |||
64 | #include "fw-api-bt-coex.h" | 66 | #include "fw-api-bt-coex.h" |
65 | #include "iwl-modparams.h" | 67 | #include "iwl-modparams.h" |
66 | #include "mvm.h" | 68 | #include "mvm.h" |
@@ -96,6 +98,20 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { | |||
96 | 98 | ||
97 | #undef EVENT_PRIO_ANT | 99 | #undef EVENT_PRIO_ANT |
98 | 100 | ||
101 | /* BT Antenna Coupling Threshold (dB) */ | ||
102 | #define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) | ||
103 | #define IWL_BT_LOAD_FORCE_SISO_THRESHOLD (3) | ||
104 | |||
105 | #define BT_ENABLE_REDUCED_TXPOWER_THRESHOLD (-62) | ||
106 | #define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65) | ||
107 | #define BT_REDUCED_TX_POWER_BIT BIT(7) | ||
108 | |||
109 | static inline bool is_loose_coex(void) | ||
110 | { | ||
111 | return iwlwifi_mod_params.ant_coupling > | ||
112 | IWL_BT_ANTENNA_COUPLING_THRESHOLD; | ||
113 | } | ||
114 | |||
99 | int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm) | 115 | int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm) |
100 | { | 116 | { |
101 | return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC, | 117 | return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC, |
@@ -186,11 +202,6 @@ static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = { | |||
186 | cpu_to_le32(0x00000000), | 202 | cpu_to_le32(0x00000000), |
187 | }; | 203 | }; |
188 | 204 | ||
189 | /* BT Antenna Coupling Threshold (dB) */ | ||
190 | #define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) | ||
191 | #define IWL_BT_LOAD_FORCE_SISO_THRESHOLD (3) | ||
192 | |||
193 | |||
194 | int iwl_send_bt_init_conf(struct iwl_mvm *mvm) | 205 | int iwl_send_bt_init_conf(struct iwl_mvm *mvm) |
195 | { | 206 | { |
196 | struct iwl_bt_coex_cmd cmd = { | 207 | struct iwl_bt_coex_cmd cmd = { |
@@ -203,8 +214,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) | |||
203 | 214 | ||
204 | cmd.flags = iwlwifi_mod_params.bt_coex_active ? | 215 | cmd.flags = iwlwifi_mod_params.bt_coex_active ? |
205 | BT_COEX_NW : BT_COEX_DISABLE; | 216 | BT_COEX_NW : BT_COEX_DISABLE; |
206 | cmd.flags |= iwlwifi_mod_params.bt_ch_announce ? BT_CH_PRIMARY_EN : 0; | 217 | cmd.flags |= BT_CH_PRIMARY_EN | BT_SYNC_2_BT_DISABLE; |
207 | cmd.flags |= BT_SYNC_2_BT_DISABLE; | ||
208 | 218 | ||
209 | cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE | | 219 | cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE | |
210 | BT_VALID_BT_PRIO_BOOST | | 220 | BT_VALID_BT_PRIO_BOOST | |
@@ -215,7 +225,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) | |||
215 | BT_VALID_REDUCED_TX_POWER | | 225 | BT_VALID_REDUCED_TX_POWER | |
216 | BT_VALID_LUT); | 226 | BT_VALID_LUT); |
217 | 227 | ||
218 | if (iwlwifi_mod_params.ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) | 228 | if (is_loose_coex()) |
219 | memcpy(&cmd.decision_lut, iwl_loose_lookup, | 229 | memcpy(&cmd.decision_lut, iwl_loose_lookup, |
220 | sizeof(iwl_tight_lookup)); | 230 | sizeof(iwl_tight_lookup)); |
221 | else | 231 | else |
@@ -228,6 +238,8 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) | |||
228 | cmd.kill_cts_msk = | 238 | cmd.kill_cts_msk = |
229 | cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]); | 239 | cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]); |
230 | 240 | ||
241 | memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif)); | ||
242 | |||
231 | /* go to CALIB state in internal BT-Coex state machine */ | 243 | /* go to CALIB state in internal BT-Coex state machine */ |
232 | ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN, | 244 | ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN, |
233 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 245 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
@@ -243,19 +255,101 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) | |||
243 | sizeof(cmd), &cmd); | 255 | sizeof(cmd), &cmd); |
244 | } | 256 | } |
245 | 257 | ||
246 | struct iwl_bt_notif_iterator_data { | 258 | static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm, |
247 | struct iwl_mvm *mvm; | 259 | bool reduced_tx_power) |
260 | { | ||
261 | enum iwl_bt_kill_msk bt_kill_msk; | ||
262 | struct iwl_bt_coex_cmd cmd = {}; | ||
263 | struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif; | ||
264 | |||
265 | lockdep_assert_held(&mvm->mutex); | ||
266 | |||
267 | if (reduced_tx_power) { | ||
268 | /* Reduced Tx power has precedence on the type of the profile */ | ||
269 | bt_kill_msk = BT_KILL_MSK_REDUCED_TXPOW; | ||
270 | } else { | ||
271 | /* Low latency BT profile is active: give higher prio to BT */ | ||
272 | if (BT_MBOX_MSG(notif, 3, SCO_STATE) || | ||
273 | BT_MBOX_MSG(notif, 3, A2DP_STATE) || | ||
274 | BT_MBOX_MSG(notif, 3, SNIFF_STATE)) | ||
275 | bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP; | ||
276 | else | ||
277 | bt_kill_msk = BT_KILL_MSK_DEFAULT; | ||
278 | } | ||
279 | |||
280 | IWL_DEBUG_COEX(mvm, | ||
281 | "Update kill_msk: %d - SCO %sactive A2DP %sactive SNIFF %sactive\n", | ||
282 | bt_kill_msk, | ||
283 | BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in", | ||
284 | BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in", | ||
285 | BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in"); | ||
286 | |||
287 | /* Don't send HCMD if there is no update */ | ||
288 | if (bt_kill_msk == mvm->bt_kill_msk) | ||
289 | return 0; | ||
290 | |||
291 | mvm->bt_kill_msk = bt_kill_msk; | ||
292 | cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]); | ||
293 | cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]); | ||
294 | cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS); | ||
295 | |||
296 | IWL_DEBUG_COEX(mvm, "bt_kill_msk = %d\n", bt_kill_msk); | ||
297 | return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, | ||
298 | sizeof(cmd), &cmd); | ||
299 | } | ||
300 | |||
301 | static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, | ||
302 | bool enable) | ||
303 | { | ||
304 | struct iwl_bt_coex_cmd cmd = { | ||
305 | .valid_bit_msk = cpu_to_le16(BT_VALID_REDUCED_TX_POWER), | ||
306 | .bt_reduced_tx_power = sta_id, | ||
307 | }; | ||
308 | struct ieee80211_sta *sta; | ||
309 | struct iwl_mvm_sta *mvmsta; | ||
310 | |||
311 | /* This can happen if the station has been removed right now */ | ||
312 | if (sta_id == IWL_MVM_STATION_COUNT) | ||
313 | return 0; | ||
314 | |||
315 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], | ||
316 | lockdep_is_held(&mvm->mutex)); | ||
317 | mvmsta = (void *)sta->drv_priv; | ||
318 | |||
319 | /* nothing to do */ | ||
320 | if (mvmsta->bt_reduced_txpower == enable) | ||
321 | return 0; | ||
322 | |||
323 | if (enable) | ||
324 | cmd.bt_reduced_tx_power |= BT_REDUCED_TX_POWER_BIT; | ||
325 | |||
326 | IWL_DEBUG_COEX(mvm, "%sable reduced Tx Power for sta %d\n", | ||
327 | enable ? "en" : "dis", sta_id); | ||
328 | |||
329 | mvmsta->bt_reduced_txpower = enable; | ||
330 | |||
331 | /* Send ASYNC since this can be sent from an atomic context */ | ||
332 | return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_ASYNC, | ||
333 | sizeof(cmd), &cmd); | ||
334 | } | ||
335 | |||
336 | struct iwl_bt_iterator_data { | ||
248 | struct iwl_bt_coex_profile_notif *notif; | 337 | struct iwl_bt_coex_profile_notif *notif; |
338 | struct iwl_mvm *mvm; | ||
339 | u32 num_bss_ifaces; | ||
340 | bool reduced_tx_power; | ||
249 | }; | 341 | }; |
250 | 342 | ||
251 | static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, | 343 | static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, |
252 | struct ieee80211_vif *vif) | 344 | struct ieee80211_vif *vif) |
253 | { | 345 | { |
254 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 346 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
255 | struct iwl_bt_notif_iterator_data *data = _data; | 347 | struct iwl_bt_iterator_data *data = _data; |
348 | struct iwl_mvm *mvm = data->mvm; | ||
256 | struct ieee80211_chanctx_conf *chanctx_conf; | 349 | struct ieee80211_chanctx_conf *chanctx_conf; |
257 | enum ieee80211_smps_mode smps_mode; | 350 | enum ieee80211_smps_mode smps_mode; |
258 | enum ieee80211_band band; | 351 | enum ieee80211_band band; |
352 | int ave_rssi; | ||
259 | 353 | ||
260 | if (vif->type != NL80211_IFTYPE_STATION) | 354 | if (vif->type != NL80211_IFTYPE_STATION) |
261 | return; | 355 | return; |
@@ -268,11 +362,13 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, | |||
268 | band = -1; | 362 | band = -1; |
269 | rcu_read_unlock(); | 363 | rcu_read_unlock(); |
270 | 364 | ||
271 | if (band != IEEE80211_BAND_2GHZ) | ||
272 | return; | ||
273 | |||
274 | smps_mode = IEEE80211_SMPS_AUTOMATIC; | 365 | smps_mode = IEEE80211_SMPS_AUTOMATIC; |
275 | 366 | ||
367 | if (band != IEEE80211_BAND_2GHZ) { | ||
368 | ieee80211_request_smps(vif, smps_mode); | ||
369 | return; | ||
370 | } | ||
371 | |||
276 | if (data->notif->bt_status) | 372 | if (data->notif->bt_status) |
277 | smps_mode = IEEE80211_SMPS_DYNAMIC; | 373 | smps_mode = IEEE80211_SMPS_DYNAMIC; |
278 | 374 | ||
@@ -285,20 +381,88 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, | |||
285 | data->notif->bt_traffic_load, smps_mode); | 381 | data->notif->bt_traffic_load, smps_mode); |
286 | 382 | ||
287 | ieee80211_request_smps(vif, smps_mode); | 383 | ieee80211_request_smps(vif, smps_mode); |
384 | |||
385 | /* don't reduce the Tx power if in loose scheme */ | ||
386 | if (is_loose_coex()) | ||
387 | return; | ||
388 | |||
389 | data->num_bss_ifaces++; | ||
390 | |||
391 | /* reduced Txpower only if there are open BT connections, so ...*/ | ||
392 | if (!BT_MBOX_MSG(data->notif, 3, OPEN_CON_2)) { | ||
393 | /* ... cancel reduced Tx power ... */ | ||
394 | if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false)) | ||
395 | IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n"); | ||
396 | data->reduced_tx_power = false; | ||
397 | |||
398 | /* ... and there is no need to get reports on RSSI any more. */ | ||
399 | ieee80211_disable_rssi_reports(vif); | ||
400 | return; | ||
401 | } | ||
402 | |||
403 | ave_rssi = ieee80211_ave_rssi(vif); | ||
404 | |||
405 | /* if the RSSI isn't valid, fake it is very low */ | ||
406 | if (!ave_rssi) | ||
407 | ave_rssi = -100; | ||
408 | if (ave_rssi > BT_ENABLE_REDUCED_TXPOWER_THRESHOLD) { | ||
409 | if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true)) | ||
410 | IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n"); | ||
411 | |||
412 | /* | ||
413 | * bt_kill_msk can be BT_KILL_MSK_REDUCED_TXPOW only if all the | ||
414 | * BSS / P2P clients have rssi above threshold. | ||
415 | * We set the bt_kill_msk to BT_KILL_MSK_REDUCED_TXPOW before | ||
416 | * the iteration, if one interface's rssi isn't good enough, | ||
417 | * bt_kill_msk will be set to default values. | ||
418 | */ | ||
419 | } else if (ave_rssi < BT_DISABLE_REDUCED_TXPOWER_THRESHOLD) { | ||
420 | if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false)) | ||
421 | IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n"); | ||
422 | |||
423 | /* | ||
424 | * One interface hasn't rssi above threshold, bt_kill_msk must | ||
425 | * be set to default values. | ||
426 | */ | ||
427 | data->reduced_tx_power = false; | ||
428 | } | ||
429 | |||
430 | /* Begin to monitor the RSSI: it may influence the reduced Tx power */ | ||
431 | ieee80211_enable_rssi_reports(vif, BT_DISABLE_REDUCED_TXPOWER_THRESHOLD, | ||
432 | BT_ENABLE_REDUCED_TXPOWER_THRESHOLD); | ||
433 | } | ||
434 | |||
435 | static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm) | ||
436 | { | ||
437 | struct iwl_bt_iterator_data data = { | ||
438 | .mvm = mvm, | ||
439 | .notif = &mvm->last_bt_notif, | ||
440 | .reduced_tx_power = true, | ||
441 | }; | ||
442 | |||
443 | ieee80211_iterate_active_interfaces_atomic( | ||
444 | mvm->hw, IEEE80211_IFACE_ITER_NORMAL, | ||
445 | iwl_mvm_bt_notif_iterator, &data); | ||
446 | |||
447 | /* | ||
448 | * If there are no BSS / P2P client interfaces, reduced Tx Power is | ||
449 | * irrelevant since it is based on the RSSI coming from the beacon. | ||
450 | * Use BT_KILL_MSK_DEFAULT in that case. | ||
451 | */ | ||
452 | data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces; | ||
453 | |||
454 | if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power)) | ||
455 | IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n"); | ||
288 | } | 456 | } |
289 | 457 | ||
458 | /* upon association, the fw will send in BT Coex notification */ | ||
290 | int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, | 459 | int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, |
291 | struct iwl_rx_cmd_buffer *rxb, | 460 | struct iwl_rx_cmd_buffer *rxb, |
292 | struct iwl_device_cmd *dev_cmd) | 461 | struct iwl_device_cmd *dev_cmd) |
293 | { | 462 | { |
294 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 463 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
295 | struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; | 464 | struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; |
296 | struct iwl_bt_notif_iterator_data data = { | 465 | |
297 | .mvm = mvm, | ||
298 | .notif = notif, | ||
299 | }; | ||
300 | struct iwl_bt_coex_cmd cmd = {}; | ||
301 | enum iwl_bt_kill_msk bt_kill_msk; | ||
302 | 466 | ||
303 | IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n"); | 467 | IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n"); |
304 | IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not "); | 468 | IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not "); |
@@ -311,38 +475,115 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, | |||
311 | /* remember this notification for future use: rssi fluctuations */ | 475 | /* remember this notification for future use: rssi fluctuations */ |
312 | memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); | 476 | memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); |
313 | 477 | ||
314 | ieee80211_iterate_active_interfaces_atomic( | 478 | iwl_mvm_bt_coex_notif_handle(mvm); |
315 | mvm->hw, IEEE80211_IFACE_ITER_NORMAL, | 479 | |
316 | iwl_mvm_bt_notif_iterator, &data); | 480 | /* |
481 | * This is an async handler for a notification, returning anything other | ||
482 | * than 0 doesn't make sense even if HCMD failed. | ||
483 | */ | ||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac, | ||
488 | struct ieee80211_vif *vif) | ||
489 | { | ||
490 | struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv; | ||
491 | struct iwl_bt_iterator_data *data = _data; | ||
492 | struct iwl_mvm *mvm = data->mvm; | ||
493 | |||
494 | struct ieee80211_sta *sta; | ||
495 | struct iwl_mvm_sta *mvmsta; | ||
496 | |||
497 | if (vif->type != NL80211_IFTYPE_STATION || | ||
498 | mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT) | ||
499 | return; | ||
500 | |||
501 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], | ||
502 | lockdep_is_held(&mvm->mutex)); | ||
503 | mvmsta = (void *)sta->drv_priv; | ||
504 | |||
505 | /* | ||
506 | * This interface doesn't support reduced Tx power (because of low | ||
507 | * RSSI probably), then set bt_kill_msk to default values. | ||
508 | */ | ||
509 | if (!mvmsta->bt_reduced_txpower) | ||
510 | data->reduced_tx_power = false; | ||
511 | /* else - possibly leave it to BT_KILL_MSK_REDUCED_TXPOW */ | ||
512 | } | ||
513 | |||
514 | void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
515 | enum ieee80211_rssi_event rssi_event) | ||
516 | { | ||
517 | struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv; | ||
518 | struct iwl_bt_iterator_data data = { | ||
519 | .mvm = mvm, | ||
520 | .reduced_tx_power = true, | ||
521 | }; | ||
522 | int ret; | ||
523 | |||
524 | mutex_lock(&mvm->mutex); | ||
525 | |||
526 | /* Rssi update while not associated ?! */ | ||
527 | if (WARN_ON_ONCE(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)) | ||
528 | goto out_unlock; | ||
317 | 529 | ||
318 | /* Low latency BT profile is active: give higher prio to BT */ | 530 | /* No open connection - reports should be disabled */ |
319 | if (BT_MBOX_MSG(notif, 3, SCO_STATE) || | 531 | if (!BT_MBOX_MSG(&mvm->last_bt_notif, 3, OPEN_CON_2)) |
320 | BT_MBOX_MSG(notif, 3, A2DP_STATE) || | 532 | goto out_unlock; |
321 | BT_MBOX_MSG(notif, 3, SNIFF_STATE)) | 533 | |
322 | bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP; | 534 | IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid, |
535 | rssi_event == RSSI_EVENT_HIGH ? "HIGH" : "LOW"); | ||
536 | |||
537 | /* | ||
538 | * Check if rssi is good enough for reduced Tx power, but not in loose | ||
539 | * scheme. | ||
540 | */ | ||
541 | if (rssi_event == RSSI_EVENT_LOW || is_loose_coex()) | ||
542 | ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, | ||
543 | false); | ||
323 | else | 544 | else |
324 | bt_kill_msk = BT_KILL_MSK_DEFAULT; | 545 | ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true); |
325 | 546 | ||
326 | /* Don't send HCMD if there is no update */ | 547 | if (ret) |
327 | if (bt_kill_msk == mvm->bt_kill_msk) | 548 | IWL_ERR(mvm, "couldn't send BT_CONFIG HCMD upon RSSI event\n"); |
328 | return 0; | ||
329 | 549 | ||
330 | IWL_DEBUG_COEX(mvm, | 550 | ieee80211_iterate_active_interfaces_atomic( |
331 | "Update kill_msk: %d - SCO %sactive A2DP %sactive SNIFF %sactive\n", | 551 | mvm->hw, IEEE80211_IFACE_ITER_NORMAL, |
332 | bt_kill_msk, | 552 | iwl_mvm_bt_rssi_iterator, &data); |
333 | BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in", | ||
334 | BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in", | ||
335 | BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in"); | ||
336 | 553 | ||
337 | mvm->bt_kill_msk = bt_kill_msk; | 554 | /* |
338 | cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]); | 555 | * If there are no BSS / P2P client interfaces, reduced Tx Power is |
339 | cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]); | 556 | * irrelevant since it is based on the RSSI coming from the beacon. |
557 | * Use BT_KILL_MSK_DEFAULT in that case. | ||
558 | */ | ||
559 | data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces; | ||
340 | 560 | ||
341 | cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS); | 561 | if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power)) |
562 | IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n"); | ||
342 | 563 | ||
343 | if (iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, sizeof(cmd), &cmd)) | 564 | out_unlock: |
344 | IWL_ERR(mvm, "Failed to sent BT Coex CMD\n"); | 565 | mutex_unlock(&mvm->mutex); |
566 | } | ||
345 | 567 | ||
346 | /* This handler is ASYNC */ | 568 | void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
347 | return 0; | 569 | { |
570 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
571 | enum ieee80211_band band; | ||
572 | |||
573 | rcu_read_lock(); | ||
574 | chanctx_conf = rcu_dereference(vif->chanctx_conf); | ||
575 | if (chanctx_conf && chanctx_conf->def.chan) | ||
576 | band = chanctx_conf->def.chan->band; | ||
577 | else | ||
578 | band = -1; | ||
579 | rcu_read_unlock(); | ||
580 | |||
581 | /* if we are in 2GHz we will get a notification from the fw */ | ||
582 | if (band == IEEE80211_BAND_2GHZ) | ||
583 | return; | ||
584 | |||
585 | /* else, we can remove all the constraints */ | ||
586 | memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif)); | ||
587 | |||
588 | iwl_mvm_bt_coex_notif_handle(mvm); | ||
348 | } | 589 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index bf087abe39f3..16bbdcc8627a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c | |||
@@ -769,7 +769,14 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
769 | struct iwl_wowlan_config_cmd wowlan_config_cmd = {}; | 769 | struct iwl_wowlan_config_cmd wowlan_config_cmd = {}; |
770 | struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {}; | 770 | struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {}; |
771 | struct iwl_wowlan_tkip_params_cmd tkip_cmd = {}; | 771 | struct iwl_wowlan_tkip_params_cmd tkip_cmd = {}; |
772 | struct iwl_d3_manager_config d3_cfg_cmd = {}; | 772 | struct iwl_d3_manager_config d3_cfg_cmd = { |
773 | /* | ||
774 | * Program the minimum sleep time to 10 seconds, as many | ||
775 | * platforms have issues processing a wakeup signal while | ||
776 | * still being in the process of suspending. | ||
777 | */ | ||
778 | .min_sleep_time = cpu_to_le32(10 * 1000 * 1000), | ||
779 | }; | ||
773 | struct wowlan_key_data key_data = { | 780 | struct wowlan_key_data key_data = { |
774 | .use_rsc_tsc = false, | 781 | .use_rsc_tsc = false, |
775 | .tkip = &tkip_cmd, | 782 | .tkip = &tkip_cmd, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index b080b4ba5458..2053dccefcd6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c | |||
@@ -300,6 +300,67 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file, | |||
300 | return count; | 300 | return count; |
301 | } | 301 | } |
302 | 302 | ||
303 | static ssize_t iwl_dbgfs_mac_params_read(struct file *file, | ||
304 | char __user *user_buf, | ||
305 | size_t count, loff_t *ppos) | ||
306 | { | ||
307 | struct ieee80211_vif *vif = file->private_data; | ||
308 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
309 | struct iwl_mvm *mvm = mvmvif->dbgfs_data; | ||
310 | u8 ap_sta_id; | ||
311 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
312 | char buf[512]; | ||
313 | int bufsz = sizeof(buf); | ||
314 | int pos = 0; | ||
315 | int i; | ||
316 | |||
317 | mutex_lock(&mvm->mutex); | ||
318 | |||
319 | ap_sta_id = mvmvif->ap_sta_id; | ||
320 | |||
321 | pos += scnprintf(buf+pos, bufsz-pos, "mac id/color: %d / %d\n", | ||
322 | mvmvif->id, mvmvif->color); | ||
323 | pos += scnprintf(buf+pos, bufsz-pos, "bssid: %pM\n", | ||
324 | vif->bss_conf.bssid); | ||
325 | pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n"); | ||
326 | for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++) { | ||
327 | pos += scnprintf(buf+pos, bufsz-pos, | ||
328 | "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n", | ||
329 | i, mvmvif->queue_params[i].txop, | ||
330 | mvmvif->queue_params[i].cw_min, | ||
331 | mvmvif->queue_params[i].cw_max, | ||
332 | mvmvif->queue_params[i].aifs, | ||
333 | mvmvif->queue_params[i].uapsd); | ||
334 | } | ||
335 | |||
336 | if (vif->type == NL80211_IFTYPE_STATION && | ||
337 | ap_sta_id != IWL_MVM_STATION_COUNT) { | ||
338 | struct ieee80211_sta *sta; | ||
339 | struct iwl_mvm_sta *mvm_sta; | ||
340 | |||
341 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[ap_sta_id], | ||
342 | lockdep_is_held(&mvm->mutex)); | ||
343 | mvm_sta = (void *)sta->drv_priv; | ||
344 | pos += scnprintf(buf+pos, bufsz-pos, | ||
345 | "ap_sta_id %d - reduced Tx power %d\n", | ||
346 | ap_sta_id, mvm_sta->bt_reduced_txpower); | ||
347 | } | ||
348 | |||
349 | rcu_read_lock(); | ||
350 | chanctx_conf = rcu_dereference(vif->chanctx_conf); | ||
351 | if (chanctx_conf) { | ||
352 | pos += scnprintf(buf+pos, bufsz-pos, | ||
353 | "idle rx chains %d, active rx chains: %d\n", | ||
354 | chanctx_conf->rx_chains_static, | ||
355 | chanctx_conf->rx_chains_dynamic); | ||
356 | } | ||
357 | rcu_read_unlock(); | ||
358 | |||
359 | mutex_unlock(&mvm->mutex); | ||
360 | |||
361 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
362 | } | ||
363 | |||
303 | #define BT_MBOX_MSG(_notif, _num, _field) \ | 364 | #define BT_MBOX_MSG(_notif, _num, _field) \ |
304 | ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ | 365 | ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ |
305 | >> BT_MBOX##_num##_##_field##_POS) | 366 | >> BT_MBOX##_num##_##_field##_POS) |
@@ -464,6 +525,9 @@ MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); | |||
464 | MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); | 525 | MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); |
465 | MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); | 526 | MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); |
466 | 527 | ||
528 | /* Interface specific debugfs entries */ | ||
529 | MVM_DEBUGFS_READ_FILE_OPS(mac_params); | ||
530 | |||
467 | int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | 531 | int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) |
468 | { | 532 | { |
469 | char buf[100]; | 533 | char buf[100]; |
@@ -494,3 +558,58 @@ err: | |||
494 | IWL_ERR(mvm, "Can't create the mvm debugfs directory\n"); | 558 | IWL_ERR(mvm, "Can't create the mvm debugfs directory\n"); |
495 | return -ENOMEM; | 559 | return -ENOMEM; |
496 | } | 560 | } |
561 | |||
562 | void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
563 | { | ||
564 | struct dentry *dbgfs_dir = vif->debugfs_dir; | ||
565 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
566 | char buf[100]; | ||
567 | |||
568 | if (!dbgfs_dir) | ||
569 | return; | ||
570 | |||
571 | mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir); | ||
572 | mvmvif->dbgfs_data = mvm; | ||
573 | |||
574 | if (!mvmvif->dbgfs_dir) { | ||
575 | IWL_ERR(mvm, "Failed to create debugfs directory under %s\n", | ||
576 | dbgfs_dir->d_name.name); | ||
577 | return; | ||
578 | } | ||
579 | |||
580 | MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, | ||
581 | S_IRUSR); | ||
582 | |||
583 | /* | ||
584 | * Create symlink for convenience pointing to interface specific | ||
585 | * debugfs entries for the driver. For example, under | ||
586 | * /sys/kernel/debug/iwlwifi/0000\:02\:00.0/iwlmvm/ | ||
587 | * find | ||
588 | * netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/ | ||
589 | */ | ||
590 | snprintf(buf, 100, "../../../%s/%s/%s/%s", | ||
591 | dbgfs_dir->d_parent->d_parent->d_name.name, | ||
592 | dbgfs_dir->d_parent->d_name.name, | ||
593 | dbgfs_dir->d_name.name, | ||
594 | mvmvif->dbgfs_dir->d_name.name); | ||
595 | |||
596 | mvmvif->dbgfs_slink = debugfs_create_symlink(dbgfs_dir->d_name.name, | ||
597 | mvm->debugfs_dir, buf); | ||
598 | if (!mvmvif->dbgfs_slink) | ||
599 | IWL_ERR(mvm, "Can't create debugfs symbolic link under %s\n", | ||
600 | dbgfs_dir->d_name.name); | ||
601 | return; | ||
602 | err: | ||
603 | IWL_ERR(mvm, "Can't create debugfs entity\n"); | ||
604 | } | ||
605 | |||
606 | void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
607 | { | ||
608 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
609 | |||
610 | debugfs_remove(mvmvif->dbgfs_slink); | ||
611 | mvmvif->dbgfs_slink = NULL; | ||
612 | |||
613 | debugfs_remove_recursive(mvmvif->dbgfs_dir); | ||
614 | mvmvif->dbgfs_dir = NULL; | ||
615 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h index 127051891e9b..81fe45f46be7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h | |||
@@ -68,73 +68,53 @@ | |||
68 | 68 | ||
69 | /** | 69 | /** |
70 | * enum iwl_scan_flags - masks for power table command flags | 70 | * enum iwl_scan_flags - masks for power table command flags |
71 | * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off | ||
72 | * receiver and transmitter. '0' - does not allow. | ||
71 | * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management, | 73 | * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management, |
72 | * '1' Driver enables PM (use rest of parameters) | 74 | * '1' Driver enables PM (use rest of parameters) |
73 | * @POWER_FLAGS_SLEEP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM, | 75 | * @POWER_FLAGS_SKIP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM, |
74 | * '1' PM could sleep over DTIM till listen Interval. | 76 | * '1' PM could sleep over DTIM till listen Interval. |
75 | * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable. | ||
76 | * @POWER_FLAGS_SNOOZE_ENA_MSK: Enable snoozing only if uAPSD is enabled and all | ||
77 | * access categories are both delivery and trigger enabled. | ||
78 | * @POWER_FLAGS_BT_SCO_ENA: Enable BT SCO coex only if uAPSD and | ||
79 | * PBW Snoozing enabled | ||
80 | * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask | 77 | * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask |
78 | * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable. | ||
81 | */ | 79 | */ |
82 | enum iwl_power_flags { | 80 | enum iwl_power_flags { |
83 | POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK = BIT(0), | 81 | POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0), |
84 | POWER_FLAGS_SLEEP_OVER_DTIM_MSK = BIT(1), | 82 | POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK = BIT(1), |
85 | POWER_FLAGS_LPRX_ENA_MSK = BIT(2), | 83 | POWER_FLAGS_SKIP_OVER_DTIM_MSK = BIT(2), |
86 | POWER_FLAGS_SNOOZE_ENA_MSK = BIT(3), | 84 | POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(9), |
87 | POWER_FLAGS_BT_SCO_ENA = BIT(4), | 85 | POWER_FLAGS_LPRX_ENA_MSK = BIT(11), |
88 | POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(5) | ||
89 | }; | 86 | }; |
90 | 87 | ||
88 | #define IWL_POWER_VEC_SIZE 5 | ||
89 | |||
91 | /** | 90 | /** |
92 | * struct iwl_powertable_cmd - Power Table Command | 91 | * struct iwl_powertable_cmd - Power Table Command |
93 | * POWER_TABLE_CMD = 0x77 (command, has simple generic response) | 92 | * POWER_TABLE_CMD = 0x77 (command, has simple generic response) |
94 | * | 93 | * |
95 | * @id_and_color: MAC contex identifier | ||
96 | * @action: Action on context - no action, add new, | ||
97 | * modify existent, remove | ||
98 | * @flags: Power table command flags from POWER_FLAGS_* | 94 | * @flags: Power table command flags from POWER_FLAGS_* |
99 | * @keep_alive_seconds: Keep alive period in seconds. Default - 25 sec. | 95 | * @keep_alive_seconds: Keep alive period in seconds. Default - 25 sec. |
100 | * Minimum allowed:- 3 * DTIM | 96 | * Minimum allowed:- 3 * DTIM. Keep alive period must be |
97 | * set regardless of power scheme or current power state. | ||
98 | * FW use this value also when PM is disabled. | ||
101 | * @rx_data_timeout: Minimum time (usec) from last Rx packet for AM to | 99 | * @rx_data_timeout: Minimum time (usec) from last Rx packet for AM to |
102 | * PSM transition - legacy PM | 100 | * PSM transition - legacy PM |
103 | * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to | 101 | * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to |
104 | * PSM transition - legacy PM | 102 | * PSM transition - legacy PM |
105 | * @rx_data_timeout_uapsd: Minimum time (usec) from last Rx packet for AM to | 103 | * @sleep_interval: not in use |
106 | * PSM transition - uAPSD | 104 | * @keep_alive_beacons: not in use |
107 | * @tx_data_timeout_uapsd: Minimum time (usec) from last Tx packet for AM to | ||
108 | * PSM transition - uAPSD | ||
109 | * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled. | 105 | * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled. |
110 | * Default: 80dbm | 106 | * Default: 80dbm |
111 | * @num_skip_dtim: Number of DTIMs to skip if Skip over DTIM flag is set | ||
112 | * @snooze_interval: TBD | ||
113 | * @snooze_window: TBD | ||
114 | * @snooze_step: TBD | ||
115 | * @qndp_tid: TBD | ||
116 | * @uapsd_ac_flags: TBD | ||
117 | * @uapsd_max_sp: TBD | ||
118 | */ | 107 | */ |
119 | struct iwl_powertable_cmd { | 108 | struct iwl_powertable_cmd { |
120 | /* COMMON_INDEX_HDR_API_S_VER_1 */ | 109 | /* PM_POWER_TABLE_CMD_API_S_VER_5 */ |
121 | __le32 id_and_color; | ||
122 | __le32 action; | ||
123 | __le16 flags; | 110 | __le16 flags; |
124 | u8 reserved; | 111 | u8 keep_alive_seconds; |
125 | __le16 keep_alive_seconds; | 112 | u8 debug_flags; |
126 | __le32 rx_data_timeout; | 113 | __le32 rx_data_timeout; |
127 | __le32 tx_data_timeout; | 114 | __le32 tx_data_timeout; |
128 | __le32 rx_data_timeout_uapsd; | 115 | __le32 sleep_interval[IWL_POWER_VEC_SIZE]; |
129 | __le32 tx_data_timeout_uapsd; | 116 | __le32 keep_alive_beacons; |
130 | u8 lprx_rssi_threshold; | 117 | __le32 lprx_rssi_threshold; |
131 | u8 num_skip_dtim; | ||
132 | __le16 snooze_interval; | ||
133 | __le16 snooze_window; | ||
134 | u8 snooze_step; | ||
135 | u8 qndp_tid; | ||
136 | u8 uapsd_ac_flags; | ||
137 | u8 uapsd_max_sp; | ||
138 | } __packed; | 118 | } __packed; |
139 | 119 | ||
140 | #endif | 120 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 1073f2682221..191dcae8ba47 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h | |||
@@ -480,15 +480,34 @@ enum { | |||
480 | TE_DEP_TSF = 2, | 480 | TE_DEP_TSF = 2, |
481 | TE_EVENT_SOCIOPATHIC = 4, | 481 | TE_EVENT_SOCIOPATHIC = 4, |
482 | }; /* MAC_EVENT_DEPENDENCY_POLICY_API_E_VER_2 */ | 482 | }; /* MAC_EVENT_DEPENDENCY_POLICY_API_E_VER_2 */ |
483 | 483 | /* | |
484 | /* When to send Time Event notifications and to whom (internal = FW) */ | 484 | * Supported Time event notifications configuration. |
485 | * A notification (both event and fragment) includes a status indicating weather | ||
486 | * the FW was able to schedule the event or not. For fragment start/end | ||
487 | * notification the status is always success. There is no start/end fragment | ||
488 | * notification for monolithic events. | ||
489 | * | ||
490 | * @TE_NOTIF_NONE: no notifications | ||
491 | * @TE_NOTIF_HOST_EVENT_START: request/receive notification on event start | ||
492 | * @TE_NOTIF_HOST_EVENT_END:request/receive notification on event end | ||
493 | * @TE_NOTIF_INTERNAL_EVENT_START: internal FW use | ||
494 | * @TE_NOTIF_INTERNAL_EVENT_END: internal FW use. | ||
495 | * @TE_NOTIF_HOST_FRAG_START: request/receive notification on frag start | ||
496 | * @TE_NOTIF_HOST_FRAG_END:request/receive notification on frag end | ||
497 | * @TE_NOTIF_INTERNAL_FRAG_START: internal FW use. | ||
498 | * @TE_NOTIF_INTERNAL_FRAG_END: internal FW use. | ||
499 | */ | ||
485 | enum { | 500 | enum { |
486 | TE_NOTIF_NONE = 0, | 501 | TE_NOTIF_NONE = 0, |
487 | TE_NOTIF_HOST_START = 0x1, | 502 | TE_NOTIF_HOST_EVENT_START = 0x1, |
488 | TE_NOTIF_HOST_END = 0x2, | 503 | TE_NOTIF_HOST_EVENT_END = 0x2, |
489 | TE_NOTIF_INTERNAL_START = 0x4, | 504 | TE_NOTIF_INTERNAL_EVENT_START = 0x4, |
490 | TE_NOTIF_INTERNAL_END = 0x8 | 505 | TE_NOTIF_INTERNAL_EVENT_END = 0x8, |
491 | }; /* MAC_EVENT_ACTION_API_E_VER_1 */ | 506 | TE_NOTIF_HOST_FRAG_START = 0x10, |
507 | TE_NOTIF_HOST_FRAG_END = 0x20, | ||
508 | TE_NOTIF_INTERNAL_FRAG_START = 0x40, | ||
509 | TE_NOTIF_INTERNAL_FRAG_END = 0x80 | ||
510 | }; /* MAC_EVENT_ACTION_API_E_VER_2 */ | ||
492 | 511 | ||
493 | /* | 512 | /* |
494 | * @TE_FRAG_NONE: fragmentation of the time event is NOT allowed. | 513 | * @TE_FRAG_NONE: fragmentation of the time event is NOT allowed. |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 3d193f8c33b6..fe031608fd91 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -502,11 +502,15 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
502 | /* | 502 | /* |
503 | * TODO: remove this temporary code. | 503 | * TODO: remove this temporary code. |
504 | * Currently MVM FW supports power management only on single MAC. | 504 | * Currently MVM FW supports power management only on single MAC. |
505 | * Iterate and disable PM on all active interfaces. | 505 | * If new interface added, disable PM on existing interface. |
506 | * P2P device is a special case, since it is handled by FW similary to | ||
507 | * scan. If P2P deviced is added, PM remains enabled on existing | ||
508 | * interface. | ||
506 | * Note: the method below does not count the new interface being added | 509 | * Note: the method below does not count the new interface being added |
507 | * at this moment. | 510 | * at this moment. |
508 | */ | 511 | */ |
509 | mvm->vif_count++; | 512 | if (vif->type != NL80211_IFTYPE_P2P_DEVICE) |
513 | mvm->vif_count++; | ||
510 | if (mvm->vif_count > 1) { | 514 | if (mvm->vif_count > 1) { |
511 | IWL_DEBUG_MAC80211(mvm, | 515 | IWL_DEBUG_MAC80211(mvm, |
512 | "Disable power on existing interfaces\n"); | 516 | "Disable power on existing interfaces\n"); |
@@ -562,6 +566,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
562 | mvm->p2p_device_vif = vif; | 566 | mvm->p2p_device_vif = vif; |
563 | } | 567 | } |
564 | 568 | ||
569 | iwl_mvm_vif_dbgfs_register(mvm, vif); | ||
565 | goto out_unlock; | 570 | goto out_unlock; |
566 | 571 | ||
567 | out_unbind: | 572 | out_unbind: |
@@ -575,10 +580,11 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
575 | /* | 580 | /* |
576 | * TODO: remove this temporary code. | 581 | * TODO: remove this temporary code. |
577 | * Currently MVM FW supports power management only on single MAC. | 582 | * Currently MVM FW supports power management only on single MAC. |
578 | * Check if only one additional interface remains after rereasing | 583 | * Check if only one additional interface remains after releasing |
579 | * current one. Update power mode on the remaining interface. | 584 | * current one. Update power mode on the remaining interface. |
580 | */ | 585 | */ |
581 | mvm->vif_count--; | 586 | if (vif->type != NL80211_IFTYPE_P2P_DEVICE) |
587 | mvm->vif_count--; | ||
582 | IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", | 588 | IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", |
583 | mvm->vif_count); | 589 | mvm->vif_count); |
584 | if (mvm->vif_count == 1) { | 590 | if (mvm->vif_count == 1) { |
@@ -640,6 +646,8 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, | |||
640 | 646 | ||
641 | mutex_lock(&mvm->mutex); | 647 | mutex_lock(&mvm->mutex); |
642 | 648 | ||
649 | iwl_mvm_vif_dbgfs_clean(mvm, vif); | ||
650 | |||
643 | /* | 651 | /* |
644 | * For AP/GO interface, the tear down of the resources allocated to the | 652 | * For AP/GO interface, the tear down of the resources allocated to the |
645 | * interface is be handled as part of the stop_ap flow. | 653 | * interface is be handled as part of the stop_ap flow. |
@@ -663,7 +671,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, | |||
663 | * Check if only one additional interface remains after removing | 671 | * Check if only one additional interface remains after removing |
664 | * current one. Update power mode on the remaining interface. | 672 | * current one. Update power mode on the remaining interface. |
665 | */ | 673 | */ |
666 | if (mvm->vif_count) | 674 | if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE) |
667 | mvm->vif_count--; | 675 | mvm->vif_count--; |
668 | IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", | 676 | IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", |
669 | mvm->vif_count); | 677 | mvm->vif_count); |
@@ -713,6 +721,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
713 | IWL_ERR(mvm, "failed to update quotas\n"); | 721 | IWL_ERR(mvm, "failed to update quotas\n"); |
714 | return; | 722 | return; |
715 | } | 723 | } |
724 | iwl_mvm_bt_coex_vif_assoc(mvm, vif); | ||
716 | } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { | 725 | } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { |
717 | /* remove AP station now that the MAC is unassoc */ | 726 | /* remove AP station now that the MAC is unassoc */ |
718 | ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); | 727 | ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); |
@@ -931,7 +940,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw, | |||
931 | */ | 940 | */ |
932 | break; | 941 | break; |
933 | case STA_NOTIFY_AWAKE: | 942 | case STA_NOTIFY_AWAKE: |
934 | if (WARN_ON(mvmsta->sta_id == IWL_INVALID_STATION)) | 943 | if (WARN_ON(mvmsta->sta_id == IWL_MVM_STATION_COUNT)) |
935 | break; | 944 | break; |
936 | iwl_mvm_sta_modify_ps_wake(mvm, sta); | 945 | iwl_mvm_sta_modify_ps_wake(mvm, sta); |
937 | break; | 946 | break; |
@@ -1326,6 +1335,15 @@ static int iwl_mvm_set_tim(struct ieee80211_hw *hw, | |||
1326 | return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif); | 1335 | return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif); |
1327 | } | 1336 | } |
1328 | 1337 | ||
1338 | static void iwl_mvm_mac_rssi_callback(struct ieee80211_hw *hw, | ||
1339 | struct ieee80211_vif *vif, | ||
1340 | enum ieee80211_rssi_event rssi_event) | ||
1341 | { | ||
1342 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | ||
1343 | |||
1344 | iwl_mvm_bt_rssi_event(mvm, vif, rssi_event); | ||
1345 | } | ||
1346 | |||
1329 | struct ieee80211_ops iwl_mvm_hw_ops = { | 1347 | struct ieee80211_ops iwl_mvm_hw_ops = { |
1330 | .tx = iwl_mvm_mac_tx, | 1348 | .tx = iwl_mvm_mac_tx, |
1331 | .ampdu_action = iwl_mvm_mac_ampdu_action, | 1349 | .ampdu_action = iwl_mvm_mac_ampdu_action, |
@@ -1349,6 +1367,7 @@ struct ieee80211_ops iwl_mvm_hw_ops = { | |||
1349 | .update_tkip_key = iwl_mvm_mac_update_tkip_key, | 1367 | .update_tkip_key = iwl_mvm_mac_update_tkip_key, |
1350 | .remain_on_channel = iwl_mvm_roc, | 1368 | .remain_on_channel = iwl_mvm_roc, |
1351 | .cancel_remain_on_channel = iwl_mvm_cancel_roc, | 1369 | .cancel_remain_on_channel = iwl_mvm_cancel_roc, |
1370 | .rssi_callback = iwl_mvm_mac_rssi_callback, | ||
1352 | 1371 | ||
1353 | .add_chanctx = iwl_mvm_add_chanctx, | 1372 | .add_chanctx = iwl_mvm_add_chanctx, |
1354 | .remove_chanctx = iwl_mvm_remove_chanctx, | 1373 | .remove_chanctx = iwl_mvm_remove_chanctx, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 53d58968e30a..8269bc562951 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -212,6 +212,7 @@ struct iwl_mvm_vif { | |||
212 | 212 | ||
213 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 213 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
214 | struct dentry *dbgfs_dir; | 214 | struct dentry *dbgfs_dir; |
215 | struct dentry *dbgfs_slink; | ||
215 | void *dbgfs_data; | 216 | void *dbgfs_data; |
216 | #endif | 217 | #endif |
217 | }; | 218 | }; |
@@ -321,6 +322,13 @@ struct iwl_mvm { | |||
321 | * can hold 16 keys at most. Reflect this fact. | 322 | * can hold 16 keys at most. Reflect this fact. |
322 | */ | 323 | */ |
323 | unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)]; | 324 | unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)]; |
325 | |||
326 | /* | ||
327 | * This counter of created interfaces is referenced only in conjunction | ||
328 | * with FW limitation related to power management. Currently PM is | ||
329 | * supported only on a single interface. | ||
330 | * IMPORTANT: this variable counts all interfaces except P2P device. | ||
331 | */ | ||
324 | u8 vif_count; | 332 | u8 vif_count; |
325 | 333 | ||
326 | struct led_classdev led; | 334 | struct led_classdev led; |
@@ -471,16 +479,22 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm); | |||
471 | /* MVM debugfs */ | 479 | /* MVM debugfs */ |
472 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 480 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
473 | int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir); | 481 | int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir); |
474 | int iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 482 | void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
475 | struct dentry *dbgfs_dir); | 483 | void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
476 | void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
477 | struct iwl_powertable_cmd *cmd); | ||
478 | #else | 484 | #else |
479 | static inline int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, | 485 | static inline int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, |
480 | struct dentry *dbgfs_dir) | 486 | struct dentry *dbgfs_dir) |
481 | { | 487 | { |
482 | return 0; | 488 | return 0; |
483 | } | 489 | } |
490 | static inline void | ||
491 | iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
492 | { | ||
493 | } | ||
494 | static inline void | ||
495 | iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
496 | { | ||
497 | } | ||
484 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 498 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
485 | 499 | ||
486 | /* rate scaling */ | 500 | /* rate scaling */ |
@@ -490,6 +504,8 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, | |||
490 | /* power managment */ | 504 | /* power managment */ |
491 | int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 505 | int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
492 | int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 506 | int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
507 | void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
508 | struct iwl_powertable_cmd *cmd); | ||
493 | 509 | ||
494 | int iwl_mvm_leds_init(struct iwl_mvm *mvm); | 510 | int iwl_mvm_leds_init(struct iwl_mvm *mvm); |
495 | void iwl_mvm_leds_exit(struct iwl_mvm *mvm); | 511 | void iwl_mvm_leds_exit(struct iwl_mvm *mvm); |
@@ -513,5 +529,8 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm); | |||
513 | int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, | 529 | int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, |
514 | struct iwl_rx_cmd_buffer *rxb, | 530 | struct iwl_rx_cmd_buffer *rxb, |
515 | struct iwl_device_cmd *cmd); | 531 | struct iwl_device_cmd *cmd); |
532 | void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
533 | enum ieee80211_rssi_event rssi_event); | ||
534 | void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | ||
516 | 535 | ||
517 | #endif /* __IWL_MVM_H__ */ | 536 | #endif /* __IWL_MVM_H__ */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index efb9a6f3faac..9395ab2a1af2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
@@ -75,23 +75,49 @@ | |||
75 | 75 | ||
76 | #define POWER_KEEP_ALIVE_PERIOD_SEC 25 | 76 | #define POWER_KEEP_ALIVE_PERIOD_SEC 25 |
77 | 77 | ||
78 | static void iwl_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 78 | static void iwl_mvm_power_log(struct iwl_mvm *mvm, |
79 | struct iwl_powertable_cmd *cmd) | 79 | struct iwl_powertable_cmd *cmd) |
80 | { | ||
81 | IWL_DEBUG_POWER(mvm, | ||
82 | "Sending power table command for power level %d, flags = 0x%X\n", | ||
83 | iwlmvm_mod_params.power_scheme, | ||
84 | le16_to_cpu(cmd->flags)); | ||
85 | IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", cmd->keep_alive_seconds); | ||
86 | |||
87 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { | ||
88 | IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n", | ||
89 | le32_to_cpu(cmd->rx_data_timeout)); | ||
90 | IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", | ||
91 | le32_to_cpu(cmd->tx_data_timeout)); | ||
92 | IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", | ||
93 | cmd->lprx_rssi_threshold); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
98 | struct iwl_powertable_cmd *cmd) | ||
80 | { | 99 | { |
81 | struct ieee80211_hw *hw = mvm->hw; | 100 | struct ieee80211_hw *hw = mvm->hw; |
82 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
83 | struct ieee80211_chanctx_conf *chanctx_conf; | 101 | struct ieee80211_chanctx_conf *chanctx_conf; |
84 | struct ieee80211_channel *chan; | 102 | struct ieee80211_channel *chan; |
85 | int dtimper, dtimper_msec; | 103 | int dtimper, dtimper_msec; |
86 | int keep_alive; | 104 | int keep_alive; |
87 | bool radar_detect = false; | 105 | bool radar_detect = false; |
88 | 106 | ||
89 | cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, | 107 | /* |
90 | mvmvif->color)); | 108 | * Regardless of power management state the driver must set |
91 | cmd->action = cpu_to_le32(FW_CTXT_ACTION_MODIFY); | 109 | * keep alive period. FW will use it for sending keep alive NDPs |
110 | * immediately after association. | ||
111 | */ | ||
112 | cmd->keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC; | ||
113 | |||
114 | if ((iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) || | ||
115 | !iwlwifi_mod_params.power_save) | ||
116 | return; | ||
117 | |||
118 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); | ||
92 | 119 | ||
93 | if ((!vif->bss_conf.ps) || | 120 | if (!vif->bss_conf.ps) |
94 | (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM)) | ||
95 | return; | 121 | return; |
96 | 122 | ||
97 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); | 123 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); |
@@ -110,26 +136,23 @@ static void iwl_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
110 | 136 | ||
111 | /* Check skip over DTIM conditions */ | 137 | /* Check skip over DTIM conditions */ |
112 | if (!radar_detect && (dtimper <= 10) && | 138 | if (!radar_detect && (dtimper <= 10) && |
113 | (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) { | 139 | (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) |
114 | cmd->flags |= cpu_to_le16(POWER_FLAGS_SLEEP_OVER_DTIM_MSK); | 140 | cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); |
115 | cmd->num_skip_dtim = 2; | ||
116 | } | ||
117 | 141 | ||
118 | /* Check that keep alive period is at least 3 * DTIM */ | 142 | /* Check that keep alive period is at least 3 * DTIM */ |
119 | dtimper_msec = dtimper * vif->bss_conf.beacon_int; | 143 | dtimper_msec = dtimper * vif->bss_conf.beacon_int; |
120 | keep_alive = max_t(int, 3 * dtimper_msec, | 144 | keep_alive = max_t(int, 3 * dtimper_msec, |
121 | MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC); | 145 | MSEC_PER_SEC * cmd->keep_alive_seconds); |
122 | keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); | 146 | keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); |
123 | 147 | cmd->keep_alive_seconds = keep_alive; | |
124 | cmd->keep_alive_seconds = cpu_to_le16(keep_alive); | ||
125 | 148 | ||
126 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP) { | 149 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP) { |
127 | /* TODO: Also for D3 (device sleep / WoWLAN) */ | 150 | /* TODO: Also for D3 (device sleep / WoWLAN) */ |
128 | cmd->rx_data_timeout = cpu_to_le32(10); | 151 | cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); |
129 | cmd->tx_data_timeout = cpu_to_le32(10); | 152 | cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); |
130 | } else { | 153 | } else { |
131 | cmd->rx_data_timeout = cpu_to_le32(50); | 154 | cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); |
132 | cmd->tx_data_timeout = cpu_to_le32(50); | 155 | cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); |
133 | } | 156 | } |
134 | } | 157 | } |
135 | 158 | ||
@@ -137,36 +160,11 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
137 | { | 160 | { |
138 | struct iwl_powertable_cmd cmd = {}; | 161 | struct iwl_powertable_cmd cmd = {}; |
139 | 162 | ||
140 | if (!iwlwifi_mod_params.power_save) { | ||
141 | IWL_DEBUG_POWER(mvm, "Power management is not allowed\n"); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) | 163 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) |
146 | return 0; | 164 | return 0; |
147 | 165 | ||
148 | iwl_power_build_cmd(mvm, vif, &cmd); | 166 | iwl_mvm_power_build_cmd(mvm, vif, &cmd); |
149 | 167 | iwl_mvm_power_log(mvm, &cmd); | |
150 | IWL_DEBUG_POWER(mvm, | ||
151 | "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n", | ||
152 | cmd.id_and_color, iwlmvm_mod_params.power_scheme, | ||
153 | le16_to_cpu(cmd.flags)); | ||
154 | |||
155 | if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { | ||
156 | IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", | ||
157 | le16_to_cpu(cmd.keep_alive_seconds)); | ||
158 | IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n", | ||
159 | le32_to_cpu(cmd.rx_data_timeout)); | ||
160 | IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", | ||
161 | le32_to_cpu(cmd.tx_data_timeout)); | ||
162 | IWL_DEBUG_POWER(mvm, "Rx timeout (uAPSD) = %u usec\n", | ||
163 | le32_to_cpu(cmd.rx_data_timeout_uapsd)); | ||
164 | IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", | ||
165 | le32_to_cpu(cmd.tx_data_timeout_uapsd)); | ||
166 | IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", | ||
167 | cmd.lprx_rssi_threshold); | ||
168 | IWL_DEBUG_POWER(mvm, "DTIMs to skip = %u\n", cmd.num_skip_dtim); | ||
169 | } | ||
170 | 168 | ||
171 | return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, | 169 | return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, |
172 | sizeof(cmd), &cmd); | 170 | sizeof(cmd), &cmd); |
@@ -175,33 +173,16 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
175 | int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | 173 | int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
176 | { | 174 | { |
177 | struct iwl_powertable_cmd cmd = {}; | 175 | struct iwl_powertable_cmd cmd = {}; |
178 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
179 | |||
180 | if (!iwlwifi_mod_params.power_save) { | ||
181 | IWL_DEBUG_POWER(mvm, "Power management is not allowed\n"); | ||
182 | return 0; | ||
183 | } | ||
184 | 176 | ||
185 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) | 177 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) |
186 | return 0; | 178 | return 0; |
187 | 179 | ||
188 | cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, | 180 | if ((iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) && |
189 | mvmvif->color)); | 181 | iwlwifi_mod_params.power_save) |
190 | cmd.action = cpu_to_le32(FW_CTXT_ACTION_MODIFY); | 182 | cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); |
191 | 183 | ||
192 | IWL_DEBUG_POWER(mvm, | 184 | iwl_mvm_power_log(mvm, &cmd); |
193 | "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n", | ||
194 | cmd.id_and_color, iwlmvm_mod_params.power_scheme, | ||
195 | le16_to_cpu(cmd.flags)); | ||
196 | 185 | ||
197 | return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, | 186 | return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, |
198 | sizeof(cmd), &cmd); | 187 | sizeof(cmd), &cmd); |
199 | } | 188 | } |
200 | |||
201 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
202 | void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
203 | struct iwl_powertable_cmd *cmd) | ||
204 | { | ||
205 | iwl_power_build_cmd(mvm, vif, cmd); | ||
206 | } | ||
207 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index a01a6612677e..55334d542e26 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
@@ -793,7 +793,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, | |||
793 | 793 | ||
794 | if (num_of_ant(tbl->ant_type) > 1) | 794 | if (num_of_ant(tbl->ant_type) > 1) |
795 | tbl->ant_type = | 795 | tbl->ant_type = |
796 | first_antenna(mvm->nvm_data->valid_tx_ant); | 796 | first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); |
797 | 797 | ||
798 | tbl->is_ht40 = 0; | 798 | tbl->is_ht40 = 0; |
799 | tbl->is_SGI = 0; | 799 | tbl->is_SGI = 0; |
@@ -1235,7 +1235,7 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm, | |||
1235 | return -1; | 1235 | return -1; |
1236 | 1236 | ||
1237 | /* Need both Tx chains/antennas to support MIMO */ | 1237 | /* Need both Tx chains/antennas to support MIMO */ |
1238 | if (num_of_ant(mvm->nvm_data->valid_tx_ant) < 2) | 1238 | if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 2) |
1239 | return -1; | 1239 | return -1; |
1240 | 1240 | ||
1241 | IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n"); | 1241 | IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n"); |
@@ -1287,7 +1287,7 @@ static int rs_switch_to_mimo3(struct iwl_mvm *mvm, | |||
1287 | return -1; | 1287 | return -1; |
1288 | 1288 | ||
1289 | /* Need both Tx chains/antennas to support MIMO */ | 1289 | /* Need both Tx chains/antennas to support MIMO */ |
1290 | if (num_of_ant(mvm->nvm_data->valid_tx_ant) < 3) | 1290 | if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 3) |
1291 | return -1; | 1291 | return -1; |
1292 | 1292 | ||
1293 | IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO3\n"); | 1293 | IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO3\n"); |
@@ -1381,7 +1381,7 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm, | |||
1381 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1381 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1382 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1382 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1383 | u8 start_action; | 1383 | u8 start_action; |
1384 | u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; | 1384 | u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
1385 | u8 tx_chains_num = num_of_ant(valid_tx_ant); | 1385 | u8 tx_chains_num = num_of_ant(valid_tx_ant); |
1386 | int ret; | 1386 | int ret; |
1387 | u8 update_search_tbl_counter = 0; | 1387 | u8 update_search_tbl_counter = 0; |
@@ -1514,7 +1514,7 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm, | |||
1514 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1514 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1515 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1515 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1516 | u8 start_action; | 1516 | u8 start_action; |
1517 | u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; | 1517 | u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
1518 | u8 tx_chains_num = num_of_ant(valid_tx_ant); | 1518 | u8 tx_chains_num = num_of_ant(valid_tx_ant); |
1519 | u8 update_search_tbl_counter = 0; | 1519 | u8 update_search_tbl_counter = 0; |
1520 | int ret; | 1520 | int ret; |
@@ -1649,7 +1649,7 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm, | |||
1649 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1649 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1650 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1650 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1651 | u8 start_action; | 1651 | u8 start_action; |
1652 | u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; | 1652 | u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
1653 | u8 tx_chains_num = num_of_ant(valid_tx_ant); | 1653 | u8 tx_chains_num = num_of_ant(valid_tx_ant); |
1654 | u8 update_search_tbl_counter = 0; | 1654 | u8 update_search_tbl_counter = 0; |
1655 | int ret; | 1655 | int ret; |
@@ -1786,7 +1786,7 @@ static int rs_move_mimo3_to_other(struct iwl_mvm *mvm, | |||
1786 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1786 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1787 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1787 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1788 | u8 start_action; | 1788 | u8 start_action; |
1789 | u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; | 1789 | u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
1790 | u8 tx_chains_num = num_of_ant(valid_tx_ant); | 1790 | u8 tx_chains_num = num_of_ant(valid_tx_ant); |
1791 | int ret; | 1791 | int ret; |
1792 | u8 update_search_tbl_counter = 0; | 1792 | u8 update_search_tbl_counter = 0; |
@@ -2449,7 +2449,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, | |||
2449 | 2449 | ||
2450 | i = lq_sta->last_txrate_idx; | 2450 | i = lq_sta->last_txrate_idx; |
2451 | 2451 | ||
2452 | valid_tx_ant = mvm->nvm_data->valid_tx_ant; | 2452 | valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
2453 | 2453 | ||
2454 | if (!lq_sta->search_better_tbl) | 2454 | if (!lq_sta->search_better_tbl) |
2455 | active_tbl = lq_sta->active_tbl; | 2455 | active_tbl = lq_sta->active_tbl; |
@@ -2639,15 +2639,15 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
2639 | 2639 | ||
2640 | /* These values will be overridden later */ | 2640 | /* These values will be overridden later */ |
2641 | lq_sta->lq.single_stream_ant_msk = | 2641 | lq_sta->lq.single_stream_ant_msk = |
2642 | first_antenna(mvm->nvm_data->valid_tx_ant); | 2642 | first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); |
2643 | lq_sta->lq.dual_stream_ant_msk = | 2643 | lq_sta->lq.dual_stream_ant_msk = |
2644 | mvm->nvm_data->valid_tx_ant & | 2644 | iwl_fw_valid_tx_ant(mvm->fw) & |
2645 | ~first_antenna(mvm->nvm_data->valid_tx_ant); | 2645 | ~first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); |
2646 | if (!lq_sta->lq.dual_stream_ant_msk) { | 2646 | if (!lq_sta->lq.dual_stream_ant_msk) { |
2647 | lq_sta->lq.dual_stream_ant_msk = ANT_AB; | 2647 | lq_sta->lq.dual_stream_ant_msk = ANT_AB; |
2648 | } else if (num_of_ant(mvm->nvm_data->valid_tx_ant) == 2) { | 2648 | } else if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) == 2) { |
2649 | lq_sta->lq.dual_stream_ant_msk = | 2649 | lq_sta->lq.dual_stream_ant_msk = |
2650 | mvm->nvm_data->valid_tx_ant; | 2650 | iwl_fw_valid_tx_ant(mvm->fw); |
2651 | } | 2651 | } |
2652 | 2652 | ||
2653 | /* as default allow aggregation for all tids */ | 2653 | /* as default allow aggregation for all tids */ |
@@ -2708,7 +2708,7 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm, | |||
2708 | index++; | 2708 | index++; |
2709 | repeat_rate--; | 2709 | repeat_rate--; |
2710 | if (mvm) | 2710 | if (mvm) |
2711 | valid_tx_ant = mvm->nvm_data->valid_tx_ant; | 2711 | valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
2712 | 2712 | ||
2713 | /* Fill rest of rate table */ | 2713 | /* Fill rest of rate table */ |
2714 | while (index < LINK_QUAL_MAX_RETRY_NUM) { | 2714 | while (index < LINK_QUAL_MAX_RETRY_NUM) { |
@@ -2813,7 +2813,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, | |||
2813 | u8 ant_sel_tx; | 2813 | u8 ant_sel_tx; |
2814 | 2814 | ||
2815 | mvm = lq_sta->drv; | 2815 | mvm = lq_sta->drv; |
2816 | valid_tx_ant = mvm->nvm_data->valid_tx_ant; | 2816 | valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
2817 | if (lq_sta->dbg_fixed_rate) { | 2817 | if (lq_sta->dbg_fixed_rate) { |
2818 | ant_sel_tx = | 2818 | ant_sel_tx = |
2819 | ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) | 2819 | ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) |
@@ -2884,9 +2884,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, | |||
2884 | desc += sprintf(buff+desc, "fixed rate 0x%X\n", | 2884 | desc += sprintf(buff+desc, "fixed rate 0x%X\n", |
2885 | lq_sta->dbg_fixed_rate); | 2885 | lq_sta->dbg_fixed_rate); |
2886 | desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", | 2886 | desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", |
2887 | (mvm->nvm_data->valid_tx_ant & ANT_A) ? "ANT_A," : "", | 2887 | (iwl_fw_valid_tx_ant(mvm->fw) & ANT_A) ? "ANT_A," : "", |
2888 | (mvm->nvm_data->valid_tx_ant & ANT_B) ? "ANT_B," : "", | 2888 | (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "", |
2889 | (mvm->nvm_data->valid_tx_ant & ANT_C) ? "ANT_C" : ""); | 2889 | (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : ""); |
2890 | desc += sprintf(buff+desc, "lq type %s\n", | 2890 | desc += sprintf(buff+desc, "lq type %s\n", |
2891 | (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); | 2891 | (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); |
2892 | if (is_Ht(tbl->lq_type)) { | 2892 | if (is_Ht(tbl->lq_type)) { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 4d872d69577f..0fd96e4da461 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
@@ -945,7 +945,7 @@ static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif, | |||
945 | mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) | 945 | mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) |
946 | return mvmvif->ap_sta_id; | 946 | return mvmvif->ap_sta_id; |
947 | 947 | ||
948 | return IWL_INVALID_STATION; | 948 | return IWL_MVM_STATION_COUNT; |
949 | } | 949 | } |
950 | 950 | ||
951 | static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, | 951 | static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, |
@@ -1093,7 +1093,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, | |||
1093 | 1093 | ||
1094 | /* Get the station id from the mvm local station table */ | 1094 | /* Get the station id from the mvm local station table */ |
1095 | sta_id = iwl_mvm_get_key_sta_id(vif, sta); | 1095 | sta_id = iwl_mvm_get_key_sta_id(vif, sta); |
1096 | if (sta_id == IWL_INVALID_STATION) { | 1096 | if (sta_id == IWL_MVM_STATION_COUNT) { |
1097 | IWL_ERR(mvm, "Failed to find station id\n"); | 1097 | IWL_ERR(mvm, "Failed to find station id\n"); |
1098 | return -EINVAL; | 1098 | return -EINVAL; |
1099 | } | 1099 | } |
@@ -1188,7 +1188,7 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, | |||
1188 | return -ENOENT; | 1188 | return -ENOENT; |
1189 | } | 1189 | } |
1190 | 1190 | ||
1191 | if (sta_id == IWL_INVALID_STATION) { | 1191 | if (sta_id == IWL_MVM_STATION_COUNT) { |
1192 | IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n"); | 1192 | IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n"); |
1193 | return 0; | 1193 | return 0; |
1194 | } | 1194 | } |
@@ -1254,7 +1254,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm, | |||
1254 | struct iwl_mvm_sta *mvm_sta; | 1254 | struct iwl_mvm_sta *mvm_sta; |
1255 | u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta); | 1255 | u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta); |
1256 | 1256 | ||
1257 | if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) | 1257 | if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT)) |
1258 | return; | 1258 | return; |
1259 | 1259 | ||
1260 | rcu_read_lock(); | 1260 | rcu_read_lock(); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index b0352df981e4..12abd2d71835 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h | |||
@@ -271,6 +271,7 @@ struct iwl_mvm_tid_data { | |||
271 | * @tid_disable_agg: bitmap: if bit(tid) is set, the fw won't send ampdus for | 271 | * @tid_disable_agg: bitmap: if bit(tid) is set, the fw won't send ampdus for |
272 | * tid. | 272 | * tid. |
273 | * @max_agg_bufsize: the maximal size of the AGG buffer for this station | 273 | * @max_agg_bufsize: the maximal size of the AGG buffer for this station |
274 | * @bt_reduced_txpower: is reduced tx power enabled for this station | ||
274 | * @lock: lock to protect the whole struct. Since %tid_data is access from Tx | 275 | * @lock: lock to protect the whole struct. Since %tid_data is access from Tx |
275 | * and from Tx response flow, it needs a spinlock. | 276 | * and from Tx response flow, it needs a spinlock. |
276 | * @pending_frames: number of frames for this STA on the shared Tx queues. | 277 | * @pending_frames: number of frames for this STA on the shared Tx queues. |
@@ -287,6 +288,7 @@ struct iwl_mvm_sta { | |||
287 | u32 mac_id_n_color; | 288 | u32 mac_id_n_color; |
288 | u16 tid_disable_agg; | 289 | u16 tid_disable_agg; |
289 | u8 max_agg_bufsize; | 290 | u8 max_agg_bufsize; |
291 | bool bt_reduced_txpower; | ||
290 | spinlock_t lock; | 292 | spinlock_t lock; |
291 | atomic_t pending_frames; | 293 | atomic_t pending_frames; |
292 | struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT]; | 294 | struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT]; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 4dc934bed055..ad9bbca99213 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c | |||
@@ -166,7 +166,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, | |||
166 | WARN_ONCE(!le32_to_cpu(notif->status), | 166 | WARN_ONCE(!le32_to_cpu(notif->status), |
167 | "Failed to schedule time event\n"); | 167 | "Failed to schedule time event\n"); |
168 | 168 | ||
169 | if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_END) { | 169 | if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_END) { |
170 | IWL_DEBUG_TE(mvm, | 170 | IWL_DEBUG_TE(mvm, |
171 | "TE ended - current time %lu, estimated end %lu\n", | 171 | "TE ended - current time %lu, estimated end %lu\n", |
172 | jiffies, te_data->end_jiffies); | 172 | jiffies, te_data->end_jiffies); |
@@ -189,7 +189,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, | |||
189 | } | 189 | } |
190 | 190 | ||
191 | iwl_mvm_te_clear_data(mvm, te_data); | 191 | iwl_mvm_te_clear_data(mvm, te_data); |
192 | } else if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_START) { | 192 | } else if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_START) { |
193 | te_data->running = true; | 193 | te_data->running = true; |
194 | te_data->end_jiffies = jiffies + | 194 | te_data->end_jiffies = jiffies + |
195 | TU_TO_JIFFIES(te_data->duration); | 195 | TU_TO_JIFFIES(te_data->duration); |
@@ -368,7 +368,8 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm, | |||
368 | time_cmd.interval_reciprocal = cpu_to_le32(iwl_mvm_reciprocal(1)); | 368 | time_cmd.interval_reciprocal = cpu_to_le32(iwl_mvm_reciprocal(1)); |
369 | time_cmd.duration = cpu_to_le32(duration); | 369 | time_cmd.duration = cpu_to_le32(duration); |
370 | time_cmd.repeat = cpu_to_le32(1); | 370 | time_cmd.repeat = cpu_to_le32(1); |
371 | time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END); | 371 | time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_EVENT_START | |
372 | TE_NOTIF_HOST_EVENT_END); | ||
372 | 373 | ||
373 | iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); | 374 | iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); |
374 | } | 375 | } |
@@ -485,7 +486,8 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
485 | time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2)); | 486 | time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2)); |
486 | time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration)); | 487 | time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration)); |
487 | time_cmd.repeat = cpu_to_le32(1); | 488 | time_cmd.repeat = cpu_to_le32(1); |
488 | time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END); | 489 | time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_EVENT_START | |
490 | TE_NOTIF_HOST_EVENT_END); | ||
489 | 491 | ||
490 | return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); | 492 | return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); |
491 | } | 493 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 0acc0bff43c7..479074303bd7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
@@ -205,7 +205,7 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, | |||
205 | rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx); | 205 | rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx); |
206 | 206 | ||
207 | mvm->mgmt_last_antenna_idx = | 207 | mvm->mgmt_last_antenna_idx = |
208 | iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant, | 208 | iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw), |
209 | mvm->mgmt_last_antenna_idx); | 209 | mvm->mgmt_last_antenna_idx); |
210 | rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; | 210 | rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; |
211 | 211 | ||
@@ -365,7 +365,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
365 | if (WARN_ON_ONCE(!mvmsta)) | 365 | if (WARN_ON_ONCE(!mvmsta)) |
366 | return -1; | 366 | return -1; |
367 | 367 | ||
368 | if (WARN_ON_ONCE(mvmsta->sta_id == IWL_INVALID_STATION)) | 368 | if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_STATION_COUNT)) |
369 | return -1; | 369 | return -1; |
370 | 370 | ||
371 | dev_cmd = iwl_mvm_set_tx_params(mvm, skb, sta, mvmsta->sta_id); | 371 | dev_cmd = iwl_mvm_set_tx_params(mvm, skb, sta, mvmsta->sta_id); |
@@ -641,10 +641,12 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
641 | } | 641 | } |
642 | 642 | ||
643 | IWL_DEBUG_TX_REPLY(mvm, | 643 | IWL_DEBUG_TX_REPLY(mvm, |
644 | "TXQ %d status %s (0x%08x)\n\t\t\t\tinitial_rate 0x%x " | 644 | "TXQ %d status %s (0x%08x)\n", |
645 | "retries %d, idx=%d ssn=%d next_reclaimed=0x%x seq_ctl=0x%x\n", | 645 | txq_id, iwl_mvm_get_tx_fail_reason(status), status); |
646 | txq_id, iwl_mvm_get_tx_fail_reason(status), | 646 | |
647 | status, le32_to_cpu(tx_resp->initial_rate), | 647 | IWL_DEBUG_TX_REPLY(mvm, |
648 | "\t\t\t\tinitial_rate 0x%x retries %d, idx=%d ssn=%d next_reclaimed=0x%x seq_ctl=0x%x\n", | ||
649 | le32_to_cpu(tx_resp->initial_rate), | ||
648 | tx_resp->failure_frame, SEQ_TO_INDEX(sequence), | 650 | tx_resp->failure_frame, SEQ_TO_INDEX(sequence), |
649 | ssn, next_reclaimed, seq_ctl); | 651 | ssn, next_reclaimed, seq_ctl); |
650 | 652 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index e308ad93aa9e..0cc8d8c0d393 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c | |||
@@ -462,7 +462,7 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, | |||
462 | .data = { lq, }, | 462 | .data = { lq, }, |
463 | }; | 463 | }; |
464 | 464 | ||
465 | if (WARN_ON(lq->sta_id == IWL_INVALID_STATION)) | 465 | if (WARN_ON(lq->sta_id == IWL_MVM_STATION_COUNT)) |
466 | return -EINVAL; | 466 | return -EINVAL; |
467 | 467 | ||
468 | if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) | 468 | if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 46ca91f77c9c..0016bb24b3d7 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
@@ -241,6 +241,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
241 | {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, | 241 | {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, |
242 | {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, | 242 | {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, |
243 | {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)}, | 243 | {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)}, |
244 | {IWL_PCI_DEVICE(0x088F, 0x5260, iwl6035_2agn_cfg)}, | ||
244 | 245 | ||
245 | /* 105 Series */ | 246 | /* 105 Series */ |
246 | {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, | 247 | {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index c3f15df67b9a..d97c1fad7bc3 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -1063,7 +1063,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | |||
1063 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); | 1063 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); |
1064 | 1064 | ||
1065 | /* If this queue is mapped to a certain station: it is an AGG queue */ | 1065 | /* If this queue is mapped to a certain station: it is an AGG queue */ |
1066 | if (sta_id != IWL_INVALID_STATION) { | 1066 | if (sta_id >= 0) { |
1067 | u16 ra_tid = BUILD_RAxTID(sta_id, tid); | 1067 | u16 ra_tid = BUILD_RAxTID(sta_id, tid); |
1068 | 1068 | ||
1069 | /* Map receiver-address / traffic-ID to this queue */ | 1069 | /* Map receiver-address / traffic-ID to this queue */ |