aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c632
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c515
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c206
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h149
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h69
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h11
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h29
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h21
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h34
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h55
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h16
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c23
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c75
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c242
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h88
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c101
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c60
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c70
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c42
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c793
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h154
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c21
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c462
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c206
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/testmode.h95
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c49
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c2
31 files changed, 3242 insertions, 995 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
index 0fad98b85f60..5b630f12bbff 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -98,126 +98,258 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
98 98
99#undef EVENT_PRIO_ANT 99#undef EVENT_PRIO_ANT
100 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) 101#define BT_ENABLE_REDUCED_TXPOWER_THRESHOLD (-62)
106#define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65) 102#define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65)
107#define BT_REDUCED_TX_POWER_BIT BIT(7) 103#define BT_ANTENNA_COUPLING_THRESHOLD (30)
108
109static inline bool is_loose_coex(void)
110{
111 return iwlwifi_mod_params.ant_coupling >
112 IWL_BT_ANTENNA_COUPLING_THRESHOLD;
113}
114 104
115int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm) 105int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm)
116{ 106{
107 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX))
108 return 0;
109
117 return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC, 110 return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC,
118 sizeof(struct iwl_bt_coex_prio_tbl_cmd), 111 sizeof(struct iwl_bt_coex_prio_tbl_cmd),
119 &iwl_bt_prio_tbl); 112 &iwl_bt_prio_tbl);
120} 113}
121 114
122static int iwl_send_bt_env(struct iwl_mvm *mvm, u8 action, u8 type) 115const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = {
123{
124 struct iwl_bt_coex_prot_env_cmd env_cmd;
125 int ret;
126
127 env_cmd.action = action;
128 env_cmd.type = type;
129 ret = iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PROT_ENV, CMD_SYNC,
130 sizeof(env_cmd), &env_cmd);
131 if (ret)
132 IWL_ERR(mvm, "failed to send BT env command\n");
133 return ret;
134}
135
136enum iwl_bt_kill_msk {
137 BT_KILL_MSK_DEFAULT,
138 BT_KILL_MSK_SCO_HID_A2DP,
139 BT_KILL_MSK_REDUCED_TXPOW,
140 BT_KILL_MSK_MAX,
141};
142
143static const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = {
144 [BT_KILL_MSK_DEFAULT] = 0xffff0000, 116 [BT_KILL_MSK_DEFAULT] = 0xffff0000,
145 [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff, 117 [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff,
146 [BT_KILL_MSK_REDUCED_TXPOW] = 0, 118 [BT_KILL_MSK_REDUCED_TXPOW] = 0,
147}; 119};
148 120
149static const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = { 121const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = {
150 [BT_KILL_MSK_DEFAULT] = 0xffff0000, 122 [BT_KILL_MSK_DEFAULT] = 0xffff0000,
151 [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff, 123 [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff,
152 [BT_KILL_MSK_REDUCED_TXPOW] = 0, 124 [BT_KILL_MSK_REDUCED_TXPOW] = 0,
153}; 125};
154 126
155#define IWL_BT_DEFAULT_BOOST (0xf0f0f0f0) 127static const __le32 iwl_bt_prio_boost[BT_COEX_BOOST_SIZE] = {
156 128 cpu_to_le32(0xf0f0f0f0),
157/* Tight Coex */ 129 cpu_to_le32(0xc0c0c0c0),
158static const __le32 iwl_tight_lookup[BT_COEX_LUT_SIZE] = { 130 cpu_to_le32(0xfcfcfcfc),
159 cpu_to_le32(0xaaaaaaaa), 131 cpu_to_le32(0xff00ff00),
160 cpu_to_le32(0xaaaaaaaa),
161 cpu_to_le32(0xaeaaaaaa),
162 cpu_to_le32(0xaaaaaaaa),
163 cpu_to_le32(0xcc00ff28),
164 cpu_to_le32(0x0000aaaa),
165 cpu_to_le32(0xcc00aaaa),
166 cpu_to_le32(0x0000aaaa),
167 cpu_to_le32(0xc0004000),
168 cpu_to_le32(0x00000000),
169 cpu_to_le32(0xf0005000),
170 cpu_to_le32(0xf0005000),
171}; 132};
172 133
173/* Loose Coex */ 134static const __le32 iwl_single_shared_ant[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = {
174static const __le32 iwl_loose_lookup[BT_COEX_LUT_SIZE] = { 135 {
175 cpu_to_le32(0xaaaaaaaa), 136 cpu_to_le32(0x40000000),
176 cpu_to_le32(0xaaaaaaaa), 137 cpu_to_le32(0x00000000),
177 cpu_to_le32(0xaaaaaaaa), 138 cpu_to_le32(0x44000000),
178 cpu_to_le32(0xaaaaaaaa), 139 cpu_to_le32(0x00000000),
179 cpu_to_le32(0xcc00ff28), 140 cpu_to_le32(0x40000000),
180 cpu_to_le32(0x0000aaaa), 141 cpu_to_le32(0x00000000),
181 cpu_to_le32(0xcc00aaaa), 142 cpu_to_le32(0x44000000),
182 cpu_to_le32(0x0000aaaa), 143 cpu_to_le32(0x00000000),
183 cpu_to_le32(0x00000000), 144 cpu_to_le32(0xc0004000),
184 cpu_to_le32(0x00000000), 145 cpu_to_le32(0xf0005000),
185 cpu_to_le32(0xf0005000), 146 cpu_to_le32(0xc0004000),
186 cpu_to_le32(0xf0005000), 147 cpu_to_le32(0xf0005000),
148 },
149 {
150 cpu_to_le32(0x40000000),
151 cpu_to_le32(0x00000000),
152 cpu_to_le32(0x44000000),
153 cpu_to_le32(0x00000000),
154 cpu_to_le32(0x40000000),
155 cpu_to_le32(0x00000000),
156 cpu_to_le32(0x44000000),
157 cpu_to_le32(0x00000000),
158 cpu_to_le32(0xc0004000),
159 cpu_to_le32(0xf0005000),
160 cpu_to_le32(0xc0004000),
161 cpu_to_le32(0xf0005000),
162 },
163 {
164 cpu_to_le32(0x40000000),
165 cpu_to_le32(0x00000000),
166 cpu_to_le32(0x44000000),
167 cpu_to_le32(0x00000000),
168 cpu_to_le32(0x40000000),
169 cpu_to_le32(0x00000000),
170 cpu_to_le32(0x44000000),
171 cpu_to_le32(0x00000000),
172 cpu_to_le32(0xc0004000),
173 cpu_to_le32(0xf0005000),
174 cpu_to_le32(0xc0004000),
175 cpu_to_le32(0xf0005000),
176 },
187}; 177};
188 178
189/* Full concurrency */ 179static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = {
190static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = { 180 {
191 cpu_to_le32(0xaaaaaaaa), 181 /* Tight */
192 cpu_to_le32(0xaaaaaaaa), 182 cpu_to_le32(0xaaaaaaaa),
193 cpu_to_le32(0xaaaaaaaa), 183 cpu_to_le32(0xaaaaaaaa),
194 cpu_to_le32(0xaaaaaaaa), 184 cpu_to_le32(0xaeaaaaaa),
195 cpu_to_le32(0xaaaaaaaa), 185 cpu_to_le32(0xaaaaaaaa),
196 cpu_to_le32(0xaaaaaaaa), 186 cpu_to_le32(0xcc00ff28),
197 cpu_to_le32(0xaaaaaaaa), 187 cpu_to_le32(0x0000aaaa),
198 cpu_to_le32(0xaaaaaaaa), 188 cpu_to_le32(0xcc00aaaa),
199 cpu_to_le32(0x00000000), 189 cpu_to_le32(0x0000aaaa),
200 cpu_to_le32(0x00000000), 190 cpu_to_le32(0xc0004000),
201 cpu_to_le32(0x00000000), 191 cpu_to_le32(0x00000000),
202 cpu_to_le32(0x00000000), 192 cpu_to_le32(0xf0005000),
193 cpu_to_le32(0xf0005000),
194 },
195 {
196 /* Loose */
197 cpu_to_le32(0xaaaaaaaa),
198 cpu_to_le32(0xaaaaaaaa),
199 cpu_to_le32(0xaaaaaaaa),
200 cpu_to_le32(0xaaaaaaaa),
201 cpu_to_le32(0xcc00ff28),
202 cpu_to_le32(0x0000aaaa),
203 cpu_to_le32(0xcc00aaaa),
204 cpu_to_le32(0x0000aaaa),
205 cpu_to_le32(0x00000000),
206 cpu_to_le32(0x00000000),
207 cpu_to_le32(0xf0005000),
208 cpu_to_le32(0xf0005000),
209 },
210 {
211 /* Tx Tx disabled */
212 cpu_to_le32(0xaaaaaaaa),
213 cpu_to_le32(0xaaaaaaaa),
214 cpu_to_le32(0xaaaaaaaa),
215 cpu_to_le32(0xaaaaaaaa),
216 cpu_to_le32(0xcc00ff28),
217 cpu_to_le32(0x0000aaaa),
218 cpu_to_le32(0xcc00aaaa),
219 cpu_to_le32(0x0000aaaa),
220 cpu_to_le32(0xC0004000),
221 cpu_to_le32(0xC0004000),
222 cpu_to_le32(0xF0005000),
223 cpu_to_le32(0xF0005000),
224 },
203}; 225};
204 226
205/* single shared antenna */ 227/* 20MHz / 40MHz below / 40Mhz above*/
206static const __le32 iwl_single_shared_ant_lookup[BT_COEX_LUT_SIZE] = { 228static const __le64 iwl_ci_mask[][3] = {
207 cpu_to_le32(0x40000000), 229 /* dummy entry for channel 0 */
208 cpu_to_le32(0x00000000), 230 {cpu_to_le64(0), cpu_to_le64(0), cpu_to_le64(0)},
209 cpu_to_le32(0x44000000), 231 {
210 cpu_to_le32(0x00000000), 232 cpu_to_le64(0x0000001FFFULL),
211 cpu_to_le32(0x40000000), 233 cpu_to_le64(0x0ULL),
212 cpu_to_le32(0x00000000), 234 cpu_to_le64(0x00007FFFFFULL),
213 cpu_to_le32(0x44000000), 235 },
214 cpu_to_le32(0x00000000), 236 {
215 cpu_to_le32(0xC0004000), 237 cpu_to_le64(0x000000FFFFULL),
216 cpu_to_le32(0xF0005000), 238 cpu_to_le64(0x0ULL),
217 cpu_to_le32(0xC0004000), 239 cpu_to_le64(0x0003FFFFFFULL),
218 cpu_to_le32(0xF0005000), 240 },
241 {
242 cpu_to_le64(0x000003FFFCULL),
243 cpu_to_le64(0x0ULL),
244 cpu_to_le64(0x000FFFFFFCULL),
245 },
246 {
247 cpu_to_le64(0x00001FFFE0ULL),
248 cpu_to_le64(0x0ULL),
249 cpu_to_le64(0x007FFFFFE0ULL),
250 },
251 {
252 cpu_to_le64(0x00007FFF80ULL),
253 cpu_to_le64(0x00007FFFFFULL),
254 cpu_to_le64(0x01FFFFFF80ULL),
255 },
256 {
257 cpu_to_le64(0x0003FFFC00ULL),
258 cpu_to_le64(0x0003FFFFFFULL),
259 cpu_to_le64(0x0FFFFFFC00ULL),
260 },
261 {
262 cpu_to_le64(0x000FFFF000ULL),
263 cpu_to_le64(0x000FFFFFFCULL),
264 cpu_to_le64(0x3FFFFFF000ULL),
265 },
266 {
267 cpu_to_le64(0x007FFF8000ULL),
268 cpu_to_le64(0x007FFFFFE0ULL),
269 cpu_to_le64(0xFFFFFF8000ULL),
270 },
271 {
272 cpu_to_le64(0x01FFFE0000ULL),
273 cpu_to_le64(0x01FFFFFF80ULL),
274 cpu_to_le64(0xFFFFFE0000ULL),
275 },
276 {
277 cpu_to_le64(0x0FFFF00000ULL),
278 cpu_to_le64(0x0FFFFFFC00ULL),
279 cpu_to_le64(0x0ULL),
280 },
281 {
282 cpu_to_le64(0x3FFFC00000ULL),
283 cpu_to_le64(0x3FFFFFF000ULL),
284 cpu_to_le64(0x0)
285 },
286 {
287 cpu_to_le64(0xFFFE000000ULL),
288 cpu_to_le64(0xFFFFFF8000ULL),
289 cpu_to_le64(0x0)
290 },
291 {
292 cpu_to_le64(0xFFF8000000ULL),
293 cpu_to_le64(0xFFFFFE0000ULL),
294 cpu_to_le64(0x0)
295 },
296 {
297 cpu_to_le64(0xFE00000000ULL),
298 cpu_to_le64(0x0ULL),
299 cpu_to_le64(0x0)
300 },
219}; 301};
220 302
303static const __le32 iwl_bt_mprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE] = {
304 cpu_to_le32(0x22002200),
305 cpu_to_le32(0x33113311),
306};
307
308static enum iwl_bt_coex_lut_type
309iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
310{
311 struct ieee80211_chanctx_conf *chanctx_conf;
312 enum iwl_bt_coex_lut_type ret;
313 u16 phy_ctx_id;
314
315 /*
316 * Checking that we hold mvm->mutex is a good idea, but the rate
317 * control can't acquire the mutex since it runs in Tx path.
318 * So this is racy in that case, but in the worst case, the AMPDU
319 * size limit will be wrong for a short time which is not a big
320 * issue.
321 */
322
323 rcu_read_lock();
324
325 chanctx_conf = rcu_dereference(vif->chanctx_conf);
326
327 if (!chanctx_conf ||
328 chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ) {
329 rcu_read_unlock();
330 return BT_COEX_LOOSE_LUT;
331 }
332
333 ret = BT_COEX_TX_DIS_LUT;
334
335 if (mvm->cfg->bt_shared_single_ant) {
336 rcu_read_unlock();
337 return ret;
338 }
339
340 phy_ctx_id = *((u16 *)chanctx_conf->drv_priv);
341
342 if (mvm->last_bt_ci_cmd.primary_ch_phy_id == phy_ctx_id)
343 ret = le32_to_cpu(mvm->last_bt_notif.primary_ch_lut);
344 else if (mvm->last_bt_ci_cmd.secondary_ch_phy_id == phy_ctx_id)
345 ret = le32_to_cpu(mvm->last_bt_notif.secondary_ch_lut);
346 /* else - default = TX TX disallowed */
347
348 rcu_read_unlock();
349
350 return ret;
351}
352
221int iwl_send_bt_init_conf(struct iwl_mvm *mvm) 353int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
222{ 354{
223 struct iwl_bt_coex_cmd *bt_cmd; 355 struct iwl_bt_coex_cmd *bt_cmd;
@@ -228,17 +360,10 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
228 .flags = CMD_SYNC, 360 .flags = CMD_SYNC,
229 }; 361 };
230 int ret; 362 int ret;
363 u32 flags;
231 364
232 /* go to CALIB state in internal BT-Coex state machine */ 365 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX))
233 ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN, 366 return 0;
234 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
235 if (ret)
236 return ret;
237
238 ret = iwl_send_bt_env(mvm, BT_COEX_ENV_CLOSE,
239 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
240 if (ret)
241 return ret;
242 367
243 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL); 368 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
244 if (!bt_cmd) 369 if (!bt_cmd)
@@ -246,40 +371,52 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
246 cmd.data[0] = bt_cmd; 371 cmd.data[0] = bt_cmd;
247 372
248 bt_cmd->max_kill = 5; 373 bt_cmd->max_kill = 5;
249 bt_cmd->bt3_time_t7_value = 1; 374 bt_cmd->bt4_antenna_isolation_thr = BT_ANTENNA_COUPLING_THRESHOLD,
250 bt_cmd->bt3_prio_sample_time = 2; 375 bt_cmd->bt4_antenna_isolation = iwlwifi_mod_params.ant_coupling,
251 bt_cmd->bt3_timer_t2_value = 0xc; 376 bt_cmd->bt4_tx_tx_delta_freq_thr = 15,
377 bt_cmd->bt4_tx_rx_max_freq0 = 15,
252 378
253 bt_cmd->flags = iwlwifi_mod_params.bt_coex_active ? 379 flags = iwlwifi_mod_params.bt_coex_active ?
254 BT_COEX_NW : BT_COEX_DISABLE; 380 BT_COEX_NW : BT_COEX_DISABLE;
255 bt_cmd->flags |= BT_CH_PRIMARY_EN | BT_SYNC_2_BT_DISABLE; 381 flags |= BT_CH_PRIMARY_EN | BT_CH_SECONDARY_EN | BT_SYNC_2_BT_DISABLE;
382 bt_cmd->flags = cpu_to_le32(flags);
256 383
257 bt_cmd->valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE | 384 bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_ENABLE |
258 BT_VALID_BT_PRIO_BOOST | 385 BT_VALID_BT_PRIO_BOOST |
259 BT_VALID_MAX_KILL | 386 BT_VALID_MAX_KILL |
260 BT_VALID_3W_TMRS | 387 BT_VALID_3W_TMRS |
261 BT_VALID_KILL_ACK | 388 BT_VALID_KILL_ACK |
262 BT_VALID_KILL_CTS | 389 BT_VALID_KILL_CTS |
263 BT_VALID_REDUCED_TX_POWER | 390 BT_VALID_REDUCED_TX_POWER |
264 BT_VALID_LUT); 391 BT_VALID_LUT |
392 BT_VALID_WIFI_RX_SW_PRIO_BOOST |
393 BT_VALID_WIFI_TX_SW_PRIO_BOOST |
394 BT_VALID_MULTI_PRIO_LUT |
395 BT_VALID_CORUN_LUT_20 |
396 BT_VALID_CORUN_LUT_40 |
397 BT_VALID_ANT_ISOLATION |
398 BT_VALID_ANT_ISOLATION_THRS |
399 BT_VALID_TXTX_DELTA_FREQ_THRS |
400 BT_VALID_TXRX_MAX_FREQ_0);
265 401
266 if (mvm->cfg->bt_shared_single_ant) 402 if (mvm->cfg->bt_shared_single_ant)
267 memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant_lookup, 403 memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant,
268 sizeof(iwl_single_shared_ant_lookup)); 404 sizeof(iwl_single_shared_ant));
269 else if (is_loose_coex())
270 memcpy(&bt_cmd->decision_lut, iwl_loose_lookup,
271 sizeof(iwl_tight_lookup));
272 else 405 else
273 memcpy(&bt_cmd->decision_lut, iwl_tight_lookup, 406 memcpy(&bt_cmd->decision_lut, iwl_combined_lookup,
274 sizeof(iwl_tight_lookup)); 407 sizeof(iwl_combined_lookup));
275 408
276 bt_cmd->bt_prio_boost = cpu_to_le32(IWL_BT_DEFAULT_BOOST); 409 memcpy(&bt_cmd->bt_prio_boost, iwl_bt_prio_boost,
410 sizeof(iwl_bt_prio_boost));
411 memcpy(&bt_cmd->bt4_multiprio_lut, iwl_bt_mprio_lut,
412 sizeof(iwl_bt_mprio_lut));
277 bt_cmd->kill_ack_msk = 413 bt_cmd->kill_ack_msk =
278 cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]); 414 cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]);
279 bt_cmd->kill_cts_msk = 415 bt_cmd->kill_cts_msk =
280 cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]); 416 cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]);
281 417
282 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif)); 418 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
419 memset(&mvm->last_bt_ci_cmd, 0, sizeof(mvm->last_bt_ci_cmd));
283 420
284 ret = iwl_mvm_send_cmd(mvm, &cmd); 421 ret = iwl_mvm_send_cmd(mvm, &cmd);
285 422
@@ -334,13 +471,17 @@ static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm,
334 if (!bt_cmd) 471 if (!bt_cmd)
335 return -ENOMEM; 472 return -ENOMEM;
336 cmd.data[0] = bt_cmd; 473 cmd.data[0] = bt_cmd;
474 bt_cmd->flags = cpu_to_le32(BT_COEX_NW);
337 475
338 bt_cmd->kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]); 476 bt_cmd->kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]);
339 bt_cmd->kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]); 477 bt_cmd->kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]);
340 bt_cmd->valid_bit_msk = 478 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_ENABLE |
341 cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS); 479 BT_VALID_KILL_ACK |
480 BT_VALID_KILL_CTS);
342 481
343 IWL_DEBUG_COEX(mvm, "bt_kill_msk = %d\n", bt_kill_msk); 482 IWL_DEBUG_COEX(mvm, "ACK Kill msk = 0x%08x, CTS Kill msk = 0x%08x\n",
483 iwl_bt_ack_kill_msk[bt_kill_msk],
484 iwl_bt_cts_kill_msk[bt_kill_msk]);
344 485
345 ret = iwl_mvm_send_cmd(mvm, &cmd); 486 ret = iwl_mvm_send_cmd(mvm, &cmd);
346 487
@@ -380,8 +521,10 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
380 if (!bt_cmd) 521 if (!bt_cmd)
381 return -ENOMEM; 522 return -ENOMEM;
382 cmd.data[0] = bt_cmd; 523 cmd.data[0] = bt_cmd;
524 bt_cmd->flags = cpu_to_le32(BT_COEX_NW);
383 525
384 bt_cmd->valid_bit_msk = cpu_to_le16(BT_VALID_REDUCED_TX_POWER), 526 bt_cmd->valid_bit_msk =
527 cpu_to_le32(BT_VALID_ENABLE | BT_VALID_REDUCED_TX_POWER);
385 bt_cmd->bt_reduced_tx_power = sta_id; 528 bt_cmd->bt_reduced_tx_power = sta_id;
386 529
387 if (enable) 530 if (enable)
@@ -403,8 +546,25 @@ struct iwl_bt_iterator_data {
403 struct iwl_mvm *mvm; 546 struct iwl_mvm *mvm;
404 u32 num_bss_ifaces; 547 u32 num_bss_ifaces;
405 bool reduced_tx_power; 548 bool reduced_tx_power;
549 struct ieee80211_chanctx_conf *primary;
550 struct ieee80211_chanctx_conf *secondary;
406}; 551};
407 552
553static inline
554void iwl_mvm_bt_coex_enable_rssi_event(struct iwl_mvm *mvm,
555 struct ieee80211_vif *vif,
556 bool enable, int rssi)
557{
558 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
559
560 mvmvif->bf_data.last_bt_coex_event = rssi;
561 mvmvif->bf_data.bt_coex_max_thold =
562 enable ? BT_ENABLE_REDUCED_TXPOWER_THRESHOLD : 0;
563 mvmvif->bf_data.bt_coex_min_thold =
564 enable ? BT_DISABLE_REDUCED_TXPOWER_THRESHOLD : 0;
565}
566
567/* must be called under rcu_read_lock */
408static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, 568static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
409 struct ieee80211_vif *vif) 569 struct ieee80211_vif *vif)
410{ 570{
@@ -413,65 +573,94 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
413 struct iwl_mvm *mvm = data->mvm; 573 struct iwl_mvm *mvm = data->mvm;
414 struct ieee80211_chanctx_conf *chanctx_conf; 574 struct ieee80211_chanctx_conf *chanctx_conf;
415 enum ieee80211_smps_mode smps_mode; 575 enum ieee80211_smps_mode smps_mode;
416 enum ieee80211_band band;
417 int ave_rssi; 576 int ave_rssi;
418 577
419 lockdep_assert_held(&mvm->mutex); 578 lockdep_assert_held(&mvm->mutex);
420 if (vif->type != NL80211_IFTYPE_STATION)
421 return;
422 579
423 rcu_read_lock(); 580 if (vif->type != NL80211_IFTYPE_STATION &&
424 chanctx_conf = rcu_dereference(vif->chanctx_conf); 581 vif->type != NL80211_IFTYPE_AP)
425 if (chanctx_conf && chanctx_conf->def.chan) 582 return;
426 band = chanctx_conf->def.chan->band;
427 else
428 band = -1;
429 rcu_read_unlock();
430 583
431 smps_mode = IEEE80211_SMPS_AUTOMATIC; 584 smps_mode = IEEE80211_SMPS_AUTOMATIC;
432 585
433 /* non associated BSSes aren't to be considered */ 586 chanctx_conf = rcu_dereference(vif->chanctx_conf);
434 if (!vif->bss_conf.assoc) 587
588 /* If channel context is invalid or not on 2.4GHz .. */
589 if ((!chanctx_conf ||
590 chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ)) {
591 /* ... and it is an associated STATION, relax constraints */
592 if (vif->type == NL80211_IFTYPE_STATION && vif->bss_conf.assoc)
593 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
594 smps_mode);
595 iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0);
435 return; 596 return;
597 }
598
599 /* SoftAP / GO will always be primary */
600 if (vif->type == NL80211_IFTYPE_AP) {
601 if (!mvmvif->ap_ibss_active)
602 return;
603
604 /* the Ack / Cts kill mask must be default if AP / GO */
605 data->reduced_tx_power = false;
436 606
437 if (band != IEEE80211_BAND_2GHZ) { 607 if (chanctx_conf == data->primary)
438 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, 608 return;
439 smps_mode); 609
610 /* downgrade the current primary no matter what its type is */
611 data->secondary = data->primary;
612 data->primary = chanctx_conf;
440 return; 613 return;
441 } 614 }
442 615
443 if (data->notif->bt_status) 616 data->num_bss_ifaces++;
444 smps_mode = IEEE80211_SMPS_DYNAMIC; 617
618 /* we are now a STA / P2P Client, and take associated ones only */
619 if (!vif->bss_conf.assoc)
620 return;
621
622 /* STA / P2P Client, try to be primary if first vif */
623 if (!data->primary || data->primary == chanctx_conf)
624 data->primary = chanctx_conf;
625 else if (!data->secondary)
626 /* if secondary is not NULL, it might be a GO */
627 data->secondary = chanctx_conf;
445 628
446 if (data->notif->bt_traffic_load >= IWL_BT_LOAD_FORCE_SISO_THRESHOLD) 629 if (le32_to_cpu(data->notif->bt_activity_grading) >= BT_HIGH_TRAFFIC)
447 smps_mode = IEEE80211_SMPS_STATIC; 630 smps_mode = IEEE80211_SMPS_STATIC;
631 else if (le32_to_cpu(data->notif->bt_activity_grading) >=
632 BT_LOW_TRAFFIC)
633 smps_mode = IEEE80211_SMPS_DYNAMIC;
448 634
449 IWL_DEBUG_COEX(data->mvm, 635 IWL_DEBUG_COEX(data->mvm,
450 "mac %d: bt_status %d traffic_load %d smps_req %d\n", 636 "mac %d: bt_status %d bt_activity_grading %d smps_req %d\n",
451 mvmvif->id, data->notif->bt_status, 637 mvmvif->id, data->notif->bt_status,
452 data->notif->bt_traffic_load, smps_mode); 638 data->notif->bt_activity_grading, smps_mode);
453 639
454 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, smps_mode); 640 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, smps_mode);
455 641
456 /* don't reduce the Tx power if in loose scheme */ 642 /* don't reduce the Tx power if in loose scheme */
457 if (is_loose_coex()) 643 if (iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT ||
644 mvm->cfg->bt_shared_single_ant) {
645 data->reduced_tx_power = false;
646 iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0);
458 return; 647 return;
648 }
459 649
460 data->num_bss_ifaces++; 650 /* reduced Txpower only if BT is on, so ...*/
461 651 if (!data->notif->bt_status) {
462 /* reduced Txpower only if there are open BT connections, so ...*/
463 if (!BT_MBOX_MSG(data->notif, 3, OPEN_CON_2)) {
464 /* ... cancel reduced Tx power ... */ 652 /* ... cancel reduced Tx power ... */
465 if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false)) 653 if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false))
466 IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n"); 654 IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
467 data->reduced_tx_power = false; 655 data->reduced_tx_power = false;
468 656
469 /* ... and there is no need to get reports on RSSI any more. */ 657 /* ... and there is no need to get reports on RSSI any more. */
470 ieee80211_disable_rssi_reports(vif); 658 iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0);
471 return; 659 return;
472 } 660 }
473 661
474 ave_rssi = ieee80211_ave_rssi(vif); 662 /* try to get the avg rssi from fw */
663 ave_rssi = mvmvif->bf_data.ave_beacon_signal;
475 664
476 /* if the RSSI isn't valid, fake it is very low */ 665 /* if the RSSI isn't valid, fake it is very low */
477 if (!ave_rssi) 666 if (!ave_rssi)
@@ -499,8 +688,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
499 } 688 }
500 689
501 /* Begin to monitor the RSSI: it may influence the reduced Tx power */ 690 /* Begin to monitor the RSSI: it may influence the reduced Tx power */
502 ieee80211_enable_rssi_reports(vif, BT_DISABLE_REDUCED_TXPOWER_THRESHOLD, 691 iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, true, ave_rssi);
503 BT_ENABLE_REDUCED_TXPOWER_THRESHOLD);
504} 692}
505 693
506static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm) 694static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
@@ -510,11 +698,72 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
510 .notif = &mvm->last_bt_notif, 698 .notif = &mvm->last_bt_notif,
511 .reduced_tx_power = true, 699 .reduced_tx_power = true,
512 }; 700 };
701 struct iwl_bt_coex_ci_cmd cmd = {};
702 u8 ci_bw_idx;
513 703
704 rcu_read_lock();
514 ieee80211_iterate_active_interfaces_atomic( 705 ieee80211_iterate_active_interfaces_atomic(
515 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 706 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
516 iwl_mvm_bt_notif_iterator, &data); 707 iwl_mvm_bt_notif_iterator, &data);
517 708
709 if (data.primary) {
710 struct ieee80211_chanctx_conf *chan = data.primary;
711 if (WARN_ON(!chan->def.chan)) {
712 rcu_read_unlock();
713 return;
714 }
715
716 if (chan->def.width < NL80211_CHAN_WIDTH_40) {
717 ci_bw_idx = 0;
718 cmd.co_run_bw_primary = 0;
719 } else {
720 cmd.co_run_bw_primary = 1;
721 if (chan->def.center_freq1 >
722 chan->def.chan->center_freq)
723 ci_bw_idx = 2;
724 else
725 ci_bw_idx = 1;
726 }
727
728 cmd.bt_primary_ci =
729 iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx];
730 cmd.primary_ch_phy_id = *((u16 *)data.primary->drv_priv);
731 }
732
733 if (data.secondary) {
734 struct ieee80211_chanctx_conf *chan = data.secondary;
735 if (WARN_ON(!data.secondary->def.chan)) {
736 rcu_read_unlock();
737 return;
738 }
739
740 if (chan->def.width < NL80211_CHAN_WIDTH_40) {
741 ci_bw_idx = 0;
742 cmd.co_run_bw_secondary = 0;
743 } else {
744 cmd.co_run_bw_secondary = 1;
745 if (chan->def.center_freq1 >
746 chan->def.chan->center_freq)
747 ci_bw_idx = 2;
748 else
749 ci_bw_idx = 1;
750 }
751
752 cmd.bt_secondary_ci =
753 iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx];
754 cmd.secondary_ch_phy_id = *((u16 *)data.primary->drv_priv);
755 }
756
757 rcu_read_unlock();
758
759 /* Don't spam the fw with the same command over and over */
760 if (memcmp(&cmd, &mvm->last_bt_ci_cmd, sizeof(cmd))) {
761 if (iwl_mvm_send_cmd_pdu(mvm, BT_COEX_CI, CMD_SYNC,
762 sizeof(cmd), &cmd))
763 IWL_ERR(mvm, "Failed to send BT_CI cmd");
764 memcpy(&mvm->last_bt_ci_cmd, &cmd, sizeof(cmd));
765 }
766
518 /* 767 /*
519 * If there are no BSS / P2P client interfaces, reduced Tx Power is 768 * If there are no BSS / P2P client interfaces, reduced Tx Power is
520 * irrelevant since it is based on the RSSI coming from the beacon. 769 * irrelevant since it is based on the RSSI coming from the beacon.
@@ -536,12 +785,18 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
536 785
537 786
538 IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n"); 787 IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
539 IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not "); 788 IWL_DEBUG_COEX(mvm, "\tBT status: %s\n",
789 notif->bt_status ? "ON" : "OFF");
540 IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn); 790 IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn);
541 IWL_DEBUG_COEX(mvm, "\tBT traffic load %d\n", notif->bt_traffic_load); 791 IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
792 IWL_DEBUG_COEX(mvm, "\tBT primary_ch_lut %d\n",
793 le32_to_cpu(notif->primary_ch_lut));
794 IWL_DEBUG_COEX(mvm, "\tBT secondary_ch_lut %d\n",
795 le32_to_cpu(notif->secondary_ch_lut));
796 IWL_DEBUG_COEX(mvm, "\tBT activity grading %d\n",
797 le32_to_cpu(notif->bt_activity_grading));
542 IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n", 798 IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n",
543 notif->bt_agg_traffic_load); 799 notif->bt_agg_traffic_load);
544 IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
545 800
546 /* remember this notification for future use: rssi fluctuations */ 801 /* remember this notification for future use: rssi fluctuations */
547 memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); 802 memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif));
@@ -565,6 +820,18 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
565 struct ieee80211_sta *sta; 820 struct ieee80211_sta *sta;
566 struct iwl_mvm_sta *mvmsta; 821 struct iwl_mvm_sta *mvmsta;
567 822
823 struct ieee80211_chanctx_conf *chanctx_conf;
824
825 rcu_read_lock();
826 chanctx_conf = rcu_dereference(vif->chanctx_conf);
827 /* If channel context is invalid or not on 2.4GHz - don't count it */
828 if (!chanctx_conf ||
829 chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ) {
830 rcu_read_unlock();
831 return;
832 }
833 rcu_read_unlock();
834
568 if (vif->type != NL80211_IFTYPE_STATION || 835 if (vif->type != NL80211_IFTYPE_STATION ||
569 mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT) 836 mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)
570 return; 837 return;
@@ -594,15 +861,15 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
594 }; 861 };
595 int ret; 862 int ret;
596 863
597 mutex_lock(&mvm->mutex); 864 lockdep_assert_held(&mvm->mutex);
598 865
599 /* Rssi update while not associated ?! */ 866 /* Rssi update while not associated ?! */
600 if (WARN_ON_ONCE(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)) 867 if (WARN_ON_ONCE(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT))
601 goto out_unlock; 868 return;
602 869
603 /* No open connection - reports should be disabled */ 870 /* No BT - reports should be disabled */
604 if (!BT_MBOX_MSG(&mvm->last_bt_notif, 3, OPEN_CON_2)) 871 if (!mvm->last_bt_notif.bt_status)
605 goto out_unlock; 872 return;
606 873
607 IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid, 874 IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid,
608 rssi_event == RSSI_EVENT_HIGH ? "HIGH" : "LOW"); 875 rssi_event == RSSI_EVENT_HIGH ? "HIGH" : "LOW");
@@ -611,7 +878,8 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
611 * Check if rssi is good enough for reduced Tx power, but not in loose 878 * Check if rssi is good enough for reduced Tx power, but not in loose
612 * scheme. 879 * scheme.
613 */ 880 */
614 if (rssi_event == RSSI_EVENT_LOW || is_loose_coex()) 881 if (rssi_event == RSSI_EVENT_LOW || mvm->cfg->bt_shared_single_ant ||
882 iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT)
615 ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, 883 ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id,
616 false); 884 false);
617 else 885 else
@@ -633,12 +901,52 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
633 901
634 if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power)) 902 if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power))
635 IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n"); 903 IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
904}
905
906#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000)
907#define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200)
636 908
637 out_unlock: 909u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm,
638 mutex_unlock(&mvm->mutex); 910 struct ieee80211_sta *sta)
911{
912 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
913 enum iwl_bt_coex_lut_type lut_type;
914
915 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
916 BT_LOW_TRAFFIC)
917 return LINK_QUAL_AGG_TIME_LIMIT_DEF;
918
919 lut_type = iwl_get_coex_type(mvm, mvmsta->vif);
920
921 if (lut_type == BT_COEX_LOOSE_LUT)
922 return LINK_QUAL_AGG_TIME_LIMIT_DEF;
923
924 /* tight coex, high bt traffic, reduce AGG time limit */
925 return LINK_QUAL_AGG_TIME_LIMIT_BT_ACT;
926}
927
928bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
929 struct ieee80211_sta *sta)
930{
931 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
932
933 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
934 BT_HIGH_TRAFFIC)
935 return true;
936
937 /*
938 * In Tight, BT can't Rx while we Tx, so use both antennas since BT is
939 * already killed.
940 * In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while we
941 * Tx.
942 */
943 return iwl_get_coex_type(mvm, mvmsta->vif) == BT_COEX_TIGHT_LUT;
639} 944}
640 945
641void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 946void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm)
642{ 947{
948 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX))
949 return;
950
643 iwl_mvm_bt_coex_notif_handle(mvm); 951 iwl_mvm_bt_coex_notif_handle(mvm);
644} 952}
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index 2bf29f7992ee..4b6d670c3509 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -70,7 +70,9 @@
70#define IWL_MVM_UAPSD_RX_DATA_TIMEOUT (50 * USEC_PER_MSEC) 70#define IWL_MVM_UAPSD_RX_DATA_TIMEOUT (50 * USEC_PER_MSEC)
71#define IWL_MVM_UAPSD_TX_DATA_TIMEOUT (50 * USEC_PER_MSEC) 71#define IWL_MVM_UAPSD_TX_DATA_TIMEOUT (50 * USEC_PER_MSEC)
72#define IWL_MVM_PS_HEAVY_TX_THLD_PACKETS 20 72#define IWL_MVM_PS_HEAVY_TX_THLD_PACKETS 20
73#define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 20 73#define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 8
74#define IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS 30
75#define IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS 20
74#define IWL_MVM_PS_HEAVY_TX_THLD_PERCENT 50 76#define IWL_MVM_PS_HEAVY_TX_THLD_PERCENT 50
75#define IWL_MVM_PS_HEAVY_RX_THLD_PERCENT 50 77#define IWL_MVM_PS_HEAVY_RX_THLD_PERCENT 50
76#define IWL_MVM_PS_SNOOZE_INTERVAL 25 78#define IWL_MVM_PS_SNOOZE_INTERVAL 25
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 417639f77b01..6f45966817bb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -67,6 +67,7 @@
67#include <net/cfg80211.h> 67#include <net/cfg80211.h>
68#include <net/ipv6.h> 68#include <net/ipv6.h>
69#include <net/tcp.h> 69#include <net/tcp.h>
70#include <net/addrconf.h>
70#include "iwl-modparams.h" 71#include "iwl-modparams.h"
71#include "fw-api.h" 72#include "fw-api.h"
72#include "mvm.h" 73#include "mvm.h"
@@ -381,14 +382,74 @@ static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
381 union { 382 union {
382 struct iwl_proto_offload_cmd_v1 v1; 383 struct iwl_proto_offload_cmd_v1 v1;
383 struct iwl_proto_offload_cmd_v2 v2; 384 struct iwl_proto_offload_cmd_v2 v2;
385 struct iwl_proto_offload_cmd_v3_small v3s;
386 struct iwl_proto_offload_cmd_v3_large v3l;
384 } cmd = {}; 387 } cmd = {};
388 struct iwl_host_cmd hcmd = {
389 .id = PROT_OFFLOAD_CONFIG_CMD,
390 .flags = CMD_SYNC,
391 .data[0] = &cmd,
392 .dataflags[0] = IWL_HCMD_DFL_DUP,
393 };
385 struct iwl_proto_offload_cmd_common *common; 394 struct iwl_proto_offload_cmd_common *common;
386 u32 enabled = 0, size; 395 u32 enabled = 0, size;
396 u32 capa_flags = mvm->fw->ucode_capa.flags;
387#if IS_ENABLED(CONFIG_IPV6) 397#if IS_ENABLED(CONFIG_IPV6)
388 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 398 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
389 int i; 399 int i;
390 400
391 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) { 401 if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL ||
402 capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE) {
403 struct iwl_ns_config *nsc;
404 struct iwl_targ_addr *addrs;
405 int n_nsc, n_addrs;
406 int c;
407
408 if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL) {
409 nsc = cmd.v3s.ns_config;
410 n_nsc = IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3S;
411 addrs = cmd.v3s.targ_addrs;
412 n_addrs = IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S;
413 } else {
414 nsc = cmd.v3l.ns_config;
415 n_nsc = IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L;
416 addrs = cmd.v3l.targ_addrs;
417 n_addrs = IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L;
418 }
419
420 if (mvmvif->num_target_ipv6_addrs)
421 enabled |= IWL_D3_PROTO_OFFLOAD_NS;
422
423 /*
424 * For each address we have (and that will fit) fill a target
425 * address struct and combine for NS offload structs with the
426 * solicited node addresses.
427 */
428 for (i = 0, c = 0;
429 i < mvmvif->num_target_ipv6_addrs &&
430 i < n_addrs && c < n_nsc; i++) {
431 struct in6_addr solicited_addr;
432 int j;
433
434 addrconf_addr_solict_mult(&mvmvif->target_ipv6_addrs[i],
435 &solicited_addr);
436 for (j = 0; j < c; j++)
437 if (ipv6_addr_cmp(&nsc[j].dest_ipv6_addr,
438 &solicited_addr) == 0)
439 break;
440 if (j == c)
441 c++;
442 addrs[i].addr = mvmvif->target_ipv6_addrs[i];
443 addrs[i].config_num = cpu_to_le32(j);
444 nsc[j].dest_ipv6_addr = solicited_addr;
445 memcpy(nsc[j].target_mac_addr, vif->addr, ETH_ALEN);
446 }
447
448 if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL)
449 cmd.v3s.num_valid_ipv6_addrs = cpu_to_le32(i);
450 else
451 cmd.v3l.num_valid_ipv6_addrs = cpu_to_le32(i);
452 } else if (capa_flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) {
392 if (mvmvif->num_target_ipv6_addrs) { 453 if (mvmvif->num_target_ipv6_addrs) {
393 enabled |= IWL_D3_PROTO_OFFLOAD_NS; 454 enabled |= IWL_D3_PROTO_OFFLOAD_NS;
394 memcpy(cmd.v2.ndp_mac_addr, vif->addr, ETH_ALEN); 455 memcpy(cmd.v2.ndp_mac_addr, vif->addr, ETH_ALEN);
@@ -419,7 +480,13 @@ static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
419 } 480 }
420#endif 481#endif
421 482
422 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) { 483 if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL) {
484 common = &cmd.v3s.common;
485 size = sizeof(cmd.v3s);
486 } else if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE) {
487 common = &cmd.v3l.common;
488 size = sizeof(cmd.v3l);
489 } else if (capa_flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) {
423 common = &cmd.v2.common; 490 common = &cmd.v2.common;
424 size = sizeof(cmd.v2); 491 size = sizeof(cmd.v2);
425 } else { 492 } else {
@@ -438,8 +505,8 @@ static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
438 505
439 common->enabled = cpu_to_le32(enabled); 506 common->enabled = cpu_to_le32(enabled);
440 507
441 return iwl_mvm_send_cmd_pdu(mvm, PROT_OFFLOAD_CONFIG_CMD, CMD_SYNC, 508 hcmd.len[0] = size;
442 size, &cmd); 509 return iwl_mvm_send_cmd(mvm, &hcmd);
443} 510}
444 511
445enum iwl_mvm_tcp_packet_type { 512enum iwl_mvm_tcp_packet_type {
@@ -793,6 +860,74 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
793 return 0; 860 return 0;
794} 861}
795 862
863static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm *mvm,
864 struct ieee80211_vif *vif)
865{
866 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
867 struct iwl_nonqos_seq_query_cmd query_cmd = {
868 .get_set_flag = cpu_to_le32(IWL_NONQOS_SEQ_GET),
869 .mac_id_n_color =
870 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
871 mvmvif->color)),
872 };
873 struct iwl_host_cmd cmd = {
874 .id = NON_QOS_TX_COUNTER_CMD,
875 .flags = CMD_SYNC | CMD_WANT_SKB,
876 };
877 int err;
878 u32 size;
879
880 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API) {
881 cmd.data[0] = &query_cmd;
882 cmd.len[0] = sizeof(query_cmd);
883 }
884
885 err = iwl_mvm_send_cmd(mvm, &cmd);
886 if (err)
887 return err;
888
889 size = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
890 size -= sizeof(cmd.resp_pkt->hdr);
891 if (size < sizeof(__le16)) {
892 err = -EINVAL;
893 } else {
894 err = le16_to_cpup((__le16 *)cmd.resp_pkt->data);
895 /* new API returns next, not last-used seqno */
896 if (mvm->fw->ucode_capa.flags &
897 IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API)
898 err -= 0x10;
899 }
900
901 iwl_free_resp(&cmd);
902 return err;
903}
904
905void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
906{
907 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
908 struct iwl_nonqos_seq_query_cmd query_cmd = {
909 .get_set_flag = cpu_to_le32(IWL_NONQOS_SEQ_SET),
910 .mac_id_n_color =
911 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
912 mvmvif->color)),
913 .value = cpu_to_le16(mvmvif->seqno),
914 };
915
916 /* return if called during restart, not resume from D3 */
917 if (!mvmvif->seqno_valid)
918 return;
919
920 mvmvif->seqno_valid = false;
921
922 if (!(mvm->fw->ucode_capa.flags &
923 IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API))
924 return;
925
926 if (iwl_mvm_send_cmd_pdu(mvm, NON_QOS_TX_COUNTER_CMD, CMD_SYNC,
927 sizeof(query_cmd), &query_cmd))
928 IWL_ERR(mvm, "failed to set non-QoS seqno\n");
929}
930
796static int __iwl_mvm_suspend(struct ieee80211_hw *hw, 931static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
797 struct cfg80211_wowlan *wowlan, 932 struct cfg80211_wowlan *wowlan,
798 bool test) 933 bool test)
@@ -829,7 +964,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
829 }; 964 };
830 int ret, i; 965 int ret, i;
831 int len __maybe_unused; 966 int len __maybe_unused;
832 u16 seq;
833 u8 old_aux_sta_id, old_ap_sta_id = IWL_MVM_STATION_COUNT; 967 u8 old_aux_sta_id, old_ap_sta_id = IWL_MVM_STATION_COUNT;
834 968
835 if (!wowlan) { 969 if (!wowlan) {
@@ -872,26 +1006,15 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
872 1006
873 mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv; 1007 mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv;
874 1008
875 /*
876 * The D3 firmware still hardcodes the AP station ID for the
877 * BSS we're associated with as 0. Store the real STA ID here
878 * and assign 0. When we leave this function, we'll restore
879 * the original value for the resume code.
880 */
881 old_ap_sta_id = mvm_ap_sta->sta_id;
882 mvm_ap_sta->sta_id = 0;
883 mvmvif->ap_sta_id = 0;
884
885 /* TODO: wowlan_config_cmd.wowlan_ba_teardown_tids */ 1009 /* TODO: wowlan_config_cmd.wowlan_ba_teardown_tids */
886 1010
887 wowlan_config_cmd.is_11n_connection = ap_sta->ht_cap.ht_supported; 1011 wowlan_config_cmd.is_11n_connection = ap_sta->ht_cap.ht_supported;
888 1012
889 /* 1013 /* Query the last used seqno and set it */
890 * We know the last used seqno, and the uCode expects to know that 1014 ret = iwl_mvm_get_last_nonqos_seq(mvm, vif);
891 * one, it will increment before TX. 1015 if (ret < 0)
892 */ 1016 goto out_noreset;
893 seq = mvm_ap_sta->last_seq_ctl & IEEE80211_SCTL_SEQ; 1017 wowlan_config_cmd.non_qos_seq = cpu_to_le16(ret);
894 wowlan_config_cmd.non_qos_seq = cpu_to_le16(seq);
895 1018
896 /* 1019 /*
897 * For QoS counters, we store the one to use next, so subtract 0x10 1020 * For QoS counters, we store the one to use next, so subtract 0x10
@@ -899,7 +1022,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
899 * increment after using the value (i.e. store the next value to use). 1022 * increment after using the value (i.e. store the next value to use).
900 */ 1023 */
901 for (i = 0; i < IWL_MAX_TID_COUNT; i++) { 1024 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
902 seq = mvm_ap_sta->tid_data[i].seq_number; 1025 u16 seq = mvm_ap_sta->tid_data[i].seq_number;
903 seq -= 0x10; 1026 seq -= 0x10;
904 wowlan_config_cmd.qos_seq[i] = cpu_to_le16(seq); 1027 wowlan_config_cmd.qos_seq[i] = cpu_to_le16(seq);
905 } 1028 }
@@ -945,6 +1068,16 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
945 iwl_trans_stop_device(mvm->trans); 1068 iwl_trans_stop_device(mvm->trans);
946 1069
947 /* 1070 /*
1071 * The D3 firmware still hardcodes the AP station ID for the
1072 * BSS we're associated with as 0. Store the real STA ID here
1073 * and assign 0. When we leave this function, we'll restore
1074 * the original value for the resume code.
1075 */
1076 old_ap_sta_id = mvm_ap_sta->sta_id;
1077 mvm_ap_sta->sta_id = 0;
1078 mvmvif->ap_sta_id = 0;
1079
1080 /*
948 * Set the HW restart bit -- this is mostly true as we're 1081 * Set the HW restart bit -- this is mostly true as we're
949 * going to load new firmware and reprogram that, though 1082 * going to load new firmware and reprogram that, though
950 * the reprogramming is going to be manual to avoid adding 1083 * the reprogramming is going to be manual to avoid adding
@@ -1059,6 +1192,10 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1059 if (ret) 1192 if (ret)
1060 goto out; 1193 goto out;
1061 1194
1195 ret = iwl_mvm_power_update_device_mode(mvm);
1196 if (ret)
1197 goto out;
1198
1062 ret = iwl_mvm_power_update_mode(mvm, vif); 1199 ret = iwl_mvm_power_update_mode(mvm, vif);
1063 if (ret) 1200 if (ret)
1064 goto out; 1201 goto out;
@@ -1109,16 +1246,26 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
1109 return __iwl_mvm_suspend(hw, wowlan, false); 1246 return __iwl_mvm_suspend(hw, wowlan, false);
1110} 1247}
1111 1248
1249/* converted data from the different status responses */
1250struct iwl_wowlan_status_data {
1251 u16 pattern_number;
1252 u16 qos_seq_ctr[8];
1253 u32 wakeup_reasons;
1254 u32 wake_packet_length;
1255 u32 wake_packet_bufsize;
1256 const u8 *wake_packet;
1257};
1258
1112static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm, 1259static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
1113 struct ieee80211_vif *vif, 1260 struct ieee80211_vif *vif,
1114 struct iwl_wowlan_status *status) 1261 struct iwl_wowlan_status_data *status)
1115{ 1262{
1116 struct sk_buff *pkt = NULL; 1263 struct sk_buff *pkt = NULL;
1117 struct cfg80211_wowlan_wakeup wakeup = { 1264 struct cfg80211_wowlan_wakeup wakeup = {
1118 .pattern_idx = -1, 1265 .pattern_idx = -1,
1119 }; 1266 };
1120 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; 1267 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
1121 u32 reasons = le32_to_cpu(status->wakeup_reasons); 1268 u32 reasons = status->wakeup_reasons;
1122 1269
1123 if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) { 1270 if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {
1124 wakeup_report = NULL; 1271 wakeup_report = NULL;
@@ -1130,7 +1277,7 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
1130 1277
1131 if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) 1278 if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN)
1132 wakeup.pattern_idx = 1279 wakeup.pattern_idx =
1133 le16_to_cpu(status->pattern_number); 1280 status->pattern_number;
1134 1281
1135 if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | 1282 if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
1136 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)) 1283 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH))
@@ -1158,8 +1305,8 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
1158 wakeup.tcp_match = true; 1305 wakeup.tcp_match = true;
1159 1306
1160 if (status->wake_packet_bufsize) { 1307 if (status->wake_packet_bufsize) {
1161 int pktsize = le32_to_cpu(status->wake_packet_bufsize); 1308 int pktsize = status->wake_packet_bufsize;
1162 int pktlen = le32_to_cpu(status->wake_packet_length); 1309 int pktlen = status->wake_packet_length;
1163 const u8 *pktdata = status->wake_packet; 1310 const u8 *pktdata = status->wake_packet;
1164 struct ieee80211_hdr *hdr = (void *)pktdata; 1311 struct ieee80211_hdr *hdr = (void *)pktdata;
1165 int truncated = pktlen - pktsize; 1312 int truncated = pktlen - pktsize;
@@ -1239,8 +1386,229 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
1239 kfree_skb(pkt); 1386 kfree_skb(pkt);
1240} 1387}
1241 1388
1389static void iwl_mvm_aes_sc_to_seq(struct aes_sc *sc,
1390 struct ieee80211_key_seq *seq)
1391{
1392 u64 pn;
1393
1394 pn = le64_to_cpu(sc->pn);
1395 seq->ccmp.pn[0] = pn >> 40;
1396 seq->ccmp.pn[1] = pn >> 32;
1397 seq->ccmp.pn[2] = pn >> 24;
1398 seq->ccmp.pn[3] = pn >> 16;
1399 seq->ccmp.pn[4] = pn >> 8;
1400 seq->ccmp.pn[5] = pn;
1401}
1402
1403static void iwl_mvm_tkip_sc_to_seq(struct tkip_sc *sc,
1404 struct ieee80211_key_seq *seq)
1405{
1406 seq->tkip.iv32 = le32_to_cpu(sc->iv32);
1407 seq->tkip.iv16 = le16_to_cpu(sc->iv16);
1408}
1409
1410static void iwl_mvm_set_aes_rx_seq(struct aes_sc *scs,
1411 struct ieee80211_key_conf *key)
1412{
1413 int tid;
1414
1415 BUILD_BUG_ON(IWL_NUM_RSC != IEEE80211_NUM_TIDS);
1416
1417 for (tid = 0; tid < IWL_NUM_RSC; tid++) {
1418 struct ieee80211_key_seq seq = {};
1419
1420 iwl_mvm_aes_sc_to_seq(&scs[tid], &seq);
1421 ieee80211_set_key_rx_seq(key, tid, &seq);
1422 }
1423}
1424
1425static void iwl_mvm_set_tkip_rx_seq(struct tkip_sc *scs,
1426 struct ieee80211_key_conf *key)
1427{
1428 int tid;
1429
1430 BUILD_BUG_ON(IWL_NUM_RSC != IEEE80211_NUM_TIDS);
1431
1432 for (tid = 0; tid < IWL_NUM_RSC; tid++) {
1433 struct ieee80211_key_seq seq = {};
1434
1435 iwl_mvm_tkip_sc_to_seq(&scs[tid], &seq);
1436 ieee80211_set_key_rx_seq(key, tid, &seq);
1437 }
1438}
1439
1440static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key,
1441 struct iwl_wowlan_status_v6 *status)
1442{
1443 union iwl_all_tsc_rsc *rsc = &status->gtk.rsc.all_tsc_rsc;
1444
1445 switch (key->cipher) {
1446 case WLAN_CIPHER_SUITE_CCMP:
1447 iwl_mvm_set_aes_rx_seq(rsc->aes.multicast_rsc, key);
1448 break;
1449 case WLAN_CIPHER_SUITE_TKIP:
1450 iwl_mvm_set_tkip_rx_seq(rsc->tkip.multicast_rsc, key);
1451 break;
1452 default:
1453 WARN_ON(1);
1454 }
1455}
1456
1457struct iwl_mvm_d3_gtk_iter_data {
1458 struct iwl_wowlan_status_v6 *status;
1459 void *last_gtk;
1460 u32 cipher;
1461 bool find_phase, unhandled_cipher;
1462 int num_keys;
1463};
1464
1465static void iwl_mvm_d3_update_gtks(struct ieee80211_hw *hw,
1466 struct ieee80211_vif *vif,
1467 struct ieee80211_sta *sta,
1468 struct ieee80211_key_conf *key,
1469 void *_data)
1470{
1471 struct iwl_mvm_d3_gtk_iter_data *data = _data;
1472
1473 if (data->unhandled_cipher)
1474 return;
1475
1476 switch (key->cipher) {
1477 case WLAN_CIPHER_SUITE_WEP40:
1478 case WLAN_CIPHER_SUITE_WEP104:
1479 /* ignore WEP completely, nothing to do */
1480 return;
1481 case WLAN_CIPHER_SUITE_CCMP:
1482 case WLAN_CIPHER_SUITE_TKIP:
1483 /* we support these */
1484 break;
1485 default:
1486 /* everything else (even CMAC for MFP) - disconnect from AP */
1487 data->unhandled_cipher = true;
1488 return;
1489 }
1490
1491 data->num_keys++;
1492
1493 /*
1494 * pairwise key - update sequence counters only;
1495 * note that this assumes no TDLS sessions are active
1496 */
1497 if (sta) {
1498 struct ieee80211_key_seq seq = {};
1499 union iwl_all_tsc_rsc *sc = &data->status->gtk.rsc.all_tsc_rsc;
1500
1501 if (data->find_phase)
1502 return;
1503
1504 switch (key->cipher) {
1505 case WLAN_CIPHER_SUITE_CCMP:
1506 iwl_mvm_aes_sc_to_seq(&sc->aes.tsc, &seq);
1507 iwl_mvm_set_aes_rx_seq(sc->aes.unicast_rsc, key);
1508 break;
1509 case WLAN_CIPHER_SUITE_TKIP:
1510 iwl_mvm_tkip_sc_to_seq(&sc->tkip.tsc, &seq);
1511 iwl_mvm_set_tkip_rx_seq(sc->tkip.unicast_rsc, key);
1512 break;
1513 }
1514 ieee80211_set_key_tx_seq(key, &seq);
1515
1516 /* that's it for this key */
1517 return;
1518 }
1519
1520 if (data->find_phase) {
1521 data->last_gtk = key;
1522 data->cipher = key->cipher;
1523 return;
1524 }
1525
1526 if (data->status->num_of_gtk_rekeys)
1527 ieee80211_remove_key(key);
1528 else if (data->last_gtk == key)
1529 iwl_mvm_set_key_rx_seq(key, data->status);
1530}
1531
1532static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
1533 struct ieee80211_vif *vif,
1534 struct iwl_wowlan_status_v6 *status)
1535{
1536 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1537 struct iwl_mvm_d3_gtk_iter_data gtkdata = {
1538 .status = status,
1539 };
1540
1541 if (!status || !vif->bss_conf.bssid)
1542 return false;
1543
1544 /* find last GTK that we used initially, if any */
1545 gtkdata.find_phase = true;
1546 ieee80211_iter_keys(mvm->hw, vif,
1547 iwl_mvm_d3_update_gtks, &gtkdata);
1548 /* not trying to keep connections with MFP/unhandled ciphers */
1549 if (gtkdata.unhandled_cipher)
1550 return false;
1551 if (!gtkdata.num_keys)
1552 return true;
1553 if (!gtkdata.last_gtk)
1554 return false;
1555
1556 /*
1557 * invalidate all other GTKs that might still exist and update
1558 * the one that we used
1559 */
1560 gtkdata.find_phase = false;
1561 ieee80211_iter_keys(mvm->hw, vif,
1562 iwl_mvm_d3_update_gtks, &gtkdata);
1563
1564 if (status->num_of_gtk_rekeys) {
1565 struct ieee80211_key_conf *key;
1566 struct {
1567 struct ieee80211_key_conf conf;
1568 u8 key[32];
1569 } conf = {
1570 .conf.cipher = gtkdata.cipher,
1571 .conf.keyidx = status->gtk.key_index,
1572 };
1573
1574 switch (gtkdata.cipher) {
1575 case WLAN_CIPHER_SUITE_CCMP:
1576 conf.conf.keylen = WLAN_KEY_LEN_CCMP;
1577 memcpy(conf.conf.key, status->gtk.decrypt_key,
1578 WLAN_KEY_LEN_CCMP);
1579 break;
1580 case WLAN_CIPHER_SUITE_TKIP:
1581 conf.conf.keylen = WLAN_KEY_LEN_TKIP;
1582 memcpy(conf.conf.key, status->gtk.decrypt_key, 16);
1583 /* leave TX MIC key zeroed, we don't use it anyway */
1584 memcpy(conf.conf.key +
1585 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
1586 status->gtk.tkip_mic_key, 8);
1587 break;
1588 }
1589
1590 key = ieee80211_gtk_rekey_add(vif, &conf.conf);
1591 if (IS_ERR(key))
1592 return false;
1593 iwl_mvm_set_key_rx_seq(key, status);
1594 }
1595
1596 if (status->num_of_gtk_rekeys) {
1597 __be64 replay_ctr =
1598 cpu_to_be64(le64_to_cpu(status->replay_ctr));
1599 ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid,
1600 (void *)&replay_ctr, GFP_KERNEL);
1601 }
1602
1603 mvmvif->seqno_valid = true;
1604 /* +0x10 because the set API expects next-to-use, not last-used */
1605 mvmvif->seqno = le16_to_cpu(status->non_qos_seq_ctr) + 0x10;
1606
1607 return true;
1608}
1609
1242/* releases the MVM mutex */ 1610/* releases the MVM mutex */
1243static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, 1611static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1244 struct ieee80211_vif *vif) 1612 struct ieee80211_vif *vif)
1245{ 1613{
1246 u32 base = mvm->error_event_table; 1614 u32 base = mvm->error_event_table;
@@ -1253,8 +1621,12 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1253 .id = WOWLAN_GET_STATUSES, 1621 .id = WOWLAN_GET_STATUSES,
1254 .flags = CMD_SYNC | CMD_WANT_SKB, 1622 .flags = CMD_SYNC | CMD_WANT_SKB,
1255 }; 1623 };
1256 struct iwl_wowlan_status *status; 1624 struct iwl_wowlan_status_data status;
1257 int ret, len; 1625 struct iwl_wowlan_status_v6 *status_v6;
1626 int ret, len, status_size, i;
1627 bool keep;
1628 struct ieee80211_sta *ap_sta;
1629 struct iwl_mvm_sta *mvm_ap_sta;
1258 1630
1259 iwl_trans_read_mem_bytes(mvm->trans, base, 1631 iwl_trans_read_mem_bytes(mvm->trans, base,
1260 &err_info, sizeof(err_info)); 1632 &err_info, sizeof(err_info));
@@ -1287,32 +1659,83 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1287 if (!cmd.resp_pkt) 1659 if (!cmd.resp_pkt)
1288 goto out_unlock; 1660 goto out_unlock;
1289 1661
1662 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API)
1663 status_size = sizeof(struct iwl_wowlan_status_v6);
1664 else
1665 status_size = sizeof(struct iwl_wowlan_status_v4);
1666
1290 len = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 1667 len = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
1291 if (len - sizeof(struct iwl_cmd_header) < sizeof(*status)) { 1668 if (len - sizeof(struct iwl_cmd_header) < status_size) {
1292 IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); 1669 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
1293 goto out_free_resp; 1670 goto out_free_resp;
1294 } 1671 }
1295 1672
1296 status = (void *)cmd.resp_pkt->data; 1673 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API) {
1674 status_v6 = (void *)cmd.resp_pkt->data;
1675
1676 status.pattern_number = le16_to_cpu(status_v6->pattern_number);
1677 for (i = 0; i < 8; i++)
1678 status.qos_seq_ctr[i] =
1679 le16_to_cpu(status_v6->qos_seq_ctr[i]);
1680 status.wakeup_reasons = le32_to_cpu(status_v6->wakeup_reasons);
1681 status.wake_packet_length =
1682 le32_to_cpu(status_v6->wake_packet_length);
1683 status.wake_packet_bufsize =
1684 le32_to_cpu(status_v6->wake_packet_bufsize);
1685 status.wake_packet = status_v6->wake_packet;
1686 } else {
1687 struct iwl_wowlan_status_v4 *status_v4;
1688 status_v6 = NULL;
1689 status_v4 = (void *)cmd.resp_pkt->data;
1690
1691 status.pattern_number = le16_to_cpu(status_v4->pattern_number);
1692 for (i = 0; i < 8; i++)
1693 status.qos_seq_ctr[i] =
1694 le16_to_cpu(status_v4->qos_seq_ctr[i]);
1695 status.wakeup_reasons = le32_to_cpu(status_v4->wakeup_reasons);
1696 status.wake_packet_length =
1697 le32_to_cpu(status_v4->wake_packet_length);
1698 status.wake_packet_bufsize =
1699 le32_to_cpu(status_v4->wake_packet_bufsize);
1700 status.wake_packet = status_v4->wake_packet;
1701 }
1297 1702
1298 if (len - sizeof(struct iwl_cmd_header) != 1703 if (len - sizeof(struct iwl_cmd_header) !=
1299 sizeof(*status) + 1704 status_size + ALIGN(status.wake_packet_bufsize, 4)) {
1300 ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) {
1301 IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); 1705 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
1302 goto out_free_resp; 1706 goto out_free_resp;
1303 } 1707 }
1304 1708
1709 /* still at hard-coded place 0 for D3 image */
1710 ap_sta = rcu_dereference_protected(
1711 mvm->fw_id_to_mac_id[0],
1712 lockdep_is_held(&mvm->mutex));
1713 if (IS_ERR_OR_NULL(ap_sta))
1714 goto out_free_resp;
1715
1716 mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv;
1717 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
1718 u16 seq = status.qos_seq_ctr[i];
1719 /* firmware stores last-used value, we store next value */
1720 seq += 0x10;
1721 mvm_ap_sta->tid_data[i].seq_number = seq;
1722 }
1723
1305 /* now we have all the data we need, unlock to avoid mac80211 issues */ 1724 /* now we have all the data we need, unlock to avoid mac80211 issues */
1306 mutex_unlock(&mvm->mutex); 1725 mutex_unlock(&mvm->mutex);
1307 1726
1308 iwl_mvm_report_wakeup_reasons(mvm, vif, status); 1727 iwl_mvm_report_wakeup_reasons(mvm, vif, &status);
1728
1729 keep = iwl_mvm_setup_connection_keep(mvm, vif, status_v6);
1730
1309 iwl_free_resp(&cmd); 1731 iwl_free_resp(&cmd);
1310 return; 1732 return keep;
1311 1733
1312 out_free_resp: 1734 out_free_resp:
1313 iwl_free_resp(&cmd); 1735 iwl_free_resp(&cmd);
1314 out_unlock: 1736 out_unlock:
1315 mutex_unlock(&mvm->mutex); 1737 mutex_unlock(&mvm->mutex);
1738 return false;
1316} 1739}
1317 1740
1318static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm) 1741static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm)
@@ -1335,6 +1758,17 @@ static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm)
1335#endif 1758#endif
1336} 1759}
1337 1760
1761static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
1762 struct ieee80211_vif *vif)
1763{
1764 /* skip the one we keep connection on */
1765 if (data == vif)
1766 return;
1767
1768 if (vif->type == NL80211_IFTYPE_STATION)
1769 ieee80211_resume_disconnect(vif);
1770}
1771
1338static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) 1772static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
1339{ 1773{
1340 struct iwl_d3_iter_data resume_iter_data = { 1774 struct iwl_d3_iter_data resume_iter_data = {
@@ -1343,6 +1777,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
1343 struct ieee80211_vif *vif = NULL; 1777 struct ieee80211_vif *vif = NULL;
1344 int ret; 1778 int ret;
1345 enum iwl_d3_status d3_status; 1779 enum iwl_d3_status d3_status;
1780 bool keep = false;
1346 1781
1347 mutex_lock(&mvm->mutex); 1782 mutex_lock(&mvm->mutex);
1348 1783
@@ -1368,7 +1803,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
1368 /* query SRAM first in case we want event logging */ 1803 /* query SRAM first in case we want event logging */
1369 iwl_mvm_read_d3_sram(mvm); 1804 iwl_mvm_read_d3_sram(mvm);
1370 1805
1371 iwl_mvm_query_wakeup_reasons(mvm, vif); 1806 keep = iwl_mvm_query_wakeup_reasons(mvm, vif);
1372 /* has unlocked the mutex, so skip that */ 1807 /* has unlocked the mutex, so skip that */
1373 goto out; 1808 goto out;
1374 1809
@@ -1376,8 +1811,10 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
1376 mutex_unlock(&mvm->mutex); 1811 mutex_unlock(&mvm->mutex);
1377 1812
1378 out: 1813 out:
1379 if (!test && vif) 1814 if (!test)
1380 ieee80211_resume_disconnect(vif); 1815 ieee80211_iterate_active_interfaces_rtnl(mvm->hw,
1816 IEEE80211_IFACE_ITER_NORMAL,
1817 iwl_mvm_d3_disconnect_iter, keep ? vif : NULL);
1381 1818
1382 /* return 1 to reconfigure the device */ 1819 /* return 1 to reconfigure the device */
1383 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); 1820 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index aac81b8984b0..0675f0c8ef93 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -246,58 +246,56 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
246 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 246 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
247} 247}
248 248
249static ssize_t iwl_dbgfs_power_down_allow_write(struct file *file, 249static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file,
250 const char __user *user_buf, 250 char __user *user_buf,
251 size_t count, loff_t *ppos) 251 size_t count, loff_t *ppos)
252{ 252{
253 struct iwl_mvm *mvm = file->private_data; 253 struct iwl_mvm *mvm = file->private_data;
254 char buf[8] = {}; 254 char buf[64];
255 int allow; 255 int bufsz = sizeof(buf);
256 256 int pos = 0;
257 if (!mvm->ucode_loaded)
258 return -EIO;
259
260 if (copy_from_user(buf, user_buf, sizeof(buf)))
261 return -EFAULT;
262
263 if (sscanf(buf, "%d", &allow) != 1)
264 return -EINVAL;
265
266 IWL_DEBUG_POWER(mvm, "%s device power down\n",
267 allow ? "allow" : "prevent");
268 257
269 /* 258 pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d0=%d\n",
270 * TODO: Send REPLY_DEBUG_CMD (0xf0) when FW support it 259 mvm->disable_power_off);
271 */ 260 pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d3=%d\n",
261 mvm->disable_power_off_d3);
272 262
273 return count; 263 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
274} 264}
275 265
276static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file, 266static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file,
277 const char __user *user_buf, 267 const char __user *user_buf,
278 size_t count, loff_t *ppos) 268 size_t count, loff_t *ppos)
279{ 269{
280 struct iwl_mvm *mvm = file->private_data; 270 struct iwl_mvm *mvm = file->private_data;
281 char buf[8] = {}; 271 char buf[64] = {};
282 int allow; 272 int ret;
273 int val;
283 274
284 if (copy_from_user(buf, user_buf, sizeof(buf))) 275 if (!mvm->ucode_loaded)
276 return -EIO;
277
278 count = min_t(size_t, count, sizeof(buf) - 1);
279 if (copy_from_user(buf, user_buf, count))
285 return -EFAULT; 280 return -EFAULT;
286 281
287 if (sscanf(buf, "%d", &allow) != 1) 282 if (!strncmp("disable_power_off_d0=", buf, 21)) {
283 if (sscanf(buf + 21, "%d", &val) != 1)
284 return -EINVAL;
285 mvm->disable_power_off = val;
286 } else if (!strncmp("disable_power_off_d3=", buf, 21)) {
287 if (sscanf(buf + 21, "%d", &val) != 1)
288 return -EINVAL;
289 mvm->disable_power_off_d3 = val;
290 } else {
288 return -EINVAL; 291 return -EINVAL;
292 }
289 293
290 IWL_DEBUG_POWER(mvm, "%s device power down in d3\n", 294 mutex_lock(&mvm->mutex);
291 allow ? "allow" : "prevent"); 295 ret = iwl_mvm_power_update_device_mode(mvm);
292 296 mutex_unlock(&mvm->mutex);
293 /*
294 * TODO: When WoWLAN FW alive notification happens, driver will send
295 * REPLY_DEBUG_CMD setting power_down_allow flag according to
296 * mvm->prevent_power_down_d3
297 */
298 mvm->prevent_power_down_d3 = !allow;
299 297
300 return count; 298 return ret ?: count;
301} 299}
302 300
303static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm, 301static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
@@ -371,7 +369,8 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
371 int val; 369 int val;
372 int ret; 370 int ret;
373 371
374 if (copy_from_user(buf, user_buf, sizeof(buf))) 372 count = min_t(size_t, count, sizeof(buf) - 1);
373 if (copy_from_user(buf, user_buf, count))
375 return -EFAULT; 374 return -EFAULT;
376 375
377 if (!strncmp("keep_alive=", buf, 11)) { 376 if (!strncmp("keep_alive=", buf, 11)) {
@@ -394,7 +393,9 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
394 if (sscanf(buf + 16, "%d", &val) != 1) 393 if (sscanf(buf + 16, "%d", &val) != 1)
395 return -EINVAL; 394 return -EINVAL;
396 param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT; 395 param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
397 } else if (!strncmp("disable_power_off=", buf, 18)) { 396 } else if (!strncmp("disable_power_off=", buf, 18) &&
397 !(mvm->fw->ucode_capa.flags &
398 IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) {
398 if (sscanf(buf + 18, "%d", &val) != 1) 399 if (sscanf(buf + 18, "%d", &val) != 1)
399 return -EINVAL; 400 return -EINVAL;
400 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF; 401 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
@@ -581,15 +582,21 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
581 BT_MBOX_PRINT(3, UPDATE_REQUEST, true); 582 BT_MBOX_PRINT(3, UPDATE_REQUEST, true);
582 583
583 pos += scnprintf(buf+pos, bufsz-pos, "bt_status = %d\n", 584 pos += scnprintf(buf+pos, bufsz-pos, "bt_status = %d\n",
584 notif->bt_status); 585 notif->bt_status);
585 pos += scnprintf(buf+pos, bufsz-pos, "bt_open_conn = %d\n", 586 pos += scnprintf(buf+pos, bufsz-pos, "bt_open_conn = %d\n",
586 notif->bt_open_conn); 587 notif->bt_open_conn);
587 pos += scnprintf(buf+pos, bufsz-pos, "bt_traffic_load = %d\n", 588 pos += scnprintf(buf+pos, bufsz-pos, "bt_traffic_load = %d\n",
588 notif->bt_traffic_load); 589 notif->bt_traffic_load);
589 pos += scnprintf(buf+pos, bufsz-pos, "bt_agg_traffic_load = %d\n", 590 pos += scnprintf(buf+pos, bufsz-pos, "bt_agg_traffic_load = %d\n",
590 notif->bt_agg_traffic_load); 591 notif->bt_agg_traffic_load);
591 pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n", 592 pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n",
592 notif->bt_ci_compliance); 593 notif->bt_ci_compliance);
594 pos += scnprintf(buf+pos, bufsz-pos, "primary_ch_lut = %d\n",
595 le32_to_cpu(notif->primary_ch_lut));
596 pos += scnprintf(buf+pos, bufsz-pos, "secondary_ch_lut = %d\n",
597 le32_to_cpu(notif->secondary_ch_lut));
598 pos += scnprintf(buf+pos, bufsz-pos, "bt_activity_grading = %d\n",
599 le32_to_cpu(notif->bt_activity_grading));
593 600
594 mutex_unlock(&mvm->mutex); 601 mutex_unlock(&mvm->mutex);
595 602
@@ -600,6 +607,38 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
600} 607}
601#undef BT_MBOX_PRINT 608#undef BT_MBOX_PRINT
602 609
610static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf,
611 size_t count, loff_t *ppos)
612{
613 struct iwl_mvm *mvm = file->private_data;
614 struct iwl_bt_coex_ci_cmd *cmd = &mvm->last_bt_ci_cmd;
615 char buf[256];
616 int bufsz = sizeof(buf);
617 int pos = 0;
618
619 mutex_lock(&mvm->mutex);
620
621 pos += scnprintf(buf+pos, bufsz-pos, "Channel inhibition CMD\n");
622 pos += scnprintf(buf+pos, bufsz-pos,
623 "\tPrimary Channel Bitmap 0x%016llx Fat: %d\n",
624 le64_to_cpu(cmd->bt_primary_ci),
625 !!cmd->co_run_bw_primary);
626 pos += scnprintf(buf+pos, bufsz-pos,
627 "\tSecondary Channel Bitmap 0x%016llx Fat: %d\n",
628 le64_to_cpu(cmd->bt_secondary_ci),
629 !!cmd->co_run_bw_secondary);
630
631 pos += scnprintf(buf+pos, bufsz-pos, "BT Configuration CMD\n");
632 pos += scnprintf(buf+pos, bufsz-pos, "\tACK Kill Mask 0x%08x\n",
633 iwl_bt_ack_kill_msk[mvm->bt_kill_msk]);
634 pos += scnprintf(buf+pos, bufsz-pos, "\tCTS Kill Mask 0x%08x\n",
635 iwl_bt_cts_kill_msk[mvm->bt_kill_msk]);
636
637 mutex_unlock(&mvm->mutex);
638
639 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
640}
641
603#define PRINT_STATS_LE32(_str, _val) \ 642#define PRINT_STATS_LE32(_str, _val) \
604 pos += scnprintf(buf + pos, bufsz - pos, \ 643 pos += scnprintf(buf + pos, bufsz - pos, \
605 fmt_table, _str, \ 644 fmt_table, _str, \
@@ -615,9 +654,11 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
615 int pos = 0; 654 int pos = 0;
616 char *buf; 655 char *buf;
617 int ret; 656 int ret;
618 int bufsz = sizeof(struct mvm_statistics_rx_phy) * 20 + 657 /* 43 is the size of each data line, 33 is the size of each header */
619 sizeof(struct mvm_statistics_rx_non_phy) * 10 + 658 size_t bufsz =
620 sizeof(struct mvm_statistics_rx_ht_phy) * 10 + 200; 659 ((sizeof(struct mvm_statistics_rx) / sizeof(__le32)) * 43) +
660 (4 * 33) + 1;
661
621 struct mvm_statistics_rx_phy *ofdm; 662 struct mvm_statistics_rx_phy *ofdm;
622 struct mvm_statistics_rx_phy *cck; 663 struct mvm_statistics_rx_phy *cck;
623 struct mvm_statistics_rx_non_phy *general; 664 struct mvm_statistics_rx_non_phy *general;
@@ -712,6 +753,7 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
712 PRINT_STATS_LE32("beacon_energy_b", general->beacon_energy_b); 753 PRINT_STATS_LE32("beacon_energy_b", general->beacon_energy_b);
713 PRINT_STATS_LE32("beacon_energy_c", general->beacon_energy_c); 754 PRINT_STATS_LE32("beacon_energy_c", general->beacon_energy_c);
714 PRINT_STATS_LE32("num_bt_kills", general->num_bt_kills); 755 PRINT_STATS_LE32("num_bt_kills", general->num_bt_kills);
756 PRINT_STATS_LE32("mac_id", general->mac_id);
715 PRINT_STATS_LE32("directed_data_mpdu", general->directed_data_mpdu); 757 PRINT_STATS_LE32("directed_data_mpdu", general->directed_data_mpdu);
716 758
717 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 759 pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
@@ -757,6 +799,59 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
757 return count; 799 return count;
758} 800}
759 801
802static ssize_t
803iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
804 char __user *user_buf,
805 size_t count, loff_t *ppos)
806{
807 struct iwl_mvm *mvm = file->private_data;
808 int pos = 0;
809 char buf[32];
810 const size_t bufsz = sizeof(buf);
811
812 /* print which antennas were set for the scan command by the user */
813 pos += scnprintf(buf + pos, bufsz - pos, "Antennas for scan: ");
814 if (mvm->scan_rx_ant & ANT_A)
815 pos += scnprintf(buf + pos, bufsz - pos, "A");
816 if (mvm->scan_rx_ant & ANT_B)
817 pos += scnprintf(buf + pos, bufsz - pos, "B");
818 if (mvm->scan_rx_ant & ANT_C)
819 pos += scnprintf(buf + pos, bufsz - pos, "C");
820 pos += scnprintf(buf + pos, bufsz - pos, " (%hhx)\n", mvm->scan_rx_ant);
821
822 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
823}
824
825static ssize_t
826iwl_dbgfs_scan_ant_rxchain_write(struct file *file,
827 const char __user *user_buf,
828 size_t count, loff_t *ppos)
829{
830 struct iwl_mvm *mvm = file->private_data;
831 char buf[8];
832 int buf_size;
833 u8 scan_rx_ant;
834
835 memset(buf, 0, sizeof(buf));
836 buf_size = min(count, sizeof(buf) - 1);
837
838 /* get the argument from the user and check if it is valid */
839 if (copy_from_user(buf, user_buf, buf_size))
840 return -EFAULT;
841 if (sscanf(buf, "%hhx", &scan_rx_ant) != 1)
842 return -EINVAL;
843 if (scan_rx_ant > ANT_ABC)
844 return -EINVAL;
845 if (scan_rx_ant & ~iwl_fw_valid_rx_ant(mvm->fw))
846 return -EINVAL;
847
848 /* change the rx antennas for scan command */
849 mvm->scan_rx_ant = scan_rx_ant;
850
851 return count;
852}
853
854
760static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif, 855static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif,
761 enum iwl_dbgfs_bf_mask param, int value) 856 enum iwl_dbgfs_bf_mask param, int value)
762{ 857{
@@ -968,7 +1063,8 @@ static ssize_t iwl_dbgfs_d3_sram_write(struct file *file,
968 char buf[8] = {}; 1063 char buf[8] = {};
969 int store; 1064 int store;
970 1065
971 if (copy_from_user(buf, user_buf, sizeof(buf))) 1066 count = min_t(size_t, count, sizeof(buf) - 1);
1067 if (copy_from_user(buf, user_buf, count))
972 return -EFAULT; 1068 return -EFAULT;
973 1069
974 if (sscanf(buf, "%d", &store) != 1) 1070 if (sscanf(buf, "%d", &store) != 1)
@@ -1063,10 +1159,12 @@ MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain);
1063MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); 1159MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram);
1064MVM_DEBUGFS_READ_FILE_OPS(stations); 1160MVM_DEBUGFS_READ_FILE_OPS(stations);
1065MVM_DEBUGFS_READ_FILE_OPS(bt_notif); 1161MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
1066MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); 1162MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
1067MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); 1163MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off);
1068MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats); 1164MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
1069MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); 1165MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart);
1166MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain);
1167
1070#ifdef CONFIG_PM_SLEEP 1168#ifdef CONFIG_PM_SLEEP
1071MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram); 1169MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram);
1072#endif 1170#endif
@@ -1087,10 +1185,14 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1087 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); 1185 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
1088 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); 1186 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
1089 MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); 1187 MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
1090 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); 1188 MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR);
1091 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); 1189 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)
1190 MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir,
1191 S_IRUSR | S_IWUSR);
1092 MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR); 1192 MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR);
1093 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); 1193 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
1194 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir,
1195 S_IWUSR | S_IRUSR);
1094#ifdef CONFIG_PM_SLEEP 1196#ifdef CONFIG_PM_SLEEP
1095 MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR); 1197 MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
1096 MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, S_IRUSR); 1198 MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, S_IRUSR);
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
index 05c61d6f384e..4ea5e24ca92d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
@@ -82,6 +82,8 @@
82 * @BT_USE_DEFAULTS: 82 * @BT_USE_DEFAULTS:
83 * @BT_SYNC_2_BT_DISABLE: 83 * @BT_SYNC_2_BT_DISABLE:
84 * @BT_COEX_CORUNNING_TBL_EN: 84 * @BT_COEX_CORUNNING_TBL_EN:
85 *
86 * The COEX_MODE must be set for each command. Even if it is not changed.
85 */ 87 */
86enum iwl_bt_coex_flags { 88enum iwl_bt_coex_flags {
87 BT_CH_PRIMARY_EN = BIT(0), 89 BT_CH_PRIMARY_EN = BIT(0),
@@ -95,14 +97,16 @@ enum iwl_bt_coex_flags {
95 BT_COEX_NW = 0x3 << BT_COEX_MODE_POS, 97 BT_COEX_NW = 0x3 << BT_COEX_MODE_POS,
96 BT_USE_DEFAULTS = BIT(6), 98 BT_USE_DEFAULTS = BIT(6),
97 BT_SYNC_2_BT_DISABLE = BIT(7), 99 BT_SYNC_2_BT_DISABLE = BIT(7),
98 /* 100 BT_COEX_CORUNNING_TBL_EN = BIT(8),
99 * For future use - when the flags will be enlarged 101 BT_COEX_MPLUT_TBL_EN = BIT(9),
100 * BT_COEX_CORUNNING_TBL_EN = BIT(8), 102 /* Bit 10 is reserved */
101 */ 103 BT_COEX_WF_PRIO_BOOST_CHECK_EN = BIT(11),
102}; 104};
103 105
104/* 106/*
105 * indicates what has changed in the BT_COEX command. 107 * indicates what has changed in the BT_COEX command.
108 * BT_VALID_ENABLE must be set for each command. Commands without this bit will
109 * discarded by the firmware
106 */ 110 */
107enum iwl_bt_coex_valid_bit_msk { 111enum iwl_bt_coex_valid_bit_msk {
108 BT_VALID_ENABLE = BIT(0), 112 BT_VALID_ENABLE = BIT(0),
@@ -121,11 +125,8 @@ enum iwl_bt_coex_valid_bit_msk {
121 BT_VALID_CORUN_LUT_40 = BIT(13), 125 BT_VALID_CORUN_LUT_40 = BIT(13),
122 BT_VALID_ANT_ISOLATION = BIT(14), 126 BT_VALID_ANT_ISOLATION = BIT(14),
123 BT_VALID_ANT_ISOLATION_THRS = BIT(15), 127 BT_VALID_ANT_ISOLATION_THRS = BIT(15),
124 /* 128 BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16),
125 * For future use - when the valid flags will be enlarged 129 BT_VALID_TXRX_MAX_FREQ_0 = BIT(17),
126 * BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16),
127 * BT_VALID_TXRX_MAX_FREQ_0 = BIT(17),
128 */
129}; 130};
130 131
131/** 132/**
@@ -142,48 +143,88 @@ enum iwl_bt_reduced_tx_power {
142 BT_REDUCED_TX_POWER_DATA = BIT(1), 143 BT_REDUCED_TX_POWER_DATA = BIT(1),
143}; 144};
144 145
146enum iwl_bt_coex_lut_type {
147 BT_COEX_TIGHT_LUT = 0,
148 BT_COEX_LOOSE_LUT,
149 BT_COEX_TX_DIS_LUT,
150
151 BT_COEX_MAX_LUT,
152};
153
145#define BT_COEX_LUT_SIZE (12) 154#define BT_COEX_LUT_SIZE (12)
155#define BT_COEX_CORUN_LUT_SIZE (32)
156#define BT_COEX_MULTI_PRIO_LUT_SIZE (2)
157#define BT_COEX_BOOST_SIZE (4)
158#define BT_REDUCED_TX_POWER_BIT BIT(7)
146 159
147/** 160/**
148 * struct iwl_bt_coex_cmd - bt coex configuration command 161 * struct iwl_bt_coex_cmd - bt coex configuration command
149 * @flags:&enum iwl_bt_coex_flags 162 * @flags:&enum iwl_bt_coex_flags
150 * @lead_time:
151 * @max_kill: 163 * @max_kill:
152 * @bt3_time_t7_value:
153 * @kill_ack_msk:
154 * @kill_cts_msk:
155 * @bt3_prio_sample_time:
156 * @bt3_timer_t2_value:
157 * @bt4_reaction_time:
158 * @decision_lut[12]:
159 * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power 164 * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power
160 * @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk 165 * @bt4_antenna_isolation:
161 * @bt_prio_boost: values for PTA boost register 166 * @bt4_antenna_isolation_thr:
167 * @bt4_tx_tx_delta_freq_thr:
168 * @bt4_tx_rx_max_freq0:
169 * @bt_prio_boost:
162 * @wifi_tx_prio_boost: SW boost of wifi tx priority 170 * @wifi_tx_prio_boost: SW boost of wifi tx priority
163 * @wifi_rx_prio_boost: SW boost of wifi rx priority 171 * @wifi_rx_prio_boost: SW boost of wifi rx priority
172 * @kill_ack_msk:
173 * @kill_cts_msk:
174 * @decision_lut:
175 * @bt4_multiprio_lut:
176 * @bt4_corun_lut20:
177 * @bt4_corun_lut40:
178 * @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk
164 * 179 *
165 * The structure is used for the BT_COEX command. 180 * The structure is used for the BT_COEX command.
166 */ 181 */
167struct iwl_bt_coex_cmd { 182struct iwl_bt_coex_cmd {
168 u8 flags; 183 __le32 flags;
169 u8 lead_time;
170 u8 max_kill; 184 u8 max_kill;
171 u8 bt3_time_t7_value; 185 u8 bt_reduced_tx_power;
186 u8 reserved[2];
187
188 u8 bt4_antenna_isolation;
189 u8 bt4_antenna_isolation_thr;
190 u8 bt4_tx_tx_delta_freq_thr;
191 u8 bt4_tx_rx_max_freq0;
192
193 __le32 bt_prio_boost[BT_COEX_BOOST_SIZE];
194 __le32 wifi_tx_prio_boost;
195 __le32 wifi_rx_prio_boost;
172 __le32 kill_ack_msk; 196 __le32 kill_ack_msk;
173 __le32 kill_cts_msk; 197 __le32 kill_cts_msk;
174 u8 bt3_prio_sample_time; 198
175 u8 bt3_timer_t2_value; 199 __le32 decision_lut[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE];
176 __le16 bt4_reaction_time; 200 __le32 bt4_multiprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE];
177 __le32 decision_lut[BT_COEX_LUT_SIZE]; 201 __le32 bt4_corun_lut20[BT_COEX_CORUN_LUT_SIZE];
178 u8 bt_reduced_tx_power; 202 __le32 bt4_corun_lut40[BT_COEX_CORUN_LUT_SIZE];
179 u8 reserved; 203
180 __le16 valid_bit_msk; 204 __le32 valid_bit_msk;
181 __le32 bt_prio_boost;
182 u8 reserved2;
183 u8 wifi_tx_prio_boost;
184 __le16 wifi_rx_prio_boost;
185} __packed; /* BT_COEX_CMD_API_S_VER_3 */ 205} __packed; /* BT_COEX_CMD_API_S_VER_3 */
186 206
207/**
208 * struct iwl_bt_coex_ci_cmd - bt coex channel inhibition command
209 * @bt_primary_ci:
210 * @bt_secondary_ci:
211 * @co_run_bw_primary:
212 * @co_run_bw_secondary:
213 * @primary_ch_phy_id:
214 * @secondary_ch_phy_id:
215 *
216 * Used for BT_COEX_CI command
217 */
218struct iwl_bt_coex_ci_cmd {
219 __le64 bt_primary_ci;
220 __le64 bt_secondary_ci;
221
222 u8 co_run_bw_primary;
223 u8 co_run_bw_secondary;
224 u8 primary_ch_phy_id;
225 u8 secondary_ch_phy_id;
226} __packed; /* BT_CI_MSG_API_S_VER_1 */
227
187#define BT_MBOX(n_dw, _msg, _pos, _nbits) \ 228#define BT_MBOX(n_dw, _msg, _pos, _nbits) \
188 BT_MBOX##n_dw##_##_msg##_POS = (_pos), \ 229 BT_MBOX##n_dw##_##_msg##_POS = (_pos), \
189 BT_MBOX##n_dw##_##_msg = BITS(_nbits) << BT_MBOX##n_dw##_##_msg##_POS 230 BT_MBOX##n_dw##_##_msg = BITS(_nbits) << BT_MBOX##n_dw##_##_msg##_POS
@@ -244,23 +285,39 @@ enum iwl_bt_mxbox_dw3 {
244 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ 285 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
245 >> BT_MBOX##_num##_##_field##_POS) 286 >> BT_MBOX##_num##_##_field##_POS)
246 287
288enum iwl_bt_activity_grading {
289 BT_OFF = 0,
290 BT_ON_NO_CONNECTION = 1,
291 BT_LOW_TRAFFIC = 2,
292 BT_HIGH_TRAFFIC = 3,
293};
294
247/** 295/**
248 * struct iwl_bt_coex_profile_notif - notification about BT coex 296 * struct iwl_bt_coex_profile_notif - notification about BT coex
249 * @mbox_msg: message from BT to WiFi 297 * @mbox_msg: message from BT to WiFi
250 * @:bt_status: 0 - off, 1 - on 298 * @msg_idx: the index of the message
251 * @:bt_open_conn: number of BT connections open 299 * @bt_status: 0 - off, 1 - on
252 * @:bt_traffic_load: load of BT traffic 300 * @bt_open_conn: number of BT connections open
253 * @:bt_agg_traffic_load: aggregated load of BT traffic 301 * @bt_traffic_load: load of BT traffic
254 * @:bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant 302 * @bt_agg_traffic_load: aggregated load of BT traffic
303 * @bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant
304 * @primary_ch_lut: LUT used for primary channel
305 * @secondary_ch_lut: LUT used for secondary channel
306 * @bt_activity_grading: the activity of BT enum %iwl_bt_activity_grading
255 */ 307 */
256struct iwl_bt_coex_profile_notif { 308struct iwl_bt_coex_profile_notif {
257 __le32 mbox_msg[4]; 309 __le32 mbox_msg[4];
310 __le32 msg_idx;
258 u8 bt_status; 311 u8 bt_status;
259 u8 bt_open_conn; 312 u8 bt_open_conn;
260 u8 bt_traffic_load; 313 u8 bt_traffic_load;
261 u8 bt_agg_traffic_load; 314 u8 bt_agg_traffic_load;
262 u8 bt_ci_compliance; 315 u8 bt_ci_compliance;
263 u8 reserved[3]; 316 u8 reserved[3];
317
318 __le32 primary_ch_lut;
319 __le32 secondary_ch_lut;
320 __le32 bt_activity_grading;
264} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_2 */ 321} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_2 */
265 322
266enum iwl_bt_coex_prio_table_event { 323enum iwl_bt_coex_prio_table_event {
@@ -300,20 +357,4 @@ struct iwl_bt_coex_prio_tbl_cmd {
300 u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; 357 u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX];
301} __packed; 358} __packed;
302 359
303enum iwl_bt_coex_env_action {
304 BT_COEX_ENV_CLOSE = 0,
305 BT_COEX_ENV_OPEN = 1,
306}; /* BT_COEX_PROT_ENV_ACTION_API_E_VER_1 */
307
308/**
309 * struct iwl_bt_coex_prot_env_cmd - BT Protection Envelope
310 * @action: enum %iwl_bt_coex_env_action
311 * @type: enum %iwl_bt_coex_prio_table_event
312 */
313struct iwl_bt_coex_prot_env_cmd {
314 u8 action; /* 0 = closed, 1 = open */
315 u8 type; /* 0 .. 15 */
316 u8 reserved[2];
317} __packed;
318
319#endif /* __fw_api_bt_coex_h__ */ 360#endif /* __fw_api_bt_coex_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
index df72fcdf8170..4e7dd8cf87dc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -100,7 +100,12 @@ enum iwl_proto_offloads {
100 100
101#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1 2 101#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1 2
102#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2 6 102#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2 6
103#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX 6 103#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L 12
104#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S 4
105#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX 12
106
107#define IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L 4
108#define IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3S 2
104 109
105/** 110/**
106 * struct iwl_proto_offload_cmd_common - ARP/NS offload common part 111 * struct iwl_proto_offload_cmd_common - ARP/NS offload common part
@@ -155,6 +160,43 @@ struct iwl_proto_offload_cmd_v2 {
155 u8 reserved2[3]; 160 u8 reserved2[3];
156} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_2 */ 161} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_2 */
157 162
163struct iwl_ns_config {
164 struct in6_addr source_ipv6_addr;
165 struct in6_addr dest_ipv6_addr;
166 u8 target_mac_addr[ETH_ALEN];
167 __le16 reserved;
168} __packed; /* NS_OFFLOAD_CONFIG */
169
170struct iwl_targ_addr {
171 struct in6_addr addr;
172 __le32 config_num;
173} __packed; /* TARGET_IPV6_ADDRESS */
174
175/**
176 * struct iwl_proto_offload_cmd_v3_small - ARP/NS offload configuration
177 * @common: common/IPv4 configuration
178 * @target_ipv6_addr: target IPv6 addresses
179 * @ns_config: NS offload configurations
180 */
181struct iwl_proto_offload_cmd_v3_small {
182 struct iwl_proto_offload_cmd_common common;
183 __le32 num_valid_ipv6_addrs;
184 struct iwl_targ_addr targ_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S];
185 struct iwl_ns_config ns_config[IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3S];
186} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_3 */
187
188/**
189 * struct iwl_proto_offload_cmd_v3_large - ARP/NS offload configuration
190 * @common: common/IPv4 configuration
191 * @target_ipv6_addr: target IPv6 addresses
192 * @ns_config: NS offload configurations
193 */
194struct iwl_proto_offload_cmd_v3_large {
195 struct iwl_proto_offload_cmd_common common;
196 __le32 num_valid_ipv6_addrs;
197 struct iwl_targ_addr targ_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L];
198 struct iwl_ns_config ns_config[IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L];
199} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_3 */
158 200
159/* 201/*
160 * WOWLAN_PATTERNS 202 * WOWLAN_PATTERNS
@@ -293,7 +335,7 @@ enum iwl_wowlan_wakeup_reason {
293 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12), 335 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12),
294}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */ 336}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */
295 337
296struct iwl_wowlan_status { 338struct iwl_wowlan_status_v4 {
297 __le64 replay_ctr; 339 __le64 replay_ctr;
298 __le16 pattern_number; 340 __le16 pattern_number;
299 __le16 non_qos_seq_ctr; 341 __le16 non_qos_seq_ctr;
@@ -308,6 +350,29 @@ struct iwl_wowlan_status {
308 u8 wake_packet[]; /* can be truncated from _length to _bufsize */ 350 u8 wake_packet[]; /* can be truncated from _length to _bufsize */
309} __packed; /* WOWLAN_STATUSES_API_S_VER_4 */ 351} __packed; /* WOWLAN_STATUSES_API_S_VER_4 */
310 352
353struct iwl_wowlan_gtk_status {
354 u8 key_index;
355 u8 reserved[3];
356 u8 decrypt_key[16];
357 u8 tkip_mic_key[8];
358 struct iwl_wowlan_rsc_tsc_params_cmd rsc;
359} __packed;
360
361struct iwl_wowlan_status_v6 {
362 struct iwl_wowlan_gtk_status gtk;
363 __le64 replay_ctr;
364 __le16 pattern_number;
365 __le16 non_qos_seq_ctr;
366 __le16 qos_seq_ctr[8];
367 __le32 wakeup_reasons;
368 __le32 num_of_gtk_rekeys;
369 __le32 transmitted_ndps;
370 __le32 received_beacons;
371 __le32 wake_packet_length;
372 __le32 wake_packet_bufsize;
373 u8 wake_packet[]; /* can be truncated from _length to _bufsize */
374} __packed; /* WOWLAN_STATUSES_API_S_VER_6 */
375
311#define IWL_WOWLAN_TCP_MAX_PACKET_LEN 64 376#define IWL_WOWLAN_TCP_MAX_PACKET_LEN 64
312#define IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN 128 377#define IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN 128
313#define IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS 2048 378#define IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS 2048
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
index 98b1feb43d38..39c3148bdfa8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
@@ -170,12 +170,14 @@ struct iwl_mac_data_ap {
170 * @beacon_tsf: beacon transmit time in TSF 170 * @beacon_tsf: beacon transmit time in TSF
171 * @bi: beacon interval in TU 171 * @bi: beacon interval in TU
172 * @bi_reciprocal: 2^32 / bi 172 * @bi_reciprocal: 2^32 / bi
173 * @beacon_template: beacon template ID
173 */ 174 */
174struct iwl_mac_data_ibss { 175struct iwl_mac_data_ibss {
175 __le32 beacon_time; 176 __le32 beacon_time;
176 __le64 beacon_tsf; 177 __le64 beacon_tsf;
177 __le32 bi; 178 __le32 bi;
178 __le32 bi_reciprocal; 179 __le32 bi_reciprocal;
180 __le32 beacon_template;
179} __packed; /* IBSS_MAC_DATA_API_S_VER_1 */ 181} __packed; /* IBSS_MAC_DATA_API_S_VER_1 */
180 182
181/** 183/**
@@ -372,4 +374,13 @@ static inline u32 iwl_mvm_reciprocal(u32 v)
372 return 0xFFFFFFFF / v; 374 return 0xFFFFFFFF / v;
373} 375}
374 376
377#define IWL_NONQOS_SEQ_GET 0x1
378#define IWL_NONQOS_SEQ_SET 0x2
379struct iwl_nonqos_seq_query_cmd {
380 __le32 get_set_flag;
381 __le32 mac_id_n_color;
382 __le16 value;
383 __le16 reserved;
384} __packed; /* NON_QOS_TX_COUNTER_GET_SET_API_S_VER_1 */
385
375#endif /* __fw_api_mac_h__ */ 386#endif /* __fw_api_mac_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index 8e7ab41079ca..5cb93ae5cd2f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -132,6 +132,33 @@ struct iwl_powertable_cmd {
132} __packed; 132} __packed;
133 133
134/** 134/**
135 * enum iwl_device_power_flags - masks for device power command flags
136 * @DEVIC_POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off
137 * receiver and transmitter. '0' - does not allow. This flag should be
138 * always set to '1' unless one need to disable actual power down for debug
139 * purposes.
140 * @DEVICE_POWER_FLAGS_CAM_MSK: '1' CAM (Continuous Active Mode) is set, meaning
141 * that power management is disabled. '0' Power management is enabled, one
142 * of power schemes is applied.
143*/
144enum iwl_device_power_flags {
145 DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0),
146 DEVICE_POWER_FLAGS_CAM_MSK = BIT(13),
147};
148
149/**
150 * struct iwl_device_power_cmd - device wide power command.
151 * DEVICE_POWER_CMD = 0x77 (command, has simple generic response)
152 *
153 * @flags: Power table command flags from DEVICE_POWER_FLAGS_*
154 */
155struct iwl_device_power_cmd {
156 /* PM_POWER_TABLE_CMD_API_S_VER_6 */
157 __le16 flags;
158 __le16 reserved;
159} __packed;
160
161/**
135 * struct iwl_mac_power_cmd - New power command containing uAPSD support 162 * struct iwl_mac_power_cmd - New power command containing uAPSD support
136 * MAC_PM_POWER_TABLE = 0xA9 (command, has simple generic response) 163 * MAC_PM_POWER_TABLE = 0xA9 (command, has simple generic response)
137 * @id_and_color: MAC contex identifier 164 * @id_and_color: MAC contex identifier
@@ -290,7 +317,7 @@ struct iwl_beacon_filter_cmd {
290#define IWL_BF_ESCAPE_TIMER_MIN 0 317#define IWL_BF_ESCAPE_TIMER_MIN 0
291 318
292#define IWL_BA_ESCAPE_TIMER_DEFAULT 6 319#define IWL_BA_ESCAPE_TIMER_DEFAULT 6
293#define IWL_BA_ESCAPE_TIMER_D3 6 320#define IWL_BA_ESCAPE_TIMER_D3 9
294#define IWL_BA_ESCAPE_TIMER_MAX 1024 321#define IWL_BA_ESCAPE_TIMER_MAX 1024
295#define IWL_BA_ESCAPE_TIMER_MIN 0 322#define IWL_BA_ESCAPE_TIMER_MIN 0
296 323
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
index fdd33bc0a594..538f1c7a5966 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
@@ -68,6 +68,7 @@
68/* 68/*
69 * These serve as indexes into 69 * These serve as indexes into
70 * struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT]; 70 * struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT];
71 * TODO: avoid overlap between legacy and HT rates
71 */ 72 */
72enum { 73enum {
73 IWL_RATE_1M_INDEX = 0, 74 IWL_RATE_1M_INDEX = 0,
@@ -78,18 +79,31 @@ enum {
78 IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX, 79 IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
79 IWL_RATE_6M_INDEX, 80 IWL_RATE_6M_INDEX,
80 IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, 81 IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
82 IWL_RATE_MCS_0_INDEX = IWL_RATE_6M_INDEX,
83 IWL_FIRST_HT_RATE = IWL_RATE_MCS_0_INDEX,
84 IWL_FIRST_VHT_RATE = IWL_RATE_MCS_0_INDEX,
81 IWL_RATE_9M_INDEX, 85 IWL_RATE_9M_INDEX,
82 IWL_RATE_12M_INDEX, 86 IWL_RATE_12M_INDEX,
87 IWL_RATE_MCS_1_INDEX = IWL_RATE_12M_INDEX,
83 IWL_RATE_18M_INDEX, 88 IWL_RATE_18M_INDEX,
89 IWL_RATE_MCS_2_INDEX = IWL_RATE_18M_INDEX,
84 IWL_RATE_24M_INDEX, 90 IWL_RATE_24M_INDEX,
91 IWL_RATE_MCS_3_INDEX = IWL_RATE_24M_INDEX,
85 IWL_RATE_36M_INDEX, 92 IWL_RATE_36M_INDEX,
93 IWL_RATE_MCS_4_INDEX = IWL_RATE_36M_INDEX,
86 IWL_RATE_48M_INDEX, 94 IWL_RATE_48M_INDEX,
95 IWL_RATE_MCS_5_INDEX = IWL_RATE_48M_INDEX,
87 IWL_RATE_54M_INDEX, 96 IWL_RATE_54M_INDEX,
97 IWL_RATE_MCS_6_INDEX = IWL_RATE_54M_INDEX,
88 IWL_LAST_NON_HT_RATE = IWL_RATE_54M_INDEX, 98 IWL_LAST_NON_HT_RATE = IWL_RATE_54M_INDEX,
89 IWL_RATE_60M_INDEX, 99 IWL_RATE_60M_INDEX,
90 IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX, 100 IWL_RATE_MCS_7_INDEX = IWL_RATE_60M_INDEX,
101 IWL_LAST_HT_RATE = IWL_RATE_MCS_7_INDEX,
102 IWL_RATE_MCS_8_INDEX,
103 IWL_RATE_MCS_9_INDEX,
104 IWL_LAST_VHT_RATE = IWL_RATE_MCS_9_INDEX,
91 IWL_RATE_COUNT_LEGACY = IWL_LAST_NON_HT_RATE + 1, 105 IWL_RATE_COUNT_LEGACY = IWL_LAST_NON_HT_RATE + 1,
92 IWL_RATE_COUNT, 106 IWL_RATE_COUNT = IWL_LAST_VHT_RATE + 1,
93}; 107};
94 108
95#define IWL_RATE_BIT_MSK(r) BIT(IWL_RATE_##r##M_INDEX) 109#define IWL_RATE_BIT_MSK(r) BIT(IWL_RATE_##r##M_INDEX)
@@ -108,6 +122,7 @@ enum {
108 IWL_RATE_2M_PLCP = 20, 122 IWL_RATE_2M_PLCP = 20,
109 IWL_RATE_5M_PLCP = 55, 123 IWL_RATE_5M_PLCP = 55,
110 IWL_RATE_11M_PLCP = 110, 124 IWL_RATE_11M_PLCP = 110,
125 IWL_RATE_INVM_PLCP = -1,
111}; 126};
112 127
113/* 128/*
@@ -164,6 +179,8 @@ enum {
164 * which is the duplicate 20 MHz MCS (bit 5 set, all others zero.) 179 * which is the duplicate 20 MHz MCS (bit 5 set, all others zero.)
165 */ 180 */
166#define RATE_HT_MCS_RATE_CODE_MSK 0x7 181#define RATE_HT_MCS_RATE_CODE_MSK 0x7
182#define RATE_HT_MCS_NSS_POS 3
183#define RATE_HT_MCS_NSS_MSK (3 << RATE_HT_MCS_NSS_POS)
167 184
168/* Bit 10: (1) Use Green Field preamble */ 185/* Bit 10: (1) Use Green Field preamble */
169#define RATE_HT_MCS_GF_POS 10 186#define RATE_HT_MCS_GF_POS 10
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index 83cb9b992ea4..c3782b48ded1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -356,6 +356,7 @@ struct iwl_scan_complete_notif {
356/* scan offload */ 356/* scan offload */
357#define IWL_MAX_SCAN_CHANNELS 40 357#define IWL_MAX_SCAN_CHANNELS 40
358#define IWL_SCAN_MAX_BLACKLIST_LEN 64 358#define IWL_SCAN_MAX_BLACKLIST_LEN 64
359#define IWL_SCAN_SHORT_BLACKLIST_LEN 16
359#define IWL_SCAN_MAX_PROFILES 11 360#define IWL_SCAN_MAX_PROFILES 11
360#define SCAN_OFFLOAD_PROBE_REQ_SIZE 512 361#define SCAN_OFFLOAD_PROBE_REQ_SIZE 512
361 362
@@ -368,6 +369,12 @@ struct iwl_scan_complete_notif {
368#define IWL_FULL_SCAN_MULTIPLIER 5 369#define IWL_FULL_SCAN_MULTIPLIER 5
369#define IWL_FAST_SCHED_SCAN_ITERATIONS 3 370#define IWL_FAST_SCHED_SCAN_ITERATIONS 3
370 371
372enum scan_framework_client {
373 SCAN_CLIENT_SCHED_SCAN = BIT(0),
374 SCAN_CLIENT_NETDETECT = BIT(1),
375 SCAN_CLIENT_ASSET_TRACKING = BIT(2),
376};
377
371/** 378/**
372 * struct iwl_scan_offload_cmd - SCAN_REQUEST_FIXED_PART_API_S_VER_6 379 * struct iwl_scan_offload_cmd - SCAN_REQUEST_FIXED_PART_API_S_VER_6
373 * @scan_flags: see enum iwl_scan_flags 380 * @scan_flags: see enum iwl_scan_flags
@@ -449,11 +456,12 @@ struct iwl_scan_offload_cfg {
449 * iwl_scan_offload_blacklist - SCAN_OFFLOAD_BLACKLIST_S 456 * iwl_scan_offload_blacklist - SCAN_OFFLOAD_BLACKLIST_S
450 * @ssid: MAC address to filter out 457 * @ssid: MAC address to filter out
451 * @reported_rssi: AP rssi reported to the host 458 * @reported_rssi: AP rssi reported to the host
459 * @client_bitmap: clients ignore this entry - enum scan_framework_client
452 */ 460 */
453struct iwl_scan_offload_blacklist { 461struct iwl_scan_offload_blacklist {
454 u8 ssid[ETH_ALEN]; 462 u8 ssid[ETH_ALEN];
455 u8 reported_rssi; 463 u8 reported_rssi;
456 u8 reserved; 464 u8 client_bitmap;
457} __packed; 465} __packed;
458 466
459enum iwl_scan_offload_network_type { 467enum iwl_scan_offload_network_type {
@@ -475,6 +483,7 @@ enum iwl_scan_offload_band_selection {
475 * @aut_alg: authentication olgorithm to match - bitmap 483 * @aut_alg: authentication olgorithm to match - bitmap
476 * @network_type: enum iwl_scan_offload_network_type 484 * @network_type: enum iwl_scan_offload_network_type
477 * @band_selection: enum iwl_scan_offload_band_selection 485 * @band_selection: enum iwl_scan_offload_band_selection
486 * @client_bitmap: clients waiting for match - enum scan_framework_client
478 */ 487 */
479struct iwl_scan_offload_profile { 488struct iwl_scan_offload_profile {
480 u8 ssid_index; 489 u8 ssid_index;
@@ -482,7 +491,8 @@ struct iwl_scan_offload_profile {
482 u8 auth_alg; 491 u8 auth_alg;
483 u8 network_type; 492 u8 network_type;
484 u8 band_selection; 493 u8 band_selection;
485 u8 reserved[3]; 494 u8 client_bitmap;
495 u8 reserved[2];
486} __packed; 496} __packed;
487 497
488/** 498/**
@@ -491,13 +501,18 @@ struct iwl_scan_offload_profile {
491 * @profiles: profiles to search for match 501 * @profiles: profiles to search for match
492 * @blacklist_len: length of blacklist 502 * @blacklist_len: length of blacklist
493 * @num_profiles: num of profiles in the list 503 * @num_profiles: num of profiles in the list
504 * @match_notify: clients waiting for match found notification
505 * @pass_match: clients waiting for the results
506 * @active_clients: active clients bitmap - enum scan_framework_client
494 */ 507 */
495struct iwl_scan_offload_profile_cfg { 508struct iwl_scan_offload_profile_cfg {
496 struct iwl_scan_offload_blacklist blacklist[IWL_SCAN_MAX_BLACKLIST_LEN];
497 struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES]; 509 struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES];
498 u8 blacklist_len; 510 u8 blacklist_len;
499 u8 num_profiles; 511 u8 num_profiles;
500 u8 reserved[2]; 512 u8 match_notify;
513 u8 pass_match;
514 u8 active_clients;
515 u8 reserved[3];
501} __packed; 516} __packed;
502 517
503/** 518/**
@@ -560,4 +575,15 @@ struct iwl_scan_offload_complete {
560 u8 reserved; 575 u8 reserved;
561} __packed; 576} __packed;
562 577
578/**
579 * iwl_sched_scan_results - SCAN_OFFLOAD_MATCH_FOUND_NTF_API_S_VER_1
580 * @ssid_bitmap: SSIDs indexes found in this iteration
581 * @client_bitmap: clients that are active and wait for this notification
582 */
583struct iwl_sched_scan_results {
584 __le16 ssid_bitmap;
585 u8 client_bitmap;
586 u8 reserved;
587};
588
563#endif 589#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
index a30691a8a85b..4aca5933a65d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
@@ -247,7 +247,7 @@ struct iwl_mvm_keyinfo {
247} __packed; 247} __packed;
248 248
249/** 249/**
250 * struct iwl_mvm_add_sta_cmd - Add / modify a station in the fw's station table 250 * struct iwl_mvm_add_sta_cmd_v5 - Add/modify a station in the fw's sta table.
251 * ( REPLY_ADD_STA = 0x18 ) 251 * ( REPLY_ADD_STA = 0x18 )
252 * @add_modify: 1: modify existing, 0: add new station 252 * @add_modify: 1: modify existing, 0: add new station
253 * @unicast_tx_key_id: unicast tx key id. Relevant only when unicast key sent 253 * @unicast_tx_key_id: unicast tx key id. Relevant only when unicast key sent
@@ -286,7 +286,7 @@ struct iwl_mvm_keyinfo {
286 * ADD_STA sets up the table entry for one station, either creating a new 286 * ADD_STA sets up the table entry for one station, either creating a new
287 * entry, or modifying a pre-existing one. 287 * entry, or modifying a pre-existing one.
288 */ 288 */
289struct iwl_mvm_add_sta_cmd { 289struct iwl_mvm_add_sta_cmd_v5 {
290 u8 add_modify; 290 u8 add_modify;
291 u8 unicast_tx_key_id; 291 u8 unicast_tx_key_id;
292 u8 multicast_tx_key_id; 292 u8 multicast_tx_key_id;
@@ -313,6 +313,57 @@ struct iwl_mvm_add_sta_cmd {
313} __packed; /* ADD_STA_CMD_API_S_VER_5 */ 313} __packed; /* ADD_STA_CMD_API_S_VER_5 */
314 314
315/** 315/**
316 * struct iwl_mvm_add_sta_cmd_v6 - Add / modify a station
317 * VER_6 of this command is quite similar to VER_5 except
318 * exclusion of all fields related to the security key installation.
319 */
320struct iwl_mvm_add_sta_cmd_v6 {
321 u8 add_modify;
322 u8 reserved1;
323 __le16 tid_disable_tx;
324 __le32 mac_id_n_color;
325 u8 addr[ETH_ALEN]; /* _STA_ID_MODIFY_INFO_API_S_VER_1 */
326 __le16 reserved2;
327 u8 sta_id;
328 u8 modify_mask;
329 __le16 reserved3;
330 __le32 station_flags;
331 __le32 station_flags_msk;
332 u8 add_immediate_ba_tid;
333 u8 remove_immediate_ba_tid;
334 __le16 add_immediate_ba_ssn;
335 __le16 sleep_tx_count;
336 __le16 sleep_state_flags;
337 __le16 assoc_id;
338 __le16 beamform_flags;
339 __le32 tfd_queue_msk;
340} __packed; /* ADD_STA_CMD_API_S_VER_6 */
341
342/**
343 * struct iwl_mvm_add_sta_key_cmd - add/modify sta key
344 * ( REPLY_ADD_STA_KEY = 0x17 )
345 * @sta_id: index of station in uCode's station table
346 * @key_offset: key offset in key storage
347 * @key_flags: type %iwl_sta_key_flag
348 * @key: key material data
349 * @key2: key material data
350 * @rx_secur_seq_cnt: RX security sequence counter for the key
351 * @tkip_rx_tsc_byte2: TSC[2] for key mix ph1 detection
352 * @tkip_rx_ttak: 10-byte unicast TKIP TTAK for Rx
353 */
354struct iwl_mvm_add_sta_key_cmd {
355 u8 sta_id;
356 u8 key_offset;
357 __le16 key_flags;
358 u8 key[16];
359 u8 key2[16];
360 u8 rx_secur_seq_cnt[16];
361 u8 tkip_rx_tsc_byte2;
362 u8 reserved;
363 __le16 tkip_rx_ttak[5];
364} __packed; /* ADD_MODIFY_STA_KEY_API_S_VER_1 */
365
366/**
316 * enum iwl_mvm_add_sta_rsp_status - status in the response to ADD_STA command 367 * enum iwl_mvm_add_sta_rsp_status - status in the response to ADD_STA command
317 * @ADD_STA_SUCCESS: operation was executed successfully 368 * @ADD_STA_SUCCESS: operation was executed successfully
318 * @ADD_STA_STATIONS_OVERLOAD: no room left in the fw's station table 369 * @ADD_STA_STATIONS_OVERLOAD: no room left in the fw's station table
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 66264cc5a016..bad5a552dd8d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -72,17 +72,17 @@
72#include "fw-api-d3.h" 72#include "fw-api-d3.h"
73#include "fw-api-bt-coex.h" 73#include "fw-api-bt-coex.h"
74 74
75/* queue and FIFO numbers by usage */ 75/* maximal number of Tx queues in any platform */
76#define IWL_MVM_MAX_QUEUES 20
77
78/* Tx queue numbers */
76enum { 79enum {
77 IWL_MVM_OFFCHANNEL_QUEUE = 8, 80 IWL_MVM_OFFCHANNEL_QUEUE = 8,
78 IWL_MVM_CMD_QUEUE = 9, 81 IWL_MVM_CMD_QUEUE = 9,
79 IWL_MVM_AUX_QUEUE = 15,
80 IWL_MVM_FIRST_AGG_QUEUE = 16,
81 IWL_MVM_NUM_QUEUES = 20,
82 IWL_MVM_LAST_AGG_QUEUE = IWL_MVM_NUM_QUEUES - 1,
83 IWL_MVM_CMD_FIFO = 7
84}; 82};
85 83
84#define IWL_MVM_CMD_FIFO 7
85
86#define IWL_MVM_STATION_COUNT 16 86#define IWL_MVM_STATION_COUNT 16
87 87
88/* commands */ 88/* commands */
@@ -97,6 +97,7 @@ enum {
97 DBG_CFG = 0x9, 97 DBG_CFG = 0x9,
98 98
99 /* station table */ 99 /* station table */
100 ADD_STA_KEY = 0x17,
100 ADD_STA = 0x18, 101 ADD_STA = 0x18,
101 REMOVE_STA = 0x19, 102 REMOVE_STA = 0x19,
102 103
@@ -114,6 +115,7 @@ enum {
114 TIME_EVENT_NOTIFICATION = 0x2a, 115 TIME_EVENT_NOTIFICATION = 0x2a,
115 BINDING_CONTEXT_CMD = 0x2b, 116 BINDING_CONTEXT_CMD = 0x2b,
116 TIME_QUOTA_CMD = 0x2c, 117 TIME_QUOTA_CMD = 0x2c,
118 NON_QOS_TX_COUNTER_CMD = 0x2d,
117 119
118 LQ_CMD = 0x4e, 120 LQ_CMD = 0x4e,
119 121
@@ -130,6 +132,7 @@ enum {
130 SCAN_OFFLOAD_COMPLETE = 0x6D, 132 SCAN_OFFLOAD_COMPLETE = 0x6D,
131 SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E, 133 SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E,
132 SCAN_OFFLOAD_CONFIG_CMD = 0x6f, 134 SCAN_OFFLOAD_CONFIG_CMD = 0x6f,
135 MATCH_FOUND_NOTIFICATION = 0xd9,
133 136
134 /* Phy */ 137 /* Phy */
135 PHY_CONFIGURATION_CMD = 0x6a, 138 PHY_CONFIGURATION_CMD = 0x6a,
@@ -178,6 +181,7 @@ enum {
178 BT_COEX_PRIO_TABLE = 0xcc, 181 BT_COEX_PRIO_TABLE = 0xcc,
179 BT_COEX_PROT_ENV = 0xcd, 182 BT_COEX_PROT_ENV = 0xcd,
180 BT_PROFILE_NOTIFICATION = 0xce, 183 BT_PROFILE_NOTIFICATION = 0xce,
184 BT_COEX_CI = 0x5d,
181 185
182 REPLY_BEACON_FILTERING_CMD = 0xd2, 186 REPLY_BEACON_FILTERING_CMD = 0xd2,
183 187
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index c76299a3a1e0..83fc5ca04433 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -199,7 +199,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
199 */ 199 */
200 200
201 for (i = 0; i < IWL_MAX_HW_QUEUES; i++) { 201 for (i = 0; i < IWL_MAX_HW_QUEUES; i++) {
202 if (i < IWL_MVM_FIRST_AGG_QUEUE && i != IWL_MVM_CMD_QUEUE) 202 if (i < mvm->first_agg_queue && i != IWL_MVM_CMD_QUEUE)
203 mvm->queue_to_mac80211[i] = i; 203 mvm->queue_to_mac80211[i] = i;
204 else 204 else
205 mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE; 205 mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE;
@@ -243,7 +243,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
243 243
244 lockdep_assert_held(&mvm->mutex); 244 lockdep_assert_held(&mvm->mutex);
245 245
246 if (mvm->init_ucode_run) 246 if (mvm->init_ucode_complete)
247 return 0; 247 return 0;
248 248
249 iwl_init_notification_wait(&mvm->notif_wait, 249 iwl_init_notification_wait(&mvm->notif_wait,
@@ -264,6 +264,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
264 if (ret) 264 if (ret)
265 goto error; 265 goto error;
266 266
267 /* Read the NVM only at driver load time, no need to do this twice */
267 if (read_nvm) { 268 if (read_nvm) {
268 /* Read nvm */ 269 /* Read nvm */
269 ret = iwl_nvm_init(mvm); 270 ret = iwl_nvm_init(mvm);
@@ -273,6 +274,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
273 } 274 }
274 } 275 }
275 276
277 /* In case we read the NVM from external file, load it to the NIC */
278 if (iwlwifi_mod_params.nvm_file)
279 iwl_mvm_load_nvm_to_nic(mvm);
280
276 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); 281 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
277 WARN_ON(ret); 282 WARN_ON(ret);
278 283
@@ -310,7 +315,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
310 ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait, 315 ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait,
311 MVM_UCODE_CALIB_TIMEOUT); 316 MVM_UCODE_CALIB_TIMEOUT);
312 if (!ret) 317 if (!ret)
313 mvm->init_ucode_run = true; 318 mvm->init_ucode_complete = true;
314 goto out; 319 goto out;
315 320
316error: 321error:
@@ -353,8 +358,12 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
353 if (ret) 358 if (ret)
354 return ret; 359 return ret;
355 360
356 /* If we were in RFKILL during module loading, load init ucode now */ 361 /*
357 if (!mvm->init_ucode_run) { 362 * If we haven't completed the run of the init ucode during
363 * module loading, load init ucode now
364 * (for example, if we were in RFKILL)
365 */
366 if (!mvm->init_ucode_complete) {
358 ret = iwl_run_init_mvm_ucode(mvm, false); 367 ret = iwl_run_init_mvm_ucode(mvm, false);
359 if (ret && !iwlmvm_mod_params.init_dbg) { 368 if (ret && !iwlmvm_mod_params.init_dbg) {
360 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret); 369 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
@@ -424,6 +433,10 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
424 goto error; 433 goto error;
425 } 434 }
426 435
436 ret = iwl_mvm_power_update_device_mode(mvm);
437 if (ret)
438 goto error;
439
427 IWL_DEBUG_INFO(mvm, "RT uCode started.\n"); 440 IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
428 return 0; 441 return 0;
429 error: 442 error:
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 5fe23a5ea9b6..ab5a7ac90dcd 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -80,7 +80,7 @@ struct iwl_mvm_mac_iface_iterator_data {
80 struct ieee80211_vif *vif; 80 struct ieee80211_vif *vif;
81 unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)]; 81 unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)];
82 unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)]; 82 unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)];
83 unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_FIRST_AGG_QUEUE)]; 83 unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_MAX_QUEUES)];
84 enum iwl_tsf_id preferred_tsf; 84 enum iwl_tsf_id preferred_tsf;
85 bool found_vif; 85 bool found_vif;
86}; 86};
@@ -218,7 +218,7 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
218 .preferred_tsf = NUM_TSF_IDS, 218 .preferred_tsf = NUM_TSF_IDS,
219 .used_hw_queues = { 219 .used_hw_queues = {
220 BIT(IWL_MVM_OFFCHANNEL_QUEUE) | 220 BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
221 BIT(IWL_MVM_AUX_QUEUE) | 221 BIT(mvm->aux_queue) |
222 BIT(IWL_MVM_CMD_QUEUE) 222 BIT(IWL_MVM_CMD_QUEUE)
223 }, 223 },
224 .found_vif = false, 224 .found_vif = false,
@@ -242,9 +242,17 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
242 * that we should share it with another interface. 242 * that we should share it with another interface.
243 */ 243 */
244 244
245 /* Currently, MAC ID 0 should be used only for the managed vif */ 245 /* Currently, MAC ID 0 should be used only for the managed/IBSS vif */
246 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 246 switch (vif->type) {
247 case NL80211_IFTYPE_ADHOC:
248 break;
249 case NL80211_IFTYPE_STATION:
250 if (!vif->p2p)
251 break;
252 /* fall through */
253 default:
247 __clear_bit(0, data.available_mac_ids); 254 __clear_bit(0, data.available_mac_ids);
255 }
248 256
249 ieee80211_iterate_active_interfaces_atomic( 257 ieee80211_iterate_active_interfaces_atomic(
250 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL, 258 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
@@ -302,9 +310,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
302 /* Find available queues, and allocate them to the ACs */ 310 /* Find available queues, and allocate them to the ACs */
303 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 311 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
304 u8 queue = find_first_zero_bit(data.used_hw_queues, 312 u8 queue = find_first_zero_bit(data.used_hw_queues,
305 IWL_MVM_FIRST_AGG_QUEUE); 313 mvm->first_agg_queue);
306 314
307 if (queue >= IWL_MVM_FIRST_AGG_QUEUE) { 315 if (queue >= mvm->first_agg_queue) {
308 IWL_ERR(mvm, "Failed to allocate queue\n"); 316 IWL_ERR(mvm, "Failed to allocate queue\n");
309 ret = -EIO; 317 ret = -EIO;
310 goto exit_fail; 318 goto exit_fail;
@@ -317,9 +325,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
317 /* Allocate the CAB queue for softAP and GO interfaces */ 325 /* Allocate the CAB queue for softAP and GO interfaces */
318 if (vif->type == NL80211_IFTYPE_AP) { 326 if (vif->type == NL80211_IFTYPE_AP) {
319 u8 queue = find_first_zero_bit(data.used_hw_queues, 327 u8 queue = find_first_zero_bit(data.used_hw_queues,
320 IWL_MVM_FIRST_AGG_QUEUE); 328 mvm->first_agg_queue);
321 329
322 if (queue >= IWL_MVM_FIRST_AGG_QUEUE) { 330 if (queue >= mvm->first_agg_queue) {
323 IWL_ERR(mvm, "Failed to allocate cab queue\n"); 331 IWL_ERR(mvm, "Failed to allocate cab queue\n");
324 ret = -EIO; 332 ret = -EIO;
325 goto exit_fail; 333 goto exit_fail;
@@ -559,8 +567,12 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
559 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); 567 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);
560 568
561 /* Don't use cts to self as the fw doesn't support it currently. */ 569 /* Don't use cts to self as the fw doesn't support it currently. */
562 if (vif->bss_conf.use_cts_prot) 570 if (vif->bss_conf.use_cts_prot) {
563 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); 571 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
572 if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8)
573 cmd->protection_flags |=
574 cpu_to_le32(MAC_PROT_FLG_SELF_CTS_EN);
575 }
564 576
565 /* 577 /*
566 * I think that we should enable these 2 flags regardless the HT PROT 578 * I think that we should enable these 2 flags regardless the HT PROT
@@ -712,6 +724,31 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
712 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); 724 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
713} 725}
714 726
727static int iwl_mvm_mac_ctxt_cmd_ibss(struct iwl_mvm *mvm,
728 struct ieee80211_vif *vif,
729 u32 action)
730{
731 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
732 struct iwl_mac_ctx_cmd cmd = {};
733
734 WARN_ON(vif->type != NL80211_IFTYPE_ADHOC);
735
736 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
737
738 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON |
739 MAC_FILTER_IN_PROBE_REQUEST);
740
741 /* cmd.ibss.beacon_time/cmd.ibss.beacon_tsf are curently ignored */
742 cmd.ibss.bi = cpu_to_le32(vif->bss_conf.beacon_int);
743 cmd.ibss.bi_reciprocal =
744 cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int));
745
746 /* TODO: Assumes that the beacon id == mac context id */
747 cmd.ibss.beacon_template = cpu_to_le32(mvmvif->id);
748
749 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
750}
751
715struct iwl_mvm_go_iterator_data { 752struct iwl_mvm_go_iterator_data {
716 bool go_active; 753 bool go_active;
717}; 754};
@@ -721,7 +758,8 @@ static void iwl_mvm_go_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif)
721 struct iwl_mvm_go_iterator_data *data = _data; 758 struct iwl_mvm_go_iterator_data *data = _data;
722 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 759 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
723 760
724 if (vif->type == NL80211_IFTYPE_AP && vif->p2p && mvmvif->ap_active) 761 if (vif->type == NL80211_IFTYPE_AP && vif->p2p &&
762 mvmvif->ap_ibss_active)
725 data->go_active = true; 763 data->go_active = true;
726} 764}
727 765
@@ -833,9 +871,10 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
833 cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate)); 871 cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate));
834 872
835 /* Set up TX beacon command fields */ 873 /* Set up TX beacon command fields */
836 iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd, 874 if (vif->type == NL80211_IFTYPE_AP)
837 beacon->data, 875 iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd,
838 beacon_skb_len); 876 beacon->data,
877 beacon_skb_len);
839 878
840 /* Submit command */ 879 /* Submit command */
841 cmd.len[0] = sizeof(beacon_cmd); 880 cmd.len[0] = sizeof(beacon_cmd);
@@ -848,14 +887,15 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
848 return iwl_mvm_send_cmd(mvm, &cmd); 887 return iwl_mvm_send_cmd(mvm, &cmd);
849} 888}
850 889
851/* The beacon template for the AP/GO context has changed and needs update */ 890/* The beacon template for the AP/GO/IBSS has changed and needs update */
852int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, 891int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
853 struct ieee80211_vif *vif) 892 struct ieee80211_vif *vif)
854{ 893{
855 struct sk_buff *beacon; 894 struct sk_buff *beacon;
856 int ret; 895 int ret;
857 896
858 WARN_ON(vif->type != NL80211_IFTYPE_AP); 897 WARN_ON(vif->type != NL80211_IFTYPE_AP &&
898 vif->type != NL80211_IFTYPE_ADHOC);
859 899
860 beacon = ieee80211_beacon_get(mvm->hw, vif); 900 beacon = ieee80211_beacon_get(mvm->hw, vif);
861 if (!beacon) 901 if (!beacon)
@@ -1018,6 +1058,8 @@ static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1018 return iwl_mvm_mac_ctxt_cmd_listener(mvm, vif, action); 1058 return iwl_mvm_mac_ctxt_cmd_listener(mvm, vif, action);
1019 case NL80211_IFTYPE_P2P_DEVICE: 1059 case NL80211_IFTYPE_P2P_DEVICE:
1020 return iwl_mvm_mac_ctxt_cmd_p2p_device(mvm, vif, action); 1060 return iwl_mvm_mac_ctxt_cmd_p2p_device(mvm, vif, action);
1061 case NL80211_IFTYPE_ADHOC:
1062 return iwl_mvm_mac_ctxt_cmd_ibss(mvm, vif, action);
1021 default: 1063 default:
1022 break; 1064 break;
1023 } 1065 }
@@ -1038,6 +1080,9 @@ int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1038 if (ret) 1080 if (ret)
1039 return ret; 1081 return ret;
1040 1082
1083 /* will only do anything at resume from D3 time */
1084 iwl_mvm_set_last_nonqos_seq(mvm, vif);
1085
1041 mvmvif->uploaded = true; 1086 mvmvif->uploaded = true;
1042 return 0; 1087 return 0;
1043} 1088}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 9833cdf6177c..f40685c3764e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -77,6 +77,7 @@
77#include "iwl-eeprom-parse.h" 77#include "iwl-eeprom-parse.h"
78#include "fw-api-scan.h" 78#include "fw-api-scan.h"
79#include "iwl-phy-db.h" 79#include "iwl-phy-db.h"
80#include "testmode.h"
80 81
81static const struct ieee80211_iface_limit iwl_mvm_limits[] = { 82static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
82 { 83 {
@@ -138,6 +139,14 @@ static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
138 } 139 }
139} 140}
140 141
142static int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm)
143{
144 /* we create the 802.11 header and SSID element */
145 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID)
146 return mvm->fw->ucode_capa.max_probe_length - 24 - 2;
147 return mvm->fw->ucode_capa.max_probe_length - 24 - 34;
148}
149
141int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) 150int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
142{ 151{
143 struct ieee80211_hw *hw = mvm->hw; 152 struct ieee80211_hw *hw = mvm->hw;
@@ -158,7 +167,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
158 IEEE80211_HW_SUPPORTS_STATIC_SMPS | 167 IEEE80211_HW_SUPPORTS_STATIC_SMPS |
159 IEEE80211_HW_SUPPORTS_UAPSD; 168 IEEE80211_HW_SUPPORTS_UAPSD;
160 169
161 hw->queues = IWL_MVM_FIRST_AGG_QUEUE; 170 hw->queues = mvm->first_agg_queue;
162 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; 171 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
163 hw->rate_control_algorithm = "iwl-mvm-rs"; 172 hw->rate_control_algorithm = "iwl-mvm-rs";
164 173
@@ -181,6 +190,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
181 BIT(NL80211_IFTYPE_P2P_GO) | 190 BIT(NL80211_IFTYPE_P2P_GO) |
182 BIT(NL80211_IFTYPE_P2P_DEVICE); 191 BIT(NL80211_IFTYPE_P2P_DEVICE);
183 192
193 /* IBSS has bugs in older versions */
194 if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8)
195 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
196
184 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 197 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
185 WIPHY_FLAG_DISABLE_BEACON_HINTS | 198 WIPHY_FLAG_DISABLE_BEACON_HINTS |
186 WIPHY_FLAG_IBSS_RSN; 199 WIPHY_FLAG_IBSS_RSN;
@@ -212,9 +225,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
212 225
213 iwl_mvm_reset_phy_ctxts(mvm); 226 iwl_mvm_reset_phy_ctxts(mvm);
214 227
215 /* we create the 802.11 header and a max-length SSID element */ 228 hw->wiphy->max_scan_ie_len = iwl_mvm_max_scan_ie_len(mvm);
216 hw->wiphy->max_scan_ie_len = 229
217 mvm->fw->ucode_capa.max_probe_length - 24 - 34;
218 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; 230 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
219 231
220 if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels) 232 if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels)
@@ -231,6 +243,15 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
231 else 243 else
232 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 244 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
233 245
246 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) {
247 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
248 hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
249 hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES;
250 /* we create the 802.11 header and zero length SSID IE. */
251 hw->wiphy->max_sched_scan_ie_len =
252 SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2;
253 }
254
234 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN | 255 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
235 NL80211_FEATURE_P2P_GO_OPPPS; 256 NL80211_FEATURE_P2P_GO_OPPPS;
236 257
@@ -548,7 +569,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
548 * In short: there's not much we can do at this point, other than 569 * In short: there's not much we can do at this point, other than
549 * allocating resources :) 570 * allocating resources :)
550 */ 571 */
551 if (vif->type == NL80211_IFTYPE_AP) { 572 if (vif->type == NL80211_IFTYPE_AP ||
573 vif->type == NL80211_IFTYPE_ADHOC) {
552 u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); 574 u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
553 ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta, 575 ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
554 qmask); 576 qmask);
@@ -698,7 +720,14 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
698 * For AP/GO interface, the tear down of the resources allocated to the 720 * For AP/GO interface, the tear down of the resources allocated to the
699 * interface is be handled as part of the stop_ap flow. 721 * interface is be handled as part of the stop_ap flow.
700 */ 722 */
701 if (vif->type == NL80211_IFTYPE_AP) { 723 if (vif->type == NL80211_IFTYPE_AP ||
724 vif->type == NL80211_IFTYPE_ADHOC) {
725#ifdef CONFIG_NL80211_TESTMODE
726 if (vif == mvm->noa_vif) {
727 mvm->noa_vif = NULL;
728 mvm->noa_duration = 0;
729 }
730#endif
702 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); 731 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
703 goto out_release; 732 goto out_release;
704 } 733 }
@@ -796,6 +825,27 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
796 return; 825 return;
797 } 826 }
798 iwl_mvm_configure_mcast_filter(mvm, vif); 827 iwl_mvm_configure_mcast_filter(mvm, vif);
828
829 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
830 &mvm->status)) {
831 /*
832 * If we're restarting then the firmware will
833 * obviously have lost synchronisation with
834 * the AP. It will attempt to synchronise by
835 * itself, but we can make it more reliable by
836 * scheduling a session protection time event.
837 *
838 * The firmware needs to receive a beacon to
839 * catch up with synchronisation, use 110% of
840 * the beacon interval.
841 *
842 * Set a large maximum delay to allow for more
843 * than a single interface.
844 */
845 u32 dur = (11 * vif->bss_conf.beacon_int) / 10;
846 iwl_mvm_protect_session(mvm, vif, dur, dur,
847 5 * dur);
848 }
799 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { 849 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
800 /* remove AP station now that the MAC is unassoc */ 850 /* remove AP station now that the MAC is unassoc */
801 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); 851 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
@@ -819,7 +869,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
819 if (ret) 869 if (ret)
820 IWL_ERR(mvm, "failed to update power mode\n"); 870 IWL_ERR(mvm, "failed to update power mode\n");
821 } 871 }
822 iwl_mvm_bt_coex_vif_assoc(mvm, vif); 872 iwl_mvm_bt_coex_vif_change(mvm);
823 } else if (changes & BSS_CHANGED_BEACON_INFO) { 873 } else if (changes & BSS_CHANGED_BEACON_INFO) {
824 /* 874 /*
825 * We received a beacon _after_ association so 875 * We received a beacon _after_ association so
@@ -848,7 +898,8 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
848 } 898 }
849} 899}
850 900
851static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 901static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
902 struct ieee80211_vif *vif)
852{ 903{
853 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 904 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
854 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 905 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
@@ -871,7 +922,7 @@ static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
871 if (ret) 922 if (ret)
872 goto out_remove; 923 goto out_remove;
873 924
874 mvmvif->ap_active = true; 925 mvmvif->ap_ibss_active = true;
875 926
876 /* Send the bcast station. At this stage the TBTT and DTIM time events 927 /* Send the bcast station. At this stage the TBTT and DTIM time events
877 * are added and applied to the scheduler */ 928 * are added and applied to the scheduler */
@@ -883,10 +934,12 @@ static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
883 if (ret) 934 if (ret)
884 goto out_rm_bcast; 935 goto out_rm_bcast;
885 936
886 /* Need to update the P2P Device MAC */ 937 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
887 if (vif->p2p && mvm->p2p_device_vif) 938 if (vif->p2p && mvm->p2p_device_vif)
888 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif); 939 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
889 940
941 iwl_mvm_bt_coex_vif_change(mvm);
942
890 mutex_unlock(&mvm->mutex); 943 mutex_unlock(&mvm->mutex);
891 return 0; 944 return 0;
892 945
@@ -901,7 +954,8 @@ out_unlock:
901 return ret; 954 return ret;
902} 955}
903 956
904static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 957static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
958 struct ieee80211_vif *vif)
905{ 959{
906 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 960 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
907 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 961 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
@@ -910,9 +964,11 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
910 964
911 mutex_lock(&mvm->mutex); 965 mutex_lock(&mvm->mutex);
912 966
913 mvmvif->ap_active = false; 967 mvmvif->ap_ibss_active = false;
968
969 iwl_mvm_bt_coex_vif_change(mvm);
914 970
915 /* Need to update the P2P Device MAC */ 971 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
916 if (vif->p2p && mvm->p2p_device_vif) 972 if (vif->p2p && mvm->p2p_device_vif)
917 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif); 973 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
918 974
@@ -924,10 +980,11 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
924 mutex_unlock(&mvm->mutex); 980 mutex_unlock(&mvm->mutex);
925} 981}
926 982
927static void iwl_mvm_bss_info_changed_ap(struct iwl_mvm *mvm, 983static void
928 struct ieee80211_vif *vif, 984iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
929 struct ieee80211_bss_conf *bss_conf, 985 struct ieee80211_vif *vif,
930 u32 changes) 986 struct ieee80211_bss_conf *bss_conf,
987 u32 changes)
931{ 988{
932 /* Need to send a new beacon template to the FW */ 989 /* Need to send a new beacon template to the FW */
933 if (changes & BSS_CHANGED_BEACON) { 990 if (changes & BSS_CHANGED_BEACON) {
@@ -950,7 +1007,8 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
950 iwl_mvm_bss_info_changed_station(mvm, vif, bss_conf, changes); 1007 iwl_mvm_bss_info_changed_station(mvm, vif, bss_conf, changes);
951 break; 1008 break;
952 case NL80211_IFTYPE_AP: 1009 case NL80211_IFTYPE_AP:
953 iwl_mvm_bss_info_changed_ap(mvm, vif, bss_conf, changes); 1010 case NL80211_IFTYPE_ADHOC:
1011 iwl_mvm_bss_info_changed_ap_ibss(mvm, vif, bss_conf, changes);
954 break; 1012 break;
955 default: 1013 default:
956 /* shouldn't happen */ 1014 /* shouldn't happen */
@@ -1163,7 +1221,54 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
1163 1221
1164 mutex_lock(&mvm->mutex); 1222 mutex_lock(&mvm->mutex);
1165 /* Try really hard to protect the session and hear a beacon */ 1223 /* Try really hard to protect the session and hear a beacon */
1166 iwl_mvm_protect_session(mvm, vif, duration, min_duration); 1224 iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500);
1225 mutex_unlock(&mvm->mutex);
1226}
1227
1228static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
1229 struct ieee80211_vif *vif,
1230 struct cfg80211_sched_scan_request *req,
1231 struct ieee80211_sched_scan_ies *ies)
1232{
1233 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1234 int ret;
1235
1236 mutex_lock(&mvm->mutex);
1237
1238 if (mvm->scan_status != IWL_MVM_SCAN_NONE) {
1239 IWL_DEBUG_SCAN(mvm,
1240 "SCHED SCAN request during internal scan - abort\n");
1241 ret = -EBUSY;
1242 goto out;
1243 }
1244
1245 mvm->scan_status = IWL_MVM_SCAN_SCHED;
1246
1247 ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies);
1248 if (ret)
1249 goto err;
1250
1251 ret = iwl_mvm_config_sched_scan_profiles(mvm, req);
1252 if (ret)
1253 goto err;
1254
1255 ret = iwl_mvm_sched_scan_start(mvm, req);
1256 if (!ret)
1257 goto out;
1258err:
1259 mvm->scan_status = IWL_MVM_SCAN_NONE;
1260out:
1261 mutex_unlock(&mvm->mutex);
1262 return ret;
1263}
1264
1265static void iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
1266 struct ieee80211_vif *vif)
1267{
1268 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1269
1270 mutex_lock(&mvm->mutex);
1271 iwl_mvm_sched_scan_stop(mvm);
1167 mutex_unlock(&mvm->mutex); 1272 mutex_unlock(&mvm->mutex);
1168} 1273}
1169 1274
@@ -1207,8 +1312,13 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1207 1312
1208 switch (cmd) { 1313 switch (cmd) {
1209 case SET_KEY: 1314 case SET_KEY:
1210 if (vif->type == NL80211_IFTYPE_AP && !sta) { 1315 if ((vif->type == NL80211_IFTYPE_ADHOC ||
1211 /* GTK on AP interface is a TX-only key, return 0 */ 1316 vif->type == NL80211_IFTYPE_AP) && !sta) {
1317 /*
1318 * GTK on AP interface is a TX-only key, return 0;
1319 * on IBSS they're per-station and because we're lazy
1320 * we don't support them for RX, so do the same.
1321 */
1212 ret = 0; 1322 ret = 0;
1213 key->hw_key_idx = STA_KEY_IDX_INVALID; 1323 key->hw_key_idx = STA_KEY_IDX_INVALID;
1214 break; 1324 break;
@@ -1252,6 +1362,9 @@ static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw,
1252{ 1362{
1253 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1363 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1254 1364
1365 if (keyconf->hw_key_idx == STA_KEY_IDX_INVALID)
1366 return;
1367
1255 iwl_mvm_update_tkip_key(mvm, vif, keyconf, sta, iv32, phase1key); 1368 iwl_mvm_update_tkip_key(mvm, vif, keyconf, sta, iv32, phase1key);
1256} 1369}
1257 1370
@@ -1445,6 +1558,7 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
1445 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def, 1558 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
1446 ctx->rx_chains_static, 1559 ctx->rx_chains_static,
1447 ctx->rx_chains_dynamic); 1560 ctx->rx_chains_dynamic);
1561 iwl_mvm_bt_coex_vif_change(mvm);
1448 mutex_unlock(&mvm->mutex); 1562 mutex_unlock(&mvm->mutex);
1449} 1563}
1450 1564
@@ -1464,14 +1578,14 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1464 1578
1465 switch (vif->type) { 1579 switch (vif->type) {
1466 case NL80211_IFTYPE_AP: 1580 case NL80211_IFTYPE_AP:
1581 case NL80211_IFTYPE_ADHOC:
1467 /* 1582 /*
1468 * The AP binding flow is handled as part of the start_ap flow 1583 * The AP binding flow is handled as part of the start_ap flow
1469 * (in bss_info_changed). 1584 * (in bss_info_changed), similarly for IBSS.
1470 */ 1585 */
1471 ret = 0; 1586 ret = 0;
1472 goto out_unlock; 1587 goto out_unlock;
1473 case NL80211_IFTYPE_STATION: 1588 case NL80211_IFTYPE_STATION:
1474 case NL80211_IFTYPE_ADHOC:
1475 case NL80211_IFTYPE_MONITOR: 1589 case NL80211_IFTYPE_MONITOR:
1476 break; 1590 break;
1477 default: 1591 default:
@@ -1517,10 +1631,10 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
1517 1631
1518 iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data); 1632 iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
1519 1633
1520 if (vif->type == NL80211_IFTYPE_AP)
1521 goto out_unlock;
1522
1523 switch (vif->type) { 1634 switch (vif->type) {
1635 case NL80211_IFTYPE_AP:
1636 case NL80211_IFTYPE_ADHOC:
1637 goto out_unlock;
1524 case NL80211_IFTYPE_MONITOR: 1638 case NL80211_IFTYPE_MONITOR:
1525 mvmvif->monitor_active = false; 1639 mvmvif->monitor_active = false;
1526 iwl_mvm_update_quotas(mvm, NULL); 1640 iwl_mvm_update_quotas(mvm, NULL);
@@ -1550,14 +1664,72 @@ static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
1550 return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif); 1664 return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif);
1551} 1665}
1552 1666
1553static void iwl_mvm_mac_rssi_callback(struct ieee80211_hw *hw, 1667#ifdef CONFIG_NL80211_TESTMODE
1668static const struct nla_policy iwl_mvm_tm_policy[IWL_MVM_TM_ATTR_MAX + 1] = {
1669 [IWL_MVM_TM_ATTR_CMD] = { .type = NLA_U32 },
1670 [IWL_MVM_TM_ATTR_NOA_DURATION] = { .type = NLA_U32 },
1671 [IWL_MVM_TM_ATTR_BEACON_FILTER_STATE] = { .type = NLA_U32 },
1672};
1673
1674static int __iwl_mvm_mac_testmode_cmd(struct iwl_mvm *mvm,
1554 struct ieee80211_vif *vif, 1675 struct ieee80211_vif *vif,
1555 enum ieee80211_rssi_event rssi_event) 1676 void *data, int len)
1677{
1678 struct nlattr *tb[IWL_MVM_TM_ATTR_MAX + 1];
1679 int err;
1680 u32 noa_duration;
1681
1682 err = nla_parse(tb, IWL_MVM_TM_ATTR_MAX, data, len, iwl_mvm_tm_policy);
1683 if (err)
1684 return err;
1685
1686 if (!tb[IWL_MVM_TM_ATTR_CMD])
1687 return -EINVAL;
1688
1689 switch (nla_get_u32(tb[IWL_MVM_TM_ATTR_CMD])) {
1690 case IWL_MVM_TM_CMD_SET_NOA:
1691 if (!vif || vif->type != NL80211_IFTYPE_AP || !vif->p2p ||
1692 !vif->bss_conf.enable_beacon ||
1693 !tb[IWL_MVM_TM_ATTR_NOA_DURATION])
1694 return -EINVAL;
1695
1696 noa_duration = nla_get_u32(tb[IWL_MVM_TM_ATTR_NOA_DURATION]);
1697 if (noa_duration >= vif->bss_conf.beacon_int)
1698 return -EINVAL;
1699
1700 mvm->noa_duration = noa_duration;
1701 mvm->noa_vif = vif;
1702
1703 return iwl_mvm_update_quotas(mvm, NULL);
1704 case IWL_MVM_TM_CMD_SET_BEACON_FILTER:
1705 /* must be associated client vif - ignore authorized */
1706 if (!vif || vif->type != NL80211_IFTYPE_STATION ||
1707 !vif->bss_conf.assoc || !vif->bss_conf.dtim_period ||
1708 !tb[IWL_MVM_TM_ATTR_BEACON_FILTER_STATE])
1709 return -EINVAL;
1710
1711 if (nla_get_u32(tb[IWL_MVM_TM_ATTR_BEACON_FILTER_STATE]))
1712 return iwl_mvm_enable_beacon_filter(mvm, vif);
1713 return iwl_mvm_disable_beacon_filter(mvm, vif);
1714 }
1715
1716 return -EOPNOTSUPP;
1717}
1718
1719static int iwl_mvm_mac_testmode_cmd(struct ieee80211_hw *hw,
1720 struct ieee80211_vif *vif,
1721 void *data, int len)
1556{ 1722{
1557 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1723 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1724 int err;
1558 1725
1559 iwl_mvm_bt_rssi_event(mvm, vif, rssi_event); 1726 mutex_lock(&mvm->mutex);
1727 err = __iwl_mvm_mac_testmode_cmd(mvm, vif, data, len);
1728 mutex_unlock(&mvm->mutex);
1729
1730 return err;
1560} 1731}
1732#endif
1561 1733
1562struct ieee80211_ops iwl_mvm_hw_ops = { 1734struct ieee80211_ops iwl_mvm_hw_ops = {
1563 .tx = iwl_mvm_mac_tx, 1735 .tx = iwl_mvm_mac_tx,
@@ -1578,23 +1750,27 @@ struct ieee80211_ops iwl_mvm_hw_ops = {
1578 .set_rts_threshold = iwl_mvm_mac_set_rts_threshold, 1750 .set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
1579 .conf_tx = iwl_mvm_mac_conf_tx, 1751 .conf_tx = iwl_mvm_mac_conf_tx,
1580 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx, 1752 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
1753 .sched_scan_start = iwl_mvm_mac_sched_scan_start,
1754 .sched_scan_stop = iwl_mvm_mac_sched_scan_stop,
1581 .set_key = iwl_mvm_mac_set_key, 1755 .set_key = iwl_mvm_mac_set_key,
1582 .update_tkip_key = iwl_mvm_mac_update_tkip_key, 1756 .update_tkip_key = iwl_mvm_mac_update_tkip_key,
1583 .remain_on_channel = iwl_mvm_roc, 1757 .remain_on_channel = iwl_mvm_roc,
1584 .cancel_remain_on_channel = iwl_mvm_cancel_roc, 1758 .cancel_remain_on_channel = iwl_mvm_cancel_roc,
1585 .rssi_callback = iwl_mvm_mac_rssi_callback,
1586
1587 .add_chanctx = iwl_mvm_add_chanctx, 1759 .add_chanctx = iwl_mvm_add_chanctx,
1588 .remove_chanctx = iwl_mvm_remove_chanctx, 1760 .remove_chanctx = iwl_mvm_remove_chanctx,
1589 .change_chanctx = iwl_mvm_change_chanctx, 1761 .change_chanctx = iwl_mvm_change_chanctx,
1590 .assign_vif_chanctx = iwl_mvm_assign_vif_chanctx, 1762 .assign_vif_chanctx = iwl_mvm_assign_vif_chanctx,
1591 .unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx, 1763 .unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx,
1592 1764
1593 .start_ap = iwl_mvm_start_ap, 1765 .start_ap = iwl_mvm_start_ap_ibss,
1594 .stop_ap = iwl_mvm_stop_ap, 1766 .stop_ap = iwl_mvm_stop_ap_ibss,
1767 .join_ibss = iwl_mvm_start_ap_ibss,
1768 .leave_ibss = iwl_mvm_stop_ap_ibss,
1595 1769
1596 .set_tim = iwl_mvm_set_tim, 1770 .set_tim = iwl_mvm_set_tim,
1597 1771
1772 CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd)
1773
1598#ifdef CONFIG_PM_SLEEP 1774#ifdef CONFIG_PM_SLEEP
1599 /* look at d3.c */ 1775 /* look at d3.c */
1600 .suspend = iwl_mvm_suspend, 1776 .suspend = iwl_mvm_suspend,
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index b0389279cc1e..6235cb729f5c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -162,6 +162,7 @@ enum iwl_power_scheme {
162struct iwl_mvm_power_ops { 162struct iwl_mvm_power_ops {
163 int (*power_update_mode)(struct iwl_mvm *mvm, 163 int (*power_update_mode)(struct iwl_mvm *mvm,
164 struct ieee80211_vif *vif); 164 struct ieee80211_vif *vif);
165 int (*power_update_device_mode)(struct iwl_mvm *mvm);
165 int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 166 int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
166#ifdef CONFIG_IWLWIFI_DEBUGFS 167#ifdef CONFIG_IWLWIFI_DEBUGFS
167 int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 168 int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
@@ -241,12 +242,18 @@ enum iwl_mvm_smps_type_request {
241* @last_beacon_signal: last beacon rssi signal in dbm 242* @last_beacon_signal: last beacon rssi signal in dbm
242* @ave_beacon_signal: average beacon signal 243* @ave_beacon_signal: average beacon signal
243* @last_cqm_event: rssi of the last cqm event 244* @last_cqm_event: rssi of the last cqm event
245* @bt_coex_min_thold: minimum threshold for BT coex
246* @bt_coex_max_thold: maximum threshold for BT coex
247* @last_bt_coex_event: rssi of the last BT coex event
244*/ 248*/
245struct iwl_mvm_vif_bf_data { 249struct iwl_mvm_vif_bf_data {
246 bool bf_enabled; 250 bool bf_enabled;
247 bool ba_enabled; 251 bool ba_enabled;
248 s8 ave_beacon_signal; 252 s8 ave_beacon_signal;
249 s8 last_cqm_event; 253 s8 last_cqm_event;
254 s8 bt_coex_min_thold;
255 s8 bt_coex_max_thold;
256 s8 last_bt_coex_event;
250}; 257};
251 258
252/** 259/**
@@ -255,8 +262,8 @@ struct iwl_mvm_vif_bf_data {
255 * @color: to solve races upon MAC addition and removal 262 * @color: to solve races upon MAC addition and removal
256 * @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA 263 * @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA
257 * @uploaded: indicates the MAC context has been added to the device 264 * @uploaded: indicates the MAC context has been added to the device
258 * @ap_active: indicates that ap context is configured, and that the interface 265 * @ap_ibss_active: indicates that AP/IBSS is configured and that the interface
259 * should get quota etc. 266 * should get quota etc.
260 * @monitor_active: indicates that monitor context is configured, and that the 267 * @monitor_active: indicates that monitor context is configured, and that the
261 * interface should get quota etc. 268 * interface should get quota etc.
262 * @queue_params: QoS params for this MAC 269 * @queue_params: QoS params for this MAC
@@ -272,7 +279,7 @@ struct iwl_mvm_vif {
272 u8 ap_sta_id; 279 u8 ap_sta_id;
273 280
274 bool uploaded; 281 bool uploaded;
275 bool ap_active; 282 bool ap_ibss_active;
276 bool monitor_active; 283 bool monitor_active;
277 struct iwl_mvm_vif_bf_data bf_data; 284 struct iwl_mvm_vif_bf_data bf_data;
278 285
@@ -306,6 +313,9 @@ struct iwl_mvm_vif {
306 313
307 int tx_key_idx; 314 int tx_key_idx;
308 315
316 bool seqno_valid;
317 u16 seqno;
318
309#if IS_ENABLED(CONFIG_IPV6) 319#if IS_ENABLED(CONFIG_IPV6)
310 /* IPv6 addresses for WoWLAN */ 320 /* IPv6 addresses for WoWLAN */
311 struct in6_addr target_ipv6_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX]; 321 struct in6_addr target_ipv6_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX];
@@ -333,6 +343,7 @@ iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif)
333enum iwl_scan_status { 343enum iwl_scan_status {
334 IWL_MVM_SCAN_NONE, 344 IWL_MVM_SCAN_NONE,
335 IWL_MVM_SCAN_OS, 345 IWL_MVM_SCAN_OS,
346 IWL_MVM_SCAN_SCHED,
336}; 347};
337 348
338/** 349/**
@@ -434,7 +445,7 @@ struct iwl_mvm {
434 445
435 enum iwl_ucode_type cur_ucode; 446 enum iwl_ucode_type cur_ucode;
436 bool ucode_loaded; 447 bool ucode_loaded;
437 bool init_ucode_run; 448 bool init_ucode_complete;
438 u32 error_event_table; 449 u32 error_event_table;
439 u32 log_event_table; 450 u32 log_event_table;
440 451
@@ -470,6 +481,9 @@ struct iwl_mvm {
470 enum iwl_scan_status scan_status; 481 enum iwl_scan_status scan_status;
471 struct iwl_scan_cmd *scan_cmd; 482 struct iwl_scan_cmd *scan_cmd;
472 483
484 /* rx chain antennas set through debugfs for the scan command */
485 u8 scan_rx_ant;
486
473 /* Internal station */ 487 /* Internal station */
474 struct iwl_mvm_int_sta aux_sta; 488 struct iwl_mvm_int_sta aux_sta;
475 489
@@ -479,7 +493,8 @@ struct iwl_mvm {
479#ifdef CONFIG_IWLWIFI_DEBUGFS 493#ifdef CONFIG_IWLWIFI_DEBUGFS
480 struct dentry *debugfs_dir; 494 struct dentry *debugfs_dir;
481 u32 dbgfs_sram_offset, dbgfs_sram_len; 495 u32 dbgfs_sram_offset, dbgfs_sram_len;
482 bool prevent_power_down_d3; 496 bool disable_power_off;
497 bool disable_power_off_d3;
483#endif 498#endif
484 499
485 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX]; 500 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
@@ -523,12 +538,23 @@ struct iwl_mvm {
523 /* BT-Coex */ 538 /* BT-Coex */
524 u8 bt_kill_msk; 539 u8 bt_kill_msk;
525 struct iwl_bt_coex_profile_notif last_bt_notif; 540 struct iwl_bt_coex_profile_notif last_bt_notif;
541 struct iwl_bt_coex_ci_cmd last_bt_ci_cmd;
526 542
527 /* Thermal Throttling and CTkill */ 543 /* Thermal Throttling and CTkill */
528 struct iwl_mvm_tt_mgmt thermal_throttle; 544 struct iwl_mvm_tt_mgmt thermal_throttle;
529 s32 temperature; /* Celsius */ 545 s32 temperature; /* Celsius */
530 546
531 const struct iwl_mvm_power_ops *pm_ops; 547 const struct iwl_mvm_power_ops *pm_ops;
548
549#ifdef CONFIG_NL80211_TESTMODE
550 u32 noa_duration;
551 struct ieee80211_vif *noa_vif;
552#endif
553
554 /* Tx queues */
555 u8 aux_queue;
556 u8 first_agg_queue;
557 u8 last_agg_queue;
532}; 558};
533 559
534/* Extract MVM priv from op_mode and _hw */ 560/* Extract MVM priv from op_mode and _hw */
@@ -570,6 +596,9 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm);
570/* Utils */ 596/* Utils */
571int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, 597int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
572 enum ieee80211_band band); 598 enum ieee80211_band band);
599void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
600 enum ieee80211_band band,
601 struct ieee80211_tx_rate *r);
573u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx); 602u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx);
574void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm); 603void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm);
575void iwl_mvm_dump_sram(struct iwl_mvm *mvm); 604void iwl_mvm_dump_sram(struct iwl_mvm *mvm);
@@ -608,6 +637,7 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
608 637
609/* NVM */ 638/* NVM */
610int iwl_nvm_init(struct iwl_mvm *mvm); 639int iwl_nvm_init(struct iwl_mvm *mvm);
640int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm);
611 641
612int iwl_mvm_up(struct iwl_mvm *mvm); 642int iwl_mvm_up(struct iwl_mvm *mvm);
613int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm); 643int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm);
@@ -682,6 +712,23 @@ int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
682 struct iwl_device_cmd *cmd); 712 struct iwl_device_cmd *cmd);
683void iwl_mvm_cancel_scan(struct iwl_mvm *mvm); 713void iwl_mvm_cancel_scan(struct iwl_mvm *mvm);
684 714
715/* Scheduled scan */
716int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
717 struct iwl_rx_cmd_buffer *rxb,
718 struct iwl_device_cmd *cmd);
719int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
720 struct ieee80211_vif *vif,
721 struct cfg80211_sched_scan_request *req,
722 struct ieee80211_sched_scan_ies *ies);
723int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
724 struct cfg80211_sched_scan_request *req);
725int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
726 struct cfg80211_sched_scan_request *req);
727void iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm);
728int iwl_mvm_rx_sched_scan_results(struct iwl_mvm *mvm,
729 struct iwl_rx_cmd_buffer *rxb,
730 struct iwl_device_cmd *cmd);
731
685/* MVM debugfs */ 732/* MVM debugfs */
686#ifdef CONFIG_IWLWIFI_DEBUGFS 733#ifdef CONFIG_IWLWIFI_DEBUGFS
687int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir); 734int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir);
@@ -720,6 +767,13 @@ static inline int iwl_mvm_power_disable(struct iwl_mvm *mvm,
720 return mvm->pm_ops->power_disable(mvm, vif); 767 return mvm->pm_ops->power_disable(mvm, vif);
721} 768}
722 769
770static inline int iwl_mvm_power_update_device_mode(struct iwl_mvm *mvm)
771{
772 if (mvm->pm_ops->power_update_device_mode)
773 return mvm->pm_ops->power_update_device_mode(mvm);
774 return 0;
775}
776
723#ifdef CONFIG_IWLWIFI_DEBUGFS 777#ifdef CONFIG_IWLWIFI_DEBUGFS
724static inline int iwl_mvm_power_dbgfs_read(struct iwl_mvm *mvm, 778static inline int iwl_mvm_power_dbgfs_read(struct iwl_mvm *mvm,
725 struct ieee80211_vif *vif, 779 struct ieee80211_vif *vif,
@@ -745,6 +799,15 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
745void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, 799void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
746 struct ieee80211_vif *vif, int idx); 800 struct ieee80211_vif *vif, int idx);
747extern const struct file_operations iwl_dbgfs_d3_test_ops; 801extern const struct file_operations iwl_dbgfs_d3_test_ops;
802#ifdef CONFIG_PM_SLEEP
803void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm,
804 struct ieee80211_vif *vif);
805#else
806static inline void
807iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
808{
809}
810#endif
748 811
749/* BT Coex */ 812/* BT Coex */
750int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm); 813int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm);
@@ -754,7 +817,20 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
754 struct iwl_device_cmd *cmd); 817 struct iwl_device_cmd *cmd);
755void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 818void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
756 enum ieee80211_rssi_event rssi_event); 819 enum ieee80211_rssi_event rssi_event);
757void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 820void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm);
821u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm,
822 struct ieee80211_sta *sta);
823bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
824 struct ieee80211_sta *sta);
825
826enum iwl_bt_kill_msk {
827 BT_KILL_MSK_DEFAULT,
828 BT_KILL_MSK_SCO_HID_A2DP,
829 BT_KILL_MSK_REDUCED_TXPOW,
830 BT_KILL_MSK_MAX,
831};
832extern const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX];
833extern const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX];
758 834
759/* beacon filtering */ 835/* beacon filtering */
760#ifdef CONFIG_IWLWIFI_DEBUGFS 836#ifdef CONFIG_IWLWIFI_DEBUGFS
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index edb94ea31654..2beffd028b67 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -77,7 +77,7 @@ static const int nvm_to_read[] = {
77 77
78/* Default NVM size to read */ 78/* Default NVM size to read */
79#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024) 79#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024)
80#define IWL_MAX_NVM_SECTION_SIZE 6000 80#define IWL_MAX_NVM_SECTION_SIZE 7000
81 81
82#define NVM_WRITE_OPCODE 1 82#define NVM_WRITE_OPCODE 1
83#define NVM_READ_OPCODE 0 83#define NVM_READ_OPCODE 0
@@ -259,6 +259,8 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
259#define MAX_NVM_FILE_LEN 16384 259#define MAX_NVM_FILE_LEN 16384
260 260
261/* 261/*
262 * Reads external NVM from a file into mvm->nvm_sections
263 *
262 * HOW TO CREATE THE NVM FILE FORMAT: 264 * HOW TO CREATE THE NVM FILE FORMAT:
263 * ------------------------------ 265 * ------------------------------
264 * 1. create hex file, format: 266 * 1. create hex file, format:
@@ -277,20 +279,23 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
277 * 279 *
278 * 4. save as "iNVM_xxx.bin" under /lib/firmware 280 * 4. save as "iNVM_xxx.bin" under /lib/firmware
279 */ 281 */
280static int iwl_mvm_load_external_nvm(struct iwl_mvm *mvm) 282static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
281{ 283{
282 int ret, section_id, section_size; 284 int ret, section_size;
285 u16 section_id;
283 const struct firmware *fw_entry; 286 const struct firmware *fw_entry;
284 const struct { 287 const struct {
285 __le16 word1; 288 __le16 word1;
286 __le16 word2; 289 __le16 word2;
287 u8 data[]; 290 u8 data[];
288 } *file_sec; 291 } *file_sec;
289 const u8 *eof; 292 const u8 *eof, *temp;
290 293
291#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF)) 294#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
292#define NVM_WORD2_ID(x) (x >> 12) 295#define NVM_WORD2_ID(x) (x >> 12)
293 296
297 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n");
298
294 /* 299 /*
295 * Obtain NVM image via request_firmware. Since we already used 300 * Obtain NVM image via request_firmware. Since we already used
296 * request_firmware_nowait() for the firmware binary load and only 301 * request_firmware_nowait() for the firmware binary load and only
@@ -362,12 +367,18 @@ static int iwl_mvm_load_external_nvm(struct iwl_mvm *mvm)
362 break; 367 break;
363 } 368 }
364 369
365 ret = iwl_nvm_write_section(mvm, section_id, file_sec->data, 370 temp = kmemdup(file_sec->data, section_size, GFP_KERNEL);
366 section_size); 371 if (!temp) {
367 if (ret < 0) { 372 ret = -ENOMEM;
368 IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret); 373 break;
374 }
375 if (WARN_ON(section_id >= NVM_NUM_OF_SECTIONS)) {
376 IWL_ERR(mvm, "Invalid NVM section ID\n");
377 ret = -EINVAL;
369 break; 378 break;
370 } 379 }
380 mvm->nvm_sections[section_id].data = temp;
381 mvm->nvm_sections[section_id].length = section_size;
371 382
372 /* advance to the next section */ 383 /* advance to the next section */
373 file_sec = (void *)(file_sec->data + section_size); 384 file_sec = (void *)(file_sec->data + section_size);
@@ -377,6 +388,28 @@ out:
377 return ret; 388 return ret;
378} 389}
379 390
391/* Loads the NVM data stored in mvm->nvm_sections into the NIC */
392int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
393{
394 int i, ret;
395 u16 section_id;
396 struct iwl_nvm_section *sections = mvm->nvm_sections;
397
398 IWL_DEBUG_EEPROM(mvm->trans->dev, "'Write to NVM\n");
399
400 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) {
401 section_id = nvm_to_read[i];
402 ret = iwl_nvm_write_section(mvm, section_id,
403 sections[section_id].data,
404 sections[section_id].length);
405 if (ret < 0) {
406 IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret);
407 break;
408 }
409 }
410 return ret;
411}
412
380int iwl_nvm_init(struct iwl_mvm *mvm) 413int iwl_nvm_init(struct iwl_mvm *mvm)
381{ 414{
382 int ret, i, section; 415 int ret, i, section;
@@ -385,36 +418,36 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
385 /* load external NVM if configured */ 418 /* load external NVM if configured */
386 if (iwlwifi_mod_params.nvm_file) { 419 if (iwlwifi_mod_params.nvm_file) {
387 /* move to External NVM flow */ 420 /* move to External NVM flow */
388 ret = iwl_mvm_load_external_nvm(mvm); 421 ret = iwl_mvm_read_external_nvm(mvm);
389 if (ret) 422 if (ret)
390 return ret; 423 return ret;
391 } 424 } else {
392 425 /* Read From FW NVM */
393 /* Read From FW NVM */ 426 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
394 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n"); 427
395 428 /* TODO: find correct NVM max size for a section */
396 /* TODO: find correct NVM max size for a section */ 429 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
397 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, 430 GFP_KERNEL);
398 GFP_KERNEL); 431 if (!nvm_buffer)
399 if (!nvm_buffer) 432 return -ENOMEM;
400 return -ENOMEM; 433 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) {
401 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) { 434 section = nvm_to_read[i];
402 section = nvm_to_read[i]; 435 /* we override the constness for initial read */
403 /* we override the constness for initial read */ 436 ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
404 ret = iwl_nvm_read_section(mvm, section, nvm_buffer); 437 if (ret < 0)
405 if (ret < 0) 438 break;
406 break; 439 temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
407 temp = kmemdup(nvm_buffer, ret, GFP_KERNEL); 440 if (!temp) {
408 if (!temp) { 441 ret = -ENOMEM;
409 ret = -ENOMEM; 442 break;
410 break; 443 }
444 mvm->nvm_sections[section].data = temp;
445 mvm->nvm_sections[section].length = ret;
411 } 446 }
412 mvm->nvm_sections[section].data = temp; 447 kfree(nvm_buffer);
413 mvm->nvm_sections[section].length = ret; 448 if (ret < 0)
449 return ret;
414 } 450 }
415 kfree(nvm_buffer);
416 if (ret < 0)
417 return ret;
418 451
419 mvm->nvm_data = iwl_parse_nvm_sections(mvm); 452 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
420 if (!mvm->nvm_data) 453 if (!mvm->nvm_data)
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 2fcc8ef88a68..59b7cb3c6134 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -224,6 +224,10 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
224 224
225 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), 225 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
226 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), 226 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
227 RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
228 iwl_mvm_rx_scan_offload_complete_notif, false),
229 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_sched_scan_results,
230 false),
227 231
228 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), 232 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
229 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), 233 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
@@ -249,6 +253,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
249 CMD(TIME_EVENT_NOTIFICATION), 253 CMD(TIME_EVENT_NOTIFICATION),
250 CMD(BINDING_CONTEXT_CMD), 254 CMD(BINDING_CONTEXT_CMD),
251 CMD(TIME_QUOTA_CMD), 255 CMD(TIME_QUOTA_CMD),
256 CMD(NON_QOS_TX_COUNTER_CMD),
252 CMD(RADIO_VERSION_NOTIFICATION), 257 CMD(RADIO_VERSION_NOTIFICATION),
253 CMD(SCAN_REQUEST_CMD), 258 CMD(SCAN_REQUEST_CMD),
254 CMD(SCAN_ABORT_CMD), 259 CMD(SCAN_ABORT_CMD),
@@ -260,10 +265,12 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
260 CMD(CALIB_RES_NOTIF_PHY_DB), 265 CMD(CALIB_RES_NOTIF_PHY_DB),
261 CMD(SET_CALIB_DEFAULT_CMD), 266 CMD(SET_CALIB_DEFAULT_CMD),
262 CMD(CALIBRATION_COMPLETE_NOTIFICATION), 267 CMD(CALIBRATION_COMPLETE_NOTIFICATION),
268 CMD(ADD_STA_KEY),
263 CMD(ADD_STA), 269 CMD(ADD_STA),
264 CMD(REMOVE_STA), 270 CMD(REMOVE_STA),
265 CMD(LQ_CMD), 271 CMD(LQ_CMD),
266 CMD(SCAN_OFFLOAD_CONFIG_CMD), 272 CMD(SCAN_OFFLOAD_CONFIG_CMD),
273 CMD(MATCH_FOUND_NOTIFICATION),
267 CMD(SCAN_OFFLOAD_REQUEST_CMD), 274 CMD(SCAN_OFFLOAD_REQUEST_CMD),
268 CMD(SCAN_OFFLOAD_ABORT_CMD), 275 CMD(SCAN_OFFLOAD_ABORT_CMD),
269 CMD(SCAN_OFFLOAD_COMPLETE), 276 CMD(SCAN_OFFLOAD_COMPLETE),
@@ -303,6 +310,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
303 CMD(REPLY_BEACON_FILTERING_CMD), 310 CMD(REPLY_BEACON_FILTERING_CMD),
304 CMD(REPLY_THERMAL_MNG_BACKOFF), 311 CMD(REPLY_THERMAL_MNG_BACKOFF),
305 CMD(MAC_PM_POWER_TABLE), 312 CMD(MAC_PM_POWER_TABLE),
313 CMD(BT_COEX_CI),
306}; 314};
307#undef CMD 315#undef CMD
308 316
@@ -344,6 +352,14 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
344 352
345 mvm->restart_fw = iwlwifi_mod_params.restart_fw ? -1 : 0; 353 mvm->restart_fw = iwlwifi_mod_params.restart_fw ? -1 : 0;
346 354
355 mvm->aux_queue = 15;
356 mvm->first_agg_queue = 16;
357 mvm->last_agg_queue = mvm->cfg->base_params->num_of_queues - 1;
358 if (mvm->cfg->base_params->num_of_queues == 16) {
359 mvm->aux_queue = 11;
360 mvm->first_agg_queue = 12;
361 }
362
347 mutex_init(&mvm->mutex); 363 mutex_init(&mvm->mutex);
348 spin_lock_init(&mvm->async_handlers_lock); 364 spin_lock_init(&mvm->async_handlers_lock);
349 INIT_LIST_HEAD(&mvm->time_event_list); 365 INIT_LIST_HEAD(&mvm->time_event_list);
@@ -401,24 +417,32 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
401 IWL_INFO(mvm, "Detected %s, REV=0x%X\n", 417 IWL_INFO(mvm, "Detected %s, REV=0x%X\n",
402 mvm->cfg->name, mvm->trans->hw_rev); 418 mvm->cfg->name, mvm->trans->hw_rev);
403 419
404 err = iwl_trans_start_hw(mvm->trans);
405 if (err)
406 goto out_free;
407
408 iwl_mvm_tt_initialize(mvm); 420 iwl_mvm_tt_initialize(mvm);
409 421
410 mutex_lock(&mvm->mutex); 422 /*
411 err = iwl_run_init_mvm_ucode(mvm, true); 423 * If the NVM exists in an external file,
412 mutex_unlock(&mvm->mutex); 424 * there is no need to unnecessarily power up the NIC at driver load
413 /* returns 0 if successful, 1 if success but in rfkill */ 425 */
414 if (err < 0 && !iwlmvm_mod_params.init_dbg) { 426 if (iwlwifi_mod_params.nvm_file) {
415 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err); 427 iwl_nvm_init(mvm);
416 goto out_free; 428 } else {
417 } 429 err = iwl_trans_start_hw(mvm->trans);
430 if (err)
431 goto out_free;
432
433 mutex_lock(&mvm->mutex);
434 err = iwl_run_init_mvm_ucode(mvm, true);
435 mutex_unlock(&mvm->mutex);
436 /* returns 0 if successful, 1 if success but in rfkill */
437 if (err < 0 && !iwlmvm_mod_params.init_dbg) {
438 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err);
439 goto out_free;
440 }
418 441
419 /* Stop the hw after the ALIVE and NVM has been read */ 442 /* Stop the hw after the ALIVE and NVM has been read */
420 if (!iwlmvm_mod_params.init_dbg) 443 if (!iwlmvm_mod_params.init_dbg)
421 iwl_trans_stop_hw(mvm->trans, false); 444 iwl_trans_stop_hw(mvm->trans, false);
445 }
422 446
423 scan_size = sizeof(struct iwl_scan_cmd) + 447 scan_size = sizeof(struct iwl_scan_cmd) +
424 mvm->fw->ucode_capa.max_probe_length + 448 mvm->fw->ucode_capa.max_probe_length +
@@ -449,7 +473,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
449 out_free: 473 out_free:
450 iwl_phy_db_free(mvm->phy_db); 474 iwl_phy_db_free(mvm->phy_db);
451 kfree(mvm->scan_cmd); 475 kfree(mvm->scan_cmd);
452 iwl_trans_stop_hw(trans, true); 476 if (!iwlwifi_mod_params.nvm_file)
477 iwl_trans_stop_hw(trans, true);
453 ieee80211_free_hw(mvm->hw); 478 ieee80211_free_hw(mvm->hw);
454 return NULL; 479 return NULL;
455} 480}
@@ -715,6 +740,9 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
715 case IWL_MVM_SCAN_OS: 740 case IWL_MVM_SCAN_OS:
716 ieee80211_scan_completed(mvm->hw, true); 741 ieee80211_scan_completed(mvm->hw, true);
717 break; 742 break;
743 case IWL_MVM_SCAN_SCHED:
744 ieee80211_sched_scan_stopped(mvm->hw);
745 break;
718 } 746 }
719 747
720 if (mvm->restart_fw > 0) 748 if (mvm->restart_fw > 0)
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index d58e393324ef..550824aa84ea 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -300,11 +300,6 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
300 } 300 }
301 301
302 if (cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) { 302 if (cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) {
303 cmd->rx_data_timeout_uapsd =
304 cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT);
305 cmd->tx_data_timeout_uapsd =
306 cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT);
307
308 if (cmd->uapsd_ac_flags == (BIT(IEEE80211_AC_VO) | 303 if (cmd->uapsd_ac_flags == (BIT(IEEE80211_AC_VO) |
309 BIT(IEEE80211_AC_VI) | 304 BIT(IEEE80211_AC_VI) |
310 BIT(IEEE80211_AC_BE) | 305 BIT(IEEE80211_AC_BE) |
@@ -319,10 +314,31 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
319 } 314 }
320 315
321 cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP; 316 cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP;
322 cmd->heavy_tx_thld_packets = 317
323 IWL_MVM_PS_HEAVY_TX_THLD_PACKETS; 318 if (mvm->cur_ucode == IWL_UCODE_WOWLAN || cmd->flags &
324 cmd->heavy_rx_thld_packets = 319 cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
325 IWL_MVM_PS_HEAVY_RX_THLD_PACKETS; 320 cmd->rx_data_timeout_uapsd =
321 cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT);
322 cmd->tx_data_timeout_uapsd =
323 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
324 } else {
325 cmd->rx_data_timeout_uapsd =
326 cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT);
327 cmd->tx_data_timeout_uapsd =
328 cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT);
329 }
330
331 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
332 cmd->heavy_tx_thld_packets =
333 IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS;
334 cmd->heavy_rx_thld_packets =
335 IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS;
336 } else {
337 cmd->heavy_tx_thld_packets =
338 IWL_MVM_PS_HEAVY_TX_THLD_PACKETS;
339 cmd->heavy_rx_thld_packets =
340 IWL_MVM_PS_HEAVY_RX_THLD_PACKETS;
341 }
326 cmd->heavy_tx_thld_percentage = 342 cmd->heavy_tx_thld_percentage =
327 IWL_MVM_PS_HEAVY_TX_THLD_PERCENT; 343 IWL_MVM_PS_HEAVY_TX_THLD_PERCENT;
328 cmd->heavy_rx_thld_percentage = 344 cmd->heavy_rx_thld_percentage =
@@ -430,6 +446,32 @@ static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm,
430 sizeof(cmd), &cmd); 446 sizeof(cmd), &cmd);
431} 447}
432 448
449static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
450{
451 struct iwl_device_power_cmd cmd = {
452 .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
453 };
454
455 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
456 return 0;
457
458 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM)
459 cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK);
460
461#ifdef CONFIG_IWLWIFI_DEBUGFS
462 if ((mvm->cur_ucode == IWL_UCODE_WOWLAN) ? mvm->disable_power_off_d3 :
463 mvm->disable_power_off)
464 cmd.flags &=
465 cpu_to_le16(~DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK);
466#endif
467 IWL_DEBUG_POWER(mvm,
468 "Sending device power command with flags = 0x%X\n",
469 cmd.flags);
470
471 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, sizeof(cmd),
472 &cmd);
473}
474
433#ifdef CONFIG_IWLWIFI_DEBUGFS 475#ifdef CONFIG_IWLWIFI_DEBUGFS
434static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, 476static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm,
435 struct ieee80211_vif *vif, char *buf, 477 struct ieee80211_vif *vif, char *buf,
@@ -440,10 +482,11 @@ static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm,
440 482
441 iwl_mvm_power_build_cmd(mvm, vif, &cmd); 483 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
442 484
443 pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n", 485 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
444 (cmd.flags & 486 pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n",
445 cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ? 487 (cmd.flags &
446 0 : 1); 488 cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ?
489 0 : 1);
447 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n", 490 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
448 iwlmvm_mod_params.power_scheme); 491 iwlmvm_mod_params.power_scheme);
449 pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n", 492 pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n",
@@ -609,6 +652,7 @@ int iwl_mvm_update_beacon_filter(struct iwl_mvm *mvm,
609 652
610const struct iwl_mvm_power_ops pm_mac_ops = { 653const struct iwl_mvm_power_ops pm_mac_ops = {
611 .power_update_mode = iwl_mvm_power_mac_update_mode, 654 .power_update_mode = iwl_mvm_power_mac_update_mode,
655 .power_update_device_mode = iwl_mvm_power_update_device,
612 .power_disable = iwl_mvm_power_mac_disable, 656 .power_disable = iwl_mvm_power_mac_disable,
613#ifdef CONFIG_IWLWIFI_DEBUGFS 657#ifdef CONFIG_IWLWIFI_DEBUGFS
614 .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read, 658 .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read,
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index 5c6ae16ec52b..17e2bc827f9a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -110,7 +110,8 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
110 data->n_interfaces[id]++; 110 data->n_interfaces[id]++;
111 break; 111 break;
112 case NL80211_IFTYPE_AP: 112 case NL80211_IFTYPE_AP:
113 if (mvmvif->ap_active) 113 case NL80211_IFTYPE_ADHOC:
114 if (mvmvif->ap_ibss_active)
114 data->n_interfaces[id]++; 115 data->n_interfaces[id]++;
115 break; 116 break;
116 case NL80211_IFTYPE_MONITOR: 117 case NL80211_IFTYPE_MONITOR:
@@ -119,16 +120,45 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
119 break; 120 break;
120 case NL80211_IFTYPE_P2P_DEVICE: 121 case NL80211_IFTYPE_P2P_DEVICE:
121 break; 122 break;
122 case NL80211_IFTYPE_ADHOC:
123 if (vif->bss_conf.ibss_joined)
124 data->n_interfaces[id]++;
125 break;
126 default: 123 default:
127 WARN_ON_ONCE(1); 124 WARN_ON_ONCE(1);
128 break; 125 break;
129 } 126 }
130} 127}
131 128
129static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm,
130 struct iwl_time_quota_cmd *cmd)
131{
132#ifdef CONFIG_NL80211_TESTMODE
133 struct iwl_mvm_vif *mvmvif;
134 int i, phy_id = -1, beacon_int = 0;
135
136 if (!mvm->noa_duration || !mvm->noa_vif)
137 return;
138
139 mvmvif = iwl_mvm_vif_from_mac80211(mvm->noa_vif);
140 if (!mvmvif->ap_ibss_active)
141 return;
142
143 phy_id = mvmvif->phy_ctxt->id;
144 beacon_int = mvm->noa_vif->bss_conf.beacon_int;
145
146 for (i = 0; i < MAX_BINDINGS; i++) {
147 u32 id_n_c = le32_to_cpu(cmd->quotas[i].id_and_color);
148 u32 id = (id_n_c & FW_CTXT_ID_MSK) >> FW_CTXT_ID_POS;
149 u32 quota = le32_to_cpu(cmd->quotas[i].quota);
150
151 if (id != phy_id)
152 continue;
153
154 quota *= (beacon_int - mvm->noa_duration);
155 quota /= beacon_int;
156
157 cmd->quotas[i].quota = cpu_to_le32(quota);
158 }
159#endif
160}
161
132int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif) 162int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
133{ 163{
134 struct iwl_time_quota_cmd cmd = {}; 164 struct iwl_time_quota_cmd cmd = {};
@@ -196,6 +226,8 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
196 /* Give the remainder of the session to the first binding */ 226 /* Give the remainder of the session to the first binding */
197 le32_add_cpu(&cmd.quotas[0].quota, quota_rem); 227 le32_add_cpu(&cmd.quotas[0].quota, quota_rem);
198 228
229 iwl_mvm_adjust_quota_for_noa(mvm, &cmd);
230
199 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC, 231 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC,
200 sizeof(cmd), &cmd); 232 sizeof(cmd), &cmd);
201 if (ret) 233 if (ret)
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 4ffaa3fa153f..a0b4cc8d9c3b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -82,13 +82,24 @@ static const u8 ant_toggle_lookup[] = {
82 [ANT_ABC] = ANT_ABC, 82 [ANT_ABC] = ANT_ABC,
83}; 83};
84 84
85#define IWL_DECLARE_RATE_INFO(r, s, rp, rn) \ 85#define IWL_DECLARE_RATE_INFO(r, s, rp, rn) \
86 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ 86 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
87 IWL_RATE_SISO_##s##M_PLCP, \ 87 IWL_RATE_HT_SISO_MCS_##s##_PLCP, \
88 IWL_RATE_MIMO2_##s##M_PLCP,\ 88 IWL_RATE_HT_MIMO2_MCS_##s##_PLCP, \
89 IWL_RATE_##rp##M_INDEX, \ 89 IWL_RATE_VHT_SISO_MCS_##s##_PLCP, \
90 IWL_RATE_VHT_MIMO2_MCS_##s##_PLCP,\
91 IWL_RATE_##rp##M_INDEX, \
90 IWL_RATE_##rn##M_INDEX } 92 IWL_RATE_##rn##M_INDEX }
91 93
94#define IWL_DECLARE_MCS_RATE(s) \
95 [IWL_RATE_MCS_##s##_INDEX] = { IWL_RATE_INVM_PLCP, \
96 IWL_RATE_HT_SISO_MCS_##s##_PLCP, \
97 IWL_RATE_HT_MIMO2_MCS_##s##_PLCP, \
98 IWL_RATE_VHT_SISO_MCS_##s##_PLCP, \
99 IWL_RATE_VHT_MIMO2_MCS_##s##_PLCP, \
100 IWL_RATE_INVM_INDEX, \
101 IWL_RATE_INVM_INDEX }
102
92/* 103/*
93 * Parameter order: 104 * Parameter order:
94 * rate, ht rate, prev rate, next rate 105 * rate, ht rate, prev rate, next rate
@@ -102,16 +113,17 @@ static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = {
102 IWL_DECLARE_RATE_INFO(2, INV, 1, 5), /* 2mbps */ 113 IWL_DECLARE_RATE_INFO(2, INV, 1, 5), /* 2mbps */
103 IWL_DECLARE_RATE_INFO(5, INV, 2, 11), /*5.5mbps */ 114 IWL_DECLARE_RATE_INFO(5, INV, 2, 11), /*5.5mbps */
104 IWL_DECLARE_RATE_INFO(11, INV, 9, 12), /* 11mbps */ 115 IWL_DECLARE_RATE_INFO(11, INV, 9, 12), /* 11mbps */
105 IWL_DECLARE_RATE_INFO(6, 6, 5, 11), /* 6mbps */ 116 IWL_DECLARE_RATE_INFO(6, 0, 5, 11), /* 6mbps ; MCS 0 */
106 IWL_DECLARE_RATE_INFO(9, 6, 6, 11), /* 9mbps */ 117 IWL_DECLARE_RATE_INFO(9, INV, 6, 11), /* 9mbps */
107 IWL_DECLARE_RATE_INFO(12, 12, 11, 18), /* 12mbps */ 118 IWL_DECLARE_RATE_INFO(12, 1, 11, 18), /* 12mbps ; MCS 1 */
108 IWL_DECLARE_RATE_INFO(18, 18, 12, 24), /* 18mbps */ 119 IWL_DECLARE_RATE_INFO(18, 2, 12, 24), /* 18mbps ; MCS 2 */
109 IWL_DECLARE_RATE_INFO(24, 24, 18, 36), /* 24mbps */ 120 IWL_DECLARE_RATE_INFO(24, 3, 18, 36), /* 24mbps ; MCS 3 */
110 IWL_DECLARE_RATE_INFO(36, 36, 24, 48), /* 36mbps */ 121 IWL_DECLARE_RATE_INFO(36, 4, 24, 48), /* 36mbps ; MCS 4 */
111 IWL_DECLARE_RATE_INFO(48, 48, 36, 54), /* 48mbps */ 122 IWL_DECLARE_RATE_INFO(48, 5, 36, 54), /* 48mbps ; MCS 5 */
112 IWL_DECLARE_RATE_INFO(54, 54, 48, INV), /* 54mbps */ 123 IWL_DECLARE_RATE_INFO(54, 6, 48, INV), /* 54mbps ; MCS 6 */
113 IWL_DECLARE_RATE_INFO(60, 60, 48, INV), /* 60mbps */ 124 IWL_DECLARE_MCS_RATE(7), /* MCS 7 */
114 /* FIXME:RS: ^^ should be INV (legacy) */ 125 IWL_DECLARE_MCS_RATE(8), /* MCS 8 */
126 IWL_DECLARE_MCS_RATE(9), /* MCS 9 */
115}; 127};
116 128
117static inline u8 rs_extract_rate(u32 rate_n_flags) 129static inline u8 rs_extract_rate(u32 rate_n_flags)
@@ -124,26 +136,30 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
124{ 136{
125 int idx = 0; 137 int idx = 0;
126 138
127 /* HT rate format */
128 if (rate_n_flags & RATE_MCS_HT_MSK) { 139 if (rate_n_flags & RATE_MCS_HT_MSK) {
129 idx = rs_extract_rate(rate_n_flags); 140 idx = rate_n_flags & RATE_HT_MCS_RATE_CODE_MSK;
130 141 idx += IWL_RATE_MCS_0_INDEX;
131 WARN_ON_ONCE(idx >= IWL_RATE_MIMO3_6M_PLCP);
132 if (idx >= IWL_RATE_MIMO2_6M_PLCP)
133 idx = idx - IWL_RATE_MIMO2_6M_PLCP;
134 142
135 idx += IWL_FIRST_OFDM_RATE; 143 /* skip 9M not supported in HT*/
136 /* skip 9M not supported in ht*/
137 if (idx >= IWL_RATE_9M_INDEX) 144 if (idx >= IWL_RATE_9M_INDEX)
138 idx += 1; 145 idx += 1;
139 if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE)) 146 if ((idx >= IWL_FIRST_HT_RATE) && (idx <= IWL_LAST_HT_RATE))
140 return idx; 147 return idx;
148 } else if (rate_n_flags & RATE_MCS_VHT_MSK) {
149 idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
150 idx += IWL_RATE_MCS_0_INDEX;
141 151
142 /* legacy rate format, search for match in table */ 152 /* skip 9M not supported in VHT*/
153 if (idx >= IWL_RATE_9M_INDEX)
154 idx++;
155 if ((idx >= IWL_FIRST_VHT_RATE) && (idx <= IWL_LAST_VHT_RATE))
156 return idx;
143 } else { 157 } else {
158 /* legacy rate format, search for match in table */
159
160 u8 legacy_rate = rs_extract_rate(rate_n_flags);
144 for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) 161 for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
145 if (iwl_rates[idx].plcp == 162 if (iwl_rates[idx].plcp == legacy_rate)
146 rs_extract_rate(rate_n_flags))
147 return idx; 163 return idx;
148 } 164 }
149 165
@@ -155,6 +171,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
155 struct ieee80211_sta *sta, 171 struct ieee80211_sta *sta,
156 struct iwl_lq_sta *lq_sta); 172 struct iwl_lq_sta *lq_sta);
157static void rs_fill_link_cmd(struct iwl_mvm *mvm, 173static void rs_fill_link_cmd(struct iwl_mvm *mvm,
174 struct ieee80211_sta *sta,
158 struct iwl_lq_sta *lq_sta, u32 rate_n_flags); 175 struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
159static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search); 176static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);
160 177
@@ -180,35 +197,52 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
180 */ 197 */
181 198
182static s32 expected_tpt_legacy[IWL_RATE_COUNT] = { 199static s32 expected_tpt_legacy[IWL_RATE_COUNT] = {
183 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0 200 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0, 0, 0
184}; 201};
185 202
186static s32 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = { 203/* Expected TpT tables. 4 indexes:
187 {0, 0, 0, 0, 42, 0, 76, 102, 124, 159, 183, 193, 202}, /* Norm */ 204 * 0 - NGI, 1 - SGI, 2 - AGG+NGI, 3 - AGG+SGI
188 {0, 0, 0, 0, 46, 0, 82, 110, 132, 168, 192, 202, 210}, /* SGI */ 205 */
189 {0, 0, 0, 0, 47, 0, 91, 133, 171, 242, 305, 334, 362}, /* AGG */ 206static s32 expected_tpt_siso_20MHz[4][IWL_RATE_COUNT] = {
190 {0, 0, 0, 0, 52, 0, 101, 145, 187, 264, 330, 361, 390}, /* AGG+SGI */ 207 {0, 0, 0, 0, 42, 0, 76, 102, 124, 159, 183, 193, 202, 216, 0},
208 {0, 0, 0, 0, 46, 0, 82, 110, 132, 168, 192, 202, 210, 225, 0},
209 {0, 0, 0, 0, 49, 0, 97, 145, 192, 285, 375, 420, 464, 551, 0},
210 {0, 0, 0, 0, 54, 0, 108, 160, 213, 315, 415, 465, 513, 608, 0},
191}; 211};
192 212
193static s32 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = { 213static s32 expected_tpt_siso_40MHz[4][IWL_RATE_COUNT] = {
194 {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257}, /* Norm */ 214 {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257, 269, 275},
195 {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264}, /* SGI */ 215 {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264, 275, 280},
196 {0, 0, 0, 0, 94, 0, 177, 249, 313, 423, 512, 550, 586}, /* AGG */ 216 {0, 0, 0, 0, 101, 0, 199, 295, 389, 570, 744, 828, 911, 1070, 1173},
197 {0, 0, 0, 0, 104, 0, 193, 270, 338, 454, 545, 584, 620}, /* AGG+SGI */ 217 {0, 0, 0, 0, 112, 0, 220, 326, 429, 629, 819, 912, 1000, 1173, 1284},
218};
219
220static s32 expected_tpt_siso_80MHz[4][IWL_RATE_COUNT] = {
221 {0, 0, 0, 0, 130, 0, 191, 223, 244, 273, 288, 294, 298, 305, 308},
222 {0, 0, 0, 0, 138, 0, 200, 231, 251, 279, 293, 298, 302, 308, 312},
223 {0, 0, 0, 0, 217, 0, 429, 634, 834, 1220, 1585, 1760, 1931, 2258, 2466},
224 {0, 0, 0, 0, 241, 0, 475, 701, 921, 1343, 1741, 1931, 2117, 2468, 2691},
198}; 225};
199 226
200static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = { 227static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = {
201 {0, 0, 0, 0, 74, 0, 123, 155, 179, 214, 236, 244, 251}, /* Norm */ 228 {0, 0, 0, 0, 74, 0, 123, 155, 179, 213, 235, 243, 250, 261, 0},
202 {0, 0, 0, 0, 81, 0, 131, 164, 188, 223, 243, 251, 257}, /* SGI */ 229 {0, 0, 0, 0, 81, 0, 131, 164, 187, 221, 242, 250, 256, 267, 0},
203 {0, 0, 0, 0, 89, 0, 167, 235, 296, 402, 488, 526, 560}, /* AGG */ 230 {0, 0, 0, 0, 98, 0, 193, 286, 375, 550, 718, 799, 878, 1032, 0},
204 {0, 0, 0, 0, 97, 0, 182, 255, 320, 431, 520, 558, 593}, /* AGG+SGI*/ 231 {0, 0, 0, 0, 109, 0, 214, 316, 414, 607, 790, 879, 965, 1132, 0},
205}; 232};
206 233
207static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = { 234static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = {
208 {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289}, /* Norm */ 235 {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289, 296, 300},
209 {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293}, /* SGI */ 236 {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293, 300, 303},
210 {0, 0, 0, 0, 171, 0, 305, 410, 496, 634, 731, 771, 805}, /* AGG */ 237 {0, 0, 0, 0, 200, 0, 390, 571, 741, 1067, 1365, 1505, 1640, 1894, 2053},
211 {0, 0, 0, 0, 186, 0, 329, 439, 527, 667, 764, 803, 838}, /* AGG+SGI */ 238 {0, 0, 0, 0, 221, 0, 430, 630, 816, 1169, 1490, 1641, 1784, 2053, 2221},
239};
240
241static s32 expected_tpt_mimo2_80MHz[4][IWL_RATE_COUNT] = {
242 {0, 0, 0, 0, 182, 0, 240, 264, 278, 299, 308, 311, 313, 317, 319},
243 {0, 0, 0, 0, 190, 0, 247, 269, 282, 302, 310, 313, 315, 319, 320},
244 {0, 0, 0, 0, 428, 0, 833, 1215, 1577, 2254, 2863, 3147, 3418, 3913, 4219},
245 {0, 0, 0, 0, 474, 0, 920, 1338, 1732, 2464, 3116, 3418, 3705, 4225, 4545},
212}; 246};
213 247
214/* mbps, mcs */ 248/* mbps, mcs */
@@ -263,7 +297,7 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm,
263 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); 297 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
264 298
265 if (lq_sta->dbg_fixed_rate) { 299 if (lq_sta->dbg_fixed_rate) {
266 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); 300 rs_fill_link_cmd(NULL, NULL, lq_sta, lq_sta->dbg_fixed_rate);
267 iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false); 301 iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
268 } 302 }
269} 303}
@@ -275,17 +309,6 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
275{ 309{
276 int ret = -EAGAIN; 310 int ret = -EAGAIN;
277 311
278 /*
279 * Don't create TX aggregation sessions when in high
280 * BT traffic, as they would just be disrupted by BT.
281 */
282 if (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >= 2) {
283 IWL_DEBUG_COEX(mvm, "BT traffic (%d), no aggregation allowed\n",
284 BT_MBOX_MSG(&mvm->last_bt_notif,
285 3, TRAFFIC_LOAD));
286 return ret;
287 }
288
289 IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n", 312 IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n",
290 sta->addr, tid); 313 sta->addr, tid);
291 ret = ieee80211_start_tx_ba_session(sta, tid, 5000); 314 ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
@@ -416,49 +439,54 @@ static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
416 */ 439 */
417/* FIXME:RS:remove this function and put the flags statically in the table */ 440/* FIXME:RS:remove this function and put the flags statically in the table */
418static u32 rate_n_flags_from_tbl(struct iwl_mvm *mvm, 441static u32 rate_n_flags_from_tbl(struct iwl_mvm *mvm,
419 struct iwl_scale_tbl_info *tbl, 442 struct iwl_scale_tbl_info *tbl, int index)
420 int index, u8 use_green)
421{ 443{
422 u32 rate_n_flags = 0; 444 u32 rate_n_flags = 0;
423 445
446 rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) &
447 RATE_MCS_ANT_ABC_MSK);
448
424 if (is_legacy(tbl->lq_type)) { 449 if (is_legacy(tbl->lq_type)) {
425 rate_n_flags = iwl_rates[index].plcp; 450 rate_n_flags |= iwl_rates[index].plcp;
426 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) 451 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
427 rate_n_flags |= RATE_MCS_CCK_MSK; 452 rate_n_flags |= RATE_MCS_CCK_MSK;
428 } else if (is_Ht(tbl->lq_type)) { 453 return rate_n_flags;
429 if (index > IWL_LAST_OFDM_RATE) { 454 }
455
456 if (is_ht(tbl->lq_type)) {
457 if (index < IWL_FIRST_HT_RATE || index > IWL_LAST_HT_RATE) {
430 IWL_ERR(mvm, "Invalid HT rate index %d\n", index); 458 IWL_ERR(mvm, "Invalid HT rate index %d\n", index);
431 index = IWL_LAST_OFDM_RATE; 459 index = IWL_LAST_HT_RATE;
432 } 460 }
433 rate_n_flags = RATE_MCS_HT_MSK; 461 rate_n_flags |= RATE_MCS_HT_MSK;
434 462
435 if (is_siso(tbl->lq_type)) 463 if (is_ht_siso(tbl->lq_type))
436 rate_n_flags |= iwl_rates[index].plcp_siso; 464 rate_n_flags |= iwl_rates[index].plcp_ht_siso;
437 else if (is_mimo2(tbl->lq_type)) 465 else if (is_ht_mimo2(tbl->lq_type))
438 rate_n_flags |= iwl_rates[index].plcp_mimo2; 466 rate_n_flags |= iwl_rates[index].plcp_ht_mimo2;
439 else 467 else
440 WARN_ON_ONCE(1); 468 WARN_ON_ONCE(1);
469 } else if (is_vht(tbl->lq_type)) {
470 if (index < IWL_FIRST_VHT_RATE || index > IWL_LAST_VHT_RATE) {
471 IWL_ERR(mvm, "Invalid VHT rate index %d\n", index);
472 index = IWL_LAST_VHT_RATE;
473 }
474 rate_n_flags |= RATE_MCS_VHT_MSK;
475 if (is_vht_siso(tbl->lq_type))
476 rate_n_flags |= iwl_rates[index].plcp_vht_siso;
477 else if (is_vht_mimo2(tbl->lq_type))
478 rate_n_flags |= iwl_rates[index].plcp_vht_mimo2;
479 else
480 WARN_ON_ONCE(1);
481
441 } else { 482 } else {
442 IWL_ERR(mvm, "Invalid tbl->lq_type %d\n", tbl->lq_type); 483 IWL_ERR(mvm, "Invalid tbl->lq_type %d\n", tbl->lq_type);
443 } 484 }
444 485
445 rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) & 486 rate_n_flags |= tbl->bw;
446 RATE_MCS_ANT_ABC_MSK); 487 if (tbl->is_SGI)
447 488 rate_n_flags |= RATE_MCS_SGI_MSK;
448 if (is_Ht(tbl->lq_type)) { 489
449 if (tbl->is_ht40)
450 rate_n_flags |= RATE_MCS_CHAN_WIDTH_40;
451 if (tbl->is_SGI)
452 rate_n_flags |= RATE_MCS_SGI_MSK;
453
454 if (use_green) {
455 rate_n_flags |= RATE_HT_MCS_GF_MSK;
456 if (is_siso(tbl->lq_type) && tbl->is_SGI) {
457 rate_n_flags &= ~RATE_MCS_SGI_MSK;
458 IWL_ERR(mvm, "GF was set with SGI:SISO\n");
459 }
460 }
461 }
462 return rate_n_flags; 490 return rate_n_flags;
463} 491}
464 492
@@ -473,7 +501,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
473{ 501{
474 u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK); 502 u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK);
475 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags); 503 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);
476 u8 mcs; 504 u8 nss;
477 505
478 memset(tbl, 0, offsetof(struct iwl_scale_tbl_info, win)); 506 memset(tbl, 0, offsetof(struct iwl_scale_tbl_info, win));
479 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); 507 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
@@ -483,41 +511,62 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
483 return -EINVAL; 511 return -EINVAL;
484 } 512 }
485 tbl->is_SGI = 0; /* default legacy setup */ 513 tbl->is_SGI = 0; /* default legacy setup */
486 tbl->is_ht40 = 0; 514 tbl->bw = 0;
487 tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS); 515 tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
488 tbl->lq_type = LQ_NONE; 516 tbl->lq_type = LQ_NONE;
489 tbl->max_search = IWL_MAX_SEARCH; 517 tbl->max_search = IWL_MAX_SEARCH;
490 518
491 /* legacy rate format */ 519 /* Legacy */
492 if (!(rate_n_flags & RATE_MCS_HT_MSK)) { 520 if (!(rate_n_flags & RATE_MCS_HT_MSK) &&
521 !(rate_n_flags & RATE_MCS_VHT_MSK)) {
493 if (num_of_ant == 1) { 522 if (num_of_ant == 1) {
494 if (band == IEEE80211_BAND_5GHZ) 523 if (band == IEEE80211_BAND_5GHZ)
495 tbl->lq_type = LQ_A; 524 tbl->lq_type = LQ_LEGACY_A;
496 else 525 else
497 tbl->lq_type = LQ_G; 526 tbl->lq_type = LQ_LEGACY_G;
498 } 527 }
499 /* HT rate format */ 528
500 } else { 529 return 0;
501 if (rate_n_flags & RATE_MCS_SGI_MSK) 530 }
502 tbl->is_SGI = 1; 531
503 532 /* HT or VHT */
504 if (rate_n_flags & RATE_MCS_CHAN_WIDTH_40) /* TODO */ 533 if (rate_n_flags & RATE_MCS_SGI_MSK)
505 tbl->is_ht40 = 1; 534 tbl->is_SGI = 1;
506 535
507 mcs = rs_extract_rate(rate_n_flags); 536 tbl->bw = rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK;
508 537
509 /* SISO */ 538 if (rate_n_flags & RATE_MCS_HT_MSK) {
510 if (mcs <= IWL_RATE_SISO_60M_PLCP) { 539 nss = ((rate_n_flags & RATE_HT_MCS_NSS_MSK) >>
511 if (num_of_ant == 1) 540 RATE_HT_MCS_NSS_POS) + 1;
512 tbl->lq_type = LQ_SISO; /*else NONE*/ 541
513 /* MIMO2 */ 542 if (nss == 1) {
514 } else if (mcs <= IWL_RATE_MIMO2_60M_PLCP) { 543 tbl->lq_type = LQ_HT_SISO;
515 if (num_of_ant == 2) 544 WARN_ON_ONCE(num_of_ant != 1);
516 tbl->lq_type = LQ_MIMO2; 545 } else if (nss == 2) {
546 tbl->lq_type = LQ_HT_MIMO2;
547 WARN_ON_ONCE(num_of_ant != 2);
548 } else {
549 WARN_ON_ONCE(1);
550 }
551 } else if (rate_n_flags & RATE_MCS_VHT_MSK) {
552 nss = ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
553 RATE_VHT_MCS_NSS_POS) + 1;
554
555 if (nss == 1) {
556 tbl->lq_type = LQ_VHT_SISO;
557 WARN_ON_ONCE(num_of_ant != 1);
558 } else if (nss == 2) {
559 tbl->lq_type = LQ_VHT_MIMO2;
560 WARN_ON_ONCE(num_of_ant != 2);
517 } else { 561 } else {
518 WARN_ON_ONCE(num_of_ant == 3); 562 WARN_ON_ONCE(1);
519 } 563 }
520 } 564 }
565
566 WARN_ON_ONCE(tbl->bw == RATE_MCS_CHAN_WIDTH_160);
567 WARN_ON_ONCE(tbl->bw == RATE_MCS_CHAN_WIDTH_80 &&
568 !is_vht(tbl->lq_type));
569
521 return 0; 570 return 0;
522} 571}
523 572
@@ -550,22 +599,6 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
550} 599}
551 600
552/** 601/**
553 * Green-field mode is valid if the station supports it and
554 * there are no non-GF stations present in the BSS.
555 */
556static bool rs_use_green(struct ieee80211_sta *sta)
557{
558 /*
559 * There's a bug somewhere in this code that causes the
560 * scaling to get stuck because GF+SGI can't be combined
561 * in SISO rates. Until we find that bug, disable GF, it
562 * has only limited benefit and we still interoperate with
563 * GF APs since we can always receive GF transmissions.
564 */
565 return false;
566}
567
568/**
569 * rs_get_supported_rates - get the available rates 602 * rs_get_supported_rates - get the available rates
570 * 603 *
571 * if management frame or broadcast frame only return 604 * if management frame or broadcast frame only return
@@ -576,16 +609,15 @@ static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
576 struct ieee80211_hdr *hdr, 609 struct ieee80211_hdr *hdr,
577 enum iwl_table_type rate_type) 610 enum iwl_table_type rate_type)
578{ 611{
579 if (is_legacy(rate_type)) { 612 if (is_legacy(rate_type))
580 return lq_sta->active_legacy_rate; 613 return lq_sta->active_legacy_rate;
581 } else { 614 else if (is_siso(rate_type))
582 if (is_siso(rate_type)) 615 return lq_sta->active_siso_rate;
583 return lq_sta->active_siso_rate; 616 else if (is_mimo2(rate_type))
584 else { 617 return lq_sta->active_mimo2_rate;
585 WARN_ON_ONCE(!is_mimo2(rate_type)); 618
586 return lq_sta->active_mimo2_rate; 619 WARN_ON_ONCE(1);
587 } 620 return 0;
588 }
589} 621}
590 622
591static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask, 623static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
@@ -652,7 +684,6 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
652 u16 rate_mask; 684 u16 rate_mask;
653 u16 high_low; 685 u16 high_low;
654 u8 switch_to_legacy = 0; 686 u8 switch_to_legacy = 0;
655 u8 is_green = lq_sta->is_green;
656 struct iwl_mvm *mvm = lq_sta->drv; 687 struct iwl_mvm *mvm = lq_sta->drv;
657 688
658 /* check if we need to switch from HT to legacy rates. 689 /* check if we need to switch from HT to legacy rates.
@@ -662,15 +693,15 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
662 switch_to_legacy = 1; 693 switch_to_legacy = 1;
663 scale_index = rs_ht_to_legacy[scale_index]; 694 scale_index = rs_ht_to_legacy[scale_index];
664 if (lq_sta->band == IEEE80211_BAND_5GHZ) 695 if (lq_sta->band == IEEE80211_BAND_5GHZ)
665 tbl->lq_type = LQ_A; 696 tbl->lq_type = LQ_LEGACY_A;
666 else 697 else
667 tbl->lq_type = LQ_G; 698 tbl->lq_type = LQ_LEGACY_G;
668 699
669 if (num_of_ant(tbl->ant_type) > 1) 700 if (num_of_ant(tbl->ant_type) > 1)
670 tbl->ant_type = 701 tbl->ant_type =
671 first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); 702 first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
672 703
673 tbl->is_ht40 = 0; 704 tbl->bw = 0;
674 tbl->is_SGI = 0; 705 tbl->is_SGI = 0;
675 tbl->max_search = IWL_MAX_SEARCH; 706 tbl->max_search = IWL_MAX_SEARCH;
676 } 707 }
@@ -701,7 +732,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
701 low = scale_index; 732 low = scale_index;
702 733
703out: 734out:
704 return rate_n_flags_from_tbl(lq_sta->drv, tbl, low, is_green); 735 return rate_n_flags_from_tbl(lq_sta->drv, tbl, low);
705} 736}
706 737
707/* 738/*
@@ -714,6 +745,18 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a,
714 (a->is_SGI == b->is_SGI); 745 (a->is_SGI == b->is_SGI);
715} 746}
716 747
748static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags)
749{
750 if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
751 return RATE_MCS_CHAN_WIDTH_40;
752 else if (flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
753 return RATE_MCS_CHAN_WIDTH_80;
754 else if (flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
755 return RATE_MCS_CHAN_WIDTH_160;
756
757 return RATE_MCS_CHAN_WIDTH_20;
758}
759
717/* 760/*
718 * mac80211 sends us Tx status 761 * mac80211 sends us Tx status
719 */ 762 */
@@ -783,16 +826,23 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
783 */ 826 */
784 if (info->band == IEEE80211_BAND_2GHZ) 827 if (info->band == IEEE80211_BAND_2GHZ)
785 mac_index += IWL_FIRST_OFDM_RATE; 828 mac_index += IWL_FIRST_OFDM_RATE;
829 } else if (mac_flags & IEEE80211_TX_RC_VHT_MCS) {
830 mac_index &= RATE_VHT_MCS_RATE_CODE_MSK;
831 if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE))
832 mac_index++;
786 } 833 }
834
787 /* Here we actually compare this rate to the latest LQ command */ 835 /* Here we actually compare this rate to the latest LQ command */
788 if ((mac_index < 0) || 836 if ((mac_index < 0) ||
789 (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) || 837 (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
790 (tbl_type.is_ht40 != !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) || 838 (tbl_type.bw != rs_ch_width_from_mac_flags(mac_flags)) ||
791 (tbl_type.ant_type != info->status.antenna) || 839 (tbl_type.ant_type != info->status.antenna) ||
792 (!!(tx_rate & RATE_MCS_HT_MSK) != 840 (!!(tx_rate & RATE_MCS_HT_MSK) !=
793 !!(mac_flags & IEEE80211_TX_RC_MCS)) || 841 !!(mac_flags & IEEE80211_TX_RC_MCS)) ||
842 (!!(tx_rate & RATE_MCS_VHT_MSK) !=
843 !!(mac_flags & IEEE80211_TX_RC_VHT_MCS)) ||
794 (!!(tx_rate & RATE_HT_MCS_GF_MSK) != 844 (!!(tx_rate & RATE_HT_MCS_GF_MSK) !=
795 !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) || 845 !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
796 (rs_index != mac_index)) { 846 (rs_index != mac_index)) {
797 IWL_DEBUG_RATE(mvm, 847 IWL_DEBUG_RATE(mvm,
798 "initial rate %d does not match %d (0x%x)\n", 848 "initial rate %d does not match %d (0x%x)\n",
@@ -947,7 +997,8 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
947 s32 (*ht_tbl_pointer)[IWL_RATE_COUNT]; 997 s32 (*ht_tbl_pointer)[IWL_RATE_COUNT];
948 998
949 /* Check for invalid LQ type */ 999 /* Check for invalid LQ type */
950 if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_Ht(tbl->lq_type))) { 1000 if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_ht(tbl->lq_type) &&
1001 !(is_vht(tbl->lq_type)))) {
951 tbl->expected_tpt = expected_tpt_legacy; 1002 tbl->expected_tpt = expected_tpt_legacy;
952 return; 1003 return;
953 } 1004 }
@@ -958,18 +1009,40 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
958 return; 1009 return;
959 } 1010 }
960 1011
1012 ht_tbl_pointer = expected_tpt_mimo2_20MHz;
961 /* Choose among many HT tables depending on number of streams 1013 /* Choose among many HT tables depending on number of streams
962 * (SISO/MIMO2), channel width (20/40), SGI, and aggregation 1014 * (SISO/MIMO2), channel width (20/40/80), SGI, and aggregation
963 * status */ 1015 * status */
964 if (is_siso(tbl->lq_type) && !tbl->is_ht40) 1016 if (is_siso(tbl->lq_type)) {
965 ht_tbl_pointer = expected_tpt_siso20MHz; 1017 switch (tbl->bw) {
966 else if (is_siso(tbl->lq_type)) 1018 case RATE_MCS_CHAN_WIDTH_20:
967 ht_tbl_pointer = expected_tpt_siso40MHz; 1019 ht_tbl_pointer = expected_tpt_siso_20MHz;
968 else if (is_mimo2(tbl->lq_type) && !tbl->is_ht40) 1020 break;
969 ht_tbl_pointer = expected_tpt_mimo2_20MHz; 1021 case RATE_MCS_CHAN_WIDTH_40:
970 else { 1022 ht_tbl_pointer = expected_tpt_siso_40MHz;
971 WARN_ON_ONCE(!is_mimo2(tbl->lq_type)); 1023 break;
972 ht_tbl_pointer = expected_tpt_mimo2_40MHz; 1024 case RATE_MCS_CHAN_WIDTH_80:
1025 ht_tbl_pointer = expected_tpt_siso_80MHz;
1026 break;
1027 default:
1028 WARN_ON_ONCE(1);
1029 }
1030 } else if (is_mimo2(tbl->lq_type)) {
1031 switch (tbl->bw) {
1032 case RATE_MCS_CHAN_WIDTH_20:
1033 ht_tbl_pointer = expected_tpt_mimo2_20MHz;
1034 break;
1035 case RATE_MCS_CHAN_WIDTH_40:
1036 ht_tbl_pointer = expected_tpt_mimo2_40MHz;
1037 break;
1038 case RATE_MCS_CHAN_WIDTH_80:
1039 ht_tbl_pointer = expected_tpt_mimo2_80MHz;
1040 break;
1041 default:
1042 WARN_ON_ONCE(1);
1043 }
1044 } else {
1045 WARN_ON_ONCE(1);
973 } 1046 }
974 1047
975 if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */ 1048 if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */
@@ -1084,9 +1157,47 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1084 return new_rate; 1157 return new_rate;
1085} 1158}
1086 1159
1087static bool iwl_is_ht40_tx_allowed(struct ieee80211_sta *sta) 1160/* Move to the next action and wrap around to the first action in case
1161 * we're at the last action. Assumes actions start at 0.
1162 */
1163static inline void rs_move_next_action(struct iwl_scale_tbl_info *tbl,
1164 u8 last_action)
1165{
1166 BUILD_BUG_ON(IWL_LEGACY_FIRST_ACTION != 0);
1167 BUILD_BUG_ON(IWL_SISO_FIRST_ACTION != 0);
1168 BUILD_BUG_ON(IWL_MIMO2_FIRST_ACTION != 0);
1169
1170 tbl->action = (tbl->action + 1) % (last_action + 1);
1171}
1172
1173static void rs_set_bw_from_sta(struct iwl_scale_tbl_info *tbl,
1174 struct ieee80211_sta *sta)
1175{
1176 if (sta->bandwidth >= IEEE80211_STA_RX_BW_80)
1177 tbl->bw = RATE_MCS_CHAN_WIDTH_80;
1178 else if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
1179 tbl->bw = RATE_MCS_CHAN_WIDTH_40;
1180 else
1181 tbl->bw = RATE_MCS_CHAN_WIDTH_20;
1182}
1183
1184static bool rs_sgi_allowed(struct iwl_scale_tbl_info *tbl,
1185 struct ieee80211_sta *sta)
1088{ 1186{
1089 return sta->bandwidth >= IEEE80211_STA_RX_BW_40; 1187 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1188 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
1189
1190 if (is_ht20(tbl) && (ht_cap->cap &
1191 IEEE80211_HT_CAP_SGI_20))
1192 return true;
1193 if (is_ht40(tbl) && (ht_cap->cap &
1194 IEEE80211_HT_CAP_SGI_40))
1195 return true;
1196 if (is_ht80(tbl) && (vht_cap->cap &
1197 IEEE80211_VHT_CAP_SHORT_GI_80))
1198 return true;
1199
1200 return false;
1090} 1201}
1091 1202
1092/* 1203/*
@@ -1099,7 +1210,6 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm,
1099{ 1210{
1100 u16 rate_mask; 1211 u16 rate_mask;
1101 s32 rate; 1212 s32 rate;
1102 s8 is_green = lq_sta->is_green;
1103 1213
1104 if (!sta->ht_cap.ht_supported) 1214 if (!sta->ht_cap.ht_supported)
1105 return -1; 1215 return -1;
@@ -1113,16 +1223,12 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm,
1113 1223
1114 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n"); 1224 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n");
1115 1225
1116 tbl->lq_type = LQ_MIMO2; 1226 tbl->lq_type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2;
1117 tbl->action = 0; 1227 tbl->action = 0;
1118 tbl->max_search = IWL_MAX_SEARCH; 1228 tbl->max_search = IWL_MAX_SEARCH;
1119 rate_mask = lq_sta->active_mimo2_rate; 1229 rate_mask = lq_sta->active_mimo2_rate;
1120 1230
1121 if (iwl_is_ht40_tx_allowed(sta)) 1231 rs_set_bw_from_sta(tbl, sta);
1122 tbl->is_ht40 = 1;
1123 else
1124 tbl->is_ht40 = 0;
1125
1126 rs_set_expected_tpt_table(lq_sta, tbl); 1232 rs_set_expected_tpt_table(lq_sta, tbl);
1127 1233
1128 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index); 1234 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
@@ -1134,10 +1240,10 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm,
1134 rate, rate_mask); 1240 rate, rate_mask);
1135 return -1; 1241 return -1;
1136 } 1242 }
1137 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate, is_green); 1243 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate);
1138 1244
1139 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index is green %X\n", 1245 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index\n",
1140 tbl->current_rate, is_green); 1246 tbl->current_rate);
1141 return 0; 1247 return 0;
1142} 1248}
1143 1249
@@ -1150,7 +1256,6 @@ static int rs_switch_to_siso(struct iwl_mvm *mvm,
1150 struct iwl_scale_tbl_info *tbl, int index) 1256 struct iwl_scale_tbl_info *tbl, int index)
1151{ 1257{
1152 u16 rate_mask; 1258 u16 rate_mask;
1153 u8 is_green = lq_sta->is_green;
1154 s32 rate; 1259 s32 rate;
1155 1260
1156 if (!sta->ht_cap.ht_supported) 1261 if (!sta->ht_cap.ht_supported)
@@ -1158,19 +1263,12 @@ static int rs_switch_to_siso(struct iwl_mvm *mvm,
1158 1263
1159 IWL_DEBUG_RATE(mvm, "LQ: try to switch to SISO\n"); 1264 IWL_DEBUG_RATE(mvm, "LQ: try to switch to SISO\n");
1160 1265
1161 tbl->lq_type = LQ_SISO; 1266 tbl->lq_type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO;
1162 tbl->action = 0; 1267 tbl->action = 0;
1163 tbl->max_search = IWL_MAX_SEARCH; 1268 tbl->max_search = IWL_MAX_SEARCH;
1164 rate_mask = lq_sta->active_siso_rate; 1269 rate_mask = lq_sta->active_siso_rate;
1165 1270
1166 if (iwl_is_ht40_tx_allowed(sta)) 1271 rs_set_bw_from_sta(tbl, sta);
1167 tbl->is_ht40 = 1;
1168 else
1169 tbl->is_ht40 = 0;
1170
1171 if (is_green)
1172 tbl->is_SGI = 0; /*11n spec: no SGI in SISO+Greenfield*/
1173
1174 rs_set_expected_tpt_table(lq_sta, tbl); 1272 rs_set_expected_tpt_table(lq_sta, tbl);
1175 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index); 1273 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
1176 1274
@@ -1181,9 +1279,9 @@ static int rs_switch_to_siso(struct iwl_mvm *mvm,
1181 rate, rate_mask); 1279 rate, rate_mask);
1182 return -1; 1280 return -1;
1183 } 1281 }
1184 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate, is_green); 1282 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate);
1185 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index is green %X\n", 1283 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index\n",
1186 tbl->current_rate, is_green); 1284 tbl->current_rate);
1187 return 0; 1285 return 0;
1188} 1286}
1189 1287
@@ -1211,14 +1309,10 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm,
1211 while (1) { 1309 while (1) {
1212 lq_sta->action_counter++; 1310 lq_sta->action_counter++;
1213 switch (tbl->action) { 1311 switch (tbl->action) {
1214 case IWL_LEGACY_SWITCH_ANTENNA1: 1312 case IWL_LEGACY_SWITCH_ANTENNA:
1215 case IWL_LEGACY_SWITCH_ANTENNA2:
1216 IWL_DEBUG_RATE(mvm, "LQ: Legacy toggle Antenna\n"); 1313 IWL_DEBUG_RATE(mvm, "LQ: Legacy toggle Antenna\n");
1217 1314
1218 if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 && 1315 if (tx_chains_num <= 1)
1219 tx_chains_num <= 1) ||
1220 (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 &&
1221 tx_chains_num <= 2))
1222 break; 1316 break;
1223 1317
1224 /* Don't change antenna if success has been great */ 1318 /* Don't change antenna if success has been great */
@@ -1273,9 +1367,7 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm,
1273 default: 1367 default:
1274 WARN_ON_ONCE(1); 1368 WARN_ON_ONCE(1);
1275 } 1369 }
1276 tbl->action++; 1370 rs_move_next_action(tbl, IWL_LEGACY_LAST_ACTION);
1277 if (tbl->action > IWL_LEGACY_SWITCH_MIMO2)
1278 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1279 1371
1280 if (tbl->action == start_action) 1372 if (tbl->action == start_action)
1281 break; 1373 break;
@@ -1285,9 +1377,7 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm,
1285 1377
1286out: 1378out:
1287 lq_sta->search_better_tbl = 1; 1379 lq_sta->search_better_tbl = 1;
1288 tbl->action++; 1380 rs_move_next_action(tbl, IWL_LEGACY_LAST_ACTION);
1289 if (tbl->action > IWL_LEGACY_SWITCH_MIMO2)
1290 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1291 if (update_search_tbl_counter) 1381 if (update_search_tbl_counter)
1292 search_tbl->action = tbl->action; 1382 search_tbl->action = tbl->action;
1293 return 0; 1383 return 0;
@@ -1300,12 +1390,10 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1300 struct iwl_lq_sta *lq_sta, 1390 struct iwl_lq_sta *lq_sta,
1301 struct ieee80211_sta *sta, int index) 1391 struct ieee80211_sta *sta, int index)
1302{ 1392{
1303 u8 is_green = lq_sta->is_green;
1304 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1393 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1305 struct iwl_scale_tbl_info *search_tbl = 1394 struct iwl_scale_tbl_info *search_tbl =
1306 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); 1395 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1307 struct iwl_rate_scale_data *window = &(tbl->win[index]); 1396 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1308 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1309 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1397 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1310 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1398 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1311 u8 start_action; 1399 u8 start_action;
@@ -1314,40 +1402,17 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1314 u8 update_search_tbl_counter = 0; 1402 u8 update_search_tbl_counter = 0;
1315 int ret; 1403 int ret;
1316 1404
1317 switch (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) { 1405 if (tbl->action == IWL_SISO_SWITCH_MIMO2 &&
1318 case IWL_BT_COEX_TRAFFIC_LOAD_NONE: 1406 !iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
1319 /* nothing */ 1407 tbl->action = IWL_SISO_SWITCH_ANTENNA;
1320 break;
1321 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1322 /* avoid antenna B unless MIMO */
1323 if (tbl->action == IWL_SISO_SWITCH_ANTENNA2)
1324 tbl->action = IWL_SISO_SWITCH_MIMO2;
1325 break;
1326 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1327 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1328 /* avoid antenna B and MIMO */
1329 valid_tx_ant =
1330 first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
1331 if (tbl->action != IWL_SISO_SWITCH_ANTENNA1)
1332 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1333 break;
1334 default:
1335 IWL_ERR(mvm, "Invalid BT load %d",
1336 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD));
1337 break;
1338 }
1339 1408
1340 start_action = tbl->action; 1409 start_action = tbl->action;
1341 while (1) { 1410 while (1) {
1342 lq_sta->action_counter++; 1411 lq_sta->action_counter++;
1343 switch (tbl->action) { 1412 switch (tbl->action) {
1344 case IWL_SISO_SWITCH_ANTENNA1: 1413 case IWL_SISO_SWITCH_ANTENNA:
1345 case IWL_SISO_SWITCH_ANTENNA2:
1346 IWL_DEBUG_RATE(mvm, "LQ: SISO toggle Antenna\n"); 1414 IWL_DEBUG_RATE(mvm, "LQ: SISO toggle Antenna\n");
1347 if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 && 1415 if (tx_chains_num <= 1)
1348 tx_chains_num <= 1) ||
1349 (tbl->action == IWL_SISO_SWITCH_ANTENNA2 &&
1350 tx_chains_num <= 2))
1351 break; 1416 break;
1352 1417
1353 if (window->success_ratio >= IWL_RS_GOOD_RATIO && 1418 if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
@@ -1380,23 +1445,12 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1380 goto out; 1445 goto out;
1381 break; 1446 break;
1382 case IWL_SISO_SWITCH_GI: 1447 case IWL_SISO_SWITCH_GI:
1383 if (!tbl->is_ht40 && !(ht_cap->cap & 1448 if (!rs_sgi_allowed(tbl, sta))
1384 IEEE80211_HT_CAP_SGI_20))
1385 break;
1386 if (tbl->is_ht40 && !(ht_cap->cap &
1387 IEEE80211_HT_CAP_SGI_40))
1388 break; 1449 break;
1389 1450
1390 IWL_DEBUG_RATE(mvm, "LQ: SISO toggle SGI/NGI\n"); 1451 IWL_DEBUG_RATE(mvm, "LQ: SISO toggle SGI/NGI\n");
1391 1452
1392 memcpy(search_tbl, tbl, sz); 1453 memcpy(search_tbl, tbl, sz);
1393 if (is_green) {
1394 if (!tbl->is_SGI)
1395 break;
1396 else
1397 IWL_ERR(mvm,
1398 "SGI was set in GF+SISO\n");
1399 }
1400 search_tbl->is_SGI = !tbl->is_SGI; 1454 search_tbl->is_SGI = !tbl->is_SGI;
1401 rs_set_expected_tpt_table(lq_sta, search_tbl); 1455 rs_set_expected_tpt_table(lq_sta, search_tbl);
1402 if (tbl->is_SGI) { 1456 if (tbl->is_SGI) {
@@ -1405,16 +1459,13 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1405 break; 1459 break;
1406 } 1460 }
1407 search_tbl->current_rate = 1461 search_tbl->current_rate =
1408 rate_n_flags_from_tbl(mvm, search_tbl, 1462 rate_n_flags_from_tbl(mvm, search_tbl, index);
1409 index, is_green);
1410 update_search_tbl_counter = 1; 1463 update_search_tbl_counter = 1;
1411 goto out; 1464 goto out;
1412 default: 1465 default:
1413 WARN_ON_ONCE(1); 1466 WARN_ON_ONCE(1);
1414 } 1467 }
1415 tbl->action++; 1468 rs_move_next_action(tbl, IWL_SISO_LAST_ACTION);
1416 if (tbl->action > IWL_SISO_SWITCH_GI)
1417 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1418 1469
1419 if (tbl->action == start_action) 1470 if (tbl->action == start_action)
1420 break; 1471 break;
@@ -1424,9 +1475,7 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1424 1475
1425 out: 1476 out:
1426 lq_sta->search_better_tbl = 1; 1477 lq_sta->search_better_tbl = 1;
1427 tbl->action++; 1478 rs_move_next_action(tbl, IWL_SISO_LAST_ACTION);
1428 if (tbl->action > IWL_SISO_SWITCH_GI)
1429 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1430 if (update_search_tbl_counter) 1479 if (update_search_tbl_counter)
1431 search_tbl->action = tbl->action; 1480 search_tbl->action = tbl->action;
1432 1481
@@ -1440,63 +1489,20 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1440 struct iwl_lq_sta *lq_sta, 1489 struct iwl_lq_sta *lq_sta,
1441 struct ieee80211_sta *sta, int index) 1490 struct ieee80211_sta *sta, int index)
1442{ 1491{
1443 s8 is_green = lq_sta->is_green;
1444 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1492 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1445 struct iwl_scale_tbl_info *search_tbl = 1493 struct iwl_scale_tbl_info *search_tbl =
1446 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); 1494 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1447 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1448 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1449 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1495 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1450 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1496 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1451 u8 start_action; 1497 u8 start_action;
1452 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); 1498 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1453 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1454 u8 update_search_tbl_counter = 0; 1499 u8 update_search_tbl_counter = 0;
1455 int ret; 1500 int ret;
1456 1501
1457 switch (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
1458 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1459 /* nothing */
1460 break;
1461 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1462 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1463 /* avoid antenna B and MIMO */
1464 if (tbl->action != IWL_MIMO2_SWITCH_SISO_A)
1465 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1466 break;
1467 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1468 /* avoid antenna B unless MIMO */
1469 if (tbl->action == IWL_MIMO2_SWITCH_SISO_B)
1470 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1471 break;
1472 default:
1473 IWL_ERR(mvm, "Invalid BT load %d",
1474 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD));
1475 break;
1476 }
1477
1478 start_action = tbl->action; 1502 start_action = tbl->action;
1479 while (1) { 1503 while (1) {
1480 lq_sta->action_counter++; 1504 lq_sta->action_counter++;
1481 switch (tbl->action) { 1505 switch (tbl->action) {
1482 case IWL_MIMO2_SWITCH_ANTENNA1:
1483 case IWL_MIMO2_SWITCH_ANTENNA2:
1484 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 toggle Antennas\n");
1485
1486 if (tx_chains_num <= 2)
1487 break;
1488
1489 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1490 break;
1491
1492 memcpy(search_tbl, tbl, sz);
1493 if (rs_toggle_antenna(valid_tx_ant,
1494 &search_tbl->current_rate,
1495 search_tbl)) {
1496 update_search_tbl_counter = 1;
1497 goto out;
1498 }
1499 break;
1500 case IWL_MIMO2_SWITCH_SISO_A: 1506 case IWL_MIMO2_SWITCH_SISO_A:
1501 case IWL_MIMO2_SWITCH_SISO_B: 1507 case IWL_MIMO2_SWITCH_SISO_B:
1502 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 switch to SISO\n"); 1508 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 switch to SISO\n");
@@ -1521,11 +1527,7 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1521 break; 1527 break;
1522 1528
1523 case IWL_MIMO2_SWITCH_GI: 1529 case IWL_MIMO2_SWITCH_GI:
1524 if (!tbl->is_ht40 && !(ht_cap->cap & 1530 if (!rs_sgi_allowed(tbl, sta))
1525 IEEE80211_HT_CAP_SGI_20))
1526 break;
1527 if (tbl->is_ht40 && !(ht_cap->cap &
1528 IEEE80211_HT_CAP_SGI_40))
1529 break; 1531 break;
1530 1532
1531 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 toggle SGI/NGI\n"); 1533 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 toggle SGI/NGI\n");
@@ -1546,16 +1548,13 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1546 break; 1548 break;
1547 } 1549 }
1548 search_tbl->current_rate = 1550 search_tbl->current_rate =
1549 rate_n_flags_from_tbl(mvm, search_tbl, 1551 rate_n_flags_from_tbl(mvm, search_tbl, index);
1550 index, is_green);
1551 update_search_tbl_counter = 1; 1552 update_search_tbl_counter = 1;
1552 goto out; 1553 goto out;
1553 default: 1554 default:
1554 WARN_ON_ONCE(1); 1555 WARN_ON_ONCE(1);
1555 } 1556 }
1556 tbl->action++; 1557 rs_move_next_action(tbl, IWL_MIMO2_LAST_ACTION);
1557 if (tbl->action > IWL_MIMO2_SWITCH_GI)
1558 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
1559 1558
1560 if (tbl->action == start_action) 1559 if (tbl->action == start_action)
1561 break; 1560 break;
@@ -1564,9 +1563,7 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1564 return 0; 1563 return 0;
1565 out: 1564 out:
1566 lq_sta->search_better_tbl = 1; 1565 lq_sta->search_better_tbl = 1;
1567 tbl->action++; 1566 rs_move_next_action(tbl, IWL_MIMO2_LAST_ACTION);
1568 if (tbl->action > IWL_MIMO2_SWITCH_GI)
1569 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
1570 if (update_search_tbl_counter) 1567 if (update_search_tbl_counter)
1571 search_tbl->action = tbl->action; 1568 search_tbl->action = tbl->action;
1572 1569
@@ -1660,15 +1657,16 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1660 * setup rate table in uCode 1657 * setup rate table in uCode
1661 */ 1658 */
1662static void rs_update_rate_tbl(struct iwl_mvm *mvm, 1659static void rs_update_rate_tbl(struct iwl_mvm *mvm,
1660 struct ieee80211_sta *sta,
1663 struct iwl_lq_sta *lq_sta, 1661 struct iwl_lq_sta *lq_sta,
1664 struct iwl_scale_tbl_info *tbl, 1662 struct iwl_scale_tbl_info *tbl,
1665 int index, u8 is_green) 1663 int index)
1666{ 1664{
1667 u32 rate; 1665 u32 rate;
1668 1666
1669 /* Update uCode's rate table. */ 1667 /* Update uCode's rate table. */
1670 rate = rate_n_flags_from_tbl(mvm, tbl, index, is_green); 1668 rate = rate_n_flags_from_tbl(mvm, tbl, index);
1671 rs_fill_link_cmd(mvm, lq_sta, rate); 1669 rs_fill_link_cmd(mvm, sta, lq_sta, rate);
1672 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false); 1670 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
1673} 1671}
1674 1672
@@ -1712,7 +1710,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1712 u8 update_lq = 0; 1710 u8 update_lq = 0;
1713 struct iwl_scale_tbl_info *tbl, *tbl1; 1711 struct iwl_scale_tbl_info *tbl, *tbl1;
1714 u16 rate_scale_index_msk = 0; 1712 u16 rate_scale_index_msk = 0;
1715 u8 is_green = 0;
1716 u8 active_tbl = 0; 1713 u8 active_tbl = 0;
1717 u8 done_search = 0; 1714 u8 done_search = 0;
1718 u16 high_low; 1715 u16 high_low;
@@ -1754,11 +1751,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1754 active_tbl = 1 - lq_sta->active_tbl; 1751 active_tbl = 1 - lq_sta->active_tbl;
1755 1752
1756 tbl = &(lq_sta->lq_info[active_tbl]); 1753 tbl = &(lq_sta->lq_info[active_tbl]);
1757 if (is_legacy(tbl->lq_type))
1758 lq_sta->is_green = 0;
1759 else
1760 lq_sta->is_green = rs_use_green(sta);
1761 is_green = lq_sta->is_green;
1762 1754
1763 /* current tx rate */ 1755 /* current tx rate */
1764 index = lq_sta->last_txrate_idx; 1756 index = lq_sta->last_txrate_idx;
@@ -1797,7 +1789,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1797 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1789 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1798 /* get "active" rate info */ 1790 /* get "active" rate info */
1799 index = iwl_hwrate_to_plcp_idx(tbl->current_rate); 1791 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
1800 rs_update_rate_tbl(mvm, lq_sta, tbl, index, is_green); 1792 rs_update_rate_tbl(mvm, sta, lq_sta, tbl, index);
1801 } 1793 }
1802 return; 1794 return;
1803 } 1795 }
@@ -1978,24 +1970,24 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1978 (current_tpt > (100 * tbl->expected_tpt[low])))) 1970 (current_tpt > (100 * tbl->expected_tpt[low]))))
1979 scale_action = 0; 1971 scale_action = 0;
1980 1972
1981 if ((BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >= 1973 if ((le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >=
1982 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && (is_mimo(tbl->lq_type))) { 1974 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && (is_mimo(tbl->lq_type))) {
1983 if (lq_sta->last_bt_traffic > 1975 if (lq_sta->last_bt_traffic >
1984 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) { 1976 le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)) {
1985 /* 1977 /*
1986 * don't set scale_action, don't want to scale up if 1978 * don't set scale_action, don't want to scale up if
1987 * the rate scale doesn't otherwise think that is a 1979 * the rate scale doesn't otherwise think that is a
1988 * good idea. 1980 * good idea.
1989 */ 1981 */
1990 } else if (lq_sta->last_bt_traffic <= 1982 } else if (lq_sta->last_bt_traffic <=
1991 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) { 1983 le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)) {
1992 scale_action = -1; 1984 scale_action = -1;
1993 } 1985 }
1994 } 1986 }
1995 lq_sta->last_bt_traffic = 1987 lq_sta->last_bt_traffic =
1996 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD); 1988 le32_to_cpu(mvm->last_bt_notif.bt_activity_grading);
1997 1989
1998 if ((BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >= 1990 if ((le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >=
1999 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && is_mimo(tbl->lq_type)) { 1991 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && is_mimo(tbl->lq_type)) {
2000 /* search for a new modulation */ 1992 /* search for a new modulation */
2001 rs_stay_in_table(lq_sta, true); 1993 rs_stay_in_table(lq_sta, true);
@@ -2032,7 +2024,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2032lq_update: 2024lq_update:
2033 /* Replace uCode's rate table for the destination station. */ 2025 /* Replace uCode's rate table for the destination station. */
2034 if (update_lq) 2026 if (update_lq)
2035 rs_update_rate_tbl(mvm, lq_sta, tbl, index, is_green); 2027 rs_update_rate_tbl(mvm, sta, lq_sta, tbl, index);
2036 2028
2037 rs_stay_in_table(lq_sta, false); 2029 rs_stay_in_table(lq_sta, false);
2038 2030
@@ -2071,7 +2063,7 @@ lq_update:
2071 IWL_DEBUG_RATE(mvm, 2063 IWL_DEBUG_RATE(mvm,
2072 "Switch current mcs: %X index: %d\n", 2064 "Switch current mcs: %X index: %d\n",
2073 tbl->current_rate, index); 2065 tbl->current_rate, index);
2074 rs_fill_link_cmd(mvm, lq_sta, tbl->current_rate); 2066 rs_fill_link_cmd(mvm, sta, lq_sta, tbl->current_rate);
2075 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false); 2067 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
2076 } else { 2068 } else {
2077 done_search = 1; 2069 done_search = 1;
@@ -2113,7 +2105,7 @@ lq_update:
2113 } 2105 }
2114 2106
2115out: 2107out:
2116 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, index, is_green); 2108 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, index);
2117 lq_sta->last_txrate_idx = index; 2109 lq_sta->last_txrate_idx = index;
2118} 2110}
2119 2111
@@ -2140,7 +2132,6 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
2140 int rate_idx; 2132 int rate_idx;
2141 int i; 2133 int i;
2142 u32 rate; 2134 u32 rate;
2143 u8 use_green = rs_use_green(sta);
2144 u8 active_tbl = 0; 2135 u8 active_tbl = 0;
2145 u8 valid_tx_ant; 2136 u8 valid_tx_ant;
2146 2137
@@ -2172,10 +2163,10 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
2172 if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type)) 2163 if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type))
2173 rs_toggle_antenna(valid_tx_ant, &rate, tbl); 2164 rs_toggle_antenna(valid_tx_ant, &rate, tbl);
2174 2165
2175 rate = rate_n_flags_from_tbl(mvm, tbl, rate_idx, use_green); 2166 rate = rate_n_flags_from_tbl(mvm, tbl, rate_idx);
2176 tbl->current_rate = rate; 2167 tbl->current_rate = rate;
2177 rs_set_expected_tpt_table(lq_sta, tbl); 2168 rs_set_expected_tpt_table(lq_sta, tbl);
2178 rs_fill_link_cmd(NULL, lq_sta, rate); 2169 rs_fill_link_cmd(NULL, NULL, lq_sta, rate);
2179 /* TODO restore station should remember the lq cmd */ 2170 /* TODO restore station should remember the lq cmd */
2180 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_SYNC, true); 2171 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_SYNC, true);
2181} 2172}
@@ -2190,7 +2181,6 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
2190 struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode); 2181 struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode);
2191 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2182 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2192 struct iwl_lq_sta *lq_sta = mvm_sta; 2183 struct iwl_lq_sta *lq_sta = mvm_sta;
2193 int rate_idx;
2194 2184
2195 IWL_DEBUG_RATE_LIMIT(mvm, "rate scale calculate new rate for skb\n"); 2185 IWL_DEBUG_RATE_LIMIT(mvm, "rate scale calculate new rate for skb\n");
2196 2186
@@ -2215,36 +2205,9 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
2215 if (rate_control_send_low(sta, mvm_sta, txrc)) 2205 if (rate_control_send_low(sta, mvm_sta, txrc))
2216 return; 2206 return;
2217 2207
2218 rate_idx = lq_sta->last_txrate_idx; 2208 iwl_mvm_hwrate_to_tx_rate(lq_sta->last_rate_n_flags,
2219 2209 info->band, &info->control.rates[0]);
2220 if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) { 2210
2221 rate_idx -= IWL_FIRST_OFDM_RATE;
2222 /* 6M and 9M shared same MCS index */
2223 rate_idx = (rate_idx > 0) ? (rate_idx - 1) : 0;
2224 WARN_ON_ONCE(rs_extract_rate(lq_sta->last_rate_n_flags) >=
2225 IWL_RATE_MIMO3_6M_PLCP);
2226 if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
2227 IWL_RATE_MIMO2_6M_PLCP)
2228 rate_idx = rate_idx + MCS_INDEX_PER_STREAM;
2229 info->control.rates[0].flags = IEEE80211_TX_RC_MCS;
2230 if (lq_sta->last_rate_n_flags & RATE_MCS_SGI_MSK)
2231 info->control.rates[0].flags |= IEEE80211_TX_RC_SHORT_GI;
2232 if (lq_sta->last_rate_n_flags & RATE_MCS_CHAN_WIDTH_40) /* TODO */
2233 info->control.rates[0].flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
2234 if (lq_sta->last_rate_n_flags & RATE_HT_MCS_GF_MSK)
2235 info->control.rates[0].flags |= IEEE80211_TX_RC_GREEN_FIELD;
2236 } else {
2237 /* Check for invalid rates */
2238 if ((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT_LEGACY) ||
2239 ((sband->band == IEEE80211_BAND_5GHZ) &&
2240 (rate_idx < IWL_FIRST_OFDM_RATE)))
2241 rate_idx = rate_lowest_index(sband, sta);
2242 /* On valid 5 GHz rate, adjust index */
2243 else if (sband->band == IEEE80211_BAND_5GHZ)
2244 rate_idx -= IWL_FIRST_OFDM_RATE;
2245 info->control.rates[0].flags = 0;
2246 }
2247 info->control.rates[0].idx = rate_idx;
2248 info->control.rates[0].count = 1; 2211 info->control.rates[0].count = 1;
2249} 2212}
2250 2213
@@ -2261,6 +2224,24 @@ static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
2261 return &sta_priv->lq_sta; 2224 return &sta_priv->lq_sta;
2262} 2225}
2263 2226
2227static int rs_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap,
2228 int nss)
2229{
2230 u16 rx_mcs = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) &
2231 (0x3 << (2 * (nss - 1)));
2232 rx_mcs >>= (2 * (nss - 1));
2233
2234 if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_7)
2235 return IWL_RATE_MCS_7_INDEX;
2236 else if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_8)
2237 return IWL_RATE_MCS_8_INDEX;
2238 else if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_9)
2239 return IWL_RATE_MCS_9_INDEX;
2240
2241 WARN_ON_ONCE(rx_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED);
2242 return -1;
2243}
2244
2264/* 2245/*
2265 * Called after adding a new station to initialize rate scaling 2246 * Called after adding a new station to initialize rate scaling
2266 */ 2247 */
@@ -2270,6 +2251,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2270 int i, j; 2251 int i, j;
2271 struct ieee80211_hw *hw = mvm->hw; 2252 struct ieee80211_hw *hw = mvm->hw;
2272 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 2253 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2254 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
2273 struct iwl_mvm_sta *sta_priv; 2255 struct iwl_mvm_sta *sta_priv;
2274 struct iwl_lq_sta *lq_sta; 2256 struct iwl_lq_sta *lq_sta;
2275 struct ieee80211_supported_band *sband; 2257 struct ieee80211_supported_band *sband;
@@ -2298,7 +2280,6 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2298 2280
2299 lq_sta->max_rate_idx = -1; 2281 lq_sta->max_rate_idx = -1;
2300 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; 2282 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
2301 lq_sta->is_green = rs_use_green(sta);
2302 lq_sta->band = sband->band; 2283 lq_sta->band = sband->band;
2303 /* 2284 /*
2304 * active legacy rates as per supported rates bitmap 2285 * active legacy rates as per supported rates bitmap
@@ -2308,25 +2289,54 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2308 for_each_set_bit(i, &supp, BITS_PER_LONG) 2289 for_each_set_bit(i, &supp, BITS_PER_LONG)
2309 lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value); 2290 lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value);
2310 2291
2311 /* 2292 /* TODO: should probably account for rx_highest for both HT/VHT */
2312 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), 2293 if (!vht_cap || !vht_cap->vht_supported) {
2313 * supp_rates[] does not; shift to convert format, force 9 MBits off. 2294 /* active_siso_rate mask includes 9 MBits (bit 5),
2314 */ 2295 * and CCK (bits 0-3), supp_rates[] does not;
2315 lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1; 2296 * shift to convert format, force 9 MBits off.
2316 lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1; 2297 */
2317 lq_sta->active_siso_rate &= ~((u16)0x2); 2298 lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1;
2318 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; 2299 lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1;
2300 lq_sta->active_siso_rate &= ~((u16)0x2);
2301 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
2302
2303 /* Same here */
2304 lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1;
2305 lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1;
2306 lq_sta->active_mimo2_rate &= ~((u16)0x2);
2307 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
2308
2309 lq_sta->is_vht = false;
2310 } else {
2311 int highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 1);
2312 if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
2313 for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
2314 if (i == IWL_RATE_9M_INDEX)
2315 continue;
2316
2317 lq_sta->active_siso_rate |= BIT(i);
2318 }
2319 }
2320
2321 highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 2);
2322 if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
2323 for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
2324 if (i == IWL_RATE_9M_INDEX)
2325 continue;
2319 2326
2320 /* Same here */ 2327 lq_sta->active_mimo2_rate |= BIT(i);
2321 lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1; 2328 }
2322 lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1; 2329 }
2323 lq_sta->active_mimo2_rate &= ~((u16)0x2); 2330
2324 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; 2331 /* TODO: avoid MCS9 in 20Mhz which isn't valid for 11ac */
2332 lq_sta->is_vht = true;
2333 }
2325 2334
2326 IWL_DEBUG_RATE(mvm, 2335 IWL_DEBUG_RATE(mvm,
2327 "SISO-RATE=%X MIMO2-RATE=%X\n", 2336 "SISO-RATE=%X MIMO2-RATE=%X VHT=%d\n",
2328 lq_sta->active_siso_rate, 2337 lq_sta->active_siso_rate,
2329 lq_sta->active_mimo2_rate); 2338 lq_sta->active_mimo2_rate,
2339 lq_sta->is_vht);
2330 2340
2331 /* These values will be overridden later */ 2341 /* These values will be overridden later */
2332 lq_sta->lq.single_stream_ant_msk = 2342 lq_sta->lq.single_stream_ant_msk =
@@ -2358,6 +2368,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2358} 2368}
2359 2369
2360static void rs_fill_link_cmd(struct iwl_mvm *mvm, 2370static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2371 struct ieee80211_sta *sta,
2361 struct iwl_lq_sta *lq_sta, u32 new_rate) 2372 struct iwl_lq_sta *lq_sta, u32 new_rate)
2362{ 2373{
2363 struct iwl_scale_tbl_info tbl_type; 2374 struct iwl_scale_tbl_info tbl_type;
@@ -2429,7 +2440,6 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2429 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, 2440 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type,
2430 &rate_idx); 2441 &rate_idx);
2431 2442
2432
2433 /* Indicate to uCode which entries might be MIMO. 2443 /* Indicate to uCode which entries might be MIMO.
2434 * If initial rate was MIMO, this will finally end up 2444 * If initial rate was MIMO, this will finally end up
2435 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */ 2445 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
@@ -2455,7 +2465,9 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2455 } 2465 }
2456 2466
2457 /* Don't allow HT rates after next pass. 2467 /* Don't allow HT rates after next pass.
2458 * rs_get_lower_rate() will change type to LQ_A or LQ_G. */ 2468 * rs_get_lower_rate() will change type to LQ_LEGACY_A
2469 * or LQ_LEGACY_G.
2470 */
2459 use_ht_possible = 0; 2471 use_ht_possible = 0;
2460 2472
2461 /* Override next rate if needed for debug purposes */ 2473 /* Override next rate if needed for debug purposes */
@@ -2474,12 +2486,9 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2474 lq_cmd->agg_time_limit = 2486 lq_cmd->agg_time_limit =
2475 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); 2487 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
2476 2488
2477 /* 2489 if (sta)
2478 * overwrite if needed, pass aggregation time limit 2490 lq_cmd->agg_time_limit =
2479 * to uCode in uSec - This is racy - but heh, at least it helps... 2491 cpu_to_le16(iwl_mvm_bt_coex_agg_time_limit(mvm, sta));
2480 */
2481 if (mvm && BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >= 2)
2482 lq_cmd->agg_time_limit = cpu_to_le16(1200);
2483} 2492}
2484 2493
2485static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 2494static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -2586,16 +2595,18 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2586 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "", 2595 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "",
2587 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : ""); 2596 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : "");
2588 desc += sprintf(buff+desc, "lq type %s\n", 2597 desc += sprintf(buff+desc, "lq type %s\n",
2589 (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); 2598 (is_legacy(tbl->lq_type)) ? "legacy" :
2590 if (is_Ht(tbl->lq_type)) { 2599 is_vht(tbl->lq_type) ? "VHT" : "HT");
2600 if (is_ht(tbl->lq_type)) {
2591 desc += sprintf(buff+desc, " %s", 2601 desc += sprintf(buff+desc, " %s",
2592 (is_siso(tbl->lq_type)) ? "SISO" : "MIMO2"); 2602 (is_siso(tbl->lq_type)) ? "SISO" : "MIMO2");
2593 desc += sprintf(buff+desc, " %s", 2603 desc += sprintf(buff+desc, " %s",
2594 (tbl->is_ht40) ? "40MHz" : "20MHz"); 2604 (is_ht20(tbl)) ? "20MHz" :
2595 desc += sprintf(buff+desc, " %s %s %s\n", 2605 (is_ht40(tbl)) ? "40MHz" :
2606 (is_ht80(tbl)) ? "80Mhz" : "BAD BW");
2607 desc += sprintf(buff+desc, " %s %s\n",
2596 (tbl->is_SGI) ? "SGI" : "", 2608 (tbl->is_SGI) ? "SGI" : "",
2597 (lq_sta->is_green) ? "GF enabled" : "", 2609 (lq_sta->is_agg) ? "AGG on" : "");
2598 (lq_sta->is_agg) ? "AGG on" : "");
2599 } 2610 }
2600 desc += sprintf(buff+desc, "last tx rate=0x%X\n", 2611 desc += sprintf(buff+desc, "last tx rate=0x%X\n",
2601 lq_sta->last_rate_n_flags); 2612 lq_sta->last_rate_n_flags);
@@ -2653,7 +2664,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2653 int desc = 0; 2664 int desc = 0;
2654 int i, j; 2665 int i, j;
2655 ssize_t ret; 2666 ssize_t ret;
2656 2667 struct iwl_scale_tbl_info *tbl;
2657 struct iwl_lq_sta *lq_sta = file->private_data; 2668 struct iwl_lq_sta *lq_sta = file->private_data;
2658 2669
2659 buff = kmalloc(1024, GFP_KERNEL); 2670 buff = kmalloc(1024, GFP_KERNEL);
@@ -2661,21 +2672,23 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2661 return -ENOMEM; 2672 return -ENOMEM;
2662 2673
2663 for (i = 0; i < LQ_SIZE; i++) { 2674 for (i = 0; i < LQ_SIZE; i++) {
2675 tbl = &(lq_sta->lq_info[i]);
2664 desc += sprintf(buff+desc, 2676 desc += sprintf(buff+desc,
2665 "%s type=%d SGI=%d HT40=%d DUP=0 GF=%d\n" 2677 "%s type=%d SGI=%d BW=%s DUP=0\n"
2666 "rate=0x%X\n", 2678 "rate=0x%X\n",
2667 lq_sta->active_tbl == i ? "*" : "x", 2679 lq_sta->active_tbl == i ? "*" : "x",
2668 lq_sta->lq_info[i].lq_type, 2680 tbl->lq_type,
2669 lq_sta->lq_info[i].is_SGI, 2681 tbl->is_SGI,
2670 lq_sta->lq_info[i].is_ht40, 2682 is_ht20(tbl) ? "20Mhz" :
2671 lq_sta->is_green, 2683 is_ht40(tbl) ? "40Mhz" :
2672 lq_sta->lq_info[i].current_rate); 2684 is_ht80(tbl) ? "80Mhz" : "ERR",
2685 tbl->current_rate);
2673 for (j = 0; j < IWL_RATE_COUNT; j++) { 2686 for (j = 0; j < IWL_RATE_COUNT; j++) {
2674 desc += sprintf(buff+desc, 2687 desc += sprintf(buff+desc,
2675 "counter=%d success=%d %%=%d\n", 2688 "counter=%d success=%d %%=%d\n",
2676 lq_sta->lq_info[i].win[j].counter, 2689 tbl->win[j].counter,
2677 lq_sta->lq_info[i].win[j].success_counter, 2690 tbl->win[j].success_counter,
2678 lq_sta->lq_info[i].win[j].success_ratio); 2691 tbl->win[j].success_ratio);
2679 } 2692 }
2680 } 2693 }
2681 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); 2694 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 465d40ee176f..5d5344f7070b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -35,9 +35,11 @@
35#include "iwl-trans.h" 35#include "iwl-trans.h"
36 36
37struct iwl_rs_rate_info { 37struct iwl_rs_rate_info {
38 u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ 38 u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
39 u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ 39 u8 plcp_ht_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
40 u8 plcp_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */ 40 u8 plcp_ht_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */
41 u8 plcp_vht_siso;
42 u8 plcp_vht_mimo2;
41 u8 prev_rs; /* previous rate used in rs algo */ 43 u8 prev_rs; /* previous rate used in rs algo */
42 u8 next_rs; /* next rate used in rs algo */ 44 u8 next_rs; /* next rate used in rs algo */
43}; 45};
@@ -83,35 +85,52 @@ enum {
83#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX) 85#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX)
84 86
85 87
86/* uCode API values for OFDM high-throughput (HT) bit rates */ 88/* uCode API values for HT/VHT bit rates */
87enum { 89enum {
88 IWL_RATE_SISO_6M_PLCP = 0, 90 IWL_RATE_HT_SISO_MCS_0_PLCP = 0,
89 IWL_RATE_SISO_12M_PLCP = 1, 91 IWL_RATE_HT_SISO_MCS_1_PLCP = 1,
90 IWL_RATE_SISO_18M_PLCP = 2, 92 IWL_RATE_HT_SISO_MCS_2_PLCP = 2,
91 IWL_RATE_SISO_24M_PLCP = 3, 93 IWL_RATE_HT_SISO_MCS_3_PLCP = 3,
92 IWL_RATE_SISO_36M_PLCP = 4, 94 IWL_RATE_HT_SISO_MCS_4_PLCP = 4,
93 IWL_RATE_SISO_48M_PLCP = 5, 95 IWL_RATE_HT_SISO_MCS_5_PLCP = 5,
94 IWL_RATE_SISO_54M_PLCP = 6, 96 IWL_RATE_HT_SISO_MCS_6_PLCP = 6,
95 IWL_RATE_SISO_60M_PLCP = 7, 97 IWL_RATE_HT_SISO_MCS_7_PLCP = 7,
96 IWL_RATE_MIMO2_6M_PLCP = 0x8, 98 IWL_RATE_HT_MIMO2_MCS_0_PLCP = 0x8,
97 IWL_RATE_MIMO2_12M_PLCP = 0x9, 99 IWL_RATE_HT_MIMO2_MCS_1_PLCP = 0x9,
98 IWL_RATE_MIMO2_18M_PLCP = 0xa, 100 IWL_RATE_HT_MIMO2_MCS_2_PLCP = 0xA,
99 IWL_RATE_MIMO2_24M_PLCP = 0xb, 101 IWL_RATE_HT_MIMO2_MCS_3_PLCP = 0xB,
100 IWL_RATE_MIMO2_36M_PLCP = 0xc, 102 IWL_RATE_HT_MIMO2_MCS_4_PLCP = 0xC,
101 IWL_RATE_MIMO2_48M_PLCP = 0xd, 103 IWL_RATE_HT_MIMO2_MCS_5_PLCP = 0xD,
102 IWL_RATE_MIMO2_54M_PLCP = 0xe, 104 IWL_RATE_HT_MIMO2_MCS_6_PLCP = 0xE,
103 IWL_RATE_MIMO2_60M_PLCP = 0xf, 105 IWL_RATE_HT_MIMO2_MCS_7_PLCP = 0xF,
104 IWL_RATE_MIMO3_6M_PLCP = 0x10, 106 IWL_RATE_VHT_SISO_MCS_0_PLCP = 0,
105 IWL_RATE_MIMO3_12M_PLCP = 0x11, 107 IWL_RATE_VHT_SISO_MCS_1_PLCP = 1,
106 IWL_RATE_MIMO3_18M_PLCP = 0x12, 108 IWL_RATE_VHT_SISO_MCS_2_PLCP = 2,
107 IWL_RATE_MIMO3_24M_PLCP = 0x13, 109 IWL_RATE_VHT_SISO_MCS_3_PLCP = 3,
108 IWL_RATE_MIMO3_36M_PLCP = 0x14, 110 IWL_RATE_VHT_SISO_MCS_4_PLCP = 4,
109 IWL_RATE_MIMO3_48M_PLCP = 0x15, 111 IWL_RATE_VHT_SISO_MCS_5_PLCP = 5,
110 IWL_RATE_MIMO3_54M_PLCP = 0x16, 112 IWL_RATE_VHT_SISO_MCS_6_PLCP = 6,
111 IWL_RATE_MIMO3_60M_PLCP = 0x17, 113 IWL_RATE_VHT_SISO_MCS_7_PLCP = 7,
112 IWL_RATE_SISO_INVM_PLCP, 114 IWL_RATE_VHT_SISO_MCS_8_PLCP = 8,
113 IWL_RATE_MIMO2_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP, 115 IWL_RATE_VHT_SISO_MCS_9_PLCP = 9,
114 IWL_RATE_MIMO3_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP, 116 IWL_RATE_VHT_MIMO2_MCS_0_PLCP = 0x10,
117 IWL_RATE_VHT_MIMO2_MCS_1_PLCP = 0x11,
118 IWL_RATE_VHT_MIMO2_MCS_2_PLCP = 0x12,
119 IWL_RATE_VHT_MIMO2_MCS_3_PLCP = 0x13,
120 IWL_RATE_VHT_MIMO2_MCS_4_PLCP = 0x14,
121 IWL_RATE_VHT_MIMO2_MCS_5_PLCP = 0x15,
122 IWL_RATE_VHT_MIMO2_MCS_6_PLCP = 0x16,
123 IWL_RATE_VHT_MIMO2_MCS_7_PLCP = 0x17,
124 IWL_RATE_VHT_MIMO2_MCS_8_PLCP = 0x18,
125 IWL_RATE_VHT_MIMO2_MCS_9_PLCP = 0x19,
126 IWL_RATE_HT_SISO_MCS_INV_PLCP,
127 IWL_RATE_HT_MIMO2_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP,
128 IWL_RATE_VHT_SISO_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP,
129 IWL_RATE_VHT_MIMO2_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP,
130 IWL_RATE_HT_SISO_MCS_8_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP,
131 IWL_RATE_HT_SISO_MCS_9_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP,
132 IWL_RATE_HT_MIMO2_MCS_8_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP,
133 IWL_RATE_HT_MIMO2_MCS_9_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP,
115}; 134};
116 135
117#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) 136#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
@@ -139,25 +158,33 @@ enum {
139#define IWL_RATE_DECREASE_TH 1920 /* 15% */ 158#define IWL_RATE_DECREASE_TH 1920 /* 15% */
140 159
141/* possible actions when in legacy mode */ 160/* possible actions when in legacy mode */
142#define IWL_LEGACY_SWITCH_ANTENNA1 0 161enum {
143#define IWL_LEGACY_SWITCH_ANTENNA2 1 162 IWL_LEGACY_SWITCH_ANTENNA,
144#define IWL_LEGACY_SWITCH_SISO 2 163 IWL_LEGACY_SWITCH_SISO,
145#define IWL_LEGACY_SWITCH_MIMO2 3 164 IWL_LEGACY_SWITCH_MIMO2,
165 IWL_LEGACY_FIRST_ACTION = IWL_LEGACY_SWITCH_ANTENNA,
166 IWL_LEGACY_LAST_ACTION = IWL_LEGACY_SWITCH_MIMO2,
167};
146 168
147/* possible actions when in siso mode */ 169/* possible actions when in siso mode */
148#define IWL_SISO_SWITCH_ANTENNA1 0 170enum {
149#define IWL_SISO_SWITCH_ANTENNA2 1 171 IWL_SISO_SWITCH_ANTENNA,
150#define IWL_SISO_SWITCH_MIMO2 2 172 IWL_SISO_SWITCH_MIMO2,
151#define IWL_SISO_SWITCH_GI 3 173 IWL_SISO_SWITCH_GI,
174 IWL_SISO_FIRST_ACTION = IWL_SISO_SWITCH_ANTENNA,
175 IWL_SISO_LAST_ACTION = IWL_SISO_SWITCH_GI,
176};
152 177
153/* possible actions when in mimo mode */ 178/* possible actions when in mimo mode */
154#define IWL_MIMO2_SWITCH_ANTENNA1 0 179enum {
155#define IWL_MIMO2_SWITCH_ANTENNA2 1 180 IWL_MIMO2_SWITCH_SISO_A,
156#define IWL_MIMO2_SWITCH_SISO_A 2 181 IWL_MIMO2_SWITCH_SISO_B,
157#define IWL_MIMO2_SWITCH_SISO_B 3 182 IWL_MIMO2_SWITCH_GI,
158#define IWL_MIMO2_SWITCH_GI 4 183 IWL_MIMO2_FIRST_ACTION = IWL_MIMO2_SWITCH_SISO_A,
184 IWL_MIMO2_LAST_ACTION = IWL_MIMO2_SWITCH_GI,
185};
159 186
160#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_GI 187#define IWL_MAX_SEARCH IWL_MIMO2_LAST_ACTION
161 188
162#define IWL_ACTION_LIMIT 3 /* # possible actions */ 189#define IWL_ACTION_LIMIT 3 /* # possible actions */
163 190
@@ -188,20 +215,31 @@ enum {
188 215
189enum iwl_table_type { 216enum iwl_table_type {
190 LQ_NONE, 217 LQ_NONE,
191 LQ_G, /* legacy types */ 218 LQ_LEGACY_G, /* legacy types */
192 LQ_A, 219 LQ_LEGACY_A,
193 LQ_SISO, /* high-throughput types */ 220 LQ_HT_SISO, /* HT types */
194 LQ_MIMO2, 221 LQ_HT_MIMO2,
222 LQ_VHT_SISO, /* VHT types */
223 LQ_VHT_MIMO2,
195 LQ_MAX, 224 LQ_MAX,
196}; 225};
197 226
198#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A)) 227#define is_legacy(tbl) (((tbl) == LQ_LEGACY_G) || ((tbl) == LQ_LEGACY_A))
199#define is_siso(tbl) ((tbl) == LQ_SISO) 228#define is_ht_siso(tbl) ((tbl) == LQ_HT_SISO)
200#define is_mimo2(tbl) ((tbl) == LQ_MIMO2) 229#define is_ht_mimo2(tbl) ((tbl) == LQ_HT_MIMO2)
201#define is_mimo(tbl) is_mimo2(tbl) 230#define is_vht_siso(tbl) ((tbl) == LQ_VHT_SISO)
202#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl)) 231#define is_vht_mimo2(tbl) ((tbl) == LQ_VHT_MIMO2)
203#define is_a_band(tbl) ((tbl) == LQ_A) 232#define is_siso(tbl) (is_ht_siso(tbl) || is_vht_siso(tbl))
204#define is_g_and(tbl) ((tbl) == LQ_G) 233#define is_mimo2(tbl) (is_ht_mimo2(tbl) || is_vht_mimo2(tbl))
234#define is_mimo(tbl) (is_mimo2(tbl))
235#define is_ht(tbl) (is_ht_siso(tbl) || is_ht_mimo2(tbl))
236#define is_vht(tbl) (is_vht_siso(tbl) || is_vht_mimo2(tbl))
237#define is_a_band(tbl) ((tbl) == LQ_LEGACY_A)
238#define is_g_band(tbl) ((tbl) == LQ_LEGACY_G)
239
240#define is_ht20(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_20)
241#define is_ht40(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_40)
242#define is_ht80(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_80)
205 243
206#define IWL_MAX_MCS_DISPLAY_SIZE 12 244#define IWL_MAX_MCS_DISPLAY_SIZE 12
207 245
@@ -232,7 +270,7 @@ struct iwl_scale_tbl_info {
232 enum iwl_table_type lq_type; 270 enum iwl_table_type lq_type;
233 u8 ant_type; 271 u8 ant_type;
234 u8 is_SGI; /* 1 = short guard interval */ 272 u8 is_SGI; /* 1 = short guard interval */
235 u8 is_ht40; /* 1 = 40 MHz channel width */ 273 u32 bw; /* channel bandwidth; RATE_MCS_CHAN_WIDTH_XX */
236 u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ 274 u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
237 u8 max_search; /* maximun number of tables we can search */ 275 u8 max_search; /* maximun number of tables we can search */
238 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ 276 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
@@ -262,7 +300,7 @@ struct iwl_lq_sta {
262 u64 flush_timer; /* time staying in mode before new search */ 300 u64 flush_timer; /* time staying in mode before new search */
263 301
264 u8 action_counter; /* # mode-switch actions tried */ 302 u8 action_counter; /* # mode-switch actions tried */
265 u8 is_green; 303 bool is_vht;
266 enum ieee80211_band band; 304 enum ieee80211_band band;
267 305
268 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ 306 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 2a8cb5a60535..a4af5019a496 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -422,6 +422,27 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
422 422
423 mvmvif->bf_data.ave_beacon_signal = sig; 423 mvmvif->bf_data.ave_beacon_signal = sig;
424 424
425 /* BT Coex */
426 if (mvmvif->bf_data.bt_coex_min_thold !=
427 mvmvif->bf_data.bt_coex_max_thold) {
428 last_event = mvmvif->bf_data.last_bt_coex_event;
429 if (sig > mvmvif->bf_data.bt_coex_max_thold &&
430 (last_event <= mvmvif->bf_data.bt_coex_min_thold ||
431 last_event == 0)) {
432 mvmvif->bf_data.last_bt_coex_event = sig;
433 IWL_DEBUG_RX(mvm, "cqm_iterator bt coex high %d\n",
434 sig);
435 iwl_mvm_bt_rssi_event(mvm, vif, RSSI_EVENT_HIGH);
436 } else if (sig < mvmvif->bf_data.bt_coex_min_thold &&
437 (last_event >= mvmvif->bf_data.bt_coex_max_thold ||
438 last_event == 0)) {
439 mvmvif->bf_data.last_bt_coex_event = sig;
440 IWL_DEBUG_RX(mvm, "cqm_iterator bt coex low %d\n",
441 sig);
442 iwl_mvm_bt_rssi_event(mvm, vif, RSSI_EVENT_LOW);
443 }
444 }
445
425 if (!(vif->driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) 446 if (!(vif->driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI))
426 return; 447 return;
427 448
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 621fb71f282a..dff7592e1ff8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -74,8 +74,12 @@
74static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) 74static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
75{ 75{
76 u16 rx_chain; 76 u16 rx_chain;
77 u8 rx_ant = iwl_fw_valid_rx_ant(mvm->fw); 77 u8 rx_ant;
78 78
79 if (mvm->scan_rx_ant != ANT_NONE)
80 rx_ant = mvm->scan_rx_ant;
81 else
82 rx_ant = iwl_fw_valid_rx_ant(mvm->fw);
79 rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS; 83 rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS;
80 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS; 84 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
81 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_SEL_POS; 85 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_SEL_POS;
@@ -93,10 +97,10 @@ static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif)
93 97
94static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif) 98static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif)
95{ 99{
96 if (vif->bss_conf.assoc) 100 if (!vif->bss_conf.assoc)
97 return cpu_to_le32(vif->bss_conf.beacon_int);
98 else
99 return 0; 101 return 0;
102
103 return cpu_to_le32(ieee80211_tu_to_usec(vif->bss_conf.beacon_int));
100} 104}
101 105
102static inline __le32 106static inline __le32
@@ -133,11 +137,12 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
133 * request. 137 * request.
134 */ 138 */
135static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, 139static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd,
136 struct cfg80211_scan_request *req) 140 struct cfg80211_scan_request *req,
141 int first)
137{ 142{
138 int fw_idx, req_idx; 143 int fw_idx, req_idx;
139 144
140 for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx > 0; 145 for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx >= first;
141 req_idx--, fw_idx++) { 146 req_idx--, fw_idx++) {
142 cmd->direct_scan[fw_idx].id = WLAN_EID_SSID; 147 cmd->direct_scan[fw_idx].id = WLAN_EID_SSID;
143 cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len; 148 cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len;
@@ -153,9 +158,9 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd,
153 * just to notify that this scan is active and not passive. 158 * just to notify that this scan is active and not passive.
154 * In order to notify the FW of the number of SSIDs we wish to scan (including 159 * In order to notify the FW of the number of SSIDs we wish to scan (including
155 * the zero-length one), we need to set the corresponding bits in chan->type, 160 * the zero-length one), we need to set the corresponding bits in chan->type,
156 * one for each SSID, and set the active bit (first). The first SSID is already 161 * one for each SSID, and set the active bit (first). If the first SSID is
157 * included in the probe template, so we need to set only req->n_ssids - 1 bits 162 * already included in the probe template, so we need to set only
158 * in addition to the first bit. 163 * req->n_ssids - 1 bits in addition to the first bit.
159 */ 164 */
160static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) 165static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids)
161{ 166{
@@ -170,7 +175,8 @@ static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band)
170} 175}
171 176
172static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd, 177static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
173 struct cfg80211_scan_request *req) 178 struct cfg80211_scan_request *req,
179 bool basic_ssid)
174{ 180{
175 u16 passive_dwell = iwl_mvm_get_passive_dwell(req->channels[0]->band); 181 u16 passive_dwell = iwl_mvm_get_passive_dwell(req->channels[0]->band);
176 u16 active_dwell = iwl_mvm_get_active_dwell(req->channels[0]->band, 182 u16 active_dwell = iwl_mvm_get_active_dwell(req->channels[0]->band,
@@ -178,10 +184,14 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
178 struct iwl_scan_channel *chan = (struct iwl_scan_channel *) 184 struct iwl_scan_channel *chan = (struct iwl_scan_channel *)
179 (cmd->data + le16_to_cpu(cmd->tx_cmd.len)); 185 (cmd->data + le16_to_cpu(cmd->tx_cmd.len));
180 int i; 186 int i;
187 int type = BIT(req->n_ssids) - 1;
188
189 if (!basic_ssid)
190 type |= BIT(req->n_ssids);
181 191
182 for (i = 0; i < cmd->channel_count; i++) { 192 for (i = 0; i < cmd->channel_count; i++) {
183 chan->channel = cpu_to_le16(req->channels[i]->hw_value); 193 chan->channel = cpu_to_le16(req->channels[i]->hw_value);
184 chan->type = cpu_to_le32(BIT(req->n_ssids) - 1); 194 chan->type = cpu_to_le32(type);
185 if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) 195 if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN)
186 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE); 196 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
187 chan->active_dwell = cpu_to_le16(active_dwell); 197 chan->active_dwell = cpu_to_le16(active_dwell);
@@ -268,6 +278,8 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
268 u32 status; 278 u32 status;
269 int ssid_len = 0; 279 int ssid_len = 0;
270 u8 *ssid = NULL; 280 u8 *ssid = NULL;
281 bool basic_ssid = !(mvm->fw->ucode_capa.flags &
282 IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID);
271 283
272 lockdep_assert_held(&mvm->mutex); 284 lockdep_assert_held(&mvm->mutex);
273 BUG_ON(mvm->scan_cmd == NULL); 285 BUG_ON(mvm->scan_cmd == NULL);
@@ -302,14 +314,16 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
302 if (req->n_ssids > 0) { 314 if (req->n_ssids > 0) {
303 cmd->passive2active = cpu_to_le16(1); 315 cmd->passive2active = cpu_to_le16(1);
304 cmd->scan_flags |= SCAN_FLAGS_PASSIVE2ACTIVE; 316 cmd->scan_flags |= SCAN_FLAGS_PASSIVE2ACTIVE;
305 ssid = req->ssids[0].ssid; 317 if (basic_ssid) {
306 ssid_len = req->ssids[0].ssid_len; 318 ssid = req->ssids[0].ssid;
319 ssid_len = req->ssids[0].ssid_len;
320 }
307 } else { 321 } else {
308 cmd->passive2active = 0; 322 cmd->passive2active = 0;
309 cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE; 323 cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE;
310 } 324 }
311 325
312 iwl_mvm_scan_fill_ssids(cmd, req); 326 iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0);
313 327
314 cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL); 328 cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL);
315 cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; 329 cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id;
@@ -326,7 +340,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
326 req->ie, req->ie_len, 340 req->ie, req->ie_len,
327 mvm->fw->ucode_capa.max_probe_length)); 341 mvm->fw->ucode_capa.max_probe_length));
328 342
329 iwl_mvm_scan_fill_channels(cmd, req); 343 iwl_mvm_scan_fill_channels(cmd, req, basic_ssid);
330 344
331 cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) + 345 cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) +
332 le16_to_cpu(cmd->tx_cmd.len) + 346 le16_to_cpu(cmd->tx_cmd.len) +
@@ -377,6 +391,21 @@ int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
377 return 0; 391 return 0;
378} 392}
379 393
394int iwl_mvm_rx_sched_scan_results(struct iwl_mvm *mvm,
395 struct iwl_rx_cmd_buffer *rxb,
396 struct iwl_device_cmd *cmd)
397{
398 struct iwl_rx_packet *pkt = rxb_addr(rxb);
399 struct iwl_sched_scan_results *notif = (void *)pkt->data;
400
401 if (notif->client_bitmap & SCAN_CLIENT_SCHED_SCAN) {
402 IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n");
403 ieee80211_sched_scan_results(mvm->hw);
404 }
405
406 return 0;
407}
408
380static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait, 409static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait,
381 struct iwl_rx_packet *pkt, void *data) 410 struct iwl_rx_packet *pkt, void *data)
382{ 411{
@@ -447,3 +476,406 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
447out_remove_notif: 476out_remove_notif:
448 iwl_remove_notification(&mvm->notif_wait, &wait_scan_abort); 477 iwl_remove_notification(&mvm->notif_wait, &wait_scan_abort);
449} 478}
479
480int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
481 struct iwl_rx_cmd_buffer *rxb,
482 struct iwl_device_cmd *cmd)
483{
484 struct iwl_rx_packet *pkt = rxb_addr(rxb);
485 struct iwl_scan_offload_complete *scan_notif = (void *)pkt->data;
486
487 IWL_DEBUG_SCAN(mvm, "Scheduled scan completed, status %s\n",
488 scan_notif->status == IWL_SCAN_OFFLOAD_COMPLETED ?
489 "completed" : "aborted");
490
491 mvm->scan_status = IWL_MVM_SCAN_NONE;
492 ieee80211_sched_scan_stopped(mvm->hw);
493
494 return 0;
495}
496
497static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm,
498 struct ieee80211_vif *vif,
499 struct ieee80211_sched_scan_ies *ies,
500 enum ieee80211_band band,
501 struct iwl_tx_cmd *cmd,
502 u8 *data)
503{
504 u16 cmd_len;
505
506 cmd->tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL);
507 cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
508 cmd->sta_id = mvm->aux_sta.sta_id;
509
510 cmd->rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm, band, false);
511
512 cmd_len = iwl_mvm_fill_probe_req((struct ieee80211_mgmt *)data,
513 vif->addr,
514 1, NULL, 0,
515 ies->ie[band], ies->len[band],
516 SCAN_OFFLOAD_PROBE_REQ_SIZE);
517 cmd->len = cpu_to_le16(cmd_len);
518}
519
520static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
521 struct ieee80211_vif *vif,
522 struct cfg80211_sched_scan_request *req,
523 struct iwl_scan_offload_cmd *scan)
524{
525 scan->channel_count =
526 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels +
527 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
528 scan->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
529 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
530 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT;
531 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm);
532 scan->max_out_time = cpu_to_le32(200 * 1024);
533 scan->suspend_time = iwl_mvm_scan_suspend_time(vif);
534 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
535 MAC_FILTER_IN_BEACON);
536 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND);
537 scan->rep_count = cpu_to_le32(1);
538}
539
540static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list)
541{
542 int i;
543
544 for (i = 0; i < PROBE_OPTION_MAX; i++) {
545 if (!ssid_list[i].len)
546 break;
547 if (ssid_list[i].len == ssid_len &&
548 !memcmp(ssid_list->ssid, ssid, ssid_len))
549 return i;
550 }
551 return -1;
552}
553
554static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req,
555 struct iwl_scan_offload_cmd *scan,
556 u32 *ssid_bitmap)
557{
558 int i, j;
559 int index;
560
561 /*
562 * copy SSIDs from match list.
563 * iwl_config_sched_scan_profiles() uses the order of these ssids to
564 * config match list.
565 */
566 for (i = 0; i < req->n_match_sets && i < PROBE_OPTION_MAX; i++) {
567 scan->direct_scan[i].id = WLAN_EID_SSID;
568 scan->direct_scan[i].len = req->match_sets[i].ssid.ssid_len;
569 memcpy(scan->direct_scan[i].ssid, req->match_sets[i].ssid.ssid,
570 scan->direct_scan[i].len);
571 }
572
573 /* add SSIDs from scan SSID list */
574 *ssid_bitmap = 0;
575 for (j = 0; j < req->n_ssids && i < PROBE_OPTION_MAX; j++) {
576 index = iwl_ssid_exist(req->ssids[j].ssid,
577 req->ssids[j].ssid_len,
578 scan->direct_scan);
579 if (index < 0) {
580 if (!req->ssids[j].ssid_len)
581 continue;
582 scan->direct_scan[i].id = WLAN_EID_SSID;
583 scan->direct_scan[i].len = req->ssids[j].ssid_len;
584 memcpy(scan->direct_scan[i].ssid, req->ssids[j].ssid,
585 scan->direct_scan[i].len);
586 *ssid_bitmap |= BIT(i + 1);
587 i++;
588 } else {
589 *ssid_bitmap |= BIT(index + 1);
590 }
591 }
592}
593
594static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
595 struct cfg80211_sched_scan_request *req,
596 struct iwl_scan_channel_cfg *channels,
597 enum ieee80211_band band,
598 int *head, int *tail,
599 u32 ssid_bitmap)
600{
601 struct ieee80211_supported_band *s_band;
602 int n_probes = req->n_ssids;
603 int n_channels = req->n_channels;
604 u8 active_dwell, passive_dwell;
605 int i, j, index = 0;
606 bool partial;
607
608 /*
609 * We have to configure all supported channels, even if we don't want to
610 * scan on them, but we have to send channels in the order that we want
611 * to scan. So add requested channels to head of the list and others to
612 * the end.
613 */
614 active_dwell = iwl_mvm_get_active_dwell(band, n_probes);
615 passive_dwell = iwl_mvm_get_passive_dwell(band);
616 s_band = &mvm->nvm_data->bands[band];
617
618 for (i = 0; i < s_band->n_channels && *head <= *tail; i++) {
619 partial = false;
620 for (j = 0; j < n_channels; j++)
621 if (s_band->channels[i].center_freq ==
622 req->channels[j]->center_freq) {
623 index = *head;
624 (*head)++;
625 /*
626 * Channels that came with the request will be
627 * in partial scan .
628 */
629 partial = true;
630 break;
631 }
632 if (!partial) {
633 index = *tail;
634 (*tail)--;
635 }
636 channels->channel_number[index] =
637 cpu_to_le16(ieee80211_frequency_to_channel(
638 s_band->channels[i].center_freq));
639 channels->dwell_time[index][0] = active_dwell;
640 channels->dwell_time[index][1] = passive_dwell;
641
642 channels->iter_count[index] = cpu_to_le16(1);
643 channels->iter_interval[index] = 0;
644
645 if (!(s_band->channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN))
646 channels->type[index] |=
647 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE);
648
649 channels->type[index] |=
650 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_FULL);
651 if (partial)
652 channels->type[index] |=
653 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL);
654
655 if (s_band->channels[i].flags & IEEE80211_CHAN_NO_HT40)
656 channels->type[index] |=
657 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_NARROW);
658
659 /* scan for all SSIDs from req->ssids */
660 channels->type[index] |= cpu_to_le32(ssid_bitmap);
661 }
662}
663
664int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
665 struct ieee80211_vif *vif,
666 struct cfg80211_sched_scan_request *req,
667 struct ieee80211_sched_scan_ies *ies)
668{
669 int supported_bands = 0;
670 int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels;
671 int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
672 int head = 0;
673 int tail = band_2ghz + band_5ghz;
674 u32 ssid_bitmap;
675 int cmd_len;
676 int ret;
677
678 struct iwl_scan_offload_cfg *scan_cfg;
679 struct iwl_host_cmd cmd = {
680 .id = SCAN_OFFLOAD_CONFIG_CMD,
681 .flags = CMD_SYNC,
682 };
683
684 lockdep_assert_held(&mvm->mutex);
685
686 if (band_2ghz)
687 supported_bands++;
688 if (band_5ghz)
689 supported_bands++;
690
691 cmd_len = sizeof(struct iwl_scan_offload_cfg) +
692 supported_bands * SCAN_OFFLOAD_PROBE_REQ_SIZE;
693
694 scan_cfg = kzalloc(cmd_len, GFP_KERNEL);
695 if (!scan_cfg)
696 return -ENOMEM;
697
698 iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd);
699 scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len);
700
701 iwl_scan_offload_build_ssid(req, &scan_cfg->scan_cmd, &ssid_bitmap);
702 /* build tx frames for supported bands */
703 if (band_2ghz) {
704 iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
705 IEEE80211_BAND_2GHZ,
706 &scan_cfg->scan_cmd.tx_cmd[0],
707 scan_cfg->data);
708 iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg,
709 IEEE80211_BAND_2GHZ, &head, &tail,
710 ssid_bitmap);
711 }
712 if (band_5ghz) {
713 iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
714 IEEE80211_BAND_5GHZ,
715 &scan_cfg->scan_cmd.tx_cmd[1],
716 scan_cfg->data +
717 SCAN_OFFLOAD_PROBE_REQ_SIZE);
718 iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg,
719 IEEE80211_BAND_5GHZ, &head, &tail,
720 ssid_bitmap);
721 }
722
723 cmd.data[0] = scan_cfg;
724 cmd.len[0] = cmd_len;
725 cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
726
727 IWL_DEBUG_SCAN(mvm, "Sending scheduled scan config\n");
728
729 ret = iwl_mvm_send_cmd(mvm, &cmd);
730 kfree(scan_cfg);
731 return ret;
732}
733
734int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
735 struct cfg80211_sched_scan_request *req)
736{
737 struct iwl_scan_offload_profile *profile;
738 struct iwl_scan_offload_profile_cfg *profile_cfg;
739 struct iwl_scan_offload_blacklist *blacklist;
740 struct iwl_host_cmd cmd = {
741 .id = SCAN_OFFLOAD_UPDATE_PROFILES_CMD,
742 .flags = CMD_SYNC,
743 .len[1] = sizeof(*profile_cfg),
744 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
745 .dataflags[1] = IWL_HCMD_DFL_NOCOPY,
746 };
747 int blacklist_len;
748 int i;
749 int ret;
750
751 if (WARN_ON(req->n_match_sets > IWL_SCAN_MAX_PROFILES))
752 return -EIO;
753
754 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SHORT_BL)
755 blacklist_len = IWL_SCAN_SHORT_BLACKLIST_LEN;
756 else
757 blacklist_len = IWL_SCAN_MAX_BLACKLIST_LEN;
758
759 blacklist = kzalloc(sizeof(*blacklist) * blacklist_len, GFP_KERNEL);
760 if (!blacklist)
761 return -ENOMEM;
762
763 profile_cfg = kzalloc(sizeof(*profile_cfg), GFP_KERNEL);
764 if (!profile_cfg) {
765 ret = -ENOMEM;
766 goto free_blacklist;
767 }
768
769 cmd.data[0] = blacklist;
770 cmd.len[0] = sizeof(*blacklist) * blacklist_len;
771 cmd.data[1] = profile_cfg;
772
773 /* No blacklist configuration */
774
775 profile_cfg->num_profiles = req->n_match_sets;
776 profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN;
777 profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN;
778 profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN;
779
780 for (i = 0; i < req->n_match_sets; i++) {
781 profile = &profile_cfg->profiles[i];
782 profile->ssid_index = i;
783 /* Support any cipher and auth algorithm */
784 profile->unicast_cipher = 0xff;
785 profile->auth_alg = 0xff;
786 profile->network_type = IWL_NETWORK_TYPE_ANY;
787 profile->band_selection = IWL_SCAN_OFFLOAD_SELECT_ANY;
788 profile->client_bitmap = SCAN_CLIENT_SCHED_SCAN;
789 }
790
791 IWL_DEBUG_SCAN(mvm, "Sending scheduled scan profile config\n");
792
793 ret = iwl_mvm_send_cmd(mvm, &cmd);
794 kfree(profile_cfg);
795free_blacklist:
796 kfree(blacklist);
797
798 return ret;
799}
800
801int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
802 struct cfg80211_sched_scan_request *req)
803{
804 struct iwl_scan_offload_req scan_req = {
805 .watchdog = IWL_SCHED_SCAN_WATCHDOG,
806
807 .schedule_line[0].iterations = IWL_FAST_SCHED_SCAN_ITERATIONS,
808 .schedule_line[0].delay = req->interval / 1000,
809 .schedule_line[0].full_scan_mul = 1,
810
811 .schedule_line[1].iterations = 0xff,
812 .schedule_line[1].delay = req->interval / 1000,
813 .schedule_line[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER,
814 };
815
816 if (req->n_match_sets && req->match_sets[0].ssid.ssid_len) {
817 IWL_DEBUG_SCAN(mvm,
818 "Sending scheduled scan with filtering, filter len %d\n",
819 req->n_match_sets);
820 scan_req.flags |=
821 cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID);
822 } else {
823 IWL_DEBUG_SCAN(mvm,
824 "Sending Scheduled scan without filtering\n");
825 }
826
827 return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, CMD_SYNC,
828 sizeof(scan_req), &scan_req);
829}
830
831static int iwl_mvm_send_sched_scan_abort(struct iwl_mvm *mvm)
832{
833 int ret;
834 struct iwl_host_cmd cmd = {
835 .id = SCAN_OFFLOAD_ABORT_CMD,
836 .flags = CMD_SYNC,
837 };
838 u32 status;
839
840 /* Exit instantly with error when device is not ready
841 * to receive scan abort command or it does not perform
842 * scheduled scan currently */
843 if (mvm->scan_status != IWL_MVM_SCAN_SCHED)
844 return -EIO;
845
846 ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status);
847 if (ret)
848 return ret;
849
850 if (status != CAN_ABORT_STATUS) {
851 /*
852 * The scan abort will return 1 for success or
853 * 2 for "failure". A failure condition can be
854 * due to simply not being in an active scan which
855 * can occur if we send the scan abort before the
856 * microcode has notified us that a scan is completed.
857 */
858 IWL_DEBUG_SCAN(mvm, "SCAN OFFLOAD ABORT ret %d.\n", status);
859 ret = -EIO;
860 }
861
862 return ret;
863}
864
865void iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm)
866{
867 int ret;
868
869 lockdep_assert_held(&mvm->mutex);
870
871 if (mvm->scan_status != IWL_MVM_SCAN_SCHED) {
872 IWL_DEBUG_SCAN(mvm, "No offloaded scan to stop\n");
873 return;
874 }
875
876 ret = iwl_mvm_send_sched_scan_abort(mvm);
877 if (ret)
878 IWL_DEBUG_SCAN(mvm, "Send stop offload scan failed %d\n", ret);
879 else
880 IWL_DEBUG_SCAN(mvm, "Successfully sent stop offload scan\n");
881}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 44add291531b..329952363a54 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -66,6 +66,115 @@
66#include "sta.h" 66#include "sta.h"
67#include "rs.h" 67#include "rs.h"
68 68
69static void iwl_mvm_add_sta_cmd_v6_to_v5(struct iwl_mvm_add_sta_cmd_v6 *cmd_v6,
70 struct iwl_mvm_add_sta_cmd_v5 *cmd_v5)
71{
72 memset(cmd_v5, 0, sizeof(*cmd_v5));
73
74 cmd_v5->add_modify = cmd_v6->add_modify;
75 cmd_v5->tid_disable_tx = cmd_v6->tid_disable_tx;
76 cmd_v5->mac_id_n_color = cmd_v6->mac_id_n_color;
77 memcpy(cmd_v5->addr, cmd_v6->addr, ETH_ALEN);
78 cmd_v5->sta_id = cmd_v6->sta_id;
79 cmd_v5->modify_mask = cmd_v6->modify_mask;
80 cmd_v5->station_flags = cmd_v6->station_flags;
81 cmd_v5->station_flags_msk = cmd_v6->station_flags_msk;
82 cmd_v5->add_immediate_ba_tid = cmd_v6->add_immediate_ba_tid;
83 cmd_v5->remove_immediate_ba_tid = cmd_v6->remove_immediate_ba_tid;
84 cmd_v5->add_immediate_ba_ssn = cmd_v6->add_immediate_ba_ssn;
85 cmd_v5->sleep_tx_count = cmd_v6->sleep_tx_count;
86 cmd_v5->sleep_state_flags = cmd_v6->sleep_state_flags;
87 cmd_v5->assoc_id = cmd_v6->assoc_id;
88 cmd_v5->beamform_flags = cmd_v6->beamform_flags;
89 cmd_v5->tfd_queue_msk = cmd_v6->tfd_queue_msk;
90}
91
92static void
93iwl_mvm_add_sta_key_to_add_sta_cmd_v5(struct iwl_mvm_add_sta_key_cmd *key_cmd,
94 struct iwl_mvm_add_sta_cmd_v5 *sta_cmd,
95 u32 mac_id_n_color)
96{
97 memset(sta_cmd, 0, sizeof(*sta_cmd));
98
99 sta_cmd->sta_id = key_cmd->sta_id;
100 sta_cmd->add_modify = STA_MODE_MODIFY;
101 sta_cmd->modify_mask = STA_MODIFY_KEY;
102 sta_cmd->mac_id_n_color = cpu_to_le32(mac_id_n_color);
103
104 sta_cmd->key.key_offset = key_cmd->key_offset;
105 sta_cmd->key.key_flags = key_cmd->key_flags;
106 memcpy(sta_cmd->key.key, key_cmd->key, sizeof(sta_cmd->key.key));
107 sta_cmd->key.tkip_rx_tsc_byte2 = key_cmd->tkip_rx_tsc_byte2;
108 memcpy(sta_cmd->key.tkip_rx_ttak, key_cmd->tkip_rx_ttak,
109 sizeof(sta_cmd->key.tkip_rx_ttak));
110}
111
112static int iwl_mvm_send_add_sta_cmd_status(struct iwl_mvm *mvm,
113 struct iwl_mvm_add_sta_cmd_v6 *cmd,
114 int *status)
115{
116 struct iwl_mvm_add_sta_cmd_v5 cmd_v5;
117
118 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD)
119 return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(*cmd),
120 cmd, status);
121
122 iwl_mvm_add_sta_cmd_v6_to_v5(cmd, &cmd_v5);
123
124 return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd_v5),
125 &cmd_v5, status);
126}
127
128static int iwl_mvm_send_add_sta_cmd(struct iwl_mvm *mvm, u32 flags,
129 struct iwl_mvm_add_sta_cmd_v6 *cmd)
130{
131 struct iwl_mvm_add_sta_cmd_v5 cmd_v5;
132
133 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD)
134 return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags,
135 sizeof(*cmd), cmd);
136
137 iwl_mvm_add_sta_cmd_v6_to_v5(cmd, &cmd_v5);
138
139 return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags, sizeof(cmd_v5),
140 &cmd_v5);
141}
142
143static int
144iwl_mvm_send_add_sta_key_cmd_status(struct iwl_mvm *mvm,
145 struct iwl_mvm_add_sta_key_cmd *cmd,
146 u32 mac_id_n_color,
147 int *status)
148{
149 struct iwl_mvm_add_sta_cmd_v5 sta_cmd;
150
151 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD)
152 return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA_KEY,
153 sizeof(*cmd), cmd, status);
154
155 iwl_mvm_add_sta_key_to_add_sta_cmd_v5(cmd, &sta_cmd, mac_id_n_color);
156
157 return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(sta_cmd),
158 &sta_cmd, status);
159}
160
161static int iwl_mvm_send_add_sta_key_cmd(struct iwl_mvm *mvm,
162 u32 flags,
163 struct iwl_mvm_add_sta_key_cmd *cmd,
164 u32 mac_id_n_color)
165{
166 struct iwl_mvm_add_sta_cmd_v5 sta_cmd;
167
168 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD)
169 return iwl_mvm_send_cmd_pdu(mvm, ADD_STA_KEY, flags,
170 sizeof(*cmd), cmd);
171
172 iwl_mvm_add_sta_key_to_add_sta_cmd_v5(cmd, &sta_cmd, mac_id_n_color);
173
174 return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags, sizeof(sta_cmd),
175 &sta_cmd);
176}
177
69static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm) 178static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm)
70{ 179{
71 int sta_id; 180 int sta_id;
@@ -87,7 +196,7 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
87 bool update) 196 bool update)
88{ 197{
89 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 198 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
90 struct iwl_mvm_add_sta_cmd add_sta_cmd; 199 struct iwl_mvm_add_sta_cmd_v6 add_sta_cmd;
91 int ret; 200 int ret;
92 u32 status; 201 u32 status;
93 u32 agg_size = 0, mpdu_dens = 0; 202 u32 agg_size = 0, mpdu_dens = 0;
@@ -175,8 +284,7 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
175 cpu_to_le32(mpdu_dens << STA_FLG_AGG_MPDU_DENS_SHIFT); 284 cpu_to_le32(mpdu_dens << STA_FLG_AGG_MPDU_DENS_SHIFT);
176 285
177 status = ADD_STA_SUCCESS; 286 status = ADD_STA_SUCCESS;
178 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(add_sta_cmd), 287 ret = iwl_mvm_send_add_sta_cmd_status(mvm, &add_sta_cmd, &status);
179 &add_sta_cmd, &status);
180 if (ret) 288 if (ret)
181 return ret; 289 return ret;
182 290
@@ -229,8 +337,12 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
229 if (vif->hw_queue[i] != IEEE80211_INVAL_HW_QUEUE) 337 if (vif->hw_queue[i] != IEEE80211_INVAL_HW_QUEUE)
230 mvm_sta->tfd_queue_msk |= BIT(vif->hw_queue[i]); 338 mvm_sta->tfd_queue_msk |= BIT(vif->hw_queue[i]);
231 339
232 /* for HW restart - need to reset the seq_number etc... */ 340 /* for HW restart - reset everything but the sequence number */
233 memset(mvm_sta->tid_data, 0, sizeof(mvm_sta->tid_data)); 341 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
342 u16 seq = mvm_sta->tid_data[i].seq_number;
343 memset(&mvm_sta->tid_data[i], 0, sizeof(mvm_sta->tid_data[i]));
344 mvm_sta->tid_data[i].seq_number = seq;
345 }
234 346
235 ret = iwl_mvm_sta_send_to_fw(mvm, sta, false); 347 ret = iwl_mvm_sta_send_to_fw(mvm, sta, false);
236 if (ret) 348 if (ret)
@@ -256,7 +368,7 @@ int iwl_mvm_update_sta(struct iwl_mvm *mvm,
256int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, 368int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
257 bool drain) 369 bool drain)
258{ 370{
259 struct iwl_mvm_add_sta_cmd cmd = {}; 371 struct iwl_mvm_add_sta_cmd_v6 cmd = {};
260 int ret; 372 int ret;
261 u32 status; 373 u32 status;
262 374
@@ -269,8 +381,7 @@ int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
269 cmd.station_flags_msk = cpu_to_le32(STA_FLG_DRAIN_FLOW); 381 cmd.station_flags_msk = cpu_to_le32(STA_FLG_DRAIN_FLOW);
270 382
271 status = ADD_STA_SUCCESS; 383 status = ADD_STA_SUCCESS;
272 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), 384 ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status);
273 &cmd, &status);
274 if (ret) 385 if (ret)
275 return ret; 386 return ret;
276 387
@@ -469,13 +580,13 @@ static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
469 const u8 *addr, 580 const u8 *addr,
470 u16 mac_id, u16 color) 581 u16 mac_id, u16 color)
471{ 582{
472 struct iwl_mvm_add_sta_cmd cmd; 583 struct iwl_mvm_add_sta_cmd_v6 cmd;
473 int ret; 584 int ret;
474 u32 status; 585 u32 status;
475 586
476 lockdep_assert_held(&mvm->mutex); 587 lockdep_assert_held(&mvm->mutex);
477 588
478 memset(&cmd, 0, sizeof(struct iwl_mvm_add_sta_cmd)); 589 memset(&cmd, 0, sizeof(struct iwl_mvm_add_sta_cmd_v6));
479 cmd.sta_id = sta->sta_id; 590 cmd.sta_id = sta->sta_id;
480 cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id, 591 cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
481 color)); 592 color));
@@ -485,8 +596,7 @@ static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
485 if (addr) 596 if (addr)
486 memcpy(cmd.addr, addr, ETH_ALEN); 597 memcpy(cmd.addr, addr, ETH_ALEN);
487 598
488 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), 599 ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status);
489 &cmd, &status);
490 if (ret) 600 if (ret)
491 return ret; 601 return ret;
492 602
@@ -534,10 +644,14 @@ int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
534 struct iwl_mvm_int_sta *bsta) 644 struct iwl_mvm_int_sta *bsta)
535{ 645{
536 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 646 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
537 static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 647 static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
648 static const u8 *baddr = _baddr;
538 649
539 lockdep_assert_held(&mvm->mutex); 650 lockdep_assert_held(&mvm->mutex);
540 651
652 if (vif->type == NL80211_IFTYPE_ADHOC)
653 baddr = vif->bss_conf.bssid;
654
541 if (WARN_ON_ONCE(bsta->sta_id == IWL_MVM_STATION_COUNT)) 655 if (WARN_ON_ONCE(bsta->sta_id == IWL_MVM_STATION_COUNT))
542 return -ENOSPC; 656 return -ENOSPC;
543 657
@@ -614,7 +728,7 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
614 int tid, u16 ssn, bool start) 728 int tid, u16 ssn, bool start)
615{ 729{
616 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 730 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
617 struct iwl_mvm_add_sta_cmd cmd = {}; 731 struct iwl_mvm_add_sta_cmd_v6 cmd = {};
618 int ret; 732 int ret;
619 u32 status; 733 u32 status;
620 734
@@ -638,8 +752,7 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
638 STA_MODIFY_REMOVE_BA_TID; 752 STA_MODIFY_REMOVE_BA_TID;
639 753
640 status = ADD_STA_SUCCESS; 754 status = ADD_STA_SUCCESS;
641 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), 755 ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status);
642 &cmd, &status);
643 if (ret) 756 if (ret)
644 return ret; 757 return ret;
645 758
@@ -674,7 +787,7 @@ static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
674 int tid, u8 queue, bool start) 787 int tid, u8 queue, bool start)
675{ 788{
676 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 789 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
677 struct iwl_mvm_add_sta_cmd cmd = {}; 790 struct iwl_mvm_add_sta_cmd_v6 cmd = {};
678 int ret; 791 int ret;
679 u32 status; 792 u32 status;
680 793
@@ -696,8 +809,7 @@ static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
696 cmd.tid_disable_tx = cpu_to_le16(mvm_sta->tid_disable_agg); 809 cmd.tid_disable_tx = cpu_to_le16(mvm_sta->tid_disable_agg);
697 810
698 status = ADD_STA_SUCCESS; 811 status = ADD_STA_SUCCESS;
699 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), 812 ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status);
700 &cmd, &status);
701 if (ret) 813 if (ret)
702 return ret; 814 return ret;
703 815
@@ -743,13 +855,13 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
743 855
744 lockdep_assert_held(&mvm->mutex); 856 lockdep_assert_held(&mvm->mutex);
745 857
746 for (txq_id = IWL_MVM_FIRST_AGG_QUEUE; 858 for (txq_id = mvm->first_agg_queue;
747 txq_id <= IWL_MVM_LAST_AGG_QUEUE; txq_id++) 859 txq_id <= mvm->last_agg_queue; txq_id++)
748 if (mvm->queue_to_mac80211[txq_id] == 860 if (mvm->queue_to_mac80211[txq_id] ==
749 IWL_INVALID_MAC80211_QUEUE) 861 IWL_INVALID_MAC80211_QUEUE)
750 break; 862 break;
751 863
752 if (txq_id > IWL_MVM_LAST_AGG_QUEUE) { 864 if (txq_id > mvm->last_agg_queue) {
753 IWL_ERR(mvm, "Failed to allocate agg queue\n"); 865 IWL_ERR(mvm, "Failed to allocate agg queue\n");
754 return -EIO; 866 return -EIO;
755 } 867 }
@@ -987,10 +1099,11 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
987 u32 cmd_flags) 1099 u32 cmd_flags)
988{ 1100{
989 __le16 key_flags; 1101 __le16 key_flags;
990 struct iwl_mvm_add_sta_cmd cmd = {}; 1102 struct iwl_mvm_add_sta_key_cmd cmd = {};
991 int ret, status; 1103 int ret, status;
992 u16 keyidx; 1104 u16 keyidx;
993 int i; 1105 int i;
1106 u32 mac_id_n_color = mvm_sta->mac_id_n_color;
994 1107
995 keyidx = (keyconf->keyidx << STA_KEY_FLG_KEYID_POS) & 1108 keyidx = (keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
996 STA_KEY_FLG_KEYID_MSK; 1109 STA_KEY_FLG_KEYID_MSK;
@@ -1000,14 +1113,14 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
1000 switch (keyconf->cipher) { 1113 switch (keyconf->cipher) {
1001 case WLAN_CIPHER_SUITE_TKIP: 1114 case WLAN_CIPHER_SUITE_TKIP:
1002 key_flags |= cpu_to_le16(STA_KEY_FLG_TKIP); 1115 key_flags |= cpu_to_le16(STA_KEY_FLG_TKIP);
1003 cmd.key.tkip_rx_tsc_byte2 = tkip_iv32; 1116 cmd.tkip_rx_tsc_byte2 = tkip_iv32;
1004 for (i = 0; i < 5; i++) 1117 for (i = 0; i < 5; i++)
1005 cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]); 1118 cmd.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]);
1006 memcpy(cmd.key.key, keyconf->key, keyconf->keylen); 1119 memcpy(cmd.key, keyconf->key, keyconf->keylen);
1007 break; 1120 break;
1008 case WLAN_CIPHER_SUITE_CCMP: 1121 case WLAN_CIPHER_SUITE_CCMP:
1009 key_flags |= cpu_to_le16(STA_KEY_FLG_CCM); 1122 key_flags |= cpu_to_le16(STA_KEY_FLG_CCM);
1010 memcpy(cmd.key.key, keyconf->key, keyconf->keylen); 1123 memcpy(cmd.key, keyconf->key, keyconf->keylen);
1011 break; 1124 break;
1012 default: 1125 default:
1013 WARN_ON(1); 1126 WARN_ON(1);
@@ -1017,20 +1130,18 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
1017 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) 1130 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1018 key_flags |= cpu_to_le16(STA_KEY_MULTICAST); 1131 key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
1019 1132
1020 cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); 1133 cmd.key_offset = keyconf->hw_key_idx;
1021 cmd.key.key_offset = keyconf->hw_key_idx; 1134 cmd.key_flags = key_flags;
1022 cmd.key.key_flags = key_flags;
1023 cmd.add_modify = STA_MODE_MODIFY;
1024 cmd.modify_mask = STA_MODIFY_KEY;
1025 cmd.sta_id = sta_id; 1135 cmd.sta_id = sta_id;
1026 1136
1027 status = ADD_STA_SUCCESS; 1137 status = ADD_STA_SUCCESS;
1028 if (cmd_flags == CMD_SYNC) 1138 if (cmd_flags == CMD_SYNC)
1029 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), 1139 ret = iwl_mvm_send_add_sta_key_cmd_status(mvm, &cmd,
1030 &cmd, &status); 1140 mac_id_n_color,
1141 &status);
1031 else 1142 else
1032 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, 1143 ret = iwl_mvm_send_add_sta_key_cmd(mvm, CMD_ASYNC, &cmd,
1033 sizeof(cmd), &cmd); 1144 mac_id_n_color);
1034 1145
1035 switch (status) { 1146 switch (status) {
1036 case ADD_STA_SUCCESS: 1147 case ADD_STA_SUCCESS:
@@ -1197,7 +1308,7 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
1197 struct ieee80211_key_conf *keyconf) 1308 struct ieee80211_key_conf *keyconf)
1198{ 1309{
1199 struct iwl_mvm_sta *mvm_sta; 1310 struct iwl_mvm_sta *mvm_sta;
1200 struct iwl_mvm_add_sta_cmd cmd = {}; 1311 struct iwl_mvm_add_sta_key_cmd cmd = {};
1201 __le16 key_flags; 1312 __le16 key_flags;
1202 int ret, status; 1313 int ret, status;
1203 u8 sta_id; 1314 u8 sta_id;
@@ -1252,17 +1363,14 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
1252 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) 1363 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1253 key_flags |= cpu_to_le16(STA_KEY_MULTICAST); 1364 key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
1254 1365
1255 cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); 1366 cmd.key_flags = key_flags;
1256 cmd.key.key_flags = key_flags; 1367 cmd.key_offset = keyconf->hw_key_idx;
1257 cmd.key.key_offset = keyconf->hw_key_idx;
1258 cmd.sta_id = sta_id; 1368 cmd.sta_id = sta_id;
1259 1369
1260 cmd.modify_mask = STA_MODIFY_KEY;
1261 cmd.add_modify = STA_MODE_MODIFY;
1262
1263 status = ADD_STA_SUCCESS; 1370 status = ADD_STA_SUCCESS;
1264 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), 1371 ret = iwl_mvm_send_add_sta_key_cmd_status(mvm, &cmd,
1265 &cmd, &status); 1372 mvm_sta->mac_id_n_color,
1373 &status);
1266 1374
1267 switch (status) { 1375 switch (status) {
1268 case ADD_STA_SUCCESS: 1376 case ADD_STA_SUCCESS:
@@ -1309,7 +1417,7 @@ void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
1309 struct ieee80211_sta *sta) 1417 struct ieee80211_sta *sta)
1310{ 1418{
1311 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1419 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
1312 struct iwl_mvm_add_sta_cmd cmd = { 1420 struct iwl_mvm_add_sta_cmd_v6 cmd = {
1313 .add_modify = STA_MODE_MODIFY, 1421 .add_modify = STA_MODE_MODIFY,
1314 .sta_id = mvmsta->sta_id, 1422 .sta_id = mvmsta->sta_id,
1315 .station_flags_msk = cpu_to_le32(STA_FLG_PS), 1423 .station_flags_msk = cpu_to_le32(STA_FLG_PS),
@@ -1317,7 +1425,7 @@ void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
1317 }; 1425 };
1318 int ret; 1426 int ret;
1319 1427
1320 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd); 1428 ret = iwl_mvm_send_add_sta_cmd(mvm, CMD_ASYNC, &cmd);
1321 if (ret) 1429 if (ret)
1322 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret); 1430 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
1323} 1431}
@@ -1331,7 +1439,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
1331 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ? 1439 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ?
1332 STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL; 1440 STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL;
1333 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1441 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
1334 struct iwl_mvm_add_sta_cmd cmd = { 1442 struct iwl_mvm_add_sta_cmd_v6 cmd = {
1335 .add_modify = STA_MODE_MODIFY, 1443 .add_modify = STA_MODE_MODIFY,
1336 .sta_id = mvmsta->sta_id, 1444 .sta_id = mvmsta->sta_id,
1337 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT, 1445 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
@@ -1346,7 +1454,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
1346 int ret; 1454 int ret;
1347 1455
1348 /* TODO: somehow the fw doesn't seem to take PS_POLL into account */ 1456 /* TODO: somehow the fw doesn't seem to take PS_POLL into account */
1349 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd); 1457 ret = iwl_mvm_send_add_sta_cmd(mvm, CMD_ASYNC, &cmd);
1350 if (ret) 1458 if (ret)
1351 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret); 1459 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
1352} 1460}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index 94b265eb32b8..4dfc359a4bdd 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -293,10 +293,6 @@ struct iwl_mvm_sta {
293 struct iwl_lq_sta lq_sta; 293 struct iwl_lq_sta lq_sta;
294 struct ieee80211_vif *vif; 294 struct ieee80211_vif *vif;
295 295
296#ifdef CONFIG_PM_SLEEP
297 u16 last_seq_ctl;
298#endif
299
300 /* Temporary, until the new TLC will control the Tx protection */ 296 /* Temporary, until the new TLC will control the Tx protection */
301 s8 tx_protection; 297 s8 tx_protection;
302 bool tt_tx_protection; 298 bool tt_tx_protection;
diff --git a/drivers/net/wireless/iwlwifi/mvm/testmode.h b/drivers/net/wireless/iwlwifi/mvm/testmode.h
new file mode 100644
index 000000000000..eb74391d91ca
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/testmode.h
@@ -0,0 +1,95 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#ifndef __IWL_MVM_TESTMODE_H__
65#define __IWL_MVM_TESTMODE_H__
66
67/**
68 * enum iwl_mvm_testmode_attrs - testmode attributes inside NL80211_ATTR_TESTDATA
69 * @IWL_MVM_TM_ATTR_UNSPEC: (invalid attribute)
70 * @IWL_MVM_TM_ATTR_CMD: sub command, see &enum iwl_mvm_testmode_commands (u32)
71 * @IWL_MVM_TM_ATTR_NOA_DURATION: requested NoA duration (u32)
72 * @IWL_MVM_TM_ATTR_BEACON_FILTER_STATE: beacon filter state (0 or 1, u32)
73 */
74enum iwl_mvm_testmode_attrs {
75 IWL_MVM_TM_ATTR_UNSPEC,
76 IWL_MVM_TM_ATTR_CMD,
77 IWL_MVM_TM_ATTR_NOA_DURATION,
78 IWL_MVM_TM_ATTR_BEACON_FILTER_STATE,
79
80 /* keep last */
81 NUM_IWL_MVM_TM_ATTRS,
82 IWL_MVM_TM_ATTR_MAX = NUM_IWL_MVM_TM_ATTRS - 1,
83};
84
85/**
86 * enum iwl_mvm_testmode_commands - MVM testmode commands
87 * @IWL_MVM_TM_CMD_SET_NOA: set NoA on GO vif for testing
88 * @IWL_MVM_TM_CMD_SET_BEACON_FILTER: turn beacon filtering off/on
89 */
90enum iwl_mvm_testmode_commands {
91 IWL_MVM_TM_CMD_SET_NOA,
92 IWL_MVM_TM_CMD_SET_BEACON_FILTER,
93};
94
95#endif /* __IWL_MVM_TESTMODE_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index 76a3c177e100..33cf56fdfc41 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -387,7 +387,8 @@ static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm,
387 387
388void iwl_mvm_protect_session(struct iwl_mvm *mvm, 388void iwl_mvm_protect_session(struct iwl_mvm *mvm,
389 struct ieee80211_vif *vif, 389 struct ieee80211_vif *vif,
390 u32 duration, u32 min_duration) 390 u32 duration, u32 min_duration,
391 u32 max_delay)
391{ 392{
392 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 393 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
393 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; 394 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
@@ -426,7 +427,7 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
426 cpu_to_le32(iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG)); 427 cpu_to_le32(iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG));
427 428
428 time_cmd.max_frags = TE_V2_FRAG_NONE; 429 time_cmd.max_frags = TE_V2_FRAG_NONE;
429 time_cmd.max_delay = cpu_to_le32(500); 430 time_cmd.max_delay = cpu_to_le32(max_delay);
430 /* TODO: why do we need to interval = bi if it is not periodic? */ 431 /* TODO: why do we need to interval = bi if it is not periodic? */
431 time_cmd.interval = cpu_to_le32(1); 432 time_cmd.interval = cpu_to_le32(1);
432 time_cmd.duration = cpu_to_le32(duration); 433 time_cmd.duration = cpu_to_le32(duration);
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h
index f86c51065ed3..d9c8d6cfa2db 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.h
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h
@@ -123,6 +123,7 @@
123 * @duration: the duration of the session in TU. 123 * @duration: the duration of the session in TU.
124 * @min_duration: will start a new session if the current session will end 124 * @min_duration: will start a new session if the current session will end
125 * in less than min_duration. 125 * in less than min_duration.
126 * @max_delay: maximum delay before starting the time event (in TU)
126 * 127 *
127 * This function can be used to start a session protection which means that the 128 * This function can be used to start a session protection which means that the
128 * fw will stay on the channel for %duration_ms milliseconds. This function 129 * fw will stay on the channel for %duration_ms milliseconds. This function
@@ -133,7 +134,8 @@
133 */ 134 */
134void iwl_mvm_protect_session(struct iwl_mvm *mvm, 135void iwl_mvm_protect_session(struct iwl_mvm *mvm,
135 struct ieee80211_vif *vif, 136 struct ieee80211_vif *vif,
136 u32 duration, u32 min_duration); 137 u32 duration, u32 min_duration,
138 u32 max_delay);
137 139
138/** 140/**
139 * iwl_mvm_stop_session_protection - cancel the session protection. 141 * iwl_mvm_stop_session_protection - cancel the session protection.
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index e05440d90319..43d97c33a75a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -417,7 +417,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
417 417
418 spin_unlock(&mvmsta->lock); 418 spin_unlock(&mvmsta->lock);
419 419
420 if (txq_id < IWL_MVM_FIRST_AGG_QUEUE) 420 if (txq_id < mvm->first_agg_queue)
421 atomic_inc(&mvm->pending_frames[mvmsta->sta_id]); 421 atomic_inc(&mvm->pending_frames[mvmsta->sta_id]);
422 422
423 return 0; 423 return 0;
@@ -511,16 +511,10 @@ const char *iwl_mvm_get_tx_fail_reason(u32 status)
511} 511}
512#endif /* CONFIG_IWLWIFI_DEBUG */ 512#endif /* CONFIG_IWLWIFI_DEBUG */
513 513
514/** 514void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
515 * translate ucode response to mac80211 tx status control values 515 enum ieee80211_band band,
516 */ 516 struct ieee80211_tx_rate *r)
517static void iwl_mvm_hwrate_to_tx_control(u32 rate_n_flags,
518 struct ieee80211_tx_info *info)
519{ 517{
520 struct ieee80211_tx_rate *r = &info->status.rates[0];
521
522 info->status.antenna =
523 ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
524 if (rate_n_flags & RATE_HT_MCS_GF_MSK) 518 if (rate_n_flags & RATE_HT_MCS_GF_MSK)
525 r->flags |= IEEE80211_TX_RC_GREEN_FIELD; 519 r->flags |= IEEE80211_TX_RC_GREEN_FIELD;
526 switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { 520 switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) {
@@ -549,10 +543,23 @@ static void iwl_mvm_hwrate_to_tx_control(u32 rate_n_flags,
549 r->flags |= IEEE80211_TX_RC_VHT_MCS; 543 r->flags |= IEEE80211_TX_RC_VHT_MCS;
550 } else { 544 } else {
551 r->idx = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags, 545 r->idx = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
552 info->band); 546 band);
553 } 547 }
554} 548}
555 549
550/**
551 * translate ucode response to mac80211 tx status control values
552 */
553static void iwl_mvm_hwrate_to_tx_status(u32 rate_n_flags,
554 struct ieee80211_tx_info *info)
555{
556 struct ieee80211_tx_rate *r = &info->status.rates[0];
557
558 info->status.antenna =
559 ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
560 iwl_mvm_hwrate_to_tx_rate(rate_n_flags, info->band, r);
561}
562
556static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, 563static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
557 struct iwl_rx_packet *pkt) 564 struct iwl_rx_packet *pkt)
558{ 565{
@@ -602,11 +609,11 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
602 } 609 }
603 610
604 info->status.rates[0].count = tx_resp->failure_frame + 1; 611 info->status.rates[0].count = tx_resp->failure_frame + 1;
605 iwl_mvm_hwrate_to_tx_control(le32_to_cpu(tx_resp->initial_rate), 612 iwl_mvm_hwrate_to_tx_status(le32_to_cpu(tx_resp->initial_rate),
606 info); 613 info);
607 614
608 /* Single frame failure in an AMPDU queue => send BAR */ 615 /* Single frame failure in an AMPDU queue => send BAR */
609 if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE && 616 if (txq_id >= mvm->first_agg_queue &&
610 !(info->flags & IEEE80211_TX_STAT_ACK)) 617 !(info->flags & IEEE80211_TX_STAT_ACK))
611 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 618 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
612 619
@@ -619,7 +626,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
619 ieee80211_tx_status_ni(mvm->hw, skb); 626 ieee80211_tx_status_ni(mvm->hw, skb);
620 } 627 }
621 628
622 if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE) { 629 if (txq_id >= mvm->first_agg_queue) {
623 /* If this is an aggregation queue, we use the ssn since: 630 /* If this is an aggregation queue, we use the ssn since:
624 * ssn = wifi seq_num % 256. 631 * ssn = wifi seq_num % 256.
625 * The seq_ctl is the sequence control of the packet to which 632 * The seq_ctl is the sequence control of the packet to which
@@ -668,10 +675,6 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
668 iwl_mvm_check_ratid_empty(mvm, sta, tid); 675 iwl_mvm_check_ratid_empty(mvm, sta, tid);
669 spin_unlock_bh(&mvmsta->lock); 676 spin_unlock_bh(&mvmsta->lock);
670 } 677 }
671
672#ifdef CONFIG_PM_SLEEP
673 mvmsta->last_seq_ctl = seq_ctl;
674#endif
675 } else { 678 } else {
676 sta = NULL; 679 sta = NULL;
677 mvmsta = NULL; 680 mvmsta = NULL;
@@ -681,7 +684,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
681 * If the txq is not an AMPDU queue, there is no chance we freed 684 * If the txq is not an AMPDU queue, there is no chance we freed
682 * several skbs. Check that out... 685 * several skbs. Check that out...
683 */ 686 */
684 if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && !WARN_ON(skb_freed > 1) && 687 if (txq_id < mvm->first_agg_queue && !WARN_ON(skb_freed > 1) &&
685 atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) { 688 atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) {
686 if (mvmsta) { 689 if (mvmsta) {
687 /* 690 /*
@@ -777,7 +780,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
777 u16 sequence = le16_to_cpu(pkt->hdr.sequence); 780 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
778 struct ieee80211_sta *sta; 781 struct ieee80211_sta *sta;
779 782
780 if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_MVM_FIRST_AGG_QUEUE)) 783 if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < mvm->first_agg_queue))
781 return; 784 return;
782 785
783 if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS)) 786 if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS))
@@ -904,8 +907,8 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
904 info->flags |= IEEE80211_TX_STAT_AMPDU; 907 info->flags |= IEEE80211_TX_STAT_AMPDU;
905 info->status.ampdu_ack_len = ba_notif->txed_2_done; 908 info->status.ampdu_ack_len = ba_notif->txed_2_done;
906 info->status.ampdu_len = ba_notif->txed; 909 info->status.ampdu_len = ba_notif->txed;
907 iwl_mvm_hwrate_to_tx_control(tid_data->rate_n_flags, 910 iwl_mvm_hwrate_to_tx_status(tid_data->rate_n_flags,
908 info); 911 info);
909 } 912 }
910 } 913 }
911 914
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index a9c357491434..ed69e9b78e82 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -466,7 +466,7 @@ void iwl_mvm_dump_sram(struct iwl_mvm *mvm)
466 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset; 466 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
467 len = img->sec[IWL_UCODE_SECTION_DATA].len; 467 len = img->sec[IWL_UCODE_SECTION_DATA].len;
468 468
469 buf = kzalloc(len, GFP_KERNEL); 469 buf = kzalloc(len, GFP_ATOMIC);
470 if (!buf) 470 if (!buf)
471 return; 471 return;
472 472