1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37#define _RTL8723A_RF6052_C_
38
39#include <osdep_service.h>
40#include <drv_types.h>
41
42#include <rtl8723a_hal.h>
43#include <usb_ops_linux.h>
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59void rtl8723a_phy_rf6052set_bw(struct rtw_adapter *Adapter,
60 enum ht_channel_width Bandwidth)
61{
62 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
63
64 switch (Bandwidth) {
65 case HT_CHANNEL_WIDTH_20:
66 pHalData->RfRegChnlVal[0] =
67 (pHalData->RfRegChnlVal[0] & 0xfffff3ff) | 0x0400;
68 PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask,
69 pHalData->RfRegChnlVal[0]);
70 break;
71 case HT_CHANNEL_WIDTH_40:
72 pHalData->RfRegChnlVal[0] =
73 (pHalData->RfRegChnlVal[0] & 0xfffff3ff);
74 PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask,
75 pHalData->RfRegChnlVal[0]);
76 break;
77 default:
78 break;
79 }
80}
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99void rtl823a_phy_rf6052setccktxpower(struct rtw_adapter *Adapter,
100 u8 *pPowerlevel)
101{
102 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
103 struct dm_priv *pdmpriv = &pHalData->dmpriv;
104 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
105 u32 TxAGC[2] = {0, 0}, tmpval = 0;
106 bool TurboScanOff = false;
107 u8 idx1, idx2;
108 u8 *ptr;
109
110
111
112
113 if (pHalData->EEPROMRegulatory != 0 || pHalData->ExternalPA)
114 TurboScanOff = true;
115
116 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
117 TxAGC[RF_PATH_A] = 0x3f3f3f3f;
118 TxAGC[RF_PATH_B] = 0x3f3f3f3f;
119
120 TurboScanOff = true;
121
122 if (TurboScanOff) {
123 for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
124 TxAGC[idx1] = pPowerlevel[idx1] |
125 (pPowerlevel[idx1] << 8) |
126 (pPowerlevel[idx1] << 16) |
127 (pPowerlevel[idx1] << 24);
128
129
130
131 if (TxAGC[idx1] > 0x20 && pHalData->ExternalPA)
132 TxAGC[idx1] = 0x20;
133 }
134 }
135 } else {
136
137
138
139
140
141
142 if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) {
143 TxAGC[RF_PATH_A] = 0x10101010;
144 TxAGC[RF_PATH_B] = 0x10101010;
145 } else if (pdmpriv->DynamicTxHighPowerLvl ==
146 TxHighPwrLevel_Level2) {
147 TxAGC[RF_PATH_A] = 0x00000000;
148 TxAGC[RF_PATH_B] = 0x00000000;
149 } else {
150 for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
151 TxAGC[idx1] = pPowerlevel[idx1] |
152 (pPowerlevel[idx1] << 8) |
153 (pPowerlevel[idx1] << 16) |
154 (pPowerlevel[idx1] << 24);
155 }
156
157 if (pHalData->EEPROMRegulatory == 0) {
158 tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][6]) +
159 (pHalData->MCSTxPowerLevelOriginalOffset[0][7]<<8);
160 TxAGC[RF_PATH_A] += tmpval;
161
162 tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][14]) +
163 (pHalData->MCSTxPowerLevelOriginalOffset[0][15]<<24);
164 TxAGC[RF_PATH_B] += tmpval;
165 }
166 }
167 }
168
169 for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
170 ptr = (u8 *)(&TxAGC[idx1]);
171 for (idx2 = 0; idx2 < 4; idx2++) {
172 if (*ptr > RF6052_MAX_TX_PWR)
173 *ptr = RF6052_MAX_TX_PWR;
174 ptr++;
175 }
176 }
177
178
179 tmpval = TxAGC[RF_PATH_A] & 0xff;
180 PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, tmpval);
181 tmpval = TxAGC[RF_PATH_A] >> 8;
182 PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
183
184
185 tmpval = TxAGC[RF_PATH_B] >> 24;
186 PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, tmpval);
187 tmpval = TxAGC[RF_PATH_B] & 0x00ffffff;
188 PHY_SetBBReg(Adapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, tmpval);
189}
190
191
192
193static void getPowerBase(struct rtw_adapter *Adapter, u8 *pPowerLevel,
194 u8 Channel, u32 *OfdmBase, u32 *MCSBase)
195{
196 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
197 u32 powerBase0, powerBase1;
198 u8 Legacy_pwrdiff = 0;
199 s8 HT20_pwrdiff = 0;
200 u8 i, powerlevel[2];
201
202 for (i = 0; i < 2; i++) {
203 powerlevel[i] = pPowerLevel[i];
204 Legacy_pwrdiff = pHalData->TxPwrLegacyHtDiff[i][Channel-1];
205 powerBase0 = powerlevel[i] + Legacy_pwrdiff;
206
207 powerBase0 = powerBase0 << 24 | powerBase0 << 16 |
208 powerBase0 << 8 | powerBase0;
209 *(OfdmBase + i) = powerBase0;
210 }
211
212 for (i = 0; i < 2; i++) {
213
214 if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20) {
215 HT20_pwrdiff = pHalData->TxPwrHt20Diff[i][Channel-1];
216 powerlevel[i] += HT20_pwrdiff;
217 }
218 powerBase1 = powerlevel[i];
219 powerBase1 = powerBase1 << 24 | powerBase1 << 16 |
220 powerBase1 << 8 | powerBase1;
221 *(MCSBase + i) = powerBase1;
222 }
223}
224
225static void
226getTxPowerWriteValByRegulatory(struct rtw_adapter *Adapter, u8 Channel,
227 u8 index, u32 *powerBase0, u32 *powerBase1,
228 u32 *pOutWriteVal)
229{
230 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
231 struct dm_priv *pdmpriv = &pHalData->dmpriv;
232 u8 i, chnlGroup = 0, pwr_diff_limit[4];
233 u32 writeVal, customer_limit, rf;
234
235
236 for (rf = 0; rf < 2; rf++) {
237 switch (pHalData->EEPROMRegulatory) {
238 case 0:
239
240
241 chnlGroup = 0;
242 writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] +
243 ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
244 break;
245 case 1:
246
247
248 if (pHalData->pwrGroupCnt == 1)
249 chnlGroup = 0;
250 if (pHalData->pwrGroupCnt >= 3) {
251 if (Channel <= 3)
252 chnlGroup = 0;
253 else if (Channel >= 4 && Channel <= 9)
254 chnlGroup = 1;
255 else if (Channel > 9)
256 chnlGroup = 2;
257
258 if (pHalData->CurrentChannelBW ==
259 HT_CHANNEL_WIDTH_20)
260 chnlGroup++;
261 else
262 chnlGroup += 4;
263 }
264 writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] +
265 ((index < 2) ? powerBase0[rf] :
266 powerBase1[rf]);
267 break;
268 case 2:
269
270 writeVal = ((index < 2) ? powerBase0[rf] :
271 powerBase1[rf]);
272 break;
273 case 3:
274 chnlGroup = 0;
275
276 for (i = 0; i < 4; i++) {
277 pwr_diff_limit[i] = (u8)((pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index +
278 (rf ? 8 : 0)]&(0x7f << (i*8))) >> (i*8));
279 if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_40) {
280 if (pwr_diff_limit[i] > pHalData->PwrGroupHT40[rf][Channel-1])
281 pwr_diff_limit[i] = pHalData->PwrGroupHT40[rf][Channel-1];
282 } else {
283 if (pwr_diff_limit[i] > pHalData->PwrGroupHT20[rf][Channel-1])
284 pwr_diff_limit[i] = pHalData->PwrGroupHT20[rf][Channel-1];
285 }
286 }
287 customer_limit = (pwr_diff_limit[3]<<24) | (pwr_diff_limit[2]<<16) |
288 (pwr_diff_limit[1]<<8) | (pwr_diff_limit[0]);
289 writeVal = customer_limit + ((index<2)?powerBase0[rf]:powerBase1[rf]);
290 break;
291 default:
292 chnlGroup = 0;
293 writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] +
294 ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
295 break;
296 }
297
298
299
300
301
302
303
304
305 if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1)
306 writeVal = 0x14141414;
307 else if (pdmpriv->DynamicTxHighPowerLvl ==
308 TxHighPwrLevel_Level2)
309 writeVal = 0x00000000;
310
311
312
313
314 if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_BT1)
315 writeVal = writeVal - 0x06060606;
316 else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_BT2)
317 writeVal = writeVal;
318 *(pOutWriteVal + rf) = writeVal;
319 }
320}
321
322static void writeOFDMPowerReg(struct rtw_adapter *Adapter, u8 index,
323 u32 *pValue)
324{
325 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
326 u16 RegOffset_A[6] = {
327 rTxAGC_A_Rate18_06, rTxAGC_A_Rate54_24,
328 rTxAGC_A_Mcs03_Mcs00, rTxAGC_A_Mcs07_Mcs04,
329 rTxAGC_A_Mcs11_Mcs08, rTxAGC_A_Mcs15_Mcs12
330 };
331 u16 RegOffset_B[6] = {
332 rTxAGC_B_Rate18_06, rTxAGC_B_Rate54_24,
333 rTxAGC_B_Mcs03_Mcs00, rTxAGC_B_Mcs07_Mcs04,
334 rTxAGC_B_Mcs11_Mcs08, rTxAGC_B_Mcs15_Mcs12
335 };
336 u8 i, rf, pwr_val[4];
337 u32 writeVal;
338 u16 RegOffset;
339
340 for (rf = 0; rf < 2; rf++) {
341 writeVal = pValue[rf];
342 for (i = 0; i < 4; i++) {
343 pwr_val[i] = (u8)((writeVal &
344 (0x7f << (i * 8))) >> (i * 8));
345 if (pwr_val[i] > RF6052_MAX_TX_PWR)
346 pwr_val[i] = RF6052_MAX_TX_PWR;
347 }
348 writeVal = pwr_val[3] << 24 | pwr_val[2] << 16 |
349 pwr_val[1] << 8 | pwr_val[0];
350
351 if (rf == 0)
352 RegOffset = RegOffset_A[index];
353 else
354 RegOffset = RegOffset_B[index];
355
356 PHY_SetBBReg(Adapter, RegOffset, bMaskDWord, writeVal);
357
358
359
360 if (((pHalData->rf_type == RF_2T2R) &&
361 (RegOffset == rTxAGC_A_Mcs15_Mcs12 ||
362 RegOffset == rTxAGC_B_Mcs15_Mcs12)) ||
363 ((pHalData->rf_type != RF_2T2R) &&
364 (RegOffset == rTxAGC_A_Mcs07_Mcs04 ||
365 RegOffset == rTxAGC_B_Mcs07_Mcs04))) {
366 writeVal = pwr_val[3];
367 if (RegOffset == rTxAGC_A_Mcs15_Mcs12 ||
368 RegOffset == rTxAGC_A_Mcs07_Mcs04)
369 RegOffset = 0xc90;
370 if (RegOffset == rTxAGC_B_Mcs15_Mcs12 ||
371 RegOffset == rTxAGC_B_Mcs07_Mcs04)
372 RegOffset = 0xc98;
373 for (i = 0; i < 3; i++) {
374 if (i != 2)
375 writeVal = (writeVal > 8) ?
376 (writeVal - 8) : 0;
377 else
378 writeVal = (writeVal > 6) ?
379 (writeVal - 6) : 0;
380 rtl8723au_write8(Adapter, RegOffset + i,
381 (u8)writeVal);
382 }
383 }
384 }
385}
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410void rtl8723a_PHY_RF6052SetOFDMTxPower(struct rtw_adapter *Adapter,
411 u8 *pPowerLevel, u8 Channel)
412{
413 u32 writeVal[2], powerBase0[2], powerBase1[2];
414 u8 index = 0;
415
416 getPowerBase(Adapter, pPowerLevel, Channel,
417 &powerBase0[0], &powerBase1[0]);
418
419 for (index = 0; index < 6; index++) {
420 getTxPowerWriteValByRegulatory(Adapter, Channel, index,
421 &powerBase0[0], &powerBase1[0], &writeVal[0]);
422
423 writeOFDMPowerReg(Adapter, index, &writeVal[0]);
424 }
425}
426
427static int phy_RF6052_Config_ParaFile(struct rtw_adapter *Adapter)
428{
429 u32 u4RegValue = 0;
430 u8 eRFPath;
431 struct bb_reg_define *pPhyReg;
432 int rtStatus = _SUCCESS;
433 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
434
435
436
437
438 for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) {
439
440 pPhyReg = &pHalData->PHYRegDef[eRFPath];
441
442
443 switch (eRFPath) {
444 case RF_PATH_A:
445 u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs,
446 bRFSI_RFENV);
447 break;
448 case RF_PATH_B:
449 u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs,
450 bRFSI_RFENV << 16);
451 break;
452 }
453
454
455 PHY_SetBBReg(Adapter, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1);
456 udelay(1);
457
458
459 PHY_SetBBReg(Adapter, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
460 udelay(1);
461
462
463 PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireAddressLength,
464 0x0);
465 udelay(1);
466
467 PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireDataLength,
468 0x0);
469 udelay(1);
470
471
472 switch (eRFPath) {
473 case RF_PATH_A:
474 ODM_ReadAndConfig_RadioA_1T_8723A(&pHalData->odmpriv);
475 break;
476 case RF_PATH_B:
477 break;
478 }
479
480 ;
481 switch (eRFPath) {
482 case RF_PATH_A:
483 PHY_SetBBReg(Adapter, pPhyReg->rfintfs,
484 bRFSI_RFENV, u4RegValue);
485 break;
486 case RF_PATH_B:
487 PHY_SetBBReg(Adapter, pPhyReg->rfintfs,
488 bRFSI_RFENV << 16, u4RegValue);
489 break;
490 }
491
492 if (rtStatus != _SUCCESS) {
493 goto phy_RF6052_Config_ParaFile_Fail;
494 }
495 }
496phy_RF6052_Config_ParaFile_Fail:
497 return rtStatus;
498}
499
500int PHY_RF6052_Config8723A(struct rtw_adapter *Adapter)
501{
502 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
503 int rtStatus = _SUCCESS;
504
505
506
507 if (pHalData->rf_type == RF_1T1R)
508 pHalData->NumTotalRFPath = 1;
509 else
510 pHalData->NumTotalRFPath = 2;
511
512
513 rtStatus = phy_RF6052_Config_ParaFile(Adapter);
514 return rtStatus;
515}
516
517
518