xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8822bs/hal/rtl8822b/rtl8822b_phy.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2015 - 2018 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 _RTL8822B_PHY_C_
16 
17 #include <hal_data.h>		/* HAL_DATA_TYPE */
18 #include "../hal_halmac.h"	/* rtw_halmac_phy_power_switch() */
19 #include "rtl8822b.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 
57 /*
58  * Description:
59  *	Initialize MAC registers
60  *
61  * Return:
62  *	_TRUE	Success
63  *	_FALSE	Fail
64  */
rtl8822b_phy_init_mac_register(PADAPTER adapter)65 u8 rtl8822b_phy_init_mac_register(PADAPTER adapter)
66 {
67 	PHAL_DATA_TYPE hal;
68 	u8 ret = _TRUE;
69 	int res;
70 	enum hal_status status;
71 
72 
73 	hal = GET_HAL_DATA(adapter);
74 
75 	ret = _FALSE;
76 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
77 	res = phy_ConfigMACWithParaFile(adapter, PHY_FILE_MAC_REG);
78 	if (_SUCCESS == res)
79 		ret = _TRUE;
80 #endif /* CONFIG_LOAD_PHY_PARA_FROM_FILE */
81 	if (_FALSE == ret) {
82 		status = odm_config_mac_with_header_file(&hal->odmpriv);
83 		if (HAL_STATUS_SUCCESS == status)
84 			ret = _TRUE;
85 	}
86 	if (_FALSE == ret)
87 		RTW_INFO("%s: Write MAC Reg Fail!!", __FUNCTION__);
88 
89 	return ret;
90 }
91 
_init_bb_reg(PADAPTER Adapter)92 static u8 _init_bb_reg(PADAPTER Adapter)
93 {
94 	PHAL_DATA_TYPE hal = GET_HAL_DATA(Adapter);
95 	u8 ret = _TRUE;
96 	int res;
97 	enum hal_status status;
98 
99 	/*
100 	 * 1. Read PHY_REG.TXT BB INIT!!
101 	 */
102 	ret = _FALSE;
103 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
104 	res = phy_ConfigBBWithParaFile(Adapter, PHY_FILE_PHY_REG, CONFIG_BB_PHY_REG);
105 	if (_SUCCESS == res)
106 		ret = _TRUE;
107 #endif
108 	if (_FALSE == ret) {
109 		status = odm_config_bb_with_header_file(&hal->odmpriv, CONFIG_BB_PHY_REG);
110 		if (HAL_STATUS_SUCCESS == status)
111 			ret = _TRUE;
112 	}
113 	if (_FALSE == ret) {
114 		RTW_INFO("%s: Write BB Reg Fail!!", __FUNCTION__);
115 		goto exit;
116 	}
117 
118 #if 0 /* No parameter with MP using currently by BB@Stanley. */
119 /*#ifdef CONFIG_MP_INCLUDED*/
120 	if (Adapter->registrypriv.mp_mode == 1) {
121 		/*
122 		 * 1.1 Read PHY_REG_MP.TXT BB INIT!!
123 		 */
124 		ret = _FALSE;
125 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
126 		res = phy_ConfigBBWithMpParaFile(Adapter, PHY_FILE_PHY_REG_MP);
127 		if (_SUCCESS == res)
128 			ret = _TRUE;
129 #endif
130 		if (_FALSE == ret) {
131 			status = odm_config_bb_with_header_file(&hal->odmpriv, CONFIG_BB_PHY_REG_MP);
132 			if (HAL_STATUS_SUCCESS == status)
133 				ret = _TRUE;
134 		}
135 		if (_FALSE == ret) {
136 			RTW_INFO("%s: Write BB Reg MP Fail!!", __FUNCTION__);
137 			goto exit;
138 		}
139 	}
140 #endif /* CONFIG_MP_INCLUDED */
141 
142 	/*
143 	 * 2. Read BB AGC table Initialization
144 	 */
145 	ret = _FALSE;
146 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
147 	res = phy_ConfigBBWithParaFile(Adapter, PHY_FILE_AGC_TAB, CONFIG_BB_AGC_TAB);
148 	if (_SUCCESS == res)
149 		ret = _TRUE;
150 #endif
151 	if (_FALSE == ret) {
152 		status = odm_config_bb_with_header_file(&hal->odmpriv, CONFIG_BB_AGC_TAB);
153 		if (HAL_STATUS_SUCCESS == status)
154 			ret = _TRUE;
155 	}
156 	if (_FALSE == ret) {
157 		RTW_INFO("%s: Write AGC Table Fail!\n", __FUNCTION__);
158 		goto exit;
159 	}
160 
161 exit:
162 	return ret;
163 }
164 
init_bb_reg(PADAPTER adapter)165 static u8 init_bb_reg(PADAPTER adapter)
166 {
167 	u8 ret = _TRUE;
168 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
169 
170 
171 	/*
172 	 * Config BB and AGC
173 	 */
174 	ret = _init_bb_reg(adapter);
175 
176 	if (rtw_phydm_set_crystal_cap(adapter, hal->crystal_cap) == _FALSE) {
177 		RTW_ERR("Init crystal_cap failed\n");
178 		rtw_warn_on(1);
179 		ret = _FALSE;
180 	}
181 
182 	return ret;
183 }
184 
_init_rf_reg(PADAPTER adapter)185 static u8 _init_rf_reg(PADAPTER adapter)
186 {
187 	u8 path;
188 	enum rf_path phydm_path;
189 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
190 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
191 	u8 *regfile;
192 #endif
193 	enum hal_status status;
194 	int res;
195 	u8 ret = _TRUE;
196 
197 
198 	/*
199 	 * Initialize RF
200 	 */
201 	for (path = 0; path < hal->NumTotalRFPath; path++) {
202 		/* Initialize RF from configuration file */
203 		switch (path) {
204 		case 0:
205 			phydm_path = RF_PATH_A;
206 			#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
207 			regfile = PHY_FILE_RADIO_A;
208 			#endif
209 			break;
210 
211 		case 1:
212 			phydm_path = RF_PATH_B;
213 			#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
214 			regfile = PHY_FILE_RADIO_B;
215 			#endif
216 			break;
217 
218 		default:
219 			RTW_INFO("%s: [WARN] Unknown path=%d, skip!\n", __FUNCTION__, path);
220 			continue;
221 		}
222 
223 		ret = _FALSE;
224 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
225 		res = PHY_ConfigRFWithParaFile(adapter, regfile, phydm_path);
226 		if (_SUCCESS == res)
227 			ret = _TRUE;
228 #endif
229 		if (_FALSE == ret) {
230 			status = odm_config_rf_with_header_file(&hal->odmpriv, CONFIG_RF_RADIO, phydm_path);
231 			if (HAL_STATUS_SUCCESS != status)
232 				goto exit;
233 #if 0 /* Remove because coverity check fail */
234 			ret = _TRUE;
235 #endif
236 		}
237 	}
238 
239 	/*
240 	 * Configuration of Tx Power Tracking
241 	 */
242 	ret = _FALSE;
243 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
244 	res = PHY_ConfigRFWithTxPwrTrackParaFile(adapter, PHY_FILE_TXPWR_TRACK);
245 	if (_SUCCESS == res)
246 		ret = _TRUE;
247 #endif
248 	if (_FALSE == ret) {
249 		status = odm_config_rf_with_tx_pwr_track_header_file(&hal->odmpriv);
250 		if (HAL_STATUS_SUCCESS != status) {
251 			RTW_INFO("%s: Write PwrTrack Table Fail!\n", __FUNCTION__);
252 			goto exit;
253 		}
254 		ret = _TRUE;
255 	}
256 
257 exit:
258 	return ret;
259 }
260 
init_rf_reg(PADAPTER adapter)261 static u8 init_rf_reg(PADAPTER adapter)
262 {
263 	u8 ret = _TRUE;
264 
265 
266 	ret = _init_rf_reg(adapter);
267 
268 	return ret;
269 }
270 
271 /*
272  * Description:
273  *	Initialize PHY(BB/RF) related functions
274  *
275  * Return:
276  *	_TRUE	Success
277  *	_FALSE	Fail
278  */
rtl8822b_phy_init(PADAPTER adapter)279 u8 rtl8822b_phy_init(PADAPTER adapter)
280 {
281 	struct dvobj_priv *d;
282 	struct dm_struct *phydm;
283 	int err;
284 	u8 ok = _TRUE;
285 	BOOLEAN ret;
286 
287 
288 	d = adapter_to_dvobj(adapter);
289 	phydm = adapter_to_phydm(adapter);
290 
291 	bb_rf_register_definition(adapter);
292 
293 	err = rtw_halmac_phy_power_switch(d, _TRUE);
294 	if (err)
295 		return _FALSE;
296 
297 	ret = config_phydm_parameter_init_8822b(phydm, ODM_PRE_SETTING);
298 	if (FALSE == ret)
299 		return _FALSE;
300 
301 	ok = init_bb_reg(adapter);
302 	if (_FALSE == ok)
303 		return _FALSE;
304 	ok = init_rf_reg(adapter);
305 	if (_FALSE == ok)
306 		return _FALSE;
307 
308 	ret = config_phydm_parameter_init_8822b(phydm, ODM_POST_SETTING);
309 	if (FALSE == ret)
310 		return _FALSE;
311 
312 	return _TRUE;
313 }
314 
315 #ifdef CONFIG_SUPPORT_HW_WPS_PBC
dm_CheckPbcGPIO(PADAPTER adapter)316 static void dm_CheckPbcGPIO(PADAPTER adapter)
317 {
318 	u8 tmp1byte;
319 	u8 bPbcPressed = _FALSE;
320 
321 	if (!adapter->registrypriv.hw_wps_pbc)
322 		return;
323 
324 #ifdef CONFIG_USB_HCI
325 	tmp1byte = rtw_read8(adapter, GPIO_IO_SEL);
326 	tmp1byte |= (HAL_8192C_HW_GPIO_WPS_BIT);
327 	rtw_write8(adapter, GPIO_IO_SEL, tmp1byte); /* enable GPIO[2] as output mode */
328 
329 	tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT);
330 	rtw_write8(adapter, GPIO_IN, tmp1byte); /* reset the floating voltage level */
331 
332 	tmp1byte = rtw_read8(adapter, GPIO_IO_SEL);
333 	tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT);
334 	rtw_write8(adapter, GPIO_IO_SEL, tmp1byte); /* enable GPIO[2] as input mode */
335 
336 	tmp1byte = rtw_read8(adapter, GPIO_IN);
337 	if (tmp1byte == 0xff)
338 		return;
339 
340 	if (tmp1byte & HAL_8192C_HW_GPIO_WPS_BIT)
341 		bPbcPressed = _TRUE;
342 #else
343 	tmp1byte = rtw_read8(adapter, GPIO_IN);
344 
345 	if ((tmp1byte == 0xff) || adapter->init_adpt_in_progress)
346 		return;
347 
348 	if ((tmp1byte & HAL_8192C_HW_GPIO_WPS_BIT) == 0)
349 		bPbcPressed = _TRUE;
350 #endif
351 
352 	if (_TRUE == bPbcPressed) {
353 		/*
354 		 * Here we only set bPbcPressed to true
355 		 * After trigger PBC, the variable will be set to false
356 		 */
357 		RTW_INFO("CheckPbcGPIO - PBC is pressed\n");
358 		rtw_request_wps_pbc_event(adapter);
359 	}
360 }
361 #endif /* CONFIG_SUPPORT_HW_WPS_PBC */
362 
363 
364 #ifdef CONFIG_PCI_HCI
365 /*
366  * Description:
367  *	Perform interrupt migration dynamically to reduce CPU utilization.
368  *
369  * Assumption:
370  *	1. Do not enable migration under WIFI test.
371  */
dm_InterruptMigration(PADAPTER adapter)372 void dm_InterruptMigration(PADAPTER adapter)
373 {
374 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
375 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
376 	BOOLEAN bCurrentIntMt, bCurrentACIntDisable;
377 	BOOLEAN IntMtToSet = _FALSE;
378 	BOOLEAN ACIntToSet = _FALSE;
379 
380 
381 	/* Retrieve current interrupt migration and Tx four ACs IMR settings first. */
382 	bCurrentIntMt = hal->bInterruptMigration;
383 	bCurrentACIntDisable = hal->bDisableTxInt;
384 
385 	/*
386 	 * <Roger_Notes> Currently we use busy traffic for reference instead of RxIntOK counts to prevent non-linear Rx statistics
387 	 * when interrupt migration is set before. 2010.03.05.
388 	 */
389 	if (!adapter->registrypriv.wifi_spec
390 	    && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
391 	    && pmlmepriv->LinkDetectInfo.bHigherBusyTraffic) {
392 		IntMtToSet = _TRUE;
393 
394 		/* To check whether we should disable Tx interrupt or not. */
395 		if (pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic)
396 			ACIntToSet = _TRUE;
397 	}
398 
399 	/* Update current settings. */
400 	if (bCurrentIntMt != IntMtToSet) {
401 		RTW_INFO("%s: Update interrupt migration(%d)\n", __FUNCTION__, IntMtToSet);
402 		if (IntMtToSet) {
403 			/*
404 			 * <Roger_Notes> Set interrupt migration timer and corresponging Tx/Rx counter.
405 			 * timer 25ns*0xfa0=100us for 0xf packets.
406 			 * 2010.03.05.
407 			 */
408 			rtw_write32(adapter, REG_INT_MIG, 0xff000fa0); /* 0x306:Rx, 0x307:Tx */
409 			hal->bInterruptMigration = IntMtToSet;
410 		} else {
411 			/* Reset all interrupt migration settings. */
412 			rtw_write32(adapter, REG_INT_MIG, 0);
413 			hal->bInterruptMigration = IntMtToSet;
414 		}
415 	}
416 }
417 #endif /* CONFIG_PCI_HCI */
418 
419 /*
420  * ============================================================
421  * functions
422  * ============================================================
423  */
init_phydm_cominfo(PADAPTER adapter)424 static void init_phydm_cominfo(PADAPTER adapter)
425 {
426 	PHAL_DATA_TYPE hal;
427 	struct dm_struct *p_dm_odm;
428 	u32 support_ability = 0;
429 	u8 cut_ver = ODM_CUT_A, fab_ver = ODM_TSMC;
430 
431 
432 	hal = GET_HAL_DATA(adapter);
433 	p_dm_odm = &hal->odmpriv;
434 
435 	Init_ODM_ComInfo(adapter);
436 
437 	odm_cmn_info_init(p_dm_odm, ODM_CMNINFO_PACKAGE_TYPE, hal->PackageType);
438 	odm_cmn_info_init(p_dm_odm, ODM_CMNINFO_IC_TYPE, ODM_RTL8822B);
439 
440 	if (IS_CHIP_VENDOR_TSMC(hal->version_id))
441 		fab_ver = ODM_TSMC;
442 	else if (IS_CHIP_VENDOR_UMC(hal->version_id))
443 		fab_ver = ODM_UMC;
444 	else if (IS_CHIP_VENDOR_SMIC(hal->version_id))
445 		fab_ver = ODM_UMC + 1;
446 	else
447 		RTW_INFO("%s: unknown Fv=%d !!\n",
448 			 __FUNCTION__, GET_CVID_MANUFACTUER(hal->version_id));
449 
450 	if (IS_A_CUT(hal->version_id))
451 		cut_ver = ODM_CUT_A;
452 	else if (IS_B_CUT(hal->version_id))
453 		cut_ver = ODM_CUT_B;
454 	else if (IS_C_CUT(hal->version_id))
455 		cut_ver = ODM_CUT_C;
456 	else if (IS_D_CUT(hal->version_id))
457 		cut_ver = ODM_CUT_D;
458 	else if (IS_E_CUT(hal->version_id))
459 		cut_ver = ODM_CUT_E;
460 	else if (IS_F_CUT(hal->version_id))
461 		cut_ver = ODM_CUT_F;
462 	else if (IS_I_CUT(hal->version_id))
463 		cut_ver = ODM_CUT_I;
464 	else if (IS_J_CUT(hal->version_id))
465 		cut_ver = ODM_CUT_J;
466 	else if (IS_K_CUT(hal->version_id))
467 		cut_ver = ODM_CUT_K;
468 	else
469 		RTW_INFO("%s: unknown Cv=%d !!\n",
470 			 __FUNCTION__, GET_CVID_CUT_VERSION(hal->version_id));
471 
472 	RTW_INFO("%s: Fv=%d Cv=%d\n", __FUNCTION__, fab_ver, cut_ver);
473 	odm_cmn_info_init(p_dm_odm, ODM_CMNINFO_FAB_VER, fab_ver);
474 	odm_cmn_info_init(p_dm_odm, ODM_CMNINFO_CUT_VER, cut_ver);
475 
476 }
477 
rtl8822b_phy_init_dm_priv(PADAPTER adapter)478 void rtl8822b_phy_init_dm_priv(PADAPTER adapter)
479 {
480 	struct dm_struct *podmpriv = adapter_to_phydm(adapter);
481 
482 	init_phydm_cominfo(adapter);
483 	odm_init_all_timers(podmpriv);
484 }
485 
rtl8822b_phy_deinit_dm_priv(PADAPTER adapter)486 void rtl8822b_phy_deinit_dm_priv(PADAPTER adapter)
487 {
488 	struct dm_struct *podmpriv = adapter_to_phydm(adapter);
489 
490 	odm_cancel_all_timers(podmpriv);
491 }
492 
rtl8822b_phy_init_haldm(PADAPTER adapter)493 void rtl8822b_phy_init_haldm(PADAPTER adapter)
494 {
495 	rtw_phydm_init(adapter);
496 }
497 
check_rxfifo_full(PADAPTER adapter)498 static void check_rxfifo_full(PADAPTER adapter)
499 {
500 	struct dvobj_priv *psdpriv = adapter->dvobj;
501 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
502 	struct registry_priv *regsty = &adapter->registrypriv;
503 	u8 val8 = 0;
504 
505 	if (regsty->check_hw_status == 1) {
506 		pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
507 		pdbgpriv->dbg_rx_fifo_curr_overflow = rtl8822b_rx_report_get(adapter, RX_FULL_DROP);
508 		if (pdbgpriv->dbg_rx_fifo_curr_overflow >= pdbgpriv->dbg_rx_fifo_last_overflow)
509 			pdbgpriv->dbg_rx_fifo_diff_overflow =
510 				pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
511 		else
512 			pdbgpriv->dbg_rx_fifo_diff_overflow =
513 				(0xFFFF - pdbgpriv->dbg_rx_fifo_last_overflow)
514 				+ pdbgpriv->dbg_rx_fifo_curr_overflow;
515 	}
516 }
517 
rtl8822b_phy_haldm_watchdog(PADAPTER adapter)518 void rtl8822b_phy_haldm_watchdog(PADAPTER adapter)
519 {
520 	BOOLEAN bFwCurrentInPSMode = _FALSE;
521 	u8 bFwPSAwake = _TRUE;
522 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
523 	u8 lps_changed = _FALSE;
524 	u8 in_lps = _FALSE;
525 	PADAPTER current_lps_iface = NULL, iface = NULL;
526 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
527 	u8 i = 0;
528 
529 #ifdef CONFIG_MP_INCLUDED
530 	/* for MP power tracking */
531 	if ((adapter->registrypriv.mp_mode == 1)
532 	    && (adapter->mppriv.mp_dm == 0))
533 		return;
534 #endif /* CONFIG_MP_INCLUDED */
535 
536 	if (!rtw_is_hw_init_completed(adapter))
537 		goto skip_dm;
538 
539 #ifdef CONFIG_LPS
540 	bFwCurrentInPSMode = adapter_to_pwrctl(adapter)->bFwCurrentInPSMode;
541 	rtw_hal_get_hwreg(adapter, HW_VAR_FWLPS_RF_ON, &bFwPSAwake);
542 #endif /* CONFIG_LPS */
543 
544 #ifdef CONFIG_P2P_PS
545 	/*
546 	 * Fw is under p2p powersaving mode, driver should stop dynamic mechanism.
547 	 */
548 	if (adapter->wdinfo.p2p_ps_mode)
549 		bFwPSAwake = _FALSE;
550 #endif /* CONFIG_P2P_PS */
551 
552 	if ((rtw_is_hw_init_completed(adapter))
553 	    && ((!bFwCurrentInPSMode) && bFwPSAwake)) {
554 
555 		/* check rx fifo */
556 		check_rxfifo_full(adapter);
557 		/*
558 		 * Dynamically switch RTS/CTS protection.
559 		 */
560 	}
561 
562 #ifdef CONFIG_LPS
563 	if (pwrpriv->bLeisurePs && bFwCurrentInPSMode && pwrpriv->pwr_mode != PS_MODE_ACTIVE
564 #ifdef CONFIG_WMMPS_STA
565 		&& !rtw_is_wmmps_mode(adapter)
566 #endif /* CONFIG_WMMPS_STA */
567 	) {
568 
569 		for (i = 0; i < dvobj->iface_nums; i++) {
570 			iface = dvobj->padapters[i];
571 			if (pwrpriv->current_lps_hw_port_id == rtw_hal_get_port(iface))
572 				current_lps_iface = iface;
573 		}
574 
575 		lps_changed = _TRUE;
576 		in_lps = _TRUE;
577 		LPS_Leave(current_lps_iface, LPS_CTRL_PHYDM);
578 	}
579 #endif
580 
581 #ifdef CONFIG_BEAMFORMING
582 #ifdef RTW_BEAMFORMING_VERSION_2
583 	if (check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) &&
584 			check_fwstate(&adapter->mlmepriv, _FW_LINKED))
585 		rtw_hal_beamforming_config_csirate(adapter);
586 #endif
587 #endif
588 
589 #ifdef CONFIG_DISABLE_ODM
590 	goto skip_dm;
591 #endif
592 
593 	rtw_phydm_watchdog(adapter, in_lps);
594 
595 
596 skip_dm:
597 
598 #ifdef CONFIG_LPS
599 	if (lps_changed)
600 		LPS_Enter(current_lps_iface, LPS_CTRL_PHYDM);
601 #endif
602 
603 	/*
604 	 * Check GPIO to determine current RF on/off and Pbc status.
605 	 * Check Hardware Radio ON/OFF or not
606 	 */
607 #ifdef CONFIG_SUPPORT_HW_WPS_PBC
608 	dm_CheckPbcGPIO(adapter);
609 #else /* !CONFIG_SUPPORT_HW_WPS_PBC */
610 	return;
611 #endif /* !CONFIG_SUPPORT_HW_WPS_PBC */
612 }
613 
phy_calculatebitshift(u32 mask)614 static u32 phy_calculatebitshift(u32 mask)
615 {
616 	u32 i;
617 
618 
619 	for (i = 0; i <= 31; i++)
620 		if (mask & BIT(i))
621 			break;
622 
623 	return i;
624 }
625 
rtl8822b_read_bb_reg(PADAPTER adapter,u32 addr,u32 mask)626 u32 rtl8822b_read_bb_reg(PADAPTER adapter, u32 addr, u32 mask)
627 {
628 	u32 val = 0, val_org, shift;
629 
630 
631 #if (DISABLE_BB_RF == 1)
632 	return 0;
633 #endif
634 
635 	val_org = rtw_read32(adapter, addr);
636 	shift = phy_calculatebitshift(mask);
637 	val = (val_org & mask) >> shift;
638 
639 	return val;
640 }
641 
rtl8822b_write_bb_reg(PADAPTER adapter,u32 addr,u32 mask,u32 val)642 void rtl8822b_write_bb_reg(PADAPTER adapter, u32 addr, u32 mask, u32 val)
643 {
644 	u32 val_org, shift;
645 
646 
647 #if (DISABLE_BB_RF == 1)
648 	return;
649 #endif
650 
651 	if (mask != 0xFFFFFFFF) {
652 		/* not "double word" write */
653 		val_org = rtw_read32(adapter, addr);
654 		shift = phy_calculatebitshift(mask);
655 		val = ((val_org & (~mask)) | ((val << shift) & mask));
656 	}
657 
658 	rtw_write32(adapter, addr, val);
659 }
660 
rtl8822b_read_rf_reg(PADAPTER adapter,enum rf_path path,u32 addr,u32 mask)661 u32 rtl8822b_read_rf_reg(PADAPTER adapter, enum rf_path path, u32 addr, u32 mask)
662 {
663 	struct dm_struct *phydm = adapter_to_phydm(adapter);
664 	u32 val;
665 
666 	val = config_phydm_read_rf_reg_8822b(phydm, path, addr, mask);
667 	if (!config_phydm_read_rf_check_8822b(val))
668 		RTW_INFO(FUNC_ADPT_FMT ": read RF reg path=%d addr=0x%x mask=0x%x FAIL!\n",
669 			 FUNC_ADPT_ARG(adapter), path, addr, mask);
670 
671 	return val;
672 }
673 
rtl8822b_write_rf_reg(PADAPTER adapter,enum rf_path path,u32 addr,u32 mask,u32 val)674 void rtl8822b_write_rf_reg(PADAPTER adapter, enum rf_path path, u32 addr, u32 mask, u32 val)
675 {
676 	struct dm_struct *phydm = adapter_to_phydm(adapter);
677 	u8 ret;
678 
679 	ret = config_phydm_write_rf_reg_8822b(phydm, path, addr, mask, val);
680 	if (_FALSE == ret)
681 		RTW_INFO(FUNC_ADPT_FMT ": write RF reg path=%d addr=0x%x mask=0x%x val=0x%x FAIL!\n",
682 			 FUNC_ADPT_ARG(adapter), path, addr, mask, val);
683 }
684 
set_tx_power_level_by_path(PADAPTER adapter,u8 channel,u8 path)685 static void set_tx_power_level_by_path(PADAPTER adapter, u8 channel, u8 path)
686 {
687 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
688 	u8 under_survey_ch = phy_check_under_survey_ch(adapter);
689 	u8 under_24g = (hal->current_band_type == BAND_ON_2_4G);
690 
691 	if (under_24g)
692 		phy_set_tx_power_index_by_rate_section(adapter, path, channel, CCK);
693 
694 	phy_set_tx_power_index_by_rate_section(adapter, path, channel, OFDM);
695 
696 	if (!under_survey_ch) {
697 		phy_set_tx_power_index_by_rate_section(adapter, path, channel, HT_MCS0_MCS7);
698 		phy_set_tx_power_index_by_rate_section(adapter, path, channel, HT_MCS8_MCS15);
699 		phy_set_tx_power_index_by_rate_section(adapter, path, channel, VHT_1SSMCS0_1SSMCS9);
700 		phy_set_tx_power_index_by_rate_section(adapter, path, channel, VHT_2SSMCS0_2SSMCS9);
701 	}
702 }
703 
rtl8822b_set_tx_power_level(PADAPTER adapter,u8 channel)704 void rtl8822b_set_tx_power_level(PADAPTER adapter, u8 channel)
705 {
706 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
707 	struct dm_struct *phydm;
708 	#ifdef CONFIG_ANTENNA_DIVERSITY
709 	struct phydm_fat_struct *p_dm_fat_table;
710 	#endif
711 	u8 path = RF_PATH_A;
712 
713 
714 	hal = GET_HAL_DATA(adapter);
715 	phydm = &hal->odmpriv;
716 
717 	#ifdef CONFIG_ANTENNA_DIVERSITY
718 	p_dm_fat_table = &phydm->dm_fat_table;
719 
720 	if (hal->AntDivCfg) {
721 		/* antenna diversity Enable */
722 		path = (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? RF_PATH_A : RF_PATH_B;
723 		set_tx_power_level_by_path(adapter, channel, path);
724 	} else
725 	#endif
726 	{
727 		/* antenna diversity disable */
728 		for (path = RF_PATH_A; path < hal->NumTotalRFPath; ++path)
729 			set_tx_power_level_by_path(adapter, channel, path);
730 	}
731 }
732 
733 /*
734  * Parameters:
735  *	padatper
736  *	powerindex	power index for rate
737  *	rfpath		Antenna(RF) path, type "enum rf_path"
738  *	rate		data rate, type "enum MGN_RATE"
739  */
rtl8822b_set_tx_power_index(PADAPTER adapter,u32 powerindex,enum rf_path rfpath,u8 rate)740 void rtl8822b_set_tx_power_index(PADAPTER adapter, u32 powerindex, enum rf_path rfpath, u8 rate)
741 {
742 	HAL_DATA_TYPE *hal = GET_HAL_DATA(adapter);
743 	struct dm_struct *phydm = adapter_to_phydm(adapter);
744 	u8 shift = 0;
745 	boolean write_ret;
746 
747 	if (!IS_1T_RATE(rate) && !IS_2T_RATE(rate)) {
748 		RTW_ERR(FUNC_ADPT_FMT" invalid rate(%s)\n", FUNC_ADPT_ARG(adapter), MGN_RATE_STR(rate));
749 		rtw_warn_on(1);
750 		goto exit;
751 	}
752 
753 	rate = MRateToHwRate(rate);
754 
755 	/*
756 	* For 8822B, phydm api use 4 bytes txagc value
757 	* driver must combine every four 1 byte to one 4 byte and send to phydm api
758 	*/
759 	shift = rate % 4;
760 	hal->txagc_set_buf |= ((powerindex & 0xff) << (shift * 8));
761 
762 	if (shift != 3)
763 		goto exit;
764 
765 	rate = rate & 0xFC;
766 	write_ret = config_phydm_write_txagc_8822b(phydm, hal->txagc_set_buf, rfpath, rate);
767 
768 	if (write_ret == true && !DBG_TX_POWER_IDX)
769 		goto clear_buf;
770 
771 	RTW_INFO(FUNC_ADPT_FMT" (index:0x%08x, %c, rate:%s(0x%02x), disable api:%d) %s\n"
772 		, FUNC_ADPT_ARG(adapter), hal->txagc_set_buf, rf_path_char(rfpath)
773 		, HDATA_RATE(rate), rate, phydm->is_disable_phy_api
774 		, write_ret == true ? "OK" : "FAIL");
775 
776 	rtw_warn_on(write_ret != true);
777 
778 clear_buf:
779 	hal->txagc_set_buf = 0;
780 
781 exit:
782 	return;
783 }
784 
785 /*
786  * Description:
787  *	Check need to switch band or not
788  * Parameters:
789  *	channelToSW	channel wiii be switch to
790  * Return:
791  *	_TRUE		need to switch band
792  *	_FALSE		not need to switch band
793  */
need_switch_band(PADAPTER adapter,u8 channelToSW)794 static u8 need_switch_band(PADAPTER adapter, u8 channelToSW)
795 {
796 	u8 u1tmp = 0;
797 	u8 ret_value = _TRUE;
798 	u8 Band = BAND_ON_5G, BandToSW = BAND_ON_5G;
799 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
800 
801 	Band = hal->current_band_type;
802 
803 	/* Use current swich channel to judge Band Type and switch Band if need */
804 	if (channelToSW > 14)
805 		BandToSW = BAND_ON_5G;
806 	else
807 		BandToSW = BAND_ON_2_4G;
808 
809 	if (BandToSW != Band) {
810 		/* record current band type for other hal use */
811 		hal->current_band_type = (BAND_TYPE)BandToSW;
812 		ret_value = _TRUE;
813 	} else
814 		ret_value = _FALSE;
815 
816 	return ret_value;
817 }
818 
get_pri_ch_id(PADAPTER adapter)819 static u8 get_pri_ch_id(PADAPTER adapter)
820 {
821 	u8 pri_ch_idx = 0;
822 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
823 
824 	if (hal->current_channel_bw == CHANNEL_WIDTH_80) {
825 		/* primary channel is at lower subband of 80MHz & 40MHz */
826 		if ((hal->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (hal->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
827 			pri_ch_idx = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
828 		/* primary channel is at lower subband of 80MHz & upper subband of 40MHz */
829 		else if ((hal->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (hal->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
830 			pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ;
831 		/* primary channel is at upper subband of 80MHz & lower subband of 40MHz */
832 		else if ((hal->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (hal->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
833 			pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ;
834 		/* primary channel is at upper subband of 80MHz & upper subband of 40MHz */
835 		else if ((hal->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (hal->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
836 			pri_ch_idx = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
837 		else {
838 			if (hal->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
839 				pri_ch_idx = VHT_DATA_SC_40_LOWER_OF_80MHZ;
840 			else if (hal->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
841 				pri_ch_idx = VHT_DATA_SC_40_UPPER_OF_80MHZ;
842 			else
843 				RTW_INFO("SCMapping: DONOT CARE Mode Setting\n");
844 		}
845 	} else if (hal->current_channel_bw == CHANNEL_WIDTH_40) {
846 		/* primary channel is at upper subband of 40MHz */
847 		if (hal->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
848 			pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ;
849 		/* primary channel is at lower subband of 40MHz */
850 		else if (hal->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
851 			pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ;
852 		else
853 			RTW_INFO("SCMapping: DONOT CARE Mode Setting\n");
854 	}
855 
856 	return  pri_ch_idx;
857 }
858 
mac_switch_bandwidth(PADAPTER adapter,u8 pri_ch_idx)859 static void mac_switch_bandwidth(PADAPTER adapter, u8 pri_ch_idx)
860 {
861 	u8 channel = 0, bw = 0;
862 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
863 	int err;
864 
865 	channel = hal->current_channel;
866 	bw = hal->current_channel_bw;
867 	err = rtw_halmac_set_bandwidth(adapter_to_dvobj(adapter), channel, pri_ch_idx, bw);
868 	if (err) {
869 		RTW_INFO(FUNC_ADPT_FMT ": (channel=%d, pri_ch_idx=%d, bw=%d) fail\n",
870 			 FUNC_ADPT_ARG(adapter), channel, pri_ch_idx, bw);
871 	}
872 }
873 
switch_chnl_and_set_bw_by_drv(PADAPTER adapter,u8 switch_band)874 static void switch_chnl_and_set_bw_by_drv(PADAPTER adapter, u8 switch_band)
875 {
876 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
877 	struct dm_struct *p_dm_odm = &hal->odmpriv;
878 	u8 center_ch = 0, ret = 0;
879 
880 	/* set channel & Bandwidth register */
881 	/* 1. set switch band register if need to switch band */
882 	if (switch_band) {
883 		/* hal->current_channel is center channel of pmlmeext->cur_channel(primary channel) */
884 		ret = config_phydm_switch_band_8822b(p_dm_odm, hal->current_channel);
885 
886 		if (!ret) {
887 			RTW_INFO("%s: config_phydm_switch_band_8822b fail\n", __FUNCTION__);
888 			rtw_warn_on(1);
889 			return;
890 		}
891 	}
892 
893 	/* 2. set channel register */
894 	if (hal->bSwChnl) {
895 		ret = config_phydm_switch_channel_8822b(p_dm_odm, hal->current_channel);
896 		hal->bSwChnl = _FALSE;
897 
898 		if (!ret) {
899 			RTW_INFO("%s: config_phydm_switch_channel_8822b fail\n", __FUNCTION__);
900 			rtw_warn_on(1);
901 			return;
902 		}
903 	}
904 
905 	/* 3. set Bandwidth register */
906 	if (hal->bSetChnlBW) {
907 		/* get primary channel index */
908 		u8 pri_ch_idx = get_pri_ch_id(adapter);
909 
910 		/* 3.1 set MAC register */
911 		mac_switch_bandwidth(adapter, pri_ch_idx);
912 
913 		/* 3.2 set BB/RF registet */
914 		ret = config_phydm_switch_bandwidth_8822b(p_dm_odm, pri_ch_idx, hal->current_channel_bw);
915 		hal->bSetChnlBW = _FALSE;
916 
917 		if (!ret) {
918 			RTW_INFO("%s: config_phydm_switch_bandwidth_8822b fail\n", __FUNCTION__);
919 			rtw_warn_on(1);
920 			return;
921 		}
922 	}
923 }
924 
925 #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
switch_chnl_and_set_bw_by_fw(PADAPTER adapter,u8 switch_band)926 static void switch_chnl_and_set_bw_by_fw(PADAPTER adapter, u8 switch_band)
927 {
928 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
929 
930 	if (switch_band ||hal->bSwChnl || hal->bSetChnlBW) {
931 		rtw_hal_switch_chnl_and_set_bw_offload(adapter,
932 			hal->current_channel, get_pri_ch_id(adapter), hal->current_channel_bw);
933 
934 		hal->bSwChnl = _FALSE;
935 		hal->bSetChnlBW = _FALSE;
936 	}
937 }
938 #endif
939 
940 /*
941  * Description:
942  *	Set channel & bandwidth & offset
943  */
rtl8822b_switch_chnl_and_set_bw(PADAPTER adapter)944 void rtl8822b_switch_chnl_and_set_bw(PADAPTER adapter)
945 {
946 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
947 	struct dm_struct *p_dm_odm = &hal->odmpriv;
948 	u8 center_ch = 0, ret = 0, switch_band = _FALSE;
949 
950 	if (adapter->bNotifyChannelChange) {
951 		RTW_INFO("[%s] bSwChnl=%d, ch=%d, bSetChnlBW=%d, bw=%d\n",
952 			 __FUNCTION__,
953 			 hal->bSwChnl,
954 			 hal->current_channel,
955 			 hal->bSetChnlBW,
956 			 hal->current_channel_bw);
957 	}
958 
959 	if (RTW_CANNOT_RUN(adapter)) {
960 		hal->bSwChnlAndSetBWInProgress = _FALSE;
961 		return;
962 	}
963 
964 	switch_band = need_switch_band(adapter, hal->current_channel);
965 
966 	/* config channel, bw, offset setting */
967 #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
968 	if (hal->ch_switch_offload) {
969 
970 	#ifdef RTW_REDUCE_SCAN_SWITCH_CH_TIME
971 		struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
972 		_adapter *iface;
973 		struct mlme_ext_priv *mlmeext;
974 		u8 drv_switch = _TRUE;
975 		int i;
976 
977 		for (i = 0; i < dvobj->iface_nums; i++) {
978 			iface = dvobj->padapters[i];
979 			mlmeext = &iface->mlmeextpriv;
980 
981 			/* check scan state */
982 			if (mlmeext_scan_state(mlmeext) != SCAN_DISABLE
983 				&& mlmeext_scan_state(mlmeext) != SCAN_COMPLETE
984 					&& mlmeext_scan_state(mlmeext) != SCAN_BACKING_OP)
985 				drv_switch = _FALSE;
986 		}
987 	#else
988 		u8 drv_switch = _FALSE;
989 	#endif
990 
991 		if (drv_switch == _TRUE)
992 			switch_chnl_and_set_bw_by_drv(adapter, switch_band);
993 		else
994 			switch_chnl_and_set_bw_by_fw(adapter, switch_band);
995 
996 	} else {
997 		switch_chnl_and_set_bw_by_drv(adapter, switch_band);
998 	}
999 #else
1000 	switch_chnl_and_set_bw_by_drv(adapter, switch_band);
1001 #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */
1002 
1003 
1004 	/* config coex setting */
1005 	if (switch_band) {
1006 #ifdef CONFIG_BT_COEXIST
1007 		if (hal->EEPROMBluetoothCoexist) {
1008 			struct mlme_ext_priv *mlmeext;
1009 
1010 			/* switch band under site survey or not, must notify to BT COEX */
1011 			mlmeext = &adapter->mlmeextpriv;
1012 			if (mlmeext_scan_state(mlmeext) != SCAN_DISABLE)
1013 				rtw_btcoex_switchband_notify(_TRUE, hal->current_band_type);
1014 			else
1015 				rtw_btcoex_switchband_notify(_FALSE, hal->current_band_type);
1016 		} else
1017 			rtw_btcoex_wifionly_switchband_notify(adapter);
1018 #else /* !CONFIG_BT_COEXIST */
1019 		rtw_btcoex_wifionly_switchband_notify(adapter);
1020 #endif /* CONFIG_BT_COEXIST */
1021 	}
1022 
1023 	/* <2016/03/09> ** This Setting is for MP Driver Only*/
1024 #ifdef CONFIG_MP_INCLUDED
1025 	if (adapter->registrypriv.mp_mode == _TRUE) {
1026 		/* <2016/02/25, VincentL> Add for 8822B Antenna Binding between "2.4G-WiFi"
1027 			And between "5G-BT", Suggested by RF SzuyiTsai*/
1028 		if (hal->current_channel <= 14) /* 2.4G*/
1029 			phy_set_rf_path_switch_8822b(p_dm_odm, 1); /*To WiFi-2.4G*/
1030 		else /* 5G */
1031 			phy_set_rf_path_switch_8822b(p_dm_odm, 0); /*To BT-5G*/
1032 	}
1033 #endif
1034 
1035 	phydm_config_kfree(p_dm_odm, hal->current_channel);
1036 
1037 	/* TX Power Setting */
1038 	odm_clear_txpowertracking_state(p_dm_odm);
1039 	rtw_hal_set_tx_power_level(adapter, hal->current_channel);
1040 
1041 	/* IQK */
1042 	if ((hal->bNeedIQK == _TRUE)
1043 	    || (adapter->registrypriv.mp_mode == 1)) {
1044 		/*phy_iq_calibrate_8822b(p_dm_odm, _FALSE);*/
1045 		rtw_phydm_iqk_trigger(adapter);
1046 		hal->bNeedIQK = _FALSE;
1047 	}
1048 }
1049 
1050 /*
1051  * Description:
1052  *	Store channel setting to hal date
1053  * Parameters:
1054  *	bSwitchChannel		swith channel or not
1055  *	bSetBandWidth		set band or not
1056  *	ChannelNum		center channel
1057  *	ChnlWidth		bandwidth
1058  *	ChnlOffsetOf40MHz	channel offset for 40MHz Bandwidth
1059  *	ChnlOffsetOf80MHz	channel offset for 80MHz Bandwidth
1060  *	CenterFrequencyIndex1	center channel index
1061  */
1062 
rtl8822b_handle_sw_chnl_and_set_bw(PADAPTER Adapter,u8 bSwitchChannel,u8 bSetBandWidth,u8 ChannelNum,enum channel_width ChnlWidth,u8 ChnlOffsetOf40MHz,u8 ChnlOffsetOf80MHz,u8 CenterFrequencyIndex1)1063 void rtl8822b_handle_sw_chnl_and_set_bw(
1064 	PADAPTER Adapter, u8 bSwitchChannel, u8 bSetBandWidth,
1065 	u8 ChannelNum, enum channel_width ChnlWidth, u8 ChnlOffsetOf40MHz,
1066 	u8 ChnlOffsetOf80MHz, u8 CenterFrequencyIndex1)
1067 {
1068 	PADAPTER pDefAdapter = GetDefaultAdapter(Adapter);
1069 	PHAL_DATA_TYPE hal = GET_HAL_DATA(pDefAdapter);
1070 	u8 tmpChannel = hal->current_channel;
1071 	enum channel_width tmpBW = hal->current_channel_bw;
1072 	u8 tmpnCur40MhzPrimeSC = hal->nCur40MhzPrimeSC;
1073 	u8 tmpnCur80MhzPrimeSC = hal->nCur80MhzPrimeSC;
1074 	u8 tmpCenterFrequencyIndex1 = hal->CurrentCenterFrequencyIndex1;
1075 	struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
1076 
1077 
1078 	/* check swchnl or setbw */
1079 	if (!bSwitchChannel && !bSetBandWidth) {
1080 		RTW_INFO("%s: not switch channel and not set bandwidth\n", __FUNCTION__);
1081 		return;
1082 	}
1083 
1084 	/* skip switch channel operation for current channel & ChannelNum(will be switch) are the same */
1085 	if (bSwitchChannel) {
1086 		if (hal->current_channel != ChannelNum) {
1087 			if (HAL_IsLegalChannel(Adapter, ChannelNum))
1088 				hal->bSwChnl = _TRUE;
1089 			else
1090 				return;
1091 		}
1092 	}
1093 
1094 	/* check set BandWidth */
1095 	if (bSetBandWidth) {
1096 		/* initial channel bw setting */
1097 		if (hal->bChnlBWInitialized == _FALSE) {
1098 			hal->bChnlBWInitialized = _TRUE;
1099 			hal->bSetChnlBW = _TRUE;
1100 		} else if ((hal->current_channel_bw != ChnlWidth) || /* check whether need set band or not */
1101 			   (hal->nCur40MhzPrimeSC != ChnlOffsetOf40MHz) ||
1102 			   (hal->nCur80MhzPrimeSC != ChnlOffsetOf80MHz) ||
1103 			(hal->CurrentCenterFrequencyIndex1 != CenterFrequencyIndex1))
1104 			hal->bSetChnlBW = _TRUE;
1105 	}
1106 
1107 	/* return if not need set bandwidth nor channel after check*/
1108 	if (!hal->bSetChnlBW && !hal->bSwChnl && hal->bNeedIQK != _TRUE)
1109 		return;
1110 
1111 	/* set channel number to hal data */
1112 	if (hal->bSwChnl) {
1113 		hal->current_channel = ChannelNum;
1114 		hal->CurrentCenterFrequencyIndex1 = ChannelNum;
1115 	}
1116 
1117 	/* set bandwidth info to hal data */
1118 	if (hal->bSetChnlBW) {
1119 		hal->current_channel_bw = ChnlWidth;
1120 		hal->nCur40MhzPrimeSC = ChnlOffsetOf40MHz;
1121 		hal->nCur80MhzPrimeSC = ChnlOffsetOf80MHz;
1122 		hal->CurrentCenterFrequencyIndex1 = CenterFrequencyIndex1;
1123 	}
1124 
1125 	/* switch channel & bandwidth */
1126 	if (!RTW_CANNOT_RUN(Adapter))
1127 		rtl8822b_switch_chnl_and_set_bw(Adapter);
1128 	else {
1129 		if (hal->bSwChnl) {
1130 			hal->current_channel = tmpChannel;
1131 			hal->CurrentCenterFrequencyIndex1 = tmpChannel;
1132 		}
1133 
1134 		if (hal->bSetChnlBW) {
1135 			hal->current_channel_bw = tmpBW;
1136 			hal->nCur40MhzPrimeSC = tmpnCur40MhzPrimeSC;
1137 			hal->nCur80MhzPrimeSC = tmpnCur80MhzPrimeSC;
1138 			hal->CurrentCenterFrequencyIndex1 = tmpCenterFrequencyIndex1;
1139 		}
1140 	}
1141 }
1142 
1143 /*
1144  * Description:
1145  *	Change channel, bandwidth & offset
1146  * Parameters:
1147  *	center_ch	center channel
1148  *	bw		bandwidth
1149  *	offset40	channel offset for 40MHz Bandwidth
1150  *	offset80	channel offset for 80MHz Bandwidth
1151  */
rtl8822b_set_channel_bw(PADAPTER adapter,u8 center_ch,enum channel_width bw,u8 offset40,u8 offset80)1152 void rtl8822b_set_channel_bw(PADAPTER adapter, u8 center_ch, enum channel_width bw, u8 offset40, u8 offset80)
1153 {
1154 	rtl8822b_handle_sw_chnl_and_set_bw(adapter, _TRUE, _TRUE, center_ch, bw, offset40, offset80, center_ch);
1155 }
1156 
rtl8822b_notch_filter_switch(PADAPTER adapter,bool enable)1157 void rtl8822b_notch_filter_switch(PADAPTER adapter, bool enable)
1158 {
1159 	if (enable)
1160 		RTW_INFO("%s: Enable notch filter\n", __FUNCTION__);
1161 	else
1162 		RTW_INFO("%s: Disable notch filter\n", __FUNCTION__);
1163 }
1164 
1165 #ifdef CONFIG_MP_INCLUDED
1166 /*
1167  * Description:
1168  *	Config RF path
1169  *
1170  * Parameters:
1171  *	adapter	pointer of struct _ADAPTER
1172  */
rtl8822b_mp_config_rfpath(PADAPTER adapter)1173 void rtl8822b_mp_config_rfpath(PADAPTER adapter)
1174 {
1175 	PHAL_DATA_TYPE hal;
1176 	PMPT_CONTEXT mpt;
1177 	ANTENNA_PATH anttx, antrx;
1178 	enum bb_path bb_tx, bb_rx;
1179 
1180 
1181 	hal = GET_HAL_DATA(adapter);
1182 	mpt = &adapter->mppriv.mpt_ctx;
1183 	anttx = hal->antenna_tx_path;
1184 	antrx = hal->AntennaRxPath;
1185 	hal->antenna_test = _TRUE;
1186 	RTW_INFO("+Config RF Path, tx=0x%x rx=0x%x\n", anttx, antrx);
1187 
1188 	switch (anttx) {
1189 	case ANTENNA_A:
1190 		mpt->mpt_rf_path = RF_PATH_A;
1191 		bb_tx = BB_PATH_A;
1192 		break;
1193 	case ANTENNA_B:
1194 		mpt->mpt_rf_path = RF_PATH_B;
1195 		bb_tx = BB_PATH_B;
1196 		break;
1197 	case ANTENNA_AB:
1198 	default:
1199 		mpt->mpt_rf_path = RF_PATH_AB;
1200 		bb_tx = BB_PATH_A | BB_PATH_B;
1201 		break;
1202 	}
1203 
1204 	switch (antrx) {
1205 	case ANTENNA_A:
1206 		bb_rx = BB_PATH_A;
1207 		break;
1208 	case ANTENNA_B:
1209 		bb_rx = BB_PATH_B;
1210 		break;
1211 	case ANTENNA_AB:
1212 	default:
1213 		bb_rx = BB_PATH_A | BB_PATH_B;
1214 		break;
1215 	}
1216 
1217 	phydm_api_trx_mode(GET_PDM_ODM(adapter), bb_tx, bb_rx, bb_tx);
1218 
1219 	RTW_INFO("-Config RF Path Finish\n");
1220 }
1221 #endif /* CONFIG_MP_INCLUDED */
1222 
1223 #ifdef CONFIG_BEAMFORMING
1224 /* REG_TXBF_CTRL		(Offset 0x42C) */
1225 #define BITS_R_TXBF1_AID_8822B			(BIT_MASK_R_TXBF1_AID_8822B << BIT_SHIFT_R_TXBF1_AID_8822B)
1226 #define BIT_CLEAR_R_TXBF1_AID_8822B(x)		((x) & (~BITS_R_TXBF1_AID_8822B))
1227 #define BIT_SET_R_TXBF1_AID_8822B(x, v)		(BIT_CLEAR_R_TXBF1_AID_8822B(x) | BIT_R_TXBF1_AID_8822B(v))
1228 
1229 #define BITS_R_TXBF0_AID_8822B			(BIT_MASK_R_TXBF0_AID_8822B << BIT_SHIFT_R_TXBF0_AID_8822B)
1230 #define BIT_CLEAR_R_TXBF0_AID_8822B(x)		((x) & (~BITS_R_TXBF0_AID_8822B))
1231 #define BIT_SET_R_TXBF0_AID_8822B(x, v)		(BIT_CLEAR_R_TXBF0_AID_8822B(x) | BIT_R_TXBF0_AID_8822B(v))
1232 
1233 /* REG_NDPA_OPT_CTRL		(Offset 0x45F) */
1234 #define BITS_R_NDPA_BW_8822B			(BIT_MASK_R_NDPA_BW_8822B << BIT_SHIFT_R_NDPA_BW_8822B)
1235 #define BIT_CLEAR_R_NDPA_BW_8822B(x)		((x) & (~BITS_R_NDPA_BW_8822B))
1236 #define BIT_SET_R_NDPA_BW_8822B(x, v)		(BIT_CLEAR_R_NDPA_BW_8822B(x) | BIT_R_NDPA_BW_8822B(v))
1237 
1238 /* REG_ASSOCIATED_BFMEE_SEL	(Offset 0x714) */
1239 #define BITS_AID1_8822B				(BIT_MASK_AID1_8822B << BIT_SHIFT_AID1_8822B)
1240 #define BIT_CLEAR_AID1_8822B(x)			((x) & (~BITS_AID1_8822B))
1241 #define BIT_SET_AID1_8822B(x, v)		(BIT_CLEAR_AID1_8822B(x) | BIT_AID1_8822B(v))
1242 
1243 #define BITS_AID0_8822B				(BIT_MASK_AID0_8822B << BIT_SHIFT_AID0_8822B)
1244 #define BIT_CLEAR_AID0_8822B(x)			((x) & (~BITS_AID0_8822B))
1245 #define BIT_SET_AID0_8822B(x, v)		(BIT_CLEAR_AID0_8822B(x) | BIT_AID0_8822B(v))
1246 
1247 /* REG_SND_PTCL_CTRL		(Offset 0x718) */
1248 #define BIT_VHTNDP_RPTPOLL_CSI_STR_OFFSET_SEL_8822B	BIT(15)
1249 
1250 /* REG_MU_TX_CTL		(Offset 0x14C0) */
1251 #define BIT_R_MU_P1_WAIT_STATE_EN_8822B		BIT(16)
1252 
1253 #define BIT_SHIFT_R_MU_RL_8822B			12
1254 #define BIT_MASK_R_MU_RL_8822B			0xF
1255 #define BITS_R_MU_RL_8822B			(BIT_MASK_R_MU_RL_8822B << BIT_SHIFT_R_MU_RL_8822B)
1256 #define BIT_R_MU_RL_8822B(x)			(((x) & BIT_MASK_R_MU_RL_8822B) << BIT_SHIFT_R_MU_RL_8822B)
1257 #define BIT_CLEAR_R_MU_RL_8822B(x)		((x) & (~BITS_R_MU_RL_8822B))
1258 #define BIT_SET_R_MU_RL_8822B(x, v)		(BIT_CLEAR_R_MU_RL_8822B(x) | BIT_R_MU_RL_8822B(v))
1259 
1260 #define BIT_SHIFT_R_MU_TAB_SEL_8822B		8
1261 #define BIT_MASK_R_MU_TAB_SEL_8822B		0x7
1262 #define BITS_R_MU_TAB_SEL_8822B			(BIT_MASK_R_MU_TAB_SEL_8822B << BIT_SHIFT_R_MU_TAB_SEL_8822B)
1263 #define BIT_R_MU_TAB_SEL_8822B(x)		(((x) & BIT_MASK_R_MU_TAB_SEL_8822B) << BIT_SHIFT_R_MU_TAB_SEL_8822B)
1264 #define BIT_CLEAR_R_MU_TAB_SEL_8822B(x)		((x) & (~BITS_R_MU_TAB_SEL_8822B))
1265 #define BIT_SET_R_MU_TAB_SEL_8822B(x, v)	(BIT_CLEAR_R_MU_TAB_SEL_8822B(x) | BIT_R_MU_TAB_SEL_8822B(v))
1266 
1267 #define BIT_R_EN_MU_MIMO_8822B			BIT(7)
1268 
1269 #define BITS_R_MU_TABLE_VALID_8822B		(BIT_MASK_R_MU_TABLE_VALID_8822B << BIT_SHIFT_R_MU_TABLE_VALID_8822B)
1270 #define BIT_CLEAR_R_MU_TABLE_VALID_8822B(x)	((x) & (~BITS_R_MU_TABLE_VALID_8822B))
1271 #define BIT_SET_R_MU_TABLE_VALID_8822B(x, v)	(BIT_CLEAR_R_MU_TABLE_VALID_8822B(x) | BIT_R_MU_TABLE_VALID_8822B(v))
1272 
1273 /* REG_WMAC_MU_BF_CTL		(Offset 0x1680) */
1274 #define BITS_WMAC_MU_BFRPTSEG_SEL_8822B			(BIT_MASK_WMAC_MU_BFRPTSEG_SEL_8822B << BIT_SHIFT_WMAC_MU_BFRPTSEG_SEL_8822B)
1275 #define BIT_CLEAR_WMAC_MU_BFRPTSEG_SEL_8822B(x)		((x) & (~BITS_WMAC_MU_BFRPTSEG_SEL_8822B))
1276 #define BIT_SET_WMAC_MU_BFRPTSEG_SEL_8822B(x, v)	(BIT_CLEAR_WMAC_MU_BFRPTSEG_SEL_8822B(x) | BIT_WMAC_MU_BFRPTSEG_SEL_8822B(v))
1277 
1278 #define BITS_WMAC_MU_BF_MYAID_8822B		(BIT_MASK_WMAC_MU_BF_MYAID_8822B << BIT_SHIFT_WMAC_MU_BF_MYAID_8822B)
1279 #define BIT_CLEAR_WMAC_MU_BF_MYAID_8822B(x)	((x) & (~BITS_WMAC_MU_BF_MYAID_8822B))
1280 #define BIT_SET_WMAC_MU_BF_MYAID_8822B(x, v)	(BIT_CLEAR_WMAC_MU_BF_MYAID_8822B(x) | BIT_WMAC_MU_BF_MYAID_8822B(v))
1281 
1282 /* REG_WMAC_ASSOCIATED_MU_BFMEE7	(Offset 0x168E) */
1283 #define BIT_STATUS_BFEE7_8822B			BIT(10)
1284 
1285 enum _HW_CFG_SOUNDING_TYPE {
1286 	HW_CFG_SOUNDING_TYPE_SOUNDDOWN,
1287 	HW_CFG_SOUNDING_TYPE_LEAVE,
1288 	HW_CFG_SOUNDING_TYPE_RESET,
1289 	HW_CFG_SOUNDING_TYPE_MAX
1290 };
1291 
_bf_get_nrx(PADAPTER adapter)1292 static u8 _bf_get_nrx(PADAPTER adapter)
1293 {
1294 	u8 nrx = 0;
1295 
1296 	nrx = GET_HAL_RX_NSS(adapter);
1297 	return (nrx - 1);
1298 }
1299 
_sounding_reset_all(PADAPTER adapter)1300 static void _sounding_reset_all(PADAPTER adapter)
1301 {
1302 	struct beamforming_info *info;
1303 	struct beamformee_entry *bfee;
1304 	u8 i;
1305 	u32 mu_tx_ctl;
1306 
1307 
1308 	info = GET_BEAMFORM_INFO(adapter);
1309 
1310 	rtw_write8(adapter, REG_TXBF_CTRL_8822B+3, 0);
1311 
1312 	/* Clear all MU entry table */
1313 	for (i = 0; i < MAX_BEAMFORMEE_ENTRY_NUM; i++) {
1314 		bfee = &info->bfee_entry[i];
1315 		for (i = 0; i < 8; i++)
1316 			bfee->gid_valid[i] = 0;
1317 	}
1318 
1319 	mu_tx_ctl = rtw_read32(adapter, REG_MU_TX_CTL_8822B);
1320 	for (i = 0; i < 6; i++) {
1321 		mu_tx_ctl = BIT_SET_R_MU_TAB_SEL_8822B(mu_tx_ctl, i);
1322 		rtw_write32(adapter, REG_MU_TX_CTL_8822B, mu_tx_ctl);
1323 		/* set MU STA gid valid table */
1324 		rtw_write32(adapter, REG_MU_STA_GID_VLD_8822B, 0);
1325 	}
1326 
1327 	/* Disable TxMU PPDU */
1328 	mu_tx_ctl &= ~BIT_R_EN_MU_MIMO_8822B;
1329 	rtw_write32(adapter, REG_MU_TX_CTL_8822B, mu_tx_ctl);
1330 }
1331 
_sounding_config_su(PADAPTER adapter,struct beamformee_entry * bfee,enum _HW_CFG_SOUNDING_TYPE cfg_type)1332 static void _sounding_config_su(PADAPTER adapter, struct beamformee_entry *bfee, enum _HW_CFG_SOUNDING_TYPE cfg_type)
1333 {
1334 	u32 txbf_ctrl, new_ctrl;
1335 
1336 
1337 	txbf_ctrl = rtw_read32(adapter, REG_TXBF_CTRL_8822B);
1338 	new_ctrl = txbf_ctrl;
1339 
1340 	/* Clear TxBF status at 20M/40/80M first */
1341 	switch (bfee->su_reg_index) {
1342 	case 0:
1343 		new_ctrl &= ~(BIT_R_TXBF0_20M_8822B|BIT_R_TXBF0_40M_8822B|BIT_R_TXBF0_80M_8822B);
1344 		break;
1345 	case 1:
1346 		new_ctrl &= ~(BIT_R_TXBF1_20M_8822B|BIT_R_TXBF1_40M_8822B|BIT_R_TXBF1_80M_8822B);
1347 		break;
1348 	}
1349 
1350 	switch (cfg_type) {
1351 	case HW_CFG_SOUNDING_TYPE_SOUNDDOWN:
1352 		switch (bfee->sound_bw) {
1353 		default:
1354 		case CHANNEL_WIDTH_80:
1355 			if (0 == bfee->su_reg_index)
1356 				new_ctrl |= BIT_R_TXBF0_80M_8822B;
1357 			else if (1 == bfee->su_reg_index)
1358 				new_ctrl |= BIT_R_TXBF1_80M_8822B;
1359 			/* fall through */
1360 		case CHANNEL_WIDTH_40:
1361 			if (0 == bfee->su_reg_index)
1362 				new_ctrl |= BIT_R_TXBF0_40M_8822B;
1363 			else if (1 == bfee->su_reg_index)
1364 				new_ctrl |= BIT_R_TXBF1_40M_8822B;
1365 			/* fall through */
1366 		case CHANNEL_WIDTH_20:
1367 			if (0 == bfee->su_reg_index)
1368 				new_ctrl |= BIT_R_TXBF0_20M_8822B;
1369 			else if (1 == bfee->su_reg_index)
1370 				new_ctrl |= BIT_R_TXBF1_20M_8822B;
1371 			break;
1372 		}
1373 		break;
1374 
1375 	default:
1376 		RTW_INFO("%s: SU cfg_type=%d, don't apply Vmatrix!\n", __FUNCTION__, cfg_type);
1377 		break;
1378 	}
1379 
1380 	if (new_ctrl != txbf_ctrl)
1381 		rtw_write32(adapter, REG_TXBF_CTRL_8822B, new_ctrl);
1382 }
1383 
_sounding_config_mu(PADAPTER adapter,struct beamformee_entry * bfee,enum _HW_CFG_SOUNDING_TYPE cfg_type)1384 static void _sounding_config_mu(PADAPTER adapter, struct beamformee_entry *bfee, enum _HW_CFG_SOUNDING_TYPE cfg_type)
1385 {
1386 	struct beamforming_info *info;
1387 	u8 is_bitmap_ready = _FALSE;
1388 	u32 mu_tx_ctl;
1389 	u16 bitmap;
1390 	u8 id1, id0, gid;
1391 	u32 gid_valid[6] = {0};
1392 	u8 i, j;
1393 	u32 val32;
1394 
1395 
1396 	info = GET_BEAMFORM_INFO(adapter);
1397 
1398 	switch (cfg_type) {
1399 	case HW_CFG_SOUNDING_TYPE_LEAVE:
1400 		RTW_INFO("%s: MU HW_CFG_SOUNDING_TYPE_LEAVE\n", __FUNCTION__);
1401 
1402 		/* Clear the entry table */
1403 		mu_tx_ctl = rtw_read32(adapter, REG_MU_TX_CTL_8822B);
1404 		if (TEST_FLAG(bfee->cap, BEAMFORMEE_CAP_VHT_MU)) {
1405 			for (i = 0; i < 8; i++)
1406 				bfee->gid_valid[i] = 0;
1407 
1408 			mu_tx_ctl = BIT_SET_R_MU_TAB_SEL_8822B(mu_tx_ctl, bfee->mu_reg_index);
1409 			rtw_write32(adapter, REG_MU_TX_CTL_8822B, mu_tx_ctl);
1410 			/* Set MU STA gid valid table */
1411 			rtw_write32(adapter, REG_MU_STA_GID_VLD_8822B, 0);
1412 		} else {
1413 			RTW_ERR("%s: ERROR! It is not an MU BFee entry!!\n",  __FUNCTION__);
1414 		}
1415 
1416 		if (info->beamformee_su_cnt == 0) {
1417 			/* Disable TxMU PPDU */
1418 			mu_tx_ctl &= ~BIT_R_EN_MU_MIMO_8822B;
1419 			rtw_write32(adapter, REG_MU_TX_CTL_8822B, mu_tx_ctl);
1420 		}
1421 
1422 		break;
1423 
1424 	case HW_CFG_SOUNDING_TYPE_SOUNDDOWN:
1425 		RTW_INFO("%s: MU HW_CFG_SOUNDING_TYPE_SOUNDDOWN\n",  __FUNCTION__);
1426 
1427 		/* Update all MU entry table */
1428 		i = 0;
1429 		do {
1430 			/* Check BB GID bitmap ready */
1431 			val32 = phy_query_bb_reg(adapter, 0xF4C, 0xFFFF0000);
1432 
1433 			is_bitmap_ready = (val32 & BIT(15)) ? _TRUE : _FALSE;
1434 			i++;
1435 			rtw_udelay_os(5);
1436 		} while ((_FALSE == is_bitmap_ready) && (i < 100));
1437 
1438 		bitmap = (u16)(val32 & 0x3FFF);
1439 
1440 		for (i = 0; i < 15; i++) {
1441 			if (i < 5) {
1442 				/* bit0~4 */
1443 				id0 = 0;
1444 				id1 = i + 1;
1445 			} else if (i < 9) {
1446 				/* bit5~8 */
1447 				id0 = 1;
1448 				id1 = i - 3;
1449 			} else if (i < 12) {
1450 				/* bit9~11 */
1451 				id0 = 2;
1452 				id1 = i - 6;
1453 			} else if (i < 14) {
1454 				/* bit12~13 */
1455 				id0 = 3;
1456 				id1 = i - 8;
1457 			} else {
1458 				/* bit14 */
1459 				id0 = 4;
1460 				id1 = i - 9;
1461 			}
1462 			if (bitmap & BIT(i)) {
1463 				/* Pair 1 */
1464 				gid = (i << 1) + 1;
1465 				gid_valid[id0] |= (BIT(gid));
1466 				gid_valid[id1] |= (BIT(gid));
1467 				/* Pair 2 */
1468 				gid += 1;
1469 				gid_valid[id0] |= (BIT(gid));
1470 				gid_valid[id1] |= (BIT(gid));
1471 			} else {
1472 				/* Pair 1 */
1473 				gid = (i << 1) + 1;
1474 				gid_valid[id0] &= ~(BIT(gid));
1475 				gid_valid[id1] &= ~(BIT(gid));
1476 				/* Pair 2 */
1477 				gid += 1;
1478 				gid_valid[id0] &= ~(BIT(gid));
1479 				gid_valid[id1] &= ~(BIT(gid));
1480 			}
1481 		}
1482 
1483 		for (i = 0; i < MAX_BEAMFORMEE_ENTRY_NUM; i++) {
1484 			bfee = &info->bfee_entry[i];
1485 			if (_FALSE == bfee->used)
1486 				continue;
1487 			if (TEST_FLAG(bfee->cap, BEAMFORMEE_CAP_VHT_MU)
1488 			    && (bfee->mu_reg_index < 6)) {
1489 				val32 = gid_valid[bfee->mu_reg_index];
1490 				for (j = 0; j < 4; j++) {
1491 					bfee->gid_valid[j] = (u8)(val32 & 0xFF);
1492 					val32 >>= 8;
1493 				}
1494 			}
1495 		}
1496 
1497 		mu_tx_ctl = rtw_read32(adapter, REG_MU_TX_CTL_8822B);
1498 		for (i = 0; i < 6; i++) {
1499 			mu_tx_ctl = BIT_SET_R_MU_TAB_SEL_8822B(mu_tx_ctl, i);
1500 			rtw_write32(adapter, REG_MU_TX_CTL_8822B, mu_tx_ctl);
1501 			/* Set MU STA gid valid table */
1502 			rtw_write32(adapter, REG_MU_STA_GID_VLD_8822B, gid_valid[i]);
1503 		}
1504 
1505 		/* Enable TxMU PPDU */
1506 		mu_tx_ctl |= BIT_R_EN_MU_MIMO_8822B;
1507 		rtw_write32(adapter, REG_MU_TX_CTL_8822B, mu_tx_ctl);
1508 
1509 		break;
1510 
1511 	default:
1512 		break;
1513 	}
1514 }
1515 
_config_sounding(PADAPTER adapter,struct beamformee_entry * bfee,u8 mu_sounding,enum _HW_CFG_SOUNDING_TYPE cfg_type)1516 static void _config_sounding(PADAPTER adapter, struct beamformee_entry *bfee, u8 mu_sounding, enum _HW_CFG_SOUNDING_TYPE cfg_type)
1517 {
1518 	if (cfg_type == HW_CFG_SOUNDING_TYPE_RESET) {
1519 		RTW_INFO("%s: HW_CFG_SOUNDING_TYPE_RESET\n", __FUNCTION__);
1520 		_sounding_reset_all(adapter);
1521 		return;
1522 	}
1523 
1524 	if (_FALSE == mu_sounding)
1525 		_sounding_config_su(adapter, bfee, cfg_type);
1526 	else
1527 		_sounding_config_mu(adapter, bfee, cfg_type);
1528 }
1529 
_config_beamformer_su(PADAPTER adapter,struct beamformer_entry * bfer)1530 static void _config_beamformer_su(PADAPTER adapter, struct beamformer_entry *bfer)
1531 {
1532 	/* Beamforming */
1533 	u8 nc_index = 0, nr_index = 0;
1534 	u8 grouping = 0, codebookinfo = 0, coefficientsize = 0;
1535 	u32 addr_bfer_info, addr_csi_rpt;
1536 	u32 csi_param;
1537 	/* Misc */
1538 	u8 i;
1539 
1540 
1541 	RTW_INFO("%s: Config SU BFer entry HW setting\n", __FUNCTION__);
1542 
1543 	if (bfer->su_reg_index == 0) {
1544 		addr_bfer_info = REG_ASSOCIATED_BFMER0_INFO_8822B;
1545 		addr_csi_rpt = REG_TX_CSI_RPT_PARAM_BW20_8822B;
1546 	} else {
1547 		addr_bfer_info = REG_ASSOCIATED_BFMER1_INFO_8822B;
1548 		addr_csi_rpt = REG_TX_CSI_RPT_PARAM_BW20_8822B + 2;
1549 	}
1550 
1551 	/* Sounding protocol control */
1552 	rtw_write8(adapter, REG_SND_PTCL_CTRL_8822B, 0xDB);
1553 
1554 	/* MAC address/Partial AID of Beamformer */
1555 	for (i = 0; i < ETH_ALEN; i++)
1556 		rtw_write8(adapter, addr_bfer_info+i, bfer->mac_addr[i]);
1557 
1558 	/* CSI report parameters of Beamformer */
1559 	nc_index = _bf_get_nrx(adapter);
1560 	/*
1561 	 * 0x718[7] = 1 use Nsts
1562 	 * 0x718[7] = 0 use reg setting
1563 	 * As Bfee, we use Nsts, so nr_index don't care
1564 	 */
1565 	nr_index = bfer->NumofSoundingDim;
1566 	grouping = 0;
1567 	/* for ac = 1, for n = 3 */
1568 	if (TEST_FLAG(bfer->cap, BEAMFORMER_CAP_VHT_SU))
1569 		codebookinfo = 1;
1570 	else if (TEST_FLAG(bfer->cap, BEAMFORMER_CAP_HT_EXPLICIT))
1571 		codebookinfo = 3;
1572 	coefficientsize = 3;
1573 	csi_param = (u16)((coefficientsize<<10)|(codebookinfo<<8)|(grouping<<6)|(nr_index<<3)|(nc_index));
1574 	rtw_write16(adapter, addr_csi_rpt, csi_param);
1575 	RTW_INFO("%s: nc=%d nr=%d group=%d codebookinfo=%d coefficientsize=%d\n",
1576 		 __FUNCTION__, nc_index, nr_index, grouping, codebookinfo, coefficientsize);
1577 	RTW_INFO("%s: csi=0x%04x\n", __FUNCTION__, csi_param);
1578 
1579 	/* ndp_rx_standby_timer */
1580 	rtw_write8(adapter, REG_SND_PTCL_CTRL_8822B+3, 0x70);
1581 }
1582 
_config_beamformer_mu(PADAPTER adapter,struct beamformer_entry * bfer)1583 static void _config_beamformer_mu(PADAPTER adapter, struct beamformer_entry *bfer)
1584 {
1585 	/* General */
1586 	PHAL_DATA_TYPE hal;
1587 	/* Beamforming */
1588 	struct beamforming_info *bf_info;
1589 	u8 nc_index = 0, nr_index = 0;
1590 	u8 grouping = 0, codebookinfo = 0, coefficientsize = 0;
1591 	u32 csi_param;
1592 	/* Misc */
1593 	u8 i, val8;
1594 	u16 val16;
1595 
1596 	RTW_INFO("%s: Config MU BFer entry HW setting\n", __FUNCTION__);
1597 
1598 	hal = GET_HAL_DATA(adapter);
1599 	bf_info = GET_BEAMFORM_INFO(adapter);
1600 
1601 	/* Reset GID table */
1602 	for (i = 0; i < 8; i++)
1603 		bfer->gid_valid[i] = 0;
1604 	for (i = 0; i < 16; i++)
1605 		bfer->user_position[i] = 0;
1606 
1607 	/* CSI report parameters of Beamformer */
1608 	nc_index = _bf_get_nrx(adapter);
1609 	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 */
1610 	grouping = 0; /* no grouping */
1611 	codebookinfo = 1; /* 7 bit for psi, 9 bit for phi */
1612 	coefficientsize = 0; /* This is nothing really matter */
1613 	csi_param = (u16)((coefficientsize<<10)|(codebookinfo<<8)|
1614 			(grouping<<6)|(nr_index<<3)|(nc_index));
1615 
1616 	RTW_INFO("%s: nc=%d nr=%d group=%d codebookinfo=%d coefficientsize=%d\n",
1617 		__func__, nc_index, nr_index, grouping, codebookinfo,
1618 		coefficientsize);
1619 	RTW_INFO("%s: csi=0x%04x\n", __func__, csi_param);
1620 
1621 	rtw_halmac_bf_add_mu_bfer(adapter_to_dvobj(adapter), bfer->p_aid,
1622 			csi_param, bfer->aid & 0xfff, HAL_CSI_SEG_4K,
1623 			bfer->mac_addr);
1624 
1625 	bf_info->cur_csi_rpt_rate = HALMAC_OFDM6;
1626 	rtw_halmac_bf_cfg_sounding(adapter_to_dvobj(adapter), HAL_BFEE,
1627 			bf_info->cur_csi_rpt_rate);
1628 
1629 	/* Set 0x6A0[14] = 1 to accept action_no_ack */
1630 	val8 = rtw_read8(adapter, REG_RXFLTMAP0_8822B+1);
1631 	val8 |= (BIT_MGTFLT14EN_8822B >> 8);
1632 	rtw_write8(adapter, REG_RXFLTMAP0_8822B+1, val8);
1633 
1634 	/* Set 0x6A2[5:4] = 1 to NDPA and BF report poll */
1635 	val8 = rtw_read8(adapter, REG_RXFLTMAP1_8822B);
1636 	val8 |= BIT_CTRLFLT4EN_8822B | BIT_CTRLFLT5EN_8822B;
1637 	rtw_write8(adapter, REG_RXFLTMAP1_8822B, val8);
1638 
1639 	/* for B-Cut */
1640 	if (IS_B_CUT(hal->version_id)) {
1641 		phy_set_bb_reg(adapter, REG_RXFLTMAP0_8822B, BIT(20), 0);
1642 		phy_set_bb_reg(adapter, REG_RXFLTMAP3_8822B, BIT(20), 0);
1643 	}
1644 }
1645 
_config_beamformee_su(PADAPTER adapter,struct beamformee_entry * bfee)1646 static void _config_beamformee_su(PADAPTER adapter, struct beamformee_entry *bfee)
1647 {
1648 	/* General */
1649 	struct mlme_priv *mlme;
1650 	/* Beamforming */
1651 	struct beamforming_info *info;
1652 	u8 idx;
1653 	u16 p_aid = 0;
1654 	/* Misc */
1655 	u8 val8;
1656 	u16 val16;
1657 	u32 val32;
1658 
1659 
1660 	RTW_INFO("%s: Config SU BFee entry HW setting\n", __FUNCTION__);
1661 
1662 	mlme = &adapter->mlmepriv;
1663 	info = GET_BEAMFORM_INFO(adapter);
1664 	idx = bfee->su_reg_index;
1665 
1666 	if ((check_fwstate(mlme, WIFI_ADHOC_STATE) == _TRUE)
1667 	    || (check_fwstate(mlme, WIFI_ADHOC_MASTER_STATE) == _TRUE))
1668 		p_aid = bfee->mac_id;
1669 	else
1670 		p_aid = bfee->p_aid;
1671 
1672 	phydm_8822btxbf_rfmode(GET_PDM_ODM(adapter), info->beamformee_su_cnt, info->beamformee_mu_cnt);
1673 
1674 	/* P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt */
1675 	val32 = rtw_read32(adapter, REG_TXBF_CTRL_8822B);
1676 	if (idx == 0) {
1677 		val32 = BIT_SET_R_TXBF0_AID_8822B(val32, p_aid);
1678 		val32 &= ~(BIT_R_TXBF0_20M_8822B | BIT_R_TXBF0_40M_8822B | BIT_R_TXBF0_80M_8822B);
1679 	} else {
1680 		val32 = BIT_SET_R_TXBF1_AID_8822B(val32, p_aid);
1681 		val32 &= ~(BIT_R_TXBF1_20M_8822B | BIT_R_TXBF1_40M_8822B | BIT_R_TXBF1_80M_8822B);
1682 	}
1683 	val32 |= BIT_R_EN_NDPA_INT_8822B | BIT_USE_NDPA_PARAMETER_8822B | BIT_R_ENABLE_NDPA_8822B;
1684 	rtw_write32(adapter, REG_TXBF_CTRL_8822B, val32);
1685 
1686 	/* CSI report parameters of Beamformee */
1687 	val32 = rtw_read32(adapter, REG_ASSOCIATED_BFMEE_SEL_8822B);
1688 	if (idx == 0) {
1689 		val32 = BIT_SET_AID0_8822B(val32, p_aid);
1690 		val32 |= BIT_TXUSER_ID0_8822B;
1691 
1692 		/* unknown? */
1693 		val32 &= 0x03FFFFFF;
1694 		val32 |= 0x60000000;
1695 	} else {
1696 		val32 = BIT_SET_AID1_8822B(val32, p_aid);
1697 		val32 |= BIT_TXUSER_ID1_8822B;
1698 
1699 		/* unknown? */
1700 		val32 &= 0x03FFFFFF;
1701 		val32 |= 0xE0000000;
1702 	}
1703 	rtw_write32(adapter, REG_ASSOCIATED_BFMEE_SEL_8822B, val32);
1704 }
1705 
_config_beamformee_mu(PADAPTER adapter,struct beamformee_entry * bfee)1706 static void _config_beamformee_mu(PADAPTER adapter, struct beamformee_entry *bfee)
1707 {
1708 	/* General */
1709 	PHAL_DATA_TYPE hal;
1710 	/* Beamforming */
1711 	struct beamforming_info *info;
1712 	u8 idx;
1713 	u32 gid_valid = 0, user_position_l = 0, user_position_h = 0;
1714 	u32 mu_reg[6] = {REG_WMAC_ASSOCIATED_MU_BFMEE2_8822B,
1715 			 REG_WMAC_ASSOCIATED_MU_BFMEE3_8822B,
1716 			 REG_WMAC_ASSOCIATED_MU_BFMEE4_8822B,
1717 			 REG_WMAC_ASSOCIATED_MU_BFMEE5_8822B,
1718 			 REG_WMAC_ASSOCIATED_MU_BFMEE6_8822B,
1719 			 REG_WMAC_ASSOCIATED_MU_BFMEE7_8822B};
1720 	/* Misc */
1721 	u8 i, val8;
1722 	u16 val16;
1723 	u32 val32;
1724 
1725 
1726 	RTW_INFO("%s: Config MU BFee entry HW setting\n", __FUNCTION__);
1727 
1728 	hal = GET_HAL_DATA(adapter);
1729 	info = GET_BEAMFORM_INFO(adapter);
1730 	idx = bfee->mu_reg_index;
1731 
1732 	/* User position table */
1733 	switch (idx) {
1734 	case 0:
1735 		gid_valid = 0x7fe;
1736 		user_position_l = 0x111110;
1737 		user_position_h = 0x0;
1738 		break;
1739 	case 1:
1740 		gid_valid = 0x7f806;
1741 		user_position_l = 0x11000004;
1742 		user_position_h = 0x11;
1743 		break;
1744 	case 2:
1745 		gid_valid = 0x1f81818;
1746 		user_position_l = 0x400040;
1747 		user_position_h = 0x11100;
1748 		break;
1749 	case 3:
1750 		gid_valid = 0x1e186060;
1751 		user_position_l = 0x4000400;
1752 		user_position_h = 0x1100040;
1753 		break;
1754 	case 4:
1755 		gid_valid = 0x66618180;
1756 		user_position_l = 0x40004000;
1757 		user_position_h = 0x10040400;
1758 		break;
1759 	case 5:
1760 		gid_valid = 0x79860600;
1761 		user_position_l = 0x40000;
1762 		user_position_h = 0x4404004;
1763 		break;
1764 	}
1765 
1766 	for (i = 0; i < 8; i++) {
1767 		if (i < 4) {
1768 			bfee->gid_valid[i] = (u8)(gid_valid & 0xFF);
1769 			gid_valid >>= 8;
1770 		} else {
1771 			bfee->gid_valid[i] = 0;
1772 		}
1773 	}
1774 	for (i = 0; i < 16; i++) {
1775 		if (i < 4)
1776 			bfee->user_position[i] = (u8)((user_position_l >> (i*8)) & 0xFF);
1777 		else if (i < 8)
1778 			bfee->user_position[i] = (u8)((user_position_h >> ((i-4)*8)) & 0xFF);
1779 		else
1780 			bfee->user_position[i] = 0;
1781 	}
1782 
1783 	/* Sounding protocol control */
1784 	rtw_write8(adapter, REG_SND_PTCL_CTRL_8822B, 0xDB);
1785 
1786 	/* select MU STA table */
1787 	val32 = rtw_read32(adapter, REG_MU_TX_CTL_8822B);
1788 	val32 = BIT_SET_R_MU_TAB_SEL_8822B(val32, idx);
1789 	rtw_write32(adapter, REG_MU_TX_CTL_8822B, val32);
1790 
1791 	/* Reset gid_valid table */
1792 	rtw_write32(adapter, REG_MU_STA_GID_VLD_8822B, 0);
1793 	rtw_write32(adapter, REG_MU_STA_USER_POS_INFO_8822B , user_position_l);
1794 	rtw_write32(adapter, REG_MU_STA_USER_POS_INFO_8822B+4 , user_position_h);
1795 
1796 	/* set validity of MU STAs */
1797 	val32 = BIT_SET_R_MU_TABLE_VALID_8822B(val32, info->beamformee_mu_reg_maping);
1798 	rtw_write32(adapter, REG_MU_TX_CTL_8822B, val32);
1799 
1800 	RTW_INFO("%s: RegMUTxCtrl=0x%x, user_position_l=0x%x, user_position_h=0x%x\n",
1801 		 __FUNCTION__, val32, user_position_l, user_position_h);
1802 
1803 	val16 = rtw_read16(adapter, mu_reg[idx]);
1804 	val16 &= 0xFE00; /* Clear PAID */
1805 	val16 |= BIT(9); /* Enable MU BFee */
1806 	val16 |= bfee->p_aid;
1807 	rtw_write16(adapter, mu_reg[idx], val16);
1808 	RTW_INFO("%s: Write mu_reg 0x%x = 0x%x\n",
1809 		 __FUNCTION__, mu_reg[idx], val16);
1810 
1811 	/* 0x42C[30] = 1 (0: from Tx desc, 1: from 0x45F) */
1812 	val8 = rtw_read8(adapter, REG_TXBF_CTRL_8822B+3);
1813 	val8 |= 0xD0; /* Set bit 28, 30, 31 to 3b'111 */
1814 	rtw_write8(adapter, REG_TXBF_CTRL_8822B+3, val8);
1815 
1816 	/* Set NDPA rate*/
1817 	val8 = phydm_get_ndpa_rate(GET_PDM_ODM(adapter));
1818 	rtw_write8(adapter, REG_NDPA_RATE_8822B, val8);
1819 
1820 	val8 = rtw_read8(adapter, REG_NDPA_OPT_CTRL_8822B);
1821 	val8 = BIT_SET_R_NDPA_BW_8822B(val8, 0); /* Clear bit 0, 1 */
1822 	rtw_write8(adapter, REG_NDPA_OPT_CTRL_8822B, val8);
1823 
1824 	val32 = rtw_read32(adapter, REG_SND_PTCL_CTRL_8822B);
1825 	val32 = (val32 & 0xFF0000FF) | 0x020200; /* Set [23:8] to 0x0202 */
1826 	rtw_write32(adapter, REG_SND_PTCL_CTRL_8822B, val32);
1827 
1828 	/* Set 0x6A0[14] = 1 to accept action_no_ack */
1829 	val8 = rtw_read8(adapter, REG_RXFLTMAP0_8822B+1);
1830 	val8 |= (BIT_MGTFLT14EN_8822B >> 8);
1831 	rtw_write8(adapter, REG_RXFLTMAP0_8822B+1, val8);
1832 
1833 	/* 0x718[15] = 1. Patch for STA2 CSI report start offset error issue for C-cut and later version */
1834 	if (!IS_A_CUT(hal->version_id) || !IS_B_CUT(hal->version_id)) {
1835 		val8 = rtw_read8(adapter, REG_SND_PTCL_CTRL_8822B+1);
1836 		val8 |= (BIT_VHTNDP_RPTPOLL_CSI_STR_OFFSET_SEL_8822B >> 8);
1837 		rtw_write8(adapter, REG_SND_PTCL_CTRL_8822B+1, val8);
1838 	}
1839 
1840 	/* End of MAC registers setting */
1841 
1842 	phydm_8822btxbf_rfmode(GET_PDM_ODM(adapter), info->beamformee_su_cnt, info->beamformee_mu_cnt);
1843 
1844 	/* <tynli_mark> <TODO> Need to set timer 2015.12.23 */
1845 	/* Special for plugfest */
1846 	rtw_mdelay_os(50); /* wait for 4-way handshake ending */
1847 	rtw_bf_send_vht_gid_mgnt_packet(adapter, bfee->mac_addr, bfee->gid_valid, bfee->user_position);
1848 }
1849 
_reset_beamformer_su(PADAPTER adapter,struct beamformer_entry * bfer)1850 static void _reset_beamformer_su(PADAPTER adapter, struct beamformer_entry *bfer)
1851 {
1852 	/* Beamforming */
1853 	struct beamforming_info *info;
1854 	u8 idx;
1855 
1856 
1857 	info = GET_BEAMFORM_INFO(adapter);
1858 	/* SU BFer */
1859 	idx = bfer->su_reg_index;
1860 
1861 	if (idx == 0) {
1862 		rtw_write32(adapter, REG_ASSOCIATED_BFMER0_INFO_8822B, 0);
1863 		rtw_write16(adapter, REG_ASSOCIATED_BFMER0_INFO_8822B+4, 0);
1864 		rtw_write16(adapter, REG_TX_CSI_RPT_PARAM_BW20_8822B, 0);
1865 	} else {
1866 		rtw_write32(adapter, REG_ASSOCIATED_BFMER1_INFO_8822B, 0);
1867 		rtw_write16(adapter, REG_ASSOCIATED_BFMER1_INFO_8822B+4, 0);
1868 		rtw_write16(adapter, REG_TX_CSI_RPT_PARAM_BW20_8822B+2, 0);
1869 	}
1870 
1871 	info->beamformer_su_reg_maping &= ~BIT(idx);
1872 	bfer->su_reg_index = 0xFF;
1873 
1874 	RTW_INFO("%s: Clear SU BFer entry(%d) HW setting\n", __FUNCTION__, idx);
1875 }
1876 
_reset_beamformer_mu(PADAPTER adapter,struct beamformer_entry * bfer)1877 static void _reset_beamformer_mu(PADAPTER adapter, struct beamformer_entry *bfer)
1878 {
1879 	struct beamforming_info *bf_info;
1880 
1881 	bf_info = GET_BEAMFORM_INFO(adapter);
1882 
1883 	rtw_halmac_bf_del_mu_bfer(adapter_to_dvobj(adapter));
1884 
1885 	if (bf_info->beamformer_su_cnt == 0 &&
1886 			bf_info->beamformer_mu_cnt == 0)
1887 		rtw_halmac_bf_del_sounding(adapter_to_dvobj(adapter), HAL_BFEE);
1888 
1889 	RTW_INFO("%s: Clear MU BFer entry HW setting\n", __FUNCTION__);
1890 }
1891 
_reset_beamformee_su(PADAPTER adapter,struct beamformee_entry * bfee)1892 static void _reset_beamformee_su(PADAPTER adapter, struct beamformee_entry *bfee)
1893 {
1894 	/* Beamforming */
1895 	struct beamforming_info *info;
1896 	u8 idx;
1897 	/* Misc */
1898 	u32 txbf_ctrl, bfmee_sel;
1899 
1900 
1901 	info = GET_BEAMFORM_INFO(adapter);
1902 	/* SU BFee */
1903 	idx = bfee->su_reg_index;
1904 
1905 	/* Force disable sounding config */
1906 	_config_sounding(adapter, bfee, _FALSE, HW_CFG_SOUNDING_TYPE_LEAVE);
1907 
1908 	/* clear P_AID */
1909 	txbf_ctrl = rtw_read32(adapter, REG_TXBF_CTRL_8822B);
1910 	bfmee_sel = rtw_read32(adapter, REG_ASSOCIATED_BFMEE_SEL_8822B);
1911 	if (idx == 0) {
1912 		txbf_ctrl = BIT_SET_R_TXBF0_AID_8822B(txbf_ctrl, 0);
1913 		txbf_ctrl &= ~(BIT_R_TXBF0_20M_8822B | BIT_R_TXBF0_40M_8822B | BIT_R_TXBF0_80M_8822B);
1914 
1915 		bfmee_sel = BIT_SET_AID0_8822B(bfmee_sel, 0);
1916 		bfmee_sel &= ~BIT_TXUSER_ID0_8822B;
1917 	} else {
1918 		txbf_ctrl = BIT_SET_R_TXBF1_AID_8822B(txbf_ctrl, 0);
1919 		txbf_ctrl &= ~(BIT_R_TXBF1_20M_8822B | BIT_R_TXBF1_40M_8822B | BIT_R_TXBF1_80M_8822B);
1920 
1921 		bfmee_sel = BIT_SET_AID1_8822B(bfmee_sel, 0);
1922 		bfmee_sel &= ~BIT_TXUSER_ID1_8822B;
1923 	}
1924 	txbf_ctrl |= BIT_R_EN_NDPA_INT_8822B | BIT_USE_NDPA_PARAMETER_8822B | BIT_R_ENABLE_NDPA_8822B;
1925 	rtw_write32(adapter, REG_TXBF_CTRL_8822B, txbf_ctrl);
1926 	rtw_write32(adapter, REG_ASSOCIATED_BFMEE_SEL_8822B, bfmee_sel);
1927 
1928 	info->beamformee_su_reg_maping &= ~BIT(idx);
1929 	bfee->su_reg_index = 0xFF;
1930 
1931 	RTW_INFO("%s: Clear SU BFee entry(%d) HW setting\n", __FUNCTION__, idx);
1932 }
1933 
_reset_beamformee_mu(PADAPTER adapter,struct beamformee_entry * bfee)1934 static void _reset_beamformee_mu(PADAPTER adapter, struct beamformee_entry *bfee)
1935 {
1936 	/* Beamforming */
1937 	struct beamforming_info *info;
1938 	u8 idx;
1939 	u32 mu_reg[6] = {REG_WMAC_ASSOCIATED_MU_BFMEE2_8822B,
1940 			 REG_WMAC_ASSOCIATED_MU_BFMEE3_8822B,
1941 			 REG_WMAC_ASSOCIATED_MU_BFMEE4_8822B,
1942 			 REG_WMAC_ASSOCIATED_MU_BFMEE5_8822B,
1943 			 REG_WMAC_ASSOCIATED_MU_BFMEE6_8822B,
1944 			 REG_WMAC_ASSOCIATED_MU_BFMEE7_8822B};
1945 	/* Misc */
1946 	u32 val32;
1947 
1948 
1949 	info = GET_BEAMFORM_INFO(adapter);
1950 	/* MU BFee */
1951 	idx = bfee->mu_reg_index;
1952 
1953 	/* Disable sending NDPA & BF-rpt-poll to this BFee */
1954 	rtw_write16(adapter, mu_reg[idx] , 0);
1955 	/* Set validity of MU STA */
1956 	val32 = rtw_read32(adapter, REG_MU_TX_CTL_8822B);
1957 	val32 &= ~BIT(idx);
1958 	rtw_write32(adapter, REG_MU_TX_CTL_8822B, val32);
1959 
1960 	/* Force disable sounding config */
1961 	_config_sounding(adapter, bfee, _TRUE, HW_CFG_SOUNDING_TYPE_LEAVE);
1962 
1963 	info->beamformee_mu_reg_maping &= ~BIT(idx);
1964 	bfee->mu_reg_index = 0xFF;
1965 
1966 	RTW_INFO("%s: Clear MU BFee entry(%d) HW setting\n", __FUNCTION__, idx);
1967 }
1968 
rtl8822b_phy_bf_reset_all(PADAPTER adapter)1969 void rtl8822b_phy_bf_reset_all(PADAPTER adapter)
1970 {
1971 	struct beamforming_info *info;
1972 	u8 i, val8;
1973 	u32 val32;
1974 
1975 
1976 	RTW_INFO("+%s\n", __FUNCTION__);
1977 	info = GET_BEAMFORM_INFO(adapter);
1978 
1979 	info->bSetBFHwConfigInProgess = _TRUE;
1980 
1981 	/* Reset MU BFer entry setting */
1982 	/* Clear validity of MU STA0 and MU STA1 */
1983 	val32 = rtw_read32(adapter, REG_MU_TX_CTL_8822B);
1984 	val32 = BIT_SET_R_MU_TABLE_VALID_8822B(val32, 0);
1985 	rtw_write32(adapter, REG_MU_TX_CTL_8822B, val32);
1986 
1987 	/* Reset SU BFer entry setting */
1988 	rtw_write32(adapter, REG_ASSOCIATED_BFMER0_INFO_8822B, 0);
1989 	rtw_write16(adapter, REG_ASSOCIATED_BFMER0_INFO_8822B+4, 0);
1990 	rtw_write16(adapter, REG_TX_CSI_RPT_PARAM_BW20_8822B, 0);
1991 
1992 	rtw_write32(adapter, REG_ASSOCIATED_BFMER1_INFO_8822B, 0);
1993 	rtw_write16(adapter, REG_ASSOCIATED_BFMER1_INFO_8822B+4, 0);
1994 	rtw_write16(adapter, REG_TX_CSI_RPT_PARAM_BW20_8822B+2, 0);
1995 
1996 	/* Force disable sounding */
1997 	_config_sounding(adapter, NULL, _FALSE, HW_CFG_SOUNDING_TYPE_RESET);
1998 
1999 	/* Config RF mode */
2000 	phydm_8822btxbf_rfmode(GET_PDM_ODM(adapter), info->beamformee_su_cnt, info->beamformee_mu_cnt);
2001 
2002 	/* Reset MU BFee entry setting */
2003 
2004 	/* Disable sending NDPA & BF-rpt-poll to all BFee */
2005 	for (i=0; i < MAX_NUM_BEAMFORMEE_MU; i++)
2006 		rtw_write16(adapter, REG_WMAC_ASSOCIATED_MU_BFMEE2_8822B+(i*2), 0);
2007 
2008 	/* set validity of MU STA */
2009 	rtw_write32(adapter, REG_MU_TX_CTL_8822B, 0);
2010 
2011 	/* Reset SU BFee entry setting */
2012 	/* SU BF0 and BF1 */
2013 	val32 = BIT_R_EN_NDPA_INT_8822B | BIT_USE_NDPA_PARAMETER_8822B | BIT_R_ENABLE_NDPA_8822B;
2014 	rtw_write32(adapter, REG_TXBF_CTRL_8822B, val32);
2015 	rtw_write32(adapter, REG_ASSOCIATED_BFMEE_SEL_8822B, 0);
2016 
2017 	info->bSetBFHwConfigInProgess = _FALSE;
2018 
2019 	/* Clear SU TxBF workaround BB registers */
2020 	if (_TRUE == info->bEnableSUTxBFWorkAround)
2021 		rtl8822b_phy_bf_set_csi_report(adapter, &info->TargetCSIInfo);
2022 
2023 	RTW_INFO("-%s\n", __FUNCTION__);
2024 }
2025 
rtl8822b_phy_bf_init(PADAPTER adapter)2026 void rtl8822b_phy_bf_init(PADAPTER adapter)
2027 {
2028 	u8 v8;
2029 	u32 v32;
2030 
2031 	v32 = rtw_read32(adapter, REG_MU_TX_CTL_8822B);
2032 	/* Enable P1 aggr new packet according to P0 transfer time */
2033 	v32 |= BIT_R_MU_P1_WAIT_STATE_EN_8822B;
2034 	/* MU Retry Limit */
2035 	v32 = BIT_SET_R_MU_RL_8822B(v32, 0xA);
2036 	/* Disable Tx MU-MIMO until sounding done */
2037 	v32 &= ~BIT_R_EN_MU_MIMO_8822B;
2038 	/* Clear validity of MU STAs */
2039 	v32 = BIT_SET_R_MU_TABLE_VALID_8822B(v32, 0);
2040 	rtw_write32(adapter, REG_MU_TX_CTL_8822B, v32);
2041 
2042 	/* MU-MIMO Option as default value */
2043 	v8 = BIT_WMAC_TXMU_ACKPOLICY_8822B(3);
2044 	v8 |= BIT_BIT_WMAC_TXMU_ACKPOLICY_EN_8822B;
2045 	rtw_write8(adapter, REG_WMAC_MU_BF_OPTION_8822B, v8);
2046 	/* MU-MIMO Control as default value */
2047 	rtw_write16(adapter, REG_WMAC_MU_BF_CTL_8822B, 0);
2048 
2049 	/* Set MU NDPA rate & BW source */
2050 	/* 0x42C[30] = 1 (0: from Tx desc, 1: from 0x45F) */
2051 	v8 = rtw_read8(adapter, REG_TXBF_CTRL_8822B+3);
2052 	v8 |= (BIT_USE_NDPA_PARAMETER_8822B >> 24);
2053 	rtw_write8(adapter, REG_TXBF_CTRL_8822B+3, v8);
2054 	/* 0x45F[7:0] = 0x10 (Rate=OFDM_6M, BW20) */
2055 	rtw_write8(adapter, REG_NDPA_OPT_CTRL_8822B, 0x10);
2056 
2057 	/* Temp Settings */
2058 	/* STA2's CSI rate is fixed at 6M */
2059 	v8 = rtw_read8(adapter, 0x6DF);
2060 	v8 = (v8 & 0xC0) | 0x4;
2061 	rtw_write8(adapter, 0x6DF, v8);
2062 	/* Grouping bitmap parameters */
2063 	rtw_write32(adapter, 0x1C94, 0xAFFFAFFF);
2064 }
2065 
rtl8822b_phy_bf_enter(PADAPTER adapter,struct sta_info * sta)2066 void rtl8822b_phy_bf_enter(PADAPTER adapter, struct sta_info *sta)
2067 {
2068 	struct beamforming_info *info;
2069 	struct beamformer_entry *bfer;
2070 	struct beamformee_entry *bfee;
2071 
2072 
2073 	RTW_INFO("+%s: " MAC_FMT "\n", __FUNCTION__, MAC_ARG(sta->cmn.mac_addr));
2074 
2075 	info = GET_BEAMFORM_INFO(adapter);
2076 	bfer = rtw_bf_bfer_get_entry_by_addr(adapter, sta->cmn.mac_addr);
2077 	bfee = rtw_bf_bfee_get_entry_by_addr(adapter, sta->cmn.mac_addr);
2078 
2079 	info->bSetBFHwConfigInProgess = _TRUE;
2080 
2081 	if (bfer) {
2082 		bfer->state = BEAMFORM_ENTRY_HW_STATE_ADDING;
2083 
2084 		if (TEST_FLAG(bfer->cap, BEAMFORMER_CAP_VHT_MU))
2085 			_config_beamformer_mu(adapter, bfer);
2086 		else if (TEST_FLAG(bfer->cap, BEAMFORMER_CAP_VHT_SU|BEAMFORMER_CAP_HT_EXPLICIT))
2087 			_config_beamformer_su(adapter, bfer);
2088 
2089 		bfer->state = BEAMFORM_ENTRY_HW_STATE_ADDED;
2090 	}
2091 
2092 	if (bfee) {
2093 		bfee->state = BEAMFORM_ENTRY_HW_STATE_ADDING;
2094 
2095 		if (TEST_FLAG(bfee->cap, BEAMFORMEE_CAP_VHT_MU))
2096 			_config_beamformee_mu(adapter, bfee);
2097 		else if (TEST_FLAG(bfee->cap, BEAMFORMEE_CAP_VHT_SU|BEAMFORMEE_CAP_HT_EXPLICIT))
2098 			_config_beamformee_su(adapter, bfee);
2099 
2100 		bfee->state = BEAMFORM_ENTRY_HW_STATE_ADDED;
2101 	}
2102 
2103 	info->bSetBFHwConfigInProgess = _FALSE;
2104 
2105 	RTW_INFO("-%s\n", __FUNCTION__);
2106 }
2107 
rtl8822b_phy_bf_leave(PADAPTER adapter,u8 * addr)2108 void rtl8822b_phy_bf_leave(PADAPTER adapter, u8 *addr)
2109 {
2110 	struct beamforming_info *info;
2111 	struct beamformer_entry *bfer;
2112 	struct beamformee_entry *bfee;
2113 
2114 
2115 	RTW_INFO("+%s: " MAC_FMT "\n", __FUNCTION__, MAC_ARG(addr));
2116 
2117 	info = GET_BEAMFORM_INFO(adapter);
2118 
2119 	bfer = rtw_bf_bfer_get_entry_by_addr(adapter, addr);
2120 	bfee = rtw_bf_bfee_get_entry_by_addr(adapter, addr);
2121 
2122 	/* Clear P_AID of Beamformee */
2123 	/* Clear MAC address of Beamformer */
2124 	/* Clear Associated Bfmee Sel */
2125 	if (bfer) {
2126 		bfer->state = BEAMFORM_ENTRY_HW_STATE_DELETING;
2127 
2128 		rtw_write8(adapter, REG_SND_PTCL_CTRL_8822B, 0xD8);
2129 
2130 		if (TEST_FLAG(bfer->cap, BEAMFORMER_CAP_VHT_MU))
2131 			_reset_beamformer_mu(adapter, bfer);
2132 		else if (TEST_FLAG(bfer->cap, BEAMFORMER_CAP_VHT_SU|BEAMFORMER_CAP_HT_EXPLICIT))
2133 			_reset_beamformer_su(adapter, bfer);
2134 
2135 		bfer->state = BEAMFORM_ENTRY_HW_STATE_NONE;
2136 		bfer->cap = BEAMFORMING_CAP_NONE;
2137 		bfer->used = _FALSE;
2138 	}
2139 
2140 	if (bfee) {
2141 		bfee->state = BEAMFORM_ENTRY_HW_STATE_DELETING;
2142 
2143 		phydm_8822btxbf_rfmode(GET_PDM_ODM(adapter), info->beamformee_su_cnt, info->beamformee_mu_cnt);
2144 
2145 		if (TEST_FLAG(bfee->cap, BEAMFORMEE_CAP_VHT_MU))
2146 			_reset_beamformee_mu(adapter, bfee);
2147 		else if (TEST_FLAG(bfee->cap, BEAMFORMEE_CAP_VHT_SU|BEAMFORMEE_CAP_HT_EXPLICIT))
2148 			_reset_beamformee_su(adapter, bfee);
2149 
2150 		bfee->state = BEAMFORM_ENTRY_HW_STATE_NONE;
2151 		bfee->cap = BEAMFORMING_CAP_NONE;
2152 		bfee->used = _FALSE;
2153 	}
2154 
2155 	RTW_INFO("-%s\n", __FUNCTION__);
2156 }
2157 
rtl8822b_phy_bf_set_gid_table(PADAPTER adapter,struct beamformer_entry * bfer_info)2158 void rtl8822b_phy_bf_set_gid_table(PADAPTER adapter,
2159 		struct beamformer_entry	*bfer_info)
2160 {
2161 	struct beamformer_entry *bfer;
2162 	struct beamforming_info *info;
2163 	u32 gid_valid[2] = {0};
2164 	u32 user_position[4] = {0};
2165 	int i;
2166 
2167 	/* update bfer info */
2168 	bfer = rtw_bf_bfer_get_entry_by_addr(adapter, bfer_info->mac_addr);
2169 	if (!bfer) {
2170 		RTW_INFO("%s: Cannot find BFer entry!!\n", __func__);
2171 		return;
2172 	}
2173 	_rtw_memcpy(bfer->gid_valid, bfer_info->gid_valid, 8);
2174 	_rtw_memcpy(bfer->user_position, bfer_info->user_position, 16);
2175 
2176 	info = GET_BEAMFORM_INFO(adapter);
2177 	info->bSetBFHwConfigInProgess = _TRUE;
2178 
2179 	/* For GID 0~31 */
2180 	for (i = 0; i < 4; i++)
2181 		gid_valid[0] |= (bfer->gid_valid[i] << (i << 3));
2182 
2183 	for (i = 0; i < 8; i++) {
2184 		if (i < 4)
2185 			user_position[0] |= (bfer->user_position[i] << (i << 3));
2186 		else
2187 			user_position[1] |= (bfer->user_position[i] << ((i - 4) << 3));
2188 	}
2189 
2190 	RTW_INFO("%s: STA0: gid_valid=0x%x, user_position_l=0x%x, user_position_h=0x%x\n",
2191 		__func__, gid_valid[0], user_position[0], user_position[1]);
2192 
2193 	/* For GID 32~64 */
2194 	for (i = 4; i < 8; i++)
2195 		gid_valid[1] |= (bfer->gid_valid[i] << ((i - 4) << 3));
2196 
2197 	for (i = 8; i < 16; i++) {
2198 		if (i < 12)
2199 			user_position[2] |= (bfer->user_position[i] << ((i - 8) << 3));
2200 		else
2201 			user_position[3] |= (bfer->user_position[i] << ((i - 12) << 3));
2202 	}
2203 
2204 	RTW_INFO("%s: STA1: gid_valid=0x%x, user_position_l=0x%x, user_position_h=0x%x\n",
2205 		__func__, gid_valid[1], user_position[2], user_position[3]);
2206 
2207 	rtw_halmac_bf_cfg_mu_bfee(adapter_to_dvobj(adapter), gid_valid, user_position);
2208 
2209 	info->bSetBFHwConfigInProgess = _FALSE;
2210 }
2211 
rtl8822b_phy_bf_set_csi_report(PADAPTER adapter,struct _RT_CSI_INFO * csi)2212 void rtl8822b_phy_bf_set_csi_report(PADAPTER adapter, struct _RT_CSI_INFO *csi)
2213 {
2214 	PHAL_DATA_TYPE hal;
2215 	struct beamforming_info *info;
2216 	BOOLEAN enable_su = FALSE;
2217 
2218 
2219 	hal = GET_HAL_DATA(adapter);
2220 	info = GET_BEAMFORM_INFO(adapter);
2221 
2222 	info->bSetBFHwConfigInProgess = _TRUE;
2223 
2224 	if (IS_A_CUT(hal->version_id) || IS_B_CUT(hal->version_id) || IS_C_CUT(hal->version_id)) {
2225 		/* If there is an MU BFee added then discard the SU BFee supported capability */
2226 		if ((info->beamformee_su_cnt > 0) && (info->beamformee_mu_cnt == 0))
2227 			enable_su = TRUE;
2228 
2229 		phydm_8822b_sutxbfer_workaroud(
2230 			GET_PDM_ODM(adapter),
2231 			enable_su,
2232 			csi->Nc,
2233 			csi->Nr,
2234 			csi->Ng,
2235 			csi->CodeBook,
2236 			csi->ChnlWidth,
2237 			csi->bVHT);
2238 
2239 		RTW_INFO("%s: bEnable=%d, Nc=%d, Nr=%d, CH_W=%d, Ng=%d, CodeBook=%d\n",
2240 			 __FUNCTION__, bEnable,
2241 			 csi->Nc, csi->Nr, csi->ChnlWidth, csi->Ng, csi->CodeBook);
2242 	}
2243 
2244 	info->bSetBFHwConfigInProgess = _FALSE;
2245 }
2246 
rtl8822b_phy_bf_sounding_status(PADAPTER adapter,u8 status)2247 void rtl8822b_phy_bf_sounding_status(PADAPTER adapter, u8 status)
2248 {
2249 	struct beamforming_info	*info;
2250 	struct sounding_info *sounding;
2251 	struct beamformee_entry *bfee;
2252 	enum _HW_CFG_SOUNDING_TYPE sounding_type;
2253 	u16 val16;
2254 	u32 val32;
2255 	u8 is_sounding_success[6] = {0};
2256 
2257 
2258 	RTW_INFO("+%s\n", __FUNCTION__);
2259 
2260 	info = GET_BEAMFORM_INFO(adapter);
2261 	sounding = &info->sounding_info;
2262 
2263 	info->bSetBFHwConfigInProgess = _TRUE;
2264 
2265 	if (sounding->state == SOUNDING_STATE_SU_SOUNDDOWN) {
2266 		/* SU sounding done */
2267 		RTW_INFO("%s: SUBFeeCurIdx=%d\n", __FUNCTION__, sounding->su_bfee_curidx);
2268 
2269 		bfee = &info->bfee_entry[sounding->su_bfee_curidx];
2270 		if (bfee->bSoundingTimeout) {
2271 			RTW_INFO("%s: Return because SUBFeeCurIdx(%d) is sounding timeout!!!\n", __FUNCTION__, sounding->su_bfee_curidx);
2272 			info->bSetBFHwConfigInProgess = _FALSE;
2273 			return;
2274 		}
2275 
2276 		RTW_INFO("%s: Config SU sound down HW settings\n", __FUNCTION__);
2277 		/* Config SU sounding */
2278 		if (_TRUE == status)
2279 			sounding_type = HW_CFG_SOUNDING_TYPE_SOUNDDOWN;
2280 		else
2281 			sounding_type = HW_CFG_SOUNDING_TYPE_LEAVE;
2282 		_config_sounding(adapter, bfee, _FALSE, sounding_type);
2283 
2284 		/* <tynli_note> Why set here? */
2285 		/* disable NDP packet use beamforming */
2286 		val16 = rtw_read16(adapter, REG_TXBF_CTRL_8822B);
2287 		val16 |= BIT_DIS_NDP_BFEN_8822B;
2288 		rtw_write16(adapter, REG_TXBF_CTRL_8822B, val16);
2289 	} else if (sounding->state == SOUNDING_STATE_MU_SOUNDDOWN) {
2290 		/* MU sounding done */
2291 		RTW_INFO("%s: Config MU sound down HW settings\n", __FUNCTION__);
2292 
2293 		val32 = rtw_read32(adapter, REG_WMAC_ASSOCIATED_MU_BFMEE2_8822B);
2294 		is_sounding_success[0] = (val32 & BIT_STATUS_BFEE2_8822B) ? 1:0;
2295 		is_sounding_success[1] = ((val32 >> 16) & BIT_STATUS_BFEE3_8822B) ? 1:0;
2296 		val32 = rtw_read32(adapter, REG_WMAC_ASSOCIATED_MU_BFMEE4_8822B);
2297 		is_sounding_success[2] = (val32 & BIT_STATUS_BFEE4_8822B) ? 1:0;
2298 		is_sounding_success[3] = ((val32 >> 16) & BIT_STATUS_BFEE5_8822B) ? 1:0;
2299 		val32 = rtw_read32(adapter, REG_WMAC_ASSOCIATED_MU_BFMEE6_8822B);
2300 		is_sounding_success[4] = (val32 & BIT_STATUS_BFEE6_8822B) ? 1:0;
2301 		is_sounding_success[5] = ((val32 >> 16) & BIT_STATUS_BFEE7_8822B) ? 1:0;
2302 
2303 		RTW_INFO("%s: is_sounding_success STA1:%d, STA2:%d, STA3:%d, STA4:%d, STA5:%d, STA6:%d\n",
2304 			 __FUNCTION__, is_sounding_success[0], is_sounding_success[1] , is_sounding_success[2],
2305 			 is_sounding_success[3], is_sounding_success[4], is_sounding_success[5]);
2306 
2307 		/* Config MU sounding */
2308 		_config_sounding(adapter, NULL, _TRUE, HW_CFG_SOUNDING_TYPE_SOUNDDOWN);
2309 	} else {
2310 		RTW_INFO("%s: Invalid sounding state(%d). Do nothing!\n", __FUNCTION__, sounding->state);
2311 	}
2312 
2313 	info->bSetBFHwConfigInProgess = _FALSE;
2314 
2315 	RTW_INFO("-%s\n", __FUNCTION__);
2316 }
2317 #endif /* CONFIG_BEAMFORMING */
2318 
2319 #ifdef CONFIG_LPS_PWR_TRACKING
rtw_lps_pwr_tracking(_adapter * adapter,u8 thermal_value)2320 void rtw_lps_pwr_tracking(_adapter *adapter, u8 thermal_value)
2321 {
2322 	#ifdef CONFIG_LPS
2323 	u8 lps_changed;
2324 
2325 	if (adapter_to_pwrctl(adapter)->bLeisurePs &&
2326 		adapter_to_pwrctl(adapter)->bFwCurrentInPSMode &&
2327 		adapter_to_pwrctl(adapter)->pwr_mode != PS_MODE_ACTIVE) {
2328 		lps_changed = _TRUE;
2329 		LPS_Leave(adapter, "LPS_CTRL_TXSS");
2330 	}
2331 
2332 	rtw_phydm_pwr_tracking_directly(adapter);
2333 
2334 	if (lps_changed)
2335 		LPS_Enter(adapter, "LPS_CTRL_TXSS");
2336 	#endif
2337 
2338 	thermal_value += THERMAL_DIFF_TH;
2339 	rtl8822b_set_fw_thermal_rpt_cmd(adapter, _TRUE, thermal_value);
2340 }
2341 #endif
2342 
2343