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