linux/drivers/staging/rtl8723bs/hal/odm_HWConfig.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/******************************************************************************
   3 *
   4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
   5 *
   6 ******************************************************************************/
   7
   8#include "odm_precomp.h"
   9
  10#define READ_AND_CONFIG_MP(ic, txt) (ODM_ReadAndConfig_MP_##ic##txt(pDM_Odm))
  11#define READ_AND_CONFIG     READ_AND_CONFIG_MP
  12
  13static u8 odm_query_rx_pwr_percentage(s8 ant_power)
  14{
  15        if ((ant_power <= -100) || (ant_power >= 20))
  16                return  0;
  17        else if (ant_power >= 0)
  18                return  100;
  19        else
  20                return 100 + ant_power;
  21
  22}
  23
  24s32 odm_signal_scale_mapping(struct dm_odm_t *dm_odm, s32 curr_sig)
  25{
  26        s32 ret_sig = 0;
  27
  28        if (dm_odm->SupportInterface  == ODM_ITRF_SDIO) {
  29                if (curr_sig >= 51 && curr_sig <= 100)
  30                        ret_sig = 100;
  31                else if (curr_sig >= 41 && curr_sig <= 50)
  32                        ret_sig = 80 + ((curr_sig - 40)*2);
  33                else if (curr_sig >= 31 && curr_sig <= 40)
  34                        ret_sig = 66 + (curr_sig - 30);
  35                else if (curr_sig >= 21 && curr_sig <= 30)
  36                        ret_sig = 54 + (curr_sig - 20);
  37                else if (curr_sig >= 10 && curr_sig <= 20)
  38                        ret_sig = 42 + (((curr_sig - 10) * 2) / 3);
  39                else if (curr_sig >= 5 && curr_sig <= 9)
  40                        ret_sig = 22 + (((curr_sig - 5) * 3) / 2);
  41                else if (curr_sig >= 1 && curr_sig <= 4)
  42                        ret_sig = 6 + (((curr_sig - 1) * 3) / 2);
  43                else
  44                        ret_sig = curr_sig;
  45        }
  46
  47        return ret_sig;
  48}
  49
  50static u8 odm_evm_db_to_percentage(s8 value)
  51{
  52        /*  */
  53        /*  -33dB~0dB to 0%~99% */
  54        /*  */
  55        s8 ret_val;
  56
  57        ret_val = value;
  58        ret_val /= 2;
  59
  60        if (ret_val >= 0)
  61                ret_val = 0;
  62        if (ret_val <= -33)
  63                ret_val = -33;
  64
  65        ret_val = 0 - ret_val;
  66        ret_val *= 3;
  67
  68        if (ret_val == 99)
  69                ret_val = 100;
  70
  71        return ret_val;
  72}
  73
  74static s8 odm_cck_rssi(u8 lna_idx, u8 vga_idx)
  75{
  76        s8 rx_pwr_all = 0x00;
  77
  78        switch (lna_idx) {
  79        /* 46  53 73 95 201301231630 */
  80        /*  46 53 77 99 201301241630 */
  81
  82        case 6:
  83                rx_pwr_all = -34 - (2 * vga_idx);
  84                break;
  85        case 4:
  86                rx_pwr_all = -14 - (2 * vga_idx);
  87                break;
  88        case 1:
  89                rx_pwr_all = 6 - (2 * vga_idx);
  90                break;
  91        case 0:
  92                rx_pwr_all = 16 - (2 * vga_idx);
  93                break;
  94        default:
  95                /* rx_pwr_all = -53+(2*(31-VGA_idx)); */
  96                break;
  97        }
  98        return rx_pwr_all;
  99}
 100
 101static void odm_rx_phy_status_parsing(struct dm_odm_t *dm_odm,
 102                                      struct odm_phy_info *phy_info,
 103                                      u8 *phy_status,
 104                                      struct odm_packet_info *pkt_info)
 105{
 106        u8 i;
 107        s8 rx_pwr[4], rx_pwr_all = 0;
 108        u8 evm, pwdb_all = 0, pwdb_all_bt;
 109        u8 rssi, total_rssi = 0;
 110        bool is_cck_rate = false;
 111        u8 rf_rx_num = 0;
 112        u8 lna_idx, vga_idx;
 113        struct phy_status_rpt_8192cd_t *phy_sta_rpt = (struct phy_status_rpt_8192cd_t *)phy_status;
 114
 115        is_cck_rate = pkt_info->data_rate <= DESC_RATE11M;
 116        phy_info->rx_mimo_signal_quality[RF_PATH_A] = -1;
 117        phy_info->rx_mimo_signal_quality[RF_PATH_B] = -1;
 118
 119
 120        if (is_cck_rate) {
 121                u8 cck_agc_rpt;
 122
 123                dm_odm->PhyDbgInfo.NumQryPhyStatusCCK++;
 124
 125                /*
 126                 * (1)Hardware does not provide RSSI for CCK/
 127                 * (2)PWDB, Average PWDB calculated by
 128                 *    hardware (for rate adaptive)
 129                 */
 130
 131                cck_agc_rpt = phy_sta_rpt->cck_agc_rpt_ofdm_cfosho_a;
 132
 133                /*
 134                 * 2011.11.28 LukeLee: 88E use different LNA & VGA gain table
 135                 * The RSSI formula should be modified according to the gain table
 136                 */
 137                lna_idx = ((cck_agc_rpt & 0xE0)>>5);
 138                vga_idx = (cck_agc_rpt & 0x1F);
 139                rx_pwr_all = odm_cck_rssi(lna_idx, vga_idx);
 140                pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
 141                if (pwdb_all > 100)
 142                        pwdb_all = 100;
 143
 144                phy_info->rx_pwd_ba11 = pwdb_all;
 145                phy_info->bt_rx_rssi_percentage = pwdb_all;
 146                phy_info->recv_signal_power = rx_pwr_all;
 147
 148                /*  (3) Get Signal Quality (EVM) */
 149
 150                /* if (pPktinfo->bPacketMatchBSSID) */
 151                {
 152                        u8 sq, sq_rpt;
 153
 154                        if (phy_info->rx_pwd_ba11 > 40 && !dm_odm->bInHctTest)
 155                                sq = 100;
 156                        else {
 157                                sq_rpt = phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all;
 158
 159                                if (sq_rpt > 64)
 160                                        sq = 0;
 161                                else if (sq_rpt < 20)
 162                                        sq = 100;
 163                                else
 164                                        sq = ((64-sq_rpt) * 100) / 44;
 165
 166                        }
 167
 168                        phy_info->signal_quality = sq;
 169                        phy_info->rx_mimo_signal_quality[RF_PATH_A] = sq;
 170                        phy_info->rx_mimo_signal_quality[RF_PATH_B] = -1;
 171                }
 172        } else { /* is OFDM rate */
 173                dm_odm->PhyDbgInfo.NumQryPhyStatusOFDM++;
 174
 175                /*
 176                 * (1)Get RSSI for HT rate
 177                 */
 178
 179                for (i = RF_PATH_A; i < RF_PATH_MAX; i++) {
 180                        /*  2008/01/30 MH we will judge RF RX path now. */
 181                        if (dm_odm->RFPathRxEnable & BIT(i))
 182                                rf_rx_num++;
 183                        /* else */
 184                                /* continue; */
 185
 186                        rx_pwr[i] = ((phy_sta_rpt->path_agc[i].gain & 0x3F) * 2) - 110;
 187
 188                        phy_info->rx_pwr[i] = rx_pwr[i];
 189
 190                        /* Translate DBM to percentage. */
 191                        rssi = odm_query_rx_pwr_percentage(rx_pwr[i]);
 192                        total_rssi += rssi;
 193
 194                        phy_info->rx_mimo_signal_strength[i] = (u8)rssi;
 195
 196                        /* Get Rx snr value in DB */
 197                        phy_info->rx_snr[i] = dm_odm->PhyDbgInfo.RxSNRdB[i] = (s32)(phy_sta_rpt->path_rxsnr[i]/2);
 198                }
 199
 200                /*
 201                 * (2)PWDB, Average PWDB calculated by hardware (for rate adaptive)
 202                 */
 203                rx_pwr_all = ((phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all >> 1) & 0x7f) - 110;
 204
 205                pwdb_all_bt = pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all);
 206
 207                phy_info->rx_pwd_ba11 = pwdb_all;
 208                phy_info->bt_rx_rssi_percentage = pwdb_all_bt;
 209                phy_info->rx_power = rx_pwr_all;
 210                phy_info->recv_signal_power = rx_pwr_all;
 211
 212                /*
 213                 * (3)EVM of HT rate
 214                 *
 215                 * Only spatial stream 1 makes sense
 216                 *
 217                 * Do not use shift operation like "rx_evmX >>= 1"
 218                 * because the compiler of free build environment
 219                 * fill most significant bit to "zero" when doing
 220                 * shifting operation which may change a negative
 221                 * value to positive one, then the dbm value (which
 222                 * is supposed to be negative) is not correct
 223                 * anymore.
 224                 */
 225                evm = odm_evm_db_to_percentage(phy_sta_rpt->stream_rxevm[0]); /* dbm */
 226
 227                /*  Fill value in RFD, Get the first spatial stream only */
 228                phy_info->signal_quality = (u8)(evm & 0xff);
 229
 230                phy_info->rx_mimo_signal_quality[RF_PATH_A] = (u8)(evm & 0xff);
 231
 232                odm_parsing_cfo(dm_odm, pkt_info, phy_sta_rpt->path_cfotail);
 233        }
 234
 235        /*
 236         * UI BSS List signal strength(in percentage), make it good
 237         * looking, from 0~100.
 238         * It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
 239         */
 240        if (is_cck_rate) {
 241                phy_info->signal_strength = (u8)(odm_signal_scale_mapping(dm_odm, pwdb_all));
 242        } else {
 243                if (rf_rx_num != 0) {
 244                        phy_info->signal_strength = (u8)(odm_signal_scale_mapping(dm_odm, total_rssi /= rf_rx_num));
 245                }
 246        }
 247}
 248
 249static void odm_Process_RSSIForDM(
 250        struct dm_odm_t *pDM_Odm, struct odm_phy_info *pPhyInfo, struct odm_packet_info *pPktinfo
 251)
 252{
 253
 254        s32 UndecoratedSmoothedPWDB, UndecoratedSmoothedCCK, UndecoratedSmoothedOFDM, RSSI_Ave;
 255        u8 isCCKrate = 0;
 256        u8 RSSI_max, RSSI_min, i;
 257        u32 OFDM_pkt = 0;
 258        u32 Weighting = 0;
 259        PSTA_INFO_T pEntry;
 260
 261
 262        if (pPktinfo->station_id == 0xFF)
 263                return;
 264
 265        pEntry = pDM_Odm->pODM_StaInfo[pPktinfo->station_id];
 266
 267        if (!IS_STA_VALID(pEntry))
 268                return;
 269
 270        if ((!pPktinfo->bssid_match))
 271                return;
 272
 273        if (pPktinfo->is_beacon)
 274                pDM_Odm->PhyDbgInfo.NumQryBeaconPkt++;
 275
 276        isCCKrate = ((pPktinfo->data_rate <= DESC_RATE11M)) ? true : false;
 277        pDM_Odm->RxRate = pPktinfo->data_rate;
 278
 279        /* Statistic for antenna/path diversity------------------ */
 280        if (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) {
 281
 282        }
 283
 284        /* Smart Antenna Debug Message------------------ */
 285
 286        UndecoratedSmoothedCCK = pEntry->rssi_stat.UndecoratedSmoothedCCK;
 287        UndecoratedSmoothedOFDM = pEntry->rssi_stat.UndecoratedSmoothedOFDM;
 288        UndecoratedSmoothedPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB;
 289
 290        if (pPktinfo->to_self || pPktinfo->is_beacon) {
 291
 292                if (!isCCKrate) { /* ofdm rate */
 293                        if (pPhyInfo->rx_mimo_signal_strength[RF_PATH_B] == 0) {
 294                                RSSI_Ave = pPhyInfo->rx_mimo_signal_strength[RF_PATH_A];
 295                                pDM_Odm->RSSI_A = pPhyInfo->rx_mimo_signal_strength[RF_PATH_A];
 296                                pDM_Odm->RSSI_B = 0;
 297                        } else {
 298                                pDM_Odm->RSSI_A =  pPhyInfo->rx_mimo_signal_strength[RF_PATH_A];
 299                                pDM_Odm->RSSI_B = pPhyInfo->rx_mimo_signal_strength[RF_PATH_B];
 300
 301                                if (
 302                                        pPhyInfo->rx_mimo_signal_strength[RF_PATH_A] >
 303                                        pPhyInfo->rx_mimo_signal_strength[RF_PATH_B]
 304                                ) {
 305                                        RSSI_max = pPhyInfo->rx_mimo_signal_strength[RF_PATH_A];
 306                                        RSSI_min = pPhyInfo->rx_mimo_signal_strength[RF_PATH_B];
 307                                } else {
 308                                        RSSI_max = pPhyInfo->rx_mimo_signal_strength[RF_PATH_B];
 309                                        RSSI_min = pPhyInfo->rx_mimo_signal_strength[RF_PATH_A];
 310                                }
 311
 312                                if ((RSSI_max-RSSI_min) < 3)
 313                                        RSSI_Ave = RSSI_max;
 314                                else if ((RSSI_max-RSSI_min) < 6)
 315                                        RSSI_Ave = RSSI_max - 1;
 316                                else if ((RSSI_max-RSSI_min) < 10)
 317                                        RSSI_Ave = RSSI_max - 2;
 318                                else
 319                                        RSSI_Ave = RSSI_max - 3;
 320                        }
 321
 322                        /* 1 Process OFDM RSSI */
 323                        if (UndecoratedSmoothedOFDM <= 0)       /*  initialize */
 324                                UndecoratedSmoothedOFDM = pPhyInfo->rx_pwd_ba11;
 325                        else {
 326                                if (pPhyInfo->rx_pwd_ba11 > (u32)UndecoratedSmoothedOFDM) {
 327                                        UndecoratedSmoothedOFDM =
 328                                                        ((UndecoratedSmoothedOFDM*(Rx_Smooth_Factor-1)) +
 329                                                        RSSI_Ave)/Rx_Smooth_Factor;
 330                                        UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM + 1;
 331                                } else {
 332                                        UndecoratedSmoothedOFDM =
 333                                                        ((UndecoratedSmoothedOFDM*(Rx_Smooth_Factor-1)) +
 334                                                        RSSI_Ave)/Rx_Smooth_Factor;
 335                                }
 336                        }
 337
 338                        pEntry->rssi_stat.PacketMap = (pEntry->rssi_stat.PacketMap<<1) | BIT0;
 339
 340                } else {
 341                        RSSI_Ave = pPhyInfo->rx_pwd_ba11;
 342                        pDM_Odm->RSSI_A = (u8) pPhyInfo->rx_pwd_ba11;
 343                        pDM_Odm->RSSI_B = 0;
 344
 345                        /* 1 Process CCK RSSI */
 346                        if (UndecoratedSmoothedCCK <= 0)        /*  initialize */
 347                                UndecoratedSmoothedCCK = pPhyInfo->rx_pwd_ba11;
 348                        else {
 349                                if (pPhyInfo->rx_pwd_ba11 > (u32)UndecoratedSmoothedCCK) {
 350                                        UndecoratedSmoothedCCK =
 351                                                        ((UndecoratedSmoothedCCK*(Rx_Smooth_Factor-1)) +
 352                                                        pPhyInfo->rx_pwd_ba11)/Rx_Smooth_Factor;
 353                                        UndecoratedSmoothedCCK = UndecoratedSmoothedCCK + 1;
 354                                } else {
 355                                        UndecoratedSmoothedCCK =
 356                                                        ((UndecoratedSmoothedCCK*(Rx_Smooth_Factor-1)) +
 357                                                        pPhyInfo->rx_pwd_ba11)/Rx_Smooth_Factor;
 358                                }
 359                        }
 360                        pEntry->rssi_stat.PacketMap = pEntry->rssi_stat.PacketMap<<1;
 361                }
 362
 363                /* if (pEntry) */
 364                {
 365                        /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */
 366                        if (pEntry->rssi_stat.ValidBit >= 64)
 367                                pEntry->rssi_stat.ValidBit = 64;
 368                        else
 369                                pEntry->rssi_stat.ValidBit++;
 370
 371                        for (i = 0; i < pEntry->rssi_stat.ValidBit; i++)
 372                                OFDM_pkt += (u8)(pEntry->rssi_stat.PacketMap>>i)&BIT0;
 373
 374                        if (pEntry->rssi_stat.ValidBit == 64) {
 375                                Weighting = ((OFDM_pkt<<4) > 64)?64:(OFDM_pkt<<4);
 376                                UndecoratedSmoothedPWDB = (Weighting*UndecoratedSmoothedOFDM+(64-Weighting)*UndecoratedSmoothedCCK)>>6;
 377                        } else {
 378                                if (pEntry->rssi_stat.ValidBit != 0)
 379                                        UndecoratedSmoothedPWDB = (OFDM_pkt*UndecoratedSmoothedOFDM+(pEntry->rssi_stat.ValidBit-OFDM_pkt)*UndecoratedSmoothedCCK)/pEntry->rssi_stat.ValidBit;
 380                                else
 381                                        UndecoratedSmoothedPWDB = 0;
 382                        }
 383
 384                        pEntry->rssi_stat.UndecoratedSmoothedCCK = UndecoratedSmoothedCCK;
 385                        pEntry->rssi_stat.UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM;
 386                        pEntry->rssi_stat.UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB;
 387                }
 388
 389        }
 390}
 391
 392
 393/*  */
 394/*  Endianness before calling this API */
 395/*  */
 396void odm_phy_status_query(struct dm_odm_t *dm_odm, struct odm_phy_info *phy_info,
 397                          u8 *phy_status, struct odm_packet_info *pkt_info)
 398{
 399
 400        odm_rx_phy_status_parsing(dm_odm, phy_info, phy_status, pkt_info);
 401
 402        if (!dm_odm->RSSI_test)
 403                odm_Process_RSSIForDM(dm_odm, phy_info, pkt_info);
 404}
 405
 406/*  */
 407/*  If you want to add a new IC, Please follow below template and generate a new one. */
 408/*  */
 409/*  */
 410
 411enum hal_status ODM_ConfigRFWithHeaderFile(
 412        struct dm_odm_t *pDM_Odm,
 413        enum ODM_RF_Config_Type ConfigType,
 414        enum rf_path eRFPath
 415)
 416{
 417        if (ConfigType == CONFIG_RF_RADIO)
 418                READ_AND_CONFIG(8723B, _RadioA);
 419        else if (ConfigType == CONFIG_RF_TXPWR_LMT)
 420                READ_AND_CONFIG(8723B, _TXPWR_LMT);
 421
 422        return HAL_STATUS_SUCCESS;
 423}
 424
 425enum hal_status ODM_ConfigRFWithTxPwrTrackHeaderFile(struct dm_odm_t *pDM_Odm)
 426{
 427        if (pDM_Odm->SupportInterface == ODM_ITRF_SDIO)
 428                READ_AND_CONFIG(8723B, _TxPowerTrack_SDIO);
 429
 430        return HAL_STATUS_SUCCESS;
 431}
 432
 433enum hal_status ODM_ConfigBBWithHeaderFile(
 434        struct dm_odm_t *pDM_Odm, enum ODM_BB_Config_Type ConfigType
 435)
 436{
 437        if (ConfigType == CONFIG_BB_PHY_REG)
 438                READ_AND_CONFIG(8723B, _PHY_REG);
 439        else if (ConfigType == CONFIG_BB_AGC_TAB)
 440                READ_AND_CONFIG(8723B, _AGC_TAB);
 441        else if (ConfigType == CONFIG_BB_PHY_REG_PG)
 442                READ_AND_CONFIG(8723B, _PHY_REG_PG);
 443
 444        return HAL_STATUS_SUCCESS;
 445}
 446
 447