Linux-libre 4.14.68-gnu
[librecmc/linux-libre.git] / drivers / staging / rtlwifi / phydm / phydm_hwconfig.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2016  Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  *****************************************************************************/
25
26 /* ************************************************************
27  * include files
28  * *************************************************************/
29
30 #include "mp_precomp.h"
31 #include "phydm_precomp.h"
32
33 #define READ_AND_CONFIG_MP(ic, txt) (odm_read_and_config_mp_##ic##txt(dm))
34 #define READ_AND_CONFIG_TC(ic, txt) (odm_read_and_config_tc_##ic##txt(dm))
35
36 #define READ_AND_CONFIG READ_AND_CONFIG_MP
37
38 #define READ_FIRMWARE_MP(ic, txt)                                              \
39         (odm_read_firmware_mp_##ic##txt(dm, p_firmware, size))
40 #define READ_FIRMWARE_TC(ic, txt)                                              \
41         (odm_read_firmware_tc_##ic##txt(dm, p_firmware, size))
42
43 #define READ_FIRMWARE READ_FIRMWARE_MP
44
45 #define GET_VERSION_MP(ic, txt) (odm_get_version_mp_##ic##txt())
46 #define GET_VERSION_TC(ic, txt) (odm_get_version_tc_##ic##txt())
47
48 #define GET_VERSION(ic, txt) GET_VERSION_MP(ic, txt)
49
50 static u32 phydm_process_rssi_pwdb(struct phy_dm_struct *dm,
51                                    struct rtl_sta_info *entry,
52                                    struct dm_per_pkt_info *pktinfo,
53                                    u32 undecorated_smoothed_ofdm,
54                                    u32 undecorated_smoothed_cck)
55 {
56         u32 weighting = 0, undecorated_smoothed_pwdb;
57         /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */
58
59         if (entry->rssi_stat.ofdm_pkt ==
60             64) { /* speed up when all packets are OFDM*/
61                 undecorated_smoothed_pwdb = undecorated_smoothed_ofdm;
62                 ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
63                              "PWDB_0[%d] = (( %d ))\n", pktinfo->station_id,
64                              undecorated_smoothed_cck);
65         } else {
66                 if (entry->rssi_stat.valid_bit < 64)
67                         entry->rssi_stat.valid_bit++;
68
69                 if (entry->rssi_stat.valid_bit == 64) {
70                         weighting = ((entry->rssi_stat.ofdm_pkt) > 4) ?
71                                             64 :
72                                             (entry->rssi_stat.ofdm_pkt << 4);
73                         undecorated_smoothed_pwdb =
74                                 (weighting * undecorated_smoothed_ofdm +
75                                  (64 - weighting) * undecorated_smoothed_cck) >>
76                                 6;
77                         ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
78                                      "PWDB_1[%d] = (( %d )), W = (( %d ))\n",
79                                      pktinfo->station_id,
80                                      undecorated_smoothed_cck, weighting);
81                 } else {
82                         if (entry->rssi_stat.valid_bit != 0)
83                                 undecorated_smoothed_pwdb =
84                                         (entry->rssi_stat.ofdm_pkt *
85                                                  undecorated_smoothed_ofdm +
86                                          (entry->rssi_stat.valid_bit -
87                                           entry->rssi_stat.ofdm_pkt) *
88                                                  undecorated_smoothed_cck) /
89                                         entry->rssi_stat.valid_bit;
90                         else
91                                 undecorated_smoothed_pwdb = 0;
92
93                         ODM_RT_TRACE(
94                                 dm, ODM_COMP_RSSI_MONITOR,
95                                 "PWDB_2[%d] = (( %d )), ofdm_pkt = (( %d )), Valid_Bit = (( %d ))\n",
96                                 pktinfo->station_id, undecorated_smoothed_cck,
97                                 entry->rssi_stat.ofdm_pkt,
98                                 entry->rssi_stat.valid_bit);
99                 }
100         }
101
102         return undecorated_smoothed_pwdb;
103 }
104
105 static u32 phydm_process_rssi_cck(struct phy_dm_struct *dm,
106                                   struct dm_phy_status_info *phy_info,
107                                   struct rtl_sta_info *entry,
108                                   u32 undecorated_smoothed_cck)
109 {
110         u32 rssi_ave;
111         u8 i;
112
113         rssi_ave = phy_info->rx_pwdb_all;
114         dm->rssi_a = (u8)phy_info->rx_pwdb_all;
115         dm->rssi_b = 0xFF;
116         dm->rssi_c = 0xFF;
117         dm->rssi_d = 0xFF;
118
119         if (entry->rssi_stat.cck_pkt <= 63)
120                 entry->rssi_stat.cck_pkt++;
121
122         /* 1 Process CCK RSSI */
123         if (undecorated_smoothed_cck <= 0) { /* initialize */
124                 undecorated_smoothed_cck = phy_info->rx_pwdb_all;
125                 entry->rssi_stat.cck_sum_power =
126                         (u16)phy_info->rx_pwdb_all; /*reset*/
127                 entry->rssi_stat.cck_pkt = 1; /*reset*/
128                 ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, "CCK_INIT: (( %d ))\n",
129                              undecorated_smoothed_cck);
130         } else if (entry->rssi_stat.cck_pkt <= CCK_RSSI_INIT_COUNT) {
131                 entry->rssi_stat.cck_sum_power =
132                         entry->rssi_stat.cck_sum_power +
133                         (u16)phy_info->rx_pwdb_all;
134                 undecorated_smoothed_cck = entry->rssi_stat.cck_sum_power /
135                                            entry->rssi_stat.cck_pkt;
136
137                 ODM_RT_TRACE(
138                         dm, ODM_COMP_RSSI_MONITOR,
139                         "CCK_0: (( %d )), SumPow = (( %d )), cck_pkt = (( %d ))\n",
140                         undecorated_smoothed_cck,
141                         entry->rssi_stat.cck_sum_power,
142                         entry->rssi_stat.cck_pkt);
143         } else {
144                 if (phy_info->rx_pwdb_all > (u32)undecorated_smoothed_cck) {
145                         undecorated_smoothed_cck =
146                                 (((undecorated_smoothed_cck) *
147                                   (RX_SMOOTH_FACTOR - 1)) +
148                                  (phy_info->rx_pwdb_all)) /
149                                 (RX_SMOOTH_FACTOR);
150                         undecorated_smoothed_cck = undecorated_smoothed_cck + 1;
151                         ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
152                                      "CCK_1: (( %d ))\n",
153                                      undecorated_smoothed_cck);
154                 } else {
155                         undecorated_smoothed_cck =
156                                 (((undecorated_smoothed_cck) *
157                                   (RX_SMOOTH_FACTOR - 1)) +
158                                  (phy_info->rx_pwdb_all)) /
159                                 (RX_SMOOTH_FACTOR);
160                         ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
161                                      "CCK_2: (( %d ))\n",
162                                      undecorated_smoothed_cck);
163                 }
164         }
165
166         i = 63;
167         entry->rssi_stat.ofdm_pkt -=
168                 (u8)((entry->rssi_stat.packet_map >> i) & BIT(0));
169         entry->rssi_stat.packet_map = entry->rssi_stat.packet_map << 1;
170         return undecorated_smoothed_cck;
171 }
172
173 static u32 phydm_process_rssi_ofdm(struct phy_dm_struct *dm,
174                                    struct dm_phy_status_info *phy_info,
175                                    struct rtl_sta_info *entry,
176                                    u32 undecorated_smoothed_ofdm)
177 {
178         u32 rssi_ave;
179         u8 rssi_max, rssi_min, i;
180
181         if (dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B)) {
182                 u8 rx_count = 0;
183                 u32 rssi_linear = 0;
184
185                 if (dm->rx_ant_status & ODM_RF_A) {
186                         dm->rssi_a = phy_info->rx_mimo_signal_strength
187                                              [ODM_RF_PATH_A];
188                         rx_count++;
189                         rssi_linear += odm_convert_to_linear(
190                                 phy_info->rx_mimo_signal_strength
191                                         [ODM_RF_PATH_A]);
192                 } else {
193                         dm->rssi_a = 0;
194                 }
195
196                 if (dm->rx_ant_status & ODM_RF_B) {
197                         dm->rssi_b = phy_info->rx_mimo_signal_strength
198                                              [ODM_RF_PATH_B];
199                         rx_count++;
200                         rssi_linear += odm_convert_to_linear(
201                                 phy_info->rx_mimo_signal_strength
202                                         [ODM_RF_PATH_B]);
203                 } else {
204                         dm->rssi_b = 0;
205                 }
206
207                 if (dm->rx_ant_status & ODM_RF_C) {
208                         dm->rssi_c = phy_info->rx_mimo_signal_strength
209                                              [ODM_RF_PATH_C];
210                         rx_count++;
211                         rssi_linear += odm_convert_to_linear(
212                                 phy_info->rx_mimo_signal_strength
213                                         [ODM_RF_PATH_C]);
214                 } else {
215                         dm->rssi_c = 0;
216                 }
217
218                 if (dm->rx_ant_status & ODM_RF_D) {
219                         dm->rssi_d = phy_info->rx_mimo_signal_strength
220                                              [ODM_RF_PATH_D];
221                         rx_count++;
222                         rssi_linear += odm_convert_to_linear(
223                                 phy_info->rx_mimo_signal_strength
224                                         [ODM_RF_PATH_D]);
225                 } else {
226                         dm->rssi_d = 0;
227                 }
228
229                 /* Calculate average RSSI */
230                 switch (rx_count) {
231                 case 2:
232                         rssi_linear = (rssi_linear >> 1);
233                         break;
234                 case 3:
235                         /* rssi_linear/3 ~ rssi_linear*11/32 */
236                         rssi_linear = ((rssi_linear) + (rssi_linear << 1) +
237                                        (rssi_linear << 3)) >>
238                                       5;
239                         break;
240                 case 4:
241                         rssi_linear = (rssi_linear >> 2);
242                         break;
243                 }
244
245                 rssi_ave = odm_convert_to_db(rssi_linear);
246         } else {
247                 if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B] == 0) {
248                         rssi_ave = phy_info->rx_mimo_signal_strength
249                                            [ODM_RF_PATH_A];
250                         dm->rssi_a = phy_info->rx_mimo_signal_strength
251                                              [ODM_RF_PATH_A];
252                         dm->rssi_b = 0;
253                 } else {
254                         dm->rssi_a = phy_info->rx_mimo_signal_strength
255                                              [ODM_RF_PATH_A];
256                         dm->rssi_b = phy_info->rx_mimo_signal_strength
257                                              [ODM_RF_PATH_B];
258
259                         if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] >
260                             phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) {
261                                 rssi_max = phy_info->rx_mimo_signal_strength
262                                                    [ODM_RF_PATH_A];
263                                 rssi_min = phy_info->rx_mimo_signal_strength
264                                                    [ODM_RF_PATH_B];
265                         } else {
266                                 rssi_max = phy_info->rx_mimo_signal_strength
267                                                    [ODM_RF_PATH_B];
268                                 rssi_min = phy_info->rx_mimo_signal_strength
269                                                    [ODM_RF_PATH_A];
270                         }
271                         if ((rssi_max - rssi_min) < 3)
272                                 rssi_ave = rssi_max;
273                         else if ((rssi_max - rssi_min) < 6)
274                                 rssi_ave = rssi_max - 1;
275                         else if ((rssi_max - rssi_min) < 10)
276                                 rssi_ave = rssi_max - 2;
277                         else
278                                 rssi_ave = rssi_max - 3;
279                 }
280         }
281
282         /* 1 Process OFDM RSSI */
283         if (undecorated_smoothed_ofdm <= 0) { /* initialize */
284                 undecorated_smoothed_ofdm = phy_info->rx_pwdb_all;
285                 ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, "OFDM_INIT: (( %d ))\n",
286                              undecorated_smoothed_ofdm);
287         } else {
288                 if (phy_info->rx_pwdb_all > (u32)undecorated_smoothed_ofdm) {
289                         undecorated_smoothed_ofdm =
290                                 (((undecorated_smoothed_ofdm) *
291                                   (RX_SMOOTH_FACTOR - 1)) +
292                                  (rssi_ave)) /
293                                 (RX_SMOOTH_FACTOR);
294                         undecorated_smoothed_ofdm =
295                                 undecorated_smoothed_ofdm + 1;
296                         ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
297                                      "OFDM_1: (( %d ))\n",
298                                      undecorated_smoothed_ofdm);
299                 } else {
300                         undecorated_smoothed_ofdm =
301                                 (((undecorated_smoothed_ofdm) *
302                                   (RX_SMOOTH_FACTOR - 1)) +
303                                  (rssi_ave)) /
304                                 (RX_SMOOTH_FACTOR);
305                         ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
306                                      "OFDM_2: (( %d ))\n",
307                                      undecorated_smoothed_ofdm);
308                 }
309         }
310
311         if (entry->rssi_stat.ofdm_pkt != 64) {
312                 i = 63;
313                 entry->rssi_stat.ofdm_pkt -=
314                         (u8)(((entry->rssi_stat.packet_map >> i) & BIT(0)) - 1);
315         }
316
317         entry->rssi_stat.packet_map =
318                 (entry->rssi_stat.packet_map << 1) | BIT(0);
319         return undecorated_smoothed_ofdm;
320 }
321
322 static u8 odm_evm_db_to_percentage(s8);
323 static u8 odm_evm_dbm_jaguar_series(s8);
324
325 static inline u32 phydm_get_rssi_average(struct phy_dm_struct *dm,
326                                          struct dm_phy_status_info *phy_info)
327 {
328         u8 rssi_max = 0, rssi_min = 0;
329
330         dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
331         dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
332
333         if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] >
334             phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) {
335                 rssi_max = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
336                 rssi_min = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
337         } else {
338                 rssi_max = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
339                 rssi_min = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
340         }
341         if ((rssi_max - rssi_min) < 3)
342                 return rssi_max;
343         else if ((rssi_max - rssi_min) < 6)
344                 return rssi_max - 1;
345         else if ((rssi_max - rssi_min) < 10)
346                 return rssi_max - 2;
347         else
348                 return rssi_max - 3;
349 }
350
351 static inline u8 phydm_get_evm_dbm(u8 i, u8 EVM,
352                                    struct phy_status_rpt_8812 *phy_sta_rpt,
353                                    struct dm_phy_status_info *phy_info)
354 {
355         if (i < ODM_RF_PATH_C)
356                 return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm[i]);
357         else
358                 return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm_cd[i - 2]);
359         /*RT_DISP(FRX, RX_PHY_SQ, ("RXRATE=%x RXEVM=%x EVM=%s%d\n",*/
360         /*pktinfo->data_rate, phy_sta_rpt->rxevm[i], "%", EVM));*/
361 }
362
363 static inline u8 phydm_get_odm_evm(u8 i, struct dm_per_pkt_info *pktinfo,
364                                    struct phy_status_rpt_8812 *phy_sta_rpt)
365 {
366         u8 evm = 0;
367
368         if (pktinfo->data_rate >= ODM_RATE6M &&
369             pktinfo->data_rate <= ODM_RATE54M) {
370                 if (i == ODM_RF_PATH_A) {
371                         evm = odm_evm_db_to_percentage(
372                                 (phy_sta_rpt->sigevm)); /*dbm*/
373                         evm += 20;
374                         if (evm > 100)
375                                 evm = 100;
376                 }
377         } else {
378                 if (i < ODM_RF_PATH_C) {
379                         if (phy_sta_rpt->rxevm[i] == -128)
380                                 phy_sta_rpt->rxevm[i] = -25;
381                         evm = odm_evm_db_to_percentage(
382                                 (phy_sta_rpt->rxevm[i])); /*dbm*/
383                 } else {
384                         if (phy_sta_rpt->rxevm_cd[i - 2] == -128)
385                                 phy_sta_rpt->rxevm_cd[i - 2] = -25;
386                         evm = odm_evm_db_to_percentage(
387                                 (phy_sta_rpt->rxevm_cd[i - 2])); /*dbm*/
388                 }
389         }
390
391         return evm;
392 }
393
394 static inline s8 phydm_get_rx_pwr(u8 LNA_idx, u8 VGA_idx, u8 cck_highpwr)
395 {
396         switch (LNA_idx) {
397         case 7:
398                 if (VGA_idx <= 27)
399                         return -100 + 2 * (27 - VGA_idx); /*VGA_idx = 27~2*/
400                 else
401                         return -100;
402                 break;
403         case 6:
404                 return -48 + 2 * (2 - VGA_idx); /*VGA_idx = 2~0*/
405         case 5:
406                 return -42 + 2 * (7 - VGA_idx); /*VGA_idx = 7~5*/
407         case 4:
408                 return -36 + 2 * (7 - VGA_idx); /*VGA_idx = 7~4*/
409         case 3:
410                 return -24 + 2 * (7 - VGA_idx); /*VGA_idx = 7~0*/
411         case 2:
412                 if (cck_highpwr)
413                         return -12 + 2 * (5 - VGA_idx); /*VGA_idx = 5~0*/
414                 else
415                         return -6 + 2 * (5 - VGA_idx);
416                 break;
417         case 1:
418                 return 8 - 2 * VGA_idx;
419         case 0:
420                 return 14 - 2 * VGA_idx;
421         default:
422                 break;
423         }
424         return 0;
425 }
426
427 static inline u8 phydm_adjust_pwdb(u8 cck_highpwr, u8 pwdb_all)
428 {
429         if (!cck_highpwr) {
430                 if (pwdb_all >= 80)
431                         return ((pwdb_all - 80) << 1) + ((pwdb_all - 80) >> 1) +
432                                80;
433                 else if ((pwdb_all <= 78) && (pwdb_all >= 20))
434                         return pwdb_all + 3;
435                 if (pwdb_all > 100)
436                         return 100;
437         }
438         return pwdb_all;
439 }
440
441 static inline u8
442 phydm_get_signal_quality_8812(struct dm_phy_status_info *phy_info,
443                               struct phy_dm_struct *dm,
444                               struct phy_status_rpt_8812 *phy_sta_rpt)
445 {
446         u8 sq_rpt;
447
448         if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test)
449                 return 100;
450
451         sq_rpt = phy_sta_rpt->pwdb_all;
452
453         if (sq_rpt > 64)
454                 return 0;
455         else if (sq_rpt < 20)
456                 return 100;
457         else
458                 return ((64 - sq_rpt) * 100) / 44;
459 }
460
461 static inline u8
462 phydm_get_signal_quality_8192(struct dm_phy_status_info *phy_info,
463                               struct phy_dm_struct *dm,
464                               struct phy_status_rpt_8192cd *phy_sta_rpt)
465 {
466         u8 sq_rpt;
467
468         if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test)
469                 return 100;
470
471         sq_rpt = phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all;
472
473         if (sq_rpt > 64)
474                 return 0;
475         else if (sq_rpt < 20)
476                 return 100;
477         else
478                 return ((64 - sq_rpt) * 100) / 44;
479 }
480
481 static u8 odm_query_rx_pwr_percentage(s8 ant_power)
482 {
483         if ((ant_power <= -100) || (ant_power >= 20))
484                 return 0;
485         else if (ant_power >= 0)
486                 return 100;
487         else
488                 return 100 + ant_power;
489 }
490
491 /*
492  * 2012/01/12 MH MOve some signal strength smooth method to MP HAL layer.
493  * IF other SW team do not support the feature, remove this section.??
494  */
495
496 s32 odm_signal_scale_mapping(struct phy_dm_struct *dm, s32 curr_sig)
497 {
498         {
499                 return curr_sig;
500         }
501 }
502
503 static u8 odm_sq_process_patch_rt_cid_819x_lenovo(struct phy_dm_struct *dm,
504                                                   u8 is_cck_rate, u8 pwdb_all,
505                                                   u8 path, u8 RSSI)
506 {
507         u8 sq = 0;
508         return sq;
509 }
510
511 static u8 odm_evm_db_to_percentage(s8 value)
512 {
513         /* -33dB~0dB to 0%~99% */
514         s8 ret_val;
515
516         ret_val = value;
517         ret_val /= 2;
518
519         if (ret_val >= 0)
520                 ret_val = 0;
521
522         if (ret_val <= -33)
523                 ret_val = -33;
524
525         ret_val = 0 - ret_val;
526         ret_val *= 3;
527
528         if (ret_val == 99)
529                 ret_val = 100;
530
531         return (u8)ret_val;
532 }
533
534 static u8 odm_evm_dbm_jaguar_series(s8 value)
535 {
536         s8 ret_val = value;
537
538         /* -33dB~0dB to 33dB ~ 0dB */
539         if (ret_val == -128)
540                 ret_val = 127;
541         else if (ret_val < 0)
542                 ret_val = 0 - ret_val;
543
544         ret_val = ret_val >> 1;
545         return (u8)ret_val;
546 }
547
548 static s16 odm_cfo(s8 value)
549 {
550         s16 ret_val;
551
552         if (value < 0) {
553                 ret_val = 0 - value;
554                 ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */
555                 ret_val =
556                         ret_val | BIT(12); /* set bit12 as 1 for negative cfo */
557         } else {
558                 ret_val = value;
559                 ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */
560         }
561         return ret_val;
562 }
563
564 static u8 phydm_rate_to_num_ss(struct phy_dm_struct *dm, u8 data_rate)
565 {
566         u8 num_ss = 1;
567
568         if (data_rate <= ODM_RATE54M)
569                 num_ss = 1;
570         else if (data_rate <= ODM_RATEMCS31)
571                 num_ss = ((data_rate - ODM_RATEMCS0) >> 3) + 1;
572         else if (data_rate <= ODM_RATEVHTSS1MCS9)
573                 num_ss = 1;
574         else if (data_rate <= ODM_RATEVHTSS2MCS9)
575                 num_ss = 2;
576         else if (data_rate <= ODM_RATEVHTSS3MCS9)
577                 num_ss = 3;
578         else if (data_rate <= ODM_RATEVHTSS4MCS9)
579                 num_ss = 4;
580
581         return num_ss;
582 }
583
584 static void odm_rx_phy_status92c_series_parsing(
585         struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
586         u8 *phy_status, struct dm_per_pkt_info *pktinfo)
587 {
588         u8 i, max_spatial_stream;
589         s8 rx_pwr[4], rx_pwr_all = 0;
590         u8 EVM, pwdb_all = 0, pwdb_all_bt;
591         u8 RSSI, total_rssi = 0;
592         bool is_cck_rate = false;
593         u8 rf_rx_num = 0;
594         u8 LNA_idx = 0;
595         u8 VGA_idx = 0;
596         u8 cck_agc_rpt;
597         u8 num_ss;
598         struct phy_status_rpt_8192cd *phy_sta_rpt =
599                 (struct phy_status_rpt_8192cd *)phy_status;
600
601         is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false;
602
603         if (pktinfo->is_to_self)
604                 dm->curr_station_id = pktinfo->station_id;
605
606         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1;
607         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
608
609         if (is_cck_rate) {
610                 dm->phy_dbg_info.num_qry_phy_status_cck++;
611                 cck_agc_rpt = phy_sta_rpt->cck_agc_rpt_ofdm_cfosho_a;
612
613                 if (dm->support_ic_type & (ODM_RTL8703B)) {
614                 } else { /*3 bit LNA*/
615
616                         LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
617                         VGA_idx = (cck_agc_rpt & 0x1F);
618                 }
619
620                 ODM_RT_TRACE(
621                         dm, ODM_COMP_RSSI_MONITOR,
622                         "ext_lna_gain (( %d )), LNA_idx: (( 0x%x )), VGA_idx: (( 0x%x )), rx_pwr_all: (( %d ))\n",
623                         dm->ext_lna_gain, LNA_idx, VGA_idx, rx_pwr_all);
624
625                 if (dm->board_type & ODM_BOARD_EXT_LNA)
626                         rx_pwr_all -= dm->ext_lna_gain;
627
628                 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
629
630                 if (pktinfo->is_to_self) {
631                         dm->cck_lna_idx = LNA_idx;
632                         dm->cck_vga_idx = VGA_idx;
633                 }
634                 phy_info->rx_pwdb_all = pwdb_all;
635
636                 phy_info->bt_rx_rssi_percentage = pwdb_all;
637                 phy_info->recv_signal_power = rx_pwr_all;
638                 /* (3) Get Signal Quality (EVM) */
639                 {
640                         u8 sq;
641
642                         sq = phydm_get_signal_quality_8192(phy_info, dm,
643                                                            phy_sta_rpt);
644                         phy_info->signal_quality = sq;
645                         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq;
646                         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
647                 }
648
649                 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) {
650                         if (i == 0)
651                                 phy_info->rx_mimo_signal_strength[0] = pwdb_all;
652                         else
653                                 phy_info->rx_mimo_signal_strength[1] = 0;
654                 }
655         } else { /* 2 is OFDM rate */
656                 dm->phy_dbg_info.num_qry_phy_status_ofdm++;
657
658                 /*  */
659                 /* (1)Get RSSI for HT rate */
660                 /*  */
661
662                 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) {
663                         /* 2008/01/30 MH we will judge RF RX path now. */
664                         if (dm->rf_path_rx_enable & BIT(i))
665                                 rf_rx_num++;
666                         /* else */
667                         /* continue; */
668
669                         rx_pwr[i] =
670                                 ((phy_sta_rpt->path_agc[i].gain & 0x3F) * 2) -
671                                 110;
672
673                         if (pktinfo->is_to_self) {
674                                 dm->ofdm_agc_idx[i] =
675                                         (phy_sta_rpt->path_agc[i].gain & 0x3F);
676                                 /**/
677                         }
678
679                         phy_info->rx_pwr[i] = rx_pwr[i];
680
681                         /* Translate DBM to percentage. */
682                         RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]);
683                         total_rssi += RSSI;
684
685                         phy_info->rx_mimo_signal_strength[i] = (u8)RSSI;
686
687                         /* Get Rx snr value in DB */
688                         dm->phy_dbg_info.rx_snr_db[i] =
689                                 (s32)(phy_sta_rpt->path_rxsnr[i] / 2);
690                         phy_info->rx_snr[i] = dm->phy_dbg_info.rx_snr_db[i];
691
692                         /* Record Signal Strength for next packet */
693                         /* if(pktinfo->is_packet_match_bssid) */
694                         {
695                         }
696                 }
697
698                 /*  */
699                 /* (2)PWDB, Average PWDB calcuated by hardware (for RA) */
700                 /*  */
701                 rx_pwr_all = (((phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all) >> 1) &
702                               0x7f) -
703                              110;
704
705                 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
706                 pwdb_all_bt = pwdb_all;
707
708                 phy_info->rx_pwdb_all = pwdb_all;
709                 phy_info->bt_rx_rssi_percentage = pwdb_all_bt;
710                 phy_info->rx_power = rx_pwr_all;
711                 phy_info->recv_signal_power = rx_pwr_all;
712
713                 if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) {
714                         /* do nothing */
715                 } else if ((dm->support_platform == ODM_WIN) &&
716                            (dm->patch_id == 25)) {
717                         /* do nothing */
718                 } else { /* mgnt_info->customer_id != RT_CID_819X_LENOVO */
719                         /*  */
720                         /* (3)EVM of HT rate */
721                         /*  */
722                         if (pktinfo->data_rate >= ODM_RATEMCS8 &&
723                             pktinfo->data_rate <= ODM_RATEMCS15) {
724                                 /* both spatial stream make sense */
725                                 max_spatial_stream = 2;
726                         } else {
727                                 /* only spatial stream 1 makes sense */
728                                 max_spatial_stream = 1;
729                         }
730
731                         for (i = 0; i < max_spatial_stream; i++) {
732                                 /*Don't use shift operation like "rx_evmX >>= 1"
733                                  *because the compilor of free build environment
734                                  *fill most significant bit to "zero" when doing
735                                  *shifting operation which may change a negative
736                                  *value to positive one, then the dbm value
737                                  *(which is supposed to be negative)  is not
738                                  *correct anymore.
739                                  */
740                                 EVM = odm_evm_db_to_percentage(
741                                         (phy_sta_rpt
742                                                  ->stream_rxevm[i])); /* dbm */
743
744                                 /* Fill value in RFD, Get the first spatial
745                                  * stream only
746                                  */
747                                 if (i == ODM_RF_PATH_A)
748                                         phy_info->signal_quality =
749                                                 (u8)(EVM & 0xff);
750                                 phy_info->rx_mimo_signal_quality[i] =
751                                         (u8)(EVM & 0xff);
752                         }
753                 }
754
755                 num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
756                 odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->path_cfotail, num_ss);
757         }
758         /* UI BSS List signal strength(in percentage), make it good looking,
759          * from 0~100.
760          */
761         /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */
762         if (is_cck_rate) {
763                 phy_info->signal_strength = (u8)(
764                         odm_signal_scale_mapping(dm, pwdb_all)); /*pwdb_all;*/
765         } else {
766                 if (rf_rx_num != 0) {
767                         phy_info->signal_strength =
768                                 (u8)(odm_signal_scale_mapping(dm, total_rssi /=
769                                                                   rf_rx_num));
770                 }
771         }
772
773         /* For 92C/92D HW (Hybrid) Antenna Diversity */
774 }
775
776 static void
777 odm_rx_phy_bw_jaguar_series_parsing(struct dm_phy_status_info *phy_info,
778                                     struct dm_per_pkt_info *pktinfo,
779                                     struct phy_status_rpt_8812 *phy_sta_rpt)
780 {
781         if (pktinfo->data_rate <= ODM_RATE54M) {
782                 switch (phy_sta_rpt->r_RFMOD) {
783                 case 1:
784                         if (phy_sta_rpt->sub_chnl == 0)
785                                 phy_info->band_width = 1;
786                         else
787                                 phy_info->band_width = 0;
788                         break;
789
790                 case 2:
791                         if (phy_sta_rpt->sub_chnl == 0)
792                                 phy_info->band_width = 2;
793                         else if (phy_sta_rpt->sub_chnl == 9 ||
794                                  phy_sta_rpt->sub_chnl == 10)
795                                 phy_info->band_width = 1;
796                         else
797                                 phy_info->band_width = 0;
798                         break;
799
800                 default:
801                 case 0:
802                         phy_info->band_width = 0;
803                         break;
804                 }
805         }
806 }
807
808 static void odm_rx_phy_status_jaguar_series_parsing(
809         struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
810         u8 *phy_status, struct dm_per_pkt_info *pktinfo)
811 {
812         u8 i, max_spatial_stream;
813         s8 rx_pwr[4], rx_pwr_all = 0;
814         u8 EVM = 0, evm_dbm, pwdb_all = 0, pwdb_all_bt;
815         u8 RSSI, avg_rssi = 0, best_rssi = 0, second_rssi = 0;
816         u8 is_cck_rate = 0;
817         u8 rf_rx_num = 0;
818         u8 cck_highpwr = 0;
819         u8 LNA_idx, VGA_idx;
820         struct phy_status_rpt_8812 *phy_sta_rpt =
821                 (struct phy_status_rpt_8812 *)phy_status;
822         struct fast_antenna_training *fat_tab = &dm->dm_fat_table;
823         u8 num_ss;
824
825         odm_rx_phy_bw_jaguar_series_parsing(phy_info, pktinfo, phy_sta_rpt);
826
827         if (pktinfo->data_rate <= ODM_RATE11M)
828                 is_cck_rate = true;
829         else
830                 is_cck_rate = false;
831
832         if (pktinfo->is_to_self)
833                 dm->curr_station_id = pktinfo->station_id;
834         else
835                 dm->curr_station_id = 0xff;
836
837         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1;
838         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
839         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_C] = -1;
840         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_D] = -1;
841
842         if (is_cck_rate) {
843                 u8 cck_agc_rpt;
844
845                 dm->phy_dbg_info.num_qry_phy_status_cck++;
846
847                 /*(1)Hardware does not provide RSSI for CCK*/
848                 /*(2)PWDB, Average PWDB calculated by hardware (for RA)*/
849
850                 cck_highpwr = dm->is_cck_high_power;
851
852                 cck_agc_rpt = phy_sta_rpt->cfosho[0];
853                 LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
854                 VGA_idx = (cck_agc_rpt & 0x1F);
855
856                 if (dm->support_ic_type == ODM_RTL8812) {
857                         rx_pwr_all =
858                                 phydm_get_rx_pwr(LNA_idx, VGA_idx, cck_highpwr);
859                         rx_pwr_all += 6;
860                         pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
861                         pwdb_all = phydm_adjust_pwdb(cck_highpwr, pwdb_all);
862
863                 } else if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
864                         s8 pout = -6;
865
866                         switch (LNA_idx) {
867                         case 5:
868                                 rx_pwr_all = pout - 32 - (2 * VGA_idx);
869                                 break;
870                         case 4:
871                                 rx_pwr_all = pout - 24 - (2 * VGA_idx);
872                                 break;
873                         case 2:
874                                 rx_pwr_all = pout - 11 - (2 * VGA_idx);
875                                 break;
876                         case 1:
877                                 rx_pwr_all = pout + 5 - (2 * VGA_idx);
878                                 break;
879                         case 0:
880                                 rx_pwr_all = pout + 21 - (2 * VGA_idx);
881                                 break;
882                         }
883                         pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
884                 } else if (dm->support_ic_type == ODM_RTL8814A ||
885                            dm->support_ic_type == ODM_RTL8822B) {
886                         s8 pout = -6;
887
888                         switch (LNA_idx) {
889                         /*CCK only use LNA: 2, 3, 5, 7*/
890                         case 7:
891                                 rx_pwr_all = pout - 32 - (2 * VGA_idx);
892                                 break;
893                         case 5:
894                                 rx_pwr_all = pout - 22 - (2 * VGA_idx);
895                                 break;
896                         case 3:
897                                 rx_pwr_all = pout - 2 - (2 * VGA_idx);
898                                 break;
899                         case 2:
900                                 rx_pwr_all = pout + 5 - (2 * VGA_idx);
901                                 break;
902                         default:
903                                 break;
904                         }
905                         pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
906                 }
907
908                 dm->cck_lna_idx = LNA_idx;
909                 dm->cck_vga_idx = VGA_idx;
910                 phy_info->rx_pwdb_all = pwdb_all;
911                 phy_info->bt_rx_rssi_percentage = pwdb_all;
912                 phy_info->recv_signal_power = rx_pwr_all;
913                 /*(3) Get Signal Quality (EVM)*/
914                 {
915                         u8 sq;
916
917                         if ((dm->support_platform == ODM_WIN) &&
918                             (dm->patch_id == RT_CID_819X_LENOVO))
919                                 sq = odm_sq_process_patch_rt_cid_819x_lenovo(
920                                         dm, is_cck_rate, pwdb_all, 0, 0);
921                         else
922                                 sq = phydm_get_signal_quality_8812(phy_info, dm,
923                                                                    phy_sta_rpt);
924
925                         phy_info->signal_quality = sq;
926                         phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq;
927                 }
928
929                 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
930                         if (i == 0)
931                                 phy_info->rx_mimo_signal_strength[0] = pwdb_all;
932                         else
933                                 phy_info->rx_mimo_signal_strength[i] = 0;
934                 }
935         } else {
936                 /*is OFDM rate*/
937                 fat_tab->hw_antsw_occur = phy_sta_rpt->hw_antsw_occur;
938
939                 dm->phy_dbg_info.num_qry_phy_status_ofdm++;
940
941                 /*(1)Get RSSI for OFDM rate*/
942
943                 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
944                         /*2008/01/30 MH we will judge RF RX path now.*/
945                         if (dm->rf_path_rx_enable & BIT(i))
946                                 rf_rx_num++;
947                         /*2012.05.25 LukeLee: Testchip AGC report is wrong,
948                          *it should be restored back to old formula in MP chip
949                          */
950                         if (i < ODM_RF_PATH_C)
951                                 rx_pwr[i] = (phy_sta_rpt->gain_trsw[i] & 0x7F) -
952                                             110;
953                         else
954                                 rx_pwr[i] = (phy_sta_rpt->gain_trsw_cd[i - 2] &
955                                              0x7F) -
956                                             110;
957
958                         phy_info->rx_pwr[i] = rx_pwr[i];
959
960                         /* Translate DBM to percentage. */
961                         RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]);
962
963                         /*total_rssi += RSSI;*/
964                         /*Get the best two RSSI*/
965                         if (RSSI > best_rssi && RSSI > second_rssi) {
966                                 second_rssi = best_rssi;
967                                 best_rssi = RSSI;
968                         } else if (RSSI > second_rssi && RSSI <= best_rssi) {
969                                 second_rssi = RSSI;
970                         }
971
972                         phy_info->rx_mimo_signal_strength[i] = (u8)RSSI;
973
974                         /*Get Rx snr value in DB*/
975                         if (i < ODM_RF_PATH_C)
976                                 phy_info->rx_snr[i] =
977                                         dm->phy_dbg_info.rx_snr_db[i] =
978                                                 phy_sta_rpt->rxsnr[i] / 2;
979                         else if (dm->support_ic_type &
980                                  (ODM_RTL8814A | ODM_RTL8822B))
981                                 phy_info->rx_snr[i] = dm->phy_dbg_info
982                                                               .rx_snr_db[i] =
983                                         phy_sta_rpt->csi_current[i - 2] / 2;
984
985                         /*(2) CFO_short  & CFO_tail*/
986                         if (i < ODM_RF_PATH_C) {
987                                 phy_info->cfo_short[i] =
988                                         odm_cfo((phy_sta_rpt->cfosho[i]));
989                                 phy_info->cfo_tail[i] =
990                                         odm_cfo((phy_sta_rpt->cfotail[i]));
991                         }
992                 }
993
994                 /*(3)PWDB, Average PWDB calculated by hardware (for RA)*/
995
996                 /*2012.05.25 LukeLee: Testchip AGC report is wrong, it should be
997                  *restored back to old formula in MP chip
998                  */
999                 if ((dm->support_ic_type &
1000                      (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) &&
1001                     (!dm->is_mp_chip))
1002                         rx_pwr_all = (phy_sta_rpt->pwdb_all & 0x7f) - 110;
1003                 else
1004                         rx_pwr_all = (((phy_sta_rpt->pwdb_all) >> 1) & 0x7f) -
1005                                      110; /*OLD FORMULA*/
1006
1007                 pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
1008                 pwdb_all_bt = pwdb_all;
1009
1010                 phy_info->rx_pwdb_all = pwdb_all;
1011                 phy_info->bt_rx_rssi_percentage = pwdb_all_bt;
1012                 phy_info->rx_power = rx_pwr_all;
1013                 phy_info->recv_signal_power = rx_pwr_all;
1014
1015                 if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) {
1016                         /*do nothing*/
1017                 } else {
1018                         /*mgnt_info->customer_id != RT_CID_819X_LENOVO*/
1019
1020                         /*(4)EVM of OFDM rate*/
1021
1022                         if ((pktinfo->data_rate >= ODM_RATEMCS8) &&
1023                             (pktinfo->data_rate <= ODM_RATEMCS15))
1024                                 max_spatial_stream = 2;
1025                         else if ((pktinfo->data_rate >= ODM_RATEVHTSS2MCS0) &&
1026                                  (pktinfo->data_rate <= ODM_RATEVHTSS2MCS9))
1027                                 max_spatial_stream = 2;
1028                         else if ((pktinfo->data_rate >= ODM_RATEMCS16) &&
1029                                  (pktinfo->data_rate <= ODM_RATEMCS23))
1030                                 max_spatial_stream = 3;
1031                         else if ((pktinfo->data_rate >= ODM_RATEVHTSS3MCS0) &&
1032                                  (pktinfo->data_rate <= ODM_RATEVHTSS3MCS9))
1033                                 max_spatial_stream = 3;
1034                         else
1035                                 max_spatial_stream = 1;
1036
1037                         for (i = 0; i < max_spatial_stream; i++) {
1038                                 /*Don't use shift operation like "rx_evmX >>= 1"
1039                                  *because the compilor of free build environment
1040                                  *fill most significant bit to "zero" when doing
1041                                  *shifting operation which may change a negative
1042                                  *value to positive one, then the dbm value
1043                                  *(which is supposed to be negative) is not
1044                                  *correct anymore.
1045                                  */
1046
1047                                 EVM = phydm_get_odm_evm(i, pktinfo,
1048                                                         phy_sta_rpt);
1049                                 evm_dbm = phydm_get_evm_dbm(i, EVM, phy_sta_rpt,
1050                                                             phy_info);
1051                                 phy_info->rx_mimo_signal_quality[i] = EVM;
1052                                 phy_info->rx_mimo_evm_dbm[i] = evm_dbm;
1053                         }
1054                 }
1055
1056                 num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
1057                 odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfotail, num_ss);
1058         }
1059
1060         /*UI BSS List signal strength(in percentage), make it good looking,
1061          *from 0~100.
1062          */
1063         /*It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().*/
1064         if (is_cck_rate) {
1065                 phy_info->signal_strength = (u8)(
1066                         odm_signal_scale_mapping(dm, pwdb_all)); /*pwdb_all;*/
1067         } else {
1068                 if (rf_rx_num != 0) {
1069                         /* 2015/01 Sean, use the best two RSSI only,
1070                          * suggested by Ynlin and ChenYu.
1071                          */
1072                         if (rf_rx_num == 1)
1073                                 avg_rssi = best_rssi;
1074                         else
1075                                 avg_rssi = (best_rssi + second_rssi) / 2;
1076                         phy_info->signal_strength =
1077                                 (u8)(odm_signal_scale_mapping(dm, avg_rssi));
1078                 }
1079         }
1080         dm->rx_pwdb_ave = dm->rx_pwdb_ave + phy_info->rx_pwdb_all;
1081
1082         dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_anta;
1083         dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_antb;
1084         dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_antc;
1085         dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_antd;
1086 }
1087
1088 void phydm_reset_rssi_for_dm(struct phy_dm_struct *dm, u8 station_id)
1089 {
1090         struct rtl_sta_info *entry;
1091
1092         entry = dm->odm_sta_info[station_id];
1093
1094         if (!IS_STA_VALID(entry))
1095                 return;
1096
1097         ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR,
1098                      "Reset RSSI for macid = (( %d ))\n", station_id);
1099
1100         entry->rssi_stat.undecorated_smoothed_cck = -1;
1101         entry->rssi_stat.undecorated_smoothed_ofdm = -1;
1102         entry->rssi_stat.undecorated_smoothed_pwdb = -1;
1103         entry->rssi_stat.ofdm_pkt = 0;
1104         entry->rssi_stat.cck_pkt = 0;
1105         entry->rssi_stat.cck_sum_power = 0;
1106         entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_INIT;
1107         entry->rssi_stat.packet_map = 0;
1108         entry->rssi_stat.valid_bit = 0;
1109 }
1110
1111 void odm_init_rssi_for_dm(struct phy_dm_struct *dm) {}
1112
1113 static void odm_process_rssi_for_dm(struct phy_dm_struct *dm,
1114                                     struct dm_phy_status_info *phy_info,
1115                                     struct dm_per_pkt_info *pktinfo)
1116 {
1117         s32 undecorated_smoothed_pwdb, undecorated_smoothed_cck,
1118                 undecorated_smoothed_ofdm;
1119         u8 is_cck_rate = 0;
1120         u8 send_rssi_2_fw = 0;
1121         struct rtl_sta_info *entry;
1122
1123         if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM)
1124                 return;
1125
1126         /* 2012/05/30 MH/Luke.Lee Add some description */
1127         /* In windows driver: AP/IBSS mode STA */
1128         entry = dm->odm_sta_info[pktinfo->station_id];
1129
1130         if (!IS_STA_VALID(entry))
1131                 return;
1132
1133         {
1134                 if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/
1135                         return;
1136         }
1137
1138         if (pktinfo->is_packet_beacon)
1139                 dm->phy_dbg_info.num_qry_beacon_pkt++;
1140
1141         is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false;
1142         dm->rx_rate = pktinfo->data_rate;
1143
1144         /* --------------Statistic for antenna/path diversity---------------- */
1145
1146         /* -----------------Smart Antenna Debug Message------------------ */
1147
1148         undecorated_smoothed_cck = entry->rssi_stat.undecorated_smoothed_cck;
1149         undecorated_smoothed_ofdm = entry->rssi_stat.undecorated_smoothed_ofdm;
1150         undecorated_smoothed_pwdb = entry->rssi_stat.undecorated_smoothed_pwdb;
1151
1152         if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) {
1153                 if (!is_cck_rate) /* ofdm rate */
1154                         undecorated_smoothed_ofdm = phydm_process_rssi_ofdm(
1155                                 dm, phy_info, entry, undecorated_smoothed_ofdm);
1156                 else
1157                         undecorated_smoothed_cck = phydm_process_rssi_cck(
1158                                 dm, phy_info, entry, undecorated_smoothed_cck);
1159
1160                 undecorated_smoothed_pwdb = phydm_process_rssi_pwdb(
1161                         dm, entry, pktinfo, undecorated_smoothed_ofdm,
1162                         undecorated_smoothed_cck);
1163
1164                 if ((entry->rssi_stat.ofdm_pkt >= 1 ||
1165                      entry->rssi_stat.cck_pkt >= 5) &&
1166                     (entry->rssi_stat.is_send_rssi == RA_RSSI_STATE_INIT)) {
1167                         send_rssi_2_fw = 1;
1168                         entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_SEND;
1169                 }
1170
1171                 entry->rssi_stat.undecorated_smoothed_cck =
1172                         undecorated_smoothed_cck;
1173                 entry->rssi_stat.undecorated_smoothed_ofdm =
1174                         undecorated_smoothed_ofdm;
1175                 entry->rssi_stat.undecorated_smoothed_pwdb =
1176                         undecorated_smoothed_pwdb;
1177
1178                 if (send_rssi_2_fw) { /* Trigger init rate by RSSI */
1179
1180                         if (entry->rssi_stat.ofdm_pkt != 0)
1181                                 entry->rssi_stat.undecorated_smoothed_pwdb =
1182                                         undecorated_smoothed_ofdm;
1183
1184                         ODM_RT_TRACE(
1185                                 dm, ODM_COMP_RSSI_MONITOR,
1186                                 "[Send to FW] PWDB = (( %d )), ofdm_pkt = (( %d )), cck_pkt = (( %d ))\n",
1187                                 undecorated_smoothed_pwdb,
1188                                 entry->rssi_stat.ofdm_pkt,
1189                                 entry->rssi_stat.cck_pkt);
1190                 }
1191         }
1192 }
1193
1194 /*
1195  * Endianness before calling this API
1196  */
1197 static void odm_phy_status_query_92c_series(struct phy_dm_struct *dm,
1198                                             struct dm_phy_status_info *phy_info,
1199                                             u8 *phy_status,
1200                                             struct dm_per_pkt_info *pktinfo)
1201 {
1202         odm_rx_phy_status92c_series_parsing(dm, phy_info, phy_status, pktinfo);
1203         odm_process_rssi_for_dm(dm, phy_info, pktinfo);
1204 }
1205
1206 /*
1207  * Endianness before calling this API
1208  */
1209
1210 static void odm_phy_status_query_jaguar_series(
1211         struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info,
1212         u8 *phy_status, struct dm_per_pkt_info *pktinfo)
1213 {
1214         odm_rx_phy_status_jaguar_series_parsing(dm, phy_info, phy_status,
1215                                                 pktinfo);
1216         odm_process_rssi_for_dm(dm, phy_info, pktinfo);
1217 }
1218
1219 void odm_phy_status_query(struct phy_dm_struct *dm,
1220                           struct dm_phy_status_info *phy_info, u8 *phy_status,
1221                           struct dm_per_pkt_info *pktinfo)
1222 {
1223         if (dm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE) {
1224                 phydm_rx_phy_status_new_type(dm, phy_status, pktinfo, phy_info);
1225                 return;
1226         }
1227
1228         if (dm->support_ic_type & ODM_IC_11AC_SERIES)
1229                 odm_phy_status_query_jaguar_series(dm, phy_info, phy_status,
1230                                                    pktinfo);
1231
1232         if (dm->support_ic_type & ODM_IC_11N_SERIES)
1233                 odm_phy_status_query_92c_series(dm, phy_info, phy_status,
1234                                                 pktinfo);
1235 }
1236
1237 /* For future use. */
1238 void odm_mac_status_query(struct phy_dm_struct *dm, u8 *mac_status, u8 mac_id,
1239                           bool is_packet_match_bssid, bool is_packet_to_self,
1240                           bool is_packet_beacon)
1241 {
1242         /* 2011/10/19 Driver team will handle in the future. */
1243 }
1244
1245 /*
1246  * If you want to add a new IC, Please follow below template and generate
1247  * a new one.
1248  */
1249
1250 enum hal_status
1251 odm_config_rf_with_header_file(struct phy_dm_struct *dm,
1252                                enum odm_rf_config_type config_type,
1253                                enum odm_rf_radio_path e_rf_path)
1254 {
1255         ODM_RT_TRACE(dm, ODM_COMP_INIT,
1256                      "===>%s (%s)\n", __func__,
1257                      (dm->is_mp_chip) ? "MPChip" : "TestChip");
1258         ODM_RT_TRACE(
1259                 dm, ODM_COMP_INIT,
1260                 "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
1261                 dm->support_platform, dm->support_interface, dm->board_type);
1262
1263         /* 1 AP doesn't use PHYDM power tracking table in these ICs */
1264         /* JJ ADD 20161014 */
1265
1266         /* 1 All platforms support */
1267         if (dm->support_ic_type == ODM_RTL8822B) {
1268                 if (config_type == CONFIG_RF_RADIO) {
1269                         if (e_rf_path == ODM_RF_PATH_A)
1270                                 READ_AND_CONFIG_MP(8822b, _radioa);
1271                         else if (e_rf_path == ODM_RF_PATH_B)
1272                                 READ_AND_CONFIG_MP(8822b, _radiob);
1273                 } else if (config_type == CONFIG_RF_TXPWR_LMT) {
1274                         if (dm->rfe_type == 5)
1275                                 READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type5);
1276                         else
1277                                 READ_AND_CONFIG_MP(8822b, _txpwr_lmt);
1278                 }
1279         }
1280
1281         return HAL_STATUS_SUCCESS;
1282 }
1283
1284 enum hal_status
1285 odm_config_rf_with_tx_pwr_track_header_file(struct phy_dm_struct *dm)
1286 {
1287         ODM_RT_TRACE(dm, ODM_COMP_INIT,
1288                      "===>%s (%s)\n", __func__,
1289                      (dm->is_mp_chip) ? "MPChip" : "TestChip");
1290         ODM_RT_TRACE(
1291                 dm, ODM_COMP_INIT,
1292                 "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
1293                 dm->support_platform, dm->support_interface, dm->board_type);
1294
1295         /* 1 AP doesn't use PHYDM power tracking table in these ICs */
1296         /* JJ ADD 20161014 */
1297
1298         /* 1 All platforms support */
1299
1300         if (dm->support_ic_type == ODM_RTL8822B) {
1301                 if (dm->rfe_type == 0)
1302                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type0);
1303                 else if (dm->rfe_type == 1)
1304                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type1);
1305                 else if (dm->rfe_type == 2)
1306                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type2);
1307                 else if ((dm->rfe_type == 3) || (dm->rfe_type == 5))
1308                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type3_type5);
1309                 else if (dm->rfe_type == 4)
1310                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type4);
1311                 else if (dm->rfe_type == 6)
1312                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type6);
1313                 else if (dm->rfe_type == 7)
1314                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type7);
1315                 else if (dm->rfe_type == 8)
1316                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type8);
1317                 else if (dm->rfe_type == 9)
1318                         READ_AND_CONFIG_MP(8822b, _txpowertrack_type9);
1319                 else
1320                         READ_AND_CONFIG_MP(8822b, _txpowertrack);
1321         }
1322
1323         return HAL_STATUS_SUCCESS;
1324 }
1325
1326 enum hal_status
1327 odm_config_bb_with_header_file(struct phy_dm_struct *dm,
1328                                enum odm_bb_config_type config_type)
1329 {
1330         /* 1 AP doesn't use PHYDM initialization in these ICs */
1331         /* JJ ADD 20161014 */
1332
1333         /* 1 All platforms support */
1334         if (dm->support_ic_type == ODM_RTL8822B) {
1335                 if (config_type == CONFIG_BB_PHY_REG)
1336                         READ_AND_CONFIG_MP(8822b, _phy_reg);
1337                 else if (config_type == CONFIG_BB_AGC_TAB)
1338                         READ_AND_CONFIG_MP(8822b, _agc_tab);
1339                 else if (config_type == CONFIG_BB_PHY_REG_PG)
1340                         READ_AND_CONFIG_MP(8822b, _phy_reg_pg);
1341                 /*else if (config_type == CONFIG_BB_PHY_REG_MP)*/
1342                 /*READ_AND_CONFIG_MP(8822b, _phy_reg_mp);*/
1343         }
1344
1345         return HAL_STATUS_SUCCESS;
1346 }
1347
1348 enum hal_status odm_config_mac_with_header_file(struct phy_dm_struct *dm)
1349 {
1350         ODM_RT_TRACE(dm, ODM_COMP_INIT,
1351                      "===>%s (%s)\n", __func__,
1352                      (dm->is_mp_chip) ? "MPChip" : "TestChip");
1353         ODM_RT_TRACE(
1354                 dm, ODM_COMP_INIT,
1355                 "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n",
1356                 dm->support_platform, dm->support_interface, dm->board_type);
1357
1358         /* 1 AP doesn't use PHYDM initialization in these ICs */
1359         /* JJ ADD 20161014 */
1360
1361         /* 1 All platforms support */
1362         if (dm->support_ic_type == ODM_RTL8822B)
1363                 READ_AND_CONFIG_MP(8822b, _mac_reg);
1364
1365         return HAL_STATUS_SUCCESS;
1366 }
1367
1368 enum hal_status
1369 odm_config_fw_with_header_file(struct phy_dm_struct *dm,
1370                                enum odm_fw_config_type config_type,
1371                                u8 *p_firmware, u32 *size)
1372 {
1373         return HAL_STATUS_SUCCESS;
1374 }
1375
1376 u32 odm_get_hw_img_version(struct phy_dm_struct *dm)
1377 {
1378         u32 version = 0;
1379
1380         /* 1 AP doesn't use PHYDM initialization in these ICs */
1381         /* JJ ADD 20161014 */
1382
1383         /*1 All platforms support*/
1384         if (dm->support_ic_type == ODM_RTL8822B)
1385                 version = GET_VERSION_MP(8822b, _mac_reg);
1386
1387         return version;
1388 }
1389
1390 /* For 8822B only!! need to move to FW finally */
1391 /*==============================================*/
1392
1393 bool phydm_query_is_mu_api(struct phy_dm_struct *phydm, u8 ppdu_idx,
1394                            u8 *p_data_rate, u8 *p_gid)
1395 {
1396         u8 data_rate = 0, gid = 0;
1397         bool is_mu = false;
1398
1399         data_rate = phydm->phy_dbg_info.num_of_ppdu[ppdu_idx];
1400         gid = phydm->phy_dbg_info.gid_num[ppdu_idx];
1401
1402         if (data_rate & BIT(7)) {
1403                 is_mu = true;
1404                 data_rate = data_rate & ~(BIT(7));
1405         } else {
1406                 is_mu = false;
1407         }
1408
1409         *p_data_rate = data_rate;
1410         *p_gid = gid;
1411
1412         return is_mu;
1413 }
1414
1415 static void phydm_rx_statistic_cal(struct phy_dm_struct *phydm, u8 *phy_status,
1416                                    struct dm_per_pkt_info *pktinfo)
1417 {
1418         struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt =
1419                 (struct phy_status_rpt_jaguar2_type1 *)phy_status;
1420         u8 date_rate = pktinfo->data_rate & ~(BIT(7));
1421
1422         if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) {
1423                 if (date_rate >= ODM_RATEVHTSS1MCS0) {
1424                         phydm->phy_dbg_info
1425                                 .num_qry_mu_vht_pkt[date_rate - 0x2C]++;
1426                         phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] =
1427                                 date_rate | BIT(7);
1428                         phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] =
1429                                 phy_sta_rpt->gid;
1430                 }
1431
1432         } else {
1433                 if (date_rate >= ODM_RATEVHTSS1MCS0) {
1434                         phydm->phy_dbg_info.num_qry_vht_pkt[date_rate - 0x2C]++;
1435                         phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] =
1436                                 date_rate;
1437                         phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] =
1438                                 phy_sta_rpt->gid;
1439                 }
1440         }
1441 }
1442
1443 static void phydm_reset_phy_info(struct phy_dm_struct *phydm,
1444                                  struct dm_phy_status_info *phy_info)
1445 {
1446         phy_info->rx_pwdb_all = 0;
1447         phy_info->signal_quality = 0;
1448         phy_info->band_width = 0;
1449         phy_info->rx_count = 0;
1450         odm_memory_set(phydm, phy_info->rx_mimo_signal_quality, 0, 4);
1451         odm_memory_set(phydm, phy_info->rx_mimo_signal_strength, 0, 4);
1452         odm_memory_set(phydm, phy_info->rx_snr, 0, 4);
1453
1454         phy_info->rx_power = -110;
1455         phy_info->recv_signal_power = -110;
1456         phy_info->bt_rx_rssi_percentage = 0;
1457         phy_info->signal_strength = 0;
1458         phy_info->bt_coex_pwr_adjust = 0;
1459         phy_info->channel = 0;
1460         phy_info->is_mu_packet = 0;
1461         phy_info->is_beamformed = 0;
1462         phy_info->rxsc = 0;
1463         odm_memory_set(phydm, phy_info->rx_pwr, -110, 4);
1464         odm_memory_set(phydm, phy_info->rx_mimo_evm_dbm, 0, 4);
1465         odm_memory_set(phydm, phy_info->cfo_short, 0, 8);
1466         odm_memory_set(phydm, phy_info->cfo_tail, 0, 8);
1467 }
1468
1469 static void phydm_set_per_path_phy_info(u8 rx_path, s8 rx_pwr, s8 rx_evm,
1470                                         s8 cfo_tail, s8 rx_snr,
1471                                         struct dm_phy_status_info *phy_info)
1472 {
1473         u8 evm_dbm = 0;
1474         u8 evm_percentage = 0;
1475
1476         /* SNR is S(8,1), EVM is S(8,1), CFO is S(8,7) */
1477
1478         if (rx_evm < 0) {
1479                 /* Calculate EVM in dBm */
1480                 evm_dbm = ((u8)(0 - rx_evm) >> 1);
1481
1482                 /* Calculate EVM in percentage */
1483                 if (evm_dbm >= 33)
1484                         evm_percentage = 100;
1485                 else
1486                         evm_percentage = (evm_dbm << 1) + (evm_dbm);
1487         }
1488
1489         phy_info->rx_pwr[rx_path] = rx_pwr;
1490         phy_info->rx_mimo_evm_dbm[rx_path] = evm_dbm;
1491
1492         /* CFO = CFO_tail * 312.5 / 2^7 ~= CFO tail * 39/512 (kHz)*/
1493         phy_info->cfo_tail[rx_path] = cfo_tail;
1494         phy_info->cfo_tail[rx_path] = ((phy_info->cfo_tail[rx_path] << 5) +
1495                                        (phy_info->cfo_tail[rx_path] << 2) +
1496                                        (phy_info->cfo_tail[rx_path] << 1) +
1497                                        (phy_info->cfo_tail[rx_path])) >>
1498                                       9;
1499
1500         phy_info->rx_mimo_signal_strength[rx_path] =
1501                 odm_query_rx_pwr_percentage(rx_pwr);
1502         phy_info->rx_mimo_signal_quality[rx_path] = evm_percentage;
1503         phy_info->rx_snr[rx_path] = rx_snr >> 1;
1504 }
1505
1506 static void phydm_set_common_phy_info(s8 rx_power, u8 channel,
1507                                       bool is_beamformed, bool is_mu_packet,
1508                                       u8 bandwidth, u8 signal_quality, u8 rxsc,
1509                                       struct dm_phy_status_info *phy_info)
1510 {
1511         phy_info->rx_power = rx_power; /* RSSI in dB */
1512         phy_info->recv_signal_power = rx_power; /* RSSI in dB */
1513         phy_info->channel = channel; /* channel number */
1514         phy_info->is_beamformed = is_beamformed; /* apply BF */
1515         phy_info->is_mu_packet = is_mu_packet; /* MU packet */
1516         phy_info->rxsc = rxsc;
1517         phy_info->rx_pwdb_all =
1518                 odm_query_rx_pwr_percentage(rx_power); /* RSSI in percentage */
1519         phy_info->signal_quality = signal_quality; /* signal quality */
1520         phy_info->band_width = bandwidth; /* bandwidth */
1521 }
1522
1523 static void phydm_get_rx_phy_status_type0(struct phy_dm_struct *dm,
1524                                           u8 *phy_status,
1525                                           struct dm_per_pkt_info *pktinfo,
1526                                           struct dm_phy_status_info *phy_info)
1527 {
1528         /* type 0 is used for cck packet */
1529
1530         struct phy_status_rpt_jaguar2_type0 *phy_sta_rpt =
1531                 (struct phy_status_rpt_jaguar2_type0 *)phy_status;
1532         u8 sq = 0;
1533         s8 rx_power = phy_sta_rpt->pwdb - 110;
1534
1535         /* JJ ADD 20161014 */
1536
1537         /* Calculate Signal Quality*/
1538         if (pktinfo->is_packet_match_bssid) {
1539                 if (phy_sta_rpt->signal_quality >= 64) {
1540                         sq = 0;
1541                 } else if (phy_sta_rpt->signal_quality <= 20) {
1542                         sq = 100;
1543                 } else {
1544                         /* mapping to 2~99% */
1545                         sq = 64 - phy_sta_rpt->signal_quality;
1546                         sq = ((sq << 3) + sq) >> 2;
1547                 }
1548         }
1549
1550         /* Modify CCK PWDB if old AGC */
1551         if (!dm->cck_new_agc) {
1552                 u8 lna_idx, vga_idx;
1553
1554                 lna_idx = ((phy_sta_rpt->lna_h << 3) | phy_sta_rpt->lna_l);
1555                 vga_idx = phy_sta_rpt->vga;
1556
1557                 /* JJ ADD 20161014 */
1558
1559                 /* Need to do !! */
1560                 /*if (dm->support_ic_type & ODM_RTL8822B) */
1561                 /*rx_power = odm_CCKRSSI_8822B(LNA_idx, VGA_idx);*/
1562         }
1563
1564         /* Update CCK packet counter */
1565         dm->phy_dbg_info.num_qry_phy_status_cck++;
1566
1567         /*CCK no STBC and LDPC*/
1568         dm->phy_dbg_info.is_ldpc_pkt = false;
1569         dm->phy_dbg_info.is_stbc_pkt = false;
1570
1571         /* Update Common information */
1572         phydm_set_common_phy_info(rx_power, phy_sta_rpt->channel, false, false,
1573                                   ODM_BW20M, sq, phy_sta_rpt->rxsc, phy_info);
1574
1575         /* Update CCK pwdb */
1576         /* Update per-path information */
1577         phydm_set_per_path_phy_info(ODM_RF_PATH_A, rx_power, 0, 0, 0, phy_info);
1578
1579         dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a;
1580         dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b;
1581         dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c;
1582         dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d;
1583 }
1584
1585 static void phydm_get_rx_phy_status_type1(struct phy_dm_struct *dm,
1586                                           u8 *phy_status,
1587                                           struct dm_per_pkt_info *pktinfo,
1588                                           struct dm_phy_status_info *phy_info)
1589 {
1590         /* type 1 is used for ofdm packet */
1591
1592         struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt =
1593                 (struct phy_status_rpt_jaguar2_type1 *)phy_status;
1594         s8 rx_pwr_db = -120;
1595         u8 i, rxsc, bw = ODM_BW20M, rx_count = 0;
1596         bool is_mu;
1597         u8 num_ss;
1598
1599         /* Update OFDM packet counter */
1600         dm->phy_dbg_info.num_qry_phy_status_ofdm++;
1601
1602         /* Update per-path information */
1603         for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
1604                 if (dm->rx_ant_status & BIT(i)) {
1605                         s8 rx_path_pwr_db;
1606
1607                         /* RX path counter */
1608                         rx_count++;
1609
1610                         /* Update per-path information
1611                          * (RSSI_dB RSSI_percentage EVM SNR CFO sq)
1612                          */
1613                         /* EVM report is reported by stream, not path */
1614                         rx_path_pwr_db = phy_sta_rpt->pwdb[i] -
1615                                          110; /* per-path pwdb in dB domain */
1616                         phydm_set_per_path_phy_info(
1617                                 i, rx_path_pwr_db,
1618                                 phy_sta_rpt->rxevm[rx_count - 1],
1619                                 phy_sta_rpt->cfo_tail[i], phy_sta_rpt->rxsnr[i],
1620                                 phy_info);
1621
1622                         /* search maximum pwdb */
1623                         if (rx_path_pwr_db > rx_pwr_db)
1624                                 rx_pwr_db = rx_path_pwr_db;
1625                 }
1626         }
1627
1628         /* mapping RX counter from 1~4 to 0~3 */
1629         if (rx_count > 0)
1630                 phy_info->rx_count = rx_count - 1;
1631
1632         /* Check if MU packet or not */
1633         if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) {
1634                 is_mu = true;
1635                 dm->phy_dbg_info.num_qry_mu_pkt++;
1636         } else {
1637                 is_mu = false;
1638         }
1639
1640         /* count BF packet */
1641         dm->phy_dbg_info.num_qry_bf_pkt =
1642                 dm->phy_dbg_info.num_qry_bf_pkt + phy_sta_rpt->beamformed;
1643
1644         /*STBC or LDPC pkt*/
1645         dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc;
1646         dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc;
1647
1648         /* Check sub-channel */
1649         if ((pktinfo->data_rate > ODM_RATE11M) &&
1650             (pktinfo->data_rate < ODM_RATEMCS0))
1651                 rxsc = phy_sta_rpt->l_rxsc;
1652         else
1653                 rxsc = phy_sta_rpt->ht_rxsc;
1654
1655         /* Check RX bandwidth */
1656         if (dm->support_ic_type & ODM_RTL8822B) {
1657                 if ((rxsc >= 1) && (rxsc <= 8))
1658                         bw = ODM_BW20M;
1659                 else if ((rxsc >= 9) && (rxsc <= 12))
1660                         bw = ODM_BW40M;
1661                 else if (rxsc >= 13)
1662                         bw = ODM_BW80M;
1663                 else
1664                         bw = phy_sta_rpt->rf_mode;
1665         } else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D |
1666                                           ODM_RTL8710B)) { /* JJ ADD 20161014 */
1667                 if (phy_sta_rpt->rf_mode == 0)
1668                         bw = ODM_BW20M;
1669                 else if ((rxsc == 1) || (rxsc == 2))
1670                         bw = ODM_BW20M;
1671                 else
1672                         bw = ODM_BW40M;
1673         }
1674
1675         /* Update packet information */
1676         phydm_set_common_phy_info(
1677                 rx_pwr_db, phy_sta_rpt->channel, (bool)phy_sta_rpt->beamformed,
1678                 is_mu, bw, odm_evm_db_to_percentage(phy_sta_rpt->rxevm[0]),
1679                 rxsc, phy_info);
1680
1681         num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate);
1682
1683         odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfo_tail, num_ss);
1684         dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a;
1685         dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b;
1686         dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c;
1687         dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d;
1688
1689         if (pktinfo->is_packet_match_bssid) {
1690                 /* */
1691                 phydm_rx_statistic_cal(dm, phy_status, pktinfo);
1692         }
1693 }
1694
1695 static void phydm_get_rx_phy_status_type2(struct phy_dm_struct *dm,
1696                                           u8 *phy_status,
1697                                           struct dm_per_pkt_info *pktinfo,
1698                                           struct dm_phy_status_info *phy_info)
1699 {
1700         struct phy_status_rpt_jaguar2_type2 *phy_sta_rpt =
1701                 (struct phy_status_rpt_jaguar2_type2 *)phy_status;
1702         s8 rx_pwr_db = -120;
1703         u8 i, rxsc, bw = ODM_BW20M, rx_count = 0;
1704
1705         /* Update OFDM packet counter */
1706         dm->phy_dbg_info.num_qry_phy_status_ofdm++;
1707
1708         /* Update per-path information */
1709         for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
1710                 if (dm->rx_ant_status & BIT(i)) {
1711                         s8 rx_path_pwr_db;
1712
1713                         /* RX path counter */
1714                         rx_count++;
1715
1716                         /* Update per-path information
1717                          * (RSSI_dB RSSI_percentage EVM SNR CFO sq)
1718                          */
1719                         rx_path_pwr_db = phy_sta_rpt->pwdb[i] -
1720                                          110; /* per-path pwdb in dB domain */
1721
1722                         phydm_set_per_path_phy_info(i, rx_path_pwr_db, 0, 0, 0,
1723                                                     phy_info);
1724
1725                         /* search maximum pwdb */
1726                         if (rx_path_pwr_db > rx_pwr_db)
1727                                 rx_pwr_db = rx_path_pwr_db;
1728                 }
1729         }
1730
1731         /* mapping RX counter from 1~4 to 0~3 */
1732         if (rx_count > 0)
1733                 phy_info->rx_count = rx_count - 1;
1734
1735         /* Check RX sub-channel */
1736         if ((pktinfo->data_rate > ODM_RATE11M) &&
1737             (pktinfo->data_rate < ODM_RATEMCS0))
1738                 rxsc = phy_sta_rpt->l_rxsc;
1739         else
1740                 rxsc = phy_sta_rpt->ht_rxsc;
1741
1742         /*STBC or LDPC pkt*/
1743         dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc;
1744         dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc;
1745
1746         /* Check RX bandwidth */
1747         /* the BW information of sc=0 is useless, because there is
1748          * no information of RF mode
1749          */
1750
1751         if (dm->support_ic_type & ODM_RTL8822B) {
1752                 if ((rxsc >= 1) && (rxsc <= 8))
1753                         bw = ODM_BW20M;
1754                 else if ((rxsc >= 9) && (rxsc <= 12))
1755                         bw = ODM_BW40M;
1756                 else if (rxsc >= 13)
1757                         bw = ODM_BW80M;
1758                 else
1759                         bw = ODM_BW20M;
1760         } else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D |
1761                                           ODM_RTL8710B)) { /* JJ ADD 20161014 */
1762                 if (rxsc == 3)
1763                         bw = ODM_BW40M;
1764                 else if ((rxsc == 1) || (rxsc == 2))
1765                         bw = ODM_BW20M;
1766                 else
1767                         bw = ODM_BW20M;
1768         }
1769
1770         /* Update packet information */
1771         phydm_set_common_phy_info(rx_pwr_db, phy_sta_rpt->channel,
1772                                   (bool)phy_sta_rpt->beamformed, false, bw, 0,
1773                                   rxsc, phy_info);
1774 }
1775
1776 static void
1777 phydm_process_rssi_for_dm_new_type(struct phy_dm_struct *dm,
1778                                    struct dm_phy_status_info *phy_info,
1779                                    struct dm_per_pkt_info *pktinfo)
1780 {
1781         s32 undecorated_smoothed_pwdb, accumulate_pwdb;
1782         u32 rssi_ave;
1783         u8 i;
1784         struct rtl_sta_info *entry;
1785         u8 scaling_factor = 4;
1786
1787         if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM)
1788                 return;
1789
1790         entry = dm->odm_sta_info[pktinfo->station_id];
1791
1792         if (!IS_STA_VALID(entry))
1793                 return;
1794
1795         if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/
1796                 return;
1797
1798         if (pktinfo->is_packet_beacon)
1799                 dm->phy_dbg_info.num_qry_beacon_pkt++;
1800
1801         if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) {
1802                 u32 rssi_linear = 0;
1803
1804                 dm->rx_rate = pktinfo->data_rate;
1805                 undecorated_smoothed_pwdb =
1806                         entry->rssi_stat.undecorated_smoothed_pwdb;
1807                 accumulate_pwdb = dm->accumulate_pwdb[pktinfo->station_id];
1808                 dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
1809                 dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
1810                 dm->rssi_c = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_C];
1811                 dm->rssi_d = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_D];
1812
1813                 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
1814                         if (phy_info->rx_mimo_signal_strength[i] != 0)
1815                                 rssi_linear += odm_convert_to_linear(
1816                                         phy_info->rx_mimo_signal_strength[i]);
1817                 }
1818
1819                 switch (phy_info->rx_count + 1) {
1820                 case 2:
1821                         rssi_linear = (rssi_linear >> 1);
1822                         break;
1823                 case 3:
1824                         /* rssi_linear/3 ~ rssi_linear*11/32 */
1825                         rssi_linear = ((rssi_linear) + (rssi_linear << 1) +
1826                                        (rssi_linear << 3)) >>
1827                                       5;
1828                         break;
1829                 case 4:
1830                         rssi_linear = (rssi_linear >> 2);
1831                         break;
1832                 }
1833                 rssi_ave = odm_convert_to_db(rssi_linear);
1834
1835                 if (undecorated_smoothed_pwdb <= 0) {
1836                         accumulate_pwdb =
1837                                 (phy_info->rx_pwdb_all << scaling_factor);
1838                         undecorated_smoothed_pwdb = phy_info->rx_pwdb_all;
1839                 } else {
1840                         accumulate_pwdb = accumulate_pwdb -
1841                                           (accumulate_pwdb >> scaling_factor) +
1842                                           rssi_ave;
1843                         undecorated_smoothed_pwdb =
1844                                 (accumulate_pwdb +
1845                                  (1 << (scaling_factor - 1))) >>
1846                                 scaling_factor;
1847                 }
1848
1849                 entry->rssi_stat.undecorated_smoothed_pwdb =
1850                         undecorated_smoothed_pwdb;
1851                 dm->accumulate_pwdb[pktinfo->station_id] = accumulate_pwdb;
1852         }
1853 }
1854
1855 void phydm_rx_phy_status_new_type(struct phy_dm_struct *phydm, u8 *phy_status,
1856                                   struct dm_per_pkt_info *pktinfo,
1857                                   struct dm_phy_status_info *phy_info)
1858 {
1859         u8 phy_status_type = (*phy_status & 0xf);
1860
1861         /* Memory reset */
1862         phydm_reset_phy_info(phydm, phy_info);
1863
1864         /* Phy status parsing */
1865         switch (phy_status_type) {
1866         case 0: {
1867                 phydm_get_rx_phy_status_type0(phydm, phy_status, pktinfo,
1868                                               phy_info);
1869                 break;
1870         }
1871         case 1: {
1872                 phydm_get_rx_phy_status_type1(phydm, phy_status, pktinfo,
1873                                               phy_info);
1874                 break;
1875         }
1876         case 2: {
1877                 phydm_get_rx_phy_status_type2(phydm, phy_status, pktinfo,
1878                                               phy_info);
1879                 break;
1880         }
1881         default:
1882                 return;
1883         }
1884
1885         /* Update signal strength to UI, and phy_info->rx_pwdb_all is the
1886          * maximum RSSI of all path
1887          */
1888         phy_info->signal_strength =
1889                 (u8)(odm_signal_scale_mapping(phydm, phy_info->rx_pwdb_all));
1890
1891         /* Calculate average RSSI and smoothed RSSI */
1892         phydm_process_rssi_for_dm_new_type(phydm, phy_info, pktinfo);
1893 }
1894
1895 u32 query_phydm_trx_capability(struct phy_dm_struct *dm)
1896 {
1897         u32 value32 = 0xFFFFFFFF;
1898
1899         return value32;
1900 }
1901
1902 u32 query_phydm_stbc_capability(struct phy_dm_struct *dm)
1903 {
1904         u32 value32 = 0xFFFFFFFF;
1905
1906         return value32;
1907 }
1908
1909 u32 query_phydm_ldpc_capability(struct phy_dm_struct *dm)
1910 {
1911         u32 value32 = 0xFFFFFFFF;
1912
1913         return value32;
1914 }
1915
1916 u32 query_phydm_txbf_parameters(struct phy_dm_struct *dm)
1917 {
1918         u32 value32 = 0xFFFFFFFF;
1919
1920         return value32;
1921 }
1922
1923 u32 query_phydm_txbf_capability(struct phy_dm_struct *dm)
1924 {
1925         u32 value32 = 0xFFFFFFFF;
1926
1927         return value32;
1928 }