1 /******************************************************************************
2 *
3 * Copyright(c) 2016 - 2017 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 *****************************************************************************/
15 #define _RTL8821C_PHY_C_
16
17 #include <hal_data.h> /* HAL_DATA_TYPE */
18 #include "../hal_halmac.h" /* REG_CCK_CHECK_8821C */
19 #include "rtl8821c.h"
20
21
22 /*
23 * Description:
24 * Initialize Register definition offset for Radio Path A/B/C/D
25 * The initialization value is constant and it should never be changes
26 */
bb_rf_register_definition(PADAPTER adapter)27 static void bb_rf_register_definition(PADAPTER adapter)
28 {
29 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
30
31
32 /* RF Interface Sowrtware Control */
33 hal->PHYRegDef[RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW;
34 hal->PHYRegDef[RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW;
35
36 /* RF Interface Output (and Enable) */
37 hal->PHYRegDef[RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE;
38 hal->PHYRegDef[RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE;
39
40 /* RF Interface (Output and) Enable */
41 hal->PHYRegDef[RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE;
42 hal->PHYRegDef[RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE;
43
44 hal->PHYRegDef[RF_PATH_A].rf3wireOffset = rA_LSSIWrite_Jaguar;
45 hal->PHYRegDef[RF_PATH_B].rf3wireOffset = rB_LSSIWrite_Jaguar;
46
47 hal->PHYRegDef[RF_PATH_A].rfHSSIPara2 = rHSSIRead_Jaguar;
48 hal->PHYRegDef[RF_PATH_B].rfHSSIPara2 = rHSSIRead_Jaguar;
49
50 /* Tranceiver Readback LSSI/HSPI mode */
51 hal->PHYRegDef[RF_PATH_A].rfLSSIReadBack = rA_SIRead_Jaguar;
52 hal->PHYRegDef[RF_PATH_B].rfLSSIReadBack = rB_SIRead_Jaguar;
53 hal->PHYRegDef[RF_PATH_A].rfLSSIReadBackPi = rA_PIRead_Jaguar;
54 hal->PHYRegDef[RF_PATH_B].rfLSSIReadBackPi = rB_PIRead_Jaguar;
55 }
56
init_bb_rf(PADAPTER adapter)57 static void init_bb_rf(PADAPTER adapter)
58 {
59 u8 val8;
60 u16 val16;
61
62
63 /* Enable BB and RF */
64 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN_8821C);
65 if (IS_HARDWARE_TYPE_8821CU(adapter))
66 val8 |= BIT_FEN_USBA_8821C;
67 else if (IS_HARDWARE_TYPE_8821CE(adapter))
68 val8 |= BIT_FEN_PCIEA_8821C;
69 rtw_write8(adapter, REG_SYS_FUNC_EN_8821C, val8);
70
71 /*
72 * 8821C MP Chip => Reset BB/RF ??
73 * Need to set BBRSTB and GLB_RSTB = 1->0->1 to generate a postive edge and negtive edge for BB
74 */
75 val8 |= BIT_FEN_BB_GLB_RSTN_8821C | BIT_FEN_BBRSTB_8821C;
76 rtw_write8(adapter, REG_SYS_FUNC_EN_8821C, val8);
77 val8 &= ~(BIT_FEN_BB_GLB_RSTN_8821C | BIT_FEN_BBRSTB_8821C);
78 rtw_write8(adapter, REG_SYS_FUNC_EN_8821C, val8);
79 val8 |= BIT_FEN_BB_GLB_RSTN_8821C | BIT_FEN_BBRSTB_8821C;
80 rtw_write8(adapter, REG_SYS_FUNC_EN_8821C, val8);
81
82 val8 = BIT_RF_EN_8821C | BIT_RF_RSTB_8821C | BIT_RF_SDMRSTB_8821C;
83 /* 0x1F[7:0] = 0x07 PathA RF Power On */
84 rtw_write8(adapter, REG_RF_CTRL_8821C, val8);
85 rtw_usleep_os(10);
86
87 /*0xEC [31:24],BIT_WLRF1_CTRL, For WLRF1 control*/
88 /* 0xEF[7:0] = 0x07 for RFE Type=2,BTG RF Power On*/
89 rtw_write8(adapter, REG_WLRF1_8821C + 3, val8);
90 rtw_usleep_os(10);
91
92 }
93
rtl8821c_init_phy_parameter_mac(PADAPTER adapter)94 u8 rtl8821c_init_phy_parameter_mac(PADAPTER adapter)
95 {
96 u8 ret = _FAIL;
97 PHAL_DATA_TYPE hal;
98
99 hal = GET_HAL_DATA(adapter);
100
101 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
102 ret = phy_ConfigMACWithParaFile(adapter, PHY_FILE_MAC_REG);
103 if (ret == _FAIL)
104 #endif /* CONFIG_LOAD_PHY_PARA_FROM_FILE */
105 {
106 odm_config_mac_with_header_file(&hal->odmpriv);
107 ret = _SUCCESS;
108 }
109
110 return ret;
111 }
112
_init_phy_parameter_bb(PADAPTER Adapter)113 static u8 _init_phy_parameter_bb(PADAPTER Adapter)
114 {
115 PHAL_DATA_TYPE hal = GET_HAL_DATA(Adapter);
116 u8 ret = _TRUE;
117 int res;
118 enum hal_status status;
119
120
121 /*
122 * 1. Read PHY_REG.TXT BB INIT!!
123 */
124 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
125 res = phy_ConfigBBWithParaFile(Adapter, PHY_FILE_PHY_REG, CONFIG_BB_PHY_REG);
126 if (res == _FAIL)
127 #endif
128 {
129 ret = _FALSE;
130 status = odm_config_bb_with_header_file(&hal->odmpriv, CONFIG_BB_PHY_REG);
131 if (HAL_STATUS_SUCCESS == status)
132 ret = _TRUE;
133 }
134
135 if (ret != _TRUE) {
136 RTW_INFO("%s: Write BB Reg Fail!!", __FUNCTION__);
137 goto exit;
138 }
139
140 #ifdef CONFIG_MP_INCLUDED
141 if (Adapter->registrypriv.mp_mode == 1) {
142 /*
143 * 1.1 Read PHY_REG_MP.TXT BB INIT!!
144 */
145 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
146 res = phy_ConfigBBWithMpParaFile(Adapter, PHY_FILE_PHY_REG_MP);
147 if (res == _FAIL)
148 #endif
149 {
150 ret = _FALSE;
151 status = odm_config_bb_with_header_file(&hal->odmpriv, CONFIG_BB_PHY_REG_MP);
152 if (HAL_STATUS_SUCCESS == status)
153 ret = _TRUE;
154 }
155
156 if (ret != _TRUE) {
157 RTW_INFO("%s : Write BB Reg MP Fail!!", __FUNCTION__);
158 goto exit;
159 }
160 }
161 #endif /* CONFIG_MP_INCLUDED */
162
163 /*
164 * 2. Read BB AGC table Initialization
165 */
166 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
167 res = phy_ConfigBBWithParaFile(Adapter, PHY_FILE_AGC_TAB, CONFIG_BB_AGC_TAB);
168 if (res == _FAIL)
169 #endif
170 {
171 ret = _FALSE;
172 status = odm_config_bb_with_header_file(&hal->odmpriv, CONFIG_BB_AGC_TAB);
173 if (HAL_STATUS_SUCCESS == status)
174 ret = _TRUE;
175 }
176
177 if (ret != _TRUE) {
178 RTW_INFO("%s: AGC Table Fail\n", __FUNCTION__);
179 goto exit;
180 }
181
182 exit:
183 return ret;
184 }
185
init_bb_reg(PADAPTER adapter)186 static u8 init_bb_reg(PADAPTER adapter)
187 {
188 u8 ret = _TRUE;
189 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
190
191
192 /*
193 * Config BB and AGC
194 */
195 ret = _init_phy_parameter_bb(adapter);
196
197 if (rtw_phydm_set_crystal_cap(adapter, hal->crystal_cap) == _FALSE) {
198 RTW_ERR("Init crystal_cap failed\n");
199 rtw_warn_on(1);
200 ret = _FALSE;
201 }
202
203 phy_set_bb_reg(adapter, rCCK0_FalseAlarmReport, BIT18 | BIT22, 0);
204 return ret;
205 }
206
_init_phy_parameter_rf(PADAPTER adapter)207 static u8 _init_phy_parameter_rf(PADAPTER adapter)
208 {
209 u32 val32 = 0;
210 enum rf_path eRFPath;
211 PBB_REGISTER_DEFINITION_T pPhyReg;
212 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
213 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
214 enum hal_status status;
215 int res;
216 u8 ret = _TRUE;
217
218
219 /*
220 * Initialize RF
221 */
222 for (eRFPath = RF_PATH_A; eRFPath < hal_spec->rf_reg_path_num; eRFPath++) {
223 pPhyReg = &hal->PHYRegDef[eRFPath];
224
225 /* Initialize RF from configuration file */
226 switch (eRFPath) {
227 case RF_PATH_A:
228 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
229 res = PHY_ConfigRFWithParaFile(adapter, PHY_FILE_RADIO_A, eRFPath);
230 if (res == _FAIL)
231 #endif
232 {
233 ret = _FALSE;
234 status = odm_config_rf_with_header_file(&hal->odmpriv, CONFIG_RF_RADIO, eRFPath);
235 if (HAL_STATUS_SUCCESS == status)
236 ret = _TRUE;
237 }
238 break;
239 case RF_PATH_B:
240 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
241 res = PHY_ConfigRFWithParaFile(adapter, PHY_FILE_RADIO_B, eRFPath);
242 if (res == _FAIL)
243 #endif
244 {
245 ret = _FALSE;
246 status = odm_config_rf_with_header_file(&hal->odmpriv, CONFIG_RF_RADIO, eRFPath);
247 if (HAL_STATUS_SUCCESS == status)
248 ret = _TRUE;
249 }
250 break;
251 default:
252 RTW_INFO("Unknown RF path!! %d\r\n", eRFPath);
253 break;
254 }
255
256 if (ret != _TRUE)
257 goto exit;
258 }
259
260 /*
261 * Configuration of Tx Power Tracking
262 */
263 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
264 res = PHY_ConfigRFWithTxPwrTrackParaFile(adapter, PHY_FILE_TXPWR_TRACK);
265 if (res == _FAIL)
266 #endif
267 {
268 ret = _FALSE;
269 status = odm_config_rf_with_tx_pwr_track_header_file(&hal->odmpriv);
270 if (HAL_STATUS_SUCCESS == status)
271 ret = _TRUE;
272 }
273 if (ret != _TRUE)
274 goto exit;
275
276 exit:
277 return ret;
278 }
279
init_rf_reg(PADAPTER adapter)280 static u8 init_rf_reg(PADAPTER adapter)
281 {
282 u8 ret = _TRUE;
283
284
285 ret = _init_phy_parameter_rf(adapter);
286
287 return ret;
288 }
rtl8821c_phy_init(PADAPTER adapter)289 u8 rtl8821c_phy_init(PADAPTER adapter)
290 {
291 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
292 struct dm_struct *phydm = &hal->odmpriv;
293
294 bb_rf_register_definition(adapter);
295
296 init_bb_rf(adapter);
297
298 if (_FALSE == config_phydm_parameter_init_8821c(phydm, ODM_PRE_SETTING))
299 return _FALSE;
300
301 if (_FALSE == init_bb_reg(adapter))
302 return _FALSE;
303
304 if (_FALSE == init_rf_reg(adapter))
305 return _FALSE;
306
307 if (_FALSE == config_phydm_parameter_init_8821c(phydm, ODM_POST_SETTING))
308 return _FALSE;
309
310 hal->phy_spec.trx_cap = query_phydm_trx_capability(phydm);
311 hal->phy_spec.stbc_cap = query_phydm_stbc_capability(phydm);
312 hal->phy_spec.ldpc_cap = query_phydm_ldpc_capability(phydm);
313 hal->phy_spec.txbf_param = query_phydm_txbf_parameters(phydm);
314 hal->phy_spec.txbf_cap = query_phydm_txbf_capability(phydm);
315 /*rtw_dump_phy_cap(RTW_DBGDUMP, adapter);*/
316 return _TRUE;
317 }
318
phy_calculatebitshift(u32 mask)319 static u32 phy_calculatebitshift(u32 mask)
320 {
321 u32 i;
322
323
324 for (i = 0; i <= 31; i++)
325 if (mask & BIT(i))
326 break;
327
328 return i;
329 }
330
rtl8821c_read_bb_reg(PADAPTER adapter,u32 addr,u32 mask)331 u32 rtl8821c_read_bb_reg(PADAPTER adapter, u32 addr, u32 mask)
332 {
333 u32 val = 0, val_org, shift;
334
335
336 #if (DISABLE_BB_RF == 1)
337 return 0;
338 #endif
339
340 val_org = rtw_read32(adapter, addr);
341 shift = phy_calculatebitshift(mask);
342 val = (val_org & mask) >> shift;
343
344 return val;
345 }
346
rtl8821c_write_bb_reg(PADAPTER adapter,u32 addr,u32 mask,u32 val)347 void rtl8821c_write_bb_reg(PADAPTER adapter, u32 addr, u32 mask, u32 val)
348 {
349 u32 val_org, shift;
350
351
352 #if (DISABLE_BB_RF == 1)
353 return;
354 #endif
355
356 if (mask != 0xFFFFFFFF) {
357 /* not "double word" write */
358 val_org = rtw_read32(adapter, addr);
359 shift = phy_calculatebitshift(mask);
360 val = ((val_org & (~mask)) | ((val << shift) & mask));
361 }
362
363 rtw_write32(adapter, addr, val);
364 }
365
rtl8821c_read_rf_reg(PADAPTER adapter,enum rf_path path,u32 addr,u32 mask)366 u32 rtl8821c_read_rf_reg(PADAPTER adapter, enum rf_path path, u32 addr, u32 mask)
367 {
368 struct dm_struct *phydm = adapter_to_phydm(adapter);
369 u32 val = 0;
370
371 val = config_phydm_read_rf_reg_8821c(phydm, path, addr, mask);
372 if (!config_phydm_read_rf_check_8821c(val))
373 RTW_INFO(FUNC_ADPT_FMT ": read RF reg path=%d addr=0x%x mask=0x%x FAIL!\n",
374 FUNC_ADPT_ARG(adapter), path, addr, mask);
375 return val;
376 }
377
rtl8821c_write_rf_reg(PADAPTER adapter,enum rf_path path,u32 addr,u32 mask,u32 val)378 void rtl8821c_write_rf_reg(PADAPTER adapter, enum rf_path path, u32 addr, u32 mask, u32 val)
379 {
380 struct dm_struct *phydm = adapter_to_phydm(adapter);
381 u8 ret;
382
383 ret = config_phydm_write_rf_reg_8821c(phydm, path, addr, mask, val);
384 if (_FALSE == ret)
385 RTW_INFO(FUNC_ADPT_FMT ": write RF reg path=%d addr=0x%x mask=0x%x val=0x%x FAIL!\n",
386 FUNC_ADPT_ARG(adapter), path, addr, mask, val);
387
388 }
389
rtl8821c_set_tx_power_level(PADAPTER adapter,u8 channel)390 void rtl8821c_set_tx_power_level(PADAPTER adapter, u8 channel)
391 {
392 u8 path = RF_PATH_A;
393 struct dm_struct *phydm = adapter_to_phydm(adapter);
394 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
395 u8 under_survey_ch = phy_check_under_survey_ch(adapter);
396 u8 under_24g = (hal->current_band_type == BAND_ON_2_4G);
397
398 /*((hal->RFEType == 2) || (hal->RFEType == 4) || (hal->RFEType == 7))*/
399 if ((channel <= 14) && (SWITCH_TO_BTG == query_phydm_default_rf_set_8821c(phydm)))
400 path = RF_PATH_B;
401
402 /*if (adapter->registrypriv.mp_mode == 1)*/
403 if (under_24g)
404 phy_set_tx_power_index_by_rate_section(adapter, path, channel, CCK);
405
406 phy_set_tx_power_index_by_rate_section(adapter, path, channel, OFDM);
407 if (!under_survey_ch) {
408 phy_set_tx_power_index_by_rate_section(adapter, path, channel, HT_MCS0_MCS7);
409 phy_set_tx_power_index_by_rate_section(adapter, path, channel, VHT_1SSMCS0_1SSMCS9);
410 }
411 }
412
413 /*
414 * Parameters:
415 * padatper
416 * powerindex power index for rate
417 * rfpath Antenna(RF) path, type "enum rf_path"
418 * rate data rate, type "enum MGN_RATE"
419 */
rtl8821c_set_tx_power_index(PADAPTER adapter,u32 powerindex,enum rf_path rfpath,u8 rate)420 void rtl8821c_set_tx_power_index(PADAPTER adapter, u32 powerindex, enum rf_path rfpath, u8 rate)
421 {
422 HAL_DATA_TYPE *hal = GET_HAL_DATA(adapter);
423 struct dm_struct *phydm = adapter_to_phydm(adapter);
424 u8 reg_path;
425 u8 shift = 0;
426 boolean write_ret;
427
428 if (!IS_1T_RATE(rate)) {
429 RTW_ERR(FUNC_ADPT_FMT" invalid rate(%s)\n", FUNC_ADPT_ARG(adapter), MGN_RATE_STR(rate));
430 rtw_warn_on(1);
431 goto exit;
432 }
433
434 /* For phydm error handling we have to pass RF_PATH_A to the phydm API,
435 * although some RFE types of 2.4G use RF_PATH_B.
436 */
437 reg_path = RF_PATH_A;
438 rate = MRateToHwRate(rate);
439
440 /*
441 * For 8821C, phydm api use 4 bytes txagc value
442 * driver must combine every four 1 byte to one 4 byte and send to phydm api
443 */
444 shift = rate % 4;
445 hal->txagc_set_buf |= ((powerindex & 0xff) << (shift * 8));
446
447 if (shift != 3 && rate != DESC_RATEVHTSS1MCS9)
448 goto exit;
449
450 rate = rate & 0xFC;
451 write_ret = config_phydm_write_txagc_8821c(phydm, hal->txagc_set_buf, reg_path, rate);
452
453 if (write_ret == true && !DBG_TX_POWER_IDX)
454 goto clear_buf;
455
456 RTW_INFO(FUNC_ADPT_FMT" (index:0x%08x, %c, rate:%s(0x%02x), disable api:%d) from %c %s\n"
457 , FUNC_ADPT_ARG(adapter), hal->txagc_set_buf, rf_path_char(reg_path)
458 , HDATA_RATE(rate), rate, phydm->is_disable_phy_api
459 , rf_path_char(rfpath)
460 , write_ret == true ? "OK" : "FAIL");
461
462 rtw_warn_on(write_ret != true);
463
464 clear_buf:
465 hal->txagc_set_buf = 0;
466
467 exit:
468 return;
469 }
470
471 /*
472 * Description:
473 * Check need to switch band or not
474 * Parameters:
475 * channelToSW channel wiii be switch to
476 * Return:
477 * _TRUE need to switch band
478 * _FALSE not need to switch band
479 */
need_switch_band(PADAPTER adapter,u8 channelToSW)480 static u8 need_switch_band(PADAPTER adapter, u8 channelToSW)
481 {
482 u8 u1tmp = 0;
483 u8 ret_value = _TRUE;
484 u8 Band = BAND_ON_5G, BandToSW = BAND_ON_5G;
485 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
486
487 Band = hal->current_band_type;
488
489 /* Use current swich channel to judge Band Type and switch Band if need */
490 if (channelToSW > 14)
491 BandToSW = BAND_ON_5G;
492 else
493 BandToSW = BAND_ON_2_4G;
494
495 if (BandToSW != Band) {
496 /* record current band type for other hal use */
497 hal->current_band_type = (BAND_TYPE)BandToSW;
498 ret_value = _TRUE;
499 } else
500 ret_value = _FALSE;
501
502 return ret_value;
503 }
504
get_pri_ch_id(PADAPTER adapter)505 static u8 get_pri_ch_id(PADAPTER adapter)
506 {
507 u8 pri_ch_idx = 0;
508 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
509
510 if (hal->current_channel_bw == CHANNEL_WIDTH_80) {
511 /* primary channel is at lower subband of 80MHz & 40MHz */
512 if ((hal->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (hal->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
513 pri_ch_idx = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
514 /* primary channel is at lower subband of 80MHz & upper subband of 40MHz */
515 else if ((hal->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (hal->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
516 pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ;
517 /* primary channel is at upper subband of 80MHz & lower subband of 40MHz */
518 else if ((hal->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (hal->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
519 pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ;
520 /* primary channel is at upper subband of 80MHz & upper subband of 40MHz */
521 else if ((hal->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (hal->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
522 pri_ch_idx = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
523 else {
524 if (hal->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
525 pri_ch_idx = VHT_DATA_SC_40_LOWER_OF_80MHZ;
526 else if (hal->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
527 pri_ch_idx = VHT_DATA_SC_40_UPPER_OF_80MHZ;
528 else
529 RTW_INFO("SCMapping: DONOT CARE Mode Setting\n");
530 }
531 } else if (hal->current_channel_bw == CHANNEL_WIDTH_40) {
532 /* primary channel is at upper subband of 40MHz */
533 if (hal->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
534 pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ;
535 /* primary channel is at lower subband of 40MHz */
536 else if (hal->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
537 pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ;
538 else
539 RTW_INFO("SCMapping: DONOT CARE Mode Setting\n");
540 }
541
542 return pri_ch_idx;
543 }
544
mac_switch_bandwidth(PADAPTER adapter,u8 pri_ch_idx)545 static void mac_switch_bandwidth(PADAPTER adapter, u8 pri_ch_idx)
546 {
547 u8 channel = 0, bw = 0;
548 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
549 int err;
550
551 channel = hal->current_channel;
552 bw = hal->current_channel_bw;
553 err = rtw_halmac_set_bandwidth(adapter_to_dvobj(adapter), channel, pri_ch_idx, bw);
554 if (err) {
555 RTW_INFO(FUNC_ADPT_FMT ": (channel=%d, pri_ch_idx=%d, bw=%d) fail\n",
556 FUNC_ADPT_ARG(adapter), channel, pri_ch_idx, bw);
557 }
558 }
phy_get_tx_bbswing_8821c(_adapter * adapter,BAND_TYPE band,u8 rf_path)559 u32 phy_get_tx_bbswing_8821c(_adapter *adapter, BAND_TYPE band, u8 rf_path)
560 {
561 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
562 struct dm_struct *pDM_Odm = &pHalData->odmpriv;
563 struct dm_rf_calibration_struct *pRFCalibrateInfo = &(pDM_Odm->rf_calibrate_info);
564 s8 bbSwing_2G = -1 * GetRegTxBBSwing_2G(adapter);
565 s8 bbSwing_5G = -1 * GetRegTxBBSwing_5G(adapter);
566 u32 out = 0x200;
567 const s8 AUTO = -1;
568
569 if (pHalData->bautoload_fail_flag) {
570 if (band == BAND_ON_2_4G) {
571 pRFCalibrateInfo->bb_swing_diff_2g = bbSwing_2G;
572 if (bbSwing_2G == 0)
573 out = 0x200; /* 0 dB */
574 else if (bbSwing_2G == -3)
575 out = 0x16A; /* -3 dB */
576 else if (bbSwing_2G == -6)
577 out = 0x101; /* -6 dB */
578 else if (bbSwing_2G == -9)
579 out = 0x0B6; /* -9 dB */
580 else {
581 if (pHalData->ExternalPA_2G) {
582 pRFCalibrateInfo->bb_swing_diff_2g = -3;
583 out = 0x16A;
584 } else {
585 pRFCalibrateInfo->bb_swing_diff_2g = 0;
586 out = 0x200;
587 }
588 }
589 } else if (band == BAND_ON_5G) {
590 pRFCalibrateInfo->bb_swing_diff_5g = bbSwing_5G;
591 if (bbSwing_5G == 0)
592 out = 0x200; /* 0 dB */
593 else if (bbSwing_5G == -3)
594 out = 0x16A; /* -3 dB */
595 else if (bbSwing_5G == -6)
596 out = 0x101; /* -6 dB */
597 else if (bbSwing_5G == -9)
598 out = 0x0B6; /* -9 dB */
599 else {
600 if (pHalData->external_pa_5g) {
601 pRFCalibrateInfo->bb_swing_diff_5g = -3;
602 out = 0x16A;
603 } else {
604 pRFCalibrateInfo->bb_swing_diff_5g = 0;
605 out = 0x200;
606 }
607 }
608 } else {
609 pRFCalibrateInfo->bb_swing_diff_2g = -3;
610 pRFCalibrateInfo->bb_swing_diff_5g = -3;
611 out = 0x16A; /* -3 dB */
612 }
613 } else {
614 u32 swing = 0, onePathSwing = 0;
615
616 if (band == BAND_ON_2_4G) {
617 if (GetRegTxBBSwing_2G(adapter) == AUTO)
618 swing = pHalData->tx_bbswing_24G;
619 else if (bbSwing_2G == 0)
620 swing = 0x00; /* 0 dB */
621 else if (bbSwing_2G == -3)
622 swing = 0x55; /* -3 dB */
623 else if (bbSwing_2G == -6)
624 swing = 0xAA; /* -6 dB */
625 else if (bbSwing_2G == -9)
626 swing = 0xFF; /* -9 dB */
627 else
628 swing = 0x00;
629 } else {
630 if (GetRegTxBBSwing_5G(adapter) == AUTO)
631 swing = pHalData->tx_bbswing_5G;
632 else if (bbSwing_5G == 0)
633 swing = 0x00; /* 0 dB */
634 else if (bbSwing_5G == -3)
635 swing = 0x55; /* -3 dB */
636 else if (bbSwing_5G == -6)
637 swing = 0xAA; /* -6 dB */
638 else if (bbSwing_5G == -9)
639 swing = 0xFF; /* -9 dB */
640 else
641 swing = 0x00;
642 }
643
644 if (rf_path == RF_PATH_A)
645 onePathSwing = (swing & 0x3) >> 0; /* 0xC6/C7[1:0] */
646
647 if (onePathSwing == 0x0) {
648 if (band == BAND_ON_2_4G)
649 pRFCalibrateInfo->bb_swing_diff_2g = 0;
650 else
651 pRFCalibrateInfo->bb_swing_diff_5g = 0;
652 out = 0x200; /* 0 dB */
653 } else if (onePathSwing == 0x1) {
654 if (band == BAND_ON_2_4G)
655 pRFCalibrateInfo->bb_swing_diff_2g = -3;
656 else
657 pRFCalibrateInfo->bb_swing_diff_5g = -3;
658 out = 0x16A; /* -3 dB */
659 } else if (onePathSwing == 0x2) {
660 if (band == BAND_ON_2_4G)
661 pRFCalibrateInfo->bb_swing_diff_2g = -6;
662 else
663 pRFCalibrateInfo->bb_swing_diff_5g = -6;
664 out = 0x101; /* -6 dB */
665 } else if (onePathSwing == 0x3) {
666 if (band == BAND_ON_2_4G)
667 pRFCalibrateInfo->bb_swing_diff_2g = -9;
668 else
669 pRFCalibrateInfo->bb_swing_diff_5g = -9;
670 out = 0x0B6; /* -9 dB */
671 }
672 }
673
674 /* RTW_INFO("<=== PHY_GetTxBBSwing_8812C, out = 0x%X\n", out); */
675
676 return out;
677 }
678
phy_set_bb_swing_by_band_8821c(_adapter * adapter,u8 band,u8 previous_band)679 void phy_set_bb_swing_by_band_8821c(_adapter *adapter, u8 band, u8 previous_band)
680 {
681 s8 BBDiffBetweenBand = 0;
682 struct dm_struct *pDM_Odm = adapter_to_phydm(adapter);
683 struct dm_rf_calibration_struct *pRFCalibrateInfo = &(pDM_Odm->rf_calibrate_info);
684
685 phy_set_bb_reg(adapter, rA_TxScale_Jaguar, 0xFFE00000,
686 phy_get_tx_bbswing_8821c(adapter, (BAND_TYPE)band, RF_PATH_A)); /* 0xC1C[31:21] */
687
688 /* When TxPowerTrack is ON, we should take care of the change of BB swing. */
689 /* That is, reset all info to trigger Tx power tracking. */
690 {
691
692 if (band != previous_band) {
693 BBDiffBetweenBand = (pRFCalibrateInfo->bb_swing_diff_2g - pRFCalibrateInfo->bb_swing_diff_5g);
694 BBDiffBetweenBand = (band == BAND_ON_2_4G) ? BBDiffBetweenBand : (-1 * BBDiffBetweenBand);
695 pRFCalibrateInfo->default_ofdm_index += BBDiffBetweenBand * 2;
696 }
697
698 odm_clear_txpowertracking_state(pDM_Odm);
699 }
700
701 }
702
phy_switch_wireless_band_8821c(_adapter * adapter)703 void phy_switch_wireless_band_8821c(_adapter *adapter)
704 {
705 u8 ret = 0;
706 PHAL_DATA_TYPE hal_data = GET_HAL_DATA(adapter);
707 struct dm_struct *pDM_Odm = &hal_data->odmpriv;
708 u8 current_band = hal_data->current_band_type;
709
710 if (need_switch_band(adapter, hal_data->current_channel) == _TRUE) {
711 #ifdef CONFIG_BT_COEXIST
712 if (hal_data->EEPROMBluetoothCoexist) {
713 struct mlme_ext_priv *mlmeext;
714
715 /* switch band under site survey or not, must notify to BT COEX */
716 mlmeext = &adapter->mlmeextpriv;
717 if (mlmeext_scan_state(mlmeext) != SCAN_DISABLE)
718 rtw_btcoex_switchband_notify(_TRUE, hal_data->current_band_type);
719 else
720 rtw_btcoex_switchband_notify(_FALSE, hal_data->current_band_type);
721 } else
722 rtw_btcoex_wifionly_switchband_notify(adapter);
723 #else /* !CONFIG_BT_COEXIST */
724 rtw_btcoex_wifionly_switchband_notify(adapter);
725 #endif /* CONFIG_BT_COEXIST */
726
727 /* hal->current_channel is center channel of pmlmeext->cur_channel(primary channel) */
728 ret = config_phydm_switch_band_8821c(pDM_Odm, hal_data->current_channel);
729
730 if (!ret) {
731 RTW_ERR("%s: config_phydm_switch_band_8821c fail\n", __func__);
732 rtw_warn_on(1);
733 return;
734 }
735 phy_set_bb_swing_by_band_8821c(adapter, hal_data->current_band_type, current_band);
736 }
737 }
738
739 /*
740 * Description:
741 * Set channel & bandwidth & offset
742 */
rtl8821c_switch_chnl_and_set_bw(PADAPTER adapter)743 void rtl8821c_switch_chnl_and_set_bw(PADAPTER adapter)
744 {
745 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
746 struct dm_struct *pDM_Odm = &hal->odmpriv;
747 u8 center_ch = 0, ret = 0;
748
749 if (adapter->bNotifyChannelChange) {
750 RTW_INFO("[%s] bSwChnl=%d, ch=%d, bSetChnlBW=%d, bw=%d\n",
751 __FUNCTION__,
752 hal->bSwChnl,
753 hal->current_channel,
754 hal->bSetChnlBW,
755 hal->current_channel_bw);
756 }
757
758 if (RTW_CANNOT_RUN(adapter)) {
759 hal->bSwChnlAndSetBWInProgress = _FALSE;
760 return;
761 }
762
763 /* set channel & Bandwidth register */
764 /* 1. set switch band register if need to switch band */
765 phy_switch_wireless_band_8821c(adapter);
766
767 /* 2. set channel register */
768 if (hal->bSwChnl) {
769 ret = config_phydm_switch_channel_8821c(pDM_Odm, hal->current_channel);
770 hal->bSwChnl = _FALSE;
771
772 if (!ret) {
773 RTW_INFO("%s: config_phydm_switch_channel_8821c fail\n", __FUNCTION__);
774 rtw_warn_on(1);
775 return;
776 }
777 }
778 phydm_config_kfree(pDM_Odm, hal->current_channel);
779
780 /* 3. set Bandwidth register */
781 if (hal->bSetChnlBW) {
782 /* get primary channel index */
783 u8 pri_ch_idx = get_pri_ch_id(adapter);
784
785 /* 3.1 set MAC register */
786 mac_switch_bandwidth(adapter, pri_ch_idx);
787
788 /* 3.2 set BB/RF registet */
789 ret = config_phydm_switch_bandwidth_8821c(pDM_Odm, pri_ch_idx, hal->current_channel_bw);
790 hal->bSetChnlBW = _FALSE;
791
792 if (!ret) {
793 RTW_INFO("%s: config_phydm_switch_bandwidth_8821c fail\n", __FUNCTION__);
794 rtw_warn_on(1);
795 return;
796 }
797 }
798
799 /* TX Power Setting */
800 /* odm_clear_txpowertracking_state(pDM_Odm); */
801 rtw_hal_set_tx_power_level(adapter, hal->current_channel);
802
803 /* IQK */
804 if ((hal->bNeedIQK == _TRUE)
805 || (adapter->registrypriv.mp_mode == 1)) {
806 #ifdef CONFIG_IQK_MONITOR
807 systime iqk_start_time = rtw_get_current_time();
808 #endif
809
810 /*phy_iq_calibrate_8821c(pDM_Odm, _FALSE);*/
811 rtw_phydm_iqk_trigger(adapter);
812
813 #ifdef CONFIG_IQK_MONITOR
814 RTW_INFO(ADPT_FMT" switch CH(%d) DO IQK : %d ms\n",
815 ADPT_ARG(adapter), hal->current_channel, rtw_get_passing_time_ms(iqk_start_time));
816 #endif
817 hal->bNeedIQK = _FALSE;
818 }
819 }
820
821 /*
822 * Description:
823 * Store channel setting to hal date
824 * Parameters:
825 * bSwitchChannel swith channel or not
826 * bSetBandWidth set band or not
827 * ChannelNum center channel
828 * ChnlWidth bandwidth
829 * ChnlOffsetOf40MHz channel offset for 40MHz Bandwidth
830 * ChnlOffsetOf80MHz channel offset for 80MHz Bandwidth
831 * CenterFrequencyIndex1 center channel index
832 */
833
rtl8821c_handle_sw_chnl_and_set_bw(PADAPTER Adapter,u8 bSwitchChannel,u8 bSetBandWidth,u8 ChannelNum,enum channel_width ChnlWidth,u8 ChnlOffsetOf40MHz,u8 ChnlOffsetOf80MHz,u8 CenterFrequencyIndex1)834 void rtl8821c_handle_sw_chnl_and_set_bw(
835 PADAPTER Adapter, u8 bSwitchChannel, u8 bSetBandWidth,
836 u8 ChannelNum, enum channel_width ChnlWidth, u8 ChnlOffsetOf40MHz,
837 u8 ChnlOffsetOf80MHz, u8 CenterFrequencyIndex1)
838 {
839 PHAL_DATA_TYPE hal = GET_HAL_DATA(Adapter);
840 u8 tmpChannel = hal->current_channel;
841 enum channel_width tmpBW = hal->current_channel_bw;
842 u8 tmpnCur40MhzPrimeSC = hal->nCur40MhzPrimeSC;
843 u8 tmpnCur80MhzPrimeSC = hal->nCur80MhzPrimeSC;
844 u8 tmpCenterFrequencyIndex1 = hal->CurrentCenterFrequencyIndex1;
845 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
846
847
848 /* check swchnl or setbw */
849 if (!bSwitchChannel && !bSetBandWidth) {
850 RTW_INFO("%s: not switch channel and not set bandwidth\n", __FUNCTION__);
851 return;
852 }
853
854 /* skip switch channel operation for current channel & ChannelNum(will be switch) are the same */
855 if (bSwitchChannel) {
856 if (hal->current_channel != ChannelNum) {
857 if (HAL_IsLegalChannel(Adapter, ChannelNum))
858 hal->bSwChnl = _TRUE;
859 else
860 return;
861 }
862 }
863
864 /* check set BandWidth */
865 if (bSetBandWidth) {
866 /* initial channel bw setting */
867 if (hal->bChnlBWInitialized == _FALSE) {
868 hal->bChnlBWInitialized = _TRUE;
869 hal->bSetChnlBW = _TRUE;
870 } else if ((hal->current_channel_bw != ChnlWidth) || /* check whether need set band or not */
871 (hal->nCur40MhzPrimeSC != ChnlOffsetOf40MHz) ||
872 (hal->nCur80MhzPrimeSC != ChnlOffsetOf80MHz) ||
873 (hal->CurrentCenterFrequencyIndex1 != CenterFrequencyIndex1))
874 hal->bSetChnlBW = _TRUE;
875 }
876
877 /* return if not need set bandwidth nor channel after check*/
878 if (!hal->bSetChnlBW && !hal->bSwChnl && hal->bNeedIQK != _TRUE)
879 return;
880
881 /* set channel number to hal data */
882 if (hal->bSwChnl) {
883 hal->current_channel = ChannelNum;
884 hal->CurrentCenterFrequencyIndex1 = ChannelNum;
885 }
886
887 /* set bandwidth info to hal data */
888 if (hal->bSetChnlBW) {
889 hal->current_channel_bw = ChnlWidth;
890 hal->nCur40MhzPrimeSC = ChnlOffsetOf40MHz;
891 hal->nCur80MhzPrimeSC = ChnlOffsetOf80MHz;
892 hal->CurrentCenterFrequencyIndex1 = CenterFrequencyIndex1;
893 }
894
895 /* switch channel & bandwidth */
896 if (!RTW_CANNOT_RUN(Adapter))
897 rtl8821c_switch_chnl_and_set_bw(Adapter);
898 else {
899 if (hal->bSwChnl) {
900 hal->current_channel = tmpChannel;
901 hal->CurrentCenterFrequencyIndex1 = tmpChannel;
902 }
903
904 if (hal->bSetChnlBW) {
905 hal->current_channel_bw = tmpBW;
906 hal->nCur40MhzPrimeSC = tmpnCur40MhzPrimeSC;
907 hal->nCur80MhzPrimeSC = tmpnCur80MhzPrimeSC;
908 hal->CurrentCenterFrequencyIndex1 = tmpCenterFrequencyIndex1;
909 }
910 }
911 }
912
913 /*
914 * Description:
915 * Change channel, bandwidth & offset
916 * Parameters:
917 * center_ch center channel
918 * bw bandwidth
919 * offset40 channel offset for 40MHz Bandwidth
920 * offset80 channel offset for 80MHz Bandwidth
921 */
rtl8821c_set_channel_bw(PADAPTER adapter,u8 center_ch,enum channel_width bw,u8 offset40,u8 offset80)922 void rtl8821c_set_channel_bw(PADAPTER adapter, u8 center_ch, enum channel_width bw, u8 offset40, u8 offset80)
923 {
924 rtl8821c_handle_sw_chnl_and_set_bw(adapter, _TRUE, _TRUE, center_ch, bw, offset40, offset80, center_ch);
925 }
926
rtl8821c_notch_filter_switch(PADAPTER adapter,bool enable)927 void rtl8821c_notch_filter_switch(PADAPTER adapter, bool enable)
928 {
929 if (enable)
930 RTW_INFO("%s: Enable notch filter\n", __FUNCTION__);
931 else
932 RTW_INFO("%s: Disable notch filter\n", __FUNCTION__);
933 }
934 #ifdef CONFIG_BEAMFORMING
935 #ifdef RTW_BEAMFORMING_VERSION_2
936 /* REG_TXBF_CTRL (Offset 0x42C) */
937 #define BITS_R_TXBF1_AID_8821C (BIT_MASK_R_TXBF1_AID_8821C << BIT_SHIFT_R_TXBF1_AID_8821C)
938 #define BIT_CLEAR_R_TXBF1_AID_8821C(x) ((x) & (~BITS_R_TXBF1_AID_8821C))
939 #define BIT_SET_R_TXBF1_AID_8821C(x, v) (BIT_CLEAR_R_TXBF1_AID_8821C(x) | BIT_R_TXBF1_AID_8821C(v))
940
941 #define BITS_R_TXBF0_AID_8821C (BIT_MASK_R_TXBF0_AID_8821C << BIT_SHIFT_R_TXBF0_AID_8821C)
942 #define BIT_CLEAR_R_TXBF0_AID_8821C(x) ((x) & (~BITS_R_TXBF0_AID_8821C))
943 #define BIT_SET_R_TXBF0_AID_8821C(x, v) (BIT_CLEAR_R_TXBF0_AID_8821C(x) | BIT_R_TXBF0_AID_8821C(v))
944
945 /* REG_NDPA_OPT_CTRL (Offset 0x45F) */
946 #define BITS_R_NDPA_BW_8821C (BIT_MASK_R_NDPA_BW_8821C << BIT_SHIFT_R_NDPA_BW_8821C)
947 #define BIT_CLEAR_R_NDPA_BW_8821C(x) ((x) & (~BITS_R_NDPA_BW_8821C))
948 #define BIT_SET_R_NDPA_BW_8821C(x, v) (BIT_CLEAR_R_NDPA_BW_8821C(x) | BIT_R_NDPA_BW_8821C(v))
949
950 /* REG_ASSOCIATED_BFMEE_SEL (Offset 0x714) */
951 #define BITS_AID1_8821C (BIT_MASK_AID1_8821C << BIT_SHIFT_AID1_8821C)
952 #define BIT_CLEAR_AID1_8821C(x) ((x) & (~BITS_AID1_8821C))
953 #define BIT_SET_AID1_8821C(x, v) (BIT_CLEAR_AID1_8821C(x) | BIT_AID1_8821C(v))
954
955 #define BITS_AID0_8821C (BIT_MASK_AID0_8821C << BIT_SHIFT_AID0_8821C)
956 #define BIT_CLEAR_AID0_8821C(x) ((x) & (~BITS_AID0_8821C))
957 #define BIT_SET_AID0_8821C(x, v) (BIT_CLEAR_AID0_8821C(x) | BIT_AID0_8821C(v))
958
959 /* REG_MU_TX_CTL (Offset 0x14C0) */
960 #define BIT_R_MU_P1_WAIT_STATE_EN_8821C BIT(16)
961
962 #define BIT_SHIFT_R_MU_RL_8821C 12
963 #define BITS_R_MU_RL_8821C (BIT_MASK_R_MU_RL_8821C << BIT_SHIFT_R_MU_RL_8821C)
964 #define BIT_R_MU_RL_8821C(x) (((x) & BIT_MASK_R_MU_RL_8821C) << BIT_SHIFT_R_MU_RL_8821C)
965 #define BIT_CLEAR_R_MU_RL_8821C(x) ((x) & (~BITS_R_MU_RL_8821C))
966 #define BIT_SET_R_MU_RL_8821C(x, v) (BIT_CLEAR_R_MU_RL_8821C(x) | BIT_R_MU_RL_8821C(v))
967
968 #define BIT_SHIFT_R_MU_TAB_SEL_8821C 8
969 #define BIT_MASK_R_MU_TAB_SEL_8821C 0x7
970 #define BITS_R_MU_TAB_SEL_8821C (BIT_MASK_R_MU_TAB_SEL_8821C << BIT_SHIFT_R_MU_TAB_SEL_8821C)
971 #define BIT_R_MU_TAB_SEL_8821C(x) (((x) & BIT_MASK_R_MU_TAB_SEL_8821C) << BIT_SHIFT_R_MU_TAB_SEL_8821C)
972 #define BIT_CLEAR_R_MU_TAB_SEL_8821C(x) ((x) & (~BITS_R_MU_TAB_SEL_8821C))
973 #define BIT_SET_R_MU_TAB_SEL_8821C(x, v) (BIT_CLEAR_R_MU_TAB_SEL_8821C(x) | BIT_R_MU_TAB_SEL_8821C(v))
974
975 #define BIT_R_EN_MU_MIMO_8821C BIT(7)
976
977 #define BITS_R_MU_TABLE_VALID_8821C (BIT_MASK_R_MU_TABLE_VALID_8821C << BIT_SHIFT_R_MU_TABLE_VALID_8821C)
978 #define BIT_CLEAR_R_MU_TABLE_VALID_8821C(x) ((x) & (~BITS_R_MU_TABLE_VALID_8821C))
979 #define BIT_SET_R_MU_TABLE_VALID_8821C(x, v) (BIT_CLEAR_R_MU_TABLE_VALID_8821C(x) | BIT_R_MU_TABLE_VALID_8821C(v))
980
981 /* REG_WMAC_MU_BF_CTL (Offset 0x1680) */
982 #define BITS_WMAC_MU_BFRPTSEG_SEL_8821C (BIT_MASK_WMAC_MU_BFRPTSEG_SEL_8821C << BIT_SHIFT_WMAC_MU_BFRPTSEG_SEL_8821C)
983 #define BIT_CLEAR_WMAC_MU_BFRPTSEG_SEL_8821C(x) ((x) & (~BITS_WMAC_MU_BFRPTSEG_SEL_8821C))
984 #define BIT_SET_WMAC_MU_BFRPTSEG_SEL_8821C(x, v) (BIT_CLEAR_WMAC_MU_BFRPTSEG_SEL_8821C(x) | BIT_WMAC_MU_BFRPTSEG_SEL_8821C(v))
985
986 #define BITS_WMAC_MU_BF_MYAID_8821C (BIT_MASK_WMAC_MU_BF_MYAID_8821C << BIT_SHIFT_WMAC_MU_BF_MYAID_8821C)
987 #define BIT_CLEAR_WMAC_MU_BF_MYAID_8821C(x) ((x) & (~BITS_WMAC_MU_BF_MYAID_8821C))
988 #define BIT_SET_WMAC_MU_BF_MYAID_8821C(x, v) (BIT_CLEAR_WMAC_MU_BF_MYAID_8821C(x) | BIT_WMAC_MU_BF_MYAID_8821C(v))
989
990 /* REG_WMAC_ASSOCIATED_MU_BFMEE7 (Offset 0x168E) */
991 #define BIT_STATUS_BFEE7_8821C BIT(10)
992
993
_bf_get_nrx(PADAPTER adapter)994 static u8 _bf_get_nrx(PADAPTER adapter)
995 {
996 u8 nrx = 0;
997
998 nrx = GET_HAL_RX_NSS(adapter);
999 return (nrx - 1);
1000 }
1001
1002
_config_beamformer_su(PADAPTER adapter,struct beamformer_entry * bfer)1003 static void _config_beamformer_su(PADAPTER adapter, struct beamformer_entry *bfer)
1004 {
1005 /* Beamforming */
1006 u8 nc_index = 0, nr_index = 0;
1007 u8 grouping = 0, codebookinfo = 0, coefficientsize = 0;
1008 u32 addr_bfer_info, addr_csi_rpt;
1009 u32 csi_param;
1010 /* Misc */
1011 u8 i;
1012
1013
1014 RTW_INFO("%s: Config SU BFer entry HW setting\n", __FUNCTION__);
1015
1016 if (bfer->su_reg_index == 0) {
1017 addr_bfer_info = REG_ASSOCIATED_BFMER0_INFO_8821C;
1018 addr_csi_rpt = REG_TX_CSI_RPT_PARAM_BW20_8821C;
1019 } else {
1020 addr_bfer_info = REG_ASSOCIATED_BFMER1_INFO_8821C;
1021 addr_csi_rpt = REG_TX_CSI_RPT_PARAM_BW20_8821C + 2;
1022 }
1023
1024 /* Sounding protocol control */
1025 rtw_write8(adapter, REG_SND_PTCL_CTRL_8821C, 0xDB);
1026
1027 /* MAC address/Partial AID of Beamformer */
1028 for (i = 0; i < ETH_ALEN; i++)
1029 rtw_write8(adapter, addr_bfer_info+i, bfer->mac_addr[i]);
1030
1031 /* CSI report parameters of Beamformer */
1032 nc_index = _bf_get_nrx(adapter);
1033 /*
1034 * 0x718[7] = 1 use Nsts
1035 * 0x718[7] = 0 use reg setting
1036 * As Bfee, we use Nsts, so nr_index don't care
1037 */
1038 nr_index = bfer->NumofSoundingDim;
1039 grouping = 0;
1040 /* for ac = 1, for n = 3 */
1041 if (TEST_FLAG(bfer->cap, BEAMFORMER_CAP_VHT_SU))
1042 codebookinfo = 1;
1043 else if (TEST_FLAG(bfer->cap, BEAMFORMER_CAP_HT_EXPLICIT))
1044 codebookinfo = 3;
1045 coefficientsize = 3;
1046 csi_param = (u16)((coefficientsize<<10)|(codebookinfo<<8)|(grouping<<6)|(nr_index<<3)|(nc_index));
1047 rtw_write16(adapter, addr_csi_rpt, csi_param);
1048 RTW_INFO("%s: nc=%d nr=%d group=%d codebookinfo=%d coefficientsize=%d\n",
1049 __FUNCTION__, nc_index, nr_index, grouping, codebookinfo, coefficientsize);
1050 RTW_INFO("%s: csi=0x%04x\n", __FUNCTION__, csi_param);
1051
1052 /* ndp_rx_standby_timer */
1053 rtw_write8(adapter, REG_SND_PTCL_CTRL_8821C+3, 0x70);
1054 }
1055
_config_beamformer_mu(PADAPTER adapter,struct beamformer_entry * bfer)1056 static void _config_beamformer_mu(PADAPTER adapter, struct beamformer_entry *bfer)
1057 {
1058 /* General */
1059 PHAL_DATA_TYPE hal;
1060 /* Beamforming */
1061 struct beamforming_info *bf_info;
1062 u8 nc_index = 0, nr_index = 0;
1063 u8 grouping = 0, codebookinfo = 0, coefficientsize = 0;
1064 u32 csi_param;
1065 /* Misc */
1066 u8 i, val8;
1067 u16 val16;
1068
1069 RTW_INFO("%s: Config MU BFer entry HW setting\n", __FUNCTION__);
1070
1071 hal = GET_HAL_DATA(adapter);
1072 bf_info = GET_BEAMFORM_INFO(adapter);
1073
1074 /* Reset GID table */
1075 for (i = 0; i < 8; i++)
1076 bfer->gid_valid[i] = 0;
1077 for (i = 0; i < 16; i++)
1078 bfer->user_position[i] = 0;
1079
1080 /* CSI report parameters of Beamformer */
1081 nc_index = _bf_get_nrx(adapter);
1082 nr_index = 1; /* 0x718[7] = 1 use Nsts, 0x718[7] = 0 use reg setting. as Bfee, we use Nsts, so Nr_index don't care */
1083 grouping = 0; /* no grouping */
1084 codebookinfo = 1; /* 7 bit for psi, 9 bit for phi */
1085 coefficientsize = 0; /* This is nothing really matter */
1086 csi_param = (u16)((coefficientsize<<10)|(codebookinfo<<8)|
1087 (grouping<<6)|(nr_index<<3)|(nc_index));
1088
1089 RTW_INFO("%s: nc=%d nr=%d group=%d codebookinfo=%d coefficientsize=%d\n",
1090 __func__, nc_index, nr_index, grouping, codebookinfo,
1091 coefficientsize);
1092 RTW_INFO("%s: csi=0x%04x\n", __func__, csi_param);
1093
1094 rtw_halmac_bf_add_mu_bfer(adapter_to_dvobj(adapter), bfer->p_aid,
1095 csi_param, bfer->aid & 0xfff, HAL_CSI_SEG_4K,
1096 bfer->mac_addr);
1097
1098 bf_info->cur_csi_rpt_rate = HALMAC_OFDM6;
1099 rtw_halmac_bf_cfg_sounding(adapter_to_dvobj(adapter), HAL_BFEE,
1100 bf_info->cur_csi_rpt_rate);
1101
1102 /* Set 0x6A0[14] = 1 to accept action_no_ack */
1103 val8 = rtw_read8(adapter, REG_RXFLTMAP0_8821C+1);
1104 val8 |= (BIT_MGTFLT14EN_8821C >> 8);
1105 rtw_write8(adapter, REG_RXFLTMAP0_8821C+1, val8);
1106
1107 /* Set 0x6A2[5:4] = 1 to NDPA and BF report poll */
1108 val8 = rtw_read8(adapter, REG_RXFLTMAP1_8821C);
1109 val8 |= BIT_CTRLFLT4EN_8821C | BIT_CTRLFLT5EN_8821C;
1110 rtw_write8(adapter, REG_RXFLTMAP1_8821C, val8);
1111
1112 /* for B-Cut */
1113 if (IS_B_CUT(hal->version_id)) {
1114 phy_set_bb_reg(adapter, REG_RXFLTMAP0_8821C, BIT(20), 0);
1115 phy_set_bb_reg(adapter, REG_RXFLTMAP3_8821C, BIT(20), 0);
1116 }
1117 }
1118
1119
1120
_reset_beamformer_su(PADAPTER adapter,struct beamformer_entry * bfer)1121 static void _reset_beamformer_su(PADAPTER adapter, struct beamformer_entry *bfer)
1122 {
1123 /* Beamforming */
1124 struct beamforming_info *info;
1125 u8 idx;
1126
1127
1128 info = GET_BEAMFORM_INFO(adapter);
1129 /* SU BFer */
1130 idx = bfer->su_reg_index;
1131
1132 if (idx == 0) {
1133 rtw_write32(adapter, REG_ASSOCIATED_BFMER0_INFO_8821C, 0);
1134 rtw_write16(adapter, REG_ASSOCIATED_BFMER0_INFO_8821C+4, 0);
1135 rtw_write16(adapter, REG_TX_CSI_RPT_PARAM_BW20_8821C, 0);
1136 } else {
1137 rtw_write32(adapter, REG_ASSOCIATED_BFMER1_INFO_8821C, 0);
1138 rtw_write16(adapter, REG_ASSOCIATED_BFMER1_INFO_8821C+4, 0);
1139 rtw_write16(adapter, REG_TX_CSI_RPT_PARAM_BW20_8821C+2, 0);
1140 }
1141
1142 info->beamformer_su_reg_maping &= ~BIT(idx);
1143 bfer->su_reg_index = 0xFF;
1144
1145 RTW_INFO("%s: Clear SU BFer entry(%d) HW setting\n", __FUNCTION__, idx);
1146 }
1147
_reset_beamformer_mu(PADAPTER adapter,struct beamformer_entry * bfer)1148 static void _reset_beamformer_mu(PADAPTER adapter, struct beamformer_entry *bfer)
1149 {
1150 struct beamforming_info *bf_info;
1151
1152 bf_info = GET_BEAMFORM_INFO(adapter);
1153
1154 rtw_halmac_bf_del_mu_bfer(adapter_to_dvobj(adapter));
1155
1156 if (bf_info->beamformer_su_cnt == 0 &&
1157 bf_info->beamformer_mu_cnt == 0)
1158 rtw_halmac_bf_del_sounding(adapter_to_dvobj(adapter), HAL_BFEE);
1159
1160 RTW_INFO("%s: Clear MU BFer entry HW setting\n", __FUNCTION__);
1161 }
1162
rtl8821c_phy_bf_init(PADAPTER adapter)1163 void rtl8821c_phy_bf_init(PADAPTER adapter)
1164 {
1165 u8 v8;
1166 u32 v32;
1167
1168 v32 = rtw_read32(adapter, REG_MU_TX_CTL_8821C);
1169 /* Enable P1 aggr new packet according to P0 transfer time */
1170 v32 |= BIT_R_MU_P1_WAIT_STATE_EN_8821C;
1171 /* MU Retry Limit */
1172 v32 = BIT_SET_R_MU_RL_8821C(v32, 0xA);
1173 /* Disable Tx MU-MIMO until sounding done */
1174 v32 &= ~BIT_R_EN_MU_MIMO_8821C;
1175 /* Clear validity of MU STAs */
1176 v32 = BIT_SET_R_MU_TABLE_VALID_8821C(v32, 0);
1177 rtw_write32(adapter, REG_MU_TX_CTL_8821C, v32);
1178
1179 /* MU-MIMO Option as default value */
1180 v8 = BIT_WMAC_TXMU_ACKPOLICY_8821C(3);
1181 v8 |= BIT_WMAC_TXMU_ACKPOLICY_EN_8821C;
1182 rtw_write8(adapter, REG_MU_BF_OPTION_8821C, v8);
1183 /* MU-MIMO Control as default value */
1184 rtw_write16(adapter, REG_WMAC_MU_BF_CTL_8821C, 0);
1185
1186 /* Set MU NDPA rate & BW source */
1187 /* 0x42C[30] = 1 (0: from Tx desc, 1: from 0x45F) */
1188 v8 = rtw_read8(adapter, REG_TXBF_CTRL_8821C+3);
1189 v8 |= (BIT_USE_NDPA_PARAMETER_8821C >> 24);
1190 rtw_write8(adapter, REG_TXBF_CTRL_8821C+3, v8);
1191 /* 0x45F[7:0] = 0x10 (Rate=OFDM_6M, BW20) */
1192 rtw_write8(adapter, REG_NDPA_OPT_CTRL_8821C, 0x10);
1193
1194 /* Temp Settings */
1195 /* STA2's CSI rate is fixed at 6M */
1196 v8 = rtw_read8(adapter, 0x6DF);
1197 v8 = (v8 & 0xC0) | 0x4;
1198 rtw_write8(adapter, 0x6DF, v8);
1199 /* Grouping bitmap parameters */
1200 rtw_write32(adapter, 0x1C94, 0xAFFFAFFF);
1201 }
1202
rtl8821c_phy_bf_enter(PADAPTER adapter,struct sta_info * sta)1203 void rtl8821c_phy_bf_enter(PADAPTER adapter, struct sta_info *sta)
1204 {
1205 struct beamforming_info *info;
1206 struct beamformer_entry *bfer;
1207
1208
1209
1210 RTW_INFO("+%s: " MAC_FMT "\n", __FUNCTION__, MAC_ARG(sta->cmn.mac_addr));
1211
1212 info = GET_BEAMFORM_INFO(adapter);
1213 bfer = rtw_bf_bfer_get_entry_by_addr(adapter, sta->cmn.mac_addr);
1214
1215
1216 info->bSetBFHwConfigInProgess = _TRUE;
1217
1218 if (bfer) {
1219 bfer->state = BEAMFORM_ENTRY_HW_STATE_ADDING;
1220
1221 if (TEST_FLAG(bfer->cap, BEAMFORMER_CAP_VHT_MU))
1222 _config_beamformer_mu(adapter, bfer);
1223 else if (TEST_FLAG(bfer->cap, BEAMFORMER_CAP_VHT_SU|BEAMFORMER_CAP_HT_EXPLICIT))
1224 _config_beamformer_su(adapter, bfer);
1225
1226 bfer->state = BEAMFORM_ENTRY_HW_STATE_ADDED;
1227 }
1228
1229 info->bSetBFHwConfigInProgess = _FALSE;
1230
1231 RTW_INFO("-%s\n", __FUNCTION__);
1232 }
1233
rtl8821c_phy_bf_leave(PADAPTER adapter,u8 * addr)1234 void rtl8821c_phy_bf_leave(PADAPTER adapter, u8 *addr)
1235 {
1236 struct beamforming_info *info;
1237 struct beamformer_entry *bfer;
1238
1239
1240
1241 RTW_INFO("+%s: " MAC_FMT "\n", __FUNCTION__, MAC_ARG(addr));
1242
1243 info = GET_BEAMFORM_INFO(adapter);
1244
1245 bfer = rtw_bf_bfer_get_entry_by_addr(adapter, addr);
1246
1247
1248 /* Clear P_AID of Beamformee */
1249 /* Clear MAC address of Beamformer */
1250 /* Clear Associated Bfmee Sel */
1251 if (bfer) {
1252 bfer->state = BEAMFORM_ENTRY_HW_STATE_DELETING;
1253
1254 rtw_write8(adapter, REG_SND_PTCL_CTRL_8821C, 0xD8);
1255
1256 if (TEST_FLAG(bfer->cap, BEAMFORMER_CAP_VHT_MU))
1257 _reset_beamformer_mu(adapter, bfer);
1258 else if (TEST_FLAG(bfer->cap, BEAMFORMER_CAP_VHT_SU|BEAMFORMER_CAP_HT_EXPLICIT))
1259 _reset_beamformer_su(adapter, bfer);
1260
1261 bfer->state = BEAMFORM_ENTRY_HW_STATE_NONE;
1262 bfer->cap = BEAMFORMING_CAP_NONE;
1263 bfer->used = _FALSE;
1264 }
1265
1266
1267 RTW_INFO("-%s\n", __FUNCTION__);
1268 }
1269
rtl8821c_phy_bf_set_gid_table(PADAPTER adapter,struct beamformer_entry * bfer_info)1270 void rtl8821c_phy_bf_set_gid_table(PADAPTER adapter,
1271 struct beamformer_entry *bfer_info)
1272 {
1273 struct beamformer_entry *bfer;
1274 struct beamforming_info *info;
1275 u32 gid_valid[2] = {0};
1276 u32 user_position[4] = {0};
1277 int i;
1278
1279 /* update bfer info */
1280 bfer = rtw_bf_bfer_get_entry_by_addr(adapter, bfer_info->mac_addr);
1281 if (!bfer) {
1282 RTW_INFO("%s: Cannot find BFer entry!!\n", __func__);
1283 return;
1284 }
1285 _rtw_memcpy(bfer->gid_valid, bfer_info->gid_valid, 8);
1286 _rtw_memcpy(bfer->user_position, bfer_info->user_position, 16);
1287
1288 info = GET_BEAMFORM_INFO(adapter);
1289 info->bSetBFHwConfigInProgess = _TRUE;
1290
1291 /* For GID 0~31 */
1292 for (i = 0; i < 4; i++)
1293 gid_valid[0] |= (bfer->gid_valid[i] << (i << 3));
1294
1295 for (i = 0; i < 8; i++) {
1296 if (i < 4)
1297 user_position[0] |= (bfer->user_position[i] << (i << 3));
1298 else
1299 user_position[1] |= (bfer->user_position[i] << ((i - 4) << 3));
1300 }
1301
1302 RTW_INFO("%s: STA0: gid_valid=0x%x, user_position_l=0x%x, user_position_h=0x%x\n",
1303 __func__, gid_valid[0], user_position[0], user_position[1]);
1304
1305 /* For GID 32~64 */
1306 for (i = 4; i < 8; i++)
1307 gid_valid[1] |= (bfer->gid_valid[i] << ((i - 4) << 3));
1308
1309 for (i = 8; i < 16; i++) {
1310 if (i < 12)
1311 user_position[2] |= (bfer->user_position[i] << ((i - 8) << 3));
1312 else
1313 user_position[3] |= (bfer->user_position[i] << ((i - 12) << 3));
1314 }
1315
1316 RTW_INFO("%s: STA1: gid_valid=0x%x, user_position_l=0x%x, user_position_h=0x%x\n",
1317 __func__, gid_valid[1], user_position[2], user_position[3]);
1318
1319 rtw_halmac_bf_cfg_mu_bfee(adapter_to_dvobj(adapter), gid_valid, user_position);
1320
1321 info->bSetBFHwConfigInProgess = _FALSE;
1322 }
1323 #endif /* RTW_BEAMFORMING_VERSION_2 */
1324 #endif /* CONFIG_BEAMFORMING */
1325 #ifdef CONFIG_MP_INCLUDED
1326 /*
1327 * Description:
1328 * Config RF path
1329 *
1330 * Parameters:
1331 * adapter pointer of struct _ADAPTER
1332 */
rtl8821c_mp_config_rfpath(PADAPTER adapter)1333 void rtl8821c_mp_config_rfpath(PADAPTER adapter)
1334 {
1335 PHAL_DATA_TYPE hal;
1336 PMPT_CONTEXT mpt;
1337 ANTENNA_PATH anttx, antrx;
1338 enum rf_path rxant;
1339
1340
1341 hal = GET_HAL_DATA(adapter);
1342 mpt = &adapter->mppriv.mpt_ctx;
1343 anttx = hal->antenna_tx_path;
1344 antrx = hal->AntennaRxPath;
1345 RTW_INFO("+Config RF Path, tx=0x%x rx=0x%x\n", anttx, antrx);
1346
1347 #if 0 /* phydm not ready */
1348 switch (anttx) {
1349 case ANTENNA_A:
1350 mpt->mpt_rf_path = ODM_RF_A;
1351 break;
1352 case ANTENNA_B:
1353 mpt->mpt_rf_path = ODM_RF_B;
1354 break;
1355 case ANTENNA_AB:
1356 default:
1357 mpt->mpt_rf_path = ODM_RF_A | ODM_RF_B;
1358 break;
1359 }
1360
1361 switch (antrx) {
1362 case ANTENNA_A:
1363 rxant = ODM_RF_A;
1364 break;
1365 case ANTENNA_B:
1366 rxant = ODM_RF_B;
1367 break;
1368 case ANTENNA_AB:
1369 default:
1370 rxant = ODM_RF_A | ODM_RF_B;
1371 break;
1372 }
1373
1374 config_phydm_trx_mode_8821c(GET_PDM_ODM(adapter), mpt->mpt_rf_path, rxant, FALSE);
1375 #endif
1376 RTW_INFO("-Config RF Path Finish\n");
1377 }
1378
1379 #endif /* CONFIG_MP_INCLUDED */
1380