blob: 5941b9a7ee3acb26f2c7fff667cbeee50c6ddc3e [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
43 * input: u32 dwBitMask //taget bit pos in the addr to be modified
44 * 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 * ****************************************************************************/
47u32 rtl8192_CalculateBitShift(u32 dwBitMask)
48{
49 u32 i;
Xenia Ragiadakou391c72a2013-06-15 07:29:01 +030050 i = ffs(dwBitMask) - 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
76 * u32 dwRegAddr //target addr to be modified
77 * u32 dwBitMask //taget bit pos in the addr to be modified
78 * u32 dwData //value to be write
79 * output: none
80 * return: none
81 * notice:
82 * ****************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +030083void rtl8192_setBBreg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask,
84 u32 dwData)
Jerry Chuang8fc85982009-11-03 07:17:11 -020085{
86
87 u32 OriginalValue, BitShift, NewValue;
88
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +030089 if (dwBitMask != bMaskDWord) { //if not "double word" write
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +030090 read_nic_dword(dev, dwRegAddr, &OriginalValue);
Jerry Chuang8fc85982009-11-03 07:17:11 -020091 BitShift = rtl8192_CalculateBitShift(dwBitMask);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -020092 NewValue = (((OriginalValue) & (~dwBitMask)) | (dwData << BitShift));
Jerry Chuang8fc85982009-11-03 07:17:11 -020093 write_nic_dword(dev, dwRegAddr, NewValue);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +030094 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -020095 write_nic_dword(dev, dwRegAddr, dwData);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +030096 }
Jerry Chuang8fc85982009-11-03 07:17:11 -020097 return;
98}
99/******************************************************************************
100 *function: This function reads specific bits from BB register
101 * input: net_device dev
102 * u32 dwRegAddr //target addr to be readback
103 * u32 dwBitMask //taget bit pos in the addr to be readback
104 * output: none
105 * return: u32 Data //the readback register value
106 * notice:
107 * ****************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300108u32 rtl8192_QueryBBReg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200109{
110 u32 Ret = 0, OriginalValue, BitShift;
111
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300112 read_nic_dword(dev, dwRegAddr, &OriginalValue);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200113 BitShift = rtl8192_CalculateBitShift(dwBitMask);
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +0300114 Ret = (OriginalValue & dwBitMask) >> BitShift;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200115
Xenia Ragiadakou4c8dd922013-06-15 07:29:03 +0300116 return Ret;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200117}
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300118static u32 phy_FwRFSerialRead(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
119 u32 Offset);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200120
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300121static void phy_FwRFSerialWrite(struct net_device *dev,
122 RF90_RADIO_PATH_E eRFPath, u32 Offset,
123 u32 Data);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200124
125/******************************************************************************
126 *function: This function read register from RF chip
127 * input: net_device dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100128 * RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
Jerry Chuang8fc85982009-11-03 07:17:11 -0200129 * u32 Offset //target address to be read
130 * output: none
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100131 * return: u32 readback value
Jerry Chuang8fc85982009-11-03 07:17:11 -0200132 * 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.
133 * ****************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300134u32 rtl8192_phy_RFSerialRead(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
135 u32 Offset)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200136{
137 struct r8192_priv *priv = ieee80211_priv(dev);
138 u32 ret = 0;
139 u32 NewOffset = 0;
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300140 BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath];
Jerry Chuang8fc85982009-11-03 07:17:11 -0200141 rtl8192_setBBreg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData, 0);
142 //make sure RF register offset is correct
143 Offset &= 0x3f;
144
145 //switch page for 8256 RF IC
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300146 if (priv->rf_chip == RF_8256) {
147 if (Offset >= 31) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200148 priv->RfReg0Value[eRFPath] |= 0x140;
149 //Switch to Reg_Mode2 for Reg 31-45
Xenia Ragiadakouceb56592013-06-15 07:29:07 +0300150 rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16));
Jerry Chuang8fc85982009-11-03 07:17:11 -0200151 //modify offset
152 NewOffset = Offset -30;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300153 } else if (Offset >= 16) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200154 priv->RfReg0Value[eRFPath] |= 0x100;
155 priv->RfReg0Value[eRFPath] &= (~0x40);
156 //Switch to Reg_Mode 1 for Reg16-30
Xenia Ragiadakouceb56592013-06-15 07:29:07 +0300157 rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16));
Jerry Chuang8fc85982009-11-03 07:17:11 -0200158
159 NewOffset = Offset - 15;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300160 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200161 NewOffset = Offset;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300162 }
163 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200164 RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be 8256\n");
165 NewOffset = Offset;
166 }
167 //put desired read addr to LSSI control Register
168 rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress, NewOffset);
169 //Issue a posedge trigger
170 //
171 rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x0);
172 rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x1);
173
174
Justin P. Mattock8ef3a7e2012-04-30 14:39:21 -0700175 // TODO: we should not delay such a long time. Ask for help from SD3
Jerry Chuang8fc85982009-11-03 07:17:11 -0200176 msleep(1);
177
178 ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData);
179
180
181 // Switch back to Reg_Mode0;
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300182 if (priv->rf_chip == RF_8256) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200183 priv->RfReg0Value[eRFPath] &= 0xebf;
184
185 rtl8192_setBBreg(
186 dev,
187 pPhyReg->rf3wireOffset,
188 bMaskDWord,
189 (priv->RfReg0Value[eRFPath] << 16));
190 }
191
192 return ret;
193
194}
195
196/******************************************************************************
197 *function: This function write data to RF register
198 * input: net_device dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100199 * RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
Jerry Chuang8fc85982009-11-03 07:17:11 -0200200 * u32 Offset //target address to be written
201 * u32 Data //The new register data to be written
202 * output: none
203 * return: none
204 * notice: For RF8256 only.
205 ===========================================================
206 *Reg Mode RegCTL[1] RegCTL[0] Note
207 * (Reg00[12]) (Reg00[10])
208 *===========================================================
209 *Reg_Mode0 0 x Reg 0 ~15(0x0 ~ 0xf)
210 *------------------------------------------------------------------
211 *Reg_Mode1 1 0 Reg 16 ~30(0x1 ~ 0xf)
212 *------------------------------------------------------------------
213 * Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf)
214 *------------------------------------------------------------------
215 * ****************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300216void rtl8192_phy_RFSerialWrite(struct net_device *dev,
217 RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200218{
219 struct r8192_priv *priv = ieee80211_priv(dev);
220 u32 DataAndAddr = 0, NewOffset = 0;
221 BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath];
222
223 Offset &= 0x3f;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300224 if (priv->rf_chip == RF_8256) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200225
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300226 if (Offset >= 31) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200227 priv->RfReg0Value[eRFPath] |= 0x140;
228 rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath] << 16));
229 NewOffset = Offset - 30;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300230 } else if (Offset >= 16) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200231 priv->RfReg0Value[eRFPath] |= 0x100;
232 priv->RfReg0Value[eRFPath] &= (~0x40);
233 rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16));
234 NewOffset = Offset - 15;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300235 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200236 NewOffset = Offset;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300237 }
238 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200239 RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be 8256\n");
240 NewOffset = Offset;
241 }
242
Justin P. Mattock589b3d02012-04-30 07:41:36 -0700243 // Put write addr in [5:0] and write data in [31:16]
Jerry Chuang8fc85982009-11-03 07:17:11 -0200244 DataAndAddr = (Data<<16) | (NewOffset&0x3f);
245
246 // Write Operation
247 rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
248
249
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300250 if (Offset == 0x0)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200251 priv->RfReg0Value[eRFPath] = Data;
252
253 // Switch back to Reg_Mode0;
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300254 if (priv->rf_chip == RF_8256) {
255 if (Offset != 0) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200256 priv->RfReg0Value[eRFPath] &= 0xebf;
257 rtl8192_setBBreg(
258 dev,
259 pPhyReg->rf3wireOffset,
260 bMaskDWord,
261 (priv->RfReg0Value[eRFPath] << 16));
262 }
263 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200264 return;
265}
266
267/******************************************************************************
268 *function: This function set specific bits to RF register
269 * input: net_device dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100270 * RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
Jerry Chuang8fc85982009-11-03 07:17:11 -0200271 * u32 RegAddr //target addr to be modified
272 * u32 BitMask //taget bit pos in the addr to be modified
273 * u32 Data //value to be write
274 * output: none
275 * return: none
276 * notice:
277 * ****************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300278void rtl8192_phy_SetRFReg(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
279 u32 RegAddr, u32 BitMask, u32 Data)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200280{
281 struct r8192_priv *priv = ieee80211_priv(dev);
282 u32 Original_Value, BitShift, New_Value;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200283
284 if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
285 return;
286
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300287 if (priv->Rf_Mode == RF_OP_By_FW) {
288 if (BitMask != bMask12Bits) { // RF data is 12 bits only
Jerry Chuang8fc85982009-11-03 07:17:11 -0200289 Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr);
290 BitShift = rtl8192_CalculateBitShift(BitMask);
291 New_Value = ((Original_Value) & (~BitMask)) | (Data<< BitShift);
292
293 phy_FwRFSerialWrite(dev, eRFPath, RegAddr, New_Value);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300294 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200295 phy_FwRFSerialWrite(dev, eRFPath, RegAddr, Data);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300296 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200297
298 udelay(200);
299
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300300 } else {
301 if (BitMask != bMask12Bits) { // RF data is 12 bits only
Jerry Chuang8fc85982009-11-03 07:17:11 -0200302 Original_Value = rtl8192_phy_RFSerialRead(dev, eRFPath, RegAddr);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200303 BitShift = rtl8192_CalculateBitShift(BitMask);
304 New_Value = (((Original_Value) & (~BitMask)) | (Data<< BitShift));
Jerry Chuang8fc85982009-11-03 07:17:11 -0200305
306 rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, New_Value);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300307 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200308 rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, Data);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300309 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200310 }
311 return;
312}
313
314/******************************************************************************
315 *function: This function reads specific bits from RF register
316 * input: net_device dev
317 * u32 RegAddr //target addr to be readback
318 * u32 BitMask //taget bit pos in the addr to be readback
319 * output: none
320 * return: u32 Data //the readback register value
321 * notice:
322 * ****************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300323u32 rtl8192_phy_QueryRFReg(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
324 u32 RegAddr, u32 BitMask)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200325{
326 u32 Original_Value, Readback_Value, BitShift;
327 struct r8192_priv *priv = ieee80211_priv(dev);
328
329
330 if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
331 return 0;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300332 if (priv->Rf_Mode == RF_OP_By_FW) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200333 Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr);
334 BitShift = rtl8192_CalculateBitShift(BitMask);
335 Readback_Value = (Original_Value & BitMask) >> BitShift;
336 udelay(200);
Xenia Ragiadakou4c8dd922013-06-15 07:29:03 +0300337 return Readback_Value;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300338 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200339 Original_Value = rtl8192_phy_RFSerialRead(dev, eRFPath, RegAddr);
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200340 BitShift = rtl8192_CalculateBitShift(BitMask);
341 Readback_Value = (Original_Value & BitMask) >> BitShift;
Xenia Ragiadakou4c8dd922013-06-15 07:29:03 +0300342 return Readback_Value;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200343 }
344}
345/******************************************************************************
346 *function: We support firmware to execute RF-R/W.
347 * input: dev
348 * output: none
349 * return: none
350 * notice:
351 * ***************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300352static u32 phy_FwRFSerialRead(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
353 u32 Offset)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200354{
355 u32 retValue = 0;
356 u32 Data = 0;
357 u8 time = 0;
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300358 u32 tmp;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200359 /* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can
360 not execute the scheme in the initial step. Otherwise, RF-R/W will waste
361 much time. This is only for site survey. */
362 // 1. Read operation need not insert data. bit 0-11
Jerry Chuang8fc85982009-11-03 07:17:11 -0200363 // 2. Write RF register address. Bit 12-19
364 Data |= ((Offset&0xFF)<<12);
365 // 3. Write RF path. bit 20-21
366 Data |= ((eRFPath&0x3)<<20);
367 // 4. Set RF read indicator. bit 22=0
Jerry Chuang8fc85982009-11-03 07:17:11 -0200368 // 5. Trigger Fw to operate the command. bit 31
369 Data |= 0x80000000;
370 // 6. We can not execute read operation if bit 31 is 1.
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300371 read_nic_dword(dev, QPNR, &tmp);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300372 while (tmp & 0x80000000) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200373 // If FW can not finish RF-R/W for more than ?? times. We must reset FW.
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300374 if (time++ < 100) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200375 udelay(10);
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300376 read_nic_dword(dev, QPNR, &tmp);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300377 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200378 break;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300379 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200380 }
381 // 7. Execute read operation.
382 write_nic_dword(dev, QPNR, Data);
383 // 8. Check if firmawre send back RF content.
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300384 read_nic_dword(dev, QPNR, &tmp);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300385 while (tmp & 0x80000000) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200386 // If FW can not finish RF-R/W for more than ?? times. We must reset FW.
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300387 if (time++ < 100) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200388 udelay(10);
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300389 read_nic_dword(dev, QPNR, &tmp);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300390 } else {
Xenia Ragiadakou4c8dd922013-06-15 07:29:03 +0300391 return 0;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300392 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200393 }
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300394 read_nic_dword(dev, RF_DATA, &retValue);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200395
Xenia Ragiadakou4c8dd922013-06-15 07:29:03 +0300396 return retValue;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200397
398} /* phy_FwRFSerialRead */
399
400/******************************************************************************
401 *function: We support firmware to execute RF-R/W.
402 * input: dev
403 * output: none
404 * return: none
405 * notice:
406 * ***************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300407static void phy_FwRFSerialWrite(struct net_device *dev,
408 RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200409{
410 u8 time = 0;
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300411 u32 tmp;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200412
Jerry Chuang8fc85982009-11-03 07:17:11 -0200413 /* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can
414 not execute the scheme in the initial step. Otherwise, RF-R/W will waste
415 much time. This is only for site survey. */
416
417 // 1. Set driver write bit and 12 bit data. bit 0-11
Jerry Chuang8fc85982009-11-03 07:17:11 -0200418 // 2. Write RF register address. bit 12-19
419 Data |= ((Offset&0xFF)<<12);
420 // 3. Write RF path. bit 20-21
421 Data |= ((eRFPath&0x3)<<20);
422 // 4. Set RF write indicator. bit 22=1
423 Data |= 0x400000;
424 // 5. Trigger Fw to operate the command. bit 31=1
425 Data |= 0x80000000;
426
427 // 6. Write operation. We can not write if bit 31 is 1.
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300428 read_nic_dword(dev, QPNR, &tmp);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300429 while (tmp & 0x80000000) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200430 // If FW can not finish RF-R/W for more than ?? times. We must reset FW.
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300431 if (time++ < 100) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200432 udelay(10);
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300433 read_nic_dword(dev, QPNR, &tmp);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300434 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200435 break;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300436 }
Jerry Chuang8fc85982009-11-03 07:17:11 -0200437 }
438 // 7. No matter check bit. We always force the write. Because FW will
439 // not accept the command.
440 write_nic_dword(dev, QPNR, Data);
441 /* 2007/11/02 MH Acoording to test, we must delay 20us to wait firmware
442 to finish RF write operation. */
443 /* 2008/01/17 MH We support delay in firmware side now. */
Jerry Chuang8fc85982009-11-03 07:17:11 -0200444
445} /* phy_FwRFSerialWrite */
446
447
448/******************************************************************************
449 *function: This function read BB parameters from Header file we gen,
450 * and do register read/write
451 * input: dev
452 * output: none
453 * return: none
454 * notice: BB parameters may change all the time, so please make
455 * sure it has been synced with the newest.
456 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300457void rtl8192_phy_configmac(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200458{
459 u32 dwArrayLen = 0, i;
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300460 u32 *pdwArray = NULL;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200461 struct r8192_priv *priv = ieee80211_priv(dev);
462
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300463 if (priv->btxpowerdata_readfromEEPORM) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200464 RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array_PG\n");
465 dwArrayLen = MACPHY_Array_PGLength;
466 pdwArray = rtl819XMACPHY_Array_PG;
467
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300468 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200469 RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array\n");
470 dwArrayLen = MACPHY_ArrayLength;
471 pdwArray = rtl819XMACPHY_Array;
472 }
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300473 for (i = 0; i < dwArrayLen; i = i+3) {
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300474 if (pdwArray[i] == 0x318) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200475 pdwArray[i+2] = 0x00000800;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200476 }
477
478 RT_TRACE(COMP_DBG, "The Rtl8190MACPHY_Array[0] is %x Rtl8190MACPHY_Array[1] is %x Rtl8190MACPHY_Array[2] is %x\n",
479 pdwArray[i], pdwArray[i+1], pdwArray[i+2]);
480 rtl8192_setBBreg(dev, pdwArray[i], pdwArray[i+1], pdwArray[i+2]);
481 }
482 return;
483
484}
485
486/******************************************************************************
Justin P. Mattock589b3d02012-04-30 07:41:36 -0700487 *function: This function does dirty work
Jerry Chuang8fc85982009-11-03 07:17:11 -0200488 * input: dev
489 * output: none
490 * return: none
491 * notice: BB parameters may change all the time, so please make
492 * sure it has been synced with the newest.
493 * ***************************************************************************/
494
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300495void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200496{
497 u32 i;
498
499#ifdef TO_DO_LIST
500 u32 *rtl8192PhyRegArrayTable = NULL, *rtl8192AgcTabArrayTable = NULL;
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300501 if (Adapter->bInHctTest) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200502 PHY_REGArrayLen = PHY_REGArrayLengthDTM;
503 AGCTAB_ArrayLen = AGCTAB_ArrayLengthDTM;
504 Rtl8190PHY_REGArray_Table = Rtl819XPHY_REGArrayDTM;
505 Rtl8190AGCTAB_Array_Table = Rtl819XAGCTAB_ArrayDTM;
506 }
507#endif
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300508 if (ConfigType == BaseBand_Config_PHY_REG) {
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300509 for (i = 0; i < PHY_REG_1T2RArrayLength; i += 2) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200510 rtl8192_setBBreg(dev, rtl819XPHY_REG_1T2RArray[i], bMaskDWord, rtl819XPHY_REG_1T2RArray[i+1]);
511 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]);
512 }
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300513 } else if (ConfigType == BaseBand_Config_AGC_TAB) {
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300514 for (i = 0; i < AGCTAB_ArrayLength; i += 2) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200515 rtl8192_setBBreg(dev, rtl819XAGCTAB_Array[i], bMaskDWord, rtl819XAGCTAB_Array[i+1]);
516 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]);
517 }
518 }
519 return;
520
521
522}
523/******************************************************************************
524 *function: This function initialize Register definition offset for Radio Path
525 * A/B/C/D
526 * input: net_device dev
527 * output: none
528 * return: none
529 * notice: Initialization value here is constant and it should never be changed
530 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300531void rtl8192_InitBBRFRegDef(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200532{
533 struct r8192_priv *priv = ieee80211_priv(dev);
Justin P. Mattock589b3d02012-04-30 07:41:36 -0700534// RF Interface Software Control
Jerry Chuang8fc85982009-11-03 07:17:11 -0200535 priv->PHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 LSBs if read 32-bit from 0x870
536 priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872)
537 priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 LSBs if read 32-bit from 0x874
538 priv->PHYRegDef[RF90_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876)
539
540 // RF Interface Readback Value
541 priv->PHYRegDef[RF90_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; // 16 LSBs if read 32-bit from 0x8E0
542 priv->PHYRegDef[RF90_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2)
543 priv->PHYRegDef[RF90_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 LSBs if read 32-bit from 0x8E4
544 priv->PHYRegDef[RF90_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6)
545
546 // RF Interface Output (and Enable)
547 priv->PHYRegDef[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x860
548 priv->PHYRegDef[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x864
549 priv->PHYRegDef[RF90_PATH_C].rfintfo = rFPGA0_XC_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x868
550 priv->PHYRegDef[RF90_PATH_D].rfintfo = rFPGA0_XD_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x86C
551
552 // RF Interface (Output and) Enable
553 priv->PHYRegDef[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862)
554 priv->PHYRegDef[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866)
555 priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86A (16-bit for 0x86A)
556 priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86C (16-bit for 0x86E)
557
Justin P. Mattock589b3d02012-04-30 07:41:36 -0700558 //Addr of LSSI. Write RF register by driver
Jerry Chuang8fc85982009-11-03 07:17:11 -0200559 priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; //LSSI Parameter
560 priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
561 priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter;
562 priv->PHYRegDef[RF90_PATH_D].rf3wireOffset = rFPGA0_XD_LSSIParameter;
563
564 // RF parameter
565 priv->PHYRegDef[RF90_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; //BB Band Select
566 priv->PHYRegDef[RF90_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter;
567 priv->PHYRegDef[RF90_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter;
568 priv->PHYRegDef[RF90_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter;
569
570 // Tx AGC Gain Stage (same for all path. Should we remove this?)
571 priv->PHYRegDef[RF90_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
572 priv->PHYRegDef[RF90_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
573 priv->PHYRegDef[RF90_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
574 priv->PHYRegDef[RF90_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
575
576 // Tranceiver A~D HSSI Parameter-1
577 priv->PHYRegDef[RF90_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; //wire control parameter1
578 priv->PHYRegDef[RF90_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; //wire control parameter1
579 priv->PHYRegDef[RF90_PATH_C].rfHSSIPara1 = rFPGA0_XC_HSSIParameter1; //wire control parameter1
580 priv->PHYRegDef[RF90_PATH_D].rfHSSIPara1 = rFPGA0_XD_HSSIParameter1; //wire control parameter1
581
582 // Tranceiver A~D HSSI Parameter-2
583 priv->PHYRegDef[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; //wire control parameter2
584 priv->PHYRegDef[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; //wire control parameter2
585 priv->PHYRegDef[RF90_PATH_C].rfHSSIPara2 = rFPGA0_XC_HSSIParameter2; //wire control parameter2
586 priv->PHYRegDef[RF90_PATH_D].rfHSSIPara2 = rFPGA0_XD_HSSIParameter2; //wire control parameter1
587
588 // RF switch Control
589 priv->PHYRegDef[RF90_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; //TR/Ant switch control
590 priv->PHYRegDef[RF90_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl;
591 priv->PHYRegDef[RF90_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl;
592 priv->PHYRegDef[RF90_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl;
593
594 // AGC control 1
595 priv->PHYRegDef[RF90_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1;
596 priv->PHYRegDef[RF90_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1;
597 priv->PHYRegDef[RF90_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1;
598 priv->PHYRegDef[RF90_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1;
599
600 // AGC control 2
601 priv->PHYRegDef[RF90_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2;
602 priv->PHYRegDef[RF90_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2;
603 priv->PHYRegDef[RF90_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2;
604 priv->PHYRegDef[RF90_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2;
605
606 // RX AFE control 1
607 priv->PHYRegDef[RF90_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance;
608 priv->PHYRegDef[RF90_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance;
609 priv->PHYRegDef[RF90_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance;
610 priv->PHYRegDef[RF90_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance;
611
612 // RX AFE control 1
613 priv->PHYRegDef[RF90_PATH_A].rfRxAFE = rOFDM0_XARxAFE;
614 priv->PHYRegDef[RF90_PATH_B].rfRxAFE = rOFDM0_XBRxAFE;
615 priv->PHYRegDef[RF90_PATH_C].rfRxAFE = rOFDM0_XCRxAFE;
616 priv->PHYRegDef[RF90_PATH_D].rfRxAFE = rOFDM0_XDRxAFE;
617
618 // Tx AFE control 1
619 priv->PHYRegDef[RF90_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance;
620 priv->PHYRegDef[RF90_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance;
621 priv->PHYRegDef[RF90_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance;
622 priv->PHYRegDef[RF90_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance;
623
624 // Tx AFE control 2
625 priv->PHYRegDef[RF90_PATH_A].rfTxAFE = rOFDM0_XATxAFE;
626 priv->PHYRegDef[RF90_PATH_B].rfTxAFE = rOFDM0_XBTxAFE;
627 priv->PHYRegDef[RF90_PATH_C].rfTxAFE = rOFDM0_XCTxAFE;
628 priv->PHYRegDef[RF90_PATH_D].rfTxAFE = rOFDM0_XDTxAFE;
629
630 // Tranceiver LSSI Readback
631 priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
632 priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
633 priv->PHYRegDef[RF90_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack;
634 priv->PHYRegDef[RF90_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack;
635
636}
637/******************************************************************************
638 *function: This function is to write register and then readback to make sure whether BB and RF is OK
639 * input: net_device dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100640 * HW90_BLOCK_E CheckBlock
641 * RF90_RADIO_PATH_E eRFPath //only used when checkblock is HW90_BLOCK_RF
Jerry Chuang8fc85982009-11-03 07:17:11 -0200642 * output: none
643 * return: return whether BB and RF is ok(0:OK; 1:Fail)
644 * notice: This function may be removed in the ASIC
645 * ***************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300646u8 rtl8192_phy_checkBBAndRF(struct net_device *dev, HW90_BLOCK_E CheckBlock,
647 RF90_RADIO_PATH_E eRFPath)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200648{
Jerry Chuang8fc85982009-11-03 07:17:11 -0200649 u8 ret = 0;
650 u32 i, CheckTimes = 4, dwRegRead = 0;
651 u32 WriteAddr[4];
652 u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f};
653 // Initialize register address offset to be checked
654 WriteAddr[HW90_BLOCK_MAC] = 0x100;
655 WriteAddr[HW90_BLOCK_PHY0] = 0x900;
656 WriteAddr[HW90_BLOCK_PHY1] = 0x800;
657 WriteAddr[HW90_BLOCK_RF] = 0x3;
658 RT_TRACE(COMP_PHY, "=======>%s(), CheckBlock:%d\n", __FUNCTION__, CheckBlock);
Xenia Ragiadakou111857c2013-06-18 05:29:37 +0300659 for (i = 0; i < CheckTimes; i++) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200660
661 //
662 // Write Data to register and readback
663 //
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300664 switch (CheckBlock) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200665 case HW90_BLOCK_MAC:
666 RT_TRACE(COMP_ERR, "PHY_CheckBBRFOK(): Never Write 0x100 here!");
667 break;
668
669 case HW90_BLOCK_PHY0:
670 case HW90_BLOCK_PHY1:
671 write_nic_dword(dev, WriteAddr[CheckBlock], WriteData[i]);
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300672 read_nic_dword(dev, WriteAddr[CheckBlock], &dwRegRead);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200673 break;
674
675 case HW90_BLOCK_RF:
676 WriteData[i] &= 0xfff;
677 rtl8192_phy_SetRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMask12Bits, WriteData[i]);
678 // TODO: we should not delay for such a long time. Ask SD3
679 msleep(1);
680 dwRegRead = rtl8192_phy_QueryRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMask12Bits);
681 msleep(1);
682 break;
683
684 default:
685 ret = 1;
686 break;
687 }
688
689
690 //
691 // Check whether readback data is correct
692 //
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300693 if (dwRegRead != WriteData[i]) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200694 RT_TRACE((COMP_PHY|COMP_ERR), "====>error=====dwRegRead: %x, WriteData: %x \n", dwRegRead, WriteData[i]);
695 ret = 1;
696 break;
697 }
698 }
699
700 return ret;
701}
702
703
704/******************************************************************************
705 *function: This function initialize BB&RF
706 * input: net_device dev
707 * output: none
708 * return: none
709 * notice: Initialization value may change all the time, so please make
710 * sure it has been synced with the newest.
711 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300712void rtl8192_BB_Config_ParaFile(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200713{
714 struct r8192_priv *priv = ieee80211_priv(dev);
715 u8 bRegValue = 0, eCheckItem = 0, rtStatus = 0;
716 u32 dwRegValue = 0;
717 /**************************************
718 //<1>Initialize BaseBand
719 **************************************/
720
721 /*--set BB Global Reset--*/
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300722 read_nic_byte(dev, BB_GLOBAL_RESET, &bRegValue);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200723 write_nic_byte(dev, BB_GLOBAL_RESET,(bRegValue|BB_GLOBAL_RESET_BIT));
724 mdelay(50);
725 /*---set BB reset Active---*/
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300726 read_nic_dword(dev, CPU_GEN, &dwRegValue);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200727 write_nic_dword(dev, CPU_GEN, (dwRegValue&(~CPU_GEN_BB_RST)));
728
729 /*----Ckeck FPGAPHY0 and PHY1 board is OK----*/
730 // TODO: this function should be removed on ASIC , Emily 2007.2.2
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300731 for (eCheckItem = (HW90_BLOCK_E)HW90_BLOCK_PHY0; eCheckItem <= HW90_BLOCK_PHY1; eCheckItem++) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200732 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 +0300733 if (rtStatus != 0) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200734 RT_TRACE((COMP_ERR | COMP_PHY), "PHY_RF8256_Config():Check PHY%d Fail!!\n", eCheckItem-1);
Xenia Ragiadakou111857c2013-06-18 05:29:37 +0300735 return;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200736 }
737 }
738 /*---- Set CCK and OFDM Block "OFF"----*/
739 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0);
740 /*----BB Register Initilazation----*/
741 //==m==>Set PHY REG From Header<==m==
742 rtl8192_phyConfigBB(dev, BaseBand_Config_PHY_REG);
743
744 /*----Set BB reset de-Active----*/
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300745 read_nic_dword(dev, CPU_GEN, &dwRegValue);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200746 write_nic_dword(dev, CPU_GEN, (dwRegValue|CPU_GEN_BB_RST));
747
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -0200748 /*----BB AGC table Initialization----*/
Jerry Chuang8fc85982009-11-03 07:17:11 -0200749 //==m==>Set PHY REG From Header<==m==
750 rtl8192_phyConfigBB(dev, BaseBand_Config_AGC_TAB);
751
752 /*----Enable XSTAL ----*/
753 write_nic_byte_E(dev, 0x5e, 0x00);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300754 if (priv->card_8192_version == (u8)VERSION_819xU_A) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200755 //Antenna gain offset from B/C/D to A
756 dwRegValue = (priv->AntennaTxPwDiff[1]<<4 | priv->AntennaTxPwDiff[0]);
757 rtl8192_setBBreg(dev, rFPGA0_TxGainStage, (bXBTxAGC|bXCTxAGC), dwRegValue);
758
759 //XSTALLCap
760 dwRegValue = priv->CrystalCap & 0xf;
761 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap, dwRegValue);
762 }
763
764 // Check if the CCK HighPower is turned ON.
765 // This is used to calculate PWDB.
766 priv->bCckHighPower = (u8)(rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter2, 0x200));
767 return;
768}
769/******************************************************************************
770 *function: This function initialize BB&RF
771 * input: net_device dev
772 * output: none
773 * return: none
774 * notice: Initialization value may change all the time, so please make
775 * sure it has been synced with the newest.
776 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300777void rtl8192_BBConfig(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200778{
779 rtl8192_InitBBRFRegDef(dev);
780 //config BB&RF. As hardCode based initialization has not been well
781 //implemented, so use file first.FIXME:should implement it for hardcode?
782 rtl8192_BB_Config_ParaFile(dev);
783 return;
784}
785
786/******************************************************************************
787 *function: This function obtains the initialization value of Tx power Level offset
788 * input: net_device dev
789 * output: none
790 * return: none
791 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300792void rtl8192_phy_getTxPower(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200793{
794 struct r8192_priv *priv = ieee80211_priv(dev);
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300795 u8 tmp;
796 read_nic_dword(dev, rTxAGC_Rate18_06, &priv->MCSTxPowerLevelOriginalOffset[0]);
797 read_nic_dword(dev, rTxAGC_Rate54_24, &priv->MCSTxPowerLevelOriginalOffset[1]);
798 read_nic_dword(dev, rTxAGC_Mcs03_Mcs00, &priv->MCSTxPowerLevelOriginalOffset[2]);
799 read_nic_dword(dev, rTxAGC_Mcs07_Mcs04, &priv->MCSTxPowerLevelOriginalOffset[3]);
800 read_nic_dword(dev, rTxAGC_Mcs11_Mcs08, &priv->MCSTxPowerLevelOriginalOffset[4]);
801 read_nic_dword(dev, rTxAGC_Mcs15_Mcs12, &priv->MCSTxPowerLevelOriginalOffset[5]);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200802
803 // read rx initial gain
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300804 read_nic_byte(dev, rOFDM0_XAAGCCore1, &priv->DefaultInitialGain[0]);
805 read_nic_byte(dev, rOFDM0_XBAGCCore1, &priv->DefaultInitialGain[1]);
806 read_nic_byte(dev, rOFDM0_XCAGCCore1, &priv->DefaultInitialGain[2]);
807 read_nic_byte(dev, rOFDM0_XDAGCCore1, &priv->DefaultInitialGain[3]);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200808 RT_TRACE(COMP_INIT, "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x) \n",
809 priv->DefaultInitialGain[0], priv->DefaultInitialGain[1],
810 priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]);
811
812 // read framesync
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300813 read_nic_byte(dev, rOFDM0_RxDetector3, &priv->framesync);
814 read_nic_byte(dev, rOFDM0_RxDetector2, &tmp);
815 priv->framesyncC34 = tmp;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200816 RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x \n",
817 rOFDM0_RxDetector3, priv->framesync);
818
819 // read SIFS (save the value read fome MACPHY_REG.txt)
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +0300820 read_nic_word(dev, SIFS, &priv->SifsTime);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200821
822 return;
823}
824
825/******************************************************************************
826 *function: This function obtains the initialization value of Tx power Level offset
827 * input: net_device dev
828 * output: none
829 * return: none
830 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300831void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200832{
833 struct r8192_priv *priv = ieee80211_priv(dev);
834 u8 powerlevel = priv->TxPowerLevelCCK[channel-1];
835 u8 powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1];
836
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300837 switch (priv->rf_chip) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200838 case RF_8256:
839 PHY_SetRF8256CCKTxPower(dev, powerlevel); //need further implement
840 PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
841 break;
842 default:
Jerry Chuang8fc85982009-11-03 07:17:11 -0200843 RT_TRACE((COMP_PHY|COMP_ERR), "error RF chipID(8225 or 8258) in function %s()\n", __FUNCTION__);
844 break;
845 }
846 return;
847}
848
849/******************************************************************************
850 *function: This function check Rf chip to do RF config
851 * input: net_device dev
852 * output: none
853 * return: only 8256 is supported
854 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300855void rtl8192_phy_RFConfig(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200856{
857 struct r8192_priv *priv = ieee80211_priv(dev);
858
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300859 switch (priv->rf_chip) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200860 case RF_8256:
861 PHY_RF8256_Config(dev);
862 break;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200863 default:
864 RT_TRACE(COMP_ERR, "error chip id\n");
865 break;
866 }
867 return;
868}
869
870/******************************************************************************
871 *function: This function update Initial gain
872 * input: net_device dev
873 * output: none
874 * return: As Windows has not implemented this, wait for complement
875 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +0300876void rtl8192_phy_updateInitGain(struct net_device *dev)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200877{
878 return;
879}
880
881/******************************************************************************
882 *function: This function read RF parameters from general head file, and do RF 3-wire
883 * input: net_device dev
884 * output: none
885 * return: return code show if RF configuration is successful(0:pass, 1:fail)
886 * Note: Delay may be required for RF configuration
887 * ***************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300888u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev,
889 RF90_RADIO_PATH_E eRFPath)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200890{
891
892 int i;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200893 u8 ret = 0;
894
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300895 switch (eRFPath) {
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100896 case RF90_PATH_A:
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300897 for (i = 0; i < RadioA_ArrayLength; i = i+2) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200898
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300899 if (rtl819XRadioA_Array[i] == 0xfe) {
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100900 mdelay(100);
901 continue;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200902 }
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100903 rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioA_Array[i], bMask12Bits, rtl819XRadioA_Array[i+1]);
904 mdelay(1);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200905
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100906 }
907 break;
908 case RF90_PATH_B:
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300909 for (i = 0; i < RadioB_ArrayLength; i = i+2) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200910
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300911 if (rtl819XRadioB_Array[i] == 0xfe) {
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100912 mdelay(100);
913 continue;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200914 }
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100915 rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioB_Array[i], bMask12Bits, rtl819XRadioB_Array[i+1]);
916 mdelay(1);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200917
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100918 }
919 break;
920 case RF90_PATH_C:
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300921 for (i = 0; i < RadioC_ArrayLength; i = i+2) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200922
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300923 if (rtl819XRadioC_Array[i] == 0xfe) {
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100924 mdelay(100);
925 continue;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200926 }
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100927 rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioC_Array[i], bMask12Bits, rtl819XRadioC_Array[i+1]);
928 mdelay(1);
Jerry Chuang8fc85982009-11-03 07:17:11 -0200929
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100930 }
931 break;
932 case RF90_PATH_D:
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +0300933 for (i = 0; i < RadioD_ArrayLength; i = i+2) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200934
Xenia Ragiadakou1111b872013-06-15 07:29:04 +0300935 if (rtl819XRadioD_Array[i] == 0xfe) {
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100936 mdelay(100);
937 continue;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200938 }
Sebastian Hahn24fbe872012-12-05 21:40:22 +0100939 rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioD_Array[i], bMask12Bits, rtl819XRadioD_Array[i+1]);
940 mdelay(1);
941
942 }
943 break;
944 default:
945 break;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200946 }
947
Joe Perches859171c2010-11-14 19:04:48 -0800948 return ret;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200949
950}
951/******************************************************************************
952 *function: This function set Tx Power of the channel
953 * input: struct net_device *dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100954 * u8 channel
Jerry Chuang8fc85982009-11-03 07:17:11 -0200955 * output: none
956 * return: none
957 * Note:
958 * ***************************************************************************/
959void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel)
960{
961 struct r8192_priv *priv = ieee80211_priv(dev);
962 u8 powerlevel = priv->TxPowerLevelCCK[channel-1];
963 u8 powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1];
964
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +0300965 switch (priv->rf_chip) {
Jerry Chuang8fc85982009-11-03 07:17:11 -0200966 case RF_8225:
967#ifdef TO_DO_LIST
968 PHY_SetRF8225CckTxPower(Adapter, powerlevel);
969 PHY_SetRF8225OfdmTxPower(Adapter, powerlevelOFDM24G);
970#endif
971 break;
972
973 case RF_8256:
974 PHY_SetRF8256CCKTxPower(dev, powerlevel);
975 PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
976 break;
977
978 case RF_8258:
979 break;
980 default:
981 RT_TRACE(COMP_ERR, "unknown rf chip ID in rtl8192_SetTxPowerLevel()\n");
982 break;
983 }
984 return;
985}
986
987/******************************************************************************
988 *function: This function set RF state on or off
989 * input: struct net_device *dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +0100990 * RT_RF_POWER_STATE eRFPowerState //Power State to set
Jerry Chuang8fc85982009-11-03 07:17:11 -0200991 * output: none
992 * return: none
993 * Note:
994 * ***************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +0300995bool rtl8192_SetRFPowerState(struct net_device *dev,
996 RT_RF_POWER_STATE eRFPowerState)
Jerry Chuang8fc85982009-11-03 07:17:11 -0200997{
998 bool bResult = true;
Jerry Chuang8fc85982009-11-03 07:17:11 -0200999 struct r8192_priv *priv = ieee80211_priv(dev);
1000
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001001 if (eRFPowerState == priv->ieee80211->eRFPowerState)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001002 return false;
1003
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001004 if (priv->SetRFPowerStateInProgress == true)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001005 return false;
1006
1007 priv->SetRFPowerStateInProgress = true;
1008
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001009 switch (priv->rf_chip) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001010 case RF_8256:
Xenia Ragiadakouceb56592013-06-15 07:29:07 +03001011 switch (eRFPowerState) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001012 case eRfOn:
Jerry Chuang8fc85982009-11-03 07:17:11 -02001013 //RF-A, RF-B
1014 //enable RF-Chip A/B
1015 rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4]
1016 //analog to digital on
1017 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8]
1018 //digital to analog on
1019 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3]
1020 //rx antenna on
1021 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
1022 //rx antenna on
1023 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
1024 //analog to digital part2 on
1025 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5]
1026
1027 break;
1028
1029 case eRfSleep:
1030
1031 break;
1032
1033 case eRfOff:
Jerry Chuang8fc85982009-11-03 07:17:11 -02001034 //RF-A, RF-B
1035 //disable RF-Chip A/B
1036 rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); // 0x860[4]
1037 //analog to digital off, for power save
1038 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
1039 //digital to analog off, for power save
1040 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0); // 0x880[4:3]
1041 //rx antenna off
1042 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0]
1043 //rx antenna off
1044 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0]
1045 //analog to digital part2 off, for power save
1046 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0); // 0x880[6:5]
1047
1048 break;
1049
1050 default:
1051 bResult = false;
1052 RT_TRACE(COMP_ERR, "SetRFPowerState819xUsb(): unknow state to set: 0x%X!!!\n", eRFPowerState);
1053 break;
1054 }
1055 break;
1056 default:
1057 RT_TRACE(COMP_ERR, "Not support rf_chip(%x)\n", priv->rf_chip);
1058 break;
1059 }
1060#ifdef TO_DO_LIST
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001061 if (bResult) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001062 // Update current RF state variable.
1063 pHalData->eRFPowerState = eRFPowerState;
Xenia Ragiadakouceb56592013-06-15 07:29:07 +03001064 switch (pHalData->RFChipID) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001065 case RF_8256:
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001066 switch (pHalData->eRFPowerState) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001067 case eRfOff:
1068 //
1069 //If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
1070 //
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001071 if (pMgntInfo->RfOffReason == RF_CHANGE_BY_IPS)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001072 Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001073 else
Jerry Chuang8fc85982009-11-03 07:17:11 -02001074 // Turn off LED if RF is not ON.
1075 Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001076 break;
1077
1078 case eRfOn:
1079 // Turn on RF we are still linked, which might happen when
1080 // we quickly turn off and on HW RF. 2006.05.12, by rcnjko.
Xenia Ragiadakouceb56592013-06-15 07:29:07 +03001081 if (pMgntInfo->bMediaConnect == TRUE)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001082 Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001083 else
Jerry Chuang8fc85982009-11-03 07:17:11 -02001084 // Turn off LED if RF is not ON.
1085 Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001086 break;
1087
1088 default:
1089 // do nothing.
1090 break;
1091 }// Switch RF state
1092 break;
1093
1094 default:
1095 RT_TRACE(COMP_RF, DBG_LOUD, ("SetRFPowerState8190(): Unknown RF type\n"));
1096 break;
1097 }
1098
1099 }
1100#endif
1101 priv->SetRFPowerStateInProgress = false;
1102
1103 return bResult;
1104}
1105
1106/****************************************************************************************
1107 *function: This function set command table variable(struct SwChnlCmd).
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001108 * input: SwChnlCmd* CmdTable //table to be set.
1109 * u32 CmdTableIdx //variable index in table to be set
1110 * u32 CmdTableSz //table size.
1111 * SwChnlCmdID CmdID //command ID to set.
Jerry Chuang8fc85982009-11-03 07:17:11 -02001112 * u32 Para1
1113 * u32 Para2
1114 * u32 msDelay
1115 * output:
1116 * return: true if finished, false otherwise
1117 * Note:
1118 * ************************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +03001119u8 rtl8192_phy_SetSwChnlCmdArray(SwChnlCmd *CmdTable, u32 CmdTableIdx,
1120 u32 CmdTableSz, SwChnlCmdID CmdID, u32 Para1,
1121 u32 Para2, u32 msDelay)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001122{
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +03001123 SwChnlCmd *pCmd;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001124
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001125 if (CmdTable == NULL) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001126 RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): CmdTable cannot be NULL.\n");
1127 return false;
1128 }
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001129 if (CmdTableIdx >= CmdTableSz) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001130 RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): Access invalid index, please check size of the table, CmdTableIdx:%d, CmdTableSz:%d\n",
1131 CmdTableIdx, CmdTableSz);
1132 return false;
1133 }
1134
1135 pCmd = CmdTable + CmdTableIdx;
1136 pCmd->CmdID = CmdID;
1137 pCmd->Para1 = Para1;
1138 pCmd->Para2 = Para2;
1139 pCmd->msDelay = msDelay;
1140
1141 return true;
1142}
1143/******************************************************************************
1144 *function: This function set channel step by step
1145 * input: struct net_device *dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001146 * u8 channel
1147 * u8* stage //3 stages
1148 * u8* step //
1149 * u32* delay //whether need to delay
Jerry Chuang8fc85982009-11-03 07:17:11 -02001150 * output: store new stage, step and delay for next step(combine with function above)
1151 * return: true if finished, false otherwise
1152 * Note: Wait for simpler function to replace it //wb
1153 * ***************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +03001154u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8 *stage,
1155 u8 *step, u32 *delay)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001156{
1157 struct r8192_priv *priv = ieee80211_priv(dev);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001158 SwChnlCmd PreCommonCmd[MAX_PRECMD_CNT];
1159 u32 PreCommonCmdCnt;
1160 SwChnlCmd PostCommonCmd[MAX_POSTCMD_CNT];
1161 u32 PostCommonCmdCnt;
1162 SwChnlCmd RfDependCmd[MAX_RFDEPENDCMD_CNT];
1163 u32 RfDependCmdCnt;
1164 SwChnlCmd *CurrentCmd = NULL;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001165 u8 eRFPath;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001166
1167 RT_TRACE(COMP_CH, "====>%s()====stage:%d, step:%d, channel:%d\n", __FUNCTION__, *stage, *step, channel);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001168 if (!IsLegalChannel(priv->ieee80211, channel)) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001169 RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n", channel);
1170 return true; //return true to tell upper caller function this channel setting is finished! Or it will in while loop.
1171 }
Jerry Chuang8fc85982009-11-03 07:17:11 -02001172//FIXME:need to check whether channel is legal or not here.WB
1173
1174
Jerry Chuang8fc85982009-11-03 07:17:11 -02001175 // <1> Fill up pre common command.
1176 PreCommonCmdCnt = 0;
1177 rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
1178 CmdID_SetTxPowerLevel, 0, 0, 0);
1179 rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
1180 CmdID_End, 0, 0, 0);
1181
1182 // <2> Fill up post common command.
1183 PostCommonCmdCnt = 0;
1184
1185 rtl8192_phy_SetSwChnlCmdArray(PostCommonCmd, PostCommonCmdCnt++, MAX_POSTCMD_CNT,
1186 CmdID_End, 0, 0, 0);
1187
1188 // <3> Fill up RF dependent command.
1189 RfDependCmdCnt = 0;
Xenia Ragiadakouceb56592013-06-15 07:29:07 +03001190 switch (priv->rf_chip) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001191 case RF_8225:
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001192 if (!(channel >= 1 && channel <= 14)) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001193 RT_TRACE(COMP_ERR, "illegal channel for Zebra 8225: %d\n", channel);
1194 return true;
1195 }
1196 rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
1197 CmdID_RF_WriteReg, rZebra1_Channel, RF_CHANNEL_TABLE_ZEBRA[channel], 10);
1198 rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
1199 CmdID_End, 0, 0, 0);
1200 break;
1201
1202 case RF_8256:
1203 // TEST!! This is not the table for 8256!!
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001204 if (!(channel >= 1 && channel <= 14)) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001205 RT_TRACE(COMP_ERR, "illegal channel for Zebra 8256: %d\n", channel);
1206 return true;
1207 }
1208 rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
1209 CmdID_RF_WriteReg, rZebra1_Channel, channel, 10);
1210 rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
1211 CmdID_End, 0, 0, 0);
1212 break;
1213
1214 case RF_8258:
1215 break;
1216
1217 default:
1218 RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip);
1219 return true;
1220 break;
1221 }
1222
1223
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001224 do {
1225 switch (*stage) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001226 case 0:
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001227 CurrentCmd = &PreCommonCmd[*step];
Jerry Chuang8fc85982009-11-03 07:17:11 -02001228 break;
1229 case 1:
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001230 CurrentCmd = &RfDependCmd[*step];
Jerry Chuang8fc85982009-11-03 07:17:11 -02001231 break;
1232 case 2:
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001233 CurrentCmd = &PostCommonCmd[*step];
Jerry Chuang8fc85982009-11-03 07:17:11 -02001234 break;
1235 }
1236
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001237 if (CurrentCmd->CmdID == CmdID_End) {
1238 if ((*stage) == 2) {
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001239 (*delay) = CurrentCmd->msDelay;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001240 return true;
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001241 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001242 (*stage)++;
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001243 (*step) = 0;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001244 continue;
1245 }
1246 }
1247
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001248 switch (CurrentCmd->CmdID) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001249 case CmdID_SetTxPowerLevel:
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001250 if (priv->card_8192_version == (u8)VERSION_819xU_A) //xiong: consider it later!
Jerry Chuang8fc85982009-11-03 07:17:11 -02001251 rtl8192_SetTxPowerLevel(dev,channel);
1252 break;
1253 case CmdID_WritePortUlong:
1254 write_nic_dword(dev, CurrentCmd->Para1, CurrentCmd->Para2);
1255 break;
1256 case CmdID_WritePortUshort:
1257 write_nic_word(dev, CurrentCmd->Para1, (u16)CurrentCmd->Para2);
1258 break;
1259 case CmdID_WritePortUchar:
1260 write_nic_byte(dev, CurrentCmd->Para1, (u8)CurrentCmd->Para2);
1261 break;
1262 case CmdID_RF_WriteReg:
Xenia Ragiadakoueadb1882013-06-15 07:29:05 +03001263 for (eRFPath = 0; eRFPath < RF90_PATH_MAX; eRFPath++) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001264 rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, bZebra1_ChannelNum, CurrentCmd->Para2);
1265 }
1266 break;
1267 default:
1268 break;
1269 }
1270
1271 break;
Xenia Ragiadakoueadb1882013-06-15 07:29:05 +03001272 } while (true);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001273
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001274 (*delay) = CurrentCmd->msDelay;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001275 (*step)++;
1276 return false;
1277}
1278
1279/******************************************************************************
Justin P. Mattock589b3d02012-04-30 07:41:36 -07001280 *function: This function does actually set channel work
Jerry Chuang8fc85982009-11-03 07:17:11 -02001281 * input: struct net_device *dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001282 * u8 channel
Jerry Chuang8fc85982009-11-03 07:17:11 -02001283 * output: none
1284 * return: noin
1285 * Note: We should not call this function directly
1286 * ***************************************************************************/
1287void rtl8192_phy_FinishSwChnlNow(struct net_device *dev, u8 channel)
1288{
1289 struct r8192_priv *priv = ieee80211_priv(dev);
1290 u32 delay = 0;
1291
Xenia Ragiadakoueadb1882013-06-15 07:29:05 +03001292 while (!rtl8192_phy_SwChnlStepByStep(dev,channel,&priv->SwChnlStage,&priv->SwChnlStep,&delay)) {
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001293 if (!priv->up)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001294 break;
1295 }
1296}
1297/******************************************************************************
1298 *function: Callback routine of the work item for switch channel.
1299 * input:
1300 *
1301 * output: none
1302 * return: noin
1303 * ***************************************************************************/
1304void rtl8192_SwChnl_WorkItem(struct net_device *dev)
1305{
1306
1307 struct r8192_priv *priv = ieee80211_priv(dev);
1308
1309 RT_TRACE(COMP_CH, "==> SwChnlCallback819xUsbWorkItem(), chan:%d\n", priv->chan);
1310
1311
1312 rtl8192_phy_FinishSwChnlNow(dev , priv->chan);
1313
1314 RT_TRACE(COMP_CH, "<== SwChnlCallback819xUsbWorkItem()\n");
1315}
1316
1317/******************************************************************************
Justin P. Mattock8ef3a7e2012-04-30 14:39:21 -07001318 *function: This function scheduled actual work item to set channel
Jerry Chuang8fc85982009-11-03 07:17:11 -02001319 * input: net_device dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001320 * u8 channel //channel to set
Jerry Chuang8fc85982009-11-03 07:17:11 -02001321 * output: none
1322 * return: return code show if workitem is scheduled(1:pass, 0:fail)
1323 * Note: Delay may be required for RF configuration
1324 * ***************************************************************************/
Xenia Ragiadakou88d8fe22013-05-11 17:22:22 +03001325u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001326{
1327 struct r8192_priv *priv = ieee80211_priv(dev);
1328 RT_TRACE(COMP_CH, "=====>%s(), SwChnlInProgress:%d\n", __FUNCTION__, priv->SwChnlInProgress);
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001329 if (!priv->up)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001330 return false;
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001331 if (priv->SwChnlInProgress)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001332 return false;
1333
Jerry Chuang8fc85982009-11-03 07:17:11 -02001334 //--------------------------------------------
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001335 switch (priv->ieee80211->mode) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001336 case WIRELESS_MODE_A:
1337 case WIRELESS_MODE_N_5G:
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001338 if (channel <= 14) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001339 RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14");
1340 return false;
1341 }
1342 break;
1343 case WIRELESS_MODE_B:
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001344 if (channel > 14) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001345 RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14");
1346 return false;
1347 }
1348 break;
1349 case WIRELESS_MODE_G:
1350 case WIRELESS_MODE_N_24G:
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001351 if (channel > 14) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001352 RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14");
1353 return false;
1354 }
1355 break;
1356 }
1357 //--------------------------------------------
1358
1359 priv->SwChnlInProgress = true;
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001360 if (channel == 0)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001361 channel = 1;
1362
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001363 priv->chan = channel;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001364
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001365 priv->SwChnlStage = 0;
1366 priv->SwChnlStep = 0;
Xenia Ragiadakoud75340e2013-06-15 07:29:06 +03001367 if (priv->up)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001368 rtl8192_SwChnl_WorkItem(dev);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001369
1370 priv->SwChnlInProgress = false;
1371 return true;
1372}
1373
1374
1375//
1376/******************************************************************************
1377 *function: Callback routine of the work item for set bandwidth mode.
1378 * input: struct net_device *dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001379 * HT_CHANNEL_WIDTH Bandwidth //20M or 40M
1380 * HT_EXTCHNL_OFFSET Offset //Upper, Lower, or Don't care
Jerry Chuang8fc85982009-11-03 07:17:11 -02001381 * output: none
1382 * return: none
1383 * Note: I doubt whether SetBWModeInProgress flag is necessary as we can
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001384 * test whether current work in the queue or not.//do I?
Jerry Chuang8fc85982009-11-03 07:17:11 -02001385 * ***************************************************************************/
1386void rtl8192_SetBWModeWorkItem(struct net_device *dev)
1387{
1388
1389 struct r8192_priv *priv = ieee80211_priv(dev);
1390 u8 regBwOpMode;
1391
1392 RT_TRACE(COMP_SWBW, "==>rtl8192_SetBWModeWorkItem() Switch to %s bandwidth\n", \
Xenia Ragiadakou4a8d1132013-06-09 14:38:43 +03001393 priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz");
Jerry Chuang8fc85982009-11-03 07:17:11 -02001394
1395
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001396 if (priv->rf_chip == RF_PSEUDO_11N) {
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001397 priv->SetBWModeInProgress = false;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001398 return;
1399 }
1400
1401 //<1>Set MAC register
Xenia Ragiadakoub3d42bf2013-06-06 16:40:51 +03001402 read_nic_byte(dev, BW_OPMODE, &regBwOpMode);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001403
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001404 switch (priv->CurrentChannelBW) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001405 case HT_CHANNEL_WIDTH_20:
1406 regBwOpMode |= BW_OPMODE_20MHZ;
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001407 // 2007/02/07 Mark by Emily because we have not verify whether this register works
Jerry Chuang8fc85982009-11-03 07:17:11 -02001408 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
1409 break;
1410
1411 case HT_CHANNEL_WIDTH_20_40:
1412 regBwOpMode &= ~BW_OPMODE_20MHZ;
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001413 // 2007/02/07 Mark by Emily because we have not verify whether this register works
Jerry Chuang8fc85982009-11-03 07:17:11 -02001414 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
1415 break;
1416
1417 default:
1418 RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n",priv->CurrentChannelBW);
1419 break;
1420 }
1421
1422 //<2>Set PHY related register
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001423 switch (priv->CurrentChannelBW) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001424 case HT_CHANNEL_WIDTH_20:
1425 // Add by Vivi 20071119
1426 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
1427 rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
1428 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1);
1429
1430 // Correct the tx power for CCK rate in 20M. Suggest by YN, 20071207
Jerry Chuang8fc85982009-11-03 07:17:11 -02001431 priv->cck_present_attentuation =
1432 priv->cck_present_attentuation_20Mdefault + priv->cck_present_attentuation_difference;
1433
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001434 if (priv->cck_present_attentuation > 22)
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001435 priv->cck_present_attentuation = 22;
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001436 if (priv->cck_present_attentuation < 0)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001437 priv->cck_present_attentuation = 0;
1438 RT_TRACE(COMP_INIT, "20M, pHalData->CCKPresentAttentuation = %d\n", priv->cck_present_attentuation);
1439
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001440 if (priv->chan == 14 && !priv->bcck_in_ch14) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001441 priv->bcck_in_ch14 = TRUE;
1442 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001443 } else if (priv->chan != 14 && priv->bcck_in_ch14) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001444 priv->bcck_in_ch14 = FALSE;
1445 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001446 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001447 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001448 }
Jerry Chuang8fc85982009-11-03 07:17:11 -02001449
1450 break;
1451 case HT_CHANNEL_WIDTH_20_40:
1452 // Add by Vivi 20071119
1453 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
1454 rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
1455 rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
Mauro Carvalho Chehabe4063222009-11-03 07:42:46 -02001456 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001457 rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001458 priv->cck_present_attentuation =
1459 priv->cck_present_attentuation_40Mdefault + priv->cck_present_attentuation_difference;
1460
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001461 if (priv->cck_present_attentuation > 22)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001462 priv->cck_present_attentuation = 22;
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001463 if (priv->cck_present_attentuation < 0)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001464 priv->cck_present_attentuation = 0;
1465
1466 RT_TRACE(COMP_INIT, "40M, pHalData->CCKPresentAttentuation = %d\n", priv->cck_present_attentuation);
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001467 if (priv->chan == 14 && !priv->bcck_in_ch14) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001468 priv->bcck_in_ch14 = true;
1469 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001470 } else if (priv->chan != 14 && priv->bcck_in_ch14) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001471 priv->bcck_in_ch14 = false;
1472 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001473 } else {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001474 dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001475 }
Jerry Chuang8fc85982009-11-03 07:17:11 -02001476
1477 break;
1478 default:
1479 RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n" ,priv->CurrentChannelBW);
1480 break;
1481
1482 }
1483 //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315
1484
Jerry Chuang8fc85982009-11-03 07:17:11 -02001485 //<3>Set RF related register
Xenia Ragiadakouceb56592013-06-15 07:29:07 +03001486 switch (priv->rf_chip) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001487 case RF_8225:
1488#ifdef TO_DO_LIST
1489 PHY_SetRF8225Bandwidth(Adapter, pHalData->CurrentChannelBW);
1490#endif
1491 break;
1492
1493 case RF_8256:
1494 PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW);
1495 break;
1496
1497 case RF_8258:
1498 // PHY_SetRF8258Bandwidth();
1499 break;
1500
1501 case RF_PSEUDO_11N:
1502 // Do Nothing
1503 break;
1504
1505 default:
1506 RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip);
1507 break;
1508 }
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001509 priv->SetBWModeInProgress = false;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001510
Xenia Ragiadakouceb56592013-06-15 07:29:07 +03001511 RT_TRACE(COMP_SWBW, "<==SetBWMode819xUsb(), %d", atomic_read(&(priv->ieee80211->atm_swbw)));
Jerry Chuang8fc85982009-11-03 07:17:11 -02001512}
1513
1514/******************************************************************************
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001515 *function: This function schedules bandwidth switch work.
Jerry Chuang8fc85982009-11-03 07:17:11 -02001516 * input: struct net_device *dev
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001517 * HT_CHANNEL_WIDTH Bandwidth //20M or 40M
1518 * HT_EXTCHNL_OFFSET Offset //Upper, Lower, or Don't care
Jerry Chuang8fc85982009-11-03 07:17:11 -02001519 * output: none
1520 * return: none
1521 * Note: I doubt whether SetBWModeInProgress flag is necessary as we can
Sebastian Hahn35997ff2012-12-05 21:40:18 +01001522 * test whether current work in the queue or not.//do I?
Jerry Chuang8fc85982009-11-03 07:17:11 -02001523 * ***************************************************************************/
Xenia Ragiadakou442543d2013-06-15 07:29:08 +03001524void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth,
1525 HT_EXTCHNL_OFFSET Offset)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001526{
1527 struct r8192_priv *priv = ieee80211_priv(dev);
1528
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001529 if (priv->SetBWModeInProgress)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001530 return;
Xenia Ragiadakouec5d3192013-06-18 05:29:36 +03001531 priv->SetBWModeInProgress = true;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001532
1533 priv->CurrentChannelBW = Bandwidth;
1534
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001535 if (Offset == HT_EXTCHNL_OFFSET_LOWER)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001536 priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER;
Xenia Ragiadakou9d8e79e2013-06-18 05:29:38 +03001537 else if (Offset == HT_EXTCHNL_OFFSET_UPPER)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001538 priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER;
1539 else
1540 priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1541
Jerry Chuang8fc85982009-11-03 07:17:11 -02001542 rtl8192_SetBWModeWorkItem(dev);
1543
1544}
1545
1546void InitialGain819xUsb(struct net_device *dev, u8 Operation)
1547{
1548 struct r8192_priv *priv = ieee80211_priv(dev);
1549
1550 priv->InitialGainOperateType = Operation;
1551
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001552 if (priv->up)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001553 queue_delayed_work(priv->priv_wq,&priv->initialgain_operate_wq,0);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001554}
1555
Jerry Chuang8fc85982009-11-03 07:17:11 -02001556extern void InitialGainOperateWorkItemCallBack(struct work_struct *work)
1557{
1558 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
1559 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,initialgain_operate_wq);
1560 struct net_device *dev = priv->ieee80211->dev;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001561#define SCAN_RX_INITIAL_GAIN 0x17
1562#define POWER_DETECTION_TH 0x08
1563 u32 BitMask;
1564 u8 initial_gain;
1565 u8 Operation;
1566
1567 Operation = priv->InitialGainOperateType;
1568
Xenia Ragiadakou4a6094c2013-06-15 07:29:02 +03001569 switch (Operation) {
Jerry Chuang8fc85982009-11-03 07:17:11 -02001570 case IG_Backup:
1571 RT_TRACE(COMP_SCAN, "IG_Backup, backup the initial gain.\n");
Xenia Ragiadakoud75340e2013-06-15 07:29:06 +03001572 initial_gain = SCAN_RX_INITIAL_GAIN;
Jerry Chuang8fc85982009-11-03 07:17:11 -02001573 BitMask = bMaskByte0;
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001574 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001575 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // FW DIG OFF
1576 priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, BitMask);
1577 priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, BitMask);
1578 priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, BitMask);
1579 priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, BitMask);
1580 BitMask = bMaskByte2;
1581 priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, BitMask);
1582
1583 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
1584 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
1585 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
1586 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
1587 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca);
1588
1589 RT_TRACE(COMP_SCAN, "Write scan initial gain = 0x%x \n", initial_gain);
1590 write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
1591 write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
1592 write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
1593 write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
1594 RT_TRACE(COMP_SCAN, "Write scan 0xa0a = 0x%x \n", POWER_DETECTION_TH);
1595 write_nic_byte(dev, 0xa0a, POWER_DETECTION_TH);
1596 break;
1597 case IG_Restore:
1598 RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial gain.\n");
1599 BitMask = 0x7f; //Bit0~ Bit6
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001600 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001601 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // FW DIG OFF
1602
1603 rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, BitMask, (u32)priv->initgain_backup.xaagccore1);
1604 rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, BitMask, (u32)priv->initgain_backup.xbagccore1);
1605 rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, BitMask, (u32)priv->initgain_backup.xcagccore1);
1606 rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, BitMask, (u32)priv->initgain_backup.xdagccore1);
1607 BitMask = bMaskByte2;
1608 rtl8192_setBBreg(dev, rCCK0_CCA, BitMask, (u32)priv->initgain_backup.cca);
1609
1610 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
1611 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
1612 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
1613 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
1614 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca);
1615
1616#ifdef RTL8190P
1617 SetTxPowerLevel8190(Adapter,priv->CurrentChannel);
1618#endif
1619#ifdef RTL8192E
1620 SetTxPowerLevel8190(Adapter,priv->CurrentChannel);
1621#endif
Jerry Chuang8fc85982009-11-03 07:17:11 -02001622 rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel);
Jerry Chuang8fc85982009-11-03 07:17:11 -02001623
Xenia Ragiadakou1111b872013-06-15 07:29:04 +03001624 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
Jerry Chuang8fc85982009-11-03 07:17:11 -02001625 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // FW DIG ON
1626 break;
1627 default:
1628 RT_TRACE(COMP_SCAN, "Unknown IG Operation. \n");
1629 break;
1630 }
1631}