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