linux/drivers/staging/rtl8723au/hal/odm.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
   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 ******************************************************************************/
  15
  16#include "odm_precomp.h"
  17#include "usb_ops_linux.h"
  18
  19static const u16 dB_Invert_Table[8][12] = {
  20        {1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4},
  21        {4, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16},
  22        {18, 20, 22, 25, 28, 32, 35, 40, 45, 50, 56, 63},
  23        {71, 79, 89, 100, 112, 126, 141, 158, 178, 200, 224, 251},
  24        {282, 316, 355, 398, 447, 501, 562, 631, 708, 794, 891, 1000},
  25        {1122, 1259, 1413, 1585, 1778, 1995, 2239, 2512, 2818, 3162, 3548, 3981},
  26        {4467, 5012, 5623, 6310, 7079, 7943, 8913, 10000, 11220, 12589, 14125, 15849},
  27        {17783, 19953, 22387, 25119, 28184, 31623, 35481, 39811, 44668, 50119, 56234, 65535}
  28};
  29
  30static u32 EDCAParam[HT_IOT_PEER_MAX][3] = {          /*  UL                    DL */
  31        {0x5ea42b, 0x5ea42b, 0x5ea42b}, /* 0:unknown AP */
  32        {0xa44f, 0x5ea44f, 0x5e431c}, /*  1:realtek AP */
  33        {0x5ea42b, 0x5ea42b, 0x5ea42b}, /*  2:unknown AP => realtek_92SE */
  34        {0x5ea32b, 0x5ea42b, 0x5e4322}, /*  3:broadcom AP */
  35        {0x5ea422, 0x00a44f, 0x00a44f}, /*  4:ralink AP */
  36        {0x5ea322, 0x00a630, 0x00a44f}, /*  5:atheros AP */
  37        {0x5e4322, 0x5e4322, 0x5e4322},/*  6:cisco AP */
  38        {0x5ea44f, 0x00a44f, 0x5ea42b}, /*  8:marvell AP */
  39        {0x5ea42b, 0x5ea42b, 0x5ea42b}, /*  10:unknown AP => 92U AP */
  40        {0x5ea42b, 0xa630, 0x5e431c}, /*  11:airgocap AP */
  41};
  42
  43/*  EDCA Parameter for AP/ADSL   by Mingzhi 2011-11-22 */
  44
  45/*  Global var */
  46u32 OFDMSwingTable23A[OFDM_TABLE_SIZE_92D] = {
  47        0x7f8001fe, /*  0, +6.0dB */
  48        0x788001e2, /*  1, +5.5dB */
  49        0x71c001c7, /*  2, +5.0dB */
  50        0x6b8001ae, /*  3, +4.5dB */
  51        0x65400195, /*  4, +4.0dB */
  52        0x5fc0017f, /*  5, +3.5dB */
  53        0x5a400169, /*  6, +3.0dB */
  54        0x55400155, /*  7, +2.5dB */
  55        0x50800142, /*  8, +2.0dB */
  56        0x4c000130, /*  9, +1.5dB */
  57        0x47c0011f, /*  10, +1.0dB */
  58        0x43c0010f, /*  11, +0.5dB */
  59        0x40000100, /*  12, +0dB */
  60        0x3c8000f2, /*  13, -0.5dB */
  61        0x390000e4, /*  14, -1.0dB */
  62        0x35c000d7, /*  15, -1.5dB */
  63        0x32c000cb, /*  16, -2.0dB */
  64        0x300000c0, /*  17, -2.5dB */
  65        0x2d4000b5, /*  18, -3.0dB */
  66        0x2ac000ab, /*  19, -3.5dB */
  67        0x288000a2, /*  20, -4.0dB */
  68        0x26000098, /*  21, -4.5dB */
  69        0x24000090, /*  22, -5.0dB */
  70        0x22000088, /*  23, -5.5dB */
  71        0x20000080, /*  24, -6.0dB */
  72        0x1e400079, /*  25, -6.5dB */
  73        0x1c800072, /*  26, -7.0dB */
  74        0x1b00006c, /*  27. -7.5dB */
  75        0x19800066, /*  28, -8.0dB */
  76        0x18000060, /*  29, -8.5dB */
  77        0x16c0005b, /*  30, -9.0dB */
  78        0x15800056, /*  31, -9.5dB */
  79        0x14400051, /*  32, -10.0dB */
  80        0x1300004c, /*  33, -10.5dB */
  81        0x12000048, /*  34, -11.0dB */
  82        0x11000044, /*  35, -11.5dB */
  83        0x10000040, /*  36, -12.0dB */
  84        0x0f00003c,/*  37, -12.5dB */
  85        0x0e400039,/*  38, -13.0dB */
  86        0x0d800036,/*  39, -13.5dB */
  87        0x0cc00033,/*  40, -14.0dB */
  88        0x0c000030,/*  41, -14.5dB */
  89        0x0b40002d,/*  42, -15.0dB */
  90};
  91
  92u8 CCKSwingTable_Ch1_Ch1323A[CCK_TABLE_SIZE][8] = {
  93        {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /*  0, +0dB */
  94        {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /*  1, -0.5dB */
  95        {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /*  2, -1.0dB */
  96        {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /*  3, -1.5dB */
  97        {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /*  4, -2.0dB */
  98        {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /*  5, -2.5dB */
  99        {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /*  6, -3.0dB */
 100        {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /*  7, -3.5dB */
 101        {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /*  8, -4.0dB */
 102        {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /*  9, -4.5dB */
 103        {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /*  10, -5.0dB */
 104        {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /*  11, -5.5dB */
 105        {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /*  12, -6.0dB */
 106        {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /*  13, -6.5dB */
 107        {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /*  14, -7.0dB */
 108        {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /*  15, -7.5dB */
 109        {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /*  16, -8.0dB */
 110        {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /*  17, -8.5dB */
 111        {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /*  18, -9.0dB */
 112        {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /*  19, -9.5dB */
 113        {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /*  20, -10.0dB */
 114        {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /*  21, -10.5dB */
 115        {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /*  22, -11.0dB */
 116        {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /*  23, -11.5dB */
 117        {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /*  24, -12.0dB */
 118        {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /*  25, -12.5dB */
 119        {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /*  26, -13.0dB */
 120        {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /*  27, -13.5dB */
 121        {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /*  28, -14.0dB */
 122        {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /*  29, -14.5dB */
 123        {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /*  30, -15.0dB */
 124        {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /*  31, -15.5dB */
 125        {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}        /*  32, -16.0dB */
 126};
 127
 128u8 CCKSwingTable_Ch1423A[CCK_TABLE_SIZE][8] = {
 129        {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /*  0, +0dB */
 130        {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /*  1, -0.5dB */
 131        {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /*  2, -1.0dB */
 132        {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /*  3, -1.5dB */
 133        {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /*  4, -2.0dB */
 134        {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /*  5, -2.5dB */
 135        {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /*  6, -3.0dB */
 136        {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /*  7, -3.5dB */
 137        {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /*  8, -4.0dB */
 138        {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /*  9, -4.5dB */
 139        {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /*  10, -5.0dB */
 140        {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /*  11, -5.5dB */
 141        {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /*  12, -6.0dB */
 142        {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /*  13, -6.5dB */
 143        {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /*  14, -7.0dB */
 144        {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /*  15, -7.5dB */
 145        {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /*  16, -8.0dB */
 146        {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /*  17, -8.5dB */
 147        {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /*  18, -9.0dB */
 148        {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /*  19, -9.5dB */
 149        {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /*  20, -10.0dB */
 150        {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /*  21, -10.5dB */
 151        {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /*  22, -11.0dB */
 152        {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /*  23, -11.5dB */
 153        {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /*  24, -12.0dB */
 154        {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /*  25, -12.5dB */
 155        {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /*  26, -13.0dB */
 156        {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /*  27, -13.5dB */
 157        {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /*  28, -14.0dB */
 158        {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /*  29, -14.5dB */
 159        {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /*  30, -15.0dB */
 160        {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /*  31, -15.5dB */
 161        {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}        /*  32, -16.0dB */
 162};
 163
 164/*  Local Function predefine. */
 165
 166/* START------------COMMON INFO RELATED--------------- */
 167void odm_CommonInfoSelfInit23a(struct dm_odm_t *pDM_Odm);
 168
 169static void odm_CommonInfoSelfUpdate(struct hal_data_8723a *pHalData);
 170
 171void odm_CmnInfoInit_Debug23a(struct dm_odm_t *pDM_Odm);
 172
 173void odm_CmnInfoUpdate_Debug23a(struct dm_odm_t *pDM_Odm);
 174
 175/* START---------------DIG--------------------------- */
 176void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm);
 177
 178void odm_DIG23aInit(struct dm_odm_t *pDM_Odm);
 179
 180void odm_DIG23a(struct rtw_adapter *adapter);
 181
 182void odm_CCKPacketDetectionThresh23a(struct dm_odm_t *pDM_Odm);
 183/* END---------------DIG--------------------------- */
 184
 185/* START-------BB POWER SAVE----------------------- */
 186void odm23a_DynBBPSInit(struct dm_odm_t *pDM_Odm);
 187
 188void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm);
 189
 190/* END---------BB POWER SAVE----------------------- */
 191
 192void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm);
 193
 194static void odm_RSSIMonitorCheck(struct dm_odm_t *pDM_Odm);
 195void odm_DynamicTxPower23a(struct dm_odm_t *pDM_Odm);
 196
 197static void odm_RefreshRateAdaptiveMask(struct dm_odm_t *pDM_Odm);
 198
 199void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm);
 200
 201static void odm_TXPowerTrackingInit(struct dm_odm_t *pDM_Odm);
 202
 203static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm);
 204static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm);
 205
 206#define         RxDefaultAnt1           0x65a9
 207#define RxDefaultAnt2           0x569a
 208
 209bool odm_StaDefAntSel(struct dm_odm_t *pDM_Odm,
 210        u32 OFDM_Ant1_Cnt,
 211        u32 OFDM_Ant2_Cnt,
 212        u32 CCK_Ant1_Cnt,
 213        u32 CCK_Ant2_Cnt,
 214        u8 *pDefAnt
 215        );
 216
 217void odm_SetRxIdleAnt(struct dm_odm_t *pDM_Odm,
 218        u8 Ant,
 219        bool   bDualPath
 220);
 221
 222/* 3 Export Interface */
 223
 224/*  2011/09/21 MH Add to describe different team necessary resource allocate?? */
 225void ODM23a_DMInit(struct dm_odm_t *pDM_Odm)
 226{
 227        /* For all IC series */
 228        odm_CommonInfoSelfInit23a(pDM_Odm);
 229        odm_CmnInfoInit_Debug23a(pDM_Odm);
 230        odm_DIG23aInit(pDM_Odm);
 231        odm_RateAdaptiveMaskInit23a(pDM_Odm);
 232
 233        odm23a_DynBBPSInit(pDM_Odm);
 234        odm_DynamicTxPower23aInit(pDM_Odm);
 235        odm_TXPowerTrackingInit(pDM_Odm);
 236        ODM_EdcaTurboInit23a(pDM_Odm);
 237}
 238
 239/*  2011/09/20 MH This is the entry pointer for all team to execute HW out source DM. */
 240/*  You can not add any dummy function here, be care, you can only use DM structure */
 241/*  to perform any new ODM_DM. */
 242void ODM_DMWatchdog23a(struct rtw_adapter *adapter)
 243{
 244        struct hal_data_8723a *pHalData = GET_HAL_DATA(adapter);
 245        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
 246        struct pwrctrl_priv *pwrctrlpriv = &adapter->pwrctrlpriv;
 247
 248        /* 2012.05.03 Luke: For all IC series */
 249        odm_CmnInfoUpdate_Debug23a(pDM_Odm);
 250        odm_CommonInfoSelfUpdate(pHalData);
 251        odm_FalseAlarmCounterStatistics23a(pDM_Odm);
 252        odm_RSSIMonitorCheck(pDM_Odm);
 253
 254        /* 8723A or 8189ES platform */
 255        /* NeilChen--2012--08--24-- */
 256        /* Fix Leave LPS issue */
 257        if ((pDM_Odm->Adapter->pwrctrlpriv.pwr_mode != PS_MODE_ACTIVE) &&/*  in LPS mode */
 258            (pDM_Odm->SupportICType & ODM_RTL8723A)) {
 259                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("----Step1: odm_DIG23a is in LPS mode\n"));
 260                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("---Step2: 8723AS is in LPS mode\n"));
 261                        odm_DIG23abyRSSI_LPS(pDM_Odm);
 262        } else {
 263                odm_DIG23a(adapter);
 264        }
 265
 266        odm_CCKPacketDetectionThresh23a(pDM_Odm);
 267
 268        if (pwrctrlpriv->bpower_saving)
 269                return;
 270
 271        odm_RefreshRateAdaptiveMask(pDM_Odm);
 272
 273        odm_DynamicBBPowerSaving23a(pDM_Odm);
 274
 275        odm_EdcaTurboCheck23a(pDM_Odm);
 276}
 277
 278/*  */
 279/*  Init /.. Fixed HW value. Only init time. */
 280/*  */
 281void ODM_CmnInfoInit23a(struct dm_odm_t *pDM_Odm,
 282                enum odm_cmninfo CmnInfo,
 283                u32 Value
 284        )
 285{
 286        /* ODM_RT_TRACE(pDM_Odm,); */
 287
 288        /*  */
 289        /*  This section is used for init value */
 290        /*  */
 291        switch  (CmnInfo) {
 292        /*  Fixed ODM value. */
 293        case    ODM_CMNINFO_MP_TEST_CHIP:
 294                pDM_Odm->bIsMPChip = (u8)Value;
 295                break;
 296        case    ODM_CMNINFO_IC_TYPE:
 297                pDM_Odm->SupportICType = Value;
 298                break;
 299        case    ODM_CMNINFO_CUT_VER:
 300                pDM_Odm->CutVersion = (u8)Value;
 301                break;
 302        case    ODM_CMNINFO_FAB_VER:
 303                pDM_Odm->FabVersion = (u8)Value;
 304                break;
 305        case    ODM_CMNINFO_BOARD_TYPE:
 306                pDM_Odm->BoardType = (u8)Value;
 307                break;
 308        case    ODM_CMNINFO_EXT_LNA:
 309                pDM_Odm->ExtLNA = (u8)Value;
 310                break;
 311        case    ODM_CMNINFO_EXT_PA:
 312                pDM_Odm->ExtPA = (u8)Value;
 313                break;
 314        case    ODM_CMNINFO_EXT_TRSW:
 315                pDM_Odm->ExtTRSW = (u8)Value;
 316                break;
 317        case    ODM_CMNINFO_BINHCT_TEST:
 318                pDM_Odm->bInHctTest = (bool)Value;
 319                break;
 320        case    ODM_CMNINFO_BWIFI_TEST:
 321                pDM_Odm->bWIFITest = (bool)Value;
 322                break;
 323        case    ODM_CMNINFO_SMART_CONCURRENT:
 324                pDM_Odm->bDualMacSmartConcurrent = (bool)Value;
 325                break;
 326        /* To remove the compiler warning, must add an empty default statement to handle the other values. */
 327        default:
 328                /* do nothing */
 329                break;
 330        }
 331}
 332
 333void ODM_CmnInfoPtrArrayHook23a(struct dm_odm_t *pDM_Odm, enum odm_cmninfo CmnInfo,
 334                                u16 Index, void *pValue)
 335{
 336        /*  Hook call by reference pointer. */
 337        switch  (CmnInfo) {
 338        /*  Dynamic call by reference pointer. */
 339        case    ODM_CMNINFO_STA_STATUS:
 340                pDM_Odm->pODM_StaInfo[Index] = (struct sta_info *)pValue;
 341                break;
 342        /* To remove the compiler warning, must add an empty default statement to handle the other values. */
 343        default:
 344                /* do nothing */
 345                break;
 346        }
 347}
 348
 349/*  Update Band/CHannel/.. The values are dynamic but non-per-packet. */
 350void ODM_CmnInfoUpdate23a(struct dm_odm_t *pDM_Odm, u32 CmnInfo, u64 Value)
 351{
 352        /*  This init variable may be changed in run time. */
 353        switch  (CmnInfo) {
 354        case    ODM_CMNINFO_WIFI_DIRECT:
 355                pDM_Odm->bWIFI_Direct = (bool)Value;
 356                break;
 357        case    ODM_CMNINFO_WIFI_DISPLAY:
 358                pDM_Odm->bWIFI_Display = (bool)Value;
 359                break;
 360        case    ODM_CMNINFO_LINK:
 361                pDM_Odm->bLinked = (bool)Value;
 362                break;
 363        case    ODM_CMNINFO_RSSI_MIN:
 364                pDM_Odm->RSSI_Min = (u8)Value;
 365                break;
 366        case    ODM_CMNINFO_DBG_COMP:
 367                pDM_Odm->DebugComponents = Value;
 368                break;
 369        case    ODM_CMNINFO_DBG_LEVEL:
 370                pDM_Odm->DebugLevel = (u32)Value;
 371                break;
 372        case    ODM_CMNINFO_RA_THRESHOLD_HIGH:
 373                pDM_Odm->RateAdaptive.HighRSSIThresh = (u8)Value;
 374                break;
 375        case    ODM_CMNINFO_RA_THRESHOLD_LOW:
 376                pDM_Odm->RateAdaptive.LowRSSIThresh = (u8)Value;
 377                break;
 378        }
 379
 380}
 381
 382void odm_CommonInfoSelfInit23a(struct dm_odm_t *pDM_Odm)
 383{
 384        u32 val32;
 385
 386        val32 = rtl8723au_read32(pDM_Odm->Adapter, rFPGA0_XA_HSSIParameter2);
 387        if (val32 & BIT(9))
 388                pDM_Odm->bCckHighPower = true;
 389        else
 390                pDM_Odm->bCckHighPower = false;
 391
 392        pDM_Odm->RFPathRxEnable =
 393                rtl8723au_read32(pDM_Odm->Adapter, rOFDM0_TRxPathEnable) & 0x0F;
 394
 395        ODM_InitDebugSetting23a(pDM_Odm);
 396}
 397
 398static void odm_CommonInfoSelfUpdate(struct hal_data_8723a *pHalData)
 399{
 400        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
 401        struct sta_info *pEntry;
 402        u8 EntryCnt = 0;
 403        u8 i;
 404
 405        for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
 406                pEntry = pDM_Odm->pODM_StaInfo[i];
 407                if (pEntry)
 408                        EntryCnt++;
 409        }
 410        if (EntryCnt == 1)
 411                pDM_Odm->bOneEntryOnly = true;
 412        else
 413                pDM_Odm->bOneEntryOnly = false;
 414}
 415
 416void odm_CmnInfoInit_Debug23a(struct dm_odm_t *pDM_Odm)
 417{
 418        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_CmnInfoInit_Debug23a ==>\n"));
 419        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportAbility = 0x%x\n", pDM_Odm->SupportAbility));
 420        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportICType = 0x%x\n", pDM_Odm->SupportICType));
 421        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("CutVersion =%d\n", pDM_Odm->CutVersion));
 422        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("FabVersion =%d\n", pDM_Odm->FabVersion));
 423        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("BoardType =%d\n", pDM_Odm->BoardType));
 424        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtLNA =%d\n", pDM_Odm->ExtLNA));
 425        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtPA =%d\n", pDM_Odm->ExtPA));
 426        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtTRSW =%d\n", pDM_Odm->ExtTRSW));
 427        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bInHctTest =%d\n", pDM_Odm->bInHctTest));
 428        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bWIFITest =%d\n", pDM_Odm->bWIFITest));
 429        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bDualMacSmartConcurrent =%d\n", pDM_Odm->bDualMacSmartConcurrent));
 430
 431}
 432
 433void odm_CmnInfoUpdate_Debug23a(struct dm_odm_t *pDM_Odm)
 434{
 435        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_CmnInfoUpdate_Debug23a ==>\n"));
 436        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bWIFI_Direct =%d\n", pDM_Odm->bWIFI_Direct));
 437        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bWIFI_Display =%d\n", pDM_Odm->bWIFI_Display));
 438        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bLinked =%d\n", pDM_Odm->bLinked));
 439        ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("RSSI_Min =%d\n", pDM_Odm->RSSI_Min));
 440}
 441
 442void ODM_Write_DIG23a(struct dm_odm_t *pDM_Odm, u8 CurrentIGI)
 443{
 444        struct rtw_adapter *adapter = pDM_Odm->Adapter;
 445        struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
 446        u32 val32;
 447
 448        if (pDM_DigTable->CurIGValue != CurrentIGI) {
 449                val32 = rtl8723au_read32(adapter, ODM_REG_IGI_A_11N);
 450                val32 &= ~ODM_BIT_IGI_11N;
 451                val32 |= CurrentIGI;
 452                rtl8723au_write32(adapter, ODM_REG_IGI_A_11N, val32);
 453                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
 454                             ("CurrentIGI(0x%02x). \n", CurrentIGI));
 455                pDM_DigTable->CurIGValue = CurrentIGI;
 456        }
 457        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
 458                     ("ODM_Write_DIG23a():CurrentIGI = 0x%x \n", CurrentIGI));
 459}
 460
 461/* Need LPS mode for CE platform --2012--08--24--- */
 462/* 8723AS/8189ES */
 463void odm_DIG23abyRSSI_LPS(struct dm_odm_t *pDM_Odm)
 464{
 465        struct rtw_adapter *pAdapter = pDM_Odm->Adapter;
 466        struct false_alarm_stats *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
 467        u8 RSSI_Lower = DM_DIG_MIN_NIC;   /* 0x1E or 0x1C */
 468        u8 bFwCurrentInPSMode = false;
 469        u8 CurrentIGI = pDM_Odm->RSSI_Min;
 470
 471        if (!(pDM_Odm->SupportICType & ODM_RTL8723A))
 472                return;
 473
 474        CurrentIGI = CurrentIGI+RSSI_OFFSET_DIG;
 475        bFwCurrentInPSMode = pAdapter->pwrctrlpriv.bFwCurrentInPSMode;
 476
 477        /*  Using FW PS mode to make IGI */
 478        if (bFwCurrentInPSMode) {
 479                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
 480                             ("---Neil---odm_DIG23a is in LPS mode\n"));
 481                /* Adjust by  FA in LPS MODE */
 482                if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_LPS)
 483                        CurrentIGI = CurrentIGI+2;
 484                else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS)
 485                        CurrentIGI = CurrentIGI+1;
 486                else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS)
 487                        CurrentIGI = CurrentIGI-1;
 488        } else {
 489                CurrentIGI = RSSI_Lower;
 490        }
 491
 492        /* Lower bound checking */
 493
 494        /* RSSI Lower bound check */
 495        if ((pDM_Odm->RSSI_Min-10) > DM_DIG_MIN_NIC)
 496                RSSI_Lower = (pDM_Odm->RSSI_Min-10);
 497        else
 498                RSSI_Lower = DM_DIG_MIN_NIC;
 499
 500        /* Upper and Lower Bound checking */
 501         if (CurrentIGI > DM_DIG_MAX_NIC)
 502                CurrentIGI = DM_DIG_MAX_NIC;
 503         else if (CurrentIGI < RSSI_Lower)
 504                CurrentIGI = RSSI_Lower;
 505
 506        ODM_Write_DIG23a(pDM_Odm, CurrentIGI);
 507}
 508
 509void odm_DIG23aInit(struct dm_odm_t *pDM_Odm)
 510{
 511        struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
 512        u32 val32;
 513
 514        val32 = rtl8723au_read32(pDM_Odm->Adapter, ODM_REG_IGI_A_11N);
 515        pDM_DigTable->CurIGValue = val32 & ODM_BIT_IGI_11N;
 516
 517        pDM_DigTable->RssiLowThresh     = DM_DIG_THRESH_LOW;
 518        pDM_DigTable->RssiHighThresh    = DM_DIG_THRESH_HIGH;
 519        pDM_DigTable->FALowThresh       = DM_FALSEALARM_THRESH_LOW;
 520        pDM_DigTable->FAHighThresh      = DM_FALSEALARM_THRESH_HIGH;
 521        if (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) {
 522                pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
 523                pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
 524        } else {
 525                pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
 526                pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
 527        }
 528        pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT;
 529        pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX;
 530        pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN;
 531        pDM_DigTable->PreCCK_CCAThres = 0xFF;
 532        pDM_DigTable->CurCCK_CCAThres = 0x83;
 533        pDM_DigTable->ForbiddenIGI = DM_DIG_MIN_NIC;
 534        pDM_DigTable->LargeFAHit = 0;
 535        pDM_DigTable->Recover_cnt = 0;
 536        pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC;
 537        pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC;
 538        pDM_DigTable->bMediaConnect_0 = false;
 539        pDM_DigTable->bMediaConnect_1 = false;
 540}
 541
 542void odm_DIG23a(struct rtw_adapter *adapter)
 543{
 544        struct hal_data_8723a *pHalData = GET_HAL_DATA(adapter);
 545        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
 546        struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
 547        struct false_alarm_stats *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
 548        u8 DIG_Dynamic_MIN;
 549        u8 DIG_MaxOfMin;
 550        bool FirstConnect, FirstDisConnect;
 551        u8 dm_dig_max, dm_dig_min;
 552        u8 CurrentIGI = pDM_DigTable->CurIGValue;
 553
 554        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
 555                     ("odm_DIG23a() ==>\n"));
 556        if (adapter->mlmepriv.bScanInProcess) {
 557                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
 558                             ("odm_DIG23a() Return: In Scan Progress \n"));
 559                return;
 560        }
 561
 562        DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0;
 563        FirstConnect = (pDM_Odm->bLinked) && (!pDM_DigTable->bMediaConnect_0);
 564        FirstDisConnect = (!pDM_Odm->bLinked) &&
 565                (pDM_DigTable->bMediaConnect_0);
 566
 567        /* 1 Boundary Decision */
 568        if ((pDM_Odm->SupportICType & ODM_RTL8723A) &&
 569            (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR || pDM_Odm->ExtLNA)) {
 570                dm_dig_max = DM_DIG_MAX_NIC_HP;
 571                dm_dig_min = DM_DIG_MIN_NIC_HP;
 572                DIG_MaxOfMin = DM_DIG_MAX_AP_HP;
 573        } else {
 574                dm_dig_max = DM_DIG_MAX_NIC;
 575                dm_dig_min = DM_DIG_MIN_NIC;
 576                DIG_MaxOfMin = DM_DIG_MAX_AP;
 577        }
 578
 579        if (pDM_Odm->bLinked) {
 580              /* 2 8723A Series, offset need to be 10 */
 581                if (pDM_Odm->SupportICType == ODM_RTL8723A) {
 582                        /* 2 Upper Bound */
 583                        if ((pDM_Odm->RSSI_Min + 10) > DM_DIG_MAX_NIC)
 584                                pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
 585                        else if ((pDM_Odm->RSSI_Min + 10) < DM_DIG_MIN_NIC)
 586                                pDM_DigTable->rx_gain_range_max = DM_DIG_MIN_NIC;
 587                        else
 588                                pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + 10;
 589
 590                        /* 2 If BT is Concurrent, need to set Lower Bound */
 591                        DIG_Dynamic_MIN = DM_DIG_MIN_NIC;
 592                } else {
 593                        /* 2 Modify DIG upper bound */
 594                        if ((pDM_Odm->RSSI_Min + 20) > dm_dig_max)
 595                                pDM_DigTable->rx_gain_range_max = dm_dig_max;
 596                        else if ((pDM_Odm->RSSI_Min + 20) < dm_dig_min)
 597                                pDM_DigTable->rx_gain_range_max = dm_dig_min;
 598                        else
 599                                pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + 20;
 600
 601                        /* 2 Modify DIG lower bound */
 602                        if (pDM_Odm->bOneEntryOnly) {
 603                                if (pDM_Odm->RSSI_Min < dm_dig_min)
 604                                        DIG_Dynamic_MIN = dm_dig_min;
 605                                else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin)
 606                                        DIG_Dynamic_MIN = DIG_MaxOfMin;
 607                                else
 608                                        DIG_Dynamic_MIN = pDM_Odm->RSSI_Min;
 609                                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
 610                                             ("odm_DIG23a() : bOneEntryOnly = true,  DIG_Dynamic_MIN = 0x%x\n",
 611                                             DIG_Dynamic_MIN));
 612                                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
 613                                             ("odm_DIG23a() : pDM_Odm->RSSI_Min =%d\n",
 614                                             pDM_Odm->RSSI_Min));
 615                        } else {
 616                                DIG_Dynamic_MIN = dm_dig_min;
 617                        }
 618                }
 619        } else {
 620                pDM_DigTable->rx_gain_range_max = dm_dig_max;
 621                DIG_Dynamic_MIN = dm_dig_min;
 622                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a() : No Link\n"));
 623        }
 624
 625        /* 1 Modify DIG lower bound, deal with abnormally large false alarm */
 626        if (pFalseAlmCnt->Cnt_all > 10000) {
 627                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
 628                             ("dm_DIG(): Abnornally false alarm case. \n"));
 629
 630                if (pDM_DigTable->LargeFAHit != 3)
 631                        pDM_DigTable->LargeFAHit++;
 632                if (pDM_DigTable->ForbiddenIGI < CurrentIGI) {
 633                        pDM_DigTable->ForbiddenIGI = CurrentIGI;
 634                        pDM_DigTable->LargeFAHit = 1;
 635                }
 636
 637                if (pDM_DigTable->LargeFAHit >= 3) {
 638                        if ((pDM_DigTable->ForbiddenIGI+1) > pDM_DigTable->rx_gain_range_max)
 639                                pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
 640                        else
 641                                pDM_DigTable->rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 1);
 642                        pDM_DigTable->Recover_cnt = 3600; /* 3600 = 2hr */
 643                }
 644        } else {
 645                /* Recovery mechanism for IGI lower bound */
 646                if (pDM_DigTable->Recover_cnt != 0) {
 647                        pDM_DigTable->Recover_cnt--;
 648                } else {
 649                        if (pDM_DigTable->LargeFAHit < 3) {
 650                                if ((pDM_DigTable->ForbiddenIGI - 1) < DIG_Dynamic_MIN) {
 651                                        pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
 652                                        pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
 653                                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
 654                                                     ("odm_DIG23a(): Normal Case: At Lower Bound\n"));
 655                                } else {
 656                                        pDM_DigTable->ForbiddenIGI--;
 657                                        pDM_DigTable->rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 1);
 658                                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
 659                                                     ("odm_DIG23a(): Normal Case: Approach Lower Bound\n"));
 660                                }
 661                        } else {
 662                                pDM_DigTable->LargeFAHit = 0;
 663                        }
 664                }
 665        }
 666        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): pDM_DigTable->LargeFAHit =%d\n", pDM_DigTable->LargeFAHit));
 667
 668        /* 1 Adjust initial gain by false alarm */
 669        if (pDM_Odm->bLinked) {
 670                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): DIG AfterLink\n"));
 671                if (FirstConnect) {
 672                        CurrentIGI = pDM_Odm->RSSI_Min;
 673                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: First Connect\n"));
 674                } else {
 675                        if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2)
 676                                CurrentIGI = CurrentIGI + 4;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+2; */
 677                        else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1)
 678                                CurrentIGI = CurrentIGI + 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */
 679                        else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0)
 680                                CurrentIGI = CurrentIGI - 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue-1; */
 681                }
 682        } else {
 683                ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): DIG BeforeLink\n"));
 684                if (FirstDisConnect) {
 685                        CurrentIGI = pDM_DigTable->rx_gain_range_min;
 686                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): First DisConnect \n"));
 687                } else {
 688                        /* 2012.03.30 LukeLee: enable DIG before link but with very high thresholds */
 689                        if (pFalseAlmCnt->Cnt_all > 10000)
 690                                CurrentIGI = CurrentIGI + 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+2; */
 691                        else if (pFalseAlmCnt->Cnt_all > 8000)
 692                                CurrentIGI = CurrentIGI + 1;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */
 693                        else if (pFalseAlmCnt->Cnt_all < 500)
 694                                CurrentIGI = CurrentIGI - 1;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue-1; */
 695                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): England DIG \n"));
 696                }
 697        }
 698        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): DIG End Adjust IGI\n"));
 699        /* 1 Check initial gain by upper/lower bound */
 700        if (CurrentIGI > pDM_DigTable->rx_gain_range_max)
 701                CurrentIGI = pDM_DigTable->rx_gain_range_max;
 702        if (CurrentIGI < pDM_DigTable->rx_gain_range_min)
 703                CurrentIGI = pDM_DigTable->rx_gain_range_min;
 704
 705        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): rx_gain_range_max = 0x%x, rx_gain_range_min = 0x%x\n",
 706                pDM_DigTable->rx_gain_range_max, pDM_DigTable->rx_gain_range_min));
 707        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): TotalFA =%d\n", pFalseAlmCnt->Cnt_all));
 708        ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): CurIGValue = 0x%x\n", CurrentIGI));
 709
 710        /* 2 High power RSSI threshold */
 711
 712        ODM_Write_DIG23a(pDM_Odm, CurrentIGI);/* ODM_Write_DIG23a(pDM_Odm, pDM_DigTable->CurIGValue); */
 713        pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
 714        pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
 715}
 716
 717/* 3 ============================================================ */
 718/* 3 FASLE ALARM CHECK */
 719/* 3 ============================================================ */
 720
 721void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm)
 722{
 723        struct rtw_adapter *adapter = pDM_Odm->Adapter;
 724        struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
 725        u32 ret_value, val32;
 726
 727        /* hold ofdm counter */
 728        /* hold page C counter */
 729        val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_HOLDC_11N);
 730        val32 |= BIT(31);
 731        rtl8723au_write32(adapter, ODM_REG_OFDM_FA_HOLDC_11N, val32);
 732        /* hold page D counter */
 733        val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTD_11N);
 734        val32 |= BIT(31);
 735        rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTD_11N, val32);
 736        ret_value = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_TYPE1_11N);
 737        FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff);
 738        FalseAlmCnt->Cnt_SB_Search_fail = (ret_value & 0xffff0000)>>16;
 739        ret_value = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_TYPE2_11N);
 740        FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff);
 741        FalseAlmCnt->Cnt_Parity_Fail = (ret_value & 0xffff0000)>>16;
 742        ret_value = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_TYPE3_11N);
 743        FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff);
 744        FalseAlmCnt->Cnt_Crc8_fail = (ret_value & 0xffff0000)>>16;
 745        ret_value = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_TYPE4_11N);
 746        FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff);
 747
 748        FalseAlmCnt->Cnt_Ofdm_fail = FalseAlmCnt->Cnt_Parity_Fail +
 749                FalseAlmCnt->Cnt_Rate_Illegal +
 750                FalseAlmCnt->Cnt_Crc8_fail +
 751                FalseAlmCnt->Cnt_Mcs_fail +
 752                FalseAlmCnt->Cnt_Fast_Fsync +
 753                FalseAlmCnt->Cnt_SB_Search_fail;
 754        /* hold cck counter */
 755        val32 = rtl8723au_read32(adapter, ODM_REG_CCK_FA_RST_11N);
 756        val32 |= (BIT(12) | BIT(14));
 757        rtl8723au_write32(adapter, ODM_REG_CCK_FA_RST_11N, val32);
 758
 759        ret_value = rtl8723au_read32(adapter, ODM_REG_CCK_FA_LSB_11N) & 0xff;
 760        FalseAlmCnt->Cnt_Cck_fail = ret_value;
 761        ret_value = rtl8723au_read32(adapter, ODM_REG_CCK_FA_MSB_11N) >> 16;
 762        FalseAlmCnt->Cnt_Cck_fail += (ret_value & 0xff00);
 763
 764        ret_value = rtl8723au_read32(adapter, ODM_REG_CCK_CCA_CNT_11N);
 765        FalseAlmCnt->Cnt_CCK_CCA =
 766                ((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8);
 767
 768        FalseAlmCnt->Cnt_all = (FalseAlmCnt->Cnt_Fast_Fsync +
 769                                FalseAlmCnt->Cnt_SB_Search_fail +
 770                                FalseAlmCnt->Cnt_Parity_Fail +
 771                                FalseAlmCnt->Cnt_Rate_Illegal +
 772                                FalseAlmCnt->Cnt_Crc8_fail +
 773                                FalseAlmCnt->Cnt_Mcs_fail +
 774                                FalseAlmCnt->Cnt_Cck_fail);
 775
 776        FalseAlmCnt->Cnt_CCA_all =
 777                FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA;
 778
 779        if (pDM_Odm->SupportICType >= ODM_RTL8723A) {
 780                /* reset false alarm counter registers */
 781                val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTC_11N);
 782                val32 |= BIT(31);
 783                rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTC_11N, val32);
 784                val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTC_11N);
 785                val32 &= ~BIT(31);
 786                rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTC_11N, val32);
 787
 788                val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTD_11N);
 789                val32 |= BIT(27);
 790                rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTD_11N, val32);
 791                val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTD_11N);
 792                val32 &= ~BIT(27);
 793                rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTD_11N, val32);
 794
 795                /* update ofdm counter */
 796                 /* update page C counter */
 797                val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_HOLDC_11N);
 798                val32 &= ~BIT(31);
 799                rtl8723au_write32(adapter, ODM_REG_OFDM_FA_HOLDC_11N, val32);
 800
 801                 /* update page D counter */
 802                val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTD_11N);
 803                val32 &= ~BIT(31);
 804                rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTD_11N, val32);
 805
 806                /* reset CCK CCA counter */
 807                val32 = rtl8723au_read32(adapter, ODM_REG_CCK_FA_RST_11N);
 808                val32 &= ~(BIT(12) | BIT(13) | BIT(14) | BIT(15));
 809                rtl8723au_write32(adapter, ODM_REG_CCK_FA_RST_11N, val32);
 810
 811                val32 = rtl8723au_read32(adapter, ODM_REG_CCK_FA_RST_11N);
 812                val32 |= (BIT(13) | BIT(15));
 813                rtl8723au_write32(adapter, ODM_REG_CCK_FA_RST_11N, val32);
 814        }
 815
 816        ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
 817                     ("Enter odm_FalseAlarmCounterStatistics23a\n"));
 818        ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
 819                     ("Cnt_Fast_Fsync =%d, Cnt_SB_Search_fail =%d\n",
 820                      FalseAlmCnt->Cnt_Fast_Fsync,
 821                      FalseAlmCnt->Cnt_SB_Search_fail));
 822        ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
 823                     ("Cnt_Parity_Fail =%d, Cnt_Rate_Illegal =%d\n",
 824                      FalseAlmCnt->Cnt_Parity_Fail,
 825                      FalseAlmCnt->Cnt_Rate_Illegal));
 826        ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
 827                     ("Cnt_Crc8_fail =%d, Cnt_Mcs_fail =%d\n",
 828                      FalseAlmCnt->Cnt_Crc8_fail, FalseAlmCnt->Cnt_Mcs_fail));
 829
 830        ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
 831                     ("Cnt_Cck_fail =%d\n", FalseAlmCnt->Cnt_Cck_fail));
 832        ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
 833                     ("Cnt_Ofdm_fail =%d\n", FalseAlmCnt->Cnt_Ofdm_fail));
 834        ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
 835                     ("Total False Alarm =%d\n", FalseAlmCnt->Cnt_all));
 836}
 837
 838/* 3 ============================================================ */
 839/* 3 CCK Packet Detect Threshold */
 840/* 3 ============================================================ */
 841
 842void odm_CCKPacketDetectionThresh23a(struct dm_odm_t *pDM_Odm)
 843{
 844        struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
 845        u8 CurCCK_CCAThres;
 846
 847        if (pDM_Odm->ExtLNA)
 848                return;
 849
 850        if (pDM_Odm->bLinked) {
 851                if (pDM_Odm->RSSI_Min > 25) {
 852                        CurCCK_CCAThres = 0xcd;
 853                } else if (pDM_Odm->RSSI_Min <= 25 && pDM_Odm->RSSI_Min > 10) {
 854                        CurCCK_CCAThres = 0x83;
 855                } else {
 856                        if (FalseAlmCnt->Cnt_Cck_fail > 1000)
 857                                CurCCK_CCAThres = 0x83;
 858                        else
 859                                CurCCK_CCAThres = 0x40;
 860                }
 861        } else {
 862                if (FalseAlmCnt->Cnt_Cck_fail > 1000)
 863                        CurCCK_CCAThres = 0x83;
 864                else
 865                        CurCCK_CCAThres = 0x40;
 866        }
 867
 868        ODM_Write_CCK_CCA_Thres23a(pDM_Odm, CurCCK_CCAThres);
 869}
 870
 871void ODM_Write_CCK_CCA_Thres23a(struct dm_odm_t *pDM_Odm, u8 CurCCK_CCAThres)
 872{
 873        struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
 874
 875        if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres)
 876                rtl8723au_write8(pDM_Odm->Adapter, ODM_REG(CCK_CCA, pDM_Odm),
 877                                 CurCCK_CCAThres);
 878        pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres;
 879        pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres;
 880}
 881
 882/* 3 ============================================================ */
 883/* 3 BB Power Save */
 884/* 3 ============================================================ */
 885void odm23a_DynBBPSInit(struct dm_odm_t *pDM_Odm)
 886{
 887        struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable;
 888
 889        pDM_PSTable->PreCCAState = CCA_MAX;
 890        pDM_PSTable->CurCCAState = CCA_MAX;
 891        pDM_PSTable->PreRFState = RF_MAX;
 892        pDM_PSTable->CurRFState = RF_MAX;
 893        pDM_PSTable->Rssi_val_min = 0;
 894        pDM_PSTable->initialize = 0;
 895}
 896
 897void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm)
 898{
 899        return;
 900}
 901
 902void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal)
 903{
 904        struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable;
 905        struct rtw_adapter *adapter = pDM_Odm->Adapter;
 906        u32 val32;
 907        u8 Rssi_Up_bound = 30;
 908        u8 Rssi_Low_bound = 25;
 909        if (pDM_PSTable->initialize == 0) {
 910
 911                pDM_PSTable->Reg874 =
 912                        rtl8723au_read32(adapter, 0x874) & 0x1CC000;
 913                pDM_PSTable->RegC70 =
 914                        rtl8723au_read32(adapter, 0xc70) & BIT(3);
 915                pDM_PSTable->Reg85C =
 916                        rtl8723au_read32(adapter, 0x85c) & 0xFF000000;
 917                pDM_PSTable->RegA74 = rtl8723au_read32(adapter, 0xa74) & 0xF000;
 918                pDM_PSTable->initialize = 1;
 919        }
 920
 921        if (!bForceInNormal) {
 922                if (pDM_Odm->RSSI_Min != 0xFF) {
 923                        if (pDM_PSTable->PreRFState == RF_Normal) {
 924                                if (pDM_Odm->RSSI_Min >= Rssi_Up_bound)
 925                                        pDM_PSTable->CurRFState = RF_Save;
 926                                else
 927                                        pDM_PSTable->CurRFState = RF_Normal;
 928                        } else {
 929                                if (pDM_Odm->RSSI_Min <= Rssi_Low_bound)
 930                                        pDM_PSTable->CurRFState = RF_Normal;
 931                                else
 932                                        pDM_PSTable->CurRFState = RF_Save;
 933                        }
 934                } else {
 935                        pDM_PSTable->CurRFState = RF_MAX;
 936                }
 937        } else {
 938                pDM_PSTable->CurRFState = RF_Normal;
 939        }
 940
 941        if (pDM_PSTable->PreRFState != pDM_PSTable->CurRFState) {
 942                if (pDM_PSTable->CurRFState == RF_Save) {
 943                        /*  <tynli_note> 8723 RSSI report will be wrong.
 944                         * Set 0x874[5]= 1 when enter BB power saving mode. */
 945                        /*  Suggested by SD3 Yu-Nan. 2011.01.20. */
 946                        /* Reg874[5]= 1b'1 */
 947                        if (pDM_Odm->SupportICType == ODM_RTL8723A) {
 948                                val32 = rtl8723au_read32(adapter, 0x874);
 949                                val32 |= BIT(5);
 950                                rtl8723au_write32(adapter, 0x874, val32);
 951                        }
 952                        /* Reg874[20:18]= 3'b010 */
 953                        val32 = rtl8723au_read32(adapter, 0x874);
 954                        val32 &= ~(BIT(18) | BIT(20));
 955                        val32 |= BIT(19);
 956                        rtl8723au_write32(adapter, 0x874, val32);
 957                        /* RegC70[3]= 1'b0 */
 958                        val32 = rtl8723au_read32(adapter, 0xc70);
 959                        val32 &= ~BIT(3);
 960                        rtl8723au_write32(adapter, 0xc70, val32);
 961                        /* Reg85C[31:24]= 0x63 */
 962                        val32 = rtl8723au_read32(adapter, 0x85c);
 963                        val32 &= 0x00ffffff;
 964                        val32 |= 0x63000000;
 965                        rtl8723au_write32(adapter, 0x85c, val32);
 966                        /* Reg874[15:14]= 2'b10 */
 967                        val32 = rtl8723au_read32(adapter, 0x874);
 968                        val32 &= ~BIT(14);
 969                        val32 |= BIT(15);
 970                        rtl8723au_write32(adapter, 0x874, val32);
 971                        /* RegA75[7:4]= 0x3 */
 972                        val32 = rtl8723au_read32(adapter, 0xa74);
 973                        val32 &= ~(BIT(14) | BIT(15));
 974                        val32 |= (BIT(12) | BIT(13));
 975                        rtl8723au_write32(adapter, 0xa74, val32);
 976                        /* Reg818[28]= 1'b0 */
 977                        val32 = rtl8723au_read32(adapter, 0x818);
 978                        val32 &= ~BIT(28);
 979                        rtl8723au_write32(adapter, 0x818, val32);
 980                        /* Reg818[28]= 1'b1 */
 981                        val32 = rtl8723au_read32(adapter, 0x818);
 982                        val32 |= BIT(28);
 983                        rtl8723au_write32(adapter, 0x818, val32);
 984                } else {
 985                        val32 = rtl8723au_read32(adapter, 0x874);
 986                        val32 |= pDM_PSTable->Reg874;
 987                        rtl8723au_write32(adapter, 0x874, val32);
 988
 989                        val32 = rtl8723au_read32(adapter, 0xc70);
 990                        val32 |= pDM_PSTable->RegC70;
 991                        rtl8723au_write32(adapter, 0xc70, val32);
 992
 993                        val32 = rtl8723au_read32(adapter, 0x85c);
 994                        val32 |= pDM_PSTable->Reg85C;
 995                        rtl8723au_write32(adapter, 0x85c, val32);
 996
 997                        val32 = rtl8723au_read32(adapter, 0xa74);
 998                        val32 |= pDM_PSTable->RegA74;
 999                        rtl8723au_write32(adapter, 0xa74, val32);
1000
1001                        val32 = rtl8723au_read32(adapter, 0x818);
1002                        val32 &= ~BIT(28);
1003                        rtl8723au_write32(adapter, 0x818, val32);
1004
1005                        /* Reg874[5]= 1b'0 */
1006                        if (pDM_Odm->SupportICType == ODM_RTL8723A) {
1007                                val32 = rtl8723au_read32(adapter, 0x874);
1008                                val32 &= ~BIT(5);
1009                                rtl8723au_write32(adapter, 0x874, val32);
1010                        }
1011                }
1012                pDM_PSTable->PreRFState = pDM_PSTable->CurRFState;
1013        }
1014}
1015
1016/* 3 ============================================================ */
1017/* 3 RATR MASK */
1018/* 3 ============================================================ */
1019/* 3 ============================================================ */
1020/* 3 Rate Adaptive */
1021/* 3 ============================================================ */
1022
1023void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm)
1024{
1025        struct odm_rate_adapt *pOdmRA = &pDM_Odm->RateAdaptive;
1026
1027        pOdmRA->Type = DM_Type_ByDriver;
1028
1029        pOdmRA->RATRState = DM_RATR_STA_INIT;
1030        pOdmRA->HighRSSIThresh = 50;
1031        pOdmRA->LowRSSIThresh = 20;
1032}
1033
1034u32 ODM_Get_Rate_Bitmap23a(struct hal_data_8723a *pHalData, u32 macid,
1035                           u32 ra_mask, u8 rssi_level)
1036{
1037        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1038        struct sta_info *pEntry;
1039        u32 rate_bitmap = 0x0fffffff;
1040        u8 WirelessMode;
1041
1042        pEntry = pDM_Odm->pODM_StaInfo[macid];
1043        if (!pEntry)
1044                return ra_mask;
1045
1046        WirelessMode = pEntry->wireless_mode;
1047
1048        switch (WirelessMode) {
1049        case ODM_WM_B:
1050                if (ra_mask & 0x0000000c)               /* 11M or 5.5M enable */
1051                        rate_bitmap = 0x0000000d;
1052                else
1053                        rate_bitmap = 0x0000000f;
1054                break;
1055        case (ODM_WM_A|ODM_WM_G):
1056                if (rssi_level == DM_RATR_STA_HIGH)
1057                        rate_bitmap = 0x00000f00;
1058                else
1059                        rate_bitmap = 0x00000ff0;
1060                break;
1061        case (ODM_WM_B|ODM_WM_G):
1062                if (rssi_level == DM_RATR_STA_HIGH)
1063                        rate_bitmap = 0x00000f00;
1064                else if (rssi_level == DM_RATR_STA_MIDDLE)
1065                        rate_bitmap = 0x00000ff0;
1066                else
1067                        rate_bitmap = 0x00000ff5;
1068                break;
1069        case (ODM_WM_B|ODM_WM_G|ODM_WM_N24G):
1070        case (ODM_WM_A|ODM_WM_B|ODM_WM_G|ODM_WM_N24G):
1071                if (pHalData->rf_type == RF_1T2R ||
1072                    pHalData->rf_type == RF_1T1R) {
1073                        if (rssi_level == DM_RATR_STA_HIGH) {
1074                                rate_bitmap = 0x000f0000;
1075                        } else if (rssi_level == DM_RATR_STA_MIDDLE) {
1076                                rate_bitmap = 0x000ff000;
1077                        } else {
1078                                if (pHalData->CurrentChannelBW ==
1079                                    HT_CHANNEL_WIDTH_40)
1080                                        rate_bitmap = 0x000ff015;
1081                                else
1082                                        rate_bitmap = 0x000ff005;
1083                        }
1084                } else {
1085                        if (rssi_level == DM_RATR_STA_HIGH) {
1086                                rate_bitmap = 0x0f8f0000;
1087                        } else if (rssi_level == DM_RATR_STA_MIDDLE) {
1088                                rate_bitmap = 0x0f8ff000;
1089                        } else {
1090                                if (pHalData->CurrentChannelBW ==
1091                                    HT_CHANNEL_WIDTH_40)
1092                                        rate_bitmap = 0x0f8ff015;
1093                                else
1094                                        rate_bitmap = 0x0f8ff005;
1095                        }
1096                }
1097                break;
1098        default:
1099                /* case WIRELESS_11_24N: */
1100                /* case WIRELESS_11_5N: */
1101                if (pHalData->rf_type == RF_1T2R)
1102                        rate_bitmap = 0x000fffff;
1103                else
1104                        rate_bitmap = 0x0fffffff;
1105                break;
1106        }
1107
1108        ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD,
1109        (" ==> rssi_level:0x%02x, WirelessMode:0x%02x, rate_bitmap:0x%08x \n",
1110         rssi_level, WirelessMode, rate_bitmap));
1111
1112        return rate_bitmap;
1113}
1114
1115/*-----------------------------------------------------------------------------
1116 * Function:    odm_RefreshRateAdaptiveMask()
1117 *
1118 * Overview:    Update rate table mask according to rssi
1119 *
1120 * Input:               NONE
1121 *
1122 * Output:              NONE
1123 *
1124 * Return:              NONE
1125 *
1126 * Revised History:
1127 *When          Who             Remark
1128 *05/27/2009    hpfan   Create Version 0.
1129 *
1130 *---------------------------------------------------------------------------*/
1131static void odm_RefreshRateAdaptiveMask(struct dm_odm_t *pDM_Odm)
1132{
1133        struct rtw_adapter *pAdapter = pDM_Odm->Adapter;
1134        u32 smoothed;
1135        u8 i;
1136
1137        if (pAdapter->bDriverStopped) {
1138                ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_TRACE,
1139                             ("<---- %s: driver is going to unload\n",
1140                              __func__));
1141                return;
1142        }
1143
1144        for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
1145                struct sta_info *pstat = pDM_Odm->pODM_StaInfo[i];
1146                if (pstat) {
1147                        smoothed = pstat->rssi_stat.UndecoratedSmoothedPWDB;
1148                        if (ODM_RAStateCheck23a(pDM_Odm, smoothed, false,
1149                                                &pstat->rssi_level)) {
1150                                ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK,
1151                                             ODM_DBG_LOUD,
1152                                             ("RSSI:%d, RSSI_LEVEL:%d\n",
1153                                              smoothed,
1154                                              pstat->rssi_level));
1155                                rtw_hal_update_ra_mask23a(pstat,
1156                                                          pstat->rssi_level);
1157                        }
1158                }
1159        }
1160}
1161
1162/*  Return Value: bool */
1163/*  - true: RATRState is changed. */
1164bool ODM_RAStateCheck23a(struct dm_odm_t *pDM_Odm, s32 RSSI, bool bForceUpdate,
1165                         u8 *pRATRState)
1166{
1167        struct odm_rate_adapt *pRA = &pDM_Odm->RateAdaptive;
1168        const u8 GoUpGap = 5;
1169        u8 HighRSSIThreshForRA = pRA->HighRSSIThresh;
1170        u8 LowRSSIThreshForRA = pRA->LowRSSIThresh;
1171        u8 RATRState;
1172
1173        /*  Threshold Adjustment: */
1174        /*  when RSSI state trends to go up one or two levels, make sure RSSI is high enough. */
1175        /*  Here GoUpGap is added to solve the boundary's level alternation issue. */
1176        switch (*pRATRState) {
1177        case DM_RATR_STA_INIT:
1178        case DM_RATR_STA_HIGH:
1179                break;
1180        case DM_RATR_STA_MIDDLE:
1181                HighRSSIThreshForRA += GoUpGap;
1182                break;
1183        case DM_RATR_STA_LOW:
1184                HighRSSIThreshForRA += GoUpGap;
1185                LowRSSIThreshForRA += GoUpGap;
1186                break;
1187        default:
1188                ODM_RT_ASSERT(pDM_Odm, false, ("wrong rssi level setting %d !",
1189                                               *pRATRState));
1190                break;
1191        }
1192
1193        /*  Decide RATRState by RSSI. */
1194        if (RSSI > HighRSSIThreshForRA)
1195                RATRState = DM_RATR_STA_HIGH;
1196        else if (RSSI > LowRSSIThreshForRA)
1197                RATRState = DM_RATR_STA_MIDDLE;
1198        else
1199                RATRState = DM_RATR_STA_LOW;
1200
1201        if (*pRATRState != RATRState || bForceUpdate) {
1202                ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD,
1203                             ("RSSI Level %d -> %d\n", *pRATRState, RATRState));
1204                *pRATRState = RATRState;
1205                return true;
1206        }
1207        return false;
1208}
1209
1210/* 3 ============================================================ */
1211/* 3 Dynamic Tx Power */
1212/* 3 ============================================================ */
1213
1214void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm)
1215{
1216        struct rtw_adapter *Adapter = pDM_Odm->Adapter;
1217        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1218        struct dm_priv *pdmpriv = &pHalData->dmpriv;
1219
1220        /*
1221         * This is never changed, so we should be able to clean up the
1222         * code checking for different values in rtl8723a_rf6052.c
1223         */
1224        pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal;
1225}
1226
1227static void
1228FindMinimumRSSI(struct rtw_adapter *pAdapter)
1229{
1230        struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
1231        struct dm_priv *pdmpriv = &pHalData->dmpriv;
1232        struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1233
1234        /* 1 1.Determine the minimum RSSI */
1235
1236        if (!pDM_Odm->bLinked && !pdmpriv->EntryMinUndecoratedSmoothedPWDB)
1237                pdmpriv->MinUndecoratedPWDBForDM = 0;
1238        else
1239                pdmpriv->MinUndecoratedPWDBForDM =
1240                        pdmpriv->EntryMinUndecoratedSmoothedPWDB;
1241}
1242
1243static void odm_RSSIMonitorCheck(struct dm_odm_t *pDM_Odm)
1244{
1245        struct rtw_adapter *Adapter = pDM_Odm->Adapter;
1246        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1247        struct dm_priv *pdmpriv = &pHalData->dmpriv;
1248        int i;
1249        int MaxDB = 0, MinDB = 0xff;
1250        u8 sta_cnt = 0;
1251        u32 tmpdb;
1252        u32 PWDB_rssi[NUM_STA] = {0};/* 0~15]:MACID, [16~31]:PWDB_rssi */
1253        struct sta_info *psta;
1254
1255        if (!pDM_Odm->bLinked)
1256                return;
1257
1258        for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
1259                psta = pDM_Odm->pODM_StaInfo[i];
1260                if (psta) {
1261                        if (psta->rssi_stat.UndecoratedSmoothedPWDB < MinDB)
1262                                MinDB = psta->rssi_stat.UndecoratedSmoothedPWDB;
1263
1264                        if (psta->rssi_stat.UndecoratedSmoothedPWDB > MaxDB)
1265                                MaxDB = psta->rssi_stat.UndecoratedSmoothedPWDB;
1266
1267                        if (psta->rssi_stat.UndecoratedSmoothedPWDB != -1) {
1268                                tmpdb = psta->rssi_stat.UndecoratedSmoothedPWDB;
1269                                PWDB_rssi[sta_cnt++] = psta->mac_id |
1270                                        (tmpdb << 16);
1271                        }
1272                }
1273        }
1274
1275        for (i = 0; i < sta_cnt; i++) {
1276                if (PWDB_rssi[i] != (0))
1277                        rtl8723a_set_rssi_cmd(Adapter, (u8 *)&PWDB_rssi[i]);
1278        }
1279
1280        pdmpriv->EntryMaxUndecoratedSmoothedPWDB = MaxDB;
1281
1282        if (MinDB != 0xff) /*  If associated entry is found */
1283                pdmpriv->EntryMinUndecoratedSmoothedPWDB = MinDB;
1284        else
1285                pdmpriv->EntryMinUndecoratedSmoothedPWDB = 0;
1286
1287        FindMinimumRSSI(Adapter);/* get pdmpriv->MinUndecoratedPWDBForDM */
1288
1289        ODM_CmnInfoUpdate23a(&pHalData->odmpriv, ODM_CMNINFO_RSSI_MIN,
1290                             pdmpriv->MinUndecoratedPWDBForDM);
1291}
1292
1293/* endif */
1294/* 3 ============================================================ */
1295/* 3 Tx Power Tracking */
1296/* 3 ============================================================ */
1297
1298static void odm_TXPowerTrackingInit(struct dm_odm_t *pDM_Odm)
1299{
1300        struct rtw_adapter *Adapter = pDM_Odm->Adapter;
1301        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1302        struct dm_priv *pdmpriv = &pHalData->dmpriv;
1303
1304        pdmpriv->bTXPowerTracking = true;
1305        pdmpriv->TXPowercount = 0;
1306        pdmpriv->bTXPowerTrackingInit = false;
1307        pdmpriv->TxPowerTrackControl = true;
1308        MSG_8723A("pdmpriv->TxPowerTrackControl = %d\n",
1309                  pdmpriv->TxPowerTrackControl);
1310
1311        pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = true;
1312}
1313
1314/* EDCA Turbo */
1315static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm)
1316{
1317        struct rtw_adapter *Adapter = pDM_Odm->Adapter;
1318
1319        pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false;
1320        Adapter->recvpriv.bIsAnyNonBEPkts = false;
1321
1322        ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD,
1323                     ("Orginial VO PARAM: 0x%x\n",
1324                      rtl8723au_read32(Adapter, ODM_EDCA_VO_PARAM)));
1325        ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD,
1326                     ("Orginial VI PARAM: 0x%x\n",
1327                      rtl8723au_read32(Adapter, ODM_EDCA_VI_PARAM)));
1328        ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD,
1329                     ("Orginial BE PARAM: 0x%x\n",
1330                      rtl8723au_read32(Adapter, ODM_EDCA_BE_PARAM)));
1331        ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD,
1332                     ("Orginial BK PARAM: 0x%x\n",
1333                      rtl8723au_read32(Adapter, ODM_EDCA_BK_PARAM)));
1334}
1335
1336static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm)
1337{
1338        struct rtw_adapter *Adapter = pDM_Odm->Adapter;
1339        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1340        struct xmit_priv *pxmitpriv = &Adapter->xmitpriv;
1341        struct recv_priv *precvpriv = &Adapter->recvpriv;
1342        struct registry_priv *pregpriv = &Adapter->registrypriv;
1343        struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
1344        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1345        u32 trafficIndex;
1346        u32 edca_param;
1347        u64 cur_tx_bytes;
1348        u64 cur_rx_bytes;
1349
1350        /*  For AP/ADSL use struct rtl8723a_priv * */
1351        /*  For CE/NIC use struct rtw_adapter * */
1352
1353        /*
1354         * 2011/09/29 MH In HW integration first stage, we provide 4
1355         * different handle to operate at the same time. In the stage2/3,
1356         * we need to prive universal interface and merge all HW dynamic
1357         * mechanism.
1358         */
1359
1360        if ((pregpriv->wifi_spec == 1))/*  (pmlmeinfo->HT_enable == 0)) */
1361                goto dm_CheckEdcaTurbo_EXIT;
1362
1363        if (pmlmeinfo->assoc_AP_vendor >=  HT_IOT_PEER_MAX)
1364                goto dm_CheckEdcaTurbo_EXIT;
1365
1366        if (rtl8723a_BT_disable_EDCA_turbo(Adapter))
1367                goto dm_CheckEdcaTurbo_EXIT;
1368
1369        /*  Check if the status needs to be changed. */
1370        if (!precvpriv->bIsAnyNonBEPkts) {
1371                cur_tx_bytes = pxmitpriv->tx_bytes - pxmitpriv->last_tx_bytes;
1372                cur_rx_bytes = precvpriv->rx_bytes - precvpriv->last_rx_bytes;
1373
1374                /* traffic, TX or RX */
1375                if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK) ||
1376                    (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS)) {
1377                        if (cur_tx_bytes > (cur_rx_bytes << 2)) {
1378                                /*  Uplink TP is present. */
1379                                trafficIndex = UP_LINK;
1380                        } else { /*  Balance TP is present. */
1381                                trafficIndex = DOWN_LINK;
1382                        }
1383                } else {
1384                        if (cur_rx_bytes > (cur_tx_bytes << 2)) {
1385                                /*  Downlink TP is present. */
1386                                trafficIndex = DOWN_LINK;
1387                        } else { /*  Balance TP is present. */
1388                                trafficIndex = UP_LINK;
1389                        }
1390                }
1391
1392                if ((pDM_Odm->DM_EDCA_Table.prv_traffic_idx != trafficIndex) ||
1393                    (!pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA)) {
1394                        if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_CISCO) &&
1395                            (pmlmeext->cur_wireless_mode & WIRELESS_11_24N))
1396                                edca_param = EDCAParam[pmlmeinfo->assoc_AP_vendor][trafficIndex];
1397                        else
1398                                edca_param = EDCAParam[HT_IOT_PEER_UNKNOWN][trafficIndex];
1399                        rtl8723au_write32(Adapter, REG_EDCA_BE_PARAM,
1400                                          edca_param);
1401
1402                        pDM_Odm->DM_EDCA_Table.prv_traffic_idx = trafficIndex;
1403                }
1404
1405                pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = true;
1406        } else {
1407                /*  Turn Off EDCA turbo here. */
1408                /*  Restore original EDCA according to the declaration of AP. */
1409                if (pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA) {
1410                        rtl8723au_write32(Adapter, REG_EDCA_BE_PARAM,
1411                                          pHalData->AcParam_BE);
1412                        pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false;
1413                }
1414        }
1415
1416dm_CheckEdcaTurbo_EXIT:
1417        /*  Set variables for next time. */
1418        precvpriv->bIsAnyNonBEPkts = false;
1419        pxmitpriv->last_tx_bytes = pxmitpriv->tx_bytes;
1420        precvpriv->last_rx_bytes = precvpriv->rx_bytes;
1421}
1422
1423u32 GetPSDData(struct dm_odm_t *pDM_Odm, unsigned int point,
1424               u8 initial_gain_psd)
1425{
1426        struct rtw_adapter *adapter = pDM_Odm->Adapter;
1427        u32 psd_report, val32;
1428
1429        /* Set DCO frequency index, offset = (40MHz/SamplePts)*point */
1430        val32 = rtl8723au_read32(adapter, 0x808);
1431        val32 &= ~0x3ff;
1432        val32 |= (point & 0x3ff);
1433        rtl8723au_write32(adapter, 0x808, val32);
1434
1435        /* Start PSD calculation, Reg808[22]= 0->1 */
1436        val32 = rtl8723au_read32(adapter, 0x808);
1437        val32 |= BIT(22);
1438        rtl8723au_write32(adapter, 0x808, val32);
1439        /* Need to wait for HW PSD report */
1440        udelay(30);
1441        val32 = rtl8723au_read32(adapter, 0x808);
1442        val32 &= ~BIT(22);
1443        rtl8723au_write32(adapter, 0x808, val32);
1444        /* Read PSD report, Reg8B4[15:0] */
1445        psd_report = rtl8723au_read32(adapter, 0x8B4) & 0x0000FFFF;
1446
1447        psd_report = (u32)(ConvertTo_dB23a(psd_report)) +
1448                (u32)(initial_gain_psd-0x1c);
1449
1450        return psd_report;
1451}
1452
1453u32 ConvertTo_dB23a(u32 Value)
1454{
1455        u8 i;
1456        u8 j;
1457        u32 dB;
1458
1459        Value = Value & 0xFFFF;
1460
1461        for (i = 0; i < 8; i++) {
1462                if (Value <= dB_Invert_Table[i][11])
1463                        break;
1464        }
1465
1466        if (i >= 8)
1467                return 96;      /*  maximum 96 dB */
1468
1469        for (j = 0; j < 12; j++) {
1470                if (Value <= dB_Invert_Table[i][j])
1471                        break;
1472        }
1473
1474        dB = i*12 + j + 1;
1475
1476        return dB;
1477}
1478
1479/*  */
1480/*  Description: */
1481/* Set Single/Dual Antenna default setting for products that do not
1482 * do detection in advance. */
1483/*  */
1484/*  Added by Joseph, 2012.03.22 */
1485/*  */
1486void ODM_SingleDualAntennaDefaultSetting(struct dm_odm_t *pDM_Odm)
1487{
1488        struct sw_ant_sw *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table;
1489
1490        pDM_SWAT_Table->ANTA_ON = true;
1491        pDM_SWAT_Table->ANTB_ON = true;
1492}
1493
1494/* 2 8723A ANT DETECT */
1495
1496static void odm_PHY_SaveAFERegisters(struct dm_odm_t *pDM_Odm, u32 *AFEReg,
1497                                     u32 *AFEBackup, u32 RegisterNum)
1498{
1499        u32 i;
1500
1501        for (i = 0 ; i < RegisterNum ; i++)
1502                AFEBackup[i] = rtl8723au_read32(pDM_Odm->Adapter, AFEReg[i]);
1503}
1504
1505static void odm_PHY_ReloadAFERegisters(struct dm_odm_t *pDM_Odm, u32 *AFEReg,
1506                                       u32 *AFEBackup, u32 RegiesterNum)
1507{
1508        u32 i;
1509
1510        for (i = 0 ; i < RegiesterNum; i++)
1511                rtl8723au_write32(pDM_Odm->Adapter, AFEReg[i], AFEBackup[i]);
1512}
1513
1514/* 2 8723A ANT DETECT */
1515/*  Description: */
1516/* Implement IQK single tone for RF DPK loopback and BB PSD scanning. */
1517/* This function is cooperated with BB team Neil. */
1518bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode)
1519{
1520        struct sw_ant_sw *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table;
1521        struct rtw_adapter *adapter = pDM_Odm->Adapter;
1522        u32 CurrentChannel, RfLoopReg;
1523        u8 n;
1524        u32 Reg88c, Regc08, Reg874, Regc50, val32;
1525        u8 initial_gain = 0x5a;
1526        u32 PSD_report_tmp;
1527        u32 AntA_report = 0x0, AntB_report = 0x0, AntO_report = 0x0;
1528        bool bResult = true;
1529        u32 AFE_Backup[16];
1530        u32 AFE_REG_8723A[16] = {
1531                rRx_Wait_CCA, rTx_CCK_RFON,
1532                rTx_CCK_BBON, rTx_OFDM_RFON,
1533                rTx_OFDM_BBON, rTx_To_Rx,
1534                rTx_To_Tx, rRx_CCK,
1535                rRx_OFDM, rRx_Wait_RIFS,
1536                rRx_TO_Rx, rStandby,
1537                rSleep, rPMPD_ANAEN,
1538                rFPGA0_XCD_SwitchControl, rBlue_Tooth};
1539
1540        if (!(pDM_Odm->SupportICType & ODM_RTL8723A))
1541                return bResult;
1542
1543        if (!(pDM_Odm->SupportAbility&ODM_BB_ANT_DIV))
1544                return bResult;
1545        /* 1 Backup Current RF/BB Settings */
1546
1547        CurrentChannel = ODM_GetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL,
1548                                      bRFRegOffsetMask);
1549        RfLoopReg = ODM_GetRFReg(pDM_Odm, RF_PATH_A, 0x00, bRFRegOffsetMask);
1550        /*  change to Antenna A */
1551        val32 = rtl8723au_read32(adapter, rFPGA0_XA_RFInterfaceOE);
1552        val32 &= ~0x300;
1553        val32 |= 0x100;         /* Enable antenna A */
1554        rtl8723au_write32(adapter, rFPGA0_XA_RFInterfaceOE, val32);
1555
1556        /*  Step 1: USE IQK to transmitter single tone */
1557
1558        udelay(10);
1559
1560        /* Store A Path Register 88c, c08, 874, c50 */
1561        Reg88c = rtl8723au_read32(adapter, rFPGA0_AnalogParameter4);
1562        Regc08 = rtl8723au_read32(adapter, rOFDM0_TRMuxPar);
1563        Reg874 = rtl8723au_read32(adapter, rFPGA0_XCD_RFInterfaceSW);
1564        Regc50 = rtl8723au_read32(adapter, rOFDM0_XAAGCCore1);
1565
1566        /*  Store AFE Registers */
1567        odm_PHY_SaveAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16);
1568
1569        /* Set PSD 128 pts */
1570        val32 = rtl8723au_read32(adapter, rFPGA0_PSDFunction);
1571        val32 &= ~(BIT(14) | BIT(15));
1572        rtl8723au_write32(adapter, rFPGA0_PSDFunction, val32);
1573
1574        /*  To SET CH1 to do */
1575        ODM_SetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask, 0x01);
1576
1577        /*  AFE all on step */
1578        rtl8723au_write32(adapter, rRx_Wait_CCA, 0x6FDB25A4);
1579        rtl8723au_write32(adapter, rTx_CCK_RFON, 0x6FDB25A4);
1580        rtl8723au_write32(adapter, rTx_CCK_BBON, 0x6FDB25A4);
1581        rtl8723au_write32(adapter, rTx_OFDM_RFON, 0x6FDB25A4);
1582        rtl8723au_write32(adapter, rTx_OFDM_BBON, 0x6FDB25A4);
1583        rtl8723au_write32(adapter, rTx_To_Rx, 0x6FDB25A4);
1584        rtl8723au_write32(adapter, rTx_To_Tx, 0x6FDB25A4);
1585        rtl8723au_write32(adapter, rRx_CCK, 0x6FDB25A4);
1586        rtl8723au_write32(adapter, rRx_OFDM, 0x6FDB25A4);
1587        rtl8723au_write32(adapter, rRx_Wait_RIFS, 0x6FDB25A4);
1588        rtl8723au_write32(adapter, rRx_TO_Rx, 0x6FDB25A4);
1589        rtl8723au_write32(adapter, rStandby, 0x6FDB25A4);
1590        rtl8723au_write32(adapter, rSleep, 0x6FDB25A4);
1591        rtl8723au_write32(adapter, rPMPD_ANAEN, 0x6FDB25A4);
1592        rtl8723au_write32(adapter, rFPGA0_XCD_SwitchControl, 0x6FDB25A4);
1593        rtl8723au_write32(adapter, rBlue_Tooth, 0x6FDB25A4);
1594
1595        /*  3 wire Disable */
1596        rtl8723au_write32(adapter, rFPGA0_AnalogParameter4, 0xCCF000C0);
1597
1598        /* BB IQK Setting */
1599        rtl8723au_write32(adapter, rOFDM0_TRMuxPar, 0x000800E4);
1600        rtl8723au_write32(adapter, rFPGA0_XCD_RFInterfaceSW, 0x22208000);
1601
1602        /* IQK setting tone@ 4.34Mhz */
1603        rtl8723au_write32(adapter, rTx_IQK_Tone_A, 0x10008C1C);
1604        rtl8723au_write32(adapter, rTx_IQK, 0x01007c00);
1605
1606        /* Page B init */
1607        rtl8723au_write32(adapter, rConfig_AntA, 0x00080000);
1608        rtl8723au_write32(adapter, rConfig_AntA, 0x0f600000);
1609        rtl8723au_write32(adapter, rRx_IQK, 0x01004800);
1610        rtl8723au_write32(adapter, rRx_IQK_Tone_A, 0x10008c1f);
1611        rtl8723au_write32(adapter, rTx_IQK_PI_A, 0x82150008);
1612        rtl8723au_write32(adapter, rRx_IQK_PI_A, 0x28150008);
1613        rtl8723au_write32(adapter, rIQK_AGC_Rsp, 0x001028d0);
1614
1615        /* RF loop Setting */
1616        ODM_SetRFReg(pDM_Odm, RF_PATH_A, 0x0, 0xFFFFF, 0x50008);
1617
1618        /* IQK Single tone start */
1619        rtl8723au_write32(adapter, rFPGA0_IQK, 0x80800000);
1620        rtl8723au_write32(adapter, rIQK_AGC_Pts, 0xf8000000);
1621        udelay(1000);
1622        PSD_report_tmp = 0x0;
1623
1624        for (n = 0; n < 2; n++) {
1625                PSD_report_tmp =  GetPSDData(pDM_Odm, 14, initial_gain);
1626                if (PSD_report_tmp > AntA_report)
1627                        AntA_report = PSD_report_tmp;
1628        }
1629
1630        PSD_report_tmp = 0x0;
1631
1632        val32 = rtl8723au_read32(adapter, rFPGA0_XA_RFInterfaceOE);
1633        val32 &= ~0x300;
1634        val32 |= 0x200;         /* Enable antenna B */
1635        rtl8723au_write32(adapter, rFPGA0_XA_RFInterfaceOE, val32);
1636        udelay(10);
1637
1638        for (n = 0; n < 2; n++) {
1639                PSD_report_tmp =  GetPSDData(pDM_Odm, 14, initial_gain);
1640                if (PSD_report_tmp > AntB_report)
1641                        AntB_report = PSD_report_tmp;
1642        }
1643
1644        /*  change to open case */
1645        /*  change to Ant A and B all open case */
1646        val32 = rtl8723au_read32(adapter, rFPGA0_XA_RFInterfaceOE);
1647        val32 &= ~0x300;
1648        rtl8723au_write32(adapter, rFPGA0_XA_RFInterfaceOE, val32);
1649        udelay(10);
1650
1651        for (n = 0; n < 2; n++) {
1652                PSD_report_tmp =  GetPSDData(pDM_Odm, 14, initial_gain);
1653                if (PSD_report_tmp > AntO_report)
1654                        AntO_report = PSD_report_tmp;
1655        }
1656
1657        /* Close IQK Single Tone function */
1658        rtl8723au_write32(adapter, rFPGA0_IQK, 0x00000000);
1659        PSD_report_tmp = 0x0;
1660
1661        /* 1 Return to antanna A */
1662        val32 = rtl8723au_read32(adapter, rFPGA0_XA_RFInterfaceOE);
1663        val32 &= ~0x300;
1664        val32 |= 0x100;         /* Enable antenna A */
1665        rtl8723au_write32(adapter, rFPGA0_XA_RFInterfaceOE, val32);
1666        rtl8723au_write32(adapter, rFPGA0_AnalogParameter4, Reg88c);
1667        rtl8723au_write32(adapter, rOFDM0_TRMuxPar, Regc08);
1668        rtl8723au_write32(adapter, rFPGA0_XCD_RFInterfaceSW, Reg874);
1669        val32 = rtl8723au_read32(adapter, rOFDM0_XAAGCCore1);
1670        val32 &= ~0x7f;
1671        val32 |= 0x40;
1672        rtl8723au_write32(adapter, rOFDM0_XAAGCCore1, val32);
1673
1674        rtl8723au_write32(adapter, rOFDM0_XAAGCCore1, Regc50);
1675        ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask,
1676                     CurrentChannel);
1677        ODM_SetRFReg(pDM_Odm, RF_PATH_A, 0x00, bRFRegOffsetMask, RfLoopReg);
1678
1679        /* Reload AFE Registers */
1680        odm_PHY_ReloadAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16);
1681
1682        ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
1683                     ("psd_report_A[%d]= %d \n", 2416, AntA_report));
1684        ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
1685                     ("psd_report_B[%d]= %d \n", 2416, AntB_report));
1686        ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
1687                     ("psd_report_O[%d]= %d \n", 2416, AntO_report));
1688
1689        /* 2 Test Ant B based on Ant A is ON */
1690        if (mode == ANTTESTB) {
1691                if (AntA_report >= 100) {
1692                        if (AntB_report > (AntA_report+1)) {
1693                                pDM_SWAT_Table->ANTB_ON = false;
1694                                ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Single Antenna A\n"));
1695                        } else {
1696                                pDM_SWAT_Table->ANTB_ON = true;
1697                                ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Dual Antenna is A and B\n"));
1698                        }
1699                } else {
1700                        ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Need to check again\n"));
1701                        pDM_SWAT_Table->ANTB_ON = false; /*  Set Antenna B off as default */
1702                        bResult = false;
1703                }
1704        } else if (mode == ANTTESTALL) {
1705                /* 2 Test Ant A and B based on DPDT Open */
1706                if ((AntO_report >= 100) & (AntO_report < 118)) {
1707                        if (AntA_report > (AntO_report+1)) {
1708                                pDM_SWAT_Table->ANTA_ON = false;
1709                                ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,
1710                                             ODM_DBG_LOUD, ("Ant A is OFF"));
1711                        } else {
1712                                pDM_SWAT_Table->ANTA_ON = true;
1713                                ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,
1714                                             ODM_DBG_LOUD, ("Ant A is ON"));
1715                        }
1716
1717                        if (AntB_report > (AntO_report+2)) {
1718                                pDM_SWAT_Table->ANTB_ON = false;
1719                                ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,
1720                                             ODM_DBG_LOUD, ("Ant B is OFF"));
1721                        } else {
1722                                pDM_SWAT_Table->ANTB_ON = true;
1723                                ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,
1724                                             ODM_DBG_LOUD, ("Ant B is ON"));
1725                        }
1726                }
1727        } else {
1728                ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
1729                ("ODM_SingleDualAntennaDetection(): Need to check again\n"));
1730                /*  Set Antenna A on as default */
1731                pDM_SWAT_Table->ANTA_ON = true;
1732                /*  Set Antenna B off as default */
1733                pDM_SWAT_Table->ANTB_ON = false;
1734                bResult = false;
1735        }
1736
1737        return bResult;
1738}
1739