1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3 *
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 *
6 ******************************************************************************/
7 #define _RTL8723B_PHYCFG_C_
8
9 #include <drv_types.h>
10 #include <rtw_debug.h>
11 #include <rtl8723b_hal.h>
12
13
14 /*---------------------------Define Local Constant---------------------------*/
15 /* Channel switch:The size of command tables for switch channel*/
16 #define MAX_PRECMD_CNT 16
17 #define MAX_RFDEPENDCMD_CNT 16
18 #define MAX_POSTCMD_CNT 16
19
20 #define MAX_DOZE_WAITING_TIMES_9x 64
21
22 /**
23 * phy_CalculateBitShift - Get shifted position of the BitMask.
24 * @BitMask: Bitmask.
25 *
26 * Return: Return the shift bit position of the mask
27 */
phy_CalculateBitShift(u32 BitMask)28 static u32 phy_CalculateBitShift(u32 BitMask)
29 {
30 u32 i;
31
32 for (i = 0; i <= 31; i++) {
33 if (((BitMask>>i) & 0x1) == 1)
34 break;
35 }
36 return i;
37 }
38
39
40 /**
41 * PHY_QueryBBReg - Read "specific bits" from BB register.
42 * @Adapter:
43 * @RegAddr: The target address to be readback
44 * @BitMask: The target bit position in the target address
45 * to be readback
46 *
47 * Return: The readback register value
48 *
49 * .. Note:: This function is equal to "GetRegSetting" in PHY programming
50 * guide
51 */
PHY_QueryBBReg_8723B(struct adapter * Adapter,u32 RegAddr,u32 BitMask)52 u32 PHY_QueryBBReg_8723B(struct adapter *Adapter, u32 RegAddr, u32 BitMask)
53 {
54 u32 OriginalValue, BitShift;
55
56 #if (DISABLE_BB_RF == 1)
57 return 0;
58 #endif
59
60 OriginalValue = rtw_read32(Adapter, RegAddr);
61 BitShift = phy_CalculateBitShift(BitMask);
62
63 return (OriginalValue & BitMask) >> BitShift;
64
65 }
66
67
68 /**
69 * PHY_SetBBReg - Write "Specific bits" to BB register (page 8~).
70 * @Adapter:
71 * @RegAddr: The target address to be modified
72 * @BitMask: The target bit position in the target address
73 * to be modified
74 * @Data: The new register value in the target bit position
75 * of the target address
76 *
77 * .. Note:: This function is equal to "PutRegSetting" in PHY programming
78 * guide
79 */
80
PHY_SetBBReg_8723B(struct adapter * Adapter,u32 RegAddr,u32 BitMask,u32 Data)81 void PHY_SetBBReg_8723B(
82 struct adapter *Adapter,
83 u32 RegAddr,
84 u32 BitMask,
85 u32 Data
86 )
87 {
88 /* u16 BBWaitCounter = 0; */
89 u32 OriginalValue, BitShift;
90
91 #if (DISABLE_BB_RF == 1)
92 return;
93 #endif
94
95 if (BitMask != bMaskDWord) { /* if not "double word" write */
96 OriginalValue = rtw_read32(Adapter, RegAddr);
97 BitShift = phy_CalculateBitShift(BitMask);
98 Data = ((OriginalValue & (~BitMask)) | ((Data << BitShift) & BitMask));
99 }
100
101 rtw_write32(Adapter, RegAddr, Data);
102
103 }
104
105
106 /* */
107 /* 2. RF register R/W API */
108 /* */
109
phy_RFSerialRead_8723B(struct adapter * Adapter,enum rf_path eRFPath,u32 Offset)110 static u32 phy_RFSerialRead_8723B(
111 struct adapter *Adapter, enum rf_path eRFPath, u32 Offset
112 )
113 {
114 u32 retValue = 0;
115 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
116 struct bb_register_def *pPhyReg = &pHalData->PHYRegDef[eRFPath];
117 u32 NewOffset;
118 u32 tmplong2;
119 u8 RfPiEnable = 0;
120 u32 MaskforPhySet = 0;
121 int i = 0;
122
123 /* */
124 /* Make sure RF register offset is correct */
125 /* */
126 Offset &= 0xff;
127
128 NewOffset = Offset;
129
130 if (eRFPath == RF_PATH_A) {
131 tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord);
132 tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset<<23) | bLSSIReadEdge; /* T65 RF */
133 PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2&(~bLSSIReadEdge));
134 } else {
135 tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XB_HSSIParameter2|MaskforPhySet, bMaskDWord);
136 tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset<<23) | bLSSIReadEdge; /* T65 RF */
137 PHY_SetBBReg(Adapter, rFPGA0_XB_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2&(~bLSSIReadEdge));
138 }
139
140 tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord);
141 PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2 & (~bLSSIReadEdge));
142 PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2 | bLSSIReadEdge);
143
144 udelay(10);
145
146 for (i = 0; i < 2; i++)
147 udelay(MAX_STALL_TIME);
148 udelay(10);
149
150 if (eRFPath == RF_PATH_A)
151 RfPiEnable = (u8)PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter1|MaskforPhySet, BIT8);
152 else if (eRFPath == RF_PATH_B)
153 RfPiEnable = (u8)PHY_QueryBBReg(Adapter, rFPGA0_XB_HSSIParameter1|MaskforPhySet, BIT8);
154
155 if (RfPiEnable) {
156 /* Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */
157 retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi|MaskforPhySet, bLSSIReadBackData);
158 } else {
159 /* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */
160 retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack|MaskforPhySet, bLSSIReadBackData);
161 }
162 return retValue;
163
164 }
165
166 /**
167 * phy_RFSerialWrite_8723B - Write data to RF register (page 8~).
168 * @Adapter:
169 * @eRFPath: Radio path of A/B/C/D
170 * @Offset: The target address to be read
171 * @Data: The new register Data in the target bit position
172 * of the target to be read
173 *
174 * .. Note:: Threre are three types of serial operations:
175 * 1. Software serial write
176 * 2. Hardware LSSI-Low Speed Serial Interface
177 * 3. Hardware HSSI-High speed
178 * serial write. Driver need to implement (1) and (2).
179 * This function is equal to the combination of RF_ReadReg() and RFLSSIRead()
180 *
181 * .. Note:: For RF8256 only
182 * The total count of RTL8256(Zebra4) register is around 36 bit it only employs
183 * 4-bit RF address. RTL8256 uses "register mode control bit" (Reg00[12], Reg00[10])
184 * to access register address bigger than 0xf. See "Appendix-4 in PHY Configuration
185 * programming guide" for more details.
186 * Thus, we define a sub-finction for RTL8526 register address conversion
187 * ===========================================================
188 * Register Mode RegCTL[1] RegCTL[0] Note
189 * (Reg00[12]) (Reg00[10])
190 * ===========================================================
191 * Reg_Mode0 0 x Reg 0 ~15(0x0 ~ 0xf)
192 * ------------------------------------------------------------------
193 * Reg_Mode1 1 0 Reg 16 ~30(0x1 ~ 0xf)
194 * ------------------------------------------------------------------
195 * Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf)
196 * ------------------------------------------------------------------
197 *
198 *2008/09/02 MH Add 92S RF definition
199 *
200 *
201 *
202 */
phy_RFSerialWrite_8723B(struct adapter * Adapter,enum rf_path eRFPath,u32 Offset,u32 Data)203 static void phy_RFSerialWrite_8723B(
204 struct adapter *Adapter,
205 enum rf_path eRFPath,
206 u32 Offset,
207 u32 Data
208 )
209 {
210 u32 DataAndAddr = 0;
211 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
212 struct bb_register_def *pPhyReg = &pHalData->PHYRegDef[eRFPath];
213 u32 NewOffset;
214
215 Offset &= 0xff;
216
217 /* */
218 /* Switch page for 8256 RF IC */
219 /* */
220 NewOffset = Offset;
221
222 /* */
223 /* Put write addr in [5:0] and write data in [31:16] */
224 /* */
225 DataAndAddr = ((NewOffset<<20) | (Data&0x000fffff)) & 0x0fffffff; /* T65 RF */
226 /* */
227 /* Write Operation */
228 /* */
229 PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
230 }
231
232
233 /**
234 * PHY_QueryRFReg - Query "Specific bits" to RF register (page 8~).
235 * @Adapter:
236 * @eRFPath: Radio path of A/B/C/D
237 * @RegAdd: The target address to be read
238 * @BitMask: The target bit position in the target address
239 * to be read
240 *
241 * Return: Readback value
242 *
243 * .. Note:: This function is equal to "GetRFRegSetting" in PHY
244 * programming guide
245 */
PHY_QueryRFReg_8723B(struct adapter * Adapter,u8 eRFPath,u32 RegAddr,u32 BitMask)246 u32 PHY_QueryRFReg_8723B(
247 struct adapter *Adapter,
248 u8 eRFPath,
249 u32 RegAddr,
250 u32 BitMask
251 )
252 {
253 u32 Original_Value, BitShift;
254
255 #if (DISABLE_BB_RF == 1)
256 return 0;
257 #endif
258
259 Original_Value = phy_RFSerialRead_8723B(Adapter, eRFPath, RegAddr);
260 BitShift = phy_CalculateBitShift(BitMask);
261
262 return (Original_Value & BitMask) >> BitShift;
263 }
264
265 /**
266 * PHY_SetRFReg - Write "Specific bits" to RF register (page 8~).
267 * @Adapter:
268 * @eRFPath: Radio path of A/B/C/D
269 * @RegAddr: The target address to be modified
270 * @BitMask: The target bit position in the target address
271 * to be modified
272 * @Data: The new register Data in the target bit position
273 * of the target address
274 *
275 * .. Note:: This function is equal to "PutRFRegSetting" in PHY
276 * programming guide.
277 */
PHY_SetRFReg_8723B(struct adapter * Adapter,u8 eRFPath,u32 RegAddr,u32 BitMask,u32 Data)278 void PHY_SetRFReg_8723B(
279 struct adapter *Adapter,
280 u8 eRFPath,
281 u32 RegAddr,
282 u32 BitMask,
283 u32 Data
284 )
285 {
286 u32 Original_Value, BitShift;
287
288 #if (DISABLE_BB_RF == 1)
289 return;
290 #endif
291
292 /* RF data is 12 bits only */
293 if (BitMask != bRFRegOffsetMask) {
294 Original_Value = phy_RFSerialRead_8723B(Adapter, eRFPath, RegAddr);
295 BitShift = phy_CalculateBitShift(BitMask);
296 Data = ((Original_Value & (~BitMask)) | (Data<<BitShift));
297 }
298
299 phy_RFSerialWrite_8723B(Adapter, eRFPath, RegAddr, Data);
300 }
301
302
303 /* */
304 /* 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */
305 /* */
306
307
308 /*-----------------------------------------------------------------------------
309 * PHY_MACConfig8192C - Condig MAC by header file or parameter file.
310 *
311 * Revised History:
312 * When Who Remark
313 * 08/12/2008 MHC Create Version 0.
314 *
315 *---------------------------------------------------------------------------
316 */
PHY_MACConfig8723B(struct adapter * Adapter)317 s32 PHY_MACConfig8723B(struct adapter *Adapter)
318 {
319 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
320
321 ODM_ReadAndConfig_MP_8723B_MAC_REG(&pHalData->odmpriv);
322 return _SUCCESS;
323 }
324
325 /**
326 * phy_InitBBRFRegisterDefinition - Initialize Register definition offset for
327 * Radio Path A/B/C/D
328 * @Adapter:
329 *
330 * .. Note:: The initialization value is constant and it should never be changes
331 */
phy_InitBBRFRegisterDefinition(struct adapter * Adapter)332 static void phy_InitBBRFRegisterDefinition(struct adapter *Adapter)
333 {
334 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
335
336 /* RF Interface Sowrtware Control */
337 pHalData->PHYRegDef[ODM_RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; /* 16 LSBs if read 32-bit from 0x870 */
338 pHalData->PHYRegDef[ODM_RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */
339
340 /* RF Interface Output (and Enable) */
341 pHalData->PHYRegDef[ODM_RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; /* 16 LSBs if read 32-bit from 0x860 */
342 pHalData->PHYRegDef[ODM_RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; /* 16 LSBs if read 32-bit from 0x864 */
343
344 /* RF Interface (Output and) Enable */
345 pHalData->PHYRegDef[ODM_RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
346 pHalData->PHYRegDef[ODM_RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */
347
348 pHalData->PHYRegDef[ODM_RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; /* LSSI Parameter */
349 pHalData->PHYRegDef[ODM_RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
350
351 pHalData->PHYRegDef[ODM_RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; /* wire control parameter2 */
352 pHalData->PHYRegDef[ODM_RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; /* wire control parameter2 */
353
354 /* Tranceiver Readback LSSI/HSPI mode */
355 pHalData->PHYRegDef[ODM_RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
356 pHalData->PHYRegDef[ODM_RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
357 pHalData->PHYRegDef[ODM_RF_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback;
358 pHalData->PHYRegDef[ODM_RF_PATH_B].rfLSSIReadBackPi = TransceiverB_HSPI_Readback;
359
360 }
361
phy_BB8723b_Config_ParaFile(struct adapter * Adapter)362 static int phy_BB8723b_Config_ParaFile(struct adapter *Adapter)
363 {
364 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
365
366 /* Read Tx Power Limit File */
367 PHY_InitTxPowerLimit(Adapter);
368 if (
369 Adapter->registrypriv.RegEnableTxPowerLimit == 1 ||
370 (Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory == 1)
371 ) {
372 ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv,
373 CONFIG_RF_TXPWR_LMT, 0);
374 }
375
376 /* */
377 /* 1. Read PHY_REG.TXT BB INIT!! */
378 /* */
379 ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG);
380
381 /* If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */
382 PHY_InitTxPowerByRate(Adapter);
383 if (
384 Adapter->registrypriv.RegEnableTxPowerByRate == 1 ||
385 (Adapter->registrypriv.RegEnableTxPowerByRate == 2 && pHalData->EEPROMRegulatory != 2)
386 ) {
387 ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv,
388 CONFIG_BB_PHY_REG_PG);
389
390 if (pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE)
391 PHY_TxPowerByRateConfiguration(Adapter);
392
393 if (
394 Adapter->registrypriv.RegEnableTxPowerLimit == 1 ||
395 (Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory == 1)
396 )
397 PHY_ConvertTxPowerLimitToPowerIndex(Adapter);
398 }
399
400 /* */
401 /* 2. Read BB AGC table Initialization */
402 /* */
403 ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_AGC_TAB);
404
405 return _SUCCESS;
406 }
407
408
PHY_BBConfig8723B(struct adapter * Adapter)409 int PHY_BBConfig8723B(struct adapter *Adapter)
410 {
411 int rtStatus = _SUCCESS;
412 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
413 u32 RegVal;
414 u8 CrystalCap;
415
416 phy_InitBBRFRegisterDefinition(Adapter);
417
418 /* Enable BB and RF */
419 RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
420 rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal|BIT13|BIT0|BIT1));
421
422 rtw_write32(Adapter, 0x948, 0x280); /* Others use Antenna S1 */
423
424 rtw_write8(Adapter, REG_RF_CTRL, RF_EN|RF_RSTB|RF_SDMRSTB);
425
426 msleep(1);
427
428 PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x1, 0xfffff, 0x780);
429
430 rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_PPLL|FEN_PCIEA|FEN_DIO_PCIE|FEN_BB_GLB_RSTn|FEN_BBRSTB);
431
432 rtw_write8(Adapter, REG_AFE_XTAL_CTRL+1, 0x80);
433
434 /* */
435 /* Config BB and AGC */
436 /* */
437 rtStatus = phy_BB8723b_Config_ParaFile(Adapter);
438
439 /* 0x2C[23:18] = 0x2C[17:12] = CrystalCap */
440 CrystalCap = pHalData->CrystalCap & 0x3F;
441 PHY_SetBBReg(Adapter, REG_MAC_PHY_CTRL, 0xFFF000, (CrystalCap | (CrystalCap << 6)));
442
443 return rtStatus;
444 }
445
phy_LCK_8723B(struct adapter * Adapter)446 static void phy_LCK_8723B(struct adapter *Adapter)
447 {
448 PHY_SetRFReg(Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFBE0);
449 PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, 0x8C01);
450 mdelay(200);
451 PHY_SetRFReg(Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFFE0);
452 }
453
PHY_RFConfig8723B(struct adapter * Adapter)454 int PHY_RFConfig8723B(struct adapter *Adapter)
455 {
456 int rtStatus = _SUCCESS;
457
458 /* */
459 /* RF config */
460 /* */
461 rtStatus = PHY_RF6052_Config8723B(Adapter);
462
463 phy_LCK_8723B(Adapter);
464
465 return rtStatus;
466 }
467
468 /**************************************************************************************************************
469 * Description:
470 * The low-level interface to set TxAGC , called by both MP and Normal Driver.
471 *
472 * <20120830, Kordan>
473 **************************************************************************************************************/
474
PHY_SetTxPowerIndex(struct adapter * Adapter,u32 PowerIndex,u8 RFPath,u8 Rate)475 void PHY_SetTxPowerIndex(
476 struct adapter *Adapter,
477 u32 PowerIndex,
478 u8 RFPath,
479 u8 Rate
480 )
481 {
482 if (RFPath == ODM_RF_PATH_A || RFPath == ODM_RF_PATH_B) {
483 switch (Rate) {
484 case MGN_1M:
485 PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, PowerIndex);
486 break;
487 case MGN_2M:
488 PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte1, PowerIndex);
489 break;
490 case MGN_5_5M:
491 PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte2, PowerIndex);
492 break;
493 case MGN_11M:
494 PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte3, PowerIndex);
495 break;
496
497 case MGN_6M:
498 PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte0, PowerIndex);
499 break;
500 case MGN_9M:
501 PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte1, PowerIndex);
502 break;
503 case MGN_12M:
504 PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte2, PowerIndex);
505 break;
506 case MGN_18M:
507 PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte3, PowerIndex);
508 break;
509
510 case MGN_24M:
511 PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte0, PowerIndex);
512 break;
513 case MGN_36M:
514 PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte1, PowerIndex);
515 break;
516 case MGN_48M:
517 PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte2, PowerIndex);
518 break;
519 case MGN_54M:
520 PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte3, PowerIndex);
521 break;
522
523 case MGN_MCS0:
524 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte0, PowerIndex);
525 break;
526 case MGN_MCS1:
527 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte1, PowerIndex);
528 break;
529 case MGN_MCS2:
530 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte2, PowerIndex);
531 break;
532 case MGN_MCS3:
533 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte3, PowerIndex);
534 break;
535
536 case MGN_MCS4:
537 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte0, PowerIndex);
538 break;
539 case MGN_MCS5:
540 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte1, PowerIndex);
541 break;
542 case MGN_MCS6:
543 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte2, PowerIndex);
544 break;
545 case MGN_MCS7:
546 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte3, PowerIndex);
547 break;
548
549 default:
550 break;
551 }
552 }
553 }
554
PHY_GetTxPowerIndex(struct adapter * padapter,u8 RFPath,u8 Rate,enum channel_width BandWidth,u8 Channel)555 u8 PHY_GetTxPowerIndex(
556 struct adapter *padapter,
557 u8 RFPath,
558 u8 Rate,
559 enum channel_width BandWidth,
560 u8 Channel
561 )
562 {
563 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
564 s8 txPower = 0, powerDiffByRate = 0, limit = 0;
565 bool bIn24G = false;
566
567 txPower = (s8) PHY_GetTxPowerIndexBase(padapter, RFPath, Rate, BandWidth, Channel, &bIn24G);
568 powerDiffByRate = PHY_GetTxPowerByRate(padapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_1TX, Rate);
569
570 limit = phy_get_tx_pwr_lmt(
571 padapter,
572 padapter->registrypriv.RegPwrTblSel,
573 (u8)(!bIn24G),
574 pHalData->CurrentChannelBW,
575 RFPath,
576 Rate,
577 pHalData->CurrentChannel
578 );
579
580 powerDiffByRate = powerDiffByRate > limit ? limit : powerDiffByRate;
581 txPower += powerDiffByRate;
582
583 txPower += PHY_GetTxPowerTrackingOffset(padapter, RFPath, Rate);
584
585 if (txPower > MAX_POWER_INDEX)
586 txPower = MAX_POWER_INDEX;
587
588 return (u8) txPower;
589 }
590
PHY_SetTxPowerLevel8723B(struct adapter * Adapter,u8 Channel)591 void PHY_SetTxPowerLevel8723B(struct adapter *Adapter, u8 Channel)
592 {
593 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
594 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
595 struct fat_t *pDM_FatTable = &pDM_Odm->DM_FatTable;
596 u8 RFPath = ODM_RF_PATH_A;
597
598 if (pHalData->AntDivCfg) {/* antenna diversity Enable */
599 RFPath = ((pDM_FatTable->RxIdleAnt == MAIN_ANT) ? ODM_RF_PATH_A : ODM_RF_PATH_B);
600 } else { /* antenna diversity disable */
601 RFPath = pHalData->ant_path;
602 }
603
604 PHY_SetTxPowerLevelByPath(Adapter, Channel, RFPath);
605 }
606
PHY_GetTxPowerLevel8723B(struct adapter * Adapter,s32 * powerlevel)607 void PHY_GetTxPowerLevel8723B(struct adapter *Adapter, s32 *powerlevel)
608 {
609 }
610
phy_SetRegBW_8723B(struct adapter * Adapter,enum channel_width CurrentBW)611 static void phy_SetRegBW_8723B(
612 struct adapter *Adapter, enum channel_width CurrentBW
613 )
614 {
615 u16 RegRfMod_BW, u2tmp = 0;
616 RegRfMod_BW = rtw_read16(Adapter, REG_TRXPTCL_CTL_8723B);
617
618 switch (CurrentBW) {
619 case CHANNEL_WIDTH_20:
620 rtw_write16(Adapter, REG_TRXPTCL_CTL_8723B, (RegRfMod_BW & 0xFE7F)); /* BIT 7 = 0, BIT 8 = 0 */
621 break;
622
623 case CHANNEL_WIDTH_40:
624 u2tmp = RegRfMod_BW | BIT7;
625 rtw_write16(Adapter, REG_TRXPTCL_CTL_8723B, (u2tmp & 0xFEFF)); /* BIT 7 = 1, BIT 8 = 0 */
626 break;
627
628 case CHANNEL_WIDTH_80:
629 u2tmp = RegRfMod_BW | BIT8;
630 rtw_write16(Adapter, REG_TRXPTCL_CTL_8723B, (u2tmp & 0xFF7F)); /* BIT 7 = 0, BIT 8 = 1 */
631 break;
632
633 default:
634 break;
635 }
636 }
637
phy_GetSecondaryChnl_8723B(struct adapter * Adapter)638 static u8 phy_GetSecondaryChnl_8723B(struct adapter *Adapter)
639 {
640 u8 SCSettingOf40 = 0, SCSettingOf20 = 0;
641 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
642
643 if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_80) {
644 if (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
645 SCSettingOf40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
646 else if (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
647 SCSettingOf40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
648
649 if (
650 (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) &&
651 (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
652 )
653 SCSettingOf20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
654 else if (
655 (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) &&
656 (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
657 )
658 SCSettingOf20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
659 else if (
660 (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) &&
661 (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
662 )
663 SCSettingOf20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
664 else if (
665 (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) &&
666 (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
667 )
668 SCSettingOf20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
669 } else if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40) {
670 if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
671 SCSettingOf20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
672 else if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
673 SCSettingOf20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
674 }
675
676 return (SCSettingOf40 << 4) | SCSettingOf20;
677 }
678
phy_PostSetBwMode8723B(struct adapter * Adapter)679 static void phy_PostSetBwMode8723B(struct adapter *Adapter)
680 {
681 u8 SubChnlNum = 0;
682 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
683
684
685 /* 3 Set Reg668 Reg440 BW */
686 phy_SetRegBW_8723B(Adapter, pHalData->CurrentChannelBW);
687
688 /* 3 Set Reg483 */
689 SubChnlNum = phy_GetSecondaryChnl_8723B(Adapter);
690 rtw_write8(Adapter, REG_DATA_SC_8723B, SubChnlNum);
691
692 /* 3 */
693 /* 3<2>Set PHY related register */
694 /* 3 */
695 switch (pHalData->CurrentChannelBW) {
696 /* 20 MHz channel*/
697 case CHANNEL_WIDTH_20:
698 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
699
700 PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
701
702 PHY_SetBBReg(Adapter, rOFDM0_TxPseudoNoiseWgt, (BIT31|BIT30), 0x0);
703 break;
704
705 /* 40 MHz channel*/
706 case CHANNEL_WIDTH_40:
707 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
708
709 PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
710
711 /* Set Control channel to upper or lower. These settings are required only for 40MHz */
712 PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand, (pHalData->nCur40MhzPrimeSC>>1));
713
714 PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00, pHalData->nCur40MhzPrimeSC);
715
716 PHY_SetBBReg(Adapter, 0x818, (BIT26|BIT27), (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
717 break;
718 default:
719 break;
720 }
721
722 /* 3<3>Set RF related register */
723 PHY_RF6052SetBandwidth8723B(Adapter, pHalData->CurrentChannelBW);
724 }
725
phy_SwChnl8723B(struct adapter * padapter)726 static void phy_SwChnl8723B(struct adapter *padapter)
727 {
728 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
729 u8 channelToSW = pHalData->CurrentChannel;
730
731 if (pHalData->rf_chip == RF_PSEUDO_11N)
732 return;
733 pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff00) | channelToSW);
734 PHY_SetRFReg(padapter, ODM_RF_PATH_A, RF_CHNLBW, 0x3FF, pHalData->RfRegChnlVal[0]);
735 PHY_SetRFReg(padapter, ODM_RF_PATH_B, RF_CHNLBW, 0x3FF, pHalData->RfRegChnlVal[0]);
736 }
737
phy_SwChnlAndSetBwMode8723B(struct adapter * Adapter)738 static void phy_SwChnlAndSetBwMode8723B(struct adapter *Adapter)
739 {
740 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
741
742 if (Adapter->bDriverStopped || Adapter->bSurpriseRemoved)
743 return;
744
745 if (pHalData->bSwChnl) {
746 phy_SwChnl8723B(Adapter);
747 pHalData->bSwChnl = false;
748 }
749
750 if (pHalData->bSetChnlBW) {
751 phy_PostSetBwMode8723B(Adapter);
752 pHalData->bSetChnlBW = false;
753 }
754
755 PHY_SetTxPowerLevel8723B(Adapter, pHalData->CurrentChannel);
756 }
757
PHY_HandleSwChnlAndSetBW8723B(struct adapter * Adapter,bool bSwitchChannel,bool bSetBandWidth,u8 ChannelNum,enum channel_width ChnlWidth,enum extchnl_offset ExtChnlOffsetOf40MHz,enum extchnl_offset ExtChnlOffsetOf80MHz,u8 CenterFrequencyIndex1)758 static void PHY_HandleSwChnlAndSetBW8723B(
759 struct adapter *Adapter,
760 bool bSwitchChannel,
761 bool bSetBandWidth,
762 u8 ChannelNum,
763 enum channel_width ChnlWidth,
764 enum extchnl_offset ExtChnlOffsetOf40MHz,
765 enum extchnl_offset ExtChnlOffsetOf80MHz,
766 u8 CenterFrequencyIndex1
767 )
768 {
769 /* static bool bInitialzed = false; */
770 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
771 u8 tmpChannel = pHalData->CurrentChannel;
772 enum channel_width tmpBW = pHalData->CurrentChannelBW;
773 u8 tmpnCur40MhzPrimeSC = pHalData->nCur40MhzPrimeSC;
774 u8 tmpnCur80MhzPrimeSC = pHalData->nCur80MhzPrimeSC;
775 u8 tmpCenterFrequencyIndex1 = pHalData->CurrentCenterFrequencyIndex1;
776
777 /* check is swchnl or setbw */
778 if (!bSwitchChannel && !bSetBandWidth)
779 return;
780
781 /* skip change for channel or bandwidth is the same */
782 if (bSwitchChannel) {
783 {
784 if (HAL_IsLegalChannel(Adapter, ChannelNum))
785 pHalData->bSwChnl = true;
786 }
787 }
788
789 if (bSetBandWidth)
790 pHalData->bSetChnlBW = true;
791
792 if (!pHalData->bSetChnlBW && !pHalData->bSwChnl)
793 return;
794
795
796 if (pHalData->bSwChnl) {
797 pHalData->CurrentChannel = ChannelNum;
798 pHalData->CurrentCenterFrequencyIndex1 = ChannelNum;
799 }
800
801
802 if (pHalData->bSetChnlBW) {
803 pHalData->CurrentChannelBW = ChnlWidth;
804 pHalData->nCur40MhzPrimeSC = ExtChnlOffsetOf40MHz;
805 pHalData->nCur80MhzPrimeSC = ExtChnlOffsetOf80MHz;
806 pHalData->CurrentCenterFrequencyIndex1 = CenterFrequencyIndex1;
807 }
808
809 /* Switch workitem or set timer to do switch channel or setbandwidth operation */
810 if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) {
811 phy_SwChnlAndSetBwMode8723B(Adapter);
812 } else {
813 if (pHalData->bSwChnl) {
814 pHalData->CurrentChannel = tmpChannel;
815 pHalData->CurrentCenterFrequencyIndex1 = tmpChannel;
816 }
817
818 if (pHalData->bSetChnlBW) {
819 pHalData->CurrentChannelBW = tmpBW;
820 pHalData->nCur40MhzPrimeSC = tmpnCur40MhzPrimeSC;
821 pHalData->nCur80MhzPrimeSC = tmpnCur80MhzPrimeSC;
822 pHalData->CurrentCenterFrequencyIndex1 = tmpCenterFrequencyIndex1;
823 }
824 }
825 }
826
PHY_SetBWMode8723B(struct adapter * Adapter,enum channel_width Bandwidth,unsigned char Offset)827 void PHY_SetBWMode8723B(
828 struct adapter *Adapter,
829 enum channel_width Bandwidth, /* 20M or 40M */
830 unsigned char Offset /* Upper, Lower, or Don't care */
831 )
832 {
833 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
834
835 PHY_HandleSwChnlAndSetBW8723B(Adapter, false, true, pHalData->CurrentChannel, Bandwidth, Offset, Offset, pHalData->CurrentChannel);
836 }
837
838 /* Call after initialization */
PHY_SwChnl8723B(struct adapter * Adapter,u8 channel)839 void PHY_SwChnl8723B(struct adapter *Adapter, u8 channel)
840 {
841 PHY_HandleSwChnlAndSetBW8723B(Adapter, true, false, channel, 0, 0, 0, channel);
842 }
843
PHY_SetSwChnlBWMode8723B(struct adapter * Adapter,u8 channel,enum channel_width Bandwidth,u8 Offset40,u8 Offset80)844 void PHY_SetSwChnlBWMode8723B(
845 struct adapter *Adapter,
846 u8 channel,
847 enum channel_width Bandwidth,
848 u8 Offset40,
849 u8 Offset80
850 )
851 {
852 PHY_HandleSwChnlAndSetBW8723B(Adapter, true, true, channel, Bandwidth, Offset40, Offset80, channel);
853 }
854