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