1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* 3 * Copyright (C) 2022 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 14 mutex_lock(&mvm->mutex); 15 16 mvmvif->mvm = mvm; 17 18 /* Not much to do here. The stack will not allow interface 19 * types or combinations that we didn't advertise, so we 20 * don't really have to check the types. 21 */ 22 23 /* make sure that beacon statistics don't go backwards with FW reset */ 24 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) 25 mvmvif->deflink.beacon_stats.accu_num_beacons += 26 mvmvif->deflink.beacon_stats.num_beacons; 27 28 /* Allocate resources for the MAC context, and add it to the fw */ 29 ret = iwl_mvm_mac_ctxt_init(mvm, vif); 30 if (ret) 31 goto out_unlock; 32 33 rcu_assign_pointer(mvm->vif_id_to_mac[mvmvif->id], vif); 34 35 mvmvif->features |= hw->netdev_features; 36 37 /* reset deflink MLO parameters */ 38 mvmvif->deflink.fw_link_id = IWL_MVM_FW_LINK_ID_INVALID; 39 mvmvif->deflink.active = 0; 40 /* the first link always points to the default one */ 41 mvmvif->link[0] = &mvmvif->deflink; 42 43 ret = iwl_mvm_mld_mac_ctxt_add(mvm, vif); 44 if (ret) 45 goto out_unlock; 46 47 /* beacon filtering */ 48 ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0); 49 if (ret) 50 goto out_remove_mac; 51 52 if (!mvm->bf_allowed_vif && 53 vif->type == NL80211_IFTYPE_STATION && !vif->p2p) { 54 mvm->bf_allowed_vif = mvmvif; 55 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | 56 IEEE80211_VIF_SUPPORTS_CQM_RSSI; 57 } 58 59 /* 60 * P2P_DEVICE interface does not have a channel context assigned to it, 61 * so a dedicated PHY context is allocated to it and the corresponding 62 * MAC context is bound to it at this stage. 63 */ 64 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { 65 mvmvif->deflink.phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm); 66 if (!mvmvif->deflink.phy_ctxt) { 67 ret = -ENOSPC; 68 goto out_free_bf; 69 } 70 71 iwl_mvm_phy_ctxt_ref(mvm, mvmvif->deflink.phy_ctxt); 72 ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf); 73 if (ret) 74 goto out_unref_phy; 75 76 ret = iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, 77 LINK_CONTEXT_MODIFY_ACTIVE | 78 LINK_CONTEXT_MODIFY_RATES_INFO, 79 true); 80 if (ret) 81 goto out_remove_link; 82 83 ret = iwl_mvm_mld_add_bcast_sta(mvm, vif, &vif->bss_conf); 84 if (ret) 85 goto out_remove_link; 86 87 /* Save a pointer to p2p device vif, so it can later be used to 88 * update the p2p device MAC when a GO is started/stopped 89 */ 90 mvm->p2p_device_vif = vif; 91 } else { 92 ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf); 93 if (ret) 94 goto out_free_bf; 95 } 96 97 ret = iwl_mvm_power_update_mac(mvm); 98 if (ret) 99 goto out_free_bf; 100 101 iwl_mvm_tcm_add_vif(mvm, vif); 102 INIT_DELAYED_WORK(&mvmvif->csa_work, 103 iwl_mvm_channel_switch_disconnect_wk); 104 105 if (vif->type == NL80211_IFTYPE_MONITOR) { 106 mvm->monitor_on = true; 107 ieee80211_hw_set(mvm->hw, RX_INCLUDES_FCS); 108 } 109 110 iwl_mvm_vif_dbgfs_register(mvm, vif); 111 112 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && 113 vif->type == NL80211_IFTYPE_STATION && !vif->p2p && 114 !mvm->csme_vif && mvm->mei_registered) { 115 iwl_mei_set_nic_info(vif->addr, mvm->nvm_data->hw_addr); 116 iwl_mei_set_netdev(ieee80211_vif_to_wdev(vif)->netdev); 117 mvm->csme_vif = vif; 118 } 119 120 goto out_unlock; 121 122 out_remove_link: 123 iwl_mvm_disable_link(mvm, vif, &vif->bss_conf); 124 out_unref_phy: 125 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt); 126 out_free_bf: 127 if (mvm->bf_allowed_vif == mvmvif) { 128 mvm->bf_allowed_vif = NULL; 129 vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER | 130 IEEE80211_VIF_SUPPORTS_CQM_RSSI); 131 } 132 out_remove_mac: 133 mvmvif->deflink.phy_ctxt = NULL; 134 mvmvif->link[0] = NULL; 135 iwl_mvm_mld_mac_ctxt_remove(mvm, vif); 136 out_unlock: 137 mutex_unlock(&mvm->mutex); 138 139 return ret; 140 } 141 142 static void iwl_mvm_mld_mac_remove_interface(struct ieee80211_hw *hw, 143 struct ieee80211_vif *vif) 144 { 145 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 146 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 147 struct iwl_probe_resp_data *probe_data; 148 149 iwl_mvm_prepare_mac_removal(mvm, vif); 150 151 if (!(vif->type == NL80211_IFTYPE_AP || 152 vif->type == NL80211_IFTYPE_ADHOC)) 153 iwl_mvm_tcm_rm_vif(mvm, vif); 154 155 mutex_lock(&mvm->mutex); 156 157 if (vif == mvm->csme_vif) { 158 iwl_mei_set_netdev(NULL); 159 mvm->csme_vif = NULL; 160 } 161 162 if (mvm->bf_allowed_vif == mvmvif) { 163 mvm->bf_allowed_vif = NULL; 164 vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER | 165 IEEE80211_VIF_SUPPORTS_CQM_RSSI); 166 } 167 168 if (vif->bss_conf.ftm_responder) 169 memset(&mvm->ftm_resp_stats, 0, sizeof(mvm->ftm_resp_stats)); 170 171 iwl_mvm_vif_dbgfs_clean(mvm, vif); 172 173 /* For AP/GO interface, the tear down of the resources allocated to the 174 * interface is be handled as part of the stop_ap flow. 175 */ 176 if (vif->type == NL80211_IFTYPE_AP || 177 vif->type == NL80211_IFTYPE_ADHOC) { 178 #ifdef CONFIG_NL80211_TESTMODE 179 if (vif == mvm->noa_vif) { 180 mvm->noa_vif = NULL; 181 mvm->noa_duration = 0; 182 } 183 #endif 184 } 185 186 iwl_mvm_power_update_mac(mvm); 187 188 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { 189 mvm->p2p_device_vif = NULL; 190 191 /* P2P device uses only one link */ 192 iwl_mvm_mld_rm_bcast_sta(mvm, vif, &vif->bss_conf); 193 iwl_mvm_disable_link(mvm, vif, &vif->bss_conf); 194 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt); 195 mvmvif->deflink.phy_ctxt = NULL; 196 } else { 197 iwl_mvm_disable_link(mvm, vif, &vif->bss_conf); 198 } 199 200 iwl_mvm_mld_mac_ctxt_remove(mvm, vif); 201 202 RCU_INIT_POINTER(mvm->vif_id_to_mac[mvmvif->id], NULL); 203 204 probe_data = rcu_dereference_protected(mvmvif->deflink.probe_resp_data, 205 lockdep_is_held(&mvm->mutex)); 206 RCU_INIT_POINTER(mvmvif->deflink.probe_resp_data, NULL); 207 if (probe_data) 208 kfree_rcu(probe_data, rcu_head); 209 210 if (vif->type == NL80211_IFTYPE_MONITOR) { 211 mvm->monitor_on = false; 212 __clear_bit(IEEE80211_HW_RX_INCLUDES_FCS, mvm->hw->flags); 213 } 214 215 mutex_unlock(&mvm->mutex); 216 } 217 218 static int 219 __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm, 220 struct ieee80211_vif *vif, 221 struct ieee80211_bss_conf *link_conf, 222 struct ieee80211_chanctx_conf *ctx, 223 bool switching_chanctx) 224 { 225 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv; 226 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id]; 227 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 228 unsigned int link_id = link_conf->link_id; 229 int ret; 230 231 if (WARN_ON_ONCE(!mvmvif->link[link_id])) 232 return -EINVAL; 233 234 /* mac parameters such as HE support can change at this stage 235 * For sta, need first to configure correct state from drv_sta_state 236 * and only after that update mac config. 237 */ 238 if (vif->type == NL80211_IFTYPE_AP) { 239 ret = iwl_mvm_mld_mac_ctxt_changed(mvm, vif, false); 240 if (ret) { 241 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); 242 return -EINVAL; 243 } 244 } 245 246 mvmvif->link[link_id]->phy_ctxt = phy_ctxt; 247 248 if (switching_chanctx) { 249 /* reactivate if we turned this off during channel switch */ 250 if (vif->type == NL80211_IFTYPE_AP) 251 mvmvif->ap_ibss_active = true; 252 } 253 254 /* send it first with phy context ID */ 255 ret = iwl_mvm_link_changed(mvm, vif, link_conf, 0, false); 256 if (ret) 257 goto out; 258 259 /* Initialize rate control for the AP station, since we might be 260 * doing a link switch here - we cannot initialize it before since 261 * this needs the phy context assigned (and in FW?), and we cannot 262 * do it later because it needs to be initialized as soon as we're 263 * able to TX on the link, i.e. when active. 264 * 265 * Firmware restart isn't quite correct yet for MLO, but we don't 266 * need to do it in that case anyway since it will happen from the 267 * normal station state callback. 268 */ 269 if (mvmvif->ap_sta && 270 !test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { 271 struct ieee80211_link_sta *link_sta; 272 273 rcu_read_lock(); 274 link_sta = rcu_dereference(mvmvif->ap_sta->link[link_id]); 275 276 if (!WARN_ON_ONCE(!link_sta)) 277 iwl_mvm_rs_rate_init(mvm, vif, mvmvif->ap_sta, 278 link_conf, link_sta, 279 phy_ctxt->channel->band); 280 rcu_read_unlock(); 281 } 282 283 /* then activate */ 284 ret = iwl_mvm_link_changed(mvm, vif, link_conf, 285 LINK_CONTEXT_MODIFY_ACTIVE | 286 LINK_CONTEXT_MODIFY_RATES_INFO, 287 true); 288 if (ret) 289 goto out; 290 291 /* 292 * Power state must be updated before quotas, 293 * otherwise fw will complain. 294 */ 295 iwl_mvm_power_update_mac(mvm); 296 297 if (vif->type == NL80211_IFTYPE_MONITOR) { 298 ret = iwl_mvm_mld_add_snif_sta(mvm, vif, link_conf); 299 if (ret) 300 goto deactivate; 301 } 302 303 return 0; 304 305 deactivate: 306 iwl_mvm_link_changed(mvm, vif, link_conf, LINK_CONTEXT_MODIFY_ACTIVE, 307 false); 308 out: 309 mvmvif->link[link_id]->phy_ctxt = NULL; 310 iwl_mvm_power_update_mac(mvm); 311 return ret; 312 } 313 314 static int iwl_mvm_mld_assign_vif_chanctx(struct ieee80211_hw *hw, 315 struct ieee80211_vif *vif, 316 struct ieee80211_bss_conf *link_conf, 317 struct ieee80211_chanctx_conf *ctx) 318 { 319 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 320 int ret; 321 322 mutex_lock(&mvm->mutex); 323 ret = __iwl_mvm_mld_assign_vif_chanctx(mvm, vif, link_conf, ctx, false); 324 mutex_unlock(&mvm->mutex); 325 326 return ret; 327 } 328 329 static void 330 __iwl_mvm_mld_unassign_vif_chanctx(struct iwl_mvm *mvm, 331 struct ieee80211_vif *vif, 332 struct ieee80211_bss_conf *link_conf, 333 struct ieee80211_chanctx_conf *ctx, 334 bool switching_chanctx) 335 { 336 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 337 unsigned int link_id = link_conf->link_id; 338 339 /* shouldn't happen, but verify link_id is valid before accessing */ 340 if (WARN_ON_ONCE(!mvmvif->link[link_id])) 341 return; 342 343 if (vif->type == NL80211_IFTYPE_AP && switching_chanctx) { 344 mvmvif->csa_countdown = false; 345 346 /* Set CS bit on all the stations */ 347 iwl_mvm_modify_all_sta_disable_tx(mvm, mvmvif, true); 348 349 /* Save blocked iface, the timeout is set on the next beacon */ 350 rcu_assign_pointer(mvm->csa_tx_blocked_vif, vif); 351 352 mvmvif->ap_ibss_active = false; 353 } 354 355 if (vif->type == NL80211_IFTYPE_MONITOR) 356 iwl_mvm_mld_rm_snif_sta(mvm, vif); 357 358 iwl_mvm_link_changed(mvm, vif, link_conf, 359 LINK_CONTEXT_MODIFY_ACTIVE, false); 360 361 if (switching_chanctx) 362 return; 363 mvmvif->link[link_id]->phy_ctxt = NULL; 364 iwl_mvm_power_update_mac(mvm); 365 } 366 367 static void iwl_mvm_mld_unassign_vif_chanctx(struct ieee80211_hw *hw, 368 struct ieee80211_vif *vif, 369 struct ieee80211_bss_conf *link_conf, 370 struct ieee80211_chanctx_conf *ctx) 371 { 372 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 373 374 mutex_lock(&mvm->mutex); 375 __iwl_mvm_mld_unassign_vif_chanctx(mvm, vif, link_conf, ctx, false); 376 mutex_unlock(&mvm->mutex); 377 } 378 379 static int iwl_mvm_mld_start_ap_ibss(struct ieee80211_hw *hw, 380 struct ieee80211_vif *vif, 381 struct ieee80211_bss_conf *link_conf) 382 { 383 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 384 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 385 int ret; 386 387 mutex_lock(&mvm->mutex); 388 /* Send the beacon template */ 389 ret = iwl_mvm_mac_ctxt_beacon_changed(mvm, vif, link_conf); 390 if (ret) 391 goto out_unlock; 392 393 /* the link should be already activated when assigning chan context */ 394 ret = iwl_mvm_link_changed(mvm, vif, link_conf, 395 LINK_CONTEXT_MODIFY_ALL & 396 ~LINK_CONTEXT_MODIFY_ACTIVE, 397 true); 398 if (ret) 399 goto out_unlock; 400 401 ret = iwl_mvm_mld_add_mcast_sta(mvm, vif, link_conf); 402 if (ret) 403 goto out_unlock; 404 405 /* Send the bcast station. At this stage the TBTT and DTIM time 406 * events are added and applied to the scheduler 407 */ 408 ret = iwl_mvm_mld_add_bcast_sta(mvm, vif, link_conf); 409 if (ret) 410 goto out_rm_mcast; 411 412 if (iwl_mvm_start_ap_ibss_common(hw, vif, &ret)) 413 goto out_failed; 414 415 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ 416 if (vif->p2p && mvm->p2p_device_vif) 417 iwl_mvm_mld_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false); 418 419 iwl_mvm_bt_coex_vif_change(mvm); 420 421 /* we don't support TDLS during DCM */ 422 if (iwl_mvm_phy_ctx_count(mvm) > 1) 423 iwl_mvm_teardown_tdls_peers(mvm); 424 425 iwl_mvm_ftm_restart_responder(mvm, vif); 426 427 goto out_unlock; 428 429 out_failed: 430 iwl_mvm_power_update_mac(mvm); 431 mvmvif->ap_ibss_active = false; 432 iwl_mvm_mld_rm_bcast_sta(mvm, vif, link_conf); 433 out_rm_mcast: 434 iwl_mvm_mld_rm_mcast_sta(mvm, vif, link_conf); 435 out_unlock: 436 mutex_unlock(&mvm->mutex); 437 return ret; 438 } 439 440 static int iwl_mvm_mld_start_ap(struct ieee80211_hw *hw, 441 struct ieee80211_vif *vif, 442 struct ieee80211_bss_conf *link_conf) 443 { 444 return iwl_mvm_mld_start_ap_ibss(hw, vif, link_conf); 445 } 446 447 static int iwl_mvm_mld_start_ibss(struct ieee80211_hw *hw, 448 struct ieee80211_vif *vif) 449 { 450 return iwl_mvm_mld_start_ap_ibss(hw, vif, &vif->bss_conf); 451 } 452 453 static void iwl_mvm_mld_stop_ap_ibss(struct ieee80211_hw *hw, 454 struct ieee80211_vif *vif, 455 struct ieee80211_bss_conf *link_conf) 456 { 457 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 458 459 mutex_lock(&mvm->mutex); 460 461 iwl_mvm_stop_ap_ibss_common(mvm, vif); 462 463 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ 464 if (vif->p2p && mvm->p2p_device_vif) 465 iwl_mvm_mld_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false); 466 467 iwl_mvm_ftm_responder_clear(mvm, vif); 468 469 iwl_mvm_mld_rm_bcast_sta(mvm, vif, link_conf); 470 iwl_mvm_mld_rm_mcast_sta(mvm, vif, link_conf); 471 472 iwl_mvm_power_update_mac(mvm); 473 mutex_unlock(&mvm->mutex); 474 } 475 476 static void iwl_mvm_mld_stop_ap(struct ieee80211_hw *hw, 477 struct ieee80211_vif *vif, 478 struct ieee80211_bss_conf *link_conf) 479 { 480 iwl_mvm_mld_stop_ap_ibss(hw, vif, link_conf); 481 } 482 483 static void iwl_mvm_mld_stop_ibss(struct ieee80211_hw *hw, 484 struct ieee80211_vif *vif) 485 { 486 iwl_mvm_mld_stop_ap_ibss(hw, vif, &vif->bss_conf); 487 } 488 489 static int iwl_mvm_mld_mac_sta_state(struct ieee80211_hw *hw, 490 struct ieee80211_vif *vif, 491 struct ieee80211_sta *sta, 492 enum ieee80211_sta_state old_state, 493 enum ieee80211_sta_state new_state) 494 { 495 struct iwl_mvm_sta_state_ops callbacks = { 496 .add_sta = iwl_mvm_mld_add_sta, 497 .update_sta = iwl_mvm_mld_update_sta, 498 .rm_sta = iwl_mvm_mld_rm_sta, 499 .mac_ctxt_changed = iwl_mvm_mld_mac_ctxt_changed, 500 }; 501 502 return iwl_mvm_mac_sta_state_common(hw, vif, sta, old_state, new_state, 503 &callbacks); 504 } 505 506 static void 507 iwl_mvm_mld_link_info_changed_station(struct iwl_mvm *mvm, 508 struct ieee80211_vif *vif, 509 struct ieee80211_bss_conf *link_conf, 510 u64 changes) 511 { 512 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 513 bool has_he, has_eht; 514 u32 link_changes = 0; 515 int ret; 516 517 if (WARN_ON_ONCE(!mvmvif->link[link_conf->link_id])) 518 return; 519 520 has_he = link_conf->he_support && !iwlwifi_mod_params.disable_11ax; 521 has_eht = link_conf->eht_support && !iwlwifi_mod_params.disable_11be; 522 523 /* Update EDCA params */ 524 if (changes & BSS_CHANGED_QOS && vif->cfg.assoc && link_conf->qos) 525 link_changes |= LINK_CONTEXT_MODIFY_QOS_PARAMS; 526 527 if (changes & BSS_CHANGED_ERP_SLOT) 528 link_changes |= LINK_CONTEXT_MODIFY_RATES_INFO; 529 530 if (vif->cfg.assoc && (has_he || has_eht)) { 531 IWL_DEBUG_MAC80211(mvm, "Associated in HE mode\n"); 532 link_changes |= LINK_CONTEXT_MODIFY_HE_PARAMS; 533 } 534 535 /* Update EHT Puncturing info */ 536 if (changes & BSS_CHANGED_EHT_PUNCTURING && vif->cfg.assoc && has_eht) 537 link_changes |= LINK_CONTEXT_MODIFY_EHT_PARAMS; 538 539 if (link_changes) { 540 ret = iwl_mvm_link_changed(mvm, vif, link_conf, link_changes, 541 true); 542 if (ret) 543 IWL_ERR(mvm, "failed to update link\n"); 544 } 545 546 ret = iwl_mvm_mld_mac_ctxt_changed(mvm, vif, false); 547 if (ret) 548 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); 549 550 memcpy(mvmvif->link[link_conf->link_id]->bssid, link_conf->bssid, 551 ETH_ALEN); 552 553 iwl_mvm_bss_info_changed_station_common(mvm, vif, link_conf, changes); 554 } 555 556 static bool iwl_mvm_mld_vif_have_valid_ap_sta(struct iwl_mvm_vif *mvmvif) 557 { 558 int i; 559 560 for_each_mvm_vif_valid_link(mvmvif, i) { 561 if (mvmvif->link[i]->ap_sta_id != IWL_MVM_INVALID_STA) 562 return true; 563 } 564 565 return false; 566 } 567 568 static void iwl_mvm_mld_vif_delete_all_stas(struct iwl_mvm *mvm, 569 struct ieee80211_vif *vif) 570 { 571 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 572 int i, ret; 573 574 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) 575 return; 576 577 for_each_mvm_vif_valid_link(mvmvif, i) { 578 struct iwl_mvm_vif_link_info *link = mvmvif->link[i]; 579 580 if (!link) 581 continue; 582 583 iwl_mvm_sec_key_remove_ap(mvm, vif, link, i); 584 ret = iwl_mvm_mld_rm_sta_id(mvm, link->ap_sta_id); 585 if (ret) 586 IWL_ERR(mvm, "failed to remove AP station\n"); 587 588 link->ap_sta_id = IWL_MVM_INVALID_STA; 589 } 590 } 591 592 static void iwl_mvm_mld_vif_cfg_changed_station(struct iwl_mvm *mvm, 593 struct ieee80211_vif *vif, 594 u64 changes) 595 { 596 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 597 struct ieee80211_bss_conf *link_conf; 598 bool protect = false; 599 unsigned int i; 600 int ret; 601 602 /* This might get called without active links during the 603 * chanctx switch, but we don't care about it anyway. 604 */ 605 if (changes == BSS_CHANGED_IDLE) 606 return; 607 608 ret = iwl_mvm_mld_mac_ctxt_changed(mvm, vif, false); 609 if (ret) 610 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); 611 612 mvmvif->associated = vif->cfg.assoc; 613 614 if (!(changes & BSS_CHANGED_ASSOC)) 615 return; 616 617 if (vif->cfg.assoc) { 618 /* clear statistics to get clean beacon counter */ 619 iwl_mvm_request_statistics(mvm, true); 620 iwl_mvm_sf_update(mvm, vif, false); 621 iwl_mvm_power_vif_assoc(mvm, vif); 622 623 for_each_mvm_vif_valid_link(mvmvif, i) { 624 memset(&mvmvif->link[i]->beacon_stats, 0, 625 sizeof(mvmvif->link[i]->beacon_stats)); 626 627 if (vif->p2p) { 628 iwl_mvm_update_smps(mvm, vif, 629 IWL_MVM_SMPS_REQ_PROT, 630 IEEE80211_SMPS_DYNAMIC, i); 631 } 632 633 rcu_read_lock(); 634 link_conf = rcu_dereference(vif->link_conf[i]); 635 if (link_conf && !link_conf->dtim_period) 636 protect = true; 637 rcu_read_unlock(); 638 } 639 640 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && 641 protect) { 642 /* If we're not restarting and still haven't 643 * heard a beacon (dtim period unknown) then 644 * make sure we still have enough minimum time 645 * remaining in the time event, since the auth 646 * might actually have taken quite a while 647 * (especially for SAE) and so the remaining 648 * time could be small without us having heard 649 * a beacon yet. 650 */ 651 iwl_mvm_protect_assoc(mvm, vif, 0); 652 } 653 654 iwl_mvm_sf_update(mvm, vif, false); 655 656 /* FIXME: need to decide about misbehaving AP handling */ 657 iwl_mvm_power_vif_assoc(mvm, vif); 658 } else if (iwl_mvm_mld_vif_have_valid_ap_sta(mvmvif)) { 659 iwl_mvm_mei_host_disassociated(mvm); 660 661 /* If update fails - SF might be running in associated 662 * mode while disassociated - which is forbidden. 663 */ 664 ret = iwl_mvm_sf_update(mvm, vif, false); 665 WARN_ONCE(ret && 666 !test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, 667 &mvm->status), 668 "Failed to update SF upon disassociation\n"); 669 670 /* If we get an assert during the connection (after the 671 * station has been added, but before the vif is set 672 * to associated), mac80211 will re-add the station and 673 * then configure the vif. Since the vif is not 674 * associated, we would remove the station here and 675 * this would fail the recovery. 676 */ 677 iwl_mvm_mld_vif_delete_all_stas(mvm, vif); 678 } 679 680 iwl_mvm_bss_info_changed_station_assoc(mvm, vif, changes); 681 } 682 683 static void 684 iwl_mvm_mld_link_info_changed_ap_ibss(struct iwl_mvm *mvm, 685 struct ieee80211_vif *vif, 686 struct ieee80211_bss_conf *link_conf, 687 u64 changes) 688 { 689 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 690 u32 link_changes = LINK_CONTEXT_MODIFY_PROTECT_FLAGS | 691 LINK_CONTEXT_MODIFY_QOS_PARAMS; 692 693 /* Changes will be applied when the AP/IBSS is started */ 694 if (!mvmvif->ap_ibss_active) 695 return; 696 697 if (link_conf->he_support) 698 link_changes |= LINK_CONTEXT_MODIFY_HE_PARAMS; 699 700 if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT | 701 BSS_CHANGED_BANDWIDTH | BSS_CHANGED_QOS | 702 BSS_CHANGED_HE_BSS_COLOR) && 703 iwl_mvm_link_changed(mvm, vif, link_conf, 704 link_changes, true)) 705 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); 706 707 /* Need to send a new beacon template to the FW */ 708 if (changes & BSS_CHANGED_BEACON && 709 iwl_mvm_mac_ctxt_beacon_changed(mvm, vif, link_conf)) 710 IWL_WARN(mvm, "Failed updating beacon data\n"); 711 712 /* FIXME: need to decide if we need FTM responder per link */ 713 if (changes & BSS_CHANGED_FTM_RESPONDER) { 714 int ret = iwl_mvm_ftm_start_responder(mvm, vif); 715 716 if (ret) 717 IWL_WARN(mvm, "Failed to enable FTM responder (%d)\n", 718 ret); 719 } 720 } 721 722 static void iwl_mvm_mld_link_info_changed(struct ieee80211_hw *hw, 723 struct ieee80211_vif *vif, 724 struct ieee80211_bss_conf *link_conf, 725 u64 changes) 726 { 727 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 728 729 mutex_lock(&mvm->mutex); 730 731 switch (vif->type) { 732 case NL80211_IFTYPE_STATION: 733 iwl_mvm_mld_link_info_changed_station(mvm, vif, link_conf, 734 changes); 735 break; 736 case NL80211_IFTYPE_AP: 737 case NL80211_IFTYPE_ADHOC: 738 iwl_mvm_mld_link_info_changed_ap_ibss(mvm, vif, link_conf, 739 changes); 740 break; 741 case NL80211_IFTYPE_MONITOR: 742 if (changes & BSS_CHANGED_MU_GROUPS) 743 iwl_mvm_update_mu_groups(mvm, vif); 744 break; 745 default: 746 /* shouldn't happen */ 747 WARN_ON_ONCE(1); 748 } 749 750 if (changes & BSS_CHANGED_TXPOWER) { 751 IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d dBm\n", 752 link_conf->txpower); 753 iwl_mvm_set_tx_power(mvm, vif, link_conf->txpower); 754 } 755 756 mutex_unlock(&mvm->mutex); 757 } 758 759 static void iwl_mvm_mld_vif_cfg_changed(struct ieee80211_hw *hw, 760 struct ieee80211_vif *vif, 761 u64 changes) 762 { 763 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 764 765 mutex_lock(&mvm->mutex); 766 767 if (changes & BSS_CHANGED_IDLE && !vif->cfg.idle) 768 iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true); 769 770 if (vif->type == NL80211_IFTYPE_STATION) 771 iwl_mvm_mld_vif_cfg_changed_station(mvm, vif, changes); 772 773 mutex_unlock(&mvm->mutex); 774 } 775 776 static int 777 iwl_mvm_mld_switch_vif_chanctx(struct ieee80211_hw *hw, 778 struct ieee80211_vif_chanctx_switch *vifs, 779 int n_vifs, 780 enum ieee80211_chanctx_switch_mode mode) 781 { 782 struct iwl_mvm_switch_vif_chanctx_ops ops = { 783 .__assign_vif_chanctx = __iwl_mvm_mld_assign_vif_chanctx, 784 .__unassign_vif_chanctx = __iwl_mvm_mld_unassign_vif_chanctx, 785 }; 786 787 return iwl_mvm_switch_vif_chanctx_common(hw, vifs, n_vifs, mode, &ops); 788 } 789 790 static void iwl_mvm_mld_config_iface_filter(struct ieee80211_hw *hw, 791 struct ieee80211_vif *vif, 792 unsigned int filter_flags, 793 unsigned int changed_flags) 794 { 795 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 796 797 /* We support only filter for probe requests */ 798 if (!(changed_flags & FIF_PROBE_REQ)) 799 return; 800 801 /* Supported only for p2p client interfaces */ 802 if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc || 803 !vif->p2p) 804 return; 805 806 mutex_lock(&mvm->mutex); 807 iwl_mvm_mld_mac_ctxt_changed(mvm, vif, false); 808 mutex_unlock(&mvm->mutex); 809 } 810 811 static int 812 iwl_mvm_mld_mac_conf_tx(struct ieee80211_hw *hw, 813 struct ieee80211_vif *vif, 814 unsigned int link_id, u16 ac, 815 const struct ieee80211_tx_queue_params *params) 816 { 817 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 818 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 819 820 mvmvif->deflink.queue_params[ac] = *params; 821 822 /* No need to update right away, we'll get BSS_CHANGED_QOS 823 * The exception is P2P_DEVICE interface which needs immediate update. 824 */ 825 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { 826 int ret; 827 828 mutex_lock(&mvm->mutex); 829 ret = iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, 830 LINK_CONTEXT_MODIFY_QOS_PARAMS, 831 true); 832 mutex_unlock(&mvm->mutex); 833 return ret; 834 } 835 return 0; 836 } 837 838 static int iwl_mvm_link_switch_phy_ctx(struct iwl_mvm *mvm, 839 struct ieee80211_vif *vif, 840 struct iwl_mvm_phy_ctxt *new_phy_ctxt) 841 { 842 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 843 int ret = 0; 844 845 lockdep_assert_held(&mvm->mutex); 846 847 /* Inorder to change the phy_ctx of a link, the link needs to be 848 * inactive. Therefore, first deactivate the link, then change its 849 * phy_ctx, and then activate it again. 850 */ 851 ret = iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, 852 LINK_CONTEXT_MODIFY_ACTIVE, false); 853 if (WARN(ret, "Failed to deactivate link\n")) 854 return ret; 855 856 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt); 857 858 mvmvif->deflink.phy_ctxt = new_phy_ctxt; 859 860 ret = iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, 0, false); 861 if (WARN(ret, "Failed to deactivate link\n")) 862 return ret; 863 864 ret = iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, 865 LINK_CONTEXT_MODIFY_ACTIVE, true); 866 WARN(ret, "Failed binding P2P_DEVICE\n"); 867 return ret; 868 } 869 870 static int iwl_mvm_mld_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 871 struct ieee80211_channel *channel, int duration, 872 enum ieee80211_roc_type type) 873 { 874 struct iwl_mvm_roc_ops ops = { 875 .add_aux_sta_for_hs20 = iwl_mvm_mld_add_aux_sta, 876 .switch_phy_ctxt = iwl_mvm_link_switch_phy_ctx, 877 }; 878 879 return iwl_mvm_roc_common(hw, vif, channel, duration, type, &ops); 880 } 881 882 static int 883 iwl_mvm_mld_change_vif_links(struct ieee80211_hw *hw, 884 struct ieee80211_vif *vif, 885 u16 old_links, u16 new_links, 886 struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]) 887 { 888 struct iwl_mvm_vif_link_info *new_link[IEEE80211_MLD_MAX_NUM_LINKS] = {}; 889 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 890 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 891 u16 removed = old_links & ~new_links; 892 u16 added = new_links & ~old_links; 893 int err, i; 894 895 if (hweight16(new_links) > 2) { 896 return -EOPNOTSUPP; 897 } else if (hweight16(new_links) > 1) { 898 unsigned int n_active = 0; 899 900 for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { 901 struct ieee80211_bss_conf *link_conf; 902 903 link_conf = link_conf_dereference_protected(vif, i); 904 if (link_conf && 905 rcu_access_pointer(link_conf->chanctx_conf)) 906 n_active++; 907 } 908 909 if (vif->type == NL80211_IFTYPE_AP) { 910 if (n_active > mvm->fw->ucode_capa.num_beacons) 911 return -EOPNOTSUPP; 912 } else if (n_active > 1) { 913 return -EOPNOTSUPP; 914 } 915 } 916 917 for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { 918 int r; 919 920 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) 921 break; 922 923 if (!(added & BIT(i))) 924 continue; 925 new_link[i] = kzalloc(sizeof(*new_link[i]), GFP_KERNEL); 926 if (!new_link[i]) { 927 err = -ENOMEM; 928 goto free; 929 } 930 931 new_link[i]->bcast_sta.sta_id = IWL_MVM_INVALID_STA; 932 new_link[i]->mcast_sta.sta_id = IWL_MVM_INVALID_STA; 933 new_link[i]->ap_sta_id = IWL_MVM_INVALID_STA; 934 new_link[i]->fw_link_id = IWL_MVM_FW_LINK_ID_INVALID; 935 936 for (r = 0; r < NUM_IWL_MVM_SMPS_REQ; r++) 937 new_link[i]->smps_requests[r] = 938 IEEE80211_SMPS_AUTOMATIC; 939 } 940 941 mutex_lock(&mvm->mutex); 942 943 if (old_links == 0) { 944 err = iwl_mvm_disable_link(mvm, vif, &vif->bss_conf); 945 if (err) 946 goto out_err; 947 mvmvif->link[0] = NULL; 948 } 949 950 for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { 951 if (removed & BIT(i)) { 952 struct ieee80211_bss_conf *link_conf = old[i]; 953 954 err = iwl_mvm_disable_link(mvm, vif, link_conf); 955 if (err) 956 goto out_err; 957 kfree(mvmvif->link[i]); 958 mvmvif->link[i] = NULL; 959 } 960 961 if (added & BIT(i)) { 962 struct ieee80211_bss_conf *link_conf; 963 964 link_conf = link_conf_dereference_protected(vif, i); 965 if (WARN_ON(!link_conf)) 966 continue; 967 968 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, 969 &mvm->status)) 970 mvmvif->link[i] = new_link[i]; 971 new_link[i] = NULL; 972 err = iwl_mvm_add_link(mvm, vif, link_conf); 973 if (err) 974 goto out_err; 975 } 976 } 977 978 err = 0; 979 if (new_links == 0) { 980 mvmvif->link[0] = &mvmvif->deflink; 981 err = iwl_mvm_add_link(mvm, vif, &vif->bss_conf); 982 } 983 984 out_err: 985 /* we really don't have a good way to roll back here ... */ 986 mutex_unlock(&mvm->mutex); 987 988 free: 989 for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) 990 kfree(new_link[i]); 991 return err; 992 } 993 994 static int 995 iwl_mvm_mld_change_sta_links(struct ieee80211_hw *hw, 996 struct ieee80211_vif *vif, 997 struct ieee80211_sta *sta, 998 u16 old_links, u16 new_links) 999 { 1000 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1001 int ret; 1002 1003 mutex_lock(&mvm->mutex); 1004 ret = iwl_mvm_mld_update_sta_links(mvm, vif, sta, old_links, new_links); 1005 mutex_unlock(&mvm->mutex); 1006 1007 return ret; 1008 } 1009 1010 const struct ieee80211_ops iwl_mvm_mld_hw_ops = { 1011 .tx = iwl_mvm_mac_tx, 1012 .wake_tx_queue = iwl_mvm_mac_wake_tx_queue, 1013 .ampdu_action = iwl_mvm_mac_ampdu_action, 1014 .get_antenna = iwl_mvm_op_get_antenna, 1015 .start = iwl_mvm_mac_start, 1016 .reconfig_complete = iwl_mvm_mac_reconfig_complete, 1017 .stop = iwl_mvm_mac_stop, 1018 .add_interface = iwl_mvm_mld_mac_add_interface, 1019 .remove_interface = iwl_mvm_mld_mac_remove_interface, 1020 .config = iwl_mvm_mac_config, 1021 .prepare_multicast = iwl_mvm_prepare_multicast, 1022 .configure_filter = iwl_mvm_configure_filter, 1023 .config_iface_filter = iwl_mvm_mld_config_iface_filter, 1024 .link_info_changed = iwl_mvm_mld_link_info_changed, 1025 .vif_cfg_changed = iwl_mvm_mld_vif_cfg_changed, 1026 .hw_scan = iwl_mvm_mac_hw_scan, 1027 .cancel_hw_scan = iwl_mvm_mac_cancel_hw_scan, 1028 .sta_pre_rcu_remove = iwl_mvm_sta_pre_rcu_remove, 1029 .sta_state = iwl_mvm_mld_mac_sta_state, 1030 .sta_notify = iwl_mvm_mac_sta_notify, 1031 .allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames, 1032 .release_buffered_frames = iwl_mvm_mac_release_buffered_frames, 1033 .set_rts_threshold = iwl_mvm_mac_set_rts_threshold, 1034 .sta_rc_update = iwl_mvm_sta_rc_update, 1035 .conf_tx = iwl_mvm_mld_mac_conf_tx, 1036 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx, 1037 .mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx, 1038 .mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover, 1039 .flush = iwl_mvm_mac_flush, 1040 .sched_scan_start = iwl_mvm_mac_sched_scan_start, 1041 .sched_scan_stop = iwl_mvm_mac_sched_scan_stop, 1042 .set_key = iwl_mvm_mac_set_key, 1043 .update_tkip_key = iwl_mvm_mac_update_tkip_key, 1044 .remain_on_channel = iwl_mvm_mld_roc, 1045 .cancel_remain_on_channel = iwl_mvm_cancel_roc, 1046 .add_chanctx = iwl_mvm_add_chanctx, 1047 .remove_chanctx = iwl_mvm_remove_chanctx, 1048 .change_chanctx = iwl_mvm_change_chanctx, 1049 .assign_vif_chanctx = iwl_mvm_mld_assign_vif_chanctx, 1050 .unassign_vif_chanctx = iwl_mvm_mld_unassign_vif_chanctx, 1051 .switch_vif_chanctx = iwl_mvm_mld_switch_vif_chanctx, 1052 1053 .start_ap = iwl_mvm_mld_start_ap, 1054 .stop_ap = iwl_mvm_mld_stop_ap, 1055 .join_ibss = iwl_mvm_mld_start_ibss, 1056 .leave_ibss = iwl_mvm_mld_stop_ibss, 1057 1058 .tx_last_beacon = iwl_mvm_tx_last_beacon, 1059 1060 .set_tim = iwl_mvm_set_tim, 1061 1062 .channel_switch = iwl_mvm_channel_switch, 1063 .pre_channel_switch = iwl_mvm_pre_channel_switch, 1064 .post_channel_switch = iwl_mvm_post_channel_switch, 1065 .abort_channel_switch = iwl_mvm_abort_channel_switch, 1066 .channel_switch_rx_beacon = iwl_mvm_channel_switch_rx_beacon, 1067 1068 .tdls_channel_switch = iwl_mvm_tdls_channel_switch, 1069 .tdls_cancel_channel_switch = iwl_mvm_tdls_cancel_channel_switch, 1070 .tdls_recv_channel_switch = iwl_mvm_tdls_recv_channel_switch, 1071 1072 .event_callback = iwl_mvm_mac_event_callback, 1073 1074 .sync_rx_queues = iwl_mvm_sync_rx_queues, 1075 1076 CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd) 1077 1078 #ifdef CONFIG_PM_SLEEP 1079 /* look at d3.c */ 1080 .suspend = iwl_mvm_suspend, 1081 .resume = iwl_mvm_resume, 1082 .set_wakeup = iwl_mvm_set_wakeup, 1083 .set_rekey_data = iwl_mvm_set_rekey_data, 1084 #if IS_ENABLED(CONFIG_IPV6) 1085 .ipv6_addr_change = iwl_mvm_ipv6_addr_change, 1086 #endif 1087 .set_default_unicast_key = iwl_mvm_set_default_unicast_key, 1088 #endif 1089 .get_survey = iwl_mvm_mac_get_survey, 1090 .sta_statistics = iwl_mvm_mac_sta_statistics, 1091 .get_ftm_responder_stats = iwl_mvm_mac_get_ftm_responder_stats, 1092 .start_pmsr = iwl_mvm_start_pmsr, 1093 .abort_pmsr = iwl_mvm_abort_pmsr, 1094 1095 #ifdef CONFIG_IWLWIFI_DEBUGFS 1096 .sta_add_debugfs = iwl_mvm_sta_add_debugfs, 1097 #endif 1098 .set_hw_timestamp = iwl_mvm_set_hw_timestamp, 1099 1100 .change_vif_links = iwl_mvm_mld_change_vif_links, 1101 .change_sta_links = iwl_mvm_mld_change_sta_links, 1102 }; 1103