Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include "r8192U.h"
0003 #include "r8192U_hw.h"
0004 #include "r819xU_phy.h"
0005 #include "r819xU_phyreg.h"
0006 #include "r8190_rtl8256.h"
0007 #include "r8192U_dm.h"
0008 #include "r819xU_firmware_img.h"
0009 
0010 #include "ieee80211/dot11d.h"
0011 #include <linux/bitops.h>
0012 
0013 static u32 RF_CHANNEL_TABLE_ZEBRA[] = {
0014     0,
0015     0x085c, /* 2412 1  */
0016     0x08dc, /* 2417 2  */
0017     0x095c, /* 2422 3  */
0018     0x09dc, /* 2427 4  */
0019     0x0a5c, /* 2432 5  */
0020     0x0adc, /* 2437 6  */
0021     0x0b5c, /* 2442 7  */
0022     0x0bdc, /* 2447 8  */
0023     0x0c5c, /* 2452 9  */
0024     0x0cdc, /* 2457 10 */
0025     0x0d5c, /* 2462 11 */
0026     0x0ddc, /* 2467 12 */
0027     0x0e5c, /* 2472 13 */
0028     0x0f72, /* 2484    */
0029 };
0030 
0031 #define rtl819XMACPHY_Array Rtl8192UsbMACPHY_Array
0032 
0033 /******************************************************************************
0034  * function:  This function checks different RF type to execute legal judgement.
0035  *            If RF Path is illegal, we will return false.
0036  * input:     net_device     *dev
0037  *            u32        e_rfpath
0038  * output:    none
0039  * return:    0(illegal, false), 1(legal, true)
0040  *****************************************************************************/
0041 u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, u32 e_rfpath)
0042 {
0043     u8 ret = 1;
0044     struct r8192_priv *priv = ieee80211_priv(dev);
0045 
0046     if (priv->rf_type == RF_2T4R) {
0047         ret = 0;
0048     } else if (priv->rf_type == RF_1T2R) {
0049         if (e_rfpath == RF90_PATH_A || e_rfpath == RF90_PATH_B)
0050             ret = 1;
0051         else if (e_rfpath == RF90_PATH_C || e_rfpath == RF90_PATH_D)
0052             ret = 0;
0053     }
0054     return ret;
0055 }
0056 
0057 /******************************************************************************
0058  * function:  This function sets specific bits to BB register
0059  * input:     net_device *dev
0060  *            u32        reg_addr   //target addr to be modified
0061  *            u32        bitmask    //taget bit pos to be modified
0062  *            u32        data       //value to be write
0063  * output:    none
0064  * return:    none
0065  * notice:
0066  ******************************************************************************/
0067 void rtl8192_setBBreg(struct net_device *dev, u32 reg_addr, u32 bitmask,
0068               u32 data)
0069 {
0070     u32 reg, bitshift;
0071 
0072     if (bitmask != bMaskDWord) {
0073         read_nic_dword(dev, reg_addr, &reg);
0074         bitshift = ffs(bitmask) - 1;
0075         reg &= ~bitmask;
0076         reg |= data << bitshift;
0077         write_nic_dword(dev, reg_addr, reg);
0078     } else {
0079         write_nic_dword(dev, reg_addr, data);
0080     }
0081 }
0082 
0083 /******************************************************************************
0084  * function:  This function reads specific bits from BB register
0085  * input:     net_device    *dev
0086  *            u32       reg_addr   //target addr to be readback
0087  *            u32       bitmask    //taget bit pos to be readback
0088  * output:    none
0089  * return:    u32       data       //the readback register value
0090  * notice:
0091  ******************************************************************************/
0092 u32 rtl8192_QueryBBReg(struct net_device *dev, u32 reg_addr, u32 bitmask)
0093 {
0094     u32 reg, bitshift;
0095 
0096     read_nic_dword(dev, reg_addr, &reg);
0097     bitshift = ffs(bitmask) - 1;
0098 
0099     return (reg & bitmask) >> bitshift;
0100 }
0101 
0102 static u32 phy_FwRFSerialRead(struct net_device *dev,
0103                   enum rf90_radio_path_e e_rfpath,
0104                   u32 offset);
0105 
0106 static void phy_FwRFSerialWrite(struct net_device *dev,
0107                 enum rf90_radio_path_e e_rfpath,
0108                 u32  offset,
0109                 u32  data);
0110 
0111 /******************************************************************************
0112  * function:  This function reads register from RF chip
0113  * input:     net_device        *dev
0114  *            rf90_radio_path_e e_rfpath    //radio path of A/B/C/D
0115  *            u32               offset     //target address to be read
0116  * output:    none
0117  * return:    u32               readback value
0118  * notice:    There are three types of serial operations:
0119  *            (1) Software serial write.
0120  *            (2)Hardware LSSI-Low Speed Serial Interface.
0121  *            (3)Hardware HSSI-High speed serial write.
0122  *            Driver here need to implement (1) and (2)
0123  *            ---need more spec for this information.
0124  ******************************************************************************/
0125 static u32 rtl8192_phy_RFSerialRead(struct net_device *dev,
0126                     enum rf90_radio_path_e e_rfpath, u32 offset)
0127 {
0128     struct r8192_priv *priv = ieee80211_priv(dev);
0129     u32 ret = 0;
0130     u32 new_offset = 0;
0131     BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[e_rfpath];
0132 
0133     rtl8192_setBBreg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData, 0);
0134     /* Make sure RF register offset is correct */
0135     offset &= 0x3f;
0136 
0137     /* Switch page for 8256 RF IC */
0138     if (priv->rf_chip == RF_8256) {
0139         if (offset >= 31) {
0140             priv->RfReg0Value[e_rfpath] |= 0x140;
0141             /* Switch to Reg_Mode2 for Reg 31-45 */
0142             rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset,
0143                      bMaskDWord,
0144                      priv->RfReg0Value[e_rfpath]<<16);
0145             /* Modify offset */
0146             new_offset = offset - 30;
0147         } else if (offset >= 16) {
0148             priv->RfReg0Value[e_rfpath] |= 0x100;
0149             priv->RfReg0Value[e_rfpath] &= (~0x40);
0150             /* Switch to Reg_Mode1 for Reg16-30 */
0151             rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset,
0152                      bMaskDWord,
0153                      priv->RfReg0Value[e_rfpath]<<16);
0154 
0155             new_offset = offset - 15;
0156         } else {
0157             new_offset = offset;
0158         }
0159     } else {
0160         RT_TRACE((COMP_PHY|COMP_ERR),
0161              "check RF type here, need to be 8256\n");
0162         new_offset = offset;
0163     }
0164     /* Put desired read addr to LSSI control Register */
0165     rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress,
0166              new_offset);
0167     /* Issue a posedge trigger */
0168     rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2,  bLSSIReadEdge, 0x0);
0169     rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2,  bLSSIReadEdge, 0x1);
0170 
0171     /* TODO: we should not delay such a long time. Ask for help from SD3 */
0172     usleep_range(1000, 1000);
0173 
0174     ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack,
0175                  bLSSIReadBackData);
0176 
0177     /* Switch back to Reg_Mode0 */
0178     if (priv->rf_chip == RF_8256) {
0179         priv->RfReg0Value[e_rfpath] &= 0xebf;
0180 
0181         rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord,
0182                  priv->RfReg0Value[e_rfpath] << 16);
0183     }
0184 
0185     return ret;
0186 }
0187 
0188 /******************************************************************************
0189  * function:  This function writes data to RF register
0190  * input:     net_device        *dev
0191  *            rf90_radio_path_e e_rfpath  //radio path of A/B/C/D
0192  *            u32               offset   //target address to be written
0193  *            u32               data     //the new register data to be written
0194  * output:    none
0195  * return:    none
0196  * notice:    For RF8256 only.
0197  * ===========================================================================
0198  * Reg Mode RegCTL[1]   RegCTL[0]       Note
0199  *      (Reg00[12]) (Reg00[10])
0200  * ===========================================================================
0201  * Reg_Mode0    0       x           Reg 0 ~ 15(0x0 ~ 0xf)
0202  * ---------------------------------------------------------------------------
0203  * Reg_Mode1    1       0           Reg 16 ~ 30(0x1 ~ 0xf)
0204  * ---------------------------------------------------------------------------
0205  * Reg_Mode2    1       1           Reg 31 ~ 45(0x1 ~ 0xf)
0206  * ---------------------------------------------------------------------------
0207  *****************************************************************************/
0208 static void rtl8192_phy_RFSerialWrite(struct net_device *dev,
0209                       enum rf90_radio_path_e e_rfpath,
0210                       u32 offset,
0211                       u32 data)
0212 {
0213     struct r8192_priv *priv = ieee80211_priv(dev);
0214     u32 DataAndAddr = 0, new_offset = 0;
0215     BB_REGISTER_DEFINITION_T    *pPhyReg = &priv->PHYRegDef[e_rfpath];
0216 
0217     offset &= 0x3f;
0218     if (priv->rf_chip == RF_8256) {
0219         if (offset >= 31) {
0220             priv->RfReg0Value[e_rfpath] |= 0x140;
0221             rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset,
0222                      bMaskDWord,
0223                      priv->RfReg0Value[e_rfpath] << 16);
0224             new_offset = offset - 30;
0225         } else if (offset >= 16) {
0226             priv->RfReg0Value[e_rfpath] |= 0x100;
0227             priv->RfReg0Value[e_rfpath] &= (~0x40);
0228             rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset,
0229                      bMaskDWord,
0230                      priv->RfReg0Value[e_rfpath]<<16);
0231             new_offset = offset - 15;
0232         } else {
0233             new_offset = offset;
0234         }
0235     } else {
0236         RT_TRACE((COMP_PHY|COMP_ERR),
0237              "check RF type here, need to be 8256\n");
0238         new_offset = offset;
0239     }
0240 
0241     /* Put write addr in [5:0] and write data in [31:16] */
0242     DataAndAddr = (data<<16) | (new_offset&0x3f);
0243 
0244     /* Write operation */
0245     rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
0246 
0247     if (offset == 0x0)
0248         priv->RfReg0Value[e_rfpath] = data;
0249 
0250     /* Switch back to Reg_Mode0 */
0251     if (priv->rf_chip == RF_8256) {
0252         if (offset != 0) {
0253             priv->RfReg0Value[e_rfpath] &= 0xebf;
0254             rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset,
0255                      bMaskDWord,
0256                      priv->RfReg0Value[e_rfpath] << 16);
0257         }
0258     }
0259 }
0260 
0261 /******************************************************************************
0262  * function:  This function set specific bits to RF register
0263  * input:     net_device        dev
0264  *            rf90_radio_path_e e_rfpath  //radio path of A/B/C/D
0265  *            u32               reg_addr //target addr to be modified
0266  *            u32               bitmask  //taget bit pos to be modified
0267  *            u32               data     //value to be written
0268  * output:    none
0269  * return:    none
0270  * notice:
0271  *****************************************************************************/
0272 void rtl8192_phy_SetRFReg(struct net_device *dev,
0273               enum rf90_radio_path_e e_rfpath,
0274               u32 reg_addr, u32 bitmask, u32 data)
0275 {
0276     struct r8192_priv *priv = ieee80211_priv(dev);
0277     u32 reg, bitshift;
0278 
0279     if (!rtl8192_phy_CheckIsLegalRFPath(dev, e_rfpath))
0280         return;
0281 
0282     if (priv->Rf_Mode == RF_OP_By_FW) {
0283         if (bitmask != bMask12Bits) {
0284             /* RF data is 12 bits only */
0285             reg = phy_FwRFSerialRead(dev, e_rfpath, reg_addr);
0286             bitshift =  ffs(bitmask) - 1;
0287             reg &= ~bitmask;
0288             reg |= data << bitshift;
0289 
0290             phy_FwRFSerialWrite(dev, e_rfpath, reg_addr, reg);
0291         } else {
0292             phy_FwRFSerialWrite(dev, e_rfpath, reg_addr, data);
0293         }
0294 
0295         udelay(200);
0296 
0297     } else {
0298         if (bitmask != bMask12Bits) {
0299             /* RF data is 12 bits only */
0300             reg = rtl8192_phy_RFSerialRead(dev, e_rfpath, reg_addr);
0301             bitshift =  ffs(bitmask) - 1;
0302             reg &= ~bitmask;
0303             reg |= data << bitshift;
0304 
0305             rtl8192_phy_RFSerialWrite(dev, e_rfpath, reg_addr, reg);
0306         } else {
0307             rtl8192_phy_RFSerialWrite(dev, e_rfpath, reg_addr, data);
0308         }
0309     }
0310 }
0311 
0312 /******************************************************************************
0313  * function:  This function reads specific bits from RF register
0314  * input:     net_device        *dev
0315  *            u32               reg_addr //target addr to be readback
0316  *            u32               bitmask  //taget bit pos to be readback
0317  * output:    none
0318  * return:    u32               data     //the readback register value
0319  * notice:
0320  *****************************************************************************/
0321 u32 rtl8192_phy_QueryRFReg(struct net_device *dev,
0322                enum rf90_radio_path_e e_rfpath,
0323                u32 reg_addr, u32 bitmask)
0324 {
0325     u32 reg, bitshift;
0326     struct r8192_priv *priv = ieee80211_priv(dev);
0327 
0328     if (!rtl8192_phy_CheckIsLegalRFPath(dev, e_rfpath))
0329         return 0;
0330     if (priv->Rf_Mode == RF_OP_By_FW) {
0331         reg = phy_FwRFSerialRead(dev, e_rfpath, reg_addr);
0332         udelay(200);
0333     } else {
0334         reg = rtl8192_phy_RFSerialRead(dev, e_rfpath, reg_addr);
0335     }
0336     bitshift =  ffs(bitmask) - 1;
0337     reg = (reg & bitmask) >> bitshift;
0338     return reg;
0339 }
0340 
0341 /******************************************************************************
0342  * function:  We support firmware to execute RF-R/W.
0343  * input:     net_device        *dev
0344  *            rf90_radio_path_e e_rfpath
0345  *            u32               offset
0346  * output:    none
0347  * return:    u32
0348  * notice:
0349  ****************************************************************************/
0350 static u32 phy_FwRFSerialRead(struct net_device *dev,
0351                   enum rf90_radio_path_e e_rfpath,
0352                   u32 offset)
0353 {
0354     u32     reg = 0;
0355     u32     data = 0;
0356     u8      time = 0;
0357     u32     tmp;
0358 
0359     /* Firmware RF Write control.
0360      * We can not execute the scheme in the initial step.
0361      * Otherwise, RF-R/W will waste much time.
0362      * This is only for site survey.
0363      */
0364     /* 1. Read operation need not insert data. bit 0-11 */
0365     /* 2. Write RF register address. bit 12-19 */
0366     data |= ((offset&0xFF)<<12);
0367     /* 3. Write RF path.  bit 20-21 */
0368     data |= ((e_rfpath&0x3)<<20);
0369     /* 4. Set RF read indicator. bit 22=0 */
0370     /* 5. Trigger Fw to operate the command. bit 31 */
0371     data |= 0x80000000;
0372     /* 6. We can not execute read operation if bit 31 is 1. */
0373     read_nic_dword(dev, QPNR, &tmp);
0374     while (tmp & 0x80000000) {
0375         /* If FW can not finish RF-R/W for more than ?? times.
0376          * We must reset FW.
0377          */
0378         if (time++ < 100) {
0379             udelay(10);
0380             read_nic_dword(dev, QPNR, &tmp);
0381         } else {
0382             break;
0383         }
0384     }
0385     /* 7. Execute read operation. */
0386     write_nic_dword(dev, QPNR, data);
0387     /* 8. Check if firmware send back RF content. */
0388     read_nic_dword(dev, QPNR, &tmp);
0389     while (tmp & 0x80000000) {
0390         /* If FW can not finish RF-R/W for more than ?? times.
0391          * We must reset FW.
0392          */
0393         if (time++ < 100) {
0394             udelay(10);
0395             read_nic_dword(dev, QPNR, &tmp);
0396         } else {
0397             return 0;
0398         }
0399     }
0400     read_nic_dword(dev, RF_DATA, &reg);
0401 
0402     return reg;
0403 }
0404 
0405 /******************************************************************************
0406  * function:  We support firmware to execute RF-R/W.
0407  * input:     net_device        *dev
0408  *            rf90_radio_path_e e_rfpath
0409  *            u32               offset
0410  *            u32               data
0411  * output:    none
0412  * return:    none
0413  * notice:
0414  ****************************************************************************/
0415 static void phy_FwRFSerialWrite(struct net_device *dev,
0416                 enum rf90_radio_path_e e_rfpath,
0417                 u32 offset, u32 data)
0418 {
0419     u8  time = 0;
0420     u32 tmp;
0421 
0422     /* Firmware RF Write control.
0423      * We can not execute the scheme in the initial step.
0424      * Otherwise, RF-R/W will waste much time.
0425      * This is only for site survey.
0426      */
0427 
0428     /* 1. Set driver write bit and 12 bit data. bit 0-11 */
0429     /* 2. Write RF register address. bit 12-19 */
0430     data |= ((offset&0xFF)<<12);
0431     /* 3. Write RF path.  bit 20-21 */
0432     data |= ((e_rfpath&0x3)<<20);
0433     /* 4. Set RF write indicator. bit 22=1 */
0434     data |= 0x400000;
0435     /* 5. Trigger Fw to operate the command. bit 31=1 */
0436     data |= 0x80000000;
0437 
0438     /* 6. Write operation. We can not write if bit 31 is 1. */
0439     read_nic_dword(dev, QPNR, &tmp);
0440     while (tmp & 0x80000000) {
0441         /* If FW can not finish RF-R/W for more than ?? times.
0442          * We must reset FW.
0443          */
0444         if (time++ < 100) {
0445             udelay(10);
0446             read_nic_dword(dev, QPNR, &tmp);
0447         } else {
0448             break;
0449         }
0450     }
0451     /* 7. No matter check bit. We always force the write.
0452      * Because FW will not accept the command.
0453      */
0454     write_nic_dword(dev, QPNR, data);
0455     /* According to test, we must delay 20us to wait firmware
0456      * to finish RF write operation.
0457      */
0458     /* We support delay in firmware side now. */
0459 }
0460 
0461 /******************************************************************************
0462  * function:  This function reads BB parameters from header file we generate,
0463  *            and do register read/write
0464  * input:     net_device    *dev
0465  * output:    none
0466  * return:    none
0467  * notice:    BB parameters may change all the time, so please make
0468  *            sure it has been synced with the newest.
0469  *****************************************************************************/
0470 void rtl8192_phy_configmac(struct net_device *dev)
0471 {
0472     u32 dwArrayLen = 0, i;
0473     u32 *pdwArray = NULL;
0474     struct r8192_priv *priv = ieee80211_priv(dev);
0475 
0476     if (priv->btxpowerdata_readfromEEPORM) {
0477         RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array_PG\n");
0478         dwArrayLen = MACPHY_Array_PGLength;
0479         pdwArray = Rtl8192UsbMACPHY_Array_PG;
0480 
0481     } else {
0482         RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array\n");
0483         dwArrayLen = MACPHY_ArrayLength;
0484         pdwArray = rtl819XMACPHY_Array;
0485     }
0486     for (i = 0; i < dwArrayLen; i = i+3) {
0487         if (pdwArray[i] == 0x318)
0488             pdwArray[i+2] = 0x00000800;
0489 
0490         RT_TRACE(COMP_DBG,
0491              "Rtl8190MACPHY_Array[0]=%x Rtl8190MACPHY_Array[1]=%x Rtl8190MACPHY_Array[2]=%x\n",
0492              pdwArray[i], pdwArray[i+1], pdwArray[i+2]);
0493         rtl8192_setBBreg(dev, pdwArray[i], pdwArray[i+1],
0494                  pdwArray[i+2]);
0495     }
0496 }
0497 
0498 /******************************************************************************
0499  * function:  This function does dirty work
0500  * input:     net_device    *dev
0501  *            u8                ConfigType
0502  * output:    none
0503  * return:    none
0504  * notice:    BB parameters may change all the time, so please make
0505  *            sure it has been synced with the newest.
0506  *****************************************************************************/
0507 static void rtl8192_phyConfigBB(struct net_device *dev,
0508                 enum baseband_config_type ConfigType)
0509 {
0510     u32 i;
0511 
0512     if (ConfigType == BASEBAND_CONFIG_PHY_REG) {
0513         for (i = 0; i < PHY_REG_1T2RArrayLength; i += 2) {
0514             rtl8192_setBBreg(dev, Rtl8192UsbPHY_REG_1T2RArray[i],
0515                      bMaskDWord,
0516                      Rtl8192UsbPHY_REG_1T2RArray[i+1]);
0517             RT_TRACE(COMP_DBG,
0518                  "i: %x, Rtl819xUsbPHY_REGArray[0]=%x Rtl819xUsbPHY_REGArray[1]=%x\n",
0519                  i, Rtl8192UsbPHY_REG_1T2RArray[i],
0520                  Rtl8192UsbPHY_REG_1T2RArray[i+1]);
0521         }
0522     } else if (ConfigType == BASEBAND_CONFIG_AGC_TAB) {
0523         for (i = 0; i < AGCTAB_ArrayLength; i += 2) {
0524             rtl8192_setBBreg(dev, Rtl8192UsbAGCTAB_Array[i],
0525                      bMaskDWord, Rtl8192UsbAGCTAB_Array[i+1]);
0526             RT_TRACE(COMP_DBG,
0527                  "i: %x, Rtl8192UsbAGCTAB_Array[0]=%x Rtl8192UsbAGCTAB_Array[1]=%x\n",
0528                  i, Rtl8192UsbAGCTAB_Array[i],
0529                  Rtl8192UsbAGCTAB_Array[i+1]);
0530         }
0531     }
0532 }
0533 
0534 /******************************************************************************
0535  * function:  This function initializes Register definition offset for
0536  *            Radio Path A/B/C/D
0537  * input:     net_device    *dev
0538  * output:    none
0539  * return:    none
0540  * notice:    Initialization value here is constant and it should never
0541  *            be changed
0542  *****************************************************************************/
0543 static void rtl8192_InitBBRFRegDef(struct net_device *dev)
0544 {
0545     struct r8192_priv *priv = ieee80211_priv(dev);
0546 
0547     /* RF Interface Software Control */
0548     /* 16 LSBs if read 32-bit from 0x870 */
0549     priv->PHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW;
0550     /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */
0551     priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW;
0552     /* 16 LSBs if read 32-bit from 0x874 */
0553     priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;
0554     /* 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) */
0555     priv->PHYRegDef[RF90_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;
0556 
0557     /* RF Interface Readback Value */
0558     /* 16 LSBs if read 32-bit from 0x8E0 */
0559     priv->PHYRegDef[RF90_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB;
0560     /* 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */
0561     priv->PHYRegDef[RF90_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;
0562     /* 16 LSBs if read 32-bit from 0x8E4 */
0563     priv->PHYRegDef[RF90_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;
0564     /* 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) */
0565     priv->PHYRegDef[RF90_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;
0566 
0567     /* RF Interface Output (and Enable) */
0568     /* 16 LSBs if read 32-bit from 0x860 */
0569     priv->PHYRegDef[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE;
0570     /* 16 LSBs if read 32-bit from 0x864 */
0571     priv->PHYRegDef[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE;
0572     /* 16 LSBs if read 32-bit from 0x868 */
0573     priv->PHYRegDef[RF90_PATH_C].rfintfo = rFPGA0_XC_RFInterfaceOE;
0574     /* 16 LSBs if read 32-bit from 0x86C */
0575     priv->PHYRegDef[RF90_PATH_D].rfintfo = rFPGA0_XD_RFInterfaceOE;
0576 
0577     /* RF Interface (Output and) Enable */
0578     /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
0579     priv->PHYRegDef[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE;
0580     /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */
0581     priv->PHYRegDef[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE;
0582     /* 16 MSBs if read 32-bit from 0x86A (16-bit for 0x86A) */
0583     priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE;
0584     /* 16 MSBs if read 32-bit from 0x86C (16-bit for 0x86E) */
0585     priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE;
0586 
0587     /* Addr of LSSI. Write RF register by driver */
0588     priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter;
0589     priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
0590     priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter;
0591     priv->PHYRegDef[RF90_PATH_D].rf3wireOffset = rFPGA0_XD_LSSIParameter;
0592 
0593     /* RF parameter */
0594     /* BB Band Select */
0595     priv->PHYRegDef[RF90_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter;
0596     priv->PHYRegDef[RF90_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter;
0597     priv->PHYRegDef[RF90_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter;
0598     priv->PHYRegDef[RF90_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter;
0599 
0600     /* Tx AGC Gain Stage (same for all path. Should we remove this?) */
0601     priv->PHYRegDef[RF90_PATH_A].rfTxGainStage = rFPGA0_TxGainStage;
0602     priv->PHYRegDef[RF90_PATH_B].rfTxGainStage = rFPGA0_TxGainStage;
0603     priv->PHYRegDef[RF90_PATH_C].rfTxGainStage = rFPGA0_TxGainStage;
0604     priv->PHYRegDef[RF90_PATH_D].rfTxGainStage = rFPGA0_TxGainStage;
0605 
0606     /* Tranceiver A~D HSSI Parameter-1 */
0607     /* wire control parameter1 */
0608     priv->PHYRegDef[RF90_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1;
0609     priv->PHYRegDef[RF90_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1;
0610     priv->PHYRegDef[RF90_PATH_C].rfHSSIPara1 = rFPGA0_XC_HSSIParameter1;
0611     priv->PHYRegDef[RF90_PATH_D].rfHSSIPara1 = rFPGA0_XD_HSSIParameter1;
0612 
0613     /* Tranceiver A~D HSSI Parameter-2 */
0614     /* wire control parameter2 */
0615     priv->PHYRegDef[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2;
0616     priv->PHYRegDef[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2;
0617     priv->PHYRegDef[RF90_PATH_C].rfHSSIPara2 = rFPGA0_XC_HSSIParameter2;
0618     priv->PHYRegDef[RF90_PATH_D].rfHSSIPara2 = rFPGA0_XD_HSSIParameter2;
0619 
0620     /* RF Switch Control */
0621     /* TR/Ant switch control */
0622     priv->PHYRegDef[RF90_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl;
0623     priv->PHYRegDef[RF90_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl;
0624     priv->PHYRegDef[RF90_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl;
0625     priv->PHYRegDef[RF90_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl;
0626 
0627     /* AGC control 1 */
0628     priv->PHYRegDef[RF90_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1;
0629     priv->PHYRegDef[RF90_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1;
0630     priv->PHYRegDef[RF90_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1;
0631     priv->PHYRegDef[RF90_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1;
0632 
0633     /* AGC control 2 */
0634     priv->PHYRegDef[RF90_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2;
0635     priv->PHYRegDef[RF90_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2;
0636     priv->PHYRegDef[RF90_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2;
0637     priv->PHYRegDef[RF90_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2;
0638 
0639     /* RX AFE control 1 */
0640     priv->PHYRegDef[RF90_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance;
0641     priv->PHYRegDef[RF90_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance;
0642     priv->PHYRegDef[RF90_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance;
0643     priv->PHYRegDef[RF90_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance;
0644 
0645     /* RX AFE control 1 */
0646     priv->PHYRegDef[RF90_PATH_A].rfRxAFE = rOFDM0_XARxAFE;
0647     priv->PHYRegDef[RF90_PATH_B].rfRxAFE = rOFDM0_XBRxAFE;
0648     priv->PHYRegDef[RF90_PATH_C].rfRxAFE = rOFDM0_XCRxAFE;
0649     priv->PHYRegDef[RF90_PATH_D].rfRxAFE = rOFDM0_XDRxAFE;
0650 
0651     /* Tx AFE control 1 */
0652     priv->PHYRegDef[RF90_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance;
0653     priv->PHYRegDef[RF90_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance;
0654     priv->PHYRegDef[RF90_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance;
0655     priv->PHYRegDef[RF90_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance;
0656 
0657     /* Tx AFE control 2 */
0658     priv->PHYRegDef[RF90_PATH_A].rfTxAFE = rOFDM0_XATxAFE;
0659     priv->PHYRegDef[RF90_PATH_B].rfTxAFE = rOFDM0_XBTxAFE;
0660     priv->PHYRegDef[RF90_PATH_C].rfTxAFE = rOFDM0_XCTxAFE;
0661     priv->PHYRegDef[RF90_PATH_D].rfTxAFE = rOFDM0_XDTxAFE;
0662 
0663     /* Tranceiver LSSI Readback */
0664     priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
0665     priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
0666     priv->PHYRegDef[RF90_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack;
0667     priv->PHYRegDef[RF90_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack;
0668 }
0669 
0670 /******************************************************************************
0671  * function:  This function is to write register and then readback to make
0672  *            sure whether BB and RF is OK
0673  * input:     net_device        *dev
0674  *            hw90_block_e      CheckBlock
0675  *            rf90_radio_path_e e_rfpath  //only used when checkblock is
0676  *                                       //HW90_BLOCK_RF
0677  * output:    none
0678  * return:    return whether BB and RF is ok (0:OK, 1:Fail)
0679  * notice:    This function may be removed in the ASIC
0680  ******************************************************************************/
0681 u8 rtl8192_phy_checkBBAndRF(struct net_device *dev, enum hw90_block_e CheckBlock,
0682                 enum rf90_radio_path_e e_rfpath)
0683 {
0684     u8 ret = 0;
0685     u32 i, CheckTimes = 4, reg = 0;
0686     u32 WriteAddr[4];
0687     u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f};
0688 
0689     /* Initialize register address offset to be checked */
0690     WriteAddr[HW90_BLOCK_MAC] = 0x100;
0691     WriteAddr[HW90_BLOCK_PHY0] = 0x900;
0692     WriteAddr[HW90_BLOCK_PHY1] = 0x800;
0693     WriteAddr[HW90_BLOCK_RF] = 0x3;
0694     RT_TRACE(COMP_PHY, "%s(), CheckBlock: %d\n", __func__, CheckBlock);
0695     for (i = 0; i < CheckTimes; i++) {
0696         /* Write data to register and readback */
0697         switch (CheckBlock) {
0698         case HW90_BLOCK_MAC:
0699             RT_TRACE(COMP_ERR,
0700                  "PHY_CheckBBRFOK(): Never Write 0x100 here!\n");
0701             break;
0702 
0703         case HW90_BLOCK_PHY0:
0704         case HW90_BLOCK_PHY1:
0705             write_nic_dword(dev, WriteAddr[CheckBlock],
0706                     WriteData[i]);
0707             read_nic_dword(dev, WriteAddr[CheckBlock], &reg);
0708             break;
0709 
0710         case HW90_BLOCK_RF:
0711             WriteData[i] &= 0xfff;
0712             rtl8192_phy_SetRFReg(dev, e_rfpath,
0713                          WriteAddr[HW90_BLOCK_RF],
0714                          bMask12Bits, WriteData[i]);
0715             /* TODO: we should not delay for such a long time.
0716              * Ask SD3
0717              */
0718             usleep_range(1000, 1000);
0719             reg = rtl8192_phy_QueryRFReg(dev, e_rfpath,
0720                              WriteAddr[HW90_BLOCK_RF],
0721                              bMask12Bits);
0722             usleep_range(1000, 1000);
0723             break;
0724 
0725         default:
0726             ret = 1;
0727             break;
0728         }
0729 
0730         /* Check whether readback data is correct */
0731         if (reg != WriteData[i]) {
0732             RT_TRACE((COMP_PHY|COMP_ERR),
0733                  "error reg: %x, WriteData: %x\n",
0734                  reg, WriteData[i]);
0735             ret = 1;
0736             break;
0737         }
0738     }
0739 
0740     return ret;
0741 }
0742 
0743 /******************************************************************************
0744  * function:  This function initializes BB&RF
0745  * input:     net_device    *dev
0746  * output:    none
0747  * return:    none
0748  * notice:    Initialization value may change all the time, so please make
0749  *            sure it has been synced with the newest.
0750  ******************************************************************************/
0751 static void rtl8192_BB_Config_ParaFile(struct net_device *dev)
0752 {
0753     struct r8192_priv *priv = ieee80211_priv(dev);
0754     u8 reg_u8 = 0, eCheckItem = 0, status = 0;
0755     u32 reg_u32 = 0;
0756 
0757     /**************************************
0758      * <1> Initialize BaseBand
0759      *************************************/
0760 
0761     /* --set BB Global Reset-- */
0762     read_nic_byte(dev, BB_GLOBAL_RESET, &reg_u8);
0763     write_nic_byte(dev, BB_GLOBAL_RESET, (reg_u8|BB_GLOBAL_RESET_BIT));
0764     mdelay(50);
0765     /* ---set BB reset Active--- */
0766     read_nic_dword(dev, CPU_GEN, &reg_u32);
0767     write_nic_dword(dev, CPU_GEN, (reg_u32&(~CPU_GEN_BB_RST)));
0768 
0769     /* ----Ckeck FPGAPHY0 and PHY1 board is OK---- */
0770     /* TODO: this function should be removed on ASIC */
0771     for (eCheckItem = (enum hw90_block_e)HW90_BLOCK_PHY0;
0772          eCheckItem <= HW90_BLOCK_PHY1; eCheckItem++) {
0773         /* don't care RF path */
0774         status = rtl8192_phy_checkBBAndRF(dev, (enum hw90_block_e)eCheckItem,
0775                           (enum rf90_radio_path_e)0);
0776         if (status != 0) {
0777             RT_TRACE((COMP_ERR | COMP_PHY),
0778                  "phy_rf8256_config(): Check PHY%d Fail!!\n",
0779                  eCheckItem-1);
0780             return;
0781         }
0782     }
0783     /* ---- Set CCK and OFDM Block "OFF"---- */
0784     rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0);
0785     /* ----BB Register Initilazation---- */
0786     /* ==m==>Set PHY REG From Header<==m== */
0787     rtl8192_phyConfigBB(dev, BASEBAND_CONFIG_PHY_REG);
0788 
0789     /* ----Set BB reset de-Active---- */
0790     read_nic_dword(dev, CPU_GEN, &reg_u32);
0791     write_nic_dword(dev, CPU_GEN, (reg_u32|CPU_GEN_BB_RST));
0792 
0793     /* ----BB AGC table Initialization---- */
0794     /* ==m==>Set PHY REG From Header<==m== */
0795     rtl8192_phyConfigBB(dev, BASEBAND_CONFIG_AGC_TAB);
0796 
0797     /* ----Enable XSTAL ---- */
0798     write_nic_byte_E(dev, 0x5e, 0x00);
0799     if (priv->card_8192_version == VERSION_819XU_A) {
0800         /* Antenna gain offset from B/C/D to A */
0801         reg_u32 = priv->AntennaTxPwDiff[1]<<4 |
0802                priv->AntennaTxPwDiff[0];
0803         rtl8192_setBBreg(dev, rFPGA0_TxGainStage, (bXBTxAGC|bXCTxAGC),
0804                  reg_u32);
0805 
0806         /* XSTALLCap */
0807         reg_u32 = priv->CrystalCap & 0xf;
0808         rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap,
0809                  reg_u32);
0810     }
0811 
0812     /* Check if the CCK HighPower is turned ON.
0813      * This is used to calculate PWDB.
0814      */
0815     priv->bCckHighPower = (u8)rtl8192_QueryBBReg(dev,
0816                              rFPGA0_XA_HSSIParameter2,
0817                              0x200);
0818 }
0819 
0820 /******************************************************************************
0821  * function:  This function initializes BB&RF
0822  * input:     net_device    *dev
0823  * output:    none
0824  * return:    none
0825  * notice:    Initialization value may change all the time, so please make
0826  *            sure it has been synced with the newest.
0827  *****************************************************************************/
0828 void rtl8192_BBConfig(struct net_device *dev)
0829 {
0830     rtl8192_InitBBRFRegDef(dev);
0831     /* config BB&RF. As hardCode based initialization has not been well
0832      * implemented, so use file first.
0833      * FIXME: should implement it for hardcode?
0834      */
0835     rtl8192_BB_Config_ParaFile(dev);
0836 }
0837 
0838 /******************************************************************************
0839  * function:  This function obtains the initialization value of Tx power Level
0840  *            offset
0841  * input:     net_device    *dev
0842  * output:    none
0843  * return:    none
0844  *****************************************************************************/
0845 void rtl8192_phy_getTxPower(struct net_device *dev)
0846 {
0847     struct r8192_priv *priv = ieee80211_priv(dev);
0848     u8 tmp;
0849 
0850     read_nic_dword(dev, rTxAGC_Rate18_06,
0851                &priv->MCSTxPowerLevelOriginalOffset[0]);
0852     read_nic_dword(dev, rTxAGC_Rate54_24,
0853                &priv->MCSTxPowerLevelOriginalOffset[1]);
0854     read_nic_dword(dev, rTxAGC_Mcs03_Mcs00,
0855                &priv->MCSTxPowerLevelOriginalOffset[2]);
0856     read_nic_dword(dev, rTxAGC_Mcs07_Mcs04,
0857                &priv->MCSTxPowerLevelOriginalOffset[3]);
0858     read_nic_dword(dev, rTxAGC_Mcs11_Mcs08,
0859                &priv->MCSTxPowerLevelOriginalOffset[4]);
0860     read_nic_dword(dev, rTxAGC_Mcs15_Mcs12,
0861                &priv->MCSTxPowerLevelOriginalOffset[5]);
0862 
0863     /* Read rx initial gain */
0864     read_nic_byte(dev, rOFDM0_XAAGCCore1, &priv->DefaultInitialGain[0]);
0865     read_nic_byte(dev, rOFDM0_XBAGCCore1, &priv->DefaultInitialGain[1]);
0866     read_nic_byte(dev, rOFDM0_XCAGCCore1, &priv->DefaultInitialGain[2]);
0867     read_nic_byte(dev, rOFDM0_XDAGCCore1, &priv->DefaultInitialGain[3]);
0868     RT_TRACE(COMP_INIT,
0869          "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n",
0870          priv->DefaultInitialGain[0], priv->DefaultInitialGain[1],
0871          priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]);
0872 
0873     /* Read framesync */
0874     read_nic_byte(dev, rOFDM0_RxDetector3, &priv->framesync);
0875     read_nic_byte(dev, rOFDM0_RxDetector2, &tmp);
0876     priv->framesyncC34 = tmp;
0877     RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x\n",
0878         rOFDM0_RxDetector3, priv->framesync);
0879 
0880     /* Read SIFS (save the value read fome MACPHY_REG.txt) */
0881     read_nic_word(dev, SIFS, &priv->SifsTime);
0882 }
0883 
0884 /******************************************************************************
0885  * function:  This function sets the initialization value of Tx power Level
0886  *            offset
0887  * input:     net_device        *dev
0888  *            u8                channel
0889  * output:    none
0890  * return:    none
0891  ******************************************************************************/
0892 void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel)
0893 {
0894     struct r8192_priv *priv = ieee80211_priv(dev);
0895     u8  powerlevel = priv->TxPowerLevelCCK[channel-1];
0896     u8  powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1];
0897 
0898     switch (priv->rf_chip) {
0899     case RF_8256:
0900         /* need further implement */
0901         phy_set_rf8256_cck_tx_power(dev, powerlevel);
0902         phy_set_rf8256_ofdm_tx_power(dev, powerlevelOFDM24G);
0903         break;
0904     default:
0905         RT_TRACE((COMP_PHY|COMP_ERR),
0906              "error RF chipID(8225 or 8258) in function %s()\n",
0907              __func__);
0908         break;
0909     }
0910 }
0911 
0912 /******************************************************************************
0913  * function:  This function checks Rf chip to do RF config
0914  * input:     net_device    *dev
0915  * output:    none
0916  * return:    only 8256 is supported
0917  ******************************************************************************/
0918 void rtl8192_phy_RFConfig(struct net_device *dev)
0919 {
0920     struct r8192_priv *priv = ieee80211_priv(dev);
0921 
0922     switch (priv->rf_chip) {
0923     case RF_8256:
0924         phy_rf8256_config(dev);
0925         break;
0926     default:
0927         RT_TRACE(COMP_ERR, "error chip id\n");
0928         break;
0929     }
0930 }
0931 
0932 /******************************************************************************
0933  * function:  This function updates Initial gain
0934  * input:     net_device    *dev
0935  * output:    none
0936  * return:    As Windows has not implemented this, wait for complement
0937  ******************************************************************************/
0938 void rtl8192_phy_updateInitGain(struct net_device *dev)
0939 {
0940 }
0941 
0942 /******************************************************************************
0943  * function:  This function read RF parameters from general head file,
0944  *            and do RF 3-wire
0945  * input:     net_device    *dev
0946  *            rf90_radio_path_e e_rfpath
0947  * output:    none
0948  * return:    return code show if RF configuration is successful(0:pass, 1:fail)
0949  * notice:    Delay may be required for RF configuration
0950  *****************************************************************************/
0951 u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev,
0952                       enum rf90_radio_path_e    e_rfpath)
0953 {
0954     int i;
0955 
0956     switch (e_rfpath) {
0957     case RF90_PATH_A:
0958         for (i = 0; i < RadioA_ArrayLength; i = i+2) {
0959             if (Rtl8192UsbRadioA_Array[i] == 0xfe) {
0960                 mdelay(100);
0961                 continue;
0962             }
0963             rtl8192_phy_SetRFReg(dev, e_rfpath,
0964                          Rtl8192UsbRadioA_Array[i],
0965                          bMask12Bits,
0966                          Rtl8192UsbRadioA_Array[i+1]);
0967             mdelay(1);
0968         }
0969         break;
0970     case RF90_PATH_B:
0971         for (i = 0; i < RadioB_ArrayLength; i = i+2) {
0972             if (Rtl8192UsbRadioB_Array[i] == 0xfe) {
0973                 mdelay(100);
0974                 continue;
0975             }
0976             rtl8192_phy_SetRFReg(dev, e_rfpath,
0977                          Rtl8192UsbRadioB_Array[i],
0978                          bMask12Bits,
0979                          Rtl8192UsbRadioB_Array[i+1]);
0980             mdelay(1);
0981         }
0982         break;
0983     case RF90_PATH_C:
0984         for (i = 0; i < RadioC_ArrayLength; i = i+2) {
0985             if (Rtl8192UsbRadioC_Array[i] == 0xfe) {
0986                 mdelay(100);
0987                 continue;
0988             }
0989             rtl8192_phy_SetRFReg(dev, e_rfpath,
0990                          Rtl8192UsbRadioC_Array[i],
0991                          bMask12Bits,
0992                          Rtl8192UsbRadioC_Array[i+1]);
0993             mdelay(1);
0994         }
0995         break;
0996     case RF90_PATH_D:
0997         for (i = 0; i < RadioD_ArrayLength; i = i+2) {
0998             if (Rtl8192UsbRadioD_Array[i] == 0xfe) {
0999                 mdelay(100);
1000                 continue;
1001             }
1002             rtl8192_phy_SetRFReg(dev, e_rfpath,
1003                          Rtl8192UsbRadioD_Array[i],
1004                          bMask12Bits,
1005                          Rtl8192UsbRadioD_Array[i+1]);
1006             mdelay(1);
1007         }
1008         break;
1009     default:
1010         break;
1011     }
1012 
1013     return 0;
1014 }
1015 
1016 /******************************************************************************
1017  * function:  This function sets Tx Power of the channel
1018  * input:     net_device        *dev
1019  *            u8                channel
1020  * output:    none
1021  * return:    none
1022  * notice:
1023  ******************************************************************************/
1024 static void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel)
1025 {
1026     struct r8192_priv *priv = ieee80211_priv(dev);
1027     u8  powerlevel = priv->TxPowerLevelCCK[channel-1];
1028     u8  powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1];
1029 
1030     switch (priv->rf_chip) {
1031     case RF_8225:
1032         break;
1033 
1034     case RF_8256:
1035         phy_set_rf8256_cck_tx_power(dev, powerlevel);
1036         phy_set_rf8256_ofdm_tx_power(dev, powerlevelOFDM24G);
1037         break;
1038 
1039     case RF_8258:
1040         break;
1041     default:
1042         RT_TRACE(COMP_ERR, "unknown rf chip ID in %s()\n", __func__);
1043         break;
1044     }
1045 }
1046 
1047 /******************************************************************************
1048  * function:  This function sets RF state on or off
1049  * input:     net_device         *dev
1050  *            RT_RF_POWER_STATE  eRFPowerState  //Power State to set
1051  * output:    none
1052  * return:    none
1053  * notice:
1054  *****************************************************************************/
1055 bool rtl8192_SetRFPowerState(struct net_device *dev,
1056                  RT_RF_POWER_STATE eRFPowerState)
1057 {
1058     bool                bResult = true;
1059     struct r8192_priv *priv = ieee80211_priv(dev);
1060 
1061     if (eRFPowerState == priv->ieee80211->eRFPowerState)
1062         return false;
1063 
1064     if (priv->SetRFPowerStateInProgress)
1065         return false;
1066 
1067     priv->SetRFPowerStateInProgress = true;
1068 
1069     switch (priv->rf_chip) {
1070     case RF_8256:
1071         switch (eRFPowerState) {
1072         case eRfOn:
1073             /* RF-A, RF-B */
1074             /* enable RF-Chip A/B - 0x860[4] */
1075             rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT(4),
1076                      0x1);
1077             /* analog to digital on - 0x88c[9:8] */
1078             rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300,
1079                      0x3);
1080             /* digital to analog on - 0x880[4:3] */
1081             rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18,
1082                      0x3);
1083             /* rx antenna on - 0xc04[1:0] */
1084             rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);
1085             /* rx antenna on - 0xd04[1:0] */
1086             rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);
1087             /* analog to digital part2 on - 0x880[6:5] */
1088             rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60,
1089                      0x3);
1090 
1091             break;
1092 
1093         case eRfSleep:
1094 
1095             break;
1096 
1097         case eRfOff:
1098             /* RF-A, RF-B */
1099             /* disable RF-Chip A/B - 0x860[4] */
1100             rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT(4),
1101                      0x0);
1102             /* analog to digital off, for power save */
1103             rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00,
1104                      0x0); /* 0x88c[11:8] */
1105             /* digital to analog off, for power save - 0x880[4:3] */
1106             rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18,
1107                      0x0);
1108             /* rx antenna off - 0xc04[3:0] */
1109             rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);
1110             /* rx antenna off - 0xd04[3:0] */
1111             rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);
1112             /* analog to digital part2 off, for power save */
1113             rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60,
1114                      0x0); /* 0x880[6:5] */
1115 
1116             break;
1117 
1118         default:
1119             bResult = false;
1120             RT_TRACE(COMP_ERR, "%s(): unknown state to set: 0x%X\n",
1121                  __func__, eRFPowerState);
1122             break;
1123         }
1124         break;
1125     default:
1126         RT_TRACE(COMP_ERR, "Not support rf_chip(%x)\n", priv->rf_chip);
1127         break;
1128     }
1129     priv->SetRFPowerStateInProgress = false;
1130 
1131     return bResult;
1132 }
1133 
1134 /******************************************************************************
1135  * function:  This function sets command table variable (struct sw_chnl_cmd).
1136  * input:     sw_chnl_cmd      *CmdTable    //table to be set
1137  *            u32            CmdTableIdx  //variable index in table to be set
1138  *            u32            CmdTableSz   //table size
1139  *            switch_chan_cmd_id    CmdID        //command ID to set
1140  *            u32            Para1
1141  *            u32            Para2
1142  *            u32            msDelay
1143  * output:
1144  * return:    true if finished, false otherwise
1145  * notice:
1146  ******************************************************************************/
1147 static u8 rtl8192_phy_SetSwChnlCmdArray(struct sw_chnl_cmd *CmdTable, u32 CmdTableIdx,
1148                     u32 CmdTableSz, enum switch_chan_cmd_id CmdID,
1149                     u32 Para1, u32 Para2, u32 msDelay)
1150 {
1151     struct sw_chnl_cmd *pCmd;
1152 
1153     if (!CmdTable) {
1154         RT_TRACE(COMP_ERR, "%s(): CmdTable cannot be NULL\n", __func__);
1155         return false;
1156     }
1157     if (CmdTableIdx >= CmdTableSz) {
1158         RT_TRACE(COMP_ERR, "%s(): Access invalid index, please check size of the table, CmdTableIdx:%d, CmdTableSz:%d\n",
1159              __func__, CmdTableIdx, CmdTableSz);
1160         return false;
1161     }
1162 
1163     pCmd = CmdTable + CmdTableIdx;
1164     pCmd->cmd_id = CmdID;
1165     pCmd->para_1 = Para1;
1166     pCmd->para_2 = Para2;
1167     pCmd->ms_delay = msDelay;
1168 
1169     return true;
1170 }
1171 
1172 /******************************************************************************
1173  * function:  This function sets channel step by step
1174  * input:     net_device        *dev
1175  *            u8                channel
1176  *            u8                *stage   //3 stages
1177  *            u8                *step
1178  *            u32               *delay   //whether need to delay
1179  * output:    store new stage, step and delay for next step
1180  *            (combine with function above)
1181  * return:    true if finished, false otherwise
1182  * notice:    Wait for simpler function to replace it
1183  *****************************************************************************/
1184 static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel,
1185                        u8 *stage, u8 *step, u32 *delay)
1186 {
1187     struct r8192_priv *priv = ieee80211_priv(dev);
1188     struct sw_chnl_cmd *pre_cmd;
1189     u32 pre_cmd_cnt = 0;
1190     struct sw_chnl_cmd *post_cmd;
1191     u32 post_cmd_cnt = 0;
1192     struct sw_chnl_cmd *rf_cmd;
1193     u32 rf_cmd_cnt = 0;
1194     struct sw_chnl_cmd *current_cmd = NULL;
1195     u8 e_rfpath;
1196     bool ret;
1197 
1198     pre_cmd = kcalloc(MAX_PRECMD_CNT, sizeof(*pre_cmd), GFP_KERNEL);
1199     if (!pre_cmd)
1200         return false;
1201 
1202     post_cmd = kcalloc(MAX_POSTCMD_CNT, sizeof(*post_cmd), GFP_KERNEL);
1203     if (!post_cmd) {
1204         kfree(pre_cmd);
1205         return false;
1206     }
1207 
1208     rf_cmd = kcalloc(MAX_RFDEPENDCMD_CNT, sizeof(*rf_cmd), GFP_KERNEL);
1209     if (!rf_cmd) {
1210         kfree(pre_cmd);
1211         kfree(post_cmd);
1212         return false;
1213     }
1214 
1215     RT_TRACE(COMP_CH, "%s() stage: %d, step: %d, channel: %d\n",
1216          __func__, *stage, *step, channel);
1217     if (!is_legal_channel(priv->ieee80211, channel)) {
1218         RT_TRACE(COMP_ERR, "set to illegal channel: %d\n", channel);
1219         /* return true to tell upper caller function this channel
1220          * setting is finished! Or it will in while loop.
1221          */
1222         ret = true;
1223         goto out;
1224     }
1225     /* FIXME: need to check whether channel is legal or not here */
1226 
1227     /* <1> Fill up pre common command. */
1228     rtl8192_phy_SetSwChnlCmdArray(pre_cmd, pre_cmd_cnt++,
1229                       MAX_PRECMD_CNT, CMD_ID_SET_TX_PWR_LEVEL,
1230                       0, 0, 0);
1231     rtl8192_phy_SetSwChnlCmdArray(pre_cmd, pre_cmd_cnt++,
1232                       MAX_PRECMD_CNT, CMD_ID_END, 0, 0, 0);
1233 
1234     /* <2> Fill up post common command. */
1235     rtl8192_phy_SetSwChnlCmdArray(post_cmd, post_cmd_cnt++,
1236                       MAX_POSTCMD_CNT, CMD_ID_END, 0, 0, 0);
1237 
1238     /* <3> Fill up RF dependent command. */
1239     switch (priv->rf_chip) {
1240     case RF_8225:
1241         if (!(channel >= 1 && channel <= 14)) {
1242             RT_TRACE(COMP_ERR,
1243                  "illegal channel for Zebra 8225: %d\n",
1244                  channel);
1245             ret = true;
1246             goto out;
1247         }
1248         rtl8192_phy_SetSwChnlCmdArray(rf_cmd, rf_cmd_cnt++,
1249                           MAX_RFDEPENDCMD_CNT,
1250                           CMD_ID_RF_WRITE_REG,
1251                           rZebra1_Channel,
1252                           RF_CHANNEL_TABLE_ZEBRA[channel],
1253                           10);
1254         rtl8192_phy_SetSwChnlCmdArray(rf_cmd, rf_cmd_cnt++,
1255                           MAX_RFDEPENDCMD_CNT,
1256                           CMD_ID_END, 0, 0, 0);
1257         break;
1258 
1259     case RF_8256:
1260         /* TEST!! This is not the table for 8256!! */
1261         if (!(channel >= 1 && channel <= 14)) {
1262             RT_TRACE(COMP_ERR,
1263                  "illegal channel for Zebra 8256: %d\n",
1264                  channel);
1265             ret = true;
1266             goto out;
1267         }
1268         rtl8192_phy_SetSwChnlCmdArray(rf_cmd, rf_cmd_cnt++,
1269                           MAX_RFDEPENDCMD_CNT,
1270                           CMD_ID_RF_WRITE_REG,
1271                           rZebra1_Channel, channel, 10);
1272         rtl8192_phy_SetSwChnlCmdArray(rf_cmd, rf_cmd_cnt++,
1273                           MAX_RFDEPENDCMD_CNT,
1274                           CMD_ID_END, 0, 0, 0);
1275         break;
1276 
1277     case RF_8258:
1278         break;
1279 
1280     default:
1281         RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip);
1282         ret = true;
1283         goto out;
1284     }
1285 
1286     do {
1287         switch (*stage) {
1288         case 0:
1289             current_cmd = &pre_cmd[*step];
1290             break;
1291         case 1:
1292             current_cmd = &rf_cmd[*step];
1293             break;
1294         case 2:
1295             current_cmd = &post_cmd[*step];
1296             break;
1297         }
1298 
1299         if (current_cmd->cmd_id == CMD_ID_END) {
1300             if ((*stage) == 2) {
1301                 *delay = current_cmd->ms_delay;
1302                 ret = true;
1303                 goto out;
1304             }
1305             (*stage)++;
1306             (*step) = 0;
1307             continue;
1308         }
1309 
1310         switch (current_cmd->cmd_id) {
1311         case CMD_ID_SET_TX_PWR_LEVEL:
1312             if (priv->card_8192_version == VERSION_819XU_A)
1313                 /* consider it later! */
1314                 rtl8192_SetTxPowerLevel(dev, channel);
1315             break;
1316         case CMD_ID_WRITE_PORT_ULONG:
1317             write_nic_dword(dev, current_cmd->para_1,
1318                     current_cmd->para_2);
1319             break;
1320         case CMD_ID_WRITE_PORT_USHORT:
1321             write_nic_word(dev, current_cmd->para_1,
1322                        (u16)current_cmd->para_2);
1323             break;
1324         case CMD_ID_WRITE_PORT_UCHAR:
1325             write_nic_byte(dev, current_cmd->para_1,
1326                        (u8)current_cmd->para_2);
1327             break;
1328         case CMD_ID_RF_WRITE_REG:
1329             for (e_rfpath = 0; e_rfpath < RF90_PATH_MAX; e_rfpath++) {
1330                 rtl8192_phy_SetRFReg(dev,
1331                              (enum rf90_radio_path_e)e_rfpath,
1332                              current_cmd->para_1,
1333                              bZebra1_ChannelNum,
1334                              current_cmd->para_2);
1335             }
1336             break;
1337         default:
1338             break;
1339         }
1340 
1341         break;
1342     } while (true);
1343 
1344     *delay = current_cmd->ms_delay;
1345     (*step)++;
1346     ret = false;
1347 
1348 out:
1349     kfree(pre_cmd);
1350     kfree(post_cmd);
1351     kfree(rf_cmd);
1352 
1353     return ret;
1354 }
1355 
1356 /******************************************************************************
1357  * function:  This function does actually set channel work
1358  * input:     net_device        *dev
1359  *            u8                channel
1360  * output:    none
1361  * return:    none
1362  * notice:    We should not call this function directly
1363  *****************************************************************************/
1364 static void rtl8192_phy_FinishSwChnlNow(struct net_device *dev, u8 channel)
1365 {
1366     struct r8192_priv *priv = ieee80211_priv(dev);
1367     u32 delay = 0;
1368 
1369     while (!rtl8192_phy_SwChnlStepByStep(dev, channel, &priv->SwChnlStage,
1370                          &priv->SwChnlStep, &delay)) {
1371         if (!priv->up)
1372             break;
1373     }
1374 }
1375 
1376 /******************************************************************************
1377  * function:  Callback routine of the work item for switch channel.
1378  * input:     net_device    *dev
1379  *
1380  * output:    none
1381  * return:    none
1382  *****************************************************************************/
1383 void rtl8192_SwChnl_WorkItem(struct net_device *dev)
1384 {
1385     struct r8192_priv *priv = ieee80211_priv(dev);
1386 
1387     RT_TRACE(COMP_CH, "==> SwChnlCallback819xUsbWorkItem(), chan:%d\n",
1388          priv->chan);
1389 
1390     rtl8192_phy_FinishSwChnlNow(dev, priv->chan);
1391 
1392     RT_TRACE(COMP_CH, "<== SwChnlCallback819xUsbWorkItem()\n");
1393 }
1394 
1395 /******************************************************************************
1396  * function:  This function scheduled actual work item to set channel
1397  * input:     net_device        *dev
1398  *            u8                channel   //channel to set
1399  * output:    none
1400  * return:    return code show if workitem is scheduled (1:pass, 0:fail)
1401  * notice:    Delay may be required for RF configuration
1402  ******************************************************************************/
1403 u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel)
1404 {
1405     struct r8192_priv *priv = ieee80211_priv(dev);
1406 
1407     RT_TRACE(COMP_CH, "%s(), SwChnlInProgress: %d\n", __func__,
1408          priv->SwChnlInProgress);
1409     if (!priv->up)
1410         return false;
1411     if (priv->SwChnlInProgress)
1412         return false;
1413 
1414     /* -------------------------------------------- */
1415     switch (priv->ieee80211->mode) {
1416     case WIRELESS_MODE_A:
1417     case WIRELESS_MODE_N_5G:
1418         if (channel <= 14) {
1419             RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14\n");
1420             return false;
1421         }
1422         break;
1423     case WIRELESS_MODE_B:
1424         if (channel > 14) {
1425             RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14\n");
1426             return false;
1427         }
1428         break;
1429     case WIRELESS_MODE_G:
1430     case WIRELESS_MODE_N_24G:
1431         if (channel > 14) {
1432             RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14\n");
1433             return false;
1434         }
1435         break;
1436     }
1437     /* -------------------------------------------- */
1438 
1439     priv->SwChnlInProgress = true;
1440     if (channel == 0)
1441         channel = 1;
1442 
1443     priv->chan = channel;
1444 
1445     priv->SwChnlStage = 0;
1446     priv->SwChnlStep = 0;
1447     if (priv->up)
1448         rtl8192_SwChnl_WorkItem(dev);
1449 
1450     priv->SwChnlInProgress = false;
1451     return true;
1452 }
1453 
1454 /******************************************************************************
1455  * function:  Callback routine of the work item for set bandwidth mode.
1456  * input:     net_device     *dev
1457  * output:    none
1458  * return:    none
1459  * notice:    I doubt whether SetBWModeInProgress flag is necessary as we can
1460  *            test whether current work in the queue or not.//do I?
1461  *****************************************************************************/
1462 void rtl8192_SetBWModeWorkItem(struct net_device *dev)
1463 {
1464     struct r8192_priv *priv = ieee80211_priv(dev);
1465     u8 regBwOpMode;
1466 
1467     RT_TRACE(COMP_SWBW, "%s()  Switch to %s bandwidth\n", __func__,
1468          priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz");
1469 
1470     if (priv->rf_chip == RF_PSEUDO_11N) {
1471         priv->SetBWModeInProgress = false;
1472         return;
1473     }
1474 
1475     /* <1> Set MAC register */
1476     read_nic_byte(dev, BW_OPMODE, &regBwOpMode);
1477 
1478     switch (priv->CurrentChannelBW) {
1479     case HT_CHANNEL_WIDTH_20:
1480         regBwOpMode |= BW_OPMODE_20MHZ;
1481         /* We have not verify whether this register works */
1482         write_nic_byte(dev, BW_OPMODE, regBwOpMode);
1483         break;
1484 
1485     case HT_CHANNEL_WIDTH_20_40:
1486         regBwOpMode &= ~BW_OPMODE_20MHZ;
1487         /* We have not verify whether this register works */
1488         write_nic_byte(dev, BW_OPMODE, regBwOpMode);
1489         break;
1490 
1491     default:
1492         RT_TRACE(COMP_ERR,
1493              "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n",
1494              priv->CurrentChannelBW);
1495         break;
1496     }
1497 
1498     /* <2> Set PHY related register */
1499     switch (priv->CurrentChannelBW) {
1500     case HT_CHANNEL_WIDTH_20:
1501         rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
1502         rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
1503         rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1,
1504                  0x00100000, 1);
1505 
1506         /* Correct the tx power for CCK rate in 20M. */
1507         priv->cck_present_attenuation =
1508             priv->cck_present_attenuation_20Mdefault +
1509             priv->cck_present_attenuation_difference;
1510 
1511         if (priv->cck_present_attenuation > 22)
1512             priv->cck_present_attenuation = 22;
1513         if (priv->cck_present_attenuation < 0)
1514             priv->cck_present_attenuation = 0;
1515         RT_TRACE(COMP_INIT,
1516              "20M, pHalData->CCKPresentAttentuation = %d\n",
1517              priv->cck_present_attenuation);
1518 
1519         if (priv->chan == 14 && !priv->bcck_in_ch14) {
1520             priv->bcck_in_ch14 = true;
1521             dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1522         } else if (priv->chan != 14 && priv->bcck_in_ch14) {
1523             priv->bcck_in_ch14 = false;
1524             dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1525         } else {
1526             dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1527         }
1528 
1529         break;
1530     case HT_CHANNEL_WIDTH_20_40:
1531         rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
1532         rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
1533         rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand,
1534                  priv->nCur40MhzPrimeSC >> 1);
1535         rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0);
1536         rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00,
1537                  priv->nCur40MhzPrimeSC);
1538         priv->cck_present_attenuation =
1539             priv->cck_present_attenuation_40Mdefault +
1540             priv->cck_present_attenuation_difference;
1541 
1542         if (priv->cck_present_attenuation > 22)
1543             priv->cck_present_attenuation = 22;
1544         if (priv->cck_present_attenuation < 0)
1545             priv->cck_present_attenuation = 0;
1546 
1547         RT_TRACE(COMP_INIT,
1548              "40M, pHalData->CCKPresentAttentuation = %d\n",
1549              priv->cck_present_attenuation);
1550         if (priv->chan == 14 && !priv->bcck_in_ch14) {
1551             priv->bcck_in_ch14 = true;
1552             dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1553         } else if (priv->chan != 14 && priv->bcck_in_ch14) {
1554             priv->bcck_in_ch14 = false;
1555             dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1556         } else {
1557             dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1558         }
1559 
1560         break;
1561     default:
1562         RT_TRACE(COMP_ERR,
1563              "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n",
1564              priv->CurrentChannelBW);
1565         break;
1566     }
1567     /* Skip over setting of J-mode in BB register here.
1568      * Default value is "None J mode".
1569      */
1570 
1571     /* <3> Set RF related register */
1572     switch (priv->rf_chip) {
1573     case RF_8225:
1574         break;
1575 
1576     case RF_8256:
1577         phy_set_rf8256_bandwidth(dev, priv->CurrentChannelBW);
1578         break;
1579 
1580     case RF_8258:
1581         break;
1582 
1583     case RF_PSEUDO_11N:
1584         break;
1585 
1586     default:
1587         RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip);
1588         break;
1589     }
1590     priv->SetBWModeInProgress = false;
1591 
1592     RT_TRACE(COMP_SWBW, "<==SetBWMode819xUsb(), %d\n",
1593          atomic_read(&priv->ieee80211->atm_swbw));
1594 }
1595 
1596 /******************************************************************************
1597  * function:  This function schedules bandwidth switch work.
1598  * input:     struct net_deviceq   *dev
1599  *            HT_CHANNEL_WIDTH     bandwidth  //20M or 40M
1600  *            HT_EXTCHNL_OFFSET    offset     //Upper, Lower, or Don't care
1601  * output:    none
1602  * return:    none
1603  * notice:    I doubt whether SetBWModeInProgress flag is necessary as we can
1604  *        test whether current work in the queue or not.//do I?
1605  *****************************************************************************/
1606 void rtl8192_SetBWMode(struct net_device *dev,
1607                enum ht_channel_width bandwidth,
1608                enum ht_extension_chan_offset offset)
1609 {
1610     struct r8192_priv *priv = ieee80211_priv(dev);
1611 
1612     if (priv->SetBWModeInProgress)
1613         return;
1614     priv->SetBWModeInProgress = true;
1615 
1616     priv->CurrentChannelBW = bandwidth;
1617 
1618     if (offset == HT_EXTCHNL_OFFSET_LOWER)
1619         priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER;
1620     else if (offset == HT_EXTCHNL_OFFSET_UPPER)
1621         priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER;
1622     else
1623         priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1624 
1625     rtl8192_SetBWModeWorkItem(dev);
1626 }
1627 
1628 void InitialGain819xUsb(struct net_device *dev, u8 Operation)
1629 {
1630     struct r8192_priv *priv = ieee80211_priv(dev);
1631 
1632     priv->InitialGainOperateType = Operation;
1633 
1634     if (priv->up)
1635         queue_delayed_work(priv->priv_wq, &priv->initialgain_operate_wq, 0);
1636 }
1637 
1638 void InitialGainOperateWorkItemCallBack(struct work_struct *work)
1639 {
1640     struct delayed_work *dwork = to_delayed_work(work);
1641     struct r8192_priv *priv = container_of(dwork, struct r8192_priv,
1642                            initialgain_operate_wq);
1643     struct net_device *dev = priv->ieee80211->dev;
1644 #define SCAN_RX_INITIAL_GAIN    0x17
1645 #define POWER_DETECTION_TH  0x08
1646     u32 bitmask;
1647     u8  initial_gain;
1648     u8  Operation;
1649 
1650     Operation = priv->InitialGainOperateType;
1651 
1652     switch (Operation) {
1653     case IG_Backup:
1654         RT_TRACE(COMP_SCAN, "IG_Backup, backup the initial gain.\n");
1655         initial_gain = SCAN_RX_INITIAL_GAIN;
1656         bitmask = bMaskByte0;
1657         if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1658             /* FW DIG OFF */
1659             rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
1660         priv->initgain_backup.xaagccore1 =
1661             (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bitmask);
1662         priv->initgain_backup.xbagccore1 =
1663             (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bitmask);
1664         priv->initgain_backup.xcagccore1 =
1665             (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bitmask);
1666         priv->initgain_backup.xdagccore1 =
1667             (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bitmask);
1668         bitmask = bMaskByte2;
1669         priv->initgain_backup.cca =
1670             (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bitmask);
1671 
1672         RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc50 is %x\n",
1673              priv->initgain_backup.xaagccore1);
1674         RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc58 is %x\n",
1675              priv->initgain_backup.xbagccore1);
1676         RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc60 is %x\n",
1677              priv->initgain_backup.xcagccore1);
1678         RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc68 is %x\n",
1679              priv->initgain_backup.xdagccore1);
1680         RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xa0a is %x\n",
1681              priv->initgain_backup.cca);
1682 
1683         RT_TRACE(COMP_SCAN, "Write scan initial gain = 0x%x\n",
1684              initial_gain);
1685         write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
1686         write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
1687         write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
1688         write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
1689         RT_TRACE(COMP_SCAN, "Write scan 0xa0a = 0x%x\n",
1690              POWER_DETECTION_TH);
1691         write_nic_byte(dev, 0xa0a, POWER_DETECTION_TH);
1692         break;
1693     case IG_Restore:
1694         RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial gain.\n");
1695         bitmask = 0x7f; /* Bit0 ~ Bit6 */
1696         if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1697             /* FW DIG OFF */
1698             rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
1699 
1700         rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bitmask,
1701                  (u32)priv->initgain_backup.xaagccore1);
1702         rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bitmask,
1703                  (u32)priv->initgain_backup.xbagccore1);
1704         rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bitmask,
1705                  (u32)priv->initgain_backup.xcagccore1);
1706         rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bitmask,
1707                  (u32)priv->initgain_backup.xdagccore1);
1708         bitmask  = bMaskByte2;
1709         rtl8192_setBBreg(dev, rCCK0_CCA, bitmask,
1710                  (u32)priv->initgain_backup.cca);
1711 
1712         RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc50 is %x\n",
1713              priv->initgain_backup.xaagccore1);
1714         RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc58 is %x\n",
1715              priv->initgain_backup.xbagccore1);
1716         RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc60 is %x\n",
1717              priv->initgain_backup.xcagccore1);
1718         RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc68 is %x\n",
1719              priv->initgain_backup.xdagccore1);
1720         RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n",
1721              priv->initgain_backup.cca);
1722 
1723         rtl8192_phy_setTxPower(dev, priv->ieee80211->current_network.channel);
1724 
1725         if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1726             /* FW DIG ON */
1727             rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);
1728         break;
1729     default:
1730         RT_TRACE(COMP_SCAN, "Unknown IG Operation.\n");
1731         break;
1732     }
1733 }