1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2007 - 2016 Realtek Corporation.
7 * wlanfae <wlanfae@realtek.com>
8 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
11 * Larry Finger <Larry.Finger@lwfinger.net>
13 *****************************************************************************/
15 /* ************************************************************
17 * *************************************************************/
19 #include "mp_precomp.h"
20 #include "phydm_precomp.h"
22 #define READ_AND_CONFIG_MP(ic, txt) (odm_read_and_config_mp_##ic##txt(dm))
23 #define READ_AND_CONFIG_TC(ic, txt) (odm_read_and_config_tc_##ic##txt(dm))
25 #define READ_AND_CONFIG READ_AND_CONFIG_MP
27 #define READ_FIRMWARE_MP(ic, txt) \
28 (odm_read_firmware_mp_##ic##txt(dm, p_firmware, size))
29 #define READ_FIRMWARE_TC(ic, txt) \
30 (odm_read_firmware_tc_##ic##txt(dm, p_firmware, size))
32 #define READ_FIRMWARE READ_FIRMWARE_MP
34 #define GET_VERSION_MP(ic, txt) (odm_get_version_mp_##ic##txt())
35 #define GET_VERSION_TC(ic, txt) (odm_get_version_tc_##ic##txt())
37 #define GET_VERSION(ic, txt) GET_VERSION_MP(ic, txt)
39 static u32 phydm_process_rssi_pwdb(struct phy_dm_struct *dm,
40 struct rtl_sta_info *entry,
41 struct dm_per_pkt_info *pktinfo,
42 u32 undecorated_smoothed_ofdm,
43 u32 undecorated_smoothed_cck)
45 u32 weighting = 0, undecorated_smoothed_pwdb;
46 /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */
48 if (entry->rssi_stat.ofdm_pkt == 64) {
49 /* speed up when all packets are OFDM */
50 undecorated_smoothed_pwdb = undecorated_smoothed_ofdm;
51 ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
52 "PWDB_0[%d] = (( %d ))\n", pktinfo->station_id,
53 undecorated_smoothed_cck);
55 if (entry->rssi_stat.valid_bit < 64)
56 entry->rssi_stat.valid_bit++;
58 if (entry->rssi_stat.valid_bit == 64) {
59 weighting = ((entry->rssi_stat.ofdm_pkt) > 4) ?
61 (entry->rssi_stat.ofdm_pkt << 4);
62 undecorated_smoothed_pwdb =
63 (weighting * undecorated_smoothed_ofdm +
64 (64 - weighting) * undecorated_smoothed_cck) >>
66 ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
67 "PWDB_1[%d] = (( %d )), W = (( %d ))\n",
69 undecorated_smoothed_cck, weighting);
71 if (entry->rssi_stat.valid_bit != 0)
72 undecorated_smoothed_pwdb =
73 (entry->rssi_stat.ofdm_pkt *
74 undecorated_smoothed_ofdm +
75 (entry->rssi_stat.valid_bit -
76 entry->rssi_stat.ofdm_pkt) *
77 undecorated_smoothed_cck) /
78 entry->rssi_stat.valid_bit;
80 undecorated_smoothed_pwdb = 0;
83 dm, ODM_COMP_RSSI_MONITOR,
84 "PWDB_2[%d] = (( %d )), ofdm_pkt = (( %d )), Valid_Bit = (( %d ))\n",
85 pktinfo->station_id, undecorated_smoothed_cck,
86 entry->rssi_stat.ofdm_pkt,
87 entry->rssi_stat.valid_bit);
91 return undecorated_smoothed_pwdb;
94 static u32 phydm_process_rssi_cck(struct phy_dm_struct *dm,
95 struct dm_phy_status_info *phy_info,
96 struct rtl_sta_info *entry,
97 u32 undecorated_smoothed_cck)
102 rssi_ave = phy_info->rx_pwdb_all;
103 dm->rssi_a = (u8)phy_info->rx_pwdb_all;
108 if (entry->rssi_stat.cck_pkt <= 63)
109 entry->rssi_stat.cck_pkt++;
111 /* 1 Process CCK RSSI */
112 if (undecorated_smoothed_cck <= 0) { /* initialize */
113 undecorated_smoothed_cck = phy_info->rx_pwdb_all;
114 entry->rssi_stat.cck_sum_power =
115 (u16)phy_info->rx_pwdb_all; /*reset*/
116 entry->rssi_stat.cck_pkt = 1; /*reset*/
117 ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, "CCK_INIT: (( %d ))\n",
118 undecorated_smoothed_cck);
119 } else if (entry->rssi_stat.cck_pkt <= CCK_RSSI_INIT_COUNT) {
120 entry->rssi_stat.cck_sum_power =
121 entry->rssi_stat.cck_sum_power +
122 (u16)phy_info->rx_pwdb_all;
123 undecorated_smoothed_cck = entry->rssi_stat.cck_sum_power /
124 entry->rssi_stat.cck_pkt;
127 dm, ODM_COMP_RSSI_MONITOR,
128 "CCK_0: (( %d )), SumPow = (( %d )), cck_pkt = (( %d ))\n",
129 undecorated_smoothed_cck,
130 entry->rssi_stat.cck_sum_power,
131 entry->rssi_stat.cck_pkt);
133 if (phy_info->rx_pwdb_all > (u32)undecorated_smoothed_cck) {
134 undecorated_smoothed_cck =
135 (((undecorated_smoothed_cck) *
136 (RX_SMOOTH_FACTOR - 1)) +
137 (phy_info->rx_pwdb_all)) /
139 undecorated_smoothed_cck = undecorated_smoothed_cck + 1;
140 ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
142 undecorated_smoothed_cck);
144 undecorated_smoothed_cck =
145 (((undecorated_smoothed_cck) *
146 (RX_SMOOTH_FACTOR - 1)) +
147 (phy_info->rx_pwdb_all)) /
149 ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
151 undecorated_smoothed_cck);
156 entry->rssi_stat.ofdm_pkt -=
157 (u8)((entry->rssi_stat.packet_map >> i) & BIT(0));
158 entry->rssi_stat.packet_map = entry->rssi_stat.packet_map << 1;
159 return undecorated_smoothed_cck;
162 static u32 phydm_process_rssi_ofdm(struct phy_dm_struct *dm,
163 struct dm_phy_status_info *phy_info,
164 struct rtl_sta_info *entry,
165 u32 undecorated_smoothed_ofdm)
168 u8 rssi_max, rssi_min, i;
170 if (dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B)) {
174 if (dm->rx_ant_status & ODM_RF_A) {
175 dm->rssi_a = phy_info->rx_mimo_signal_strength
178 rssi_linear += odm_convert_to_linear(
179 phy_info->rx_mimo_signal_strength
185 if (dm->rx_ant_status & ODM_RF_B) {
186 dm->rssi_b = phy_info->rx_mimo_signal_strength
189 rssi_linear += odm_convert_to_linear(
190 phy_info->rx_mimo_signal_strength
196 if (dm->rx_ant_status & ODM_RF_C) {
197 dm->rssi_c = phy_info->rx_mimo_signal_strength
200 rssi_linear += odm_convert_to_linear(
201 phy_info->rx_mimo_signal_strength
207 if (dm->rx_ant_status & ODM_RF_D) {
208 dm->rssi_d = phy_info->rx_mimo_signal_strength
211 rssi_linear += odm_convert_to_linear(
212 phy_info->rx_mimo_signal_strength
218 /* Calculate average RSSI */
221 rssi_linear = (rssi_linear >> 1);
224 /* rssi_linear/3 ~ rssi_linear*11/32 */
225 rssi_linear = ((rssi_linear) + (rssi_linear << 1) +
226 (rssi_linear << 3)) >>
230 rssi_linear = (rssi_linear >> 2);
234 rssi_ave = odm_convert_to_db(rssi_linear);
236 if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B] == 0) {
237 rssi_ave = phy_info->rx_mimo_signal_strength
239 dm->rssi_a = phy_info->rx_mimo_signal_strength
243 dm->rssi_a = phy_info->rx_mimo_signal_strength
245 dm->rssi_b = phy_info->rx_mimo_signal_strength
248 if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] >
249 phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) {
250 rssi_max = phy_info->rx_mimo_signal_strength
252 rssi_min = phy_info->rx_mimo_signal_strength
255 rssi_max = phy_info->rx_mimo_signal_strength
257 rssi_min = phy_info->rx_mimo_signal_strength
260 if ((rssi_max - rssi_min) < 3)
262 else if ((rssi_max - rssi_min) < 6)
263 rssi_ave = rssi_max - 1;
264 else if ((rssi_max - rssi_min) < 10)
265 rssi_ave = rssi_max - 2;
267 rssi_ave = rssi_max - 3;
271 /* 1 Process OFDM RSSI */
272 if (undecorated_smoothed_ofdm <= 0) { /* initialize */
273 undecorated_smoothed_ofdm = phy_info->rx_pwdb_all;
274 ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, "OFDM_INIT: (( %d ))\n",
275 undecorated_smoothed_ofdm);
277 if (phy_info->rx_pwdb_all > (u32)undecorated_smoothed_ofdm) {
278 undecorated_smoothed_ofdm =
279 (((undecorated_smoothed_ofdm) *
280 (RX_SMOOTH_FACTOR - 1)) +
283 undecorated_smoothed_ofdm =
284 undecorated_smoothed_ofdm + 1;
285 ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
286 "OFDM_1: (( %d ))\n",
287 undecorated_smoothed_ofdm);
289 undecorated_smoothed_ofdm =
290 (((undecorated_smoothed_ofdm) *
291 (RX_SMOOTH_FACTOR - 1)) +
294 ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
295 "OFDM_2: (( %d ))\n",
296 undecorated_smoothed_ofdm);
300 if (entry->rssi_stat.ofdm_pkt != 64) {
302 entry->rssi_stat.ofdm_pkt -=
303 (u8)(((entry->rssi_stat.packet_map >> i) & BIT(0)) - 1);
306 entry->rssi_stat.packet_map =
307 (entry->rssi_stat.packet_map << 1) | BIT(0);
308 return undecorated_smoothed_ofdm;
311 static u8 odm_evm_db_to_percentage(s8);
312 static u8 odm_evm_dbm_jaguar_series(s8);
314 static inline u32 phydm_get_rssi_average(struct phy_dm_struct *dm,
315 struct dm_phy_status_info *phy_info)
317 u8 rssi_max = 0, rssi_min = 0;
319 dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
320 dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
322 if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] >
323 phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) {
324 rssi_max = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
325 rssi_min = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
327 rssi_max = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
328 rssi_min = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
330 if ((rssi_max - rssi_min) < 3)
332 else if ((rssi_max - rssi_min) < 6)
334 else if ((rssi_max - rssi_min) < 10)
340 static inline u8 phydm_get_evm_dbm(u8 i, u8 EVM,
341 struct phy_status_rpt_8812 *phy_sta_rpt,
342 struct dm_phy_status_info *phy_info)
344 if (i < ODM_RF_PATH_C)
345 return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm[i]);
347 return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm_cd[i - 2]);
348 /*RT_DISP(FRX, RX_PHY_SQ, ("RXRATE=%x RXEVM=%x EVM=%s%d\n",*/
349 /*pktinfo->data_rate, phy_sta_rpt->rxevm[i], "%", EVM));*/
352 static inline u8 phydm_get_odm_evm(u8 i, struct dm_per_pkt_info *pktinfo,
353 struct phy_status_rpt_8812 *phy_sta_rpt)
357 if (pktinfo->data_rate >= ODM_RATE6M &&
358 pktinfo->data_rate <= ODM_RATE54M) {
359 if (i == ODM_RF_PATH_A) {
360 evm = odm_evm_db_to_percentage(
361 (phy_sta_rpt->sigevm)); /*dbm*/
367 if (i < ODM_RF_PATH_C) {
368 if (phy_sta_rpt->rxevm[i] == -128)
369 phy_sta_rpt->rxevm[i] = -25;
370 evm = odm_evm_db_to_percentage(
371 (phy_sta_rpt->rxevm[i])); /*dbm*/
373 if (phy_sta_rpt->rxevm_cd[i - 2] == -128)
374 phy_sta_rpt->rxevm_cd[i - 2] = -25;
375 evm = odm_evm_db_to_percentage(
376 (phy_sta_rpt->rxevm_cd[i - 2])); /*dbm*/
383 static inline s8 phydm_get_rx_pwr(u8 LNA_idx, u8 VGA_idx, u8 cck_highpwr)
388 return -100 + 2 * (27 - VGA_idx); /*VGA_idx = 27~2*/
393 return -48 + 2 * (2 - VGA_idx); /*VGA_idx = 2~0*/
395 return -42 + 2 * (7 - VGA_idx); /*VGA_idx = 7~5*/
397 return -36 + 2 * (7 - VGA_idx); /*VGA_idx = 7~4*/
399 return -24 + 2 * (7 - VGA_idx); /*VGA_idx = 7~0*/
402 return -12 + 2 * (5 - VGA_idx); /*VGA_idx = 5~0*/
404 return -6 + 2 * (5 - VGA_idx);
407 return 8 - 2 * VGA_idx;
409 return 14 - 2 * VGA_idx;
416 static inline u8 phydm_adjust_pwdb(u8 cck_highpwr, u8 pwdb_all)
420 return ((pwdb_all - 80) << 1) + ((pwdb_all - 80) >> 1) +
422 else if ((pwdb_all <= 78) && (pwdb_all >= 20))
431 phydm_get_signal_quality_8812(struct dm_phy_status_info *phy_info,
432 struct phy_dm_struct *dm,
433 struct phy_status_rpt_8812 *phy_sta_rpt)
437 if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test)
440 sq_rpt = phy_sta_rpt->pwdb_all;
444 else if (sq_rpt < 20)
447 return ((64 - sq_rpt) * 100) / 44;
451 phydm_get_signal_quality_8192(struct dm_phy_status_info *phy_info,
452 struct phy_dm_struct *dm,
453 struct phy_status_rpt_8192cd *phy_sta_rpt)
457 if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test)
460 sq_rpt = phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all;
464 else if (sq_rpt < 20)
467 return ((64 - sq_rpt) * 100) / 44;
470 static u8 odm_query_rx_pwr_percentage(s8 ant_power)
472 if ((ant_power <= -100) || (ant_power >= 20))
474 else if (ant_power >= 0)
477 return 100 + ant_power;
480 static u8 odm_evm_db_to_percentage(s8 value)
482 /* -33dB~0dB to 0%~99% */
494 ret_val = 0 - ret_val;
503 static u8 odm_evm_dbm_jaguar_series(s8 value)
507 /* -33dB~0dB to 33dB ~ 0dB */
510 else if (ret_val < 0)
511 ret_val = 0 - ret_val;
513 ret_val = ret_val >> 1;
517 static s16 odm_cfo(s8 value)
523 ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */
525 ret_val | BIT(12); /* set bit12 as 1 for negative cfo */
528 ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */
533 static u8 phydm_rate_to_num_ss(struct phy_dm_struct *dm, u8 data_rate)
537 if (data_rate <= ODM_RATE54M)
539 else if (data_rate <= ODM_RATEMCS31)
540 num_ss = ((data_rate - ODM_RATEMCS0) >> 3) + 1;
541 else if (data_rate <= ODM_RATEVHTSS1MCS9)
543 else if (data_rate <= ODM_RATEVHTSS2MCS9)
545 else if (data_rate <= ODM_RATEVHTSS3MCS9)
547 else if (data_rate <= ODM_RATEVHTSS4MCS9)
553 static void odm_rx_phy_status92c_series_parsing(
554 struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
555 u8 *phy_status, struct dm_per_pkt_info *pktinfo)
557 u8 i, max_spatial_stream;
558 s8 rx_pwr[4], rx_pwr_all = 0;
559 u8 EVM, pwdb_all = 0, pwdb_all_bt;
560 u8 RSSI, total_rssi = 0;
561 bool is_cck_rate = false;
567 struct phy_status_rpt_8192cd *phy_sta_rpt =
568 (struct phy_status_rpt_8192cd *)phy_status;
570 is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false;
572 if (pktinfo->is_to_self)
573 dm->curr_station_id = pktinfo->station_id;
575 phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1;
576 phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
579 dm->phy_dbg_info.num_qry_phy_status_cck++;
580 cck_agc_rpt = phy_sta_rpt->cck_agc_rpt_ofdm_cfosho_a;
582 if (dm->support_ic_type & (ODM_RTL8703B)) {
583 } else { /*3 bit LNA*/
585 LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
586 VGA_idx = (cck_agc_rpt & 0x1F);
590 dm, ODM_COMP_RSSI_MONITOR,
591 "ext_lna_gain (( %d )), LNA_idx: (( 0x%x )), VGA_idx: (( 0x%x )), rx_pwr_all: (( %d ))\n",
592 dm->ext_lna_gain, LNA_idx, VGA_idx, rx_pwr_all);
594 if (dm->board_type & ODM_BOARD_EXT_LNA)
595 rx_pwr_all -= dm->ext_lna_gain;
597 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
599 if (pktinfo->is_to_self) {
600 dm->cck_lna_idx = LNA_idx;
601 dm->cck_vga_idx = VGA_idx;
603 phy_info->rx_pwdb_all = pwdb_all;
605 phy_info->bt_rx_rssi_percentage = pwdb_all;
606 phy_info->recv_signal_power = rx_pwr_all;
607 /* (3) Get Signal Quality (EVM) */
611 sq = phydm_get_signal_quality_8192(phy_info, dm,
613 phy_info->signal_quality = sq;
614 phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq;
615 phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
618 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) {
620 phy_info->rx_mimo_signal_strength[0] = pwdb_all;
622 phy_info->rx_mimo_signal_strength[1] = 0;
624 } else { /* 2 is OFDM rate */
625 dm->phy_dbg_info.num_qry_phy_status_ofdm++;
628 /* (1)Get RSSI for HT rate */
631 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) {
632 /* 2008/01/30 MH we will judge RF RX path now. */
633 if (dm->rf_path_rx_enable & BIT(i))
639 ((phy_sta_rpt->path_agc[i].gain & 0x3F) * 2) -
642 if (pktinfo->is_to_self) {
643 dm->ofdm_agc_idx[i] =
644 (phy_sta_rpt->path_agc[i].gain & 0x3F);
648 phy_info->rx_pwr[i] = rx_pwr[i];
650 /* Translate DBM to percentage. */
651 RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]);
654 phy_info->rx_mimo_signal_strength[i] = (u8)RSSI;
656 /* Get Rx snr value in DB */
657 dm->phy_dbg_info.rx_snr_db[i] =
658 (s32)(phy_sta_rpt->path_rxsnr[i] / 2);
659 phy_info->rx_snr[i] = dm->phy_dbg_info.rx_snr_db[i];
661 /* Record Signal Strength for next packet */
662 /* if(pktinfo->is_packet_match_bssid) */
668 /* (2)PWDB, Average PWDB calcuated by hardware (for RA) */
670 rx_pwr_all = (((phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all) >> 1) &
674 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
675 pwdb_all_bt = pwdb_all;
677 phy_info->rx_pwdb_all = pwdb_all;
678 phy_info->bt_rx_rssi_percentage = pwdb_all_bt;
679 phy_info->rx_power = rx_pwr_all;
680 phy_info->recv_signal_power = rx_pwr_all;
682 if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) {
684 } else if ((dm->support_platform == ODM_WIN) &&
685 (dm->patch_id == 25)) {
687 } else { /* mgnt_info->customer_id != RT_CID_819X_LENOVO */
689 /* (3)EVM of HT rate */
691 if (pktinfo->data_rate >= ODM_RATEMCS8 &&
692 pktinfo->data_rate <= ODM_RATEMCS15) {
693 /* both spatial stream make sense */
694 max_spatial_stream = 2;
696 /* only spatial stream 1 makes sense */
697 max_spatial_stream = 1;
700 for (i = 0; i < max_spatial_stream; i++) {
701 /*Don't use shift operation like "rx_evmX >>= 1"
702 *because the compilor of free build environment
703 *fill most significant bit to "zero" when doing
704 *shifting operation which may change a negative
705 *value to positive one, then the dbm value
706 *(which is supposed to be negative) is not
709 EVM = odm_evm_db_to_percentage(
711 ->stream_rxevm[i])); /* dbm */
713 /* Fill value in RFD, Get the first spatial
716 if (i == ODM_RF_PATH_A)
717 phy_info->signal_quality =
719 phy_info->rx_mimo_signal_quality[i] =
724 num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
725 odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->path_cfotail, num_ss);
727 /* UI BSS List signal strength(in percentage), make it good looking,
730 /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */
732 phy_info->signal_strength = pwdb_all;
733 else if (rf_rx_num != 0)
734 phy_info->signal_strength = (total_rssi /= rf_rx_num);
736 /* For 92C/92D HW (Hybrid) Antenna Diversity */
740 odm_rx_phy_bw_jaguar_series_parsing(struct dm_phy_status_info *phy_info,
741 struct dm_per_pkt_info *pktinfo,
742 struct phy_status_rpt_8812 *phy_sta_rpt)
744 if (pktinfo->data_rate <= ODM_RATE54M) {
745 switch (phy_sta_rpt->r_RFMOD) {
747 if (phy_sta_rpt->sub_chnl == 0)
748 phy_info->band_width = 1;
750 phy_info->band_width = 0;
754 if (phy_sta_rpt->sub_chnl == 0)
755 phy_info->band_width = 2;
756 else if (phy_sta_rpt->sub_chnl == 9 ||
757 phy_sta_rpt->sub_chnl == 10)
758 phy_info->band_width = 1;
760 phy_info->band_width = 0;
765 phy_info->band_width = 0;
771 static void odm_rx_phy_status_jaguar_series_parsing(
772 struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
773 u8 *phy_status, struct dm_per_pkt_info *pktinfo)
775 u8 i, max_spatial_stream;
776 s8 rx_pwr[4], rx_pwr_all = 0;
777 u8 EVM = 0, evm_dbm, pwdb_all = 0, pwdb_all_bt;
778 u8 RSSI, avg_rssi = 0, best_rssi = 0, second_rssi = 0;
783 struct phy_status_rpt_8812 *phy_sta_rpt =
784 (struct phy_status_rpt_8812 *)phy_status;
785 struct fast_antenna_training *fat_tab = &dm->dm_fat_table;
788 odm_rx_phy_bw_jaguar_series_parsing(phy_info, pktinfo, phy_sta_rpt);
790 if (pktinfo->data_rate <= ODM_RATE11M)
795 if (pktinfo->is_to_self)
796 dm->curr_station_id = pktinfo->station_id;
798 dm->curr_station_id = 0xff;
800 phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1;
801 phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
802 phy_info->rx_mimo_signal_quality[ODM_RF_PATH_C] = -1;
803 phy_info->rx_mimo_signal_quality[ODM_RF_PATH_D] = -1;
808 dm->phy_dbg_info.num_qry_phy_status_cck++;
810 /*(1)Hardware does not provide RSSI for CCK*/
811 /*(2)PWDB, Average PWDB calculated by hardware (for RA)*/
813 cck_highpwr = dm->is_cck_high_power;
815 cck_agc_rpt = phy_sta_rpt->cfosho[0];
816 LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
817 VGA_idx = (cck_agc_rpt & 0x1F);
819 if (dm->support_ic_type == ODM_RTL8812) {
821 phydm_get_rx_pwr(LNA_idx, VGA_idx, cck_highpwr);
823 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
824 pwdb_all = phydm_adjust_pwdb(cck_highpwr, pwdb_all);
826 } else if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
831 rx_pwr_all = pout - 32 - (2 * VGA_idx);
834 rx_pwr_all = pout - 24 - (2 * VGA_idx);
837 rx_pwr_all = pout - 11 - (2 * VGA_idx);
840 rx_pwr_all = pout + 5 - (2 * VGA_idx);
843 rx_pwr_all = pout + 21 - (2 * VGA_idx);
846 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
847 } else if (dm->support_ic_type == ODM_RTL8814A ||
848 dm->support_ic_type == ODM_RTL8822B) {
852 /*CCK only use LNA: 2, 3, 5, 7*/
854 rx_pwr_all = pout - 32 - (2 * VGA_idx);
857 rx_pwr_all = pout - 22 - (2 * VGA_idx);
860 rx_pwr_all = pout - 2 - (2 * VGA_idx);
863 rx_pwr_all = pout + 5 - (2 * VGA_idx);
868 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
871 dm->cck_lna_idx = LNA_idx;
872 dm->cck_vga_idx = VGA_idx;
873 phy_info->rx_pwdb_all = pwdb_all;
874 phy_info->bt_rx_rssi_percentage = pwdb_all;
875 phy_info->recv_signal_power = rx_pwr_all;
876 /*(3) Get Signal Quality (EVM)*/
880 if (!(dm->support_platform == ODM_WIN &&
881 dm->patch_id == RT_CID_819X_LENOVO))
882 sq = phydm_get_signal_quality_8812(phy_info, dm,
885 phy_info->signal_quality = sq;
886 phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq;
889 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
891 phy_info->rx_mimo_signal_strength[0] = pwdb_all;
893 phy_info->rx_mimo_signal_strength[i] = 0;
897 fat_tab->hw_antsw_occur = phy_sta_rpt->hw_antsw_occur;
899 dm->phy_dbg_info.num_qry_phy_status_ofdm++;
901 /*(1)Get RSSI for OFDM rate*/
903 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
904 /*2008/01/30 MH we will judge RF RX path now.*/
905 if (dm->rf_path_rx_enable & BIT(i))
907 /*2012.05.25 LukeLee: Testchip AGC report is wrong,
908 *it should be restored back to old formula in MP chip
910 if (i < ODM_RF_PATH_C)
911 rx_pwr[i] = (phy_sta_rpt->gain_trsw[i] & 0x7F) -
914 rx_pwr[i] = (phy_sta_rpt->gain_trsw_cd[i - 2] &
918 phy_info->rx_pwr[i] = rx_pwr[i];
920 /* Translate DBM to percentage. */
921 RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]);
923 /*total_rssi += RSSI;*/
924 /*Get the best two RSSI*/
925 if (RSSI > best_rssi && RSSI > second_rssi) {
926 second_rssi = best_rssi;
928 } else if (RSSI > second_rssi && RSSI <= best_rssi) {
932 phy_info->rx_mimo_signal_strength[i] = (u8)RSSI;
934 /*Get Rx snr value in DB*/
935 if (i < ODM_RF_PATH_C)
936 phy_info->rx_snr[i] =
937 dm->phy_dbg_info.rx_snr_db[i] =
938 phy_sta_rpt->rxsnr[i] / 2;
939 else if (dm->support_ic_type &
940 (ODM_RTL8814A | ODM_RTL8822B))
941 phy_info->rx_snr[i] = dm->phy_dbg_info
943 phy_sta_rpt->csi_current[i - 2] / 2;
945 /*(2) CFO_short & CFO_tail*/
946 if (i < ODM_RF_PATH_C) {
947 phy_info->cfo_short[i] =
948 odm_cfo((phy_sta_rpt->cfosho[i]));
949 phy_info->cfo_tail[i] =
950 odm_cfo((phy_sta_rpt->cfotail[i]));
954 /*(3)PWDB, Average PWDB calculated by hardware (for RA)*/
956 /*2012.05.25 LukeLee: Testchip AGC report is wrong, it should be
957 *restored back to old formula in MP chip
959 if ((dm->support_ic_type &
960 (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) &&
962 rx_pwr_all = (phy_sta_rpt->pwdb_all & 0x7f) - 110;
964 rx_pwr_all = (((phy_sta_rpt->pwdb_all) >> 1) & 0x7f) -
967 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
968 pwdb_all_bt = pwdb_all;
970 phy_info->rx_pwdb_all = pwdb_all;
971 phy_info->bt_rx_rssi_percentage = pwdb_all_bt;
972 phy_info->rx_power = rx_pwr_all;
973 phy_info->recv_signal_power = rx_pwr_all;
975 if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) {
978 /*mgnt_info->customer_id != RT_CID_819X_LENOVO*/
980 /*(4)EVM of OFDM rate*/
982 if ((pktinfo->data_rate >= ODM_RATEMCS8) &&
983 (pktinfo->data_rate <= ODM_RATEMCS15))
984 max_spatial_stream = 2;
985 else if ((pktinfo->data_rate >= ODM_RATEVHTSS2MCS0) &&
986 (pktinfo->data_rate <= ODM_RATEVHTSS2MCS9))
987 max_spatial_stream = 2;
988 else if ((pktinfo->data_rate >= ODM_RATEMCS16) &&
989 (pktinfo->data_rate <= ODM_RATEMCS23))
990 max_spatial_stream = 3;
991 else if ((pktinfo->data_rate >= ODM_RATEVHTSS3MCS0) &&
992 (pktinfo->data_rate <= ODM_RATEVHTSS3MCS9))
993 max_spatial_stream = 3;
995 max_spatial_stream = 1;
997 for (i = 0; i < max_spatial_stream; i++) {
998 /*Don't use shift operation like "rx_evmX >>= 1"
999 *because the compilor of free build environment
1000 *fill most significant bit to "zero" when doing
1001 *shifting operation which may change a negative
1002 *value to positive one, then the dbm value
1003 *(which is supposed to be negative) is not
1007 EVM = phydm_get_odm_evm(i, pktinfo,
1009 evm_dbm = phydm_get_evm_dbm(i, EVM, phy_sta_rpt,
1011 phy_info->rx_mimo_signal_quality[i] = EVM;
1012 phy_info->rx_mimo_evm_dbm[i] = evm_dbm;
1016 num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
1017 odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfotail, num_ss);
1020 /*UI BSS List signal strength(in percentage), make it good looking,
1023 /*It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().*/
1025 phy_info->signal_strength = pwdb_all;
1026 } else if (rf_rx_num != 0) {
1027 /* 2015/01 Sean, use the best two RSSI only,
1028 * suggested by Ynlin and ChenYu.
1031 avg_rssi = best_rssi;
1033 avg_rssi = (best_rssi + second_rssi) / 2;
1035 phy_info->signal_strength = avg_rssi;
1038 dm->rx_pwdb_ave = dm->rx_pwdb_ave + phy_info->rx_pwdb_all;
1040 dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_anta;
1041 dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_antb;
1042 dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_antc;
1043 dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_antd;
1046 void phydm_reset_rssi_for_dm(struct phy_dm_struct *dm, u8 station_id)
1048 struct rtl_sta_info *entry;
1050 entry = dm->odm_sta_info[station_id];
1052 if (!IS_STA_VALID(entry))
1055 ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
1056 "Reset RSSI for macid = (( %d ))\n", station_id);
1058 entry->rssi_stat.undecorated_smoothed_cck = -1;
1059 entry->rssi_stat.undecorated_smoothed_ofdm = -1;
1060 entry->rssi_stat.undecorated_smoothed_pwdb = -1;
1061 entry->rssi_stat.ofdm_pkt = 0;
1062 entry->rssi_stat.cck_pkt = 0;
1063 entry->rssi_stat.cck_sum_power = 0;
1064 entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_INIT;
1065 entry->rssi_stat.packet_map = 0;
1066 entry->rssi_stat.valid_bit = 0;
1069 void odm_init_rssi_for_dm(struct phy_dm_struct *dm) {}
1071 static void odm_process_rssi_for_dm(struct phy_dm_struct *dm,
1072 struct dm_phy_status_info *phy_info,
1073 struct dm_per_pkt_info *pktinfo)
1075 s32 undecorated_smoothed_pwdb, undecorated_smoothed_cck,
1076 undecorated_smoothed_ofdm;
1078 u8 send_rssi_2_fw = 0;
1079 struct rtl_sta_info *entry;
1081 if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM)
1084 /* 2012/05/30 MH/Luke.Lee Add some description */
1085 /* In windows driver: AP/IBSS mode STA */
1086 entry = dm->odm_sta_info[pktinfo->station_id];
1088 if (!IS_STA_VALID(entry))
1092 if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/
1096 if (pktinfo->is_packet_beacon)
1097 dm->phy_dbg_info.num_qry_beacon_pkt++;
1099 is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false;
1100 dm->rx_rate = pktinfo->data_rate;
1102 /* --------------Statistic for antenna/path diversity---------------- */
1104 /* -----------------Smart Antenna Debug Message------------------ */
1106 undecorated_smoothed_cck = entry->rssi_stat.undecorated_smoothed_cck;
1107 undecorated_smoothed_ofdm = entry->rssi_stat.undecorated_smoothed_ofdm;
1108 undecorated_smoothed_pwdb = entry->rssi_stat.undecorated_smoothed_pwdb;
1110 if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) {
1111 if (!is_cck_rate) /* ofdm rate */
1112 undecorated_smoothed_ofdm = phydm_process_rssi_ofdm(
1113 dm, phy_info, entry, undecorated_smoothed_ofdm);
1115 undecorated_smoothed_cck = phydm_process_rssi_cck(
1116 dm, phy_info, entry, undecorated_smoothed_cck);
1118 undecorated_smoothed_pwdb = phydm_process_rssi_pwdb(
1119 dm, entry, pktinfo, undecorated_smoothed_ofdm,
1120 undecorated_smoothed_cck);
1122 if ((entry->rssi_stat.ofdm_pkt >= 1 ||
1123 entry->rssi_stat.cck_pkt >= 5) &&
1124 (entry->rssi_stat.is_send_rssi == RA_RSSI_STATE_INIT)) {
1126 entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_SEND;
1129 entry->rssi_stat.undecorated_smoothed_cck =
1130 undecorated_smoothed_cck;
1131 entry->rssi_stat.undecorated_smoothed_ofdm =
1132 undecorated_smoothed_ofdm;
1133 entry->rssi_stat.undecorated_smoothed_pwdb =
1134 undecorated_smoothed_pwdb;
1136 if (send_rssi_2_fw) { /* Trigger init rate by RSSI */
1138 if (entry->rssi_stat.ofdm_pkt != 0)
1139 entry->rssi_stat.undecorated_smoothed_pwdb =
1140 undecorated_smoothed_ofdm;
1143 dm, ODM_COMP_RSSI_MONITOR,
1144 "[Send to FW] PWDB = (( %d )), ofdm_pkt = (( %d )), cck_pkt = (( %d ))\n",
1145 undecorated_smoothed_pwdb,
1146 entry->rssi_stat.ofdm_pkt,
1147 entry->rssi_stat.cck_pkt);
1153 * Endianness before calling this API
1155 static void odm_phy_status_query_92c_series(struct phy_dm_struct *dm,
1156 struct dm_phy_status_info *phy_info,
1158 struct dm_per_pkt_info *pktinfo)
1160 odm_rx_phy_status92c_series_parsing(dm, phy_info, phy_status, pktinfo);
1161 odm_process_rssi_for_dm(dm, phy_info, pktinfo);
1165 * Endianness before calling this API
1168 static void odm_phy_status_query_jaguar_series(
1169 struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
1170 u8 *phy_status, struct dm_per_pkt_info *pktinfo)
1172 odm_rx_phy_status_jaguar_series_parsing(dm, phy_info, phy_status,
1174 odm_process_rssi_for_dm(dm, phy_info, pktinfo);
1177 void odm_phy_status_query(struct phy_dm_struct *dm,
1178 struct dm_phy_status_info *phy_info, u8 *phy_status,
1179 struct dm_per_pkt_info *pktinfo)
1181 if (dm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE) {
1182 phydm_rx_phy_status_new_type(dm, phy_status, pktinfo, phy_info);
1186 if (dm->support_ic_type & ODM_IC_11AC_SERIES)
1187 odm_phy_status_query_jaguar_series(dm, phy_info, phy_status,
1190 if (dm->support_ic_type & ODM_IC_11N_SERIES)
1191 odm_phy_status_query_92c_series(dm, phy_info, phy_status,
1195 /* For future use. */
1196 void odm_mac_status_query(struct phy_dm_struct *dm, u8 *mac_status, u8 mac_id,
1197 bool is_packet_match_bssid, bool is_packet_to_self,
1198 bool is_packet_beacon)
1200 /* 2011/10/19 Driver team will handle in the future. */
1204 * If you want to add a new IC, Please follow below template and generate
1209 odm_config_rf_with_header_file(struct phy_dm_struct *dm,
1210 enum odm_rf_config_type config_type,
1211 enum odm_rf_radio_path e_rf_path)
1213 ODM_RT_TRACE(dm, ODM_COMP_INIT,
1214 "===>%s (%s)\n", __func__,
1215 (dm->is_mp_chip) ? "MPChip" : "TestChip");
1218 "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
1219 dm->support_platform, dm->support_interface, dm->board_type);
1221 /* 1 AP doesn't use PHYDM power tracking table in these ICs */
1222 /* JJ ADD 20161014 */
1224 /* 1 All platforms support */
1225 if (dm->support_ic_type == ODM_RTL8822B) {
1226 if (config_type == CONFIG_RF_RADIO) {
1227 if (e_rf_path == ODM_RF_PATH_A)
1228 READ_AND_CONFIG_MP(8822b, _radioa);
1229 else if (e_rf_path == ODM_RF_PATH_B)
1230 READ_AND_CONFIG_MP(8822b, _radiob);
1231 } else if (config_type == CONFIG_RF_TXPWR_LMT) {
1232 if (dm->rfe_type == 5)
1233 READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type5);
1235 READ_AND_CONFIG_MP(8822b, _txpwr_lmt);
1239 return HAL_STATUS_SUCCESS;
1243 odm_config_rf_with_tx_pwr_track_header_file(struct phy_dm_struct *dm)
1245 ODM_RT_TRACE(dm, ODM_COMP_INIT,
1246 "===>%s (%s)\n", __func__,
1247 (dm->is_mp_chip) ? "MPChip" : "TestChip");
1250 "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
1251 dm->support_platform, dm->support_interface, dm->board_type);
1253 /* 1 AP doesn't use PHYDM power tracking table in these ICs */
1254 /* JJ ADD 20161014 */
1256 /* 1 All platforms support */
1258 if (dm->support_ic_type == ODM_RTL8822B) {
1259 if (dm->rfe_type == 0)
1260 READ_AND_CONFIG_MP(8822b, _txpowertrack_type0);
1261 else if (dm->rfe_type == 1)
1262 READ_AND_CONFIG_MP(8822b, _txpowertrack_type1);
1263 else if (dm->rfe_type == 2)
1264 READ_AND_CONFIG_MP(8822b, _txpowertrack_type2);
1265 else if ((dm->rfe_type == 3) || (dm->rfe_type == 5))
1266 READ_AND_CONFIG_MP(8822b, _txpowertrack_type3_type5);
1267 else if (dm->rfe_type == 4)
1268 READ_AND_CONFIG_MP(8822b, _txpowertrack_type4);
1269 else if (dm->rfe_type == 6)
1270 READ_AND_CONFIG_MP(8822b, _txpowertrack_type6);
1271 else if (dm->rfe_type == 7)
1272 READ_AND_CONFIG_MP(8822b, _txpowertrack_type7);
1273 else if (dm->rfe_type == 8)
1274 READ_AND_CONFIG_MP(8822b, _txpowertrack_type8);
1275 else if (dm->rfe_type == 9)
1276 READ_AND_CONFIG_MP(8822b, _txpowertrack_type9);
1278 READ_AND_CONFIG_MP(8822b, _txpowertrack);
1281 return HAL_STATUS_SUCCESS;
1285 odm_config_bb_with_header_file(struct phy_dm_struct *dm,
1286 enum odm_bb_config_type config_type)
1288 /* 1 AP doesn't use PHYDM initialization in these ICs */
1289 /* JJ ADD 20161014 */
1291 /* 1 All platforms support */
1292 if (dm->support_ic_type == ODM_RTL8822B) {
1293 if (config_type == CONFIG_BB_PHY_REG)
1294 READ_AND_CONFIG_MP(8822b, _phy_reg);
1295 else if (config_type == CONFIG_BB_AGC_TAB)
1296 READ_AND_CONFIG_MP(8822b, _agc_tab);
1297 else if (config_type == CONFIG_BB_PHY_REG_PG)
1298 READ_AND_CONFIG_MP(8822b, _phy_reg_pg);
1299 /*else if (config_type == CONFIG_BB_PHY_REG_MP)*/
1300 /*READ_AND_CONFIG_MP(8822b, _phy_reg_mp);*/
1303 return HAL_STATUS_SUCCESS;
1306 enum hal_status odm_config_mac_with_header_file(struct phy_dm_struct *dm)
1308 ODM_RT_TRACE(dm, ODM_COMP_INIT,
1309 "===>%s (%s)\n", __func__,
1310 (dm->is_mp_chip) ? "MPChip" : "TestChip");
1313 "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
1314 dm->support_platform, dm->support_interface, dm->board_type);
1316 /* 1 AP doesn't use PHYDM initialization in these ICs */
1317 /* JJ ADD 20161014 */
1319 /* 1 All platforms support */
1320 if (dm->support_ic_type == ODM_RTL8822B)
1321 READ_AND_CONFIG_MP(8822b, _mac_reg);
1323 return HAL_STATUS_SUCCESS;
1327 odm_config_fw_with_header_file(struct phy_dm_struct *dm,
1328 enum odm_fw_config_type config_type,
1329 u8 *p_firmware, u32 *size)
1331 return HAL_STATUS_SUCCESS;
1334 u32 odm_get_hw_img_version(struct phy_dm_struct *dm)
1338 /* 1 AP doesn't use PHYDM initialization in these ICs */
1339 /* JJ ADD 20161014 */
1341 /*1 All platforms support*/
1342 if (dm->support_ic_type == ODM_RTL8822B)
1343 version = GET_VERSION_MP(8822b, _mac_reg);
1348 /* For 8822B only!! need to move to FW finally */
1349 /*==============================================*/
1351 bool phydm_query_is_mu_api(struct phy_dm_struct *phydm, u8 ppdu_idx,
1352 u8 *p_data_rate, u8 *p_gid)
1354 u8 data_rate = 0, gid = 0;
1357 data_rate = phydm->phy_dbg_info.num_of_ppdu[ppdu_idx];
1358 gid = phydm->phy_dbg_info.gid_num[ppdu_idx];
1360 if (data_rate & BIT(7)) {
1362 data_rate = data_rate & ~(BIT(7));
1367 *p_data_rate = data_rate;
1373 static void phydm_rx_statistic_cal(struct phy_dm_struct *phydm, u8 *phy_status,
1374 struct dm_per_pkt_info *pktinfo)
1376 struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt =
1377 (struct phy_status_rpt_jaguar2_type1 *)phy_status;
1378 u8 date_rate = pktinfo->data_rate & ~(BIT(7));
1380 if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) {
1381 if (date_rate >= ODM_RATEVHTSS1MCS0) {
1383 .num_qry_mu_vht_pkt[date_rate - 0x2C]++;
1384 phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] =
1386 phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] =
1391 if (date_rate >= ODM_RATEVHTSS1MCS0) {
1392 phydm->phy_dbg_info.num_qry_vht_pkt[date_rate - 0x2C]++;
1393 phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] =
1395 phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] =
1401 static void phydm_reset_phy_info(struct phy_dm_struct *phydm,
1402 struct dm_phy_status_info *phy_info)
1404 phy_info->rx_pwdb_all = 0;
1405 phy_info->signal_quality = 0;
1406 phy_info->band_width = 0;
1407 phy_info->rx_count = 0;
1408 odm_memory_set(phydm, phy_info->rx_mimo_signal_quality, 0, 4);
1409 odm_memory_set(phydm, phy_info->rx_mimo_signal_strength, 0, 4);
1410 odm_memory_set(phydm, phy_info->rx_snr, 0, 4);
1412 phy_info->rx_power = -110;
1413 phy_info->recv_signal_power = -110;
1414 phy_info->bt_rx_rssi_percentage = 0;
1415 phy_info->signal_strength = 0;
1416 phy_info->bt_coex_pwr_adjust = 0;
1417 phy_info->channel = 0;
1418 phy_info->is_mu_packet = 0;
1419 phy_info->is_beamformed = 0;
1421 odm_memory_set(phydm, phy_info->rx_pwr, -110, 4);
1422 odm_memory_set(phydm, phy_info->rx_mimo_evm_dbm, 0, 4);
1423 odm_memory_set(phydm, phy_info->cfo_short, 0, 8);
1424 odm_memory_set(phydm, phy_info->cfo_tail, 0, 8);
1427 static void phydm_set_per_path_phy_info(u8 rx_path, s8 rx_pwr, s8 rx_evm,
1428 s8 cfo_tail, s8 rx_snr,
1429 struct dm_phy_status_info *phy_info)
1432 u8 evm_percentage = 0;
1434 /* SNR is S(8,1), EVM is S(8,1), CFO is S(8,7) */
1437 /* Calculate EVM in dBm */
1438 evm_dbm = ((u8)(0 - rx_evm) >> 1);
1440 /* Calculate EVM in percentage */
1442 evm_percentage = 100;
1444 evm_percentage = (evm_dbm << 1) + (evm_dbm);
1447 phy_info->rx_pwr[rx_path] = rx_pwr;
1448 phy_info->rx_mimo_evm_dbm[rx_path] = evm_dbm;
1450 /* CFO = CFO_tail * 312.5 / 2^7 ~= CFO tail * 39/512 (kHz)*/
1451 phy_info->cfo_tail[rx_path] = cfo_tail;
1452 phy_info->cfo_tail[rx_path] = ((phy_info->cfo_tail[rx_path] << 5) +
1453 (phy_info->cfo_tail[rx_path] << 2) +
1454 (phy_info->cfo_tail[rx_path] << 1) +
1455 (phy_info->cfo_tail[rx_path])) >>
1458 phy_info->rx_mimo_signal_strength[rx_path] =
1459 odm_query_rx_pwr_percentage(rx_pwr);
1460 phy_info->rx_mimo_signal_quality[rx_path] = evm_percentage;
1461 phy_info->rx_snr[rx_path] = rx_snr >> 1;
1464 static void phydm_set_common_phy_info(s8 rx_power, u8 channel,
1465 bool is_beamformed, bool is_mu_packet,
1466 u8 bandwidth, u8 signal_quality, u8 rxsc,
1467 struct dm_phy_status_info *phy_info)
1469 phy_info->rx_power = rx_power; /* RSSI in dB */
1470 phy_info->recv_signal_power = rx_power; /* RSSI in dB */
1471 phy_info->channel = channel; /* channel number */
1472 phy_info->is_beamformed = is_beamformed; /* apply BF */
1473 phy_info->is_mu_packet = is_mu_packet; /* MU packet */
1474 phy_info->rxsc = rxsc;
1475 phy_info->rx_pwdb_all =
1476 odm_query_rx_pwr_percentage(rx_power); /* RSSI in percentage */
1477 phy_info->signal_quality = signal_quality; /* signal quality */
1478 phy_info->band_width = bandwidth; /* bandwidth */
1481 static void phydm_get_rx_phy_status_type0(struct phy_dm_struct *dm,
1483 struct dm_per_pkt_info *pktinfo,
1484 struct dm_phy_status_info *phy_info)
1486 /* type 0 is used for cck packet */
1488 struct phy_status_rpt_jaguar2_type0 *phy_sta_rpt =
1489 (struct phy_status_rpt_jaguar2_type0 *)phy_status;
1491 s8 rx_power = phy_sta_rpt->pwdb - 110;
1493 /* JJ ADD 20161014 */
1495 /* Calculate Signal Quality*/
1496 if (pktinfo->is_packet_match_bssid) {
1497 if (phy_sta_rpt->signal_quality >= 64) {
1499 } else if (phy_sta_rpt->signal_quality <= 20) {
1502 /* mapping to 2~99% */
1503 sq = 64 - phy_sta_rpt->signal_quality;
1504 sq = ((sq << 3) + sq) >> 2;
1508 /* Modify CCK PWDB if old AGC */
1509 if (!dm->cck_new_agc) {
1510 u8 lna_idx, vga_idx;
1512 lna_idx = ((phy_sta_rpt->lna_h << 3) | phy_sta_rpt->lna_l);
1513 vga_idx = phy_sta_rpt->vga;
1515 /* JJ ADD 20161014 */
1518 /*if (dm->support_ic_type & ODM_RTL8822B) */
1519 /*rx_power = odm_CCKRSSI_8822B(LNA_idx, VGA_idx);*/
1522 /* Update CCK packet counter */
1523 dm->phy_dbg_info.num_qry_phy_status_cck++;
1525 /*CCK no STBC and LDPC*/
1526 dm->phy_dbg_info.is_ldpc_pkt = false;
1527 dm->phy_dbg_info.is_stbc_pkt = false;
1529 /* Update Common information */
1530 phydm_set_common_phy_info(rx_power, phy_sta_rpt->channel, false, false,
1531 ODM_BW20M, sq, phy_sta_rpt->rxsc, phy_info);
1533 /* Update CCK pwdb */
1534 /* Update per-path information */
1535 phydm_set_per_path_phy_info(ODM_RF_PATH_A, rx_power, 0, 0, 0, phy_info);
1537 dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a;
1538 dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b;
1539 dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c;
1540 dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d;
1543 static void phydm_get_rx_phy_status_type1(struct phy_dm_struct *dm,
1545 struct dm_per_pkt_info *pktinfo,
1546 struct dm_phy_status_info *phy_info)
1548 /* type 1 is used for ofdm packet */
1550 struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt =
1551 (struct phy_status_rpt_jaguar2_type1 *)phy_status;
1552 s8 rx_pwr_db = -120;
1553 u8 i, rxsc, bw = ODM_BW20M, rx_count = 0;
1557 /* Update OFDM packet counter */
1558 dm->phy_dbg_info.num_qry_phy_status_ofdm++;
1560 /* Update per-path information */
1561 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
1562 if (dm->rx_ant_status & BIT(i)) {
1565 /* RX path counter */
1568 /* Update per-path information
1569 * (RSSI_dB RSSI_percentage EVM SNR CFO sq)
1571 /* EVM report is reported by stream, not path */
1572 rx_path_pwr_db = phy_sta_rpt->pwdb[i] -
1573 110; /* per-path pwdb in dB domain */
1574 phydm_set_per_path_phy_info(
1576 phy_sta_rpt->rxevm[rx_count - 1],
1577 phy_sta_rpt->cfo_tail[i], phy_sta_rpt->rxsnr[i],
1580 /* search maximum pwdb */
1581 if (rx_path_pwr_db > rx_pwr_db)
1582 rx_pwr_db = rx_path_pwr_db;
1586 /* mapping RX counter from 1~4 to 0~3 */
1588 phy_info->rx_count = rx_count - 1;
1590 /* Check if MU packet or not */
1591 if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) {
1593 dm->phy_dbg_info.num_qry_mu_pkt++;
1598 /* count BF packet */
1599 dm->phy_dbg_info.num_qry_bf_pkt =
1600 dm->phy_dbg_info.num_qry_bf_pkt + phy_sta_rpt->beamformed;
1602 /*STBC or LDPC pkt*/
1603 dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc;
1604 dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc;
1606 /* Check sub-channel */
1607 if ((pktinfo->data_rate > ODM_RATE11M) &&
1608 (pktinfo->data_rate < ODM_RATEMCS0))
1609 rxsc = phy_sta_rpt->l_rxsc;
1611 rxsc = phy_sta_rpt->ht_rxsc;
1613 /* Check RX bandwidth */
1614 if (dm->support_ic_type & ODM_RTL8822B) {
1615 if ((rxsc >= 1) && (rxsc <= 8))
1617 else if ((rxsc >= 9) && (rxsc <= 12))
1619 else if (rxsc >= 13)
1622 bw = phy_sta_rpt->rf_mode;
1623 } else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D |
1624 ODM_RTL8710B)) { /* JJ ADD 20161014 */
1625 if (phy_sta_rpt->rf_mode == 0)
1627 else if ((rxsc == 1) || (rxsc == 2))
1633 /* Update packet information */
1634 phydm_set_common_phy_info(
1635 rx_pwr_db, phy_sta_rpt->channel, (bool)phy_sta_rpt->beamformed,
1636 is_mu, bw, odm_evm_db_to_percentage(phy_sta_rpt->rxevm[0]),
1639 num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
1641 odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfo_tail, num_ss);
1642 dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a;
1643 dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b;
1644 dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c;
1645 dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d;
1647 if (pktinfo->is_packet_match_bssid) {
1649 phydm_rx_statistic_cal(dm, phy_status, pktinfo);
1653 static void phydm_get_rx_phy_status_type2(struct phy_dm_struct *dm,
1655 struct dm_per_pkt_info *pktinfo,
1656 struct dm_phy_status_info *phy_info)
1658 struct phy_status_rpt_jaguar2_type2 *phy_sta_rpt =
1659 (struct phy_status_rpt_jaguar2_type2 *)phy_status;
1660 s8 rx_pwr_db = -120;
1661 u8 i, rxsc, bw = ODM_BW20M, rx_count = 0;
1663 /* Update OFDM packet counter */
1664 dm->phy_dbg_info.num_qry_phy_status_ofdm++;
1666 /* Update per-path information */
1667 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
1668 if (dm->rx_ant_status & BIT(i)) {
1671 /* RX path counter */
1674 /* Update per-path information
1675 * (RSSI_dB RSSI_percentage EVM SNR CFO sq)
1677 rx_path_pwr_db = phy_sta_rpt->pwdb[i] -
1678 110; /* per-path pwdb in dB domain */
1680 phydm_set_per_path_phy_info(i, rx_path_pwr_db, 0, 0, 0,
1683 /* search maximum pwdb */
1684 if (rx_path_pwr_db > rx_pwr_db)
1685 rx_pwr_db = rx_path_pwr_db;
1689 /* mapping RX counter from 1~4 to 0~3 */
1691 phy_info->rx_count = rx_count - 1;
1693 /* Check RX sub-channel */
1694 if ((pktinfo->data_rate > ODM_RATE11M) &&
1695 (pktinfo->data_rate < ODM_RATEMCS0))
1696 rxsc = phy_sta_rpt->l_rxsc;
1698 rxsc = phy_sta_rpt->ht_rxsc;
1700 /*STBC or LDPC pkt*/
1701 dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc;
1702 dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc;
1704 /* Check RX bandwidth */
1705 /* the BW information of sc=0 is useless, because there is
1706 * no information of RF mode
1709 if (dm->support_ic_type & ODM_RTL8822B) {
1710 if ((rxsc >= 1) && (rxsc <= 8))
1712 else if ((rxsc >= 9) && (rxsc <= 12))
1714 else if (rxsc >= 13)
1718 } else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D |
1719 ODM_RTL8710B)) { /* JJ ADD 20161014 */
1726 /* Update packet information */
1727 phydm_set_common_phy_info(rx_pwr_db, phy_sta_rpt->channel,
1728 (bool)phy_sta_rpt->beamformed, false, bw, 0,
1733 phydm_process_rssi_for_dm_new_type(struct phy_dm_struct *dm,
1734 struct dm_phy_status_info *phy_info,
1735 struct dm_per_pkt_info *pktinfo)
1737 s32 undecorated_smoothed_pwdb, accumulate_pwdb;
1740 struct rtl_sta_info *entry;
1741 u8 scaling_factor = 4;
1743 if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM)
1746 entry = dm->odm_sta_info[pktinfo->station_id];
1748 if (!IS_STA_VALID(entry))
1751 if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/
1754 if (pktinfo->is_packet_beacon)
1755 dm->phy_dbg_info.num_qry_beacon_pkt++;
1757 if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) {
1758 u32 rssi_linear = 0;
1760 dm->rx_rate = pktinfo->data_rate;
1761 undecorated_smoothed_pwdb =
1762 entry->rssi_stat.undecorated_smoothed_pwdb;
1763 accumulate_pwdb = dm->accumulate_pwdb[pktinfo->station_id];
1764 dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
1765 dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
1766 dm->rssi_c = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_C];
1767 dm->rssi_d = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_D];
1769 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
1770 if (phy_info->rx_mimo_signal_strength[i] != 0)
1771 rssi_linear += odm_convert_to_linear(
1772 phy_info->rx_mimo_signal_strength[i]);
1775 switch (phy_info->rx_count + 1) {
1777 rssi_linear = (rssi_linear >> 1);
1780 /* rssi_linear/3 ~ rssi_linear*11/32 */
1781 rssi_linear = ((rssi_linear) + (rssi_linear << 1) +
1782 (rssi_linear << 3)) >>
1786 rssi_linear = (rssi_linear >> 2);
1789 rssi_ave = odm_convert_to_db(rssi_linear);
1791 if (undecorated_smoothed_pwdb <= 0) {
1793 (phy_info->rx_pwdb_all << scaling_factor);
1794 undecorated_smoothed_pwdb = phy_info->rx_pwdb_all;
1796 accumulate_pwdb = accumulate_pwdb -
1797 (accumulate_pwdb >> scaling_factor) +
1799 undecorated_smoothed_pwdb =
1801 (1 << (scaling_factor - 1))) >>
1805 entry->rssi_stat.undecorated_smoothed_pwdb =
1806 undecorated_smoothed_pwdb;
1807 dm->accumulate_pwdb[pktinfo->station_id] = accumulate_pwdb;
1811 void phydm_rx_phy_status_new_type(struct phy_dm_struct *phydm, u8 *phy_status,
1812 struct dm_per_pkt_info *pktinfo,
1813 struct dm_phy_status_info *phy_info)
1815 u8 phy_status_type = (*phy_status & 0xf);
1818 phydm_reset_phy_info(phydm, phy_info);
1820 /* Phy status parsing */
1821 switch (phy_status_type) {
1823 phydm_get_rx_phy_status_type0(phydm, phy_status, pktinfo,
1828 phydm_get_rx_phy_status_type1(phydm, phy_status, pktinfo,
1833 phydm_get_rx_phy_status_type2(phydm, phy_status, pktinfo,
1841 /* Update signal strength to UI, and phy_info->rx_pwdb_all is the
1842 * maximum RSSI of all path
1844 phy_info->signal_strength = phy_info->rx_pwdb_all;
1846 /* Calculate average RSSI and smoothed RSSI */
1847 phydm_process_rssi_for_dm_new_type(phydm, phy_info, pktinfo);