GNU Linux-libre 4.19.286-gnu1
[releases.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 ==
49             64) { /* 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 /*
481  * 2012/01/12 MH MOve some signal strength smooth method to MP HAL layer.
482  * IF other SW team do not support the feature, remove this section.??
483  */
484
485 s32 odm_signal_scale_mapping(struct phy_dm_struct *dm, s32 curr_sig)
486 {
487         {
488                 return curr_sig;
489         }
490 }
491
492 static u8 odm_sq_process_patch_rt_cid_819x_lenovo(struct phy_dm_struct *dm,
493                                                   u8 is_cck_rate, u8 pwdb_all,
494                                                   u8 path, u8 RSSI)
495 {
496         u8 sq = 0;
497         return sq;
498 }
499
500 static u8 odm_evm_db_to_percentage(s8 value)
501 {
502         /* -33dB~0dB to 0%~99% */
503         s8 ret_val;
504
505         ret_val = value;
506         ret_val /= 2;
507
508         if (ret_val >= 0)
509                 ret_val = 0;
510
511         if (ret_val <= -33)
512                 ret_val = -33;
513
514         ret_val = 0 - ret_val;
515         ret_val *= 3;
516
517         if (ret_val == 99)
518                 ret_val = 100;
519
520         return (u8)ret_val;
521 }
522
523 static u8 odm_evm_dbm_jaguar_series(s8 value)
524 {
525         s8 ret_val = value;
526
527         /* -33dB~0dB to 33dB ~ 0dB */
528         if (ret_val == -128)
529                 ret_val = 127;
530         else if (ret_val < 0)
531                 ret_val = 0 - ret_val;
532
533         ret_val = ret_val >> 1;
534         return (u8)ret_val;
535 }
536
537 static s16 odm_cfo(s8 value)
538 {
539         s16 ret_val;
540
541         if (value < 0) {
542                 ret_val = 0 - value;
543                 ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */
544                 ret_val =
545                         ret_val | BIT(12); /* set bit12 as 1 for negative cfo */
546         } else {
547                 ret_val = value;
548                 ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */
549         }
550         return ret_val;
551 }
552
553 static u8 phydm_rate_to_num_ss(struct phy_dm_struct *dm, u8 data_rate)
554 {
555         u8 num_ss = 1;
556
557         if (data_rate <= ODM_RATE54M)
558                 num_ss = 1;
559         else if (data_rate <= ODM_RATEMCS31)
560                 num_ss = ((data_rate - ODM_RATEMCS0) >> 3) + 1;
561         else if (data_rate <= ODM_RATEVHTSS1MCS9)
562                 num_ss = 1;
563         else if (data_rate <= ODM_RATEVHTSS2MCS9)
564                 num_ss = 2;
565         else if (data_rate <= ODM_RATEVHTSS3MCS9)
566                 num_ss = 3;
567         else if (data_rate <= ODM_RATEVHTSS4MCS9)
568                 num_ss = 4;
569
570         return num_ss;
571 }
572
573 static void odm_rx_phy_status92c_series_parsing(
574         struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
575         u8 *phy_status, struct dm_per_pkt_info *pktinfo)
576 {
577         u8 i, max_spatial_stream;
578         s8 rx_pwr[4], rx_pwr_all = 0;
579         u8 EVM, pwdb_all = 0, pwdb_all_bt;
580         u8 RSSI, total_rssi = 0;
581         bool is_cck_rate = false;
582         u8 rf_rx_num = 0;
583         u8 LNA_idx = 0;
584         u8 VGA_idx = 0;
585         u8 cck_agc_rpt;
586         u8 num_ss;
587         struct phy_status_rpt_8192cd *phy_sta_rpt =
588                 (struct phy_status_rpt_8192cd *)phy_status;
589
590         is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false;
591
592         if (pktinfo->is_to_self)
593                 dm->curr_station_id = pktinfo->station_id;
594
595         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1;
596         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
597
598         if (is_cck_rate) {
599                 dm->phy_dbg_info.num_qry_phy_status_cck++;
600                 cck_agc_rpt = phy_sta_rpt->cck_agc_rpt_ofdm_cfosho_a;
601
602                 if (dm->support_ic_type & (ODM_RTL8703B)) {
603                 } else { /*3 bit LNA*/
604
605                         LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
606                         VGA_idx = (cck_agc_rpt & 0x1F);
607                 }
608
609                 ODM_RT_TRACE(
610                         dm, ODM_COMP_RSSI_MONITOR,
611                         "ext_lna_gain (( %d )), LNA_idx: (( 0x%x )), VGA_idx: (( 0x%x )), rx_pwr_all: (( %d ))\n",
612                         dm->ext_lna_gain, LNA_idx, VGA_idx, rx_pwr_all);
613
614                 if (dm->board_type & ODM_BOARD_EXT_LNA)
615                         rx_pwr_all -= dm->ext_lna_gain;
616
617                 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
618
619                 if (pktinfo->is_to_self) {
620                         dm->cck_lna_idx = LNA_idx;
621                         dm->cck_vga_idx = VGA_idx;
622                 }
623                 phy_info->rx_pwdb_all = pwdb_all;
624
625                 phy_info->bt_rx_rssi_percentage = pwdb_all;
626                 phy_info->recv_signal_power = rx_pwr_all;
627                 /* (3) Get Signal Quality (EVM) */
628                 {
629                         u8 sq;
630
631                         sq = phydm_get_signal_quality_8192(phy_info, dm,
632                                                            phy_sta_rpt);
633                         phy_info->signal_quality = sq;
634                         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq;
635                         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
636                 }
637
638                 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) {
639                         if (i == 0)
640                                 phy_info->rx_mimo_signal_strength[0] = pwdb_all;
641                         else
642                                 phy_info->rx_mimo_signal_strength[1] = 0;
643                 }
644         } else { /* 2 is OFDM rate */
645                 dm->phy_dbg_info.num_qry_phy_status_ofdm++;
646
647                 /*  */
648                 /* (1)Get RSSI for HT rate */
649                 /*  */
650
651                 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) {
652                         /* 2008/01/30 MH we will judge RF RX path now. */
653                         if (dm->rf_path_rx_enable & BIT(i))
654                                 rf_rx_num++;
655                         /* else */
656                         /* continue; */
657
658                         rx_pwr[i] =
659                                 ((phy_sta_rpt->path_agc[i].gain & 0x3F) * 2) -
660                                 110;
661
662                         if (pktinfo->is_to_self) {
663                                 dm->ofdm_agc_idx[i] =
664                                         (phy_sta_rpt->path_agc[i].gain & 0x3F);
665                                 /**/
666                         }
667
668                         phy_info->rx_pwr[i] = rx_pwr[i];
669
670                         /* Translate DBM to percentage. */
671                         RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]);
672                         total_rssi += RSSI;
673
674                         phy_info->rx_mimo_signal_strength[i] = (u8)RSSI;
675
676                         /* Get Rx snr value in DB */
677                         dm->phy_dbg_info.rx_snr_db[i] =
678                                 (s32)(phy_sta_rpt->path_rxsnr[i] / 2);
679                         phy_info->rx_snr[i] = dm->phy_dbg_info.rx_snr_db[i];
680
681                         /* Record Signal Strength for next packet */
682                         /* if(pktinfo->is_packet_match_bssid) */
683                         {
684                         }
685                 }
686
687                 /*  */
688                 /* (2)PWDB, Average PWDB calcuated by hardware (for RA) */
689                 /*  */
690                 rx_pwr_all = (((phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all) >> 1) &
691                               0x7f) -
692                              110;
693
694                 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
695                 pwdb_all_bt = pwdb_all;
696
697                 phy_info->rx_pwdb_all = pwdb_all;
698                 phy_info->bt_rx_rssi_percentage = pwdb_all_bt;
699                 phy_info->rx_power = rx_pwr_all;
700                 phy_info->recv_signal_power = rx_pwr_all;
701
702                 if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) {
703                         /* do nothing */
704                 } else if ((dm->support_platform == ODM_WIN) &&
705                            (dm->patch_id == 25)) {
706                         /* do nothing */
707                 } else { /* mgnt_info->customer_id != RT_CID_819X_LENOVO */
708                         /*  */
709                         /* (3)EVM of HT rate */
710                         /*  */
711                         if (pktinfo->data_rate >= ODM_RATEMCS8 &&
712                             pktinfo->data_rate <= ODM_RATEMCS15) {
713                                 /* both spatial stream make sense */
714                                 max_spatial_stream = 2;
715                         } else {
716                                 /* only spatial stream 1 makes sense */
717                                 max_spatial_stream = 1;
718                         }
719
720                         for (i = 0; i < max_spatial_stream; i++) {
721                                 /*Don't use shift operation like "rx_evmX >>= 1"
722                                  *because the compilor of free build environment
723                                  *fill most significant bit to "zero" when doing
724                                  *shifting operation which may change a negative
725                                  *value to positive one, then the dbm value
726                                  *(which is supposed to be negative)  is not
727                                  *correct anymore.
728                                  */
729                                 EVM = odm_evm_db_to_percentage(
730                                         (phy_sta_rpt
731                                                  ->stream_rxevm[i])); /* dbm */
732
733                                 /* Fill value in RFD, Get the first spatial
734                                  * stream only
735                                  */
736                                 if (i == ODM_RF_PATH_A)
737                                         phy_info->signal_quality =
738                                                 (u8)(EVM & 0xff);
739                                 phy_info->rx_mimo_signal_quality[i] =
740                                         (u8)(EVM & 0xff);
741                         }
742                 }
743
744                 num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
745                 odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->path_cfotail, num_ss);
746         }
747         /* UI BSS List signal strength(in percentage), make it good looking,
748          * from 0~100.
749          */
750         /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */
751         if (is_cck_rate) {
752                 phy_info->signal_strength = (u8)(
753                         odm_signal_scale_mapping(dm, pwdb_all)); /*pwdb_all;*/
754         } else {
755                 if (rf_rx_num != 0) {
756                         phy_info->signal_strength =
757                                 (u8)(odm_signal_scale_mapping(dm, total_rssi /=
758                                                                   rf_rx_num));
759                 }
760         }
761
762         /* For 92C/92D HW (Hybrid) Antenna Diversity */
763 }
764
765 static void
766 odm_rx_phy_bw_jaguar_series_parsing(struct dm_phy_status_info *phy_info,
767                                     struct dm_per_pkt_info *pktinfo,
768                                     struct phy_status_rpt_8812 *phy_sta_rpt)
769 {
770         if (pktinfo->data_rate <= ODM_RATE54M) {
771                 switch (phy_sta_rpt->r_RFMOD) {
772                 case 1:
773                         if (phy_sta_rpt->sub_chnl == 0)
774                                 phy_info->band_width = 1;
775                         else
776                                 phy_info->band_width = 0;
777                         break;
778
779                 case 2:
780                         if (phy_sta_rpt->sub_chnl == 0)
781                                 phy_info->band_width = 2;
782                         else if (phy_sta_rpt->sub_chnl == 9 ||
783                                  phy_sta_rpt->sub_chnl == 10)
784                                 phy_info->band_width = 1;
785                         else
786                                 phy_info->band_width = 0;
787                         break;
788
789                 default:
790                 case 0:
791                         phy_info->band_width = 0;
792                         break;
793                 }
794         }
795 }
796
797 static void odm_rx_phy_status_jaguar_series_parsing(
798         struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
799         u8 *phy_status, struct dm_per_pkt_info *pktinfo)
800 {
801         u8 i, max_spatial_stream;
802         s8 rx_pwr[4], rx_pwr_all = 0;
803         u8 EVM = 0, evm_dbm, pwdb_all = 0, pwdb_all_bt;
804         u8 RSSI, avg_rssi = 0, best_rssi = 0, second_rssi = 0;
805         u8 is_cck_rate = 0;
806         u8 rf_rx_num = 0;
807         u8 cck_highpwr = 0;
808         u8 LNA_idx, VGA_idx;
809         struct phy_status_rpt_8812 *phy_sta_rpt =
810                 (struct phy_status_rpt_8812 *)phy_status;
811         struct fast_antenna_training *fat_tab = &dm->dm_fat_table;
812         u8 num_ss;
813
814         odm_rx_phy_bw_jaguar_series_parsing(phy_info, pktinfo, phy_sta_rpt);
815
816         if (pktinfo->data_rate <= ODM_RATE11M)
817                 is_cck_rate = true;
818         else
819                 is_cck_rate = false;
820
821         if (pktinfo->is_to_self)
822                 dm->curr_station_id = pktinfo->station_id;
823         else
824                 dm->curr_station_id = 0xff;
825
826         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1;
827         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
828         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_C] = -1;
829         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_D] = -1;
830
831         if (is_cck_rate) {
832                 u8 cck_agc_rpt;
833
834                 dm->phy_dbg_info.num_qry_phy_status_cck++;
835
836                 /*(1)Hardware does not provide RSSI for CCK*/
837                 /*(2)PWDB, Average PWDB calculated by hardware (for RA)*/
838
839                 cck_highpwr = dm->is_cck_high_power;
840
841                 cck_agc_rpt = phy_sta_rpt->cfosho[0];
842                 LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
843                 VGA_idx = (cck_agc_rpt & 0x1F);
844
845                 if (dm->support_ic_type == ODM_RTL8812) {
846                         rx_pwr_all =
847                                 phydm_get_rx_pwr(LNA_idx, VGA_idx, cck_highpwr);
848                         rx_pwr_all += 6;
849                         pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
850                         pwdb_all = phydm_adjust_pwdb(cck_highpwr, pwdb_all);
851
852                 } else if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
853                         s8 pout = -6;
854
855                         switch (LNA_idx) {
856                         case 5:
857                                 rx_pwr_all = pout - 32 - (2 * VGA_idx);
858                                 break;
859                         case 4:
860                                 rx_pwr_all = pout - 24 - (2 * VGA_idx);
861                                 break;
862                         case 2:
863                                 rx_pwr_all = pout - 11 - (2 * VGA_idx);
864                                 break;
865                         case 1:
866                                 rx_pwr_all = pout + 5 - (2 * VGA_idx);
867                                 break;
868                         case 0:
869                                 rx_pwr_all = pout + 21 - (2 * VGA_idx);
870                                 break;
871                         }
872                         pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
873                 } else if (dm->support_ic_type == ODM_RTL8814A ||
874                            dm->support_ic_type == ODM_RTL8822B) {
875                         s8 pout = -6;
876
877                         switch (LNA_idx) {
878                         /*CCK only use LNA: 2, 3, 5, 7*/
879                         case 7:
880                                 rx_pwr_all = pout - 32 - (2 * VGA_idx);
881                                 break;
882                         case 5:
883                                 rx_pwr_all = pout - 22 - (2 * VGA_idx);
884                                 break;
885                         case 3:
886                                 rx_pwr_all = pout - 2 - (2 * VGA_idx);
887                                 break;
888                         case 2:
889                                 rx_pwr_all = pout + 5 - (2 * VGA_idx);
890                                 break;
891                         default:
892                                 break;
893                         }
894                         pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
895                 }
896
897                 dm->cck_lna_idx = LNA_idx;
898                 dm->cck_vga_idx = VGA_idx;
899                 phy_info->rx_pwdb_all = pwdb_all;
900                 phy_info->bt_rx_rssi_percentage = pwdb_all;
901                 phy_info->recv_signal_power = rx_pwr_all;
902                 /*(3) Get Signal Quality (EVM)*/
903                 {
904                         u8 sq;
905
906                         if ((dm->support_platform == ODM_WIN) &&
907                             (dm->patch_id == RT_CID_819X_LENOVO))
908                                 sq = odm_sq_process_patch_rt_cid_819x_lenovo(
909                                         dm, is_cck_rate, pwdb_all, 0, 0);
910                         else
911                                 sq = phydm_get_signal_quality_8812(phy_info, dm,
912                                                                    phy_sta_rpt);
913
914                         phy_info->signal_quality = sq;
915                         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq;
916                 }
917
918                 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
919                         if (i == 0)
920                                 phy_info->rx_mimo_signal_strength[0] = pwdb_all;
921                         else
922                                 phy_info->rx_mimo_signal_strength[i] = 0;
923                 }
924         } else {
925                 /*is OFDM rate*/
926                 fat_tab->hw_antsw_occur = phy_sta_rpt->hw_antsw_occur;
927
928                 dm->phy_dbg_info.num_qry_phy_status_ofdm++;
929
930                 /*(1)Get RSSI for OFDM rate*/
931
932                 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
933                         /*2008/01/30 MH we will judge RF RX path now.*/
934                         if (dm->rf_path_rx_enable & BIT(i))
935                                 rf_rx_num++;
936                         /*2012.05.25 LukeLee: Testchip AGC report is wrong,
937                          *it should be restored back to old formula in MP chip
938                          */
939                         if (i < ODM_RF_PATH_C)
940                                 rx_pwr[i] = (phy_sta_rpt->gain_trsw[i] & 0x7F) -
941                                             110;
942                         else
943                                 rx_pwr[i] = (phy_sta_rpt->gain_trsw_cd[i - 2] &
944                                              0x7F) -
945                                             110;
946
947                         phy_info->rx_pwr[i] = rx_pwr[i];
948
949                         /* Translate DBM to percentage. */
950                         RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]);
951
952                         /*total_rssi += RSSI;*/
953                         /*Get the best two RSSI*/
954                         if (RSSI > best_rssi && RSSI > second_rssi) {
955                                 second_rssi = best_rssi;
956                                 best_rssi = RSSI;
957                         } else if (RSSI > second_rssi && RSSI <= best_rssi) {
958                                 second_rssi = RSSI;
959                         }
960
961                         phy_info->rx_mimo_signal_strength[i] = (u8)RSSI;
962
963                         /*Get Rx snr value in DB*/
964                         if (i < ODM_RF_PATH_C)
965                                 phy_info->rx_snr[i] =
966                                         dm->phy_dbg_info.rx_snr_db[i] =
967                                                 phy_sta_rpt->rxsnr[i] / 2;
968                         else if (dm->support_ic_type &
969                                  (ODM_RTL8814A | ODM_RTL8822B))
970                                 phy_info->rx_snr[i] = dm->phy_dbg_info
971                                                               .rx_snr_db[i] =
972                                         phy_sta_rpt->csi_current[i - 2] / 2;
973
974                         /*(2) CFO_short  & CFO_tail*/
975                         if (i < ODM_RF_PATH_C) {
976                                 phy_info->cfo_short[i] =
977                                         odm_cfo((phy_sta_rpt->cfosho[i]));
978                                 phy_info->cfo_tail[i] =
979                                         odm_cfo((phy_sta_rpt->cfotail[i]));
980                         }
981                 }
982
983                 /*(3)PWDB, Average PWDB calculated by hardware (for RA)*/
984
985                 /*2012.05.25 LukeLee: Testchip AGC report is wrong, it should be
986                  *restored back to old formula in MP chip
987                  */
988                 if ((dm->support_ic_type &
989                      (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) &&
990                     (!dm->is_mp_chip))
991                         rx_pwr_all = (phy_sta_rpt->pwdb_all & 0x7f) - 110;
992                 else
993                         rx_pwr_all = (((phy_sta_rpt->pwdb_all) >> 1) & 0x7f) -
994                                      110; /*OLD FORMULA*/
995
996                 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
997                 pwdb_all_bt = pwdb_all;
998
999                 phy_info->rx_pwdb_all = pwdb_all;
1000                 phy_info->bt_rx_rssi_percentage = pwdb_all_bt;
1001                 phy_info->rx_power = rx_pwr_all;
1002                 phy_info->recv_signal_power = rx_pwr_all;
1003
1004                 if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) {
1005                         /*do nothing*/
1006                 } else {
1007                         /*mgnt_info->customer_id != RT_CID_819X_LENOVO*/
1008
1009                         /*(4)EVM of OFDM rate*/
1010
1011                         if ((pktinfo->data_rate >= ODM_RATEMCS8) &&
1012                             (pktinfo->data_rate <= ODM_RATEMCS15))
1013                                 max_spatial_stream = 2;
1014                         else if ((pktinfo->data_rate >= ODM_RATEVHTSS2MCS0) &&
1015                                  (pktinfo->data_rate <= ODM_RATEVHTSS2MCS9))
1016                                 max_spatial_stream = 2;
1017                         else if ((pktinfo->data_rate >= ODM_RATEMCS16) &&
1018                                  (pktinfo->data_rate <= ODM_RATEMCS23))
1019                                 max_spatial_stream = 3;
1020                         else if ((pktinfo->data_rate >= ODM_RATEVHTSS3MCS0) &&
1021                                  (pktinfo->data_rate <= ODM_RATEVHTSS3MCS9))
1022                                 max_spatial_stream = 3;
1023                         else
1024                                 max_spatial_stream = 1;
1025
1026                         for (i = 0; i < max_spatial_stream; i++) {
1027                                 /*Don't use shift operation like "rx_evmX >>= 1"
1028                                  *because the compilor of free build environment
1029                                  *fill most significant bit to "zero" when doing
1030                                  *shifting operation which may change a negative
1031                                  *value to positive one, then the dbm value
1032                                  *(which is supposed to be negative) is not
1033                                  *correct anymore.
1034                                  */
1035
1036                                 EVM = phydm_get_odm_evm(i, pktinfo,
1037                                                         phy_sta_rpt);
1038                                 evm_dbm = phydm_get_evm_dbm(i, EVM, phy_sta_rpt,
1039                                                             phy_info);
1040                                 phy_info->rx_mimo_signal_quality[i] = EVM;
1041                                 phy_info->rx_mimo_evm_dbm[i] = evm_dbm;
1042                         }
1043                 }
1044
1045                 num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
1046                 odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfotail, num_ss);
1047         }
1048
1049         /*UI BSS List signal strength(in percentage), make it good looking,
1050          *from 0~100.
1051          */
1052         /*It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().*/
1053         if (is_cck_rate) {
1054                 phy_info->signal_strength = (u8)(
1055                         odm_signal_scale_mapping(dm, pwdb_all)); /*pwdb_all;*/
1056         } else {
1057                 if (rf_rx_num != 0) {
1058                         /* 2015/01 Sean, use the best two RSSI only,
1059                          * suggested by Ynlin and ChenYu.
1060                          */
1061                         if (rf_rx_num == 1)
1062                                 avg_rssi = best_rssi;
1063                         else
1064                                 avg_rssi = (best_rssi + second_rssi) / 2;
1065                         phy_info->signal_strength =
1066                                 (u8)(odm_signal_scale_mapping(dm, avg_rssi));
1067                 }
1068         }
1069         dm->rx_pwdb_ave = dm->rx_pwdb_ave + phy_info->rx_pwdb_all;
1070
1071         dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_anta;
1072         dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_antb;
1073         dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_antc;
1074         dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_antd;
1075 }
1076
1077 void phydm_reset_rssi_for_dm(struct phy_dm_struct *dm, u8 station_id)
1078 {
1079         struct rtl_sta_info *entry;
1080
1081         entry = dm->odm_sta_info[station_id];
1082
1083         if (!IS_STA_VALID(entry))
1084                 return;
1085
1086         ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
1087                      "Reset RSSI for macid = (( %d ))\n", station_id);
1088
1089         entry->rssi_stat.undecorated_smoothed_cck = -1;
1090         entry->rssi_stat.undecorated_smoothed_ofdm = -1;
1091         entry->rssi_stat.undecorated_smoothed_pwdb = -1;
1092         entry->rssi_stat.ofdm_pkt = 0;
1093         entry->rssi_stat.cck_pkt = 0;
1094         entry->rssi_stat.cck_sum_power = 0;
1095         entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_INIT;
1096         entry->rssi_stat.packet_map = 0;
1097         entry->rssi_stat.valid_bit = 0;
1098 }
1099
1100 void odm_init_rssi_for_dm(struct phy_dm_struct *dm) {}
1101
1102 static void odm_process_rssi_for_dm(struct phy_dm_struct *dm,
1103                                     struct dm_phy_status_info *phy_info,
1104                                     struct dm_per_pkt_info *pktinfo)
1105 {
1106         s32 undecorated_smoothed_pwdb, undecorated_smoothed_cck,
1107                 undecorated_smoothed_ofdm;
1108         u8 is_cck_rate = 0;
1109         u8 send_rssi_2_fw = 0;
1110         struct rtl_sta_info *entry;
1111
1112         if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM)
1113                 return;
1114
1115         /* 2012/05/30 MH/Luke.Lee Add some description */
1116         /* In windows driver: AP/IBSS mode STA */
1117         entry = dm->odm_sta_info[pktinfo->station_id];
1118
1119         if (!IS_STA_VALID(entry))
1120                 return;
1121
1122         {
1123                 if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/
1124                         return;
1125         }
1126
1127         if (pktinfo->is_packet_beacon)
1128                 dm->phy_dbg_info.num_qry_beacon_pkt++;
1129
1130         is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false;
1131         dm->rx_rate = pktinfo->data_rate;
1132
1133         /* --------------Statistic for antenna/path diversity---------------- */
1134
1135         /* -----------------Smart Antenna Debug Message------------------ */
1136
1137         undecorated_smoothed_cck = entry->rssi_stat.undecorated_smoothed_cck;
1138         undecorated_smoothed_ofdm = entry->rssi_stat.undecorated_smoothed_ofdm;
1139         undecorated_smoothed_pwdb = entry->rssi_stat.undecorated_smoothed_pwdb;
1140
1141         if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) {
1142                 if (!is_cck_rate) /* ofdm rate */
1143                         undecorated_smoothed_ofdm = phydm_process_rssi_ofdm(
1144                                 dm, phy_info, entry, undecorated_smoothed_ofdm);
1145                 else
1146                         undecorated_smoothed_cck = phydm_process_rssi_cck(
1147                                 dm, phy_info, entry, undecorated_smoothed_cck);
1148
1149                 undecorated_smoothed_pwdb = phydm_process_rssi_pwdb(
1150                         dm, entry, pktinfo, undecorated_smoothed_ofdm,
1151                         undecorated_smoothed_cck);
1152
1153                 if ((entry->rssi_stat.ofdm_pkt >= 1 ||
1154                      entry->rssi_stat.cck_pkt >= 5) &&
1155                     (entry->rssi_stat.is_send_rssi == RA_RSSI_STATE_INIT)) {
1156                         send_rssi_2_fw = 1;
1157                         entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_SEND;
1158                 }
1159
1160                 entry->rssi_stat.undecorated_smoothed_cck =
1161                         undecorated_smoothed_cck;
1162                 entry->rssi_stat.undecorated_smoothed_ofdm =
1163                         undecorated_smoothed_ofdm;
1164                 entry->rssi_stat.undecorated_smoothed_pwdb =
1165                         undecorated_smoothed_pwdb;
1166
1167                 if (send_rssi_2_fw) { /* Trigger init rate by RSSI */
1168
1169                         if (entry->rssi_stat.ofdm_pkt != 0)
1170                                 entry->rssi_stat.undecorated_smoothed_pwdb =
1171                                         undecorated_smoothed_ofdm;
1172
1173                         ODM_RT_TRACE(
1174                                 dm, ODM_COMP_RSSI_MONITOR,
1175                                 "[Send to FW] PWDB = (( %d )), ofdm_pkt = (( %d )), cck_pkt = (( %d ))\n",
1176                                 undecorated_smoothed_pwdb,
1177                                 entry->rssi_stat.ofdm_pkt,
1178                                 entry->rssi_stat.cck_pkt);
1179                 }
1180         }
1181 }
1182
1183 /*
1184  * Endianness before calling this API
1185  */
1186 static void odm_phy_status_query_92c_series(struct phy_dm_struct *dm,
1187                                             struct dm_phy_status_info *phy_info,
1188                                             u8 *phy_status,
1189                                             struct dm_per_pkt_info *pktinfo)
1190 {
1191         odm_rx_phy_status92c_series_parsing(dm, phy_info, phy_status, pktinfo);
1192         odm_process_rssi_for_dm(dm, phy_info, pktinfo);
1193 }
1194
1195 /*
1196  * Endianness before calling this API
1197  */
1198
1199 static void odm_phy_status_query_jaguar_series(
1200         struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
1201         u8 *phy_status, struct dm_per_pkt_info *pktinfo)
1202 {
1203         odm_rx_phy_status_jaguar_series_parsing(dm, phy_info, phy_status,
1204                                                 pktinfo);
1205         odm_process_rssi_for_dm(dm, phy_info, pktinfo);
1206 }
1207
1208 void odm_phy_status_query(struct phy_dm_struct *dm,
1209                           struct dm_phy_status_info *phy_info, u8 *phy_status,
1210                           struct dm_per_pkt_info *pktinfo)
1211 {
1212         if (dm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE) {
1213                 phydm_rx_phy_status_new_type(dm, phy_status, pktinfo, phy_info);
1214                 return;
1215         }
1216
1217         if (dm->support_ic_type & ODM_IC_11AC_SERIES)
1218                 odm_phy_status_query_jaguar_series(dm, phy_info, phy_status,
1219                                                    pktinfo);
1220
1221         if (dm->support_ic_type & ODM_IC_11N_SERIES)
1222                 odm_phy_status_query_92c_series(dm, phy_info, phy_status,
1223                                                 pktinfo);
1224 }
1225
1226 /* For future use. */
1227 void odm_mac_status_query(struct phy_dm_struct *dm, u8 *mac_status, u8 mac_id,
1228                           bool is_packet_match_bssid, bool is_packet_to_self,
1229                           bool is_packet_beacon)
1230 {
1231         /* 2011/10/19 Driver team will handle in the future. */
1232 }
1233
1234 /*
1235  * If you want to add a new IC, Please follow below template and generate
1236  * a new one.
1237  */
1238
1239 enum hal_status
1240 odm_config_rf_with_header_file(struct phy_dm_struct *dm,
1241                                enum odm_rf_config_type config_type,
1242                                enum odm_rf_radio_path e_rf_path)
1243 {
1244         ODM_RT_TRACE(dm, ODM_COMP_INIT,
1245                      "===>%s (%s)\n", __func__,
1246                      (dm->is_mp_chip) ? "MPChip" : "TestChip");
1247         ODM_RT_TRACE(
1248                 dm, ODM_COMP_INIT,
1249                 "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
1250                 dm->support_platform, dm->support_interface, dm->board_type);
1251
1252         /* 1 AP doesn't use PHYDM power tracking table in these ICs */
1253         /* JJ ADD 20161014 */
1254
1255         /* 1 All platforms support */
1256         if (dm->support_ic_type == ODM_RTL8822B) {
1257                 if (config_type == CONFIG_RF_RADIO) {
1258                         if (e_rf_path == ODM_RF_PATH_A)
1259                                 READ_AND_CONFIG_MP(8822b, _radioa);
1260                         else if (e_rf_path == ODM_RF_PATH_B)
1261                                 READ_AND_CONFIG_MP(8822b, _radiob);
1262                 } else if (config_type == CONFIG_RF_TXPWR_LMT) {
1263                         if (dm->rfe_type == 5)
1264                                 READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type5);
1265                         else
1266                                 READ_AND_CONFIG_MP(8822b, _txpwr_lmt);
1267                 }
1268         }
1269
1270         return HAL_STATUS_SUCCESS;
1271 }
1272
1273 enum hal_status
1274 odm_config_rf_with_tx_pwr_track_header_file(struct phy_dm_struct *dm)
1275 {
1276         ODM_RT_TRACE(dm, ODM_COMP_INIT,
1277                      "===>%s (%s)\n", __func__,
1278                      (dm->is_mp_chip) ? "MPChip" : "TestChip");
1279         ODM_RT_TRACE(
1280                 dm, ODM_COMP_INIT,
1281                 "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
1282                 dm->support_platform, dm->support_interface, dm->board_type);
1283
1284         /* 1 AP doesn't use PHYDM power tracking table in these ICs */
1285         /* JJ ADD 20161014 */
1286
1287         /* 1 All platforms support */
1288
1289         if (dm->support_ic_type == ODM_RTL8822B) {
1290                 if (dm->rfe_type == 0)
1291                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type0);
1292                 else if (dm->rfe_type == 1)
1293                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type1);
1294                 else if (dm->rfe_type == 2)
1295                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type2);
1296                 else if ((dm->rfe_type == 3) || (dm->rfe_type == 5))
1297                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type3_type5);
1298                 else if (dm->rfe_type == 4)
1299                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type4);
1300                 else if (dm->rfe_type == 6)
1301                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type6);
1302                 else if (dm->rfe_type == 7)
1303                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type7);
1304                 else if (dm->rfe_type == 8)
1305                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type8);
1306                 else if (dm->rfe_type == 9)
1307                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type9);
1308                 else
1309                         READ_AND_CONFIG_MP(8822b, _txpowertrack);
1310         }
1311
1312         return HAL_STATUS_SUCCESS;
1313 }
1314
1315 enum hal_status
1316 odm_config_bb_with_header_file(struct phy_dm_struct *dm,
1317                                enum odm_bb_config_type config_type)
1318 {
1319         /* 1 AP doesn't use PHYDM initialization in these ICs */
1320         /* JJ ADD 20161014 */
1321
1322         /* 1 All platforms support */
1323         if (dm->support_ic_type == ODM_RTL8822B) {
1324                 if (config_type == CONFIG_BB_PHY_REG)
1325                         READ_AND_CONFIG_MP(8822b, _phy_reg);
1326                 else if (config_type == CONFIG_BB_AGC_TAB)
1327                         READ_AND_CONFIG_MP(8822b, _agc_tab);
1328                 else if (config_type == CONFIG_BB_PHY_REG_PG)
1329                         READ_AND_CONFIG_MP(8822b, _phy_reg_pg);
1330                 /*else if (config_type == CONFIG_BB_PHY_REG_MP)*/
1331                 /*READ_AND_CONFIG_MP(8822b, _phy_reg_mp);*/
1332         }
1333
1334         return HAL_STATUS_SUCCESS;
1335 }
1336
1337 enum hal_status odm_config_mac_with_header_file(struct phy_dm_struct *dm)
1338 {
1339         ODM_RT_TRACE(dm, ODM_COMP_INIT,
1340                      "===>%s (%s)\n", __func__,
1341                      (dm->is_mp_chip) ? "MPChip" : "TestChip");
1342         ODM_RT_TRACE(
1343                 dm, ODM_COMP_INIT,
1344                 "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
1345                 dm->support_platform, dm->support_interface, dm->board_type);
1346
1347         /* 1 AP doesn't use PHYDM initialization in these ICs */
1348         /* JJ ADD 20161014 */
1349
1350         /* 1 All platforms support */
1351         if (dm->support_ic_type == ODM_RTL8822B)
1352                 READ_AND_CONFIG_MP(8822b, _mac_reg);
1353
1354         return HAL_STATUS_SUCCESS;
1355 }
1356
1357 enum hal_status
1358 odm_config_fw_with_header_file(struct phy_dm_struct *dm,
1359                                enum odm_fw_config_type config_type,
1360                                u8 *p_firmware, u32 *size)
1361 {
1362         return HAL_STATUS_SUCCESS;
1363 }
1364
1365 u32 odm_get_hw_img_version(struct phy_dm_struct *dm)
1366 {
1367         u32 version = 0;
1368
1369         /* 1 AP doesn't use PHYDM initialization in these ICs */
1370         /* JJ ADD 20161014 */
1371
1372         /*1 All platforms support*/
1373         if (dm->support_ic_type == ODM_RTL8822B)
1374                 version = GET_VERSION_MP(8822b, _mac_reg);
1375
1376         return version;
1377 }
1378
1379 /* For 8822B only!! need to move to FW finally */
1380 /*==============================================*/
1381
1382 bool phydm_query_is_mu_api(struct phy_dm_struct *phydm, u8 ppdu_idx,
1383                            u8 *p_data_rate, u8 *p_gid)
1384 {
1385         u8 data_rate = 0, gid = 0;
1386         bool is_mu = false;
1387
1388         data_rate = phydm->phy_dbg_info.num_of_ppdu[ppdu_idx];
1389         gid = phydm->phy_dbg_info.gid_num[ppdu_idx];
1390
1391         if (data_rate & BIT(7)) {
1392                 is_mu = true;
1393                 data_rate = data_rate & ~(BIT(7));
1394         } else {
1395                 is_mu = false;
1396         }
1397
1398         *p_data_rate = data_rate;
1399         *p_gid = gid;
1400
1401         return is_mu;
1402 }
1403
1404 static void phydm_rx_statistic_cal(struct phy_dm_struct *phydm, u8 *phy_status,
1405                                    struct dm_per_pkt_info *pktinfo)
1406 {
1407         struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt =
1408                 (struct phy_status_rpt_jaguar2_type1 *)phy_status;
1409         u8 date_rate = pktinfo->data_rate & ~(BIT(7));
1410
1411         if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) {
1412                 if (date_rate >= ODM_RATEVHTSS1MCS0) {
1413                         phydm->phy_dbg_info
1414                                 .num_qry_mu_vht_pkt[date_rate - 0x2C]++;
1415                         phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] =
1416                                 date_rate | BIT(7);
1417                         phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] =
1418                                 phy_sta_rpt->gid;
1419                 }
1420
1421         } else {
1422                 if (date_rate >= ODM_RATEVHTSS1MCS0) {
1423                         phydm->phy_dbg_info.num_qry_vht_pkt[date_rate - 0x2C]++;
1424                         phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] =
1425                                 date_rate;
1426                         phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] =
1427                                 phy_sta_rpt->gid;
1428                 }
1429         }
1430 }
1431
1432 static void phydm_reset_phy_info(struct phy_dm_struct *phydm,
1433                                  struct dm_phy_status_info *phy_info)
1434 {
1435         phy_info->rx_pwdb_all = 0;
1436         phy_info->signal_quality = 0;
1437         phy_info->band_width = 0;
1438         phy_info->rx_count = 0;
1439         odm_memory_set(phydm, phy_info->rx_mimo_signal_quality, 0, 4);
1440         odm_memory_set(phydm, phy_info->rx_mimo_signal_strength, 0, 4);
1441         odm_memory_set(phydm, phy_info->rx_snr, 0, 4);
1442
1443         phy_info->rx_power = -110;
1444         phy_info->recv_signal_power = -110;
1445         phy_info->bt_rx_rssi_percentage = 0;
1446         phy_info->signal_strength = 0;
1447         phy_info->bt_coex_pwr_adjust = 0;
1448         phy_info->channel = 0;
1449         phy_info->is_mu_packet = 0;
1450         phy_info->is_beamformed = 0;
1451         phy_info->rxsc = 0;
1452         odm_memory_set(phydm, phy_info->rx_pwr, -110, 4);
1453         odm_memory_set(phydm, phy_info->rx_mimo_evm_dbm, 0, 4);
1454         odm_memory_set(phydm, phy_info->cfo_short, 0, 8);
1455         odm_memory_set(phydm, phy_info->cfo_tail, 0, 8);
1456 }
1457
1458 static void phydm_set_per_path_phy_info(u8 rx_path, s8 rx_pwr, s8 rx_evm,
1459                                         s8 cfo_tail, s8 rx_snr,
1460                                         struct dm_phy_status_info *phy_info)
1461 {
1462         u8 evm_dbm = 0;
1463         u8 evm_percentage = 0;
1464
1465         /* SNR is S(8,1), EVM is S(8,1), CFO is S(8,7) */
1466
1467         if (rx_evm < 0) {
1468                 /* Calculate EVM in dBm */
1469                 evm_dbm = ((u8)(0 - rx_evm) >> 1);
1470
1471                 /* Calculate EVM in percentage */
1472                 if (evm_dbm >= 33)
1473                         evm_percentage = 100;
1474                 else
1475                         evm_percentage = (evm_dbm << 1) + (evm_dbm);
1476         }
1477
1478         phy_info->rx_pwr[rx_path] = rx_pwr;
1479         phy_info->rx_mimo_evm_dbm[rx_path] = evm_dbm;
1480
1481         /* CFO = CFO_tail * 312.5 / 2^7 ~= CFO tail * 39/512 (kHz)*/
1482         phy_info->cfo_tail[rx_path] = cfo_tail;
1483         phy_info->cfo_tail[rx_path] = ((phy_info->cfo_tail[rx_path] << 5) +
1484                                        (phy_info->cfo_tail[rx_path] << 2) +
1485                                        (phy_info->cfo_tail[rx_path] << 1) +
1486                                        (phy_info->cfo_tail[rx_path])) >>
1487                                       9;
1488
1489         phy_info->rx_mimo_signal_strength[rx_path] =
1490                 odm_query_rx_pwr_percentage(rx_pwr);
1491         phy_info->rx_mimo_signal_quality[rx_path] = evm_percentage;
1492         phy_info->rx_snr[rx_path] = rx_snr >> 1;
1493 }
1494
1495 static void phydm_set_common_phy_info(s8 rx_power, u8 channel,
1496                                       bool is_beamformed, bool is_mu_packet,
1497                                       u8 bandwidth, u8 signal_quality, u8 rxsc,
1498                                       struct dm_phy_status_info *phy_info)
1499 {
1500         phy_info->rx_power = rx_power; /* RSSI in dB */
1501         phy_info->recv_signal_power = rx_power; /* RSSI in dB */
1502         phy_info->channel = channel; /* channel number */
1503         phy_info->is_beamformed = is_beamformed; /* apply BF */
1504         phy_info->is_mu_packet = is_mu_packet; /* MU packet */
1505         phy_info->rxsc = rxsc;
1506         phy_info->rx_pwdb_all =
1507                 odm_query_rx_pwr_percentage(rx_power); /* RSSI in percentage */
1508         phy_info->signal_quality = signal_quality; /* signal quality */
1509         phy_info->band_width = bandwidth; /* bandwidth */
1510 }
1511
1512 static void phydm_get_rx_phy_status_type0(struct phy_dm_struct *dm,
1513                                           u8 *phy_status,
1514                                           struct dm_per_pkt_info *pktinfo,
1515                                           struct dm_phy_status_info *phy_info)
1516 {
1517         /* type 0 is used for cck packet */
1518
1519         struct phy_status_rpt_jaguar2_type0 *phy_sta_rpt =
1520                 (struct phy_status_rpt_jaguar2_type0 *)phy_status;
1521         u8 sq = 0;
1522         s8 rx_power = phy_sta_rpt->pwdb - 110;
1523
1524         /* JJ ADD 20161014 */
1525
1526         /* Calculate Signal Quality*/
1527         if (pktinfo->is_packet_match_bssid) {
1528                 if (phy_sta_rpt->signal_quality >= 64) {
1529                         sq = 0;
1530                 } else if (phy_sta_rpt->signal_quality <= 20) {
1531                         sq = 100;
1532                 } else {
1533                         /* mapping to 2~99% */
1534                         sq = 64 - phy_sta_rpt->signal_quality;
1535                         sq = ((sq << 3) + sq) >> 2;
1536                 }
1537         }
1538
1539         /* Modify CCK PWDB if old AGC */
1540         if (!dm->cck_new_agc) {
1541                 u8 lna_idx, vga_idx;
1542
1543                 lna_idx = ((phy_sta_rpt->lna_h << 3) | phy_sta_rpt->lna_l);
1544                 vga_idx = phy_sta_rpt->vga;
1545
1546                 /* JJ ADD 20161014 */
1547
1548                 /* Need to do !! */
1549                 /*if (dm->support_ic_type & ODM_RTL8822B) */
1550                 /*rx_power = odm_CCKRSSI_8822B(LNA_idx, VGA_idx);*/
1551         }
1552
1553         /* Update CCK packet counter */
1554         dm->phy_dbg_info.num_qry_phy_status_cck++;
1555
1556         /*CCK no STBC and LDPC*/
1557         dm->phy_dbg_info.is_ldpc_pkt = false;
1558         dm->phy_dbg_info.is_stbc_pkt = false;
1559
1560         /* Update Common information */
1561         phydm_set_common_phy_info(rx_power, phy_sta_rpt->channel, false, false,
1562                                   ODM_BW20M, sq, phy_sta_rpt->rxsc, phy_info);
1563
1564         /* Update CCK pwdb */
1565         /* Update per-path information */
1566         phydm_set_per_path_phy_info(ODM_RF_PATH_A, rx_power, 0, 0, 0, phy_info);
1567
1568         dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a;
1569         dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b;
1570         dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c;
1571         dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d;
1572 }
1573
1574 static void phydm_get_rx_phy_status_type1(struct phy_dm_struct *dm,
1575                                           u8 *phy_status,
1576                                           struct dm_per_pkt_info *pktinfo,
1577                                           struct dm_phy_status_info *phy_info)
1578 {
1579         /* type 1 is used for ofdm packet */
1580
1581         struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt =
1582                 (struct phy_status_rpt_jaguar2_type1 *)phy_status;
1583         s8 rx_pwr_db = -120;
1584         u8 i, rxsc, bw = ODM_BW20M, rx_count = 0;
1585         bool is_mu;
1586         u8 num_ss;
1587
1588         /* Update OFDM packet counter */
1589         dm->phy_dbg_info.num_qry_phy_status_ofdm++;
1590
1591         /* Update per-path information */
1592         for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
1593                 if (dm->rx_ant_status & BIT(i)) {
1594                         s8 rx_path_pwr_db;
1595
1596                         /* RX path counter */
1597                         rx_count++;
1598
1599                         /* Update per-path information
1600                          * (RSSI_dB RSSI_percentage EVM SNR CFO sq)
1601                          */
1602                         /* EVM report is reported by stream, not path */
1603                         rx_path_pwr_db = phy_sta_rpt->pwdb[i] -
1604                                          110; /* per-path pwdb in dB domain */
1605                         phydm_set_per_path_phy_info(
1606                                 i, rx_path_pwr_db,
1607                                 phy_sta_rpt->rxevm[rx_count - 1],
1608                                 phy_sta_rpt->cfo_tail[i], phy_sta_rpt->rxsnr[i],
1609                                 phy_info);
1610
1611                         /* search maximum pwdb */
1612                         if (rx_path_pwr_db > rx_pwr_db)
1613                                 rx_pwr_db = rx_path_pwr_db;
1614                 }
1615         }
1616
1617         /* mapping RX counter from 1~4 to 0~3 */
1618         if (rx_count > 0)
1619                 phy_info->rx_count = rx_count - 1;
1620
1621         /* Check if MU packet or not */
1622         if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) {
1623                 is_mu = true;
1624                 dm->phy_dbg_info.num_qry_mu_pkt++;
1625         } else {
1626                 is_mu = false;
1627         }
1628
1629         /* count BF packet */
1630         dm->phy_dbg_info.num_qry_bf_pkt =
1631                 dm->phy_dbg_info.num_qry_bf_pkt + phy_sta_rpt->beamformed;
1632
1633         /*STBC or LDPC pkt*/
1634         dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc;
1635         dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc;
1636
1637         /* Check sub-channel */
1638         if ((pktinfo->data_rate > ODM_RATE11M) &&
1639             (pktinfo->data_rate < ODM_RATEMCS0))
1640                 rxsc = phy_sta_rpt->l_rxsc;
1641         else
1642                 rxsc = phy_sta_rpt->ht_rxsc;
1643
1644         /* Check RX bandwidth */
1645         if (dm->support_ic_type & ODM_RTL8822B) {
1646                 if ((rxsc >= 1) && (rxsc <= 8))
1647                         bw = ODM_BW20M;
1648                 else if ((rxsc >= 9) && (rxsc <= 12))
1649                         bw = ODM_BW40M;
1650                 else if (rxsc >= 13)
1651                         bw = ODM_BW80M;
1652                 else
1653                         bw = phy_sta_rpt->rf_mode;
1654         } else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D |
1655                                           ODM_RTL8710B)) { /* JJ ADD 20161014 */
1656                 if (phy_sta_rpt->rf_mode == 0)
1657                         bw = ODM_BW20M;
1658                 else if ((rxsc == 1) || (rxsc == 2))
1659                         bw = ODM_BW20M;
1660                 else
1661                         bw = ODM_BW40M;
1662         }
1663
1664         /* Update packet information */
1665         phydm_set_common_phy_info(
1666                 rx_pwr_db, phy_sta_rpt->channel, (bool)phy_sta_rpt->beamformed,
1667                 is_mu, bw, odm_evm_db_to_percentage(phy_sta_rpt->rxevm[0]),
1668                 rxsc, phy_info);
1669
1670         num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
1671
1672         odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfo_tail, num_ss);
1673         dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a;
1674         dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b;
1675         dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c;
1676         dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d;
1677
1678         if (pktinfo->is_packet_match_bssid) {
1679                 /* */
1680                 phydm_rx_statistic_cal(dm, phy_status, pktinfo);
1681         }
1682 }
1683
1684 static void phydm_get_rx_phy_status_type2(struct phy_dm_struct *dm,
1685                                           u8 *phy_status,
1686                                           struct dm_per_pkt_info *pktinfo,
1687                                           struct dm_phy_status_info *phy_info)
1688 {
1689         struct phy_status_rpt_jaguar2_type2 *phy_sta_rpt =
1690                 (struct phy_status_rpt_jaguar2_type2 *)phy_status;
1691         s8 rx_pwr_db = -120;
1692         u8 i, rxsc, bw = ODM_BW20M, rx_count = 0;
1693
1694         /* Update OFDM packet counter */
1695         dm->phy_dbg_info.num_qry_phy_status_ofdm++;
1696
1697         /* Update per-path information */
1698         for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
1699                 if (dm->rx_ant_status & BIT(i)) {
1700                         s8 rx_path_pwr_db;
1701
1702                         /* RX path counter */
1703                         rx_count++;
1704
1705                         /* Update per-path information
1706                          * (RSSI_dB RSSI_percentage EVM SNR CFO sq)
1707                          */
1708                         rx_path_pwr_db = phy_sta_rpt->pwdb[i] -
1709                                          110; /* per-path pwdb in dB domain */
1710
1711                         phydm_set_per_path_phy_info(i, rx_path_pwr_db, 0, 0, 0,
1712                                                     phy_info);
1713
1714                         /* search maximum pwdb */
1715                         if (rx_path_pwr_db > rx_pwr_db)
1716                                 rx_pwr_db = rx_path_pwr_db;
1717                 }
1718         }
1719
1720         /* mapping RX counter from 1~4 to 0~3 */
1721         if (rx_count > 0)
1722                 phy_info->rx_count = rx_count - 1;
1723
1724         /* Check RX sub-channel */
1725         if ((pktinfo->data_rate > ODM_RATE11M) &&
1726             (pktinfo->data_rate < ODM_RATEMCS0))
1727                 rxsc = phy_sta_rpt->l_rxsc;
1728         else
1729                 rxsc = phy_sta_rpt->ht_rxsc;
1730
1731         /*STBC or LDPC pkt*/
1732         dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc;
1733         dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc;
1734
1735         /* Check RX bandwidth */
1736         /* the BW information of sc=0 is useless, because there is
1737          * no information of RF mode
1738          */
1739
1740         if (dm->support_ic_type & ODM_RTL8822B) {
1741                 if ((rxsc >= 1) && (rxsc <= 8))
1742                         bw = ODM_BW20M;
1743                 else if ((rxsc >= 9) && (rxsc <= 12))
1744                         bw = ODM_BW40M;
1745                 else if (rxsc >= 13)
1746                         bw = ODM_BW80M;
1747                 else
1748                         bw = ODM_BW20M;
1749         } else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D |
1750                                           ODM_RTL8710B)) { /* JJ ADD 20161014 */
1751                 if (rxsc == 3)
1752                         bw = ODM_BW40M;
1753                 else if ((rxsc == 1) || (rxsc == 2))
1754                         bw = ODM_BW20M;
1755                 else
1756                         bw = ODM_BW20M;
1757         }
1758
1759         /* Update packet information */
1760         phydm_set_common_phy_info(rx_pwr_db, phy_sta_rpt->channel,
1761                                   (bool)phy_sta_rpt->beamformed, false, bw, 0,
1762                                   rxsc, phy_info);
1763 }
1764
1765 static void
1766 phydm_process_rssi_for_dm_new_type(struct phy_dm_struct *dm,
1767                                    struct dm_phy_status_info *phy_info,
1768                                    struct dm_per_pkt_info *pktinfo)
1769 {
1770         s32 undecorated_smoothed_pwdb, accumulate_pwdb;
1771         u32 rssi_ave;
1772         u8 i;
1773         struct rtl_sta_info *entry;
1774         u8 scaling_factor = 4;
1775
1776         if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM)
1777                 return;
1778
1779         entry = dm->odm_sta_info[pktinfo->station_id];
1780
1781         if (!IS_STA_VALID(entry))
1782                 return;
1783
1784         if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/
1785                 return;
1786
1787         if (pktinfo->is_packet_beacon)
1788                 dm->phy_dbg_info.num_qry_beacon_pkt++;
1789
1790         if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) {
1791                 u32 rssi_linear = 0;
1792
1793                 dm->rx_rate = pktinfo->data_rate;
1794                 undecorated_smoothed_pwdb =
1795                         entry->rssi_stat.undecorated_smoothed_pwdb;
1796                 accumulate_pwdb = dm->accumulate_pwdb[pktinfo->station_id];
1797                 dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
1798                 dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
1799                 dm->rssi_c = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_C];
1800                 dm->rssi_d = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_D];
1801
1802                 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
1803                         if (phy_info->rx_mimo_signal_strength[i] != 0)
1804                                 rssi_linear += odm_convert_to_linear(
1805                                         phy_info->rx_mimo_signal_strength[i]);
1806                 }
1807
1808                 switch (phy_info->rx_count + 1) {
1809                 case 2:
1810                         rssi_linear = (rssi_linear >> 1);
1811                         break;
1812                 case 3:
1813                         /* rssi_linear/3 ~ rssi_linear*11/32 */
1814                         rssi_linear = ((rssi_linear) + (rssi_linear << 1) +
1815                                        (rssi_linear << 3)) >>
1816                                       5;
1817                         break;
1818                 case 4:
1819                         rssi_linear = (rssi_linear >> 2);
1820                         break;
1821                 }
1822                 rssi_ave = odm_convert_to_db(rssi_linear);
1823
1824                 if (undecorated_smoothed_pwdb <= 0) {
1825                         accumulate_pwdb =
1826                                 (phy_info->rx_pwdb_all << scaling_factor);
1827                         undecorated_smoothed_pwdb = phy_info->rx_pwdb_all;
1828                 } else {
1829                         accumulate_pwdb = accumulate_pwdb -
1830                                           (accumulate_pwdb >> scaling_factor) +
1831                                           rssi_ave;
1832                         undecorated_smoothed_pwdb =
1833                                 (accumulate_pwdb +
1834                                  (1 << (scaling_factor - 1))) >>
1835                                 scaling_factor;
1836                 }
1837
1838                 entry->rssi_stat.undecorated_smoothed_pwdb =
1839                         undecorated_smoothed_pwdb;
1840                 dm->accumulate_pwdb[pktinfo->station_id] = accumulate_pwdb;
1841         }
1842 }
1843
1844 void phydm_rx_phy_status_new_type(struct phy_dm_struct *phydm, u8 *phy_status,
1845                                   struct dm_per_pkt_info *pktinfo,
1846                                   struct dm_phy_status_info *phy_info)
1847 {
1848         u8 phy_status_type = (*phy_status & 0xf);
1849
1850         /* Memory reset */
1851         phydm_reset_phy_info(phydm, phy_info);
1852
1853         /* Phy status parsing */
1854         switch (phy_status_type) {
1855         case 0: {
1856                 phydm_get_rx_phy_status_type0(phydm, phy_status, pktinfo,
1857                                               phy_info);
1858                 break;
1859         }
1860         case 1: {
1861                 phydm_get_rx_phy_status_type1(phydm, phy_status, pktinfo,
1862                                               phy_info);
1863                 break;
1864         }
1865         case 2: {
1866                 phydm_get_rx_phy_status_type2(phydm, phy_status, pktinfo,
1867                                               phy_info);
1868                 break;
1869         }
1870         default:
1871                 return;
1872         }
1873
1874         /* Update signal strength to UI, and phy_info->rx_pwdb_all is the
1875          * maximum RSSI of all path
1876          */
1877         phy_info->signal_strength =
1878                 (u8)(odm_signal_scale_mapping(phydm, phy_info->rx_pwdb_all));
1879
1880         /* Calculate average RSSI and smoothed RSSI */
1881         phydm_process_rssi_for_dm_new_type(phydm, phy_info, pktinfo);
1882 }
1883
1884 u32 query_phydm_trx_capability(struct phy_dm_struct *dm)
1885 {
1886         u32 value32 = 0xFFFFFFFF;
1887
1888         return value32;
1889 }
1890
1891 u32 query_phydm_stbc_capability(struct phy_dm_struct *dm)
1892 {
1893         u32 value32 = 0xFFFFFFFF;
1894
1895         return value32;
1896 }
1897
1898 u32 query_phydm_ldpc_capability(struct phy_dm_struct *dm)
1899 {
1900         u32 value32 = 0xFFFFFFFF;
1901
1902         return value32;
1903 }
1904
1905 u32 query_phydm_txbf_parameters(struct phy_dm_struct *dm)
1906 {
1907         u32 value32 = 0xFFFFFFFF;
1908
1909         return value32;
1910 }
1911
1912 u32 query_phydm_txbf_capability(struct phy_dm_struct *dm)
1913 {
1914         u32 value32 = 0xFFFFFFFF;
1915
1916         return value32;
1917 }