Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / staging / rtl8723au / hal / rtl8723a_phycfg.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15 #define _RTL8723A_PHYCFG_C_
16
17 #include <osdep_service.h>
18 #include <drv_types.h>
19
20 #include <rtl8723a_hal.h>
21 #include <usb_ops_linux.h>
22
23 /*---------------------------Define Local Constant---------------------------*/
24 /* Channel switch:The size of command tables for switch channel*/
25 #define MAX_PRECMD_CNT 16
26 #define MAX_RFDEPENDCMD_CNT 16
27 #define MAX_POSTCMD_CNT 16
28
29 #define MAX_DOZE_WAITING_TIMES_9x 64
30
31 /*---------------------------Define Local Constant---------------------------*/
32
33 /*------------------------Define global variable-----------------------------*/
34
35 /*------------------------Define local variable------------------------------*/
36
37 /*--------------------Define export function prototype-----------------------*/
38 /*  Please refer to header file */
39 /*--------------------Define export function prototype-----------------------*/
40
41 /*----------------------------Function Body----------------------------------*/
42 /*  */
43 /*  1. BB register R/W API */
44 /*  */
45
46 /**
47 * Function:     phy_CalculateBitShift
48 *
49 * OverView:     Get shifted position of the BitMask
50 *
51 * Input:
52 *                       u32             BitMask,
53 *
54 * Output:       none
55 * Return:               u32             Return the shift bit bit position of the mask
56 */
57 static  u32 phy_CalculateBitShift(u32 BitMask)
58 {
59         u32 i;
60
61         for (i = 0; i <= 31; i++) {
62                 if (((BitMask>>i) & 0x1) == 1)
63                         break;
64         }
65
66         return i;
67 }
68
69 /**
70 * Function:     PHY_QueryBBReg
71 *
72 * OverView:     Read "sepcific bits" from BB register
73 *
74 * Input:
75 *       struct rtw_adapter *    Adapter,
76 *       u32                     RegAddr,        Target address to be readback
77 *       u32                     BitMask         Target bit position in the
78 *                                               target address to be readback
79 * Output:
80 *       None
81 * Return:
82 *       u32                     Data            The readback register value
83 * Note:
84 *       This function is equal to "GetRegSetting" in PHY programming guide
85 */
86 u32
87 PHY_QueryBBReg(struct rtw_adapter *Adapter, u32 RegAddr, u32 BitMask)
88 {
89         u32     ReturnValue = 0, OriginalValue, BitShift;
90
91         OriginalValue = rtl8723au_read32(Adapter, RegAddr);
92         BitShift = phy_CalculateBitShift(BitMask);
93         ReturnValue = (OriginalValue & BitMask) >> BitShift;
94         return ReturnValue;
95 }
96
97 /**
98 * Function:     PHY_SetBBReg
99 *
100 * OverView:     Write "Specific bits" to BB register (page 8~)
101 *
102 * Input:
103 *       struct rtw_adapter *    Adapter,
104 *       u32                     RegAddr,        Target address to be modified
105 *       u32                     BitMask         Target bit position in the
106 *                                               target address to be modified
107 *       u32                     Data            The new register value in the
108 *                                               target bit position of the
109 *                                                target address
110 *
111 * Output:
112 *       None
113 * Return:
114 *       None
115 * Note:
116 *       This function is equal to "PutRegSetting" in PHY programming guide
117 */
118
119 void
120 PHY_SetBBReg(struct rtw_adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
121 {
122         u32 OriginalValue, BitShift;
123
124         if (BitMask != bMaskDWord) {/* if not "double word" write */
125                 OriginalValue = rtl8723au_read32(Adapter, RegAddr);
126                 BitShift = phy_CalculateBitShift(BitMask);
127                 Data = (OriginalValue & (~BitMask)) | (Data << BitShift);
128         }
129
130         rtl8723au_write32(Adapter, RegAddr, Data);
131
132         /* RTPRINT(FPHY, PHY_BBW, ("BBW MASK = 0x%lx Addr[0x%lx]= 0x%lx\n", BitMask, RegAddr, Data)); */
133 }
134
135 /*  */
136 /*  2. RF register R/W API */
137 /*  */
138
139 /**
140 * Function:     phy_RFSerialRead
141 *
142 * OverView:     Read regster from RF chips
143 *
144 * Input:
145 *               struct rtw_adapter *            Adapter,
146 *               enum RF_RADIO_PATH      eRFPath,        Radio path of A/B/C/D
147 *               u32 Offset,                     The target address to be read
148 *
149 * Output:       None
150 * Return:       u32                     reback value
151 * Note:         Threre are three types of serial operations:
152 *               1. Software serial write
153 *               2. Hardware LSSI-Low Speed Serial Interface
154 *               3. Hardware HSSI-High speed
155 *               serial write. Driver need to implement (1) and (2).
156 *               This function is equal to the combination of RF_ReadReg() and
157 *               RFLSSIRead()
158 */
159 static u32
160 phy_RFSerialRead(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
161                  u32 Offset)
162 {
163         u32 retValue = 0;
164         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
165         struct bb_reg_define *pPhyReg = &pHalData->PHYRegDef[eRFPath];
166         u32 NewOffset;
167         u32 tmplong, tmplong2;
168         u8 RfPiEnable = 0;
169         /*  */
170         /*  Make sure RF register offset is correct */
171         /*  */
172         Offset &= 0x3f;
173
174         /*  */
175         /*  Switch page for 8256 RF IC */
176         /*  */
177         NewOffset = Offset;
178
179         /*  2009/06/17 MH We can not execute IO for power save or
180             other accident mode. */
181         /* if (RT_CANNOT_IO(Adapter)) */
182         /*  */
183         /*      RTPRINT(FPHY, PHY_RFR, ("phy_RFSerialRead return all one\n")); */
184         /*      return  0xFFFFFFFF; */
185         /*  */
186
187         /*  For 92S LSSI Read RFLSSIRead */
188         /*  For RF A/B write 0x824/82c(does not work in the future) */
189         /*  We must use 0x824 for RF A and B to execute read trigger */
190         tmplong = rtl8723au_read32(Adapter, rFPGA0_XA_HSSIParameter2);
191         if (eRFPath == RF_PATH_A)
192                 tmplong2 = tmplong;
193         else
194                 tmplong2 = rtl8723au_read32(Adapter, pPhyReg->rfHSSIPara2);
195
196         tmplong2 = (tmplong2 & ~bLSSIReadAddress) |
197                 (NewOffset << 23) | bLSSIReadEdge;      /* T65 RF */
198
199         rtl8723au_write32(Adapter, rFPGA0_XA_HSSIParameter2,
200                           tmplong & (~bLSSIReadEdge));
201         udelay(10);/*  PlatformStallExecution(10); */
202
203         rtl8723au_write32(Adapter, pPhyReg->rfHSSIPara2, tmplong2);
204         udelay(100);/* PlatformStallExecution(100); */
205
206         rtl8723au_write32(Adapter, rFPGA0_XA_HSSIParameter2,
207                           tmplong | bLSSIReadEdge);
208         udelay(10);/* PlatformStallExecution(10); */
209
210         if (eRFPath == RF_PATH_A)
211                 RfPiEnable = (u8)PHY_QueryBBReg(Adapter,
212                                                 rFPGA0_XA_HSSIParameter1,
213                                                 BIT(8));
214         else if (eRFPath == RF_PATH_B)
215                 RfPiEnable = (u8)PHY_QueryBBReg(Adapter,
216                                                 rFPGA0_XB_HSSIParameter1,
217                                                 BIT(8));
218
219         if (RfPiEnable) {
220                 /* Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */
221                 retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi,
222                                           bLSSIReadBackData);
223                 /* DBG_8723A("Readback from RF-PI : 0x%x\n", retValue); */
224         } else {
225                 /* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */
226                 retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack,
227                                           bLSSIReadBackData);
228                 /* DBG_8723A("Readback from RF-SI : 0x%x\n", retValue); */
229         }
230         /* DBG_8723A("RFR-%d Addr[0x%x]= 0x%x\n", eRFPath, pPhyReg->rfLSSIReadBack, retValue); */
231
232         return retValue;
233 }
234
235 /**
236 * Function:     phy_RFSerialWrite
237 *
238 * OverView:     Write data to RF register (page 8~)
239 *
240 * Input:
241 *       struct rtw_adapter *            Adapter,
242 *       enum RF_RADIO_PATH      eRFPath,        Radio path of A/B/C/D
243 *       u32 Offset,                     The target address to be read
244 *       u32 Data                        The new register Data in the target
245 *                                       bit position of the target to be read
246 *
247 * Output:
248 *       None
249 * Return:
250 *       None
251 * Note:
252 *       Threre are three types of serial operations:
253 *               1. Software serial write
254 *               2. Hardware LSSI-Low Speed Serial Interface
255 *               3. Hardware HSSI-High speed
256 *               serial write. Driver need to implement (1) and (2).
257 *               This function is equal to the combination of RF_ReadReg() and
258 *               RFLSSIRead()
259 *
260 * Note:   For RF8256 only
261 * The total count of RTL8256(Zebra4) register is around 36 bit it only employs
262 * 4-bit RF address. RTL8256 uses "register mode control bit"
263 * (Reg00[12], Reg00[10]) to access register address bigger than 0xf.
264 * See "Appendix-4 in PHY Configuration programming guide" for more details.
265 * Thus, we define a sub-finction for RTL8526 register address conversion
266 * ===========================================================
267 * Register Mode:        RegCTL[1]       RegCTL[0]       Note
268 *                       (Reg00[12])     (Reg00[10])
269 * ===========================================================
270 * Reg_Mode0             0               x               Reg 0 ~15(0x0 ~ 0xf)
271 * ------------------------------------------------------------------
272 * Reg_Mode1             1               0               Reg 16 ~30(0x1 ~ 0xf)
273 * ------------------------------------------------------------------
274 * Reg_Mode2             1               1               Reg 31 ~ 45(0x1 ~ 0xf)
275 * ------------------------------------------------------------------
276 *
277 *       2008/09/02      MH      Add 92S RF definition
278 */
279 static  void
280 phy_RFSerialWrite(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
281                   u32 Offset, u32 Data)
282 {
283         u32 DataAndAddr = 0;
284         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
285         struct bb_reg_define *pPhyReg = &pHalData->PHYRegDef[eRFPath];
286         u32 NewOffset;
287
288         /*  2009/06/17 MH We can not execute IO for power save or
289             other accident mode. */
290         /* if (RT_CANNOT_IO(Adapter)) */
291         /*  */
292         /*      RTPRINT(FPHY, PHY_RFW, ("phy_RFSerialWrite stop\n")); */
293         /*      return; */
294         /*  */
295
296         Offset &= 0x3f;
297
298         /*  */
299         /*  Shadow Update */
300         /*  */
301         /* PHY_RFShadowWrite(Adapter, eRFPath, Offset, Data); */
302
303         /*  */
304         /*  Switch page for 8256 RF IC */
305         /*  */
306         NewOffset = Offset;
307
308         /*  */
309         /*  Put write addr in [5:0]  and write data in [31:16] */
310         /*  */
311         /* DataAndAddr = (Data<<16) | (NewOffset&0x3f); */
312         /*  T65 RF */
313         DataAndAddr = ((NewOffset<<20) | (Data&0x000fffff)) & 0x0fffffff;
314
315         /*  */
316         /*  Write Operation */
317         /*  */
318         rtl8723au_write32(Adapter, pPhyReg->rf3wireOffset, DataAndAddr);
319 }
320
321 /**
322 * Function:     PHY_QueryRFReg
323 *
324 * OverView:     Query "Specific bits" to RF register (page 8~)
325 *
326 * Input:
327 *       struct rtw_adapter *            Adapter,
328 *       enum RF_RADIO_PATH      eRFPath,        Radio path of A/B/C/D
329 *       u32 RegAddr,                    The target address to be read
330 *       u32BitMask                      The target bit position in the target
331 *                                       address to be read
332 *
333 * Output:
334 *       None
335 * Return:
336 *       u32                             Readback value
337 * Note:
338 *       This function is equal to "GetRFRegSetting" in PHY programming guide
339 */
340 u32
341 PHY_QueryRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
342                u32 RegAddr, u32 BitMask)
343 {
344         u32 Original_Value, Readback_Value, BitShift;
345         /* struct hal_data_8723a        *pHalData = GET_HAL_DATA(Adapter); */
346         /* u8   RFWaitCounter = 0; */
347         /* _irqL        irqL; */
348
349         Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr);
350
351         BitShift =  phy_CalculateBitShift(BitMask);
352         Readback_Value = (Original_Value & BitMask) >> BitShift;
353
354         return Readback_Value;
355 }
356
357 /**
358 * Function:     PHY_SetRFReg
359 *
360 * OverView:     Write "Specific bits" to RF register (page 8~)
361 *
362 * Input:
363 *       struct rtw_adapter *            Adapter,
364 *       enum RF_RADIO_PATH      eRFPath,        Radio path of A/B/C/D
365 *       u32 RegAddr,                    The target address to be modified
366 *       u32 BitMask                     The target bit position in the target
367 *                                       address to be modified
368 *       u32 Data                        The new register Data in the target
369 *                                       bit position of the target address
370 *
371 * Output:
372 *       None
373 * Return:
374 *       None
375 * Note: This function is equal to "PutRFRegSetting" in PHY programming guide
376 */
377 void
378 PHY_SetRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
379              u32 RegAddr, u32 BitMask, u32 Data)
380 {
381         /* struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); */
382         /* u8 RFWaitCounter     = 0; */
383         u32 Original_Value, BitShift;
384
385         /*  RF data is 12 bits only */
386         if (BitMask != bRFRegOffsetMask) {
387                 Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr);
388                 BitShift =  phy_CalculateBitShift(BitMask);
389                 Data = (Original_Value & (~BitMask)) | (Data << BitShift);
390         }
391
392         phy_RFSerialWrite(Adapter, eRFPath, RegAddr, Data);
393 }
394
395 /*  3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */
396
397 /*-----------------------------------------------------------------------------
398  * Function:    PHY_MACConfig8723A
399  *
400  * Overview:    Condig MAC by header file or parameter file.
401  *
402  * Input:       NONE
403  *
404  * Output:      NONE
405  *
406  * Return:      NONE
407  *
408  * Revised History:
409  *  When                Who             Remark
410  *  08/12/2008  MHC             Create Version 0.
411  *
412  *---------------------------------------------------------------------------*/
413 int PHY_MACConfig8723A(struct rtw_adapter *Adapter)
414 {
415         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
416
417         /*  */
418         /*  Config MAC */
419         /*  */
420         ODM_ReadAndConfig_MAC_REG_8723A(&pHalData->odmpriv);
421
422         /*  2010.07.13 AMPDU aggregation number 9 */
423         rtl8723au_write8(Adapter, REG_MAX_AGGR_NUM, 0x0A);
424         if (pHalData->rf_type == RF_2T2R &&
425             BOARD_USB_DONGLE == pHalData->BoardType)
426                 rtl8723au_write8(Adapter, 0x40, 0x04);
427
428         return _SUCCESS;
429 }
430
431 /**
432 * Function:     phy_InitBBRFRegisterDefinition
433 *
434 * OverView:     Initialize Register definition offset for Radio Path A/B/C/D
435 *
436 * Input:
437 *                       struct rtw_adapter *            Adapter,
438 *
439 * Output:       None
440 * Return:               None
441 * Note:
442 *       The initialization value is constant and it should never be changes
443 */
444 static  void
445 phy_InitBBRFRegisterDefinition(struct rtw_adapter *Adapter)
446 {
447         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
448
449         /*  RF Interface Sowrtware Control */
450          /*  16 LSBs if read 32-bit from 0x870 */
451         pHalData->PHYRegDef[RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW;
452          /*  16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */
453         pHalData->PHYRegDef[RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW;
454
455         /*  RF Interface Readback Value */
456         /*  16 LSBs if read 32-bit from 0x8E0 */
457         pHalData->PHYRegDef[RF_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB;
458         /*  16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */
459         pHalData->PHYRegDef[RF_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;
460
461         /*  RF Interface Output (and Enable) */
462         /*  16 LSBs if read 32-bit from 0x860 */
463         pHalData->PHYRegDef[RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE;
464          /*  16 LSBs if read 32-bit from 0x864 */
465         pHalData->PHYRegDef[RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE;
466
467         /*  RF Interface (Output and)  Enable */
468          /*  16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
469         pHalData->PHYRegDef[RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE;
470         /*  16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */
471         pHalData->PHYRegDef[RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE;
472
473         /* Addr of LSSI. Wirte RF register by driver */
474         pHalData->PHYRegDef[RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter;
475         pHalData->PHYRegDef[RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
476
477         /*  RF parameter */
478         /* BB Band Select */
479         pHalData->PHYRegDef[RF_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter;
480         pHalData->PHYRegDef[RF_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter;
481
482         /*  Tx AGC Gain Stage (same for all path. Should we remove this?) */
483         pHalData->PHYRegDef[RF_PATH_A].rfTxGainStage = rFPGA0_TxGainStage;
484         pHalData->PHYRegDef[RF_PATH_B].rfTxGainStage = rFPGA0_TxGainStage;
485
486         /*  Tranceiver A~D HSSI Parameter-1 */
487         /* wire control parameter1 */
488         pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1;
489         /* wire control parameter1 */
490         pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1;
491
492         /*  Tranceiver A~D HSSI Parameter-2 */
493         /* wire control parameter2 */
494         pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2;
495         /* wire control parameter2 */
496         pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2;
497
498         /*  RF switch Control */
499         pHalData->PHYRegDef[RF_PATH_A].rfSwitchControl =
500                 rFPGA0_XAB_SwitchControl; /* TR/Ant switch control */
501         pHalData->PHYRegDef[RF_PATH_B].rfSwitchControl =
502                 rFPGA0_XAB_SwitchControl;
503
504         /*  AGC control 1 */
505         pHalData->PHYRegDef[RF_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1;
506         pHalData->PHYRegDef[RF_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1;
507
508         /*  AGC control 2 */
509         pHalData->PHYRegDef[RF_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2;
510         pHalData->PHYRegDef[RF_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2;
511
512         /*  RX AFE control 1 */
513         pHalData->PHYRegDef[RF_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance;
514         pHalData->PHYRegDef[RF_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance;
515
516         /*  RX AFE control 1 */
517         pHalData->PHYRegDef[RF_PATH_A].rfRxAFE = rOFDM0_XARxAFE;
518         pHalData->PHYRegDef[RF_PATH_B].rfRxAFE = rOFDM0_XBRxAFE;
519
520         /*  Tx AFE control 1 */
521         pHalData->PHYRegDef[RF_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance;
522         pHalData->PHYRegDef[RF_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance;
523
524         /*  Tx AFE control 2 */
525         pHalData->PHYRegDef[RF_PATH_A].rfTxAFE = rOFDM0_XATxAFE;
526         pHalData->PHYRegDef[RF_PATH_B].rfTxAFE = rOFDM0_XBTxAFE;
527
528         /*  Tranceiver LSSI Readback SI mode */
529         pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
530         pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
531
532         /*  Tranceiver LSSI Readback PI mode */
533         pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBackPi =
534                 TransceiverA_HSPI_Readback;
535         pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBackPi =
536                 TransceiverB_HSPI_Readback;
537 }
538
539 /*  The following is for High Power PA */
540 static void
541 storePwrIndexDiffRateOffset(struct rtw_adapter *Adapter, u32 RegAddr,
542                             u32 BitMask, u32 Data)
543 {
544         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
545
546         if (RegAddr == rTxAGC_A_Rate18_06) {
547                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0] = Data;
548         }
549         if (RegAddr == rTxAGC_A_Rate54_24) {
550                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][1] = Data;
551         }
552         if (RegAddr == rTxAGC_A_CCK1_Mcs32) {
553                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][6] = Data;
554         }
555         if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0xffffff00) {
556                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][7] = Data;
557         }
558         if (RegAddr == rTxAGC_A_Mcs03_Mcs00) {
559                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][2] = Data;
560         }
561         if (RegAddr == rTxAGC_A_Mcs07_Mcs04) {
562                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][3] = Data;
563         }
564         if (RegAddr == rTxAGC_A_Mcs11_Mcs08) {
565                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][4] = Data;
566         }
567         if (RegAddr == rTxAGC_A_Mcs15_Mcs12) {
568                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][5] = Data;
569         }
570         if (RegAddr == rTxAGC_B_Rate18_06) {
571                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][8] = Data;
572         }
573         if (RegAddr == rTxAGC_B_Rate54_24) {
574                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][9] = Data;
575         }
576         if (RegAddr == rTxAGC_B_CCK1_55_Mcs32) {
577                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][14] = Data;
578         }
579         if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0x000000ff) {
580                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][15] = Data;
581         }
582         if (RegAddr == rTxAGC_B_Mcs03_Mcs00) {
583                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][10] = Data;
584         }
585         if (RegAddr == rTxAGC_B_Mcs07_Mcs04) {
586                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][11] = Data;
587         }
588         if (RegAddr == rTxAGC_B_Mcs11_Mcs08) {
589                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][12] = Data;
590         }
591         if (RegAddr == rTxAGC_B_Mcs15_Mcs12) {
592                 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][13] = Data;
593                 pHalData->pwrGroupCnt++;
594         }
595 }
596
597 /*-----------------------------------------------------------------------------
598  * Function:    phy_ConfigBBWithPgHeaderFile
599  *
600  * Overview:    Config PHY_REG_PG array
601  *
602  * Input:       NONE
603  *
604  * Output:      NONE
605  *
606  * Return:      NONE
607  *
608  * Revised History:
609  * When         Who     Remark
610  * 11/06/2008   MHC     Add later!!!!!!.. Please modify for new files!!!!
611  * 11/10/2008   tynli   Modify to mew files.
612  *---------------------------------------------------------------------------*/
613 static  int
614 phy_ConfigBBWithPgHeaderFile(struct rtw_adapter *Adapter)
615 {
616         int i;
617         u32 *Rtl819XPHY_REGArray_Table_PG;
618         u16 PHY_REGArrayPGLen;
619
620         PHY_REGArrayPGLen = Rtl8723_PHY_REG_Array_PGLength;
621         Rtl819XPHY_REGArray_Table_PG = (u32 *)Rtl8723_PHY_REG_Array_PG;
622
623         for (i = 0; i < PHY_REGArrayPGLen; i = i + 3) {
624                 storePwrIndexDiffRateOffset(Adapter,
625                                             Rtl819XPHY_REGArray_Table_PG[i],
626                                             Rtl819XPHY_REGArray_Table_PG[i+1],
627                                             Rtl819XPHY_REGArray_Table_PG[i+2]);
628         }
629
630         return _SUCCESS;
631 }
632
633 static void
634 phy_BB8192C_Config_1T(struct rtw_adapter *Adapter)
635 {
636         /* for path - B */
637         PHY_SetBBReg(Adapter, rFPGA0_TxInfo, 0x3, 0x2);
638         PHY_SetBBReg(Adapter, rFPGA1_TxInfo, 0x300033, 0x200022);
639
640         /*  20100519 Joseph: Add for 1T2R config. Suggested by Kevin,
641             Jenyu and Yunan. */
642         PHY_SetBBReg(Adapter, rCCK0_AFESetting, bMaskByte3, 0x45);
643         PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, bMaskByte0, 0x23);
644         /*  B path first AGC */
645         PHY_SetBBReg(Adapter, rOFDM0_AGCParameter1, 0x30, 0x1);
646
647         PHY_SetBBReg(Adapter, 0xe74, 0x0c000000, 0x2);
648         PHY_SetBBReg(Adapter, 0xe78, 0x0c000000, 0x2);
649         PHY_SetBBReg(Adapter, 0xe7c, 0x0c000000, 0x2);
650         PHY_SetBBReg(Adapter, 0xe80, 0x0c000000, 0x2);
651         PHY_SetBBReg(Adapter, 0xe88, 0x0c000000, 0x2);
652 }
653
654 static int
655 phy_BB8723a_Config_ParaFile(struct rtw_adapter *Adapter)
656 {
657         struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter);
658         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
659         int rtStatus = _SUCCESS;
660
661         /*  */
662         /*  1. Read PHY_REG.TXT BB INIT!! */
663         /*  We will seperate as 88C / 92C according to chip version */
664         /*  */
665         ODM_ReadAndConfig_PHY_REG_1T_8723A(&pHalData->odmpriv);
666
667         /*  */
668         /*  20100318 Joseph: Config 2T2R to 1T2R if necessary. */
669         /*  */
670         if (pHalData->rf_type == RF_1T2R) {
671                 phy_BB8192C_Config_1T(Adapter);
672                 DBG_8723A("phy_BB8723a_Config_ParaFile():Config to 1T!!\n");
673         }
674
675         /*  */
676         /*  2. If EEPROM or EFUSE autoload OK, We must config by
677             PHY_REG_PG.txt */
678         /*  */
679         if (pEEPROM->bautoload_fail_flag == false) {
680                 pHalData->pwrGroupCnt = 0;
681
682                 rtStatus = phy_ConfigBBWithPgHeaderFile(Adapter);
683         }
684
685         if (rtStatus != _SUCCESS)
686                 goto phy_BB8190_Config_ParaFile_Fail;
687
688         /*  */
689         /*  3. BB AGC table Initialization */
690         /*  */
691         ODM_ReadAndConfig_AGC_TAB_1T_8723A(&pHalData->odmpriv);
692
693 phy_BB8190_Config_ParaFile_Fail:
694
695         return rtStatus;
696 }
697
698 int
699 PHY_BBConfig8723A(struct rtw_adapter *Adapter)
700 {
701         int rtStatus = _SUCCESS;
702         struct hal_data_8723a   *pHalData = GET_HAL_DATA(Adapter);
703         u8 TmpU1B = 0;
704         u8 CrystalCap;
705
706         phy_InitBBRFRegisterDefinition(Adapter);
707
708         /*  Suggested by Scott. tynli_test. 2010.12.30. */
709         /* 1. 0x28[1] = 1 */
710         TmpU1B = rtl8723au_read8(Adapter, REG_AFE_PLL_CTRL);
711         udelay(2);
712         rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL, TmpU1B | BIT(1));
713         udelay(2);
714
715         /* 2. 0x29[7:0] = 0xFF */
716         rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL+1, 0xff);
717         udelay(2);
718
719         /* 3. 0x02[1:0] = 2b'11 */
720         TmpU1B = rtl8723au_read8(Adapter, REG_SYS_FUNC_EN);
721         rtl8723au_write8(Adapter, REG_SYS_FUNC_EN,
722                          (TmpU1B | FEN_BB_GLB_RSTn | FEN_BBRSTB));
723
724         /* 4. 0x25[6] = 0 */
725         TmpU1B = rtl8723au_read8(Adapter, REG_AFE_XTAL_CTRL + 1);
726         rtl8723au_write8(Adapter, REG_AFE_XTAL_CTRL+1, TmpU1B & ~BIT(6));
727
728         /* 5. 0x24[20] = 0      Advised by SD3 Alex Wang. 2011.02.09. */
729         TmpU1B = rtl8723au_read8(Adapter, REG_AFE_XTAL_CTRL+2);
730         rtl8723au_write8(Adapter, REG_AFE_XTAL_CTRL+2, TmpU1B & ~BIT(4));
731
732         /* 6. 0x1f[7:0] = 0x07 */
733         rtl8723au_write8(Adapter, REG_RF_CTRL, 0x07);
734
735         /*  */
736         /*  Config BB and AGC */
737         /*  */
738         rtStatus = phy_BB8723a_Config_ParaFile(Adapter);
739
740 /* only for B-cut */
741         if (pHalData->EEPROMVersion >= 0x01) {
742                 CrystalCap = pHalData->CrystalCap & 0x3F;
743                 PHY_SetBBReg(Adapter, REG_MAC_PHY_CTRL, 0xFFF000,
744                              (CrystalCap | (CrystalCap << 6)));
745         }
746
747         rtl8723au_write32(Adapter, REG_LDOA15_CTRL, 0x01572505);
748         return rtStatus;
749 }
750
751 static void getTxPowerIndex(struct rtw_adapter *Adapter,
752                             u8 channel, u8 *cckPowerLevel,  u8 *ofdmPowerLevel)
753 {
754         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
755         u8 index = (channel - 1);
756         /*  1. CCK */
757         cckPowerLevel[RF_PATH_A] = pHalData->TxPwrLevelCck[RF_PATH_A][index];
758         cckPowerLevel[RF_PATH_B] = pHalData->TxPwrLevelCck[RF_PATH_B][index];
759
760         /*  2. OFDM for 1S or 2S */
761         if (GET_RF_TYPE(Adapter) == RF_1T2R || GET_RF_TYPE(Adapter) == RF_1T1R) {
762                 /*  Read HT 40 OFDM TX power */
763                 ofdmPowerLevel[RF_PATH_A] =
764                         pHalData->TxPwrLevelHT40_1S[RF_PATH_A][index];
765                 ofdmPowerLevel[RF_PATH_B] =
766                         pHalData->TxPwrLevelHT40_1S[RF_PATH_B][index];
767         } else if (GET_RF_TYPE(Adapter) == RF_2T2R) {
768                 /*  Read HT 40 OFDM TX power */
769                 ofdmPowerLevel[RF_PATH_A] =
770                         pHalData->TxPwrLevelHT40_2S[RF_PATH_A][index];
771                 ofdmPowerLevel[RF_PATH_B] =
772                         pHalData->TxPwrLevelHT40_2S[RF_PATH_B][index];
773         }
774 }
775
776 static void ccxPowerIndexCheck(struct rtw_adapter *Adapter, u8 channel,
777                                u8 *cckPowerLevel, u8 *ofdmPowerLevel)
778 {
779 }
780
781 /*-----------------------------------------------------------------------------
782  * Function:    SetTxPowerLevel8723A()
783  *
784  * Overview:    This function is export to "HalCommon" moudule
785  *                      We must consider RF path later!!!!!!!
786  *
787  * Input:       struct rtw_adapter *            Adapter
788  *                      u8              channel
789  *
790  * Output:      NONE
791  *
792  * Return:      NONE
793  *
794  *---------------------------------------------------------------------------*/
795 void PHY_SetTxPowerLevel8723A(struct rtw_adapter *Adapter, u8 channel)
796 {
797         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
798         u8 cckPowerLevel[2], ofdmPowerLevel[2]; /*  [0]:RF-A, [1]:RF-B */
799
800         if (pHalData->bTXPowerDataReadFromEEPORM == false)
801                 return;
802
803         getTxPowerIndex(Adapter, channel, &cckPowerLevel[0],
804                         &ofdmPowerLevel[0]);
805
806         ccxPowerIndexCheck(Adapter, channel, &cckPowerLevel[0],
807                            &ofdmPowerLevel[0]);
808
809         rtl823a_phy_rf6052setccktxpower(Adapter, &cckPowerLevel[0]);
810         rtl8723a_PHY_RF6052SetOFDMTxPower(Adapter, &ofdmPowerLevel[0], channel);
811 }
812
813 /*-----------------------------------------------------------------------------
814  * Function:    PHY_SetBWMode23aCallback8192C()
815  *
816  * Overview:    Timer callback function for SetSetBWMode23a
817  *
818  * Input:               PRT_TIMER               pTimer
819  *
820  * Output:      NONE
821  *
822  * Return:      NONE
823  *
824  * Note:
825  *      (1) We do not take j mode into consideration now
826  *      (2) Will two workitem of "switch channel" and
827  *          "switch channel bandwidth" run concurrently?
828  *---------------------------------------------------------------------------*/
829 static void
830 _PHY_SetBWMode23a92C(struct rtw_adapter *Adapter)
831 {
832         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
833         u8 regBwOpMode;
834         u8 regRRSR_RSC;
835
836         if (Adapter->bDriverStopped)
837                 return;
838
839         /* 3 */
840         /* 3<1>Set MAC register */
841         /* 3 */
842
843         regBwOpMode = rtl8723au_read8(Adapter, REG_BWOPMODE);
844         regRRSR_RSC = rtl8723au_read8(Adapter, REG_RRSR+2);
845
846         switch (pHalData->CurrentChannelBW) {
847         case HT_CHANNEL_WIDTH_20:
848                 regBwOpMode |= BW_OPMODE_20MHZ;
849                 rtl8723au_write8(Adapter, REG_BWOPMODE, regBwOpMode);
850                 break;
851         case HT_CHANNEL_WIDTH_40:
852                 regBwOpMode &= ~BW_OPMODE_20MHZ;
853                 rtl8723au_write8(Adapter, REG_BWOPMODE, regBwOpMode);
854                 regRRSR_RSC = (regRRSR_RSC & 0x90) |
855                         (pHalData->nCur40MhzPrimeSC << 5);
856                 rtl8723au_write8(Adapter, REG_RRSR+2, regRRSR_RSC);
857                 break;
858
859         default:
860                 break;
861         }
862
863         /* 3 */
864         /* 3<2>Set PHY related register */
865         /* 3 */
866         switch (pHalData->CurrentChannelBW) {
867                 /* 20 MHz channel*/
868         case HT_CHANNEL_WIDTH_20:
869                 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
870                 PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
871                 PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT(10), 1);
872
873                 break;
874
875                 /* 40 MHz channel*/
876         case HT_CHANNEL_WIDTH_40:
877                 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
878                 PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
879
880                 /*  Set Control channel to upper or lower. These settings
881                     are required only for 40MHz */
882                 PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand,
883                              (pHalData->nCur40MhzPrimeSC >> 1));
884                 PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00,
885                              pHalData->nCur40MhzPrimeSC);
886                 PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT(10), 0);
887
888                 PHY_SetBBReg(Adapter, 0x818, BIT(26) | BIT(27),
889                              (pHalData->nCur40MhzPrimeSC ==
890                               HAL_PRIME_CHNL_OFFSET_LOWER) ? 2:1);
891                 break;
892
893         default:
894                 break;
895         }
896         /* Skip over setting of J-mode in BB register here. Default value
897            is "None J mode". Emily 20070315 */
898
899         /*  Added it for 20/40 mhz switch time evaluation by guangan 070531 */
900         /* NowL = PlatformEFIORead4Byte(Adapter, TSFR); */
901         /* NowH = PlatformEFIORead4Byte(Adapter, TSFR+4); */
902         /* EndTime = ((u64)NowH << 32) + NowL; */
903
904         rtl8723a_phy_rf6052set_bw(Adapter, pHalData->CurrentChannelBW);
905 }
906
907  /*-----------------------------------------------------------------------------
908  * Function:   SetBWMode23a8190Pci()
909  *
910  * Overview:  This function is export to "HalCommon" moudule
911  *
912  * Input:               struct rtw_adapter *                    Adapter
913  *                      enum ht_channel_width   Bandwidth       20M or 40M
914  *
915  * Output:      NONE
916  *
917  * Return:      NONE
918  *
919  * Note:                We do not take j mode into consideration now
920  *---------------------------------------------------------------------------*/
921 void
922 PHY_SetBWMode23a8723A(struct rtw_adapter *Adapter,
923                    enum ht_channel_width Bandwidth, unsigned char Offset)
924 {
925         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
926         enum ht_channel_width tmpBW = pHalData->CurrentChannelBW;
927
928         pHalData->CurrentChannelBW = Bandwidth;
929
930         pHalData->nCur40MhzPrimeSC = Offset;
931
932         if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved))
933                 _PHY_SetBWMode23a92C(Adapter);
934         else
935                 pHalData->CurrentChannelBW = tmpBW;
936 }
937
938 static void _PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
939 {
940         enum RF_RADIO_PATH eRFPath;
941         u32 param1, param2;
942         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
943
944         /* s1. pre common command - CmdID_SetTxPowerLevel */
945         PHY_SetTxPowerLevel8723A(Adapter, channel);
946
947         /* s2. RF dependent command - CmdID_RF_WriteReg,
948            param1 = RF_CHNLBW, param2 = channel */
949         param1 = RF_CHNLBW;
950         param2 = channel;
951         for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) {
952                 pHalData->RfRegChnlVal[eRFPath] =
953                         (pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | param2;
954                 PHY_SetRFReg(Adapter, eRFPath, param1,
955                              bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]);
956         }
957
958         /* s3. post common command - CmdID_End, None */
959 }
960
961 void PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
962 {
963         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
964         u8 tmpchannel = pHalData->CurrentChannel;
965         bool  result = true;
966
967         if (channel == 0)
968                 channel = 1;
969
970         pHalData->CurrentChannel = channel;
971
972         if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) {
973                 _PHY_SwChnl8723A(Adapter, channel);
974
975                 if (!result)
976                         pHalData->CurrentChannel = tmpchannel;
977         } else {
978                 pHalData->CurrentChannel = tmpchannel;
979         }
980 }