linux/drivers/staging/rtlwifi/phydm/phydm_hwconfig.c
<<
>>
Prefs
   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
  50static 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
 105static 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
 173static 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
 322static u8 odm_evm_db_to_percentage(s8);
 323static u8 odm_evm_dbm_jaguar_series(s8);
 324
 325static 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
 351static 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
 363static 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
 394static 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
 427static 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
 441static inline u8
 442phydm_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
 461static inline u8
 462phydm_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
 481static 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
 496s32 odm_signal_scale_mapping(struct phy_dm_struct *dm, s32 curr_sig)
 497{
 498        {
 499                return curr_sig;
 500        }
 501}
 502
 503static 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
 511static 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
 534static 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
 548static 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
 564static 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
 584static 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
 776static void
 777odm_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
 808static 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
1088void 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
1111void odm_init_rssi_for_dm(struct phy_dm_struct *dm) {}
1112
1113static 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 */
1197static 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
1210static 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
1219void 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. */
1238void 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
1250enum hal_status
1251odm_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
1284enum hal_status
1285odm_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
1326enum hal_status
1327odm_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
1348enum 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
1368enum hal_status
1369odm_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
1376u32 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
1393bool 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
1415static 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
1443static 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
1469static 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
1506static 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
1523static 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
1585static 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
1695static 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
1776static void
1777phydm_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
1855void 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
1895u32 query_phydm_trx_capability(struct phy_dm_struct *dm)
1896{
1897        u32 value32 = 0xFFFFFFFF;
1898
1899        return value32;
1900}
1901
1902u32 query_phydm_stbc_capability(struct phy_dm_struct *dm)
1903{
1904        u32 value32 = 0xFFFFFFFF;
1905
1906        return value32;
1907}
1908
1909u32 query_phydm_ldpc_capability(struct phy_dm_struct *dm)
1910{
1911        u32 value32 = 0xFFFFFFFF;
1912
1913        return value32;
1914}
1915
1916u32 query_phydm_txbf_parameters(struct phy_dm_struct *dm)
1917{
1918        u32 value32 = 0xFFFFFFFF;
1919
1920        return value32;
1921}
1922
1923u32 query_phydm_txbf_capability(struct phy_dm_struct *dm)
1924{
1925        u32 value32 = 0xFFFFFFFF;
1926
1927        return value32;
1928}
1929