blob: 387d137ec9ffacbb9282396abe278b9f93b8fc4c [file] [log] [blame]
Jerry Chuang8fc85982009-11-03 07:17:11 -02001#include "r8192U.h"
2#include "r8192U_hw.h"
3#include "r819xU_phy.h"
4#include "r819xU_phyreg.h"
5#include "r8190_rtl8256.h"
6#include "r8192U_dm.h"
7#include "r819xU_firmware_img.h"
8
Jerry Chuang8fc85982009-11-03 07:17:11 -02009#include "dot11d.h"
Xenia Ragiadakou391c72a2013-06-15 07:29:01 +030010#include <linux/bitops.h>
11
Jerry Chuang8fc85982009-11-03 07:17:11 -020012static u32 RF_CHANNEL_TABLE_ZEBRA[] = {
13 0,
14 0x085c, //2412 1
15 0x08dc, //2417 2
16 0x095c, //2422 3
17 0x09dc, //2427 4
18 0x0a5c, //2432 5
19 0x0adc, //2437 6
20 0x0b5c, //2442 7
21 0x0bdc, //2447 8
22 0x0c5c, //2452 9
23 0x0cdc, //2457 10
24 0x0d5c, //2462 11
25 0x0ddc, //2467 12
26 0x0e5c, //2472 13
27 0x0f72, //2484
28};
29
30
31#define rtl819XPHY_REG_1T2RArray Rtl8192UsbPHY_REG_1T2RArray
32#define rtl819XMACPHY_Array_PG Rtl8192UsbMACPHY_Array_PG
33#define rtl819XMACPHY_Array Rtl8192UsbMACPHY_Array
34#define rtl819XRadioA_Array Rtl8192UsbRadioA_Array
35#define rtl819XRadioB_Array Rtl8192UsbRadioB_Array
36#define rtl819XRadioC_Array Rtl8192UsbRadioC_Array
37#define rtl819XRadioD_Array Rtl8192UsbRadioD_Array
38#define rtl819XAGCTAB_Array Rtl8192UsbAGCTAB_Array
39
40/******************************************************************************
41 *function: This function read BB parameters from Header file we gen,
42 * and do register read/write
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +030043 * input: u32 bitmask //taget bit pos in the addr to be modified
Jerry Chuang8fc85982009-11-03 07:17:11 -020044 * output: none
Justin P. Mattock589b3d02012-04-30 07:41:36 -070045 * return: u32 return the shift bit position of the mask
Jerry Chuang8fc85982009-11-03 07:17:11 -020046 * ****************************************************************************/
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +030047u32 rtl8192_CalculateBitShift(u32 bitmask)
Jerry Chuang8fc85982009-11-03 07:17:11 -020048{
49 u32 i;
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +030050 i = ffs(bitmask) - 1;
Jerry Chuang8fc85982009-11-03 07:17:11 -020051 return i;
52}
53/******************************************************************************
54 *function: This function check different RF type to execute legal judgement. If RF Path is illegal, we will return false.
55 * input: none
56 * output: none
57 * return: 0(illegal, false), 1(legal,true)
58 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +030059u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, u32 eRFPath)
Jerry Chuang8fc85982009-11-03 07:17:11 -020060{
61 u8 ret = 1;
62 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +030063 if (priv->rf_type == RF_2T4R) {
Jerry Chuang8fc85982009-11-03 07:17:11 -020064 ret = 0;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +030065 } else if (priv->rf_type == RF_1T2R) {
Jerry Chuang8fc85982009-11-03 07:17:11 -020066 if (eRFPath == RF90_PATH_A || eRFPath == RF90_PATH_B)
67 ret = 1;
68 else if (eRFPath == RF90_PATH_C || eRFPath == RF90_PATH_D)
69 ret = 0;
70 }
71 return ret;
72}
73/******************************************************************************
74 *function: This function set specific bits to BB register
75 * input: net_device dev
Xenia Ragiadakou79931632013-06-18 05:29:41 +030076 * u32 reg_addr //target addr to be modified
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +030077 * u32 bitmask //taget bit pos in the addr to be modified
Xenia Ragiadakou79931632013-06-18 05:29:41 +030078 * u32 data //value to be write
Jerry Chuang8fc85982009-11-03 07:17:11 -020079 * output: none
80 * return: none
81 * notice:
82 * ****************************************************************************/
Xenia Ragiadakou79931632013-06-18 05:29:41 +030083void rtl8192_setBBreg(struct net_device *dev, u32 reg_addr, u32 bitmask,
84 u32 data)
Jerry Chuang8fc85982009-11-03 07:17:11 -020085{
86
Xenia Ragiadakou79931632013-06-18 05:29:41 +030087 u32 reg, bitshift;
Jerry Chuang8fc85982009-11-03 07:17:11 -020088
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +030089 if (bitmask != bMaskDWord) { //if not "double word" write
Xenia Ragiadakou79931632013-06-18 05:29:41 +030090 read_nic_dword(dev, reg_addr, &reg);
91 bitshift = rtl8192_CalculateBitShift(bitmask);
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +030092 reg &= ~bitmask;
Xenia Ragiadakou79931632013-06-18 05:29:41 +030093 reg |= data << bitshift;
94 write_nic_dword(dev, reg_addr, reg);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +030095 } else {
Xenia Ragiadakou79931632013-06-18 05:29:41 +030096 write_nic_dword(dev, reg_addr, data);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +030097 }
Jerry Chuang8fc85982009-11-03 07:17:11 -020098 return;
99}
100/******************************************************************************
101 *function: This function reads specific bits from BB register
102 * input: net_device dev
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300103 * u32 reg_addr //target addr to be readback
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +0300104 * u32 bitmask //taget bit pos in the addr to be readback
Jerry Chuang8fc85982009-11-03 07:17:11 -0200105 * output: none
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300106 * return: u32 data //the readback register value
Jerry Chuang8fc85982009-11-03 07:17:11 -0200107 * notice:
108 * ****************************************************************************/
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300109u32 rtl8192_QueryBBReg(struct net_device *dev, u32 reg_addr, u32 bitmask)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200110{
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300111 u32 Ret = 0, reg, bitshift;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200112
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300113 read_nic_dword(dev, reg_addr, &reg);
114 bitshift = rtl8192_CalculateBitShift(bitmask);
115 Ret = (reg & bitmask) >> bitshift;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200116
Xenia Ragiadakou4c8dd922013-06-15 07:29:03 +0300117 return Ret;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200118}
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300119static u32 phy_FwRFSerialRead(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300120 u32 offset);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200121
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300122static void phy_FwRFSerialWrite(struct net_device *dev,
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300123 RF90_RADIO_PATH_E eRFPath, u32 offset,
124 u32 data);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200125
126/******************************************************************************
127 *function: This function read register from RF chip
128 * input: net_device dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100129 * RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300130 * u32 offset //target address to be read
Jerry Chuang8fc85982009-11-03 07:17:11 -0200131 * output: none
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100132 * return: u32 readback value
Jerry Chuang8fc85982009-11-03 07:17:11 -0200133 * notice: There are three types of serial operations:(1) Software serial write.(2)Hardware LSSI-Low Speed Serial Interface.(3)Hardware HSSI-High speed serial write. Driver here need to implement (1) and (2)---need more spec for this information.
134 * ****************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300135u32 rtl8192_phy_RFSerialRead(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300136 u32 offset)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200137{
138 struct r8192_priv *priv = ieee80211_priv(dev);
139 u32 ret = 0;
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300140 u32 new_offset = 0;
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300141 BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath];
Jerry Chuang8fc85982009-11-03 07:17:11 -0200142 rtl8192_setBBreg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData, 0);
143 //make sure RF register offset is correct
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300144 offset &= 0x3f;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200145
146 //switch page for 8256 RF IC
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300147 if (priv->rf_chip == RF_8256) {
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300148 if (offset >= 31) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200149 priv->RfReg0Value[eRFPath] |= 0x140;
150 //Switch to Reg_Mode2 for Reg 31-45
Xenia Ragiadakouceb56592013-06-15 07:29:07 +0300151 rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16));
Jerry Chuang8fc85982009-11-03 07:17:11 -0200152 //modify offset
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300153 new_offset = offset - 30;
154 } else if (offset >= 16) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200155 priv->RfReg0Value[eRFPath] |= 0x100;
156 priv->RfReg0Value[eRFPath] &= (~0x40);
157 //Switch to Reg_Mode 1 for Reg16-30
Xenia Ragiadakouceb56592013-06-15 07:29:07 +0300158 rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16));
Jerry Chuang8fc85982009-11-03 07:17:11 -0200159
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300160 new_offset = offset - 15;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300161 } else {
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300162 new_offset = offset;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300163 }
164 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200165 RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be 8256\n");
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300166 new_offset = offset;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200167 }
168 //put desired read addr to LSSI control Register
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300169 rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress, new_offset);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200170 //Issue a posedge trigger
171 //
172 rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x0);
173 rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x1);
174
175
Justin P. Mattock8ef3a7e2012-04-30 14:39:21 -0700176 // TODO: we should not delay such a long time. Ask for help from SD3
Jerry Chuang8fc85982009-11-03 07:17:11 -0200177 msleep(1);
178
179 ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData);
180
181
182 // Switch back to Reg_Mode0;
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300183 if (priv->rf_chip == RF_8256) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200184 priv->RfReg0Value[eRFPath] &= 0xebf;
185
186 rtl8192_setBBreg(
187 dev,
188 pPhyReg->rf3wireOffset,
189 bMaskDWord,
190 (priv->RfReg0Value[eRFPath] << 16));
191 }
192
193 return ret;
194
195}
196
197/******************************************************************************
198 *function: This function write data to RF register
199 * input: net_device dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100200 * RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300201 * u32 offset //target address to be written
202 * u32 data //The new register data to be written
Jerry Chuang8fc85982009-11-03 07:17:11 -0200203 * output: none
204 * return: none
205 * notice: For RF8256 only.
206 ===========================================================
207 *Reg Mode RegCTL[1] RegCTL[0] Note
208 * (Reg00[12]) (Reg00[10])
209 *===========================================================
210 *Reg_Mode0 0 x Reg 0 ~15(0x0 ~ 0xf)
211 *------------------------------------------------------------------
212 *Reg_Mode1 1 0 Reg 16 ~30(0x1 ~ 0xf)
213 *------------------------------------------------------------------
214 * Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf)
215 *------------------------------------------------------------------
216 * ****************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300217void rtl8192_phy_RFSerialWrite(struct net_device *dev,
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300218 RF90_RADIO_PATH_E eRFPath, u32 offset, u32 data)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200219{
220 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300221 u32 DataAndAddr = 0, new_offset = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200222 BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath];
223
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300224 offset &= 0x3f;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300225 if (priv->rf_chip == RF_8256) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200226
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300227 if (offset >= 31) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200228 priv->RfReg0Value[eRFPath] |= 0x140;
229 rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath] << 16));
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300230 new_offset = offset - 30;
231 } else if (offset >= 16) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200232 priv->RfReg0Value[eRFPath] |= 0x100;
233 priv->RfReg0Value[eRFPath] &= (~0x40);
234 rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16));
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300235 new_offset = offset - 15;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300236 } else {
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300237 new_offset = offset;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300238 }
239 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200240 RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be 8256\n");
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300241 new_offset = offset;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200242 }
243
Justin P. Mattock589b3d02012-04-30 07:41:36 -0700244 // Put write addr in [5:0] and write data in [31:16]
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300245 DataAndAddr = (data<<16) | (new_offset&0x3f);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200246
247 // Write Operation
248 rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
249
250
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300251 if (offset == 0x0)
252 priv->RfReg0Value[eRFPath] = data;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200253
254 // Switch back to Reg_Mode0;
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300255 if (priv->rf_chip == RF_8256) {
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300256 if (offset != 0) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200257 priv->RfReg0Value[eRFPath] &= 0xebf;
258 rtl8192_setBBreg(
259 dev,
260 pPhyReg->rf3wireOffset,
261 bMaskDWord,
262 (priv->RfReg0Value[eRFPath] << 16));
263 }
264 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200265 return;
266}
267
268/******************************************************************************
269 *function: This function set specific bits to RF register
270 * input: net_device dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100271 * RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300272 * u32 reg_addr //target addr to be modified
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +0300273 * u32 bitmask //taget bit pos in the addr to be modified
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300274 * u32 data //value to be write
Jerry Chuang8fc85982009-11-03 07:17:11 -0200275 * output: none
276 * return: none
277 * notice:
278 * ****************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300279void rtl8192_phy_SetRFReg(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300280 u32 reg_addr, u32 bitmask, u32 data)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200281{
282 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300283 u32 reg, bitshift;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200284
285 if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
286 return;
287
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300288 if (priv->Rf_Mode == RF_OP_By_FW) {
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +0300289 if (bitmask != bMask12Bits) { // RF data is 12 bits only
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300290 reg = phy_FwRFSerialRead(dev, eRFPath, reg_addr);
291 bitshift = rtl8192_CalculateBitShift(bitmask);
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +0300292 reg &= ~bitmask;
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300293 reg |= data << bitshift;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200294
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300295 phy_FwRFSerialWrite(dev, eRFPath, reg_addr, reg);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300296 } else {
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300297 phy_FwRFSerialWrite(dev, eRFPath, reg_addr, data);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300298 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200299
300 udelay(200);
301
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300302 } else {
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +0300303 if (bitmask != bMask12Bits) { // RF data is 12 bits only
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300304 reg = rtl8192_phy_RFSerialRead(dev, eRFPath, reg_addr);
305 bitshift = rtl8192_CalculateBitShift(bitmask);
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +0300306 reg &= ~bitmask;
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300307 reg |= data << bitshift;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200308
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300309 rtl8192_phy_RFSerialWrite(dev, eRFPath, reg_addr, reg);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300310 } else {
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300311 rtl8192_phy_RFSerialWrite(dev, eRFPath, reg_addr, data);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300312 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200313 }
314 return;
315}
316
317/******************************************************************************
318 *function: This function reads specific bits from RF register
319 * input: net_device dev
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300320 * u32 reg_addr //target addr to be readback
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +0300321 * u32 bitmask //taget bit pos in the addr to be readback
Jerry Chuang8fc85982009-11-03 07:17:11 -0200322 * output: none
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300323 * return: u32 data //the readback register value
Jerry Chuang8fc85982009-11-03 07:17:11 -0200324 * notice:
325 * ****************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300326u32 rtl8192_phy_QueryRFReg(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300327 u32 reg_addr, u32 bitmask)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200328{
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300329 u32 reg, bitshift;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200330 struct r8192_priv *priv = ieee80211_priv(dev);
331
332
333 if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
334 return 0;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300335 if (priv->Rf_Mode == RF_OP_By_FW) {
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300336 reg = phy_FwRFSerialRead(dev, eRFPath, reg_addr);
337 bitshift = rtl8192_CalculateBitShift(bitmask);
338 reg = (reg & bitmask) >> bitshift;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200339 udelay(200);
Xenia Ragiadakou07ecbbf2013-06-18 05:29:39 +0300340 return reg;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300341 } else {
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300342 reg = rtl8192_phy_RFSerialRead(dev, eRFPath, reg_addr);
343 bitshift = rtl8192_CalculateBitShift(bitmask);
344 reg = (reg & bitmask) >> bitshift;
Xenia Ragiadakou07ecbbf2013-06-18 05:29:39 +0300345 return reg;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200346 }
347}
348/******************************************************************************
349 *function: We support firmware to execute RF-R/W.
350 * input: dev
351 * output: none
352 * return: none
353 * notice:
354 * ***************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300355static u32 phy_FwRFSerialRead(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300356 u32 offset)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200357{
Xenia Ragiadakou07ecbbf2013-06-18 05:29:39 +0300358 u32 reg = 0;
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300359 u32 data = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200360 u8 time = 0;
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300361 u32 tmp;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200362 /* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can
363 not execute the scheme in the initial step. Otherwise, RF-R/W will waste
364 much time. This is only for site survey. */
365 // 1. Read operation need not insert data. bit 0-11
Jerry Chuang8fc85982009-11-03 07:17:11 -0200366 // 2. Write RF register address. Bit 12-19
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300367 data |= ((offset&0xFF)<<12);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200368 // 3. Write RF path. bit 20-21
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300369 data |= ((eRFPath&0x3)<<20);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200370 // 4. Set RF read indicator. bit 22=0
Jerry Chuang8fc85982009-11-03 07:17:11 -0200371 // 5. Trigger Fw to operate the command. bit 31
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300372 data |= 0x80000000;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200373 // 6. We can not execute read operation if bit 31 is 1.
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300374 read_nic_dword(dev, QPNR, &tmp);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300375 while (tmp & 0x80000000) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200376 // If FW can not finish RF-R/W for more than ?? times. We must reset FW.
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300377 if (time++ < 100) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200378 udelay(10);
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300379 read_nic_dword(dev, QPNR, &tmp);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300380 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200381 break;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300382 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200383 }
384 // 7. Execute read operation.
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300385 write_nic_dword(dev, QPNR, data);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200386 // 8. Check if firmawre send back RF content.
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300387 read_nic_dword(dev, QPNR, &tmp);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300388 while (tmp & 0x80000000) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200389 // If FW can not finish RF-R/W for more than ?? times. We must reset FW.
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300390 if (time++ < 100) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200391 udelay(10);
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300392 read_nic_dword(dev, QPNR, &tmp);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300393 } else {
Xenia Ragiadakou4c8dd922013-06-15 07:29:03 +0300394 return 0;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300395 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200396 }
Xenia Ragiadakou07ecbbf2013-06-18 05:29:39 +0300397 read_nic_dword(dev, RF_DATA, &reg);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200398
Xenia Ragiadakou07ecbbf2013-06-18 05:29:39 +0300399 return reg;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200400
401} /* phy_FwRFSerialRead */
402
403/******************************************************************************
404 *function: We support firmware to execute RF-R/W.
405 * input: dev
406 * output: none
407 * return: none
408 * notice:
409 * ***************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300410static void phy_FwRFSerialWrite(struct net_device *dev,
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300411 RF90_RADIO_PATH_E eRFPath, u32 offset, u32 data)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200412{
413 u8 time = 0;
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300414 u32 tmp;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200415
Jerry Chuang8fc85982009-11-03 07:17:11 -0200416 /* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can
417 not execute the scheme in the initial step. Otherwise, RF-R/W will waste
418 much time. This is only for site survey. */
419
420 // 1. Set driver write bit and 12 bit data. bit 0-11
Jerry Chuang8fc85982009-11-03 07:17:11 -0200421 // 2. Write RF register address. bit 12-19
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300422 data |= ((offset&0xFF)<<12);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200423 // 3. Write RF path. bit 20-21
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300424 data |= ((eRFPath&0x3)<<20);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200425 // 4. Set RF write indicator. bit 22=1
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300426 data |= 0x400000;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200427 // 5. Trigger Fw to operate the command. bit 31=1
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300428 data |= 0x80000000;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200429
430 // 6. Write operation. We can not write if bit 31 is 1.
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300431 read_nic_dword(dev, QPNR, &tmp);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300432 while (tmp & 0x80000000) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200433 // If FW can not finish RF-R/W for more than ?? times. We must reset FW.
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300434 if (time++ < 100) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200435 udelay(10);
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300436 read_nic_dword(dev, QPNR, &tmp);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300437 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200438 break;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300439 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200440 }
441 // 7. No matter check bit. We always force the write. Because FW will
442 // not accept the command.
Xenia Ragiadakou79931632013-06-18 05:29:41 +0300443 write_nic_dword(dev, QPNR, data);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200444 /* 2007/11/02 MH Acoording to test, we must delay 20us to wait firmware
445 to finish RF write operation. */
446 /* 2008/01/17 MH We support delay in firmware side now. */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200447
448} /* phy_FwRFSerialWrite */
449
450
451/******************************************************************************
452 *function: This function read BB parameters from Header file we gen,
453 * and do register read/write
454 * input: dev
455 * output: none
456 * return: none
457 * notice: BB parameters may change all the time, so please make
458 * sure it has been synced with the newest.
459 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300460void rtl8192_phy_configmac(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200461{
462 u32 dwArrayLen = 0, i;
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300463 u32 *pdwArray = NULL;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200464 struct r8192_priv *priv = ieee80211_priv(dev);
465
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300466 if (priv->btxpowerdata_readfromEEPORM) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200467 RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array_PG\n");
468 dwArrayLen = MACPHY_Array_PGLength;
469 pdwArray = rtl819XMACPHY_Array_PG;
470
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300471 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200472 RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array\n");
473 dwArrayLen = MACPHY_ArrayLength;
474 pdwArray = rtl819XMACPHY_Array;
475 }
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300476 for (i = 0; i < dwArrayLen; i = i+3) {
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300477 if (pdwArray[i] == 0x318) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200478 pdwArray[i+2] = 0x00000800;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200479 }
480
481 RT_TRACE(COMP_DBG, "The Rtl8190MACPHY_Array[0] is %x Rtl8190MACPHY_Array[1] is %x Rtl8190MACPHY_Array[2] is %x\n",
482 pdwArray[i], pdwArray[i+1], pdwArray[i+2]);
483 rtl8192_setBBreg(dev, pdwArray[i], pdwArray[i+1], pdwArray[i+2]);
484 }
485 return;
486
487}
488
489/******************************************************************************
Justin P. Mattock589b3d02012-04-30 07:41:36 -0700490 *function: This function does dirty work
Jerry Chuang8fc85982009-11-03 07:17:11 -0200491 * input: dev
492 * output: none
493 * return: none
494 * notice: BB parameters may change all the time, so please make
495 * sure it has been synced with the newest.
496 * ***************************************************************************/
497
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300498void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200499{
500 u32 i;
501
502#ifdef TO_DO_LIST
503 u32 *rtl8192PhyRegArrayTable = NULL, *rtl8192AgcTabArrayTable = NULL;
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300504 if (Adapter->bInHctTest) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200505 PHY_REGArrayLen = PHY_REGArrayLengthDTM;
506 AGCTAB_ArrayLen = AGCTAB_ArrayLengthDTM;
507 Rtl8190PHY_REGArray_Table = Rtl819XPHY_REGArrayDTM;
508 Rtl8190AGCTAB_Array_Table = Rtl819XAGCTAB_ArrayDTM;
509 }
510#endif
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300511 if (ConfigType == BaseBand_Config_PHY_REG) {
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300512 for (i = 0; i < PHY_REG_1T2RArrayLength; i += 2) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200513 rtl8192_setBBreg(dev, rtl819XPHY_REG_1T2RArray[i], bMaskDWord, rtl819XPHY_REG_1T2RArray[i+1]);
514 RT_TRACE(COMP_DBG, "i: %x, The Rtl819xUsbPHY_REGArray[0] is %x Rtl819xUsbPHY_REGArray[1] is %x \n",i, rtl819XPHY_REG_1T2RArray[i], rtl819XPHY_REG_1T2RArray[i+1]);
515 }
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300516 } else if (ConfigType == BaseBand_Config_AGC_TAB) {
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300517 for (i = 0; i < AGCTAB_ArrayLength; i += 2) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200518 rtl8192_setBBreg(dev, rtl819XAGCTAB_Array[i], bMaskDWord, rtl819XAGCTAB_Array[i+1]);
519 RT_TRACE(COMP_DBG, "i:%x, The rtl819XAGCTAB_Array[0] is %x rtl819XAGCTAB_Array[1] is %x \n",i, rtl819XAGCTAB_Array[i], rtl819XAGCTAB_Array[i+1]);
520 }
521 }
522 return;
523
524
525}
526/******************************************************************************
527 *function: This function initialize Register definition offset for Radio Path
528 * A/B/C/D
529 * input: net_device dev
530 * output: none
531 * return: none
532 * notice: Initialization value here is constant and it should never be changed
533 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300534void rtl8192_InitBBRFRegDef(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200535{
536 struct r8192_priv *priv = ieee80211_priv(dev);
Justin P. Mattock589b3d02012-04-30 07:41:36 -0700537// RF Interface Software Control
Jerry Chuang8fc85982009-11-03 07:17:11 -0200538 priv->PHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 LSBs if read 32-bit from 0x870
539 priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872)
540 priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 LSBs if read 32-bit from 0x874
541 priv->PHYRegDef[RF90_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876)
542
543 // RF Interface Readback Value
544 priv->PHYRegDef[RF90_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; // 16 LSBs if read 32-bit from 0x8E0
545 priv->PHYRegDef[RF90_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2)
546 priv->PHYRegDef[RF90_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 LSBs if read 32-bit from 0x8E4
547 priv->PHYRegDef[RF90_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6)
548
549 // RF Interface Output (and Enable)
550 priv->PHYRegDef[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x860
551 priv->PHYRegDef[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x864
552 priv->PHYRegDef[RF90_PATH_C].rfintfo = rFPGA0_XC_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x868
553 priv->PHYRegDef[RF90_PATH_D].rfintfo = rFPGA0_XD_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x86C
554
555 // RF Interface (Output and) Enable
556 priv->PHYRegDef[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862)
557 priv->PHYRegDef[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866)
558 priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86A (16-bit for 0x86A)
559 priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86C (16-bit for 0x86E)
560
Justin P. Mattock589b3d02012-04-30 07:41:36 -0700561 //Addr of LSSI. Write RF register by driver
Jerry Chuang8fc85982009-11-03 07:17:11 -0200562 priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; //LSSI Parameter
563 priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
564 priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter;
565 priv->PHYRegDef[RF90_PATH_D].rf3wireOffset = rFPGA0_XD_LSSIParameter;
566
567 // RF parameter
568 priv->PHYRegDef[RF90_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; //BB Band Select
569 priv->PHYRegDef[RF90_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter;
570 priv->PHYRegDef[RF90_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter;
571 priv->PHYRegDef[RF90_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter;
572
573 // Tx AGC Gain Stage (same for all path. Should we remove this?)
574 priv->PHYRegDef[RF90_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
575 priv->PHYRegDef[RF90_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
576 priv->PHYRegDef[RF90_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
577 priv->PHYRegDef[RF90_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
578
579 // Tranceiver A~D HSSI Parameter-1
580 priv->PHYRegDef[RF90_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; //wire control parameter1
581 priv->PHYRegDef[RF90_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; //wire control parameter1
582 priv->PHYRegDef[RF90_PATH_C].rfHSSIPara1 = rFPGA0_XC_HSSIParameter1; //wire control parameter1
583 priv->PHYRegDef[RF90_PATH_D].rfHSSIPara1 = rFPGA0_XD_HSSIParameter1; //wire control parameter1
584
585 // Tranceiver A~D HSSI Parameter-2
586 priv->PHYRegDef[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; //wire control parameter2
587 priv->PHYRegDef[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; //wire control parameter2
588 priv->PHYRegDef[RF90_PATH_C].rfHSSIPara2 = rFPGA0_XC_HSSIParameter2; //wire control parameter2
589 priv->PHYRegDef[RF90_PATH_D].rfHSSIPara2 = rFPGA0_XD_HSSIParameter2; //wire control parameter1
590
591 // RF switch Control
592 priv->PHYRegDef[RF90_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; //TR/Ant switch control
593 priv->PHYRegDef[RF90_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl;
594 priv->PHYRegDef[RF90_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl;
595 priv->PHYRegDef[RF90_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl;
596
597 // AGC control 1
598 priv->PHYRegDef[RF90_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1;
599 priv->PHYRegDef[RF90_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1;
600 priv->PHYRegDef[RF90_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1;
601 priv->PHYRegDef[RF90_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1;
602
603 // AGC control 2
604 priv->PHYRegDef[RF90_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2;
605 priv->PHYRegDef[RF90_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2;
606 priv->PHYRegDef[RF90_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2;
607 priv->PHYRegDef[RF90_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2;
608
609 // RX AFE control 1
610 priv->PHYRegDef[RF90_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance;
611 priv->PHYRegDef[RF90_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance;
612 priv->PHYRegDef[RF90_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance;
613 priv->PHYRegDef[RF90_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance;
614
615 // RX AFE control 1
616 priv->PHYRegDef[RF90_PATH_A].rfRxAFE = rOFDM0_XARxAFE;
617 priv->PHYRegDef[RF90_PATH_B].rfRxAFE = rOFDM0_XBRxAFE;
618 priv->PHYRegDef[RF90_PATH_C].rfRxAFE = rOFDM0_XCRxAFE;
619 priv->PHYRegDef[RF90_PATH_D].rfRxAFE = rOFDM0_XDRxAFE;
620
621 // Tx AFE control 1
622 priv->PHYRegDef[RF90_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance;
623 priv->PHYRegDef[RF90_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance;
624 priv->PHYRegDef[RF90_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance;
625 priv->PHYRegDef[RF90_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance;
626
627 // Tx AFE control 2
628 priv->PHYRegDef[RF90_PATH_A].rfTxAFE = rOFDM0_XATxAFE;
629 priv->PHYRegDef[RF90_PATH_B].rfTxAFE = rOFDM0_XBTxAFE;
630 priv->PHYRegDef[RF90_PATH_C].rfTxAFE = rOFDM0_XCTxAFE;
631 priv->PHYRegDef[RF90_PATH_D].rfTxAFE = rOFDM0_XDTxAFE;
632
633 // Tranceiver LSSI Readback
634 priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
635 priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
636 priv->PHYRegDef[RF90_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack;
637 priv->PHYRegDef[RF90_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack;
638
639}
640/******************************************************************************
641 *function: This function is to write register and then readback to make sure whether BB and RF is OK
642 * input: net_device dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100643 * HW90_BLOCK_E CheckBlock
644 * RF90_RADIO_PATH_E eRFPath //only used when checkblock is HW90_BLOCK_RF
Jerry Chuang8fc85982009-11-03 07:17:11 -0200645 * output: none
646 * return: return whether BB and RF is ok(0:OK; 1:Fail)
647 * notice: This function may be removed in the ASIC
648 * ***************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300649u8 rtl8192_phy_checkBBAndRF(struct net_device *dev, HW90_BLOCK_E CheckBlock,
650 RF90_RADIO_PATH_E eRFPath)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200651{
Jerry Chuang8fc85982009-11-03 07:17:11 -0200652 u8 ret = 0;
653 u32 i, CheckTimes = 4, dwRegRead = 0;
654 u32 WriteAddr[4];
655 u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f};
656 // Initialize register address offset to be checked
657 WriteAddr[HW90_BLOCK_MAC] = 0x100;
658 WriteAddr[HW90_BLOCK_PHY0] = 0x900;
659 WriteAddr[HW90_BLOCK_PHY1] = 0x800;
660 WriteAddr[HW90_BLOCK_RF] = 0x3;
661 RT_TRACE(COMP_PHY, "=======>%s(), CheckBlock:%d\n", __FUNCTION__, CheckBlock);
Xenia Ragiadakou111857c2013-06-18 05:29:37 +0300662 for (i = 0; i < CheckTimes; i++) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200663
664 //
665 // Write Data to register and readback
666 //
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300667 switch (CheckBlock) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200668 case HW90_BLOCK_MAC:
669 RT_TRACE(COMP_ERR, "PHY_CheckBBRFOK(): Never Write 0x100 here!");
670 break;
671
672 case HW90_BLOCK_PHY0:
673 case HW90_BLOCK_PHY1:
674 write_nic_dword(dev, WriteAddr[CheckBlock], WriteData[i]);
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300675 read_nic_dword(dev, WriteAddr[CheckBlock], &dwRegRead);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200676 break;
677
678 case HW90_BLOCK_RF:
679 WriteData[i] &= 0xfff;
680 rtl8192_phy_SetRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMask12Bits, WriteData[i]);
681 // TODO: we should not delay for such a long time. Ask SD3
682 msleep(1);
683 dwRegRead = rtl8192_phy_QueryRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMask12Bits);
684 msleep(1);
685 break;
686
687 default:
688 ret = 1;
689 break;
690 }
691
692
693 //
694 // Check whether readback data is correct
695 //
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300696 if (dwRegRead != WriteData[i]) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200697 RT_TRACE((COMP_PHY|COMP_ERR), "====>error=====dwRegRead: %x, WriteData: %x \n", dwRegRead, WriteData[i]);
698 ret = 1;
699 break;
700 }
701 }
702
703 return ret;
704}
705
706
707/******************************************************************************
708 *function: This function initialize BB&RF
709 * input: net_device dev
710 * output: none
711 * return: none
712 * notice: Initialization value may change all the time, so please make
713 * sure it has been synced with the newest.
714 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300715void rtl8192_BB_Config_ParaFile(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200716{
717 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakou07ecbbf2013-06-18 05:29:39 +0300718 u8 reg_u8 = 0, eCheckItem = 0, rtStatus = 0;
719 u32 reg_u32 = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200720 /**************************************
721 //<1>Initialize BaseBand
722 **************************************/
723
724 /*--set BB Global Reset--*/
Xenia Ragiadakou07ecbbf2013-06-18 05:29:39 +0300725 read_nic_byte(dev, BB_GLOBAL_RESET, &reg_u8);
726 write_nic_byte(dev, BB_GLOBAL_RESET,(reg_u8|BB_GLOBAL_RESET_BIT));
Jerry Chuang8fc85982009-11-03 07:17:11 -0200727 mdelay(50);
728 /*---set BB reset Active---*/
Xenia Ragiadakou07ecbbf2013-06-18 05:29:39 +0300729 read_nic_dword(dev, CPU_GEN, &reg_u32);
730 write_nic_dword(dev, CPU_GEN, (reg_u32&(~CPU_GEN_BB_RST)));
Jerry Chuang8fc85982009-11-03 07:17:11 -0200731
732 /*----Ckeck FPGAPHY0 and PHY1 board is OK----*/
733 // TODO: this function should be removed on ASIC , Emily 2007.2.2
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300734 for (eCheckItem = (HW90_BLOCK_E)HW90_BLOCK_PHY0; eCheckItem <= HW90_BLOCK_PHY1; eCheckItem++) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200735 rtStatus = rtl8192_phy_checkBBAndRF(dev, (HW90_BLOCK_E)eCheckItem, (RF90_RADIO_PATH_E)0); //don't care RF path
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300736 if (rtStatus != 0) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200737 RT_TRACE((COMP_ERR | COMP_PHY), "PHY_RF8256_Config():Check PHY%d Fail!!\n", eCheckItem-1);
Xenia Ragiadakou111857c2013-06-18 05:29:37 +0300738 return;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200739 }
740 }
741 /*---- Set CCK and OFDM Block "OFF"----*/
742 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0);
743 /*----BB Register Initilazation----*/
744 //==m==>Set PHY REG From Header<==m==
745 rtl8192_phyConfigBB(dev, BaseBand_Config_PHY_REG);
746
747 /*----Set BB reset de-Active----*/
Xenia Ragiadakou07ecbbf2013-06-18 05:29:39 +0300748 read_nic_dword(dev, CPU_GEN, &reg_u32);
749 write_nic_dword(dev, CPU_GEN, (reg_u32|CPU_GEN_BB_RST));
Jerry Chuang8fc85982009-11-03 07:17:11 -0200750
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200751 /*----BB AGC table Initialization----*/
Jerry Chuang8fc85982009-11-03 07:17:11 -0200752 //==m==>Set PHY REG From Header<==m==
753 rtl8192_phyConfigBB(dev, BaseBand_Config_AGC_TAB);
754
755 /*----Enable XSTAL ----*/
756 write_nic_byte_E(dev, 0x5e, 0x00);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300757 if (priv->card_8192_version == (u8)VERSION_819xU_A) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200758 //Antenna gain offset from B/C/D to A
Xenia Ragiadakou07ecbbf2013-06-18 05:29:39 +0300759 reg_u32 = (priv->AntennaTxPwDiff[1]<<4 | priv->AntennaTxPwDiff[0]);
760 rtl8192_setBBreg(dev, rFPGA0_TxGainStage, (bXBTxAGC|bXCTxAGC), reg_u32);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200761
762 //XSTALLCap
Xenia Ragiadakou07ecbbf2013-06-18 05:29:39 +0300763 reg_u32 = priv->CrystalCap & 0xf;
764 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap, reg_u32);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200765 }
766
767 // Check if the CCK HighPower is turned ON.
768 // This is used to calculate PWDB.
769 priv->bCckHighPower = (u8)(rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter2, 0x200));
770 return;
771}
772/******************************************************************************
773 *function: This function initialize BB&RF
774 * input: net_device dev
775 * output: none
776 * return: none
777 * notice: Initialization value may change all the time, so please make
778 * sure it has been synced with the newest.
779 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300780void rtl8192_BBConfig(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200781{
782 rtl8192_InitBBRFRegDef(dev);
783 //config BB&RF. As hardCode based initialization has not been well
784 //implemented, so use file first.FIXME:should implement it for hardcode?
785 rtl8192_BB_Config_ParaFile(dev);
786 return;
787}
788
789/******************************************************************************
790 *function: This function obtains the initialization value of Tx power Level offset
791 * input: net_device dev
792 * output: none
793 * return: none
794 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300795void rtl8192_phy_getTxPower(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200796{
797 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300798 u8 tmp;
799 read_nic_dword(dev, rTxAGC_Rate18_06, &priv->MCSTxPowerLevelOriginalOffset[0]);
800 read_nic_dword(dev, rTxAGC_Rate54_24, &priv->MCSTxPowerLevelOriginalOffset[1]);
801 read_nic_dword(dev, rTxAGC_Mcs03_Mcs00, &priv->MCSTxPowerLevelOriginalOffset[2]);
802 read_nic_dword(dev, rTxAGC_Mcs07_Mcs04, &priv->MCSTxPowerLevelOriginalOffset[3]);
803 read_nic_dword(dev, rTxAGC_Mcs11_Mcs08, &priv->MCSTxPowerLevelOriginalOffset[4]);
804 read_nic_dword(dev, rTxAGC_Mcs15_Mcs12, &priv->MCSTxPowerLevelOriginalOffset[5]);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200805
806 // read rx initial gain
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300807 read_nic_byte(dev, rOFDM0_XAAGCCore1, &priv->DefaultInitialGain[0]);
808 read_nic_byte(dev, rOFDM0_XBAGCCore1, &priv->DefaultInitialGain[1]);
809 read_nic_byte(dev, rOFDM0_XCAGCCore1, &priv->DefaultInitialGain[2]);
810 read_nic_byte(dev, rOFDM0_XDAGCCore1, &priv->DefaultInitialGain[3]);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200811 RT_TRACE(COMP_INIT, "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x) \n",
812 priv->DefaultInitialGain[0], priv->DefaultInitialGain[1],
813 priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]);
814
815 // read framesync
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300816 read_nic_byte(dev, rOFDM0_RxDetector3, &priv->framesync);
817 read_nic_byte(dev, rOFDM0_RxDetector2, &tmp);
818 priv->framesyncC34 = tmp;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200819 RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x \n",
820 rOFDM0_RxDetector3, priv->framesync);
821
822 // read SIFS (save the value read fome MACPHY_REG.txt)
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300823 read_nic_word(dev, SIFS, &priv->SifsTime);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200824
825 return;
826}
827
828/******************************************************************************
829 *function: This function obtains the initialization value of Tx power Level offset
830 * input: net_device dev
831 * output: none
832 * return: none
833 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300834void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200835{
836 struct r8192_priv *priv = ieee80211_priv(dev);
837 u8 powerlevel = priv->TxPowerLevelCCK[channel-1];
838 u8 powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1];
839
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300840 switch (priv->rf_chip) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200841 case RF_8256:
842 PHY_SetRF8256CCKTxPower(dev, powerlevel); //need further implement
843 PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
844 break;
845 default:
Jerry Chuang8fc85982009-11-03 07:17:11 -0200846 RT_TRACE((COMP_PHY|COMP_ERR), "error RF chipID(8225 or 8258) in function %s()\n", __FUNCTION__);
847 break;
848 }
849 return;
850}
851
852/******************************************************************************
853 *function: This function check Rf chip to do RF config
854 * input: net_device dev
855 * output: none
856 * return: only 8256 is supported
857 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300858void rtl8192_phy_RFConfig(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200859{
860 struct r8192_priv *priv = ieee80211_priv(dev);
861
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300862 switch (priv->rf_chip) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200863 case RF_8256:
864 PHY_RF8256_Config(dev);
865 break;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200866 default:
867 RT_TRACE(COMP_ERR, "error chip id\n");
868 break;
869 }
870 return;
871}
872
873/******************************************************************************
874 *function: This function update Initial gain
875 * input: net_device dev
876 * output: none
877 * return: As Windows has not implemented this, wait for complement
878 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300879void rtl8192_phy_updateInitGain(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200880{
881 return;
882}
883
884/******************************************************************************
885 *function: This function read RF parameters from general head file, and do RF 3-wire
886 * input: net_device dev
887 * output: none
888 * return: return code show if RF configuration is successful(0:pass, 1:fail)
889 * Note: Delay may be required for RF configuration
890 * ***************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300891u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev,
892 RF90_RADIO_PATH_E eRFPath)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200893{
894
895 int i;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200896 u8 ret = 0;
897
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300898 switch (eRFPath) {
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100899 case RF90_PATH_A:
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300900 for (i = 0; i < RadioA_ArrayLength; i = i+2) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200901
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300902 if (rtl819XRadioA_Array[i] == 0xfe) {
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100903 mdelay(100);
904 continue;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200905 }
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100906 rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioA_Array[i], bMask12Bits, rtl819XRadioA_Array[i+1]);
907 mdelay(1);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200908
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100909 }
910 break;
911 case RF90_PATH_B:
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300912 for (i = 0; i < RadioB_ArrayLength; i = i+2) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200913
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300914 if (rtl819XRadioB_Array[i] == 0xfe) {
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100915 mdelay(100);
916 continue;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200917 }
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100918 rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioB_Array[i], bMask12Bits, rtl819XRadioB_Array[i+1]);
919 mdelay(1);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200920
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100921 }
922 break;
923 case RF90_PATH_C:
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300924 for (i = 0; i < RadioC_ArrayLength; i = i+2) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200925
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300926 if (rtl819XRadioC_Array[i] == 0xfe) {
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100927 mdelay(100);
928 continue;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200929 }
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100930 rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioC_Array[i], bMask12Bits, rtl819XRadioC_Array[i+1]);
931 mdelay(1);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200932
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100933 }
934 break;
935 case RF90_PATH_D:
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300936 for (i = 0; i < RadioD_ArrayLength; i = i+2) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200937
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300938 if (rtl819XRadioD_Array[i] == 0xfe) {
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100939 mdelay(100);
940 continue;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200941 }
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100942 rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioD_Array[i], bMask12Bits, rtl819XRadioD_Array[i+1]);
943 mdelay(1);
944
945 }
946 break;
947 default:
948 break;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200949 }
950
Joe Perches859171c2010-11-14 19:04:48 -0800951 return ret;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200952
953}
954/******************************************************************************
955 *function: This function set Tx Power of the channel
956 * input: struct net_device *dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100957 * u8 channel
Jerry Chuang8fc85982009-11-03 07:17:11 -0200958 * output: none
959 * return: none
960 * Note:
961 * ***************************************************************************/
962void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel)
963{
964 struct r8192_priv *priv = ieee80211_priv(dev);
965 u8 powerlevel = priv->TxPowerLevelCCK[channel-1];
966 u8 powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1];
967
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300968 switch (priv->rf_chip) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200969 case RF_8225:
970#ifdef TO_DO_LIST
971 PHY_SetRF8225CckTxPower(Adapter, powerlevel);
972 PHY_SetRF8225OfdmTxPower(Adapter, powerlevelOFDM24G);
973#endif
974 break;
975
976 case RF_8256:
977 PHY_SetRF8256CCKTxPower(dev, powerlevel);
978 PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
979 break;
980
981 case RF_8258:
982 break;
983 default:
984 RT_TRACE(COMP_ERR, "unknown rf chip ID in rtl8192_SetTxPowerLevel()\n");
985 break;
986 }
987 return;
988}
989
990/******************************************************************************
991 *function: This function set RF state on or off
992 * input: struct net_device *dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100993 * RT_RF_POWER_STATE eRFPowerState //Power State to set
Jerry Chuang8fc85982009-11-03 07:17:11 -0200994 * output: none
995 * return: none
996 * Note:
997 * ***************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300998bool rtl8192_SetRFPowerState(struct net_device *dev,
999 RT_RF_POWER_STATE eRFPowerState)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001000{
1001 bool bResult = true;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001002 struct r8192_priv *priv = ieee80211_priv(dev);
1003
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001004 if (eRFPowerState == priv->ieee80211->eRFPowerState)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001005 return false;
1006
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001007 if (priv->SetRFPowerStateInProgress == true)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001008 return false;
1009
1010 priv->SetRFPowerStateInProgress = true;
1011
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001012 switch (priv->rf_chip) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001013 case RF_8256:
Xenia Ragiadakouceb56592013-06-15 07:29:07 +03001014 switch (eRFPowerState) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001015 case eRfOn:
Jerry Chuang8fc85982009-11-03 07:17:11 -02001016 //RF-A, RF-B
1017 //enable RF-Chip A/B
1018 rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4]
1019 //analog to digital on
1020 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8]
1021 //digital to analog on
1022 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3]
1023 //rx antenna on
1024 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
1025 //rx antenna on
1026 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
1027 //analog to digital part2 on
1028 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5]
1029
1030 break;
1031
1032 case eRfSleep:
1033
1034 break;
1035
1036 case eRfOff:
Jerry Chuang8fc85982009-11-03 07:17:11 -02001037 //RF-A, RF-B
1038 //disable RF-Chip A/B
1039 rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); // 0x860[4]
1040 //analog to digital off, for power save
1041 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
1042 //digital to analog off, for power save
1043 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0); // 0x880[4:3]
1044 //rx antenna off
1045 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0]
1046 //rx antenna off
1047 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0]
1048 //analog to digital part2 off, for power save
1049 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0); // 0x880[6:5]
1050
1051 break;
1052
1053 default:
1054 bResult = false;
1055 RT_TRACE(COMP_ERR, "SetRFPowerState819xUsb(): unknow state to set: 0x%X!!!\n", eRFPowerState);
1056 break;
1057 }
1058 break;
1059 default:
1060 RT_TRACE(COMP_ERR, "Not support rf_chip(%x)\n", priv->rf_chip);
1061 break;
1062 }
1063#ifdef TO_DO_LIST
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001064 if (bResult) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001065 // Update current RF state variable.
1066 pHalData->eRFPowerState = eRFPowerState;
Xenia Ragiadakouceb56592013-06-15 07:29:07 +03001067 switch (pHalData->RFChipID) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001068 case RF_8256:
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001069 switch (pHalData->eRFPowerState) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001070 case eRfOff:
1071 //
1072 //If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
1073 //
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001074 if (pMgntInfo->RfOffReason == RF_CHANGE_BY_IPS)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001075 Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001076 else
Jerry Chuang8fc85982009-11-03 07:17:11 -02001077 // Turn off LED if RF is not ON.
1078 Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001079 break;
1080
1081 case eRfOn:
1082 // Turn on RF we are still linked, which might happen when
1083 // we quickly turn off and on HW RF. 2006.05.12, by rcnjko.
Xenia Ragiadakouceb56592013-06-15 07:29:07 +03001084 if (pMgntInfo->bMediaConnect == TRUE)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001085 Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001086 else
Jerry Chuang8fc85982009-11-03 07:17:11 -02001087 // Turn off LED if RF is not ON.
1088 Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001089 break;
1090
1091 default:
1092 // do nothing.
1093 break;
1094 }// Switch RF state
1095 break;
1096
1097 default:
1098 RT_TRACE(COMP_RF, DBG_LOUD, ("SetRFPowerState8190(): Unknown RF type\n"));
1099 break;
1100 }
1101
1102 }
1103#endif
1104 priv->SetRFPowerStateInProgress = false;
1105
1106 return bResult;
1107}
1108
1109/****************************************************************************************
1110 *function: This function set command table variable(struct SwChnlCmd).
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001111 * input: SwChnlCmd* CmdTable //table to be set.
1112 * u32 CmdTableIdx //variable index in table to be set
1113 * u32 CmdTableSz //table size.
1114 * SwChnlCmdID CmdID //command ID to set.
Jerry Chuang8fc85982009-11-03 07:17:11 -02001115 * u32 Para1
1116 * u32 Para2
1117 * u32 msDelay
1118 * output:
1119 * return: true if finished, false otherwise
1120 * Note:
1121 * ************************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +03001122u8 rtl8192_phy_SetSwChnlCmdArray(SwChnlCmd *CmdTable, u32 CmdTableIdx,
1123 u32 CmdTableSz, SwChnlCmdID CmdID, u32 Para1,
1124 u32 Para2, u32 msDelay)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001125{
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +03001126 SwChnlCmd *pCmd;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001127
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001128 if (CmdTable == NULL) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001129 RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): CmdTable cannot be NULL.\n");
1130 return false;
1131 }
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001132 if (CmdTableIdx >= CmdTableSz) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001133 RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): Access invalid index, please check size of the table, CmdTableIdx:%d, CmdTableSz:%d\n",
1134 CmdTableIdx, CmdTableSz);
1135 return false;
1136 }
1137
1138 pCmd = CmdTable + CmdTableIdx;
1139 pCmd->CmdID = CmdID;
1140 pCmd->Para1 = Para1;
1141 pCmd->Para2 = Para2;
1142 pCmd->msDelay = msDelay;
1143
1144 return true;
1145}
1146/******************************************************************************
1147 *function: This function set channel step by step
1148 * input: struct net_device *dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001149 * u8 channel
1150 * u8* stage //3 stages
1151 * u8* step //
1152 * u32* delay //whether need to delay
Jerry Chuang8fc85982009-11-03 07:17:11 -02001153 * output: store new stage, step and delay for next step(combine with function above)
1154 * return: true if finished, false otherwise
1155 * Note: Wait for simpler function to replace it //wb
1156 * ***************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +03001157u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8 *stage,
1158 u8 *step, u32 *delay)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001159{
1160 struct r8192_priv *priv = ieee80211_priv(dev);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001161 SwChnlCmd PreCommonCmd[MAX_PRECMD_CNT];
1162 u32 PreCommonCmdCnt;
1163 SwChnlCmd PostCommonCmd[MAX_POSTCMD_CNT];
1164 u32 PostCommonCmdCnt;
1165 SwChnlCmd RfDependCmd[MAX_RFDEPENDCMD_CNT];
1166 u32 RfDependCmdCnt;
1167 SwChnlCmd *CurrentCmd = NULL;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001168 u8 eRFPath;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001169
1170 RT_TRACE(COMP_CH, "====>%s()====stage:%d, step:%d, channel:%d\n", __FUNCTION__, *stage, *step, channel);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001171 if (!IsLegalChannel(priv->ieee80211, channel)) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001172 RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n", channel);
1173 return true; //return true to tell upper caller function this channel setting is finished! Or it will in while loop.
1174 }
Jerry Chuang8fc85982009-11-03 07:17:11 -02001175//FIXME:need to check whether channel is legal or not here.WB
1176
1177
Jerry Chuang8fc85982009-11-03 07:17:11 -02001178 // <1> Fill up pre common command.
1179 PreCommonCmdCnt = 0;
1180 rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
1181 CmdID_SetTxPowerLevel, 0, 0, 0);
1182 rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
1183 CmdID_End, 0, 0, 0);
1184
1185 // <2> Fill up post common command.
1186 PostCommonCmdCnt = 0;
1187
1188 rtl8192_phy_SetSwChnlCmdArray(PostCommonCmd, PostCommonCmdCnt++, MAX_POSTCMD_CNT,
1189 CmdID_End, 0, 0, 0);
1190
1191 // <3> Fill up RF dependent command.
1192 RfDependCmdCnt = 0;
Xenia Ragiadakouceb56592013-06-15 07:29:07 +03001193 switch (priv->rf_chip) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001194 case RF_8225:
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001195 if (!(channel >= 1 && channel <= 14)) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001196 RT_TRACE(COMP_ERR, "illegal channel for Zebra 8225: %d\n", channel);
1197 return true;
1198 }
1199 rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
1200 CmdID_RF_WriteReg, rZebra1_Channel, RF_CHANNEL_TABLE_ZEBRA[channel], 10);
1201 rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
1202 CmdID_End, 0, 0, 0);
1203 break;
1204
1205 case RF_8256:
1206 // TEST!! This is not the table for 8256!!
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001207 if (!(channel >= 1 && channel <= 14)) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001208 RT_TRACE(COMP_ERR, "illegal channel for Zebra 8256: %d\n", channel);
1209 return true;
1210 }
1211 rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
1212 CmdID_RF_WriteReg, rZebra1_Channel, channel, 10);
1213 rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
1214 CmdID_End, 0, 0, 0);
1215 break;
1216
1217 case RF_8258:
1218 break;
1219
1220 default:
1221 RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip);
1222 return true;
1223 break;
1224 }
1225
1226
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001227 do {
1228 switch (*stage) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001229 case 0:
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001230 CurrentCmd = &PreCommonCmd[*step];
Jerry Chuang8fc85982009-11-03 07:17:11 -02001231 break;
1232 case 1:
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001233 CurrentCmd = &RfDependCmd[*step];
Jerry Chuang8fc85982009-11-03 07:17:11 -02001234 break;
1235 case 2:
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001236 CurrentCmd = &PostCommonCmd[*step];
Jerry Chuang8fc85982009-11-03 07:17:11 -02001237 break;
1238 }
1239
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001240 if (CurrentCmd->CmdID == CmdID_End) {
1241 if ((*stage) == 2) {
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001242 (*delay) = CurrentCmd->msDelay;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001243 return true;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001244 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001245 (*stage)++;
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001246 (*step) = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001247 continue;
1248 }
1249 }
1250
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001251 switch (CurrentCmd->CmdID) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001252 case CmdID_SetTxPowerLevel:
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001253 if (priv->card_8192_version == (u8)VERSION_819xU_A) //xiong: consider it later!
Jerry Chuang8fc85982009-11-03 07:17:11 -02001254 rtl8192_SetTxPowerLevel(dev,channel);
1255 break;
1256 case CmdID_WritePortUlong:
1257 write_nic_dword(dev, CurrentCmd->Para1, CurrentCmd->Para2);
1258 break;
1259 case CmdID_WritePortUshort:
1260 write_nic_word(dev, CurrentCmd->Para1, (u16)CurrentCmd->Para2);
1261 break;
1262 case CmdID_WritePortUchar:
1263 write_nic_byte(dev, CurrentCmd->Para1, (u8)CurrentCmd->Para2);
1264 break;
1265 case CmdID_RF_WriteReg:
Xenia Ragiadakoueadb1882013-06-15 07:29:05 +03001266 for (eRFPath = 0; eRFPath < RF90_PATH_MAX; eRFPath++) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001267 rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, bZebra1_ChannelNum, CurrentCmd->Para2);
1268 }
1269 break;
1270 default:
1271 break;
1272 }
1273
1274 break;
Xenia Ragiadakoueadb1882013-06-15 07:29:05 +03001275 } while (true);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001276
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001277 (*delay) = CurrentCmd->msDelay;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001278 (*step)++;
1279 return false;
1280}
1281
1282/******************************************************************************
Justin P. Mattock589b3d02012-04-30 07:41:36 -07001283 *function: This function does actually set channel work
Jerry Chuang8fc85982009-11-03 07:17:11 -02001284 * input: struct net_device *dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001285 * u8 channel
Jerry Chuang8fc85982009-11-03 07:17:11 -02001286 * output: none
1287 * return: noin
1288 * Note: We should not call this function directly
1289 * ***************************************************************************/
1290void rtl8192_phy_FinishSwChnlNow(struct net_device *dev, u8 channel)
1291{
1292 struct r8192_priv *priv = ieee80211_priv(dev);
1293 u32 delay = 0;
1294
Xenia Ragiadakoueadb1882013-06-15 07:29:05 +03001295 while (!rtl8192_phy_SwChnlStepByStep(dev,channel,&priv->SwChnlStage,&priv->SwChnlStep,&delay)) {
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001296 if (!priv->up)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001297 break;
1298 }
1299}
1300/******************************************************************************
1301 *function: Callback routine of the work item for switch channel.
1302 * input:
1303 *
1304 * output: none
1305 * return: noin
1306 * ***************************************************************************/
1307void rtl8192_SwChnl_WorkItem(struct net_device *dev)
1308{
1309
1310 struct r8192_priv *priv = ieee80211_priv(dev);
1311
1312 RT_TRACE(COMP_CH, "==> SwChnlCallback819xUsbWorkItem(), chan:%d\n", priv->chan);
1313
1314
1315 rtl8192_phy_FinishSwChnlNow(dev , priv->chan);
1316
1317 RT_TRACE(COMP_CH, "<== SwChnlCallback819xUsbWorkItem()\n");
1318}
1319
1320/******************************************************************************
Justin P. Mattock8ef3a7e2012-04-30 14:39:21 -07001321 *function: This function scheduled actual work item to set channel
Jerry Chuang8fc85982009-11-03 07:17:11 -02001322 * input: net_device dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001323 * u8 channel //channel to set
Jerry Chuang8fc85982009-11-03 07:17:11 -02001324 * output: none
1325 * return: return code show if workitem is scheduled(1:pass, 0:fail)
1326 * Note: Delay may be required for RF configuration
1327 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +03001328u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001329{
1330 struct r8192_priv *priv = ieee80211_priv(dev);
1331 RT_TRACE(COMP_CH, "=====>%s(), SwChnlInProgress:%d\n", __FUNCTION__, priv->SwChnlInProgress);
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001332 if (!priv->up)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001333 return false;
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001334 if (priv->SwChnlInProgress)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001335 return false;
1336
Jerry Chuang8fc85982009-11-03 07:17:11 -02001337 //--------------------------------------------
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001338 switch (priv->ieee80211->mode) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001339 case WIRELESS_MODE_A:
1340 case WIRELESS_MODE_N_5G:
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001341 if (channel <= 14) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001342 RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14");
1343 return false;
1344 }
1345 break;
1346 case WIRELESS_MODE_B:
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001347 if (channel > 14) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001348 RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14");
1349 return false;
1350 }
1351 break;
1352 case WIRELESS_MODE_G:
1353 case WIRELESS_MODE_N_24G:
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001354 if (channel > 14) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001355 RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14");
1356 return false;
1357 }
1358 break;
1359 }
1360 //--------------------------------------------
1361
1362 priv->SwChnlInProgress = true;
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001363 if (channel == 0)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001364 channel = 1;
1365
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001366 priv->chan = channel;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001367
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001368 priv->SwChnlStage = 0;
1369 priv->SwChnlStep = 0;
Xenia Ragiadakoud75340e2013-06-15 07:29:06 +03001370 if (priv->up)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001371 rtl8192_SwChnl_WorkItem(dev);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001372
1373 priv->SwChnlInProgress = false;
1374 return true;
1375}
1376
1377
1378//
1379/******************************************************************************
1380 *function: Callback routine of the work item for set bandwidth mode.
1381 * input: struct net_device *dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001382 * HT_CHANNEL_WIDTH Bandwidth //20M or 40M
1383 * HT_EXTCHNL_OFFSET Offset //Upper, Lower, or Don't care
Jerry Chuang8fc85982009-11-03 07:17:11 -02001384 * output: none
1385 * return: none
1386 * Note: I doubt whether SetBWModeInProgress flag is necessary as we can
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001387 * test whether current work in the queue or not.//do I?
Jerry Chuang8fc85982009-11-03 07:17:11 -02001388 * ***************************************************************************/
1389void rtl8192_SetBWModeWorkItem(struct net_device *dev)
1390{
1391
1392 struct r8192_priv *priv = ieee80211_priv(dev);
1393 u8 regBwOpMode;
1394
1395 RT_TRACE(COMP_SWBW, "==>rtl8192_SetBWModeWorkItem() Switch to %s bandwidth\n", \
Xenia Ragiadakou4a8d1132013-06-09 14:38:43 +03001396 priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz");
Jerry Chuang8fc85982009-11-03 07:17:11 -02001397
1398
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001399 if (priv->rf_chip == RF_PSEUDO_11N) {
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001400 priv->SetBWModeInProgress = false;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001401 return;
1402 }
1403
1404 //<1>Set MAC register
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +03001405 read_nic_byte(dev, BW_OPMODE, &regBwOpMode);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001406
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001407 switch (priv->CurrentChannelBW) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001408 case HT_CHANNEL_WIDTH_20:
1409 regBwOpMode |= BW_OPMODE_20MHZ;
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001410 // 2007/02/07 Mark by Emily because we have not verify whether this register works
Jerry Chuang8fc85982009-11-03 07:17:11 -02001411 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
1412 break;
1413
1414 case HT_CHANNEL_WIDTH_20_40:
1415 regBwOpMode &= ~BW_OPMODE_20MHZ;
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001416 // 2007/02/07 Mark by Emily because we have not verify whether this register works
Jerry Chuang8fc85982009-11-03 07:17:11 -02001417 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
1418 break;
1419
1420 default:
1421 RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n",priv->CurrentChannelBW);
1422 break;
1423 }
1424
1425 //<2>Set PHY related register
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001426 switch (priv->CurrentChannelBW) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001427 case HT_CHANNEL_WIDTH_20:
1428 // Add by Vivi 20071119
1429 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
1430 rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
1431 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1);
1432
1433 // Correct the tx power for CCK rate in 20M. Suggest by YN, 20071207
Jerry Chuang8fc85982009-11-03 07:17:11 -02001434 priv->cck_present_attentuation =
1435 priv->cck_present_attentuation_20Mdefault + priv->cck_present_attentuation_difference;
1436
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001437 if (priv->cck_present_attentuation > 22)
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001438 priv->cck_present_attentuation = 22;
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001439 if (priv->cck_present_attentuation < 0)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001440 priv->cck_present_attentuation = 0;
1441 RT_TRACE(COMP_INIT, "20M, pHalData->CCKPresentAttentuation = %d\n", priv->cck_present_attentuation);
1442
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001443 if (priv->chan == 14 && !priv->bcck_in_ch14) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001444 priv->bcck_in_ch14 = TRUE;
1445 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001446 } else if (priv->chan != 14 && priv->bcck_in_ch14) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001447 priv->bcck_in_ch14 = FALSE;
1448 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001449 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001450 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001451 }
Jerry Chuang8fc85982009-11-03 07:17:11 -02001452
1453 break;
1454 case HT_CHANNEL_WIDTH_20_40:
1455 // Add by Vivi 20071119
1456 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
1457 rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
1458 rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001459 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001460 rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001461 priv->cck_present_attentuation =
1462 priv->cck_present_attentuation_40Mdefault + priv->cck_present_attentuation_difference;
1463
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001464 if (priv->cck_present_attentuation > 22)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001465 priv->cck_present_attentuation = 22;
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001466 if (priv->cck_present_attentuation < 0)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001467 priv->cck_present_attentuation = 0;
1468
1469 RT_TRACE(COMP_INIT, "40M, pHalData->CCKPresentAttentuation = %d\n", priv->cck_present_attentuation);
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001470 if (priv->chan == 14 && !priv->bcck_in_ch14) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001471 priv->bcck_in_ch14 = true;
1472 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001473 } else if (priv->chan != 14 && priv->bcck_in_ch14) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001474 priv->bcck_in_ch14 = false;
1475 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001476 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001477 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001478 }
Jerry Chuang8fc85982009-11-03 07:17:11 -02001479
1480 break;
1481 default:
1482 RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n" ,priv->CurrentChannelBW);
1483 break;
1484
1485 }
1486 //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315
1487
Jerry Chuang8fc85982009-11-03 07:17:11 -02001488 //<3>Set RF related register
Xenia Ragiadakouceb56592013-06-15 07:29:07 +03001489 switch (priv->rf_chip) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001490 case RF_8225:
1491#ifdef TO_DO_LIST
1492 PHY_SetRF8225Bandwidth(Adapter, pHalData->CurrentChannelBW);
1493#endif
1494 break;
1495
1496 case RF_8256:
1497 PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW);
1498 break;
1499
1500 case RF_8258:
1501 // PHY_SetRF8258Bandwidth();
1502 break;
1503
1504 case RF_PSEUDO_11N:
1505 // Do Nothing
1506 break;
1507
1508 default:
1509 RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip);
1510 break;
1511 }
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001512 priv->SetBWModeInProgress = false;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001513
Xenia Ragiadakouceb56592013-06-15 07:29:07 +03001514 RT_TRACE(COMP_SWBW, "<==SetBWMode819xUsb(), %d", atomic_read(&(priv->ieee80211->atm_swbw)));
Jerry Chuang8fc85982009-11-03 07:17:11 -02001515}
1516
1517/******************************************************************************
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001518 *function: This function schedules bandwidth switch work.
Jerry Chuang8fc85982009-11-03 07:17:11 -02001519 * input: struct net_device *dev
Xenia Ragiadakou79931632013-06-18 05:29:41 +03001520 * HT_CHANNEL_WIDTH bandwidth //20M or 40M
1521 * HT_EXTCHNL_OFFSET offset //Upper, Lower, or Don't care
Jerry Chuang8fc85982009-11-03 07:17:11 -02001522 * output: none
1523 * return: none
1524 * Note: I doubt whether SetBWModeInProgress flag is necessary as we can
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001525 * test whether current work in the queue or not.//do I?
Jerry Chuang8fc85982009-11-03 07:17:11 -02001526 * ***************************************************************************/
Xenia Ragiadakou79931632013-06-18 05:29:41 +03001527void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH bandwidth,
1528 HT_EXTCHNL_OFFSET offset)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001529{
1530 struct r8192_priv *priv = ieee80211_priv(dev);
1531
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001532 if (priv->SetBWModeInProgress)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001533 return;
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001534 priv->SetBWModeInProgress = true;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001535
Xenia Ragiadakou79931632013-06-18 05:29:41 +03001536 priv->CurrentChannelBW = bandwidth;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001537
Xenia Ragiadakou79931632013-06-18 05:29:41 +03001538 if (offset == HT_EXTCHNL_OFFSET_LOWER)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001539 priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER;
Xenia Ragiadakou79931632013-06-18 05:29:41 +03001540 else if (offset == HT_EXTCHNL_OFFSET_UPPER)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001541 priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER;
1542 else
1543 priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1544
Jerry Chuang8fc85982009-11-03 07:17:11 -02001545 rtl8192_SetBWModeWorkItem(dev);
1546
1547}
1548
1549void InitialGain819xUsb(struct net_device *dev, u8 Operation)
1550{
1551 struct r8192_priv *priv = ieee80211_priv(dev);
1552
1553 priv->InitialGainOperateType = Operation;
1554
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001555 if (priv->up)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001556 queue_delayed_work(priv->priv_wq,&priv->initialgain_operate_wq,0);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001557}
1558
Jerry Chuang8fc85982009-11-03 07:17:11 -02001559extern void InitialGainOperateWorkItemCallBack(struct work_struct *work)
1560{
1561 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
1562 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,initialgain_operate_wq);
1563 struct net_device *dev = priv->ieee80211->dev;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001564#define SCAN_RX_INITIAL_GAIN 0x17
1565#define POWER_DETECTION_TH 0x08
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +03001566 u32 bitmask;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001567 u8 initial_gain;
1568 u8 Operation;
1569
1570 Operation = priv->InitialGainOperateType;
1571
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001572 switch (Operation) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001573 case IG_Backup:
1574 RT_TRACE(COMP_SCAN, "IG_Backup, backup the initial gain.\n");
Xenia Ragiadakoud75340e2013-06-15 07:29:06 +03001575 initial_gain = SCAN_RX_INITIAL_GAIN;
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +03001576 bitmask = bMaskByte0;
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001577 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001578 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // FW DIG OFF
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +03001579 priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bitmask);
1580 priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bitmask);
1581 priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bitmask);
1582 priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bitmask);
1583 bitmask = bMaskByte2;
1584 priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bitmask);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001585
1586 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
1587 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
1588 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
1589 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
1590 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca);
1591
1592 RT_TRACE(COMP_SCAN, "Write scan initial gain = 0x%x \n", initial_gain);
1593 write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
1594 write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
1595 write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
1596 write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
1597 RT_TRACE(COMP_SCAN, "Write scan 0xa0a = 0x%x \n", POWER_DETECTION_TH);
1598 write_nic_byte(dev, 0xa0a, POWER_DETECTION_TH);
1599 break;
1600 case IG_Restore:
1601 RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial gain.\n");
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +03001602 bitmask = 0x7f; //Bit0~ Bit6
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001603 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001604 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // FW DIG OFF
1605
Xenia Ragiadakou9f66ddb2013-06-18 05:29:40 +03001606 rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bitmask, (u32)priv->initgain_backup.xaagccore1);
1607 rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bitmask, (u32)priv->initgain_backup.xbagccore1);
1608 rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bitmask, (u32)priv->initgain_backup.xcagccore1);
1609 rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bitmask, (u32)priv->initgain_backup.xdagccore1);
1610 bitmask = bMaskByte2;
1611 rtl8192_setBBreg(dev, rCCK0_CCA, bitmask, (u32)priv->initgain_backup.cca);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001612
1613 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
1614 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
1615 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
1616 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
1617 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca);
1618
1619#ifdef RTL8190P
1620 SetTxPowerLevel8190(Adapter,priv->CurrentChannel);
1621#endif
1622#ifdef RTL8192E
1623 SetTxPowerLevel8190(Adapter,priv->CurrentChannel);
1624#endif
Jerry Chuang8fc85982009-11-03 07:17:11 -02001625 rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001626
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001627 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001628 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // FW DIG ON
1629 break;
1630 default:
1631 RT_TRACE(COMP_SCAN, "Unknown IG Operation. \n");
1632 break;
1633 }
1634}