Linux-libre 5.0.10-gnu
[librecmc/linux-libre.git] / drivers / staging / rtlwifi / phydm / phydm_hwconfig.c
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2016  Realtek Corporation.
5  *
6  * Contact Information:
7  * wlanfae <wlanfae@realtek.com>
8  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
9  * Hsinchu 300, Taiwan.
10  *
11  * Larry Finger <Larry.Finger@lwfinger.net>
12  *
13  *****************************************************************************/
14
15 /* ************************************************************
16  * include files
17  * *************************************************************/
18
19 #include "mp_precomp.h"
20 #include "phydm_precomp.h"
21
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))
24
25 #define READ_AND_CONFIG READ_AND_CONFIG_MP
26
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))
31
32 #define READ_FIRMWARE READ_FIRMWARE_MP
33
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())
36
37 #define GET_VERSION(ic, txt) GET_VERSION_MP(ic, txt)
38
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)
44 {
45         u32 weighting = 0, undecorated_smoothed_pwdb;
46         /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */
47
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);
54         } else {
55                 if (entry->rssi_stat.valid_bit < 64)
56                         entry->rssi_stat.valid_bit++;
57
58                 if (entry->rssi_stat.valid_bit == 64) {
59                         weighting = ((entry->rssi_stat.ofdm_pkt) > 4) ?
60                                             64 :
61                                             (entry->rssi_stat.ofdm_pkt << 4);
62                         undecorated_smoothed_pwdb =
63                                 (weighting * undecorated_smoothed_ofdm +
64                                  (64 - weighting) * undecorated_smoothed_cck) >>
65                                 6;
66                         ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
67                                      "PWDB_1[%d] = (( %d )), W = (( %d ))\n",
68                                      pktinfo->station_id,
69                                      undecorated_smoothed_cck, weighting);
70                 } else {
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;
79                         else
80                                 undecorated_smoothed_pwdb = 0;
81
82                         ODM_RT_TRACE(
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);
88                 }
89         }
90
91         return undecorated_smoothed_pwdb;
92 }
93
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)
98 {
99         u32 rssi_ave;
100         u8 i;
101
102         rssi_ave = phy_info->rx_pwdb_all;
103         dm->rssi_a = (u8)phy_info->rx_pwdb_all;
104         dm->rssi_b = 0xFF;
105         dm->rssi_c = 0xFF;
106         dm->rssi_d = 0xFF;
107
108         if (entry->rssi_stat.cck_pkt <= 63)
109                 entry->rssi_stat.cck_pkt++;
110
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;
125
126                 ODM_RT_TRACE(
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);
132         } else {
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)) /
138                                 (RX_SMOOTH_FACTOR);
139                         undecorated_smoothed_cck = undecorated_smoothed_cck + 1;
140                         ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
141                                      "CCK_1: (( %d ))\n",
142                                      undecorated_smoothed_cck);
143                 } else {
144                         undecorated_smoothed_cck =
145                                 (((undecorated_smoothed_cck) *
146                                   (RX_SMOOTH_FACTOR - 1)) +
147                                  (phy_info->rx_pwdb_all)) /
148                                 (RX_SMOOTH_FACTOR);
149                         ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
150                                      "CCK_2: (( %d ))\n",
151                                      undecorated_smoothed_cck);
152                 }
153         }
154
155         i = 63;
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;
160 }
161
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)
166 {
167         u32 rssi_ave;
168         u8 rssi_max, rssi_min, i;
169
170         if (dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B)) {
171                 u8 rx_count = 0;
172                 u32 rssi_linear = 0;
173
174                 if (dm->rx_ant_status & ODM_RF_A) {
175                         dm->rssi_a = phy_info->rx_mimo_signal_strength
176                                              [ODM_RF_PATH_A];
177                         rx_count++;
178                         rssi_linear += odm_convert_to_linear(
179                                 phy_info->rx_mimo_signal_strength
180                                         [ODM_RF_PATH_A]);
181                 } else {
182                         dm->rssi_a = 0;
183                 }
184
185                 if (dm->rx_ant_status & ODM_RF_B) {
186                         dm->rssi_b = phy_info->rx_mimo_signal_strength
187                                              [ODM_RF_PATH_B];
188                         rx_count++;
189                         rssi_linear += odm_convert_to_linear(
190                                 phy_info->rx_mimo_signal_strength
191                                         [ODM_RF_PATH_B]);
192                 } else {
193                         dm->rssi_b = 0;
194                 }
195
196                 if (dm->rx_ant_status & ODM_RF_C) {
197                         dm->rssi_c = phy_info->rx_mimo_signal_strength
198                                              [ODM_RF_PATH_C];
199                         rx_count++;
200                         rssi_linear += odm_convert_to_linear(
201                                 phy_info->rx_mimo_signal_strength
202                                         [ODM_RF_PATH_C]);
203                 } else {
204                         dm->rssi_c = 0;
205                 }
206
207                 if (dm->rx_ant_status & ODM_RF_D) {
208                         dm->rssi_d = phy_info->rx_mimo_signal_strength
209                                              [ODM_RF_PATH_D];
210                         rx_count++;
211                         rssi_linear += odm_convert_to_linear(
212                                 phy_info->rx_mimo_signal_strength
213                                         [ODM_RF_PATH_D]);
214                 } else {
215                         dm->rssi_d = 0;
216                 }
217
218                 /* Calculate average RSSI */
219                 switch (rx_count) {
220                 case 2:
221                         rssi_linear = (rssi_linear >> 1);
222                         break;
223                 case 3:
224                         /* rssi_linear/3 ~ rssi_linear*11/32 */
225                         rssi_linear = ((rssi_linear) + (rssi_linear << 1) +
226                                        (rssi_linear << 3)) >>
227                                       5;
228                         break;
229                 case 4:
230                         rssi_linear = (rssi_linear >> 2);
231                         break;
232                 }
233
234                 rssi_ave = odm_convert_to_db(rssi_linear);
235         } else {
236                 if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B] == 0) {
237                         rssi_ave = phy_info->rx_mimo_signal_strength
238                                            [ODM_RF_PATH_A];
239                         dm->rssi_a = phy_info->rx_mimo_signal_strength
240                                              [ODM_RF_PATH_A];
241                         dm->rssi_b = 0;
242                 } else {
243                         dm->rssi_a = phy_info->rx_mimo_signal_strength
244                                              [ODM_RF_PATH_A];
245                         dm->rssi_b = phy_info->rx_mimo_signal_strength
246                                              [ODM_RF_PATH_B];
247
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
251                                                    [ODM_RF_PATH_A];
252                                 rssi_min = phy_info->rx_mimo_signal_strength
253                                                    [ODM_RF_PATH_B];
254                         } else {
255                                 rssi_max = phy_info->rx_mimo_signal_strength
256                                                    [ODM_RF_PATH_B];
257                                 rssi_min = phy_info->rx_mimo_signal_strength
258                                                    [ODM_RF_PATH_A];
259                         }
260                         if ((rssi_max - rssi_min) < 3)
261                                 rssi_ave = rssi_max;
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;
266                         else
267                                 rssi_ave = rssi_max - 3;
268                 }
269         }
270
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);
276         } else {
277                 if (phy_info->rx_pwdb_all > (u32)undecorated_smoothed_ofdm) {
278                         undecorated_smoothed_ofdm =
279                                 (((undecorated_smoothed_ofdm) *
280                                   (RX_SMOOTH_FACTOR - 1)) +
281                                  (rssi_ave)) /
282                                 (RX_SMOOTH_FACTOR);
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);
288                 } else {
289                         undecorated_smoothed_ofdm =
290                                 (((undecorated_smoothed_ofdm) *
291                                   (RX_SMOOTH_FACTOR - 1)) +
292                                  (rssi_ave)) /
293                                 (RX_SMOOTH_FACTOR);
294                         ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
295                                      "OFDM_2: (( %d ))\n",
296                                      undecorated_smoothed_ofdm);
297                 }
298         }
299
300         if (entry->rssi_stat.ofdm_pkt != 64) {
301                 i = 63;
302                 entry->rssi_stat.ofdm_pkt -=
303                         (u8)(((entry->rssi_stat.packet_map >> i) & BIT(0)) - 1);
304         }
305
306         entry->rssi_stat.packet_map =
307                 (entry->rssi_stat.packet_map << 1) | BIT(0);
308         return undecorated_smoothed_ofdm;
309 }
310
311 static u8 odm_evm_db_to_percentage(s8);
312 static u8 odm_evm_dbm_jaguar_series(s8);
313
314 static inline u32 phydm_get_rssi_average(struct phy_dm_struct *dm,
315                                          struct dm_phy_status_info *phy_info)
316 {
317         u8 rssi_max = 0, rssi_min = 0;
318
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];
321
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];
326         } else {
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];
329         }
330         if ((rssi_max - rssi_min) < 3)
331                 return rssi_max;
332         else if ((rssi_max - rssi_min) < 6)
333                 return rssi_max - 1;
334         else if ((rssi_max - rssi_min) < 10)
335                 return rssi_max - 2;
336         else
337                 return rssi_max - 3;
338 }
339
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)
343 {
344         if (i < ODM_RF_PATH_C)
345                 return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm[i]);
346         else
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));*/
350 }
351
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)
354 {
355         u8 evm = 0;
356
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*/
362                         evm += 20;
363                         if (evm > 100)
364                                 evm = 100;
365                 }
366         } else {
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*/
372                 } else {
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*/
377                 }
378         }
379
380         return evm;
381 }
382
383 static inline s8 phydm_get_rx_pwr(u8 LNA_idx, u8 VGA_idx, u8 cck_highpwr)
384 {
385         switch (LNA_idx) {
386         case 7:
387                 if (VGA_idx <= 27)
388                         return -100 + 2 * (27 - VGA_idx); /*VGA_idx = 27~2*/
389                 else
390                         return -100;
391                 break;
392         case 6:
393                 return -48 + 2 * (2 - VGA_idx); /*VGA_idx = 2~0*/
394         case 5:
395                 return -42 + 2 * (7 - VGA_idx); /*VGA_idx = 7~5*/
396         case 4:
397                 return -36 + 2 * (7 - VGA_idx); /*VGA_idx = 7~4*/
398         case 3:
399                 return -24 + 2 * (7 - VGA_idx); /*VGA_idx = 7~0*/
400         case 2:
401                 if (cck_highpwr)
402                         return -12 + 2 * (5 - VGA_idx); /*VGA_idx = 5~0*/
403                 else
404                         return -6 + 2 * (5 - VGA_idx);
405                 break;
406         case 1:
407                 return 8 - 2 * VGA_idx;
408         case 0:
409                 return 14 - 2 * VGA_idx;
410         default:
411                 break;
412         }
413         return 0;
414 }
415
416 static inline u8 phydm_adjust_pwdb(u8 cck_highpwr, u8 pwdb_all)
417 {
418         if (!cck_highpwr) {
419                 if (pwdb_all >= 80)
420                         return ((pwdb_all - 80) << 1) + ((pwdb_all - 80) >> 1) +
421                                80;
422                 else if ((pwdb_all <= 78) && (pwdb_all >= 20))
423                         return pwdb_all + 3;
424                 if (pwdb_all > 100)
425                         return 100;
426         }
427         return pwdb_all;
428 }
429
430 static inline u8
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)
434 {
435         u8 sq_rpt;
436
437         if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test)
438                 return 100;
439
440         sq_rpt = phy_sta_rpt->pwdb_all;
441
442         if (sq_rpt > 64)
443                 return 0;
444         else if (sq_rpt < 20)
445                 return 100;
446         else
447                 return ((64 - sq_rpt) * 100) / 44;
448 }
449
450 static inline u8
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)
454 {
455         u8 sq_rpt;
456
457         if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test)
458                 return 100;
459
460         sq_rpt = phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all;
461
462         if (sq_rpt > 64)
463                 return 0;
464         else if (sq_rpt < 20)
465                 return 100;
466         else
467                 return ((64 - sq_rpt) * 100) / 44;
468 }
469
470 static u8 odm_query_rx_pwr_percentage(s8 ant_power)
471 {
472         if ((ant_power <= -100) || (ant_power >= 20))
473                 return 0;
474         else if (ant_power >= 0)
475                 return 100;
476         else
477                 return 100 + ant_power;
478 }
479
480 static u8 odm_evm_db_to_percentage(s8 value)
481 {
482         /* -33dB~0dB to 0%~99% */
483         s8 ret_val;
484
485         ret_val = value;
486         ret_val /= 2;
487
488         if (ret_val >= 0)
489                 ret_val = 0;
490
491         if (ret_val <= -33)
492                 ret_val = -33;
493
494         ret_val = 0 - ret_val;
495         ret_val *= 3;
496
497         if (ret_val == 99)
498                 ret_val = 100;
499
500         return (u8)ret_val;
501 }
502
503 static u8 odm_evm_dbm_jaguar_series(s8 value)
504 {
505         s8 ret_val = value;
506
507         /* -33dB~0dB to 33dB ~ 0dB */
508         if (ret_val == -128)
509                 ret_val = 127;
510         else if (ret_val < 0)
511                 ret_val = 0 - ret_val;
512
513         ret_val = ret_val >> 1;
514         return (u8)ret_val;
515 }
516
517 static s16 odm_cfo(s8 value)
518 {
519         s16 ret_val;
520
521         if (value < 0) {
522                 ret_val = 0 - value;
523                 ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */
524                 ret_val =
525                         ret_val | BIT(12); /* set bit12 as 1 for negative cfo */
526         } else {
527                 ret_val = value;
528                 ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */
529         }
530         return ret_val;
531 }
532
533 static u8 phydm_rate_to_num_ss(struct phy_dm_struct *dm, u8 data_rate)
534 {
535         u8 num_ss = 1;
536
537         if (data_rate <= ODM_RATE54M)
538                 num_ss = 1;
539         else if (data_rate <= ODM_RATEMCS31)
540                 num_ss = ((data_rate - ODM_RATEMCS0) >> 3) + 1;
541         else if (data_rate <= ODM_RATEVHTSS1MCS9)
542                 num_ss = 1;
543         else if (data_rate <= ODM_RATEVHTSS2MCS9)
544                 num_ss = 2;
545         else if (data_rate <= ODM_RATEVHTSS3MCS9)
546                 num_ss = 3;
547         else if (data_rate <= ODM_RATEVHTSS4MCS9)
548                 num_ss = 4;
549
550         return num_ss;
551 }
552
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)
556 {
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;
562         u8 rf_rx_num = 0;
563         u8 LNA_idx = 0;
564         u8 VGA_idx = 0;
565         u8 cck_agc_rpt;
566         u8 num_ss;
567         struct phy_status_rpt_8192cd *phy_sta_rpt =
568                 (struct phy_status_rpt_8192cd *)phy_status;
569
570         is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false;
571
572         if (pktinfo->is_to_self)
573                 dm->curr_station_id = pktinfo->station_id;
574
575         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1;
576         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
577
578         if (is_cck_rate) {
579                 dm->phy_dbg_info.num_qry_phy_status_cck++;
580                 cck_agc_rpt = phy_sta_rpt->cck_agc_rpt_ofdm_cfosho_a;
581
582                 if (dm->support_ic_type & (ODM_RTL8703B)) {
583                 } else { /*3 bit LNA*/
584
585                         LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
586                         VGA_idx = (cck_agc_rpt & 0x1F);
587                 }
588
589                 ODM_RT_TRACE(
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);
593
594                 if (dm->board_type & ODM_BOARD_EXT_LNA)
595                         rx_pwr_all -= dm->ext_lna_gain;
596
597                 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
598
599                 if (pktinfo->is_to_self) {
600                         dm->cck_lna_idx = LNA_idx;
601                         dm->cck_vga_idx = VGA_idx;
602                 }
603                 phy_info->rx_pwdb_all = pwdb_all;
604
605                 phy_info->bt_rx_rssi_percentage = pwdb_all;
606                 phy_info->recv_signal_power = rx_pwr_all;
607                 /* (3) Get Signal Quality (EVM) */
608                 {
609                         u8 sq;
610
611                         sq = phydm_get_signal_quality_8192(phy_info, dm,
612                                                            phy_sta_rpt);
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;
616                 }
617
618                 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) {
619                         if (i == 0)
620                                 phy_info->rx_mimo_signal_strength[0] = pwdb_all;
621                         else
622                                 phy_info->rx_mimo_signal_strength[1] = 0;
623                 }
624         } else { /* 2 is OFDM rate */
625                 dm->phy_dbg_info.num_qry_phy_status_ofdm++;
626
627                 /*  */
628                 /* (1)Get RSSI for HT rate */
629                 /*  */
630
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))
634                                 rf_rx_num++;
635                         /* else */
636                         /* continue; */
637
638                         rx_pwr[i] =
639                                 ((phy_sta_rpt->path_agc[i].gain & 0x3F) * 2) -
640                                 110;
641
642                         if (pktinfo->is_to_self) {
643                                 dm->ofdm_agc_idx[i] =
644                                         (phy_sta_rpt->path_agc[i].gain & 0x3F);
645                                 /**/
646                         }
647
648                         phy_info->rx_pwr[i] = rx_pwr[i];
649
650                         /* Translate DBM to percentage. */
651                         RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]);
652                         total_rssi += RSSI;
653
654                         phy_info->rx_mimo_signal_strength[i] = (u8)RSSI;
655
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];
660
661                         /* Record Signal Strength for next packet */
662                         /* if(pktinfo->is_packet_match_bssid) */
663                         {
664                         }
665                 }
666
667                 /*  */
668                 /* (2)PWDB, Average PWDB calcuated by hardware (for RA) */
669                 /*  */
670                 rx_pwr_all = (((phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all) >> 1) &
671                               0x7f) -
672                              110;
673
674                 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
675                 pwdb_all_bt = pwdb_all;
676
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;
681
682                 if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) {
683                         /* do nothing */
684                 } else if ((dm->support_platform == ODM_WIN) &&
685                            (dm->patch_id == 25)) {
686                         /* do nothing */
687                 } else { /* mgnt_info->customer_id != RT_CID_819X_LENOVO */
688                         /*  */
689                         /* (3)EVM of HT rate */
690                         /*  */
691                         if (pktinfo->data_rate >= ODM_RATEMCS8 &&
692                             pktinfo->data_rate <= ODM_RATEMCS15) {
693                                 /* both spatial stream make sense */
694                                 max_spatial_stream = 2;
695                         } else {
696                                 /* only spatial stream 1 makes sense */
697                                 max_spatial_stream = 1;
698                         }
699
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
707                                  *correct anymore.
708                                  */
709                                 EVM = odm_evm_db_to_percentage(
710                                         (phy_sta_rpt
711                                                  ->stream_rxevm[i])); /* dbm */
712
713                                 /* Fill value in RFD, Get the first spatial
714                                  * stream only
715                                  */
716                                 if (i == ODM_RF_PATH_A)
717                                         phy_info->signal_quality =
718                                                 (u8)(EVM & 0xff);
719                                 phy_info->rx_mimo_signal_quality[i] =
720                                         (u8)(EVM & 0xff);
721                         }
722                 }
723
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);
726         }
727         /* UI BSS List signal strength(in percentage), make it good looking,
728          * from 0~100.
729          */
730         /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */
731         if (is_cck_rate)
732                 phy_info->signal_strength = pwdb_all;
733         else if (rf_rx_num != 0)
734                 phy_info->signal_strength = (total_rssi /= rf_rx_num);
735
736         /* For 92C/92D HW (Hybrid) Antenna Diversity */
737 }
738
739 static void
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)
743 {
744         if (pktinfo->data_rate <= ODM_RATE54M) {
745                 switch (phy_sta_rpt->r_RFMOD) {
746                 case 1:
747                         if (phy_sta_rpt->sub_chnl == 0)
748                                 phy_info->band_width = 1;
749                         else
750                                 phy_info->band_width = 0;
751                         break;
752
753                 case 2:
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;
759                         else
760                                 phy_info->band_width = 0;
761                         break;
762
763                 default:
764                 case 0:
765                         phy_info->band_width = 0;
766                         break;
767                 }
768         }
769 }
770
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)
774 {
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;
779         u8 is_cck_rate = 0;
780         u8 rf_rx_num = 0;
781         u8 cck_highpwr = 0;
782         u8 LNA_idx, VGA_idx;
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;
786         u8 num_ss;
787
788         odm_rx_phy_bw_jaguar_series_parsing(phy_info, pktinfo, phy_sta_rpt);
789
790         if (pktinfo->data_rate <= ODM_RATE11M)
791                 is_cck_rate = true;
792         else
793                 is_cck_rate = false;
794
795         if (pktinfo->is_to_self)
796                 dm->curr_station_id = pktinfo->station_id;
797         else
798                 dm->curr_station_id = 0xff;
799
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;
804
805         if (is_cck_rate) {
806                 u8 cck_agc_rpt;
807
808                 dm->phy_dbg_info.num_qry_phy_status_cck++;
809
810                 /*(1)Hardware does not provide RSSI for CCK*/
811                 /*(2)PWDB, Average PWDB calculated by hardware (for RA)*/
812
813                 cck_highpwr = dm->is_cck_high_power;
814
815                 cck_agc_rpt = phy_sta_rpt->cfosho[0];
816                 LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
817                 VGA_idx = (cck_agc_rpt & 0x1F);
818
819                 if (dm->support_ic_type == ODM_RTL8812) {
820                         rx_pwr_all =
821                                 phydm_get_rx_pwr(LNA_idx, VGA_idx, cck_highpwr);
822                         rx_pwr_all += 6;
823                         pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
824                         pwdb_all = phydm_adjust_pwdb(cck_highpwr, pwdb_all);
825
826                 } else if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
827                         s8 pout = -6;
828
829                         switch (LNA_idx) {
830                         case 5:
831                                 rx_pwr_all = pout - 32 - (2 * VGA_idx);
832                                 break;
833                         case 4:
834                                 rx_pwr_all = pout - 24 - (2 * VGA_idx);
835                                 break;
836                         case 2:
837                                 rx_pwr_all = pout - 11 - (2 * VGA_idx);
838                                 break;
839                         case 1:
840                                 rx_pwr_all = pout + 5 - (2 * VGA_idx);
841                                 break;
842                         case 0:
843                                 rx_pwr_all = pout + 21 - (2 * VGA_idx);
844                                 break;
845                         }
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) {
849                         s8 pout = -6;
850
851                         switch (LNA_idx) {
852                         /*CCK only use LNA: 2, 3, 5, 7*/
853                         case 7:
854                                 rx_pwr_all = pout - 32 - (2 * VGA_idx);
855                                 break;
856                         case 5:
857                                 rx_pwr_all = pout - 22 - (2 * VGA_idx);
858                                 break;
859                         case 3:
860                                 rx_pwr_all = pout - 2 - (2 * VGA_idx);
861                                 break;
862                         case 2:
863                                 rx_pwr_all = pout + 5 - (2 * VGA_idx);
864                                 break;
865                         default:
866                                 break;
867                         }
868                         pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
869                 }
870
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)*/
877                 {
878                         u8 sq = 0;
879
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,
883                                                                    phy_sta_rpt);
884
885                         phy_info->signal_quality = sq;
886                         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq;
887                 }
888
889                 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
890                         if (i == 0)
891                                 phy_info->rx_mimo_signal_strength[0] = pwdb_all;
892                         else
893                                 phy_info->rx_mimo_signal_strength[i] = 0;
894                 }
895         } else {
896                 /*is OFDM rate*/
897                 fat_tab->hw_antsw_occur = phy_sta_rpt->hw_antsw_occur;
898
899                 dm->phy_dbg_info.num_qry_phy_status_ofdm++;
900
901                 /*(1)Get RSSI for OFDM rate*/
902
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))
906                                 rf_rx_num++;
907                         /*2012.05.25 LukeLee: Testchip AGC report is wrong,
908                          *it should be restored back to old formula in MP chip
909                          */
910                         if (i < ODM_RF_PATH_C)
911                                 rx_pwr[i] = (phy_sta_rpt->gain_trsw[i] & 0x7F) -
912                                             110;
913                         else
914                                 rx_pwr[i] = (phy_sta_rpt->gain_trsw_cd[i - 2] &
915                                              0x7F) -
916                                             110;
917
918                         phy_info->rx_pwr[i] = rx_pwr[i];
919
920                         /* Translate DBM to percentage. */
921                         RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]);
922
923                         /*total_rssi += RSSI;*/
924                         /*Get the best two RSSI*/
925                         if (RSSI > best_rssi && RSSI > second_rssi) {
926                                 second_rssi = best_rssi;
927                                 best_rssi = RSSI;
928                         } else if (RSSI > second_rssi && RSSI <= best_rssi) {
929                                 second_rssi = RSSI;
930                         }
931
932                         phy_info->rx_mimo_signal_strength[i] = (u8)RSSI;
933
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
942                                                               .rx_snr_db[i] =
943                                         phy_sta_rpt->csi_current[i - 2] / 2;
944
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]));
951                         }
952                 }
953
954                 /*(3)PWDB, Average PWDB calculated by hardware (for RA)*/
955
956                 /*2012.05.25 LukeLee: Testchip AGC report is wrong, it should be
957                  *restored back to old formula in MP chip
958                  */
959                 if ((dm->support_ic_type &
960                      (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) &&
961                     (!dm->is_mp_chip))
962                         rx_pwr_all = (phy_sta_rpt->pwdb_all & 0x7f) - 110;
963                 else
964                         rx_pwr_all = (((phy_sta_rpt->pwdb_all) >> 1) & 0x7f) -
965                                      110; /*OLD FORMULA*/
966
967                 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
968                 pwdb_all_bt = pwdb_all;
969
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;
974
975                 if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) {
976                         /*do nothing*/
977                 } else {
978                         /*mgnt_info->customer_id != RT_CID_819X_LENOVO*/
979
980                         /*(4)EVM of OFDM rate*/
981
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;
994                         else
995                                 max_spatial_stream = 1;
996
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
1004                                  *correct anymore.
1005                                  */
1006
1007                                 EVM = phydm_get_odm_evm(i, pktinfo,
1008                                                         phy_sta_rpt);
1009                                 evm_dbm = phydm_get_evm_dbm(i, EVM, phy_sta_rpt,
1010                                                             phy_info);
1011                                 phy_info->rx_mimo_signal_quality[i] = EVM;
1012                                 phy_info->rx_mimo_evm_dbm[i] = evm_dbm;
1013                         }
1014                 }
1015
1016                 num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
1017                 odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfotail, num_ss);
1018         }
1019
1020         /*UI BSS List signal strength(in percentage), make it good looking,
1021          *from 0~100.
1022          */
1023         /*It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().*/
1024         if (is_cck_rate) {
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.
1029                  */
1030                 if (rf_rx_num == 1)
1031                         avg_rssi = best_rssi;
1032                 else
1033                         avg_rssi = (best_rssi + second_rssi) / 2;
1034
1035                 phy_info->signal_strength = avg_rssi;
1036         }
1037
1038         dm->rx_pwdb_ave = dm->rx_pwdb_ave + phy_info->rx_pwdb_all;
1039
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;
1044 }
1045
1046 void phydm_reset_rssi_for_dm(struct phy_dm_struct *dm, u8 station_id)
1047 {
1048         struct rtl_sta_info *entry;
1049
1050         entry = dm->odm_sta_info[station_id];
1051
1052         if (!IS_STA_VALID(entry))
1053                 return;
1054
1055         ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
1056                      "Reset RSSI for macid = (( %d ))\n", station_id);
1057
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;
1067 }
1068
1069 void odm_init_rssi_for_dm(struct phy_dm_struct *dm) {}
1070
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)
1074 {
1075         s32 undecorated_smoothed_pwdb, undecorated_smoothed_cck,
1076                 undecorated_smoothed_ofdm;
1077         u8 is_cck_rate = 0;
1078         u8 send_rssi_2_fw = 0;
1079         struct rtl_sta_info *entry;
1080
1081         if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM)
1082                 return;
1083
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];
1087
1088         if (!IS_STA_VALID(entry))
1089                 return;
1090
1091         {
1092                 if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/
1093                         return;
1094         }
1095
1096         if (pktinfo->is_packet_beacon)
1097                 dm->phy_dbg_info.num_qry_beacon_pkt++;
1098
1099         is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false;
1100         dm->rx_rate = pktinfo->data_rate;
1101
1102         /* --------------Statistic for antenna/path diversity---------------- */
1103
1104         /* -----------------Smart Antenna Debug Message------------------ */
1105
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;
1109
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);
1114                 else
1115                         undecorated_smoothed_cck = phydm_process_rssi_cck(
1116                                 dm, phy_info, entry, undecorated_smoothed_cck);
1117
1118                 undecorated_smoothed_pwdb = phydm_process_rssi_pwdb(
1119                         dm, entry, pktinfo, undecorated_smoothed_ofdm,
1120                         undecorated_smoothed_cck);
1121
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)) {
1125                         send_rssi_2_fw = 1;
1126                         entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_SEND;
1127                 }
1128
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;
1135
1136                 if (send_rssi_2_fw) { /* Trigger init rate by RSSI */
1137
1138                         if (entry->rssi_stat.ofdm_pkt != 0)
1139                                 entry->rssi_stat.undecorated_smoothed_pwdb =
1140                                         undecorated_smoothed_ofdm;
1141
1142                         ODM_RT_TRACE(
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);
1148                 }
1149         }
1150 }
1151
1152 /*
1153  * Endianness before calling this API
1154  */
1155 static void odm_phy_status_query_92c_series(struct phy_dm_struct *dm,
1156                                             struct dm_phy_status_info *phy_info,
1157                                             u8 *phy_status,
1158                                             struct dm_per_pkt_info *pktinfo)
1159 {
1160         odm_rx_phy_status92c_series_parsing(dm, phy_info, phy_status, pktinfo);
1161         odm_process_rssi_for_dm(dm, phy_info, pktinfo);
1162 }
1163
1164 /*
1165  * Endianness before calling this API
1166  */
1167
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)
1171 {
1172         odm_rx_phy_status_jaguar_series_parsing(dm, phy_info, phy_status,
1173                                                 pktinfo);
1174         odm_process_rssi_for_dm(dm, phy_info, pktinfo);
1175 }
1176
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)
1180 {
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);
1183                 return;
1184         }
1185
1186         if (dm->support_ic_type & ODM_IC_11AC_SERIES)
1187                 odm_phy_status_query_jaguar_series(dm, phy_info, phy_status,
1188                                                    pktinfo);
1189
1190         if (dm->support_ic_type & ODM_IC_11N_SERIES)
1191                 odm_phy_status_query_92c_series(dm, phy_info, phy_status,
1192                                                 pktinfo);
1193 }
1194
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)
1199 {
1200         /* 2011/10/19 Driver team will handle in the future. */
1201 }
1202
1203 /*
1204  * If you want to add a new IC, Please follow below template and generate
1205  * a new one.
1206  */
1207
1208 enum hal_status
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)
1212 {
1213         ODM_RT_TRACE(dm, ODM_COMP_INIT,
1214                      "===>%s (%s)\n", __func__,
1215                      (dm->is_mp_chip) ? "MPChip" : "TestChip");
1216         ODM_RT_TRACE(
1217                 dm, ODM_COMP_INIT,
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);
1220
1221         /* 1 AP doesn't use PHYDM power tracking table in these ICs */
1222         /* JJ ADD 20161014 */
1223
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);
1234                         else
1235                                 READ_AND_CONFIG_MP(8822b, _txpwr_lmt);
1236                 }
1237         }
1238
1239         return HAL_STATUS_SUCCESS;
1240 }
1241
1242 enum hal_status
1243 odm_config_rf_with_tx_pwr_track_header_file(struct phy_dm_struct *dm)
1244 {
1245         ODM_RT_TRACE(dm, ODM_COMP_INIT,
1246                      "===>%s (%s)\n", __func__,
1247                      (dm->is_mp_chip) ? "MPChip" : "TestChip");
1248         ODM_RT_TRACE(
1249                 dm, ODM_COMP_INIT,
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);
1252
1253         /* 1 AP doesn't use PHYDM power tracking table in these ICs */
1254         /* JJ ADD 20161014 */
1255
1256         /* 1 All platforms support */
1257
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);
1277                 else
1278                         READ_AND_CONFIG_MP(8822b, _txpowertrack);
1279         }
1280
1281         return HAL_STATUS_SUCCESS;
1282 }
1283
1284 enum hal_status
1285 odm_config_bb_with_header_file(struct phy_dm_struct *dm,
1286                                enum odm_bb_config_type config_type)
1287 {
1288         /* 1 AP doesn't use PHYDM initialization in these ICs */
1289         /* JJ ADD 20161014 */
1290
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);*/
1301         }
1302
1303         return HAL_STATUS_SUCCESS;
1304 }
1305
1306 enum hal_status odm_config_mac_with_header_file(struct phy_dm_struct *dm)
1307 {
1308         ODM_RT_TRACE(dm, ODM_COMP_INIT,
1309                      "===>%s (%s)\n", __func__,
1310                      (dm->is_mp_chip) ? "MPChip" : "TestChip");
1311         ODM_RT_TRACE(
1312                 dm, ODM_COMP_INIT,
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);
1315
1316         /* 1 AP doesn't use PHYDM initialization in these ICs */
1317         /* JJ ADD 20161014 */
1318
1319         /* 1 All platforms support */
1320         if (dm->support_ic_type == ODM_RTL8822B)
1321                 READ_AND_CONFIG_MP(8822b, _mac_reg);
1322
1323         return HAL_STATUS_SUCCESS;
1324 }
1325
1326 enum hal_status
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)
1330 {
1331         return HAL_STATUS_SUCCESS;
1332 }
1333
1334 u32 odm_get_hw_img_version(struct phy_dm_struct *dm)
1335 {
1336         u32 version = 0;
1337
1338         /* 1 AP doesn't use PHYDM initialization in these ICs */
1339         /* JJ ADD 20161014 */
1340
1341         /*1 All platforms support*/
1342         if (dm->support_ic_type == ODM_RTL8822B)
1343                 version = GET_VERSION_MP(8822b, _mac_reg);
1344
1345         return version;
1346 }
1347
1348 /* For 8822B only!! need to move to FW finally */
1349 /*==============================================*/
1350
1351 bool phydm_query_is_mu_api(struct phy_dm_struct *phydm, u8 ppdu_idx,
1352                            u8 *p_data_rate, u8 *p_gid)
1353 {
1354         u8 data_rate = 0, gid = 0;
1355         bool is_mu = false;
1356
1357         data_rate = phydm->phy_dbg_info.num_of_ppdu[ppdu_idx];
1358         gid = phydm->phy_dbg_info.gid_num[ppdu_idx];
1359
1360         if (data_rate & BIT(7)) {
1361                 is_mu = true;
1362                 data_rate = data_rate & ~(BIT(7));
1363         } else {
1364                 is_mu = false;
1365         }
1366
1367         *p_data_rate = data_rate;
1368         *p_gid = gid;
1369
1370         return is_mu;
1371 }
1372
1373 static void phydm_rx_statistic_cal(struct phy_dm_struct *phydm, u8 *phy_status,
1374                                    struct dm_per_pkt_info *pktinfo)
1375 {
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));
1379
1380         if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) {
1381                 if (date_rate >= ODM_RATEVHTSS1MCS0) {
1382                         phydm->phy_dbg_info
1383                                 .num_qry_mu_vht_pkt[date_rate - 0x2C]++;
1384                         phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] =
1385                                 date_rate | BIT(7);
1386                         phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] =
1387                                 phy_sta_rpt->gid;
1388                 }
1389
1390         } else {
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] =
1394                                 date_rate;
1395                         phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] =
1396                                 phy_sta_rpt->gid;
1397                 }
1398         }
1399 }
1400
1401 static void phydm_reset_phy_info(struct phy_dm_struct *phydm,
1402                                  struct dm_phy_status_info *phy_info)
1403 {
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);
1411
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;
1420         phy_info->rxsc = 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);
1425 }
1426
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)
1430 {
1431         u8 evm_dbm = 0;
1432         u8 evm_percentage = 0;
1433
1434         /* SNR is S(8,1), EVM is S(8,1), CFO is S(8,7) */
1435
1436         if (rx_evm < 0) {
1437                 /* Calculate EVM in dBm */
1438                 evm_dbm = ((u8)(0 - rx_evm) >> 1);
1439
1440                 /* Calculate EVM in percentage */
1441                 if (evm_dbm >= 33)
1442                         evm_percentage = 100;
1443                 else
1444                         evm_percentage = (evm_dbm << 1) + (evm_dbm);
1445         }
1446
1447         phy_info->rx_pwr[rx_path] = rx_pwr;
1448         phy_info->rx_mimo_evm_dbm[rx_path] = evm_dbm;
1449
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])) >>
1456                                       9;
1457
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;
1462 }
1463
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)
1468 {
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 */
1479 }
1480
1481 static void phydm_get_rx_phy_status_type0(struct phy_dm_struct *dm,
1482                                           u8 *phy_status,
1483                                           struct dm_per_pkt_info *pktinfo,
1484                                           struct dm_phy_status_info *phy_info)
1485 {
1486         /* type 0 is used for cck packet */
1487
1488         struct phy_status_rpt_jaguar2_type0 *phy_sta_rpt =
1489                 (struct phy_status_rpt_jaguar2_type0 *)phy_status;
1490         u8 sq = 0;
1491         s8 rx_power = phy_sta_rpt->pwdb - 110;
1492
1493         /* JJ ADD 20161014 */
1494
1495         /* Calculate Signal Quality*/
1496         if (pktinfo->is_packet_match_bssid) {
1497                 if (phy_sta_rpt->signal_quality >= 64) {
1498                         sq = 0;
1499                 } else if (phy_sta_rpt->signal_quality <= 20) {
1500                         sq = 100;
1501                 } else {
1502                         /* mapping to 2~99% */
1503                         sq = 64 - phy_sta_rpt->signal_quality;
1504                         sq = ((sq << 3) + sq) >> 2;
1505                 }
1506         }
1507
1508         /* Modify CCK PWDB if old AGC */
1509         if (!dm->cck_new_agc) {
1510                 u8 lna_idx, vga_idx;
1511
1512                 lna_idx = ((phy_sta_rpt->lna_h << 3) | phy_sta_rpt->lna_l);
1513                 vga_idx = phy_sta_rpt->vga;
1514
1515                 /* JJ ADD 20161014 */
1516
1517                 /* Need to do !! */
1518                 /*if (dm->support_ic_type & ODM_RTL8822B) */
1519                 /*rx_power = odm_CCKRSSI_8822B(LNA_idx, VGA_idx);*/
1520         }
1521
1522         /* Update CCK packet counter */
1523         dm->phy_dbg_info.num_qry_phy_status_cck++;
1524
1525         /*CCK no STBC and LDPC*/
1526         dm->phy_dbg_info.is_ldpc_pkt = false;
1527         dm->phy_dbg_info.is_stbc_pkt = false;
1528
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);
1532
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);
1536
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;
1541 }
1542
1543 static void phydm_get_rx_phy_status_type1(struct phy_dm_struct *dm,
1544                                           u8 *phy_status,
1545                                           struct dm_per_pkt_info *pktinfo,
1546                                           struct dm_phy_status_info *phy_info)
1547 {
1548         /* type 1 is used for ofdm packet */
1549
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;
1554         bool is_mu;
1555         u8 num_ss;
1556
1557         /* Update OFDM packet counter */
1558         dm->phy_dbg_info.num_qry_phy_status_ofdm++;
1559
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)) {
1563                         s8 rx_path_pwr_db;
1564
1565                         /* RX path counter */
1566                         rx_count++;
1567
1568                         /* Update per-path information
1569                          * (RSSI_dB RSSI_percentage EVM SNR CFO sq)
1570                          */
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(
1575                                 i, rx_path_pwr_db,
1576                                 phy_sta_rpt->rxevm[rx_count - 1],
1577                                 phy_sta_rpt->cfo_tail[i], phy_sta_rpt->rxsnr[i],
1578                                 phy_info);
1579
1580                         /* search maximum pwdb */
1581                         if (rx_path_pwr_db > rx_pwr_db)
1582                                 rx_pwr_db = rx_path_pwr_db;
1583                 }
1584         }
1585
1586         /* mapping RX counter from 1~4 to 0~3 */
1587         if (rx_count > 0)
1588                 phy_info->rx_count = rx_count - 1;
1589
1590         /* Check if MU packet or not */
1591         if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) {
1592                 is_mu = true;
1593                 dm->phy_dbg_info.num_qry_mu_pkt++;
1594         } else {
1595                 is_mu = false;
1596         }
1597
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;
1601
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;
1605
1606         /* Check sub-channel */
1607         if ((pktinfo->data_rate > ODM_RATE11M) &&
1608             (pktinfo->data_rate < ODM_RATEMCS0))
1609                 rxsc = phy_sta_rpt->l_rxsc;
1610         else
1611                 rxsc = phy_sta_rpt->ht_rxsc;
1612
1613         /* Check RX bandwidth */
1614         if (dm->support_ic_type & ODM_RTL8822B) {
1615                 if ((rxsc >= 1) && (rxsc <= 8))
1616                         bw = ODM_BW20M;
1617                 else if ((rxsc >= 9) && (rxsc <= 12))
1618                         bw = ODM_BW40M;
1619                 else if (rxsc >= 13)
1620                         bw = ODM_BW80M;
1621                 else
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)
1626                         bw = ODM_BW20M;
1627                 else if ((rxsc == 1) || (rxsc == 2))
1628                         bw = ODM_BW20M;
1629                 else
1630                         bw = ODM_BW40M;
1631         }
1632
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]),
1637                 rxsc, phy_info);
1638
1639         num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
1640
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;
1646
1647         if (pktinfo->is_packet_match_bssid) {
1648                 /* */
1649                 phydm_rx_statistic_cal(dm, phy_status, pktinfo);
1650         }
1651 }
1652
1653 static void phydm_get_rx_phy_status_type2(struct phy_dm_struct *dm,
1654                                           u8 *phy_status,
1655                                           struct dm_per_pkt_info *pktinfo,
1656                                           struct dm_phy_status_info *phy_info)
1657 {
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;
1662
1663         /* Update OFDM packet counter */
1664         dm->phy_dbg_info.num_qry_phy_status_ofdm++;
1665
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)) {
1669                         s8 rx_path_pwr_db;
1670
1671                         /* RX path counter */
1672                         rx_count++;
1673
1674                         /* Update per-path information
1675                          * (RSSI_dB RSSI_percentage EVM SNR CFO sq)
1676                          */
1677                         rx_path_pwr_db = phy_sta_rpt->pwdb[i] -
1678                                          110; /* per-path pwdb in dB domain */
1679
1680                         phydm_set_per_path_phy_info(i, rx_path_pwr_db, 0, 0, 0,
1681                                                     phy_info);
1682
1683                         /* search maximum pwdb */
1684                         if (rx_path_pwr_db > rx_pwr_db)
1685                                 rx_pwr_db = rx_path_pwr_db;
1686                 }
1687         }
1688
1689         /* mapping RX counter from 1~4 to 0~3 */
1690         if (rx_count > 0)
1691                 phy_info->rx_count = rx_count - 1;
1692
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;
1697         else
1698                 rxsc = phy_sta_rpt->ht_rxsc;
1699
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;
1703
1704         /* Check RX bandwidth */
1705         /* the BW information of sc=0 is useless, because there is
1706          * no information of RF mode
1707          */
1708
1709         if (dm->support_ic_type & ODM_RTL8822B) {
1710                 if ((rxsc >= 1) && (rxsc <= 8))
1711                         bw = ODM_BW20M;
1712                 else if ((rxsc >= 9) && (rxsc <= 12))
1713                         bw = ODM_BW40M;
1714                 else if (rxsc >= 13)
1715                         bw = ODM_BW80M;
1716                 else
1717                         bw = ODM_BW20M;
1718         } else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D |
1719                                           ODM_RTL8710B)) { /* JJ ADD 20161014 */
1720                 if (rxsc == 3)
1721                         bw = ODM_BW40M;
1722                 else
1723                         bw = ODM_BW20M;
1724         }
1725
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,
1729                                   rxsc, phy_info);
1730 }
1731
1732 static void
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)
1736 {
1737         s32 undecorated_smoothed_pwdb, accumulate_pwdb;
1738         u32 rssi_ave;
1739         u8 i;
1740         struct rtl_sta_info *entry;
1741         u8 scaling_factor = 4;
1742
1743         if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM)
1744                 return;
1745
1746         entry = dm->odm_sta_info[pktinfo->station_id];
1747
1748         if (!IS_STA_VALID(entry))
1749                 return;
1750
1751         if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/
1752                 return;
1753
1754         if (pktinfo->is_packet_beacon)
1755                 dm->phy_dbg_info.num_qry_beacon_pkt++;
1756
1757         if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) {
1758                 u32 rssi_linear = 0;
1759
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];
1768
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]);
1773                 }
1774
1775                 switch (phy_info->rx_count + 1) {
1776                 case 2:
1777                         rssi_linear = (rssi_linear >> 1);
1778                         break;
1779                 case 3:
1780                         /* rssi_linear/3 ~ rssi_linear*11/32 */
1781                         rssi_linear = ((rssi_linear) + (rssi_linear << 1) +
1782                                        (rssi_linear << 3)) >>
1783                                       5;
1784                         break;
1785                 case 4:
1786                         rssi_linear = (rssi_linear >> 2);
1787                         break;
1788                 }
1789                 rssi_ave = odm_convert_to_db(rssi_linear);
1790
1791                 if (undecorated_smoothed_pwdb <= 0) {
1792                         accumulate_pwdb =
1793                                 (phy_info->rx_pwdb_all << scaling_factor);
1794                         undecorated_smoothed_pwdb = phy_info->rx_pwdb_all;
1795                 } else {
1796                         accumulate_pwdb = accumulate_pwdb -
1797                                           (accumulate_pwdb >> scaling_factor) +
1798                                           rssi_ave;
1799                         undecorated_smoothed_pwdb =
1800                                 (accumulate_pwdb +
1801                                  (1 << (scaling_factor - 1))) >>
1802                                 scaling_factor;
1803                 }
1804
1805                 entry->rssi_stat.undecorated_smoothed_pwdb =
1806                         undecorated_smoothed_pwdb;
1807                 dm->accumulate_pwdb[pktinfo->station_id] = accumulate_pwdb;
1808         }
1809 }
1810
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)
1814 {
1815         u8 phy_status_type = (*phy_status & 0xf);
1816
1817         /* Memory reset */
1818         phydm_reset_phy_info(phydm, phy_info);
1819
1820         /* Phy status parsing */
1821         switch (phy_status_type) {
1822         case 0: {
1823                 phydm_get_rx_phy_status_type0(phydm, phy_status, pktinfo,
1824                                               phy_info);
1825                 break;
1826         }
1827         case 1: {
1828                 phydm_get_rx_phy_status_type1(phydm, phy_status, pktinfo,
1829                                               phy_info);
1830                 break;
1831         }
1832         case 2: {
1833                 phydm_get_rx_phy_status_type2(phydm, phy_status, pktinfo,
1834                                               phy_info);
1835                 break;
1836         }
1837         default:
1838                 return;
1839         }
1840
1841         /* Update signal strength to UI, and phy_info->rx_pwdb_all is the
1842          * maximum RSSI of all path
1843          */
1844         phy_info->signal_strength = phy_info->rx_pwdb_all;
1845
1846         /* Calculate average RSSI and smoothed RSSI */
1847         phydm_process_rssi_for_dm_new_type(phydm, phy_info, pktinfo);
1848 }