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