1 /* 2 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <target_if_cfr.h> 20 #include <wlan_tgt_def_config.h> 21 #include <target_type.h> 22 #include <hif_hw_version.h> 23 #include <target_if.h> 24 #include <wlan_lmac_if_def.h> 25 #include <wlan_osif_priv.h> 26 #include <init_deinit_lmac.h> 27 #include <wlan_cfr_utils_api.h> 28 #ifdef DIRECT_BUF_RX_ENABLE 29 #include <target_if_direct_buf_rx_api.h> 30 #endif 31 #include <target_if_cfr_enh.h> 32 #include "cdp_txrx_ctrl.h" 33 34 #define CMN_NOISE_FLOOR (-96) 35 #define NUM_CHAINS_FW_TO_HOST(n) ((1 << ((n) + 1)) - 1) 36 37 #define CFR_INVALID_SNR 0x80 38 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 static inline 48 u_int32_t snr_to_signal_strength(uint8_t snr) 49 { 50 /* SNR value 0x80 indicates -128dB which is not a valid value */ 51 return (snr != CFR_INVALID_SNR) ? 52 (((int8_t)snr) + CMN_NOISE_FLOOR) : 53 ((int8_t)snr); 54 } 55 56 /** 57 * get_lut_entry() - Retrieve LUT entry using cookie number 58 * @pcfr: PDEV CFR object 59 * @offset: cookie number 60 * 61 * Return: look up table entry 62 */ 63 static struct look_up_table *get_lut_entry(struct pdev_cfr *pcfr, 64 int offset) 65 { 66 if (offset >= pcfr->lut_num) { 67 cfr_err("Invalid offset %d, lut_num %d", 68 offset, pcfr->lut_num); 69 return NULL; 70 } 71 72 return pcfr->lut[offset]; 73 } 74 75 /** 76 * release_lut_entry_enh() - Clear all params in an LUT entry 77 * @pdev: objmgr PDEV 78 * @lut: pointer to LUT 79 * 80 * Return: status 81 */ 82 static int release_lut_entry_enh(struct wlan_objmgr_pdev *pdev, 83 struct look_up_table *lut) 84 { 85 lut->dbr_recv = false; 86 lut->tx_recv = false; 87 lut->data = NULL; 88 lut->data_len = 0; 89 lut->dbr_ppdu_id = 0; 90 lut->tx_ppdu_id = 0; 91 lut->dbr_tstamp = 0; 92 lut->txrx_tstamp = 0; 93 lut->tx_address1 = 0; 94 lut->tx_address2 = 0; 95 lut->dbr_address = 0; 96 qdf_mem_zero(&lut->header, sizeof(struct csi_cfr_header)); 97 98 return 0; 99 } 100 101 /** 102 * target_if_cfr_dump_lut_enh() - dump all valid lut entries 103 * @pdev: objmgr pdev 104 * 105 * return: none 106 */ 107 void target_if_cfr_dump_lut_enh(struct wlan_objmgr_pdev *pdev) 108 { 109 struct pdev_cfr *pcfr; 110 struct look_up_table *lut = NULL; 111 int i = 0; 112 uint64_t diff; 113 QDF_STATUS retval = 0; 114 115 retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID); 116 if (retval != QDF_STATUS_SUCCESS) { 117 cfr_err("failed to get pdev reference"); 118 return; 119 } 120 121 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 122 WLAN_UMAC_COMP_CFR); 123 if (!pcfr) { 124 cfr_err("pdev object for CFR is null"); 125 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 126 return; 127 } 128 129 qdf_spin_lock_bh(&pcfr->lut_lock); 130 131 for (i = 0; i < pcfr->lut_num; i++) { 132 lut = get_lut_entry(pcfr, i); 133 if (!lut) 134 continue; 135 if (lut->dbr_recv ^ lut->tx_recv) { 136 diff = (lut->dbr_tstamp > lut->txrx_tstamp) ? 137 (lut->dbr_tstamp - lut->txrx_tstamp) : 138 (lut->txrx_tstamp - lut->dbr_tstamp); 139 } 140 } 141 142 qdf_spin_unlock_bh(&pcfr->lut_lock); 143 144 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 145 } 146 147 /** 148 * cfr_free_pending_dbr_events() - Flush all pending DBR events. This is useful 149 * in cases where for RXTLV drops in host monitor status ring is huge. 150 * @pdev: objmgr pdev 151 * 152 * return: none 153 */ 154 static void cfr_free_pending_dbr_events(struct wlan_objmgr_pdev *pdev) 155 { 156 struct pdev_cfr *pcfr; 157 struct look_up_table *lut = NULL; 158 int i = 0; 159 QDF_STATUS retval = 0; 160 161 retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID); 162 if (retval != QDF_STATUS_SUCCESS) { 163 cfr_err("failed to get pdev reference"); 164 return; 165 } 166 167 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 168 WLAN_UMAC_COMP_CFR); 169 if (!pcfr) { 170 cfr_err("pdev object for CFR is null"); 171 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 172 return; 173 } 174 175 for (i = 0; i < pcfr->lut_num; i++) { 176 lut = get_lut_entry(pcfr, i); 177 if (!lut) 178 continue; 179 180 if (lut->dbr_recv && !lut->tx_recv && 181 (lut->dbr_tstamp < pcfr->last_success_tstamp)) { 182 target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, 183 lut->dbr_address, 184 i, 0); 185 pcfr->flush_dbr_cnt++; 186 release_lut_entry_enh(pdev, lut); 187 } 188 } 189 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 190 } 191 192 /** 193 * dump_freeze_tlv() - Dump freeze TLV sent in enhanced DMA header 194 * @freeze_tlv: Freeze TLV sent from MAC to PHY 195 * @cookie: Index into lookup table 196 * 197 * Return: none 198 */ 199 static void dump_freeze_tlv(void *freeze_tlv, uint32_t cookie) 200 { 201 struct macrx_freeze_capture_channel *freeze = 202 (struct macrx_freeze_capture_channel *)freeze_tlv; 203 204 cfr_debug("<DBRCOMP><FREEZE><%u>\n" 205 "freeze: %d capture_reason: %d packet_type: 0x%x\n" 206 "packet_subtype: 0x%x sw_peer_id_valid: %d sw_peer_id: %d\n" 207 "phy_ppdu_id: 0x%04x packet_ta_upper_16: 0x%04x\n" 208 "packet_ta_mid_16: 0x%04x packet_ta_lower_16: 0x%04x\n" 209 "packet_ra_upper_16: 0x%04x packet_ra_mid_16: 0x%04x\n" 210 "packet_ra_lower_16: 0x%04x tsf_timestamp_63_48: 0x%04x\n" 211 "tsf_timestamp_47_32: 0x%04x tsf_timestamp_31_16: 0x%04x\n" 212 "tsf_timestamp_15_0: 0x%04x user_index_or_user_mask_5_0: %d\n" 213 "directed: %d\n", 214 cookie, 215 freeze->freeze, 216 freeze->capture_reason, 217 freeze->packet_type, 218 freeze->packet_sub_type, 219 freeze->sw_peer_id_valid, 220 freeze->sw_peer_id, 221 freeze->phy_ppdu_id, 222 freeze->packet_ta_upper_16, 223 freeze->packet_ta_mid_16, 224 freeze->packet_ta_lower_16, 225 freeze->packet_ra_upper_16, 226 freeze->packet_ra_mid_16, 227 freeze->packet_ra_lower_16, 228 freeze->tsf_timestamp_63_48, 229 freeze->tsf_timestamp_47_32, 230 freeze->tsf_timestamp_31_16, 231 freeze->tsf_timestamp_15_0, 232 freeze->user_index_or_user_mask_5_0, 233 freeze->directed); 234 } 235 236 /** 237 * dump_freeze_tlv_v3() - Dump freeze TLV v2 sent in enhanced DMA header 238 * @freeze_tlv: Freeze TLV sent from MAC to PHY 239 * @cookie: Index into lookup table 240 * 241 * Return: none 242 */ 243 static void dump_freeze_tlv_v3(void *freeze_tlv, uint32_t cookie) 244 { 245 struct macrx_freeze_capture_channel_v3 *freeze = 246 (struct macrx_freeze_capture_channel_v3 *)freeze_tlv; 247 248 cfr_debug("<DBRCOMP><FREEZE><%u>\n" 249 "freeze: %d capture_reason: %d packet_type: 0x%x\n" 250 "packet_subtype: 0x%x sw_peer_id_valid: %d sw_peer_id: %d\n" 251 "phy_ppdu_id: 0x%04x packet_ta_upper_16: 0x%04x\n" 252 "packet_ta_mid_16: 0x%04x packet_ta_lower_16: 0x%04x\n" 253 "packet_ra_upper_16: 0x%04x packet_ra_mid_16: 0x%04x\n" 254 "packet_ra_lower_16: 0x%04x\n" 255 "tsf_63_48_or_user_mask_36_32: 0x%04x\n" 256 "tsf_timestamp_47_32: 0x%04x\n" 257 "tsf_timestamp_31_16: 0x%04x\n" 258 "tsf_timestamp_15_0: 0x%04x\n" 259 "user_index_or_user_mask_15_0: 0x%04x\n" 260 "user_mask_31_16: 0x%04x\n" 261 "directed: %d\n", 262 cookie, 263 freeze->freeze, 264 freeze->capture_reason, 265 freeze->packet_type, 266 freeze->packet_sub_type, 267 freeze->sw_peer_id_valid, 268 freeze->sw_peer_id, 269 freeze->phy_ppdu_id, 270 freeze->packet_ta_upper_16, 271 freeze->packet_ta_mid_16, 272 freeze->packet_ta_lower_16, 273 freeze->packet_ra_upper_16, 274 freeze->packet_ra_mid_16, 275 freeze->packet_ra_lower_16, 276 freeze->tsf_63_48_or_user_mask_36_32, 277 freeze->tsf_timestamp_47_32, 278 freeze->tsf_timestamp_31_16, 279 freeze->tsf_timestamp_15_0, 280 freeze->user_index_or_user_mask_15_0, 281 freeze->user_mask_31_16, 282 freeze->directed); 283 } 284 285 /** 286 * dump_mu_rx_info() - Dump MU info in enhanced DMA header 287 * @mu_rx_user_info: MU info sent by ucode 288 * @mu_rx_num_users: Number of MU users in UL-MU-PPDU 289 * @cookie: Index into lookup table 290 * 291 * Return: none 292 */ 293 static void dump_mu_rx_info(void *mu_rx_user_info, 294 uint8_t mu_rx_num_users, 295 uint32_t cookie) 296 { 297 uint8_t i; 298 struct uplink_user_setup_info *ul_mu_user_info = 299 (struct uplink_user_setup_info *)mu_rx_user_info; 300 301 for (i = 0 ; i < mu_rx_num_users; i++) { 302 cfr_debug("<DBRCOMP><MU><%u>\n" 303 "<user_id:%d>\n" 304 "bw_info_valid = %d\n" 305 "uplink_receive_type = %d\n" 306 "uplink_11ax_mcs = %d\n" 307 "ru_width = %d\n" 308 "nss = %d\n" 309 "stream_offset = %d\n" 310 "sta_dcm = %d\n" 311 "sta_coding = %d\n" 312 "ru_start_index = %d\n", 313 cookie, 314 i, 315 ul_mu_user_info->bw_info_valid, 316 ul_mu_user_info->uplink_receive_type, 317 ul_mu_user_info->uplink_11ax_mcs, 318 ul_mu_user_info->ru_width, 319 ul_mu_user_info->nss, 320 ul_mu_user_info->stream_offset, 321 ul_mu_user_info->sta_dcm, 322 ul_mu_user_info->sta_coding, 323 ul_mu_user_info->ru_start_index); 324 ul_mu_user_info += sizeof(struct uplink_user_setup_info); 325 } 326 } 327 328 static void dump_metadata(struct csi_cfr_header *header, uint32_t cookie) 329 { 330 uint8_t user_id, chain_id; 331 struct cfr_metadata_version_3 *meta = &header->u.meta_v3; 332 uint8_t *usermac = NULL; 333 334 cfr_debug("<METADATA><%u>\n" 335 "start_magic_num = 0x%x\n" 336 "vendorid = 0x%x\n" 337 "cfr_metadata_version = %d\n" 338 "cfr_data_version = %d\n" 339 "chip_type = %d\n" 340 "platform_type = %d\n" 341 "status = %d\n" 342 "capture_bw = %d\n" 343 "channel_bw = %d\n" 344 "phy_mode = %d\n" 345 "prim20_chan = %d\n" 346 "center_freq1 = %d\n" 347 "center_freq2 = %d\n" 348 "ack_capture_mode = %d\n" 349 "cfr_capture_type = %d\n" 350 "sts_count = %d\n" 351 "num_rx_chain = %d\n" 352 "timestamp = 0x%x\n" 353 "length = %d\n" 354 "is_mu_ppdu = %d\n" 355 "num_users = %d\n", 356 cookie, 357 header->start_magic_num, 358 header->vendorid, 359 header->cfr_metadata_version, 360 header->cfr_data_version, 361 header->chip_type, 362 header->pltform_type, 363 meta->status, 364 meta->capture_bw, 365 meta->channel_bw, 366 meta->phy_mode, 367 meta->prim20_chan, 368 meta->center_freq1, 369 meta->center_freq2, 370 meta->capture_mode, 371 meta->capture_type, 372 meta->sts_count, 373 meta->num_rx_chain, 374 meta->timestamp, 375 meta->length, 376 meta->is_mu_ppdu, 377 meta->num_mu_users); 378 379 if (meta->is_mu_ppdu) { 380 for (user_id = 0; user_id < meta->num_mu_users; user_id++) { 381 usermac = meta->peer_addr.mu_peer_addr[user_id]; 382 cfr_debug("peermac[%d]: " QDF_MAC_ADDR_STR, 383 user_id, QDF_MAC_ADDR_ARRAY(usermac)); 384 } 385 } else { 386 cfr_debug("peermac: " QDF_MAC_ADDR_STR, 387 QDF_MAC_ADDR_ARRAY(meta->peer_addr.su_peer_addr)); 388 } 389 390 for (chain_id = 0; chain_id < HOST_MAX_CHAINS; chain_id++) { 391 cfr_debug("chain_rssi[%d] = %d\n", 392 chain_id, 393 meta->chain_rssi[chain_id]); 394 } 395 396 for (chain_id = 0; chain_id < HOST_MAX_CHAINS; chain_id++) { 397 cfr_debug("chain_phase[%d] = %d\n", 398 chain_id, 399 meta->chain_phase[chain_id]); 400 } 401 } 402 403 /** 404 * dump_enh_dma_hdr() - Dump enhanced DMA header populated by ucode 405 * @dma_hdr: pointer to enhanced DMA header 406 * @freeze_tlv: pointer to MACRX_FREEZE_CAPTURE_CHANNEL TLV 407 * @mu_rx_user_info: UPLINK_USER_SETUP_INFO TLV 408 * @header: pointer to metadata passed to userspace 409 * @error: Indicates whether it is an error 410 * @cookie: Index into lookup table 411 * 412 * Return: none 413 */ 414 static void dump_enh_dma_hdr(struct whal_cfir_enhanced_hdr *dma_hdr, 415 void *freeze_tlv, void *mu_rx_user_info, 416 struct csi_cfr_header *header, int error, 417 uint32_t cookie) 418 { 419 if (!error) { 420 cfr_debug("<DBRCOMP><%u>\n" 421 "Tag: 0x%02x Length: %d udone: %d\n" 422 "ctype: %d preamble: %d Nss: %d\n" 423 "num_chains: %d bw: %d peervalid: %d\n" 424 "peer_id: %d ppdu_id: 0x%04x total_bytes: %d\n" 425 "header_version: %d target_id: %d cfr_fmt: %d\n" 426 "mu_rx_data_incl: %d freeze_data_incl: %d\n" 427 "mu_rx_num_users: %d decimation_factor: %d\n" 428 "freeze_tlv_version: %d\n", 429 cookie, 430 dma_hdr->tag, 431 dma_hdr->length, 432 dma_hdr->upload_done, 433 dma_hdr->capture_type, 434 dma_hdr->preamble_type, 435 dma_hdr->nss, 436 dma_hdr->num_chains, 437 dma_hdr->upload_pkt_bw, 438 dma_hdr->sw_peer_id_valid, 439 dma_hdr->sw_peer_id, 440 dma_hdr->phy_ppdu_id, 441 dma_hdr->total_bytes, 442 dma_hdr->header_version, 443 dma_hdr->target_id, 444 dma_hdr->cfr_fmt, 445 dma_hdr->mu_rx_data_incl, 446 dma_hdr->freeze_data_incl, 447 dma_hdr->mu_rx_num_users, 448 dma_hdr->decimation_factor, 449 dma_hdr->freeze_tlv_version); 450 451 if (dma_hdr->freeze_data_incl) { 452 if (dma_hdr->freeze_tlv_version == 453 MACRX_FREEZE_TLV_VERSION_3) 454 dump_freeze_tlv_v3(freeze_tlv, cookie); 455 else 456 dump_freeze_tlv(freeze_tlv, cookie); 457 } 458 459 if (dma_hdr->mu_rx_data_incl) 460 dump_mu_rx_info(mu_rx_user_info, 461 dma_hdr->mu_rx_num_users, 462 cookie); 463 } else { 464 cfr_err("<DBRCOMP><%u>\n" 465 "Tag: 0x%02x Length: %d udone: %d\n" 466 "ctype: %d preamble: %d Nss: %d\n" 467 "num_chains: %d bw: %d peervalid: %d\n" 468 "peer_id: %d ppdu_id: 0x%04x total_bytes: %d\n" 469 "header_version: %d target_id: %d cfr_fmt: %d\n" 470 "mu_rx_data_incl: %d freeze_data_incl: %d\n" 471 "mu_rx_num_users: %d decimation_factor: %d\n" 472 "freeze_tlv_version: %d\n", 473 cookie, 474 dma_hdr->tag, 475 dma_hdr->length, 476 dma_hdr->upload_done, 477 dma_hdr->capture_type, 478 dma_hdr->preamble_type, 479 dma_hdr->nss, 480 dma_hdr->num_chains, 481 dma_hdr->upload_pkt_bw, 482 dma_hdr->sw_peer_id_valid, 483 dma_hdr->sw_peer_id, 484 dma_hdr->phy_ppdu_id, 485 dma_hdr->total_bytes, 486 dma_hdr->header_version, 487 dma_hdr->target_id, 488 dma_hdr->cfr_fmt, 489 dma_hdr->mu_rx_data_incl, 490 dma_hdr->freeze_data_incl, 491 dma_hdr->mu_rx_num_users, 492 dma_hdr->decimation_factor, 493 dma_hdr->freeze_tlv_version); 494 } 495 } 496 497 /** 498 * extract_peer_mac_from_freeze_tlv() - extract macaddr from freeze tlv 499 * @freeze_tlv: Freeze TLV sent from MAC to PHY 500 * @peermac: macaddr of the peer 501 * 502 * Return: none 503 */ 504 static void 505 extract_peer_mac_from_freeze_tlv(void *freeze_tlv, uint8_t *peermac) 506 { 507 /* 508 * Packet_ta fields position is common between freeze tlv v1 509 * and v2, hence typecasting to v1 is also fine 510 */ 511 struct macrx_freeze_capture_channel *freeze = 512 (struct macrx_freeze_capture_channel *)freeze_tlv; 513 514 peermac[0] = freeze->packet_ta_lower_16 & 0x00FF; 515 peermac[1] = (freeze->packet_ta_lower_16 & 0xFF00) >> 8; 516 peermac[2] = freeze->packet_ta_mid_16 & 0x00FF; 517 peermac[3] = (freeze->packet_ta_mid_16 & 0xFF00) >> 8; 518 peermac[4] = freeze->packet_ta_upper_16 & 0x00FF; 519 peermac[5] = (freeze->packet_ta_upper_16 & 0xFF00) >> 8; 520 } 521 522 /** 523 * check_dma_length() - Sanity check DMA header and payload length 524 * @dma_hdr: pointer to enhanced DMA header 525 * 526 * Return: QDF_STATUS 527 */ 528 static QDF_STATUS check_dma_length(struct look_up_table *lut, 529 uint32_t target_type) 530 { 531 if (target_type == TARGET_TYPE_QCN9000) { 532 if (lut->header_length <= PINE_MAX_HEADER_LENGTH_WORDS && 533 lut->payload_length <= PINE_MAX_DATA_LENGTH_BYTES) { 534 return QDF_STATUS_SUCCESS; 535 } 536 } else { 537 if (lut->header_length <= CYP_MAX_HEADER_LENGTH_WORDS && 538 lut->payload_length <= CYP_MAX_DATA_LENGTH_BYTES) { 539 return QDF_STATUS_SUCCESS; 540 } 541 } 542 return QDF_STATUS_E_FAILURE; 543 } 544 545 /** 546 * correlate_and_relay_enh() - Correlate TXRX and DBR events and stream CFR 547 * data to userspace 548 * @pdev: objmgr PDEV 549 * @cookie: Index into lookup table 550 * @lut: pointer to lookup table 551 * @module_id: ID of the event received 552 * 0 - DBR event 553 * 1 - TXRX event 554 * 555 * Return: 556 * - STATUS_ERROR 557 * - STATUS_HOLD 558 * - STATUS_STREAM_AND_RELEASE 559 */ 560 static int correlate_and_relay_enh(struct wlan_objmgr_pdev *pdev, 561 uint32_t cookie, 562 struct look_up_table *lut, 563 uint8_t module_id) 564 { 565 struct pdev_cfr *pcfr; 566 uint64_t diff; 567 int status = STATUS_ERROR; 568 struct wlan_objmgr_psoc *psoc; 569 uint32_t target_type; 570 571 if (module_id > 1) { 572 cfr_err("Received request with invalid mod id. Investigate!!"); 573 QDF_ASSERT(0); 574 status = STATUS_ERROR; 575 goto done; 576 } 577 578 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 579 WLAN_UMAC_COMP_CFR); 580 581 psoc = wlan_pdev_get_psoc(pdev); 582 if (qdf_unlikely(!psoc)) { 583 cfr_err("psoc is null\n"); 584 status = STATUS_ERROR; 585 goto done; 586 } 587 588 target_type = target_if_cfr_get_target_type(psoc); 589 590 if (module_id == CORRELATE_TX_EV_MODULE_ID) { 591 if (lut->tx_recv) 592 pcfr->cfr_dma_aborts++; 593 lut->tx_recv = true; 594 } else if (module_id == CORRELATE_DBR_MODULE_ID) { 595 pcfr->dbr_evt_cnt++; 596 lut->dbr_recv = true; 597 } 598 599 if ((lut->dbr_recv) && (lut->tx_recv)) { 600 if (lut->dbr_ppdu_id == lut->tx_ppdu_id) { 601 pcfr->last_success_tstamp = lut->dbr_tstamp; 602 if (lut->dbr_tstamp > lut->txrx_tstamp) { 603 diff = lut->dbr_tstamp - lut->txrx_tstamp; 604 cfr_debug("<CORRELATE><%u>: " 605 "TXRX evt -> DBR evt" 606 "(delay = %llu ms)\n", cookie, diff); 607 } else if (lut->txrx_tstamp > lut->dbr_tstamp) { 608 diff = lut->txrx_tstamp - lut->dbr_tstamp; 609 cfr_debug("<CORRELATE><%u>: " 610 "DBR evt -> TXRX evt" 611 "(delay = %llu ms)\n", cookie, diff); 612 } 613 614 /* 615 * Flush pending dbr events, if newer PPDU TLV is 616 * received 617 */ 618 cfr_free_pending_dbr_events(pdev); 619 620 if (check_dma_length(lut, target_type) == 621 QDF_STATUS_SUCCESS) { 622 pcfr->release_cnt++; 623 cfr_debug("<CORRELATE><%u>:Stream and release " 624 "CFR data for " 625 "ppdu_id:0x%04x\n", cookie, 626 lut->tx_ppdu_id); 627 status = STATUS_STREAM_AND_RELEASE; 628 goto done; 629 } else { 630 pcfr->invalid_dma_length_cnt++; 631 cfr_err("<CORRELATE><%u>:CFR buffers " 632 "received with invalid length " 633 "header_length_words = %d " 634 "cfr_payload_length_bytes = %d " 635 "ppdu_id:0x%04x\n", 636 cookie, 637 lut->header_length, 638 lut->payload_length, 639 lut->tx_ppdu_id); 640 /* 641 * Assert here as length exceeding the allowed 642 * limit would anyway manifest as random crash 643 */ 644 QDF_ASSERT(0); 645 status = STATUS_ERROR; 646 goto done; 647 } 648 } else { 649 /* 650 * When there is a ppdu id mismatch, discard the TXRX 651 * event since multiple PPDUs are likely to have same 652 * dma addr, due to ucode aborts 653 */ 654 cfr_debug("Received new dbr event for same " 655 "cookie %u", 656 cookie); 657 lut->tx_recv = false; 658 lut->tx_ppdu_id = 0; 659 pcfr->clear_txrx_event++; 660 pcfr->cfr_dma_aborts++; 661 status = STATUS_HOLD; 662 } 663 } else { 664 status = STATUS_HOLD; 665 } 666 done: 667 return status; 668 } 669 670 /** 671 * target_if_cfr_rx_tlv_process() - Process PPDU status TLVs and store info in 672 * lookup table 673 * @pdev_obj: PDEV object 674 * @nbuf: ppdu info 675 * 676 * Return: none 677 */ 678 void target_if_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf) 679 { 680 struct cdp_rx_indication_ppdu *cdp_rx_ppdu; 681 struct cdp_rx_stats_ppdu_user *rx_stats_peruser; 682 struct cdp_rx_ppdu_cfr_info *cfr_info; 683 qdf_dma_addr_t buf_addr = 0, buf_addr_extn = 0; 684 struct pdev_cfr *pcfr; 685 struct look_up_table *lut = NULL; 686 struct csi_cfr_header *header = NULL; 687 uint32_t cookie; 688 struct wlan_objmgr_psoc *psoc; 689 struct wlan_channel *bss_chan; 690 enum wlan_phymode ch_phymode; 691 uint16_t ch_freq; 692 uint32_t ch_cfreq1; 693 uint32_t ch_cfreq2; 694 struct wlan_objmgr_vdev *vdev = NULL; 695 int i, status = 0; 696 QDF_STATUS retval = 0; 697 struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL; 698 struct cfr_metadata_version_3 *meta = NULL; 699 uint8_t srng_id = 0; 700 struct wlan_lmac_if_rx_ops *rx_ops; 701 702 if (qdf_unlikely(!pdev)) { 703 cfr_err("pdev is null\n"); 704 qdf_nbuf_free(nbuf); 705 return; 706 } 707 708 retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID); 709 if (qdf_unlikely(retval != QDF_STATUS_SUCCESS)) { 710 cfr_err("failed to get pdev reference"); 711 qdf_nbuf_free(nbuf); 712 return; 713 } 714 715 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 716 WLAN_UMAC_COMP_CFR); 717 if (qdf_unlikely(!pcfr)) { 718 cfr_err("pdev object for CFR is NULL"); 719 goto relref; 720 } 721 722 cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)qdf_nbuf_data(nbuf); 723 cfr_info = &cdp_rx_ppdu->cfr_info; 724 725 if (!cfr_info->bb_captured_channel) 726 goto relref; 727 728 psoc = wlan_pdev_get_psoc(pdev); 729 if (qdf_unlikely(!psoc)) { 730 cfr_err("psoc is null\n"); 731 goto relref; 732 } 733 734 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 735 if (!rx_ops) { 736 cfr_err("rx_ops is NULL"); 737 goto relref; 738 } 739 cfr_rx_ops = &rx_ops->cfr_rx_ops; 740 buf_addr_extn = cfr_info->rtt_che_buffer_pointer_high8 & 0xF; 741 buf_addr = (cfr_info->rtt_che_buffer_pointer_low32 | 742 ((uint64_t)buf_addr_extn << 32)); 743 744 srng_id = pcfr->rcc_param.srng_id; 745 if (target_if_dbr_cookie_lookup(pdev, DBR_MODULE_CFR, buf_addr, 746 &cookie, srng_id)) { 747 cfr_debug("Cookie lookup failure for addr: 0x%pK", 748 (void *)((uintptr_t)buf_addr)); 749 goto relref; 750 } 751 752 cfr_debug("<RXTLV><%u>:buffer address: 0x%pK\n" 753 "<WIFIRX_PPDU_START_E> ppdu_id: 0x%04x\n" 754 "<WIFIRXPCU_PPDU_END_INFO_E> BB_CAPTURED_CHANNEL = %d\n" 755 "<WIFIPHYRX_PKT_END_E> RX_LOCATION_INFO_VALID = %d\n" 756 "<WIFIPHYRX_PKT_END_E> RTT_CHE_BUFFER_POINTER_LOW32 = %x\n" 757 "<WIFIPHYRX_PKT_END_E> RTT_CHE_BUFFER_POINTER_HIGH8 = %x\n" 758 "<WIFIPHYRX_PKT_END_E> CHAN_CAPTURE_STATUS = %d\n", 759 cookie, 760 (void *)((uintptr_t)buf_addr), 761 cdp_rx_ppdu->ppdu_id, 762 cfr_info->bb_captured_channel, 763 cfr_info->rx_location_info_valid, 764 cfr_info->rtt_che_buffer_pointer_low32, 765 cfr_info->rtt_che_buffer_pointer_high8, 766 cfr_info->chan_capture_status); 767 768 qdf_spin_lock_bh(&pcfr->lut_lock); 769 770 lut = get_lut_entry(pcfr, cookie); 771 if (qdf_unlikely(!lut)) { 772 cfr_err("lut is NULL"); 773 goto unlock; 774 } 775 776 vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_CFR_ID); 777 if (qdf_unlikely(!vdev)) { 778 cfr_debug("vdev is null\n"); 779 goto unlock; 780 } 781 782 bss_chan = wlan_vdev_mlme_get_bss_chan(vdev); 783 ch_freq = bss_chan->ch_freq; 784 ch_cfreq1 = bss_chan->ch_cfreq1; 785 ch_cfreq2 = bss_chan->ch_cfreq2; 786 ch_phymode = bss_chan->ch_phymode; 787 wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); 788 789 pcfr->rx_tlv_evt_cnt++; 790 lut->tx_ppdu_id = cdp_rx_ppdu->ppdu_id; 791 lut->tx_address1 = cfr_info->rtt_che_buffer_pointer_low32; 792 lut->tx_address2 = cfr_info->rtt_che_buffer_pointer_high8; 793 lut->txrx_tstamp = qdf_ktime_to_ms(qdf_ktime_get()); 794 header = &lut->header; 795 meta = &header->u.meta_v3; 796 797 header->start_magic_num = 0xDEADBEAF; 798 header->vendorid = 0x8cfdf0; 799 header->cfr_metadata_version = CFR_META_VERSION_3; 800 header->cfr_data_version = CFR_DATA_VERSION_1; 801 header->chip_type = pcfr->chip_type; 802 header->pltform_type = CFR_PLATFORM_TYPE_ARM; 803 header->Reserved = 0; 804 805 meta->status = 1; 806 meta->phy_mode = ch_phymode; 807 meta->prim20_chan = ch_freq; 808 meta->center_freq1 = ch_cfreq1; 809 meta->center_freq2 = ch_cfreq2; 810 meta->capture_mode = 0; 811 812 meta->timestamp = cdp_rx_ppdu->timestamp; 813 meta->is_mu_ppdu = (cdp_rx_ppdu->u.ppdu_type == CDP_RX_TYPE_SU) ? 0 : 1; 814 meta->num_mu_users = (meta->is_mu_ppdu) ? (cdp_rx_ppdu->num_users) : 0; 815 816 if (meta->num_mu_users > pcfr->max_mu_users) 817 meta->num_mu_users = pcfr->max_mu_users; 818 819 for (i = 0; i < MAX_CHAIN; i++) 820 meta->chain_rssi[i] = 821 snr_to_signal_strength(cdp_rx_ppdu->per_chain_rssi[i]); 822 823 if (cdp_rx_ppdu->u.ppdu_type != CDP_RX_TYPE_SU) { 824 for (i = 0 ; i < meta->num_mu_users; i++) { 825 rx_stats_peruser = &cdp_rx_ppdu->user[i]; 826 qdf_mem_copy(meta->peer_addr.mu_peer_addr[i], 827 rx_stats_peruser->mac_addr, 828 QDF_MAC_ADDR_SIZE); 829 } 830 } 831 status = correlate_and_relay_enh(pdev, cookie, lut, 832 CORRELATE_TX_EV_MODULE_ID); 833 if (status == STATUS_STREAM_AND_RELEASE) { 834 if (cfr_rx_ops->cfr_info_send) 835 status = cfr_rx_ops->cfr_info_send(pdev, 836 &lut->header, 837 sizeof(struct 838 csi_cfr_header), 839 lut->data, 840 lut->data_len, 841 &end_magic, 4); 842 dump_metadata(header, cookie); 843 release_lut_entry_enh(pdev, lut); 844 target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, buf_addr, 845 cookie, srng_id); 846 } 847 848 unlock: 849 qdf_spin_unlock_bh(&pcfr->lut_lock); 850 relref: 851 qdf_nbuf_free(nbuf); 852 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 853 } 854 855 /** 856 * freeze_reason_to_capture_type() - Convert capture type enum in freeze tlv 857 * to the cfr type enum shared with userspace 858 * @freeze_tlv: pointer to MACRX_FREEZE_CAPTURE_CHANNEL TLV 859 * 860 * Return: cfr type enum 861 */ 862 static uint8_t freeze_reason_to_capture_type(void *freeze_tlv) 863 { 864 /* 865 * Capture_reason field position is common between freeze_tlv v1 866 * and v2, hence typcasting to any one is fine 867 */ 868 struct macrx_freeze_capture_channel *freeze = 869 (struct macrx_freeze_capture_channel *)freeze_tlv; 870 871 switch (freeze->capture_reason) { 872 case FREEZE_REASON_TM: 873 return CFR_TYPE_METHOD_TM; 874 case FREEZE_REASON_FTM: 875 return CFR_TYPE_METHOD_FTM; 876 case FREEZE_REASON_TA_RA_TYPE_FILTER: 877 return CFR_TYPE_METHOD_TA_RA_TYPE_FILTER; 878 case FREEZE_REASON_NDPA_NDP: 879 return CFR_TYPE_METHOD_NDPA_NDP; 880 case FREEZE_REASON_ALL_PACKET: 881 return CFR_TYPE_METHOD_ALL_PACKET; 882 case FREEZE_REASON_ACK_RESP_TO_TM_FTM: 883 return CFR_TYPE_METHOD_ACK_RESP_TO_TM_FTM; 884 default: 885 return CFR_TYPE_METHOD_AUTO; 886 } 887 return CFR_TYPE_METHOD_AUTO; 888 } 889 890 #ifdef DIRECT_BUF_RX_ENABLE 891 /** 892 * enh_cfr_dbr_event_handler() - Process DBR event for CFR data DMA completion 893 * @pdev: PDEV object 894 * @payload: pointer to CFR data 895 * 896 * Return: status 897 */ 898 static bool enh_cfr_dbr_event_handler(struct wlan_objmgr_pdev *pdev, 899 struct direct_buf_rx_data *payload) 900 { 901 uint8_t *data = NULL; 902 uint32_t cookie = 0; 903 struct whal_cfir_enhanced_hdr dma_hdr = {0}; 904 int length, status = 0; 905 struct wlan_objmgr_psoc *psoc; 906 struct pdev_cfr *pcfr; 907 struct look_up_table *lut = NULL; 908 struct csi_cfr_header *header = NULL; 909 void *mu_rx_user_info = NULL, *freeze_tlv = NULL; 910 uint8_t capture_type = CFR_TYPE_METHOD_AUTO; 911 uint8_t *peer_macaddr = NULL; 912 struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL; 913 struct cfr_metadata_version_3 *meta = NULL; 914 struct wlan_lmac_if_rx_ops *rx_ops; 915 916 if ((!pdev) || (!payload)) { 917 cfr_err("pdev or payload is null"); 918 return true; 919 } 920 921 psoc = wlan_pdev_get_psoc(pdev); 922 if (!psoc) { 923 cfr_err("psoc is null"); 924 return true; 925 } 926 927 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 928 if (!rx_ops) { 929 cfr_err("rx_ops is NULL"); 930 return true; 931 } 932 cfr_rx_ops = &rx_ops->cfr_rx_ops; 933 934 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 935 WLAN_UMAC_COMP_CFR); 936 if (!pcfr) { 937 cfr_err("pdev object for CFR is null"); 938 return true; 939 } 940 941 data = payload->vaddr; 942 cookie = payload->cookie; 943 944 cfr_debug("<DBRCOMP><%u>:bufferaddr: 0x%pK cookie: %u\n", cookie, 945 (void *)((uintptr_t)payload->paddr), cookie); 946 947 qdf_mem_copy(&dma_hdr, &data[0], 948 sizeof(struct whal_cfir_enhanced_hdr)); 949 950 if (dma_hdr.freeze_data_incl) { 951 freeze_tlv = data + sizeof(struct whal_cfir_enhanced_hdr); 952 capture_type = freeze_reason_to_capture_type(freeze_tlv); 953 } 954 955 if (dma_hdr.mu_rx_data_incl) { 956 uint8_t freeze_tlv_len; 957 958 if (dma_hdr.freeze_tlv_version == MACRX_FREEZE_TLV_VERSION_3) { 959 freeze_tlv_len = 960 sizeof(struct macrx_freeze_capture_channel_v3); 961 } else { 962 freeze_tlv_len = 963 sizeof(struct macrx_freeze_capture_channel); 964 } 965 mu_rx_user_info = data + 966 sizeof(struct whal_cfir_enhanced_hdr) + 967 (dma_hdr.freeze_data_incl ? freeze_tlv_len : 0); 968 } 969 970 length = dma_hdr.length * 4; 971 length += dma_hdr.total_bytes; /* size of cfr data */ 972 973 qdf_spin_lock_bh(&pcfr->lut_lock); 974 975 lut = get_lut_entry(pcfr, cookie); 976 if (!lut) { 977 cfr_err("lut is NULL"); 978 qdf_spin_unlock_bh(&pcfr->lut_lock); 979 return true; 980 } 981 982 lut->data = data; 983 lut->data_len = length; 984 lut->dbr_ppdu_id = dma_hdr.phy_ppdu_id; 985 lut->dbr_address = payload->paddr; 986 lut->dbr_tstamp = qdf_ktime_to_ms(qdf_ktime_get()); 987 lut->header_length = dma_hdr.length; 988 lut->payload_length = dma_hdr.total_bytes; 989 qdf_mem_copy(&lut->dma_hdr, &dma_hdr, 990 sizeof(struct whal_cfir_dma_hdr)); 991 992 header = &lut->header; 993 header->chip_type = pcfr->chip_type; 994 meta = &header->u.meta_v3; 995 meta->channel_bw = dma_hdr.upload_pkt_bw; 996 meta->num_rx_chain = NUM_CHAINS_FW_TO_HOST(dma_hdr.num_chains); 997 meta->length = length; 998 /* For Tx based captures, capture type is sent from FW */ 999 if (capture_type != CFR_TYPE_METHOD_ACK_RESP_TO_TM_FTM) { 1000 meta->capture_type = capture_type; 1001 meta->sts_count = (dma_hdr.nss + 1); 1002 if (!dma_hdr.mu_rx_data_incl) { 1003 /* extract peer addr from freeze tlv */ 1004 peer_macaddr = meta->peer_addr.su_peer_addr; 1005 if (dma_hdr.freeze_data_incl) { 1006 extract_peer_mac_from_freeze_tlv(freeze_tlv, 1007 peer_macaddr); 1008 } 1009 } 1010 } 1011 1012 if (dma_hdr.freeze_data_incl) { 1013 dump_enh_dma_hdr(&dma_hdr, freeze_tlv, mu_rx_user_info, 1014 header, 0, cookie); 1015 } 1016 1017 status = correlate_and_relay_enh(pdev, cookie, lut, 1018 CORRELATE_DBR_MODULE_ID); 1019 if (status == STATUS_STREAM_AND_RELEASE) { 1020 /* 1021 * Message format 1022 * Meta data Header + actual payload + trailer 1023 */ 1024 if (cfr_rx_ops->cfr_info_send) 1025 status = cfr_rx_ops->cfr_info_send(pdev, 1026 &lut->header, 1027 sizeof(struct 1028 csi_cfr_header), 1029 lut->data, 1030 lut->data_len, 1031 &end_magic, 4); 1032 dump_metadata(header, cookie); 1033 release_lut_entry_enh(pdev, lut); 1034 status = true; 1035 } else if (status == STATUS_HOLD) { 1036 status = false; 1037 } else { 1038 status = true; 1039 } 1040 1041 qdf_spin_unlock_bh(&pcfr->lut_lock); 1042 return status; 1043 } 1044 1045 /** 1046 * target_if_register_to_dbr_enh() - Initialize DBR ring and register callback 1047 * for DBR events 1048 * @pdev: PDEV object 1049 * 1050 * Return: status 1051 */ 1052 static QDF_STATUS 1053 target_if_register_to_dbr_enh(struct wlan_objmgr_pdev *pdev) 1054 { 1055 struct wlan_objmgr_psoc *psoc; 1056 struct wlan_lmac_if_direct_buf_rx_tx_ops *dbr_tx_ops = NULL; 1057 struct dbr_module_config dbr_config; 1058 struct wlan_lmac_if_tx_ops *tx_ops; 1059 1060 psoc = wlan_pdev_get_psoc(pdev); 1061 tx_ops = wlan_psoc_get_lmac_if_txops(psoc); 1062 if (!tx_ops) { 1063 cfr_err("tx_ops is NULL"); 1064 return QDF_STATUS_SUCCESS; 1065 } 1066 dbr_tx_ops = &tx_ops->dbr_tx_ops; 1067 dbr_config.num_resp_per_event = DBR_NUM_RESP_PER_EVENT_CFR; 1068 dbr_config.event_timeout_in_ms = DBR_EVENT_TIMEOUT_IN_MS_CFR; 1069 if (dbr_tx_ops->direct_buf_rx_module_register) { 1070 return dbr_tx_ops->direct_buf_rx_module_register 1071 (pdev, DBR_MODULE_CFR, &dbr_config, 1072 enh_cfr_dbr_event_handler); 1073 } 1074 1075 return QDF_STATUS_SUCCESS; 1076 } 1077 1078 /** 1079 * target_if_unregister_to_dbr_enh() - Unregister callback for DBR events 1080 * @pdev: PDEV object 1081 * 1082 * Return: status 1083 */ 1084 static QDF_STATUS 1085 target_if_unregister_to_dbr_enh(struct wlan_objmgr_pdev *pdev) 1086 { 1087 struct wlan_objmgr_psoc *psoc; 1088 struct wlan_lmac_if_direct_buf_rx_tx_ops *dbr_tx_ops = NULL; 1089 struct wlan_lmac_if_tx_ops *tx_ops; 1090 1091 psoc = wlan_pdev_get_psoc(pdev); 1092 tx_ops = wlan_psoc_get_lmac_if_txops(psoc); 1093 if (!tx_ops) { 1094 cfr_err("tx_ops is NULL"); 1095 return QDF_STATUS_SUCCESS; 1096 } 1097 dbr_tx_ops = &tx_ops->dbr_tx_ops; 1098 if (dbr_tx_ops->direct_buf_rx_module_unregister) { 1099 return dbr_tx_ops->direct_buf_rx_module_unregister 1100 (pdev, DBR_MODULE_CFR); 1101 } 1102 1103 return QDF_STATUS_SUCCESS; 1104 } 1105 #endif 1106 1107 /** 1108 * dump_cfr_peer_tx_event_enh() - Dump TX completion event 1109 * @event: ptr to WMI TX completion event for QOS frames sent during 1110 * one-shot capture 1111 * @cookie: Index into lookup table 1112 * 1113 * Return: none 1114 */ 1115 static void dump_cfr_peer_tx_event_enh(wmi_cfr_peer_tx_event_param *event, 1116 uint32_t cookie) 1117 { 1118 cfr_debug("<TXCOMP><%u>CFR capture method: %d vdev_id: %d mac: " 1119 QDF_MAC_ADDR_STR, cookie, 1120 event->capture_method, event->vdev_id, 1121 QDF_MAC_ADDR_ARRAY(event->peer_mac_addr.bytes)); 1122 1123 cfr_debug("<TXCOMP><%u>Chan: %d bw: %d phymode: %d cfreq1: %d cfrq2: %d " 1124 "nss: %d\n", 1125 cookie, 1126 event->primary_20mhz_chan, event->bandwidth, 1127 event->phy_mode, event->band_center_freq1, 1128 event->band_center_freq2, event->spatial_streams); 1129 1130 cfr_debug("<TXCOMP><%u>Correlation_info1: 0x%08x " 1131 "Correlation_info2: 0x%08x\n", 1132 cookie, 1133 event->correlation_info_1, event->correlation_info_2); 1134 1135 cfr_debug("<TXCOMP><%u>status: 0x%x ts: %d counter: %d rssi0: 0x%08x\n", 1136 cookie, 1137 event->status, event->timestamp_us, event->counter, 1138 event->chain_rssi[0]); 1139 } 1140 1141 #ifdef DIRECT_BUF_RX_ENABLE 1142 /** 1143 * enh_prepare_cfr_header_txstatus() - Prepare CFR metadata for TX failures 1144 * @tx_evt_param: ptr to WMI TX completion event 1145 * @header: pointer to metadata 1146 * 1147 * Return: none 1148 */ 1149 static void enh_prepare_cfr_header_txstatus(wmi_cfr_peer_tx_event_param 1150 *tx_evt_param, 1151 struct csi_cfr_header *header, 1152 uint32_t target_type) 1153 { 1154 header->start_magic_num = 0xDEADBEAF; 1155 header->vendorid = 0x8cfdf0; 1156 header->cfr_metadata_version = CFR_META_VERSION_3; 1157 header->cfr_data_version = CFR_DATA_VERSION_1; 1158 1159 if (target_type == TARGET_TYPE_QCN9000) 1160 header->chip_type = CFR_CAPTURE_RADIO_PINE; 1161 else 1162 header->chip_type = CFR_CAPTURE_RADIO_CYP; 1163 1164 header->pltform_type = CFR_PLATFORM_TYPE_ARM; 1165 header->Reserved = 0; 1166 header->u.meta_v3.status = 0; /* failure */ 1167 header->u.meta_v3.length = 0; 1168 1169 qdf_mem_copy(&header->u.meta_v3.peer_addr.su_peer_addr[0], 1170 &tx_evt_param->peer_mac_addr.bytes[0], QDF_MAC_ADDR_SIZE); 1171 } 1172 1173 /** 1174 * target_if_peer_capture_event() - WMI TX completion event for one-shot 1175 * capture 1176 * @sc: pointer to offload soc object 1177 * @data: WMI TX completion event buffer 1178 * @datalen: WMI Tx completion event buffer length 1179 * 1180 * Return: status 1181 */ 1182 static int 1183 target_if_peer_capture_event(ol_scn_t sc, uint8_t *data, uint32_t datalen) 1184 { 1185 QDF_STATUS retval = 0; 1186 struct wmi_unified *wmi_handle; 1187 struct wlan_objmgr_psoc *psoc; 1188 struct wlan_objmgr_pdev *pdev; 1189 struct wlan_objmgr_vdev *vdev; 1190 uint32_t cookie; 1191 struct pdev_cfr *pcfr; 1192 struct look_up_table *lut = NULL; 1193 struct csi_cfr_header *header = NULL; 1194 struct csi_cfr_header header_error = {0}; 1195 wmi_cfr_peer_tx_event_param tx_evt_param = {0}; 1196 qdf_dma_addr_t buf_addr = 0, buf_addr_temp = 0; 1197 int status; 1198 struct wlan_channel *bss_chan; 1199 struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL; 1200 struct wlan_lmac_if_rx_ops *rx_ops; 1201 uint32_t target_type; 1202 1203 if (!sc || !data) { 1204 cfr_err("sc or data is null"); 1205 return -EINVAL; 1206 } 1207 1208 psoc = target_if_get_psoc_from_scn_hdl(sc); 1209 if (!psoc) { 1210 cfr_err("psoc is null"); 1211 return -EINVAL; 1212 } 1213 1214 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1215 if (!rx_ops) { 1216 cfr_err("rx_ops is NULL"); 1217 return -EINVAL; 1218 } 1219 cfr_rx_ops = &rx_ops->cfr_rx_ops; 1220 1221 retval = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_CFR_ID); 1222 if (QDF_IS_STATUS_ERROR(retval)) { 1223 cfr_err("unable to get psoc reference"); 1224 return -EINVAL; 1225 } 1226 1227 wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); 1228 if (!wmi_handle) { 1229 cfr_err("wmi_handle is null"); 1230 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1231 return -EINVAL; 1232 } 1233 1234 retval = wmi_extract_cfr_peer_tx_event_param(wmi_handle, data, 1235 &tx_evt_param); 1236 1237 if (retval != QDF_STATUS_SUCCESS) { 1238 cfr_err("Failed to extract cfr tx event param"); 1239 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1240 return -EINVAL; 1241 } 1242 1243 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, tx_evt_param.vdev_id, 1244 WLAN_CFR_ID); 1245 if (!vdev) { 1246 cfr_err("vdev is null"); 1247 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1248 return -EINVAL; 1249 } 1250 1251 pdev = wlan_vdev_get_pdev(vdev); 1252 if (!pdev) { 1253 cfr_err("pdev is null"); 1254 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1255 wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); 1256 return -EINVAL; 1257 } 1258 1259 retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID); 1260 if (retval != QDF_STATUS_SUCCESS) { 1261 cfr_err("failed to get pdev reference"); 1262 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1263 wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); 1264 return -EINVAL; 1265 } 1266 1267 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1268 WLAN_UMAC_COMP_CFR); 1269 if (!pcfr) { 1270 cfr_err("pdev object for CFR is NULL"); 1271 retval = -EINVAL; 1272 goto relref; 1273 } 1274 1275 target_type = target_if_cfr_get_target_type(psoc); 1276 1277 if ((tx_evt_param.status & PEER_CFR_CAPTURE_EVT_PS_STATUS_MASK) == 1) { 1278 cfr_err("CFR capture failed as peer is in powersave: " 1279 QDF_MAC_ADDR_STR, 1280 QDF_MAC_ADDR_ARRAY(tx_evt_param.peer_mac_addr.bytes)); 1281 1282 enh_prepare_cfr_header_txstatus(&tx_evt_param, 1283 &header_error, 1284 target_type); 1285 if (cfr_rx_ops->cfr_info_send) 1286 cfr_rx_ops->cfr_info_send(pdev, 1287 &header_error, 1288 sizeof(struct 1289 csi_cfr_header), 1290 NULL, 0, &end_magic, 4); 1291 1292 retval = -EINVAL; 1293 goto relref; 1294 } 1295 1296 if ((tx_evt_param.status & PEER_CFR_CAPTURE_EVT_STATUS_MASK) == 0) { 1297 cfr_debug("CFR capture failed for peer: " QDF_MAC_ADDR_STR, 1298 QDF_MAC_ADDR_ARRAY(tx_evt_param.peer_mac_addr.bytes)); 1299 pcfr->tx_peer_status_cfr_fail++; 1300 retval = -EINVAL; 1301 goto relref; 1302 } 1303 1304 if (tx_evt_param.status & CFR_TX_EVT_STATUS_MASK) { 1305 cfr_debug("TX packet returned status %d for peer: " 1306 QDF_MAC_ADDR_STR, 1307 tx_evt_param.status & CFR_TX_EVT_STATUS_MASK, 1308 QDF_MAC_ADDR_ARRAY(tx_evt_param.peer_mac_addr.bytes)); 1309 pcfr->tx_evt_status_cfr_fail++; 1310 retval = -EINVAL; 1311 goto relref; 1312 } 1313 1314 buf_addr_temp = (tx_evt_param.correlation_info_2 & 0x0f); 1315 buf_addr = (tx_evt_param.correlation_info_1 | 1316 ((uint64_t)buf_addr_temp << 32)); 1317 1318 if (target_if_dbr_cookie_lookup(pdev, DBR_MODULE_CFR, buf_addr, 1319 &cookie, 0)) { 1320 cfr_debug("Cookie lookup failure for addr: 0x%pK status: 0x%x", 1321 (void *)((uintptr_t)buf_addr), tx_evt_param.status); 1322 pcfr->tx_dbr_cookie_lookup_fail++; 1323 retval = -EINVAL; 1324 goto relref; 1325 } 1326 1327 cfr_debug("buffer address: 0x%pK cookie: %u", 1328 (void *)((uintptr_t)buf_addr), cookie); 1329 1330 dump_cfr_peer_tx_event_enh(&tx_evt_param, cookie); 1331 1332 qdf_spin_lock_bh(&pcfr->lut_lock); 1333 1334 lut = get_lut_entry(pcfr, cookie); 1335 if (!lut) { 1336 cfr_err("lut is NULL\n"); 1337 retval = -EINVAL; 1338 goto unlock; 1339 } 1340 1341 pcfr->tx_evt_cnt++; 1342 pcfr->total_tx_evt_cnt++; 1343 1344 lut->tx_ppdu_id = (tx_evt_param.correlation_info_2 >> 16); 1345 lut->tx_address1 = tx_evt_param.correlation_info_1; 1346 lut->tx_address2 = tx_evt_param.correlation_info_2; 1347 lut->txrx_tstamp = qdf_ktime_to_ms(qdf_ktime_get()); 1348 1349 header = &lut->header; 1350 header->start_magic_num = 0xDEADBEAF; 1351 header->vendorid = 0x8cfdf0; 1352 header->cfr_metadata_version = CFR_META_VERSION_3; 1353 header->cfr_data_version = CFR_DATA_VERSION_1; 1354 1355 if (target_type == TARGET_TYPE_QCN9000) 1356 header->chip_type = CFR_CAPTURE_RADIO_PINE; 1357 else 1358 header->chip_type = CFR_CAPTURE_RADIO_CYP; 1359 1360 header->pltform_type = CFR_PLATFORM_TYPE_ARM; 1361 header->Reserved = 0; 1362 header->u.meta_v3.status = (tx_evt_param.status & 1363 PEER_CFR_CAPTURE_EVT_STATUS_MASK) ? 1364 1 : 0; 1365 header->u.meta_v3.capture_bw = tx_evt_param.bandwidth; 1366 1367 bss_chan = wlan_vdev_mlme_get_bss_chan(vdev); 1368 header->u.meta_v3.phy_mode = bss_chan->ch_phymode; 1369 1370 header->u.meta_v3.prim20_chan = tx_evt_param.primary_20mhz_chan; 1371 header->u.meta_v3.center_freq1 = tx_evt_param.band_center_freq1; 1372 header->u.meta_v3.center_freq2 = tx_evt_param.band_center_freq2; 1373 1374 /* Currently CFR data is captured on ACK of a Qos NULL frame. 1375 * For 20 MHz, ACK is Legacy and for 40/80/160, ACK is DUP Legacy. 1376 */ 1377 header->u.meta_v3.capture_mode = tx_evt_param.bandwidth ? 1378 CFR_DUP_LEGACY_ACK : CFR_LEGACY_ACK; 1379 header->u.meta_v3.capture_type = tx_evt_param.capture_method; 1380 header->u.meta_v3.num_rx_chain = wlan_vdev_mlme_get_rxchainmask(vdev); 1381 header->u.meta_v3.sts_count = tx_evt_param.spatial_streams; 1382 header->u.meta_v3.timestamp = tx_evt_param.timestamp_us; 1383 1384 qdf_mem_copy(&header->u.meta_v3.peer_addr.su_peer_addr[0], 1385 &tx_evt_param.peer_mac_addr.bytes[0], QDF_MAC_ADDR_SIZE); 1386 qdf_mem_copy(&header->u.meta_v3.chain_rssi[0], 1387 &tx_evt_param.chain_rssi[0], 1388 HOST_MAX_CHAINS * sizeof(tx_evt_param.chain_rssi[0])); 1389 qdf_mem_copy(&header->u.meta_v3.chain_phase[0], 1390 &tx_evt_param.chain_phase[0], 1391 HOST_MAX_CHAINS * sizeof(tx_evt_param.chain_phase[0])); 1392 1393 status = correlate_and_relay_enh(pdev, cookie, lut, 1394 CORRELATE_TX_EV_MODULE_ID); 1395 if (status == STATUS_STREAM_AND_RELEASE) { 1396 if (cfr_rx_ops->cfr_info_send) 1397 status = cfr_rx_ops->cfr_info_send(pdev, 1398 &lut->header, 1399 sizeof( 1400 struct 1401 csi_cfr_header), 1402 lut->data, 1403 lut->data_len, 1404 &end_magic, 4); 1405 dump_metadata(header, cookie); 1406 release_lut_entry_enh(pdev, lut); 1407 target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, buf_addr, 1408 cookie, 0); 1409 } else { 1410 retval = -EINVAL; 1411 } 1412 1413 unlock: 1414 qdf_spin_unlock_bh(&pcfr->lut_lock); 1415 relref: 1416 1417 wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID); 1418 wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID); 1419 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 1420 1421 return retval; 1422 } 1423 #else 1424 static int 1425 target_if_peer_capture_event(ol_scn_t sc, uint8_t *data, uint32_t datalen) 1426 { 1427 return 0; 1428 } 1429 #endif 1430 1431 /** 1432 * target_if_register_tx_completion_enh_event_handler() - Register callback for 1433 * WMI TX completion event 1434 * @psoc: PSOC object 1435 * 1436 * Return: Success/Failure status 1437 */ 1438 static int 1439 target_if_register_tx_completion_enh_event_handler(struct wlan_objmgr_psoc 1440 *psoc) 1441 { 1442 /* Register completion handler here */ 1443 wmi_unified_t wmi_hdl; 1444 int ret = 0; 1445 1446 wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc); 1447 if (!wmi_hdl) { 1448 cfr_err("Unable to get wmi handle"); 1449 return -EINVAL; 1450 } 1451 1452 ret = wmi_unified_register_event_handler(wmi_hdl, 1453 wmi_peer_cfr_capture_event_id, 1454 target_if_peer_capture_event, 1455 WMI_RX_UMAC_CTX); 1456 /* 1457 * Event registration is called per pdev 1458 * Ignore erorr if event is alreday registred. 1459 */ 1460 if (ret == QDF_STATUS_E_FAILURE) 1461 ret = QDF_STATUS_SUCCESS; 1462 1463 return ret; 1464 } 1465 1466 /** 1467 * target_if_unregister_tx_completion_enh_event_handler() - Unregister callback 1468 * for WMI TX completion event 1469 * @psoc: PSOC object 1470 * 1471 * Return: Success/Failure status 1472 */ 1473 static int 1474 target_if_unregister_tx_completion_enh_event_handler(struct wlan_objmgr_psoc 1475 *psoc) 1476 { 1477 /* Unregister completion handler here */ 1478 wmi_unified_t wmi_hdl; 1479 int status = 0; 1480 1481 wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc); 1482 if (!wmi_hdl) { 1483 cfr_err("Unable to get wmi handle"); 1484 return -EINVAL; 1485 } 1486 1487 status = wmi_unified_unregister_event(wmi_hdl, 1488 wmi_peer_cfr_capture_event_id); 1489 return status; 1490 } 1491 1492 /** 1493 * lut_ageout_timer_task() - Timer to flush pending TXRX/DBR events 1494 * 1495 * Return: none 1496 */ 1497 static os_timer_func(lut_ageout_timer_task) 1498 { 1499 int i = 0; 1500 struct pdev_cfr *pcfr = NULL; 1501 struct wlan_objmgr_pdev *pdev = NULL; 1502 struct look_up_table *lut = NULL; 1503 uint64_t diff, cur_tstamp; 1504 uint8_t srng_id = 0; 1505 1506 OS_GET_TIMER_ARG(pcfr, struct pdev_cfr*); 1507 1508 if (!pcfr) { 1509 cfr_err("pdev object for CFR is null"); 1510 return; 1511 } 1512 1513 pdev = pcfr->pdev_obj; 1514 if (!pdev) { 1515 cfr_err("pdev is null"); 1516 return; 1517 } 1518 1519 srng_id = pcfr->rcc_param.srng_id; 1520 if (wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID) 1521 != QDF_STATUS_SUCCESS) { 1522 cfr_err("failed to get pdev reference"); 1523 return; 1524 } 1525 1526 cur_tstamp = qdf_ktime_to_ms(qdf_ktime_get()); 1527 1528 qdf_spin_lock_bh(&pcfr->lut_lock); 1529 1530 for (i = 0; i < pcfr->lut_num; i++) { 1531 lut = get_lut_entry(pcfr, i); 1532 if (!lut) 1533 continue; 1534 1535 if (lut->dbr_recv && !lut->tx_recv) { 1536 diff = cur_tstamp - lut->dbr_tstamp; 1537 if (diff > LUT_AGE_THRESHOLD) { 1538 target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, 1539 lut->dbr_address, 1540 i, srng_id); 1541 pcfr->flush_timeout_dbr_cnt++; 1542 release_lut_entry_enh(pdev, lut); 1543 } 1544 } 1545 } 1546 1547 qdf_spin_unlock_bh(&pcfr->lut_lock); 1548 1549 if (pcfr->lut_timer_init) 1550 qdf_timer_mod(&pcfr->lut_age_timer, LUT_AGE_TIMER); 1551 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); 1552 } 1553 1554 /** 1555 * target_if_cfr_start_lut_age_timer() - Start timer to flush aged-out LUT 1556 * entries 1557 * @pdev: pointer to pdev object 1558 * 1559 * Return: None 1560 */ 1561 void target_if_cfr_start_lut_age_timer(struct wlan_objmgr_pdev *pdev) 1562 { 1563 struct pdev_cfr *pcfr; 1564 1565 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1566 WLAN_UMAC_COMP_CFR); 1567 if (pcfr->lut_timer_init) 1568 qdf_timer_mod(&pcfr->lut_age_timer, LUT_AGE_TIMER); 1569 } 1570 1571 /** 1572 * target_if_cfr_stop_lut_age_timer() - Stop timer to flush aged-out LUT 1573 * entries 1574 * @pdev: pointer to pdev object 1575 * 1576 * Return: None 1577 */ 1578 void target_if_cfr_stop_lut_age_timer(struct wlan_objmgr_pdev *pdev) 1579 { 1580 struct pdev_cfr *pcfr; 1581 1582 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1583 WLAN_UMAC_COMP_CFR); 1584 if (pcfr->lut_timer_init) 1585 qdf_timer_stop(&pcfr->lut_age_timer); 1586 } 1587 1588 /** 1589 * target_if_cfr_update_global_cfg() - Update global config after a successful 1590 * commit 1591 * @pdev: pointer to pdev object 1592 * 1593 * Return: None 1594 */ 1595 void target_if_cfr_update_global_cfg(struct wlan_objmgr_pdev *pdev) 1596 { 1597 int grp_id; 1598 struct pdev_cfr *pcfr; 1599 struct ta_ra_cfr_cfg *curr_cfg = NULL; 1600 struct ta_ra_cfr_cfg *glbl_cfg = NULL; 1601 unsigned long *modified_in_this_session; 1602 1603 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1604 WLAN_UMAC_COMP_CFR); 1605 modified_in_this_session = 1606 (unsigned long *)&pcfr->rcc_param.modified_in_curr_session; 1607 1608 for (grp_id = 0; grp_id < MAX_TA_RA_ENTRIES; grp_id++) { 1609 if (qdf_test_bit(grp_id, modified_in_this_session)) { 1610 /* Populating global config based on user's input */ 1611 glbl_cfg = &pcfr->global[grp_id]; 1612 curr_cfg = &pcfr->rcc_param.curr[grp_id]; 1613 1614 if (curr_cfg->valid_ta) 1615 qdf_mem_copy(glbl_cfg->tx_addr, 1616 curr_cfg->tx_addr, 1617 QDF_MAC_ADDR_SIZE); 1618 1619 if (curr_cfg->valid_ra) 1620 qdf_mem_copy(glbl_cfg->rx_addr, 1621 curr_cfg->rx_addr, 1622 QDF_MAC_ADDR_SIZE); 1623 1624 if (curr_cfg->valid_ta_mask) 1625 qdf_mem_copy(glbl_cfg->tx_addr_mask, 1626 curr_cfg->tx_addr_mask, 1627 QDF_MAC_ADDR_SIZE); 1628 1629 if (curr_cfg->valid_ra_mask) 1630 qdf_mem_copy(glbl_cfg->rx_addr_mask, 1631 curr_cfg->rx_addr_mask, 1632 QDF_MAC_ADDR_SIZE); 1633 1634 if (curr_cfg->valid_bw_mask) 1635 glbl_cfg->bw = curr_cfg->bw; 1636 1637 if (curr_cfg->valid_nss_mask) 1638 glbl_cfg->nss = curr_cfg->nss; 1639 1640 if (curr_cfg->valid_mgmt_subtype) 1641 glbl_cfg->mgmt_subtype_filter = 1642 curr_cfg->mgmt_subtype_filter; 1643 1644 if (curr_cfg->valid_ctrl_subtype) 1645 glbl_cfg->ctrl_subtype_filter = 1646 curr_cfg->ctrl_subtype_filter; 1647 1648 if (curr_cfg->valid_data_subtype) 1649 glbl_cfg->data_subtype_filter = 1650 curr_cfg->data_subtype_filter; 1651 } 1652 } 1653 } 1654 1655 /** 1656 * cfr_enh_init_pdev() - Inits cfr pdev and registers necessary handlers. 1657 * @psoc: pointer to psoc object 1658 * @pdev: pointer to pdev object 1659 * 1660 * Return: Registration status for necessary handlers 1661 */ 1662 QDF_STATUS cfr_enh_init_pdev(struct wlan_objmgr_psoc *psoc, 1663 struct wlan_objmgr_pdev *pdev) 1664 { 1665 QDF_STATUS status = QDF_STATUS_SUCCESS; 1666 struct pdev_cfr *pcfr; 1667 uint32_t target_type; 1668 struct psoc_cfr *cfr_sc; 1669 1670 if (!pdev) { 1671 cfr_err("PDEV is NULL!"); 1672 return QDF_STATUS_E_NULL_VALUE; 1673 } 1674 1675 if (!psoc) { 1676 cfr_err("PSOC is NULL"); 1677 return QDF_STATUS_E_NULL_VALUE; 1678 } 1679 1680 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1681 WLAN_UMAC_COMP_CFR); 1682 if (!pcfr) { 1683 cfr_err("pcfr is NULL!"); 1684 return QDF_STATUS_E_NULL_VALUE; 1685 } 1686 1687 cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc, 1688 WLAN_UMAC_COMP_CFR); 1689 1690 if (!cfr_sc) { 1691 cfr_err("cfr_sc is NULL"); 1692 return QDF_STATUS_E_NULL_VALUE; 1693 } 1694 1695 target_type = target_if_cfr_get_target_type(psoc); 1696 1697 #if DIRECT_BUF_RX_ENABLE 1698 status = target_if_register_to_dbr_enh(pdev); 1699 if (status != QDF_STATUS_SUCCESS) { 1700 cfr_err("Failed to register with dbr"); 1701 return status; 1702 } 1703 #endif 1704 1705 status = target_if_register_tx_completion_enh_event_handler(psoc); 1706 if (status != QDF_STATUS_SUCCESS) { 1707 cfr_err("Failed to register with tx event handler"); 1708 return status; 1709 } 1710 1711 pcfr->is_cfr_rcc_capable = 1; 1712 pcfr->rcc_param.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 1713 pcfr->rcc_param.modified_in_curr_session = MAX_RESET_CFG_ENTRY; 1714 pcfr->rcc_param.num_grp_tlvs = MAX_TA_RA_ENTRIES; 1715 pcfr->rcc_param.vdev_id = CFR_INVALID_VDEV_ID; 1716 pcfr->rcc_param.srng_id = DEFAULT_SRNGID_CFR; 1717 pcfr->is_cap_interval_mode_sel_support = 1718 cfr_sc->is_cap_interval_mode_sel_support; 1719 pcfr->is_mo_marking_support = cfr_sc->is_mo_marking_support; 1720 1721 target_if_cfr_default_ta_ra_config(&pcfr->rcc_param, 1722 true, MAX_RESET_CFG_ENTRY); 1723 1724 status = target_if_cfr_config_rcc(pdev, &pcfr->rcc_param); 1725 if (status == QDF_STATUS_SUCCESS) { 1726 /* Update global configuration */ 1727 target_if_cfr_update_global_cfg(pdev); 1728 } else { 1729 cfr_err("Sending WMI to configure default has failed\n"); 1730 return status; 1731 } 1732 1733 pcfr->rcc_param.modified_in_curr_session = 0; 1734 1735 pcfr->cfr_max_sta_count = MAX_CFR_ENABLED_CLIENTS; 1736 1737 if (target_type == TARGET_TYPE_QCN9000) { 1738 pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_PINE; 1739 pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_PINE; 1740 pcfr->chip_type = CFR_CAPTURE_RADIO_PINE; 1741 pcfr->max_mu_users = PINE_CFR_MU_USERS; 1742 } else { 1743 pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_CYP; 1744 pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_CYP; 1745 pcfr->chip_type = CFR_CAPTURE_RADIO_CYP; 1746 pcfr->max_mu_users = CYP_CFR_MU_USERS; 1747 } 1748 1749 if (!pcfr->lut_timer_init) { 1750 qdf_timer_init(NULL, 1751 &(pcfr->lut_age_timer), 1752 lut_ageout_timer_task, (void *)pcfr, 1753 QDF_TIMER_TYPE_WAKE_APPS); 1754 pcfr->lut_timer_init = 1; 1755 } 1756 1757 qdf_spinlock_create(&pcfr->lut_lock); 1758 1759 return status; 1760 } 1761 1762 /** 1763 * cfr_enh_deinit_pdev() - De-inits corresponding pdev and handlers. 1764 * @psoc: pointer to psoc object 1765 * @pdev: pointer to pdev object 1766 * 1767 * Return: De-registration status for necessary handlers 1768 */ 1769 QDF_STATUS cfr_enh_deinit_pdev(struct wlan_objmgr_psoc *psoc, 1770 struct wlan_objmgr_pdev *pdev) 1771 { 1772 int status; 1773 struct pdev_cfr *pcfr; 1774 1775 pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, 1776 WLAN_UMAC_COMP_CFR); 1777 if (!pcfr) { 1778 cfr_err("pcfr is NULL"); 1779 return -EINVAL; 1780 } 1781 1782 if (pcfr->lut_timer_init) { 1783 qdf_timer_stop(&pcfr->lut_age_timer); 1784 qdf_timer_free(&(pcfr->lut_age_timer)); 1785 pcfr->lut_timer_init = 0; 1786 } 1787 1788 pcfr->tx_evt_cnt = 0; 1789 pcfr->dbr_evt_cnt = 0; 1790 pcfr->release_cnt = 0; 1791 pcfr->total_tx_evt_cnt = 0; 1792 pcfr->rx_tlv_evt_cnt = 0; 1793 pcfr->flush_dbr_cnt = 0; 1794 pcfr->flush_timeout_dbr_cnt = 0; 1795 pcfr->invalid_dma_length_cnt = 0; 1796 pcfr->clear_txrx_event = 0; 1797 pcfr->cfr_dma_aborts = 0; 1798 pcfr->tx_peer_status_cfr_fail = 0; 1799 pcfr->tx_evt_status_cfr_fail = 0; 1800 pcfr->tx_dbr_cookie_lookup_fail = 0; 1801 qdf_mem_zero(&pcfr->rcc_param, sizeof(struct cfr_rcc_param)); 1802 qdf_mem_zero(&pcfr->global, (sizeof(struct ta_ra_cfr_cfg) * 1803 MAX_TA_RA_ENTRIES)); 1804 pcfr->cfr_timer_enable = 0; 1805 1806 #ifdef DIRECT_BUF_RX_ENABLE 1807 status = target_if_unregister_to_dbr_enh(pdev); 1808 if (status != QDF_STATUS_SUCCESS) 1809 cfr_err("Failed to register with dbr"); 1810 #endif 1811 1812 status = target_if_unregister_tx_completion_enh_event_handler(psoc); 1813 if (status != QDF_STATUS_SUCCESS) 1814 cfr_err("Failed to register with dbr"); 1815 1816 qdf_spinlock_destroy(&pcfr->lut_lock); 1817 1818 return status; 1819 } 1820