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