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