FILE
mac80211.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2/* 3 * Copyright (C) 2024-2025 Intel Corporation 4 */ 5 6#include <net/mac80211.h> 7#include <linux/fips.h> 8#include <linux/ip.h> 9 10#include "mld.h" 11#include "mac80211.h" 12#include "phy.h" 13#include "iface.h" 14#include "power.h" 15#include "sta.h" 16#include "agg.h" 17#include "scan.h" 18#include "d3.h" 19#include "tlc.h" 20#include "key.h" 21#include "ap.h" 22#include "tx.h" 23#include "roc.h" 24#include "mlo.h" 25#include "stats.h" 26#include "iwl-nvm-parse.h" 27#include "ftm-initiator.h" 28#include "low_latency.h" 29#include "fw/api/scan.h" 30#include "fw/api/context.h" 31#include "fw/api/filter.h" 32#include "fw/api/sta.h" 33#include "fw/api/tdls.h" 34#ifdef CONFIG_PM_SLEEP 35#include "fw/api/d3.h" 36#endif /* CONFIG_PM_SLEEP */ 37#include "iwl-trans.h" 38 39#define IWL_MLD_LIMITS(ap) \ 40 { \ 41 .max = 2, \ 42 .types = BIT(NL80211_IFTYPE_STATION), \ 43 }, \ 44 { \ 45 .max = 1, \ 46 .types = ap | \ 47 BIT(NL80211_IFTYPE_P2P_CLIENT) | \ 48 BIT(NL80211_IFTYPE_P2P_GO), \ 49 }, \ 50 { \ 51 .max = 1, \ 52 .types = BIT(NL80211_IFTYPE_P2P_DEVICE), \ 53 } 54 55static const struct ieee80211_iface_limit iwl_mld_limits[] = { 56 IWL_MLD_LIMITS(0) 57}; 58 59static const struct ieee80211_iface_limit iwl_mld_limits_ap[] = { 60 IWL_MLD_LIMITS(BIT(NL80211_IFTYPE_AP)) 61}; 62 63static const struct ieee80211_iface_combination 64iwl_mld_iface_combinations[] = { 65 { 66 .num_different_channels = 2, 67 .max_interfaces = 4, 68 .limits = iwl_mld_limits, 69 .n_limits = ARRAY_SIZE(iwl_mld_limits), 70 }, 71 { 72 .num_different_channels = 1, 73 .max_interfaces = 4, 74 .limits = iwl_mld_limits_ap, 75 .n_limits = ARRAY_SIZE(iwl_mld_limits_ap), 76 }, 77}; 78 79static const u8 ext_capa_base[IWL_MLD_STA_EXT_CAPA_SIZE] = { 80 [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, 81 [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, 82 [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF | 83 WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB, 84 [8] = WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB, 85}; 86 87#define IWL_MLD_EMLSR_CAPA (IEEE80211_EML_CAP_EMLSR_SUPP | \ 88 IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_32US << \ 89 __bf_shf(IEEE80211_EML_CAP_EMLSR_PADDING_DELAY) | \ 90 IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_64US << \ 91 __bf_shf(IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY)) 92#define IWL_MLD_CAPA_OPS (FIELD_PREP_CONST( \ 93 IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP, \ 94 IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP_SAME) | \ 95 IEEE80211_MLD_CAP_OP_LINK_RECONF_SUPPORT) 96 97static void iwl_mld_hw_set_addresses(struct iwl_mld *mld) 98{ 99 struct wiphy *wiphy = mld->wiphy; 100 int num_addrs = 1; 101 102 /* Extract MAC address */ 103 memcpy(mld->addresses[0].addr, mld->nvm_data->hw_addr, ETH_ALEN); 104 wiphy->addresses = mld->addresses; 105 wiphy->n_addresses = 1; 106 107 /* Extract additional MAC addresses if available */ 108 if (mld->nvm_data->n_hw_addrs > 1) 109 num_addrs = min(mld->nvm_data->n_hw_addrs, 110 IWL_MLD_MAX_ADDRESSES); 111 112 for (int i = 1; i < num_addrs; i++) { 113 memcpy(mld->addresses[i].addr, 114 mld->addresses[i - 1].addr, 115 ETH_ALEN); 116 mld->addresses[i].addr[ETH_ALEN - 1]++; 117 wiphy->n_addresses++; 118 } 119} 120 121static void iwl_mld_hw_set_channels(struct iwl_mld *mld) 122{ 123 struct wiphy *wiphy = mld->wiphy; 124 struct ieee80211_supported_band *bands = mld->nvm_data->bands; 125 126 wiphy->bands[NL80211_BAND_2GHZ] = &bands[NL80211_BAND_2GHZ]; 127 wiphy->bands[NL80211_BAND_5GHZ] = &bands[NL80211_BAND_5GHZ]; 128 129 if (bands[NL80211_BAND_6GHZ].n_channels) 130 wiphy->bands[NL80211_BAND_6GHZ] = &bands[NL80211_BAND_6GHZ]; 131} 132 133static void iwl_mld_hw_set_security(struct iwl_mld *mld) 134{ 135 struct ieee80211_hw *hw = mld->hw; 136 static const u32 mld_ciphers[] = { 137 WLAN_CIPHER_SUITE_WEP40, 138 WLAN_CIPHER_SUITE_WEP104, 139 WLAN_CIPHER_SUITE_TKIP, 140 WLAN_CIPHER_SUITE_CCMP, 141 WLAN_CIPHER_SUITE_GCMP, 142 WLAN_CIPHER_SUITE_GCMP_256, 143 WLAN_CIPHER_SUITE_AES_CMAC, 144 WLAN_CIPHER_SUITE_BIP_GMAC_128, 145 WLAN_CIPHER_SUITE_BIP_GMAC_256 146 }; 147 148 if (fips_enabled) 149 return; 150 151 hw->wiphy->n_cipher_suites = ARRAY_SIZE(mld_ciphers); 152 hw->wiphy->cipher_suites = mld_ciphers; 153 154 ieee80211_hw_set(hw, MFP_CAPABLE); 155 wiphy_ext_feature_set(hw->wiphy, 156 NL80211_EXT_FEATURE_BEACON_PROTECTION); 157} 158 159static void iwl_mld_hw_set_antennas(struct iwl_mld *mld) 160{ 161 struct wiphy *wiphy = mld->wiphy; 162 163 wiphy->available_antennas_tx = iwl_mld_get_valid_tx_ant(mld); 164 wiphy->available_antennas_rx = iwl_mld_get_valid_rx_ant(mld); 165} 166 167static void iwl_mld_hw_set_pm(struct iwl_mld *mld) 168{ 169#ifdef CONFIG_PM_SLEEP 170 struct wiphy *wiphy = mld->wiphy; 171 172 if (!device_can_wakeup(mld->trans->dev)) 173 return; 174 175 if (fips_enabled) 176 return; 177 178 mld->wowlan.flags |= WIPHY_WOWLAN_MAGIC_PKT | 179 WIPHY_WOWLAN_DISCONNECT | 180 WIPHY_WOWLAN_EAP_IDENTITY_REQ | 181 WIPHY_WOWLAN_RFKILL_RELEASE | 182 WIPHY_WOWLAN_NET_DETECT | 183 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 184 WIPHY_WOWLAN_GTK_REKEY_FAILURE | 185 WIPHY_WOWLAN_4WAY_HANDSHAKE; 186 187 mld->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS; 188 mld->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN; 189 mld->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN; 190 mld->wowlan.max_nd_match_sets = IWL_SCAN_MAX_PROFILES_V2; 191 192 wiphy->wowlan = &mld->wowlan; 193#endif /* CONFIG_PM_SLEEP */ 194} 195 196static void iwl_mac_hw_set_radiotap(struct iwl_mld *mld) 197{ 198 struct ieee80211_hw *hw = mld->hw; 199 200 hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FEC | 201 IEEE80211_RADIOTAP_MCS_HAVE_STBC; 202 203 hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC | 204 IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED; 205 206 hw->radiotap_timestamp.units_pos = 207 IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US | 208 IEEE80211_RADIOTAP_TIMESTAMP_SPOS_PLCP_SIG_ACQ; 209 210 /* this is the case for CCK frames, it's better (only 8) for OFDM */ 211 hw->radiotap_timestamp.accuracy = 22; 212} 213 214static void iwl_mac_hw_set_flags(struct iwl_mld *mld) 215{ 216 struct ieee80211_hw *hw = mld->hw; 217 218 ieee80211_hw_set(hw, USES_RSS); 219 ieee80211_hw_set(hw, HANDLES_QUIET_CSA); 220 ieee80211_hw_set(hw, AP_LINK_PS); 221 ieee80211_hw_set(hw, SIGNAL_DBM); 222 ieee80211_hw_set(hw, SPECTRUM_MGMT); 223 ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); 224 ieee80211_hw_set(hw, WANT_MONITOR_VIF); 225 ieee80211_hw_set(hw, SUPPORTS_PS); 226 ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); 227 ieee80211_hw_set(hw, AMPDU_AGGREGATION); 228 ieee80211_hw_set(hw, CONNECTION_MONITOR); 229 ieee80211_hw_set(hw, CHANCTX_STA_CSA); 230 ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); 231 ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS); 232 ieee80211_hw_set(hw, NEEDS_UNIQUE_STA_ADDR); 233 ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); 234 ieee80211_hw_set(hw, BUFF_MMPDU_TXQ); 235 ieee80211_hw_set(hw, STA_MMPDU_TXQ); 236 ieee80211_hw_set(hw, TX_AMSDU); 237 ieee80211_hw_set(hw, TX_FRAG_LIST); 238 ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW); 239 ieee80211_hw_set(hw, HAS_RATE_CONTROL); 240 ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER); 241 ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); 242 ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); 243 ieee80211_hw_set(hw, TDLS_WIDER_BW); 244} 245 246static void iwl_mac_hw_set_wiphy(struct iwl_mld *mld) 247{ 248 struct ieee80211_hw *hw = mld->hw; 249 struct wiphy *wiphy = hw->wiphy; 250 const struct iwl_ucode_capabilities *ucode_capa = &mld->fw->ucode_capa; 251 252 snprintf(wiphy->fw_version, 253 sizeof(wiphy->fw_version), 254 "%.31s", mld->fw->fw_version); 255 256 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 257 BIT(NL80211_IFTYPE_P2P_CLIENT) | 258 BIT(NL80211_IFTYPE_AP) | 259 BIT(NL80211_IFTYPE_P2P_GO) | 260 BIT(NL80211_IFTYPE_P2P_DEVICE) | 261 BIT(NL80211_IFTYPE_ADHOC); 262 263 wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR | 264 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR | 265 NL80211_FEATURE_ND_RANDOM_MAC_ADDR | 266 NL80211_FEATURE_HT_IBSS | 267 NL80211_FEATURE_P2P_GO_CTWIN | 268 NL80211_FEATURE_LOW_PRIORITY_SCAN | 269 NL80211_FEATURE_P2P_GO_OPPPS | 270 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE | 271 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION | 272 NL80211_FEATURE_TX_POWER_INSERTION | 273 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES; 274 275 wiphy->flags |= WIPHY_FLAG_IBSS_RSN | 276 WIPHY_FLAG_AP_UAPSD | 277 WIPHY_FLAG_HAS_CHANNEL_SWITCH | 278 WIPHY_FLAG_SPLIT_SCAN_6GHZ | 279 WIPHY_FLAG_SUPPORTS_TDLS | 280 WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK; 281 282 /* For fips_enabled, don't support WiFi7 due to WPA3/MFP requirements */ 283 if (mld->nvm_data->sku_cap_11be_enable && 284 !iwlwifi_mod_params.disable_11ax && 285 !iwlwifi_mod_params.disable_11be && 286 !fips_enabled) 287 wiphy->flags |= WIPHY_FLAG_SUPPORTS_MLO; 288 289 /* the firmware uses u8 for num of iterations, but 0xff is saved for 290 * infinite loop, so the maximum number of iterations is actually 254. 291 */ 292 wiphy->max_sched_scan_plan_iterations = 254; 293 wiphy->max_sched_scan_ie_len = iwl_mld_scan_max_template_size(); 294 wiphy->max_scan_ie_len = iwl_mld_scan_max_template_size(); 295 wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX; 296 wiphy->max_scan_ssids = PROBE_OPTION_MAX; 297 wiphy->max_sched_scan_plans = IWL_MAX_SCHED_SCAN_PLANS; 298 wiphy->max_sched_scan_reqs = 1; 299 wiphy->max_sched_scan_plan_interval = U16_MAX; 300 wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES_V2; 301 302 wiphy->max_remain_on_channel_duration = 10000; 303 304 wiphy->hw_version = mld->trans->info.hw_id; 305 306 wiphy->hw_timestamp_max_peers = 1; 307 308 wiphy->iface_combinations = iwl_mld_iface_combinations; 309 wiphy->n_iface_combinations = ARRAY_SIZE(iwl_mld_iface_combinations); 310 311 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS); 312 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_DFS_CONCURRENT); 313 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_LEGACY); 314 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SCAN_START_TIME); 315 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BSS_PARENT_TSF); 316 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT); 317 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP); 318 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME); 319 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE); 320 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER); 321 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT); 322 323 if (fw_has_capa(ucode_capa, IWL_UCODE_TLV_CAPA_PROTECTED_TWT)) 324 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_PROTECTED_TWT); 325 326 if (iwlmld_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) 327 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; 328 else 329 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 330 331 /* We are done for non-HE */ 332 if (iwlwifi_mod_params.disable_11ax) 333 return; 334 335 ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); 336 ieee80211_hw_set(hw, SUPPORTS_ONLY_HE_MULTI_BSSID); 337 338 wiphy->iftype_ext_capab = mld->ext_capab; 339 wiphy->num_iftype_ext_capab = ARRAY_SIZE(mld->ext_capab); 340 341 BUILD_BUG_ON(sizeof(mld->sta_ext_capab) < sizeof(ext_capa_base)); 342 343 memcpy(mld->sta_ext_capab, ext_capa_base, sizeof(ext_capa_base)); 344 345 mld->ext_capab[0].iftype = NL80211_IFTYPE_STATION; 346 mld->ext_capab[0].extended_capabilities = mld->sta_ext_capab; 347 mld->ext_capab[0].extended_capabilities_mask = mld->sta_ext_capab; 348 mld->ext_capab[0].extended_capabilities_len = sizeof(mld->sta_ext_capab); 349 350 if (!mld->nvm_data->sku_cap_11be_enable || 351 iwlwifi_mod_params.disable_11be) 352 return; 353 354 mld->ext_capab[0].eml_capabilities = IWL_MLD_EMLSR_CAPA; 355 mld->ext_capab[0].mld_capa_and_ops = IWL_MLD_CAPA_OPS; 356 357} 358 359static void iwl_mac_hw_set_misc(struct iwl_mld *mld) 360{ 361 struct ieee80211_hw *hw = mld->hw; 362 363 hw->queues = IEEE80211_NUM_ACS; 364 365 hw->netdev_features = NETIF_F_HIGHDMA | NETIF_F_SG; 366 hw->netdev_features |= mld->trans->mac_cfg->base->features; 367 368 hw->max_tx_fragments = mld->trans->info.max_skb_frags; 369 hw->max_listen_interval = IWL_MLD_CONN_LISTEN_INTERVAL; 370 371 hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL; 372 hw->uapsd_queues = IEEE80211_WMM_IE_STA_QOSINFO_AC_VO | 373 IEEE80211_WMM_IE_STA_QOSINFO_AC_VI | 374 IEEE80211_WMM_IE_STA_QOSINFO_AC_BK | 375 IEEE80211_WMM_IE_STA_QOSINFO_AC_BE; 376 377 hw->chanctx_data_size = sizeof(struct iwl_mld_phy); 378 hw->vif_data_size = sizeof(struct iwl_mld_vif); 379 hw->sta_data_size = sizeof(struct iwl_mld_sta); 380 hw->txq_data_size = sizeof(struct iwl_mld_txq); 381 382 /* TODO: Remove this division when IEEE80211_MAX_AMPDU_BUF_EHT size 383 * is supported. 384 * Note: ensure that IWL_DEFAULT_QUEUE_SIZE_EHT is updated accordingly. 385 */ 386 hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_EHT / 2; 387} 388 389static int iwl_mld_hw_verify_preconditions(struct iwl_mld *mld) 390{ 391 int ratecheck; 392 393 /* check for rates version 3 */ 394 ratecheck = 395 (iwl_fw_lookup_cmd_ver(mld->fw, TX_CMD, 0) >= 11) + 396 (iwl_fw_lookup_notif_ver(mld->fw, DATA_PATH_GROUP, 397 TLC_MNG_UPDATE_NOTIF, 0) >= 4) + 398 (iwl_fw_lookup_notif_ver(mld->fw, LEGACY_GROUP, 399 REPLY_RX_MPDU_CMD, 0) >= 6) + 400 (iwl_fw_lookup_notif_ver(mld->fw, LONG_GROUP, TX_CMD, 0) >= 9); 401 402 if (ratecheck != 0 && ratecheck != 4) { 403 IWL_ERR(mld, "Firmware has inconsistent rates\n"); 404 return -EINVAL; 405 } 406 407 /* 11ax is expected to be enabled for all supported devices */ 408 if (WARN_ON(!mld->nvm_data->sku_cap_11ax_enable)) 409 return -EINVAL; 410 411 /* LAR is expected to be enabled for all supported devices */ 412 if (WARN_ON(!mld->nvm_data->lar_enabled)) 413 return -EINVAL; 414 415 /* All supported devices are currently using version 3 of the cmd. 416 * Since version 3, IWL_SCAN_MAX_PROFILES_V2 shall be used where 417 * necessary. 418 */ 419 if (WARN_ON(iwl_fw_lookup_cmd_ver(mld->fw, 420 SCAN_OFFLOAD_UPDATE_PROFILES_CMD, 421 IWL_FW_CMD_VER_UNKNOWN) != 3)) 422 return -EINVAL; 423 424 return 0; 425} 426 427int iwl_mld_register_hw(struct iwl_mld *mld) 428{ 429 /* verify once essential preconditions required for setting 430 * the hw capabilities 431 */ 432 if (iwl_mld_hw_verify_preconditions(mld)) 433 return -EINVAL; 434 435 iwl_mld_hw_set_addresses(mld); 436 iwl_mld_hw_set_channels(mld); 437 iwl_mld_hw_set_security(mld); 438 iwl_mld_hw_set_pm(mld); 439 iwl_mld_hw_set_antennas(mld); 440 iwl_mac_hw_set_radiotap(mld); 441 iwl_mac_hw_set_flags(mld); 442 iwl_mac_hw_set_wiphy(mld); 443 iwl_mac_hw_set_misc(mld); 444 445 SET_IEEE80211_DEV(mld->hw, mld->trans->dev); 446 447 return ieee80211_register_hw(mld->hw); 448} 449 450static void 451iwl_mld_mac80211_tx(struct ieee80211_hw *hw, 452 struct ieee80211_tx_control *control, struct sk_buff *skb) 453{ 454 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 455 struct ieee80211_sta *sta = control->sta; 456 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 457 struct ieee80211_hdr *hdr = (void *)skb->data; 458 u32 link_id = u32_get_bits(info->control.flags, 459 IEEE80211_TX_CTRL_MLO_LINK); 460 461 /* In AP mode, mgmt frames are sent on the bcast station, 462 * so the FW can't translate the MLD addr to the link addr. Do it here 463 */ 464 if (ieee80211_is_mgmt(hdr->frame_control) && sta && 465 link_id != IEEE80211_LINK_UNSPECIFIED && 466 !ieee80211_is_probe_resp(hdr->frame_control)) { 467 /* translate MLD addresses to LINK addresses */ 468 struct ieee80211_link_sta *link_sta = 469 rcu_dereference(sta->link[link_id]); 470 struct ieee80211_bss_conf *link_conf = 471 rcu_dereference(info->control.vif->link_conf[link_id]); 472 struct ieee80211_mgmt *mgmt; 473 474 if (WARN_ON(!link_sta || !link_conf)) { 475 ieee80211_free_txskb(hw, skb); 476 return; 477 } 478 479 mgmt = (void *)hdr; 480 memcpy(mgmt->da, link_sta->addr, ETH_ALEN); 481 memcpy(mgmt->sa, link_conf->addr, ETH_ALEN); 482 memcpy(mgmt->bssid, link_conf->bssid, ETH_ALEN); 483 } 484 485 iwl_mld_tx_skb(mld, skb, NULL); 486} 487 488static void 489iwl_mld_restart_cleanup(struct iwl_mld *mld) 490{ 491 iwl_cleanup_mld(mld); 492 493 ieee80211_iterate_interfaces(mld->hw, IEEE80211_IFACE_ITER_ACTIVE, 494 iwl_mld_cleanup_vif, NULL); 495 496 ieee80211_iterate_stations_atomic(mld->hw, 497 iwl_mld_cleanup_sta, NULL); 498 499 iwl_mld_ftm_restart_cleanup(mld); 500} 501 502static 503int iwl_mld_mac80211_start(struct ieee80211_hw *hw) 504{ 505 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 506 bool in_d3 = false; 507 int ret = 0; 508 509 lockdep_assert_wiphy(mld->wiphy); 510 511#ifdef CONFIG_PM_SLEEP 512 /* Unless the host goes into hibernate the FW always stays on and 513 * the d3_resume flow is used. When wowlan is configured, mac80211 514 * would call it's resume callback and the wowlan_resume flow 515 * would be used. 516 */ 517 518 in_d3 = mld->fw_status.in_d3; 519 if (in_d3) { 520 /* mac80211 already cleaned up the state, no need for cleanup */ 521 ret = iwl_mld_no_wowlan_resume(mld); 522 if (ret) { 523 iwl_mld_stop_fw(mld); 524 /* We're not really restarting in the sense of 525 * in_hw_restart even if we got an error during 526 * this. We'll just start again below and have 527 * nothing to recover, mac80211 will do anyway. 528 */ 529 mld->fw_status.in_hw_restart = false; 530 } 531 } 532#endif /* CONFIG_PM_SLEEP */ 533 534 if (mld->fw_status.in_hw_restart) { 535 iwl_mld_stop_fw(mld); 536 iwl_mld_restart_cleanup(mld); 537 } 538 539 if (!in_d3 || ret) { 540 ret = iwl_mld_start_fw(mld); 541 if (ret) 542 goto error; 543 } 544 545 mld->scan.last_start_time_jiffies = jiffies; 546 547 iwl_dbg_tlv_time_point(&mld->fwrt, IWL_FW_INI_TIME_POINT_POST_INIT, 548 NULL); 549 iwl_dbg_tlv_time_point(&mld->fwrt, IWL_FW_INI_TIME_POINT_PERIODIC, 550 NULL); 551 552 return 0; 553 554error: 555 /* If we failed to restart the hw, there is nothing useful 556 * we can do but indicate we are no longer in restart. 557 */ 558 mld->fw_status.in_hw_restart = false; 559 560 return ret; 561} 562 563static 564void iwl_mld_mac80211_stop(struct ieee80211_hw *hw, bool suspend) 565{ 566 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 567 568 lockdep_assert_wiphy(mld->wiphy); 569 570 wiphy_work_cancel(mld->wiphy, &mld->add_txqs_wk); 571 572 /* if the suspend flow fails the fw is in error. Stop it here, and it 573 * will be started upon wakeup 574 */ 575 if (!suspend || 576 (IS_ENABLED(CONFIG_PM_SLEEP) && iwl_mld_no_wowlan_suspend(mld))) 577 iwl_mld_stop_fw(mld); 578 579 /* Clear in_hw_restart flag when stopping the hw, as mac80211 won't 580 * execute the restart. 581 */ 582 mld->fw_status.in_hw_restart = false; 583 584 /* We shouldn't have any UIDs still set. Loop over all the UIDs to 585 * make sure there's nothing left there and warn if any is found. 586 */ 587 for (int i = 0; i < ARRAY_SIZE(mld->scan.uid_status); i++) 588 if (WARN_ONCE(mld->scan.uid_status[i], 589 "UMAC scan UID %d status was not cleaned (0x%x 0x%x)\n", 590 i, mld->scan.uid_status[i], mld->scan.status)) 591 mld->scan.uid_status[i] = 0; 592} 593 594static 595int iwl_mld_mac80211_config(struct ieee80211_hw *hw, int radio_idx, 596 u32 changed) 597{ 598 return 0; 599} 600 601static 602int iwl_mld_mac80211_add_interface(struct ieee80211_hw *hw, 603 struct ieee80211_vif *vif) 604{ 605 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 606 int ret; 607 608 lockdep_assert_wiphy(mld->wiphy); 609 610 /* Construct mld_vif, add it to fw, and map its ID to ieee80211_vif */ 611 ret = iwl_mld_add_vif(mld, vif); 612 if (ret) 613 return ret; 614 615 /* 616 * Add the default link, but not if this is an MLD vif as that implies 617 * the HW is restarting and it will be configured by change_vif_links. 618 */ 619 if (!ieee80211_vif_is_mld(vif)) 620 ret = iwl_mld_add_link(mld, &vif->bss_conf); 621 if (ret) 622 goto err; 623 624 if (vif->type == NL80211_IFTYPE_STATION) { 625 vif->driver_flags |= IEEE80211_VIF_REMOVE_AP_AFTER_DISASSOC; 626 if (!vif->p2p) 627 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | 628 IEEE80211_VIF_SUPPORTS_CQM_RSSI; 629 } 630 631 if (vif->p2p) 632 vif->driver_flags |= IEEE80211_VIF_IGNORE_OFDMA_WIDER_BW; 633 634 /* 635 * For an MLD vif (in restart) we may not have a link; delay the call 636 * the initial change_vif_links. 637 */ 638 if (vif->type == NL80211_IFTYPE_STATION && 639 !ieee80211_vif_is_mld(vif)) 640 iwl_mld_update_mac_power(mld, vif, false); 641 642 if (vif->type == NL80211_IFTYPE_MONITOR) { 643 mld->monitor.on = true; 644 ieee80211_hw_set(mld->hw, RX_INCLUDES_FCS); 645 } 646 647 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) 648 mld->p2p_device_vif = vif; 649 650 return 0; 651 652err: 653 iwl_mld_rm_vif(mld, vif); 654 return ret; 655} 656 657static 658void iwl_mld_mac80211_remove_interface(struct ieee80211_hw *hw, 659 struct ieee80211_vif *vif) 660{ 661 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 662 663 lockdep_assert_wiphy(mld->wiphy); 664 665 if (ieee80211_vif_type_p2p(vif) == NL80211_IFTYPE_STATION) 666 vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER | 667 IEEE80211_VIF_SUPPORTS_CQM_RSSI); 668 669 if (vif->type == NL80211_IFTYPE_MONITOR) { 670 __clear_bit(IEEE80211_HW_RX_INCLUDES_FCS, mld->hw->flags); 671 mld->monitor.on = false; 672 } 673 674 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) 675 mld->p2p_device_vif = NULL; 676 677 iwl_mld_remove_link(mld, &vif->bss_conf); 678 679#ifdef CONFIG_IWLWIFI_DEBUGFS 680 debugfs_remove(iwl_mld_vif_from_mac80211(vif)->dbgfs_slink); 681 iwl_mld_vif_from_mac80211(vif)->dbgfs_slink = NULL; 682#endif 683 684 iwl_mld_rm_vif(mld, vif); 685 686 mld->monitor.phy.valid = false; 687} 688 689struct iwl_mld_mc_iter_data { 690 struct iwl_mld *mld; 691 int port_id; 692}; 693 694static void iwl_mld_mc_iface_iterator(void *data, u8 *mac, 695 struct ieee80211_vif *vif) 696{ 697 struct iwl_mld_mc_iter_data *mc_data = data; 698 struct iwl_mld *mld = mc_data->mld; 699 struct iwl_mcast_filter_cmd *cmd = mld->mcast_filter_cmd; 700 struct iwl_host_cmd hcmd = { 701 .id = MCAST_FILTER_CMD, 702 .dataflags[0] = IWL_HCMD_DFL_NOCOPY, 703 }; 704 int ret, len; 705 706 /* If we don't have free ports, mcast frames will be dropped */ 707 if (WARN_ON_ONCE(mc_data->port_id >= MAX_PORT_ID_NUM)) 708 return; 709 710 if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc) 711 return; 712 713 cmd->port_id = mc_data->port_id++; 714 ether_addr_copy(cmd->bssid, vif->bss_conf.bssid); 715 len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4); 716 717 hcmd.len[0] = len; 718 hcmd.data[0] = cmd; 719 720 ret = iwl_mld_send_cmd(mld, &hcmd); 721 if (ret) 722 IWL_ERR(mld, "mcast filter cmd error. ret=%d\n", ret); 723} 724 725void iwl_mld_recalc_multicast_filter(struct iwl_mld *mld) 726{ 727 struct iwl_mld_mc_iter_data iter_data = { 728 .mld = mld, 729 }; 730 731 if (WARN_ON_ONCE(!mld->mcast_filter_cmd)) 732 return; 733 734 ieee80211_iterate_active_interfaces(mld->hw, 735 IEEE80211_IFACE_ITER_NORMAL, 736 iwl_mld_mc_iface_iterator, 737 &iter_data); 738} 739 740static u64 741iwl_mld_mac80211_prepare_multicast(struct ieee80211_hw *hw, 742 struct netdev_hw_addr_list *mc_list) 743{ 744 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 745 struct iwl_mcast_filter_cmd *cmd; 746 struct netdev_hw_addr *addr; 747 int addr_count = netdev_hw_addr_list_count(mc_list); 748 bool pass_all = addr_count > MAX_MCAST_FILTERING_ADDRESSES; 749 int len; 750 751 if (pass_all) 752 addr_count = 0; 753 754 /* len must be a multiple of 4 */ 755 len = roundup(sizeof(*cmd) + addr_count * ETH_ALEN, 4); 756 cmd = kzalloc(len, GFP_ATOMIC); 757 if (!cmd) 758 return 0; 759 760 if (pass_all) { 761 cmd->pass_all = 1; 762 goto out; 763 } 764 765 netdev_hw_addr_list_for_each(addr, mc_list) { 766 IWL_DEBUG_MAC80211(mld, "mcast addr (%d): %pM\n", 767 cmd->count, addr->addr); 768 ether_addr_copy(&cmd->addr_list[cmd->count * ETH_ALEN], 769 addr->addr); 770 cmd->count++; 771 } 772 773out: 774 return (u64)(unsigned long)cmd; 775} 776 777static 778void iwl_mld_mac80211_configure_filter(struct ieee80211_hw *hw, 779 unsigned int changed_flags, 780 unsigned int *total_flags, 781 u64 multicast) 782{ 783 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 784 struct iwl_mcast_filter_cmd *cmd = (void *)(unsigned long)multicast; 785 786 /* Replace previous configuration */ 787 kfree(mld->mcast_filter_cmd); 788 mld->mcast_filter_cmd = cmd; 789 790 if (!cmd) 791 goto out; 792 793 if (changed_flags & FIF_ALLMULTI) 794 cmd->pass_all = !!(*total_flags & FIF_ALLMULTI); 795 796 if (cmd->pass_all) 797 cmd->count = 0; 798 799 iwl_mld_recalc_multicast_filter(mld); 800out: 801 *total_flags = 0; 802} 803 804static 805void iwl_mld_mac80211_wake_tx_queue(struct ieee80211_hw *hw, 806 struct ieee80211_txq *txq) 807{ 808 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 809 struct iwl_mld_txq *mld_txq = iwl_mld_txq_from_mac80211(txq); 810 811 if (likely(mld_txq->status.allocated) || !txq->sta) { 812 iwl_mld_tx_from_txq(mld, txq); 813 return; 814 } 815 816 /* We don't support TSPEC tids. %IEEE80211_NUM_TIDS is for mgmt */ 817 if (txq->tid != IEEE80211_NUM_TIDS && txq->tid >= IWL_MAX_TID_COUNT) { 818 IWL_DEBUG_MAC80211(mld, "TID %d is not supported\n", txq->tid); 819 return; 820 } 821 822 /* The worker will handle any packets we leave on the txq now */ 823 824 spin_lock_bh(&mld->add_txqs_lock); 825 /* The list is being deleted only after the queue is fully allocated. */ 826 if (list_empty(&mld_txq->list) && 827 /* recheck under lock, otherwise it can be added twice */ 828 !mld_txq->status.allocated) { 829 list_add_tail(&mld_txq->list, &mld->txqs_to_add); 830 wiphy_work_queue(mld->wiphy, &mld->add_txqs_wk); 831 } 832 spin_unlock_bh(&mld->add_txqs_lock); 833} 834 835static void iwl_mld_teardown_tdls_peers(struct iwl_mld *mld) 836{ 837 lockdep_assert_wiphy(mld->wiphy); 838 839 for (int i = 0; i < mld->fw->ucode_capa.num_stations; i++) { 840 struct ieee80211_link_sta *link_sta; 841 struct iwl_mld_sta *mld_sta; 842 843 link_sta = wiphy_dereference(mld->wiphy, 844 mld->fw_id_to_link_sta[i]); 845 if (IS_ERR_OR_NULL(link_sta)) 846 continue; 847 848 if (!link_sta->sta->tdls) 849 continue; 850 851 mld_sta = iwl_mld_sta_from_mac80211(link_sta->sta); 852 853 ieee80211_tdls_oper_request(mld_sta->vif, link_sta->addr, 854 NL80211_TDLS_TEARDOWN, 855 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, 856 GFP_KERNEL); 857 } 858} 859 860static 861int iwl_mld_add_chanctx(struct ieee80211_hw *hw, 862 struct ieee80211_chanctx_conf *ctx) 863{ 864 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 865 struct iwl_mld_phy *phy = iwl_mld_phy_from_mac80211(ctx); 866 int fw_id = iwl_mld_allocate_fw_phy_id(mld); 867 int ret; 868 869 if (fw_id < 0) 870 return fw_id; 871 872 phy->mld = mld; 873 phy->fw_id = fw_id; 874 phy->chandef = *iwl_mld_get_chandef_from_chanctx(mld, ctx); 875 876 ret = iwl_mld_phy_fw_action(mld, ctx, FW_CTXT_ACTION_ADD); 877 if (ret) { 878 mld->used_phy_ids &= ~BIT(phy->fw_id); 879 return ret; 880 } 881 882 if (hweight8(mld->used_phy_ids) > 1) 883 iwl_mld_teardown_tdls_peers(mld); 884 885 return 0; 886} 887 888static 889void iwl_mld_remove_chanctx(struct ieee80211_hw *hw, 890 struct ieee80211_chanctx_conf *ctx) 891{ 892 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 893 struct iwl_mld_phy *phy = iwl_mld_phy_from_mac80211(ctx); 894 895 iwl_mld_phy_fw_action(mld, ctx, FW_CTXT_ACTION_REMOVE); 896 mld->used_phy_ids &= ~BIT(phy->fw_id); 897} 898 899static 900void iwl_mld_change_chanctx(struct ieee80211_hw *hw, 901 struct ieee80211_chanctx_conf *ctx, u32 changed) 902{ 903 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 904 struct iwl_mld_phy *phy = iwl_mld_phy_from_mac80211(ctx); 905 struct cfg80211_chan_def *chandef = 906 iwl_mld_get_chandef_from_chanctx(mld, ctx); 907 908 /* We don't care about these */ 909 if (!(changed & ~(IEEE80211_CHANCTX_CHANGE_RX_CHAINS | 910 IEEE80211_CHANCTX_CHANGE_RADAR | 911 IEEE80211_CHANCTX_CHANGE_CHANNEL))) 912 return; 913 914 /* Check if a FW update is required */ 915 916 if (changed & IEEE80211_CHANCTX_CHANGE_AP) 917 goto update; 918 919 if (chandef->chan == phy->chandef.chan && 920 chandef->center_freq1 == phy->chandef.center_freq1 && 921 chandef->punctured == phy->chandef.punctured) { 922 /* Check if we are toggling between HT and non-HT, no-op */ 923 if (phy->chandef.width == chandef->width || 924 (phy->chandef.width <= NL80211_CHAN_WIDTH_20 && 925 chandef->width <= NL80211_CHAN_WIDTH_20)) 926 return; 927 } 928update: 929 930 iwl_mld_update_phy_chandef(mld, ctx); 931} 932 933static u8 934iwl_mld_chandef_get_primary_80(struct cfg80211_chan_def *chandef) 935{ 936 int data_start; 937 int control_start; 938 int bw; 939 940 if (chandef->width == NL80211_CHAN_WIDTH_320) 941 bw = 320; 942 else if (chandef->width == NL80211_CHAN_WIDTH_160) 943 bw = 160; 944 else 945 return 0; 946 947 /* data is bw wide so the start is half the width */ 948 data_start = chandef->center_freq1 - bw / 2; 949 /* control is 20Mhz width */ 950 control_start = chandef->chan->center_freq - 10; 951 952 return (control_start - data_start) / 80; 953} 954 955static bool iwl_mld_can_activate_link(struct iwl_mld *mld, 956 struct ieee80211_vif *vif, 957 struct ieee80211_bss_conf *link) 958{ 959 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 960 struct iwl_mld_sta *mld_sta; 961 struct iwl_mld_link_sta *link_sta; 962 963 /* In association, we activate the assoc link before adding the STA. */ 964 if (!mld_vif->ap_sta || !vif->cfg.assoc) 965 return true; 966 967 mld_sta = iwl_mld_sta_from_mac80211(mld_vif->ap_sta); 968 969 /* When switching links, we need to wait with the activation until the 970 * STA was added to the FW. It'll be activated in 971 * iwl_mld_update_link_stas 972 */ 973 link_sta = wiphy_dereference(mld->wiphy, mld_sta->link[link->link_id]); 974 975 /* In restart we can have a link_sta that doesn't exist in FW yet */ 976 return link_sta && link_sta->in_fw; 977} 978 979static 980int iwl_mld_assign_vif_chanctx(struct ieee80211_hw *hw, 981 struct ieee80211_vif *vif, 982 struct ieee80211_bss_conf *link, 983 struct ieee80211_chanctx_conf *ctx) 984{ 985 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 986 struct iwl_mld_link *mld_link = iwl_mld_link_from_mac80211(link); 987 struct iwl_mld_link *temp_mld_link; 988 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 989 u16 final_active_links = 0; 990 int ret; 991 992 lockdep_assert_wiphy(mld->wiphy); 993 994 if (WARN_ON(!mld_link)) 995 return -EINVAL; 996 997 if (!rcu_access_pointer(mld_link->chan_ctx)) { 998 /* Track addition of non-BSS link */ 999 if (ieee80211_vif_type_p2p(vif) != NL80211_IFTYPE_STATION) { 1000 ret = iwl_mld_emlsr_check_non_bss_block(mld, 1); 1001 if (ret) 1002 return ret; 1003 } 1004 } 1005 1006 /* for AP, mac parameters such as HE support are updated at this stage. */ 1007 if (vif->type == NL80211_IFTYPE_AP) { 1008 ret = iwl_mld_mac_fw_action(mld, vif, FW_CTXT_ACTION_MODIFY); 1009 1010 if (ret) { 1011 IWL_ERR(mld, "failed to update MAC %pM\n", vif->addr); 1012 return -EINVAL; 1013 } 1014 } 1015 1016 rcu_assign_pointer(mld_link->chan_ctx, ctx); 1017 1018 /* We cannot rely on vif->active_links at this stage as it contains 1019 * both the removed links and the newly added links. 1020 * Therefore, we create our own bitmap of the final active links, 1021 * which does not include the removed links. 1022 */ 1023 for_each_mld_vif_valid_link(mld_vif, temp_mld_link) { 1024 if (rcu_access_pointer(temp_mld_link->chan_ctx)) 1025 final_active_links |= BIT(link_id); 1026 } 1027 1028 if (hweight16(final_active_links) > 1) { 1029 /* Indicate to mac80211 that EML is enabled */ 1030 vif->driver_flags |= IEEE80211_VIF_EML_ACTIVE; 1031 mld_vif->emlsr.last_entry_ts = jiffies; 1032 1033 if (final_active_links == mld_vif->emlsr.selected_links) 1034 mld_vif->emlsr.primary = mld_vif->emlsr.selected_primary; 1035 else 1036 mld_vif->emlsr.primary = __ffs(final_active_links); 1037 1038 iwl_dbg_tlv_time_point(&mld->fwrt, IWL_FW_INI_TIME_ESR_LINK_UP, 1039 NULL); 1040 } 1041 1042 /* First send the link command with the phy context ID. 1043 * Now that we have the phy, we know the band so also the rates 1044 */ 1045 ret = iwl_mld_change_link_in_fw(mld, link, 1046 LINK_CONTEXT_MODIFY_RATES_INFO); 1047 if (ret) 1048 goto err; 1049 1050 /* TODO: Initialize rate control for the AP station, since we might be 1051 * doing a link switch here - we cannot initialize it before since 1052 * this needs the phy context assigned (and in FW?), and we cannot 1053 * do it later because it needs to be initialized as soon as we're 1054 * able to TX on the link, i.e. when active. (task=link-switch) 1055 */ 1056 1057 /* Now activate the link */ 1058 if (iwl_mld_can_activate_link(mld, vif, link)) { 1059 ret = iwl_mld_activate_link(mld, link); 1060 if (ret) 1061 goto err; 1062 } 1063 1064 if (vif->type == NL80211_IFTYPE_STATION) 1065 iwl_mld_send_ap_tx_power_constraint_cmd(mld, vif, link); 1066 1067 if (vif->type == NL80211_IFTYPE_MONITOR) { 1068 ret = iwl_mld_add_mon_sta(mld, vif, link); 1069 if (ret) 1070 goto deactivate_link; 1071 1072 mld->monitor.p80 = 1073 iwl_mld_chandef_get_primary_80(&vif->bss_conf.chanreq.oper); 1074 } 1075 1076 return 0; 1077 1078deactivate_link: 1079 if (mld_link->active) 1080 iwl_mld_deactivate_link(mld, link); 1081err: 1082 RCU_INIT_POINTER(mld_link->chan_ctx, NULL); 1083 return ret; 1084} 1085 1086static 1087void iwl_mld_unassign_vif_chanctx(struct ieee80211_hw *hw, 1088 struct ieee80211_vif *vif, 1089 struct ieee80211_bss_conf *link, 1090 struct ieee80211_chanctx_conf *ctx) 1091{ 1092 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1093 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 1094 struct iwl_mld_link *mld_link = iwl_mld_link_from_mac80211(link); 1095 unsigned int n_active = iwl_mld_count_active_links(mld, vif); 1096 1097 if (WARN_ON(!mld_link)) 1098 return; 1099 1100 /* Track removal of non-BSS link */ 1101 if (ieee80211_vif_type_p2p(vif) != NL80211_IFTYPE_STATION) 1102 iwl_mld_emlsr_check_non_bss_block(mld, -1); 1103 1104 iwl_mld_deactivate_link(mld, link); 1105 1106 if (vif->type == NL80211_IFTYPE_MONITOR) 1107 iwl_mld_remove_mon_sta(mld, vif, link); 1108 1109 if (n_active > 1) { 1110 /* Indicate to mac80211 that EML is disabled */ 1111 vif->driver_flags &= ~IEEE80211_VIF_EML_ACTIVE; 1112 1113 iwl_dbg_tlv_time_point(&mld->fwrt, 1114 IWL_FW_INI_TIME_ESR_LINK_DOWN, 1115 NULL); 1116 } 1117 1118 RCU_INIT_POINTER(mld_link->chan_ctx, NULL); 1119 1120 /* in the non-MLO case, remove/re-add the link to clean up FW state. 1121 * In MLO, it'll be done in drv_change_vif_link 1122 */ 1123 if (!ieee80211_vif_is_mld(vif) && !mld_vif->ap_sta && 1124 !WARN_ON_ONCE(vif->cfg.assoc) && 1125 vif->type != NL80211_IFTYPE_AP && !mld->fw_status.in_hw_restart) { 1126 iwl_mld_remove_link(mld, link); 1127 iwl_mld_add_link(mld, link); 1128 } 1129} 1130 1131static 1132int iwl_mld_mac80211_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, 1133 u32 value) 1134{ 1135 return 0; 1136} 1137 1138static void 1139iwl_mld_link_info_changed_ap_ibss(struct iwl_mld *mld, 1140 struct ieee80211_vif *vif, 1141 struct ieee80211_bss_conf *link, 1142 u64 changes) 1143{ 1144 u32 link_changes = 0; 1145 1146 if (changes & BSS_CHANGED_ERP_SLOT) 1147 link_changes |= LINK_CONTEXT_MODIFY_RATES_INFO; 1148 1149 if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT)) 1150 link_changes |= LINK_CONTEXT_MODIFY_PROTECT_FLAGS; 1151 1152 if (changes & (BSS_CHANGED_QOS | BSS_CHANGED_BANDWIDTH)) 1153 link_changes |= LINK_CONTEXT_MODIFY_QOS_PARAMS; 1154 1155 if (changes & BSS_CHANGED_HE_BSS_COLOR) 1156 link_changes |= LINK_CONTEXT_MODIFY_HE_PARAMS; 1157 1158 if (link_changes) 1159 iwl_mld_change_link_in_fw(mld, link, link_changes); 1160 1161 if (changes & BSS_CHANGED_BEACON) 1162 iwl_mld_update_beacon_template(mld, vif, link); 1163} 1164 1165static 1166u32 iwl_mld_link_changed_mapping(struct iwl_mld *mld, 1167 struct ieee80211_vif *vif, 1168 struct ieee80211_bss_conf *link_conf, 1169 u64 changes) 1170{ 1171 u32 link_changes = 0; 1172 bool has_he, has_eht; 1173 1174 if (changes & BSS_CHANGED_QOS && vif->cfg.assoc && link_conf->qos) 1175 link_changes |= LINK_CONTEXT_MODIFY_QOS_PARAMS; 1176 1177 if (changes & (BSS_CHANGED_ERP_PREAMBLE | BSS_CHANGED_BASIC_RATES | 1178 BSS_CHANGED_ERP_SLOT)) 1179 link_changes |= LINK_CONTEXT_MODIFY_RATES_INFO; 1180 1181 if (changes & (BSS_CHANGED_HT | BSS_CHANGED_ERP_CTS_PROT)) 1182 link_changes |= LINK_CONTEXT_MODIFY_PROTECT_FLAGS; 1183 1184 /* TODO: task=MLO check mac80211's HE flags and if command is needed 1185 * every time there's a link change. Currently used flags are 1186 * BSS_CHANGED_HE_OBSS_PD and BSS_CHANGED_HE_BSS_COLOR. 1187 */ 1188 has_he = link_conf->he_support && !iwlwifi_mod_params.disable_11ax; 1189 has_eht = link_conf->eht_support && !iwlwifi_mod_params.disable_11be; 1190 1191 if (vif->cfg.assoc && (has_he || has_eht)) { 1192 IWL_DEBUG_MAC80211(mld, "Associated in HE mode\n"); 1193 link_changes |= LINK_CONTEXT_MODIFY_HE_PARAMS; 1194 } 1195 1196 return link_changes; 1197} 1198 1199static void 1200iwl_mld_mac80211_link_info_changed_sta(struct iwl_mld *mld, 1201 struct ieee80211_vif *vif, 1202 struct ieee80211_bss_conf *link_conf, 1203 u64 changes) 1204{ 1205 u32 link_changes = iwl_mld_link_changed_mapping(mld, vif, link_conf, 1206 changes); 1207 1208 if (link_changes) 1209 iwl_mld_change_link_in_fw(mld, link_conf, link_changes); 1210 1211 if (changes & BSS_CHANGED_TPE) 1212 iwl_mld_send_ap_tx_power_constraint_cmd(mld, vif, link_conf); 1213 1214 if (changes & BSS_CHANGED_BEACON_INFO) 1215 iwl_mld_update_mac_power(mld, vif, false); 1216 1217 /* The firmware will wait quite a while after association before it 1218 * starts filtering the beacons. We can safely enable beacon filtering 1219 * upon CQM configuration, even if we didn't get a beacon yet. 1220 */ 1221 if (changes & (BSS_CHANGED_CQM | BSS_CHANGED_BEACON_INFO)) 1222 iwl_mld_enable_beacon_filter(mld, link_conf, false); 1223 1224 if (changes & BSS_CHANGED_BANDWIDTH) 1225 iwl_mld_retry_emlsr(mld, vif); 1226} 1227 1228static int iwl_mld_update_mu_groups(struct iwl_mld *mld, 1229 struct ieee80211_bss_conf *link_conf) 1230{ 1231 struct iwl_mu_group_mgmt_cmd cmd = {}; 1232 1233 BUILD_BUG_ON(sizeof(cmd.membership_status) != 1234 sizeof(link_conf->mu_group.membership)); 1235 BUILD_BUG_ON(sizeof(cmd.user_position) != 1236 sizeof(link_conf->mu_group.position)); 1237 1238 memcpy(cmd.membership_status, link_conf->mu_group.membership, 1239 WLAN_MEMBERSHIP_LEN); 1240 memcpy(cmd.user_position, link_conf->mu_group.position, 1241 WLAN_USER_POSITION_LEN); 1242 1243 return iwl_mld_send_cmd_pdu(mld, 1244 WIDE_ID(DATA_PATH_GROUP, 1245 UPDATE_MU_GROUPS_CMD), 1246 &cmd); 1247} 1248 1249static void 1250iwl_mld_mac80211_link_info_changed(struct ieee80211_hw *hw, 1251 struct ieee80211_vif *vif, 1252 struct ieee80211_bss_conf *link_conf, 1253 u64 changes) 1254{ 1255 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1256 1257 switch (vif->type) { 1258 case NL80211_IFTYPE_STATION: 1259 iwl_mld_mac80211_link_info_changed_sta(mld, vif, link_conf, 1260 changes); 1261 break; 1262 case NL80211_IFTYPE_AP: 1263 case NL80211_IFTYPE_ADHOC: 1264 iwl_mld_link_info_changed_ap_ibss(mld, vif, link_conf, 1265 changes); 1266 break; 1267 case NL80211_IFTYPE_MONITOR: 1268 /* The firmware tracks this on its own in STATION mode, but 1269 * obviously not in sniffer mode. 1270 */ 1271 if (changes & BSS_CHANGED_MU_GROUPS) 1272 iwl_mld_update_mu_groups(mld, link_conf); 1273 break; 1274 default: 1275 /* shouldn't happen */ 1276 WARN_ON_ONCE(1); 1277 } 1278 1279 /* We now know our BSSID, we can configure the MAC context with 1280 * eht_support if needed. 1281 */ 1282 if (changes & BSS_CHANGED_BSSID) 1283 iwl_mld_mac_fw_action(mld, vif, FW_CTXT_ACTION_MODIFY); 1284 1285 if (changes & BSS_CHANGED_TXPOWER) 1286 iwl_mld_set_tx_power(mld, link_conf, link_conf->txpower); 1287} 1288 1289static void 1290iwl_mld_smps_workaround(struct iwl_mld *mld, struct ieee80211_vif *vif, bool enable) 1291{ 1292 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 1293 bool workaround_required = 1294 iwl_fw_lookup_cmd_ver(mld->fw, MAC_PM_POWER_TABLE, 0) < 2; 1295 1296 if (!workaround_required) 1297 return; 1298 1299 /* Send the device-level power commands since the 1300 * firmware checks the POWER_TABLE_CMD's POWER_SAVE_EN bit to 1301 * determine SMPS mode. 1302 */ 1303 if (mld_vif->ps_disabled == !enable) 1304 return; 1305 1306 mld_vif->ps_disabled = !enable; 1307 1308 iwl_mld_update_device_power(mld, false); 1309} 1310 1311static 1312void iwl_mld_mac80211_vif_cfg_changed(struct ieee80211_hw *hw, 1313 struct ieee80211_vif *vif, 1314 u64 changes) 1315{ 1316 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1317 int ret; 1318 1319 lockdep_assert_wiphy(mld->wiphy); 1320 1321 if (vif->type != NL80211_IFTYPE_STATION) 1322 return; 1323 1324 if (changes & BSS_CHANGED_ASSOC) { 1325 ret = iwl_mld_mac_fw_action(mld, vif, FW_CTXT_ACTION_MODIFY); 1326 if (ret) 1327 IWL_ERR(mld, "failed to update context\n"); 1328 1329 if (vif->cfg.assoc) { 1330 /* Clear statistics to get clean beacon counter, and 1331 * ask for periodic statistics, as they are needed for 1332 * link selection and RX OMI decisions. 1333 */ 1334 iwl_mld_clear_stats_in_fw(mld); 1335 iwl_mld_request_periodic_fw_stats(mld, true); 1336 1337 iwl_mld_set_vif_associated(mld, vif); 1338 } else { 1339 iwl_mld_request_periodic_fw_stats(mld, false); 1340 } 1341 } 1342 1343 if (changes & BSS_CHANGED_PS) { 1344 iwl_mld_smps_workaround(mld, vif, vif->cfg.ps); 1345 iwl_mld_update_mac_power(mld, vif, false); 1346 } 1347 1348 /* TODO: task=MLO BSS_CHANGED_MLD_VALID_LINKS/CHANGED_MLD_TTLM */ 1349} 1350 1351static int 1352iwl_mld_mac80211_hw_scan(struct ieee80211_hw *hw, 1353 struct ieee80211_vif *vif, 1354 struct ieee80211_scan_request *hw_req) 1355{ 1356 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1357 int ret; 1358 1359 if (WARN_ON(!hw_req->req.n_channels || 1360 hw_req->req.n_channels > 1361 mld->fw->ucode_capa.n_scan_channels)) 1362 return -EINVAL; 1363 1364 ret = iwl_mld_regular_scan_start(mld, vif, &hw_req->req, &hw_req->ies); 1365 if (!ret) { 1366 /* We will be busy with scanning, so the counters may not reflect the 1367 * reality. Stop checking the counters until the scan ends 1368 */ 1369 iwl_mld_start_ignoring_tpt_updates(mld); 1370 } 1371 1372 return ret; 1373} 1374 1375static void 1376iwl_mld_mac80211_cancel_hw_scan(struct ieee80211_hw *hw, 1377 struct ieee80211_vif *vif) 1378{ 1379 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1380 1381 /* Due to a race condition, it's possible that mac80211 asks 1382 * us to stop a hw_scan when it's already stopped. This can 1383 * happen, for instance, if we stopped the scan ourselves, 1384 * called ieee80211_scan_completed() and the userspace called 1385 * cancel scan before ieee80211_scan_work() could run. 1386 * To handle that, simply return if the scan is not running. 1387 */ 1388 if (mld->scan.status & IWL_MLD_SCAN_REGULAR) { 1389 iwl_mld_scan_stop(mld, IWL_MLD_SCAN_REGULAR, true); 1390 /* Scan is over, we can check again the tpt counters */ 1391 iwl_mld_stop_ignoring_tpt_updates(mld); 1392 } 1393} 1394 1395static int 1396iwl_mld_mac80211_sched_scan_start(struct ieee80211_hw *hw, 1397 struct ieee80211_vif *vif, 1398 struct cfg80211_sched_scan_request *req, 1399 struct ieee80211_scan_ies *ies) 1400{ 1401 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1402 1403 return iwl_mld_sched_scan_start(mld, vif, req, ies, IWL_MLD_SCAN_SCHED); 1404} 1405 1406static int 1407iwl_mld_mac80211_sched_scan_stop(struct ieee80211_hw *hw, 1408 struct ieee80211_vif *vif) 1409{ 1410 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1411 1412 /* Due to a race condition, it's possible that mac80211 asks 1413 * us to stop a sched_scan when it's already stopped. This 1414 * can happen, for instance, if we stopped the scan ourselves, 1415 * called ieee80211_sched_scan_stopped() and the userspace called 1416 * stop sched scan before ieee80211_sched_scan_stopped_work() 1417 * could run. To handle this, simply return if the scan is 1418 * not running. 1419 */ 1420 if (!(mld->scan.status & IWL_MLD_SCAN_SCHED)) 1421 return 0; 1422 1423 return iwl_mld_scan_stop(mld, IWL_MLD_SCAN_SCHED, false); 1424} 1425 1426static void 1427iwl_mld_mac80211_reconfig_complete(struct ieee80211_hw *hw, 1428 enum ieee80211_reconfig_type reconfig_type) 1429{ 1430 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1431 1432 switch (reconfig_type) { 1433 case IEEE80211_RECONFIG_TYPE_RESTART: 1434 mld->fw_status.in_hw_restart = false; 1435 iwl_mld_send_recovery_cmd(mld, ERROR_RECOVERY_END_OF_RECOVERY); 1436 iwl_trans_finish_sw_reset(mld->trans); 1437 /* no need to lock, adding in parallel would schedule too */ 1438 if (!list_empty(&mld->txqs_to_add)) 1439 wiphy_work_queue(mld->wiphy, &mld->add_txqs_wk); 1440 1441 IWL_INFO(mld, "restart completed\n"); 1442 break; 1443 case IEEE80211_RECONFIG_TYPE_SUSPEND: 1444 break; 1445 } 1446} 1447 1448static 1449void iwl_mld_mac80211_mgd_prepare_tx(struct ieee80211_hw *hw, 1450 struct ieee80211_vif *vif, 1451 struct ieee80211_prep_tx_info *info) 1452{ 1453 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1454 u32 duration = IWL_MLD_SESSION_PROTECTION_ASSOC_TIME_MS; 1455 1456 /* After a successful association the connection is established 1457 * and we can rely on the quota to send the disassociation frame. 1458 */ 1459 if (info->was_assoc) 1460 return; 1461 1462 if (info->duration > duration) 1463 duration = info->duration; 1464 1465 iwl_mld_schedule_session_protection(mld, vif, duration, 1466 IWL_MLD_SESSION_PROTECTION_MIN_TIME_MS, 1467 info->link_id); 1468} 1469 1470static 1471void iwl_mld_mac_mgd_complete_tx(struct ieee80211_hw *hw, 1472 struct ieee80211_vif *vif, 1473 struct ieee80211_prep_tx_info *info) 1474{ 1475 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1476 1477 /* Successful authentication is the only case that requires to let 1478 * the session protection go. We'll need it for the upcoming 1479 * association. For all the other cases, we need to cancel the session 1480 * protection. 1481 * After successful association the connection is established and 1482 * further mgd tx can rely on the quota. 1483 */ 1484 if (info->success && info->subtype == IEEE80211_STYPE_AUTH) 1485 return; 1486 1487 /* The firmware will be on medium after we configure the vif as 1488 * associated. Removing the session protection allows the firmware 1489 * to stop being on medium. In order to ensure the continuity of our 1490 * presence on medium, we need first to configure the vif as associated 1491 * and only then, remove the session protection. 1492 * Currently, mac80211 calls vif_cfg_changed() first and then, 1493 * drv_mgd_complete_tx(). Ensure that this assumption stays true by 1494 * a warning. 1495 */ 1496 WARN_ON(info->success && 1497 (info->subtype == IEEE80211_STYPE_ASSOC_REQ || 1498 info->subtype == IEEE80211_STYPE_REASSOC_REQ) && 1499 !vif->cfg.assoc); 1500 1501 iwl_mld_cancel_session_protection(mld, vif, info->link_id); 1502} 1503 1504static int 1505iwl_mld_mac80211_conf_tx(struct ieee80211_hw *hw, 1506 struct ieee80211_vif *vif, 1507 unsigned int link_id, u16 ac, 1508 const struct ieee80211_tx_queue_params *params) 1509{ 1510 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1511 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 1512 struct iwl_mld_link *link; 1513 1514 lockdep_assert_wiphy(mld->wiphy); 1515 1516 link = iwl_mld_link_dereference_check(mld_vif, link_id); 1517 if (!link) 1518 return -EINVAL; 1519 1520 link->queue_params[ac] = *params; 1521 1522 /* No need to update right away, we'll get BSS_CHANGED_QOS 1523 * The exception is P2P_DEVICE interface which needs immediate update. 1524 */ 1525 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) 1526 iwl_mld_change_link_in_fw(mld, &vif->bss_conf, 1527 LINK_CONTEXT_MODIFY_QOS_PARAMS); 1528 1529 return 0; 1530} 1531 1532static void iwl_mld_set_uapsd(struct iwl_mld *mld, struct ieee80211_vif *vif) 1533{ 1534 vif->driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD; 1535 1536 if (vif->type != NL80211_IFTYPE_STATION) 1537 return; 1538 1539 if (vif->p2p && 1540 !(iwlwifi_mod_params.uapsd_disable & IWL_DISABLE_UAPSD_P2P_CLIENT)) 1541 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD; 1542 1543 if (!vif->p2p && 1544 !(iwlwifi_mod_params.uapsd_disable & IWL_DISABLE_UAPSD_BSS)) 1545 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD; 1546} 1547 1548int iwl_mld_tdls_sta_count(struct iwl_mld *mld) 1549{ 1550 int count = 0; 1551 1552 lockdep_assert_wiphy(mld->wiphy); 1553 1554 for (int i = 0; i < mld->fw->ucode_capa.num_stations; i++) { 1555 struct ieee80211_link_sta *link_sta; 1556 1557 link_sta = wiphy_dereference(mld->wiphy, 1558 mld->fw_id_to_link_sta[i]); 1559 if (IS_ERR_OR_NULL(link_sta)) 1560 continue; 1561 1562 if (!link_sta->sta->tdls) 1563 continue; 1564 1565 count++; 1566 } 1567 1568 return count; 1569} 1570 1571static void iwl_mld_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy, 1572 struct cfg80211_bss *bss, 1573 void *_data) 1574{ 1575 bool *tolerated = _data; 1576 const struct cfg80211_bss_ies *ies; 1577 const struct element *elem; 1578 1579 rcu_read_lock(); 1580 ies = rcu_dereference(bss->ies); 1581 elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, ies->data, 1582 ies->len); 1583 1584 if (!elem || elem->datalen < 10 || 1585 !(elem->data[10] & 1586 WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) { 1587 *tolerated = false; 1588 } 1589 rcu_read_unlock(); 1590} 1591 1592static void 1593iwl_mld_check_he_obss_narrow_bw_ru(struct iwl_mld *mld, 1594 struct iwl_mld_link *mld_link, 1595 struct ieee80211_bss_conf *link_conf) 1596{ 1597 bool tolerated = true; 1598 1599 if (WARN_ON_ONCE(!link_conf->chanreq.oper.chan)) 1600 return; 1601 1602 if (!(link_conf->chanreq.oper.chan->flags & IEEE80211_CHAN_RADAR)) { 1603 mld_link->he_ru_2mhz_block = false; 1604 return; 1605 } 1606 1607 cfg80211_bss_iter(mld->wiphy, &link_conf->chanreq.oper, 1608 iwl_mld_check_he_obss_narrow_bw_ru_iter, &tolerated); 1609 1610 /* If there is at least one AP on radar channel that cannot 1611 * tolerate 26-tone RU UL OFDMA transmissions using HE TB PPDU. 1612 */ 1613 mld_link->he_ru_2mhz_block = !tolerated; 1614} 1615 1616static void iwl_mld_link_set_2mhz_block(struct iwl_mld *mld, 1617 struct ieee80211_vif *vif, 1618 struct ieee80211_sta *sta) 1619{ 1620 struct ieee80211_link_sta *link_sta; 1621 unsigned int link_id; 1622 1623 for_each_sta_active_link(vif, sta, link_sta, link_id) { 1624 struct ieee80211_bss_conf *link_conf = 1625 link_conf_dereference_protected(vif, link_id); 1626 struct iwl_mld_link *mld_link = 1627 iwl_mld_link_from_mac80211(link_conf); 1628 1629 if (WARN_ON(!link_conf || !mld_link)) 1630 continue; 1631 1632 if (link_sta->he_cap.has_he) 1633 iwl_mld_check_he_obss_narrow_bw_ru(mld, mld_link, 1634 link_conf); 1635 } 1636} 1637 1638static int iwl_mld_move_sta_state_up(struct iwl_mld *mld, 1639 struct ieee80211_vif *vif, 1640 struct ieee80211_sta *sta, 1641 enum ieee80211_sta_state old_state, 1642 enum ieee80211_sta_state new_state) 1643{ 1644 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 1645 int tdls_count = 0; 1646 int ret; 1647 1648 if (old_state == IEEE80211_STA_NOTEXIST && 1649 new_state == IEEE80211_STA_NONE) { 1650 if (sta->tdls) { 1651 if (vif->p2p || hweight8(mld->used_phy_ids) != 1) 1652 return -EBUSY; 1653 1654 tdls_count = iwl_mld_tdls_sta_count(mld); 1655 if (tdls_count >= IWL_TDLS_STA_COUNT) 1656 return -EBUSY; 1657 } 1658 1659 ret = iwl_mld_add_sta(mld, sta, vif, STATION_TYPE_PEER); 1660 if (ret) 1661 return ret; 1662 1663 /* just added first TDLS STA, so disable PM */ 1664 if (sta->tdls && tdls_count == 0) 1665 iwl_mld_update_mac_power(mld, vif, false); 1666 1667 if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) 1668 mld_vif->ap_sta = sta; 1669 1670 /* Initialize TLC here already - this really tells 1671 * the firmware only what the supported legacy rates are 1672 * (may be) since it's initialized already from what the 1673 * AP advertised in the beacon/probe response. This will 1674 * allow the firmware to send auth/assoc frames with one 1675 * of the supported rates already, rather than having to 1676 * use a mandatory rate. 1677 * If we're the AP, we'll just assume mandatory rates at 1678 * this point, but we know nothing about the STA anyway. 1679 */ 1680 iwl_mld_config_tlc(mld, vif, sta); 1681 1682 return ret; 1683 } else if (old_state == IEEE80211_STA_NONE && 1684 new_state == IEEE80211_STA_AUTH) { 1685 iwl_mld_set_uapsd(mld, vif); 1686 return 0; 1687 } else if (old_state == IEEE80211_STA_AUTH && 1688 new_state == IEEE80211_STA_ASSOC) { 1689 ret = iwl_mld_update_all_link_stations(mld, sta); 1690 1691 if (vif->type == NL80211_IFTYPE_STATION) 1692 iwl_mld_link_set_2mhz_block(mld, vif, sta); 1693 1694 if (sta->tdls) { 1695 /* 1696 * update MAC since wifi generation flags may change, 1697 * we also update MAC on association to the AP via the 1698 * vif assoc change 1699 */ 1700 iwl_mld_mac_fw_action(mld, vif, FW_CTXT_ACTION_MODIFY); 1701 } 1702 1703 /* Now the link_sta's capabilities are set, update the FW */ 1704 iwl_mld_config_tlc(mld, vif, sta); 1705 1706 if (vif->type == NL80211_IFTYPE_AP) { 1707 /* Update MAC_CFG_FILTER_ACCEPT_BEACON if at least 1708 * one sta is associated 1709 */ 1710 if (++mld_vif->num_associated_stas == 1) 1711 ret = iwl_mld_mac_fw_action(mld, vif, 1712 FW_CTXT_ACTION_MODIFY); 1713 } 1714 1715 return ret; 1716 } else if (old_state == IEEE80211_STA_ASSOC && 1717 new_state == IEEE80211_STA_AUTHORIZED) { 1718 ret = 0; 1719 1720 if (!sta->tdls) { 1721 mld_vif->authorized = true; 1722 1723 /* Ensure any block due to a non-BSS link is synced */ 1724 iwl_mld_emlsr_check_non_bss_block(mld, 0); 1725 1726 /* Block EMLSR until a certain throughput it reached */ 1727 if (!mld->fw_status.in_hw_restart && 1728 IWL_MLD_ENTER_EMLSR_TPT_THRESH > 0) 1729 iwl_mld_block_emlsr(mld_vif->mld, vif, 1730 IWL_MLD_EMLSR_BLOCKED_TPT, 1731 0); 1732 1733 /* clear COEX_HIGH_PRIORITY_ENABLE */ 1734 ret = iwl_mld_mac_fw_action(mld, vif, 1735 FW_CTXT_ACTION_MODIFY); 1736 if (ret) 1737 return ret; 1738 iwl_mld_smps_workaround(mld, vif, vif->cfg.ps); 1739 } 1740 1741 /* MFP is set by default before the station is authorized. 1742 * Clear it here in case it's not used. 1743 */ 1744 if (!sta->mfp) 1745 ret = iwl_mld_update_all_link_stations(mld, sta); 1746 1747 /* We can use wide bandwidth now, not only 20 MHz */ 1748 iwl_mld_config_tlc(mld, vif, sta); 1749 1750 return ret; 1751 } else { 1752 return -EINVAL; 1753 } 1754} 1755 1756static int iwl_mld_move_sta_state_down(struct iwl_mld *mld, 1757 struct ieee80211_vif *vif, 1758 struct ieee80211_sta *sta, 1759 enum ieee80211_sta_state old_state, 1760 enum ieee80211_sta_state new_state) 1761{ 1762 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 1763 1764 if (old_state == IEEE80211_STA_AUTHORIZED && 1765 new_state == IEEE80211_STA_ASSOC) { 1766 if (!sta->tdls) { 1767 mld_vif->authorized = false; 1768 1769 memset(&mld_vif->emlsr.zeroed_on_not_authorized, 0, 1770 sizeof(mld_vif->emlsr.zeroed_on_not_authorized)); 1771 1772 wiphy_delayed_work_cancel(mld->wiphy, 1773 &mld_vif->emlsr.prevent_done_wk); 1774 wiphy_delayed_work_cancel(mld->wiphy, 1775 &mld_vif->emlsr.tmp_non_bss_done_wk); 1776 wiphy_work_cancel(mld->wiphy, &mld_vif->emlsr.unblock_tpt_wk); 1777 wiphy_delayed_work_cancel(mld->wiphy, 1778 &mld_vif->emlsr.check_tpt_wk); 1779 wiphy_delayed_work_cancel(mld->wiphy, 1780 &mld_vif->mlo_scan_start_wk); 1781 1782 iwl_mld_reset_cca_40mhz_workaround(mld, vif); 1783 iwl_mld_smps_workaround(mld, vif, true); 1784 } 1785 1786 /* once we move into assoc state, need to update the FW to 1787 * stop using wide bandwidth 1788 */ 1789 iwl_mld_config_tlc(mld, vif, sta); 1790 } else if (old_state == IEEE80211_STA_ASSOC && 1791 new_state == IEEE80211_STA_AUTH) { 1792 if (vif->type == NL80211_IFTYPE_AP && 1793 !WARN_ON(!mld_vif->num_associated_stas)) { 1794 /* Update MAC_CFG_FILTER_ACCEPT_BEACON if the last sta 1795 * is disassociating 1796 */ 1797 if (--mld_vif->num_associated_stas == 0) 1798 iwl_mld_mac_fw_action(mld, vif, 1799 FW_CTXT_ACTION_MODIFY); 1800 } 1801 } else if (old_state == IEEE80211_STA_AUTH && 1802 new_state == IEEE80211_STA_NONE) { 1803 /* nothing */ 1804 } else if (old_state == IEEE80211_STA_NONE && 1805 new_state == IEEE80211_STA_NOTEXIST) { 1806 iwl_mld_remove_sta(mld, sta); 1807 1808 if (sta->tdls && iwl_mld_tdls_sta_count(mld) == 0) { 1809 /* just removed last TDLS STA, so enable PM */ 1810 iwl_mld_update_mac_power(mld, vif, false); 1811 } 1812 1813 if (sta->tdls) { 1814 /* 1815 * update MAC since wifi generation flags may change, 1816 * we also update MAC on disassociation to the AP via 1817 * the vif assoc change 1818 */ 1819 iwl_mld_mac_fw_action(mld, vif, FW_CTXT_ACTION_MODIFY); 1820 } 1821 } else { 1822 return -EINVAL; 1823 } 1824 return 0; 1825} 1826 1827static int iwl_mld_mac80211_sta_state(struct ieee80211_hw *hw, 1828 struct ieee80211_vif *vif, 1829 struct ieee80211_sta *sta, 1830 enum ieee80211_sta_state old_state, 1831 enum ieee80211_sta_state new_state) 1832{ 1833 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1834 struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta); 1835 1836 IWL_DEBUG_MAC80211(mld, "station %pM state change %d->%d\n", 1837 sta->addr, old_state, new_state); 1838 1839 mld_sta->sta_state = new_state; 1840 1841 if (old_state < new_state) 1842 return iwl_mld_move_sta_state_up(mld, vif, sta, old_state, 1843 new_state); 1844 else 1845 return iwl_mld_move_sta_state_down(mld, vif, sta, old_state, 1846 new_state); 1847} 1848 1849static void iwl_mld_mac80211_flush(struct ieee80211_hw *hw, 1850 struct ieee80211_vif *vif, 1851 u32 queues, bool drop) 1852{ 1853 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1854 1855 /* Make sure we're done with the deferred traffic before flushing */ 1856 iwl_mld_add_txq_list(mld); 1857 1858 for (int i = 0; i < mld->fw->ucode_capa.num_stations; i++) { 1859 struct ieee80211_link_sta *link_sta = 1860 wiphy_dereference(mld->wiphy, 1861 mld->fw_id_to_link_sta[i]); 1862 1863 if (IS_ERR_OR_NULL(link_sta)) 1864 continue; 1865 1866 /* Check that the sta belongs to the given vif */ 1867 if (vif && vif != iwl_mld_sta_from_mac80211(link_sta->sta)->vif) 1868 continue; 1869 1870 if (drop) 1871 iwl_mld_flush_sta_txqs(mld, link_sta->sta); 1872 else 1873 iwl_mld_wait_sta_txqs_empty(mld, link_sta->sta); 1874 } 1875} 1876 1877static void iwl_mld_mac80211_flush_sta(struct ieee80211_hw *hw, 1878 struct ieee80211_vif *vif, 1879 struct ieee80211_sta *sta) 1880{ 1881 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1882 1883 iwl_mld_flush_sta_txqs(mld, sta); 1884} 1885 1886static int 1887iwl_mld_mac80211_ampdu_action(struct ieee80211_hw *hw, 1888 struct ieee80211_vif *vif, 1889 struct ieee80211_ampdu_params *params) 1890{ 1891 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1892 struct ieee80211_sta *sta = params->sta; 1893 enum ieee80211_ampdu_mlme_action action = params->action; 1894 u16 tid = params->tid; 1895 u16 ssn = params->ssn; 1896 u16 buf_size = params->buf_size; 1897 u16 timeout = params->timeout; 1898 int ret; 1899 1900 IWL_DEBUG_HT(mld, "A-MPDU action on addr %pM tid: %d action: %d\n", 1901 sta->addr, tid, action); 1902 1903 switch (action) { 1904 case IEEE80211_AMPDU_RX_START: 1905 if (!iwl_enable_rx_ampdu()) { 1906 ret = -EINVAL; 1907 break; 1908 } 1909 ret = iwl_mld_ampdu_rx_start(mld, sta, tid, ssn, buf_size, 1910 timeout); 1911 break; 1912 case IEEE80211_AMPDU_RX_STOP: 1913 ret = iwl_mld_ampdu_rx_stop(mld, sta, tid); 1914 break; 1915 default: 1916 /* The mac80211 TX_AMPDU_SETUP_IN_HW flag is set for all 1917 * devices, since all support TX A-MPDU offload in hardware. 1918 * Therefore, no TX action should be requested here. 1919 */ 1920 WARN_ON_ONCE(1); 1921 return -EINVAL; 1922 } 1923 1924 return ret; 1925} 1926 1927static bool iwl_mld_can_hw_csum(struct sk_buff *skb) 1928{ 1929 u8 protocol = ip_hdr(skb)->protocol; 1930 1931 return protocol == IPPROTO_TCP || protocol == IPPROTO_UDP; 1932} 1933 1934static bool iwl_mld_mac80211_can_aggregate(struct ieee80211_hw *hw, 1935 struct sk_buff *head, 1936 struct sk_buff *skb) 1937{ 1938 if (!IS_ENABLED(CONFIG_INET)) 1939 return false; 1940 1941 /* For now don't aggregate IPv6 in AMSDU */ 1942 if (skb->protocol != htons(ETH_P_IP)) 1943 return false; 1944 1945 /* Allow aggregation only if both frames have the same HW csum offload 1946 * capability, ensuring consistent HW or SW csum handling in A-MSDU. 1947 */ 1948 return iwl_mld_can_hw_csum(skb) == iwl_mld_can_hw_csum(head); 1949} 1950 1951static void iwl_mld_mac80211_sync_rx_queues(struct ieee80211_hw *hw) 1952{ 1953 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1954 1955 iwl_mld_sync_rx_queues(mld, IWL_MLD_RXQ_EMPTY, NULL, 0); 1956} 1957 1958static void iwl_mld_sta_rc_update(struct ieee80211_hw *hw, 1959 struct ieee80211_vif *vif, 1960 struct ieee80211_link_sta *link_sta, 1961 u32 changed) 1962{ 1963 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1964 1965 if (changed & (IEEE80211_RC_BW_CHANGED | 1966 IEEE80211_RC_SUPP_RATES_CHANGED | 1967 IEEE80211_RC_NSS_CHANGED)) { 1968 struct ieee80211_bss_conf *link = 1969 link_conf_dereference_check(vif, link_sta->link_id); 1970 1971 if (WARN_ON(!link)) 1972 return; 1973 1974 iwl_mld_config_tlc_link(mld, vif, link, link_sta); 1975 } 1976} 1977 1978#ifdef CONFIG_PM_SLEEP 1979static void iwl_mld_set_wakeup(struct ieee80211_hw *hw, bool enabled) 1980{ 1981 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1982 1983 device_set_wakeup_enable(mld->trans->dev, enabled); 1984} 1985 1986/* Returns 0 on success. 1 if failed to suspend with wowlan: 1987 * If the circumstances didn't satisfy the conditions for suspension 1988 * with wowlan, mac80211 would use the no_wowlan flow. 1989 * If an error had occurred we update the trans status and state here 1990 * and the result will be stopping the FW. 1991 */ 1992static int 1993iwl_mld_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) 1994{ 1995 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1996 int ret; 1997 1998 iwl_fw_runtime_suspend(&mld->fwrt); 1999 2000 ret = iwl_mld_wowlan_suspend(mld, wowlan); 2001 if (ret) 2002 return 1; 2003 2004 if (iwl_mld_no_wowlan_suspend(mld)) 2005 return 1; 2006 2007 return 0; 2008} 2009 2010static int iwl_mld_resume(struct ieee80211_hw *hw) 2011{ 2012 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2013 int ret; 2014 2015 ret = iwl_mld_wowlan_resume(mld); 2016 if (ret) 2017 return ret; 2018 2019 iwl_fw_runtime_resume(&mld->fwrt); 2020 2021 iwl_mld_low_latency_restart(mld); 2022 2023 return 0; 2024} 2025#endif 2026 2027static int iwl_mld_alloc_ptk_pn(struct iwl_mld *mld, 2028 struct iwl_mld_sta *mld_sta, 2029 struct ieee80211_key_conf *key, 2030 struct iwl_mld_ptk_pn **ptk_pn) 2031{ 2032 u8 num_rx_queues = mld->trans->info.num_rxqs; 2033 int keyidx = key->keyidx; 2034 struct ieee80211_key_seq seq; 2035 2036 if (WARN_ON(keyidx >= ARRAY_SIZE(mld_sta->ptk_pn))) 2037 return -EINVAL; 2038 2039 WARN_ON(rcu_access_pointer(mld_sta->ptk_pn[keyidx])); 2040 *ptk_pn = kzalloc(struct_size(*ptk_pn, q, num_rx_queues), 2041 GFP_KERNEL); 2042 if (!*ptk_pn) 2043 return -ENOMEM; 2044 2045 for (u8 tid = 0; tid < IWL_MAX_TID_COUNT; tid++) { 2046 ieee80211_get_key_rx_seq(key, tid, &seq); 2047 for (u8 q = 0; q < num_rx_queues; q++) 2048 memcpy((*ptk_pn)->q[q].pn[tid], seq.ccmp.pn, 2049 IEEE80211_CCMP_PN_LEN); 2050 } 2051 2052 rcu_assign_pointer(mld_sta->ptk_pn[keyidx], *ptk_pn); 2053 2054 return 0; 2055} 2056 2057static int iwl_mld_set_key_add(struct iwl_mld *mld, 2058 struct ieee80211_vif *vif, 2059 struct ieee80211_sta *sta, 2060 struct ieee80211_key_conf *key) 2061{ 2062 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 2063 struct iwl_mld_sta *mld_sta = 2064 sta ? iwl_mld_sta_from_mac80211(sta) : NULL; 2065 struct iwl_mld_ptk_pn *ptk_pn = NULL; 2066 int keyidx = key->keyidx; 2067 int ret; 2068 2069 /* Will be set to 0 if added successfully */ 2070 key->hw_key_idx = STA_KEY_IDX_INVALID; 2071 2072 switch (key->cipher) { 2073 case WLAN_CIPHER_SUITE_WEP40: 2074 case WLAN_CIPHER_SUITE_WEP104: 2075 IWL_DEBUG_MAC80211(mld, "Use SW encryption for WEP\n"); 2076 return -EOPNOTSUPP; 2077 case WLAN_CIPHER_SUITE_TKIP: 2078 if (vif->type == NL80211_IFTYPE_STATION) { 2079 key->flags |= IEEE80211_KEY_FLAG_PUT_MIC_SPACE; 2080 break; 2081 } 2082 IWL_DEBUG_MAC80211(mld, "Use SW encryption for TKIP\n"); 2083 return -EOPNOTSUPP; 2084 case WLAN_CIPHER_SUITE_CCMP: 2085 case WLAN_CIPHER_SUITE_GCMP: 2086 case WLAN_CIPHER_SUITE_GCMP_256: 2087 case WLAN_CIPHER_SUITE_AES_CMAC: 2088 case WLAN_CIPHER_SUITE_BIP_GMAC_128: 2089 case WLAN_CIPHER_SUITE_BIP_GMAC_256: 2090 break; 2091 default: 2092 return -EOPNOTSUPP; 2093 } 2094 2095 if (keyidx == 6 || keyidx == 7) 2096 iwl_mld_track_bigtk(mld, vif, key, true); 2097 2098 /* After exiting from RFKILL, hostapd configures GTK/ITGK before the 2099 * AP is started, but those keys can't be sent to the FW before the 2100 * MCAST/BCAST STAs are added to it (which happens upon AP start). 2101 * Store it here to be sent later when the AP is started. 2102 */ 2103 if ((vif->type == NL80211_IFTYPE_ADHOC || 2104 vif->type == NL80211_IFTYPE_AP) && !sta && 2105 !mld_vif->ap_ibss_active) 2106 return iwl_mld_store_ap_early_key(mld, key, mld_vif); 2107 2108 if (!mld->fw_status.in_hw_restart && mld_sta && 2109 key->flags & IEEE80211_KEY_FLAG_PAIRWISE && 2110 (key->cipher == WLAN_CIPHER_SUITE_CCMP || 2111 key->cipher == WLAN_CIPHER_SUITE_GCMP || 2112 key->cipher == WLAN_CIPHER_SUITE_GCMP_256)) { 2113 ret = iwl_mld_alloc_ptk_pn(mld, mld_sta, key, &ptk_pn); 2114 if (ret) 2115 return ret; 2116 } 2117 2118 IWL_DEBUG_MAC80211(mld, "set hwcrypto key (sta:%pM, id:%d)\n", 2119 sta ? sta->addr : NULL, keyidx); 2120 2121 ret = iwl_mld_add_key(mld, vif, sta, key); 2122 if (ret) { 2123 IWL_WARN(mld, "set key failed (%d)\n", ret); 2124 if (ptk_pn) { 2125 RCU_INIT_POINTER(mld_sta->ptk_pn[keyidx], NULL); 2126 kfree(ptk_pn); 2127 } 2128 2129 return -EOPNOTSUPP; 2130 } 2131 2132 return 0; 2133} 2134 2135static void iwl_mld_set_key_remove(struct iwl_mld *mld, 2136 struct ieee80211_vif *vif, 2137 struct ieee80211_sta *sta, 2138 struct ieee80211_key_conf *key) 2139{ 2140 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 2141 struct iwl_mld_sta *mld_sta = 2142 sta ? iwl_mld_sta_from_mac80211(sta) : NULL; 2143 int keyidx = key->keyidx; 2144 2145 if (keyidx == 6 || keyidx == 7) 2146 iwl_mld_track_bigtk(mld, vif, key, false); 2147 2148 if (mld_sta && key->flags & IEEE80211_KEY_FLAG_PAIRWISE && 2149 (key->cipher == WLAN_CIPHER_SUITE_CCMP || 2150 key->cipher == WLAN_CIPHER_SUITE_GCMP || 2151 key->cipher == WLAN_CIPHER_SUITE_GCMP_256)) { 2152 struct iwl_mld_ptk_pn *ptk_pn; 2153 2154 if (WARN_ON(keyidx >= ARRAY_SIZE(mld_sta->ptk_pn))) 2155 return; 2156 2157 ptk_pn = wiphy_dereference(mld->wiphy, 2158 mld_sta->ptk_pn[keyidx]); 2159 RCU_INIT_POINTER(mld_sta->ptk_pn[keyidx], NULL); 2160 if (!WARN_ON(!ptk_pn)) 2161 kfree_rcu(ptk_pn, rcu_head); 2162 } 2163 2164 /* if this key was stored to be added later to the FW - free it here */ 2165 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) 2166 iwl_mld_free_ap_early_key(mld, key, mld_vif); 2167 2168 /* We already removed it */ 2169 if (key->hw_key_idx == STA_KEY_IDX_INVALID) 2170 return; 2171 2172 IWL_DEBUG_MAC80211(mld, "disable hwcrypto key\n"); 2173 2174 iwl_mld_remove_key(mld, vif, sta, key); 2175} 2176 2177static int iwl_mld_mac80211_set_key(struct ieee80211_hw *hw, 2178 enum set_key_cmd cmd, 2179 struct ieee80211_vif *vif, 2180 struct ieee80211_sta *sta, 2181 struct ieee80211_key_conf *key) 2182{ 2183 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2184 int ret; 2185 2186 switch (cmd) { 2187 case SET_KEY: 2188 ret = iwl_mld_set_key_add(mld, vif, sta, key); 2189 if (ret) 2190 ret = -EOPNOTSUPP; 2191 break; 2192 case DISABLE_KEY: 2193 iwl_mld_set_key_remove(mld, vif, sta, key); 2194 ret = 0; 2195 break; 2196 default: 2197 ret = -EINVAL; 2198 break; 2199 } 2200 2201 return ret; 2202} 2203 2204static int 2205iwl_mld_pre_channel_switch(struct ieee80211_hw *hw, 2206 struct ieee80211_vif *vif, 2207 struct ieee80211_channel_switch *chsw) 2208{ 2209 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2210 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 2211 struct iwl_mld_link *mld_link = 2212 iwl_mld_link_dereference_check(mld_vif, chsw->link_id); 2213 u8 primary; 2214 int selected; 2215 2216 lockdep_assert_wiphy(mld->wiphy); 2217 2218 if (WARN_ON(!mld_link)) 2219 return -EINVAL; 2220 2221 IWL_DEBUG_MAC80211(mld, "pre CSA to freq %d\n", 2222 chsw->chandef.center_freq1); 2223 2224 if (!iwl_mld_emlsr_active(vif)) 2225 return 0; 2226 2227 primary = iwl_mld_get_primary_link(vif); 2228 2229 /* stay on the primary link unless it is undergoing a CSA with quiet */ 2230 if (chsw->link_id == primary && chsw->block_tx) 2231 selected = iwl_mld_get_other_link(vif, primary); 2232 else 2233 selected = primary; 2234 2235 /* Remember to tell the firmware that this link can't tx 2236 * Note that this logic seems to be unrelated to emlsr, but it 2237 * really is needed only when emlsr is active. When we have a 2238 * single link, the firmware will handle all this on its own. 2239 * In multi-link scenarios, we can learn about the CSA from 2240 * another link and this logic is too complex for the firmware 2241 * to track. 2242 * Since we want to de-activate the link that got a CSA with mode=1, 2243 * we need to tell the firmware not to send any frame on that link 2244 * as the firmware may not be aware that link is under a CSA 2245 * with mode=1 (no Tx allowed). 2246 */ 2247 mld_link->silent_deactivation = chsw->block_tx; 2248 iwl_mld_exit_emlsr(mld, vif, IWL_MLD_EMLSR_EXIT_CSA, selected); 2249 2250 return 0; 2251} 2252 2253static void 2254iwl_mld_channel_switch(struct ieee80211_hw *hw, 2255 struct ieee80211_vif *vif, 2256 struct ieee80211_channel_switch *chsw) 2257{ 2258 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2259 2260 /* By implementing this operation, we prevent mac80211 from 2261 * starting its own channel switch timer, so that we can call 2262 * ieee80211_chswitch_done() ourselves at the right time 2263 * (Upon receiving the channel_switch_start notification from the fw) 2264 */ 2265 IWL_DEBUG_MAC80211(mld, 2266 "dummy channel switch op\n"); 2267} 2268 2269static int 2270iwl_mld_post_channel_switch(struct ieee80211_hw *hw, 2271 struct ieee80211_vif *vif, 2272 struct ieee80211_bss_conf *link_conf) 2273{ 2274 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2275 struct iwl_mld_link *mld_link = iwl_mld_link_from_mac80211(link_conf); 2276 2277 lockdep_assert_wiphy(mld->wiphy); 2278 2279 WARN_ON(mld_link->silent_deactivation); 2280 2281 return 0; 2282} 2283 2284static void 2285iwl_mld_abort_channel_switch(struct ieee80211_hw *hw, 2286 struct ieee80211_vif *vif, 2287 struct ieee80211_bss_conf *link_conf) 2288{ 2289 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2290 struct iwl_mld_link *mld_link = iwl_mld_link_from_mac80211(link_conf); 2291 2292 IWL_DEBUG_MAC80211(mld, 2293 "abort channel switch op\n"); 2294 mld_link->silent_deactivation = false; 2295} 2296 2297static int 2298iwl_mld_switch_vif_chanctx_swap(struct ieee80211_hw *hw, 2299 struct ieee80211_vif_chanctx_switch *vifs) 2300{ 2301 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2302 int ret; 2303 2304 iwl_mld_unassign_vif_chanctx(hw, vifs[0].vif, vifs[0].link_conf, 2305 vifs[0].old_ctx); 2306 iwl_mld_remove_chanctx(hw, vifs[0].old_ctx); 2307 2308 ret = iwl_mld_add_chanctx(hw, vifs[0].new_ctx); 2309 if (ret) { 2310 IWL_ERR(mld, "failed to add new_ctx during channel switch\n"); 2311 goto out_reassign; 2312 } 2313 2314 ret = iwl_mld_assign_vif_chanctx(hw, vifs[0].vif, vifs[0].link_conf, 2315 vifs[0].new_ctx); 2316 if (ret) { 2317 IWL_ERR(mld, 2318 "failed to assign new_ctx during channel switch\n"); 2319 goto out_remove; 2320 } 2321 2322 return 0; 2323 2324 out_remove: 2325 iwl_mld_remove_chanctx(hw, vifs[0].new_ctx); 2326 out_reassign: 2327 if (iwl_mld_add_chanctx(hw, vifs[0].old_ctx)) { 2328 IWL_ERR(mld, "failed to add old_ctx after failure\n"); 2329 return ret; 2330 } 2331 2332 if (iwl_mld_assign_vif_chanctx(hw, vifs[0].vif, vifs[0].link_conf, 2333 vifs[0].old_ctx)) 2334 IWL_ERR(mld, "failed to reassign old_ctx after failure\n"); 2335 2336 return ret; 2337} 2338 2339static int 2340iwl_mld_switch_vif_chanctx_reassign(struct ieee80211_hw *hw, 2341 struct ieee80211_vif_chanctx_switch *vifs) 2342{ 2343 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2344 int ret; 2345 2346 iwl_mld_unassign_vif_chanctx(hw, vifs[0].vif, vifs[0].link_conf, 2347 vifs[0].old_ctx); 2348 ret = iwl_mld_assign_vif_chanctx(hw, vifs[0].vif, vifs[0].link_conf, 2349 vifs[0].new_ctx); 2350 if (ret) { 2351 IWL_ERR(mld, 2352 "failed to assign new_ctx during channel switch\n"); 2353 goto out_reassign; 2354 } 2355 2356 return 0; 2357 2358out_reassign: 2359 if (iwl_mld_assign_vif_chanctx(hw, vifs[0].vif, vifs[0].link_conf, 2360 vifs[0].old_ctx)) 2361 IWL_ERR(mld, "failed to reassign old_ctx after failure\n"); 2362 2363 return ret; 2364} 2365 2366static int 2367iwl_mld_switch_vif_chanctx(struct ieee80211_hw *hw, 2368 struct ieee80211_vif_chanctx_switch *vifs, 2369 int n_vifs, 2370 enum ieee80211_chanctx_switch_mode mode) 2371{ 2372 int ret; 2373 2374 /* we only support a single-vif right now */ 2375 if (n_vifs > 1) 2376 return -EOPNOTSUPP; 2377 2378 switch (mode) { 2379 case CHANCTX_SWMODE_SWAP_CONTEXTS: 2380 ret = iwl_mld_switch_vif_chanctx_swap(hw, vifs); 2381 break; 2382 case CHANCTX_SWMODE_REASSIGN_VIF: 2383 ret = iwl_mld_switch_vif_chanctx_reassign(hw, vifs); 2384 break; 2385 default: 2386 ret = -EOPNOTSUPP; 2387 break; 2388 } 2389 2390 return ret; 2391} 2392 2393static void iwl_mld_sta_pre_rcu_remove(struct ieee80211_hw *hw, 2394 struct ieee80211_vif *vif, 2395 struct ieee80211_sta *sta) 2396{ 2397 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2398 struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta); 2399 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 2400 struct iwl_mld_link_sta *mld_link_sta; 2401 u8 link_id; 2402 2403 lockdep_assert_wiphy(mld->wiphy); 2404 2405 /* This is called before mac80211 does RCU synchronisation, 2406 * so here we already invalidate our internal RCU-protected 2407 * station pointer. The rest of the code will thus no longer 2408 * be able to find the station this way, and we don't rely 2409 * on further RCU synchronisation after the sta_state() 2410 * callback deleted the station. 2411 */ 2412 for_each_mld_link_sta(mld_sta, mld_link_sta, link_id) 2413 RCU_INIT_POINTER(mld->fw_id_to_link_sta[mld_link_sta->fw_id], 2414 NULL); 2415 2416 if (sta == mld_vif->ap_sta) 2417 mld_vif->ap_sta = NULL; 2418} 2419 2420static void 2421iwl_mld_mac80211_mgd_protect_tdls_discover(struct ieee80211_hw *hw, 2422 struct ieee80211_vif *vif, 2423 unsigned int link_id) 2424{ 2425 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2426 struct ieee80211_bss_conf *link_conf; 2427 u32 duration; 2428 int ret; 2429 2430 link_conf = wiphy_dereference(hw->wiphy, vif->link_conf[link_id]); 2431 if (WARN_ON_ONCE(!link_conf)) 2432 return; 2433 2434 /* Protect the session to hear the TDLS setup response on the channel */ 2435 2436 duration = 2 * link_conf->dtim_period * link_conf->beacon_int; 2437 2438 ret = iwl_mld_start_session_protection(mld, vif, duration, duration, 2439 link_id, HZ / 5); 2440 if (ret) 2441 IWL_ERR(mld, 2442 "Failed to start session protection for TDLS: %d\n", 2443 ret); 2444} 2445 2446static bool iwl_mld_can_activate_links(struct ieee80211_hw *hw, 2447 struct ieee80211_vif *vif, 2448 u16 desired_links) 2449{ 2450 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2451 int n_links = hweight16(desired_links); 2452 2453 /* Check if HW supports the wanted number of links */ 2454 return n_links <= iwl_mld_max_active_links(mld, vif); 2455} 2456 2457static int 2458iwl_mld_change_vif_links(struct ieee80211_hw *hw, 2459 struct ieee80211_vif *vif, 2460 u16 old_links, u16 new_links, 2461 struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]) 2462{ 2463 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 2464 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2465 struct ieee80211_bss_conf *link_conf; 2466 u16 removed = old_links & ~new_links; 2467 u16 added = new_links & ~old_links; 2468 int err; 2469 2470 lockdep_assert_wiphy(mld->wiphy); 2471 2472 /* 2473 * No bits designate non-MLO mode. We can handle MLO exit/enter by 2474 * simply mapping that to link ID zero internally. 2475 * Note that mac80211 does such a non-MLO to MLO switch during restart 2476 * if it was in MLO before. In that case, we do not have a link to 2477 * remove. 2478 */ 2479 if (old_links == 0 && !mld->fw_status.in_hw_restart) 2480 removed |= BIT(0); 2481 2482 if (new_links == 0) 2483 added |= BIT(0); 2484 2485 for (int i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { 2486 if (removed & BIT(i) && !WARN_ON(!old[i])) 2487 iwl_mld_remove_link(mld, old[i]); 2488 } 2489 2490 for (int i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { 2491 if (added & BIT(i)) { 2492 link_conf = link_conf_dereference_protected(vif, i); 2493 if (!link_conf) { 2494 err = -EINVAL; 2495 goto remove_added_links; 2496 } 2497 2498 err = iwl_mld_add_link(mld, link_conf); 2499 if (err) 2500 goto remove_added_links; 2501 } 2502 } 2503 2504 /* 2505 * Ensure we always have a valid primary_link. When using multiple 2506 * links the proper value is set in assign_vif_chanctx. 2507 */ 2508 mld_vif->emlsr.primary = new_links ? __ffs(new_links) : 0; 2509 2510 /* 2511 * Special MLO restart case. We did not have a link when the interface 2512 * was added, so do the power configuration now. 2513 */ 2514 if (old_links == 0 && mld->fw_status.in_hw_restart) 2515 iwl_mld_update_mac_power(mld, vif, false); 2516 2517 return 0; 2518 2519remove_added_links: 2520 for (int i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { 2521 if (!(added & BIT(i))) 2522 continue; 2523 2524 link_conf = link_conf_dereference_protected(vif, i); 2525 if (!link_conf || !iwl_mld_link_from_mac80211(link_conf)) 2526 continue; 2527 2528 iwl_mld_remove_link(mld, link_conf); 2529 } 2530 2531 if (WARN_ON(!iwl_mld_error_before_recovery(mld))) 2532 return err; 2533 2534 /* reconfig will fix us anyway */ 2535 return 0; 2536} 2537 2538static int iwl_mld_change_sta_links(struct ieee80211_hw *hw, 2539 struct ieee80211_vif *vif, 2540 struct ieee80211_sta *sta, 2541 u16 old_links, u16 new_links) 2542{ 2543 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2544 2545 return iwl_mld_update_link_stas(mld, vif, sta, old_links, new_links); 2546} 2547 2548static int iwl_mld_mac80211_join_ibss(struct ieee80211_hw *hw, 2549 struct ieee80211_vif *vif) 2550{ 2551 return iwl_mld_start_ap_ibss(hw, vif, &vif->bss_conf); 2552} 2553 2554static void iwl_mld_mac80211_leave_ibss(struct ieee80211_hw *hw, 2555 struct ieee80211_vif *vif) 2556{ 2557 return iwl_mld_stop_ap_ibss(hw, vif, &vif->bss_conf); 2558} 2559 2560static int iwl_mld_mac80211_tx_last_beacon(struct ieee80211_hw *hw) 2561{ 2562 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2563 2564 return mld->ibss_manager; 2565} 2566 2567static void iwl_mld_prep_add_interface(struct ieee80211_hw *hw, 2568 enum nl80211_iftype type) 2569{ 2570 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2571 2572 IWL_DEBUG_MAC80211(mld, "prep_add_interface: type=%u\n", type); 2573 2574 if (!(type == NL80211_IFTYPE_AP || 2575 type == NL80211_IFTYPE_P2P_GO || 2576 type == NL80211_IFTYPE_P2P_CLIENT)) 2577 return; 2578 2579 iwl_mld_emlsr_block_tmp_non_bss(mld); 2580} 2581 2582static int iwl_mld_set_hw_timestamp(struct ieee80211_hw *hw, 2583 struct ieee80211_vif *vif, 2584 struct cfg80211_set_hw_timestamp *hwts) 2585{ 2586 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2587 u32 protocols = 0; 2588 2589 /* HW timestamping is only supported for a specific station */ 2590 if (!hwts->macaddr) 2591 return -EOPNOTSUPP; 2592 2593 if (hwts->enable) 2594 protocols = 2595 IWL_TIME_SYNC_PROTOCOL_TM | IWL_TIME_SYNC_PROTOCOL_FTM; 2596 2597 return iwl_mld_time_sync_config(mld, hwts->macaddr, protocols); 2598} 2599 2600static int iwl_mld_start_pmsr(struct ieee80211_hw *hw, 2601 struct ieee80211_vif *vif, 2602 struct cfg80211_pmsr_request *request) 2603{ 2604 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2605 2606 return iwl_mld_ftm_start(mld, vif, request); 2607} 2608 2609static enum ieee80211_neg_ttlm_res 2610iwl_mld_can_neg_ttlm(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 2611 struct ieee80211_neg_ttlm *neg_ttlm) 2612{ 2613 u16 map; 2614 2615 /* Verify all TIDs are mapped to the same links set */ 2616 map = neg_ttlm->downlink[0]; 2617 for (int i = 0; i < IEEE80211_TTLM_NUM_TIDS; i++) { 2618 if (neg_ttlm->downlink[i] != neg_ttlm->uplink[i] || 2619 neg_ttlm->uplink[i] != map) 2620 return NEG_TTLM_RES_REJECT; 2621 } 2622 2623 return NEG_TTLM_RES_ACCEPT; 2624} 2625 2626static int iwl_mld_get_antenna(struct ieee80211_hw *hw, int radio_idx, 2627 u32 *tx_ant, u32 *rx_ant) 2628{ 2629 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2630 2631 *tx_ant = iwl_mld_get_valid_tx_ant(mld); 2632 *rx_ant = iwl_mld_get_valid_rx_ant(mld); 2633 2634 return 0; 2635} 2636 2637static int iwl_mld_set_antenna(struct ieee80211_hw *hw, int radio_idx, 2638 u32 tx_ant, u32 rx_ant) 2639{ 2640 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 2641 2642 if (WARN_ON(!mld->nvm_data)) 2643 return -EBUSY; 2644 2645 /* mac80211 ensures the device is not started, 2646 * so the firmware cannot be running 2647 */ 2648 2649 mld->set_tx_ant = tx_ant; 2650 mld->set_rx_ant = rx_ant; 2651 2652 iwl_reinit_cab(mld->trans, mld->nvm_data, tx_ant, rx_ant, mld->fw); 2653 2654 return 0; 2655} 2656 2657const struct ieee80211_ops iwl_mld_hw_ops = { 2658 .tx = iwl_mld_mac80211_tx, 2659 .start = iwl_mld_mac80211_start, 2660 .stop = iwl_mld_mac80211_stop, 2661 .config = iwl_mld_mac80211_config, 2662 .get_antenna = iwl_mld_get_antenna, 2663 .set_antenna = iwl_mld_set_antenna, 2664 .add_interface = iwl_mld_mac80211_add_interface, 2665 .remove_interface = iwl_mld_mac80211_remove_interface, 2666 .conf_tx = iwl_mld_mac80211_conf_tx, 2667 .prepare_multicast = iwl_mld_mac80211_prepare_multicast, 2668 .configure_filter = iwl_mld_mac80211_configure_filter, 2669 .reconfig_complete = iwl_mld_mac80211_reconfig_complete, 2670 .wake_tx_queue = iwl_mld_mac80211_wake_tx_queue, 2671 .add_chanctx = iwl_mld_add_chanctx, 2672 .remove_chanctx = iwl_mld_remove_chanctx, 2673 .change_chanctx = iwl_mld_change_chanctx, 2674 .assign_vif_chanctx = iwl_mld_assign_vif_chanctx, 2675 .unassign_vif_chanctx = iwl_mld_unassign_vif_chanctx, 2676 .set_rts_threshold = iwl_mld_mac80211_set_rts_threshold, 2677 .link_info_changed = iwl_mld_mac80211_link_info_changed, 2678 .vif_cfg_changed = iwl_mld_mac80211_vif_cfg_changed, 2679 .set_key = iwl_mld_mac80211_set_key, 2680 .hw_scan = iwl_mld_mac80211_hw_scan, 2681 .cancel_hw_scan = iwl_mld_mac80211_cancel_hw_scan, 2682 .sched_scan_start = iwl_mld_mac80211_sched_scan_start, 2683 .sched_scan_stop = iwl_mld_mac80211_sched_scan_stop, 2684 .mgd_prepare_tx = iwl_mld_mac80211_mgd_prepare_tx, 2685 .mgd_complete_tx = iwl_mld_mac_mgd_complete_tx, 2686 .sta_state = iwl_mld_mac80211_sta_state, 2687 .sta_statistics = iwl_mld_mac80211_sta_statistics, 2688 .get_survey = iwl_mld_mac80211_get_survey, 2689 .flush = iwl_mld_mac80211_flush, 2690 .flush_sta = iwl_mld_mac80211_flush_sta, 2691 .ampdu_action = iwl_mld_mac80211_ampdu_action, 2692 .can_aggregate_in_amsdu = iwl_mld_mac80211_can_aggregate, 2693 .sync_rx_queues = iwl_mld_mac80211_sync_rx_queues, 2694 .link_sta_rc_update = iwl_mld_sta_rc_update, 2695 .start_ap = iwl_mld_start_ap_ibss, 2696 .stop_ap = iwl_mld_stop_ap_ibss, 2697 .pre_channel_switch = iwl_mld_pre_channel_switch, 2698 .channel_switch = iwl_mld_channel_switch, 2699 .post_channel_switch = iwl_mld_post_channel_switch, 2700 .abort_channel_switch = iwl_mld_abort_channel_switch, 2701 .switch_vif_chanctx = iwl_mld_switch_vif_chanctx, 2702 .sta_pre_rcu_remove = iwl_mld_sta_pre_rcu_remove, 2703 .remain_on_channel = iwl_mld_start_roc, 2704 .cancel_remain_on_channel = iwl_mld_cancel_roc, 2705 .can_activate_links = iwl_mld_can_activate_links, 2706 .change_vif_links = iwl_mld_change_vif_links, 2707 .change_sta_links = iwl_mld_change_sta_links, 2708#ifdef CONFIG_PM_SLEEP 2709 .suspend = iwl_mld_suspend, 2710 .resume = iwl_mld_resume, 2711 .set_wakeup = iwl_mld_set_wakeup, 2712 .set_rekey_data = iwl_mld_set_rekey_data, 2713#if IS_ENABLED(CONFIG_IPV6) 2714 .ipv6_addr_change = iwl_mld_ipv6_addr_change, 2715#endif /* IS_ENABLED(CONFIG_IPV6) */ 2716#endif /* CONFIG_PM_SLEEP */ 2717#ifdef CONFIG_IWLWIFI_DEBUGFS 2718 .vif_add_debugfs = iwl_mld_add_vif_debugfs, 2719 .link_add_debugfs = iwl_mld_add_link_debugfs, 2720 .link_sta_add_debugfs = iwl_mld_add_link_sta_debugfs, 2721#endif 2722 .mgd_protect_tdls_discover = iwl_mld_mac80211_mgd_protect_tdls_discover, 2723 .join_ibss = iwl_mld_mac80211_join_ibss, 2724 .leave_ibss = iwl_mld_mac80211_leave_ibss, 2725 .tx_last_beacon = iwl_mld_mac80211_tx_last_beacon, 2726 .prep_add_interface = iwl_mld_prep_add_interface, 2727 .set_hw_timestamp = iwl_mld_set_hw_timestamp, 2728 .start_pmsr = iwl_mld_start_pmsr, 2729 .can_neg_ttlm = iwl_mld_can_neg_ttlm, 2730};
~/
Read-only file preview.