1 /* 2 * Copyright (c) 2019 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /** 20 * DOC: vdev_mgr_ops.c 21 * 22 * This file provide API definitions for filling data structures 23 * and sending vdev mgmt commands to target_if/mlme 24 */ 25 #include "vdev_mgr_ops.h" 26 #include <wlan_objmgr_vdev_obj.h> 27 #include <wlan_vdev_mlme_api.h> 28 #include <wlan_mlme_dbg.h> 29 #include <wlan_vdev_mgr_tgt_if_tx_api.h> 30 #include <target_if.h> 31 #include <init_deinit_lmac.h> 32 #include <wlan_lmac_if_api.h> 33 #include <wlan_reg_services_api.h> 34 #include <wlan_dfs_tgt_api.h> 35 #include <wlan_vdev_mgr_ucfg_api.h> 36 37 static QDF_STATUS vdev_mgr_create_param_update( 38 struct vdev_mlme_obj *mlme_obj, 39 struct vdev_create_params *param) 40 { 41 struct wlan_objmgr_pdev *pdev; 42 struct wlan_objmgr_vdev *vdev; 43 struct vdev_mlme_mbss_11ax *mbss; 44 45 vdev = mlme_obj->vdev; 46 if (!vdev) { 47 mlme_err("VDEV is NULL"); 48 return QDF_STATUS_E_INVAL; 49 } 50 51 pdev = wlan_vdev_get_pdev(vdev); 52 if (!pdev) { 53 mlme_err("PDEV is NULL"); 54 return QDF_STATUS_E_INVAL; 55 } 56 57 mbss = &mlme_obj->mgmt.mbss_11ax; 58 param->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 59 param->vdev_id = wlan_vdev_get_id(vdev); 60 param->nss_2g = mlme_obj->mgmt.generic.nss_2g; 61 param->nss_5g = mlme_obj->mgmt.generic.nss_5g; 62 param->type = mlme_obj->mgmt.generic.type; 63 param->subtype = mlme_obj->mgmt.generic.subtype; 64 param->mbssid_flags = mbss->mbssid_flags; 65 param->vdevid_trans = mbss->vdevid_trans; 66 67 return QDF_STATUS_SUCCESS; 68 } 69 70 QDF_STATUS vdev_mgr_create_send(struct vdev_mlme_obj *mlme_obj) 71 { 72 QDF_STATUS status; 73 struct vdev_create_params param = {0}; 74 75 if (!mlme_obj) { 76 mlme_err("VDEV_MLME is NULL"); 77 return QDF_STATUS_E_INVAL; 78 } 79 80 status = vdev_mgr_create_param_update(mlme_obj, ¶m); 81 if (QDF_IS_STATUS_ERROR(status)) { 82 mlme_err("Param Update Error: %d", status); 83 return status; 84 } 85 86 status = tgt_vdev_mgr_create_send(mlme_obj, ¶m); 87 88 return status; 89 } 90 91 static QDF_STATUS vdev_mgr_start_param_update( 92 struct vdev_mlme_obj *mlme_obj, 93 struct vdev_start_params *param) 94 { 95 struct wlan_channel *bss_chan; 96 uint32_t dfs_reg; 97 uint64_t chan_flags; 98 uint16_t chan_flags_ext; 99 bool set_agile = false, dfs_set_cfreq2 = false; 100 struct wlan_objmgr_vdev *vdev; 101 struct wlan_objmgr_pdev *pdev; 102 103 vdev = mlme_obj->vdev; 104 if (!vdev) { 105 mlme_err("VDEV is NULL"); 106 return QDF_STATUS_E_INVAL; 107 } 108 109 pdev = wlan_vdev_get_pdev(vdev); 110 if (!pdev) { 111 mlme_err("PDEV is NULL"); 112 return QDF_STATUS_E_INVAL; 113 } 114 115 if (wlan_objmgr_pdev_try_get_ref(pdev, WLAN_MLME_SB_ID) != 116 QDF_STATUS_SUCCESS) { 117 mlme_err("Failed to get pdev reference"); 118 return QDF_STATUS_E_FAILURE; 119 } 120 121 bss_chan = wlan_vdev_mlme_get_bss_chan(vdev); 122 param->vdev_id = wlan_vdev_get_id(vdev); 123 chan_flags = mlme_obj->mgmt.generic.chan_flags; 124 chan_flags_ext = mlme_obj->mgmt.generic.chan_flags_ext; 125 126 tgt_dfs_set_current_channel(pdev, bss_chan->ch_freq, 127 chan_flags, chan_flags_ext, 128 bss_chan->ch_ieee, 129 bss_chan->ch_freq_seg1, 130 bss_chan->ch_freq_seg2); 131 132 param->beacon_interval = mlme_obj->proto.generic.beacon_interval; 133 param->dtim_period = mlme_obj->proto.generic.dtim_period; 134 param->disable_hw_ack = mlme_obj->mgmt.generic.disable_hw_ack; 135 param->preferred_rx_streams = 136 mlme_obj->mgmt.chainmask_info.num_rx_chain; 137 param->preferred_tx_streams = 138 mlme_obj->mgmt.chainmask_info.num_tx_chain; 139 140 wlan_reg_get_dfs_region(pdev, &dfs_reg); 141 param->regdomain = dfs_reg; 142 param->he_ops = mlme_obj->proto.he_ops_info.he_ops; 143 144 param->channel.chan_id = bss_chan->ch_ieee; 145 param->channel.pwr = mlme_obj->mgmt.generic.tx_power; 146 param->channel.mhz = bss_chan->ch_freq; 147 param->channel.half_rate = mlme_obj->mgmt.rate_info.half_rate; 148 param->channel.quarter_rate = mlme_obj->mgmt.rate_info.quarter_rate; 149 param->channel.dfs_set = mlme_obj->mgmt.generic.dfs_set; 150 param->channel.dfs_set_cfreq2 = mlme_obj->mgmt.generic.dfs_set_cfreq2; 151 param->channel.is_chan_passive = 152 mlme_obj->mgmt.generic.is_chan_passive; 153 param->channel.allow_ht = mlme_obj->proto.ht_info.allow_ht; 154 param->channel.allow_vht = mlme_obj->proto.vht_info.allow_vht; 155 param->channel.phy_mode = bss_chan->ch_phymode; 156 param->channel.cfreq1 = mlme_obj->mgmt.generic.cfreq1; 157 param->channel.cfreq2 = mlme_obj->mgmt.generic.cfreq2; 158 param->channel.maxpower = mlme_obj->mgmt.generic.maxpower; 159 param->channel.minpower = mlme_obj->mgmt.generic.minpower; 160 param->channel.maxregpower = mlme_obj->mgmt.generic.maxregpower; 161 param->channel.antennamax = mlme_obj->mgmt.generic.antennamax; 162 param->channel.reg_class_id = mlme_obj->mgmt.generic.reg_class_id; 163 param->bcn_tx_rate_code = mlme_obj->mgmt.rate_info.bcn_tx_rate; 164 param->ldpc_rx_enabled = mlme_obj->proto.generic.ldpc; 165 wlan_vdev_mlme_get_ssid(vdev, param->ssid.mac_ssid, 166 ¶m->ssid.length); 167 168 if (bss_chan->ch_phymode == WLAN_PHYMODE_11AXA_HE80_80) { 169 tgt_dfs_find_vht80_chan_for_precac(pdev, 170 param->channel.phy_mode, 171 bss_chan->ch_freq_seg1, 172 ¶m->channel.cfreq1, 173 ¶m->channel.cfreq2, 174 ¶m->channel.phy_mode, 175 &dfs_set_cfreq2, 176 &set_agile); 177 178 param->channel.dfs_set_cfreq2 = dfs_set_cfreq2; 179 param->channel.set_agile = set_agile; 180 } 181 182 wlan_objmgr_pdev_release_ref(pdev, WLAN_MLME_SB_ID); 183 return QDF_STATUS_SUCCESS; 184 } 185 186 QDF_STATUS vdev_mgr_start_send( 187 struct vdev_mlme_obj *mlme_obj, 188 bool restart) 189 { 190 QDF_STATUS status; 191 struct vdev_start_params param = {0}; 192 193 if (!mlme_obj) { 194 mlme_err("VDEV_MLME is NULL"); 195 return QDF_STATUS_E_INVAL; 196 } 197 198 status = vdev_mgr_start_param_update(mlme_obj, ¶m); 199 if (QDF_IS_STATUS_ERROR(status)) { 200 mlme_err("Param Update Error: %d", status); 201 return status; 202 } 203 204 param.is_restart = restart; 205 status = tgt_vdev_mgr_start_send(mlme_obj, ¶m); 206 207 return status; 208 } 209 210 static QDF_STATUS vdev_mgr_delete_param_update( 211 struct vdev_mlme_obj *mlme_obj, 212 struct vdev_delete_params *param) 213 { 214 struct wlan_objmgr_vdev *vdev; 215 216 vdev = mlme_obj->vdev; 217 if (!vdev) { 218 mlme_err("VDEV is NULL"); 219 return QDF_STATUS_E_INVAL; 220 } 221 222 param->vdev_id = wlan_vdev_get_id(vdev); 223 return QDF_STATUS_SUCCESS; 224 } 225 226 QDF_STATUS vdev_mgr_delete_send(struct vdev_mlme_obj *mlme_obj) 227 { 228 QDF_STATUS status; 229 struct vdev_delete_params param; 230 231 if (!mlme_obj) { 232 mlme_err("VDEV_MLME is NULL"); 233 return QDF_STATUS_E_INVAL; 234 } 235 236 status = vdev_mgr_delete_param_update(mlme_obj, ¶m); 237 if (QDF_IS_STATUS_ERROR(status)) { 238 mlme_err("Param Update Error: %d", status); 239 return status; 240 } 241 242 status = tgt_vdev_mgr_delete_send(mlme_obj, ¶m); 243 244 return status; 245 } 246 247 static QDF_STATUS vdev_mgr_stop_param_update( 248 struct vdev_mlme_obj *mlme_obj, 249 struct vdev_stop_params *param) 250 { 251 struct wlan_objmgr_vdev *vdev; 252 253 vdev = mlme_obj->vdev; 254 if (!vdev) { 255 mlme_err("VDEV is NULL"); 256 return QDF_STATUS_E_INVAL; 257 } 258 259 param->vdev_id = wlan_vdev_get_id(vdev); 260 261 return QDF_STATUS_SUCCESS; 262 } 263 264 QDF_STATUS vdev_mgr_stop_send(struct vdev_mlme_obj *mlme_obj) 265 { 266 QDF_STATUS status; 267 struct vdev_stop_params param = {0}; 268 269 if (!mlme_obj) { 270 mlme_err("VDEV_MLME is NULL"); 271 return QDF_STATUS_E_INVAL; 272 } 273 274 status = vdev_mgr_stop_param_update(mlme_obj, ¶m); 275 if (QDF_IS_STATUS_ERROR(status)) { 276 mlme_err("Param Update Error: %d", status); 277 return status; 278 } 279 280 status = tgt_vdev_mgr_stop_send(mlme_obj, ¶m); 281 282 return status; 283 } 284 285 static QDF_STATUS vdev_mgr_config_ratemask_update( 286 struct vdev_mlme_obj *mlme_obj, 287 struct config_ratemask_params *param) 288 { 289 struct wlan_objmgr_vdev *vdev; 290 291 vdev = mlme_obj->vdev; 292 param->vdev_id = wlan_vdev_get_id(vdev); 293 param->type = mlme_obj->mgmt.rate_info.type; 294 param->lower32 = mlme_obj->mgmt.rate_info.lower32; 295 param->higher32 = mlme_obj->mgmt.rate_info.higher32; 296 param->lower32_2 = mlme_obj->mgmt.rate_info.lower32_2; 297 298 return QDF_STATUS_SUCCESS; 299 } 300 301 static QDF_STATUS vdev_mgr_bcn_tmpl_param_update( 302 struct vdev_mlme_obj *mlme_obj, 303 struct beacon_tmpl_params *param) 304 { 305 return QDF_STATUS_SUCCESS; 306 } 307 308 static QDF_STATUS vdev_mgr_sta_ps_param_update( 309 struct vdev_mlme_obj *mlme_obj, 310 struct sta_ps_params *param) 311 { 312 struct wlan_objmgr_vdev *vdev; 313 314 vdev = mlme_obj->vdev; 315 param->vdev_id = wlan_vdev_get_id(vdev); 316 param->param_id = WLAN_MLME_CFG_UAPSD; 317 param->value = mlme_obj->proto.sta.uapsd_cfg; 318 return QDF_STATUS_SUCCESS; 319 } 320 321 static QDF_STATUS vdev_mgr_up_param_update( 322 struct vdev_mlme_obj *mlme_obj, 323 struct vdev_up_params *param) 324 { 325 struct vdev_mlme_mbss_11ax *mbss; 326 struct wlan_objmgr_vdev *vdev; 327 328 vdev = mlme_obj->vdev; 329 param->vdev_id = wlan_vdev_get_id(vdev); 330 param->assoc_id = mlme_obj->proto.sta.assoc_id; 331 mbss = &mlme_obj->mgmt.mbss_11ax; 332 if (mbss->profile_idx) { 333 param->profile_idx = mbss->profile_idx; 334 param->profile_num = mbss->profile_num; 335 qdf_mem_copy(param->trans_bssid, mbss->trans_bssid, 336 QDF_MAC_ADDR_SIZE); 337 } 338 339 return QDF_STATUS_SUCCESS; 340 } 341 342 QDF_STATUS vdev_mgr_up_send(struct vdev_mlme_obj *mlme_obj) 343 { 344 QDF_STATUS status; 345 struct vdev_up_params param = {0}; 346 struct config_ratemask_params rm_param = {0}; 347 struct sta_ps_params ps_param = {0}; 348 struct beacon_tmpl_params bcn_tmpl_param = {0}; 349 enum QDF_OPMODE opmode; 350 struct wlan_objmgr_vdev *vdev; 351 352 if (!mlme_obj) { 353 mlme_err("VDEV_MLME is NULL"); 354 return QDF_STATUS_E_INVAL; 355 } 356 357 vdev = mlme_obj->vdev; 358 if (!vdev) { 359 mlme_err("VDEV is NULL"); 360 return QDF_STATUS_E_INVAL; 361 } 362 363 vdev_mgr_up_param_update(mlme_obj, ¶m); 364 vdev_mgr_bcn_tmpl_param_update(mlme_obj, &bcn_tmpl_param); 365 366 opmode = wlan_vdev_mlme_get_opmode(vdev); 367 if (opmode == QDF_STA_MODE) { 368 vdev_mgr_sta_ps_param_update(mlme_obj, &ps_param); 369 status = tgt_vdev_mgr_sta_ps_param_send(mlme_obj, &ps_param); 370 371 } else if (opmode == QDF_SAP_MODE) { 372 vdev_mgr_config_ratemask_update(mlme_obj, &rm_param); 373 status = tgt_vdev_mgr_config_ratemask_cmd_send(mlme_obj, 374 &rm_param); 375 } 376 377 status = tgt_vdev_mgr_beacon_tmpl_send(mlme_obj, &bcn_tmpl_param); 378 if (QDF_IS_STATUS_ERROR(status)) 379 return status; 380 381 status = tgt_vdev_mgr_up_send(mlme_obj, ¶m); 382 383 return status; 384 } 385 386 static QDF_STATUS vdev_mgr_down_param_update( 387 struct vdev_mlme_obj *mlme_obj, 388 struct vdev_down_params *param) 389 { 390 struct wlan_objmgr_vdev *vdev; 391 392 vdev = mlme_obj->vdev; 393 if (!vdev) { 394 mlme_err("VDEV is NULL"); 395 return QDF_STATUS_E_INVAL; 396 } 397 398 param->vdev_id = wlan_vdev_get_id(vdev); 399 400 return QDF_STATUS_SUCCESS; 401 } 402 403 QDF_STATUS vdev_mgr_down_send(struct vdev_mlme_obj *mlme_obj) 404 { 405 QDF_STATUS status; 406 struct vdev_down_params param = {0}; 407 408 if (!mlme_obj) { 409 mlme_err("VDEV_MLME is NULL"); 410 return QDF_STATUS_E_INVAL; 411 } 412 413 status = vdev_mgr_down_param_update(mlme_obj, ¶m); 414 if (QDF_IS_STATUS_ERROR(status)) { 415 mlme_err("Param Update Error: %d", status); 416 return status; 417 } 418 419 status = tgt_vdev_mgr_down_send(mlme_obj, ¶m); 420 421 return status; 422 } 423 424 static QDF_STATUS vdev_mgr_peer_flush_tids_param_update( 425 struct vdev_mlme_obj *mlme_obj, 426 struct peer_flush_params *param, 427 uint8_t *mac, 428 uint32_t peer_tid_bitmap) 429 { 430 struct wlan_objmgr_vdev *vdev; 431 432 vdev = mlme_obj->vdev; 433 if (!vdev) { 434 mlme_err("VDEV is NULL"); 435 return QDF_STATUS_E_INVAL; 436 } 437 438 param->vdev_id = wlan_vdev_get_id(vdev); 439 param->peer_tid_bitmap = peer_tid_bitmap; 440 qdf_mem_copy(param->peer_mac, mac, sizeof(*mac)); 441 return QDF_STATUS_SUCCESS; 442 } 443 444 QDF_STATUS vdev_mgr_peer_flush_tids_send(struct vdev_mlme_obj *mlme_obj, 445 uint8_t *mac, 446 uint32_t peer_tid_bitmap) 447 { 448 QDF_STATUS status; 449 struct peer_flush_params param = {0}; 450 451 if (!mlme_obj || !mac) { 452 mlme_err("Invalid input"); 453 return QDF_STATUS_E_INVAL; 454 } 455 456 status = vdev_mgr_peer_flush_tids_param_update(mlme_obj, ¶m, 457 mac, peer_tid_bitmap); 458 if (QDF_IS_STATUS_ERROR(status)) { 459 mlme_err("Param Update Error: %d", status); 460 return status; 461 } 462 463 status = tgt_vdev_mgr_peer_flush_tids_send(mlme_obj, ¶m); 464 465 return status; 466 } 467 468 static QDF_STATUS vdev_mgr_multiple_restart_param_update( 469 struct wlan_objmgr_pdev *pdev, 470 struct mlme_channel_param *chan, 471 uint32_t disable_hw_ack, 472 uint32_t *vdev_ids, 473 uint32_t num_vdevs, 474 struct multiple_vdev_restart_params *param) 475 { 476 param->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 477 param->requestor_id = MULTIPLE_VDEV_RESTART_REQ_ID; 478 param->disable_hw_ack = disable_hw_ack; 479 param->cac_duration_ms = WLAN_DFS_WAIT_MS; 480 param->num_vdevs = num_vdevs; 481 482 qdf_mem_copy(param->vdev_ids, vdev_ids, 483 sizeof(uint32_t) * (param->num_vdevs)); 484 qdf_mem_copy(¶m->ch_param, chan, 485 sizeof(struct mlme_channel_param)); 486 487 return QDF_STATUS_SUCCESS; 488 } 489 490 QDF_STATUS vdev_mgr_multiple_restart_send(struct wlan_objmgr_pdev *pdev, 491 struct mlme_channel_param *chan, 492 uint32_t disable_hw_ack, 493 uint32_t *vdev_ids, 494 uint32_t num_vdevs) 495 { 496 struct multiple_vdev_restart_params param = {0}; 497 498 vdev_mgr_multiple_restart_param_update(pdev, chan, 499 disable_hw_ack, 500 vdev_ids, num_vdevs, 501 ¶m); 502 503 return tgt_vdev_mgr_multiple_vdev_restart_send(pdev, ¶m); 504 } 505 506 qdf_export_symbol(vdev_mgr_multiple_restart_send); 507