1 /* 2 * Copyright (c) 2019-2020 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 #include <target_if_cfr.h> 20 #include <wlan_tgt_def_config.h> 21 #include <target_type.h> 22 #include <hif_hw_version.h> 23 #include <target_if.h> 24 #include <wlan_lmac_if_def.h> 25 #include <wlan_osif_priv.h> 26 #include <init_deinit_lmac.h> 27 #include <wlan_cfr_utils_api.h> 28 #include <wlan_objmgr_pdev_obj.h> 29 #include <target_if_cfr_enh.h> 30 #ifdef CFR_USE_FIXED_FOLDER 31 #include "target_if_cfr_6490.h" 32 #include "target_if_cfr_adrastea.h" 33 #include "wlan_reg_services_api.h" 34 #else 35 #include <target_if_cfr_8074v2.h> 36 #endif 37 38 int target_if_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, 39 struct wlan_objmgr_peer *peer) 40 { 41 struct peer_cfr *pe; 42 struct peer_cfr_params param = {0}; 43 struct wmi_unified *pdev_wmi_handle = NULL; 44 struct wlan_objmgr_vdev *vdev = {0}; 45 struct pdev_cfr *pdev_cfrobj; 46 int retv = 0; 47 48 pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR); 49 if (pe == NULL) 50 return -EINVAL; 51 52 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); 53 if (!pdev_wmi_handle) { 54 cfr_err("pdev wmi handle NULL"); 55 return -EINVAL; 56 } 57 vdev = wlan_peer_get_vdev(peer); 58 59 qdf_mem_set(¶m, sizeof(param), 0); 60 61 param.request = PEER_CFR_CAPTURE_DISABLE; 62 param.macaddr = wlan_peer_get_macaddr(peer); 63 param.vdev_id = wlan_vdev_get_id(vdev); 64 65 param.periodicity = pe->period; 66 param.bandwidth = pe->bandwidth; 67 param.capture_method = pe->capture_method; 68 69 retv = wmi_unified_send_peer_cfr_capture_cmd(pdev_wmi_handle, ¶m); 70 71 pdev_cfrobj = wlan_objmgr_pdev_get_comp_private_obj(pdev, 72 WLAN_UMAC_COMP_CFR); 73 if (!pdev_cfrobj) { 74 cfr_err("pdev object for CFR is null"); 75 return -EINVAL; 76 } 77 cfr_err("CFR capture stats for this capture:"); 78 cfr_err("DBR event count = %llu, Tx event count = %llu " 79 "Release count = %llu", 80 pdev_cfrobj->dbr_evt_cnt, pdev_cfrobj->tx_evt_cnt, 81 pdev_cfrobj->release_cnt); 82 83 pdev_cfrobj->dbr_evt_cnt = 0; 84 pdev_cfrobj->tx_evt_cnt = 0; 85 pdev_cfrobj->release_cnt = 0; 86 pdev_cfrobj->tx_peer_status_cfr_fail = 0; 87 pdev_cfrobj->tx_evt_status_cfr_fail = 0; 88 pdev_cfrobj->tx_dbr_cookie_lookup_fail = 0; 89 90 return retv; 91 } 92 93 int target_if_cfr_start_capture(struct wlan_objmgr_pdev *pdev, 94 struct wlan_objmgr_peer *peer, 95 struct cfr_capture_params *cfr_params) 96 { 97 struct peer_cfr_params param = {0}; 98 struct wmi_unified *pdev_wmi_handle = NULL; 99 struct wlan_objmgr_vdev *vdev; 100 int retv = 0; 101 102 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); 103 if (!pdev_wmi_handle) { 104 cfr_err("pdev wmi handle NULL"); 105 return -EINVAL; 106 } 107 vdev = wlan_peer_get_vdev(peer); 108 qdf_mem_set(¶m, sizeof(param), 0); 109 110 param.request = PEER_CFR_CAPTURE_ENABLE; 111 param.macaddr = wlan_peer_get_macaddr(peer); 112 param.vdev_id = wlan_vdev_get_id(vdev); 113 114 param.periodicity = cfr_params->period; 115 param.bandwidth = cfr_params->bandwidth; 116 param.capture_method = cfr_params->method; 117 118 retv = wmi_unified_send_peer_cfr_capture_cmd(pdev_wmi_handle, ¶m); 119 return retv; 120 } 121 122 int target_if_cfr_pdev_set_param(struct wlan_objmgr_pdev *pdev, 123 uint32_t param_id, uint32_t param_value) 124 { 125 struct pdev_params pparam; 126 uint32_t pdev_id; 127 struct wmi_unified *pdev_wmi_handle = NULL; 128 129 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 130 if (pdev_id < 0) 131 return -EINVAL; 132 133 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); 134 if (!pdev_wmi_handle) { 135 cfr_err("pdev wmi handle NULL"); 136 return -EINVAL; 137 } 138 qdf_mem_set(&pparam, sizeof(pparam), 0); 139 pparam.param_id = param_id; 140 pparam.param_value = param_value; 141 142 return wmi_unified_pdev_param_send(pdev_wmi_handle, 143 &pparam, pdev_id); 144 } 145 146 int target_if_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev, 147 uint32_t cfr_timer) 148 { 149 struct pdev_cfr *pa; 150 int retval; 151 152 pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); 153 if (pa == NULL) 154 return QDF_STATUS_E_FAILURE; 155 156 if (!cfr_timer) { 157 /* disable periodic cfr capture */ 158 retval = 159 target_if_cfr_pdev_set_param(pdev, 160 wmi_pdev_param_per_peer_prd_cfr_enable, 161 WMI_HOST_PEER_CFR_TIMER_DISABLE); 162 163 if (retval == QDF_STATUS_SUCCESS) 164 pa->cfr_timer_enable = 0; 165 } else { 166 /* enable periodic cfr capture (default base timer is 10ms ) */ 167 retval = 168 target_if_cfr_pdev_set_param(pdev, 169 wmi_pdev_param_per_peer_prd_cfr_enable, 170 WMI_HOST_PEER_CFR_TIMER_ENABLE); 171 172 if (retval == QDF_STATUS_SUCCESS) 173 pa->cfr_timer_enable = 1; 174 } 175 176 return retval; 177 } 178 179 int target_if_cfr_get_target_type(struct wlan_objmgr_psoc *psoc) 180 { 181 uint32_t target_type = 0; 182 struct wlan_lmac_if_target_tx_ops *target_type_tx_ops; 183 struct wlan_lmac_if_tx_ops *tx_ops; 184 185 tx_ops = wlan_psoc_get_lmac_if_txops(psoc); 186 if (!tx_ops) { 187 cfr_err("tx_ops is NULL"); 188 return target_type; 189 } 190 target_type_tx_ops = &tx_ops->target_tx_ops; 191 192 if (target_type_tx_ops->tgt_get_tgt_type) 193 target_type = target_type_tx_ops->tgt_get_tgt_type(psoc); 194 195 return target_type; 196 } 197 198 #ifdef CFR_USE_FIXED_FOLDER 199 int target_if_cfr_init_pdev(struct wlan_objmgr_psoc *psoc, 200 struct wlan_objmgr_pdev *pdev) 201 { 202 uint32_t target_type; 203 QDF_STATUS status; 204 205 target_type = target_if_cfr_get_target_type(psoc); 206 207 if (target_type == TARGET_TYPE_QCA6490) { 208 status = cfr_6490_init_pdev(psoc, pdev); 209 } else if (target_type == TARGET_TYPE_ADRASTEA) { 210 status = cfr_adrastea_init_pdev(psoc, pdev); 211 } else { 212 cfr_info("unsupport chip"); 213 status = QDF_STATUS_SUCCESS; 214 } 215 216 return qdf_status_to_os_return(status); 217 } 218 219 int target_if_cfr_deinit_pdev(struct wlan_objmgr_psoc *psoc, 220 struct wlan_objmgr_pdev *pdev) 221 { 222 uint32_t target_type; 223 QDF_STATUS status; 224 225 target_type = target_if_cfr_get_target_type(psoc); 226 227 if (target_type == TARGET_TYPE_QCA6490) { 228 status = cfr_6490_deinit_pdev(psoc, pdev); 229 } else if (target_type == TARGET_TYPE_ADRASTEA) { 230 status = cfr_adrastea_deinit_pdev(psoc, pdev); 231 } else { 232 cfr_info("unsupport chip"); 233 status = QDF_STATUS_SUCCESS; 234 } 235 236 return qdf_status_to_os_return(status); 237 } 238 #else 239 int target_if_cfr_init_pdev(struct wlan_objmgr_psoc *psoc, 240 struct wlan_objmgr_pdev *pdev) 241 { 242 uint32_t target_type; 243 struct pdev_cfr *pa; 244 struct psoc_cfr *cfr_sc; 245 246 if (wlan_cfr_is_feature_disabled(pdev)) { 247 cfr_err("cfr is disabled"); 248 return QDF_STATUS_E_NOSUPPORT; 249 } 250 251 pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); 252 if (pa == NULL) 253 return QDF_STATUS_E_FAILURE; 254 255 /* Reset unassociated entries for every init */ 256 qdf_mem_zero(&pa->unassoc_pool[0], MAX_CFR_ENABLED_CLIENTS * 257 sizeof(struct unassoc_pool_entry)); 258 259 cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc, 260 WLAN_UMAC_COMP_CFR); 261 262 if (cfr_sc == NULL) 263 return QDF_STATUS_E_FAILURE; 264 265 target_type = target_if_cfr_get_target_type(psoc); 266 267 if (target_type == TARGET_TYPE_QCA8074V2) { 268 pa->is_cfr_capable = cfr_sc->is_cfr_capable; 269 return cfr_8074v2_init_pdev(psoc, pdev); 270 } else if ((target_type == TARGET_TYPE_IPQ4019) || 271 (target_type == TARGET_TYPE_QCA9984) || 272 (target_type == TARGET_TYPE_QCA9888)) { 273 274 pa->is_cfr_capable = cfr_sc->is_cfr_capable; 275 276 return cfr_wifi2_0_init_pdev(psoc, pdev); 277 } else if ((target_type == TARGET_TYPE_QCA6018) || 278 (target_type == TARGET_TYPE_QCN9000)) { 279 pa->is_cfr_capable = cfr_sc->is_cfr_capable; 280 return cfr_enh_init_pdev(psoc, pdev); 281 } else 282 return QDF_STATUS_E_NOSUPPORT; 283 } 284 285 int target_if_cfr_deinit_pdev(struct wlan_objmgr_psoc *psoc, 286 struct wlan_objmgr_pdev *pdev) 287 { 288 uint32_t target_type; 289 290 if (wlan_cfr_is_feature_disabled(pdev)) { 291 cfr_err("cfr is disabled"); 292 return QDF_STATUS_E_NOSUPPORT; 293 } 294 295 target_type = target_if_cfr_get_target_type(psoc); 296 297 if (target_type == TARGET_TYPE_QCA8074V2) { 298 return cfr_8074v2_deinit_pdev(psoc, pdev); 299 } else if ((target_type == TARGET_TYPE_IPQ4019) || 300 (target_type == TARGET_TYPE_QCA9984) || 301 (target_type == TARGET_TYPE_QCA9888)) { 302 303 return cfr_wifi2_0_deinit_pdev(psoc, pdev); 304 } else if ((target_type == TARGET_TYPE_QCA6018) || 305 (target_type == TARGET_TYPE_QCN9000)) { 306 return cfr_enh_deinit_pdev(psoc, pdev); 307 } else 308 return QDF_STATUS_E_NOSUPPORT; 309 } 310 #endif 311 312 #ifdef WLAN_ENH_CFR_ENABLE 313 #ifdef QCA_WIFI_QCA6490 314 static uint8_t target_if_cfr_get_mac_id(struct wlan_objmgr_pdev *pdev) 315 { 316 struct wlan_objmgr_vdev *vdev; 317 struct wlan_channel *bss_chan; 318 struct pdev_cfr *pcfr; 319 uint8_t mac_id = 0; 320 321 if (!pdev) { 322 cfr_err("null pdev"); 323 return mac_id; 324 } 325 326 mac_id = wlan_objmgr_pdev_get_pdev_id(pdev); 327 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); 328 if (!pcfr) { 329 cfr_err("null pcfr"); 330 return mac_id; 331 } 332 333 if (pcfr->rcc_param.vdev_id == CFR_INVALID_VDEV_ID) 334 return mac_id; 335 336 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, 337 pcfr->rcc_param.vdev_id, 338 WLAN_CFR_ID); 339 if (!vdev) { 340 cfr_err("null vdev"); 341 return mac_id; 342 } 343 344 bss_chan = wlan_vdev_mlme_get_bss_chan(vdev); 345 if (!bss_chan) { 346 cfr_info("null bss chan"); 347 wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); 348 return mac_id; 349 } 350 351 cfr_debug("bss freq %d", bss_chan->ch_freq); 352 if (wlan_reg_is_24ghz_ch_freq(bss_chan->ch_freq)) 353 mac_id = CFR_MAC_ID_24G; 354 else 355 mac_id = CFR_MAC_ID_5G; 356 357 pcfr->rcc_param.srng_id = mac_id; 358 wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); 359 360 return mac_id; 361 } 362 363 static uint8_t target_if_cfr_get_pdev_id(struct wlan_objmgr_pdev *pdev) 364 { 365 return target_if_cfr_get_mac_id(pdev); 366 } 367 #else 368 static uint8_t target_if_cfr_get_pdev_id(struct wlan_objmgr_pdev *pdev) 369 { 370 return wlan_objmgr_pdev_get_pdev_id(pdev); 371 } 372 #endif /* QCA_WIFI_QCA6490 */ 373 374 QDF_STATUS target_if_cfr_config_rcc(struct wlan_objmgr_pdev *pdev, 375 struct cfr_rcc_param *rcc_info) 376 { 377 QDF_STATUS status; 378 struct wmi_unified *pdev_wmi_handle = NULL; 379 380 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); 381 if (!pdev_wmi_handle) { 382 cfr_err("pdev_wmi_handle is null"); 383 return QDF_STATUS_E_NULL_VALUE; 384 } 385 386 rcc_info->pdev_id = target_if_cfr_get_pdev_id(pdev); 387 rcc_info->num_grp_tlvs = 388 count_set_bits(rcc_info->modified_in_curr_session); 389 390 status = wmi_unified_send_cfr_rcc_cmd(pdev_wmi_handle, rcc_info); 391 return status; 392 } 393 394 void target_if_cfr_default_ta_ra_config(struct cfr_rcc_param *rcc_info, 395 bool allvalid, uint16_t reset_cfg) 396 { 397 struct ta_ra_cfr_cfg *curr_cfg = NULL; 398 int grp_id; 399 unsigned long bitmap = reset_cfg; 400 uint8_t def_mac[QDF_MAC_ADDR_SIZE] = {0xFF, 0xFF, 0xFF, 401 0xFF, 0xFF, 0xFF}; 402 uint8_t null_mac[QDF_MAC_ADDR_SIZE] = {0x00, 0x00, 0x00, 403 0x00, 0x00, 0x00}; 404 405 for (grp_id = 0; grp_id < MAX_TA_RA_ENTRIES; grp_id++) { 406 if (qdf_test_bit(grp_id, &bitmap)) { 407 curr_cfg = &rcc_info->curr[grp_id]; 408 qdf_mem_copy(curr_cfg->tx_addr, 409 null_mac, QDF_MAC_ADDR_SIZE); 410 qdf_mem_copy(curr_cfg->tx_addr_mask, 411 def_mac, QDF_MAC_ADDR_SIZE); 412 qdf_mem_copy(curr_cfg->rx_addr, 413 null_mac, QDF_MAC_ADDR_SIZE); 414 qdf_mem_copy(curr_cfg->rx_addr_mask, 415 def_mac, QDF_MAC_ADDR_SIZE); 416 curr_cfg->bw = 0xf; 417 curr_cfg->nss = 0xff; 418 curr_cfg->mgmt_subtype_filter = 0; 419 curr_cfg->ctrl_subtype_filter = 0; 420 curr_cfg->data_subtype_filter = 0; 421 if (!allvalid) { 422 curr_cfg->valid_ta = 0; 423 curr_cfg->valid_ta_mask = 0; 424 curr_cfg->valid_ra = 0; 425 curr_cfg->valid_ra_mask = 0; 426 curr_cfg->valid_bw_mask = 0; 427 curr_cfg->valid_nss_mask = 0; 428 curr_cfg->valid_mgmt_subtype = 0; 429 curr_cfg->valid_ctrl_subtype = 0; 430 curr_cfg->valid_data_subtype = 0; 431 } else { 432 curr_cfg->valid_ta = 1; 433 curr_cfg->valid_ta_mask = 1; 434 curr_cfg->valid_ra = 1; 435 curr_cfg->valid_ra_mask = 1; 436 curr_cfg->valid_bw_mask = 1; 437 curr_cfg->valid_nss_mask = 1; 438 curr_cfg->valid_mgmt_subtype = 1; 439 curr_cfg->valid_ctrl_subtype = 1; 440 curr_cfg->valid_data_subtype = 1; 441 } 442 } 443 } 444 } 445 #endif 446 447 #ifdef WLAN_ENH_CFR_ENABLE 448 #ifdef CFR_USE_FIXED_FOLDER 449 static void target_if_enh_cfr_add_ops(struct wlan_lmac_if_tx_ops *tx_ops) 450 { 451 tx_ops->cfr_tx_ops.cfr_subscribe_ppdu_desc = 452 target_if_cfr_subscribe_ppdu_desc; 453 } 454 #else 455 static void target_if_enh_cfr_add_ops(struct wlan_lmac_if_tx_ops *tx_ops) 456 { 457 } 458 #endif /* CFR_USE_FIXED_FOLDER */ 459 static void target_if_enh_cfr_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) 460 { 461 tx_ops->cfr_tx_ops.cfr_config_rcc = 462 target_if_cfr_config_rcc; 463 tx_ops->cfr_tx_ops.cfr_start_lut_timer = 464 target_if_cfr_start_lut_age_timer; 465 tx_ops->cfr_tx_ops.cfr_stop_lut_timer = 466 target_if_cfr_stop_lut_age_timer; 467 tx_ops->cfr_tx_ops.cfr_default_ta_ra_cfg = 468 target_if_cfr_default_ta_ra_config; 469 tx_ops->cfr_tx_ops.cfr_dump_lut_enh = 470 target_if_cfr_dump_lut_enh; 471 tx_ops->cfr_tx_ops.cfr_rx_tlv_process = 472 target_if_cfr_rx_tlv_process; 473 tx_ops->cfr_tx_ops.cfr_update_global_cfg = 474 target_if_cfr_update_global_cfg; 475 target_if_enh_cfr_add_ops(tx_ops); 476 } 477 #else 478 static void target_if_enh_cfr_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) 479 { 480 } 481 #endif 482 483 void target_if_cfr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) 484 { 485 tx_ops->cfr_tx_ops.cfr_init_pdev = 486 target_if_cfr_init_pdev; 487 tx_ops->cfr_tx_ops.cfr_deinit_pdev = 488 target_if_cfr_deinit_pdev; 489 tx_ops->cfr_tx_ops.cfr_enable_cfr_timer = 490 target_if_cfr_enable_cfr_timer; 491 tx_ops->cfr_tx_ops.cfr_start_capture = 492 target_if_cfr_start_capture; 493 tx_ops->cfr_tx_ops.cfr_stop_capture = 494 target_if_cfr_stop_capture; 495 target_if_enh_cfr_tx_ops(tx_ops); 496 } 497 498 void target_if_cfr_set_cfr_support(struct wlan_objmgr_psoc *psoc, 499 uint8_t value) 500 { 501 struct wlan_lmac_if_rx_ops *rx_ops; 502 503 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 504 if (!rx_ops) { 505 cfr_err("rx_ops is NULL"); 506 return; 507 } 508 if (rx_ops->cfr_rx_ops.cfr_support_set) 509 rx_ops->cfr_rx_ops.cfr_support_set(psoc, value); 510 } 511 512 QDF_STATUS 513 target_if_cfr_set_capture_count_support(struct wlan_objmgr_psoc *psoc, 514 uint8_t value) 515 { 516 struct wlan_lmac_if_rx_ops *rx_ops; 517 518 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 519 if (!rx_ops) { 520 cfr_err("rx_ops is NULL"); 521 return QDF_STATUS_E_INVAL; 522 } 523 524 if (rx_ops->cfr_rx_ops.cfr_capture_count_support_set) 525 return rx_ops->cfr_rx_ops.cfr_capture_count_support_set( 526 psoc, value); 527 528 return QDF_STATUS_E_INVAL; 529 } 530 531 QDF_STATUS 532 target_if_cfr_set_mo_marking_support(struct wlan_objmgr_psoc *psoc, 533 uint8_t value) 534 { 535 struct wlan_lmac_if_rx_ops *rx_ops; 536 537 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 538 if (!rx_ops) { 539 cfr_err("rx_ops is NULL"); 540 return QDF_STATUS_E_INVAL; 541 } 542 543 if (rx_ops->cfr_rx_ops.cfr_mo_marking_support_set) 544 return rx_ops->cfr_rx_ops.cfr_mo_marking_support_set( 545 psoc, value); 546 547 return QDF_STATUS_E_INVAL; 548 } 549 550 void target_if_cfr_info_send(struct wlan_objmgr_pdev *pdev, void *head, 551 size_t hlen, void *data, size_t dlen, void *tail, 552 size_t tlen) 553 { 554 struct wlan_objmgr_psoc *psoc; 555 struct wlan_lmac_if_rx_ops *rx_ops; 556 557 psoc = wlan_pdev_get_psoc(pdev); 558 559 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 560 if (!rx_ops) { 561 cfr_err("rx_ops is NULL"); 562 return; 563 } 564 if (rx_ops->cfr_rx_ops.cfr_info_send) 565 rx_ops->cfr_rx_ops.cfr_info_send(pdev, head, hlen, data, dlen, 566 tail, tlen); 567 } 568