aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-04-10 14:10:24 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-10 14:10:24 -0400
commitd72c728210fa803a21203360c0f40b32972d795a (patch)
tree95189c1a9181e3317dea2a139f390f5013e921a2 /drivers/net
parent655d8e2328a6ef6b6b514609a4c1e33508d3a1da (diff)
parent2d055afdcada4bd8b510e9d2a8566fbded3c9696 (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h6
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c16
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c7
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c45
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c333
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c9
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c119
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h64
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h33
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c31
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h27
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c115
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c36
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c14
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c1
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c2
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 */
77extern struct iwl_lib_ops iwl1000_lib; 79extern struct iwl_lib_ops iwl1000_lib;
78extern struct iwl_lib_ops iwl2000_lib; 80extern struct iwl_lib_ops iwl2000_lib;
@@ -176,7 +178,7 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr);
176/* lib */ 178/* lib */
177int iwlagn_send_tx_power(struct iwl_priv *priv); 179int iwlagn_send_tx_power(struct iwl_priv *priv);
178void iwlagn_temperature(struct iwl_priv *priv); 180void iwlagn_temperature(struct iwl_priv *priv);
179int iwlagn_txfifo_flush(struct iwl_priv *priv); 181int iwlagn_txfifo_flush(struct iwl_priv *priv, u32 scd_q_msk);
180void iwlagn_dev_txfifo_flush(struct iwl_priv *priv); 182void iwlagn_dev_txfifo_flush(struct iwl_priv *priv);
181int iwlagn_send_beacon_cmd(struct iwl_priv *priv); 183int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
182int iwl_send_statistics_request(struct iwl_priv *priv, 184int 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);
211int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, 213int 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);
215int iwlagn_tx_agg_flush(struct iwl_priv *priv, struct ieee80211_vif *vif,
216 struct ieee80211_sta *sta, u16 tid);
213int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, 217int 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 */
139int iwlagn_txfifo_flush(struct iwl_priv *priv) 139int 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
677int 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
677int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, 722int 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,
682static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, 681static 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
109static inline bool is_loose_coex(void)
110{
111 return iwlwifi_mod_params.ant_coupling >
112 IWL_BT_ANTENNA_COUPLING_THRESHOLD;
113}
114
99int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm) 115int 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
194int iwl_send_bt_init_conf(struct iwl_mvm *mvm) 205int 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
246struct iwl_bt_notif_iterator_data { 258static 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
301static 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
336struct 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
251static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, 343static 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
435static 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 */
290int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, 459int 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
487static 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
514void 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 */ 568void 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
303static 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);
464MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); 525MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow);
465MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); 526MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart);
466 527
528/* Interface specific debugfs entries */
529MVM_DEBUGFS_READ_FILE_OPS(mac_params);
530
467int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) 531int 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
562void 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;
602err:
603 IWL_ERR(mvm, "Can't create debugfs entity\n");
604}
605
606void 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*/
82enum iwl_power_flags { 80enum 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 */
119struct iwl_powertable_cmd { 108struct 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 */
485enum { 500enum {
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
1338static 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
1329struct ieee80211_ops iwl_mvm_hw_ops = { 1347struct 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
473int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir); 481int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir);
474int iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 482void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
475 struct dentry *dbgfs_dir); 483void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
476void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
477 struct iwl_powertable_cmd *cmd);
478#else 484#else
479static inline int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, 485static 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}
490static inline void
491iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
492{
493}
494static inline void
495iwl_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 */
491int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 505int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
492int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 506int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
507void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
508 struct iwl_powertable_cmd *cmd);
493 509
494int iwl_mvm_leds_init(struct iwl_mvm *mvm); 510int iwl_mvm_leds_init(struct iwl_mvm *mvm);
495void iwl_mvm_leds_exit(struct iwl_mvm *mvm); 511void iwl_mvm_leds_exit(struct iwl_mvm *mvm);
@@ -513,5 +529,8 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm);
513int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, 529int 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);
532void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
533 enum ieee80211_rssi_event rssi_event);
534void 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
78static void iwl_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 78static 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
97void 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)
175int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 173int 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
202void 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
951static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, 951static 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 */