Commit | Line | Data |
---|---|---|
f7c92d2c LF |
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> | |
050abc45 | 21 | #include <usb_ops_linux.h> |
f7c92d2c LF |
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 | ||
050abc45 | 91 | OriginalValue = rtl8723au_read32(Adapter, RegAddr); |
f7c92d2c LF |
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 | /* RT_TRACE(COMP_RF, DBG_TRACE, ("--->PHY_SetBBReg(): RegAddr(%#lx), BitMask(%#lx), Data(%#lx)\n", RegAddr, BitMask, Data)); */ | |
125 | ||
126 | if (BitMask != bMaskDWord) {/* if not "double word" write */ | |
050abc45 | 127 | OriginalValue = rtl8723au_read32(Adapter, RegAddr); |
f7c92d2c LF |
128 | BitShift = phy_CalculateBitShift(BitMask); |
129 | Data = ((OriginalValue & (~BitMask)) | (Data << BitShift)); | |
130 | } | |
131 | ||
edbfd672 | 132 | rtl8723au_write32(Adapter, RegAddr, Data); |
f7c92d2c LF |
133 | |
134 | /* RTPRINT(FPHY, PHY_BBW, ("BBW MASK = 0x%lx Addr[0x%lx]= 0x%lx\n", BitMask, RegAddr, Data)); */ | |
135 | /* RT_TRACE(COMP_RF, DBG_TRACE, ("<---PHY_SetBBReg(): RegAddr(%#lx), BitMask(%#lx), Data(%#lx)\n", RegAddr, BitMask, Data)); */ | |
136 | } | |
137 | ||
138 | /* */ | |
139 | /* 2. RF register R/W API */ | |
140 | /* */ | |
141 | ||
142 | /** | |
143 | * Function: phy_RFSerialRead | |
144 | * | |
145 | * OverView: Read regster from RF chips | |
146 | * | |
147 | * Input: | |
148 | * struct rtw_adapter * Adapter, | |
149 | * enum RF_RADIO_PATH eRFPath, Radio path of A/B/C/D | |
150 | * u32 Offset, The target address to be read | |
151 | * | |
152 | * Output: None | |
153 | * Return: u32 reback value | |
154 | * Note: Threre are three types of serial operations: | |
155 | * 1. Software serial write | |
156 | * 2. Hardware LSSI-Low Speed Serial Interface | |
157 | * 3. Hardware HSSI-High speed | |
158 | * serial write. Driver need to implement (1) and (2). | |
159 | * This function is equal to the combination of RF_ReadReg() and | |
160 | * RFLSSIRead() | |
161 | */ | |
162 | static u32 | |
163 | phy_RFSerialRead(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath, | |
164 | u32 Offset) | |
165 | { | |
166 | u32 retValue = 0; | |
167 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | |
168 | struct bb_reg_define *pPhyReg = &pHalData->PHYRegDef[eRFPath]; | |
169 | u32 NewOffset; | |
170 | u32 tmplong, tmplong2; | |
171 | u8 RfPiEnable = 0; | |
172 | /* */ | |
173 | /* Make sure RF register offset is correct */ | |
174 | /* */ | |
175 | Offset &= 0x3f; | |
176 | ||
177 | /* */ | |
178 | /* Switch page for 8256 RF IC */ | |
179 | /* */ | |
180 | NewOffset = Offset; | |
181 | ||
182 | /* 2009/06/17 MH We can not execute IO for power save or | |
183 | other accident mode. */ | |
184 | /* if (RT_CANNOT_IO(Adapter)) */ | |
185 | /* */ | |
186 | /* RTPRINT(FPHY, PHY_RFR, ("phy_RFSerialRead return all one\n")); */ | |
187 | /* return 0xFFFFFFFF; */ | |
188 | /* */ | |
189 | ||
190 | /* For 92S LSSI Read RFLSSIRead */ | |
191 | /* For RF A/B write 0x824/82c(does not work in the future) */ | |
192 | /* We must use 0x824 for RF A and B to execute read trigger */ | |
193 | tmplong = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord); | |
194 | if (eRFPath == RF_PATH_A) | |
195 | tmplong2 = tmplong; | |
196 | else | |
197 | tmplong2 = PHY_QueryBBReg(Adapter, pPhyReg->rfHSSIPara2, | |
198 | bMaskDWord); | |
199 | ||
200 | tmplong2 = (tmplong2 & ~bLSSIReadAddress) | | |
201 | (NewOffset << 23) | bLSSIReadEdge; /* T65 RF */ | |
202 | ||
203 | PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2, | |
204 | bMaskDWord, tmplong & (~bLSSIReadEdge)); | |
205 | udelay(10);/* PlatformStallExecution(10); */ | |
206 | ||
207 | PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord, tmplong2); | |
208 | udelay(100);/* PlatformStallExecution(100); */ | |
209 | ||
210 | PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord, | |
211 | tmplong | bLSSIReadEdge); | |
212 | udelay(10);/* PlatformStallExecution(10); */ | |
213 | ||
214 | if (eRFPath == RF_PATH_A) | |
215 | RfPiEnable = (u8)PHY_QueryBBReg(Adapter, | |
8f7654c1 JS |
216 | rFPGA0_XA_HSSIParameter1, |
217 | BIT(8)); | |
f7c92d2c LF |
218 | else if (eRFPath == RF_PATH_B) |
219 | RfPiEnable = (u8)PHY_QueryBBReg(Adapter, | |
8f7654c1 JS |
220 | rFPGA0_XB_HSSIParameter1, |
221 | BIT(8)); | |
f7c92d2c LF |
222 | |
223 | if (RfPiEnable) { | |
224 | /* Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */ | |
225 | retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi, | |
226 | bLSSIReadBackData); | |
227 | /* DBG_8723A("Readback from RF-PI : 0x%x\n", retValue); */ | |
228 | } else { | |
229 | /* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */ | |
230 | retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack, | |
231 | bLSSIReadBackData); | |
232 | /* DBG_8723A("Readback from RF-SI : 0x%x\n", retValue); */ | |
233 | } | |
234 | /* DBG_8723A("RFR-%d Addr[0x%x]= 0x%x\n", eRFPath, pPhyReg->rfLSSIReadBack, retValue); */ | |
235 | ||
236 | return retValue; | |
237 | } | |
238 | ||
239 | /** | |
240 | * Function: phy_RFSerialWrite | |
241 | * | |
242 | * OverView: Write data to RF register (page 8~) | |
243 | * | |
244 | * Input: | |
245 | * struct rtw_adapter * Adapter, | |
246 | * enum RF_RADIO_PATH eRFPath, Radio path of A/B/C/D | |
247 | * u32 Offset, The target address to be read | |
248 | * u32 Data The new register Data in the target | |
249 | * bit position of the target to be read | |
250 | * | |
251 | * Output: | |
252 | * None | |
253 | * Return: | |
254 | * None | |
255 | * Note: | |
256 | * Threre are three types of serial operations: | |
257 | * 1. Software serial write | |
258 | * 2. Hardware LSSI-Low Speed Serial Interface | |
259 | * 3. Hardware HSSI-High speed | |
260 | * serial write. Driver need to implement (1) and (2). | |
261 | * This function is equal to the combination of RF_ReadReg() and | |
262 | * RFLSSIRead() | |
263 | * | |
264 | * Note: For RF8256 only | |
265 | * The total count of RTL8256(Zebra4) register is around 36 bit it only employs | |
266 | * 4-bit RF address. RTL8256 uses "register mode control bit" | |
267 | * (Reg00[12], Reg00[10]) to access register address bigger than 0xf. | |
268 | * See "Appendix-4 in PHY Configuration programming guide" for more details. | |
269 | * Thus, we define a sub-finction for RTL8526 register address conversion | |
270 | * =========================================================== | |
271 | * Register Mode: RegCTL[1] RegCTL[0] Note | |
272 | * (Reg00[12]) (Reg00[10]) | |
273 | * =========================================================== | |
274 | * Reg_Mode0 0 x Reg 0 ~15(0x0 ~ 0xf) | |
275 | * ------------------------------------------------------------------ | |
276 | * Reg_Mode1 1 0 Reg 16 ~30(0x1 ~ 0xf) | |
277 | * ------------------------------------------------------------------ | |
278 | * Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf) | |
279 | * ------------------------------------------------------------------ | |
280 | * | |
281 | * 2008/09/02 MH Add 92S RF definition | |
282 | */ | |
283 | static void | |
284 | phy_RFSerialWrite(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath, | |
285 | u32 Offset, u32 Data) | |
286 | { | |
287 | u32 DataAndAddr = 0; | |
288 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | |
289 | struct bb_reg_define *pPhyReg = &pHalData->PHYRegDef[eRFPath]; | |
290 | u32 NewOffset; | |
291 | ||
292 | /* 2009/06/17 MH We can not execute IO for power save or | |
293 | other accident mode. */ | |
294 | /* if (RT_CANNOT_IO(Adapter)) */ | |
295 | /* */ | |
296 | /* RTPRINT(FPHY, PHY_RFW, ("phy_RFSerialWrite stop\n")); */ | |
297 | /* return; */ | |
298 | /* */ | |
299 | ||
300 | Offset &= 0x3f; | |
301 | ||
302 | /* */ | |
303 | /* Shadow Update */ | |
304 | /* */ | |
305 | /* PHY_RFShadowWrite(Adapter, eRFPath, Offset, Data); */ | |
306 | ||
307 | /* */ | |
308 | /* Switch page for 8256 RF IC */ | |
309 | /* */ | |
310 | NewOffset = Offset; | |
311 | ||
312 | /* */ | |
313 | /* Put write addr in [5:0] and write data in [31:16] */ | |
314 | /* */ | |
315 | /* DataAndAddr = (Data<<16) | (NewOffset&0x3f); */ | |
316 | /* T65 RF */ | |
317 | DataAndAddr = ((NewOffset<<20) | (Data&0x000fffff)) & 0x0fffffff; | |
318 | ||
319 | /* */ | |
320 | /* Write Operation */ | |
321 | /* */ | |
322 | PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); | |
323 | /* RTPRINT(FPHY, PHY_RFW, ("RFW-%d Addr[0x%lx]= 0x%lx\n", eRFPath, pPhyReg->rf3wireOffset, DataAndAddr)); */ | |
324 | ||
325 | } | |
326 | ||
327 | /** | |
328 | * Function: PHY_QueryRFReg | |
329 | * | |
330 | * OverView: Query "Specific bits" to RF register (page 8~) | |
331 | * | |
332 | * Input: | |
333 | * struct rtw_adapter * Adapter, | |
334 | * enum RF_RADIO_PATH eRFPath, Radio path of A/B/C/D | |
335 | * u32 RegAddr, The target address to be read | |
336 | * u32BitMask The target bit position in the target | |
337 | * address to be read | |
338 | * | |
339 | * Output: | |
340 | * None | |
341 | * Return: | |
342 | * u32 Readback value | |
343 | * Note: | |
344 | * This function is equal to "GetRFRegSetting" in PHY programming guide | |
345 | */ | |
346 | u32 | |
347 | PHY_QueryRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath, | |
348 | u32 RegAddr, u32 BitMask) | |
349 | { | |
350 | u32 Original_Value, Readback_Value, BitShift; | |
351 | /* struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); */ | |
352 | /* u8 RFWaitCounter = 0; */ | |
353 | /* _irqL irqL; */ | |
354 | ||
355 | Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr); | |
356 | ||
357 | BitShift = phy_CalculateBitShift(BitMask); | |
358 | Readback_Value = (Original_Value & BitMask) >> BitShift; | |
359 | ||
360 | return Readback_Value; | |
361 | } | |
362 | ||
363 | /** | |
364 | * Function: PHY_SetRFReg | |
365 | * | |
366 | * OverView: Write "Specific bits" to RF register (page 8~) | |
367 | * | |
368 | * Input: | |
369 | * struct rtw_adapter * Adapter, | |
370 | * enum RF_RADIO_PATH eRFPath, Radio path of A/B/C/D | |
371 | * u32 RegAddr, The target address to be modified | |
372 | * u32 BitMask The target bit position in the target | |
373 | * address to be modified | |
374 | * u32 Data The new register Data in the target | |
375 | * bit position of the target address | |
376 | * | |
377 | * Output: | |
378 | * None | |
379 | * Return: | |
380 | * None | |
381 | * Note: This function is equal to "PutRFRegSetting" in PHY programming guide | |
382 | */ | |
383 | void | |
384 | PHY_SetRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath, | |
385 | u32 RegAddr, u32 BitMask, u32 Data) | |
386 | { | |
387 | /* struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); */ | |
388 | /* u8 RFWaitCounter = 0; */ | |
389 | u32 Original_Value, BitShift; | |
390 | ||
391 | /* RF data is 12 bits only */ | |
392 | if (BitMask != bRFRegOffsetMask) { | |
393 | Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr); | |
394 | BitShift = phy_CalculateBitShift(BitMask); | |
395 | Data = ((Original_Value & (~BitMask)) | (Data << BitShift)); | |
396 | } | |
397 | ||
398 | phy_RFSerialWrite(Adapter, eRFPath, RegAddr, Data); | |
399 | } | |
400 | ||
401 | /* 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */ | |
402 | ||
403 | /*----------------------------------------------------------------------------- | |
404 | * Function: PHY_MACConfig8723A | |
405 | * | |
406 | * Overview: Condig MAC by header file or parameter file. | |
407 | * | |
408 | * Input: NONE | |
409 | * | |
410 | * Output: NONE | |
411 | * | |
412 | * Return: NONE | |
413 | * | |
414 | * Revised History: | |
415 | * When Who Remark | |
416 | * 08/12/2008 MHC Create Version 0. | |
417 | * | |
418 | *---------------------------------------------------------------------------*/ | |
c691ec33 | 419 | int PHY_MACConfig8723A(struct rtw_adapter *Adapter) |
f7c92d2c LF |
420 | { |
421 | int rtStatus = _SUCCESS; | |
422 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | |
f7c92d2c LF |
423 | bool is92C = IS_92C_SERIAL(pHalData->VersionID); |
424 | ||
f7c92d2c LF |
425 | /* */ |
426 | /* Config MAC */ | |
427 | /* */ | |
14659677 | 428 | if (ODM_ConfigMACWithHeaderFile23a(&pHalData->odmpriv) == _FAIL) |
f7c92d2c LF |
429 | rtStatus = _FAIL; |
430 | ||
431 | /* 2010.07.13 AMPDU aggregation number 9 */ | |
432 | /* rtw_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); */ | |
edbfd672 | 433 | rtl8723au_write8(Adapter, REG_MAX_AGGR_NUM, 0x0A); |
f7c92d2c | 434 | if (is92C && (BOARD_USB_DONGLE == pHalData->BoardType)) |
edbfd672 | 435 | rtl8723au_write8(Adapter, 0x40, 0x04); |
f7c92d2c LF |
436 | |
437 | return rtStatus; | |
438 | } | |
439 | ||
440 | /** | |
441 | * Function: phy_InitBBRFRegisterDefinition | |
442 | * | |
443 | * OverView: Initialize Register definition offset for Radio Path A/B/C/D | |
444 | * | |
445 | * Input: | |
446 | * struct rtw_adapter * Adapter, | |
447 | * | |
448 | * Output: None | |
449 | * Return: None | |
450 | * Note: | |
451 | * The initialization value is constant and it should never be changes | |
452 | */ | |
453 | static void | |
454 | phy_InitBBRFRegisterDefinition(struct rtw_adapter *Adapter) | |
455 | { | |
456 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | |
457 | ||
458 | /* RF Interface Sowrtware Control */ | |
459 | /* 16 LSBs if read 32-bit from 0x870 */ | |
460 | pHalData->PHYRegDef[RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; | |
461 | /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */ | |
462 | pHalData->PHYRegDef[RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; | |
f7c92d2c LF |
463 | |
464 | /* RF Interface Readback Value */ | |
465 | /* 16 LSBs if read 32-bit from 0x8E0 */ | |
466 | pHalData->PHYRegDef[RF_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; | |
467 | /* 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */ | |
468 | pHalData->PHYRegDef[RF_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB; | |
f7c92d2c LF |
469 | |
470 | /* RF Interface Output (and Enable) */ | |
471 | /* 16 LSBs if read 32-bit from 0x860 */ | |
472 | pHalData->PHYRegDef[RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; | |
473 | /* 16 LSBs if read 32-bit from 0x864 */ | |
474 | pHalData->PHYRegDef[RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; | |
475 | ||
476 | /* RF Interface (Output and) Enable */ | |
477 | /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */ | |
478 | pHalData->PHYRegDef[RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; | |
479 | /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */ | |
480 | pHalData->PHYRegDef[RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; | |
481 | ||
482 | /* Addr of LSSI. Wirte RF register by driver */ | |
483 | pHalData->PHYRegDef[RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; | |
484 | pHalData->PHYRegDef[RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; | |
485 | ||
486 | /* RF parameter */ | |
487 | /* BB Band Select */ | |
488 | pHalData->PHYRegDef[RF_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; | |
489 | pHalData->PHYRegDef[RF_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter; | |
f7c92d2c LF |
490 | |
491 | /* Tx AGC Gain Stage (same for all path. Should we remove this?) */ | |
492 | pHalData->PHYRegDef[RF_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; | |
493 | pHalData->PHYRegDef[RF_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; | |
f7c92d2c LF |
494 | |
495 | /* Tranceiver A~D HSSI Parameter-1 */ | |
496 | /* wire control parameter1 */ | |
497 | pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; | |
498 | /* wire control parameter1 */ | |
499 | pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; | |
500 | ||
501 | /* Tranceiver A~D HSSI Parameter-2 */ | |
502 | /* wire control parameter2 */ | |
503 | pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; | |
504 | /* wire control parameter2 */ | |
505 | pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; | |
506 | ||
507 | /* RF switch Control */ | |
508 | pHalData->PHYRegDef[RF_PATH_A].rfSwitchControl = | |
509 | rFPGA0_XAB_SwitchControl; /* TR/Ant switch control */ | |
510 | pHalData->PHYRegDef[RF_PATH_B].rfSwitchControl = | |
511 | rFPGA0_XAB_SwitchControl; | |
f7c92d2c LF |
512 | |
513 | /* AGC control 1 */ | |
514 | pHalData->PHYRegDef[RF_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1; | |
515 | pHalData->PHYRegDef[RF_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1; | |
f7c92d2c LF |
516 | |
517 | /* AGC control 2 */ | |
518 | pHalData->PHYRegDef[RF_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2; | |
519 | pHalData->PHYRegDef[RF_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2; | |
f7c92d2c LF |
520 | |
521 | /* RX AFE control 1 */ | |
522 | pHalData->PHYRegDef[RF_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance; | |
523 | pHalData->PHYRegDef[RF_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance; | |
f7c92d2c LF |
524 | |
525 | /* RX AFE control 1 */ | |
526 | pHalData->PHYRegDef[RF_PATH_A].rfRxAFE = rOFDM0_XARxAFE; | |
527 | pHalData->PHYRegDef[RF_PATH_B].rfRxAFE = rOFDM0_XBRxAFE; | |
f7c92d2c LF |
528 | |
529 | /* Tx AFE control 1 */ | |
530 | pHalData->PHYRegDef[RF_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance; | |
531 | pHalData->PHYRegDef[RF_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance; | |
f7c92d2c LF |
532 | |
533 | /* Tx AFE control 2 */ | |
534 | pHalData->PHYRegDef[RF_PATH_A].rfTxAFE = rOFDM0_XATxAFE; | |
535 | pHalData->PHYRegDef[RF_PATH_B].rfTxAFE = rOFDM0_XBTxAFE; | |
f7c92d2c LF |
536 | |
537 | /* Tranceiver LSSI Readback SI mode */ | |
538 | pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; | |
539 | pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; | |
f7c92d2c LF |
540 | |
541 | /* Tranceiver LSSI Readback PI mode */ | |
542 | pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBackPi = | |
543 | TransceiverA_HSPI_Readback; | |
544 | pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBackPi = | |
545 | TransceiverB_HSPI_Readback; | |
f7c92d2c LF |
546 | } |
547 | ||
548 | /* The following is for High Power PA */ | |
549 | static void | |
550 | storePwrIndexDiffRateOffset(struct rtw_adapter *Adapter, u32 RegAddr, | |
551 | u32 BitMask, u32 Data) | |
552 | { | |
553 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | |
554 | ||
555 | if (RegAddr == rTxAGC_A_Rate18_06) { | |
556 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0] = Data; | |
557 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
558 | ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%lx\n", | |
559 | pHalData->pwrGroupCnt, */ | |
560 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
561 | pHalData->pwrGroupCnt][0])); */ | |
562 | } | |
563 | if (RegAddr == rTxAGC_A_Rate54_24) { | |
564 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][1] = Data; | |
565 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
566 | ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%lx\n", | |
567 | pHalData->pwrGroupCnt, */ | |
568 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
569 | pHalData->pwrGroupCnt][1])); */ | |
570 | } | |
571 | if (RegAddr == rTxAGC_A_CCK1_Mcs32) { | |
572 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][6] = Data; | |
573 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
574 | ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%lx\n", | |
575 | pHalData->pwrGroupCnt, */ | |
576 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
577 | pHalData->pwrGroupCnt][6])); */ | |
578 | } | |
579 | if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0xffffff00) { | |
580 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][7] = Data; | |
581 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
582 | ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%lx\n", | |
583 | pHalData->pwrGroupCnt, */ | |
584 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
585 | pHalData->pwrGroupCnt][7])); */ | |
586 | } | |
587 | if (RegAddr == rTxAGC_A_Mcs03_Mcs00) { | |
588 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][2] = Data; | |
589 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
590 | ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%lx\n", | |
591 | pHalData->pwrGroupCnt, */ | |
592 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
593 | pHalData->pwrGroupCnt][2])); */ | |
594 | } | |
595 | if (RegAddr == rTxAGC_A_Mcs07_Mcs04) { | |
596 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][3] = Data; | |
597 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
598 | ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%lx\n", | |
599 | pHalData->pwrGroupCnt, */ | |
600 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
601 | pHalData->pwrGroupCnt][3])); */ | |
602 | } | |
603 | if (RegAddr == rTxAGC_A_Mcs11_Mcs08) { | |
604 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][4] = Data; | |
605 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
606 | ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%lx\n", | |
607 | pHalData->pwrGroupCnt, */ | |
608 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
609 | pHalData->pwrGroupCnt][4])); */ | |
610 | } | |
611 | if (RegAddr == rTxAGC_A_Mcs15_Mcs12) { | |
612 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][5] = Data; | |
613 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
614 | ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%lx\n", | |
615 | pHalData->pwrGroupCnt, */ | |
616 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
617 | pHalData->pwrGroupCnt][5])); */ | |
618 | } | |
619 | if (RegAddr == rTxAGC_B_Rate18_06) { | |
620 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][8] = Data; | |
621 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
622 | ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%lx\n", | |
623 | pHalData->pwrGroupCnt, */ | |
624 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
625 | pHalData->pwrGroupCnt][8])); */ | |
626 | } | |
627 | if (RegAddr == rTxAGC_B_Rate54_24) { | |
628 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][9] = Data; | |
629 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
630 | ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%lx\n", | |
631 | pHalData->pwrGroupCnt, */ | |
632 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
633 | pHalData->pwrGroupCnt][9])); */ | |
634 | } | |
635 | if (RegAddr == rTxAGC_B_CCK1_55_Mcs32) { | |
636 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][14] = Data; | |
637 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
638 | ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%lx\n", | |
639 | pHalData->pwrGroupCnt, */ | |
640 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
641 | pHalData->pwrGroupCnt][14])); */ | |
642 | } | |
643 | if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0x000000ff) { | |
644 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][15] = Data; | |
645 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
646 | ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%lx\n", | |
647 | pHalData->pwrGroupCnt, */ | |
648 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
649 | pHalData->pwrGroupCnt][15])); */ | |
650 | } | |
651 | if (RegAddr == rTxAGC_B_Mcs03_Mcs00) { | |
652 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][10] = Data; | |
653 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
654 | ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%lx\n", | |
655 | pHalData->pwrGroupCnt, */ | |
656 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
657 | pHalData->pwrGroupCnt][10])); */ | |
658 | } | |
659 | if (RegAddr == rTxAGC_B_Mcs07_Mcs04) { | |
660 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][11] = Data; | |
661 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
662 | ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%lx\n", | |
663 | pHalData->pwrGroupCnt, */ | |
664 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
665 | pHalData->pwrGroupCnt][11])); */ | |
666 | } | |
667 | if (RegAddr == rTxAGC_B_Mcs11_Mcs08) { | |
668 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][12] = Data; | |
669 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
670 | ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%lx\n", | |
671 | pHalData->pwrGroupCnt, */ | |
672 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
673 | pHalData->pwrGroupCnt][12])); */ | |
674 | } | |
675 | if (RegAddr == rTxAGC_B_Mcs15_Mcs12) { | |
676 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][13] = Data; | |
677 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | |
678 | ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%lx\n", | |
679 | pHalData->pwrGroupCnt, */ | |
680 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | |
681 | pHalData->pwrGroupCnt][13])); */ | |
682 | pHalData->pwrGroupCnt++; | |
683 | } | |
684 | } | |
685 | ||
686 | /*----------------------------------------------------------------------------- | |
687 | * Function: phy_ConfigBBWithPgHeaderFile | |
688 | * | |
689 | * Overview: Config PHY_REG_PG array | |
690 | * | |
691 | * Input: NONE | |
692 | * | |
693 | * Output: NONE | |
694 | * | |
695 | * Return: NONE | |
696 | * | |
697 | * Revised History: | |
698 | * When Who Remark | |
699 | * 11/06/2008 MHC Add later!!!!!!.. Please modify for new files!!!! | |
700 | * 11/10/2008 tynli Modify to mew files. | |
701 | *---------------------------------------------------------------------------*/ | |
702 | static int | |
703 | phy_ConfigBBWithPgHeaderFile(struct rtw_adapter *Adapter, u8 ConfigType) | |
704 | { | |
705 | int i; | |
706 | u32 *Rtl819XPHY_REGArray_Table_PG; | |
707 | u16 PHY_REGArrayPGLen; | |
708 | ||
709 | PHY_REGArrayPGLen = Rtl8723_PHY_REG_Array_PGLength; | |
710 | Rtl819XPHY_REGArray_Table_PG = (u32 *)Rtl8723_PHY_REG_Array_PG; | |
711 | ||
712 | if (ConfigType == BaseBand_Config_PHY_REG) { | |
713 | for (i = 0; i < PHY_REGArrayPGLen; i = i + 3) { | |
714 | storePwrIndexDiffRateOffset(Adapter, | |
715 | Rtl819XPHY_REGArray_Table_PG[i], | |
716 | Rtl819XPHY_REGArray_Table_PG[i+1], | |
717 | Rtl819XPHY_REGArray_Table_PG[i+2]); | |
718 | } | |
719 | } | |
720 | ||
721 | return _SUCCESS; | |
722 | } /* phy_ConfigBBWithPgHeaderFile */ | |
723 | ||
724 | static void | |
725 | phy_BB8192C_Config_1T(struct rtw_adapter *Adapter) | |
726 | { | |
727 | /* for path - B */ | |
728 | PHY_SetBBReg(Adapter, rFPGA0_TxInfo, 0x3, 0x2); | |
729 | PHY_SetBBReg(Adapter, rFPGA1_TxInfo, 0x300033, 0x200022); | |
730 | ||
731 | /* 20100519 Joseph: Add for 1T2R config. Suggested by Kevin, | |
732 | Jenyu and Yunan. */ | |
733 | PHY_SetBBReg(Adapter, rCCK0_AFESetting, bMaskByte3, 0x45); | |
734 | PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, bMaskByte0, 0x23); | |
735 | /* B path first AGC */ | |
736 | PHY_SetBBReg(Adapter, rOFDM0_AGCParameter1, 0x30, 0x1); | |
737 | ||
738 | PHY_SetBBReg(Adapter, 0xe74, 0x0c000000, 0x2); | |
739 | PHY_SetBBReg(Adapter, 0xe78, 0x0c000000, 0x2); | |
740 | PHY_SetBBReg(Adapter, 0xe7c, 0x0c000000, 0x2); | |
741 | PHY_SetBBReg(Adapter, 0xe80, 0x0c000000, 0x2); | |
742 | PHY_SetBBReg(Adapter, 0xe88, 0x0c000000, 0x2); | |
743 | } | |
744 | ||
745 | static int | |
746 | phy_BB8723a_Config_ParaFile(struct rtw_adapter *Adapter) | |
747 | { | |
748 | struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter); | |
749 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | |
750 | int rtStatus = _SUCCESS; | |
751 | ||
f7c92d2c LF |
752 | /* */ |
753 | /* 1. Read PHY_REG.TXT BB INIT!! */ | |
754 | /* We will seperate as 88C / 92C according to chip version */ | |
755 | /* */ | |
14659677 JS |
756 | if (ODM_ConfigBBWithHeaderFile23a(&pHalData->odmpriv, |
757 | CONFIG_BB_PHY_REG) == _FAIL) | |
f7c92d2c LF |
758 | rtStatus = _FAIL; |
759 | if (rtStatus != _SUCCESS) | |
760 | goto phy_BB8190_Config_ParaFile_Fail; | |
761 | ||
762 | /* */ | |
763 | /* 20100318 Joseph: Config 2T2R to 1T2R if necessary. */ | |
764 | /* */ | |
765 | if (pHalData->rf_type == RF_1T2R) { | |
766 | phy_BB8192C_Config_1T(Adapter); | |
767 | DBG_8723A("phy_BB8723a_Config_ParaFile():Config to 1T!!\n"); | |
768 | } | |
769 | ||
770 | /* */ | |
771 | /* 2. If EEPROM or EFUSE autoload OK, We must config by | |
772 | PHY_REG_PG.txt */ | |
773 | /* */ | |
774 | if (pEEPROM->bautoload_fail_flag == false) { | |
775 | pHalData->pwrGroupCnt = 0; | |
776 | ||
777 | rtStatus = phy_ConfigBBWithPgHeaderFile(Adapter, | |
778 | BaseBand_Config_PHY_REG); | |
779 | } | |
780 | ||
781 | if (rtStatus != _SUCCESS) | |
782 | goto phy_BB8190_Config_ParaFile_Fail; | |
783 | ||
784 | /* */ | |
785 | /* 3. BB AGC table Initialization */ | |
786 | /* */ | |
14659677 JS |
787 | if (ODM_ConfigBBWithHeaderFile23a(&pHalData->odmpriv, |
788 | CONFIG_BB_AGC_TAB) == _FAIL) | |
f7c92d2c LF |
789 | rtStatus = _FAIL; |
790 | ||
791 | phy_BB8190_Config_ParaFile_Fail: | |
792 | ||
793 | return rtStatus; | |
794 | } | |
795 | ||
796 | int | |
797 | PHY_BBConfig8723A(struct rtw_adapter *Adapter) | |
798 | { | |
799 | int rtStatus = _SUCCESS; | |
800 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | |
801 | u8 TmpU1B = 0; | |
802 | u8 CrystalCap; | |
803 | ||
804 | phy_InitBBRFRegisterDefinition(Adapter); | |
805 | ||
806 | /* Suggested by Scott. tynli_test. 2010.12.30. */ | |
807 | /* 1. 0x28[1] = 1 */ | |
050abc45 | 808 | TmpU1B = rtl8723au_read8(Adapter, REG_AFE_PLL_CTRL); |
f7c92d2c | 809 | udelay(2); |
edbfd672 | 810 | rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL, TmpU1B | BIT(1)); |
f7c92d2c LF |
811 | udelay(2); |
812 | ||
813 | /* 2. 0x29[7:0] = 0xFF */ | |
edbfd672 | 814 | rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL+1, 0xff); |
f7c92d2c LF |
815 | udelay(2); |
816 | ||
817 | /* 3. 0x02[1:0] = 2b'11 */ | |
050abc45 | 818 | TmpU1B = rtl8723au_read8(Adapter, REG_SYS_FUNC_EN); |
edbfd672 JS |
819 | rtl8723au_write8(Adapter, REG_SYS_FUNC_EN, |
820 | (TmpU1B | FEN_BB_GLB_RSTn | FEN_BBRSTB)); | |
f7c92d2c LF |
821 | |
822 | /* 4. 0x25[6] = 0 */ | |
050abc45 | 823 | TmpU1B = rtl8723au_read8(Adapter, REG_AFE_XTAL_CTRL + 1); |
edbfd672 | 824 | rtl8723au_write8(Adapter, REG_AFE_XTAL_CTRL+1, TmpU1B & ~BIT(6)); |
f7c92d2c LF |
825 | |
826 | /* 5. 0x24[20] = 0 Advised by SD3 Alex Wang. 2011.02.09. */ | |
050abc45 | 827 | TmpU1B = rtl8723au_read8(Adapter, REG_AFE_XTAL_CTRL+2); |
edbfd672 | 828 | rtl8723au_write8(Adapter, REG_AFE_XTAL_CTRL+2, TmpU1B & ~BIT(4)); |
f7c92d2c LF |
829 | |
830 | /* 6. 0x1f[7:0] = 0x07 */ | |
edbfd672 | 831 | rtl8723au_write8(Adapter, REG_RF_CTRL, 0x07); |
f7c92d2c LF |
832 | |
833 | /* */ | |
834 | /* Config BB and AGC */ | |
835 | /* */ | |
836 | rtStatus = phy_BB8723a_Config_ParaFile(Adapter); | |
837 | ||
838 | /* only for B-cut */ | |
839 | if (pHalData->EEPROMVersion >= 0x01) { | |
840 | CrystalCap = pHalData->CrystalCap & 0x3F; | |
841 | PHY_SetBBReg(Adapter, REG_MAC_PHY_CTRL, 0xFFF000, | |
842 | (CrystalCap | (CrystalCap << 6))); | |
843 | } | |
844 | ||
845 | PHY_SetBBReg(Adapter, REG_LDOA15_CTRL, bMaskDWord, 0x01572505); | |
846 | return rtStatus; | |
847 | } | |
848 | ||
849 | int | |
850 | PHY_RFConfig8723A(struct rtw_adapter *Adapter) | |
851 | { | |
852 | int rtStatus = _SUCCESS; | |
853 | ||
854 | /* */ | |
855 | /* RF config */ | |
856 | /* */ | |
857 | rtStatus = PHY_RF6052_Config8723A(Adapter); | |
858 | return rtStatus; | |
859 | } | |
860 | ||
861 | static void getTxPowerIndex(struct rtw_adapter *Adapter, | |
862 | u8 channel, u8 *cckPowerLevel, u8 *ofdmPowerLevel) | |
863 | { | |
864 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | |
865 | u8 index = (channel - 1); | |
866 | /* 1. CCK */ | |
867 | cckPowerLevel[RF_PATH_A] = pHalData->TxPwrLevelCck[RF_PATH_A][index]; | |
868 | cckPowerLevel[RF_PATH_B] = pHalData->TxPwrLevelCck[RF_PATH_B][index]; | |
869 | ||
870 | /* 2. OFDM for 1S or 2S */ | |
871 | if (GET_RF_TYPE(Adapter) == RF_1T2R || GET_RF_TYPE(Adapter) == RF_1T1R) { | |
872 | /* Read HT 40 OFDM TX power */ | |
873 | ofdmPowerLevel[RF_PATH_A] = | |
874 | pHalData->TxPwrLevelHT40_1S[RF_PATH_A][index]; | |
875 | ofdmPowerLevel[RF_PATH_B] = | |
876 | pHalData->TxPwrLevelHT40_1S[RF_PATH_B][index]; | |
877 | } else if (GET_RF_TYPE(Adapter) == RF_2T2R) { | |
878 | /* Read HT 40 OFDM TX power */ | |
879 | ofdmPowerLevel[RF_PATH_A] = | |
880 | pHalData->TxPwrLevelHT40_2S[RF_PATH_A][index]; | |
881 | ofdmPowerLevel[RF_PATH_B] = | |
882 | pHalData->TxPwrLevelHT40_2S[RF_PATH_B][index]; | |
883 | } | |
884 | } | |
885 | ||
886 | static void ccxPowerIndexCheck(struct rtw_adapter *Adapter, u8 channel, | |
887 | u8 *cckPowerLevel, u8 *ofdmPowerLevel) | |
888 | { | |
889 | } | |
890 | ||
891 | /*----------------------------------------------------------------------------- | |
892 | * Function: SetTxPowerLevel8723A() | |
893 | * | |
894 | * Overview: This function is export to "HalCommon" moudule | |
895 | * We must consider RF path later!!!!!!! | |
896 | * | |
897 | * Input: struct rtw_adapter * Adapter | |
898 | * u8 channel | |
899 | * | |
900 | * Output: NONE | |
901 | * | |
902 | * Return: NONE | |
903 | * | |
904 | *---------------------------------------------------------------------------*/ | |
905 | void PHY_SetTxPowerLevel8723A(struct rtw_adapter *Adapter, u8 channel) | |
906 | { | |
907 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | |
908 | u8 cckPowerLevel[2], ofdmPowerLevel[2]; /* [0]:RF-A, [1]:RF-B */ | |
909 | ||
910 | if (pHalData->bTXPowerDataReadFromEEPORM == false) | |
911 | return; | |
912 | ||
913 | getTxPowerIndex(Adapter, channel, &cckPowerLevel[0], | |
914 | &ofdmPowerLevel[0]); | |
915 | ||
916 | ccxPowerIndexCheck(Adapter, channel, &cckPowerLevel[0], | |
917 | &ofdmPowerLevel[0]); | |
918 | ||
919 | rtl823a_phy_rf6052setccktxpower(Adapter, &cckPowerLevel[0]); | |
920 | rtl8723a_PHY_RF6052SetOFDMTxPower(Adapter, &ofdmPowerLevel[0], channel); | |
921 | } | |
922 | ||
923 | /*----------------------------------------------------------------------------- | |
924 | * Function: PHY_SetBWMode23aCallback8192C() | |
925 | * | |
926 | * Overview: Timer callback function for SetSetBWMode23a | |
927 | * | |
928 | * Input: PRT_TIMER pTimer | |
929 | * | |
930 | * Output: NONE | |
931 | * | |
932 | * Return: NONE | |
933 | * | |
934 | * Note: | |
935 | * (1) We do not take j mode into consideration now | |
936 | * (2) Will two workitem of "switch channel" and | |
937 | * "switch channel bandwidth" run concurrently? | |
938 | *---------------------------------------------------------------------------*/ | |
939 | static void | |
940 | _PHY_SetBWMode23a92C(struct rtw_adapter *Adapter) | |
941 | { | |
942 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | |
943 | u8 regBwOpMode; | |
944 | u8 regRRSR_RSC; | |
945 | ||
946 | if (pHalData->rf_chip == RF_PSEUDO_11N) | |
947 | return; | |
948 | ||
949 | /* There is no 40MHz mode in RF_8225. */ | |
950 | if (pHalData->rf_chip == RF_8225) | |
951 | return; | |
952 | ||
953 | if (Adapter->bDriverStopped) | |
954 | return; | |
955 | ||
956 | /* 3 */ | |
957 | /* 3<1>Set MAC register */ | |
958 | /* 3 */ | |
959 | ||
050abc45 JS |
960 | regBwOpMode = rtl8723au_read8(Adapter, REG_BWOPMODE); |
961 | regRRSR_RSC = rtl8723au_read8(Adapter, REG_RRSR+2); | |
f7c92d2c LF |
962 | |
963 | switch (pHalData->CurrentChannelBW) { | |
964 | case HT_CHANNEL_WIDTH_20: | |
965 | regBwOpMode |= BW_OPMODE_20MHZ; | |
edbfd672 | 966 | rtl8723au_write8(Adapter, REG_BWOPMODE, regBwOpMode); |
f7c92d2c LF |
967 | break; |
968 | case HT_CHANNEL_WIDTH_40: | |
969 | regBwOpMode &= ~BW_OPMODE_20MHZ; | |
edbfd672 | 970 | rtl8723au_write8(Adapter, REG_BWOPMODE, regBwOpMode); |
f7c92d2c LF |
971 | regRRSR_RSC = (regRRSR_RSC & 0x90) | |
972 | (pHalData->nCur40MhzPrimeSC << 5); | |
edbfd672 | 973 | rtl8723au_write8(Adapter, REG_RRSR+2, regRRSR_RSC); |
f7c92d2c LF |
974 | break; |
975 | ||
976 | default: | |
977 | break; | |
978 | } | |
979 | ||
980 | /* 3 */ | |
981 | /* 3<2>Set PHY related register */ | |
982 | /* 3 */ | |
983 | switch (pHalData->CurrentChannelBW) { | |
984 | /* 20 MHz channel*/ | |
985 | case HT_CHANNEL_WIDTH_20: | |
986 | PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0); | |
987 | PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0); | |
8f7654c1 | 988 | PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT(10), 1); |
f7c92d2c LF |
989 | |
990 | break; | |
991 | ||
992 | /* 40 MHz channel*/ | |
993 | case HT_CHANNEL_WIDTH_40: | |
994 | PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1); | |
995 | PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1); | |
996 | ||
997 | /* Set Control channel to upper or lower. These settings | |
998 | are required only for 40MHz */ | |
999 | PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand, | |
1000 | (pHalData->nCur40MhzPrimeSC >> 1)); | |
1001 | PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00, | |
1002 | pHalData->nCur40MhzPrimeSC); | |
8f7654c1 | 1003 | PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT(10), 0); |
f7c92d2c | 1004 | |
8f7654c1 | 1005 | PHY_SetBBReg(Adapter, 0x818, BIT(26) | BIT(27), |
f7c92d2c LF |
1006 | (pHalData->nCur40MhzPrimeSC == |
1007 | HAL_PRIME_CHNL_OFFSET_LOWER) ? 2:1); | |
1008 | break; | |
1009 | ||
1010 | default: | |
1011 | /*RT_TRACE(COMP_DBG, DBG_LOUD, | |
1012 | ("PHY_SetBWMode23aCallback8192C(): unknown Bandwidth: %#X\n" \ | |
1013 | , pHalData->CurrentChannelBW));*/ | |
1014 | break; | |
1015 | } | |
1016 | /* Skip over setting of J-mode in BB register here. Default value | |
1017 | is "None J mode". Emily 20070315 */ | |
1018 | ||
1019 | /* Added it for 20/40 mhz switch time evaluation by guangan 070531 */ | |
1020 | /* NowL = PlatformEFIORead4Byte(Adapter, TSFR); */ | |
1021 | /* NowH = PlatformEFIORead4Byte(Adapter, TSFR+4); */ | |
1022 | /* EndTime = ((u64)NowH << 32) + NowL; */ | |
1023 | /* RT_TRACE(COMP_SCAN, DBG_LOUD, ("SetBWMode23aCallback8190Pci: time | |
1024 | of SetBWMode23a = %I64d us!\n", (EndTime - BeginTime))); */ | |
1025 | ||
1026 | /* 3<3>Set RF related register */ | |
1027 | switch (pHalData->rf_chip) { | |
1028 | case RF_8225: | |
1029 | /* PHY_SetRF8225Bandwidth(Adapter, | |
1030 | pHalData->CurrentChannelBW); */ | |
1031 | break; | |
1032 | ||
1033 | case RF_8256: | |
1034 | /* Please implement this function in Hal8190PciPhy8256.c */ | |
1035 | /* PHY_SetRF8256Bandwidth(Adapter, | |
1036 | pHalData->CurrentChannelBW); */ | |
1037 | break; | |
1038 | ||
1039 | case RF_8258: | |
1040 | /* Please implement this function in Hal8190PciPhy8258.c */ | |
1041 | /* PHY_SetRF8258Bandwidth(); */ | |
1042 | break; | |
1043 | ||
1044 | case RF_PSEUDO_11N: | |
1045 | /* Do Nothing */ | |
1046 | break; | |
1047 | ||
1048 | case RF_6052: | |
1049 | rtl8723a_phy_rf6052set_bw(Adapter, pHalData->CurrentChannelBW); | |
1050 | break; | |
1051 | ||
1052 | default: | |
1053 | /* RT_ASSERT(false, ("Unknown RFChipID: %d\n", | |
1054 | pHalData->RFChipID)); */ | |
1055 | break; | |
1056 | } | |
1057 | ||
1058 | /* pHalData->SetBWMode23aInProgress = false; */ | |
1059 | ||
1060 | /* RT_TRACE(COMP_SCAN, DBG_LOUD, | |
1061 | ("<== PHY_SetBWMode23aCallback8192C() \n")); */ | |
1062 | } | |
1063 | ||
1064 | /*----------------------------------------------------------------------------- | |
1065 | * Function: SetBWMode23a8190Pci() | |
1066 | * | |
1067 | * Overview: This function is export to "HalCommon" moudule | |
1068 | * | |
1069 | * Input: struct rtw_adapter * Adapter | |
1070 | * enum ht_channel_width Bandwidth 20M or 40M | |
1071 | * | |
1072 | * Output: NONE | |
1073 | * | |
1074 | * Return: NONE | |
1075 | * | |
1076 | * Note: We do not take j mode into consideration now | |
1077 | *---------------------------------------------------------------------------*/ | |
1078 | void | |
1079 | PHY_SetBWMode23a8723A(struct rtw_adapter *Adapter, | |
1080 | enum ht_channel_width Bandwidth, unsigned char Offset) | |
1081 | { | |
1082 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | |
1083 | enum ht_channel_width tmpBW = pHalData->CurrentChannelBW; | |
1084 | ||
1085 | pHalData->CurrentChannelBW = Bandwidth; | |
1086 | ||
1087 | pHalData->nCur40MhzPrimeSC = Offset; | |
1088 | ||
1089 | if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) | |
1090 | _PHY_SetBWMode23a92C(Adapter); | |
1091 | else | |
1092 | pHalData->CurrentChannelBW = tmpBW; | |
1093 | } | |
1094 | ||
1095 | static void _PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel) | |
1096 | { | |
1097 | u8 eRFPath; | |
1098 | u32 param1, param2; | |
1099 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | |
1100 | ||
f7c92d2c LF |
1101 | /* s1. pre common command - CmdID_SetTxPowerLevel */ |
1102 | PHY_SetTxPowerLevel8723A(Adapter, channel); | |
1103 | ||
1104 | /* s2. RF dependent command - CmdID_RF_WriteReg, | |
1105 | param1 = RF_CHNLBW, param2 = channel */ | |
1106 | param1 = RF_CHNLBW; | |
1107 | param2 = channel; | |
1108 | for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) { | |
1109 | pHalData->RfRegChnlVal[eRFPath] = | |
1110 | (pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | param2; | |
1111 | PHY_SetRFReg(Adapter, (enum RF_RADIO_PATH)eRFPath, param1, | |
1112 | bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]); | |
1113 | } | |
1114 | ||
1115 | /* s3. post common command - CmdID_End, None */ | |
1116 | } | |
1117 | ||
1118 | void PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel) | |
1119 | { | |
1120 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | |
1121 | u8 tmpchannel = pHalData->CurrentChannel; | |
1122 | bool result = true; | |
1123 | ||
1124 | if (pHalData->rf_chip == RF_PSEUDO_11N) { | |
1125 | /* return immediately if it is peudo-phy */ | |
1126 | return; | |
1127 | } | |
1128 | ||
1129 | if (channel == 0) | |
1130 | channel = 1; | |
1131 | ||
1132 | pHalData->CurrentChannel = channel; | |
1133 | ||
1134 | if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) { | |
1135 | _PHY_SwChnl8723A(Adapter, channel); | |
1136 | ||
1137 | if (!result) | |
1138 | pHalData->CurrentChannel = tmpchannel; | |
1139 | } else { | |
1140 | pHalData->CurrentChannel = tmpchannel; | |
1141 | } | |
1142 | } |