1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* 3 * Copyright (C) 2022-2025 Intel Corporation 4 */ 5 #include "mvm.h" 6 7 static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw, 8 struct ieee80211_vif *vif) 9 { 10 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 11 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 12 int ret; 13 int i; 14 15 guard(mvm)(mvm); 16 17 iwl_mvm_mac_init_mvmvif(mvm, mvmvif); 18 19 mvmvif->mvm = mvm; 20 21 vif->driver_flags |= IEEE80211_VIF_REMOVE_AP_AFTER_DISASSOC; 22 23 /* Not much to do here. The stack will not allow interface 24 * types or combinations that we didn't advertise, so we 25 * don't really have to check the types. 26 */ 27 28 /* make sure that beacon statistics don't go backwards with FW reset */ 29 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) 30 for_each_mvm_vif_valid_link(mvmvif, i) 31 mvmvif->link[i]->beacon_stats.accu_num_beacons += 32 mvmvif->link[i]->beacon_stats.num_beacons; 33 34 /* Allocate resources for the MAC context, and add it to the fw */ 35 ret = iwl_mvm_mac_ctxt_init(mvm, vif); 36 if (ret) 37 return ret; 38 39 rcu_assign_pointer(mvm->vif_id_to_mac[mvmvif->id], vif); 40 41 mvmvif->features |= hw->netdev_features; 42 43 /* reset deflink MLO parameters */ 44 mvmvif->deflink.fw_link_id = IWL_MVM_FW_LINK_ID_INVALID; 45 mvmvif->deflink.active = 0; 46 47 ret = iwl_mvm_mld_mac_ctxt_add(mvm, vif); 48 if (ret) 49 return ret; 50 51 /* beacon filtering */ 52 ret = iwl_mvm_disable_beacon_filter(mvm, vif); 53 if (ret) 54 goto out_remove_mac; 55 56 if (!mvm->bf_allowed_vif && 57 vif->type == NL80211_IFTYPE_STATION && !vif->p2p) { 58 mvm->bf_allowed_vif = mvmvif; 59 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | 60 IEEE80211_VIF_SUPPORTS_CQM_RSSI; 61 } 62 63 /* We want link[0] to point to the default link, unless we have MLO and 64 * in this case this will be modified later by .change_vif_links() 65 * If we are in the restart flow with an MLD connection, we will wait 66 * to .change_vif_links() to setup the links. 67 */ 68 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) || 69 !ieee80211_vif_is_mld(vif)) { 70 mvmvif->link[0] = &mvmvif->deflink; 71 72 ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf); 73 if (ret) 74 goto out_free_bf; 75 } 76 77 /* Save a pointer to p2p device vif, so it can later be used to 78 * update the p2p device MAC when a GO is started/stopped 79 */ 80 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) 81 mvm->p2p_device_vif = vif; 82 83 ret = iwl_mvm_power_update_mac(mvm); 84 if (ret) 85 goto out_free_bf; 86 87 iwl_mvm_tcm_add_vif(mvm, vif); 88 89 if (vif->type == NL80211_IFTYPE_MONITOR) { 90 mvm->monitor_on = true; 91 ieee80211_hw_set(mvm->hw, RX_INCLUDES_FCS); 92 } 93 94 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) 95 iwl_mvm_vif_dbgfs_add_link(mvm, vif); 96 97 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && 98 vif->type == NL80211_IFTYPE_STATION && !vif->p2p && 99 !mvm->csme_vif && mvm->mei_registered) { 100 iwl_mei_set_nic_info(vif->addr, mvm->nvm_data->hw_addr); 101 iwl_mei_set_netdev(ieee80211_vif_to_wdev(vif)->netdev); 102 mvm->csme_vif = vif; 103 } 104 105 if (vif->p2p || iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1) < 5) 106 vif->driver_flags |= IEEE80211_VIF_IGNORE_OFDMA_WIDER_BW; 107 108 return 0; 109 110 out_free_bf: 111 if (mvm->bf_allowed_vif == mvmvif) { 112 mvm->bf_allowed_vif = NULL; 113 vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER | 114 IEEE80211_VIF_SUPPORTS_CQM_RSSI); 115 } 116 out_remove_mac: 117 mvmvif->link[0] = NULL; 118 iwl_mvm_mld_mac_ctxt_remove(mvm, vif); 119 return ret; 120 } 121 122 static void iwl_mvm_mld_mac_remove_interface(struct ieee80211_hw *hw, 123 struct ieee80211_vif *vif) 124 { 125 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 126 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 127 struct iwl_probe_resp_data *probe_data; 128 129 iwl_mvm_prepare_mac_removal(mvm, vif); 130 131 if (!(vif->type == NL80211_IFTYPE_AP || 132 vif->type == NL80211_IFTYPE_ADHOC)) 133 iwl_mvm_tcm_rm_vif(mvm, vif); 134 135 guard(mvm)(mvm); 136 137 if (vif == mvm->csme_vif) { 138 iwl_mei_set_netdev(NULL); 139 mvm->csme_vif = NULL; 140 } 141 142 if (mvm->bf_allowed_vif == mvmvif) { 143 mvm->bf_allowed_vif = NULL; 144 vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER | 145 IEEE80211_VIF_SUPPORTS_CQM_RSSI); 146 } 147 148 if (vif->bss_conf.ftm_responder) 149 memset(&mvm->ftm_resp_stats, 0, sizeof(mvm->ftm_resp_stats)); 150 151 iwl_mvm_vif_dbgfs_rm_link(mvm, vif); 152 153 iwl_mvm_power_update_mac(mvm); 154 155 /* Before the interface removal, mac80211 would cancel the ROC, and the 156 * ROC worker would be scheduled if needed. The worker would be flushed 157 * in iwl_mvm_prepare_mac_removal() and thus at this point the link is 158 * not active. So need only to remove the link. 159 */ 160 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { 161 if (mvmvif->deflink.phy_ctxt) { 162 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt); 163 mvmvif->deflink.phy_ctxt = NULL; 164 } 165 mvm->p2p_device_vif = NULL; 166 iwl_mvm_remove_link(mvm, vif, &vif->bss_conf); 167 } else { 168 iwl_mvm_disable_link(mvm, vif, &vif->bss_conf); 169 } 170 171 iwl_mvm_mld_mac_ctxt_remove(mvm, vif); 172 173 RCU_INIT_POINTER(mvm->vif_id_to_mac[mvmvif->id], NULL); 174 175 probe_data = rcu_dereference_protected(mvmvif->deflink.probe_resp_data, 176 lockdep_is_held(&mvm->mutex)); 177 RCU_INIT_POINTER(mvmvif->deflink.probe_resp_data, NULL); 178 if (probe_data) 179 kfree_rcu(probe_data, rcu_head); 180 181 if (vif->type == NL80211_IFTYPE_MONITOR) { 182 mvm->monitor_on = false; 183 __clear_bit(IEEE80211_HW_RX_INCLUDES_FCS, mvm->hw->flags); 184 } 185 } 186 187 static unsigned int iwl_mvm_mld_count_active_links(struct iwl_mvm_vif *mvmvif) 188 { 189 unsigned int n_active = 0; 190 int i; 191 192 for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { 193 if (mvmvif->link[i] && mvmvif->link[i]->phy_ctxt) 194 n_active++; 195 } 196 197 return n_active; 198 } 199 200 static int iwl_mvm_esr_mode_active(struct iwl_mvm *mvm, 201 struct ieee80211_vif *vif) 202 { 203 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 204 int link_id, ret = 0; 205 206 mvmvif->esr_active = true; 207 208 /* Indicate to mac80211 that EML is enabled */ 209 vif->driver_flags |= IEEE80211_VIF_EML_ACTIVE; 210 211 iwl_mvm_update_smps_on_active_links(mvm, vif, IWL_MVM_SMPS_REQ_FW, 212 IEEE80211_SMPS_OFF); 213 214 for_each_mvm_vif_valid_link(mvmvif, link_id) { 215 struct iwl_mvm_vif_link_info *link = mvmvif->link[link_id]; 216 217 if (!link->phy_ctxt) 218 continue; 219 220 ret = iwl_mvm_phy_send_rlc(mvm, link->phy_ctxt, 2, 2); 221 if (ret) 222 break; 223 224 link->phy_ctxt->rlc_disabled = true; 225 } 226 227 if (vif->active_links == mvmvif->link_selection_res && 228 !WARN_ON(!(vif->active_links & BIT(mvmvif->link_selection_primary)))) 229 mvmvif->primary_link = mvmvif->link_selection_primary; 230 else 231 mvmvif->primary_link = __ffs(vif->active_links); 232 233 iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_ESR_LINK_UP, 234 NULL); 235 236 return ret; 237 } 238 239 static int 240 __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm, 241 struct ieee80211_vif *vif, 242 struct ieee80211_bss_conf *link_conf, 243 struct ieee80211_chanctx_conf *ctx, 244 bool switching_chanctx) 245 { 246 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv; 247 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id]; 248 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 249 unsigned int n_active = iwl_mvm_mld_count_active_links(mvmvif); 250 unsigned int link_id = link_conf->link_id; 251 int ret; 252 253 if (WARN_ON_ONCE(!mvmvif->link[link_id])) 254 return -EINVAL; 255 256 /* if the assigned one was not counted yet, count it now */ 257 if (!mvmvif->link[link_id]->phy_ctxt) 258 n_active++; 259 260 /* mac parameters such as HE support can change at this stage 261 * For sta, need first to configure correct state from drv_sta_state 262 * and only after that update mac config. 263 */ 264 if (vif->type == NL80211_IFTYPE_AP) { 265 ret = iwl_mvm_mld_mac_ctxt_changed(mvm, vif, false); 266 if (ret) { 267 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); 268 return -EINVAL; 269 } 270 } 271 272 mvmvif->link[link_id]->phy_ctxt = phy_ctxt; 273 274 if (iwl_mvm_is_esr_supported(mvm->fwrt.trans) && n_active > 1) { 275 mvmvif->link[link_id]->listen_lmac = true; 276 ret = iwl_mvm_esr_mode_active(mvm, vif); 277 if (ret) { 278 IWL_ERR(mvm, "failed to activate ESR mode (%d)\n", ret); 279 goto out; 280 } 281 } 282 283 if (switching_chanctx) { 284 /* reactivate if we turned this off during channel switch */ 285 if (vif->type == NL80211_IFTYPE_AP) 286 mvmvif->ap_ibss_active = true; 287 } 288 289 /* send it first with phy context ID */ 290 ret = iwl_mvm_link_changed(mvm, vif, link_conf, 0, false); 291 if (ret) 292 goto out; 293 294 /* 295 * if link switching (link not active yet) we'll activate it in 296 * firmware later on link-info change, which mac80211 guarantees 297 * for link switch after the stations are set up 298 */ 299 if (ieee80211_vif_link_active(vif, link_conf->link_id)) { 300 ret = iwl_mvm_link_changed(mvm, vif, link_conf, 301 LINK_CONTEXT_MODIFY_ACTIVE | 302 LINK_CONTEXT_MODIFY_RATES_INFO, 303 true); 304 if (ret) 305 goto out; 306 } 307 308 if (vif->type == NL80211_IFTYPE_STATION) 309 iwl_mvm_send_ap_tx_power_constraint_cmd(mvm, vif, 310 link_conf, 311 false); 312 313 /* 314 * Power state must be updated before quotas, 315 * otherwise fw will complain. 316 */ 317 iwl_mvm_power_update_mac(mvm); 318 319 if (vif->type == NL80211_IFTYPE_MONITOR) { 320 ret = iwl_mvm_mld_add_snif_sta(mvm, vif, link_conf); 321 if (ret) 322 goto deactivate; 323 } 324 325 return 0; 326 327 deactivate: 328 iwl_mvm_link_changed(mvm, vif, link_conf, LINK_CONTEXT_MODIFY_ACTIVE, 329 false); 330 out: 331 mvmvif->link[link_id]->phy_ctxt = NULL; 332 iwl_mvm_power_update_mac(mvm); 333 return ret; 334 } 335 336 static int iwl_mvm_mld_assign_vif_chanctx(struct ieee80211_hw *hw, 337 struct ieee80211_vif *vif, 338 struct ieee80211_bss_conf *link_conf, 339 struct ieee80211_chanctx_conf *ctx) 340 { 341 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 342 343 /* update EMLSR mode */ 344 if (ieee80211_vif_type_p2p(vif) != NL80211_IFTYPE_STATION) { 345 int ret; 346 347 ret = iwl_mvm_esr_non_bss_link(mvm, vif, link_conf->link_id, 348 true); 349 /* 350 * Don't activate this link if failed to exit EMLSR in 351 * the BSS interface 352 */ 353 if (ret) 354 return ret; 355 } 356 357 guard(mvm)(mvm); 358 return __iwl_mvm_mld_assign_vif_chanctx(mvm, vif, link_conf, ctx, false); 359 } 360 361 static int iwl_mvm_esr_mode_inactive(struct iwl_mvm *mvm, 362 struct ieee80211_vif *vif) 363 { 364 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 365 struct ieee80211_bss_conf *link_conf; 366 int link_id, ret = 0; 367 368 mvmvif->esr_active = false; 369 370 vif->driver_flags &= ~IEEE80211_VIF_EML_ACTIVE; 371 372 iwl_mvm_update_smps_on_active_links(mvm, vif, IWL_MVM_SMPS_REQ_FW, 373 IEEE80211_SMPS_AUTOMATIC); 374 375 for_each_vif_active_link(vif, link_conf, link_id) { 376 struct ieee80211_chanctx_conf *chanctx_conf; 377 struct iwl_mvm_phy_ctxt *phy_ctxt; 378 u8 static_chains, dynamic_chains; 379 380 mvmvif->link[link_id]->listen_lmac = false; 381 382 rcu_read_lock(); 383 384 chanctx_conf = rcu_dereference(link_conf->chanctx_conf); 385 phy_ctxt = mvmvif->link[link_id]->phy_ctxt; 386 387 if (!chanctx_conf || !phy_ctxt) { 388 rcu_read_unlock(); 389 continue; 390 } 391 392 phy_ctxt->rlc_disabled = false; 393 static_chains = chanctx_conf->rx_chains_static; 394 dynamic_chains = chanctx_conf->rx_chains_dynamic; 395 396 rcu_read_unlock(); 397 398 ret = iwl_mvm_phy_send_rlc(mvm, phy_ctxt, static_chains, 399 dynamic_chains); 400 if (ret) 401 break; 402 } 403 404 iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_ESR_LINK_DOWN, 405 NULL); 406 407 return ret; 408 } 409 410 static void 411 __iwl_mvm_mld_unassign_vif_chanctx(struct iwl_mvm *mvm, 412 struct ieee80211_vif *vif, 413 struct ieee80211_bss_conf *link_conf, 414 struct ieee80211_chanctx_conf *ctx, 415 bool switching_chanctx) 416 417 { 418 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 419 unsigned int n_active = iwl_mvm_mld_count_active_links(mvmvif); 420 unsigned int link_id = link_conf->link_id; 421 422 /* shouldn't happen, but verify link_id is valid before accessing */ 423 if (WARN_ON_ONCE(!mvmvif->link[link_id])) 424 return; 425 426 if (vif->type == NL80211_IFTYPE_AP && switching_chanctx) { 427 mvmvif->csa_countdown = false; 428 429 /* Set CS bit on all the stations */ 430 iwl_mvm_modify_all_sta_disable_tx(mvm, mvmvif, true); 431 432 /* Save blocked iface, the timeout is set on the next beacon */ 433 rcu_assign_pointer(mvm->csa_tx_blocked_vif, vif); 434 435 mvmvif->ap_ibss_active = false; 436 } 437 438 iwl_mvm_link_changed(mvm, vif, link_conf, 439 LINK_CONTEXT_MODIFY_ACTIVE, false); 440 441 if (iwl_mvm_is_esr_supported(mvm->fwrt.trans) && n_active > 1) { 442 int ret = iwl_mvm_esr_mode_inactive(mvm, vif); 443 444 if (ret) 445 IWL_ERR(mvm, "failed to deactivate ESR mode (%d)\n", 446 ret); 447 } 448 449 if (vif->type == NL80211_IFTYPE_MONITOR) 450 iwl_mvm_mld_rm_snif_sta(mvm, vif); 451 452 if (switching_chanctx) 453 return; 454 mvmvif->link[link_id]->phy_ctxt = NULL; 455 iwl_mvm_power_update_mac(mvm); 456 } 457 458 static void iwl_mvm_mld_unassign_vif_chanctx(struct ieee80211_hw *hw, 459 struct ieee80211_vif *vif, 460 struct ieee80211_bss_conf *link_conf, 461 struct ieee80211_chanctx_conf *ctx) 462 { 463 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 464 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 465 466 mutex_lock(&mvm->mutex); 467 __iwl_mvm_mld_unassign_vif_chanctx(mvm, vif, link_conf, ctx, false); 468 /* in the non-MLD case, remove/re-add the link to clean up FW state */ 469 if (!ieee80211_vif_is_mld(vif) && !mvmvif->ap_sta && 470 !WARN_ON_ONCE(vif->cfg.assoc)) { 471 iwl_mvm_remove_link(mvm, vif, link_conf); 472 iwl_mvm_add_link(mvm, vif, link_conf); 473 } 474 mutex_unlock(&mvm->mutex); 475 476 /* update EMLSR mode */ 477 if (ieee80211_vif_type_p2p(vif) != NL80211_IFTYPE_STATION) 478 iwl_mvm_esr_non_bss_link(mvm, vif, link_conf->link_id, false); 479 } 480 481 static void 482 iwl_mvm_tpe_sta_cmd_data(struct iwl_txpower_constraints_cmd *cmd, 483 const struct ieee80211_bss_conf *bss_info) 484 { 485 u8 i; 486 487 /* 488 * NOTE: the 0 here is IEEE80211_TPE_CAT_6GHZ_DEFAULT, 489 * we fully ignore IEEE80211_TPE_CAT_6GHZ_SUBORDINATE 490 */ 491 492 BUILD_BUG_ON(ARRAY_SIZE(cmd->psd_pwr) != 493 ARRAY_SIZE(bss_info->tpe.psd_local[0].power)); 494 495 /* if not valid, mac80211 puts default (max value) */ 496 for (i = 0; i < ARRAY_SIZE(cmd->psd_pwr); i++) 497 cmd->psd_pwr[i] = min(bss_info->tpe.psd_local[0].power[i], 498 bss_info->tpe.psd_reg_client[0].power[i]); 499 500 BUILD_BUG_ON(ARRAY_SIZE(cmd->eirp_pwr) != 501 ARRAY_SIZE(bss_info->tpe.max_local[0].power)); 502 503 for (i = 0; i < ARRAY_SIZE(cmd->eirp_pwr); i++) 504 cmd->eirp_pwr[i] = min(bss_info->tpe.max_local[0].power[i], 505 bss_info->tpe.max_reg_client[0].power[i]); 506 } 507 508 void 509 iwl_mvm_send_ap_tx_power_constraint_cmd(struct iwl_mvm *mvm, 510 struct ieee80211_vif *vif, 511 struct ieee80211_bss_conf *bss_conf, 512 bool is_ap) 513 { 514 struct iwl_txpower_constraints_cmd cmd = {}; 515 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 516 struct iwl_mvm_vif_link_info *link_info = 517 mvmvif->link[bss_conf->link_id]; 518 u32 cmd_id = WIDE_ID(PHY_OPS_GROUP, AP_TX_POWER_CONSTRAINTS_CMD); 519 u32 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 520 IWL_FW_CMD_VER_UNKNOWN); 521 int ret; 522 523 lockdep_assert_held(&mvm->mutex); 524 525 if (cmd_ver == IWL_FW_CMD_VER_UNKNOWN) 526 return; 527 528 if (!link_info->active || 529 link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID) 530 return; 531 532 if (bss_conf->chanreq.oper.chan->band != NL80211_BAND_6GHZ) 533 return; 534 535 cmd.link_id = cpu_to_le16(link_info->fw_link_id); 536 memset(cmd.psd_pwr, DEFAULT_TPE_TX_POWER, sizeof(cmd.psd_pwr)); 537 memset(cmd.eirp_pwr, DEFAULT_TPE_TX_POWER, sizeof(cmd.eirp_pwr)); 538 539 if (is_ap) { 540 cmd.ap_type = cpu_to_le16(IWL_6GHZ_AP_TYPE_VLP); 541 } else if (bss_conf->power_type == IEEE80211_REG_UNSET_AP) { 542 return; 543 } else { 544 cmd.ap_type = cpu_to_le16(bss_conf->power_type - 1); 545 iwl_mvm_tpe_sta_cmd_data(&cmd, bss_conf); 546 } 547 548 ret = iwl_mvm_send_cmd_pdu(mvm, 549 WIDE_ID(PHY_OPS_GROUP, 550 AP_TX_POWER_CONSTRAINTS_CMD), 551 0, sizeof(cmd), &cmd); 552 if (ret) 553 IWL_ERR(mvm, 554 "failed to send AP_TX_POWER_CONSTRAINTS_CMD (%d)\n", 555 ret); 556 } 557 558 static int iwl_mvm_mld_start_ap_ibss(struct ieee80211_hw *hw, 559 struct ieee80211_vif *vif, 560 struct ieee80211_bss_conf *link_conf) 561 { 562 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 563 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 564 int ret; 565 566 guard(mvm)(mvm); 567 568 if (vif->type == NL80211_IFTYPE_AP) 569 iwl_mvm_send_ap_tx_power_constraint_cmd(mvm, vif, 570 link_conf, true); 571 572 /* Send the beacon template */ 573 ret = iwl_mvm_mac_ctxt_beacon_changed(mvm, vif, link_conf); 574 if (ret) 575 return ret; 576 577 /* the link should be already activated when assigning chan context */ 578 ret = iwl_mvm_link_changed(mvm, vif, link_conf, 579 LINK_CONTEXT_MODIFY_ALL & 580 ~LINK_CONTEXT_MODIFY_ACTIVE, 581 true); 582 if (ret) 583 return ret; 584 585 ret = iwl_mvm_mld_add_mcast_sta(mvm, vif, link_conf); 586 if (ret) 587 return ret; 588 589 /* Send the bcast station. At this stage the TBTT and DTIM time 590 * events are added and applied to the scheduler 591 */ 592 ret = iwl_mvm_mld_add_bcast_sta(mvm, vif, link_conf); 593 if (ret) 594 goto out_rm_mcast; 595 596 if (iwl_mvm_start_ap_ibss_common(hw, vif, &ret)) 597 goto out_failed; 598 599 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ 600 if (vif->p2p && mvm->p2p_device_vif) 601 iwl_mvm_mld_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false); 602 603 iwl_mvm_bt_coex_vif_change(mvm); 604 605 /* we don't support TDLS during DCM */ 606 if (iwl_mvm_phy_ctx_count(mvm) > 1) 607 iwl_mvm_teardown_tdls_peers(mvm); 608 609 iwl_mvm_ftm_restart_responder(mvm, vif, link_conf); 610 611 return 0; 612 613 out_failed: 614 iwl_mvm_power_update_mac(mvm); 615 mvmvif->ap_ibss_active = false; 616 iwl_mvm_mld_rm_bcast_sta(mvm, vif, link_conf); 617 out_rm_mcast: 618 iwl_mvm_mld_rm_mcast_sta(mvm, vif, link_conf); 619 return ret; 620 } 621 622 static int iwl_mvm_mld_start_ap(struct ieee80211_hw *hw, 623 struct ieee80211_vif *vif, 624 struct ieee80211_bss_conf *link_conf) 625 { 626 return iwl_mvm_mld_start_ap_ibss(hw, vif, link_conf); 627 } 628 629 static int iwl_mvm_mld_start_ibss(struct ieee80211_hw *hw, 630 struct ieee80211_vif *vif) 631 { 632 return iwl_mvm_mld_start_ap_ibss(hw, vif, &vif->bss_conf); 633 } 634 635 static void iwl_mvm_mld_stop_ap_ibss(struct ieee80211_hw *hw, 636 struct ieee80211_vif *vif, 637 struct ieee80211_bss_conf *link_conf) 638 { 639 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 640 641 guard(mvm)(mvm); 642 643 iwl_mvm_stop_ap_ibss_common(mvm, vif); 644 645 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ 646 if (vif->p2p && mvm->p2p_device_vif) 647 iwl_mvm_mld_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false); 648 649 iwl_mvm_ftm_responder_clear(mvm, vif); 650 651 iwl_mvm_mld_rm_bcast_sta(mvm, vif, link_conf); 652 iwl_mvm_mld_rm_mcast_sta(mvm, vif, link_conf); 653 654 iwl_mvm_power_update_mac(mvm); 655 } 656 657 static void iwl_mvm_mld_stop_ap(struct ieee80211_hw *hw, 658 struct ieee80211_vif *vif, 659 struct ieee80211_bss_conf *link_conf) 660 { 661 iwl_mvm_mld_stop_ap_ibss(hw, vif, link_conf); 662 } 663 664 static void iwl_mvm_mld_stop_ibss(struct ieee80211_hw *hw, 665 struct ieee80211_vif *vif) 666 { 667 iwl_mvm_mld_stop_ap_ibss(hw, vif, &vif->bss_conf); 668 } 669 670 static int iwl_mvm_mld_mac_sta_state(struct ieee80211_hw *hw, 671 struct ieee80211_vif *vif, 672 struct ieee80211_sta *sta, 673 enum ieee80211_sta_state old_state, 674 enum ieee80211_sta_state new_state) 675 { 676 static const struct iwl_mvm_sta_state_ops callbacks = { 677 .add_sta = iwl_mvm_mld_add_sta, 678 .update_sta = iwl_mvm_mld_update_sta, 679 .rm_sta = iwl_mvm_mld_rm_sta, 680 .mac_ctxt_changed = iwl_mvm_mld_mac_ctxt_changed, 681 }; 682 683 return iwl_mvm_mac_sta_state_common(hw, vif, sta, old_state, new_state, 684 &callbacks); 685 } 686 687 static bool iwl_mvm_esr_bw_criteria(struct iwl_mvm *mvm, 688 struct ieee80211_vif *vif, 689 struct ieee80211_bss_conf *link_conf) 690 { 691 struct ieee80211_bss_conf *other_link; 692 int link_id; 693 694 /* Exit EMLSR if links don't have equal bandwidths */ 695 for_each_vif_active_link(vif, other_link, link_id) { 696 if (link_id == link_conf->link_id) 697 continue; 698 if (link_conf->chanreq.oper.width == 699 other_link->chanreq.oper.width) 700 return true; 701 } 702 703 return false; 704 } 705 706 static void 707 iwl_mvm_mld_link_info_changed_station(struct iwl_mvm *mvm, 708 struct ieee80211_vif *vif, 709 struct ieee80211_bss_conf *link_conf, 710 u64 changes) 711 { 712 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 713 bool has_he, has_eht; 714 u32 link_changes = 0; 715 int ret; 716 717 if (WARN_ON_ONCE(!mvmvif->link[link_conf->link_id])) 718 return; 719 720 /* not yet marked active in vif means during link switch */ 721 if (!ieee80211_vif_link_active(vif, link_conf->link_id) && 722 vif->cfg.assoc && mvmvif->link[link_conf->link_id]->phy_ctxt) 723 link_changes |= LINK_CONTEXT_MODIFY_ACTIVE; 724 725 has_he = link_conf->he_support && !iwlwifi_mod_params.disable_11ax; 726 has_eht = link_conf->eht_support && !iwlwifi_mod_params.disable_11be; 727 728 /* Update EDCA params */ 729 if (changes & BSS_CHANGED_QOS && vif->cfg.assoc && link_conf->qos) 730 link_changes |= LINK_CONTEXT_MODIFY_QOS_PARAMS; 731 732 if (changes & BSS_CHANGED_ERP_SLOT) 733 link_changes |= LINK_CONTEXT_MODIFY_RATES_INFO; 734 735 if (vif->cfg.assoc && (has_he || has_eht)) { 736 IWL_DEBUG_MAC80211(mvm, "Associated in HE mode\n"); 737 link_changes |= LINK_CONTEXT_MODIFY_HE_PARAMS; 738 } 739 740 if ((changes & BSS_CHANGED_BANDWIDTH) && 741 ieee80211_vif_link_active(vif, link_conf->link_id) && 742 mvmvif->esr_active && 743 !iwl_mvm_esr_bw_criteria(mvm, vif, link_conf)) 744 iwl_mvm_exit_esr(mvm, vif, 745 IWL_MVM_ESR_EXIT_BANDWIDTH, 746 iwl_mvm_get_primary_link(vif)); 747 748 /* if associated, maybe puncturing changed - we'll check later */ 749 if (vif->cfg.assoc) 750 link_changes |= LINK_CONTEXT_MODIFY_EHT_PARAMS; 751 752 if (link_changes) { 753 ret = iwl_mvm_link_changed(mvm, vif, link_conf, link_changes, 754 true); 755 if (ret) 756 IWL_ERR(mvm, "failed to update link\n"); 757 } 758 759 ret = iwl_mvm_mld_mac_ctxt_changed(mvm, vif, false); 760 if (ret) 761 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); 762 763 memcpy(mvmvif->link[link_conf->link_id]->bssid, link_conf->bssid, 764 ETH_ALEN); 765 766 iwl_mvm_bss_info_changed_station_common(mvm, vif, link_conf, changes); 767 } 768 769 static bool iwl_mvm_mld_vif_have_valid_ap_sta(struct iwl_mvm_vif *mvmvif) 770 { 771 int i; 772 773 for_each_mvm_vif_valid_link(mvmvif, i) { 774 if (mvmvif->link[i]->ap_sta_id != IWL_INVALID_STA) 775 return true; 776 } 777 778 return false; 779 } 780 781 static void iwl_mvm_mld_vif_cfg_changed_station(struct iwl_mvm *mvm, 782 struct ieee80211_vif *vif, 783 u64 changes) 784 { 785 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 786 struct ieee80211_bss_conf *link_conf; 787 bool protect = false; 788 unsigned int i; 789 int ret; 790 791 /* This might get called without active links during the 792 * chanctx switch, but we don't care about it anyway. 793 */ 794 if (changes == BSS_CHANGED_IDLE) 795 return; 796 797 ret = iwl_mvm_mld_mac_ctxt_changed(mvm, vif, false); 798 if (ret) 799 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); 800 801 mvmvif->associated = vif->cfg.assoc; 802 803 if (changes & BSS_CHANGED_ASSOC) { 804 if (vif->cfg.assoc) { 805 mvmvif->session_prot_connection_loss = false; 806 807 /* 808 * Clear statistics to get clean beacon counter, and ask for 809 * periodic statistics, as they are needed for link 810 * selection and RX OMI decisions. 811 */ 812 iwl_mvm_request_statistics(mvm, true); 813 iwl_mvm_request_periodic_system_statistics(mvm, true); 814 iwl_mvm_sf_update(mvm, vif, false); 815 iwl_mvm_power_vif_assoc(mvm, vif); 816 817 for_each_mvm_vif_valid_link(mvmvif, i) { 818 memset(&mvmvif->link[i]->beacon_stats, 0, 819 sizeof(mvmvif->link[i]->beacon_stats)); 820 821 if (vif->p2p) { 822 iwl_mvm_update_smps(mvm, vif, 823 IWL_MVM_SMPS_REQ_PROT, 824 IEEE80211_SMPS_DYNAMIC, i); 825 } 826 827 rcu_read_lock(); 828 link_conf = rcu_dereference(vif->link_conf[i]); 829 if (link_conf && !link_conf->dtim_period) 830 protect = true; 831 rcu_read_unlock(); 832 } 833 834 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && 835 protect) { 836 /* We are in assoc so only one link is active- 837 * The association link 838 */ 839 unsigned int link_id = 840 ffs(vif->active_links) - 1; 841 842 /* If we're not restarting and still haven't 843 * heard a beacon (dtim period unknown) then 844 * make sure we still have enough minimum time 845 * remaining in the time event, since the auth 846 * might actually have taken quite a while 847 * (especially for SAE) and so the remaining 848 * time could be small without us having heard 849 * a beacon yet. 850 */ 851 iwl_mvm_protect_assoc(mvm, vif, 0, link_id); 852 } 853 854 iwl_mvm_sf_update(mvm, vif, false); 855 856 /* FIXME: need to decide about misbehaving AP handling */ 857 iwl_mvm_power_vif_assoc(mvm, vif); 858 } else if (iwl_mvm_mld_vif_have_valid_ap_sta(mvmvif)) { 859 iwl_mvm_mei_host_disassociated(mvm); 860 861 iwl_mvm_request_periodic_system_statistics(mvm, false); 862 863 /* If update fails - SF might be running in associated 864 * mode while disassociated - which is forbidden. 865 */ 866 ret = iwl_mvm_sf_update(mvm, vif, false); 867 WARN_ONCE(ret && 868 !test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, 869 &mvm->status), 870 "Failed to update SF upon disassociation\n"); 871 } 872 873 iwl_mvm_bss_info_changed_station_assoc(mvm, vif, changes); 874 } 875 876 if (changes & BSS_CHANGED_PS) { 877 iwl_mvm_smps_workaround(mvm, vif, false); 878 ret = iwl_mvm_power_update_mac(mvm); 879 if (ret) 880 IWL_ERR(mvm, "failed to update power mode\n"); 881 } 882 883 if (changes & (BSS_CHANGED_MLD_VALID_LINKS | BSS_CHANGED_MLD_TTLM) && 884 ieee80211_vif_is_mld(vif) && mvmvif->authorized) 885 wiphy_delayed_work_queue(mvm->hw->wiphy, 886 &mvmvif->mlo_int_scan_wk, 0); 887 } 888 889 static void 890 iwl_mvm_mld_link_info_changed_ap_ibss(struct iwl_mvm *mvm, 891 struct ieee80211_vif *vif, 892 struct ieee80211_bss_conf *link_conf, 893 u64 changes) 894 { 895 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 896 u32 link_changes = LINK_CONTEXT_MODIFY_PROTECT_FLAGS | 897 LINK_CONTEXT_MODIFY_QOS_PARAMS; 898 899 /* Changes will be applied when the AP/IBSS is started */ 900 if (!mvmvif->ap_ibss_active) 901 return; 902 903 if (link_conf->he_support) 904 link_changes |= LINK_CONTEXT_MODIFY_HE_PARAMS; 905 906 if (changes & BSS_CHANGED_ERP_SLOT) 907 link_changes |= LINK_CONTEXT_MODIFY_RATES_INFO; 908 909 if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_SLOT | 910 BSS_CHANGED_HT | 911 BSS_CHANGED_BANDWIDTH | BSS_CHANGED_QOS | 912 BSS_CHANGED_HE_BSS_COLOR) && 913 iwl_mvm_link_changed(mvm, vif, link_conf, 914 link_changes, true)) 915 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); 916 917 /* Need to send a new beacon template to the FW */ 918 if (changes & BSS_CHANGED_BEACON && 919 iwl_mvm_mac_ctxt_beacon_changed(mvm, vif, link_conf)) 920 IWL_WARN(mvm, "Failed updating beacon data\n"); 921 922 /* FIXME: need to decide if we need FTM responder per link */ 923 if (changes & BSS_CHANGED_FTM_RESPONDER) { 924 int ret = iwl_mvm_ftm_start_responder(mvm, vif, link_conf); 925 926 if (ret) 927 IWL_WARN(mvm, "Failed to enable FTM responder (%d)\n", 928 ret); 929 } 930 } 931 932 static void iwl_mvm_mld_link_info_changed(struct ieee80211_hw *hw, 933 struct ieee80211_vif *vif, 934 struct ieee80211_bss_conf *link_conf, 935 u64 changes) 936 { 937 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 938 939 guard(mvm)(mvm); 940 941 switch (vif->type) { 942 case NL80211_IFTYPE_STATION: 943 iwl_mvm_mld_link_info_changed_station(mvm, vif, link_conf, 944 changes); 945 break; 946 case NL80211_IFTYPE_AP: 947 case NL80211_IFTYPE_ADHOC: 948 iwl_mvm_mld_link_info_changed_ap_ibss(mvm, vif, link_conf, 949 changes); 950 break; 951 case NL80211_IFTYPE_MONITOR: 952 if (changes & BSS_CHANGED_MU_GROUPS) 953 iwl_mvm_update_mu_groups(mvm, vif); 954 break; 955 default: 956 /* shouldn't happen */ 957 WARN_ON_ONCE(1); 958 } 959 960 if (changes & BSS_CHANGED_TXPOWER) { 961 IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d dBm\n", 962 link_conf->txpower); 963 iwl_mvm_set_tx_power(mvm, link_conf, link_conf->txpower); 964 } 965 } 966 967 static void iwl_mvm_mld_vif_cfg_changed(struct ieee80211_hw *hw, 968 struct ieee80211_vif *vif, 969 u64 changes) 970 { 971 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 972 973 guard(mvm)(mvm); 974 975 if (changes & BSS_CHANGED_IDLE && !vif->cfg.idle) 976 iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true); 977 978 if (vif->type == NL80211_IFTYPE_STATION) 979 iwl_mvm_mld_vif_cfg_changed_station(mvm, vif, changes); 980 } 981 982 static int 983 iwl_mvm_mld_switch_vif_chanctx(struct ieee80211_hw *hw, 984 struct ieee80211_vif_chanctx_switch *vifs, 985 int n_vifs, 986 enum ieee80211_chanctx_switch_mode mode) 987 { 988 static const struct iwl_mvm_switch_vif_chanctx_ops ops = { 989 .__assign_vif_chanctx = __iwl_mvm_mld_assign_vif_chanctx, 990 .__unassign_vif_chanctx = __iwl_mvm_mld_unassign_vif_chanctx, 991 }; 992 993 return iwl_mvm_switch_vif_chanctx_common(hw, vifs, n_vifs, mode, &ops); 994 } 995 996 static void iwl_mvm_mld_config_iface_filter(struct ieee80211_hw *hw, 997 struct ieee80211_vif *vif, 998 unsigned int filter_flags, 999 unsigned int changed_flags) 1000 { 1001 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1002 1003 /* We support only filter for probe requests */ 1004 if (!(changed_flags & FIF_PROBE_REQ)) 1005 return; 1006 1007 /* Supported only for p2p client interfaces */ 1008 if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc || 1009 !vif->p2p) 1010 return; 1011 1012 guard(mvm)(mvm); 1013 iwl_mvm_mld_mac_ctxt_changed(mvm, vif, false); 1014 } 1015 1016 static int 1017 iwl_mvm_mld_mac_conf_tx(struct ieee80211_hw *hw, 1018 struct ieee80211_vif *vif, 1019 unsigned int link_id, u16 ac, 1020 const struct ieee80211_tx_queue_params *params) 1021 { 1022 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1023 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 1024 struct iwl_mvm_vif_link_info *mvm_link = mvmvif->link[link_id]; 1025 1026 if (!mvm_link) 1027 return -EINVAL; 1028 1029 mvm_link->queue_params[ac] = *params; 1030 1031 /* No need to update right away, we'll get BSS_CHANGED_QOS 1032 * The exception is P2P_DEVICE interface which needs immediate update. 1033 */ 1034 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { 1035 guard(mvm)(mvm); 1036 return iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, 1037 LINK_CONTEXT_MODIFY_QOS_PARAMS, 1038 true); 1039 } 1040 return 0; 1041 } 1042 1043 static int iwl_mvm_mld_roc_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 1044 { 1045 int ret; 1046 1047 lockdep_assert_held(&mvm->mutex); 1048 1049 /* The PHY context ID might have changed so need to set it */ 1050 ret = iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, 0, false); 1051 if (WARN(ret, "Failed to set PHY context ID\n")) 1052 return ret; 1053 1054 ret = iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, 1055 LINK_CONTEXT_MODIFY_ACTIVE | 1056 LINK_CONTEXT_MODIFY_RATES_INFO, 1057 true); 1058 1059 if (WARN(ret, "Failed linking P2P_DEVICE\n")) 1060 return ret; 1061 1062 /* The station and queue allocation must be done only after the linking 1063 * is done, as otherwise the FW might incorrectly configure its state. 1064 */ 1065 return iwl_mvm_mld_add_bcast_sta(mvm, vif, &vif->bss_conf); 1066 } 1067 1068 static int iwl_mvm_mld_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1069 struct ieee80211_channel *channel, int duration, 1070 enum ieee80211_roc_type type) 1071 { 1072 static const struct iwl_mvm_roc_ops ops = { 1073 .add_aux_sta_for_hs20 = iwl_mvm_mld_add_aux_sta, 1074 .link = iwl_mvm_mld_roc_link, 1075 }; 1076 1077 return iwl_mvm_roc_common(hw, vif, channel, duration, type, &ops); 1078 } 1079 1080 static int 1081 iwl_mvm_mld_change_vif_links(struct ieee80211_hw *hw, 1082 struct ieee80211_vif *vif, 1083 u16 old_links, u16 new_links, 1084 struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]) 1085 { 1086 struct iwl_mvm_vif_link_info *new_link[IEEE80211_MLD_MAX_NUM_LINKS] = {}; 1087 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 1088 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1089 u16 removed = old_links & ~new_links; 1090 u16 added = new_links & ~old_links; 1091 int err, i; 1092 1093 for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { 1094 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) 1095 break; 1096 1097 if (!(added & BIT(i))) 1098 continue; 1099 new_link[i] = kzalloc(sizeof(*new_link[i]), GFP_KERNEL); 1100 if (!new_link[i]) { 1101 err = -ENOMEM; 1102 goto free; 1103 } 1104 1105 new_link[i]->fw_link_id = IWL_MVM_FW_LINK_ID_INVALID; 1106 iwl_mvm_init_link(new_link[i]); 1107 } 1108 1109 mutex_lock(&mvm->mutex); 1110 1111 /* If we're in RESTART flow, the default link wasn't added in 1112 * drv_add_interface(), and link[0] doesn't point to it. 1113 */ 1114 if (old_links == 0 && !test_bit(IWL_MVM_STATUS_IN_HW_RESTART, 1115 &mvm->status)) { 1116 err = iwl_mvm_disable_link(mvm, vif, &vif->bss_conf); 1117 if (err) 1118 goto out_err; 1119 mvmvif->link[0] = NULL; 1120 } 1121 1122 for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { 1123 if (removed & BIT(i)) { 1124 struct ieee80211_bss_conf *link_conf = old[i]; 1125 1126 err = iwl_mvm_disable_link(mvm, vif, link_conf); 1127 if (err) 1128 goto out_err; 1129 kfree(mvmvif->link[i]); 1130 mvmvif->link[i] = NULL; 1131 } else if (added & BIT(i)) { 1132 struct ieee80211_bss_conf *link_conf; 1133 1134 link_conf = link_conf_dereference_protected(vif, i); 1135 if (WARN_ON(!link_conf)) 1136 continue; 1137 1138 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, 1139 &mvm->status)) 1140 mvmvif->link[i] = new_link[i]; 1141 new_link[i] = NULL; 1142 err = iwl_mvm_add_link(mvm, vif, link_conf); 1143 if (err) 1144 goto out_err; 1145 } 1146 } 1147 1148 err = 0; 1149 if (new_links == 0) { 1150 mvmvif->link[0] = &mvmvif->deflink; 1151 err = iwl_mvm_add_link(mvm, vif, &vif->bss_conf); 1152 if (err == 0) 1153 mvmvif->primary_link = 0; 1154 } else if (!(new_links & BIT(mvmvif->primary_link))) { 1155 /* 1156 * Ensure we always have a valid primary_link, the real 1157 * decision happens later when PHY is activated. 1158 */ 1159 mvmvif->primary_link = __ffs(new_links); 1160 } 1161 1162 out_err: 1163 /* we really don't have a good way to roll back here ... */ 1164 mutex_unlock(&mvm->mutex); 1165 1166 free: 1167 for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) 1168 kfree(new_link[i]); 1169 return err; 1170 } 1171 1172 static int 1173 iwl_mvm_mld_change_sta_links(struct ieee80211_hw *hw, 1174 struct ieee80211_vif *vif, 1175 struct ieee80211_sta *sta, 1176 u16 old_links, u16 new_links) 1177 { 1178 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1179 1180 guard(mvm)(mvm); 1181 return iwl_mvm_mld_update_sta_links(mvm, vif, sta, old_links, new_links); 1182 } 1183 1184 bool iwl_mvm_vif_has_esr_cap(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 1185 { 1186 const struct wiphy_iftype_ext_capab *ext_capa; 1187 1188 lockdep_assert_held(&mvm->mutex); 1189 1190 if (!ieee80211_vif_is_mld(vif) || !vif->cfg.assoc || 1191 hweight16(ieee80211_vif_usable_links(vif)) == 1) 1192 return false; 1193 1194 if (!(vif->cfg.eml_cap & IEEE80211_EML_CAP_EMLSR_SUPP)) 1195 return false; 1196 1197 ext_capa = cfg80211_get_iftype_ext_capa(mvm->hw->wiphy, 1198 ieee80211_vif_type_p2p(vif)); 1199 return (ext_capa && 1200 (ext_capa->eml_capabilities & IEEE80211_EML_CAP_EMLSR_SUPP)); 1201 } 1202 1203 static bool iwl_mvm_mld_can_activate_links(struct ieee80211_hw *hw, 1204 struct ieee80211_vif *vif, 1205 u16 desired_links) 1206 { 1207 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1208 int n_links = hweight16(desired_links); 1209 1210 if (n_links <= 1) 1211 return true; 1212 1213 guard(mvm)(mvm); 1214 1215 /* Check if HW supports the wanted number of links */ 1216 if (n_links > iwl_mvm_max_active_links(mvm, vif)) 1217 return false; 1218 1219 /* If it is an eSR device, check that we can enter eSR */ 1220 return iwl_mvm_is_esr_supported(mvm->fwrt.trans) && 1221 iwl_mvm_vif_has_esr_cap(mvm, vif); 1222 } 1223 1224 static enum ieee80211_neg_ttlm_res 1225 iwl_mvm_mld_can_neg_ttlm(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1226 struct ieee80211_neg_ttlm *neg_ttlm) 1227 { 1228 u16 map; 1229 u8 i; 1230 1231 /* Verify all TIDs are mapped to the same links set */ 1232 map = neg_ttlm->downlink[0]; 1233 for (i = 0; i < IEEE80211_TTLM_NUM_TIDS; i++) { 1234 if (neg_ttlm->downlink[i] != neg_ttlm->uplink[i] || 1235 neg_ttlm->uplink[i] != map) 1236 return NEG_TTLM_RES_REJECT; 1237 } 1238 1239 return NEG_TTLM_RES_ACCEPT; 1240 } 1241 1242 static int 1243 iwl_mvm_mld_mac_pre_channel_switch(struct ieee80211_hw *hw, 1244 struct ieee80211_vif *vif, 1245 struct ieee80211_channel_switch *chsw) 1246 { 1247 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 1248 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1249 int ret; 1250 1251 mutex_lock(&mvm->mutex); 1252 if (mvmvif->esr_active) { 1253 u8 primary = iwl_mvm_get_primary_link(vif); 1254 int selected; 1255 1256 /* prefer primary unless quiet CSA on it */ 1257 if (chsw->link_id == primary && chsw->block_tx) 1258 selected = iwl_mvm_get_other_link(vif, primary); 1259 else 1260 selected = primary; 1261 1262 /* 1263 * remembers to tell the firmware that this link can't tx 1264 * Note that this logic seems to be unrelated to esr, but it 1265 * really is needed only when esr is active. When we have a 1266 * single link, the firmware will handle all this on its own. 1267 * In multi-link scenarios, we can learn about the CSA from 1268 * another link and this logic is too complex for the firmware 1269 * to track. 1270 * Since we want to de-activate the link that got a CSA, we 1271 * need to tell the firmware not to send any frame on that link 1272 * as the firmware may not be aware that link is under a CSA 1273 * with mode=1 (no Tx allowed). 1274 */ 1275 if (chsw->block_tx && mvmvif->link[chsw->link_id]) 1276 mvmvif->link[chsw->link_id]->csa_block_tx = true; 1277 1278 iwl_mvm_exit_esr(mvm, vif, IWL_MVM_ESR_EXIT_CSA, selected); 1279 mutex_unlock(&mvm->mutex); 1280 1281 /* 1282 * If we've not kept the link active that's doing the CSA 1283 * then we don't need to do anything else, just return. 1284 */ 1285 if (selected != chsw->link_id) 1286 return 0; 1287 1288 mutex_lock(&mvm->mutex); 1289 } 1290 1291 ret = iwl_mvm_pre_channel_switch(mvm, vif, chsw); 1292 mutex_unlock(&mvm->mutex); 1293 1294 return ret; 1295 } 1296 1297 #define IWL_MVM_MLD_UNBLOCK_ESR_NON_BSS_TIMEOUT (5 * HZ) 1298 1299 static void iwl_mvm_mld_prep_add_interface(struct ieee80211_hw *hw, 1300 enum nl80211_iftype type) 1301 { 1302 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1303 struct ieee80211_vif *bss_vif = iwl_mvm_get_bss_vif(mvm); 1304 struct iwl_mvm_vif *mvmvif; 1305 int ret; 1306 1307 IWL_DEBUG_MAC80211(mvm, "prep_add_interface: type=%u\n", 1308 type); 1309 1310 if (IS_ERR_OR_NULL(bss_vif) || 1311 !(type == NL80211_IFTYPE_AP || 1312 type == NL80211_IFTYPE_P2P_GO || 1313 type == NL80211_IFTYPE_P2P_CLIENT)) 1314 return; 1315 1316 mvmvif = iwl_mvm_vif_from_mac80211(bss_vif); 1317 ret = iwl_mvm_block_esr_sync(mvm, bss_vif, 1318 IWL_MVM_ESR_BLOCKED_TMP_NON_BSS); 1319 if (ret) 1320 return; 1321 1322 wiphy_delayed_work_queue(mvmvif->mvm->hw->wiphy, 1323 &mvmvif->unblock_esr_tmp_non_bss_wk, 1324 IWL_MVM_MLD_UNBLOCK_ESR_NON_BSS_TIMEOUT); 1325 } 1326 1327 const struct ieee80211_ops iwl_mvm_mld_hw_ops = { 1328 .tx = iwl_mvm_mac_tx, 1329 .wake_tx_queue = iwl_mvm_mac_wake_tx_queue, 1330 .ampdu_action = iwl_mvm_mac_ampdu_action, 1331 .get_antenna = iwl_mvm_op_get_antenna, 1332 .set_antenna = iwl_mvm_op_set_antenna, 1333 .start = iwl_mvm_mac_start, 1334 .reconfig_complete = iwl_mvm_mac_reconfig_complete, 1335 .stop = iwl_mvm_mac_stop, 1336 .add_interface = iwl_mvm_mld_mac_add_interface, 1337 .remove_interface = iwl_mvm_mld_mac_remove_interface, 1338 .config = iwl_mvm_mac_config, 1339 .prepare_multicast = iwl_mvm_prepare_multicast, 1340 .configure_filter = iwl_mvm_configure_filter, 1341 .config_iface_filter = iwl_mvm_mld_config_iface_filter, 1342 .link_info_changed = iwl_mvm_mld_link_info_changed, 1343 .vif_cfg_changed = iwl_mvm_mld_vif_cfg_changed, 1344 .hw_scan = iwl_mvm_mac_hw_scan, 1345 .cancel_hw_scan = iwl_mvm_mac_cancel_hw_scan, 1346 .sta_pre_rcu_remove = iwl_mvm_sta_pre_rcu_remove, 1347 .sta_state = iwl_mvm_mld_mac_sta_state, 1348 .sta_notify = iwl_mvm_mac_sta_notify, 1349 .allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames, 1350 .release_buffered_frames = iwl_mvm_mac_release_buffered_frames, 1351 .set_rts_threshold = iwl_mvm_mac_set_rts_threshold, 1352 .link_sta_rc_update = iwl_mvm_sta_rc_update, 1353 .conf_tx = iwl_mvm_mld_mac_conf_tx, 1354 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx, 1355 .mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx, 1356 .mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover, 1357 .flush = iwl_mvm_mac_flush, 1358 .flush_sta = iwl_mvm_mac_flush_sta, 1359 .sched_scan_start = iwl_mvm_mac_sched_scan_start, 1360 .sched_scan_stop = iwl_mvm_mac_sched_scan_stop, 1361 .set_key = iwl_mvm_mac_set_key, 1362 .update_tkip_key = iwl_mvm_mac_update_tkip_key, 1363 .remain_on_channel = iwl_mvm_mld_roc, 1364 .cancel_remain_on_channel = iwl_mvm_cancel_roc, 1365 .add_chanctx = iwl_mvm_add_chanctx, 1366 .remove_chanctx = iwl_mvm_remove_chanctx, 1367 .change_chanctx = iwl_mvm_change_chanctx, 1368 .assign_vif_chanctx = iwl_mvm_mld_assign_vif_chanctx, 1369 .unassign_vif_chanctx = iwl_mvm_mld_unassign_vif_chanctx, 1370 .switch_vif_chanctx = iwl_mvm_mld_switch_vif_chanctx, 1371 1372 .start_ap = iwl_mvm_mld_start_ap, 1373 .stop_ap = iwl_mvm_mld_stop_ap, 1374 .join_ibss = iwl_mvm_mld_start_ibss, 1375 .leave_ibss = iwl_mvm_mld_stop_ibss, 1376 1377 .tx_last_beacon = iwl_mvm_tx_last_beacon, 1378 1379 .channel_switch = iwl_mvm_channel_switch, 1380 .pre_channel_switch = iwl_mvm_mld_mac_pre_channel_switch, 1381 .post_channel_switch = iwl_mvm_post_channel_switch, 1382 .abort_channel_switch = iwl_mvm_abort_channel_switch, 1383 .channel_switch_rx_beacon = iwl_mvm_channel_switch_rx_beacon, 1384 1385 .tdls_channel_switch = iwl_mvm_tdls_channel_switch, 1386 .tdls_cancel_channel_switch = iwl_mvm_tdls_cancel_channel_switch, 1387 .tdls_recv_channel_switch = iwl_mvm_tdls_recv_channel_switch, 1388 1389 .event_callback = iwl_mvm_mac_event_callback, 1390 1391 .sync_rx_queues = iwl_mvm_sync_rx_queues, 1392 1393 #ifdef CONFIG_PM_SLEEP 1394 /* look at d3.c */ 1395 .suspend = iwl_mvm_suspend, 1396 .resume = iwl_mvm_resume, 1397 .set_wakeup = iwl_mvm_set_wakeup, 1398 .set_rekey_data = iwl_mvm_set_rekey_data, 1399 #if IS_ENABLED(CONFIG_IPV6) 1400 .ipv6_addr_change = iwl_mvm_ipv6_addr_change, 1401 #endif 1402 .set_default_unicast_key = iwl_mvm_set_default_unicast_key, 1403 #endif 1404 .get_survey = iwl_mvm_mac_get_survey, 1405 .sta_statistics = iwl_mvm_mac_sta_statistics, 1406 .get_ftm_responder_stats = iwl_mvm_mac_get_ftm_responder_stats, 1407 .start_pmsr = iwl_mvm_start_pmsr, 1408 .abort_pmsr = iwl_mvm_abort_pmsr, 1409 1410 #ifdef CONFIG_IWLWIFI_DEBUGFS 1411 .vif_add_debugfs = iwl_mvm_vif_add_debugfs, 1412 .link_add_debugfs = iwl_mvm_link_add_debugfs, 1413 .link_sta_add_debugfs = iwl_mvm_link_sta_add_debugfs, 1414 #endif 1415 .set_hw_timestamp = iwl_mvm_set_hw_timestamp, 1416 1417 .change_vif_links = iwl_mvm_mld_change_vif_links, 1418 .change_sta_links = iwl_mvm_mld_change_sta_links, 1419 .can_activate_links = iwl_mvm_mld_can_activate_links, 1420 .can_neg_ttlm = iwl_mvm_mld_can_neg_ttlm, 1421 .prep_add_interface = iwl_mvm_mld_prep_add_interface, 1422 }; 1423