xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8821cs/hal/rtl8821c/rtl8821c_phy.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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