blob: a5fc2d1cb062b3bbcd364fa28ed2fc4317312d58 [file] [log] [blame]
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001/******************************************************************************
Florian Schilhabeldc7bbaa2010-07-14 14:44:00 +02002 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 *
4 * This program is distributed in the hope that it will be useful, but WITHOUT
5 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
7 * more details.
8 *
9 * You should have received a copy of the GNU General Public License along with
10 * this program; if not, write to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
12 *
13 * The full GNU General Public License is included in this distribution in the
14 * file called LICENSE.
15 *
16 * Contact Information:
17 * wlanfae <wlanfae@realtek.com>
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070018******************************************************************************/
19#include "r8192U.h"
20#include "r8192U_dm.h"
21#include "r8192S_rtl6052.h"
22
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070023#include "r8192S_hw.h"
24#include "r8192S_phy.h"
25#include "r8192S_phyreg.h"
26#include "r8192SU_HWImg.h"
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070027
Bartlomiej Zolnierkiewicz2a7d71a2009-06-12 18:29:19 +020028#include "ieee80211/dot11d.h"
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070029
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070030/* Channel switch:The size of command tables for switch channel*/
31#define MAX_PRECMD_CNT 16
32#define MAX_RFDEPENDCMD_CNT 16
33#define MAX_POSTCMD_CNT 16
34#define MAX_DOZE_WAITING_TIMES_9x 64
35
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070036static u32
37phy_CalculateBitShift(u32 BitMask);
38static RT_STATUS
39phy_ConfigMACWithHeaderFile(struct net_device* dev);
40static void
41phy_InitBBRFRegisterDefinition(struct net_device* dev);
42static RT_STATUS
43phy_BB8192S_Config_ParaFile(struct net_device* dev);
44static RT_STATUS
45phy_ConfigBBWithHeaderFile(struct net_device* dev,u8 ConfigType);
46static bool
47phy_SetRFPowerState8192SU(struct net_device* dev,RT_RF_POWER_STATE eRFPowerState);
48void
49SetBWModeCallback8192SUsbWorkItem(struct net_device *dev);
50void
51SetBWModeCallback8192SUsbWorkItem(struct net_device *dev);
52void
53SwChnlCallback8192SUsbWorkItem(struct net_device *dev );
54static void
55phy_FinishSwChnlNow(struct net_device* dev,u8 channel);
56static bool
57phy_SwChnlStepByStep(
58 struct net_device* dev,
59 u8 channel,
60 u8 *stage,
61 u8 *step,
62 u32 *delay
63 );
64static RT_STATUS
65phy_ConfigBBWithPgHeaderFile(struct net_device* dev,u8 ConfigType);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070066static long phy_TxPwrIdxToDbm( struct net_device* dev, WIRELESS_MODE WirelessMode, u8 TxPwrIdx);
67static u8 phy_DbmToTxPwrIdx( struct net_device* dev, WIRELESS_MODE WirelessMode, long PowerInDbm);
68void phy_SetFwCmdIOCallback(struct net_device* dev);
69
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070070//
71// Description:
72// Base Band read by 4181 to make sure that operation could be done in unlimited cycle.
73//
74// Assumption:
75// - Only use on RTL8192S USB interface.
76// - PASSIVE LEVEL
77//
Jerry Chuang5f53d8c2009-05-21 22:16:02 -070078//use in phy only
79u32 phy_QueryUsbBBReg(struct net_device* dev, u32 RegAddr)
80{
81 struct r8192_priv *priv = ieee80211_priv(dev);
82 u32 ReturnValue = 0xffffffff;
83 u8 PollingCnt = 50;
84 u8 BBWaitCounter = 0;
85
86
87 //
88 // <Roger_Notes> Due to PASSIVE_LEVEL, so we ONLY simply busy waiting for a while here.
89 // We have to make sure that previous BB I/O has been done.
90 // 2008.08.20.
91 //
92 while(priv->bChangeBBInProgress)
93 {
94 BBWaitCounter ++;
95 RT_TRACE(COMP_RF, "phy_QueryUsbBBReg(): Wait 1 ms (%d times)...\n", BBWaitCounter);
96 msleep(1); // 1 ms
97
98 // Wait too long, return FALSE to avoid to be stuck here.
Florian Schilhabeldc7bbaa2010-07-14 14:44:00 +020099 if((BBWaitCounter > 100) )
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700100 {
101 RT_TRACE(COMP_RF, "phy_QueryUsbBBReg(): (%d) Wait too logn to query BB!!\n", BBWaitCounter);
102 return ReturnValue;
103 }
104 }
105
106 priv->bChangeBBInProgress = true;
107
108 read_nic_dword(dev, RegAddr);
109
110 do
111 {// Make sure that access could be done.
112 if((read_nic_byte(dev, PHY_REG)&HST_RDBUSY) == 0)
113 break;
114 }while( --PollingCnt );
115
116 if(PollingCnt == 0)
117 {
118 RT_TRACE(COMP_RF, "Fail!!!phy_QueryUsbBBReg(): RegAddr(%#x) = %#x\n", RegAddr, ReturnValue);
119 }
120 else
121 {
122 // Data FW read back.
123 ReturnValue = read_nic_dword(dev, PHY_REG_DATA);
124 RT_TRACE(COMP_RF, "phy_QueryUsbBBReg(): RegAddr(%#x) = %#x, PollingCnt(%d)\n", RegAddr, ReturnValue, PollingCnt);
125 }
126
127 priv->bChangeBBInProgress = false;
128
129 return ReturnValue;
130}
131
132
133
134//
135// Description:
136// Base Band wrote by 4181 to make sure that operation could be done in unlimited cycle.
137//
138// Assumption:
139// - Only use on RTL8192S USB interface.
140// - PASSIVE LEVEL
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700141//use in phy only
142void
143phy_SetUsbBBReg(struct net_device* dev,u32 RegAddr,u32 Data)
144{
145 struct r8192_priv *priv = ieee80211_priv(dev);
146 u8 BBWaitCounter = 0;
147
148 RT_TRACE(COMP_RF, "phy_SetUsbBBReg(): RegAddr(%#x) <= %#x\n", RegAddr, Data);
149
150 //
151 // <Roger_Notes> Due to PASSIVE_LEVEL, so we ONLY simply busy waiting for a while here.
152 // We have to make sure that previous BB I/O has been done.
153 // 2008.08.20.
154 //
155 while(priv->bChangeBBInProgress)
156 {
157 BBWaitCounter ++;
158 RT_TRACE(COMP_RF, "phy_SetUsbBBReg(): Wait 1 ms (%d times)...\n", BBWaitCounter);
159 msleep(1); // 1 ms
160
161 if((BBWaitCounter > 100))// || RT_USB_CANNOT_IO(Adapter))
162 {
163 RT_TRACE(COMP_RF, "phy_SetUsbBBReg(): (%d) Wait too logn to query BB!!\n", BBWaitCounter);
164 return;
165 }
166 }
167
168 priv->bChangeBBInProgress = true;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700169 write_nic_dword(dev, RegAddr, Data);
170
171 priv->bChangeBBInProgress = false;
172}
173
174
175
176//
177// Description:
178// RF read by 4181 to make sure that operation could be done in unlimited cycle.
179//
180// Assumption:
181// - Only use on RTL8192S USB interface.
182// - PASSIVE LEVEL
183// - RT_RF_OPERATE_SPINLOCK is acquired and keep on holding to the end.FIXLZM
184//
185// Created by Roger, 2008.09.06.
186//
187//use in phy only
188u32 phy_QueryUsbRFReg( struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset)
189{
190
191 struct r8192_priv *priv = ieee80211_priv(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700192 u32 ReturnValue = 0;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700193 u8 PollingCnt = 50;
194 u8 RFWaitCounter = 0;
195
196
197 //
198 // <Roger_Notes> Due to PASSIVE_LEVEL, so we ONLY simply busy waiting for a while here.
199 // We have to make sure that previous RF I/O has been done.
200 // 2008.08.20.
201 //
202 while(priv->bChangeRFInProgress)
203 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700204 down(&priv->rf_sem);
205
206 RFWaitCounter ++;
207 RT_TRACE(COMP_RF, "phy_QueryUsbRFReg(): Wait 1 ms (%d times)...\n", RFWaitCounter);
208 msleep(1); // 1 ms
209
210 if((RFWaitCounter > 100)) //|| RT_USB_CANNOT_IO(Adapter))
211 {
212 RT_TRACE(COMP_RF, "phy_QueryUsbRFReg(): (%d) Wait too logn to query BB!!\n", RFWaitCounter);
213 return 0xffffffff;
214 }
215 else
216 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700217 }
218 }
219
220 priv->bChangeRFInProgress = true;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700221 Offset &= 0x3f; //RF_Offset= 0x00~0x3F
222
223 write_nic_dword(dev, RF_BB_CMD_ADDR, 0xF0000002|
224 (Offset<<8)| //RF_Offset= 0x00~0x3F
225 (eRFPath<<16)); //RF_Path = 0(A) or 1(B)
226
227 do
228 {// Make sure that access could be done.
229 if(read_nic_dword(dev, RF_BB_CMD_ADDR) == 0)
230 break;
231 }while( --PollingCnt );
232
233 // Data FW read back.
234 ReturnValue = read_nic_dword(dev, RF_BB_CMD_DATA);
235
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700236 up(&priv->rf_sem);
237 priv->bChangeRFInProgress = false;
238
239 RT_TRACE(COMP_RF, "phy_QueryUsbRFReg(): eRFPath(%d), Offset(%#x) = %#x\n", eRFPath, Offset, ReturnValue);
240
241 return ReturnValue;
242
243}
244
245
246//
247// Description:
248// RF wrote by 4181 to make sure that operation could be done in unlimited cycle.
249//
250// Assumption:
251// - Only use on RTL8192S USB interface.
252// - PASSIVE LEVEL
253// - RT_RF_OPERATE_SPINLOCK is acquired and keep on holding to the end.FIXLZM
254//
255// Created by Roger, 2008.09.06.
256//
257//use in phy only
258void phy_SetUsbRFReg(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32 RegAddr,u32 Data)
259{
260
261 struct r8192_priv *priv = ieee80211_priv(dev);
262 u8 PollingCnt = 50;
263 u8 RFWaitCounter = 0;
264
265
266 //
267 // <Roger_Notes> Due to PASSIVE_LEVEL, so we ONLY simply busy waiting for a while here.
268 // We have to make sure that previous BB I/O has been done.
269 // 2008.08.20.
270 //
271 while(priv->bChangeRFInProgress)
272 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700273 down(&priv->rf_sem);
274
275 RFWaitCounter ++;
276 RT_TRACE(COMP_RF, "phy_SetUsbRFReg(): Wait 1 ms (%d times)...\n", RFWaitCounter);
277 msleep(1); // 1 ms
278
Florian Schilhabel0825c402010-07-14 14:44:18 +0200279 if((RFWaitCounter > 100))
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700280 {
281 RT_TRACE(COMP_RF, "phy_SetUsbRFReg(): (%d) Wait too logn to query BB!!\n", RFWaitCounter);
282 return;
283 }
284 else
285 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700286 }
287 }
288
289 priv->bChangeRFInProgress = true;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700290
291
292 RegAddr &= 0x3f; //RF_Offset= 0x00~0x3F
293
294 write_nic_dword(dev, RF_BB_CMD_DATA, Data);
295 write_nic_dword(dev, RF_BB_CMD_ADDR, 0xF0000003|
296 (RegAddr<<8)| //RF_Offset= 0x00~0x3F
297 (eRFPath<<16)); //RF_Path = 0(A) or 1(B)
298
299 do
300 {// Make sure that access could be done.
301 if(read_nic_dword(dev, RF_BB_CMD_ADDR) == 0)
302 break;
303 }while( --PollingCnt );
304
305 if(PollingCnt == 0)
306 {
307 RT_TRACE(COMP_RF, "phy_SetUsbRFReg(): Set RegAddr(%#x) = %#x Fail!!!\n", RegAddr, Data);
308 }
309
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700310 up(&priv->rf_sem);
311 priv->bChangeRFInProgress = false;
312
313}
314
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700315//
316// 1. BB register R/W API
317//
318/**
319* Function: PHY_QueryBBReg
320*
321* OverView: Read "sepcific bits" from BB register
322*
323* Input:
324* PADAPTER Adapter,
325* u32 RegAddr, //The target address to be readback
326* u32 BitMask //The target bit position in the target address
327* //to be readback
328* Output: None
329* Return: u32 Data //The readback register value
330* Note: This function is equal to "GetRegSetting" in PHY programming guide
331*/
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700332u32 rtl8192_QueryBBReg(struct net_device* dev, u32 RegAddr, u32 BitMask)
333{
334
335 u32 ReturnValue = 0, OriginalValue, BitShift;
336
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700337
338 RT_TRACE(COMP_RF, "--->PHY_QueryBBReg(): RegAddr(%#x), BitMask(%#x)\n", RegAddr, BitMask);
339
340 //
341 // <Roger_Notes> Due to 8051 operation cycle (limitation cycle: 6us) and 1-Byte access issue, we should use
342 // 4181 to access Base Band instead of 8051 on USB interface to make sure that access could be done in
343 // infinite cycle.
344 // 2008.09.06.
345 //
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700346 if(IS_BB_REG_OFFSET_92S(RegAddr))
347 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700348
349 if((RegAddr & 0x03) != 0)
350 {
351 printk("%s: Not DWORD alignment!!\n", __FUNCTION__);
352 return 0;
353 }
354
355 OriginalValue = phy_QueryUsbBBReg(dev, RegAddr);
356 }
357 else
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700358 {
359 OriginalValue = read_nic_dword(dev, RegAddr);
360 }
361
362 BitShift = phy_CalculateBitShift(BitMask);
363 ReturnValue = (OriginalValue & BitMask) >> BitShift;
364
Florian Schilhabeldc7bbaa2010-07-14 14:44:00 +0200365
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700366 RT_TRACE(COMP_RF, "<---PHY_QueryBBReg(): RegAddr(%#x), BitMask(%#x), OriginalValue(%#x)\n", RegAddr, BitMask, OriginalValue);
367 return (ReturnValue);
368}
369
370/**
371* Function: PHY_SetBBReg
372*
373* OverView: Write "Specific bits" to BB register (page 8~)
374*
375* Input:
376* PADAPTER Adapter,
377* u32 RegAddr, //The target address to be modified
378* u32 BitMask //The target bit position in the target address
379* //to be modified
380* u32 Data //The new register value in the target bit position
381* //of the target address
382*
383* Output: None
384* Return: None
385* Note: This function is equal to "PutRegSetting" in PHY programming guide
386*/
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700387void rtl8192_setBBreg(struct net_device* dev, u32 RegAddr, u32 BitMask, u32 Data)
388{
389 u32 OriginalValue, BitShift, NewValue;
390
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700391
392 RT_TRACE(COMP_RF, "--->PHY_SetBBReg(): RegAddr(%#x), BitMask(%#x), Data(%#x)\n", RegAddr, BitMask, Data);
393
394 //
395 // <Roger_Notes> Due to 8051 operation cycle (limitation cycle: 6us) and 1-Byte access issue, we should use
396 // 4181 to access Base Band instead of 8051 on USB interface to make sure that access could be done in
397 // infinite cycle.
398 // 2008.09.06.
399 //
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700400 if(IS_BB_REG_OFFSET_92S(RegAddr))
401 {
402 if((RegAddr & 0x03) != 0)
403 {
404 printk("%s: Not DWORD alignment!!\n", __FUNCTION__);
405 return;
406 }
407
408 if(BitMask!= bMaskDWord)
409 {//if not "double word" write
410 OriginalValue = phy_QueryUsbBBReg(dev, RegAddr);
411 BitShift = phy_CalculateBitShift(BitMask);
412 NewValue = (((OriginalValue) & (~BitMask))|(Data << BitShift));
413 phy_SetUsbBBReg(dev, RegAddr, NewValue);
414 }else
415 phy_SetUsbBBReg(dev, RegAddr, Data);
416 }
417 else
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700418 {
419 if(BitMask!= bMaskDWord)
420 {//if not "double word" write
421 OriginalValue = read_nic_dword(dev, RegAddr);
422 BitShift = phy_CalculateBitShift(BitMask);
423 NewValue = (((OriginalValue) & (~BitMask)) | (Data << BitShift));
424 write_nic_dword(dev, RegAddr, NewValue);
425 }else
426 write_nic_dword(dev, RegAddr, Data);
427 }
428
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700429
430 return;
431}
432
433
434//
435// 2. RF register R/W API
436//
437/**
438* Function: PHY_QueryRFReg
439*
440* OverView: Query "Specific bits" to RF register (page 8~)
441*
442* Input:
443* PADAPTER Adapter,
444* RF90_RADIO_PATH_E eRFPath, //Radio path of A/B/C/D
445* u32 RegAddr, //The target address to be read
446* u32 BitMask //The target bit position in the target address
447* //to be read
448*
449* Output: None
450* Return: u32 Readback value
451* Note: This function is equal to "GetRFRegSetting" in PHY programming guide
452*/
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700453u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask)
454{
455 u32 Original_Value, Readback_Value, BitShift;//, flags;
456 struct r8192_priv *priv = ieee80211_priv(dev);
457
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700458
459 RT_TRACE(COMP_RF, "--->PHY_QueryRFReg(): RegAddr(%#x), eRFPath(%#x), BitMask(%#x)\n", RegAddr, eRFPath,BitMask);
460
461 if (!((priv->rf_pathmap >> eRFPath) & 0x1))
462 {
463 printk("EEEEEError: rfpath off! rf_pathmap=%x eRFPath=%x\n", priv->rf_pathmap, eRFPath);
464 return 0;
465 }
466
467 if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
468 {
469 printk("EEEEEError: not legal rfpath! eRFPath=%x\n", eRFPath);
470 return 0;
471 }
472
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700473 down(&priv->rf_sem);
474 //
475 // <Roger_Notes> Due to 8051 operation cycle (limitation cycle: 6us) and 1-Byte access issue, we should use
476 // 4181 to access Base Band instead of 8051 on USB interface to make sure that access could be done in
477 // infinite cycle.
478 // 2008.09.06.
479 //
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700480 Original_Value = phy_QueryUsbRFReg(dev, eRFPath, RegAddr);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700481
482 BitShift = phy_CalculateBitShift(BitMask);
483 Readback_Value = (Original_Value & BitMask) >> BitShift;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700484 up(&priv->rf_sem);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700485
486 return (Readback_Value);
487}
488
489/**
490* Function: PHY_SetRFReg
491*
492* OverView: Write "Specific bits" to RF register (page 8~)
493*
494* Input:
495* PADAPTER Adapter,
496* RF90_RADIO_PATH_E eRFPath, //Radio path of A/B/C/D
497* u32 RegAddr, //The target address to be modified
498* u32 BitMask //The target bit position in the target address
499* //to be modified
500* u32 Data //The new register Data in the target bit position
501* //of the target address
502*
503* Output: None
504* Return: None
505* Note: This function is equal to "PutRFRegSetting" in PHY programming guide
506*/
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700507void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data)
508{
509
510 struct r8192_priv *priv = ieee80211_priv(dev);
511 u32 Original_Value, BitShift, New_Value;//, flags;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700512
513 RT_TRACE(COMP_RF, "--->PHY_SetRFReg(): RegAddr(%#x), BitMask(%#x), Data(%#x), eRFPath(%#x)\n",
514 RegAddr, BitMask, Data, eRFPath);
515
516 if (!((priv->rf_pathmap >> eRFPath) & 0x1))
517 {
518 printk("EEEEEError: rfpath off! rf_pathmap=%x eRFPath=%x\n", priv->rf_pathmap, eRFPath);
519 return ;
520 }
521 if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
522 {
523 printk("EEEEEError: not legal rfpath! eRFPath=%x\n", eRFPath);
524 return;
525 }
526
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700527 down(&priv->rf_sem);
528 //
529 // <Roger_Notes> Due to 8051 operation cycle (limitation cycle: 6us) and 1-Byte access issue, we should use
530 // 4181 to access Base Band instead of 8051 on USB interface to make sure that access could be done in
531 // infinite cycle.
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700532
533 if (BitMask != bRFRegOffsetMask) // RF data is 12 bits only
534 {
535 Original_Value = phy_QueryUsbRFReg(dev, eRFPath, RegAddr);
536 BitShift = phy_CalculateBitShift(BitMask);
537 New_Value = (((Original_Value)&(~BitMask))|(Data<< BitShift));
538 phy_SetUsbRFReg(dev, eRFPath, RegAddr, New_Value);
539 }
540 else
541 phy_SetUsbRFReg(dev, eRFPath, RegAddr, Data);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700542 up(&priv->rf_sem);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700543 RT_TRACE(COMP_RF, "<---PHY_SetRFReg(): RegAddr(%#x), BitMask(%#x), Data(%#x), eRFPath(%#x)\n",
544 RegAddr, BitMask, Data, eRFPath);
545
546}
547
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700548/**
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700549* Function: phy_CalculateBitShift
550*
551* OverView: Get shifted position of the BitMask
552*
553* Input:
554* u32 BitMask,
555*
556* Output: none
557* Return: u32 Return the shift bit bit position of the mask
558*/
559//use in phy only
560static u32 phy_CalculateBitShift(u32 BitMask)
561{
562 u32 i;
563
564 for(i=0; i<=31; i++)
565 {
566 if ( ((BitMask>>i) & 0x1 ) == 1)
567 break;
568 }
569
570 return (i);
571}
572
573
574//
575// 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt.
576//
577/*-----------------------------------------------------------------------------
578 * Function: PHY_MACConfig8192S
579 *
580 * Overview: Condig MAC by header file or parameter file.
581 *
582 * Input: NONE
583 *
584 * Output: NONE
585 *
586 * Return: NONE
587 *
588 * Revised History:
589 * When Who Remark
590 * 08/12/2008 MHC Create Version 0.
591 *
592 *---------------------------------------------------------------------------*/
593//adapter_start
594extern bool PHY_MACConfig8192S(struct net_device* dev)
595{
596 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
597
598 //
599 // Config MAC
600 //
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700601 rtStatus = phy_ConfigMACWithHeaderFile(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700602 return (rtStatus == RT_STATUS_SUCCESS) ? true:false;
603
604}
605
606//adapter_start
607extern bool
608PHY_BBConfig8192S(struct net_device* dev)
609{
610 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
611
612 u8 PathMap = 0, index = 0, rf_num = 0;
613 struct r8192_priv *priv = ieee80211_priv(dev);
614 phy_InitBBRFRegisterDefinition(dev);
615
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700616
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700617 rtStatus = phy_BB8192S_Config_ParaFile(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700618
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700619 PathMap = (u8)(rtl8192_QueryBBReg(dev, rFPGA0_TxInfo, 0xf) |
620 rtl8192_QueryBBReg(dev, rOFDM0_TRxPathEnable, 0xf));
621 priv->rf_pathmap = PathMap;
622 for(index = 0; index<4; index++)
623 {
624 if((PathMap>>index)&0x1)
625 rf_num++;
626 }
627
628 if((priv->rf_type==RF_1T1R && rf_num!=1) ||
629 (priv->rf_type==RF_1T2R && rf_num!=2) ||
630 (priv->rf_type==RF_2T2R && rf_num!=2) ||
631 (priv->rf_type==RF_2T2R_GREEN && rf_num!=2) ||
632 (priv->rf_type==RF_2T4R && rf_num!=4))
633 {
634 RT_TRACE( COMP_INIT, "PHY_BBConfig8192S: RF_Type(%x) does not match RF_Num(%x)!!\n", priv->rf_type, rf_num);
635 }
636 return (rtStatus == RT_STATUS_SUCCESS) ? 1:0;
637}
638
639//adapter_start
640extern bool
641PHY_RFConfig8192S(struct net_device* dev)
642{
643 struct r8192_priv *priv = ieee80211_priv(dev);
644 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
645
646 //Set priv->rf_chip = RF_8225 to do real PHY FPGA initilization
647
648 //<Roger_EXP> We assign RF type here temporally. 2008.09.12.
649 priv->rf_chip = RF_6052;
650
651 //
652 // RF config
653 //
654 switch(priv->rf_chip)
655 {
656 case RF_8225:
657 case RF_6052:
658 rtStatus = PHY_RF6052_Config(dev);
659 break;
660
661 case RF_8256:
662 //rtStatus = PHY_RF8256_Config(dev);
663 break;
664
665 case RF_8258:
666 break;
667
668 case RF_PSEUDO_11N:
669 //rtStatus = PHY_RF8225_Config(dev);
670 break;
671 default:
672 break;
673 }
674
675 return (rtStatus == RT_STATUS_SUCCESS) ? 1:0;
676}
677
678
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700679#ifdef TO_DO_LIST
680static RT_STATUS
681phy_BB8190_Config_HardCode(struct net_device* dev)
682{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700683 return RT_STATUS_SUCCESS;
684}
685#endif
686
687/*-----------------------------------------------------------------------------
688 * Function: phy_SetBBtoDiffRFWithHeaderFile()
689 *
690 * Overview: This function
691 *
692 *
693 * Input: PADAPTER Adapter
694 * u1Byte ConfigType 0 => PHY_CONFIG
695 *
696 * Output: NONE
697 *
698 * Return: RT_STATUS_SUCCESS: configuration file exist
699 * When Who Remark
700 * 2008/11/10 tynli
701 * use in phy only
702 *---------------------------------------------------------------------------*/
703static RT_STATUS
704phy_SetBBtoDiffRFWithHeaderFile(struct net_device* dev, u8 ConfigType)
705{
706 int i;
707 struct r8192_priv *priv = ieee80211_priv(dev);
708 u32* Rtl819XPHY_REGArraytoXTXR_Table;
709 u16 PHY_REGArraytoXTXRLen;
710
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700711
712 if(priv->rf_type == RF_1T1R)
713 {
714 Rtl819XPHY_REGArraytoXTXR_Table = Rtl819XPHY_REG_to1T1R_Array;
715 PHY_REGArraytoXTXRLen = PHY_ChangeTo_1T1RArrayLength;
716 }
717 else if(priv->rf_type == RF_1T2R)
718 {
719 Rtl819XPHY_REGArraytoXTXR_Table = Rtl819XPHY_REG_to1T2R_Array;
720 PHY_REGArraytoXTXRLen = PHY_ChangeTo_1T2RArrayLength;
721 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700722 else
723 {
724 return RT_STATUS_FAILURE;
725 }
726
727 if(ConfigType == BaseBand_Config_PHY_REG)
728 {
729 for(i=0;i<PHY_REGArraytoXTXRLen;i=i+3)
730 {
731 if (Rtl819XPHY_REGArraytoXTXR_Table[i] == 0xfe)
732 mdelay(50);
733 else if (Rtl819XPHY_REGArraytoXTXR_Table[i] == 0xfd)
734 mdelay(5);
735 else if (Rtl819XPHY_REGArraytoXTXR_Table[i] == 0xfc)
736 mdelay(1);
737 else if (Rtl819XPHY_REGArraytoXTXR_Table[i] == 0xfb)
738 udelay(50);
739 else if (Rtl819XPHY_REGArraytoXTXR_Table[i] == 0xfa)
740 udelay(5);
741 else if (Rtl819XPHY_REGArraytoXTXR_Table[i] == 0xf9)
742 udelay(1);
743 rtl8192_setBBreg(dev, Rtl819XPHY_REGArraytoXTXR_Table[i], Rtl819XPHY_REGArraytoXTXR_Table[i+1], Rtl819XPHY_REGArraytoXTXR_Table[i+2]);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700744 }
745 }
746 else {
747 RT_TRACE(COMP_SEND, "phy_SetBBtoDiffRFWithHeaderFile(): ConfigType != BaseBand_Config_PHY_REG\n");
748 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700749 return RT_STATUS_SUCCESS;
750}
751
752
753//use in phy only
754static RT_STATUS
755phy_BB8192S_Config_ParaFile(struct net_device* dev)
756{
757 struct r8192_priv *priv = ieee80211_priv(dev);
758 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700759
760 RT_TRACE(COMP_INIT, "==>phy_BB8192S_Config_ParaFile\n");
761
762 //
763 // 1. Read PHY_REG.TXT BB INIT!!
Anand Gadiyar935e99f2010-05-12 13:03:13 +0530764 // We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700765 //
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700766 if (priv->rf_type == RF_1T2R || priv->rf_type == RF_2T2R ||
767 priv->rf_type == RF_1T1R ||priv->rf_type == RF_2T2R_GREEN)
768 {
769 rtStatus = phy_ConfigBBWithHeaderFile(dev,BaseBand_Config_PHY_REG);
770 if(priv->rf_type != RF_2T2R && priv->rf_type != RF_2T2R_GREEN)
771 {//2008.11.10 Added by tynli. The default PHY_REG.txt we read is for 2T2R,
772 //so we should reconfig BB reg with the right PHY parameters.
773 rtStatus = phy_SetBBtoDiffRFWithHeaderFile(dev,BaseBand_Config_PHY_REG);
774 }
775 }else
776 rtStatus = RT_STATUS_FAILURE;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700777
778 if(rtStatus != RT_STATUS_SUCCESS){
779 RT_TRACE(COMP_INIT, "phy_BB8192S_Config_ParaFile():Write BB Reg Fail!!");
780 goto phy_BB8190_Config_ParaFile_Fail;
781 }
782
783 //
784 // 2. If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt
785 //
786 if (priv->AutoloadFailFlag == false)
787 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700788 rtStatus = phy_ConfigBBWithPgHeaderFile(dev,BaseBand_Config_PHY_REG);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700789 }
790 if(rtStatus != RT_STATUS_SUCCESS){
791 RT_TRACE(COMP_INIT, "phy_BB8192S_Config_ParaFile():BB_PG Reg Fail!!");
792 goto phy_BB8190_Config_ParaFile_Fail;
793 }
794
795 //
796 // 3. BB AGC table Initialization
797 //
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700798 rtStatus = phy_ConfigBBWithHeaderFile(dev,BaseBand_Config_AGC_TAB);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700799
800 if(rtStatus != RT_STATUS_SUCCESS){
801 printk( "phy_BB8192S_Config_ParaFile():AGC Table Fail\n");
802 goto phy_BB8190_Config_ParaFile_Fail;
803 }
804
805
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700806 // Check if the CCK HighPower is turned ON.
807 // This is used to calculate PWDB.
808 priv->bCckHighPower = (bool)(rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter2, 0x200));
809
810
811phy_BB8190_Config_ParaFile_Fail:
812 return rtStatus;
813}
814
815/*-----------------------------------------------------------------------------
816 * Function: phy_ConfigMACWithHeaderFile()
817 *
818 * Overview: This function read BB parameters from Header file we gen, and do register
819 * Read/Write
820 *
821 * Input: PADAPTER Adapter
822 * char* pFileName
823 *
824 * Output: NONE
825 *
826 * Return: RT_STATUS_SUCCESS: configuration file exist
827 *
828 * Note: The format of MACPHY_REG.txt is different from PHY and RF.
829 * [Register][Mask][Value]
830 *---------------------------------------------------------------------------*/
831//use in phy only
832static RT_STATUS
833phy_ConfigMACWithHeaderFile(struct net_device* dev)
834{
835 u32 i = 0;
836 u32 ArrayLength = 0;
837 u32* ptrArray;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700838
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700839 { //2008.11.06 Modified by tynli.
840 RT_TRACE(COMP_INIT, "Read Rtl819XMACPHY_Array\n");
841 ArrayLength = MAC_2T_ArrayLength;
842 ptrArray = Rtl819XMAC_Array;
843 }
844
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700845 for(i = 0 ;i < ArrayLength;i=i+2){ // Add by tynli for 2 column
846 write_nic_byte(dev, ptrArray[i], (u8)ptrArray[i+1]);
847 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700848 return RT_STATUS_SUCCESS;
849}
850
851/*-----------------------------------------------------------------------------
852 * Function: phy_ConfigBBWithHeaderFile()
853 *
854 * Overview: This function read BB parameters from general file format, and do register
855 * Read/Write
856 *
857 * Input: PADAPTER Adapter
858 * u8 ConfigType 0 => PHY_CONFIG
859 * 1 =>AGC_TAB
860 *
861 * Output: NONE
862 *
863 * Return: RT_STATUS_SUCCESS: configuration file exist
864 *
865 *---------------------------------------------------------------------------*/
866//use in phy only
867static RT_STATUS
868phy_ConfigBBWithHeaderFile(struct net_device* dev,u8 ConfigType)
869{
870 int i;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700871 u32* Rtl819XPHY_REGArray_Table;
872 u32* Rtl819XAGCTAB_Array_Table;
873 u16 PHY_REGArrayLen, AGCTAB_ArrayLen;
Florian Schilhabeldc7bbaa2010-07-14 14:44:00 +0200874
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700875 AGCTAB_ArrayLen = AGCTAB_ArrayLength;
876 Rtl819XAGCTAB_Array_Table = Rtl819XAGCTAB_Array;
877 PHY_REGArrayLen = PHY_REG_2T2RArrayLength; // Default RF_type: 2T2R
878 Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_Array;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700879
880 if(ConfigType == BaseBand_Config_PHY_REG)
881 {
882 for(i=0;i<PHY_REGArrayLen;i=i+2)
883 {
884 if (Rtl819XPHY_REGArray_Table[i] == 0xfe)
885 mdelay(50);
886 else if (Rtl819XPHY_REGArray_Table[i] == 0xfd)
887 mdelay(5);
888 else if (Rtl819XPHY_REGArray_Table[i] == 0xfc)
889 mdelay(1);
890 else if (Rtl819XPHY_REGArray_Table[i] == 0xfb)
891 udelay(50);
892 else if (Rtl819XPHY_REGArray_Table[i] == 0xfa)
893 udelay(5);
894 else if (Rtl819XPHY_REGArray_Table[i] == 0xf9)
895 udelay(1);
896 rtl8192_setBBreg(dev, Rtl819XPHY_REGArray_Table[i], bMaskDWord, Rtl819XPHY_REGArray_Table[i+1]);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700897
898 }
899 }
900 else if(ConfigType == BaseBand_Config_AGC_TAB){
901 for(i=0;i<AGCTAB_ArrayLen;i=i+2)
902 {
903 rtl8192_setBBreg(dev, Rtl819XAGCTAB_Array_Table[i], bMaskDWord, Rtl819XAGCTAB_Array_Table[i+1]);
904 }
905 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700906 return RT_STATUS_SUCCESS;
907}
908
909/*-----------------------------------------------------------------------------
910 * Function: phy_ConfigBBWithPgHeaderFile
911 *
912 * Overview: Config PHY_REG_PG array
913 *
914 * Input: NONE
915 *
916 * Output: NONE
917 *
918 * Return: NONE
919 *
920 * Revised History:
921 * When Who Remark
922 * 11/06/2008 MHC Add later!!!!!!.. Please modify for new files!!!!
923 * 11/10/2008 tynli Modify to mew files.
924 //use in phy only
925 *---------------------------------------------------------------------------*/
926static RT_STATUS
927phy_ConfigBBWithPgHeaderFile(struct net_device* dev,u8 ConfigType)
928{
929 int i;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700930 u32* Rtl819XPHY_REGArray_Table_PG;
931 u16 PHY_REGArrayPGLen;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700932
933 PHY_REGArrayPGLen = PHY_REG_Array_PGLength;
934 Rtl819XPHY_REGArray_Table_PG = Rtl819XPHY_REG_Array_PG;
935
936 if(ConfigType == BaseBand_Config_PHY_REG)
937 {
938 for(i=0;i<PHY_REGArrayPGLen;i=i+3)
939 {
940 if (Rtl819XPHY_REGArray_Table_PG[i] == 0xfe)
941 mdelay(50);
942 else if (Rtl819XPHY_REGArray_Table_PG[i] == 0xfd)
943 mdelay(5);
944 else if (Rtl819XPHY_REGArray_Table_PG[i] == 0xfc)
945 mdelay(1);
946 else if (Rtl819XPHY_REGArray_Table_PG[i] == 0xfb)
947 udelay(50);
948 else if (Rtl819XPHY_REGArray_Table_PG[i] == 0xfa)
949 udelay(5);
950 else if (Rtl819XPHY_REGArray_Table_PG[i] == 0xf9)
951 udelay(1);
952 rtl8192_setBBreg(dev, Rtl819XPHY_REGArray_Table_PG[i], Rtl819XPHY_REGArray_Table_PG[i+1], Rtl819XPHY_REGArray_Table_PG[i+2]);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700953 }
954 }else{
955 RT_TRACE(COMP_SEND, "phy_ConfigBBWithPgHeaderFile(): ConfigType != BaseBand_Config_PHY_REG\n");
956 }
957 return RT_STATUS_SUCCESS;
958
Florian Schilhabeldc7bbaa2010-07-14 14:44:00 +0200959}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700960
961/*-----------------------------------------------------------------------------
962 * Function: PHY_ConfigRFWithHeaderFile()
963 *
964 * Overview: This function read RF parameters from general file format, and do RF 3-wire
965 *
966 * Input: PADAPTER Adapter
967 * char* pFileName
968 * RF90_RADIO_PATH_E eRFPath
969 *
970 * Output: NONE
971 *
972 * Return: RT_STATUS_SUCCESS: configuration file exist
973 *
974 * Note: Delay may be required for RF configuration
975 *---------------------------------------------------------------------------*/
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700976u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E eRFPath)
977{
978
979 struct r8192_priv *priv = ieee80211_priv(dev);
980 int i;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700981 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
982 u32 *Rtl819XRadioA_Array_Table;
983 u32 *Rtl819XRadioB_Array_Table;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -0700984 u16 RadioA_ArrayLen,RadioB_ArrayLen;
985
986 { //2008.11.06 Modified by tynli
987 RadioA_ArrayLen = RadioA_1T_ArrayLength;
988 Rtl819XRadioA_Array_Table=Rtl819XRadioA_Array;
989 Rtl819XRadioB_Array_Table=Rtl819XRadioB_Array;
990 RadioB_ArrayLen = RadioB_ArrayLength;
991 }
992
993 if( priv->rf_type == RF_2T2R_GREEN )
994 {
995 Rtl819XRadioB_Array_Table = Rtl819XRadioB_GM_Array;
996 RadioB_ArrayLen = RadioB_GM_ArrayLength;
997 }
998 else
999 {
1000 Rtl819XRadioB_Array_Table = Rtl819XRadioB_Array;
1001 RadioB_ArrayLen = RadioB_ArrayLength;
1002 }
1003
1004 rtStatus = RT_STATUS_SUCCESS;
1005
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001006
1007 switch(eRFPath){
1008 case RF90_PATH_A:
1009 for(i = 0;i<RadioA_ArrayLen; i=i+2){
1010 if(Rtl819XRadioA_Array_Table[i] == 0xfe)
1011 { // Deay specific ms. Only RF configuration require delay.
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001012 mdelay(1000);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001013 }
1014 else if (Rtl819XRadioA_Array_Table[i] == 0xfd)
1015 mdelay(5);
1016 else if (Rtl819XRadioA_Array_Table[i] == 0xfc)
1017 mdelay(1);
1018 else if (Rtl819XRadioA_Array_Table[i] == 0xfb)
1019 udelay(50);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001020 else if (Rtl819XRadioA_Array_Table[i] == 0xfa)
1021 udelay(5);
1022 else if (Rtl819XRadioA_Array_Table[i] == 0xf9)
1023 udelay(1);
1024 else
1025 {
1026 rtl8192_phy_SetRFReg(dev, eRFPath, Rtl819XRadioA_Array_Table[i], bRFRegOffsetMask, Rtl819XRadioA_Array_Table[i+1]);
1027 }
1028 }
1029 break;
1030 case RF90_PATH_B:
1031 for(i = 0;i<RadioB_ArrayLen; i=i+2){
1032 if(Rtl819XRadioB_Array_Table[i] == 0xfe)
1033 { // Deay specific ms. Only RF configuration require delay.
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001034 mdelay(1000);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001035 }
1036 else if (Rtl819XRadioB_Array_Table[i] == 0xfd)
1037 mdelay(5);
1038 else if (Rtl819XRadioB_Array_Table[i] == 0xfc)
1039 mdelay(1);
1040 else if (Rtl819XRadioB_Array_Table[i] == 0xfb)
1041 udelay(50);
1042 else if (Rtl819XRadioB_Array_Table[i] == 0xfa)
1043 udelay(5);
1044 else if (Rtl819XRadioB_Array_Table[i] == 0xf9)
1045 udelay(1);
1046 else
1047 {
1048 rtl8192_phy_SetRFReg(dev, eRFPath, Rtl819XRadioB_Array_Table[i], bRFRegOffsetMask, Rtl819XRadioB_Array_Table[i+1]);
1049 }
1050 }
1051 break;
1052 case RF90_PATH_C:
1053 break;
1054 case RF90_PATH_D:
1055 break;
1056 default:
1057 break;
1058 }
1059
1060 return rtStatus;
1061
1062}
1063
1064/*-----------------------------------------------------------------------------
1065 * Function: PHY_CheckBBAndRFOK()
1066 *
1067 * Overview: This function is write register and then readback to make sure whether
1068 * BB[PHY0, PHY1], RF[Patha, path b, path c, path d] is Ok
1069 *
1070 * Input: PADAPTER Adapter
1071 * HW90_BLOCK_E CheckBlock
1072 * RF90_RADIO_PATH_E eRFPath // it is used only when CheckBlock is HW90_BLOCK_RF
1073 *
1074 * Output: NONE
1075 *
1076 * Return: RT_STATUS_SUCCESS: PHY is OK
1077 *
1078 * Note: This function may be removed in the ASIC
1079 *---------------------------------------------------------------------------*/
1080//in 8256 phy_RF8256_Config_HardCode
1081//but we don't use it temp
1082RT_STATUS
1083PHY_CheckBBAndRFOK(
1084 struct net_device* dev,
1085 HW90_BLOCK_E CheckBlock,
1086 RF90_RADIO_PATH_E eRFPath
1087 )
1088{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001089 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
1090 u32 i, CheckTimes = 4,ulRegRead = 0;
1091 u32 WriteAddr[4];
1092 u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f};
1093
1094 // Initialize register address offset to be checked
1095 WriteAddr[HW90_BLOCK_MAC] = 0x100;
1096 WriteAddr[HW90_BLOCK_PHY0] = 0x900;
1097 WriteAddr[HW90_BLOCK_PHY1] = 0x800;
1098 WriteAddr[HW90_BLOCK_RF] = 0x3;
1099
1100 for(i=0 ; i < CheckTimes ; i++)
1101 {
1102
1103 //
1104 // Write Data to register and readback
1105 //
1106 switch(CheckBlock)
1107 {
1108 case HW90_BLOCK_MAC:
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001109 RT_TRACE(COMP_INIT, "PHY_CheckBBRFOK(): Never Write 0x100 here!\n");
1110 break;
1111
1112 case HW90_BLOCK_PHY0:
1113 case HW90_BLOCK_PHY1:
1114 write_nic_dword(dev, WriteAddr[CheckBlock], WriteData[i]);
1115 ulRegRead = read_nic_dword(dev, WriteAddr[CheckBlock]);
1116 break;
1117
1118 case HW90_BLOCK_RF:
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001119 WriteData[i] &= 0xfff;
1120 rtl8192_phy_SetRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bRFRegOffsetMask, WriteData[i]);
1121 // TODO: we should not delay for such a long time. Ask SD3
1122 mdelay(10);
1123 ulRegRead = rtl8192_phy_QueryRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMaskDWord);
1124 mdelay(10);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001125 break;
1126
1127 default:
1128 rtStatus = RT_STATUS_FAILURE;
1129 break;
1130 }
1131
1132
1133 //
1134 // Check whether readback data is correct
1135 //
1136 if(ulRegRead != WriteData[i])
1137 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001138 RT_TRACE(COMP_ERR, "read back error(read:%x, write:%x)\n", ulRegRead, WriteData[i]);
1139 rtStatus = RT_STATUS_FAILURE;
1140 break;
1141 }
1142 }
1143
1144 return rtStatus;
1145}
1146
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001147#ifdef TO_DO_LIST
1148void
1149PHY_SetRFPowerState8192SUsb(
1150 struct net_device* dev,
1151 RF_POWER_STATE RFPowerState
1152 )
1153{
1154 struct r8192_priv *priv = ieee80211_priv(dev);
1155 bool WaitShutDown = FALSE;
1156 u32 DWordContent;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001157 u8 eRFPath;
1158 BB_REGISTER_DEFINITION_T *pPhyReg;
1159
1160 if(priv->SetRFPowerStateInProgress == TRUE)
1161 return;
1162
1163 priv->SetRFPowerStateInProgress = TRUE;
1164
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001165
1166 if(RFPowerState==RF_SHUT_DOWN)
1167 {
1168 RFPowerState=RF_OFF;
1169 WaitShutDown=TRUE;
1170 }
1171
1172
1173 priv->RFPowerState = RFPowerState;
1174 switch( priv->rf_chip )
1175 {
1176 case RF_8225:
1177 case RF_6052:
1178 switch( RFPowerState )
1179 {
1180 case RF_ON:
1181 break;
1182
1183 case RF_SLEEP:
1184 break;
1185
1186 case RF_OFF:
1187 break;
1188 }
1189 break;
1190
1191 case RF_8256:
1192 switch( RFPowerState )
1193 {
1194 case RF_ON:
1195 break;
1196
1197 case RF_SLEEP:
1198 break;
1199
1200 case RF_OFF:
1201 for(eRFPath=(RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath < RF90_PATH_MAX; eRFPath++)
1202 {
1203 if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
1204 continue;
1205
1206 pPhyReg = &priv->PHYRegDef[eRFPath];
1207 rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, bRFSI_RFENV);
1208 rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0);
1209 }
1210 break;
1211 }
1212 break;
1213
1214 case RF_8258:
1215 break;
Florian Schilhabeldc7bbaa2010-07-14 14:44:00 +02001216 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001217
1218 priv->SetRFPowerStateInProgress = FALSE;
1219}
1220#endif
1221
1222#ifdef RTL8192U
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001223void
1224PHY_UpdateInitialGain(
1225 struct net_device* dev
1226 )
1227{
1228 struct r8192_priv *priv = ieee80211_priv(dev);
Florian Schilhabeldc7bbaa2010-07-14 14:44:00 +02001229
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001230
1231 switch(priv->rf_chip)
1232 {
1233 case RF_8225:
1234 break;
1235 case RF_8256:
1236 break;
1237 case RF_8258:
1238 break;
1239 case RF_PSEUDO_11N:
1240 break;
1241 case RF_6052:
1242 break;
1243 default:
1244 RT_TRACE(COMP_DBG, "PHY_UpdateInitialGain(): unknown rf_chip: %#X\n", priv->rf_chip);
1245 break;
1246 }
1247}
1248#endif
1249
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001250void PHY_GetHWRegOriginalValue(struct net_device* dev)
1251{
1252 struct r8192_priv *priv = ieee80211_priv(dev);
1253
1254 // read tx power offset
1255 // Simulate 8192
1256 priv->MCSTxPowerLevelOriginalOffset[0] =
1257 rtl8192_QueryBBReg(dev, rTxAGC_Rate18_06, bMaskDWord);
1258 priv->MCSTxPowerLevelOriginalOffset[1] =
1259 rtl8192_QueryBBReg(dev, rTxAGC_Rate54_24, bMaskDWord);
1260 priv->MCSTxPowerLevelOriginalOffset[2] =
1261 rtl8192_QueryBBReg(dev, rTxAGC_Mcs03_Mcs00, bMaskDWord);
1262 priv->MCSTxPowerLevelOriginalOffset[3] =
1263 rtl8192_QueryBBReg(dev, rTxAGC_Mcs07_Mcs04, bMaskDWord);
1264 priv->MCSTxPowerLevelOriginalOffset[4] =
1265 rtl8192_QueryBBReg(dev, rTxAGC_Mcs11_Mcs08, bMaskDWord);
1266 priv->MCSTxPowerLevelOriginalOffset[5] =
1267 rtl8192_QueryBBReg(dev, rTxAGC_Mcs15_Mcs12, bMaskDWord);
1268
1269 // Read CCK offset
1270 priv->MCSTxPowerLevelOriginalOffset[6] =
1271 rtl8192_QueryBBReg(dev, rTxAGC_CCK_Mcs32, bMaskDWord);
1272 RT_TRACE(COMP_INIT, "Legacy OFDM =%08x/%08x HT_OFDM=%08x/%08x/%08x/%08x\n",
1273 priv->MCSTxPowerLevelOriginalOffset[0], priv->MCSTxPowerLevelOriginalOffset[1] ,
1274 priv->MCSTxPowerLevelOriginalOffset[2], priv->MCSTxPowerLevelOriginalOffset[3] ,
1275 priv->MCSTxPowerLevelOriginalOffset[4], priv->MCSTxPowerLevelOriginalOffset[5] );
1276
1277 // read rx initial gain
1278 priv->DefaultInitialGain[0] = rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bMaskByte0);
1279 priv->DefaultInitialGain[1] = rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bMaskByte0);
1280 priv->DefaultInitialGain[2] = rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bMaskByte0);
1281 priv->DefaultInitialGain[3] = rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bMaskByte0);
1282 RT_TRACE(COMP_INIT, "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x) \n",
1283 priv->DefaultInitialGain[0], priv->DefaultInitialGain[1],
1284 priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]);
1285
1286 // read framesync
1287 priv->framesync = rtl8192_QueryBBReg(dev, rOFDM0_RxDetector3, bMaskByte0);
1288 priv->framesyncC34 = rtl8192_QueryBBReg(dev, rOFDM0_RxDetector2, bMaskDWord);
1289 RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x \n",
1290 rOFDM0_RxDetector3, priv->framesync);
1291}
1292//YJ,modified,090107,end
1293
1294
1295
1296/**
1297* Function: phy_InitBBRFRegisterDefinition
1298*
1299* OverView: Initialize Register definition offset for Radio Path A/B/C/D
1300*
1301* Input:
1302* PADAPTER Adapter,
1303*
1304* Output: None
1305* Return: None
1306* Note: The initialization value is constant and it should never be changes
1307*/
1308//use in phy only
1309static void phy_InitBBRFRegisterDefinition( struct net_device* dev)
1310{
1311 struct r8192_priv *priv = ieee80211_priv(dev);
1312
1313 // RF Interface Sowrtware Control
1314 priv->PHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 LSBs if read 32-bit from 0x870
1315 priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872)
1316 priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 LSBs if read 32-bit from 0x874
1317 priv->PHYRegDef[RF90_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876)
1318
1319 // RF Interface Readback Value
1320 priv->PHYRegDef[RF90_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; // 16 LSBs if read 32-bit from 0x8E0
1321 priv->PHYRegDef[RF90_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2)
1322 priv->PHYRegDef[RF90_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 LSBs if read 32-bit from 0x8E4
1323 priv->PHYRegDef[RF90_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6)
1324
1325 // RF Interface Output (and Enable)
1326 priv->PHYRegDef[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x860
1327 priv->PHYRegDef[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x864
1328 priv->PHYRegDef[RF90_PATH_C].rfintfo = rFPGA0_XC_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x868
1329 priv->PHYRegDef[RF90_PATH_D].rfintfo = rFPGA0_XD_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x86C
1330
1331 // RF Interface (Output and) Enable
1332 priv->PHYRegDef[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862)
1333 priv->PHYRegDef[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866)
1334 priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86A (16-bit for 0x86A)
1335 priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86C (16-bit for 0x86E)
1336
1337 //Addr of LSSI. Wirte RF register by driver
1338 priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; //LSSI Parameter
1339 priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
1340 priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter;
1341 priv->PHYRegDef[RF90_PATH_D].rf3wireOffset = rFPGA0_XD_LSSIParameter;
1342
1343 // RF parameter
1344 priv->PHYRegDef[RF90_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; //BB Band Select
1345 priv->PHYRegDef[RF90_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter;
1346 priv->PHYRegDef[RF90_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter;
1347 priv->PHYRegDef[RF90_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter;
1348
1349 // Tx AGC Gain Stage (same for all path. Should we remove this?)
1350 priv->PHYRegDef[RF90_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
1351 priv->PHYRegDef[RF90_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
1352 priv->PHYRegDef[RF90_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
1353 priv->PHYRegDef[RF90_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
1354
1355 // Tranceiver A~D HSSI Parameter-1
1356 priv->PHYRegDef[RF90_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; //wire control parameter1
1357 priv->PHYRegDef[RF90_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; //wire control parameter1
1358 priv->PHYRegDef[RF90_PATH_C].rfHSSIPara1 = rFPGA0_XC_HSSIParameter1; //wire control parameter1
1359 priv->PHYRegDef[RF90_PATH_D].rfHSSIPara1 = rFPGA0_XD_HSSIParameter1; //wire control parameter1
1360
1361 // Tranceiver A~D HSSI Parameter-2
1362 priv->PHYRegDef[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; //wire control parameter2
1363 priv->PHYRegDef[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; //wire control parameter2
1364 priv->PHYRegDef[RF90_PATH_C].rfHSSIPara2 = rFPGA0_XC_HSSIParameter2; //wire control parameter2
1365 priv->PHYRegDef[RF90_PATH_D].rfHSSIPara2 = rFPGA0_XD_HSSIParameter2; //wire control parameter1
1366
1367 // RF switch Control
1368 priv->PHYRegDef[RF90_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; //TR/Ant switch control
1369 priv->PHYRegDef[RF90_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl;
1370 priv->PHYRegDef[RF90_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl;
1371 priv->PHYRegDef[RF90_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl;
1372
1373 // AGC control 1
1374 priv->PHYRegDef[RF90_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1;
1375 priv->PHYRegDef[RF90_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1;
1376 priv->PHYRegDef[RF90_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1;
1377 priv->PHYRegDef[RF90_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1;
1378
1379 // AGC control 2
1380 priv->PHYRegDef[RF90_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2;
1381 priv->PHYRegDef[RF90_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2;
1382 priv->PHYRegDef[RF90_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2;
1383 priv->PHYRegDef[RF90_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2;
1384
1385 // RX AFE control 1
1386 priv->PHYRegDef[RF90_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance;
1387 priv->PHYRegDef[RF90_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance;
1388 priv->PHYRegDef[RF90_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance;
1389 priv->PHYRegDef[RF90_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance;
1390
1391 // RX AFE control 1
1392 priv->PHYRegDef[RF90_PATH_A].rfRxAFE = rOFDM0_XARxAFE;
1393 priv->PHYRegDef[RF90_PATH_B].rfRxAFE = rOFDM0_XBRxAFE;
1394 priv->PHYRegDef[RF90_PATH_C].rfRxAFE = rOFDM0_XCRxAFE;
1395 priv->PHYRegDef[RF90_PATH_D].rfRxAFE = rOFDM0_XDRxAFE;
1396
1397 // Tx AFE control 1
1398 priv->PHYRegDef[RF90_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance;
1399 priv->PHYRegDef[RF90_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance;
1400 priv->PHYRegDef[RF90_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance;
1401 priv->PHYRegDef[RF90_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance;
1402
1403 // Tx AFE control 2
1404 priv->PHYRegDef[RF90_PATH_A].rfTxAFE = rOFDM0_XATxAFE;
1405 priv->PHYRegDef[RF90_PATH_B].rfTxAFE = rOFDM0_XBTxAFE;
1406 priv->PHYRegDef[RF90_PATH_C].rfTxAFE = rOFDM0_XCTxAFE;
1407 priv->PHYRegDef[RF90_PATH_D].rfTxAFE = rOFDM0_XDTxAFE;
1408
1409 // Tranceiver LSSI Readback SI mode
1410 priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
1411 priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
1412 priv->PHYRegDef[RF90_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack;
1413 priv->PHYRegDef[RF90_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack;
1414
1415 // Tranceiver LSSI Readback PI mode
1416 priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback;
1417 priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBackPi = TransceiverB_HSPI_Readback;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001418
1419}
1420
1421
1422//
1423// Description: Change RF power state.
1424//
1425// Assumption: This function must be executed in re-schdulable context,
1426// ie. PASSIVE_LEVEL.
1427//
Florian Schilhabeldc7bbaa2010-07-14 14:44:00 +02001428
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001429bool PHY_SetRFPowerState(struct net_device* dev, RT_RF_POWER_STATE eRFPowerState)
1430{
1431 struct r8192_priv *priv = ieee80211_priv(dev);
1432 bool bResult = FALSE;
1433
1434 RT_TRACE(COMP_RF, "---------> PHY_SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
1435
1436 if(eRFPowerState == priv->ieee80211->eRFPowerState)
1437 {
1438 RT_TRACE(COMP_RF, "<--------- PHY_SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
1439 return bResult;
1440 }
1441
1442 bResult = phy_SetRFPowerState8192SU(dev, eRFPowerState);
1443
1444 RT_TRACE(COMP_RF, "<--------- PHY_SetRFPowerState(): bResult(%d)\n", bResult);
1445
1446 return bResult;
1447}
1448
1449//use in phy only
1450static bool phy_SetRFPowerState8192SU(struct net_device* dev,RT_RF_POWER_STATE eRFPowerState)
1451{
1452 struct r8192_priv *priv = ieee80211_priv(dev);
1453 bool bResult = TRUE;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001454 u8 u1bTmp;
1455
1456 if(priv->SetRFPowerStateInProgress == TRUE)
1457 return FALSE;
1458
1459 priv->SetRFPowerStateInProgress = TRUE;
1460
1461 switch(priv->rf_chip )
1462 {
1463 default:
1464 switch( eRFPowerState )
1465 {
1466 case eRfOn:
1467 write_nic_dword(dev, WFM5, FW_BB_RESET_ENABLE);
1468 write_nic_word(dev, CMDR, 0x37FC);
1469 write_nic_byte(dev, PHY_CCA, 0x3);
1470 write_nic_byte(dev, TXPAUSE, 0x00);
1471 write_nic_byte(dev, SPS1_CTRL, 0x64);
1472 break;
1473
1474 //
1475 // In current solution, RFSleep=RFOff in order to save power under 802.11 power save.
1476 // By Bruce, 2008-01-16.
1477 //
1478 case eRfSleep:
1479 case eRfOff:
1480 if (priv->ieee80211->eRFPowerState == eRfSleep || priv->ieee80211->eRFPowerState == eRfOff)
1481 break;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001482 //
1483 //RF Off/Sleep sequence. Designed/tested from SD4 Scott, SD1 Grent and Jonbon.
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001484 // (0) Disable FW BB reset checking
1485 write_nic_dword(dev, WFM5, FW_BB_RESET_DISABLE);
1486
1487 // (1) Switching Power Supply Register : Disable LD12 & SW12 (for IT)
1488 u1bTmp = read_nic_byte(dev, LDOV12D_CTRL);
1489 u1bTmp |= BIT0;
1490 write_nic_byte(dev, LDOV12D_CTRL, u1bTmp);
1491
1492 write_nic_byte(dev, SPS1_CTRL, 0x0);
1493 write_nic_byte(dev, TXPAUSE, 0xFF);
1494
1495 // (2) MAC Tx/Rx enable, BB enable, CCK/OFDM enable
1496 write_nic_word(dev, CMDR, 0x77FC);
1497 write_nic_byte(dev, PHY_CCA, 0x0);
1498 udelay(100);
1499
1500 write_nic_word(dev, CMDR, 0x37FC);
1501 udelay(10);
1502
1503 write_nic_word(dev, CMDR, 0x77FC);
1504 udelay(10);
1505
1506 // (3) Reset BB TRX blocks
1507 write_nic_word(dev, CMDR, 0x57FC);
1508 break;
1509
1510 default:
1511 bResult = FALSE;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001512 break;
1513 }
1514 break;
1515
1516 }
1517 priv->ieee80211->eRFPowerState = eRFPowerState;
1518#ifdef TO_DO_LIST
1519 if(bResult)
1520 {
1521 // Update current RF state variable.
1522 priv->ieee80211->eRFPowerState = eRFPowerState;
1523
1524 switch(priv->rf_chip )
1525 {
1526 case RF_8256:
1527 switch(priv->ieee80211->eRFPowerState)
1528 {
1529 case eRfOff:
1530 //
1531 //If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
1532 //
1533 if(pMgntInfo->RfOffReason==RF_CHANGE_BY_IPS )
1534 {
1535 dev->HalFunc.LedControlHandler(dev,LED_CTL_NO_LINK);
1536 }
1537 else
1538 {
1539 // Turn off LED if RF is not ON.
1540 dev->HalFunc.LedControlHandler(dev, LED_CTL_POWER_OFF);
1541 }
1542 break;
1543
1544 case eRfOn:
1545 // Turn on RF we are still linked, which might happen when
1546 // we quickly turn off and on HW RF. 2006.05.12, by rcnjko.
1547 if( pMgntInfo->bMediaConnect == TRUE )
1548 {
1549 dev->HalFunc.LedControlHandler(dev, LED_CTL_LINK);
1550 }
1551 else
1552 {
1553 // Turn off LED if RF is not ON.
1554 dev->HalFunc.LedControlHandler(dev, LED_CTL_NO_LINK);
1555 }
1556 break;
1557
1558 default:
1559 // do nothing.
1560 break;
1561 }// Switch RF state
1562
1563 break;
1564
1565 default:
1566 RT_TRACE(COMP_RF, "phy_SetRFPowerState8192SU(): Unknown RF type\n");
1567 break;
1568 }// Switch rf_chip
1569 }
1570#endif
1571 priv->SetRFPowerStateInProgress = FALSE;
1572
1573 return bResult;
1574}
1575
1576/*-----------------------------------------------------------------------------
1577 * Function: GetTxPowerLevel8190()
1578 *
1579 * Overview: This function is export to "common" moudule
1580 *
1581 * Input: PADAPTER Adapter
1582 * psByte Power Level
1583 *
1584 * Output: NONE
1585 *
1586 * Return: NONE
1587 *
1588 *---------------------------------------------------------------------------*/
1589 // no use temp
1590 void
1591PHY_GetTxPowerLevel8192S(
1592 struct net_device* dev,
1593 long* powerlevel
1594 )
1595{
1596 struct r8192_priv *priv = ieee80211_priv(dev);
1597 u8 TxPwrLevel = 0;
1598 long TxPwrDbm;
1599 //
1600 // Because the Tx power indexes are different, we report the maximum of them to
1601 // meet the CCX TPC request. By Bruce, 2008-01-31.
1602 //
1603
1604 // CCK
1605 TxPwrLevel = priv->CurrentCckTxPwrIdx;
1606 TxPwrDbm = phy_TxPwrIdxToDbm(dev, WIRELESS_MODE_B, TxPwrLevel);
1607
1608 // Legacy OFDM
1609 TxPwrLevel = priv->CurrentOfdm24GTxPwrIdx + priv->LegacyHTTxPowerDiff;
1610
1611 // Compare with Legacy OFDM Tx power.
1612 if(phy_TxPwrIdxToDbm(dev, WIRELESS_MODE_G, TxPwrLevel) > TxPwrDbm)
1613 TxPwrDbm = phy_TxPwrIdxToDbm(dev, WIRELESS_MODE_G, TxPwrLevel);
1614
1615 // HT OFDM
1616 TxPwrLevel = priv->CurrentOfdm24GTxPwrIdx;
1617
1618 // Compare with HT OFDM Tx power.
1619 if(phy_TxPwrIdxToDbm(dev, WIRELESS_MODE_N_24G, TxPwrLevel) > TxPwrDbm)
1620 TxPwrDbm = phy_TxPwrIdxToDbm(dev, WIRELESS_MODE_N_24G, TxPwrLevel);
1621
1622 *powerlevel = TxPwrDbm;
1623}
1624
1625/*-----------------------------------------------------------------------------
1626 * Function: SetTxPowerLevel8190()
1627 *
1628 * Overview: This function is export to "HalCommon" moudule
1629 *
1630 * Input: PADAPTER Adapter
1631 * u1Byte channel
1632 *
1633 * Output: NONE
1634 *
1635 * Return: NONE
1636 * 2008/11/04 MHC We remove EEPROM_93C56.
1637 * We need to move CCX relative code to independet file.
1638* 2009/01/21 MHC Support new EEPROM format from SD3 requirement.
1639 *---------------------------------------------------------------------------*/
1640 void PHY_SetTxPowerLevel8192S(struct net_device* dev, u8 channel)
1641{
1642 struct r8192_priv *priv = ieee80211_priv(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001643 u8 powerlevel = (u8)EEPROM_Default_TxPower, powerlevelOFDM24G = 0x10;
1644 s8 ant_pwr_diff = 0;
1645 u32 u4RegValue;
1646 u8 index = (channel -1);
1647 // 2009/01/22 MH Add for new EEPROM format from SD3
1648 u8 pwrdiff[2] = {0};
1649 u8 ht20pwr[2] = {0}, ht40pwr[2] = {0};
1650 u8 rfpath = 0, rfpathnum = 2;
1651
1652 if(priv->bTXPowerDataReadFromEEPORM == FALSE)
1653 return;
1654
Florian Schilhabel495c57f2010-05-04 14:24:35 +02001655 /*
1656 * Read predefined TX power index in EEPROM
1657 */
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001658 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001659 //
1660 // Mainly we use RF-A Tx Power to write the Tx Power registers, but the RF-B Tx
1661 // Power must be calculated by the antenna diff.
1662 // So we have to rewrite Antenna gain offset register here.
1663 // Please refer to BB register 0x80c
1664 // 1. For CCK.
1665 // 2. For OFDM 1T or 2T
1666 //
1667
1668 // 1. CCK
1669 powerlevel = priv->RfTxPwrLevelCck[0][index];
1670
1671 if (priv->rf_type == RF_1T2R || priv->rf_type == RF_1T1R)
1672 {
1673 // Read HT 40 OFDM TX power
1674 powerlevelOFDM24G = priv->RfTxPwrLevelOfdm1T[0][index];
1675 // RF B HT OFDM pwr-RFA HT OFDM pwr
1676 // Only one RF we need not to decide B <-> A pwr diff
1677
1678 // Legacy<->HT pwr diff, we only care about path A.
1679
1680 // We only assume 1T as RF path A
1681 rfpathnum = 1;
1682 ht20pwr[0] = ht40pwr[0] = priv->RfTxPwrLevelOfdm1T[0][index];
1683 }
1684 else if (priv->rf_type == RF_2T2R)
1685 {
1686 // Read HT 40 OFDM TX power
1687 powerlevelOFDM24G = priv->RfTxPwrLevelOfdm2T[0][index];
1688 // RF B HT OFDM pwr-RFA HT OFDM pwr
1689 ant_pwr_diff = priv->RfTxPwrLevelOfdm2T[1][index] -
1690 priv->RfTxPwrLevelOfdm2T[0][index];
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001691
1692 ht20pwr[0] = ht40pwr[0] = priv->RfTxPwrLevelOfdm2T[0][index];
1693 ht20pwr[1] = ht40pwr[1] = priv->RfTxPwrLevelOfdm2T[1][index];
1694 }
1695
1696 //
1697 // 2009/01/21 MH Support new EEPROM format from SD3 requirement
1698 // 2009/02/10 Cosa, Here is only for reg B/C/D to A gain diff.
1699 //
1700 if (priv->EEPROMVersion == 2) // Defined by SD1 Jong
1701 {
1702 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
1703 {
1704 for (rfpath = 0; rfpath < rfpathnum; rfpath++)
1705 {
1706 // HT 20<->40 pwr diff
1707 pwrdiff[rfpath] = priv->TxPwrHt20Diff[rfpath][index];
1708
1709 // Calculate Antenna pwr diff
1710 if (pwrdiff[rfpath] < 8) // 0~+7
1711 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001712 ht20pwr[rfpath] += pwrdiff[rfpath];
1713 }
1714 else // index8-15=-8~-1
1715 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001716 ht20pwr[rfpath] -= (15-pwrdiff[rfpath]);
1717 }
1718 }
1719
1720 // RF B HT OFDM pwr-RFA HT OFDM pwr
1721 if (priv->rf_type == RF_2T2R)
1722 ant_pwr_diff = ht20pwr[1] - ht20pwr[0];
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001723 }
1724
1725 // Band Edge scheme is enabled for FCC mode
1726 if (priv->TxPwrbandEdgeFlag == 1/* && pHalData->ChannelPlan == 0*/)
1727 {
1728 for (rfpath = 0; rfpath < rfpathnum; rfpath++)
1729 {
1730 pwrdiff[rfpath] = 0;
1731 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1732 {
1733 if (channel <= 3)
1734 pwrdiff[rfpath] = priv->TxPwrbandEdgeHt40[rfpath][0];
1735 else if (channel >= 9)
1736 pwrdiff[rfpath] = priv->TxPwrbandEdgeHt40[rfpath][1];
1737 else
1738 pwrdiff[rfpath] = 0;
1739
1740 ht40pwr[rfpath] -= pwrdiff[rfpath];
1741 }
1742 else if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
1743 {
1744 if (channel == 1)
1745 pwrdiff[rfpath] = priv->TxPwrbandEdgeHt20[rfpath][0];
1746 else if (channel >= 11)
1747 pwrdiff[rfpath] = priv->TxPwrbandEdgeHt20[rfpath][1];
1748 else
1749 pwrdiff[rfpath] = 0;
1750
1751 ht20pwr[rfpath] -= pwrdiff[rfpath];
1752 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001753 }
1754
1755 if (priv->rf_type == RF_2T2R)
1756 {
1757 // HT 20/40 must decide if they need to minus BD pwr offset
1758 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1759 ant_pwr_diff = ht40pwr[1] - ht40pwr[0];
1760 else
1761 ant_pwr_diff = ht20pwr[1] - ht20pwr[0];
1762 }
1763 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
1764 {
1765 if (channel <= 1 || channel >= 11)
1766 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001767 }
1768 }
1769 else
1770 {
1771 if (channel <= 3 || channel >= 9)
1772 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001773 }
1774 }
1775 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001776 }
1777
1778 //Cosa added for protection, the reg rFPGA0_TxGainStage
1779 // range is from 7~-8, index = 0x0~0xf
1780 if(ant_pwr_diff > 7)
1781 ant_pwr_diff = 7;
1782 if(ant_pwr_diff < -8)
1783 ant_pwr_diff = -8;
1784
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001785 ant_pwr_diff &= 0xf;
1786
1787 // Antenna TX power difference
1788 priv->AntennaTxPwDiff[2] = 0;// RF-D, don't care
1789 priv->AntennaTxPwDiff[1] = 0;// RF-C, don't care
1790 priv->AntennaTxPwDiff[0] = (u8)(ant_pwr_diff); // RF-B
1791
1792 // Antenna gain offset from B/C/D to A
1793 u4RegValue = ( priv->AntennaTxPwDiff[2]<<8 |
1794 priv->AntennaTxPwDiff[1]<<4 |
1795 priv->AntennaTxPwDiff[0] );
1796
1797 // Notify Tx power difference for B/C/D to A!!!
1798 rtl8192_setBBreg(dev, rFPGA0_TxGainStage, (bXBTxAGC|bXCTxAGC|bXDTxAGC), u4RegValue);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001799 }
1800
1801 //
1802 // CCX 2 S31, AP control of client transmit power:
1803 // 1. We shall not exceed Cell Power Limit as possible as we can.
1804 // 2. Tolerance is +/- 5dB.
1805 // 3. 802.11h Power Contraint takes higher precedence over CCX Cell Power Limit.
1806 //
1807 // TODO:
1808 // 1. 802.11h power contraint
1809 //
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001810 //
1811#ifdef TODO //WB, 11h has not implemented now.
1812 if( priv->ieee80211->iw_mode != IW_MODE_INFRA && priv->bWithCcxCellPwr &&
1813 channel == priv->ieee80211->current_network.channel)// & priv->ieee80211->mAssoc )
1814 {
1815 u8 CckCellPwrIdx = phy_DbmToTxPwrIdx(dev, WIRELESS_MODE_B, priv->CcxCellPwr);
1816 u8 LegacyOfdmCellPwrIdx = phy_DbmToTxPwrIdx(dev, WIRELESS_MODE_G, priv->CcxCellPwr);
1817 u8 OfdmCellPwrIdx = phy_DbmToTxPwrIdx(dev, WIRELESS_MODE_N_24G, priv->CcxCellPwr);
1818
1819 RT_TRACE(COMP_TXAGC,
1820 ("CCX Cell Limit: %d dbm => CCK Tx power index : %d, Legacy OFDM Tx power index : %d, OFDM Tx power index: %d\n",
1821 priv->CcxCellPwr, CckCellPwrIdx, LegacyOfdmCellPwrIdx, OfdmCellPwrIdx));
1822 RT_TRACE(COMP_TXAGC,
1823 ("EEPROM channel(%d) => CCK Tx power index: %d, Legacy OFDM Tx power index : %d, OFDM Tx power index: %d\n",
1824 channel, powerlevel, powerlevelOFDM24G + priv->LegacyHTTxPowerDiff, powerlevelOFDM24G));
1825
1826 // CCK
1827 if(powerlevel > CckCellPwrIdx)
1828 powerlevel = CckCellPwrIdx;
1829 // Legacy OFDM, HT OFDM
1830 if(powerlevelOFDM24G + priv->LegacyHTTxPowerDiff > LegacyOfdmCellPwrIdx)
1831 {
1832 if((OfdmCellPwrIdx - priv->LegacyHTTxPowerDiff) > 0)
1833 {
1834 powerlevelOFDM24G = OfdmCellPwrIdx - priv->LegacyHTTxPowerDiff;
1835 }
1836 else
1837 {
1838 powerlevelOFDM24G = 0;
1839 }
1840 }
1841
1842 RT_TRACE(COMP_TXAGC,
1843 ("Altered CCK Tx power index : %d, Legacy OFDM Tx power index: %d, OFDM Tx power index: %d\n",
1844 powerlevel, powerlevelOFDM24G + priv->LegacyHTTxPowerDiff, powerlevelOFDM24G));
1845 }
1846#endif
1847
1848 priv->CurrentCckTxPwrIdx = powerlevel;
1849 priv->CurrentOfdm24GTxPwrIdx = powerlevelOFDM24G;
1850
1851 switch(priv->rf_chip)
1852 {
1853 case RF_8225:
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001854 break;
1855
1856 case RF_8256:
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001857 break;
1858
1859 case RF_6052:
1860 PHY_RF6052SetCckTxPower(dev, powerlevel);
1861 PHY_RF6052SetOFDMTxPower(dev, powerlevelOFDM24G);
1862 break;
1863
1864 case RF_8258:
1865 break;
1866 default:
1867 break;
1868 }
1869
1870}
1871
1872//
1873// Description:
1874// Update transmit power level of all channel supported.
1875//
1876// TODO:
1877// A mode.
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001878bool PHY_UpdateTxPowerDbm8192S(struct net_device* dev, long powerInDbm)
1879{
1880 struct r8192_priv *priv = ieee80211_priv(dev);
1881 u8 idx;
1882 u8 rf_path;
1883
1884 // TODO: A mode Tx power.
1885 u8 CckTxPwrIdx = phy_DbmToTxPwrIdx(dev, WIRELESS_MODE_B, powerInDbm);
1886 u8 OfdmTxPwrIdx = phy_DbmToTxPwrIdx(dev, WIRELESS_MODE_N_24G, powerInDbm);
1887
1888 if(OfdmTxPwrIdx - priv->LegacyHTTxPowerDiff > 0)
1889 OfdmTxPwrIdx -= priv->LegacyHTTxPowerDiff;
1890 else
1891 OfdmTxPwrIdx = 0;
1892
1893 for(idx = 0; idx < 14; idx++)
1894 {
1895 priv->TxPowerLevelCCK[idx] = CckTxPwrIdx;
1896 priv->TxPowerLevelCCK_A[idx] = CckTxPwrIdx;
1897 priv->TxPowerLevelCCK_C[idx] = CckTxPwrIdx;
1898 priv->TxPowerLevelOFDM24G[idx] = OfdmTxPwrIdx;
1899 priv->TxPowerLevelOFDM24G_A[idx] = OfdmTxPwrIdx;
1900 priv->TxPowerLevelOFDM24G_C[idx] = OfdmTxPwrIdx;
1901
1902 for (rf_path = 0; rf_path < 2; rf_path++)
1903 {
1904 priv->RfTxPwrLevelCck[rf_path][idx] = CckTxPwrIdx;
1905 priv->RfTxPwrLevelOfdm1T[rf_path][idx] = \
1906 priv->RfTxPwrLevelOfdm2T[rf_path][idx] = OfdmTxPwrIdx;
1907 }
1908 }
1909
1910 PHY_SetTxPowerLevel8192S(dev, priv->chan);
1911
1912 return TRUE;
1913}
1914
1915/*
1916 Description:
1917 When beacon interval is changed, the values of the
1918 hw registers should be modified.
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001919*/
1920
1921extern void PHY_SetBeaconHwReg( struct net_device* dev, u16 BeaconInterval)
1922{
1923 u32 NewBeaconNum;
1924
1925 NewBeaconNum = BeaconInterval *32 - 64;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001926 write_nic_dword(dev, WFM3+4, NewBeaconNum);
1927 write_nic_dword(dev, WFM3, 0xB026007C);
1928}
1929
1930//
1931// Description:
1932// Map dBm into Tx power index according to
1933// current HW model, for example, RF and PA, and
1934// current wireless mode.
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001935// use in phy only
1936static u8 phy_DbmToTxPwrIdx(
1937 struct net_device* dev,
1938 WIRELESS_MODE WirelessMode,
1939 long PowerInDbm
1940 )
1941{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001942 u8 TxPwrIdx = 0;
1943 long Offset = 0;
1944
1945
1946 //
1947 // Tested by MP, we found that CCK Index 0 equals to -7dbm, OFDM legacy equals to
1948 // 3dbm, and OFDM HT equals to 0dbm repectively.
1949 // Note:
1950 // The mapping may be different by different NICs. Do not use this formula for what needs accurate result.
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001951 //
1952 switch(WirelessMode)
1953 {
1954 case WIRELESS_MODE_B:
1955 Offset = -7;
1956 break;
1957
1958 case WIRELESS_MODE_G:
1959 case WIRELESS_MODE_N_24G:
1960 Offset = -8;
1961 break;
1962 default:
1963 break;
1964 }
1965
1966 if((PowerInDbm - Offset) > 0)
1967 {
1968 TxPwrIdx = (u8)((PowerInDbm - Offset) * 2);
1969 }
1970 else
1971 {
1972 TxPwrIdx = 0;
1973 }
1974
1975 // Tx Power Index is too large.
1976 if(TxPwrIdx > MAX_TXPWR_IDX_NMODE_92S)
1977 TxPwrIdx = MAX_TXPWR_IDX_NMODE_92S;
1978
1979 return TxPwrIdx;
1980}
1981//
1982// Description:
1983// Map Tx power index into dBm according to
1984// current HW model, for example, RF and PA, and
1985// current wireless mode.
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07001986// use in phy only
1987static long phy_TxPwrIdxToDbm(
1988 struct net_device* dev,
1989 WIRELESS_MODE WirelessMode,
1990 u8 TxPwrIdx
1991 )
1992{
1993 //struct r8192_priv *priv = ieee80211_priv(dev);
1994 long Offset = 0;
1995 long PwrOutDbm = 0;
1996
1997 //
1998 // Tested by MP, we found that CCK Index 0 equals to -7dbm, OFDM legacy equals to
1999 // 3dbm, and OFDM HT equals to 0dbm repectively.
2000 // Note:
2001 // The mapping may be different by different NICs. Do not use this formula for what needs accurate result.
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002002 //
2003 switch(WirelessMode)
2004 {
2005 case WIRELESS_MODE_B:
2006 Offset = -7;
2007 break;
2008
2009 case WIRELESS_MODE_G:
2010 case WIRELESS_MODE_N_24G:
2011 Offset = -8;
2012 break;
2013 default:
2014 break;
2015 }
2016
2017 PwrOutDbm = TxPwrIdx / 2 + Offset; // Discard the decimal part.
2018
2019 return PwrOutDbm;
2020}
2021
2022#ifdef TO_DO_LIST
2023extern VOID
2024PHY_ScanOperationBackup8192S(
2025 IN PADAPTER Adapter,
2026 IN u1Byte Operation
2027 )
2028{
2029
2030 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
2031 PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
2032 u4Byte BitMask;
2033 u1Byte initial_gain;
2034
2035
2036
2037
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002038
2039 if(!Adapter->bDriverStopped)
2040 {
2041 switch(Operation)
2042 {
2043 case SCAN_OPT_BACKUP:
2044 //
2045 // <Roger_Notes> We halt FW DIG and disable high ppower both two DMs here
2046 // and resume both two DMs while scan complete.
2047 // 2008.11.27.
2048 //
2049 Adapter->HalFunc.SetFwCmdHandler(Adapter, FW_CMD_PAUSE_DM_BY_SCAN);
2050 break;
2051
2052 case SCAN_OPT_RESTORE:
2053 //
2054 // <Roger_Notes> We resume DIG and enable high power both two DMs here and
2055 // recover earlier DIG settings.
2056 // 2008.11.27.
2057 //
2058 Adapter->HalFunc.SetFwCmdHandler(Adapter, FW_CMD_RESUME_DM_BY_SCAN);
2059 break;
2060
2061 default:
2062 RT_TRACE(COMP_SCAN, DBG_LOUD, ("Unknown Scan Backup Operation. \n"));
2063 break;
2064 }
2065 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002066}
2067#endif
2068
2069//nouse temp
2070void PHY_InitialGain8192S(struct net_device* dev,u8 Operation )
2071{
2072
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002073}
2074
2075/*-----------------------------------------------------------------------------
2076 * Function: SetBWModeCallback8190Pci()
2077 *
2078 * Overview: Timer callback function for SetSetBWMode
2079 *
2080 * Input: PRT_TIMER pTimer
2081 *
2082 * Output: NONE
2083 *
2084 * Return: NONE
2085 *
2086 * Note: (1) We do not take j mode into consideration now
2087 * (2) Will two workitem of "switch channel" and "switch channel bandwidth" run
2088 * concurrently?
2089 *---------------------------------------------------------------------------*/
2090// use in phy only (in win it's timer)
2091void PHY_SetBWModeCallback8192S(struct net_device *dev)
2092{
2093 struct r8192_priv *priv = ieee80211_priv(dev);
2094 u8 regBwOpMode;
2095
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002096 u8 regRRSR_RSC;
2097
2098 RT_TRACE(COMP_SWBW, "==>SetBWModeCallback8190Pci() Switch to %s bandwidth\n", \
2099 priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz");
2100
2101 if(priv->rf_chip == RF_PSEUDO_11N)
2102 {
2103 priv->SetBWModeInProgress= FALSE;
2104 return;
2105 }
2106
2107 if(!priv->up)
2108 return;
2109
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002110
2111 //3//
2112 //3//<1>Set MAC register
2113 //3//
2114 regBwOpMode = read_nic_byte(dev, BW_OPMODE);
2115 regRRSR_RSC = read_nic_byte(dev, RRSR+2);
2116
2117 switch(priv->CurrentChannelBW)
2118 {
2119 case HT_CHANNEL_WIDTH_20:
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002120
2121 regBwOpMode |= BW_OPMODE_20MHZ;
2122 // 2007/02/07 Mark by Emily becasue we have not verify whether this register works
2123 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
2124 break;
2125
2126 case HT_CHANNEL_WIDTH_20_40:
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002127
2128 regBwOpMode &= ~BW_OPMODE_20MHZ;
2129 // 2007/02/07 Mark by Emily becasue we have not verify whether this register works
2130 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
2131 regRRSR_RSC = (regRRSR_RSC&0x90) |(priv->nCur40MhzPrimeSC<<5);
2132 write_nic_byte(dev, RRSR+2, regRRSR_RSC);
2133 break;
2134
2135 default:
Joe Perchesc7e10c92010-02-01 23:22:14 -08002136 RT_TRACE(COMP_DBG, "SetBWModeCallback8190Pci(): unknown Bandwidth: %#X\n",
2137 priv->CurrentChannelBW);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002138 break;
2139 }
2140
2141 //3//
2142 //3//<2>Set PHY related register
2143 //3//
2144 switch(priv->CurrentChannelBW)
2145 {
2146 /* 20 MHz channel*/
2147 case HT_CHANNEL_WIDTH_20:
2148 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
2149 rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
2150
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002151 if (priv->card_8192_version >= VERSION_8192S_BCUT)
2152 write_nic_byte(dev, rFPGA0_AnalogParameter2, 0x58);
2153
2154
2155 break;
2156
2157 /* 40 MHz channel*/
2158 case HT_CHANNEL_WIDTH_20_40:
2159 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
2160 rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
2161
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002162
2163 // Set Control channel to upper or lower. These settings are required only for 40MHz
2164 rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
2165 rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC);
2166
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002167 if (priv->card_8192_version >= VERSION_8192S_BCUT)
2168 write_nic_byte(dev, rFPGA0_AnalogParameter2, 0x18);
2169
2170 break;
2171
2172 default:
2173 RT_TRACE(COMP_DBG, "SetBWModeCallback8190Pci(): unknown Bandwidth: %#X\n"\
2174 ,priv->CurrentChannelBW);
2175 break;
2176
2177 }
2178 //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315
2179
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002180
2181 //3<3>Set RF related register
2182 switch( priv->rf_chip )
2183 {
2184 case RF_8225:
2185 //PHY_SetRF8225Bandwidth(dev, priv->CurrentChannelBW);
2186 break;
2187
2188 case RF_8256:
2189 // Please implement this function in Hal8190PciPhy8256.c
2190 //PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW);
2191 break;
2192
2193 case RF_8258:
2194 // Please implement this function in Hal8190PciPhy8258.c
2195 // PHY_SetRF8258Bandwidth();
2196 break;
2197
2198 case RF_PSEUDO_11N:
2199 // Do Nothing
2200 break;
2201
2202 case RF_6052:
2203 PHY_RF6052SetBandwidth(dev, priv->CurrentChannelBW);
2204 break;
2205 default:
2206 printk("Unknown rf_chip: %d\n", priv->rf_chip);
2207 break;
2208 }
2209
2210 priv->SetBWModeInProgress= FALSE;
2211
2212 RT_TRACE(COMP_SWBW, "<==SetBWModeCallback8190Pci() \n" );
2213}
2214
2215
2216 /*-----------------------------------------------------------------------------
2217 * Function: SetBWMode8190Pci()
2218 *
2219 * Overview: This function is export to "HalCommon" moudule
2220 *
2221 * Input: PADAPTER Adapter
2222 * HT_CHANNEL_WIDTH Bandwidth //20M or 40M
2223 *
2224 * Output: NONE
2225 *
2226 * Return: NONE
2227 *
2228 * Note: We do not take j mode into consideration now
2229 *---------------------------------------------------------------------------*/
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002230void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset)
2231{
2232 struct r8192_priv *priv = ieee80211_priv(dev);
2233 HT_CHANNEL_WIDTH tmpBW = priv->CurrentChannelBW;
2234
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002235 if(priv->SetBWModeInProgress)
2236 return;
2237
2238 priv->SetBWModeInProgress= TRUE;
2239
2240 priv->CurrentChannelBW = Bandwidth;
2241
2242 if(Offset==HT_EXTCHNL_OFFSET_LOWER)
2243 priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER;
2244 else if(Offset==HT_EXTCHNL_OFFSET_UPPER)
2245 priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER;
2246 else
2247 priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2248
Florian Schilhabel0825c402010-07-14 14:44:18 +02002249 if((priv->up) )
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002250 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002251 SetBWModeCallback8192SUsbWorkItem(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002252 }
2253 else
2254 {
2255 RT_TRACE(COMP_SCAN, "PHY_SetBWMode8192S() SetBWModeInProgress FALSE driver sleep or unload\n");
2256 priv->SetBWModeInProgress= FALSE;
2257 priv->CurrentChannelBW = tmpBW;
2258 }
2259}
2260
2261// use in phy only (in win it's timer)
2262void PHY_SwChnlCallback8192S(struct net_device *dev)
2263{
2264
2265 struct r8192_priv *priv = ieee80211_priv(dev);
2266 u32 delay;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002267
2268 RT_TRACE(COMP_CH, "==>SwChnlCallback8190Pci(), switch to channel %d\n", priv->chan);
2269
2270 if(!priv->up)
2271 return;
2272
2273 if(priv->rf_chip == RF_PSEUDO_11N)
2274 {
2275 priv->SwChnlInProgress=FALSE;
2276 return; //return immediately if it is peudo-phy
2277 }
2278
2279 do{
2280 if(!priv->SwChnlInProgress)
2281 break;
2282
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002283 if(!phy_SwChnlStepByStep(dev, priv->chan, &priv->SwChnlStage, &priv->SwChnlStep, &delay))
2284 {
2285 if(delay>0)
2286 {
2287 mdelay(delay);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002288 }
2289 else
2290 continue;
2291 }
2292 else
2293 {
2294 priv->SwChnlInProgress=FALSE;
2295 break;
2296 }
2297 }while(true);
2298}
2299
2300// Call after initialization
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002301u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel)
2302{
2303 struct r8192_priv *priv = ieee80211_priv(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002304
2305 if(!priv->up)
2306 return false;
2307
2308 if(priv->SwChnlInProgress)
2309 return false;
2310
2311 if(priv->SetBWModeInProgress)
2312 return false;
2313
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002314 switch(priv->ieee80211->mode)
2315 {
2316 case WIRELESS_MODE_A:
2317 case WIRELESS_MODE_N_5G:
2318 if (channel<=14){
2319 RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14");
2320 return false;
2321 }
2322 break;
2323
2324 case WIRELESS_MODE_B:
2325 if (channel>14){
2326 RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14");
2327 return false;
2328 }
2329 break;
2330
2331 case WIRELESS_MODE_G:
2332 case WIRELESS_MODE_N_24G:
2333 if (channel>14){
2334 RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14");
2335 return false;
2336 }
2337 break;
2338
2339 default:
Florian Schilhabeldc7bbaa2010-07-14 14:44:00 +02002340 ;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002341 break;
2342 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002343
2344 priv->SwChnlInProgress = TRUE;
2345 if( channel == 0)
2346 channel = 1;
2347
2348 priv->chan=channel;
2349
2350 priv->SwChnlStage=0;
2351 priv->SwChnlStep=0;
2352
Florian Schilhabeldc7bbaa2010-07-14 14:44:00 +02002353 if((priv->up))
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002354 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002355 SwChnlCallback8192SUsbWorkItem(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002356#ifdef TO_DO_LIST
2357 if(bResult)
2358 {
2359 RT_TRACE(COMP_SCAN, "PHY_SwChnl8192S SwChnlInProgress TRUE schdule workitem done\n");
2360 }
2361 else
2362 {
2363 RT_TRACE(COMP_SCAN, "PHY_SwChnl8192S SwChnlInProgress FALSE schdule workitem error\n");
2364 priv->SwChnlInProgress = false;
2365 priv->CurrentChannel = tmpchannel;
2366 }
2367#endif
2368 }
2369 else
2370 {
2371 RT_TRACE(COMP_SCAN, "PHY_SwChnl8192S SwChnlInProgress FALSE driver sleep or unload\n");
2372 priv->SwChnlInProgress = false;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002373 }
2374 return true;
2375}
2376
2377
2378//
2379// Description:
2380// Switch channel synchronously. Called by SwChnlByDelayHandler.
2381//
2382// Implemented by Bruce, 2008-02-14.
2383// The following procedure is operted according to SwChanlCallback8190Pci().
2384// However, this procedure is performed synchronously which should be running under
2385// passive level.
Florian Schilhabel0825c402010-07-14 14:44:18 +02002386
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002387void PHY_SwChnlPhy8192S( // Only called during initialize
2388 struct net_device* dev,
2389 u8 channel
2390 )
2391{
2392 struct r8192_priv *priv = ieee80211_priv(dev);
2393
2394 RT_TRACE(COMP_SCAN, "==>PHY_SwChnlPhy8192S(), switch to channel %d.\n", priv->chan);
2395
2396#ifdef TO_DO_LIST
2397 // Cannot IO.
2398 if(RT_CANNOT_IO(dev))
2399 return;
2400#endif
2401
2402 // Channel Switching is in progress.
2403 if(priv->SwChnlInProgress)
2404 return;
2405
2406 //return immediately if it is peudo-phy
2407 if(priv->rf_chip == RF_PSEUDO_11N)
2408 {
2409 priv->SwChnlInProgress=FALSE;
2410 return;
2411 }
2412
2413 priv->SwChnlInProgress = TRUE;
2414 if( channel == 0)
2415 channel = 1;
2416
2417 priv->chan=channel;
2418
2419 priv->SwChnlStage = 0;
2420 priv->SwChnlStep = 0;
2421
2422 phy_FinishSwChnlNow(dev,channel);
2423
2424 priv->SwChnlInProgress = FALSE;
2425}
2426
2427// use in phy only
2428static bool
2429phy_SetSwChnlCmdArray(
2430 SwChnlCmd* CmdTable,
2431 u32 CmdTableIdx,
2432 u32 CmdTableSz,
2433 SwChnlCmdID CmdID,
2434 u32 Para1,
2435 u32 Para2,
2436 u32 msDelay
2437 )
2438{
2439 SwChnlCmd* pCmd;
2440
2441 if(CmdTable == NULL)
2442 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002443 return FALSE;
2444 }
2445 if(CmdTableIdx >= CmdTableSz)
2446 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002447 return FALSE;
2448 }
2449
2450 pCmd = CmdTable + CmdTableIdx;
2451 pCmd->CmdID = CmdID;
2452 pCmd->Para1 = Para1;
2453 pCmd->Para2 = Para2;
2454 pCmd->msDelay = msDelay;
2455
2456 return TRUE;
2457}
2458
2459// use in phy only
2460static bool
2461phy_SwChnlStepByStep(
2462 struct net_device* dev,
2463 u8 channel,
2464 u8 *stage,
2465 u8 *step,
2466 u32 *delay
2467 )
2468{
2469 struct r8192_priv *priv = ieee80211_priv(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002470 SwChnlCmd PreCommonCmd[MAX_PRECMD_CNT];
2471 u32 PreCommonCmdCnt;
2472 SwChnlCmd PostCommonCmd[MAX_POSTCMD_CNT];
2473 u32 PostCommonCmdCnt;
2474 SwChnlCmd RfDependCmd[MAX_RFDEPENDCMD_CNT];
2475 u32 RfDependCmdCnt;
2476 SwChnlCmd *CurrentCmd = NULL;
2477 u8 eRFPath;
2478
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002479 RT_TRACE(COMP_CH, "===========>%s(), channel:%d, stage:%d, step:%d\n", __FUNCTION__, channel, *stage, *step);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002480 if (!IsLegalChannel(priv->ieee80211, channel))
2481 {
2482 RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n", channel);
2483 return true; //return true to tell upper caller function this channel setting is finished! Or it will in while loop.
2484 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002485
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002486 // <1> Fill up pre common command.
2487 PreCommonCmdCnt = 0;
2488 phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
2489 CmdID_SetTxPowerLevel, 0, 0, 0);
2490 phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
2491 CmdID_End, 0, 0, 0);
2492
2493 // <2> Fill up post common command.
2494 PostCommonCmdCnt = 0;
2495
2496 phy_SetSwChnlCmdArray(PostCommonCmd, PostCommonCmdCnt++, MAX_POSTCMD_CNT,
2497 CmdID_End, 0, 0, 0);
2498
2499 // <3> Fill up RF dependent command.
2500 RfDependCmdCnt = 0;
2501 switch( priv->rf_chip )
2502 {
2503 case RF_8225:
2504 if (channel < 1 || channel > 14)
2505 RT_TRACE(COMP_ERR, "illegal channel for zebra:%d\n", channel);
Florian Schilhabeldc7bbaa2010-07-14 14:44:00 +02002506
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002507 phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
2508 CmdID_RF_WriteReg, rRfChannel, channel, 10);
2509 phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
2510 CmdID_End, 0, 0, 0);
2511 break;
2512
2513 case RF_8256:
2514 if (channel < 1 || channel > 14)
2515 RT_TRACE(COMP_ERR, "illegal channel for zebra:%d\n", channel);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002516 phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
2517 CmdID_RF_WriteReg, rRfChannel, channel, 10);
2518 phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
2519 CmdID_End, 0, 0, 0);
2520 break;
2521
2522 case RF_6052:
2523 if (channel < 1 || channel > 14)
2524 RT_TRACE(COMP_ERR, "illegal channel for zebra:%d\n", channel);
2525 phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
2526 CmdID_RF_WriteReg, RF_CHNLBW, channel, 10);
2527 phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
2528 CmdID_End, 0, 0, 0);
2529 break;
2530
2531 case RF_8258:
2532 break;
2533
2534 default:
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002535 return FALSE;
2536 break;
2537 }
2538
2539
2540 do{
2541 switch(*stage)
2542 {
2543 case 0:
2544 CurrentCmd=&PreCommonCmd[*step];
2545 break;
2546 case 1:
2547 CurrentCmd=&RfDependCmd[*step];
2548 break;
2549 case 2:
2550 CurrentCmd=&PostCommonCmd[*step];
2551 break;
2552 }
2553
2554 if(CurrentCmd->CmdID==CmdID_End)
2555 {
2556 if((*stage)==2)
2557 {
2558 return TRUE;
2559 }
2560 else
2561 {
2562 (*stage)++;
2563 (*step)=0;
2564 continue;
2565 }
2566 }
2567
2568 switch(CurrentCmd->CmdID)
2569 {
2570 case CmdID_SetTxPowerLevel:
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002571 PHY_SetTxPowerLevel8192S(dev,channel);
2572 break;
2573 case CmdID_WritePortUlong:
2574 write_nic_dword(dev, CurrentCmd->Para1, CurrentCmd->Para2);
2575 break;
2576 case CmdID_WritePortUshort:
2577 write_nic_word(dev, CurrentCmd->Para1, (u16)CurrentCmd->Para2);
2578 break;
2579 case CmdID_WritePortUchar:
2580 write_nic_byte(dev, CurrentCmd->Para1, (u8)CurrentCmd->Para2);
2581 break;
2582 case CmdID_RF_WriteReg: // Only modify channel for the register now !!!!!
2583 for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
2584 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002585 // For new T65 RF 0222d register 0x18 bit 0-9 = channel number.
2586 rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, 0x1f, (CurrentCmd->Para2));
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002587 }
2588 break;
2589 default:
2590 break;
2591 }
2592
2593 break;
2594 }while(TRUE);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002595
2596 (*delay)=CurrentCmd->msDelay;
2597 (*step)++;
2598 RT_TRACE(COMP_CH, "<===========%s(), channel:%d, stage:%d, step:%d\n", __FUNCTION__, channel, *stage, *step);
2599 return FALSE;
2600}
2601
2602//called PHY_SwChnlPhy8192S, SwChnlCallback8192SUsbWorkItem
2603// use in phy only
2604static void
2605phy_FinishSwChnlNow( // We should not call this function directly
2606 struct net_device* dev,
2607 u8 channel
2608 )
2609{
2610 struct r8192_priv *priv = ieee80211_priv(dev);
2611 u32 delay;
2612
2613 while(!phy_SwChnlStepByStep(dev,channel,&priv->SwChnlStage,&priv->SwChnlStep,&delay))
2614 {
2615 if(delay>0)
2616 mdelay(delay);
2617 if(!priv->up)
2618 break;
2619 }
2620}
2621
2622
2623/*-----------------------------------------------------------------------------
2624 * Function: PHYCheckIsLegalRfPath8190Pci()
2625 *
2626 * Overview: Check different RF type to execute legal judgement. If RF Path is illegal
2627 * We will return false.
2628 *
2629 * Input: NONE
2630 *
2631 * Output: NONE
2632 *
2633 * Return: NONE
2634 *
2635 * Revised History:
2636 * When Who Remark
2637 * 11/15/2007 MHC Create Version 0.
2638 *
2639 *---------------------------------------------------------------------------*/
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002640u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath)
2641{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002642 bool rtValue = TRUE;
2643
2644 // NOt check RF Path now.!
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002645 return rtValue;
2646
2647} /* PHY_CheckIsLegalRfPath8192S */
2648
2649
2650
2651/*-----------------------------------------------------------------------------
2652 * Function: PHY_IQCalibrate8192S()
2653 *
2654 * Overview: After all MAC/PHY/RF is configued. We must execute IQ calibration
2655 * to improve RF EVM!!?
2656 *
2657 * Input: IN PADAPTER pAdapter
2658 *
2659 * Output: NONE
2660 *
2661 * Return: NONE
2662 *
2663 * Revised History:
2664 * When Who Remark
2665 * 10/07/2008 MHC Create. Document from SD3 RFSI Jenyu.
2666 *
2667 *---------------------------------------------------------------------------*/
2668 //called by InitializeAdapter8192SE
2669void
2670PHY_IQCalibrate( struct net_device* dev)
2671{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002672 u32 i, reg;
2673 u32 old_value;
2674 long X, Y, TX0[4];
2675 u32 TXA[4];
2676
2677 // 1. Check QFN68 or 64 92S (Read from EEPROM)
2678
2679 //
2680 // 2. QFN 68
2681 //
2682 // For 1T2R IQK only now !!!
2683 for (i = 0; i < 10; i++)
2684 {
2685 // IQK
2686 rtl8192_setBBreg(dev, 0xc04, bMaskDWord, 0x00a05430);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002687 udelay(5);
2688 rtl8192_setBBreg(dev, 0xc08, bMaskDWord, 0x000800e4);
2689 udelay(5);
2690 rtl8192_setBBreg(dev, 0xe28, bMaskDWord, 0x80800000);
2691 udelay(5);
2692 rtl8192_setBBreg(dev, 0xe40, bMaskDWord, 0x02140148);
2693 udelay(5);
2694 rtl8192_setBBreg(dev, 0xe44, bMaskDWord, 0x681604a2);
2695 udelay(5);
2696 rtl8192_setBBreg(dev, 0xe4c, bMaskDWord, 0x000028d1);
2697 udelay(5);
2698 rtl8192_setBBreg(dev, 0xe60, bMaskDWord, 0x0214014d);
2699 udelay(5);
2700 rtl8192_setBBreg(dev, 0xe64, bMaskDWord, 0x281608ba);
2701 udelay(5);
2702 rtl8192_setBBreg(dev, 0xe6c, bMaskDWord, 0x000028d1);
2703 udelay(5);
2704 rtl8192_setBBreg(dev, 0xe48, bMaskDWord, 0xfb000001);
2705 udelay(5);
2706 rtl8192_setBBreg(dev, 0xe48, bMaskDWord, 0xf8000001);
2707 udelay(2000);
2708 rtl8192_setBBreg(dev, 0xc04, bMaskDWord, 0x00a05433);
2709 udelay(5);
2710 rtl8192_setBBreg(dev, 0xc08, bMaskDWord, 0x000000e4);
2711 udelay(5);
2712 rtl8192_setBBreg(dev, 0xe28, bMaskDWord, 0x0);
2713
2714
2715 reg = rtl8192_QueryBBReg(dev, 0xeac, bMaskDWord);
2716
2717 // Readback IQK value and rewrite
2718 if (!(reg&(BIT27|BIT28|BIT30|BIT31)))
2719 {
2720 old_value = (rtl8192_QueryBBReg(dev, 0xc80, bMaskDWord) & 0x3FF);
2721
2722 // Calibrate init gain for A path for TX0
2723 X = (rtl8192_QueryBBReg(dev, 0xe94, bMaskDWord) & 0x03FF0000)>>16;
2724 TXA[RF90_PATH_A] = (X * old_value)/0x100;
2725 reg = rtl8192_QueryBBReg(dev, 0xc80, bMaskDWord);
2726 reg = (reg & 0xFFFFFC00) | (u32)TXA[RF90_PATH_A];
2727 rtl8192_setBBreg(dev, 0xc80, bMaskDWord, reg);
2728 udelay(5);
2729
2730 // Calibrate init gain for C path for TX0
2731 Y = ( rtl8192_QueryBBReg(dev, 0xe9C, bMaskDWord) & 0x03FF0000)>>16;
2732 TX0[RF90_PATH_C] = ((Y * old_value)/0x100);
2733 reg = rtl8192_QueryBBReg(dev, 0xc80, bMaskDWord);
2734 reg = (reg & 0xffc0ffff) |((u32) (TX0[RF90_PATH_C]&0x3F)<<16);
2735 rtl8192_setBBreg(dev, 0xc80, bMaskDWord, reg);
2736 reg = rtl8192_QueryBBReg(dev, 0xc94, bMaskDWord);
2737 reg = (reg & 0x0fffffff) |(((Y&0x3c0)>>6)<<28);
2738 rtl8192_setBBreg(dev, 0xc94, bMaskDWord, reg);
2739 udelay(5);
2740
2741 // Calibrate RX A and B for RX0
2742 reg = rtl8192_QueryBBReg(dev, 0xc14, bMaskDWord);
2743 X = (rtl8192_QueryBBReg(dev, 0xea4, bMaskDWord) & 0x03FF0000)>>16;
2744 reg = (reg & 0xFFFFFC00) |X;
2745 rtl8192_setBBreg(dev, 0xc14, bMaskDWord, reg);
2746 Y = (rtl8192_QueryBBReg(dev, 0xeac, bMaskDWord) & 0x003F0000)>>16;
2747 reg = (reg & 0xFFFF03FF) |Y<<10;
2748 rtl8192_setBBreg(dev, 0xc14, bMaskDWord, reg);
2749 udelay(5);
2750 old_value = (rtl8192_QueryBBReg(dev, 0xc88, bMaskDWord) & 0x3FF);
2751
2752 // Calibrate init gain for A path for TX1 !!!!!!
2753 X = (rtl8192_QueryBBReg(dev, 0xeb4, bMaskDWord) & 0x03FF0000)>>16;
2754 reg = rtl8192_QueryBBReg(dev, 0xc88, bMaskDWord);
2755 TXA[RF90_PATH_A] = (X * old_value) / 0x100;
2756 reg = (reg & 0xFFFFFC00) | TXA[RF90_PATH_A];
2757 rtl8192_setBBreg(dev, 0xc88, bMaskDWord, reg);
2758 udelay(5);
2759
2760 // Calibrate init gain for C path for TX1
2761 Y = (rtl8192_QueryBBReg(dev, 0xebc, bMaskDWord)& 0x03FF0000)>>16;
2762 TX0[RF90_PATH_C] = ((Y * old_value)/0x100);
2763 reg = rtl8192_QueryBBReg(dev, 0xc88, bMaskDWord);
2764 reg = (reg & 0xffc0ffff) |( (TX0[RF90_PATH_C]&0x3F)<<16);
2765 rtl8192_setBBreg(dev, 0xc88, bMaskDWord, reg);
2766 reg = rtl8192_QueryBBReg(dev, 0xc9c, bMaskDWord);
2767 reg = (reg & 0x0fffffff) |(((Y&0x3c0)>>6)<<28);
2768 rtl8192_setBBreg(dev, 0xc9c, bMaskDWord, reg);
2769 udelay(5);
2770
2771 // Calibrate RX A and B for RX1
2772 reg = rtl8192_QueryBBReg(dev, 0xc1c, bMaskDWord);
2773 X = (rtl8192_QueryBBReg(dev, 0xec4, bMaskDWord) & 0x03FF0000)>>16;
2774 reg = (reg & 0xFFFFFC00) |X;
2775 rtl8192_setBBreg(dev, 0xc1c, bMaskDWord, reg);
2776
2777 Y = (rtl8192_QueryBBReg(dev, 0xecc, bMaskDWord) & 0x003F0000)>>16;
2778 reg = (reg & 0xFFFF03FF) |Y<<10;
2779 rtl8192_setBBreg(dev, 0xc1c, bMaskDWord, reg);
2780 udelay(5);
2781
2782 RT_TRACE(COMP_INIT, "PHY_IQCalibrate OK\n");
2783 break;
2784 }
2785
2786 }
2787
2788
2789 //
2790 // 3. QFN64. Not enabled now !!! We must use different gain table for 1T2R.
2791 //
2792
2793
2794}
2795
2796/*-----------------------------------------------------------------------------
2797 * Function: PHY_IQCalibrateBcut()
2798 *
2799 * Overview: After all MAC/PHY/RF is configued. We must execute IQ calibration
2800 * to improve RF EVM!!?
2801 *
2802 * Input: IN PADAPTER pAdapter
2803 *
2804 * Output: NONE
2805 *
2806 * Return: NONE
2807 *
2808 * Revised History:
2809 * When Who Remark
2810 * 11/18/2008 MHC Create. Document from SD3 RFSI Jenyu.
2811 * 92S B-cut QFN 68 pin IQ calibration procedure.doc
2812 *
2813 *---------------------------------------------------------------------------*/
2814extern void PHY_IQCalibrateBcut(struct net_device* dev)
2815{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002816 u32 i, reg;
2817 u32 old_value;
2818 long X, Y, TX0[4];
2819 u32 TXA[4];
2820 u32 calibrate_set[13] = {0};
2821 u32 load_value[13];
2822 u8 RfPiEnable=0;
2823
2824 // 0. Check QFN68 or 64 92S (Read from EEPROM/EFUSE)
2825
2826 //
2827 // 1. Save e70~ee0 register setting, and load calibration setting
2828 //
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002829 calibrate_set [0] = 0xee0;
2830 calibrate_set [1] = 0xedc;
2831 calibrate_set [2] = 0xe70;
2832 calibrate_set [3] = 0xe74;
2833 calibrate_set [4] = 0xe78;
2834 calibrate_set [5] = 0xe7c;
2835 calibrate_set [6] = 0xe80;
2836 calibrate_set [7] = 0xe84;
2837 calibrate_set [8] = 0xe88;
2838 calibrate_set [9] = 0xe8c;
2839 calibrate_set [10] = 0xed0;
2840 calibrate_set [11] = 0xed4;
2841 calibrate_set [12] = 0xed8;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002842 for (i = 0; i < 13; i++)
2843 {
2844 load_value[i] = rtl8192_QueryBBReg(dev, calibrate_set[i], bMaskDWord);
2845 rtl8192_setBBreg(dev, calibrate_set[i], bMaskDWord, 0x3fed92fb);
2846
2847 }
2848
2849 RfPiEnable = (u8)rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter1, BIT8);
2850
2851 //
2852 // 2. QFN 68
2853 //
2854 // For 1T2R IQK only now !!!
2855 for (i = 0; i < 10; i++)
2856 {
2857 RT_TRACE(COMP_INIT, "IQK -%d\n", i);
2858 //BB switch to PI mode. If default is PI mode, ignoring 2 commands below.
2859 if (!RfPiEnable) //if original is SI mode, then switch to PI mode.
2860 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002861 rtl8192_setBBreg(dev, 0x820, bMaskDWord, 0x01000100);
2862 rtl8192_setBBreg(dev, 0x828, bMaskDWord, 0x01000100);
2863 }
2864
2865 // IQK
2866 // 2. IQ calibration & LO leakage calibration
2867 rtl8192_setBBreg(dev, 0xc04, bMaskDWord, 0x00a05430);
2868 udelay(5);
2869 rtl8192_setBBreg(dev, 0xc08, bMaskDWord, 0x000800e4);
2870 udelay(5);
2871 rtl8192_setBBreg(dev, 0xe28, bMaskDWord, 0x80800000);
2872 udelay(5);
2873 //path-A IQ K and LO K gain setting
2874 rtl8192_setBBreg(dev, 0xe40, bMaskDWord, 0x02140102);
2875 udelay(5);
2876 rtl8192_setBBreg(dev, 0xe44, bMaskDWord, 0x681604c2);
2877 udelay(5);
2878 //set LO calibration
2879 rtl8192_setBBreg(dev, 0xe4c, bMaskDWord, 0x000028d1);
2880 udelay(5);
2881 //path-B IQ K and LO K gain setting
2882 rtl8192_setBBreg(dev, 0xe60, bMaskDWord, 0x02140102);
2883 udelay(5);
2884 rtl8192_setBBreg(dev, 0xe64, bMaskDWord, 0x28160d05);
2885 udelay(5);
2886 //K idac_I & IQ
2887 rtl8192_setBBreg(dev, 0xe48, bMaskDWord, 0xfb000000);
2888 udelay(5);
2889 rtl8192_setBBreg(dev, 0xe48, bMaskDWord, 0xf8000000);
2890 udelay(5);
2891
2892 // delay 2ms
2893 udelay(2000);
2894
2895 //idac_Q setting
2896 rtl8192_setBBreg(dev, 0xe6c, bMaskDWord, 0x020028d1);
2897 udelay(5);
2898 //K idac_Q & IQ
2899 rtl8192_setBBreg(dev, 0xe48, bMaskDWord, 0xfb000000);
2900 udelay(5);
2901 rtl8192_setBBreg(dev, 0xe48, bMaskDWord, 0xf8000000);
2902
2903 // delay 2ms
2904 udelay(2000);
2905
2906 rtl8192_setBBreg(dev, 0xc04, bMaskDWord, 0x00a05433);
2907 udelay(5);
2908 rtl8192_setBBreg(dev, 0xc08, bMaskDWord, 0x000000e4);
2909 udelay(5);
2910 rtl8192_setBBreg(dev, 0xe28, bMaskDWord, 0x0);
2911
2912 if (!RfPiEnable) //if original is SI mode, then switch to PI mode.
2913 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002914 rtl8192_setBBreg(dev, 0x820, bMaskDWord, 0x01000000);
2915 rtl8192_setBBreg(dev, 0x828, bMaskDWord, 0x01000000);
2916 }
2917
2918
2919 reg = rtl8192_QueryBBReg(dev, 0xeac, bMaskDWord);
2920
2921 // 3. check fail bit, and fill BB IQ matrix
2922 // Readback IQK value and rewrite
2923 if (!(reg&(BIT27|BIT28|BIT30|BIT31)))
2924 {
2925 old_value = (rtl8192_QueryBBReg(dev, 0xc80, bMaskDWord) & 0x3FF);
2926
2927 // Calibrate init gain for A path for TX0
2928 X = (rtl8192_QueryBBReg(dev, 0xe94, bMaskDWord) & 0x03FF0000)>>16;
2929 TXA[RF90_PATH_A] = (X * old_value)/0x100;
2930 reg = rtl8192_QueryBBReg(dev, 0xc80, bMaskDWord);
2931 reg = (reg & 0xFFFFFC00) | (u32)TXA[RF90_PATH_A];
2932 rtl8192_setBBreg(dev, 0xc80, bMaskDWord, reg);
2933 udelay(5);
2934
2935 // Calibrate init gain for C path for TX0
2936 Y = ( rtl8192_QueryBBReg(dev, 0xe9C, bMaskDWord) & 0x03FF0000)>>16;
2937 TX0[RF90_PATH_C] = ((Y * old_value)/0x100);
2938 reg = rtl8192_QueryBBReg(dev, 0xc80, bMaskDWord);
2939 reg = (reg & 0xffc0ffff) |((u32) (TX0[RF90_PATH_C]&0x3F)<<16);
2940 rtl8192_setBBreg(dev, 0xc80, bMaskDWord, reg);
2941 reg = rtl8192_QueryBBReg(dev, 0xc94, bMaskDWord);
2942 reg = (reg & 0x0fffffff) |(((Y&0x3c0)>>6)<<28);
2943 rtl8192_setBBreg(dev, 0xc94, bMaskDWord, reg);
2944 udelay(5);
2945
2946 // Calibrate RX A and B for RX0
2947 reg = rtl8192_QueryBBReg(dev, 0xc14, bMaskDWord);
2948 X = (rtl8192_QueryBBReg(dev, 0xea4, bMaskDWord) & 0x03FF0000)>>16;
2949 reg = (reg & 0xFFFFFC00) |X;
2950 rtl8192_setBBreg(dev, 0xc14, bMaskDWord, reg);
2951 Y = (rtl8192_QueryBBReg(dev, 0xeac, bMaskDWord) & 0x003F0000)>>16;
2952 reg = (reg & 0xFFFF03FF) |Y<<10;
2953 rtl8192_setBBreg(dev, 0xc14, bMaskDWord, reg);
2954 udelay(5);
2955 old_value = (rtl8192_QueryBBReg(dev, 0xc88, bMaskDWord) & 0x3FF);
2956
2957 // Calibrate init gain for A path for TX1 !!!!!!
2958 X = (rtl8192_QueryBBReg(dev, 0xeb4, bMaskDWord) & 0x03FF0000)>>16;
2959 reg = rtl8192_QueryBBReg(dev, 0xc88, bMaskDWord);
2960 TXA[RF90_PATH_A] = (X * old_value) / 0x100;
2961 reg = (reg & 0xFFFFFC00) | TXA[RF90_PATH_A];
2962 rtl8192_setBBreg(dev, 0xc88, bMaskDWord, reg);
2963 udelay(5);
2964
2965 // Calibrate init gain for C path for TX1
2966 Y = (rtl8192_QueryBBReg(dev, 0xebc, bMaskDWord)& 0x03FF0000)>>16;
2967 TX0[RF90_PATH_C] = ((Y * old_value)/0x100);
2968 reg = rtl8192_QueryBBReg(dev, 0xc88, bMaskDWord);
2969 reg = (reg & 0xffc0ffff) |( (TX0[RF90_PATH_C]&0x3F)<<16);
2970 rtl8192_setBBreg(dev, 0xc88, bMaskDWord, reg);
2971 reg = rtl8192_QueryBBReg(dev, 0xc9c, bMaskDWord);
2972 reg = (reg & 0x0fffffff) |(((Y&0x3c0)>>6)<<28);
2973 rtl8192_setBBreg(dev, 0xc9c, bMaskDWord, reg);
2974 udelay(5);
2975
2976 // Calibrate RX A and B for RX1
2977 reg = rtl8192_QueryBBReg(dev, 0xc1c, bMaskDWord);
2978 X = (rtl8192_QueryBBReg(dev, 0xec4, bMaskDWord) & 0x03FF0000)>>16;
2979 reg = (reg & 0xFFFFFC00) |X;
2980 rtl8192_setBBreg(dev, 0xc1c, bMaskDWord, reg);
2981
2982 Y = (rtl8192_QueryBBReg(dev, 0xecc, bMaskDWord) & 0x003F0000)>>16;
2983 reg = (reg & 0xFFFF03FF) |Y<<10;
2984 rtl8192_setBBreg(dev, 0xc1c, bMaskDWord, reg);
2985 udelay(5);
2986
2987 RT_TRACE(COMP_INIT, "PHY_IQCalibrate OK\n");
2988 break;
2989 }
2990
2991 }
2992
2993 //
2994 // 4. Reload e70~ee0 register setting.
2995 //
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07002996 for (i = 0; i < 13; i++)
2997 rtl8192_setBBreg(dev, calibrate_set[i], bMaskDWord, load_value[i]);
2998
2999
3000 //
3001 // 3. QFN64. Not enabled now !!! We must use different gain table for 1T2R.
3002 //
3003
3004
3005
Florian Schilhabeldc7bbaa2010-07-14 14:44:00 +02003006}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003007
3008
3009//
3010// Move from phycfg.c to gen.c to be code independent later
3011//
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003012
3013// use in phy only (in win it's timer)
3014void SwChnlCallback8192SUsb(struct net_device *dev)
3015{
3016
3017 struct r8192_priv *priv = ieee80211_priv(dev);
3018 u32 delay;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003019
Joe Perchesc7e10c92010-02-01 23:22:14 -08003020 RT_TRACE(COMP_SCAN, "==>SwChnlCallback8190Pci(), switch to channel %d\n",
3021 priv->chan);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003022
3023
3024 if(!priv->up)
3025 return;
3026
3027 if(priv->rf_chip == RF_PSEUDO_11N)
3028 {
3029 priv->SwChnlInProgress=FALSE;
3030 return; //return immediately if it is peudo-phy
3031 }
3032
3033 do{
3034 if(!priv->SwChnlInProgress)
3035 break;
3036
3037 if(!phy_SwChnlStepByStep(dev, priv->chan, &priv->SwChnlStage, &priv->SwChnlStep, &delay))
3038 {
3039 if(delay>0)
3040 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003041
3042 }
3043 else
3044 continue;
3045 }
3046 else
3047 {
3048 priv->SwChnlInProgress=FALSE;
3049 }
3050 break;
3051 }while(TRUE);
3052}
3053
3054
3055//
3056// Callback routine of the work item for switch channel.
3057//
3058// use in phy only (in win it's work)
3059void SwChnlCallback8192SUsbWorkItem(struct net_device *dev )
3060{
3061 struct r8192_priv *priv = ieee80211_priv(dev);
3062
3063 RT_TRACE(COMP_TRACE, "==> SwChnlCallback8192SUsbWorkItem()\n");
3064#ifdef TO_DO_LIST
3065 if(pAdapter->bInSetPower && RT_USB_CANNOT_IO(pAdapter))
3066 {
3067 RT_TRACE(COMP_SCAN, DBG_LOUD, ("<== SwChnlCallback8192SUsbWorkItem() SwChnlInProgress FALSE driver sleep or unload\n"));
3068
3069 pHalData->SwChnlInProgress = FALSE;
3070 return;
3071 }
3072#endif
3073 phy_FinishSwChnlNow(dev, priv->chan);
3074 priv->SwChnlInProgress = FALSE;
3075
3076 RT_TRACE(COMP_TRACE, "<== SwChnlCallback8192SUsbWorkItem()\n");
3077}
3078
3079
3080/*-----------------------------------------------------------------------------
3081 * Function: SetBWModeCallback8192SUsb()
3082 *
3083 * Overview: Timer callback function for SetSetBWMode
3084 *
3085 * Input: PRT_TIMER pTimer
3086 *
3087 * Output: NONE
3088 *
3089 * Return: NONE
3090 *
3091 * Note: (1) We do not take j mode into consideration now
3092 * (2) Will two workitem of "switch channel" and "switch channel bandwidth" run
3093 * concurrently?
3094 *---------------------------------------------------------------------------*/
Florian Schilhabeldc7bbaa2010-07-14 14:44:00 +02003095// use in phy only
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003096void SetBWModeCallback8192SUsb(struct net_device *dev)
3097{
3098 struct r8192_priv *priv = ieee80211_priv(dev);
3099 u8 regBwOpMode;
3100
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003101 u8 regRRSR_RSC;
3102
3103 RT_TRACE(COMP_SCAN, "==>SetBWModeCallback8190Pci() Switch to %s bandwidth\n", \
3104 priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz");
3105
3106 if(priv->rf_chip == RF_PSEUDO_11N)
3107 {
3108 priv->SetBWModeInProgress= FALSE;
3109 return;
3110 }
3111
3112 if(!priv->up)
3113 return;
3114
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003115
3116 //3<1>Set MAC register
3117 regBwOpMode = read_nic_byte(dev, BW_OPMODE);
3118 regRRSR_RSC = read_nic_byte(dev, RRSR+2);
3119
3120 switch(priv->CurrentChannelBW)
3121 {
3122 case HT_CHANNEL_WIDTH_20:
3123 regBwOpMode |= BW_OPMODE_20MHZ;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003124 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3125 break;
3126
3127 case HT_CHANNEL_WIDTH_20_40:
3128 regBwOpMode &= ~BW_OPMODE_20MHZ;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003129 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3130
3131 regRRSR_RSC = (regRRSR_RSC&0x90) |(priv->nCur40MhzPrimeSC<<5);
3132 write_nic_byte(dev, RRSR+2, regRRSR_RSC);
3133 break;
3134
3135 default:
Joe Perchesc7e10c92010-02-01 23:22:14 -08003136 RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci(): unknown Bandwidth: %#X\n",
3137 priv->CurrentChannelBW);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003138 break;
3139 }
3140
3141 //3 <2>Set PHY related register
3142 switch(priv->CurrentChannelBW)
3143 {
3144 case HT_CHANNEL_WIDTH_20:
3145 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
3146 rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003147
3148 if (priv->card_8192_version >= VERSION_8192S_BCUT)
3149 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58);
3150
3151 break;
3152 case HT_CHANNEL_WIDTH_20_40:
3153 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
3154 rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
3155 rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
3156 rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC);
3157
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003158 if (priv->card_8192_version >= VERSION_8192S_BCUT)
3159 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x18);
3160
3161 break;
3162 default:
3163 RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci(): unknown Bandwidth: %#X\n"\
3164 ,priv->CurrentChannelBW);
3165 break;
3166
3167 }
3168 //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315
3169
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003170#if 1
3171 //3<3>Set RF related register
3172 switch( priv->rf_chip )
3173 {
3174 case RF_8225:
3175 PHY_SetRF8225Bandwidth(dev, priv->CurrentChannelBW);
3176 break;
3177
3178 case RF_8256:
3179 // Please implement this function in Hal8190PciPhy8256.c
3180 //PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW);
3181 break;
3182
3183 case RF_6052:
3184 PHY_RF6052SetBandwidth(dev, priv->CurrentChannelBW);
3185 break;
3186
3187 case RF_8258:
3188 // Please implement this function in Hal8190PciPhy8258.c
3189 // PHY_SetRF8258Bandwidth();
3190 break;
3191
3192 case RF_PSEUDO_11N:
3193 // Do Nothing
3194 break;
3195
3196 default:
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003197 break;
3198 }
3199#endif
3200 priv->SetBWModeInProgress= FALSE;
3201
3202 RT_TRACE(COMP_SCAN, "<==SetBWMode8190Pci()" );
3203}
3204
Florian Schilhabeldf35bf62010-03-18 15:18:34 +01003205/*
3206 * Callback routine of the work item for set bandwidth mode.
3207 *
3208 * use in phy only (in win it's work)
3209 */
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003210void SetBWModeCallback8192SUsbWorkItem(struct net_device *dev)
3211{
Florian Schilhabeldf35bf62010-03-18 15:18:34 +01003212 struct r8192_priv *priv = ieee80211_priv(dev);
3213 u8 regBwOpMode;
3214 u8 regRRSR_RSC;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003215
Florian Schilhabeldf35bf62010-03-18 15:18:34 +01003216 RT_TRACE(COMP_SCAN, "%s(): Switch to %s bandwidth", __func__,
3217 priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ? "20MHz" : "40MHz");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003218
Florian Schilhabeldf35bf62010-03-18 15:18:34 +01003219 if (priv->rf_chip == RF_PSEUDO_11N) {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003220 priv->SetBWModeInProgress= FALSE;
3221 return;
3222 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003223 if(!priv->up)
3224 return;
Florian Schilhabeldf35bf62010-03-18 15:18:34 +01003225 /* Set MAC register */
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003226 regBwOpMode = read_nic_byte(dev, BW_OPMODE);
3227 regRRSR_RSC = read_nic_byte(dev, RRSR+2);
Florian Schilhabeldf35bf62010-03-18 15:18:34 +01003228 switch (priv->CurrentChannelBW) {
3229 case HT_CHANNEL_WIDTH_20:
3230 regBwOpMode |= BW_OPMODE_20MHZ;
3231 /* we have not verified whether this register works */
3232 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3233 break;
3234 case HT_CHANNEL_WIDTH_20_40:
3235 regBwOpMode &= ~BW_OPMODE_20MHZ;
3236 /* we have not verified whether this register works */
3237 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3238 regRRSR_RSC = (regRRSR_RSC&0x90) | (priv->nCur40MhzPrimeSC<<5);
3239 write_nic_byte(dev, RRSR+2, regRRSR_RSC);
3240 break;
3241 default:
3242 RT_TRACE(COMP_DBG, "%s(): unknown Bandwidth: %#X", __func__,
3243 priv->CurrentChannelBW);
3244 break;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003245 }
Florian Schilhabeldf35bf62010-03-18 15:18:34 +01003246 /* Set PHY related register */
3247 switch (priv->CurrentChannelBW) {
3248 case HT_CHANNEL_WIDTH_20:
3249 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
3250 rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
3251 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58);
3252 break;
3253 case HT_CHANNEL_WIDTH_20_40:
3254 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
3255 rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
3256 /*
3257 * Set Control channel to upper or lower.
3258 * These settings are required only for 40MHz
3259 */
3260 rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand,
3261 (priv->nCur40MhzPrimeSC>>1));
3262 rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00,
3263 priv->nCur40MhzPrimeSC);
3264 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x18);
3265 break;
3266 default:
3267 RT_TRACE(COMP_DBG, "%s(): unknown Bandwidth: %#X", __func__,
3268 priv->CurrentChannelBW);
3269 break;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003270
3271 }
Florian Schilhabeldf35bf62010-03-18 15:18:34 +01003272 /*
3273 * Skip over setting of J-mode in BB register here.
3274 * Default value is "None J mode".
3275 */
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003276
Florian Schilhabeldf35bf62010-03-18 15:18:34 +01003277 /* Set RF related register */
3278 switch (priv->rf_chip) {
3279 case RF_8225:
3280 PHY_SetRF8225Bandwidth(dev, priv->CurrentChannelBW);
3281 break;
3282 case RF_8256:
3283 /* Please implement this function in Hal8190PciPhy8256.c */
3284 /* PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW); */
3285 break;
3286 case RF_6052:
3287 PHY_RF6052SetBandwidth(dev, priv->CurrentChannelBW);
3288 break;
3289 case RF_8258:
3290 /* Please implement this function in Hal8190PciPhy8258.c */
3291 /* PHY_SetRF8258Bandwidth(); */
3292 break;
3293 case RF_PSEUDO_11N:
3294 /* Do Nothing */
3295 break;
3296 default:
3297 RT_TRACE(COMP_DBG, "%s(): unknown rf_chip: %d", __func__,
3298 priv->rf_chip);
3299 break;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003300 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003301 priv->SetBWModeInProgress= FALSE;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003302}
3303
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003304void InitialGain8192S(struct net_device *dev, u8 Operation)
3305{
3306#ifdef TO_DO_LIST
3307 struct r8192_priv *priv = ieee80211_priv(dev);
3308#endif
3309
3310}
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003311
3312void InitialGain819xUsb(struct net_device *dev, u8 Operation)
3313{
3314 struct r8192_priv *priv = ieee80211_priv(dev);
3315
3316 priv->InitialGainOperateType = Operation;
3317
3318 if(priv->up)
3319 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003320 queue_delayed_work(priv->priv_wq,&priv->initialgain_operate_wq,0);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003321 }
3322}
3323
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003324extern void InitialGainOperateWorkItemCallBack(struct work_struct *work)
3325{
3326 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
3327 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,initialgain_operate_wq);
3328 struct net_device *dev = priv->ieee80211->dev;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003329#define SCAN_RX_INITIAL_GAIN 0x17
3330#define POWER_DETECTION_TH 0x08
3331 u32 BitMask;
3332 u8 initial_gain;
3333 u8 Operation;
3334
3335 Operation = priv->InitialGainOperateType;
3336
3337 switch(Operation)
3338 {
3339 case IG_Backup:
3340 RT_TRACE(COMP_SCAN, "IG_Backup, backup the initial gain.\n");
3341 initial_gain = SCAN_RX_INITIAL_GAIN;//priv->DefaultInitialGain[0];//
3342 BitMask = bMaskByte0;
3343 if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
3344 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // FW DIG OFF
3345 priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, BitMask);
3346 priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, BitMask);
3347 priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, BitMask);
3348 priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, BitMask);
3349 BitMask = bMaskByte2;
3350 priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, BitMask);
3351
3352 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
3353 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
3354 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
3355 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
3356 RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca);
3357
3358 RT_TRACE(COMP_SCAN, "Write scan initial gain = 0x%x \n", initial_gain);
3359 write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
3360 write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
3361 write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
3362 write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
3363 RT_TRACE(COMP_SCAN, "Write scan 0xa0a = 0x%x \n", POWER_DETECTION_TH);
3364 write_nic_byte(dev, 0xa0a, POWER_DETECTION_TH);
3365 break;
3366 case IG_Restore:
3367 RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial gain.\n");
3368 BitMask = 0x7f; //Bit0~ Bit6
3369 if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
3370 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // FW DIG OFF
3371
3372 rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, BitMask, (u32)priv->initgain_backup.xaagccore1);
3373 rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, BitMask, (u32)priv->initgain_backup.xbagccore1);
3374 rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, BitMask, (u32)priv->initgain_backup.xcagccore1);
3375 rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, BitMask, (u32)priv->initgain_backup.xdagccore1);
3376 BitMask = bMaskByte2;
3377 rtl8192_setBBreg(dev, rCCK0_CCA, BitMask, (u32)priv->initgain_backup.cca);
3378
3379 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
3380 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
3381 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
3382 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
3383 RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca);
3384
3385 PHY_SetTxPowerLevel8192S(dev,priv->ieee80211->current_network.channel);
3386
3387 if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
3388 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // FW DIG ON
3389 break;
3390 default:
3391 RT_TRACE(COMP_SCAN, "Unknown IG Operation. \n");
3392 break;
3393 }
3394}
3395
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003396
3397//-----------------------------------------------------------------------------
3398// Description:
3399// Schedule workitem to send specific CMD IO to FW.
3400// Added by Roger, 2008.12.03.
3401//
3402//-----------------------------------------------------------------------------
3403bool HalSetFwCmd8192S(struct net_device* dev, FW_CMD_IO_TYPE FwCmdIO)
3404{
3405 struct r8192_priv *priv = ieee80211_priv(dev);
3406 u16 FwCmdWaitCounter = 0;
3407
3408 u16 FwCmdWaitLimit = 1000;
3409
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003410 if(priv->bInHctTest)
3411 return true;
3412
3413 RT_TRACE(COMP_CMD, "-->HalSetFwCmd8192S(): Set FW Cmd(%x), SetFwCmdInProgress(%d)\n", (u32)FwCmdIO, priv->SetFwCmdInProgress);
3414
3415 // Will be done by high power respectively.
3416 if(FwCmdIO==FW_CMD_DIG_HALT || FwCmdIO==FW_CMD_DIG_RESUME)
3417 {
3418 RT_TRACE(COMP_CMD, "<--HalSetFwCmd8192S(): Set FW Cmd(%x)\n", (u32)FwCmdIO);
3419 return false;
3420 }
3421
3422#if 1
3423 while(priv->SetFwCmdInProgress && FwCmdWaitCounter<FwCmdWaitLimit)
3424 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003425
3426 RT_TRACE(COMP_CMD, "HalSetFwCmd8192S(): previous workitem not finish!!\n");
3427 return false;
3428 FwCmdWaitCounter ++;
3429 RT_TRACE(COMP_CMD, "HalSetFwCmd8192S(): Wait 10 ms (%d times)...\n", FwCmdWaitCounter);
3430 udelay(100);
3431 }
3432
3433 if(FwCmdWaitCounter == FwCmdWaitLimit)
3434 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003435 RT_TRACE(COMP_CMD, "HalSetFwCmd8192S(): Wait too logn to set FW CMD\n");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003436 }
3437#endif
3438 if (priv->SetFwCmdInProgress)
3439 {
3440 RT_TRACE(COMP_ERR, "<--HalSetFwCmd8192S(): Set FW Cmd(%#x)\n", FwCmdIO);
3441 return false;
3442 }
3443 priv->SetFwCmdInProgress = TRUE;
3444 priv->CurrentFwCmdIO = FwCmdIO; // Update current FW Cmd for callback use.
3445
3446 phy_SetFwCmdIOCallback(dev);
3447 return true;
3448}
3449void ChkFwCmdIoDone(struct net_device* dev)
3450{
3451 u16 PollingCnt = 1000;
3452 u32 tmpValue;
3453
3454 do
3455 {// Make sure that CMD IO has be accepted by FW.
3456#ifdef TO_DO_LIST
3457 if(RT_USB_CANNOT_IO(Adapter))
3458 {
3459 RT_TRACE(COMP_CMD, "ChkFwCmdIoDone(): USB can NOT IO!!\n");
3460 return;
3461 }
3462#endif
3463 udelay(10); // sleep 20us
3464 tmpValue = read_nic_dword(dev, WFM5);
3465 if(tmpValue == 0)
3466 {
3467 RT_TRACE(COMP_CMD, "[FW CMD] Set FW Cmd success!!\n");
3468 break;
3469 }
3470 else
3471 {
3472 RT_TRACE(COMP_CMD, "[FW CMD] Polling FW Cmd PollingCnt(%d)!!\n", PollingCnt);
3473 }
3474 }while( --PollingCnt );
3475
3476 if(PollingCnt == 0)
3477 {
3478 RT_TRACE(COMP_ERR, "[FW CMD] Set FW Cmd fail!!\n");
3479 }
3480}
3481// Callback routine of the timer callback for FW Cmd IO.
3482//
3483// Description:
3484// This routine will send specific CMD IO to FW and check whether it is done.
3485//
3486void phy_SetFwCmdIOCallback(struct net_device* dev)
3487{
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003488 struct r8192_priv *priv = ieee80211_priv(dev);
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003489 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
3490 rt_firmware *pFirmware = priv->pFirmware;
3491 u32 input, CurrentAID = 0;;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003492 if(!priv->up)
3493 {
3494 RT_TRACE(COMP_CMD, "SetFwCmdIOTimerCallback(): driver is going to unload\n");
3495 return;
3496 }
3497
3498 RT_TRACE(COMP_CMD, "--->SetFwCmdIOTimerCallback(): Cmd(%#x), SetFwCmdInProgress(%d)\n", priv->CurrentFwCmdIO, priv->SetFwCmdInProgress);
3499
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003500 if(pFirmware->FirmwareVersion >= 0x34)
3501 {
3502 switch(priv->CurrentFwCmdIO)
3503 {
3504 case FW_CMD_RA_REFRESH_N:
3505 priv->CurrentFwCmdIO = FW_CMD_RA_REFRESH_N_COMB;
3506 break;
3507 case FW_CMD_RA_REFRESH_BG:
3508 priv->CurrentFwCmdIO = FW_CMD_RA_REFRESH_BG_COMB;
3509 break;
3510 default:
3511 break;
3512 }
3513 }
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003514 switch(priv->CurrentFwCmdIO)
3515 {
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003516
3517 case FW_CMD_RA_RESET:
3518 write_nic_dword(dev, WFM5, FW_RA_RESET);
3519 break;
3520
3521 case FW_CMD_RA_ACTIVE:
3522 write_nic_dword(dev, WFM5, FW_RA_ACTIVE);
3523 break;
3524
3525 case FW_CMD_RA_REFRESH_N:
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003526 RT_TRACE(COMP_CMD, "[FW CMD] Set RA n refresh!!\n");
3527 if(pHTInfo->IOTRaFunc & HT_IOT_RAFUNC_DISABLE_ALL)
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003528 input = FW_RA_REFRESH;
3529 else
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003530 input = FW_RA_REFRESH | (pHTInfo->IOTRaFunc << 8);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003531 write_nic_dword(dev, WFM5, input);
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003532 ChkFwCmdIoDone(dev);
3533 write_nic_dword(dev, WFM5, FW_RA_ENABLE_RSSI_MASK);
3534 ChkFwCmdIoDone(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003535 break;
3536 case FW_CMD_RA_REFRESH_BG:
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003537 RT_TRACE(COMP_CMD, "[FW CMD] Set RA BG refresh!!\n");
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003538 write_nic_dword(dev, WFM5, FW_RA_REFRESH);
3539 ChkFwCmdIoDone(dev);
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003540 write_nic_dword(dev, WFM5, FW_RA_DISABLE_RSSI_MASK);
3541 ChkFwCmdIoDone(dev);
3542 break;
3543
3544 case FW_CMD_RA_REFRESH_N_COMB:
3545 RT_TRACE(COMP_CMD, "[FW CMD] Set RA n Combo refresh!!\n");
3546 if(pHTInfo->IOTRaFunc & HT_IOT_RAFUNC_DISABLE_ALL)
3547 input = FW_RA_IOT_N_COMB;
3548 else
3549 input = FW_RA_IOT_N_COMB | (((pHTInfo->IOTRaFunc)&0x0f) << 8);
3550 input = input |((pHTInfo->IOTPeer & 0xf) <<12);
3551 RT_TRACE(COMP_CMD, "[FW CMD] Set RA/IOT Comb in n mode!! input(%#x)\n", input);
3552 write_nic_dword(dev, WFM5, input);
3553 ChkFwCmdIoDone(dev);
3554 break;
3555
3556 case FW_CMD_RA_REFRESH_BG_COMB:
3557 RT_TRACE(COMP_CMD, "[FW CMD] Set RA B/G Combo refresh!!\n");
3558 if(pHTInfo->IOTRaFunc & HT_IOT_RAFUNC_DISABLE_ALL)
3559 input = FW_RA_IOT_BG_COMB;
3560 else
3561 input = FW_RA_IOT_BG_COMB | (((pHTInfo->IOTRaFunc)&0x0f) << 8);
3562 input = input |((pHTInfo->IOTPeer & 0xf) <<12);
3563 RT_TRACE(COMP_CMD, "[FW CMD] Set RA/IOT Comb in B/G mode!! input(%#x)\n", input);
3564 write_nic_dword(dev, WFM5, input);
3565 ChkFwCmdIoDone(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003566 break;
3567
3568 case FW_CMD_IQK_ENABLE:
3569 write_nic_dword(dev, WFM5, FW_IQK_ENABLE);
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003570 ChkFwCmdIoDone(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003571 break;
3572
3573 case FW_CMD_TXPWR_TRACK_ENABLE:
3574 write_nic_dword(dev, WFM5, FW_TXPWR_TRACK_ENABLE);
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003575 ChkFwCmdIoDone(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003576 break;
3577
3578 case FW_CMD_TXPWR_TRACK_DISABLE:
3579 write_nic_dword(dev, WFM5, FW_TXPWR_TRACK_DISABLE);
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003580 ChkFwCmdIoDone(dev);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003581 break;
3582
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003583 case FW_CMD_PAUSE_DM_BY_SCAN:
3584 RT_TRACE(COMP_CMD,"[FW CMD] Pause DM by Scan!!\n");
3585 rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bMaskByte0, 0x17);
3586 rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bMaskByte0, 0x17);
3587 rtl8192_setBBreg(dev, rCCK0_CCA, bMaskByte2, 0x40);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003588 break;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003589
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003590 case FW_CMD_RESUME_DM_BY_SCAN:
3591 RT_TRACE(COMP_CMD, "[FW CMD] Resume DM by Scan!!\n");
3592 rtl8192_setBBreg(dev, rCCK0_CCA, bMaskByte2, 0x83);
3593 PHY_SetTxPowerLevel8192S(dev, priv->chan);
3594 break;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003595 case FW_CMD_HIGH_PWR_DISABLE:
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003596 RT_TRACE(COMP_CMD, "[FW CMD] High Pwr Disable!!\n");
3597 if(priv->DMFlag & HAL_DM_HIPWR_DISABLE)
3598 break;
3599 rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bMaskByte0, 0x17);
3600 rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bMaskByte0, 0x17);
3601 rtl8192_setBBreg(dev, rCCK0_CCA, bMaskByte2, 0x40);
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003602 break;
3603
3604 case FW_CMD_HIGH_PWR_ENABLE:
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003605 RT_TRACE(COMP_CMD, "[FW CMD] High Pwr Enable!!\n");
3606 if(priv->DMFlag & HAL_DM_HIPWR_DISABLE)
3607 break;
3608 rtl8192_setBBreg(dev, rCCK0_CCA, bMaskByte2, 0x83);
3609 break;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003610
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003611 case FW_CMD_LPS_ENTER:
3612 RT_TRACE(COMP_CMD, "[FW CMD] Enter LPS mode!!\n");
3613 CurrentAID = priv->ieee80211->assoc_id;
3614 write_nic_dword(dev, WFM5, (FW_LPS_ENTER| ((CurrentAID|0xc000)<<8)) );
3615 ChkFwCmdIoDone(dev);
3616 pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO;
3617 break;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003618
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003619 case FW_CMD_LPS_LEAVE:
3620 RT_TRACE(COMP_CMD, "[FW CMD] Leave LPS mode!!\n");
3621 write_nic_dword(dev, WFM5, FW_LPS_LEAVE );
3622 ChkFwCmdIoDone(dev);
3623 pHTInfo->IOTAction &= (~HT_IOT_ACT_DISABLE_EDCA_TURBO);
3624 break;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003625
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003626 default:
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003627 break;
3628 }
3629
Florian Schilhabel653e99e2010-07-14 14:47:27 +02003630 priv->SetFwCmdInProgress = false;
Jerry Chuang5f53d8c2009-05-21 22:16:02 -07003631 RT_TRACE(COMP_CMD, "<---SetFwCmdIOWorkItemCallback()\n");
3632
3633}
3634