1 /* 2 * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 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 #include <target_if_cfr.h> 21 #include <wlan_tgt_def_config.h> 22 #include <target_type.h> 23 #include <hif_hw_version.h> 24 #include <target_if.h> 25 #include <wlan_lmac_if_def.h> 26 #include <wlan_osif_priv.h> 27 #include <init_deinit_lmac.h> 28 #include <wlan_cfr_utils_api.h> 29 #include <target_if_direct_buf_rx_api.h> 30 #include <target_if_cfr_enh.h> 31 #include "cdp_txrx_ctrl.h" 32 #include <wlan_reg_services_api.h> 33 34 #define CMN_NOISE_FLOOR (-96) 35 #define NUM_CHAINS_FW_TO_HOST(n) ((1 << ((n) + 1)) - 1) 36 37 #define CFR_INVALID_SNR 0x80 38 #define CHAIN_SHIFT_INDEX_PINE_SCAN 2 39 40 static u_int32_t end_magic = 0xBEAFDEAD; 41 42 /** 43 * snr_to_signal_strength() - Convert SNR(dB) to signal strength(dBm) 44 * @snr: SNR in dB 45 * 46 * Return: signal strength in dBm 47 */ 48 #if defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_KIWI) 49 static inline 50 u_int32_t snr_to_signal_strength(uint8_t snr) 51 { 52 /* target onverts snr to dBm */ 53 return snr; 54 } 55 #else 56 static inline 57 u_int32_t snr_to_signal_strength(uint8_t snr) 58 { 59 /* SNR value 0x80 indicates -128dB which is not a valid value */ 60 return (snr != CFR_INVALID_SNR) ? 61 (((int8_t)snr) + CMN_NOISE_FLOOR) : 62 ((int8_t)snr); 63 } 64 #endif 65 66 /** 67 * target_if_snr_to_signal_strength() - wrapper API to snr_to_signal_strength to 68 * consider target_type. 69 * @target_type: target type of the pdev 70 * @meta: pointer to CFR metadata 71 * @ppdu: rx ppdu having per chain rssi to be converted to dBm 72 * 73 * Return: none 74 */ 75 static inline 76 void target_if_snr_to_signal_strength(uint32_t target_type, 77 struct enh_cfr_metadata *meta, 78 struct cdp_rx_indication_ppdu *ppdu) 79 { 80 uint8_t i; 81 82 /* No need to add CMN_NOISE_FLOOR for york */ 83 if (target_type == TARGET_TYPE_QCN9160) { 84 for (i = 0; i < MAX_CHAIN; i++) { 85 meta->chain_rssi[i] = (int8_t)ppdu->per_chain_rssi[i]; 86 } 87 } else { 88 for (i = 0; i < MAX_CHAIN; i++) { 89 meta->chain_rssi[i] = 90 snr_to_signal_strength(ppdu->per_chain_rssi[i]); 91 } 92 } 93 } 94 95 /** 96 * get_lut_entry() - Retrieve LUT entry using cookie number 97 * @pcfr: PDEV CFR object 98 * @offset: cookie number 99 * 100 * Return: look up table entry 101 */ 102 static struct look_up_table *get_lut_entry(struct pdev_cfr *pcfr, 103 int offset) 104 { 105 if (offset >= pcfr->lut_num) { 106 cfr_err("Invalid offset %d, lut_num %d", 107 offset, pcfr->lut_num); 108 return NULL; 109 } 110 111 return pcfr->lut[offset]; 112 } 113 114 /** 115 * release_lut_entry_enh() - Clear all params in an LUT entry 116 * @pdev: objmgr PDEV 117 * @lut: pointer to LUT 118 * 119 * Return: status 120 */ 121 static int release_lut_entry_enh(struct wlan_objmgr_pdev *pdev, 122 struct look_up_table *lut) 123 { 124 lut->dbr_recv = false; 125 lut->tx_recv = false; 126 lut->data = NULL; 127 lut->data_len = 0; 128 lut->dbr_ppdu_id = 0; 129 lut->tx_ppdu_id = 0; 130 lut->dbr_tstamp = 0; 131 lut->txrx_tstamp = 0; 132 lut->tx_address1 = 0; 133 lut->tx_address2 = 0; 134 lut->dbr_address = 0; 135 qdf_mem_zero(&lut->header, sizeof(struct csi_cfr_header)); 136 137 return 0; 138 } 139 140 /** 141 * target_if_cfr_dump_lut_enh() - dump all valid lut entries 142 * @pdev: objmgr pdev 143 * 144 * return: none 145 */ 146 void target_if_cfr_dump_lut_enh(struct wlan_objmgr_pdev *pdev) 147 { 148 struct pdev_cfr *pcfr; 149 struct look_up_table *lut = NULL; 150 int i = 0; 151 uint64_t diff; 152 QDF_STATUS retval = 0; 153 154 retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID); 155 if (retval != QDF_STATUS_SUCCESS) { 156 cfr_err("failed to get pdev reference"); 157 return; 158 } 159 160 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 161 WLAN_UMAC_COMP_CFR); 162 if (!pcfr) { 163 cfr_err("pdev object for CFR is null"); 164 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 165 return; 166 } 167 168 qdf_spin_lock_bh(&pcfr->lut_lock); 169 170 for (i = 0; i < pcfr->lut_num; i++) { 171 lut = get_lut_entry(pcfr, i); 172 if (!lut) 173 continue; 174 if (lut->dbr_recv ^ lut->tx_recv) { 175 diff = (lut->dbr_tstamp > lut->txrx_tstamp) ? 176 (lut->dbr_tstamp - lut->txrx_tstamp) : 177 (lut->txrx_tstamp - lut->dbr_tstamp); 178 } 179 } 180 181 qdf_spin_unlock_bh(&pcfr->lut_lock); 182 183 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 184 } 185 186 /** 187 * cfr_free_pending_dbr_events() - Flush all pending DBR events. This is useful 188 * in cases where for RXTLV drops in host monitor status ring is huge. 189 * @pdev: objmgr pdev 190 * 191 * return: none 192 */ 193 static void cfr_free_pending_dbr_events(struct wlan_objmgr_pdev *pdev) 194 { 195 struct pdev_cfr *pcfr; 196 struct look_up_table *lut = NULL; 197 int i = 0; 198 QDF_STATUS retval = 0; 199 200 retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID); 201 if (retval != QDF_STATUS_SUCCESS) { 202 cfr_err("failed to get pdev reference"); 203 return; 204 } 205 206 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 207 WLAN_UMAC_COMP_CFR); 208 if (!pcfr) { 209 cfr_err("pdev object for CFR is null"); 210 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 211 return; 212 } 213 214 for (i = 0; i < pcfr->lut_num; i++) { 215 lut = get_lut_entry(pcfr, i); 216 if (!lut) 217 continue; 218 219 if (lut->dbr_recv && !lut->tx_recv && 220 (lut->dbr_tstamp < pcfr->last_success_tstamp)) { 221 target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, 222 lut->dbr_address, 223 i, 0); 224 pcfr->flush_dbr_cnt++; 225 release_lut_entry_enh(pdev, lut); 226 } 227 } 228 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 229 } 230 231 /** 232 * dump_freeze_tlv() - Dump freeze TLV sent in enhanced DMA header 233 * @freeze_tlv: Freeze TLV sent from MAC to PHY 234 * @cookie: Index into lookup table 235 * 236 * Return: none 237 */ 238 static void dump_freeze_tlv(void *freeze_tlv, uint32_t cookie) 239 { 240 struct macrx_freeze_capture_channel *freeze = 241 (struct macrx_freeze_capture_channel *)freeze_tlv; 242 243 cfr_debug("<DBRCOMP><FREEZE><%u>\n" 244 "freeze: %d capture_reason: %d packet_type: 0x%x\n" 245 "packet_subtype: 0x%x sw_peer_id_valid: %d sw_peer_id: %d\n" 246 "phy_ppdu_id: 0x%04x packet_ta_upper_16: 0x%04x\n" 247 "packet_ta_mid_16: 0x%04x packet_ta_lower_16: 0x%04x\n" 248 "packet_ra_upper_16: 0x%04x packet_ra_mid_16: 0x%04x\n" 249 "packet_ra_lower_16: 0x%04x tsf_timestamp_63_48: 0x%04x\n" 250 "tsf_timestamp_47_32: 0x%04x tsf_timestamp_31_16: 0x%04x\n" 251 "tsf_timestamp_15_0: 0x%04x user_index_or_user_mask_5_0: %d\n" 252 "directed: %d\n", 253 cookie, 254 freeze->freeze, 255 freeze->capture_reason, 256 freeze->packet_type, 257 freeze->packet_sub_type, 258 freeze->sw_peer_id_valid, 259 freeze->sw_peer_id, 260 freeze->phy_ppdu_id, 261 freeze->packet_ta_upper_16, 262 freeze->packet_ta_mid_16, 263 freeze->packet_ta_lower_16, 264 freeze->packet_ra_upper_16, 265 freeze->packet_ra_mid_16, 266 freeze->packet_ra_lower_16, 267 freeze->tsf_timestamp_63_48, 268 freeze->tsf_timestamp_47_32, 269 freeze->tsf_timestamp_31_16, 270 freeze->tsf_timestamp_15_0, 271 freeze->user_index_or_user_mask_5_0, 272 freeze->directed); 273 } 274 275 /** 276 * dump_freeze_tlv_v3() - Dump freeze TLV v2 sent in enhanced DMA header 277 * @freeze_tlv: Freeze TLV sent from MAC to PHY 278 * @cookie: Index into lookup table 279 * 280 * Return: none 281 */ 282 static void dump_freeze_tlv_v3(void *freeze_tlv, uint32_t cookie) 283 { 284 struct macrx_freeze_capture_channel_v3 *freeze = 285 (struct macrx_freeze_capture_channel_v3 *)freeze_tlv; 286 287 cfr_debug("<DBRCOMP><FREEZE><%u>\n" 288 "freeze: %d capture_reason: %d packet_type: 0x%x\n" 289 "packet_subtype: 0x%x sw_peer_id_valid: %d sw_peer_id: %d\n" 290 "phy_ppdu_id: 0x%04x packet_ta_upper_16: 0x%04x\n" 291 "packet_ta_mid_16: 0x%04x packet_ta_lower_16: 0x%04x\n" 292 "packet_ra_upper_16: 0x%04x packet_ra_mid_16: 0x%04x\n" 293 "packet_ra_lower_16: 0x%04x\n" 294 "tsf_63_48_or_user_mask_36_32: 0x%04x\n" 295 "tsf_timestamp_47_32: 0x%04x\n" 296 "tsf_timestamp_31_16: 0x%04x\n" 297 "tsf_timestamp_15_0: 0x%04x\n" 298 "user_index_or_user_mask_15_0: 0x%04x\n" 299 "user_mask_31_16: 0x%04x\n" 300 "directed: %d\n", 301 cookie, 302 freeze->freeze, 303 freeze->capture_reason, 304 freeze->packet_type, 305 freeze->packet_sub_type, 306 freeze->sw_peer_id_valid, 307 freeze->sw_peer_id, 308 freeze->phy_ppdu_id, 309 freeze->packet_ta_upper_16, 310 freeze->packet_ta_mid_16, 311 freeze->packet_ta_lower_16, 312 freeze->packet_ra_upper_16, 313 freeze->packet_ra_mid_16, 314 freeze->packet_ra_lower_16, 315 freeze->tsf_63_48_or_user_mask_36_32, 316 freeze->tsf_timestamp_47_32, 317 freeze->tsf_timestamp_31_16, 318 freeze->tsf_timestamp_15_0, 319 freeze->user_index_or_user_mask_15_0, 320 freeze->user_mask_31_16, 321 freeze->directed); 322 } 323 324 /** 325 * dump_freeze_tlv_v5() - Dump freeze TLV sent in enhanced DMA header 326 * @freeze_tlv: Freeze TLV sent from MAC to PHY 327 * @cookie: Index into lookup table 328 * 329 * Return: none 330 */ 331 static void dump_freeze_tlv_v5(void *freeze_tlv, uint32_t cookie) 332 { 333 struct macrx_freeze_capture_channel_v5 *freeze = 334 (struct macrx_freeze_capture_channel_v5 *)freeze_tlv; 335 336 cfr_debug("<DBRCOMP><FREEZE><%u>\n" 337 "freeze: %d capture_reason: %d packet_type: 0x%x\n" 338 "packet_subtype: 0x%x sw_peer_id_valid: %d sw_peer_id: %d\n" 339 "phy_ppdu_id: 0x%04x packet_ta_lower_16: 0x%04x\n" 340 "packet_ta_mid_16: 0x%04x packet_ta_upper_16: 0x%04x\n" 341 "packet_ra_lower_16: 0x%04x packet_ra_mid_16: 0x%04x\n" 342 "packet_ra_upper_16: 0x%04x\n" 343 "tsf_timestamp_15_0: 0x%04x\n" 344 "tsf_timestamp_31_16: 0x%04x\n" 345 "tsf_timestamp_47_32: 0x%04x\n" 346 "tsf_timestamp_63_48: 0x%04x\n" 347 "user_index_or_user_mask_5_0: 0x%04x\n" 348 "directed: %d\n" 349 "user_mask_21_6: 0x%04x\n" 350 "user_mask_36_22: 0x%04x\n", 351 cookie, 352 freeze->freeze, 353 freeze->capture_reason, 354 freeze->packet_type, 355 freeze->packet_sub_type, 356 freeze->sw_peer_id_valid, 357 freeze->sw_peer_id, 358 freeze->phy_ppdu_id, 359 freeze->packet_ta_lower_16, 360 freeze->packet_ta_mid_16, 361 freeze->packet_ta_upper_16, 362 freeze->packet_ra_lower_16, 363 freeze->packet_ra_mid_16, 364 freeze->packet_ra_upper_16, 365 freeze->tsf_timestamp_15_0, 366 freeze->tsf_timestamp_31_16, 367 freeze->tsf_timestamp_47_32, 368 freeze->tsf_timestamp_63_48, 369 freeze->user_index_or_user_mask_5_0, 370 freeze->directed, 371 freeze->user_mask_21_6, 372 freeze->user_mask_36_22); 373 } 374 375 /** 376 * dump_mu_rx_info() - Dump MU info in enhanced DMA header 377 * @mu_rx_user_info: MU info sent by ucode 378 * @mu_rx_num_users: Number of MU users in UL-MU-PPDU 379 * @cookie: Index into lookup table 380 * 381 * Return: none 382 */ 383 static void dump_mu_rx_info(void *mu_rx_user_info, 384 uint8_t mu_rx_num_users, 385 uint32_t cookie) 386 { 387 uint8_t i; 388 struct uplink_user_setup_info *ul_mu_user_info = 389 (struct uplink_user_setup_info *)mu_rx_user_info; 390 391 for (i = 0 ; i < mu_rx_num_users; i++) { 392 cfr_debug("<DBRCOMP><MU><%u>\n" 393 "<user_id:%d>\n" 394 "bw_info_valid = %d\n" 395 "uplink_receive_type = %d\n" 396 "uplink_11ax_mcs = %d\n" 397 "ru_width = %d\n" 398 "nss = %d\n" 399 "stream_offset = %d\n" 400 "sta_dcm = %d\n" 401 "sta_coding = %d\n" 402 "ru_start_index = %d\n", 403 cookie, 404 i, 405 ul_mu_user_info->bw_info_valid, 406 ul_mu_user_info->uplink_receive_type, 407 ul_mu_user_info->uplink_11ax_mcs, 408 ul_mu_user_info->ru_width, 409 ul_mu_user_info->nss, 410 ul_mu_user_info->stream_offset, 411 ul_mu_user_info->sta_dcm, 412 ul_mu_user_info->sta_coding, 413 ul_mu_user_info->ru_start_index); 414 ul_mu_user_info += sizeof(struct uplink_user_setup_info); 415 } 416 } 417 418 /** 419 * dump_mu_rx_info_v2() - Dump MU info in enhanced DMA header 420 * @mu_rx_user_info: MU info sent by ucode 421 * @mu_rx_num_users: Number of MU users in UL-MU-PPDU 422 * @cookie: Index into lookup table 423 * 424 * Return: none 425 */ 426 static void dump_mu_rx_info_v2(void *mu_rx_user_info, 427 uint8_t mu_rx_num_users, 428 uint32_t cookie) 429 { 430 uint8_t i; 431 struct uplink_user_setup_info_v2 *ul_mu_user_info = 432 (struct uplink_user_setup_info_v2 *)mu_rx_user_info; 433 434 for (i = 0 ; i < mu_rx_num_users; i++) { 435 cfr_debug("<DBRCOMP><MU><%u>\n" 436 "<user_id:%d>\n" 437 "bw_info_valid = %d\n" 438 "uplink_receive_type = %d\n" 439 "uplink_11ax_mcs = %d\n" 440 "nss = %d\n" 441 "stream_offset = %d\n" 442 "sta_dcm = %d\n" 443 "sta_coding = %d\n" 444 "ru_type_80_0 = %d\n" 445 "ru_type_80_1 = %d\n" 446 "ru_type_80_2 = %d\n" 447 "ru_type_80_3 = %d\n" 448 "ru_start_index_80_0 = %d\n" 449 "ru_start_index_80_1 = %d\n" 450 "ru_start_index_80_2 = %d\n" 451 "ru_start_index_80_3 = %d\n", 452 cookie, 453 i, 454 ul_mu_user_info->bw_info_valid, 455 ul_mu_user_info->uplink_receive_type, 456 ul_mu_user_info->uplink_11ax_mcs, 457 ul_mu_user_info->nss, 458 ul_mu_user_info->stream_offset, 459 ul_mu_user_info->sta_dcm, 460 ul_mu_user_info->sta_coding, 461 ul_mu_user_info->ru_type_80_0, 462 ul_mu_user_info->ru_type_80_1, 463 ul_mu_user_info->ru_type_80_2, 464 ul_mu_user_info->ru_type_80_3, 465 ul_mu_user_info->ru_start_index_80_0, 466 ul_mu_user_info->ru_start_index_80_1, 467 ul_mu_user_info->ru_start_index_80_2, 468 ul_mu_user_info->ru_start_index_80_3); 469 ul_mu_user_info += sizeof(struct uplink_user_setup_info_v2); 470 } 471 } 472 473 static void dump_metadata(struct csi_cfr_header *header, uint32_t cookie) 474 { 475 uint8_t user_id, chain_id; 476 struct enh_cfr_metadata *meta = &header->u.meta_enh; 477 uint8_t *usermac = NULL; 478 479 cfr_debug("<METADATA><%u>\n" 480 "start_magic_num = 0x%x\n" 481 "vendorid = 0x%x\n" 482 "cfr_metadata_version = %d\n" 483 "cfr_data_version = %d\n" 484 "cfr_metadata_len = %d\n" 485 "chip_type = %d\n" 486 "platform_type = %d\n" 487 "status = %d\n" 488 "capture_bw = %d\n" 489 "channel_bw = %d\n" 490 "phy_mode = %d\n" 491 "prim20_chan = %d\n" 492 "center_freq1 = %d\n" 493 "center_freq2 = %d\n" 494 "ack_capture_mode = %d\n" 495 "cfr_capture_type = %d\n" 496 "sts_count = %d\n" 497 "num_rx_chain = %d\n" 498 "timestamp = %llu\n" 499 "length = %d\n" 500 "is_mu_ppdu = %d\n" 501 "num_users = %d\n", 502 cookie, 503 header->cmn.start_magic_num, 504 header->cmn.vendorid, 505 header->cmn.cfr_metadata_version, 506 header->cmn.cfr_data_version, 507 header->cmn.cfr_metadata_len, 508 header->cmn.chip_type, 509 header->cmn.pltform_type, 510 meta->status, 511 meta->capture_bw, 512 meta->channel_bw, 513 meta->phy_mode, 514 meta->prim20_chan, 515 meta->center_freq1, 516 meta->center_freq2, 517 meta->capture_mode, 518 meta->capture_type, 519 meta->sts_count, 520 meta->num_rx_chain, 521 meta->timestamp, 522 meta->length, 523 meta->is_mu_ppdu, 524 meta->num_mu_users); 525 526 if (meta->is_mu_ppdu) { 527 for (user_id = 0; user_id < meta->num_mu_users; user_id++) { 528 usermac = meta->peer_addr.mu_peer_addr[user_id]; 529 cfr_debug("peermac[%d]: " QDF_MAC_ADDR_FMT, 530 user_id, QDF_MAC_ADDR_REF(usermac)); 531 } 532 } else { 533 cfr_debug("peermac: " QDF_MAC_ADDR_FMT, 534 QDF_MAC_ADDR_REF(meta->peer_addr.su_peer_addr)); 535 } 536 537 for (chain_id = 0; chain_id < HOST_MAX_CHAINS; chain_id++) { 538 cfr_debug("chain_rssi[%d] = %d\n", 539 chain_id, 540 meta->chain_rssi[chain_id]); 541 } 542 543 for (chain_id = 0; chain_id < HOST_MAX_CHAINS; chain_id++) { 544 cfr_debug("chain_phase[%d] = %d\n", 545 chain_id, 546 meta->chain_phase[chain_id]); 547 } 548 549 if (header->cmn.cfr_metadata_version >= CFR_META_VERSION_5) { 550 cfr_debug("rtt_cfo_measurement = %d\n", 551 meta->rtt_cfo_measurement); 552 cfr_debug("rx_start_ts = %u\n", meta->rx_start_ts); 553 554 for (chain_id = 0; chain_id < HOST_MAX_CHAINS; chain_id++) { 555 cfr_debug("agc_gain[%d] = %d\n", 556 chain_id, 557 meta->agc_gain[chain_id]); 558 cfr_debug("agc_gain_tbl_idx[%d] = %d\n", 559 chain_id, 560 meta->agc_gain_tbl_index[chain_id]); 561 } 562 563 cfr_debug("mcs_rate = %u\n", meta->mcs_rate); 564 cfr_debug("gi_type = %u\n", meta->gi_type); 565 } 566 } 567 568 /** 569 * dump_enh_dma_hdr() - Dump enhanced DMA header populated by ucode 570 * @dma_hdr: pointer to enhanced DMA header 571 * @freeze_tlv: pointer to MACRX_FREEZE_CAPTURE_CHANNEL TLV 572 * @mu_rx_user_info: UPLINK_USER_SETUP_INFO TLV 573 * @header: pointer to metadata passed to userspace 574 * @error: Indicates whether it is an error 575 * @cookie: Index into lookup table 576 * 577 * Return: none 578 */ 579 static void dump_enh_dma_hdr(struct whal_cfir_enhanced_hdr *dma_hdr, 580 void *freeze_tlv, void *mu_rx_user_info, 581 struct csi_cfr_header *header, int error, 582 uint32_t cookie) 583 { 584 if (!error) { 585 if (dma_hdr->header_version == UPLOAD_HEADER_VERSION_9) { 586 cfr_debug("<DBRCOMP><%u>\n" 587 "Tag: 0x%02x Length: %d udone: %d\n" 588 "ctype: %d preamble: %d Nss: %d\n" 589 "num_chains: %d bw: %d peervalid: %d\n" 590 "peer_id: %d ppdu_id: 0x%04x\n" 591 "total_bytes: %d header_version: %d\n" 592 "target_id: %d cfr_fmt: %d\n" 593 "mu_rx_data_incl: %d freeze_data_incl: %d\n" 594 "mu_rx_num_users: %d decimation_factor: %d\n" 595 "freeze_tlv_version: %d\n" 596 "he_ltf_type: %u ext_preamble_type = %u\n", 597 cookie, 598 dma_hdr->tag, 599 dma_hdr->length, 600 dma_hdr->upload_done, 601 dma_hdr->capture_type, 602 dma_hdr->preamble_type, 603 dma_hdr->nss, 604 dma_hdr->num_chains, 605 dma_hdr->upload_pkt_bw, 606 dma_hdr->sw_peer_id_valid, 607 dma_hdr->sw_peer_id, 608 dma_hdr->phy_ppdu_id, 609 dma_hdr->total_bytes, 610 dma_hdr->header_version, 611 dma_hdr->target_id, 612 dma_hdr->cfr_fmt, 613 dma_hdr->mu_rx_data_incl, 614 dma_hdr->freeze_data_incl, 615 dma_hdr->mu_rx_num_users, 616 dma_hdr->decimation_factor, 617 dma_hdr->freeze_tlv_version, 618 dma_hdr->rsvd3, 619 dma_hdr->rsvd4); 620 621 } else { 622 cfr_debug("<DBRCOMP><%u>\n" 623 "Tag: 0x%02x Length: %d udone: %d\n" 624 "ctype: %d preamble: %d Nss: %d\n" 625 "num_chains: %d bw: %d peervalid: %d\n" 626 "peer_id: %d ppdu_id: 0x%04x\n" 627 "total_bytes: %d header_version: %d\n" 628 "target_id: %d cfr_fmt: %d\n" 629 "mu_rx_data_incl: %d freeze_data_incl: %d\n" 630 "mu_rx_num_users: %d decimation_factor: %d\n" 631 "freeze_tlv_version: %d\n", 632 cookie, 633 dma_hdr->tag, 634 dma_hdr->length, 635 dma_hdr->upload_done, 636 dma_hdr->capture_type, 637 dma_hdr->preamble_type, 638 dma_hdr->nss, 639 dma_hdr->num_chains, 640 dma_hdr->upload_pkt_bw, 641 dma_hdr->sw_peer_id_valid, 642 dma_hdr->sw_peer_id, 643 dma_hdr->phy_ppdu_id, 644 dma_hdr->total_bytes, 645 dma_hdr->header_version, 646 dma_hdr->target_id, 647 dma_hdr->cfr_fmt, 648 dma_hdr->mu_rx_data_incl, 649 dma_hdr->freeze_data_incl, 650 dma_hdr->mu_rx_num_users, 651 dma_hdr->decimation_factor, 652 dma_hdr->freeze_tlv_version); 653 } 654 655 if (dma_hdr->freeze_data_incl) { 656 if (dma_hdr->freeze_tlv_version == 657 MACRX_FREEZE_TLV_VERSION_3) 658 dump_freeze_tlv_v3(freeze_tlv, cookie); 659 else if (dma_hdr->freeze_tlv_version == 660 MACRX_FREEZE_TLV_VERSION_5) 661 dump_freeze_tlv_v5(freeze_tlv, cookie); 662 else 663 dump_freeze_tlv(freeze_tlv, cookie); 664 } 665 666 if ((dma_hdr->mu_rx_data_incl) && 667 (dma_hdr->freeze_tlv_version == 668 MACRX_FREEZE_TLV_VERSION_5)) { 669 dump_mu_rx_info_v2(mu_rx_user_info, 670 dma_hdr->mu_rx_num_users, 671 cookie); 672 } else if (dma_hdr->mu_rx_data_incl) { 673 dump_mu_rx_info(mu_rx_user_info, 674 dma_hdr->mu_rx_num_users, 675 cookie); 676 } 677 } else { 678 cfr_err("<DBRCOMP><%u>\n" 679 "Tag: 0x%02x Length: %d udone: %d\n" 680 "ctype: %d preamble: %d Nss: %d\n" 681 "num_chains: %d bw: %d peervalid: %d\n" 682 "peer_id: %d ppdu_id: 0x%04x total_bytes: %d\n" 683 "header_version: %d target_id: %d cfr_fmt: %d\n" 684 "mu_rx_data_incl: %d freeze_data_incl: %d\n" 685 "mu_rx_num_users: %d decimation_factor: %d\n" 686 "freeze_tlv_version: %d\n", 687 cookie, 688 dma_hdr->tag, 689 dma_hdr->length, 690 dma_hdr->upload_done, 691 dma_hdr->capture_type, 692 dma_hdr->preamble_type, 693 dma_hdr->nss, 694 dma_hdr->num_chains, 695 dma_hdr->upload_pkt_bw, 696 dma_hdr->sw_peer_id_valid, 697 dma_hdr->sw_peer_id, 698 dma_hdr->phy_ppdu_id, 699 dma_hdr->total_bytes, 700 dma_hdr->header_version, 701 dma_hdr->target_id, 702 dma_hdr->cfr_fmt, 703 dma_hdr->mu_rx_data_incl, 704 dma_hdr->freeze_data_incl, 705 dma_hdr->mu_rx_num_users, 706 dma_hdr->decimation_factor, 707 dma_hdr->freeze_tlv_version); 708 } 709 } 710 711 /** 712 * extract_peer_mac_from_freeze_tlv() - extract macaddr from freeze tlv 713 * @freeze_tlv: Freeze TLV sent from MAC to PHY 714 * @peermac: macaddr of the peer 715 * 716 * Return: none 717 */ 718 static void 719 extract_peer_mac_from_freeze_tlv(void *freeze_tlv, uint8_t *peermac) 720 { 721 /* 722 * Packet_ta fields position is common between freeze tlv v1 723 * and v2, hence typecasting to v1 is also fine 724 */ 725 struct macrx_freeze_capture_channel *freeze = 726 (struct macrx_freeze_capture_channel *)freeze_tlv; 727 728 peermac[0] = freeze->packet_ta_lower_16 & 0x00FF; 729 peermac[1] = (freeze->packet_ta_lower_16 & 0xFF00) >> 8; 730 peermac[2] = freeze->packet_ta_mid_16 & 0x00FF; 731 peermac[3] = (freeze->packet_ta_mid_16 & 0xFF00) >> 8; 732 peermac[4] = freeze->packet_ta_upper_16 & 0x00FF; 733 peermac[5] = (freeze->packet_ta_upper_16 & 0xFF00) >> 8; 734 } 735 736 /** 737 * check_dma_length() - Sanity check DMA header and payload length 738 * @lut: lookup table entry to check 739 * @target_type: target type 740 * 741 * Return: QDF_STATUS 742 */ 743 static QDF_STATUS check_dma_length(struct look_up_table *lut, 744 uint32_t target_type) 745 { 746 if (target_type == TARGET_TYPE_QCN9000) { 747 if (lut->header_length <= PINE_MAX_HEADER_LENGTH_WORDS && 748 lut->payload_length <= PINE_MAX_DATA_LENGTH_BYTES) { 749 return QDF_STATUS_SUCCESS; 750 } 751 } else if (target_type == TARGET_TYPE_QCN6122 || 752 target_type == TARGET_TYPE_QCN9160) { 753 if (lut->header_length <= SPRUCE_MAX_HEADER_LENGTH_WORDS && 754 lut->payload_length <= SPRUCE_MAX_DATA_LENGTH_BYTES) { 755 return QDF_STATUS_SUCCESS; 756 } 757 } else if (target_type == TARGET_TYPE_QCA5018) { 758 if (lut->header_length <= MAPLE_MAX_HEADER_LENGTH_WORDS && 759 lut->payload_length <= MAPLE_MAX_DATA_LENGTH_BYTES) { 760 return QDF_STATUS_SUCCESS; 761 } 762 } else if (target_type == TARGET_TYPE_QCN9224) { 763 if (lut->header_length <= WAIKIKI_MAX_HEADER_LENGTH_WORDS && 764 lut->payload_length <= WAIKIKI_MAX_DATA_LENGTH_BYTES) { 765 return QDF_STATUS_SUCCESS; 766 } 767 } else if (target_type == TARGET_TYPE_QCN6432) { 768 if (lut->header_length <= QCN6432_MAX_HEADER_LENGTH_WORDS && 769 lut->payload_length <= QCN6432_MAX_DATA_LENGTH_BYTES) { 770 return QDF_STATUS_SUCCESS; 771 } 772 } else if (target_type == TARGET_TYPE_QCA5332) { 773 if (lut->header_length <= QCA5332_MAX_HEADER_LENGTH_WORDS && 774 lut->payload_length <= QCA5332_MAX_DATA_LENGTH_BYTES) { 775 return QDF_STATUS_SUCCESS; 776 } 777 } else { 778 if (lut->header_length <= CYP_MAX_HEADER_LENGTH_WORDS && 779 lut->payload_length <= CYP_MAX_DATA_LENGTH_BYTES) { 780 return QDF_STATUS_SUCCESS; 781 } 782 } 783 return QDF_STATUS_E_FAILURE; 784 } 785 786 /** 787 * correlate_and_relay_enh() - Correlate TXRX and DBR events and stream CFR 788 * data to userspace 789 * @pdev: objmgr PDEV 790 * @cookie: Index into lookup table 791 * @lut: pointer to lookup table 792 * @module_id: ID of the event received 793 * 0 - DBR event 794 * 1 - TXRX event 795 * 796 * Return: 797 * - STATUS_ERROR 798 * - STATUS_HOLD 799 * - STATUS_STREAM_AND_RELEASE 800 */ 801 static int correlate_and_relay_enh(struct wlan_objmgr_pdev *pdev, 802 uint32_t cookie, 803 struct look_up_table *lut, 804 uint8_t module_id) 805 { 806 struct pdev_cfr *pcfr; 807 uint64_t diff; 808 int status = STATUS_ERROR; 809 struct wlan_objmgr_psoc *psoc; 810 uint32_t target_type; 811 812 if (module_id > 1) { 813 cfr_err("Received request with invalid mod id. Investigate!!"); 814 QDF_ASSERT(0); 815 status = STATUS_ERROR; 816 goto done; 817 } 818 819 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 820 WLAN_UMAC_COMP_CFR); 821 822 psoc = wlan_pdev_get_psoc(pdev); 823 if (qdf_unlikely(!psoc)) { 824 cfr_err("psoc is null\n"); 825 status = STATUS_ERROR; 826 goto done; 827 } 828 829 target_type = target_if_cfr_get_target_type(psoc); 830 831 if (module_id == CORRELATE_TX_EV_MODULE_ID) { 832 if (lut->tx_recv) 833 pcfr->cfr_dma_aborts++; 834 lut->tx_recv = true; 835 } else if (module_id == CORRELATE_DBR_MODULE_ID) { 836 pcfr->dbr_evt_cnt++; 837 lut->dbr_recv = true; 838 } 839 840 if ((lut->dbr_recv) && (lut->tx_recv)) { 841 if (lut->dbr_ppdu_id == lut->tx_ppdu_id) { 842 pcfr->last_success_tstamp = lut->dbr_tstamp; 843 if (lut->dbr_tstamp > lut->txrx_tstamp) { 844 diff = lut->dbr_tstamp - lut->txrx_tstamp; 845 cfr_debug("<CORRELATE><%u>: " 846 "TXRX evt -> DBR evt" 847 "(delay = %llu ms)\n", cookie, diff); 848 } else if (lut->txrx_tstamp > lut->dbr_tstamp) { 849 diff = lut->txrx_tstamp - lut->dbr_tstamp; 850 cfr_debug("<CORRELATE><%u>: " 851 "DBR evt -> TXRX evt" 852 "(delay = %llu ms)\n", cookie, diff); 853 } 854 855 /* 856 * Flush pending dbr events, if newer PPDU TLV is 857 * received 858 */ 859 cfr_free_pending_dbr_events(pdev); 860 861 if (check_dma_length(lut, target_type) == 862 QDF_STATUS_SUCCESS) { 863 pcfr->release_cnt++; 864 cfr_debug("<CORRELATE><%u>:Stream and release " 865 "CFR data for " 866 "ppdu_id:0x%04x\n", cookie, 867 lut->tx_ppdu_id); 868 status = STATUS_STREAM_AND_RELEASE; 869 goto done; 870 } else { 871 pcfr->invalid_dma_length_cnt++; 872 cfr_err("<CORRELATE><%u>:CFR buffers " 873 "received with invalid length " 874 "header_length_words = %d " 875 "cfr_payload_length_bytes = %d " 876 "ppdu_id:0x%04x\n", 877 cookie, 878 lut->header_length, 879 lut->payload_length, 880 lut->tx_ppdu_id); 881 /* 882 * Assert here as length exceeding the allowed 883 * limit would anyway manifest as random crash 884 */ 885 QDF_ASSERT(0); 886 status = STATUS_ERROR; 887 goto done; 888 } 889 } else { 890 /* 891 * When there is a ppdu id mismatch, discard the TXRX 892 * event since multiple PPDUs are likely to have same 893 * dma addr, due to ucode aborts 894 */ 895 cfr_debug("Received new dbr event for same " 896 "cookie %u", 897 cookie); 898 lut->tx_recv = false; 899 lut->tx_ppdu_id = 0; 900 pcfr->clear_txrx_event++; 901 pcfr->cfr_dma_aborts++; 902 status = STATUS_HOLD; 903 } 904 } else { 905 status = STATUS_HOLD; 906 } 907 done: 908 return status; 909 } 910 911 /** 912 * target_if_cfr_get_11be_support_flag(): check if target supports 11be 913 * @pdev_id: pdev id of the pdev 914 * @tgt_hdl: psoc info of pdev associated with pdev_id. Caller of this API to 915 * ensure that tgt_hdl is not NULL 916 * 917 * Return: true if 11be supported, false otherwise 918 */ 919 #ifdef WLAN_FEATURE_11BE 920 static inline 921 bool target_if_cfr_get_11be_support_flag(uint8_t pdev_id, 922 struct target_psoc_info *tgt_hdl) 923 { 924 struct wlan_psoc_host_mac_phy_caps *mac_phy_cap_arr, *mac_phy_cap; 925 926 mac_phy_cap_arr = target_psoc_get_mac_phy_cap(tgt_hdl); 927 928 if (!mac_phy_cap_arr) 929 return false; 930 931 mac_phy_cap = &mac_phy_cap_arr[pdev_id]; 932 if (mac_phy_cap && mac_phy_cap->supports_11be) 933 return true; 934 935 return false; 936 } 937 #else 938 static inline 939 bool target_if_cfr_get_11be_support_flag(uint8_t pdev_id, 940 struct target_psoc_info *tgt_hdl) 941 { 942 return false; 943 } 944 #endif 945 946 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 947 static inline 948 bool is_valid_gain_table_idx(uint16_t tbl_idx, struct pdev_cfr *pcfr) 949 { 950 /* if default gain table return true */ 951 if (!tbl_idx) 952 return true; 953 954 /* non zero gain table is invalid when is_enh_aoa_data is not set */ 955 if (!pcfr->is_enh_aoa_data) 956 return false; 957 958 if ((tbl_idx > 0) && (tbl_idx < pcfr->max_agc_gain_tbls)) 959 return true; 960 961 return false; 962 } 963 964 static inline 965 uint16_t get_max_agc_gain(struct wlan_objmgr_vdev *vdev, 966 uint16_t tbl_idx, struct pdev_cfr *pcfr, 967 bool supports_11be) 968 { 969 uint16_t *max_agc_gain_per_tbl = NULL; 970 struct wlan_channel *bss_chan; 971 972 if (!supports_11be) 973 return MAX_AGC_GAIN; 974 975 if (!pcfr->is_enh_aoa_data) 976 return INVALID_AGC_GAIN; 977 978 bss_chan = wlan_vdev_mlme_get_bss_chan(vdev); 979 if (wlan_reg_is_24ghz_ch_freq(bss_chan->ch_freq)) 980 max_agc_gain_per_tbl = pcfr->max_agc_gain_per_tbl_2g; 981 else if (wlan_reg_is_5ghz_ch_freq(bss_chan->ch_freq)) 982 max_agc_gain_per_tbl = pcfr->max_agc_gain_per_tbl_5g; 983 else if (wlan_reg_is_6ghz_chan_freq(bss_chan->ch_freq)) 984 max_agc_gain_per_tbl = pcfr->max_agc_gain_per_tbl_6g; 985 986 if (is_valid_gain_table_idx(tbl_idx, pcfr) && max_agc_gain_per_tbl) 987 return max_agc_gain_per_tbl[tbl_idx]; 988 else 989 return INVALID_AGC_GAIN; 990 } 991 992 static 993 void populate_enh_chain_phase(struct wlan_objmgr_vdev *vdev, 994 struct pdev_cfr *pcfr, 995 struct enh_cfr_metadata *meta, 996 bool invalid_gain_table_idx) 997 { 998 uint16_t *phase_array, *gain_array; 999 uint16_t phase_delta; 1000 uint32_t start_ent, stop_ent, chain, tbl_idx, grp_stp_idx, found; 1001 uint32_t data_idx, rf_chain; 1002 1003 if (invalid_gain_table_idx || !pcfr->is_enh_aoa_data) { 1004 /** 1005 * When AoA is enabled but invalid gain table index is reported 1006 * by HW, it indicates the AoA result is not reliable. Hence, 1007 * set the chain_phase to 0xFFFF indicating an error. 1008 * Set invalid phase when enhanced aoa capability is not set. 1009 */ 1010 for (chain = 0; chain < pcfr->max_aoa_chains; chain++) 1011 meta->chain_phase[chain] = INVALID_PHASE_DELTA; 1012 1013 return; 1014 } 1015 1016 for (chain = 0; chain < pcfr->max_aoa_chains; chain++) { 1017 rf_chain = (pcfr->xbar_config) ? 1018 ((pcfr->xbar_config >> (3 * chain)) & 0x07) : 1019 chain; 1020 data_idx = (rf_chain * pcfr->max_entries_all_table); 1021 1022 phase_array = &pcfr->enh_phase_delta_array[data_idx]; 1023 gain_array = &pcfr->gain_stop_index_array[data_idx]; 1024 tbl_idx = meta->agc_gain_tbl_index[chain]; 1025 start_ent = pcfr->start_ent[tbl_idx]; 1026 stop_ent = start_ent + pcfr->max_bdf_entries_per_tbl[tbl_idx]; 1027 1028 /** 1029 * if default gain table exceeds max_agc_gain, chain_phase needs 1030 * to be considered as 0. Remaining gain tables would have a 1031 * phase delta assigned with max agc gain as well 1032 */ 1033 if (!tbl_idx && (meta->agc_gain[chain] == 1034 get_max_agc_gain(vdev, tbl_idx, pcfr, true))) { 1035 phase_delta = 0; 1036 meta->chain_phase[chain] = 1037 (pcfr->ibf_cal_val[rf_chain] + 1038 phase_delta) & 0x3FF; 1039 continue; 1040 } 1041 1042 for (grp_stp_idx = start_ent, found = 0; 1043 grp_stp_idx < stop_ent; grp_stp_idx++) { 1044 if (meta->agc_gain[chain] <= gain_array[grp_stp_idx]) { 1045 phase_delta = phase_array[grp_stp_idx]; 1046 found = 1; 1047 break; 1048 } 1049 } 1050 1051 if ((!found) && (grp_stp_idx >= stop_ent)) 1052 phase_delta = 0; 1053 1054 /** 1055 * FW sets 0xFFFF as invalid phase delta in invalid cases. 1056 * Retain same in HOST as well. In case of valid phase, add the 1057 * ibf cal value to the delta & ensure the derived phase value 1058 * is in the range of 0 - 1024 indicating 0 - 360 degrees. 1059 */ 1060 if (phase_delta == INVALID_PHASE_DELTA) 1061 meta->chain_phase[chain] = INVALID_PHASE_DELTA; 1062 else 1063 meta->chain_phase[chain] = 1064 ((pcfr->ibf_cal_val[rf_chain] + phase_delta) & 1065 0x3FF); 1066 } 1067 } 1068 #else 1069 static inline 1070 bool is_valid_gain_table_idx(uint16_t tbl_idx, struct pdev_cfr *pcfr) 1071 { 1072 /* if default gain table return true */ 1073 if (!tbl_idx) 1074 return true; 1075 1076 return false; 1077 } 1078 1079 static inline 1080 uint16_t get_max_agc_gain(struct wlan_objmgr_vdev *vdev, 1081 uint16_t tbl_idx, struct pdev_cfr *pcfr, 1082 bool supports_11be) 1083 { 1084 if (!supports_11be) 1085 return MAX_AGC_GAIN; 1086 1087 return INVALID_AGC_GAIN; 1088 } 1089 1090 static 1091 void populate_enh_chain_phase(struct wlan_objmgr_vdev *vdev, 1092 struct pdev_cfr *pcfr, 1093 struct enh_cfr_metadata *meta, 1094 bool invalid_gain_table_idx) 1095 { 1096 uint8_t chain; 1097 1098 cfr_debug("Enahced AoA not supported.. Invsetigate"); 1099 for (chain = 0; chain < pcfr->max_aoa_chains; chain++) 1100 meta->chain_phase[chain] = INVALID_PHASE_DELTA; 1101 } 1102 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ 1103 1104 static 1105 void populate_chain_phase(struct wlan_objmgr_vdev *vdev, 1106 struct pdev_cfr *pcfr, 1107 struct enh_cfr_metadata *meta, 1108 bool invalid_gain_table_idx) 1109 { 1110 uint8_t i; 1111 uint16_t gain, pdelta; 1112 1113 if (invalid_gain_table_idx) { 1114 /** 1115 * When AoA is enabled but invalid gain table index is reported 1116 * by HW, it indicates the AoA result is not reliable. Hence, 1117 * set the chain_phase to 0xFFFF indicating an error. 1118 */ 1119 for (i = 0; i < pcfr->max_aoa_chains; i++) { 1120 if (wlan_vdev_mlme_is_special_vdev(vdev) && 1121 i == CHAIN_SHIFT_INDEX_PINE_SCAN) { 1122 meta->chain_phase[i - 1] = INVALID_PHASE_DELTA; 1123 break; 1124 } 1125 meta->chain_phase[i] = INVALID_PHASE_DELTA; 1126 } 1127 return; 1128 } 1129 1130 for (i = 0; i < pcfr->max_aoa_chains; i++) { 1131 /** 1132 * phase delta stored in reverse order by FW. 1133 * Hence, index accordingly 1134 */ 1135 gain = meta->agc_gain[i]; 1136 if (gain < MAX_AGC_GAIN) { 1137 pdelta = pcfr->phase_delta[i][MAX_AGC_GAIN - 1138 1 - 1139 gain]; 1140 } else { 1141 /* populate 0 for last gain index */ 1142 pdelta = 0; 1143 } 1144 /** 1145 * FW sets 0xFFFF as invalid phase delta in 1146 * invalid cases. Retain same in HOST as well. 1147 * In case of valid phase, add the ibf cal value 1148 * to the delta & ensure the derived phase value 1149 * is in the range of 0 - 1024 indicating 0 - 360 1150 * degrees 1151 */ 1152 if (pdelta == INVALID_PHASE_DELTA) { 1153 if (wlan_vdev_mlme_is_special_vdev(vdev) && 1154 i == CHAIN_SHIFT_INDEX_PINE_SCAN) { 1155 meta->chain_phase[i - 1] = 1156 INVALID_PHASE_DELTA; 1157 break; 1158 } 1159 meta->chain_phase[i] = INVALID_PHASE_DELTA; 1160 } else { 1161 if (wlan_vdev_mlme_is_special_vdev(vdev) && 1162 i == CHAIN_SHIFT_INDEX_PINE_SCAN) { 1163 meta->chain_phase[i - 1] = 1164 ((pcfr->ibf_cal_val[i] + 1165 pdelta) & 0x3FF); 1166 break; 1167 } 1168 meta->chain_phase[i] = ((pcfr->ibf_cal_val[i] + 1169 pdelta) & 0x3FF); 1170 } 1171 } 1172 } 1173 1174 /** 1175 * target_if_cfr_rx_tlv_process() - Process PPDU status TLVs and store info in 1176 * lookup table 1177 * @pdev: PDEV object 1178 * @nbuf: ppdu info 1179 * 1180 * Return: none 1181 */ 1182 void target_if_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf) 1183 { 1184 struct cdp_rx_indication_ppdu *cdp_rx_ppdu; 1185 struct cdp_rx_stats_ppdu_user *rx_stats_peruser; 1186 struct cdp_rx_ppdu_cfr_info *cfr_info; 1187 qdf_dma_addr_t buf_addr = 0, buf_addr_extn = 0; 1188 struct pdev_cfr *pcfr; 1189 struct look_up_table *lut = NULL; 1190 struct csi_cfr_header *header = NULL; 1191 uint32_t cookie; 1192 struct wlan_objmgr_psoc *psoc; 1193 struct wlan_channel *bss_chan; 1194 enum wlan_phymode ch_phymode; 1195 uint16_t ch_freq; 1196 uint32_t ch_cfreq1; 1197 uint32_t ch_cfreq2; 1198 struct wlan_objmgr_vdev *vdev = NULL; 1199 int i, status = 0; 1200 QDF_STATUS retval = 0; 1201 struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL; 1202 struct enh_cfr_metadata *meta = NULL; 1203 uint8_t srng_id = 0; 1204 struct wlan_lmac_if_rx_ops *rx_ops; 1205 uint32_t target_type; 1206 uint16_t gain_info[HOST_MAX_CHAINS]; 1207 bool invalid_gain_table_idx = false; 1208 uint32_t max_agc_gain = 0; 1209 bool supports_11be; 1210 uint8_t pdev_id; 1211 struct target_psoc_info *tgt_hdl; 1212 1213 if (qdf_unlikely(!pdev)) { 1214 cfr_err("pdev is null\n"); 1215 qdf_nbuf_free(nbuf); 1216 return; 1217 } 1218 1219 retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID); 1220 if (qdf_unlikely(retval != QDF_STATUS_SUCCESS)) { 1221 cfr_err("failed to get pdev reference"); 1222 qdf_nbuf_free(nbuf); 1223 return; 1224 } 1225 1226 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1227 WLAN_UMAC_COMP_CFR); 1228 if (qdf_unlikely(!pcfr)) { 1229 cfr_err("pdev object for CFR is NULL"); 1230 goto relref; 1231 } 1232 1233 cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)qdf_nbuf_data(nbuf); 1234 cfr_info = &cdp_rx_ppdu->cfr_info; 1235 1236 if (!cfr_info->bb_captured_channel) 1237 goto relref; 1238 1239 psoc = wlan_pdev_get_psoc(pdev); 1240 if (qdf_unlikely(!psoc)) { 1241 cfr_err("psoc is null\n"); 1242 goto relref; 1243 } 1244 1245 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1246 if (!rx_ops) { 1247 cfr_err("rx_ops is NULL"); 1248 goto relref; 1249 } 1250 1251 tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc); 1252 if (qdf_unlikely(!tgt_hdl)) { 1253 cfr_err("tgt_hdl is NULL"); 1254 goto relref; 1255 } 1256 1257 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1258 1259 supports_11be = target_if_cfr_get_11be_support_flag(pdev_id, tgt_hdl); 1260 1261 target_type = target_if_cfr_get_target_type(psoc); 1262 cfr_rx_ops = &rx_ops->cfr_rx_ops; 1263 buf_addr_extn = cfr_info->rtt_che_buffer_pointer_high8 & 0xF; 1264 buf_addr = (cfr_info->rtt_che_buffer_pointer_low32 | 1265 ((uint64_t)buf_addr_extn << 32)); 1266 1267 srng_id = pcfr->rcc_param.srng_id; 1268 if (target_if_dbr_cookie_lookup(pdev, DBR_MODULE_CFR, buf_addr, 1269 &cookie, srng_id)) { 1270 cfr_debug("Cookie lookup failure for addr: 0x%pK", 1271 (void *)((uintptr_t)buf_addr)); 1272 goto relref; 1273 } 1274 1275 cfr_debug("<RXTLV><%u>:buffer address: 0x%pK\n" 1276 "<WIFIRX_PPDU_START_E> ppdu_id: 0x%04x\n" 1277 "<WIFIRXPCU_PPDU_END_INFO_E> BB_CAPTURED_CHANNEL = %d\n" 1278 "<WIFIPHYRX_PKT_END_E> RX_LOCATION_INFO_VALID = %d\n" 1279 "<WIFIPHYRX_PKT_END_E> RTT_CHE_BUFFER_POINTER_LOW32 = %x\n" 1280 "<WIFIPHYRX_PKT_END_E> RTT_CHE_BUFFER_POINTER_HIGH8 = %x\n" 1281 "<WIFIPHYRX_PKT_END_E> CHAN_CAPTURE_STATUS = %d\n", 1282 cookie, 1283 (void *)((uintptr_t)buf_addr), 1284 cdp_rx_ppdu->ppdu_id, 1285 cfr_info->bb_captured_channel, 1286 cfr_info->rx_location_info_valid, 1287 cfr_info->rtt_che_buffer_pointer_low32, 1288 cfr_info->rtt_che_buffer_pointer_high8, 1289 cfr_info->chan_capture_status); 1290 1291 qdf_spin_lock_bh(&pcfr->lut_lock); 1292 1293 lut = get_lut_entry(pcfr, cookie); 1294 if (qdf_unlikely(!lut)) { 1295 cfr_err("lut is NULL"); 1296 goto unlock; 1297 } 1298 1299 if (pcfr->rcc_param.vdev_id == CFR_INVALID_VDEV_ID) 1300 vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_CFR_ID); 1301 else 1302 vdev = wlan_objmgr_get_vdev_by_id_from_pdev( 1303 pdev, pcfr->rcc_param.vdev_id, WLAN_CFR_ID); 1304 if (qdf_unlikely(!vdev)) { 1305 cfr_debug("vdev is null\n"); 1306 goto unlock; 1307 } 1308 1309 bss_chan = wlan_vdev_mlme_get_bss_chan(vdev); 1310 ch_freq = bss_chan->ch_freq; 1311 ch_cfreq1 = bss_chan->ch_cfreq1; 1312 ch_cfreq2 = bss_chan->ch_cfreq2; 1313 ch_phymode = bss_chan->ch_phymode; 1314 wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); 1315 1316 pcfr->rx_tlv_evt_cnt++; 1317 lut->tx_ppdu_id = cdp_rx_ppdu->ppdu_id; 1318 lut->tx_address1 = cfr_info->rtt_che_buffer_pointer_low32; 1319 lut->tx_address2 = cfr_info->rtt_che_buffer_pointer_high8; 1320 lut->txrx_tstamp = qdf_ktime_to_ms(qdf_ktime_get()); 1321 header = &lut->header; 1322 meta = &header->u.meta_enh; 1323 1324 target_if_cfr_fill_header(header, false, target_type, true); 1325 1326 meta->status = 1; 1327 meta->phy_mode = ch_phymode; 1328 meta->prim20_chan = ch_freq; 1329 meta->center_freq1 = ch_cfreq1; 1330 meta->center_freq2 = ch_cfreq2; 1331 meta->capture_mode = 0; 1332 1333 meta->timestamp = cdp_rx_ppdu->timestamp; 1334 meta->is_mu_ppdu = (cdp_rx_ppdu->u.ppdu_type == CDP_RX_TYPE_SU) ? 0 : 1; 1335 meta->num_mu_users = (meta->is_mu_ppdu) ? (cdp_rx_ppdu->num_users) : 0; 1336 1337 meta->rtt_cfo_measurement = cfr_info->rtt_cfo_measurement; 1338 meta->rx_start_ts = cfr_info->rx_start_ts; 1339 1340 gain_info[0] = get_u16_lsb(cfr_info->agc_gain_info0); 1341 gain_info[1] = get_u16_msb(cfr_info->agc_gain_info0); 1342 gain_info[2] = get_u16_lsb(cfr_info->agc_gain_info1); 1343 gain_info[3] = get_u16_msb(cfr_info->agc_gain_info1); 1344 gain_info[4] = get_u16_lsb(cfr_info->agc_gain_info2); 1345 gain_info[5] = get_u16_msb(cfr_info->agc_gain_info2); 1346 gain_info[6] = get_u16_lsb(cfr_info->agc_gain_info3); 1347 gain_info[7] = get_u16_msb(cfr_info->agc_gain_info3); 1348 1349 for (i = 0; i < HOST_MAX_CHAINS; i++) { 1350 meta->agc_gain[i] = get_gain_db(gain_info[i]); 1351 meta->agc_gain_tbl_index[i] = get_gain_table_idx(gain_info[i]); 1352 max_agc_gain = get_max_agc_gain(vdev, 1353 meta->agc_gain_tbl_index[i], 1354 pcfr, 1355 supports_11be); 1356 if (!is_valid_gain_table_idx(meta->agc_gain_tbl_index[i], 1357 pcfr)) { 1358 cfr_debug("Invalid gain table index reported"); 1359 invalid_gain_table_idx = true; 1360 } 1361 1362 if (meta->agc_gain[i] > max_agc_gain) 1363 meta->agc_gain[i] = max_agc_gain; 1364 } 1365 1366 if (wlan_vdev_mlme_is_special_vdev(vdev)) { 1367 for (i = 0; i < pcfr->max_aoa_chains; i++) 1368 meta->chain_phase[i] = INVALID_PHASE_DELTA; 1369 } 1370 1371 /** 1372 * Do not derive the chain phase when capability is not set Or 1373 * when an invalid gain table index is reported by Hardware. 1374 */ 1375 if (pcfr->is_aoa_for_rcc_support) { 1376 if (supports_11be) { 1377 populate_enh_chain_phase(vdev, pcfr, 1378 meta, invalid_gain_table_idx); 1379 } else { 1380 populate_chain_phase(vdev, pcfr, 1381 meta, invalid_gain_table_idx); 1382 } 1383 } 1384 1385 meta->mcs_rate = cfr_info->mcs_rate; 1386 meta->gi_type = cfr_info->gi_type; 1387 meta->sig_info.ltf_size = cdp_rx_ppdu->u.ltf_size; 1388 meta->sig_info.stbc = cdp_rx_ppdu->u.stbc; 1389 meta->sig_info.sgi = (cdp_rx_ppdu->u.gi == CDP_SGI_0_4_US) ? 1 : 0; 1390 meta->sig_info.dcm = cdp_rx_ppdu->u.dcm; 1391 meta->sig_info.coding = cdp_rx_ppdu->u.ldpc; 1392 meta->sig_info.beamformed = cdp_rx_ppdu->beamformed; 1393 1394 if (meta->num_mu_users > pcfr->max_mu_users) 1395 meta->num_mu_users = pcfr->max_mu_users; 1396 1397 target_if_snr_to_signal_strength(target_type, meta, cdp_rx_ppdu); 1398 1399 if (cdp_rx_ppdu->u.ppdu_type != CDP_RX_TYPE_SU) { 1400 for (i = 0 ; i < meta->num_mu_users; i++) { 1401 rx_stats_peruser = &cdp_rx_ppdu->user[i]; 1402 qdf_mem_copy(meta->peer_addr.mu_peer_addr[i], 1403 rx_stats_peruser->mac_addr, 1404 QDF_MAC_ADDR_SIZE); 1405 } 1406 } 1407 status = correlate_and_relay_enh(pdev, cookie, lut, 1408 CORRELATE_TX_EV_MODULE_ID); 1409 if (status == STATUS_STREAM_AND_RELEASE) { 1410 if (cfr_rx_ops->cfr_info_send) 1411 status = cfr_rx_ops->cfr_info_send(pdev, 1412 &lut->header, 1413 sizeof(struct 1414 csi_cfr_header), 1415 lut->data, 1416 lut->data_len, 1417 &end_magic, 4); 1418 dump_metadata(header, cookie); 1419 release_lut_entry_enh(pdev, lut); 1420 target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, buf_addr, 1421 cookie, srng_id); 1422 } 1423 1424 unlock: 1425 qdf_spin_unlock_bh(&pcfr->lut_lock); 1426 relref: 1427 qdf_nbuf_free(nbuf); 1428 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 1429 } 1430 1431 /** 1432 * freeze_reason_to_capture_type() - Convert capture type enum in freeze tlv 1433 * to the cfr type enum shared with userspace 1434 * @freeze_tlv: pointer to MACRX_FREEZE_CAPTURE_CHANNEL TLV 1435 * 1436 * Return: cfr type enum 1437 */ 1438 static uint8_t freeze_reason_to_capture_type(void *freeze_tlv) 1439 { 1440 /* 1441 * Capture_reason field position is common between freeze_tlv v1 1442 * and v2, hence typecasting to any one is fine 1443 */ 1444 struct macrx_freeze_capture_channel *freeze = 1445 (struct macrx_freeze_capture_channel *)freeze_tlv; 1446 1447 switch (freeze->capture_reason) { 1448 case FREEZE_REASON_TM: 1449 return CFR_TYPE_METHOD_TM; 1450 case FREEZE_REASON_FTM: 1451 return CFR_TYPE_METHOD_FTM; 1452 case FREEZE_REASON_TA_RA_TYPE_FILTER: 1453 return CFR_TYPE_METHOD_TA_RA_TYPE_FILTER; 1454 case FREEZE_REASON_NDPA_NDP: 1455 return CFR_TYPE_METHOD_NDPA_NDP; 1456 case FREEZE_REASON_ALL_PACKET: 1457 return CFR_TYPE_METHOD_ALL_PACKET; 1458 case FREEZE_REASON_ACK_RESP_TO_TM_FTM: 1459 return CFR_TYPE_METHOD_ACK_RESP_TO_TM_FTM; 1460 default: 1461 return CFR_TYPE_METHOD_AUTO; 1462 } 1463 return CFR_TYPE_METHOD_AUTO; 1464 } 1465 1466 #ifdef DIRECT_BUF_RX_ENABLE 1467 /** 1468 * enh_cfr_dbr_event_handler() - Process DBR event for CFR data DMA completion 1469 * @pdev: PDEV object 1470 * @payload: pointer to CFR data 1471 * 1472 * Return: status 1473 */ 1474 static bool enh_cfr_dbr_event_handler(struct wlan_objmgr_pdev *pdev, 1475 struct direct_buf_rx_data *payload) 1476 { 1477 uint8_t *data = NULL; 1478 uint32_t cookie = 0; 1479 struct whal_cfir_enhanced_hdr dma_hdr = {0}; 1480 int length, status = 0; 1481 struct wlan_objmgr_psoc *psoc; 1482 struct pdev_cfr *pcfr; 1483 struct look_up_table *lut = NULL; 1484 struct csi_cfr_header *header = NULL; 1485 void *mu_rx_user_info = NULL, *freeze_tlv = NULL; 1486 uint8_t capture_type = CFR_TYPE_METHOD_AUTO; 1487 uint8_t *peer_macaddr = NULL; 1488 struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL; 1489 struct enh_cfr_metadata *meta = NULL; 1490 struct wlan_lmac_if_rx_ops *rx_ops; 1491 1492 if ((!pdev) || (!payload)) { 1493 cfr_err("pdev or payload is null"); 1494 return true; 1495 } 1496 1497 psoc = wlan_pdev_get_psoc(pdev); 1498 if (!psoc) { 1499 cfr_err("psoc is null"); 1500 return true; 1501 } 1502 1503 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1504 if (!rx_ops) { 1505 cfr_err("rx_ops is NULL"); 1506 return true; 1507 } 1508 cfr_rx_ops = &rx_ops->cfr_rx_ops; 1509 1510 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1511 WLAN_UMAC_COMP_CFR); 1512 if (!pcfr) { 1513 cfr_err("pdev object for CFR is null"); 1514 return true; 1515 } 1516 1517 data = payload->vaddr; 1518 cookie = payload->cookie; 1519 1520 cfr_debug("<DBRCOMP><%u>:bufferaddr: 0x%pK cookie: %u\n", cookie, 1521 (void *)((uintptr_t)payload->paddr), cookie); 1522 1523 qdf_mem_copy(&dma_hdr, &data[0], 1524 sizeof(struct whal_cfir_enhanced_hdr)); 1525 1526 if (dma_hdr.freeze_data_incl) { 1527 freeze_tlv = data + sizeof(struct whal_cfir_enhanced_hdr); 1528 capture_type = freeze_reason_to_capture_type(freeze_tlv); 1529 } 1530 1531 if (dma_hdr.mu_rx_data_incl) { 1532 uint8_t freeze_tlv_len; 1533 1534 if (dma_hdr.freeze_tlv_version == MACRX_FREEZE_TLV_VERSION_3) { 1535 freeze_tlv_len = 1536 sizeof(struct macrx_freeze_capture_channel_v3); 1537 } else if (dma_hdr.freeze_tlv_version == 1538 MACRX_FREEZE_TLV_VERSION_5) { 1539 freeze_tlv_len = 1540 sizeof(struct macrx_freeze_capture_channel_v5); 1541 } else { 1542 freeze_tlv_len = 1543 sizeof(struct macrx_freeze_capture_channel); 1544 } 1545 mu_rx_user_info = data + 1546 sizeof(struct whal_cfir_enhanced_hdr) + 1547 (dma_hdr.freeze_data_incl ? freeze_tlv_len : 0); 1548 } 1549 1550 length = dma_hdr.length * 4; 1551 length += dma_hdr.total_bytes; /* size of cfr data */ 1552 1553 qdf_spin_lock_bh(&pcfr->lut_lock); 1554 1555 lut = get_lut_entry(pcfr, cookie); 1556 if (!lut) { 1557 cfr_err("lut is NULL"); 1558 qdf_spin_unlock_bh(&pcfr->lut_lock); 1559 return true; 1560 } 1561 1562 lut->data = data; 1563 lut->data_len = length; 1564 lut->dbr_ppdu_id = dma_hdr.phy_ppdu_id; 1565 lut->dbr_address = payload->paddr; 1566 lut->dbr_tstamp = qdf_ktime_to_ms(qdf_ktime_get()); 1567 lut->header_length = dma_hdr.length; 1568 lut->payload_length = dma_hdr.total_bytes; 1569 qdf_mem_copy(&lut->dma_hdr, &dma_hdr, 1570 sizeof(struct whal_cfir_dma_hdr)); 1571 1572 header = &lut->header; 1573 header->cmn.chip_type = pcfr->chip_type; 1574 meta = &header->u.meta_enh; 1575 meta->channel_bw = dma_hdr.upload_pkt_bw; 1576 meta->num_rx_chain = NUM_CHAINS_FW_TO_HOST(dma_hdr.num_chains); 1577 meta->length = length; 1578 /* For Tx based captures, capture type is sent from FW */ 1579 if (capture_type != CFR_TYPE_METHOD_ACK_RESP_TO_TM_FTM) { 1580 meta->capture_type = capture_type; 1581 meta->sts_count = (dma_hdr.nss + 1); 1582 if (!dma_hdr.mu_rx_data_incl) { 1583 /* extract peer addr from freeze tlv */ 1584 peer_macaddr = meta->peer_addr.su_peer_addr; 1585 if (dma_hdr.freeze_data_incl) { 1586 extract_peer_mac_from_freeze_tlv(freeze_tlv, 1587 peer_macaddr); 1588 } 1589 } 1590 } 1591 1592 if (dma_hdr.freeze_data_incl) { 1593 dump_enh_dma_hdr(&dma_hdr, freeze_tlv, mu_rx_user_info, 1594 header, 0, cookie); 1595 } 1596 1597 status = correlate_and_relay_enh(pdev, cookie, lut, 1598 CORRELATE_DBR_MODULE_ID); 1599 if (status == STATUS_STREAM_AND_RELEASE) { 1600 /* 1601 * Message format 1602 * Meta data Header + actual payload + trailer 1603 */ 1604 if (cfr_rx_ops->cfr_info_send) 1605 status = cfr_rx_ops->cfr_info_send(pdev, 1606 &lut->header, 1607 sizeof(struct 1608 csi_cfr_header), 1609 lut->data, 1610 lut->data_len, 1611 &end_magic, 4); 1612 dump_metadata(header, cookie); 1613 release_lut_entry_enh(pdev, lut); 1614 status = true; 1615 } else if (status == STATUS_HOLD) { 1616 status = false; 1617 } else { 1618 status = true; 1619 } 1620 1621 qdf_spin_unlock_bh(&pcfr->lut_lock); 1622 return status; 1623 } 1624 1625 /** 1626 * target_if_register_to_dbr_enh() - Initialize DBR ring and register callback 1627 * for DBR events 1628 * @pdev: PDEV object 1629 * 1630 * Return: status 1631 */ 1632 static QDF_STATUS 1633 target_if_register_to_dbr_enh(struct wlan_objmgr_pdev *pdev) 1634 { 1635 struct wlan_objmgr_psoc *psoc; 1636 struct wlan_lmac_if_direct_buf_rx_tx_ops *dbr_tx_ops = NULL; 1637 struct dbr_module_config dbr_config; 1638 struct wlan_lmac_if_tx_ops *tx_ops; 1639 1640 psoc = wlan_pdev_get_psoc(pdev); 1641 tx_ops = wlan_psoc_get_lmac_if_txops(psoc); 1642 if (!tx_ops) { 1643 cfr_err("tx_ops is NULL"); 1644 return QDF_STATUS_SUCCESS; 1645 } 1646 dbr_tx_ops = &tx_ops->dbr_tx_ops; 1647 dbr_config.num_resp_per_event = DBR_NUM_RESP_PER_EVENT_CFR; 1648 dbr_config.event_timeout_in_ms = DBR_EVENT_TIMEOUT_IN_MS_CFR; 1649 if (dbr_tx_ops->direct_buf_rx_module_register) { 1650 return dbr_tx_ops->direct_buf_rx_module_register 1651 (pdev, DBR_MODULE_CFR, &dbr_config, 1652 enh_cfr_dbr_event_handler); 1653 } 1654 1655 return QDF_STATUS_SUCCESS; 1656 } 1657 1658 /** 1659 * target_if_unregister_to_dbr_enh() - Unregister callback for DBR events 1660 * @pdev: PDEV object 1661 * 1662 * Return: status 1663 */ 1664 static QDF_STATUS 1665 target_if_unregister_to_dbr_enh(struct wlan_objmgr_pdev *pdev) 1666 { 1667 struct wlan_objmgr_psoc *psoc; 1668 struct wlan_lmac_if_direct_buf_rx_tx_ops *dbr_tx_ops = NULL; 1669 struct wlan_lmac_if_tx_ops *tx_ops; 1670 1671 psoc = wlan_pdev_get_psoc(pdev); 1672 tx_ops = wlan_psoc_get_lmac_if_txops(psoc); 1673 if (!tx_ops) { 1674 cfr_err("tx_ops is NULL"); 1675 return QDF_STATUS_SUCCESS; 1676 } 1677 dbr_tx_ops = &tx_ops->dbr_tx_ops; 1678 if (dbr_tx_ops->direct_buf_rx_module_unregister) { 1679 return dbr_tx_ops->direct_buf_rx_module_unregister 1680 (pdev, DBR_MODULE_CFR); 1681 } 1682 1683 return QDF_STATUS_SUCCESS; 1684 } 1685 #endif 1686 1687 /** 1688 * dump_cfr_peer_tx_event_enh() - Dump TX completion event 1689 * @event: ptr to WMI TX completion event for QOS frames sent during 1690 * one-shot capture 1691 * @cookie: Index into lookup table 1692 * 1693 * Return: none 1694 */ 1695 static void dump_cfr_peer_tx_event_enh(wmi_cfr_peer_tx_event_param *event, 1696 uint32_t cookie) 1697 { 1698 cfr_debug("<TXCOMP><%u>CFR capture method: %d vdev_id: %d mac: " 1699 QDF_MAC_ADDR_FMT, cookie, 1700 event->capture_method, event->vdev_id, 1701 QDF_MAC_ADDR_REF(event->peer_mac_addr.bytes)); 1702 1703 cfr_debug("<TXCOMP><%u>Chan: %d bw: %d phymode: %d cfreq1: %d cfrq2: %d " 1704 "nss: %d\n", 1705 cookie, 1706 event->primary_20mhz_chan, event->bandwidth, 1707 event->phy_mode, event->band_center_freq1, 1708 event->band_center_freq2, event->spatial_streams); 1709 1710 cfr_debug("<TXCOMP><%u>Correlation_info1: 0x%08x " 1711 "Correlation_info2: 0x%08x\n", 1712 cookie, 1713 event->correlation_info_1, event->correlation_info_2); 1714 1715 cfr_debug("<TXCOMP><%u>status: 0x%x ts: %d counter: %d rssi0: 0x%08x\n", 1716 cookie, 1717 event->status, event->timestamp_us, event->counter, 1718 event->chain_rssi[0]); 1719 } 1720 1721 static void 1722 populate_phase_delta(struct pdev_cfr *pcfr, 1723 struct wmi_cfr_phase_delta_param param) 1724 { 1725 int c, g, pc, pg; 1726 uint32_t c_mask = param.chain_phase_mask; 1727 1728 pc = 0; 1729 1730 /* populate phase delta for max chains indicated by target */ 1731 for (c = 0; c < pcfr->max_aoa_chains; c++) { 1732 pg = 0; 1733 if (((0x1 << c) & c_mask) && (pc < WMI_MAX_CHAINS_PHASE)) { 1734 pcfr->ibf_cal_val[c] = param.ibf_cal_val[pc]; 1735 for (g = 0; g < MAX_AGC_GAIN; g = g + 2) { 1736 if (pg < WMI_MAX_AOA_PHASE_DELTA) { 1737 pcfr->phase_delta[c][g] = get_u16_lsb 1738 (param.phase_delta[pc][pg]); 1739 pcfr->phase_delta[c][g + 1] = get_u16_msb 1740 (param.phase_delta[pc][pg]); 1741 pg++; 1742 } 1743 } 1744 pc++; 1745 } 1746 } 1747 } 1748 1749 static int 1750 target_if_pdev_aoa_phasedaelta_event_handler(ol_scn_t sc, 1751 uint8_t *data, 1752 uint32_t datalen) 1753 { 1754 struct wmi_unified *wmi_handle; 1755 struct wlan_objmgr_psoc *psoc; 1756 struct wlan_objmgr_pdev *pdev; 1757 struct pdev_cfr *pcfr; 1758 QDF_STATUS retval = 0; 1759 struct wmi_cfr_phase_delta_param param = {0}; 1760 1761 if (!sc || !data) { 1762 cfr_err("sc or data is null"); 1763 return -EINVAL; 1764 } 1765 1766 psoc = target_if_get_psoc_from_scn_hdl(sc); 1767 if (!psoc) { 1768 cfr_err("psoc is null"); 1769 return -EINVAL; 1770 } 1771 1772 retval = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_CFR_ID); 1773 if (QDF_IS_STATUS_ERROR(retval)) { 1774 cfr_err("unable to get psoc reference"); 1775 return -EINVAL; 1776 } 1777 1778 wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); 1779 if (!wmi_handle) { 1780 cfr_err("wmi_handle is null"); 1781 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1782 return -EINVAL; 1783 } 1784 1785 retval = wmi_extract_cfr_pdev_phase_delta_event 1786 (wmi_handle, data, ¶m); 1787 1788 if (QDF_IS_STATUS_ERROR(retval)) { 1789 cfr_err("Failed to extract phase params"); 1790 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1791 return -EINVAL; 1792 } 1793 1794 pdev = wlan_objmgr_get_pdev_by_id(psoc, param.pdev_id, WLAN_CFR_ID); 1795 if (!pdev) { 1796 cfr_err("pdev is null"); 1797 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1798 return -EINVAL; 1799 } 1800 1801 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); 1802 if (!pcfr) { 1803 cfr_err("pdev object for CFR is NULL"); 1804 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1805 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 1806 return -EINVAL; 1807 } 1808 1809 if (!pcfr->is_aoa_for_rcc_support) { 1810 cfr_err("AoA data event from unsupported target"); 1811 } 1812 1813 pcfr->freq = param.freq; 1814 pcfr->max_aoa_chains = (param.max_chains <= HOST_MAX_CHAINS) ? 1815 param.max_chains : HOST_MAX_CHAINS; 1816 1817 populate_phase_delta(pcfr, param); 1818 1819 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1820 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 1821 1822 return retval; 1823 } 1824 1825 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 1826 static int 1827 target_if_pdev_enhanced_aoa_phasedelta_event_handler(ol_scn_t sc, 1828 uint8_t *data, 1829 uint32_t datalen) 1830 { 1831 struct wmi_unified *wmi_handle; 1832 struct wlan_objmgr_psoc *psoc; 1833 struct wlan_objmgr_pdev *pdev; 1834 struct pdev_cfr *pcfr; 1835 QDF_STATUS retval = 0; 1836 struct wmi_cfr_enh_phase_delta_param param = {0}; 1837 uint32_t dst_idx, src_idx, max_src_ent, max_dst_ent; 1838 uint32_t num_data_chains; 1839 uint32_t offset; 1840 1841 qdf_bitmap(data_chain_bmap, sizeof(uint32_t) * QDF_CHAR_BIT); 1842 1843 if (!sc || !data) { 1844 cfr_err("sc or data is null"); 1845 return -EINVAL; 1846 } 1847 1848 psoc = target_if_get_psoc_from_scn_hdl(sc); 1849 if (!psoc) { 1850 cfr_err("psoc is null"); 1851 return -EINVAL; 1852 } 1853 1854 retval = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_CFR_ID); 1855 if (QDF_IS_STATUS_ERROR(retval)) { 1856 cfr_err("unable to get psoc reference"); 1857 return -EINVAL; 1858 } 1859 1860 wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); 1861 if (!wmi_handle) { 1862 cfr_err("wmi_handle is null"); 1863 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1864 return -EINVAL; 1865 } 1866 1867 retval = wmi_extract_cfr_pdev_enhanced_aoa_phasedelta_event_fixed_param 1868 (wmi_handle, data, ¶m); 1869 1870 if (QDF_IS_STATUS_ERROR(retval)) { 1871 cfr_err("Failed to extract phase delta fixed param tlv"); 1872 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1873 return -EINVAL; 1874 } 1875 1876 pdev = wlan_objmgr_get_pdev_by_id(psoc, param.pdev_id, WLAN_CFR_ID); 1877 if (!pdev) { 1878 cfr_err("pdev is null"); 1879 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1880 return -EINVAL; 1881 } 1882 1883 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); 1884 1885 if (!pcfr) { 1886 cfr_err("pdev object for CFR is NULL"); 1887 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1888 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 1889 return -EINVAL; 1890 } 1891 1892 pcfr->freq = param.freq; 1893 pcfr->max_aoa_chains = (param.max_chains <= HOST_MAX_CHAINS) ? 1894 param.max_chains : HOST_MAX_CHAINS; 1895 1896 num_data_chains = qdf_get_hweight32(param.data_for_chainmask); 1897 1898 if (num_data_chains != param.max_chains) 1899 cfr_debug("data not received for all chains"); 1900 1901 qdf_mem_zero(data_chain_bmap, sizeof(data_chain_bmap)); 1902 qdf_mem_copy(data_chain_bmap, ¶m.data_for_chainmask, 1903 qdf_min(sizeof(data_chain_bmap), 1904 sizeof(param.data_for_chainmask))); 1905 pcfr->xbar_config = param.xbar_config; 1906 1907 qdf_mem_copy(pcfr->ibf_cal_val, param.ibf_cal_val, 1908 sizeof(uint32_t) * HOST_MAX_CHAINS); 1909 1910 param.array_size = (pcfr->max_aoa_chains * 1911 pcfr->max_entries_all_table * sizeof(uint16_t)); 1912 1913 param.gain_stop_index_array = qdf_mem_malloc(param.array_size); 1914 if (!param.gain_stop_index_array) { 1915 cfr_err("Failed to allocate gain stop index array"); 1916 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1917 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 1918 return -EINVAL; 1919 } 1920 1921 param.enh_phase_delta_array = qdf_mem_malloc(param.array_size); 1922 if (!param.enh_phase_delta_array) { 1923 cfr_err("Failed to allocate phase delta array"); 1924 qdf_mem_free(param.gain_stop_index_array); 1925 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1926 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 1927 return -EINVAL; 1928 } 1929 1930 qdf_mem_zero(param.gain_stop_index_array, param.array_size); 1931 qdf_mem_zero(param.enh_phase_delta_array, param.array_size); 1932 1933 retval = wmi_extract_cfr_pdev_enhanced_aoa_phasedelta_event_data 1934 (wmi_handle, data, ¶m); 1935 1936 if (QDF_IS_STATUS_ERROR(retval)) { 1937 cfr_err("Failed to extract phase data tlv"); 1938 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1939 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 1940 qdf_mem_free(param.gain_stop_index_array); 1941 qdf_mem_free(param.enh_phase_delta_array); 1942 return -EINVAL; 1943 } 1944 1945 if (!pcfr->is_aoa_for_rcc_support || !pcfr->is_enh_aoa_data) 1946 cfr_err("AoA data event from unsupported target"); 1947 1948 max_src_ent = param.array_size / sizeof(uint32_t); 1949 max_dst_ent = pcfr->max_entries_all_table * pcfr->max_aoa_chains; 1950 1951 offset = pcfr->max_entries_all_table * 1952 qdf_find_first_bit(data_chain_bmap, 1953 sizeof(uint32_t) * QDF_CHAR_BIT); 1954 for (dst_idx = (0 + offset), src_idx = 0; 1955 ((dst_idx < max_dst_ent) && (src_idx < max_src_ent)); 1956 dst_idx += 2, src_idx++) { 1957 uint32_t data; 1958 1959 data = param.gain_stop_index_array[src_idx]; 1960 pcfr->gain_stop_index_array[dst_idx] = get_u16_lsb(data); 1961 pcfr->gain_stop_index_array[dst_idx + 1] = get_u16_msb(data); 1962 1963 data = param.enh_phase_delta_array[src_idx]; 1964 pcfr->enh_phase_delta_array[dst_idx] = get_u16_lsb(data); 1965 pcfr->enh_phase_delta_array[dst_idx + 1] = get_u16_msb(data); 1966 } 1967 1968 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1969 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 1970 qdf_mem_free(param.gain_stop_index_array); 1971 qdf_mem_free(param.enh_phase_delta_array); 1972 1973 return QDF_STATUS_SUCCESS; 1974 } 1975 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ 1976 1977 #ifdef DIRECT_BUF_RX_ENABLE 1978 /** 1979 * enh_prepare_cfr_header_txstatus() - Prepare CFR metadata for TX failures 1980 * @tx_evt_param: ptr to WMI TX completion event 1981 * @header: pointer to metadata 1982 * @target_type: target type 1983 * 1984 * Return: none 1985 */ 1986 static void enh_prepare_cfr_header_txstatus(wmi_cfr_peer_tx_event_param 1987 *tx_evt_param, 1988 struct csi_cfr_header *header, 1989 uint32_t target_type) 1990 { 1991 target_if_cfr_fill_header(header, false, target_type, false); 1992 header->u.meta_enh.status = 0; /* failure */ 1993 header->u.meta_enh.length = 0; 1994 header->u.meta_enh.rtt_cfo_measurement = tx_evt_param->cfo_measurement; 1995 header->u.meta_enh.rx_start_ts = tx_evt_param->rx_start_ts; 1996 1997 qdf_mem_copy(&header->u.meta_enh.peer_addr.su_peer_addr[0], 1998 &tx_evt_param->peer_mac_addr.bytes[0], QDF_MAC_ADDR_SIZE); 1999 } 2000 2001 /** 2002 * target_if_peer_capture_event() - WMI TX completion event for one-shot 2003 * capture 2004 * @sc: pointer to offload soc object 2005 * @data: WMI TX completion event buffer 2006 * @datalen: WMI Tx completion event buffer length 2007 * 2008 * Return: status 2009 */ 2010 static int 2011 target_if_peer_capture_event(ol_scn_t sc, uint8_t *data, uint32_t datalen) 2012 { 2013 QDF_STATUS retval = 0; 2014 struct wmi_unified *wmi_handle; 2015 struct wlan_objmgr_psoc *psoc; 2016 struct wlan_objmgr_pdev *pdev; 2017 struct wlan_objmgr_vdev *vdev; 2018 uint32_t cookie; 2019 struct pdev_cfr *pcfr; 2020 struct look_up_table *lut = NULL; 2021 struct csi_cfr_header *header = NULL; 2022 struct csi_cfr_header header_error = {{0} }; 2023 wmi_cfr_peer_tx_event_param tx_evt_param = {0}; 2024 qdf_dma_addr_t buf_addr = 0, buf_addr_temp = 0; 2025 int status; 2026 struct wlan_channel *bss_chan; 2027 struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL; 2028 struct wlan_lmac_if_rx_ops *rx_ops; 2029 uint32_t target_type; 2030 2031 if (!sc || !data) { 2032 cfr_err("sc or data is null"); 2033 return -EINVAL; 2034 } 2035 2036 psoc = target_if_get_psoc_from_scn_hdl(sc); 2037 if (!psoc) { 2038 cfr_err("psoc is null"); 2039 return -EINVAL; 2040 } 2041 2042 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 2043 if (!rx_ops) { 2044 cfr_err("rx_ops is NULL"); 2045 return -EINVAL; 2046 } 2047 cfr_rx_ops = &rx_ops->cfr_rx_ops; 2048 2049 retval = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_CFR_ID); 2050 if (QDF_IS_STATUS_ERROR(retval)) { 2051 cfr_err("unable to get psoc reference"); 2052 return -EINVAL; 2053 } 2054 2055 wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); 2056 if (!wmi_handle) { 2057 cfr_err("wmi_handle is null"); 2058 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 2059 return -EINVAL; 2060 } 2061 2062 retval = wmi_extract_cfr_peer_tx_event_param(wmi_handle, data, 2063 &tx_evt_param); 2064 2065 if (retval != QDF_STATUS_SUCCESS) { 2066 cfr_err("Failed to extract cfr tx event param"); 2067 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 2068 return -EINVAL; 2069 } 2070 2071 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, tx_evt_param.vdev_id, 2072 WLAN_CFR_ID); 2073 if (!vdev) { 2074 cfr_err("vdev is null"); 2075 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 2076 return -EINVAL; 2077 } 2078 2079 pdev = wlan_vdev_get_pdev(vdev); 2080 if (!pdev) { 2081 cfr_err("pdev is null"); 2082 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 2083 wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); 2084 return -EINVAL; 2085 } 2086 2087 retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID); 2088 if (retval != QDF_STATUS_SUCCESS) { 2089 cfr_err("failed to get pdev reference"); 2090 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 2091 wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); 2092 return -EINVAL; 2093 } 2094 2095 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 2096 WLAN_UMAC_COMP_CFR); 2097 if (!pcfr) { 2098 cfr_err("pdev object for CFR is NULL"); 2099 retval = -EINVAL; 2100 goto relref; 2101 } 2102 2103 target_type = target_if_cfr_get_target_type(psoc); 2104 2105 if (tx_evt_param.status & PEER_CFR_CAPTURE_EVT_PS_STATUS_MASK) { 2106 cfr_err("CFR capture failed as peer is in powersave: " 2107 QDF_MAC_ADDR_FMT, 2108 QDF_MAC_ADDR_REF(tx_evt_param.peer_mac_addr.bytes)); 2109 2110 enh_prepare_cfr_header_txstatus(&tx_evt_param, 2111 &header_error, 2112 target_type); 2113 if (cfr_rx_ops->cfr_info_send) 2114 cfr_rx_ops->cfr_info_send(pdev, 2115 &header_error, 2116 sizeof(struct 2117 csi_cfr_header), 2118 NULL, 0, &end_magic, 4); 2119 2120 retval = -EINVAL; 2121 goto relref; 2122 } 2123 2124 if ((tx_evt_param.status & PEER_CFR_CAPTURE_EVT_STATUS_MASK) == 0) { 2125 cfr_debug("CFR capture failed for peer: " QDF_MAC_ADDR_FMT, 2126 QDF_MAC_ADDR_REF(tx_evt_param.peer_mac_addr.bytes)); 2127 pcfr->tx_peer_status_cfr_fail++; 2128 retval = -EINVAL; 2129 goto relref; 2130 } 2131 2132 if (tx_evt_param.status & CFR_TX_EVT_STATUS_MASK) { 2133 cfr_debug("TX packet returned status %d for peer: " 2134 QDF_MAC_ADDR_FMT, 2135 tx_evt_param.status & CFR_TX_EVT_STATUS_MASK, 2136 QDF_MAC_ADDR_REF(tx_evt_param.peer_mac_addr.bytes)); 2137 pcfr->tx_evt_status_cfr_fail++; 2138 retval = -EINVAL; 2139 goto relref; 2140 } 2141 2142 buf_addr_temp = (tx_evt_param.correlation_info_2 & 0x0f); 2143 buf_addr = (tx_evt_param.correlation_info_1 | 2144 ((uint64_t)buf_addr_temp << 32)); 2145 2146 if (target_if_dbr_cookie_lookup(pdev, DBR_MODULE_CFR, buf_addr, 2147 &cookie, 0)) { 2148 cfr_debug("Cookie lookup failure for addr: 0x%pK status: 0x%x", 2149 (void *)((uintptr_t)buf_addr), tx_evt_param.status); 2150 pcfr->tx_dbr_cookie_lookup_fail++; 2151 retval = -EINVAL; 2152 goto relref; 2153 } 2154 2155 cfr_debug("buffer address: 0x%pK cookie: %u", 2156 (void *)((uintptr_t)buf_addr), cookie); 2157 2158 dump_cfr_peer_tx_event_enh(&tx_evt_param, cookie); 2159 2160 qdf_spin_lock_bh(&pcfr->lut_lock); 2161 2162 lut = get_lut_entry(pcfr, cookie); 2163 if (!lut) { 2164 cfr_err("lut is NULL\n"); 2165 retval = -EINVAL; 2166 goto unlock; 2167 } 2168 2169 pcfr->tx_evt_cnt++; 2170 pcfr->total_tx_evt_cnt++; 2171 2172 lut->tx_ppdu_id = (tx_evt_param.correlation_info_2 >> 16); 2173 lut->tx_address1 = tx_evt_param.correlation_info_1; 2174 lut->tx_address2 = tx_evt_param.correlation_info_2; 2175 lut->txrx_tstamp = qdf_ktime_to_ms(qdf_ktime_get()); 2176 2177 header = &lut->header; 2178 target_if_cfr_fill_header(header, false, target_type, false); 2179 header->u.meta_enh.status = (tx_evt_param.status & 2180 PEER_CFR_CAPTURE_EVT_STATUS_MASK) ? 2181 1 : 0; 2182 header->u.meta_enh.capture_bw = tx_evt_param.bandwidth; 2183 2184 bss_chan = wlan_vdev_mlme_get_bss_chan(vdev); 2185 header->u.meta_enh.phy_mode = bss_chan->ch_phymode; 2186 2187 header->u.meta_enh.prim20_chan = tx_evt_param.primary_20mhz_chan; 2188 header->u.meta_enh.center_freq1 = tx_evt_param.band_center_freq1; 2189 header->u.meta_enh.center_freq2 = tx_evt_param.band_center_freq2; 2190 2191 /* Currently CFR data is captured on ACK of a Qos NULL frame. 2192 * For 20 MHz, ACK is Legacy and for 40/80/160, ACK is DUP Legacy. 2193 */ 2194 header->u.meta_enh.capture_mode = tx_evt_param.bandwidth ? 2195 CFR_DUP_LEGACY_ACK : CFR_LEGACY_ACK; 2196 header->u.meta_enh.capture_type = tx_evt_param.capture_method; 2197 header->u.meta_enh.num_rx_chain = wlan_vdev_mlme_get_rxchainmask(vdev); 2198 header->u.meta_enh.sts_count = tx_evt_param.spatial_streams; 2199 header->u.meta_enh.timestamp = tx_evt_param.timestamp_us; 2200 2201 qdf_mem_copy(&header->u.meta_enh.peer_addr.su_peer_addr[0], 2202 &tx_evt_param.peer_mac_addr.bytes[0], QDF_MAC_ADDR_SIZE); 2203 qdf_mem_copy(&header->u.meta_enh.chain_rssi[0], 2204 &tx_evt_param.chain_rssi[0], 2205 HOST_MAX_CHAINS * sizeof(tx_evt_param.chain_rssi[0])); 2206 qdf_mem_copy(&header->u.meta_enh.chain_phase[0], 2207 &tx_evt_param.chain_phase[0], 2208 HOST_MAX_CHAINS * sizeof(tx_evt_param.chain_phase[0])); 2209 qdf_mem_copy(&header->u.meta_enh.agc_gain[0], 2210 &tx_evt_param.agc_gain[0], 2211 HOST_MAX_CHAINS * sizeof(tx_evt_param.agc_gain[0])); 2212 qdf_mem_copy(&header->u.meta_enh.agc_gain_tbl_index[0], 2213 &tx_evt_param.agc_gain_tbl_index[0], 2214 (HOST_MAX_CHAINS * 2215 sizeof(tx_evt_param.agc_gain_tbl_index[0]))); 2216 2217 header->u.meta_enh.rtt_cfo_measurement = tx_evt_param.cfo_measurement; 2218 header->u.meta_enh.rx_start_ts = tx_evt_param.rx_start_ts; 2219 header->u.meta_enh.mcs_rate = tx_evt_param.mcs_rate; 2220 header->u.meta_enh.gi_type = tx_evt_param.gi_type; 2221 2222 status = correlate_and_relay_enh(pdev, cookie, lut, 2223 CORRELATE_TX_EV_MODULE_ID); 2224 if (status == STATUS_STREAM_AND_RELEASE) { 2225 if (cfr_rx_ops->cfr_info_send) 2226 status = cfr_rx_ops->cfr_info_send(pdev, 2227 &lut->header, 2228 sizeof( 2229 struct 2230 csi_cfr_header), 2231 lut->data, 2232 lut->data_len, 2233 &end_magic, 4); 2234 dump_metadata(header, cookie); 2235 release_lut_entry_enh(pdev, lut); 2236 target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, buf_addr, 2237 cookie, 0); 2238 } else { 2239 retval = -EINVAL; 2240 } 2241 2242 unlock: 2243 qdf_spin_unlock_bh(&pcfr->lut_lock); 2244 relref: 2245 2246 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 2247 wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); 2248 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 2249 2250 return retval; 2251 } 2252 #else 2253 static int 2254 target_if_peer_capture_event(ol_scn_t sc, uint8_t *data, uint32_t datalen) 2255 { 2256 return 0; 2257 } 2258 #endif 2259 2260 /** 2261 * target_if_register_phase_delta_for_rcc_event_handler() - Register callback 2262 * for WMI phase delta event 2263 * @psoc: PSOC object 2264 * 2265 * Return: Success/Failure status 2266 */ 2267 static QDF_STATUS 2268 target_if_register_phase_delta_for_rcc_event_handler(struct wlan_objmgr_psoc 2269 *psoc) 2270 { 2271 wmi_unified_t wmi_hdl; 2272 QDF_STATUS ret = QDF_STATUS_SUCCESS; 2273 2274 wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc); 2275 if (!wmi_hdl) { 2276 cfr_err("Unable to get wmi handle"); 2277 return QDF_STATUS_E_NULL_VALUE; 2278 } 2279 2280 ret = wmi_unified_register_event_handler 2281 (wmi_hdl, wmi_pdev_aoa_phasedelta_event_id, 2282 target_if_pdev_aoa_phasedaelta_event_handler, 2283 WMI_RX_UMAC_CTX); 2284 2285 /* 2286 * Event registration is called per pdev 2287 * Ignore error if event is already registered. 2288 */ 2289 if (ret == QDF_STATUS_E_FAILURE) 2290 ret = QDF_STATUS_SUCCESS; 2291 2292 return ret; 2293 } 2294 2295 /** 2296 * target_if_unregister_phase_delta_for_rcc_event_handler() - Unregister 2297 * call back for WMI phase delta for rcc event 2298 * @psoc: PSOC object 2299 * 2300 * Return Success/Failure status 2301 */ 2302 static QDF_STATUS 2303 target_if_unregister_phase_delta_for_rcc_event_handler(struct wlan_objmgr_psoc 2304 *psoc) 2305 { 2306 wmi_unified_t wmi_hdl; 2307 QDF_STATUS status = QDF_STATUS_SUCCESS; 2308 2309 wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc); 2310 if (!wmi_hdl) { 2311 cfr_err("Unable to get wmi handle"); 2312 return QDF_STATUS_E_NULL_VALUE; 2313 } 2314 2315 status = wmi_unified_unregister_event 2316 (wmi_hdl, wmi_pdev_aoa_phasedelta_event_id); 2317 2318 return status; 2319 } 2320 2321 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT 2322 static QDF_STATUS 2323 target_if_register_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc 2324 *psoc) 2325 { 2326 wmi_unified_t wmi_hdl; 2327 QDF_STATUS ret = QDF_STATUS_SUCCESS; 2328 2329 wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc); 2330 if (!wmi_hdl) { 2331 cfr_err("Unable to get wmi handle"); 2332 return QDF_STATUS_E_NULL_VALUE; 2333 } 2334 2335 ret = wmi_unified_register_event_handler 2336 (wmi_hdl, wmi_pdev_enhanced_aoa_phasedelta_eventid, 2337 target_if_pdev_enhanced_aoa_phasedelta_event_handler, 2338 WMI_RX_UMAC_CTX); 2339 2340 /* 2341 * Event registration is called per pdev 2342 * Ignore error if event is already registered. 2343 */ 2344 if (ret == QDF_STATUS_E_FAILURE) 2345 ret = QDF_STATUS_SUCCESS; 2346 2347 return ret; 2348 } 2349 2350 static QDF_STATUS 2351 target_if_unregister_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc 2352 *psoc) 2353 { 2354 wmi_unified_t wmi_hdl; 2355 QDF_STATUS status = QDF_STATUS_SUCCESS; 2356 2357 wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc); 2358 if (!wmi_hdl) { 2359 cfr_err("Unable to get wmi handle"); 2360 return QDF_STATUS_E_NULL_VALUE; 2361 } 2362 2363 status = wmi_unified_unregister_event 2364 (wmi_hdl, wmi_pdev_enhanced_aoa_phasedelta_eventid); 2365 2366 return status; 2367 } 2368 #else 2369 static QDF_STATUS 2370 target_if_register_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc 2371 *psoc) 2372 { 2373 return QDF_STATUS_SUCCESS; 2374 } 2375 2376 static QDF_STATUS 2377 target_if_unregister_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc 2378 *psoc) 2379 { 2380 return QDF_STATUS_SUCCESS; 2381 } 2382 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ 2383 2384 /** 2385 * target_if_register_tx_completion_enh_event_handler() - Register callback for 2386 * WMI TX completion event 2387 * @psoc: PSOC object 2388 * 2389 * Return: Success/Failure status 2390 */ 2391 static QDF_STATUS 2392 target_if_register_tx_completion_enh_event_handler(struct wlan_objmgr_psoc 2393 *psoc) 2394 { 2395 /* Register completion handler here */ 2396 wmi_unified_t wmi_hdl; 2397 QDF_STATUS ret = QDF_STATUS_SUCCESS; 2398 2399 wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc); 2400 if (!wmi_hdl) { 2401 cfr_err("Unable to get wmi handle"); 2402 return QDF_STATUS_E_NULL_VALUE; 2403 } 2404 2405 ret = wmi_unified_register_event_handler(wmi_hdl, 2406 wmi_peer_cfr_capture_event_id, 2407 target_if_peer_capture_event, 2408 WMI_RX_UMAC_CTX); 2409 /* 2410 * Event registration is called per pdev 2411 * Ignore error if event is already registered. 2412 */ 2413 if (ret == QDF_STATUS_E_FAILURE) 2414 ret = QDF_STATUS_SUCCESS; 2415 2416 return ret; 2417 } 2418 2419 /** 2420 * target_if_unregister_tx_completion_enh_event_handler() - Unregister callback 2421 * for WMI TX completion event 2422 * @psoc: PSOC object 2423 * 2424 * Return: Success/Failure status 2425 */ 2426 static QDF_STATUS 2427 target_if_unregister_tx_completion_enh_event_handler(struct wlan_objmgr_psoc 2428 *psoc) 2429 { 2430 /* Unregister completion handler here */ 2431 wmi_unified_t wmi_hdl; 2432 QDF_STATUS status = QDF_STATUS_SUCCESS; 2433 2434 wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc); 2435 if (!wmi_hdl) { 2436 cfr_err("Unable to get wmi handle"); 2437 return QDF_STATUS_E_NULL_VALUE; 2438 } 2439 2440 status = wmi_unified_unregister_event(wmi_hdl, 2441 wmi_peer_cfr_capture_event_id); 2442 return status; 2443 } 2444 2445 /* 2446 * lut_ageout_timer_task() - Timer to flush pending TXRX/DBR events 2447 * 2448 * Return: none 2449 * NB: kernel-doc script doesn't parse os_timer_func 2450 2451 */ 2452 static os_timer_func(lut_ageout_timer_task) 2453 { 2454 int i = 0; 2455 struct pdev_cfr *pcfr = NULL; 2456 struct wlan_objmgr_pdev *pdev = NULL; 2457 struct look_up_table *lut = NULL; 2458 uint64_t diff, cur_tstamp; 2459 uint8_t srng_id = 0; 2460 2461 OS_GET_TIMER_ARG(pcfr, struct pdev_cfr*); 2462 2463 if (!pcfr) { 2464 cfr_err("pdev object for CFR is null"); 2465 return; 2466 } 2467 2468 pdev = pcfr->pdev_obj; 2469 if (!pdev) { 2470 cfr_err("pdev is null"); 2471 return; 2472 } 2473 2474 srng_id = pcfr->rcc_param.srng_id; 2475 if (wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID) 2476 != QDF_STATUS_SUCCESS) { 2477 cfr_err("failed to get pdev reference"); 2478 return; 2479 } 2480 2481 cur_tstamp = qdf_ktime_to_ms(qdf_ktime_get()); 2482 2483 qdf_spin_lock_bh(&pcfr->lut_lock); 2484 2485 for (i = 0; i < pcfr->lut_num; i++) { 2486 lut = get_lut_entry(pcfr, i); 2487 if (!lut) 2488 continue; 2489 2490 if (lut->dbr_recv && !lut->tx_recv) { 2491 diff = cur_tstamp - lut->dbr_tstamp; 2492 if (diff > LUT_AGE_THRESHOLD) { 2493 target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, 2494 lut->dbr_address, 2495 i, srng_id); 2496 pcfr->flush_timeout_dbr_cnt++; 2497 release_lut_entry_enh(pdev, lut); 2498 } 2499 } 2500 } 2501 2502 qdf_spin_unlock_bh(&pcfr->lut_lock); 2503 2504 if (pcfr->lut_timer_init) 2505 qdf_timer_mod(&pcfr->lut_age_timer, LUT_AGE_TIMER); 2506 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 2507 } 2508 2509 /** 2510 * target_if_cfr_start_lut_age_timer() - Start timer to flush aged-out LUT 2511 * entries 2512 * @pdev: pointer to pdev object 2513 * 2514 * Return: None 2515 */ 2516 void target_if_cfr_start_lut_age_timer(struct wlan_objmgr_pdev *pdev) 2517 { 2518 struct pdev_cfr *pcfr; 2519 2520 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 2521 WLAN_UMAC_COMP_CFR); 2522 if (pcfr->lut_timer_init) 2523 qdf_timer_mod(&pcfr->lut_age_timer, LUT_AGE_TIMER); 2524 } 2525 2526 /** 2527 * target_if_cfr_stop_lut_age_timer() - Stop timer to flush aged-out LUT 2528 * entries 2529 * @pdev: pointer to pdev object 2530 * 2531 * Return: None 2532 */ 2533 void target_if_cfr_stop_lut_age_timer(struct wlan_objmgr_pdev *pdev) 2534 { 2535 struct pdev_cfr *pcfr; 2536 2537 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 2538 WLAN_UMAC_COMP_CFR); 2539 if (pcfr->lut_timer_init) 2540 qdf_timer_stop(&pcfr->lut_age_timer); 2541 } 2542 2543 /** 2544 * target_if_cfr_update_global_cfg() - Update global config after a successful 2545 * commit 2546 * @pdev: pointer to pdev object 2547 * 2548 * Return: None 2549 */ 2550 void target_if_cfr_update_global_cfg(struct wlan_objmgr_pdev *pdev) 2551 { 2552 int grp_id; 2553 struct pdev_cfr *pcfr; 2554 struct ta_ra_cfr_cfg *curr_cfg = NULL; 2555 struct ta_ra_cfr_cfg *glbl_cfg = NULL; 2556 2557 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 2558 WLAN_UMAC_COMP_CFR); 2559 2560 if (!pcfr) { 2561 target_if_err("pcfr is null"); 2562 return; 2563 } 2564 2565 for (grp_id = 0; grp_id < MAX_TA_RA_ENTRIES; grp_id++) { 2566 if (qdf_test_bit(grp_id, 2567 &pcfr->rcc_param.modified_in_curr_session)) { 2568 /* Populating global config based on user's input */ 2569 glbl_cfg = &pcfr->global[grp_id]; 2570 curr_cfg = &pcfr->rcc_param.curr[grp_id]; 2571 2572 if (curr_cfg->valid_ta) 2573 qdf_mem_copy(glbl_cfg->tx_addr, 2574 curr_cfg->tx_addr, 2575 QDF_MAC_ADDR_SIZE); 2576 2577 if (curr_cfg->valid_ra) 2578 qdf_mem_copy(glbl_cfg->rx_addr, 2579 curr_cfg->rx_addr, 2580 QDF_MAC_ADDR_SIZE); 2581 2582 if (curr_cfg->valid_ta_mask) 2583 qdf_mem_copy(glbl_cfg->tx_addr_mask, 2584 curr_cfg->tx_addr_mask, 2585 QDF_MAC_ADDR_SIZE); 2586 2587 if (curr_cfg->valid_ra_mask) 2588 qdf_mem_copy(glbl_cfg->rx_addr_mask, 2589 curr_cfg->rx_addr_mask, 2590 QDF_MAC_ADDR_SIZE); 2591 2592 if (curr_cfg->valid_bw_mask) 2593 glbl_cfg->bw = curr_cfg->bw; 2594 2595 if (curr_cfg->valid_nss_mask) 2596 glbl_cfg->nss = curr_cfg->nss; 2597 2598 if (curr_cfg->valid_mgmt_subtype) 2599 glbl_cfg->mgmt_subtype_filter = 2600 curr_cfg->mgmt_subtype_filter; 2601 2602 if (curr_cfg->valid_ctrl_subtype) 2603 glbl_cfg->ctrl_subtype_filter = 2604 curr_cfg->ctrl_subtype_filter; 2605 2606 if (curr_cfg->valid_data_subtype) 2607 glbl_cfg->data_subtype_filter = 2608 curr_cfg->data_subtype_filter; 2609 } 2610 } 2611 } 2612 2613 /** 2614 * cfr_enh_init_pdev() - Inits cfr pdev and registers necessary handlers. 2615 * @psoc: pointer to psoc object 2616 * @pdev: pointer to pdev object 2617 * 2618 * Return: Registration status for necessary handlers 2619 */ 2620 QDF_STATUS cfr_enh_init_pdev(struct wlan_objmgr_psoc *psoc, 2621 struct wlan_objmgr_pdev *pdev) 2622 { 2623 QDF_STATUS status = QDF_STATUS_SUCCESS; 2624 struct pdev_cfr *pcfr; 2625 uint32_t target_type; 2626 struct psoc_cfr *cfr_sc; 2627 2628 if (!pdev) { 2629 cfr_err("PDEV is NULL!"); 2630 return QDF_STATUS_E_NULL_VALUE; 2631 } 2632 2633 if (!psoc) { 2634 cfr_err("PSOC is NULL"); 2635 return QDF_STATUS_E_NULL_VALUE; 2636 } 2637 2638 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 2639 WLAN_UMAC_COMP_CFR); 2640 if (!pcfr) { 2641 cfr_err("pcfr is NULL!"); 2642 return QDF_STATUS_E_NULL_VALUE; 2643 } 2644 2645 cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc, 2646 WLAN_UMAC_COMP_CFR); 2647 2648 if (!cfr_sc) { 2649 cfr_err("cfr_sc is NULL"); 2650 return QDF_STATUS_E_NULL_VALUE; 2651 } 2652 2653 target_type = target_if_cfr_get_target_type(psoc); 2654 2655 #if DIRECT_BUF_RX_ENABLE 2656 status = target_if_register_to_dbr_enh(pdev); 2657 if (status != QDF_STATUS_SUCCESS) { 2658 cfr_err("Failed to register with dbr"); 2659 return status; 2660 } 2661 #endif 2662 2663 status = target_if_register_tx_completion_enh_event_handler(psoc); 2664 if (status != QDF_STATUS_SUCCESS) { 2665 cfr_err("Failed to register with tx event handler"); 2666 return status; 2667 } 2668 2669 status = target_if_register_enh_phase_for_rcc_event_handler(psoc); 2670 if (status != QDF_STATUS_SUCCESS) { 2671 cfr_err("Failed to register with phase delta event handler"); 2672 return status; 2673 } 2674 2675 status = target_if_register_phase_delta_for_rcc_event_handler(psoc); 2676 if (status != QDF_STATUS_SUCCESS) { 2677 cfr_err("Failed to register with phase delta event handler"); 2678 return status; 2679 } 2680 2681 pcfr->is_cfr_rcc_capable = 1; 2682 pcfr->rcc_param.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 2683 pcfr->rcc_param.modified_in_curr_session = MAX_RESET_CFG_ENTRY; 2684 pcfr->rcc_param.num_grp_tlvs = MAX_TA_RA_ENTRIES; 2685 pcfr->rcc_param.vdev_id = CFR_INVALID_VDEV_ID; 2686 pcfr->rcc_param.srng_id = DEFAULT_SRNGID_CFR; 2687 pcfr->is_cap_interval_mode_sel_support = 2688 cfr_sc->is_cap_interval_mode_sel_support; 2689 pcfr->is_mo_marking_support = cfr_sc->is_mo_marking_support; 2690 pcfr->is_aoa_for_rcc_support = cfr_sc->is_aoa_for_rcc_support; 2691 2692 if (pcfr->is_aoa_for_rcc_support) { 2693 qdf_mem_set(pcfr->ibf_cal_val, 2694 sizeof(uint32_t) * HOST_MAX_CHAINS, 2695 0); 2696 qdf_mem_set(pcfr->phase_delta, 2697 sizeof(uint16_t) * HOST_MAX_CHAINS * MAX_AGC_GAIN, 2698 0); 2699 pcfr->max_aoa_chains = 0; 2700 } 2701 2702 target_if_cfr_default_ta_ra_config(&pcfr->rcc_param, 2703 true, MAX_RESET_CFG_ENTRY); 2704 2705 status = target_if_cfr_config_rcc(pdev, &pcfr->rcc_param); 2706 if (status == QDF_STATUS_SUCCESS) { 2707 /* Update global configuration */ 2708 target_if_cfr_update_global_cfg(pdev); 2709 } else { 2710 cfr_err("Sending WMI to configure default has failed"); 2711 return status; 2712 } 2713 2714 pcfr->rcc_param.modified_in_curr_session = 0; 2715 2716 pcfr->cfr_max_sta_count = MAX_CFR_ENABLED_CLIENTS; 2717 2718 if (target_type == TARGET_TYPE_QCN9000) { 2719 pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_PINE; 2720 pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_PINE; 2721 pcfr->chip_type = CFR_CAPTURE_RADIO_PINE; 2722 pcfr->max_mu_users = PINE_CFR_MU_USERS; 2723 } else if (target_type == TARGET_TYPE_QCA5018) { 2724 pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_MAPLE; 2725 pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_MAPLE; 2726 pcfr->chip_type = CFR_CAPTURE_RADIO_MAPLE; 2727 pcfr->max_mu_users = MAPLE_CFR_MU_USERS; 2728 } else if (target_type == TARGET_TYPE_QCN6122 || 2729 target_type == TARGET_TYPE_QCN9160) { 2730 pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_SPRUCE; 2731 pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_SPRUCE; 2732 pcfr->chip_type = (target_type == TARGET_TYPE_QCN6122) ? 2733 CFR_CAPTURE_RADIO_SPRUCE : CFR_CAPTURE_RADIO_YORK; 2734 pcfr->max_mu_users = SPRUCE_CFR_MU_USERS; 2735 } else if (target_type == TARGET_TYPE_QCN9224) { 2736 pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_WAIKIKI; 2737 pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_WAIKIKI; 2738 pcfr->chip_type = CFR_CAPTURE_RADIO_WAIKIKI; 2739 pcfr->max_mu_users = WAIKIKI_CFR_MU_USERS; 2740 } else if (target_type == TARGET_TYPE_QCN6432) { 2741 pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_QCN6432; 2742 pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_QCN6432; 2743 pcfr->chip_type = CFR_CAPTURE_RADIO_PEBBLE; 2744 pcfr->max_mu_users = QCN6432_CFR_MU_USERS; 2745 } else if (target_type == TARGET_TYPE_QCA5332) { 2746 pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_QCA5332; 2747 pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_QCA5332; 2748 pcfr->chip_type = CFR_CAPTURE_RADIO_MIAMI; 2749 pcfr->max_mu_users = QCA5332_CFR_MU_USERS; 2750 } else { 2751 pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_CYP; 2752 pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_CYP; 2753 pcfr->chip_type = CFR_CAPTURE_RADIO_CYP; 2754 pcfr->max_mu_users = CYP_CFR_MU_USERS; 2755 } 2756 2757 if (!pcfr->lut_timer_init) { 2758 qdf_timer_init(NULL, 2759 &(pcfr->lut_age_timer), 2760 lut_ageout_timer_task, (void *)pcfr, 2761 QDF_TIMER_TYPE_WAKE_APPS); 2762 pcfr->lut_timer_init = 1; 2763 } 2764 2765 qdf_spinlock_create(&pcfr->lut_lock); 2766 pcfr->lut_lock_initialised = true; 2767 2768 return status; 2769 } 2770 2771 /** 2772 * cfr_enh_deinit_pdev() - De-inits corresponding pdev and handlers. 2773 * @psoc: pointer to psoc object 2774 * @pdev: pointer to pdev object 2775 * 2776 * Return: De-registration status for necessary handlers 2777 */ 2778 QDF_STATUS cfr_enh_deinit_pdev(struct wlan_objmgr_psoc *psoc, 2779 struct wlan_objmgr_pdev *pdev) 2780 { 2781 QDF_STATUS status; 2782 struct pdev_cfr *pcfr; 2783 2784 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 2785 WLAN_UMAC_COMP_CFR); 2786 if (!pcfr) { 2787 cfr_err("pcfr is NULL"); 2788 return QDF_STATUS_E_NULL_VALUE; 2789 } 2790 2791 if (pcfr->lut_timer_init) { 2792 qdf_timer_stop(&pcfr->lut_age_timer); 2793 qdf_timer_free(&(pcfr->lut_age_timer)); 2794 pcfr->lut_timer_init = 0; 2795 } 2796 2797 pcfr->tx_evt_cnt = 0; 2798 pcfr->dbr_evt_cnt = 0; 2799 pcfr->release_cnt = 0; 2800 pcfr->total_tx_evt_cnt = 0; 2801 pcfr->rx_tlv_evt_cnt = 0; 2802 pcfr->flush_dbr_cnt = 0; 2803 pcfr->flush_timeout_dbr_cnt = 0; 2804 pcfr->invalid_dma_length_cnt = 0; 2805 pcfr->clear_txrx_event = 0; 2806 pcfr->cfr_dma_aborts = 0; 2807 pcfr->tx_peer_status_cfr_fail = 0; 2808 pcfr->tx_evt_status_cfr_fail = 0; 2809 pcfr->tx_dbr_cookie_lookup_fail = 0; 2810 qdf_mem_zero(&pcfr->rcc_param, sizeof(struct cfr_rcc_param)); 2811 qdf_mem_zero(&pcfr->global, (sizeof(struct ta_ra_cfr_cfg) * 2812 MAX_TA_RA_ENTRIES)); 2813 pcfr->cfr_timer_enable = 0; 2814 2815 #ifdef DIRECT_BUF_RX_ENABLE 2816 status = target_if_unregister_to_dbr_enh(pdev); 2817 if (status != QDF_STATUS_SUCCESS) 2818 cfr_err("Failed to register with dbr"); 2819 #endif 2820 2821 status = target_if_unregister_tx_completion_enh_event_handler(psoc); 2822 if (status != QDF_STATUS_SUCCESS) 2823 cfr_err("Failed to register with dbr"); 2824 2825 status = target_if_unregister_enh_phase_for_rcc_event_handler(psoc); 2826 if (status != QDF_STATUS_SUCCESS) 2827 cfr_err("Failed to unregister phase delta handler"); 2828 2829 status = target_if_unregister_phase_delta_for_rcc_event_handler(psoc); 2830 if (status != QDF_STATUS_SUCCESS) 2831 cfr_err("Failed to unregister phase delta handler"); 2832 2833 if (pcfr->lut_lock_initialised) { 2834 qdf_spinlock_destroy(&pcfr->lut_lock); 2835 pcfr->lut_lock_initialised = false; 2836 } 2837 2838 return status; 2839 } 2840