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