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