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