wifi: iwlwifi: mvm: update IGTK in mvmvif upon D3 resume
[linux-block.git] / drivers / net / wireless / intel / iwlwifi / mvm / mac80211.c
CommitLineData
8e99ea8d
JB
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2/*
207be64f 3 * Copyright (C) 2012-2014, 2018-2023 Intel Corporation
8e99ea8d
JB
4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
5 * Copyright (C) 2016-2017 Intel Deutschland GmbH
6 */
8ca151b5
JB
7#include <linux/kernel.h>
8#include <linux/slab.h>
9#include <linux/skbuff.h>
10#include <linux/netdevice.h>
11#include <linux/etherdevice.h>
f0c2646a 12#include <linux/ip.h>
2ee8f021 13#include <linux/if_arp.h>
2f89a5d7 14#include <linux/time.h>
8ca151b5 15#include <net/mac80211.h>
7b1dd048 16#include <net/ieee80211_radiotap.h>
f0c2646a 17#include <net/tcp.h>
8ca151b5 18
5283dd67 19#include "iwl-drv.h"
8ca151b5
JB
20#include "iwl-op-mode.h"
21#include "iwl-io.h"
22#include "mvm.h"
23#include "sta.h"
24#include "time-event.h"
25#include "iwl-eeprom-parse.h"
8ca151b5 26#include "iwl-phy-db.h"
507cadf2 27#include "testmode.h"
d962f9b1 28#include "fw/error-dump.h"
655e6d6d 29#include "iwl-prph.h"
88931cc9 30#include "iwl-nvm-parse.h"
cf85123a 31#include "time-sync.h"
8ca151b5
JB
32
33static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
34 {
35 .max = 1,
8eb38710 36 .types = BIT(NL80211_IFTYPE_STATION),
8ca151b5 37 },
3c15a0fb
JB
38 {
39 .max = 1,
8eb38710
IP
40 .types = BIT(NL80211_IFTYPE_AP) |
41 BIT(NL80211_IFTYPE_P2P_CLIENT) |
3c15a0fb
JB
42 BIT(NL80211_IFTYPE_P2P_GO),
43 },
44 {
45 .max = 1,
46 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
47 },
8ca151b5
JB
48};
49
50static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
51 {
2624a5ca 52 .num_different_channels = 2,
8ca151b5
JB
53 .max_interfaces = 3,
54 .limits = iwl_mvm_limits,
55 .n_limits = ARRAY_SIZE(iwl_mvm_limits),
56 },
57};
58
fc36ffda
JB
59static const struct cfg80211_pmsr_capabilities iwl_mvm_pmsr_capa = {
60 .max_peers = IWL_MVM_TOF_MAX_APS,
61 .report_ap_tsf = 1,
62 .randomize_mac_addr = 1,
63
64 .ftm = {
65 .supported = 1,
66 .asap = 1,
67 .non_asap = 1,
68 .request_lci = 1,
69 .request_civicloc = 1,
6815e3d0
AS
70 .trigger_based = 1,
71 .non_trigger_based = 1,
fc36ffda
JB
72 .max_bursts_exponent = -1, /* all supported */
73 .max_ftms_per_burst = 0, /* no limits */
74 .bandwidths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
75 BIT(NL80211_CHAN_WIDTH_20) |
76 BIT(NL80211_CHAN_WIDTH_40) |
8a2c1516
AS
77 BIT(NL80211_CHAN_WIDTH_80) |
78 BIT(NL80211_CHAN_WIDTH_160),
fc36ffda
JB
79 .preambles = BIT(NL80211_PREAMBLE_LEGACY) |
80 BIT(NL80211_PREAMBLE_HT) |
6815e3d0
AS
81 BIT(NL80211_PREAMBLE_VHT) |
82 BIT(NL80211_PREAMBLE_HE),
fc36ffda
JB
83 },
84};
85
6569e7d3
JB
86static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
87 enum set_key_cmd cmd,
88 struct ieee80211_vif *vif,
89 struct ieee80211_sta *sta,
90 struct ieee80211_key_conf *key);
c56e00a3 91
fe0f2de3
IP
92static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
93{
94 int i;
95
96 memset(mvm->phy_ctxts, 0, sizeof(mvm->phy_ctxts));
97 for (i = 0; i < NUM_PHY_CTX; i++) {
98 mvm->phy_ctxts[i].id = i;
99 mvm->phy_ctxts[i].ref = 0;
100 }
101}
102
88931cc9 103struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy,
8ba2d7a1 104 const char *alpha2,
47c8b154
JD
105 enum iwl_mcc_source src_id,
106 bool *changed)
88931cc9
AN
107{
108 struct ieee80211_regdomain *regd = NULL;
109 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
110 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
e9b63341 111 struct iwl_mcc_update_resp_v8 *resp;
e27c506a 112 u8 resp_ver;
88931cc9
AN
113
114 IWL_DEBUG_LAR(mvm, "Getting regdomain data for %s from FW\n", alpha2);
115
8ba2d7a1 116 lockdep_assert_held(&mvm->mutex);
88931cc9 117
8ba2d7a1 118 resp = iwl_mvm_update_mcc(mvm, alpha2, src_id);
88931cc9
AN
119 if (IS_ERR_OR_NULL(resp)) {
120 IWL_DEBUG_LAR(mvm, "Could not get update from FW %d\n",
b8c474d9 121 PTR_ERR_OR_ZERO(resp));
6d19a5eb 122 resp = NULL;
8ba2d7a1 123 goto out;
88931cc9
AN
124 }
125
82715ac7
EG
126 if (changed) {
127 u32 status = le32_to_cpu(resp->status);
128
129 *changed = (status == MCC_RESP_NEW_CHAN_PROFILE ||
130 status == MCC_RESP_ILLEGAL);
131 }
e27c506a
GA
132 resp_ver = iwl_fw_lookup_notif_ver(mvm->fw, IWL_ALWAYS_LONG_GROUP,
133 MCC_UPDATE_CMD, 0);
134 IWL_DEBUG_LAR(mvm, "MCC update response version: %d\n", resp_ver);
47c8b154 135
162ee3c9 136 regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg,
88931cc9
AN
137 __le32_to_cpu(resp->n_channels),
138 resp->channels,
77e30e10 139 __le16_to_cpu(resp->mcc),
2763bba6 140 __le16_to_cpu(resp->geo_info),
e9b63341 141 le32_to_cpu(resp->cap), resp_ver);
8ba2d7a1
EH
142 /* Store the return source id */
143 src_id = resp->source_id;
88931cc9
AN
144 if (IS_ERR_OR_NULL(regd)) {
145 IWL_DEBUG_LAR(mvm, "Could not get parse update from FW %d\n",
b8c474d9 146 PTR_ERR_OR_ZERO(regd));
8ba2d7a1 147 goto out;
88931cc9
AN
148 }
149
8ba2d7a1
EH
150 IWL_DEBUG_LAR(mvm, "setting alpha2 from FW to %s (0x%x, 0x%x) src=%d\n",
151 regd->alpha2, regd->alpha2[0], regd->alpha2[1], src_id);
88931cc9 152 mvm->lar_regdom_set = true;
8ba2d7a1 153 mvm->mcc_src = src_id;
88931cc9 154
6d19a5eb
EG
155 iwl_mei_set_country_code(__le16_to_cpu(resp->mcc));
156
8ba2d7a1 157out:
6d19a5eb 158 kfree(resp);
88931cc9
AN
159 return regd;
160}
161
47c8b154
JD
162void iwl_mvm_update_changed_regdom(struct iwl_mvm *mvm)
163{
164 bool changed;
165 struct ieee80211_regdomain *regd;
166
167 if (!iwl_mvm_is_lar_supported(mvm))
168 return;
169
170 regd = iwl_mvm_get_current_regdomain(mvm, &changed);
171 if (!IS_ERR_OR_NULL(regd)) {
172 /* only update the regulatory core if changed */
173 if (changed)
174 regulatory_set_wiphy_regd(mvm->hw->wiphy, regd);
175
176 kfree(regd);
177 }
178}
179
180struct ieee80211_regdomain *iwl_mvm_get_current_regdomain(struct iwl_mvm *mvm,
181 bool *changed)
8ba2d7a1
EH
182{
183 return iwl_mvm_get_regdomain(mvm->hw->wiphy, "ZZ",
184 iwl_mvm_is_wifi_mcc_supported(mvm) ?
185 MCC_SOURCE_GET_CURRENT :
47c8b154 186 MCC_SOURCE_OLD_FW, changed);
8ba2d7a1
EH
187}
188
189int iwl_mvm_init_fw_regd(struct iwl_mvm *mvm)
190{
191 enum iwl_mcc_source used_src;
192 struct ieee80211_regdomain *regd;
b6e160ab
AN
193 int ret;
194 bool changed;
8ba2d7a1 195 const struct ieee80211_regdomain *r =
a05829a7 196 wiphy_dereference(mvm->hw->wiphy, mvm->hw->wiphy->regd);
8ba2d7a1
EH
197
198 if (!r)
b6e160ab 199 return -ENOENT;
8ba2d7a1
EH
200
201 /* save the last source in case we overwrite it below */
202 used_src = mvm->mcc_src;
203 if (iwl_mvm_is_wifi_mcc_supported(mvm)) {
204 /* Notify the firmware we support wifi location updates */
47c8b154 205 regd = iwl_mvm_get_current_regdomain(mvm, NULL);
8ba2d7a1
EH
206 if (!IS_ERR_OR_NULL(regd))
207 kfree(regd);
208 }
209
210 /* Now set our last stored MCC and source */
b6e160ab
AN
211 regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, r->alpha2, used_src,
212 &changed);
8ba2d7a1
EH
213 if (IS_ERR_OR_NULL(regd))
214 return -EIO;
215
b6e160ab
AN
216 /* update cfg80211 if the regdomain was changed */
217 if (changed)
a05829a7 218 ret = regulatory_set_wiphy_regd_sync(mvm->hw->wiphy, regd);
b6e160ab
AN
219 else
220 ret = 0;
8ba2d7a1 221
b6e160ab
AN
222 kfree(regd);
223 return ret;
8ba2d7a1
EH
224}
225
8e33f046 226/* Each capability added here should also be add to tm_if_types_ext_capa_sta */
7f2ea521 227static const u8 he_if_types_ext_capa_sta[] = {
7360f99e 228 [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
918cbf39 229 [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
784d4a42
JB
230 [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF |
231 WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB,
232 [8] = WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB,
7360f99e
EG
233};
234
8e33f046
KP
235static const u8 tm_if_types_ext_capa_sta[] = {
236 [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
237 [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT |
238 WLAN_EXT_CAPA3_TIMING_MEASUREMENT_SUPPORT,
784d4a42
JB
239 [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF |
240 WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB,
241 [8] = WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB,
8e33f046
KP
242 [9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT,
243};
244
245/* Additional interface types for which extended capabilities are
246 * specified separately
247 */
6107f300
EG
248
249#define IWL_MVM_EMLSR_CAPA (IEEE80211_EML_CAP_EMLSR_SUPP | \
250 IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_32US << \
251 __bf_shf(IEEE80211_EML_CAP_EMLSR_PADDING_DELAY) | \
252 IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_64US << \
253 __bf_shf(IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY))
254
8e33f046 255static const struct wiphy_iftype_ext_capab add_iftypes_ext_capa[] = {
7360f99e
EG
256 {
257 .iftype = NL80211_IFTYPE_STATION,
258 .extended_capabilities = he_if_types_ext_capa_sta,
259 .extended_capabilities_mask = he_if_types_ext_capa_sta,
260 .extended_capabilities_len = sizeof(he_if_types_ext_capa_sta),
6107f300
EG
261 /* relevant only if EHT is supported */
262 .eml_capabilities = IWL_MVM_EMLSR_CAPA,
7360f99e 263 },
8e33f046
KP
264 {
265 .iftype = NL80211_IFTYPE_STATION,
266 .extended_capabilities = tm_if_types_ext_capa_sta,
267 .extended_capabilities_mask = tm_if_types_ext_capa_sta,
268 .extended_capabilities_len = sizeof(tm_if_types_ext_capa_sta),
269 /* relevant only if EHT is supported */
6107f300 270 .eml_capabilities = IWL_MVM_EMLSR_CAPA,
8e33f046 271 },
7360f99e
EG
272};
273
cbce62a3 274int iwl_mvm_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
e8503aec
BG
275{
276 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
277 *tx_ant = iwl_mvm_get_valid_tx_ant(mvm);
278 *rx_ant = iwl_mvm_get_valid_rx_ant(mvm);
279 return 0;
280}
281
4ea1ed1d
EG
282int iwl_mvm_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
283{
284 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
285
286 /* This has been tested on those devices only */
287 if (mvm->trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_9000 &&
288 mvm->trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_22000)
289 return -ENOTSUPP;
290
291 if (!mvm->nvm_data)
292 return -EBUSY;
293
294 /* mac80211 ensures the device is not started,
295 * so the firmware cannot be running
296 */
297
298 mvm->set_tx_ant = tx_ant;
299 mvm->set_rx_ant = rx_ant;
300
301 iwl_reinit_cab(mvm->trans, mvm->nvm_data, tx_ant, rx_ant, mvm->fw);
302
303 return 0;
304}
305
8ca151b5
JB
306int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
307{
308 struct ieee80211_hw *hw = mvm->hw;
831e85f3 309 int num_mac, ret, i;
5f4c02e2
JB
310 static const u32 mvm_ciphers[] = {
311 WLAN_CIPHER_SUITE_WEP40,
312 WLAN_CIPHER_SUITE_WEP104,
313 WLAN_CIPHER_SUITE_TKIP,
314 WLAN_CIPHER_SUITE_CCMP,
315 };
3f37c229
IY
316#ifdef CONFIG_PM_SLEEP
317 bool unified = fw_has_capa(&mvm->fw->ucode_capa,
318 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
319#endif
a5de7de7
JB
320 u32 sec_key_id = WIDE_ID(DATA_PATH_GROUP, SEC_KEY_CMD);
321 u8 sec_key_ver = iwl_fw_lookup_cmd_ver(mvm->fw, sec_key_id, 0);
8ca151b5
JB
322
323 /* Tell mac80211 our characteristics */
30686bf7
JB
324 ieee80211_hw_set(hw, SIGNAL_DBM);
325 ieee80211_hw_set(hw, SPECTRUM_MGMT);
326 ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
30686bf7
JB
327 ieee80211_hw_set(hw, WANT_MONITOR_VIF);
328 ieee80211_hw_set(hw, SUPPORTS_PS);
329 ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
330 ieee80211_hw_set(hw, AMPDU_AGGREGATION);
30686bf7
JB
331 ieee80211_hw_set(hw, CONNECTION_MONITOR);
332 ieee80211_hw_set(hw, CHANCTX_STA_CSA);
333 ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
334 ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
909ddf0b 335 ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
30433d3b 336 ieee80211_hw_set(hw, NEEDS_UNIQUE_STA_ADDR);
520229e4 337 ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
cfbc6c4c
SS
338 ieee80211_hw_set(hw, BUFF_MMPDU_TXQ);
339 ieee80211_hw_set(hw, STA_MMPDU_TXQ);
ef2b47b8 340
0120e6b3 341 /* Set this early since we need to have it for the check below */
b3366330
JB
342 if (mvm->mld_api_is_used && mvm->nvm_data->sku_cap_11be_enable &&
343 !iwlwifi_mod_params.disable_11ax &&
344 !iwlwifi_mod_params.disable_11be)
0120e6b3
GG
345 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_MLO;
346
ef2b47b8
JB
347 /* With MLD FW API, it tracks timing by itself,
348 * no need for any timing from the host
349 */
350 if (!mvm->mld_api_is_used)
351 ieee80211_hw_set(hw, TIMING_BEACON_ONLY);
352
353 /* We should probably have this, but mac80211
354 * currently doesn't support it for MLO.
355 */
356 if (!(hw->wiphy->flags & WIPHY_FLAG_SUPPORTS_MLO))
357 ieee80211_hw_set(hw, DEAUTH_NEED_MGD_TX_PREP);
358
cfb21b11
JB
359 /*
360 * On older devices, enabling TX A-MSDU occasionally leads to
361 * something getting messed up, the command read from the FIFO
362 * gets out of sync and isn't a TX command, so that we have an
363 * assert EDC.
364 *
365 * It's not clear where the bug is, but since we didn't used to
366 * support A-MSDU until moving the mac80211 iTXQs, just leave it
367 * for older devices. We also don't see this issue on any newer
368 * devices.
369 */
7d34a7d7 370 if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000)
cfb21b11 371 ieee80211_hw_set(hw, TX_AMSDU);
438af969 372 ieee80211_hw_set(hw, TX_FRAG_LIST);
ecaf71de 373
4243edb4 374 if (iwl_mvm_has_tlc_offload(mvm)) {
ecaf71de
GG
375 ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
376 ieee80211_hw_set(hw, HAS_RATE_CONTROL);
377 }
378
29fa9a98
EG
379 /* We want to use the mac80211's reorder buffer for 9000 */
380 if (iwl_mvm_has_new_rx_api(mvm) &&
381 mvm->trans->trans_cfg->device_family > IWL_DEVICE_FAMILY_9000)
b915c101 382 ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
960f864b
JB
383
384 if (fw_has_capa(&mvm->fw->ucode_capa,
385 IWL_UCODE_TLV_CAPA_STA_PM_NOTIF)) {
65e25482 386 ieee80211_hw_set(hw, AP_LINK_PS);
960f864b
JB
387 } else if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) {
388 /*
389 * we absolutely need this for the new TX API since that comes
390 * with many more queues than the current code can deal with
391 * for station powersave
392 */
393 return -EINVAL;
394 }
8ca151b5 395
80938abc
JB
396 if (mvm->trans->num_rx_queues > 1)
397 ieee80211_hw_set(hw, USES_RSS);
398
2d7cf549
JB
399 if (mvm->trans->max_skb_frags)
400 hw->netdev_features = NETIF_F_HIGHDMA | NETIF_F_SG;
401
366fc672 402 hw->queues = IEEE80211_NUM_ACS;
398e8c6c 403 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
7b1dd048
EG
404 hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FEC |
405 IEEE80211_RADIOTAP_MCS_HAVE_STBC;
339b3086
ES
406 hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC |
407 IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED;
371a17ed
JB
408
409 hw->radiotap_timestamp.units_pos =
410 IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US |
411 IEEE80211_RADIOTAP_TIMESTAMP_SPOS_PLCP_SIG_ACQ;
412 /* this is the case for CCK frames, it's better (only 8) for OFDM */
413 hw->radiotap_timestamp.accuracy = 22;
414
4243edb4 415 if (!iwl_mvm_has_tlc_offload(mvm))
9f66a397
GG
416 hw->rate_control_algorithm = RS_NAME;
417
848955cc
JB
418 hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES;
419 hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
438af969 420 hw->max_tx_fragments = mvm->trans->max_skb_frags;
8ca151b5 421
8e160ab8 422 BUILD_BUG_ON(ARRAY_SIZE(mvm->ciphers) < ARRAY_SIZE(mvm_ciphers) + 6);
5f4c02e2
JB
423 memcpy(mvm->ciphers, mvm_ciphers, sizeof(mvm_ciphers));
424 hw->wiphy->n_cipher_suites = ARRAY_SIZE(mvm_ciphers);
425 hw->wiphy->cipher_suites = mvm->ciphers;
426
2a53d166
AB
427 if (iwl_mvm_has_new_rx_api(mvm)) {
428 mvm->ciphers[hw->wiphy->n_cipher_suites] =
429 WLAN_CIPHER_SUITE_GCMP;
430 hw->wiphy->n_cipher_suites++;
431 mvm->ciphers[hw->wiphy->n_cipher_suites] =
432 WLAN_CIPHER_SUITE_GCMP_256;
433 hw->wiphy->n_cipher_suites++;
434 }
435
f4bfdc5e
EG
436 if (iwlwifi_mod_params.swcrypto)
437 IWL_ERR(mvm,
438 "iwlmvm doesn't allow to disable HW crypto, check swcrypto module parameter\n");
439 if (!iwlwifi_mod_params.bt_coex_active)
440 IWL_ERR(mvm,
441 "iwlmvm doesn't allow to disable BT Coex, check bt_coex_active module parameter\n");
442
443 ieee80211_hw_set(hw, MFP_CAPABLE);
444 mvm->ciphers[hw->wiphy->n_cipher_suites] = WLAN_CIPHER_SUITE_AES_CMAC;
445 hw->wiphy->n_cipher_suites++;
446 if (iwl_mvm_has_new_rx_api(mvm)) {
5f4c02e2 447 mvm->ciphers[hw->wiphy->n_cipher_suites] =
f4bfdc5e
EG
448 WLAN_CIPHER_SUITE_BIP_GMAC_128;
449 hw->wiphy->n_cipher_suites++;
450 mvm->ciphers[hw->wiphy->n_cipher_suites] =
451 WLAN_CIPHER_SUITE_BIP_GMAC_256;
5f4c02e2
JB
452 hw->wiphy->n_cipher_suites++;
453 }
454
ef2e7a51
IP
455 wiphy_ext_feature_set(hw->wiphy,
456 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY);
d16b96b5
JB
457 wiphy_ext_feature_set(hw->wiphy,
458 NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT);
ef2e7a51 459
b73f9a4a 460 if (fw_has_capa(&mvm->fw->ucode_capa,
fc36ffda 461 IWL_UCODE_TLV_CAPA_FTM_CALIBRATED)) {
b73f9a4a
JB
462 wiphy_ext_feature_set(hw->wiphy,
463 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);
fc36ffda
JB
464 hw->wiphy->pmsr_capa = &iwl_mvm_pmsr_capa;
465 }
b73f9a4a 466
a5de7de7
JB
467 if (sec_key_ver &&
468 fw_has_capa(&mvm->fw->ucode_capa,
469 IWL_UCODE_TLV_CAPA_BIGTK_TX_SUPPORT))
470 wiphy_ext_feature_set(hw->wiphy,
471 NL80211_EXT_FEATURE_BEACON_PROTECTION);
472 else if (fw_has_capa(&mvm->fw->ucode_capa,
473 IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT))
b1fdc250
JB
474 wiphy_ext_feature_set(hw->wiphy,
475 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT);
476
cf85123a
AS
477 if (fw_has_capa(&mvm->fw->ucode_capa,
478 IWL_UCODE_TLV_CAPA_TIME_SYNC_BOTH_FTM_TM))
479 hw->wiphy->hw_timestamp_max_peers = 1;
480
30686bf7 481 ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
1f940386
LC
482 hw->wiphy->features |=
483 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
3db93420
JB
484 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR |
485 NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
fb98be5e 486
8ca151b5
JB
487 hw->sta_data_size = sizeof(struct iwl_mvm_sta);
488 hw->vif_data_size = sizeof(struct iwl_mvm_vif);
fe0f2de3 489 hw->chanctx_data_size = sizeof(u16);
cfbc6c4c 490 hw->txq_data_size = sizeof(struct iwl_mvm_txq);
8ca151b5
JB
491
492 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3c15a0fb
JB
493 BIT(NL80211_IFTYPE_P2P_CLIENT) |
494 BIT(NL80211_IFTYPE_AP) |
495 BIT(NL80211_IFTYPE_P2P_GO) |
c13b1725
EG
496 BIT(NL80211_IFTYPE_P2P_DEVICE) |
497 BIT(NL80211_IFTYPE_ADHOC);
5023d966 498
a2f73b6c 499 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
e47df5bd 500 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
33e3fd99
AW
501
502 /* The new Tx API does not allow to pass the key or keyid of a MPDU to
503 * the hw, preventing us to control which key(id) to use per MPDU.
504 * Till that's fixed we can't use Extended Key ID for the newer cards.
505 */
506 if (!iwl_mvm_has_new_tx_api(mvm))
507 wiphy_ext_feature_set(hw->wiphy,
508 NL80211_EXT_FEATURE_EXT_KEY_ID);
e47df5bd
JB
509 hw->wiphy->features |= NL80211_FEATURE_HT_IBSS;
510
8ba2d7a1
EH
511 hw->wiphy->regulatory_flags |= REGULATORY_ENABLE_RELAX_NO_IR;
512 if (iwl_mvm_is_lar_supported(mvm))
513 hw->wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
514 else
515 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
516 REGULATORY_DISABLE_BEACON_HINTS;
8ca151b5 517
4b87e5af 518 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
94bbed72 519 hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
eae94cf8 520 hw->wiphy->flags |= WIPHY_FLAG_SPLIT_SCAN_6GHZ;
bd3398e2 521
8ca151b5
JB
522 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
523 hw->wiphy->n_iface_combinations =
524 ARRAY_SIZE(iwl_mvm_iface_combinations);
525
c451e6d4 526 hw->wiphy->max_remain_on_channel_duration = 10000;
4f1847cf 527 hw->max_listen_interval = IWL_MVM_CONN_LISTEN_INTERVAL;
8ca151b5
JB
528
529 /* Extract MAC address */
530 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
531 hw->wiphy->addresses = mvm->addresses;
532 hw->wiphy->n_addresses = 1;
831e85f3
IP
533
534 /* Extract additional MAC addresses if available */
535 num_mac = (mvm->nvm_data->n_hw_addrs > 1) ?
536 min(IWL_MVM_MAX_ADDRESSES, mvm->nvm_data->n_hw_addrs) : 1;
537
538 for (i = 1; i < num_mac; i++) {
539 memcpy(mvm->addresses[i].addr, mvm->addresses[i-1].addr,
8ca151b5 540 ETH_ALEN);
831e85f3 541 mvm->addresses[i].addr[5]++;
8ca151b5
JB
542 hw->wiphy->n_addresses++;
543 }
544
fe0f2de3
IP
545 iwl_mvm_reset_phy_ctxts(mvm);
546
999d2568 547 hw->wiphy->max_scan_ie_len = iwl_mvm_max_scan_ie_len(mvm);
20f1a5de 548
8ca151b5
JB
549 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
550
c7d42480 551 BUILD_BUG_ON(IWL_MVM_SCAN_STOPPING_MASK & IWL_MVM_SCAN_MASK);
507e4cda
LC
552 BUILD_BUG_ON(IWL_MVM_MAX_UMAC_SCANS > HWEIGHT32(IWL_MVM_SCAN_MASK) ||
553 IWL_MVM_MAX_LMAC_SCANS > HWEIGHT32(IWL_MVM_SCAN_MASK));
554
859d914c 555 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN))
507e4cda
LC
556 mvm->max_scans = IWL_MVM_MAX_UMAC_SCANS;
557 else
558 mvm->max_scans = IWL_MVM_MAX_LMAC_SCANS;
559
57fbcce3
JB
560 if (mvm->nvm_data->bands[NL80211_BAND_2GHZ].n_channels)
561 hw->wiphy->bands[NL80211_BAND_2GHZ] =
562 &mvm->nvm_data->bands[NL80211_BAND_2GHZ];
563 if (mvm->nvm_data->bands[NL80211_BAND_5GHZ].n_channels) {
564 hw->wiphy->bands[NL80211_BAND_5GHZ] =
565 &mvm->nvm_data->bands[NL80211_BAND_5GHZ];
8ca151b5 566
859d914c
JB
567 if (fw_has_capa(&mvm->fw->ucode_capa,
568 IWL_UCODE_TLV_CAPA_BEAMFORMER) &&
569 fw_has_api(&mvm->fw->ucode_capa,
570 IWL_UCODE_TLV_API_LQ_SS_PARAMS))
57fbcce3 571 hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.cap |=
3d44eebf
ES
572 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
573 }
eae94cf8
LC
574 if (fw_has_capa(&mvm->fw->ucode_capa,
575 IWL_UCODE_TLV_CAPA_PSC_CHAN_SUPPORT) &&
576 mvm->nvm_data->bands[NL80211_BAND_6GHZ].n_channels)
577 hw->wiphy->bands[NL80211_BAND_6GHZ] =
578 &mvm->nvm_data->bands[NL80211_BAND_6GHZ];
3d44eebf 579
8ca151b5
JB
580 hw->wiphy->hw_version = mvm->trans->hw_id;
581
ade50652 582 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
8ca151b5
JB
583 hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
584 else
585 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
586
ca986ad9 587 hw->wiphy->max_sched_scan_reqs = 1;
9954b37c 588 hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
5d1234ba 589 hw->wiphy->max_match_sets = iwl_umac_scan_get_max_profiles(mvm->fw);
9954b37c
EG
590 /* we create the 802.11 header and zero length SSID IE. */
591 hw->wiphy->max_sched_scan_ie_len =
592 SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2;
cd55ccea
AS
593 hw->wiphy->max_sched_scan_plans = IWL_MAX_SCHED_SCAN_PLANS;
594 hw->wiphy->max_sched_scan_plan_interval = U16_MAX;
595
596 /*
597 * the firmware uses u8 for num of iterations, but 0xff is saved for
598 * infinite loop, so the maximum number of iterations is actually 254.
599 */
600 hw->wiphy->max_sched_scan_plan_iterations = 254;
35a000b7 601
8ca151b5 602 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
ab480030 603 NL80211_FEATURE_LOW_PRIORITY_SCAN |
0d8614b4 604 NL80211_FEATURE_P2P_GO_OPPPS |
a904a08b 605 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
0d8614b4 606 NL80211_FEATURE_DYNAMIC_SMPS |
9b5452fd
EG
607 NL80211_FEATURE_STATIC_SMPS |
608 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION;
8ca151b5 609
859d914c
JB
610 if (fw_has_capa(&mvm->fw->ucode_capa,
611 IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT))
f1daa00e 612 hw->wiphy->features |= NL80211_FEATURE_TX_POWER_INSERTION;
859d914c
JB
613 if (fw_has_capa(&mvm->fw->ucode_capa,
614 IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT))
226bcd48 615 hw->wiphy->features |= NL80211_FEATURE_QUIET;
f1daa00e 616
859d914c
JB
617 if (fw_has_capa(&mvm->fw->ucode_capa,
618 IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT))
73897bd1
AO
619 hw->wiphy->features |=
620 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES;
621
859d914c
JB
622 if (fw_has_capa(&mvm->fw->ucode_capa,
623 IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT))
73897bd1
AO
624 hw->wiphy->features |= NL80211_FEATURE_WFA_TPC_IE_IN_PROBES;
625
971cbe50 626 if (iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_KEK_KCK_MATERIAL,
2a42aea7
NE
627 IWL_FW_CMD_VER_UNKNOWN) == 3)
628 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK;
629
aacf8f18
AS
630 if (fw_has_api(&mvm->fw->ucode_capa,
631 IWL_UCODE_TLV_API_SCAN_TSF_REPORT)) {
632 wiphy_ext_feature_set(hw->wiphy,
633 NL80211_EXT_FEATURE_SCAN_START_TIME);
634 wiphy_ext_feature_set(hw->wiphy,
635 NL80211_EXT_FEATURE_BSS_PARENT_TSF);
aacf8f18
AS
636 }
637
8f691af9 638 if (iwl_mvm_is_oce_supported(mvm)) {
971cbe50 639 u8 scan_ver = iwl_fw_lookup_cmd_ver(mvm->fw, SCAN_REQ_UMAC, 0);
773a042f 640
8f691af9
ZR
641 wiphy_ext_feature_set(hw->wiphy,
642 NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP);
643 wiphy_ext_feature_set(hw->wiphy,
644 NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME);
8f691af9
ZR
645 wiphy_ext_feature_set(hw->wiphy,
646 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE);
773a042f
AS
647
648 /* Old firmware also supports probe deferral and suppression */
649 if (scan_ver < 15)
650 wiphy_ext_feature_set(hw->wiphy,
651 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION);
8f691af9
ZR
652 }
653
8e33f046
KP
654 hw->wiphy->iftype_ext_capab = NULL;
655 hw->wiphy->num_iftype_ext_capab = 0;
656
7360f99e
EG
657 if (mvm->nvm_data->sku_cap_11ax_enable &&
658 !iwlwifi_mod_params.disable_11ax) {
8e33f046 659 hw->wiphy->iftype_ext_capab = add_iftypes_ext_capa;
7360f99e 660 hw->wiphy->num_iftype_ext_capab =
8e33f046 661 ARRAY_SIZE(add_iftypes_ext_capa) - 1;
918cbf39
SS
662
663 ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
664 ieee80211_hw_set(hw, SUPPORTS_ONLY_HE_MULTI_BSSID);
7360f99e
EG
665 }
666
8e33f046
KP
667 if (iwl_fw_lookup_cmd_ver(mvm->fw,
668 WIDE_ID(DATA_PATH_GROUP,
669 WNM_80211V_TIMING_MEASUREMENT_CONFIG_CMD),
670 IWL_FW_CMD_VER_UNKNOWN) >= 1) {
671 IWL_DEBUG_INFO(mvm->trans, "Timing measurement supported\n");
672
673 if (!hw->wiphy->iftype_ext_capab) {
674 hw->wiphy->num_iftype_ext_capab = 1;
675 hw->wiphy->iftype_ext_capab = add_iftypes_ext_capa +
676 ARRAY_SIZE(add_iftypes_ext_capa) - 1;
677 } else {
678 hw->wiphy->iftype_ext_capab = add_iftypes_ext_capa + 1;
679 }
680 }
681
8ca151b5
JB
682 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
683
684#ifdef CONFIG_PM_SLEEP
3f37c229 685 if ((unified || mvm->fw->img[IWL_UCODE_WOWLAN].num_sec) &&
8ca151b5
JB
686 mvm->trans->ops->d3_suspend &&
687 mvm->trans->ops->d3_resume &&
688 device_can_wakeup(mvm->trans->dev)) {
91742449
EP
689 mvm->wowlan.flags |= WIPHY_WOWLAN_MAGIC_PKT |
690 WIPHY_WOWLAN_DISCONNECT |
691 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
692 WIPHY_WOWLAN_RFKILL_RELEASE |
693 WIPHY_WOWLAN_NET_DETECT;
f4bfdc5e
EG
694 mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
695 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
696 WIPHY_WOWLAN_4WAY_HANDSHAKE;
964dc9e2
JB
697
698 mvm->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
699 mvm->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
700 mvm->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
5d1234ba
TM
701 mvm->wowlan.max_nd_match_sets =
702 iwl_umac_scan_get_max_profiles(mvm->fw);
964dc9e2 703 hw->wiphy->wowlan = &mvm->wowlan;
8ca151b5
JB
704 }
705#endif
706
707 ret = iwl_mvm_leds_init(mvm);
708 if (ret)
709 return ret;
710
859d914c
JB
711 if (fw_has_capa(&mvm->fw->ucode_capa,
712 IWL_UCODE_TLV_CAPA_TDLS_SUPPORT)) {
d8f1c515
AN
713 IWL_DEBUG_TDLS(mvm, "TDLS supported\n");
714 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
7c4f0843 715 ieee80211_hw_set(hw, TDLS_WIDER_BW);
d8f1c515
AN
716 }
717
859d914c
JB
718 if (fw_has_capa(&mvm->fw->ucode_capa,
719 IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH)) {
1d3c3f63
AN
720 IWL_DEBUG_TDLS(mvm, "TDLS channel switch supported\n");
721 hw->wiphy->features |= NL80211_FEATURE_TDLS_CHANNEL_SWITCH;
722 }
723
93190fb0 724 hw->netdev_features |= mvm->cfg->features;
59fa61f3 725 if (!iwl_mvm_is_csum_supported(mvm))
6772aab7 726 hw->netdev_features &= ~IWL_CSUM_NETIF_FLAGS_MASK;
41837ca9 727
91b08c2d
AE
728 if (mvm->cfg->vht_mu_mimo_supported)
729 wiphy_ext_feature_set(hw->wiphy,
730 NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER);
731
9c11d8a9
ST
732 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_PROTECTED_TWT))
733 wiphy_ext_feature_set(hw->wiphy,
734 NL80211_EXT_FEATURE_PROTECTED_TWT);
735
bfcfdb59
EG
736 iwl_mvm_vendor_cmds_register(mvm);
737
e8503aec
BG
738 hw->wiphy->available_antennas_tx = iwl_mvm_get_valid_tx_ant(mvm);
739 hw->wiphy->available_antennas_rx = iwl_mvm_get_valid_rx_ant(mvm);
740
de645e89
JB
741 ret = ieee80211_register_hw(mvm->hw);
742 if (ret) {
743 iwl_mvm_leds_exit(mvm);
de645e89
JB
744 }
745
b7327d89 746 return ret;
8ca151b5
JB
747}
748
df2378ab
JB
749static void iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
750 struct ieee80211_sta *sta)
751{
752 if (likely(sta)) {
753 if (likely(iwl_mvm_tx_skb_sta(mvm, skb, sta) == 0))
754 return;
755 } else {
756 if (likely(iwl_mvm_tx_skb_non_sta(mvm, skb) == 0))
757 return;
758 }
759
760 ieee80211_free_txskb(mvm->hw, skb);
761}
762
cbce62a3
MK
763void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
764 struct ieee80211_tx_control *control, struct sk_buff *skb)
8ca151b5
JB
765{
766 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3e56eadf
JB
767 struct ieee80211_sta *sta = control->sta;
768 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
769 struct ieee80211_hdr *hdr = (void *)skb->data;
cfbc6c4c
SS
770 bool offchannel = IEEE80211_SKB_CB(skb)->flags &
771 IEEE80211_TX_CTL_TX_OFFCHAN;
90723da6
ST
772 u32 link_id = u32_get_bits(info->control.flags,
773 IEEE80211_TX_CTRL_MLO_LINK);
774 struct ieee80211_sta *tmp_sta = sta;
8ca151b5 775
9ee718aa
EL
776 if (iwl_mvm_is_radio_killed(mvm)) {
777 IWL_DEBUG_DROP(mvm, "Dropping - RF/CT KILL\n");
8ca151b5
JB
778 goto drop;
779 }
780
cfbc6c4c 781 if (offchannel &&
a6cc5163
MG
782 !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status) &&
783 !test_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status))
8ca151b5
JB
784 goto drop;
785
10516783
JB
786 /*
787 * bufferable MMPDUs or MMPDUs on STA interfaces come via TXQs
788 * so we treat the others as broadcast
789 */
790 if (ieee80211_is_mgmt(hdr->frame_control))
3e56eadf
JB
791 sta = NULL;
792
dc1aca22 793 /* If there is no sta, and it's not offchannel - send through AP */
cfbc6c4c
SS
794 if (!sta && info->control.vif->type == NL80211_IFTYPE_STATION &&
795 !offchannel) {
dc1aca22
AO
796 struct iwl_mvm_vif *mvmvif =
797 iwl_mvm_vif_from_mac80211(info->control.vif);
650cadb7 798 u8 ap_sta_id = READ_ONCE(mvmvif->deflink.ap_sta_id);
dc1aca22 799
be9ae34e 800 if (ap_sta_id < mvm->fw->ucode_capa.num_stations) {
dc1aca22
AO
801 /* mac80211 holds rcu read lock */
802 sta = rcu_dereference(mvm->fw_id_to_mac_id[ap_sta_id]);
803 if (IS_ERR_OR_NULL(sta))
804 goto drop;
805 }
806 }
807
90723da6
ST
808 if (tmp_sta && !sta && link_id != IEEE80211_LINK_UNSPECIFIED &&
809 !ieee80211_is_probe_resp(hdr->frame_control)) {
810 /* translate MLD addresses to LINK addresses */
811 struct ieee80211_link_sta *link_sta =
812 rcu_dereference(tmp_sta->link[link_id]);
813 struct ieee80211_bss_conf *link_conf =
814 rcu_dereference(info->control.vif->link_conf[link_id]);
815 struct ieee80211_mgmt *mgmt;
816
817 if (WARN_ON(!link_sta || !link_conf))
818 goto drop;
819
820 /* if sta is NULL, the frame is a management frame */
821 mgmt = (void *)hdr;
822 memcpy(mgmt->da, link_sta->addr, ETH_ALEN);
823 memcpy(mgmt->sa, link_conf->addr, ETH_ALEN);
824 memcpy(mgmt->bssid, link_conf->bssid, ETH_ALEN);
825 }
826
df2378ab 827 iwl_mvm_tx_skb(mvm, skb, sta);
8ca151b5
JB
828 return;
829 drop:
830 ieee80211_free_txskb(hw, skb);
831}
832
cfbc6c4c 833void iwl_mvm_mac_itxq_xmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
205e2210 834{
cfbc6c4c
SS
835 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
836 struct iwl_mvm_txq *mvmtxq = iwl_mvm_txq_from_mac80211(txq);
837 struct sk_buff *skb = NULL;
838
fba8248e
SS
839 /*
840 * No need for threads to be pending here, they can leave the first
841 * taker all the work.
842 *
843 * mvmtxq->tx_request logic:
844 *
845 * If 0, no one is currently TXing, set to 1 to indicate current thread
846 * will now start TX and other threads should quit.
847 *
848 * If 1, another thread is currently TXing, set to 2 to indicate to
849 * that thread that there was another request. Since that request may
850 * have raced with the check whether the queue is empty, the TXing
851 * thread should check the queue's status one more time before leaving.
852 * This check is done in order to not leave any TX hanging in the queue
853 * until the next TX invocation (which may not even happen).
854 *
855 * If 2, another thread is currently TXing, and it will already double
856 * check the queue, so do nothing.
857 */
858 if (atomic_fetch_add_unless(&mvmtxq->tx_request, 1, 2))
859 return;
cfbc6c4c
SS
860
861 rcu_read_lock();
fba8248e 862 do {
b58e3d43
JB
863 while (likely(!test_bit(IWL_MVM_TXQ_STATE_STOP_FULL,
864 &mvmtxq->state) &&
865 !test_bit(IWL_MVM_TXQ_STATE_STOP_REDIRECT,
866 &mvmtxq->state) &&
00520b7a 867 !test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status))) {
fba8248e
SS
868 skb = ieee80211_tx_dequeue(hw, txq);
869
f50d693b
SS
870 if (!skb) {
871 if (txq->sta)
872 IWL_DEBUG_TX(mvm,
873 "TXQ of sta %pM tid %d is now empty\n",
874 txq->sta->addr,
875 txq->tid);
fba8248e 876 break;
f50d693b 877 }
fba8248e 878
df2378ab 879 iwl_mvm_tx_skb(mvm, skb, txq->sta);
fba8248e
SS
880 }
881 } while (atomic_dec_return(&mvmtxq->tx_request));
cfbc6c4c 882 rcu_read_unlock();
205e2210
EG
883}
884
cbce62a3
MK
885void iwl_mvm_mac_wake_tx_queue(struct ieee80211_hw *hw,
886 struct ieee80211_txq *txq)
205e2210 887{
cfbc6c4c
SS
888 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
889 struct iwl_mvm_txq *mvmtxq = iwl_mvm_txq_from_mac80211(txq);
205e2210 890
923bf981
JB
891 if (likely(test_bit(IWL_MVM_TXQ_STATE_READY, &mvmtxq->state)) ||
892 !txq->sta) {
cfbc6c4c
SS
893 iwl_mvm_mac_itxq_xmit(hw, txq);
894 return;
895 }
896
923bf981
JB
897 /* iwl_mvm_mac_itxq_xmit() will later be called by the worker
898 * to handle any packets we leave on the txq now
899 */
cfbc6c4c 900
923bf981
JB
901 spin_lock_bh(&mvm->add_stream_lock);
902 /* The list is being deleted only after the queue is fully allocated. */
903 if (list_empty(&mvmtxq->list) &&
904 /* recheck under lock */
905 !test_bit(IWL_MVM_TXQ_STATE_READY, &mvmtxq->state)) {
906 list_add_tail(&mvmtxq->list, &mvm->add_stream_txqs);
907 schedule_work(&mvm->add_stream_wk);
908 }
909 spin_unlock_bh(&mvm->add_stream_lock);
205e2210
EG
910}
911
7174beb6
JB
912#define CHECK_BA_TRIGGER(_mvm, _trig, _tid_bm, _tid, _fmt...) \
913 do { \
914 if (!(le16_to_cpu(_tid_bm) & BIT(_tid))) \
915 break; \
916 iwl_fw_dbg_collect_trig(&(_mvm)->fwrt, _trig, _fmt); \
4203263d
EG
917 } while (0)
918
919static void
920iwl_mvm_ampdu_check_trigger(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
921 struct ieee80211_sta *sta, u16 tid, u16 rx_ba_ssn,
922 enum ieee80211_ampdu_mlme_action action)
923{
924 struct iwl_fw_dbg_trigger_tlv *trig;
925 struct iwl_fw_dbg_trigger_ba *ba_trig;
926
6c042d75
SS
927 trig = iwl_fw_dbg_trigger_on(&mvm->fwrt, ieee80211_vif_to_wdev(vif),
928 FW_DBG_TRIGGER_BA);
929 if (!trig)
4203263d
EG
930 return;
931
4203263d
EG
932 ba_trig = (void *)trig->data;
933
4203263d
EG
934 switch (action) {
935 case IEEE80211_AMPDU_TX_OPERATIONAL: {
936 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
937 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
938
939 CHECK_BA_TRIGGER(mvm, trig, ba_trig->tx_ba_start, tid,
940 "TX AGG START: MAC %pM tid %d ssn %d\n",
941 sta->addr, tid, tid_data->ssn);
942 break;
943 }
944 case IEEE80211_AMPDU_TX_STOP_CONT:
945 CHECK_BA_TRIGGER(mvm, trig, ba_trig->tx_ba_stop, tid,
946 "TX AGG STOP: MAC %pM tid %d\n",
947 sta->addr, tid);
948 break;
949 case IEEE80211_AMPDU_RX_START:
950 CHECK_BA_TRIGGER(mvm, trig, ba_trig->rx_ba_start, tid,
951 "RX AGG START: MAC %pM tid %d ssn %d\n",
952 sta->addr, tid, rx_ba_ssn);
953 break;
954 case IEEE80211_AMPDU_RX_STOP:
955 CHECK_BA_TRIGGER(mvm, trig, ba_trig->rx_ba_stop, tid,
956 "RX AGG STOP: MAC %pM tid %d\n",
957 sta->addr, tid);
958 break;
959 default:
960 break;
961 }
962}
963
cbce62a3
MK
964int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
965 struct ieee80211_vif *vif,
966 struct ieee80211_ampdu_params *params)
8ca151b5
JB
967{
968 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
969 int ret;
50ea05ef
SS
970 struct ieee80211_sta *sta = params->sta;
971 enum ieee80211_ampdu_mlme_action action = params->action;
972 u16 tid = params->tid;
973 u16 *ssn = &params->ssn;
514c3069 974 u16 buf_size = params->buf_size;
bb81bb68 975 bool amsdu = params->amsdu;
10b2b201 976 u16 timeout = params->timeout;
8ca151b5
JB
977
978 IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n",
979 sta->addr, tid, action);
980
981 if (!(mvm->nvm_data->sku_cap_11n_enable))
982 return -EACCES;
983
984 mutex_lock(&mvm->mutex);
985
986 switch (action) {
987 case IEEE80211_AMPDU_RX_START:
650cadb7 988 if (iwl_mvm_vif_from_mac80211(vif)->deflink.ap_sta_id ==
c8ee33e1 989 iwl_mvm_sta_from_mac80211(sta)->deflink.sta_id) {
b0ffe455
JB
990 struct iwl_mvm_vif *mvmvif;
991 u16 macid = iwl_mvm_vif_from_mac80211(vif)->id;
992 struct iwl_mvm_tcm_mac *mdata = &mvm->tcm.data[macid];
993
994 mdata->opened_rx_ba_sessions = true;
995 mvmvif = iwl_mvm_vif_from_mac80211(vif);
996 cancel_delayed_work(&mvmvif->uapsd_nonagg_detected_wk);
997 }
e78da25e 998 if (!iwl_enable_rx_ampdu()) {
8ca151b5
JB
999 ret = -EINVAL;
1000 break;
1001 }
10b2b201
SS
1002 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, *ssn, true, buf_size,
1003 timeout);
8ca151b5
JB
1004 break;
1005 case IEEE80211_AMPDU_RX_STOP:
10b2b201
SS
1006 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false, buf_size,
1007 timeout);
8ca151b5
JB
1008 break;
1009 case IEEE80211_AMPDU_TX_START:
e78da25e 1010 if (!iwl_enable_tx_ampdu()) {
5d158efa
EG
1011 ret = -EINVAL;
1012 break;
1013 }
8ca151b5
JB
1014 ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn);
1015 break;
1016 case IEEE80211_AMPDU_TX_STOP_CONT:
e3d9e7ce
EG
1017 ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid);
1018 break;
8ca151b5
JB
1019 case IEEE80211_AMPDU_TX_STOP_FLUSH:
1020 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
e3d9e7ce 1021 ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid);
8ca151b5
JB
1022 break;
1023 case IEEE80211_AMPDU_TX_OPERATIONAL:
bb81bb68
EG
1024 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid,
1025 buf_size, amsdu);
8ca151b5
JB
1026 break;
1027 default:
1028 WARN_ON_ONCE(1);
1029 ret = -EINVAL;
1030 break;
1031 }
4203263d
EG
1032
1033 if (!ret) {
1034 u16 rx_ba_ssn = 0;
1035
1036 if (action == IEEE80211_AMPDU_RX_START)
1037 rx_ba_ssn = *ssn;
1038
1039 iwl_mvm_ampdu_check_trigger(mvm, vif, sta, tid,
1040 rx_ba_ssn, action);
1041 }
8ca151b5
JB
1042 mutex_unlock(&mvm->mutex);
1043
1044 return ret;
1045}
1046
1047static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
1048 struct ieee80211_vif *vif)
1049{
1050 struct iwl_mvm *mvm = data;
1051 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
bf976c81 1052 struct iwl_probe_resp_data *probe_data;
79faae3a 1053 unsigned int link_id;
8ca151b5
JB
1054
1055 mvmvif->uploaded = false;
8ca151b5 1056
8ca151b5
JB
1057 spin_lock_bh(&mvm->time_event_lock);
1058 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
1059 spin_unlock_bh(&mvm->time_event_lock);
1060
8a275bad 1061 memset(&mvmvif->bf_data, 0, sizeof(mvmvif->bf_data));
828c79d9 1062 mvmvif->ap_sta = NULL;
79faae3a
GG
1063
1064 for_each_mvm_vif_valid_link(mvmvif, link_id) {
1065 mvmvif->link[link_id]->ap_sta_id = IWL_MVM_INVALID_STA;
1066 mvmvif->link[link_id]->fw_link_id = IWL_MVM_FW_LINK_ID_INVALID;
1067 mvmvif->link[link_id]->phy_ctxt = NULL;
bf976c81 1068 mvmvif->link[link_id]->active = 0;
d615ea32 1069 mvmvif->link[link_id]->igtk = NULL;
79faae3a 1070 }
bf976c81
JB
1071
1072 probe_data = rcu_dereference_protected(mvmvif->deflink.probe_resp_data,
1073 lockdep_is_held(&mvm->mutex));
1074 if (probe_data)
1075 kfree_rcu(probe_data, rcu_head);
1076 RCU_INIT_POINTER(mvmvif->deflink.probe_resp_data, NULL);
8ca151b5
JB
1077}
1078
1079static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
1080{
fcb6b92a 1081 iwl_mvm_stop_device(mvm);
8ca151b5 1082
9bf13bee
JB
1083 mvm->cur_aid = 0;
1084
9af91f46 1085 mvm->scan_status = 0;
b1873300 1086 mvm->ps_disabled = false;
b3500b47 1087 mvm->rfkill_safe_init_done = false;
8ca151b5
JB
1088
1089 /* just in case one was running */
305d236e 1090 iwl_mvm_cleanup_roc_te(mvm);
8ca151b5
JB
1091 ieee80211_remain_on_channel_expired(mvm->hw);
1092
fc36ffda
JB
1093 iwl_mvm_ftm_restart(mvm);
1094
737719fe
AN
1095 /*
1096 * cleanup all interfaces, even inactive ones, as some might have
1097 * gone down during the HW restart
1098 */
1099 ieee80211_iterate_interfaces(mvm->hw, 0, iwl_mvm_cleanup_iterator, mvm);
8ca151b5 1100
fe0f2de3
IP
1101 mvm->p2p_device_vif = NULL;
1102
1103 iwl_mvm_reset_phy_ctxts(mvm);
9c3deeb5 1104 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
8a275bad 1105 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
8a275bad 1106 memset(&mvm->last_bt_ci_cmd, 0, sizeof(mvm->last_bt_ci_cmd));
8ca151b5
JB
1107
1108 ieee80211_wake_queues(mvm->hw);
1109
113a0447 1110 mvm->rx_ba_sessions = 0;
7174beb6 1111 mvm->fwrt.dump.conf = FW_DBG_INVALID;
baf41bc3 1112 mvm->monitor_on = false;
fb40cd9d
MK
1113#ifdef CONFIG_IWLWIFI_DEBUGFS
1114 mvm->beacon_inject_active = false;
1115#endif
91a8bcde
JB
1116
1117 /* keep statistics ticking */
1118 iwl_mvm_accu_radio_stats(mvm);
8ca151b5
JB
1119}
1120
a0a09243 1121int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
8ca151b5 1122{
8ca151b5
JB
1123 int ret;
1124
a0a09243 1125 lockdep_assert_held(&mvm->mutex);
8ca151b5 1126
6d19a5eb
EG
1127 ret = iwl_mvm_mei_get_ownership(mvm);
1128 if (ret)
1129 return ret;
1130
1131 if (mvm->mei_nvm_data) {
1132 /* We got the NIC, we can now free the MEI NVM data */
1133 kfree(mvm->mei_nvm_data);
1134 mvm->mei_nvm_data = NULL;
1135
1136 /*
1137 * We can't free the nvm_data we allocated based on the SAP
1138 * data because we registered to cfg80211 with the channels
1139 * allocated on mvm->nvm_data. Keep a pointer in temp_nvm_data
1140 * just in order to be able free it later.
1141 * NULLify nvm_data so that we will read the NVM from the
1142 * firmware this time.
1143 */
1144 mvm->temp_nvm_data = mvm->nvm_data;
1145 mvm->nvm_data = NULL;
1146 }
1147
bf8b286f
JB
1148 if (test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status)) {
1149 /*
1150 * Now convert the HW_RESTART_REQUESTED flag to IN_HW_RESTART
1151 * so later code will - from now on - see that we're doing it.
1152 */
1153 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
1154 clear_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
a42b2af3 1155 /* Clean up some internal and mac80211 state on restart */
8ca151b5 1156 iwl_mvm_restart_cleanup(mvm);
a42b2af3 1157 }
8ca151b5 1158 ret = iwl_mvm_up(mvm);
c47af22a 1159
b108d8c7
SM
1160 iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_POST_INIT,
1161 NULL);
1162 iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_PERIODIC,
1163 NULL);
da2eb669 1164
e8fe3b41
IP
1165 mvm->last_reset_or_resume_time_jiffies = jiffies;
1166
c47af22a
JB
1167 if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
1168 /* Something went wrong - we need to finish some cleanup
1169 * that normally iwl_mvm_mac_restart_complete() below
1170 * would do.
1171 */
1172 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
c47af22a
JB
1173 }
1174
a0a09243
LC
1175 return ret;
1176}
1177
cbce62a3 1178int iwl_mvm_mac_start(struct ieee80211_hw *hw)
a0a09243
LC
1179{
1180 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1181 int ret;
5283dd67 1182 int retry, max_retry = 0;
a0a09243
LC
1183
1184 mutex_lock(&mvm->mutex);
5283dd67
MG
1185
1186 /* we are starting the mac not in error flow, and restart is enabled */
1187 if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) &&
1188 iwlwifi_mod_params.fw_restart) {
1189 max_retry = IWL_MAX_INIT_RETRY;
1190 /*
1191 * This will prevent mac80211 recovery flows to trigger during
1192 * init failures
1193 */
1194 set_bit(IWL_MVM_STATUS_STARTING, &mvm->status);
1195 }
1196
1197 for (retry = 0; retry <= max_retry; retry++) {
1198 ret = __iwl_mvm_mac_start(mvm);
bdd94061 1199 if (!ret || mvm->pldr_sync)
5283dd67
MG
1200 break;
1201
1202 IWL_ERR(mvm, "mac start retry %d\n", retry);
1203 }
1204 clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status);
1205
8ca151b5
JB
1206 mutex_unlock(&mvm->mutex);
1207
7ce1f215
EG
1208 iwl_mvm_mei_set_sw_rfkill_state(mvm);
1209
8ca151b5
JB
1210 return ret;
1211}
1212
cf2c92d8 1213static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
8ca151b5 1214{
8ca151b5
JB
1215 int ret;
1216
1217 mutex_lock(&mvm->mutex);
1218
1219 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
4d4183c4 1220
e7afe89f 1221 ret = iwl_mvm_update_quotas(mvm, true, NULL);
8ca151b5
JB
1222 if (ret)
1223 IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
1224 ret);
1225
f130bb75
MG
1226 iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_END_OF_RECOVERY);
1227
cbd2ae2d
AN
1228 /*
1229 * If we have TDLS peers, remove them. We don't know the last seqno/PN
1230 * of packets the FW sent out, so we must reconnect.
1231 */
1232 iwl_mvm_teardown_tdls_peers(mvm);
1233
8ca151b5
JB
1234 mutex_unlock(&mvm->mutex);
1235}
1236
cbce62a3
MK
1237void iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw,
1238 enum ieee80211_reconfig_type reconfig_type)
cf2c92d8
EP
1239{
1240 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1241
1242 switch (reconfig_type) {
1243 case IEEE80211_RECONFIG_TYPE_RESTART:
1244 iwl_mvm_restart_complete(mvm);
1245 break;
1246 case IEEE80211_RECONFIG_TYPE_SUSPEND:
1247 break;
1248 }
1249}
1250
a0a09243 1251void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
8ca151b5 1252{
a0a09243 1253 lockdep_assert_held(&mvm->mutex);
7498cf4c 1254
b68bd2e3
IP
1255 iwl_mvm_ftm_initiator_smooth_stop(mvm);
1256
91a8bcde
JB
1257 /* firmware counters are obviously reset now, but we shouldn't
1258 * partially track so also clear the fw_reset_accu counters.
1259 */
1260 memset(&mvm->accu_radio_stats, 0, sizeof(mvm->accu_radio_stats));
1261
8ca151b5
JB
1262 /* async_handlers_wk is now blocked */
1263
1724fc78 1264 if (!iwl_mvm_has_new_station_api(mvm->fw))
2c2c3647 1265 iwl_mvm_rm_aux_sta(mvm);
f327236d 1266
fcb6b92a 1267 iwl_mvm_stop_device(mvm);
8ca151b5
JB
1268
1269 iwl_mvm_async_handlers_purge(mvm);
1270 /* async_handlers_list is empty and will stay empty: HW is stopped */
1271
0a79a0c0 1272 /*
155f7e04
EG
1273 * Clear IN_HW_RESTART and HW_RESTART_REQUESTED flag when stopping the
1274 * hw (as restart_complete() won't be called in this case) and mac80211
1275 * won't execute the restart.
8b2b9fbf
AN
1276 * But make sure to cleanup interfaces that have gone down before/during
1277 * HW restart was requested.
0a79a0c0 1278 */
155f7e04
EG
1279 if (test_and_clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) ||
1280 test_and_clear_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
1281 &mvm->status))
8b2b9fbf
AN
1282 ieee80211_iterate_interfaces(mvm->hw, 0,
1283 iwl_mvm_cleanup_iterator, mvm);
0a79a0c0 1284
963221be
AB
1285 /* We shouldn't have any UIDs still set. Loop over all the UIDs to
1286 * make sure there's nothing left there and warn if any is found.
1287 */
859d914c 1288 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
963221be
AB
1289 int i;
1290
507e4cda 1291 for (i = 0; i < mvm->max_scans; i++) {
6185af2a
LC
1292 if (WARN_ONCE(mvm->scan_uid_status[i],
1293 "UMAC scan UID %d status was not cleaned\n",
1294 i))
1295 mvm->scan_uid_status[i] = 0;
963221be
AB
1296 }
1297 }
a0a09243 1298}
bc44886d 1299
cbce62a3 1300void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
a0a09243
LC
1301{
1302 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1303
a0a09243 1304 flush_work(&mvm->async_handlers_wk);
24afba76 1305 flush_work(&mvm->add_stream_wk);
771147b0
JB
1306
1307 /*
1308 * Lock and clear the firmware running bit here already, so that
1309 * new commands coming in elsewhere, e.g. from debugfs, will not
1310 * be able to proceed. This is important here because one of those
7174beb6 1311 * debugfs files causes the firmware dump to be triggered, and if we
771147b0
JB
1312 * don't stop debugfs accesses before canceling that it could be
1313 * retriggered after we flush it but before we've cleared the bit.
1314 */
1315 clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status);
1316
d3a108a4 1317 cancel_delayed_work_sync(&mvm->cs_tx_unblock_dwork);
69e04642 1318 cancel_delayed_work_sync(&mvm->scan_timeout_dwork);
a0a09243 1319
f9084775
NE
1320 /*
1321 * The work item could be running or queued if the
1322 * ROC time event stops just as we get here.
1323 */
1324 flush_work(&mvm->roc_done_wk);
1325
7ce1f215
EG
1326 iwl_mvm_mei_set_sw_rfkill_state(mvm);
1327
a0a09243
LC
1328 mutex_lock(&mvm->mutex);
1329 __iwl_mvm_mac_stop(mvm);
8ca151b5
JB
1330 mutex_unlock(&mvm->mutex);
1331
1332 /*
1333 * The worker might have been waiting for the mutex, let it run and
1334 * discover that its list is now empty.
1335 */
1336 cancel_work_sync(&mvm->async_handlers_wk);
1337}
1338
1ab26632 1339struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
fe0f2de3
IP
1340{
1341 u16 i;
1342
1343 lockdep_assert_held(&mvm->mutex);
1344
1345 for (i = 0; i < NUM_PHY_CTX; i++)
1346 if (!mvm->phy_ctxts[i].ref)
1347 return &mvm->phy_ctxts[i];
1348
1349 IWL_ERR(mvm, "No available PHY context\n");
1350 return NULL;
1351}
1352
f551d013
GG
1353int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1354 s16 tx_power)
d44c3fe6 1355{
971cbe50 1356 u32 cmd_id = REDUCE_TX_POWER_CMD;
0791c2fc 1357 int len;
216cdfb5
LC
1358 struct iwl_dev_tx_power_cmd cmd = {
1359 .common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC),
1360 .common.mac_context_id =
d44c3fe6 1361 cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id),
216cdfb5 1362 .common.pwr_restriction = cpu_to_le16(8 * tx_power),
d44c3fe6 1363 };
971cbe50 1364 u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id,
e80bfd11 1365 IWL_FW_CMD_VER_UNKNOWN);
d44c3fe6 1366
d44c3fe6 1367 if (tx_power == IWL_DEFAULT_MAX_TX_POWER)
216cdfb5 1368 cmd.common.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER);
d44c3fe6 1369
b0aa02b3
AB
1370 if (cmd_ver == 7)
1371 len = sizeof(cmd.v7);
1372 else if (cmd_ver == 6)
fbb7957d
LC
1373 len = sizeof(cmd.v6);
1374 else if (fw_has_api(&mvm->fw->ucode_capa,
1375 IWL_UCODE_TLV_API_REDUCE_TX_POWER))
0791c2fc
HD
1376 len = sizeof(cmd.v5);
1377 else if (fw_has_capa(&mvm->fw->ucode_capa,
1378 IWL_UCODE_TLV_CAPA_TX_POWER_ACK))
1379 len = sizeof(cmd.v4);
1380 else
216cdfb5
LC
1381 len = sizeof(cmd.v3);
1382
1383 /* all structs have the same common part, add it */
1384 len += sizeof(cmd.common);
da03f029 1385
971cbe50 1386 return iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, len, &cmd);
d44c3fe6
AA
1387}
1388
03117f30 1389int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
a469a593
EG
1390 struct ieee80211_vif *vif,
1391 struct ieee80211_bss_conf *link_conf)
f6780614
SS
1392{
1393 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1394 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1395 int ret;
1396
1397 mutex_lock(&mvm->mutex);
1398
f6780614
SS
1399 if (vif->type == NL80211_IFTYPE_STATION) {
1400 struct iwl_mvm_sta *mvmsta;
3723c7c5
EG
1401 unsigned int link_id = link_conf->link_id;
1402 u8 ap_sta_id = mvmvif->link[link_id]->ap_sta_id;
f6780614
SS
1403
1404 mvmvif->csa_bcn_pending = false;
3723c7c5 1405 mvmsta = iwl_mvm_sta_from_staid_protected(mvm, ap_sta_id);
f6780614
SS
1406
1407 if (WARN_ON(!mvmsta)) {
1408 ret = -EIO;
1409 goto out_unlock;
1410 }
1411
df720373 1412 iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
03117f30
MK
1413 if (mvm->mld_api_is_used)
1414 iwl_mvm_mld_mac_ctxt_changed(mvm, vif, false);
1415 else
1416 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
f6780614 1417
0202bcf0
EG
1418 if (!fw_has_capa(&mvm->fw->ucode_capa,
1419 IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
1420 ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
1421 if (ret)
1422 goto out_unlock;
f6780614 1423
0202bcf0
EG
1424 iwl_mvm_stop_session_protection(mvm, vif);
1425 }
f6780614
SS
1426 }
1427
1428 mvmvif->ps_disabled = false;
1429
1430 ret = iwl_mvm_power_update_ps(mvm);
1431
1432out_unlock:
caf46377
SS
1433 if (mvmvif->csa_failed)
1434 ret = -EIO;
f6780614
SS
1435 mutex_unlock(&mvm->mutex);
1436
1437 return ret;
1438}
1439
cbce62a3
MK
1440void iwl_mvm_abort_channel_switch(struct ieee80211_hw *hw,
1441 struct ieee80211_vif *vif)
f6780614
SS
1442{
1443 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1444 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1445 struct iwl_chan_switch_te_cmd cmd = {
1446 .mac_id = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
1447 mvmvif->color)),
1448 .action = cpu_to_le32(FW_CTXT_ACTION_REMOVE),
1449 };
1450
ad12b231
NE
1451 /*
1452 * In the new flow since FW is in charge of the timing,
1453 * if driver has canceled the channel switch he will receive the
1454 * CHANNEL_SWITCH_START_NOTIF notification from FW and then cancel it
1455 */
1456 if (iwl_fw_lookup_notif_ver(mvm->fw, MAC_CONF_GROUP,
1457 CHANNEL_SWITCH_ERROR_NOTIF, 0))
1458 return;
1459
f6780614
SS
1460 IWL_DEBUG_MAC80211(mvm, "Abort CSA on mac %d\n", mvmvif->id);
1461
1462 mutex_lock(&mvm->mutex);
58ddd9b6
EG
1463 if (!fw_has_capa(&mvm->fw->ucode_capa,
1464 IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
1465 iwl_mvm_remove_csa_period(mvm, vif);
1466 else
1467 WARN_ON(iwl_mvm_send_cmd_pdu(mvm,
1468 WIDE_ID(MAC_CONF_GROUP,
1469 CHANNEL_SWITCH_TIME_EVENT_CMD),
1470 0, sizeof(cmd), &cmd));
caf46377 1471 mvmvif->csa_failed = true;
f6780614
SS
1472 mutex_unlock(&mvm->mutex);
1473
a469a593
EG
1474 /* If we're here, we can't support MLD */
1475 iwl_mvm_post_channel_switch(hw, vif, &vif->bss_conf);
f6780614
SS
1476}
1477
1ab26632 1478void iwl_mvm_channel_switch_disconnect_wk(struct work_struct *wk)
f6780614 1479{
f6780614
SS
1480 struct iwl_mvm_vif *mvmvif;
1481 struct ieee80211_vif *vif;
1482
1483 mvmvif = container_of(wk, struct iwl_mvm_vif, csa_work.work);
1484 vif = container_of((void *)mvmvif, struct ieee80211_vif, drv_priv);
f6780614 1485
70162580 1486 /* Trigger disconnect (should clear the CSA state) */
a469a593 1487 ieee80211_chswitch_done(vif, false, 0);
f6780614
SS
1488}
1489
5abf3154
MG
1490static u8
1491iwl_mvm_chandef_get_primary_80(struct cfg80211_chan_def *chandef)
1492{
1493 int data_start;
1494 int control_start;
1495 int bw;
1496
1497 if (chandef->width == NL80211_CHAN_WIDTH_320)
1498 bw = 320;
1499 else if (chandef->width == NL80211_CHAN_WIDTH_160)
1500 bw = 160;
1501 else
1502 return 0;
1503
1504 /* data is bw wide so the start is half the width */
1505 data_start = chandef->center_freq1 - bw / 2;
1506 /* control is 20Mhz width */
1507 control_start = chandef->chan->center_freq - 10;
1508
1509 return (control_start - data_start) / 80;
1510}
1511
1be4858e
JB
1512static int iwl_mvm_alloc_bcast_mcast_sta(struct iwl_mvm *mvm,
1513 struct ieee80211_vif *vif)
8ca151b5 1514{
8ca151b5 1515 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1be4858e 1516 int ret;
1ab26632
MK
1517
1518 lockdep_assert_held(&mvm->mutex);
8ca151b5 1519
1be4858e
JB
1520 ret = iwl_mvm_alloc_bcast_sta(mvm, vif);
1521 if (ret) {
1522 IWL_ERR(mvm, "Failed to allocate bcast sta\n");
1523 return ret;
1524 }
1525
1526 /* Only queue for this station is the mcast queue,
1527 * which shouldn't be in TFD mask anyway
1528 */
1529 return iwl_mvm_allocate_int_sta(mvm, &mvmvif->deflink.mcast_sta, 0,
1530 vif->type,
1531 IWL_STA_MULTICAST);
1532}
1533
1534static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
1535 struct ieee80211_vif *vif)
1536{
1537 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1538 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1539 int ret;
1540
1541 mutex_lock(&mvm->mutex);
1542
aa5e1832 1543 mvmvif->mvm = mvm;
650cadb7
GG
1544
1545 /* the first link always points to the default one */
1546 mvmvif->link[0] = &mvmvif->deflink;
aa5e1832 1547
8ca151b5
JB
1548 /*
1549 * Not much to do here. The stack will not allow interface
1550 * types or combinations that we didn't advertise, so we
1551 * don't really have to check the types.
1552 */
1553
33cef925
JB
1554 /* make sure that beacon statistics don't go backwards with FW reset */
1555 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
650cadb7
GG
1556 mvmvif->deflink.beacon_stats.accu_num_beacons +=
1557 mvmvif->deflink.beacon_stats.num_beacons;
33cef925 1558
e89044d7 1559 /* Allocate resources for the MAC context, and add it to the fw */
1be4858e
JB
1560 ret = iwl_mvm_mac_ctxt_init(mvm, vif);
1561 if (ret)
1562 goto out;
8ca151b5 1563
698478c4
SS
1564 rcu_assign_pointer(mvm->vif_id_to_mac[mvmvif->id], vif);
1565
1be4858e
JB
1566 /* Currently not much to do for NAN */
1567 if (vif->type == NL80211_IFTYPE_NAN) {
1568 ret = 0;
1569 goto out;
1570 }
1571
8ca151b5
JB
1572 /*
1573 * The AP binding flow can be done only after the beacon
1574 * template is configured (which happens only in the mac80211
1575 * start_ap() flow), and adding the broadcast station can happen
1576 * only after the binding.
1577 * In addition, since modifying the MAC before adding a bcast
1578 * station is not allowed by the FW, delay the adding of MAC context to
1579 * the point where we can also add the bcast station.
1580 * In short: there's not much we can do at this point, other than
1581 * allocating resources :)
1582 */
5023d966
JB
1583 if (vif->type == NL80211_IFTYPE_AP ||
1584 vif->type == NL80211_IFTYPE_ADHOC) {
c36235ac 1585 iwl_mvm_vif_dbgfs_add_link(mvm, vif);
1be4858e
JB
1586 ret = 0;
1587 goto out;
8ca151b5
JB
1588 }
1589
93190fb0
AA
1590 mvmvif->features |= hw->netdev_features;
1591
8ca151b5
JB
1592 ret = iwl_mvm_mac_ctxt_add(mvm, vif);
1593 if (ret)
98c0de7b 1594 goto out_unlock;
8ca151b5 1595
999609f1 1596 ret = iwl_mvm_power_update_mac(mvm);
e5e7aa8e 1597 if (ret)
fd66fc1c 1598 goto out_remove_mac;
8ca151b5 1599
7df15b1e 1600 /* beacon filtering */
a1022927 1601 ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
bd3351ba
EP
1602 if (ret)
1603 goto out_remove_mac;
1604
7df15b1e 1605 if (!mvm->bf_allowed_vif &&
73e5f2c5 1606 vif->type == NL80211_IFTYPE_STATION && !vif->p2p) {
7df15b1e 1607 mvm->bf_allowed_vif = mvmvif;
a20fd398
AO
1608 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
1609 IEEE80211_VIF_SUPPORTS_CQM_RSSI;
7df15b1e
HG
1610 }
1611
84ef7cbe 1612 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
8ca151b5 1613 mvm->p2p_device_vif = vif;
8ca151b5 1614
b0ffe455 1615 iwl_mvm_tcm_add_vif(mvm, vif);
f6780614
SS
1616 INIT_DELAYED_WORK(&mvmvif->csa_work,
1617 iwl_mvm_channel_switch_disconnect_wk);
b0ffe455 1618
5abf3154 1619 if (vif->type == NL80211_IFTYPE_MONITOR) {
baf41bc3 1620 mvm->monitor_on = true;
5abf3154
MG
1621 mvm->monitor_p80 =
1622 iwl_mvm_chandef_get_primary_80(&vif->bss_conf.chandef);
1623 }
baf41bc3 1624
c36235ac 1625 iwl_mvm_vif_dbgfs_add_link(mvm, vif);
6d19a5eb
EG
1626
1627 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
1628 vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
1629 !mvm->csme_vif && mvm->mei_registered) {
1630 iwl_mei_set_nic_info(vif->addr, mvm->nvm_data->hw_addr);
1631 iwl_mei_set_netdev(ieee80211_vif_to_wdev(vif)->netdev);
1632 mvm->csme_vif = vif;
1633 }
1634
1ab26632
MK
1635out:
1636 if (!ret && (vif->type == NL80211_IFTYPE_AP ||
1637 vif->type == NL80211_IFTYPE_ADHOC))
1638 ret = iwl_mvm_alloc_bcast_mcast_sta(mvm, vif);
1639
8ca151b5
JB
1640 goto out_unlock;
1641
8ca151b5 1642 out_remove_mac:
650cadb7 1643 mvmvif->deflink.phy_ctxt = NULL;
8ca151b5 1644 iwl_mvm_mac_ctxt_remove(mvm, vif);
8ca151b5
JB
1645 out_unlock:
1646 mutex_unlock(&mvm->mutex);
1647
1648 return ret;
1649}
1650
cb145863
JB
1651void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
1652 struct ieee80211_vif *vif)
8ca151b5 1653{
8ca151b5
JB
1654 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
1655 /*
1656 * Flush the ROC worker which will flush the OFFCHANNEL queue.
1657 * We assume here that all the packets sent to the OFFCHANNEL
1658 * queue are sent in ROC session.
1659 */
1660 flush_work(&mvm->roc_done_wk);
8ca151b5 1661 }
38a12b5b
JB
1662}
1663
60efeca1
MK
1664/* This function is doing the common part of removing the interface for
1665 * both - MLD and non-MLD modes. Returns true if removing the interface
1666 * is done
1667 */
cb145863
JB
1668static bool iwl_mvm_mac_remove_interface_common(struct ieee80211_hw *hw,
1669 struct ieee80211_vif *vif)
38a12b5b
JB
1670{
1671 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1672 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
86e177d8 1673 struct iwl_probe_resp_data *probe_data;
38a12b5b
JB
1674
1675 iwl_mvm_prepare_mac_removal(mvm, vif);
8ca151b5 1676
b0ffe455
JB
1677 if (!(vif->type == NL80211_IFTYPE_AP ||
1678 vif->type == NL80211_IFTYPE_ADHOC))
1679 iwl_mvm_tcm_rm_vif(mvm, vif);
1680
8ca151b5
JB
1681 mutex_lock(&mvm->mutex);
1682
6d19a5eb
EG
1683 if (vif == mvm->csme_vif) {
1684 iwl_mei_set_netdev(NULL);
1685 mvm->csme_vif = NULL;
1686 }
1687
650cadb7 1688 probe_data = rcu_dereference_protected(mvmvif->deflink.probe_resp_data,
86e177d8 1689 lockdep_is_held(&mvm->mutex));
650cadb7 1690 RCU_INIT_POINTER(mvmvif->deflink.probe_resp_data, NULL);
86e177d8
GG
1691 if (probe_data)
1692 kfree_rcu(probe_data, rcu_head);
1693
7df15b1e
HG
1694 if (mvm->bf_allowed_vif == mvmvif) {
1695 mvm->bf_allowed_vif = NULL;
a20fd398
AO
1696 vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER |
1697 IEEE80211_VIF_SUPPORTS_CQM_RSSI);
7df15b1e
HG
1698 }
1699
b73f9a4a
JB
1700 if (vif->bss_conf.ftm_responder)
1701 memset(&mvm->ftm_resp_stats, 0, sizeof(mvm->ftm_resp_stats));
1702
c36235ac 1703 iwl_mvm_vif_dbgfs_rm_link(mvm, vif);
63494374 1704
8ca151b5
JB
1705 /*
1706 * For AP/GO interface, the tear down of the resources allocated to the
38a12b5b 1707 * interface is be handled as part of the stop_ap flow.
8ca151b5 1708 */
5023d966
JB
1709 if (vif->type == NL80211_IFTYPE_AP ||
1710 vif->type == NL80211_IFTYPE_ADHOC) {
507cadf2
DS
1711#ifdef CONFIG_NL80211_TESTMODE
1712 if (vif == mvm->noa_vif) {
1713 mvm->noa_vif = NULL;
1714 mvm->noa_duration = 0;
1715 }
1716#endif
60efeca1 1717 return true;
8ca151b5
JB
1718 }
1719
60efeca1
MK
1720 iwl_mvm_power_update_mac(mvm);
1721 return false;
1722}
1723
1724static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
1725 struct ieee80211_vif *vif)
1726{
1727 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1728 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1729
1730 if (iwl_mvm_mac_remove_interface_common(hw, vif))
1731 goto out;
1732
84ef7cbe
IP
1733 /* Before the interface removal, mac80211 would cancel the ROC, and the
1734 * ROC worker would be scheduled if needed. The worker would be flushed
1735 * in iwl_mvm_prepare_mac_removal() and thus at this point there is no
1736 * binding etc. so nothing needs to be done here.
1737 */
8ca151b5 1738 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
84ef7cbe
IP
1739 if (mvmvif->deflink.phy_ctxt) {
1740 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt);
1741 mvmvif->deflink.phy_ctxt = NULL;
1742 }
8ca151b5 1743 mvm->p2p_device_vif = NULL;
8ca151b5
JB
1744 }
1745
8ca151b5
JB
1746 iwl_mvm_mac_ctxt_remove(mvm, vif);
1747
698478c4
SS
1748 RCU_INIT_POINTER(mvm->vif_id_to_mac[mvmvif->id], NULL);
1749
baf41bc3
ST
1750 if (vif->type == NL80211_IFTYPE_MONITOR)
1751 mvm->monitor_on = false;
1752
60efeca1
MK
1753out:
1754 if (vif->type == NL80211_IFTYPE_AP ||
1755 vif->type == NL80211_IFTYPE_ADHOC) {
650cadb7 1756 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->deflink.mcast_sta);
60efeca1
MK
1757 iwl_mvm_dealloc_bcast_sta(mvm, vif);
1758 }
8ca151b5 1759
8ca151b5 1760 mutex_unlock(&mvm->mutex);
8ca151b5
JB
1761}
1762
e59647ea
EP
1763struct iwl_mvm_mc_iter_data {
1764 struct iwl_mvm *mvm;
1765 int port_id;
1766};
1767
1768static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac,
1769 struct ieee80211_vif *vif)
1770{
1771 struct iwl_mvm_mc_iter_data *data = _data;
1772 struct iwl_mvm *mvm = data->mvm;
1773 struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd;
97bce57b
LC
1774 struct iwl_host_cmd hcmd = {
1775 .id = MCAST_FILTER_CMD,
1776 .flags = CMD_ASYNC,
1777 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
1778 };
e59647ea
EP
1779 int ret, len;
1780
1781 /* if we don't have free ports, mcast frames will be dropped */
1782 if (WARN_ON_ONCE(data->port_id >= MAX_PORT_ID_NUM))
1783 return;
1784
1785 if (vif->type != NL80211_IFTYPE_STATION ||
f276e20b 1786 !vif->cfg.assoc)
e59647ea
EP
1787 return;
1788
1789 cmd->port_id = data->port_id++;
1790 memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
1791 len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4);
1792
97bce57b
LC
1793 hcmd.len[0] = len;
1794 hcmd.data[0] = cmd;
1795
1796 ret = iwl_mvm_send_cmd(mvm, &hcmd);
e59647ea
EP
1797 if (ret)
1798 IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret);
1799}
1800
1801static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm)
1802{
1803 struct iwl_mvm_mc_iter_data iter_data = {
1804 .mvm = mvm,
88f2fd73 1805 };
db66abee 1806 int ret;
88f2fd73 1807
e59647ea
EP
1808 lockdep_assert_held(&mvm->mutex);
1809
1810 if (WARN_ON_ONCE(!mvm->mcast_filter_cmd))
1811 return;
1812
1c4abec0 1813 ieee80211_iterate_active_interfaces_atomic(
e59647ea
EP
1814 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1815 iwl_mvm_mc_iface_iterator, &iter_data);
db66abee
JB
1816
1817 /*
1818 * Send a (synchronous) ech command so that we wait for the
1819 * multiple asynchronous MCAST_FILTER_CMD commands sent by
1820 * the interface iterator. Otherwise, we might get here over
1821 * and over again (by userspace just sending a lot of these)
1822 * and the CPU can send them faster than the firmware can
1823 * process them.
1824 * Note that the CPU is still faster - but with this we'll
1825 * actually send fewer commands overall because the CPU will
1826 * not schedule the work in mac80211 as frequently if it's
1827 * still running when rescheduled (possibly multiple times).
1828 */
1829 ret = iwl_mvm_send_cmd_pdu(mvm, ECHO_CMD, 0, 0, NULL);
1830 if (ret)
1831 IWL_ERR(mvm, "Failed to synchronize multicast groups update\n");
88f2fd73
MG
1832}
1833
cbce62a3
MK
1834u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw,
1835 struct netdev_hw_addr_list *mc_list)
8ca151b5 1836{
e59647ea
EP
1837 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1838 struct iwl_mcast_filter_cmd *cmd;
1839 struct netdev_hw_addr *addr;
f3bd58f4
MS
1840 int addr_count;
1841 bool pass_all;
e59647ea
EP
1842 int len;
1843
f3bd58f4
MS
1844 addr_count = netdev_hw_addr_list_count(mc_list);
1845 pass_all = addr_count > MAX_MCAST_FILTERING_ADDRESSES ||
1846 IWL_MVM_FW_MCAST_FILTER_PASS_ALL;
1847 if (pass_all)
e59647ea 1848 addr_count = 0;
e59647ea
EP
1849
1850 len = roundup(sizeof(*cmd) + addr_count * ETH_ALEN, 4);
1851 cmd = kzalloc(len, GFP_ATOMIC);
1852 if (!cmd)
1853 return 0;
1854
1855 if (pass_all) {
1856 cmd->pass_all = 1;
1857 return (u64)(unsigned long)cmd;
1858 }
1859
1860 netdev_hw_addr_list_for_each(addr, mc_list) {
1861 IWL_DEBUG_MAC80211(mvm, "mcast addr (%d): %pM\n",
1862 cmd->count, addr->addr);
1863 memcpy(&cmd->addr_list[cmd->count * ETH_ALEN],
1864 addr->addr, ETH_ALEN);
1865 cmd->count++;
1866 }
1867
1868 return (u64)(unsigned long)cmd;
8ca151b5
JB
1869}
1870
cbce62a3
MK
1871void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
1872 unsigned int changed_flags,
1873 unsigned int *total_flags, u64 multicast)
8ca151b5 1874{
e59647ea
EP
1875 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1876 struct iwl_mcast_filter_cmd *cmd = (void *)(unsigned long)multicast;
8ca151b5 1877
e59647ea 1878 mutex_lock(&mvm->mutex);
51b6b9e0 1879
e59647ea
EP
1880 /* replace previous configuration */
1881 kfree(mvm->mcast_filter_cmd);
1882 mvm->mcast_filter_cmd = cmd;
51b6b9e0 1883
e59647ea
EP
1884 if (!cmd)
1885 goto out;
51b6b9e0 1886
61e7d91b
LC
1887 if (changed_flags & FIF_ALLMULTI)
1888 cmd->pass_all = !!(*total_flags & FIF_ALLMULTI);
1889
1890 if (cmd->pass_all)
1891 cmd->count = 0;
1892
e59647ea
EP
1893 iwl_mvm_recalc_multicast(mvm);
1894out:
1895 mutex_unlock(&mvm->mutex);
1896 *total_flags = 0;
51b6b9e0
EG
1897}
1898
effd1929
AO
1899static void iwl_mvm_config_iface_filter(struct ieee80211_hw *hw,
1900 struct ieee80211_vif *vif,
1901 unsigned int filter_flags,
1902 unsigned int changed_flags)
1903{
1904 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1905
1906 /* We support only filter for probe requests */
1907 if (!(changed_flags & FIF_PROBE_REQ))
1908 return;
1909
1910 /* Supported only for p2p client interfaces */
f276e20b 1911 if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc ||
effd1929
AO
1912 !vif->p2p)
1913 return;
1914
1915 mutex_lock(&mvm->mutex);
1916 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
1917 mutex_unlock(&mvm->mutex);
1918}
1919
22c58834 1920int iwl_mvm_update_mu_groups(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
a07a8f37
SS
1921{
1922 struct iwl_mu_group_mgmt_cmd cmd = {};
1923
1924 memcpy(cmd.membership_status, vif->bss_conf.mu_group.membership,
1925 WLAN_MEMBERSHIP_LEN);
1926 memcpy(cmd.user_position, vif->bss_conf.mu_group.position,
1927 WLAN_USER_POSITION_LEN);
1928
1929 return iwl_mvm_send_cmd_pdu(mvm,
1930 WIDE_ID(DATA_PATH_GROUP,
1931 UPDATE_MU_GROUPS_CMD),
1932 0, sizeof(cmd), &cmd);
1933}
1934
f92659a1
SS
1935static void iwl_mvm_mu_mimo_iface_iterator(void *_data, u8 *mac,
1936 struct ieee80211_vif *vif)
1937{
d0a9123e 1938 if (vif->bss_conf.mu_mimo_owner) {
f92659a1
SS
1939 struct iwl_mu_group_mgmt_notif *notif = _data;
1940
1941 /*
1942 * MU-MIMO Group Id action frame is little endian. We treat
1943 * the data received from firmware as if it came from the
1944 * action frame, so no conversion is needed.
1945 */
afe0d181 1946 ieee80211_update_mu_groups(vif, 0,
f92659a1
SS
1947 (u8 *)&notif->membership_status,
1948 (u8 *)&notif->user_position);
1949 }
1950}
1951
1952void iwl_mvm_mu_mimo_grp_notif(struct iwl_mvm *mvm,
1953 struct iwl_rx_cmd_buffer *rxb)
1954{
1955 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1956 struct iwl_mu_group_mgmt_notif *notif = (void *)pkt->data;
1957
1958 ieee80211_iterate_active_interfaces_atomic(
1959 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1960 iwl_mvm_mu_mimo_iface_iterator, notif);
1961}
1962
514c3069
LC
1963static u8 iwl_mvm_he_get_ppe_val(u8 *ppe, u8 ppe_pos_bit)
1964{
1965 u8 byte_num = ppe_pos_bit / 8;
1966 u8 bit_num = ppe_pos_bit % 8;
1967 u8 residue_bits;
1968 u8 res;
1969
1970 if (bit_num <= 5)
1971 return (ppe[byte_num] >> bit_num) &
1972 (BIT(IEEE80211_PPE_THRES_INFO_PPET_SIZE) - 1);
1973
1974 /*
1975 * If bit_num > 5, we have to combine bits with next byte.
1976 * Calculate how many bits we need to take from current byte (called
1977 * here "residue_bits"), and add them to bits from next byte.
1978 */
1979
1980 residue_bits = 8 - bit_num;
1981
1982 res = (ppe[byte_num + 1] &
1983 (BIT(IEEE80211_PPE_THRES_INFO_PPET_SIZE - residue_bits) - 1)) <<
1984 residue_bits;
1985 res += (ppe[byte_num] >> bit_num) & (BIT(residue_bits) - 1);
1986
1987 return res;
1988}
1989
091296d3
MK
1990static void iwl_mvm_parse_ppe(struct iwl_mvm *mvm,
1991 struct iwl_he_pkt_ext_v2 *pkt_ext, u8 nss,
cb63eb43
MK
1992 u8 ru_index_bitmap, u8 *ppe, u8 ppe_pos_bit,
1993 bool inheritance)
091296d3
MK
1994{
1995 int i;
1996
1997 /*
1998 * FW currently supports only nss == MAX_HE_SUPP_NSS
1999 *
2000 * If nss > MAX: we can ignore values we don't support
2001 * If nss < MAX: we can set zeros in other streams
2002 */
2003 if (nss > MAX_HE_SUPP_NSS) {
4d8421f2
JD
2004 IWL_DEBUG_INFO(mvm, "Got NSS = %d - trimming to %d\n", nss,
2005 MAX_HE_SUPP_NSS);
091296d3
MK
2006 nss = MAX_HE_SUPP_NSS;
2007 }
2008
2009 for (i = 0; i < nss; i++) {
2010 u8 ru_index_tmp = ru_index_bitmap << 1;
2011 u8 low_th = IWL_HE_PKT_EXT_NONE, high_th = IWL_HE_PKT_EXT_NONE;
2012 u8 bw;
2013
2014 for (bw = 0;
2015 bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
2016 bw++) {
2017 ru_index_tmp >>= 1;
2018
cb63eb43
MK
2019 /*
2020 * According to the 11be spec, if for a specific BW the PPE Thresholds
2021 * isn't present - it should inherit the thresholds from the last
2022 * BW for which we had PPE Thresholds. In 11ax though, we don't have
2023 * this inheritance - continue in this case
2024 */
2025 if (!(ru_index_tmp & 1)) {
2026 if (inheritance)
2027 goto set_thresholds;
2028 else
2029 continue;
2030 }
091296d3
MK
2031
2032 high_th = iwl_mvm_he_get_ppe_val(ppe, ppe_pos_bit);
2033 ppe_pos_bit += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
2034 low_th = iwl_mvm_he_get_ppe_val(ppe, ppe_pos_bit);
2035 ppe_pos_bit += IEEE80211_PPE_THRES_INFO_PPET_SIZE;
2036
cb63eb43 2037set_thresholds:
091296d3
MK
2038 pkt_ext->pkt_ext_qam_th[i][bw][0] = low_th;
2039 pkt_ext->pkt_ext_qam_th[i][bw][1] = high_th;
2040 }
2041 }
2042}
2043
2044static void iwl_mvm_set_pkt_ext_from_he_ppe(struct iwl_mvm *mvm,
57974a55 2045 struct ieee80211_link_sta *link_sta,
cb63eb43
MK
2046 struct iwl_he_pkt_ext_v2 *pkt_ext,
2047 bool inheritance)
091296d3 2048{
57974a55
GG
2049 u8 nss = (link_sta->he_cap.ppe_thres[0] &
2050 IEEE80211_PPE_THRES_NSS_MASK) + 1;
2051 u8 *ppe = &link_sta->he_cap.ppe_thres[0];
091296d3
MK
2052 u8 ru_index_bitmap =
2053 u8_get_bits(*ppe,
2054 IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK);
2055 /* Starting after PPE header */
2056 u8 ppe_pos_bit = IEEE80211_HE_PPE_THRES_INFO_HEADER_SIZE;
2057
cb63eb43
MK
2058 iwl_mvm_parse_ppe(mvm, pkt_ext, nss, ru_index_bitmap, ppe, ppe_pos_bit,
2059 inheritance);
091296d3
MK
2060}
2061
4df6a075
MK
2062static int
2063iwl_mvm_set_pkt_ext_from_nominal_padding(struct iwl_he_pkt_ext_v2 *pkt_ext,
2064 u8 nominal_padding)
091296d3
MK
2065{
2066 int low_th = -1;
2067 int high_th = -1;
2068 int i;
2069
cb63eb43 2070 /* all the macros are the same for EHT and HE */
091296d3 2071 switch (nominal_padding) {
cb63eb43 2072 case IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_0US:
091296d3
MK
2073 low_th = IWL_HE_PKT_EXT_NONE;
2074 high_th = IWL_HE_PKT_EXT_NONE;
2075 break;
cb63eb43 2076 case IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_8US:
091296d3
MK
2077 low_th = IWL_HE_PKT_EXT_BPSK;
2078 high_th = IWL_HE_PKT_EXT_NONE;
2079 break;
cb63eb43
MK
2080 case IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_16US:
2081 case IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_20US:
091296d3
MK
2082 low_th = IWL_HE_PKT_EXT_NONE;
2083 high_th = IWL_HE_PKT_EXT_BPSK;
2084 break;
2085 }
2086
4df6a075
MK
2087 if (low_th < 0 || high_th < 0)
2088 return -EINVAL;
2089
091296d3 2090 /* Set the PPE thresholds accordingly */
4df6a075
MK
2091 for (i = 0; i < MAX_HE_SUPP_NSS; i++) {
2092 u8 bw;
091296d3 2093
4df6a075
MK
2094 for (bw = 0;
2095 bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
2096 bw++) {
2097 pkt_ext->pkt_ext_qam_th[i][bw][0] = low_th;
2098 pkt_ext->pkt_ext_qam_th[i][bw][1] = high_th;
091296d3 2099 }
091296d3 2100 }
4df6a075
MK
2101
2102 return 0;
091296d3
MK
2103}
2104
cb63eb43
MK
2105static void iwl_mvm_get_optimal_ppe_info(struct iwl_he_pkt_ext_v2 *pkt_ext,
2106 u8 nominal_padding)
2107{
2108 int i;
2109
2110 for (i = 0; i < MAX_HE_SUPP_NSS; i++) {
2111 u8 bw;
2112
2113 for (bw = 0; bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]);
2114 bw++) {
2115 u8 *qam_th = &pkt_ext->pkt_ext_qam_th[i][bw][0];
2116
2117 if (nominal_padding >
2118 IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_8US &&
2119 qam_th[1] == IWL_HE_PKT_EXT_NONE)
2120 qam_th[1] = IWL_HE_PKT_EXT_4096QAM;
2121 else if (nominal_padding ==
2122 IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_8US &&
2123 qam_th[0] == IWL_HE_PKT_EXT_NONE &&
2124 qam_th[1] == IWL_HE_PKT_EXT_NONE)
2125 qam_th[0] = IWL_HE_PKT_EXT_4096QAM;
2126 }
2127 }
2128}
2129
4df6a075 2130/* Set the pkt_ext field according to PPE Thresholds element */
57974a55
GG
2131int iwl_mvm_set_sta_pkt_ext(struct iwl_mvm *mvm,
2132 struct ieee80211_link_sta *link_sta,
87f7e243 2133 struct iwl_he_pkt_ext_v2 *pkt_ext)
4df6a075
MK
2134{
2135 u8 nominal_padding;
2136 int i, ret = 0;
2137
57974a55
GG
2138 if (WARN_ON(!link_sta))
2139 return -EINVAL;
2140
4df6a075
MK
2141 /* Initialize the PPE thresholds to "None" (7), as described in Table
2142 * 9-262ac of 80211.ax/D3.0.
2143 */
2144 memset(pkt_ext, IWL_HE_PKT_EXT_NONE,
2145 sizeof(struct iwl_he_pkt_ext_v2));
2146
57974a55 2147 if (link_sta->eht_cap.has_eht) {
4df6a075 2148 nominal_padding =
57974a55 2149 u8_get_bits(link_sta->eht_cap.eht_cap_elem.phy_cap_info[5],
4df6a075
MK
2150 IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK);
2151
2152 /* If PPE Thresholds exists, parse them into a FW-familiar
2153 * format.
2154 */
57974a55 2155 if (link_sta->eht_cap.eht_cap_elem.phy_cap_info[5] &
4df6a075 2156 IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT) {
57974a55 2157 u8 nss = (link_sta->eht_cap.eht_ppe_thres[0] &
4df6a075 2158 IEEE80211_EHT_PPE_THRES_NSS_MASK) + 1;
57974a55 2159 u8 *ppe = &link_sta->eht_cap.eht_ppe_thres[0];
4df6a075
MK
2160 u8 ru_index_bitmap =
2161 u16_get_bits(*ppe,
2162 IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK);
2163 /* Starting after PPE header */
2164 u8 ppe_pos_bit = IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE;
2165
2166 iwl_mvm_parse_ppe(mvm, pkt_ext, nss, ru_index_bitmap,
2167 ppe, ppe_pos_bit, true);
57974a55
GG
2168 /* EHT PPE Thresholds doesn't exist - set the API according to
2169 * HE PPE Tresholds
4df6a075 2170 */
57974a55 2171 } else if (link_sta->he_cap.he_cap_elem.phy_cap_info[6] &
4df6a075
MK
2172 IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
2173 /* Even though HE Capabilities IE doesn't contain PPE
2174 * Thresholds for BW 320Mhz, thresholds for this BW will
2175 * be filled in with the same values as 160Mhz, due to
2176 * the inheritance, as required.
2177 */
57974a55 2178 iwl_mvm_set_pkt_ext_from_he_ppe(mvm, link_sta, pkt_ext,
4df6a075
MK
2179 true);
2180
2181 /* According to the requirements, for MCSs 12-13 the
2182 * maximum value between HE PPE Threshold and Common
2183 * Nominal Packet Padding needs to be taken
2184 */
2185 iwl_mvm_get_optimal_ppe_info(pkt_ext, nominal_padding);
2186
2187 /* if PPE Thresholds doesn't present in both EHT IE and HE IE -
2188 * take the Thresholds from Common Nominal Packet Padding field
2189 */
2190 } else {
2191 ret = iwl_mvm_set_pkt_ext_from_nominal_padding(pkt_ext,
2192 nominal_padding);
2193 }
57974a55 2194 } else if (link_sta->he_cap.has_he) {
4df6a075 2195 /* If PPE Thresholds exist, parse them into a FW-familiar format. */
57974a55 2196 if (link_sta->he_cap.he_cap_elem.phy_cap_info[6] &
4df6a075 2197 IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
57974a55 2198 iwl_mvm_set_pkt_ext_from_he_ppe(mvm, link_sta, pkt_ext,
4df6a075
MK
2199 false);
2200 /* PPE Thresholds doesn't exist - set the API PPE values
2201 * according to Common Nominal Packet Padding field.
2202 */
2203 } else {
2204 nominal_padding =
57974a55 2205 u8_get_bits(link_sta->he_cap.he_cap_elem.phy_cap_info[9],
4df6a075
MK
2206 IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK);
2207 if (nominal_padding != IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_RESERVED)
2208 ret = iwl_mvm_set_pkt_ext_from_nominal_padding(pkt_ext,
2209 nominal_padding);
2210 }
2211 }
2212
2213 for (i = 0; i < MAX_HE_SUPP_NSS; i++) {
2214 int bw;
2215
2216 for (bw = 0;
2217 bw < ARRAY_SIZE(*pkt_ext->pkt_ext_qam_th[i]);
2218 bw++) {
2219 u8 *qam_th =
2220 &pkt_ext->pkt_ext_qam_th[i][bw][0];
2221
2222 IWL_DEBUG_HT(mvm,
2223 "PPE table: nss[%d] bw[%d] PPET8 = %d, PPET16 = %d\n",
2224 i, bw, qam_th[0], qam_th[1]);
2225 }
2226 }
2227 return ret;
2228}
2229
9c4f15ca
MK
2230/*
2231 * This function sets the MU EDCA parameters ans returns whether MU EDCA
2232 * is enabled or not
2233 */
55eb1c5f 2234bool iwl_mvm_set_fw_mu_edca_params(struct iwl_mvm *mvm,
e119e740 2235 const struct iwl_mvm_vif_link_info *link_info,
55eb1c5f 2236 struct iwl_he_backoff_conf *trig_based_txf)
9c4f15ca
MK
2237{
2238 int i;
2239 /* Mark MU EDCA as enabled, unless none detected on some AC */
2240 bool mu_edca_enabled = true;
2241
2242 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
e119e740
EG
2243 const struct ieee80211_he_mu_edca_param_ac_rec *mu_edca =
2244 &link_info->queue_params[i].mu_edca_param_rec;
9c4f15ca
MK
2245 u8 ac = iwl_mvm_mac80211_ac_to_ucode_ac(i);
2246
e119e740 2247 if (!link_info->queue_params[i].mu_edca) {
9c4f15ca
MK
2248 mu_edca_enabled = false;
2249 break;
2250 }
2251
2252 trig_based_txf[ac].cwmin =
2253 cpu_to_le16(mu_edca->ecw_min_max & 0xf);
2254 trig_based_txf[ac].cwmax =
2255 cpu_to_le16((mu_edca->ecw_min_max & 0xf0) >> 4);
2256 trig_based_txf[ac].aifsn =
2257 cpu_to_le16(mu_edca->aifsn & 0xf);
2258 trig_based_txf[ac].mu_time =
2259 cpu_to_le16(mu_edca->mu_edca_timer);
2260 }
2261
2262 return mu_edca_enabled;
2263}
2264
9be162a7 2265bool iwl_mvm_is_nic_ack_enabled(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
9c4f15ca
MK
2266{
2267 const struct ieee80211_supported_band *sband;
2268 const struct ieee80211_sta_he_cap *own_he_cap = NULL;
2269
2270 /* This capability is the same for all bands,
2271 * so take it from one of them.
2272 */
2273 sband = mvm->hw->wiphy->bands[NL80211_BAND_2GHZ];
1ec7291e 2274 own_he_cap = ieee80211_get_he_iftype_cap_vif(sband, vif);
9c4f15ca
MK
2275
2276 return (own_he_cap && (own_he_cap->he_cap_elem.mac_cap_info[2] &
2277 IEEE80211_HE_MAC_CAP2_ACK_EN));
2278}
2279
57974a55
GG
2280__le32 iwl_mvm_get_sta_htc_flags(struct ieee80211_sta *sta,
2281 struct ieee80211_link_sta *link_sta)
4df6a075 2282{
57974a55
GG
2283 u8 *mac_cap_info =
2284 &link_sta->he_cap.he_cap_elem.mac_cap_info[0];
4df6a075
MK
2285 __le32 htc_flags = 0;
2286
2287 if (mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_HTC_HE)
2288 htc_flags |= cpu_to_le32(IWL_HE_HTC_SUPPORT);
2289 if ((mac_cap_info[1] & IEEE80211_HE_MAC_CAP1_LINK_ADAPTATION) ||
2290 (mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_LINK_ADAPTATION)) {
2291 u8 link_adap =
2292 ((mac_cap_info[2] &
2293 IEEE80211_HE_MAC_CAP2_LINK_ADAPTATION) << 1) +
2294 (mac_cap_info[1] &
2295 IEEE80211_HE_MAC_CAP1_LINK_ADAPTATION);
2296
2297 if (link_adap == 2)
2298 htc_flags |=
2299 cpu_to_le32(IWL_HE_HTC_LINK_ADAP_UNSOLICITED);
2300 else if (link_adap == 3)
2301 htc_flags |= cpu_to_le32(IWL_HE_HTC_LINK_ADAP_BOTH);
2302 }
2303 if (mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_BSR)
2304 htc_flags |= cpu_to_le32(IWL_HE_HTC_BSR_SUPP);
2305 if (mac_cap_info[3] & IEEE80211_HE_MAC_CAP3_OMI_CONTROL)
2306 htc_flags |= cpu_to_le32(IWL_HE_HTC_OMI_SUPP);
2307 if (mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR)
2308 htc_flags |= cpu_to_le32(IWL_HE_HTC_BQR_SUPP);
2309
2310 return htc_flags;
2311}
2312
514c3069
LC
2313static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,
2314 struct ieee80211_vif *vif, u8 sta_id)
2315{
2316 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
42506dd2 2317 struct iwl_he_sta_context_cmd_v3 sta_ctxt_cmd = {
514c3069
LC
2318 .sta_id = sta_id,
2319 .tid_limit = IWL_MAX_TID_COUNT,
dd56e902 2320 .bss_color = vif->bss_conf.he_bss_color.color,
514c3069
LC
2321 .htc_trig_based_pkt_ext = vif->bss_conf.htc_trig_based_pkt_ext,
2322 .frame_time_rts_th =
2323 cpu_to_le16(vif->bss_conf.frame_time_rts_th),
2324 };
42506dd2
JB
2325 struct iwl_he_sta_context_cmd_v2 sta_ctxt_cmd_v2 = {};
2326 u32 cmd_id = WIDE_ID(DATA_PATH_GROUP, STA_HE_CTXT_CMD);
2327 u8 ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 2);
2328 int size;
514c3069
LC
2329 struct ieee80211_sta *sta;
2330 u32 flags;
2331 int i;
42506dd2
JB
2332 void *cmd;
2333
2334 if (!fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_MBSSID_HE))
2335 ver = 1;
2336
2337 switch (ver) {
2338 case 1:
2339 /* same layout as v2 except some data at the end */
2340 cmd = &sta_ctxt_cmd_v2;
2341 size = sizeof(struct iwl_he_sta_context_cmd_v1);
2342 break;
2343 case 2:
2344 cmd = &sta_ctxt_cmd_v2;
2345 size = sizeof(struct iwl_he_sta_context_cmd_v2);
2346 break;
2347 case 3:
2348 cmd = &sta_ctxt_cmd;
2349 size = sizeof(struct iwl_he_sta_context_cmd_v3);
2350 break;
2351 default:
2352 IWL_ERR(mvm, "bad STA_HE_CTXT_CMD version %d\n", ver);
2353 return;
2354 }
514c3069
LC
2355
2356 rcu_read_lock();
2357
2358 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_ctxt_cmd.sta_id]);
12d47f0e 2359 if (IS_ERR_OR_NULL(sta)) {
514c3069
LC
2360 rcu_read_unlock();
2361 WARN(1, "Can't find STA to configure HE\n");
2362 return;
2363 }
2364
046d2e7c 2365 if (!sta->deflink.he_cap.has_he) {
514c3069
LC
2366 rcu_read_unlock();
2367 return;
2368 }
2369
2370 flags = 0;
2371
4f58121d 2372 /* Block 26-tone RU OFDMA transmissions */
650cadb7 2373 if (mvmvif->deflink.he_ru_2mhz_block)
4f58121d
IP
2374 flags |= STA_CTXT_HE_RU_2MHZ_BLOCK;
2375
514c3069 2376 /* HTC flags */
57974a55 2377 sta_ctxt_cmd.htc_flags = iwl_mvm_get_sta_htc_flags(sta, &sta->deflink);
cb63eb43 2378
4df6a075 2379 /* PPE Thresholds */
57974a55 2380 if (!iwl_mvm_set_sta_pkt_ext(mvm, &sta->deflink, &sta_ctxt_cmd.pkt_ext))
4df6a075 2381 flags |= STA_CTXT_HE_PACKET_EXT;
73f23d91 2382
046d2e7c 2383 if (sta->deflink.he_cap.he_cap_elem.mac_cap_info[2] &
73f23d91
ST
2384 IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP)
2385 flags |= STA_CTXT_HE_32BIT_BA_BITMAP;
2386
046d2e7c 2387 if (sta->deflink.he_cap.he_cap_elem.mac_cap_info[2] &
73f23d91
ST
2388 IEEE80211_HE_MAC_CAP2_ACK_EN)
2389 flags |= STA_CTXT_HE_ACK_ENABLED;
2390
514c3069
LC
2391 rcu_read_unlock();
2392
e119e740 2393 if (iwl_mvm_set_fw_mu_edca_params(mvm, &mvmvif->deflink,
9c4f15ca
MK
2394 &sta_ctxt_cmd.trig_based_txf[0]))
2395 flags |= STA_CTXT_HE_MU_EDCA_CW;
514c3069
LC
2396
2397 if (vif->bss_conf.uora_exists) {
2398 flags |= STA_CTXT_HE_TRIG_RND_ALLOC;
2399
2400 sta_ctxt_cmd.rand_alloc_ecwmin =
2401 vif->bss_conf.uora_ocw_range & 0x7;
2402 sta_ctxt_cmd.rand_alloc_ecwmax =
2403 (vif->bss_conf.uora_ocw_range >> 3) & 0x7;
2404 }
2405
9c4f15ca 2406 if (!iwl_mvm_is_nic_ack_enabled(mvm, vif))
ee1a02d7
ST
2407 flags |= STA_CTXT_HE_NIC_NOT_ACK_ENABLED;
2408
918cbf39
SS
2409 if (vif->bss_conf.nontransmitted) {
2410 flags |= STA_CTXT_HE_REF_BSSID_VALID;
2411 ether_addr_copy(sta_ctxt_cmd.ref_bssid_addr,
2412 vif->bss_conf.transmitter_bssid);
d14ae796
SS
2413 sta_ctxt_cmd.max_bssid_indicator =
2414 vif->bss_conf.bssid_indicator;
2415 sta_ctxt_cmd.bssid_index = vif->bss_conf.bssid_index;
2416 sta_ctxt_cmd.ema_ap = vif->bss_conf.ema_ap;
2417 sta_ctxt_cmd.profile_periodicity =
2418 vif->bss_conf.profile_periodicity;
918cbf39 2419 }
514c3069
LC
2420
2421 sta_ctxt_cmd.flags = cpu_to_le32(flags);
2422
42506dd2
JB
2423 if (ver < 3) {
2424 /* fields before pkt_ext */
2425 BUILD_BUG_ON(offsetof(typeof(sta_ctxt_cmd), pkt_ext) !=
2426 offsetof(typeof(sta_ctxt_cmd_v2), pkt_ext));
2427 memcpy(&sta_ctxt_cmd_v2, &sta_ctxt_cmd,
2428 offsetof(typeof(sta_ctxt_cmd), pkt_ext));
2429
2430 /* pkt_ext */
2431 for (i = 0;
2432 i < ARRAY_SIZE(sta_ctxt_cmd_v2.pkt_ext.pkt_ext_qam_th);
2433 i++) {
2434 u8 bw;
2435
2436 for (bw = 0;
2437 bw < ARRAY_SIZE(sta_ctxt_cmd_v2.pkt_ext.pkt_ext_qam_th[i]);
2438 bw++) {
2439 BUILD_BUG_ON(sizeof(sta_ctxt_cmd.pkt_ext.pkt_ext_qam_th[i][bw]) !=
2440 sizeof(sta_ctxt_cmd_v2.pkt_ext.pkt_ext_qam_th[i][bw]));
2441
2442 memcpy(&sta_ctxt_cmd_v2.pkt_ext.pkt_ext_qam_th[i][bw],
2443 &sta_ctxt_cmd.pkt_ext.pkt_ext_qam_th[i][bw],
2444 sizeof(sta_ctxt_cmd.pkt_ext.pkt_ext_qam_th[i][bw]));
2445 }
2446 }
2447
2448 /* fields after pkt_ext */
2449 BUILD_BUG_ON(sizeof(sta_ctxt_cmd) -
2450 offsetofend(typeof(sta_ctxt_cmd), pkt_ext) !=
2451 sizeof(sta_ctxt_cmd_v2) -
2452 offsetofend(typeof(sta_ctxt_cmd_v2), pkt_ext));
2453 memcpy((u8 *)&sta_ctxt_cmd_v2 +
2454 offsetofend(typeof(sta_ctxt_cmd_v2), pkt_ext),
2455 (u8 *)&sta_ctxt_cmd +
2456 offsetofend(typeof(sta_ctxt_cmd), pkt_ext),
2457 sizeof(sta_ctxt_cmd) -
2458 offsetofend(typeof(sta_ctxt_cmd), pkt_ext));
2459 sta_ctxt_cmd_v2.reserved3 = 0;
2460 }
2461
2462 if (iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, size, cmd))
514c3069
LC
2463 IWL_ERR(mvm, "Failed to config FW to work HE!\n");
2464}
2465
660eba5a 2466void iwl_mvm_protect_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
23673041 2467 u32 duration_override, unsigned int link_id)
af84ac57
JB
2468{
2469 u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS;
2470 u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS;
2471
2472 if (duration_override > duration)
2473 duration = duration_override;
2474
2475 /* Try really hard to protect the session and hear a beacon
2476 * The new session protection command allows us to protect the
2477 * session for a much longer time since the firmware will internally
2478 * create two events: a 300TU one with a very high priority that
2479 * won't be fragmented which should be enough for 99% of the cases,
2480 * and another one (which we configure here to be 900TU long) which
2481 * will have a slightly lower priority, but more importantly, can be
2482 * fragmented so that it'll allow other activities to run.
2483 */
2484 if (fw_has_capa(&mvm->fw->ucode_capa,
2485 IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD))
2486 iwl_mvm_schedule_session_protection(mvm, vif, 900,
23673041
MK
2487 min_duration, false,
2488 link_id);
af84ac57
JB
2489 else
2490 iwl_mvm_protect_session(mvm, vif, duration,
2491 min_duration, 500, false);
2492}
2493
660eba5a
MK
2494/* Handle association common part to MLD and non-MLD modes */
2495void iwl_mvm_bss_info_changed_station_assoc(struct iwl_mvm *mvm,
2496 struct ieee80211_vif *vif,
2497 u64 changes)
2498{
2499 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2500 int ret;
2501
2502 /* The firmware tracks the MU-MIMO group on its own.
2503 * However, on HW restart we should restore this data.
2504 */
2505 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
2506 (changes & BSS_CHANGED_MU_GROUPS) && vif->bss_conf.mu_mimo_owner) {
2507 ret = iwl_mvm_update_mu_groups(mvm, vif);
2508 if (ret)
2509 IWL_ERR(mvm,
2510 "failed to update VHT MU_MIMO groups\n");
2511 }
2512
2513 iwl_mvm_recalc_multicast(mvm);
2514
2515 /* reset rssi values */
2516 mvmvif->bf_data.ave_beacon_signal = 0;
2517
2518 iwl_mvm_bt_coex_vif_change(mvm);
1a3e7039
GG
2519 iwl_mvm_update_smps_on_active_links(mvm, vif, IWL_MVM_SMPS_REQ_TT,
2520 IEEE80211_SMPS_AUTOMATIC);
660eba5a
MK
2521 if (fw_has_capa(&mvm->fw->ucode_capa,
2522 IWL_UCODE_TLV_CAPA_UMAC_SCAN))
2523 iwl_mvm_config_scan(mvm);
2524}
2525
2526/* Execute the common part for MLD and non-MLD modes */
1a3e7039
GG
2527void
2528iwl_mvm_bss_info_changed_station_common(struct iwl_mvm *mvm,
2529 struct ieee80211_vif *vif,
2530 struct ieee80211_bss_conf *link_conf,
2531 u64 changes)
660eba5a
MK
2532{
2533 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2534 int ret;
2535
2536 if (changes & BSS_CHANGED_BEACON_INFO) {
2537 /* We received a beacon from the associated AP so
2538 * remove the session protection.
2539 */
2540 iwl_mvm_stop_session_protection(mvm, vif);
2541
2542 iwl_mvm_sf_update(mvm, vif, false);
2543 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
2544 }
2545
2546 if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS | BSS_CHANGED_QOS |
2547 /* Send power command on every beacon change,
2548 * because we may have not enabled beacon abort yet.
2549 */
2550 BSS_CHANGED_BEACON_INFO)) {
2551 ret = iwl_mvm_power_update_mac(mvm);
2552 if (ret)
2553 IWL_ERR(mvm, "failed to update power mode\n");
2554 }
2555
2556 if (changes & BSS_CHANGED_CQM) {
2557 IWL_DEBUG_MAC80211(mvm, "cqm info_changed\n");
2558 /* reset cqm events tracking */
2559 mvmvif->bf_data.last_cqm_event = 0;
2560 if (mvmvif->bf_data.bf_enabled) {
22c58834
GG
2561 /* FIXME: need to update per link when FW API will
2562 * support it
2563 */
660eba5a
MK
2564 ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
2565 if (ret)
2566 IWL_ERR(mvm,
2567 "failed to update CQM thresholds\n");
2568 }
2569 }
2570
2571 if (changes & BSS_CHANGED_BANDWIDTH)
1a3e7039 2572 iwl_mvm_update_link_smps(vif, link_conf);
660eba5a
MK
2573}
2574
8ca151b5
JB
2575static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
2576 struct ieee80211_vif *vif,
2577 struct ieee80211_bss_conf *bss_conf,
7b7090b4 2578 u64 changes)
8ca151b5
JB
2579{
2580 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2581 int ret;
2582
6e97b0d2 2583 /*
cdaba917
EG
2584 * Re-calculate the tsf id, as the leader-follower relations depend
2585 * on the beacon interval, which was not known when the station
2586 * interface was added.
6e97b0d2 2587 */
f276e20b 2588 if (changes & BSS_CHANGED_ASSOC && vif->cfg.assoc) {
cb63eb43
MK
2589 if ((vif->bss_conf.he_support &&
2590 !iwlwifi_mod_params.disable_11ax) ||
2591 (vif->bss_conf.eht_support &&
2592 !iwlwifi_mod_params.disable_11be))
650cadb7 2593 iwl_mvm_cfg_he_sta(mvm, vif, mvmvif->deflink.ap_sta_id);
514c3069 2594
6e97b0d2 2595 iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
514c3069 2596 }
6e97b0d2 2597
40ecdd01
ST
2598 /* Update MU EDCA params */
2599 if (changes & BSS_CHANGED_QOS && mvmvif->associated &&
cb63eb43
MK
2600 vif->cfg.assoc &&
2601 ((vif->bss_conf.he_support &&
2602 !iwlwifi_mod_params.disable_11ax) ||
2603 (vif->bss_conf.eht_support &&
2604 !iwlwifi_mod_params.disable_11be)))
650cadb7 2605 iwl_mvm_cfg_he_sta(mvm, vif, mvmvif->deflink.ap_sta_id);
40ecdd01 2606
3dfd3a97
JB
2607 /*
2608 * If we're not associated yet, take the (new) BSSID before associating
2609 * so the firmware knows. If we're already associated, then use the old
2610 * BSSID here, and we'll send a cleared one later in the CHANGED_ASSOC
2611 * branch for disassociation below.
2612 */
2613 if (changes & BSS_CHANGED_BSSID && !mvmvif->associated)
650cadb7 2614 memcpy(mvmvif->deflink.bssid, bss_conf->bssid, ETH_ALEN);
3dfd3a97 2615
650cadb7 2616 ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, mvmvif->deflink.bssid);
8ca151b5
JB
2617 if (ret)
2618 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
2619
3dfd3a97 2620 /* after sending it once, adopt mac80211 data */
650cadb7 2621 memcpy(mvmvif->deflink.bssid, bss_conf->bssid, ETH_ALEN);
f276e20b 2622 mvmvif->associated = vif->cfg.assoc;
3dfd3a97 2623
8ca151b5 2624 if (changes & BSS_CHANGED_ASSOC) {
f276e20b 2625 if (vif->cfg.assoc) {
33cef925
JB
2626 /* clear statistics to get clean beacon counter */
2627 iwl_mvm_request_statistics(mvm, true);
650cadb7
GG
2628 memset(&mvmvif->deflink.beacon_stats, 0,
2629 sizeof(mvmvif->deflink.beacon_stats));
33cef925 2630
8ca151b5 2631 /* add quota for this interface */
7754ae79 2632 ret = iwl_mvm_update_quotas(mvm, true, NULL);
8ca151b5
JB
2633 if (ret) {
2634 IWL_ERR(mvm, "failed to update quotas\n");
2635 return;
2636 }
016d27e1
JB
2637
2638 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
fe959c7b
EG
2639 &mvm->status) &&
2640 !fw_has_capa(&mvm->fw->ucode_capa,
2641 IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) {
016d27e1
JB
2642 /*
2643 * If we're restarting then the firmware will
2644 * obviously have lost synchronisation with
2645 * the AP. It will attempt to synchronise by
2646 * itself, but we can make it more reliable by
2647 * scheduling a session protection time event.
2648 *
2649 * The firmware needs to receive a beacon to
2650 * catch up with synchronisation, use 110% of
2651 * the beacon interval.
2652 *
2653 * Set a large maximum delay to allow for more
2654 * than a single interface.
fe959c7b
EG
2655 *
2656 * For new firmware versions, rely on the
2657 * firmware. This is relevant for DCM scenarios
2658 * only anyway.
016d27e1
JB
2659 */
2660 u32 dur = (11 * vif->bss_conf.beacon_int) / 10;
2661 iwl_mvm_protect_session(mvm, vif, dur, dur,
d20d37bc 2662 5 * dur, false);
af84ac57
JB
2663 } else if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
2664 &mvm->status) &&
2665 !vif->bss_conf.dtim_period) {
2666 /*
2667 * If we're not restarting and still haven't
2668 * heard a beacon (dtim period unknown) then
2669 * make sure we still have enough minimum time
2670 * remaining in the time event, since the auth
2671 * might actually have taken quite a while
2672 * (especially for SAE) and so the remaining
2673 * time could be small without us having heard
2674 * a beacon yet.
2675 */
23673041 2676 iwl_mvm_protect_assoc(mvm, vif, 0, 0);
016d27e1 2677 }
1f3b0ff8
LE
2678
2679 iwl_mvm_sf_update(mvm, vif, false);
175a70b7 2680 iwl_mvm_power_vif_assoc(mvm, vif);
697162a1 2681 if (vif->p2p) {
697162a1
EG
2682 iwl_mvm_update_smps(mvm, vif,
2683 IWL_MVM_SMPS_REQ_PROT,
1a3e7039 2684 IEEE80211_SMPS_DYNAMIC, 0);
697162a1 2685 }
650cadb7 2686 } else if (mvmvif->deflink.ap_sta_id != IWL_MVM_INVALID_STA) {
6d19a5eb 2687 iwl_mvm_mei_host_disassociated(mvm);
1f3b0ff8
LE
2688 /*
2689 * If update fails - SF might be running in associated
2690 * mode while disassociated - which is forbidden.
2691 */
69e508b4
IP
2692 ret = iwl_mvm_sf_update(mvm, vif, false);
2693 WARN_ONCE(ret &&
2694 !test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
2695 &mvm->status),
1f3b0ff8
LE
2696 "Failed to update SF upon disassociation\n");
2697
6b28f978
EG
2698 /*
2699 * If we get an assert during the connection (after the
2700 * station has been added, but before the vif is set
2701 * to associated), mac80211 will re-add the station and
2702 * then configure the vif. Since the vif is not
2703 * associated, we would remove the station here and
2704 * this would fail the recovery.
2705 */
2706 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
2707 &mvm->status)) {
5c75a208 2708 /* first remove remaining keys */
ba9eef6b 2709 iwl_mvm_sec_key_remove_ap(mvm, vif,
072573f6 2710 &mvmvif->deflink, 0);
5c75a208 2711
6b28f978
EG
2712 /*
2713 * Remove AP station now that
2714 * the MAC is unassoc
2715 */
2716 ret = iwl_mvm_rm_sta_id(mvm, vif,
650cadb7 2717 mvmvif->deflink.ap_sta_id);
6b28f978
EG
2718 if (ret)
2719 IWL_ERR(mvm,
2720 "failed to remove AP station\n");
2721
650cadb7 2722 mvmvif->deflink.ap_sta_id = IWL_MVM_INVALID_STA;
6b28f978 2723 }
37577fe2 2724
8ca151b5 2725 /* remove quota for this interface */
7754ae79 2726 ret = iwl_mvm_update_quotas(mvm, false, NULL);
8ca151b5
JB
2727 if (ret)
2728 IWL_ERR(mvm, "failed to update quotas\n");
29a90a49 2729
3dfd3a97
JB
2730 /* this will take the cleared BSSID from bss_conf */
2731 ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
2732 if (ret)
2733 IWL_ERR(mvm,
2734 "failed to update MAC %pM (clear after unassoc)\n",
2735 vif->addr);
8ca151b5 2736 }
a20fd398 2737
660eba5a 2738 iwl_mvm_bss_info_changed_station_assoc(mvm, vif, changes);
cc87d322 2739 }
a07a8f37 2740
1a3e7039
GG
2741 iwl_mvm_bss_info_changed_station_common(mvm, vif, &vif->bss_conf,
2742 changes);
8ca151b5 2743}
e59647ea 2744
f947b62c
MK
2745bool iwl_mvm_start_ap_ibss_common(struct ieee80211_hw *hw,
2746 struct ieee80211_vif *vif,
2747 int *ret)
2748{
2749 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2750 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2751 int i;
a20fd398 2752
f947b62c 2753 lockdep_assert_held(&mvm->mutex);
b45242c9 2754
f947b62c 2755 mvmvif->ap_assoc_sta_count = 0;
cc87d322 2756
f947b62c
MK
2757 /* must be set before quota calculations */
2758 mvmvif->ap_ibss_active = true;
cc87d322 2759
f947b62c
MK
2760 /* send all the early keys to the device now */
2761 for (i = 0; i < ARRAY_SIZE(mvmvif->ap_early_keys); i++) {
2762 struct ieee80211_key_conf *key = mvmvif->ap_early_keys[i];
2763
2764 if (!key)
2765 continue;
2766
2767 mvmvif->ap_early_keys[i] = NULL;
2768
2769 *ret = __iwl_mvm_mac_set_key(hw, SET_KEY, vif, NULL, key);
2770 if (*ret)
2771 return true;
1bc10d3b
JB
2772 }
2773
f947b62c
MK
2774 if (vif->type == NL80211_IFTYPE_AP && !vif->p2p) {
2775 iwl_mvm_vif_set_low_latency(mvmvif, true,
2776 LOW_LATENCY_VIF_TYPE);
2777 iwl_mvm_send_low_latency_cmd(mvm, true, mvmvif->id);
a20fd398 2778 }
2ee8f021 2779
f947b62c
MK
2780 /* power updated needs to be done before quotas */
2781 iwl_mvm_power_update_mac(mvm);
2782
2783 return false;
8ca151b5
JB
2784}
2785
5023d966 2786static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
ae7ba17b 2787 struct ieee80211_vif *vif,
b327c84c 2788 struct ieee80211_bss_conf *link_conf)
8ca151b5
JB
2789{
2790 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2791 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
f947b62c 2792 int ret;
8ca151b5
JB
2793
2794 mutex_lock(&mvm->mutex);
2795
6e97b0d2 2796 /*
cdaba917
EG
2797 * Re-calculate the tsf id, as the leader-follower relations depend on
2798 * the beacon interval, which was not known when the AP interface
2799 * was added.
6e97b0d2
IP
2800 */
2801 if (vif->type == NL80211_IFTYPE_AP)
2802 iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
2803
36cf5377
GG
2804 /* For older devices need to send beacon template before adding mac
2805 * context. For the newer, the beacon is a resource that belongs to a
2806 * MAC, so need to send beacon template after adding the mac.
2807 */
2808 if (mvm->trans->trans_cfg->device_family > IWL_DEVICE_FAMILY_22000) {
2809 /* Add the mac context */
2810 ret = iwl_mvm_mac_ctxt_add(mvm, vif);
2811 if (ret)
2812 goto out_unlock;
94939080 2813
36cf5377
GG
2814 /* Send the beacon template */
2815 ret = iwl_mvm_mac_ctxt_beacon_changed(mvm, vif, link_conf);
2816 if (ret)
2817 goto out_unlock;
2818 } else {
2819 /* Send the beacon template */
2820 ret = iwl_mvm_mac_ctxt_beacon_changed(mvm, vif, link_conf);
2821 if (ret)
2822 goto out_unlock;
2823
2824 /* Add the mac context */
2825 ret = iwl_mvm_mac_ctxt_add(mvm, vif);
2826 if (ret)
2827 goto out_unlock;
2828 }
8ca151b5
JB
2829
2830 /* Perform the binding */
2831 ret = iwl_mvm_binding_add_vif(mvm, vif);
2832 if (ret)
2833 goto out_remove;
2834
63dd5d02
SS
2835 /*
2836 * This is not very nice, but the simplest:
2837 * For older FWs adding the mcast sta before the bcast station may
2838 * cause assert 0x2b00.
2839 * This is fixed in later FW so make the order of removal depend on
2840 * the TLV
2841 */
2842 if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE)) {
2843 ret = iwl_mvm_add_mcast_sta(mvm, vif);
2844 if (ret)
2845 goto out_unbind;
2846 /*
2847 * Send the bcast station. At this stage the TBTT and DTIM time
2848 * events are added and applied to the scheduler
2849 */
2850 ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
2851 if (ret) {
2852 iwl_mvm_rm_mcast_sta(mvm, vif);
2853 goto out_unbind;
2854 }
2855 } else {
2856 /*
2857 * Send the bcast station. At this stage the TBTT and DTIM time
2858 * events are added and applied to the scheduler
2859 */
75fd4fec 2860 ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
63dd5d02
SS
2861 if (ret)
2862 goto out_unbind;
75fd4fec 2863 ret = iwl_mvm_add_mcast_sta(mvm, vif);
63dd5d02
SS
2864 if (ret) {
2865 iwl_mvm_send_rm_bcast_sta(mvm, vif);
2866 goto out_unbind;
2867 }
2868 }
26d6c16b 2869
f947b62c
MK
2870 if (iwl_mvm_start_ap_ibss_common(hw, vif, &ret))
2871 goto out_failed;
a11e144e 2872
7754ae79 2873 ret = iwl_mvm_update_quotas(mvm, false, NULL);
8ca151b5 2874 if (ret)
f947b62c 2875 goto out_failed;
8ca151b5 2876
5023d966 2877 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
8ca151b5 2878 if (vif->p2p && mvm->p2p_device_vif)
3dfd3a97 2879 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
8ca151b5 2880
8e484f0b 2881 iwl_mvm_bt_coex_vif_change(mvm);
dac94da8 2882
f697267f
AN
2883 /* we don't support TDLS during DCM */
2884 if (iwl_mvm_phy_ctx_count(mvm) > 1)
2885 iwl_mvm_teardown_tdls_peers(mvm);
2886
fd940de7 2887 iwl_mvm_ftm_restart_responder(mvm, vif, &vif->bss_conf);
b73f9a4a 2888
939e4904 2889 goto out_unlock;
8ca151b5 2890
f947b62c 2891out_failed:
999609f1 2892 iwl_mvm_power_update_mac(mvm);
5691e218 2893 mvmvif->ap_ibss_active = false;
013290aa 2894 iwl_mvm_send_rm_bcast_sta(mvm, vif);
ced19f26 2895 iwl_mvm_rm_mcast_sta(mvm, vif);
8ca151b5
JB
2896out_unbind:
2897 iwl_mvm_binding_remove_vif(mvm, vif);
2898out_remove:
2899 iwl_mvm_mac_ctxt_remove(mvm, vif);
2900out_unlock:
2901 mutex_unlock(&mvm->mutex);
2902 return ret;
2903}
2904
ae7ba17b
ST
2905static int iwl_mvm_start_ap(struct ieee80211_hw *hw,
2906 struct ieee80211_vif *vif,
b327c84c 2907 struct ieee80211_bss_conf *link_conf)
ae7ba17b 2908{
b327c84c 2909 return iwl_mvm_start_ap_ibss(hw, vif, link_conf);
ae7ba17b
ST
2910}
2911
2912static int iwl_mvm_start_ibss(struct ieee80211_hw *hw,
2913 struct ieee80211_vif *vif)
2914{
b327c84c 2915 return iwl_mvm_start_ap_ibss(hw, vif, &vif->bss_conf);
ae7ba17b
ST
2916}
2917
fd1a54c1
MK
2918/* Common part for MLD and non-MLD ops */
2919void iwl_mvm_stop_ap_ibss_common(struct iwl_mvm *mvm,
2920 struct ieee80211_vif *vif)
8ca151b5 2921{
8ca151b5
JB
2922 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2923
fd1a54c1 2924 lockdep_assert_held(&mvm->mutex);
38a12b5b 2925
fd1a54c1 2926 iwl_mvm_prepare_mac_removal(mvm, vif);
8ca151b5 2927
664322fa 2928 /* Handle AP stop while in CSA */
7f0a7c67
AO
2929 if (rcu_access_pointer(mvm->csa_vif) == vif) {
2930 iwl_mvm_remove_time_event(mvm, mvmvif,
2931 &mvmvif->time_event_data);
664322fa 2932 RCU_INIT_POINTER(mvm->csa_vif, NULL);
e9cb0327 2933 mvmvif->csa_countdown = false;
7f0a7c67 2934 }
664322fa 2935
003e5236
AO
2936 if (rcu_access_pointer(mvm->csa_tx_blocked_vif) == vif) {
2937 RCU_INIT_POINTER(mvm->csa_tx_blocked_vif, NULL);
2938 mvm->csa_tx_block_bcn_timeout = 0;
2939 }
2940
5023d966 2941 mvmvif->ap_ibss_active = false;
1c87bbad 2942 mvm->ap_last_beacon_gp2 = 0;
8ca151b5 2943
47242744
TM
2944 if (vif->type == NL80211_IFTYPE_AP && !vif->p2p) {
2945 iwl_mvm_vif_set_low_latency(mvmvif, false,
2946 LOW_LATENCY_VIF_TYPE);
2947 iwl_mvm_send_low_latency_cmd(mvm, false, mvmvif->id);
2948 }
2949
8e484f0b 2950 iwl_mvm_bt_coex_vif_change(mvm);
fd1a54c1
MK
2951}
2952
2953static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
2954 struct ieee80211_vif *vif,
2955 struct ieee80211_bss_conf *link_conf)
2956{
2957 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2958
2959 mutex_lock(&mvm->mutex);
2960
2961 iwl_mvm_stop_ap_ibss_common(mvm, vif);
dac94da8 2962
5023d966 2963 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
8ca151b5 2964 if (vif->p2p && mvm->p2p_device_vif)
3dfd3a97 2965 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
8ca151b5 2966
7754ae79 2967 iwl_mvm_update_quotas(mvm, false, NULL);
ced19f26 2968
be82ecd3
AS
2969 iwl_mvm_ftm_responder_clear(mvm, vif);
2970
ced19f26
SS
2971 /*
2972 * This is not very nice, but the simplest:
2973 * For older FWs removing the mcast sta before the bcast station may
2974 * cause assert 0x2b00.
2975 * This is fixed in later FW (which will stop beaconing when removing
2976 * bcast station).
2977 * So make the order of removal depend on the TLV
2978 */
2979 if (!fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
2980 iwl_mvm_rm_mcast_sta(mvm, vif);
013290aa 2981 iwl_mvm_send_rm_bcast_sta(mvm, vif);
ced19f26
SS
2982 if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
2983 iwl_mvm_rm_mcast_sta(mvm, vif);
8ca151b5 2984 iwl_mvm_binding_remove_vif(mvm, vif);
a11e144e 2985
999609f1 2986 iwl_mvm_power_update_mac(mvm);
a11e144e 2987
8ca151b5
JB
2988 iwl_mvm_mac_ctxt_remove(mvm, vif);
2989
2990 mutex_unlock(&mvm->mutex);
2991}
2992
ae7ba17b
ST
2993static void iwl_mvm_stop_ap(struct ieee80211_hw *hw,
2994 struct ieee80211_vif *vif,
b327c84c 2995 struct ieee80211_bss_conf *link_conf)
ae7ba17b 2996{
b327c84c 2997 iwl_mvm_stop_ap_ibss(hw, vif, link_conf);
ae7ba17b
ST
2998}
2999
3000static void iwl_mvm_stop_ibss(struct ieee80211_hw *hw,
3001 struct ieee80211_vif *vif)
3002{
b327c84c 3003 iwl_mvm_stop_ap_ibss(hw, vif, &vif->bss_conf);
ae7ba17b
ST
3004}
3005
5023d966
JB
3006static void
3007iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
3008 struct ieee80211_vif *vif,
3009 struct ieee80211_bss_conf *bss_conf,
7b7090b4 3010 u64 changes)
8ca151b5 3011{
be2056fc 3012 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
8a5e3660 3013
be2056fc
IP
3014 /* Changes will be applied when the AP/IBSS is started */
3015 if (!mvmvif->ap_ibss_active)
3016 return;
3017
863230da 3018 if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT |
f7d8b702 3019 BSS_CHANGED_BANDWIDTH | BSS_CHANGED_QOS) &&
3dfd3a97 3020 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL))
863230da 3021 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
8a5e3660 3022
8ca151b5 3023 /* Need to send a new beacon template to the FW */
863230da 3024 if (changes & BSS_CHANGED_BEACON &&
36cf5377 3025 iwl_mvm_mac_ctxt_beacon_changed(mvm, vif, &vif->bss_conf))
863230da 3026 IWL_WARN(mvm, "Failed updating beacon data\n");
79b7a69d 3027
b73f9a4a 3028 if (changes & BSS_CHANGED_FTM_RESPONDER) {
fd940de7 3029 int ret = iwl_mvm_ftm_start_responder(mvm, vif, &vif->bss_conf);
b73f9a4a
JB
3030
3031 if (ret)
3032 IWL_WARN(mvm, "Failed to enable FTM responder (%d)\n",
3033 ret);
3034 }
3035
8ca151b5
JB
3036}
3037
3038static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
3039 struct ieee80211_vif *vif,
3040 struct ieee80211_bss_conf *bss_conf,
7b7090b4 3041 u64 changes)
8ca151b5
JB
3042{
3043 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3044
3045 mutex_lock(&mvm->mutex);
3046
f276e20b 3047 if (changes & BSS_CHANGED_IDLE && !vif->cfg.idle)
c7d42480 3048 iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true);
723f02ed 3049
8ca151b5
JB
3050 switch (vif->type) {
3051 case NL80211_IFTYPE_STATION:
df7e3098 3052 iwl_mvm_bss_info_changed_station(mvm, vif, bss_conf, changes);
8ca151b5
JB
3053 break;
3054 case NL80211_IFTYPE_AP:
5023d966 3055 case NL80211_IFTYPE_ADHOC:
df7e3098 3056 iwl_mvm_bss_info_changed_ap_ibss(mvm, vif, bss_conf, changes);
8ca151b5 3057 break;
91b08c2d
AE
3058 case NL80211_IFTYPE_MONITOR:
3059 if (changes & BSS_CHANGED_MU_GROUPS)
3060 iwl_mvm_update_mu_groups(mvm, vif);
3061 break;
8ca151b5
JB
3062 default:
3063 /* shouldn't happen */
3064 WARN_ON_ONCE(1);
3065 }
3066
9aae43a4
JB
3067 if (changes & BSS_CHANGED_TXPOWER) {
3068 IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d dBm\n",
3069 bss_conf->txpower);
3070 iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower);
3071 }
3072
8ca151b5
JB
3073 mutex_unlock(&mvm->mutex);
3074}
3075
cbce62a3
MK
3076int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3077 struct ieee80211_scan_request *hw_req)
8ca151b5
JB
3078{
3079 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3080 int ret;
3081
6749dd80
LC
3082 if (hw_req->req.n_channels == 0 ||
3083 hw_req->req.n_channels > mvm->fw->ucode_capa.n_scan_channels)
8ca151b5
JB
3084 return -EINVAL;
3085
3086 mutex_lock(&mvm->mutex);
6749dd80 3087 ret = iwl_mvm_reg_scan_start(mvm, vif, &hw_req->req, &hw_req->ies);
8ca151b5 3088 mutex_unlock(&mvm->mutex);
6749dd80 3089
8ca151b5
JB
3090 return ret;
3091}
3092
cbce62a3
MK
3093void iwl_mvm_mac_cancel_hw_scan(struct ieee80211_hw *hw,
3094 struct ieee80211_vif *vif)
8ca151b5
JB
3095{
3096 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3097
3098 mutex_lock(&mvm->mutex);
3099
e7d3abab
LC
3100 /* Due to a race condition, it's possible that mac80211 asks
3101 * us to stop a hw_scan when it's already stopped. This can
3102 * happen, for instance, if we stopped the scan ourselves,
3103 * called ieee80211_scan_completed() and the userspace called
3104 * cancel scan scan before ieee80211_scan_work() could run.
3105 * To handle that, simply return if the scan is not running.
3106 */
262888fc 3107 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR)
c7d42480 3108 iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true);
8ca151b5
JB
3109
3110 mutex_unlock(&mvm->mutex);
3111}
3112
cbce62a3 3113void
8ca151b5 3114iwl_mvm_mac_allow_buffered_frames(struct ieee80211_hw *hw,
3e56eadf 3115 struct ieee80211_sta *sta, u16 tids,
8ca151b5
JB
3116 int num_frames,
3117 enum ieee80211_frame_release_type reason,
3118 bool more_data)
3119{
3120 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
8ca151b5 3121
3e56eadf 3122 /* Called when we need to transmit (a) frame(s) from mac80211 */
8ca151b5 3123
3e56eadf
JB
3124 iwl_mvm_sta_modify_sleep_tx_count(mvm, sta, reason, num_frames,
3125 tids, more_data, false);
3126}
3127
cbce62a3 3128void
3e56eadf
JB
3129iwl_mvm_mac_release_buffered_frames(struct ieee80211_hw *hw,
3130 struct ieee80211_sta *sta, u16 tids,
3131 int num_frames,
3132 enum ieee80211_frame_release_type reason,
3133 bool more_data)
3134{
3135 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3136
9a3fcf91 3137 /* Called when we need to transmit (a) frame(s) from agg or dqa queue */
3e56eadf
JB
3138
3139 iwl_mvm_sta_modify_sleep_tx_count(mvm, sta, reason, num_frames,
3140 tids, more_data, true);
8ca151b5
JB
3141}
3142
65e25482
JB
3143static void __iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
3144 enum sta_notify_cmd cmd,
3145 struct ieee80211_sta *sta)
8ca151b5
JB
3146{
3147 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
5b577a90 3148 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
c22b0ff5 3149 unsigned long txqs = 0, tids = 0;
3e56eadf 3150 int tid;
8ca151b5 3151
960f864b
JB
3152 /*
3153 * If we have TVQM then we get too high queue numbers - luckily
3154 * we really shouldn't get here with that because such hardware
3155 * should have firmware supporting buffer station offload.
3156 */
3157 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
3158 return;
3159
c22b0ff5 3160 spin_lock_bh(&mvmsta->lock);
311590a3 3161 for (tid = 0; tid < ARRAY_SIZE(mvmsta->tid_data); tid++) {
c22b0ff5
EG
3162 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
3163
6862fcee 3164 if (tid_data->txq_id == IWL_MVM_INVALID_QUEUE)
1c17627b
SS
3165 continue;
3166
c22b0ff5
EG
3167 __set_bit(tid_data->txq_id, &txqs);
3168
dd32162d 3169 if (iwl_mvm_tid_queued(mvm, tid_data) == 0)
c22b0ff5
EG
3170 continue;
3171
3172 __set_bit(tid, &tids);
3173 }
3174
8ca151b5
JB
3175 switch (cmd) {
3176 case STA_NOTIFY_SLEEP:
c22b0ff5 3177 for_each_set_bit(tid, &tids, IWL_MAX_TID_COUNT)
3e56eadf 3178 ieee80211_sta_set_buffered(sta, tid, true);
c22b0ff5
EG
3179
3180 if (txqs)
3181 iwl_trans_freeze_txq_timer(mvm->trans, txqs, true);
8ca151b5
JB
3182 /*
3183 * The fw updates the STA to be asleep. Tx packets on the Tx
3184 * queues to this station will not be transmitted. The fw will
3185 * send a Tx response with TX_STATUS_FAIL_DEST_PS.
3186 */
3187 break;
3188 case STA_NOTIFY_AWAKE:
c8ee33e1 3189 if (WARN_ON(mvmsta->deflink.sta_id == IWL_MVM_INVALID_STA))
8ca151b5 3190 break;
c22b0ff5
EG
3191
3192 if (txqs)
3193 iwl_trans_freeze_txq_timer(mvm->trans, txqs, false);
9cc40712 3194 iwl_mvm_sta_modify_ps_wake(mvm, sta);
8ca151b5
JB
3195 break;
3196 default:
3197 break;
3198 }
c22b0ff5 3199 spin_unlock_bh(&mvmsta->lock);
8ca151b5
JB
3200}
3201
cbce62a3
MK
3202void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3203 enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
65e25482
JB
3204{
3205 __iwl_mvm_mac_sta_notify(hw, cmd, sta);
3206}
3207
3208void iwl_mvm_sta_pm_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
3209{
3210 struct iwl_rx_packet *pkt = rxb_addr(rxb);
3211 struct iwl_mvm_pm_state_notification *notif = (void *)pkt->data;
3212 struct ieee80211_sta *sta;
3213 struct iwl_mvm_sta *mvmsta;
3214 bool sleeping = (notif->type != IWL_MVM_PM_EVENT_AWAKE);
3215
be9ae34e 3216 if (WARN_ON(notif->sta_id >= mvm->fw->ucode_capa.num_stations))
65e25482
JB
3217 return;
3218
3219 rcu_read_lock();
a9560029 3220 sta = rcu_dereference(mvm->fw_id_to_mac_id[notif->sta_id]);
65e25482
JB
3221 if (WARN_ON(IS_ERR_OR_NULL(sta))) {
3222 rcu_read_unlock();
3223 return;
3224 }
3225
3226 mvmsta = iwl_mvm_sta_from_mac80211(sta);
3227
3228 if (!mvmsta->vif ||
3229 mvmsta->vif->type != NL80211_IFTYPE_AP) {
3230 rcu_read_unlock();
3231 return;
3232 }
3233
3234 if (mvmsta->sleeping != sleeping) {
3235 mvmsta->sleeping = sleeping;
3236 __iwl_mvm_mac_sta_notify(mvm->hw,
3237 sleeping ? STA_NOTIFY_SLEEP : STA_NOTIFY_AWAKE,
3238 sta);
3239 ieee80211_sta_ps_transition(sta, sleeping);
3240 }
3241
3242 if (sleeping) {
3243 switch (notif->type) {
3244 case IWL_MVM_PM_EVENT_AWAKE:
3245 case IWL_MVM_PM_EVENT_ASLEEP:
3246 break;
3247 case IWL_MVM_PM_EVENT_UAPSD:
3248 ieee80211_sta_uapsd_trigger(sta, IEEE80211_NUM_TIDS);
3249 break;
3250 case IWL_MVM_PM_EVENT_PS_POLL:
3251 ieee80211_sta_pspoll(sta);
3252 break;
3253 default:
3254 break;
3255 }
3256 }
3257
3258 rcu_read_unlock();
3259}
3260
cbce62a3
MK
3261void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
3262 struct ieee80211_vif *vif,
3263 struct ieee80211_sta *sta)
1ddbbb0c
JB
3264{
3265 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
9d8ce6af 3266 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
79faae3a 3267 unsigned int link_id;
1ddbbb0c
JB
3268
3269 /*
3270 * This is called before mac80211 does RCU synchronisation,
3271 * so here we already invalidate our internal RCU-protected
3272 * station pointer. The rest of the code will thus no longer
3273 * be able to find the station this way, and we don't rely
3274 * on further RCU synchronisation after the sta_state()
3275 * callback deleted the station.
79faae3a
GG
3276 * Since there's mvm->mutex here, no need to have RCU lock for
3277 * mvm_sta->link access.
1ddbbb0c
JB
3278 */
3279 mutex_lock(&mvm->mutex);
79faae3a
GG
3280 for (link_id = 0; link_id < ARRAY_SIZE(mvm_sta->link); link_id++) {
3281 struct iwl_mvm_link_sta *link_sta;
3282 u32 sta_id;
94939080 3283
79faae3a
GG
3284 if (!mvm_sta->link[link_id])
3285 continue;
94939080 3286
79faae3a
GG
3287 link_sta = rcu_dereference_protected(mvm_sta->link[link_id],
3288 lockdep_is_held(&mvm->mutex));
3289 sta_id = link_sta->sta_id;
b8a85a1d 3290 if (sta == rcu_access_pointer(mvm->fw_id_to_mac_id[sta_id])) {
3e75668b
JB
3291 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta_id],
3292 ERR_PTR(-ENOENT));
b8a85a1d
JB
3293 RCU_INIT_POINTER(mvm->fw_id_to_link_sta[sta_id], NULL);
3294 }
79faae3a 3295 }
1ddbbb0c
JB
3296 mutex_unlock(&mvm->mutex);
3297}
3298
bd1ba664
JB
3299static void iwl_mvm_check_uapsd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
3300 const u8 *bssid)
3301{
b0ffe455
JB
3302 int i;
3303
3304 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
3305 struct iwl_mvm_tcm_mac *mdata;
3306
3307 mdata = &mvm->tcm.data[iwl_mvm_vif_from_mac80211(vif)->id];
3308 ewma_rate_init(&mdata->uapsd_nonagg_detect.rate);
3309 mdata->opened_rx_ba_sessions = false;
3310 }
3311
bd1ba664
JB
3312 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT))
3313 return;
3314
c5241b0c 3315 if (vif->p2p && !iwl_mvm_is_p2p_scm_uapsd_supported(mvm)) {
cee5a882
AA
3316 vif->driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD;
3317 return;
3318 }
3319
11dee0b4
EG
3320 if (!vif->p2p &&
3321 (iwlwifi_mod_params.uapsd_disable & IWL_DISABLE_UAPSD_BSS)) {
bd1ba664
JB
3322 vif->driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD;
3323 return;
3324 }
3325
b0ffe455
JB
3326 for (i = 0; i < IWL_MVM_UAPSD_NOAGG_LIST_LEN; i++) {
3327 if (ether_addr_equal(mvm->uapsd_noagg_bssids[i].addr, bssid)) {
3328 vif->driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD;
3329 return;
3330 }
3331 }
3332
bd1ba664
JB
3333 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
3334}
3335
1e8f1329
GBA
3336static void
3337iwl_mvm_tdls_check_trigger(struct iwl_mvm *mvm,
3338 struct ieee80211_vif *vif, u8 *peer_addr,
3339 enum nl80211_tdls_operation action)
3340{
3341 struct iwl_fw_dbg_trigger_tlv *trig;
3342 struct iwl_fw_dbg_trigger_tdls *tdls_trig;
3343
6c042d75
SS
3344 trig = iwl_fw_dbg_trigger_on(&mvm->fwrt, ieee80211_vif_to_wdev(vif),
3345 FW_DBG_TRIGGER_TDLS);
3346 if (!trig)
1e8f1329
GBA
3347 return;
3348
1e8f1329 3349 tdls_trig = (void *)trig->data;
1e8f1329
GBA
3350
3351 if (!(tdls_trig->action_bitmap & BIT(action)))
3352 return;
3353
3354 if (tdls_trig->peer_mode &&
3355 memcmp(tdls_trig->peer, peer_addr, ETH_ALEN) != 0)
3356 return;
3357
7174beb6
JB
3358 iwl_fw_dbg_collect_trig(&mvm->fwrt, trig,
3359 "TDLS event occurred, peer %pM, action %d",
3360 peer_addr, action);
1e8f1329
GBA
3361}
3362
4f58121d
IP
3363struct iwl_mvm_he_obss_narrow_bw_ru_data {
3364 bool tolerated;
3365};
3366
3367static void iwl_mvm_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
3368 struct cfg80211_bss *bss,
3369 void *_data)
3370{
3371 struct iwl_mvm_he_obss_narrow_bw_ru_data *data = _data;
6c608cd6 3372 const struct cfg80211_bss_ies *ies;
4f58121d
IP
3373 const struct element *elem;
3374
6c608cd6
JB
3375 rcu_read_lock();
3376 ies = rcu_dereference(bss->ies);
3377 elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, ies->data,
3378 ies->len);
4f58121d
IP
3379
3380 if (!elem || elem->datalen < 10 ||
3381 !(elem->data[10] &
3382 WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) {
3383 data->tolerated = false;
3384 }
6c608cd6 3385 rcu_read_unlock();
4f58121d
IP
3386}
3387
6e1b5956
JB
3388static void
3389iwl_mvm_check_he_obss_narrow_bw_ru(struct ieee80211_hw *hw,
3390 struct ieee80211_vif *vif,
3391 unsigned int link_id,
3392 struct ieee80211_bss_conf *link_conf)
4f58121d
IP
3393{
3394 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3395 struct iwl_mvm_he_obss_narrow_bw_ru_data iter_data = {
3396 .tolerated = true,
3397 };
3398
6e1b5956
JB
3399 if (WARN_ON_ONCE(!link_conf->chandef.chan ||
3400 !mvmvif->link[link_id]))
3401 return;
3402
3403 if (!(link_conf->chandef.chan->flags & IEEE80211_CHAN_RADAR)) {
3404 mvmvif->link[link_id]->he_ru_2mhz_block = false;
4f58121d
IP
3405 return;
3406 }
3407
6e1b5956 3408 cfg80211_bss_iter(hw->wiphy, &link_conf->chandef,
4f58121d
IP
3409 iwl_mvm_check_he_obss_narrow_bw_ru_iter,
3410 &iter_data);
3411
3412 /*
3413 * If there is at least one AP on radar channel that cannot
3414 * tolerate 26-tone RU UL OFDMA transmissions using HE TB PPDU.
3415 */
6e1b5956 3416 mvmvif->link[link_id]->he_ru_2mhz_block = !iter_data.tolerated;
4f58121d
IP
3417}
3418
f7d6ef33
JB
3419static void iwl_mvm_reset_cca_40mhz_workaround(struct iwl_mvm *mvm,
3420 struct ieee80211_vif *vif)
3421{
3422 struct ieee80211_supported_band *sband;
3423 const struct ieee80211_sta_he_cap *he_cap;
3424
3425 if (vif->type != NL80211_IFTYPE_STATION)
3426 return;
3427
3428 if (!mvm->cca_40mhz_workaround)
3429 return;
3430
3431 /* decrement and check that we reached zero */
3432 mvm->cca_40mhz_workaround--;
3433 if (mvm->cca_40mhz_workaround)
3434 return;
3435
3436 sband = mvm->hw->wiphy->bands[NL80211_BAND_2GHZ];
3437
3438 sband->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
3439
1ec7291e 3440 he_cap = ieee80211_get_he_iftype_cap_vif(sband, vif);
f7d6ef33
JB
3441
3442 if (he_cap) {
3443 /* we know that ours is writable */
0301bcd5 3444 struct ieee80211_sta_he_cap *he = (void *)(uintptr_t)he_cap;
f7d6ef33
JB
3445
3446 he->he_cap_elem.phy_cap_info[0] |=
3447 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
3448 }
3449}
3450
6d19a5eb
EG
3451static void iwl_mvm_mei_host_associated(struct iwl_mvm *mvm,
3452 struct ieee80211_vif *vif,
3453 struct iwl_mvm_sta *mvm_sta)
3454{
3455#if IS_ENABLED(CONFIG_IWLMEI)
3456 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3457 struct iwl_mei_conn_info conn_info = {
f276e20b 3458 .ssid_len = vif->cfg.ssid_len,
6d19a5eb
EG
3459 };
3460
3461 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
3462 return;
3463
3464 if (!mvm->mei_registered)
3465 return;
3466
6c07b73e
JB
3467 /* FIXME: MEI needs to be updated for MLO */
3468 if (!vif->bss_conf.chandef.chan)
3469 return;
3470
3471 conn_info.channel = vif->bss_conf.chandef.chan->hw_value;
3472
6d19a5eb 3473 switch (mvm_sta->pairwise_cipher) {
e5d3a64e
AS
3474 case WLAN_CIPHER_SUITE_TKIP:
3475 conn_info.pairwise_cipher = IWL_MEI_CIPHER_TKIP;
3476 break;
6d19a5eb
EG
3477 case WLAN_CIPHER_SUITE_CCMP:
3478 conn_info.pairwise_cipher = IWL_MEI_CIPHER_CCMP;
3479 break;
3480 case WLAN_CIPHER_SUITE_GCMP:
3481 conn_info.pairwise_cipher = IWL_MEI_CIPHER_GCMP;
3482 break;
3483 case WLAN_CIPHER_SUITE_GCMP_256:
3484 conn_info.pairwise_cipher = IWL_MEI_CIPHER_GCMP_256;
3485 break;
3486 case 0:
3487 /* open profile */
3488 break;
3489 default:
3490 /* cipher not supported, don't send anything to iwlmei */
3491 return;
3492 }
3493
3494 switch (mvmvif->rekey_data.akm) {
3495 case WLAN_AKM_SUITE_SAE & 0xff:
3496 conn_info.auth_mode = IWL_MEI_AKM_AUTH_SAE;
3497 break;
3498 case WLAN_AKM_SUITE_PSK & 0xff:
3499 conn_info.auth_mode = IWL_MEI_AKM_AUTH_RSNA_PSK;
3500 break;
3501 case WLAN_AKM_SUITE_8021X & 0xff:
3502 conn_info.auth_mode = IWL_MEI_AKM_AUTH_RSNA;
3503 break;
3504 case 0:
3505 /* open profile */
3506 conn_info.auth_mode = IWL_MEI_AKM_AUTH_OPEN;
3507 break;
3508 default:
3509 /* auth method / AKM not supported */
3510 /* TODO: All the FT vesions of these? */
3511 return;
3512 }
3513
f276e20b 3514 memcpy(conn_info.ssid, vif->cfg.ssid, vif->cfg.ssid_len);
6d19a5eb
EG
3515 memcpy(conn_info.bssid, vif->bss_conf.bssid, ETH_ALEN);
3516
3517 /* TODO: add support for collocated AP data */
3518 iwl_mei_host_associated(&conn_info, NULL);
3519#endif
3520}
3521
87f7e243
MK
3522static int iwl_mvm_mac_ctxt_changed_wrapper(struct iwl_mvm *mvm,
3523 struct ieee80211_vif *vif,
3524 bool force_assoc_off)
3525{
3526 return iwl_mvm_mac_ctxt_changed(mvm, vif, force_assoc_off, NULL);
3527}
3528
8ca151b5
JB
3529static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
3530 struct ieee80211_vif *vif,
3531 struct ieee80211_sta *sta,
3532 enum ieee80211_sta_state old_state,
3533 enum ieee80211_sta_state new_state)
87f7e243 3534{
a2906ea6 3535 static const struct iwl_mvm_sta_state_ops callbacks = {
87f7e243
MK
3536 .add_sta = iwl_mvm_add_sta,
3537 .update_sta = iwl_mvm_update_sta,
3538 .rm_sta = iwl_mvm_rm_sta,
3539 .mac_ctxt_changed = iwl_mvm_mac_ctxt_changed_wrapper,
3540 };
3541
3542 return iwl_mvm_mac_sta_state_common(hw, vif, sta, old_state, new_state,
3543 &callbacks);
3544}
3545
57974a55
GG
3546/* FIXME: temporary making two assumptions in all sta handling functions:
3547 * (1) when setting sta state, the link exists and protected
3548 * (2) if a link is valid in sta then it's valid in vif (can
3549 * use same index in the link array)
3550 */
f53be9c4
GG
3551static void iwl_mvm_rs_rate_init_all_links(struct iwl_mvm *mvm,
3552 struct ieee80211_vif *vif,
15d41834 3553 struct ieee80211_sta *sta)
f53be9c4
GG
3554{
3555 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3556 unsigned int link_id;
3557
3558 for_each_mvm_vif_valid_link(mvmvif, link_id) {
3559 struct ieee80211_bss_conf *conf =
a705a782 3560 link_conf_dereference_check(vif, link_id);
f53be9c4 3561 struct ieee80211_link_sta *link_sta =
a705a782 3562 link_sta_dereference_check(sta, link_id);
f53be9c4
GG
3563
3564 if (!conf || !link_sta || !mvmvif->link[link_id]->phy_ctxt)
3565 continue;
57974a55 3566
c45217bd 3567 iwl_mvm_rs_rate_init(mvm, vif, sta, conf, link_sta,
15d41834 3568 mvmvif->link[link_id]->phy_ctxt->channel->band);
f53be9c4
GG
3569 }
3570}
57974a55
GG
3571
3572#define IWL_MVM_MIN_BEACON_INTERVAL_TU 16
3573
3574static bool iwl_mvm_vif_conf_from_sta(struct iwl_mvm *mvm,
3575 struct ieee80211_vif *vif,
3576 struct ieee80211_sta *sta)
3577{
207be64f
MK
3578 struct ieee80211_link_sta *link_sta;
3579 unsigned int link_id;
57974a55
GG
3580
3581 /* Beacon interval check - firmware will crash if the beacon
3582 * interval is less than 16. We can't avoid connecting at all,
3583 * so refuse the station state change, this will cause mac80211
3584 * to abandon attempts to connect to this AP, and eventually
3585 * wpa_s will blocklist the AP...
3586 */
3587
207be64f 3588 for_each_sta_active_link(vif, sta, link_sta, link_id) {
57974a55 3589 struct ieee80211_bss_conf *link_conf =
207be64f 3590 link_conf_dereference_protected(vif, link_id);
57974a55 3591
207be64f 3592 if (!link_conf)
57974a55
GG
3593 continue;
3594
3595 if (link_conf->beacon_int < IWL_MVM_MIN_BEACON_INTERVAL_TU) {
3596 IWL_ERR(mvm,
3597 "Beacon interval %d for AP %pM is too small\n",
3598 link_conf->beacon_int, link_sta->addr);
3599 return false;
3600 }
3601
3602 link_conf->he_support = link_sta->he_cap.has_he;
3603 }
3604
3605 return true;
3606}
3607
3608static void iwl_mvm_vif_set_he_support(struct ieee80211_hw *hw,
3609 struct ieee80211_vif *vif,
3610 struct ieee80211_sta *sta,
3611 bool is_sta)
3612{
3613 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
207be64f
MK
3614 struct ieee80211_link_sta *link_sta;
3615 unsigned int link_id;
57974a55 3616
207be64f 3617 for_each_sta_active_link(vif, sta, link_sta, link_id) {
57974a55 3618 struct ieee80211_bss_conf *link_conf =
207be64f 3619 link_conf_dereference_protected(vif, link_id);
57974a55 3620
207be64f 3621 if (!link_conf || !mvmvif->link[link_id])
57974a55
GG
3622 continue;
3623
3624 link_conf->he_support = link_sta->he_cap.has_he;
3625
3626 if (is_sta) {
207be64f 3627 mvmvif->link[link_id]->he_ru_2mhz_block = false;
57974a55 3628 if (link_sta->he_cap.has_he)
207be64f
MK
3629 iwl_mvm_check_he_obss_narrow_bw_ru(hw, vif,
3630 link_id,
6e1b5956 3631 link_conf);
57974a55
GG
3632 }
3633 }
3634}
3635
3636static int
3637iwl_mvm_sta_state_notexist_to_none(struct iwl_mvm *mvm,
3638 struct ieee80211_vif *vif,
3639 struct ieee80211_sta *sta,
a2906ea6 3640 const struct iwl_mvm_sta_state_ops *callbacks)
57974a55 3641{
0c9a8f90 3642 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
207be64f 3643 struct ieee80211_link_sta *link_sta;
57974a55
GG
3644 unsigned int i;
3645 int ret;
3646
3647 lockdep_assert_held(&mvm->mutex);
3648
3649 if (vif->type == NL80211_IFTYPE_STATION &&
3650 !iwl_mvm_vif_conf_from_sta(mvm, vif, sta))
3651 return -EINVAL;
3652
3653 if (sta->tdls &&
3654 (vif->p2p ||
3655 iwl_mvm_tdls_sta_count(mvm, NULL) == IWL_MVM_TDLS_STA_COUNT ||
3656 iwl_mvm_phy_ctx_count(mvm) > 1)) {
3657 IWL_DEBUG_MAC80211(mvm, "refusing TDLS sta\n");
3658 return -EBUSY;
3659 }
3660
3661 ret = callbacks->add_sta(mvm, vif, sta);
3662 if (sta->tdls && ret == 0) {
3663 iwl_mvm_recalc_tdls_state(mvm, vif, true);
3664 iwl_mvm_tdls_check_trigger(mvm, vif, sta->addr,
3665 NL80211_TDLS_SETUP);
3666 }
3667
207be64f 3668 for_each_sta_active_link(vif, sta, link_sta, i)
57974a55 3669 link_sta->agg.max_rc_amsdu_len = 1;
207be64f 3670
57974a55
GG
3671 ieee80211_sta_recalc_aggregates(sta);
3672
0c9a8f90
JB
3673 if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
3674 mvmvif->ap_sta = sta;
3675
57974a55
GG
3676 return 0;
3677}
3678
3679static int
3680iwl_mvm_sta_state_auth_to_assoc(struct ieee80211_hw *hw,
3681 struct iwl_mvm *mvm,
3682 struct ieee80211_vif *vif,
3683 struct ieee80211_sta *sta,
a2906ea6 3684 const struct iwl_mvm_sta_state_ops *callbacks)
57974a55
GG
3685{
3686 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3687 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
207be64f
MK
3688 struct ieee80211_link_sta *link_sta;
3689 unsigned int link_id;
57974a55
GG
3690
3691 lockdep_assert_held(&mvm->mutex);
3692
3693 if (vif->type == NL80211_IFTYPE_AP) {
3694 iwl_mvm_vif_set_he_support(hw, vif, sta, false);
3695 mvmvif->ap_assoc_sta_count++;
3696 callbacks->mac_ctxt_changed(mvm, vif, false);
3697
3698 /* since the below is not for MLD API, it's ok to use
3699 * the default bss_conf
3700 */
3701 if (!mvm->mld_api_is_used &&
3702 ((vif->bss_conf.he_support &&
3703 !iwlwifi_mod_params.disable_11ax) ||
3704 (vif->bss_conf.eht_support &&
3705 !iwlwifi_mod_params.disable_11be)))
3706 iwl_mvm_cfg_he_sta(mvm, vif, mvm_sta->deflink.sta_id);
3707 } else if (vif->type == NL80211_IFTYPE_STATION) {
3708 iwl_mvm_vif_set_he_support(hw, vif, sta, true);
3709
3710 callbacks->mac_ctxt_changed(mvm, vif, false);
3711
3712 if (!mvm->mld_api_is_used)
3713 goto out;
3714
207be64f 3715 for_each_sta_active_link(vif, sta, link_sta, link_id) {
57974a55 3716 struct ieee80211_bss_conf *link_conf =
207be64f 3717 link_conf_dereference_protected(vif, link_id);
57974a55
GG
3718
3719 if (WARN_ON(!link_conf))
3720 return -EINVAL;
207be64f 3721 if (!mvmvif->link[link_id])
f14ad95a 3722 continue;
57974a55
GG
3723
3724 iwl_mvm_link_changed(mvm, vif, link_conf,
3725 LINK_CONTEXT_MODIFY_ALL &
3726 ~LINK_CONTEXT_MODIFY_ACTIVE,
3727 true);
3728 }
3729 }
3730
3731out:
15d41834 3732 iwl_mvm_rs_rate_init_all_links(mvm, vif, sta);
57974a55
GG
3733
3734 return callbacks->update_sta(mvm, vif, sta);
3735}
3736
3737static int
3738iwl_mvm_sta_state_assoc_to_authorized(struct iwl_mvm *mvm,
3739 struct ieee80211_vif *vif,
3740 struct ieee80211_sta *sta,
a2906ea6 3741 const struct iwl_mvm_sta_state_ops *callbacks)
57974a55
GG
3742{
3743 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3744 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
3745
3746 lockdep_assert_held(&mvm->mutex);
3747
3748 /* we don't support TDLS during DCM */
3749 if (iwl_mvm_phy_ctx_count(mvm) > 1)
3750 iwl_mvm_teardown_tdls_peers(mvm);
3751
3752 if (sta->tdls) {
3753 iwl_mvm_tdls_check_trigger(mvm, vif, sta->addr,
3754 NL80211_TDLS_ENABLE_LINK);
3755 } else {
3756 /* enable beacon filtering */
3757 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
3758
3759 mvmvif->authorized = 1;
3760
3761 callbacks->mac_ctxt_changed(mvm, vif, false);
3762 iwl_mvm_mei_host_associated(mvm, vif, mvm_sta);
b9be67fb
IP
3763
3764 /* when client is authorized (AP station marked as such),
3765 * try to enable more links
3766 */
3767 if (vif->type == NL80211_IFTYPE_STATION &&
3768 !test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
3769 iwl_mvm_mld_select_links(mvm, vif, false);
57974a55
GG
3770 }
3771
15d41834
JB
3772 mvm_sta->authorized = true;
3773
3774 iwl_mvm_rs_rate_init_all_links(mvm, vif, sta);
6d19a5eb 3775
5a86dcb4
AS
3776 /* MFP is set by default before the station is authorized.
3777 * Clear it here in case it's not used.
3778 */
3779 if (!sta->mfp)
3780 return callbacks->update_sta(mvm, vif, sta);
3781
57974a55 3782 return 0;
6d19a5eb
EG
3783}
3784
57974a55
GG
3785static int
3786iwl_mvm_sta_state_authorized_to_assoc(struct iwl_mvm *mvm,
3787 struct ieee80211_vif *vif,
3788 struct ieee80211_sta *sta,
a2906ea6 3789 const struct iwl_mvm_sta_state_ops *callbacks)
57974a55
GG
3790{
3791 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
15d41834 3792 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
57974a55
GG
3793
3794 lockdep_assert_held(&mvm->mutex);
3795
15d41834
JB
3796 mvmsta->authorized = false;
3797
57974a55
GG
3798 /* once we move into assoc state, need to update rate scale to
3799 * disable using wide bandwidth
3800 */
15d41834 3801 iwl_mvm_rs_rate_init_all_links(mvm, vif, sta);
57974a55
GG
3802
3803 if (!sta->tdls) {
3804 /* Set this but don't call iwl_mvm_mac_ctxt_changed()
3805 * yet to avoid sending high prio again for a little
3806 * time.
3807 */
3808 mvmvif->authorized = 0;
3809
3810 /* disable beacon filtering */
fccf5ff1 3811 iwl_mvm_disable_beacon_filter(mvm, vif, 0);
57974a55
GG
3812 }
3813
3814 return 0;
3815}
3816
87f7e243
MK
3817/* Common part for MLD and non-MLD modes */
3818int iwl_mvm_mac_sta_state_common(struct ieee80211_hw *hw,
8ca151b5
JB
3819 struct ieee80211_vif *vif,
3820 struct ieee80211_sta *sta,
3821 enum ieee80211_sta_state old_state,
87f7e243 3822 enum ieee80211_sta_state new_state,
a2906ea6 3823 const struct iwl_mvm_sta_state_ops *callbacks)
8ca151b5
JB
3824{
3825 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3826 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
6ea29ce5 3827 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
de107600 3828 struct ieee80211_link_sta *link_sta;
57974a55 3829 unsigned int link_id;
8ca151b5
JB
3830 int ret;
3831
3832 IWL_DEBUG_MAC80211(mvm, "station %pM state change %d->%d\n",
3833 sta->addr, old_state, new_state);
3834
24afba76
LK
3835 /*
3836 * If we are in a STA removal flow and in DQA mode:
3837 *
3838 * This is after the sync_rcu part, so the queues have already been
3839 * flushed. No more TXs on their way in mac80211's path, and no more in
3840 * the queues.
3841 * Also, we won't be getting any new TX frames for this station.
3842 * What we might have are deferred TX frames that need to be taken care
3843 * of.
3844 *
3845 * Drop any still-queued deferred-frame before removing the STA, and
3846 * make sure the worker is no longer handling frames for this STA.
3847 */
3848 if (old_state == IEEE80211_STA_NONE &&
c8f54701 3849 new_state == IEEE80211_STA_NOTEXIST) {
24afba76
LK
3850 flush_work(&mvm->add_stream_wk);
3851
3852 /*
3853 * No need to make sure deferred TX indication is off since the
3854 * worker will already remove it if it was on
3855 */
f7d6ef33
JB
3856
3857 /*
3858 * Additionally, reset the 40 MHz capability if we disconnected
3859 * from the AP now.
3860 */
3861 iwl_mvm_reset_cca_40mhz_workaround(mvm, vif);
783336b0
JB
3862
3863 /* Also free dup data just in case any assertions below fail */
3864 kfree(mvm_sta->dup_data);
24afba76
LK
3865 }
3866
8ca151b5 3867 mutex_lock(&mvm->mutex);
57974a55 3868
828c79d9
EG
3869 /* this would be a mac80211 bug ... but don't crash, unless we had a
3870 * firmware crash while we were activating a link, in which case it is
3871 * legit to have phy_ctxt = NULL. Don't bother not to WARN if we are in
3872 * recovery flow since we spit tons of error messages anyway.
3873 */
de107600 3874 for_each_sta_active_link(vif, sta, link_sta, link_id) {
3d6d21b2
JB
3875 if (WARN_ON_ONCE(!mvmvif->link[link_id] ||
3876 !mvmvif->link[link_id]->phy_ctxt)) {
57974a55
GG
3877 mutex_unlock(&mvm->mutex);
3878 return test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
3879 &mvm->status) ? 0 : -EINVAL;
3880 }
3881 }
3882
6ea29ce5 3883 /* track whether or not the station is associated */
d94c5a82 3884 mvm_sta->sta_state = new_state;
6ea29ce5 3885
8ca151b5
JB
3886 if (old_state == IEEE80211_STA_NOTEXIST &&
3887 new_state == IEEE80211_STA_NONE) {
57974a55
GG
3888 ret = iwl_mvm_sta_state_notexist_to_none(mvm, vif, sta,
3889 callbacks);
3890 if (ret < 0)
48bc1307 3891 goto out_unlock;
8ca151b5
JB
3892 } else if (old_state == IEEE80211_STA_NONE &&
3893 new_state == IEEE80211_STA_AUTH) {
e820c2da
HD
3894 /*
3895 * EBS may be disabled due to previous failures reported by FW.
3896 * Reset EBS status here assuming environment has been changed.
3897 */
3898 mvm->last_ebs_successful = true;
bd1ba664 3899 iwl_mvm_check_uapsd(mvm, vif, sta->addr);
8ca151b5
JB
3900 ret = 0;
3901 } else if (old_state == IEEE80211_STA_AUTH &&
3902 new_state == IEEE80211_STA_ASSOC) {
57974a55
GG
3903 ret = iwl_mvm_sta_state_auth_to_assoc(hw, mvm, vif, sta,
3904 callbacks);
8ca151b5
JB
3905 } else if (old_state == IEEE80211_STA_ASSOC &&
3906 new_state == IEEE80211_STA_AUTHORIZED) {
57974a55
GG
3907 ret = iwl_mvm_sta_state_assoc_to_authorized(mvm, vif, sta,
3908 callbacks);
8ca151b5
JB
3909 } else if (old_state == IEEE80211_STA_AUTHORIZED &&
3910 new_state == IEEE80211_STA_ASSOC) {
57974a55
GG
3911 ret = iwl_mvm_sta_state_authorized_to_assoc(mvm, vif, sta,
3912 callbacks);
8ca151b5
JB
3913 } else if (old_state == IEEE80211_STA_ASSOC &&
3914 new_state == IEEE80211_STA_AUTH) {
8be30c13
AB
3915 if (vif->type == NL80211_IFTYPE_AP) {
3916 mvmvif->ap_assoc_sta_count--;
87f7e243 3917 callbacks->mac_ctxt_changed(mvm, vif, false);
d5d8ee52 3918 } else if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
cf7a7457 3919 iwl_mvm_stop_session_protection(mvm, vif);
8ca151b5
JB
3920 ret = 0;
3921 } else if (old_state == IEEE80211_STA_AUTH &&
3922 new_state == IEEE80211_STA_NONE) {
3923 ret = 0;
3924 } else if (old_state == IEEE80211_STA_NONE &&
3925 new_state == IEEE80211_STA_NOTEXIST) {
0c9a8f90 3926 if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
d5d8ee52 3927 iwl_mvm_stop_session_protection(mvm, vif);
0c9a8f90
JB
3928 mvmvif->ap_sta = NULL;
3929 }
87f7e243 3930 ret = callbacks->rm_sta(mvm, vif, sta);
1e8f1329 3931 if (sta->tdls) {
fa3d07e4 3932 iwl_mvm_recalc_tdls_state(mvm, vif, false);
1e8f1329
GBA
3933 iwl_mvm_tdls_check_trigger(mvm, vif, sta->addr,
3934 NL80211_TDLS_DISABLE_LINK);
3935 }
34a880d8 3936
44135b7c
IP
3937 if (unlikely(ret &&
3938 test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
3939 &mvm->status)))
3940 ret = 0;
8ca151b5
JB
3941 } else {
3942 ret = -EIO;
3943 }
48bc1307 3944 out_unlock:
8ca151b5
JB
3945 mutex_unlock(&mvm->mutex);
3946
9c126cd6
LK
3947 if (sta->tdls && ret == 0) {
3948 if (old_state == IEEE80211_STA_NOTEXIST &&
3949 new_state == IEEE80211_STA_NONE)
3950 ieee80211_reserve_tid(sta, IWL_MVM_TDLS_FW_TID);
3951 else if (old_state == IEEE80211_STA_NONE &&
3952 new_state == IEEE80211_STA_NOTEXIST)
3953 ieee80211_unreserve_tid(sta, IWL_MVM_TDLS_FW_TID);
3954 }
3955
8ca151b5
JB
3956 return ret;
3957}
3958
cbce62a3 3959int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
8ca151b5
JB
3960{
3961 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3962
3963 mvm->rts_threshold = value;
3964
3965 return 0;
3966}
3967
cbce62a3
MK
3968void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3969 struct ieee80211_sta *sta, u32 changed)
1f3b0ff8
LE
3970{
3971 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
dcfe3b10
JB
3972
3973 if (changed & (IEEE80211_RC_BW_CHANGED |
3974 IEEE80211_RC_SUPP_RATES_CHANGED |
3975 IEEE80211_RC_NSS_CHANGED))
15d41834 3976 iwl_mvm_rs_rate_init_all_links(mvm, vif, sta);
1f3b0ff8
LE
3977
3978 if (vif->type == NL80211_IFTYPE_STATION &&
3979 changed & IEEE80211_RC_NSS_CHANGED)
3980 iwl_mvm_sf_update(mvm, vif, false);
3981}
3982
8ca151b5 3983static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,
b3e2130b
JB
3984 struct ieee80211_vif *vif,
3985 unsigned int link_id, u16 ac,
8ca151b5
JB
3986 const struct ieee80211_tx_queue_params *params)
3987{
3988 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3989 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3990
650cadb7 3991 mvmvif->deflink.queue_params[ac] = *params;
8ca151b5
JB
3992
3993 /*
3994 * No need to update right away, we'll get BSS_CHANGED_QOS
3995 * The exception is P2P_DEVICE interface which needs immediate update.
3996 */
3997 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
3998 int ret;
3999
4000 mutex_lock(&mvm->mutex);
3dfd3a97 4001 ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
8ca151b5
JB
4002 mutex_unlock(&mvm->mutex);
4003 return ret;
4004 }
4005 return 0;
4006}
4007
cbce62a3
MK
4008void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
4009 struct ieee80211_vif *vif,
4010 struct ieee80211_prep_tx_info *info)
8ca151b5
JB
4011{
4012 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
d4e36e55 4013
8ca151b5 4014 mutex_lock(&mvm->mutex);
23673041 4015 iwl_mvm_protect_assoc(mvm, vif, info->duration, info->link_id);
8ca151b5
JB
4016 mutex_unlock(&mvm->mutex);
4017}
4018
cbce62a3
MK
4019void iwl_mvm_mac_mgd_complete_tx(struct ieee80211_hw *hw,
4020 struct ieee80211_vif *vif,
4021 struct ieee80211_prep_tx_info *info)
6b1259d1
JB
4022{
4023 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
4024
4025 /* for successful cases (auth/assoc), don't cancel session protection */
4026 if (info->success)
4027 return;
4028
4029 mutex_lock(&mvm->mutex);
4030 iwl_mvm_stop_session_protection(mvm, vif);
4031 mutex_unlock(&mvm->mutex);
4032}
4033
cbce62a3
MK
4034int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
4035 struct ieee80211_vif *vif,
4036 struct cfg80211_sched_scan_request *req,
4037 struct ieee80211_scan_ies *ies)
35a000b7
DS
4038{
4039 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
35a000b7 4040
35a000b7 4041 int ret;
4660dfbb 4042
35a000b7
DS
4043 mutex_lock(&mvm->mutex);
4044
f276e20b 4045 if (!vif->cfg.idle) {
bd5e4744
DS
4046 ret = -EBUSY;
4047 goto out;
4048 }
4049
19945dfb 4050 ret = iwl_mvm_sched_scan_start(mvm, vif, req, ies, IWL_MVM_SCAN_SCHED);
d2496221 4051
35a000b7
DS
4052out:
4053 mutex_unlock(&mvm->mutex);
4054 return ret;
4055}
4056
cbce62a3
MK
4057int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
4058 struct ieee80211_vif *vif)
35a000b7
DS
4059{
4060 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
33ea27f6 4061 int ret;
35a000b7
DS
4062
4063 mutex_lock(&mvm->mutex);
e7d3abab
LC
4064
4065 /* Due to a race condition, it's possible that mac80211 asks
4066 * us to stop a sched_scan when it's already stopped. This
4067 * can happen, for instance, if we stopped the scan ourselves,
4068 * called ieee80211_sched_scan_stopped() and the userspace called
4069 * stop sched scan scan before ieee80211_sched_scan_stopped_work()
4070 * could run. To handle this, simply return if the scan is
4071 * not running.
4072 */
262888fc 4073 if (!(mvm->scan_status & IWL_MVM_SCAN_SCHED)) {
e7d3abab
LC
4074 mutex_unlock(&mvm->mutex);
4075 return 0;
4076 }
4077
c7d42480 4078 ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, false);
35a000b7 4079 mutex_unlock(&mvm->mutex);
33ea27f6 4080 iwl_mvm_wait_for_async_handlers(mvm);
37e3308c 4081
33ea27f6 4082 return ret;
35a000b7
DS
4083}
4084
6569e7d3
JB
4085static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
4086 enum set_key_cmd cmd,
4087 struct ieee80211_vif *vif,
4088 struct ieee80211_sta *sta,
4089 struct ieee80211_key_conf *key)
8ca151b5 4090{
c56e00a3 4091 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
8ca151b5 4092 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
46c7b05a 4093 struct iwl_mvm_sta *mvmsta = NULL;
d066a530 4094 struct iwl_mvm_key_pn *ptk_pn = NULL;
f5e28eac 4095 int keyidx = key->keyidx;
5c75a208
JB
4096 u32 sec_key_id = WIDE_ID(DATA_PATH_GROUP, SEC_KEY_CMD);
4097 u8 sec_key_ver = iwl_fw_lookup_cmd_ver(mvm->fw, sec_key_id, 0);
c56e00a3 4098 int ret, i;
d6ee54a9 4099 u8 key_offset;
8ca151b5 4100
46c7b05a
EG
4101 if (sta)
4102 mvmsta = iwl_mvm_sta_from_mac80211(sta);
6d19a5eb 4103
8ca151b5
JB
4104 switch (key->cipher) {
4105 case WLAN_CIPHER_SUITE_TKIP:
286ca8eb 4106 if (!mvm->trans->trans_cfg->gen2) {
7f768ad5
DS
4107 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
4108 key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
4109 } else if (vif->type == NL80211_IFTYPE_STATION) {
4110 key->flags |= IEEE80211_KEY_FLAG_PUT_MIC_SPACE;
4111 } else {
4112 IWL_DEBUG_MAC80211(mvm, "Use SW encryption for TKIP\n");
4113 return -EOPNOTSUPP;
4114 }
8ca151b5 4115 break;
ca8c0f4b 4116 case WLAN_CIPHER_SUITE_CCMP:
2a53d166
AB
4117 case WLAN_CIPHER_SUITE_GCMP:
4118 case WLAN_CIPHER_SUITE_GCMP_256:
85aeb58c
DS
4119 if (!iwl_mvm_has_new_tx_api(mvm))
4120 key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
ca8c0f4b 4121 break;
8ca151b5 4122 case WLAN_CIPHER_SUITE_AES_CMAC:
8e160ab8
AB
4123 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
4124 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
30686bf7 4125 WARN_ON_ONCE(!ieee80211_hw_check(hw, MFP_CAPABLE));
8ca151b5
JB
4126 break;
4127 case WLAN_CIPHER_SUITE_WEP40:
4128 case WLAN_CIPHER_SUITE_WEP104:
475c6bde
JB
4129 if (vif->type == NL80211_IFTYPE_STATION)
4130 break;
4131 if (iwl_mvm_has_new_tx_api(mvm))
4132 return -EOPNOTSUPP;
4133 /* support HW crypto on TX */
4134 return 0;
8ca151b5 4135 default:
8b3d2c48 4136 return -EOPNOTSUPP;
8ca151b5
JB
4137 }
4138
8ca151b5
JB
4139 switch (cmd) {
4140 case SET_KEY:
a5de7de7
JB
4141 if (vif->type == NL80211_IFTYPE_STATION &&
4142 (keyidx == 6 || keyidx == 7))
b1fdc250
JB
4143 rcu_assign_pointer(mvmvif->bcn_prot.keys[keyidx - 6],
4144 key);
4145
5023d966
JB
4146 if ((vif->type == NL80211_IFTYPE_ADHOC ||
4147 vif->type == NL80211_IFTYPE_AP) && !sta) {
4148 /*
4149 * GTK on AP interface is a TX-only key, return 0;
4150 * on IBSS they're per-station and because we're lazy
4151 * we don't support them for RX, so do the same.
f05d1e04
JB
4152 * CMAC/GMAC in AP/IBSS modes must be done in software
4153 * on older NICs.
a5de7de7
JB
4154 *
4155 * Except, of course, beacon protection - it must be
f05d1e04
JB
4156 * offloaded since we just set a beacon template, and
4157 * then we must also offload the IGTK (not just BIGTK)
4158 * for firmware reasons.
4159 *
4160 * So just check for beacon protection - if we don't
4161 * have it we cannot get here with keyidx >= 6, and
4162 * if we do have it we need to send the key to FW in
4163 * all cases (CMAC/GMAC).
5023d966 4164 */
f05d1e04
JB
4165 if (!wiphy_ext_feature_isset(hw->wiphy,
4166 NL80211_EXT_FEATURE_BEACON_PROTECTION) &&
a5de7de7
JB
4167 (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
4168 key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
4169 key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256)) {
81279c49 4170 ret = -EOPNOTSUPP;
a1c2ff30
AO
4171 break;
4172 }
85aeb58c
DS
4173
4174 if (key->cipher != WLAN_CIPHER_SUITE_GCMP &&
4175 key->cipher != WLAN_CIPHER_SUITE_GCMP_256 &&
4176 !iwl_mvm_has_new_tx_api(mvm)) {
4177 key->hw_key_idx = STA_KEY_IDX_INVALID;
a1c2ff30 4178 ret = 0;
85aeb58c
DS
4179 break;
4180 }
c56e00a3
JB
4181
4182 if (!mvmvif->ap_ibss_active) {
4183 for (i = 0;
4184 i < ARRAY_SIZE(mvmvif->ap_early_keys);
4185 i++) {
4186 if (!mvmvif->ap_early_keys[i]) {
4187 mvmvif->ap_early_keys[i] = key;
4188 break;
4189 }
4190 }
4191
4192 if (i >= ARRAY_SIZE(mvmvif->ap_early_keys))
4193 ret = -ENOSPC;
a1c2ff30
AO
4194 else
4195 ret = 0;
c56e00a3
JB
4196
4197 break;
4198 }
6caffd4f
JB
4199 }
4200
b546dcd6
JB
4201 /* During FW restart, in order to restore the state as it was,
4202 * don't try to reprogram keys we previously failed for.
4203 */
4204 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
4205 key->hw_key_idx == STA_KEY_IDX_INVALID) {
4206 IWL_DEBUG_MAC80211(mvm,
4207 "skip invalid idx key programming during restart\n");
4208 ret = 0;
4209 break;
4210 }
4211
f5e28eac 4212 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
46c7b05a 4213 mvmsta && iwl_mvm_has_new_rx_api(mvm) &&
f5e28eac
JB
4214 key->flags & IEEE80211_KEY_FLAG_PAIRWISE &&
4215 (key->cipher == WLAN_CIPHER_SUITE_CCMP ||
2a53d166
AB
4216 key->cipher == WLAN_CIPHER_SUITE_GCMP ||
4217 key->cipher == WLAN_CIPHER_SUITE_GCMP_256)) {
f5e28eac
JB
4218 struct ieee80211_key_seq seq;
4219 int tid, q;
4220
f5e28eac 4221 WARN_ON(rcu_access_pointer(mvmsta->ptk_pn[keyidx]));
acafe7e3
KC
4222 ptk_pn = kzalloc(struct_size(ptk_pn, q,
4223 mvm->trans->num_rx_queues),
f5e28eac
JB
4224 GFP_KERNEL);
4225 if (!ptk_pn) {
4226 ret = -ENOMEM;
4227 break;
4228 }
4229
4230 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
4231 ieee80211_get_key_rx_seq(key, tid, &seq);
4232 for (q = 0; q < mvm->trans->num_rx_queues; q++)
4233 memcpy(ptk_pn->q[q].pn[tid],
4234 seq.ccmp.pn,
4235 IEEE80211_CCMP_PN_LEN);
4236 }
4237
4238 rcu_assign_pointer(mvmsta->ptk_pn[keyidx], ptk_pn);
4239 }
4240
d6ee54a9
LC
4241 /* in HW restart reuse the index, otherwise request a new one */
4242 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
4243 key_offset = key->hw_key_idx;
4244 else
4245 key_offset = STA_KEY_IDX_INVALID;
4246
46c7b05a 4247 if (mvmsta && key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
6d19a5eb
EG
4248 mvmsta->pairwise_cipher = key->cipher;
4249
a5de7de7
JB
4250 IWL_DEBUG_MAC80211(mvm, "set hwcrypto key (sta:%pM, id:%d)\n",
4251 sta ? sta->addr : NULL, key->keyidx);
5c75a208
JB
4252
4253 if (sec_key_ver)
4254 ret = iwl_mvm_sec_key_add(mvm, vif, sta, key);
4255 else
4256 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, key_offset);
4257
8ca151b5
JB
4258 if (ret) {
4259 IWL_WARN(mvm, "set key failed\n");
475c6bde 4260 key->hw_key_idx = STA_KEY_IDX_INVALID;
d066a530
JB
4261 if (ptk_pn) {
4262 RCU_INIT_POINTER(mvmsta->ptk_pn[keyidx], NULL);
4263 kfree(ptk_pn);
4264 }
8ca151b5
JB
4265 /*
4266 * can't add key for RX, but we don't need it
475c6bde
JB
4267 * in the device for TX so still return 0,
4268 * unless we have new TX API where we cannot
4269 * put key material into the TX_CMD
8ca151b5 4270 */
475c6bde
JB
4271 if (iwl_mvm_has_new_tx_api(mvm))
4272 ret = -EOPNOTSUPP;
4273 else
4274 ret = 0;
8ca151b5
JB
4275 }
4276
4277 break;
4278 case DISABLE_KEY:
a5de7de7
JB
4279 if (vif->type == NL80211_IFTYPE_STATION &&
4280 (keyidx == 6 || keyidx == 7))
b1fdc250
JB
4281 RCU_INIT_POINTER(mvmvif->bcn_prot.keys[keyidx - 6],
4282 NULL);
4283
c56e00a3
JB
4284 ret = -ENOENT;
4285 for (i = 0; i < ARRAY_SIZE(mvmvif->ap_early_keys); i++) {
4286 if (mvmvif->ap_early_keys[i] == key) {
4287 mvmvif->ap_early_keys[i] = NULL;
4288 ret = 0;
4289 }
4290 }
4291
4292 /* found in pending list - don't do anything else */
4293 if (ret == 0)
4294 break;
4295
6caffd4f
JB
4296 if (key->hw_key_idx == STA_KEY_IDX_INVALID) {
4297 ret = 0;
4298 break;
4299 }
4300
46c7b05a 4301 if (mvmsta && iwl_mvm_has_new_rx_api(mvm) &&
f5e28eac
JB
4302 key->flags & IEEE80211_KEY_FLAG_PAIRWISE &&
4303 (key->cipher == WLAN_CIPHER_SUITE_CCMP ||
2a53d166
AB
4304 key->cipher == WLAN_CIPHER_SUITE_GCMP ||
4305 key->cipher == WLAN_CIPHER_SUITE_GCMP_256)) {
f5e28eac
JB
4306 ptk_pn = rcu_dereference_protected(
4307 mvmsta->ptk_pn[keyidx],
4308 lockdep_is_held(&mvm->mutex));
4309 RCU_INIT_POINTER(mvmsta->ptk_pn[keyidx], NULL);
4310 if (ptk_pn)
4311 kfree_rcu(ptk_pn, rcu_head);
4312 }
4313
8ca151b5 4314 IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n");
5c75a208
JB
4315 if (sec_key_ver)
4316 ret = iwl_mvm_sec_key_del(mvm, vif, sta, key);
4317 else
4318 ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key);
8ca151b5
JB
4319 break;
4320 default:
4321 ret = -EINVAL;
4322 }
4323
6569e7d3
JB
4324 return ret;
4325}
4326
cbce62a3
MK
4327int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
4328 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
4329 struct ieee80211_key_conf *key)
6569e7d3
JB
4330{
4331 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
4332 int ret;
4333
4334 mutex_lock(&mvm->mutex);
4335 ret = __iwl_mvm_mac_set_key(hw, cmd, vif, sta, key);
8ca151b5 4336 mutex_unlock(&mvm->mutex);
6569e7d3 4337
8ca151b5
JB
4338 return ret;
4339}
4340
cbce62a3
MK
4341void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw,
4342 struct ieee80211_vif *vif,
4343 struct ieee80211_key_conf *keyconf,
4344 struct ieee80211_sta *sta,
4345 u32 iv32, u16 *phase1key)
8ca151b5
JB
4346{
4347 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
4348
5023d966
JB
4349 if (keyconf->hw_key_idx == STA_KEY_IDX_INVALID)
4350 return;
4351
8ca151b5
JB
4352 iwl_mvm_update_tkip_key(mvm, vif, keyconf, sta, iv32, phase1key);
4353}
4354
4355
b112889c
AM
4356static bool iwl_mvm_rx_aux_roc(struct iwl_notif_wait_data *notif_wait,
4357 struct iwl_rx_packet *pkt, void *data)
4358{
4359 struct iwl_mvm *mvm =
4360 container_of(notif_wait, struct iwl_mvm, notif_wait);
4361 struct iwl_hs20_roc_res *resp;
4362 int resp_len = iwl_rx_packet_payload_len(pkt);
4363 struct iwl_mvm_time_event_data *te_data = data;
4364
4365 if (WARN_ON(pkt->hdr.cmd != HOT_SPOT_CMD))
4366 return true;
4367
4368 if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
4369 IWL_ERR(mvm, "Invalid HOT_SPOT_CMD response\n");
4370 return true;
4371 }
4372
4373 resp = (void *)pkt->data;
4374
4375 IWL_DEBUG_TE(mvm,
b71a9c35 4376 "Aux ROC: Received response from ucode: status=%d uid=%d\n",
b112889c
AM
4377 resp->status, resp->event_unique_id);
4378
4379 te_data->uid = le32_to_cpu(resp->event_unique_id);
4380 IWL_DEBUG_TE(mvm, "TIME_EVENT_CMD response - UID = 0x%x\n",
4381 te_data->uid);
4382
4383 spin_lock_bh(&mvm->time_event_lock);
4384 list_add_tail(&te_data->list, &mvm->aux_roc_te_list);
4385 spin_unlock_bh(&mvm->time_event_lock);
4386
4387 return true;
4388}
4389
dc28e12f
MG
4390#define AUX_ROC_MIN_DURATION MSEC_TO_TU(100)
4391#define AUX_ROC_MIN_DELAY MSEC_TO_TU(200)
4392#define AUX_ROC_MAX_DELAY MSEC_TO_TU(600)
4393#define AUX_ROC_SAFETY_BUFFER MSEC_TO_TU(20)
4394#define AUX_ROC_MIN_SAFETY_BUFFER MSEC_TO_TU(10)
67ac248e
ST
4395
4396static void iwl_mvm_roc_duration_and_delay(struct ieee80211_vif *vif,
4397 u32 duration_ms,
4398 u32 *duration_tu,
4399 u32 *delay)
4400{
4401 u32 dtim_interval = vif->bss_conf.dtim_period *
4402 vif->bss_conf.beacon_int;
4403
4404 *delay = AUX_ROC_MIN_DELAY;
4405 *duration_tu = MSEC_TO_TU(duration_ms);
4406
4407 /*
4408 * If we are associated we want the delay time to be at least one
4409 * dtim interval so that the FW can wait until after the DTIM and
4410 * then start the time event, this will potentially allow us to
4411 * remain off-channel for the max duration.
4412 * Since we want to use almost a whole dtim interval we would also
4413 * like the delay to be for 2-3 dtim intervals, in case there are
4414 * other time events with higher priority.
4415 */
4416 if (vif->cfg.assoc) {
4417 *delay = min_t(u32, dtim_interval * 3, AUX_ROC_MAX_DELAY);
4418 /* We cannot remain off-channel longer than the DTIM interval */
4419 if (dtim_interval <= *duration_tu) {
4420 *duration_tu = dtim_interval - AUX_ROC_SAFETY_BUFFER;
4421 if (*duration_tu <= AUX_ROC_MIN_DURATION)
4422 *duration_tu = dtim_interval -
4423 AUX_ROC_MIN_SAFETY_BUFFER;
4424 }
4425 }
4426}
4427
b112889c
AM
4428static int iwl_mvm_send_aux_roc_cmd(struct iwl_mvm *mvm,
4429 struct ieee80211_channel *channel,
4430 struct ieee80211_vif *vif,
4431 int duration)
4432{
afc1e3b4 4433 int res;
b112889c
AM
4434 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
4435 struct iwl_mvm_time_event_data *te_data = &mvmvif->hs_time_event_data;
6eb031d2 4436 static const u16 time_event_response[] = { HOT_SPOT_CMD };
b112889c 4437 struct iwl_notification_wait wait_time_event;
dc28e12f 4438 u32 req_dur, delay;
b112889c
AM
4439 struct iwl_hs20_roc_req aux_roc_req = {
4440 .action = cpu_to_le32(FW_CTXT_ACTION_ADD),
4441 .id_and_color =
4442 cpu_to_le32(FW_CMD_ID_AND_COLOR(MAC_INDEX_AUX, 0)),
4443 .sta_id_and_color = cpu_to_le32(mvm->aux_sta.sta_id),
57e861d9
DS
4444 };
4445 struct iwl_hs20_roc_req_tail *tail = iwl_mvm_chan_info_cmd_tail(mvm,
4446 &aux_roc_req.channel_info);
4447 u16 len = sizeof(aux_roc_req) - iwl_mvm_chan_info_padding(mvm);
4448
4449 /* Set the channel info data */
4450 iwl_mvm_set_chan_info(mvm, &aux_roc_req.channel_info, channel->hw_value,
3717f91a 4451 iwl_mvm_phy_band_from_nl80211(channel->band),
7ac87575 4452 IWL_PHY_CHANNEL_MODE20,
57e861d9
DS
4453 0);
4454
4455 /* Set the time and duration */
afc1e3b4 4456 tail->apply_time = cpu_to_le32(iwl_mvm_get_systime(mvm));
b112889c 4457
67ac248e 4458 iwl_mvm_roc_duration_and_delay(vif, duration, &req_dur, &delay);
57e861d9
DS
4459 tail->duration = cpu_to_le32(req_dur);
4460 tail->apply_time_max_delay = cpu_to_le32(delay);
dc28e12f
MG
4461
4462 IWL_DEBUG_TE(mvm,
903b3f9b
EG
4463 "ROC: Requesting to remain on channel %u for %ums\n",
4464 channel->hw_value, req_dur);
4465 IWL_DEBUG_TE(mvm,
67ac248e
ST
4466 "\t(requested = %ums, max_delay = %ums)\n",
4467 duration, delay);
903b3f9b 4468
b112889c 4469 /* Set the node address */
57e861d9 4470 memcpy(tail->node_addr, vif->addr, ETH_ALEN);
b112889c 4471
a6cc5163
MG
4472 lockdep_assert_held(&mvm->mutex);
4473
4474 spin_lock_bh(&mvm->time_event_lock);
4475
4476 if (WARN_ON(te_data->id == HOT_SPOT_CMD)) {
4477 spin_unlock_bh(&mvm->time_event_lock);
4478 return -EIO;
4479 }
4480
b112889c
AM
4481 te_data->vif = vif;
4482 te_data->duration = duration;
4483 te_data->id = HOT_SPOT_CMD;
4484
b112889c
AM
4485 spin_unlock_bh(&mvm->time_event_lock);
4486
4487 /*
4488 * Use a notification wait, which really just processes the
4489 * command response and doesn't wait for anything, in order
4490 * to be able to process the response and get the UID inside
4491 * the RX path. Using CMD_WANT_SKB doesn't work because it
4492 * stores the buffer and then wakes up this thread, by which
4493 * time another notification (that the time event started)
4494 * might already be processed unsuccessfully.
4495 */
4496 iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event,
4497 time_event_response,
4498 ARRAY_SIZE(time_event_response),
4499 iwl_mvm_rx_aux_roc, te_data);
4500
57e861d9 4501 res = iwl_mvm_send_cmd_pdu(mvm, HOT_SPOT_CMD, 0, len,
b112889c
AM
4502 &aux_roc_req);
4503
4504 if (res) {
4505 IWL_ERR(mvm, "Couldn't send HOT_SPOT_CMD: %d\n", res);
4506 iwl_remove_notification(&mvm->notif_wait, &wait_time_event);
4507 goto out_clear_te;
4508 }
4509
4510 /* No need to wait for anything, so just pass 1 (0 isn't valid) */
4511 res = iwl_wait_notification(&mvm->notif_wait, &wait_time_event, 1);
4512 /* should never fail */
4513 WARN_ON_ONCE(res);
4514
4515 if (res) {
4516 out_clear_te:
4517 spin_lock_bh(&mvm->time_event_lock);
4518 iwl_mvm_te_clear_data(mvm, te_data);
4519 spin_unlock_bh(&mvm->time_event_lock);
4520 }
4521
4522 return res;
4523}
4524
67ac248e
ST
4525static int iwl_mvm_roc_add_cmd(struct iwl_mvm *mvm,
4526 struct ieee80211_channel *channel,
4527 struct ieee80211_vif *vif,
4528 int duration, u32 activity)
4529{
4530 int res;
4531 u32 duration_tu, delay;
4532 struct iwl_roc_req roc_req = {
4533 .action = cpu_to_le32(FW_CTXT_ACTION_ADD),
4534 .activity = cpu_to_le32(activity),
4535 .sta_id = cpu_to_le32(mvm->aux_sta.sta_id),
4536 };
4537
4538 lockdep_assert_held(&mvm->mutex);
4539
4540 /* Set the channel info data */
4541 iwl_mvm_set_chan_info(mvm, &roc_req.channel_info,
4542 channel->hw_value,
4543 iwl_mvm_phy_band_from_nl80211(channel->band),
4544 IWL_PHY_CHANNEL_MODE20, 0);
4545
4546 iwl_mvm_roc_duration_and_delay(vif, duration, &duration_tu,
4547 &delay);
4548 roc_req.duration = cpu_to_le32(duration_tu);
4549 roc_req.max_delay = cpu_to_le32(delay);
4550
4551 IWL_DEBUG_TE(mvm,
4552 "\t(requested = %ums, max_delay = %ums)\n",
4553 duration, delay);
4554 IWL_DEBUG_TE(mvm,
4555 "Requesting to remain on channel %u for %utu\n",
4556 channel->hw_value, duration_tu);
4557
4558 /* Set the node address */
4559 memcpy(roc_req.node_addr, vif->addr, ETH_ALEN);
4560
4561 res = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(MAC_CONF_GROUP, ROC_CMD),
4562 0, sizeof(roc_req), &roc_req);
4563
4564 return res;
4565}
4566
feebebae
MK
4567static int iwl_mvm_add_aux_sta_for_hs20(struct iwl_mvm *mvm, u32 lmac_id)
4568{
4569 int ret = 0;
4570
4571 lockdep_assert_held(&mvm->mutex);
4572
4573 if (!fw_has_capa(&mvm->fw->ucode_capa,
4574 IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT)) {
4575 IWL_ERR(mvm, "hotspot not supported\n");
4576 return -EINVAL;
4577 }
4578
1724fc78 4579 if (iwl_mvm_has_new_station_api(mvm->fw)) {
feebebae
MK
4580 ret = iwl_mvm_add_aux_sta(mvm, lmac_id);
4581 WARN(ret, "Failed to allocate aux station");
4582 }
4583
4584 return ret;
4585}
4586
84ef7cbe 4587static int iwl_mvm_roc_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
feebebae 4588{
84ef7cbe 4589 int ret;
feebebae
MK
4590
4591 lockdep_assert_held(&mvm->mutex);
4592
84ef7cbe
IP
4593 ret = iwl_mvm_binding_add_vif(mvm, vif);
4594 if (WARN(ret, "Failed binding P2P_DEVICE\n"))
feebebae
MK
4595 return ret;
4596
84ef7cbe
IP
4597 /* The station and queue allocation must be done only after the binding
4598 * is done, as otherwise the FW might incorrectly configure its state.
4599 */
4600 return iwl_mvm_add_p2p_bcast_sta(mvm, vif);
feebebae
MK
4601}
4602
8ca151b5
JB
4603static int iwl_mvm_roc(struct ieee80211_hw *hw,
4604 struct ieee80211_vif *vif,
4605 struct ieee80211_channel *channel,
d339d5ca
IP
4606 int duration,
4607 enum ieee80211_roc_type type)
fe8b2ad3 4608{
a2906ea6 4609 static const struct iwl_mvm_roc_ops ops = {
fe8b2ad3 4610 .add_aux_sta_for_hs20 = iwl_mvm_add_aux_sta_for_hs20,
84ef7cbe 4611 .link = iwl_mvm_roc_link,
fe8b2ad3
MK
4612 };
4613
4614 return iwl_mvm_roc_common(hw, vif, channel, duration, type, &ops);
4615}
4616
67ac248e
ST
4617static int iwl_mvm_roc_station(struct iwl_mvm *mvm,
4618 struct ieee80211_channel *channel,
4619 struct ieee80211_vif *vif,
4620 int duration)
4621{
4622 int ret;
4623 u32 cmd_id = WIDE_ID(MAC_CONF_GROUP, ROC_CMD);
4624 u8 fw_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id,
4625 IWL_FW_CMD_VER_UNKNOWN);
4626
4627 if (fw_ver == IWL_FW_CMD_VER_UNKNOWN) {
4628 ret = iwl_mvm_send_aux_roc_cmd(mvm, channel, vif, duration);
4629 } else if (fw_ver == 3) {
4630 ret = iwl_mvm_roc_add_cmd(mvm, channel, vif, duration,
4631 ROC_ACTIVITY_HOTSPOT);
4632 } else {
4633 ret = -EOPNOTSUPP;
4634 IWL_ERR(mvm, "ROC command version %d mismatch!\n", fw_ver);
4635 }
4636
4637 return ret;
4638}
4639
34cc3a4a
EG
4640static int iwl_mvm_p2p_find_phy_ctxt(struct iwl_mvm *mvm,
4641 struct ieee80211_vif *vif,
4642 struct ieee80211_channel *channel)
4643{
4644 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
4645 struct cfg80211_chan_def chandef;
4646 int i;
4647
4648 lockdep_assert_held(&mvm->mutex);
4649
4650 if (mvmvif->deflink.phy_ctxt &&
4651 channel == mvmvif->deflink.phy_ctxt->channel)
4652 return 0;
4653
4654 /* Try using a PHY context that is already in use */
4655 for (i = 0; i < NUM_PHY_CTX; i++) {
4656 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[i];
4657
4658 if (!phy_ctxt->ref || mvmvif->deflink.phy_ctxt == phy_ctxt)
4659 continue;
4660
4661 if (channel == phy_ctxt->channel) {
4662 if (mvmvif->deflink.phy_ctxt)
4663 iwl_mvm_phy_ctxt_unref(mvm,
4664 mvmvif->deflink.phy_ctxt);
4665
4666 mvmvif->deflink.phy_ctxt = phy_ctxt;
4667 iwl_mvm_phy_ctxt_ref(mvm, mvmvif->deflink.phy_ctxt);
4668 return 0;
4669 }
4670 }
4671
4672 /* We already have a phy_ctxt, but it's not on the right channel */
4673 if (mvmvif->deflink.phy_ctxt)
4674 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt);
4675
4676 mvmvif->deflink.phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
4677 if (!mvmvif->deflink.phy_ctxt)
4678 return -ENOSPC;
4679
4680 cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
4681
4682 return iwl_mvm_phy_ctxt_add(mvm, mvmvif->deflink.phy_ctxt,
4683 &chandef, 1, 1);
4684}
4685
fe8b2ad3
MK
4686/* Execute the common part for MLD and non-MLD modes */
4687int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4688 struct ieee80211_channel *channel, int duration,
4689 enum ieee80211_roc_type type,
a2906ea6 4690 const struct iwl_mvm_roc_ops *ops)
8ca151b5
JB
4691{
4692 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
feebebae 4693 u32 lmac_id;
34cc3a4a 4694 int ret;
31d385ae
IP
4695
4696 IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
4697 duration, type);
8ca151b5 4698
9834781c
JB
4699 /*
4700 * Flush the done work, just in case it's still pending, so that
4701 * the work it does can complete and we can accept new frames.
4702 */
6ed13164
MG
4703 flush_work(&mvm->roc_done_wk);
4704
a6cc5163
MG
4705 mutex_lock(&mvm->mutex);
4706
b112889c
AM
4707 switch (vif->type) {
4708 case NL80211_IFTYPE_STATION:
d51439a6 4709 lmac_id = iwl_mvm_get_lmac_id(mvm, channel->band);
feebebae
MK
4710
4711 /* Use aux roc framework (HS20) */
fe8b2ad3 4712 ret = ops->add_aux_sta_for_hs20(mvm, lmac_id);
feebebae 4713 if (!ret)
67ac248e 4714 ret = iwl_mvm_roc_station(mvm, channel, vif, duration);
a6cc5163 4715 goto out_unlock;
b112889c
AM
4716 case NL80211_IFTYPE_P2P_DEVICE:
4717 /* handle below */
4718 break;
4719 default:
84ef7cbe 4720 IWL_ERR(mvm, "ROC: Invalid vif type=%u\n", vif->type);
a6cc5163
MG
4721 ret = -EINVAL;
4722 goto out_unlock;
8ca151b5
JB
4723 }
4724
31d385ae 4725
34cc3a4a
EG
4726 ret = iwl_mvm_p2p_find_phy_ctxt(mvm, vif, channel);
4727 if (ret)
84ef7cbe 4728 goto out_unlock;
31d385ae 4729
84ef7cbe
IP
4730 ret = ops->link(mvm, vif);
4731 if (ret)
4732 goto out_unlock;
8ca151b5 4733
84ef7cbe 4734 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type);
31d385ae 4735out_unlock:
8ca151b5
JB
4736 mutex_unlock(&mvm->mutex);
4737 IWL_DEBUG_MAC80211(mvm, "leave\n");
8ca151b5
JB
4738 return ret;
4739}
4740
fe8b2ad3
MK
4741int iwl_mvm_cancel_roc(struct ieee80211_hw *hw,
4742 struct ieee80211_vif *vif)
8ca151b5
JB
4743{
4744 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
4745
4746 IWL_DEBUG_MAC80211(mvm, "enter\n");
4747
4748 mutex_lock(&mvm->mutex);
fe959c7b 4749 iwl_mvm_stop_roc(mvm, vif);
8ca151b5
JB
4750 mutex_unlock(&mvm->mutex);
4751
4752 IWL_DEBUG_MAC80211(mvm, "leave\n");
4753 return 0;
4754}
4755
b73f9a4a
JB
4756struct iwl_mvm_ftm_responder_iter_data {
4757 bool responder;
4758 struct ieee80211_chanctx_conf *ctx;
4759};
4760
4761static void iwl_mvm_ftm_responder_chanctx_iter(void *_data, u8 *mac,
4762 struct ieee80211_vif *vif)
4763{
4764 struct iwl_mvm_ftm_responder_iter_data *data = _data;
4765
d0a9123e 4766 if (rcu_access_pointer(vif->bss_conf.chanctx_conf) == data->ctx &&
b73f9a4a
JB
4767 vif->type == NL80211_IFTYPE_AP && vif->bss_conf.ftmr_params)
4768 data->responder = true;
4769}
4770
4771static bool iwl_mvm_is_ftm_responder_chanctx(struct iwl_mvm *mvm,
4772 struct ieee80211_chanctx_conf *ctx)
4773{
4774 struct iwl_mvm_ftm_responder_iter_data data = {
4775 .responder = false,
4776 .ctx = ctx,
4777 };
4778
4779 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
4780 IEEE80211_IFACE_ITER_NORMAL,
4781 iwl_mvm_ftm_responder_chanctx_iter,
4782 &data);
4783 return data.responder;
4784}
4785
b08c1d97
LC
4786static int __iwl_mvm_add_chanctx(struct iwl_mvm *mvm,
4787 struct ieee80211_chanctx_conf *ctx)
8ca151b5 4788{
fe0f2de3
IP
4789 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
4790 struct iwl_mvm_phy_ctxt *phy_ctxt;
3d66848f
ST
4791 bool use_def = iwl_mvm_is_ftm_responder_chanctx(mvm, ctx) ||
4792 iwl_mvm_enable_fils(mvm, ctx);
4793 struct cfg80211_chan_def *def = use_def ? &ctx->def : &ctx->min_def;
8ca151b5
JB
4794 int ret;
4795
b08c1d97
LC
4796 lockdep_assert_held(&mvm->mutex);
4797
53a9d61e 4798 IWL_DEBUG_MAC80211(mvm, "Add channel context\n");
fe0f2de3 4799
fe0f2de3
IP
4800 phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
4801 if (!phy_ctxt) {
4802 ret = -ENOSPC;
4803 goto out;
4804 }
8ca151b5 4805
f3276ff0
EG
4806 ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, def,
4807 ctx->rx_chains_static,
4808 ctx->rx_chains_dynamic);
fe0f2de3
IP
4809 if (ret) {
4810 IWL_ERR(mvm, "Failed to add PHY context\n");
4811 goto out;
4812 }
4813
4814 *phy_ctxt_id = phy_ctxt->id;
4815out:
b08c1d97
LC
4816 return ret;
4817}
4818
cbce62a3
MK
4819int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
4820 struct ieee80211_chanctx_conf *ctx)
b08c1d97
LC
4821{
4822 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
4823 int ret;
4824
4825 mutex_lock(&mvm->mutex);
4826 ret = __iwl_mvm_add_chanctx(mvm, ctx);
8ca151b5 4827 mutex_unlock(&mvm->mutex);
b08c1d97 4828
8ca151b5
JB
4829 return ret;
4830}
4831
b08c1d97
LC
4832static void __iwl_mvm_remove_chanctx(struct iwl_mvm *mvm,
4833 struct ieee80211_chanctx_conf *ctx)
4834{
4835 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
4836 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
4837
4838 lockdep_assert_held(&mvm->mutex);
4839
4840 iwl_mvm_phy_ctxt_unref(mvm, phy_ctxt);
4841}
4842
cbce62a3
MK
4843void iwl_mvm_remove_chanctx(struct ieee80211_hw *hw,
4844 struct ieee80211_chanctx_conf *ctx)
8ca151b5
JB
4845{
4846 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
8ca151b5
JB
4847
4848 mutex_lock(&mvm->mutex);
b08c1d97 4849 __iwl_mvm_remove_chanctx(mvm, ctx);
8ca151b5
JB
4850 mutex_unlock(&mvm->mutex);
4851}
4852
cbce62a3
MK
4853void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
4854 struct ieee80211_chanctx_conf *ctx, u32 changed)
8ca151b5
JB
4855{
4856 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
fe0f2de3
IP
4857 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
4858 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
3d66848f
ST
4859 bool use_def = iwl_mvm_is_ftm_responder_chanctx(mvm, ctx) ||
4860 iwl_mvm_enable_fils(mvm, ctx);
4861 struct cfg80211_chan_def *def = use_def ? &ctx->def : &ctx->min_def;
8ca151b5 4862
31d385ae
IP
4863 if (WARN_ONCE((phy_ctxt->ref > 1) &&
4864 (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH |
4865 IEEE80211_CHANCTX_CHANGE_RX_CHAINS |
2dceedae
AN
4866 IEEE80211_CHANCTX_CHANGE_RADAR |
4867 IEEE80211_CHANCTX_CHANGE_MIN_WIDTH)),
31d385ae
IP
4868 "Cannot change PHY. Ref=%d, changed=0x%X\n",
4869 phy_ctxt->ref, changed))
4870 return;
4871
8ca151b5 4872 mutex_lock(&mvm->mutex);
7a20bcce
EG
4873
4874 /* we are only changing the min_width, may be a noop */
4875 if (changed == IEEE80211_CHANCTX_CHANGE_MIN_WIDTH) {
b73f9a4a 4876 if (phy_ctxt->width == def->width)
7a20bcce
EG
4877 goto out_unlock;
4878
4879 /* we are just toggling between 20_NOHT and 20 */
4880 if (phy_ctxt->width <= NL80211_CHAN_WIDTH_20 &&
b73f9a4a 4881 def->width <= NL80211_CHAN_WIDTH_20)
7a20bcce
EG
4882 goto out_unlock;
4883 }
4884
4d66449a 4885 iwl_mvm_bt_coex_vif_change(mvm);
b73f9a4a 4886 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, def,
8ca151b5
JB
4887 ctx->rx_chains_static,
4888 ctx->rx_chains_dynamic);
7a20bcce
EG
4889
4890out_unlock:
8ca151b5
JB
4891 mutex_unlock(&mvm->mutex);
4892}
4893
8a919a78
MK
4894/*
4895 * This function executes the common part for MLD and non-MLD modes.
4896 *
4897 * Returns true if we're done assigning the chanctx
4898 * (either on failure or success)
4899 */
4263ac7f
GG
4900static bool
4901__iwl_mvm_assign_vif_chanctx_common(struct iwl_mvm *mvm,
4902 struct ieee80211_vif *vif,
4903 struct ieee80211_chanctx_conf *ctx,
4904 bool switching_chanctx, int *ret)
8ca151b5 4905{
fe0f2de3
IP
4906 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
4907 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
8ca151b5 4908 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
8ca151b5 4909
b08c1d97 4910 lockdep_assert_held(&mvm->mutex);
8ca151b5 4911
650cadb7 4912 mvmvif->deflink.phy_ctxt = phy_ctxt;
8ca151b5
JB
4913
4914 switch (vif->type) {
4915 case NL80211_IFTYPE_AP:
4741dd04
LC
4916 /* only needed if we're switching chanctx (i.e. during CSA) */
4917 if (switching_chanctx) {
bd3398e2
AO
4918 mvmvif->ap_ibss_active = true;
4919 break;
4920 }
5a2abdca 4921 fallthrough;
5023d966 4922 case NL80211_IFTYPE_ADHOC:
8ca151b5
JB
4923 /*
4924 * The AP binding flow is handled as part of the start_ap flow
5023d966 4925 * (in bss_info_changed), similarly for IBSS.
8ca151b5 4926 */
8a919a78
MK
4927 *ret = 0;
4928 return true;
8ca151b5 4929 case NL80211_IFTYPE_STATION:
2533edce 4930 break;
8ca151b5 4931 case NL80211_IFTYPE_MONITOR:
2533edce
LC
4932 /* always disable PS when a monitor interface is active */
4933 mvmvif->ps_disabled = true;
8ca151b5
JB
4934 break;
4935 default:
8a919a78
MK
4936 *ret = -EINVAL;
4937 return true;
8ca151b5 4938 }
8a919a78
MK
4939 return false;
4940}
4941
4942static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
4943 struct ieee80211_vif *vif,
4263ac7f 4944 struct ieee80211_bss_conf *link_conf,
8a919a78
MK
4945 struct ieee80211_chanctx_conf *ctx,
4946 bool switching_chanctx)
4947{
4948 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
4949 int ret;
4950
4263ac7f
GG
4951 if (WARN_ON(!link_conf))
4952 return -EINVAL;
4953
8a919a78
MK
4954 if (__iwl_mvm_assign_vif_chanctx_common(mvm, vif, ctx,
4955 switching_chanctx, &ret))
4956 goto out;
8ca151b5
JB
4957
4958 ret = iwl_mvm_binding_add_vif(mvm, vif);
4959 if (ret)
b08c1d97 4960 goto out;
8ca151b5
JB
4961
4962 /*
92d85562
AB
4963 * Power state must be updated before quotas,
4964 * otherwise fw will complain.
4965 */
999609f1 4966 iwl_mvm_power_update_mac(mvm);
92d85562
AB
4967
4968 /* Setting the quota at this stage is only required for monitor
8ca151b5
JB
4969 * interfaces. For the other types, the bss_info changed flow
4970 * will handle quota settings.
4971 */
4972 if (vif->type == NL80211_IFTYPE_MONITOR) {
1e1391ca 4973 mvmvif->monitor_active = true;
7754ae79 4974 ret = iwl_mvm_update_quotas(mvm, false, NULL);
8ca151b5
JB
4975 if (ret)
4976 goto out_remove_binding;
0e39eb03
CRI
4977
4978 ret = iwl_mvm_add_snif_sta(mvm, vif);
4979 if (ret)
4980 goto out_remove_binding;
4981
8ca151b5
JB
4982 }
4983
bd3398e2 4984 /* Handle binding during CSA */
a57c688d 4985 if (vif->type == NL80211_IFTYPE_AP) {
7754ae79 4986 iwl_mvm_update_quotas(mvm, false, NULL);
3dfd3a97 4987 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
bd3398e2
AO
4988 }
4989
8a919a78
MK
4990 if (vif->type == NL80211_IFTYPE_STATION) {
4991 if (!switching_chanctx) {
4992 mvmvif->csa_bcn_pending = false;
4993 goto out;
4994 }
4995
74a10252 4996 mvmvif->csa_bcn_pending = true;
686e7fe1 4997
74a10252
SS
4998 if (!fw_has_capa(&mvm->fw->ucode_capa,
4999 IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
11d0d831 5000 u32 duration = 5 * vif->bss_conf.beacon_int;
686e7fe1 5001
74a10252
SS
5002 /* Protect the session to make sure we hear the first
5003 * beacon on the new channel.
5004 */
5005 iwl_mvm_protect_session(mvm, vif, duration, duration,
5006 vif->bss_conf.beacon_int / 2,
5007 true);
74a10252 5008 }
686e7fe1 5009
7754ae79 5010 iwl_mvm_update_quotas(mvm, false, NULL);
0ce04ce7
LC
5011 }
5012
b08c1d97 5013 goto out;
8ca151b5 5014
b08c1d97 5015out_remove_binding:
8ca151b5 5016 iwl_mvm_binding_remove_vif(mvm, vif);
999609f1 5017 iwl_mvm_power_update_mac(mvm);
b08c1d97 5018out:
8ca151b5 5019 if (ret)
650cadb7 5020 mvmvif->deflink.phy_ctxt = NULL;
8ca151b5
JB
5021 return ret;
5022}
8a919a78 5023
b08c1d97
LC
5024static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
5025 struct ieee80211_vif *vif,
727eff4d 5026 struct ieee80211_bss_conf *link_conf,
b08c1d97 5027 struct ieee80211_chanctx_conf *ctx)
8ca151b5
JB
5028{
5029 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
b08c1d97 5030 int ret;
8ca151b5
JB
5031
5032 mutex_lock(&mvm->mutex);
4263ac7f 5033 ret = __iwl_mvm_assign_vif_chanctx(mvm, vif, link_conf, ctx, false);
b08c1d97
LC
5034 mutex_unlock(&mvm->mutex);
5035
5036 return ret;
5037}
5038
daddfae5
MK
5039/*
5040 * This function executes the common part for MLD and non-MLD modes.
5041 *
5042 * Returns if chanctx unassign chanctx is done
5043 * (either on failure or success)
5044 */
4263ac7f
GG
5045static bool __iwl_mvm_unassign_vif_chanctx_common(struct iwl_mvm *mvm,
5046 struct ieee80211_vif *vif,
5047 bool switching_chanctx)
b08c1d97
LC
5048{
5049 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
5050
5051 lockdep_assert_held(&mvm->mutex);
650cadb7
GG
5052 iwl_mvm_remove_time_event(mvm, mvmvif,
5053 &mvmvif->time_event_data);
8ca151b5 5054
8ca151b5 5055 switch (vif->type) {
5023d966 5056 case NL80211_IFTYPE_ADHOC:
daddfae5 5057 return true;
8ca151b5 5058 case NL80211_IFTYPE_MONITOR:
1e1391ca 5059 mvmvif->monitor_active = false;
2533edce 5060 mvmvif->ps_disabled = false;
8ca151b5 5061 break;
bd3398e2
AO
5062 case NL80211_IFTYPE_AP:
5063 /* This part is triggered only during CSA */
4741dd04 5064 if (!switching_chanctx || !mvmvif->ap_ibss_active)
daddfae5 5065 return true;
bd3398e2 5066
7ef0aab6
AO
5067 mvmvif->csa_countdown = false;
5068
003e5236
AO
5069 /* Set CS bit on all the stations */
5070 iwl_mvm_modify_all_sta_disable_tx(mvm, mvmvif, true);
5071
5072 /* Save blocked iface, the timeout is set on the next beacon */
5073 rcu_assign_pointer(mvm->csa_tx_blocked_vif, vif);
5074
bd3398e2 5075 mvmvif->ap_ibss_active = false;
f0c97783 5076 break;
daddfae5
MK
5077 default:
5078 break;
5079 }
5080 return false;
5081}
f0c97783 5082
daddfae5
MK
5083static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
5084 struct ieee80211_vif *vif,
4263ac7f 5085 struct ieee80211_bss_conf *link_conf,
daddfae5
MK
5086 struct ieee80211_chanctx_conf *ctx,
5087 bool switching_chanctx)
5088{
5089 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
5090 struct ieee80211_vif *disabled_vif = NULL;
5091
5092 if (__iwl_mvm_unassign_vif_chanctx_common(mvm, vif, switching_chanctx))
5093 goto out;
f0c97783 5094
daddfae5
MK
5095 if (vif->type == NL80211_IFTYPE_MONITOR)
5096 iwl_mvm_rm_snif_sta(mvm, vif);
f0c97783 5097
daddfae5
MK
5098
5099 if (vif->type == NL80211_IFTYPE_STATION && switching_chanctx) {
5100 disabled_vif = vif;
74a10252
SS
5101 if (!fw_has_capa(&mvm->fw->ucode_capa,
5102 IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
5103 iwl_mvm_mac_ctxt_changed(mvm, vif, true, NULL);
8ca151b5
JB
5104 }
5105
7754ae79 5106 iwl_mvm_update_quotas(mvm, false, disabled_vif);
1e1391ca 5107 iwl_mvm_binding_remove_vif(mvm, vif);
1c2abf72 5108
b08c1d97 5109out:
bf544e9a
SS
5110 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD) &&
5111 switching_chanctx)
5112 return;
650cadb7 5113 mvmvif->deflink.phy_ctxt = NULL;
999609f1 5114 iwl_mvm_power_update_mac(mvm);
b08c1d97
LC
5115}
5116
5117static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
5118 struct ieee80211_vif *vif,
727eff4d 5119 struct ieee80211_bss_conf *link_conf,
b08c1d97
LC
5120 struct ieee80211_chanctx_conf *ctx)
5121{
5122 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
5123
5124 mutex_lock(&mvm->mutex);
4263ac7f 5125 __iwl_mvm_unassign_vif_chanctx(mvm, vif, link_conf, ctx, false);
8ca151b5
JB
5126 mutex_unlock(&mvm->mutex);
5127}
5128
50cc9574
LC
5129static int
5130iwl_mvm_switch_vif_chanctx_swap(struct iwl_mvm *mvm,
660eba5a 5131 struct ieee80211_vif_chanctx_switch *vifs,
a2906ea6 5132 const struct iwl_mvm_switch_vif_chanctx_ops *ops)
b08c1d97 5133{
b08c1d97
LC
5134 int ret;
5135
b08c1d97 5136 mutex_lock(&mvm->mutex);
4263ac7f
GG
5137 ops->__unassign_vif_chanctx(mvm, vifs[0].vif, vifs[0].link_conf,
5138 vifs[0].old_ctx, true);
b08c1d97
LC
5139 __iwl_mvm_remove_chanctx(mvm, vifs[0].old_ctx);
5140
5141 ret = __iwl_mvm_add_chanctx(mvm, vifs[0].new_ctx);
5142 if (ret) {
5143 IWL_ERR(mvm, "failed to add new_ctx during channel switch\n");
5144 goto out_reassign;
5145 }
5146
4263ac7f
GG
5147 ret = ops->__assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].link_conf,
5148 vifs[0].new_ctx, true);
b08c1d97
LC
5149 if (ret) {
5150 IWL_ERR(mvm,
5151 "failed to assign new_ctx during channel switch\n");
5152 goto out_remove;
5153 }
5154
f697267f
AN
5155 /* we don't support TDLS during DCM - can be caused by channel switch */
5156 if (iwl_mvm_phy_ctx_count(mvm) > 1)
5157 iwl_mvm_teardown_tdls_peers(mvm);
5158
b08c1d97
LC
5159 goto out;
5160
5161out_remove:
5162 __iwl_mvm_remove_chanctx(mvm, vifs[0].new_ctx);
5163
5164out_reassign:
6fd1fb63 5165 if (__iwl_mvm_add_chanctx(mvm, vifs[0].old_ctx)) {
b08c1d97
LC
5166 IWL_ERR(mvm, "failed to add old_ctx back after failure.\n");
5167 goto out_restart;
5168 }
5169
4263ac7f
GG
5170 if (ops->__assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].link_conf,
5171 vifs[0].old_ctx, true)) {
b08c1d97
LC
5172 IWL_ERR(mvm, "failed to reassign old_ctx after failure.\n");
5173 goto out_restart;
5174 }
5175
5176 goto out;
5177
5178out_restart:
5179 /* things keep failing, better restart the hw */
5180 iwl_mvm_nic_restart(mvm, false);
5181
5182out:
5183 mutex_unlock(&mvm->mutex);
50cc9574
LC
5184
5185 return ret;
5186}
5187
48a256e8
LC
5188static int
5189iwl_mvm_switch_vif_chanctx_reassign(struct iwl_mvm *mvm,
660eba5a 5190 struct ieee80211_vif_chanctx_switch *vifs,
a2906ea6 5191 const struct iwl_mvm_switch_vif_chanctx_ops *ops)
48a256e8
LC
5192{
5193 int ret;
5194
5195 mutex_lock(&mvm->mutex);
4263ac7f
GG
5196 ops->__unassign_vif_chanctx(mvm, vifs[0].vif, vifs[0].link_conf,
5197 vifs[0].old_ctx, true);
48a256e8 5198
4263ac7f
GG
5199 ret = ops->__assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].link_conf,
5200 vifs[0].new_ctx, true);
48a256e8
LC
5201 if (ret) {
5202 IWL_ERR(mvm,
5203 "failed to assign new_ctx during channel switch\n");
5204 goto out_reassign;
5205 }
5206
5207 goto out;
5208
5209out_reassign:
4263ac7f
GG
5210 if (ops->__assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].link_conf,
5211 vifs[0].old_ctx, true)) {
48a256e8
LC
5212 IWL_ERR(mvm, "failed to reassign old_ctx after failure.\n");
5213 goto out_restart;
5214 }
5215
5216 goto out;
5217
5218out_restart:
5219 /* things keep failing, better restart the hw */
5220 iwl_mvm_nic_restart(mvm, false);
5221
5222out:
5223 mutex_unlock(&mvm->mutex);
5224
5225 return ret;
5226}
5227
660eba5a
MK
5228/* Execute the common part for both MLD and non-MLD modes */
5229int
5230iwl_mvm_switch_vif_chanctx_common(struct ieee80211_hw *hw,
5231 struct ieee80211_vif_chanctx_switch *vifs,
5232 int n_vifs,
5233 enum ieee80211_chanctx_switch_mode mode,
a2906ea6 5234 const struct iwl_mvm_switch_vif_chanctx_ops *ops)
50cc9574
LC
5235{
5236 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
5237 int ret;
5238
5239 /* we only support a single-vif right now */
5240 if (n_vifs > 1)
5241 return -EOPNOTSUPP;
5242
5243 switch (mode) {
5244 case CHANCTX_SWMODE_SWAP_CONTEXTS:
660eba5a 5245 ret = iwl_mvm_switch_vif_chanctx_swap(mvm, vifs, ops);
50cc9574
LC
5246 break;
5247 case CHANCTX_SWMODE_REASSIGN_VIF:
660eba5a 5248 ret = iwl_mvm_switch_vif_chanctx_reassign(mvm, vifs, ops);
50cc9574
LC
5249 break;
5250 default:
5251 ret = -EOPNOTSUPP;
5252 break;
5253 }
5254
b08c1d97
LC
5255 return ret;
5256}
5257
660eba5a
MK
5258static int iwl_mvm_switch_vif_chanctx(struct ieee80211_hw *hw,
5259 struct ieee80211_vif_chanctx_switch *vifs,
5260 int n_vifs,
5261 enum ieee80211_chanctx_switch_mode mode)
5262{
a2906ea6 5263 static const struct iwl_mvm_switch_vif_chanctx_ops ops = {
660eba5a
MK
5264 .__assign_vif_chanctx = __iwl_mvm_assign_vif_chanctx,
5265 .__unassign_vif_chanctx = __iwl_mvm_unassign_vif_chanctx,
5266 };
5267
5268 return iwl_mvm_switch_vif_chanctx_common(hw, vifs, n_vifs, mode, &ops);
5269}
5270
cbce62a3 5271int iwl_mvm_tx_last_beacon(struct ieee80211_hw *hw)
2f0282db
JB
5272{
5273 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
5274
5275 return mvm->ibss_manager;
5276}
5277
a32973ee
JB
5278static int iwl_mvm_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
5279 bool set)
8ca151b5
JB
5280{
5281 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
9d8ce6af 5282 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
8ca151b5
JB
5283
5284 if (!mvm_sta || !mvm_sta->vif) {
5285 IWL_ERR(mvm, "Station is not associated to a vif\n");
5286 return -EINVAL;
5287 }
5288
36cf5377
GG
5289 return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif,
5290 &mvm_sta->vif->bss_conf);
8ca151b5
JB
5291}
5292
507cadf2
DS
5293#ifdef CONFIG_NL80211_TESTMODE
5294static const struct nla_policy iwl_mvm_tm_policy[IWL_MVM_TM_ATTR_MAX + 1] = {
5295 [IWL_MVM_TM_ATTR_CMD] = { .type = NLA_U32 },
5296 [IWL_MVM_TM_ATTR_NOA_DURATION] = { .type = NLA_U32 },
f6c6ad42 5297 [IWL_MVM_TM_ATTR_BEACON_FILTER_STATE] = { .type = NLA_U32 },
507cadf2
DS
5298};
5299
5300static int __iwl_mvm_mac_testmode_cmd(struct iwl_mvm *mvm,
5301 struct ieee80211_vif *vif,
5302 void *data, int len)
5303{
5304 struct nlattr *tb[IWL_MVM_TM_ATTR_MAX + 1];
5305 int err;
5306 u32 noa_duration;
5307
8cb08174
JB
5308 err = nla_parse_deprecated(tb, IWL_MVM_TM_ATTR_MAX, data, len,
5309 iwl_mvm_tm_policy, NULL);
507cadf2
DS
5310 if (err)
5311 return err;
5312
5313 if (!tb[IWL_MVM_TM_ATTR_CMD])
5314 return -EINVAL;
5315
5316 switch (nla_get_u32(tb[IWL_MVM_TM_ATTR_CMD])) {
5317 case IWL_MVM_TM_CMD_SET_NOA:
5318 if (!vif || vif->type != NL80211_IFTYPE_AP || !vif->p2p ||
5319 !vif->bss_conf.enable_beacon ||
5320 !tb[IWL_MVM_TM_ATTR_NOA_DURATION])
5321 return -EINVAL;
5322
5323 noa_duration = nla_get_u32(tb[IWL_MVM_TM_ATTR_NOA_DURATION]);
5324 if (noa_duration >= vif->bss_conf.beacon_int)
5325 return -EINVAL;
5326
5327 mvm->noa_duration = noa_duration;
5328 mvm->noa_vif = vif;
5329
22b21041 5330 return iwl_mvm_update_quotas(mvm, true, NULL);
f6c6ad42
JB
5331 case IWL_MVM_TM_CMD_SET_BEACON_FILTER:
5332 /* must be associated client vif - ignore authorized */
5333 if (!vif || vif->type != NL80211_IFTYPE_STATION ||
f276e20b 5334 !vif->cfg.assoc || !vif->bss_conf.dtim_period ||
f6c6ad42
JB
5335 !tb[IWL_MVM_TM_ATTR_BEACON_FILTER_STATE])
5336 return -EINVAL;
5337
5338 if (nla_get_u32(tb[IWL_MVM_TM_ATTR_BEACON_FILTER_STATE]))
a1022927
EG
5339 return iwl_mvm_enable_beacon_filter(mvm, vif, 0);
5340 return iwl_mvm_disable_beacon_filter(mvm, vif, 0);
507cadf2
DS
5341 }
5342
5343 return -EOPNOTSUPP;
5344}
5345
cbce62a3
MK
5346int iwl_mvm_mac_testmode_cmd(struct ieee80211_hw *hw,
5347 struct ieee80211_vif *vif,
5348 void *data, int len)
507cadf2
DS
5349{
5350 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
5351 int err;
5352
5353 mutex_lock(&mvm->mutex);
5354 err = __iwl_mvm_mac_testmode_cmd(mvm, vif, data, len);
5355 mutex_unlock(&mvm->mutex);
5356
5357 return err;
5358}
5359#endif
5360
cbce62a3
MK
5361void iwl_mvm_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5362 struct ieee80211_channel_switch *chsw)
622e3f9b
LC
5363{
5364 /* By implementing this operation, we prevent mac80211 from
5365 * starting its own channel switch timer, so that we can call
5366 * ieee80211_chswitch_done() ourselves at the right time
5367 * (which is when the absence time event starts).
5368 */
5369
5370 IWL_DEBUG_MAC80211(IWL_MAC80211_GET_MVM(hw),
5371 "dummy channel switch op\n");
5372}
5373
74a10252
SS
5374static int iwl_mvm_schedule_client_csa(struct iwl_mvm *mvm,
5375 struct ieee80211_vif *vif,
5376 struct ieee80211_channel_switch *chsw)
5377{
5378 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
5379 struct iwl_chan_switch_te_cmd cmd = {
5380 .mac_id = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
5381 mvmvif->color)),
5382 .action = cpu_to_le32(FW_CTXT_ACTION_ADD),
5383 .tsf = cpu_to_le32(chsw->timestamp),
5384 .cs_count = chsw->count,
77738865 5385 .cs_mode = chsw->block_tx,
74a10252
SS
5386 };
5387
5388 lockdep_assert_held(&mvm->mutex);
5389
9cfcf71c
SS
5390 if (chsw->delay)
5391 cmd.cs_delayed_bcn_count =
5392 DIV_ROUND_UP(chsw->delay, vif->bss_conf.beacon_int);
5393
74a10252
SS
5394 return iwl_mvm_send_cmd_pdu(mvm,
5395 WIDE_ID(MAC_CONF_GROUP,
5396 CHANNEL_SWITCH_TIME_EVENT_CMD),
5397 0, sizeof(cmd), &cmd);
5398}
5399
0202bcf0
EG
5400static int iwl_mvm_old_pre_chan_sw_sta(struct iwl_mvm *mvm,
5401 struct ieee80211_vif *vif,
5402 struct ieee80211_channel_switch *chsw)
5403{
5404 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
5405 u32 apply_time;
5406
5407 /* Schedule the time event to a bit before beacon 1,
5408 * to make sure we're in the new channel when the
5409 * GO/AP arrives. In case count <= 1 immediately schedule the
5410 * TE (this might result with some packet loss or connection
5411 * loss).
5412 */
5413 if (chsw->count <= 1)
5414 apply_time = 0;
5415 else
5416 apply_time = chsw->device_timestamp +
5417 ((vif->bss_conf.beacon_int * (chsw->count - 1) -
5418 IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
5419
5420 if (chsw->block_tx)
5421 iwl_mvm_csa_client_absent(mvm, vif);
5422
5423 if (mvmvif->bf_data.bf_enabled) {
5424 int ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
5425
5426 if (ret)
5427 return ret;
5428 }
5429
5430 iwl_mvm_schedule_csa_period(mvm, vif, vif->bss_conf.beacon_int,
5431 apply_time);
5432
5433 return 0;
5434}
5435
f6780614 5436#define IWL_MAX_CSA_BLOCK_TX 1500
cbce62a3
MK
5437int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
5438 struct ieee80211_vif *vif,
5439 struct ieee80211_channel_switch *chsw)
bd3398e2
AO
5440{
5441 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
664322fa 5442 struct ieee80211_vif *csa_vif;
f6c34820 5443 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
f028905c 5444 int ret;
bd3398e2
AO
5445
5446 mutex_lock(&mvm->mutex);
664322fa 5447
81d62d5a
JB
5448 mvmvif->csa_failed = false;
5449
6b20d774 5450 IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n",
f028905c 5451 chsw->chandef.center_freq1);
6b20d774 5452
7174beb6
JB
5453 iwl_fw_dbg_trigger_simple_stop(&mvm->fwrt,
5454 ieee80211_vif_to_wdev(vif),
5455 FW_DBG_TRIGGER_CHANNEL_SWITCH);
f35d9c55 5456
6b20d774
LC
5457 switch (vif->type) {
5458 case NL80211_IFTYPE_AP:
5459 csa_vif =
5460 rcu_dereference_protected(mvm->csa_vif,
5461 lockdep_is_held(&mvm->mutex));
d0a9123e 5462 if (WARN_ONCE(csa_vif && csa_vif->bss_conf.csa_active,
6b20d774
LC
5463 "Another CSA is already in progress")) {
5464 ret = -EBUSY;
5465 goto out_unlock;
5466 }
5467
d3a108a4
AO
5468 /* we still didn't unblock tx. prevent new CS meanwhile */
5469 if (rcu_dereference_protected(mvm->csa_tx_blocked_vif,
5470 lockdep_is_held(&mvm->mutex))) {
5471 ret = -EBUSY;
5472 goto out_unlock;
5473 }
5474
6b20d774 5475 rcu_assign_pointer(mvm->csa_vif, vif);
7ef0aab6 5476
7ef0aab6
AO
5477 if (WARN_ONCE(mvmvif->csa_countdown,
5478 "Previous CSA countdown didn't complete")) {
5479 ret = -EBUSY;
5480 goto out_unlock;
5481 }
5482
d3a108a4
AO
5483 mvmvif->csa_target_freq = chsw->chandef.chan->center_freq;
5484
6b20d774 5485 break;
dc88b4ba 5486 case NL80211_IFTYPE_STATION:
ad12b231
NE
5487 /*
5488 * In the new flow FW is in charge of timing the switch so there
5489 * is no need for all of this
5490 */
5491 if (iwl_fw_lookup_notif_ver(mvm->fw, MAC_CONF_GROUP,
5492 CHANNEL_SWITCH_ERROR_NOTIF,
5493 0))
5494 break;
5495
2360acbd
EG
5496 /*
5497 * We haven't configured the firmware to be associated yet since
5498 * we don't know the dtim period. In this case, the firmware can't
5499 * track the beacons.
5500 */
f276e20b 5501 if (!vif->cfg.assoc || !vif->bss_conf.dtim_period) {
2360acbd
EG
5502 ret = -EBUSY;
5503 goto out_unlock;
5504 }
5505
aee2eac7
JB
5506 if (chsw->delay > IWL_MAX_CSA_BLOCK_TX &&
5507 hweight16(vif->valid_links) <= 1)
87d9564e
JB
5508 schedule_delayed_work(&mvmvif->csa_work, 0);
5509
f6780614 5510 if (chsw->block_tx) {
f6780614
SS
5511 /*
5512 * In case of undetermined / long time with immediate
5513 * quiet monitor status to gracefully disconnect
5514 */
5515 if (!chsw->count ||
5516 chsw->count * vif->bss_conf.beacon_int >
5517 IWL_MAX_CSA_BLOCK_TX)
5518 schedule_delayed_work(&mvmvif->csa_work,
5519 msecs_to_jiffies(IWL_MAX_CSA_BLOCK_TX));
5520 }
dc88b4ba 5521
0202bcf0
EG
5522 if (!fw_has_capa(&mvm->fw->ucode_capa,
5523 IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
5524 ret = iwl_mvm_old_pre_chan_sw_sta(mvm, vif, chsw);
c6e0a3e0
LC
5525 if (ret)
5526 goto out_unlock;
0202bcf0 5527 } else {
74a10252 5528 iwl_mvm_schedule_client_csa(mvm, vif, chsw);
0202bcf0 5529 }
81b4e44e
SS
5530
5531 mvmvif->csa_count = chsw->count;
5532 mvmvif->csa_misbehave = false;
dc88b4ba 5533 break;
6b20d774
LC
5534 default:
5535 break;
5536 }
bd3398e2 5537
f6c34820
LC
5538 mvmvif->ps_disabled = true;
5539
5540 ret = iwl_mvm_power_update_ps(mvm);
5541 if (ret)
5542 goto out_unlock;
f028905c 5543
e198f5e7
AN
5544 /* we won't be on this channel any longer */
5545 iwl_mvm_teardown_tdls_peers(mvm);
5546
bd3398e2
AO
5547out_unlock:
5548 mutex_unlock(&mvm->mutex);
f028905c
LC
5549
5550 return ret;
bd3398e2
AO
5551}
5552
cbce62a3
MK
5553void iwl_mvm_channel_switch_rx_beacon(struct ieee80211_hw *hw,
5554 struct ieee80211_vif *vif,
5555 struct ieee80211_channel_switch *chsw)
f6c34820 5556{
f6c34820 5557 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
c37763d2
SS
5558 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
5559 struct iwl_chan_switch_te_cmd cmd = {
5560 .mac_id = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
5561 mvmvif->color)),
5562 .action = cpu_to_le32(FW_CTXT_ACTION_MODIFY),
5563 .tsf = cpu_to_le32(chsw->timestamp),
5564 .cs_count = chsw->count,
77738865 5565 .cs_mode = chsw->block_tx,
c37763d2 5566 };
a57c688d 5567
ad12b231
NE
5568 /*
5569 * In the new flow FW is in charge of timing the switch so there is no
5570 * need for all of this
5571 */
5572 if (iwl_fw_lookup_notif_ver(mvm->fw, MAC_CONF_GROUP,
5573 CHANNEL_SWITCH_ERROR_NOTIF, 0))
5574 return;
5575
c37763d2
SS
5576 if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CS_MODIFY))
5577 return;
a57c688d 5578
c3eae059
GG
5579 IWL_DEBUG_MAC80211(mvm, "Modify CSA on mac %d count = %d (old %d) mode = %d\n",
5580 mvmvif->id, chsw->count, mvmvif->csa_count, chsw->block_tx);
5581
81b4e44e
SS
5582 if (chsw->count >= mvmvif->csa_count && chsw->block_tx) {
5583 if (mvmvif->csa_misbehave) {
5584 /* Second time, give up on this AP*/
5585 iwl_mvm_abort_channel_switch(hw, vif);
a469a593 5586 ieee80211_chswitch_done(vif, false, 0);
81b4e44e
SS
5587 mvmvif->csa_misbehave = false;
5588 return;
a57c688d 5589 }
81b4e44e 5590 mvmvif->csa_misbehave = true;
a57c688d 5591 }
81b4e44e 5592 mvmvif->csa_count = chsw->count;
a57c688d 5593
caf46377
SS
5594 mutex_lock(&mvm->mutex);
5595 if (mvmvif->csa_failed)
5596 goto out_unlock;
f6c34820 5597
c37763d2
SS
5598 WARN_ON(iwl_mvm_send_cmd_pdu(mvm,
5599 WIDE_ID(MAC_CONF_GROUP,
5600 CHANNEL_SWITCH_TIME_EVENT_CMD),
caf46377
SS
5601 0, sizeof(cmd), &cmd));
5602out_unlock:
5603 mutex_unlock(&mvm->mutex);
f6c34820
LC
5604}
5605
6110d9e5
DS
5606static void iwl_mvm_flush_no_vif(struct iwl_mvm *mvm, u32 queues, bool drop)
5607{
435d0827
SS
5608 int i;
5609
06195639 5610 if (!iwl_mvm_has_new_tx_api(mvm)) {
309c4848
LC
5611 if (drop) {
5612 mutex_lock(&mvm->mutex);
6110d9e5 5613 iwl_mvm_flush_tx_path(mvm,
d4e3a341 5614 iwl_mvm_flushable_queues(mvm) & queues);
309c4848
LC
5615 mutex_unlock(&mvm->mutex);
5616 } else {
06195639 5617 iwl_trans_wait_tx_queues_empty(mvm->trans, queues);
309c4848 5618 }
435d0827
SS
5619 return;
5620 }
6110d9e5 5621
435d0827 5622 mutex_lock(&mvm->mutex);
be9ae34e 5623 for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
435d0827 5624 struct ieee80211_sta *sta;
6110d9e5 5625
435d0827
SS
5626 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
5627 lockdep_is_held(&mvm->mutex));
5628 if (IS_ERR_OR_NULL(sta))
5629 continue;
6110d9e5 5630
06195639 5631 if (drop)
d4e3a341 5632 iwl_mvm_flush_sta_tids(mvm, i, 0xFFFF);
06195639
SS
5633 else
5634 iwl_mvm_wait_sta_queues_empty(mvm,
5635 iwl_mvm_sta_from_mac80211(sta));
6110d9e5 5636 }
435d0827 5637 mutex_unlock(&mvm->mutex);
6110d9e5
DS
5638}
5639
cbce62a3
MK
5640void iwl_mvm_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5641 u32 queues, bool drop)
c5b0e7c0
EG
5642{
5643 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
5644 struct iwl_mvm_vif *mvmvif;
5645 struct iwl_mvm_sta *mvmsta;
a0f6bf2a 5646 struct ieee80211_sta *sta;
d3f9cd61 5647 bool ap_sta_done = false;
a0f6bf2a
AN
5648 int i;
5649 u32 msk = 0;
c5b0e7c0 5650
6110d9e5
DS
5651 if (!vif) {
5652 iwl_mvm_flush_no_vif(mvm, queues, drop);
5653 return;
5654 }
5655
24afba76 5656 /* Make sure we're done with the deferred traffic before flushing */
c8f54701 5657 flush_work(&mvm->add_stream_wk);
24afba76 5658
c5b0e7c0
EG
5659 mutex_lock(&mvm->mutex);
5660 mvmvif = iwl_mvm_vif_from_mac80211(vif);
c5b0e7c0 5661
a0f6bf2a 5662 /* flush the AP-station and all TDLS peers */
be9ae34e 5663 for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
a0f6bf2a
AN
5664 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
5665 lockdep_is_held(&mvm->mutex));
5666 if (IS_ERR_OR_NULL(sta))
5667 continue;
5668
5669 mvmsta = iwl_mvm_sta_from_mac80211(sta);
5670 if (mvmsta->vif != vif)
5671 continue;
5672
d3f9cd61
JB
5673 if (sta == mvmvif->ap_sta) {
5674 if (ap_sta_done)
5675 continue;
5676 ap_sta_done = true;
5677 }
5678
d49394a1 5679 if (drop) {
39176296
JB
5680 if (iwl_mvm_flush_sta(mvm, mvmsta->deflink.sta_id,
5681 mvmsta->tfd_queue_msk))
d49394a1
SS
5682 IWL_ERR(mvm, "flush request fail\n");
5683 } else {
d6d517b7
SS
5684 if (iwl_mvm_has_new_tx_api(mvm))
5685 iwl_mvm_wait_sta_queues_empty(mvm, mvmsta);
f7bd883b
JB
5686 else /* only used for !iwl_mvm_has_new_tx_api() below */
5687 msk |= mvmsta->tfd_queue_msk;
d49394a1 5688 }
480acbce 5689 }
c5b0e7c0 5690
d49394a1 5691 mutex_unlock(&mvm->mutex);
4e6c48e0 5692
d49394a1
SS
5693 /* this can take a while, and we may need/want other operations
5694 * to succeed while doing this, so do it without the mutex held
5695 */
d6d517b7 5696 if (!drop && !iwl_mvm_has_new_tx_api(mvm))
a1a57877 5697 iwl_trans_wait_tx_queues_empty(mvm->trans, msk);
c5b0e7c0
EG
5698}
5699
a6cc6ccb
JB
5700void iwl_mvm_mac_flush_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5701 struct ieee80211_sta *sta)
5702{
43874283 5703 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
a6cc6ccb 5704 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
43874283
JB
5705 struct iwl_mvm_link_sta *mvm_link_sta;
5706 struct ieee80211_link_sta *link_sta;
5707 int link_id;
a6cc6ccb
JB
5708
5709 mutex_lock(&mvm->mutex);
43874283
JB
5710 for_each_sta_active_link(vif, sta, link_sta, link_id) {
5711 mvm_link_sta = rcu_dereference_protected(mvmsta->link[link_id],
5712 lockdep_is_held(&mvm->mutex));
5713 if (!mvm_link_sta)
a6cc6ccb
JB
5714 continue;
5715
43874283 5716 if (iwl_mvm_flush_sta(mvm, mvm_link_sta->sta_id,
39176296 5717 mvmsta->tfd_queue_msk))
a6cc6ccb
JB
5718 IWL_ERR(mvm, "flush request fail\n");
5719 }
5720 mutex_unlock(&mvm->mutex);
5721}
5722
cbce62a3
MK
5723int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx,
5724 struct survey_info *survey)
91a8bcde
JB
5725{
5726 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
5727 int ret;
5728
5729 memset(survey, 0, sizeof(*survey));
5730
5731 /* only support global statistics right now */
5732 if (idx != 0)
5733 return -ENOENT;
5734
280a3efa
JB
5735 if (!fw_has_capa(&mvm->fw->ucode_capa,
5736 IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS))
91a8bcde
JB
5737 return -ENOENT;
5738
5739 mutex_lock(&mvm->mutex);
5740
aab6930d 5741 if (iwl_mvm_firmware_running(mvm)) {
33cef925 5742 ret = iwl_mvm_request_statistics(mvm, false);
91a8bcde
JB
5743 if (ret)
5744 goto out;
5745 }
5746
5747 survey->filled = SURVEY_INFO_TIME |
5748 SURVEY_INFO_TIME_RX |
5749 SURVEY_INFO_TIME_TX |
5750 SURVEY_INFO_TIME_SCAN;
5751 survey->time = mvm->accu_radio_stats.on_time_rf +
5752 mvm->radio_stats.on_time_rf;
5753 do_div(survey->time, USEC_PER_MSEC);
5754
5755 survey->time_rx = mvm->accu_radio_stats.rx_time +
5756 mvm->radio_stats.rx_time;
5757 do_div(survey->time_rx, USEC_PER_MSEC);
5758
5759 survey->time_tx = mvm->accu_radio_stats.tx_time +
5760 mvm->radio_stats.tx_time;
5761 do_div(survey->time_tx, USEC_PER_MSEC);
5762
5763 survey->time_scan = mvm->accu_radio_stats.on_time_scan +
5764 mvm->radio_stats.on_time_scan;
5765 do_div(survey->time_scan, USEC_PER_MSEC);
5766
10a7c028 5767 ret = 0;
91a8bcde
JB
5768 out:
5769 mutex_unlock(&mvm->mutex);
5770 return ret;
5771}
5772
ed780545
JB
5773static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo)
5774{
82cdbd11 5775 u32 format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK;
7138763e 5776 u32 gi_ltf;
82cdbd11
MK
5777
5778 switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) {
ed780545
JB
5779 case RATE_MCS_CHAN_WIDTH_20:
5780 rinfo->bw = RATE_INFO_BW_20;
5781 break;
5782 case RATE_MCS_CHAN_WIDTH_40:
5783 rinfo->bw = RATE_INFO_BW_40;
5784 break;
5785 case RATE_MCS_CHAN_WIDTH_80:
5786 rinfo->bw = RATE_INFO_BW_80;
5787 break;
5788 case RATE_MCS_CHAN_WIDTH_160:
5789 rinfo->bw = RATE_INFO_BW_160;
5790 break;
23dcee94
JB
5791 case RATE_MCS_CHAN_WIDTH_320:
5792 rinfo->bw = RATE_INFO_BW_320;
5793 break;
ed780545
JB
5794 }
5795
82cdbd11
MK
5796 if (format == RATE_MCS_CCK_MSK ||
5797 format == RATE_MCS_LEGACY_OFDM_MSK) {
5798 int rate = u32_get_bits(rate_n_flags, RATE_LEGACY_RATE_MSK);
5799
5800 /* add the offset needed to get to the legacy ofdm indices */
5801 if (format == RATE_MCS_LEGACY_OFDM_MSK)
5802 rate += IWL_FIRST_OFDM_RATE;
5803
5804 switch (rate) {
5805 case IWL_RATE_1M_INDEX:
5806 rinfo->legacy = 10;
5807 break;
5808 case IWL_RATE_2M_INDEX:
5809 rinfo->legacy = 20;
5810 break;
5811 case IWL_RATE_5M_INDEX:
5812 rinfo->legacy = 55;
5813 break;
5814 case IWL_RATE_11M_INDEX:
5815 rinfo->legacy = 110;
5816 break;
5817 case IWL_RATE_6M_INDEX:
5818 rinfo->legacy = 60;
5819 break;
5820 case IWL_RATE_9M_INDEX:
5821 rinfo->legacy = 90;
5822 break;
5823 case IWL_RATE_12M_INDEX:
5824 rinfo->legacy = 120;
5825 break;
5826 case IWL_RATE_18M_INDEX:
5827 rinfo->legacy = 180;
5828 break;
5829 case IWL_RATE_24M_INDEX:
5830 rinfo->legacy = 240;
5831 break;
5832 case IWL_RATE_36M_INDEX:
5833 rinfo->legacy = 360;
5834 break;
5835 case IWL_RATE_48M_INDEX:
5836 rinfo->legacy = 480;
5837 break;
5838 case IWL_RATE_54M_INDEX:
5839 rinfo->legacy = 540;
5840 }
5841 return;
5842 }
5843
5844 rinfo->nss = u32_get_bits(rate_n_flags,
5845 RATE_MCS_NSS_MSK) + 1;
5846 rinfo->mcs = format == RATE_MCS_HT_MSK ?
5847 RATE_HT_MCS_INDEX(rate_n_flags) :
5848 u32_get_bits(rate_n_flags, RATE_MCS_CODE_MSK);
5849
7138763e
JB
5850 if (rate_n_flags & RATE_MCS_SGI_MSK)
5851 rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
5852
5853 switch (format) {
23dcee94
JB
5854 case RATE_MCS_EHT_MSK:
5855 /* TODO: GI/LTF/RU. How does the firmware encode them? */
5856 rinfo->flags |= RATE_INFO_FLAGS_EHT_MCS;
5857 break;
7138763e
JB
5858 case RATE_MCS_HE_MSK:
5859 gi_ltf = u32_get_bits(rate_n_flags, RATE_MCS_HE_GI_LTF_MSK);
ed780545
JB
5860
5861 rinfo->flags |= RATE_INFO_FLAGS_HE_MCS;
ed780545 5862
82cdbd11 5863 if (rate_n_flags & RATE_MCS_HE_106T_MSK) {
ed780545
JB
5864 rinfo->bw = RATE_INFO_BW_HE_RU;
5865 rinfo->he_ru_alloc = NL80211_RATE_INFO_HE_RU_ALLOC_106;
5866 }
5867
82cdbd11
MK
5868 switch (rate_n_flags & RATE_MCS_HE_TYPE_MSK) {
5869 case RATE_MCS_HE_TYPE_SU:
5870 case RATE_MCS_HE_TYPE_EXT_SU:
ed780545
JB
5871 if (gi_ltf == 0 || gi_ltf == 1)
5872 rinfo->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
5873 else if (gi_ltf == 2)
5874 rinfo->he_gi = NL80211_RATE_INFO_HE_GI_1_6;
82cdbd11 5875 else if (gi_ltf == 3)
ed780545 5876 rinfo->he_gi = NL80211_RATE_INFO_HE_GI_3_2;
82cdbd11
MK
5877 else
5878 rinfo->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
ed780545 5879 break;
82cdbd11 5880 case RATE_MCS_HE_TYPE_MU:
ed780545
JB
5881 if (gi_ltf == 0 || gi_ltf == 1)
5882 rinfo->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
5883 else if (gi_ltf == 2)
5884 rinfo->he_gi = NL80211_RATE_INFO_HE_GI_1_6;
5885 else
5886 rinfo->he_gi = NL80211_RATE_INFO_HE_GI_3_2;
5887 break;
82cdbd11 5888 case RATE_MCS_HE_TYPE_TRIG:
ed780545
JB
5889 if (gi_ltf == 0 || gi_ltf == 1)
5890 rinfo->he_gi = NL80211_RATE_INFO_HE_GI_1_6;
5891 else
5892 rinfo->he_gi = NL80211_RATE_INFO_HE_GI_3_2;
5893 break;
5894 }
5895
5896 if (rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK)
5897 rinfo->he_dcm = 1;
7138763e
JB
5898 break;
5899 case RATE_MCS_HT_MSK:
82cdbd11 5900 rinfo->flags |= RATE_INFO_FLAGS_MCS;
7138763e
JB
5901 break;
5902 case RATE_MCS_VHT_MSK:
82cdbd11 5903 rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS;
7138763e 5904 break;
ed780545
JB
5905 }
5906}
5907
cbce62a3
MK
5908void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw,
5909 struct ieee80211_vif *vif,
5910 struct ieee80211_sta *sta,
5911 struct station_info *sinfo)
33cef925
JB
5912{
5913 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
5914 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
5915 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
5916
c8ee33e1
GG
5917 if (mvmsta->deflink.avg_energy) {
5918 sinfo->signal_avg = -(s8)mvmsta->deflink.avg_energy;
22d0d2fa 5919 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
988b5968
SS
5920 }
5921
ed780545 5922 if (iwl_mvm_has_tlc_offload(mvm)) {
c8ee33e1 5923 struct iwl_lq_sta_rs_fw *lq_sta = &mvmsta->deflink.lq_sta.rs_fw;
ed780545
JB
5924
5925 iwl_mvm_set_sta_rate(lq_sta->last_rate_n_flags, &sinfo->txrate);
5926 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
5927 }
5928
33cef925
JB
5929 /* if beacon filtering isn't on mac80211 does it anyway */
5930 if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
5931 return;
5932
f276e20b 5933 if (!vif->cfg.assoc)
33cef925
JB
5934 return;
5935
5936 mutex_lock(&mvm->mutex);
5937
c8ee33e1 5938 if (mvmvif->deflink.ap_sta_id != mvmsta->deflink.sta_id)
33cef925
JB
5939 goto unlock;
5940
5941 if (iwl_mvm_request_statistics(mvm, false))
5942 goto unlock;
5943
650cadb7
GG
5944 sinfo->rx_beacon = mvmvif->deflink.beacon_stats.num_beacons +
5945 mvmvif->deflink.beacon_stats.accu_num_beacons;
22d0d2fa 5946 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_RX);
650cadb7 5947 if (mvmvif->deflink.beacon_stats.avg_signal) {
33cef925 5948 /* firmware only reports a value after RXing a few beacons */
650cadb7
GG
5949 sinfo->rx_beacon_signal_avg =
5950 mvmvif->deflink.beacon_stats.avg_signal;
22d0d2fa 5951 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG);
33cef925
JB
5952 }
5953 unlock:
5954 mutex_unlock(&mvm->mutex);
5955}
5956
119c2a13
MG
5957static void iwl_mvm_event_mlme_callback_ini(struct iwl_mvm *mvm,
5958 struct ieee80211_vif *vif,
5959 const struct ieee80211_mlme_event *mlme)
5960{
1a81bddf
MG
5961 if ((mlme->data == ASSOC_EVENT || mlme->data == AUTH_EVENT) &&
5962 (mlme->status == MLME_DENIED || mlme->status == MLME_TIMEOUT)) {
119c2a13
MG
5963 iwl_dbg_tlv_time_point(&mvm->fwrt,
5964 IWL_FW_INI_TIME_POINT_ASSOC_FAILED,
5965 NULL);
5966 return;
5967 }
5968
119c2a13
MG
5969 if (mlme->data == DEAUTH_RX_EVENT || mlme->data == DEAUTH_TX_EVENT) {
5970 iwl_dbg_tlv_time_point(&mvm->fwrt,
5971 IWL_FW_INI_TIME_POINT_DEASSOC,
5972 NULL);
5973 return;
5974 }
5975}
5976
4203263d
EG
5977static void iwl_mvm_event_mlme_callback(struct iwl_mvm *mvm,
5978 struct ieee80211_vif *vif,
5979 const struct ieee80211_event *event)
d42f5350 5980{
7174beb6
JB
5981#define CHECK_MLME_TRIGGER(_cnt, _fmt...) \
5982 do { \
5983 if ((trig_mlme->_cnt) && --(trig_mlme->_cnt)) \
5984 break; \
5985 iwl_fw_dbg_collect_trig(&(mvm)->fwrt, trig, _fmt); \
d42f5350
EG
5986 } while (0)
5987
d42f5350
EG
5988 struct iwl_fw_dbg_trigger_tlv *trig;
5989 struct iwl_fw_dbg_trigger_mlme *trig_mlme;
d42f5350 5990
119c2a13
MG
5991 if (iwl_trans_dbg_ini_valid(mvm->trans)) {
5992 iwl_mvm_event_mlme_callback_ini(mvm, vif, &event->u.mlme);
5993 return;
5994 }
5995
6c042d75
SS
5996 trig = iwl_fw_dbg_trigger_on(&mvm->fwrt, ieee80211_vif_to_wdev(vif),
5997 FW_DBG_TRIGGER_MLME);
5998 if (!trig)
d42f5350
EG
5999 return;
6000
d42f5350 6001 trig_mlme = (void *)trig->data;
d42f5350 6002
d42f5350
EG
6003 if (event->u.mlme.data == ASSOC_EVENT) {
6004 if (event->u.mlme.status == MLME_DENIED)
4c324a51 6005 CHECK_MLME_TRIGGER(stop_assoc_denied,
d42f5350
EG
6006 "DENIED ASSOC: reason %d",
6007 event->u.mlme.reason);
6008 else if (event->u.mlme.status == MLME_TIMEOUT)
4c324a51 6009 CHECK_MLME_TRIGGER(stop_assoc_timeout,
d42f5350
EG
6010 "ASSOC TIMEOUT");
6011 } else if (event->u.mlme.data == AUTH_EVENT) {
6012 if (event->u.mlme.status == MLME_DENIED)
4c324a51 6013 CHECK_MLME_TRIGGER(stop_auth_denied,
d42f5350
EG
6014 "DENIED AUTH: reason %d",
6015 event->u.mlme.reason);
6016 else if (event->u.mlme.status == MLME_TIMEOUT)
4c324a51 6017 CHECK_MLME_TRIGGER(stop_auth_timeout,
d42f5350
EG
6018 "AUTH TIMEOUT");
6019 } else if (event->u.mlme.data == DEAUTH_RX_EVENT) {
4c324a51 6020 CHECK_MLME_TRIGGER(stop_rx_deauth,
d42f5350
EG
6021 "DEAUTH RX %d", event->u.mlme.reason);
6022 } else if (event->u.mlme.data == DEAUTH_TX_EVENT) {
4c324a51 6023 CHECK_MLME_TRIGGER(stop_tx_deauth,
d42f5350
EG
6024 "DEAUTH TX %d", event->u.mlme.reason);
6025 }
6026#undef CHECK_MLME_TRIGGER
6027}
6028
4203263d
EG
6029static void iwl_mvm_event_bar_rx_callback(struct iwl_mvm *mvm,
6030 struct ieee80211_vif *vif,
6031 const struct ieee80211_event *event)
6032{
6033 struct iwl_fw_dbg_trigger_tlv *trig;
6034 struct iwl_fw_dbg_trigger_ba *ba_trig;
6035
6c042d75
SS
6036 trig = iwl_fw_dbg_trigger_on(&mvm->fwrt, ieee80211_vif_to_wdev(vif),
6037 FW_DBG_TRIGGER_BA);
6038 if (!trig)
4203263d
EG
6039 return;
6040
4203263d 6041 ba_trig = (void *)trig->data;
4203263d
EG
6042
6043 if (!(le16_to_cpu(ba_trig->rx_bar) & BIT(event->u.ba.tid)))
6044 return;
6045
7174beb6
JB
6046 iwl_fw_dbg_collect_trig(&mvm->fwrt, trig,
6047 "BAR received from %pM, tid %d, ssn %d",
6048 event->u.ba.sta->addr, event->u.ba.tid,
6049 event->u.ba.ssn);
4203263d
EG
6050}
6051
cbce62a3
MK
6052void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw,
6053 struct ieee80211_vif *vif,
6054 const struct ieee80211_event *event)
4203263d
EG
6055{
6056 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
6057
6058 switch (event->type) {
6059 case MLME_EVENT:
6060 iwl_mvm_event_mlme_callback(mvm, vif, event);
6061 break;
6062 case BAR_RX_EVENT:
6063 iwl_mvm_event_bar_rx_callback(mvm, vif, event);
6064 break;
6065 case BA_FRAME_TIMEOUT:
528a542a
EG
6066 iwl_mvm_event_frame_timeout_callback(mvm, vif, event->u.ba.sta,
6067 event->u.ba.tid);
4203263d
EG
6068 break;
6069 default:
6070 break;
6071 }
6072}
6073
d0ff5d22 6074void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
5e1688ce
JB
6075 enum iwl_mvm_rxq_notif_type type,
6076 bool sync,
6077 const void *data, u32 size)
0636b938 6078{
5e1688ce
JB
6079 struct {
6080 struct iwl_rxq_sync_cmd cmd;
6081 struct iwl_mvm_internal_rxq_notif notif;
6082 } __packed cmd = {
6083 .cmd.rxq_mask = cpu_to_le32(BIT(mvm->trans->num_rx_queues) - 1),
6084 .cmd.count =
6085 cpu_to_le32(sizeof(struct iwl_mvm_internal_rxq_notif) +
6086 size),
6087 .notif.type = type,
6088 .notif.sync = sync,
6089 };
6090 struct iwl_host_cmd hcmd = {
6091 .id = WIDE_ID(DATA_PATH_GROUP, TRIGGER_RX_QUEUES_NOTIF_CMD),
6092 .data[0] = &cmd,
6093 .len[0] = sizeof(cmd),
6094 .data[1] = data,
6095 .len[1] = size,
6096 .flags = sync ? 0 : CMD_ASYNC,
6097 };
0636b938
SS
6098 int ret;
6099
5e1688ce
JB
6100 /* size must be a multiple of DWORD */
6101 if (WARN_ON(cmd.cmd.count & cpu_to_le32(3)))
6102 return;
0636b938 6103
cb8550e1 6104 if (!iwl_mvm_has_new_rx_api(mvm))
0636b938
SS
6105 return;
6106
5e1688ce
JB
6107 if (sync) {
6108 cmd.notif.cookie = mvm->queue_sync_cookie;
2f7a04c7 6109 mvm->queue_sync_state = (1 << mvm->trans->num_rx_queues) - 1;
a2113cc4 6110 }
0636b938 6111
5e1688ce 6112 ret = iwl_mvm_send_cmd(mvm, &hcmd);
0636b938
SS
6113 if (ret) {
6114 IWL_ERR(mvm, "Failed to trigger RX queues sync (%d)\n", ret);
6115 goto out;
6116 }
d0ff5d22 6117
5e1688ce 6118 if (sync) {
3c514bf8 6119 lockdep_assert_held(&mvm->mutex);
3a732c65 6120 ret = wait_event_timeout(mvm->rx_sync_waitq,
2f7a04c7 6121 READ_ONCE(mvm->queue_sync_state) == 0 ||
6ad04359 6122 iwl_mvm_is_radio_killed(mvm),
d0ff5d22 6123 HZ);
2f7a04c7
JB
6124 WARN_ONCE(!ret && !iwl_mvm_is_radio_killed(mvm),
6125 "queue sync: failed to sync, state is 0x%lx\n",
6126 mvm->queue_sync_state);
6ad04359 6127 }
0636b938
SS
6128
6129out:
5e1688ce 6130 if (sync) {
5f8a3561 6131 mvm->queue_sync_state = 0;
a2113cc4 6132 mvm->queue_sync_cookie++;
5f8a3561 6133 }
0636b938
SS
6134}
6135
cbce62a3 6136void iwl_mvm_sync_rx_queues(struct ieee80211_hw *hw)
0636b938
SS
6137{
6138 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
6139
6140 mutex_lock(&mvm->mutex);
5e1688ce 6141 iwl_mvm_sync_rx_queues_internal(mvm, IWL_MVM_RXQ_EMPTY, true, NULL, 0);
0636b938
SS
6142 mutex_unlock(&mvm->mutex);
6143}
6144
cbce62a3 6145int
b73f9a4a
JB
6146iwl_mvm_mac_get_ftm_responder_stats(struct ieee80211_hw *hw,
6147 struct ieee80211_vif *vif,
6148 struct cfg80211_ftm_responder_stats *stats)
6149{
6150 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
6151 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
6152
6153 if (vif->p2p || vif->type != NL80211_IFTYPE_AP ||
6154 !mvmvif->ap_ibss_active || !vif->bss_conf.ftm_responder)
6155 return -EINVAL;
6156
6157 mutex_lock(&mvm->mutex);
6158 *stats = mvm->ftm_resp_stats;
6159 mutex_unlock(&mvm->mutex);
6160
6161 stats->filled = BIT(NL80211_FTM_STATS_SUCCESS_NUM) |
6162 BIT(NL80211_FTM_STATS_PARTIAL_NUM) |
6163 BIT(NL80211_FTM_STATS_FAILED_NUM) |
6164 BIT(NL80211_FTM_STATS_ASAP_NUM) |
6165 BIT(NL80211_FTM_STATS_NON_ASAP_NUM) |
6166 BIT(NL80211_FTM_STATS_TOTAL_DURATION_MSEC) |
6167 BIT(NL80211_FTM_STATS_UNKNOWN_TRIGGERS_NUM) |
6168 BIT(NL80211_FTM_STATS_RESCHEDULE_REQUESTS_NUM) |
6169 BIT(NL80211_FTM_STATS_OUT_OF_WINDOW_TRIGGERS_NUM);
6170
6171 return 0;
6172}
6173
cbce62a3
MK
6174int iwl_mvm_start_pmsr(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6175 struct cfg80211_pmsr_request *request)
fc36ffda
JB
6176{
6177 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
6178 int ret;
6179
6180 mutex_lock(&mvm->mutex);
6181 ret = iwl_mvm_ftm_start(mvm, vif, request);
6182 mutex_unlock(&mvm->mutex);
6183
6184 return ret;
6185}
6186
cbce62a3
MK
6187void iwl_mvm_abort_pmsr(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6188 struct cfg80211_pmsr_request *request)
fc36ffda
JB
6189{
6190 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
6191
6192 mutex_lock(&mvm->mutex);
6193 iwl_mvm_ftm_abort(mvm, request);
6194 mutex_unlock(&mvm->mutex);
6195}
6196
438af969
SS
6197static bool iwl_mvm_can_hw_csum(struct sk_buff *skb)
6198{
6199 u8 protocol = ip_hdr(skb)->protocol;
6200
6201 if (!IS_ENABLED(CONFIG_INET))
6202 return false;
6203
6204 return protocol == IPPROTO_TCP || protocol == IPPROTO_UDP;
6205}
6206
6207static bool iwl_mvm_mac_can_aggregate(struct ieee80211_hw *hw,
6208 struct sk_buff *head,
6209 struct sk_buff *skb)
6210{
6211 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
6212
6213 /* For now don't aggregate IPv6 in AMSDU */
6214 if (skb->protocol != htons(ETH_P_IP))
6215 return false;
6216
6217 if (!iwl_mvm_is_csum_supported(mvm))
6218 return true;
6219
6220 return iwl_mvm_can_hw_csum(skb) == iwl_mvm_can_hw_csum(head);
6221}
6222
be8897e2
AS
6223int iwl_mvm_set_hw_timestamp(struct ieee80211_hw *hw,
6224 struct ieee80211_vif *vif,
6225 struct cfg80211_set_hw_timestamp *hwts)
cf85123a
AS
6226{
6227 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
6228 u32 protocols = 0;
6229 int ret;
6230
6231 /* HW timestamping is only supported for a specific station */
6232 if (!hwts->macaddr)
6233 return -EOPNOTSUPP;
6234
6235 if (hwts->enable)
6236 protocols =
6237 IWL_TIME_SYNC_PROTOCOL_TM | IWL_TIME_SYNC_PROTOCOL_FTM;
6238
6239 mutex_lock(&mvm->mutex);
6240 ret = iwl_mvm_time_sync_config(mvm, hwts->macaddr, protocols);
6241 mutex_unlock(&mvm->mutex);
6242
6243 return ret;
6244}
6245
e5209263 6246const struct ieee80211_ops iwl_mvm_hw_ops = {
8ca151b5 6247 .tx = iwl_mvm_mac_tx,
cfbc6c4c 6248 .wake_tx_queue = iwl_mvm_mac_wake_tx_queue,
8ca151b5 6249 .ampdu_action = iwl_mvm_mac_ampdu_action,
e8503aec 6250 .get_antenna = iwl_mvm_op_get_antenna,
4ea1ed1d 6251 .set_antenna = iwl_mvm_op_set_antenna,
8ca151b5 6252 .start = iwl_mvm_mac_start,
cf2c92d8 6253 .reconfig_complete = iwl_mvm_mac_reconfig_complete,
8ca151b5
JB
6254 .stop = iwl_mvm_mac_stop,
6255 .add_interface = iwl_mvm_mac_add_interface,
6256 .remove_interface = iwl_mvm_mac_remove_interface,
6257 .config = iwl_mvm_mac_config,
e59647ea 6258 .prepare_multicast = iwl_mvm_prepare_multicast,
8ca151b5 6259 .configure_filter = iwl_mvm_configure_filter,
effd1929 6260 .config_iface_filter = iwl_mvm_config_iface_filter,
8ca151b5
JB
6261 .bss_info_changed = iwl_mvm_bss_info_changed,
6262 .hw_scan = iwl_mvm_mac_hw_scan,
6263 .cancel_hw_scan = iwl_mvm_mac_cancel_hw_scan,
1ddbbb0c 6264 .sta_pre_rcu_remove = iwl_mvm_sta_pre_rcu_remove,
8ca151b5
JB
6265 .sta_state = iwl_mvm_mac_sta_state,
6266 .sta_notify = iwl_mvm_mac_sta_notify,
6267 .allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames,
3e56eadf 6268 .release_buffered_frames = iwl_mvm_mac_release_buffered_frames,
8ca151b5 6269 .set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
1f3b0ff8 6270 .sta_rc_update = iwl_mvm_sta_rc_update,
8ca151b5
JB
6271 .conf_tx = iwl_mvm_mac_conf_tx,
6272 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
6b1259d1 6273 .mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx,
07ecd897 6274 .mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover,
c5b0e7c0 6275 .flush = iwl_mvm_mac_flush,
a6cc6ccb 6276 .flush_sta = iwl_mvm_mac_flush_sta,
35a000b7
DS
6277 .sched_scan_start = iwl_mvm_mac_sched_scan_start,
6278 .sched_scan_stop = iwl_mvm_mac_sched_scan_stop,
8ca151b5
JB
6279 .set_key = iwl_mvm_mac_set_key,
6280 .update_tkip_key = iwl_mvm_mac_update_tkip_key,
6281 .remain_on_channel = iwl_mvm_roc,
6282 .cancel_remain_on_channel = iwl_mvm_cancel_roc,
8ca151b5
JB
6283 .add_chanctx = iwl_mvm_add_chanctx,
6284 .remove_chanctx = iwl_mvm_remove_chanctx,
6285 .change_chanctx = iwl_mvm_change_chanctx,
6286 .assign_vif_chanctx = iwl_mvm_assign_vif_chanctx,
6287 .unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx,
b08c1d97 6288 .switch_vif_chanctx = iwl_mvm_switch_vif_chanctx,
8ca151b5 6289
ae7ba17b
ST
6290 .start_ap = iwl_mvm_start_ap,
6291 .stop_ap = iwl_mvm_stop_ap,
6292 .join_ibss = iwl_mvm_start_ibss,
6293 .leave_ibss = iwl_mvm_stop_ibss,
8ca151b5 6294
2f0282db
JB
6295 .tx_last_beacon = iwl_mvm_tx_last_beacon,
6296
8ca151b5
JB
6297 .set_tim = iwl_mvm_set_tim,
6298
622e3f9b 6299 .channel_switch = iwl_mvm_channel_switch,
f028905c 6300 .pre_channel_switch = iwl_mvm_pre_channel_switch,
f6c34820 6301 .post_channel_switch = iwl_mvm_post_channel_switch,
79221126 6302 .abort_channel_switch = iwl_mvm_abort_channel_switch,
c37763d2 6303 .channel_switch_rx_beacon = iwl_mvm_channel_switch_rx_beacon,
bd3398e2 6304
1d3c3f63
AN
6305 .tdls_channel_switch = iwl_mvm_tdls_channel_switch,
6306 .tdls_cancel_channel_switch = iwl_mvm_tdls_cancel_channel_switch,
6307 .tdls_recv_channel_switch = iwl_mvm_tdls_recv_channel_switch,
6308
d42f5350
EG
6309 .event_callback = iwl_mvm_mac_event_callback,
6310
0636b938
SS
6311 .sync_rx_queues = iwl_mvm_sync_rx_queues,
6312
507cadf2
DS
6313 CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd)
6314
8ca151b5
JB
6315#ifdef CONFIG_PM_SLEEP
6316 /* look at d3.c */
6317 .suspend = iwl_mvm_suspend,
6318 .resume = iwl_mvm_resume,
6319 .set_wakeup = iwl_mvm_set_wakeup,
6320 .set_rekey_data = iwl_mvm_set_rekey_data,
6321#if IS_ENABLED(CONFIG_IPV6)
6322 .ipv6_addr_change = iwl_mvm_ipv6_addr_change,
6323#endif
6324 .set_default_unicast_key = iwl_mvm_set_default_unicast_key,
6325#endif
91a8bcde 6326 .get_survey = iwl_mvm_mac_get_survey,
33cef925 6327 .sta_statistics = iwl_mvm_mac_sta_statistics,
b73f9a4a 6328 .get_ftm_responder_stats = iwl_mvm_mac_get_ftm_responder_stats,
fc36ffda
JB
6329 .start_pmsr = iwl_mvm_start_pmsr,
6330 .abort_pmsr = iwl_mvm_abort_pmsr,
b73f9a4a 6331
438af969 6332 .can_aggregate_in_amsdu = iwl_mvm_mac_can_aggregate,
177a11cf 6333#ifdef CONFIG_IWLWIFI_DEBUGFS
c36235ac 6334 .vif_add_debugfs = iwl_mvm_vif_add_debugfs,
3f244876 6335 .link_sta_add_debugfs = iwl_mvm_link_sta_add_debugfs,
177a11cf 6336#endif
cf85123a 6337 .set_hw_timestamp = iwl_mvm_set_hw_timestamp,
8ca151b5 6338};