1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3
4 #define _RTL8188E_PHYCFG_C_
5
6 #include "../include/osdep_service.h"
7 #include "../include/drv_types.h"
8 #include "../include/rtw_iol.h"
9 #include "../include/rtl8188e_hal.h"
10
11 /* */
12 /* 1. BB register R/W API */
13 /* */
14
15 /* Get shifted position of the bit mask */
phy_calculate_bit_shift(u32 bitmask)16 static u32 phy_calculate_bit_shift(u32 bitmask)
17 {
18 u32 i = ffs(bitmask);
19
20 return i ? i - 1 : 32;
21 }
22
23 /**
24 * Function: PHY_QueryBBReg
25 *
26 * OverView: Read "sepcific bits" from BB register
27 *
28 * Input:
29 * struct adapter *Adapter,
30 * u32 RegAddr, The target address to be readback
31 * u32 BitMask The target bit position in the target address
32 * to be readback
33 * Output: None
34 * Return: u32 Data The readback register value
35 * Note: This function is equal to "GetRegSetting" in PHY programming guide
36 */
37 u32
rtl8188e_PHY_QueryBBReg(struct adapter * Adapter,u32 RegAddr,u32 BitMask)38 rtl8188e_PHY_QueryBBReg(
39 struct adapter *Adapter,
40 u32 RegAddr,
41 u32 BitMask
42 )
43 {
44 u32 ReturnValue = 0, OriginalValue, BitShift;
45 int res;
46
47 res = rtw_read32(Adapter, RegAddr, &OriginalValue);
48 if (res)
49 return 0;
50
51 BitShift = phy_calculate_bit_shift(BitMask);
52 ReturnValue = (OriginalValue & BitMask) >> BitShift;
53 return ReturnValue;
54 }
55
56 /**
57 * Function: PHY_SetBBReg
58 *
59 * OverView: Write "Specific bits" to BB register (page 8~)
60 *
61 * Input:
62 * struct adapter *Adapter,
63 * u32 RegAddr, The target address to be modified
64 * u32 BitMask The target bit position in the target address
65 * to be modified
66 * u32 Data The new register value in the target bit position
67 * of the target address
68 *
69 * Output: None
70 * Return: None
71 * Note: This function is equal to "PutRegSetting" in PHY programming guide
72 */
73
rtl8188e_PHY_SetBBReg(struct adapter * Adapter,u32 RegAddr,u32 BitMask,u32 Data)74 void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
75 {
76 u32 OriginalValue, BitShift;
77 int res;
78
79 if (BitMask != bMaskDWord) { /* if not "double word" write */
80 res = rtw_read32(Adapter, RegAddr, &OriginalValue);
81 if (res)
82 return;
83
84 BitShift = phy_calculate_bit_shift(BitMask);
85 Data = ((OriginalValue & (~BitMask)) | (Data << BitShift));
86 }
87
88 rtw_write32(Adapter, RegAddr, Data);
89 }
90
91 /* */
92 /* 2. RF register R/W API */
93 /* */
94 /**
95 * Function: phy_RFSerialRead
96 *
97 * OverView: Read regster from RF chips
98 *
99 * Input:
100 * struct adapter *Adapter,
101 * u32 Offset, The target address to be read
102 *
103 * Output: None
104 * Return: u32 reback value
105 * Note: Threre are three types of serial operations:
106 * 1. Software serial write
107 * 2. Hardware LSSI-Low Speed Serial Interface
108 * 3. Hardware HSSI-High speed
109 * serial write. Driver need to implement (1) and (2).
110 * This function is equal to the combination of RF_ReadReg() and RFLSSIRead()
111 */
112 static u32
phy_RFSerialRead(struct adapter * Adapter,u32 Offset)113 phy_RFSerialRead(
114 struct adapter *Adapter,
115 u32 Offset
116 )
117 {
118 u32 retValue = 0;
119 struct hal_data_8188e *pHalData = &Adapter->haldata;
120 struct bb_reg_def *pPhyReg = &pHalData->PHYRegDef;
121 u32 NewOffset;
122 u32 tmplong, tmplong2;
123 u8 RfPiEnable = 0;
124 /* */
125 /* Make sure RF register offset is correct */
126 /* */
127 Offset &= 0xff;
128
129 /* */
130 /* Switch page for 8256 RF IC */
131 /* */
132 NewOffset = Offset;
133
134 /* For 92S LSSI Read RFLSSIRead */
135 /* For RF A/B write 0x824/82c(does not work in the future) */
136 /* We must use 0x824 for RF A and B to execute read trigger */
137 tmplong = rtl8188e_PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord);
138 tmplong2 = tmplong;
139
140 tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset << 23) | bLSSIReadEdge; /* T65 RF */
141
142 rtl8188e_PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord, tmplong & (~bLSSIReadEdge));
143 udelay(10);/* PlatformStallExecution(10); */
144
145 rtl8188e_PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord, tmplong2);
146 udelay(100);/* PlatformStallExecution(100); */
147
148 udelay(10);/* PlatformStallExecution(10); */
149
150 RfPiEnable = (u8)rtl8188e_PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter1, BIT(8));
151
152 if (RfPiEnable) { /* Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */
153 retValue = rtl8188e_PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi, bLSSIReadBackData);
154 } else { /* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */
155 retValue = rtl8188e_PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack, bLSSIReadBackData);
156 }
157 return retValue;
158 }
159
160 /**
161 * Function: phy_RFSerialWrite
162 *
163 * OverView: Write data to RF register (page 8~)
164 *
165 * Input:
166 * struct adapter *Adapter,
167 * enum rf_radio_path eRFPath, Radio path of A/B/C/D
168 * u32 Offset, The target address to be read
169 * u32 Data The new register Data in the target bit position
170 * of the target to be read
171 *
172 * Output: None
173 * Return: None
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 */
203 static void
phy_RFSerialWrite(struct adapter * Adapter,u32 Offset,u32 Data)204 phy_RFSerialWrite(
205 struct adapter *Adapter,
206 u32 Offset,
207 u32 Data
208 )
209 {
210 u32 DataAndAddr = 0;
211 struct hal_data_8188e *pHalData = &Adapter->haldata;
212 struct bb_reg_def *pPhyReg = &pHalData->PHYRegDef;
213 u32 NewOffset;
214
215 /* 2009/06/17 MH We can not execute IO for power save or other accident mode. */
216
217 Offset &= 0xff;
218
219 /* */
220 /* Switch page for 8256 RF IC */
221 /* */
222 NewOffset = Offset;
223
224 /* */
225 /* Put write addr in [5:0] and write data in [31:16] */
226 /* */
227 DataAndAddr = ((NewOffset << 20) | (Data & 0x000fffff)) & 0x0fffffff; /* T65 RF */
228
229 /* */
230 /* Write Operation */
231 /* */
232 rtl8188e_PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
233 }
234
235 /**
236 * Function: PHY_QueryRFReg
237 *
238 * OverView: Query "Specific bits" to RF register (page 8~)
239 *
240 * Input:
241 * struct adapter *Adapter,
242 * u32 RegAddr, The target address to be read
243 * u32 BitMask The target bit position in the target address
244 * to be read
245 *
246 * Output: None
247 * Return: u32 Readback value
248 * Note: This function is equal to "GetRFRegSetting" in PHY programming guide
249 */
rtl8188e_PHY_QueryRFReg(struct adapter * Adapter,u32 RegAddr,u32 BitMask)250 u32 rtl8188e_PHY_QueryRFReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask)
251 {
252 u32 Original_Value, Readback_Value, BitShift;
253
254 Original_Value = phy_RFSerialRead(Adapter, RegAddr);
255
256 BitShift = phy_calculate_bit_shift(BitMask);
257 Readback_Value = (Original_Value & BitMask) >> BitShift;
258 return Readback_Value;
259 }
260
261 /**
262 * Function: PHY_SetRFReg
263 *
264 * OverView: Write "Specific bits" to RF register (page 8~)
265 *
266 * Input:
267 * struct adapter *Adapter,
268 * u32 RegAddr, The target address to be modified
269 * u32 BitMask The target bit position in the target address
270 * to be modified
271 * u32 Data The new register Data in the target bit position
272 * of the target address
273 *
274 * Output: None
275 * Return: None
276 * Note: This function is equal to "PutRFRegSetting" in PHY programming guide
277 */
278 void
rtl8188e_PHY_SetRFReg(struct adapter * Adapter,u32 RegAddr,u32 BitMask,u32 Data)279 rtl8188e_PHY_SetRFReg(
280 struct adapter *Adapter,
281 u32 RegAddr,
282 u32 BitMask,
283 u32 Data
284 )
285 {
286 u32 Original_Value, BitShift;
287
288 /* RF data is 12 bits only */
289 if (BitMask != bRFRegOffsetMask) {
290 Original_Value = phy_RFSerialRead(Adapter, RegAddr);
291 BitShift = phy_calculate_bit_shift(BitMask);
292 Data = ((Original_Value & (~BitMask)) | (Data << BitShift));
293 }
294
295 phy_RFSerialWrite(Adapter, RegAddr, Data);
296 }
297
298 /* */
299 /* 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */
300 /* */
301
302 /*-----------------------------------------------------------------------------
303 * Function: PHY_MACConfig8192C
304 *
305 * Overview: Condig MAC by header file or parameter file.
306 *
307 * Input: NONE
308 *
309 * Output: NONE
310 *
311 * Return: NONE
312 *
313 * Revised History:
314 * When Who Remark
315 * 08/12/2008 MHC Create Version 0.
316 *
317 *---------------------------------------------------------------------------*/
PHY_MACConfig8188E(struct adapter * Adapter)318 s32 PHY_MACConfig8188E(struct adapter *Adapter)
319 {
320 struct hal_data_8188e *pHalData = &Adapter->haldata;
321 int rtStatus = _SUCCESS;
322
323 /* */
324 /* Config MAC */
325 /* */
326 if (ODM_ReadAndConfig_MAC_REG_8188E(&pHalData->odmpriv))
327 rtStatus = _FAIL;
328
329 /* 2010.07.13 AMPDU aggregation number B */
330 rtw_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM);
331
332 return rtStatus;
333 }
334
335 /**
336 * Function: phy_InitBBRFRegisterDefinition
337 *
338 * OverView: Initialize Register definition offset for Radio Path A/B/C/D
339 *
340 * Input:
341 * struct adapter *Adapter,
342 *
343 * Output: None
344 * Return: None
345 * Note: The initialization value is constant and it should never be changes
346 */
347 static void
phy_InitBBRFRegisterDefinition(struct adapter * Adapter)348 phy_InitBBRFRegisterDefinition(
349 struct adapter *Adapter
350 )
351 {
352 struct hal_data_8188e *pHalData = &Adapter->haldata;
353
354 /* RF Interface Sowrtware Control */
355 pHalData->PHYRegDef.rfintfs = rFPGA0_XAB_RFInterfaceSW; /* 16 LSBs if read 32-bit from 0x870 */
356
357 /* RF Interface Readback Value */
358 pHalData->PHYRegDef.rfintfi = rFPGA0_XAB_RFInterfaceRB; /* 16 LSBs if read 32-bit from 0x8E0 */
359
360 /* RF Interface Output (and Enable) */
361 pHalData->PHYRegDef.rfintfo = rFPGA0_XA_RFInterfaceOE; /* 16 LSBs if read 32-bit from 0x860 */
362
363 /* RF Interface (Output and) Enable */
364 pHalData->PHYRegDef.rfintfe = rFPGA0_XA_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
365
366 /* Addr of LSSI. Wirte RF register by driver */
367 pHalData->PHYRegDef.rf3wireOffset = rFPGA0_XA_LSSIParameter; /* LSSI Parameter */
368
369 /* RF parameter */
370 pHalData->PHYRegDef.rfLSSI_Select = rFPGA0_XAB_RFParameter; /* BB Band Select */
371
372 /* Tx AGC Gain Stage (same for all path. Should we remove this?) */
373 pHalData->PHYRegDef.rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */
374
375 /* Transceiver A~D HSSI Parameter-1 */
376 pHalData->PHYRegDef.rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; /* wire control parameter1 */
377
378 /* Transceiver A~D HSSI Parameter-2 */
379 pHalData->PHYRegDef.rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; /* wire control parameter2 */
380
381 /* RF switch Control */
382 pHalData->PHYRegDef.rfSwitchControl = rFPGA0_XAB_SwitchControl; /* TR/Ant switch control */
383
384 /* AGC control 1 */
385 pHalData->PHYRegDef.rfAGCControl1 = rOFDM0_XAAGCCore1;
386
387 /* AGC control 2 */
388 pHalData->PHYRegDef.rfAGCControl2 = rOFDM0_XAAGCCore2;
389
390 /* RX AFE control 1 */
391 pHalData->PHYRegDef.rfRxIQImbalance = rOFDM0_XARxIQImbalance;
392
393 /* RX AFE control 1 */
394 pHalData->PHYRegDef.rfRxAFE = rOFDM0_XARxAFE;
395
396 /* Tx AFE control 1 */
397 pHalData->PHYRegDef.rfTxIQImbalance = rOFDM0_XATxIQImbalance;
398
399 /* Tx AFE control 2 */
400 pHalData->PHYRegDef.rfTxAFE = rOFDM0_XATxAFE;
401
402 /* Transceiver LSSI Readback SI mode */
403 pHalData->PHYRegDef.rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
404
405 /* Transceiver LSSI Readback PI mode */
406 pHalData->PHYRegDef.rfLSSIReadBackPi = TransceiverA_HSPI_Readback;
407 }
408
storePwrIndexDiffRateOffset(struct adapter * Adapter,u32 RegAddr,u32 BitMask,u32 Data)409 void storePwrIndexDiffRateOffset(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
410 {
411 struct hal_data_8188e *pHalData = &Adapter->haldata;
412
413 if (RegAddr == rTxAGC_A_Rate18_06)
414 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0] = Data;
415 if (RegAddr == rTxAGC_A_Rate54_24)
416 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][1] = Data;
417 if (RegAddr == rTxAGC_A_CCK1_Mcs32)
418 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][6] = Data;
419 if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0xffffff00)
420 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][7] = Data;
421 if (RegAddr == rTxAGC_A_Mcs03_Mcs00)
422 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][2] = Data;
423 if (RegAddr == rTxAGC_A_Mcs07_Mcs04)
424 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][3] = Data;
425 if (RegAddr == rTxAGC_A_Mcs11_Mcs08)
426 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][4] = Data;
427 if (RegAddr == rTxAGC_A_Mcs15_Mcs12) {
428 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][5] = Data;
429 pHalData->pwrGroupCnt++;
430 }
431 if (RegAddr == rTxAGC_B_Rate18_06)
432 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][8] = Data;
433 if (RegAddr == rTxAGC_B_Rate54_24)
434 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][9] = Data;
435 if (RegAddr == rTxAGC_B_CCK1_55_Mcs32)
436 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][14] = Data;
437 if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0x000000ff)
438 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][15] = Data;
439 if (RegAddr == rTxAGC_B_Mcs03_Mcs00)
440 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][10] = Data;
441 if (RegAddr == rTxAGC_B_Mcs07_Mcs04)
442 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][11] = Data;
443 if (RegAddr == rTxAGC_B_Mcs11_Mcs08)
444 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][12] = Data;
445 if (RegAddr == rTxAGC_B_Mcs15_Mcs12)
446 pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][13] = Data;
447 }
448
phy_BB8188E_Config_ParaFile(struct adapter * Adapter)449 static int phy_BB8188E_Config_ParaFile(struct adapter *Adapter)
450 {
451 struct eeprom_priv *pEEPROM = &Adapter->eeprompriv;
452 struct hal_data_8188e *pHalData = &Adapter->haldata;
453
454 /* */
455 /* 1. Read PHY_REG.TXT BB INIT!! */
456 /* We will separate as 88C / 92C according to chip version */
457 /* */
458 if (ODM_ReadAndConfig_PHY_REG_1T_8188E(&pHalData->odmpriv))
459 return _FAIL;
460
461 /* 2. If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */
462 if (!pEEPROM->bautoload_fail_flag) {
463 pHalData->pwrGroupCnt = 0;
464 ODM_ReadAndConfig_PHY_REG_PG_8188E(&pHalData->odmpriv);
465 }
466
467 /* 3. BB AGC table Initialization */
468 if (ODM_ReadAndConfig_AGC_TAB_1T_8188E(&pHalData->odmpriv))
469 return _FAIL;
470
471 return _SUCCESS;
472 }
473
474 int
PHY_BBConfig8188E(struct adapter * Adapter)475 PHY_BBConfig8188E(
476 struct adapter *Adapter
477 )
478 {
479 int rtStatus = _SUCCESS;
480 struct hal_data_8188e *pHalData = &Adapter->haldata;
481 u16 RegVal;
482 u8 CrystalCap;
483 int res;
484
485 phy_InitBBRFRegisterDefinition(Adapter);
486
487 /* Enable BB and RF */
488 res = rtw_read16(Adapter, REG_SYS_FUNC_EN, &RegVal);
489 if (res)
490 return _FAIL;
491
492 rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal | BIT(13) | BIT(0) | BIT(1)));
493
494 /* 20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */
495
496 rtw_write8(Adapter, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
497
498 rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | FEN_BB_GLB_RSTn | FEN_BBRSTB);
499
500 /* Config BB and AGC */
501 rtStatus = phy_BB8188E_Config_ParaFile(Adapter);
502
503 /* write 0x24[16:11] = 0x24[22:17] = CrystalCap */
504 CrystalCap = pHalData->CrystalCap & 0x3F;
505 rtl8188e_PHY_SetBBReg(Adapter, REG_AFE_XTAL_CTRL, 0x7ff800, (CrystalCap | (CrystalCap << 6)));
506
507 return rtStatus;
508 }
509
getTxPowerIndex88E(struct adapter * Adapter,u8 channel,u8 * cckPowerLevel,u8 * ofdmPowerLevel,u8 * BW20PowerLevel,u8 * BW40PowerLevel)510 static void getTxPowerIndex88E(struct adapter *Adapter, u8 channel, u8 *cckPowerLevel,
511 u8 *ofdmPowerLevel, u8 *BW20PowerLevel,
512 u8 *BW40PowerLevel)
513 {
514 struct hal_data_8188e *pHalData = &Adapter->haldata;
515 u8 index = (channel - 1);
516
517 /* 1. CCK */
518 cckPowerLevel[RF_PATH_A] = pHalData->Index24G_CCK_Base[index];
519 /* 2. OFDM */
520 ofdmPowerLevel[RF_PATH_A] = pHalData->Index24G_BW40_Base[index] +
521 pHalData->OFDM_24G_Diff[RF_PATH_A];
522 /* 1. BW20 */
523 BW20PowerLevel[RF_PATH_A] = pHalData->Index24G_BW40_Base[index] +
524 pHalData->BW20_24G_Diff[RF_PATH_A];
525 /* 2. BW40 */
526 BW40PowerLevel[RF_PATH_A] = pHalData->Index24G_BW40_Base[index];
527 }
528
529 /*-----------------------------------------------------------------------------
530 * Function: SetTxPowerLevel8190()
531 *
532 * Overview: This function is export to "HalCommon" moudule
533 * We must consider RF path later!!!!!!!
534 *
535 * Input: struct adapter *Adapter
536 * u8 channel
537 *
538 * Output: NONE
539 *
540 * Return: NONE
541 * 2008/11/04 MHC We remove EEPROM_93C56.
542 * We need to move CCX relative code to independet file.
543 * 2009/01/21 MHC Support new EEPROM format from SD3 requirement.
544 *
545 *---------------------------------------------------------------------------*/
546 void
PHY_SetTxPowerLevel8188E(struct adapter * Adapter,u8 channel)547 PHY_SetTxPowerLevel8188E(
548 struct adapter *Adapter,
549 u8 channel
550 )
551 {
552 u8 cckPowerLevel[MAX_TX_COUNT] = {0};
553 u8 ofdmPowerLevel[MAX_TX_COUNT] = {0};/* [0]:RF-A, [1]:RF-B */
554 u8 BW20PowerLevel[MAX_TX_COUNT] = {0};
555 u8 BW40PowerLevel[MAX_TX_COUNT] = {0};
556
557 getTxPowerIndex88E(Adapter, channel, &cckPowerLevel[0], &ofdmPowerLevel[0], &BW20PowerLevel[0], &BW40PowerLevel[0]);
558
559 rtl8188e_PHY_RF6052SetCckTxPower(Adapter, &cckPowerLevel[0]);
560 rtl8188e_PHY_RF6052SetOFDMTxPower(Adapter, &ofdmPowerLevel[0], &BW20PowerLevel[0], &BW40PowerLevel[0], channel);
561 }
562
563 /*-----------------------------------------------------------------------------
564 * Function: PHY_SetBWModeCallback8192C()
565 *
566 * Overview: Timer callback function for SetSetBWMode
567 *
568 * Input: PRT_TIMER pTimer
569 *
570 * Output: NONE
571 *
572 * Return: NONE
573 *
574 * Note: (1) We do not take j mode into consideration now
575 * (2) Will two workitem of "switch channel" and "switch channel bandwidth" run
576 * concurrently?
577 *---------------------------------------------------------------------------*/
578 static void
_PHY_SetBWMode92C(struct adapter * Adapter)579 _PHY_SetBWMode92C(
580 struct adapter *Adapter
581 )
582 {
583 struct hal_data_8188e *pHalData = &Adapter->haldata;
584 u8 regBwOpMode;
585 u8 regRRSR_RSC;
586 int res;
587
588 if (Adapter->bDriverStopped)
589 return;
590
591 /* 3 */
592 /* 3<1>Set MAC register */
593 /* 3 */
594
595 res = rtw_read8(Adapter, REG_BWOPMODE, ®BwOpMode);
596 if (res)
597 return;
598
599 res = rtw_read8(Adapter, REG_RRSR + 2, ®RRSR_RSC);
600 if (res)
601 return;
602
603 switch (pHalData->CurrentChannelBW) {
604 case HT_CHANNEL_WIDTH_20:
605 regBwOpMode |= BW_OPMODE_20MHZ;
606 /* 2007/02/07 Mark by Emily because we have not verify whether this register works */
607 rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode);
608 break;
609 case HT_CHANNEL_WIDTH_40:
610 regBwOpMode &= ~BW_OPMODE_20MHZ;
611 /* 2007/02/07 Mark by Emily because we have not verify whether this register works */
612 rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode);
613 regRRSR_RSC = (regRRSR_RSC & 0x90) | (pHalData->nCur40MhzPrimeSC << 5);
614 rtw_write8(Adapter, REG_RRSR + 2, regRRSR_RSC);
615 break;
616 default:
617 break;
618 }
619
620 /* 3 */
621 /* 3 <2>Set PHY related register */
622 /* 3 */
623 switch (pHalData->CurrentChannelBW) {
624 /* 20 MHz channel*/
625 case HT_CHANNEL_WIDTH_20:
626 rtl8188e_PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
627 rtl8188e_PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
628 break;
629 /* 40 MHz channel*/
630 case HT_CHANNEL_WIDTH_40:
631 rtl8188e_PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
632 rtl8188e_PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
633 /* Set Control channel to upper or lower. These settings are required only for 40MHz */
634 rtl8188e_PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand, (pHalData->nCur40MhzPrimeSC >> 1));
635 rtl8188e_PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00, pHalData->nCur40MhzPrimeSC);
636 rtl8188e_PHY_SetBBReg(Adapter, 0x818, (BIT(26) | BIT(27)),
637 (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
638 break;
639 default:
640 break;
641 }
642 /* Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315 */
643
644 rtl8188e_PHY_RF6052SetBandwidth(Adapter, pHalData->CurrentChannelBW);
645 }
646
647 /*-----------------------------------------------------------------------------
648 * Function: SetBWMode8190Pci()
649 *
650 * Overview: This function is export to "HalCommon" moudule
651 *
652 * Input: struct adapter *Adapter
653 * enum ht_channel_width Bandwidth 20M or 40M
654 *
655 * Output: NONE
656 *
657 * Return: NONE
658 *
659 * Note: We do not take j mode into consideration now
660 *---------------------------------------------------------------------------*/
PHY_SetBWMode8188E(struct adapter * Adapter,enum ht_channel_width Bandwidth,unsigned char Offset)661 void PHY_SetBWMode8188E(struct adapter *Adapter, enum ht_channel_width Bandwidth, /* 20M or 40M */
662 unsigned char Offset) /* Upper, Lower, or Don't care */
663 {
664 struct hal_data_8188e *pHalData = &Adapter->haldata;
665 enum ht_channel_width tmpBW = pHalData->CurrentChannelBW;
666
667 pHalData->CurrentChannelBW = Bandwidth;
668
669 pHalData->nCur40MhzPrimeSC = Offset;
670
671 if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved))
672 _PHY_SetBWMode92C(Adapter);
673 else
674 pHalData->CurrentChannelBW = tmpBW;
675 }
676
_PHY_SwChnl8192C(struct adapter * Adapter,u8 channel)677 static void _PHY_SwChnl8192C(struct adapter *Adapter, u8 channel)
678 {
679 u32 param1, param2;
680 struct hal_data_8188e *pHalData = &Adapter->haldata;
681
682 /* s1. pre common command - CmdID_SetTxPowerLevel */
683 PHY_SetTxPowerLevel8188E(Adapter, channel);
684
685 /* s2. RF dependent command - CmdID_RF_WriteReg, param1=RF_CHNLBW, param2=channel */
686 param1 = RF_CHNLBW;
687 param2 = channel;
688 pHalData->RfRegChnlVal = ((pHalData->RfRegChnlVal & 0xfffffc00) | param2);
689 rtl8188e_PHY_SetRFReg(Adapter, param1, bRFRegOffsetMask, pHalData->RfRegChnlVal);
690 }
691
PHY_SwChnl8188E(struct adapter * Adapter,u8 channel)692 void PHY_SwChnl8188E(struct adapter *Adapter, u8 channel)
693 {
694 /* Call after initialization */
695 struct hal_data_8188e *pHalData = &Adapter->haldata;
696
697 if (channel == 0)
698 channel = 1;
699
700 if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) {
701 pHalData->CurrentChannel = channel;
702 _PHY_SwChnl8192C(Adapter, channel);
703 }
704 }
705