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 (
342 Adapter->registrypriv.RegEnableTxPowerLimit == 1 ||
343 (Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory == 1)
344 ) {
345 ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv,
346 CONFIG_RF_TXPWR_LMT, 0);
347 }
348
349 /* */
350 /* 1. Read PHY_REG.TXT BB INIT!! */
351 /* */
352 ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG);
353
354 /* If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */
355 PHY_InitTxPowerByRate(Adapter);
356 if (
357 Adapter->registrypriv.RegEnableTxPowerByRate == 1 ||
358 (Adapter->registrypriv.RegEnableTxPowerByRate == 2 && pHalData->EEPROMRegulatory != 2)
359 ) {
360 ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv,
361 CONFIG_BB_PHY_REG_PG);
362
363 if (pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE)
364 PHY_TxPowerByRateConfiguration(Adapter);
365
366 if (
367 Adapter->registrypriv.RegEnableTxPowerLimit == 1 ||
368 (Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory == 1)
369 )
370 PHY_ConvertTxPowerLimitToPowerIndex(Adapter);
371 }
372
373 /* */
374 /* 2. Read BB AGC table Initialization */
375 /* */
376 ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_AGC_TAB);
377
378 return _SUCCESS;
379 }
380
381
PHY_BBConfig8723B(struct adapter * Adapter)382 int PHY_BBConfig8723B(struct adapter *Adapter)
383 {
384 int rtStatus = _SUCCESS;
385 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
386 u32 RegVal;
387 u8 CrystalCap;
388
389 phy_InitBBRFRegisterDefinition(Adapter);
390
391 /* Enable BB and RF */
392 RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
393 rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal|BIT13|BIT0|BIT1));
394
395 rtw_write32(Adapter, 0x948, 0x280); /* Others use Antenna S1 */
396
397 rtw_write8(Adapter, REG_RF_CTRL, RF_EN|RF_RSTB|RF_SDMRSTB);
398
399 msleep(1);
400
401 PHY_SetRFReg(Adapter, RF_PATH_A, 0x1, 0xfffff, 0x780);
402
403 rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_PPLL|FEN_PCIEA|FEN_DIO_PCIE|FEN_BB_GLB_RSTn|FEN_BBRSTB);
404
405 rtw_write8(Adapter, REG_AFE_XTAL_CTRL+1, 0x80);
406
407 /* */
408 /* Config BB and AGC */
409 /* */
410 rtStatus = phy_BB8723b_Config_ParaFile(Adapter);
411
412 /* 0x2C[23:18] = 0x2C[17:12] = CrystalCap */
413 CrystalCap = pHalData->CrystalCap & 0x3F;
414 PHY_SetBBReg(Adapter, REG_MAC_PHY_CTRL, 0xFFF000, (CrystalCap | (CrystalCap << 6)));
415
416 return rtStatus;
417 }
418
phy_LCK_8723B(struct adapter * Adapter)419 static void phy_LCK_8723B(struct adapter *Adapter)
420 {
421 PHY_SetRFReg(Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFBE0);
422 PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, 0x8C01);
423 mdelay(200);
424 PHY_SetRFReg(Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFFE0);
425 }
426
PHY_RFConfig8723B(struct adapter * Adapter)427 int PHY_RFConfig8723B(struct adapter *Adapter)
428 {
429 int rtStatus = _SUCCESS;
430
431 /* */
432 /* RF config */
433 /* */
434 rtStatus = PHY_RF6052_Config8723B(Adapter);
435
436 phy_LCK_8723B(Adapter);
437
438 return rtStatus;
439 }
440
441 /**************************************************************************************************************
442 * Description:
443 * The low-level interface to set TxAGC , called by both MP and Normal Driver.
444 *
445 * <20120830, Kordan>
446 **************************************************************************************************************/
447
PHY_SetTxPowerIndex(struct adapter * Adapter,u32 PowerIndex,u8 RFPath,u8 Rate)448 void PHY_SetTxPowerIndex(
449 struct adapter *Adapter,
450 u32 PowerIndex,
451 u8 RFPath,
452 u8 Rate
453 )
454 {
455 if (RFPath == RF_PATH_A || RFPath == RF_PATH_B) {
456 switch (Rate) {
457 case MGN_1M:
458 PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, PowerIndex);
459 break;
460 case MGN_2M:
461 PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte1, PowerIndex);
462 break;
463 case MGN_5_5M:
464 PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte2, PowerIndex);
465 break;
466 case MGN_11M:
467 PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte3, PowerIndex);
468 break;
469
470 case MGN_6M:
471 PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte0, PowerIndex);
472 break;
473 case MGN_9M:
474 PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte1, PowerIndex);
475 break;
476 case MGN_12M:
477 PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte2, PowerIndex);
478 break;
479 case MGN_18M:
480 PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte3, PowerIndex);
481 break;
482
483 case MGN_24M:
484 PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte0, PowerIndex);
485 break;
486 case MGN_36M:
487 PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte1, PowerIndex);
488 break;
489 case MGN_48M:
490 PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte2, PowerIndex);
491 break;
492 case MGN_54M:
493 PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte3, PowerIndex);
494 break;
495
496 case MGN_MCS0:
497 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte0, PowerIndex);
498 break;
499 case MGN_MCS1:
500 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte1, PowerIndex);
501 break;
502 case MGN_MCS2:
503 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte2, PowerIndex);
504 break;
505 case MGN_MCS3:
506 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte3, PowerIndex);
507 break;
508
509 case MGN_MCS4:
510 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte0, PowerIndex);
511 break;
512 case MGN_MCS5:
513 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte1, PowerIndex);
514 break;
515 case MGN_MCS6:
516 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte2, PowerIndex);
517 break;
518 case MGN_MCS7:
519 PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte3, PowerIndex);
520 break;
521
522 default:
523 break;
524 }
525 }
526 }
527
PHY_GetTxPowerIndex(struct adapter * padapter,u8 RFPath,u8 Rate,enum channel_width BandWidth,u8 Channel)528 u8 PHY_GetTxPowerIndex(
529 struct adapter *padapter,
530 u8 RFPath,
531 u8 Rate,
532 enum channel_width BandWidth,
533 u8 Channel
534 )
535 {
536 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
537 s8 txPower = 0, powerDiffByRate = 0, limit = 0;
538
539 txPower = (s8) PHY_GetTxPowerIndexBase(padapter, RFPath, Rate, BandWidth, Channel);
540 powerDiffByRate = PHY_GetTxPowerByRate(padapter, RF_PATH_A, Rate);
541
542 limit = phy_get_tx_pwr_lmt(
543 padapter,
544 padapter->registrypriv.RegPwrTblSel,
545 pHalData->CurrentChannelBW,
546 RFPath,
547 Rate,
548 pHalData->CurrentChannel
549 );
550
551 powerDiffByRate = powerDiffByRate > limit ? limit : powerDiffByRate;
552 txPower += powerDiffByRate;
553
554 txPower += PHY_GetTxPowerTrackingOffset(padapter, RFPath, Rate);
555
556 if (txPower > MAX_POWER_INDEX)
557 txPower = MAX_POWER_INDEX;
558
559 return (u8) txPower;
560 }
561
PHY_SetTxPowerLevel8723B(struct adapter * Adapter,u8 Channel)562 void PHY_SetTxPowerLevel8723B(struct adapter *Adapter, u8 Channel)
563 {
564 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
565 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
566 struct fat_t *pDM_FatTable = &pDM_Odm->DM_FatTable;
567 u8 RFPath = RF_PATH_A;
568
569 if (pHalData->AntDivCfg) {/* antenna diversity Enable */
570 RFPath = ((pDM_FatTable->RxIdleAnt == MAIN_ANT) ? RF_PATH_A : RF_PATH_B);
571 } else { /* antenna diversity disable */
572 RFPath = pHalData->ant_path;
573 }
574
575 PHY_SetTxPowerLevelByPath(Adapter, Channel, RFPath);
576 }
577
PHY_GetTxPowerLevel8723B(struct adapter * Adapter,s32 * powerlevel)578 void PHY_GetTxPowerLevel8723B(struct adapter *Adapter, s32 *powerlevel)
579 {
580 }
581
phy_SetRegBW_8723B(struct adapter * Adapter,enum channel_width CurrentBW)582 static void phy_SetRegBW_8723B(
583 struct adapter *Adapter, enum channel_width CurrentBW
584 )
585 {
586 u16 RegRfMod_BW, u2tmp = 0;
587 RegRfMod_BW = rtw_read16(Adapter, REG_TRXPTCL_CTL_8723B);
588
589 switch (CurrentBW) {
590 case CHANNEL_WIDTH_20:
591 rtw_write16(Adapter, REG_TRXPTCL_CTL_8723B, (RegRfMod_BW & 0xFE7F)); /* BIT 7 = 0, BIT 8 = 0 */
592 break;
593
594 case CHANNEL_WIDTH_40:
595 u2tmp = RegRfMod_BW | BIT7;
596 rtw_write16(Adapter, REG_TRXPTCL_CTL_8723B, (u2tmp & 0xFEFF)); /* BIT 7 = 1, BIT 8 = 0 */
597 break;
598
599 default:
600 break;
601 }
602 }
603
phy_GetSecondaryChnl_8723B(struct adapter * Adapter)604 static u8 phy_GetSecondaryChnl_8723B(struct adapter *Adapter)
605 {
606 u8 SCSettingOf40 = 0, SCSettingOf20 = 0;
607 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
608
609 if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40) {
610 if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
611 SCSettingOf20 = HT_DATA_SC_20_UPPER_OF_40MHZ;
612 else if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
613 SCSettingOf20 = HT_DATA_SC_20_LOWER_OF_40MHZ;
614 }
615
616 return (SCSettingOf40 << 4) | SCSettingOf20;
617 }
618
phy_PostSetBwMode8723B(struct adapter * Adapter)619 static void phy_PostSetBwMode8723B(struct adapter *Adapter)
620 {
621 u8 SubChnlNum = 0;
622 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
623
624
625 /* 3 Set Reg668 Reg440 BW */
626 phy_SetRegBW_8723B(Adapter, pHalData->CurrentChannelBW);
627
628 /* 3 Set Reg483 */
629 SubChnlNum = phy_GetSecondaryChnl_8723B(Adapter);
630 rtw_write8(Adapter, REG_DATA_SC_8723B, SubChnlNum);
631
632 /* 3 */
633 /* 3<2>Set PHY related register */
634 /* 3 */
635 switch (pHalData->CurrentChannelBW) {
636 /* 20 MHz channel*/
637 case CHANNEL_WIDTH_20:
638 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
639
640 PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
641
642 PHY_SetBBReg(Adapter, rOFDM0_TxPseudoNoiseWgt, (BIT31|BIT30), 0x0);
643 break;
644
645 /* 40 MHz channel*/
646 case CHANNEL_WIDTH_40:
647 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
648
649 PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
650
651 /* Set Control channel to upper or lower. These settings are required only for 40MHz */
652 PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand, (pHalData->nCur40MhzPrimeSC>>1));
653
654 PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00, pHalData->nCur40MhzPrimeSC);
655
656 PHY_SetBBReg(Adapter, 0x818, (BIT26|BIT27), (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
657 break;
658 default:
659 break;
660 }
661
662 /* 3<3>Set RF related register */
663 PHY_RF6052SetBandwidth8723B(Adapter, pHalData->CurrentChannelBW);
664 }
665
phy_SwChnl8723B(struct adapter * padapter)666 static void phy_SwChnl8723B(struct adapter *padapter)
667 {
668 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
669 u8 channelToSW = pHalData->CurrentChannel;
670
671 if (pHalData->rf_chip == RF_PSEUDO_11N)
672 return;
673 pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff00) | channelToSW);
674 PHY_SetRFReg(padapter, RF_PATH_A, RF_CHNLBW, 0x3FF, pHalData->RfRegChnlVal[0]);
675 PHY_SetRFReg(padapter, RF_PATH_B, RF_CHNLBW, 0x3FF, pHalData->RfRegChnlVal[0]);
676 }
677
phy_SwChnlAndSetBwMode8723B(struct adapter * Adapter)678 static void phy_SwChnlAndSetBwMode8723B(struct adapter *Adapter)
679 {
680 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
681
682 if (Adapter->bDriverStopped || Adapter->bSurpriseRemoved)
683 return;
684
685 if (pHalData->bSwChnl) {
686 phy_SwChnl8723B(Adapter);
687 pHalData->bSwChnl = false;
688 }
689
690 if (pHalData->bSetChnlBW) {
691 phy_PostSetBwMode8723B(Adapter);
692 pHalData->bSetChnlBW = false;
693 }
694
695 PHY_SetTxPowerLevel8723B(Adapter, pHalData->CurrentChannel);
696 }
697
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)698 static void PHY_HandleSwChnlAndSetBW8723B(
699 struct adapter *Adapter,
700 bool bSwitchChannel,
701 bool bSetBandWidth,
702 u8 ChannelNum,
703 enum channel_width ChnlWidth,
704 enum extchnl_offset ExtChnlOffsetOf40MHz,
705 enum extchnl_offset ExtChnlOffsetOf80MHz,
706 u8 CenterFrequencyIndex1
707 )
708 {
709 /* static bool bInitialzed = false; */
710 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
711 u8 tmpChannel = pHalData->CurrentChannel;
712 enum channel_width tmpBW = pHalData->CurrentChannelBW;
713 u8 tmpnCur40MhzPrimeSC = pHalData->nCur40MhzPrimeSC;
714 u8 tmpnCur80MhzPrimeSC = pHalData->nCur80MhzPrimeSC;
715 u8 tmpCenterFrequencyIndex1 = pHalData->CurrentCenterFrequencyIndex1;
716
717 /* check is swchnl or setbw */
718 if (!bSwitchChannel && !bSetBandWidth)
719 return;
720
721 /* skip change for channel or bandwidth is the same */
722 if (bSwitchChannel) {
723 {
724 if (HAL_IsLegalChannel(Adapter, ChannelNum))
725 pHalData->bSwChnl = true;
726 }
727 }
728
729 if (bSetBandWidth)
730 pHalData->bSetChnlBW = true;
731
732 if (!pHalData->bSetChnlBW && !pHalData->bSwChnl)
733 return;
734
735
736 if (pHalData->bSwChnl) {
737 pHalData->CurrentChannel = ChannelNum;
738 pHalData->CurrentCenterFrequencyIndex1 = ChannelNum;
739 }
740
741
742 if (pHalData->bSetChnlBW) {
743 pHalData->CurrentChannelBW = ChnlWidth;
744 pHalData->nCur40MhzPrimeSC = ExtChnlOffsetOf40MHz;
745 pHalData->nCur80MhzPrimeSC = ExtChnlOffsetOf80MHz;
746 pHalData->CurrentCenterFrequencyIndex1 = CenterFrequencyIndex1;
747 }
748
749 /* Switch workitem or set timer to do switch channel or setbandwidth operation */
750 if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) {
751 phy_SwChnlAndSetBwMode8723B(Adapter);
752 } else {
753 if (pHalData->bSwChnl) {
754 pHalData->CurrentChannel = tmpChannel;
755 pHalData->CurrentCenterFrequencyIndex1 = tmpChannel;
756 }
757
758 if (pHalData->bSetChnlBW) {
759 pHalData->CurrentChannelBW = tmpBW;
760 pHalData->nCur40MhzPrimeSC = tmpnCur40MhzPrimeSC;
761 pHalData->nCur80MhzPrimeSC = tmpnCur80MhzPrimeSC;
762 pHalData->CurrentCenterFrequencyIndex1 = tmpCenterFrequencyIndex1;
763 }
764 }
765 }
766
PHY_SetBWMode8723B(struct adapter * Adapter,enum channel_width Bandwidth,unsigned char Offset)767 void PHY_SetBWMode8723B(
768 struct adapter *Adapter,
769 enum channel_width Bandwidth, /* 20M or 40M */
770 unsigned char Offset /* Upper, Lower, or Don't care */
771 )
772 {
773 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
774
775 PHY_HandleSwChnlAndSetBW8723B(Adapter, false, true, pHalData->CurrentChannel, Bandwidth, Offset, Offset, pHalData->CurrentChannel);
776 }
777
778 /* Call after initialization */
PHY_SwChnl8723B(struct adapter * Adapter,u8 channel)779 void PHY_SwChnl8723B(struct adapter *Adapter, u8 channel)
780 {
781 PHY_HandleSwChnlAndSetBW8723B(Adapter, true, false, channel, 0, 0, 0, channel);
782 }
783
PHY_SetSwChnlBWMode8723B(struct adapter * Adapter,u8 channel,enum channel_width Bandwidth,u8 Offset40,u8 Offset80)784 void PHY_SetSwChnlBWMode8723B(
785 struct adapter *Adapter,
786 u8 channel,
787 enum channel_width Bandwidth,
788 u8 Offset40,
789 u8 Offset80
790 )
791 {
792 PHY_HandleSwChnlAndSetBW8723B(Adapter, true, true, channel, Bandwidth, Offset40, Offset80, channel);
793 }
794