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 */
phy_CalculateBitShift(u32 BitMask)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
PHY_QueryBBReg(struct rtw_adapter * Adapter,u32 RegAddr,u32 BitMask)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
PHY_SetBBReg(struct rtw_adapter * Adapter,u32 RegAddr,u32 BitMask,u32 Data)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
phy_RFSerialRead(struct rtw_adapter * Adapter,enum RF_RADIO_PATH eRFPath,u32 Offset)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
phy_RFSerialWrite(struct rtw_adapter * Adapter,enum RF_RADIO_PATH eRFPath,u32 Offset,u32 Data)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
PHY_QueryRFReg(struct rtw_adapter * Adapter,enum RF_RADIO_PATH eRFPath,u32 RegAddr,u32 BitMask)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
PHY_SetRFReg(struct rtw_adapter * Adapter,enum RF_RADIO_PATH eRFPath,u32 RegAddr,u32 BitMask,u32 Data)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 *---------------------------------------------------------------------------*/
PHY_MACConfig8723A(struct rtw_adapter * Adapter)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
phy_InitBBRFRegisterDefinition(struct rtw_adapter * Adapter)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
storePwrIndexDiffRateOffset(struct rtw_adapter * Adapter,u32 RegAddr,u32 BitMask,u32 Data)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
phy_ConfigBBWithPgHeaderFile(struct rtw_adapter * Adapter)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
phy_BB8192C_Config_1T(struct rtw_adapter * Adapter)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
phy_BB8723a_Config_ParaFile(struct rtw_adapter * Adapter)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 separate 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
PHY_BBConfig8723A(struct rtw_adapter * Adapter)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 /*-----------------------------------------------------------------------------
752 * Function: SetTxPowerLevel8723A()
753 *
754 * Overview: This function is export to "HalCommon" moudule
755 * We must consider RF path later!!!!!!!
756 *
757 * Input: struct rtw_adapter * Adapter
758 * u8 channel
759 *
760 * Output: NONE
761 *
762 * Return: NONE
763 *
764 *---------------------------------------------------------------------------*/
PHY_SetTxPowerLevel8723A(struct rtw_adapter * Adapter,u8 channel)765 void PHY_SetTxPowerLevel8723A(struct rtw_adapter *Adapter, u8 channel)
766 {
767 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
768 u8 cckpwr[2], ofdmpwr[2]; /* [0]:RF-A, [1]:RF-B */
769 int i = channel - 1;
770
771 if (pHalData->bTXPowerDataReadFromEEPORM == false)
772 return;
773
774 /* 1. CCK */
775 cckpwr[RF_PATH_A] = pHalData->TxPwrLevelCck[RF_PATH_A][i];
776 cckpwr[RF_PATH_B] = pHalData->TxPwrLevelCck[RF_PATH_B][i];
777
778 /* 2. OFDM for 1S or 2S */
779 if (GET_RF_TYPE(Adapter) == RF_1T2R ||
780 GET_RF_TYPE(Adapter) == RF_1T1R) {
781 /* Read HT 40 OFDM TX power */
782 ofdmpwr[RF_PATH_A] = pHalData->TxPwrLevelHT40_1S[RF_PATH_A][i];
783 ofdmpwr[RF_PATH_B] = pHalData->TxPwrLevelHT40_1S[RF_PATH_B][i];
784 } else if (GET_RF_TYPE(Adapter) == RF_2T2R) {
785 /* Read HT 40 OFDM TX power */
786 ofdmpwr[RF_PATH_A] = pHalData->TxPwrLevelHT40_2S[RF_PATH_A][i];
787 ofdmpwr[RF_PATH_B] = pHalData->TxPwrLevelHT40_2S[RF_PATH_B][i];
788 }
789
790 rtl823a_phy_rf6052setccktxpower(Adapter, &cckpwr[0]);
791 rtl8723a_PHY_RF6052SetOFDMTxPower(Adapter, &ofdmpwr[0], channel);
792 }
793
794 /*-----------------------------------------------------------------------------
795 * Function: PHY_SetBWMode23aCallback8192C()
796 *
797 * Overview: Timer callback function for SetSetBWMode23a
798 *
799 * Input: PRT_TIMER pTimer
800 *
801 * Output: NONE
802 *
803 * Return: NONE
804 *
805 * Note:
806 * (1) We do not take j mode into consideration now
807 * (2) Will two workitem of "switch channel" and
808 * "switch channel bandwidth" run concurrently?
809 *---------------------------------------------------------------------------*/
810 static void
_PHY_SetBWMode23a92C(struct rtw_adapter * Adapter)811 _PHY_SetBWMode23a92C(struct rtw_adapter *Adapter)
812 {
813 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
814 u8 regBwOpMode;
815 u8 regRRSR_RSC;
816
817 if (Adapter->bDriverStopped)
818 return;
819
820 /* 3 */
821 /* 3<1>Set MAC register */
822 /* 3 */
823
824 regBwOpMode = rtl8723au_read8(Adapter, REG_BWOPMODE);
825 regRRSR_RSC = rtl8723au_read8(Adapter, REG_RRSR+2);
826
827 switch (pHalData->CurrentChannelBW) {
828 case HT_CHANNEL_WIDTH_20:
829 regBwOpMode |= BW_OPMODE_20MHZ;
830 rtl8723au_write8(Adapter, REG_BWOPMODE, regBwOpMode);
831 break;
832 case HT_CHANNEL_WIDTH_40:
833 regBwOpMode &= ~BW_OPMODE_20MHZ;
834 rtl8723au_write8(Adapter, REG_BWOPMODE, regBwOpMode);
835 regRRSR_RSC = (regRRSR_RSC & 0x90) |
836 (pHalData->nCur40MhzPrimeSC << 5);
837 rtl8723au_write8(Adapter, REG_RRSR+2, regRRSR_RSC);
838 break;
839
840 default:
841 break;
842 }
843
844 /* 3 */
845 /* 3<2>Set PHY related register */
846 /* 3 */
847 switch (pHalData->CurrentChannelBW) {
848 /* 20 MHz channel*/
849 case HT_CHANNEL_WIDTH_20:
850 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
851 PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
852 PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT(10), 1);
853
854 break;
855
856 /* 40 MHz channel*/
857 case HT_CHANNEL_WIDTH_40:
858 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
859 PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
860
861 /* Set Control channel to upper or lower. These settings
862 are required only for 40MHz */
863 PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand,
864 (pHalData->nCur40MhzPrimeSC >> 1));
865 PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00,
866 pHalData->nCur40MhzPrimeSC);
867 PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT(10), 0);
868
869 PHY_SetBBReg(Adapter, 0x818, BIT(26) | BIT(27),
870 (pHalData->nCur40MhzPrimeSC ==
871 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2:1);
872 break;
873
874 default:
875 break;
876 }
877 /* Skip over setting of J-mode in BB register here. Default value
878 is "None J mode". Emily 20070315 */
879
880 /* Added it for 20/40 mhz switch time evaluation by guangan 070531 */
881 /* NowL = PlatformEFIORead4Byte(Adapter, TSFR); */
882 /* NowH = PlatformEFIORead4Byte(Adapter, TSFR+4); */
883 /* EndTime = ((u64)NowH << 32) + NowL; */
884
885 rtl8723a_phy_rf6052set_bw(Adapter, pHalData->CurrentChannelBW);
886 }
887
888 /*-----------------------------------------------------------------------------
889 * Function: SetBWMode23a8190Pci()
890 *
891 * Overview: This function is export to "HalCommon" moudule
892 *
893 * Input: struct rtw_adapter * Adapter
894 * enum ht_channel_width Bandwidth 20M or 40M
895 *
896 * Output: NONE
897 *
898 * Return: NONE
899 *
900 * Note: We do not take j mode into consideration now
901 *---------------------------------------------------------------------------*/
902 void
PHY_SetBWMode23a8723A(struct rtw_adapter * Adapter,enum ht_channel_width Bandwidth,unsigned char Offset)903 PHY_SetBWMode23a8723A(struct rtw_adapter *Adapter,
904 enum ht_channel_width Bandwidth, unsigned char Offset)
905 {
906 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
907 enum ht_channel_width tmpBW = pHalData->CurrentChannelBW;
908
909 pHalData->CurrentChannelBW = Bandwidth;
910
911 pHalData->nCur40MhzPrimeSC = Offset;
912
913 if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved))
914 _PHY_SetBWMode23a92C(Adapter);
915 else
916 pHalData->CurrentChannelBW = tmpBW;
917 }
918
_PHY_SwChnl8723A(struct rtw_adapter * Adapter,u8 channel)919 static void _PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
920 {
921 enum RF_RADIO_PATH eRFPath;
922 u32 param1, param2;
923 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
924
925 /* s1. pre common command - CmdID_SetTxPowerLevel */
926 PHY_SetTxPowerLevel8723A(Adapter, channel);
927
928 /* s2. RF dependent command - CmdID_RF_WriteReg,
929 param1 = RF_CHNLBW, param2 = channel */
930 param1 = RF_CHNLBW;
931 param2 = channel;
932 for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) {
933 pHalData->RfRegChnlVal[eRFPath] =
934 (pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | param2;
935 PHY_SetRFReg(Adapter, eRFPath, param1,
936 bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]);
937 }
938
939 /* s3. post common command - CmdID_End, None */
940 }
941
PHY_SwChnl8723A(struct rtw_adapter * Adapter,u8 channel)942 void PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
943 {
944 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
945 u8 tmpchannel = pHalData->CurrentChannel;
946 bool result = true;
947
948 if (channel == 0)
949 channel = 1;
950
951 pHalData->CurrentChannel = channel;
952
953 if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) {
954 _PHY_SwChnl8723A(Adapter, channel);
955
956 if (!result)
957 pHalData->CurrentChannel = tmpchannel;
958 } else {
959 pHalData->CurrentChannel = tmpchannel;
960 }
961 }
962