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