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