]> Pileus Git - ~andy/linux/blob - drivers/staging/rtl8192su/r8192S_phy.c
Merge branches 'softirq-for-linus', 'x86-debug-for-linus', 'x86-numa-for-linus',...
[~andy/linux] / drivers / staging / rtl8192su / r8192S_phy.c
1 /******************************************************************************
2  * 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>
18 ******************************************************************************/
19 #include "r8192U.h"
20 #include "r8192U_dm.h"
21 #include "r8192S_rtl6052.h"
22
23 #include "r8192S_hw.h"
24 #include "r8192S_phy.h"
25 #include "r8192S_phyreg.h"
26 #include "r8192SU_HWImg.h"
27
28 #include "ieee80211/dot11d.h"
29
30 /* 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
36 static  u32
37 phy_CalculateBitShift(u32 BitMask);
38 static  RT_STATUS
39 phy_ConfigMACWithHeaderFile(struct net_device* dev);
40 static void
41 phy_InitBBRFRegisterDefinition(struct net_device* dev);
42 static  RT_STATUS
43 phy_BB8192S_Config_ParaFile(struct net_device* dev);
44 static  RT_STATUS
45 phy_ConfigBBWithHeaderFile(struct net_device* dev,u8 ConfigType);
46 static bool
47 phy_SetRFPowerState8192SU(struct net_device* dev,RT_RF_POWER_STATE eRFPowerState);
48 void
49 SetBWModeCallback8192SUsbWorkItem(struct net_device *dev);
50 void
51 SetBWModeCallback8192SUsbWorkItem(struct net_device *dev);
52 void
53 SwChnlCallback8192SUsbWorkItem(struct net_device *dev );
54 static void
55 phy_FinishSwChnlNow(struct net_device* dev,u8 channel);
56 static bool
57 phy_SwChnlStepByStep(
58         struct net_device* dev,
59         u8              channel,
60         u8              *stage,
61         u8              *step,
62         u32             *delay
63         );
64 static RT_STATUS
65 phy_ConfigBBWithPgHeaderFile(struct net_device* dev,u8 ConfigType);
66 static long phy_TxPwrIdxToDbm( struct net_device* dev, WIRELESS_MODE   WirelessMode, u8 TxPwrIdx);
67 static u8 phy_DbmToTxPwrIdx( struct net_device* dev, WIRELESS_MODE WirelessMode, long PowerInDbm);
68 void phy_SetFwCmdIOCallback(struct net_device* dev);
69
70 //
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 //
78 //use in phy only
79 u32 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.
99                 if((BBWaitCounter > 100) )
100                 {
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
141 //use in phy only
142 void
143 phy_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;
169         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
188 u32 phy_QueryUsbRFReg(  struct net_device* dev, RF90_RADIO_PATH_E eRFPath,      u32     Offset)
189 {
190
191         struct r8192_priv *priv = ieee80211_priv(dev);
192         u32     ReturnValue = 0;
193         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         {
204                 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                 {
217                 }
218         }
219
220         priv->bChangeRFInProgress = true;
221         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
236         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
258 void 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         {
273                 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
279                 if((RFWaitCounter > 100))
280                 {
281                         RT_TRACE(COMP_RF, "phy_SetUsbRFReg(): (%d) Wait too logn to query BB!!\n", RFWaitCounter);
282                         return;
283                 }
284                 else
285                 {
286                 }
287         }
288
289         priv->bChangeRFInProgress = true;
290
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
310         up(&priv->rf_sem);
311         priv->bChangeRFInProgress = false;
312
313 }
314
315 //
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 */
332 u32 rtl8192_QueryBBReg(struct net_device* dev, u32 RegAddr, u32 BitMask)
333 {
334
335         u32     ReturnValue = 0, OriginalValue, BitShift;
336
337
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         //
346         if(IS_BB_REG_OFFSET_92S(RegAddr))
347         {
348
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
358         {
359         OriginalValue = read_nic_dword(dev, RegAddr);
360         }
361
362         BitShift = phy_CalculateBitShift(BitMask);
363         ReturnValue = (OriginalValue & BitMask) >> BitShift;
364
365
366         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 */
387 void rtl8192_setBBreg(struct net_device* dev, u32 RegAddr, u32 BitMask, u32 Data)
388 {
389         u32     OriginalValue, BitShift, NewValue;
390
391
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         //
400         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
418         {
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
429
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 */
453 u32 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
458
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
473         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         //
480         Original_Value = phy_QueryUsbRFReg(dev, eRFPath, RegAddr);
481
482         BitShift =  phy_CalculateBitShift(BitMask);
483         Readback_Value = (Original_Value & BitMask) >> BitShift;
484         up(&priv->rf_sem);
485
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 */
507 void 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;
512
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
527         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.
532
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);
542         up(&priv->rf_sem);
543         RT_TRACE(COMP_RF, "<---PHY_SetRFReg(): RegAddr(%#x), BitMask(%#x), Data(%#x), eRFPath(%#x)\n",
544                         RegAddr, BitMask, Data, eRFPath);
545
546 }
547
548 /**
549 * 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
560 static 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
594 extern bool PHY_MACConfig8192S(struct net_device* dev)
595 {
596         RT_STATUS               rtStatus = RT_STATUS_SUCCESS;
597
598         //
599         // Config MAC
600         //
601         rtStatus = phy_ConfigMACWithHeaderFile(dev);
602         return (rtStatus == RT_STATUS_SUCCESS) ? true:false;
603
604 }
605
606 //adapter_start
607 extern  bool
608 PHY_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
616
617                         rtStatus = phy_BB8192S_Config_ParaFile(dev);
618
619         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
640 extern  bool
641 PHY_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
679 #ifdef TO_DO_LIST
680 static RT_STATUS
681 phy_BB8190_Config_HardCode(struct net_device* dev)
682 {
683         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  *---------------------------------------------------------------------------*/
703 static RT_STATUS
704 phy_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
711
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         }
722         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]);
744                 }
745         }
746         else {
747                 RT_TRACE(COMP_SEND, "phy_SetBBtoDiffRFWithHeaderFile(): ConfigType != BaseBand_Config_PHY_REG\n");
748         }
749         return RT_STATUS_SUCCESS;
750 }
751
752
753 //use in phy only
754 static  RT_STATUS
755 phy_BB8192S_Config_ParaFile(struct net_device* dev)
756 {
757         struct r8192_priv       *priv = ieee80211_priv(dev);
758         RT_STATUS                       rtStatus = RT_STATUS_SUCCESS;
759
760         RT_TRACE(COMP_INIT, "==>phy_BB8192S_Config_ParaFile\n");
761
762         //
763         // 1. Read PHY_REG.TXT BB INIT!!
764         // We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R
765         //
766         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;
777
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         {
788                 rtStatus = phy_ConfigBBWithPgHeaderFile(dev,BaseBand_Config_PHY_REG);
789         }
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         //
798         rtStatus = phy_ConfigBBWithHeaderFile(dev,BaseBand_Config_AGC_TAB);
799
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
806         // 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
811 phy_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
832 static  RT_STATUS
833 phy_ConfigMACWithHeaderFile(struct net_device* dev)
834 {
835         u32                                     i = 0;
836         u32                                     ArrayLength = 0;
837         u32*                                    ptrArray;
838
839         { //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
845         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         }
848         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
867 static  RT_STATUS
868 phy_ConfigBBWithHeaderFile(struct net_device* dev,u8 ConfigType)
869 {
870         int             i;
871         u32*    Rtl819XPHY_REGArray_Table;
872         u32*    Rtl819XAGCTAB_Array_Table;
873         u16             PHY_REGArrayLen, AGCTAB_ArrayLen;
874
875         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;
879
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]);
897
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         }
906         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  *---------------------------------------------------------------------------*/
926 static RT_STATUS
927 phy_ConfigBBWithPgHeaderFile(struct net_device* dev,u8 ConfigType)
928 {
929         int i;
930         u32*    Rtl819XPHY_REGArray_Table_PG;
931         u16     PHY_REGArrayPGLen;
932
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]);
953                 }
954         }else{
955                 RT_TRACE(COMP_SEND, "phy_ConfigBBWithPgHeaderFile(): ConfigType != BaseBand_Config_PHY_REG\n");
956         }
957         return RT_STATUS_SUCCESS;
958
959 }
960
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  *---------------------------------------------------------------------------*/
976 u8 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;
981         RT_STATUS       rtStatus = RT_STATUS_SUCCESS;
982         u32                     *Rtl819XRadioA_Array_Table;
983         u32                     *Rtl819XRadioB_Array_Table;
984         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
1006
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.
1012                                                 mdelay(1000);
1013                                 }
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);
1020                                         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.
1034                                                 mdelay(1000);
1035                                 }
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
1082 RT_STATUS
1083 PHY_CheckBBAndRFOK(
1084         struct net_device* dev,
1085         HW90_BLOCK_E            CheckBlock,
1086         RF90_RADIO_PATH_E       eRFPath
1087         )
1088 {
1089         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:
1109                         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:
1119                         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);
1125                         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                 {
1138                         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
1147 #ifdef TO_DO_LIST
1148 void
1149 PHY_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;
1157         u8                              eRFPath;
1158         BB_REGISTER_DEFINITION_T        *pPhyReg;
1159
1160         if(priv->SetRFPowerStateInProgress == TRUE)
1161                 return;
1162
1163         priv->SetRFPowerStateInProgress = TRUE;
1164
1165
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;
1216         }
1217
1218         priv->SetRFPowerStateInProgress = FALSE;
1219 }
1220 #endif
1221
1222 #ifdef RTL8192U
1223 void
1224 PHY_UpdateInitialGain(
1225         struct net_device* dev
1226         )
1227 {
1228         struct r8192_priv       *priv = ieee80211_priv(dev);
1229
1230
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
1250 void 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
1309 static 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;
1418
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 //
1428
1429 bool 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
1450 static 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;
1454         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;
1482                                 //
1483                                 //RF Off/Sleep sequence. Designed/tested from SD4 Scott, SD1 Grent and Jonbon.
1484                                 // (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;
1512                                 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
1591 PHY_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);
1643         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
1655         /*
1656          * Read predefined TX power index in EEPROM
1657          */
1658         {
1659                 //
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];
1691
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                                 {
1712                                         ht20pwr[rfpath] += pwrdiff[rfpath];
1713                                 }
1714                                 else                            // index8-15=-8~-1
1715                                 {
1716                                         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];
1723                 }
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                                 }
1753                         }
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                                 {
1767                                 }
1768                         }
1769                         else
1770                         {
1771                                 if (channel <= 3 || channel >= 9)
1772                                 {
1773                                 }
1774                         }
1775                 }
1776                 }
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
1785                 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);
1799         }
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         //
1810         //
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:
1854                 break;
1855
1856                 case RF_8256:
1857                         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.
1878 bool 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.
1919 */
1920
1921 extern void PHY_SetBeaconHwReg( struct net_device* dev, u16 BeaconInterval)
1922 {
1923         u32 NewBeaconNum;
1924
1925         NewBeaconNum = BeaconInterval *32 - 64;
1926         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.
1935 //    use in phy only
1936 static u8 phy_DbmToTxPwrIdx(
1937         struct net_device* dev,
1938         WIRELESS_MODE   WirelessMode,
1939         long                    PowerInDbm
1940         )
1941 {
1942         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.
1951         //
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.
1986 //    use in phy only
1987 static 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.
2002         //
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
2023 extern  VOID
2024 PHY_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
2038
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         }
2066 }
2067 #endif
2068
2069 //nouse temp
2070 void PHY_InitialGain8192S(struct net_device* dev,u8 Operation   )
2071 {
2072
2073 }
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)
2091 void PHY_SetBWModeCallback8192S(struct net_device *dev)
2092 {
2093         struct r8192_priv *priv = ieee80211_priv(dev);
2094         u8                              regBwOpMode;
2095
2096         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
2110
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:
2120
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:
2127
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:
2136                         RT_TRACE(COMP_DBG, "SetBWModeCallback8190Pci(): unknown Bandwidth: %#X\n",
2137                                  priv->CurrentChannelBW);
2138                         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
2151                         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
2162
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
2167                         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
2180
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  *---------------------------------------------------------------------------*/
2230 void 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
2235         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
2249         if((priv->up) )
2250         {
2251         SetBWModeCallback8192SUsbWorkItem(dev);
2252         }
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)
2262 void PHY_SwChnlCallback8192S(struct net_device *dev)
2263 {
2264
2265         struct r8192_priv *priv = ieee80211_priv(dev);
2266         u32             delay;
2267
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
2283                 if(!phy_SwChnlStepByStep(dev, priv->chan, &priv->SwChnlStage, &priv->SwChnlStep, &delay))
2284                 {
2285                         if(delay>0)
2286                         {
2287                                 mdelay(delay);
2288                         }
2289                         else
2290                         continue;
2291                 }
2292                 else
2293                 {
2294                         priv->SwChnlInProgress=FALSE;
2295                         break;
2296                 }
2297         }while(true);
2298 }
2299
2300 // Call after initialization
2301 u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel)
2302 {
2303         struct r8192_priv *priv = ieee80211_priv(dev);
2304
2305         if(!priv->up)
2306                 return false;
2307
2308         if(priv->SwChnlInProgress)
2309                 return false;
2310
2311         if(priv->SetBWModeInProgress)
2312                 return false;
2313
2314         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:
2340                         ;
2341                 break;
2342         }
2343
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
2353         if((priv->up))
2354         {
2355         SwChnlCallback8192SUsbWorkItem(dev);
2356 #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;
2373         }
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.
2386
2387 void 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
2428 static bool
2429 phy_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         {
2443                 return FALSE;
2444         }
2445         if(CmdTableIdx >= CmdTableSz)
2446         {
2447                 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
2460 static bool
2461 phy_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);
2470         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
2479         RT_TRACE(COMP_CH, "===========>%s(), channel:%d, stage:%d, step:%d\n", __FUNCTION__, channel, *stage, *step);
2480         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         }
2485
2486                 // <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);
2506
2507                 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);
2516                 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:
2535                 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:
2571                                 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                         {
2585                         // 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));
2587                         }
2588                         break;
2589                 default:
2590                         break;
2591                 }
2592
2593                 break;
2594         }while(TRUE);
2595
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
2604 static void
2605 phy_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  *---------------------------------------------------------------------------*/
2640 u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath)
2641 {
2642         bool                            rtValue = TRUE;
2643
2644         // NOt check RF Path now.!
2645         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
2669 void
2670 PHY_IQCalibrate(        struct net_device* dev)
2671 {
2672         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);
2687                 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  *---------------------------------------------------------------------------*/
2814 extern void PHY_IQCalibrateBcut(struct net_device* dev)
2815 {
2816         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         //
2829         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;
2842         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                 {
2861                         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                 {
2914                         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         //
2996         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
3006 }
3007
3008
3009 //
3010 // Move from phycfg.c to gen.c to be code independent later
3011 //
3012
3013 //    use in phy only (in win it's timer)
3014 void SwChnlCallback8192SUsb(struct net_device *dev)
3015 {
3016
3017         struct r8192_priv *priv = ieee80211_priv(dev);
3018         u32                     delay;
3019
3020         RT_TRACE(COMP_SCAN, "==>SwChnlCallback8190Pci(), switch to channel %d\n",
3021                  priv->chan);
3022
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                         {
3041
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)
3059 void 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  *---------------------------------------------------------------------------*/
3095 //    use in phy only
3096 void SetBWModeCallback8192SUsb(struct net_device *dev)
3097 {
3098         struct r8192_priv *priv = ieee80211_priv(dev);
3099         u8                              regBwOpMode;
3100
3101         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
3115
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;
3124                         write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3125                         break;
3126
3127                 case HT_CHANNEL_WIDTH_20_40:
3128                         regBwOpMode &= ~BW_OPMODE_20MHZ;
3129                         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:
3136                         RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci(): unknown Bandwidth: %#X\n",
3137                                  priv->CurrentChannelBW);
3138                         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);
3147
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
3158                         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
3170 #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:
3197                         break;
3198         }
3199 #endif
3200         priv->SetBWModeInProgress= FALSE;
3201
3202         RT_TRACE(COMP_SCAN, "<==SetBWMode8190Pci()" );
3203 }
3204
3205 /*
3206  * Callback routine of the work item for set bandwidth mode.
3207  *
3208  *    use in phy only (in win it's work)
3209  */
3210 void SetBWModeCallback8192SUsbWorkItem(struct net_device *dev)
3211 {
3212         struct r8192_priv *priv = ieee80211_priv(dev);
3213         u8 regBwOpMode;
3214         u8 regRRSR_RSC;
3215
3216         RT_TRACE(COMP_SCAN, "%s(): Switch to %s bandwidth", __func__,
3217         priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ? "20MHz" : "40MHz");
3218
3219         if (priv->rf_chip == RF_PSEUDO_11N) {
3220                 priv->SetBWModeInProgress= FALSE;
3221                 return;
3222         }
3223         if(!priv->up)
3224                 return;
3225         /* Set MAC register */
3226         regBwOpMode = read_nic_byte(dev, BW_OPMODE);
3227         regRRSR_RSC = read_nic_byte(dev, RRSR+2);
3228         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;
3245         }
3246         /* 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;
3270
3271         }
3272         /*
3273          * Skip over setting of J-mode in BB register here.
3274          * Default value is "None J mode".
3275          */
3276
3277         /* 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;
3300         }
3301         priv->SetBWModeInProgress= FALSE;
3302 }
3303
3304 void 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 }
3311
3312 void 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         {
3320                 queue_delayed_work(priv->priv_wq,&priv->initialgain_operate_wq,0);
3321         }
3322 }
3323
3324 extern 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;
3329 #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
3396
3397 //-----------------------------------------------------------------------------
3398 //      Description:
3399 //              Schedule workitem to send specific CMD IO to FW.
3400 //      Added by Roger, 2008.12.03.
3401 //
3402 //-----------------------------------------------------------------------------
3403 bool 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
3410         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         {
3425
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         {
3435                 RT_TRACE(COMP_CMD, "HalSetFwCmd8192S(): Wait too logn to set FW CMD\n");
3436         }
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 }
3449 void 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 //
3486 void phy_SetFwCmdIOCallback(struct net_device* dev)
3487 {
3488         struct r8192_priv *priv = ieee80211_priv(dev);
3489         PRT_HIGH_THROUGHPUT     pHTInfo = priv->ieee80211->pHTInfo;
3490         rt_firmware             *pFirmware = priv->pFirmware;
3491         u32     input, CurrentAID = 0;;
3492         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
3500         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         }
3514         switch(priv->CurrentFwCmdIO)
3515         {
3516
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:
3526                         RT_TRACE(COMP_CMD, "[FW CMD] Set RA n refresh!!\n");
3527                         if(pHTInfo->IOTRaFunc & HT_IOT_RAFUNC_DISABLE_ALL)
3528                                 input = FW_RA_REFRESH;
3529                         else
3530                                 input = FW_RA_REFRESH | (pHTInfo->IOTRaFunc << 8);
3531                         write_nic_dword(dev, WFM5, input);
3532                         ChkFwCmdIoDone(dev);
3533                         write_nic_dword(dev, WFM5, FW_RA_ENABLE_RSSI_MASK);
3534                         ChkFwCmdIoDone(dev);
3535                         break;
3536                 case FW_CMD_RA_REFRESH_BG:
3537                         RT_TRACE(COMP_CMD, "[FW CMD] Set RA BG refresh!!\n");
3538                         write_nic_dword(dev, WFM5, FW_RA_REFRESH);
3539                         ChkFwCmdIoDone(dev);
3540                         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);
3566                         break;
3567
3568                 case FW_CMD_IQK_ENABLE:
3569                         write_nic_dword(dev, WFM5, FW_IQK_ENABLE);
3570                         ChkFwCmdIoDone(dev);
3571                         break;
3572
3573                 case FW_CMD_TXPWR_TRACK_ENABLE:
3574                         write_nic_dword(dev, WFM5, FW_TXPWR_TRACK_ENABLE);
3575                         ChkFwCmdIoDone(dev);
3576                         break;
3577
3578                 case FW_CMD_TXPWR_TRACK_DISABLE:
3579                         write_nic_dword(dev, WFM5, FW_TXPWR_TRACK_DISABLE);
3580                         ChkFwCmdIoDone(dev);
3581                         break;
3582
3583                 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);
3588                         break;
3589
3590                 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;
3595                 case FW_CMD_HIGH_PWR_DISABLE:
3596                         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);
3602                         break;
3603
3604                 case FW_CMD_HIGH_PWR_ENABLE:
3605                         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;
3610
3611                 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;
3618
3619                 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;
3625
3626                 default:
3627                         break;
3628         }
3629
3630         priv->SetFwCmdInProgress = false;
3631         RT_TRACE(COMP_CMD, "<---SetFwCmdIOWorkItemCallback()\n");
3632
3633 }
3634