1 /* 2 * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: vdev_mgr_ops.c 22 * 23 * This file provide API definitions for filling data structures 24 * and sending vdev mgmt commands to target_if/mlme 25 */ 26 #include "vdev_mgr_ops.h" 27 #include <wlan_objmgr_vdev_obj.h> 28 #include <wlan_vdev_mlme_api.h> 29 #include <wlan_mlme_dbg.h> 30 #include <wlan_vdev_mgr_tgt_if_tx_api.h> 31 #include <target_if.h> 32 #include <init_deinit_lmac.h> 33 #include <wlan_lmac_if_api.h> 34 #include <wlan_reg_services_api.h> 35 #include <wlan_dfs_tgt_api.h> 36 #include <wlan_dfs_utils_api.h> 37 #include <wlan_vdev_mgr_ucfg_api.h> 38 #include <qdf_module.h> 39 #include <cdp_txrx_ctrl.h> 40 #ifdef WLAN_FEATURE_11BE_MLO 41 #include <wlan_mlo_mgr_ap.h> 42 #endif 43 #include <wlan_vdev_mgr_utils_api.h> 44 45 #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT 46 /** 47 * vdev_mgr_alloc_vdev_stats_id() - Allocate vdev stats id for vdev 48 * @vdev - pointer to vdev 49 * @param - pointer to vdev create params 50 * 51 * Return: none 52 */ 53 static void vdev_mgr_alloc_vdev_stats_id(struct wlan_objmgr_vdev *vdev, 54 struct vdev_create_params *param) 55 { 56 struct wlan_objmgr_psoc *psoc; 57 uint8_t vdev_stats_id = CDP_INVALID_VDEV_STATS_ID; 58 59 if ((param->type == WLAN_VDEV_MLME_TYPE_MONITOR) || 60 (param->subtype == WLAN_VDEV_MLME_SUBTYPE_SMART_MONITOR) || 61 (param->special_vdev_mode)) { 62 param->vdev_stats_id = CDP_INVALID_VDEV_STATS_ID; 63 return; 64 } 65 psoc = wlan_vdev_get_psoc(vdev); 66 if (!psoc || !wlan_psoc_get_dp_handle(psoc)) { 67 mlme_err("PSOC or PSOC DP Handle is NULL"); 68 param->vdev_stats_id = CDP_INVALID_VDEV_STATS_ID; 69 return; 70 } 71 72 /* Get vdev_stats_id from dp_soc via cdp call */ 73 cdp_vdev_alloc_vdev_stats_id(wlan_psoc_get_dp_handle(psoc), 74 &vdev_stats_id); 75 76 param->vdev_stats_id = vdev_stats_id; 77 } 78 79 /** 80 * vdev_mgr_reset_vdev_stats_id() -Reset vdev stats id 81 * @vdev - pointer to vdev 82 * @vdev_stats_id - Value of vdev_stats_id 83 * 84 * Return: none 85 */ 86 static void vdev_mgr_reset_vdev_stats_id(struct wlan_objmgr_vdev *vdev, 87 uint8_t vdev_stats_id) 88 { 89 struct wlan_objmgr_psoc *psoc; 90 91 if (vdev_stats_id == CDP_INVALID_VDEV_STATS_ID) 92 return; 93 94 psoc = wlan_vdev_get_psoc(vdev); 95 if (!psoc || !wlan_psoc_get_dp_handle(psoc)) { 96 mlme_err("PSOC or PSOC DP Handle is NULL"); 97 return; 98 } 99 100 cdp_vdev_reset_vdev_stats_id(wlan_psoc_get_dp_handle(psoc), 101 vdev_stats_id); 102 } 103 #else 104 static void vdev_mgr_alloc_vdev_stats_id(struct wlan_objmgr_vdev *vdev, 105 struct vdev_create_params *param) 106 { 107 /* Assign Invalid vdev_stats_id */ 108 param->vdev_stats_id = CDP_INVALID_VDEV_STATS_ID; 109 } 110 111 static void vdev_mgr_reset_vdev_stats_id(struct wlan_objmgr_vdev *vdev, 112 uint8_t vdev_stats_id) 113 {} 114 #endif /* QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT */ 115 116 #ifdef WLAN_FEATURE_11BE_MLO 117 static inline void 118 vdev_mgr_param_mld_mac_addr_copy(struct wlan_objmgr_vdev *vdev, 119 struct vdev_create_params *param) 120 { 121 WLAN_ADDR_COPY(param->mlo_mac, wlan_vdev_mlme_get_mldaddr(vdev)); 122 } 123 #else /* WLAN_FEATURE_11BE_MLO */ 124 static inline void 125 vdev_mgr_param_mld_mac_addr_copy(struct wlan_objmgr_vdev *vdev, 126 struct vdev_create_params *param) 127 { 128 } 129 #endif /* WLAN_FEATURE_11BE_MLO */ 130 131 static QDF_STATUS vdev_mgr_create_param_update( 132 struct vdev_mlme_obj *mlme_obj, 133 struct vdev_create_params *param) 134 { 135 struct wlan_objmgr_pdev *pdev; 136 struct wlan_objmgr_vdev *vdev; 137 struct vdev_mlme_mbss_11ax *mbss; 138 139 vdev = mlme_obj->vdev; 140 if (!vdev) { 141 mlme_err("VDEV is NULL"); 142 return QDF_STATUS_E_INVAL; 143 } 144 145 pdev = wlan_vdev_get_pdev(vdev); 146 if (!pdev) { 147 mlme_err("PDEV is NULL"); 148 return QDF_STATUS_E_INVAL; 149 } 150 151 mbss = &mlme_obj->mgmt.mbss_11ax; 152 param->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 153 param->vdev_id = wlan_vdev_get_id(vdev); 154 param->nss_2g = mlme_obj->proto.generic.nss_2g; 155 param->nss_5g = mlme_obj->proto.generic.nss_5g; 156 param->type = mlme_obj->mgmt.generic.type; 157 param->subtype = mlme_obj->mgmt.generic.subtype; 158 param->mbssid_flags = mbss->mbssid_flags; 159 param->vdevid_trans = mbss->vdevid_trans; 160 param->special_vdev_mode = mlme_obj->mgmt.generic.special_vdev_mode; 161 162 vdev_mgr_alloc_vdev_stats_id(vdev, param); 163 param->vdev_stats_id_valid = 164 ((param->vdev_stats_id != CDP_INVALID_VDEV_STATS_ID) ? true : false); 165 vdev_mgr_param_mld_mac_addr_copy(vdev, param); 166 167 return QDF_STATUS_SUCCESS; 168 } 169 170 QDF_STATUS vdev_mgr_create_send(struct vdev_mlme_obj *mlme_obj) 171 { 172 QDF_STATUS status; 173 struct vdev_create_params param = {0}; 174 175 if (!mlme_obj) { 176 mlme_err("VDEV_MLME is NULL"); 177 return QDF_STATUS_E_INVAL; 178 } 179 180 status = vdev_mgr_create_param_update(mlme_obj, ¶m); 181 if (QDF_IS_STATUS_ERROR(status)) { 182 mlme_err("Param Update Error: %d", status); 183 return status; 184 } 185 186 status = tgt_vdev_mgr_create_send(mlme_obj, ¶m); 187 if (QDF_IS_STATUS_ERROR(status)) { 188 /* Reset the vdev_stats_id */ 189 vdev_mgr_reset_vdev_stats_id(mlme_obj->vdev, 190 param.vdev_stats_id); 191 } 192 return status; 193 } 194 195 #ifdef MOBILE_DFS_SUPPORT 196 static bool vdev_mgr_is_opmode_sap_or_p2p_go(enum QDF_OPMODE op_mode) 197 { 198 return (op_mode == QDF_SAP_MODE || op_mode == QDF_P2P_GO_MODE); 199 } 200 201 static bool vdev_mgr_is_49G_5G_chan_freq(uint16_t chan_freq) 202 { 203 return WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq) || 204 WLAN_REG_IS_49GHZ_FREQ(chan_freq); 205 } 206 #else 207 static inline bool vdev_mgr_is_opmode_sap_or_p2p_go(enum QDF_OPMODE op_mode) 208 { 209 return true; 210 } 211 212 static inline bool vdev_mgr_is_49G_5G_chan_freq(uint16_t chan_freq) 213 { 214 return true; 215 } 216 #endif 217 218 #ifdef WLAN_FEATURE_11BE 219 static void 220 vdev_mgr_start_param_update_11be(struct vdev_mlme_obj *mlme_obj, 221 struct vdev_start_params *param, 222 struct wlan_channel *des_chan) 223 { 224 param->eht_ops = mlme_obj->proto.eht_ops_info.eht_ops; 225 param->channel.puncture_bitmap = des_chan->puncture_bitmap; 226 } 227 228 static inline void 229 vdev_mgr_set_cur_chan_punc_bitmap(struct wlan_channel *des_chan, 230 uint16_t *puncture_bitmap) 231 { 232 *puncture_bitmap = des_chan->puncture_bitmap; 233 } 234 #else 235 static void 236 vdev_mgr_start_param_update_11be(struct vdev_mlme_obj *mlme_obj, 237 struct vdev_start_params *param, 238 struct wlan_channel *des_chan) 239 { 240 } 241 242 static inline void 243 vdev_mgr_set_cur_chan_punc_bitmap(struct wlan_channel *des_chan, 244 uint16_t *puncture_bitmap) 245 { 246 *puncture_bitmap = 0; 247 } 248 #endif 249 250 #ifdef WLAN_FEATURE_11BE_MLO 251 #ifdef WLAN_MCAST_MLO 252 static inline void 253 vdev_mgr_start_param_update_mlo_mcast(struct wlan_objmgr_vdev *vdev, 254 struct vdev_start_params *param) 255 { 256 if (wlan_vdev_mlme_is_mlo_mcast_vdev(vdev)) 257 param->mlo_flags.mlo_mcast_vdev = 1; 258 } 259 #else 260 #define vdev_mgr_start_param_update_mlo_mcast(vdev, param) 261 #endif 262 263 static void 264 vdev_mgr_start_param_update_mlo_partner(struct wlan_objmgr_vdev *vdev, 265 struct vdev_start_params *param) 266 { 267 struct wlan_objmgr_pdev *pdev; 268 struct mlo_vdev_start_partner_links *mlo_ptr = ¶m->mlo_partner; 269 struct wlan_objmgr_vdev *vdev_list[WLAN_UMAC_MLO_MAX_VDEVS] = {NULL}; 270 uint16_t num_links = 0; 271 uint8_t i = 0, p_idx = 0; 272 273 mlo_ap_get_vdev_list(vdev, &num_links, vdev_list); 274 if (!num_links) { 275 mlme_err("No VDEVs under AP-MLD"); 276 return; 277 } 278 279 if (num_links > QDF_ARRAY_SIZE(vdev_list)) { 280 mlme_err("Invalid number of VDEVs under AP-MLD num_links:%u", 281 num_links); 282 for (i = 0; i < QDF_ARRAY_SIZE(vdev_list); i++) 283 mlo_release_vdev_ref(vdev_list[i]); 284 return; 285 } 286 287 for (i = 0; i < num_links; i++) { 288 if (vdev_list[i] == vdev) { 289 mlo_release_vdev_ref(vdev_list[i]); 290 continue; 291 } 292 293 pdev = wlan_vdev_get_pdev(vdev_list[i]); 294 mlo_ptr->partner_info[p_idx].vdev_id = 295 wlan_vdev_get_id(vdev_list[i]); 296 mlo_ptr->partner_info[p_idx].hw_mld_link_id = 297 wlan_mlo_get_pdev_hw_link_id(pdev); 298 qdf_mem_copy(mlo_ptr->partner_info[p_idx].mac_addr, 299 wlan_vdev_mlme_get_macaddr(vdev_list[i]), 300 QDF_MAC_ADDR_SIZE); 301 mlo_release_vdev_ref(vdev_list[i]); 302 p_idx++; 303 } 304 mlo_ptr->num_links = p_idx; 305 } 306 307 static void 308 vdev_mgr_start_param_update_mlo(struct vdev_mlme_obj *mlme_obj, 309 struct vdev_start_params *param) 310 { 311 struct wlan_objmgr_vdev *vdev; 312 313 vdev = mlme_obj->vdev; 314 if (!vdev) { 315 mlme_err("VDEV is NULL"); 316 return; 317 } 318 319 if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) 320 return; 321 322 param->mlo_flags.mlo_enabled = 1; 323 324 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE && 325 !wlan_vdev_mlme_is_mlo_link_vdev(vdev)) 326 param->mlo_flags.mlo_assoc_link = 1; 327 328 if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) && 329 wlan_vdev_mlme_cap_get(vdev, WLAN_VDEV_C_EMLSR_CAP)) { 330 param->mlo_flags.emlsr_support = 1; 331 mlme_debug("eMLSR support=%d", param->mlo_flags.emlsr_support); 332 } 333 334 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) { 335 if (wlan_vdev_mlme_op_flags_get( 336 vdev, WLAN_VDEV_OP_MLO_LINK_ADD)) 337 param->mlo_flags.mlo_link_add = 1; 338 339 vdev_mgr_start_param_update_mlo_mcast(vdev, param); 340 vdev_mgr_start_param_update_mlo_partner(vdev, param); 341 } 342 } 343 #else 344 static void 345 vdev_mgr_start_param_update_mlo(struct vdev_mlme_obj *mlme_obj, 346 struct vdev_start_params *param) 347 { 348 } 349 #endif 350 351 #ifdef MOBILE_DFS_SUPPORT 352 static void 353 vdev_mgr_start_param_update_cac_ms(struct wlan_objmgr_vdev *vdev, 354 struct vdev_start_params *param) 355 { 356 param->cac_duration_ms = 357 wlan_util_vdev_mgr_get_cac_timeout_for_vdev(vdev); 358 } 359 #else 360 static void 361 vdev_mgr_start_param_update_cac_ms(struct wlan_objmgr_vdev *vdev, 362 struct vdev_start_params *param) 363 { 364 } 365 #endif 366 367 static QDF_STATUS vdev_mgr_start_param_update( 368 struct vdev_mlme_obj *mlme_obj, 369 struct vdev_start_params *param) 370 { 371 struct wlan_channel *des_chan; 372 uint32_t dfs_reg; 373 bool is_stadfs_en = false; 374 struct wlan_objmgr_vdev *vdev; 375 struct wlan_objmgr_pdev *pdev; 376 enum QDF_OPMODE op_mode; 377 bool is_dfs_chan_updated = false; 378 struct vdev_mlme_mbss_11ax *mbss; 379 uint16_t puncture_bitmap; 380 381 vdev = mlme_obj->vdev; 382 if (!vdev) { 383 mlme_err("VDEV is NULL"); 384 return QDF_STATUS_E_INVAL; 385 } 386 387 pdev = wlan_vdev_get_pdev(vdev); 388 if (!pdev) { 389 mlme_err("PDEV is NULL"); 390 return QDF_STATUS_E_INVAL; 391 } 392 393 if (wlan_objmgr_pdev_try_get_ref(pdev, WLAN_MLME_SB_ID) != 394 QDF_STATUS_SUCCESS) { 395 mlme_err("Failed to get pdev reference"); 396 return QDF_STATUS_E_FAILURE; 397 } 398 399 des_chan = wlan_vdev_mlme_get_des_chan(vdev); 400 param->vdev_id = wlan_vdev_get_id(vdev); 401 402 op_mode = wlan_vdev_mlme_get_opmode(vdev); 403 if (vdev_mgr_is_opmode_sap_or_p2p_go(op_mode) && 404 vdev_mgr_is_49G_5G_chan_freq(des_chan->ch_freq)) { 405 vdev_mgr_set_cur_chan_punc_bitmap(des_chan, &puncture_bitmap); 406 tgt_dfs_set_current_channel_for_freq(pdev, des_chan->ch_freq, 407 des_chan->ch_flags, 408 des_chan->ch_flagext, 409 des_chan->ch_ieee, 410 des_chan->ch_freq_seg1, 411 des_chan->ch_freq_seg2, 412 des_chan->ch_cfreq1, 413 des_chan->ch_cfreq2, 414 puncture_bitmap, 415 &is_dfs_chan_updated); 416 if (des_chan->ch_cfreq2) 417 param->channel.dfs_set_cfreq2 = 418 utils_is_dfs_cfreq2_ch(pdev); 419 } 420 421 /* The Agile state machine should be stopped only once for the channel 422 * change. If the same channel is being sent to the FW then do 423 * not send unnecessary STOP to the state machine. 424 */ 425 if (is_dfs_chan_updated) 426 utils_dfs_agile_sm_deliver_evt(pdev, 427 DFS_AGILE_SM_EV_AGILE_STOP); 428 429 is_stadfs_en = tgt_dfs_is_stadfs_enabled(pdev); 430 param->channel.is_stadfs_en = is_stadfs_en; 431 param->beacon_interval = mlme_obj->proto.generic.beacon_interval; 432 param->dtim_period = mlme_obj->proto.generic.dtim_period; 433 param->disable_hw_ack = mlme_obj->mgmt.generic.disable_hw_ack; 434 param->preferred_rx_streams = 435 mlme_obj->mgmt.chainmask_info.num_rx_chain; 436 param->preferred_tx_streams = 437 mlme_obj->mgmt.chainmask_info.num_tx_chain; 438 439 wlan_reg_get_dfs_region(pdev, &dfs_reg); 440 param->regdomain = dfs_reg; 441 param->he_ops = mlme_obj->proto.he_ops_info.he_ops; 442 443 vdev_mgr_start_param_update_11be(mlme_obj, param, des_chan); 444 vdev_mgr_start_param_update_mlo(mlme_obj, param); 445 446 param->channel.chan_id = des_chan->ch_ieee; 447 param->channel.pwr = mlme_obj->mgmt.generic.tx_power; 448 param->channel.mhz = des_chan->ch_freq; 449 param->channel.half_rate = mlme_obj->mgmt.rate_info.half_rate; 450 param->channel.quarter_rate = mlme_obj->mgmt.rate_info.quarter_rate; 451 452 if (vdev_mgr_is_opmode_sap_or_p2p_go(op_mode)) 453 param->channel.dfs_set = wlan_reg_is_dfs_for_freq( 454 pdev, 455 des_chan->ch_freq); 456 457 param->channel.is_chan_passive = 458 utils_is_dfs_chan_for_freq(pdev, param->channel.mhz); 459 param->channel.allow_ht = mlme_obj->proto.ht_info.allow_ht; 460 param->channel.allow_vht = mlme_obj->proto.vht_info.allow_vht; 461 param->channel.phy_mode = mlme_obj->mgmt.generic.phy_mode; 462 param->channel.cfreq1 = des_chan->ch_cfreq1; 463 param->channel.cfreq2 = des_chan->ch_cfreq2; 464 param->channel.maxpower = mlme_obj->mgmt.generic.maxpower; 465 param->channel.minpower = mlme_obj->mgmt.generic.minpower; 466 param->channel.maxregpower = mlme_obj->mgmt.generic.maxregpower; 467 param->channel.antennamax = mlme_obj->mgmt.generic.antennamax; 468 param->channel.reg_class_id = mlme_obj->mgmt.generic.reg_class_id; 469 param->bcn_tx_rate_code = vdev_mgr_fetch_ratecode(mlme_obj); 470 param->ldpc_rx_enabled = mlme_obj->proto.generic.ldpc; 471 472 mbss = &mlme_obj->mgmt.mbss_11ax; 473 param->mbssid_flags = mbss->mbssid_flags; 474 param->mbssid_multi_group_flag = mbss->is_multi_mbssid; 475 param->mbssid_multi_group_id = mbss->grp_id; 476 param->vdevid_trans = mbss->vdevid_trans; 477 478 if (mlme_obj->mgmt.generic.type == WLAN_VDEV_MLME_TYPE_AP) { 479 param->hidden_ssid = mlme_obj->mgmt.ap.hidden_ssid; 480 vdev_mgr_start_param_update_cac_ms(vdev, param); 481 } 482 wlan_vdev_mlme_get_ssid(vdev, param->ssid.ssid, ¶m->ssid.length); 483 484 wlan_objmgr_pdev_release_ref(pdev, WLAN_MLME_SB_ID); 485 return QDF_STATUS_SUCCESS; 486 } 487 488 QDF_STATUS vdev_mgr_start_send( 489 struct vdev_mlme_obj *mlme_obj, 490 bool restart) 491 { 492 QDF_STATUS status; 493 struct vdev_start_params param = {0}; 494 495 if (!mlme_obj) { 496 mlme_err("VDEV_MLME is NULL"); 497 return QDF_STATUS_E_INVAL; 498 } 499 500 status = vdev_mgr_start_param_update(mlme_obj, ¶m); 501 if (QDF_IS_STATUS_ERROR(status)) { 502 mlme_err("Param Update Error: %d", status); 503 return status; 504 } 505 506 param.is_restart = restart; 507 status = tgt_vdev_mgr_start_send(mlme_obj, ¶m); 508 509 return status; 510 } 511 512 static QDF_STATUS vdev_mgr_delete_param_update( 513 struct vdev_mlme_obj *mlme_obj, 514 struct vdev_delete_params *param) 515 { 516 struct wlan_objmgr_vdev *vdev; 517 518 vdev = mlme_obj->vdev; 519 if (!vdev) { 520 mlme_err("VDEV is NULL"); 521 return QDF_STATUS_E_INVAL; 522 } 523 524 param->vdev_id = wlan_vdev_get_id(vdev); 525 return QDF_STATUS_SUCCESS; 526 } 527 528 QDF_STATUS vdev_mgr_delete_send(struct vdev_mlme_obj *mlme_obj) 529 { 530 QDF_STATUS status; 531 struct vdev_delete_params param; 532 533 if (!mlme_obj) { 534 mlme_err("VDEV_MLME is NULL"); 535 return QDF_STATUS_E_INVAL; 536 } 537 538 status = vdev_mgr_delete_param_update(mlme_obj, ¶m); 539 if (QDF_IS_STATUS_ERROR(status)) { 540 mlme_err("Param Update Error: %d", status); 541 return status; 542 } 543 544 status = tgt_vdev_mgr_delete_send(mlme_obj, ¶m); 545 546 return status; 547 } 548 549 static QDF_STATUS vdev_mgr_stop_param_update( 550 struct vdev_mlme_obj *mlme_obj, 551 struct vdev_stop_params *param) 552 { 553 struct wlan_objmgr_vdev *vdev; 554 555 vdev = mlme_obj->vdev; 556 if (!vdev) { 557 mlme_err("VDEV is NULL"); 558 return QDF_STATUS_E_INVAL; 559 } 560 561 param->vdev_id = wlan_vdev_get_id(vdev); 562 563 return QDF_STATUS_SUCCESS; 564 } 565 566 QDF_STATUS vdev_mgr_stop_send(struct vdev_mlme_obj *mlme_obj) 567 { 568 QDF_STATUS status; 569 struct vdev_stop_params param = {0}; 570 571 if (!mlme_obj) { 572 mlme_err("VDEV_MLME is NULL"); 573 return QDF_STATUS_E_INVAL; 574 } 575 576 status = vdev_mgr_stop_param_update(mlme_obj, ¶m); 577 if (QDF_IS_STATUS_ERROR(status)) { 578 mlme_err("Param Update Error: %d", status); 579 return status; 580 } 581 582 status = tgt_vdev_mgr_stop_send(mlme_obj, ¶m); 583 584 return status; 585 } 586 587 static QDF_STATUS vdev_mgr_bcn_tmpl_param_update( 588 struct vdev_mlme_obj *mlme_obj, 589 struct beacon_tmpl_params *param) 590 { 591 return QDF_STATUS_SUCCESS; 592 } 593 594 static QDF_STATUS vdev_mgr_sta_ps_param_update( 595 struct vdev_mlme_obj *mlme_obj, 596 struct sta_ps_params *param) 597 { 598 struct wlan_objmgr_vdev *vdev; 599 600 vdev = mlme_obj->vdev; 601 param->vdev_id = wlan_vdev_get_id(vdev); 602 param->param_id = WLAN_MLME_CFG_UAPSD; 603 param->value = mlme_obj->proto.sta.uapsd_cfg; 604 return QDF_STATUS_SUCCESS; 605 } 606 607 static QDF_STATUS vdev_mgr_up_param_update( 608 struct vdev_mlme_obj *mlme_obj, 609 struct vdev_up_params *param) 610 { 611 struct vdev_mlme_mbss_11ax *mbss; 612 struct wlan_objmgr_vdev *vdev; 613 614 vdev = mlme_obj->vdev; 615 param->vdev_id = wlan_vdev_get_id(vdev); 616 param->assoc_id = mlme_obj->proto.sta.assoc_id; 617 mbss = &mlme_obj->mgmt.mbss_11ax; 618 param->profile_idx = mbss->profile_idx; 619 param->profile_num = mbss->profile_num; 620 qdf_mem_copy(param->trans_bssid, mbss->trans_bssid, QDF_MAC_ADDR_SIZE); 621 622 return QDF_STATUS_SUCCESS; 623 } 624 625 QDF_STATUS vdev_mgr_up_send(struct vdev_mlme_obj *mlme_obj) 626 { 627 QDF_STATUS status; 628 struct vdev_up_params param = {0}; 629 struct sta_ps_params ps_param = {0}; 630 struct beacon_tmpl_params bcn_tmpl_param = {0}; 631 enum QDF_OPMODE opmode; 632 struct wlan_objmgr_vdev *vdev; 633 struct config_fils_params fils_param = {0}; 634 uint8_t is_6g_sap_fd_enabled; 635 bool is_non_tx_vdev; 636 637 if (!mlme_obj) { 638 mlme_err("VDEV_MLME is NULL"); 639 return QDF_STATUS_E_INVAL; 640 } 641 642 vdev = mlme_obj->vdev; 643 if (!vdev) { 644 mlme_err("VDEV is NULL"); 645 return QDF_STATUS_E_INVAL; 646 } 647 648 vdev_mgr_up_param_update(mlme_obj, ¶m); 649 vdev_mgr_bcn_tmpl_param_update(mlme_obj, &bcn_tmpl_param); 650 651 opmode = wlan_vdev_mlme_get_opmode(vdev); 652 if (opmode == QDF_STA_MODE) { 653 vdev_mgr_sta_ps_param_update(mlme_obj, &ps_param); 654 status = tgt_vdev_mgr_sta_ps_param_send(mlme_obj, &ps_param); 655 656 } 657 658 status = tgt_vdev_mgr_beacon_tmpl_send(mlme_obj, &bcn_tmpl_param); 659 if (QDF_IS_STATUS_ERROR(status)) 660 return status; 661 662 status = tgt_vdev_mgr_up_send(mlme_obj, ¶m); 663 if (QDF_IS_STATUS_ERROR(status)) 664 return status; 665 666 /* Reset the max channel switch time and last beacon sent time as the 667 * VDEV UP command sent to FW. 668 */ 669 mlme_obj->mgmt.ap.max_chan_switch_time = 0; 670 mlme_obj->mgmt.ap.last_bcn_ts_ms = 0; 671 672 is_6g_sap_fd_enabled = wlan_vdev_mlme_feat_ext_cap_get(vdev, 673 WLAN_VDEV_FEXT_FILS_DISC_6G_SAP); 674 mlme_debug("SAP FD enabled %d", is_6g_sap_fd_enabled); 675 676 /* 677 * In case of a non-tx vdev, 'profile_num' must be greater 678 * than 0 indicating one or more non-tx vdev and 'profile_idx' 679 * must be in the range [1, 2^n] where n is the max bssid 680 * indicator 681 */ 682 is_non_tx_vdev = param.profile_num && param.profile_idx; 683 684 if (opmode == QDF_SAP_MODE && mlme_obj->vdev->vdev_mlme.des_chan && 685 WLAN_REG_IS_6GHZ_CHAN_FREQ( 686 mlme_obj->vdev->vdev_mlme.des_chan->ch_freq) && 687 !is_non_tx_vdev) { 688 fils_param.vdev_id = wlan_vdev_get_id(mlme_obj->vdev); 689 if (is_6g_sap_fd_enabled) { 690 fils_param.fd_period = DEFAULT_FILS_DISCOVERY_PERIOD; 691 } else { 692 if (wlan_vdev_mlme_feat_ext2_cap_get(vdev, 693 WLAN_VDEV_FEXT2_20TU_PRB_RESP)) { 694 fils_param.send_prb_rsp_frame = true; 695 fils_param.fd_period = 696 DEFAULT_PROBE_RESP_PERIOD; 697 } else { 698 mlme_err("SAP FD and 20TU Prb both are disabled"); 699 } 700 } 701 status = tgt_vdev_mgr_fils_enable_send(mlme_obj, 702 &fils_param); 703 } 704 705 return status; 706 } 707 708 static QDF_STATUS vdev_mgr_down_param_update( 709 struct vdev_mlme_obj *mlme_obj, 710 struct vdev_down_params *param) 711 { 712 struct wlan_objmgr_vdev *vdev; 713 714 vdev = mlme_obj->vdev; 715 if (!vdev) { 716 mlme_err("VDEV is NULL"); 717 return QDF_STATUS_E_INVAL; 718 } 719 720 param->vdev_id = wlan_vdev_get_id(vdev); 721 722 return QDF_STATUS_SUCCESS; 723 } 724 725 QDF_STATUS vdev_mgr_down_send(struct vdev_mlme_obj *mlme_obj) 726 { 727 QDF_STATUS status; 728 struct vdev_down_params param = {0}; 729 730 if (!mlme_obj) { 731 mlme_err("VDEV_MLME is NULL"); 732 return QDF_STATUS_E_INVAL; 733 } 734 735 status = vdev_mgr_down_param_update(mlme_obj, ¶m); 736 if (QDF_IS_STATUS_ERROR(status)) { 737 mlme_err("Param Update Error: %d", status); 738 return status; 739 } 740 741 status = tgt_vdev_mgr_down_send(mlme_obj, ¶m); 742 743 return status; 744 } 745 746 static QDF_STATUS vdev_mgr_peer_flush_tids_param_update( 747 struct vdev_mlme_obj *mlme_obj, 748 struct peer_flush_params *param, 749 uint8_t *mac, 750 uint32_t peer_tid_bitmap) 751 { 752 struct wlan_objmgr_vdev *vdev; 753 754 vdev = mlme_obj->vdev; 755 if (!vdev) { 756 mlme_err("VDEV is NULL"); 757 return QDF_STATUS_E_INVAL; 758 } 759 760 param->vdev_id = wlan_vdev_get_id(vdev); 761 param->peer_tid_bitmap = peer_tid_bitmap; 762 qdf_mem_copy(param->peer_mac, mac, QDF_MAC_ADDR_SIZE); 763 return QDF_STATUS_SUCCESS; 764 } 765 766 QDF_STATUS vdev_mgr_peer_flush_tids_send(struct vdev_mlme_obj *mlme_obj, 767 uint8_t *mac, 768 uint32_t peer_tid_bitmap) 769 { 770 QDF_STATUS status; 771 struct peer_flush_params param = {0}; 772 773 if (!mlme_obj || !mac) { 774 mlme_err("Invalid input"); 775 return QDF_STATUS_E_INVAL; 776 } 777 778 status = vdev_mgr_peer_flush_tids_param_update(mlme_obj, ¶m, 779 mac, peer_tid_bitmap); 780 if (QDF_IS_STATUS_ERROR(status)) { 781 mlme_err("Param Update Error: %d", status); 782 return status; 783 } 784 785 status = tgt_vdev_mgr_peer_flush_tids_send(mlme_obj, ¶m); 786 787 return status; 788 } 789 790 static QDF_STATUS vdev_mgr_multiple_restart_param_update( 791 struct wlan_objmgr_pdev *pdev, 792 struct mlme_channel_param *chan, 793 uint32_t disable_hw_ack, 794 uint32_t *vdev_ids, 795 uint32_t num_vdevs, 796 struct vdev_mlme_mvr_param *mvr_param, 797 struct multiple_vdev_restart_params *param) 798 { 799 param->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 800 param->requestor_id = MULTIPLE_VDEV_RESTART_REQ_ID; 801 param->disable_hw_ack = disable_hw_ack; 802 param->cac_duration_ms = WLAN_DFS_WAIT_MS; 803 param->num_vdevs = num_vdevs; 804 805 qdf_mem_copy(¶m->ch_param, chan, 806 sizeof(struct mlme_channel_param)); 807 808 param->vdev_ids = vdev_ids; 809 param->mvr_param = mvr_param; 810 param->max_vdevs = wlan_pdev_get_max_vdev_count(pdev); 811 param->mvr_bmap_enabled = wlan_pdev_nif_feat_cap_get(pdev, 812 WLAN_PDEV_F_MULTIVDEV_RESTART_BMAP); 813 814 return QDF_STATUS_SUCCESS; 815 } 816 817 QDF_STATUS vdev_mgr_multiple_restart_send(struct wlan_objmgr_pdev *pdev, 818 struct mlme_channel_param *chan, 819 uint32_t disable_hw_ack, 820 uint32_t *vdev_ids, 821 uint32_t num_vdevs, 822 struct vdev_mlme_mvr_param *mvr_param) 823 { 824 struct multiple_vdev_restart_params param = {0}; 825 826 vdev_mgr_multiple_restart_param_update(pdev, chan, 827 disable_hw_ack, 828 vdev_ids, num_vdevs, 829 mvr_param, ¶m); 830 831 return tgt_vdev_mgr_multiple_vdev_restart_send(pdev, ¶m); 832 } 833 834 qdf_export_symbol(vdev_mgr_multiple_restart_send); 835 836 static QDF_STATUS vdev_mgr_set_custom_aggr_size_param_update( 837 struct vdev_mlme_obj *mlme_obj, 838 struct set_custom_aggr_size_params *param, 839 bool is_amsdu) 840 { 841 struct wlan_objmgr_vdev *vdev; 842 843 vdev = mlme_obj->vdev; 844 if (!vdev) { 845 mlme_err("VDEV is NULL"); 846 return QDF_STATUS_E_INVAL; 847 } 848 849 param->aggr_type = is_amsdu ? WLAN_MLME_CUSTOM_AGGR_TYPE_AMSDU 850 : WLAN_MLME_CUSTOM_AGGR_TYPE_AMPDU; 851 /* 852 * We are only setting TX params, therefore 853 * we are disabling rx_aggr_size 854 */ 855 param->rx_aggr_size_disable = true; 856 param->tx_aggr_size = is_amsdu ? mlme_obj->mgmt.generic.amsdu 857 : mlme_obj->mgmt.generic.ampdu; 858 param->vdev_id = wlan_vdev_get_id(vdev); 859 860 return QDF_STATUS_SUCCESS; 861 } 862 863 QDF_STATUS vdev_mgr_set_custom_aggr_size_send( 864 struct vdev_mlme_obj *vdev_mlme, 865 bool is_amsdu) 866 { 867 QDF_STATUS status; 868 struct set_custom_aggr_size_params param = {0}; 869 870 status = vdev_mgr_set_custom_aggr_size_param_update(vdev_mlme, 871 ¶m, is_amsdu); 872 if (QDF_IS_STATUS_ERROR(status)) { 873 mlme_err("Param Update Error: %d", status); 874 return status; 875 } 876 877 return tgt_vdev_mgr_set_custom_aggr_size_send(vdev_mlme, ¶m); 878 } 879 880 static QDF_STATUS vdev_mgr_peer_delete_all_param_update( 881 struct vdev_mlme_obj *mlme_obj, 882 struct peer_delete_all_params *param) 883 { 884 struct wlan_objmgr_vdev *vdev; 885 886 vdev = mlme_obj->vdev; 887 if (!vdev) { 888 mlme_err("VDEV is NULL"); 889 return QDF_STATUS_E_INVAL; 890 } 891 892 param->vdev_id = wlan_vdev_get_id(vdev); 893 return QDF_STATUS_SUCCESS; 894 } 895 896 QDF_STATUS vdev_mgr_peer_delete_all_send(struct vdev_mlme_obj *mlme_obj) 897 { 898 QDF_STATUS status; 899 struct peer_delete_all_params param = {0}; 900 901 if (!mlme_obj) { 902 mlme_err("Invalid input"); 903 return QDF_STATUS_E_INVAL; 904 } 905 906 status = vdev_mgr_peer_delete_all_param_update(mlme_obj, ¶m); 907 if (QDF_IS_STATUS_ERROR(status)) { 908 mlme_err("Param Update Error: %d", status); 909 return status; 910 } 911 912 status = tgt_vdev_mgr_peer_delete_all_send(mlme_obj, ¶m); 913 914 return status; 915 } 916 917 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 918 QDF_STATUS vdev_mgr_send_set_mac_addr(struct qdf_mac_addr mac_addr, 919 struct qdf_mac_addr mld_addr, 920 struct wlan_objmgr_vdev *vdev) 921 { 922 return tgt_vdev_mgr_send_set_mac_addr(mac_addr, mld_addr, vdev); 923 } 924 925 QDF_STATUS vdev_mgr_cdp_vdev_attach(struct vdev_mlme_obj *mlme_obj) 926 { 927 return tgt_vdev_mgr_cdp_vdev_attach(mlme_obj); 928 } 929 930 QDF_STATUS vdev_mgr_cdp_vdev_detach(struct vdev_mlme_obj *mlme_obj) 931 { 932 return tgt_vdev_mgr_cdp_vdev_detach(mlme_obj); 933 } 934 #endif 935