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