From cee4c3d6b8251fff5227329a7ff8de01d1bb568b Mon Sep 17 00:00:00 2001 From: Alex Zhao Date: Tue, 1 Dec 2020 16:04:34 +0800 Subject: [PATCH] net: rockchip_wlan: update rtl8821cs to "v5.12.0-8-g39bbb8dd2.20201015_COEX20200730-5151" Signed-off-by: Alex Zhao Change-Id: I0678acad3e33911177f865a26e34ca6639187004 --- .../wireless/rockchip_wlan/rtl8821cs/Makefile | 119 +- .../rtl8821cs/core/crypto/aes-ccm.c | 422 +- .../rtl8821cs/core/crypto/aes-ctr.c | 140 +- .../rtl8821cs/core/crypto/aes-gcm.c | 652 +- .../rtl8821cs/core/crypto/aes-internal-enc.c | 258 +- .../rtl8821cs/core/crypto/aes-internal.c | 1686 +-- .../rtl8821cs/core/crypto/aes-omac1.c | 344 +- .../rtl8821cs/core/crypto/aes-siv.c | 414 +- .../rockchip_wlan/rtl8821cs/core/crypto/aes.h | 42 +- .../rtl8821cs/core/crypto/aes_i.h | 250 +- .../rtl8821cs/core/crypto/aes_siv.h | 42 +- .../rtl8821cs/core/crypto/aes_wrap.h | 146 +- .../rtl8821cs/core/crypto/ccmp.c | 768 +- .../rtl8821cs/core/crypto/gcmp.c | 386 +- .../rtl8821cs/core/crypto/rtw_crypto_wrap.c | 175 +- .../rtl8821cs/core/crypto/rtw_crypto_wrap.h | 129 +- .../rtl8821cs/core/crypto/sha256-internal.c | 460 +- .../rtl8821cs/core/crypto/sha256-prf.c | 218 +- .../rtl8821cs/core/crypto/sha256.c | 208 +- .../rtl8821cs/core/crypto/sha256.h | 60 +- .../rtl8821cs/core/crypto/sha256_i.h | 50 +- .../rtl8821cs/core/crypto/wlancrypto_wrap.h | 68 +- .../rtl8821cs/core/efuse/rtw_efuse.c | 26 +- .../rtl8821cs/core/mesh/rtw_mesh.c | 26 +- .../rtl8821cs/core/mesh/rtw_mesh.h | 3 +- .../rtl8821cs/core/mesh/rtw_mesh_hwmp.c | 156 - .../rockchip_wlan/rtl8821cs/core/rtw_ap.c | 556 +- .../rtl8821cs/core/rtw_beamforming.c | 129 +- .../rockchip_wlan/rtl8821cs/core/rtw_btcoex.c | 16 + .../rockchip_wlan/rtl8821cs/core/rtw_chplan.c | 3096 +++-- .../rockchip_wlan/rtl8821cs/core/rtw_chplan.h | 165 +- .../rockchip_wlan/rtl8821cs/core/rtw_cmd.c | 434 +- .../rockchip_wlan/rtl8821cs/core/rtw_debug.c | 875 +- .../rockchip_wlan/rtl8821cs/core/rtw_ft.c | 669 + .../rtl8821cs/core/rtw_ieee80211.c | 430 +- .../rtl8821cs/core/rtw_ioctl_set.c | 22 +- .../rockchip_wlan/rtl8821cs/core/rtw_iol.c | 2 +- .../rockchip_wlan/rtl8821cs/core/rtw_mbo.c | 804 ++ .../rockchip_wlan/rtl8821cs/core/rtw_mem.c | 43 + .../rockchip_wlan/rtl8821cs/core/rtw_mi.c | 36 +- .../rockchip_wlan/rtl8821cs/core/rtw_mlme.c | 1160 +- .../rtl8821cs/core/rtw_mlme_ext.c | 2098 ++- .../rockchip_wlan/rtl8821cs/core/rtw_mp.c | 32 +- .../rockchip_wlan/rtl8821cs/core/rtw_odm.c | 33 +- .../rockchip_wlan/rtl8821cs/core/rtw_p2p.c | 412 +- .../rtl8821cs/core/rtw_pwrctrl.c | 172 +- .../rockchip_wlan/rtl8821cs/core/rtw_recv.c | 867 +- .../rockchip_wlan/rtl8821cs/core/rtw_rf.c | 1044 +- .../rockchip_wlan/rtl8821cs/core/rtw_rm.c | 637 +- .../rockchip_wlan/rtl8821cs/core/rtw_rm_fsm.c | 6 +- .../rtl8821cs/core/rtw_rm_util.c | 67 + .../rockchip_wlan/rtl8821cs/core/rtw_roch.c | 592 + .../rockchip_wlan/rtl8821cs/core/rtw_rson.c | 4 + .../rtl8821cs/core/rtw_security.c | 2 +- .../rockchip_wlan/rtl8821cs/core/rtw_sreset.c | 10 +- .../rtl8821cs/core/rtw_sta_mgt.c | 33 +- .../rtl8821cs/core/rtw_swcrypto.c | 592 +- .../rockchip_wlan/rtl8821cs/core/rtw_tdls.c | 15 +- .../rockchip_wlan/rtl8821cs/core/rtw_vht.c | 53 +- .../rtl8821cs/core/rtw_wlan_util.c | 767 +- .../rockchip_wlan/rtl8821cs/core/rtw_wnm.c | 1099 ++ .../rockchip_wlan/rtl8821cs/core/rtw_xmit.c | 701 +- .../rtl8821cs/core/wds/rtw_wds.c | 787 ++ .../rtl8821cs/core/wds/rtw_wds.h | 66 + .../rtl8821cs/hal/btc/halbtc8821c1ant.c | 80 +- .../rtl8821cs/hal/btc/halbtc8821c2ant.c | 11299 ++++++++-------- .../rtl8821cs/hal/btc/halbtc8821c2ant.h | 1032 +- .../rtl8821cs/hal/btc/halbtcoutsrc.h | 98 +- .../rtl8821cs/hal/btc/mp_precomp.h | 9 + .../rtl8821cs/hal/efuse/efuse_mask.h | 7 + .../rockchip_wlan/rtl8821cs/hal/hal_btcoex.c | 241 +- .../rtl8821cs/hal/hal_btcoex_wifionly.c | 15 + .../rockchip_wlan/rtl8821cs/hal/hal_com.c | 2265 +++- .../rockchip_wlan/rtl8821cs/hal/hal_com_c2h.h | 2 + .../rtl8821cs/hal/hal_com_phycfg.c | 1040 +- .../rockchip_wlan/rtl8821cs/hal/hal_dm.c | 140 +- .../rockchip_wlan/rtl8821cs/hal/hal_dm.h | 7 +- .../rockchip_wlan/rtl8821cs/hal/hal_dm_acs.c | 31 +- .../rockchip_wlan/rtl8821cs/hal/hal_dm_acs.h | 6 + .../rockchip_wlan/rtl8821cs/hal/hal_halmac.c | 41 +- .../rockchip_wlan/rtl8821cs/hal/hal_halmac.h | 3 + .../rtl8821cs/hal/hal_hci/hal_sdio.c | 102 +- .../rockchip_wlan/rtl8821cs/hal/hal_intf.c | 71 +- .../rockchip_wlan/rtl8821cs/hal/hal_mcc.c | 177 +- .../rockchip_wlan/rtl8821cs/hal/hal_mp.c | 78 +- .../halmac/halmac_88xx/halmac_efuse_88xx.c | 40 +- .../rtl8821cs/hal/halmac/halmac_api.h | 8 +- .../rtl8821cs/hal/phydm/ap_makefile.mk | 22 +- .../rtl8821cs/hal/phydm/halrf/halphyrf_ap.c | 7 +- .../rtl8821cs/hal/phydm/halrf/halphyrf_ce.c | 19 +- .../rtl8821cs/hal/phydm/halrf/halphyrf_iot.c | 22 +- .../rtl8821cs/hal/phydm/halrf/halphyrf_win.c | 48 +- .../rtl8821cs/hal/phydm/halrf/halrf.c | 426 +- .../rtl8821cs/hal/phydm/halrf/halrf.h | 84 +- .../rtl8821cs/hal/phydm/halrf/halrf_debug.c | 11 +- .../rtl8821cs/hal/phydm/halrf/halrf_debug.h | 17 + .../rtl8821cs/hal/phydm/halrf/halrf_dpk.h | 88 +- .../rtl8821cs/hal/phydm/halrf/halrf_iqk.h | 11 +- .../rtl8821cs/hal/phydm/halrf/halrf_kfree.c | 1119 +- .../rtl8821cs/hal/phydm/halrf/halrf_kfree.h | 69 +- .../hal/phydm/halrf/halrf_powertracking.c | 12 +- .../hal/phydm/halrf/halrf_powertracking_ap.c | 56 +- .../hal/phydm/halrf/halrf_powertracking_ap.h | 1 + .../hal/phydm/halrf/halrf_powertracking_ce.c | 21 +- .../hal/phydm/halrf/halrf_powertracking_ce.h | 1 + .../hal/phydm/halrf/halrf_powertracking_iot.c | 68 +- .../hal/phydm/halrf/halrf_powertracking_iot.h | 35 +- .../hal/phydm/halrf/halrf_powertracking_win.c | 17 + .../hal/phydm/halrf/halrf_powertracking_win.h | 1 + .../phydm/halrf/rtl8821c/halhwimg8821c_rf.c | 8025 ++++++----- .../phydm/halrf/rtl8821c/halhwimg8821c_rf.h | 27 +- .../rockchip_wlan/rtl8821cs/hal/phydm/phydm.c | 279 +- .../rockchip_wlan/rtl8821cs/hal/phydm/phydm.h | 67 +- .../rtl8821cs/hal/phydm/phydm.mk | 16 +- .../rtl8821cs/hal/phydm/phydm_adaptivity.c | 41 +- .../rtl8821cs/hal/phydm/phydm_adaptivity.h | 4 +- .../rtl8821cs/hal/phydm/phydm_adc_sampling.c | 52 +- .../rtl8821cs/hal/phydm/phydm_adc_sampling.h | 4 +- .../rtl8821cs/hal/phydm/phydm_antdiv.c | 481 +- .../rtl8821cs/hal/phydm/phydm_antdiv.h | 23 +- .../rtl8821cs/hal/phydm/phydm_api.c | 509 +- .../rtl8821cs/hal/phydm/phydm_api.h | 16 +- .../rtl8821cs/hal/phydm/phydm_beamforming.c | 7 +- .../rtl8821cs/hal/phydm/phydm_beamforming.h | 2 +- .../rtl8821cs/hal/phydm/phydm_cck_pd.c | 844 +- .../rtl8821cs/hal/phydm/phydm_cck_pd.h | 46 +- .../hal/phydm/phydm_cck_rx_pathdiv.c | 3 +- .../rtl8821cs/hal/phydm/phydm_ccx.c | 1881 ++- .../rtl8821cs/hal/phydm/phydm_ccx.h | 207 +- .../rtl8821cs/hal/phydm/phydm_cfotracking.c | 19 +- .../rtl8821cs/hal/phydm/phydm_debug.c | 373 +- .../rtl8821cs/hal/phydm/phydm_debug.h | 4 +- .../rtl8821cs/hal/phydm/phydm_dfs.c | 21 +- .../rtl8821cs/hal/phydm/phydm_dig.c | 798 +- .../rtl8821cs/hal/phydm/phydm_dig.h | 57 +- .../hal/phydm/phydm_dynamictxpower.c | 148 +- .../hal/phydm/phydm_dynamictxpower.h | 11 +- .../rtl8821cs/hal/phydm/phydm_features.h | 3 + .../rtl8821cs/hal/phydm/phydm_features_ap.h | 34 +- .../rtl8821cs/hal/phydm/phydm_features_ce.h | 20 +- .../rtl8821cs/hal/phydm/phydm_features_iot.h | 10 +- .../rtl8821cs/hal/phydm/phydm_features_win.h | 19 +- .../rtl8821cs/hal/phydm/phydm_hwconfig.c | 59 +- .../rtl8821cs/hal/phydm/phydm_interface.c | 30 +- .../rtl8821cs/hal/phydm/phydm_interface.h | 4 + .../rtl8821cs/hal/phydm/phydm_lna_sat.c | 413 +- .../rtl8821cs/hal/phydm/phydm_lna_sat.h | 25 +- .../rtl8821cs/hal/phydm/phydm_math_lib.c | 31 +- .../rtl8821cs/hal/phydm/phydm_mp.c | 398 +- .../rtl8821cs/hal/phydm/phydm_mp.h | 23 +- .../rtl8821cs/hal/phydm/phydm_noisemonitor.c | 12 +- .../rtl8821cs/hal/phydm/phydm_pathdiv.c | 6 +- .../rtl8821cs/hal/phydm/phydm_phystatus.c | 178 +- .../rtl8821cs/hal/phydm/phydm_phystatus.h | 76 +- .../hal/phydm/phydm_pmac_tx_setting.c | 488 +- .../hal/phydm/phydm_pmac_tx_setting.h | 23 +- .../rtl8821cs/hal/phydm/phydm_pre_define.h | 95 +- .../rtl8821cs/hal/phydm/phydm_precomp.h | 33 +- .../rtl8821cs/hal/phydm/phydm_primary_cca.h | 11 - .../rtl8821cs/hal/phydm/phydm_psd.c | 114 +- .../rtl8821cs/hal/phydm/phydm_rainfo.c | 195 +- .../rtl8821cs/hal/phydm/phydm_rainfo.h | 38 +- .../rtl8821cs/hal/phydm/phydm_regtable.h | 121 + .../rtl8821cs/hal/phydm/phydm_rssi_monitor.c | 22 +- .../rtl8821cs/hal/phydm/phydm_rssi_monitor.h | 3 + .../rtl8821cs/hal/phydm/phydm_soml.c | 26 +- .../rtl8821cs/hal/phydm/phydm_types.h | 81 + .../hal/phydm/rtl8821c/halhwimg8821c_bb.c | 407 +- .../hal/phydm/rtl8821c/halhwimg8821c_bb.h | 2 +- .../hal/phydm/rtl8821c/halhwimg8821c_mac.c | 4 +- .../hal/phydm/rtl8821c/halhwimg8821c_mac.h | 2 +- .../hal/phydm/rtl8821c/phydm_hal_api8821c.c | 8 + .../hal/phydm/rtl8821c/phydm_regconfig8821c.c | 14 + .../hal/phydm/rtl8821c/phydm_regconfig8821c.h | 6 +- .../hal/phydm/rtl8821c/phydm_rtl8821c.c | 58 + .../hal/phydm/rtl8821c/phydm_rtl8821c.h | 32 + .../hal/phydm/rtl8821c/version_rtl8821c.h | 6 +- .../rtl8821cs/hal/phydm/sd4_phydm_2_kernel.mk | 1 - .../hal/phydm/txbf/phydm_hal_txbf_api.c | 43 +- .../hal/phydm/txbf/phydm_hal_txbf_api.h | 3 +- .../rtl8821cs/hal/rtl8821c/rtl8821c.h | 7 +- .../rtl8821cs/hal/rtl8821c/rtl8821c_cmd.c | 86 +- .../rtl8821cs/hal/rtl8821c/rtl8821c_dm.c | 64 +- .../rtl8821cs/hal/rtl8821c/rtl8821c_halinit.c | 5 - .../rtl8821cs/hal/rtl8821c/rtl8821c_ops.c | 116 +- .../hal/rtl8821c/sdio/rtl8821cs_io.c | 1 + .../hal/rtl8821c/sdio/rtl8821cs_ops.c | 3 + .../hal/rtl8821c/sdio/rtl8821cs_recv.c | 65 +- .../hal/rtl8821c/sdio/rtl8821cs_xmit.c | 44 + .../hal/rtl8821c/sdio/rtl8821cs_xmit.h | 3 + .../rockchip_wlan/rtl8821cs/halmac.mk | 43 +- .../rtl8821cs/include/HalVerDef.h | 2 + .../rtl8821cs/include/autoconf.h | 9 +- .../rtl8821cs/include/cmn_info/rtw_sta_info.h | 10 + .../rtl8821cs/include/drv_conf.h | 159 +- .../rtl8821cs/include/drv_types.h | 182 +- .../rtl8821cs/include/hal_btcoex.h | 2 + .../rtl8821cs/include/hal_btcoex_wifionly.h | 5 +- .../rockchip_wlan/rtl8821cs/include/hal_com.h | 125 +- .../rtl8821cs/include/hal_com_h2c.h | 159 +- .../rtl8821cs/include/hal_com_phycfg.h | 63 +- .../rtl8821cs/include/hal_com_reg.h | 12 +- .../rtl8821cs/include/hal_data.h | 8 +- .../rtl8821cs/include/hal_ic_cfg.h | 113 +- .../rtl8821cs/include/hal_intf.h | 28 +- .../rockchip_wlan/rtl8821cs/include/hal_pg.h | 43 + .../rtl8821cs/include/hal_sdio.h | 17 +- .../rtl8821cs/include/ieee80211.h | 172 +- .../rtl8821cs/include/osdep_intf.h | 8 +- .../rtl8821cs/include/osdep_service.h | 62 + .../rtl8821cs/include/osdep_service_linux.h | 14 + .../rtl8821cs/include/pci_osintf.h | 5 +- .../rtl8821cs/include/recv_osdep.h | 5 +- .../rtl8821cs/include/rtl8188e_hal.h | 7 +- .../rtl8821cs/include/rtl8188e_xmit.h | 9 + .../rtl8821cs/include/rtl8188f_cmd.h | 6 - .../rtl8821cs/include/rtl8188f_recv.h | 7 +- .../rtl8821cs/include/rtl8188f_xmit.h | 6 + .../rtl8821cs/include/rtl8192e_cmd.h | 6 - .../rtl8821cs/include/rtl8192e_xmit.h | 9 + .../rtl8821cs/include/rtl8192f_cmd.h | 31 +- .../rtl8821cs/include/rtl8192f_hal.h | 7 +- .../rtl8821cs/include/rtl8192f_led.h | 17 + .../rtl8821cs/include/rtl8192f_rf.h | 9 +- .../rtl8821cs/include/rtl8192f_spec.h | 4 +- .../rtl8821cs/include/rtl8192f_xmit.h | 9 + .../rtl8821cs/include/rtl8703b_cmd.h | 6 - .../rtl8821cs/include/rtl8703b_xmit.h | 9 + .../rtl8821cs/include/rtl8710b_cmd.h | 6 - .../rtl8821cs/include/rtl8710b_xmit.h | 3 + .../rtl8821cs/include/rtl8723b_cmd.h | 6 - .../rtl8821cs/include/rtl8723b_xmit.h | 9 + .../rtl8821cs/include/rtl8723d_cmd.h | 6 - .../rtl8821cs/include/rtl8723d_xmit.h | 9 + .../rtl8821cs/include/rtl8723f_hal.h | 263 + .../rtl8821cs/include/rtl8723fs_hal.h | 32 + .../rtl8821cs/include/rtl8723fu_hal.h | 62 + .../rtl8821cs/include/rtl8812a_cmd.h | 6 - .../rtl8821cs/include/rtl8812a_xmit.h | 6 + .../rtl8821cs/include/rtl8814a_cmd.h | 5 - .../rtl8821cs/include/rtl8814a_xmit.h | 6 + .../rtl8821cs/include/rtl8821a_xmit.h | 3 + .../rockchip_wlan/rtl8821cs/include/rtw_ap.h | 31 +- .../rtl8821cs/include/rtw_btcoex.h | 8 + .../rockchip_wlan/rtl8821cs/include/rtw_cmd.h | 30 +- .../rtl8821cs/include/rtw_debug.h | 44 +- .../rtl8821cs/include/rtw_efuse.h | 14 +- .../rtl8821cs/include/rtw_event.h | 1 + .../rockchip_wlan/rtl8821cs/include/rtw_ft.h | 184 + .../rockchip_wlan/rtl8821cs/include/rtw_mbo.h | 115 + .../rockchip_wlan/rtl8821cs/include/rtw_mcc.h | 4 + .../rockchip_wlan/rtl8821cs/include/rtw_mem.h | 12 - .../rockchip_wlan/rtl8821cs/include/rtw_mi.h | 23 +- .../rtl8821cs/include/rtw_mlme.h | 305 +- .../rtl8821cs/include/rtw_mlme_ext.h | 147 +- .../rockchip_wlan/rtl8821cs/include/rtw_mp.h | 4 + .../rockchip_wlan/rtl8821cs/include/rtw_odm.h | 6 +- .../rockchip_wlan/rtl8821cs/include/rtw_p2p.h | 2 - .../rtl8821cs/include/rtw_pwrctrl.h | 153 +- .../rtl8821cs/include/rtw_recv.h | 44 +- .../rockchip_wlan/rtl8821cs/include/rtw_rf.h | 72 +- .../rockchip_wlan/rtl8821cs/include/rtw_rm.h | 17 + .../rtl8821cs/include/rtw_rm_fsm.h | 20 +- .../rtl8821cs/include/rtw_rm_util.h | 5 + .../rtl8821cs/include/rtw_roch.h | 62 + .../rtl8821cs/include/rtw_security.h | 2 +- .../rtl8821cs/include/rtw_version.h | 4 +- .../rockchip_wlan/rtl8821cs/include/rtw_vht.h | 7 +- .../rockchip_wlan/rtl8821cs/include/rtw_wnm.h | 210 + .../rtl8821cs/include/rtw_xmit.h | 114 +- .../rtl8821cs/include/sdio_ops.h | 3 +- .../rtl8821cs/include/sta_info.h | 19 +- .../rockchip_wlan/rtl8821cs/include/wifi.h | 82 +- .../rtl8821cs/include/xmit_osdep.h | 2 + .../rtl8821cs/os_dep/linux/ioctl_cfg80211.c | 1851 +-- .../rtl8821cs/os_dep/linux/ioctl_cfg80211.h | 39 +- .../rtl8821cs/os_dep/linux/ioctl_linux.c | 449 +- .../rtl8821cs/os_dep/linux/ioctl_mp.c | 346 +- .../rtl8821cs/os_dep/linux/nlrtw.c | 584 + .../rtl8821cs/os_dep/linux/nlrtw.h | 49 + .../rtl8821cs/os_dep/linux/os_intfs.c | 457 +- .../rtl8821cs/os_dep/linux/recv_linux.c | 122 +- .../rtl8821cs/os_dep/linux/rtw_android.c | 5 +- .../rtl8821cs/os_dep/linux/rtw_cfgvendor.c | 65 + .../rtl8821cs/os_dep/linux/rtw_proc.c | 956 +- .../rtl8821cs/os_dep/linux/rtw_proc.h | 6 + .../rtl8821cs/os_dep/linux/rtw_rhashtable.c | 6 +- .../rtl8821cs/os_dep/linux/rtw_rhashtable.h | 12 +- .../rtl8821cs/os_dep/linux/sdio_intf.c | 34 +- .../rtl8821cs/os_dep/linux/wifi_regd.c | 657 +- .../linux/wifi_regd.h} | 23 +- .../rtl8821cs/os_dep/linux/xmit_linux.c | 174 +- .../rtl8821cs/os_dep/osdep_service.c | 353 +- .../platform/custom_country_chplan.h | 2 +- 294 files changed, 47782 insertions(+), 24221 deletions(-) create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ft.c create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mbo.c create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_roch.c create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_wnm.c create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/core/wds/rtw_wds.c create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/core/wds/rtw_wds.h create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_rtl8821c.c create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_rtl8821c.h create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723f_hal.h create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723fs_hal.h create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723fu_hal.h create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_ft.h create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mbo.h create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_roch.h create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_wnm.h create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/nlrtw.c create mode 100644 drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/nlrtw.h rename drivers/net/wireless/rockchip_wlan/rtl8821cs/{include/rtw_wifi_regd.h => os_dep/linux/wifi_regd.h} (71%) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/Makefile b/drivers/net/wireless/rockchip_wlan/rtl8821cs/Makefile index 0f98f42e22dd..797d011e6756 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/Makefile +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/Makefile @@ -45,12 +45,15 @@ CONFIG_RTL8710B = n CONFIG_RTL8192F = n CONFIG_RTL8822C = n CONFIG_RTL8814B = n +CONFIG_RTL8723F = n ######################### Interface ########################### CONFIG_USB_HCI = n CONFIG_PCI_HCI = n CONFIG_SDIO_HCI = y CONFIG_GSPI_HCI = n ########################## Features ########################### +CONFIG_AP_MODE = y +CONFIG_P2P = y CONFIG_MP_INCLUDED = y CONFIG_POWER_SAVING = y CONFIG_IPS_MODE = default @@ -87,10 +90,11 @@ CONFIG_ICMP_VOQ = n CONFIG_IP_R_MONITOR = n #arp VOQ and high rate # user priority mapping rule : tos, dscp CONFIG_RTW_UP_MAPPING_RULE = tos +CONFIG_RTW_MBO = n ########################## Android ########################### -# CONFIG_RTW_ANDROID - 0: no Android, 4/5/6/7/8/9/10 : Android version -CONFIG_RTW_ANDROID = 10 +# CONFIG_RTW_ANDROID - 0: no Android, 4/5/6/7/8/9/10/11 : Android version +CONFIG_RTW_ANDROID = 11 ifeq ($(shell test $(CONFIG_RTW_ANDROID) -gt 0; echo $$?), 0) EXTRA_CFLAGS += -DCONFIG_RTW_ANDROID=$(CONFIG_RTW_ANDROID) @@ -107,8 +111,8 @@ CONFIG_PROC_DEBUG = y ######################## Wake On Lan ########################## CONFIG_WOWLAN = y -#bit2: deauth, bit1: unicast, bit0: magic pkt. -CONFIG_WAKEUP_TYPE = 0x7 +#bit3: ARP enable, bit2: deauth, bit1: unicast, bit0: magic pkt. +CONFIG_WAKEUP_TYPE = 0xf CONFIG_WOW_LPS_MODE = default #bit0: disBBRF off, #bit1: Wireless remote controller (WRC) CONFIG_SUSPEND_TYPE = 0 @@ -128,6 +132,10 @@ CONFIG_AP_WOWLAN = n CONFIG_RTW_SDIO_PM_KEEP_POWER = y ###################### MP HW TX MODE FOR VHT ####################### CONFIG_MP_VHT_HW_TX_MODE = n +###################### ROAMING ##################################### +CONFIG_LAYER2_ROAMING = y +#bit0: ROAM_ON_EXPIRED, #bit1: ROAM_ON_RESUME, #bit2: ROAM_ACTIVE +CONFIG_ROAMING_FLAG = 0x3 ###################### Platform Related ####################### CONFIG_PLATFORM_I386_PC = n CONFIG_PLATFORM_ANDROID_X86 = n @@ -181,6 +189,7 @@ CONFIG_PLATFORM_MOZART = n CONFIG_PLATFORM_RTK119X = n CONFIG_PLATFORM_RTK119X_AM = n CONFIG_PLATFORM_RTK129X = n +CONFIG_PLATFORM_RTK1319 = n CONFIG_PLATFORM_RTK390X = n CONFIG_PLATFORM_NOVATEK_NT72668 = n CONFIG_PLATFORM_HISILICON = n @@ -228,6 +237,7 @@ _OS_INTFS_FILES := os_dep/osdep_service.o \ os_dep/linux/wifi_regd.o \ os_dep/linux/rtw_android.o \ os_dep/linux/rtw_proc.o \ + os_dep/linux/nlrtw.o \ os_dep/linux/rtw_rhashtable.o ifeq ($(CONFIG_MP_INCLUDED), y) @@ -727,6 +737,18 @@ endif endif +########### HAL_RTL8723F ################################# +ifeq ($(CONFIG_RTL8723F), y) +RTL871X := rtl8723f +ifeq ($(CONFIG_USB_HCI), y) +MODULE_NAME = 8723fu +endif +ifeq ($(CONFIG_SDIO_HCI), y) +MODULE_NAME = 8723fs +endif + +endif + ########### HAL_RTL8188F ################################# ifeq ($(CONFIG_RTL8188F), y) @@ -1013,6 +1035,17 @@ endif ########### END OF PATH ################################# +ifeq ($(CONFIG_AP_MODE), y) +EXTRA_CFLAGS += -DCONFIG_AP_MODE +endif + +ifeq ($(CONFIG_P2P), y) +EXTRA_CFLAGS += -DCONFIG_P2P +ifneq ($(CONFIG_AP_MODE), y) +$(error "CONFIG_AP_MODE is required for CONFIG_P2P") +endif +endif + ifeq ($(CONFIG_USB_HCI), y) ifeq ($(CONFIG_USB_AUTOSUSPEND), y) EXTRA_CFLAGS += -DCONFIG_USB_AUTOSUSPEND @@ -1160,11 +1193,18 @@ endif ifeq ($(CONFIG_AP_WOWLAN), y) EXTRA_CFLAGS += -DCONFIG_AP_WOWLAN +ifeq ($(CONFIG_AP_MODE), n) +EXTRA_CFLAGS += -DCONFIG_AP_MODE +endif ifeq ($(CONFIG_SDIO_HCI), y) EXTRA_CFLAGS += -DCONFIG_RTW_SDIO_PM_KEEP_POWER endif endif +ifeq ($(CONFIG_LAYER2_ROAMING), y) +EXTRA_CFLAGS += -DCONFIG_LAYER2_ROAMING -DCONFIG_ROAMING_FLAG=$(CONFIG_ROAMING_FLAG) +endif + ifeq ($(CONFIG_PNO_SUPPORT), y) EXTRA_CFLAGS += -DCONFIG_PNO_SUPPORT ifeq ($(CONFIG_PNO_SET_DEBUG), y) @@ -1286,6 +1326,11 @@ endif EXTRA_CFLAGS += -DDM_ODM_SUPPORT_TYPE=0x04 +ifeq ($(CONFIG_RTW_MBO), y) +EXTRA_CFLAGS += -DCONFIG_RTW_MBO -DCONFIG_RTW_80211K -DCONFIG_RTW_WNM -DCONFIG_RTW_BTM_ROAM +EXTRA_CFLAGS += -DCONFIG_RTW_80211R +endif + ifeq ($(CONFIG_PLATFORM_I386_PC), y) EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT @@ -1660,7 +1705,9 @@ EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE EXTRA_CFLAGS += -DCONFIG_RESUME_IN_WORKQUEUE # default setting for Power control #EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC +ifeq ($(CONFIG_SDIO_HCI), y) EXTRA_CFLAGS += -DRTW_SUPPORT_PLATFORM_SHUTDOWN +endif # default setting for Special function ARCH := arm CROSS_COMPILE := /home/android_sdk/Rockchip/Rk3188/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- @@ -2038,11 +2085,13 @@ MODULE_NAME := 8192eu endif +# Actions-Micro use this flag for DHC 1195 and DHC 1395 ifeq ($(CONFIG_PLATFORM_RTK119X_AM), y) EXTRA_CFLAGS += -DCONFIG_PLATFORM_RTK119X_AM EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -EXTRA_CFLAGS += -DCONFIG_TRAFFIC_PROTECT -EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE -DCONFIG_FULL_CH_IN_P2P_HANDSHAKE +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_FULL_CH_IN_P2P_HANDSHAKE +EXTRA_CFLAGS += -DCONFIG_SEL_P2P_IFACE=2 EXTRA_CFLAGS += -DCONFIG_IFACE_NUMBER=3 EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT @@ -2060,7 +2109,43 @@ endif ifeq ($(CONFIG_PLATFORM_RTK129X), y) EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -EXTRA_CFLAGS += -DRTK_129X_PLATFORM +EXTRA_CFLAGS += -DCONFIG_PLATFORM_RTK129X +EXTRA_CFLAGS += -DCONFIG_TRAFFIC_PROTECT +# default setting for Android 4.1, 4.2 +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +#EXTRA_CFLAGS += -DCONFIG_P2P_IPS -DCONFIG_QOS_OPTIMIZATION +EXTRA_CFLAGS += -DCONFIG_QOS_OPTIMIZATION +# Enable this for Android 5.0 +EXTRA_CFLAGS += -DCONFIG_RADIO_WORK +ifeq ($(CONFIG_RTL8821C)$(CONFIG_SDIO_HCI),yy) +EXTRA_CFLAGS += -DCONFIG_WAKEUP_GPIO_INPUT_MODE +EXTRA_CFLAGS += -DCONFIG_BT_WAKE_HST_OPEN_DRAIN +endif +EXTRA_CFLAGS += -Wno-error=date-time +# default setting for Android 7.0 +ifeq ($(RTK_ANDROID_VERSION), nougat) +EXTRA_CFLAGS += -DRTW_P2P_GROUP_INTERFACE=1 +endif +#EXTRA_CFLAGS += -DCONFIG_#PLATFORM_OPS +ifeq ($(CONFIG_USB_HCI), y) +EXTRA_CFLAGS += -DCONFIG_USE_USB_BUFFER_ALLOC_TX +endif + +ARCH := arm64 + +# ==== Cross compile setting for Android 4.4 SDK ===== +#CROSS_COMPILE := arm-linux-gnueabihf- +#KVER := 4.1.10 +#CROSS_COMPILE := $(CROSS) +#KSRC := $(LINUX_KERNEL_PATH) +CROSS_COMPILE := /home/android_sdk/DHC/trunk-6.0.0_r1-QA160627/phoenix/toolchain/asdk64-4.9.4-a53-EL-3.10-g2.19-a64nt-160307/bin/asdk64-linux- +KSRC := /home/android_sdk/DHC/trunk-6.0.0_r1-QA160627/linux-kernel +endif + +ifeq ($(CONFIG_PLATFORM_RTK1319), y) +EXTRA_CFLAGS += -DCONFIG_PLATFORM_RTK1319 +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN EXTRA_CFLAGS += -DCONFIG_TRAFFIC_PROTECT # default setting for Android 4.1, 4.2 EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE @@ -2214,6 +2299,14 @@ ifeq ($(CONFIG_CUSTOMER_HUAWEI), y) EXTRA_CFLAGS += -DCONFIG_HUAWEI_PROC endif +CONFIG_PLATFORM_CMAP_INTFS = n +ifeq ($(CONFIG_PLATFORM_CMAP_INTFS), y) +PLATFORM_CMAP_INTFS_TYPE = 00 +EXTRA_CFLAGS += -DCONFIG_PLATFORM_CMAP_INTFS -DCMAP_UNASSOC_METRICS_STA_MAX=32 +_OS_INTFS_FILES += os_dep/linux/custom_multiap_intfs/custom_multiap_intfs.o +_PLATFORM_FILES += platform/custom_multiap_intfs_$(PLATFORM_CMAP_INTFS_TYPE).o +endif + ifeq ($(CONFIG_MULTIDRV), y) ifeq ($(CONFIG_SDIO_HCI), y) @@ -2261,6 +2354,11 @@ ifeq ($(CONFIG_RTL8814B), y) include $(src)/rtl8814b.mk endif +########### HAL_RTL8723F ################################# +ifeq ($(CONFIG_RTL8723F), y) +include $(src)/rtl8723f.mk +endif + rtk_core := core/rtw_cmd.o \ core/rtw_security.o \ core/rtw_debug.o \ @@ -2280,6 +2378,7 @@ rtk_core := core/rtw_cmd.o \ core/rtw_recv.o \ core/rtw_sta_mgt.o \ core/rtw_ap.o \ + core/wds/rtw_wds.o \ core/mesh/rtw_mesh.o \ core/mesh/rtw_mesh_pathtbl.o \ core/mesh/rtw_mesh_hwmp.o \ @@ -2296,8 +2395,12 @@ rtk_core := core/rtw_cmd.o \ core/rtw_odm.o \ core/rtw_rm.o \ core/rtw_rm_fsm.o \ + core/rtw_ft.o \ + core/rtw_wnm.o \ + core/rtw_mbo.o \ core/rtw_rm_util.o \ - core/efuse/rtw_efuse.o + core/efuse/rtw_efuse.o \ + core/rtw_roch.o ifeq ($(CONFIG_SDIO_HCI), y) rtk_core += core/rtw_sdio.o diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-ccm.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-ccm.c index e68d84e86824..b6c40d944db7 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-ccm.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-ccm.c @@ -1,212 +1,212 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * Counter with CBC-MAC (CCM) with AES - * - * Copyright (c) 2010-2012, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#include "rtw_crypto_wrap.h" - -#include "aes.h" -#include "aes_wrap.h" - - -static void xor_aes_block(u8 *dst, const u8 *src) -{ - u32 *d = (u32 *) dst; - u32 *s = (u32 *) src; - *d++ ^= *s++; - *d++ ^= *s++; - *d++ ^= *s++; - *d++ ^= *s++; -} - - -static void aes_ccm_auth_start(void *aes, size_t M, size_t L, const u8 *nonce, - const u8 *aad, size_t aad_len, size_t plain_len, - u8 *x) -{ - u8 aad_buf[2 * AES_BLOCK_SIZE]; - u8 b[AES_BLOCK_SIZE]; - - /* Authentication */ - /* B_0: Flags | Nonce N | l(m) */ - b[0] = aad_len ? 0x40 : 0 /* Adata */; - b[0] |= (((M - 2) / 2) /* M' */ << 3); - b[0] |= (L - 1) /* L' */; - os_memcpy(&b[1], nonce, 15 - L); - WPA_PUT_BE16(&b[AES_BLOCK_SIZE - L], plain_len); - - wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM B_0", b, AES_BLOCK_SIZE); - aes_encrypt(aes, b, x); /* X_1 = E(K, B_0) */ - - if (!aad_len) - return; - - WPA_PUT_BE16(aad_buf, aad_len); - os_memcpy(aad_buf + 2, aad, aad_len); - os_memset(aad_buf + 2 + aad_len, 0, sizeof(aad_buf) - 2 - aad_len); - - xor_aes_block(aad_buf, x); - aes_encrypt(aes, aad_buf, x); /* X_2 = E(K, X_1 XOR B_1) */ - - if (aad_len > AES_BLOCK_SIZE - 2) { - xor_aes_block(&aad_buf[AES_BLOCK_SIZE], x); - /* X_3 = E(K, X_2 XOR B_2) */ - aes_encrypt(aes, &aad_buf[AES_BLOCK_SIZE], x); - } -} - - -static void aes_ccm_auth(void *aes, const u8 *data, size_t len, u8 *x) -{ - size_t last = len % AES_BLOCK_SIZE; - size_t i; - - for (i = 0; i < len / AES_BLOCK_SIZE; i++) { - /* X_i+1 = E(K, X_i XOR B_i) */ - xor_aes_block(x, data); - data += AES_BLOCK_SIZE; - aes_encrypt(aes, x, x); - } - if (last) { - /* XOR zero-padded last block */ - for (i = 0; i < last; i++) - x[i] ^= *data++; - aes_encrypt(aes, x, x); - } -} - - -static void aes_ccm_encr_start(size_t L, const u8 *nonce, u8 *a) -{ - /* A_i = Flags | Nonce N | Counter i */ - a[0] = L - 1; /* Flags = L' */ - os_memcpy(&a[1], nonce, 15 - L); -} - - -static void aes_ccm_encr(void *aes, size_t L, const u8 *in, size_t len, u8 *out, - u8 *a) -{ - size_t last = len % AES_BLOCK_SIZE; - size_t i; - - /* crypt = msg XOR (S_1 | S_2 | ... | S_n) */ - for (i = 1; i <= len / AES_BLOCK_SIZE; i++) { - WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], i); - /* S_i = E(K, A_i) */ - aes_encrypt(aes, a, out); - xor_aes_block(out, in); - out += AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - } - if (last) { - WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], i); - aes_encrypt(aes, a, out); - /* XOR zero-padded last block */ - for (i = 0; i < last; i++) - *out++ ^= *in++; - } -} - - -static void aes_ccm_encr_auth(void *aes, size_t M, u8 *x, u8 *a, u8 *auth) -{ - size_t i; - u8 tmp[AES_BLOCK_SIZE]; - - wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM T", x, M); - /* U = T XOR S_0; S_0 = E(K, A_0) */ - WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], 0); - aes_encrypt(aes, a, tmp); - for (i = 0; i < M; i++) - auth[i] = x[i] ^ tmp[i]; - wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM U", auth, M); -} - - -static void aes_ccm_decr_auth(void *aes, size_t M, u8 *a, const u8 *auth, u8 *t) -{ - size_t i; - u8 tmp[AES_BLOCK_SIZE]; - - wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM U", auth, M); - /* U = T XOR S_0; S_0 = E(K, A_0) */ - WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], 0); - aes_encrypt(aes, a, tmp); - for (i = 0; i < M; i++) - t[i] = auth[i] ^ tmp[i]; - wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM T", t, M); -} - - -/* AES-CCM with fixed L=2 and aad_len <= 30 assumption */ -int aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce, - size_t M, const u8 *plain, size_t plain_len, - const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth) -{ - const size_t L = 2; - void *aes; - u8 x[AES_BLOCK_SIZE], a[AES_BLOCK_SIZE]; - - if (aad_len > 30 || M > AES_BLOCK_SIZE) - return -1; - - aes = aes_encrypt_init(key, key_len); - if (aes == NULL) - return -1; - - aes_ccm_auth_start(aes, M, L, nonce, aad, aad_len, plain_len, x); - aes_ccm_auth(aes, plain, plain_len, x); - - /* Encryption */ - aes_ccm_encr_start(L, nonce, a); - aes_ccm_encr(aes, L, plain, plain_len, crypt, a); - aes_ccm_encr_auth(aes, M, x, a, auth); - - aes_encrypt_deinit(aes); - - return 0; -} - - -/* AES-CCM with fixed L=2 and aad_len <= 30 assumption */ -int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, - size_t M, const u8 *crypt, size_t crypt_len, - const u8 *aad, size_t aad_len, const u8 *auth, u8 *plain) -{ - const size_t L = 2; - void *aes; - u8 x[AES_BLOCK_SIZE], a[AES_BLOCK_SIZE]; - u8 t[AES_BLOCK_SIZE]; - - if (aad_len > 30 || M > AES_BLOCK_SIZE) - return -1; - - aes = aes_encrypt_init(key, key_len); - if (aes == NULL) - return -1; - - /* Decryption */ - aes_ccm_encr_start(L, nonce, a); - aes_ccm_decr_auth(aes, M, a, auth, t); - - /* plaintext = msg XOR (S_1 | S_2 | ... | S_n) */ - aes_ccm_encr(aes, L, crypt, crypt_len, plain, a); - - aes_ccm_auth_start(aes, M, L, nonce, aad, aad_len, crypt_len, x); - aes_ccm_auth(aes, plain, crypt_len, x); - - aes_encrypt_deinit(aes); - - if (os_memcmp_const(x, t, M) != 0) { - wpa_printf(_MSG_EXCESSIVE_, "CCM: Auth mismatch"); - return -1; - } - - return 0; -} +/* + * Counter with CBC-MAC (CCM) with AES + * + * Copyright (c) 2010-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes.h" +#include "aes_wrap.h" + + +static void xor_aes_block(u8 *dst, const u8 *src) +{ + u32 *d = (u32 *) dst; + u32 *s = (u32 *) src; + *d++ ^= *s++; + *d++ ^= *s++; + *d++ ^= *s++; + *d++ ^= *s++; +} + + +static void aes_ccm_auth_start(void *aes, size_t M, size_t L, const u8 *nonce, + const u8 *aad, size_t aad_len, size_t plain_len, + u8 *x) +{ + u8 aad_buf[2 * AES_BLOCK_SIZE]; + u8 b[AES_BLOCK_SIZE]; + + /* Authentication */ + /* B_0: Flags | Nonce N | l(m) */ + b[0] = aad_len ? 0x40 : 0 /* Adata */; + b[0] |= (((M - 2) / 2) /* M' */ << 3); + b[0] |= (L - 1) /* L' */; + os_memcpy(&b[1], nonce, 15 - L); + WPA_PUT_BE16(&b[AES_BLOCK_SIZE - L], plain_len); + + wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM B_0", b, AES_BLOCK_SIZE); + aes_encrypt(aes, b, x); /* X_1 = E(K, B_0) */ + + if (!aad_len) + return; + + WPA_PUT_BE16(aad_buf, aad_len); + os_memcpy(aad_buf + 2, aad, aad_len); + os_memset(aad_buf + 2 + aad_len, 0, sizeof(aad_buf) - 2 - aad_len); + + xor_aes_block(aad_buf, x); + aes_encrypt(aes, aad_buf, x); /* X_2 = E(K, X_1 XOR B_1) */ + + if (aad_len > AES_BLOCK_SIZE - 2) { + xor_aes_block(&aad_buf[AES_BLOCK_SIZE], x); + /* X_3 = E(K, X_2 XOR B_2) */ + aes_encrypt(aes, &aad_buf[AES_BLOCK_SIZE], x); + } +} + + +static void aes_ccm_auth(void *aes, const u8 *data, size_t len, u8 *x) +{ + size_t last = len % AES_BLOCK_SIZE; + size_t i; + + for (i = 0; i < len / AES_BLOCK_SIZE; i++) { + /* X_i+1 = E(K, X_i XOR B_i) */ + xor_aes_block(x, data); + data += AES_BLOCK_SIZE; + aes_encrypt(aes, x, x); + } + if (last) { + /* XOR zero-padded last block */ + for (i = 0; i < last; i++) + x[i] ^= *data++; + aes_encrypt(aes, x, x); + } +} + + +static void aes_ccm_encr_start(size_t L, const u8 *nonce, u8 *a) +{ + /* A_i = Flags | Nonce N | Counter i */ + a[0] = L - 1; /* Flags = L' */ + os_memcpy(&a[1], nonce, 15 - L); +} + + +static void aes_ccm_encr(void *aes, size_t L, const u8 *in, size_t len, u8 *out, + u8 *a) +{ + size_t last = len % AES_BLOCK_SIZE; + size_t i; + + /* crypt = msg XOR (S_1 | S_2 | ... | S_n) */ + for (i = 1; i <= len / AES_BLOCK_SIZE; i++) { + WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], i); + /* S_i = E(K, A_i) */ + aes_encrypt(aes, a, out); + xor_aes_block(out, in); + out += AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + } + if (last) { + WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], i); + aes_encrypt(aes, a, out); + /* XOR zero-padded last block */ + for (i = 0; i < last; i++) + *out++ ^= *in++; + } +} + + +static void aes_ccm_encr_auth(void *aes, size_t M, u8 *x, u8 *a, u8 *auth) +{ + size_t i; + u8 tmp[AES_BLOCK_SIZE]; + + wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM T", x, M); + /* U = T XOR S_0; S_0 = E(K, A_0) */ + WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], 0); + aes_encrypt(aes, a, tmp); + for (i = 0; i < M; i++) + auth[i] = x[i] ^ tmp[i]; + wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM U", auth, M); +} + + +static void aes_ccm_decr_auth(void *aes, size_t M, u8 *a, const u8 *auth, u8 *t) +{ + size_t i; + u8 tmp[AES_BLOCK_SIZE]; + + wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM U", auth, M); + /* U = T XOR S_0; S_0 = E(K, A_0) */ + WPA_PUT_BE16(&a[AES_BLOCK_SIZE - 2], 0); + aes_encrypt(aes, a, tmp); + for (i = 0; i < M; i++) + t[i] = auth[i] ^ tmp[i]; + wpa_hexdump_key(_MSG_EXCESSIVE_, "CCM T", t, M); +} + + +/* AES-CCM with fixed L=2 and aad_len <= 30 assumption */ +int aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce, + size_t M, const u8 *plain, size_t plain_len, + const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth) +{ + const size_t L = 2; + void *aes; + u8 x[AES_BLOCK_SIZE], a[AES_BLOCK_SIZE]; + + if (aad_len > 30 || M > AES_BLOCK_SIZE) + return -1; + + aes = aes_encrypt_init(key, key_len); + if (aes == NULL) + return -1; + + aes_ccm_auth_start(aes, M, L, nonce, aad, aad_len, plain_len, x); + aes_ccm_auth(aes, plain, plain_len, x); + + /* Encryption */ + aes_ccm_encr_start(L, nonce, a); + aes_ccm_encr(aes, L, plain, plain_len, crypt, a); + aes_ccm_encr_auth(aes, M, x, a, auth); + + aes_encrypt_deinit(aes); + + return 0; +} + + +/* AES-CCM with fixed L=2 and aad_len <= 30 assumption */ +int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, + size_t M, const u8 *crypt, size_t crypt_len, + const u8 *aad, size_t aad_len, const u8 *auth, u8 *plain) +{ + const size_t L = 2; + void *aes; + u8 x[AES_BLOCK_SIZE], a[AES_BLOCK_SIZE]; + u8 t[AES_BLOCK_SIZE]; + + if (aad_len > 30 || M > AES_BLOCK_SIZE) + return -1; + + aes = aes_encrypt_init(key, key_len); + if (aes == NULL) + return -1; + + /* Decryption */ + aes_ccm_encr_start(L, nonce, a); + aes_ccm_decr_auth(aes, M, a, auth, t); + + /* plaintext = msg XOR (S_1 | S_2 | ... | S_n) */ + aes_ccm_encr(aes, L, crypt, crypt_len, plain, a); + + aes_ccm_auth_start(aes, M, L, nonce, aad, aad_len, crypt_len, x); + aes_ccm_auth(aes, plain, crypt_len, x); + + aes_encrypt_deinit(aes); + + if (os_memcmp_const(x, t, M) != 0) { + wpa_printf(_MSG_EXCESSIVE_, "CCM: Auth mismatch"); + return -1; + } + + return 0; +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-ctr.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-ctr.c index 72cb56a4b9b3..01d99c62e09f 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-ctr.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-ctr.c @@ -1,71 +1,71 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * AES-128/192/256 CTR - * - * Copyright (c) 2003-2007, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#include "rtw_crypto_wrap.h" - -#include "aes.h" -#include "aes_wrap.h" - -/** - * aes_ctr_encrypt - AES-128/192/256 CTR mode encryption - * @key: Key for encryption (key_len bytes) - * @key_len: Length of the key (16, 24, or 32 bytes) - * @nonce: Nonce for counter mode (16 bytes) - * @data: Data to encrypt in-place - * @data_len: Length of data in bytes - * Returns: 0 on success, -1 on failure - */ -int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, - u8 *data, size_t data_len) -{ - void *ctx; - size_t j, len, left = data_len; - int i; - u8 *pos = data; - u8 counter[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE]; - - ctx = aes_encrypt_init(key, key_len); - if (ctx == NULL) - return -1; - os_memcpy(counter, nonce, AES_BLOCK_SIZE); - - while (left > 0) { - aes_encrypt(ctx, counter, buf); - - len = (left < AES_BLOCK_SIZE) ? left : AES_BLOCK_SIZE; - for (j = 0; j < len; j++) - pos[j] ^= buf[j]; - pos += len; - left -= len; - - for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { - counter[i]++; - if (counter[i]) - break; - } - } - aes_encrypt_deinit(ctx); - return 0; -} - - -/** - * aes_128_ctr_encrypt - AES-128 CTR mode encryption - * @key: Key for encryption (key_len bytes) - * @nonce: Nonce for counter mode (16 bytes) - * @data: Data to encrypt in-place - * @data_len: Length of data in bytes - * Returns: 0 on success, -1 on failure - */ -int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, - u8 *data, size_t data_len) -{ - return aes_ctr_encrypt(key, 16, nonce, data, data_len); -} +/* + * AES-128/192/256 CTR + * + * Copyright (c) 2003-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes.h" +#include "aes_wrap.h" + +/** + * aes_ctr_encrypt - AES-128/192/256 CTR mode encryption + * @key: Key for encryption (key_len bytes) + * @key_len: Length of the key (16, 24, or 32 bytes) + * @nonce: Nonce for counter mode (16 bytes) + * @data: Data to encrypt in-place + * @data_len: Length of data in bytes + * Returns: 0 on success, -1 on failure + */ +int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, + u8 *data, size_t data_len) +{ + void *ctx; + size_t j, len, left = data_len; + int i; + u8 *pos = data; + u8 counter[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE]; + + ctx = aes_encrypt_init(key, key_len); + if (ctx == NULL) + return -1; + os_memcpy(counter, nonce, AES_BLOCK_SIZE); + + while (left > 0) { + aes_encrypt(ctx, counter, buf); + + len = (left < AES_BLOCK_SIZE) ? left : AES_BLOCK_SIZE; + for (j = 0; j < len; j++) + pos[j] ^= buf[j]; + pos += len; + left -= len; + + for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { + counter[i]++; + if (counter[i]) + break; + } + } + aes_encrypt_deinit(ctx); + return 0; +} + + +/** + * aes_128_ctr_encrypt - AES-128 CTR mode encryption + * @key: Key for encryption (key_len bytes) + * @nonce: Nonce for counter mode (16 bytes) + * @data: Data to encrypt in-place + * @data_len: Length of data in bytes + * Returns: 0 on success, -1 on failure + */ +int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, + u8 *data, size_t data_len) +{ + return aes_ctr_encrypt(key, 16, nonce, data, data_len); +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-gcm.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-gcm.c index a879a234dcc8..e5fe797c92ac 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-gcm.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-gcm.c @@ -1,327 +1,327 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * Galois/Counter Mode (GCM) and GMAC with AES - * - * Copyright (c) 2012, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#include "rtw_crypto_wrap.h" - -#include "aes.h" -#include "aes_wrap.h" - -static void inc32(u8 *block) -{ - u32 val; - val = WPA_GET_BE32(block + AES_BLOCK_SIZE - 4); - val++; - WPA_PUT_BE32(block + AES_BLOCK_SIZE - 4, val); -} - - -static void xor_block(u8 *dst, const u8 *src) -{ - u32 *d = (u32 *) dst; - u32 *s = (u32 *) src; - *d++ ^= *s++; - *d++ ^= *s++; - *d++ ^= *s++; - *d++ ^= *s++; -} - - -static void shift_right_block(u8 *v) -{ - u32 val; - - val = WPA_GET_BE32(v + 12); - val >>= 1; - if (v[11] & 0x01) - val |= 0x80000000; - WPA_PUT_BE32(v + 12, val); - - val = WPA_GET_BE32(v + 8); - val >>= 1; - if (v[7] & 0x01) - val |= 0x80000000; - WPA_PUT_BE32(v + 8, val); - - val = WPA_GET_BE32(v + 4); - val >>= 1; - if (v[3] & 0x01) - val |= 0x80000000; - WPA_PUT_BE32(v + 4, val); - - val = WPA_GET_BE32(v); - val >>= 1; - WPA_PUT_BE32(v, val); -} - - -/* Multiplication in GF(2^128) */ -static void gf_mult(const u8 *x, const u8 *y, u8 *z) -{ - u8 v[16]; - int i, j; - - os_memset(z, 0, 16); /* Z_0 = 0^128 */ - os_memcpy(v, y, 16); /* V_0 = Y */ - - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) { - if (x[i] & BIT(7 - j)) { - /* Z_(i + 1) = Z_i XOR V_i */ - xor_block(z, v); - } else { - /* Z_(i + 1) = Z_i */ - } - - if (v[15] & 0x01) { - /* V_(i + 1) = (V_i >> 1) XOR R */ - shift_right_block(v); - /* R = 11100001 || 0^120 */ - v[0] ^= 0xe1; - } else { - /* V_(i + 1) = V_i >> 1 */ - shift_right_block(v); - } - } - } -} - - -static void ghash_start(u8 *y) -{ - /* Y_0 = 0^128 */ - os_memset(y, 0, 16); -} - - -static void ghash(const u8 *h, const u8 *x, size_t xlen, u8 *y) -{ - size_t m, i; - const u8 *xpos = x; - u8 tmp[16]; - - m = xlen / 16; - - for (i = 0; i < m; i++) { - /* Y_i = (Y^(i-1) XOR X_i) dot H */ - xor_block(y, xpos); - xpos += 16; - - /* dot operation: - * multiplication operation for binary Galois (finite) field of - * 2^128 elements */ - gf_mult(y, h, tmp); - os_memcpy(y, tmp, 16); - } - - if (x + xlen > xpos) { - /* Add zero padded last block */ - size_t last = x + xlen - xpos; - os_memcpy(tmp, xpos, last); - os_memset(tmp + last, 0, sizeof(tmp) - last); - - /* Y_i = (Y^(i-1) XOR X_i) dot H */ - xor_block(y, tmp); - - /* dot operation: - * multiplication operation for binary Galois (finite) field of - * 2^128 elements */ - gf_mult(y, h, tmp); - os_memcpy(y, tmp, 16); - } - - /* Return Y_m */ -} - - -static void aes_gctr(void *aes, const u8 *icb, const u8 *x, size_t xlen, u8 *y) -{ - size_t i, n, last; - u8 cb[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE]; - const u8 *xpos = x; - u8 *ypos = y; - - if (xlen == 0) - return; - - n = xlen / 16; - - os_memcpy(cb, icb, AES_BLOCK_SIZE); - /* Full blocks */ - for (i = 0; i < n; i++) { - aes_encrypt(aes, cb, ypos); - xor_block(ypos, xpos); - xpos += AES_BLOCK_SIZE; - ypos += AES_BLOCK_SIZE; - inc32(cb); - } - - last = x + xlen - xpos; - if (last) { - /* Last, partial block */ - aes_encrypt(aes, cb, tmp); - for (i = 0; i < last; i++) - *ypos++ = *xpos++ ^ tmp[i]; - } -} - - -static void * aes_gcm_init_hash_subkey(const u8 *key, size_t key_len, u8 *H) -{ - void *aes; - - aes = aes_encrypt_init(key, key_len); - if (aes == NULL) - return NULL; - - /* Generate hash subkey H = AES_K(0^128) */ - os_memset(H, 0, AES_BLOCK_SIZE); - aes_encrypt(aes, H, H); - wpa_hexdump_key(_MSG_EXCESSIVE_, "Hash subkey H for GHASH", - H, AES_BLOCK_SIZE); - return aes; -} - - -static void aes_gcm_prepare_j0(const u8 *iv, size_t iv_len, const u8 *H, u8 *J0) -{ - u8 len_buf[16]; - - if (iv_len == 12) { - /* Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */ - os_memcpy(J0, iv, iv_len); - os_memset(J0 + iv_len, 0, AES_BLOCK_SIZE - iv_len); - J0[AES_BLOCK_SIZE - 1] = 0x01; - } else { - /* - * s = 128 * ceil(len(IV)/128) - len(IV) - * J_0 = GHASH_H(IV || 0^(s+64) || [len(IV)]_64) - */ - ghash_start(J0); - ghash(H, iv, iv_len, J0); - WPA_PUT_BE64(len_buf, 0); - WPA_PUT_BE64(len_buf + 8, iv_len * 8); - ghash(H, len_buf, sizeof(len_buf), J0); - } -} - - -static void aes_gcm_gctr(void *aes, const u8 *J0, const u8 *in, size_t len, - u8 *out) -{ - u8 J0inc[AES_BLOCK_SIZE]; - - if (len == 0) - return; - - os_memcpy(J0inc, J0, AES_BLOCK_SIZE); - inc32(J0inc); - aes_gctr(aes, J0inc, in, len, out); -} - - -static void aes_gcm_ghash(const u8 *H, const u8 *aad, size_t aad_len, - const u8 *crypt, size_t crypt_len, u8 *S) -{ - u8 len_buf[16]; - - /* - * u = 128 * ceil[len(C)/128] - len(C) - * v = 128 * ceil[len(A)/128] - len(A) - * S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64) - * (i.e., zero padded to block size A || C and lengths of each in bits) - */ - ghash_start(S); - ghash(H, aad, aad_len, S); - ghash(H, crypt, crypt_len, S); - WPA_PUT_BE64(len_buf, aad_len * 8); - WPA_PUT_BE64(len_buf + 8, crypt_len * 8); - ghash(H, len_buf, sizeof(len_buf), S); - - wpa_hexdump_key(_MSG_EXCESSIVE_, "S = GHASH_H(...)", S, 16); -} - - -/** - * aes_gcm_ae - GCM-AE_K(IV, P, A) - */ -int aes_gcm_ae(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len, - const u8 *plain, size_t plain_len, - const u8 *aad, size_t aad_len, u8 *crypt, u8 *tag) -{ - u8 H[AES_BLOCK_SIZE]; - u8 J0[AES_BLOCK_SIZE]; - u8 S[16]; - void *aes; - - aes = aes_gcm_init_hash_subkey(key, key_len, H); - if (aes == NULL) - return -1; - - aes_gcm_prepare_j0(iv, iv_len, H, J0); - - /* C = GCTR_K(inc_32(J_0), P) */ - aes_gcm_gctr(aes, J0, plain, plain_len, crypt); - - aes_gcm_ghash(H, aad, aad_len, crypt, plain_len, S); - - /* T = MSB_t(GCTR_K(J_0, S)) */ - aes_gctr(aes, J0, S, sizeof(S), tag); - - /* Return (C, T) */ - - aes_encrypt_deinit(aes); - - return 0; -} - - -/** - * aes_gcm_ad - GCM-AD_K(IV, C, A, T) - */ -int aes_gcm_ad(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len, - const u8 *crypt, size_t crypt_len, - const u8 *aad, size_t aad_len, const u8 *tag, u8 *plain) -{ - u8 H[AES_BLOCK_SIZE]; - u8 J0[AES_BLOCK_SIZE]; - u8 S[16], T[16]; - void *aes; - - aes = aes_gcm_init_hash_subkey(key, key_len, H); - if (aes == NULL) - return -1; - - aes_gcm_prepare_j0(iv, iv_len, H, J0); - - /* P = GCTR_K(inc_32(J_0), C) */ - aes_gcm_gctr(aes, J0, crypt, crypt_len, plain); - - aes_gcm_ghash(H, aad, aad_len, crypt, crypt_len, S); - - /* T' = MSB_t(GCTR_K(J_0, S)) */ - aes_gctr(aes, J0, S, sizeof(S), T); - - aes_encrypt_deinit(aes); - - if (os_memcmp_const(tag, T, 16) != 0) { - wpa_printf(_MSG_EXCESSIVE_, "GCM: Tag mismatch"); - return -1; - } - - return 0; -} - - -int aes_gmac(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len, - const u8 *aad, size_t aad_len, u8 *tag) -{ - return aes_gcm_ae(key, key_len, iv, iv_len, NULL, 0, aad, aad_len, NULL, - tag); -} +/* + * Galois/Counter Mode (GCM) and GMAC with AES + * + * Copyright (c) 2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes.h" +#include "aes_wrap.h" + +static void inc32(u8 *block) +{ + u32 val; + val = WPA_GET_BE32(block + AES_BLOCK_SIZE - 4); + val++; + WPA_PUT_BE32(block + AES_BLOCK_SIZE - 4, val); +} + + +static void xor_block(u8 *dst, const u8 *src) +{ + u32 *d = (u32 *) dst; + u32 *s = (u32 *) src; + *d++ ^= *s++; + *d++ ^= *s++; + *d++ ^= *s++; + *d++ ^= *s++; +} + + +static void shift_right_block(u8 *v) +{ + u32 val; + + val = WPA_GET_BE32(v + 12); + val >>= 1; + if (v[11] & 0x01) + val |= 0x80000000; + WPA_PUT_BE32(v + 12, val); + + val = WPA_GET_BE32(v + 8); + val >>= 1; + if (v[7] & 0x01) + val |= 0x80000000; + WPA_PUT_BE32(v + 8, val); + + val = WPA_GET_BE32(v + 4); + val >>= 1; + if (v[3] & 0x01) + val |= 0x80000000; + WPA_PUT_BE32(v + 4, val); + + val = WPA_GET_BE32(v); + val >>= 1; + WPA_PUT_BE32(v, val); +} + + +/* Multiplication in GF(2^128) */ +static void gf_mult(const u8 *x, const u8 *y, u8 *z) +{ + u8 v[16]; + int i, j; + + os_memset(z, 0, 16); /* Z_0 = 0^128 */ + os_memcpy(v, y, 16); /* V_0 = Y */ + + for (i = 0; i < 16; i++) { + for (j = 0; j < 8; j++) { + if (x[i] & BIT(7 - j)) { + /* Z_(i + 1) = Z_i XOR V_i */ + xor_block(z, v); + } else { + /* Z_(i + 1) = Z_i */ + } + + if (v[15] & 0x01) { + /* V_(i + 1) = (V_i >> 1) XOR R */ + shift_right_block(v); + /* R = 11100001 || 0^120 */ + v[0] ^= 0xe1; + } else { + /* V_(i + 1) = V_i >> 1 */ + shift_right_block(v); + } + } + } +} + + +static void ghash_start(u8 *y) +{ + /* Y_0 = 0^128 */ + os_memset(y, 0, 16); +} + + +static void ghash(const u8 *h, const u8 *x, size_t xlen, u8 *y) +{ + size_t m, i; + const u8 *xpos = x; + u8 tmp[16]; + + m = xlen / 16; + + for (i = 0; i < m; i++) { + /* Y_i = (Y^(i-1) XOR X_i) dot H */ + xor_block(y, xpos); + xpos += 16; + + /* dot operation: + * multiplication operation for binary Galois (finite) field of + * 2^128 elements */ + gf_mult(y, h, tmp); + os_memcpy(y, tmp, 16); + } + + if (x + xlen > xpos) { + /* Add zero padded last block */ + size_t last = x + xlen - xpos; + os_memcpy(tmp, xpos, last); + os_memset(tmp + last, 0, sizeof(tmp) - last); + + /* Y_i = (Y^(i-1) XOR X_i) dot H */ + xor_block(y, tmp); + + /* dot operation: + * multiplication operation for binary Galois (finite) field of + * 2^128 elements */ + gf_mult(y, h, tmp); + os_memcpy(y, tmp, 16); + } + + /* Return Y_m */ +} + + +static void aes_gctr(void *aes, const u8 *icb, const u8 *x, size_t xlen, u8 *y) +{ + size_t i, n, last; + u8 cb[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE]; + const u8 *xpos = x; + u8 *ypos = y; + + if (xlen == 0) + return; + + n = xlen / 16; + + os_memcpy(cb, icb, AES_BLOCK_SIZE); + /* Full blocks */ + for (i = 0; i < n; i++) { + aes_encrypt(aes, cb, ypos); + xor_block(ypos, xpos); + xpos += AES_BLOCK_SIZE; + ypos += AES_BLOCK_SIZE; + inc32(cb); + } + + last = x + xlen - xpos; + if (last) { + /* Last, partial block */ + aes_encrypt(aes, cb, tmp); + for (i = 0; i < last; i++) + *ypos++ = *xpos++ ^ tmp[i]; + } +} + + +static void * aes_gcm_init_hash_subkey(const u8 *key, size_t key_len, u8 *H) +{ + void *aes; + + aes = aes_encrypt_init(key, key_len); + if (aes == NULL) + return NULL; + + /* Generate hash subkey H = AES_K(0^128) */ + os_memset(H, 0, AES_BLOCK_SIZE); + aes_encrypt(aes, H, H); + wpa_hexdump_key(_MSG_EXCESSIVE_, "Hash subkey H for GHASH", + H, AES_BLOCK_SIZE); + return aes; +} + + +static void aes_gcm_prepare_j0(const u8 *iv, size_t iv_len, const u8 *H, u8 *J0) +{ + u8 len_buf[16]; + + if (iv_len == 12) { + /* Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */ + os_memcpy(J0, iv, iv_len); + os_memset(J0 + iv_len, 0, AES_BLOCK_SIZE - iv_len); + J0[AES_BLOCK_SIZE - 1] = 0x01; + } else { + /* + * s = 128 * ceil(len(IV)/128) - len(IV) + * J_0 = GHASH_H(IV || 0^(s+64) || [len(IV)]_64) + */ + ghash_start(J0); + ghash(H, iv, iv_len, J0); + WPA_PUT_BE64(len_buf, 0); + WPA_PUT_BE64(len_buf + 8, iv_len * 8); + ghash(H, len_buf, sizeof(len_buf), J0); + } +} + + +static void aes_gcm_gctr(void *aes, const u8 *J0, const u8 *in, size_t len, + u8 *out) +{ + u8 J0inc[AES_BLOCK_SIZE]; + + if (len == 0) + return; + + os_memcpy(J0inc, J0, AES_BLOCK_SIZE); + inc32(J0inc); + aes_gctr(aes, J0inc, in, len, out); +} + + +static void aes_gcm_ghash(const u8 *H, const u8 *aad, size_t aad_len, + const u8 *crypt, size_t crypt_len, u8 *S) +{ + u8 len_buf[16]; + + /* + * u = 128 * ceil[len(C)/128] - len(C) + * v = 128 * ceil[len(A)/128] - len(A) + * S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64) + * (i.e., zero padded to block size A || C and lengths of each in bits) + */ + ghash_start(S); + ghash(H, aad, aad_len, S); + ghash(H, crypt, crypt_len, S); + WPA_PUT_BE64(len_buf, aad_len * 8); + WPA_PUT_BE64(len_buf + 8, crypt_len * 8); + ghash(H, len_buf, sizeof(len_buf), S); + + wpa_hexdump_key(_MSG_EXCESSIVE_, "S = GHASH_H(...)", S, 16); +} + + +/** + * aes_gcm_ae - GCM-AE_K(IV, P, A) + */ +int aes_gcm_ae(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len, + const u8 *plain, size_t plain_len, + const u8 *aad, size_t aad_len, u8 *crypt, u8 *tag) +{ + u8 H[AES_BLOCK_SIZE]; + u8 J0[AES_BLOCK_SIZE]; + u8 S[16]; + void *aes; + + aes = aes_gcm_init_hash_subkey(key, key_len, H); + if (aes == NULL) + return -1; + + aes_gcm_prepare_j0(iv, iv_len, H, J0); + + /* C = GCTR_K(inc_32(J_0), P) */ + aes_gcm_gctr(aes, J0, plain, plain_len, crypt); + + aes_gcm_ghash(H, aad, aad_len, crypt, plain_len, S); + + /* T = MSB_t(GCTR_K(J_0, S)) */ + aes_gctr(aes, J0, S, sizeof(S), tag); + + /* Return (C, T) */ + + aes_encrypt_deinit(aes); + + return 0; +} + + +/** + * aes_gcm_ad - GCM-AD_K(IV, C, A, T) + */ +int aes_gcm_ad(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len, + const u8 *crypt, size_t crypt_len, + const u8 *aad, size_t aad_len, const u8 *tag, u8 *plain) +{ + u8 H[AES_BLOCK_SIZE]; + u8 J0[AES_BLOCK_SIZE]; + u8 S[16], T[16]; + void *aes; + + aes = aes_gcm_init_hash_subkey(key, key_len, H); + if (aes == NULL) + return -1; + + aes_gcm_prepare_j0(iv, iv_len, H, J0); + + /* P = GCTR_K(inc_32(J_0), C) */ + aes_gcm_gctr(aes, J0, crypt, crypt_len, plain); + + aes_gcm_ghash(H, aad, aad_len, crypt, crypt_len, S); + + /* T' = MSB_t(GCTR_K(J_0, S)) */ + aes_gctr(aes, J0, S, sizeof(S), T); + + aes_encrypt_deinit(aes); + + if (os_memcmp_const(tag, T, 16) != 0) { + wpa_printf(_MSG_EXCESSIVE_, "GCM: Tag mismatch"); + return -1; + } + + return 0; +} + + +int aes_gmac(const u8 *key, size_t key_len, const u8 *iv, size_t iv_len, + const u8 *aad, size_t aad_len, u8 *tag) +{ + return aes_gcm_ae(key, key_len, iv, iv_len, NULL, 0, aad, aad_len, NULL, + tag); +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-internal-enc.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-internal-enc.c index c0891ce4fcf2..67e3a7f3571e 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-internal-enc.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-internal-enc.c @@ -1,130 +1,130 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * AES (Rijndael) cipher - encrypt - * - * Modifications to public domain implementation: - * - cleanup - * - use C pre-processor to make it easier to change S table access - * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at - * cost of reduced throughput (quite small difference on Pentium 4, - * 10-25% when using -O1 or -O2 optimization) - * - * Copyright (c) 2003-2012, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#include "rtw_crypto_wrap.h" - -#include "aes_i.h" - -static void rijndaelEncrypt(const u32 rk[], int Nr, const u8 pt[16], u8 ct[16]) -{ - u32 s0, s1, s2, s3, t0, t1, t2, t3; -#ifndef FULL_UNROLL - int r; -#endif /* ?FULL_UNROLL */ - - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(pt ) ^ rk[0]; - s1 = GETU32(pt + 4) ^ rk[1]; - s2 = GETU32(pt + 8) ^ rk[2]; - s3 = GETU32(pt + 12) ^ rk[3]; - -#define ROUND(i,d,s) \ -d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \ -d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \ -d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \ -d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3] - -#ifdef FULL_UNROLL - - ROUND(1,t,s); - ROUND(2,s,t); - ROUND(3,t,s); - ROUND(4,s,t); - ROUND(5,t,s); - ROUND(6,s,t); - ROUND(7,t,s); - ROUND(8,s,t); - ROUND(9,t,s); - if (Nr > 10) { - ROUND(10,s,t); - ROUND(11,t,s); - if (Nr > 12) { - ROUND(12,s,t); - ROUND(13,t,s); - } - } - - rk += Nr << 2; - -#else /* !FULL_UNROLL */ - - /* Nr - 1 full rounds: */ - r = Nr >> 1; - for (;;) { - ROUND(1,t,s); - rk += 8; - if (--r == 0) - break; - ROUND(0,s,t); - } - -#endif /* ?FULL_UNROLL */ - -#undef ROUND - - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0]; - PUTU32(ct , s0); - s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1]; - PUTU32(ct + 4, s1); - s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2]; - PUTU32(ct + 8, s2); - s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3]; - PUTU32(ct + 12, s3); -} - - -void * aes_encrypt_init(const u8 *key, size_t len) -{ - u32 *rk; - int res; - - if (TEST_FAIL()) - return NULL; - - rk = os_malloc(AES_PRIV_SIZE); - if (rk == NULL) - return NULL; - res = rijndaelKeySetupEnc(rk, key, len * 8); - if (res < 0) { - rtw_mfree(rk, AES_PRIV_SIZE); - return NULL; - } - rk[AES_PRIV_NR_POS] = res; - return rk; -} - - -int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) -{ - u32 *rk = ctx; - rijndaelEncrypt(ctx, rk[AES_PRIV_NR_POS], plain, crypt); - return 0; -} - - -void aes_encrypt_deinit(void *ctx) -{ - os_memset(ctx, 0, AES_PRIV_SIZE); - rtw_mfree(ctx, AES_PRIV_SIZE); -} +/* + * AES (Rijndael) cipher - encrypt + * + * Modifications to public domain implementation: + * - cleanup + * - use C pre-processor to make it easier to change S table access + * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at + * cost of reduced throughput (quite small difference on Pentium 4, + * 10-25% when using -O1 or -O2 optimization) + * + * Copyright (c) 2003-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes_i.h" + +static void rijndaelEncrypt(const u32 rk[], int Nr, const u8 pt[16], u8 ct[16]) +{ + u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(pt ) ^ rk[0]; + s1 = GETU32(pt + 4) ^ rk[1]; + s2 = GETU32(pt + 8) ^ rk[2]; + s3 = GETU32(pt + 12) ^ rk[3]; + +#define ROUND(i,d,s) \ +d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \ +d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \ +d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \ +d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3] + +#ifdef FULL_UNROLL + + ROUND(1,t,s); + ROUND(2,s,t); + ROUND(3,t,s); + ROUND(4,s,t); + ROUND(5,t,s); + ROUND(6,s,t); + ROUND(7,t,s); + ROUND(8,s,t); + ROUND(9,t,s); + if (Nr > 10) { + ROUND(10,s,t); + ROUND(11,t,s); + if (Nr > 12) { + ROUND(12,s,t); + ROUND(13,t,s); + } + } + + rk += Nr << 2; + +#else /* !FULL_UNROLL */ + + /* Nr - 1 full rounds: */ + r = Nr >> 1; + for (;;) { + ROUND(1,t,s); + rk += 8; + if (--r == 0) + break; + ROUND(0,s,t); + } + +#endif /* ?FULL_UNROLL */ + +#undef ROUND + + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0]; + PUTU32(ct , s0); + s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1]; + PUTU32(ct + 4, s1); + s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2]; + PUTU32(ct + 8, s2); + s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3]; + PUTU32(ct + 12, s3); +} + + +void * aes_encrypt_init(const u8 *key, size_t len) +{ + u32 *rk; + int res; + + if (TEST_FAIL()) + return NULL; + + rk = os_malloc(AES_PRIV_SIZE); + if (rk == NULL) + return NULL; + res = rijndaelKeySetupEnc(rk, key, len * 8); + if (res < 0) { + rtw_mfree(rk, AES_PRIV_SIZE); + return NULL; + } + rk[AES_PRIV_NR_POS] = res; + return rk; +} + + +int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) +{ + u32 *rk = ctx; + rijndaelEncrypt(ctx, rk[AES_PRIV_NR_POS], plain, crypt); + return 0; +} + + +void aes_encrypt_deinit(void *ctx) +{ + os_memset(ctx, 0, AES_PRIV_SIZE); + rtw_mfree(ctx, AES_PRIV_SIZE); +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-internal.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-internal.c index 9c8de33dec96..c980909a794d 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-internal.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-internal.c @@ -1,844 +1,844 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * AES (Rijndael) cipher - * - * Modifications to public domain implementation: - * - cleanup - * - use C pre-processor to make it easier to change S table access - * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at - * cost of reduced throughput (quite small difference on Pentium 4, - * 10-25% when using -O1 or -O2 optimization) - * - * Copyright (c) 2003-2012, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#include "rtw_crypto_wrap.h" - -#include "aes_i.h" - -/* - * rijndael-alg-fst.c - * - * @version 3.0 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * @author Vincent Rijmen - * @author Antoon Bosselaers - * @author Paulo Barreto - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -/* -Te0[x] = S [x].[02, 01, 01, 03]; -Te1[x] = S [x].[03, 02, 01, 01]; -Te2[x] = S [x].[01, 03, 02, 01]; -Te3[x] = S [x].[01, 01, 03, 02]; -Te4[x] = S [x].[01, 01, 01, 01]; - -Td0[x] = Si[x].[0e, 09, 0d, 0b]; -Td1[x] = Si[x].[0b, 0e, 09, 0d]; -Td2[x] = Si[x].[0d, 0b, 0e, 09]; -Td3[x] = Si[x].[09, 0d, 0b, 0e]; -Td4[x] = Si[x].[01, 01, 01, 01]; -*/ - -const u32 Te0[256] = { - 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, - 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, - 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, - 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, - 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, - 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, - 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, - 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, - 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, - 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, - 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, - 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, - 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, - 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, - 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, - 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, - 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, - 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, - 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, - 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, - 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, - 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, - 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, - 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, - 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, - 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, - 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, - 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, - 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, - 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, - 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, - 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, - 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, - 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, - 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, - 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, - 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, - 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, - 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, - 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, - 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, - 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, - 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, - 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, - 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, - 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, - 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, - 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, - 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, - 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, - 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, - 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, - 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, - 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, - 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, - 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, - 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, - 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, - 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, - 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, - 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, - 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, - 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, - 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, -}; -#ifndef AES_SMALL_TABLES -const u32 Te1[256] = { - 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, - 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, - 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, - 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, - 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, - 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, - 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, - 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, - 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, - 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, - 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, - 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, - 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, - 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, - 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, - 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, - 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, - 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, - 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, - 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, - 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, - 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, - 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, - 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, - 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, - 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, - 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, - 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, - 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, - 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, - 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, - 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, - 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, - 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, - 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, - 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, - 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, - 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, - 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, - 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, - 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, - 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, - 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, - 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, - 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, - 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, - 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, - 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, - 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, - 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, - 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, - 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, - 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, - 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, - 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, - 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, - 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, - 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, - 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, - 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, - 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, - 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, - 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, - 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, -}; -const u32 Te2[256] = { - 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, - 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, - 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, - 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, - 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, - 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, - 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, - 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, - 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, - 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, - 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, - 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, - 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, - 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, - 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, - 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, - 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, - 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, - 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, - 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, - 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, - 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, - 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, - 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, - 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, - 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, - 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, - 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, - 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, - 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, - 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, - 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, - 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, - 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, - 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, - 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, - 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, - 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, - 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, - 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, - 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, - 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, - 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, - 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, - 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, - 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, - 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, - 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, - 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, - 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, - 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, - 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, - 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, - 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, - 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, - 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, - 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, - 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, - 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, - 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, - 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, - 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, - 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, - 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, -}; -const u32 Te3[256] = { - - 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, - 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, - 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, - 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, - 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, - 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, - 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, - 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, - 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, - 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, - 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, - 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, - 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, - 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, - 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, - 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, - 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, - 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, - 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, - 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, - 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, - 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, - 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, - 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, - 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, - 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, - 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, - 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, - 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, - 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, - 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, - 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, - 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, - 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, - 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, - 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, - 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, - 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, - 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, - 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, - 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, - 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, - 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, - 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, - 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, - 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, - 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, - 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, - 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, - 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, - 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, - 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, - 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, - 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, - 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, - 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, - 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, - 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, - 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, - 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, - 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, - 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, - 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, - 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, -}; -const u32 Te4[256] = { - 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, - 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, - 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, - 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, - 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, - 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, - 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, - 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, - 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, - 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, - 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, - 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, - 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, - 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, - 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, - 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, - 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, - 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, - 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, - 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, - 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, - 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, - 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, - 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, - 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, - 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, - 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, - 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, - 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, - 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, - 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, - 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, - 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, - 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, - 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, - 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, - 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, - 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, - 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, - 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, - 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, - 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, - 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, - 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, - 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, - 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, - 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, - 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, - 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, - 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, - 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, - 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, - 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, - 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, - 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, - 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, - 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, - 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, - 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, - 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, - 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, - 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, - 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, - 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, -}; -#endif /* AES_SMALL_TABLES */ -const u32 Td0[256] = { - 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, - 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, - 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, - 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, - 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, - 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, - 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, - 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, - 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, - 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, - 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, - 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, - 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, - 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, - 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, - 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, - 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, - 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, - 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, - 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, - 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, - 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, - 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, - 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, - 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, - 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, - 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, - 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, - 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, - 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, - 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, - 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, - 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, - 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, - 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, - 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, - 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, - 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, - 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, - 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, - 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, - 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, - 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, - 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, - 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, - 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, - 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, - 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, - 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, - 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, - 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, - 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, - 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, - 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, - 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, - 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, - 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, - 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, - 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, - 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, - 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, - 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, - 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, - 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, -}; -#ifndef AES_SMALL_TABLES -const u32 Td1[256] = { - 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, - 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, - 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, - 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, - 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, - 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, - 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, - 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, - 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, - 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, - 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, - 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, - 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, - 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, - 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, - 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, - 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, - 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, - 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, - 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, - 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, - 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, - 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, - 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, - 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, - 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, - 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, - 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, - 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, - 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, - 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, - 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, - 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, - 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, - 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, - 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, - 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, - 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, - 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, - 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, - 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, - 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, - 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, - 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, - 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, - 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, - 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, - 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, - 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, - 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, - 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, - 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, - 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, - 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, - 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, - 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, - 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, - 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, - 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, - 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, - 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, - 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, - 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, - 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, -}; -const u32 Td2[256] = { - 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, - 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, - 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, - 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, - 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, - 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, - 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, - 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, - 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, - 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, - 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, - 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, - 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, - 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, - 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, - 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, - 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, - 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, - 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, - 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, - - 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, - 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, - 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, - 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, - 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, - 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, - 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, - 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, - 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, - 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, - 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, - 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, - 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, - 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, - 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, - 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, - 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, - 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, - 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, - 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, - 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, - 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, - 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, - 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, - 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, - 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, - 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, - 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, - 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, - 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, - 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, - 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, - 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, - 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, - 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, - 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, - 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, - 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, - 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, - 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, - 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, - 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, - 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, - 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, -}; -const u32 Td3[256] = { - 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, - 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, - 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, - 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, - 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, - 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, - 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, - 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, - 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, - 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, - 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, - 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, - 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, - 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, - 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, - 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, - 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, - 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, - 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, - 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, - 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, - 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, - 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, - 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, - 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, - 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, - 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, - 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, - 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, - 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, - 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, - 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, - 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, - 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, - 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, - 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, - 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, - 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, - 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, - 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, - 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, - 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, - 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, - 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, - 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, - 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, - 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, - 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, - 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, - 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, - 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, - 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, - 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, - 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, - 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, - 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, - 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, - 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, - 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, - 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, - 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, - 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, - 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, - 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, -}; -const u32 Td4[256] = { - 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, - 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, - 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, - 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, - 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, - 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, - 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, - 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, - 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, - 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, - 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, - 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, - 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, - 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, - 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, - 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, - 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, - 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, - 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, - 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, - 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, - 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, - 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, - 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, - 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, - 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, - 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, - 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, - 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, - 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, - 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, - 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, - 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, - 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, - 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, - 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, - 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, - 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, - 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, - 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, - 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, - 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, - 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, - 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, - 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, - 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, - 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, - 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, - 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, - 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, - 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, - 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, - 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, - 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, - 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, - 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, - 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, - 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, - 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, - 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, - 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, - 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, - 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, - 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, -}; -const u32 rcon[] = { - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ -}; -#else /* AES_SMALL_TABLES */ -const u8 Td4s[256] = { - 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, - 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, - 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, - 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, - 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, - 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, - 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, - 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, - 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, - 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, - 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, - 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, - 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, - 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, - 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, - 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, - 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, - 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, - 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, - 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, - 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, - 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, - 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, - 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, - 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, - 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, - 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, - 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, - 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, - 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, - 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, - 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, -}; -const u8 rcons[] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 - /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ -}; -#endif /* AES_SMALL_TABLES */ -/** - * Expand the cipher key into the encryption key schedule. - * - * @return the number of rounds for the given cipher key size. - */ -int rijndaelKeySetupEnc(u32 rk[], const u8 cipherKey[], int keyBits) -{ - int i; - u32 temp; - - rk[0] = GETU32(cipherKey ); - rk[1] = GETU32(cipherKey + 4); - rk[2] = GETU32(cipherKey + 8); - rk[3] = GETU32(cipherKey + 12); - - if (keyBits == 128) { - for (i = 0; i < 10; i++) { - temp = rk[3]; - rk[4] = rk[0] ^ TE421(temp) ^ TE432(temp) ^ - TE443(temp) ^ TE414(temp) ^ RCON(i); - rk[5] = rk[1] ^ rk[4]; - rk[6] = rk[2] ^ rk[5]; - rk[7] = rk[3] ^ rk[6]; - rk += 4; - } - return 10; - } - - rk[4] = GETU32(cipherKey + 16); - rk[5] = GETU32(cipherKey + 20); - - if (keyBits == 192) { - for (i = 0; i < 8; i++) { - temp = rk[5]; - rk[6] = rk[0] ^ TE421(temp) ^ TE432(temp) ^ - TE443(temp) ^ TE414(temp) ^ RCON(i); - rk[7] = rk[1] ^ rk[6]; - rk[8] = rk[2] ^ rk[7]; - rk[9] = rk[3] ^ rk[8]; - if (i == 7) - return 12; - rk[10] = rk[4] ^ rk[9]; - rk[11] = rk[5] ^ rk[10]; - rk += 6; - } - } - - rk[6] = GETU32(cipherKey + 24); - rk[7] = GETU32(cipherKey + 28); - - if (keyBits == 256) { - for (i = 0; i < 7; i++) { - temp = rk[7]; - rk[8] = rk[0] ^ TE421(temp) ^ TE432(temp) ^ - TE443(temp) ^ TE414(temp) ^ RCON(i); - rk[9] = rk[1] ^ rk[8]; - rk[10] = rk[2] ^ rk[9]; - rk[11] = rk[3] ^ rk[10]; - if (i == 6) - return 14; - temp = rk[11]; - rk[12] = rk[4] ^ TE411(temp) ^ TE422(temp) ^ - TE433(temp) ^ TE444(temp); - rk[13] = rk[5] ^ rk[12]; - rk[14] = rk[6] ^ rk[13]; - rk[15] = rk[7] ^ rk[14]; - rk += 8; - } - } - - return -1; -} +/* + * AES (Rijndael) cipher + * + * Modifications to public domain implementation: + * - cleanup + * - use C pre-processor to make it easier to change S table access + * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at + * cost of reduced throughput (quite small difference on Pentium 4, + * 10-25% when using -O1 or -O2 optimization) + * + * Copyright (c) 2003-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes_i.h" + +/* + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +/* +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; +Te4[x] = S [x].[01, 01, 01, 01]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01, 01, 01, 01]; +*/ + +const u32 Te0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; +#ifndef AES_SMALL_TABLES +const u32 Te1[256] = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +}; +const u32 Te2[256] = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +}; +const u32 Te3[256] = { + + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}; +const u32 Te4[256] = { + 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, + 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, + 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, + 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, + 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, + 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, + 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, + 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, + 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, + 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, + 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, + 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, + 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, + 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, + 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, + 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, + 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, + 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, + 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, + 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, + 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, + 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, + 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, + 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, + 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, + 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, + 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, + 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, + 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, + 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, + 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, + 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, + 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, + 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, + 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, + 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, + 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, + 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, + 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, + 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, + 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, + 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, + 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, + 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, + 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, + 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, + 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, + 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, + 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, + 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, + 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, + 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, + 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, + 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, + 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, + 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, + 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, + 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, + 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, + 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, + 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, + 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, + 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, + 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, +}; +#endif /* AES_SMALL_TABLES */ +const u32 Td0[256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +}; +#ifndef AES_SMALL_TABLES +const u32 Td1[256] = { + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, + 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, + 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, + 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, + 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, + 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, + 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, + 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, + 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, + 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, + 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, + 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, + 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, + 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, + 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, + 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, + 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, + 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, + 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, + 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, + 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, + 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, + 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, + 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, + 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, + 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, + 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, + 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, + 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, + 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, + 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, + 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, + 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, + 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, + 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, + 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, + 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, + 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, + 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, + 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, + 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, + 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, + 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, + 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, + 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, + 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, + 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, + 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, + 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, + 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, + 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, + 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, + 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, + 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, + 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, + 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, + 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, + 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, +}; +const u32 Td2[256] = { + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, + 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, + 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, + 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, + 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, + 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, + 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, + 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, + 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, + 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, + 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, + 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, + 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, + 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, + 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, + 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, + 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, + 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, + 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, + 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, + 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, + 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, + 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, + 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, + 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, + 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, + 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, + 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, + 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, + 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, + 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, + 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, + 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, + 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, + 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, + 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, + 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, + 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, + 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, + 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, + 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, + 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, + 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, + 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, + 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, + 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, + 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, + 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, + 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, + 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, + 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, + 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, + 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, + 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, + 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, + 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, + 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, + 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, +}; +const u32 Td3[256] = { + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, + 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, + 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, + 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, + 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, + 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, + 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, + 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, + 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, + 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, + 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, + 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, + 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, + 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, + 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, + 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, + 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, + 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, + 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, + 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, + 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, + 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, + 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, + 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, + 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, + 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, + 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, + 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, + 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, + 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, + 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, + 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, + 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, + 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, + 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, + 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, + 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, + 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, + 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, + 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, + 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, + 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, + 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, + 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, + 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, + 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, + 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, + 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, + 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, + 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, + 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, + 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, + 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, + 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, + 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, + 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, + 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, + 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, +}; +const u32 Td4[256] = { + 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, + 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, + 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, + 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, + 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, + 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, + 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, + 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, + 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, + 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, + 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, + 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, + 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, + 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, + 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, + 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, + 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, + 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, + 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, + 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, + 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, + 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, + 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, + 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, + 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, + 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, + 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, + 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, + 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, + 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, + 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, + 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, + 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, + 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, + 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, + 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, + 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, + 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, + 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, + 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, + 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, + 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, + 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, + 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, + 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, + 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, + 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, + 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, + 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, + 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, + 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, + 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, + 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, + 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, + 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, + 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, + 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, + 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, + 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, + 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, + 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, + 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, + 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, + 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, +}; +const u32 rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; +#else /* AES_SMALL_TABLES */ +const u8 Td4s[256] = { + 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, + 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, + 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, + 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, + 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, + 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, + 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, + 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, + 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, + 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, + 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, + 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, + 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, + 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, + 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, + 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, + 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, + 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, + 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, + 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, + 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, + 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, + 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, + 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, + 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, + 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, + 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, + 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, + 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, + 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, + 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, + 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, +}; +const u8 rcons[] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 + /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; +#endif /* AES_SMALL_TABLES */ +/** + * Expand the cipher key into the encryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +int rijndaelKeySetupEnc(u32 rk[], const u8 cipherKey[], int keyBits) +{ + int i; + u32 temp; + + rk[0] = GETU32(cipherKey ); + rk[1] = GETU32(cipherKey + 4); + rk[2] = GETU32(cipherKey + 8); + rk[3] = GETU32(cipherKey + 12); + + if (keyBits == 128) { + for (i = 0; i < 10; i++) { + temp = rk[3]; + rk[4] = rk[0] ^ TE421(temp) ^ TE432(temp) ^ + TE443(temp) ^ TE414(temp) ^ RCON(i); + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + rk += 4; + } + return 10; + } + + rk[4] = GETU32(cipherKey + 16); + rk[5] = GETU32(cipherKey + 20); + + if (keyBits == 192) { + for (i = 0; i < 8; i++) { + temp = rk[5]; + rk[6] = rk[0] ^ TE421(temp) ^ TE432(temp) ^ + TE443(temp) ^ TE414(temp) ^ RCON(i); + rk[7] = rk[1] ^ rk[6]; + rk[8] = rk[2] ^ rk[7]; + rk[9] = rk[3] ^ rk[8]; + if (i == 7) + return 12; + rk[10] = rk[4] ^ rk[9]; + rk[11] = rk[5] ^ rk[10]; + rk += 6; + } + } + + rk[6] = GETU32(cipherKey + 24); + rk[7] = GETU32(cipherKey + 28); + + if (keyBits == 256) { + for (i = 0; i < 7; i++) { + temp = rk[7]; + rk[8] = rk[0] ^ TE421(temp) ^ TE432(temp) ^ + TE443(temp) ^ TE414(temp) ^ RCON(i); + rk[9] = rk[1] ^ rk[8]; + rk[10] = rk[2] ^ rk[9]; + rk[11] = rk[3] ^ rk[10]; + if (i == 6) + return 14; + temp = rk[11]; + rk[12] = rk[4] ^ TE411(temp) ^ TE422(temp) ^ + TE433(temp) ^ TE444(temp); + rk[13] = rk[5] ^ rk[12]; + rk[14] = rk[6] ^ rk[13]; + rk[15] = rk[7] ^ rk[14]; + rk += 8; + } + } + + return -1; +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-omac1.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-omac1.c index 8cbe51cfbec2..0e5277468f61 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-omac1.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-omac1.c @@ -1,173 +1,173 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * One-key CBC MAC (OMAC1) hash with AES - * - * Copyright (c) 2003-2007, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#include "rtw_crypto_wrap.h" - -#include "aes.h" -#include "aes_wrap.h" - -static void gf_mulx(u8 *pad) -{ - int i, carry; - - carry = pad[0] & 0x80; - for (i = 0; i < AES_BLOCK_SIZE - 1; i++) - pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); - pad[AES_BLOCK_SIZE - 1] <<= 1; - if (carry) - pad[AES_BLOCK_SIZE - 1] ^= 0x87; -} - - -/** - * omac1_aes_vector - One-Key CBC MAC (OMAC1) hash with AES - * @key: Key for the hash operation - * @key_len: Key length in octets - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) - * Returns: 0 on success, -1 on failure - * - * This is a mode for using block cipher (AES in this case) for authentication. - * OMAC1 was standardized with the name CMAC by NIST in a Special Publication - * (SP) 800-38B. - */ -int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem, - const u8 *addr[], const size_t *len, u8 *mac) -{ - void *ctx; - u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE]; - const u8 *pos, *end; - size_t i, e, left, total_len; - - if (TEST_FAIL()) - return -1; - - ctx = aes_encrypt_init(key, key_len); - if (ctx == NULL) - return -1; - os_memset(cbc, 0, AES_BLOCK_SIZE); - - total_len = 0; - for (e = 0; e < num_elem; e++) - total_len += len[e]; - left = total_len; - - e = 0; - pos = addr[0]; - end = pos + len[0]; - - while (left >= AES_BLOCK_SIZE) { - for (i = 0; i < AES_BLOCK_SIZE; i++) { - cbc[i] ^= *pos++; - if (pos >= end) { - /* - * Stop if there are no more bytes to process - * since there are no more entries in the array. - */ - if (i + 1 == AES_BLOCK_SIZE && - left == AES_BLOCK_SIZE) - break; - e++; - pos = addr[e]; - end = pos + len[e]; - } - } - if (left > AES_BLOCK_SIZE) - aes_encrypt(ctx, cbc, cbc); - left -= AES_BLOCK_SIZE; - } - - os_memset(pad, 0, AES_BLOCK_SIZE); - aes_encrypt(ctx, pad, pad); - gf_mulx(pad); - - if (left || total_len == 0) { - for (i = 0; i < left; i++) { - cbc[i] ^= *pos++; - if (pos >= end) { - /* - * Stop if there are no more bytes to process - * since there are no more entries in the array. - */ - if (i + 1 == left) - break; - e++; - pos = addr[e]; - end = pos + len[e]; - } - } - cbc[left] ^= 0x80; - gf_mulx(pad); - } - - for (i = 0; i < AES_BLOCK_SIZE; i++) - pad[i] ^= cbc[i]; - aes_encrypt(ctx, pad, mac); - aes_encrypt_deinit(ctx); - return 0; -} - - -/** - * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128 - * @key: 128-bit key for the hash operation - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) - * Returns: 0 on success, -1 on failure - * - * This is a mode for using block cipher (AES in this case) for authentication. - * OMAC1 was standardized with the name CMAC by NIST in a Special Publication - * (SP) 800-38B. - */ -int omac1_aes_128_vector(const u8 *key, size_t num_elem, - const u8 *addr[], const size_t *len, u8 *mac) -{ - return omac1_aes_vector(key, 16, num_elem, addr, len, mac); -} - - -/** - * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC) - * @key: 128-bit key for the hash operation - * @data: Data buffer for which a MAC is determined - * @data_len: Length of data buffer in bytes - * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) - * Returns: 0 on success, -1 on failure - * - * This is a mode for using block cipher (AES in this case) for authentication. - * OMAC1 was standardized with the name CMAC by NIST in a Special Publication - * (SP) 800-38B. - */ -int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) -{ - return omac1_aes_128_vector(key, 1, &data, &data_len, mac); -} - - -/** - * omac1_aes_256 - One-Key CBC MAC (OMAC1) hash with AES-256 (aka AES-CMAC) - * @key: 256-bit key for the hash operation - * @data: Data buffer for which a MAC is determined - * @data_len: Length of data buffer in bytes - * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) - * Returns: 0 on success, -1 on failure - * - * This is a mode for using block cipher (AES in this case) for authentication. - * OMAC1 was standardized with the name CMAC by NIST in a Special Publication - * (SP) 800-38B. - */ -int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac) -{ - return omac1_aes_vector(key, 32, 1, &data, &data_len, mac); -} +/* + * One-key CBC MAC (OMAC1) hash with AES + * + * Copyright (c) 2003-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes.h" +#include "aes_wrap.h" + +static void gf_mulx(u8 *pad) +{ + int i, carry; + + carry = pad[0] & 0x80; + for (i = 0; i < AES_BLOCK_SIZE - 1; i++) + pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); + pad[AES_BLOCK_SIZE - 1] <<= 1; + if (carry) + pad[AES_BLOCK_SIZE - 1] ^= 0x87; +} + + +/** + * omac1_aes_vector - One-Key CBC MAC (OMAC1) hash with AES + * @key: Key for the hash operation + * @key_len: Key length in octets + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) + * Returns: 0 on success, -1 on failure + * + * This is a mode for using block cipher (AES in this case) for authentication. + * OMAC1 was standardized with the name CMAC by NIST in a Special Publication + * (SP) 800-38B. + */ +int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) +{ + void *ctx; + u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE]; + const u8 *pos, *end; + size_t i, e, left, total_len; + + if (TEST_FAIL()) + return -1; + + ctx = aes_encrypt_init(key, key_len); + if (ctx == NULL) + return -1; + os_memset(cbc, 0, AES_BLOCK_SIZE); + + total_len = 0; + for (e = 0; e < num_elem; e++) + total_len += len[e]; + left = total_len; + + e = 0; + pos = addr[0]; + end = pos + len[0]; + + while (left >= AES_BLOCK_SIZE) { + for (i = 0; i < AES_BLOCK_SIZE; i++) { + cbc[i] ^= *pos++; + if (pos >= end) { + /* + * Stop if there are no more bytes to process + * since there are no more entries in the array. + */ + if (i + 1 == AES_BLOCK_SIZE && + left == AES_BLOCK_SIZE) + break; + e++; + pos = addr[e]; + end = pos + len[e]; + } + } + if (left > AES_BLOCK_SIZE) + aes_encrypt(ctx, cbc, cbc); + left -= AES_BLOCK_SIZE; + } + + os_memset(pad, 0, AES_BLOCK_SIZE); + aes_encrypt(ctx, pad, pad); + gf_mulx(pad); + + if (left || total_len == 0) { + for (i = 0; i < left; i++) { + cbc[i] ^= *pos++; + if (pos >= end) { + /* + * Stop if there are no more bytes to process + * since there are no more entries in the array. + */ + if (i + 1 == left) + break; + e++; + pos = addr[e]; + end = pos + len[e]; + } + } + cbc[left] ^= 0x80; + gf_mulx(pad); + } + + for (i = 0; i < AES_BLOCK_SIZE; i++) + pad[i] ^= cbc[i]; + aes_encrypt(ctx, pad, mac); + aes_encrypt_deinit(ctx); + return 0; +} + + +/** + * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128 + * @key: 128-bit key for the hash operation + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) + * Returns: 0 on success, -1 on failure + * + * This is a mode for using block cipher (AES in this case) for authentication. + * OMAC1 was standardized with the name CMAC by NIST in a Special Publication + * (SP) 800-38B. + */ +int omac1_aes_128_vector(const u8 *key, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) +{ + return omac1_aes_vector(key, 16, num_elem, addr, len, mac); +} + + +/** + * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC) + * @key: 128-bit key for the hash operation + * @data: Data buffer for which a MAC is determined + * @data_len: Length of data buffer in bytes + * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) + * Returns: 0 on success, -1 on failure + * + * This is a mode for using block cipher (AES in this case) for authentication. + * OMAC1 was standardized with the name CMAC by NIST in a Special Publication + * (SP) 800-38B. + */ +int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) +{ + return omac1_aes_128_vector(key, 1, &data, &data_len, mac); +} + + +/** + * omac1_aes_256 - One-Key CBC MAC (OMAC1) hash with AES-256 (aka AES-CMAC) + * @key: 256-bit key for the hash operation + * @data: Data buffer for which a MAC is determined + * @data_len: Length of data buffer in bytes + * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) + * Returns: 0 on success, -1 on failure + * + * This is a mode for using block cipher (AES in this case) for authentication. + * OMAC1 was standardized with the name CMAC by NIST in a Special Publication + * (SP) 800-38B. + */ +int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac) +{ + return omac1_aes_vector(key, 32, 1, &data, &data_len, mac); +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-siv.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-siv.c index 6661208c882b..4997140e3a2c 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-siv.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes-siv.c @@ -1,208 +1,208 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * AES SIV (RFC 5297) - * Copyright (c) 2013 Cozybit, Inc. - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#include "rtw_crypto_wrap.h" - -#include "aes.h" -#include "aes_wrap.h" -#include "aes_siv.h" - - -static const u8 zero[AES_BLOCK_SIZE]; - - -static void dbl(u8 *pad) -{ - int i, carry; - - carry = pad[0] & 0x80; - for (i = 0; i < AES_BLOCK_SIZE - 1; i++) - pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); - pad[AES_BLOCK_SIZE - 1] <<= 1; - if (carry) - pad[AES_BLOCK_SIZE - 1] ^= 0x87; -} - - -static void xor(u8 *a, const u8 *b) -{ - int i; - - for (i = 0; i < AES_BLOCK_SIZE; i++) - *a++ ^= *b++; -} - - -static void xorend(u8 *a, int alen, const u8 *b, int blen) -{ - int i; - - if (alen < blen) - return; - - for (i = 0; i < blen; i++) - a[alen - blen + i] ^= b[i]; -} - - -static void pad_block(u8 *pad, const u8 *addr, size_t len) -{ - os_memset(pad, 0, AES_BLOCK_SIZE); - os_memcpy(pad, addr, len); - - if (len < AES_BLOCK_SIZE) - pad[len] = 0x80; -} - - -static int aes_s2v(const u8 *key, size_t key_len, - size_t num_elem, const u8 *addr[], size_t *len, u8 *mac) -{ - u8 tmp[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE]; - u8 *buf = NULL; - int ret; - size_t i; - const u8 *data[1]; - size_t data_len[1]; - - if (!num_elem) { - os_memcpy(tmp, zero, sizeof(zero)); - tmp[AES_BLOCK_SIZE - 1] = 1; - data[0] = tmp; - data_len[0] = sizeof(tmp); - return omac1_aes_vector(key, key_len, 1, data, data_len, mac); - } - - data[0] = zero; - data_len[0] = sizeof(zero); - ret = omac1_aes_vector(key, key_len, 1, data, data_len, tmp); - if (ret) - return ret; - - for (i = 0; i < num_elem - 1; i++) { - ret = omac1_aes_vector(key, key_len, 1, &addr[i], &len[i], - tmp2); - if (ret) - return ret; - - dbl(tmp); - xor(tmp, tmp2); - } - if (len[i] >= AES_BLOCK_SIZE) { - buf = os_memdup(addr[i], len[i]); - if (!buf) - return -ENOMEM; - - xorend(buf, len[i], tmp, AES_BLOCK_SIZE); - data[0] = buf; - ret = omac1_aes_vector(key, key_len, 1, data, &len[i], mac); - bin_clear_free(buf, len[i]); - return ret; - } - - dbl(tmp); - pad_block(tmp2, addr[i], len[i]); - xor(tmp, tmp2); - - data[0] = tmp; - data_len[0] = sizeof(tmp); - return omac1_aes_vector(key, key_len, 1, data, data_len, mac); -} - - -int aes_siv_encrypt(const u8 *key, size_t key_len, - const u8 *pw, size_t pwlen, - size_t num_elem, const u8 *addr[], const size_t *len, - u8 *out) -{ - const u8 *_addr[6]; - size_t _len[6]; - const u8 *k1, *k2; - u8 v[AES_BLOCK_SIZE]; - size_t i; - u8 *iv, *crypt_pw; - - if (num_elem > ARRAY_SIZE(_addr) - 1 || - (key_len != 32 && key_len != 48 && key_len != 64)) - return -1; - - key_len /= 2; - k1 = key; - k2 = key + key_len; - - for (i = 0; i < num_elem; i++) { - _addr[i] = addr[i]; - _len[i] = len[i]; - } - _addr[num_elem] = pw; - _len[num_elem] = pwlen; - - if (aes_s2v(k1, key_len, num_elem + 1, _addr, _len, v)) - return -1; - - iv = out; - crypt_pw = out + AES_BLOCK_SIZE; - - os_memcpy(iv, v, AES_BLOCK_SIZE); - os_memcpy(crypt_pw, pw, pwlen); - - /* zero out 63rd and 31st bits of ctr (from right) */ - v[8] &= 0x7f; - v[12] &= 0x7f; - return aes_ctr_encrypt(k2, key_len, v, crypt_pw, pwlen); -} - - -int aes_siv_decrypt(const u8 *key, size_t key_len, - const u8 *iv_crypt, size_t iv_c_len, - size_t num_elem, const u8 *addr[], const size_t *len, - u8 *out) -{ - const u8 *_addr[6]; - size_t _len[6]; - const u8 *k1, *k2; - size_t crypt_len; - size_t i; - int ret; - u8 iv[AES_BLOCK_SIZE]; - u8 check[AES_BLOCK_SIZE]; - - if (iv_c_len < AES_BLOCK_SIZE || num_elem > ARRAY_SIZE(_addr) - 1 || - (key_len != 32 && key_len != 48 && key_len != 64)) - return -1; - crypt_len = iv_c_len - AES_BLOCK_SIZE; - key_len /= 2; - k1 = key; - k2 = key + key_len; - - for (i = 0; i < num_elem; i++) { - _addr[i] = addr[i]; - _len[i] = len[i]; - } - _addr[num_elem] = out; - _len[num_elem] = crypt_len; - - os_memcpy(iv, iv_crypt, AES_BLOCK_SIZE); - os_memcpy(out, iv_crypt + AES_BLOCK_SIZE, crypt_len); - - iv[8] &= 0x7f; - iv[12] &= 0x7f; - - ret = aes_ctr_encrypt(k2, key_len, iv, out, crypt_len); - if (ret) - return ret; - - ret = aes_s2v(k1, key_len, num_elem + 1, _addr, _len, check); - if (ret) - return ret; - if (os_memcmp(check, iv_crypt, AES_BLOCK_SIZE) == 0) - return 0; - - return -1; -} +/* + * AES SIV (RFC 5297) + * Copyright (c) 2013 Cozybit, Inc. + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes.h" +#include "aes_wrap.h" +#include "aes_siv.h" + + +static const u8 zero[AES_BLOCK_SIZE]; + + +static void dbl(u8 *pad) +{ + int i, carry; + + carry = pad[0] & 0x80; + for (i = 0; i < AES_BLOCK_SIZE - 1; i++) + pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); + pad[AES_BLOCK_SIZE - 1] <<= 1; + if (carry) + pad[AES_BLOCK_SIZE - 1] ^= 0x87; +} + + +static void xor(u8 *a, const u8 *b) +{ + int i; + + for (i = 0; i < AES_BLOCK_SIZE; i++) + *a++ ^= *b++; +} + + +static void xorend(u8 *a, int alen, const u8 *b, int blen) +{ + int i; + + if (alen < blen) + return; + + for (i = 0; i < blen; i++) + a[alen - blen + i] ^= b[i]; +} + + +static void pad_block(u8 *pad, const u8 *addr, size_t len) +{ + os_memset(pad, 0, AES_BLOCK_SIZE); + os_memcpy(pad, addr, len); + + if (len < AES_BLOCK_SIZE) + pad[len] = 0x80; +} + + +static int aes_s2v(const u8 *key, size_t key_len, + size_t num_elem, const u8 *addr[], size_t *len, u8 *mac) +{ + u8 tmp[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE]; + u8 *buf = NULL; + int ret; + size_t i; + const u8 *data[1]; + size_t data_len[1]; + + if (!num_elem) { + os_memcpy(tmp, zero, sizeof(zero)); + tmp[AES_BLOCK_SIZE - 1] = 1; + data[0] = tmp; + data_len[0] = sizeof(tmp); + return omac1_aes_vector(key, key_len, 1, data, data_len, mac); + } + + data[0] = zero; + data_len[0] = sizeof(zero); + ret = omac1_aes_vector(key, key_len, 1, data, data_len, tmp); + if (ret) + return ret; + + for (i = 0; i < num_elem - 1; i++) { + ret = omac1_aes_vector(key, key_len, 1, &addr[i], &len[i], + tmp2); + if (ret) + return ret; + + dbl(tmp); + xor(tmp, tmp2); + } + if (len[i] >= AES_BLOCK_SIZE) { + buf = os_memdup(addr[i], len[i]); + if (!buf) + return -ENOMEM; + + xorend(buf, len[i], tmp, AES_BLOCK_SIZE); + data[0] = buf; + ret = omac1_aes_vector(key, key_len, 1, data, &len[i], mac); + bin_clear_free(buf, len[i]); + return ret; + } + + dbl(tmp); + pad_block(tmp2, addr[i], len[i]); + xor(tmp, tmp2); + + data[0] = tmp; + data_len[0] = sizeof(tmp); + return omac1_aes_vector(key, key_len, 1, data, data_len, mac); +} + + +int aes_siv_encrypt(const u8 *key, size_t key_len, + const u8 *pw, size_t pwlen, + size_t num_elem, const u8 *addr[], const size_t *len, + u8 *out) +{ + const u8 *_addr[6]; + size_t _len[6]; + const u8 *k1, *k2; + u8 v[AES_BLOCK_SIZE]; + size_t i; + u8 *iv, *crypt_pw; + + if (num_elem > ARRAY_SIZE(_addr) - 1 || + (key_len != 32 && key_len != 48 && key_len != 64)) + return -1; + + key_len /= 2; + k1 = key; + k2 = key + key_len; + + for (i = 0; i < num_elem; i++) { + _addr[i] = addr[i]; + _len[i] = len[i]; + } + _addr[num_elem] = pw; + _len[num_elem] = pwlen; + + if (aes_s2v(k1, key_len, num_elem + 1, _addr, _len, v)) + return -1; + + iv = out; + crypt_pw = out + AES_BLOCK_SIZE; + + os_memcpy(iv, v, AES_BLOCK_SIZE); + os_memcpy(crypt_pw, pw, pwlen); + + /* zero out 63rd and 31st bits of ctr (from right) */ + v[8] &= 0x7f; + v[12] &= 0x7f; + return aes_ctr_encrypt(k2, key_len, v, crypt_pw, pwlen); +} + + +int aes_siv_decrypt(const u8 *key, size_t key_len, + const u8 *iv_crypt, size_t iv_c_len, + size_t num_elem, const u8 *addr[], const size_t *len, + u8 *out) +{ + const u8 *_addr[6]; + size_t _len[6]; + const u8 *k1, *k2; + size_t crypt_len; + size_t i; + int ret; + u8 iv[AES_BLOCK_SIZE]; + u8 check[AES_BLOCK_SIZE]; + + if (iv_c_len < AES_BLOCK_SIZE || num_elem > ARRAY_SIZE(_addr) - 1 || + (key_len != 32 && key_len != 48 && key_len != 64)) + return -1; + crypt_len = iv_c_len - AES_BLOCK_SIZE; + key_len /= 2; + k1 = key; + k2 = key + key_len; + + for (i = 0; i < num_elem; i++) { + _addr[i] = addr[i]; + _len[i] = len[i]; + } + _addr[num_elem] = out; + _len[num_elem] = crypt_len; + + os_memcpy(iv, iv_crypt, AES_BLOCK_SIZE); + os_memcpy(out, iv_crypt + AES_BLOCK_SIZE, crypt_len); + + iv[8] &= 0x7f; + iv[12] &= 0x7f; + + ret = aes_ctr_encrypt(k2, key_len, iv, out, crypt_len); + if (ret) + return ret; + + ret = aes_s2v(k1, key_len, num_elem + 1, _addr, _len, check); + if (ret) + return ret; + if (os_memcmp(check, iv_crypt, AES_BLOCK_SIZE) == 0) + return 0; + + return -1; +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes.h index 7a02050b7409..a391aa850873 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes.h @@ -1,22 +1,22 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * AES functions - * Copyright (c) 2003-2006, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#ifndef AES_H -#define AES_H - -#define AES_BLOCK_SIZE 16 - -void * aes_encrypt_init(const u8 *key, size_t len); -int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt); -void aes_encrypt_deinit(void *ctx); -void * aes_decrypt_init(const u8 *key, size_t len); -int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain); -void aes_decrypt_deinit(void *ctx); - -#endif /* AES_H */ +/* + * AES functions + * Copyright (c) 2003-2006, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef AES_H +#define AES_H + +#define AES_BLOCK_SIZE 16 + +void * aes_encrypt_init(const u8 *key, size_t len); +int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt); +void aes_encrypt_deinit(void *ctx); +void * aes_decrypt_init(const u8 *key, size_t len); +int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain); +void aes_decrypt_deinit(void *ctx); + +#endif /* AES_H */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes_i.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes_i.h index 12bda601a080..bfb74235f0e5 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes_i.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes_i.h @@ -1,126 +1,126 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * AES (Rijndael) cipher - * Copyright (c) 2003-2012, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#ifndef AES_I_H -#define AES_I_H - -#include "aes.h" - -/* #define FULL_UNROLL */ -#define AES_SMALL_TABLES - -extern const u32 Te0[256]; -extern const u32 Te1[256]; -extern const u32 Te2[256]; -extern const u32 Te3[256]; -extern const u32 Te4[256]; -extern const u32 Td0[256]; -extern const u32 Td1[256]; -extern const u32 Td2[256]; -extern const u32 Td3[256]; -extern const u32 Td4[256]; -extern const u32 rcon[10]; -extern const u8 Td4s[256]; -extern const u8 rcons[10]; - -#ifndef AES_SMALL_TABLES - -#define RCON(i) rcon[(i)] - -#define TE0(i) Te0[((i) >> 24) & 0xff] -#define TE1(i) Te1[((i) >> 16) & 0xff] -#define TE2(i) Te2[((i) >> 8) & 0xff] -#define TE3(i) Te3[(i) & 0xff] -#define TE41(i) (Te4[((i) >> 24) & 0xff] & 0xff000000) -#define TE42(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000) -#define TE43(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00) -#define TE44(i) (Te4[(i) & 0xff] & 0x000000ff) -#define TE421(i) (Te4[((i) >> 16) & 0xff] & 0xff000000) -#define TE432(i) (Te4[((i) >> 8) & 0xff] & 0x00ff0000) -#define TE443(i) (Te4[(i) & 0xff] & 0x0000ff00) -#define TE414(i) (Te4[((i) >> 24) & 0xff] & 0x000000ff) -#define TE411(i) (Te4[((i) >> 24) & 0xff] & 0xff000000) -#define TE422(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000) -#define TE433(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00) -#define TE444(i) (Te4[(i) & 0xff] & 0x000000ff) -#define TE4(i) (Te4[(i)] & 0x000000ff) - -#define TD0(i) Td0[((i) >> 24) & 0xff] -#define TD1(i) Td1[((i) >> 16) & 0xff] -#define TD2(i) Td2[((i) >> 8) & 0xff] -#define TD3(i) Td3[(i) & 0xff] -#define TD41(i) (Td4[((i) >> 24) & 0xff] & 0xff000000) -#define TD42(i) (Td4[((i) >> 16) & 0xff] & 0x00ff0000) -#define TD43(i) (Td4[((i) >> 8) & 0xff] & 0x0000ff00) -#define TD44(i) (Td4[(i) & 0xff] & 0x000000ff) -#define TD0_(i) Td0[(i) & 0xff] -#define TD1_(i) Td1[(i) & 0xff] -#define TD2_(i) Td2[(i) & 0xff] -#define TD3_(i) Td3[(i) & 0xff] - -#else /* AES_SMALL_TABLES */ - -#define RCON(i) (rcons[(i)] << 24) - -static inline u32 rotr(u32 val, int bits) -{ - return (val >> bits) | (val << (32 - bits)); -} - -#define TE0(i) Te0[((i) >> 24) & 0xff] -#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8) -#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16) -#define TE3(i) rotr(Te0[(i) & 0xff], 24) -#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000) -#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000) -#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00) -#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff) -#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000) -#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000) -#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00) -#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff) -#define TE411(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000) -#define TE422(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000) -#define TE433(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00) -#define TE444(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff) -#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff) - -#define TD0(i) Td0[((i) >> 24) & 0xff] -#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8) -#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16) -#define TD3(i) rotr(Td0[(i) & 0xff], 24) -#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24) -#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16) -#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8) -#define TD44(i) (Td4s[(i) & 0xff]) -#define TD0_(i) Td0[(i) & 0xff] -#define TD1_(i) rotr(Td0[(i) & 0xff], 8) -#define TD2_(i) rotr(Td0[(i) & 0xff], 16) -#define TD3_(i) rotr(Td0[(i) & 0xff], 24) - -#endif /* AES_SMALL_TABLES */ - -#ifdef _MSC_VER -#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) -#define GETU32(p) SWAP(*((u32 *)(p))) -#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } -#else -#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \ -((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) -#define PUTU32(ct, st) { \ -(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \ -(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } -#endif - -#define AES_PRIV_SIZE (4 * 4 * 15 + 4) -#define AES_PRIV_NR_POS (4 * 15) - -int rijndaelKeySetupEnc(u32 rk[], const u8 cipherKey[], int keyBits); - -#endif /* AES_I_H */ +/* + * AES (Rijndael) cipher + * Copyright (c) 2003-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef AES_I_H +#define AES_I_H + +#include "aes.h" + +/* #define FULL_UNROLL */ +#define AES_SMALL_TABLES + +extern const u32 Te0[256]; +extern const u32 Te1[256]; +extern const u32 Te2[256]; +extern const u32 Te3[256]; +extern const u32 Te4[256]; +extern const u32 Td0[256]; +extern const u32 Td1[256]; +extern const u32 Td2[256]; +extern const u32 Td3[256]; +extern const u32 Td4[256]; +extern const u32 rcon[10]; +extern const u8 Td4s[256]; +extern const u8 rcons[10]; + +#ifndef AES_SMALL_TABLES + +#define RCON(i) rcon[(i)] + +#define TE0(i) Te0[((i) >> 24) & 0xff] +#define TE1(i) Te1[((i) >> 16) & 0xff] +#define TE2(i) Te2[((i) >> 8) & 0xff] +#define TE3(i) Te3[(i) & 0xff] +#define TE41(i) (Te4[((i) >> 24) & 0xff] & 0xff000000) +#define TE42(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE43(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE44(i) (Te4[(i) & 0xff] & 0x000000ff) +#define TE421(i) (Te4[((i) >> 16) & 0xff] & 0xff000000) +#define TE432(i) (Te4[((i) >> 8) & 0xff] & 0x00ff0000) +#define TE443(i) (Te4[(i) & 0xff] & 0x0000ff00) +#define TE414(i) (Te4[((i) >> 24) & 0xff] & 0x000000ff) +#define TE411(i) (Te4[((i) >> 24) & 0xff] & 0xff000000) +#define TE422(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE433(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE444(i) (Te4[(i) & 0xff] & 0x000000ff) +#define TE4(i) (Te4[(i)] & 0x000000ff) + +#define TD0(i) Td0[((i) >> 24) & 0xff] +#define TD1(i) Td1[((i) >> 16) & 0xff] +#define TD2(i) Td2[((i) >> 8) & 0xff] +#define TD3(i) Td3[(i) & 0xff] +#define TD41(i) (Td4[((i) >> 24) & 0xff] & 0xff000000) +#define TD42(i) (Td4[((i) >> 16) & 0xff] & 0x00ff0000) +#define TD43(i) (Td4[((i) >> 8) & 0xff] & 0x0000ff00) +#define TD44(i) (Td4[(i) & 0xff] & 0x000000ff) +#define TD0_(i) Td0[(i) & 0xff] +#define TD1_(i) Td1[(i) & 0xff] +#define TD2_(i) Td2[(i) & 0xff] +#define TD3_(i) Td3[(i) & 0xff] + +#else /* AES_SMALL_TABLES */ + +#define RCON(i) (rcons[(i)] << 24) + +static inline u32 rotr(u32 val, int bits) +{ + return (val >> bits) | (val << (32 - bits)); +} + +#define TE0(i) Te0[((i) >> 24) & 0xff] +#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8) +#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16) +#define TE3(i) rotr(Te0[(i) & 0xff], 24) +#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000) +#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff) +#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000) +#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000) +#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00) +#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff) +#define TE411(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000) +#define TE422(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE433(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE444(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff) +#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff) + +#define TD0(i) Td0[((i) >> 24) & 0xff] +#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8) +#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16) +#define TD3(i) rotr(Td0[(i) & 0xff], 24) +#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24) +#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16) +#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8) +#define TD44(i) (Td4s[(i) & 0xff]) +#define TD0_(i) Td0[(i) & 0xff] +#define TD1_(i) rotr(Td0[(i) & 0xff], 8) +#define TD2_(i) rotr(Td0[(i) & 0xff], 16) +#define TD3_(i) rotr(Td0[(i) & 0xff], 24) + +#endif /* AES_SMALL_TABLES */ + +#ifdef _MSC_VER +#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) +#define GETU32(p) SWAP(*((u32 *)(p))) +#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } +#else +#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \ +((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) +#define PUTU32(ct, st) { \ +(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \ +(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } +#endif + +#define AES_PRIV_SIZE (4 * 4 * 15 + 4) +#define AES_PRIV_NR_POS (4 * 15) + +int rijndaelKeySetupEnc(u32 rk[], const u8 cipherKey[], int keyBits); + +#endif /* AES_I_H */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes_siv.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes_siv.h index a14db1f04394..6ee69f2615e3 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes_siv.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes_siv.h @@ -1,22 +1,22 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * AES SIV (RFC 5297) - * Copyright (c) 2013 Cozybit, Inc. - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#ifndef AES_SIV_H -#define AES_SIV_H - -int aes_siv_encrypt(const u8 *key, size_t key_len, - const u8 *pw, size_t pwlen, - size_t num_elem, const u8 *addr[], const size_t *len, - u8 *out); -int aes_siv_decrypt(const u8 *key, size_t key_len, - const u8 *iv_crypt, size_t iv_c_len, - size_t num_elem, const u8 *addr[], const size_t *len, - u8 *out); - -#endif /* AES_SIV_H */ +/* + * AES SIV (RFC 5297) + * Copyright (c) 2013 Cozybit, Inc. + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef AES_SIV_H +#define AES_SIV_H + +int aes_siv_encrypt(const u8 *key, size_t key_len, + const u8 *pw, size_t pwlen, + size_t num_elem, const u8 *addr[], const size_t *len, + u8 *out); +int aes_siv_decrypt(const u8 *key, size_t key_len, + const u8 *iv_crypt, size_t iv_c_len, + size_t num_elem, const u8 *addr[], const size_t *len, + u8 *out); + +#endif /* AES_SIV_H */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes_wrap.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes_wrap.h index 8477870cbbb0..47b6bf18e36f 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes_wrap.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/aes_wrap.h @@ -1,74 +1,74 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * AES-based functions - * - * - AES Key Wrap Algorithm (RFC3394) - * - One-Key CBC MAC (OMAC1) hash with AES-128 and AES-256 - * - AES-128/192/256 CTR mode encryption - * - AES-128 EAX mode encryption/decryption - * - AES-128 CBC - * - AES-GCM - * - AES-CCM - * - * Copyright (c) 2003-2012, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#ifndef AES_WRAP_H -#define AES_WRAP_H - -int __must_check aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, - u8 *cipher); -int __must_check aes_unwrap(const u8 *kek, size_t kek_len, int n, - const u8 *cipher, u8 *plain); -int __must_check omac1_aes_vector(const u8 *key, size_t key_len, - size_t num_elem, const u8 *addr[], - const size_t *len, u8 *mac); -int __must_check omac1_aes_128_vector(const u8 *key, size_t num_elem, - const u8 *addr[], const size_t *len, - u8 *mac); -int __must_check omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, - u8 *mac); -int __must_check omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, - u8 *mac); -int __must_check aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out); -int __must_check aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, - u8 *data, size_t data_len); -int __must_check aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, - u8 *data, size_t data_len); -int __must_check aes_128_eax_encrypt(const u8 *key, - const u8 *nonce, size_t nonce_len, - const u8 *hdr, size_t hdr_len, - u8 *data, size_t data_len, u8 *tag); -int __must_check aes_128_eax_decrypt(const u8 *key, - const u8 *nonce, size_t nonce_len, - const u8 *hdr, size_t hdr_len, - u8 *data, size_t data_len, const u8 *tag); -int __must_check aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, - size_t data_len); -int __must_check aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, - size_t data_len); -int __must_check aes_gcm_ae(const u8 *key, size_t key_len, - const u8 *iv, size_t iv_len, - const u8 *plain, size_t plain_len, - const u8 *aad, size_t aad_len, - u8 *crypt, u8 *tag); -int __must_check aes_gcm_ad(const u8 *key, size_t key_len, - const u8 *iv, size_t iv_len, - const u8 *crypt, size_t crypt_len, - const u8 *aad, size_t aad_len, const u8 *tag, - u8 *plain); -int __must_check aes_gmac(const u8 *key, size_t key_len, - const u8 *iv, size_t iv_len, - const u8 *aad, size_t aad_len, u8 *tag); -int __must_check aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce, - size_t M, const u8 *plain, size_t plain_len, - const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth); -int __must_check aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, - size_t M, const u8 *crypt, size_t crypt_len, - const u8 *aad, size_t aad_len, const u8 *auth, - u8 *plain); - -#endif /* AES_WRAP_H */ +/* + * AES-based functions + * + * - AES Key Wrap Algorithm (RFC3394) + * - One-Key CBC MAC (OMAC1) hash with AES-128 and AES-256 + * - AES-128/192/256 CTR mode encryption + * - AES-128 EAX mode encryption/decryption + * - AES-128 CBC + * - AES-GCM + * - AES-CCM + * + * Copyright (c) 2003-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef AES_WRAP_H +#define AES_WRAP_H + +int __must_check aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, + u8 *cipher); +int __must_check aes_unwrap(const u8 *kek, size_t kek_len, int n, + const u8 *cipher, u8 *plain); +int __must_check omac1_aes_vector(const u8 *key, size_t key_len, + size_t num_elem, const u8 *addr[], + const size_t *len, u8 *mac); +int __must_check omac1_aes_128_vector(const u8 *key, size_t num_elem, + const u8 *addr[], const size_t *len, + u8 *mac); +int __must_check omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, + u8 *mac); +int __must_check omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, + u8 *mac); +int __must_check aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out); +int __must_check aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, + u8 *data, size_t data_len); +int __must_check aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, + u8 *data, size_t data_len); +int __must_check aes_128_eax_encrypt(const u8 *key, + const u8 *nonce, size_t nonce_len, + const u8 *hdr, size_t hdr_len, + u8 *data, size_t data_len, u8 *tag); +int __must_check aes_128_eax_decrypt(const u8 *key, + const u8 *nonce, size_t nonce_len, + const u8 *hdr, size_t hdr_len, + u8 *data, size_t data_len, const u8 *tag); +int __must_check aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, + size_t data_len); +int __must_check aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, + size_t data_len); +int __must_check aes_gcm_ae(const u8 *key, size_t key_len, + const u8 *iv, size_t iv_len, + const u8 *plain, size_t plain_len, + const u8 *aad, size_t aad_len, + u8 *crypt, u8 *tag); +int __must_check aes_gcm_ad(const u8 *key, size_t key_len, + const u8 *iv, size_t iv_len, + const u8 *crypt, size_t crypt_len, + const u8 *aad, size_t aad_len, const u8 *tag, + u8 *plain); +int __must_check aes_gmac(const u8 *key, size_t key_len, + const u8 *iv, size_t iv_len, + const u8 *aad, size_t aad_len, u8 *tag); +int __must_check aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce, + size_t M, const u8 *plain, size_t plain_len, + const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth); +int __must_check aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, + size_t M, const u8 *crypt, size_t crypt_len, + const u8 *aad, size_t aad_len, const u8 *auth, + u8 *plain); + +#endif /* AES_WRAP_H */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/ccmp.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/ccmp.c index 021b746b7e9c..b1a648dae4b3 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/ccmp.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/ccmp.c @@ -1,385 +1,385 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * CTR with CBC-MAC Protocol (CCMP) - * Copyright (c) 2010-2012, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#include "rtw_crypto_wrap.h" - -#include "aes.h" -#include "aes_wrap.h" -#include "wlancrypto_wrap.h" - - - -static void ccmp_aad_nonce(const struct ieee80211_hdr *hdr, const u8 *data, - u8 *aad, size_t *aad_len, u8 *nonce) -{ - u16 fc, stype, seq; - int qos = 0, addr4 = 0; - u8 *pos; - - nonce[0] = 0; - - fc = le_to_host16(hdr->frame_control); - stype = WLAN_FC_GET_STYPE(fc); - if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == - (WLAN_FC_TODS | WLAN_FC_FROMDS)) - addr4 = 1; - - if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) { - fc &= ~0x0070; /* Mask subtype bits */ - if (stype & WLAN_FC_STYPE_QOS_DATA) { - const u8 *qc; - qos = 1; - fc &= ~WLAN_FC_ORDER; - qc = (const u8 *)hdr + 24; - if (addr4) - qc += ETH_ALEN; - nonce[0] = qc[0] & 0x0f; - } - } else if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT) - nonce[0] |= 0x10; /* Management */ - - fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA); - fc |= WLAN_FC_ISWEP; - WPA_PUT_LE16(aad, fc); - pos = aad + 2; - os_memcpy(pos, hdr->addr1, 3 * ETH_ALEN); - pos += 3 * ETH_ALEN; - seq = le_to_host16(hdr->seq_ctrl); - seq &= ~0xfff0; /* Mask Seq#; do not modify Frag# */ - WPA_PUT_LE16(pos, seq); - pos += 2; - - os_memcpy(pos, (u8 *)hdr + 24, addr4 * ETH_ALEN + qos * 2); - pos += addr4 * ETH_ALEN; - if (qos) { - pos[0] &= ~0x70; - if (1 /* FIX: either device has SPP A-MSDU Capab = 0 */) - pos[0] &= ~0x80; - pos++; - *pos++ = 0x00; - } - - *aad_len = pos - aad; - - os_memcpy(nonce + 1, hdr->addr2, ETH_ALEN); - nonce[7] = data[7]; /* PN5 */ - nonce[8] = data[6]; /* PN4 */ - nonce[9] = data[5]; /* PN3 */ - nonce[10] = data[4]; /* PN2 */ - nonce[11] = data[1]; /* PN1 */ - nonce[12] = data[0]; /* PN0 */ -} - - -static void ccmp_aad_nonce_pv1(const u8 *hdr, const u8 *a1, const u8 *a2, - const u8 *a3, const u8 *pn, - u8 *aad, size_t *aad_len, u8 *nonce) -{ - u16 fc, type; - u8 *pos; - - nonce[0] = BIT(5); /* PV1 */ - /* TODO: Priority for QMF; 0 is used for Data frames */ - - fc = WPA_GET_LE16(hdr); - type = (fc & (BIT(2) | BIT(3) | BIT(4))) >> 2; - - if (type == 1) - nonce[0] |= 0x10; /* Management */ - - fc &= ~(BIT(10) | BIT(11) | BIT(13) | BIT(14) | BIT(15)); - fc |= BIT(12); - WPA_PUT_LE16(aad, fc); - pos = aad + 2; - if (type == 0 || type == 3) { - const u8 *sc; - - os_memcpy(pos, a1, ETH_ALEN); - pos += ETH_ALEN; - os_memcpy(pos, a2, ETH_ALEN); - pos += ETH_ALEN; - - if (type == 0) { - /* Either A1 or A2 contains SID */ - sc = hdr + 2 + 2 + ETH_ALEN; - } else { - /* Both A1 and A2 contain full addresses */ - sc = hdr + 2 + 2 * ETH_ALEN; - } - /* SC with Sequence Number subfield (bits 4-15 of the Sequence - * Control field) masked to 0. */ - *pos++ = *sc & 0x0f; - *pos++ = 0; - - if (a3) { - os_memcpy(pos, a3, ETH_ALEN); - pos += ETH_ALEN; - } - } - - *aad_len = pos - aad; - - os_memcpy(nonce + 1, a2, ETH_ALEN); - nonce[7] = pn[5]; /* PN5 */ - nonce[8] = pn[4]; /* PN4 */ - nonce[9] = pn[3]; /* PN3 */ - nonce[10] = pn[2]; /* PN2 */ - nonce[11] = pn[1]; /* PN1 */ - nonce[12] = pn[0]; /* PN0 */ -} - - -u8 * ccmp_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr, - const u8 *data, size_t data_len, size_t *decrypted_len) -{ - u8 aad[30], nonce[13]; - size_t aad_len; - size_t mlen; - u8 *plain; - - if (data_len < 8 + 8) - return NULL; - - plain = os_malloc(data_len + AES_BLOCK_SIZE); - if (plain == NULL) - return NULL; - - mlen = data_len - 8 - 8; - - os_memset(aad, 0, sizeof(aad)); - ccmp_aad_nonce(hdr, data, aad, &aad_len, nonce); - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP AAD", aad, aad_len); - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP nonce", nonce, 13); - - if (aes_ccm_ad(tk, 16, nonce, 8, data + 8, mlen, aad, aad_len, - data + 8 + mlen, plain) < 0) { - u16 seq_ctrl = le_to_host16(hdr->seq_ctrl); - wpa_printf(_MSG_INFO_, "Invalid CCMP MIC in frame: A1=" MACSTR - " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u", - MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), - MAC2STR(hdr->addr3), - WLAN_GET_SEQ_SEQ(seq_ctrl), - WLAN_GET_SEQ_FRAG(seq_ctrl)); - rtw_mfree(plain, data_len + AES_BLOCK_SIZE); - return NULL; - } - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP decrypted", plain, mlen); - - *decrypted_len = mlen; - return plain; -} - - -void ccmp_get_pn(u8 *pn, const u8 *data) -{ - pn[0] = data[7]; /* PN5 */ - pn[1] = data[6]; /* PN4 */ - pn[2] = data[5]; /* PN3 */ - pn[3] = data[4]; /* PN2 */ - pn[4] = data[1]; /* PN1 */ - pn[5] = data[0]; /* PN0 */ -} - - -u8 * ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos, - u8 *pn, int keyid, size_t *encrypted_len) -{ - u8 aad[30], nonce[13]; - size_t aad_len, plen; - u8 *crypt, *pos, *pdata; - struct ieee80211_hdr *hdr; - - if (len < hdrlen || hdrlen < 24) - return NULL; - plen = len - hdrlen; - - crypt = os_malloc(hdrlen + 8 + plen + 8 + AES_BLOCK_SIZE); - if (crypt == NULL) - return NULL; - - if (pn == NULL) { - os_memcpy(crypt, frame, hdrlen + 8); - hdr = (struct ieee80211_hdr *) crypt; - hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); - pos = crypt + hdrlen + 8; - pdata = frame + hdrlen + 8; - } else { - os_memcpy(crypt, frame, hdrlen); - hdr = (struct ieee80211_hdr *) crypt; - hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); - pos = crypt + hdrlen; - *pos++ = pn[5]; /* PN0 */ - *pos++ = pn[4]; /* PN1 */ - *pos++ = 0x00; /* Rsvd */ - *pos++ = 0x20 | (keyid << 6); - *pos++ = pn[3]; /* PN2 */ - *pos++ = pn[2]; /* PN3 */ - *pos++ = pn[1]; /* PN4 */ - *pos++ = pn[0]; /* PN5 */ - pdata = frame + hdrlen; - } - - os_memset(aad, 0, sizeof(aad)); - ccmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce); - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP AAD", aad, aad_len); - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP nonce", nonce, 13); - - if (aes_ccm_ae(tk, 16, nonce, 8, pdata, plen, aad, aad_len, - pos, pos + plen) < 0) { - rtw_mfree(crypt, hdrlen + 8 + plen + 8 + AES_BLOCK_SIZE); - return NULL; - } - - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP encrypted", crypt + hdrlen + 8, plen); - - *encrypted_len = hdrlen + 8 + plen + 8; - - return crypt; -} - - -u8 * ccmp_encrypt_pv1(const u8 *tk, const u8 *a1, const u8 *a2, const u8 *a3, - const u8 *frame, size_t len, - size_t hdrlen, const u8 *pn, int keyid, - size_t *encrypted_len) -{ - u8 aad[24], nonce[13]; - size_t aad_len, plen; - u8 *crypt, *pos; - struct ieee80211_hdr *hdr; - - if (len < hdrlen || hdrlen < 12) - return NULL; - plen = len - hdrlen; - - crypt = os_malloc(hdrlen + plen + 8 + AES_BLOCK_SIZE); - if (crypt == NULL) - return NULL; - - os_memcpy(crypt, frame, hdrlen); - hdr = (struct ieee80211_hdr *) crypt; - hdr->frame_control |= host_to_le16(BIT(12)); /* Protected Frame */ - pos = crypt + hdrlen; - - os_memset(aad, 0, sizeof(aad)); - ccmp_aad_nonce_pv1(crypt, a1, a2, a3, pn, aad, &aad_len, nonce); - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP AAD", aad, aad_len); - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP nonce", nonce, sizeof(nonce)); - - if (aes_ccm_ae(tk, 16, nonce, 8, frame + hdrlen, plen, aad, aad_len, - pos, pos + plen) < 0) { - rtw_mfree(crypt, hdrlen + plen + 8 + AES_BLOCK_SIZE); - return NULL; - } - - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP encrypted", crypt + hdrlen, plen); - - *encrypted_len = hdrlen + plen + 8; - - return crypt; -} - - -u8 * ccmp_256_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr, - const u8 *data, size_t data_len, size_t *decrypted_len) -{ - u8 aad[30], nonce[13]; - size_t aad_len; - size_t mlen; - u8 *plain; - - if (data_len < 8 + 16) - return NULL; - - plain = os_malloc(data_len + AES_BLOCK_SIZE); - if (plain == NULL) - return NULL; - - mlen = data_len - 8 - 16; - - os_memset(aad, 0, sizeof(aad)); - ccmp_aad_nonce(hdr, data, aad, &aad_len, nonce); - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 AAD", aad, aad_len); - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 nonce", nonce, 13); - - if (aes_ccm_ad(tk, 32, nonce, 16, data + 8, mlen, aad, aad_len, - data + 8 + mlen, plain) < 0) { - u16 seq_ctrl = le_to_host16(hdr->seq_ctrl); - wpa_printf(_MSG_INFO_, "Invalid CCMP-256 MIC in frame: A1=" MACSTR - " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u", - MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), - MAC2STR(hdr->addr3), - WLAN_GET_SEQ_SEQ(seq_ctrl), - WLAN_GET_SEQ_FRAG(seq_ctrl)); - rtw_mfree(plain, data_len + AES_BLOCK_SIZE); - return NULL; - } - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 decrypted", plain, mlen); - - *decrypted_len = mlen; - return plain; -} - - -u8 * ccmp_256_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, - u8 *qos, u8 *pn, int keyid, size_t *encrypted_len) -{ - u8 aad[30], nonce[13]; - size_t aad_len, plen; - u8 *crypt, *pos, *pdata; - struct ieee80211_hdr *hdr; - - if (len < hdrlen || hdrlen < 24) - return NULL; - plen = len - hdrlen; - - crypt = os_malloc(hdrlen + 8 + plen + 16 + AES_BLOCK_SIZE); - if (crypt == NULL) - return NULL; - - if (pn == NULL) { - os_memcpy(crypt, frame, hdrlen + 8); - hdr = (struct ieee80211_hdr *) crypt; - hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); - pos = crypt + hdrlen + 8; - pdata = frame + hdrlen + 8; - } else { - os_memcpy(crypt, frame, hdrlen); - hdr = (struct ieee80211_hdr *) crypt; - hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); - pos = crypt + hdrlen; - *pos++ = pn[5]; /* PN0 */ - *pos++ = pn[4]; /* PN1 */ - *pos++ = 0x00; /* Rsvd */ - *pos++ = 0x20 | (keyid << 6); - *pos++ = pn[3]; /* PN2 */ - *pos++ = pn[2]; /* PN3 */ - *pos++ = pn[1]; /* PN4 */ - *pos++ = pn[0]; /* PN5 */ - pdata = frame + hdrlen; - } - - os_memset(aad, 0, sizeof(aad)); - ccmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce); - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 AAD", aad, aad_len); - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 nonce", nonce, 13); - - if (aes_ccm_ae(tk, 32, nonce, 16, pdata, plen, aad, aad_len, - pos, pos + plen) < 0) { - rtw_mfree(crypt, hdrlen + 8 + plen + 16 + AES_BLOCK_SIZE); - return NULL; - } - - wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 encrypted", crypt + hdrlen + 8, - plen); - - *encrypted_len = hdrlen + 8 + plen + 16; - - return crypt; -} +/* + * CTR with CBC-MAC Protocol (CCMP) + * Copyright (c) 2010-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes.h" +#include "aes_wrap.h" +#include "wlancrypto_wrap.h" + + + +static void ccmp_aad_nonce(const struct ieee80211_hdr *hdr, const u8 *data, + u8 *aad, size_t *aad_len, u8 *nonce) +{ + u16 fc, stype, seq; + int qos = 0, addr4 = 0; + u8 *pos; + + nonce[0] = 0; + + fc = le_to_host16(hdr->frame_control); + stype = WLAN_FC_GET_STYPE(fc); + if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == + (WLAN_FC_TODS | WLAN_FC_FROMDS)) + addr4 = 1; + + if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) { + fc &= ~0x0070; /* Mask subtype bits */ + if (stype & WLAN_FC_STYPE_QOS_DATA) { + const u8 *qc; + qos = 1; + fc &= ~WLAN_FC_ORDER; + qc = (const u8 *)hdr + 24; + if (addr4) + qc += ETH_ALEN; + nonce[0] = qc[0] & 0x0f; + } + } else if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT) + nonce[0] |= 0x10; /* Management */ + + fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA); + fc |= WLAN_FC_ISWEP; + WPA_PUT_LE16(aad, fc); + pos = aad + 2; + os_memcpy(pos, GetAddr1Ptr((u8 *)hdr), 3 * ETH_ALEN); + pos += 3 * ETH_ALEN; + seq = le_to_host16(hdr->seq_ctrl); + seq &= ~0xfff0; /* Mask Seq#; do not modify Frag# */ + WPA_PUT_LE16(pos, seq); + pos += 2; + + os_memcpy(pos, (u8 *)hdr + 24, addr4 * ETH_ALEN + qos * 2); + pos += addr4 * ETH_ALEN; + if (qos) { + pos[0] &= ~0x70; + if (1 /* FIX: either device has SPP A-MSDU Capab = 0 */) + pos[0] &= ~0x80; + pos++; + *pos++ = 0x00; + } + + *aad_len = pos - aad; + + os_memcpy(nonce + 1, hdr->addr2, ETH_ALEN); + nonce[7] = data[7]; /* PN5 */ + nonce[8] = data[6]; /* PN4 */ + nonce[9] = data[5]; /* PN3 */ + nonce[10] = data[4]; /* PN2 */ + nonce[11] = data[1]; /* PN1 */ + nonce[12] = data[0]; /* PN0 */ +} + + +static void ccmp_aad_nonce_pv1(const u8 *hdr, const u8 *a1, const u8 *a2, + const u8 *a3, const u8 *pn, + u8 *aad, size_t *aad_len, u8 *nonce) +{ + u16 fc, type; + u8 *pos; + + nonce[0] = BIT(5); /* PV1 */ + /* TODO: Priority for QMF; 0 is used for Data frames */ + + fc = WPA_GET_LE16(hdr); + type = (fc & (BIT(2) | BIT(3) | BIT(4))) >> 2; + + if (type == 1) + nonce[0] |= 0x10; /* Management */ + + fc &= ~(BIT(10) | BIT(11) | BIT(13) | BIT(14) | BIT(15)); + fc |= BIT(12); + WPA_PUT_LE16(aad, fc); + pos = aad + 2; + if (type == 0 || type == 3) { + const u8 *sc; + + os_memcpy(pos, a1, ETH_ALEN); + pos += ETH_ALEN; + os_memcpy(pos, a2, ETH_ALEN); + pos += ETH_ALEN; + + if (type == 0) { + /* Either A1 or A2 contains SID */ + sc = hdr + 2 + 2 + ETH_ALEN; + } else { + /* Both A1 and A2 contain full addresses */ + sc = hdr + 2 + 2 * ETH_ALEN; + } + /* SC with Sequence Number subfield (bits 4-15 of the Sequence + * Control field) masked to 0. */ + *pos++ = *sc & 0x0f; + *pos++ = 0; + + if (a3) { + os_memcpy(pos, a3, ETH_ALEN); + pos += ETH_ALEN; + } + } + + *aad_len = pos - aad; + + os_memcpy(nonce + 1, a2, ETH_ALEN); + nonce[7] = pn[5]; /* PN5 */ + nonce[8] = pn[4]; /* PN4 */ + nonce[9] = pn[3]; /* PN3 */ + nonce[10] = pn[2]; /* PN2 */ + nonce[11] = pn[1]; /* PN1 */ + nonce[12] = pn[0]; /* PN0 */ +} + + +u8 * ccmp_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr, + const u8 *data, size_t data_len, size_t *decrypted_len) +{ + u8 aad[30], nonce[13]; + size_t aad_len; + size_t mlen; + u8 *plain; + + if (data_len < 8 + 8) + return NULL; + + plain = os_malloc(data_len + AES_BLOCK_SIZE); + if (plain == NULL) + return NULL; + + mlen = data_len - 8 - 8; + + os_memset(aad, 0, sizeof(aad)); + ccmp_aad_nonce(hdr, data, aad, &aad_len, nonce); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP AAD", aad, aad_len); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP nonce", nonce, 13); + + if (aes_ccm_ad(tk, 16, nonce, 8, data + 8, mlen, aad, aad_len, + data + 8 + mlen, plain) < 0) { + u16 seq_ctrl = le_to_host16(hdr->seq_ctrl); + wpa_printf(_MSG_INFO_, "Invalid CCMP MIC in frame: A1=" MACSTR + " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u", + MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), + MAC2STR(hdr->addr3), + WLAN_GET_SEQ_SEQ(seq_ctrl), + WLAN_GET_SEQ_FRAG(seq_ctrl)); + rtw_mfree(plain, data_len + AES_BLOCK_SIZE); + return NULL; + } + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP decrypted", plain, mlen); + + *decrypted_len = mlen; + return plain; +} + + +void ccmp_get_pn(u8 *pn, const u8 *data) +{ + pn[0] = data[7]; /* PN5 */ + pn[1] = data[6]; /* PN4 */ + pn[2] = data[5]; /* PN3 */ + pn[3] = data[4]; /* PN2 */ + pn[4] = data[1]; /* PN1 */ + pn[5] = data[0]; /* PN0 */ +} + + +u8 * ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos, + u8 *pn, int keyid, size_t *encrypted_len) +{ + u8 aad[30], nonce[13]; + size_t aad_len, plen; + u8 *crypt, *pos, *pdata; + struct ieee80211_hdr *hdr; + + if (len < hdrlen || hdrlen < 24) + return NULL; + plen = len - hdrlen; + + crypt = os_malloc(hdrlen + 8 + plen + 8 + AES_BLOCK_SIZE); + if (crypt == NULL) + return NULL; + + if (pn == NULL) { + os_memcpy(crypt, frame, hdrlen + 8); + hdr = (struct ieee80211_hdr *) crypt; + hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); + pos = crypt + hdrlen + 8; + pdata = frame + hdrlen + 8; + } else { + os_memcpy(crypt, frame, hdrlen); + hdr = (struct ieee80211_hdr *) crypt; + hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); + pos = crypt + hdrlen; + *pos++ = pn[5]; /* PN0 */ + *pos++ = pn[4]; /* PN1 */ + *pos++ = 0x00; /* Rsvd */ + *pos++ = 0x20 | (keyid << 6); + *pos++ = pn[3]; /* PN2 */ + *pos++ = pn[2]; /* PN3 */ + *pos++ = pn[1]; /* PN4 */ + *pos++ = pn[0]; /* PN5 */ + pdata = frame + hdrlen; + } + + os_memset(aad, 0, sizeof(aad)); + ccmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP AAD", aad, aad_len); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP nonce", nonce, 13); + + if (aes_ccm_ae(tk, 16, nonce, 8, pdata, plen, aad, aad_len, + pos, pos + plen) < 0) { + rtw_mfree(crypt, hdrlen + 8 + plen + 8 + AES_BLOCK_SIZE); + return NULL; + } + + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP encrypted", crypt + hdrlen + 8, plen); + + *encrypted_len = hdrlen + 8 + plen + 8; + + return crypt; +} + + +u8 * ccmp_encrypt_pv1(const u8 *tk, const u8 *a1, const u8 *a2, const u8 *a3, + const u8 *frame, size_t len, + size_t hdrlen, const u8 *pn, int keyid, + size_t *encrypted_len) +{ + u8 aad[24], nonce[13]; + size_t aad_len, plen; + u8 *crypt, *pos; + struct ieee80211_hdr *hdr; + + if (len < hdrlen || hdrlen < 12) + return NULL; + plen = len - hdrlen; + + crypt = os_malloc(hdrlen + plen + 8 + AES_BLOCK_SIZE); + if (crypt == NULL) + return NULL; + + os_memcpy(crypt, frame, hdrlen); + hdr = (struct ieee80211_hdr *) crypt; + hdr->frame_control |= host_to_le16(BIT(12)); /* Protected Frame */ + pos = crypt + hdrlen; + + os_memset(aad, 0, sizeof(aad)); + ccmp_aad_nonce_pv1(crypt, a1, a2, a3, pn, aad, &aad_len, nonce); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP AAD", aad, aad_len); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP nonce", nonce, sizeof(nonce)); + + if (aes_ccm_ae(tk, 16, nonce, 8, frame + hdrlen, plen, aad, aad_len, + pos, pos + plen) < 0) { + rtw_mfree(crypt, hdrlen + plen + 8 + AES_BLOCK_SIZE); + return NULL; + } + + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP encrypted", crypt + hdrlen, plen); + + *encrypted_len = hdrlen + plen + 8; + + return crypt; +} + + +u8 * ccmp_256_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr, + const u8 *data, size_t data_len, size_t *decrypted_len) +{ + u8 aad[30], nonce[13]; + size_t aad_len; + size_t mlen; + u8 *plain; + + if (data_len < 8 + 16) + return NULL; + + plain = os_malloc(data_len + AES_BLOCK_SIZE); + if (plain == NULL) + return NULL; + + mlen = data_len - 8 - 16; + + os_memset(aad, 0, sizeof(aad)); + ccmp_aad_nonce(hdr, data, aad, &aad_len, nonce); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 AAD", aad, aad_len); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 nonce", nonce, 13); + + if (aes_ccm_ad(tk, 32, nonce, 16, data + 8, mlen, aad, aad_len, + data + 8 + mlen, plain) < 0) { + u16 seq_ctrl = le_to_host16(hdr->seq_ctrl); + wpa_printf(_MSG_INFO_, "Invalid CCMP-256 MIC in frame: A1=" MACSTR + " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u", + MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), + MAC2STR(hdr->addr3), + WLAN_GET_SEQ_SEQ(seq_ctrl), + WLAN_GET_SEQ_FRAG(seq_ctrl)); + rtw_mfree(plain, data_len + AES_BLOCK_SIZE); + return NULL; + } + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 decrypted", plain, mlen); + + *decrypted_len = mlen; + return plain; +} + + +u8 * ccmp_256_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, + u8 *qos, u8 *pn, int keyid, size_t *encrypted_len) +{ + u8 aad[30], nonce[13]; + size_t aad_len, plen; + u8 *crypt, *pos, *pdata; + struct ieee80211_hdr *hdr; + + if (len < hdrlen || hdrlen < 24) + return NULL; + plen = len - hdrlen; + + crypt = os_malloc(hdrlen + 8 + plen + 16 + AES_BLOCK_SIZE); + if (crypt == NULL) + return NULL; + + if (pn == NULL) { + os_memcpy(crypt, frame, hdrlen + 8); + hdr = (struct ieee80211_hdr *) crypt; + hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); + pos = crypt + hdrlen + 8; + pdata = frame + hdrlen + 8; + } else { + os_memcpy(crypt, frame, hdrlen); + hdr = (struct ieee80211_hdr *) crypt; + hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP); + pos = crypt + hdrlen; + *pos++ = pn[5]; /* PN0 */ + *pos++ = pn[4]; /* PN1 */ + *pos++ = 0x00; /* Rsvd */ + *pos++ = 0x20 | (keyid << 6); + *pos++ = pn[3]; /* PN2 */ + *pos++ = pn[2]; /* PN3 */ + *pos++ = pn[1]; /* PN4 */ + *pos++ = pn[0]; /* PN5 */ + pdata = frame + hdrlen; + } + + os_memset(aad, 0, sizeof(aad)); + ccmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 AAD", aad, aad_len); + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 nonce", nonce, 13); + + if (aes_ccm_ae(tk, 32, nonce, 16, pdata, plen, aad, aad_len, + pos, pos + plen) < 0) { + rtw_mfree(crypt, hdrlen + 8 + plen + 16 + AES_BLOCK_SIZE); + return NULL; + } + + wpa_hexdump(_MSG_EXCESSIVE_, "CCMP-256 encrypted", crypt + hdrlen + 8, + plen); + + *encrypted_len = hdrlen + 8 + plen + 16; + + return crypt; +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/gcmp.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/gcmp.c index e97b45ad0228..db9a8c31fea5 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/gcmp.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/gcmp.c @@ -1,194 +1,194 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * GCM with GMAC Protocol (GCMP) - * Copyright (c) 2012, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#include "rtw_crypto_wrap.h" - -#include "aes.h" -#include "aes_wrap.h" -#include "wlancrypto_wrap.h" - - -static void gcmp_aad_nonce(const struct ieee80211_hdr *hdr, const u8 *data, - u8 *aad, size_t *aad_len, u8 *nonce) -{ - u16 fc, stype, seq; - int qos = 0, addr4 = 0; - u8 *pos; - - fc = le_to_host16(hdr->frame_control); - stype = WLAN_FC_GET_STYPE(fc); - if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == - (WLAN_FC_TODS | WLAN_FC_FROMDS)) - addr4 = 1; - - if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) { - fc &= ~0x0070; /* Mask subtype bits */ - if (stype & WLAN_FC_STYPE_QOS_DATA) { - const u8 *qc; - qos = 1; - fc &= ~WLAN_FC_ORDER; - qc = (const u8 *)hdr + 24; - if (addr4) - qc += ETH_ALEN; - } - } - - fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA); - WPA_PUT_LE16(aad, fc); - pos = aad + 2; - os_memcpy(pos, hdr->addr1, 3 * ETH_ALEN); - pos += 3 * ETH_ALEN; - seq = le_to_host16(hdr->seq_ctrl); - seq &= ~0xfff0; /* Mask Seq#; do not modify Frag# */ - WPA_PUT_LE16(pos, seq); - pos += 2; - - wpa_printf(_MSG_INFO_, "pos - aad = %u, qos(%d)\n", (pos - aad), qos); - - os_memcpy(pos, (u8 *)hdr + 24, addr4 * ETH_ALEN + qos * 2); - pos += addr4 * ETH_ALEN; - if (qos) { - pos[0] &= ~0x70; - if (1 /* FIX: either device has SPP A-MSDU Capab = 0 */) - pos[0] &= ~0x80; - pos++; - *pos++ = 0x00; - } - - wpa_printf(_MSG_INFO_, "pos - aad = %u\n", (pos - aad)); - *aad_len = pos - aad; - - os_memcpy(nonce, hdr->addr2, ETH_ALEN); - nonce[6] = data[7]; /* PN5 */ - nonce[7] = data[6]; /* PN4 */ - nonce[8] = data[5]; /* PN3 */ - nonce[9] = data[4]; /* PN2 */ - nonce[10] = data[1]; /* PN1 */ - nonce[11] = data[0]; /* PN0 */ -} - -/** - * gcmp_decrypt - - * @tk: the temporal key - * @tk_len: length of @tk - * @hdr: the mac header - * @data: payload after mac header (PN + enc_data + MIC) - * @data_len: length of @data (PN + enc_data + MIC) - * @decrypted_len: length of the data decrypted - */ -u8 * gcmp_decrypt(const u8 *tk, size_t tk_len, const struct ieee80211_hdr *hdr, - const u8 *data, size_t data_len, size_t *decrypted_len) -{ - u8 aad[30], nonce[12], *plain; - size_t aad_len, mlen; - const u8 *m; - - if (data_len < 8 + 16) - return NULL; - - plain = os_malloc(data_len + AES_BLOCK_SIZE); - if (plain == NULL) - return NULL; - - m = data + 8; - mlen = data_len - 8 - 16; - - os_memset(aad, 0, sizeof(aad)); - gcmp_aad_nonce(hdr, data, aad, &aad_len, nonce); - wpa_hexdump(_MSG_EXCESSIVE_, "GCMP AAD", aad, aad_len); - wpa_hexdump(_MSG_EXCESSIVE_, "GCMP nonce", nonce, sizeof(nonce)); - - if (aes_gcm_ad(tk, tk_len, nonce, sizeof(nonce), m, mlen, aad, aad_len, - m + mlen, plain) < 0) { - u16 seq_ctrl = le_to_host16(hdr->seq_ctrl); - wpa_printf(_MSG_INFO_, "Invalid GCMP frame: A1=" MACSTR - " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u", - MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), - MAC2STR(hdr->addr3), - WLAN_GET_SEQ_SEQ(seq_ctrl), - WLAN_GET_SEQ_FRAG(seq_ctrl)); - rtw_mfree(plain, data_len + AES_BLOCK_SIZE); - return NULL; - } - - *decrypted_len = mlen; - return plain; -} - -/** - * gcmp_encrypt - - * @tk: the temporal key - * @tk_len: length of @tk - * @frame: the point to mac header, the frame including mac header and payload, - * if @pn is NULL, then the frame including pn - * @len: length of @frame - * length = mac header + payload - * @hdrlen: length of the mac header - * @qos: pointer to the QOS field of the frame - * @pn: packet number - * @keyid: key id - * @encrypted_len: length of the encrypted frame - * including mac header, pn, payload and MIC - */ -u8 * gcmp_encrypt(const u8 *tk, size_t tk_len, const u8 *frame, size_t len, - size_t hdrlen, const u8 *qos, - const u8 *pn, int keyid, size_t *encrypted_len) -{ - u8 aad[30], nonce[12], *crypt, *pos; - const u8 *pdata; - size_t aad_len, plen; - struct ieee80211_hdr *hdr; - - if (len < hdrlen || hdrlen < 24) - return NULL; - plen = len - hdrlen; - - crypt = os_malloc(hdrlen + 8 + plen + 16 + AES_BLOCK_SIZE); - if (crypt == NULL) - return NULL; - - if (pn == NULL) { - os_memcpy(crypt, frame, hdrlen + 8); - hdr = (struct ieee80211_hdr *)crypt; - pos = crypt + hdrlen + 8; - pdata = frame + hdrlen + 8; - } else { - os_memcpy(crypt, frame, hdrlen); - hdr = (struct ieee80211_hdr *)crypt; - pos = crypt + hdrlen; - - *pos++ = pn[5]; /* PN0 */ - *pos++ = pn[4]; /* PN1 */ - *pos++ = 0x00; /* Rsvd */ - *pos++ = 0x20 | (keyid << 6); - *pos++ = pn[3]; /* PN2 */ - *pos++ = pn[2]; /* PN3 */ - *pos++ = pn[1]; /* PN4 */ - *pos++ = pn[0]; /* PN5 */ - pdata = frame + hdrlen; - } - - os_memset(aad, 0, sizeof(aad)); - gcmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce); - wpa_hexdump(_MSG_EXCESSIVE_, "GCMP AAD", aad, aad_len); - wpa_hexdump(_MSG_EXCESSIVE_, "GCMP nonce", nonce, sizeof(nonce)); - - if (aes_gcm_ae(tk, tk_len, nonce, sizeof(nonce), pdata, plen, - aad, aad_len, pos, pos + plen) < 0) { - rtw_mfree(crypt, hdrlen + 8 + plen + 16 + AES_BLOCK_SIZE); - return NULL; - } - - wpa_hexdump(_MSG_EXCESSIVE_, "GCMP MIC", pos + plen, 16); - wpa_hexdump(_MSG_EXCESSIVE_, "GCMP encrypted", pos, plen); - - *encrypted_len = hdrlen + 8 + plen + 16; - - return crypt; -} +/* + * GCM with GMAC Protocol (GCMP) + * Copyright (c) 2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "aes.h" +#include "aes_wrap.h" +#include "wlancrypto_wrap.h" + + +static void gcmp_aad_nonce(const struct ieee80211_hdr *hdr, const u8 *data, + u8 *aad, size_t *aad_len, u8 *nonce) +{ + u16 fc, stype, seq; + int qos = 0, addr4 = 0; + u8 *pos; + + fc = le_to_host16(hdr->frame_control); + stype = WLAN_FC_GET_STYPE(fc); + if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == + (WLAN_FC_TODS | WLAN_FC_FROMDS)) + addr4 = 1; + + if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) { + fc &= ~0x0070; /* Mask subtype bits */ + if (stype & WLAN_FC_STYPE_QOS_DATA) { + const u8 *qc; + qos = 1; + fc &= ~WLAN_FC_ORDER; + qc = (const u8 *)hdr + 24; + if (addr4) + qc += ETH_ALEN; + } + } + + fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA); + WPA_PUT_LE16(aad, fc); + pos = aad + 2; + os_memcpy(pos, GetAddr1Ptr((u8 *)hdr), 3 * ETH_ALEN); + pos += 3 * ETH_ALEN; + seq = le_to_host16(hdr->seq_ctrl); + seq &= ~0xfff0; /* Mask Seq#; do not modify Frag# */ + WPA_PUT_LE16(pos, seq); + pos += 2; + + wpa_printf(_MSG_INFO_, "pos - aad = %u, qos(%d)\n", (pos - aad), qos); + + os_memcpy(pos, (u8 *)hdr + 24, addr4 * ETH_ALEN + qos * 2); + pos += addr4 * ETH_ALEN; + if (qos) { + pos[0] &= ~0x70; + if (1 /* FIX: either device has SPP A-MSDU Capab = 0 */) + pos[0] &= ~0x80; + pos++; + *pos++ = 0x00; + } + + wpa_printf(_MSG_INFO_, "pos - aad = %u\n", (pos - aad)); + *aad_len = pos - aad; + + os_memcpy(nonce, hdr->addr2, ETH_ALEN); + nonce[6] = data[7]; /* PN5 */ + nonce[7] = data[6]; /* PN4 */ + nonce[8] = data[5]; /* PN3 */ + nonce[9] = data[4]; /* PN2 */ + nonce[10] = data[1]; /* PN1 */ + nonce[11] = data[0]; /* PN0 */ +} + +/** + * gcmp_decrypt - + * @tk: the temporal key + * @tk_len: length of @tk + * @hdr: the mac header + * @data: payload after mac header (PN + enc_data + MIC) + * @data_len: length of @data (PN + enc_data + MIC) + * @decrypted_len: length of the data decrypted + */ +u8 * gcmp_decrypt(const u8 *tk, size_t tk_len, const struct ieee80211_hdr *hdr, + const u8 *data, size_t data_len, size_t *decrypted_len) +{ + u8 aad[30], nonce[12], *plain; + size_t aad_len, mlen; + const u8 *m; + + if (data_len < 8 + 16) + return NULL; + + plain = os_malloc(data_len + AES_BLOCK_SIZE); + if (plain == NULL) + return NULL; + + m = data + 8; + mlen = data_len - 8 - 16; + + os_memset(aad, 0, sizeof(aad)); + gcmp_aad_nonce(hdr, data, aad, &aad_len, nonce); + wpa_hexdump(_MSG_EXCESSIVE_, "GCMP AAD", aad, aad_len); + wpa_hexdump(_MSG_EXCESSIVE_, "GCMP nonce", nonce, sizeof(nonce)); + + if (aes_gcm_ad(tk, tk_len, nonce, sizeof(nonce), m, mlen, aad, aad_len, + m + mlen, plain) < 0) { + u16 seq_ctrl = le_to_host16(hdr->seq_ctrl); + wpa_printf(_MSG_INFO_, "Invalid GCMP frame: A1=" MACSTR + " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u", + MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), + MAC2STR(hdr->addr3), + WLAN_GET_SEQ_SEQ(seq_ctrl), + WLAN_GET_SEQ_FRAG(seq_ctrl)); + rtw_mfree(plain, data_len + AES_BLOCK_SIZE); + return NULL; + } + + *decrypted_len = mlen; + return plain; +} + +/** + * gcmp_encrypt - + * @tk: the temporal key + * @tk_len: length of @tk + * @frame: the point to mac header, the frame including mac header and payload, + * if @pn is NULL, then the frame including pn + * @len: length of @frame + * length = mac header + payload + * @hdrlen: length of the mac header + * @qos: pointer to the QOS field of the frame + * @pn: packet number + * @keyid: key id + * @encrypted_len: length of the encrypted frame + * including mac header, pn, payload and MIC + */ +u8 * gcmp_encrypt(const u8 *tk, size_t tk_len, const u8 *frame, size_t len, + size_t hdrlen, const u8 *qos, + const u8 *pn, int keyid, size_t *encrypted_len) +{ + u8 aad[30], nonce[12], *crypt, *pos; + const u8 *pdata; + size_t aad_len, plen; + struct ieee80211_hdr *hdr; + + if (len < hdrlen || hdrlen < 24) + return NULL; + plen = len - hdrlen; + + crypt = os_malloc(hdrlen + 8 + plen + 16 + AES_BLOCK_SIZE); + if (crypt == NULL) + return NULL; + + if (pn == NULL) { + os_memcpy(crypt, frame, hdrlen + 8); + hdr = (struct ieee80211_hdr *)crypt; + pos = crypt + hdrlen + 8; + pdata = frame + hdrlen + 8; + } else { + os_memcpy(crypt, frame, hdrlen); + hdr = (struct ieee80211_hdr *)crypt; + pos = crypt + hdrlen; + + *pos++ = pn[5]; /* PN0 */ + *pos++ = pn[4]; /* PN1 */ + *pos++ = 0x00; /* Rsvd */ + *pos++ = 0x20 | (keyid << 6); + *pos++ = pn[3]; /* PN2 */ + *pos++ = pn[2]; /* PN3 */ + *pos++ = pn[1]; /* PN4 */ + *pos++ = pn[0]; /* PN5 */ + pdata = frame + hdrlen; + } + + os_memset(aad, 0, sizeof(aad)); + gcmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce); + wpa_hexdump(_MSG_EXCESSIVE_, "GCMP AAD", aad, aad_len); + wpa_hexdump(_MSG_EXCESSIVE_, "GCMP nonce", nonce, sizeof(nonce)); + + if (aes_gcm_ae(tk, tk_len, nonce, sizeof(nonce), pdata, plen, + aad, aad_len, pos, pos + plen) < 0) { + rtw_mfree(crypt, hdrlen + 8 + plen + 16 + AES_BLOCK_SIZE); + return NULL; + } + + wpa_hexdump(_MSG_EXCESSIVE_, "GCMP MIC", pos + plen, 16); + wpa_hexdump(_MSG_EXCESSIVE_, "GCMP encrypted", pos, plen); + + *encrypted_len = hdrlen + 8 + plen + 16; + + return crypt; +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/rtw_crypto_wrap.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/rtw_crypto_wrap.c index c028dbf4d588..19e1754754dd 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/rtw_crypto_wrap.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/rtw_crypto_wrap.c @@ -1,91 +1,86 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#include "rtw_crypto_wrap.h" - -#ifndef DEBUG_CRYPTO -#define DEBUG_CRYPTO 0 -#endif /* DEBUG_CRYTO */ - -int os_memcmp(const void *s1, const void *s2, size_t n) -{ - return _rtw_memcmp2(s1, s2, n); -} - -int os_memcmp_const(const void *a, const void *b, size_t len) -{ - const u8 *aa = a; - const u8 *bb = b; - size_t i; - u8 res; - - for (res = 0, i = 0; i < len; i++) - res |= aa[i] ^ bb[i]; - - return res; -} - -void* os_memdup(const void *src, u32 sz) -{ - void *r = rtw_malloc(sz); - - if (r && src) - _rtw_memcpy(r, src, sz); - return r; -} - -size_t os_strlen(const char *s) -{ - const char *p = s; - while (*p) - p++; - return p - s; -} - - -void forced_memzero(void *ptr, size_t len) -{ - _rtw_memset(ptr, 0, len); -} - -void bin_clear_free(void *bin, size_t len) -{ - if (bin) { - forced_memzero(bin, len); - rtw_mfree(bin, len); - } -} - -void wpa_printf(int level, const char *fmt, ...) -{ -#if DEBUG_CRYPTO -#define MSG_LEN 100 - va_list args; - u8 buf[MSG_LEN] = { 0 }; - int err; - - va_start(args, fmt); - err = vsnprintf(buf, MSG_LEN, fmt, args); - va_end(args); - - RTW_INFO("%s", buf); -#undef MSG_LEN -#endif /* DEBUG_CRYPTO */ -} - -void wpa_hexdump(int level, const char *title, const void *buf, size_t len) -{ -#if DEBUG_CRYPTO - RTW_INFO_DUMP((u8 *)title, buf, len); -#endif /* DEBUG_CRYPTO */ -} - -void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len) -{ -#if DEBUG_CRYPTO - RTW_INFO_DUMP((u8 *)title, buf, len); -#endif /* DEBUG_CRYPTO */ -} - -u32 crc32(const u8 *frame, size_t frame_len) -{ - return rtw_calc_crc32((u8 *)frame, frame_len); -} +#include "rtw_crypto_wrap.h" + +#ifndef DEBUG_CRYPTO +#define DEBUG_CRYPTO 0 +#endif /* DEBUG_CRYTO */ + +int os_memcmp(const void *s1, const void *s2, size_t n) +{ + return _rtw_memcmp2(s1, s2, n); +} + +int os_memcmp_const(const void *a, const void *b, size_t len) +{ + const u8 *aa = a; + const u8 *bb = b; + size_t i; + u8 res; + + for (res = 0, i = 0; i < len; i++) + res |= aa[i] ^ bb[i]; + + return res; +} + +void* os_memdup(const void *src, u32 sz) +{ + void *r = rtw_malloc(sz); + + if (r && src) + _rtw_memcpy(r, src, sz); + return r; +} + +size_t os_strlen(const char *s) +{ + const char *p = s; + while (*p) + p++; + return p - s; +} + + +void forced_memzero(void *ptr, size_t len) +{ + _rtw_memset(ptr, 0, len); +} + +void bin_clear_free(void *bin, size_t len) +{ + if (bin) { + forced_memzero(bin, len); + rtw_mfree(bin, len); + } +} + +void wpa_printf(int level, const char *fmt, ...) +{ +#if DEBUG_CRYPTO +#define MSG_LEN 100 + va_list args; + u8 buf[MSG_LEN] = { 0 }; + int err; + + va_start(args, fmt); + err = vsnprintf(buf, MSG_LEN, fmt, args); + va_end(args); + + RTW_INFO("%s", buf); +#undef MSG_LEN +#endif /* DEBUG_CRYPTO */ +} + +void wpa_hexdump(int level, const char *title, const void *buf, size_t len) +{ +#if DEBUG_CRYPTO + RTW_INFO_DUMP((u8 *)title, buf, len); +#endif /* DEBUG_CRYPTO */ +} + +void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len) +{ +#if DEBUG_CRYPTO + RTW_INFO_DUMP((u8 *)title, buf, len); +#endif /* DEBUG_CRYPTO */ +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/rtw_crypto_wrap.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/rtw_crypto_wrap.h index 4a362b6e58aa..32384923732d 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/rtw_crypto_wrap.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/rtw_crypto_wrap.h @@ -1,66 +1,65 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef RTW_CRYTO_WRAP_H -#define RTW_CRYTO_WRAP_H - -#include - -#define TEST_FAIL() 0 - -#define os_memset _rtw_memset -#define os_memcpy _rtw_memcpy -#define os_malloc rtw_malloc - -#define le_to_host16 le16_to_cpu -#define host_to_le16 cpu_to_le16 - -#define WPA_PUT_LE16 RTW_PUT_LE16 -#define WPA_GET_LE16 RTW_GET_LE16 -#define WPA_PUT_LE32 RTW_PUT_LE32 -#define WPA_GET_LE32 RTW_GET_LE32 -#define WPA_PUT_LE64 RTW_PUT_LE64 -#define WPA_GET_LE64 RTW_GET_LE64 -#define WPA_PUT_BE16 RTW_PUT_BE16 -#define WPA_GET_BE16 RTW_GET_BE16 -#define WPA_PUT_BE32 RTW_PUT_BE32 -#define WPA_GET_BE32 RTW_GET_BE32 -#define WPA_PUT_BE64 RTW_PUT_BE64 -#define WPA_GET_BE64 RTW_GET_BE64 - -#ifndef MAC2STR -#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] -#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" -#endif - -#define WLAN_FC_PVER 0x0003 -#define WLAN_FC_TODS 0x0100 -#define WLAN_FC_FROMDS 0x0200 -#define WLAN_FC_MOREFRAG 0x0400 -#define WLAN_FC_RETRY 0x0800 -#define WLAN_FC_PWRMGT 0x1000 -#define WLAN_FC_MOREDATA 0x2000 -#define WLAN_FC_ISWEP 0x4000 -#define WLAN_FC_ORDER 0x8000 - -#define WLAN_FC_TYPE_DATA RTW_IEEE80211_FTYPE_DATA -#define WLAN_FC_TYPE_MGMT RTW_IEEE80211_FTYPE_MGMT - -#define WLAN_FC_STYPE_QOS_DATA RTW_IEEE80211_STYPE_QOS_DATA - -enum { - _MSG_EXCESSIVE_, _MSG_MSGDUMP_, _MSG_DEBUG_, _MSG_INFO_, _MSG_WARNING_, _MSG_ERROR_ -}; - -int os_memcmp(const void *s1, const void *s2, size_t n); -int os_memcmp_const(const void *a, const void *b, size_t len); -void* os_memdup(const void *src, u32 sz); -size_t os_strlen(const char *s); - -void forced_memzero(void *ptr, size_t len); -void bin_clear_free(void *bin, size_t len); - -void wpa_printf(int level, const char *fmt, ...); -void wpa_hexdump(int level, const char *title, const void *buf, size_t len); -void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len); - -u32 crc32(const u8 *frame, size_t frame_len); -#endif /* RTW_CRYTO_WRAP_H */ +#ifndef RTW_CRYTO_WRAP_H +#define RTW_CRYTO_WRAP_H + +#include + +#define TEST_FAIL() 0 + +#define os_memset _rtw_memset +#define os_memcpy _rtw_memcpy +#define os_malloc rtw_malloc + +#define le_to_host16 le16_to_cpu +#define host_to_le16 cpu_to_le16 + +#define WPA_PUT_LE16 RTW_PUT_LE16 +#define WPA_GET_LE16 RTW_GET_LE16 +#define WPA_PUT_LE32 RTW_PUT_LE32 +#define WPA_GET_LE32 RTW_GET_LE32 +#define WPA_PUT_LE64 RTW_PUT_LE64 +#define WPA_GET_LE64 RTW_GET_LE64 +#define WPA_PUT_BE16 RTW_PUT_BE16 +#define WPA_GET_BE16 RTW_GET_BE16 +#define WPA_PUT_BE32 RTW_PUT_BE32 +#define WPA_GET_BE32 RTW_GET_BE32 +#define WPA_PUT_BE64 RTW_PUT_BE64 +#define WPA_GET_BE64 RTW_GET_BE64 + +#ifndef MAC2STR +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" +#endif + +#define WLAN_FC_PVER 0x0003 +#define WLAN_FC_TODS 0x0100 +#define WLAN_FC_FROMDS 0x0200 +#define WLAN_FC_MOREFRAG 0x0400 +#define WLAN_FC_RETRY 0x0800 +#define WLAN_FC_PWRMGT 0x1000 +#define WLAN_FC_MOREDATA 0x2000 +#define WLAN_FC_ISWEP 0x4000 +#define WLAN_FC_ORDER 0x8000 + +#define WLAN_FC_TYPE_DATA RTW_IEEE80211_FTYPE_DATA +#define WLAN_FC_TYPE_MGMT RTW_IEEE80211_FTYPE_MGMT + +#define WLAN_FC_STYPE_QOS_DATA RTW_IEEE80211_STYPE_QOS_DATA + +enum { + _MSG_EXCESSIVE_, _MSG_MSGDUMP_, _MSG_DEBUG_, _MSG_INFO_, _MSG_WARNING_, _MSG_ERROR_ +}; + +int os_memcmp(const void *s1, const void *s2, size_t n); +int os_memcmp_const(const void *a, const void *b, size_t len); +void* os_memdup(const void *src, u32 sz); +size_t os_strlen(const char *s); + +void forced_memzero(void *ptr, size_t len); +void bin_clear_free(void *bin, size_t len); + +void wpa_printf(int level, const char *fmt, ...); +void wpa_hexdump(int level, const char *title, const void *buf, size_t len); +void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len); + +#endif /* RTW_CRYTO_WRAP_H */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256-internal.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256-internal.c index de63ed6b08da..3a269aa8c4fa 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256-internal.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256-internal.c @@ -1,231 +1,231 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * SHA-256 hash implementation and interface functions - * Copyright (c) 2003-2011, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#include "rtw_crypto_wrap.h" - -//#include "common.h" -#include "sha256.h" -#include "sha256_i.h" -//#include "crypto.h" -#include "wlancrypto_wrap.h" - - -/** - * sha256_vector - SHA256 hash for data vector - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash - * Returns: 0 on success, -1 of failure - */ -int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, - u8 *mac) -{ - struct sha256_state ctx; - size_t i; - - if (TEST_FAIL()) - return -1; - - sha256_init(&ctx); - for (i = 0; i < num_elem; i++) - if (sha256_process(&ctx, addr[i], len[i])) - return -1; - if (sha256_done(&ctx, mac)) - return -1; - return 0; -} - - -/* ===== start - public domain SHA256 implementation ===== */ - -/* This is based on SHA256 implementation in LibTomCrypt that was released into - * public domain by Tom St Denis. */ - -/* the K array */ -static const unsigned long K[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, - 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, - 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, - 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, - 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, - 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, - 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, - 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, - 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, - 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL -}; - - -/* Various logical functions */ -#define RORc(x, y) \ -( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \ - ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL) -#define Ch(x,y,z) (z ^ (x & (y ^ z))) -#define Maj(x,y,z) (((x | y) & z) | (x & y)) -#define S(x, n) RORc((x), (n)) -#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) -#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) -#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) -#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) -#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) -#ifndef MIN -#define MIN(x, y) (((x) < (y)) ? (x) : (y)) -#endif - -/* compress 512-bits */ -static int sha256_compress(struct sha256_state *md, unsigned char *buf) -{ - u32 S[8], W[64], t0, t1; - u32 t; - int i; - - /* copy state into S */ - for (i = 0; i < 8; i++) { - S[i] = md->state[i]; - } - - /* copy the state into 512-bits into W[0..15] */ - for (i = 0; i < 16; i++) - W[i] = WPA_GET_BE32(buf + (4 * i)); - - /* fill W[16..63] */ - for (i = 16; i < 64; i++) { - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + - W[i - 16]; - } - - /* Compress */ -#define RND(a,b,c,d,e,f,g,h,i) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ - h = t0 + t1; - - for (i = 0; i < 64; ++i) { - RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); - t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; - S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; - } - - /* feedback */ - for (i = 0; i < 8; i++) { - md->state[i] = md->state[i] + S[i]; - } - return 0; -} - - -/* Initialize the hash state */ -void sha256_init(struct sha256_state *md) -{ - md->curlen = 0; - md->length = 0; - md->state[0] = 0x6A09E667UL; - md->state[1] = 0xBB67AE85UL; - md->state[2] = 0x3C6EF372UL; - md->state[3] = 0xA54FF53AUL; - md->state[4] = 0x510E527FUL; - md->state[5] = 0x9B05688CUL; - md->state[6] = 0x1F83D9ABUL; - md->state[7] = 0x5BE0CD19UL; -} - -/** - Process a block of memory though the hash - @param md The hash state - @param in The data to hash - @param inlen The length of the data (octets) - @return CRYPT_OK if successful -*/ -int sha256_process(struct sha256_state *md, const unsigned char *in, - unsigned long inlen) -{ - unsigned long n; - - if (md->curlen >= sizeof(md->buf)) - return -1; - - while (inlen > 0) { - if (md->curlen == 0 && inlen >= SHA256_BLOCK_SIZE) { - if (sha256_compress(md, (unsigned char *) in) < 0) - return -1; - md->length += SHA256_BLOCK_SIZE * 8; - in += SHA256_BLOCK_SIZE; - inlen -= SHA256_BLOCK_SIZE; - } else { - n = MIN(inlen, (SHA256_BLOCK_SIZE - md->curlen)); - os_memcpy(md->buf + md->curlen, in, n); - md->curlen += n; - in += n; - inlen -= n; - if (md->curlen == SHA256_BLOCK_SIZE) { - if (sha256_compress(md, md->buf) < 0) - return -1; - md->length += 8 * SHA256_BLOCK_SIZE; - md->curlen = 0; - } - } - } - - return 0; -} - - -/** - Terminate the hash to get the digest - @param md The hash state - @param out [out] The destination of the hash (32 bytes) - @return CRYPT_OK if successful -*/ -int sha256_done(struct sha256_state *md, unsigned char *out) -{ - int i; - - if (md->curlen >= sizeof(md->buf)) - return -1; - - /* increase the length of the message */ - md->length += md->curlen * 8; - - /* append the '1' bit */ - md->buf[md->curlen++] = (unsigned char) 0x80; - - /* if the length is currently above 56 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (md->curlen > 56) { - while (md->curlen < SHA256_BLOCK_SIZE) { - md->buf[md->curlen++] = (unsigned char) 0; - } - sha256_compress(md, md->buf); - md->curlen = 0; - } - - /* pad up to 56 bytes of zeroes */ - while (md->curlen < 56) { - md->buf[md->curlen++] = (unsigned char) 0; - } - - /* store length */ - WPA_PUT_BE64(md->buf + 56, md->length); - sha256_compress(md, md->buf); - - /* copy output */ - for (i = 0; i < 8; i++) - WPA_PUT_BE32(out + (4 * i), md->state[i]); - - return 0; -} - -/* ===== end - public domain SHA256 implementation ===== */ +/* + * SHA-256 hash implementation and interface functions + * Copyright (c) 2003-2011, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +//#include "common.h" +#include "sha256.h" +#include "sha256_i.h" +//#include "crypto.h" +#include "wlancrypto_wrap.h" + + +/** + * sha256_vector - SHA256 hash for data vector + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 of failure + */ +int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, + u8 *mac) +{ + struct _sha256_state ctx; + size_t i; + + if (TEST_FAIL()) + return -1; + + _sha256_init(&ctx); + for (i = 0; i < num_elem; i++) + if (sha256_process(&ctx, addr[i], len[i])) + return -1; + if (sha256_done(&ctx, mac)) + return -1; + return 0; +} + + +/* ===== start - public domain SHA256 implementation ===== */ + +/* This is based on SHA256 implementation in LibTomCrypt that was released into + * public domain by Tom St Denis. */ + +/* the K array */ +static const unsigned long K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + + +/* Various logical functions */ +#define RORc(x, y) \ +( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \ + ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL) +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) RORc((x), (n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +/* compress 512-bits */ +static int sha256_compress(struct _sha256_state *md, unsigned char *buf) +{ + u32 S[8], W[64], t0, t1; + u32 t; + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->state[i]; + } + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) + W[i] = WPA_GET_BE32(buf + (4 * i)); + + /* fill W[16..63] */ + for (i = 16; i < 64; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + + W[i - 16]; + } + + /* Compress */ +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 64; ++i) { + RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); + t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; + S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; + } + + /* feedback */ + for (i = 0; i < 8; i++) { + md->state[i] = md->state[i] + S[i]; + } + return 0; +} + + +/* Initialize the hash state */ +void _sha256_init(struct _sha256_state *md) +{ + md->curlen = 0; + md->length = 0; + md->state[0] = 0x6A09E667UL; + md->state[1] = 0xBB67AE85UL; + md->state[2] = 0x3C6EF372UL; + md->state[3] = 0xA54FF53AUL; + md->state[4] = 0x510E527FUL; + md->state[5] = 0x9B05688CUL; + md->state[6] = 0x1F83D9ABUL; + md->state[7] = 0x5BE0CD19UL; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +int sha256_process(struct _sha256_state *md, const unsigned char *in, + unsigned long inlen) +{ + unsigned long n; + + if (md->curlen >= sizeof(md->buf)) + return -1; + + while (inlen > 0) { + if (md->curlen == 0 && inlen >= SHA256_BLOCK_SIZE) { + if (sha256_compress(md, (unsigned char *) in) < 0) + return -1; + md->length += SHA256_BLOCK_SIZE * 8; + in += SHA256_BLOCK_SIZE; + inlen -= SHA256_BLOCK_SIZE; + } else { + n = MIN(inlen, (SHA256_BLOCK_SIZE - md->curlen)); + os_memcpy(md->buf + md->curlen, in, n); + md->curlen += n; + in += n; + inlen -= n; + if (md->curlen == SHA256_BLOCK_SIZE) { + if (sha256_compress(md, md->buf) < 0) + return -1; + md->length += 8 * SHA256_BLOCK_SIZE; + md->curlen = 0; + } + } + } + + return 0; +} + + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful +*/ +int sha256_done(struct _sha256_state *md, unsigned char *out) +{ + int i; + + if (md->curlen >= sizeof(md->buf)) + return -1; + + /* increase the length of the message */ + md->length += md->curlen * 8; + + /* append the '1' bit */ + md->buf[md->curlen++] = (unsigned char) 0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->curlen > 56) { + while (md->curlen < SHA256_BLOCK_SIZE) { + md->buf[md->curlen++] = (unsigned char) 0; + } + sha256_compress(md, md->buf); + md->curlen = 0; + } + + /* pad up to 56 bytes of zeroes */ + while (md->curlen < 56) { + md->buf[md->curlen++] = (unsigned char) 0; + } + + /* store length */ + WPA_PUT_BE64(md->buf + 56, md->length); + sha256_compress(md, md->buf); + + /* copy output */ + for (i = 0; i < 8; i++) + WPA_PUT_BE32(out + (4 * i), md->state[i]); + + return 0; +} + +/* ===== end - public domain SHA256 implementation ===== */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256-prf.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256-prf.c index c69031b323d1..df0cd7b89b99 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256-prf.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256-prf.c @@ -1,110 +1,110 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * SHA256-based PRF (IEEE 802.11r) - * Copyright (c) 2003-2016, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#include "rtw_crypto_wrap.h" - -//#include "common.h" -#include "sha256.h" -//#include "crypto.h" -#include "wlancrypto_wrap.h" - - -/** - * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2) - * @key: Key for PRF - * @key_len: Length of the key in bytes - * @label: A unique label for each purpose of the PRF - * @data: Extra data to bind into the key - * @data_len: Length of the data - * @buf: Buffer for the generated pseudo-random key - * @buf_len: Number of bytes of key to generate - * Returns: 0 on success, -1 on failure - * - * This function is used to derive new, cryptographically separate keys from a - * given key. - */ -int sha256_prf(const u8 *key, size_t key_len, const char *label, - const u8 *data, size_t data_len, u8 *buf, size_t buf_len) -{ - return sha256_prf_bits(key, key_len, label, data, data_len, buf, - buf_len * 8); -} - - -/** - * sha256_prf_bits - IEEE Std 802.11-2012, 11.6.1.7.2 Key derivation function - * @key: Key for KDF - * @key_len: Length of the key in bytes - * @label: A unique label for each purpose of the PRF - * @data: Extra data to bind into the key - * @data_len: Length of the data - * @buf: Buffer for the generated pseudo-random key - * @buf_len: Number of bits of key to generate - * Returns: 0 on success, -1 on failure - * - * This function is used to derive new, cryptographically separate keys from a - * given key. If the requested buf_len is not divisible by eight, the least - * significant 1-7 bits of the last octet in the output are not part of the - * requested output. - */ -int sha256_prf_bits(const u8 *key, size_t key_len, const char *label, - const u8 *data, size_t data_len, u8 *buf, - size_t buf_len_bits) -{ - u16 counter = 1; - size_t pos, plen; - u8 hash[SHA256_MAC_LEN]; - const u8 *addr[4]; - size_t len[4]; - u8 counter_le[2], length_le[2]; - size_t buf_len = (buf_len_bits + 7) / 8; - - addr[0] = counter_le; - len[0] = 2; - addr[1] = (u8 *) label; - len[1] = os_strlen(label); - addr[2] = data; - len[2] = data_len; - addr[3] = length_le; - len[3] = sizeof(length_le); - - WPA_PUT_LE16(length_le, buf_len_bits); - pos = 0; - while (pos < buf_len) { - plen = buf_len - pos; - WPA_PUT_LE16(counter_le, counter); - if (plen >= SHA256_MAC_LEN) { - if (hmac_sha256_vector(key, key_len, 4, addr, len, - &buf[pos]) < 0) - return -1; - pos += SHA256_MAC_LEN; - } else { - if (hmac_sha256_vector(key, key_len, 4, addr, len, - hash) < 0) - return -1; - os_memcpy(&buf[pos], hash, plen); - pos += plen; - break; - } - counter++; - } - - /* - * Mask out unused bits in the last octet if it does not use all the - * bits. - */ - if (buf_len_bits % 8) { - u8 mask = 0xff << (8 - buf_len_bits % 8); - buf[pos - 1] &= mask; - } - - forced_memzero(hash, sizeof(hash)); - - return 0; -} +/* + * SHA256-based PRF (IEEE 802.11r) + * Copyright (c) 2003-2016, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +//#include "common.h" +#include "sha256.h" +//#include "crypto.h" +#include "wlancrypto_wrap.h" + + +/** + * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2) + * @key: Key for PRF + * @key_len: Length of the key in bytes + * @label: A unique label for each purpose of the PRF + * @data: Extra data to bind into the key + * @data_len: Length of the data + * @buf: Buffer for the generated pseudo-random key + * @buf_len: Number of bytes of key to generate + * Returns: 0 on success, -1 on failure + * + * This function is used to derive new, cryptographically separate keys from a + * given key. + */ +int sha256_prf(const u8 *key, size_t key_len, const char *label, + const u8 *data, size_t data_len, u8 *buf, size_t buf_len) +{ + return sha256_prf_bits(key, key_len, label, data, data_len, buf, + buf_len * 8); +} + + +/** + * sha256_prf_bits - IEEE Std 802.11-2012, 11.6.1.7.2 Key derivation function + * @key: Key for KDF + * @key_len: Length of the key in bytes + * @label: A unique label for each purpose of the PRF + * @data: Extra data to bind into the key + * @data_len: Length of the data + * @buf: Buffer for the generated pseudo-random key + * @buf_len: Number of bits of key to generate + * Returns: 0 on success, -1 on failure + * + * This function is used to derive new, cryptographically separate keys from a + * given key. If the requested buf_len is not divisible by eight, the least + * significant 1-7 bits of the last octet in the output are not part of the + * requested output. + */ +int sha256_prf_bits(const u8 *key, size_t key_len, const char *label, + const u8 *data, size_t data_len, u8 *buf, + size_t buf_len_bits) +{ + u16 counter = 1; + size_t pos, plen; + u8 hash[SHA256_MAC_LEN]; + const u8 *addr[4]; + size_t len[4]; + u8 counter_le[2], length_le[2]; + size_t buf_len = (buf_len_bits + 7) / 8; + + addr[0] = counter_le; + len[0] = 2; + addr[1] = (u8 *) label; + len[1] = os_strlen(label); + addr[2] = data; + len[2] = data_len; + addr[3] = length_le; + len[3] = sizeof(length_le); + + WPA_PUT_LE16(length_le, buf_len_bits); + pos = 0; + while (pos < buf_len) { + plen = buf_len - pos; + WPA_PUT_LE16(counter_le, counter); + if (plen >= SHA256_MAC_LEN) { + if (hmac_sha256_vector(key, key_len, 4, addr, len, + &buf[pos]) < 0) + return -1; + pos += SHA256_MAC_LEN; + } else { + if (hmac_sha256_vector(key, key_len, 4, addr, len, + hash) < 0) + return -1; + os_memcpy(&buf[pos], hash, plen); + pos += plen; + break; + } + counter++; + } + + /* + * Mask out unused bits in the last octet if it does not use all the + * bits. + */ + if (buf_len_bits % 8) { + u8 mask = 0xff << (8 - buf_len_bits % 8); + buf[pos - 1] &= mask; + } + + forced_memzero(hash, sizeof(hash)); + + return 0; +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256.c index cdcab23ccd18..d881814a86a2 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256.c @@ -1,105 +1,105 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * SHA-256 hash implementation and interface functions - * Copyright (c) 2003-2012, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#include "rtw_crypto_wrap.h" - -#include "sha256.h" -//#include "crypto.h" -#include "wlancrypto_wrap.h" - - -/** - * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104) - * @key: Key for HMAC operations - * @key_len: Length of the key in bytes - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash (32 bytes) - * Returns: 0 on success, -1 on failure - */ -int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, - const u8 *addr[], const size_t *len, u8 *mac) -{ - unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ - unsigned char tk[32]; - const u8 *_addr[6]; - size_t _len[6], i; - - if (num_elem > 5) { - /* - * Fixed limit on the number of fragments to avoid having to - * allocate memory (which could fail). - */ - return -1; - } - - /* if key is longer than 64 bytes reset it to key = SHA256(key) */ - if (key_len > 64) { - if (sha256_vector(1, &key, &key_len, tk) < 0) - return -1; - key = tk; - key_len = 32; - } - - /* the HMAC_SHA256 transform looks like: - * - * SHA256(K XOR opad, SHA256(K XOR ipad, text)) - * - * where K is an n byte key - * ipad is the byte 0x36 repeated 64 times - * opad is the byte 0x5c repeated 64 times - * and text is the data being protected */ - - /* start out by storing key in ipad */ - os_memset(k_pad, 0, sizeof(k_pad)); - os_memcpy(k_pad, key, key_len); - /* XOR key with ipad values */ - for (i = 0; i < 64; i++) - k_pad[i] ^= 0x36; - - /* perform inner SHA256 */ - _addr[0] = k_pad; - _len[0] = 64; - for (i = 0; i < num_elem; i++) { - _addr[i + 1] = addr[i]; - _len[i + 1] = len[i]; - } - if (sha256_vector(1 + num_elem, _addr, _len, mac) < 0) - return -1; - - os_memset(k_pad, 0, sizeof(k_pad)); - os_memcpy(k_pad, key, key_len); - /* XOR key with opad values */ - for (i = 0; i < 64; i++) - k_pad[i] ^= 0x5c; - - /* perform outer SHA256 */ - _addr[0] = k_pad; - _len[0] = 64; - _addr[1] = mac; - _len[1] = SHA256_MAC_LEN; - return sha256_vector(2, _addr, _len, mac); -} - - -/** - * hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104) - * @key: Key for HMAC operations - * @key_len: Length of the key in bytes - * @data: Pointers to the data area - * @data_len: Length of the data area - * @mac: Buffer for the hash (32 bytes) - * Returns: 0 on success, -1 on failure - */ -int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, - size_t data_len, u8 *mac) -{ - return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac); -} +/* + * SHA-256 hash implementation and interface functions + * Copyright (c) 2003-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "rtw_crypto_wrap.h" + +#include "sha256.h" +//#include "crypto.h" +#include "wlancrypto_wrap.h" + + +/** + * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104) + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash (32 bytes) + * Returns: 0 on success, -1 on failure + */ +int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac) +{ + unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ + unsigned char tk[32]; + const u8 *_addr[6]; + size_t _len[6], i; + + if (num_elem > 5) { + /* + * Fixed limit on the number of fragments to avoid having to + * allocate memory (which could fail). + */ + return -1; + } + + /* if key is longer than 64 bytes reset it to key = SHA256(key) */ + if (key_len > 64) { + if (sha256_vector(1, &key, &key_len, tk) < 0) + return -1; + key = tk; + key_len = 32; + } + + /* the HMAC_SHA256 transform looks like: + * + * SHA256(K XOR opad, SHA256(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected */ + + /* start out by storing key in ipad */ + os_memset(k_pad, 0, sizeof(k_pad)); + os_memcpy(k_pad, key, key_len); + /* XOR key with ipad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x36; + + /* perform inner SHA256 */ + _addr[0] = k_pad; + _len[0] = 64; + for (i = 0; i < num_elem; i++) { + _addr[i + 1] = addr[i]; + _len[i + 1] = len[i]; + } + if (sha256_vector(1 + num_elem, _addr, _len, mac) < 0) + return -1; + + os_memset(k_pad, 0, sizeof(k_pad)); + os_memcpy(k_pad, key, key_len); + /* XOR key with opad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x5c; + + /* perform outer SHA256 */ + _addr[0] = k_pad; + _len[0] = 64; + _addr[1] = mac; + _len[1] = SHA256_MAC_LEN; + return sha256_vector(2, _addr, _len, mac); +} + + +/** + * hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104) + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @data: Pointers to the data area + * @data_len: Length of the data area + * @mac: Buffer for the hash (32 bytes) + * Returns: 0 on success, -1 on failure + */ +int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, + size_t data_len, u8 *mac) +{ + return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac); +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256.h index 7bc6b5b67ebf..2d4726dae8f4 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256.h @@ -1,31 +1,31 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * SHA256 hash implementation and interface functions - * Copyright (c) 2003-2016, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#ifndef SHA256_H -#define SHA256_H - -#define SHA256_MAC_LEN 32 - -int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, - const u8 *addr[], const size_t *len, u8 *mac); -int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, - size_t data_len, u8 *mac); -int sha256_prf(const u8 *key, size_t key_len, const char *label, - const u8 *data, size_t data_len, u8 *buf, size_t buf_len); -int sha256_prf_bits(const u8 *key, size_t key_len, const char *label, - const u8 *data, size_t data_len, u8 *buf, - size_t buf_len_bits); -void tls_prf_sha256(const u8 *secret, size_t secret_len, - const char *label, const u8 *seed, size_t seed_len, - u8 *out, size_t outlen); -int hmac_sha256_kdf(const u8 *secret, size_t secret_len, - const char *label, const u8 *seed, size_t seed_len, - u8 *out, size_t outlen); - -#endif /* SHA256_H */ +/* + * SHA256 hash implementation and interface functions + * Copyright (c) 2003-2016, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef SHA256_H +#define SHA256_H + +#define SHA256_MAC_LEN 32 + +int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac); +int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, + size_t data_len, u8 *mac); +int sha256_prf(const u8 *key, size_t key_len, const char *label, + const u8 *data, size_t data_len, u8 *buf, size_t buf_len); +int sha256_prf_bits(const u8 *key, size_t key_len, const char *label, + const u8 *data, size_t data_len, u8 *buf, + size_t buf_len_bits); +void tls_prf_sha256(const u8 *secret, size_t secret_len, + const char *label, const u8 *seed, size_t seed_len, + u8 *out, size_t outlen); +int hmac_sha256_kdf(const u8 *secret, size_t secret_len, + const char *label, const u8 *seed, size_t seed_len, + u8 *out, size_t outlen); + +#endif /* SHA256_H */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256_i.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256_i.h index 91135ae1a831..4d6f3108eff3 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256_i.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/sha256_i.h @@ -1,26 +1,26 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * SHA-256 internal definitions - * Copyright (c) 2003-2011, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#ifndef SHA256_I_H -#define SHA256_I_H - -#define SHA256_BLOCK_SIZE 64 - -struct sha256_state { - u64 length; - u32 state[8], curlen; - u8 buf[SHA256_BLOCK_SIZE]; -}; - -void sha256_init(struct sha256_state *md); -int sha256_process(struct sha256_state *md, const unsigned char *in, - unsigned long inlen); -int sha256_done(struct sha256_state *md, unsigned char *out); - -#endif /* SHA256_I_H */ +/* + * SHA-256 internal definitions + * Copyright (c) 2003-2011, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef SHA256_I_H +#define SHA256_I_H + +#define SHA256_BLOCK_SIZE 64 + +struct _sha256_state { + u64 length; + u32 state[8], curlen; + u8 buf[SHA256_BLOCK_SIZE]; +}; + +void _sha256_init(struct _sha256_state *md); +int sha256_process(struct _sha256_state *md, const unsigned char *in, + unsigned long inlen); +int sha256_done(struct _sha256_state *md, unsigned char *out); + +#endif /* SHA256_I_H */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/wlancrypto_wrap.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/wlancrypto_wrap.h index dd75725ca147..919931db3127 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/wlancrypto_wrap.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/crypto/wlancrypto_wrap.h @@ -1,35 +1,35 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* - * wlantest - IEEE 802.11 protocol monitoring and testing tool - * Copyright (c) 2010-2013, Jouni Malinen - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#ifndef WLANCRYPTO_WRAP_H -#define WLANCRYPTO_WRAP_H - -int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, - u8 *mac); - -u8* ccmp_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr, - const u8 *data, size_t data_len, size_t *decrypted_len); -u8* ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos, - u8 *pn, int keyid, size_t *encrypted_len); -u8* ccmp_encrypt_pv1(const u8 *tk, const u8 *a1, const u8 *a2, const u8 *a3, - const u8 *frame, size_t len, - size_t hdrlen, const u8 *pn, int keyid, - size_t *encrypted_len); -u8* ccmp_256_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr, - const u8 *data, size_t data_len, size_t *decrypted_len); -u8* ccmp_256_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, - u8 *qos, u8 *pn, int keyid, size_t *encrypted_len); - -u8* gcmp_decrypt(const u8 *tk, size_t tk_len, const struct ieee80211_hdr *hdr, - const u8 *data, size_t data_len, size_t *decrypted_len); -u8* gcmp_encrypt(const u8 *tk, size_t tk_len, const u8 *frame, size_t len, - size_t hdrlen, const u8 *qos, - const u8 *pn, int keyid, size_t *encrypted_len); - -#endif /* WLANCRYPTO_WRAP_H */ +/* + * wlantest - IEEE 802.11 protocol monitoring and testing tool + * Copyright (c) 2010-2013, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef WLANCRYPTO_WRAP_H +#define WLANCRYPTO_WRAP_H + +int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, + u8 *mac); + +u8* ccmp_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr, + const u8 *data, size_t data_len, size_t *decrypted_len); +u8* ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos, + u8 *pn, int keyid, size_t *encrypted_len); +u8* ccmp_encrypt_pv1(const u8 *tk, const u8 *a1, const u8 *a2, const u8 *a3, + const u8 *frame, size_t len, + size_t hdrlen, const u8 *pn, int keyid, + size_t *encrypted_len); +u8* ccmp_256_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr, + const u8 *data, size_t data_len, size_t *decrypted_len); +u8* ccmp_256_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, + u8 *qos, u8 *pn, int keyid, size_t *encrypted_len); + +u8* gcmp_decrypt(const u8 *tk, size_t tk_len, const struct ieee80211_hdr *hdr, + const u8 *data, size_t data_len, size_t *decrypted_len); +u8* gcmp_encrypt(const u8 *tk, size_t tk_len, const u8 *frame, size_t len, + size_t hdrlen, const u8 *qos, + const u8 *pn, int keyid, size_t *encrypted_len); + +#endif /* WLANCRYPTO_WRAP_H */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/efuse/rtw_efuse.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/efuse/rtw_efuse.c index ba0218791920..1f301e651517 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/efuse/rtw_efuse.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/efuse/rtw_efuse.c @@ -207,6 +207,10 @@ BOOLEAN efuse_IsMasked(PADAPTER pAdapter, u16 Offset) if (IS_HARDWARE_TYPE_8814B(pAdapter)) return (IS_MASKED(8814B, _MUSB, Offset)) ? TRUE : FALSE; #endif +#if defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_8723F(pAdapter)) + return (IS_MASKED(8723F, _MUSB, Offset)) ? TRUE : FALSE; +#endif #endif /*CONFIG_USB_HCI*/ #ifdef CONFIG_PCI_HCI @@ -298,6 +302,10 @@ BOOLEAN efuse_IsMasked(PADAPTER pAdapter, u16 Offset) if (IS_HARDWARE_TYPE_8822C(pAdapter)) return (IS_MASKED(8822C, _MSDIO, Offset)) ? TRUE : FALSE; #endif +#if defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_8723F(pAdapter)) + return (IS_MASKED(8723F, _MSDIO, Offset)) ? TRUE : FALSE; +#endif #endif /*CONFIG_SDIO_HCI*/ return FALSE; @@ -363,6 +371,10 @@ void rtw_efuse_mask_array(PADAPTER pAdapter, u8 *pArray) if (IS_HARDWARE_TYPE_8814B(pAdapter)) GET_MASK_ARRAY(8814B, _MUSB, pArray); #endif +#if defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_8723F(pAdapter)) + GET_MASK_ARRAY(8723F, _MUSB, pArray); +#endif #endif /*CONFIG_USB_HCI*/ #ifdef CONFIG_PCI_HCI @@ -453,6 +465,10 @@ void rtw_efuse_mask_array(PADAPTER pAdapter, u8 *pArray) if (IS_HARDWARE_TYPE_8822C(pAdapter)) GET_MASK_ARRAY(8822C , _MSDIO, pArray); #endif +#if defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_8723F(pAdapter)) + GET_MASK_ARRAY(8723F, _MSDIO, pArray); +#endif #endif /*CONFIG_SDIO_HCI*/ } @@ -517,6 +533,10 @@ u16 rtw_get_efuse_mask_arraylen(PADAPTER pAdapter) return GET_MASK_ARRAY_LEN(8814B, _MUSB); } #endif +#if defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_8723F(pAdapter)) + return GET_MASK_ARRAY_LEN(8723F, _MUSB); +#endif #endif /*CONFIG_USB_HCI*/ #ifdef CONFIG_PCI_HCI @@ -607,6 +627,10 @@ u16 rtw_get_efuse_mask_arraylen(PADAPTER pAdapter) if (IS_HARDWARE_TYPE_8822C(pAdapter)) return GET_MASK_ARRAY_LEN(8822C, _MSDIO); #endif +#if defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_8723F(pAdapter)) + return GET_MASK_ARRAY_LEN(8723F, _MSDIO); +#endif #endif/*CONFIG_SDIO_HCI*/ return 0; } @@ -1045,7 +1069,7 @@ u8 efuse_bt_GetCurrentSize(PADAPTER adapter, u16 *usesize) u16 efuse_bt_GetMaxSize(PADAPTER adapter) { - return EFUSE_BT_REAL_CONTENT_LEN; + return EFUSE_BT_REAL_CONTENT_LEN - EFUSE_PROTECT_BYTES_BANK; } void EFUSE_GetEfuseDefinition(PADAPTER adapter, u8 efusetype, u8 type, void *out, BOOLEAN test) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/mesh/rtw_mesh.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/mesh/rtw_mesh.c index a160c716d0a7..380fc8933596 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/mesh/rtw_mesh.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/mesh/rtw_mesh.c @@ -1040,6 +1040,7 @@ u8 rtw_mesh_select_operating_ch(_adapter *adapter) int ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, scanned->network.Configuration.DSConfig); if (ch_set_idx >= 0 + && !(rfctl->channel_set[ch_set_idx].flags & RTW_CHF_NO_IR) && !CH_IS_NON_OCP(&rfctl->channel_set[ch_set_idx]) ) { u8 nop, accept; @@ -3307,6 +3308,7 @@ void rtw_mesh_cfg_init_peer_sel_policy(struct rtw_mesh_cfg *mcfg) void rtw_mesh_cfg_init(_adapter *adapter) { + struct registry_priv *regsty = adapter_to_regsty(adapter); struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg; mcfg->max_peer_links = RTW_MESH_MAX_PEER_LINKS; @@ -3337,8 +3339,8 @@ void rtw_mesh_cfg_init(_adapter *adapter) #endif #if CONFIG_RTW_MESH_DATA_BMC_TO_UC - mcfg->b2u_flags_msrc = 0; - mcfg->b2u_flags_mfwd = RTW_MESH_B2U_GA_UCAST; + mcfg->b2u_flags_msrc = regsty->msrc_b2u_flags; + mcfg->b2u_flags_mfwd = regsty->mfwd_b2u_flags; #endif } @@ -3546,7 +3548,7 @@ endlookup: static bool rtw_mesh_data_bmc_to_uc(_adapter *adapter , const u8 *da, const u8 *sa, const u8 *mda, const u8 *msa , u8 ae_need, const u8 *ori_ta, u8 mfwd_ttl - , _list *b2u_list, u8 *b2u_num, u32 *b2u_mseq) + , u16 os_qid, _list *b2u_list, u8 *b2u_num, u32 *b2u_mseq) { struct sta_priv *stapriv = &adapter->stapriv; struct xmit_priv *xmitpriv = &adapter->xmitpriv; @@ -3589,7 +3591,7 @@ static bool rtw_mesh_data_bmc_to_uc(_adapter *adapter || is_zero_mac_addr(sta->cmn.mac_addr)) continue; - b2uframe = rtw_alloc_xmitframe(xmitpriv); + b2uframe = rtw_alloc_xmitframe(xmitpriv, os_qid); if (!b2uframe) { bmc_need = _TRUE; break; @@ -3629,7 +3631,7 @@ void dump_mesh_b2u_flags(void *sel, _adapter *adapter) } #endif /* CONFIG_RTW_MESH_DATA_BMC_TO_UC */ -int rtw_mesh_addr_resolve(_adapter *adapter, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list) +int rtw_mesh_addr_resolve(_adapter *adapter, u16 os_qid, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list) { struct pkt_file pktfile; struct ethhdr etherhdr; @@ -3691,7 +3693,7 @@ int rtw_mesh_addr_resolve(_adapter *adapter, struct xmit_frame *xframe, _pkt *pk bmc_need = rtw_mesh_data_bmc_to_uc(adapter , etherhdr.h_dest, etherhdr.h_source , etherhdr.h_dest, adapter_mac_addr(adapter), ae_need, NULL, 0 - , b2u_list, &b2u_num, &b2u_mseq); + , os_qid, b2u_list, &b2u_num, &b2u_mseq); if (bmc_need == _FALSE) { res = RTW_BMC_NO_NEED; goto exit; @@ -3868,7 +3870,7 @@ int rtw_mesh_rx_data_validate_hdr(_adapter *adapter, union recv_frame *rframe, s goto exit; switch (rattrib->to_fr_ds) { - case 1: + case 2: if (!IS_MCAST(GetAddr1Ptr(whdr))) goto exit; *sta = rtw_get_stainfo(stapriv, get_addr2_ptr(whdr)); @@ -3956,7 +3958,7 @@ int rtw_mesh_rx_data_validate_mctrl(_adapter *adapter, union recv_frame *rframe ae = mctrl->flags & MESH_FLAGS_AE; mlen = ae_to_mesh_ctrl_len[ae]; switch (rattrib->to_fr_ds) { - case 1: + case 2: *da = mda; if (ae == MESH_FLAGS_AE_A4) *sa = mctrl->eaddr1; @@ -4066,6 +4068,7 @@ int rtw_mesh_rx_msdu_act_check(union recv_frame *rframe , const u8 *mda, const u8 *msa , const u8 *da, const u8 *sa , struct rtw_ieee80211s_hdr *mctrl + , u8 *msdu, enum rtw_rx_llc_hdl llc_hdl , struct xmit_frame **fwd_frame, _list *b2u_list) { _adapter *adapter = rframe->u.hdr.adapter; @@ -4075,6 +4078,7 @@ int rtw_mesh_rx_msdu_act_check(union recv_frame *rframe struct rtw_mesh_path *mppath; u8 is_mda_bmc = IS_MCAST(mda); u8 is_mda_self = !is_mda_bmc && _rtw_memcmp(mda, adapter_mac_addr(adapter), ETH_ALEN); + u16 os_qid; struct xmit_frame *xframe; struct pkt_attrib *xattrib; u8 fwd_ra[ETH_ALEN] = {0}; @@ -4302,6 +4306,8 @@ fwd_chk: goto exit; } + os_qid = rtw_os_recv_select_queue(msdu, llc_hdl); + #if CONFIG_RTW_MESH_DATA_BMC_TO_UC _rtw_init_listhead(b2u_list); #endif @@ -4315,13 +4321,13 @@ fwd_chk: ) { bmc_need = rtw_mesh_data_bmc_to_uc(adapter , da, sa, mda, msa, ae_need, rframe->u.hdr.psta->cmn.mac_addr, mctrl->ttl - 1 - , b2u_list, &b2u_num, &fwd_mseq); + , os_qid, b2u_list, &b2u_num, &fwd_mseq); } if (bmc_need == _TRUE) #endif { - xframe = rtw_alloc_xmitframe(&adapter->xmitpriv); + xframe = rtw_alloc_xmitframe(&adapter->xmitpriv, os_qid); if (!xframe) { #ifdef DBG_TX_DROP_FRAME RTW_INFO("DBG_TX_DROP_FRAME "FUNC_ADPT_FMT" rtw_alloc_xmitframe fail\n" diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/mesh/rtw_mesh.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/mesh/rtw_mesh.h index 14ef2f62536b..01b591d645f4 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/mesh/rtw_mesh.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/mesh/rtw_mesh.h @@ -503,7 +503,7 @@ void rtw_mesh_deinit_mesh_info(_adapter *adapter); void dump_mesh_b2u_flags(void *sel, _adapter *adapter); #endif -int rtw_mesh_addr_resolve(_adapter *adapter, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list); +int rtw_mesh_addr_resolve(_adapter *adapter, u16 os_qid, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list); s8 rtw_mesh_tx_set_whdr_mctrl_len(u8 mesh_frame_mode, struct pkt_attrib *attrib); void rtw_mesh_tx_build_mctrl(_adapter *adapter, struct pkt_attrib *attrib, u8 *buf); @@ -520,6 +520,7 @@ int rtw_mesh_rx_msdu_act_check(union recv_frame *rframe , const u8 *mda, const u8 *msa , const u8 *da, const u8 *sa , struct rtw_ieee80211s_hdr *mctrl + , u8 *msdu, enum rtw_rx_llc_hdl llc_hdl , struct xmit_frame **fwd_frame, _list *b2u_list); void dump_mesh_stats(void *sel, _adapter *adapter); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/mesh/rtw_mesh_hwmp.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/mesh/rtw_mesh_hwmp.c index ab7694ac9034..848918ab49fb 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/mesh/rtw_mesh_hwmp.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/mesh/rtw_mesh_hwmp.c @@ -395,162 +395,6 @@ int rtw_mesh_path_error_tx(_adapter *adapter, return 0; } -static u32 rtw_get_vht_bitrate(u8 mcs, u8 bw, u8 nss, u8 sgi) -{ - static const u32 base[4][10] = { - { 6500000, - 13000000, - 19500000, - 26000000, - 39000000, - 52000000, - 58500000, - 65000000, - 78000000, - /* not in the spec, but some devices use this: */ - 86500000, - }, - { 13500000, - 27000000, - 40500000, - 54000000, - 81000000, - 108000000, - 121500000, - 135000000, - 162000000, - 180000000, - }, - { 29300000, - 58500000, - 87800000, - 117000000, - 175500000, - 234000000, - 263300000, - 292500000, - 351000000, - 390000000, - }, - { 58500000, - 117000000, - 175500000, - 234000000, - 351000000, - 468000000, - 526500000, - 585000000, - 702000000, - 780000000, - }, - }; - u32 bitrate; - int bw_idx; - - if (mcs > 9) { - RTW_HWMP_INFO("Invalid mcs = %d\n", mcs); - return 0; - } - - if (nss > 4 || nss < 1) { - RTW_HWMP_INFO("Now only support nss = 1, 2, 3, 4\n"); - } - - switch (bw) { - case CHANNEL_WIDTH_160: - bw_idx = 3; - break; - case CHANNEL_WIDTH_80: - bw_idx = 2; - break; - case CHANNEL_WIDTH_40: - bw_idx = 1; - break; - case CHANNEL_WIDTH_20: - bw_idx = 0; - break; - default: - RTW_HWMP_INFO("bw = %d currently not supported\n", bw); - return 0; - } - - bitrate = base[bw_idx][mcs]; - bitrate *= nss; - - if (sgi) - bitrate = (bitrate / 9) * 10; - - /* do NOT round down here */ - return (bitrate + 50000) / 100000; -} - -static u32 rtw_get_ht_bitrate(u8 mcs, u8 bw, u8 sgi) -{ - int modulation, streams, bitrate; - - /* the formula below does only work for MCS values smaller than 32 */ - if (mcs >= 32) { - RTW_HWMP_INFO("Invalid mcs = %d\n", mcs); - return 0; - } - - if (bw > 1) { - RTW_HWMP_INFO("Now HT only support bw = 0(20Mhz), 1(40Mhz)\n"); - return 0; - } - - modulation = mcs & 7; - streams = (mcs >> 3) + 1; - - bitrate = (bw == 1) ? 13500000 : 6500000; - - if (modulation < 4) - bitrate *= (modulation + 1); - else if (modulation == 4) - bitrate *= (modulation + 2); - else - bitrate *= (modulation + 3); - - bitrate *= streams; - - if (sgi) - bitrate = (bitrate / 9) * 10; - - /* do NOT round down here */ - return (bitrate + 50000) / 100000; -} - -/** - * @bw: 0(20Mhz), 1(40Mhz), 2(80Mhz), 3(160Mhz) - * @rate_idx: DESC_RATEXXXX & 0x7f - * @sgi: DESC_RATEXXXX >> 7 - * Returns: bitrate in 100kbps - */ -static u32 rtw_desc_rate_to_bitrate(u8 bw, u8 rate_idx, u8 sgi) -{ - u32 bitrate; - - if (rate_idx <= DESC_RATE54M){ - u16 ofdm_rate[12] = {10, 20, 55, 110, - 60, 90, 120, 180, 240, 360, 480, 540}; - bitrate = ofdm_rate[rate_idx]; - } else if ((DESC_RATEMCS0 <= rate_idx) && - (rate_idx <= DESC_RATEMCS31)) { - u8 mcs = rate_idx - DESC_RATEMCS0; - bitrate = rtw_get_ht_bitrate(mcs, bw, sgi); - } else if ((DESC_RATEVHTSS1MCS0 <= rate_idx) && - (rate_idx <= DESC_RATEVHTSS4MCS9)) { - u8 mcs = (rate_idx - DESC_RATEVHTSS1MCS0) % 10; - u8 nss = ((rate_idx - DESC_RATEVHTSS1MCS0) / 10) + 1; - bitrate = rtw_get_vht_bitrate(mcs, bw, nss, sgi); - } else { - /* 60Ghz ??? */ - bitrate = 1; - } - - return bitrate; -} - static u32 rtw_airtime_link_metric_get(_adapter *adapter, struct sta_info *sta) { struct dm_struct *dm = adapter_to_phydm(adapter); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ap.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ap.c index e852c652d9e8..9b7bb0d03403 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ap.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ap.c @@ -172,7 +172,7 @@ void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *d u8 bmatch = _FALSE; u8 *pie = pnetwork->IEs; u8 *p = NULL, *dst_ie = NULL, *premainder_ie = NULL, *pbackup_remainder_ie = NULL; - u32 i, offset, ielen, ie_offset, remainder_ielen = 0; + u32 i, offset, ielen = 0, ie_offset, remainder_ielen = 0; for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;) { pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i); @@ -428,6 +428,10 @@ void expire_timeout_chk(_adapter *padapter) } #endif +#ifdef CONFIG_RTW_WDS + rtw_wds_path_expire(padapter); +#endif + #ifdef CONFIG_MCC_MODE /* then driver may check fail due to not recv client's frame under sitesurvey, * don't expire timeout chk under MCC under sitesurvey */ @@ -513,20 +517,17 @@ void expire_timeout_chk(_adapter *padapter) if (chk_sta_is_alive(psta) || !psta->expire_to) { psta->expire_to = pstapriv->expire_to; psta->keep_alive_trycnt = 0; -#ifdef CONFIG_TX_MCAST2UNI + #if !defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && defined(CONFIG_80211N_HT) psta->under_exist_checking = 0; -#endif /* CONFIG_TX_MCAST2UNI */ + #endif } else psta->expire_to--; -#ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK -#ifdef CONFIG_80211N_HT -#ifdef CONFIG_TX_MCAST2UNI +#if !defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && defined(CONFIG_80211N_HT) if ((psta->flags & WLAN_STA_HT) && (psta->htpriv.agg_enable_bitmap || psta->under_exist_checking)) { /* check sta by delba(addba) for 11n STA */ /* ToDo: use CCX report to check for all STAs */ /* RTW_INFO("asoc check by DELBA/ADDBA! (pstapriv->expire_to=%d s)(psta->expire_to=%d s), [%02x, %d]\n", pstapriv->expire_to*2, psta->expire_to*2, psta->htpriv.agg_enable_bitmap, psta->under_exist_checking); */ - if (psta->expire_to <= (pstapriv->expire_to - 50)) { RTW_INFO("asoc expire by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to - psta->expire_to) * 2); psta->under_exist_checking = 0; @@ -540,9 +541,7 @@ void expire_timeout_chk(_adapter *padapter) psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */ } } -#endif /* CONFIG_TX_MCAST2UNI */ -#endif /* CONFIG_80211N_HT */ -#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */ +#endif /* !defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && defined(CONFIG_80211N_HT) */ if (psta->expire_to <= 0) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -1209,6 +1208,19 @@ void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta) _exit_critical_bh(&psta->lock, &irqL); } +#ifdef CONFIG_RTW_80211K +static void update_rm_cap(u8 *frame_head, _adapter *pa, u32 pktlen, int offset) +{ + u8 *res; + sint len; + + res = rtw_get_ie(frame_head + offset, _EID_RRM_EN_CAP_IE_, &len, + pktlen - offset); + if (res != NULL) + _rtw_memcpy((void *)pa->rmpriv.rm_en_cap_def, (res + 2), len); +} +#endif + static void update_ap_info(_adapter *padapter, struct sta_info *psta) { struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); @@ -1643,7 +1655,8 @@ void start_bss_network(_adapter *padapter, struct createbss_parm *parm) WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network); struct dvobj_priv *pdvobj = padapter->dvobj; s16 req_ch = REQ_CH_NONE, req_bw = REQ_BW_NONE, req_offset = REQ_OFFSET_NONE; - u8 ch_to_set = 0, bw_to_set, offset_to_set; + u8 u_ch = 0, u_bw, u_offset; + bool set_u_ch; u8 doiqk = _FALSE; /* use for check ch bw offset can be allowed or not */ u8 chbw_allow = _TRUE; @@ -1726,7 +1739,7 @@ void start_bss_network(_adapter *padapter, struct createbss_parm *parm) chbw_decision: ifbmp_ch_changed = rtw_ap_chbw_decision(padapter, parm->ifbmp, parm->excl_ifbmp , req_ch, req_bw, req_offset - , &ch_to_set, &bw_to_set, &offset_to_set, &chbw_allow); + , &u_ch, &u_bw, &u_offset, &chbw_allow, &set_u_ch); for (i = 0; i < pdvobj->iface_nums; i++) { if (!(parm->ifbmp & BIT(i)) || !pdvobj->padapters[i]) @@ -1773,17 +1786,36 @@ chbw_decision: rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); } - if (ch_to_set != 0) { - set_channel_bwmode(padapter, ch_to_set, offset_to_set, bw_to_set); - rtw_mi_update_union_chan_inf(padapter, ch_to_set, offset_to_set, bw_to_set); - } + if (set_u_ch) + set_channel_bwmode(padapter, u_ch, u_offset, u_bw); doiqk = _FALSE; rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); #ifdef CONFIG_MCC_MODE /* after set_channel_bwmode for backup IQK */ - rtw_hal_set_mcc_setting_start_bss_network(padapter, chbw_allow); + if (rtw_hal_set_mcc_setting_start_bss_network(padapter, chbw_allow) == _FAIL) { + /* MCC setting fail, update to buddy's channel */ + rtw_mi_get_ch_setting_union_no_self(padapter, &u_ch, &u_bw, &u_offset); + pnetwork->Configuration.DSConfig = u_ch; + padapter->mlmeextpriv.cur_channel = u_ch; + padapter->mlmeextpriv.cur_bwmode = u_bw; + padapter->mlmeextpriv.cur_ch_offset = u_offset; + + if (ifbmp_ch_changed == 0) { + u8 ht_option = 0; + +#ifdef CONFIG_80211N_HT + ht_option = padapter->mlmepriv.htpriv.ht_option; +#endif + + rtw_cfg80211_ch_switch_notify(padapter + , padapter->mlmeextpriv.cur_channel + , padapter->mlmeextpriv.cur_bwmode + , padapter->mlmeextpriv.cur_ch_offset + , ht_option, 0); + } + } #endif #if defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) @@ -1802,11 +1834,13 @@ chbw_decision: , pdvobj->padapters[i]->mlmeextpriv.cur_channel , pdvobj->padapters[i]->mlmeextpriv.cur_bwmode , pdvobj->padapters[i]->mlmeextpriv.cur_ch_offset - , ht_option); + , ht_option, 0); } } #endif /* defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) */ + rtw_rfctl_update_op_mode(adapter_to_rfctl(padapter), parm->ifbmp, 1); + if (DUMP_ADAPTERS_STATUS) { RTW_INFO(FUNC_ADPT_FMT" done\n", FUNC_ADPT_ARG(padapter)); dump_adapters_status(RTW_DBGDUMP , adapter_to_dvobj(padapter)); @@ -1897,7 +1931,8 @@ update_beacon: #endif /* !defined(CONFIG_INTERRUPT_BASED_TXBCN) */ #ifdef CONFIG_FW_HANDLE_TXBCN - if (mlme_act != MLME_OPCH_SWITCH) + if (mlme_act != MLME_OPCH_SWITCH + && pmlmeext->bstart_bss == _TRUE) rtw_ap_mbid_bcn_en(padapter, padapter->vap_id); #endif } @@ -1942,6 +1977,7 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) /* ERP Information element */ /* Extended supported rates */ /* WPA/WPA2 */ + /* Radio Resource Management */ /* Wi-Fi Wireless Multimedia Extensions */ /* ht_capab, ht_oper */ /* WPS IE */ @@ -2192,6 +2228,12 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) } psecuritypriv->mfp_opt = mfp_opt; +#ifdef CONFIG_RTW_80211K + /* RRM */ + update_rm_cap(pbuf, padapter, len, _BEACON_IE_OFFSET_); + +#endif /* CONFIG_RTW_80211K */ + /* wmm */ ie_len = 0; pmlmepriv->qospriv.qos_option = 0; @@ -2231,11 +2273,12 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor = MAX_AMPDU_FACTOR_64K; struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p + 2); +#ifdef CONFIG_RTW_DEBUG if (0) { RTW_INFO(FUNC_ADPT_FMT" HT_CAP_IE from upper layer:\n", FUNC_ADPT_ARG(padapter)); dump_ht_cap_ie_content(RTW_DBGDUMP, p + 2, ie_len); } - +#endif /* CONFIG_RTW_DEBUG */ pHT_caps_ie = p; ht_cap = _TRUE; @@ -2331,11 +2374,12 @@ int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) #endif /* CONFIG_BEAMFORMING */ _rtw_memcpy(&pmlmepriv->htpriv.ht_cap, p + 2, ie_len); - +#ifdef CONFIG_RTW_DEBUG if (0) { RTW_INFO(FUNC_ADPT_FMT" HT_CAP_IE driver masked:\n", FUNC_ADPT_ARG(padapter)); dump_ht_cap_ie_content(RTW_DBGDUMP, p + 2, ie_len); } +#endif /* CONFIG_RTW_DEBUG */ } /* parsing HT_INFO_IE */ @@ -3852,10 +3896,19 @@ u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reaso psta->pauth_frame = NULL; psta->auth_len = 0; } + if (psta->passoc_req && psta->assoc_req_len > 0) { + rtw_mfree(psta->passoc_req , psta->assoc_req_len); + psta->passoc_req = NULL; + psta->assoc_req_len = 0; + } #endif /* CONFIG_IOCTL_CFG80211 */ _exit_critical_bh(&psta->lock, &irqL); if (!MLME_IS_MESH(padapter)) { + #ifdef CONFIG_RTW_WDS + rtw_wds_path_flush_by_nexthop(psta); + #endif + #ifdef CONFIG_IOCTL_CFG80211 #ifdef COMPAT_KERNEL_RELEASE rtw_cfg80211_indicate_sta_disassoc(padapter, psta->cmn.mac_addr, reason); @@ -4146,6 +4199,11 @@ void start_ap_mode(_adapter *padapter) for (i = 0 ; i < pstapriv->max_aid; i++) pstapriv->sta_aid[i] = NULL; +#ifdef CONFIG_RTW_WDS + if (MLME_IS_AP(padapter)) + rtw_wds_pathtbl_init(padapter); +#endif + psta = rtw_get_bcmc_stainfo(padapter); /*_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);*/ if (psta) @@ -4193,6 +4251,8 @@ void stop_ap_mode(_adapter *padapter) rtw_dfs_rd_en_decision(padapter, self_action, 0); #endif + rtw_rfctl_update_op_mode(adapter_to_rfctl(padapter), BIT(padapter->iface_id), 0); + /* free scan queue */ rtw_free_network_queue(padapter, _TRUE); @@ -4214,6 +4274,12 @@ void stop_ap_mode(_adapter *padapter) } pmlmepriv->ap_isolate = 0; +#ifdef CONFIG_RTW_WDS + adapter_set_use_wds(padapter, 0); +#endif +#ifdef CONFIG_RTW_MULTI_AP + padapter->multi_ap = 0; +#endif rtw_free_mlme_priv_ie_data(pmlmepriv); #ifdef CONFIG_SUPPORT_MULTI_BCN @@ -4260,6 +4326,10 @@ void stop_ap_mode(_adapter *padapter) rtw_btcoex_MediaStatusNotify(padapter, 0); /* disconnect */ #endif +#ifdef CONFIG_RTW_WDS + if (MLME_IS_AP(padapter)) + rtw_wds_pathtbl_unregister(padapter); +#endif } #endif /* CONFIG_NATIVEAP_MLME */ @@ -4461,15 +4531,22 @@ static u8 rtw_ap_update_chbw_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp static u8 rtw_ap_ch_specific_chk(_adapter *adapter, u8 ch, u8 *bw, u8 *offset, const char *caller) { - struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); - RT_CHANNEL_INFO *chset = adapter_to_chset(adapter); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + RT_CHANNEL_INFO *chset = rfctl->channel_set; + int ch_idx; u8 ret = _SUCCESS; - if (rtw_chset_search_ch(chset, ch) < 0) { + ch_idx = rtw_chset_search_ch(chset, ch); + if (ch_idx < 0) { RTW_WARN("%s ch:%u doesn't fit in chplan\n", caller, ch); ret = _FAIL; goto exit; } + if (chset[ch_idx].flags & RTW_CHF_NO_IR) { + RTW_WARN("%s ch:%u is passive\n", caller, ch); + ret = _FAIL; + goto exit; + } rtw_adjust_chbw(adapter, ch, bw, offset); @@ -4479,8 +4556,8 @@ static u8 rtw_ap_ch_specific_chk(_adapter *adapter, u8 ch, u8 *bw, u8 *offset, c goto exit; } - while (!rtw_chset_is_chbw_valid(chset, ch, *bw, *offset) - || (rtw_odm_dfs_domain_unknown(dvobj) && rtw_is_dfs_chbw(ch, *bw, *offset)) + while (!rtw_chset_is_chbw_valid(chset, ch, *bw, *offset, 0, 0) + || (rtw_rfctl_dfs_domain_unknown(rfctl) && rtw_chset_is_dfs_chbw(chset, ch, *bw, *offset)) ) { if (*bw > CHANNEL_WIDTH_20) (*bw)--; @@ -4490,7 +4567,7 @@ static u8 rtw_ap_ch_specific_chk(_adapter *adapter, u8 ch, u8 *bw, u8 *offset, c } } - if (rtw_odm_dfs_domain_unknown(dvobj) && rtw_is_dfs_chbw(ch, *bw, *offset)) { + if (rtw_rfctl_dfs_domain_unknown(rfctl) && rtw_chset_is_dfs_chbw(chset, ch, *bw, *offset)) { RTW_WARN("%s DFS channel %u can't be used\n", caller, ch); ret = _FAIL; goto exit; @@ -4503,18 +4580,17 @@ exit: static bool rtw_ap_choose_chbw(_adapter *adapter, u8 sel_ch, u8 max_bw, u8 cur_ch , u8 *ch, u8 *bw, u8 *offset, bool by_int_info, u8 mesh_only, const char *caller) { - struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); bool ch_avail = _FALSE; #if defined(CONFIG_DFS_MASTER) - if (!rtw_odm_dfs_domain_unknown(dvobj)) { + if (!rtw_rfctl_dfs_domain_unknown(rfctl)) { if (rfctl->radar_detected && rfctl->dbg_dfs_choose_dfs_ch_first ) { ch_avail = rtw_choose_shortest_waiting_ch(rfctl, sel_ch, max_bw , ch, bw, offset - , RTW_CHF_2G | RTW_CHF_NON_DFS + , RTW_CHF_DFS, 0 , cur_ch, by_int_info, mesh_only); if (ch_avail == _TRUE) { RTW_INFO("%s choose 5G DFS channel for debug\n", caller); @@ -4523,29 +4599,29 @@ static bool rtw_ap_choose_chbw(_adapter *adapter, u8 sel_ch, u8 max_bw, u8 cur_c } if (rfctl->radar_detected - && rfctl->dfs_ch_sel_d_flags + && (rfctl->dfs_ch_sel_e_flags || rfctl->dfs_ch_sel_d_flags) ) { ch_avail = rtw_choose_shortest_waiting_ch(rfctl, sel_ch, max_bw , ch, bw, offset - , rfctl->dfs_ch_sel_d_flags + , rfctl->dfs_ch_sel_e_flags, rfctl->dfs_ch_sel_d_flags , cur_ch, by_int_info, mesh_only); if (ch_avail == _TRUE) { - RTW_INFO("%s choose with dfs_ch_sel_d_flags:0x%02x for debug\n" - , caller, rfctl->dfs_ch_sel_d_flags); + RTW_INFO("%s choose with dfs_ch_sel_ e_flags:0x%02x d_flags:0x%02x for debug\n" + , caller, rfctl->dfs_ch_sel_e_flags, rfctl->dfs_ch_sel_d_flags); goto exit; } } ch_avail = rtw_choose_shortest_waiting_ch(rfctl, sel_ch, max_bw , ch, bw, offset - , 0 + , 0, 0 , cur_ch, by_int_info, mesh_only); } else #endif /* defined(CONFIG_DFS_MASTER) */ { ch_avail = rtw_choose_shortest_waiting_ch(rfctl, sel_ch, max_bw , ch, bw, offset - , RTW_CHF_DFS + , 0, RTW_CHF_DFS , cur_ch, by_int_info, mesh_only); } #if defined(CONFIG_DFS_MASTER) @@ -4559,7 +4635,7 @@ exit: u8 rtw_ap_chbw_decision(_adapter *adapter, u8 ifbmp, u8 excl_ifbmp , s16 req_ch, s8 req_bw, s8 req_offset - , u8 *ch, u8 *bw, u8 *offset, u8 *chbw_allow) + , u8 *ch, u8 *bw, u8 *offset, u8 *chbw_allow, bool *set_u_ch) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); RT_CHANNEL_INFO *chset = adapter_to_chset(adapter); @@ -4576,13 +4652,14 @@ u8 rtw_ap_chbw_decision(_adapter *adapter, u8 ifbmp, u8 excl_ifbmp WLAN_BSSID_EX *network; struct mi_state mstate; struct mi_state mstate_others; - bool set_u_ch = _FALSE; u8 ifbmp_others = 0xFF & ~ifbmp & ~excl_ifbmp; u8 ifbmp_ch_changed = 0; bool ifbmp_all_mesh = 0; _adapter *iface; int i; + *set_u_ch = _FALSE; + #ifdef CONFIG_RTW_MESH for (i = 0; i < dvobj->iface_nums; i++) if ((ifbmp & BIT(i)) && dvobj->padapters) @@ -4684,8 +4761,8 @@ u8 rtw_ap_chbw_decision(_adapter *adapter, u8 ifbmp, u8 excl_ifbmp if (rtw_is_chbw_grouped(u_ch, u_bw, u_offset, dec_ch[i], dec_bw[i], dec_offset[i])) { rtw_chset_sync_chbw(chset , &dec_ch[i], &dec_bw[i], &dec_offset[i] - , &u_ch, &u_bw, &u_offset); - set_u_ch = _TRUE; + , &u_ch, &u_bw, &u_offset, 1, 0); + *set_u_ch = _TRUE; /* channel bw offset can be allowed, not need MCC */ *chbw_allow = _TRUE; @@ -4745,7 +4822,7 @@ u8 rtw_ap_chbw_decision(_adapter *adapter, u8 ifbmp, u8 excl_ifbmp #endif /* CONFIG_MCC_MODE */ if (req_ch == 0 && dec_bw[i] > u_bw - && rtw_is_dfs_chbw(u_ch, u_bw, u_offset) + && rtw_chset_is_dfs_chbw(chset, u_ch, u_bw, u_offset) ) { /* request comes from upper layer, prevent from additional channel waiting */ dec_bw[i] = u_bw; @@ -4756,10 +4833,10 @@ u8 rtw_ap_chbw_decision(_adapter *adapter, u8 ifbmp, u8 excl_ifbmp /* follow */ rtw_chset_sync_chbw(chset , &dec_ch[i], &dec_bw[i], &dec_offset[i] - , &u_ch, &u_bw, &u_offset); + , &u_ch, &u_bw, &u_offset, 1, 0); } - set_u_ch = _TRUE; + *set_u_ch = _TRUE; } else { /* autonomous decision */ @@ -4879,7 +4956,7 @@ update_bss_chbw: #endif } - set_u_ch = _TRUE; + *set_u_ch = _TRUE; } ifbmp_ch_changed = rtw_ap_update_chbw_by_ifbmp(dvobj, ifbmp @@ -4890,16 +4967,18 @@ update_bss_chbw: if (u_ch != 0) RTW_INFO("%s union:%u,%u,%u\n", __func__, u_ch, u_bw, u_offset); - if (rtw_mi_check_fwstate(adapter, WIFI_UNDER_SURVEY)) { - /* scanning, leave ch setting to scan state machine */ - set_u_ch = _FALSE; - } - - if (set_u_ch == _TRUE) { + if (*set_u_ch == _TRUE) { + rtw_mi_update_union_chan_inf(adapter, u_ch, u_offset, u_bw); *ch = u_ch; *bw = u_bw; *offset = u_offset; } + + if (rtw_mi_check_fwstate(adapter, WIFI_UNDER_SURVEY)) { + /* scanning, leave ch setting to scan state machine */ + *set_u_ch = _FALSE; + } + exit: return ifbmp_ch_changed; } @@ -5466,6 +5545,383 @@ exit: return; } +void rtw_ap_parse_sta_multi_ap_ie(_adapter *adapter, struct sta_info *sta, u8 *ies, int ies_len) +{ + sta->flags &= ~WLAN_STA_MULTI_AP; + +#ifdef CONFIG_RTW_MULTI_AP + if (adapter->multi_ap + && (rtw_get_multi_ap_ie_ext(ies, ies_len) & MULTI_AP_BACKHAUL_STA) + ) { + if (adapter->multi_ap & MULTI_AP_BACKHAUL_BSS) /* with backhaul bss, enable WDS */ + sta->flags |= WLAN_STA_MULTI_AP | WLAN_STA_WDS; + else if (adapter->multi_ap & MULTI_AP_FRONTHAUL_BSS) /* fronthaul bss only */ + sta->flags |= WLAN_STA_MULTI_AP; + } +#endif +} + +#if CONFIG_RTW_AP_DATA_BMC_TO_UC +static bool rtw_ap_data_bmc_to_uc(_adapter *adapter + , const u8 *da, const u8 *sa, const u8 *ori_ta + , u16 os_qid, _list *b2u_list) +{ + struct sta_priv *stapriv = &adapter->stapriv; + struct xmit_priv *xmitpriv = &adapter->xmitpriv; + _irqL irqL; + _list *head, *list; + struct sta_info *sta; + char b2u_sta_id[NUM_STA]; + u8 b2u_sta_num = 0; + bool bmc_need = _FALSE; + int i; + + _enter_critical_bh(&stapriv->asoc_list_lock, &irqL); + head = &stapriv->asoc_list; + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + int stainfo_offset; + + sta = LIST_CONTAINOR(list, struct sta_info, asoc_list); + list = get_next(list); + + stainfo_offset = rtw_stainfo_offset(stapriv, sta); + if (stainfo_offset_valid(stainfo_offset)) + b2u_sta_id[b2u_sta_num++] = stainfo_offset; + } + _exit_critical_bh(&stapriv->asoc_list_lock, &irqL); + + if (!b2u_sta_num) + goto exit; + + for (i = 0; i < b2u_sta_num; i++) { + struct xmit_frame *b2uframe; + struct pkt_attrib *attrib; + + sta = rtw_get_stainfo_by_offset(stapriv, b2u_sta_id[i]); + if (!(sta->state & WIFI_ASOC_STATE) + || _rtw_memcmp(sta->cmn.mac_addr, sa, ETH_ALEN) == _TRUE + || (ori_ta && _rtw_memcmp(sta->cmn.mac_addr, ori_ta, ETH_ALEN) == _TRUE) + || is_broadcast_mac_addr(sta->cmn.mac_addr) + || is_zero_mac_addr(sta->cmn.mac_addr)) + continue; + + b2uframe = rtw_alloc_xmitframe(xmitpriv, os_qid); + if (!b2uframe) { + bmc_need = _TRUE; + break; + } + + attrib = &b2uframe->attrib; + + _rtw_memcpy(attrib->ra, sta->cmn.mac_addr, ETH_ALEN); + _rtw_memcpy(attrib->ta, adapter_mac_addr(adapter), ETH_ALEN); + #ifdef CONFIG_RTW_WDS + if (adapter_use_wds(adapter) && (sta->flags & WLAN_STA_WDS)) { + _rtw_memcpy(attrib->dst, da, ETH_ALEN); + attrib->wds = 1; + } else + #endif + _rtw_memcpy(attrib->dst, attrib->ra, ETH_ALEN); + _rtw_memcpy(attrib->src, sa, ETH_ALEN); + + rtw_list_insert_tail(&b2uframe->list, b2u_list); + } + +exit: + return bmc_need; +} + +void dump_ap_b2u_flags(void *sel, _adapter *adapter) +{ + RTW_PRINT_SEL(sel, "%4s %4s\n", "src", "fwd"); + RTW_PRINT_SEL(sel, "0x%02x 0x%02x\n", adapter->b2u_flags_ap_src, adapter->b2u_flags_ap_fwd); +} +#endif /* CONFIG_RTW_AP_DATA_BMC_TO_UC */ + +static int rtw_ap_nexthop_resolve(_adapter *adapter, struct xmit_frame *xframe) +{ + struct pkt_attrib *attrib = &xframe->attrib; + int ret = _SUCCESS; + +#ifdef CONFIG_RTW_WDS + if (adapter_use_wds(adapter) + && rtw_wds_nexthop_lookup(adapter, attrib->dst, attrib->ra) == 0 + ) { + if (_rtw_memcmp(attrib->dst, attrib->ra, ETH_ALEN) == _FALSE) + attrib->wds = 1; + } else +#endif + _rtw_memcpy(attrib->ra, attrib->dst, ETH_ALEN); + + return ret; +} + +int rtw_ap_addr_resolve(_adapter *adapter, u16 os_qid, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list) +{ + struct pkt_file pktfile; + struct ethhdr etherhdr; + struct pkt_attrib *attrib; + struct rtw_mesh_path *mpath = NULL, *mppath = NULL; + u8 is_da_mcast; + u8 addr4_need; +#if CONFIG_RTW_AP_DATA_BMC_TO_UC + bool bmc_need = _TRUE; +#endif + int res = _SUCCESS; + + _rtw_open_pktfile(pkt, &pktfile); + if (_rtw_pktfile_read(&pktfile, (u8 *)ðerhdr, ETH_HLEN) != ETH_HLEN) { + res = _FAIL; + goto exit; + } + + xframe->pkt = pkt; +#if CONFIG_RTW_AP_DATA_BMC_TO_UC + _rtw_init_listhead(b2u_list); +#endif + + is_da_mcast = IS_MCAST(etherhdr.h_dest); + if (is_da_mcast) { + #if CONFIG_RTW_AP_DATA_BMC_TO_UC + if (rtw_ap_src_b2u_policy_chk(adapter->b2u_flags_ap_src, etherhdr.h_dest) + && adapter->registrypriv.wifi_spec == 0 + && adapter->xmitpriv.free_xmitframe_cnt > (NR_XMITFRAME / 4) + ) { + bmc_need = rtw_ap_data_bmc_to_uc(adapter + , etherhdr.h_dest, etherhdr.h_source, NULL, os_qid, b2u_list); + if (bmc_need == _FALSE) { + res = RTW_BMC_NO_NEED; + goto exit; + } + } + #endif + } + + attrib = &xframe->attrib; + + _rtw_memcpy(attrib->dst, etherhdr.h_dest, ETH_ALEN); + _rtw_memcpy(attrib->src, etherhdr.h_source, ETH_ALEN); + _rtw_memcpy(attrib->ta, adapter_mac_addr(adapter), ETH_ALEN); + + if (is_da_mcast) + _rtw_memcpy(attrib->ra, attrib->dst, ETH_ALEN); + else + res = rtw_ap_nexthop_resolve(adapter, xframe); + +exit: + return res; +} + +int rtw_ap_rx_data_validate_hdr(_adapter *adapter, union recv_frame *rframe, struct sta_info **sta) +{ + struct sta_priv *stapriv = &adapter->stapriv; + struct rx_pkt_attrib *rattrib = &rframe->u.hdr.attrib; + u8 *whdr = get_recvframe_data(rframe); + u8 is_ra_bmc = 0; + sint ret = _FAIL; + + if (!(MLME_STATE(adapter) & WIFI_ASOC_STATE)) + goto exit; + + switch (rattrib->to_fr_ds) { + case 1: + if (IS_MCAST(GetAddr1Ptr(whdr))) + goto exit; + _rtw_memcpy(rattrib->ra, GetAddr1Ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->ta, get_addr2_ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->dst, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */ + _rtw_memcpy(rattrib->src, get_addr2_ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->bssid, GetAddr1Ptr(whdr), ETH_ALEN); + break; + case 3: + is_ra_bmc = IS_MCAST(GetAddr1Ptr(whdr)) ? 1 : 0; + _rtw_memcpy(rattrib->ra, GetAddr1Ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->ta, get_addr2_ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->dst, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */ + _rtw_memcpy(rattrib->src, GetAddr4Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */ + if (!is_ra_bmc) + _rtw_memcpy(rattrib->bssid, GetAddr1Ptr(whdr), ETH_ALEN); + break; + default: + ret = RTW_RX_HANDLED; /* don't count for drop */ + goto exit; + } + + *sta = rtw_get_stainfo(stapriv, rattrib->ta); + if (*sta == NULL) { + if (!is_ra_bmc && !IS_RADAR_DETECTED(adapter_to_rfctl(adapter))) { + #ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL + RTW_INFO(FUNC_ADPT_FMT" issue_deauth to "MAC_FMT" with reason(7), unknown TA\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(rattrib->ta)); + issue_deauth(adapter, rattrib->ta, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + #endif + } + ret = RTW_RX_HANDLED; + goto exit; + } + +#ifdef CONFIG_RTW_WDS_AUTO_EN + if (rattrib->to_fr_ds == 3 && !(sta->flags & WLAN_STA_WDS)) + sta->flags |= WLAN_STA_WDS; +#endif + + process_pwrbit_data(adapter, rframe, *sta); + + if ((get_frame_sub_type(whdr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) + process_wmmps_data(adapter, rframe, *sta); + + if (get_frame_sub_type(whdr) & BIT(6)) { + /* No data, will not indicate to upper layer, temporily count it here */ + count_rx_stats(adapter, rframe, *sta); + ret = RTW_RX_HANDLED; + goto exit; + } + + ret = _SUCCESS; + +exit: + return ret; +} + +int rtw_ap_rx_msdu_act_check(union recv_frame *rframe + , const u8 *da, const u8 *sa + , u8 *msdu, enum rtw_rx_llc_hdl llc_hdl + , struct xmit_frame **fwd_frame, _list *b2u_list) +{ + _adapter *adapter = rframe->u.hdr.adapter; + struct rx_pkt_attrib *rattrib = &rframe->u.hdr.attrib; + struct rtw_wds_path *wpath; + u8 is_da_bmc = IS_MCAST(da); + u8 is_da_self = !is_da_bmc && _rtw_memcmp(da, adapter_mac_addr(adapter), ETH_ALEN); + u8 is_da_peer = 0; + int in_wds_tbl = 0; + u16 os_qid; + struct xmit_frame *xframe; + struct pkt_attrib *xattrib; + u8 fwd_ra[ETH_ALEN] = {0}; + int act = 0; +#if CONFIG_RTW_AP_DATA_BMC_TO_UC + bool bmc_need = _TRUE; +#endif + +#ifdef CONFIG_RTW_WDS + /* update/create wds info for SA, RA */ + if (adapter_use_wds(adapter) + && (rframe->u.hdr.psta->state & WIFI_ASOC_STATE) + && _rtw_memcmp(sa, rframe->u.hdr.psta->cmn.mac_addr, ETH_ALEN) == _FALSE + ) { + rtw_rcu_read_lock(); + wpath = rtw_wds_path_lookup(adapter, sa); + if (!wpath) + rtw_wds_path_add(adapter, sa, rframe->u.hdr.psta); + else { + rtw_wds_path_assign_nexthop(wpath, rframe->u.hdr.psta); + wpath->last_update = rtw_get_current_time(); + } + rtw_rcu_read_unlock(); + } +#endif + + /* SA is self, need no further process */ + if (_rtw_memcmp(sa, adapter_mac_addr(adapter), ETH_ALEN) == _TRUE) + goto exit; + + if (is_da_bmc) { + /* DA is bmc addr */ + act |= RTW_RX_MSDU_ACT_INDICATE; + if (adapter->mlmepriv.ap_isolate) + goto exit; + goto fwd_chk; + + } + + if (is_da_self) { + /* DA is self, indicate */ + act |= RTW_RX_MSDU_ACT_INDICATE; + goto exit; + } + + /* DA is not self */ +#ifdef CONFIG_RTW_WDS + if (adapter_use_wds(adapter)) + in_wds_tbl = rtw_wds_nexthop_lookup(adapter, da, fwd_ra) == 0; +#endif + if (!in_wds_tbl) + is_da_peer = rtw_get_stainfo(&adapter->stapriv, da) ? 1 : 0; + + if (in_wds_tbl || is_da_peer) { + /* DA is known (peer or can be forwarded by peer) */ + if (adapter->mlmepriv.ap_isolate) { + #if defined(DBG_RX_DROP_FRAME) + RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" DA("MAC_FMT") through peer, ap_isolate\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(da)); + #endif + goto exit; + } + goto fwd_chk; + } + + /* DA is unknown*/ + act |= RTW_RX_MSDU_ACT_INDICATE; + goto exit; + +fwd_chk: + + if (adapter->stapriv.asoc_list_cnt <= 1) + goto exit; + + os_qid = rtw_os_recv_select_queue(msdu, llc_hdl); + +#if CONFIG_RTW_AP_DATA_BMC_TO_UC + _rtw_init_listhead(b2u_list); + + if (is_da_bmc + && rtw_ap_fwd_b2u_policy_chk(adapter->b2u_flags_ap_fwd, da, rattrib->to_fr_ds == 3 && !IS_MCAST(rattrib->ra)) + && adapter->registrypriv.wifi_spec == 0 + && adapter->xmitpriv.free_xmitframe_cnt > (NR_XMITFRAME / 4) + ) { + bmc_need = rtw_ap_data_bmc_to_uc(adapter + , da, sa, rframe->u.hdr.psta->cmn.mac_addr + , os_qid, b2u_list); + } + + if (bmc_need == _TRUE) +#endif + { + xframe = rtw_alloc_xmitframe(&adapter->xmitpriv, os_qid); + if (!xframe) { + #ifdef DBG_TX_DROP_FRAME + RTW_INFO("DBG_TX_DROP_FRAME "FUNC_ADPT_FMT" rtw_alloc_xmitframe fail\n" + , FUNC_ADPT_ARG(adapter)); + #endif + goto exit; + } + + xattrib = &xframe->attrib; + + _rtw_memcpy(xattrib->dst, da, ETH_ALEN); + _rtw_memcpy(xattrib->src, sa, ETH_ALEN); + _rtw_memcpy(xattrib->ta, adapter_mac_addr(adapter), ETH_ALEN); + + #ifdef CONFIG_RTW_WDS + if (in_wds_tbl && _rtw_memcmp(da, fwd_ra, ETH_ALEN) == _FALSE) { + _rtw_memcpy(xattrib->ra, fwd_ra, ETH_ALEN); + xattrib->wds = 1; + } else + #endif + _rtw_memcpy(xattrib->ra, da, ETH_ALEN); + + *fwd_frame = xframe; + } + + act |= RTW_RX_MSDU_ACT_FORWARD; + +exit: + return act; +} + #ifdef CONFIG_RTW_TOKEN_BASED_XMIT void rtw_issue_action_token_req(_adapter *padapter, struct sta_info *pstat) { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_beamforming.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_beamforming.c index 423e47614040..bd96beff7bdf 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_beamforming.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_beamforming.c @@ -95,11 +95,13 @@ static void _get_sta_beamform_cap(PADAPTER adapter, struct sta_info *sta, u8 *sta_bf_cap, u8 *sounding_dim, u8 *comp_steering) { struct beamforming_info *info; + struct mlme_priv *mlme; struct ht_priv *ht; + u16 ht_bf_cap; #ifdef CONFIG_80211AC_VHT struct vht_priv *vht; + u16 vht_bf_cap; #endif /* CONFIG_80211AC_VHT */ - u16 bf_cap; *sta_bf_cap = 0; @@ -111,56 +113,123 @@ static void _get_sta_beamform_cap(PADAPTER adapter, struct sta_info *sta, #ifdef CONFIG_80211AC_VHT vht = &adapter->mlmepriv.vhtpriv; #endif /* CONFIG_80211AC_VHT */ + mlme = &adapter->mlmepriv; - if (is_supported_ht(sta->wireless_mode) == _TRUE) { - /* HT */ - bf_cap = ht->beamform_cap; + if (is_supported_ht(sta->wireless_mode) == _FALSE) + return; - if (TEST_FLAG(bf_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) { - info->beamforming_cap |= BEAMFORMEE_CAP_HT_EXPLICIT; - *sta_bf_cap |= BEAMFORMER_CAP_HT_EXPLICIT; - *sounding_dim = (bf_cap & BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP) >> 6; - } - if (TEST_FLAG(bf_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE)) { + /* HT */ + if (check_fwstate(mlme, WIFI_AP_STATE)) { + /* Get peer clinet's BF cap: the cap. is intersected with associated AP.*/ + ht_bf_cap = sta->htpriv.beamform_cap; + RTW_INFO("At AP state, peer sta's ht_bf_cap=0x%x\n", ht_bf_cap); + + if (TEST_FLAG(ht_bf_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) { info->beamforming_cap |= BEAMFORMER_CAP_HT_EXPLICIT; *sta_bf_cap |= BEAMFORMEE_CAP_HT_EXPLICIT; - *comp_steering = (bf_cap & BEAMFORMING_HT_BEAMFORMER_STEER_NUM) >> 4; + *comp_steering = (ht_bf_cap & BEAMFORMING_HT_BEAMFORMER_STEER_NUM) >> 4; + RTW_INFO("%s: we support BEAMFORMER_CAP_HT_EXPLICIT\n", __func__); + } + if (TEST_FLAG(ht_bf_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE)) { + info->beamforming_cap |= BEAMFORMEE_CAP_HT_EXPLICIT; + *sta_bf_cap |= BEAMFORMER_CAP_HT_EXPLICIT; + *sounding_dim = (ht_bf_cap & BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP) >> 6; + RTW_INFO("%s: we support BEAMFORMEE_CAP_HT_EXPLICIT\n", __func__); + } + } else { + /* Get adapter's BF Cap: the cap. is intersected with associated AP.*/ + ht_bf_cap = ht->beamform_cap; + RTW_INFO("At non-AP state, adapter's ht_bf_cap=0x%x\n", ht_bf_cap); + + if (TEST_FLAG(ht_bf_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) { + info->beamforming_cap |= BEAMFORMEE_CAP_HT_EXPLICIT; + *sta_bf_cap |= BEAMFORMER_CAP_HT_EXPLICIT; + *sounding_dim = (ht_bf_cap & BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP) >> 6; + RTW_INFO("%s: we support BEAMFORMEE_CAP_HT_EXPLICIT\n", __func__); + } + if (TEST_FLAG(ht_bf_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE)) { + info->beamforming_cap |= BEAMFORMER_CAP_HT_EXPLICIT; + *sta_bf_cap |= BEAMFORMEE_CAP_HT_EXPLICIT; + *comp_steering = (ht_bf_cap & BEAMFORMING_HT_BEAMFORMER_STEER_NUM) >> 4; + RTW_INFO("%s: we support BEAMFORMER_CAP_HT_EXPLICIT\n", __func__); } } #ifdef CONFIG_80211AC_VHT - if (is_supported_vht(sta->wireless_mode) == _TRUE) { - /* VHT */ - bf_cap = vht->beamform_cap; - /* We are SU Beamformee because the STA is SU Beamformer */ - if (TEST_FLAG(bf_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE)) { - info->beamforming_cap |= BEAMFORMEE_CAP_VHT_SU; - *sta_bf_cap |= BEAMFORMER_CAP_VHT_SU; + if (is_supported_vht(sta->wireless_mode) == _FALSE) + return; - /* We are MU Beamformee because the STA is MU Beamformer */ - if (TEST_FLAG(bf_cap, BEAMFORMING_VHT_MU_MIMO_STA_ENABLE)) { - info->beamforming_cap |= BEAMFORMEE_CAP_VHT_MU; - *sta_bf_cap |= BEAMFORMER_CAP_VHT_MU; - } + /* VHT */ + if (check_fwstate(mlme, WIFI_AP_STATE)) { + /* Get peer clinet's BF cap: the cap. is intersected with associated AP.*/ + vht_bf_cap = sta->vhtpriv.beamform_cap; + RTW_INFO("At AP state, peer sta's vht_bf_cap=0x%x\n", vht_bf_cap); - *sounding_dim = (bf_cap & BEAMFORMING_VHT_BEAMFORMEE_SOUND_DIM) >> 12; - } /* We are SU Beamformer because the STA is SU Beamformee */ - if (TEST_FLAG(bf_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE)) { + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE)) { info->beamforming_cap |= BEAMFORMER_CAP_VHT_SU; *sta_bf_cap |= BEAMFORMEE_CAP_VHT_SU; + RTW_INFO("%s: we support BEAMFORMER_CAP_VHT_SU\n", __func__); /* We are MU Beamformer because the STA is MU Beamformee */ - if (TEST_FLAG(bf_cap, BEAMFORMING_VHT_MU_MIMO_AP_ENABLE)) { + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_MU_MIMO_STA_ENABLE)) { info->beamforming_cap |= BEAMFORMER_CAP_VHT_MU; *sta_bf_cap |= BEAMFORMEE_CAP_VHT_MU; + RTW_INFO("%s: we support BEAMFORMER_CAP_VHT_MU\n", __func__); } - *comp_steering = (bf_cap & BEAMFORMING_VHT_BEAMFORMER_STS_CAP) >> 8; + *comp_steering = (vht_bf_cap & BEAMFORMING_VHT_BEAMFORMER_STS_CAP) >> 8; + } + /* We are SU Beamformee because the STA is SU Beamformer */ + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE)) { + info->beamforming_cap |= BEAMFORMEE_CAP_VHT_SU; + *sta_bf_cap |= BEAMFORMER_CAP_VHT_SU; + RTW_INFO("%s: we support BEAMFORMEE_CAP_VHT_SU\n", __func__); + + /* The STA is MU Beamformer, but we(AP) should not be MU Beamformee */ + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_MU_MIMO_AP_ENABLE)) { + RTW_WARN("%s: Associated STA should not be a MU BFer.\n", __func__); + } + + *sounding_dim = (vht_bf_cap & BEAMFORMING_VHT_BEAMFORMEE_SOUND_DIM) >> 12; + } + } else { + /* Get adapter's BF Cap: the cap. is intersected with associated AP.*/ + vht_bf_cap = vht->beamform_cap; + RTW_INFO("At non-AP state, adapter's vht_bf_cap=0x%x\n", vht_bf_cap); + + /* We are SU Beamformee */ + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE)) { + info->beamforming_cap |= BEAMFORMEE_CAP_VHT_SU; + *sta_bf_cap |= BEAMFORMER_CAP_VHT_SU; + RTW_INFO("%s: we support BEAMFORMEE_CAP_VHT_SU\n", __func__); + + /* We are MU Beamformee */ + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_MU_MIMO_STA_ENABLE)) { + info->beamforming_cap |= BEAMFORMEE_CAP_VHT_MU; + *sta_bf_cap |= BEAMFORMER_CAP_VHT_MU; + RTW_INFO("%s: we support BEAMFORMEE_CAP_VHT_MU\n", __func__); + } + + *sounding_dim = (vht_bf_cap & BEAMFORMING_VHT_BEAMFORMEE_SOUND_DIM) >> 12; + } + /* We are SU Beamformer */ + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE)) { + info->beamforming_cap |= BEAMFORMER_CAP_VHT_SU; + *sta_bf_cap |= BEAMFORMEE_CAP_VHT_SU; + RTW_INFO("%s: we support BEAMFORMER_CAP_VHT_SU\n", __func__); + + /* We are MU Beamformer, but client should not be a MU Beamformer */ + if (TEST_FLAG(vht_bf_cap, BEAMFORMING_VHT_MU_MIMO_AP_ENABLE)) { + RTW_WARN("%s: non-AP state should not support MU BFer.\n", __func__); + } + + *comp_steering = (vht_bf_cap & BEAMFORMING_VHT_BEAMFORMER_STS_CAP) >> 8; } } #endif /* CONFIG_80211AC_VHT */ + } static u8 _send_ht_ndpa_packet(PADAPTER adapter, u8 *ra, enum channel_width bw) @@ -1387,6 +1456,10 @@ static void _beamforming_enter(PADAPTER adapter, void *p) __FUNCTION__, MAC_ARG(sta_copy->cmn.mac_addr)); return; } + + RTW_INFO("%s: find STA info for " MAC_FMT "\n", + __FUNCTION__, MAC_ARG(sta_copy->cmn.mac_addr)); + if (sta != sta_copy) { RTW_WARN("%s: Origin sta(fake)=%p realsta=%p for " MAC_FMT "\n", __FUNCTION__, sta_copy, sta, MAC_ARG(sta_copy->cmn.mac_addr)); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_btcoex.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_btcoex.c index 78544a55e14c..a0dcf219a482 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_btcoex.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_btcoex.c @@ -179,6 +179,17 @@ void rtw_btcoex_IQKNotify(PADAPTER padapter, u8 state) hal_btcoex_IQKNotify(padapter, state); } +void rtw_btcoex_WLRFKNotify(PADAPTER padapter, u8 path, u8 type, u8 state) +{ + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + + hal_btcoex_WLRFKNotify(padapter, path, type, state); +} + void rtw_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf) { PHAL_DATA_TYPE pHalData; @@ -316,6 +327,11 @@ void rtw_btcoex_SetManualControl(PADAPTER padapter, u8 manual) hal_btcoex_SetManualControl(padapter, _FALSE); } +void rtw_btcoex_set_policy_control(PADAPTER padapter, u8 btc_policy) +{ + hal_btcoex_set_policy_control(padapter, btc_policy); +} + u8 rtw_btcoex_1Ant(PADAPTER padapter) { return hal_btcoex_1Ant(padapter); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_chplan.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_chplan.c index 6a50e2e597f6..1c7ba5fa40a9 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_chplan.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_chplan.c @@ -17,409 +17,353 @@ #include -#define RTW_DOMAIN_MAP_VER "43e" -#define RTW_COUNTRY_MAP_VER "25" +#define RTW_DOMAIN_MAP_VER "54" +#define RTW_DOMAIN_MAP_M_VER "g" +#define RTW_COUNTRY_MAP_VER "27" -#ifdef LEGACY_CHANNEL_PLAN_REF -/******************************************************** -ChannelPlan definitions -*********************************************************/ -static RT_CHANNEL_PLAN legacy_channel_plan[] = { - /* 0x00, RTW_CHPLAN_FCC */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 32}, - /* 0x01, RTW_CHPLAN_IC */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 31}, - /* 0x02, RTW_CHPLAN_ETSI */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 32}, - /* 0x03, RTW_CHPLAN_SPAIN */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, - /* 0x04, RTW_CHPLAN_FRANCE */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, - /* 0x05, RTW_CHPLAN_MKK */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, - /* 0x06, RTW_CHPLAN_MKK1 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, - /* 0x07, RTW_CHPLAN_ISRAEL */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, - /* 0x08, RTW_CHPLAN_TELEC */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, - /* 0x09, RTW_CHPLAN_GLOBAL_DOAMIN */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, - /* 0x0A, RTW_CHPLAN_WORLD_WIDE_13 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, - /* 0x0B, RTW_CHPLAN_TAIWAN */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 26}, - /* 0x0C, RTW_CHPLAN_CHINA */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 149, 153, 157, 161, 165}, 18}, - /* 0x0D, RTW_CHPLAN_SINGAPORE_INDIA_MEXICO */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 24}, - /* 0x0E, RTW_CHPLAN_KOREA */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 31}, - /* 0x0F, RTW_CHPLAN_TURKEY */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19}, - /* 0x10, RTW_CHPLAN_JAPAN */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 32}, - /* 0x11, RTW_CHPLAN_FCC_NO_DFS */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 149, 153, 157, 161, 165}, 20}, - /* 0x12, RTW_CHPLAN_JAPAN_NO_DFS */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48}, 17}, - /* 0x13, RTW_CHPLAN_WORLD_WIDE_5G */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 37}, - /* 0x14, RTW_CHPLAN_TAIWAN_NO_DFS */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 56, 60, 64, 149, 153, 157, 161, 165}, 19}, -}; -#endif - -enum rtw_rd_2g { - RTW_RD_2G_NULL = 0, - RTW_RD_2G_WORLD = 1, /* Worldwird 13 */ - RTW_RD_2G_ETSI1 = 2, /* Europe */ - RTW_RD_2G_FCC1 = 3, /* US */ - RTW_RD_2G_MKK1 = 4, /* Japan */ - RTW_RD_2G_ETSI2 = 5, /* France */ - RTW_RD_2G_GLOBAL = 6, /* Global domain */ - RTW_RD_2G_MKK2 = 7, /* Japan */ - RTW_RD_2G_FCC2 = 8, /* US */ - RTW_RD_2G_IC1 = 9, /* Canada */ - RTW_RD_2G_WORLD1 = 10, /* Worldwide 11 */ - RTW_RD_2G_KCC1 = 11, /* Korea */ - RTW_RD_2G_IC2 = 12, /* Canada */ - - RTW_RD_2G_MAX, +struct ch_list_t { + u8 *len_ch_attr; }; -enum rtw_rd_5g { - RTW_RD_5G_NULL = 0, /* */ - RTW_RD_5G_ETSI1 = 1, /* Europe */ - RTW_RD_5G_ETSI2 = 2, /* Australia, New Zealand */ - RTW_RD_5G_ETSI3 = 3, /* Russia */ - RTW_RD_5G_FCC1 = 4, /* US */ - RTW_RD_5G_FCC2 = 5, /* FCC w/o DFS Channels */ - RTW_RD_5G_FCC3 = 6, /* Bolivia, Chile, El Salvador, Venezuela */ - RTW_RD_5G_FCC4 = 7, /* Venezuela */ - RTW_RD_5G_FCC5 = 8, /* China */ - RTW_RD_5G_FCC6 = 9, /* */ - RTW_RD_5G_FCC7 = 10, /* US(w/o Weather radar) */ - RTW_RD_5G_IC1 = 11, /* Canada(w/o Weather radar) */ - RTW_RD_5G_KCC1 = 12, /* Korea */ - RTW_RD_5G_MKK1 = 13, /* Japan */ - RTW_RD_5G_MKK2 = 14, /* Japan (W52, W53) */ - RTW_RD_5G_MKK3 = 15, /* Japan (W56) */ - RTW_RD_5G_NCC1 = 16, /* Taiwan, (w/o Weather radar) */ - RTW_RD_5G_NCC2 = 17, /* Taiwan, Band2, Band4 */ - RTW_RD_5G_NCC3 = 18, /* Taiwan w/o DFS, Band4 only */ - RTW_RD_5G_ETSI4 = 19, /* Europe w/o DFS, Band1 only */ - RTW_RD_5G_ETSI5 = 20, /* Australia, New Zealand(w/o Weather radar) */ - RTW_RD_5G_FCC8 = 21, /* Latin America */ - RTW_RD_5G_ETSI6 = 22, /* Israel, Bahrain, Egypt, India, China, Malaysia */ - RTW_RD_5G_ETSI7 = 23, /* China */ - RTW_RD_5G_ETSI8 = 24, /* Jordan */ - RTW_RD_5G_ETSI9 = 25, /* Lebanon */ - RTW_RD_5G_ETSI10 = 26, /* Qatar */ - RTW_RD_5G_ETSI11 = 27, /* Russia */ - RTW_RD_5G_NCC4 = 28, /* Taiwan, (w/o Weather radar) */ - RTW_RD_5G_ETSI12 = 29, /* Indonesia */ - RTW_RD_5G_FCC9 = 30, /* (w/o Weather radar) */ - RTW_RD_5G_ETSI13 = 31, /* (w/o Weather radar) */ - RTW_RD_5G_FCC10 = 32, /* Argentina(w/o Weather radar) */ - RTW_RD_5G_MKK4 = 33, /* Japan (W52) */ - RTW_RD_5G_ETSI14 = 34, /* Russia */ - RTW_RD_5G_FCC11 = 35, /* US(include CH144) */ - RTW_RD_5G_ETSI15 = 36, /* Malaysia */ - RTW_RD_5G_MKK5 = 37, /* Japan */ - RTW_RD_5G_ETSI16 = 38, /* Europe */ - RTW_RD_5G_ETSI17 = 39, /* Europe */ - RTW_RD_5G_FCC12 = 40, /* FCC */ - RTW_RD_5G_FCC13 = 41, /* FCC */ - RTW_RD_5G_FCC14 = 42, /* FCC w/o Weather radar(w/o 5600~5650MHz) */ - RTW_RD_5G_FCC15 = 43, /* FCC w/o Band3 */ - RTW_RD_5G_FCC16 = 44, /* FCC w/o Band3 */ - RTW_RD_5G_ETSI18 = 45, /* ETSI w/o DFS Band2&3 */ - RTW_RD_5G_ETSI19 = 46, /* Europe */ - RTW_RD_5G_FCC17 = 47, /* FCC w/o Weather radar(w/o 5600~5650MHz) */ - RTW_RD_5G_ETSI20 = 48, /* Europe */ - RTW_RD_5G_IC2 = 49, /* Canada(w/o Weather radar), include ch144 */ - RTW_RD_5G_ETSI21 = 50, /* Australia, New Zealand(w/o Weather radar) */ - RTW_RD_5G_FCC18 = 51, /* */ - RTW_RD_5G_WORLD = 52, /* Worldwide */ - RTW_RD_5G_CHILE1 = 53, /* Chile */ - RTW_RD_5G_ACMA1 = 54, /* Australia, New Zealand (w/o Weather radar) (w/o Ch120~Ch128) */ - RTW_RD_5G_WORLD1 = 55, /* 5G Worldwide Band1&2 */ - RTW_RD_5G_CHILE2 = 56, /* Chile (Band2,Band3) */ - RTW_RD_5G_KCC2 = 57, /* Korea (New standard) */ - RTW_RD_5G_KCC3 = 58, /* Korea (2018 Dec 05 New standard, include ch144) */ - RTW_RD_5G_MKK6 = 59, /* Japan */ - RTW_RD_5G_MKK7 = 60, /* Japan */ - RTW_RD_5G_MKK8 = 61, /* Japan */ - RTW_RD_5G_MEX1 = 62, /* Mexico */ - RTW_RD_5G_ETSI22 = 63, /* Europe */ - RTW_RD_5G_MKK9 = 64, /* Japan */ - RTW_RD_5G_FCC19 = 65, /* FCC */ - RTW_RD_5G_FCC20 = 66, /* FCC w/o Band3 */ - RTW_RD_5G_FCC21 = 67, /* FCC */ - RTW_RD_5G_ETSI23 = 68, /* Indonesia */ - - /* === Below are driver defined for legacy channel plan compatible, DON'T assign index ==== */ - RTW_RD_5G_OLD_FCC1, - RTW_RD_5G_OLD_NCC1, - RTW_RD_5G_OLD_KCC1, - - RTW_RD_5G_MAX, +#define CLA_2G_12_14_PASSIVE BIT0 + +#define CLA_5G_B1_PASSIVE BIT0 +#define CLA_5G_B2_PASSIVE BIT1 +#define CLA_5G_B3_PASSIVE BIT2 +#define CLA_5G_B4_PASSIVE BIT3 +#define CLA_5G_B2_DFS BIT4 +#define CLA_5G_B3_DFS BIT5 +#define CLA_5G_B4_DFS BIT6 + +#define CH_LIST_ENT(_len, arg...) \ + {.len_ch_attr = (u8[_len + 2]) {_len, ##arg}, } + +#define CH_LIST_LEN(_ch_list) (_ch_list.len_ch_attr[0]) +#define CH_LIST_CH(_ch_list, _i) (_ch_list.len_ch_attr[_i + 1]) +#define CH_LIST_ATTRIB(_ch_list) (_ch_list.len_ch_attr[CH_LIST_LEN(_ch_list) + 1]) + +enum rtw_chd_2g { + RTW_CHD_2G_00 = 0, + RTW_CHD_2G_01 = 1, + RTW_CHD_2G_02 = 2, + RTW_CHD_2G_03 = 3, + RTW_CHD_2G_04 = 4, + RTW_CHD_2G_05 = 5, + RTW_CHD_2G_06 = 6, + + RTW_CHD_2G_MAX, + RTW_CHD_2G_NULL = RTW_CHD_2G_00, }; -struct ch_list_t { - u8 *len_ch; +enum rtw_chd_5g { + RTW_CHD_5G_00 = 0, + RTW_CHD_5G_01 = 1, + RTW_CHD_5G_02 = 2, + RTW_CHD_5G_03 = 3, + RTW_CHD_5G_04 = 4, + RTW_CHD_5G_05 = 5, + RTW_CHD_5G_06 = 6, + RTW_CHD_5G_07 = 7, + RTW_CHD_5G_08 = 8, + RTW_CHD_5G_09 = 9, + RTW_CHD_5G_10 = 10, + RTW_CHD_5G_11 = 11, + RTW_CHD_5G_12 = 12, + RTW_CHD_5G_13 = 13, + RTW_CHD_5G_14 = 14, + RTW_CHD_5G_15 = 15, + RTW_CHD_5G_16 = 16, + RTW_CHD_5G_17 = 17, + RTW_CHD_5G_18 = 18, + RTW_CHD_5G_19 = 19, + RTW_CHD_5G_20 = 20, + RTW_CHD_5G_21 = 21, + RTW_CHD_5G_22 = 22, + RTW_CHD_5G_23 = 23, + RTW_CHD_5G_24 = 24, + RTW_CHD_5G_25 = 25, + RTW_CHD_5G_26 = 26, + RTW_CHD_5G_27 = 27, + RTW_CHD_5G_28 = 28, + RTW_CHD_5G_29 = 29, + RTW_CHD_5G_30 = 30, + RTW_CHD_5G_31 = 31, + RTW_CHD_5G_32 = 32, + RTW_CHD_5G_33 = 33, + RTW_CHD_5G_34 = 34, + RTW_CHD_5G_35 = 35, + RTW_CHD_5G_36 = 36, + RTW_CHD_5G_37 = 37, + RTW_CHD_5G_38 = 38, + RTW_CHD_5G_39 = 39, + RTW_CHD_5G_40 = 40, + RTW_CHD_5G_41 = 41, + RTW_CHD_5G_42 = 42, + RTW_CHD_5G_43 = 43, + RTW_CHD_5G_44 = 44, + RTW_CHD_5G_45 = 45, + RTW_CHD_5G_46 = 46, + RTW_CHD_5G_47 = 47, + RTW_CHD_5G_48 = 48, + RTW_CHD_5G_49 = 49, + RTW_CHD_5G_50 = 50, + RTW_CHD_5G_51 = 51, + + RTW_CHD_5G_MAX, + RTW_CHD_5G_NULL = RTW_CHD_5G_00, }; -#define CH_LIST_ENT(_len, arg...) \ - {.len_ch = (u8[_len + 1]) {_len, ##arg}, } +static const struct ch_list_t rtw_channel_def_2g[] = { + /* 0, RTW_CHD_2G_00 */ CH_LIST_ENT(0, 0), + /* 1, RTW_CHD_2G_01 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, CLA_2G_12_14_PASSIVE), + /* 2, RTW_CHD_2G_02 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0), + /* 3, RTW_CHD_2G_03 */ CH_LIST_ENT(11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0), + /* 4, RTW_CHD_2G_04 */ CH_LIST_ENT(14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0), + /* 5, RTW_CHD_2G_05 */ CH_LIST_ENT(4, 10, 11, 12, 13, 0), + /* 6, RTW_CHD_2G_06 */ CH_LIST_ENT(14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, CLA_2G_12_14_PASSIVE), +}; -#define CH_LIST_LEN(_ch_list) (_ch_list.len_ch[0]) -#define CH_LIST_CH(_ch_list, _i) (_ch_list.len_ch[_i + 1]) +#if CONFIG_IEEE80211_BAND_5GHZ +static const struct ch_list_t rtw_channel_def_5g[] = { + /* 0, RTW_CHD_5G_00 */ CH_LIST_ENT(0, 0), + /* 1, RTW_CHD_5G_01 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 2, RTW_CHD_5G_02 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 3, RTW_CHD_5G_03 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 4, RTW_CHD_5G_04 */ CH_LIST_ENT(22, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 5, RTW_CHD_5G_05 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 6, RTW_CHD_5G_06 */ CH_LIST_ENT(9, 36, 40, 44, 48, 149, 153, 157, 161, 165, 0), + /* 7, RTW_CHD_5G_07 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B2_DFS), + /* 8, RTW_CHD_5G_08 */ CH_LIST_ENT(12, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, CLA_5G_B2_DFS), + /* 9, RTW_CHD_5G_09 */ CH_LIST_ENT(5, 149, 153, 157, 161, 165, 0), + /* 10, RTW_CHD_5G_10 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64, CLA_5G_B2_DFS), + /* 11, RTW_CHD_5G_11 */ CH_LIST_ENT(11, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, CLA_5G_B3_DFS), + /* 12, RTW_CHD_5G_12 */ CH_LIST_ENT(16, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 13, RTW_CHD_5G_13 */ CH_LIST_ENT(8, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B2_DFS), + /* 14, RTW_CHD_5G_14 */ CH_LIST_ENT(4, 36, 40, 44, 48, 0), + /* 15, RTW_CHD_5G_15 */ CH_LIST_ENT(4, 149, 153, 157, 161, 0), + /* 16, RTW_CHD_5G_16 */ CH_LIST_ENT(11, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 0), + /* 17, RTW_CHD_5G_17 */ CH_LIST_ENT(16, 36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 18, RTW_CHD_5G_18 */ CH_LIST_ENT(17, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 19, RTW_CHD_5G_19 */ CH_LIST_ENT(16, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 20, RTW_CHD_5G_20 */ CH_LIST_ENT(20, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 21, RTW_CHD_5G_21 */ CH_LIST_ENT(11, 36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 22, RTW_CHD_5G_22 */ CH_LIST_ENT(25, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 23, RTW_CHD_5G_23 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 24, RTW_CHD_5G_24 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), + /* 25, RTW_CHD_5G_25 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE), + /* 26, RTW_CHD_5G_26 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE), + /* 27, RTW_CHD_5G_27 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE), + /* 28, RTW_CHD_5G_28 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B2_PASSIVE), + /* 29, RTW_CHD_5G_29 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE), + /* 30, RTW_CHD_5G_30 */ CH_LIST_ENT(9, 36, 40, 44, 48, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B4_PASSIVE), + /* 31, RTW_CHD_5G_31 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), + /* 32, RTW_CHD_5G_32 */ CH_LIST_ENT(9, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B2_DFS), + /* 33, RTW_CHD_5G_33 */ CH_LIST_ENT(22, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 144, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 34, RTW_CHD_5G_34 */ CH_LIST_ENT(13, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B3_DFS), + /* 35, RTW_CHD_5G_35 */ CH_LIST_ENT(8, 100, 104, 108, 112, 116, 132, 136, 140, CLA_5G_B3_DFS), + /* 36, RTW_CHD_5G_36 */ CH_LIST_ENT(25, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B2_DFS | CLA_5G_B3_PASSIVE | CLA_5G_B3_DFS | CLA_5G_B4_PASSIVE), + /* 37, RTW_CHD_5G_37 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE), + /* 38, RTW_CHD_5G_38 */ CH_LIST_ENT(16, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 39, RTW_CHD_5G_39 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_DFS | CLA_5G_B3_DFS | CLA_5G_B4_DFS), + /* 40, RTW_CHD_5G_40 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 41, RTW_CHD_5G_41 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS | CLA_5G_B4_PASSIVE), + /* 42, RTW_CHD_5G_42 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_DFS | CLA_5G_B3_DFS | CLA_5G_B4_PASSIVE), + /* 43, RTW_CHD_5G_43 */ CH_LIST_ENT(23, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), + /* 44, RTW_CHD_5G_44 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE | CLA_5G_B4_PASSIVE), + /* 45, RTW_CHD_5G_45 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165, CLA_5G_B1_PASSIVE | CLA_5G_B2_PASSIVE | CLA_5G_B4_PASSIVE), + /* 46, RTW_CHD_5G_46 */ CH_LIST_ENT(12, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, CLA_5G_B2_PASSIVE), + /* 47, RTW_CHD_5G_47 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, CLA_5G_B2_PASSIVE | CLA_5G_B3_PASSIVE), + /* 48, RTW_CHD_5G_48 */ CH_LIST_ENT(20, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 49, RTW_CHD_5G_49 */ CH_LIST_ENT(17, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 50, RTW_CHD_5G_50 */ CH_LIST_ENT(17, 36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, 144, 149, 153, 157, 161, 165, CLA_5G_B2_DFS | CLA_5G_B3_DFS), + /* 51, RTW_CHD_5G_51 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, CLA_5G_B2_DFS | CLA_5G_B3_DFS), +}; +#endif /* CONFIG_IEEE80211_BAND_5GHZ */ struct chplan_ent_t { - u8 rd_2g; + u8 regd_2g; /* value of REGULATION_TXPWR_LMT */ + u8 chd_2g; #if CONFIG_IEEE80211_BAND_5GHZ - u8 rd_5g; + u8 regd_5g; /* value of REGULATION_TXPWR_LMT */ + u8 chd_5g; #endif - u8 regd; /* value of REGULATION_TXPWR_LMT */ }; #if CONFIG_IEEE80211_BAND_5GHZ -#define CHPLAN_ENT(i2g, i5g, regd) {i2g, i5g, regd} +#define CHPLAN_ENT(_regd_2g, _chd_2g, _regd_5g, _chd_5g) {.regd_2g = _regd_2g, .chd_2g = _chd_2g, .regd_5g = _regd_5g, .chd_5g = _chd_5g} #else -#define CHPLAN_ENT(i2g, i5g, regd) {i2g, regd} +#define CHPLAN_ENT(_regd_2g, _chd_2g, _regd_5g, _chd_5g) {.regd_2g = _regd_2g, .chd_2g = _chd_2g} #endif -static struct ch_list_t RTW_ChannelPlan2G[] = { - /* 0, RTW_RD_2G_NULL */ CH_LIST_ENT(0), - /* 1, RTW_RD_2G_WORLD */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), - /* 2, RTW_RD_2G_ETSI1 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), - /* 3, RTW_RD_2G_FCC1 */ CH_LIST_ENT(11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), - /* 4, RTW_RD_2G_MKK1 */ CH_LIST_ENT(14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), - /* 5, RTW_RD_2G_ETSI2 */ CH_LIST_ENT(4, 10, 11, 12, 13), - /* 6, RTW_RD_2G_GLOBAL */ CH_LIST_ENT(14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), - /* 7, RTW_RD_2G_MKK2 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), - /* 8, RTW_RD_2G_FCC2 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), - /* 9, RTW_RD_2G_IC1 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), - /* 10, RTW_RD_2G_WORLD1 */ CH_LIST_ENT(11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), - /* 11, RTW_RD_2G_KCC1 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), - /* 12, RTW_RD_2G_IC2 */ CH_LIST_ENT(11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), +#define CHPLAN_ENT_NOT_DEFINED CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_NULL, TXPWR_LMT_NONE, RTW_CHD_5G_NULL) + +static const struct chplan_ent_t RTW_ChannelPlanMap[] = { + /* 0x00 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_49), + /* 0x01 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_50), + /* 0x02 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_03, TXPWR_LMT_ETSI, RTW_CHD_5G_07), + /* 0x03 */ CHPLAN_ENT(TXPWR_LMT_ACMA, RTW_CHD_2G_02, TXPWR_LMT_ACMA, RTW_CHD_5G_33), + /* 0x04 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_51), + /* 0x05 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x06 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x07 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x08 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x09 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x0A */ CHPLAN_ENT_NOT_DEFINED, + /* 0x0B */ CHPLAN_ENT_NOT_DEFINED, + /* 0x0C */ CHPLAN_ENT_NOT_DEFINED, + /* 0x0D */ CHPLAN_ENT_NOT_DEFINED, + /* 0x0E */ CHPLAN_ENT_NOT_DEFINED, + /* 0x0F */ CHPLAN_ENT_NOT_DEFINED, + /* 0x10 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x11 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x12 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x13 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x14 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x15 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x16 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x17 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x18 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x19 */ CHPLAN_ENT_NOT_DEFINED, + /* 0x1A */ CHPLAN_ENT_NOT_DEFINED, + /* 0x1B */ CHPLAN_ENT_NOT_DEFINED, + /* 0x1C */ CHPLAN_ENT_NOT_DEFINED, + /* 0x1D */ CHPLAN_ENT_NOT_DEFINED, + /* 0x1E */ CHPLAN_ENT_NOT_DEFINED, + /* 0x1F */ CHPLAN_ENT_NOT_DEFINED, + /* 0x20 */ CHPLAN_ENT(TXPWR_LMT_WW, RTW_CHD_2G_01, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x21 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x22 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x23 */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_04, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x24 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_05, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x25 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_03), + /* 0x26 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_02), + /* 0x27 */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_04, TXPWR_LMT_MKK, RTW_CHD_5G_02), + /* 0x28 */ CHPLAN_ENT(TXPWR_LMT_KCC, RTW_CHD_2G_01, TXPWR_LMT_KCC, RTW_CHD_5G_05), + /* 0x29 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_06), + /* 0x2A */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x2B */ CHPLAN_ENT(TXPWR_LMT_IC, RTW_CHD_2G_02, TXPWR_LMT_IC, RTW_CHD_5G_33), + /* 0x2C */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_02, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x2D */ CHPLAN_ENT(TXPWR_LMT_CHILE, RTW_CHD_2G_01, TXPWR_LMT_CHILE, RTW_CHD_5G_22), + /* 0x2E */ CHPLAN_ENT(TXPWR_LMT_WW, RTW_CHD_2G_03, TXPWR_LMT_WW, RTW_CHD_5G_37), + /* 0x2F */ CHPLAN_ENT(TXPWR_LMT_CHILE, RTW_CHD_2G_01, TXPWR_LMT_CHILE, RTW_CHD_5G_38), + /* 0x30 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_07), + /* 0x31 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_08), + /* 0x32 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_09), + /* 0x33 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_10), + /* 0x34 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_01), + /* 0x35 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_03), + /* 0x36 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_04), + /* 0x37 */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_04, TXPWR_LMT_MKK, RTW_CHD_5G_10), + /* 0x38 */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_04, TXPWR_LMT_MKK, RTW_CHD_5G_11), + /* 0x39 */ CHPLAN_ENT(TXPWR_LMT_NCC, RTW_CHD_2G_03, TXPWR_LMT_NCC, RTW_CHD_5G_12), + /* 0x3A */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_02), + /* 0x3B */ CHPLAN_ENT(TXPWR_LMT_ACMA, RTW_CHD_2G_02, TXPWR_LMT_ACMA, RTW_CHD_5G_01), + /* 0x3C */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_10), + /* 0x3D */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_15), + /* 0x3E */ CHPLAN_ENT(TXPWR_LMT_KCC, RTW_CHD_2G_02, TXPWR_LMT_KCC, RTW_CHD_5G_03), + /* 0x3F */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_22), + /* 0x40 */ CHPLAN_ENT(TXPWR_LMT_NCC, RTW_CHD_2G_03, TXPWR_LMT_NCC, RTW_CHD_5G_13), + /* 0x41 */ CHPLAN_ENT(TXPWR_LMT_WW, RTW_CHD_2G_06, TXPWR_LMT_NONE, RTW_CHD_5G_00), + /* 0x42 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_14), + /* 0x43 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_06), + /* 0x44 */ CHPLAN_ENT(TXPWR_LMT_NCC, RTW_CHD_2G_03, TXPWR_LMT_NCC, RTW_CHD_5G_09), + /* 0x45 */ CHPLAN_ENT(TXPWR_LMT_ACMA, RTW_CHD_2G_01, TXPWR_LMT_ACMA, RTW_CHD_5G_01), + /* 0x46 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_15), + /* 0x47 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_10), + /* 0x48 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_07), + /* 0x49 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_06), + /* 0x4A */ CHPLAN_ENT(TXPWR_LMT_IC, RTW_CHD_2G_03, TXPWR_LMT_IC, RTW_CHD_5G_33), + /* 0x4B */ CHPLAN_ENT(TXPWR_LMT_KCC, RTW_CHD_2G_02, TXPWR_LMT_KCC, RTW_CHD_5G_22), + /* 0x4C */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_28), + /* 0x4D */ CHPLAN_ENT(TXPWR_LMT_MEXICO, RTW_CHD_2G_02, TXPWR_LMT_MEXICO, RTW_CHD_5G_01), + /* 0x4E */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_42), + /* 0x4F */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_MKK, RTW_CHD_5G_43), + /* 0x50 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_16), + /* 0x51 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_09), + /* 0x52 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_17), + /* 0x53 */ CHPLAN_ENT(TXPWR_LMT_NCC, RTW_CHD_2G_03, TXPWR_LMT_NCC, RTW_CHD_5G_18), + /* 0x54 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_15), + /* 0x55 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_01), + /* 0x56 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_19), + /* 0x57 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_20), + /* 0x58 */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_02, TXPWR_LMT_MKK, RTW_CHD_5G_14), + /* 0x59 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_21), + /* 0x5A */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_FCC, RTW_CHD_5G_44), + /* 0x5B */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_FCC, RTW_CHD_5G_45), + /* 0x5C */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_FCC, RTW_CHD_5G_43), + /* 0x5D */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_08), + /* 0x5E */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_03), + /* 0x5F */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_02, TXPWR_LMT_MKK, RTW_CHD_5G_47), + /* 0x60 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_09), + /* 0x61 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_FCC, RTW_CHD_5G_01), + /* 0x62 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_FCC, RTW_CHD_5G_03), + /* 0x63 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_23), + /* 0x64 */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_02, TXPWR_LMT_MKK, RTW_CHD_5G_24), + /* 0x65 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_24), + /* 0x66 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_27), + /* 0x67 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_25), + /* 0x68 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_FCC, RTW_CHD_5G_27), + /* 0x69 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_FCC, RTW_CHD_5G_25), + /* 0x6A */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_25), + /* 0x6B */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_29), + /* 0x6C */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_26), + /* 0x6D */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_FCC, RTW_CHD_5G_28), + /* 0x6E */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_25), + /* 0x6F */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_ETSI, RTW_CHD_5G_06), + /* 0x70 */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_ETSI, RTW_CHD_5G_30), + /* 0x71 */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_ETSI, RTW_CHD_5G_25), + /* 0x72 */ CHPLAN_ENT(TXPWR_LMT_NONE, RTW_CHD_2G_00, TXPWR_LMT_ETSI, RTW_CHD_5G_31), + /* 0x73 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_01), + /* 0x74 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_FCC, RTW_CHD_5G_19), + /* 0x75 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_32), + /* 0x76 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_02, TXPWR_LMT_FCC, RTW_CHD_5G_22), + /* 0x77 */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_01, TXPWR_LMT_ETSI, RTW_CHD_5G_34), + /* 0x78 */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_03, TXPWR_LMT_FCC, RTW_CHD_5G_35), + /* 0x79 */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_02, TXPWR_LMT_MKK, RTW_CHD_5G_02), + /* 0x7A */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_28), + /* 0x7B */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_46), + /* 0x7C */ CHPLAN_ENT(TXPWR_LMT_ETSI, RTW_CHD_2G_02, TXPWR_LMT_ETSI, RTW_CHD_5G_47), + /* 0x7D */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_04, TXPWR_LMT_MKK, RTW_CHD_5G_48), + /* 0x7E */ CHPLAN_ENT(TXPWR_LMT_MKK, RTW_CHD_2G_02, TXPWR_LMT_MKK, RTW_CHD_5G_48), + /* 0x7F */ CHPLAN_ENT(TXPWR_LMT_FCC, RTW_CHD_2G_01, TXPWR_LMT_FCC, RTW_CHD_5G_03), }; -#if CONFIG_IEEE80211_BAND_5GHZ -static struct ch_list_t RTW_ChannelPlan5G[] = { - /* 0, RTW_RD_5G_NULL */ CH_LIST_ENT(0), - /* 1, RTW_RD_5G_ETSI1 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140), - /* 2, RTW_RD_5G_ETSI2 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165), - /* 3, RTW_RD_5G_ETSI3 */ CH_LIST_ENT(22, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165), - /* 4, RTW_RD_5G_FCC1 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165), - /* 5, RTW_RD_5G_FCC2 */ CH_LIST_ENT(9, 36, 40, 44, 48, 149, 153, 157, 161, 165), - /* 6, RTW_RD_5G_FCC3 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165), - /* 7, RTW_RD_5G_FCC4 */ CH_LIST_ENT(12, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161), - /* 8, RTW_RD_5G_FCC5 */ CH_LIST_ENT(5, 149, 153, 157, 161, 165), - /* 9, RTW_RD_5G_FCC6 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64), - /* 10, RTW_RD_5G_FCC7 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165), - /* 11, RTW_RD_5G_IC1 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165), - /* 12, RTW_RD_5G_KCC1 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161), - /* 13, RTW_RD_5G_MKK1 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140), - /* 14, RTW_RD_5G_MKK2 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64), - /* 15, RTW_RD_5G_MKK3 */ CH_LIST_ENT(11, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140), - /* 16, RTW_RD_5G_NCC1 */ CH_LIST_ENT(16, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165), - /* 17, RTW_RD_5G_NCC2 */ CH_LIST_ENT(8, 56, 60, 64, 149, 153, 157, 161, 165), - /* 18, RTW_RD_5G_NCC3 */ CH_LIST_ENT(5, 149, 153, 157, 161, 165), - /* 19, RTW_RD_5G_ETSI4 */ CH_LIST_ENT(4, 36, 40, 44, 48), - /* 20, RTW_RD_5G_ETSI5 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165), - /* 21, RTW_RD_5G_FCC8 */ CH_LIST_ENT(4, 149, 153, 157, 161), - /* 22, RTW_RD_5G_ETSI6 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64), - /* 23, RTW_RD_5G_ETSI7 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165), - /* 24, RTW_RD_5G_ETSI8 */ CH_LIST_ENT(9, 36, 40, 44, 48, 149, 153, 157, 161, 165), - /* 25, RTW_RD_5G_ETSI9 */ CH_LIST_ENT(11, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140), - /* 26, RTW_RD_5G_ETSI10 */ CH_LIST_ENT(5, 149, 153, 157, 161, 165), - /* 27, RTW_RD_5G_ETSI11 */ CH_LIST_ENT(16, 36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, 149, 153, 157, 161, 165), - /* 28, RTW_RD_5G_NCC4 */ CH_LIST_ENT(17, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165), - /* 29, RTW_RD_5G_ETSI12 */ CH_LIST_ENT(4, 149, 153, 157, 161), - /* 30, RTW_RD_5G_FCC9 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165), - /* 31, RTW_RD_5G_ETSI13 */ CH_LIST_ENT(16, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140), - /* 32, RTW_RD_5G_FCC10 */ CH_LIST_ENT(20, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161), - /* 33, RTW_RD_5G_MKK4 */ CH_LIST_ENT(4, 36, 40, 44, 48), - /* 34, RTW_RD_5G_ETSI14 */ CH_LIST_ENT(11, 36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140), - /* 35, RTW_RD_5G_FCC11 */ CH_LIST_ENT(25, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165), - /* 36, RTW_RD_5G_ETSI15 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 149, 153, 157, 161, 165), - /* 37, RTW_RD_5G_MKK5 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165), - /* 38, RTW_RD_5G_ETSI16 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165), - /* 39, RTW_RD_5G_ETSI17 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165), - /* 40, RTW_RD_5G_FCC12*/ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165), - /* 41, RTW_RD_5G_FCC13 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165), - /* 42, RTW_RD_5G_FCC14 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165), - /* 43, RTW_RD_5G_FCC15 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165), - /* 44, RTW_RD_5G_FCC16 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165), - /* 45, RTW_RD_5G_ETSI18 */ CH_LIST_ENT(9, 36, 40, 44, 48, 149, 153, 157, 161, 165), - /* 46, RTW_RD_5G_ETSI19 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165), - /* 47, RTW_RD_5G_FCC17 */ CH_LIST_ENT(16, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140), - /* 48, RTW_RD_5G_ETSI20 */ CH_LIST_ENT(9, 52, 56, 60, 64, 149, 153, 157, 161, 165), - /* 49, RTW_RD_5G_IC2 */ CH_LIST_ENT(22, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 144, 149, 153, 157, 161, 165), - /* 50, RTW_RD_5G_ETSI21 */ CH_LIST_ENT(13, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165), - /* 51, RTW_RD_5G_FCC18 */ CH_LIST_ENT(8, 100, 104, 108, 112, 116, 132, 136, 140), - /* 52, RTW_RD_5G_WORLD */ CH_LIST_ENT(25, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165), - /* 53, RTW_RD_5G_CHILE1 */ CH_LIST_ENT(25, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165), - /* 54, RTW_RD_5G_ACMA1 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165), - /* 55, RTW_RD_5G_WORLD1 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64), - /* 56, RTW_RD_5G_CHILE2 */ CH_LIST_ENT(16, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144), - /* 57, RTW_RD_5G_KCC2 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165), - /* 58, RTW_RD_5G_KCC3 */ CH_LIST_ENT(25, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165), - /* 59, RTW_RD_5G_MKK6 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 149, 153, 157, 161, 165), - /* 60, RTW_RD_5G_MKK7 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165), - /* 61, RTW_RD_5G_MKK8 */ CH_LIST_ENT(23, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 136, 140, 149, 153, 157, 161, 165), - /* 62, RTW_RD_5G_MEX1 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165), - /* 63, RTW_RD_5G_ETSI22 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165), - /* 64, RTW_RD_5G_MKK9 */ CH_LIST_ENT(23, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 136, 140, 149, 153, 157, 161, 165), - /* 65, RTW_RD_5G_FCC19 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165), - /* 66, RTW_RD_5G_FCC20 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165), - /* 67, RTW_RD_5G_FCC21 */ CH_LIST_ENT(23, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 136, 140, 149, 153, 157, 161, 165), - /* 68, RTW_RD_5G_ETSI23 */ CH_LIST_ENT(12, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161), +const int RTW_ChannelPlanMap_size = sizeof(RTW_ChannelPlanMap) / sizeof(RTW_ChannelPlanMap[0]); - /* === Below are driver defined for legacy channel plan compatible, NO static index assigned ==== */ - /* RTW_RD_5G_OLD_FCC1 */ CH_LIST_ENT(20, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165), - /* RTW_RD_5G_OLD_NCC1 */ CH_LIST_ENT(15, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165), - /* RTW_RD_5G_OLD_KCC1 */ CH_LIST_ENT(20, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165), -}; -#endif /* CONFIG_IEEE80211_BAND_5GHZ */ +u8 rtw_chplan_get_default_regd_2g(u8 id) +{ + return RTW_ChannelPlanMap[id].regd_2g; +} -static struct chplan_ent_t RTW_ChannelPlanMap[RTW_CHPLAN_MAX] = { - /* ===== 0x00 ~ 0x1F, legacy channel plan ===== */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_KCC1, TXPWR_LMT_FCC), /* 0x00, RTW_CHPLAN_FCC */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_OLD_FCC1, TXPWR_LMT_FCC), /* 0x01, RTW_CHPLAN_IC */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI1, TXPWR_LMT_ETSI), /* 0x02, RTW_CHPLAN_ETSI */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_NULL, TXPWR_LMT_ETSI), /* 0x03, RTW_CHPLAN_SPAIN */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_NULL, TXPWR_LMT_ETSI), /* 0x04, RTW_CHPLAN_FRANCE */ - CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_MKK), /* 0x05, RTW_CHPLAN_MKK */ - CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_MKK), /* 0x06, RTW_CHPLAN_MKK1 */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_FCC6, TXPWR_LMT_ETSI), /* 0x07, RTW_CHPLAN_ISRAEL */ - CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_FCC6, TXPWR_LMT_MKK), /* 0x08, RTW_CHPLAN_TELEC */ - CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x09, RTW_CHPLAN_GLOBAL_DOAMIN */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x0A, RTW_CHPLAN_WORLD_WIDE_13 */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_OLD_NCC1, TXPWR_LMT_FCC), /* 0x0B, RTW_CHPLAN_TAIWAN */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_FCC5, TXPWR_LMT_ETSI), /* 0x0C, RTW_CHPLAN_CHINA */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC3, TXPWR_LMT_WW), /* 0x0D, RTW_CHPLAN_SINGAPORE_INDIA_MEXICO */ /* ETSI:Singapore, India. FCC:Mexico => WW */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_OLD_KCC1, TXPWR_LMT_ETSI), /* 0x0E, RTW_CHPLAN_KOREA */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC6, TXPWR_LMT_ETSI), /* 0x0F, RTW_CHPLAN_TURKEY */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI1, TXPWR_LMT_MKK), /* 0x10, RTW_CHPLAN_JAPAN */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC2, TXPWR_LMT_FCC), /* 0x11, RTW_CHPLAN_FCC_NO_DFS */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_FCC7, TXPWR_LMT_MKK), /* 0x12, RTW_CHPLAN_JAPAN_NO_DFS */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC1, TXPWR_LMT_WW), /* 0x13, RTW_CHPLAN_WORLD_WIDE_5G */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NCC2, TXPWR_LMT_FCC), /* 0x14, RTW_CHPLAN_TAIWAN_NO_DFS */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC7, TXPWR_LMT_ETSI), /* 0x15, RTW_CHPLAN_ETSI_NO_DFS */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_NCC1, TXPWR_LMT_ETSI), /* 0x16, RTW_CHPLAN_KOREA_NO_DFS */ - CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_FCC7, TXPWR_LMT_MKK), /* 0x17, RTW_CHPLAN_JAPAN_NO_DFS */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_FCC5, TXPWR_LMT_ETSI), /* 0x18, RTW_CHPLAN_PAKISTAN_NO_DFS */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC5, TXPWR_LMT_FCC), /* 0x19, RTW_CHPLAN_TAIWAN2_NO_DFS */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x1A, */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x1B, */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x1C, */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x1D, */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x1E, */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_FCC1, TXPWR_LMT_WW), /* 0x1F, RTW_CHPLAN_WORLD_WIDE_ONLY_5G */ - - /* ===== 0x20 ~ 0x7F, new channel plan ===== */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x20, RTW_CHPLAN_WORLD_NULL */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_NULL, TXPWR_LMT_ETSI), /* 0x21, RTW_CHPLAN_ETSI1_NULL */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NULL, TXPWR_LMT_FCC), /* 0x22, RTW_CHPLAN_FCC1_NULL */ - CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_MKK), /* 0x23, RTW_CHPLAN_MKK1_NULL */ - CHPLAN_ENT(RTW_RD_2G_ETSI2, RTW_RD_5G_NULL, TXPWR_LMT_ETSI), /* 0x24, RTW_CHPLAN_ETSI2_NULL */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC1, TXPWR_LMT_FCC), /* 0x25, RTW_CHPLAN_FCC1_FCC1 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI1, TXPWR_LMT_ETSI), /* 0x26, RTW_CHPLAN_WORLD_ETSI1 */ - CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_MKK1, TXPWR_LMT_MKK), /* 0x27, RTW_CHPLAN_MKK1_MKK1 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_KCC1, TXPWR_LMT_KCC), /* 0x28, RTW_CHPLAN_WORLD_KCC1 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC2, TXPWR_LMT_FCC), /* 0x29, RTW_CHPLAN_WORLD_FCC2 */ - CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_NULL, TXPWR_LMT_FCC), /* 0x2A, RTW_CHPLAN_FCC2_NULL */ - CHPLAN_ENT(RTW_RD_2G_IC1, RTW_RD_5G_IC2, TXPWR_LMT_IC), /* 0x2B, RTW_CHPLAN_IC1_IC2 */ - CHPLAN_ENT(RTW_RD_2G_MKK2, RTW_RD_5G_NULL, TXPWR_LMT_MKK), /* 0x2C, RTW_CHPLAN_MKK2_NULL */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_CHILE1, TXPWR_LMT_CHILE), /* 0x2D, RTW_CHPLAN_WORLD_CHILE1 */ - CHPLAN_ENT(RTW_RD_2G_WORLD1, RTW_RD_5G_WORLD1, TXPWR_LMT_WW), /* 0x2E, RTW_CHPLAN_WORLD1_WORLD1 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_CHILE2, TXPWR_LMT_CHILE), /* 0x2F, RTW_CHPLAN_WORLD_CHILE2 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC3, TXPWR_LMT_FCC), /* 0x30, RTW_CHPLAN_WORLD_FCC3 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC4, TXPWR_LMT_FCC), /* 0x31, RTW_CHPLAN_WORLD_FCC4 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC5, TXPWR_LMT_FCC), /* 0x32, RTW_CHPLAN_WORLD_FCC5 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC6, TXPWR_LMT_FCC), /* 0x33, RTW_CHPLAN_WORLD_FCC6 */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC7, TXPWR_LMT_FCC), /* 0x34, RTW_CHPLAN_FCC1_FCC7 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI2, TXPWR_LMT_ETSI), /* 0x35, RTW_CHPLAN_WORLD_ETSI2 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI3, TXPWR_LMT_ETSI), /* 0x36, RTW_CHPLAN_WORLD_ETSI3 */ - CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_MKK2, TXPWR_LMT_MKK), /* 0x37, RTW_CHPLAN_MKK1_MKK2 */ - CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_MKK3, TXPWR_LMT_MKK), /* 0x38, RTW_CHPLAN_MKK1_MKK3 */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NCC1, TXPWR_LMT_FCC), /* 0x39, RTW_CHPLAN_FCC1_NCC1 */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI1, TXPWR_LMT_ETSI), /* 0x3A, RTW_CHPLAN_ETSI1_ETSI1 */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ACMA1, TXPWR_LMT_ACMA), /* 0x3B, RTW_CHPLAN_ETSI1_ACMA1 */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI6, TXPWR_LMT_ETSI), /* 0x3C, RTW_CHPLAN_ETSI1_ETSI6 */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI12, TXPWR_LMT_ETSI), /* 0x3D, RTW_CHPLAN_ETSI1_ETSI12 */ - CHPLAN_ENT(RTW_RD_2G_KCC1, RTW_RD_5G_KCC2, TXPWR_LMT_KCC), /* 0x3E, RTW_CHPLAN_KCC1_KCC2 */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC11, TXPWR_LMT_FCC), /* 0x3F, RTW_CHPLAN_FCC1_FCC11*/ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NCC2, TXPWR_LMT_FCC), /* 0x40, RTW_CHPLAN_FCC1_NCC2 */ - CHPLAN_ENT(RTW_RD_2G_GLOBAL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x41, RTW_CHPLAN_GLOBAL_NULL */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI4, TXPWR_LMT_ETSI), /* 0x42, RTW_CHPLAN_ETSI1_ETSI4 */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC2, TXPWR_LMT_FCC), /* 0x43, RTW_CHPLAN_FCC1_FCC2 */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NCC3, TXPWR_LMT_FCC), /* 0x44, RTW_CHPLAN_FCC1_NCC3 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ACMA1, TXPWR_LMT_ACMA), /* 0x45, RTW_CHPLAN_WORLD_ACMA1 */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC8, TXPWR_LMT_FCC), /* 0x46, RTW_CHPLAN_FCC1_FCC8 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI6, TXPWR_LMT_ETSI), /* 0x47, RTW_CHPLAN_WORLD_ETSI6 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI7, TXPWR_LMT_ETSI), /* 0x48, RTW_CHPLAN_WORLD_ETSI7 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI8, TXPWR_LMT_ETSI), /* 0x49, RTW_CHPLAN_WORLD_ETSI8 */ - CHPLAN_ENT(RTW_RD_2G_IC2, RTW_RD_5G_IC2, TXPWR_LMT_IC), /* 0x4A, RTW_CHPLAN_IC2_IC2 */ - CHPLAN_ENT(RTW_RD_2G_KCC1, RTW_RD_5G_KCC3, TXPWR_LMT_KCC), /* 0x4B, RTW_CHPLAN_KCC1_KCC3 */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC15, TXPWR_LMT_FCC), /* 0x4C, RTW_CHPLAN_FCC1_FCC15 */ - CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_MEX1, TXPWR_LMT_MEXICO), /* 0x4D, RTW_CHPLAN_FCC2_MEX1 */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI22, TXPWR_LMT_ETSI), /* 0x4E, RTW_CHPLAN_ETSI1_ETSI22 */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_MKK9, TXPWR_LMT_MKK), /* 0x4F, RTW_CHPLAN_NULL_MKK9 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI9, TXPWR_LMT_ETSI), /* 0x50, RTW_CHPLAN_WORLD_ETSI9 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI10, TXPWR_LMT_ETSI), /* 0x51, RTW_CHPLAN_WORLD_ETSI10 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI11, TXPWR_LMT_ETSI), /* 0x52, RTW_CHPLAN_WORLD_ETSI11 */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NCC4, TXPWR_LMT_FCC), /* 0x53, RTW_CHPLAN_FCC1_NCC4 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI12, TXPWR_LMT_ETSI), /* 0x54, RTW_CHPLAN_WORLD_ETSI12 */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC9, TXPWR_LMT_FCC), /* 0x55, RTW_CHPLAN_FCC1_FCC9 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI13, TXPWR_LMT_ETSI), /* 0x56, RTW_CHPLAN_WORLD_ETSI13 */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC10, TXPWR_LMT_FCC), /* 0x57, RTW_CHPLAN_FCC1_FCC10 */ - CHPLAN_ENT(RTW_RD_2G_MKK2, RTW_RD_5G_MKK4, TXPWR_LMT_MKK), /* 0x58, RTW_CHPLAN_MKK2_MKK4 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI14, TXPWR_LMT_ETSI), /* 0x59, RTW_CHPLAN_WORLD_ETSI14 */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_FCC19, TXPWR_LMT_FCC), /* 0x5A, RTW_CHPLAN_NULL_FCC19 */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_FCC20, TXPWR_LMT_FCC), /* 0x5B, RTW_CHPLAN_NULL_FCC20 */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_FCC21, TXPWR_LMT_FCC), /* 0x5C, RTW_CHPLAN_NULL_FCC21 */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI23, TXPWR_LMT_ETSI), /* 0x5D, RTW_CHPLAN_ETSI1_ETSI23 */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI2, TXPWR_LMT_ETSI), /* 0x5E, RTW_CHPLAN_ETSI1_ETSI2 */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x5F, */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC5, TXPWR_LMT_FCC), /* 0x60, RTW_CHPLAN_FCC1_FCC5 */ - CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC7, TXPWR_LMT_FCC), /* 0x61, RTW_CHPLAN_FCC2_FCC7 */ - CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC1, TXPWR_LMT_FCC), /* 0x62, RTW_CHPLAN_FCC2_FCC1 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI15, TXPWR_LMT_ETSI), /* 0x63, RTW_CHPLAN_WORLD_ETSI15 */ - CHPLAN_ENT(RTW_RD_2G_MKK2, RTW_RD_5G_MKK5, TXPWR_LMT_MKK), /* 0x64, RTW_CHPLAN_MKK2_MKK5 */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI16, TXPWR_LMT_ETSI), /* 0x65, RTW_CHPLAN_ETSI1_ETSI16 */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC14, TXPWR_LMT_FCC), /* 0x66, RTW_CHPLAN_FCC1_FCC14 */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC12, TXPWR_LMT_FCC), /* 0x67, RTW_CHPLAN_FCC1_FCC12 */ - CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC14, TXPWR_LMT_FCC), /* 0x68, RTW_CHPLAN_FCC2_FCC14 */ - CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC12, TXPWR_LMT_FCC), /* 0x69, RTW_CHPLAN_FCC2_FCC12 */ - CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI17, TXPWR_LMT_ETSI), /* 0x6A, RTW_CHPLAN_ETSI1_ETSI17 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC16, TXPWR_LMT_FCC), /* 0x6B, RTW_CHPLAN_WORLD_FCC16 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC13, TXPWR_LMT_FCC), /* 0x6C, RTW_CHPLAN_WORLD_FCC13 */ - CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC15, TXPWR_LMT_FCC), /* 0x6D, RTW_CHPLAN_FCC2_FCC15 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC12, TXPWR_LMT_FCC), /* 0x6E, RTW_CHPLAN_WORLD_FCC12 */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_ETSI8, TXPWR_LMT_ETSI), /* 0x6F, RTW_CHPLAN_NULL_ETSI8 */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_ETSI18, TXPWR_LMT_ETSI), /* 0x70, RTW_CHPLAN_NULL_ETSI18 */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_ETSI17, TXPWR_LMT_ETSI), /* 0x71, RTW_CHPLAN_NULL_ETSI17 */ - CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_ETSI19, TXPWR_LMT_ETSI), /* 0x72, RTW_CHPLAN_NULL_ETSI19 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC7, TXPWR_LMT_FCC), /* 0x73, RTW_CHPLAN_WORLD_FCC7 */ - CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC17, TXPWR_LMT_FCC), /* 0x74, RTW_CHPLAN_FCC2_FCC17 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI20, TXPWR_LMT_ETSI), /* 0x75, RTW_CHPLAN_WORLD_ETSI20 */ - CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC11, TXPWR_LMT_FCC), /* 0x76, RTW_CHPLAN_FCC2_FCC11 */ - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI21, TXPWR_LMT_ETSI), /* 0x77, RTW_CHPLAN_WORLD_ETSI21 */ - CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC18, TXPWR_LMT_FCC), /* 0x78, RTW_CHPLAN_FCC1_FCC18 */ - CHPLAN_ENT(RTW_RD_2G_MKK2, RTW_RD_5G_MKK1, TXPWR_LMT_MKK), /* 0x79, RTW_CHPLAN_MKK2_MKK1 */ -}; - -static struct chplan_ent_t RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = - CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC1, TXPWR_LMT_FCC); /* 0x7F, Realtek Define */ +u8 rtw_chplan_get_default_regd_5g(u8 id) +{ +#if CONFIG_IEEE80211_BAND_5GHZ + return RTW_ChannelPlanMap[id].regd_5g; +#else + return TXPWR_LMT_NONE; +#endif +} u8 rtw_chplan_get_default_regd(u8 id) { - u8 regd; + u8 regd_2g = rtw_chplan_get_default_regd_2g(id); + u8 regd_5g = rtw_chplan_get_default_regd_5g(id); - if (id == RTW_CHPLAN_REALTEK_DEFINE) - regd = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.regd; - else - regd = RTW_ChannelPlanMap[id].regd; - - return regd; + if (regd_2g != TXPWR_LMT_NONE && regd_5g != TXPWR_LMT_NONE) { + if (regd_2g != regd_5g) + RTW_WARN("channel_plan:0x%02x, regd_2g:%u, regd_5g:%u not the same\n", id, regd_2g, regd_5g); + return regd_5g; + } + return regd_2g != TXPWR_LMT_NONE ? regd_2g : regd_5g; } bool rtw_chplan_is_empty(u8 id) { - struct chplan_ent_t *chplan_map; + const struct chplan_ent_t *chplan_map = &RTW_ChannelPlanMap[id]; - if (id == RTW_CHPLAN_REALTEK_DEFINE) - chplan_map = &RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE; - else - chplan_map = &RTW_ChannelPlanMap[id]; - - if (chplan_map->rd_2g == RTW_RD_2G_NULL + if (chplan_map->chd_2g == RTW_CHD_2G_NULL #if CONFIG_IEEE80211_BAND_5GHZ - && chplan_map->rd_5g == RTW_RD_5G_NULL + && chplan_map->chd_5g == RTW_CHD_5G_NULL #endif ) return _TRUE; @@ -427,6 +371,11 @@ bool rtw_chplan_is_empty(u8 id) return _FALSE; } +bool rtw_is_channel_plan_valid(u8 id) +{ + return id < RTW_ChannelPlanMap_size && !rtw_chplan_is_empty(id); +} + bool rtw_regsty_is_excl_chs(struct registry_priv *regsty, u8 ch) { int i; @@ -440,58 +389,20 @@ bool rtw_regsty_is_excl_chs(struct registry_priv *regsty, u8 ch) return _FALSE; } -inline static u8 rtw_rd_5g_band1_passive(u8 rtw_rd_5g) -{ - u8 passive = 0; - - switch (rtw_rd_5g) { - case RTW_RD_5G_FCC13: - case RTW_RD_5G_FCC16: - case RTW_RD_5G_ETSI18: - case RTW_RD_5G_ETSI19: - case RTW_RD_5G_WORLD: - case RTW_RD_5G_WORLD1: - case RTW_RD_5G_MKK6: - case RTW_RD_5G_MKK7: - case RTW_RD_5G_ETSI22: - case RTW_RD_5G_MKK9: - case RTW_RD_5G_FCC19: - case RTW_RD_5G_FCC20: - case RTW_RD_5G_FCC21: - passive = 1; - }; - - return passive; -} - -inline static u8 rtw_rd_5g_band4_passive(u8 rtw_rd_5g) -{ - u8 passive = 0; - - switch (rtw_rd_5g) { - case RTW_RD_5G_MKK5: - case RTW_RD_5G_ETSI16: - case RTW_RD_5G_ETSI18: - case RTW_RD_5G_ETSI19: - case RTW_RD_5G_WORLD: - case RTW_RD_5G_MKK8: - case RTW_RD_5G_ETSI22: - case RTW_RD_5G_MKK9: - case RTW_RD_5G_FCC19: - case RTW_RD_5G_FCC20: - case RTW_RD_5G_FCC21: - passive = 1; - }; - - return passive; -} - -u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set) +const char *_regd_src_str[] = { + [REGD_SRC_RTK_PRIV] = "RTK_PRIV", + [REGD_SRC_OS] = "OS", + [REGD_SRC_NUM] = "UNKNOWN", +}; + +static u8 init_channel_set_from_rtk_priv(_adapter *padapter, RT_CHANNEL_INFO *channel_set) { + struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); struct registry_priv *regsty = adapter_to_regsty(padapter); - u8 index, chanset_size = 0; - u8 b5GBand = _FALSE, b2_4GBand = _FALSE; - u8 rd_2g = 0, rd_5g = 0; + u8 ChannelPlan = rfctl->ChannelPlan; + u8 index, chanset_size = 0; + u8 b5GBand = _FALSE, b2_4GBand = _FALSE; + u8 ch, attrib; #ifdef CONFIG_DFS_MASTER int i; #endif @@ -515,13 +426,13 @@ u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel } if (b2_4GBand) { - if (ChannelPlan == RTW_CHPLAN_REALTEK_DEFINE) - rd_2g = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.rd_2g; - else - rd_2g = RTW_ChannelPlanMap[ChannelPlan].rd_2g; + u8 chd_2g = RTW_ChannelPlanMap[ChannelPlan].chd_2g; + + attrib = CH_LIST_ATTRIB(rtw_channel_def_2g[chd_2g]); - for (index = 0; index < CH_LIST_LEN(RTW_ChannelPlan2G[rd_2g]); index++) { - if (rtw_regsty_is_excl_chs(regsty, CH_LIST_CH(RTW_ChannelPlan2G[rd_2g], index)) == _TRUE) + for (index = 0; index < CH_LIST_LEN(rtw_channel_def_2g[chd_2g]); index++) { + ch = CH_LIST_CH(rtw_channel_def_2g[chd_2g], index); + if (rtw_regsty_is_excl_chs(regsty, ch) == _TRUE) continue; if (chanset_size >= MAX_CHANNEL_NUM) { @@ -529,27 +440,15 @@ u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel break; } - channel_set[chanset_size].ChannelNum = CH_LIST_CH(RTW_ChannelPlan2G[rd_2g], index); - - if (ChannelPlan == RTW_CHPLAN_GLOBAL_DOAMIN - || rd_2g == RTW_RD_2G_GLOBAL - ) { - /* Channel 1~11 is active, and 12~14 is passive */ - if (channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11) - channel_set[chanset_size].ScanType = SCAN_ACTIVE; - else if ((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14)) - channel_set[chanset_size].ScanType = SCAN_PASSIVE; - } else if (ChannelPlan == RTW_CHPLAN_WORLD_WIDE_13 - || ChannelPlan == RTW_CHPLAN_WORLD_WIDE_5G - || rd_2g == RTW_RD_2G_WORLD - ) { - /* channel 12~13, passive scan */ - if (channel_set[chanset_size].ChannelNum <= 11) - channel_set[chanset_size].ScanType = SCAN_ACTIVE; - else - channel_set[chanset_size].ScanType = SCAN_PASSIVE; - } else - channel_set[chanset_size].ScanType = SCAN_ACTIVE; + channel_set[chanset_size].ChannelNum = ch; + + if (ch >= 12 && ch <= 14 && (attrib & CLA_2G_12_14_PASSIVE)) + channel_set[chanset_size].flags |= RTW_CHF_NO_IR; + + if (channel_set[chanset_size].flags & RTW_CHF_NO_IR) { + if (rfctl->country_ent || ch <= 11) + RTW_INFO("ch%u is PASSIVE\n", ch); + } chanset_size++; } @@ -557,16 +456,20 @@ u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel #if CONFIG_IEEE80211_BAND_5GHZ if (b5GBand) { - if (ChannelPlan == RTW_CHPLAN_REALTEK_DEFINE) - rd_5g = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.rd_5g; - else - rd_5g = RTW_ChannelPlanMap[ChannelPlan].rd_5g; + bool dfs; + u8 chd_5g = RTW_ChannelPlanMap[ChannelPlan].chd_5g; + + attrib = CH_LIST_ATTRIB(rtw_channel_def_5g[chd_5g]); - for (index = 0; index < CH_LIST_LEN(RTW_ChannelPlan5G[rd_5g]); index++) { - if (rtw_regsty_is_excl_chs(regsty, CH_LIST_CH(RTW_ChannelPlan5G[rd_5g], index)) == _TRUE) + for (index = 0; index < CH_LIST_LEN(rtw_channel_def_5g[chd_5g]); index++) { + ch = CH_LIST_CH(rtw_channel_def_5g[chd_5g], index); + if (rtw_regsty_is_excl_chs(regsty, ch) == _TRUE) continue; + dfs = (rtw_is_5g_band2(ch) && (attrib & CLA_5G_B2_DFS)) + || (rtw_is_5g_band3(ch) && (attrib & CLA_5G_B3_DFS)) + || (rtw_is_5g_band4(ch) && (attrib & CLA_5G_B4_DFS)); #if !CONFIG_DFS - if (rtw_is_dfs_ch(CH_LIST_CH(RTW_ChannelPlan5G[rd_5g], index))) + if (dfs) continue; #endif @@ -575,18 +478,22 @@ u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel break; } - channel_set[chanset_size].ChannelNum = CH_LIST_CH(RTW_ChannelPlan5G[rd_5g], index); + channel_set[chanset_size].ChannelNum = ch; - if ((ChannelPlan == RTW_CHPLAN_WORLD_WIDE_5G) /* all channels passive */ - || (rtw_is_5g_band1(channel_set[chanset_size].ChannelNum) - && rtw_rd_5g_band1_passive(rd_5g)) /* band1 passive */ - || (rtw_is_5g_band4(channel_set[chanset_size].ChannelNum) - && rtw_rd_5g_band4_passive(rd_5g)) /* band4 passive */ - || (rtw_is_dfs_ch(channel_set[chanset_size].ChannelNum)) /* DFS channel(band2, 3) passive */ + if ((rtw_is_5g_band1(ch) && (attrib & CLA_5G_B1_PASSIVE)) /* band1 passive */ + || (rtw_is_5g_band2(ch) && (attrib & CLA_5G_B2_PASSIVE)) /* band2 passive */ + || (rtw_is_5g_band3(ch) && (attrib & CLA_5G_B3_PASSIVE)) /* band3 passive */ + || (rtw_is_5g_band4(ch) && (attrib & CLA_5G_B4_PASSIVE)) /* band4 passive */ ) - channel_set[chanset_size].ScanType = SCAN_PASSIVE; - else - channel_set[chanset_size].ScanType = SCAN_ACTIVE; + channel_set[chanset_size].flags |= RTW_CHF_NO_IR; + + if (dfs) + channel_set[chanset_size].flags |= RTW_CHF_DFS; + + if (channel_set[chanset_size].flags & RTW_CHF_NO_IR) { + if (rfctl->country_ent || (channel_set[chanset_size].flags & RTW_CHF_DFS)) + RTW_INFO("ch%u is PASSIVE%s\n", ch, dfs ? " DFS" : ""); + } chanset_size++; } @@ -608,23 +515,113 @@ u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel return chanset_size; } +u8 init_channel_set(_adapter *adapter) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + if (rfctl->regd_src == REGD_SRC_RTK_PRIV) + return init_channel_set_from_rtk_priv(adapter, rfctl->channel_set); +#ifdef CONFIG_REGD_SRC_FROM_OS + else if (rfctl->regd_src == REGD_SRC_OS) + return rtw_os_init_channel_set(adapter, rfctl->channel_set); +#endif + else + rtw_warn_on(1); + + return 0; +} + +bool rtw_chset_is_dfs_range(struct _RT_CHANNEL_INFO *chset, u32 hi, u32 lo) +{ + u8 hi_ch = rtw_freq2ch(hi); + u8 lo_ch = rtw_freq2ch(lo); + int i; + + for (i = 0; i < MAX_CHANNEL_NUM && chset[i].ChannelNum != 0; i++){ + if (!(chset[i].flags & RTW_CHF_DFS)) + continue; + if (hi_ch > chset[i].ChannelNum && lo_ch < chset[i].ChannelNum) + return 1; + } + + return 0; +} + +bool rtw_chset_is_dfs_ch(struct _RT_CHANNEL_INFO *chset, u8 ch) +{ + int i; + + for (i = 0; i < MAX_CHANNEL_NUM && chset[i].ChannelNum != 0; i++){ + if (chset[i].ChannelNum == ch) + return chset[i].flags & RTW_CHF_DFS ? 1 : 0; + } + + return 0; +} + +bool rtw_chset_is_dfs_chbw(struct _RT_CHANNEL_INFO *chset, u8 ch, u8 bw, u8 offset) +{ + u32 hi, lo; + + if (!rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo)) + return 0; + + return rtw_chset_is_dfs_range(chset, hi, lo); +} + +u8 rtw_process_beacon_hint(_adapter *adapter, WLAN_BSSID_EX *bss) +{ +#ifndef RTW_CHPLAN_BEACON_HINT_NON_WORLD_WIDE +#define RTW_CHPLAN_BEACON_HINT_NON_WORLD_WIDE 0 +#endif + +#ifndef RTW_CHPLAN_BEACON_HINT_ON_2G_CH_1_11 +#define RTW_CHPLAN_BEACON_HINT_ON_2G_CH_1_11 0 +#endif + +#ifndef RTW_CHPLAN_BEACON_HINT_ON_DFS_CH +#define RTW_CHPLAN_BEACON_HINT_ON_DFS_CH 0 +#endif + + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + RT_CHANNEL_INFO *chset = rfctl->channel_set; + u8 ch = bss->Configuration.DSConfig; + int chset_idx = rtw_chset_search_ch(chset, ch); + u8 act_cnt = 0; + + if (chset_idx < 0) + goto exit; + + if ((chset[chset_idx].flags & RTW_CHF_NO_IR) + && (RTW_CHPLAN_BEACON_HINT_NON_WORLD_WIDE || !rfctl->country_ent || IS_ALPHA2_WORLDWIDE(rfctl->country_ent->alpha2)) + && (RTW_CHPLAN_BEACON_HINT_ON_2G_CH_1_11 || !(ch <= 11)) + && (RTW_CHPLAN_BEACON_HINT_ON_DFS_CH || !(chset[chset_idx].flags & RTW_CHF_DFS)) + ) { + RTW_INFO("%s: change ch:%d to active\n", __func__, ch); + chset[chset_idx].flags &= ~RTW_CHF_NO_IR; + act_cnt++; + } + +exit: + return act_cnt; +} + +const char *_rtw_dfs_regd_str[] = { + [RTW_DFS_REGD_NONE] = "NONE", + [RTW_DFS_REGD_FCC] = "FCC", + [RTW_DFS_REGD_MKK] = "MKK", + [RTW_DFS_REGD_ETSI] = "ETSI", +}; + #ifdef CONFIG_80211AC_VHT #define COUNTRY_CHPLAN_ASSIGN_EN_11AC(_val) , .en_11ac = (_val) #else #define COUNTRY_CHPLAN_ASSIGN_EN_11AC(_val) #endif -#if RTW_DEF_MODULE_REGULATORY_CERT -#define COUNTRY_CHPLAN_ASSIGN_DEF_MODULE_FLAGS(_val) , .def_module_flags = (_val) -#else -#define COUNTRY_CHPLAN_ASSIGN_DEF_MODULE_FLAGS(_val) -#endif - -/* has def_module_flags specified, used by common map and HAL dfference map */ -#define COUNTRY_CHPLAN_ENT(_alpha2, _chplan, _en_11ac, _def_module_flags) \ +#define COUNTRY_CHPLAN_ENT(_alpha2, _chplan, _en_11ac) \ {.alpha2 = (_alpha2), .chplan = (_chplan) \ COUNTRY_CHPLAN_ASSIGN_EN_11AC(_en_11ac) \ - COUNTRY_CHPLAN_ASSIGN_DEF_MODULE_FLAGS(_def_module_flags) \ } #ifdef CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP @@ -633,487 +630,1739 @@ u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel #elif RTW_DEF_MODULE_REGULATORY_CERT -/* leave def_module_flags empty, def_module_flags check is done on country_chplan_map */ #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8821AE_HMC_M2) /* 2013 certify */ -static const struct country_chplan RTL8821AE_HMC_M2_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("CA", 0x34, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("CL", 0x30, 1, 0), /* Chile */ - COUNTRY_CHPLAN_ENT("CN", 0x51, 1, 0), /* China */ - COUNTRY_CHPLAN_ENT("CO", 0x34, 1, 0), /* Colombia */ - COUNTRY_CHPLAN_ENT("CR", 0x34, 1, 0), /* Costa Rica */ - COUNTRY_CHPLAN_ENT("DO", 0x34, 1, 0), /* Dominican Republic */ - COUNTRY_CHPLAN_ENT("EC", 0x34, 1, 0), /* Ecuador */ - COUNTRY_CHPLAN_ENT("GT", 0x34, 1, 0), /* Guatemala */ - COUNTRY_CHPLAN_ENT("ID", 0x3D, 0, 0), /* Indonesia */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("MX", 0x34, 1, 0), /* Mexico */ - COUNTRY_CHPLAN_ENT("MY", 0x47, 1, 0), /* Malaysia */ - COUNTRY_CHPLAN_ENT("NI", 0x34, 1, 0), /* Nicaragua */ - COUNTRY_CHPLAN_ENT("PA", 0x34, 1, 0), /* Panama */ - COUNTRY_CHPLAN_ENT("PE", 0x34, 1, 0), /* Peru */ - COUNTRY_CHPLAN_ENT("PR", 0x34, 1, 0), /* Puerto Rico */ - COUNTRY_CHPLAN_ENT("PY", 0x34, 1, 0), /* Paraguay */ - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("UA", 0x36, 0, 0), /* Ukraine */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ +static const struct country_chplan RTL8821AE_HMC_M2_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x34, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x30, 1), + COUNTRY_CHPLAN_ENT("CN", 0x51, 1), + COUNTRY_CHPLAN_ENT("CO", 0x34, 1), + COUNTRY_CHPLAN_ENT("CR", 0x34, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x34, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x34, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x34, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x3D, 0), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x34, 1), + COUNTRY_CHPLAN_ENT("MY", 0x47, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x34, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x34, 1), + COUNTRY_CHPLAN_ENT("PE", 0x34, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x34, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x34, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("UA", 0x36, 0), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8821AU) /* 2014 certify */ -static const struct country_chplan RTL8821AU_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("CA", 0x34, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("ID", 0x3D, 0, 0), /* Indonesia */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("RU", 0x59, 0, 0), /* Russia(fac/gost), Kaliningrad */ - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("UA", 0x36, 0, 0), /* Ukraine */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ +static const struct country_chplan RTL8821AU_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x34, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x3D, 0), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 0), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("UA", 0x36, 0), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8812AENF_NGFF) /* 2014 certify */ -static const struct country_chplan RTL8812AENF_NGFF_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ +static const struct country_chplan RTL8812AENF_NGFF_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8812AEBT_HMC) /* 2013 certify */ -static const struct country_chplan RTL8812AEBT_HMC_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("CA", 0x34, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("RU", 0x59, 0, 0), /* Russia(fac/gost), Kaliningrad */ - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("UA", 0x36, 0, 0), /* Ukraine */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ +static const struct country_chplan RTL8812AEBT_HMC_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x34, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 0), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("UA", 0x36, 0), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8188EE_HMC_M2) /* 2012 certify */ -static const struct country_chplan RTL8188EE_HMC_M2_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("AW", 0x34, 1, 0), /* Aruba */ - COUNTRY_CHPLAN_ENT("BB", 0x34, 1, 0), /* Barbados */ - COUNTRY_CHPLAN_ENT("CA", 0x20, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("CO", 0x34, 1, 0), /* Colombia */ - COUNTRY_CHPLAN_ENT("CR", 0x34, 1, 0), /* Costa Rica */ - COUNTRY_CHPLAN_ENT("DO", 0x34, 1, 0), /* Dominican Republic */ - COUNTRY_CHPLAN_ENT("EC", 0x34, 1, 0), /* Ecuador */ - COUNTRY_CHPLAN_ENT("GT", 0x34, 1, 0), /* Guatemala */ - COUNTRY_CHPLAN_ENT("HT", 0x34, 1, 0), /* Haiti */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("MX", 0x34, 1, 0), /* Mexico */ - COUNTRY_CHPLAN_ENT("NI", 0x34, 1, 0), /* Nicaragua */ - COUNTRY_CHPLAN_ENT("PA", 0x34, 1, 0), /* Panama */ - COUNTRY_CHPLAN_ENT("PE", 0x34, 1, 0), /* Peru */ - COUNTRY_CHPLAN_ENT("PR", 0x34, 1, 0), /* Puerto Rico */ - COUNTRY_CHPLAN_ENT("PY", 0x34, 1, 0), /* Paraguay */ - COUNTRY_CHPLAN_ENT("SC", 0x34, 1, 0), /* Seychelles */ - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ - COUNTRY_CHPLAN_ENT("VC", 0x34, 1, 0), /* Saint Vincent and the Grenadines */ +static const struct country_chplan RTL8188EE_HMC_M2_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AM", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AW", 0x34, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BB", 0x34, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BF", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BI", 0x26, 1), + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BN", 0x47, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x20, 1), + COUNTRY_CHPLAN_ENT("CD", 0x26, 1), + COUNTRY_CHPLAN_ENT("CF", 0x26, 1), + COUNTRY_CHPLAN_ENT("CG", 0x26, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CM", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x34, 1), + COUNTRY_CHPLAN_ENT("CR", 0x34, 1), + COUNTRY_CHPLAN_ENT("CV", 0x26, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x34, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x34, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("ET", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GA", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GD", 0x76, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GM", 0x26, 1), + COUNTRY_CHPLAN_ENT("GN", 0x26, 1), + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x34, 1), + COUNTRY_CHPLAN_ENT("GW", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HT", 0x34, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x5D, 1), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LR", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("ML", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MU", 0x26, 1), + COUNTRY_CHPLAN_ENT("MW", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x34, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NE", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x34, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x34, 1), + COUNTRY_CHPLAN_ENT("PE", 0x34, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x34, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x34, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("RW", 0x26, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SC", 0x34, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SL", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("TD", 0x26, 1), + COUNTRY_CHPLAN_ENT("TG", 0x26, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), + COUNTRY_CHPLAN_ENT("VC", 0x34, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8723BE_HMC_M2) /* 2013 certify */ -static const struct country_chplan RTL8723BE_HMC_M2_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("AW", 0x34, 1, 0), /* Aruba */ - COUNTRY_CHPLAN_ENT("BS", 0x34, 1, 0), /* Bahamas */ - COUNTRY_CHPLAN_ENT("CA", 0x20, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("CO", 0x34, 1, 0), /* Colombia */ - COUNTRY_CHPLAN_ENT("CR", 0x34, 1, 0), /* Costa Rica */ - COUNTRY_CHPLAN_ENT("DO", 0x34, 1, 0), /* Dominican Republic */ - COUNTRY_CHPLAN_ENT("EC", 0x34, 1, 0), /* Ecuador */ - COUNTRY_CHPLAN_ENT("GT", 0x34, 1, 0), /* Guatemala */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("MX", 0x34, 1, 0), /* Mexico */ - COUNTRY_CHPLAN_ENT("NI", 0x34, 1, 0), /* Nicaragua */ - COUNTRY_CHPLAN_ENT("PA", 0x34, 1, 0), /* Panama */ - COUNTRY_CHPLAN_ENT("PE", 0x34, 1, 0), /* Peru */ - COUNTRY_CHPLAN_ENT("PR", 0x34, 1, 0), /* Puerto Rico */ - COUNTRY_CHPLAN_ENT("PY", 0x34, 1, 0), /* Paraguay */ - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ +static const struct country_chplan RTL8723BE_HMC_M2_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AM", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AO", 0x47, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AW", 0x34, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BF", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BI", 0x26, 1), + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BS", 0x34, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x20, 1), + COUNTRY_CHPLAN_ENT("CD", 0x26, 1), + COUNTRY_CHPLAN_ENT("CF", 0x26, 1), + COUNTRY_CHPLAN_ENT("CG", 0x26, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CM", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x34, 1), + COUNTRY_CHPLAN_ENT("CR", 0x34, 1), + COUNTRY_CHPLAN_ENT("CV", 0x26, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x34, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x34, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("ET", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GA", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GD", 0x76, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GM", 0x26, 1), + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x34, 1), + COUNTRY_CHPLAN_ENT("GW", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x5D, 1), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LR", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MG", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("ML", 0x26, 1), + COUNTRY_CHPLAN_ENT("MR", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MU", 0x26, 1), + COUNTRY_CHPLAN_ENT("MW", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x34, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NE", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x34, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x34, 1), + COUNTRY_CHPLAN_ENT("PE", 0x34, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x34, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x34, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("RW", 0x26, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SL", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("SZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("TD", 0x26, 1), + COUNTRY_CHPLAN_ENT("TG", 0x26, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8723BS_NGFF1216) /* 2014 certify */ -static const struct country_chplan RTL8723BS_NGFF1216_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("BB", 0x34, 1, 0), /* Barbados */ - COUNTRY_CHPLAN_ENT("CA", 0x20, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("CO", 0x34, 1, 0), /* Colombia */ - COUNTRY_CHPLAN_ENT("CR", 0x34, 1, 0), /* Costa Rica */ - COUNTRY_CHPLAN_ENT("DO", 0x34, 1, 0), /* Dominican Republic */ - COUNTRY_CHPLAN_ENT("EC", 0x34, 1, 0), /* Ecuador */ - COUNTRY_CHPLAN_ENT("GT", 0x34, 1, 0), /* Guatemala */ - COUNTRY_CHPLAN_ENT("HT", 0x34, 1, 0), /* Haiti */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("MX", 0x34, 1, 0), /* Mexico */ - COUNTRY_CHPLAN_ENT("NI", 0x34, 1, 0), /* Nicaragua */ - COUNTRY_CHPLAN_ENT("PA", 0x34, 1, 0), /* Panama */ - COUNTRY_CHPLAN_ENT("PE", 0x34, 1, 0), /* Peru */ - COUNTRY_CHPLAN_ENT("PR", 0x34, 1, 0), /* Puerto Rico */ - COUNTRY_CHPLAN_ENT("PY", 0x34, 1, 0), /* Paraguay */ - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ +static const struct country_chplan RTL8723BS_NGFF1216_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AO", 0x47, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BB", 0x34, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x20, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x34, 1), + COUNTRY_CHPLAN_ENT("CR", 0x34, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x34, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x34, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x34, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HT", 0x34, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x5D, 1), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("MQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x34, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x34, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x34, 1), + COUNTRY_CHPLAN_ENT("PE", 0x34, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x34, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x34, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("YE", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8192EEBT_HMC_M2) /* 2013 certify */ -static const struct country_chplan RTL8192EEBT_HMC_M2_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("AW", 0x34, 1, 0), /* Aruba */ - COUNTRY_CHPLAN_ENT("CA", 0x20, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("CO", 0x34, 1, 0), /* Colombia */ - COUNTRY_CHPLAN_ENT("CR", 0x34, 1, 0), /* Costa Rica */ - COUNTRY_CHPLAN_ENT("DO", 0x34, 1, 0), /* Dominican Republic */ - COUNTRY_CHPLAN_ENT("EC", 0x34, 1, 0), /* Ecuador */ - COUNTRY_CHPLAN_ENT("GT", 0x34, 1, 0), /* Guatemala */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("MX", 0x34, 1, 0), /* Mexico */ - COUNTRY_CHPLAN_ENT("NI", 0x34, 1, 0), /* Nicaragua */ - COUNTRY_CHPLAN_ENT("PA", 0x34, 1, 0), /* Panama */ - COUNTRY_CHPLAN_ENT("PE", 0x34, 1, 0), /* Peru */ - COUNTRY_CHPLAN_ENT("PR", 0x34, 1, 0), /* Puerto Rico */ - COUNTRY_CHPLAN_ENT("PY", 0x34, 1, 0), /* Paraguay */ - COUNTRY_CHPLAN_ENT("SC", 0x34, 1, 0), /* Seychelles */ - COUNTRY_CHPLAN_ENT("ST", 0x34, 1, 0), /* Sao Tome and Principe */ - COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0), /* Taiwan */ - COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0), /* United States of America (USA) */ +static const struct country_chplan RTL8192EEBT_HMC_M2_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AM", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AO", 0x47, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AW", 0x34, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BF", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BI", 0x26, 1), + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x20, 1), + COUNTRY_CHPLAN_ENT("CD", 0x26, 1), + COUNTRY_CHPLAN_ENT("CF", 0x26, 1), + COUNTRY_CHPLAN_ENT("CG", 0x26, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CM", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x34, 1), + COUNTRY_CHPLAN_ENT("CR", 0x34, 1), + COUNTRY_CHPLAN_ENT("CV", 0x26, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x34, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x34, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("EH", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("ET", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GA", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GD", 0x76, 1), + COUNTRY_CHPLAN_ENT("GF", 0x26, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GM", 0x26, 1), + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x34, 1), + COUNTRY_CHPLAN_ENT("GW", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x5D, 1), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LR", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("ML", 0x26, 1), + COUNTRY_CHPLAN_ENT("MR", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MU", 0x26, 1), + COUNTRY_CHPLAN_ENT("MW", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x34, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NE", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x34, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x34, 1), + COUNTRY_CHPLAN_ENT("PE", 0x34, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x34, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x34, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("RW", 0x26, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SC", 0x34, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SL", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("ST", 0x34, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("TD", 0x26, 1), + COUNTRY_CHPLAN_ENT("TF", 0x26, 1), + COUNTRY_CHPLAN_ENT("TG", 0x26, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), + COUNTRY_CHPLAN_ENT("TW", 0x39, 1), + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x34, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("YT", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8723DE_NGFF1630) /* 2016 certify */ -static const struct country_chplan RTL8723DE_NGFF1630_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("CA", 0x2A, 1, 0), /* Canada */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ - COUNTRY_CHPLAN_ENT("MX", 0x34, 1, 0), /* Mexico */ +static const struct country_chplan RTL8723DE_NGFF1630_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x2A, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x76, 1), + COUNTRY_CHPLAN_ENT("CR", 0x76, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x76, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x76, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x61, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x5D, 1), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("KZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x34, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NA", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x76, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x76, 1), + COUNTRY_CHPLAN_ENT("PE", 0x76, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x76, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x76, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), + COUNTRY_CHPLAN_ENT("TW", 0x76, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("US", 0x76, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8822BE) /* 2016 certify */ -static const struct country_chplan RTL8822BE_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("ID", 0x3D, 0, 0), /* Indonesia */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ +static const struct country_chplan RTL8822BE_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AM", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AO", 0x47, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BB", 0x76, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BF", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BI", 0x26, 1), + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BM", 0x76, 1), + COUNTRY_CHPLAN_ENT("BN", 0x47, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BS", 0x76, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x2B, 1), + COUNTRY_CHPLAN_ENT("CD", 0x26, 1), + COUNTRY_CHPLAN_ENT("CF", 0x26, 1), + COUNTRY_CHPLAN_ENT("CG", 0x26, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CM", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x76, 1), + COUNTRY_CHPLAN_ENT("CR", 0x76, 1), + COUNTRY_CHPLAN_ENT("CV", 0x26, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x76, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x76, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("EH", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FJ", 0x76, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GA", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GE", 0x26, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GI", 0x26, 1), + COUNTRY_CHPLAN_ENT("GL", 0x26, 1), + COUNTRY_CHPLAN_ENT("GM", 0x26, 1), + COUNTRY_CHPLAN_ENT("GN", 0x26, 1), + COUNTRY_CHPLAN_ENT("GP", 0x26, 1), + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x61, 1), + COUNTRY_CHPLAN_ENT("GU", 0x76, 1), + COUNTRY_CHPLAN_ENT("GW", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HT", 0x76, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x3D, 0), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("KZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LR", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MG", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("ML", 0x26, 1), + COUNTRY_CHPLAN_ENT("MO", 0x35, 1), + COUNTRY_CHPLAN_ENT("MQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("MR", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MU", 0x26, 1), + COUNTRY_CHPLAN_ENT("MW", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x4D, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NA", 0x26, 1), + COUNTRY_CHPLAN_ENT("NE", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x76, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x76, 1), + COUNTRY_CHPLAN_ENT("PE", 0x76, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x76, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x76, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SC", 0x76, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SL", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("ST", 0x76, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("TD", 0x26, 1), + COUNTRY_CHPLAN_ENT("TF", 0x26, 1), + COUNTRY_CHPLAN_ENT("TG", 0x26, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), + COUNTRY_CHPLAN_ENT("TW", 0x76, 1), + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x76, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("YT", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8821CE) /* 2016 certify */ -static const struct country_chplan RTL8821CE_country_chplan_exc_map[] = { - COUNTRY_CHPLAN_ENT("ID", 0x3D, 0, 0), /* Indonesia */ - COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0), /* South Korea */ +static const struct country_chplan RTL8821CE_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AM", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AO", 0x47, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BB", 0x76, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BF", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BI", 0x26, 1), + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BM", 0x76, 1), + COUNTRY_CHPLAN_ENT("BN", 0x47, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BS", 0x76, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x2B, 1), + COUNTRY_CHPLAN_ENT("CD", 0x26, 1), + COUNTRY_CHPLAN_ENT("CF", 0x26, 1), + COUNTRY_CHPLAN_ENT("CG", 0x26, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CM", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x76, 1), + COUNTRY_CHPLAN_ENT("CR", 0x76, 1), + COUNTRY_CHPLAN_ENT("CV", 0x26, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x76, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x76, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("EH", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("ET", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FJ", 0x76, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GA", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GE", 0x26, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GI", 0x26, 1), + COUNTRY_CHPLAN_ENT("GL", 0x26, 1), + COUNTRY_CHPLAN_ENT("GM", 0x26, 1), + COUNTRY_CHPLAN_ENT("GN", 0x26, 1), + COUNTRY_CHPLAN_ENT("GP", 0x26, 1), + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x61, 1), + COUNTRY_CHPLAN_ENT("GU", 0x76, 1), + COUNTRY_CHPLAN_ENT("GW", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HT", 0x76, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("ID", 0x3D, 0), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x28, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("KZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LR", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MG", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("ML", 0x26, 1), + COUNTRY_CHPLAN_ENT("MO", 0x35, 1), + COUNTRY_CHPLAN_ENT("MQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("MR", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MU", 0x26, 1), + COUNTRY_CHPLAN_ENT("MW", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x4D, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NA", 0x26, 1), + COUNTRY_CHPLAN_ENT("NE", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x76, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x76, 1), + COUNTRY_CHPLAN_ENT("PE", 0x76, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x76, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x76, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SC", 0x76, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SL", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("ST", 0x76, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("TD", 0x26, 1), + COUNTRY_CHPLAN_ENT("TF", 0x26, 1), + COUNTRY_CHPLAN_ENT("TG", 0x26, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TW", 0x76, 1), + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x76, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("YT", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif #if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8822CE) /* 2018 certify */ -static const struct country_chplan RTL8822CE_country_chplan_exc_map[] = { +static const struct country_chplan RTL8822CE_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), + COUNTRY_CHPLAN_ENT("AM", 0x26, 1), + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), + COUNTRY_CHPLAN_ENT("AO", 0x47, 1), + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), + COUNTRY_CHPLAN_ENT("AW", 0x76, 1), + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), + COUNTRY_CHPLAN_ENT("BB", 0x76, 1), + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), + COUNTRY_CHPLAN_ENT("BF", 0x26, 1), + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), + COUNTRY_CHPLAN_ENT("BI", 0x26, 1), + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("BM", 0x76, 1), + COUNTRY_CHPLAN_ENT("BN", 0x47, 1), + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), + COUNTRY_CHPLAN_ENT("BS", 0x76, 1), + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CA", 0x2B, 1), + COUNTRY_CHPLAN_ENT("CD", 0x26, 1), + COUNTRY_CHPLAN_ENT("CF", 0x26, 1), + COUNTRY_CHPLAN_ENT("CG", 0x26, 1), + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), + COUNTRY_CHPLAN_ENT("CM", 0x26, 1), + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), + COUNTRY_CHPLAN_ENT("CO", 0x76, 1), + COUNTRY_CHPLAN_ENT("CR", 0x76, 1), + COUNTRY_CHPLAN_ENT("CV", 0x26, 1), + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), + COUNTRY_CHPLAN_ENT("DJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), + COUNTRY_CHPLAN_ENT("DO", 0x76, 1), + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), + COUNTRY_CHPLAN_ENT("EC", 0x76, 1), + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), + COUNTRY_CHPLAN_ENT("EH", 0x47, 1), + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), + COUNTRY_CHPLAN_ENT("ET", 0x26, 1), + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), + COUNTRY_CHPLAN_ENT("FJ", 0x76, 1), + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GA", 0x26, 1), + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), + COUNTRY_CHPLAN_ENT("GE", 0x26, 1), + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), + COUNTRY_CHPLAN_ENT("GI", 0x26, 1), + COUNTRY_CHPLAN_ENT("GL", 0x26, 1), + COUNTRY_CHPLAN_ENT("GM", 0x26, 1), + COUNTRY_CHPLAN_ENT("GN", 0x26, 1), + COUNTRY_CHPLAN_ENT("GP", 0x26, 1), + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), + COUNTRY_CHPLAN_ENT("GT", 0x61, 1), + COUNTRY_CHPLAN_ENT("GU", 0x76, 1), + COUNTRY_CHPLAN_ENT("GW", 0x26, 1), + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), + COUNTRY_CHPLAN_ENT("HT", 0x76, 1), + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), + COUNTRY_CHPLAN_ENT("KM", 0x26, 1), + COUNTRY_CHPLAN_ENT("KR", 0x4B, 1), + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), + COUNTRY_CHPLAN_ENT("KZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), + COUNTRY_CHPLAN_ENT("LR", 0x26, 1), + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), + COUNTRY_CHPLAN_ENT("MG", 0x26, 1), + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), + COUNTRY_CHPLAN_ENT("ML", 0x26, 1), + COUNTRY_CHPLAN_ENT("MO", 0x35, 1), + COUNTRY_CHPLAN_ENT("MQ", 0x26, 1), + COUNTRY_CHPLAN_ENT("MR", 0x26, 1), + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), + COUNTRY_CHPLAN_ENT("MU", 0x26, 1), + COUNTRY_CHPLAN_ENT("MW", 0x26, 1), + COUNTRY_CHPLAN_ENT("MX", 0x4D, 1), + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("NA", 0x26, 1), + COUNTRY_CHPLAN_ENT("NE", 0x26, 1), + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), + COUNTRY_CHPLAN_ENT("NI", 0x76, 1), + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), + COUNTRY_CHPLAN_ENT("PA", 0x76, 1), + COUNTRY_CHPLAN_ENT("PE", 0x76, 1), + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), + COUNTRY_CHPLAN_ENT("PR", 0x76, 1), + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), + COUNTRY_CHPLAN_ENT("PY", 0x76, 1), + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), + COUNTRY_CHPLAN_ENT("SC", 0x76, 1), + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), + COUNTRY_CHPLAN_ENT("SL", 0x26, 1), + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), + COUNTRY_CHPLAN_ENT("ST", 0x76, 1), + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), + COUNTRY_CHPLAN_ENT("SZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("TD", 0x26, 1), + COUNTRY_CHPLAN_ENT("TF", 0x26, 1), + COUNTRY_CHPLAN_ENT("TG", 0x26, 1), + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), + COUNTRY_CHPLAN_ENT("TJ", 0x26, 1), + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), + COUNTRY_CHPLAN_ENT("TW", 0x76, 1), + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), + COUNTRY_CHPLAN_ENT("US", 0x76, 1), + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), + COUNTRY_CHPLAN_ENT("YT", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1), + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), }; #endif /** - * rtw_def_module_get_chplan_from_country - - * @country_code: string of country code - * @return: - * Return NULL for case referring to common map + * rtw_def_module_country_chplan_map - + * @hal_map: returned map + * @return: size of map */ -static const struct country_chplan *rtw_def_module_get_chplan_from_country(const char *country_code) +static u16 rtw_def_module_country_chplan_map(const struct country_chplan **hal_map) { - const struct country_chplan *ent = NULL; - const struct country_chplan *hal_map = NULL; u16 hal_map_sz = 0; - int i; /* TODO: runtime selection for multi driver */ #if (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8821AE_HMC_M2) - hal_map = RTL8821AE_HMC_M2_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8821AE_HMC_M2_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8821AE_HMC_M2_country_chplan_map; + hal_map_sz = sizeof(RTL8821AE_HMC_M2_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8821AU) - hal_map = RTL8821AU_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8821AU_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8821AU_country_chplan_map; + hal_map_sz = sizeof(RTL8821AU_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8812AENF_NGFF) - hal_map = RTL8812AENF_NGFF_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8812AENF_NGFF_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8812AENF_NGFF_country_chplan_map; + hal_map_sz = sizeof(RTL8812AENF_NGFF_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8812AEBT_HMC) - hal_map = RTL8812AEBT_HMC_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8812AEBT_HMC_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8812AEBT_HMC_country_chplan_map; + hal_map_sz = sizeof(RTL8812AEBT_HMC_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8188EE_HMC_M2) - hal_map = RTL8188EE_HMC_M2_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8188EE_HMC_M2_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8188EE_HMC_M2_country_chplan_map; + hal_map_sz = sizeof(RTL8188EE_HMC_M2_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8723BE_HMC_M2) - hal_map = RTL8723BE_HMC_M2_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8723BE_HMC_M2_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8723BE_HMC_M2_country_chplan_map; + hal_map_sz = sizeof(RTL8723BE_HMC_M2_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8723BS_NGFF1216) - hal_map = RTL8723BS_NGFF1216_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8723BS_NGFF1216_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8723BS_NGFF1216_country_chplan_map; + hal_map_sz = sizeof(RTL8723BS_NGFF1216_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8192EEBT_HMC_M2) - hal_map = RTL8192EEBT_HMC_M2_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8192EEBT_HMC_M2_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8192EEBT_HMC_M2_country_chplan_map; + hal_map_sz = sizeof(RTL8192EEBT_HMC_M2_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8723DE_NGFF1630) - hal_map = RTL8723DE_NGFF1630_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8723DE_NGFF1630_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8723DE_NGFF1630_country_chplan_map; + hal_map_sz = sizeof(RTL8723DE_NGFF1630_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8822BE) - hal_map = RTL8822BE_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8822BE_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8822BE_country_chplan_map; + hal_map_sz = sizeof(RTL8822BE_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8821CE) - hal_map = RTL8821CE_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8821CE_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8821CE_country_chplan_map; + hal_map_sz = sizeof(RTL8821CE_country_chplan_map) / sizeof(struct country_chplan); #elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8822CE) - hal_map = RTL8822CE_country_chplan_exc_map; - hal_map_sz = sizeof(RTL8822CE_country_chplan_exc_map) / sizeof(struct country_chplan); + *hal_map = RTL8822CE_country_chplan_map; + hal_map_sz = sizeof(RTL8822CE_country_chplan_map) / sizeof(struct country_chplan); #endif - if (hal_map == NULL || hal_map_sz == 0) - goto exit; - - for (i = 0; i < hal_map_sz; i++) { - if (strncmp(country_code, hal_map[i].alpha2, 2) == 0) { - ent = &hal_map[i]; - break; - } - } - -exit: - return ent; + return hal_map_sz; } -#endif /* CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP or RTW_DEF_MODULE_REGULATORY_CERT */ +#else static const struct country_chplan country_chplan_map[] = { - COUNTRY_CHPLAN_ENT("AD", 0x26, 1, 0x000), /* Andorra */ - COUNTRY_CHPLAN_ENT("AE", 0x35, 1, 0xFFB), /* United Arab Emirates */ - COUNTRY_CHPLAN_ENT("AF", 0x42, 1, 0x000), /* Afghanistan */ - COUNTRY_CHPLAN_ENT("AG", 0x76, 1, 0x000), /* Antigua & Barbuda */ - COUNTRY_CHPLAN_ENT("AI", 0x26, 1, 0x000), /* Anguilla(UK) */ - COUNTRY_CHPLAN_ENT("AL", 0x26, 1, 0xFF1), /* Albania */ - COUNTRY_CHPLAN_ENT("AM", 0x26, 1, 0xEB0), /* Armenia */ - COUNTRY_CHPLAN_ENT("AN", 0x76, 1, 0xFF1), /* Netherlands Antilles */ - COUNTRY_CHPLAN_ENT("AO", 0x47, 1, 0xEE0), /* Angola */ - COUNTRY_CHPLAN_ENT("AQ", 0x26, 1, 0x000), /* Antarctica */ - COUNTRY_CHPLAN_ENT("AR", 0x61, 1, 0xFF3), /* Argentina */ - COUNTRY_CHPLAN_ENT("AS", 0x76, 1, 0x000), /* American Samoa */ - COUNTRY_CHPLAN_ENT("AT", 0x26, 1, 0xFFB), /* Austria */ - COUNTRY_CHPLAN_ENT("AU", 0x45, 1, 0xFFB), /* Australia */ - COUNTRY_CHPLAN_ENT("AW", 0x76, 1, 0x8B0), /* Aruba */ - COUNTRY_CHPLAN_ENT("AZ", 0x26, 1, 0xFF1), /* Azerbaijan */ - COUNTRY_CHPLAN_ENT("BA", 0x26, 1, 0xFF1), /* Bosnia & Herzegovina */ - COUNTRY_CHPLAN_ENT("BB", 0x76, 1, 0xE50), /* Barbados */ - COUNTRY_CHPLAN_ENT("BD", 0x26, 1, 0xFF1), /* Bangladesh */ - COUNTRY_CHPLAN_ENT("BE", 0x26, 1, 0xFFB), /* Belgium */ - COUNTRY_CHPLAN_ENT("BF", 0x26, 1, 0xEB0), /* Burkina Faso */ - COUNTRY_CHPLAN_ENT("BG", 0x26, 1, 0xFF1), /* Bulgaria */ - COUNTRY_CHPLAN_ENT("BH", 0x48, 1, 0xFF1), /* Bahrain */ - COUNTRY_CHPLAN_ENT("BI", 0x26, 1, 0xEB0), /* Burundi */ - COUNTRY_CHPLAN_ENT("BJ", 0x26, 1, 0xEB0), /* Benin */ - COUNTRY_CHPLAN_ENT("BM", 0x76, 1, 0xE00), /* Bermuda (UK) */ - COUNTRY_CHPLAN_ENT("BN", 0x47, 1, 0xE10), /* Brunei */ - COUNTRY_CHPLAN_ENT("BO", 0x73, 1, 0xFF1), /* Bolivia */ - COUNTRY_CHPLAN_ENT("BR", 0x62, 1, 0xFF1), /* Brazil */ - COUNTRY_CHPLAN_ENT("BS", 0x76, 1, 0xE20), /* Bahamas */ - COUNTRY_CHPLAN_ENT("BT", 0x26, 1, 0x000), /* Bhutan */ - COUNTRY_CHPLAN_ENT("BV", 0x26, 1, 0x000), /* Bouvet Island (Norway) */ - COUNTRY_CHPLAN_ENT("BW", 0x35, 1, 0xEF1), /* Botswana */ - COUNTRY_CHPLAN_ENT("BY", 0x26, 1, 0xFF1), /* Belarus */ - COUNTRY_CHPLAN_ENT("BZ", 0x76, 1, 0x000), /* Belize */ - COUNTRY_CHPLAN_ENT("CA", 0x2B, 1, 0xFFB), /* Canada */ - COUNTRY_CHPLAN_ENT("CC", 0x26, 1, 0x000), /* Cocos (Keeling) Islands (Australia) */ - COUNTRY_CHPLAN_ENT("CD", 0x26, 1, 0xEB0), /* Congo, Republic of the */ - COUNTRY_CHPLAN_ENT("CF", 0x26, 1, 0xEB0), /* Central African Republic */ - COUNTRY_CHPLAN_ENT("CG", 0x26, 1, 0xEB0), /* Congo, Democratic Republic of the. Zaire */ - COUNTRY_CHPLAN_ENT("CH", 0x26, 1, 0xFFB), /* Switzerland */ - COUNTRY_CHPLAN_ENT("CI", 0x42, 1, 0xFF1), /* Cote d'Ivoire */ - COUNTRY_CHPLAN_ENT("CK", 0x26, 1, 0x000), /* Cook Islands */ - COUNTRY_CHPLAN_ENT("CL", 0x2D, 1, 0xFF1), /* Chile */ - COUNTRY_CHPLAN_ENT("CM", 0x26, 1, 0xEB0), /* Cameroon */ - COUNTRY_CHPLAN_ENT("CN", 0x48, 1, 0xFFB), /* China */ - COUNTRY_CHPLAN_ENT("CO", 0x76, 1, 0xFF1), /* Colombia */ - COUNTRY_CHPLAN_ENT("CR", 0x76, 1, 0xFF1), /* Costa Rica */ - COUNTRY_CHPLAN_ENT("CV", 0x26, 1, 0xEB0), /* Cape Verde */ - COUNTRY_CHPLAN_ENT("CX", 0x45, 1, 0x000), /* Christmas Island (Australia) */ - COUNTRY_CHPLAN_ENT("CY", 0x26, 1, 0xFFB), /* Cyprus */ - COUNTRY_CHPLAN_ENT("CZ", 0x26, 1, 0xFFB), /* Czech Republic */ - COUNTRY_CHPLAN_ENT("DE", 0x26, 1, 0xFFB), /* Germany */ - COUNTRY_CHPLAN_ENT("DJ", 0x26, 1, 0xE80), /* Djibouti */ - COUNTRY_CHPLAN_ENT("DK", 0x26, 1, 0xFFB), /* Denmark */ - COUNTRY_CHPLAN_ENT("DM", 0x76, 1, 0x000), /* Dominica */ - COUNTRY_CHPLAN_ENT("DO", 0x76, 1, 0xFF1), /* Dominican Republic */ - COUNTRY_CHPLAN_ENT("DZ", 0x26, 1, 0xFF1), /* Algeria */ - COUNTRY_CHPLAN_ENT("EC", 0x76, 1, 0xFF1), /* Ecuador */ - COUNTRY_CHPLAN_ENT("EE", 0x26, 1, 0xFFB), /* Estonia */ - COUNTRY_CHPLAN_ENT("EG", 0x47, 1, 0xFF1), /* Egypt */ - COUNTRY_CHPLAN_ENT("EH", 0x47, 1, 0xE80), /* Western Sahara */ - COUNTRY_CHPLAN_ENT("ER", 0x26, 1, 0x000), /* Eritrea */ - COUNTRY_CHPLAN_ENT("ES", 0x26, 1, 0xFFB), /* Spain, Canary Islands, Ceuta, Melilla */ - COUNTRY_CHPLAN_ENT("ET", 0x26, 1, 0xCB0), /* Ethiopia */ - COUNTRY_CHPLAN_ENT("FI", 0x26, 1, 0xFFB), /* Finland */ - COUNTRY_CHPLAN_ENT("FJ", 0x76, 1, 0xE00), /* Fiji */ - COUNTRY_CHPLAN_ENT("FK", 0x26, 1, 0x000), /* Falkland Islands (Islas Malvinas) (UK) */ - COUNTRY_CHPLAN_ENT("FM", 0x76, 1, 0x000), /* Micronesia, Federated States of (USA) */ - COUNTRY_CHPLAN_ENT("FO", 0x26, 1, 0x000), /* Faroe Islands (Denmark) */ - COUNTRY_CHPLAN_ENT("FR", 0x26, 1, 0xFFB), /* France */ - COUNTRY_CHPLAN_ENT("GA", 0x26, 1, 0xEB0), /* Gabon */ - COUNTRY_CHPLAN_ENT("GB", 0x26, 1, 0xFFB), /* Great Britain (United Kingdom; England) */ - COUNTRY_CHPLAN_ENT("GD", 0x76, 1, 0x0B0), /* Grenada */ - COUNTRY_CHPLAN_ENT("GE", 0x26, 1, 0xE00), /* Georgia */ - COUNTRY_CHPLAN_ENT("GF", 0x26, 1, 0x080), /* French Guiana */ - COUNTRY_CHPLAN_ENT("GG", 0x26, 1, 0x000), /* Guernsey (UK) */ - COUNTRY_CHPLAN_ENT("GH", 0x26, 1, 0xFF1), /* Ghana */ - COUNTRY_CHPLAN_ENT("GI", 0x26, 1, 0xE00), /* Gibraltar (UK) */ - COUNTRY_CHPLAN_ENT("GL", 0x26, 1, 0xE00), /* Greenland (Denmark) */ - COUNTRY_CHPLAN_ENT("GM", 0x26, 1, 0xEB0), /* Gambia */ - COUNTRY_CHPLAN_ENT("GN", 0x26, 1, 0xE10), /* Guinea */ - COUNTRY_CHPLAN_ENT("GP", 0x26, 1, 0xE00), /* Guadeloupe (France) */ - COUNTRY_CHPLAN_ENT("GQ", 0x26, 1, 0xEB0), /* Equatorial Guinea */ - COUNTRY_CHPLAN_ENT("GR", 0x26, 1, 0xFFB), /* Greece */ - COUNTRY_CHPLAN_ENT("GS", 0x26, 1, 0x000), /* South Georgia and the Sandwich Islands (UK) */ - COUNTRY_CHPLAN_ENT("GT", 0x61, 1, 0xFF1), /* Guatemala */ - COUNTRY_CHPLAN_ENT("GU", 0x76, 1, 0xE00), /* Guam (USA) */ - COUNTRY_CHPLAN_ENT("GW", 0x26, 1, 0xEB0), /* Guinea-Bissau */ - COUNTRY_CHPLAN_ENT("GY", 0x44, 1, 0x000), /* Guyana */ - COUNTRY_CHPLAN_ENT("HK", 0x35, 1, 0xFFB), /* Hong Kong */ - COUNTRY_CHPLAN_ENT("HM", 0x45, 1, 0x000), /* Heard and McDonald Islands (Australia) */ - COUNTRY_CHPLAN_ENT("HN", 0x32, 1, 0xFF1), /* Honduras */ - COUNTRY_CHPLAN_ENT("HR", 0x26, 1, 0xFF9), /* Croatia */ - COUNTRY_CHPLAN_ENT("HT", 0x76, 1, 0xE50), /* Haiti */ - COUNTRY_CHPLAN_ENT("HU", 0x26, 1, 0xFFB), /* Hungary */ - COUNTRY_CHPLAN_ENT("ID", 0x5D, 1, 0x7F3), /* Indonesia */ - COUNTRY_CHPLAN_ENT("IE", 0x26, 1, 0xFFB), /* Ireland */ - COUNTRY_CHPLAN_ENT("IL", 0x47, 1, 0xFF1), /* Israel */ - COUNTRY_CHPLAN_ENT("IM", 0x26, 1, 0x000), /* Isle of Man (UK) */ - COUNTRY_CHPLAN_ENT("IN", 0x48, 1, 0xFF1), /* India */ - COUNTRY_CHPLAN_ENT("IO", 0x26, 1, 0x000), /* British Indian Ocean Territory (UK) */ - COUNTRY_CHPLAN_ENT("IQ", 0x26, 1, 0x000), /* Iraq */ - COUNTRY_CHPLAN_ENT("IR", 0x26, 0, 0x000), /* Iran */ - COUNTRY_CHPLAN_ENT("IS", 0x26, 1, 0xFFB), /* Iceland */ - COUNTRY_CHPLAN_ENT("IT", 0x26, 1, 0xFFB), /* Italy */ - COUNTRY_CHPLAN_ENT("JE", 0x26, 1, 0x000), /* Jersey (UK) */ - COUNTRY_CHPLAN_ENT("JM", 0x32, 1, 0xFF1), /* Jamaica */ - COUNTRY_CHPLAN_ENT("JO", 0x49, 1, 0xFFB), /* Jordan */ - COUNTRY_CHPLAN_ENT("JP", 0x27, 1, 0xFFF), /* Japan- Telec */ - COUNTRY_CHPLAN_ENT("KE", 0x47, 1, 0xFF9), /* Kenya */ - COUNTRY_CHPLAN_ENT("KG", 0x26, 1, 0xFF1), /* Kyrgyzstan */ - COUNTRY_CHPLAN_ENT("KH", 0x26, 1, 0xFF1), /* Cambodia */ - COUNTRY_CHPLAN_ENT("KI", 0x26, 1, 0x000), /* Kiribati */ - COUNTRY_CHPLAN_ENT("KM", 0x26, 1, 0x800), /* Comoros */ - COUNTRY_CHPLAN_ENT("KN", 0x76, 1, 0x000), /* Saint Kitts and Nevis */ - COUNTRY_CHPLAN_ENT("KR", 0x4B, 1, 0xFFB), /* South Korea */ - COUNTRY_CHPLAN_ENT("KW", 0x47, 1, 0xFFB), /* Kuwait */ - COUNTRY_CHPLAN_ENT("KY", 0x76, 1, 0x000), /* Cayman Islands (UK) */ - COUNTRY_CHPLAN_ENT("KZ", 0x26, 1, 0xF00), /* Kazakhstan */ - COUNTRY_CHPLAN_ENT("LA", 0x26, 1, 0x000), /* Laos */ - COUNTRY_CHPLAN_ENT("LB", 0x26, 1, 0xFF1), /* Lebanon */ - COUNTRY_CHPLAN_ENT("LC", 0x76, 1, 0x000), /* Saint Lucia */ - COUNTRY_CHPLAN_ENT("LI", 0x26, 1, 0xFFB), /* Liechtenstein */ - COUNTRY_CHPLAN_ENT("LK", 0x26, 1, 0xFF1), /* Sri Lanka */ - COUNTRY_CHPLAN_ENT("LR", 0x26, 1, 0xEB0), /* Liberia */ - COUNTRY_CHPLAN_ENT("LS", 0x26, 1, 0xFF1), /* Lesotho */ - COUNTRY_CHPLAN_ENT("LT", 0x26, 1, 0xFFB), /* Lithuania */ - COUNTRY_CHPLAN_ENT("LU", 0x26, 1, 0xFFB), /* Luxembourg */ - COUNTRY_CHPLAN_ENT("LV", 0x26, 1, 0xFFB), /* Latvia */ - COUNTRY_CHPLAN_ENT("LY", 0x26, 1, 0x000), /* Libya */ - COUNTRY_CHPLAN_ENT("MA", 0x47, 1, 0xFF1), /* Morocco */ - COUNTRY_CHPLAN_ENT("MC", 0x26, 1, 0xFFB), /* Monaco */ - COUNTRY_CHPLAN_ENT("MD", 0x26, 1, 0xFF1), /* Moldova */ - COUNTRY_CHPLAN_ENT("ME", 0x26, 1, 0xFF1), /* Montenegro */ - COUNTRY_CHPLAN_ENT("MF", 0x76, 1, 0x000), /* Saint Martin */ - COUNTRY_CHPLAN_ENT("MG", 0x26, 1, 0xE20), /* Madagascar */ - COUNTRY_CHPLAN_ENT("MH", 0x76, 1, 0x000), /* Marshall Islands (USA) */ - COUNTRY_CHPLAN_ENT("MK", 0x26, 1, 0xFF1), /* Republic of Macedonia (FYROM) */ - COUNTRY_CHPLAN_ENT("ML", 0x26, 1, 0xEB0), /* Mali */ - COUNTRY_CHPLAN_ENT("MM", 0x26, 1, 0x000), /* Burma (Myanmar) */ - COUNTRY_CHPLAN_ENT("MN", 0x26, 1, 0x000), /* Mongolia */ - COUNTRY_CHPLAN_ENT("MO", 0x35, 1, 0xE00), /* Macau */ - COUNTRY_CHPLAN_ENT("MP", 0x76, 1, 0x000), /* Northern Mariana Islands (USA) */ - COUNTRY_CHPLAN_ENT("MQ", 0x26, 1, 0xE40), /* Martinique (France) */ - COUNTRY_CHPLAN_ENT("MR", 0x26, 1, 0xEA0), /* Mauritania */ - COUNTRY_CHPLAN_ENT("MS", 0x26, 1, 0x000), /* Montserrat (UK) */ - COUNTRY_CHPLAN_ENT("MT", 0x26, 1, 0xFFB), /* Malta */ - COUNTRY_CHPLAN_ENT("MU", 0x26, 1, 0xEB0), /* Mauritius */ - COUNTRY_CHPLAN_ENT("MV", 0x47, 1, 0x000), /* Maldives */ - COUNTRY_CHPLAN_ENT("MW", 0x26, 1, 0xEB0), /* Malawi */ - COUNTRY_CHPLAN_ENT("MX", 0x4D, 1, 0xFF1), /* Mexico */ - COUNTRY_CHPLAN_ENT("MY", 0x63, 1, 0xFF1), /* Malaysia */ - COUNTRY_CHPLAN_ENT("MZ", 0x26, 1, 0xFF1), /* Mozambique */ - COUNTRY_CHPLAN_ENT("NA", 0x26, 1, 0xF00), /* Namibia */ - COUNTRY_CHPLAN_ENT("NC", 0x26, 1, 0x000), /* New Caledonia */ - COUNTRY_CHPLAN_ENT("NE", 0x26, 1, 0xEB0), /* Niger */ - COUNTRY_CHPLAN_ENT("NF", 0x45, 1, 0x000), /* Norfolk Island (Australia) */ - COUNTRY_CHPLAN_ENT("NG", 0x75, 1, 0xFF9), /* Nigeria */ - COUNTRY_CHPLAN_ENT("NI", 0x76, 1, 0xFF1), /* Nicaragua */ - COUNTRY_CHPLAN_ENT("NL", 0x26, 1, 0xFFB), /* Netherlands */ - COUNTRY_CHPLAN_ENT("NO", 0x26, 1, 0xFFB), /* Norway */ - COUNTRY_CHPLAN_ENT("NP", 0x48, 1, 0xEF0), /* Nepal */ - COUNTRY_CHPLAN_ENT("NR", 0x26, 1, 0x000), /* Nauru */ - COUNTRY_CHPLAN_ENT("NU", 0x45, 1, 0x000), /* Niue */ - COUNTRY_CHPLAN_ENT("NZ", 0x45, 1, 0xFFB), /* New Zealand */ - COUNTRY_CHPLAN_ENT("OM", 0x26, 1, 0xFF9), /* Oman */ - COUNTRY_CHPLAN_ENT("PA", 0x76, 1, 0xFF1), /* Panama */ - COUNTRY_CHPLAN_ENT("PE", 0x76, 1, 0xFF1), /* Peru */ - COUNTRY_CHPLAN_ENT("PF", 0x26, 1, 0x000), /* French Polynesia (France) */ - COUNTRY_CHPLAN_ENT("PG", 0x35, 1, 0xFF1), /* Papua New Guinea */ - COUNTRY_CHPLAN_ENT("PH", 0x35, 1, 0xFF1), /* Philippines */ - COUNTRY_CHPLAN_ENT("PK", 0x51, 1, 0xFF1), /* Pakistan */ - COUNTRY_CHPLAN_ENT("PL", 0x26, 1, 0xFFB), /* Poland */ - COUNTRY_CHPLAN_ENT("PM", 0x26, 1, 0x000), /* Saint Pierre and Miquelon (France) */ - COUNTRY_CHPLAN_ENT("PR", 0x76, 1, 0xFF1), /* Puerto Rico */ - COUNTRY_CHPLAN_ENT("PT", 0x26, 1, 0xFFB), /* Portugal */ - COUNTRY_CHPLAN_ENT("PW", 0x76, 1, 0x000), /* Palau */ - COUNTRY_CHPLAN_ENT("PY", 0x76, 1, 0xFF1), /* Paraguay */ - COUNTRY_CHPLAN_ENT("QA", 0x35, 1, 0xFF9), /* Qatar */ - COUNTRY_CHPLAN_ENT("RE", 0x26, 1, 0x000), /* Reunion (France) */ - COUNTRY_CHPLAN_ENT("RO", 0x26, 1, 0xFF1), /* Romania */ - COUNTRY_CHPLAN_ENT("RS", 0x26, 1, 0xFF1), /* Serbia, Kosovo */ - COUNTRY_CHPLAN_ENT("RU", 0x59, 1, 0xFFB), /* Russia(fac/gost), Kaliningrad */ - COUNTRY_CHPLAN_ENT("RW", 0x26, 1, 0x0B0), /* Rwanda */ - COUNTRY_CHPLAN_ENT("SA", 0x35, 1, 0xFFB), /* Saudi Arabia */ - COUNTRY_CHPLAN_ENT("SB", 0x26, 1, 0x000), /* Solomon Islands */ - COUNTRY_CHPLAN_ENT("SC", 0x76, 1, 0xE90), /* Seychelles */ - COUNTRY_CHPLAN_ENT("SE", 0x26, 1, 0xFFB), /* Sweden */ - COUNTRY_CHPLAN_ENT("SG", 0x35, 1, 0xFFB), /* Singapore */ - COUNTRY_CHPLAN_ENT("SH", 0x26, 1, 0x000), /* Saint Helena (UK) */ - COUNTRY_CHPLAN_ENT("SI", 0x26, 1, 0xFFB), /* Slovenia */ - COUNTRY_CHPLAN_ENT("SJ", 0x26, 1, 0x000), /* Svalbard (Norway) */ - COUNTRY_CHPLAN_ENT("SK", 0x26, 1, 0xFFB), /* Slovakia */ - COUNTRY_CHPLAN_ENT("SL", 0x26, 1, 0xEB0), /* Sierra Leone */ - COUNTRY_CHPLAN_ENT("SM", 0x26, 1, 0x000), /* San Marino */ - COUNTRY_CHPLAN_ENT("SN", 0x26, 1, 0xFF1), /* Senegal */ - COUNTRY_CHPLAN_ENT("SO", 0x26, 1, 0x000), /* Somalia */ - COUNTRY_CHPLAN_ENT("SR", 0x74, 1, 0x000), /* Suriname */ - COUNTRY_CHPLAN_ENT("ST", 0x76, 1, 0xE80), /* Sao Tome and Principe */ - COUNTRY_CHPLAN_ENT("SV", 0x30, 1, 0xFF1), /* El Salvador */ - COUNTRY_CHPLAN_ENT("SX", 0x76, 1, 0x000), /* Sint Marteen */ - COUNTRY_CHPLAN_ENT("SZ", 0x26, 1, 0x820), /* Swaziland */ - COUNTRY_CHPLAN_ENT("TC", 0x26, 1, 0x000), /* Turks and Caicos Islands (UK) */ - COUNTRY_CHPLAN_ENT("TD", 0x26, 1, 0xEB0), /* Chad */ - COUNTRY_CHPLAN_ENT("TF", 0x26, 1, 0xE80), /* French Southern and Antarctic Lands (FR Southern Territories) */ - COUNTRY_CHPLAN_ENT("TG", 0x26, 1, 0xEB0), /* Togo */ - COUNTRY_CHPLAN_ENT("TH", 0x35, 1, 0xFF1), /* Thailand */ - COUNTRY_CHPLAN_ENT("TJ", 0x26, 1, 0xE40), /* Tajikistan */ - COUNTRY_CHPLAN_ENT("TK", 0x45, 1, 0x000), /* Tokelau */ - COUNTRY_CHPLAN_ENT("TM", 0x26, 1, 0x000), /* Turkmenistan */ - COUNTRY_CHPLAN_ENT("TN", 0x47, 1, 0xFF1), /* Tunisia */ - COUNTRY_CHPLAN_ENT("TO", 0x26, 1, 0x000), /* Tonga */ - COUNTRY_CHPLAN_ENT("TR", 0x26, 1, 0xFF1), /* Turkey, Northern Cyprus */ - COUNTRY_CHPLAN_ENT("TT", 0x76, 1, 0x3F1), /* Trinidad & Tobago */ - COUNTRY_CHPLAN_ENT("TV", 0x21, 0, 0x000), /* Tuvalu */ - COUNTRY_CHPLAN_ENT("TW", 0x76, 1, 0xFFF), /* Taiwan */ - COUNTRY_CHPLAN_ENT("TZ", 0x26, 1, 0xEF0), /* Tanzania */ - COUNTRY_CHPLAN_ENT("UA", 0x36, 1, 0xFFB), /* Ukraine */ - COUNTRY_CHPLAN_ENT("UG", 0x26, 1, 0xEF1), /* Uganda */ - COUNTRY_CHPLAN_ENT("US", 0x76, 1, 0xFFF), /* United States of America (USA) */ - COUNTRY_CHPLAN_ENT("UY", 0x30, 1, 0xFF1), /* Uruguay */ - COUNTRY_CHPLAN_ENT("UZ", 0x47, 1, 0xEF0), /* Uzbekistan */ - COUNTRY_CHPLAN_ENT("VA", 0x26, 1, 0x000), /* Holy See (Vatican City) */ - COUNTRY_CHPLAN_ENT("VC", 0x76, 1, 0x010), /* Saint Vincent and the Grenadines */ - COUNTRY_CHPLAN_ENT("VE", 0x30, 1, 0xFF1), /* Venezuela */ - COUNTRY_CHPLAN_ENT("VG", 0x76, 1, 0x000), /* British Virgin Islands (UK) */ - COUNTRY_CHPLAN_ENT("VI", 0x76, 1, 0x000), /* United States Virgin Islands (USA) */ - COUNTRY_CHPLAN_ENT("VN", 0x35, 1, 0xFF1), /* Vietnam */ - COUNTRY_CHPLAN_ENT("VU", 0x26, 1, 0x000), /* Vanuatu */ - COUNTRY_CHPLAN_ENT("WF", 0x26, 1, 0x000), /* Wallis and Futuna (France) */ - COUNTRY_CHPLAN_ENT("WS", 0x76, 1, 0x000), /* Samoa */ - COUNTRY_CHPLAN_ENT("YE", 0x26, 1, 0x040), /* Yemen */ - COUNTRY_CHPLAN_ENT("YT", 0x26, 1, 0xE80), /* Mayotte (France) */ - COUNTRY_CHPLAN_ENT("ZA", 0x35, 1, 0xFF1), /* South Africa */ - COUNTRY_CHPLAN_ENT("ZM", 0x26, 1, 0xEB0), /* Zambia */ - COUNTRY_CHPLAN_ENT("ZW", 0x26, 1, 0xFF1), /* Zimbabwe */ + COUNTRY_CHPLAN_ENT("AD", 0x26, 1), /* Andorra */ + COUNTRY_CHPLAN_ENT("AE", 0x35, 1), /* United Arab Emirates */ + COUNTRY_CHPLAN_ENT("AF", 0x42, 1), /* Afghanistan */ + COUNTRY_CHPLAN_ENT("AG", 0x76, 1), /* Antigua & Barbuda */ + COUNTRY_CHPLAN_ENT("AI", 0x26, 1), /* Anguilla(UK) */ + COUNTRY_CHPLAN_ENT("AL", 0x26, 1), /* Albania */ + COUNTRY_CHPLAN_ENT("AM", 0x26, 1), /* Armenia */ + COUNTRY_CHPLAN_ENT("AN", 0x76, 1), /* Netherlands Antilles */ + COUNTRY_CHPLAN_ENT("AO", 0x47, 1), /* Angola */ + COUNTRY_CHPLAN_ENT("AQ", 0x26, 1), /* Antarctica */ + COUNTRY_CHPLAN_ENT("AR", 0x61, 1), /* Argentina */ + COUNTRY_CHPLAN_ENT("AS", 0x76, 1), /* American Samoa */ + COUNTRY_CHPLAN_ENT("AT", 0x26, 1), /* Austria */ + COUNTRY_CHPLAN_ENT("AU", 0x45, 1), /* Australia */ + COUNTRY_CHPLAN_ENT("AW", 0x76, 1), /* Aruba */ + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1), /* Azerbaijan */ + COUNTRY_CHPLAN_ENT("BA", 0x26, 1), /* Bosnia & Herzegovina */ + COUNTRY_CHPLAN_ENT("BB", 0x76, 1), /* Barbados */ + COUNTRY_CHPLAN_ENT("BD", 0x26, 1), /* Bangladesh */ + COUNTRY_CHPLAN_ENT("BE", 0x26, 1), /* Belgium */ + COUNTRY_CHPLAN_ENT("BF", 0x26, 1), /* Burkina Faso */ + COUNTRY_CHPLAN_ENT("BG", 0x26, 1), /* Bulgaria */ + COUNTRY_CHPLAN_ENT("BH", 0x48, 1), /* Bahrain */ + COUNTRY_CHPLAN_ENT("BI", 0x26, 1), /* Burundi */ + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1), /* Benin */ + COUNTRY_CHPLAN_ENT("BM", 0x76, 1), /* Bermuda (UK) */ + COUNTRY_CHPLAN_ENT("BN", 0x47, 1), /* Brunei */ + COUNTRY_CHPLAN_ENT("BO", 0x73, 1), /* Bolivia */ + COUNTRY_CHPLAN_ENT("BR", 0x62, 1), /* Brazil */ + COUNTRY_CHPLAN_ENT("BS", 0x76, 1), /* Bahamas */ + COUNTRY_CHPLAN_ENT("BT", 0x26, 1), /* Bhutan */ + COUNTRY_CHPLAN_ENT("BV", 0x26, 1), /* Bouvet Island (Norway) */ + COUNTRY_CHPLAN_ENT("BW", 0x35, 1), /* Botswana */ + COUNTRY_CHPLAN_ENT("BY", 0x26, 1), /* Belarus */ + COUNTRY_CHPLAN_ENT("BZ", 0x76, 1), /* Belize */ + COUNTRY_CHPLAN_ENT("CA", 0x2B, 1), /* Canada */ + COUNTRY_CHPLAN_ENT("CC", 0x26, 1), /* Cocos (Keeling) Islands (Australia) */ + COUNTRY_CHPLAN_ENT("CD", 0x26, 1), /* Congo, Republic of the */ + COUNTRY_CHPLAN_ENT("CF", 0x26, 1), /* Central African Republic */ + COUNTRY_CHPLAN_ENT("CG", 0x26, 1), /* Congo, Democratic Republic of the. Zaire */ + COUNTRY_CHPLAN_ENT("CH", 0x26, 1), /* Switzerland */ + COUNTRY_CHPLAN_ENT("CI", 0x42, 1), /* Cote d'Ivoire */ + COUNTRY_CHPLAN_ENT("CK", 0x26, 1), /* Cook Islands */ + COUNTRY_CHPLAN_ENT("CL", 0x2D, 1), /* Chile */ + COUNTRY_CHPLAN_ENT("CM", 0x26, 1), /* Cameroon */ + COUNTRY_CHPLAN_ENT("CN", 0x48, 1), /* China */ + COUNTRY_CHPLAN_ENT("CO", 0x76, 1), /* Colombia */ + COUNTRY_CHPLAN_ENT("CR", 0x76, 1), /* Costa Rica */ + COUNTRY_CHPLAN_ENT("CV", 0x26, 1), /* Cape Verde */ + COUNTRY_CHPLAN_ENT("CX", 0x45, 1), /* Christmas Island (Australia) */ + COUNTRY_CHPLAN_ENT("CY", 0x26, 1), /* Cyprus */ + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1), /* Czech Republic */ + COUNTRY_CHPLAN_ENT("DE", 0x26, 1), /* Germany */ + COUNTRY_CHPLAN_ENT("DJ", 0x26, 1), /* Djibouti */ + COUNTRY_CHPLAN_ENT("DK", 0x26, 1), /* Denmark */ + COUNTRY_CHPLAN_ENT("DM", 0x76, 1), /* Dominica */ + COUNTRY_CHPLAN_ENT("DO", 0x76, 1), /* Dominican Republic */ + COUNTRY_CHPLAN_ENT("DZ", 0x00, 1), /* Algeria */ + COUNTRY_CHPLAN_ENT("EC", 0x76, 1), /* Ecuador */ + COUNTRY_CHPLAN_ENT("EE", 0x26, 1), /* Estonia */ + COUNTRY_CHPLAN_ENT("EG", 0x47, 1), /* Egypt */ + COUNTRY_CHPLAN_ENT("EH", 0x47, 1), /* Western Sahara */ + COUNTRY_CHPLAN_ENT("ER", 0x26, 1), /* Eritrea */ + COUNTRY_CHPLAN_ENT("ES", 0x26, 1), /* Spain, Canary Islands, Ceuta, Melilla */ + COUNTRY_CHPLAN_ENT("ET", 0x26, 1), /* Ethiopia */ + COUNTRY_CHPLAN_ENT("FI", 0x26, 1), /* Finland */ + COUNTRY_CHPLAN_ENT("FJ", 0x76, 1), /* Fiji */ + COUNTRY_CHPLAN_ENT("FK", 0x26, 1), /* Falkland Islands (Islas Malvinas) (UK) */ + COUNTRY_CHPLAN_ENT("FM", 0x76, 1), /* Micronesia, Federated States of (USA) */ + COUNTRY_CHPLAN_ENT("FO", 0x26, 1), /* Faroe Islands (Denmark) */ + COUNTRY_CHPLAN_ENT("FR", 0x26, 1), /* France */ + COUNTRY_CHPLAN_ENT("GA", 0x26, 1), /* Gabon */ + COUNTRY_CHPLAN_ENT("GB", 0x26, 1), /* Great Britain (United Kingdom; England) */ + COUNTRY_CHPLAN_ENT("GD", 0x76, 1), /* Grenada */ + COUNTRY_CHPLAN_ENT("GE", 0x26, 1), /* Georgia */ + COUNTRY_CHPLAN_ENT("GF", 0x26, 1), /* French Guiana */ + COUNTRY_CHPLAN_ENT("GG", 0x26, 1), /* Guernsey (UK) */ + COUNTRY_CHPLAN_ENT("GH", 0x26, 1), /* Ghana */ + COUNTRY_CHPLAN_ENT("GI", 0x26, 1), /* Gibraltar (UK) */ + COUNTRY_CHPLAN_ENT("GL", 0x26, 1), /* Greenland (Denmark) */ + COUNTRY_CHPLAN_ENT("GM", 0x26, 1), /* Gambia */ + COUNTRY_CHPLAN_ENT("GN", 0x26, 1), /* Guinea */ + COUNTRY_CHPLAN_ENT("GP", 0x26, 1), /* Guadeloupe (France) */ + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1), /* Equatorial Guinea */ + COUNTRY_CHPLAN_ENT("GR", 0x26, 1), /* Greece */ + COUNTRY_CHPLAN_ENT("GS", 0x26, 1), /* South Georgia and the Sandwich Islands (UK) */ + COUNTRY_CHPLAN_ENT("GT", 0x61, 1), /* Guatemala */ + COUNTRY_CHPLAN_ENT("GU", 0x76, 1), /* Guam (USA) */ + COUNTRY_CHPLAN_ENT("GW", 0x26, 1), /* Guinea-Bissau */ + COUNTRY_CHPLAN_ENT("GY", 0x44, 1), /* Guyana */ + COUNTRY_CHPLAN_ENT("HK", 0x35, 1), /* Hong Kong */ + COUNTRY_CHPLAN_ENT("HM", 0x45, 1), /* Heard and McDonald Islands (Australia) */ + COUNTRY_CHPLAN_ENT("HN", 0x32, 1), /* Honduras */ + COUNTRY_CHPLAN_ENT("HR", 0x26, 1), /* Croatia */ + COUNTRY_CHPLAN_ENT("HT", 0x76, 1), /* Haiti */ + COUNTRY_CHPLAN_ENT("HU", 0x26, 1), /* Hungary */ + COUNTRY_CHPLAN_ENT("ID", 0x5D, 1), /* Indonesia */ + COUNTRY_CHPLAN_ENT("IE", 0x26, 1), /* Ireland */ + COUNTRY_CHPLAN_ENT("IL", 0x47, 1), /* Israel */ + COUNTRY_CHPLAN_ENT("IM", 0x26, 1), /* Isle of Man (UK) */ + COUNTRY_CHPLAN_ENT("IN", 0x48, 1), /* India */ + COUNTRY_CHPLAN_ENT("IO", 0x26, 1), /* British Indian Ocean Territory (UK) */ + COUNTRY_CHPLAN_ENT("IQ", 0x26, 1), /* Iraq */ + COUNTRY_CHPLAN_ENT("IR", 0x26, 0), /* Iran */ + COUNTRY_CHPLAN_ENT("IS", 0x26, 1), /* Iceland */ + COUNTRY_CHPLAN_ENT("IT", 0x26, 1), /* Italy */ + COUNTRY_CHPLAN_ENT("JE", 0x26, 1), /* Jersey (UK) */ + COUNTRY_CHPLAN_ENT("JM", 0x32, 1), /* Jamaica */ + COUNTRY_CHPLAN_ENT("JO", 0x49, 1), /* Jordan */ + COUNTRY_CHPLAN_ENT("JP", 0x27, 1), /* Japan- Telec */ + COUNTRY_CHPLAN_ENT("KE", 0x47, 1), /* Kenya */ + COUNTRY_CHPLAN_ENT("KG", 0x26, 1), /* Kyrgyzstan */ + COUNTRY_CHPLAN_ENT("KH", 0x26, 1), /* Cambodia */ + COUNTRY_CHPLAN_ENT("KI", 0x26, 1), /* Kiribati */ + COUNTRY_CHPLAN_ENT("KM", 0x26, 1), /* Comoros */ + COUNTRY_CHPLAN_ENT("KN", 0x76, 1), /* Saint Kitts and Nevis */ + COUNTRY_CHPLAN_ENT("KR", 0x4B, 1), /* South Korea */ + COUNTRY_CHPLAN_ENT("KW", 0x26, 1), /* Kuwait */ + COUNTRY_CHPLAN_ENT("KY", 0x76, 1), /* Cayman Islands (UK) */ + COUNTRY_CHPLAN_ENT("KZ", 0x26, 1), /* Kazakhstan */ + COUNTRY_CHPLAN_ENT("LA", 0x26, 1), /* Laos */ + COUNTRY_CHPLAN_ENT("LB", 0x26, 1), /* Lebanon */ + COUNTRY_CHPLAN_ENT("LC", 0x76, 1), /* Saint Lucia */ + COUNTRY_CHPLAN_ENT("LI", 0x26, 1), /* Liechtenstein */ + COUNTRY_CHPLAN_ENT("LK", 0x26, 1), /* Sri Lanka */ + COUNTRY_CHPLAN_ENT("LR", 0x26, 1), /* Liberia */ + COUNTRY_CHPLAN_ENT("LS", 0x26, 1), /* Lesotho */ + COUNTRY_CHPLAN_ENT("LT", 0x26, 1), /* Lithuania */ + COUNTRY_CHPLAN_ENT("LU", 0x26, 1), /* Luxembourg */ + COUNTRY_CHPLAN_ENT("LV", 0x26, 1), /* Latvia */ + COUNTRY_CHPLAN_ENT("LY", 0x26, 1), /* Libya */ + COUNTRY_CHPLAN_ENT("MA", 0x47, 1), /* Morocco */ + COUNTRY_CHPLAN_ENT("MC", 0x26, 1), /* Monaco */ + COUNTRY_CHPLAN_ENT("MD", 0x26, 1), /* Moldova */ + COUNTRY_CHPLAN_ENT("ME", 0x26, 1), /* Montenegro */ + COUNTRY_CHPLAN_ENT("MF", 0x76, 1), /* Saint Martin */ + COUNTRY_CHPLAN_ENT("MG", 0x26, 1), /* Madagascar */ + COUNTRY_CHPLAN_ENT("MH", 0x76, 1), /* Marshall Islands (USA) */ + COUNTRY_CHPLAN_ENT("MK", 0x26, 1), /* Republic of Macedonia (FYROM) */ + COUNTRY_CHPLAN_ENT("ML", 0x26, 1), /* Mali */ + COUNTRY_CHPLAN_ENT("MM", 0x26, 1), /* Burma (Myanmar) */ + COUNTRY_CHPLAN_ENT("MN", 0x26, 1), /* Mongolia */ + COUNTRY_CHPLAN_ENT("MO", 0x35, 1), /* Macau */ + COUNTRY_CHPLAN_ENT("MP", 0x76, 1), /* Northern Mariana Islands (USA) */ + COUNTRY_CHPLAN_ENT("MQ", 0x26, 1), /* Martinique (France) */ + COUNTRY_CHPLAN_ENT("MR", 0x26, 1), /* Mauritania */ + COUNTRY_CHPLAN_ENT("MS", 0x26, 1), /* Montserrat (UK) */ + COUNTRY_CHPLAN_ENT("MT", 0x26, 1), /* Malta */ + COUNTRY_CHPLAN_ENT("MU", 0x26, 1), /* Mauritius */ + COUNTRY_CHPLAN_ENT("MV", 0x47, 1), /* Maldives */ + COUNTRY_CHPLAN_ENT("MW", 0x26, 1), /* Malawi */ + COUNTRY_CHPLAN_ENT("MX", 0x4D, 1), /* Mexico */ + COUNTRY_CHPLAN_ENT("MY", 0x63, 1), /* Malaysia */ + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1), /* Mozambique */ + COUNTRY_CHPLAN_ENT("NA", 0x26, 1), /* Namibia */ + COUNTRY_CHPLAN_ENT("NC", 0x26, 1), /* New Caledonia */ + COUNTRY_CHPLAN_ENT("NE", 0x26, 1), /* Niger */ + COUNTRY_CHPLAN_ENT("NF", 0x45, 1), /* Norfolk Island (Australia) */ + COUNTRY_CHPLAN_ENT("NG", 0x75, 1), /* Nigeria */ + COUNTRY_CHPLAN_ENT("NI", 0x76, 1), /* Nicaragua */ + COUNTRY_CHPLAN_ENT("NL", 0x26, 1), /* Netherlands */ + COUNTRY_CHPLAN_ENT("NO", 0x26, 1), /* Norway */ + COUNTRY_CHPLAN_ENT("NP", 0x48, 1), /* Nepal */ + COUNTRY_CHPLAN_ENT("NR", 0x26, 1), /* Nauru */ + COUNTRY_CHPLAN_ENT("NU", 0x45, 1), /* Niue */ + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1), /* New Zealand */ + COUNTRY_CHPLAN_ENT("OM", 0x26, 1), /* Oman */ + COUNTRY_CHPLAN_ENT("PA", 0x76, 1), /* Panama */ + COUNTRY_CHPLAN_ENT("PE", 0x76, 1), /* Peru */ + COUNTRY_CHPLAN_ENT("PF", 0x26, 1), /* French Polynesia (France) */ + COUNTRY_CHPLAN_ENT("PG", 0x35, 1), /* Papua New Guinea */ + COUNTRY_CHPLAN_ENT("PH", 0x35, 1), /* Philippines */ + COUNTRY_CHPLAN_ENT("PK", 0x51, 1), /* Pakistan */ + COUNTRY_CHPLAN_ENT("PL", 0x26, 1), /* Poland */ + COUNTRY_CHPLAN_ENT("PM", 0x26, 1), /* Saint Pierre and Miquelon (France) */ + COUNTRY_CHPLAN_ENT("PR", 0x76, 1), /* Puerto Rico */ + COUNTRY_CHPLAN_ENT("PT", 0x26, 1), /* Portugal */ + COUNTRY_CHPLAN_ENT("PW", 0x76, 1), /* Palau */ + COUNTRY_CHPLAN_ENT("PY", 0x76, 1), /* Paraguay */ + COUNTRY_CHPLAN_ENT("QA", 0x35, 1), /* Qatar */ + COUNTRY_CHPLAN_ENT("RE", 0x26, 1), /* Reunion (France) */ + COUNTRY_CHPLAN_ENT("RO", 0x26, 1), /* Romania */ + COUNTRY_CHPLAN_ENT("RS", 0x26, 1), /* Serbia, Kosovo */ + COUNTRY_CHPLAN_ENT("RU", 0x59, 1), /* Russia(fac/gost), Kaliningrad */ + COUNTRY_CHPLAN_ENT("RW", 0x26, 1), /* Rwanda */ + COUNTRY_CHPLAN_ENT("SA", 0x35, 1), /* Saudi Arabia */ + COUNTRY_CHPLAN_ENT("SB", 0x26, 1), /* Solomon Islands */ + COUNTRY_CHPLAN_ENT("SC", 0x76, 1), /* Seychelles */ + COUNTRY_CHPLAN_ENT("SE", 0x26, 1), /* Sweden */ + COUNTRY_CHPLAN_ENT("SG", 0x35, 1), /* Singapore */ + COUNTRY_CHPLAN_ENT("SH", 0x26, 1), /* Saint Helena (UK) */ + COUNTRY_CHPLAN_ENT("SI", 0x26, 1), /* Slovenia */ + COUNTRY_CHPLAN_ENT("SJ", 0x26, 1), /* Svalbard (Norway) */ + COUNTRY_CHPLAN_ENT("SK", 0x26, 1), /* Slovakia */ + COUNTRY_CHPLAN_ENT("SL", 0x26, 1), /* Sierra Leone */ + COUNTRY_CHPLAN_ENT("SM", 0x26, 1), /* San Marino */ + COUNTRY_CHPLAN_ENT("SN", 0x26, 1), /* Senegal */ + COUNTRY_CHPLAN_ENT("SO", 0x26, 1), /* Somalia */ + COUNTRY_CHPLAN_ENT("SR", 0x74, 1), /* Suriname */ + COUNTRY_CHPLAN_ENT("ST", 0x76, 1), /* Sao Tome and Principe */ + COUNTRY_CHPLAN_ENT("SV", 0x30, 1), /* El Salvador */ + COUNTRY_CHPLAN_ENT("SX", 0x76, 1), /* Sint Marteen */ + COUNTRY_CHPLAN_ENT("SZ", 0x26, 1), /* Swaziland */ + COUNTRY_CHPLAN_ENT("TC", 0x26, 1), /* Turks and Caicos Islands (UK) */ + COUNTRY_CHPLAN_ENT("TD", 0x26, 1), /* Chad */ + COUNTRY_CHPLAN_ENT("TF", 0x26, 1), /* French Southern and Antarctic Lands (FR Southern Territories) */ + COUNTRY_CHPLAN_ENT("TG", 0x26, 1), /* Togo */ + COUNTRY_CHPLAN_ENT("TH", 0x35, 1), /* Thailand */ + COUNTRY_CHPLAN_ENT("TJ", 0x26, 1), /* Tajikistan */ + COUNTRY_CHPLAN_ENT("TK", 0x45, 1), /* Tokelau */ + COUNTRY_CHPLAN_ENT("TM", 0x26, 1), /* Turkmenistan */ + COUNTRY_CHPLAN_ENT("TN", 0x47, 1), /* Tunisia */ + COUNTRY_CHPLAN_ENT("TO", 0x26, 1), /* Tonga */ + COUNTRY_CHPLAN_ENT("TR", 0x26, 1), /* Turkey, Northern Cyprus */ + COUNTRY_CHPLAN_ENT("TT", 0x76, 1), /* Trinidad & Tobago */ + COUNTRY_CHPLAN_ENT("TV", 0x21, 0), /* Tuvalu */ + COUNTRY_CHPLAN_ENT("TW", 0x76, 1), /* Taiwan */ + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1), /* Tanzania */ + COUNTRY_CHPLAN_ENT("UA", 0x35, 1), /* Ukraine */ + COUNTRY_CHPLAN_ENT("UG", 0x26, 1), /* Uganda */ + COUNTRY_CHPLAN_ENT("US", 0x76, 1), /* United States of America (USA) */ + COUNTRY_CHPLAN_ENT("UY", 0x30, 1), /* Uruguay */ + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1), /* Uzbekistan */ + COUNTRY_CHPLAN_ENT("VA", 0x26, 1), /* Holy See (Vatican City) */ + COUNTRY_CHPLAN_ENT("VC", 0x76, 1), /* Saint Vincent and the Grenadines */ + COUNTRY_CHPLAN_ENT("VE", 0x30, 1), /* Venezuela */ + COUNTRY_CHPLAN_ENT("VG", 0x76, 1), /* British Virgin Islands (UK) */ + COUNTRY_CHPLAN_ENT("VI", 0x76, 1), /* United States Virgin Islands (USA) */ + COUNTRY_CHPLAN_ENT("VN", 0x35, 1), /* Vietnam */ + COUNTRY_CHPLAN_ENT("VU", 0x26, 1), /* Vanuatu */ + COUNTRY_CHPLAN_ENT("WF", 0x26, 1), /* Wallis and Futuna (France) */ + COUNTRY_CHPLAN_ENT("WS", 0x76, 1), /* Samoa */ + COUNTRY_CHPLAN_ENT("YE", 0x26, 1), /* Yemen */ + COUNTRY_CHPLAN_ENT("YT", 0x26, 1), /* Mayotte (France) */ + COUNTRY_CHPLAN_ENT("ZA", 0x35, 1), /* South Africa */ + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1), /* Zambia */ + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1), /* Zimbabwe */ }; +#endif /* CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP or RTW_DEF_MODULE_REGULATORY_CERT or newest */ /* * rtw_get_chplan_from_country - @@ -1123,9 +2372,6 @@ static const struct country_chplan country_chplan_map[] = { */ const struct country_chplan *rtw_get_chplan_from_country(const char *country_code) { -#if RTW_DEF_MODULE_REGULATORY_CERT - const struct country_chplan *exc_ent = NULL; -#endif const struct country_chplan *ent = NULL; const struct country_chplan *map = NULL; u16 map_sz = 0; @@ -1138,10 +2384,9 @@ const struct country_chplan *rtw_get_chplan_from_country(const char *country_cod #ifdef CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP map = CUSTOMIZED_country_chplan_map; map_sz = sizeof(CUSTOMIZED_country_chplan_map) / sizeof(struct country_chplan); +#elif RTW_DEF_MODULE_REGULATORY_CERT + map_sz = rtw_def_module_country_chplan_map(&map); #else - #if RTW_DEF_MODULE_REGULATORY_CERT - exc_ent = rtw_def_module_get_chplan_from_country(code); - #endif map = country_chplan_map; map_sz = sizeof(country_chplan_map) / sizeof(struct country_chplan); #endif @@ -1153,20 +2398,20 @@ const struct country_chplan *rtw_get_chplan_from_country(const char *country_cod } } - #if RTW_DEF_MODULE_REGULATORY_CERT - if (!ent || !(COUNTRY_CHPLAN_DEF_MODULE_FALGS(ent) & RTW_DEF_MODULE_REGULATORY_CERT)) - exc_ent = ent = NULL; - if (exc_ent) - ent = exc_ent; - #endif - return ent; } void dump_country_chplan(void *sel, const struct country_chplan *ent) { - RTW_PRINT_SEL(sel, "\"%c%c\", 0x%02X%s\n" - , ent->alpha2[0], ent->alpha2[1], ent->chplan + char buf[16]; + + if (ent->chplan == RTW_CHPLAN_UNSPECIFIED) + sprintf(buf, "NA"); + else + sprintf(buf, "0x%02X", ent->chplan); + + RTW_PRINT_SEL(sel, "\"%c%c\", %s%s\n" + , ent->alpha2[0], ent->alpha2[1], buf , COUNTRY_CHPLAN_EN_11AC(ent) ? " ac" : "" ); } @@ -1199,7 +2444,7 @@ void dump_chplan_id_list(void *sel) u8 first = 1; int i; - for (i = 0; i < RTW_CHPLAN_MAX; i++) { + for (i = 0; i < RTW_ChannelPlanMap_size; i++) { if (!rtw_is_channel_plan_valid(i)) continue; @@ -1209,33 +2454,64 @@ void dump_chplan_id_list(void *sel) } else _RTW_PRINT_SEL(sel, "0x%02X ", i); } - - _RTW_PRINT_SEL(sel, "0x7F\n"); } +#ifdef CONFIG_RTW_DEBUG void dump_chplan_test(void *sel) { int i, j; + /* check redundent */ + for (i = 0; i < RTW_CHD_2G_MAX; i++) { + for (j = 0; j < i; j++) { + if (CH_LIST_LEN(rtw_channel_def_2g[i]) == CH_LIST_LEN(rtw_channel_def_2g[j]) + && _rtw_memcmp(&CH_LIST_CH(rtw_channel_def_2g[i], 0), &CH_LIST_CH(rtw_channel_def_2g[j], 0), CH_LIST_LEN(rtw_channel_def_2g[i]) + 1) == _TRUE) + RTW_PRINT_SEL(sel, "2G chd:%u and %u is the same\n", i, j); + } + } + /* check invalid channel */ - for (i = 0; i < RTW_RD_2G_MAX; i++) { - for (j = 0; j < CH_LIST_LEN(RTW_ChannelPlan2G[i]); j++) { - if (rtw_ch2freq(CH_LIST_CH(RTW_ChannelPlan2G[i], j)) == 0) - RTW_PRINT_SEL(sel, "invalid ch:%u at (%d,%d)\n", CH_LIST_CH(RTW_ChannelPlan2G[i], j), i, j); + for (i = 0; i < RTW_CHD_2G_MAX; i++) { + for (j = 0; j < CH_LIST_LEN(rtw_channel_def_2g[i]); j++) { + if (rtw_ch2freq(CH_LIST_CH(rtw_channel_def_2g[i], j)) == 0) + RTW_PRINT_SEL(sel, "2G invalid ch:%u at (%d,%d)\n", CH_LIST_CH(rtw_channel_def_2g[i], j), i, j); } } #if CONFIG_IEEE80211_BAND_5GHZ - for (i = 0; i < RTW_RD_5G_MAX; i++) { - for (j = 0; j < CH_LIST_LEN(RTW_ChannelPlan5G[i]); j++) { - if (rtw_ch2freq(CH_LIST_CH(RTW_ChannelPlan5G[i], j)) == 0) - RTW_PRINT_SEL(sel, "invalid ch:%u at (%d,%d)\n", CH_LIST_CH(RTW_ChannelPlan5G[i], j), i, j); + /* check redundent */ + for (i = 0; i < RTW_CHD_5G_MAX; i++) { + for (j = 0; j < i; j++) { + if (CH_LIST_LEN(rtw_channel_def_5g[i]) == CH_LIST_LEN(rtw_channel_def_5g[j]) + && _rtw_memcmp(&CH_LIST_CH(rtw_channel_def_5g[i], 0), &CH_LIST_CH(rtw_channel_def_5g[j], 0), CH_LIST_LEN(rtw_channel_def_5g[i]) + 1) == _TRUE) + RTW_PRINT_SEL(sel, "5G chd:%u and %u is the same\n", i, j); + } + } + + /* check invalid channel */ + for (i = 0; i < RTW_CHD_5G_MAX; i++) { + for (j = 0; j < CH_LIST_LEN(rtw_channel_def_5g[i]); j++) { + if (rtw_ch2freq(CH_LIST_CH(rtw_channel_def_5g[i], j)) == 0) + RTW_PRINT_SEL(sel, "5G invalid ch:%u at (%d,%d)\n", CH_LIST_CH(rtw_channel_def_5g[i], j), i, j); } } #endif + + /* check redundent */ + for (i = 0; i < RTW_ChannelPlanMap_size; i++) { + if (!rtw_is_channel_plan_valid(i)) + continue; + for (j = 0; j < i; j++) { + if (!rtw_is_channel_plan_valid(j)) + continue; + if (_rtw_memcmp(&RTW_ChannelPlanMap[i], &RTW_ChannelPlanMap[j], sizeof(RTW_ChannelPlanMap[i])) == _TRUE) + RTW_PRINT_SEL(sel, "channel plan 0x%02x and 0x%02x is the same\n", i, j); + } + } } +#endif /* CONFIG_RTW_DEBUG */ void dump_chplan_ver(void *sel) { - RTW_PRINT_SEL(sel, "%s-%s\n", RTW_DOMAIN_MAP_VER, RTW_COUNTRY_MAP_VER); + RTW_PRINT_SEL(sel, "%s%s-%s\n", RTW_DOMAIN_MAP_VER, RTW_DOMAIN_MAP_M_VER, RTW_COUNTRY_MAP_VER); } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_chplan.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_chplan.h index 97f008bd6462..f0e7dd6ca8dd 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_chplan.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_chplan.h @@ -16,135 +16,33 @@ #ifndef __RTW_CHPLAN_H__ #define __RTW_CHPLAN_H__ -enum rtw_chplan_id { - /* ===== 0x00 ~ 0x1F, legacy channel plan ===== */ - RTW_CHPLAN_FCC = 0x00, - RTW_CHPLAN_IC = 0x01, - RTW_CHPLAN_ETSI = 0x02, - RTW_CHPLAN_SPAIN = 0x03, - RTW_CHPLAN_FRANCE = 0x04, - RTW_CHPLAN_MKK = 0x05, - RTW_CHPLAN_MKK1 = 0x06, - RTW_CHPLAN_ISRAEL = 0x07, - RTW_CHPLAN_TELEC = 0x08, - RTW_CHPLAN_GLOBAL_DOAMIN = 0x09, - RTW_CHPLAN_WORLD_WIDE_13 = 0x0A, - RTW_CHPLAN_TAIWAN = 0x0B, - RTW_CHPLAN_CHINA = 0x0C, - RTW_CHPLAN_SINGAPORE_INDIA_MEXICO = 0x0D, - RTW_CHPLAN_KOREA = 0x0E, - RTW_CHPLAN_TURKEY = 0x0F, - RTW_CHPLAN_JAPAN = 0x10, - RTW_CHPLAN_FCC_NO_DFS = 0x11, - RTW_CHPLAN_JAPAN_NO_DFS = 0x12, - RTW_CHPLAN_WORLD_WIDE_5G = 0x13, - RTW_CHPLAN_TAIWAN_NO_DFS = 0x14, +#define RTW_CHPLAN_UNSPECIFIED 0xFF - /* ===== 0x20 ~ 0x7F, new channel plan ===== */ - RTW_CHPLAN_WORLD_NULL = 0x20, - RTW_CHPLAN_ETSI1_NULL = 0x21, - RTW_CHPLAN_FCC1_NULL = 0x22, - RTW_CHPLAN_MKK1_NULL = 0x23, - RTW_CHPLAN_ETSI2_NULL = 0x24, - RTW_CHPLAN_FCC1_FCC1 = 0x25, - RTW_CHPLAN_WORLD_ETSI1 = 0x26, - RTW_CHPLAN_MKK1_MKK1 = 0x27, - RTW_CHPLAN_WORLD_KCC1 = 0x28, - RTW_CHPLAN_WORLD_FCC2 = 0x29, - RTW_CHPLAN_FCC2_NULL = 0x2A, - RTW_CHPLAN_IC1_IC2 = 0x2B, - RTW_CHPLAN_MKK2_NULL = 0x2C, - RTW_CHPLAN_WORLD_CHILE1= 0x2D, - RTW_CHPLAN_WORLD1_WORLD1 = 0x2E, - RTW_CHPLAN_WORLD_CHILE2 = 0x2F, - RTW_CHPLAN_WORLD_FCC3 = 0x30, - RTW_CHPLAN_WORLD_FCC4 = 0x31, - RTW_CHPLAN_WORLD_FCC5 = 0x32, - RTW_CHPLAN_WORLD_FCC6 = 0x33, - RTW_CHPLAN_FCC1_FCC7 = 0x34, - RTW_CHPLAN_WORLD_ETSI2 = 0x35, - RTW_CHPLAN_WORLD_ETSI3 = 0x36, - RTW_CHPLAN_MKK1_MKK2 = 0x37, - RTW_CHPLAN_MKK1_MKK3 = 0x38, - RTW_CHPLAN_FCC1_NCC1 = 0x39, - RTW_CHPLAN_ETSI1_ETSI1 = 0x3A, - RTW_CHPLAN_ETSI1_ACMA1 = 0x3B, - RTW_CHPLAN_ETSI1_ETSI6 = 0x3C, - RTW_CHPLAN_ETSI1_ETSI12 = 0x3D, - RTW_CHPLAN_KCC1_KCC2 = 0x3E, - RTW_CHPLAN_FCC1_FCC11 = 0x3F, - RTW_CHPLAN_FCC1_NCC2 = 0x40, - RTW_CHPLAN_GLOBAL_NULL = 0x41, - RTW_CHPLAN_ETSI1_ETSI4 = 0x42, - RTW_CHPLAN_FCC1_FCC2 = 0x43, - RTW_CHPLAN_FCC1_NCC3 = 0x44, - RTW_CHPLAN_WORLD_ACMA1 = 0x45, - RTW_CHPLAN_FCC1_FCC8 = 0x46, - RTW_CHPLAN_WORLD_ETSI6 = 0x47, - RTW_CHPLAN_WORLD_ETSI7 = 0x48, - RTW_CHPLAN_WORLD_ETSI8 = 0x49, - RTW_CHPLAN_IC2_IC2 = 0x4A, - RTW_CHPLAN_KCC1_KCC3 = 0x4B, - RTW_CHPLAN_FCC1_FCC15 = 0x4C, - RTW_CHPLAN_FCC2_MEX1 = 0x4D, - RTW_CHPLAN_ETSI1_ETSI22 = 0x4E, - RTW_CHPLAN_NULL_MKK9 = 0x4F, - RTW_CHPLAN_WORLD_ETSI9 = 0x50, - RTW_CHPLAN_WORLD_ETSI10 = 0x51, - RTW_CHPLAN_WORLD_ETSI11 = 0x52, - RTW_CHPLAN_FCC1_NCC4 = 0x53, - RTW_CHPLAN_WORLD_ETSI12 = 0x54, - RTW_CHPLAN_FCC1_FCC9 = 0x55, - RTW_CHPLAN_WORLD_ETSI13 = 0x56, - RTW_CHPLAN_FCC1_FCC10 = 0x57, - RTW_CHPLAN_MKK2_MKK4 = 0x58, - RTW_CHPLAN_WORLD_ETSI14 = 0x59, - RTW_CHPLAN_NULL_FCC19 = 0x5A, - RTW_CHPLAN_NULL_FCC20 = 0x5B, - RTW_CHPLAN_NULL_FCC21 = 0x5C, - RTW_CHPLAN_ETSI1_ETSI23 = 0x5D, - RTW_CHPLAN_ETSI1_ETSI2 = 0x5E, - RTW_CHPLAN_FCC1_FCC5 = 0x60, - RTW_CHPLAN_FCC2_FCC7 = 0x61, - RTW_CHPLAN_FCC2_FCC1 = 0x62, - RTW_CHPLAN_WORLD_ETSI15 = 0x63, - RTW_CHPLAN_MKK2_MKK5 = 0x64, - RTW_CHPLAN_ETSI1_ETSI16 = 0x65, - RTW_CHPLAN_FCC1_FCC14 = 0x66, - RTW_CHPLAN_FCC1_FCC12 = 0x67, - RTW_CHPLAN_FCC2_FCC14 = 0x68, - RTW_CHPLAN_FCC2_FCC12 = 0x69, - RTW_CHPLAN_ETSI1_ETSI17 = 0x6A, - RTW_CHPLAN_WORLD_FCC16 = 0x6B, - RTW_CHPLAN_WORLD_FCC13 = 0x6C, - RTW_CHPLAN_FCC2_FCC15 = 0x6D, - RTW_CHPLAN_WORLD_FCC12 = 0x6E, - RTW_CHPLAN_NULL_ETSI8 = 0x6F, - RTW_CHPLAN_NULL_ETSI18 = 0x70, - RTW_CHPLAN_NULL_ETSI17 = 0x71, - RTW_CHPLAN_NULL_ETSI19 = 0x72, - RTW_CHPLAN_WORLD_FCC7 = 0x73, - RTW_CHPLAN_FCC2_FCC17 = 0x74, - RTW_CHPLAN_WORLD_ETSI20 = 0x75, - RTW_CHPLAN_FCC2_FCC11 = 0x76, - RTW_CHPLAN_WORLD_ETSI21 = 0x77, - RTW_CHPLAN_FCC1_FCC18 = 0x78, - RTW_CHPLAN_MKK2_MKK1 = 0x79, +u8 rtw_chplan_get_default_regd(u8 id); +bool rtw_chplan_is_empty(u8 id); +bool rtw_is_channel_plan_valid(u8 id); +bool rtw_regsty_is_excl_chs(struct registry_priv *regsty, u8 ch); - RTW_CHPLAN_MAX, - RTW_CHPLAN_REALTEK_DEFINE = 0x7F, - RTW_CHPLAN_UNSPECIFIED = 0xFF, +enum regd_src_t { + REGD_SRC_RTK_PRIV = 0, /* Regulatory settings from Realtek framework (Realtek defined or customized) */ + REGD_SRC_OS = 1, /* Regulatory settings from OS */ + REGD_SRC_NUM, }; -u8 rtw_chplan_get_default_regd(u8 id); -bool rtw_chplan_is_empty(u8 id); -#define rtw_is_channel_plan_valid(chplan) (((chplan) < RTW_CHPLAN_MAX || (chplan) == RTW_CHPLAN_REALTEK_DEFINE) && !rtw_chplan_is_empty(chplan)) -#define rtw_is_legacy_channel_plan(chplan) ((chplan) < 0x20) +#define regd_src_is_valid(src) ((src) < REGD_SRC_NUM) + +extern const char *_regd_src_str[]; +#define regd_src_str(src) ((src) >= REGD_SRC_NUM ? _regd_src_str[REGD_SRC_NUM] : _regd_src_str[src]) struct _RT_CHANNEL_INFO; -u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, struct _RT_CHANNEL_INFO *channel_set); +u8 init_channel_set(_adapter *adapter); +bool rtw_chset_is_dfs_range(struct _RT_CHANNEL_INFO *chset, u32 hi, u32 lo); +bool rtw_chset_is_dfs_ch(struct _RT_CHANNEL_INFO *chset, u8 ch); +bool rtw_chset_is_dfs_chbw(struct _RT_CHANNEL_INFO *chset, u8 ch, u8 bw, u8 offset); +u8 rtw_process_beacon_hint(_adapter *adapter, WLAN_BSSID_EX *bss); #define IS_ALPHA2_NO_SPECIFIED(_alpha2) ((*((u16 *)(_alpha2))) == 0xFFFF) +#define IS_ALPHA2_WORLDWIDE(_alpha2) (strncmp(_alpha2, "00", 2) == 0) #define RTW_MODULE_RTL8821AE_HMC_M2 BIT0 /* RTL8821AE(HMC + M.2) */ #define RTW_MODULE_RTL8821AU BIT1 /* RTL8821AU */ @@ -159,15 +57,24 @@ u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, struct _RT_CHANNEL_INFO #define RTW_MODULE_RTL8821CE BIT10 /* RTL8821CE */ #define RTW_MODULE_RTL8822CE BIT11 /* RTL8822CE */ +enum rtw_dfs_regd { + RTW_DFS_REGD_NONE = 0, + RTW_DFS_REGD_FCC = 1, + RTW_DFS_REGD_MKK = 2, + RTW_DFS_REGD_ETSI = 3, + RTW_DFS_REGD_NUM, + RTW_DFS_REGD_AUTO = 0xFF, /* follow channel plan */ +}; + +extern const char *_rtw_dfs_regd_str[]; +#define rtw_dfs_regd_str(region) (((region) >= RTW_DFS_REGD_NUM) ? _rtw_dfs_regd_str[RTW_DFS_REGD_NONE] : _rtw_dfs_regd_str[(region)]) + struct country_chplan { - char alpha2[2]; + char alpha2[2]; /* "00" means worldwide */ u8 chplan; #ifdef CONFIG_80211AC_VHT u8 en_11ac; #endif -#if RTW_DEF_MODULE_REGULATORY_CERT - u16 def_module_flags; /* RTW_MODULE_RTLXXX */ -#endif }; #ifdef CONFIG_80211AC_VHT @@ -176,18 +83,14 @@ struct country_chplan { #define COUNTRY_CHPLAN_EN_11AC(_ent) 0 #endif -#if RTW_DEF_MODULE_REGULATORY_CERT -#define COUNTRY_CHPLAN_DEF_MODULE_FALGS(_ent) ((_ent)->def_module_flags) -#else -#define COUNTRY_CHPLAN_DEF_MODULE_FALGS(_ent) 0 -#endif - const struct country_chplan *rtw_get_chplan_from_country(const char *country_code); void dump_country_chplan(void *sel, const struct country_chplan *ent); void dump_country_chplan_map(void *sel); void dump_chplan_id_list(void *sel); +#ifdef CONFIG_RTW_DEBUG void dump_chplan_test(void *sel); +#endif void dump_chplan_ver(void *sel); #endif /* __RTW_CHPLAN_H__ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_cmd.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_cmd.c index 3f17107294e1..0a561e0b37b5 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_cmd.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_cmd.c @@ -392,7 +392,11 @@ void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv) int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj); int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) { +#ifndef CONFIG_MAC_LOOPBACK_DRIVER u8 bAllow = _FALSE; /* set to _TRUE to allow enqueuing cmd when hw_init_completed is _FALSE */ +#else + u8 bAllow = _TRUE; /* hw_init_completed is _FALSE in the case of MAC loopback*/ +#endif #ifdef SUPPORT_HW_RFOFF_DETECTED /* To decide allow or not */ @@ -884,6 +888,7 @@ void rtw_readtssi_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd) } +#ifdef CONFIG_AP_MODE static u8 rtw_createbss_cmd(_adapter *adapter, int flags, bool adhoc , u8 ifbmp, u8 excl_ifbmp, s16 req_ch, s8 req_bw, s8 req_offset) { @@ -894,7 +899,7 @@ static u8 rtw_createbss_cmd(_adapter *adapter, int flags, bool adhoc u8 res = _SUCCESS; if (req_ch > 0 && req_bw >= 0 && req_offset >= 0) { - if (!rtw_chset_is_chbw_valid(adapter_to_chset(adapter), req_ch, req_bw, req_offset)) { + if (!rtw_chset_is_chbw_valid(adapter_to_chset(adapter), req_ch, req_bw, req_offset, 0, 0)) { res = _FAIL; goto exit; } @@ -982,42 +987,7 @@ inline u8 rtw_change_bss_chbw_cmd(_adapter *adapter, int flags , req_ch, req_bw, req_offset ); } - -#ifdef CONFIG_RTW_80211R -static void rtw_ft_validate_akm_type(_adapter *padapter, - struct wlan_network *pnetwork) -{ - struct security_priv *psecuritypriv = &(padapter->securitypriv); - struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); - u32 tmp_len; - u8 *ptmp; - - /*IEEE802.11-2012 Std. Table 8-101-AKM suite selectors*/ - if (rtw_ft_valid_akm(padapter, psecuritypriv->rsn_akm_suite_type)) { - ptmp = rtw_get_ie(&pnetwork->network.IEs[12], - _MDIE_, &tmp_len, (pnetwork->network.IELength-12)); - if (ptmp) { - pft_roam->mdid = *(u16 *)(ptmp+2); - pft_roam->ft_cap = *(ptmp+4); - - RTW_INFO("FT: target " MAC_FMT " mdid=(0x%2x), capacity=(0x%2x)\n", - MAC_ARG(pnetwork->network.MacAddress), pft_roam->mdid, pft_roam->ft_cap); - rtw_ft_set_flags(padapter, RTW_FT_PEER_EN); - - if (rtw_ft_otd_roam_en(padapter)) - rtw_ft_set_flags(padapter, RTW_FT_PEER_OTD_EN); - } else { - /* Don't use FT roaming if target AP cannot support FT */ - rtw_ft_clr_flags(padapter, (RTW_FT_PEER_EN|RTW_FT_PEER_OTD_EN)); - rtw_ft_reset_status(padapter); - } - } else { - /* It could be a non-FT connection */ - rtw_ft_clr_flags(padapter, (RTW_FT_PEER_EN|RTW_FT_PEER_OTD_EN)); - rtw_ft_reset_status(padapter); - } -} -#endif +#endif /* CONFIG_AP_MODE */ u8 rtw_joinbss_cmd(_adapter *padapter, struct wlan_network *pnetwork) { @@ -1175,10 +1145,17 @@ u8 rtw_joinbss_cmd(_adapter *padapter, struct wlan_network *pnetwork) && REGSTY_IS_11AC_ENABLE(pregistrypriv) && is_supported_vht(pregistrypriv->wireless_mode) && (!rfctl->country_ent || COUNTRY_CHPLAN_EN_11AC(rfctl->country_ent)) - && ((padapter->registrypriv.wifi_spec == 0) || (pnetwork->network.Configuration.DSConfig > 14)) ) { - rtw_restructure_vht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], - pnetwork->network.IELength, &psecnetwork->IELength); + u8 vht_enable = 0; + + if (pnetwork->network.Configuration.DSConfig > 14) + vht_enable = 1; + else if ((REGSTY_IS_11AC_24G_ENABLE(pregistrypriv)) && (padapter->registrypriv.wifi_spec == 0)) + vht_enable = 1; + + if (vht_enable == 1) + rtw_restructure_vht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], + pnetwork->network.IELength, &psecnetwork->IELength); } #endif #endif /* CONFIG_80211N_HT */ @@ -1265,10 +1242,9 @@ exit: return res; } - +#ifdef CONFIG_AP_MODE u8 rtw_stop_ap_cmd(_adapter *adapter, u8 flags) { -#ifdef CONFIG_AP_MODE struct cmd_obj *cmdobj; struct drvextra_cmd_parm *parm; struct cmd_priv *pcmdpriv = &adapter->cmdpriv; @@ -1315,11 +1291,10 @@ u8 rtw_stop_ap_cmd(_adapter *adapter, u8 flags) _exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL); } } - exit: return res; -#endif } +#endif /* CONFIG_AP_MODE */ #ifdef CONFIG_RTW_TOKEN_BASED_XMIT u8 rtw_tx_control_cmd(_adapter *adapter) @@ -1753,6 +1728,47 @@ exit: } +u8 rtw_iqk_cmd(_adapter *padapter, u8 flags) +{ + struct cmd_obj *pcmdobj; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + struct submit_ctx sctx; + u8 res = _SUCCESS; + + if (flags & RTW_CMDF_DIRECTLY) { + /* no need to enqueue, do the cmd hdl */ + rtw_iqk_hdl(padapter, NULL); + } else { + /* need enqueue, prepare cmd_obj and enqueue */ + pcmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (pcmdobj == NULL) { + res = _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_parm_rsp(pcmdobj, CMD_DO_IQK); + + if (flags & RTW_CMDF_WAIT_ACK) { + pcmdobj->sctx = &sctx; + rtw_sctx_init(&sctx, 10 * 1000); + } + + res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); + + if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { + rtw_sctx_wait(&sctx, __func__); + _enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + if (sctx.status == RTW_SCTX_SUBMITTED) + pcmdobj->sctx = NULL; + _exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + } + } + +exit: + + return res; +} + u8 rtw_set_chbw_cmd(_adapter *padapter, u8 ch, u8 bw, u8 ch_offset, u8 flags) { struct cmd_obj *pcmdobj; @@ -1820,7 +1836,7 @@ exit: return res; } -u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct country_chplan *country_ent, u8 swconfig) +static u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct country_chplan *country_ent, enum regd_src_t regd_src, u8 swconfig) { struct cmd_obj *cmdobj; struct SetChannelPlan_param *parm; @@ -1828,7 +1844,6 @@ u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct cou struct submit_ctx sctx; u8 res = _SUCCESS; - /* check if allow software config */ if (swconfig && rtw_hal_is_disable_sw_channel_plan(adapter) == _TRUE) { res = _FAIL; @@ -1840,7 +1855,7 @@ u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct cou chplan = country_ent->chplan; /* check input parameter */ - if (!rtw_is_channel_plan_valid(chplan)) { + if (regd_src == REGD_SRC_RTK_PRIV && !rtw_is_channel_plan_valid(chplan)) { res = _FAIL; goto exit; } @@ -1851,12 +1866,13 @@ u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct cou res = _FAIL; goto exit; } + parm->regd_src = regd_src; parm->country_ent = country_ent; parm->channel_plan = chplan; if (flags & RTW_CMDF_DIRECTLY) { /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ - if (H2C_SUCCESS != set_chplan_hdl(adapter, (u8 *)parm)) + if (H2C_SUCCESS != rtw_set_chplan_hdl(adapter, (u8 *)parm)) res = _FAIL; rtw_mfree((u8 *)parm, sizeof(*parm)); } else { @@ -1894,10 +1910,11 @@ u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct cou res = _FAIL; goto exit; } + parm->regd_src = regd_src; parm->country_ent = country_ent; parm->channel_plan = chplan; - if (H2C_SUCCESS != set_chplan_hdl(adapter, (u8 *)parm)) + if (H2C_SUCCESS != rtw_set_chplan_hdl(adapter, (u8 *)parm)) res = _FAIL; else res = _SUCCESS; @@ -1911,7 +1928,7 @@ exit: inline u8 rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, u8 swconfig) { - return _rtw_set_chplan_cmd(adapter, flags, chplan, NULL, swconfig); + return _rtw_set_chplan_cmd(adapter, flags, chplan, NULL, REGD_SRC_RTK_PRIV, swconfig); } inline u8 rtw_set_country_cmd(_adapter *adapter, int flags, const char *country_code, u8 swconfig) @@ -1934,7 +1951,108 @@ inline u8 rtw_set_country_cmd(_adapter *adapter, int flags, const char *country_ RTW_PRINT("%s country_code:\"%c%c\" mapping to chplan:0x%02x\n", __func__, country_code[0], country_code[1], ent->chplan); - return _rtw_set_chplan_cmd(adapter, flags, RTW_CHPLAN_UNSPECIFIED, ent, swconfig); + return _rtw_set_chplan_cmd(adapter, flags, RTW_CHPLAN_UNSPECIFIED, ent, REGD_SRC_RTK_PRIV, swconfig); +} + +#ifdef CONFIG_REGD_SRC_FROM_OS +inline u8 rtw_sync_os_regd_cmd(_adapter *adapter, int flags, const char *country_code, u8 dfs_region) +{ + struct country_chplan *ent; + const struct country_chplan *rtk_ent; + + /* allocate entry for regd source out of driver */ + ent = rtw_malloc(sizeof(*ent)); + if (ent == NULL) + return _FAIL; + + rtk_ent = rtw_get_chplan_from_country(country_code); + + _rtw_memcpy(ent->alpha2, country_code, 2); + + /* + * Regulation follows OS, the internal txpwr limit selection is searched by alpha2 + * "00" => WW, others use string mapping + * When no matching txpwr limit selection is found, use + * 1. txpwr lmit selection associated with alpha2 inside driver regulation database + * 2. WW when driver has no support of this alpha2 + */ + + ent->chplan = rtk_ent ? rtk_ent->chplan : RTW_CHPLAN_UNSPECIFIED; + #ifdef CONFIG_80211AC_VHT + ent->en_11ac = 1; + #endif + + /* TODO: dfs_region */ + + return _rtw_set_chplan_cmd(adapter, flags, RTW_CHPLAN_UNSPECIFIED, ent, REGD_SRC_OS, 1); +} +#endif /* CONFIG_REGD_SRC_FROM_OS */ + +u8 rtw_get_chplan_cmd(_adapter *adapter, int flags, struct get_chplan_resp **resp) +{ + struct cmd_obj *cmdobj; + struct get_channel_plan_param *parm; + struct cmd_priv *pcmdpriv = &adapter->cmdpriv; + struct submit_ctx sctx; + u8 res = _FAIL; + + if (!(flags & (RTW_CMDF_DIRECTLY | RTW_CMDF_WAIT_ACK))) + goto exit; + + /* prepare cmd parameter */ + parm = rtw_zmalloc(sizeof(*parm)); + if (parm == NULL) + goto exit; + parm->resp = resp; + + if (flags & RTW_CMDF_DIRECTLY) { + /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ + if (H2C_SUCCESS == rtw_get_chplan_hdl(adapter, (u8 *)parm)) + res = _SUCCESS; + rtw_mfree((u8 *)parm, sizeof(*parm)); + } else { + /* need enqueue, prepare cmd_obj and enqueue */ + cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(*cmdobj)); + if (cmdobj == NULL) { + rtw_mfree((u8 *)parm, sizeof(*parm)); + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_GET_CHANPLAN); + + if (flags & RTW_CMDF_WAIT_ACK) { + cmdobj->sctx = &sctx; + rtw_sctx_init(&sctx, 2000); + } + + res = rtw_enqueue_cmd(pcmdpriv, cmdobj); + + if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { + rtw_sctx_wait(&sctx, __func__); + _enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + if (sctx.status == RTW_SCTX_SUBMITTED) + cmdobj->sctx = NULL; + _exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + if (sctx.status != RTW_SCTX_DONE_SUCCESS) + res = _FAIL; + } + + /* allow get channel plan when cmd_thread is not running */ + if (res != _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { + parm = rtw_zmalloc(sizeof(*parm)); + if (parm == NULL) + goto exit; + parm->resp = resp; + + if (H2C_SUCCESS == rtw_get_chplan_hdl(adapter, (u8 *)parm)) + res = _SUCCESS; + + rtw_mfree((u8 *)parm, sizeof(*parm)); + } + } + +exit: + return res; } u8 rtw_led_blink_cmd(_adapter *padapter, void *pLed) @@ -2788,7 +2906,7 @@ u8 traffic_status_watchdog(_adapter *padapter, u8 from_timer) } - +#ifdef CONFIG_AP_MODE /* for 11n Logo 4.2.31/4.2.32 */ static void dynamic_update_bcn_check(_adapter *padapter) { @@ -2841,10 +2959,12 @@ static void dynamic_update_bcn_check(_adapter *padapter) count ++; } } +#endif /* CONFIG_AP_MODE */ + void rtw_iface_dynamic_chk_wk_hdl(_adapter *padapter) { - #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK #ifdef CONFIG_AP_MODE + #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) { expire_timeout_chk(padapter); #ifdef CONFIG_RTW_MESH @@ -2852,10 +2972,12 @@ void rtw_iface_dynamic_chk_wk_hdl(_adapter *padapter) rtw_mesh_peer_status_chk(padapter); #endif } - #endif #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */ + dynamic_update_bcn_check(padapter); + #endif /* CONFIG_AP_MODE */ + linked_status_chk(padapter, 0); traffic_status_watchdog(padapter, 0); @@ -2897,6 +3019,14 @@ void rtw_dynamic_chk_wk_hdl(_adapter *padapter) rtw_btcoex_Handler(padapter); #endif +#ifdef CONFIG_RTW_MULTI_AP + rtw_ch_util_rpt(padapter); +#endif + +#ifdef CONFIG_DFS_MASTER + rtw_chset_chk_non_ocp_finish(adapter_to_rfctl(padapter)); +#endif + #ifdef CONFIG_IPS_CHECK_IN_WD /* always call rtw_ps_processor() at last one. */ rtw_ps_processor(padapter); @@ -3165,7 +3295,7 @@ void rtw_lps_change_dtim_hdl(_adapter *padapter, u8 dtim) /* RTW_INFO("change DTIM from %d to %d, ps_mode=%d\n", pwrpriv->dtim, dtim, ps_mode); */ - rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); + rtw_exec_lps(padapter, ps_mode); } #ifdef CONFIG_LPS_LCLK @@ -3410,28 +3540,22 @@ exit: return res; } +#endif /* CONFIG_P2P */ #ifdef CONFIG_IOCTL_CFG80211 -static u8 _p2p_roch_cmd(_adapter *adapter +static struct rtw_roch_parm *rtw_alloc_roch_parm(_adapter *adapter , u64 cookie, struct wireless_dev *wdev , struct ieee80211_channel *ch, enum nl80211_channel_type ch_type , unsigned int duration , u8 flags ) { - struct cmd_obj *cmdobj; - struct drvextra_cmd_parm *parm; - struct p2p_roch_parm *roch_parm; - struct cmd_priv *pcmdpriv = &adapter->cmdpriv; - struct submit_ctx sctx; - u8 cancel = duration ? 0 : 1; - u8 res = _SUCCESS; + struct rtw_roch_parm *roch_parm; + bool cancel = duration ? 0 : 1; - roch_parm = (struct p2p_roch_parm *)rtw_zmalloc(sizeof(struct p2p_roch_parm)); - if (roch_parm == NULL) { - res = _FAIL; - goto exit; - } + roch_parm = (struct rtw_roch_parm *)rtw_zmalloc(sizeof(struct rtw_roch_parm)); + if (!roch_parm) + return NULL; roch_parm->cookie = cookie; roch_parm->wdev = wdev; @@ -3441,76 +3565,36 @@ static u8 _p2p_roch_cmd(_adapter *adapter roch_parm->duration = duration; } - if (flags & RTW_CMDF_DIRECTLY) { - /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ - if (H2C_SUCCESS != p2p_protocol_wk_hdl(adapter, cancel ? P2P_CANCEL_RO_CH_WK : P2P_RO_CH_WK, (u8 *)roch_parm)) - res = _FAIL; - rtw_mfree((u8 *)roch_parm, sizeof(*roch_parm)); - } else { - /* need enqueue, prepare cmd_obj and enqueue */ - parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); - if (parm == NULL) { - rtw_mfree((u8 *)roch_parm, sizeof(*roch_parm)); - res = _FAIL; - goto exit; - } - - parm->ec_id = P2P_PROTO_WK_CID; - parm->type = cancel ? P2P_CANCEL_RO_CH_WK : P2P_RO_CH_WK; - parm->size = sizeof(*roch_parm); - parm->pbuf = (u8 *)roch_parm; - - cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(*cmdobj)); - if (cmdobj == NULL) { - res = _FAIL; - rtw_mfree((u8 *)roch_parm, sizeof(*roch_parm)); - rtw_mfree((u8 *)parm, sizeof(*parm)); - goto exit; - } - - init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, CMD_SET_DRV_EXTRA); - - if (flags & RTW_CMDF_WAIT_ACK) { - cmdobj->sctx = &sctx; - rtw_sctx_init(&sctx, 10 * 1000); - } - - res = rtw_enqueue_cmd(pcmdpriv, cmdobj); - - if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { - rtw_sctx_wait(&sctx, __func__); - _enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL); - if (sctx.status == RTW_SCTX_SUBMITTED) - cmdobj->sctx = NULL; - _exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL); - if (sctx.status != RTW_SCTX_DONE_SUCCESS) - res = _FAIL; - } - } - -exit: - return res; + return roch_parm; } -inline u8 p2p_roch_cmd(_adapter *adapter +inline u8 rtw_roch_cmd(_adapter *adapter , u64 cookie, struct wireless_dev *wdev , struct ieee80211_channel *ch, enum nl80211_channel_type ch_type , unsigned int duration , u8 flags ) { - return _p2p_roch_cmd(adapter, cookie, wdev, ch, ch_type, duration, flags); + struct rtw_roch_parm *roch_parm; + + roch_parm = rtw_alloc_roch_parm(adapter, cookie, wdev, ch, ch_type, duration, flags); + if (!roch_parm) + return _FAIL; + + return rtw_roch_wk_cmd(adapter, ROCH_RO_CH_WK, roch_parm, flags); } -inline u8 p2p_cancel_roch_cmd(_adapter *adapter, u64 cookie, struct wireless_dev *wdev, u8 flags) +inline u8 rtw_cancel_roch_cmd(_adapter *adapter, u64 cookie, struct wireless_dev *wdev, u8 flags) { - return _p2p_roch_cmd(adapter, cookie, wdev, NULL, 0, 0, flags); + struct rtw_roch_parm *roch_parm; + + roch_parm = rtw_alloc_roch_parm(adapter, cookie, wdev, NULL, 0, 0, flags); + if (!roch_parm) + return _FAIL; + + return rtw_roch_wk_cmd(adapter, ROCH_CANCEL_RO_CH_WK, roch_parm, flags); } -#endif /* CONFIG_IOCTL_CFG80211 */ -#endif /* CONFIG_P2P */ - -#ifdef CONFIG_IOCTL_CFG80211 inline u8 rtw_mgnt_tx_cmd(_adapter *adapter, u8 tx_ch, u8 no_cck, const u8 *buf, size_t len, int wait_ack, u8 flags) { struct cmd_obj *cmdobj; @@ -3630,9 +3714,11 @@ void rtw_dfs_ch_switch_hdl(struct dvobj_priv *dvobj) { struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); _adapter *pri_adapter = dvobj_get_primary_adapter(dvobj); + struct mlme_ext_priv *pmlmeext = &pri_adapter->mlmeextpriv; u8 ifbmp_m = rtw_mi_get_ap_mesh_ifbmp(pri_adapter); u8 ifbmp_s = rtw_mi_get_ld_sta_ifbmp(pri_adapter); s16 req_ch; + u8 req_bw = CHANNEL_WIDTH_20, req_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; rtw_hal_macid_sleep_all_used(pri_adapter); @@ -3659,7 +3745,29 @@ void rtw_dfs_ch_switch_hdl(struct dvobj_priv *dvobj) RTW_INFO("%s switch to ch%d\n", __func__, req_ch); } - /* issue deauth for all asoc STA ifaces */ + /* only support 80 Mhz so far */ + if(rfctl->csa_ch_width == 1 || rfctl->csa_ch_width == 2 || rfctl->csa_ch_width == 3) { + if (rtw_get_offset_by_chbw(req_ch, CHANNEL_WIDTH_80, &req_offset)) { + req_bw = CHANNEL_WIDTH_80; + } else { + req_bw = CHANNEL_WIDTH_20; + req_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + } + } else if(rfctl->csa_ch_offset == 1) { + req_bw = CHANNEL_WIDTH_40; + req_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + } else if(rfctl->csa_ch_offset == 3) { + req_bw = CHANNEL_WIDTH_40; + req_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + } else{ + req_bw = CHANNEL_WIDTH_20; + req_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + } + + RTW_INFO("req_ch=%d, req_bw=%d, req_offset=%d, ifbmp_m=0x%02x, ifbmp_s=0x%02x\n" + , req_ch, req_bw, req_offset, ifbmp_m, ifbmp_s); + + /* update ch, bw, offset for all asoc STA ifaces */ if (ifbmp_s) { _adapter *iface; int i; @@ -3668,18 +3776,29 @@ void rtw_dfs_ch_switch_hdl(struct dvobj_priv *dvobj) iface = dvobj->padapters[i]; if (!iface || !(ifbmp_s & BIT(iface->iface_id))) continue; - set_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING); - - /* TODO: true op ch switching */ - issue_deauth(iface, get_bssid(&iface->mlmepriv), WLAN_REASON_DEAUTH_LEAVING); + + /* update STA mode ch/bw/offset */ + iface->mlmeextpriv.cur_channel = req_ch; + iface->mlmeextpriv.cur_bwmode = req_bw; + iface->mlmeextpriv.cur_ch_offset = req_offset; + /* updaet STA mode DSConfig , ap mode will update in rtw_change_bss_chbw_cmd */ + iface->mlmepriv.cur_network.network.Configuration.DSConfig = req_ch; + set_fwstate(&iface->mlmepriv, WIFI_CSA_UPDATE_BEACON); + } } + if (rfctl->csa_ch > 0) { + RTW_INFO("pmlmeext->csa_timer 70 seconds\n"); + /* wait 70 seconds for receiving beacons */ + _set_timer(&pmlmeext->csa_timer, CAC_TIME_MS + 10000); + } + #ifdef CONFIG_AP_MODE if (ifbmp_m) { - /* trigger channel selection without consideraton of asoc STA ifaces */ + /* trigger channel selection with consideraton of asoc STA ifaces */ rtw_change_bss_chbw_cmd(dvobj_get_primary_adapter(dvobj), RTW_CMDF_DIRECTLY - , ifbmp_m, ifbmp_s, req_ch, REQ_BW_ORI, REQ_OFFSET_NONE); + , ifbmp_m, 0, req_ch, REQ_BW_ORI, REQ_OFFSET_NONE); } else #endif { @@ -3688,27 +3807,19 @@ void rtw_dfs_ch_switch_hdl(struct dvobj_priv *dvobj) #ifdef CONFIG_DFS_MASTER rtw_dfs_rd_en_decision(pri_adapter, MLME_OPCH_SWITCH, ifbmp_s); #endif - set_channel_bwmode(pri_adapter, req_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + LeaveAllPowerSaveModeDirect(pri_adapter); + set_channel_bwmode(pri_adapter, req_ch, req_offset, req_bw); + /* update union ch/bw/offset for STA only */ + rtw_mi_update_union_chan_inf(pri_adapter, req_ch, req_offset, req_bw); + rtw_rfctl_update_op_mode(rfctl, 0, 0); } - - /* make asoc STA ifaces disconnect */ - /* TODO: true op ch switching */ - if (ifbmp_s) { - _adapter *iface; - int i; - for (i = 0; i < dvobj->iface_nums; i++) { - iface = dvobj->padapters[i]; - if (!iface || !(ifbmp_s & BIT(iface->iface_id))) - continue; - rtw_disassoc_cmd(iface, 0, RTW_CMDF_DIRECTLY); - rtw_indicate_disconnect(iface, 0, _FALSE); - rtw_free_assoc_resources(iface, _TRUE); - rtw_free_network_queue(iface, _TRUE); - } - } - rfctl->csa_ch = 0; + rfctl->csa_switch_cnt = 0; + rfctl->csa_ch_offset = 0; + rfctl->csa_ch_width = 0; + rfctl->csa_ch_freq_seg0 = 0; + rfctl->csa_ch_freq_seg1 = 0; rtw_hal_macid_wakeup_all_used(pri_adapter); rtw_mi_os_xmit_schedule(pri_adapter); @@ -3794,10 +3905,13 @@ u8 rtw_dfs_rd_hdl(_adapter *adapter) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + u8 cch; if (!rfctl->radar_detect_enabled) goto exit; + cch = rtw_get_center_ch(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset); + if (dvobj->oper_channel != rfctl->radar_detect_ch || rtw_get_passing_time_ms(rtw_get_on_oper_ch_time(adapter)) < 300 ) { @@ -3834,6 +3948,10 @@ u8 rtw_dfs_rd_hdl(_adapter *adapter) rtw_chset_update_non_ocp(rfctl->channel_set , rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset); + if (IS_UNDER_CAC(rfctl)) + rtw_nlrtw_cac_abort_event(adapter, cch, rfctl->radar_detect_bw); + rtw_nlrtw_radar_detect_event(adapter, cch, rfctl->radar_detect_bw); + rtw_dfs_ch_switch_hdl(dvobj); if (rfctl->radar_detect_enabled) @@ -3851,6 +3969,7 @@ cac_status_chk: rtw_hal_set_hwreg(adapter, HW_VAR_TXPAUSE, &pause); rfctl->cac_start_time = rfctl->cac_end_time = RTW_CAC_STOPPED; + rtw_nlrtw_cac_finish_event(adapter, cch, rfctl->radar_detect_bw); if (rtw_mi_check_fwstate(adapter, WIFI_UNDER_LINKING|WIFI_UNDER_SURVEY) == _FALSE) { u8 doiqk = _TRUE; @@ -3866,8 +3985,10 @@ cac_status_chk: doiqk = _FALSE; rtw_hal_set_hwreg(adapter , HW_VAR_DO_IQK , &doiqk); + #ifdef CONFIG_AP_MODE ResumeTxBeacon(adapter); rtw_mi_tx_beacon_hdl(adapter); + #endif } } @@ -4079,12 +4200,12 @@ void rtw_dfs_rd_en_decision(_adapter *adapter, u8 mlme_act, u8 excl_ifbmp) } if (MSTATE_STA_LD_NUM(&mstate) > 0) { - if (rtw_is_dfs_chbw(u_ch, u_bw, u_offset)) { + if (rtw_chset_is_dfs_chbw(rfctl->channel_set, u_ch, u_bw, u_offset)) { /* * if operate as slave w/o radar detect, * rely on AP on which STA mode connects */ - if (IS_DFS_SLAVE_WITH_RD(rfctl) && !rtw_odm_dfs_domain_unknown(dvobj)) + if (IS_DFS_SLAVE_WITH_RD(rfctl) && !rtw_rfctl_dfs_domain_unknown(rfctl)) needed = _TRUE; ld_sta_in_dfs = _TRUE; } @@ -4096,7 +4217,7 @@ void rtw_dfs_rd_en_decision(_adapter *adapter, u8 mlme_act, u8 excl_ifbmp) goto apply; } - if (rtw_is_dfs_chbw(u_ch, u_bw, u_offset)) + if (rtw_chset_is_dfs_chbw(rfctl->channel_set, u_ch, u_bw, u_offset)) needed = _TRUE; apply: @@ -5314,6 +5435,13 @@ u8 rtw_drvextra_cmd_hdl(_adapter *padapter, unsigned char *pbuf) ret = rtw_mgnt_tx_handler(padapter, pdrvextra_cmd->pbuf); break; #endif /* CONFIG_IOCTL_CFG80211 */ + +#if (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) + case ROCH_WK_CID: + ret = rtw_roch_wk_hdl(padapter, pdrvextra_cmd->type, pdrvextra_cmd->pbuf); + break; +#endif /* (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) */ + #ifdef CONFIG_MCC_MODE case MCC_CMD_WK_CID: ret = rtw_mcc_cmd_hdl(padapter, pdrvextra_cmd->type, pdrvextra_cmd->pbuf); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_debug.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_debug.c index 82535252544d..812660d27a89 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_debug.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_debug.c @@ -45,8 +45,11 @@ void dump_drv_version(void *sel) RTW_PRINT_SEL(sel, "%s %s\n", DRV_NAME, DRIVERVERSION); } +#ifdef CONFIG_PROC_DEBUG void dump_drv_cfg(void *sel) { +extern uint rtw_recvbuf_nr; + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)) char *kernel_version = utsname()->release; @@ -245,10 +248,12 @@ void dump_drv_cfg(void *sel) RTW_PRINT_SEL(sel, "\n=== RECV-INFO ===\n"); RTW_PRINT_SEL(sel, "NR_RECVFRAME = %d\n", NR_RECVFRAME); - RTW_PRINT_SEL(sel, "NR_RECVBUFF = %d\n", NR_RECVBUFF); + RTW_PRINT_SEL(sel, "NR_RECVBUFF = %d, rtw_recvbuf_nr = %d\n", NR_RECVBUFF, rtw_recvbuf_nr); RTW_PRINT_SEL(sel, "MAX_RECVBUF_SZ = %d\n", MAX_RECVBUF_SZ); } +#endif /* CONFIG_PROC_DEBUG */ + void dump_log_level(void *sel) { @@ -324,7 +329,7 @@ void mac_reg_dump(void *sel, _adapter *adapter) } #endif /* CONFIG_RTL8814A */ -#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) ||defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) +#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) for (i = 0x1000; i < 0x1800; i += 4) { if (j % 4 == 1) RTW_PRINT_SEL(sel, "0x%04x", i); @@ -332,7 +337,24 @@ void mac_reg_dump(void *sel, _adapter *adapter) if ((j++) % 4 == 0) _RTW_PRINT_SEL(sel, "\n"); } -#endif /* CONFIG_RTL8822B or 8821c or 8192f*/ +#endif /* CONFIG_RTL8822B or 8821c*/ + +#if defined(CONFIG_RTL8192F) + for (i = 0x1000; i < 0x1100; i += 4) { + if (j % 4 == 1) + RTW_PRINT_SEL(sel, "0x%04x", i); + _RTW_PRINT_SEL(sel, " 0x%08x ", rtw_read32(adapter, i)); + if ((j++) % 4 == 0) + _RTW_PRINT_SEL(sel, "\n"); + } + for (i = 0x1300; i < 0x1360; i += 4) { + if (j % 4 == 1) + RTW_PRINT_SEL(sel, "0x%04x", i); + _RTW_PRINT_SEL(sel, " 0x%08x ", rtw_read32(adapter, i)); + if ((j++) % 4 == 0) + _RTW_PRINT_SEL(sel, "\n"); + } +#endif #if defined(CONFIG_RTL8814B) for (i = 0x2000; i < 0x2800; i += 4) { @@ -542,6 +564,7 @@ void dump_tx_rate_bmp(void *sel, struct dvobj_priv *dvobj) void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) { +#if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG) struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); int i; _adapter *iface; @@ -615,11 +638,11 @@ void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) #define INFO_CNT_ARG #endif - RTW_PRINT_SEL(sel, "%-2s %-15s %c %-3s %-3s %-3s %-17s %-4s %-7s" + RTW_PRINT_SEL(sel, "%-2s %-15s %c %-3s %-3s %-3s %-17s %-4s %-7s %-5s" P2P_INFO_TITLE_FMT TSF_PAUSE_TIME_TITLE_FMT " %s"INFO_FMT"\n" - , "id", "ifname", ' ', "bup", "nup", "ncd", "macaddr", "port", "ch" + , "id", "ifname", ' ', "bup", "nup", "ncd", "macaddr", "port", "ch", "class" P2P_INFO_TITLE_ARG TSF_PAUSE_TIME_TITLE_ARG , "status"INFO_ARG); @@ -634,7 +657,7 @@ void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) #if (defined(CONFIG_SUPPORT_MULTI_BCN) && defined(CONFIG_FW_HANDLE_TXBCN)) || defined(CONFIG_CLIENT_PORT_CFG) _rtw_memset(&str_val, '\0', sizeof(str_val)); #endif - #if defined(CONFIG_SUPPORT_MULTI_BCN) && defined(CONFIG_FW_HANDLE_TXBCN) + #if defined(CONFIG_AP_MODE) && defined(CONFIG_SUPPORT_MULTI_BCN) && defined(CONFIG_FW_HANDLE_TXBCN) if (MLME_IS_AP(iface) || MLME_IS_MESH(iface)) { u8 len; char *p = str_val; @@ -671,7 +694,7 @@ void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) } #endif - RTW_PRINT_SEL(sel, "%2d %-15s %c %3u %3u %3u "MAC_FMT" %4hhu %3u,%u,%u" + RTW_PRINT_SEL(sel, "%2d %-15s %c %3u %3u %3u "MAC_FMT" %4hhu %3u,%u,%u %5u" P2P_INFO_VALUE_FMT TSF_PAUSE_TIME_VALUE_FMT " "MLME_STATE_FMT" " INFO_CNT_FMT"\n" @@ -685,6 +708,9 @@ void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) , iface->mlmeextpriv.cur_channel , iface->mlmeextpriv.cur_bwmode , iface->mlmeextpriv.cur_ch_offset + , rtw_get_op_class_by_chbw(iface->mlmeextpriv.cur_channel + , iface->mlmeextpriv.cur_bwmode + , iface->mlmeextpriv.cur_ch_offset) P2P_INFO_VALUE_ARG TSF_PAUSE_TIME_VALUE_ARG , MLME_STATE_ARG(iface) @@ -698,9 +724,9 @@ void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) "-------\n"); if (rtw_mi_get_ch_setting_union(dvobj_get_primary_adapter(dvobj), &u_ch, &u_bw, &u_offset)) - RTW_PRINT_SEL(sel, "%55s %3u,%u,%u\n" + RTW_PRINT_SEL(sel, "%55s %3u,%u,%u %5u\n" , "union:" - , u_ch, u_bw, u_offset); + , u_ch, u_bw, u_offset, rtw_get_op_class_by_chbw(u_ch, u_bw, u_offset)); RTW_PRINT_SEL(sel, "%55s %3u,%u,%u offch_state:%d\n" , "oper:" @@ -724,9 +750,9 @@ void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) else { u32 non_ocp_ms; u32 cac_ms; - u8 dfs_domain = rtw_odm_get_dfs_domain(dvobj); + u8 dfs_domain = rtw_rfctl_get_dfs_domain(rfctl); - _RTW_PRINT_SEL(sel, ", domain:%u", dfs_domain); + _RTW_PRINT_SEL(sel, ", domain:%s(%u)", rtw_dfs_regd_str(dfs_domain), dfs_domain); rtw_get_ch_waiting_ms(rfctl , rfctl->radar_detect_ch @@ -745,8 +771,10 @@ void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) _RTW_PRINT_SEL(sel, "\n"); } #endif /* CONFIG_DFS_MASTER */ +#endif /* CONFIG_RTW_DEBUG || CONFIG_PROC_DEBUG */ } +#if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG) #define SEC_CAM_ENT_ID_TITLE_FMT "%-2s" #define SEC_CAM_ENT_ID_TITLE_ARG "id" #define SEC_CAM_ENT_ID_VALUE_FMT "%2u" @@ -784,9 +812,11 @@ void dump_sec_cam_ent_title(void *sel, u8 has_id) } else RTW_PRINT_SEL(sel, SEC_CAM_ENT_TITLE_FMT"\n", SEC_CAM_ENT_TITLE_ARG); } +#endif void dump_sec_cam(void *sel, _adapter *adapter) { +#if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG) struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; struct sec_cam_ent ent; @@ -798,10 +828,12 @@ void dump_sec_cam(void *sel, _adapter *adapter) rtw_sec_read_cam_ent(adapter, i, (u8 *)(&ent.ctrl), ent.mac, ent.key); dump_sec_cam_ent(sel , &ent, i); } +#endif } void dump_sec_cam_cache(void *sel, _adapter *adapter) { +#if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG) struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; int i; @@ -812,7 +844,7 @@ void dump_sec_cam_cache(void *sel, _adapter *adapter) if (dvobj->cam_cache[i].ctrl != 0) dump_sec_cam_ent(sel, &dvobj->cam_cache[i], i); } - +#endif } static u8 fwdl_test_chksum_fail = 0; @@ -891,6 +923,7 @@ u16 rtw_ap_linking_test_force_asoc_fail(void) } #endif +#ifdef CONFIG_PROC_DEBUG int proc_get_defs_param(struct seq_file *m, void *v) { struct net_device *dev = m->private; @@ -938,7 +971,6 @@ ssize_t proc_set_defs_param(struct file *file, const char __user *buffer, size_t } -#ifdef CONFIG_PROC_DEBUG ssize_t proc_set_write_reg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { struct net_device *dev = data; @@ -1352,44 +1384,609 @@ ssize_t proc_set_roam_tgt_addr(struct file *file, const char __user *buffer, siz } #endif /* CONFIG_LAYER2_ROAMING */ -#ifdef CONFIG_RTW_80211R -ssize_t proc_set_ft_flags(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +#ifdef CONFIG_WAR_OFFLOAD +int proc_get_war_offload_enable(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + + if (_TRUE == pwrpriv->wowlan_war_offload_mode) { + RTW_PRINT_SEL(m, "\n[ Offload Feature Enabled ]\n"); + + if (WAR_ARP_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) { + RTW_PRINT_SEL(m, "\n ARP Reponse offload enabled\n"); + } +#ifdef CONFIG_OFFLOAD_MDNS_V4 + if (WAR_MDNS_V4_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) { + RTW_PRINT_SEL(m, "\n MDNS v4 Reponse offload enabled\n"); + } + if (WAR_MDNS_V4_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl) { + RTW_PRINT_SEL(m, "\n MDNS v4 Wakeup offload enabled\n"); + } +#endif /* CONFIG_OFFLOAD_MDNS_v4 */ +#ifdef CONFIG_OFFLOAD_MDNS_V6 + if (WAR_MDNS_V6_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) { + RTW_PRINT_SEL(m, "\n MDNS v6 Reponse offload enabled\n"); + } + if (WAR_MDNS_V6_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl) { + RTW_PRINT_SEL(m, "\n MDNS v6 Wakeup offload enabled\n"); + } +#endif /* CONFIG_OFFLOAD_MDNS_V6 */ + + if (WAR_ARP_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl) { + RTW_PRINT_SEL(m, "\n ARP Request wakeup enabled\n"); + } + + } else { + RTW_PRINT_SEL(m, "\n[ Offload Feature Disabled ]\n"); + } + + return 0; +} + +ssize_t proc_set_war_offload_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { struct net_device *dev = data; - _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); - + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); char tmp[32]; - u8 flags; + u32 offload_cfg = 0; - if (count < 1) + if (NULL == buffer) { + RTW_INFO(FUNC_ADPT_FMT ": input buffer is NULL!\n", FUNC_ADPT_ARG(padapter)); return -EFAULT; + } + + if (count < 1) { + RTW_INFO(FUNC_ADPT_FMT ": input length is 0!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } if (count > sizeof(tmp)) { + RTW_INFO(FUNC_ADPT_FMT ": input length is too large\n", FUNC_ADPT_ARG(padapter)); rtw_warn_on(1); return -EFAULT; } if (buffer && !copy_from_user(tmp, buffer, count)) { - int num = sscanf(tmp, "%hhx", &flags); + int num = sscanf(tmp, "%x", &offload_cfg); - if (num == 1) - adapter->mlmepriv.ft_roam.ft_flags = flags; + if (num == 1) { + RTW_INFO(FUNC_ADPT_FMT ": Set war offload cfg = %x\n", FUNC_ADPT_ARG(padapter), offload_cfg); + pwrpriv->wowlan_war_offload_ctrl = offload_cfg; + pwrpriv->wowlan_war_offload_mode = offload_cfg?_TRUE:_FALSE; + + } } return count; +} + +ssize_t proc_set_war_offload_ipv4_addr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + char tmp[128]; + u32 ip_addr = 0, ip_subnet = 0, ip_gateway = 0, index = 0; + struct war_ipv4_fmt* pip_info = &pwrpriv->wowlan_war_offload_ipv4; + + if (NULL == buffer) { + RTW_INFO(FUNC_ADPT_FMT ": input buffer is NULL!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count < 1) { + RTW_INFO(FUNC_ADPT_FMT ": input length is 0!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + RTW_INFO(FUNC_ADPT_FMT ": input length is too large\n", FUNC_ADPT_ARG(padapter)); + rtw_warn_on(1); + return -EFAULT; + } + + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%d %x %x %x", &index, &ip_addr, &ip_subnet, &ip_gateway); + + if (num == 4) { + pip_info->ip_addr[index-1] = ip_addr; + pip_info->ip_subnet[index-1] = ip_subnet; + pip_info->ip_gateway[index-1] = ip_gateway; + RTW_INFO(FUNC_ADPT_FMT "Setup IPv4 address:\n", FUNC_ADPT_ARG(padapter)); + RTW_INFO("Index(%d) IP=%d.%d.%d.%d\n", index, (ip_addr & 0xff), ((ip_addr & 0xff00)>>8), ((ip_addr & 0xff0000)>>16), ((ip_addr & 0xff000000)>>24)); + } else { + RTW_INFO("Wrong input buffer count (%d)\n", num); + return -EFAULT; + } + } + + return count; +} + +ssize_t proc_set_war_offload_ipv6_addr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + char tmp[255]; + u32 ip_addr = 0, ip_subnet = 0, ip_gateway = 0; + struct war_ipv6_fmt* pip_info = &pwrpriv->wowlan_war_offload_ipv6; + + if (NULL == buffer) { + RTW_INFO(FUNC_ADPT_FMT ": input buffer is NULL!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count < 1) { + RTW_INFO(FUNC_ADPT_FMT ": input length is 0!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + RTW_INFO(FUNC_ADPT_FMT ": input length is too large\n", FUNC_ADPT_ARG(padapter)); + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num; + int i; + u32 index; + u16 val[64]; + u16 big_endian_val[64]; + + num = sscanf(tmp, "%d %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", &index, &val[0], &val[1], &val[2], &val[3], &val[4], &val[5], &val[6], &val[7]); + for (i=0;i<8;i++) { + big_endian_val[i] = htons(val[i]); + } + _rtw_memcpy(pip_info->ipv6_addr[index-1], big_endian_val, RTW_IPv6_ADDR_LEN); + + if (num == 9) { + RTW_INFO(FUNC_ADPT_FMT "Setup IPv6 address\n", FUNC_ADPT_ARG(padapter)); + } else { + RTW_INFO("Wrong input count (%d)\n", num); + return -EFAULT; + } + } + + return count; +} + +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) + +int proc_get_war_offload_mdns_domain_name(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + + if (_TRUE == pwrpriv->wowlan_war_offload_mode) { + if ((WAR_MDNS_V4_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V4_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl)) { + RTW_PRINT_SEL(m, "\nDomain Name:[%s](%d)\n\n", + pwrpriv->wowlan_war_offload_mdns_domain_name, pwrpriv->wowlan_war_offload_mdns_domain_name_len); + } else { + RTW_PRINT_SEL(m, "\nMSND RSP Not enabled\n\n"); + } + } else { + RTW_PRINT_SEL(m, "\nOffload Not enabled\n\n"); + } + + return 0; +} + +ssize_t proc_set_war_offload_mdns_domain_name(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + char tmp[MAX_MDNS_DOMAIN_NAME_LEN+1]; + char domain_name[MAX_MDNS_DOMAIN_NAME_LEN+1]; + + if (NULL == buffer) { + RTW_INFO(FUNC_ADPT_FMT ": input buffer is NULL!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count < 1) { + RTW_INFO(FUNC_ADPT_FMT ": input length is 0!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + RTW_INFO(FUNC_ADPT_FMT ": input length is large than MAX_MDNS_DOMAIN_NAME_LEN(%d)\n", FUNC_ADPT_ARG(padapter), MAX_MDNS_DOMAIN_NAME_LEN); + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%s", domain_name); + if(1 == num) { + pwrpriv->wowlan_war_offload_mdns_domain_name_len = strlen(domain_name); + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_domain_name, 0x00, MAX_MDNS_DOMAIN_NAME_LEN); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_domain_name, domain_name, strlen(domain_name)); + } + } + + return count; +} + + +int proc_get_war_offload_mdns_machine_name(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + int i=0; + + if (_TRUE == pwrpriv->wowlan_war_offload_mode) { + if ((WAR_MDNS_V4_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V4_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl)) { + for(i=0; iwowlan_war_offload_mdns_mnane_num; i++) + { + RTW_PRINT_SEL(m, "[%d]", i); + rtw_wow_war_mdns_dump_buf(m, "Machine Name", + pwrpriv->wowlan_war_offload_mdns_mnane[i].name, pwrpriv->wowlan_war_offload_mdns_mnane[i].name_len); + } + RTW_PRINT_SEL(m, "\n"); + } else { + RTW_PRINT_SEL(m, "\nMSND RSP Not enabled\n\n"); + } + } else { + RTW_PRINT_SEL(m, "\nOffload Not enabled\n\n"); + } + + return 0; +} + + +ssize_t proc_set_war_offload_mdns_machine_name(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + char tmp[MAX_MDNS_MACHINE_NAME_LEN*3-1+1]; + + if (NULL == buffer) { + RTW_INFO(FUNC_ADPT_FMT ": input buffer is NULL!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count < 1) { + RTW_INFO(FUNC_ADPT_FMT ": input length is 0!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + RTW_INFO(FUNC_ADPT_FMT ": input length, %lu, is large than MAX_MDNS_MACHINE_NAME_LEN(%d)\n", FUNC_ADPT_ARG(padapter), (count+1)/3, MAX_MDNS_MACHINE_NAME_LEN); + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + if( strncmp(tmp, "clean", 5) == 0 ) + { + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_mnane, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_mnane)); + pwrpriv->wowlan_war_offload_mdns_mnane_num = 0; + }else{ + int idx = pwrpriv->wowlan_war_offload_mdns_mnane_num; + if(idx == MAX_MDNS_MACHINE_NAME_NUM){ + RTW_INFO(FUNC_ADPT_FMT ": the num of machine name is already %d(MAX_MDNS_MACHINE_NAME_NUM)!\n", FUNC_ADPT_ARG(padapter), MAX_MDNS_MACHINE_NAME_NUM); + return -EFAULT; + } + if(rtw_wow_war_mdns_parser_pattern(tmp, pwrpriv->wowlan_war_offload_mdns_mnane[idx].name, + (u32 *) &pwrpriv->wowlan_war_offload_mdns_mnane[idx].name_len, MAX_MDNS_MACHINE_NAME_LEN)) + pwrpriv->wowlan_war_offload_mdns_mnane_num++; + } + } + + return count; +} + + +int proc_get_war_offload_mdns_service_info(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + struct war_mdns_service_info *psinfo = pwrpriv->wowlan_war_offload_mdns_service; + int i=0, j=0; + + if (_TRUE == pwrpriv->wowlan_war_offload_mode) { + if ((WAR_MDNS_V4_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V4_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_WAKEUP_EN & pwrpriv->wowlan_war_offload_ctrl)) { + for(i=0; iwowlan_war_offload_mdns_service_info_num; i++) + { + RTW_PRINT_SEL(m, "[%d] service info ===> \n", i+1); + RTW_PRINT_SEL(m, "\tservice-transport-domain : %s(%d)- %s(%d)- %s(%d)\n", + psinfo[i].service, psinfo[i].service_len, + psinfo[i].transport, psinfo[i].transport_len, + psinfo[i].domain, psinfo[i].domain_len); + RTW_PRINT_SEL(m, "\ttarget for srv rsp : %s(%d)\n", psinfo[i].target, psinfo[i].target_len); + RTW_PRINT_SEL(m, "\tport : %x-%x, ttl : %d \n", psinfo[i].port[0], psinfo[i].port[1], psinfo[i].ttl); + j = psinfo[i].txt_rsp_idx; + RTW_PRINT_SEL(m, "\ttype txt rsp. [%d] \n", j); + rtw_wow_war_mdns_dump_txt(m, "type txt rsp. (Str)", + pwrpriv->wowlan_war_offload_mdns_txt_rsp[j].txt, pwrpriv->wowlan_war_offload_mdns_txt_rsp[j].txt_len); + + } + RTW_PRINT_SEL(m, "\n"); + } else { + RTW_PRINT_SEL(m, "\nMSND RSP Not enabled\n\n"); + } + } else { + RTW_PRINT_SEL(m, "\nOffload Not enabled\n\n"); + } + + return 0; +} + +ssize_t proc_set_war_offload_mdns_service_info(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + struct war_mdns_service_info *psinfo = pwrpriv->wowlan_war_offload_mdns_service; + u8 idx = 0, port[2], i=0; + char *tmp=NULL; + char srv[MAX_MDNS_SERVICE_NAME_LEN+1], trans[MAX_MDNS_TRANS_LEN+1], domain[MAX_MDNS_DOMAIN_LEN+1]; + char target[MAX_MDNS_TARGET_LEN+1]; + u32 ttl, tmp_txt_len=0, port0 =0, port1 =0; + u16 max_input_size = (MAX_MDNS_SERVICE_NAME_LEN+MAX_MDNS_TRANS_LEN+MAX_MDNS_DOMAIN_LEN+MAX_MDNS_TARGET_LEN+2); + int txt_idx; + + if (NULL == buffer) { + RTW_INFO(FUNC_ADPT_FMT ": input buffer is NULL!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count < 1) { + RTW_INFO(FUNC_ADPT_FMT ": input length is 0!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count > (sizeof(char)*(max_input_size)) ) { + RTW_INFO(FUNC_ADPT_FMT ": input length is too large\n", FUNC_ADPT_ARG(padapter)); + rtw_warn_on(1); + return -EFAULT; + } + + tmp = rtw_zvmalloc(sizeof(char)*(max_input_size)); + if (NULL == tmp) { + RTW_INFO(FUNC_ADPT_FMT ": tmp buffer allocate fail!!\n", FUNC_ADPT_ARG(padapter)); + count = -EFAULT; + goto exit; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%15s %4s %5s %63s %x %x %u %d", srv, trans, domain, target, &port0, &port1, &ttl, &txt_idx); + /* MAX_MDNS_SERVICE_NAME_LEN(15), MAX_MDNS_TRANS_LEN(4), MAX_MDNS_DOMAIN_LEN(5), MAX_MDNS_TARGET_LEN(63) */ + int idx = pwrpriv->wowlan_war_offload_mdns_service_info_num; + u16 curent_txt_total_size = 0; + //u16 sscanf_parameter_length = strlen(srv)+strlen(trans)+strlen(domain)+strlen(target)+2+2+4+1+num; + + if( strncmp(srv, "clean", 5) == 0 ) { + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_service, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_service)); + pwrpriv->wowlan_war_offload_mdns_service_info_num = 0; + } + /*else if(count != sscanf_parameter_length) + { + RTW_INFO(FUNC_ADPT_FMT ": Length of total parameters does not match the input buffer. (%d != %lu)\n", + FUNC_ADPT_ARG(padapter), sscanf_parameter_length, count); + RTW_INFO(FUNC_ADPT_FMT ": Please check the content and length of each parameter.\n", FUNC_ADPT_ARG(padapter)); + RTW_INFO(FUNC_ADPT_FMT ": input buffer = (%s)(%lu)!\n\n", FUNC_ADPT_ARG(padapter), tmp, count); + RTW_INFO(FUNC_ADPT_FMT ": srv = %s (%lu)!\n", FUNC_ADPT_ARG(padapter), srv, strlen(srv)); + RTW_INFO(FUNC_ADPT_FMT ": trans = %s (%lu)!\n", FUNC_ADPT_ARG(padapter), trans, strlen(trans)); + RTW_INFO(FUNC_ADPT_FMT ": domain = %s (%lu)!\n", FUNC_ADPT_ARG(padapter), domain, strlen(domain)); + RTW_INFO(FUNC_ADPT_FMT ": target = %s (%lu)!\n", FUNC_ADPT_ARG(padapter), target, strlen(target)); + RTW_INFO(FUNC_ADPT_FMT ": port = %x-%x, ttl = %d!\n", FUNC_ADPT_ARG(padapter), port0, port1, ttl); + RTW_INFO(FUNC_ADPT_FMT ": txt idx = %d!\n", FUNC_ADPT_ARG(padapter), txt_idx); + count = -EFAULT; + goto exit; + }*/else + { + port[0] = (u8)port0; + port[1] = (u8)port1; + + if(txt_idx >= MAX_MDNS_TXT_NUM) { + RTW_INFO(FUNC_ADPT_FMT ": input txt idx, %d, is out of range (0~%d)!\n", FUNC_ADPT_ARG(padapter), txt_idx, MAX_MDNS_TXT_NUM-1); + count = -EFAULT; + goto exit; + } + + if(pwrpriv->wowlan_war_offload_mdns_txt_rsp[txt_idx].txt_len == 0) { + RTW_INFO(FUNC_ADPT_FMT ": wowlan_war_offload_mdns_txt_rsp[%d] is null! Please initiate it first.\n", FUNC_ADPT_ARG(padapter), txt_idx); + count = -EFAULT; + goto exit; + } + + // 1. set the value of members for this new service + psinfo[idx].service_len = strlen(srv); + _rtw_memcpy(psinfo[idx].service, srv, psinfo[idx].service_len ); + psinfo[idx].transport_len = strlen(trans); + _rtw_memcpy(psinfo[idx].transport, trans, psinfo[idx].transport_len ); + psinfo[idx].domain_len = strlen(domain); + _rtw_memcpy(psinfo[idx].domain, domain, psinfo[idx].domain_len ); + psinfo[idx].target_len = strlen(target); + _rtw_memcpy(psinfo[idx].target, target, psinfo[idx].target_len ); + _rtw_memcpy(psinfo[idx].port, port, 2 ); + psinfo[idx].ttl = ttl; + psinfo[idx].txt_rsp_idx = txt_idx; + pwrpriv->wowlan_war_offload_mdns_service_info_num++; + } + } + +exit: + if(tmp) + rtw_vmfree(tmp, sizeof(char)*(max_input_size)); + return count; } -int proc_get_ft_flags(struct seq_file *m, void *v) +int proc_get_war_offload_mdns_txt_rsp(struct seq_file *m, void *v) { struct net_device *dev = m->private; _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + int i=0; - RTW_PRINT_SEL(m, "0x%02x\n", adapter->mlmepriv.ft_roam.ft_flags); + if (_TRUE == pwrpriv->wowlan_war_offload_mode) { + if ((WAR_MDNS_V4_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_RSP_EN & pwrpriv->wowlan_war_offload_ctrl) ) { + for(i=0; iwowlan_war_offload_mdns_txt_rsp_num; i++) { + RTW_PRINT_SEL(m, "[%d]", i); + if(pwrpriv->wowlan_war_offload_mdns_txt_rsp[i].txt_len==0){ + RTW_PRINT_SEL(m, " (null)\n"); + continue; + } + rtw_wow_war_mdns_dump_txt(m, "type txt rsp. (Str)", + pwrpriv->wowlan_war_offload_mdns_txt_rsp[i].txt, pwrpriv->wowlan_war_offload_mdns_txt_rsp[i].txt_len); + rtw_wow_war_mdns_dump_buf(m, "type txt rsp. (Hex)", + pwrpriv->wowlan_war_offload_mdns_txt_rsp[i].txt, pwrpriv->wowlan_war_offload_mdns_txt_rsp[i].txt_len); + } + RTW_PRINT_SEL(m, "\n"); + } else { + RTW_PRINT_SEL(m, "\nMSND RSP Not enabled\n\n"); + } + } else { + RTW_PRINT_SEL(m, "\nOffload Not enabled\n\n"); + } return 0; } -#endif + +ssize_t proc_set_war_offload_mdns_txt_rsp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + u16 max_input_size = (1+6+MAX_MDNS_TXT_SINGLE_LEN+2); + char* tmp=NULL; + char op[7]={0}, txt_str[MAX_MDNS_TXT_SINGLE_LEN+1]={0}; + int idx; + + if (NULL == buffer) { + RTW_INFO(FUNC_ADPT_FMT ": input buffer is NULL!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + if (count < 1) { + RTW_INFO(FUNC_ADPT_FMT ": input length is 0!\n", FUNC_ADPT_ARG(padapter)); + return -EFAULT; + } + + tmp = rtw_zvmalloc(sizeof(char)*(max_input_size)); + if (NULL == tmp) { + RTW_INFO(FUNC_ADPT_FMT ": tmp buffer allocate fail!!\n", FUNC_ADPT_ARG(padapter)); + count = -EFAULT; + goto exit; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + if( strncmp(tmp, "clean", 5) == 0 ) + { + /* clean ==> */ + if(pwrpriv->wowlan_war_offload_mdns_service_info_num==0){ + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_txt_rsp, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_txt_rsp)); + }else{ + RTW_INFO(FUNC_ADPT_FMT ": Txt rsp are refered! (Current service_info_num = %d)\n", FUNC_ADPT_ARG(padapter), pwrpriv->wowlan_war_offload_mdns_service_info_num); + count = -EFAULT; + goto exit; + } + + }else{ + /* set ==> */ + int num = sscanf(tmp, "%d %6s %256c", &idx, op, txt_str); + u16 sscanf_parameter_length = 0, txt_len = 0; + + txt_len = (strlen(txt_str)>MAX_MDNS_TXT_SINGLE_LEN)?MAX_MDNS_TXT_SINGLE_LEN:(strlen(txt_str)-1); + txt_str[txt_len]='\0'; + sscanf_parameter_length = 1 + strlen(op) + txt_len + num; + + if(count != sscanf_parameter_length) { + RTW_INFO(FUNC_ADPT_FMT ": Length of total parameters does not match the input buffer. (%d != %lu)(num=%d)\n", + FUNC_ADPT_ARG(padapter), sscanf_parameter_length, count, num); + RTW_INFO(FUNC_ADPT_FMT ": Please check the content and length of each parameter.\n", FUNC_ADPT_ARG(padapter)); + RTW_INFO(FUNC_ADPT_FMT ": input buffer = (%s)(%lu)!\n\n", FUNC_ADPT_ARG(padapter), tmp, count); + RTW_INFO(FUNC_ADPT_FMT ": op. = %s (%lu)!\n", FUNC_ADPT_ARG(padapter), op, strlen(op)); + RTW_INFO(FUNC_ADPT_FMT ": txt = %s (%lu)!\n", FUNC_ADPT_ARG(padapter), txt_str, strlen(txt_str)); + count = -EFAULT; + goto exit; + } else { + + u16 offset; + + if(idx >= MAX_MDNS_TXT_NUM) { + RTW_INFO(FUNC_ADPT_FMT ": the index, %d, is over the range of txt rsp(0~%d)!\n", FUNC_ADPT_ARG(padapter), idx, MAX_MDNS_TXT_NUM-1); + count = -EFAULT; + goto exit; + } + + if( strncmp(op, "new", 3) == 0 ) { + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt, 0, pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt_len); + pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt_len = 0; + }else if(strncmp(op, "append", 6) == 0 ){ + if((pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt_len+strlen(txt_str)+1) > MAX_MDNS_TXT_LEN) { + RTW_INFO(FUNC_ADPT_FMT ": the txt rsp(%d) will be over the limitation(%d) if append input string(%lu)!\n", FUNC_ADPT_ARG(padapter), + pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt_len, + MAX_MDNS_TXT_LEN, strlen(txt_str)+1); + count = -EFAULT; + goto exit; + } + }else{ + RTW_INFO(FUNC_ADPT_FMT ": Invaild op str %s (new/append only)!\n", FUNC_ADPT_ARG(padapter), op); + count = -EFAULT; + goto exit; + } + + offset = pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt_len; + pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt[offset++] = strlen(txt_str); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt + offset, txt_str, strlen(txt_str)); + pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt_len += (strlen(txt_str) + 1); /* actul len with length field */ + + /* Dump ==> */ + //RTW_PRINT_SEL(RTW_DBGDUMP, "[%d]", idx); + //rtw_wow_war_mdns_dump_txt(RTW_DBGDUMP, "type txt rsp. (Str)", + // pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt, pwrpriv->wowlan_war_offload_mdns_txt_rsp[idx].txt_len); + } + } + } + +exit: + if(tmp) + rtw_vmfree(tmp, sizeof(char)*(max_input_size)); + return count; + +} + +#endif /* CONFIG_OFFLOAD_MDNS_V4 || CONFIG_OFFLOAD_MDNS_V6 */ +#endif /* CONFIG_WAR_OFFLOAD */ + + int proc_get_qos_option(struct seq_file *m, void *v) { @@ -1675,7 +2272,9 @@ int proc_get_survey_info(struct seq_file *m, void *v) ie_wpa2 = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &ielen, pnetwork->network.IELength - 12); ie_cap = rtw_get_capability(&pnetwork->network); ie_wps = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsielen); +#ifdef CONFIG_P2P ie_p2p = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &ielen); +#endif ssid = pnetwork->network.Ssid.Ssid; sprintf(flag_str, "%s%s%s%s%s%s%s", (ie_wpa) ? "[WPA]" : "", @@ -1987,9 +2586,14 @@ int proc_get_trx_info(struct seq_file *m, void *v) RTW_PRINT_SEL(m, "free_recvframe_cnt=%d\n" , precvpriv->free_recvframe_cnt); - for (i = 0; i < 4; i++) { + for (i = 0; i < pxmitpriv->hwxmit_entry; i++) { phwxmit = pxmitpriv->hwxmits + i; - RTW_PRINT_SEL(m, "%d, hwq.accnt=%d\n", i, phwxmit->accnt); +#ifdef CONFIG_RTW_MGMT_QUEUE + if (i == pxmitpriv->hwxmit_entry - 1) + RTW_PRINT_SEL(m, "%d, hw_mgmt_q.accnt=%d\n", i, phwxmit->accnt); + else +#endif + RTW_PRINT_SEL(m, "%d, hwq.accnt=%d\n", i, phwxmit->accnt); } rtw_hal_get_hwreg(padapter, HW_VAR_DUMP_MAC_TXFIFO, (u8 *)m); @@ -3196,6 +3800,66 @@ ssize_t proc_set_rx_ampdu(struct file *file, const char __user *buffer, size_t c return count; } +#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT +int proc_get_tx_aval_th(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + + if (padapter) { + + switch(dvobj->tx_aval_int_thr_mode) { + case 0: + RTW_PRINT_SEL(m, "tx_aval_int_thr_mode = %u (auto) \n", dvobj->tx_aval_int_thr_mode); + break; + case 1: + RTW_PRINT_SEL(m, "tx_aval_int_thr_mode = %u (fixed)\n", dvobj->tx_aval_int_thr_mode); + RTW_PRINT_SEL(m, "tx_aval_threshold = 0x%x\n", dvobj->tx_aval_int_thr_value); + break; + case 2: + RTW_PRINT_SEL(m, "tx_aval_int_thr_mode = %u(by sdio_tx_max_len)\n", dvobj->tx_aval_int_thr_mode); + break; + default: + break; + } + } + return 0; +} + +ssize_t proc_set_tx_aval_th(struct file *file, const char __user *buffer + , size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + char tmp[32]; + u32 mode; + u32 threshold; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%d %d ",&mode, &threshold); + + if(num >= 1) + dvobj->tx_aval_int_thr_mode = mode; + if(num >= 2) + dvobj->tx_aval_int_thr_value = threshold; + RTW_INFO("dvobj->tx_aval_int_thr_mode= 0x%x\n", mode); + RTW_INFO("dvobj->tx_aval_int_thr_value= 0x%x(range need 1~255)\n", threshold); + } + + return count; +} +#endif /*CONFIG_SDIO_TX_ENABLE_AVAL_INT*/ int proc_get_rx_ampdu_factor(struct seq_file *m, void *v) { @@ -3511,6 +4175,51 @@ ssize_t proc_set_tx_amsdu_rate(struct file *file, const char __user *buffer, siz } #endif /* CONFIG_TX_AMSDU */ #endif /* CONFIG_80211N_HT */ + +#ifdef CONFIG_80211AC_VHT +int proc_get_vht_24g_enable(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + + if (pregpriv) + RTW_PRINT_SEL(m, "%d\n", pregpriv->vht_24g_enable); + + return 0; +} + +ssize_t proc_set_vht_24g_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + char tmp[32]; + u32 mode; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%d ", &mode); + + if ((num == 1) && pregpriv && (mode < 2)) { + pregpriv->vht_24g_enable = mode; + RTW_INFO("vht_24g_enable = %d\n", pregpriv->vht_24g_enable); + } + } + + return count; + +} +#endif + ssize_t proc_set_dyn_rrsr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { struct net_device *dev = data; @@ -3987,6 +4696,11 @@ int proc_get_all_sta_info(struct seq_file *m, void *v) RTW_PRINT_SEL(m, "sta_xmitpriv.be_q_qcnt=%d\n", psta->sta_xmitpriv.be_q.qcnt); RTW_PRINT_SEL(m, "sta_xmitpriv.bk_q_qcnt=%d\n", psta->sta_xmitpriv.bk_q.qcnt); +#ifdef CONFIG_RTW_MGMT_QUEUE + RTW_PRINT_SEL(m, "management sleepq_len=%d\n", psta->mgmt_sleepq_len); + RTW_PRINT_SEL(m, "sta_xmitpriv.mgmt_q_qcnt=%d\n", psta->sta_xmitpriv.mgmt_q.qcnt); +#endif + RTW_PRINT_SEL(m, "capability=0x%x\n", psta->capability); RTW_PRINT_SEL(m, "flags=0x%x\n", psta->flags); RTW_PRINT_SEL(m, "wpa_psk=0x%x\n", psta->wpa_psk); @@ -4026,6 +4740,9 @@ int proc_get_all_sta_info(struct seq_file *m, void *v) if (STA_OP_WFD_MODE(psta)) RTW_PRINT_SEL(m, "op_wfd_mode:0x%02x\n", STA_OP_WFD_MODE(psta)); + RTW_PRINT_SEL(m, "tx_bitrate_100kbps=%u\n", rtw_desc_rate_to_bitrate(psta->cmn.bw_mode, rtw_get_current_tx_rate(padapter, psta), rtw_get_current_tx_sgi(padapter, psta))); + RTW_PRINT_SEL(m, "rx_bitrate_100kbps=%u\n", rtw_desc_rate_to_bitrate(psta->cmn.bw_mode, psta->curr_rx_rate & 0x7f, (psta->curr_rx_rate & 0x80) >> 7)); + RTW_PRINT_SEL(m, "rssi=%d\n", psta->cmn.rssi_stat.rssi); RTW_PRINT_SEL(m, "==============================\n"); } @@ -5021,7 +5738,7 @@ ssize_t proc_set_wakeup_event(struct file *file, const char __user *buffer, else return -EFAULT; - if (num == 1 && wakeup_event <= 0x07) { + if (num == 1 && wakeup_event <= 0x0f) { registry_par->wakeup_event = wakeup_event; if (wakeup_event & BIT(1)) @@ -5051,6 +5768,30 @@ int proc_get_wakeup_reason(struct seq_file *m, void *v) RTW_PRINT_SEL(m, "last wake reason: %#02x\n", val); return 0; } +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +int proc_dump_wow_keep_alive_info(struct seq_file *m, void *v) { + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + int i; + + RTW_PRINT_SEL(m, "wowlan_keep_alive_mode: %d\n", pwrpriv->wowlan_keep_alive_mode); + RTW_PRINT_SEL(m,"LocKeepAlive: %d\n", pwrpriv->keep_alive_pattern_loc ); + RTW_PRINT_SEL(m, "keep_alive_pattern_len: %d\n", pwrpriv->keep_alive_pattern_len); + RTW_PRINT_SEL(m,"keep_alive_pattern= \n" ); + for (i=0 ; i < pwrpriv->keep_alive_pattern_len ; i++) { + RTW_PRINT_SEL(m,"[0x%x] ",pwrpriv->keep_alive_pattern[i]); + if(i%8 == 7) + RTW_PRINT_SEL(m,"\n"); + } + RTW_PRINT_SEL(m,"\n"); + RTW_PRINT_SEL(m," wowlan_keep_alive_period= %d ms\n", pwrpriv->wowlan_keep_alive_period*100); + RTW_PRINT_SEL(m," wowlan_keep_alive_retry_counter= %d\n", pwrpriv->wowlan_keep_alive_retry_counter); + RTW_PRINT_SEL(m," wowlan_keep_alive_retry_interval= %d ms\n", pwrpriv->wowlan_keep_alive_retry_interval*100); + return 0; +} +#endif /* CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + #endif /*CONFIG_WOWLAN*/ #ifdef CONFIG_GPIO_WAKEUP @@ -5059,9 +5800,14 @@ int proc_get_wowlan_gpio_info(struct seq_file *m, void *v) struct net_device *dev = m->private; _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + u8 gpio_index = pwrpriv->wowlan_gpio_index; + u8 gpio_output_state = pwrpriv->wowlan_gpio_output_state; u8 val = pwrpriv->is_high_active; - RTW_PRINT_SEL(m, "wakeup_gpio_idx: %d\n", WAKEUP_GPIO_IDX); + RTW_PRINT_SEL(m, "wakeup_gpio_idx: %d\n", gpio_index); +#if (!defined(CONFIG_WAKEUP_GPIO_INPUT_MODE) && !defined(CONFIG_RTW_ONE_PIN_GPIO)) + RTW_PRINT_SEL(m, "current_gpio_output_state: %d\n", gpio_output_state); +#endif RTW_PRINT_SEL(m, "high_active: %d\n", val); return 0; @@ -5102,22 +5848,22 @@ ssize_t proc_set_wowlan_gpio_info(struct file *file, const char __user *buffer, rtw_ps_deny(padapter, PS_DENY_IOCTL); LeaveAllPowerSaveModeDirect(padapter); - #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE +#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE if (pwrpriv->is_high_active == 0) - rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX); + rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index); else - rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, 0); - #else + rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, + GPIO_OUTPUT_LOW); +#else val8 = (pwrpriv->is_high_active == 0) ? 1 : 0; - rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE); - rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8); - #endif + rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE); + rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8); +#endif rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL); - RTW_INFO("set %s %d\n", "gpio_high_active", - pwrpriv->is_high_active); - RTW_INFO("%s: set GPIO_%d %d as default.\n", - __func__, WAKEUP_GPIO_IDX, val8); + RTW_INFO("%s set GPIO_%d to %s_ACTIVE\n", __func__, + pwrpriv->wowlan_gpio_index, + pwrpriv->is_high_active ? "HIGH" : "LOW"); } return count; @@ -5952,6 +6698,46 @@ ssize_t proc_set_monitor(struct file *file, const char __user *buffer, size_t co return count; } + +#ifdef RTW_SIMPLE_CONFIG +/* For RtwSimleConfig */ +int proc_get_simple_config(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + RTW_PRINT_SEL(m, "RTW Simple Config : %s\n", padapter->rtw_simple_config ? "Enable" : "Disable"); + + return 0; +} + +ssize_t proc_set_simple_config(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + char tmp[32]; + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 ret; + + if (count < 1) { + RTW_INFO("argument size is less than 1\n"); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%hhd", &ret); + + padapter->rtw_simple_config = ret ? _TRUE : _FALSE; + } + + return count; +} +#endif + #ifdef DBG_XMIT_BLOCK int proc_get_xmit_block(struct seq_file *m, void *v) { @@ -6017,7 +6803,7 @@ int proc_get_efuse_map(struct seq_file *m, void *v) ips_mode = pwrctrlpriv->ips_mode; rtw_pm_set_ips(padapter, IPS_NONE); - +#ifdef CONFIG_EFUSE_CONFIG_FILE if (pHalData->efuse_file_status == EFUSE_FILE_LOADED) { RTW_PRINT_SEL(m, "File eFuse Map loaded! file path:%s\nDriver eFuse Map From File\n", EFUSE_MAP_PATH); if (pHalData->bautoload_fail_flag) @@ -6026,7 +6812,10 @@ int proc_get_efuse_map(struct seq_file *m, void *v) RTW_PRINT_SEL(m, "Open File eFuse Map Fail ! file path:%s\nDriver eFuse Map From Default\n", EFUSE_MAP_PATH); if (pHalData->bautoload_fail_flag) RTW_PRINT_SEL(m, "HW Autoload fail!!!\n"); - } else { + } else +#endif + + { RTW_PRINT_SEL(m, "Driver eFuse Map From HW\n"); if (pHalData->bautoload_fail_flag) RTW_PRINT_SEL(m, "HW Autoload fail!!!\n"); @@ -6229,6 +7018,7 @@ ssize_t proc_set_tx_deauth(struct file *file, const char __user *buffer, size_t return count; /* TX unicast deauth to AP */ issue_deauth_11w(padapter, get_my_bssid(&(pmlmeinfo->network)), 0, (u8)key_type); +#ifdef CONFIG_AP_MODE } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) { u8 updated = _FALSE; @@ -6279,6 +7069,7 @@ ssize_t proc_set_tx_deauth(struct file *file, const char __user *buffer, size_t } associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL); +#endif /* CONFIG_AP_MODE */ } return count; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ft.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ft.c new file mode 100644 index 000000000000..2260f876ebe6 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ft.c @@ -0,0 +1,669 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#include +#include + +#ifdef CONFIG_RTW_80211R + +#ifndef RTW_FT_DBG + #define RTW_FT_DBG 0 +#endif +#if RTW_FT_DBG + #define RTW_FT_INFO(fmt, arg...) \ + RTW_INFO(fmt, arg) + #define RTW_FT_DUMP(str, data, len) \ + RTW_INFO_DUMP(str, data, len) +#else + #define RTW_FT_INFO(fmt, arg...) do {} while (0) + #define RTW_FT_DUMP(str, data, len) do {} while (0) +#endif + +void rtw_ft_info_init(struct ft_roam_info *pft) +{ + _rtw_memset(pft, 0, sizeof(struct ft_roam_info)); + pft->ft_flags = 0 + | RTW_FT_EN + /* | RTW_FT_OTD_EN */ +#ifdef CONFIG_RTW_BTM_ROAM + | RTW_FT_BTM_ROAM +#endif + ; + pft->ft_updated_bcn = _FALSE; + RTW_FT_INFO("%s : ft_flags=0x%02x\n", __func__, pft->ft_flags); +} + +ssize_t rtw_ft_proc_flags_set(struct file *file, + const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + char tmp[32]; + u8 flags; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%hhx", &flags); + if (num == 1) + adapter->mlmepriv.ft_roam.ft_flags = flags; + } + + return count; + +} + +int rtw_ft_proc_flags_get(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + RTW_PRINT_SEL(m, "0x%02x\n", adapter->mlmepriv.ft_roam.ft_flags); + + return 0; +} + +u8 rtw_ft_chk_roaming_candidate( + _adapter *padapter, struct wlan_network *competitor) +{ + u8 *pmdie; + u32 mdie_len = 0; + struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); + + if (!(pmdie = rtw_get_ie(&competitor->network.IEs[12], + _MDIE_, &mdie_len, competitor->network.IELength-12))) { + RTW_INFO("FT : MDIE not foud in competitor!\n"); + return _FALSE; + } + + if (!_rtw_memcmp(&pft_roam->mdid, (pmdie+2), 2)) { + RTW_INFO("FT : unmatched MDIE!\n"); + return _FALSE; + } + + /*The candidate don't support over-the-DS*/ + if (rtw_ft_valid_otd_candidate(padapter, pmdie)) { + RTW_INFO("FT: ignore the candidate(" + MAC_FMT ") for over-the-DS\n", + MAC_ARG(competitor->network.MacAddress)); + /* rtw_ft_clr_flags(padapter, RTW_FT_PEER_OTD_EN); */ + return _FALSE; + } + + if (rtw_ft_chk_flags(padapter, RTW_FT_TEST_RSSI_ROAM)) { + if (!_rtw_memcmp(padapter->mlmepriv.cur_network.network.MacAddress, + competitor->network.MacAddress, ETH_ALEN) ) { + competitor->network.Rssi +=20; + RTW_FT_INFO("%s : update "MAC_FMT" RSSI to %d for RTW_FT_TEST_RSSI_ROAM\n", + __func__, MAC_ARG(competitor->network.MacAddress), + (int)competitor->network.Rssi); + rtw_ft_clr_flags(padapter, RTW_FT_TEST_RSSI_ROAM); + } + } + + return _TRUE; +} + +void rtw_ft_update_stainfo(_adapter *padapter, WLAN_BSSID_EX *pnetwork) +{ + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta = NULL; + + psta = rtw_get_stainfo(pstapriv, pnetwork->MacAddress); + if (psta == NULL) + psta = rtw_alloc_stainfo(pstapriv, pnetwork->MacAddress); + + if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { + + padapter->securitypriv.binstallGrpkey = _FALSE; + padapter->securitypriv.busetkipkey = _FALSE; + padapter->securitypriv.bgrpkey_handshake = _FALSE; + + psta->ieee8021x_blocked = _TRUE; + psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; + + _rtw_memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype)); + _rtw_memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype)); + _rtw_memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype)); + } + +} + +void rtw_ft_reassoc_event_callback(_adapter *padapter, u8 *pbuf) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf; + struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&(pmlmeinfo->network); + struct cfg80211_ft_event_params ft_evt_parms; + _irqL irqL; + + _rtw_memset(&ft_evt_parms, 0, sizeof(ft_evt_parms)); + rtw_ft_update_stainfo(padapter, pnetwork); + ft_evt_parms.ies_len = pft_roam->ft_event.ies_len; + ft_evt_parms.ies = rtw_zmalloc(ft_evt_parms.ies_len); + if (ft_evt_parms.ies) + _rtw_memcpy((void *)ft_evt_parms.ies, pft_roam->ft_event.ies, ft_evt_parms.ies_len); + else + goto err_2; + + ft_evt_parms.target_ap = rtw_zmalloc(ETH_ALEN); + if (ft_evt_parms.target_ap) + _rtw_memcpy((void *)ft_evt_parms.target_ap, pstassoc->macaddr, ETH_ALEN); + else + goto err_1; + + ft_evt_parms.ric_ies = pft_roam->ft_event.ric_ies; + ft_evt_parms.ric_ies_len = pft_roam->ft_event.ric_ies_len; + + /* It's a KERNEL issue between v4.11 ~ v4.16, + * <= v4.10, NLMSG_DEFAULT_SIZE is used for nlmsg_new(). + * v4.11 ~ v4.16, only used "100 + >ric_ies_len" for nlmsg_new() + * even then DRIVER don't support RIC. + * >= v4.17, issue should correct as "100 + ies_len + ric_ies_len". + */ + #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0))) + if (!ft_evt_parms.ric_ies_len) + ft_evt_parms.ric_ies_len = ft_evt_parms.ies_len; + else + ft_evt_parms.ric_ies_len += ft_evt_parms.ies_len; + #endif + + rtw_ft_lock_set_status(padapter, RTW_FT_AUTHENTICATED_STA, &irqL); + rtw_cfg80211_ft_event(padapter, &ft_evt_parms); + RTW_INFO("%s: to "MAC_FMT"\n", __func__, MAC_ARG(ft_evt_parms.target_ap)); + + rtw_mfree((u8 *)pft_roam->ft_event.target_ap, ETH_ALEN); +err_1: + rtw_mfree((u8 *)ft_evt_parms.ies, ft_evt_parms.ies_len); +err_2: + return; +} + +void rtw_ft_validate_akm_type(_adapter *padapter, + struct wlan_network *pnetwork) +{ + struct security_priv *psecuritypriv = &(padapter->securitypriv); + struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); + u32 tmp_len; + u8 *ptmp; + + /*IEEE802.11-2012 Std. Table 8-101-AKM suite selectors*/ + if (rtw_ft_valid_akm(padapter, psecuritypriv->rsn_akm_suite_type)) { + ptmp = rtw_get_ie(&pnetwork->network.IEs[12], + _MDIE_, &tmp_len, (pnetwork->network.IELength-12)); + if (ptmp) { + pft_roam->mdid = *(u16 *)(ptmp+2); + pft_roam->ft_cap = *(ptmp+4); + + RTW_INFO("FT: target " MAC_FMT " mdid=(0x%2x), capacity=(0x%2x)\n", + MAC_ARG(pnetwork->network.MacAddress), pft_roam->mdid, pft_roam->ft_cap); + rtw_ft_set_flags(padapter, RTW_FT_PEER_EN); + RTW_FT_INFO("%s : peer support FTOTA(0x%02x)\n", __func__, pft_roam->ft_flags); + + if (rtw_ft_otd_roam_en(padapter)) { + rtw_ft_set_flags(padapter, RTW_FT_PEER_OTD_EN); + RTW_FT_INFO("%s : peer support FTOTD(0x%02x)\n", __func__, pft_roam->ft_flags); + } + } else { + /* Don't use FT roaming if target AP cannot support FT */ + rtw_ft_clr_flags(padapter, (RTW_FT_PEER_EN|RTW_FT_PEER_OTD_EN)); + rtw_ft_reset_status(padapter); + } + } else { + /* It could be a non-FT connection */ + rtw_ft_clr_flags(padapter, (RTW_FT_PEER_EN|RTW_FT_PEER_OTD_EN)); + rtw_ft_reset_status(padapter); + } + + RTW_FT_INFO("%s : ft_flags=0x%02x\n", __func__, pft_roam->ft_flags); +} + +void rtw_ft_update_bcn(_adapter *padapter, union recv_frame *precv_frame) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint len = precv_frame->u.hdr.len; + WLAN_BSSID_EX *pbss; + + if (rtw_ft_chk_status(padapter,RTW_FT_ASSOCIATED_STA) + && (pmlmepriv->ft_roam.ft_updated_bcn == _FALSE)) { + pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX)); + if (pbss) { + if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) { + struct beacon_keys recv_beacon; + + update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE); + /* Move into rtw_get_bcn_keys */ + /* rtw_get_bcn_info(&(pmlmepriv->cur_network)); */ + + /* update bcn keys */ + if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) { + RTW_FT_INFO("%s: beacon keys ready\n", __func__); + _rtw_memcpy(&pmlmepriv->cur_beacon_keys, + &recv_beacon, sizeof(recv_beacon)); + if (is_hidden_ssid(recv_beacon.ssid, recv_beacon.ssid_len)) { + _rtw_memcpy(pmlmepriv->cur_beacon_keys.ssid, pmlmeinfo->network.Ssid.Ssid, IW_ESSID_MAX_SIZE); + pmlmepriv->cur_beacon_keys.ssid_len = pmlmeinfo->network.Ssid.SsidLength; + } + } else { + RTW_ERR("%s: get beacon keys failed\n", __func__); + _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon)); + } + #ifdef CONFIG_BCN_CNT_CONFIRM_HDL + pmlmepriv->new_beacon_cnts = 0; + #endif + } + rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX)); + } + + /* check the vendor of the assoc AP */ + pmlmeinfo->assoc_AP_vendor = + check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), + (len - sizeof(struct rtw_ieee80211_hdr_3addr))); + + /* update TSF Value */ + update_TSF(pmlmeext, pframe, len); + pmlmeext->bcn_cnt = 0; + pmlmeext->last_bcn_cnt = 0; + pmlmepriv->ft_roam.ft_updated_bcn = _TRUE; + } +} + +void rtw_ft_start_clnt_join(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); + + if (rtw_ft_otd_roam(padapter)) { + pmlmeinfo->state = WIFI_FW_AUTH_SUCCESS | WIFI_FW_STATION_STATE; + pft_roam->ft_event.ies = + (pft_roam->ft_action + sizeof(struct rtw_ieee80211_hdr_3addr) + 16); + pft_roam->ft_event.ies_len = + (pft_roam->ft_action_len - sizeof(struct rtw_ieee80211_hdr_3addr)); + + /*Not support RIC*/ + pft_roam->ft_event.ric_ies = NULL; + pft_roam->ft_event.ric_ies_len = 0; + rtw_ft_report_evt(padapter); + return; + } + + pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE; + start_clnt_auth(padapter); +} + +u8 rtw_ft_update_rsnie( + _adapter *padapter, u8 bwrite, + struct pkt_attrib *pattrib, u8 **pframe) +{ + struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); + u8 *pie; + u32 len; + + pie = rtw_get_ie(pft_roam->updated_ft_ies, EID_WPA2, &len, + pft_roam->updated_ft_ies_len); + + if (!bwrite) + return (pie)?_SUCCESS:_FAIL; + + if (pie) { + *pframe = rtw_set_ie(((u8 *)*pframe), EID_WPA2, len, + pie+2, &(pattrib->pktlen)); + } else + return _FAIL; + + return _SUCCESS; +} + +static u8 rtw_ft_update_mdie( + _adapter *padapter, struct pkt_attrib *pattrib, u8 **pframe) +{ + struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); + u8 *pie, mdie[3]; + u32 len = 3; + + if (rtw_ft_roam(padapter)) { + if ((pie = rtw_get_ie(pft_roam->updated_ft_ies, _MDIE_, + &len, pft_roam->updated_ft_ies_len))) { + pie = (pie + 2); /* ignore md-id & length */ + } else + return _FAIL; + } else { + *((u16 *)&mdie[0]) = pft_roam->mdid; + mdie[2] = pft_roam->ft_cap; + pie = &mdie[0]; + } + + *pframe = rtw_set_ie(((u8 *)*pframe), _MDIE_, len , pie, &(pattrib->pktlen)); + return _SUCCESS; +} + +static u8 rtw_ft_update_ftie( + _adapter *padapter, struct pkt_attrib *pattrib, u8 **pframe) +{ + struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); + u8 *pie; + u32 len; + + if ((pie = rtw_get_ie(pft_roam->updated_ft_ies, _FTIE_, &len, + pft_roam->updated_ft_ies_len)) != NULL) { + *pframe = rtw_set_ie(*pframe, _FTIE_, len , + (pie+2), &(pattrib->pktlen)); + } else + return _FAIL; + + return _SUCCESS; +} + +void rtw_ft_build_auth_req_ies(_adapter *padapter, + struct pkt_attrib *pattrib, u8 **pframe) +{ + u8 ftie_append = _TRUE; + + if (!pattrib || !(*pframe)) + return; + + if (!rtw_ft_roam(padapter)) + return; + + ftie_append = rtw_ft_update_rsnie(padapter, _TRUE, pattrib, pframe); + rtw_ft_update_mdie(padapter, pattrib, pframe); + if (ftie_append) + rtw_ft_update_ftie(padapter, pattrib, pframe); +} + +void rtw_ft_build_assoc_req_ies(_adapter *padapter, + u8 is_reassoc, struct pkt_attrib *pattrib, u8 **pframe) +{ + if (!pattrib || !(*pframe)) + return; + + if (rtw_ft_chk_flags(padapter, RTW_FT_PEER_EN)) + rtw_ft_update_mdie(padapter, pattrib, pframe); + + if ((!is_reassoc) || (!rtw_ft_roam(padapter))) + return; + + if (rtw_ft_update_rsnie(padapter, _FALSE, pattrib, pframe)) + rtw_ft_update_ftie(padapter, pattrib, pframe); +} + +u8 rtw_ft_update_auth_rsp_ies(_adapter *padapter, u8 *pframe, u32 len) +{ + u8 ret = _SUCCESS; + u8 target_ap_addr[ETH_ALEN] = {0}; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); + + if (!rtw_ft_roam(padapter)) + return _FAIL; + + /*rtw_ft_report_reassoc_evt already, + * and waiting for cfg80211_rtw_update_ft_ies */ + if (rtw_ft_authed_sta(padapter)) + return ret; + + if (!pframe || !len) + return _FAIL; + + rtw_buf_update(&pmlmepriv->auth_rsp, + &pmlmepriv->auth_rsp_len, pframe, len); + pft_roam->ft_event.ies = + (pmlmepriv->auth_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6); + pft_roam->ft_event.ies_len = + (pmlmepriv->auth_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6); + + /*Not support RIC*/ + pft_roam->ft_event.ric_ies = NULL; + pft_roam->ft_event.ric_ies_len = 0; + _rtw_memcpy(target_ap_addr, pmlmepriv->assoc_bssid, ETH_ALEN); + rtw_ft_report_reassoc_evt(padapter, target_ap_addr); + + return ret; +} + +static void rtw_ft_start_clnt_action(_adapter *padapter, u8 *pTargetAddr) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + rtw_ft_set_status(padapter, RTW_FT_REQUESTING_STA); + rtw_ft_issue_action_req(padapter, pTargetAddr); + _set_timer(&pmlmeext->ft_link_timer, REASSOC_TO); +} + +void rtw_ft_start_roam(_adapter *padapter, u8 *pTargetAddr) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + if (rtw_ft_otd_roam(padapter)) { + RTW_FT_INFO("%s : try OTD roaming\n", __func__); + rtw_ft_start_clnt_action(padapter, pTargetAddr); + } else { + /*wait a little time to retrieve packets buffered in the current ap while scan*/ + RTW_FT_INFO("%s : start roaming timer\n", __func__); + _set_timer(&pmlmeext->ft_roam_timer, 30); + } +} + +void rtw_ft_issue_action_req(_adapter *padapter, u8 *pTargetAddr) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct xmit_frame *pmgntframe; + struct rtw_ieee80211_hdr *pwlanhdr; + struct pkt_attrib *pattrib; + u8 *pframe; + u8 category = RTW_WLAN_CATEGORY_FT; + u8 action = RTW_WLAN_ACTION_FT_REQ; + + pmgntframe = alloc_mgtxmitframe(pxmitpriv); + if (pmgntframe == NULL) + return; + + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + pwlanhdr->frame_ctl = 0; + + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + set_frame_sub_type(pframe, WIFI_ACTION); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); + + _rtw_memcpy(pframe, adapter_mac_addr(padapter), ETH_ALEN); + pframe += ETH_ALEN; + pattrib->pktlen += ETH_ALEN; + + _rtw_memcpy(pframe, pTargetAddr, ETH_ALEN); + pframe += ETH_ALEN; + pattrib->pktlen += ETH_ALEN; + + rtw_ft_update_mdie(padapter, pattrib, &pframe); + if (rtw_ft_update_rsnie(padapter, _TRUE, pattrib, &pframe)) + rtw_ft_update_ftie(padapter, pattrib, &pframe); + + RTW_INFO("FT : issue RTW_WLAN_ACTION_FT_REQ\n"); + pattrib->last_txcmdsz = pattrib->pktlen; + dump_mgntframe(padapter, pmgntframe); +} + +void rtw_ft_report_evt(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&(pmlmeinfo->network); + struct cfg80211_ft_event_params ft_evt_parms; + _irqL irqL; + + _rtw_memset(&ft_evt_parms, 0, sizeof(ft_evt_parms)); + rtw_ft_update_stainfo(padapter, pnetwork); + + if (!pnetwork) + goto err_2; + + ft_evt_parms.ies_len = pft_roam->ft_event.ies_len; + ft_evt_parms.ies = rtw_zmalloc(ft_evt_parms.ies_len); + if (ft_evt_parms.ies) + _rtw_memcpy((void *)ft_evt_parms.ies, pft_roam->ft_event.ies, ft_evt_parms.ies_len); + else + goto err_2; + + ft_evt_parms.target_ap = rtw_zmalloc(ETH_ALEN); + if (ft_evt_parms.target_ap) + _rtw_memcpy((void *)ft_evt_parms.target_ap, pnetwork->MacAddress, ETH_ALEN); + else + goto err_1; + + ft_evt_parms.ric_ies = pft_roam->ft_event.ric_ies; + ft_evt_parms.ric_ies_len = pft_roam->ft_event.ric_ies_len; + + /* It's a KERNEL issue between v4.11 ~ v4.16, + * <= v4.10, NLMSG_DEFAULT_SIZE is used for nlmsg_new(). + * v4.11 ~ v4.16, only used "100 + >ric_ies_len" for nlmsg_new() + * even then DRIVER don't support RIC. + * >= v4.17, issue should correct as "100 + ies_len + ric_ies_len". + */ + #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0))) + ft_evt_parms.ric_ies_len = (ft_evt_parms.ies_len <= 100 )? + (0):(ft_evt_parms.ies_len - 100); + #endif + + rtw_ft_lock_set_status(padapter, RTW_FT_AUTHENTICATED_STA, &irqL); + rtw_cfg80211_ft_event(padapter, &ft_evt_parms); + RTW_INFO("FT: rtw_ft_report_evt\n"); + rtw_mfree((u8 *)pft_roam->ft_event.target_ap, ETH_ALEN); +err_1: + rtw_mfree((u8 *)ft_evt_parms.ies, ft_evt_parms.ies_len); +err_2: + return; +} + +void rtw_ft_report_reassoc_evt(_adapter *padapter, u8 *pMacAddr) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); + struct cmd_obj *pcmd_obj = NULL; + struct stassoc_event *passoc_sta_evt = NULL; + struct rtw_evt_header *evt_hdr = NULL; + u8 *pevtcmd = NULL; + u32 cmdsz = 0; + + pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (pcmd_obj == NULL) + return; + + cmdsz = (sizeof(struct stassoc_event) + sizeof(struct rtw_evt_header)); + pevtcmd = (u8 *)rtw_zmalloc(cmdsz); + if (pevtcmd == NULL) { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + return; + } + + _rtw_init_listhead(&pcmd_obj->list); + pcmd_obj->cmdcode = CMD_SET_MLME_EVT; + pcmd_obj->cmdsz = cmdsz; + pcmd_obj->parmbuf = pevtcmd; + pcmd_obj->rsp = NULL; + pcmd_obj->rspsz = 0; + + evt_hdr = (struct rtw_evt_header *)(pevtcmd); + evt_hdr->len = sizeof(struct stassoc_event); + evt_hdr->id = EVT_FT_REASSOC; + evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + + passoc_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct rtw_evt_header)); + _rtw_memcpy((unsigned char *)(&(passoc_sta_evt->macaddr)), pMacAddr, ETH_ALEN); + rtw_enqueue_cmd(pcmdpriv, pcmd_obj); +} + +void rtw_ft_link_timer_hdl(void *ctx) +{ + _adapter *padapter = (_adapter *)ctx; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); + + if (rtw_ft_chk_status(padapter, RTW_FT_REQUESTING_STA)) { + if (pft_roam->ft_req_retry_cnt < RTW_FT_ACTION_REQ_LMT) { + pft_roam->ft_req_retry_cnt++; + rtw_ft_issue_action_req(padapter, (u8 *)pmlmepriv->roam_network->network.MacAddress); + _set_timer(&pmlmeext->ft_link_timer, REASSOC_TO); + } else { + pft_roam->ft_req_retry_cnt = 0; + if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) + rtw_ft_set_status(padapter, RTW_FT_ASSOCIATED_STA); + else + rtw_ft_reset_status(padapter); + } + } +} + +void rtw_ft_roam_timer_hdl(void *ctx) +{ + _adapter *padapter = (_adapter *)ctx; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + RTW_FT_INFO("%s : try roaming\n", __func__); + receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress + , WLAN_REASON_ACTIVE_ROAM, _FALSE); +} + +void rtw_ft_roam_status_reset(_adapter *padapter) +{ + struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); + + if ((rtw_to_roam(padapter) > 0) && + (!rtw_ft_chk_status(padapter, RTW_FT_REQUESTED_STA))) { + rtw_ft_reset_status(padapter); + } + + padapter->mlmepriv.ft_roam.ft_updated_bcn = _FALSE; +} + +#endif /* CONFIG_RTW_80211R */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ieee80211.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ieee80211.c index 72274bd246ef..b7b1a4ad199b 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ieee80211.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ieee80211.c @@ -85,6 +85,20 @@ u8 WIFI_OFDMRATES[] = { IEEE80211_OFDM_RATE_54MB }; +const char *MGN_RATE_STR(enum MGN_RATE rate) +{ + u8 hw_rate; + + if (rate == MGN_MCS32) + return "MCS32"; + + hw_rate = MRateToHwRate(rate); + if (hw_rate == DESC_RATE1M && rate != MGN_1M) + hw_rate = DESC_RATE_NUM; /* invalid case */ + + return HDATA_RATE(hw_rate); +} + u8 mgn_rates_cck[4] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M}; u8 mgn_rates_ofdm[8] = {MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M}; u8 mgn_rates_mcs0_7[8] = {MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7}; @@ -524,17 +538,24 @@ u8 rtw_update_rate_bymode(WLAN_BSSID_EX *pbss_network, u32 mode) pbss_network->IELength -= ie_len; } network_type = WIRELESS_11B; - } else if ((mode & WIRELESS_11B) == 0) { - /* Remove CCK in support_rate IE */ - rtw_filter_suppport_rateie(pbss_network, OFDM); - if (pbss_network->Configuration.DSConfig > 14) + } else { + if (pbss_network->Configuration.DSConfig > 14) { + /* Remove CCK in support_rate IE */ + rtw_filter_suppport_rateie(pbss_network, OFDM); network_type = WIRELESS_11A; - else - network_type = WIRELESS_11G; - } else - network_type = WIRELESS_11BG; /* do nothing */ + } else { + if ((mode & WIRELESS_11B) == 0) { + /* Remove CCK in support_rate IE */ + rtw_filter_suppport_rateie(pbss_network, OFDM); + network_type = WIRELESS_11G; + } else { + network_type = WIRELESS_11BG; + } + } + } rtw_set_supported_rate(pbss_network->SupportedRates, network_type); + return network_type; } @@ -855,6 +876,7 @@ int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int rtw_rsne_info_parse(const u8 *ie, uint ie_len, struct rsne_info *info) { const u8 *pos = ie; + u16 ver; u16 cnt; _rtw_memset(info, 0, sizeof(struct rsne_info)); @@ -864,7 +886,13 @@ int rtw_rsne_info_parse(const u8 *ie, uint ie_len, struct rsne_info *info) if (*ie != WLAN_EID_RSN || *(ie + 1) != ie_len - 2) goto err; - pos += 2 + 2; + pos += 2; + + /* Version */ + ver = RTW_GET_LE16(pos); + if(1 != ver) + goto err; + pos += 2; /* Group CS */ if (ie + ie_len < pos + 4) { @@ -926,11 +954,8 @@ int rtw_rsne_info_parse(const u8 *ie, uint ie_len, struct rsne_info *info) } cnt = RTW_GET_LE16(pos); pos += 2; - if (ie + ie_len < pos + 16 * cnt) { - if (ie + ie_len != pos) - goto err; - goto exit; - } + if (ie + ie_len < pos + 16 * cnt) + goto err; info->pmkid_cnt = cnt; info->pmkid_list = (u8 *)pos; pos += 16 * cnt; @@ -970,8 +995,10 @@ int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, if (pairwise_cipher) { *pairwise_cipher = 0; - for (i = 0; i < info.pcs_cnt; i++) - *pairwise_cipher |= rtw_get_rsn_cipher_suite(info.pcs_list + 4 * i); + if (info.pcs_list) { + for (i = 0; i < info.pcs_cnt; i++) + *pairwise_cipher |= rtw_get_rsn_cipher_suite(info.pcs_list + 4 * i); + } } if (gmcs) { @@ -983,8 +1010,10 @@ int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, if (akm) { *akm = 0; - for (i = 0; i < info.akm_cnt; i++) - *akm |= rtw_get_akm_suite_bitmap(info.akm_list + 4 * i); + if (info.akm_list) { + for (i = 0; i < info.akm_cnt; i++) + *akm |= rtw_get_akm_suite_bitmap(info.akm_list + 4 * i); + } } if (mfp_opt) { @@ -1774,6 +1803,7 @@ err_chk: RTW_INFO("%s mac addr:"MAC_FMT"\n", __func__, MAC_ARG(out)); } +#ifdef CONFIG_RTW_DEBUG #ifdef CONFIG_80211N_HT void dump_ht_cap_ie_content(void *sel, const u8 *buf, u32 buf_len) { @@ -1836,36 +1866,6 @@ void dump_ht_op_ie(void *sel, const u8 *ie, u32 ie_len) } #endif /* CONFIG_80211N_HT */ -void dump_ies(void *sel, const u8 *buf, u32 buf_len) -{ - const u8 *pos = buf; - u8 id, len; - - while (pos - buf + 1 < buf_len) { - id = *pos; - len = *(pos + 1); - - RTW_PRINT_SEL(sel, "%s ID:%u, LEN:%u\n", __FUNCTION__, id, len); -#ifdef CONFIG_80211N_HT - dump_ht_cap_ie(sel, pos, len + 2); - dump_ht_op_ie(sel, pos, len + 2); -#endif -#ifdef CONFIG_80211AC_VHT - dump_vht_cap_ie(sel, pos, len + 2); - dump_vht_op_ie(sel, pos, len + 2); -#endif - dump_wps_ie(sel, pos, len + 2); -#ifdef CONFIG_P2P - dump_p2p_ie(sel, pos, len + 2); -#ifdef CONFIG_WFD - dump_wfd_ie(sel, pos, len + 2); -#endif -#endif - - pos += (2 + len); - } -} - void dump_wps_ie(void *sel, const u8 *ie, u32 ie_len) { const u8 *pos = ie; @@ -1890,6 +1890,41 @@ void dump_wps_ie(void *sel, const u8 *ie, u32 ie_len) pos += (4 + len); } } +#endif /* CONFIG_RTW_DEBUG */ +void dump_ies(void *sel, const u8 *buf, u32 buf_len) +{ +#ifdef CONFIG_RTW_DEBUG + const u8 *pos = buf; + u8 id, len; + + while (pos - buf + 1 < buf_len) { + id = *pos; + len = *(pos + 1); + + RTW_PRINT_SEL(sel, "%s ID:%u, LEN:%u\n", __FUNCTION__, id, len); +#ifdef CONFIG_80211N_HT + dump_ht_cap_ie(sel, pos, len + 2); + dump_ht_op_ie(sel, pos, len + 2); +#endif +#ifdef CONFIG_80211AC_VHT + dump_vht_cap_ie(sel, pos, len + 2); + dump_vht_op_ie(sel, pos, len + 2); +#endif + dump_wps_ie(sel, pos, len + 2); +#ifdef CONFIG_P2P + dump_p2p_ie(sel, pos, len + 2); +#ifdef CONFIG_WFD + dump_wfd_ie(sel, pos, len + 2); +#endif +#endif +#ifdef CONFIG_RTW_MULTI_AP + dump_multi_ap_ie(sel, pos, len + 2); +#endif + + pos += (2 + len); + } +#endif /* CONFIG_RTW_DEBUG */ +} /** * rtw_ies_get_chbw - get operation ch, bw, offset from IEs of BSS. @@ -2071,6 +2106,7 @@ void rtw_sync_chbw(u8 *req_ch, u8 *req_bw, u8 *req_offset } } +#ifdef CONFIG_P2P /** * rtw_get_p2p_merged_len - Get merged ie length from muitiple p2p ies. * @in_ie: Pointer of the first p2p ie @@ -2480,31 +2516,7 @@ void rtw_bss_ex_del_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id) break; } } - -void dump_wfd_ie(void *sel, const u8 *ie, u32 ie_len) -{ - const u8 *pos = ie; - u8 id; - u16 len; - - const u8 *wfd_ie; - uint wfd_ielen; - - wfd_ie = rtw_get_wfd_ie(ie, ie_len, NULL, &wfd_ielen); - if (wfd_ie != ie || wfd_ielen == 0) - return; - - pos += 6; - while (pos - ie + 3 <= ie_len) { - id = *pos; - len = RTW_GET_BE16(pos + 1); - - RTW_PRINT_SEL(sel, "%s ID:%u, LEN:%u%s\n", __func__, id, len - , ((pos - ie + 3 + len) <= ie_len) ? "" : "(exceed ie_len)"); - - pos += (3 + len); - } -} +#endif /* CONFIG_P2P */ /** * rtw_get_wfd_ie - Search WFD IE from a series of IEs @@ -2560,6 +2572,84 @@ u8 *rtw_get_wfd_ie(const u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen) return (u8 *)wfd_ie_ptr; } +uint rtw_del_wfd_ie(u8 *ies, uint ies_len_ori, const char *msg) +{ +#define DBG_DEL_WFD_IE 0 + + u8 *target_ie; + u32 target_ie_len; + uint ies_len = ies_len_ori; + int index = 0; + + while (1) { + target_ie = rtw_get_wfd_ie(ies, ies_len, NULL, &target_ie_len); + if (target_ie && target_ie_len) { + u8 *next_ie = target_ie + target_ie_len; + uint remain_len = ies_len - (next_ie - ies); + + if (DBG_DEL_WFD_IE && msg) { + RTW_INFO("%s %d before\n", __func__, index); + dump_ies(RTW_DBGDUMP, ies, ies_len); + + RTW_INFO("ies:%p, ies_len:%u\n", ies, ies_len); + RTW_INFO("target_ie:%p, target_ie_len:%u\n", target_ie, target_ie_len); + RTW_INFO("next_ie:%p, remain_len:%u\n", next_ie, remain_len); + } + + _rtw_memmove(target_ie, next_ie, remain_len); + _rtw_memset(target_ie + remain_len, 0, target_ie_len); + ies_len -= target_ie_len; + + if (DBG_DEL_WFD_IE && msg) { + RTW_INFO("%s %d after\n", __func__, index); + dump_ies(RTW_DBGDUMP, ies, ies_len); + } + + index++; + } else + break; + } + + return ies_len; +} + +void rtw_bss_ex_del_wfd_ie(WLAN_BSSID_EX *bss_ex) +{ +#define DBG_BSS_EX_DEL_WFD_IE 0 + u8 *ies = BSS_EX_TLV_IES(bss_ex); + uint ies_len_ori = BSS_EX_TLV_IES_LEN(bss_ex); + uint ies_len; + + ies_len = rtw_del_wfd_ie(ies, ies_len_ori, DBG_BSS_EX_DEL_WFD_IE ? __func__ : NULL); + bss_ex->IELength -= ies_len_ori - ies_len; +} + +#ifdef CONFIG_WFD +void dump_wfd_ie(void *sel, const u8 *ie, u32 ie_len) +{ + const u8 *pos = ie; + u8 id; + u16 len; + + const u8 *wfd_ie; + uint wfd_ielen; + + wfd_ie = rtw_get_wfd_ie(ie, ie_len, NULL, &wfd_ielen); + if (wfd_ie != ie || wfd_ielen == 0) + return; + + pos += 6; + while (pos - ie + 3 <= ie_len) { + id = *pos; + len = RTW_GET_BE16(pos + 1); + + RTW_PRINT_SEL(sel, "%s ID:%u, LEN:%u%s\n", __func__, id, len + , ((pos - ie + 3 + len) <= ie_len) ? "" : "(exceed ie_len)"); + + pos += (3 + len); + } +} + /** * rtw_get_wfd_attr - Search a specific WFD attribute from a given WFD IE * @wfd_ie: Address of WFD IE to search @@ -2650,47 +2740,6 @@ u8 *rtw_get_wfd_attr_content(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id, u8 * return NULL; } -uint rtw_del_wfd_ie(u8 *ies, uint ies_len_ori, const char *msg) -{ -#define DBG_DEL_WFD_IE 0 - - u8 *target_ie; - u32 target_ie_len; - uint ies_len = ies_len_ori; - int index = 0; - - while (1) { - target_ie = rtw_get_wfd_ie(ies, ies_len, NULL, &target_ie_len); - if (target_ie && target_ie_len) { - u8 *next_ie = target_ie + target_ie_len; - uint remain_len = ies_len - (next_ie - ies); - - if (DBG_DEL_WFD_IE && msg) { - RTW_INFO("%s %d before\n", __func__, index); - dump_ies(RTW_DBGDUMP, ies, ies_len); - - RTW_INFO("ies:%p, ies_len:%u\n", ies, ies_len); - RTW_INFO("target_ie:%p, target_ie_len:%u\n", target_ie, target_ie_len); - RTW_INFO("next_ie:%p, remain_len:%u\n", next_ie, remain_len); - } - - _rtw_memmove(target_ie, next_ie, remain_len); - _rtw_memset(target_ie + remain_len, 0, target_ie_len); - ies_len -= target_ie_len; - - if (DBG_DEL_WFD_IE && msg) { - RTW_INFO("%s %d after\n", __func__, index); - dump_ies(RTW_DBGDUMP, ies, ies_len); - } - - index++; - } else - break; - } - - return ies_len; -} - uint rtw_del_wfd_attr(u8 *ie, uint ielen_ori, u8 attr_id) { #define DBG_DEL_WFD_ATTR 0 @@ -2738,17 +2787,6 @@ inline u8 *rtw_bss_ex_get_wfd_ie(WLAN_BSSID_EX *bss_ex, u8 *wfd_ie, uint *wfd_ie return rtw_get_wfd_ie(BSS_EX_TLV_IES(bss_ex), BSS_EX_TLV_IES_LEN(bss_ex), wfd_ie, wfd_ielen); } -void rtw_bss_ex_del_wfd_ie(WLAN_BSSID_EX *bss_ex) -{ -#define DBG_BSS_EX_DEL_WFD_IE 0 - u8 *ies = BSS_EX_TLV_IES(bss_ex); - uint ies_len_ori = BSS_EX_TLV_IES_LEN(bss_ex); - uint ies_len; - - ies_len = rtw_del_wfd_ie(ies, ies_len_ori, DBG_BSS_EX_DEL_WFD_IE ? __func__ : NULL); - bss_ex->IELength -= ies_len_ori - ies_len; -} - void rtw_bss_ex_del_wfd_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id) { #define DBG_BSS_EX_DEL_WFD_ATTR 0 @@ -2806,6 +2844,79 @@ void rtw_bss_ex_del_wfd_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id) break; } } +#endif /* CONFIG_WFD */ + +#ifdef CONFIG_RTW_MULTI_AP +void dump_multi_ap_ie(void *sel, const u8 *ie, u32 ie_len) +{ + const u8 *pos = ie; + u8 id; + u8 len; + + const u8 *multi_ap_ie; + uint multi_ap_ielen; + + multi_ap_ie = rtw_get_ie_ex(ie, ie_len, WLAN_EID_VENDOR_SPECIFIC, MULTI_AP_OUI, 4, NULL, &multi_ap_ielen); + if (multi_ap_ie != ie || multi_ap_ielen == 0) + return; + + pos += 6; + while (pos - ie + 2 <= ie_len) { + id = *pos; + len = *(pos + 1); + + RTW_PRINT_SEL(sel, "%s ID:%u, LEN:%u%s\n", __func__, id, len + , ((pos - ie + 2 + len) <= ie_len) ? "" : "(exceed ie_len)"); + RTW_DUMP_SEL(sel, pos + 2, len); + + pos += (2 + len); + } +} + +/** + * rtw_get_multi_ap_ext - Search Multi-AP IE from a series of IEs and return extension subelement value + * @ies: Address of IEs to search + * @ies_len: Length limit from in_ie + * + * Returns: The address of the target IE found, or NULL + */ +u8 rtw_get_multi_ap_ie_ext(const u8 *ies, int ies_len) +{ + u8 *ie; + uint ielen; + u8 val = 0; + + ie = rtw_get_ie_ex(ies, ies_len, WLAN_EID_VENDOR_SPECIFIC, MULTI_AP_OUI, 4, NULL, &ielen); + if (ielen < 9) + goto exit; + + if (ie[6] != MULTI_AP_SUB_ELEM_TYPE) + goto exit; + + val = ie[8]; + +exit: + return val; +} + +u8 *rtw_set_multi_ap_ie_ext(u8 *pbuf, uint *frlen, u8 val) +{ + u8 cont_len = 7; + + *pbuf++ = WLAN_EID_VENDOR_SPECIFIC; + *pbuf++ = cont_len; + _rtw_memcpy(pbuf, MULTI_AP_OUI, 4); + pbuf += 4; + *pbuf++ = MULTI_AP_SUB_ELEM_TYPE; + *pbuf++ = 1; /* len */ + *pbuf++ = val; + + if (frlen) + *frlen = *frlen + (cont_len + 2); + + return pbuf; +} +#endif /* CONFIG_RTW_MULTI_AP */ /* Baron adds to avoid FreeBSD warning */ int ieee80211_is_empty_essid(const char *essid, int essid_len) @@ -2961,6 +3072,23 @@ u16 rtw_ht_mcs_rate(u8 bw_40MHz, u8 short_GI, unsigned char *MCS_rate) return max_rate; } +u8 rtw_ht_cap_get_rx_nss(u8 *ht_cap) +{ + u8 *ht_mcs_set = HT_CAP_ELE_SUP_MCS_SET(ht_cap); + + return rtw_ht_mcsset_to_nss(ht_mcs_set); +} + +u8 rtw_ht_cap_get_tx_nss(u8 *ht_cap) +{ + u8 *ht_mcs_set = HT_CAP_ELE_SUP_MCS_SET(ht_cap); + + if (GET_HT_CAP_ELE_TX_MCS_DEF(ht_cap) && GET_HT_CAP_ELE_TRX_MCS_NEQ(ht_cap)) + return GET_HT_CAP_ELE_TX_MAX_SS(ht_cap) + 1; + + return rtw_ht_cap_get_rx_nss(ht_cap); +} + int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, u8 *action) { const u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr); @@ -2993,23 +3121,41 @@ int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, u8 *act } static const char *_action_public_str[] = { - "ACT_PUB_BSSCOEXIST", - "ACT_PUB_DSE_ENABLE", - "ACT_PUB_DSE_DEENABLE", - "ACT_PUB_DSE_REG_LOCATION", - "ACT_PUB_EXT_CHL_SWITCH", - "ACT_PUB_DSE_MSR_REQ", - "ACT_PUB_DSE_MSR_RPRT", - "ACT_PUB_MP", - "ACT_PUB_DSE_PWR_CONSTRAINT", - "ACT_PUB_VENDOR", - "ACT_PUB_GAS_INITIAL_REQ", - "ACT_PUB_GAS_INITIAL_RSP", - "ACT_PUB_GAS_COMEBACK_REQ", - "ACT_PUB_GAS_COMEBACK_RSP", - "ACT_PUB_TDLS_DISCOVERY_RSP", - "ACT_PUB_LOCATION_TRACK", - "ACT_PUB_RSVD", + [ACT_PUBLIC_BSSCOEXIST] = "ACT_PUB_BSSCOEXIST", + [ACT_PUBLIC_DSE_ENABLE] = "ACT_PUB_DSE_ENABLE", + [ACT_PUBLIC_DSE_DEENABLE] = "ACT_PUB_DSE_DEENABLE", + [ACT_PUBLIC_DSE_REG_LOCATION] = "ACT_PUB_DSE_REG_LOCATION", + [ACT_PUBLIC_EXT_CHL_SWITCH] = "ACT_PUB_EXT_CHL_SWITCH", + [ACT_PUBLIC_DSE_MSR_REQ] = "ACT_PUB_DSE_MSR_REQ", + [ACT_PUBLIC_DSE_MSR_RPRT] = "ACT_PUB_DSE_MSR_RPRT", + [ACT_PUBLIC_MP] = "ACT_PUB_MP", + [ACT_PUBLIC_DSE_PWR_CONSTRAINT] = "ACT_PUB_DSE_PWR_CONSTRAINT", + [ACT_PUBLIC_VENDOR] = "ACT_PUB_VENDOR", + [ACT_PUBLIC_GAS_INITIAL_REQ] = "ACT_PUB_GAS_INITIAL_REQ", + [ACT_PUBLIC_GAS_INITIAL_RSP] = "ACT_PUB_GAS_INITIAL_RSP", + [ACT_PUBLIC_GAS_COMEBACK_REQ] = "ACT_PUB_GAS_COMEBACK_REQ", + [ACT_PUBLIC_GAS_COMEBACK_RSP] = "ACT_PUB_GAS_COMEBACK_RSP", + [ACT_PUBLIC_TDLS_DISCOVERY_RSP] = "ACT_PUB_TDLS_DISCOVERY_RSP", + [ACT_PUBLIC_LOCATION_TRACK] = "ACT_PUB_LOCATION_TRACK", + [ACT_PUBLIC_QAB_REQ] = "ACT_PUB_QAB_REQ", + [ACT_PUBLIC_QAB_RSP] = "ACT_PUB_QAB_RSP", + [ACT_PUBLIC_QMF_POLICY] = "ACT_PUB_QMF_POLICY", + [ACT_PUBLIC_QMF_POLICY_CHANGE] = "ACT_PUB_QMF_POLICY_CHANGE", + [ACT_PUBLIC_QLOAD_REQ] = "ACT_PUB_QLOAD_REQ", + [ACT_PUBLIC_QLOAD_REPORT] = "ACT_PUB_QLOAD_REPORT", + [ACT_PUBLIC_HCCA_TXOP_ADV] = "ACT_PUB_HCCA_TXOP_ADV", + [ACT_PUBLIC_HCCA_TXOP_RSP] = "ACT_PUB_HCCA_TXOP_RSP", + [ACT_PUBLIC_PUBLIC_KEY] = "ACT_PUB_PUBLIC_KEY", + [ACT_PUBLIC_CH_AVAILABILITY_QUERY] = "ACT_PUB_CH_AVAILABILITY_QUERY", + [ACT_PUBLIC_CH_SCHEDULE_MGMT] = "ACT_PUB_CH_SCHEDULE_MGMT", + [ACT_PUBLIC_CONTACT_VERI_SIGNAL] = "ACT_PUB_CONTACT_VERI_SIGNAL", + [ACT_PUBLIC_GDD_ENABLE_REQ] = "ACT_PUB_GDD_ENABLE_REQ", + [ACT_PUBLIC_GDD_ENABLE_RSP] = "ACT_PUB_GDD_ENABLE_RSP", + [ACT_PUBLIC_NETWORK_CH_CONTROL] = "ACT_PUB_NETWORK_CH_CONTROL", + [ACT_PUBLIC_WHITE_SPACE_MAP_ANN] = "ACT_PUB_WHITE_SPACE_MAP_ANN", + [ACT_PUBLIC_FTM_REQ] = "ACT_PUB_FTM_REQ", + [ACT_PUBLIC_FTM] = "ACT_PUB_FTM", + [ACT_PUBLIC_MAX] = "ACT_PUB_RSVD", }; const char *action_public_str(u8 action) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ioctl_set.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ioctl_set.c index 9db67278164e..7c005d4a6914 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ioctl_set.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_ioctl_set.c @@ -142,6 +142,7 @@ u8 rtw_do_join(_adapter *padapter) _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); } else { if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) { + #ifdef CONFIG_AP_MODE /* submit createbss_cmd to change to a ADHOC_MASTER */ /* pmlmepriv->lock has been acquired by caller... */ @@ -165,8 +166,7 @@ u8 rtw_do_join(_adapter *padapter) } pmlmepriv->to_join = _FALSE; - - + #endif /* CONFIG_AP_MODE */ } else { /* can't associate ; reset under-linking */ _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING); @@ -883,8 +883,12 @@ int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode) */ int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan) { - /* handle by cmd_thread to sync with scan operation */ - return rtw_set_chplan_cmd(adapter, RTW_CMDF_WAIT_ACK, channel_plan, 1); + struct registry_priv *regsty = adapter_to_regsty(adapter); + + if (!REGSTY_REGD_SRC_FROM_OS(regsty)) + return rtw_set_chplan_cmd(adapter, RTW_CMDF_WAIT_ACK, channel_plan, 1); + RTW_WARN("%s(): not applied\n", __func__); + return _SUCCESS; } /* @@ -897,11 +901,13 @@ int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan) int rtw_set_country(_adapter *adapter, const char *country_code) { #ifdef CONFIG_RTW_IOCTL_SET_COUNTRY - return rtw_set_country_cmd(adapter, RTW_CMDF_WAIT_ACK, country_code, 1); -#else - RTW_INFO("%s(): not applied\n", __func__); - return _SUCCESS; + struct registry_priv *regsty = adapter_to_regsty(adapter); + + if (!REGSTY_REGD_SRC_FROM_OS(regsty)) + return rtw_set_country_cmd(adapter, RTW_CMDF_WAIT_ACK, country_code, 1); #endif + RTW_WARN("%s(): not applied\n", __func__); + return _SUCCESS; } /* diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_iol.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_iol.c index 07c419f15571..cca65454f659 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_iol.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_iol.c @@ -25,7 +25,7 @@ struct xmit_frame *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter) struct xmit_priv *pxmitpriv = &(adapter->xmitpriv); #if 1 - xmit_frame = rtw_alloc_xmitframe(pxmitpriv); + xmit_frame = rtw_alloc_xmitframe(pxmitpriv, 0); if (xmit_frame == NULL) { RTW_INFO("%s rtw_alloc_xmitframe return null\n", __FUNCTION__); goto exit; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mbo.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mbo.c new file mode 100644 index 000000000000..3f195d81d174 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mbo.c @@ -0,0 +1,804 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#include +#include + +#ifdef CONFIG_RTW_MBO + +#ifndef RTW_MBO_DBG +#define RTW_MBO_DBG 0 +#endif +#if RTW_MBO_DBG + #define RTW_MBO_INFO(fmt, arg...) \ + RTW_INFO(fmt, arg) + #define RTW_MBO_DUMP(str, data, len) \ + RTW_INFO_DUMP(str, data, len) +#else + #define RTW_MBO_INFO(fmt, arg...) do {} while (0) + #define RTW_MBO_DUMP(str, data, len) do {} while (0) +#endif + +/* Cellular Data Connectivity field + * 1 : Cellular data connection available + * 2 : Cellular data connection not available + * 3 : Not Cellular data capable + * otherwise : Reserved +*/ +int rtw_mbo_cell_data_conn = 2; +module_param(rtw_mbo_cell_data_conn, int, 0644); + +static u8 wfa_mbo_oui[] = {0x50, 0x6F, 0x9A, 0x16}; + +#define rtw_mbo_get_oui(p) ((u8 *)(p) + 2) + +#define rtw_mbo_get_attr_id(p) ((u8 *)(p)) + +#define rtw_mbo_get_disallow_res(p) ((u8 *)(p) + 3) + +#define rtw_mbo_set_1byte_ie(p, v, l) \ + rtw_set_fixed_ie((p), 1, (v), (l)) + +#define rtw_mbo_set_4byte_ie(p, v, l) \ + rtw_set_fixed_ie((p), 4, (v), (l)) + +#define rtw_mbo_set_nbyte_ie(p, sz, v, l) \ + rtw_set_fixed_ie((p), (sz), (v), (l)) + +#define rtw_mbo_subfield_set(p, offset, val) (*(p + offset) = val) + +#define rtw_mbo_subfields_set(p, offset, buf, len) \ + do { \ + u32 _offset = 0; \ + u8 *_p = p + offset; \ + while(_offset < len) { \ + *(_p + _offset) = *(buf + _offset); \ + _offset++; \ + } \ + } while(0) + +static u8 *rtw_mbo_ie_get(u8 *pie, u32 *plen, u32 limit) +{ + const u8 *p = pie; + u32 tmp, i; + + if (limit <= 1) + return NULL; + + i = 0; + *plen = 0; + while (1) { + if ((*p == _VENDOR_SPECIFIC_IE_) && + (_rtw_memcmp(rtw_mbo_get_oui(p), wfa_mbo_oui, 4))) { + *plen = *(p + 1); + RTW_MBO_DUMP("VENDOR_SPECIFIC_IE MBO: ", p, *(p + 1)); + return (u8 *)p; + } else { + tmp = *(p + 1); + p += (tmp + 2); + i += (tmp + 2); + } + + if (i >= limit) + break; + } + + return NULL; +} + +static u8 *rtw_mbo_attrs_get(u8 *pie, u32 limit, u8 attr_id, u32 *attr_len) +{ + u8 *p = NULL; + u32 offset, plen = 0; + + if ((pie == NULL) || (limit <= 1)) + goto exit; + + if ((p = rtw_mbo_ie_get(pie, &plen, limit)) == NULL) + goto exit; + + /* shift 2 + OUI size and move to attributes content */ + p = p + 2 + sizeof(wfa_mbo_oui); + plen = plen - 4; + RTW_MBO_DUMP("Attributes contents: ", p, plen); + + if ((p = rtw_get_ie(p, attr_id, attr_len, plen)) == NULL) + goto exit; + + RTW_MBO_INFO("%s : id=%u(len=%u)\n", __func__, attr_id, *attr_len); + RTW_MBO_DUMP("contents : ", p, *attr_len); + +exit: + return p; + +} + +static u32 rtw_mbo_attr_sz_get( + _adapter *padapter, u8 id) +{ + u32 len = 0; + + switch (id) { + case RTW_MBO_ATTR_NPREF_CH_RPT_ID: + { + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *prpt = &(prfctl->ch_rtp); + struct npref_ch* pch; + u32 i, attr_len, offset; + + for (i=0; i < prpt->nm_of_rpt; i++) { + pch = &prpt->ch_rpt[i]; + /*attr_len = ch list + op class + preference + reason */ + attr_len = pch->nm_of_ch + 3; + /* offset = id + len field + attr_len */ + offset = attr_len + 2; + len += offset; + } + } + break; + case RTW_MBO_ATTR_CELL_DATA_CAP_ID: + case RTW_MBO_ATTR_TRANS_REJ_ID: + len = 3; + break; + default: + break; + } + + return len; +} + +static void rtw_mbo_build_mbo_ie_hdr( + u8 **pframe, struct pkt_attrib *pattrib, u8 payload_len) +{ + u8 eid = RTW_MBO_EID; + u8 len = payload_len + 4; + + *pframe = rtw_mbo_set_1byte_ie(*pframe, &eid, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &len, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_4byte_ie(*pframe, wfa_mbo_oui, &(pattrib->pktlen)); +} + +void rtw_mbo_build_cell_data_cap_attr( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 attr_id = RTW_MBO_ATTR_CELL_DATA_CAP_ID; + u8 attr_len = 1; + u8 cell_data_con = rtw_mbo_cell_data_conn; + + /* used Cellular Data Capabilities from supplicant */ + if (!rtw_mbo_wifi_logo_test(padapter) && + pmlmepriv->pcell_data_cap_ie && pmlmepriv->cell_data_cap_len == 1) { + cell_data_con = *pmlmepriv->pcell_data_cap_ie; + RTW_MBO_INFO("%s : used Cellular Data Capabilities(%u) from supplicant!\n", + __func__, *pmlmepriv->pcell_data_cap_ie); + } + + *pframe = rtw_mbo_set_1byte_ie(*pframe, &attr_id, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &attr_len, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &cell_data_con, &(pattrib->pktlen)); +} + +static void rtw_mbo_update_cell_data_cap( + _adapter *padapter, u8 *pie, u32 ie_len) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 *mbo_attr; + u32 mbo_attrlen; + + if ((pie == NULL) || (ie_len == 0)) + return; + + mbo_attr = rtw_mbo_attrs_get(pie, ie_len, + RTW_MBO_ATTR_CELL_DATA_CAP_ID, &mbo_attrlen); + + if ((mbo_attr == NULL) || (mbo_attrlen == 0) ) { + RTW_INFO("MBO : Cellular Data Capabilities not found!\n"); + return; + } + + rtw_buf_update(&pmlmepriv->pcell_data_cap_ie, + &pmlmepriv->cell_data_cap_len, (mbo_attr + 2), mbo_attrlen); + RTW_MBO_DUMP("rtw_mbo_update_cell_data_cap : ", + pmlmepriv->pcell_data_cap_ie, pmlmepriv->cell_data_cap_len); +} + +void rtw_mbo_update_ie_data( + _adapter *padapter, u8 *pie, u32 ie_len) +{ + rtw_mbo_update_cell_data_cap(padapter, pie, ie_len); +} + +static u8 rtw_mbo_current_op_class_get(_adapter *padapter) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct p2p_channels *pch_list = &(prfctl->channel_list); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct p2p_reg_class *preg_class; + int class_idx, ch_idx; + u8 cur_op_class = 0; + + for(class_idx =0; class_idx < pch_list->reg_classes; class_idx++) { + preg_class = &pch_list->reg_class[class_idx]; + for (ch_idx = 0; ch_idx <= preg_class->channels; ch_idx++) { + if (pmlmeext->cur_channel == preg_class->channel[ch_idx]) { + cur_op_class = preg_class->reg_class; + RTW_MBO_INFO("%s : current ch : %d, op class : %d\n", + __func__, pmlmeext->cur_channel, cur_op_class); + break; + } + } + } + + return cur_op_class; +} + +static void rtw_mbo_supp_op_classes_get(_adapter *padapter, u8 *pclasses) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct p2p_channels *pch_list = &(prfctl->channel_list); + int class_idx; + + if (pclasses == NULL) + return; + + RTW_MBO_INFO("%s : support op class \n", __func__); + for(class_idx = 0; class_idx < pch_list->reg_classes; class_idx++) { + *(pclasses + class_idx) = pch_list->reg_class[class_idx].reg_class; + RTW_MBO_INFO("%u ,", *(pclasses + class_idx)); + } + + RTW_MBO_INFO("%s : \n", __func__); +} + +void rtw_mbo_build_supp_op_class_elem( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + u8 payload[32] = {0}; + u8 delimiter_130 = 130; /*0x82*/ + u8 reg_class_nm, len; + + if ((reg_class_nm = prfctl->channel_list.reg_classes) == 0) + return; + + payload[0] = rtw_mbo_current_op_class_get(padapter); + rtw_mbo_supp_op_classes_get(padapter, &payload[1]); + + /* IEEE 802.11 Std Current Operating Class Extension Sequence */ + payload[reg_class_nm + 1] = delimiter_130; + payload[reg_class_nm + 2] = 0x00; + + RTW_MBO_DUMP("op class :", payload, reg_class_nm); + + /* Current Operating Class field + Operating Class field + + OneHundredAndThirty Delimiter field */ + len = reg_class_nm + 3; + *pframe = rtw_set_ie(*pframe, EID_SupRegulatory, len , + payload, &(pattrib->pktlen)); +} + +static u8 rtw_mbo_construct_npref_ch_rpt_attr( + _adapter *padapter, u8 *pbuf, u32 buf_len, u32 *plen) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *prpt = &(prfctl->ch_rtp); + struct npref_ch* pch; + u32 attr_len, offset; + int i; + u8 *p = pbuf; + + if (prpt->nm_of_rpt == 0) { + *plen = 0; + return _FALSE; + } + + for (i=0; i < prpt->nm_of_rpt; i++) { + pch = &prpt->ch_rpt[i]; + /* attr_len = ch list + op class + preference + reason */ + attr_len = pch->nm_of_ch + 3; + /* offset = id + len field + attr_len */ + offset = attr_len + 2; + rtw_mbo_subfield_set(p, 0, RTW_MBO_ATTR_NPREF_CH_RPT_ID); + rtw_mbo_subfield_set(p, 1, attr_len); + rtw_mbo_subfield_set(p, 2, pch->op_class); + rtw_mbo_subfields_set(p, 3, pch->chs, pch->nm_of_ch); + rtw_mbo_subfield_set(p, (offset - 2), pch->preference); + rtw_mbo_subfield_set(p, (offset - 1), pch->reason); + p += offset; + *plen += offset; + + if (*plen >= buf_len) { + RTW_ERR("MBO : construct non-preferred channel report fail!\n"); + return _FALSE; + } + } + + return _TRUE; +} + +void rtw_mbo_build_npref_ch_rpt_attr( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *prpt = &(prfctl->ch_rtp); + u32 tmp_sz = 0, body_len = 0; + u8 *ptmp; + + tmp_sz = prpt->nm_of_rpt * sizeof(struct npref_ch); + ptmp = rtw_zmalloc(tmp_sz); + if (ptmp == NULL) + return; + + if (rtw_mbo_construct_npref_ch_rpt_attr(padapter, ptmp, tmp_sz, &body_len) == _FALSE) { + rtw_mfree(ptmp, tmp_sz); + return; + } + + RTW_MBO_DUMP("Non-preferred Channel Report :", ptmp, body_len); + *pframe = rtw_mbo_set_nbyte_ie(*pframe, body_len, ptmp, &(pattrib->pktlen)); + + rtw_mfree(ptmp, tmp_sz); +} + +void rtw_mbo_build_trans_reject_reason_attr( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib, u8 *pres) +{ + u8 attr_id = RTW_MBO_ATTR_TRANS_REJ_ID; + u8 attr_len = 1; + u32 len = 0; + + len = rtw_mbo_attr_sz_get(padapter, RTW_MBO_ATTR_TRANS_REJ_ID); + if ((len == 0) || (len > 3)) { + RTW_ERR("MBO : build Transition Rejection Reason attribute fail(len=%u)\n", len); + return; + } + + rtw_mbo_build_mbo_ie_hdr(pframe, pattrib, len); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &attr_id, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &attr_len, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, pres, &(pattrib->pktlen)); +} + +u8 rtw_mbo_disallowed_network(struct wlan_network *pnetwork) +{ + u8 *p, *attr_id, *res; + u32 attr_len = 0; + u8 disallow = _FALSE; + + if (pnetwork == NULL) + goto exit; + + p = rtw_mbo_attrs_get(pnetwork->network.IEs, + pnetwork->network.IELength, + RTW_MBO_ATTR_ASSOC_DISABLED_ID, + &attr_len); + + if (p == NULL) { + RTW_MBO_INFO("%s :Assoc Disallowed attribute not found!\n",__func__); + goto exit; + } + + RTW_MBO_DUMP("Association Disallowed attribute :",p , attr_len + 2); + RTW_INFO("MBO : block "MAC_FMT" assoc disallowed reason %d\n", + MAC_ARG(pnetwork->network.MacAddress), *(rtw_mbo_get_disallow_res(p))); + + disallow = _TRUE; +exit: + return disallow; +} + +void rtw_mbo_build_exented_cap( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib) +{ + u8 content[8] = { 0 }; + + rtw_wnm_set_ext_cap_btm(content, 1); + rtw_mbo_set_ext_cap_internw(content, 1); + *pframe = rtw_set_ie(*pframe, + EID_EXTCapability, + 8, + content, + &(pattrib->pktlen)); +} + +static void rtw_mbo_non_pref_chans_dump(struct npref_ch* pch) +{ + int i; + u8 buf[128] = {0}; + + for (i=0; i < pch->nm_of_ch; i++) + rtw_sprintf(buf, 128, "%s,%d", buf, pch->chs[i]); + + RTW_MBO_INFO("%s : op_class=%01x, ch=%s, preference=%d, reason=%d\n", + __func__, pch->op_class, buf, pch->preference, pch->reason); +} + +static u8 rtw_mbo_non_pref_chan_exist(struct npref_ch* pch, u8 ch) +{ + u32 i; + u8 found = _FALSE; + + for (i=0; i < pch->nm_of_ch; i++) { + if (pch->chs[i] == ch) { + found = _TRUE; + break; + } + } + + return found; +} + +static struct npref_ch* rtw_mbo_non_pref_chan_get( + _adapter *padapter, u8 op_class, u8 prefe, u8 res) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *prpt = &(prfctl->ch_rtp); + struct npref_ch* pch = NULL; + int i; + + if (prpt->nm_of_rpt == 0) + return pch; + + for (i=0; i < prpt->nm_of_rpt; i++) { + if ((prpt->ch_rpt[i].op_class == op_class) && + (prpt->ch_rpt[i].preference == prefe) && + (prpt->ch_rpt[i].reason == res)) { + pch = &prpt->ch_rpt[i]; + break; + } + } + + return pch; +} + +static void rtw_mbo_non_pref_chan_set( + struct npref_ch* pch, u8 op_class, u8 ch, u8 prefe, u8 res, u8 update) +{ + u32 offset = pch->nm_of_ch; + + if (update) { + if (rtw_mbo_non_pref_chan_exist(pch, ch) == _FALSE) { + pch->chs[offset] = ch; + pch->nm_of_ch++; + } + } else { + pch->op_class = op_class; + pch->chs[0] = ch; + pch->preference = prefe; + pch->reason = res; + pch->nm_of_ch = 1; + } +} + +static void rtw_mbo_non_pref_chans_update( + _adapter *padapter, u8 op_class, u8 ch, u8 prefe, u8 res) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *pch_rpt = &(prfctl->ch_rtp); + struct npref_ch* pch; + + if (pch_rpt->nm_of_rpt >= RTW_MBO_MAX_CH_RPT_NUM) { + RTW_ERR("MBO : %d non_pref_chan entries supported!", + RTW_MBO_MAX_CH_RPT_NUM); + return; + } + + if (pch_rpt->nm_of_rpt == 0) { + pch = &pch_rpt->ch_rpt[0]; + rtw_mbo_non_pref_chan_set(pch, op_class, ch, prefe, res, _FALSE); + pch_rpt->nm_of_rpt = 1; + return; + } + + pch = rtw_mbo_non_pref_chan_get(padapter, op_class, prefe, res); + if (pch == NULL) { + pch = &pch_rpt->ch_rpt[pch_rpt->nm_of_rpt]; + rtw_mbo_non_pref_chan_set(pch, op_class, ch, prefe, res, _FALSE); + pch_rpt->nm_of_rpt++; + } else + rtw_mbo_non_pref_chan_set(pch, op_class, ch, prefe, res, _TRUE); + + rtw_mbo_non_pref_chans_dump(pch); +} + +static void rtw_mbo_non_pref_chans_set( + _adapter *padapter, char *param, ssize_t sz) +{ + char *pnext; + u32 op_class, ch, prefe, res; + int i = 0; + + do { + pnext = strsep(¶m, " "); + if (pnext == NULL) + break; + + sscanf(pnext, "%d:%d:%d:%d", &op_class, &ch, &prefe, &res); + rtw_mbo_non_pref_chans_update(padapter, op_class, ch, prefe, res); + + if ((i++) > 10) { + RTW_ERR("MBO : overflow %d \n", i); + break; + } + + } while(param != '\0'); + +} + +static void rtw_mbo_non_pref_chans_del( + _adapter *padapter, char *param, ssize_t sz) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *prpt = &(prfctl->ch_rtp); + + RTW_INFO("%s : delete non_pref_chan %s\n", __func__, param); + _rtw_memset(prpt, 0, sizeof(struct npref_ch_rtp)); +} + +ssize_t rtw_mbo_proc_non_pref_chans_set( + struct file *pfile, const char __user *buffer, + size_t count, loff_t *pos, void *pdata) +{ + struct net_device *dev = pdata; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 tmp[128] = {0}; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + if (strncmp(tmp, "add", 3) == 0) + rtw_mbo_non_pref_chans_set(padapter, &tmp[4], (count - 4)); + else if (strncmp(tmp, "delete", 6) == 0) + rtw_mbo_non_pref_chans_del(padapter, &tmp[7], (count - 7)); + else { + RTW_ERR("MBO : Invalid format : echo [add|delete] :::\n"); + return -EFAULT; + } + } + +#ifdef CONFIG_RTW_WNM + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) && + check_fwstate(pmlmepriv, WIFI_STATION_STATE)) + rtw_wnm_issue_action(padapter, RTW_WLAN_ACTION_WNM_NOTIF_REQ, 0, 0); +#endif + + return count; +} + +int rtw_mbo_proc_non_pref_chans_get( + struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *prpt = &(prfctl->ch_rtp); + struct npref_ch* pch; + int i,j; + u8 buf[32] = {0}; + + RTW_PRINT_SEL(m, "op_class ch preference reason \n"); + RTW_PRINT_SEL(m, "=======================================================\n"); + + + if (prpt->nm_of_rpt == 0) { + RTW_PRINT_SEL(m, " empty table \n"); + return 0; + } + + for (i=0; i < prpt->nm_of_rpt; i++) { + pch = &prpt->ch_rpt[i]; + buf[0]='\0'; + for (j=0; j < pch->nm_of_ch; j++) { + if (j == 0) + rtw_sprintf(buf, 32, "%02u", pch->chs[j]); + else + rtw_sprintf(buf, 32, "%s,%02u", buf, pch->chs[j]); + } + + RTW_PRINT_SEL(m, " %04u %20s %02u %02u\n", + pch->op_class, buf, pch->preference, pch->reason); + } + + return 0; +} + +ssize_t rtw_mbo_proc_cell_data_set( + struct file *pfile, const char __user *buffer, + size_t count, loff_t *pos, void *pdata) +{ + struct net_device *dev = pdata; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + int mbo_cell_data = 0; + u8 tmp[8] = {0}; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) + return -EFAULT; + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%d", &mbo_cell_data); + if (num == 1) { + rtw_mbo_cell_data_conn = mbo_cell_data; + #ifdef CONFIG_RTW_WNM + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) && + check_fwstate(pmlmepriv, WIFI_STATION_STATE)) + rtw_wnm_issue_action(padapter, RTW_WLAN_ACTION_WNM_NOTIF_REQ, 0, 0); + #endif + } + } + + + return count; +} + +int rtw_mbo_proc_cell_data_get( + struct seq_file *m, void *v) +{ +#if 0 + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); +#endif + + RTW_PRINT_SEL(m, "Cellular Data Connectivity : %d\n", rtw_mbo_cell_data_conn); + return 0; +} + +static void rtw_mbo_non_pref_chan_subelem_parsing( + _adapter *padapter, u8 *subelem, size_t subelem_len) +{ + u8 *pnon_pref_chans; + u32 non_pref_chan_offset, op_subelem_len; + u32 oui_offset = 3; + /* wpa_supplicant don't apped OUI Type */ + u32 oui_type_offset = 0; + + RTW_MBO_DUMP("Non-preferred Channel subelem : ", subelem , subelem_len); + + /* Subelem : + Vendor Specific | Length | WFA OUI | OUI Type | MBO Attributes */ + non_pref_chan_offset = 2 + oui_offset + oui_type_offset; + pnon_pref_chans = subelem + non_pref_chan_offset; + op_subelem_len = subelem_len - non_pref_chan_offset; + + /* wpa_supplicant don't indicate non_pref_chan length, + so we cannot get how many non_pref_chan in a wnm notification */ + RTW_MBO_DUMP("Non-preferred Channel : ", pnon_pref_chans, op_subelem_len); +} + +void rtw_mbo_wnm_notification_parsing( + _adapter *padapter, const u8 *pdata, size_t data_len) +{ + u8 *paction; + u8 category, action, dialog, type; + u32 len; + + if ((pdata == NULL) || (data_len == 0)) + return; + + RTW_MBO_DUMP("WNM notification data : ", pdata, data_len); + paction = (u8 *)pdata + sizeof(struct rtw_ieee80211_hdr_3addr); + category = paction[0]; + action = paction[1]; + dialog = paction[2]; + type = paction[3]; + + if ((action == RTW_WLAN_ACTION_WNM_NOTIF_REQ) && + (type == WLAN_EID_VENDOR_SPECIFIC)) { + rtw_mbo_non_pref_chan_subelem_parsing(padapter, &paction[4], + (data_len - sizeof(struct rtw_ieee80211_hdr_3addr))); + } + +} + +void rtw_mbo_build_wnm_notification( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib) +{ + struct rf_ctl_t *prfctl = adapter_to_rfctl(padapter); + struct npref_ch_rtp *prpt = &(prfctl->ch_rtp); + struct npref_ch* pch; + u8 subelem_id = WLAN_EID_VENDOR_SPECIFIC; + u8 non_pref_ch_oui[] = {0x50, 0x6F, 0x9A, 0x2}; + u8 cell_data_cap_oui[] = {0x50, 0x6F, 0x9A, 0x3}; + u8 cell_data_con = rtw_mbo_cell_data_conn; + u8 len, cell_data_con_len = 0, *pcont = *pframe; + int i; + + if (rtw_mbo_cell_data_conn > 0) { + len = 0x5; + *pframe = rtw_mbo_set_1byte_ie(*pframe, &subelem_id, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &len, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_4byte_ie(*pframe, cell_data_cap_oui, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &cell_data_con, &(pattrib->pktlen)); + RTW_MBO_INFO("%s : Cellular Data Capabilities subelemen\n", __func__); + RTW_MBO_DUMP(":", pcont, len + 2); + pcont += len + 2 ; + } + + if (prpt->nm_of_rpt == 0) { + len = 0x4; + *pframe = rtw_mbo_set_1byte_ie(*pframe, &subelem_id, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &len, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_4byte_ie(*pframe, non_pref_ch_oui, &(pattrib->pktlen)); + RTW_MBO_INFO("%s :Non-preferred Channel Report subelement without data\n", __func__); + return; + } + + for (i=0; i < prpt->nm_of_rpt; i++) { + pch = &prpt->ch_rpt[i]; + /* OUI(3B) + OUT-type(1B) + op-class(1B) + ch list(nB) + + Preference(1B) + reason(1B) */ + len = pch->nm_of_ch + 7; + *pframe = rtw_mbo_set_1byte_ie(*pframe, &subelem_id, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &len, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_4byte_ie(*pframe, non_pref_ch_oui, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &pch->op_class, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_nbyte_ie(*pframe, pch->nm_of_ch, pch->chs, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &pch->preference, &(pattrib->pktlen)); + *pframe = rtw_mbo_set_1byte_ie(*pframe, &pch->reason, &(pattrib->pktlen)); + RTW_MBO_INFO("%s :Non-preferred Channel Report subelement\n", __func__); + RTW_MBO_DUMP(":", pcont, len); + pcont = *pframe; + } +} + +void rtw_mbo_build_probe_req_ies( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib) +{ + u32 len =0; + + rtw_mbo_build_exented_cap(padapter, pframe, pattrib); + + len = rtw_mbo_attr_sz_get(padapter, RTW_MBO_ATTR_CELL_DATA_CAP_ID); + if ((len == 0) || (len > 3)) { + RTW_ERR("MBO : build Cellular Data Capabilities attribute fail(len=%u)\n", len); + return; + } + + rtw_mbo_build_mbo_ie_hdr(pframe, pattrib, len); + rtw_mbo_build_cell_data_cap_attr(padapter, pframe, pattrib); +} + +void rtw_mbo_build_assoc_req_ies( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib) +{ + u32 len = 0; + + rtw_mbo_build_supp_op_class_elem(padapter, pframe, pattrib); + + len += rtw_mbo_attr_sz_get(padapter, RTW_MBO_ATTR_CELL_DATA_CAP_ID); + len += rtw_mbo_attr_sz_get(padapter, RTW_MBO_ATTR_NPREF_CH_RPT_ID); + if ((len == 0)|| (len < 3)) { + RTW_ERR("MBO : build assoc MBO IE fail(len=%u)\n", len); + return; + } + + rtw_mbo_build_mbo_ie_hdr(pframe, pattrib, len); + rtw_mbo_build_cell_data_cap_attr(padapter, pframe, pattrib); + rtw_mbo_build_npref_ch_rpt_attr(padapter, pframe, pattrib); +} + +#endif /* CONFIG_RTW_MBO */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mem.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mem.c index 4f241751050e..3a262de1d7ec 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mem.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mem.c @@ -22,6 +22,49 @@ MODULE_DESCRIPTION("Realtek Wireless Lan Driver"); MODULE_AUTHOR("Realtek Semiconductor Corp."); MODULE_VERSION("DRIVERVERSION"); +/* for MAX_RECVBUF_SZ */ +#if defined(CONFIG_RTL8188E) +#include +#elif defined(CONFIG_RTL8188F) +#include +#elif defined(CONFIG_RTL8188GTV) +#include +#elif defined(CONFIG_RTL8710B) +#include +#elif defined(CONFIG_RTL8192E) +#include +#elif defined(CONFIG_RTL8192F) +#include +#elif defined(CONFIG_RTL8723B) +#include +#elif defined(CONFIG_RTL8703B) +#include +#elif defined(CONFIG_RTL8723D) +#include +#elif defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) +#include +#elif defined(CONFIG_RTL8822B) +#include +#elif defined(CONFIG_RTL8822C) +#include +#elif defined(CONFIG_RTL8814A) +#include +#elif defined(CONFIG_RTL8814B) +#include +#endif + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +#define MAX_RTKM_RECVBUF_SZ MAX_RECVBUF_SZ +#define MAX_RTKM_NR_PREALLOC_RECV_SKB NR_RECVBUFF +#else /* !CONFIG_SDIO_HCI */ +#ifdef CONFIG_PLATFORM_MSTAR_HIGH + #define MAX_RTKM_RECVBUF_SZ (31744) /* 31k */ +#else + #define MAX_RTKM_RECVBUF_SZ (15360) /* 15k */ +#endif /* CONFIG_PLATFORM_MSTAR_HIGH */ +#define MAX_RTKM_NR_PREALLOC_RECV_SKB 16 +#endif /* !CONFIG_SDIO_HCI */ + struct sk_buff_head rtk_skb_mem_q; struct u8 *rtk_buf_mem[NR_RECVBUFF]; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mi.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mi.c index eea2c4009a9f..ba91b96e0419 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mi.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mi.c @@ -21,11 +21,15 @@ void rtw_mi_update_union_chan_inf(_adapter *adapter, u8 ch, u8 offset , u8 bw) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); - struct mi_state *iface_state = &dvobj->iface_state; - iface_state->union_ch = ch; - iface_state->union_bw = bw; - iface_state->union_offset = offset; + if (!ch) { + dvobj->union_ch_bak = dvobj->union_ch; + dvobj->union_bw_bak = dvobj->union_bw; + dvobj->union_offset_bak = dvobj->union_offset; + } + dvobj->union_ch = ch; + dvobj->union_bw = bw; + dvobj->union_offset = offset; } #ifdef DBG_IFACE_STATUS @@ -184,7 +188,6 @@ inline int rtw_mi_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw return rtw_mi_get_ch_setting_union_by_ifbmp(adapter_to_dvobj(adapter), 0xFF & ~BIT(adapter->iface_id), ch, bw, offset); } -/* For now, not return union_ch/bw/offset */ void rtw_mi_status_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, struct mi_state *mstate) { _adapter *iface; @@ -260,10 +263,10 @@ void rtw_mi_status_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, struct mi_state #ifdef CONFIG_IOCTL_CFG80211 if (rtw_cfg80211_get_is_mgmt_tx(iface)) MSTATE_MGMT_TX_NUM(mstate)++; - #ifdef CONFIG_P2P + if (rtw_cfg80211_get_is_roch(iface) == _TRUE) MSTATE_ROCH_NUM(mstate)++; - #endif + #endif /* CONFIG_IOCTL_CFG80211 */ #ifdef CONFIG_P2P if (MLME_IS_PD(iface)) @@ -287,7 +290,6 @@ inline void rtw_mi_status_no_others(_adapter *adapter, struct mi_state *mstate) return rtw_mi_status_by_ifbmp(adapter_to_dvobj(adapter), BIT(adapter->iface_id), mstate); } -/* For now, not handle union_ch/bw/offset */ inline void rtw_mi_status_merge(struct mi_state *d, struct mi_state *a) { d->sta_num += a->sta_num; @@ -368,7 +370,6 @@ inline void rtw_mi_update_iface_status(struct mlme_priv *pmlmepriv, sint state) struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct mi_state *iface_state = &dvobj->iface_state; struct mi_state tmp_mstate; - u8 u_ch, u_offset, u_bw; if (state == WIFI_MONITOR_STATE || state == 0xFFFFFFFF @@ -381,16 +382,6 @@ inline void rtw_mi_update_iface_status(struct mlme_priv *pmlmepriv, sint state) rtw_mi_status(adapter, &tmp_mstate); _rtw_memcpy(iface_state, &tmp_mstate, sizeof(struct mi_state)); - if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset)) - rtw_mi_update_union_chan_inf(adapter , u_ch, u_offset , u_bw); - else { - if (0) { - dump_adapters_status(RTW_DBGDUMP , dvobj); - RTW_INFO("%s-[ERROR] cannot get union channel\n", __func__); - rtw_warn_on(1); - } - } - #ifdef DBG_IFACE_STATUS DBG_IFACE_STATUS_DUMP(adapter); #endif @@ -822,6 +813,7 @@ void rtw_mi_buddy_set_scan_deny(_adapter *adapter, u32 ms) } #endif /*CONFIG_SET_SCAN_DENY_TIMER*/ +#ifdef CONFIG_AP_MODE static u8 _rtw_mi_beacon_update(_adapter *padapter, void *data) { if (!MLME_IS_STA(padapter) @@ -841,6 +833,7 @@ void rtw_mi_buddy_beacon_update(_adapter *padapter) { _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_beacon_update); } +#endif /* CONFIG_AP_MODE */ #ifndef CONFIG_MI_WITH_MBSSID_CAM static u8 _rtw_mi_hal_dump_macaddr(_adapter *padapter, void *sel) @@ -1157,7 +1150,7 @@ u8 rtw_mi_sreset_adapter_hdl(_adapter *padapter, u8 bstart) return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_sreset_adapter_hdl); } -#if defined(DBG_CONFIG_ERROR_RESET) && defined(CONFIG_CONCURRENT_MODE) +#if defined(CONFIG_AP_MODE) && defined(DBG_CONFIG_ERROR_RESET) && defined(CONFIG_CONCURRENT_MODE) void rtw_mi_ap_info_restore(_adapter *adapter) { int i; @@ -1185,6 +1178,8 @@ u8 rtw_mi_buddy_sreset_adapter_hdl(_adapter *padapter, u8 bstart) return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_sreset_adapter_hdl); } + +#ifdef CONFIG_AP_MODE static u8 _rtw_mi_tx_beacon_hdl(_adapter *adapter, void *data) { if ((MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) @@ -1226,6 +1221,7 @@ u8 rtw_mi_buddy_set_tx_beacon_cmd(_adapter *padapter) { return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_set_tx_beacon_cmd); } +#endif /* CONFIG_AP_MODE */ #ifdef CONFIG_P2P static u8 _rtw_mi_p2p_chk_state(_adapter *adapter, void *data) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mlme.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mlme.c index b416a58d210a..2c979203a54f 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mlme.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mlme.c @@ -16,6 +16,9 @@ #define _RTW_MLME_C_ #include +#ifdef CONFIG_PLATFORM_CMAP_INTFS +#include "../os_dep/linux/custom_multiap_intfs/custom_multiap_intfs.h" +#endif extern void indicate_wx_scan_complete_event(_adapter *padapter); extern u8 rtw_do_join(_adapter *padapter); @@ -46,6 +49,9 @@ sint _rtw_init_mlme_priv(_adapter *padapter) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); sint res = _SUCCESS; +#ifdef CONFIG_RTW_MULTI_AP + struct unassoc_sta_info *unassoc_sta; +#endif /* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */ @@ -101,6 +107,35 @@ sint _rtw_init_mlme_priv(_adapter *padapter) pnetwork++; } +#ifdef CONFIG_RTW_MULTI_AP + if (is_primary_adapter(padapter)) { + _rtw_init_queue(&(pmlmepriv->free_unassoc_sta_queue)); + _rtw_init_queue(&(pmlmepriv->unassoc_sta_queue)); + for (i = 0; i < UNASOC_STA_SRC_NUM; i++) + pmlmepriv->unassoc_sta_mode_of_stype[i] = padapter->registrypriv.unassoc_sta_mode_of_stype[i]; + if (padapter->registrypriv.max_unassoc_sta_cnt != 0) + pmlmepriv->max_unassoc_sta_cnt = padapter->registrypriv.max_unassoc_sta_cnt; + else if (rfctl->max_chan_nums <= MAX_CHANNEL_NUM_2G) + pmlmepriv->max_unassoc_sta_cnt = MAX_UNASSOC_STA_CNT; + else + pmlmepriv->max_unassoc_sta_cnt = MAX_UNASSOC_STA_CNT * 2; + pbuf = rtw_zvmalloc(pmlmepriv->max_unassoc_sta_cnt * (sizeof(struct unassoc_sta_info))); + if (pbuf == NULL) { + res = _FAIL; + goto exit; + } + pmlmepriv->free_unassoc_sta_buf = pbuf; + unassoc_sta = (struct unassoc_sta_info *) pbuf; + for (i = 0; i < pmlmepriv->max_unassoc_sta_cnt; i++) { + _rtw_init_listhead(&(unassoc_sta->list)); + rtw_list_insert_tail(&(unassoc_sta->list), &(pmlmepriv->free_unassoc_sta_queue.queue)); + unassoc_sta++; + } + } +#ifdef CONFIG_PLATFORM_CMAP_INTFS + rtw_init_timer(&pmlmepriv->cmap_unassoc_sta_timer, padapter, cmap_unassoc_sta_report_info_timer, padapter); +#endif +#endif /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ rtw_clear_scan_deny(padapter); @@ -114,16 +149,7 @@ sint _rtw_init_mlme_priv(_adapter *padapter) #define RTW_ROAM_RSSI_DIFF_TH 10 #define RTW_ROAM_SCAN_INTERVAL (5) /* 5*(2 second)*/ #define RTW_ROAM_RSSI_THRESHOLD 70 - - pmlmepriv->roam_flags = 0 - | RTW_ROAM_ON_EXPIRED -#ifdef CONFIG_LAYER2_ROAMING_RESUME - | RTW_ROAM_ON_RESUME -#endif -#ifdef CONFIG_LAYER2_ROAMING_ACTIVE - | RTW_ROAM_ACTIVE -#endif - ; + pmlmepriv->roam_flags = CONFIG_ROAMING_FLAG; pmlmepriv->roam_scanr_exp_ms = RTW_ROAM_SCAN_RESULT_EXP_MS; pmlmepriv->roam_rssi_diff_th = RTW_ROAM_RSSI_DIFF_TH; @@ -160,46 +186,46 @@ void rtw_mfree_mlme_priv_lock(struct mlme_priv *pmlmepriv) _rtw_spinlock_free(&pmlmepriv->lock); _rtw_spinlock_free(&(pmlmepriv->free_bss_pool.lock)); _rtw_spinlock_free(&(pmlmepriv->scanned_queue.lock)); -} - -static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen) -{ - if (*ppie) { - rtw_mfree(*ppie, *plen); - *plen = 0; - *ppie = NULL; +#ifdef CONFIG_RTW_MULTI_AP + if (is_primary_adapter(mlme_to_adapter(pmlmepriv))) { + _rtw_spinlock_free(&(pmlmepriv->unassoc_sta_queue.lock)); + _rtw_spinlock_free(&(pmlmepriv->free_unassoc_sta_queue.lock)); } +#endif } void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv) { -#if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len); rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len); - rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len); +#if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + rtw_buf_free(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len); + rtw_buf_free(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len); + rtw_buf_free(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len); + rtw_buf_free(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_resp_ie, &pmlmepriv->p2p_assoc_resp_ie_len); + rtw_buf_free(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len); + rtw_buf_free(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len); + rtw_buf_free(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len); + rtw_buf_free(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len); + rtw_buf_free(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len); + rtw_buf_free(&pmlmepriv->p2p_assoc_resp_ie, &pmlmepriv->p2p_assoc_resp_ie_len); #endif #if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211) - rtw_free_mlme_ie_data(&pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wfd_go_probe_resp_ie, &pmlmepriv->wfd_go_probe_resp_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len); - rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_resp_ie, &pmlmepriv->wfd_assoc_resp_ie_len); + rtw_buf_free(&pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len); + rtw_buf_free(&pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len); + rtw_buf_free(&pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len); + rtw_buf_free(&pmlmepriv->wfd_go_probe_resp_ie, &pmlmepriv->wfd_go_probe_resp_ie_len); + rtw_buf_free(&pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len); + rtw_buf_free(&pmlmepriv->wfd_assoc_resp_ie, &pmlmepriv->wfd_assoc_resp_ie_len); #endif #ifdef CONFIG_RTW_80211R - rtw_free_mlme_ie_data(&pmlmepriv->auth_rsp, &pmlmepriv->auth_rsp_len); + rtw_buf_free(&pmlmepriv->auth_rsp, &pmlmepriv->auth_rsp_len); +#endif +#ifdef CONFIG_RTW_MBO + rtw_buf_free(&pmlmepriv->pcell_data_cap_ie, &pmlmepriv->cell_data_cap_len); #endif } @@ -314,6 +340,15 @@ void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) if (pmlmepriv->free_bss_buf) rtw_vmfree(pmlmepriv->free_bss_buf, pmlmepriv->max_bss_cnt * sizeof(struct wlan_network)); +#ifdef CONFIG_RTW_MULTI_AP + if (is_primary_adapter(adapter)) { + if (pmlmepriv->free_unassoc_sta_buf) + rtw_vmfree(pmlmepriv->free_unassoc_sta_buf, pmlmepriv->max_unassoc_sta_cnt * sizeof(struct unassoc_sta_info)); + } +#ifdef CONFIG_PLATFORM_CMAP_INTFS + _cancel_timer_ex(&pmlmepriv->cmap_unassoc_sta_timer); +#endif +#endif } exit: return; @@ -1176,10 +1211,8 @@ void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork) if (adapter->registrypriv.wifi_spec == 0) rtw_bss_ex_del_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO); #endif - if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST)) rtw_bss_ex_del_wfd_ie(pnetwork); - /* Wi-Fi driver will update the current network if the scan result of the connected AP be updated by scan. */ update_ie = rtw_update_scanned_network(adapter, pnetwork); @@ -1190,6 +1223,455 @@ void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork) } +#ifdef CONFIG_RTW_MULTI_AP +void rtw_unassoc_sta_set_mode(_adapter *adapter, u8 stype, u8 mode) +{ + if (stype >= UNASOC_STA_SRC_NUM + || mode >= UNASOC_STA_MODE_NUM) + return; + + adapter = GET_PRIMARY_ADAPTER(adapter); + + if (adapter->mlmepriv.unassoc_sta_mode_of_stype[stype] == mode) + return; + + adapter->mlmepriv.unassoc_sta_mode_of_stype[stype] = mode; + + rtw_run_in_thread_cmd_wait(adapter, ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), adapter, 2000); +} + +bool rtw_unassoc_sta_src_chk(_adapter *adapter, u8 stype) +{ + if (stype >= UNASOC_STA_SRC_NUM) + return 0; + + adapter = GET_PRIMARY_ADAPTER(adapter); + + return adapter->mlmepriv.unassoc_sta_mode_of_stype[stype] == UNASOC_STA_MODE_ALL + || (adapter->mlmepriv.unassoc_sta_mode_of_stype[stype] == UNASOC_STA_MODE_INTERESTED + && adapter->mlmepriv.interested_unassoc_sta_cnt) + ; +} + +const char *unasoc_sta_src_str[] = { + "BMC", + "NMY_UC", +}; + +const char *unasoc_sta_mode_str[] = { + "DISABLED", + "INTERESTED", + "ALL", +}; + +void dump_unassoc_sta(void *sel, _adapter *adapter) +{ + struct mlme_priv *mlmepriv; + _queue *queue; + _list *list, *head; + struct unassoc_sta_info **unassoc_sta_arr; + struct unassoc_sta_info *unassoc_sta; + u16 i, unassoc_sta_cnt = 0; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + for (i = 0; i < UNASOC_STA_SRC_NUM; i++) { + RTW_PRINT_SEL(sel, "[%u]%-6s:%u(%s)\n", i, unasoc_sta_src_str[i] + , mlmepriv->unassoc_sta_mode_of_stype[i], unasoc_sta_mode_str[mlmepriv->unassoc_sta_mode_of_stype[i]]); + } + RTW_PRINT_SEL(sel, "interested_unassoc_sta_cnt:%u\n", mlmepriv->interested_unassoc_sta_cnt); + + unassoc_sta_arr = rtw_zvmalloc(mlmepriv->max_unassoc_sta_cnt * sizeof(struct unassoc_sta_info *)); + if (!unassoc_sta_arr) + return; + + enter_critical_bh(&queue->lock); + head = get_list_head(queue); + list = get_next(head); + + while (rtw_end_of_queue_search(head, list) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list, struct unassoc_sta_info, list); + list = get_next(list); + + unassoc_sta_arr[unassoc_sta_cnt++] = unassoc_sta; + } + + exit_critical_bh(&queue->lock); + + RTW_PRINT_SEL(sel, " %17s %18s %6s\n", "mac_addr", "measure_delta_time", "rssi"); + + for (i = 0; i < unassoc_sta_cnt; i++) { + u8 rcpi; + s8 rx_power; + u32 measure_delta_time; + + unassoc_sta = unassoc_sta_arr[i]; + + measure_delta_time = rtw_systime_to_ms(rtw_get_current_time() - unassoc_sta->time); + + RTW_PRINT_SEL(sel, "%c "MAC_FMT" %18u %6d\n" + , unassoc_sta->interested ? '*' : ' ' + , MAC_ARG(unassoc_sta->addr), measure_delta_time, unassoc_sta->recv_signal_power); + } + + rtw_vmfree(unassoc_sta_arr, mlmepriv->max_unassoc_sta_cnt * sizeof(struct unassoc_sta_info *)); +} + +static void del_unassoc_sta(struct mlme_priv *mlmepriv, struct unassoc_sta_info *unassoc_sta) +{ + _irqL irqL; + _queue *free_queue = &(mlmepriv->free_unassoc_sta_queue); + + if (unassoc_sta->interested) + mlmepriv->interested_unassoc_sta_cnt--; + if (mlmepriv->interested_unassoc_sta_cnt == 0) { + rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv) + , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv)); + } + + _enter_critical_bh(&free_queue->lock, &irqL); + rtw_list_delete(&(unassoc_sta->list)); + rtw_list_insert_tail(&(unassoc_sta->list), &(free_queue->queue)); + _exit_critical_bh(&free_queue->lock, &irqL); +} + +static u8 del_unassoc_sta_chk(struct mlme_priv *mlmepriv, struct unassoc_sta_info *unassoc_sta) +{ + systime cur, lifetime; + + if (unassoc_sta == NULL) + return UNASOC_STA_DEL_CHK_SKIP; + + if (unassoc_sta->interested) + return UNASOC_STA_DEL_CHK_SKIP; + + cur = rtw_get_current_time(); + lifetime = unassoc_sta->time + rtw_ms_to_systime(UNASSOC_STA_LIFETIME_MS); + if (rtw_time_before(cur, lifetime)) + return UNASOC_STA_DEL_CHK_ALIVE; + + del_unassoc_sta(mlmepriv, unassoc_sta); + + return UNASOC_STA_DEL_CHK_DELETED; +} + +static struct unassoc_sta_info *alloc_unassoc_sta(struct mlme_priv *mlmepriv) +{ + _irqL irqL; + struct unassoc_sta_info *unassoc_sta; + _queue *free_queue = &mlmepriv->free_unassoc_sta_queue; + _list *list = NULL; + + + _enter_critical_bh(&free_queue->lock, &irqL); + + if (_rtw_queue_empty(free_queue) == _TRUE) { + unassoc_sta = NULL; + goto exit; + } + list = get_next(&(free_queue->queue)); + + unassoc_sta = LIST_CONTAINOR(list, struct unassoc_sta_info, list); + + rtw_list_delete(&unassoc_sta->list); + + _rtw_memset(unassoc_sta->addr, 0, ETH_ALEN); + unassoc_sta->recv_signal_power = 0; + unassoc_sta->time = 0; + unassoc_sta->interested = 0; +exit: + _exit_critical_bh(&free_queue->lock, &irqL); + + return unassoc_sta; + +} + +void rtw_del_unassoc_sta_queue(_adapter *adapter) +{ + struct unassoc_sta_info *unassoc_sta; + struct mlme_priv *mlmepriv; + _queue *queue; + _irqL irqL; + _list *head, *list; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + _enter_critical_bh(&queue->lock, &irqL); + head = get_list_head(queue); + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list); + list = get_next(list); + + del_unassoc_sta(mlmepriv, unassoc_sta); + } + + _exit_critical_bh(&queue->lock, &irqL); + +} + +void rtw_del_unassoc_sta(_adapter *adapter, u8 *addr) +{ + struct unassoc_sta_info *unassoc_sta; + struct mlme_priv *mlmepriv; + _queue *queue; + _irqL irqL; + _list *head, *list; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + _enter_critical_bh(&queue->lock, &irqL); + head = get_list_head(queue); + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list); + list = get_next(list); + + if (_rtw_memcmp(addr, unassoc_sta->addr, ETH_ALEN) == _TRUE) { + del_unassoc_sta(mlmepriv, unassoc_sta); + goto unlock_unassoc_sta_queue; + } + } + +unlock_unassoc_sta_queue: + _exit_critical_bh(&queue->lock, &irqL); +} + +void rtw_rx_add_unassoc_sta(_adapter *adapter, u8 stype, u8 *addr, s8 recv_signal_power) +{ + struct unassoc_sta_info *unassoc_sta; + struct unassoc_sta_info *oldest_unassoc_sta = NULL; + struct mlme_priv *mlmepriv; + _queue *queue; + _irqL irqL; + _list *head, *list; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + _enter_critical_bh(&queue->lock, &irqL); + head = get_list_head(queue); + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list); + list = get_next(list); + + if (_rtw_memcmp(addr, unassoc_sta->addr, ETH_ALEN) == _TRUE) { + if (unassoc_sta->interested + || mlmepriv->unassoc_sta_mode_of_stype[stype] >= UNASOC_STA_MODE_ALL + ) { + unassoc_sta->recv_signal_power = recv_signal_power; + unassoc_sta->time = rtw_get_current_time(); + goto unlock_unassoc_sta_queue; + } + } + + if (del_unassoc_sta_chk(mlmepriv, unassoc_sta) == UNASOC_STA_DEL_CHK_ALIVE) { + if (oldest_unassoc_sta == NULL) + oldest_unassoc_sta = unassoc_sta; + else if (rtw_time_before(unassoc_sta->time, oldest_unassoc_sta->time)) + oldest_unassoc_sta = unassoc_sta; + } + } + + if (mlmepriv->unassoc_sta_mode_of_stype[stype] <= UNASOC_STA_MODE_INTERESTED) + goto unlock_unassoc_sta_queue; + + unassoc_sta = alloc_unassoc_sta(mlmepriv); + if (unassoc_sta == NULL) { + if (oldest_unassoc_sta) { + del_unassoc_sta(mlmepriv, oldest_unassoc_sta); + unassoc_sta = alloc_unassoc_sta(mlmepriv); + } else + goto unlock_unassoc_sta_queue; + } + _rtw_memcpy(unassoc_sta->addr, addr, ETH_ALEN); + unassoc_sta->recv_signal_power = recv_signal_power; + unassoc_sta->time = rtw_get_current_time(); + rtw_list_insert_tail(&(unassoc_sta->list), &(queue->queue)); + +unlock_unassoc_sta_queue: + _exit_critical_bh(&queue->lock, &irqL); +} + +void rtw_add_interested_unassoc_sta(_adapter *adapter, u8 *addr) +{ + struct unassoc_sta_info *unassoc_sta; + struct unassoc_sta_info *oldest_unassoc_sta = NULL; + struct mlme_priv *mlmepriv; + _queue *queue; + _irqL irqL; + _list *head, *list; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + _enter_critical_bh(&queue->lock, &irqL); + head = get_list_head(queue); + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list); + list = get_next(list); + + if (_rtw_memcmp(addr, unassoc_sta->addr, ETH_ALEN) == _TRUE) { + if (!unassoc_sta->interested) { + unassoc_sta->interested = 1; + mlmepriv->interested_unassoc_sta_cnt++; + if (mlmepriv->interested_unassoc_sta_cnt == 1) { + rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv) + , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv)); + } + } + goto unlock_unassoc_sta_queue; + } + + if (del_unassoc_sta_chk(mlmepriv, unassoc_sta) == UNASOC_STA_DEL_CHK_ALIVE) { + if (oldest_unassoc_sta == NULL) + oldest_unassoc_sta = unassoc_sta; + else if (rtw_time_after(unassoc_sta->time, oldest_unassoc_sta->time)) + oldest_unassoc_sta = unassoc_sta; + } + } + unassoc_sta = alloc_unassoc_sta(mlmepriv); + if (unassoc_sta == NULL) { + RTW_INFO(FUNC_ADPT_FMT": Allocate fail\n", FUNC_ADPT_ARG(adapter)); + if (oldest_unassoc_sta) { + RTW_INFO(FUNC_ADPT_FMT": Delete oldest entry and try again.\n", FUNC_ADPT_ARG(adapter)); + del_unassoc_sta(mlmepriv, oldest_unassoc_sta); + unassoc_sta = alloc_unassoc_sta(mlmepriv); + } else + goto unlock_unassoc_sta_queue; + } + _rtw_memcpy(unassoc_sta->addr, addr, ETH_ALEN); + unassoc_sta->interested = 1; + unassoc_sta->recv_signal_power = 0; + unassoc_sta->time = rtw_get_current_time() - rtw_ms_to_systime(UNASSOC_STA_LIFETIME_MS); + rtw_list_insert_tail(&(unassoc_sta->list), &(queue->queue)); + mlmepriv->interested_unassoc_sta_cnt++; + if (mlmepriv->interested_unassoc_sta_cnt == 1) { + rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv) + , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv)); + } + +unlock_unassoc_sta_queue: + _exit_critical_bh(&queue->lock, &irqL); +} + +void rtw_undo_interested_unassoc_sta(_adapter *adapter, u8 *addr) +{ + struct unassoc_sta_info *unassoc_sta; + struct mlme_priv *mlmepriv; + _queue *queue; + _irqL irqL; + _list *head, *list; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + _enter_critical_bh(&queue->lock, &irqL); + head = get_list_head(queue); + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list); + list = get_next(list); + + if (_rtw_memcmp(addr, unassoc_sta->addr, ETH_ALEN) == _TRUE) { + if (unassoc_sta->interested) { + unassoc_sta->interested = 0; + mlmepriv->interested_unassoc_sta_cnt--; + if (mlmepriv->interested_unassoc_sta_cnt == 0) { + rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv) + , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv)); + } + } + goto unlock_unassoc_sta_queue; + } + } +unlock_unassoc_sta_queue: + _exit_critical_bh(&queue->lock, &irqL); +} + +void rtw_undo_all_interested_unassoc_sta(_adapter *adapter) +{ + struct unassoc_sta_info *unassoc_sta; + struct mlme_priv *mlmepriv; + _queue *queue; + _irqL irqL; + _list *head, *list; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + _enter_critical_bh(&queue->lock, &irqL); + head = get_list_head(queue); + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list); + list = get_next(list); + + if (unassoc_sta->interested) { + unassoc_sta->interested = 0; + mlmepriv->interested_unassoc_sta_cnt--; + if (mlmepriv->interested_unassoc_sta_cnt == 0) { + rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv) + , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv)); + goto unlock_unassoc_sta_queue; + } + } + } +unlock_unassoc_sta_queue: + _exit_critical_bh(&queue->lock, &irqL); +} + +u8 rtw_search_unassoc_sta(_adapter *adapter, u8 *addr, struct unassoc_sta_info *ret_sta) +{ + struct unassoc_sta_info *unassoc_sta = NULL; + struct mlme_priv *mlmepriv; + _queue *queue; + _irqL irqL; + _list *head, *list; + u8 searched = 0; + + adapter = GET_PRIMARY_ADAPTER(adapter); + mlmepriv = &(adapter->mlmepriv); + queue = &(mlmepriv->unassoc_sta_queue); + + _enter_critical_bh(&queue->lock, &irqL); + head = get_list_head(queue); + list = get_next(head); + + while ((rtw_end_of_queue_search(head, list)) == _FALSE) { + unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list); + list = get_next(list); + + if (_rtw_memcmp(addr, unassoc_sta->addr, ETH_ALEN) == _TRUE) { + memcpy(ret_sta, unassoc_sta, sizeof(struct unassoc_sta_info)); + searched = 1; + break; + } + } + _exit_critical_bh(&queue->lock, &irqL); + + return searched; +} +#endif /* CONFIG_RTW_MULTI_AP */ + /* select the desired network based on the capability of the (i)bss. * check items: (1) security * (2) network_type @@ -1245,18 +1727,275 @@ int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork) bselected = _FALSE; } +#ifdef CONFIG_RTW_MBO + if (rtw_mbo_disallowed_network(pnetwork) == _TRUE) + bselected = _FALSE; +#endif return bselected; } +#ifdef CONFIG_80211D +static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); + struct registry_priv *pregistrypriv; + struct mlme_ext_priv *pmlmeext; + RT_CHANNEL_INFO *chplan_new; + u8 channel; + u8 i; + + + pregistrypriv = &padapter->registrypriv; + pmlmeext = &padapter->mlmeextpriv; + + /* Adjust channel plan by AP Country IE */ + if (pregistrypriv->enable80211d + && (!pmlmeext->update_channel_plan_by_ap_done)) { + u8 *ie, *p; + u32 len; + RT_CHANNEL_PLAN chplan_ap; + RT_CHANNEL_INFO *chplan_sta = NULL; + u8 country[4]; + u8 fcn; /* first channel number */ + u8 noc; /* number of channel */ + u8 j, k; + + ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); + if (!ie) + return; + if (len < 6) + return; + + ie += 2; + p = ie; + ie += len; + + _rtw_memset(country, 0, 4); + _rtw_memcpy(country, p, 3); + p += 3; + RTW_INFO("%s: 802.11d country=%s\n", __FUNCTION__, country); + + i = 0; + while ((ie - p) >= 3) { + fcn = *(p++); + noc = *(p++); + p++; + + for (j = 0; j < noc; j++) { + if (fcn <= 14) + channel = fcn + j; /* 2.4 GHz */ + else + channel = fcn + j * 4; /* 5 GHz */ + + chplan_ap.Channel[i++] = channel; + } + } + chplan_ap.Len = i; + +#ifdef CONFIG_RTW_DEBUG + i = 0; + RTW_INFO("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid); + while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0)) { + _RTW_INFO("%02d,", chplan_ap.Channel[i]); + i++; + } + _RTW_INFO("}\n"); +#endif + + chplan_sta = rtw_malloc(sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM); + if (!chplan_sta) + goto done_update_chplan_from_ap; + + _rtw_memcpy(chplan_sta, rfctl->channel_set, sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM); +#ifdef CONFIG_RTW_DEBUG + i = 0; + RTW_INFO("%s: STA channel plan {", __FUNCTION__); + while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) { + _RTW_INFO("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].flags & RTW_CHF_NO_IR ? 'p' : 'a'); + i++; + } + _RTW_INFO("}\n"); +#endif + + _rtw_memset(rfctl->channel_set, 0, sizeof(rfctl->channel_set)); + chplan_new = rfctl->channel_set; + + i = j = k = 0; + if (pregistrypriv->wireless_mode & WIRELESS_11G) { + do { + if ((i == MAX_CHANNEL_NUM) + || (chplan_sta[i].ChannelNum == 0) + || (chplan_sta[i].ChannelNum > 14)) + break; + + if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14)) + break; + + if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + i++; + j++; + k++; + } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; +#if 0 + if (chplan_sta[i].flags & RTW_CHF_NO_IR) + chplan_new[k].flags |= RTW_CHF_NO_IR; +#else + chplan_new[k].flags |= RTW_CHF_NO_IR; +#endif + i++; + k++; + } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + j++; + k++; + } + } while (1); + + /* change AP not support channel to Passive scan */ + while ((i < MAX_CHANNEL_NUM) + && (chplan_sta[i].ChannelNum != 0) + && (chplan_sta[i].ChannelNum <= 14)) { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; +#if 0 + if (chplan_sta[i].flags & RTW_CHF_NO_IR) + chplan_new[k].flags |= RTW_CHF_NO_IR; +#else + chplan_new[k].flags |= RTW_CHF_NO_IR; +#endif + i++; + k++; + } + + /* add channel AP supported */ + while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + j++; + k++; + } + } else { + /* keep original STA 2.4G channel plan */ + while ((i < MAX_CHANNEL_NUM) + && (chplan_sta[i].ChannelNum != 0) + && (chplan_sta[i].ChannelNum <= 14)) { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; + if (chplan_sta[i].flags & RTW_CHF_NO_IR) + chplan_new[k].flags |= RTW_CHF_NO_IR; + i++; + k++; + } + + /* skip AP 2.4G channel plan */ + while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) + j++; + } + + if (pregistrypriv->wireless_mode & WIRELESS_11A) { + do { + if ((i >= MAX_CHANNEL_NUM) + || (chplan_sta[i].ChannelNum == 0)) + break; + + if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0)) + break; + + if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + i++; + j++; + k++; + } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; +#if 0 + if (chplan_sta[i].flags & RTW_CHF_NO_IR) + chplan_new[k].flags |= RTW_CHF_NO_IR; +#else + chplan_new[k].flags |= RTW_CHF_NO_IR; +#endif + i++; + k++; + } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + j++; + k++; + } + } while (1); + + /* change AP not support channel to Passive scan */ + while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; +#if 0 + if (chplan_sta[i].flags & RTW_CHF_NO_IR) + chplan_new[k].flags |= RTW_CHF_NO_IR; +#else + chplan_new[k].flags |= RTW_CHF_NO_IR; +#endif + i++; + k++; + } + + /* add channel AP supported */ + while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + j++; + k++; + } + } else { + /* keep original STA 5G channel plan */ + while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; + if (chplan_sta[i].flags & RTW_CHF_NO_IR) + chplan_new[k].flags |= RTW_CHF_NO_IR; + i++; + k++; + } + } + + pmlmeext->update_channel_plan_by_ap_done = 1; + rtw_nlrtw_reg_change_event(padapter); + +#ifdef CONFIG_RTW_DEBUG + k = 0; + RTW_INFO("%s: new STA channel plan {", __FUNCTION__); + while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) { + _RTW_INFO("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].flags & RTW_CHF_NO_IR ? 'p' : 'c'); + k++; + } + _RTW_INFO("}\n"); +#endif + +#if 0 + /* recover the right channel index */ + channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum; + k = 0; + while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) { + if (chplan_new[k].ChannelNum == channel) { + RTW_INFO("%s: change mlme_ext sitesurvey channel index from %d to %d\n", + __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k); + pmlmeext->sitesurvey_res.channel_idx = k; + break; + } + k++; + } +#endif + +done_update_chplan_from_ap: + if (chplan_sta) + rtw_mfree(chplan_sta, sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM); + } +} +#endif + void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf) { _irqL irqL; u32 len; + u8 val8; WLAN_BSSID_EX *pnetwork; struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); - pnetwork = (WLAN_BSSID_EX *)pbuf; len = get_WLAN_BSSID_EX_sz(pnetwork); @@ -1264,6 +2003,25 @@ void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf) return; } +#ifdef CONFIG_RTW_80211K + val8 = 0; + rtw_hal_get_hwreg(adapter, HW_VAR_FREECNT, &val8); + + /* use TSF if no free run counter */ + if (val8==0) + pnetwork->PhyInfo.free_cnt = (u32)rtw_hal_get_tsftr_by_port( + adapter, rtw_hal_get_port(adapter)); +#endif + + if (pnetwork->InfrastructureMode == Ndis802_11Infrastructure) { + #ifdef CONFIG_80211D + process_80211d(adapter, pnetwork); + #endif + if (MLME_IS_SCAN(adapter)) { + adapter->mlmeextpriv.sitesurvey_res.activate_ch_cnt + += rtw_process_beacon_hint(adapter, pnetwork); + } + } _enter_critical_bh(&pmlmepriv->lock, &irqL); @@ -1347,6 +2105,7 @@ void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf) if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS) _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); + #ifdef CONFIG_AP_MODE else { WLAN_BSSID_EX *pdev_network = &(adapter->registrypriv.dev_network); u8 *pibss = adapter->registrypriv.dev_network.MacAddress; @@ -1369,6 +2128,7 @@ void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf) pmlmepriv->to_join = _FALSE; } + #endif /* CONFIG_AP_MODE */ } } else { int s_ret; @@ -1406,17 +2166,21 @@ void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf) } } } else { - if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) { + if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE) + #if (defined(CONFIG_RTW_WNM) && defined(CONFIG_RTW_80211R)) + || rtw_wnm_btm_roam_triggered(adapter) + #endif + ) { if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) { if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) { -#ifdef CONFIG_RTW_80211R + #ifdef CONFIG_RTW_80211R rtw_ft_start_roam(adapter, (u8 *)pmlmepriv->roam_network->network.MacAddress); -#else + #else receive_disconnect(adapter, pmlmepriv->cur_network.network.MacAddress , WLAN_REASON_ACTIVE_ROAM, _FALSE); -#endif + #endif } } } @@ -1456,6 +2220,11 @@ void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf) rtw_cfg80211_indicate_scan_done_for_buddy(adapter, _FALSE); #endif + if (parm->activate_ch_cnt) { + op_class_pref_apply_regulatory(adapter, REG_BEACON_HINT); + rtw_nlrtw_reg_beacon_hint_event(adapter); + } + #ifdef CONFIG_RTW_MESH #if CONFIG_RTW_MESH_OFFCH_CAND if (rtw_mesh_offch_candidate_accepted(adapter)) { @@ -1761,6 +2530,11 @@ void rtw_indicate_connect(_adapter *padapter) rtw_led_control(padapter, LED_CTL_LINK); rtw_os_indicate_connect(padapter); + + #ifdef CONFIG_RTW_WDS + if (MLME_IS_STA(padapter)) + rtw_wds_gptr_tbl_init(padapter); + #endif } rtw_set_to_roam(padapter, 0); @@ -1825,6 +2599,13 @@ void rtw_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally_generate if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) || (rtw_to_roam(padapter) <= 0) ) { + #ifdef CONFIG_RTW_WDS + adapter_set_use_wds(padapter, 0); + rtw_wds_gptr_tbl_unregister(padapter); + #endif + #ifdef CONFIG_RTW_MULTI_AP + padapter->multi_ap = 0; + #endif #ifdef CONFIG_RTW_TOKEN_BASED_XMIT if (ATOMIC_READ(&padapter->tbtx_tx_pause) == _TRUE) { @@ -2100,6 +2881,17 @@ static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wl #ifdef CONFIG_RTW_80211K _rtw_memcpy(&psta->rm_en_cap, pnetwork->network.PhyInfo.rm_en_cap, 5); #endif +#ifdef CONFIG_RTW_MULTI_AP + if (padapter->multi_ap & MULTI_AP_BACKHAUL_STA) { + u8 multi_ap = rtw_get_multi_ap_ie_ext(pmlmepriv->assoc_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6 + , pmlmepriv->assoc_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6); + + if (multi_ap & MULTI_AP_BACKHAUL_BSS) /* backhaul bss, enable WDS */ + psta->flags |= WLAN_STA_MULTI_AP | WLAN_STA_WDS; + else if (multi_ap & MULTI_AP_FRONTHAUL_BSS) /* fronthaul bss only */ + psta->flags |= WLAN_STA_MULTI_AP; + } +#endif #ifdef CONFIG_RTS_FULL_BW rtw_parse_sta_vendor_ie_8812(padapter, psta, BSS_EX_TLV_IES(&cur_network->network), BSS_EX_TLV_IES_LEN(&cur_network->network)); #endif @@ -2510,10 +3302,6 @@ void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf) if (passoc_req) { assoc_req_len = psta->assoc_req_len; _rtw_memcpy(passoc_req, psta->passoc_req, assoc_req_len); - - rtw_mfree(psta->passoc_req , psta->assoc_req_len); - psta->passoc_req = NULL; - psta->assoc_req_len = 0; } } _exit_critical_bh(&psta->lock, &irqL); @@ -2533,6 +3321,13 @@ void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf) #endif/*CONFIG_BEAMFORMING*/ if (is_wep_enc(adapter->securitypriv.dot11PrivacyAlgrthm)) rtw_ap_wep_pk_setting(adapter, psta); + + #ifdef CONFIG_PLATFORM_CMAP_INTFS + if (MLME_IS_AP(adapter)) { + cmap_intfs_nl_sta_event(psta->cmn.mac_addr, adapter_mac_addr(adapter), 1 + , psta->passoc_req + IEEE80211_3ADDR_LEN, psta->assoc_req_len - IEEE80211_3ADDR_LEN); + } + #endif } goto exit; } @@ -2591,12 +3386,12 @@ exit: #ifdef CONFIG_IEEE80211W void rtw_sta_timeout_event_callback(_adapter *adapter, u8 *pbuf) { +#ifdef CONFIG_AP_MODE _irqL irqL; struct sta_info *psta; struct stadel_event *pstadel = (struct stadel_event *)pbuf; struct sta_priv *pstapriv = &adapter->stapriv; - psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr); if (psta) { @@ -2616,189 +3411,10 @@ void rtw_sta_timeout_event_callback(_adapter *adapter, u8 *pbuf) associated_clients_update(adapter, updated, STA_INFO_UPDATE_ALL); } - - - +#endif /* CONFIG_AP_MODE */ } #endif /* CONFIG_IEEE80211W */ -#ifdef CONFIG_RTW_80211R -void rtw_ft_info_init(struct ft_roam_info *pft) -{ - _rtw_memset(pft, 0, sizeof(struct ft_roam_info)); - pft->ft_flags = 0 - | RTW_FT_EN - | RTW_FT_OTD_EN -#ifdef CONFIG_RTW_BTM_ROAM - | RTW_FT_BTM_ROAM -#endif - ; - pft->ft_updated_bcn = _FALSE; -} - -u8 rtw_ft_chk_roaming_candidate( - _adapter *padapter, struct wlan_network *competitor) -{ - u8 *pmdie; - u32 mdie_len = 0; - struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); - - if (!(pmdie = rtw_get_ie(&competitor->network.IEs[12], - _MDIE_, &mdie_len, competitor->network.IELength-12))) - return _FALSE; - - if (!_rtw_memcmp(&pft_roam->mdid, (pmdie+2), 2)) - return _FALSE; - - /*The candidate don't support over-the-DS*/ - if (rtw_ft_valid_otd_candidate(padapter, pmdie)) { - RTW_INFO("FT: ignore the candidate(" - MAC_FMT ") for over-the-DS\n", - MAC_ARG(competitor->network.MacAddress)); - rtw_ft_clr_flags(padapter, RTW_FT_PEER_OTD_EN); - return _FALSE; - } - - return _TRUE; -} - -void rtw_ft_update_stainfo(_adapter *padapter, WLAN_BSSID_EX *pnetwork) -{ - struct sta_priv *pstapriv = &padapter->stapriv; - struct sta_info *psta = NULL; - - psta = rtw_get_stainfo(pstapriv, pnetwork->MacAddress); - if (psta == NULL) - psta = rtw_alloc_stainfo(pstapriv, pnetwork->MacAddress); - - if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { - - padapter->securitypriv.binstallGrpkey = _FALSE; - padapter->securitypriv.busetkipkey = _FALSE; - padapter->securitypriv.bgrpkey_handshake = _FALSE; - - psta->ieee8021x_blocked = _TRUE; - psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; - - _rtw_memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype)); - _rtw_memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype)); - _rtw_memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype)); - } - -} - -void rtw_ft_reassoc_event_callback(_adapter *padapter, u8 *pbuf) -{ - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf; - struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&(pmlmeinfo->network); - struct cfg80211_ft_event_params ft_evt_parms; - _irqL irqL; - - _rtw_memset(&ft_evt_parms, 0, sizeof(ft_evt_parms)); - rtw_ft_update_stainfo(padapter, pnetwork); - ft_evt_parms.ies_len = pft_roam->ft_event.ies_len; - ft_evt_parms.ies = rtw_zmalloc(ft_evt_parms.ies_len); - if (ft_evt_parms.ies) - _rtw_memcpy((void *)ft_evt_parms.ies, pft_roam->ft_event.ies, ft_evt_parms.ies_len); - else - goto err_2; - - ft_evt_parms.target_ap = rtw_zmalloc(ETH_ALEN); - if (ft_evt_parms.target_ap) - _rtw_memcpy((void *)ft_evt_parms.target_ap, pstassoc->macaddr, ETH_ALEN); - else - goto err_1; - - ft_evt_parms.ric_ies = pft_roam->ft_event.ric_ies; - ft_evt_parms.ric_ies_len = pft_roam->ft_event.ric_ies_len; - - rtw_ft_lock_set_status(padapter, RTW_FT_AUTHENTICATED_STA, &irqL); - rtw_cfg80211_ft_event(padapter, &ft_evt_parms); - RTW_INFO("%s: to "MAC_FMT"\n", __func__, MAC_ARG(ft_evt_parms.target_ap)); - - rtw_mfree((u8 *)pft_roam->ft_event.target_ap, ETH_ALEN); -err_1: - rtw_mfree((u8 *)ft_evt_parms.ies, ft_evt_parms.ies_len); -err_2: - return; -} -#endif - -#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) -void rtw_roam_nb_info_init(_adapter *padapter) -{ - struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); - - _rtw_memset(&pnb->nb_rpt, 0, sizeof(pnb->nb_rpt)); - _rtw_memset(&pnb->nb_rpt_ch_list, 0, sizeof(pnb->nb_rpt_ch_list)); - _rtw_memset(&pnb->roam_target_addr, 0, ETH_ALEN); - pnb->nb_rpt_valid = _FALSE; - pnb->nb_rpt_ch_list_num = 0; - pnb->preference_en = _FALSE; - pnb->nb_rpt_is_same = _TRUE; - pnb->last_nb_rpt_entries = 0; -#ifdef CONFIG_RTW_WNM - rtw_init_timer(&pnb->roam_scan_timer, - padapter, rtw_wnm_roam_scan_hdl, - padapter); -#endif -} - -u8 rtw_roam_nb_scan_list_set( - _adapter *padapter, struct sitesurvey_parm *pparm) -{ - u8 ret = _FALSE; - u32 i; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct roam_nb_info *pnb = &(pmlmepriv->nb_info); - - if (!rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE)) - return ret; - - if (!pmlmepriv->need_to_roam) - return ret; - - if ((!pmlmepriv->nb_info.nb_rpt_valid) || (!pnb->nb_rpt_ch_list_num)) - return ret; - - if (!pparm) - return ret; - - rtw_init_sitesurvey_parm(padapter, pparm); - if (rtw_roam_busy_scan(padapter, pnb)) { - pparm->ch_num = 1; - pparm->ch[pmlmepriv->ch_cnt].hw_value = - pnb->nb_rpt_ch_list[pmlmepriv->ch_cnt].hw_value; - pmlmepriv->ch_cnt++; - ret = _TRUE; - if (pmlmepriv->ch_cnt == pnb->nb_rpt_ch_list_num) { - pmlmepriv->nb_info.nb_rpt_valid = _FALSE; - pmlmepriv->ch_cnt = 0; - } - goto set_bssid_list; - } - - pparm->ch_num = (pnb->nb_rpt_ch_list_num > RTW_CHANNEL_SCAN_AMOUNT)? - (RTW_CHANNEL_SCAN_AMOUNT):(pnb->nb_rpt_ch_list_num); - for (i=0; ich_num; i++) { - pparm->ch[i].hw_value = pnb->nb_rpt_ch_list[i].hw_value; - pparm->ch[i].flags = RTW_IEEE80211_CHAN_PASSIVE_SCAN; - } - - pmlmepriv->nb_info.nb_rpt_valid = _FALSE; - pmlmepriv->ch_cnt = 0; - ret = _TRUE; - -set_bssid_list: - rtw_set_802_11_bssid_list_scan(padapter, pparm); - return ret; -} -#endif - void rtw_sta_mstatus_disc_rpt(_adapter *adapter, u8 mac_id) { struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl; @@ -2879,6 +3495,7 @@ void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf) goto exit; } +#ifdef CONFIG_AP_MODE if (MLME_IS_AP(adapter)) { #ifdef CONFIG_IOCTL_CFG80211 #ifdef COMPAT_KERNEL_RELEASE @@ -2888,10 +3505,15 @@ void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf) #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) */ #endif /* CONFIG_IOCTL_CFG80211 */ + #ifdef CONFIG_PLATFORM_CMAP_INTFS + cmap_intfs_nl_sta_event(pstadel->macaddr, adapter_mac_addr(adapter), 0, NULL, 0); + #endif + rtw_free_stainfo(adapter, psta); goto exit; } +#endif /* CONFIG_AP_MODE */ mlmeext_sta_del_event_callback(adapter); @@ -2917,6 +3539,14 @@ void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf) roam = _TRUE; roam_target = pmlmepriv->roam_network; } + +#ifdef CONFIG_RTW_80211R + if (reason == WLAN_REASON_ACTIVE_ROAM && rtw_ft_chk_flags(adapter, RTW_FT_BTM_ROAM)) { + roam = _TRUE; + roam_target = pmlmepriv->roam_network; + } +#endif + if (roam == _TRUE) { if (rtw_to_roam(adapter) > 0) rtw_dec_to_roam(adapter); /* this stadel_event is caused by roaming, decrease to_roam */ @@ -2936,6 +3566,7 @@ void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf) _rtw_roaming(adapter, roam_target); } +#ifdef CONFIG_AP_MODE if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { @@ -2978,7 +3609,7 @@ void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf) } } - +#endif /* CONFIG_AP_MODE */ _exit_critical_bh(&pmlmepriv->lock, &irqL2); exit: #ifdef CONFIG_RTS_FULL_BW @@ -3158,8 +3789,10 @@ void rtw_drv_scan_by_self(_adapter *padapter, u8 reason) RTW_INFO(FUNC_ADPT_FMT" need to roam, don't care BusyTraffic\n", FUNC_ADPT_ARG(padapter)); else #endif + { RTW_INFO(FUNC_ADPT_FMT" exit BusyTraffic\n", FUNC_ADPT_ARG(padapter)); goto exit; + } } else if (ssc_chk != SS_ALLOW) goto exit; @@ -3268,9 +3901,7 @@ static u8 is_drv_in_lps(_adapter *adapter) } void rtw_iface_dynamic_check_timer_handlder(_adapter *adapter) { -#ifdef CONFIG_AP_MODE struct mlme_priv *pmlmepriv = &adapter->mlmepriv; -#endif /* CONFIG_AP_MODE */ if (adapter->net_closed == _TRUE) return; @@ -3307,7 +3938,7 @@ void rtw_iface_dynamic_check_timer_handlder(_adapter *adapter) #ifdef CONFIG_BR_EXT - +if (!adapter_use_wds(adapter)) { #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) rcu_read_lock(); #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) */ @@ -3332,7 +3963,7 @@ void rtw_iface_dynamic_check_timer_handlder(_adapter *adapter) #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) rcu_read_unlock(); #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) */ - +} #endif /* CONFIG_BR_EXT */ } @@ -3531,7 +4162,7 @@ static int rtw_check_roaming_candidate(struct mlme_priv *mlme if (rtw_chset_search_ch(chset, ch) < 0) goto exit; if (IS_DFS_SLAVE_WITH_RD(rfctl) - && !rtw_odm_dfs_domain_unknown(rfctl_to_dvobj(rfctl)) + && !rtw_rfctl_dfs_domain_unknown(rfctl) && rtw_chset_is_ch_non_ocp(chset, ch)) goto exit; @@ -3552,14 +4183,7 @@ static int rtw_check_roaming_candidate(struct mlme_priv *mlme goto exit; #endif -#ifdef CONFIG_RTW_80211R - if (rtw_ft_chk_flags(adapter, RTW_FT_PEER_EN)) { - if (rtw_ft_chk_roaming_candidate(adapter, competitor) == _FALSE) - goto exit; - } -#endif - - RTW_INFO("roam candidate:%s %s("MAC_FMT", ch%3u) rssi:%d, age:%5d\n", + RTW_INFO("roam candidate:%s %s("MAC_FMT", ch%3u) rssi:%d dBm, age:%5d\n", (competitor == mlme->cur_network_scanned) ? "*" : " " , competitor->network.Ssid.Ssid, MAC_ARG(competitor->network.MacAddress), @@ -3575,16 +4199,24 @@ static int rtw_check_roaming_candidate(struct mlme_priv *mlme else goto exit; } -#if 1 - if (rtw_get_passing_time_ms(competitor->last_scanned) >= mlme->roam_scanr_exp_ms) - goto exit; -#if defined(CONFIG_RTW_80211R) && defined(CONFIG_RTW_WNM) +#ifdef CONFIG_RTW_80211R + if (rtw_ft_chk_flags(adapter, RTW_FT_PEER_EN)) { + if (rtw_ft_chk_roaming_candidate(adapter, competitor) == _FALSE) + goto exit; + } + +#ifdef CONFIG_RTW_WNM if (rtw_wnm_btm_diff_bss(adapter) && rtw_wnm_btm_roam_candidate(adapter, competitor)) { goto update; } #endif +#endif + +#if 1 + if (rtw_get_passing_time_ms(competitor->last_scanned) >= mlme->roam_scanr_exp_ms) + goto exit; if (competitor->network.Rssi - mlme->cur_network_scanned->network.Rssi < mlme->roam_rssi_diff_th) goto exit; @@ -3708,7 +4340,7 @@ static int rtw_check_join_candidate(struct mlme_priv *mlme if (rtw_chset_search_ch(chset, ch) < 0) goto exit; if (IS_DFS_SLAVE_WITH_RD(rfctl) - && !rtw_odm_dfs_domain_unknown(rfctl_to_dvobj(rfctl)) + && !rtw_rfctl_dfs_domain_unknown(rfctl) && rtw_chset_is_ch_non_ocp(chset, ch)) goto exit; @@ -3764,7 +4396,7 @@ static int rtw_check_join_candidate(struct mlme_priv *mlme if (updated) { RTW_INFO("[by_bssid:%u][assoc_ssid:%s][to_roam:%u] " - "new candidate: %s("MAC_FMT", ch%u) rssi:%d\n", + "new candidate: %s("MAC_FMT", ch%u) rssi:%d dBm\n", mlme->assoc_by_bssid, mlme->assoc_ssid.Ssid, rtw_to_roam(adapter), @@ -4264,6 +4896,9 @@ int rtw_rsn_sync_pmkid(_adapter *adapter, u8 *ie, uint ie_len, int i_ent) if (i_ent < 0 && info.pmkid_cnt == 0) goto exit; + if (info.pmkid_list == NULL) + goto exit; + if (i_ent >= 0 && info.pmkid_cnt == 1 && _rtw_memcmp(info.pmkid_list, sec->PMKIDList[i_ent].PMKID, 16)) { RTW_INFO(FUNC_ADPT_FMT" has carried the same PMKID:"KEY_FMT"\n" , FUNC_ADPT_ARG(adapter), KEY_ARG(&sec->PMKIDList[i_ent].PMKID)); @@ -4515,10 +5150,13 @@ void rtw_ht_use_default_setting(_adapter *padapter) CLEAR_FLAGS(phtpriv->beamform_cap); #ifdef CONFIG_BEAMFORMING #ifdef RTW_BEAMFORMING_VERSION_2 +#ifdef CONFIG_CONCURRENT_MODE /* only enable beamforming in STA client mode */ - if (MLME_IS_STA(padapter) && !MLME_IS_GC(padapter) - && !MLME_IS_ADHOC(padapter) - && !MLME_IS_MESH(padapter)) + if (MLME_IS_STA(padapter) && !MLME_IS_GC(padapter)) +#else + if ((MLME_IS_AP(padapter) && !MLME_IS_GO(padapter)) || + (MLME_IS_STA(padapter) && !MLME_IS_GC(padapter))) +#endif #endif { rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&bHwSupportBeamformer); @@ -4634,16 +5272,16 @@ unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, ui /* adjust bw to fit in channel plan setting */ if (oper_bw == CHANNEL_WIDTH_40 && oper_offset != HAL_PRIME_CHNL_OFFSET_DONT_CARE /* check this because TDLS has no info to set offset */ - && (!rtw_chset_is_chbw_valid(chset, channel, oper_bw, oper_offset) + && (!rtw_chset_is_chbw_valid(chset, channel, oper_bw, oper_offset, 1, 1) || (IS_DFS_SLAVE_WITH_RD(rfctl) - && !rtw_odm_dfs_domain_unknown(rfctl_to_dvobj(rfctl)) + && !rtw_rfctl_dfs_domain_unknown(rfctl) && rtw_chset_is_chbw_non_ocp(chset, channel, oper_bw, oper_offset)) ) ) { oper_bw = CHANNEL_WIDTH_20; oper_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - rtw_warn_on(!rtw_chset_is_chbw_valid(chset, channel, oper_bw, oper_offset)); - if (IS_DFS_SLAVE_WITH_RD(rfctl) && !rtw_odm_dfs_domain_unknown(rfctl_to_dvobj(rfctl))) + rtw_warn_on(!rtw_chset_is_chbw_valid(chset, channel, oper_bw, oper_offset, 1, 1)); + if (IS_DFS_SLAVE_WITH_RD(rfctl) && !rtw_rfctl_dfs_domain_unknown(rfctl)) rtw_warn_on(rtw_chset_is_chbw_non_ocp(chset, channel, oper_bw, oper_offset)); } @@ -4881,16 +5519,16 @@ void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel) (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) && (pmlmeinfo->HT_info.infos[0] & BIT(2))) { int i; - u8 tx_nss = 0; + u8 rx_nss = 0; - tx_nss = GET_HAL_TX_NSS(padapter); + rx_nss = GET_HAL_RX_NSS(padapter); /* update the MCS set */ for (i = 0; i < 16; i++) pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i]; /* update the MCS rates */ - switch (tx_nss) { + switch (rx_nss) { case 1: set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R); break; @@ -4909,7 +5547,7 @@ void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel) set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_4R); break; default: - RTW_WARN("tx_nss:%u is not expected\n", tx_nss); + RTW_WARN("rx_nss:%u is not expected\n", rx_nss); } /* switch to the 40M Hz mode accoring to the AP */ @@ -5076,6 +5714,10 @@ void rtw_append_exented_cap(_adapter *padapter, u8 *out_ie, uint *pout_len) #ifdef CONFIG_RTW_WNM rtw_wnm_set_ext_cap_btm(cap_content, 1); #endif + +#ifdef CONFIG_RTW_MBO + rtw_mbo_set_ext_cap_internw(cap_content, 1); +#endif /* From 802.11 specification,if a STA does not support any of capabilities defined in the Extended Capabilities element, then the STA is not required to diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mlme_ext.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mlme_ext.c index 098d6dda73d8..457938cefa34 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mlme_ext.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mlme_ext.c @@ -16,12 +16,8 @@ #define _RTW_MLME_EXT_C_ #include -#ifdef CONFIG_IOCTL_CFG80211 - #include -#endif /* CONFIG_IOCTL_CFG80211 */ #include - struct mlme_handler mlme_sta_tbl[] = { {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq}, {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp}, @@ -110,6 +106,7 @@ unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04}; unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09}; unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A}; unsigned char DPP_OUI[] = {0x50, 0x6F, 0x9A, 0x1A}; +unsigned char MULTI_AP_OUI[] = {0x50, 0x6F, 0x9A, 0x1B}; unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; @@ -223,6 +220,40 @@ void rtw_txpwr_init_regd(struct rf_ctl_t *rfctl) goto release_lock; } +#ifdef CONFIG_REGD_SRC_FROM_OS + if (rfctl->regd_src == REGD_SRC_OS) { + if (IS_ALPHA2_WORLDWIDE(rfctl->country_ent->alpha2)) + rfctl->regd_name = regd_str(TXPWR_LMT_WW); + else { + char alpha2[3] = { + rfctl->country_ent->alpha2[0], rfctl->country_ent->alpha2[1], 0}; + + ent = _rtw_txpwr_lmt_get_by_name(rfctl, alpha2); + if (ent) + rfctl->regd_name = ent->regd_name; + } + + if (rfctl->regd_name) { + RTW_PRINT("mapping country:%c%c to regd_name:%s\n" + , rfctl->country_ent->alpha2[0] + , rfctl->country_ent->alpha2[1] + , rfctl->regd_name + ); + goto release_lock; + } + + if (rfctl->ChannelPlan == RTW_CHPLAN_UNSPECIFIED) { + rfctl->regd_name = regd_str(TXPWR_LMT_WW); + RTW_PRINT("mapping unsupported country:%c%c to regd_name:%s\n" + , rfctl->country_ent->alpha2[0] + , rfctl->country_ent->alpha2[1] + , rfctl->regd_name + ); + goto release_lock; + } + } +#endif + /* follow default channel plan mapping */ regd = rtw_chplan_get_default_regd(rfctl->ChannelPlan); if (regd == TXPWR_LMT_NONE) @@ -251,10 +282,11 @@ void rtw_txpwr_init_regd(struct rf_ctl_t *rfctl) */ case TXPWR_LMT_IC: case TXPWR_LMT_KCC: + case TXPWR_LMT_NCC: case TXPWR_LMT_ACMA: case TXPWR_LMT_CHILE: case TXPWR_LMT_MEXICO: - if (regd == TXPWR_LMT_IC || regd == TXPWR_LMT_CHILE || regd == TXPWR_LMT_MEXICO) + if (regd == TXPWR_LMT_IC || regd == TXPWR_LMT_NCC || regd == TXPWR_LMT_CHILE || regd == TXPWR_LMT_MEXICO) regd = TXPWR_LMT_FCC; else if (regd == TXPWR_LMT_KCC || regd == TXPWR_LMT_ACMA) regd = TXPWR_LMT_ETSI; @@ -267,6 +299,7 @@ void rtw_txpwr_init_regd(struct rf_ctl_t *rfctl) ); if (rfctl->regd_name) break; + /* fall through */ default: rfctl->regd_name = regd_str(TXPWR_LMT_WW); RTW_PRINT("assign %s for default case\n", regd_str(TXPWR_LMT_WW)); @@ -278,12 +311,11 @@ release_lock: } #endif /* CONFIG_TXPWR_LIMIT */ -void rtw_rfctl_init(_adapter *adapter) +int rtw_rfctl_init(_adapter *adapter) { + struct registry_priv *regsty = adapter_to_regsty(adapter); struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); - - rfctl->max_chan_nums = init_channel_set(adapter, rfctl->ChannelPlan, rfctl->channel_set); - init_channel_list(adapter, rfctl->channel_set, &rfctl->channel_list); + int ret; _rtw_mutex_init(&rfctl->offch_mutex); @@ -296,12 +328,22 @@ void rtw_rfctl_init(_adapter *adapter) rfctl->ch_sel_within_same_band = 1; #ifdef CONFIG_DFS_MASTER + rfctl->dfs_region_domain = regsty->dfs_region_domain; rfctl->cac_start_time = rfctl->cac_end_time = RTW_CAC_STOPPED; rtw_init_timer(&(rfctl->radar_detect_timer), adapter, rtw_dfs_rd_timer_hdl, rfctl); #endif #if CONFIG_DFS_SLAVE_WITH_RADAR_DETECT rfctl->dfs_slave_with_rd = 1; #endif + + if (regsty->antenna_gain != UNSPECIFIED_MBM) + rfctl->antenna_gain = regsty->antenna_gain; + + ret = op_class_pref_init(adapter); + if (ret != _SUCCESS) + op_class_pref_deinit(adapter); + + return ret; } void rtw_rfctl_deinit(_adapter *adapter) @@ -315,6 +357,131 @@ void rtw_rfctl_deinit(_adapter *adapter) rtw_txpwr_lmt_list_free(rfctl); _rtw_mutex_free(&rfctl->txpwr_lmt_mutex); #endif + +#ifdef CONFIG_REGD_SRC_FROM_OS + if (rfctl->regd_src == REGD_SRC_OS) + rtw_mfree((void *)rfctl->country_ent, sizeof(struct country_chplan)); +#endif + + op_class_pref_deinit(adapter); +} + +void rtw_rfctl_chplan_init(_adapter *adapter) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + rfctl->max_chan_nums = init_channel_set(adapter); + op_class_pref_apply_regulatory(adapter, REG_CHANGE); + init_channel_list(adapter, rfctl->channel_set, &rfctl->channel_list); +} + +void rtw_rfctl_update_op_mode(struct rf_ctl_t *rfctl, u8 ifbmp_mod, u8 if_op) +{ + struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl); + _adapter *iface; + struct mlme_ext_priv *mlmeext; + u8 op_class = 0; + u8 op_ch = 0; + s16 op_txpwr_max; + u8 if_op_class[CONFIG_IFACE_NUMBER] = {0}; + u8 if_op_ch[CONFIG_IFACE_NUMBER] = {0}; + u8 ch, bw, offset; + u8 u_ch = 0, u_bw, u_offset; + bool notify = 0; + int i; + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (!iface) + continue; + mlmeext = &iface->mlmeextpriv; + + if (ifbmp_mod & BIT(i)) { + if (!if_op) + continue; + } else if (!MLME_IS_ASOC(iface) || MLME_IS_OPCH_SW(iface)) + continue; + + ch = mlmeext->cur_channel; + bw = mlmeext->cur_bwmode; + offset = mlmeext->cur_ch_offset; + if_op_class[i] = rtw_get_op_class_by_chbw(ch, bw, offset); + if_op_ch[i] = if_op_class[i] ? ch : 0; + + if (!u_ch) { + u_ch = ch; + u_bw = bw; + u_offset = offset; + } else { + rtw_warn_on(!rtw_is_chbw_grouped(u_ch, u_bw, u_offset, ch, bw, offset)); + rtw_sync_chbw(&ch, &bw, &offset, &u_ch, &u_bw, &u_offset); + } + } + + op_class = rtw_get_op_class_by_chbw(u_ch, u_bw, u_offset); + op_ch = op_class ? u_ch : 0; + op_txpwr_max = rtw_rfctl_get_oper_txpwr_max_mbm(rfctl, u_ch, u_bw, u_offset, ifbmp_mod, if_op, 1); + + if (op_class != rfctl->op_class + || op_ch != rfctl->op_ch + || op_txpwr_max != rfctl->op_txpwr_max + || _rtw_memcmp(if_op_class, rfctl->if_op_class, sizeof(u8) * CONFIG_IFACE_NUMBER) == _FALSE + || _rtw_memcmp(if_op_ch, rfctl->if_op_ch, sizeof(u8) * CONFIG_IFACE_NUMBER) == _FALSE) + notify = 1; + + rfctl->op_class = op_class; + rfctl->op_ch = op_ch; + rfctl->op_txpwr_max = op_txpwr_max; + _rtw_memcpy(rfctl->if_op_class, if_op_class, sizeof(u8) * CONFIG_IFACE_NUMBER); + _rtw_memcpy(rfctl->if_op_ch, if_op_ch, sizeof(u8) * CONFIG_IFACE_NUMBER); + + if (0) + RTW_INFO("radio: %u,%u,%u %d notify:%d\n", u_ch, u_bw, u_offset, op_txpwr_max, notify); + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (!iface) + continue; + mlmeext = &iface->mlmeextpriv; + + if (ifbmp_mod & BIT(i)) { + if (!if_op) + continue; + } else if (!MLME_IS_ASOC(iface)) + continue; + if (0) + RTW_INFO(ADPT_FMT": %u,%u,%u\n", ADPT_ARG(iface) + , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset); + } + + if (notify) + rtw_nlrtw_radio_opmode_notify(rfctl); + +#ifdef CONFIG_PLATFORM_CMAP_INTFS + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (!iface) + continue; + cmap_intfs_nl_bss_status_event(iface, 0); + } +#endif +} + +inline u8 rtw_rfctl_get_dfs_domain(struct rf_ctl_t *rfctl) +{ +#ifdef CONFIG_DFS_MASTER + return rfctl->dfs_region_domain; +#else + return RTW_DFS_REGD_NONE; +#endif +} + +inline u8 rtw_rfctl_dfs_domain_unknown(struct rf_ctl_t *rfctl) +{ +#ifdef CONFIG_DFS_MASTER + return rtw_rfctl_get_dfs_domain(rfctl) == RTW_DFS_REGD_NONE; +#else + return 1; +#endif } #ifdef CONFIG_DFS_MASTER @@ -364,11 +531,13 @@ bool rtw_is_cac_reset_needed(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset) needed = _TRUE; } else if (rtw_is_range_a_in_b(cur_hi, cur_lo, hi, lo)) { /* request is supper set of current */ - if ((hi != cur_hi && rtw_is_dfs_range(hi, cur_hi)) || (lo != cur_lo && rtw_is_dfs_range(cur_lo, lo))) + if ((hi != cur_hi && rtw_chset_is_dfs_range(rfctl->channel_set, hi, cur_hi)) + || (lo != cur_lo && rtw_chset_is_dfs_range(rfctl->channel_set, cur_lo, lo))) needed = _TRUE; } else { /* request is not supper set of current, but has overlap */ - if ((lo < cur_lo && rtw_is_dfs_range(cur_lo, lo)) || (hi > cur_hi && rtw_is_dfs_range(hi, cur_hi))) + if ((lo < cur_lo && rtw_chset_is_dfs_range(rfctl->channel_set, cur_lo, lo)) + || (hi > cur_hi && rtw_chset_is_dfs_range(rfctl->channel_set, hi, cur_hi))) needed = _TRUE; } @@ -497,10 +666,11 @@ exit: * @offset: bandwidth offset on which radar is detected * @ms: ms to add from now to update non_ocp_end_time, ms < 0 means use NON_OCP_TIME_MS */ -static void _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms) +static bool _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms) { u32 hi = 0, lo = 0; int i; + bool updated = 0; if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) goto exit; @@ -518,21 +688,84 @@ static void _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(ms); else ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(NON_OCP_TIME_MS); + ch_set[i].flags |= RTW_CHF_NON_OCP; + updated = 1; } } exit: - return; + return updated; } -inline void rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset) +inline bool rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset) { - _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, -1); + return _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, -1); } -inline void rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms) +inline bool rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms) { - _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, ms); + return _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, ms); +} + +static bool rtw_chset_chk_non_ocp_finish_for_chbw(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset) +{ + RT_CHANNEL_INFO *ch_set = rfctl->channel_set; + u8 cch; + u8 *op_chs; + u8 op_ch_num; + int i; + int ch_idx; + bool ret = 0; + + cch = rtw_get_center_ch(ch, bw, offset); + + if (!rtw_get_op_chs_by_cch_bw(cch, bw, &op_chs, &op_ch_num)) + goto exit; + + for (i = 0; i < op_ch_num; i++) { + if (0) + RTW_INFO("%u,%u,%u - cch:%u, bw:%u, op_ch:%u\n", ch, bw, offset, cch, bw, *(op_chs + i)); + ch_idx = rtw_chset_search_ch(ch_set, *(op_chs + i)); + if (ch_idx == -1) + break; + if (!(ch_set[ch_idx].flags & RTW_CHF_NON_OCP) || CH_IS_NON_OCP(&ch_set[ch_idx])) + break; + } + + if (op_ch_num != 0 && i == op_ch_num) { + ret = 1; + /* clear RTTW_CHF_NON_OCP flag */ + for (i = 0; i < op_ch_num; i++) { + ch_idx = rtw_chset_search_ch(ch_set, *(op_chs + i)); + ch_set[ch_idx].flags &= ~RTW_CHF_NON_OCP; + } + rtw_nlrtw_nop_finish_event(dvobj_get_primary_adapter(rfctl_to_dvobj(rfctl)), cch, bw); + } + +exit: + return ret; +} + +/* called by watchdog to clear RTW_CHF_NON_OCP and generate NON_OCP finish event */ +void rtw_chset_chk_non_ocp_finish(struct rf_ctl_t *rfctl) +{ + u8 ch, bw, offset; + int i; + + bw = CHANNEL_WIDTH_160; + while (1) { + for (i = 0; i < rfctl->max_chan_nums; i++) { + ch = rfctl->channel_set[i].ChannelNum; + if (!(rfctl->channel_set[i].flags & RTW_CHF_NON_OCP)) + continue; + if (!rtw_get_offset_by_chbw(ch, bw, &offset)) + continue; + + rtw_chset_chk_non_ocp_finish_for_chbw(rfctl, ch, bw, offset); + } + if (bw-- == CHANNEL_WIDTH_20) + break; + } } u32 rtw_get_ch_waiting_ms(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, u32 *r_non_ocp_ms, u32 *r_cac_ms) @@ -564,14 +797,14 @@ u32 rtw_get_ch_waiting_ms(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, u32 * in_rd_range = 1; } - if (!rtw_is_dfs_chbw(ch, bw, offset)) + if (!rtw_chset_is_dfs_chbw(rfctl->channel_set, ch, bw, offset)) cac_ms = 0; else if (in_rd_range && !non_ocp_ms) { if (IS_CH_WAITING(rfctl)) cac_ms = rtw_systime_to_ms(rfctl->cac_end_time - rtw_get_current_time()); else cac_ms = 0; - } else if (rtw_is_long_cac_ch(ch, bw, offset, rtw_odm_get_dfs_domain(dvobj))) + } else if (rtw_is_long_cac_ch(ch, bw, offset, rtw_rfctl_get_dfs_domain(rfctl))) cac_ms = CAC_TIME_CE_MS; else cac_ms = CAC_TIME_MS; @@ -643,7 +876,7 @@ u32 rtw_force_stop_cac(struct rf_ctl_t *rfctl, u32 timeout_ms) /* choose channel with shortest waiting (non ocp + cac) time */ bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw , u8 *dec_ch, u8 *dec_bw, u8 *dec_offset - , u8 d_flags, u8 cur_ch, bool by_int_info, u8 mesh_only) + , u8 e_flags, u8 d_flags, u8 cur_ch, bool by_int_info, u8 mesh_only) { #ifndef DBG_CHOOSE_SHORTEST_WAITING_CH #define DBG_CHOOSE_SHORTEST_WAITING_CH 0 @@ -664,8 +897,8 @@ bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw return _FALSE; } - RTW_INFO("%s: sel_ch:%u max_bw:%u d_flags:0x%02x cur_ch:%u within_sb:%d%s%s\n" - , __func__, sel_ch, max_bw, d_flags, cur_ch, rfctl->ch_sel_within_same_band + RTW_INFO("%s: sel_ch:%u max_bw:%u e_flags:0x%02x d_flags:0x%02x cur_ch:%u within_sb:%d%s%s\n" + , __func__, sel_ch, max_bw, e_flags, d_flags, cur_ch, rfctl->ch_sel_within_same_band , by_int_info ? " int" : "", mesh_only ? " mesh_only" : ""); /* full search and narrow bw judegement first to avoid potetial judegement timing issue */ @@ -678,6 +911,9 @@ bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw u32 cac_ms = 0; u32 waiting_ms = 0; u16 int_factor = 0; + bool dfs_ch; + bool non_ocp; + bool long_cac; ch = rfctl->channel_set[i].ChannelNum; if (sel_ch) { @@ -686,12 +922,6 @@ bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw } else if (rfctl->ch_sel_within_same_band && !rtw_is_same_band(cur_ch, ch)) continue; - if ((d_flags & RTW_CHF_2G) && ch <= 14) - continue; - - if ((d_flags & RTW_CHF_5G) && ch > 14) - continue; - if (ch > 14) { if (bw > REGSTY_BW_5G(regsty)) continue; @@ -706,23 +936,29 @@ bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw if (!rtw_get_offset_by_chbw(ch, bw, &offset)) continue; - if (!rtw_chset_is_chbw_valid(rfctl->channel_set, ch, bw, offset)) + if (!rtw_chset_is_chbw_valid(rfctl->channel_set, ch, bw, offset, 0, 0)) continue; - if ((d_flags & RTW_CHF_NON_OCP) && rtw_chset_is_chbw_non_ocp(rfctl->channel_set, ch, bw, offset)) - continue; + if ((e_flags & RTW_CHF_DFS) || (d_flags & RTW_CHF_DFS)) { + dfs_ch = rtw_chset_is_dfs_chbw(rfctl->channel_set, ch, bw, offset); + if (((e_flags & RTW_CHF_DFS) && !dfs_ch) + || ((d_flags & RTW_CHF_DFS) && dfs_ch)) + continue; + } - if ((d_flags & RTW_CHF_DFS) && rtw_is_dfs_chbw(ch, bw, offset)) - continue; + if ((e_flags & RTW_CHF_LONG_CAC) || (d_flags & RTW_CHF_LONG_CAC)) { + long_cac = rtw_is_long_cac_ch(ch, bw, offset, rtw_rfctl_get_dfs_domain(rfctl)); + if (((e_flags & RTW_CHF_LONG_CAC) && !long_cac) + || ((d_flags & RTW_CHF_LONG_CAC) && long_cac)) + continue; + } - if ((d_flags & RTW_CHF_LONG_CAC) && rtw_is_long_cac_ch(ch, bw, offset, rtw_odm_get_dfs_domain(dvobj))) - continue; - - if ((d_flags & RTW_CHF_NON_DFS) && !rtw_is_dfs_chbw(ch, bw, offset)) - continue; - - if ((d_flags & RTW_CHF_NON_LONG_CAC) && !rtw_is_long_cac_ch(ch, bw, offset, rtw_odm_get_dfs_domain(dvobj))) - continue; + if ((e_flags & RTW_CHF_NON_OCP) || (d_flags & RTW_CHF_NON_OCP)) { + non_ocp = rtw_chset_is_chbw_non_ocp(rfctl->channel_set, ch, bw, offset); + if (((e_flags & RTW_CHF_NON_OCP) && !non_ocp) + || ((d_flags & RTW_CHF_NON_OCP) && non_ocp)) + continue; + } #ifdef CONFIG_DFS_MASTER waiting_ms = rtw_get_ch_waiting_ms(rfctl, ch, bw, offset, &non_ocp_ms, &cac_ms); @@ -777,29 +1013,43 @@ bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw return _FALSE; } -void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set) +#ifdef CONFIG_PROC_DEBUG +#define RTW_CHF_FMT "%s%s%s%s%s%s" + +#define RTW_CHF_ARG_NO_IR(flags) (flags & RTW_CHF_NO_IR) ? " NO_IR" : "" +#define RTW_CHF_ARG_DFS(flags) , (flags & RTW_CHF_DFS) ? " DFS" : "" +#define RTW_CHF_ARG_NO_HT40U(flags) , (flags & RTW_CHF_NO_HT40U) ? " NO_40M+" : "" +#define RTW_CHF_ARG_NO_HT40L(flags) , (flags & RTW_CHF_NO_HT40L) ? " NO_40M-" : "" +#define RTW_CHF_ARG_NO_80MHZ(flags) , (flags & RTW_CHF_NO_80MHZ) ? " NO_80M" : "" +#define RTW_CHF_ARG_NO_160MHZ(flags) , (flags & RTW_CHF_NO_160MHZ) ? " NO_160M" : "" + +#define RTW_CHF_ARG(flags) \ + RTW_CHF_ARG_NO_IR(flags) \ + RTW_CHF_ARG_DFS(flags) \ + RTW_CHF_ARG_NO_HT40U(flags) \ + RTW_CHF_ARG_NO_HT40L(flags) \ + RTW_CHF_ARG_NO_80MHZ(flags) \ + RTW_CHF_ARG_NO_160MHZ(flags) + +void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set, u8 chset_num) { - u8 i; + char buf[8]; + u8 i; - for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) { - RTW_PRINT_SEL(sel, "ch:%3u, freq:%u, scan_type:%d" - , ch_set[i].ChannelNum, rtw_ch2freq(ch_set[i].ChannelNum), ch_set[i].ScanType); + RTW_PRINT_SEL(sel, "%-3s %-4s %-4s flags\n", "ch", "freq", "nocp"); -#ifdef CONFIG_FIND_BEST_CHANNEL - _RTW_PRINT_SEL(sel, ", rx_count:%u", ch_set[i].rx_count); -#endif + for (i = 0; i < MAX_CHANNEL_NUM && i < chset_num && ch_set[i].ChannelNum != 0; i++) { + #ifdef CONFIG_DFS_MASTER + if ((ch_set[i].flags & RTW_CHF_DFS) && CH_IS_NON_OCP(&ch_set[i])) + snprintf(buf, 8, "%d", rtw_systime_to_ms(ch_set[i].non_ocp_end_time - rtw_get_current_time()) / 1000); + else + #endif + snprintf(buf, 8, "0"); -#ifdef CONFIG_DFS_MASTER - if (rtw_is_dfs_ch(ch_set[i].ChannelNum)) { - if (CH_IS_NON_OCP(&ch_set[i])) - _RTW_PRINT_SEL(sel, ", non_ocp:%d" - , rtw_systime_to_ms(ch_set[i].non_ocp_end_time - rtw_get_current_time())); - else - _RTW_PRINT_SEL(sel, ", non_ocp:N/A"); - } -#endif - - _RTW_PRINT_SEL(sel, "\n"); + RTW_PRINT_SEL(sel, "%3u %4u %4s"RTW_CHF_FMT"\n" + , ch_set[i].ChannelNum, rtw_ch2freq(ch_set[i].ChannelNum), buf + , RTW_CHF_ARG(ch_set[i].flags) + ); } RTW_PRINT_SEL(sel, "total ch number:%d\n", i); @@ -809,19 +1059,25 @@ void dump_cur_chset(void *sel, struct rf_ctl_t *rfctl) { struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl); struct registry_priv *regsty = dvobj_to_regsty(dvobj); + struct get_chplan_resp *chplan; int i; - if (rfctl->country_ent) - dump_country_chplan(sel, rfctl->country_ent); + if (rtw_get_chplan_cmd(dvobj_get_primary_adapter(dvobj), RTW_CMDF_WAIT_ACK, &chplan) == _FAIL) + return; + + RTW_PRINT_SEL(sel, "regd_src:%s(%d)\n", regd_src_str(chplan->regd_src), chplan->regd_src); + + if (chplan->has_country) + dump_country_chplan(sel, &chplan->country_ent); else - RTW_PRINT_SEL(sel, "chplan:0x%02X\n", rfctl->ChannelPlan); + RTW_PRINT_SEL(sel, "chplan:0x%02X\n", chplan->channel_plan); #if CONFIG_TXPWR_LIMIT - RTW_PRINT_SEL(sel, "PLS regd:%s\n", rfctl->regd_name); + RTW_PRINT_SEL(sel, "PLS regd:%s\n", chplan->regd_name); #endif #ifdef CONFIG_DFS_MASTER - RTW_PRINT_SEL(sel, "dfs_domain:%u\n", rtw_odm_get_dfs_domain(dvobj)); + RTW_PRINT_SEL(sel, "dfs_domain:%s(%u)\n", rtw_dfs_regd_str(chplan->dfs_domain), chplan->dfs_domain); #endif for (i = 0; i < MAX_CHANNEL_NUM; i++) @@ -838,8 +1094,11 @@ void dump_cur_chset(void *sel, struct rf_ctl_t *rfctl) _RTW_PRINT_SEL(sel, "\n"); } - dump_chset(sel, rfctl->channel_set); + dump_chset(sel, chplan->chset, chplan->chset_num); + + rtw_vmfree(chplan, sizeof(struct get_chplan_resp) + sizeof(RT_CHANNEL_INFO) * chplan->chset_num); } +#endif /* * Search the @param ch in given @param ch_set @@ -872,13 +1131,15 @@ int rtw_chset_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch) * * return valid (1) or not (0) */ -u8 rtw_chset_is_chbw_valid(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset) +u8 rtw_chset_is_chbw_valid(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset + , bool allow_primary_passive, bool allow_passive) { u8 cch; u8 *op_chs; u8 op_ch_num; u8 valid = 0; int i; + int ch_idx; cch = rtw_get_center_ch(ch, bw, offset); @@ -888,7 +1149,23 @@ u8 rtw_chset_is_chbw_valid(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset) for (i = 0; i < op_ch_num; i++) { if (0) RTW_INFO("%u,%u,%u - cch:%u, bw:%u, op_ch:%u\n", ch, bw, offset, cch, bw, *(op_chs + i)); - if (rtw_chset_search_ch(ch_set, *(op_chs + i)) == -1) + ch_idx = rtw_chset_search_ch(ch_set, *(op_chs + i)); + if (ch_idx == -1) + break; + if (ch_set[ch_idx].flags & RTW_CHF_NO_IR) { + if ((!allow_primary_passive && ch_set[ch_idx].ChannelNum == ch) + || (!allow_passive && ch_set[ch_idx].ChannelNum != ch)) + break; + } + if (bw >= CHANNEL_WIDTH_40) { + if ((ch_set[ch_idx].flags & RTW_CHF_NO_HT40U) && i % 2 == 0) + break; + if ((ch_set[ch_idx].flags & RTW_CHF_NO_HT40L) && i % 2 == 1) + break; + } + if (bw >= CHANNEL_WIDTH_80 && (ch_set[ch_idx].flags & RTW_CHF_NO_80MHZ)) + break; + if (bw >= CHANNEL_WIDTH_160 && (ch_set[ch_idx].flags & RTW_CHF_NO_160MHZ)) break; } @@ -908,9 +1185,11 @@ exit: * @g_ch: pointer of the ongoing group ch * @g_bw: pointer of the ongoing group bw, may be modified further * @g_offset: pointer of the ongoing group offset, may be modified further + * @allow_primary_passive: if allow passive primary ch when deciding chbw + * @allow_passive: if allow passive ch (not primary) when deciding chbw */ void rtw_chset_sync_chbw(RT_CHANNEL_INFO *ch_set, u8 *req_ch, u8 *req_bw, u8 *req_offset - , u8 *g_ch, u8 *g_bw, u8 *g_offset) + , u8 *g_ch, u8 *g_bw, u8 *g_offset, bool allow_primary_passive, bool allow_passive) { u8 r_ch, r_bw, r_offset; u8 u_ch, u_bw, u_offset; @@ -926,7 +1205,7 @@ void rtw_chset_sync_chbw(RT_CHANNEL_INFO *ch_set, u8 *req_ch, u8 *req_bw, u8 *re rtw_sync_chbw(&r_ch, &r_bw, &r_offset, &u_ch, &u_bw, &u_offset); - if (rtw_chset_is_chbw_valid(ch_set, r_ch, r_bw, r_offset)) + if (rtw_chset_is_chbw_valid(ch_set, r_ch, r_bw, r_offset, allow_primary_passive, allow_passive)) break; if (cur_bw == CHANNEL_WIDTH_20) { rtw_warn_on(1); @@ -1095,7 +1374,11 @@ static void init_mlme_ext_priv_value(_adapter *padapter) #ifdef CONFIG_SCAN_BACKOP mlmeext_assign_scan_backop_flags_sta(pmlmeext, /*SS_BACKOP_EN|*/SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME); #ifdef CONFIG_AP_MODE - mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME); + #ifdef CONFIG_CUSTOMER_EZVIZ_CHIME2 + mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME | SS_BACKOP_EN_NL); + #else + mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME); + #endif #endif #ifdef CONFIG_RTW_MESH mlmeext_assign_scan_backop_flags_mesh(pmlmeext, /*SS_BACKOP_EN | */SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME); @@ -1155,6 +1438,9 @@ void init_mlme_ext_timer(_adapter *padapter) rtw_init_timer(&pmlmeext->tbtx_xmit_timer, padapter, rtw_tbtx_xmit_timer_hdl, padapter); rtw_init_timer(&pmlmeext->tbtx_token_dispatch_timer, padapter, rtw_tbtx_token_dispatch_timer_hdl, padapter); #endif +#ifdef CONFIG_DFS + rtw_init_timer(&pmlmeext->csa_timer, padapter->pnetdev, csa_timer_hdl, padapter); +#endif } int init_mlme_ext_priv(_adapter *padapter) @@ -1226,6 +1512,9 @@ void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext) if (rtw_is_drv_stopped(padapter)) { _cancel_timer_ex(&pmlmeext->survey_timer); _cancel_timer_ex(&pmlmeext->link_timer); +#ifdef CONFIG_DFS + _cancel_timer_ex(&pmlmeext->csa_timer); +#endif /* CONFIG_DFS */ } } @@ -1377,7 +1666,7 @@ void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame) ptable->func = &OnAuth; else ptable->func = &OnAuthClient; - /* pass through */ + /* fall through */ case WIFI_ASSOCREQ: case WIFI_REASSOCREQ: _mgt_dispatcher(padapter, ptable, precv_frame); @@ -1484,7 +1773,6 @@ unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame) struct sta_priv *pstapriv = &padapter->stapriv; #endif - #ifdef CONFIG_P2P struct wifidirect_info *pwdinfo = &(padapter->wdinfo); struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; @@ -1814,18 +2102,17 @@ unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame) } /* for 11n Logo 4.2.31/4.2.32 */ +#ifdef CONFIG_AP_MODE static void rtw_check_legacy_ap(_adapter *padapter, u8 *pframe, u32 len) { - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if (!padapter->registrypriv.wifi_spec) return; - + if(!MLME_IS_AP(padapter)) return; - if (pmlmeext->bstart_bss == _TRUE) { int left; @@ -1853,9 +2140,9 @@ static void rtw_check_legacy_ap(_adapter *padapter, u8 *pframe, u32 len) ATOMIC_SET(&pmlmepriv->olbc, _TRUE); ATOMIC_SET(&pmlmepriv->olbc_ht, _TRUE); } - } } +#endif /* CONFIG_AP_MODE */ unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame) { @@ -1899,7 +2186,9 @@ unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame) rtw_mi_report_survey_event(padapter, precv_frame); #endif +#ifdef CONFIG_AP_MODE rtw_check_legacy_ap(padapter, pframe, len); +#endif if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) { if ((pmlmeinfo->state & WIFI_FW_AUTH_NULL) @@ -2085,6 +2374,7 @@ _END_ONBEACON_: } +#ifdef CONFIG_AP_MODE static u32 rtw_get_sta_num_by_state(_adapter *padapter, u32 state) { _irqL irqL; @@ -2129,6 +2419,7 @@ static u8 rtw_defs_attack_chk(_adapter *padapter) /* RTW_INFO("%s : current linking num=%u\n", __func__, sta_limit); */ return is_reject; } +#endif unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame) { @@ -2420,7 +2711,7 @@ auth_fail: issue_auth(padapter, pstat, (unsigned short)status); #endif -#endif +#endif /* CONFIG_AP_MODE */ return _FAIL; } @@ -2741,6 +3032,8 @@ unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame) pstat->p2p_status_code = p2p_status_code; #endif /* CONFIG_P2P */ + rtw_ap_parse_sta_multi_ap_ie(padapter, pstat, pos, left); + #ifdef CONFIG_RTW_REPEATER_SON if (rtw_rson_ap_check_sta(padapter, pframe, pkt_len, ie_offset)) goto OnAssocReqFail; @@ -3228,6 +3521,9 @@ unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame) RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM\n" , FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe)); + #ifdef CONFIG_RTW_WNM + if (rtw_wnm_try_btm_roam_imnt(padapter) > 0) + #endif receive_disconnect(padapter, get_addr2_ptr(pframe), reason, _FALSE); } pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE; @@ -3386,12 +3682,42 @@ unsigned int on_action_wnm(_adapter *adapter, union recv_frame *rframe) #ifdef CONFIG_RTW_80211R case RTW_WLAN_ACTION_WNM_BTM_REQ: if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) { - RTW_INFO("WNM: RTW_WLAN_ACTION_WNM_BTM_REQ recv.\n"); + RTW_INFO("WNM: BSS Transition Management Request recv.\n"); rtw_wnm_process_btm_req(adapter, frame_body, frame_body_len); } ret = _SUCCESS; break; -#endif +#endif + case RTW_WLAN_ACTION_WNM_BTM_RSP: + if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) && + (pmlmepriv->nb_info.features & RTW_WNM_FEATURE_BTM_REQ_EN)) { + struct btm_rsp_hdr rsp; + u32 sz; + + RTW_INFO("WNM: BSS Transition Management Response recv.\n"); + sz = rtw_wnm_btm_rsp_candidates_sz_get(adapter, + frame_body, frame_body_len); + _rtw_memset(&rsp, 0, sizeof(rsp)); + + if (sz > 0) + rsp.pcandidates = rtw_zmalloc(sz); + + rtw_wnm_process_btm_rsp(adapter, frame_body, frame_body_len, &rsp); + /* TODO : handle candidates info in rsp.pcandidates for upper-layer services */ + #ifdef CONFIG_PLATFORM_CMAP_INTFS + cmap_intfs_nl_btm_resp_event(adapter, sta->cmn.mac_addr, + adapter_mac_addr(adapter), + rsp.status, rsp.bssid, + rsp.pcandidates, + rsp.candidates_num); + #endif + if (0 && rsp.pcandidates && (rsp.candidates_num > 0)) + RTW_INFO_DUMP("pcandidates : ", rsp.pcandidates, sz); + + if ((sz > 0) && (rsp.pcandidates != NULL)) + rtw_mfree(rsp.pcandidates, sz); + } + /* fall through */ default: #ifdef CONFIG_IOCTL_CFG80211 cnt += sprintf((msg + cnt), "ACT_WNM %u", action); @@ -3695,7 +4021,7 @@ u16 rtw_rx_ampdu_apply(_adapter *adapter) adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, sta_size); } /* TODO: TDLS peer */ - +#ifdef CONFIG_AP_MODE } else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) { _irqL irqL; _list *phead, *plist; @@ -3732,6 +4058,7 @@ u16 rtw_rx_ampdu_apply(_adapter *adapter) adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, sta_size); } } +#endif /* CONFIG_AP_MODE */ } /* TODO: ADHOC */ @@ -3808,7 +4135,7 @@ unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame) status = RTW_GET_LE16(&frame_body[3]); tid = ((frame_body[5] >> 2) & 0x7); if (status == 0) { - /* successful */ + /* successful */ RTW_INFO("agg_enable for TID=%d\n", tid); psta->htpriv.agg_enable_bitmap |= 1 << tid; psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); @@ -3824,12 +4151,14 @@ unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame) } else psta->htpriv.agg_enable_bitmap &= ~BIT(tid); + #ifdef CONFIG_AP_MODE if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { RTW_INFO("%s alive check - rx ADDBA response\n", __func__); psta->htpriv.agg_enable_bitmap &= ~BIT(tid); psta->expire_to = pstapriv->expire_to; psta->state ^= WIFI_STA_ALIVE_CHK_STATE; } + #endif /* RTW_INFO("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap); */ break; @@ -6315,6 +6644,9 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame) u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; u8 *merged_p2pie = NULL; u32 merged_p2p_ielen = 0; +#ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#endif #endif /* CONFIG_P2P */ frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); @@ -6351,7 +6683,7 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame) } #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE)) - _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer); + _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer); #endif /* CONFIG_CONCURRENT_MODE */ /* Commented by Kurt 20110902 */ @@ -6715,8 +7047,9 @@ unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame) u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); u8 category, action; - /* check RA matches or not */ - if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN)) + /* check RA matches or broadcast */ + if (!(_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN) || + is_broadcast_mac_addr(GetAddr1Ptr(pframe)))) goto exit; category = frame_body[0]; @@ -6746,249 +7079,6 @@ exit: return ret; } -#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) -static u8 rtw_wnm_nb_elem_parsing( - u8* pdata, u32 data_len, u8 from_btm, - u32 *nb_rpt_num, u8 *nb_rpt_is_same, - struct roam_nb_info *pnb, struct wnm_btm_cant *pcandidates) -{ - u8 bfound = _FALSE, ret = _SUCCESS; - u8 *ptr, *pend, *op; - u32 elem_len, subelem_len, op_len; - u32 i, nb_rpt_entries = 0; - struct nb_rpt_hdr *pie; - struct wnm_btm_cant *pcandidate; - - if ((!pdata) || (!pnb)) - return _FAIL; - - if ((from_btm) && (!pcandidates)) - return _FAIL; - - ptr = pdata; - pend = ptr + data_len; - elem_len = data_len; - subelem_len = (u32)*(pdata+1); - - for (i=0; i < RTW_MAX_NB_RPT_NUM; i++) { - if (((ptr + 7) > pend) || (elem_len < subelem_len)) - break; - - if (*ptr != 0x34) { - RTW_ERR("WNM: invalid data(0x%2x)!\n", *ptr); - ret = _FAIL; - break; - } - - pie = (struct nb_rpt_hdr *)ptr; - if (from_btm) { - op = rtw_get_ie((u8 *)(ptr+15), - WNM_BTM_CAND_PREF_SUBEID, - &op_len, (subelem_len - 15)); - } - - ptr = (u8 *)(ptr + subelem_len + 2); - elem_len -= (subelem_len +2); - subelem_len = *(ptr+1); - if (from_btm) { - pcandidate = (pcandidates + i); - _rtw_memcpy(&pcandidate->nb_rpt, pie, sizeof(struct nb_rpt_hdr)); - if (op && (op_len !=0)) { - pcandidate->preference = *(op + 2); - bfound = _TRUE; - } else - pcandidate->preference = 0; - - RTW_DBG("WNM: preference check bssid("MAC_FMT - ") ,bss_info(0x%04X), reg_class(0x%02X), ch(%d)," - " phy_type(0x%02X), preference(0x%02X)\n", - MAC_ARG(pcandidate->nb_rpt.bssid), pcandidate->nb_rpt.bss_info, - pcandidate->nb_rpt.reg_class, pcandidate->nb_rpt.ch_num, - pcandidate->nb_rpt.phy_type, pcandidate->preference); - } else { - if (_rtw_memcmp(&pnb->nb_rpt[i], pie, sizeof(struct nb_rpt_hdr)) == _FALSE) - *nb_rpt_is_same = _FALSE; - _rtw_memcpy(&pnb->nb_rpt[i], pie, sizeof(struct nb_rpt_hdr)); - } - nb_rpt_entries++; - } - - if (from_btm) - pnb->preference_en = (bfound)?_TRUE:_FALSE; - - *nb_rpt_num = nb_rpt_entries; - return ret; -} - -/* selection sorting based on preference value - * : nb_rpt_entries - candidate num - * / : pcandidates - candidate list - * return : TRUE - means pcandidates is updated. - */ -static u8 rtw_wnm_candidates_sorting( - u32 nb_rpt_entries, struct wnm_btm_cant *pcandidates) -{ - u8 updated = _FALSE; - u32 i, j, pos; - struct wnm_btm_cant swap; - struct wnm_btm_cant *pcant_1, *pcant_2; - - if ((!nb_rpt_entries) || (!pcandidates)) - return updated; - - for (i=0; i < (nb_rpt_entries - 1); i++) { - pos = i; - for (j=(i + 1); j < nb_rpt_entries; j++) { - pcant_1 = pcandidates+pos; - pcant_2 = pcandidates+j; - if ((pcant_1->preference) < (pcant_2->preference)) - pos = j; - } - - if (pos != i) { - updated = _TRUE; - _rtw_memcpy(&swap, (pcandidates+i), sizeof(struct wnm_btm_cant)); - _rtw_memcpy((pcandidates+i), (pcandidates+pos), sizeof(struct wnm_btm_cant)); - _rtw_memcpy((pcandidates+pos), &swap, sizeof(struct wnm_btm_cant)); - } - } - return updated; -} - -static void rtw_wnm_nb_info_update( - u32 nb_rpt_entries, u8 from_btm, - struct roam_nb_info *pnb, struct wnm_btm_cant *pcandidates, - u8 *nb_rpt_is_same) -{ - u8 is_found; - u32 i, j; - struct wnm_btm_cant *pcand; - - if (!pnb) - return; - - pnb->nb_rpt_ch_list_num = 0; - for (i=0; inb_rpt[i], &pcand->nb_rpt, - sizeof(struct nb_rpt_hdr)) == _FALSE) - *nb_rpt_is_same = _FALSE; - _rtw_memcpy(&pnb->nb_rpt[i], &pcand->nb_rpt, sizeof(struct nb_rpt_hdr)); - } - - RTW_DBG("WNM: bssid(" MAC_FMT - ") , bss_info(0x%04X), reg_class(0x%02X), ch_num(%d), phy_type(0x%02X)\n", - MAC_ARG(pnb->nb_rpt[i].bssid), pnb->nb_rpt[i].bss_info, - pnb->nb_rpt[i].reg_class, pnb->nb_rpt[i].ch_num, - pnb->nb_rpt[i].phy_type); - - if (pnb->nb_rpt[i].ch_num == 0) - continue; - - for (j=0; jnb_rpt[i].ch_num == pnb->nb_rpt_ch_list[j].hw_value) { - is_found = _TRUE; - break; - } - } - - if (!is_found) { - pnb->nb_rpt_ch_list[pnb->nb_rpt_ch_list_num].hw_value = pnb->nb_rpt[i].ch_num; - pnb->nb_rpt_ch_list_num++; - } - } -} - -static void rtw_wnm_btm_candidate_select(_adapter *padapter) -{ - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); - struct wlan_network *pnetwork; - u8 bfound = _FALSE; - u32 i; - - for (i = 0; i < pnb->last_nb_rpt_entries; i++) { - pnetwork = rtw_find_network( - &(pmlmepriv->scanned_queue), - pnb->nb_rpt[i].bssid); - - if (pnetwork) { - bfound = _TRUE; - break; - } - } - - if (bfound) { - _rtw_memcpy(pnb->roam_target_addr, pnb->nb_rpt[i].bssid, ETH_ALEN); - RTW_INFO("WNM : select btm entry(%d) - %s("MAC_FMT", ch%u) rssi:%d\n" - , i - , pnetwork->network.Ssid.Ssid - , MAC_ARG(pnetwork->network.MacAddress) - , pnetwork->network.Configuration.DSConfig - , (int)pnetwork->network.Rssi); - } else - _rtw_memset(pnb->roam_target_addr,0, ETH_ALEN); -} - -u32 rtw_wnm_btm_candidates_survey( - _adapter *padapter, u8* pframe, u32 elem_len, u8 from_btm) -{ - struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); - struct wnm_btm_cant *pcandidate_list = NULL; - u8 nb_rpt_is_same = _TRUE; - u32 ret = _FAIL; - u32 nb_rpt_entries = 0; - - if (from_btm) { - u32 mlen = sizeof(struct wnm_btm_cant) * RTW_MAX_NB_RPT_NUM; - pcandidate_list = (struct wnm_btm_cant *)rtw_malloc(mlen); - if (pcandidate_list == NULL) - goto exit; - } - - /*clean the status set last time*/ - _rtw_memset(&pnb->nb_rpt_ch_list, 0, sizeof(pnb->nb_rpt_ch_list)); - pnb->nb_rpt_valid = _FALSE; - if (!rtw_wnm_nb_elem_parsing( - pframe, elem_len, from_btm, - &nb_rpt_entries, &nb_rpt_is_same, - pnb, pcandidate_list)) - goto exit; - - if (nb_rpt_entries != 0) { - if ((from_btm) && (rtw_wnm_btm_preference_cap(padapter))) - rtw_wnm_candidates_sorting(nb_rpt_entries, pcandidate_list); - - rtw_wnm_nb_info_update( - nb_rpt_entries, from_btm, - pnb, pcandidate_list, &nb_rpt_is_same); - } - - RTW_INFO("nb_rpt_is_same = %d, nb_rpt_entries = %d, last_nb_rpt_entries = %d\n", - nb_rpt_is_same, nb_rpt_entries, pnb->last_nb_rpt_entries); - if ((nb_rpt_is_same == _TRUE) && (nb_rpt_entries == pnb->last_nb_rpt_entries)) - pnb->nb_rpt_is_same = _TRUE; - else { - pnb->nb_rpt_is_same = _FALSE; - pnb->last_nb_rpt_entries = nb_rpt_entries; - } - - if ((from_btm) && (nb_rpt_entries != 0)) - rtw_wnm_btm_candidate_select(padapter); - - pnb->nb_rpt_valid = _TRUE; - ret = _SUCCESS; - -exit: - if (from_btm && pcandidate_list) - rtw_mfree((u8 *)pcandidate_list, sizeof(struct wnm_btm_cant) * RTW_MAX_NB_RPT_NUM); - - return ret; -} -#endif - unsigned int OnAction_ft(_adapter *padapter, union recv_frame *precv_frame) { #ifdef CONFIG_RTW_80211R @@ -6998,7 +7088,7 @@ unsigned int OnAction_ft(_adapter *padapter, union recv_frame *precv_frame) u8 category = 0; u8 *pframe = NULL; u8 *pframe_body = NULL; - u8 sta_addr[ETH_ALEN] = {0}; + u8 tgt_addr[ETH_ALEN]; u8 *pie = NULL; u32 ft_ie_len = 0; u32 status_code = 0; @@ -7036,8 +7126,9 @@ unsigned int OnAction_ft(_adapter *padapter, union recv_frame *precv_frame) goto exit; } - if (is_zero_mac_addr(&pframe_body[8]) || is_broadcast_mac_addr(&pframe_body[8])) { - RTW_ERR("FT: Invalid Target MAC Address "MAC_FMT"\n", MAC_ARG(padapter->mlmepriv.roam_tgt_addr)); + _rtw_memcpy(tgt_addr, &pframe_body[8], ETH_ALEN); + if (is_zero_mac_addr(tgt_addr) || is_broadcast_mac_addr(tgt_addr)) { + RTW_ERR("FT: Invalid Target MAC Address "MAC_FMT"\n", MAC_ARG(tgt_addr)); goto exit; } @@ -7074,238 +7165,6 @@ exit: #endif } -#ifdef CONFIG_RTW_WNM -u8 rtw_wmn_btm_rsp_reason_decision(_adapter *padapter, u8* req_mode) -{ - struct recv_priv *precvpriv = &padapter->recvpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 reason = 0; - - if (!rtw_wnm_btm_diff_bss(padapter)) { - /* Reject - No suitable BSS transition candidates */ - reason = 7; - goto candidate_remove; - } - -#ifdef CONFIG_RTW_80211R - if (rtw_ft_chk_flags(padapter, RTW_FT_BTM_ROAM)) { - /* Accept */ - reason = 0; - goto under_survey; - } -#endif - - if (((*req_mode) & DISASSOC_IMMINENT) == 0) { - /* Reject - Unspecified reject reason */ - reason = 1; - goto candidate_remove; - } - - if (precvpriv->signal_strength_data.avg_val >= pmlmepriv->roam_rssi_threshold) { - reason = 1; - goto candidate_remove; - } - -under_survey: - if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)) { - RTW_INFO("%s reject due to WIFI_UNDER_SURVEY\n", __func__); - reason = 1; - } - -candidate_remove: - if (reason !=0) - rtw_wnm_reset_btm_candidate(&padapter->mlmepriv.nb_info); - - return reason; -} - -static u32 rtw_wnm_btm_candidates_offset_get(u8* pframe) -{ - u8 *pos = pframe; - u32 offset = 0; - - if (!pframe) - return 0; - - offset += 7; - pos += offset; - - /* BSS Termination Duration check */ - if (wnm_btm_bss_term_inc(pframe)) { - offset += 12; - pos += offset; - } - - /* Session Information URL check*/ - if (wnm_btm_ess_disassoc_im(pframe)) { - /*URL length field + URL variable length*/ - offset = 1 + *(pframe + offset); - pos += offset; - } - - offset = (pos - pframe); - return offset; -} - -static void rtw_wnm_btm_req_hdr_parsing(u8* pframe, struct btm_req_hdr *phdr) -{ - u8 *pos = pframe; - u32 offset = 0; - - if (!pframe || !phdr) - return; - - _rtw_memset(phdr, 0, sizeof(struct btm_req_hdr)); - phdr->req_mode = wnm_btm_req_mode(pframe); - phdr->disassoc_timer = wnm_btm_disassoc_timer(pframe); - phdr->validity_interval = wnm_btm_valid_interval(pframe); - if (wnm_btm_bss_term_inc(pframe)) { - _rtw_memcpy(&phdr->term_duration, - wnm_btm_term_duration_offset(pframe), - sizeof(struct btm_term_duration)); - } - - RTW_DBG("WNM: req_mode(%1x), disassoc_timer(%02x), interval(%x)\n", - phdr->req_mode, phdr->disassoc_timer, phdr->validity_interval); - if (wnm_btm_bss_term_inc(pframe)) - RTW_INFO("WNM: tsf(%llx), duration(%2x)\n", - phdr->term_duration.tsf, phdr->term_duration.duration); -} - -void rtw_wnm_roam_scan_hdl(void *ctx) -{ - _adapter *padapter = (_adapter *)ctx; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - - if (rtw_is_scan_deny(padapter)) - RTW_INFO("WNM: roam scan would abort by scan_deny!\n"); - - pmlmepriv->need_to_roam = _TRUE; - rtw_drv_scan_by_self(padapter, RTW_AUTO_SCAN_REASON_ROAM); -} - -static void rtw_wnm_roam_scan(_adapter *padapter) -{ - struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); - - if (rtw_is_scan_deny(padapter)) { - _cancel_timer_ex(&pnb->roam_scan_timer); - _set_timer(&pnb->roam_scan_timer, 1000); - } else - rtw_wnm_roam_scan_hdl((void *)padapter); -} - -void rtw_wnm_process_btm_req(_adapter *padapter, u8* pframe, u32 frame_len) -{ - struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); - struct btm_req_hdr req_hdr; - u8 *ptr, reason; - u32 elem_len, offset; - - rtw_wnm_btm_req_hdr_parsing(pframe, &req_hdr); - offset = rtw_wnm_btm_candidates_offset_get(pframe); - if ((offset == 0) || ((frame_len - offset) <= 15)) - return; - - ptr = (pframe + offset); - elem_len = (frame_len - offset); - rtw_wnm_btm_candidates_survey(padapter, ptr, elem_len, _TRUE); - reason = rtw_wmn_btm_rsp_reason_decision(padapter, &pframe[3]); - rtw_wnm_issue_action(padapter, - RTW_WLAN_ACTION_WNM_BTM_RSP, reason); - - if (reason == 0) - rtw_wnm_roam_scan(padapter); -} - -void rtw_wnm_reset_btm_candidate(struct roam_nb_info *pnb) -{ - pnb->preference_en = _FALSE; - _rtw_memset(pnb->roam_target_addr, 0, ETH_ALEN); -} - -void rtw_wnm_reset_btm_state(_adapter *padapter) -{ - struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); - - pnb->last_nb_rpt_entries = 0; - pnb->nb_rpt_is_same = _TRUE; - pnb->nb_rpt_valid = _FALSE; - pnb->nb_rpt_ch_list_num = 0; - rtw_wnm_reset_btm_candidate(pnb); - _rtw_memset(&pnb->nb_rpt, 0, sizeof(pnb->nb_rpt)); - _rtw_memset(&pnb->nb_rpt_ch_list, 0, sizeof(pnb->nb_rpt_ch_list)); -} - -void rtw_wnm_issue_action(_adapter *padapter, u8 action, u8 reason) -{ - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct xmit_frame *pmgntframe; - struct rtw_ieee80211_hdr *pwlanhdr; - struct pkt_attrib *pattrib; - u8 category, dialog_token, termination_delay, *pframe; - u16 *fctrl; - - if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) - return ; - - pattrib = &(pmgntframe->attrib); - update_mgntframe_attrib(padapter, pattrib); - _rtw_memset(pmgntframe->buf_addr, 0, (WLANHDR_OFFSET + TXDESC_OFFSET)); - - pframe = (u8 *)(pmgntframe->buf_addr + TXDESC_OFFSET); - pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; - - fctrl = &(pwlanhdr->frame_ctl); - *(fctrl) = 0; - - _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); - - SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); - pmlmeext->mgnt_seq++; - set_frame_sub_type(pframe, WIFI_ACTION); - - pframe += sizeof(struct rtw_ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); - - category = RTW_WLAN_CATEGORY_WNM; - pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); - pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); - - switch (action) { - case RTW_WLAN_ACTION_WNM_BTM_QUERY: - pframe = rtw_set_fixed_ie(pframe, 1, &(dialog_token), &(pattrib->pktlen)); - pframe = rtw_set_fixed_ie(pframe, 1, &(reason), &(pattrib->pktlen)); - RTW_INFO("WNM: RTW_WLAN_ACTION_WNM_BTM_QUERY sent.\n"); - break; - case RTW_WLAN_ACTION_WNM_BTM_RSP: - termination_delay = 0; - pframe = rtw_set_fixed_ie(pframe, 1, &(dialog_token), &(pattrib->pktlen)); - pframe = rtw_set_fixed_ie(pframe, 1, &(reason), &(pattrib->pktlen)); - pframe = rtw_set_fixed_ie(pframe, 1, &(termination_delay), &(pattrib->pktlen)); - if (!is_zero_mac_addr(pmlmepriv->nb_info.roam_target_addr)) { - pframe = rtw_set_fixed_ie(pframe, 6, - pmlmepriv->nb_info.roam_target_addr, &(pattrib->pktlen)); - } - RTW_INFO("WNM: RTW_WLAN_ACTION_WNM_BTM_RSP sent. reason = %d\n", reason); - break; - default: - goto exit; - } - - pattrib->last_txcmdsz = pattrib->pktlen; - dump_mgntframe(padapter, pmgntframe); - -exit: - return; -} -#endif - unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame) { u8 *pframe = precv_frame->u.hdr.rx_data; @@ -7811,12 +7670,35 @@ void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib) } +#ifdef CONFIG_RTW_MGMT_QUEUE +void update_mgntframe_subtype(_adapter *padapter, struct xmit_frame *pmgntframe) +{ + struct pkt_attrib *pattrib = &pmgntframe->attrib; + u8 *pframe; + u8 subtype, category ,action; + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + subtype = get_frame_sub_type(pframe); /* bit(7)~bit(2) */ + pattrib->subtype = subtype; + + rtw_action_frame_parse(pframe, pattrib->pktlen, &category, &action); + + if ((subtype == WIFI_ACTION && !(action == ACT_PUBLIC_FTM_REQ || action == ACT_PUBLIC_FTM)) || + subtype == WIFI_DISASSOC || subtype == WIFI_DEAUTH || + (subtype == WIFI_PROBERSP && MLME_IS_ADHOC(padapter))) + pattrib->ps_dontq = 0; + else + pattrib->ps_dontq = 1; +} +#endif void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib) { u8 wireless_mode; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta; #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP struct wifidirect_info *pwdinfo = &(padapter->wdinfo); @@ -7844,8 +7726,6 @@ void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib) struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); - struct sta_priv *pstapriv = &padapter->stapriv; - struct sta_info *psta; psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress); if (psta) { @@ -7860,7 +7740,6 @@ void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib) } #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */ - pattrib->pktlen = 0; if (IS_CCK_RATE(pmlmeext->tx_rate)) @@ -7885,14 +7764,17 @@ void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib) pattrib->mbssid = 0; pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no; +#ifdef CONFIG_RTW_MGMT_QUEUE + pattrib->ps_dontq = 1; +#endif } void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe) { - u8 *pframe; - struct pkt_attrib *pattrib = &pmgntframe->attrib; -#if defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) - struct sta_info *sta = NULL; + u8 *pframe; + struct pkt_attrib *pattrib = &pmgntframe->attrib; +#if defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) || defined(CONFIG_RTW_MGMT_QUEUE) + struct sta_info *sta = NULL; #endif pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; @@ -7900,17 +7782,18 @@ void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntfr _rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN); _rtw_memcpy(pattrib->ta, get_addr2_ptr(pframe), ETH_ALEN); -#if defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) +#if defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) || defined(CONFIG_RTW_MGMT_QUEUE) sta = pattrib->psta; if (!sta) { sta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); pattrib->psta = sta; } + #ifdef CONFIG_BEAMFORMING if (sta) update_attrib_txbf_info(padapter, pattrib, sta); #endif -#endif /* defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) */ +#endif /* defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) || defined(CONFIG_RTW_MGMT_QUEUE) */ } void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe) @@ -7943,7 +7826,11 @@ s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, i ret = rtw_hal_mgnt_xmit(padapter, pmgntframe); - if (ret == _SUCCESS) + if (ret == _SUCCESS +#ifdef CONFIG_RTW_MGMT_QUEUE + || ret == RTW_QUEUE_MGMT +#endif + ) ret = rtw_sctx_wait(&sctx, __func__); _enter_critical(&pxmitpriv->lock_sctx, &irqL); @@ -7971,7 +7858,14 @@ s32 dump_mgntframe_and_wait_ack_timeout(_adapter *padapter, struct xmit_frame *p pxmitpriv->seq_no = seq_no++; pmgntframe->ack_report = 1; rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms); - if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) + + ret = rtw_hal_mgnt_xmit(padapter, pmgntframe); + + if (ret == _SUCCESS +#ifdef CONFIG_RTW_MGMT_QUEUE + || ret == RTW_QUEUE_MGMT +#endif + ) ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__); pxmitpriv->ack_tx = _FALSE; @@ -8027,6 +7921,7 @@ int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode) return len_diff; } +#ifdef CONFIG_AP_MODE void issue_beacon(_adapter *padapter, int timeout_ms) { struct xmit_frame *pmgntframe; @@ -8224,12 +8119,6 @@ void issue_beacon(_adapter *padapter, int timeout_ms) _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS); } -#ifdef CONFIG_RTW_80211K - pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, - sizeof(padapter->rmpriv.rm_en_cap_def), - padapter->rmpriv.rm_en_cap_def, &pattrib->pktlen); -#endif - #ifdef CONFIG_P2P if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { u32 len; @@ -8353,6 +8242,7 @@ _issue_bcn: dump_mgntframe(padapter, pmgntframe); } +#endif /* CONFIG_AP_MODE */ void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq) { @@ -8553,12 +8443,6 @@ void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probe } -#ifdef CONFIG_RTW_80211K - pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, - sizeof(padapter->rmpriv.rm_en_cap_def), - padapter->rmpriv.rm_en_cap_def, &pattrib->pktlen); -#endif - #ifdef CONFIG_P2P if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) /* IOT issue, When wifi_spec is not set, send probe_resp with P2P IE even if probe_req has no P2P IE */ @@ -8760,6 +8644,10 @@ int _issue_probereq(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 #endif/*CONFIG_RTL8812A*/ +#ifdef CONFIG_RTW_MBO + rtw_mbo_build_probe_req_ies( padapter, &pframe, pattrib); +#endif + pattrib->last_txcmdsz = pattrib->pktlen; @@ -8996,7 +8884,7 @@ void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *p struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network); - u8 *ie = pnetwork->IEs; + u8 *ie = pnetwork->IEs, cap[5], i; #ifdef CONFIG_P2P struct wifidirect_info *pwdinfo = &(padapter->wdinfo); #ifdef CONFIG_WFD @@ -9045,7 +8933,9 @@ void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *p /* capability */ val = *(unsigned short *)rtw_get_capability_from_ie(ie); - +#ifdef CONFIG_RTW_80211K + val |= cap_RM; +#endif pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen)); ie_status = cpu_to_le16(status); @@ -9134,6 +9024,17 @@ void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *p } #endif /* CONFIG_80211AC_VHT */ +#ifdef CONFIG_RTW_80211K + /* FILL RM Enabled Capabilities with joint capabilities */ + for (i = 0; i < 5; i++) { + cap[i] = padapter->rmpriv.rm_en_cap_def[i] + & pstat->rm_en_cap[i]; + } + if (pstat->capability & cap_RM) + pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, 5, + (u8 *)cap, &(pattrib->pktlen)); +#endif /* CONFIG_RTW_80211K */ + /* FILL WMM IE */ if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) { uint ie_len = 0; @@ -9192,6 +9093,12 @@ void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *p #endif #endif /* CONFIG_P2P */ + +#ifdef CONFIG_RTW_MULTI_AP + if (padapter->multi_ap && (pstat->flags & WLAN_STA_MULTI_AP)) + pframe = rtw_set_multi_ap_ie_ext(pframe, &pattrib->pktlen, padapter->multi_ap); +#endif + #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_ASSOCRESP_VENDOR_IE_BIT); #endif @@ -9221,8 +9128,6 @@ static u32 rtw_append_assoc_req_owe_ie(_adapter *adapter, u8 *pbuf) if (sec == NULL) goto exit; - //if (sec->owe_ie && sec->owe_ie_len > 0) { - //rk fixed: warning: address of array 'sec->owe_ie' will always evaluate to 'true' [-Wpointer-bool-conversion] if (sec->owe_ie_len > 0) { len = sec->owe_ie_len; _rtw_memcpy(pbuf, sec->owe_ie, len); @@ -9274,7 +9179,6 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) pattrib = &pmgntframe->attrib; update_mgntframe_attrib(padapter, pattrib); - _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; @@ -9301,6 +9205,9 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) #if CONFIG_DFS _rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); cap |= cap_SpecMgmt; +#ifdef CONFIG_RTW_80211K + cap |= cap_RM; +#endif _rtw_memcpy(pframe, &cap, 2); #else _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); @@ -9434,14 +9341,16 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) else RTW_INFO("%s: Connect to AP without 11b and 11g data rate!\n", __FUNCTION__); +#ifdef CONFIG_RTW_MBO + rtw_mbo_build_assoc_req_ies(padapter, &pframe, pattrib); +#endif +#ifdef CONFIG_RTW_80211R + rtw_ft_build_assoc_req_ies(padapter, is_reassoc, pattrib, &pframe); +#endif #ifdef CONFIG_RTW_80211K - if (pmlmeinfo->network.PhyInfo.rm_en_cap[0] /* RM Enabled Capabilities */ - | pmlmeinfo->network.PhyInfo.rm_en_cap[1] - | pmlmeinfo->network.PhyInfo.rm_en_cap[2] - | pmlmeinfo->network.PhyInfo.rm_en_cap[3] - | pmlmeinfo->network.PhyInfo.rm_en_cap[4]) - pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, 5, - (u8 *)padapter->rmpriv.rm_en_cap_def, &(pattrib->pktlen)); + pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, 5, + (u8 *)padapter->rmpriv.rm_en_cap_def, + &(pattrib->pktlen)); #endif /* CONFIG_RTW_80211K */ /* vendor specific IE, such as WPA, WMM, WPS */ @@ -9681,6 +9590,11 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) #endif #endif /* CONFIG_P2P */ +#ifdef CONFIG_RTW_MULTI_AP + if (padapter->multi_ap) + pframe = rtw_set_multi_ap_ie_ext(pframe, &pattrib->pktlen, padapter->multi_ap); +#endif + /* OWE */ { u32 owe_ie_len; @@ -9701,19 +9615,19 @@ void _issue_assocreq(_adapter *padapter, u8 is_reassoc) pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen ); #endif/*CONFIG_RTL8812A*/ -#ifdef CONFIG_RTW_80211R - rtw_ft_build_assoc_req_ies(padapter, is_reassoc, pattrib, &pframe); -#endif - pattrib->last_txcmdsz = pattrib->pktlen; dump_mgntframe(padapter, pmgntframe); ret = _SUCCESS; exit: - if (ret == _SUCCESS) + if (ret == _SUCCESS) { rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen); - else + #ifdef CONFIG_RTW_WNM + if (is_reassoc == _TRUE) + rtw_wnm_update_reassoc_req_ie(padapter); + #endif + } else rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len); return; @@ -11039,6 +10953,7 @@ unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr) return _SUCCESS; } +#ifdef CONFIG_AP_MODE unsigned int send_beacon(_adapter *padapter) { #if defined(CONFIG_PCI_HCI) && !defined(CONFIG_PCI_BCN_POLLING) @@ -11168,6 +11083,7 @@ unsigned int send_beacon(_adapter *padapter) #endif /*defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)*/ } +#endif /* CONFIG_AP_MODE */ /**************************************************************************** @@ -11289,11 +11205,13 @@ u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSI RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len); return _FAIL; } +#ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT if (rtw_validate_value(_SUPPORTEDRATES_IE_, p+2, len) == _FALSE) { rtw_absorb_ssid_ifneed(padapter, bssid, pframe); RTW_DBG_DUMP("Invalidated Support Rate IE --", p, len+2); return _FAIL; } +#endif /* #ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT */ _rtw_memcpy(bssid->SupportedRates, (p + 2), len); i = len; } @@ -11304,11 +11222,13 @@ u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSI RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len); return _FAIL; } +#ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT if (rtw_validate_value(_EXT_SUPPORTEDRATES_IE_, p+2, len) == _FALSE) { rtw_absorb_ssid_ifneed(padapter, bssid, pframe); RTW_DBG_DUMP("Invalidated EXT Support Rate IE --", p, len+2); return _FAIL; } +#endif /* #ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT */ _rtw_memcpy(bssid->SupportedRates + i, (p + 2), len); } @@ -11461,6 +11381,7 @@ u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSI return _SUCCESS; } +#ifdef CONFIG_AP_MODE void start_create_ibss(_adapter *padapter) { unsigned short caps; @@ -11525,6 +11446,7 @@ void start_create_ibss(_adapter *padapter) update_bmc_sta(padapter); } +#endif /* CONFIG_AP_MODE */ void start_clnt_join(_adapter *padapter) { @@ -11695,7 +11617,11 @@ void start_clnt_assoc(_adapter *padapter) pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE); #ifdef CONFIG_RTW_80211R - if (rtw_ft_roam(padapter)) + if (rtw_ft_roam(padapter) + #ifdef CONFIG_RTW_WNM + || rtw_wnm_btm_reassoc_req(padapter) + #endif + ) issue_reassocreq(padapter); else #endif @@ -11737,257 +11663,24 @@ unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsi return _SUCCESS; } -#ifdef CONFIG_80211D -static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid) +static void rtw_hidden_ssid_bss_count(_adapter *adapter, WLAN_BSSID_EX *bss) { - struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); - struct registry_priv *pregistrypriv; - struct mlme_ext_priv *pmlmeext; - RT_CHANNEL_INFO *chplan_new; - u8 channel; - u8 i; + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + RT_CHANNEL_INFO *chset = rfctl->channel_set; + int chset_idx; + if (bss->InfrastructureMode != Ndis802_11Infrastructure) + return; - pregistrypriv = &padapter->registrypriv; - pmlmeext = &padapter->mlmeextpriv; + if (!hidden_ssid_ap(bss)) + return; - /* Adjust channel plan by AP Country IE */ - if (pregistrypriv->enable80211d - && (!pmlmeext->update_channel_plan_by_ap_done)) { - u8 *ie, *p; - u32 len; - RT_CHANNEL_PLAN chplan_ap; - RT_CHANNEL_INFO *chplan_sta = NULL; - u8 country[4]; - u8 fcn; /* first channel number */ - u8 noc; /* number of channel */ - u8 j, k; - - ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); - if (!ie) - return; - if (len < 6) - return; - - ie += 2; - p = ie; - ie += len; - - _rtw_memset(country, 0, 4); - _rtw_memcpy(country, p, 3); - p += 3; - RTW_INFO("%s: 802.11d country=%s\n", __FUNCTION__, country); - - i = 0; - while ((ie - p) >= 3) { - fcn = *(p++); - noc = *(p++); - p++; - - for (j = 0; j < noc; j++) { - if (fcn <= 14) - channel = fcn + j; /* 2.4 GHz */ - else - channel = fcn + j * 4; /* 5 GHz */ - - chplan_ap.Channel[i++] = channel; - } - } - chplan_ap.Len = i; - -#ifdef CONFIG_RTW_DEBUG - i = 0; - RTW_INFO("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid); - while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0)) { - _RTW_INFO("%02d,", chplan_ap.Channel[i]); - i++; - } - _RTW_INFO("}\n"); -#endif - - chplan_sta = rtw_malloc(sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM); - if (!chplan_sta) - goto done_update_chplan_from_ap; - - _rtw_memcpy(chplan_sta, rfctl->channel_set, sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM); -#ifdef CONFIG_RTW_DEBUG - i = 0; - RTW_INFO("%s: STA channel plan {", __FUNCTION__); - while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) { - _RTW_INFO("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType == SCAN_PASSIVE ? 'p' : 'a'); - i++; - } - _RTW_INFO("}\n"); -#endif - - _rtw_memset(rfctl->channel_set, 0, sizeof(rfctl->channel_set)); - chplan_new = rfctl->channel_set; - - i = j = k = 0; - if (pregistrypriv->wireless_mode & WIRELESS_11G) { - do { - if ((i == MAX_CHANNEL_NUM) - || (chplan_sta[i].ChannelNum == 0) - || (chplan_sta[i].ChannelNum > 14)) - break; - - if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14)) - break; - - if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) { - chplan_new[k].ChannelNum = chplan_ap.Channel[j]; - chplan_new[k].ScanType = SCAN_ACTIVE; - i++; - j++; - k++; - } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) { - chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; -#if 0 - chplan_new[k].ScanType = chplan_sta[i].ScanType; -#else - chplan_new[k].ScanType = SCAN_PASSIVE; -#endif - i++; - k++; - } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) { - chplan_new[k].ChannelNum = chplan_ap.Channel[j]; - chplan_new[k].ScanType = SCAN_ACTIVE; - j++; - k++; - } - } while (1); - - /* change AP not support channel to Passive scan */ - while ((i < MAX_CHANNEL_NUM) - && (chplan_sta[i].ChannelNum != 0) - && (chplan_sta[i].ChannelNum <= 14)) { - chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; -#if 0 - chplan_new[k].ScanType = chplan_sta[i].ScanType; -#else - chplan_new[k].ScanType = SCAN_PASSIVE; -#endif - i++; - k++; - } - - /* add channel AP supported */ - while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) { - chplan_new[k].ChannelNum = chplan_ap.Channel[j]; - chplan_new[k].ScanType = SCAN_ACTIVE; - j++; - k++; - } - } else { - /* keep original STA 2.4G channel plan */ - while ((i < MAX_CHANNEL_NUM) - && (chplan_sta[i].ChannelNum != 0) - && (chplan_sta[i].ChannelNum <= 14)) { - chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; - chplan_new[k].ScanType = chplan_sta[i].ScanType; - i++; - k++; - } - - /* skip AP 2.4G channel plan */ - while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) - j++; - } - - if (pregistrypriv->wireless_mode & WIRELESS_11A) { - do { - if ((i >= MAX_CHANNEL_NUM) - || (chplan_sta[i].ChannelNum == 0)) - break; - - if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0)) - break; - - if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) { - chplan_new[k].ChannelNum = chplan_ap.Channel[j]; - chplan_new[k].ScanType = SCAN_ACTIVE; - i++; - j++; - k++; - } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) { - chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; -#if 0 - chplan_new[k].ScanType = chplan_sta[i].ScanType; -#else - chplan_new[k].ScanType = SCAN_PASSIVE; -#endif - i++; - k++; - } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) { - chplan_new[k].ChannelNum = chplan_ap.Channel[j]; - chplan_new[k].ScanType = SCAN_ACTIVE; - j++; - k++; - } - } while (1); - - /* change AP not support channel to Passive scan */ - while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) { - chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; -#if 0 - chplan_new[k].ScanType = chplan_sta[i].ScanType; -#else - chplan_new[k].ScanType = SCAN_PASSIVE; -#endif - i++; - k++; - } - - /* add channel AP supported */ - while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) { - chplan_new[k].ChannelNum = chplan_ap.Channel[j]; - chplan_new[k].ScanType = SCAN_ACTIVE; - j++; - k++; - } - } else { - /* keep original STA 5G channel plan */ - while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) { - chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; - chplan_new[k].ScanType = chplan_sta[i].ScanType; - i++; - k++; - } - } - - pmlmeext->update_channel_plan_by_ap_done = 1; - -#ifdef CONFIG_RTW_DEBUG - k = 0; - RTW_INFO("%s: new STA channel plan {", __FUNCTION__); - while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) { - _RTW_INFO("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType == SCAN_PASSIVE ? 'p' : 'c'); - k++; - } - _RTW_INFO("}\n"); -#endif - -#if 0 - /* recover the right channel index */ - channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum; - k = 0; - while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) { - if (chplan_new[k].ChannelNum == channel) { - RTW_INFO("%s: change mlme_ext sitesurvey channel index from %d to %d\n", - __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k); - pmlmeext->sitesurvey_res.channel_idx = k; - break; - } - k++; - } -#endif - -done_update_chplan_from_ap: - if (chplan_sta) - rtw_mfree(chplan_sta, sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM); - } + chset_idx = rtw_chset_search_ch(chset, bss->Configuration.DSConfig); + if (chset_idx < 0) + return; + + chset[chset_idx].hidden_bss_cnt++; } -#endif /**************************************************************************** @@ -12006,15 +11699,12 @@ void report_survey_event(_adapter *padapter, union recv_frame *precv_frame) struct cmd_priv *pcmdpriv; /* u8 *pframe = precv_frame->u.hdr.rx_data; */ /* uint len = precv_frame->u.hdr.len; */ - RT_CHANNEL_INFO *chset; - int ch_set_idx = -1; if (!padapter) return; pmlmeext = &padapter->mlmeextpriv; pcmdpriv = &padapter->cmdpriv; - chset = adapter_to_chset(padapter); pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); if (pcmd_obj == NULL) @@ -12049,25 +11739,7 @@ void report_survey_event(_adapter *padapter, union recv_frame *precv_frame) return; } -#ifdef CONFIG_80211D - process_80211d(padapter, &psurvey_evt->bss); -#endif - - ch_set_idx = rtw_chset_search_ch(chset, psurvey_evt->bss.Configuration.DSConfig); - if (ch_set_idx >= 0) { - if (psurvey_evt->bss.InfrastructureMode == Ndis802_11Infrastructure) { - if (chset[ch_set_idx].ScanType == SCAN_PASSIVE - && !rtw_is_dfs_ch(psurvey_evt->bss.Configuration.DSConfig) - ) { - RTW_INFO("%s: change ch:%d to active\n", __func__, psurvey_evt->bss.Configuration.DSConfig); - chset[ch_set_idx].ScanType = SCAN_ACTIVE; - } - #if CONFIG_IEEE80211_BAND_5GHZ && CONFIG_DFS - if (hidden_ssid_ap(&psurvey_evt->bss)) - chset[ch_set_idx].hidden_bss_cnt++; - #endif - } - } + rtw_hidden_ssid_bss_count(padapter, &psurvey_evt->bss); rtw_enqueue_cmd(pcmdpriv, pcmd_obj); @@ -12117,6 +11789,7 @@ void report_surveydone_event(_adapter *padapter, bool acs) psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct rtw_evt_header)); psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt; + psurveydone_evt->activate_ch_cnt = pmlmeext->sitesurvey_res.activate_ch_cnt; psurveydone_evt->acs = acs; RTW_INFO("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter)); @@ -12599,10 +12272,10 @@ static void rtw_mlmeext_disconnect(_adapter *padapter) rtw_dfs_rd_en_decision(padapter, self_action, 0); #endif - if (rtw_mi_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0) { + if (rtw_mi_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0) set_channel_bwmode(padapter, ch, offset, bw); - rtw_mi_update_union_chan_inf(padapter, ch, offset, bw); - } + rtw_mi_update_union_chan_inf(padapter, ch, offset, bw); + rtw_rfctl_update_op_mode(adapter_to_rfctl(padapter), BIT(padapter->iface_id), 0); } flush_all_cam_entry(padapter); @@ -12671,11 +12344,12 @@ void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res) pmlmepriv->GetGatewayTryCnt = 0; #endif +#ifdef CONFIG_AP_MODE if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { /* update bc/mc sta_info */ update_bmc_sta(padapter); } - +#endif /* turn on dynamic functions */ /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */ @@ -12779,6 +12453,7 @@ void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta) if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { /* adhoc master or sta_count>1 */ /* nothing to do */ } else { /* adhoc client */ + #ifdef CONFIG_AP_MODE /* update TSF Value */ /* update_TSF(pmlmeext, pframe, len); */ @@ -12790,6 +12465,7 @@ void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta) rtw_warn_on(1); pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; + #endif } join_type = 2; @@ -12873,6 +12549,7 @@ void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer) } } + u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta) { u8 ret = _FALSE; @@ -13059,15 +12736,20 @@ void linked_status_chk(_adapter *padapter, u8 from_timer) struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct sta_priv *pstapriv = &padapter->stapriv; -#if defined(CONFIG_ARP_KEEP_ALIVE) || defined(CONFIG_LAYER2_ROAMING) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; -#endif #ifdef CONFIG_LAYER2_ROAMING struct recv_priv *precvpriv = &padapter->recvpriv; #endif +#ifdef CONFIG_RTW_WDS + rtw_wds_gptr_expire(padapter); +#endif + if (padapter->registrypriv.mp_mode == _TRUE) return; + + if (check_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON)) + return; if (is_client_associated_to_ap(padapter)) { /* linked infrastructure client mode */ @@ -13642,415 +13324,6 @@ void sa_query_timer_hdl(void *ctx) #endif /* CONFIG_IEEE80211W */ -#ifdef CONFIG_RTW_80211R -void rtw_ft_update_bcn(_adapter *padapter, union recv_frame *precv_frame) -{ - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 *pframe = precv_frame->u.hdr.rx_data; - uint len = precv_frame->u.hdr.len; - WLAN_BSSID_EX *pbss; - - if (rtw_ft_chk_status(padapter,RTW_FT_ASSOCIATED_STA) - && (pmlmepriv->ft_roam.ft_updated_bcn == _FALSE)) { - pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX)); - if (pbss) { - if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) { - struct beacon_keys recv_beacon; - - update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE); - - /* update bcn keys */ - if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) { - RTW_INFO("%s: beacon keys ready\n", __func__); - _rtw_memcpy(&pmlmepriv->cur_beacon_keys, - &recv_beacon, sizeof(recv_beacon)); - if (is_hidden_ssid(recv_beacon.ssid, recv_beacon.ssid_len)) { - _rtw_memcpy(pmlmepriv->cur_beacon_keys.ssid, pmlmeinfo->network.Ssid.Ssid, IW_ESSID_MAX_SIZE); - pmlmepriv->cur_beacon_keys.ssid_len = pmlmeinfo->network.Ssid.SsidLength; - } - } else { - RTW_ERR("%s: get beacon keys failed\n", __func__); - _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon)); - } - #ifdef CONFIG_BCN_CNT_CONFIRM_HDL - pmlmepriv->new_beacon_cnts = 0; - #endif - } - rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX)); - } - - /* check the vendor of the assoc AP */ - pmlmeinfo->assoc_AP_vendor = - check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), - (len - sizeof(struct rtw_ieee80211_hdr_3addr))); - - /* update TSF Value */ - update_TSF(pmlmeext, pframe, len); - pmlmeext->bcn_cnt = 0; - pmlmeext->last_bcn_cnt = 0; - pmlmepriv->ft_roam.ft_updated_bcn = _TRUE; - } -} - -void rtw_ft_start_clnt_join(_adapter *padapter) -{ - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); - - if (rtw_ft_otd_roam(padapter)) { - pmlmeinfo->state = WIFI_FW_AUTH_SUCCESS | WIFI_FW_STATION_STATE; - pft_roam->ft_event.ies = - (pft_roam->ft_action + sizeof(struct rtw_ieee80211_hdr_3addr) + 16); - pft_roam->ft_event.ies_len = - (pft_roam->ft_action_len - sizeof(struct rtw_ieee80211_hdr_3addr)); - - /*Not support RIC*/ - pft_roam->ft_event.ric_ies = NULL; - pft_roam->ft_event.ric_ies_len = 0; - rtw_ft_report_evt(padapter); - return; - } - - pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE; - start_clnt_auth(padapter); -} - -u8 rtw_ft_update_rsnie( - _adapter *padapter, u8 bwrite, - struct pkt_attrib *pattrib, u8 **pframe) -{ - struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); - u8 *pie; - u32 len; - - pie = rtw_get_ie(pft_roam->updated_ft_ies, EID_WPA2, &len, - pft_roam->updated_ft_ies_len); - - if (!bwrite) - return (pie)?_SUCCESS:_FAIL; - - if (pie) { - *pframe = rtw_set_ie(((u8 *)*pframe), EID_WPA2, len, - pie+2, &(pattrib->pktlen)); - } else - return _FAIL; - - return _SUCCESS; -} - -static u8 rtw_ft_update_mdie( - _adapter *padapter, struct pkt_attrib *pattrib, u8 **pframe) -{ - struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); - u8 *pie, mdie[3]; - u32 len = 3; - - if (rtw_ft_roam(padapter)) { - if ((pie = rtw_get_ie(pft_roam->updated_ft_ies, _MDIE_, - &len, pft_roam->updated_ft_ies_len))) { - pie = (pie + 2); /* ignore md-id & length */ - } else - return _FAIL; - } else { - *((u16 *)&mdie[0]) = pft_roam->mdid; - mdie[2] = pft_roam->ft_cap; - pie = &mdie[0]; - } - - *pframe = rtw_set_ie(((u8 *)*pframe), _MDIE_, len , pie, &(pattrib->pktlen)); - return _SUCCESS; -} - -static u8 rtw_ft_update_ftie( - _adapter *padapter, struct pkt_attrib *pattrib, u8 **pframe) -{ - struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); - u8 *pie; - u32 len; - - if ((pie = rtw_get_ie(pft_roam->updated_ft_ies, _FTIE_, &len, - pft_roam->updated_ft_ies_len)) != NULL) { - *pframe = rtw_set_ie(*pframe, _FTIE_, len , - (pie+2), &(pattrib->pktlen)); - } else - return _FAIL; - - return _SUCCESS; -} - -void rtw_ft_build_auth_req_ies(_adapter *padapter, - struct pkt_attrib *pattrib, u8 **pframe) -{ - u8 ftie_append = _TRUE; - - if (!pattrib || !(*pframe)) - return; - - if (!rtw_ft_roam(padapter)) - return; - - ftie_append = rtw_ft_update_rsnie(padapter, _TRUE, pattrib, pframe); - rtw_ft_update_mdie(padapter, pattrib, pframe); - if (ftie_append) - rtw_ft_update_ftie(padapter, pattrib, pframe); -} - -void rtw_ft_build_assoc_req_ies(_adapter *padapter, - u8 is_reassoc, struct pkt_attrib *pattrib, u8 **pframe) -{ - if (!pattrib || !(*pframe)) - return; - - if (rtw_ft_chk_flags(padapter, RTW_FT_PEER_EN)) - rtw_ft_update_mdie(padapter, pattrib, pframe); - - if ((!is_reassoc) || (!rtw_ft_roam(padapter))) - return; - - if (rtw_ft_update_rsnie(padapter, _FALSE, pattrib, pframe)) - rtw_ft_update_ftie(padapter, pattrib, pframe); -} - -u8 rtw_ft_update_auth_rsp_ies(_adapter *padapter, u8 *pframe, u32 len) -{ - u8 ret = _SUCCESS; - u8 target_ap_addr[ETH_ALEN] = {0}; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); - - if (!rtw_ft_roam(padapter)) - return _FAIL; - - /*rtw_ft_report_reassoc_evt already, - * and waiting for cfg80211_rtw_update_ft_ies */ - if (rtw_ft_authed_sta(padapter)) - return ret; - - if (!pframe || !len) - return _FAIL; - - rtw_buf_update(&pmlmepriv->auth_rsp, - &pmlmepriv->auth_rsp_len, pframe, len); - pft_roam->ft_event.ies = - (pmlmepriv->auth_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6); - pft_roam->ft_event.ies_len = - (pmlmepriv->auth_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6); - - /*Not support RIC*/ - pft_roam->ft_event.ric_ies = NULL; - pft_roam->ft_event.ric_ies_len = 0; - _rtw_memcpy(target_ap_addr, pmlmepriv->assoc_bssid, ETH_ALEN); - rtw_ft_report_reassoc_evt(padapter, target_ap_addr); - - return ret; -} - -static void rtw_ft_start_clnt_action(_adapter *padapter, u8 *pTargetAddr) -{ - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - - rtw_ft_set_status(padapter, RTW_FT_REQUESTING_STA); - rtw_ft_issue_action_req(padapter, pTargetAddr); - _set_timer(&pmlmeext->ft_link_timer, REASSOC_TO); -} - -void rtw_ft_start_roam(_adapter *padapter, u8 *pTargetAddr) -{ - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - - if (rtw_ft_otd_roam(padapter)) { - rtw_ft_start_clnt_action(padapter, pTargetAddr); - } else { - /*wait a little time to retrieve packets buffered in the current ap while scan*/ - _set_timer(&pmlmeext->ft_roam_timer, 30); - } -} - -void rtw_ft_issue_action_req(_adapter *padapter, u8 *pTargetAddr) -{ - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct xmit_frame *pmgntframe; - struct rtw_ieee80211_hdr *pwlanhdr; - struct pkt_attrib *pattrib; - u8 *pframe; - u8 category = RTW_WLAN_CATEGORY_FT; - u8 action = RTW_WLAN_ACTION_FT_REQ; - - pmgntframe = alloc_mgtxmitframe(pxmitpriv); - if (pmgntframe == NULL) - return; - - pattrib = &pmgntframe->attrib; - update_mgntframe_attrib(padapter, pattrib); - _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); - - pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; - pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; - pwlanhdr->frame_ctl = 0; - - _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); - - SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); - pmlmeext->mgnt_seq++; - set_frame_sub_type(pframe, WIFI_ACTION); - - pframe += sizeof(struct rtw_ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); - - pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); - pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); - - _rtw_memcpy(pframe, adapter_mac_addr(padapter), ETH_ALEN); - pframe += ETH_ALEN; - pattrib->pktlen += ETH_ALEN; - - _rtw_memcpy(pframe, pTargetAddr, ETH_ALEN); - pframe += ETH_ALEN; - pattrib->pktlen += ETH_ALEN; - - rtw_ft_update_mdie(padapter, pattrib, &pframe); - if (rtw_ft_update_rsnie(padapter, _TRUE, pattrib, &pframe)) - rtw_ft_update_ftie(padapter, pattrib, &pframe); - - pattrib->last_txcmdsz = pattrib->pktlen; - dump_mgntframe(padapter, pmgntframe); -} - -void rtw_ft_report_evt(_adapter *padapter) -{ - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&(pmlmeinfo->network); - struct cfg80211_ft_event_params ft_evt_parms; - _irqL irqL; - - _rtw_memset(&ft_evt_parms, 0, sizeof(ft_evt_parms)); - rtw_ft_update_stainfo(padapter, pnetwork); - - if (!pnetwork) - goto err_2; - - ft_evt_parms.ies_len = pft_roam->ft_event.ies_len; - ft_evt_parms.ies = rtw_zmalloc(ft_evt_parms.ies_len); - if (ft_evt_parms.ies) - _rtw_memcpy((void *)ft_evt_parms.ies, pft_roam->ft_event.ies, ft_evt_parms.ies_len); - else - goto err_2; - - ft_evt_parms.target_ap = rtw_zmalloc(ETH_ALEN); - if (ft_evt_parms.target_ap) - _rtw_memcpy((void *)ft_evt_parms.target_ap, pnetwork->MacAddress, ETH_ALEN); - else - goto err_1; - - ft_evt_parms.ric_ies = pft_roam->ft_event.ric_ies; - ft_evt_parms.ric_ies_len = pft_roam->ft_event.ric_ies_len; - - rtw_ft_lock_set_status(padapter, RTW_FT_AUTHENTICATED_STA, &irqL); - rtw_cfg80211_ft_event(padapter, &ft_evt_parms); - RTW_INFO("FT: rtw_ft_report_evt\n"); - rtw_mfree((u8 *)pft_roam->ft_event.target_ap, ETH_ALEN); -err_1: - rtw_mfree((u8 *)ft_evt_parms.ies, ft_evt_parms.ies_len); -err_2: - return; -} - -void rtw_ft_report_reassoc_evt(_adapter *padapter, u8 *pMacAddr) -{ - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); - struct cmd_obj *pcmd_obj = NULL; - struct stassoc_event *passoc_sta_evt = NULL; - struct rtw_evt_header *evt_hdr = NULL; - u8 *pevtcmd = NULL; - u32 cmdsz = 0; - - pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); - if (pcmd_obj == NULL) - return; - - cmdsz = (sizeof(struct stassoc_event) + sizeof(struct rtw_evt_header)); - pevtcmd = (u8 *)rtw_zmalloc(cmdsz); - if (pevtcmd == NULL) { - rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); - return; - } - - _rtw_init_listhead(&pcmd_obj->list); - pcmd_obj->cmdcode = CMD_SET_MLME_EVT; - pcmd_obj->cmdsz = cmdsz; - pcmd_obj->parmbuf = pevtcmd; - pcmd_obj->rsp = NULL; - pcmd_obj->rspsz = 0; - - evt_hdr = (struct rtw_evt_header *)(pevtcmd); - evt_hdr->len = sizeof(struct stassoc_event); - evt_hdr->id = EVT_FT_REASSOC; - evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); - - passoc_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct rtw_evt_header)); - _rtw_memcpy((unsigned char *)(&(passoc_sta_evt->macaddr)), pMacAddr, ETH_ALEN); - rtw_enqueue_cmd(pcmdpriv, pcmd_obj); -} - -void rtw_ft_link_timer_hdl(void *ctx) -{ - _adapter *padapter = (_adapter *)ctx; - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam); - - if (rtw_ft_chk_status(padapter, RTW_FT_REQUESTING_STA)) { - if (pft_roam->ft_req_retry_cnt < RTW_FT_ACTION_REQ_LMT) { - pft_roam->ft_req_retry_cnt++; - rtw_ft_issue_action_req(padapter, (u8 *)pmlmepriv->roam_network->network.MacAddress); - _set_timer(&pmlmeext->ft_link_timer, REASSOC_TO); - } else { - pft_roam->ft_req_retry_cnt = 0; - if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) - rtw_ft_set_status(padapter, RTW_FT_ASSOCIATED_STA); - else - rtw_ft_reset_status(padapter); - } - } -} - -void rtw_ft_roam_timer_hdl(void *ctx) -{ - _adapter *padapter = (_adapter *)ctx; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - - receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress - , WLAN_REASON_ACTIVE_ROAM, _FALSE); -} - -void rtw_ft_roam_status_reset(_adapter *padapter) -{ - struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam); - - if ((rtw_to_roam(padapter) > 0) && - (!rtw_ft_chk_status(padapter, RTW_FT_REQUESTED_STA))) { - rtw_ft_reset_status(padapter); - } - - padapter->mlmepriv.ft_roam.ft_updated_bcn = _FALSE; -} -#endif - - #ifdef CONFIG_AUTO_AP_MODE void rtw_auto_ap_rx_msg_dump(_adapter *padapter, union recv_frame *precv_frame, u8 *ehdr_pos) { @@ -14272,6 +13545,7 @@ u8 setopmode_hdl(_adapter *padapter, u8 *pbuf) u8 createbss_hdl(_adapter *padapter, u8 *pbuf) { +#ifdef CONFIG_AP_MODE struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network)); @@ -14280,14 +13554,12 @@ u8 createbss_hdl(_adapter *padapter, u8 *pbuf) u8 ret = H2C_SUCCESS; /* u8 initialgain; */ -#ifdef CONFIG_AP_MODE if ((parm->req_ch == 0 && pmlmeinfo->state == WIFI_FW_AP_STATE) || parm->req_ch != 0 ) { start_bss_network(padapter, parm); goto exit; } -#endif /* below is for ad-hoc master */ if (parm->adhoc) { @@ -14331,6 +13603,9 @@ ibss_post_hdl: exit: return ret; +#else + return H2C_SUCCESS; +#endif /* CONFIG_AP_MODE */ } u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf) @@ -14508,7 +13783,6 @@ u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf) rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); set_channel_bwmode(padapter, u_ch, u_offset, u_bw); - rtw_mi_update_union_chan_inf(padapter, u_ch, u_offset, u_bw); doiqk = _FALSE; rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); @@ -14812,7 +14086,7 @@ static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel _rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel)); - if (rfctl->channel_set[set_idx].ScanType == SCAN_PASSIVE) + if (rfctl->channel_set[set_idx].flags & (RTW_CHF_NO_IR | RTW_CHF_DFS)) out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN; j++; @@ -14840,7 +14114,7 @@ static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel out[j].hw_value = chan; - if (rfctl->channel_set[i].ScanType == SCAN_PASSIVE) + if (rfctl->channel_set[i].flags & (RTW_CHF_NO_IR | RTW_CHF_DFS)) out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN; j++; @@ -14866,10 +14140,9 @@ static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm int i; ss->bss_cnt = 0; + ss->activate_ch_cnt = 0; ss->channel_idx = 0; -#if CONFIG_IEEE80211_BAND_5GHZ && CONFIG_DFS - ss->dfs_ch_ssid_scan = 0; -#endif + ss->force_ssid_scan = 0; ss->igi_scan = 0; ss->igi_before_scan = 0; #ifdef CONFIG_SCAN_BACKOP @@ -14894,10 +14167,8 @@ static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm , parm->acs ); -#if CONFIG_IEEE80211_BAND_5GHZ && CONFIG_DFS for (i = 0; i < MAX_CHANNEL_NUM; i++) chset[i].hidden_bss_cnt = 0; -#endif ss->bw = parm->bw; ss->igi = parm->igi; @@ -14942,7 +14213,7 @@ static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch, RT_SCAN_TYPE * scan_ch = pwdinfo->social_chan[ss->channel_idx]; ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, scan_ch); if (ch_set_idx >= 0) - scan_type = rfctl->channel_set[ch_set_idx].ScanType; + scan_type = rfctl->channel_set[ch_set_idx].flags & RTW_CHF_NO_IR ? SCAN_PASSIVE : SCAN_ACTIVE; else scan_type = SCAN_ACTIVE; } else @@ -14954,34 +14225,32 @@ static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch, RT_SCAN_TYPE * backop_flags = rtw_scan_backop_decision(padapter); #endif -#if CONFIG_IEEE80211_BAND_5GHZ && CONFIG_DFS #ifdef CONFIG_SCAN_BACKOP if (!(backop_flags && ss->scan_cnt >= ss->scan_cnt_max)) #endif { #ifdef CONFIG_RTW_WIFI_HAL if (adapter_to_dvobj(padapter)->nodfs) { - while ( ss->channel_idx < ss->ch_num && rtw_is_dfs_ch(ss->ch[ss->channel_idx].hw_value)) + while (ss->channel_idx < ss->ch_num && rtw_chset_is_dfs_ch(rfctl->channel_set, ss->ch[ss->channel_idx].hw_value)) ss->channel_idx++; } else #endif - if (ss->channel_idx != 0 && ss->dfs_ch_ssid_scan == 0 + if (ss->channel_idx != 0 && ss->force_ssid_scan == 0 && pmlmeext->sitesurvey_res.ssid_num - && rtw_is_dfs_ch(ss->ch[ss->channel_idx - 1].hw_value) + && (ss->ch[ss->channel_idx - 1].flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ) { ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, ss->ch[ss->channel_idx - 1].hw_value); if (ch_set_idx != -1 && rfctl->channel_set[ch_set_idx].hidden_bss_cnt && (!IS_DFS_SLAVE_WITH_RD(rfctl) - || rtw_odm_dfs_domain_unknown(rfctl_to_dvobj(rfctl)) + || rtw_rfctl_dfs_domain_unknown(rfctl) || !CH_IS_NON_OCP(&rfctl->channel_set[ch_set_idx])) ) { ss->channel_idx--; - ss->dfs_ch_ssid_scan = 1; + ss->force_ssid_scan = 1; } } else - ss->dfs_ch_ssid_scan = 0; + ss->force_ssid_scan = 0; } -#endif /* CONFIG_IEEE80211_BAND_5GHZ && CONFIG_DFS */ if (ss->channel_idx < ss->ch_num) { ch = &ss->ch[ss->channel_idx]; @@ -15081,12 +14350,9 @@ void site_survey(_adapter *padapter, u8 survey_channel, RT_SCAN_TYPE ScanType) if (survey_channel != 0) { set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); -#if CONFIG_IEEE80211_BAND_5GHZ && CONFIG_DFS - if (ScanType == SCAN_PASSIVE && ss->dfs_ch_ssid_scan) + if (ScanType == SCAN_PASSIVE && ss->force_ssid_scan) ssid_scan = 1; - else -#endif - if (ScanType == SCAN_ACTIVE) { + else if (ScanType == SCAN_ACTIVE) { #ifdef CONFIG_P2P #ifdef CONFIG_IOCTL_CFG80211 if (rtw_cfg80211_is_p2p_scan(padapter)) @@ -15423,6 +14689,9 @@ u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf) #ifdef CONFIG_P2P struct wifidirect_info *pwdinfo = &padapter->wdinfo; +#ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#endif #endif #ifdef DBG_CHECK_FW_PS_STATE @@ -15547,7 +14816,7 @@ operation_by_state: , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time) , scan_type ? 'A' : 'P', ss->scan_mode ? 'A' : 'P' , ss->ssid[0].SsidLength ? 'S' : ' ' - , ss->dfs_ch_ssid_scan ? 'D' : ' ' + , ss->force_ssid_scan ? 'F' : ' ' ); #else RTW_INFO(FUNC_ADPT_FMT" %s ch:%u (idx:%d) at %dms, %c%c%c%c\n" @@ -15558,7 +14827,7 @@ operation_by_state: , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time) , scan_type ? 'A' : 'P', ss->scan_mode ? 'A' : 'P' , ss->ssid[0].SsidLength ? 'S' : ' ' - , ss->dfs_ch_ssid_scan ? 'D' : ' ' + , ss->force_ssid_scan ? 'F' : ' ' ); #endif /* CONFIG_P2P */ #endif /*DBG_SITESURVEY*/ @@ -15616,8 +14885,12 @@ operation_by_state: #endif /* CONFIG_MCC_MODE */ if (need_ch_setting_union) { - if (rtw_mi_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0) + if (rtw_mi_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0) { rtw_warn_on(1); + back_ch = pmlmeext->cur_channel; + back_bw = pmlmeext->cur_bwmode; + back_ch_offset = pmlmeext->cur_ch_offset; + } } #ifdef DBG_SITESURVEY @@ -15752,7 +15025,7 @@ operation_by_state: #ifdef CONFIG_CONCURRENT_MODE if (pwdinfo->driver_interface == DRIVER_WEXT) { if (rtw_mi_check_status(padapter, MI_LINKED)) - _set_timer(&pwdinfo->ap_p2p_switch_timer, 500); + _set_timer(&prochinfo->ap_roch_ch_switch_timer, 500); } #endif @@ -16357,6 +15630,7 @@ u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf) u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf) { +#ifdef CONFIG_AP_MODE /*RTW_INFO(FUNC_ADPT_FMT, FUNC_ADPT_ARG(padapter));*/ #ifdef CONFIG_SWTIMER_BASED_TXBCN @@ -16372,7 +15646,7 @@ u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf) /* tx bc/mc frames after update TIM */ chk_bmc_sleepq_hdl(padapter, NULL); #endif - +#endif /* CONFIG_AP_MODE */ return H2C_SUCCESS; } @@ -16382,6 +15656,7 @@ u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf) * set WLAN_BSSID_EX.SupportedRates * update WLAN_BSSID_EX.IEs's Supported Rate and Extended Supported Rate ie */ +#ifdef CONFIG_AP_MODE void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch) { u8 network_type, rate_len, total_rate_len, remainder_rate_len; @@ -16443,6 +15718,7 @@ void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch) pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork); } +#endif /* CONFIG_AP_MODE */ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) { @@ -16453,7 +15729,7 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) struct mlme_priv *mlme; struct mlme_ext_priv *mlmeext; u8 u_ch, u_offset, u_bw; - int i; + int i, ret; dvobj = adapter_to_dvobj(adapter); @@ -16462,19 +15738,20 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) dump_adapters_status(RTW_DBGDUMP , dvobj); } - if (join_res >= 0) { + ret = rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset); + if (join_res >= 0 && ret <= 0) { + join_res = -1; + dump_adapters_status(RTW_DBGDUMP , dvobj); + rtw_warn_on(1); + } + if (join_res >= 0) { #ifdef CONFIG_MCC_MODE /* MCC setting success, don't go to ch union process */ if (rtw_hal_set_mcc_setting_join_done_chk_ch(adapter)) return; #endif /* CONFIG_MCC_MODE */ - if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset) <= 0) { - dump_adapters_status(RTW_DBGDUMP , dvobj); - rtw_warn_on(1); - } - for (i = 0; i < dvobj->iface_nums; i++) { iface = dvobj->padapters[i]; mlme = &iface->mlmepriv; @@ -16483,6 +15760,7 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) if (!iface || iface == adapter) continue; +#ifdef CONFIG_AP_MODE if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface)) && check_fwstate(mlme, WIFI_ASOC_STATE) ) { @@ -16508,7 +15786,7 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) rtw_chset_sync_chbw(adapter_to_chset(adapter) , &mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset - , &u_ch, &u_bw, &u_offset); + , &u_ch, &u_bw, &u_offset, 1, 0); RTW_INFO(FUNC_ADPT_FMT" %u,%u,%u => %u,%u,%u\n", FUNC_ADPT_ARG(iface) , ori_ch, ori_bw, ori_offset @@ -16531,7 +15809,7 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) rtw_cfg80211_ch_switch_notify(iface , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset - , ht_option); + , ht_option, 0); #endif } } @@ -16539,6 +15817,7 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) clr_fwstate(mlme, WIFI_OP_CH_SWITCHING); update_beacon(iface, 0xFF, NULL, _TRUE, 0); } +#endif /* CONFIG_AP_MODE */ } #ifdef CONFIG_DFS_MASTER @@ -16552,13 +15831,14 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) if (!iface || iface == adapter) continue; - +#ifdef CONFIG_AP_MODE if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface)) && check_fwstate(mlme, WIFI_ASOC_STATE) ) { clr_fwstate(mlme, WIFI_OP_CH_SWITCHING); update_beacon(iface, 0xFF, NULL, _TRUE, 0); } +#endif } #ifdef CONFIG_DFS_MASTER rtw_dfs_rd_en_decision(adapter, MLME_STA_DISCONNECTED, 0); @@ -16568,9 +15848,13 @@ void rtw_join_done_chk_ch(_adapter *adapter, int join_res) if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset)) { RTW_INFO(FUNC_ADPT_FMT" union:%u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset); set_channel_bwmode(adapter, u_ch, u_offset, u_bw); - rtw_mi_update_union_chan_inf(adapter, u_ch, u_offset, u_bw); } + rtw_mi_update_union_chan_inf(adapter, u_ch, u_offset, u_bw); + + if (join_res >= 0) + rtw_rfctl_update_op_mode(adapter_to_rfctl(adapter), BIT(adapter->iface_id), 1); + if (DUMP_ADAPTERS_STATUS) { RTW_INFO(FUNC_ADPT_FMT" exit\n", FUNC_ADPT_ARG(adapter)); dump_adapters_status(RTW_DBGDUMP , dvobj); @@ -16699,6 +15983,7 @@ connect_allow_hdl: if (!iface || iface == adapter) continue; + #ifdef CONFIG_AP_MODE if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface)) && check_fwstate(mlme, WIFI_ASOC_STATE) ) { @@ -16711,8 +15996,9 @@ connect_allow_hdl: rtw_hal_set_hwreg(iface, HW_VAR_CHECK_TXBUF, 0); set_fwstate(mlme, WIFI_OP_CH_SWITCHING); - - } else if (check_fwstate(mlme, WIFI_STATION_STATE) + } else + #endif /* CONFIG_AP_MODE */ + if (check_fwstate(mlme, WIFI_STATION_STATE) && check_fwstate(mlme, WIFI_ASOC_STATE) ) { rtw_disassoc_cmd(iface, 500, RTW_CMDF_DIRECTLY); @@ -16732,6 +16018,7 @@ exit: if (connect_allow == _TRUE) { RTW_INFO(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset); + rtw_mi_update_union_chan_inf(adapter, u_ch, u_offset, u_bw); *ch = u_ch; *bw = u_bw; *offset = u_offset; @@ -16744,12 +16031,12 @@ exit: ht_option = adapter->mlmepriv.htpriv.ht_option; #endif /* CONFIG_80211N_HT */ - /* + /* when supplicant send the mlme frame, the bss freq is updated by channel switch event. */ rtw_cfg80211_ch_switch_notify(adapter, - cur_ch, cur_bw, cur_ch_offset, ht_option); + cur_ch, cur_bw, cur_ch_offset, ht_option, 1); } #endif } @@ -16778,10 +16065,19 @@ void rtw_set_external_auth_status(_adapter *padapter, #endif /* CONFIG_IOCTL_CFG80211 */ } +u8 rtw_iqk_hdl(_adapter *padapter, unsigned char *pbuf) +{ + rtw_hal_phydm_cal_trigger(padapter); + return H2C_SUCCESS; +} + u8 rtw_set_chbw_hdl(_adapter *padapter, u8 *pbuf) { struct set_ch_parm *set_ch_parm; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + u8 ifbmp_s = rtw_mi_get_ld_sta_ifbmp(padapter); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + u8 u_ch, u_bw, u_offset; if (!pbuf) return H2C_PARAMETERS_ERROR; @@ -16792,43 +16088,73 @@ u8 rtw_set_chbw_hdl(_adapter *padapter, u8 *pbuf) FUNC_NDEV_ARG(padapter->pnetdev), set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset); - pmlmeext->cur_channel = set_ch_parm->ch; - pmlmeext->cur_ch_offset = set_ch_parm->ch_offset; - pmlmeext->cur_bwmode = set_ch_parm->bw; + /* update ch, bw, offset for all asoc STA ifaces */ + if (ifbmp_s) { + _adapter *iface; + int i; + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (!iface || !(ifbmp_s & BIT(iface->iface_id))) + continue; + + /* update STA mode ch/bw/offset */ + iface->mlmeextpriv.cur_channel = set_ch_parm->ch; + iface->mlmeextpriv.cur_bwmode = set_ch_parm->bw; + iface->mlmeextpriv.cur_ch_offset = set_ch_parm->ch_offset; + /* updaet STA mode DSConfig , ap mode will update in rtw_change_bss_chbw_cmd */ + iface->mlmepriv.cur_network.network.Configuration.DSConfig = set_ch_parm->ch; + } + } + + LeaveAllPowerSaveModeDirect(padapter); + set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw); + rtw_mi_get_ch_setting_union(padapter, &u_ch, &u_bw, &u_offset); + rtw_mi_update_union_chan_inf(padapter, u_ch, u_offset, u_bw); + rtw_rfctl_update_op_mode(dvobj_to_rfctl(dvobj), 0, 0); + return H2C_SUCCESS; } -u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf) +u8 rtw_set_chplan_hdl(_adapter *padapter, unsigned char *pbuf) { - struct SetChannelPlan_param *setChannelPlan_param; + struct SetChannelPlan_param *param; struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); if (!pbuf) return H2C_PARAMETERS_ERROR; - setChannelPlan_param = (struct SetChannelPlan_param *)pbuf; + param = (struct SetChannelPlan_param *)pbuf; - if (!rtw_is_channel_plan_valid(setChannelPlan_param->channel_plan)) + if (param->regd_src == REGD_SRC_RTK_PRIV + && !rtw_is_channel_plan_valid(param->channel_plan)) return H2C_PARAMETERS_ERROR; - rfctl->country_ent = setChannelPlan_param->country_ent; - rfctl->ChannelPlan = setChannelPlan_param->channel_plan; +#ifdef CONFIG_REGD_SRC_FROM_OS + if (rfctl->regd_src == REGD_SRC_OS) + rtw_mfree((void *)rfctl->country_ent, sizeof(struct country_chplan)); +#endif + + rfctl->regd_src = param->regd_src; + rfctl->country_ent = param->country_ent; + rfctl->ChannelPlan = param->channel_plan; - rfctl->max_chan_nums = init_channel_set(padapter, rfctl->ChannelPlan, rfctl->channel_set); - init_channel_list(padapter, rfctl->channel_set, &rfctl->channel_list); #if CONFIG_TXPWR_LIMIT rtw_txpwr_init_regd(rfctl); #endif + rtw_rfctl_chplan_init(padapter); + rtw_hal_set_odm_var(padapter, HAL_ODM_REGULATION, NULL, _TRUE); #ifdef CONFIG_IOCTL_CFG80211 rtw_regd_apply_flags(adapter_to_wiphy(padapter)); #endif + rtw_nlrtw_reg_change_event(padapter); + if (GET_HAL_DATA(padapter)->txpwr_limit_loaded && rtw_get_hw_init_completed(padapter)) rtw_hal_update_txpwr_level(padapter); @@ -16836,6 +16162,45 @@ u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf) return H2C_SUCCESS; } +u8 rtw_get_chplan_hdl(_adapter *padapter, unsigned char *pbuf) +{ + struct get_channel_plan_param *param; + struct get_chplan_resp *resp; + struct rf_ctl_t *rfctl; + + if (!pbuf) + return H2C_PARAMETERS_ERROR; + + rfctl = adapter_to_rfctl(padapter); + param = (struct get_channel_plan_param *)pbuf; + + resp = rtw_vmalloc(sizeof(struct get_chplan_resp) + sizeof(RT_CHANNEL_INFO) * rfctl->max_chan_nums); + if (!resp) + return H2C_CMD_FAIL; + + resp->regd_src = rfctl->regd_src; + + if (rfctl->country_ent) { + _rtw_memcpy(&resp->country_ent, rfctl->country_ent, sizeof(struct country_chplan)); + resp->has_country = 1; + } else + resp->has_country = 0; + + resp->channel_plan = rfctl->ChannelPlan; +#if CONFIG_TXPWR_LIMIT + resp->regd_name = rfctl->regd_name; +#endif +#ifdef CONFIG_DFS_MASTER + resp->dfs_domain = rtw_rfctl_get_dfs_domain(rfctl); +#endif + resp->chset_num = rfctl->max_chan_nums; + + _rtw_memcpy(resp->chset, rfctl->channel_set, sizeof(RT_CHANNEL_INFO) * rfctl->max_chan_nums); + *param->resp = resp; + + return H2C_SUCCESS; +} + u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf) { struct LedBlink_param *ledBlink_param; @@ -16852,6 +16217,49 @@ u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf) return H2C_SUCCESS; } +void csa_timer_hdl(void *FunctionContext) +{ + _adapter *padapter = (_adapter *)FunctionContext; + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 i, update_beacon = _FALSE; + + for (i = 0; i < dvobj->iface_nums; i++) { + _adapter *iface; + iface = dvobj->padapters[i]; + if (!iface) + continue; + if (check_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON)) { + clr_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON); + update_beacon = _TRUE; + } + } + + /* wait beacons more than 70 seconds */ + if(update_beacon == _TRUE) { + RTW_INFO("wait beacons more than 70 seconds\n"); + return ; + } + + if(rfctl->csa_ch == 0) { + RTW_INFO("channel switch done\n"); + return ; + } + + /* channel switch */ + if (rtw_set_csa_cmd(padapter) != _SUCCESS) { + rfctl->csa_ch = 0; + rfctl->csa_switch_cnt = 0; + rfctl->csa_ch_offset = 0; + rfctl->csa_ch_width = 0; + rfctl->csa_ch_freq_seg0 = 0; + rfctl->csa_ch_freq_seg1 = 0; + } +} + u8 set_csa_hdl(_adapter *adapter, unsigned char *pbuf) { #if CONFIG_DFS @@ -16994,7 +16402,11 @@ u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf) rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk); /* switch back to base-chnl */ + doiqk = _TRUE; + rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk); set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + doiqk = _FALSE; + rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk); rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mp.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mp.c index a7e7b35e746e..cf47256a9f0b 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mp.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_mp.c @@ -394,7 +394,14 @@ void mpt_InitHWConfig(PADAPTER Adapter) PlatformEFIOWrite2Byte(Adapter, REG_RXFLTMAP1_8814B, 0x2000); } #endif - +#if defined(CONFIG_RTL8723F) + /* todo: 8723F not verify yet */ + else if (IS_HARDWARE_TYPE_8723F(Adapter)) { + /* 8723F mac is similar with 8723D, + * but can't find 8723D here. + */ + } +#endif } static void PHY_IQCalibrate(PADAPTER padapter, u8 bReCovery) @@ -519,6 +526,10 @@ static void PHY_SetRFPathSwitch(PADAPTER padapter , BOOLEAN bMain) { } else if (IS_HARDWARE_TYPE_8814B(padapter)) { #ifdef CONFIG_RTL8814B /* phy_set_rf_path_switch_8814b(phydm, bMain); */ +#endif + } else if (IS_HARDWARE_TYPE_8723F(padapter)) { +#ifdef CONFIG_RTL8723F + phy_set_rf_path_switch_8723f(phydm, bMain); #endif } } @@ -753,6 +764,7 @@ static void init_mp_data(PADAPTER padapter) pDM_Odm->rf_calibrate_info.txpowertrack_control = _FALSE; } + void MPT_PwrCtlDM(PADAPTER padapter, u32 trk_type) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); @@ -1283,7 +1295,7 @@ static struct xmit_frame *alloc_mp_xmitframe(struct xmit_priv *pxmitpriv) struct xmit_frame *pmpframe; struct xmit_buf *pxmitbuf; - pmpframe = rtw_alloc_xmitframe(pxmitpriv); + pmpframe = rtw_alloc_xmitframe(pxmitpriv, 0); if (pmpframe == NULL) return NULL; @@ -2006,6 +2018,11 @@ void SetPacketTx(PADAPTER padapter) rtl8814b_prepare_mp_txdesc(padapter, pmp_priv); #endif /* CONFIG_RTL8814B */ +#if defined(CONFIG_RTL8723F) + if (IS_HARDWARE_TYPE_8723F(padapter)) + rtl8723f_prepare_mp_txdesc(padapter, pmp_priv); +#endif /* CONFIG_RTL8723F */ + /* 3 4. make wlan header, make_wlanhdr() */ hdr = (struct rtw_ieee80211_hdr *)pkt_start; set_frame_sub_type(&hdr->frame_ctl, pattrib->subtype); @@ -2125,6 +2142,7 @@ void SetPacketRx(PADAPTER pAdapter, u8 bStartRx, u8 bAB) pHalData->ReceiveConfig |= RCR_APP_PHYST_RXFF; #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) +/* todo: 8723F */ write_bbreg(pAdapter, 0x550, BIT3, bEnable); #endif rtw_write16(pAdapter, REG_RXFLTMAP0, 0xFFEF); /* REG_RXFLTMAP0 (RX Filter Map Group 0) */ @@ -2366,7 +2384,9 @@ static u32 rtw_GetPSDData(PADAPTER pAdapter, u32 point) { u32 psd_val = 0; -#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) \ + || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) + u16 psd_reg = 0x910; u16 psd_regL = 0xF44; #else @@ -2441,12 +2461,12 @@ u32 mp_query_psd(PADAPTER pAdapter, u8 *data) data[0] = '\0'; pdata = data; - if (psd_stop > 1536 || psd_stop < 1) { + if (psd_stop > 1792 || psd_stop < 1) { rtw_warn_on(1); - psd_stop = 1536; + psd_stop = 1792; } - if (IS_HARDWARE_TYPE_8822C(pAdapter)) { + if (IS_HARDWARE_TYPE_8822C(pAdapter) || IS_HARDWARE_TYPE_8723F(pAdapter)) { u32 *psdbuf = rtw_zmalloc(sizeof(u32)*256); if (psdbuf == NULL) { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_odm.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_odm.c index 4c579971519a..b719fb0a2711 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_odm.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_odm.c @@ -179,24 +179,9 @@ void rtw_odm_releasespinlock(_adapter *adapter, enum rt_spinlock_type type) } } -inline u8 rtw_odm_get_dfs_domain(struct dvobj_priv *dvobj) +s16 rtw_odm_get_tx_power_mbm(struct dm_struct *dm, u8 rfpath, u8 rate, u8 bw, u8 cch) { -#ifdef CONFIG_DFS_MASTER - struct dm_struct *pDM_Odm = dvobj_to_phydm(dvobj); - - return pDM_Odm->dfs_region_domain; -#else - return PHYDM_DFS_DOMAIN_UNKNOWN; -#endif -} - -inline u8 rtw_odm_dfs_domain_unknown(struct dvobj_priv *dvobj) -{ -#ifdef CONFIG_DFS_MASTER - return rtw_odm_get_dfs_domain(dvobj) == PHYDM_DFS_DOMAIN_UNKNOWN; -#else - return 1; -#endif + return phy_get_txpwr_single_mbm(dm->adapter, rfpath, mgn_rate_to_rs(rate), rate, bw, cch, 0, 0, 0, NULL); } #ifdef CONFIG_DFS_MASTER @@ -221,6 +206,20 @@ inline BOOLEAN rtw_odm_radar_detect(_adapter *adapter) return phydm_radar_detect(adapter_to_phydm(adapter)); } +static enum phydm_dfs_region_domain _rtw_dfs_regd_to_phydm[] = { + [RTW_DFS_REGD_NONE] = PHYDM_DFS_DOMAIN_UNKNOWN, + [RTW_DFS_REGD_FCC] = PHYDM_DFS_DOMAIN_FCC, + [RTW_DFS_REGD_MKK] = PHYDM_DFS_DOMAIN_MKK, + [RTW_DFS_REGD_ETSI] = PHYDM_DFS_DOMAIN_ETSI, +}; + +#define rtw_dfs_regd_to_phydm(region) (((region) >= RTW_DFS_REGD_NUM) ? _rtw_dfs_regd_to_phydm[RTW_DFS_REGD_NONE] : _rtw_dfs_regd_to_phydm[(region)]) + +void rtw_odm_update_dfs_region(struct dvobj_priv *dvobj) +{ + odm_cmn_info_init(dvobj_to_phydm(dvobj), ODM_CMNINFO_DFS_REGION_DOMAIN, rtw_dfs_regd_to_phydm(rtw_rfctl_get_dfs_domain(dvobj_to_rfctl(dvobj)))); +} + inline u8 rtw_odm_radar_detect_polling_int_ms(struct dvobj_priv *dvobj) { return phydm_dfs_polling_time(dvobj_to_phydm(dvobj)); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_p2p.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_p2p.c index 204bbf3be1c6..41c51c99842b 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_p2p.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_p2p.c @@ -2912,6 +2912,7 @@ u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo, u8 *pfr { #ifdef CONFIG_CONCURRENT_MODE _adapter *padapter = pwdinfo->padapter; + struct roch_info *prochinfo = &padapter->rochinfo; #endif u8 *ies; u32 ies_len; @@ -2957,7 +2958,7 @@ u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo, u8 *pfr if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) { /* Switch back to the AP channel soon. */ - _set_timer(&pwdinfo->ap_p2p_switch_timer, 100); + _set_timer(&prochinfo->ap_roch_ch_switch_timer, 100); } #endif } else { @@ -3030,8 +3031,6 @@ void find_phase_handler(_adapter *padapter) } -void p2p_concurrent_handler(_adapter *padapter); - void restore_p2p_state_handler(_adapter *padapter) { struct wifidirect_info *pwdinfo = &padapter->wdinfo; @@ -3056,7 +3055,7 @@ void restore_p2p_state_handler(_adapter *padapter) if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) { #ifdef CONFIG_CONCURRENT_MODE - p2p_concurrent_handler(padapter); + rtw_concurrent_handler(padapter); #else /* In the P2P client mode, the driver should not switch back to its listen channel */ /* because this P2P client should stay at the operating channel of P2P GO. */ @@ -3103,344 +3102,7 @@ void pre_tx_negoreq_handler(_adapter *padapter) } -#ifdef CONFIG_CONCURRENT_MODE -void p2p_concurrent_handler(_adapter *padapter) -{ - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - u8 val8; - #ifdef CONFIG_IOCTL_CFG80211 - if (pwdinfo->driver_interface == DRIVER_CFG80211 - && !rtw_cfg80211_get_is_roch(padapter)) - return; -#endif - - if (rtw_mi_check_status(padapter, MI_LINKED)) { - u8 union_ch = rtw_mi_get_union_chan(padapter); - u8 union_bw = rtw_mi_get_union_bw(padapter); - u8 union_offset = rtw_mi_get_union_offset(padapter); - - pwdinfo->operating_channel = union_ch; - - if (pwdinfo->driver_interface == DRIVER_CFG80211) { - RTW_INFO("%s, switch ch back to union=%u,%u, %u\n" - , __func__, union_ch, union_bw, union_offset); - set_channel_bwmode(padapter, union_ch, union_offset, union_bw); - rtw_back_opch(padapter); - - } else if (pwdinfo->driver_interface == DRIVER_WEXT) { - if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) { - /* Now, the driver stays on the AP's channel. */ - /* If the pwdinfo->ext_listen_period = 0, that means the P2P listen state is not available on listen channel. */ - if (pwdinfo->ext_listen_period > 0) { - RTW_INFO("[%s] P2P_STATE_IDLE, ext_listen_period = %d\n", __FUNCTION__, pwdinfo->ext_listen_period); - - if (union_ch != pwdinfo->listen_channel) { - rtw_leave_opch(padapter); - set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - } - - rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); - - if (!rtw_mi_check_mlmeinfo_state(padapter, WIFI_FW_AP_STATE)) { - val8 = 1; - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - } - /* Todo: To check the value of pwdinfo->ext_listen_period is equal to 0 or not. */ - _set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period); - } - - } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) || - rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL) || - (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _FALSE) || - rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ)) { - /* Now, the driver is in the listen state of P2P mode. */ - RTW_INFO("[%s] P2P_STATE_IDLE, ext_listen_interval = %d\n", __FUNCTION__, pwdinfo->ext_listen_interval); - - /* Commented by Albert 2012/11/01 */ - /* If the AP's channel is the same as the listen channel, we should still be in the listen state */ - /* Other P2P device is still able to find this device out even this device is in the AP's channel. */ - /* So, configure this device to be able to receive the probe request frame and set it to listen state. */ - if (union_ch != pwdinfo->listen_channel) { - - set_channel_bwmode(padapter, union_ch, union_offset, union_bw); - if (!rtw_mi_check_status(padapter, MI_AP_MODE)) { - val8 = 0; - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - } - rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE); - rtw_back_opch(padapter); - } - - /* Todo: To check the value of pwdinfo->ext_listen_interval is equal to 0 or not. */ - _set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval); - - } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK)) { - /* The driver had finished the P2P handshake successfully. */ - val8 = 0; - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - set_channel_bwmode(padapter, union_ch, union_offset, union_bw); - rtw_back_opch(padapter); - - } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) { - val8 = 1; - set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - issue_probereq_p2p(padapter, NULL); - _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); - } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _TRUE) { - val8 = 1; - set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - issue_probereq_p2p(padapter, NULL); - _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); - } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ) && pwdinfo->invitereq_info.benable == _TRUE) { - /* - val8 = 1; - set_channel_bwmode(padapter, , HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); - issue_probereq_p2p(padapter, NULL); - _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); - */ - } - } - } else { - /* In p2p+softap. When in P2P_STATE_GONEGO_OK, not back to listen channel.*/ - if (!rtw_p2p_chk_state(pwdinfo , P2P_STATE_GONEGO_OK) || padapter->registrypriv.full_ch_in_p2p_handshake == 0) - set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - else - RTW_INFO("%s, buddy not linked, go nego ok, not back to listen channel\n", __func__); - } - -} -#endif - -#ifdef CONFIG_IOCTL_CFG80211 -u8 roch_stay_in_cur_chan(_adapter *padapter) -{ - int i; - _adapter *iface; - struct mlme_priv *pmlmepriv; - struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); - u8 rst = _FALSE; - - for (i = 0; i < dvobj->iface_nums; i++) { - iface = dvobj->padapters[i]; - if (iface) { - pmlmepriv = &iface->mlmepriv; - - if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS | WIFI_UNDER_KEY_HANDSHAKE) == _TRUE) { - RTW_INFO(ADPT_FMT"- WIFI_UNDER_LINKING |WIFI_UNDER_WPS | WIFI_UNDER_KEY_HANDSHAKE (mlme state:0x%x)\n", - ADPT_ARG(iface), get_fwstate(&iface->mlmepriv)); - rst = _TRUE; - break; - } - #ifdef CONFIG_AP_MODE - if (MLME_IS_AP(iface) || MLME_IS_MESH(iface)) { - if (rtw_ap_sta_states_check(iface) == _TRUE) { - rst = _TRUE; - break; - } - } - #endif - } - } - - return rst; -} - -static int ro_ch_handler(_adapter *adapter, u8 *buf) -{ - int ret = H2C_SUCCESS; - struct p2p_roch_parm *roch_parm = (struct p2p_roch_parm *)buf; - struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); - struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &adapter->cfg80211_wdinfo; -#ifdef CONFIG_CONCURRENT_MODE - struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; -#ifdef RTW_ROCH_BACK_OP - struct wifidirect_info *pwdinfo = &adapter->wdinfo; -#endif -#endif - u8 ready_on_channel = _FALSE; - u8 remain_ch; - unsigned int duration; - - _enter_critical_mutex(&pwdev_priv->roch_mutex, NULL); - - if (rtw_cfg80211_get_is_roch(adapter) != _TRUE) - goto exit; - - remain_ch = (u8)ieee80211_frequency_to_channel(roch_parm->ch.center_freq); - duration = roch_parm->duration; - - RTW_INFO(FUNC_ADPT_FMT" ch:%u duration:%d, cookie:0x%llx\n" - , FUNC_ADPT_ARG(adapter), remain_ch, roch_parm->duration, roch_parm->cookie); - - if (roch_parm->wdev && roch_parm->cookie) { - if (pcfg80211_wdinfo->ro_ch_wdev != roch_parm->wdev) { - RTW_WARN(FUNC_ADPT_FMT" ongoing wdev:%p, wdev:%p\n" - , FUNC_ADPT_ARG(adapter), pcfg80211_wdinfo->ro_ch_wdev, roch_parm->wdev); - rtw_warn_on(1); - } - - if (pcfg80211_wdinfo->remain_on_ch_cookie != roch_parm->cookie) { - RTW_WARN(FUNC_ADPT_FMT" ongoing cookie:0x%llx, cookie:0x%llx\n" - , FUNC_ADPT_ARG(adapter), pcfg80211_wdinfo->remain_on_ch_cookie, roch_parm->cookie); - rtw_warn_on(1); - } - } - - if (roch_stay_in_cur_chan(adapter) == _TRUE) { - remain_ch = rtw_mi_get_union_chan(adapter); - RTW_INFO(FUNC_ADPT_FMT" stay in union ch:%d\n", FUNC_ADPT_ARG(adapter), remain_ch); - } - - #ifdef CONFIG_CONCURRENT_MODE - if (rtw_mi_check_status(adapter, MI_LINKED) && (0 != rtw_mi_get_union_chan(adapter))) { - if ((remain_ch != rtw_mi_get_union_chan(adapter)) && !check_fwstate(&adapter->mlmepriv, WIFI_ASOC_STATE)) { - if (remain_ch != pmlmeext->cur_channel - #ifdef RTW_ROCH_BACK_OP - || ATOMIC_READ(&pwdev_priv->switch_ch_to) == 1 - #endif - ) { - rtw_leave_opch(adapter); - - #ifdef RTW_ROCH_BACK_OP - RTW_INFO("%s, set switch ch timer, duration=%d\n", __func__, duration - pwdinfo->ext_listen_interval); - ATOMIC_SET(&pwdev_priv->switch_ch_to, 0); - _set_timer(&pwdinfo->ap_p2p_switch_timer, duration - pwdinfo->ext_listen_interval); - #endif - } - } - ready_on_channel = _TRUE; - } else - #endif /* CONFIG_CONCURRENT_MODE */ - { - if (remain_ch != rtw_get_oper_ch(adapter)) - ready_on_channel = _TRUE; - } - - if (ready_on_channel == _TRUE) { - #ifndef RTW_SINGLE_WIPHY - if (!check_fwstate(&adapter->mlmepriv, WIFI_ASOC_STATE)) - #endif - { - #ifdef CONFIG_CONCURRENT_MODE - if (rtw_get_oper_ch(adapter) != remain_ch) - #endif - { - /* if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic) */ - set_channel_bwmode(adapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - } - } - } - - #ifdef CONFIG_BT_COEXIST - rtw_btcoex_ScanNotify(adapter, _TRUE); - #endif - - RTW_INFO("%s, set ro ch timer, duration=%d\n", __func__, duration); - _set_timer(&pcfg80211_wdinfo->remain_on_ch_timer, duration); - -exit: - _exit_critical_mutex(&pwdev_priv->roch_mutex, NULL); - - return ret; -} - -static int cancel_ro_ch_handler(_adapter *padapter, u8 *buf) -{ - int ret = H2C_SUCCESS; - struct p2p_roch_parm *roch_parm = (struct p2p_roch_parm *)buf; - struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); - struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; - struct wireless_dev *wdev; - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - u8 ch, bw, offset; - - _enter_critical_mutex(&pwdev_priv->roch_mutex, NULL); - - if (rtw_cfg80211_get_is_roch(padapter) != _TRUE) - goto exit; - - if (roch_parm->wdev && roch_parm->cookie) { - if (pcfg80211_wdinfo->ro_ch_wdev != roch_parm->wdev) { - RTW_WARN(FUNC_ADPT_FMT" ongoing wdev:%p, wdev:%p\n" - , FUNC_ADPT_ARG(padapter), pcfg80211_wdinfo->ro_ch_wdev, roch_parm->wdev); - rtw_warn_on(1); - } - - if (pcfg80211_wdinfo->remain_on_ch_cookie != roch_parm->cookie) { - RTW_WARN(FUNC_ADPT_FMT" ongoing cookie:0x%llx, cookie:0x%llx\n" - , FUNC_ADPT_ARG(padapter), pcfg80211_wdinfo->remain_on_ch_cookie, roch_parm->cookie); - rtw_warn_on(1); - } - } - -#if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) - _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer); - ATOMIC_SET(&pwdev_priv->switch_ch_to, 1); -#endif - - if (rtw_mi_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { - if (0) - RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", - FUNC_ADPT_ARG(padapter), ch, bw, offset); - } else if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->listen_channel) { - ch = pwdinfo->listen_channel; - bw = CHANNEL_WIDTH_20; - offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - if (0) - RTW_INFO(FUNC_ADPT_FMT" back to listen ch - ch:%u, bw:%u, offset:%u\n", - FUNC_ADPT_ARG(padapter), ch, bw, offset); - } else { - ch = pcfg80211_wdinfo->restore_channel; - bw = CHANNEL_WIDTH_20; - offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - if (0) - RTW_INFO(FUNC_ADPT_FMT" back to restore ch - ch:%u, bw:%u, offset:%u\n", - FUNC_ADPT_ARG(padapter), ch, bw, offset); - } - - set_channel_bwmode(padapter, ch, offset, bw); - rtw_back_opch(padapter); - - rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); -#ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo)); -#endif - - wdev = pcfg80211_wdinfo->ro_ch_wdev; - - rtw_cfg80211_set_is_roch(padapter, _FALSE); - pcfg80211_wdinfo->ro_ch_wdev = NULL; - rtw_cfg80211_set_last_ro_ch_time(padapter); - - rtw_cfg80211_remain_on_channel_expired(wdev - , pcfg80211_wdinfo->remain_on_ch_cookie - , &pcfg80211_wdinfo->remain_on_ch_channel - , pcfg80211_wdinfo->remain_on_ch_type, GFP_KERNEL); - - RTW_INFO("cfg80211_remain_on_channel_expired cookie:0x%llx\n" - , pcfg80211_wdinfo->remain_on_ch_cookie); - -#ifdef CONFIG_BT_COEXIST - rtw_btcoex_ScanNotify(padapter, _FALSE); -#endif - -exit: - _exit_critical_mutex(&pwdev_priv->roch_mutex, NULL); - - return ret; -} - -static void ro_ch_timer_process(void *FunctionContext) -{ - _adapter *adapter = (_adapter *)FunctionContext; - - p2p_cancel_roch_cmd(adapter, 0, NULL, 0); -} #if 0 static void rtw_change_p2pie_op_ch(_adapter *padapter, const u8 *frame_body, u32 len, u8 ch) @@ -4276,15 +3938,6 @@ int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx) return is_p2p_frame; } - -void rtw_init_cfg80211_wifidirect_info(_adapter *padapter) -{ - struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; - - _rtw_memset(pcfg80211_wdinfo, 0x00, sizeof(struct cfg80211_wifidirect_info)); - - rtw_init_timer(&pcfg80211_wdinfo->remain_on_ch_timer, padapter, ro_ch_timer_process, padapter); -} #endif /* CONFIG_IOCTL_CFG80211 */ s32 p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf) @@ -4303,7 +3956,7 @@ s32 p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf) case P2P_PRE_TX_PROVDISC_PROCESS_WK: #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_check_status(padapter, MI_LINKED)) - p2p_concurrent_handler(padapter); + rtw_concurrent_handler(padapter); else pre_tx_provdisc_handler(padapter); #else @@ -4314,7 +3967,7 @@ s32 p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf) case P2P_PRE_TX_INVITEREQ_PROCESS_WK: #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_check_status(padapter, MI_LINKED)) - p2p_concurrent_handler(padapter); + rtw_concurrent_handler(padapter); else pre_tx_invitereq_handler(padapter); #else @@ -4325,7 +3978,7 @@ s32 p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf) case P2P_PRE_TX_NEGOREQ_PROCESS_WK: #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_check_status(padapter, MI_LINKED)) - p2p_concurrent_handler(padapter); + rtw_concurrent_handler(padapter); else pre_tx_negoreq_handler(padapter); #else @@ -4333,21 +3986,6 @@ s32 p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf) #endif break; -#ifdef CONFIG_CONCURRENT_MODE - case P2P_AP_P2P_CH_SWITCH_PROCESS_WK: - p2p_concurrent_handler(padapter); - break; -#endif - -#ifdef CONFIG_IOCTL_CFG80211 - case P2P_RO_CH_WK: - ret = ro_ch_handler(padapter, buf); - break; - case P2P_CANCEL_RO_CH_WK: - ret = cancel_ro_ch_handler(padapter, buf); - break; -#endif - default: rtw_warn_on(1); break; @@ -4500,13 +4138,16 @@ void p2p_ps_wk_hdl(_adapter *padapter, u8 p2p_ps_state) rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); +#ifdef CONFIG_LPS if (pwdinfo->opp_ps == 1) { if (pwrpriv->smart_ps == 0) { pwrpriv->smart_ps = 2; if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) - rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(pwrpriv->pwr_mode))); + rtw_exec_lps(padapter, pwrpriv->pwr_mode); } } +#endif /* CONFIG_LPS */ + pwdinfo->noa_index = 0; pwdinfo->ctwindow = 0; pwdinfo->opp_ps = 0; @@ -4537,14 +4178,17 @@ void p2p_ps_wk_hdl(_adapter *padapter, u8 p2p_ps_state) #endif /* CONFIG_MCC_MODE */ pwdinfo->p2p_ps_state = p2p_ps_state; +#ifdef CONFIG_LPS if (pwdinfo->ctwindow > 0) { if (pwrpriv->smart_ps != 0) { pwrpriv->smart_ps = 0; RTW_INFO("%s(): Enter CTW, change SmartPS\n", __FUNCTION__); if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) - rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(pwrpriv->pwr_mode))); + rtw_exec_lps(padapter, pwrpriv->pwr_mode); } } +#endif /* CONFIG_LPS */ + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); } break; @@ -4709,26 +4353,6 @@ static void find_phase_timer_process(void *FunctionContext) p2p_protocol_wk_cmd(adapter, P2P_FIND_PHASE_WK); } -#ifdef CONFIG_CONCURRENT_MODE -void ap_p2p_switch_timer_process(void *FunctionContext) -{ - _adapter *adapter = (_adapter *)FunctionContext; - struct wifidirect_info *pwdinfo = &adapter->wdinfo; -#ifdef CONFIG_IOCTL_CFG80211 - struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); -#endif - - if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) - return; - -#ifdef CONFIG_IOCTL_CFG80211 - ATOMIC_SET(&pwdev_priv->switch_ch_to, 1); -#endif - - p2p_protocol_wk_cmd(adapter, P2P_AP_P2P_CH_SWITCH_PROCESS_WK); -} -#endif - void reset_global_wifidirect_info(_adapter *padapter) { struct wifidirect_info *pwdinfo; @@ -4960,9 +4584,6 @@ void rtw_init_wifidirect_timers(_adapter *padapter) rtw_init_timer(&pwdinfo->pre_tx_scan_timer, padapter, pre_tx_scan_timer_process, padapter); rtw_init_timer(&pwdinfo->reset_ch_sitesurvey, padapter, reset_ch_sitesurvey_timer_process, padapter); rtw_init_timer(&pwdinfo->reset_ch_sitesurvey2, padapter, reset_ch_sitesurvey_timer_process2, padapter); -#ifdef CONFIG_CONCURRENT_MODE - rtw_init_timer(&pwdinfo->ap_p2p_switch_timer, padapter, ap_p2p_switch_timer_process, padapter); -#endif } void rtw_init_wifidirect_addrs(_adapter *padapter, u8 *dev_addr, u8 *iface_addr) @@ -5289,6 +4910,9 @@ int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role) { int ret = _SUCCESS; struct wifidirect_info *pwdinfo = &(padapter->wdinfo); +#ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#endif if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT || role == P2P_ROLE_GO) { #if defined(CONFIG_CONCURRENT_MODE) && (!defined(RTW_P2P_GROUP_INTERFACE) || !RTW_P2P_GROUP_INTERFACE) @@ -5352,7 +4976,7 @@ int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role) reset_ch_sitesurvey_timer_process(padapter); reset_ch_sitesurvey_timer_process2(padapter); #ifdef CONFIG_CONCURRENT_MODE - _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer); + _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer); #endif rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE); rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_NONE); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_pwrctrl.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_pwrctrl.c index f5e32ce18f2a..cc3101867f55 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_pwrctrl.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_pwrctrl.c @@ -233,7 +233,7 @@ bool rtw_pwr_unassociated_idle(_adapter *adapter) || MLME_IS_AP(iface) || MLME_IS_MESH(iface) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) - #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) + #if defined(CONFIG_IOCTL_CFG80211) || rtw_cfg80211_get_is_roch(iface) == _TRUE || (rtw_cfg80211_is_ro_ch_once(adapter) && rtw_cfg80211_get_last_ro_ch_passing_ms(adapter) < 3000) @@ -666,7 +666,7 @@ u8 PS_RDY_CHECK(_adapter *padapter) || MLME_IS_MESH(padapter) || MLME_IS_MONITOR(padapter) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) - #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) + #if defined(CONFIG_IOCTL_CFG80211) || rtw_cfg80211_get_is_roch(padapter) == _TRUE #endif || rtw_is_scan_deny(padapter) @@ -809,22 +809,126 @@ void rtw_set_fw_in_ips_mode(PADAPTER padapter, u8 enable) } #endif /* CONFIG_PNO_SUPPORT */ - -void rtw_leave_lps_and_chk(_adapter *padapter, u8 ps_mode) +void rtw_exec_lps(_adapter *padapter, u8 ps_mode) { struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + if (ps_mode == PS_MODE_ACTIVE) { +#ifdef CONFIG_LPS_ACK + _enter_critical_mutex(&pwrpriv->lps_ack_mutex, NULL); + rtw_sctx_init(&pwrpriv->lps_ack_sctx, 100); +#endif /* CONFIG_LPS_ACK */ + + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); + rtw_hal_set_hwreg(padapter, HW_VAR_LPS_STATE_CHK, (u8 *)(&ps_mode)); + +#ifdef CONFIG_LPS_ACK + _exit_critical_mutex(&pwrpriv->lps_ack_mutex, NULL); +#endif /* CONFIG_LPS_ACK */ + } else { + if (MLME_IS_ASOC(padapter)) + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); + else + RTW_INFO(FUNC_ADPT_FMT": It can't execute LPS without Wi-Fi connection!\n", + FUNC_ADPT_ARG(padapter)); + } +} + +void rtw_lps_rfon_ctrl(_adapter *padapter, u8 rfon_ctrl) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + u8 rpwm = 0; + + if (pwrpriv->bFwCurrentInPSMode && pwrpriv->pwr_mode != PS_MODE_ACTIVE) { + if (rfon_ctrl == rf_on) { +#ifdef CONFIG_LPS_LCLK + if (pwrpriv->lps_level >= LPS_LCLK) { + s32 ready = _FAIL; + systime stime; + s32 utime; + u32 timeout; /* unit: ms */ + +#ifdef LPS_RPWM_WAIT_MS + timeout = LPS_RPWM_WAIT_MS; +#else + timeout = 30; +#endif /* !LPS_RPWM_WAIT_MS */ + + stime = rtw_get_current_time(); + do { + ready = rtw_register_task_alive(padapter, LPS_ALIVE); + if (ready == _SUCCESS) + break; + + utime = rtw_get_passing_time_ms(stime); + if (utime > timeout) + break; + + rtw_msleep_os(1); + } while (1); + + if (ready == _FAIL) + RTW_INFO(FUNC_ADPT_FMT": It is not ready to leave 32K !!!\n", + FUNC_ADPT_ARG(padapter)); + } +#endif /* CONFIG_LPS_LCLK */ + #ifdef CONFIG_LPS_ACK _enter_critical_mutex(&pwrpriv->lps_ack_mutex, NULL); rtw_sctx_init(&pwrpriv->lps_ack_sctx, 100); #endif /* CONFIG_LPS_ACK */ - rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); - rtw_hal_set_hwreg(padapter, HW_VAR_LPS_STATE_CHK, (u8 *)(&ps_mode)); + + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE_RFON_CTRL, (u8 *)(&rfon_ctrl)); + rtw_hal_set_hwreg(padapter, HW_VAR_LPS_RFON_CHK, (u8 *)(&rfon_ctrl)); #ifdef CONFIG_LPS_ACK _exit_critical_mutex(&pwrpriv->lps_ack_mutex, NULL); #endif /* CONFIG_LPS_ACK */ - + } else { + if (MLME_IS_ASOC(padapter)) { +#ifdef CONFIG_LPS_PG + if (pwrpriv->lps_level == LPS_PG) { + if (rtw_hal_set_lps_pg_info_cmd(padapter) == _FAIL) + RTW_INFO(FUNC_ADPT_FMT": Send PG H2C command Fail! \n", + FUNC_ADPT_ARG(padapter)); + } +#endif /* CONFIG_LPS_PG */ + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE_RFON_CTRL, (u8 *)(&rfon_ctrl)); + } else { + RTW_INFO(FUNC_ADPT_FMT": It can't execute RFON without Wi-Fi connection!\n", + FUNC_ADPT_ARG(padapter)); + } + +#ifdef CONFIG_LPS_LCLK + if (pwrpriv->lps_level >= LPS_LCLK) { + rtw_unregister_task_alive(padapter, LPS_ALIVE); + + if (pwrpriv->alives == 0) { + u8 polling_cnt = 0; + u8 reg_val8 = 0; + u8 result = _FAIL; + + do { + rtw_msleep_os(1); + reg_val8 = rtw_read8(padapter, REG_CR); + if (reg_val8 == 0xEA) { + result= _SUCCESS; + break; + } + polling_cnt++; + } while (polling_cnt < 100); + + if (result == _FAIL ) + RTW_INFO(FUNC_ADPT_FMT": It is not finished to enter 32K !!!\n", + FUNC_ADPT_ARG(padapter)); + } + } +#endif /* CONFIG_LPS_LCLK */ + } + } else { + RTW_INFO(FUNC_ADPT_FMT": RFON can't work due to ps state is not in LPS !\n", + FUNC_ADPT_ARG(padapter)); + } } void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode, const char *msg) @@ -972,7 +1076,7 @@ void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode rtw_hal_set_hwreg(padapter, HW_VAR_H2C_INACTIVE_IPS, (u8 *)(&ps_mode)); #endif /* CONFIG_WOWLAN */ - rtw_leave_lps_and_chk(padapter, ps_mode); + rtw_exec_lps(padapter, ps_mode); #ifdef CONFIG_LPS_PG if (pwrpriv->lps_level == LPS_PG) { @@ -1053,9 +1157,8 @@ void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode pwrpriv->wmm_smart_ps = pregistrypriv->wmm_smart_ps; #endif /* CONFIG_WMMPS_STA */ + rtw_exec_lps(padapter, ps_mode); - if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) - rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); #ifdef CONFIG_WOWLAN if (pwrpriv->wowlan_mode == _TRUE) rtw_hal_set_hwreg(padapter, HW_VAR_H2C_INACTIVE_IPS, (u8 *)(&ps_mode)); @@ -1519,7 +1622,8 @@ static void dma_event_callback(struct work_struct *work) #ifdef CONFIG_LPS_RPWM_TIMER #define DBG_CPWM_CHK_FAIL -#if defined(DBG_CPWM_CHK_FAIL) && (defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)) +#if defined(DBG_CPWM_CHK_FAIL) && (defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) \ + || defined(CONFIG_RTL8723F)) #define CPU_EXCEPTION_CODE 0xFAFAFAFA static void rtw_cpwm_chk_fail_debug(_adapter *padapter) { @@ -1588,7 +1692,8 @@ static void rpwmtimeout_workitem_callback(struct work_struct *work) pwrpriv->rpwm_retry = 0; _exit_pwrlock(&pwrpriv->lock); -#if defined(DBG_CPWM_CHK_FAIL) && (defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)) +#if defined(DBG_CPWM_CHK_FAIL) && (defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) \ + || defined(CONFIG_RTL8723F)) RTW_INFO("+%s: rpwm=0x%02X cpwm=0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm); rtw_cpwm_chk_fail_debug(padapter); #endif @@ -2085,7 +2190,7 @@ void rtw_init_pwrctrl_priv(PADAPTER padapter) struct registry_priv *registry_par = &padapter->registrypriv; #endif #ifdef CONFIG_GPIO_WAKEUP - u8 val8 = 0; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); #endif #if defined(CONFIG_CONCURRENT_MODE) @@ -2192,23 +2297,38 @@ void rtw_init_pwrctrl_priv(PADAPTER padapter) #endif /* CONFIG_HAS_EARLYSUSPEND || CONFIG_ANDROID_POWER */ #ifdef CONFIG_GPIO_WAKEUP + pwrctrlpriv->wowlan_gpio_index = WAKEUP_GPIO_IDX; + /* set output low state in initial */ + pwrctrlpriv->wowlan_gpio_output_state = GPIO_OUTPUT_LOW; /*default low active*/ pwrctrlpriv->is_high_active = HIGH_ACTIVE_DEV2HST; pwrctrlpriv->hst2dev_high_active = HIGH_ACTIVE_HST2DEV; + +#if (defined(CONFIG_RTL8192F) && defined(CONFIG_USB_HCI) && defined(CONFIG_BT_COEXIST)) + if (pHalData->EEPROMBluetoothCoexist == _TRUE) { + /* for 8725AU case */ + pwrctrlpriv->wowlan_gpio_index = WAKEUP_GPIO_IDX_8725AU; + pwrctrlpriv->is_high_active = HIGH_ACTIVE_DEV2HST_8725AU; + } +#endif #ifdef CONFIG_RTW_ONE_PIN_GPIO - rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE); - rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX); + rtw_hal_switch_gpio_wl_ctrl(padapter, pwrctrlpriv->wowlan_gpio_index, _TRUE); + rtw_hal_set_input_gpio(padapter, pwrctrlpriv->wowlan_gpio_index); #else #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE if (pwrctrlpriv->is_high_active == 0) - rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX); + rtw_hal_set_input_gpio(padapter, pwrctrlpriv->wowlan_gpio_index); else - rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, 0); + rtw_hal_set_output_gpio(padapter, pwrctrlpriv->wowlan_gpio_index, + GPIO_OUTPUT_LOW); #else - val8 = (pwrctrlpriv->is_high_active == 0) ? 1 : 0; - rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8); - RTW_INFO("%s: set GPIO_%d %d as default.\n", - __func__, WAKEUP_GPIO_IDX, val8); + rtw_hal_set_output_gpio(padapter, pwrctrlpriv->wowlan_gpio_index + , pwrctrlpriv->wowlan_gpio_output_state); + rtw_hal_switch_gpio_wl_ctrl(padapter, pwrctrlpriv->wowlan_gpio_index, _TRUE); + RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in initial and %s_ACTIVE.\n", + __func__, pwrctrlpriv->wowlan_gpio_index, + pwrctrlpriv->wowlan_gpio_output_state ? "HIGH" : "LOW", + pwrctrlpriv->is_high_active ? "HIGI" : "LOW"); #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/ #endif /* CONFIG_RTW_ONE_PIN_GPIO */ #endif /* CONFIG_GPIO_WAKEUP */ @@ -2248,7 +2368,17 @@ void rtw_init_pwrctrl_priv(PADAPTER padapter) #ifdef CONFIG_WOW_PATTERN_HW_CAM _rtw_mutex_init(&pwrctrlpriv->wowlan_pattern_cam_mutex); #endif + +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + pwrctrlpriv->wowlan_keep_alive_ack_index = 0xFF; + pwrctrlpriv->wowlan_wake_pattern_index = 0xFF; +#endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ pwrctrlpriv->wowlan_aoac_rpt_loc = 0; +#ifdef CONFIG_WAR_OFFLOAD +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) + rtw_wow_war_mdns_parms_reset(padapter, _TRUE); +#endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */ +#endif /* CONFIG_WAR_OFFLOAD */ #endif /* CONFIG_WOWLAN */ #ifdef CONFIG_LPS_POFF diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_recv.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_recv.c index b176ce5cbc77..e68c5b30da4d 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_recv.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_recv.c @@ -1114,6 +1114,102 @@ exit: return ret; } + +sint rtw_tdls_rx_data_validate_hdr( + _adapter *adapter, + union recv_frame *precv_frame, + struct sta_info **psta +) +{ + u8 *ptr = precv_frame->u.hdr.rx_data; + sint ret = _SUCCESS; + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &adapter->stapriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + u8 *mybssid = get_bssid(pmlmepriv); + u8 *myhwaddr = adapter_mac_addr(adapter); + u8 *sta_addr = pattrib->ta; + sint bmcast = IS_MCAST(pattrib->dst); + + struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; +#ifdef CONFIG_TDLS_CH_SW + struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info; +#endif + struct sta_info *ptdls_sta = NULL; + u8 *psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE; + /* frame body located after [+2]: ether-type, [+1]: payload type */ + u8 *pframe_body = psnap_type + 2 + 1; + + *psta = ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->ta); + if (ptdls_sta == NULL) { + ret = _FAIL; + goto exit; + } else if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) { + /* filter packets that SA is myself or multicast or broadcast */ + if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) { + ret = _FAIL; + goto exit; + } + /* da should be for me */ + if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) { + ret = _FAIL; + goto exit; + } + /* check BSSID */ + if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) { + ret = _FAIL; + goto exit; + } + +#ifdef CONFIG_TDLS_CH_SW + if (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE) { + if (adapter->mlmeextpriv.cur_channel != rtw_get_oper_ch(adapter)) { + pchsw_info->ch_sw_state |= TDLS_PEER_AT_OFF_STATE; + if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE)) + _cancel_timer_ex(&ptdls_sta->ch_sw_timer); + /* On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame); */ + } + } +#endif + + /* process UAPSD tdls sta */ + process_pwrbit_data(adapter, precv_frame, ptdls_sta); + + /* if NULL-frame, check pwrbit */ + if ((get_frame_sub_type(ptr) & WIFI_DATA_NULL) == WIFI_DATA_NULL) { + /* NULL-frame with pwrbit=1, buffer_STA should buffer frames for sleep_STA */ + if (GetPwrMgt(ptr)) { + /* it would be triggered when we are off channel and receiving NULL DATA */ + /* we can confirm that peer STA is at off channel */ + RTW_INFO("TDLS: recv peer null frame with pwr bit 1\n"); + /* ptdls_sta->tdls_sta_state|=TDLS_PEER_SLEEP_STATE; */ + } + + /* TODO: Updated BSSID's seq. */ + /* RTW_INFO("drop Null Data\n"); */ + ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE); + ret = _FAIL; + goto exit; + } + + /* receive some of all TDLS management frames, process it at ON_TDLS */ + if (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, 2)) { + ret = OnTDLS(adapter, precv_frame); + goto exit; + } + + if ((get_frame_sub_type(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) + process_wmmps_data(adapter, precv_frame, ptdls_sta); + + ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE); + + } + +exit: + return ret; +} #endif /* CONFIG_TDLS */ void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_info *sta) @@ -1177,6 +1273,157 @@ void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_in } +int rtw_sta_rx_data_validate_hdr(_adapter *adapter, union recv_frame *rframe, struct sta_info **sta) +{ + struct sta_priv *stapriv = &adapter->stapriv; + u8 *mybssid = get_bssid(&adapter->mlmepriv); + u8 *myhwaddr = adapter_mac_addr(adapter); + struct rx_pkt_attrib *rattrib = &rframe->u.hdr.attrib; + u8 *whdr = get_recvframe_data(rframe); + u8 is_ra_bmc = IS_MCAST(GetAddr1Ptr(whdr)) ? 1 : 0; + sint ret = _FAIL; + + if (rattrib->to_fr_ds == 0) { + _rtw_memcpy(rattrib->ra, GetAddr1Ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->ta, get_addr2_ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->dst, GetAddr1Ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->src, get_addr2_ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->bssid, GetAddr3Ptr(whdr), ETH_ALEN); + + #ifdef CONFIG_TDLS + if (adapter->tdlsinfo.link_established == _TRUE) + ret = rtw_tdls_rx_data_validate_hdr(adapter, rframe, sta); + else + #endif + { + /* For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */ + if (!_rtw_memcmp(rattrib->bssid, rattrib->src, ETH_ALEN)) + goto exit; + + *sta = rtw_get_stainfo(stapriv, get_addr2_ptr(whdr)); + if (*sta) + ret = _SUCCESS; + } + goto exit; + } + + if (!(MLME_STATE(adapter) & (WIFI_ASOC_STATE | WIFI_UNDER_LINKING))) { + if (!is_ra_bmc) { + /* for AP multicast issue , modify by yiwei */ + static systime send_issue_deauth_time = 0; + + /* RTW_INFO("After send deauth , %u ms has elapsed.\n", rtw_get_passing_time_ms(send_issue_deauth_time)); */ + if (rtw_get_passing_time_ms(send_issue_deauth_time) > 10000 || send_issue_deauth_time == 0) { + send_issue_deauth_time = rtw_get_current_time(); + RTW_INFO(FUNC_ADPT_FMT" issue_deauth to "MAC_FMT" with reason(7), mlme_state:0x%x\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(get_addr2_ptr(whdr)), MLME_STATE(adapter)); + issue_deauth(adapter, get_addr2_ptr(whdr), WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + } + } + #ifdef DBG_RX_DROP_FRAME + RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" fw_state:0x%x\n" + , FUNC_ADPT_ARG(adapter), MLME_STATE(adapter)); + #endif + goto exit; + } + + _rtw_memcpy(rattrib->ra, GetAddr1Ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->ta, get_addr2_ptr(whdr), ETH_ALEN); + + switch (rattrib->to_fr_ds) { + case 2: + _rtw_memcpy(rattrib->dst, GetAddr1Ptr(whdr), ETH_ALEN); + _rtw_memcpy(rattrib->src, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */ + _rtw_memcpy(rattrib->bssid, get_addr2_ptr(whdr), ETH_ALEN); + break; + case 3: + _rtw_memcpy(rattrib->dst, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */ + _rtw_memcpy(rattrib->src, GetAddr4Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */ + _rtw_memcpy(rattrib->bssid, get_addr2_ptr(whdr), ETH_ALEN); + break; + default: + ret = RTW_RX_HANDLED; /* don't count for drop */ + goto exit; + } + + /* filter packets that SA is myself */ + if (!rattrib->amsdu && _rtw_memcmp(myhwaddr, rattrib->src, ETH_ALEN)) { + #ifdef DBG_RX_DROP_FRAME + RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" SA="MAC_FMT", myhwaddr="MAC_FMT"\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(rattrib->src), MAC_ARG(myhwaddr)); + #endif + goto exit; + } + + *sta = rtw_get_stainfo(stapriv, rattrib->ta); + if (*sta == NULL) { + #ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL + if (!is_ra_bmc && !IS_RADAR_DETECTED(adapter_to_rfctl(adapter))) { + RTW_INFO(FUNC_ADPT_FMT" issue_deauth to "MAC_FMT" with reason(7), unknown TA\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(rattrib->ta)); + issue_deauth(adapter, rattrib->ta, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + } + #endif + #ifdef DBG_RX_DROP_FRAME + RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" can't get psta under STATION_MODE ; drop pkt\n" + , FUNC_ADPT_ARG(adapter)); + #endif + goto exit; + } + +#ifdef CONFIG_RTW_WDS_AUTO_EN + if (rattrib->to_fr_ds == 3 && !(sta->flags & WLAN_STA_WDS)) + sta->flags |= WLAN_STA_WDS; +#endif + + /*if ((get_frame_sub_type(whdr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { + } + */ + + if (get_frame_sub_type(whdr) & BIT(6)) { + /* No data, will not indicate to upper layer, temporily count it here */ + count_rx_stats(adapter, rframe, *sta); + ret = RTW_RX_HANDLED; + goto exit; + } + +#ifdef CONFIG_RTW_WDS + if (adapter_use_wds(adapter) + && !rattrib->amsdu && IS_MCAST(rattrib->dst) + && rtw_rx_wds_gptr_check(adapter, rattrib->src) + ) { + /* will not indicate to upper layer, temporily count it here */ + count_rx_stats(adapter, rframe, *sta); + ret = RTW_RX_HANDLED; + goto exit; + } +#endif + + ret = _SUCCESS; + +exit: + return ret; +} + +int rtw_sta_rx_amsdu_act_check(union recv_frame *rframe + , const u8 *da, const u8 *sa) +{ + int act = RTW_RX_MSDU_ACT_INDICATE; + +#ifdef CONFIG_RTW_WDS + _adapter *adapter = rframe->u.hdr.adapter; + + if (adapter_use_wds(adapter) + && IS_MCAST(da) + && rtw_rx_wds_gptr_check(adapter, sa) + ) { + act = 0; + } +#endif + + return act; +} + sint sta2sta_data_frame( _adapter *adapter, union recv_frame *precv_frame, @@ -1193,18 +1440,6 @@ sint sta2sta_data_frame( u8 *sta_addr = pattrib->ta; sint bmcast = IS_MCAST(pattrib->dst); -#ifdef CONFIG_TDLS - struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; -#ifdef CONFIG_TDLS_CH_SW - struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info; -#endif - struct sta_info *ptdls_sta = NULL; - u8 *psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE; - /* frame body located after [+2]: ether-type, [+1]: payload type */ - u8 *pframe_body = psnap_type + 2 + 1; -#endif - - /* RTW_INFO("[%s] %d, seqnum:%d\n", __FUNCTION__, __LINE__, pattrib->seq_num); */ if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) || @@ -1228,102 +1463,6 @@ sint sta2sta_data_frame( goto exit; } - } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) { -#ifdef CONFIG_TDLS - - /* direct link data transfer */ - if (ptdlsinfo->link_established == _TRUE) { - *psta = ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->ta); - if (ptdls_sta == NULL) { - ret = _FAIL; - goto exit; - } else if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) { - /* filter packets that SA is myself or multicast or broadcast */ - if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) { - ret = _FAIL; - goto exit; - } - /* da should be for me */ - if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) { - ret = _FAIL; - goto exit; - } - /* check BSSID */ - if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || - _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || - (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) { - ret = _FAIL; - goto exit; - } - -#ifdef CONFIG_TDLS_CH_SW - if (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE) { - if (adapter->mlmeextpriv.cur_channel != rtw_get_oper_ch(adapter)) { - pchsw_info->ch_sw_state |= TDLS_PEER_AT_OFF_STATE; - if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE)) - _cancel_timer_ex(&ptdls_sta->ch_sw_timer); - /* On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame); */ - } - } -#endif - - /* process UAPSD tdls sta */ - process_pwrbit_data(adapter, precv_frame, ptdls_sta); - - /* if NULL-frame, check pwrbit */ - if ((get_frame_sub_type(ptr) & WIFI_DATA_NULL) == WIFI_DATA_NULL) { - /* NULL-frame with pwrbit=1, buffer_STA should buffer frames for sleep_STA */ - if (GetPwrMgt(ptr)) { - /* it would be triggered when we are off channel and receiving NULL DATA */ - /* we can confirm that peer STA is at off channel */ - RTW_INFO("TDLS: recv peer null frame with pwr bit 1\n"); - /* ptdls_sta->tdls_sta_state|=TDLS_PEER_SLEEP_STATE; */ - } - - /* TODO: Updated BSSID's seq. */ - /* RTW_INFO("drop Null Data\n"); */ - ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE); - ret = _FAIL; - goto exit; - } - - /* receive some of all TDLS management frames, process it at ON_TDLS */ - if (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, 2)) { - ret = OnTDLS(adapter, precv_frame); - goto exit; - } - - if ((get_frame_sub_type(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) - process_wmmps_data(adapter, precv_frame, ptdls_sta); - - ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE); - - } - } else -#endif /* CONFIG_TDLS */ - { - /* For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */ - if (!_rtw_memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) { - ret = _FAIL; - goto exit; - } - } - - } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) { - if (bmcast) { - /* For AP mode, if DA == MCAST, then BSSID should be also MCAST */ - if (!IS_MCAST(pattrib->bssid)) { - ret = _FAIL; - goto exit; - } - } else { /* not mc-frame */ - /* For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID */ - if (!_rtw_memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) { - ret = _FAIL; - goto exit; - } - } - } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) { _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); _rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN); @@ -1335,11 +1474,7 @@ sint sta2sta_data_frame( } else ret = _FAIL; -#ifdef CONFIG_TDLS - if (ptdls_sta == NULL) -#endif - *psta = rtw_get_stainfo(pstapriv, sta_addr); - + *psta = rtw_get_stainfo(pstapriv, sta_addr); if (*psta == NULL) { #ifdef CONFIG_MP_INCLUDED if (adapter->registrypriv.mp_mode == 1) { @@ -1353,7 +1488,6 @@ sint sta2sta_data_frame( exit: return ret; - } sint ap2sta_data_frame( @@ -1366,79 +1500,10 @@ sint ap2sta_data_frame( sint ret = _SUCCESS; struct sta_priv *pstapriv = &adapter->stapriv; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - u8 *mybssid = get_bssid(pmlmepriv); u8 *myhwaddr = adapter_mac_addr(adapter); sint bmcast = IS_MCAST(pattrib->dst); - - if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) - && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE - || check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) - ) { - - /* filter packets that SA is myself or multicast or broadcast */ - if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) { - #ifdef DBG_RX_DROP_FRAME - RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" SA="MAC_FMT", myhwaddr="MAC_FMT"\n" - , FUNC_ADPT_ARG(adapter), MAC_ARG(pattrib->src), MAC_ARG(myhwaddr)); - #endif - ret = _FAIL; - goto exit; - } - - /* da should be for me */ - if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) { - #ifdef DBG_RX_DROP_FRAME - RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" DA="MAC_FMT"\n" - , FUNC_ADPT_ARG(adapter), MAC_ARG(pattrib->dst)); - #endif - ret = _FAIL; - goto exit; - } - - - /* check BSSID */ - if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || - _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || - (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) { - #ifdef DBG_RX_DROP_FRAME - RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" BSSID="MAC_FMT", mybssid="MAC_FMT"\n" - , FUNC_ADPT_ARG(adapter), MAC_ARG(pattrib->bssid), MAC_ARG(mybssid)); - #endif -#ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL - if (!bmcast - && !IS_RADAR_DETECTED(adapter_to_rfctl(adapter)) - ) { - RTW_INFO(ADPT_FMT" -issue_deauth to the nonassociated ap=" MAC_FMT " for the reason(7)\n", ADPT_ARG(adapter), MAC_ARG(pattrib->bssid)); - issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); - } -#endif - ret = _FAIL; - goto exit; - } - - *psta = rtw_get_stainfo(pstapriv, pattrib->ta); - if (*psta == NULL) { - #ifdef DBG_RX_DROP_FRAME - RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" can't get psta under STATION_MODE ; drop pkt\n" - , FUNC_ADPT_ARG(adapter)); - #endif - ret = _FAIL; - goto exit; - } - - /*if ((get_frame_sub_type(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { - } - */ - - if (get_frame_sub_type(ptr) & BIT(6)) { - /* No data, will not indicate to upper layer, temporily count it here */ - count_rx_stats(adapter, precv_frame, *psta); - ret = RTW_RX_HANDLED; - goto exit; - } - - } else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && + if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) { _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); _rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN); @@ -1457,11 +1522,6 @@ sint ap2sta_data_frame( goto exit; } - - } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) { - /* Special case */ - ret = RTW_RX_HANDLED; - goto exit; } else { if (_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast)) { *psta = rtw_get_stainfo(pstapriv, pattrib->ta); @@ -1490,8 +1550,6 @@ sint ap2sta_data_frame( } exit: - - return ret; } @@ -1508,39 +1566,7 @@ sint sta2ap_data_frame( unsigned char *mybssid = get_bssid(pmlmepriv); sint ret = _SUCCESS; - - if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) { - /* For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR */ - if (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN)) { - ret = _FAIL; - goto exit; - } - - *psta = rtw_get_stainfo(pstapriv, pattrib->ta); - if (*psta == NULL) { - if (!IS_RADAR_DETECTED(adapter_to_rfctl(adapter))) { -#ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL - RTW_INFO("issue_deauth to sta=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src)); - issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); -#endif - } - - ret = RTW_RX_HANDLED; - goto exit; - } - - process_pwrbit_data(adapter, precv_frame, *psta); - - if ((get_frame_sub_type(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) - process_wmmps_data(adapter, precv_frame, *psta); - - if (get_frame_sub_type(ptr) & BIT(6)) { - /* No data, will not indicate to upper layer, temporily count it here */ - count_rx_stats(adapter, precv_frame, *psta); - ret = RTW_RX_HANDLED; - goto exit; - } - } else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && + if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) { /* RTW_INFO("%s ,in WIFI_MP_STATE\n",__func__); */ _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); @@ -1640,11 +1666,13 @@ sint validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame) if (wmmps_ac) return _FAIL; + #ifdef CONFIG_AP_MODE if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { RTW_INFO("%s alive check-rx ps-poll\n", __func__); psta->expire_to = pstapriv->expire_to; psta->state ^= WIFI_STA_ALIVE_CHK_STATE; } + #endif if ((psta->state & WIFI_SLEEP_STATE) && (rtw_tim_map_is_set(padapter, pstapriv->sta_dz_bitmap, psta->cmn.aid))) { _irqL irqL; @@ -2050,8 +2078,18 @@ sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame) if (MLME_IS_MESH(adapter)) { ret = rtw_mesh_rx_data_validate_hdr(adapter, precv_frame, &psta); goto pre_validate_status_chk; - } + } else #endif +#ifdef CONFIG_AP_MODE + if (MLME_IS_AP(adapter)) { + ret = rtw_ap_rx_data_validate_hdr(adapter, precv_frame, &psta); + goto pre_validate_status_chk; + } else +#endif + if (MLME_IS_STA(adapter)) { + ret = rtw_sta_rx_data_validate_hdr(adapter, precv_frame, &psta); + goto pre_validate_status_chk; + } switch (pattrib->to_fr_ds) { case 0: @@ -2066,19 +2104,19 @@ sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame) case 1: _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); _rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN); - _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); - _rtw_memcpy(pattrib->src, GetAddr3Ptr(ptr), ETH_ALEN); - _rtw_memcpy(pattrib->bssid, get_addr2_ptr(ptr), ETH_ALEN); - ret = ap2sta_data_frame(adapter, precv_frame, &psta); + _rtw_memcpy(pattrib->dst, GetAddr3Ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->bssid, GetAddr1Ptr(ptr), ETH_ALEN); + ret = sta2ap_data_frame(adapter, precv_frame, &psta); break; case 2: _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); _rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN); - _rtw_memcpy(pattrib->dst, GetAddr3Ptr(ptr), ETH_ALEN); - _rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN); - _rtw_memcpy(pattrib->bssid, GetAddr1Ptr(ptr), ETH_ALEN); - ret = sta2ap_data_frame(adapter, precv_frame, &psta); + _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->src, GetAddr3Ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->bssid, get_addr2_ptr(ptr), ETH_ALEN); + ret = ap2sta_data_frame(adapter, precv_frame, &psta); break; case 3: @@ -2088,9 +2126,8 @@ sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame) break; } -#ifdef CONFIG_RTW_MESH pre_validate_status_chk: -#endif + if (ret == _FAIL) { #ifdef DBG_RX_DROP_FRAME RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" case:%d, res:%d, ra="MAC_FMT", ta="MAC_FMT"\n" @@ -2382,89 +2419,62 @@ exit: return retval; } +/* Reture expected handling for LLC */ +enum rtw_rx_llc_hdl rtw_recv_llc_parse(u8 *msdu, u16 msdu_len) +{ + u16 eth_type; + + if (msdu_len < 8) + return RTW_RX_LLC_KEEP; + + eth_type = RTW_GET_BE16(msdu + SNAP_SIZE); + + if ((_rtw_memcmp(msdu, rtw_rfc1042_header, SNAP_SIZE) + && eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) + || _rtw_memcmp(msdu, rtw_bridge_tunnel_header, SNAP_SIZE)) { + /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ + return RTW_RX_LLC_REMOVE; + } else { + /* Leave Ethernet header part of hdr and full payload */ + return RTW_RX_LLC_KEEP; + } + + /* TODO: VLAN tagged */ +} /* remove the wlanhdr and add the eth_hdr */ -sint wlanhdr_to_ethhdr(union recv_frame *precvframe) +sint wlanhdr_to_ethhdr(union recv_frame *precvframe, enum rtw_rx_llc_hdl llc_hdl) { - sint rmv_len; - u16 eth_type, len; - u8 bsnaphdr; - u8 *psnap_type; - struct ieee80211_snap_hdr *psnap; - - sint ret = _SUCCESS; - _adapter *adapter = precvframe->u.hdr.adapter; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - u8 *ptr = get_recvframe_data(precvframe) ; /* point to frame_ctrl field */ struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; - + sint rmv_len; + u16 eth_type, len; + sint ret = _SUCCESS; if (pattrib->encrypt) recvframe_pull_tail(precvframe, pattrib->icv_len); - psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib)); - psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib) + SNAP_SIZE; - /* convert hdr + possible LLC headers into Ethernet header */ - /* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */ - if ((_rtw_memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) && - (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) == _FALSE) && - (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2) == _FALSE)) || - /* eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || */ - _rtw_memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ - bsnaphdr = _TRUE; - } else { - /* Leave Ethernet header part of hdr and full payload */ - bsnaphdr = _FALSE; - } - - rmv_len = pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib) + (bsnaphdr ? SNAP_SIZE : 0); + rmv_len = pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib) + (llc_hdl ? SNAP_SIZE : 0); len = precvframe->u.hdr.len - rmv_len; - - _rtw_memcpy(ð_type, ptr + rmv_len, 2); - eth_type = ntohs((unsigned short)eth_type); /* pattrib->ether_type */ - pattrib->eth_type = eth_type; - - - if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)) { - ptr += rmv_len ; - *ptr = 0x87; - *(ptr + 1) = 0x12; - - eth_type = 0x8712; - /* append rx status for mp test packets */ - ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24); - if (!ptr) { - ret = _FAIL; - goto exiting; - } - _rtw_memcpy(ptr, get_rxmem(precvframe), 24); - ptr += 24; - } else { - ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0))); - if (!ptr) { - ret = _FAIL; - goto exiting; - } + ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (llc_hdl ? 2 : 0))); + if (!ptr) { + ret = _FAIL; + goto exiting; } - if (ptr) { - _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN); - _rtw_memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN); + _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN); + _rtw_memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN); - if (!bsnaphdr) { - len = htons(len); - _rtw_memcpy(ptr + 12, &len, 2); - } - - rtw_rframe_set_os_pkt(precvframe); + if (!llc_hdl) { + len = htons(len); + _rtw_memcpy(ptr + 12, &len, 2); } + rtw_rframe_set_os_pkt(precvframe); + exiting: return ret; - } #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) @@ -2729,13 +2739,14 @@ static int rtw_recv_indicatepkt_check(union recv_frame *rframe, u8 *ehdr_pos, u3 _adapter *adapter = rframe->u.hdr.adapter; struct recv_priv *recvpriv = &adapter->recvpriv; struct ethhdr *ehdr = (struct ethhdr *)ehdr_pos; + struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib; #ifdef DBG_IP_R_MONITOR int i; - struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib; struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; struct wlan_network *cur_network = &(pmlmepriv->cur_network); #endif/*DBG_IP_R_MONITOR*/ + enum eap_type eapol_type; int ret = _FAIL; #ifdef CONFIG_WAPI_SUPPORT @@ -2751,8 +2762,13 @@ static int rtw_recv_indicatepkt_check(union recv_frame *rframe, u8 *ehdr_pos, u3 if (rframe->u.hdr.psta) rtw_st_ctl_rx(rframe->u.hdr.psta, ehdr_pos); - if (ntohs(ehdr->h_proto) == 0x888e) - parsing_eapol_packet(adapter, ehdr_pos + ETH_HLEN, rframe->u.hdr.psta, 0); + if (ntohs(ehdr->h_proto) == 0x888e) { + eapol_type = parsing_eapol_packet(adapter, ehdr_pos + ETH_HLEN, rframe->u.hdr.psta, 0); + if ((eapol_type == EAPOL_1_4 || eapol_type == EAPOL_3_4) && pattrib->encrypt == 0) { + rframe->u.hdr.psta->resp_nonenc_eapol_key_starttime = rtw_get_current_time(); + RTW_INFO("Receive unencrypted eapol key\n"); + } + } #ifdef DBG_ARP_DUMP else if (ntohs(ehdr->h_proto) == ETH_P_ARP) dump_arp_pkt(RTW_DBGDUMP, ehdr->h_dest, ehdr->h_source, ehdr_pos + ETH_HLEN, 0); @@ -2807,7 +2823,7 @@ exit: return ret; } -#ifdef CONFIG_RTW_MESH +#if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) static void recv_free_fwd_resource(_adapter *adapter, struct xmit_frame *fwd_frame, _list *b2u_list) { struct xmit_priv *xmitpriv = &adapter->xmitpriv; @@ -2815,7 +2831,7 @@ static void recv_free_fwd_resource(_adapter *adapter, struct xmit_frame *fwd_fra if (fwd_frame) rtw_free_xmitframe(xmitpriv, fwd_frame); -#if CONFIG_RTW_MESH_DATA_BMC_TO_UC +#if CONFIG_RTW_DATA_BMC_TO_UC if (!rtw_is_list_empty(b2u_list)) { struct xmit_frame *b2uframe; _list *list; @@ -2848,7 +2864,7 @@ static void recv_fwd_pkt_hdl(_adapter *adapter, _pkt *pkt } } -#if CONFIG_RTW_MESH_DATA_BMC_TO_UC +#if CONFIG_RTW_DATA_BMC_TO_UC if (!rtw_is_list_empty(b2u_list)) { _list *list = get_next(b2u_list); struct xmit_frame *b2uframe; @@ -2885,7 +2901,7 @@ static void recv_fwd_pkt_hdl(_adapter *adapter, _pkt *pkt exit: return; } -#endif /* CONFIG_RTW_MESH */ +#endif /* defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) */ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) { @@ -2899,10 +2915,11 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) _queue *pfree_recv_queue = &(precvpriv->free_recv_queue); const u8 *da, *sa; int act; -#ifdef CONFIG_RTW_MESH /* TODO: move AP mode forward & b2u logic here */ +#if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) struct xmit_frame *fwd_frame; _list b2u_list; #endif + enum rtw_rx_llc_hdl llc_hdl; u8 mctrl_len = 0; int ret = _SUCCESS; @@ -2912,6 +2929,8 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) if (rattrib->iv_len > 0) recvframe_pull(prframe, rattrib->iv_len); + if (rattrib->encrypt) + recvframe_pull_tail(prframe, rattrib->icv_len); a_len = prframe->u.hdr.len; pdata = prframe->u.hdr.rx_data; @@ -2925,10 +2944,11 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) } act = RTW_RX_MSDU_ACT_INDICATE; + #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) + fwd_frame = NULL; + #endif #ifdef CONFIG_RTW_MESH - fwd_frame = NULL; - if (MLME_IS_MESH(padapter)) { u8 *mda = pdata, *msa = pdata + ETH_ALEN; struct rtw_ieee80211s_hdr *mctrl = (struct rtw_ieee80211s_hdr *)(pdata + ETH_HLEN); @@ -2939,31 +2959,41 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) if (v_ret != _SUCCESS) goto move_to_next; + llc_hdl = rtw_recv_llc_parse(pdata + ETH_HLEN + mctrl_len, nSubframe_Length - mctrl_len); act = rtw_mesh_rx_msdu_act_check(prframe - , mda, msa, da, sa, mctrl, &fwd_frame, &b2u_list); + , mda, msa, da, sa, mctrl + , pdata + ETH_HLEN + mctrl_len, llc_hdl + , &fwd_frame, &b2u_list); } else #endif { da = pdata; sa = pdata + ETH_ALEN; + llc_hdl = rtw_recv_llc_parse(pdata + ETH_HLEN, nSubframe_Length); + #ifdef CONFIG_AP_MODE + if (MLME_IS_AP(padapter)) { + act = rtw_ap_rx_msdu_act_check(prframe, da, sa + , pdata + ETH_HLEN, llc_hdl, &fwd_frame, &b2u_list); + } else + #endif + if (MLME_IS_STA(padapter)) + act = rtw_sta_rx_amsdu_act_check(prframe, da, sa); } - #ifdef CONFIG_RTW_MESH if (!act) goto move_to_next; - #endif rtw_led_rx_control(padapter, da); sub_pkt = rtw_os_alloc_msdu_pkt(prframe, da, sa - , pdata + ETH_HLEN + mctrl_len, nSubframe_Length - mctrl_len); + , pdata + ETH_HLEN + mctrl_len, nSubframe_Length - mctrl_len, llc_hdl); if (sub_pkt == NULL) { if (act & RTW_RX_MSDU_ACT_INDICATE) { #ifdef DBG_RX_DROP_FRAME RTW_INFO("DBG_RX_DROP_FRAME %s rtw_os_alloc_msdu_pkt fail\n", __func__); #endif } - #ifdef CONFIG_RTW_MESH + #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) if (act & RTW_RX_MSDU_ACT_FORWARD) { #ifdef DBG_TX_DROP_FRAME RTW_INFO("DBG_TX_DROP_FRAME %s rtw_os_alloc_msdu_pkt fail\n", __func__); @@ -2974,7 +3004,7 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) break; } - #ifdef CONFIG_RTW_MESH + #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) if (act & RTW_RX_MSDU_ACT_FORWARD) { recv_fwd_pkt_hdl(padapter, sub_pkt, act, fwd_frame, &b2u_list); if (!(act & RTW_RX_MSDU_ACT_INDICATE)) @@ -2987,9 +3017,7 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) else rtw_os_pkt_free(sub_pkt); -#ifdef CONFIG_RTW_MESH move_to_next: -#endif /* move the data point to data content */ pdata += ETH_HLEN; a_len -= ETH_HLEN; @@ -3046,22 +3074,35 @@ static int recv_process_mpdu(_adapter *padapter, union recv_frame *prframe) goto exit; } } else { + u8 *msdu = get_recvframe_data(prframe) + + pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib); + u16 msdu_len = prframe->u.hdr.len + - pattrib->hdrlen - pattrib->iv_len - RATTRIB_GET_MCTRL_LEN(pattrib) + - (pattrib->encrypt ? pattrib->icv_len : 0); + enum rtw_rx_llc_hdl llc_hdl = rtw_recv_llc_parse(msdu, msdu_len); int act = RTW_RX_MSDU_ACT_INDICATE; - #ifdef CONFIG_RTW_MESH /* TODO: move AP mode forward & b2u logic here */ + #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) struct xmit_frame *fwd_frame = NULL; _list b2u_list; - if (MLME_IS_MESH(padapter) && pattrib->mesh_ctrl_present) { - act = rtw_mesh_rx_msdu_act_check(prframe - , pattrib->mda, pattrib->msa - , pattrib->dst, pattrib->src - , (struct rtw_ieee80211s_hdr *)(get_recvframe_data(prframe) + pattrib->hdrlen + pattrib->iv_len) - , &fwd_frame, &b2u_list); - } + #ifdef CONFIG_RTW_MESH + if (MLME_IS_MESH(padapter)) { + if (pattrib->mesh_ctrl_present) + act = rtw_mesh_rx_msdu_act_check(prframe + , pattrib->mda, pattrib->msa + , pattrib->dst, pattrib->src + , (struct rtw_ieee80211s_hdr *)(msdu - RATTRIB_GET_MCTRL_LEN(pattrib)) + , msdu, llc_hdl + , &fwd_frame, &b2u_list); + } else + #endif + if (MLME_IS_AP(padapter)) + act = rtw_ap_rx_msdu_act_check(prframe, pattrib->dst, pattrib->src + , msdu, llc_hdl, &fwd_frame, &b2u_list); #endif - #ifdef CONFIG_RTW_MESH + #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) if (!act) { rtw_free_recvframe(prframe, pfree_recv_queue); ret = _FAIL; @@ -3071,7 +3112,7 @@ static int recv_process_mpdu(_adapter *padapter, union recv_frame *prframe) rtw_led_rx_control(padapter, pattrib->dst); - ret = wlanhdr_to_ethhdr(prframe); + ret = wlanhdr_to_ethhdr(prframe, llc_hdl); if (ret != _SUCCESS) { if (act & RTW_RX_MSDU_ACT_INDICATE) { #ifdef DBG_RX_DROP_FRAME @@ -3079,7 +3120,7 @@ static int recv_process_mpdu(_adapter *padapter, union recv_frame *prframe) , FUNC_ADPT_ARG(padapter)); #endif } - #ifdef CONFIG_RTW_MESH + #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) if (act & RTW_RX_MSDU_ACT_FORWARD) { #ifdef DBG_TX_DROP_FRAME RTW_INFO("DBG_TX_DROP_FRAME %s wlanhdr_to_ethhdr fail\n", __func__); @@ -3091,7 +3132,7 @@ static int recv_process_mpdu(_adapter *padapter, union recv_frame *prframe) goto exit; } - #ifdef CONFIG_RTW_MESH + #if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) if (act & RTW_RX_MSDU_ACT_FORWARD) { recv_fwd_pkt_hdl(padapter, prframe->u.hdr.pkt, act, fwd_frame, &b2u_list); if (!(act & RTW_RX_MSDU_ACT_INDICATE)) { @@ -3575,7 +3616,7 @@ int validate_mp_recv_frame(_adapter *adapter, union recv_frame *precv_frame) type = GetFrameType(ptr); subtype = get_frame_sub_type(ptr); /* bit(7)~bit(2) */ - RTW_INFO("hdr len = %d iv_len=%d \n", pattrib->hdrlen , pattrib->iv_len); + RTW_DBG("hdr len = %d iv_len=%d \n", pattrib->hdrlen , pattrib->iv_len); prx_data = ptr + pattrib->hdrlen + pattrib->iv_len; for (i = 0; i < precv_frame->u.hdr.len; i++) { @@ -3641,55 +3682,31 @@ int validate_mp_recv_frame(_adapter *adapter, union recv_frame *precv_frame) static sint MPwlanhdr_to_ethhdr(union recv_frame *precvframe) { sint rmv_len; - u16 eth_type, len; - u8 bsnaphdr; - u8 *psnap_type; + u16 len; u8 mcastheadermac[] = {0x01, 0x00, 0x5e}; - - struct ieee80211_snap_hdr *psnap; - sint ret = _SUCCESS; _adapter *adapter = precvframe->u.hdr.adapter; u8 *ptr = get_recvframe_data(precvframe) ; /* point to frame_ctrl field */ struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; + enum rtw_rx_llc_hdl llc_hdl; if (pattrib->encrypt) recvframe_pull_tail(precvframe, pattrib->icv_len); - psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len); - psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE; - /* convert hdr + possible LLC headers into Ethernet header */ - /* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */ - if ((_rtw_memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) && - (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) == _FALSE) && - (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2) == _FALSE)) || - /* eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || */ - _rtw_memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ - bsnaphdr = _TRUE; - } else { - /* Leave Ethernet header part of hdr and full payload */ - bsnaphdr = _FALSE; - } + llc_hdl = rtw_recv_llc_parse(ptr + pattrib->hdrlen + pattrib->iv_len + , precvframe->u.hdr.len - pattrib->hdrlen - pattrib->iv_len); - rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr ? SNAP_SIZE : 0); + rmv_len = pattrib->hdrlen + pattrib->iv_len + (llc_hdl ? SNAP_SIZE : 0); len = precvframe->u.hdr.len - rmv_len; - - _rtw_memcpy(ð_type, ptr + rmv_len, 2); - eth_type = ntohs((unsigned short)eth_type); /* pattrib->ether_type */ - pattrib->eth_type = eth_type; - - { - ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0))); - } + ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (llc_hdl ? 2 : 0))); _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN); _rtw_memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN); - if (!bsnaphdr) { + if (!llc_hdl) { len = htons(len); _rtw_memcpy(ptr + 12, &len, 2); } @@ -3768,18 +3785,16 @@ int mp_recv_frame(_adapter *padapter, union recv_frame *rframe) _rtw_memcpy(pattrib->ta, psa, ETH_ALEN); ret = sta2sta_data_frame(padapter, rframe, &psta); break; - case 1: - _rtw_memcpy(pattrib->ra, pda, ETH_ALEN); - _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN); - ret = ap2sta_data_frame(padapter, rframe, &psta); - break; - - case 2: _rtw_memcpy(pattrib->ra, pbssid, ETH_ALEN); _rtw_memcpy(pattrib->ta, psa, ETH_ALEN); ret = sta2ap_data_frame(padapter, rframe, &psta); break; + case 2: + _rtw_memcpy(pattrib->ra, pda, ETH_ALEN); + _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN); + ret = ap2sta_data_frame(padapter, rframe, &psta); + break; case 3: _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); _rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN); @@ -4045,12 +4060,16 @@ int recv_func(_adapter *padapter, union recv_frame *rframe) struct recv_priv *recvpriv = &padapter->recvpriv; struct security_priv *psecuritypriv = &padapter->securitypriv; struct mlme_priv *mlmepriv = &padapter->mlmepriv; + u8 *ptr = rframe->u.hdr.rx_data; #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL u8 type; - u8 *ptr = rframe->u.hdr.rx_data; #endif - if (check_fwstate(mlmepriv, WIFI_MONITOR_STATE)) { + if (check_fwstate(mlmepriv, WIFI_MONITOR_STATE) +#ifdef RTW_SIMPLE_CONFIG + || (check_fwstate(mlmepriv, WIFI_AP_STATE) && padapter->rtw_simple_config == _TRUE && IS_MCAST(get_ra(ptr))) +#endif + ) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)) recv_frame_monitor(padapter, rframe); #endif @@ -4449,7 +4468,9 @@ void rx_query_phy_status( pkt_info.is_packet_beacon = pkt_info.is_packet_match_bssid && (get_frame_sub_type(wlanhdr) == WIFI_BEACON); - if (psta && IsFrameTypeData(wlanhdr)) { + if (psta && IsFrameTypeData(wlanhdr) + && !(get_frame_sub_type(wlanhdr) & BIT(6)) /* don't count NULL data */ + ) { if (is_ra_bmc) psta->curr_rx_rate_bmc = pattrib->data_rate; else @@ -4528,6 +4549,12 @@ u8 adapter_allow_bmc_data_rx(_adapter *adapter) if (check_fwstate(&adapter->mlmepriv, WIFI_MONITOR_STATE | WIFI_MP_STATE) == _TRUE) return 1; +#ifdef RTW_SIMPLE_CONFIG + /* allow AP to receive multicast packet for RtwSimpleConfigV4 */ + if (MLME_IS_AP(adapter) && adapter->rtw_simple_config) + return 1; +#endif + if (MLME_IS_AP(adapter)) return 0; @@ -4541,49 +4568,89 @@ s32 pre_recv_entry(union recv_frame *precvframe, u8 *pphy_status) { s32 ret = _SUCCESS; u8 *pbuf = precvframe->u.hdr.rx_data; - u8 *pda = get_ra(pbuf); - u8 ra_is_bmc = IS_MCAST(pda); + u8 *ra = get_ra(pbuf); + u8 ra_is_bmc = IS_MCAST(ra); + bool phy_queried = 0; _adapter *primary_padapter = precvframe->u.hdr.adapter; -#ifdef CONFIG_CONCURRENT_MODE _adapter *iface = NULL; - #ifdef CONFIG_MP_INCLUDED +#ifdef CONFIG_MP_INCLUDED if (rtw_mp_mode_check(primary_padapter)) - goto bypass_concurrent_hdl; - #endif + goto query_phy_status; +#endif +#ifdef CONFIG_WIFI_MONITOR + if (MLME_IS_MONITOR(primary_padapter)) + goto query_phy_status; +#endif - if (ra_is_bmc == _FALSE) { /*unicast packets*/ - iface = rtw_get_iface_by_macddr(primary_padapter , pda); - if (NULL == iface) { - #ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI - if (_rtw_memcmp(pda, adapter_pno_mac_addr(primary_padapter), - ETH_ALEN) != _TRUE) - #endif - RTW_INFO("%s [WARN] Cannot find appropriate adapter - mac_addr : "MAC_FMT"\n", __func__, MAC_ARG(pda)); - /*rtw_warn_on(1);*/ - } else + if (ra_is_bmc == _FALSE) { + /* UC frame */ + iface = rtw_get_iface_by_macddr(primary_padapter , ra); + if (!iface) { + #ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI + if (_rtw_memcmp(ra, adapter_pno_mac_addr(primary_padapter), ETH_ALEN)) + goto query_phy_status; + #endif + + #ifdef CONFIG_RTW_MULTI_AP + /* unasoc STA RCPI */ + if (rtw_unassoc_sta_src_chk(primary_padapter, UNASOC_STA_SRC_RX_NMY_UC)) { + if (pphy_status) { + rx_query_phy_status(precvframe, pphy_status); + rtw_rx_add_unassoc_sta(primary_padapter, UNASOC_STA_SRC_RX_NMY_UC, get_ta(pbuf) + , precvframe->u.hdr.attrib.phy_info.recv_signal_power); + } + } else + #endif + RTW_INFO("%s [WARN] Cannot find appropriate adapter - mac_addr : "MAC_FMT"\n" + , __func__, MAC_ARG(ra)); + + rtw_free_recvframe(precvframe, &precvframe->u.hdr.adapter->recvpriv.free_recv_queue); + goto exit; + } + #ifdef CONFIG_CONCURRENT_MODE + else precvframe->u.hdr.adapter = iface; - } else /* Handle BC/MC Packets */ + #endif + + } else { + /* BMC frame */ + #ifdef CONFIG_CONCURRENT_MODE rtw_mi_buddy_clone_bcmc_packet(primary_padapter, precvframe, pphy_status); -bypass_concurrent_hdl: -#endif /* CONFIG_CONCURRENT_MODE */ - if (primary_padapter->registrypriv.mp_mode != 1) { - /* skip unnecessary bmc data frame for primary adapter */ - if (ra_is_bmc == _TRUE && GetFrameType(pbuf) == WIFI_DATA_TYPE + #endif + + #ifdef CONFIG_RTW_MULTI_AP + /* unasoc STA RCPI */ + if (pphy_status + && rtw_unassoc_sta_src_chk(primary_padapter, UNASOC_STA_SRC_RX_BMC) + ) { + phy_queried = 1; + rx_query_phy_status(precvframe, pphy_status); + rtw_rx_add_unassoc_sta(primary_padapter, UNASOC_STA_SRC_RX_BMC, get_ta(pbuf) + , precvframe->u.hdr.attrib.phy_info.recv_signal_power); + } + #endif + + /* skip unnecessary BMC data frame for primary adapter */ + if (GetFrameType(pbuf) == WIFI_DATA_TYPE && !adapter_allow_bmc_data_rx(precvframe->u.hdr.adapter) ) { rtw_free_recvframe(precvframe, &precvframe->u.hdr.adapter->recvpriv.free_recv_queue); goto exit; } } - - if (pphy_status) { - rx_query_phy_status(precvframe, pphy_status); - -#ifdef CONFIG_WIFI_MONITOR - rx_query_moinfo(&precvframe->u.hdr.attrib, pphy_status); +#if defined(CONFIG_MP_INCLUDED) || defined(CONFIG_WIFI_MONITOR) || defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) +query_phy_status: #endif + if (pphy_status) { + if (!phy_queried) + rx_query_phy_status(precvframe, pphy_status); + #ifdef CONFIG_WIFI_MONITOR + if (MLME_IS_MONITOR(primary_padapter)) + rx_query_moinfo(&precvframe->u.hdr.attrib, pphy_status); + #endif } + ret = rtw_recv_entry(precvframe); exit: diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rf.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rf.c index f416bb5efdda..8b3a6d4a1610 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rf.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rf.c @@ -27,6 +27,8 @@ u8 center_ch_2g[CENTER_CH_2G_NUM] = { /* G05 */14 }; +#define ch_to_cch_2g_idx(ch) ((ch) - 1) + u8 center_ch_2g_40m[CENTER_CH_2G_40M_NUM] = { 3, 4, @@ -95,6 +97,13 @@ u8 center_ch_5g_20m[CENTER_CH_5G_20M_NUM] = { /* G13 */173, 177 }; +#define ch_to_cch_5g_20m_idx(ch) \ + ( \ + ((ch) >= 36 && (ch) <= 64) ? (((ch) - 36) >> 2) : \ + ((ch) >= 100 && (ch) <= 144) ? 8 + (((ch) - 100) >> 2) : \ + ((ch) >= 149 && (ch) <= 177) ? 20 + (((ch) - 149) >> 2) : 255 \ + ) + u8 center_ch_5g_40m[CENTER_CH_5G_40M_NUM] = { /* G00 */38, /* G01 */46, @@ -305,7 +314,7 @@ inline u8 center_chs_2g(u8 bw, u8 id) inline u8 center_chs_5g_num(u8 bw) { - if (bw > CHANNEL_WIDTH_80) + if (bw > CHANNEL_WIDTH_160) return 0; return center_chs_5g_by_bw[bw].ch_num; @@ -313,7 +322,7 @@ inline u8 center_chs_5g_num(u8 bw) inline u8 center_chs_5g(u8 bw, u8 id) { - if (bw > CHANNEL_WIDTH_80) + if (bw > CHANNEL_WIDTH_160) return 0; if (id >= center_chs_5g_num(bw)) @@ -369,6 +378,131 @@ exit: return valid; } +u8 rtw_get_offset_by_chbw(u8 ch, u8 bw, u8 *r_offset) +{ + u8 valid = 1; + u8 offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + if (bw == CHANNEL_WIDTH_20) + goto exit; + + if (bw >= CHANNEL_WIDTH_80 && ch <= 14) { + valid = 0; + goto exit; + } + + if (ch >= 1 && ch <= 4) + offset = HAL_PRIME_CHNL_OFFSET_LOWER; + else if (ch >= 5 && ch <= 9) { + if (*r_offset == HAL_PRIME_CHNL_OFFSET_LOWER || *r_offset == HAL_PRIME_CHNL_OFFSET_UPPER) + offset = *r_offset; /* both lower and upper is valid, obey input value */ + else + offset = HAL_PRIME_CHNL_OFFSET_UPPER; /* default use upper */ + } else if (ch >= 10 && ch <= 13) + offset = HAL_PRIME_CHNL_OFFSET_UPPER; + else if (ch == 14) { + valid = 0; /* ch14 doesn't support 40MHz bandwidth */ + goto exit; + } else if (ch >= 36 && ch <= 177) { + switch (ch) { + case 36: + case 44: + case 52: + case 60: + case 100: + case 108: + case 116: + case 124: + case 132: + case 140: + case 149: + case 157: + case 165: + case 173: + offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + case 40: + case 48: + case 56: + case 64: + case 104: + case 112: + case 120: + case 128: + case 136: + case 144: + case 153: + case 161: + case 169: + case 177: + offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + default: + valid = 0; + break; + } + } else + valid = 0; + +exit: + if (valid && r_offset) + *r_offset = offset; + return valid; +} + +u8 rtw_get_center_ch(u8 ch, u8 bw, u8 offset) +{ + u8 cch = ch; + + if (bw == CHANNEL_WIDTH_160) { + if (ch % 4 == 0) { + if (ch >= 36 && ch <= 64) + cch = 50; + else if (ch >= 100 && ch <= 128) + cch = 114; + } else if (ch % 4 == 1) { + if (ch >= 149 && ch <= 177) + cch = 163; + } + + } else if (bw == CHANNEL_WIDTH_80) { + if (ch <= 14) + cch = 7; /* special case for 2.4G */ + else if (ch % 4 == 0) { + if (ch >= 36 && ch <= 48) + cch = 42; + else if (ch >= 52 && ch <= 64) + cch = 58; + else if (ch >= 100 && ch <= 112) + cch = 106; + else if (ch >= 116 && ch <= 128) + cch = 122; + else if (ch >= 132 && ch <= 144) + cch = 138; + } else if (ch % 4 == 1) { + if (ch >= 149 && ch <= 161) + cch = 155; + else if (ch >= 165 && ch <= 177) + cch = 171; + } + + } else if (bw == CHANNEL_WIDTH_40) { + if (offset == HAL_PRIME_CHNL_OFFSET_LOWER) + cch = ch + 2; + else if (offset == HAL_PRIME_CHNL_OFFSET_UPPER) + cch = ch - 2; + + } else if (bw == CHANNEL_WIDTH_20 + || bw == CHANNEL_WIDTH_10 + || bw == CHANNEL_WIDTH_5 + ) + ; /* same as ch */ + else + rtw_warn_on(1); + + return cch; +} + u8 rtw_get_ch_group(u8 ch, u8 *group, u8 *cck_group) { BAND_TYPE band = BAND_MAX; @@ -505,7 +639,10 @@ bool rtw_chbw_to_freq_range(u8 ch, u8 bw, u8 offset, u32 *hi, u32 *lo) goto exit; } - if (bw == CHANNEL_WIDTH_80) { + if (bw == CHANNEL_WIDTH_160) { + hi_ret = freq + 80; + lo_ret = freq - 80; + } else if (bw == CHANNEL_WIDTH_80) { hi_ret = freq + 40; lo_ret = freq - 40; } else if (bw == CHANNEL_WIDTH_40) { @@ -529,23 +666,23 @@ exit: } const char *const _ch_width_str[CHANNEL_WIDTH_MAX] = { - "20MHz", - "40MHz", - "80MHz", - "160MHz", - "80_80MHz", - "5MHz", - "10MHz", + [CHANNEL_WIDTH_20] = "20MHz", + [CHANNEL_WIDTH_40] = "40MHz", + [CHANNEL_WIDTH_80] = "80MHz", + [CHANNEL_WIDTH_160] = "160MHz", + [CHANNEL_WIDTH_80_80] = "80_80MHz", + [CHANNEL_WIDTH_5] = "5MHz", + [CHANNEL_WIDTH_10] = "10MHz", }; const u8 _ch_width_to_bw_cap[CHANNEL_WIDTH_MAX] = { - BW_CAP_20M, - BW_CAP_40M, - BW_CAP_80M, - BW_CAP_160M, - BW_CAP_80_80M, - BW_CAP_5M, - BW_CAP_10M, + [CHANNEL_WIDTH_20] = BW_CAP_20M, + [CHANNEL_WIDTH_40] = BW_CAP_40M, + [CHANNEL_WIDTH_80] = BW_CAP_80M, + [CHANNEL_WIDTH_160] = BW_CAP_160M, + [CHANNEL_WIDTH_80_80] = BW_CAP_80_80M, + [CHANNEL_WIDTH_5] = BW_CAP_5M, + [CHANNEL_WIDTH_10] = BW_CAP_10M, }; const char *const _band_str[] = { @@ -560,89 +697,779 @@ const u8 _band_to_band_cap[] = { 0, }; -const u8 _rf_type_to_rf_tx_cnt[] = { - 1, /*RF_1T1R*/ - 1, /*RF_1T2R*/ - 2, /*RF_2T2R*/ - 2, /*RF_2T3R*/ - 2, /*RF_2T4R*/ - 3, /*RF_3T3R*/ - 3, /*RF_3T4R*/ - 4, /*RF_4T4R*/ - 1, /*RF_TYPE_MAX*/ +const char *const _opc_bw_str[OPC_BW_NUM] = { + "20M ", /* OPC_BW20 */ + "40M+", /* OPC_BW40PLUS */ + "40M-", /* OPC_BW40MINUS */ + "80M ", /* OPC_BW80 */ + "160M ", /* OPC_BW160 */ + "80+80M ", /* OPC_BW80P80 */ }; -const u8 _rf_type_to_rf_rx_cnt[] = { - 1, /*RF_1T1R*/ - 2, /*RF_1T2R*/ - 2, /*RF_2T2R*/ - 3, /*RF_2T3R*/ - 4, /*RF_2T4R*/ - 3, /*RF_3T3R*/ - 4, /*RF_3T4R*/ - 4, /*RF_4T4R*/ - 1, /*RF_TYPE_MAX*/ +const u8 _opc_bw_to_ch_width[OPC_BW_NUM] = { + CHANNEL_WIDTH_20, /* OPC_BW20 */ + CHANNEL_WIDTH_40, /* OPC_BW40PLUS */ + CHANNEL_WIDTH_40, /* OPC_BW40MINUS */ + CHANNEL_WIDTH_80, /* OPC_BW80 */ + CHANNEL_WIDTH_160, /* OPC_BW160 */ + CHANNEL_WIDTH_80_80, /* OPC_BW80P80 */ }; -const char *const _rf_type_to_rfpath_str[] = { - "RF_1T1R", - "RF_1T2R", - "RF_2T2R", - "RF_2T3R", - "RF_2T4R", - "RF_3T3R", - "RF_3T4R", - "RF_4T4R", - "RF_TYPE_MAX" +/* global operating class database */ + +struct op_class_t { + u8 class_id; + BAND_TYPE band; + enum opc_bw bw; + u8 *len_ch_attr; +}; + +#define OPC_CH_LIST_LEN(_opc) (_opc.len_ch_attr[0]) +#define OPC_CH_LIST_CH(_opc, _i) (_opc.len_ch_attr[_i + 1]) + +#define OP_CLASS_ENT(_class, _band, _bw, _len, arg...) \ + {.class_id = _class, .band = _band, .bw = _bw, .len_ch_attr = (uint8_t[_len + 1]) {_len, ##arg},} + +/* 802.11-2016 Table E-4, partial */ +static const struct op_class_t global_op_class[] = { + /* 2G ch1~13, 20M */ + OP_CLASS_ENT(81, BAND_ON_2_4G, OPC_BW20, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), + /* 2G ch14, 20M */ + OP_CLASS_ENT(82, BAND_ON_2_4G, OPC_BW20, 1, 14), + /* 2G, 40M */ + OP_CLASS_ENT(83, BAND_ON_2_4G, OPC_BW40PLUS, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9), + OP_CLASS_ENT(84, BAND_ON_2_4G, OPC_BW40MINUS, 9, 5, 6, 7, 8, 9, 10, 11, 12, 13), + /* 5G band 1, 20M & 40M */ + OP_CLASS_ENT(115, BAND_ON_5G, OPC_BW20, 4, 36, 40, 44, 48), + OP_CLASS_ENT(116, BAND_ON_5G, OPC_BW40PLUS, 2, 36, 44), + OP_CLASS_ENT(117, BAND_ON_5G, OPC_BW40MINUS, 2, 40, 48), + /* 5G band 2, 20M & 40M */ + OP_CLASS_ENT(118, BAND_ON_5G, OPC_BW20, 4, 52, 56, 60, 64), + OP_CLASS_ENT(119, BAND_ON_5G, OPC_BW40PLUS, 2, 52, 60), + OP_CLASS_ENT(120, BAND_ON_5G, OPC_BW40MINUS, 2, 56, 64), + /* 5G band 3, 20M & 40M */ + OP_CLASS_ENT(121, BAND_ON_5G, OPC_BW20, 12, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144), + OP_CLASS_ENT(122, BAND_ON_5G, OPC_BW40PLUS, 6, 100, 108, 116, 124, 132, 140), + OP_CLASS_ENT(123, BAND_ON_5G, OPC_BW40MINUS, 6, 104, 112, 120, 128, 136, 144), + /* 5G band 4, 20M & 40M */ + OP_CLASS_ENT(124, BAND_ON_5G, OPC_BW20, 4, 149, 153, 157, 161), + OP_CLASS_ENT(125, BAND_ON_5G, OPC_BW20, 6, 149, 153, 157, 161, 165, 169), + OP_CLASS_ENT(126, BAND_ON_5G, OPC_BW40PLUS, 2, 149, 157), + OP_CLASS_ENT(127, BAND_ON_5G, OPC_BW40MINUS, 2, 153, 161), + /* 5G, 80M & 160M */ + OP_CLASS_ENT(128, BAND_ON_5G, OPC_BW80, 24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161), + OP_CLASS_ENT(129, BAND_ON_5G, OPC_BW160, 16, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128), + #if 0 /* TODO */ + /* 5G, 80+80M */ + {130, BAND_ON_5G, OPC_BW80P80, 0x0FFFFFF}, + #endif +}; + +static const int global_op_class_num = sizeof(global_op_class) / sizeof(struct op_class_t); + +static const struct op_class_t *get_global_op_class_by_id(u8 gid) +{ + int i; + + for (i = 0; i < global_op_class_num; i++) + if (global_op_class[i].class_id == gid) + break; + + return i < global_op_class_num ? &global_op_class[i] : NULL; +} + +bool is_valid_global_op_class_id(u8 gid) +{ + return get_global_op_class_by_id(gid) ? 1 : 0; +} + +static bool is_valid_global_op_class_ch(const struct op_class_t *opc, u8 ch) +{ + int array_idx; + int i; + + if (opc < global_op_class + || (((u8 *)opc) - ((u8 *)global_op_class)) % sizeof(struct op_class_t) + ) { + RTW_ERR("Invalid opc pointer:%p (global_op_class:%p, sizeof(struct op_class_t):%zu, %zu)\n" + , opc, global_op_class, sizeof(struct op_class_t), (((u8 *)opc) - ((u8 *)global_op_class)) % sizeof(struct op_class_t)); + return 0; + } + + array_idx = (((u8 *)opc) - ((u8 *)global_op_class)) / sizeof(struct op_class_t); + + for (i = 0; i < OPC_CH_LIST_LEN(global_op_class[array_idx]); i++) + if (OPC_CH_LIST_CH(global_op_class[array_idx], i) == ch) + break; + + return i < OPC_CH_LIST_LEN(global_op_class[array_idx]); +} + +static enum opc_bw get_global_opc_bw_by_id(u8 gid) +{ + int i; + + for (i = 0; i < global_op_class_num; i++) + if (global_op_class[i].class_id == gid) + break; + + return i < global_op_class_num ? global_op_class[i].bw : OPC_BW_NUM; +} + +/* -2: logic error, -1: error, 0: is already BW20 */ +s16 get_sub_op_class(u8 gid, u8 ch) +{ + const struct op_class_t *opc = get_global_op_class_by_id(gid); + int i; + enum channel_width bw; + + if (!opc) + return -1; + + if (!is_valid_global_op_class_ch(opc, ch)) { + return -1; + } + + if (opc->bw == OPC_BW20) + return 0; + + bw = opc_bw_to_ch_width(opc->bw); + + for (i = 0; i < global_op_class_num; i++) { + if (bw != opc_bw_to_ch_width(global_op_class[i].bw) + 1) + continue; + if (is_valid_global_op_class_ch(&global_op_class[i], ch)) + break; + } + + return i < global_op_class_num ? global_op_class[i].class_id : -2; +} + +static void dump_op_class_ch_title(void *sel) +{ + RTW_PRINT_SEL(sel, "%-5s %-4s %-7s ch_list\n" + , "class", "band", "bw"); +} + +static void dump_global_op_class_ch_single(void *sel, u8 gid) +{ + u8 i; + char buf[100]; + char *pos = buf; + + for (i = 0; i < OPC_CH_LIST_LEN(global_op_class[gid]); i++) + pos += snprintf(pos, 100 - (pos - buf), " %u", OPC_CH_LIST_CH(global_op_class[gid], i)); + + RTW_PRINT_SEL(sel, "%5u %4s %7s%s\n" + , global_op_class[gid].class_id + , band_str(global_op_class[gid].band) + , opc_bw_str(global_op_class[gid].bw), buf); +} + +#ifdef CONFIG_RTW_DEBUG +static bool dbg_global_op_class_validate(u8 gid) +{ + u8 i; + u8 ch, bw, offset, cch; + bool ret = 1; + + switch (global_op_class[gid].bw) { + case OPC_BW20: + bw = CHANNEL_WIDTH_20; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case OPC_BW40PLUS: + bw = CHANNEL_WIDTH_40; + offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + case OPC_BW40MINUS: + bw = CHANNEL_WIDTH_40; + offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + case OPC_BW80: + bw = CHANNEL_WIDTH_80; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case OPC_BW160: + bw = CHANNEL_WIDTH_160; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case OPC_BW80P80: /* TODO */ + default: + RTW_ERR("%s class:%u unsupported opc_bw:%u\n" + , __func__, global_op_class[gid].class_id, global_op_class[gid].bw); + ret = 0; + goto exit; + } + + for (i = 0; i < OPC_CH_LIST_LEN(global_op_class[gid]); i++) { + u8 *op_chs; + u8 op_ch_num; + u8 k; + + ch = OPC_CH_LIST_CH(global_op_class[gid], i); + cch = rtw_get_center_ch(ch ,bw, offset); + if (!cch) { + RTW_ERR("%s can't get cch from class:%u ch:%u\n" + , __func__, global_op_class[gid].class_id, ch); + ret = 0; + continue; + } + + if (!rtw_get_op_chs_by_cch_bw(cch, bw, &op_chs, &op_ch_num)) { + RTW_ERR("%s can't get op chs from class:%u cch:%u\n" + , __func__, global_op_class[gid].class_id, cch); + ret = 0; + continue; + } + + for (k = 0; k < op_ch_num; k++) { + if (*(op_chs + k) == ch) + break; + } + if (k >= op_ch_num) { + RTW_ERR("%s can't get ch:%u from op_chs class:%u cch:%u\n" + , __func__, ch, global_op_class[i].class_id, cch); + ret = 0; + } + } + +exit: + return ret; +} +#endif /* CONFIG_RTW_DEBUG */ + +void dump_global_op_class(void *sel) +{ + u8 i; + + dump_op_class_ch_title(sel); + + for (i = 0; i < global_op_class_num; i++) + dump_global_op_class_ch_single(sel, i); +} + +u8 rtw_get_op_class_by_chbw(u8 ch, u8 bw, u8 offset) +{ + BAND_TYPE band = BAND_MAX; + int i; + u8 gid = 0; /* invalid */ + + if (rtw_is_2g_ch(ch)) + band = BAND_ON_2_4G; + else if (rtw_is_5g_ch(ch)) + band = BAND_ON_5G; + else + goto exit; + + switch (bw) { + case CHANNEL_WIDTH_20: + case CHANNEL_WIDTH_40: + case CHANNEL_WIDTH_80: + case CHANNEL_WIDTH_160: + #if 0 /* TODO */ + case CHANNEL_WIDTH_80_80: + #endif + break; + default: + goto exit; + } + + for (i = 0; i < global_op_class_num; i++) { + if (band != global_op_class[i].band) + continue; + + if (opc_bw_to_ch_width(global_op_class[i].bw) != bw) + continue; + + if ((global_op_class[i].bw == OPC_BW40PLUS + && offset != HAL_PRIME_CHNL_OFFSET_LOWER) + || (global_op_class[i].bw == OPC_BW40MINUS + && offset != HAL_PRIME_CHNL_OFFSET_UPPER) + ) + continue; + + if (is_valid_global_op_class_ch(&global_op_class[i], ch)) + goto get; + } + +get: + if (i < global_op_class_num) { + #if 0 /* TODO */ + if (bw == CHANNEL_WIDTH_80_80) { + /* search another ch */ + if (!is_valid_global_op_class_ch(&global_op_class[i], ch2)) + goto exit; + } + #endif + + gid = global_op_class[i].class_id; + } + +exit: + return gid; +} + +u8 rtw_get_bw_offset_by_op_class_ch(u8 gid, u8 ch, u8 *bw, u8 *offset) +{ + enum opc_bw opc_bw; + u8 valid = 0; + int i; + + opc_bw = get_global_opc_bw_by_id(gid); + if (opc_bw == OPC_BW_NUM) + goto exit; + + *bw = opc_bw_to_ch_width(opc_bw); + + if (opc_bw == OPC_BW40PLUS) + *offset = HAL_PRIME_CHNL_OFFSET_LOWER; + else if (opc_bw == OPC_BW40MINUS) + *offset = HAL_PRIME_CHNL_OFFSET_UPPER; + + if (rtw_get_offset_by_chbw(ch, *bw, offset)) + valid = 1; + +exit: + return valid; +} + +static struct op_class_pref_t *opc_pref_alloc(u8 class_id) +{ + int i, j; + struct op_class_pref_t *opc_pref = NULL; + + for (i = 0; i < global_op_class_num; i++) + if (global_op_class[i].class_id == class_id) + break; + + if (i >= global_op_class_num) + goto exit; + + opc_pref = rtw_zmalloc(sizeof(*opc_pref)); + if (!opc_pref) + goto exit; + + opc_pref->class_id = global_op_class[i].class_id; + opc_pref->band = global_op_class[i].band; + opc_pref->bw = global_op_class[i].bw; + + for (j = 0; j < OPC_CH_LIST_LEN(global_op_class[i]); j++) { + opc_pref->chs[j].ch = OPC_CH_LIST_CH(global_op_class[i], j); + opc_pref->chs[j].static_non_op = 1; + opc_pref->chs[j].no_ir = 1; + opc_pref->chs[j].max_txpwr = UNSPECIFIED_MBM; + } + opc_pref->ch_num = OPC_CH_LIST_LEN(global_op_class[i]); + +exit: + return opc_pref; +} + +static void opc_pref_free(struct op_class_pref_t *opc_pref) +{ + rtw_mfree(opc_pref, sizeof(*opc_pref)); +} + +int op_class_pref_init(_adapter *adapter) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + struct registry_priv *regsty = adapter_to_regsty(adapter); + u8 bw; + struct op_class_pref_t *opc_pref; + int i; + u8 op_class_num = 0; + u8 band_bmp = 0; + u8 bw_bmp[BAND_MAX] = {0}; + int ret = _FAIL; + + rfctl->spt_op_class_ch = rtw_zmalloc(sizeof(struct op_class_pref_t *) * global_op_class_num); + if (!rfctl->spt_op_class_ch) { + RTW_ERR("%s alloc rfctl->spt_op_class_ch fail\n", __func__); + goto exit; + } + + if (IsSupported24G(regsty->wireless_mode) && hal_chk_band_cap(adapter, BAND_CAP_2G)) + band_bmp |= BAND_CAP_2G; + if (is_supported_5g(regsty->wireless_mode) && hal_chk_band_cap(adapter, BAND_CAP_5G)) + band_bmp |= BAND_CAP_5G; + + bw_bmp[BAND_ON_2_4G] = (ch_width_to_bw_cap(REGSTY_BW_2G(regsty) + 1) - 1) & (GET_HAL_SPEC(adapter)->bw_cap); + bw_bmp[BAND_ON_5G] = (ch_width_to_bw_cap(REGSTY_BW_5G(regsty) + 1) - 1) & (GET_HAL_SPEC(adapter)->bw_cap); + if (!REGSTY_IS_11AC_ENABLE(regsty) + || !is_supported_vht(regsty->wireless_mode) + ) + bw_bmp[BAND_ON_5G] &= ~(BW_CAP_80M | BW_CAP_160M); + + if (0) { + RTW_INFO("REGSTY_BW_2G(regsty):%u\n", REGSTY_BW_2G(regsty)); + RTW_INFO("REGSTY_BW_5G(regsty):%u\n", REGSTY_BW_5G(regsty)); + RTW_INFO("GET_HAL_SPEC(adapter)->bw_cap:0x%x\n", GET_HAL_SPEC(adapter)->bw_cap); + RTW_INFO("band_bmp:0x%x\n", band_bmp); + RTW_INFO("bw_bmp[2G]:0x%x\n", bw_bmp[BAND_ON_2_4G]); + RTW_INFO("bw_bmp[5G]:0x%x\n", bw_bmp[BAND_ON_5G]); + } + + for (i = 0; i < global_op_class_num; i++) { + #ifdef CONFIG_RTW_DEBUG + rtw_warn_on(!dbg_global_op_class_validate(i)); + #endif + + if (!(band_bmp & band_to_band_cap(global_op_class[i].band))) + continue; + + bw = opc_bw_to_ch_width(global_op_class[i].bw); + if (bw == CHANNEL_WIDTH_MAX + || bw == CHANNEL_WIDTH_80_80 /* TODO */ + ) + continue; + + if (!(bw_bmp[global_op_class[i].band] & ch_width_to_bw_cap(bw))) + continue; + + opc_pref = opc_pref_alloc(global_op_class[i].class_id); + if (!opc_pref) { + RTW_ERR("%s opc_pref_alloc(%u) fail\n", __func__, global_op_class[i].class_id); + goto exit; + } + + if (opc_pref->ch_num) { + rfctl->spt_op_class_ch[i] = opc_pref; + op_class_num++; + } else + opc_pref_free(opc_pref); + } + + rfctl->cap_spt_op_class_num = op_class_num; + ret = _SUCCESS; + +exit: + return ret; +} + +void op_class_pref_deinit(_adapter *adapter) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + int i; + + if (!rfctl->spt_op_class_ch) + return; + + for (i = 0; i < global_op_class_num; i++) { + if (rfctl->spt_op_class_ch[i]) { + opc_pref_free(rfctl->spt_op_class_ch[i]); + rfctl->spt_op_class_ch[i] = NULL; + } + } + + rtw_mfree(rfctl->spt_op_class_ch, sizeof(struct op_class_pref_t *) * global_op_class_num); + rfctl->spt_op_class_ch = NULL; +} + +void op_class_pref_apply_regulatory(_adapter *adapter, u8 reason) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + RT_CHANNEL_INFO *chset = rfctl->channel_set; + struct registry_priv *regsty = adapter_to_regsty(adapter); + u8 ch, bw, offset, cch; + struct op_class_pref_t *opc_pref; + int i, j; + u8 reg_op_class_num = 0; + u8 op_class_num = 0; + + for (i = 0; i < global_op_class_num; i++) { + if (!rfctl->spt_op_class_ch[i]) + continue; + opc_pref = rfctl->spt_op_class_ch[i]; + + /* reset all channel */ + for (j = 0; opc_pref->chs[j].ch != 0; j++) { + if (reason >= REG_CHANGE) + opc_pref->chs[j].static_non_op = 1; + if (reason != REG_TXPWR_CHANGE) + opc_pref->chs[j].no_ir = 1; + if (reason >= REG_TXPWR_CHANGE) + opc_pref->chs[j].max_txpwr = UNSPECIFIED_MBM; + } + if (reason >= REG_CHANGE) + opc_pref->op_ch_num = 0; + if (reason != REG_TXPWR_CHANGE) + opc_pref->ir_ch_num = 0; + + switch (opc_pref->bw) { + case OPC_BW20: + bw = CHANNEL_WIDTH_20; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case OPC_BW40PLUS: + bw = CHANNEL_WIDTH_40; + offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + case OPC_BW40MINUS: + bw = CHANNEL_WIDTH_40; + offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + case OPC_BW80: + bw = CHANNEL_WIDTH_80; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case OPC_BW160: + bw = CHANNEL_WIDTH_160; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case OPC_BW80P80: /* TODO */ + default: + continue; + } + + if (rfctl->country_ent && !COUNTRY_CHPLAN_EN_11AC(rfctl->country_ent) + && (bw == CHANNEL_WIDTH_80 || bw == CHANNEL_WIDTH_160)) + continue; + + for (j = 0; opc_pref->chs[j].ch != 0; j++) { + u8 *op_chs; + u8 op_ch_num; + u8 k, l; + int chset_idx; + + ch = opc_pref->chs[j].ch; + + if (reason >= REG_TXPWR_CHANGE) + opc_pref->chs[j].max_txpwr = rtw_rfctl_get_reg_max_txpwr_mbm(rfctl, ch, bw, offset, 1); + + if (reason == REG_TXPWR_CHANGE) + continue; + + cch = rtw_get_center_ch(ch ,bw, offset); + if (!cch) + continue; + + if (!rtw_get_op_chs_by_cch_bw(cch, bw, &op_chs, &op_ch_num)) + continue; + + for (k = 0, l = 0; k < op_ch_num; k++) { + chset_idx = rtw_chset_search_ch(chset, *(op_chs + k)); + if (chset_idx == -1) + break; + if (bw >= CHANNEL_WIDTH_40) { + if ((chset[chset_idx].flags & RTW_CHF_NO_HT40U) && k % 2 == 0) + break; + if ((chset[chset_idx].flags & RTW_CHF_NO_HT40L) && k % 2 == 1) + break; + } + if (bw >= CHANNEL_WIDTH_80 && (chset[chset_idx].flags & RTW_CHF_NO_80MHZ)) + break; + if (bw >= CHANNEL_WIDTH_160 && (chset[chset_idx].flags & RTW_CHF_NO_160MHZ)) + break; + if ((chset[chset_idx].flags & RTW_CHF_DFS) && rtw_rfctl_dfs_domain_unknown(rfctl)) + continue; + if (chset[chset_idx].flags & RTW_CHF_NO_IR) + continue; + l++; + } + if (k < op_ch_num) + continue; + + if (reason >= REG_CHANGE) { + opc_pref->chs[j].static_non_op = 0; + opc_pref->op_ch_num++; + } + + if (l >= op_ch_num) { + opc_pref->chs[j].no_ir = 0; + opc_pref->ir_ch_num++; + } + } + + if (opc_pref->op_ch_num) + reg_op_class_num++; + if (opc_pref->ir_ch_num) + op_class_num++; + } + + rfctl->reg_spt_op_class_num = reg_op_class_num; + rfctl->cur_spt_op_class_num = op_class_num; +} + +static void dump_opc_pref_single(void *sel, struct op_class_pref_t *opc_pref, bool show_snon_ocp, bool show_no_ir, bool detail) +{ + u8 i; + u8 ch_num = 0; + char buf[256]; + char *pos = buf; + + if (!show_snon_ocp && !opc_pref->op_ch_num) + return; + if (!show_no_ir && !opc_pref->ir_ch_num) + return; + + for (i = 0; opc_pref->chs[i].ch != 0; i++) { + if ((show_snon_ocp || !opc_pref->chs[i].static_non_op) + && (show_no_ir || !opc_pref->chs[i].no_ir) + ) { + if (detail) + pos += snprintf(pos, 256 - (pos - buf), " %4u", opc_pref->chs[i].ch); + else + pos += snprintf(pos, 256 - (pos - buf), " %u", opc_pref->chs[i].ch); + } + } + + RTW_PRINT_SEL(sel, "%5u %4s %7s%s\n" + , opc_pref->class_id + , band_str(opc_pref->band) + , opc_bw_str(opc_pref->bw), buf); + + if (!detail) + return; + + pos = buf; + for (i = 0; opc_pref->chs[i].ch != 0; i++) { + if ((show_snon_ocp || !opc_pref->chs[i].static_non_op) + && (show_no_ir || !opc_pref->chs[i].no_ir) + ) { + pos += snprintf(pos, 256 - (pos - buf), " %c%c" + , opc_pref->chs[i].no_ir ? ' ' : 'I' + , opc_pref->chs[i].static_non_op ? ' ' : 'E' + ); + } + } + RTW_PRINT_SEL(sel, " %s\n", buf); + + pos = buf; + for (i = 0; opc_pref->chs[i].ch != 0; i++) { + if ((show_snon_ocp || !opc_pref->chs[i].static_non_op) + && (show_no_ir || !opc_pref->chs[i].no_ir) + ) { + if (opc_pref->chs[i].max_txpwr == UNSPECIFIED_MBM) + pos += snprintf(pos, 256 - (pos - buf), " "); + else + pos += snprintf(pos, 256 - (pos - buf), " %4d", opc_pref->chs[i].max_txpwr); + } + } + RTW_PRINT_SEL(sel, " %s\n", buf); +} + +void dump_cap_spt_op_class_ch(void *sel, struct rf_ctl_t *rfctl, bool detail) +{ + u8 i; + + dump_op_class_ch_title(sel); + + for (i = 0; i < global_op_class_num; i++) { + if (!rfctl->spt_op_class_ch[i]) + continue; + dump_opc_pref_single(sel, rfctl->spt_op_class_ch[i], 1, 1, detail); + } + + RTW_PRINT_SEL(sel, "op_class number:%d\n", rfctl->cap_spt_op_class_num); +} + +void dump_reg_spt_op_class_ch(void *sel, struct rf_ctl_t *rfctl, bool detail) +{ + u8 i; + + dump_op_class_ch_title(sel); + + for (i = 0; i < global_op_class_num; i++) { + if (!rfctl->spt_op_class_ch[i]) + continue; + dump_opc_pref_single(sel, rfctl->spt_op_class_ch[i], 0, 1, detail); + } + + RTW_PRINT_SEL(sel, "op_class number:%d\n", rfctl->reg_spt_op_class_num); +} + +void dump_cur_spt_op_class_ch(void *sel, struct rf_ctl_t *rfctl, bool detail) +{ + u8 i; + + dump_op_class_ch_title(sel); + + for (i = 0; i < global_op_class_num; i++) { + if (!rfctl->spt_op_class_ch[i]) + continue; + dump_opc_pref_single(sel, rfctl->spt_op_class_ch[i], 0, 0, detail); + } + + RTW_PRINT_SEL(sel, "op_class number:%d\n", rfctl->cur_spt_op_class_num); +} + +const u8 _rf_type_to_rf_tx_cnt[RF_TYPE_MAX] = { + [RF_1T1R] = 1, + [RF_1T2R] = 1, + [RF_1T3R] = 1, + [RF_1T4R] = 1, + [RF_2T1R] = 2, + [RF_2T2R] = 2, + [RF_2T3R] = 2, + [RF_2T4R] = 2, + [RF_3T1R] = 3, + [RF_3T2R] = 3, + [RF_3T3R] = 3, + [RF_3T4R] = 3, + [RF_4T1R] = 4, + [RF_4T2R] = 4, + [RF_4T3R] = 4, + [RF_4T4R] = 4, +}; + +const u8 _rf_type_to_rf_rx_cnt[RF_TYPE_MAX] = { + [RF_1T1R] = 1, + [RF_1T2R] = 2, + [RF_1T3R] = 3, + [RF_1T4R] = 4, + [RF_2T1R] = 1, + [RF_2T2R] = 2, + [RF_2T3R] = 3, + [RF_2T4R] = 4, + [RF_3T1R] = 1, + [RF_3T2R] = 2, + [RF_3T3R] = 3, + [RF_3T4R] = 4, + [RF_4T1R] = 1, + [RF_4T2R] = 2, + [RF_4T3R] = 3, + [RF_4T4R] = 4, +}; + +const char *const _rf_type_to_rfpath_str[RF_TYPE_MAX] = { + [RF_1T1R] = "RF_1T1R", + [RF_1T2R] = "RF_1T2R", + [RF_1T3R] = "RF_1T3R", + [RF_1T4R] = "RF_1T4R", + [RF_2T1R] = "RF_2T1R", + [RF_2T2R] = "RF_2T2R", + [RF_2T3R] = "RF_2T3R", + [RF_2T4R] = "RF_2T4R", + [RF_3T1R] = "RF_3T1R", + [RF_3T2R] = "RF_3T2R", + [RF_3T3R] = "RF_3T3R", + [RF_3T4R] = "RF_3T4R", + [RF_4T1R] = "RF_4T1R", + [RF_4T2R] = "RF_4T2R", + [RF_4T3R] = "RF_4T3R", + [RF_4T4R] = "RF_4T4R", }; void rf_type_to_default_trx_bmp(enum rf_type rf, enum bb_path *tx, enum bb_path *rx) { - switch (rf) { - case RF_1T1R: - *tx = BB_PATH_A; - *rx = BB_PATH_A; - break; - case RF_1T2R: - *tx = BB_PATH_A; - *rx = BB_PATH_AB; - break; - case RF_2T2R: - *tx = BB_PATH_AB; - *rx = BB_PATH_AB; - break; - case RF_2T3R: - *tx = BB_PATH_AB; - *rx = BB_PATH_ABC; - break; - case RF_2T4R: - *tx = BB_PATH_AB; - *rx = BB_PATH_ABCD; - break; - case RF_3T3R: - *tx = BB_PATH_ABC; - *rx = BB_PATH_ABC; - break; - case RF_3T4R: - *tx = BB_PATH_ABC; - *rx = BB_PATH_ABCD; - break; - case RF_4T4R: - *tx = BB_PATH_ABCD; - *rx = BB_PATH_ABCD; - break; - default: - *tx = BB_PATH_A; - *rx = BB_PATH_A; - break; - } + u8 tx_num = rf_type_to_rf_tx_cnt(rf); + u8 rx_num = rf_type_to_rf_rx_cnt(rf); + int i; + + *tx = *rx = 0; + + for (i = 0; i < tx_num; i++) + *tx |= BIT(i); + for (i = 0; i < rx_num; i++) + *rx |= BIT(i); } static const u8 _trx_num_to_rf_type[RF_PATH_MAX][RF_PATH_MAX] = { - {RF_1T1R, RF_1T2R, RF_TYPE_MAX, RF_TYPE_MAX}, - {RF_TYPE_MAX, RF_2T2R, RF_2T3R, RF_2T4R}, - {RF_TYPE_MAX, RF_TYPE_MAX, RF_3T3R, RF_3T4R}, - {RF_TYPE_MAX, RF_TYPE_MAX, RF_TYPE_MAX, RF_4T4R}, + {RF_1T1R, RF_1T2R, RF_1T3R, RF_1T4R}, + {RF_2T1R, RF_2T2R, RF_2T3R, RF_2T4R}, + {RF_3T1R, RF_3T2R, RF_3T3R, RF_3T4R}, + {RF_4T1R, RF_4T2R, RF_4T3R, RF_4T4R}, }; enum rf_type trx_num_to_rf_type(u8 tx_num, u8 rx_num) @@ -776,9 +1603,12 @@ const char *const _regd_str[] = { "ETSI", "IC", "KCC", + "NCC", "ACMA", "CHILE", + "UKRAINE", "MEXICO", + "CN", "WW", }; @@ -1483,7 +2313,8 @@ exit: void rtw_rf_set_tx_gain_offset(_adapter *adapter, u8 path, s8 offset) { -#if !defined(CONFIG_RTL8814A) && !defined(CONFIG_RTL8822B) && !defined(CONFIG_RTL8821C) && !defined(CONFIG_RTL8822C) +#if !defined(CONFIG_RTL8814A) && !defined(CONFIG_RTL8822B) && !defined(CONFIG_RTL8821C) && !defined(CONFIG_RTL8822C) \ + && !defined(CONFIG_RTL8723F) u8 write_value; #endif u8 target_path = 0; @@ -1543,15 +2374,17 @@ void rtw_rf_set_tx_gain_offset(_adapter *adapter, u8 path, s8 offset) rtw_hal_write_rfreg(adapter, target_path, 0x55, 0x0f8000, write_value); break; #endif /* CONFIG_RTL8821A */ -#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8822C) +#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8822C) \ + || defined(CONFIG_RTL8723F) case RTL8814A: case RTL8822B: case RTL8822C: case RTL8821C: case RTL8192F: + case RTL8723F: RTW_INFO("\nkfree by PhyDM on the sw CH. path %d\n", path); break; -#endif /* CONFIG_RTL8814A || CONFIG_RTL8822B || CONFIG_RTL8821C */ +#endif /* CONFIG_RTL8814A || CONFIG_RTL8822B || CONFIG_RTL8821C || CONFIG_RTL8723F */ default: rtw_warn_on(1); @@ -1589,34 +2422,9 @@ void rtw_rf_apply_tx_gain_offset(_adapter *adapter, u8 ch) } } -inline u8 rtw_is_dfs_range(u32 hi, u32 lo) -{ - return rtw_is_range_overlap(hi, lo, 5720 + 10, 5260 - 10); -} - -u8 rtw_is_dfs_ch(u8 ch) -{ - u32 hi, lo; - - if (!rtw_chbw_to_freq_range(ch, CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE, &hi, &lo)) - return 0; - - return rtw_is_dfs_range(hi, lo); -} - -u8 rtw_is_dfs_chbw(u8 ch, u8 bw, u8 offset) -{ - u32 hi, lo; - - if (!rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo)) - return 0; - - return rtw_is_dfs_range(hi, lo); -} - bool rtw_is_long_cac_range(u32 hi, u32 lo, u8 dfs_region) { - return (dfs_region == PHYDM_DFS_DOMAIN_ETSI && rtw_is_range_overlap(hi, lo, 5650, 5600)) ? _TRUE : _FALSE; + return (dfs_region == RTW_DFS_REGD_ETSI && rtw_is_range_overlap(hi, lo, 5650, 5600)) ? _TRUE : _FALSE; } bool rtw_is_long_cac_ch(u8 ch, u8 bw, u8 offset, u8 dfs_region) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rm.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rm.c index 2d934b73601c..a71a4ebffecd 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rm.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rm.c @@ -22,6 +22,9 @@ #endif #define pstr(s) s+strlen(s) +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif u8 rm_post_event_hdl(_adapter *padapter, u8 *pbuf) { @@ -192,8 +195,6 @@ int rm_en_cap_chk_and_set(struct rm_obj *prm, enum rm_cap_en en) /* for caller outside rm */ u8 rm_add_nb_req(_adapter *padapter, struct sta_info *psta) { - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct rm_obj *prm; @@ -206,16 +207,9 @@ u8 rm_add_nb_req(_adapter *padapter, struct sta_info *psta) prm->psta = psta; prm->q.category = RTW_WLAN_CATEGORY_RADIO_MEAS; - do { - pmlmeinfo->dialogToken++; - } while (pmlmeinfo->dialogToken == 0); - - prm->q.diag_token = pmlmeinfo->dialogToken; - prm->q.m_token = 1; - - prm->rmid = psta->cmn.aid << 16 - | prm->q.diag_token << 8 - | RM_MASTER; + prm->q.diag_token = rm_gen_dialog_token(padapter); + prm->q.m_token = rm_gen_meas_token(padapter); + prm->rmid = rm_gen_rmid(padapter, prm, RM_MASTER); prm->q.action_code = RM_ACT_NB_REP_REQ; @@ -371,8 +365,8 @@ int ready_for_scan(struct rm_obj *prm) int rm_sitesurvey(struct rm_obj *prm) { - int meas_ch_num=0; - u8 ch_num=0, op_class=0, val8; + int meas_ch_amount=0; + u8 op_class=0, val8; struct rtw_ieee80211_channel *pch_set; struct sitesurvey_parm parm; @@ -382,33 +376,40 @@ int rm_sitesurvey(struct rm_obj *prm) pch_set = &prm->q.ch_set[0]; _rtw_memset(pch_set, 0, - sizeof(struct rtw_ieee80211_channel) * MAX_OP_CHANNEL_SET_NUM); + sizeof(struct rtw_ieee80211_channel) * RTW_CHANNEL_SCAN_AMOUNT); + op_class = prm->q.op_class; if (prm->q.ch_num == 0) { /* ch_num=0 : scan all ch in operating class */ - op_class = prm->q.op_class; + meas_ch_amount = rm_get_ch_set(pch_set, + op_class, prm->q.ch_num); } else if (prm->q.ch_num == 255) { - /* 802.11 p.499 */ - /* ch_num=255 : scan all ch in current operating class */ - op_class = rm_get_oper_class_via_ch( - (u8)prm->psta->padapter->mlmeextpriv.cur_channel); + /* 802.11 p.1066 */ + /* ch_num=255 : If the Channel Number is 255 and includes + * AP Channel Report subelements + */ + meas_ch_amount = rm_get_ch_set_from_bcn_req_opt(pch_set, &prm->q.opt.bcn); } else - ch_num = prm->q.ch_num; + meas_ch_amount = rm_get_ch_set(pch_set, op_class, prm->q.ch_num); /* get means channel */ - meas_ch_num = rm_get_ch_set(pch_set, op_class, ch_num); - prm->q.ch_set_ch_amount = meas_ch_num; + prm->q.ch_set_ch_amount = meas_ch_amount; + +#if (RM_MORE_DBG_MSG) + RTW_INFO("survey (%d) chaannels\n", meas_ch_amount); +#endif _rtw_memset(&parm, 0, sizeof(struct sitesurvey_parm)); _rtw_memcpy(parm.ch, pch_set, - sizeof(struct rtw_ieee80211_channel) * MAX_OP_CHANNEL_SET_NUM); + sizeof(struct rtw_ieee80211_channel) * + MIN(meas_ch_amount, RTW_CHANNEL_SCAN_AMOUNT)); _rtw_memcpy(&parm.ssid[0], &prm->q.opt.bcn.ssid, IW_ESSID_MAX_SIZE); parm.ssid_num = 1; parm.scan_mode = prm->q.m_mode; - parm.ch_num = meas_ch_num; + parm.ch_num = meas_ch_amount; parm.igi = 0; parm.token = prm->rmid; parm.duration = prm->q.meas_dur; @@ -502,6 +503,8 @@ static int rm_parse_bcn_req_s_elem(struct rm_obj *prm, u8 *pbody, int req_len) u8 *popt_id; int i, p=0; /* position */ int len = req_len; + int ap_ch_rpt_idx = 0; + struct _RT_OPERATING_CLASS *op; /* opt length,2:pbody[0]+ pbody[1] */ @@ -535,7 +538,6 @@ static int rm_parse_bcn_req_s_elem(struct rm_obj *prm, u8 *pbody, int req_len) &pbody[p+2], pbody[p+1]); #endif #endif - RTW_INFO("RM: bcn_req_ssid=%s\n", prm->q.opt.bcn.ssid.Ssid); @@ -588,11 +590,32 @@ static int rm_parse_bcn_req_s_elem(struct rm_obj *prm, u8 *pbody, int req_len) popt_id[prm->q.opt.bcn.opt_id_num++] = pbody[p]; break; - case bcn_req_ac_ch_rep: + case bcn_req_ap_ch_rep: #if (RM_MORE_DBG_MSG) - RTW_INFO("RM: bcn_req_ac_ch_rep\n"); + RTW_INFO("RM: bcn_req_ap_ch_rep\n"); #endif + if (ap_ch_rpt_idx > BCN_REQ_OPT_AP_CH_RPT_MAX_NUM) { + RTW_ERR("RM: bcn_req_ap_ch_rep over size\n"); + break; + } + popt_id[prm->q.opt.bcn.opt_id_num++] = pbody[p]; + /* get channel list + * EID:len:op-class:ch-list + */ + op = rtw_malloc(sizeof (*op)); + op->global_op_class = pbody[p + 2]; + i = pbody[p + 1] - 1; /* ch list len; (-1) is op class */ + +#if (RM_MORE_DBG_MSG) + RTW_INFO("%d op class %d has %d ch\n", + ap_ch_rpt_idx,op->global_op_class,i); +#endif + op->Len = i; + memcpy(op->Channel, &pbody[p + 3], + MIN(i, MAX_CH_NUM_IN_OP_CLASS)); + prm->q.opt.bcn.ap_ch_rpt[ap_ch_rpt_idx++] = op; + prm->q.opt.bcn.ap_ch_rpt_num = ap_ch_rpt_idx; break; default: @@ -704,10 +727,7 @@ int rm_recv_radio_mens_req(_adapter *padapter, prm->q.m_token = pmeas_body[2]; prm->q.m_mode = pmeas_body[3]; prm->q.m_type = pmeas_body[4]; - - prm->rmid = psta->cmn.aid << 16 - | prm->q.diag_token << 8 - | RM_SLAVE; + prm->rmid = rm_gen_rmid(padapter, prm, RM_SLAVE); RTW_INFO("RM: rmid=%x, bssid " MAC_FMT "\n", prm->rmid, MAC_ARG(prm->psta->cmn.mac_addr)); @@ -767,7 +787,7 @@ done: int rm_recv_radio_mens_rep(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *psta) { - int ret = _FALSE; + int len, ret = _FALSE; struct rm_obj *prm; u32 rmid; u8 *pdiag_body = (u8 *)(precv_frame->u.hdr.rx_data + @@ -780,8 +800,11 @@ int rm_recv_radio_mens_rep(_adapter *padapter, | RM_MASTER; prm = rm_get_rmobj(padapter, rmid); - if (prm == NULL) - return _FALSE; + if (prm == NULL) { + /* not belong to us, report to upper */ + rtw_cfg80211_rx_rrm_action(psta->padapter, precv_frame); + return _TRUE; + } prm->p.action_code = pdiag_body[1]; prm->p.diag_token = pdiag_body[2]; @@ -808,6 +831,13 @@ int rm_recv_radio_mens_rep(_adapter *padapter, RTW_INFO("RM: recv %s\n", rm_type_rep_name(prm->p.m_type)); rm_post_event(padapter, prm->rmid, RM_EV_recv_rep); + /* report to upper via ioctl */ + if ((prm->from_ioctl == true) && + prm->q.m_type == bcn_req) { + len = pmeas_body[1] + 2; /* 2 : EID(1B) length(1B) */ + indicate_beacon_report(prm->psta->cmn.mac_addr, + 1, len, pmeas_body); + } return ret; } @@ -841,10 +871,7 @@ int rm_recv_link_mens_req(_adapter *padapter, prm->q.rx_rate = hw_rate_to_m_rate(precv_frame->u.hdr.attrib.data_rate); prm->q.rx_bw = precv_frame->u.hdr.attrib.bw; prm->q.rx_rsni = rm_get_frame_rsni(prm, precv_frame); - - prm->rmid = psta->cmn.aid << 16 - | prm->q.diag_token << 8 - | RM_SLAVE; + prm->rmid = rm_gen_rmid(padapter, prm, RM_SLAVE); RTW_INFO("RM: rmid=%x, bssid" MAC_FMT " rx_pwr=%ddBm, rate=%s\n", prm->rmid, MAC_ARG(prm->psta->cmn.mac_addr), prm->q.rx_pwr, @@ -880,8 +907,9 @@ int rm_recv_link_mens_rep(_adapter *padapter, prm = rm_get_rmobj(padapter, rmid); if (prm == NULL) { - RTW_ERR("RM: rmid 0x%08x not found\n", rmid); - return ret; + /* not belong to us, report to upper */ + rtw_cfg80211_rx_rrm_action(psta->padapter, precv_frame); + return _TRUE; } RTW_INFO("RM: rmid=%x, bssid " MAC_FMT "\n", prm->rmid, @@ -923,8 +951,12 @@ int rm_radio_mens_nb_rep(_adapter *padapter, | RM_MASTER; prm = rm_get_rmobj(padapter, rmid); - if (prm == NULL) - return _FALSE; + + if (prm == NULL) { + /* not belong to us, report to upper */ + rtw_cfg80211_rx_rrm_action(psta->padapter, precv_frame); + return _TRUE; + } prm->p.action_code = pdiag_body[1]; prm->p.diag_token = pdiag_body[2]; @@ -1109,6 +1141,9 @@ static u8 *rm_gen_bcn_detail_elem(_adapter *padapter, u8 *pframe, continue; #if (RM_MORE_DBG_MSG) switch (eid) { + case EID_SsId: + RTW_INFO("RM: EID_SSID\n"); + break; case EID_QBSSLoad: RTW_INFO("RM: EID_QBSSLoad\n"); break; @@ -1118,16 +1153,24 @@ static u8 *rm_gen_bcn_detail_elem(_adapter *padapter, u8 *pframe, case _MDIE_: RTW_INFO("RM: EID_MobilityDomain\n"); break; + case EID_Vendor: + RTW_INFO("RM: EID_Vendor\n"); + break; default: RTW_INFO("RM: EID %d todo\n",eid); break; } #endif pframe = rtw_set_ie(pframe, eid, - len,ptr+2, &my_len); + len, ptr+2, &my_len); } /* for() */ break; - case bcn_req_ac_ch_rep: + case bcn_req_rep_detail: + RTW_INFO("RM: bcn_req_rep_detail\n"); + break; + case bcn_req_ap_ch_rep: + RTW_INFO("RM: bcn_req_ap_ch_rep\n"); + break; default: RTW_INFO("RM: OPT %d TODO\n",prm->q.opt.bcn.opt_id[j]); break; @@ -1237,7 +1280,10 @@ static u8 *rm_gen_bcn_rep_ie (struct rm_obj *prm, pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len); /* ParentTSF */ - val32 = prm->meas_start_time + pnetwork->network.PhyInfo.free_cnt; + val32 = pnetwork->network.PhyInfo.free_cnt; + if (prm->free_run_counter_valid) + val32 += prm->meas_start_time; + pframe = rtw_set_fixed_ie(pframe, 4, (u8 *)&val32, &my_len); /* Generate Beacon detail */ @@ -1256,6 +1302,99 @@ static u8 *rm_gen_bcn_rep_ie (struct rm_obj *prm, return pframe; } +#if 0 /* check MBO logo */ +static int rm_match_sub_elem(_adapter *padapter, + struct rm_obj *prm, struct wlan_network *pnetwork) +{ + WLAN_BSSID_EX *pbss = &pnetwork->network; + unsigned int my_len; + int j, k, len; + u8 *plen; + u8 *ptr; + u8 val8, eid; + + + my_len = 0; + /* Reporting Detail values + * 0: No fixed length fields or elements + * 1: All fixed length fields and any requested elements + * in the Request info element if present + * 2: All fixed length fields and elements + * 3-255: Reserved + */ + + /* report_detail != 1 */ + if (prm->q.opt.bcn.rep_detail != 1) + return _TRUE; + + /* report_detail = 1 */ + + for (j = 0; j < prm->q.opt.bcn.opt_id_num; j++) { + switch (prm->q.opt.bcn.opt_id[j]) { + case bcn_req_ssid: + /* SSID */ +#if (RM_MORE_DBG_MSG) + RTW_INFO("RM: bcn_req_ssid\n"); +#endif + if (pbss->Ssid.SsidLength == 0) + return _FALSE; + break; + case bcn_req_req: + if (prm->q.opt.bcn.req_start == NULL) + break; +#if (RM_MORE_DBG_MSG) + RTW_INFO("RM: bcn_req_req"); +#endif + for (k=0; kq.opt.bcn.req_len; k++) { + eid = prm->q.opt.bcn.req_start[k]; + + val8 = pbss->IELength - _FIXED_IE_LENGTH_; + ptr = rtw_get_ie(pbss->IEs + _FIXED_IE_LENGTH_, + eid, &len, val8); + +#if (RM_MORE_DBG_MSG) + switch (eid) { + case EID_SsId: + RTW_INFO("RM: EID_SSID\n"); + break; + case EID_QBSSLoad: + RTW_INFO("RM: EID_QBSSLoad\n"); + break; + case EID_HTCapability: + RTW_INFO("RM: EID_HTCapability\n"); + break; + case _MDIE_: + RTW_INFO("RM: EID_MobilityDomain\n"); + break; + case EID_Vendor: + RTW_INFO("RM: EID_Vendor\n"); + break; + default: + RTW_INFO("RM: EID %d todo\n",eid); + break; + } +#endif + if (!ptr) { + RTW_INFO("RM: EID %d not found\n",eid); + return _FALSE; + } + } /* for() */ + break; + case bcn_req_rep_detail: + RTW_INFO("RM: bcn_req_rep_detail\n"); + break; + case bcn_req_ap_ch_rep: + RTW_INFO("RM: bcn_req_ap_ch_rep\n"); + break; + default: + RTW_INFO("RM: OPT %d TODO\n",prm->q.opt.bcn.opt_id[j]); + break; + } + } + return _TRUE; +} +#endif + static int retrieve_scan_result(struct rm_obj *prm) { _irqL irqL; @@ -1265,7 +1404,7 @@ static int retrieve_scan_result(struct rm_obj *prm) struct rtw_ieee80211_channel *pch_set; struct wlan_network *pnetwork = NULL; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - int i, meas_ch_num=0; + int i; PWLAN_BSSID_EX pbss; unsigned int matched_network; int len, my_len; @@ -1288,7 +1427,6 @@ static int retrieve_scan_result(struct rm_obj *prm) /* get requested measurement channel set */ pch_set = prm->q.ch_set; - meas_ch_num = prm->q.ch_set_ch_amount; /* search scan queue to find requested SSID */ while (1) { @@ -1299,88 +1437,98 @@ static int retrieve_scan_result(struct rm_obj *prm) pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); pbss = &pnetwork->network; +#if 0 + RTW_INFO("RM: ooo ch %u ssid %s bssid "MAC_FMT"\n", + pbss->Configuration.DSConfig, pbss->Ssid.Ssid, + MAC_ARG(pbss->MacAddress)); /* * report network if requested channel set contains * the channel matchs selected network */ if (rtw_chset_search_ch(adapter_to_chset(padapter), - pbss->Configuration.DSConfig) == 0) + pbss->Configuration.DSConfig) < 0) /* not match */ goto next; if (rtw_mlme_band_check(padapter, pbss->Configuration.DSConfig) == _FALSE) goto next; - +#endif if (rtw_validate_ssid(&(pbss->Ssid)) == _FALSE) goto next; + /* match bssid */ + if (is_wildcard_bssid(prm->q.bssid) == FALSE) + if (_rtw_memcmp(prm->q.bssid, + pbss->MacAddress, 6) == _FALSE) + //continue; + goto next; + /* + * default wildcard SSID. wildcard SSID: + * A SSID value (null) used to represent all SSIDs + */ + + /* match ssid */ + if ((prm->q.opt.bcn.ssid.SsidLength > 0) && + _rtw_memcmp(prm->q.opt.bcn.ssid.Ssid, + pbss->Ssid.Ssid, + prm->q.opt.bcn.ssid.SsidLength) == _FALSE) + goto next; + /* go through measurement requested channels */ - for (i = 0; i < meas_ch_num; i++) { + for (i = 0; i < prm->q.ch_set_ch_amount; i++) { + if ((pch_set[i].hw_value) == + (pbss->Configuration.DSConfig)) /* match ch */ + break; + } + if (i >= prm->q.ch_set_ch_amount) /* channel mismatch */ + goto next; - /* match channel */ - if (pch_set[i].hw_value != pbss->Configuration.DSConfig) - continue; - - /* match bssid */ - if (is_wildcard_bssid(prm->q.bssid) == FALSE) - if (_rtw_memcmp(prm->q.bssid, - pbss->MacAddress, 6) == _FALSE) { - continue; - } - /* - * default wildcard SSID. wildcard SSID: - * A SSID value (null) used to represent all SSIDs - */ - - /* match ssid */ - if ((prm->q.opt.bcn.ssid.SsidLength > 0) && - _rtw_memcmp(prm->q.opt.bcn.ssid.Ssid, - pbss->Ssid.Ssid, - prm->q.opt.bcn.ssid.SsidLength) == _FALSE) - continue; - - /* match condition */ - if (rm_bcn_req_cond_mach(prm, pnetwork) == _FALSE) { - RTW_INFO("RM: condition mismatch ch %u ssid %s bssid "MAC_FMT"\n", - pch_set[i].hw_value, pbss->Ssid.Ssid, - MAC_ARG(pbss->MacAddress)); - RTW_INFO("RM: condition %u:%u\n", - prm->q.opt.bcn.rep_cond.cond, - prm->q.opt.bcn.rep_cond.threshold); - continue; - } - - /* Found a matched SSID */ - matched_network++; - - RTW_INFO("RM: ch %u Found %s bssid "MAC_FMT"\n", - pch_set[i].hw_value, pbss->Ssid.Ssid, + /* match condition */ + if (rm_bcn_req_cond_mach(prm, pnetwork) == _FALSE) { + RTW_INFO("RM: condition mismatch ch %u ssid %s bssid "MAC_FMT"\n", + pbss->Configuration.DSConfig, pbss->Ssid.Ssid, MAC_ARG(pbss->MacAddress)); + RTW_INFO("RM: condition %u:%u\n", + prm->q.opt.bcn.rep_cond.cond, + prm->q.opt.bcn.rep_cond.threshold); + goto next; + //continue; + } +#if 0 /* check MBO logo */ + /* match subelement */ + if (rm_match_sub_elem(padapter, prm, pnetwork) == _FALSE) + goto next; +#endif + /* Found a matched SSID */ + matched_network++; - len = 0; - _rtw_memset(tmp_buf, 0, MAX_XMIT_EXTBUF_SZ); - rm_gen_bcn_rep_ie(prm, tmp_buf, pnetwork, &len); + RTW_INFO("RM: ch %u Found %s bssid "MAC_FMT"\n", + pbss->Configuration.DSConfig, pbss->Ssid.Ssid, + MAC_ARG(pbss->MacAddress)); + + len = 0; + _rtw_memset(tmp_buf, 0, MAX_XMIT_EXTBUF_SZ); + rm_gen_bcn_rep_ie(prm, tmp_buf, pnetwork, &len); new_packet: - if (my_len == 0) { - pbuf = rtw_malloc(MAX_XMIT_EXTBUF_SZ); - if (pbuf == NULL) - goto fail; - prm->buf[buf_idx].pbuf = pbuf; - } + if (my_len == 0) { + pbuf = rtw_malloc(MAX_XMIT_EXTBUF_SZ); + if (pbuf == NULL) + goto fail; + prm->buf[buf_idx].pbuf = pbuf; + } - if ((MAX_XMIT_EXTBUF_SZ - (my_len+len+24+4)) > 0) { - pbuf = rtw_set_fixed_ie(pbuf, - len, tmp_buf, &my_len); - prm->buf[buf_idx].len = my_len; - } else { - if (my_len == 0) /* not enough space */ - goto fail; + if ((MAX_XMIT_EXTBUF_SZ - (my_len+len+24+4)) > 0) { + pbuf = rtw_set_fixed_ie(pbuf, + len, tmp_buf, &my_len); + prm->buf[buf_idx].len = my_len; + } else { + if (my_len == 0) /* not enough space */ + goto fail; - my_len = 0; - buf_idx++; - goto new_packet; - } - } /* for() */ + my_len = 0; + buf_idx++; + goto new_packet; + } next: plist = get_next(plist); } /* while() */ @@ -1648,17 +1796,96 @@ int issue_link_meas_rep(struct rm_obj *prm) } static u8 *rm_gen_bcn_req_s_elem(_adapter *padapter, - u8 *pframe, unsigned int *fr_len) + struct rm_obj *prm, u8 *pframe, unsigned int *fr_len) { - u8 val8; + u8 val8, l; + int i; unsigned int my_len = 0; - u8 bssid[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - + struct _RT_OPERATING_CLASS *op; + /* meas mode */ val8 = bcn_req_active; /* measurement mode T8-64 */ pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len); - pframe = rtw_set_fixed_ie(pframe, 6, bssid, &my_len); + /* bssid */ + pframe = rtw_set_fixed_ie(pframe, 6, prm->q.bssid, &my_len); + + /* + * opt ssid (0) + */ + l = MIN(32, (int)prm->q.opt.bcn.ssid.SsidLength); + + l = (int)prm->q.opt.bcn.ssid.SsidLength; + + if (l > 32) + RTW_ERR("RM: %s SSID len over size %d! skip it!\n",__func__, l); + + if (l > 0 && l <= 32) { + /* Type */ + val8 = bcn_req_ssid; + pframe = rtw_set_fixed_ie(pframe, 1, + &val8, &my_len); + /* Len */ + pframe = rtw_set_fixed_ie(pframe, 1, + &l, &my_len); + /* Value */ + pframe = rtw_set_fixed_ie(pframe, l, + prm->q.opt.bcn.ssid.Ssid, &my_len); + } + + /* + * opt reporting detail (2) + */ + /* Type */ + val8 = bcn_req_rep_detail; + pframe = rtw_set_fixed_ie(pframe, 1, + &val8, &my_len); + /* Len */ + l = 1; + pframe = rtw_set_fixed_ie(pframe, 1, + &l, &my_len); + /* Value */ + pframe = rtw_set_fixed_ie(pframe, l, + &prm->q.opt.bcn.rep_detail, &my_len); + + /* + * opt request (10) + */ + + if (prm->q.opt.bcn.req_id_num > 0) { + /* Type */ + val8 = bcn_req_req; + pframe = rtw_set_fixed_ie(pframe, 1, + &val8, &my_len); + /* Len */ + l = prm->q.opt.bcn.req_id_num; + pframe = rtw_set_fixed_ie(pframe, 1, + &l, &my_len); + /* Value */ + pframe = rtw_set_fixed_ie(pframe, l, + prm->q.opt.bcn.req_id, &my_len); + } + + /* + * opt ap channel report (51) + */ + for (i = 0; i < prm->q.opt.bcn.ap_ch_rpt_num; i++) { + op = prm->q.opt.bcn.ap_ch_rpt[i]; + if (op == NULL) + break; + /* Type */ + val8 = bcn_req_ap_ch_rep; + pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len); + l = (u8)op->Len + 1; + /* length */ + pframe = rtw_set_fixed_ie(pframe, 1, &l, &my_len); + + /* op class */ + val8 = op->global_op_class; + pframe = rtw_set_fixed_ie(pframe, 1, &val8, &my_len); + /* channel */ + pframe = rtw_set_fixed_ie(pframe, op->Len, op->Channel, &my_len); + } /* update length to caller */ *fr_len += my_len; @@ -1739,6 +1966,8 @@ int issue_radio_meas_req(struct rm_obj *prm) } pattr = &pmgntframe->attrib; pframe = build_wlan_hdr(padapter, pmgntframe, prm->psta, WIFI_ACTION); + + /* Category, Action code, Dialog token */ pframe = rtw_set_fixed_ie(pframe, 3, &prm->q.category, &pattr->pktlen); /* repeat */ @@ -1748,22 +1977,21 @@ int issue_radio_meas_req(struct rm_obj *prm) my_len = 0; plen = pframe + 1; + /* Element ID, Length, Meas token, Meas Mode, Meas type, op class, ch */ pframe = rtw_set_fixed_ie(pframe, 7, &prm->q.e_id, &my_len); /* random interval */ - val16 = 100; /* 100 TU */ - val16 = cpu_to_le16(val16); + val16 = cpu_to_le16(prm->q.rand_intvl); /* TU */ pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&val16, &my_len); /* measurement duration */ - val16 = 100; - val16 = cpu_to_le16(val16); + val16 = cpu_to_le16(prm->q.meas_dur); pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&val16, &my_len); /* optional subelement */ switch (prm->q.m_type) { case bcn_req: - pframe = rm_gen_bcn_req_s_elem(padapter, pframe, &my_len); + pframe = rm_gen_bcn_req_s_elem(padapter, prm, pframe, &my_len); break; case ch_load_req: pframe = rm_gen_ch_load_req_s_elem(padapter, pframe, &my_len); @@ -1805,9 +2033,11 @@ int rm_radio_meas_report_cond(struct rm_obj *prm) case ch_load_cond_anpi_equal_greater: if (val8 >= prm->q.opt.clm.rep_cond.threshold) return _SUCCESS; + break; case ch_load_cond_anpi_equal_less: if (val8 <= prm->q.opt.clm.rep_cond.threshold) return _SUCCESS; + break; default: break; } @@ -2117,7 +2347,6 @@ done: static int rm_dbg_modify_meas(_adapter *padapter, char *s) { struct rm_priv *prmpriv = &padapter->rmpriv; - struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info; struct rm_obj *prm; struct sta_info *psta; char *pmac, *ptr, *paid, *prpt, *pnbp, *pclm, *pnhm, *pbcn, *plnk; @@ -2148,7 +2377,7 @@ static int rm_dbg_modify_meas(_adapter *padapter, char *s) } } prm = (struct rm_obj *)prmpriv->prm_sel; - prm->q.m_token = 1; + prm->q.m_token = rm_gen_meas_token(padapter); psta = prm->psta; if (paid) { /* find sta_info according to aid */ @@ -2167,26 +2396,16 @@ static int rm_dbg_modify_meas(_adapter *padapter, char *s) if (psta) { prm->psta = psta; - -#if 0 - prm->q.diag_token = psta->rm_diag_token++; -#else - /* TODO dialog should base on sta_info */ - do { - pmlmeinfo->dialogToken++; - } while (pmlmeinfo->dialogToken == 0); - - prm->q.diag_token = pmlmeinfo->dialogToken; -#endif - prm->rmid = psta->cmn.aid << 16 - | prm->q.diag_token << 8 - | RM_MASTER; + prm->q.diag_token = rm_gen_dialog_token(padapter); + prm->rmid = rm_gen_rmid(padapter, prm, RM_MASTER); } else return _FAIL; prm->q.action_code = RM_ACT_RADIO_MEAS_REQ; if (pbcn) { prm->q.m_type = bcn_req; + prm->q.rand_intvl = le16_to_cpu(100); + prm->q.meas_dur = le16_to_cpu(100); } else if (pnhm) { prm->q.m_type = noise_histo_req; } else if (pclm) { @@ -2243,6 +2462,108 @@ static void rm_dbg_activate_meas(_adapter *padapter, char *s) prmpriv->prm_sel = NULL; } +/* for ioctl */ +int rm_send_bcn_reqs(_adapter *padapter, u8 *sta_addr, u8 op_class, u8 ch, + u16 measure_duration, u8 measure_mode, u8 *bssid, u8 *ssid, + u8 reporting_detail, + u8 n_ap_ch_rpt, struct _RT_OPERATING_CLASS *rpt, + u8 n_elem_id, u8 *elem_id_list) + +{ + struct rm_obj *prm; + char *pact; + struct sta_info *psta; + struct _RT_OPERATING_CLASS *prpt; + void *ptr; + int i,j,sz; + u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + + if (n_ap_ch_rpt > BCN_REQ_OPT_AP_CH_RPT_MAX_NUM) { + RTW_ERR("RM: chset num %d > %d\n", + n_ap_ch_rpt, BCN_REQ_OPT_AP_CH_RPT_MAX_NUM); + return -1; + } + /* dest sta */ + psta = rtw_get_stainfo(&padapter->stapriv, sta_addr); + if (!psta) { + RTW_ERR("RM: psta not found\n"); + return -2; + } + prm = rm_alloc_rmobj(padapter); + if (prm == NULL) { + RTW_ERR("RM: unable to alloc rm obj for requeset\n"); + return -3; + } + + prm->psta = psta; + prm->q.meas_dur = measure_duration; + + /* Figure 8-104 Measurement Requested format */ + prm->q.category = RTW_WLAN_CATEGORY_RADIO_MEAS; + prm->q.action_code = RM_ACT_RADIO_MEAS_REQ; + prm->q.m_mode = measure_mode; + prm->q.m_type = bcn_req; + prm->q.diag_token = rm_gen_dialog_token(padapter); + prm->q.m_token = rm_gen_meas_token(padapter); + prm->rmid = rm_gen_rmid(padapter, prm, RM_MASTER); + + prm->q.e_id = _MEAS_REQ_IE_; /* 38 */ + prm->q.ch_num = ch; + prm->q.op_class = op_class; + prm->from_ioctl = true; + + if (bssid != NULL) + memcpy(prm->q.bssid, bssid, ETH_ALEN); + else + memcpy(prm->q.bssid, bcast, ETH_ALEN); + + if (ssid != NULL) { + i = MIN(32, strlen(ssid)); + prm->q.opt.bcn.ssid.SsidLength = i; + memcpy(prm->q.opt.bcn.ssid.Ssid, ssid, i); + } + + if (n_ap_ch_rpt > 0) { + prm->q.opt.bcn.ap_ch_rpt_num = n_ap_ch_rpt; + j = 0; + for (i = 0; i < n_ap_ch_rpt; i++) { + prpt = rpt++; + if (prpt == NULL) + break; + + sz = sizeof(struct _RT_OPERATING_CLASS) * prpt->Len; + ptr = rtw_malloc(sz); + _rtw_memcpy(ptr, prpt, sz); + prm->q.opt.bcn.ap_ch_rpt[i] = (struct _RT_OPERATING_CLASS *)ptr; + } + } + prm->q.opt.bcn.rep_detail = reporting_detail; + + if ((n_elem_id > 0) && (n_elem_id < BCN_REQ_REQ_OPT_MAX_NUM)) { + prm->q.opt.bcn.req_id_num = n_elem_id; + _rtw_memcpy(prm->q.opt.bcn.req_id, elem_id_list, n_elem_id); + } + /* enquee rmobj */ + rm_enqueue_rmobj(padapter, prm, _FALSE); + + RTW_INFO("\nAdd rmid=%x, meas_type=%s ok\n", + prm->rmid, rm_type_req_name(prm->q.m_type)); + + if (prm->psta) + RTW_INFO("mac="MAC_FMT"\n", MAC_ARG(prm->psta->cmn.mac_addr)); + return 0; +} + +void indicate_beacon_report(u8 *sta_addr, + u8 n_measure_rpt, u32 elem_len, u8 *elem) +{ + RTW_INFO("RM: recv bcn reprot from mac="MAC_FMT"\n", MAC_ARG(sta_addr)); +#ifdef CONFIG_PLATFORM_CMAP_INTFS + cmap_intfs_nl_beacon_report_event(sta_addr, n_measure_rpt, elem_len, elem); +#endif +} + static void rm_dbg_add_meas(_adapter *padapter, char *s) { struct rm_priv *prmpriv = &(padapter->rmpriv); @@ -2412,6 +2733,37 @@ static void rm_dbg_list_meas(_adapter *padapter, char *s) } #endif /* RM_SUPPORT_IWPRIV_DBG */ +int verify_bcn_req(_adapter *padapter, struct sta_info *psta) +{ + char *bssid = NULL; + char ssid[] = "RealKungFu"; + u8 op_class = 0; + u8 ch = 255; + u16 measure_duration = 100; + u8 reporting_detaial = 0; + u8 n_ap_ch_rpt = 6; + u8 measure_mode = bcn_req_active; + u8 req[] = {1,2,3}; + u8 req_len = sizeof(req); + + + static RT_OPERATING_CLASS US[] = { + /* 0, OP_CLASS_NULL */ //{ 0, 0, {}}, + /* 1, OP_CLASS_1 */ {115, 4, {36, 40, 44, 48}}, + /* 2, OP_CLASS_2 */ {118, 4, {52, 56, 60, 64}}, + /* 3, OP_CLASS_3 */ {124, 4, {149, 153, 157, 161}}, + /* 4, OP_CLASS_4 */ {121, 11, {100, 104, 108, 112, 116, 120, 124, + 128, 132, 136, 140}}, + /* 5, OP_CLASS_5 */ {125, 5, {149, 153, 157, 161, 165}}, + /* 6, OP_CLASS_12 */ { 81, 11, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}} + }; + + rm_send_bcn_reqs(padapter, psta->cmn.mac_addr, op_class, ch, + measure_duration, measure_mode, bssid, ssid, + reporting_detaial, n_ap_ch_rpt, US, req_len, req); + return 0; +} + void rm_dbg_cmd(_adapter *padapter, char *s) { unsigned val; @@ -2422,6 +2774,19 @@ void rm_dbg_cmd(_adapter *padapter, char *s) if (_rtw_memcmp(s, "help", 4)) { rm_dbg_help(padapter, s); + } else if (_rtw_memcmp(s, "send_bcn_req", 12)) { + + /* rtwpriv wls1 rrm send_bcn_req aid=1 */ + paid = strstr(s, "aid="); + if (paid) { /* find sta_info according to aid */ + paid += 4; /* skip aid= */ + sscanf(paid, "%u", &val); /* aid=x */ + psta = rm_get_sta(padapter, val, NULL); + + if (psta) + verify_bcn_req(padapter, psta); + } + } else if (_rtw_memcmp(s, "list_sta", 8)) { rm_dbg_list_sta(padapter, s); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rm_fsm.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rm_fsm.c index 6ca0f011d787..ce3f745cc0c0 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rm_fsm.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rm_fsm.c @@ -123,6 +123,7 @@ int rtw_init_rm(_adapter *padapter) padapter, rm_timer_callback, padapter); _set_timer(&prmpriv->rm_timer, CLOCK_UNIT); + prmpriv->meas_token = 1; return _SUCCESS; } @@ -669,8 +670,9 @@ static int rm_state_do_meas(struct rm_obj *prm, enum RM_EV_ID evid) switch (prm->q.m_type) { case bcn_req: val8 = 1; /* Enable free run counter */ - rtw_hal_set_hwreg(padapter, - HW_VAR_FREECNT, &val8); + prm->free_run_counter_valid = rtw_hal_set_hwreg( + padapter, HW_VAR_FREECNT, &val8); + rm_sitesurvey(prm); break; case ch_load_req: diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rm_util.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rm_util.c index f9c88029d5b5..04fe99ba8e6c 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rm_util.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rm_util.c @@ -66,6 +66,29 @@ done: return ch_amount; } +u8 rm_get_ch_set_from_bcn_req_opt( + struct rtw_ieee80211_channel *pch_set, struct bcn_req_opt *opt) +{ + int i,j,k,sz; + struct _RT_OPERATING_CLASS *ap_ch_rpt; + u8 ch_amount = 0; + + k = 0; + for (i = 0; i < opt->ap_ch_rpt_num; i++) { + if (opt->ap_ch_rpt[i] == NULL) + break; + ap_ch_rpt = opt->ap_ch_rpt[i]; + for (j = 0; j < ap_ch_rpt->Len; j++) { + pch_set[k].hw_value = + ap_ch_rpt->Channel[j]; + RTW_INFO("RM: meas_ch[%d].hw_value = %u\n", + j, pch_set[k].hw_value); + k++; + } + } + return k; +} + u8 rm_get_oper_class_via_ch(u8 ch) { int i,j,sz; @@ -432,4 +455,48 @@ int rm_get_path_a_max_tx_power(_adapter *adapter, s8 *path_a) return 0; } +u8 rm_gen_dialog_token(_adapter *padapter) +{ + struct rm_priv *prmpriv = &(padapter->rmpriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + + do { + pmlmeinfo->dialogToken++; + } while (pmlmeinfo->dialogToken == 0); + + return pmlmeinfo->dialogToken; +} + +u8 rm_gen_meas_token(_adapter *padapter) +{ + struct rm_priv *prmpriv = &(padapter->rmpriv); + + do { + prmpriv->meas_token++; + } while (prmpriv->meas_token == 0); + + return prmpriv->meas_token; +} + +u32 rm_gen_rmid(_adapter *padapter, struct rm_obj *prm, u8 role) +{ + u32 rmid; + + if (prm->psta == NULL) + goto err; + + if (prm->q.diag_token == 0) + goto err; + + rmid = prm->psta->cmn.aid << 16 + | prm->q.diag_token << 8 + | role; + + return rmid; +err: + RTW_ERR("RM: unable to gen rmid\n"); + return 0; +} + #endif /* CONFIG_RTW_80211K */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_roch.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_roch.c new file mode 100644 index 000000000000..e4d7403b44fd --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_roch.c @@ -0,0 +1,592 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2020 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#include + +#ifdef CONFIG_IOCTL_CFG80211 +u8 rtw_roch_stay_in_cur_chan(_adapter *padapter) +{ + int i; + _adapter *iface; + struct mlme_priv *pmlmepriv; + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + u8 rst = _FALSE; + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (iface) { + pmlmepriv = &iface->mlmepriv; + + if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS | WIFI_UNDER_KEY_HANDSHAKE) == _TRUE) { + RTW_INFO(ADPT_FMT"- WIFI_UNDER_LINKING |WIFI_UNDER_WPS | WIFI_UNDER_KEY_HANDSHAKE (mlme state:0x%x)\n", + ADPT_ARG(iface), get_fwstate(&iface->mlmepriv)); + rst = _TRUE; + break; + } + #ifdef CONFIG_AP_MODE + if (MLME_IS_AP(iface) || MLME_IS_MESH(iface)) { + if (rtw_ap_sta_states_check(iface) == _TRUE) { + rst = _TRUE; + break; + } + } + #endif + } + } + + return rst; +} + +static int rtw_ro_ch_handler(_adapter *adapter, u8 *buf) +{ + int ret = H2C_SUCCESS; + struct rtw_roch_parm *roch_parm = (struct rtw_roch_parm *)buf; + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); + struct roch_info *prochinfo = &adapter->rochinfo; +#ifdef CONFIG_CONCURRENT_MODE + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; +#endif + u8 ready_on_channel = _FALSE; + u8 remain_ch; + unsigned int duration; + + _enter_critical_mutex(&pwdev_priv->roch_mutex, NULL); + + if (rtw_cfg80211_get_is_roch(adapter) != _TRUE) + goto exit; + + remain_ch = (u8)ieee80211_frequency_to_channel(roch_parm->ch.center_freq); + duration = roch_parm->duration; + + RTW_INFO(FUNC_ADPT_FMT" ch:%u duration:%d, cookie:0x%llx\n" + , FUNC_ADPT_ARG(adapter), remain_ch, roch_parm->duration, roch_parm->cookie); + + if (roch_parm->wdev && roch_parm->cookie) { + if (prochinfo->ro_ch_wdev != roch_parm->wdev) { + RTW_WARN(FUNC_ADPT_FMT" ongoing wdev:%p, wdev:%p\n" + , FUNC_ADPT_ARG(adapter), prochinfo->ro_ch_wdev, roch_parm->wdev); + rtw_warn_on(1); + } + + if (prochinfo->remain_on_ch_cookie != roch_parm->cookie) { + RTW_WARN(FUNC_ADPT_FMT" ongoing cookie:0x%llx, cookie:0x%llx\n" + , FUNC_ADPT_ARG(adapter), prochinfo->remain_on_ch_cookie, roch_parm->cookie); + rtw_warn_on(1); + } + } + + if (rtw_roch_stay_in_cur_chan(adapter) == _TRUE) { + remain_ch = rtw_mi_get_union_chan(adapter); + RTW_INFO(FUNC_ADPT_FMT" stay in union ch:%d\n", FUNC_ADPT_ARG(adapter), remain_ch); + } + + #ifdef CONFIG_CONCURRENT_MODE + if (rtw_mi_check_status(adapter, MI_LINKED) && (0 != rtw_mi_get_union_chan(adapter))) { + if ((remain_ch != rtw_mi_get_union_chan(adapter)) && !check_fwstate(&adapter->mlmepriv, WIFI_ASOC_STATE)) { + if (remain_ch != pmlmeext->cur_channel + #ifdef RTW_ROCH_BACK_OP + || ATOMIC_READ(&pwdev_priv->switch_ch_to) == 1 + #endif + ) { + rtw_leave_opch(adapter); + + #ifdef RTW_ROCH_BACK_OP + RTW_INFO("%s, set switch ch timer, duration=%d\n", __func__, prochinfo->max_away_dur); + ATOMIC_SET(&pwdev_priv->switch_ch_to, 0); + /* remain_ch is not same as union channel. duration is max_away_dur to + * back to AP's channel. + */ + _set_timer(&prochinfo->ap_roch_ch_switch_timer, prochinfo->max_away_dur); + #endif + } + } + ready_on_channel = _TRUE; + } else + #endif /* CONFIG_CONCURRENT_MODE */ + { + if (remain_ch != rtw_get_oper_ch(adapter)) + ready_on_channel = _TRUE; + } + + if (ready_on_channel == _TRUE) { + #ifndef RTW_SINGLE_WIPHY + if (!check_fwstate(&adapter->mlmepriv, WIFI_ASOC_STATE)) + #endif + { + #ifdef CONFIG_CONCURRENT_MODE + if (rtw_get_oper_ch(adapter) != remain_ch) + #endif + { + /* if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic) */ + set_channel_bwmode(adapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + } + } + } + + #ifdef CONFIG_BT_COEXIST + rtw_btcoex_ScanNotify(adapter, _TRUE); + #endif + + RTW_INFO("%s, set ro ch timer, duration=%d\n", __func__, duration); + _set_timer(&prochinfo->remain_on_ch_timer, duration); + +exit: + _exit_critical_mutex(&pwdev_priv->roch_mutex, NULL); + + return ret; +} + +static int rtw_cancel_ro_ch_handler(_adapter *padapter, u8 *buf) +{ + int ret = H2C_SUCCESS; + struct rtw_roch_parm *roch_parm = (struct rtw_roch_parm *)buf; + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); + struct roch_info *prochinfo = &padapter->rochinfo; + struct wireless_dev *wdev; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +#endif + u8 ch, bw, offset; + + _enter_critical_mutex(&pwdev_priv->roch_mutex, NULL); + + if (rtw_cfg80211_get_is_roch(padapter) != _TRUE) + goto exit; + + if (roch_parm->wdev && roch_parm->cookie) { + if (prochinfo->ro_ch_wdev != roch_parm->wdev) { + RTW_WARN(FUNC_ADPT_FMT" ongoing wdev:%p, wdev:%p\n" + , FUNC_ADPT_ARG(padapter), prochinfo->ro_ch_wdev, roch_parm->wdev); + rtw_warn_on(1); + } + + if (prochinfo->remain_on_ch_cookie != roch_parm->cookie) { + RTW_WARN(FUNC_ADPT_FMT" ongoing cookie:0x%llx, cookie:0x%llx\n" + , FUNC_ADPT_ARG(padapter), prochinfo->remain_on_ch_cookie, roch_parm->cookie); + rtw_warn_on(1); + } + } + +#if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) + _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer); + ATOMIC_SET(&pwdev_priv->switch_ch_to, 1); +#endif + + if (rtw_mi_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { + if (0) + RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); +#ifdef CONFIG_P2P + } else if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->listen_channel) { + ch = pwdinfo->listen_channel; + bw = CHANNEL_WIDTH_20; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + if (0) + RTW_INFO(FUNC_ADPT_FMT" back to listen ch - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); +#endif + } else { + ch = prochinfo->restore_channel; + bw = CHANNEL_WIDTH_20; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + if (0) + RTW_INFO(FUNC_ADPT_FMT" back to restore ch - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + } + + set_channel_bwmode(padapter, ch, offset, bw); + rtw_back_opch(padapter); +#ifdef CONFIG_P2P + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); +#ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo)); +#endif +#endif + + wdev = prochinfo->ro_ch_wdev; + + rtw_cfg80211_set_is_roch(padapter, _FALSE); + prochinfo->ro_ch_wdev = NULL; + rtw_cfg80211_set_last_ro_ch_time(padapter); + + rtw_cfg80211_remain_on_channel_expired(wdev + , prochinfo->remain_on_ch_cookie + , &prochinfo->remain_on_ch_channel + , prochinfo->remain_on_ch_type, GFP_KERNEL); + + RTW_INFO("cfg80211_remain_on_channel_expired cookie:0x%llx\n" + , prochinfo->remain_on_ch_cookie); + +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_ScanNotify(padapter, _FALSE); +#endif + +exit: + _exit_critical_mutex(&pwdev_priv->roch_mutex, NULL); + + return ret; +} + +static void rtw_ro_ch_timer_process(void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + + rtw_cancel_roch_cmd(adapter, 0, NULL, 0); +} +#endif /* CONFIG_IOCTL_CFG80211 */ + +#if (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) +s32 rtw_roch_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf) +{ + int ret = H2C_SUCCESS; + + switch (intCmdType) { + +#ifdef CONFIG_IOCTL_CFG80211 + case ROCH_RO_CH_WK: + ret = rtw_ro_ch_handler(padapter, buf); + break; + case ROCH_CANCEL_RO_CH_WK: + ret = rtw_cancel_ro_ch_handler(padapter, buf); + break; +#endif + +#ifdef CONFIG_CONCURRENT_MODE + case ROCH_AP_ROCH_CH_SWITCH_PROCESS_WK: + rtw_concurrent_handler(padapter); + break; +#endif + + default: + rtw_warn_on(1); + break; + } + + return ret; +} + +static int get_roch_parm_size(struct rtw_roch_parm *roch_parm) +{ +#ifdef CONFIG_IOCTL_CFG80211 + return (roch_parm ? sizeof(*roch_parm) : 0); +#else + rtw_warn_on(roch_parm); + return 0; +#endif +} + +u8 rtw_roch_wk_cmd(_adapter *padapter, int intCmdType, struct rtw_roch_parm *roch_parm, u8 flags) +{ + struct cmd_obj *ph2c = NULL; + struct drvextra_cmd_parm *pdrvextra_cmd_parm = NULL; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + struct submit_ctx sctx; + u8 res = _SUCCESS; + + if (flags & RTW_CMDF_DIRECTLY) { + /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ + if (H2C_SUCCESS != rtw_roch_wk_hdl(padapter, intCmdType, (u8 *)roch_parm)) + res = _FAIL; + goto free_parm; + } else { + ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (!ph2c) { + res = _FAIL; + goto free_parm; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if (!pdrvextra_cmd_parm) { + res = _FAIL; + goto free_parm; + } + + pdrvextra_cmd_parm->ec_id = ROCH_WK_CID; + pdrvextra_cmd_parm->type = intCmdType; + pdrvextra_cmd_parm->size = get_roch_parm_size(roch_parm); + pdrvextra_cmd_parm->pbuf = (u8 *)roch_parm; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, CMD_SET_DRV_EXTRA); + + if (flags & RTW_CMDF_WAIT_ACK) { + ph2c->sctx = &sctx; + rtw_sctx_init(&sctx, 10 * 1000); + } + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + + if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { + rtw_sctx_wait(&sctx, __func__); + _enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + if (sctx.status == RTW_SCTX_SUBMITTED) + ph2c->sctx = NULL; + _exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + if (sctx.status != RTW_SCTX_DONE_SUCCESS) + res = _FAIL; + } + } + + return res; + +free_parm: + if (roch_parm) + rtw_mfree((u8 *)roch_parm, get_roch_parm_size(roch_parm)); + if (ph2c) + rtw_mfree((u8 *)ph2c, sizeof(*ph2c)); + + return res; +} + +#ifdef CONFIG_CONCURRENT_MODE +void rtw_ap_roch_ch_switch_timer_process(void *ctx) +{ + _adapter *adapter = (_adapter *)ctx; +#ifdef CONFIG_IOCTL_CFG80211 + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); +#endif + +#ifdef CONFIG_IOCTL_CFG80211 + ATOMIC_SET(&pwdev_priv->switch_ch_to, 1); +#endif + + rtw_roch_wk_cmd(adapter, ROCH_AP_ROCH_CH_SWITCH_PROCESS_WK, NULL, 0); +} + +static bool chk_need_stay_in_cur_chan(_adapter *padapter) +{ +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + + /* When CONFIG_FULL_CH_IN_P2P_HANDSHAKE is defined and the + * interface is in the P2P_STATE_GONEGO_OK state, do not let the + * interface switch to the listen channel, because the interface will + * switch to the OP channel after the GO negotiation is successful. + */ + if (padapter->registrypriv.full_ch_in_p2p_handshake == 1 && rtw_p2p_chk_state(pwdinfo , P2P_STATE_GONEGO_OK)) { + RTW_INFO("%s, No linked interface now, but go nego ok, do not back to listen channel\n", __func__); + return _TRUE; + } +#endif + + return _FALSE; +} + +static bool chk_driver_interface(_adapter *padapter, u8 driver_interface) +{ +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + + if (pwdinfo->driver_interface == driver_interface) + return _TRUE; +#elif defined(CONFIG_IOCTL_CFG80211) + if (driver_interface == DRIVER_CFG80211) + return _TRUE; +#endif + + return _FALSE; +} + +static u8 get_remain_ch(_adapter *padapter) +{ + struct roch_info *prochinfo = &padapter->rochinfo; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +#endif + u8 remain_ch; + +#ifdef CONFIG_P2P + remain_ch = pwdinfo->listen_channel; +#elif defined(CONFIG_IOCTL_CFG80211) + if (chk_driver_interface(padapter, DRIVER_CFG80211)) + remain_ch = ieee80211_frequency_to_channel(prochinfo->remain_on_ch_channel.center_freq); + else + rtw_warn_on(1); +#endif + + return remain_ch; +} + +void rtw_concurrent_handler(_adapter *padapter) +{ +#ifdef CONFIG_IOCTL_CFG80211 + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); +#endif + struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); + struct roch_info *prochinfo = &padapter->rochinfo; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + u8 val8; +#endif + u8 remain_ch = get_remain_ch(padapter); + +#ifdef CONFIG_IOCTL_CFG80211 + if (chk_driver_interface(padapter, DRIVER_CFG80211) + && !rtw_cfg80211_get_is_roch(padapter)) + return; +#endif + + if (rtw_mi_check_status(padapter, MI_LINKED)) { + u8 union_ch = rtw_mi_get_union_chan(padapter); + u8 union_bw = rtw_mi_get_union_bw(padapter); + u8 union_offset = rtw_mi_get_union_offset(padapter); + unsigned int duration; + + #ifdef CONFIG_P2P + pwdinfo->operating_channel = union_ch; + #endif + + if (chk_driver_interface(padapter, DRIVER_CFG80211)) { + #ifdef CONFIG_IOCTL_CFG80211 + _enter_critical_mutex(&pwdev_priv->roch_mutex, NULL); + + if (rtw_get_oper_ch(padapter) != union_ch) { + /* Current channel is not AP's channel - switching to AP's channel */ + RTW_INFO("%s, switch ch back to union=%u,%u, %u\n" + , __func__, union_ch, union_bw, union_offset); + set_channel_bwmode(padapter, union_ch, union_offset, union_bw); + rtw_back_opch(padapter); + + /* Now, the driver stays on AP's channel. We should stay on AP's + * channel for min_home_dur (duration) and next switch channel is + * listen channel. + */ + duration = prochinfo->min_home_dur; + } else { + /* Current channel is AP's channel - switching to listen channel */ + RTW_INFO("%s, switch ch to roch=%u\n" + , __func__, remain_ch); + rtw_leave_opch(padapter); + set_channel_bwmode(padapter, + remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + + /* Now, the driver stays on listen channel. We should stay on listen + * channel for max_away_dur (duration) and next switch channel is AP's + * channel. + */ + duration = prochinfo->max_away_dur; + } + + /* set channel switch timer */ + ATOMIC_SET(&pwdev_priv->switch_ch_to, 0); + _set_timer(&prochinfo->ap_roch_ch_switch_timer, duration); + RTW_INFO("%s, set switch ch timer, duration=%d\n", __func__, duration); + + _exit_critical_mutex(&pwdev_priv->roch_mutex, NULL); + #endif + } + #ifdef CONFIG_P2P + else if (chk_driver_interface(padapter, DRIVER_WEXT)) { + if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) { + /* Now, the driver stays on the AP's channel. */ + /* If the pwdinfo->ext_listen_period = 0, that means the P2P listen state is not available on listen channel. */ + if (pwdinfo->ext_listen_period > 0) { + RTW_INFO("[%s] P2P_STATE_IDLE, ext_listen_period = %d\n", __FUNCTION__, pwdinfo->ext_listen_period); + + if (union_ch != pwdinfo->listen_channel) { + rtw_leave_opch(padapter); + set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + } + + rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); + + if (!rtw_mi_check_mlmeinfo_state(padapter, WIFI_FW_AP_STATE)) { + val8 = 1; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + } + /* Todo: To check the value of pwdinfo->ext_listen_period is equal to 0 or not. */ + _set_timer(&prochinfo->ap_roch_ch_switch_timer, pwdinfo->ext_listen_period); + } + + } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) || + rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL) || + (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _FALSE) || + rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ)) { + /* Now, the driver is in the listen state of P2P mode. */ + RTW_INFO("[%s] P2P_STATE_IDLE, ext_listen_interval = %d\n", __FUNCTION__, pwdinfo->ext_listen_interval); + + /* Commented by Albert 2012/11/01 */ + /* If the AP's channel is the same as the listen channel, we should still be in the listen state */ + /* Other P2P device is still able to find this device out even this device is in the AP's channel. */ + /* So, configure this device to be able to receive the probe request frame and set it to listen state. */ + if (union_ch != pwdinfo->listen_channel) { + + set_channel_bwmode(padapter, union_ch, union_offset, union_bw); + if (!rtw_mi_check_status(padapter, MI_AP_MODE)) { + val8 = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + } + rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE); + rtw_back_opch(padapter); + } + + /* Todo: To check the value of pwdinfo->ext_listen_interval is equal to 0 or not. */ + _set_timer(&prochinfo->ap_roch_ch_switch_timer, pwdinfo->ext_listen_interval); + + } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK)) { + /* The driver had finished the P2P handshake successfully. */ + val8 = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + set_channel_bwmode(padapter, union_ch, union_offset, union_bw); + rtw_back_opch(padapter); + + } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) { + val8 = 1; + set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); + } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _TRUE) { + val8 = 1; + set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); + } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ) && pwdinfo->invitereq_info.benable == _TRUE) { + /* + val8 = 1; + set_channel_bwmode(padapter, , HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + */ + } + } + #endif /* CONFIG_P2P */ + } else if (!chk_need_stay_in_cur_chan(padapter)) { + set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + } +} +#endif /* CONFIG_CONCURRENT_MODE */ + +void rtw_init_roch_info(_adapter *padapter) +{ + struct roch_info *prochinfo = &padapter->rochinfo; + + _rtw_memset(prochinfo, 0x00, sizeof(struct roch_info)); + +#ifdef CONFIG_CONCURRENT_MODE + rtw_init_timer(&prochinfo->ap_roch_ch_switch_timer, padapter, rtw_ap_roch_ch_switch_timer_process, padapter); +#ifdef CONFIG_IOCTL_CFG80211 + prochinfo->min_home_dur = 1500; /* min duration for traffic, home_time */ + prochinfo->max_away_dur = 250; /* max acceptable away duration, home_away_time */ +#endif +#endif + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_init_timer(&prochinfo->remain_on_ch_timer, padapter, rtw_ro_ch_timer_process, padapter); +#endif +} +#endif /* (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) */ \ No newline at end of file diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rson.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rson.c index 93aed18ebb7d..dc2304529d45 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rson.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_rson.c @@ -286,7 +286,9 @@ void rtw_rson_do_disconnect(_adapter *padapter) pdvobj->rson_data.hopcnt = RTW_RSON_HC_NOTREADY; pdvobj->rson_data.connectible = RTW_RSON_DENYCONNECT; pdvobj->rson_data.loading = 0; + #ifdef CONFIG_AP_MODE rtw_mi_tx_beacon_hdl(padapter); + #endif #endif } @@ -312,7 +314,9 @@ void rtw_rson_join_done(_adapter *padapter) pdvobj->rson_data.hopcnt = rson_data.hopcnt + 1; pdvobj->rson_data.connectible = RTW_RSON_ALLOWCONNECT; pdvobj->rson_data.loading = 0; + #ifdef CONFIG_AP_MODE rtw_mi_tx_beacon_hdl(padapter); + #endif #endif } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_security.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_security.c index cc8383a2d947..4e549edf65eb 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_security.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_security.c @@ -2832,7 +2832,7 @@ u32 rtw_bip_verify(enum security_type gmcs, u16 pkt_len, ClearPwrMgt(BIP_AAD); ClearMData(BIP_AAD); /* conscruct AAD, copy address 1 to address 3 */ - _rtw_memcpy(BIP_AAD + 2, pwlanhdr->addr1, 18); + _rtw_memcpy(BIP_AAD + 2, GetAddr1Ptr((u8 *)pwlanhdr), 18); if (rtw_calculate_bip_mic(gmcs, whdr_pos, pkt_len, key, BIP_AAD, ori_len, mic) == _FAIL) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_sreset.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_sreset.c index b02d9b89084b..536a1998a6f1 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_sreset.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_sreset.c @@ -205,10 +205,14 @@ void sreset_restore_network_status(_adapter *padapter) if (check_fwstate(mlmepriv, WIFI_STATION_STATE)) { RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_STATION_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv)); sreset_restore_network_station(padapter); - } else if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) { + } +#ifdef CONFIG_AP_MODE + else if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) { RTW_INFO(FUNC_ADPT_FMT" %s\n", FUNC_ADPT_ARG(padapter), MLME_IS_AP(padapter) ? "AP" : "MESH"); rtw_ap_restore_network(padapter); - } else if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE)) + } +#endif + else if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE)) RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv)); else RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv)); @@ -299,7 +303,7 @@ void sreset_reset(_adapter *padapter) _ips_enter(padapter); _ips_leave(padapter); #endif -#ifdef CONFIG_CONCURRENT_MODE +#if defined(CONFIG_AP_MODE) && defined(CONFIG_CONCURRENT_MODE) rtw_mi_ap_info_restore(padapter); #endif rtw_mi_sreset_adapter_hdl(padapter, _TRUE);/*sreset_start_adapter*/ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_sta_mgt.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_sta_mgt.c index 3381fccb1331..379da79071f4 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_sta_mgt.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_sta_mgt.c @@ -204,7 +204,9 @@ void _rtw_init_stainfo(struct sta_info *psta) /* _rtw_init_listhead(&psta->wakeup_list); */ _rtw_init_queue(&psta->sleep_q); - +#ifdef CONFIG_RTW_MGMT_QUEUE + _rtw_init_queue(&psta->mgmt_sleep_q); +#endif _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv); _rtw_init_sta_recv_priv(&psta->sta_recvpriv); @@ -304,12 +306,11 @@ u32 _rtw_init_sta_priv(struct sta_priv *pstapriv) #endif pstapriv->max_num_sta = NUM_STA; -#endif - #if CONFIG_RTW_MACADDR_ACL for (i = 0; i < RTW_ACL_PERIOD_NUM; i++) rtw_macaddr_acl_init(adapter, i); #endif +#endif /* CONFIG_AP_MODE */ #if CONFIG_RTW_PRE_LINK_STA rtw_pre_link_sta_ctl_init(pstapriv); @@ -369,6 +370,9 @@ void _rtw_free_sta_xmit_priv_lock(struct sta_xmit_priv *psta_xmitpriv) _rtw_spinlock_free(&(psta_xmitpriv->bk_q.sta_pending.lock)); _rtw_spinlock_free(&(psta_xmitpriv->vi_q.sta_pending.lock)); _rtw_spinlock_free(&(psta_xmitpriv->vo_q.sta_pending.lock)); +#ifdef CONFIG_RTW_MGMT_QUEUE + _rtw_spinlock_free(&(psta_xmitpriv->mgmt_q.sta_pending.lock)); +#endif } static void _rtw_free_sta_recv_priv_lock(struct sta_recv_priv *psta_recvpriv) @@ -565,6 +569,8 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, const u8 *hwaddr) _rtw_memcpy(&psta->sta_recvpriv.bmc_tid_rxseq[i], &wRxSeqInitialValue, 2); _rtw_memset(&psta->sta_recvpriv.rxcache.iv[i], 0, sizeof(psta->sta_recvpriv.rxcache.iv[i])); } + _rtw_memcpy(&psta->sta_recvpriv.nonqos_bmc_rxseq,&wRxSeqInitialValue,2); + _rtw_memcpy(&psta->sta_recvpriv.nonqos_rxseq,&wRxSeqInitialValue,2); rtw_init_timer(&psta->addba_retry_timer, psta->padapter, addba_timer_hdl, psta); #ifdef CONFIG_IEEE80211W @@ -586,7 +592,6 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, const u8 *hwaddr) , FUNC_ADPT_ARG(pstapriv->padapter), i, preorder_ctrl->indicate_seq); #endif preorder_ctrl->wend_b = 0xffff; - /* preorder_ctrl->wsize_b = (NR_RECVBUFF-2); */ preorder_ctrl->wsize_b = 64;/* 64; */ preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID; @@ -645,7 +650,6 @@ u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) struct hw_xmit *phwxmit; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - int pending_qcnt[4]; u8 is_pre_link_sta = _FALSE; @@ -691,6 +695,11 @@ u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q); psta->sleepq_len = 0; +#ifdef CONFIG_RTW_MGMT_QUEUE + rtw_free_mgmt_xmitframe_queue(pxmitpriv, &psta->mgmt_sleep_q); + psta->mgmt_sleepq_len = 0; +#endif + /* vo */ /* _enter_critical_bh(&(pxmitpriv->vo_pending.lock), &irqL0); */ rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending); @@ -731,6 +740,15 @@ u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) pstaxmitpriv->bk_q.qcnt = 0; /* _exit_critical_bh(&(pxmitpriv->bk_pending.lock), &irqL0); */ +#ifdef CONFIG_RTW_MGMT_QUEUE + /* mgmt */ + rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->mgmt_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->mgmt_q.tx_pending)); + phwxmit = pxmitpriv->hwxmits + 4; + phwxmit->accnt -= pstaxmitpriv->mgmt_q.qcnt; + pstaxmitpriv->mgmt_q.qcnt = 0; +#endif + rtw_os_wake_queue_at_free_stainfo(padapter, pending_qcnt); _exit_critical_bh(&pxmitpriv->lock, &irqL0); @@ -836,9 +854,9 @@ u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) #endif /* CONFIG_NATIVEAP_MLME */ -#ifdef CONFIG_TX_MCAST2UNI +#if !defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && defined(CONFIG_80211N_HT) psta->under_exist_checking = 0; -#endif /* CONFIG_TX_MCAST2UNI */ +#endif #endif /* CONFIG_AP_MODE */ @@ -969,7 +987,6 @@ u32 rtw_init_bcmc_stainfo(_adapter *padapter) NDIS_802_11_MAC_ADDRESS bcast_addr = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; struct sta_priv *pstapriv = &padapter->stapriv; - /* _queue *pstapending = &padapter->xmitpriv.bm_pending; */ psta = rtw_alloc_stainfo(pstapriv, bcast_addr); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_swcrypto.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_swcrypto.c index 437e29d24476..2544600ba80f 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_swcrypto.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_swcrypto.c @@ -1,297 +1,297 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2017 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - *****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include - -/** - * rtw_ccmp_encrypt - - * @key: the temporal key - * @hdrlen: mac header length - * @frame: the frame including the mac header, pn and payload - * @plen: payload length, i.e., length of the plain text, without PN and MIC - */ -int _rtw_ccmp_encrypt(u8 *key, u32 key_len, uint hdrlen, u8 *frame, uint plen) -{ - u8 *enc = NULL; - size_t enc_len = 0; - - if (key_len == 16) { /* 128 bits */ - enc = ccmp_encrypt(key, - frame, - hdrlen + plen, - hdrlen, - (hdrlen == 26) ? (frame + hdrlen - 2) : NULL, - NULL, 0, &enc_len); - } else if (key_len == 32) { /* 256 bits */ - enc = ccmp_256_encrypt(key, - frame, - hdrlen + plen, - hdrlen, - (hdrlen == 26) ? (frame + hdrlen - 2) : NULL, - NULL, 0, &enc_len); - } - - if (enc == NULL) { - RTW_INFO("Failed to encrypt CCMP(%u) frame", key_len); - return _FAIL; - } - - /* Copy @enc back to @frame and free @enc */ - _rtw_memcpy(frame, enc, enc_len); - rtw_mfree(enc, enc_len + AES_BLOCK_SIZE); - - return _SUCCESS; -} - - -/** - * rtw_ccmp_decrypt - - * @key: the temporal key - * @hdrlen: length of the mac header - * @frame: the raw frame (@hdrlen + PN + enc_data + MIC) - * @plen: length of the frame (@hdrlen + PN + enc_data + MIC) - */ -int _rtw_ccmp_decrypt(u8 *key, u32 key_len, uint hdrlen, u8 *frame, - uint plen) -{ - u8 *plain = NULL; - size_t plain_len = 0; - const struct ieee80211_hdr *hdr; - - hdr = (const struct ieee80211_hdr *)frame; - - if (key_len == 16) { /* 128 bits */ - plain = ccmp_decrypt(key, - hdr, - frame + hdrlen, /* PN + enc_data + MIC */ - plen - hdrlen, /* PN + enc_data + MIC */ - &plain_len); - } else if (key_len == 32) { /* 256 bits */ - plain = ccmp_256_decrypt(key, - hdr, - frame + hdrlen, /* PN + enc_data + MIC */ - plen - hdrlen, /* PN + enc_data + MIC */ - &plain_len); - } - - if (plain == NULL) { - RTW_INFO("Failed to decrypt CCMP(%u) frame", key_len); - return _FAIL; - } - - /* Copy @plain back to @frame and free @plain */ - _rtw_memcpy(frame + hdrlen + 8, plain, plain_len); - rtw_mfree(plain, plen - hdrlen + AES_BLOCK_SIZE); - - RTW_DBG_DUMP("ccmp_decrypt(): decrypted frame\n", - frame, hdrlen + 8 + plen); - - return _SUCCESS; -} - - -#ifdef CONFIG_RTW_MESH_AEK -/* wrapper to ase_siv_encrypt and aes_siv_decrypt */ -int _aes_siv_encrypt(const u8 *key, size_t key_len, - const u8 *pw, size_t pwlen, - size_t num_elem, const u8 *addr[], const size_t *len, u8 *out) -{ - return aes_siv_encrypt(key, key_len, pw, pwlen, num_elem, addr, len, out); -} -int _aes_siv_decrypt(const u8 *key, size_t key_len, - const u8 *iv_crypt, size_t iv_c_len, - size_t num_elem, const u8 *addr[], const size_t *len, u8 *out) -{ - return aes_siv_decrypt(key, key_len, iv_crypt, iv_c_len, num_elem, addr, len, out); -} -#endif - - -/** - * _rtw_gcmp_encrypt - - * @key: the temporal key - * @hdrlen: mac header length - * @frame: the frame including the mac header, pn and payload - * @plen: payload length, i.e., length of the plain text, without PN and MIC - */ -int _rtw_gcmp_encrypt(u8 *key, u32 key_len, uint hdrlen, u8 *frame, uint plen) -{ - u8 *enc = NULL; - size_t enc_len = 0; - - enc = gcmp_encrypt(key, key_len, - frame, - hdrlen + plen, - hdrlen, - (hdrlen == 26) ? (frame + hdrlen - 2) : NULL, - NULL, 0, &enc_len); - if (enc == NULL) { - RTW_INFO("Failed to encrypt GCMP frame"); - return _FAIL; - } - - /* Copy @enc back to @frame and free @enc */ - _rtw_memcpy(frame, enc, enc_len); - rtw_mfree(enc, enc_len + AES_BLOCK_SIZE); - - return _SUCCESS; -} - - -/** - * _rtw_gcmp_decrypt - - * @key: the temporal key - * @hdrlen: length of the mac header - * @frame: the raw frame (@hdrlen + PN + enc_data + MIC) - * @plen: length of the frame (@hdrlen + PN + enc_data + MIC) - */ -int _rtw_gcmp_decrypt(u8 *key, u32 key_len, uint hdrlen, u8 *frame, uint plen) -{ - u8 *plain = NULL; - size_t plain_len = 0; - const struct ieee80211_hdr *hdr; - - hdr = (const struct ieee80211_hdr *)frame; - - plain = gcmp_decrypt(key, key_len, - hdr, - frame + hdrlen, /* PN + enc_data + MIC */ - plen - hdrlen, /* PN + enc_data + MIC */ - &plain_len); - - if (plain == NULL) { - RTW_INFO("Failed to decrypt GCMP(%u) frame", key_len); - return _FAIL; - } - - /* Copy @plain back to @frame and free @plain */ - _rtw_memcpy(frame + hdrlen + 8, plain, plain_len); - rtw_mfree(plain, plen - hdrlen + AES_BLOCK_SIZE); - - RTW_DBG_DUMP("gcmp_decipher(): decrypted frame\n", - frame, hdrlen + 8 + plen); - - return _SUCCESS; -} - - -#if defined(CONFIG_IEEE80211W) | defined(CONFIG_TDLS) -u8 _bip_ccmp_protect(const u8 *key, size_t key_len, - const u8 *data, size_t data_len, u8 *mic) -{ - u8 res = _SUCCESS; - - if (key_len == 16) { - if (omac1_aes_128(key, data, data_len, mic)) { - res = _FAIL; - RTW_ERR("%s : omac1_aes_128 fail!", __func__); - } - } else if (key_len == 32) { - if (omac1_aes_256(key, data, data_len, mic)) { - res = _FAIL; - RTW_ERR("%s : omac1_aes_256 fail!", __func__); - } - } else { - RTW_ERR("%s : key_len not match!", __func__); - res = _FAIL; - } - - return res; -} - - -u8 _bip_gcmp_protect(u8 *whdr_pos, size_t len, - const u8 *key, size_t key_len, - const u8 *data, size_t data_len, u8 *mic) -{ - u8 res = _SUCCESS; - u32 mic_len = 16; - u8 nonce[12], *npos; - const u8 *gcmp_ipn; - - gcmp_ipn = whdr_pos + len - mic_len - 6; - - /* Nonce: A2 | IPN */ - _rtw_memcpy(nonce, get_addr2_ptr(whdr_pos), ETH_ALEN); - npos = nonce + ETH_ALEN; - *npos++ = gcmp_ipn[5]; - *npos++ = gcmp_ipn[4]; - *npos++ = gcmp_ipn[3]; - *npos++ = gcmp_ipn[2]; - *npos++ = gcmp_ipn[1]; - *npos++ = gcmp_ipn[0]; - - if (aes_gmac(key, key_len, nonce, sizeof(nonce), - data, data_len, mic)) { - res = _FAIL; - RTW_ERR("%s : aes_gmac fail!", __func__); - } - - return res; -} -#endif /* CONFIG_IEEE80211W */ - - -#ifdef CONFIG_TDLS -void _tdls_generate_tpk(void *sta, const u8 *own_addr, const u8 *bssid) -{ - struct sta_info *psta = (struct sta_info *)sta; - u8 *SNonce = psta->SNonce; - u8 *ANonce = psta->ANonce; - - u8 key_input[SHA256_MAC_LEN]; - const u8 *nonce[2]; - size_t len[2]; - u8 data[3 * ETH_ALEN]; - - /* IEEE Std 802.11z-2010 8.5.9.1: - * TPK-Key-Input = SHA-256(min(SNonce, ANonce) || max(SNonce, ANonce)) - */ - len[0] = 32; - len[1] = 32; - if (_rtw_memcmp2(SNonce, ANonce, 32) < 0) { - nonce[0] = SNonce; - nonce[1] = ANonce; - } else { - nonce[0] = ANonce; - nonce[1] = SNonce; - } - - sha256_vector(2, nonce, len, key_input); - - /* - * TPK = KDF-Hash-Length(TPK-Key-Input, "TDLS PMK", - * min(MAC_I, MAC_R) || max(MAC_I, MAC_R) || BSSID) - */ - - if (_rtw_memcmp2(own_addr, psta->cmn.mac_addr, ETH_ALEN) < 0) { - _rtw_memcpy(data, own_addr, ETH_ALEN); - _rtw_memcpy(data + ETH_ALEN, psta->cmn.mac_addr, ETH_ALEN); - } else { - _rtw_memcpy(data, psta->cmn.mac_addr, ETH_ALEN); - _rtw_memcpy(data + ETH_ALEN, own_addr, ETH_ALEN); - } - - _rtw_memcpy(data + 2 * ETH_ALEN, bssid, ETH_ALEN); - - sha256_prf(key_input, SHA256_MAC_LEN, "TDLS PMK", data, sizeof(data), (u8 *)&psta->tpk, sizeof(psta->tpk)); -} -#endif /* CONFIG_TDLS */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +/** + * rtw_ccmp_encrypt - + * @key: the temporal key + * @hdrlen: mac header length + * @frame: the frame including the mac header, pn and payload + * @plen: payload length, i.e., length of the plain text, without PN and MIC + */ +int _rtw_ccmp_encrypt(u8 *key, u32 key_len, uint hdrlen, u8 *frame, uint plen) +{ + u8 *enc = NULL; + size_t enc_len = 0; + + if (key_len == 16) { /* 128 bits */ + enc = ccmp_encrypt(key, + frame, + hdrlen + plen, + hdrlen, + (hdrlen == 26) ? (frame + hdrlen - 2) : NULL, + NULL, 0, &enc_len); + } else if (key_len == 32) { /* 256 bits */ + enc = ccmp_256_encrypt(key, + frame, + hdrlen + plen, + hdrlen, + (hdrlen == 26) ? (frame + hdrlen - 2) : NULL, + NULL, 0, &enc_len); + } + + if (enc == NULL) { + RTW_INFO("Failed to encrypt CCMP(%u) frame", key_len); + return _FAIL; + } + + /* Copy @enc back to @frame and free @enc */ + _rtw_memcpy(frame, enc, enc_len); + rtw_mfree(enc, enc_len + AES_BLOCK_SIZE); + + return _SUCCESS; +} + + +/** + * rtw_ccmp_decrypt - + * @key: the temporal key + * @hdrlen: length of the mac header + * @frame: the raw frame (@hdrlen + PN + enc_data + MIC) + * @plen: length of the frame (@hdrlen + PN + enc_data + MIC) + */ +int _rtw_ccmp_decrypt(u8 *key, u32 key_len, uint hdrlen, u8 *frame, + uint plen) +{ + u8 *plain = NULL; + size_t plain_len = 0; + const struct ieee80211_hdr *hdr; + + hdr = (const struct ieee80211_hdr *)frame; + + if (key_len == 16) { /* 128 bits */ + plain = ccmp_decrypt(key, + hdr, + frame + hdrlen, /* PN + enc_data + MIC */ + plen - hdrlen, /* PN + enc_data + MIC */ + &plain_len); + } else if (key_len == 32) { /* 256 bits */ + plain = ccmp_256_decrypt(key, + hdr, + frame + hdrlen, /* PN + enc_data + MIC */ + plen - hdrlen, /* PN + enc_data + MIC */ + &plain_len); + } + + if (plain == NULL) { + RTW_INFO("Failed to decrypt CCMP(%u) frame", key_len); + return _FAIL; + } + + /* Copy @plain back to @frame and free @plain */ + _rtw_memcpy(frame + hdrlen + 8, plain, plain_len); + rtw_mfree(plain, plen - hdrlen + AES_BLOCK_SIZE); + + RTW_DBG_DUMP("ccmp_decrypt(): decrypted frame\n", + frame, hdrlen + 8 + plen); + + return _SUCCESS; +} + + +#ifdef CONFIG_RTW_MESH_AEK +/* wrapper to ase_siv_encrypt and aes_siv_decrypt */ +int _aes_siv_encrypt(const u8 *key, size_t key_len, + const u8 *pw, size_t pwlen, + size_t num_elem, const u8 *addr[], const size_t *len, u8 *out) +{ + return aes_siv_encrypt(key, key_len, pw, pwlen, num_elem, addr, len, out); +} +int _aes_siv_decrypt(const u8 *key, size_t key_len, + const u8 *iv_crypt, size_t iv_c_len, + size_t num_elem, const u8 *addr[], const size_t *len, u8 *out) +{ + return aes_siv_decrypt(key, key_len, iv_crypt, iv_c_len, num_elem, addr, len, out); +} +#endif + + +/** + * _rtw_gcmp_encrypt - + * @key: the temporal key + * @hdrlen: mac header length + * @frame: the frame including the mac header, pn and payload + * @plen: payload length, i.e., length of the plain text, without PN and MIC + */ +int _rtw_gcmp_encrypt(u8 *key, u32 key_len, uint hdrlen, u8 *frame, uint plen) +{ + u8 *enc = NULL; + size_t enc_len = 0; + + enc = gcmp_encrypt(key, key_len, + frame, + hdrlen + plen, + hdrlen, + (hdrlen == 26) ? (frame + hdrlen - 2) : NULL, + NULL, 0, &enc_len); + if (enc == NULL) { + RTW_INFO("Failed to encrypt GCMP frame"); + return _FAIL; + } + + /* Copy @enc back to @frame and free @enc */ + _rtw_memcpy(frame, enc, enc_len); + rtw_mfree(enc, enc_len + AES_BLOCK_SIZE); + + return _SUCCESS; +} + + +/** + * _rtw_gcmp_decrypt - + * @key: the temporal key + * @hdrlen: length of the mac header + * @frame: the raw frame (@hdrlen + PN + enc_data + MIC) + * @plen: length of the frame (@hdrlen + PN + enc_data + MIC) + */ +int _rtw_gcmp_decrypt(u8 *key, u32 key_len, uint hdrlen, u8 *frame, uint plen) +{ + u8 *plain = NULL; + size_t plain_len = 0; + const struct ieee80211_hdr *hdr; + + hdr = (const struct ieee80211_hdr *)frame; + + plain = gcmp_decrypt(key, key_len, + hdr, + frame + hdrlen, /* PN + enc_data + MIC */ + plen - hdrlen, /* PN + enc_data + MIC */ + &plain_len); + + if (plain == NULL) { + RTW_INFO("Failed to decrypt GCMP(%u) frame", key_len); + return _FAIL; + } + + /* Copy @plain back to @frame and free @plain */ + _rtw_memcpy(frame + hdrlen + 8, plain, plain_len); + rtw_mfree(plain, plen - hdrlen + AES_BLOCK_SIZE); + + RTW_DBG_DUMP("gcmp_decipher(): decrypted frame\n", + frame, hdrlen + 8 + plen); + + return _SUCCESS; +} + + +#if defined(CONFIG_IEEE80211W) | defined(CONFIG_TDLS) +u8 _bip_ccmp_protect(const u8 *key, size_t key_len, + const u8 *data, size_t data_len, u8 *mic) +{ + u8 res = _SUCCESS; + + if (key_len == 16) { + if (omac1_aes_128(key, data, data_len, mic)) { + res = _FAIL; + RTW_ERR("%s : omac1_aes_128 fail!", __func__); + } + } else if (key_len == 32) { + if (omac1_aes_256(key, data, data_len, mic)) { + res = _FAIL; + RTW_ERR("%s : omac1_aes_256 fail!", __func__); + } + } else { + RTW_ERR("%s : key_len not match!", __func__); + res = _FAIL; + } + + return res; +} + + +u8 _bip_gcmp_protect(u8 *whdr_pos, size_t len, + const u8 *key, size_t key_len, + const u8 *data, size_t data_len, u8 *mic) +{ + u8 res = _SUCCESS; + u32 mic_len = 16; + u8 nonce[12], *npos; + const u8 *gcmp_ipn; + + gcmp_ipn = whdr_pos + len - mic_len - 6; + + /* Nonce: A2 | IPN */ + _rtw_memcpy(nonce, get_addr2_ptr(whdr_pos), ETH_ALEN); + npos = nonce + ETH_ALEN; + *npos++ = gcmp_ipn[5]; + *npos++ = gcmp_ipn[4]; + *npos++ = gcmp_ipn[3]; + *npos++ = gcmp_ipn[2]; + *npos++ = gcmp_ipn[1]; + *npos++ = gcmp_ipn[0]; + + if (aes_gmac(key, key_len, nonce, sizeof(nonce), + data, data_len, mic)) { + res = _FAIL; + RTW_ERR("%s : aes_gmac fail!", __func__); + } + + return res; +} +#endif /* CONFIG_IEEE80211W */ + + +#ifdef CONFIG_TDLS +void _tdls_generate_tpk(void *sta, const u8 *own_addr, const u8 *bssid) +{ + struct sta_info *psta = (struct sta_info *)sta; + u8 *SNonce = psta->SNonce; + u8 *ANonce = psta->ANonce; + + u8 key_input[SHA256_MAC_LEN]; + const u8 *nonce[2]; + size_t len[2]; + u8 data[3 * ETH_ALEN]; + + /* IEEE Std 802.11z-2010 8.5.9.1: + * TPK-Key-Input = SHA-256(min(SNonce, ANonce) || max(SNonce, ANonce)) + */ + len[0] = 32; + len[1] = 32; + if (_rtw_memcmp2(SNonce, ANonce, 32) < 0) { + nonce[0] = SNonce; + nonce[1] = ANonce; + } else { + nonce[0] = ANonce; + nonce[1] = SNonce; + } + + sha256_vector(2, nonce, len, key_input); + + /* + * TPK = KDF-Hash-Length(TPK-Key-Input, "TDLS PMK", + * min(MAC_I, MAC_R) || max(MAC_I, MAC_R) || BSSID) + */ + + if (_rtw_memcmp2(own_addr, psta->cmn.mac_addr, ETH_ALEN) < 0) { + _rtw_memcpy(data, own_addr, ETH_ALEN); + _rtw_memcpy(data + ETH_ALEN, psta->cmn.mac_addr, ETH_ALEN); + } else { + _rtw_memcpy(data, psta->cmn.mac_addr, ETH_ALEN); + _rtw_memcpy(data + ETH_ALEN, own_addr, ETH_ALEN); + } + + _rtw_memcpy(data + 2 * ETH_ALEN, bssid, ETH_ALEN); + + sha256_prf(key_input, SHA256_MAC_LEN, "TDLS PMK", data, sizeof(data), (u8 *)&psta->tpk, sizeof(psta->tpk)); +} +#endif /* CONFIG_TDLS */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_tdls.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_tdls.c index f4ce72055bee..77cde4739ac4 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_tdls.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_tdls.c @@ -931,6 +931,7 @@ u8 *rtw_tdls_set_ch_sw(u8 *pframe, struct pkt_attrib *pattrib, struct sta_info * void rtw_tdls_set_ch_sw_oper_control(_adapter *padapter, u8 enable) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u8 bcn_early_case; if (enable == _TRUE) { #ifdef CONFIG_TDLS_CH_SW_V2 @@ -940,14 +941,18 @@ void rtw_tdls_set_ch_sw_oper_control(_adapter *padapter, u8 enable) #ifdef CONFIG_TDLS_CH_SW_BY_DRV pHalData->ch_switch_offload = _FALSE; #endif + bcn_early_case = TDLS_BCN_ERLY_ON; } - else + else { pHalData->ch_switch_offload = _FALSE; - + bcn_early_case = TDLS_BCN_ERLY_OFF; + } + if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) != enable) ATOMIC_SET(&padapter->tdlsinfo.chsw_info.chsw_on, enable); - rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_BCN_EARLY_C2H_RPT, &enable); + rtw_hal_set_hwreg(padapter, HW_VAR_BCN_EARLY_C2H_RPT, &enable); + rtw_hal_set_hwreg(padapter, HW_VAR_SET_DRV_ERLY_INT, &bcn_early_case); RTW_INFO("[TDLS] %s Bcn Early C2H Report\n", (enable == _TRUE) ? "Start" : "Stop"); } @@ -963,6 +968,7 @@ void rtw_tdls_ch_sw_back_to_base_chnl(_adapter *padapter) rtw_tdls_cmd(padapter, pchsw_info->addr, TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED); } +#ifndef CONFIG_TDLS_CH_SW_V2 static void rtw_tdls_chsw_oper_init(_adapter *padapter, u32 timeout_ms) { struct submit_ctx *chsw_sctx = &padapter->tdlsinfo.chsw_info.chsw_sctx; @@ -983,6 +989,7 @@ void rtw_tdls_chsw_oper_done(_adapter *padapter) rtw_sctx_done(&chsw_sctx); } +#endif s32 rtw_tdls_do_ch_sw(_adapter *padapter, struct sta_info *ptdls_sta, u8 chnl_type, u8 channel, u8 channel_offset, u16 bwmode, u16 ch_switch_time) { @@ -2591,6 +2598,7 @@ sint On_TDLS_Ch_Switch_Req(_adapter *padapter, union recv_frame *precv_frame, st j += (pIE->Length + 2); } +#ifndef CONFIG_TDLS_CH_SW_V2 rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk); if (take_care_iqk == _TRUE) { u8 central_chnl; @@ -2605,6 +2613,7 @@ sint On_TDLS_Ch_Switch_Req(_adapter *padapter, union recv_frame *precv_frame, st return _FAIL; } } +#endif /* cancel ch sw monitor timer for responder */ if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE)) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_vht.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_vht.c index ac0be780e04e..012ae50c6278 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_vht.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_vht.c @@ -33,6 +33,7 @@ const u8 _vht_sup_ch_width_set_to_bw_cap[] = { 0, }; +#ifdef CONFIG_RTW_DEBUG const char *const _vht_sup_ch_width_set_str[] = { "80MHz", "160MHz", @@ -105,40 +106,47 @@ void dump_vht_op_ie(void *sel, const u8 *ie, u32 ie_len) dump_vht_op_ie_content(sel, vht_op_ie + 2, vht_op_ielen); } +#endif /* 20/40/80, ShortGI, MCS Rate */ -const u16 VHT_MCS_DATA_RATE[3][2][30] = { +const u16 VHT_MCS_DATA_RATE[3][2][40] = { /* unit: 0.5M */ { { 13, 26, 39, 52, 78, 104, 117, 130, 156, 156, 26, 52, 78, 104, 156, 208, 234, 260, 312, 312, - 39, 78, 117, 156, 234, 312, 351, 390, 468, 520 + 39, 78, 117, 156, 234, 312, 351, 390, 468, 520, + 52, 104, 156, 208, 312, 416, 468, 520, 624, 624, }, /* Long GI, 20MHz */ { 14, 29, 43, 58, 87, 116, 130, 144, 173, 173, 29, 58, 87, 116, 173, 231, 260, 289, 347, 347, - 43, 87, 130, 173, 260, 347, 390, 433, 520, 578 + 43, 87, 130, 173, 260, 347, 390, 433, 520, 578, + 58, 116, 173, 231, 347, 462, 520, 578, 693, 693, } }, /* Short GI, 20MHz */ { { 27, 54, 81, 108, 162, 216, 243, 270, 324, 360, 54, 108, 162, 216, 324, 432, 486, 540, 648, 720, - 81, 162, 243, 324, 486, 648, 729, 810, 972, 1080 + 81, 162, 243, 324, 486, 648, 729, 810, 972, 1080, + 108, 216, 324, 432, 648, 864, 972, 1080, 1296, 1440, }, /* Long GI, 40MHz */ { 30, 60, 90, 120, 180, 240, 270, 300, 360, 400, 60, 120, 180, 240, 360, 480, 540, 600, 720, 800, - 90, 180, 270, 360, 540, 720, 810, 900, 1080, 1200 + 90, 180, 270, 360, 540, 720, 810, 900, 1080, 1200, + 120, 240, 360, 480, 720, 960, 1080, 1200, 1440, 1600, } }, /* Short GI, 40MHz */ { { - 59, 117, 176, 234, 351, 468, 527, 585, 702, 780, + 59, 117, 176, 234, 351, 468, 527, 585, 702, 780, 117, 234, 351, 468, 702, 936, 1053, 1170, 1404, 1560, - 176, 351, 527, 702, 1053, 1404, 1580, 1755, 2106, 2340 + 176, 351, 527, 702, 1053, 1404, 1580, 1755, 2106, 2340, + 234, 468, 702, 936, 1404, 1872, 2106, 2340, 2808, 3120, }, /* Long GI, 80MHz */ { 65, 130, 195, 260, 390, 520, 585, 650, 780, 867, 130, 260, 390, 520, 780, 1040, 1170, 1300, 1560, 1734, - 195, 390, 585, 780, 1170, 1560, 1755, 1950, 2340, 2600 + 195, 390, 585, 780, 1170, 1560, 1755, 1950, 2340, 2600, + 260, 520, 780, 1040, 1560, 2080, 2340, 2600, 3120, 3467, } } /* Short GI, 80MHz */ }; @@ -210,8 +218,8 @@ void rtw_vht_nss_to_mcsmap(u8 nss, u8 *target_mcs_map, u8 *cur_mcs_map) u16 rtw_vht_mcs_to_data_rate(u8 bw, u8 short_GI, u8 vht_mcs_rate) { - if (vht_mcs_rate > MGN_VHT3SS_MCS9) - vht_mcs_rate = MGN_VHT3SS_MCS9; + if (vht_mcs_rate > MGN_VHT4SS_MCS9) + vht_mcs_rate = MGN_VHT4SS_MCS9; /* RTW_INFO("bw=%d, short_GI=%d, ((vht_mcs_rate - MGN_VHT1SS_MCS0)&0x3f)=%d\n", bw, short_GI, ((vht_mcs_rate - MGN_VHT1SS_MCS0)&0x3f)); */ return VHT_MCS_DATA_RATE[bw][short_GI][((vht_mcs_rate - MGN_VHT1SS_MCS0) & 0x3f)]; } @@ -265,10 +273,13 @@ void rtw_vht_use_default_setting(_adapter *padapter) CLEAR_FLAGS(pvhtpriv->beamform_cap); #ifdef CONFIG_BEAMFORMING #ifdef RTW_BEAMFORMING_VERSION_2 +#ifdef CONFIG_CONCURRENT_MODE /* only enable beamforming in STA client mode */ - if (MLME_IS_STA(padapter) && !MLME_IS_GC(padapter) - && !MLME_IS_ADHOC(padapter) - && !MLME_IS_MESH(padapter)) + if (MLME_IS_STA(padapter) && !MLME_IS_GC(padapter)) +#else + if ((MLME_IS_AP(padapter) && !MLME_IS_GO(padapter)) || + (MLME_IS_STA(padapter) && !MLME_IS_GC(padapter))) +#endif #endif { rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, @@ -337,13 +348,13 @@ u64 rtw_vht_mcs_map_to_bitmap(u8 *mcs_map, u8 nss) switch (tmp) { case 2: - bitmap = bitmap | (0x03ff << j); + bitmap = bitmap | ((u64)0x03ff << j); break; case 1: - bitmap = bitmap | (0x01ff << j); + bitmap = bitmap | ((u64)0x01ff << j); break; case 0: - bitmap = bitmap | (0x00ff << j); + bitmap = bitmap | ((u64)0x00ff << j); break; default: break; @@ -990,9 +1001,9 @@ u32 rtw_restructure_vht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_le oper_bw = rtw_min(oper_bw, max_bw); /* try downgrage bw to fit in channel plan setting */ - while (!rtw_chset_is_chbw_valid(chset, oper_ch, oper_bw, oper_offset) + while (!rtw_chset_is_chbw_valid(chset, oper_ch, oper_bw, oper_offset, 1, 1) || (IS_DFS_SLAVE_WITH_RD(rfctl) - && !rtw_odm_dfs_domain_unknown(rfctl_to_dvobj(rfctl)) + && !rtw_rfctl_dfs_domain_unknown(rfctl) && rtw_chset_is_chbw_non_ocp(chset, oper_ch, oper_bw, oper_offset)) ) { oper_bw--; @@ -1004,8 +1015,8 @@ u32 rtw_restructure_vht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_le } } - rtw_warn_on(!rtw_chset_is_chbw_valid(chset, oper_ch, oper_bw, oper_offset)); - if (IS_DFS_SLAVE_WITH_RD(rfctl) && !rtw_odm_dfs_domain_unknown(rfctl_to_dvobj(rfctl))) + rtw_warn_on(!rtw_chset_is_chbw_valid(chset, oper_ch, oper_bw, oper_offset, 1, 1)); + if (IS_DFS_SLAVE_WITH_RD(rfctl) && !rtw_rfctl_dfs_domain_unknown(rfctl)) rtw_warn_on(rtw_chset_is_chbw_non_ocp(chset, oper_ch, oper_bw, oper_offset)); /* update VHT_OP_IE */ @@ -1058,6 +1069,7 @@ void VHTOnAssocRsp(_adapter *padapter) rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MAX_TIME, (u8 *)(&pvhtpriv->vht_highest_rate)); } +#ifdef CONFIG_AP_MODE void rtw_vht_ies_attach(_adapter *padapter, WLAN_BSSID_EX *pnetwork) { struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); @@ -1126,4 +1138,5 @@ void rtw_check_for_vht20(_adapter *adapter, u8 *ies, int ies_len) } } } +#endif /* CONFIG_AP_MODE */ #endif /* CONFIG_80211AC_VHT */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_wlan_util.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_wlan_util.c index 333fd5a99cfa..e162b0867dd3 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_wlan_util.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_wlan_util.c @@ -474,114 +474,6 @@ inline void rtw_set_oper_choffset(_adapter *adapter, u8 offset) adapter_to_dvobj(adapter)->oper_ch_offset = offset; } -u8 rtw_get_offset_by_chbw(u8 ch, u8 bw, u8 *r_offset) -{ - u8 valid = 1; - u8 offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - - if (bw == CHANNEL_WIDTH_20) - goto exit; - - if (bw >= CHANNEL_WIDTH_80 && ch <= 14) { - valid = 0; - goto exit; - } - - if (ch >= 1 && ch <= 4) - offset = HAL_PRIME_CHNL_OFFSET_LOWER; - else if (ch >= 5 && ch <= 9) { - if (*r_offset == HAL_PRIME_CHNL_OFFSET_LOWER || *r_offset == HAL_PRIME_CHNL_OFFSET_UPPER) - offset = *r_offset; /* both lower and upper is valid, obey input value */ - else - offset = HAL_PRIME_CHNL_OFFSET_UPPER; /* default use upper */ - } else if (ch >= 10 && ch <= 13) - offset = HAL_PRIME_CHNL_OFFSET_UPPER; - else if (ch == 14) { - valid = 0; /* ch14 doesn't support 40MHz bandwidth */ - goto exit; - } else if (ch >= 36 && ch <= 177) { - switch (ch) { - case 36: - case 44: - case 52: - case 60: - case 100: - case 108: - case 116: - case 124: - case 132: - case 140: - case 149: - case 157: - case 165: - case 173: - offset = HAL_PRIME_CHNL_OFFSET_LOWER; - break; - case 40: - case 48: - case 56: - case 64: - case 104: - case 112: - case 120: - case 128: - case 136: - case 144: - case 153: - case 161: - case 169: - case 177: - offset = HAL_PRIME_CHNL_OFFSET_UPPER; - break; - default: - valid = 0; - break; - } - } else - valid = 0; - -exit: - if (valid && r_offset) - *r_offset = offset; - return valid; -} - -u8 rtw_get_center_ch(u8 channel, u8 chnl_bw, u8 chnl_offset) -{ - u8 center_ch = channel; - - if (chnl_bw == CHANNEL_WIDTH_80) { - if (channel == 36 || channel == 40 || channel == 44 || channel == 48) - center_ch = 42; - else if (channel == 52 || channel == 56 || channel == 60 || channel == 64) - center_ch = 58; - else if (channel == 100 || channel == 104 || channel == 108 || channel == 112) - center_ch = 106; - else if (channel == 116 || channel == 120 || channel == 124 || channel == 128) - center_ch = 122; - else if (channel == 132 || channel == 136 || channel == 140 || channel == 144) - center_ch = 138; - else if (channel == 149 || channel == 153 || channel == 157 || channel == 161) - center_ch = 155; - else if (channel == 165 || channel == 169 || channel == 173 || channel == 177) - center_ch = 171; - else if (channel <= 14) - center_ch = 7; - } else if (chnl_bw == CHANNEL_WIDTH_40) { - if (chnl_offset == HAL_PRIME_CHNL_OFFSET_LOWER) - center_ch = channel + 2; - else - center_ch = channel - 2; - } else if (chnl_bw == CHANNEL_WIDTH_20 || - chnl_bw == CHANNEL_WIDTH_10 || - chnl_bw == CHANNEL_WIDTH_5) - center_ch = channel; - else - rtw_warn_on(1); - - return center_ch; -} - inline systime rtw_get_on_oper_ch_time(_adapter *adapter) { return adapter_to_dvobj(adapter)->on_oper_ch_time; @@ -1438,9 +1330,12 @@ void rtw_clean_hw_dk_cam(_adapter *adapter) { int i; - for (i = 0; i < 4; i++) - rtw_sec_clr_cam_ent(adapter, i); - /*_clear_cam_entry(adapter, i);*/ + for (i = 0; i < 4; i++) { + if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_WRITE_CAM_NEW_RULE)) + _clear_cam_entry(adapter, i); + else + rtw_sec_clr_cam_ent(adapter, i); + } } void flush_all_cam_entry(_adapter *padapter) @@ -1462,6 +1357,7 @@ void flush_all_cam_entry(_adapter *padapter) rtw_clearstakey_cmd(padapter, psta, _FALSE); } } else if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) { +#ifdef CONFIG_AP_MODE #ifndef SEC_DEFAULT_KEY_SEARCH int cam_id = -1; u8 *addr = adapter_mac_addr(padapter); @@ -1489,6 +1385,7 @@ void flush_all_cam_entry(_adapter *padapter) /* clear default key related key search setting */ rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_FALSE); #endif +#endif /* CONFIG_AP_MODE */ } #else /*NON CONFIG_CONCURRENT_MODE*/ @@ -1935,7 +1832,7 @@ void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) #ifdef CONFIG_80211N_HT unsigned int i; u8 max_AMPDU_len, min_MPDU_spacing; - u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, cur_beamform_cap = 0, tx_nss = 0; + u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, cur_beamform_cap = 0, rx_nss = 0; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -1986,9 +1883,9 @@ void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) for (i = 0; i < 16; i++) pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i]; - tx_nss = GET_HAL_TX_NSS(padapter); + rx_nss = GET_HAL_RX_NSS(padapter); - switch (tx_nss) { + switch (rx_nss) { case 1: set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R); break; @@ -2007,7 +1904,7 @@ void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_4R); break; default: - RTW_WARN("rf_type:%d or tx_nss:%u is not expected\n", GET_HAL_RFPATH(padapter), tx_nss); + RTW_WARN("rf_type:%d or rx_nss:%u is not expected\n", GET_HAL_RFPATH(padapter), rx_nss); } if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { @@ -2328,7 +2225,7 @@ int validate_beacon_len(u8 *pframe, u32 len) return _TRUE; } - +#ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT u8 support_rate_ranges[] = { IEEE80211_CCK_RATE_1MB, IEEE80211_CCK_RATE_2MB, @@ -2399,6 +2296,7 @@ bool rtw_validate_value(u16 EID, u8 *p, u16 len) }; return _TRUE; } +#endif /* CONFIG_CHECK_SPECIFIC_IE_CONTENT */ bool is_hidden_ssid(char *ssid, int len) { @@ -2644,6 +2542,7 @@ int rtw_update_bcn_keys_of_network(struct wlan_network *network) void rtw_dump_bcn_keys(void *sel, struct beacon_keys *recv_beacon) { +#if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG) u8 ssid[IW_ESSID_MAX_SIZE + 1]; _rtw_memcpy(ssid, recv_beacon->ssid, recv_beacon->ssid_len); @@ -2658,6 +2557,7 @@ void rtw_dump_bcn_keys(void *sel, struct beacon_keys *recv_beacon) RTW_PRINT_SEL(sel, "sec = %d, group = 0x%x, pair = 0x%x, akm = 0x%08x\n" , recv_beacon->encryp_protocol, recv_beacon->group_cipher , recv_beacon->pairwise_cipher, recv_beacon->akm); +#endif } void rtw_bcn_key_err_fix(struct beacon_keys *cur, struct beacon_keys *recv) @@ -2713,6 +2613,11 @@ int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len) struct beacon_keys *cur_beacon = &pmlmepriv->cur_beacon_keys; struct beacon_keys recv_beacon; int ret = 0; + u8 ifbmp_m = rtw_mi_get_ap_mesh_ifbmp(Adapter); + u8 ifbmp_s = rtw_mi_get_ld_sta_ifbmp(Adapter); + struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter); + _adapter *pri_adapter = dvobj_get_primary_adapter(dvobj); + struct mlme_ext_priv *pmlmeext = &pri_adapter->mlmeextpriv; if (is_client_associated_to_ap(Adapter) == _FALSE) goto exit_success; @@ -2721,7 +2626,7 @@ int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len) goto exit_success; /* parsing failed => broken IE */ #ifdef DBG_RX_BCN - rtw_debug_bcn(Adapter, pframe, packet_len); + rtw_debug_rx_bcn(Adapter, pframe, packet_len); #endif /* hidden ssid, replace with current beacon ssid directly */ @@ -2730,6 +2635,69 @@ int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len) recv_beacon.ssid_len = cur_beacon->ssid_len; } + if (check_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON)) { + u8 u_ch, u_offset, u_bw; + struct sta_info *psta = NULL; + _rtw_memcpy(cur_beacon, &recv_beacon, sizeof(recv_beacon)); + clr_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON); + rtw_mi_get_ch_setting_union(Adapter, &u_ch, &u_bw, &u_offset); + + /* RTW_INFO("u_ch=%d, u_bw=%d, u_offset=%d \n", u_ch, u_bw, u_offset); + RTW_INFO("recv_beacon.ch=%d, recv_beacon.bw=%d, recv_beacon.offset=%d \n", recv_beacon.ch, recv_beacon.bw, recv_beacon.offset); */ + /* rtw_dump_bcn_keys(RTW_DBGDUMP, &recv_beacon); */ + + /* RTW_INFO("_cancel_timer_async csa_timer\n"); */ + _cancel_timer_async(&pmlmeext->csa_timer); + + /* beacon bw/offset is different from CSA IE */ + if((recv_beacon.bw > u_bw) || + ((recv_beacon.offset != HAL_PRIME_CHNL_OFFSET_DONT_CARE) && ((u_offset != HAL_PRIME_CHNL_OFFSET_DONT_CARE)) + && (recv_beacon.offset != u_offset))) { + + /* update ch, bw, offset for all asoc STA ifaces */ + if (ifbmp_s) { + _adapter *iface; + int i; + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (!iface || !(ifbmp_s & BIT(iface->iface_id))) + continue; + + iface->mlmeextpriv.cur_channel = recv_beacon.ch; + iface->mlmeextpriv.cur_bwmode = recv_beacon.bw; + iface->mlmeextpriv.cur_ch_offset = recv_beacon.offset; + iface->mlmepriv.cur_network.network.Configuration.DSConfig = recv_beacon.ch; + } + } + +#ifdef CONFIG_AP_MODE + if (ifbmp_m) { + rtw_change_bss_chbw_cmd(dvobj_get_primary_adapter(dvobj), 0 + , ifbmp_m, 0, recv_beacon.ch, REQ_BW_ORI, REQ_OFFSET_NONE); + } else +#endif + { + #ifdef CONFIG_DFS_MASTER + rtw_dfs_rd_en_decision(dvobj_get_primary_adapter(dvobj), MLME_OPCH_SWITCH, ifbmp_s); + #endif + rtw_set_chbw_cmd(Adapter, recv_beacon.ch, recv_beacon.bw, recv_beacon.offset, 0); + } + rtw_mi_get_ch_setting_union(Adapter, &u_ch, &u_bw, &u_offset); + + /* RTW_INFO("u_ch=%d, u_bw=%d, u_offset=%d \n", u_ch, u_bw, u_offset); */ + } else { + RTW_INFO("u_ch=%d, u_bw=%d, u_offset=%d, recv_beacon.ch=%d, recv_beacon.bw=%d, recv_beacon.offset=%d\n" + , u_ch, u_bw, u_offset, recv_beacon.ch, recv_beacon.bw, recv_beacon.offset); + } + + rtw_iqk_cmd(Adapter, 0); + psta = rtw_get_stainfo(&Adapter->stapriv, get_bssid(&Adapter->mlmepriv)); + if (psta) + rtw_dm_ra_mask_wk_cmd(Adapter, (u8 *)psta); + + } + #ifdef CONFIG_BCN_CNT_CONFIRM_HDL if (_rtw_memcmp(&recv_beacon, cur_beacon, sizeof(recv_beacon)) == _TRUE) pmlmepriv->new_beacon_cnts = 0; @@ -2840,9 +2808,11 @@ void update_beacon_info(_adapter *padapter, u8 *pframe, uint pkt_len, struct sta void process_csa_ie(_adapter *padapter, u8 *ies, uint ies_len) { struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); - unsigned int i; - PNDIS_802_11_VARIABLE_IEs pIE; - u8 ch = 0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + unsigned int i, j, countdown; + PNDIS_802_11_VARIABLE_IEs pIE, sub_pie; + u8 ch = 0, csa_ch_offset = 0, csa_ch_width = 0, csa_ch_freq_seg0 = 0, csa_ch_freq_seg1 = 0, csa_switch_cnt = 0; /* TODO: compare with scheduling CSA */ if (rfctl->csa_ch) @@ -2854,6 +2824,31 @@ void process_csa_ie(_adapter *padapter, u8 *ies, uint ies_len) switch (pIE->ElementID) { case _CH_SWTICH_ANNOUNCE_: ch = *(pIE->data + 1); + csa_switch_cnt = *(pIE->data + 2); + break; + case WLAN_EID_SECONDARY_CHANNEL_OFFSET: + csa_ch_offset = *(pIE->data); + break; + case WLAN_EID_WIDE_BANDWIDTH_CHANNEL_SWITCH: + csa_ch_width = *(pIE->data); + csa_ch_freq_seg0 = *(pIE->data+1); + csa_ch_freq_seg1 = *(pIE->data+2); + /* RTW_INFO("bw:%02x center_freq_0:%d center_freq_1:%d, ch=%d\n" + , csa_ch_width, csa_ch_freq_seg0, csa_ch_freq_seg1, ch); */ + break; + case WLAN_EID_CHANNEL_SWITCH_WRAPPER: + for(j=0; j + 1 < pIE->Length;) { + sub_pie = (PNDIS_802_11_VARIABLE_IEs)(ies + i + j + 2); + if(sub_pie->ElementID == WLAN_EID_WIDE_BANDWIDTH_CHANNEL_SWITCH) { + csa_ch_width = *(sub_pie->data); + csa_ch_freq_seg0 = *(sub_pie->data+1); + csa_ch_freq_seg1 = *(sub_pie->data+2); + /* RTW_INFO("2. sub_IE:%02x IE_length:%02x bw:%02x center_freq_0:%d center_freq_1:%d, ch=%d\n" + , sub_pie->ElementID, sub_pie->Length, csa_ch_width, csa_ch_freq_seg0, csa_ch_freq_seg1, ch); */ + } + j += (sub_pie->Length + 2); + } + break; default: break; @@ -2863,32 +2858,44 @@ void process_csa_ie(_adapter *padapter, u8 *ies, uint ies_len) } if (ch != 0) { + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + _adapter *pri_adapter = dvobj_get_primary_adapter(dvobj); + rfctl->csa_ch = ch; - if (rtw_set_csa_cmd(padapter) != _SUCCESS) - rfctl->csa_ch = 0; + rfctl->csa_switch_cnt = csa_switch_cnt; + rfctl->csa_ch_offset = csa_ch_offset; + rfctl->csa_ch_width = csa_ch_width; + rfctl->csa_ch_freq_seg0 = csa_ch_freq_seg0; + rfctl->csa_ch_freq_seg1 = csa_ch_freq_seg1; + + countdown = pmlmeinfo->network.Configuration.BeaconPeriod * (csa_switch_cnt+1); /* ms */ + RTW_INFO("csa: set countdown timer to %d ms\n", countdown); + _set_timer(&pri_adapter->mlmeextpriv.csa_timer, countdown); + } } #endif /* CONFIG_DFS */ -void parsing_eapol_packet(_adapter *padapter, u8 *key_payload, struct sta_info *psta, u8 trx_type) +enum eap_type parsing_eapol_packet(_adapter *padapter, u8 *key_payload, struct sta_info *psta, u8 trx_type) { struct security_priv *psecuritypriv = &(padapter->securitypriv); struct ieee802_1x_hdr *hdr; struct wpa_eapol_key *key; u16 key_info, key_data_length; char *trx_msg = trx_type ? "send" : "recv"; + enum eap_type eapol_type; hdr = (struct ieee802_1x_hdr *) key_payload; /* WPS - eapol start packet */ if (hdr->type == 1 && hdr->length == 0) { RTW_INFO("%s eapol start packet\n", trx_msg); - return; + return EAPOL_START; } if (hdr->type == 0) { /* WPS - eapol packet */ RTW_INFO("%s eapol packet\n", trx_msg); - return; + return EAPOL_PACKET; } key = (struct wpa_eapol_key *) (hdr + 1); @@ -2898,24 +2905,32 @@ void parsing_eapol_packet(_adapter *padapter, u8 *key_payload, struct sta_info * if (!(key_info & WPA_KEY_INFO_KEY_TYPE)) { /* WPA group key handshake */ if (key_info & WPA_KEY_INFO_ACK) { RTW_PRINT("%s eapol packet - WPA Group Key 1/2\n", trx_msg); + eapol_type = EAPOL_WPA_GROUP_KEY_1_2; } else { RTW_PRINT("%s eapol packet - WPA Group Key 2/2\n", trx_msg); + eapol_type = EAPOL_WPA_GROUP_KEY_2_2; /* WPA key-handshake has completed */ if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK) psta->state &= (~WIFI_UNDER_KEY_HANDSHAKE); } } else if (key_info & WPA_KEY_INFO_MIC) { - if (key_data_length == 0) + if (key_data_length == 0) { RTW_PRINT("%s eapol packet 4/4\n", trx_msg); - else if (key_info & WPA_KEY_INFO_ACK) + eapol_type = EAPOL_4_4; + } else if (key_info & WPA_KEY_INFO_ACK) { RTW_PRINT("%s eapol packet 3/4\n", trx_msg); - else + eapol_type = EAPOL_3_4; + } else { RTW_PRINT("%s eapol packet 2/4\n", trx_msg); + eapol_type = EAPOL_2_4; + } } else { RTW_PRINT("%s eapol packet 1/4\n", trx_msg); + eapol_type = EAPOL_1_4; } + return eapol_type; } unsigned int is_ap_in_tkip(_adapter *padapter) @@ -4794,6 +4809,269 @@ void rtw_get_sec_iv(PADAPTER padapter, u8 *pcur_dot11txpn, u8 *StaAddr) pcur_dot11txpn[5], pcur_dot11txpn[6], pcur_dot11txpn[7]); } } + +#ifdef CONFIG_WAR_OFFLOAD +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) +void rtw_wow_war_mdns_dump_buf(struct seq_file *m, u8 *title, u8 *buf, u32 len) +{ + u32 i; + + RTW_PRINT_SEL(m, "\t%s (%d)\n\t\t", title, len); + for (i = 1; i <= len; i++) + { + RTW_PRINT_SEL(m, "%2.2x-", *(buf + i - 1)); + if( (i%16 == 0) && (len != i) ) RTW_PRINT_SEL(m, "\n\t\t"); + } + RTW_PRINT_SEL(m, "\n\n"); +} + +void rtw_wow_war_mdns_dump_txt(struct seq_file *m, u8 *title, u8 *buf, u32 len) +{ + u16 idx=1, offset=0; /* offset = the location of L in the Length.Value */ + + RTW_PRINT_SEL(m, "\t%s (%d)\n\t", title, len); + for (; offset < len; idx++) + { + int item_len = buf[offset]; + u8 item_buf[256]={0}; + + _rtw_memcpy(item_buf, (buf + offset + 1), item_len); + RTW_PRINT_SEL(m, "\t[%d] => %s (%d)\n\t", idx, item_buf, item_len); + _rtw_memset(item_buf, 0, sizeof(item_buf)); + offset += (1+item_len); + } + RTW_PRINT_SEL(m, "\n\n"); +} + +bool rtw_wow_war_mdns_parser_pattern(u8 *input, char *target, + u32 *target_len, u32 type) +{ + char *cp = NULL, *end = NULL; + size_t len = 0; + int pos = 0, mask_pos = 0, res = 0; + u8 member[2] = {0}; + + /* reset */ + _rtw_memset(target, '\0', type); + (*target_len) = 0; + + cp = strchr(input, '='); + if (cp) { + *cp = 0; + cp++; + input = cp; + } + + while (1) { + cp = strchr(input, ':'); + + if (cp) { + len = strlen(input) - strlen(cp); + *cp = 0; + cp++; + } else + len = 2; + + { + u8 hex,idx=0, pos_in_unit_as_4bit = 0; + + strncpy(member, input, len); + res = sscanf(member, "%02hhx", &hex); + + target[pos] = hex; + + /* RTW_INFO("==> in; input-member = %s, hex = %x, target[%d] = %x\n", member, hex, target[pos], pos); */ + + for(idx = 0; idx<2;idx++) + { + pos_in_unit_as_4bit = pos*2 + (1-idx); + mask_pos = (pos_in_unit_as_4bit /8); + + if(!IsHexDigit(member[idx])) + { + RTW_ERR("%s:[ERROR] pattern is invalid!!(%c)\n",__func__, member[idx]); + goto error; + } + + /* RTW_INFO("==> in; pos = %d, pos_in_unit_as_4bit = %d, mask-pos = %d \n", pos, pos_in_unit_as_4bit, mask_pos); + RTW_INFO("==> in; hex(0x%02x), member(%c%c) \n", pattern[pos], member[1], member[0]); */ + } + /* RTW_INFO_DUMP("Pattern Mask: ",bit_mask, 6); */ + } + + pos++; + if (!cp) + break; + input = cp; + } + + (*target_len) = pos; + + return _TRUE; +error: + return _FALSE; + +} + +static struct war_mdns_service_info default_sinfo[] = { +/* example of default setting */ + RTW_MDNS_SRV_INFO("_ipp", 4, "_tcp", 4, "local", 5, 0x02, 0x77, 7200, "KM1", 3, 0), + RTW_MDNS_SRV_INFO("_ipps", 5, "_tcp", 4, "local", 5, 0x02, 0x77, 7200, "KM2", 3, 0), + RTW_MDNS_SRV_INFO("_http", 5, "_tcp", 4, "local", 5, 0x00, 0x50, 7200, "KM3", 3, 2), + RTW_MDNS_SRV_INFO("_privet", 7, "_tcp", 4, "local", 5, 0x00, 0x50, 7200, "KM4", 3, 3), + RTW_MDNS_SRV_INFO("_https", 6, "_tcp", 4, "local", 5, 0x01, 0xbb, 7200, "KM5", 3, 2), + RTW_MDNS_SRV_INFO("_uscan", 6, "_tcp", 4, "local", 5, 0x1f, 0x91, 7200, "KM6", 3, 4), + RTW_MDNS_SRV_INFO("_printer", 8, "_tcp", 4, "local", 5, 0x23, 0x8c, 7200, "KM7", 3, 1), + RTW_MDNS_SRV_INFO("_pdl-datastream", 15, "_tcp", 4, "local", 5, 0x23, 0x8c, 7200, "KM8", 3, 1) + +}; + +void rtw_wow_war_mdns_parms_reset(_adapter *adapter, u8 is_set_default) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + u8 i =0; + u16 offset=0; + u8 default_domain_name[] = "Generic"; + //u8 default_machine_name[] = { 0x0a, 0x5f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x04, 0x5f, 0x73, 0x75, 0x62 }; + //u8 default_machine_name_len = 16; + u8 default_machine_name[] = { 0x0a, 0x5f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c}; /* length : 10 name : _universal */ + u8 default_machine_name_len = 11; + + /* set default txt value*/ + char *default_txt_rsp_0_for_serive[2] = { "_ipp", "_ipps" }; + char *default_txt_rsp_0[25] = { + "txtvers=1", "qtotal=1", "usb_MFG=KONICA MINOLTA", "usb_MDL=C754Series", + "rp=ipp/print","priority=54","tr=Generic 35c-4", "product=DriverName", + "pdl=application/postscript,image/urf,application/octet-stream,image/jpeg", + "adminurl=http://KM00D91C.local./wcd/a_network.xml", + "note=Copy Room", "Transparent=T", "Binary=T", "TBCP=T", + "URF=V1,4,w8,SRGB24,ADOBERGB24-48,DEVW8,DEVRGB24,DEVCMYK32,RS150000000,IS19-20-21,MT1-3,OB1,PQ4,DM1,FN3-14,CP255", + "rfo=ipp/faxout", "Fax=T", "Scan=T", "Duplex=T", "Color=T", "air=none", + "Kind=document,envelope,photo", + "PaperMax=tabloid-A3", "UUID=6c183832-69ba-541b-baf6-6d947c144325", "TLS=1.2" + }; + + char *default_txt_rsp_1_for_serive[2] = { "_printer", "_pdl-datastream" }; + char *default_txt_rsp_1[13] = { + "txtvers=1", "qtotal=1", "usb_MFG=KONICA MINOLTA", "usb_MDL=C754Series", + "rp=print","priority=51","tr=Generic 35c-4", "product=DriverName", + "pdl=application/postscript", "note=Copy Room", "Transparent=T", "Binary=T", "TBCP=F" + }; + + char *default_txt_rsp_2_for_serive[2] = { "_http", "_https" }; + char *default_txt_rsp_2[1] = { + "Path=/" + }; + + char *default_txt_rsp_3_for_serive[1] = { "_privet" }; + char *default_txt_rsp_3[5] = { + "txtvers=1", "url=https://www.google.com/cloudprint", + "type=printer", "cs=not-configured","note=Copy Room" + }; + + char *default_txt_rsp_4_for_serive[1] = { "_uscan" }; + char *default_txt_rsp_4[11] = { + "txtvers=1", "vers=2.5", "adminurl=http://KM00D91C.local./wsd/a_network_airprint.xml", + "representation=http://KM00D91C.local./wcd/DeviceIcon_1283png", + "rs=eSCL", "ty=KONICA MINOLTA bishub C287", "note=japan", + "pdl=image/jpeg,image/tiff,application/pdf", + "UUID=dd5454cc-e196-5711-aa1f-35be49a6ca9f", + "cs=color,grayscale,binary", "is=platen,adf,duplex=T" + }; + + + /* reset ===> */ + + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_domain_name, 0, MAX_MDNS_DOMAIN_NAME_LEN); + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_mnane, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_mnane)); + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_service, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_service)); + _rtw_memset(pwrpriv->wowlan_war_offload_mdns_txt_rsp, 0, sizeof(pwrpriv->wowlan_war_offload_mdns_txt_rsp)); + + pwrpriv->wowlan_war_offload_mdns_domain_name_len = 0; + pwrpriv->wowlan_war_offload_mdns_mnane_num = 0; + pwrpriv->wowlan_war_offload_mdns_service_info_num = 0; + pwrpriv->wowlan_war_offload_mdns_txt_rsp_num = 0; + pwrpriv->wowlan_war_offload_mdns_para_cur_size = 0; + pwrpriv->wowlan_war_offload_mdns_rsp_cur_size = 0; + + /* init ===> */ + + if(is_set_default) + { + // domain_name + pwrpriv->wowlan_war_offload_mdns_domain_name_len = strlen(default_domain_name); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_domain_name, default_domain_name, sizeof(default_domain_name)); + + // machine name + pwrpriv->wowlan_war_offload_mdns_mnane_num = 1; + pwrpriv->wowlan_war_offload_mdns_mnane[0].name_len = default_machine_name_len; + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_mnane[0].name, default_machine_name, default_machine_name_len); + + // service info + pwrpriv->wowlan_war_offload_mdns_service_info_num = 8; + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_service, default_sinfo, sizeof(default_sinfo)); + + // type txt rsp 0~5 + // 0 + for(offset=0, i=0; i<25; i++) + { + pwrpriv->wowlan_war_offload_mdns_txt_rsp[0].txt[offset++] = strlen(default_txt_rsp_0[i]); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[0].txt + offset, default_txt_rsp_0[i], strlen(default_txt_rsp_0[i])); + offset += strlen(default_txt_rsp_0[i]); + RTW_INFO("==> default_txt_rsp_0[%d]: [%s](%zu), offset(%d)\n", i, default_txt_rsp_0[i], strlen(default_txt_rsp_0[i]), offset); + } + pwrpriv->wowlan_war_offload_mdns_txt_rsp[0].txt_len = offset; + // RTW_INFO("==> offset = %d\n\n", offset); + + + // 1 + for(offset=0, i=0; i<13; i++) + { + pwrpriv->wowlan_war_offload_mdns_txt_rsp[1].txt[offset++] = strlen(default_txt_rsp_1[i]); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[1].txt + offset, default_txt_rsp_1[i], strlen(default_txt_rsp_1[i])); + offset += strlen(default_txt_rsp_1[i]); + } + pwrpriv->wowlan_war_offload_mdns_txt_rsp[1].txt_len = offset; + // RTW_INFO("==> offset = %d\n\n", offset); + + // 2 + for(offset=0, i=0; i<1; i++) + { + pwrpriv->wowlan_war_offload_mdns_txt_rsp[2].txt[offset++] = strlen(default_txt_rsp_2[i]); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[2].txt + offset, default_txt_rsp_2[i], strlen(default_txt_rsp_2[i])); + offset += strlen(default_txt_rsp_2[i]); + } + pwrpriv->wowlan_war_offload_mdns_txt_rsp[2].txt_len = offset; + // RTW_INFO("==> offset = %d\n\n", offset); + + // 3 + for(offset=0, i=0; i<5; i++) + { + pwrpriv->wowlan_war_offload_mdns_txt_rsp[3].txt[offset++] = strlen(default_txt_rsp_3[i]); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[3].txt + offset, default_txt_rsp_3[i], strlen(default_txt_rsp_3[i])); + offset += strlen(default_txt_rsp_3[i]); + } + pwrpriv->wowlan_war_offload_mdns_txt_rsp[3].txt_len = offset; + // RTW_INFO("==> offset = %d\n\n", offset); + + // 4 + for(offset=0, i=0; i<11; i++) + { + pwrpriv->wowlan_war_offload_mdns_txt_rsp[4].txt[offset++] = strlen(default_txt_rsp_4[i]); + _rtw_memcpy(pwrpriv->wowlan_war_offload_mdns_txt_rsp[4].txt + offset, default_txt_rsp_4[i], strlen(default_txt_rsp_4[i])); + offset += strlen(default_txt_rsp_4[i]); + } + pwrpriv->wowlan_war_offload_mdns_txt_rsp[4].txt_len = offset; + // RTW_INFO("==> offset = %d\n\n", offset); + + /* txt_rsp_num is always as MAX_MDNS_TXT_NUM because the input mechanism(new/append) makes the entities are not in order */ + pwrpriv->wowlan_war_offload_mdns_txt_rsp_num = MAX_MDNS_TXT_NUM; + } +} + + +#endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */ +#endif /* CONFIG_WAR_OFFLOAD */ #endif /* CONFIG_WOWLAN */ inline bool _rtw_wow_chk_cap(_adapter *adapter, u8 cap) @@ -5150,3 +5428,236 @@ inline void rtw_collect_bcn_info(_adapter *adapter) /*TODO get offset of bcn's timestamp*/ /*pmlmeext->bcn_timestamp;*/ } + +static u32 rtw_get_vht_bitrate(u8 mcs, u8 bw, u8 nss, u8 sgi) +{ + static const u32 base[4][10] = { + { 6500000, + 13000000, + 19500000, + 26000000, + 39000000, + 52000000, + 58500000, + 65000000, + 78000000, + /* not in the spec, but some devices use this: */ + 86500000, + }, + { 13500000, + 27000000, + 40500000, + 54000000, + 81000000, + 108000000, + 121500000, + 135000000, + 162000000, + 180000000, + }, + { 29300000, + 58500000, + 87800000, + 117000000, + 175500000, + 234000000, + 263300000, + 292500000, + 351000000, + 390000000, + }, + { 58500000, + 117000000, + 175500000, + 234000000, + 351000000, + 468000000, + 526500000, + 585000000, + 702000000, + 780000000, + }, + }; + u32 bitrate; + int bw_idx; + + if (mcs > 9) { + RTW_INFO("Invalid mcs = %d\n", mcs); + return 0; + } + + if (nss > 4 || nss < 1) { + RTW_INFO("Now only support nss = 1, 2, 3, 4\n"); + } + + switch (bw) { + case CHANNEL_WIDTH_160: + bw_idx = 3; + break; + case CHANNEL_WIDTH_80: + bw_idx = 2; + break; + case CHANNEL_WIDTH_40: + bw_idx = 1; + break; + case CHANNEL_WIDTH_20: + bw_idx = 0; + break; + default: + RTW_INFO("bw = %d currently not supported\n", bw); + return 0; + } + + bitrate = base[bw_idx][mcs]; + bitrate *= nss; + + if (sgi) + bitrate = (bitrate / 9) * 10; + + /* do NOT round down here */ + return (bitrate + 50000) / 100000; +} + +static u32 rtw_get_ht_bitrate(u8 mcs, u8 bw, u8 sgi) +{ + int modulation, streams, bitrate; + + /* the formula below does only work for MCS values smaller than 32 */ + if (mcs >= 32) { + RTW_INFO("Invalid mcs = %d\n", mcs); + return 0; + } + + if (bw > 1) { + RTW_INFO("Now HT only support bw = 0(20Mhz), 1(40Mhz)\n"); + return 0; + } + + modulation = mcs & 7; + streams = (mcs >> 3) + 1; + + bitrate = (bw == 1) ? 13500000 : 6500000; + + if (modulation < 4) + bitrate *= (modulation + 1); + else if (modulation == 4) + bitrate *= (modulation + 2); + else + bitrate *= (modulation + 3); + + bitrate *= streams; + + if (sgi) + bitrate = (bitrate / 9) * 10; + + return (bitrate + 50000) / 100000; +} + +/** + * @bw: 0(20Mhz), 1(40Mhz), 2(80Mhz), 3(160Mhz) + * @rate_idx: DESC_RATEXXXX & 0x7f + * @sgi: DESC_RATEXXXX >> 7 + * Returns: bitrate in 100kbps + */ +u32 rtw_desc_rate_to_bitrate(u8 bw, u8 rate_idx, u8 sgi) +{ + u32 bitrate; + + if (rate_idx <= DESC_RATE54M){ + u16 ofdm_rate[12] = {10, 20, 55, 110, + 60, 90, 120, 180, 240, 360, 480, 540}; + + bitrate = ofdm_rate[rate_idx]; + } else if ((DESC_RATEMCS0 <= rate_idx) && + (rate_idx <= DESC_RATEMCS31)) { + u8 mcs = rate_idx - DESC_RATEMCS0; + + bitrate = rtw_get_ht_bitrate(mcs, bw, sgi); + } else if ((DESC_RATEVHTSS1MCS0 <= rate_idx) && + (rate_idx <= DESC_RATEVHTSS4MCS9)) { + u8 mcs = (rate_idx - DESC_RATEVHTSS1MCS0) % 10; + u8 nss = ((rate_idx - DESC_RATEVHTSS1MCS0) / 10) + 1; + + bitrate = rtw_get_vht_bitrate(mcs, bw, nss, sgi); + } else { + /* TODO: 60Ghz */ + bitrate = 1; + } + + return bitrate; +} + +#ifdef CONFIG_RTW_MULTI_AP +u8 rtw_get_ch_utilization(_adapter *adapter) +{ + u16 clm = rtw_phydm_clm_ratio(adapter); + u16 nhm = rtw_phydm_nhm_ratio(adapter); + u16 ch_util; + + ch_util = clm / 3 + (2 * (nhm / 3)); + /* For Multi-AP, scaling 0-100 to 0-255 */ + ch_util = 255 * ch_util / 100; + + return (u8)ch_util; +} + +void rtw_ch_util_rpt(_adapter *adapter) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + _adapter *iface; + int i, j; + u8 i_rpts = 0; + u8 *ch_util; + u8 **bssid; + u8 threshold = GET_PRIMARY_ADAPTER(adapter)->ch_util_threshold; + u8 need_rpt = 0; + + if (threshold == 0) + return; + + ch_util = rtw_zmalloc(sizeof(u8) * dvobj->iface_nums); + if (!ch_util) + goto err_out; + bssid = (u8 **) rtw_zmalloc(sizeof(u8 *) * dvobj->iface_nums); + if (!bssid) + goto err_out1; + for (j = 0; j < dvobj->iface_nums; j++) { + *(bssid + j) = (u8 *) rtw_zmalloc(sizeof(u8) * ETH_ALEN); + if (!(*(bssid + j))) + goto err_out2; + } + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if ((iface) && MLME_IS_AP(iface)) { + *(ch_util + i_rpts) = rtw_get_ch_utilization(iface); + _rtw_memcpy(*(bssid + i_rpts), iface->mac_addr, ETH_ALEN); + + if (*(ch_util + i_rpts) > threshold) + need_rpt = 1; + + i_rpts++; + } + } + + if (need_rpt) + rtw_nlrtw_ch_util_rpt(adapter, i_rpts, ch_util, bssid); + + rtw_mfree(ch_util, sizeof(u8) * dvobj->iface_nums); + for (i = 0; i < dvobj->iface_nums; i++) + rtw_mfree(*(bssid + i), ETH_ALEN); + rtw_mfree(bssid, sizeof(u8 *) * dvobj->iface_nums); + + return; + +err_out2: + for (i = 0; i < j; i++) + rtw_mfree(*(bssid + i), sizeof(u8) * ETH_ALEN); + rtw_mfree(bssid, sizeof(sizeof(u8 *) * dvobj->iface_nums)); +err_out1: + rtw_mfree(ch_util, sizeof(u8) * dvobj->iface_nums); +err_out: + RTW_INFO("[%s] rtw_zmalloc fail\n", __func__); +} +#endif + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_wnm.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_wnm.c new file mode 100644 index 000000000000..ae51c9496854 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_wnm.c @@ -0,0 +1,1099 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#include +#include + +#ifndef RTW_WNM_DBG + #define RTW_WNM_DBG 0 +#endif +#if RTW_WNM_DBG + #define RTW_WNM_INFO(fmt, arg...) \ + RTW_INFO(fmt, arg) + #define RTW_WNM_DUMP(str, data, len) \ + RTW_INFO_DUMP(str, data, len) +#else + #define RTW_WNM_INFO(fmt, arg...) do {} while (0) + #define RTW_WNM_DUMP(str, data, len) do {} while (0) +#endif + +#ifdef CONFIG_RTW_WNM + +static u32 wnm_defualt_validity_time = 6000; +static u32 wnm_default_disassoc_time = 5000; +static u32 wnm_disassoc_wait_time = 500; + +/* for wifi test, need more validity time to wait scan done */ +static u32 wnm_ext_validity_time = 4000; + +static void rtw_wmn_btm_cache_update(_adapter *padapter, struct btm_req_hdr *phdr) +{ + struct btm_rpt_cache *pcache = &(padapter->mlmepriv.nb_info.btm_cache); + + pcache->dialog_token = phdr->dialog_token; + pcache->req_mode = phdr->req_mode; + pcache->disassoc_timer = le16_to_cpu(phdr->disassoc_timer); + + if (phdr->validity_interval > 0) + pcache->validity_interval = phdr->validity_interval; + + pcache->term_duration.id = phdr->term_duration.id; + pcache->term_duration.len = phdr->term_duration.len; + pcache->term_duration.tsf = le64_to_cpu(phdr->term_duration.tsf); + pcache->term_duration.duration = le16_to_cpu(phdr->term_duration.duration); + + RTW_WNM_INFO("%s: req_mode(0x%02x), disassoc_timer(0x%04x), " + "validity_interval(0x%02x %s), tsf(0x%llx), duration(0x%02x)\n", + __func__, pcache->req_mode, pcache->disassoc_timer, + pcache->validity_interval, (!phdr->validity_interval)?"default":"", + pcache->term_duration.tsf, + pcache->term_duration.duration); + + if (pcache->validity_interval > 0) { + pcache->validity_time = pcache->validity_interval * 100; + #ifdef CONFIG_RTW_MBO + if (rtw_mbo_wifi_logo_test(padapter)) + pcache->validity_time += wnm_ext_validity_time; + #endif + } + + if (pcache->disassoc_timer > 0) { + pcache->disassoc_time= pcache->disassoc_timer * 100; + #ifdef CONFIG_RTW_MBO + if (rtw_mbo_wifi_logo_test(padapter)) + pcache->disassoc_time += wnm_ext_validity_time; + #endif + } + + pcache->req_stime = rtw_get_current_time(); + + RTW_WNM_INFO("%s: validity_time=%u, disassoc_time=%u\n", + __func__, pcache->validity_time, pcache->disassoc_time); +} + +static u8 rtw_wnm_btm_candidate_validity(struct btm_rpt_cache *pcache, u8 flag) +{ + u8 is_validity =_TRUE; + u32 req_validity_time = rtw_get_passing_time_ms(pcache->req_stime); + + if ((flag & BIT(0)) && (req_validity_time > pcache->validity_time)) + is_validity = _FALSE; + + if ((flag & BIT(1)) && (req_validity_time > pcache->disassoc_time)) + is_validity = _FALSE; + + RTW_WNM_INFO("%s : validity=%u, rtime=%u, vtime=%u. dtime=%u\n", + __func__, is_validity, req_validity_time, + pcache->validity_time, pcache->disassoc_time); + return is_validity; +} + +u8 rtw_wmn_btm_rsp_reason_decision(_adapter *padapter, u8* req_mode) +{ + struct recv_priv *precvpriv = &padapter->recvpriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 reason = 0; + + if (!rtw_wnm_btm_diff_bss(padapter)) { + /* Reject - No suitable BSS transition candidates */ + reason = 7; + goto candidate_remove; + } + +#ifdef CONFIG_RTW_80211R + if (rtw_ft_chk_flags(padapter, RTW_FT_BTM_ROAM)) { + /* Accept */ + reason = 0; + goto under_survey; + } +#endif + + if (((*req_mode) & DISASSOC_IMMINENT) == 0) { + /* Reject - Unspecified reject reason */ + reason = 1; + goto candidate_remove; + } + + if (precvpriv->signal_strength_data.avg_val >= pmlmepriv->roam_rssi_threshold) { + reason = 1; + RTW_WNM_INFO("%s : Reject - under high roam rssi(%u, %u) \n", + __func__, precvpriv->signal_strength_data.avg_val, + pmlmepriv->roam_rssi_threshold); + goto candidate_remove; + } + +#ifdef CONFIG_RTW_80211R +under_survey: + if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)) { + RTW_WNM_INFO("%s reject due to _FW_UNDER_SURVEY\n", __func__); + reason = 1; + } +#endif + +candidate_remove: + if (reason !=0) + rtw_wnm_reset_btm_candidate(&pmlmepriv->nb_info); + + return reason; +} + +static u32 rtw_wnm_btm_candidates_offset_get(u8* pframe) +{ + u32 offset = 0; + + if (!pframe) + return 0; + + offset += 7; + + /* BSS Termination Duration check */ + if (wnm_btm_bss_term_inc(pframe)) + offset += 12; + + /* Session Information URL check*/ + if (wnm_btm_ess_disassoc_im(pframe)) { + /*URL length field + URL variable length*/ + offset = 1 + *(pframe + offset); + } + + RTW_WNM_INFO("%s : hdr offset=%u\n", __func__, offset); + return offset; +} + +static void rtw_wnm_btm_req_hdr_parsing(u8* pframe, struct btm_req_hdr *phdr) +{ + u8 *pos; + u32 offset = 0; + + if (!pframe || !phdr) + return; + + _rtw_memset(phdr, 0, sizeof(struct btm_req_hdr)); + phdr->dialog_token = wnm_btm_dialog_token(pframe); + phdr->req_mode = wnm_btm_req_mode(pframe); + phdr->disassoc_timer = wnm_btm_disassoc_timer(pframe); + phdr->validity_interval = wnm_btm_valid_interval(pframe); + if (wnm_btm_bss_term_inc(pframe)) { + pos = wnm_btm_term_duration_offset(pframe); + if (*pos == WNM_BTM_TERM_DUR_SUBEID) { + phdr->term_duration.id = *pos; + phdr->term_duration.len = *(pos + 1); + phdr->term_duration.tsf = *((u64*)(pos + 2)); + phdr->term_duration.duration= *((u16*)(pos + 10)); + } else + RTW_WNM_INFO("%s : invaild BSS Termination Duration content!\n", __func__); + } + + RTW_WNM_INFO("WNM: req_mode(0x%02x), disassoc_timer(0x%04x), validity_interval(0x%02x)\n", + phdr->req_mode, phdr->disassoc_timer, phdr->validity_interval); + if (wnm_btm_bss_term_inc(pframe)) + RTW_WNM_INFO("WNM: tsf(0x%llx), duration(0x%4x)\n", + phdr->term_duration.tsf, phdr->term_duration.duration); +} + +u8 rtw_wnm_btm_reassoc_req(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct roam_nb_info *pnb = &(pmlmepriv->nb_info); + u8 breassoc = _FALSE; + + if (_rtw_memcmp(get_my_bssid(&(pmlmeinfo->network)), + pnb->roam_target_addr, ETH_ALEN)) { + RTW_WNM_INFO("%s : bss "MAC_FMT" found in roam_target "MAC_FMT"\n", + __func__, MAC_ARG(get_my_bssid(&(pmlmeinfo->network))), + MAC_ARG(pnb->roam_target_addr)); + + breassoc = _TRUE; + } + + return breassoc; +} + +void rtw_wnm_roam_scan_hdl(void *ctx) +{ + _adapter *padapter = (_adapter *)ctx; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + if (rtw_is_scan_deny(padapter)) + RTW_WNM_INFO("%s: roam scan would abort by scan_deny!\n", __func__); + +#ifdef CONFIG_RTW_80211R + if (rtw_ft_chk_flags(padapter, RTW_FT_BTM_ROAM)) { + pmlmepriv->need_to_roam = _TRUE; + rtw_set_to_roam(padapter, padapter->registrypriv.max_roaming_times); + RTW_WNM_INFO("%s : enable roaming\n", __func__); + } + + rtw_drv_scan_by_self(padapter, RTW_AUTO_SCAN_REASON_ROAM); +#endif +} + +static void rtw_wnm_roam_scan(_adapter *padapter) +{ + struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); + + if (rtw_is_scan_deny(padapter)) { + _cancel_timer_ex(&pnb->roam_scan_timer); + _set_timer(&pnb->roam_scan_timer, 1000); + } else + rtw_wnm_roam_scan_hdl((void *)padapter); +} + +void rtw_wnm_disassoc_chk_hdl(void *ctx) +{ + _adapter *padapter = (_adapter *)ctx; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct roam_nb_info *pnb = &(pmlmepriv->nb_info); + + RTW_WNM_INFO("%s : expired\n", __func__); + if (pnb->disassoc_waiting <= 0 ) { + RTW_WNM_INFO("%s : btm roam is interrupted by disassoc\n", __func__); + return; + } + + pnb->disassoc_waiting = _FALSE; + rtw_wnm_roam_scan(padapter); +} + +u8 rtw_wnm_try_btm_roam_imnt(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct roam_nb_info *pnb = &(pmlmepriv->nb_info); + struct btm_rpt_cache *pcache = &(pnb->btm_cache); + u8 reason = 0, flag = 0; + + if (!rtw_wnm_btm_preference_cap(padapter)) { + RTW_WNM_INFO("%s : no btm candidate can be used!\n", __func__); + return 1; + } + + flag = BIT(0) | BIT(1); + if (!rtw_wnm_btm_candidate_validity(pcache, flag)) + return 1; + +#ifdef CONFIG_RTW_MBO + if (!rtw_mbo_wifi_logo_test(padapter) + && !(pcache->req_mode & DISASSOC_IMMINENT)) { + RTW_WNM_INFO("%s : non-disassoc imminet req\n", __func__); + return 1; + } +#endif + + RTW_WNM_INFO("%s : disassoc_waiting(%d)\n", __func__, pnb->disassoc_waiting); + if (pnb->disassoc_waiting) { + _cancel_timer_ex(&pnb->disassoc_chk_timer); + pnb->disassoc_waiting = _FALSE; + rtw_wnm_roam_scan_hdl((void *)padapter); + } else if (!pnb->disassoc_waiting) + RTW_WNM_INFO("%s : waiting for btm roaming start/finish\n", __func__); + else + reason = 1; + + return reason; +} + +void rtw_wnm_process_btm_req(_adapter *padapter, u8* pframe, u32 frame_len) +{ + struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); + struct btm_req_hdr req_hdr; + u8 *ptr, reason; + u32 elem_len, offset; + + rtw_wnm_btm_req_hdr_parsing(pframe, &req_hdr); + offset = rtw_wnm_btm_candidates_offset_get(pframe); + if (offset == 0) + return; + + if ((frame_len - offset) <= 15) { + RTW_INFO("WNM : Reject - no suitable BSS transition candidates!\n"); + rtw_wnm_issue_action(padapter, + RTW_WLAN_ACTION_WNM_BTM_RSP, 7, req_hdr.dialog_token); + return; + } + + rtw_wmn_btm_cache_update(padapter, &req_hdr); + + ptr = (pframe + offset); + elem_len = (frame_len - offset); + rtw_wnm_btm_candidates_survey(padapter, ptr, elem_len, _TRUE); + reason = rtw_wmn_btm_rsp_reason_decision(padapter, &pframe[3]); + +#ifdef CONFIG_RTW_MBO + /* for wifi-test; AP2 could power-off when BTM-req received */ + if ((reason > 0) && (rtw_mbo_wifi_logo_test(padapter))) { + _rtw_memcpy(pnb->roam_target_addr, pnb->nb_rpt[0].bssid, ETH_ALEN); + RTW_WNM_INFO("%s : used report 0 as roam_target_addr(reason=%u)\n", + __func__, reason); + reason = 0; + pnb->preference_en = _TRUE; + pnb->nb_rpt_valid = _FALSE; + } +#endif + + rtw_wnm_issue_action(padapter, + RTW_WLAN_ACTION_WNM_BTM_RSP, reason, req_hdr.dialog_token); + + if (reason == 0) { + pnb->disassoc_waiting = _TRUE; + _set_timer(&pnb->disassoc_chk_timer, wnm_disassoc_wait_time); + } + +} + +void rtw_wnm_reset_btm_candidate(struct roam_nb_info *pnb) +{ + pnb->preference_en = _FALSE; + _rtw_memset(pnb->roam_target_addr, 0, ETH_ALEN); +} + +void rtw_wnm_reset_btm_cache(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct roam_nb_info *pnb = &(pmlmepriv->nb_info); + struct btm_rpt_cache *pcache = &(pnb->btm_cache); + u8 flag = 0; + + flag |= BIT(0); + if (rtw_wnm_btm_candidate_validity(pcache, flag)) + return; + + rtw_wnm_reset_btm_candidate(pnb); + _rtw_memset(pcache, 0, sizeof(struct btm_rpt_cache)); + pcache->validity_time = wnm_defualt_validity_time; + pcache->disassoc_time= wnm_default_disassoc_time; + +#ifdef CONFIG_RTW_80211R + if (rtw_ft_chk_flags(padapter, RTW_FT_BTM_ROAM)) { + pmlmepriv->need_to_roam = _FALSE; + rtw_set_to_roam(padapter, 0); + RTW_WNM_INFO("%s : disabled roaming\n", __func__); + } +#endif +} + +void rtw_wnm_reset_btm_state(_adapter *padapter) +{ + struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); + + pnb->last_nb_rpt_entries = 0; + pnb->nb_rpt_is_same = _TRUE; + pnb->nb_rpt_valid = _FALSE; + pnb->nb_rpt_ch_list_num = 0; + pnb->disassoc_waiting = -1; + _rtw_memset(&pnb->nb_rpt, 0, sizeof(pnb->nb_rpt)); + _rtw_memset(&pnb->nb_rpt_ch_list, 0, sizeof(pnb->nb_rpt_ch_list)); + rtw_wnm_reset_btm_cache(padapter); +} + +u32 rtw_wnm_btm_rsp_candidates_sz_get( + _adapter *padapter, u8* pframe, u32 frame_len) +{ + u32 num = 0, sz = 0; + u8 status; + u8 *ptr; + + if (!pframe || (frame_len <= 5)) + goto exit; + + status = wnm_btm_rsp_status(pframe); + if (((status != 0) && (status != 6)) || (frame_len < 23)) + goto exit; + + if (status == 0) + num = (frame_len - 5 - ETH_ALEN)/18; + else + num = (frame_len - 5)/18; + sz = sizeof(struct wnm_btm_cant) * num; +exit: + RTW_WNM_INFO("WNM: %u candidates(sz=%u) in BTM rsp\n", num, sz); + return sz; +} + +void rtw_wnm_process_btm_rsp(_adapter *padapter, + u8* pframe, u32 frame_len, struct btm_rsp_hdr *prsp) +{ + prsp->dialog_token = wnm_btm_dialog_token(pframe); + prsp->status = wnm_btm_rsp_status(pframe); + prsp->termination_delay = wnm_btm_rsp_term_delay(pframe); + + if ((pframe == NULL) || (frame_len == 0)) + return; + + prsp->status = *(pframe + 3); + prsp->termination_delay = *(pframe + 4); + + /* no Target BSSID & Candidate in frame */ + if (frame_len <= 5) + return; + + /* accept */ + if ((prsp->status == 0) && (frame_len >= 11)) + _rtw_memcpy(prsp->bssid, (pframe + 5), ETH_ALEN); + + /* STA BSS Transition Candidate List provided, + and at least one NB report exist */ + if (((prsp->status == 0) || (prsp->status == 6)) && (frame_len >= 23)) { + struct wnm_btm_cant cant; + u8 *ptr, *pend; + u32 idx = 0; + + ptr = pframe + 5; + if (prsp->status == 0) + ptr += ETH_ALEN; + + pend = ptr + frame_len; + prsp->candidates_num = 0; + while (ptr < pend) { + if (*ptr != RTW_WLAN_ACTION_WNM_NB_RPT_ELEM) + break; + _rtw_memset(&cant, 0, sizeof(cant)); + cant.nb_rpt.id = *ptr; + cant.nb_rpt.len = *(ptr + 1); + _rtw_memcpy(cant.nb_rpt.bssid, (ptr + 2), ETH_ALEN); + cant.nb_rpt.bss_info = *((u32 *)(ptr + 8)); + cant.nb_rpt.reg_class = *(ptr + 12); + cant.nb_rpt.ch_num = *(ptr + 13); + cant.nb_rpt.phy_type= *(ptr + 14); + + if (*(ptr + 15) == WNM_BTM_CAND_PREF_SUBEID) + cant.preference = *(ptr + 17); + ptr = ptr + cant.nb_rpt.len + 2; + if (prsp->pcandidates) { + prsp->candidates_num++; + _rtw_memcpy((prsp->pcandidates + sizeof(cant) * idx), &cant, sizeof(cant)); + } + + idx++; + RTW_WNM_INFO("WNM: btm rsp candidate bssid("MAC_FMT + ") ,bss_info(0x%04X), reg_class(0x%02X), ch(%d)," + " phy_type(0x%02X), preference(0x%02X)\n", + MAC_ARG(cant.nb_rpt.bssid), cant.nb_rpt.bss_info, + cant.nb_rpt.reg_class, cant.nb_rpt.ch_num, + cant.nb_rpt.phy_type, cant.preference); + if ((prsp->pcandidates) && (prsp->candidates_num > 0)) + RTW_WNM_DUMP("WNM candidates: ", prsp->pcandidates, + (sizeof(struct wnm_btm_cant) * prsp->candidates_num)); + } + } + +} + +void rtw_wnm_hdr_init(_adapter *padapter, + struct xmit_frame *pactionframe, u8 *pmac, + u8 action, u8 **pcontent) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct pkt_attrib *pattrib; + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *pfctrl; + u8 category; + + pattrib = &(pactionframe->attrib); + update_mgntframe_attrib(padapter, pattrib); + _rtw_memset(pactionframe->buf_addr, 0, (WLANHDR_OFFSET + TXDESC_OFFSET)); + + *pcontent = (u8 *)(pactionframe->buf_addr + TXDESC_OFFSET); + pwlanhdr = (struct rtw_ieee80211_hdr *)(*pcontent); + pfctrl = &(pwlanhdr->frame_ctl); + *(pfctrl) = 0; + + _rtw_memcpy(pwlanhdr->addr1, pmac, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + set_frame_sub_type(*pcontent, WIFI_ACTION); + + *pcontent += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + category = RTW_WLAN_CATEGORY_WNM; + *pcontent = rtw_set_fixed_ie(*pcontent, 1, &(category), &(pattrib->pktlen)); + *pcontent = rtw_set_fixed_ie(*pcontent, 1, &(action), &(pattrib->pktlen)); +} + +void rtw_wnm_build_btm_req_ies(_adapter *padapter, + u8 **pframe, struct pkt_attrib *pattrib, + struct btm_req_hdr *phdr, u8 *purl, u32 url_len, + u8 *pcandidates, u8 candidate_cnt) +{ + int i; + + *pframe = rtw_set_fixed_ie(*pframe, 1, + &phdr->dialog_token, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 1, + &phdr->req_mode, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 2, + (u8 *)&phdr->disassoc_timer, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 1, + &phdr->validity_interval, &(pattrib->pktlen)); + + if (phdr->req_mode & BSS_TERMINATION_INCLUDED) { + *pframe = rtw_set_fixed_ie(*pframe, 1, + &phdr->term_duration.id, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 1, + &phdr->term_duration.len, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 8, + (u8 *)&phdr->term_duration.tsf, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 2, + (u8 *)&phdr->term_duration.duration, &(pattrib->pktlen)); + } + + if ((purl != NULL) && (url_len > 0) && + (phdr->req_mode & ESS_DISASSOC_IMMINENT)) { + *pframe = rtw_set_fixed_ie(*pframe, 1, + (u8 *)&url_len, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, + url_len, purl, &(pattrib->pktlen)); + } + + if ((pcandidates != NULL) && (candidate_cnt > 0)) { + for (i=0; inb_rpt); + + *pframe = rtw_set_fixed_ie(*pframe, 1, + &pcandidate->nb_rpt.id, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 1, + &pcandidate->nb_rpt.len, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, ETH_ALEN, + pcandidate->nb_rpt.bssid, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 4, + (u8 *)&pcandidate->nb_rpt.bss_info, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 1, + &pcandidate->nb_rpt.reg_class, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 1, + &pcandidate->nb_rpt.ch_num, &(pattrib->pktlen)); + *pframe = rtw_set_fixed_ie(*pframe, 1, + &pcandidate->nb_rpt.phy_type, &(pattrib->pktlen)); + *pframe = rtw_set_ie(*pframe, WNM_BTM_CAND_PREF_SUBEID, 1, + (u8 *)&pcandidate->preference, &(pattrib->pktlen)); + } + } + +} + +void rtw_wnm_issue_btm_req(_adapter *padapter, + u8 *pmac, struct btm_req_hdr *phdr, u8 *purl, u32 url_len, + u8 *pcandidates, u8 candidate_cnt) +{ + struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + u8 action, *pframe, dialog_token = 0; + + if (!pmac || is_zero_mac_addr(pmac) + || is_broadcast_mac_addr(pmac)) + return ; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + return ; + + rtw_wnm_hdr_init(padapter, pmgntframe, pmac, + RTW_WLAN_ACTION_WNM_BTM_REQ, &pframe); + + pattrib = &(pmgntframe->attrib); + rtw_wnm_build_btm_req_ies(padapter, &pframe, pattrib, + phdr, purl, url_len, pcandidates, candidate_cnt); + + if (0) { + u8 *__p = (u8 *)(pmgntframe->buf_addr + TXDESC_OFFSET); + RTW_WNM_DUMP("WNM BTM REQ :", __p, pattrib->pktlen); + } + + pattrib->last_txcmdsz = pattrib->pktlen; + dump_mgntframe(padapter, pmgntframe); + RTW_INFO("WNM: BSS Transition Management Request sent\n"); +} + +void rtw_wnm_issue_action(_adapter *padapter, + u8 action, u8 reason, u8 dialog) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct xmit_frame *pmgntframe; + struct rtw_ieee80211_hdr *pwlanhdr; + struct pkt_attrib *pattrib; + u8 category, termination_delay, *pframe, dialog_token = 0; +#ifdef CONFIG_RTW_MBO + u8 mbo_trans_rej_res = 1; /* Unspecified reason */ + u8 mbo_notif_req_type ; +#endif + u16 *fctrl; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + return ; + + pattrib = &(pmgntframe->attrib); + update_mgntframe_attrib(padapter, pattrib); + _rtw_memset(pmgntframe->buf_addr, 0, (WLANHDR_OFFSET + TXDESC_OFFSET)); + + pframe = (u8 *)(pmgntframe->buf_addr + TXDESC_OFFSET); + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + set_frame_sub_type(pframe, WIFI_ACTION); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + category = RTW_WLAN_CATEGORY_WNM; + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); + + switch (action) { + case RTW_WLAN_ACTION_WNM_BTM_QUERY: + dialog_token++; + pframe = rtw_set_fixed_ie(pframe, 1, &(dialog_token), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(reason), &(pattrib->pktlen)); + RTW_INFO("WNM: BSS Transition Management Query sent\n"); + break; + case RTW_WLAN_ACTION_WNM_BTM_RSP: + dialog_token = dialog; + termination_delay = 0; + pframe = rtw_set_fixed_ie(pframe, 1, &(dialog_token), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(reason), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(termination_delay), &(pattrib->pktlen)); + if (!reason && !is_zero_mac_addr(pmlmepriv->nb_info.roam_target_addr)) { + pframe = rtw_set_fixed_ie(pframe, 6, + pmlmepriv->nb_info.roam_target_addr, &(pattrib->pktlen)); + } + +#ifdef CONFIG_RTW_MBO + rtw_mbo_build_trans_reject_reason_attr(padapter, + &pframe, pattrib, &mbo_trans_rej_res); +#endif + + RTW_INFO("WNM: BSS Transition Management Response sent(reason:%d)\n", reason); + break; + case RTW_WLAN_ACTION_WNM_NOTIF_REQ: +#ifdef CONFIG_RTW_MBO + dialog_token++; + mbo_notif_req_type = WLAN_EID_VENDOR_SPECIFIC; + pframe = rtw_set_fixed_ie(pframe, 1, &(dialog_token), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(mbo_notif_req_type), &(pattrib->pktlen)); + rtw_mbo_build_wnm_notification(padapter, &pframe, pattrib); + RTW_INFO("WNM: Notification request sent\n"); +#endif + break; + default: + goto exit; + } + + pattrib->last_txcmdsz = pattrib->pktlen; + dump_mgntframe(padapter, pmgntframe); + +exit: + return; +} + +/* argument req_ie@cfg80211_roamed()/cfg80211_connect_result() + is association request IEs format. if driver used reassoc-req format, + RSN IE could not be parsed @supplicant process */ +void rtw_wnm_update_reassoc_req_ie(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u32 dup_len, offset; + u8 *pdup; + + if (!pmlmepriv->assoc_req || !pmlmepriv->assoc_req_len) + return; + + /* total len is assoc req len without Current AP Field*/ + dup_len = pmlmepriv->assoc_req_len - ETH_ALEN; + + /* offset is a len of 80211 header + capability(2B) + listen interval(2B) */ + offset = sizeof(struct rtw_ieee80211_hdr_3addr) + 4; + + pdup = rtw_zmalloc(dup_len); + if (pdup) { + /* remove Current AP Field @reassoc req IE */ + _rtw_memcpy(pdup, pmlmepriv->assoc_req, offset); + _rtw_memcpy(pdup + offset, pmlmepriv->assoc_req + offset + ETH_ALEN, + pmlmepriv->assoc_req_len - offset); + rtw_buf_update(&pmlmepriv->assoc_req, + &pmlmepriv->assoc_req_len, pdup, dup_len); + rtw_mfree(pdup, dup_len); + } +} +#endif /* CONFIG_RTW_WNM */ + +#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) +void rtw_roam_nb_info_init(_adapter *padapter) +{ + struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); + struct btm_rpt_cache *pcache = &(pnb->btm_cache); + + _rtw_memset(&pnb->nb_rpt, 0, sizeof(pnb->nb_rpt)); + _rtw_memset(&pnb->nb_rpt_ch_list, 0, sizeof(pnb->nb_rpt_ch_list)); + _rtw_memset(&pnb->roam_target_addr, 0, ETH_ALEN); + pnb->nb_rpt_valid = _FALSE; + pnb->nb_rpt_ch_list_num = 0; + pnb->preference_en = _FALSE; + pnb->nb_rpt_is_same = _TRUE; + pnb->last_nb_rpt_entries = 0; + pnb->disassoc_waiting = -1; +#ifdef CONFIG_RTW_WNM + pnb->features = 0; + /* pnb->features |= RTW_WNM_FEATURE_BTM_REQ_EN; */ + +#ifdef CONFIG_PLATFORM_CMAP_INTFS + pnb->features |= RTW_WNM_FEATURE_BTM_REQ_EN; +#endif + + rtw_init_timer(&pnb->roam_scan_timer, + padapter, rtw_wnm_roam_scan_hdl, + padapter); + rtw_init_timer(&pnb->disassoc_chk_timer, + padapter, rtw_wnm_disassoc_chk_hdl, + padapter); + + _rtw_memset(pcache, 0, sizeof(struct btm_rpt_cache)); + pcache->validity_time = wnm_defualt_validity_time; + pcache->disassoc_time= wnm_default_disassoc_time ; +#endif +} + +u8 rtw_roam_nb_scan_list_set( + _adapter *padapter, struct sitesurvey_parm *pparm) +{ + u8 ret = _FALSE; + u32 i; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct roam_nb_info *pnb = &(pmlmepriv->nb_info); + +#ifdef CONFIG_RTW_80211R + if (!rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE) + && !rtw_ft_chk_flags(padapter, RTW_FT_BTM_ROAM)) + return ret; +#endif + + if (!pmlmepriv->need_to_roam) + return ret; + + if ((!pmlmepriv->nb_info.nb_rpt_valid) || (!pnb->nb_rpt_ch_list_num)) + return ret; + + if (!pparm) + return ret; + + rtw_init_sitesurvey_parm(padapter, pparm); + if (rtw_roam_busy_scan(padapter, pnb)) { + pparm->ch_num = 1; + pparm->ch[pmlmepriv->ch_cnt].hw_value = + pnb->nb_rpt_ch_list[pmlmepriv->ch_cnt].hw_value; + pmlmepriv->ch_cnt++; + ret = _TRUE; + + RTW_WNM_INFO("%s: ch_cnt=%u, (%u)hw_value=%u\n", + __func__, pparm->ch_num, pmlmepriv->ch_cnt, + pparm->ch[pmlmepriv->ch_cnt].hw_value); + + if (pmlmepriv->ch_cnt == pnb->nb_rpt_ch_list_num) { + pmlmepriv->nb_info.nb_rpt_valid = _FALSE; + pmlmepriv->ch_cnt = 0; + } + goto set_bssid_list; + } + + pparm->ch_num = (pnb->nb_rpt_ch_list_num > RTW_CHANNEL_SCAN_AMOUNT)? + (RTW_CHANNEL_SCAN_AMOUNT):(pnb->nb_rpt_ch_list_num); + for (i=0; ich_num; i++) { + pparm->ch[i].hw_value = pnb->nb_rpt_ch_list[i].hw_value; + pparm->ch[i].flags = RTW_IEEE80211_CHAN_PASSIVE_SCAN; + } + + pmlmepriv->nb_info.nb_rpt_valid = _FALSE; + pmlmepriv->ch_cnt = 0; + ret = _TRUE; + +set_bssid_list: + rtw_set_802_11_bssid_list_scan(padapter, pparm); + return ret; +} + +static u8 rtw_wnm_nb_elem_parsing( + u8* pdata, u32 data_len, u8 from_btm, + u32 *nb_rpt_num, u8 *nb_rpt_is_same, + struct roam_nb_info *pnb, struct wnm_btm_cant *pcandidates) +{ + u8 bfound = _FALSE, ret = _SUCCESS; + u8 *ptr, *pend, *op; + u32 elem_len, subelem_len, op_len; + u32 i, nb_rpt_entries = 0; + struct nb_rpt_hdr *pie; + struct wnm_btm_cant *pcandidate; + + if ((!pdata) || (!pnb)) + return _FAIL; + + if ((from_btm) && (!pcandidates)) + return _FAIL; + + ptr = pdata; + pend = ptr + data_len; + elem_len = data_len; + subelem_len = (u32)*(pdata+1); + + for (i=0; i < RTW_MAX_NB_RPT_NUM; i++) { + if (((ptr + 7) > pend) || (elem_len < subelem_len)) + break; + + if (*ptr != RTW_WLAN_ACTION_WNM_NB_RPT_ELEM) { + RTW_WNM_INFO("WNM: end of data(0x%2x)!\n", *ptr); + break; + } + + pie = (struct nb_rpt_hdr *)ptr; + if (from_btm) { + op = rtw_get_ie((u8 *)(ptr+15), + WNM_BTM_CAND_PREF_SUBEID, + &op_len, (subelem_len - 15)); + } + + ptr = (u8 *)(ptr + subelem_len + 2); + elem_len -= (subelem_len +2); + subelem_len = *(ptr+1); + if (from_btm) { + pcandidate = (pcandidates + i); + _rtw_memcpy(&pcandidate->nb_rpt, pie, sizeof(struct nb_rpt_hdr)); + if (op && (op_len !=0)) { + pcandidate->preference = *(op + 2); + bfound = _TRUE; + } else + pcandidate->preference = 0; + + RTW_WNM_INFO("WNM: preference check bssid("MAC_FMT + ") ,bss_info(0x%04X), reg_class(0x%02X), ch(%d)," + " phy_type(0x%02X), preference(0x%02X)\n", + MAC_ARG(pcandidate->nb_rpt.bssid), pcandidate->nb_rpt.bss_info, + pcandidate->nb_rpt.reg_class, pcandidate->nb_rpt.ch_num, + pcandidate->nb_rpt.phy_type, pcandidate->preference); + } else { + if (_rtw_memcmp(&pnb->nb_rpt[i], pie, sizeof(struct nb_rpt_hdr)) == _FALSE) + *nb_rpt_is_same = _FALSE; + _rtw_memcpy(&pnb->nb_rpt[i], pie, sizeof(struct nb_rpt_hdr)); + } + nb_rpt_entries++; + } + + if (from_btm) + pnb->preference_en = (bfound)?_TRUE:_FALSE; + + *nb_rpt_num = nb_rpt_entries; + return ret; +} + +/* selection sorting based on preference value + * IN : nb_rpt_entries - candidate num + * IN/OUT : pcandidates - candidate list + * return : TRUE - means pcandidates is updated. + */ +static u8 rtw_wnm_candidates_sorting( + u32 nb_rpt_entries, struct wnm_btm_cant *pcandidates) +{ + u8 updated = _FALSE; + u32 i, j, pos; + struct wnm_btm_cant swap; + struct wnm_btm_cant *pcant_1, *pcant_2; + + if ((!nb_rpt_entries) || (!pcandidates)) + return updated; + + for (i=0; i < (nb_rpt_entries - 1); i++) { + pos = i; + for (j=(i + 1); j < nb_rpt_entries; j++) { + pcant_1 = pcandidates+pos; + pcant_2 = pcandidates+j; + if ((pcant_1->preference) < (pcant_2->preference)) + pos = j; + } + + if (pos != i) { + updated = _TRUE; + _rtw_memcpy(&swap, (pcandidates+i), sizeof(struct wnm_btm_cant)); + _rtw_memcpy((pcandidates+i), (pcandidates+pos), sizeof(struct wnm_btm_cant)); + _rtw_memcpy((pcandidates+pos), &swap, sizeof(struct wnm_btm_cant)); + } + } + return updated; +} + +static void rtw_wnm_nb_info_update( + u32 nb_rpt_entries, u8 from_btm, + struct roam_nb_info *pnb, struct wnm_btm_cant *pcandidates, + u8 *nb_rpt_is_same) +{ + u8 is_found; + u32 i, j; + struct wnm_btm_cant *pcand; + + if (!pnb) + return; + + pnb->nb_rpt_ch_list_num = 0; + for (i=0; inb_rpt[i], &pcand->nb_rpt, + sizeof(struct nb_rpt_hdr)) == _FALSE) + *nb_rpt_is_same = _FALSE; + _rtw_memcpy(&pnb->nb_rpt[i], &pcand->nb_rpt, sizeof(struct nb_rpt_hdr)); + } + + RTW_WNM_INFO("WNM: bssid(" MAC_FMT + ") , bss_info(0x%04X), reg_class(0x%02X), ch_num(%d), phy_type(0x%02X)\n", + MAC_ARG(pnb->nb_rpt[i].bssid), pnb->nb_rpt[i].bss_info, + pnb->nb_rpt[i].reg_class, pnb->nb_rpt[i].ch_num, + pnb->nb_rpt[i].phy_type); + + if (pnb->nb_rpt[i].ch_num == 0) + continue; + + for (j=0; jnb_rpt[i].ch_num == pnb->nb_rpt_ch_list[j].hw_value) { + is_found = _TRUE; + break; + } + } + + if (!is_found) { + pnb->nb_rpt_ch_list[pnb->nb_rpt_ch_list_num].hw_value = pnb->nb_rpt[i].ch_num; + pnb->nb_rpt_ch_list_num++; + } + } +} + +static void rtw_wnm_btm_candidate_select(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); + struct wlan_network *pnetwork; + u8 bfound = _FALSE; + u8 ignore_currrent = _FALSE; + u32 i; + +#ifdef CONFIG_RTW_80211R + if (rtw_ft_chk_flags(padapter, RTW_FT_BTM_ROAM)) + ignore_currrent = _TRUE; +#endif + + for (i = 0; i < pnb->last_nb_rpt_entries; i++) { + if (ignore_currrent && + (_rtw_memcmp(pnb->nb_rpt[i].bssid,\ + padapter->mlmepriv.cur_network.network.MacAddress, ETH_ALEN))) { + RTW_WNM_INFO("WNM : ignore candidate "MAC_FMT" for it's connected(%u)!\n", + MAC_ARG(pnb->nb_rpt[i].bssid), i); + continue; + } + + pnetwork = rtw_find_network( + &(pmlmepriv->scanned_queue), + pnb->nb_rpt[i].bssid); + + if (pnetwork) { + bfound = _TRUE; + break; + } + } + + if (bfound) { + _rtw_memcpy(pnb->roam_target_addr, pnb->nb_rpt[i].bssid, ETH_ALEN); + RTW_INFO("WNM : select btm entry(%d) - %s("MAC_FMT", ch:%u) rssi:%d\n" + , i + , pnetwork->network.Ssid.Ssid + , MAC_ARG(pnetwork->network.MacAddress) + , pnetwork->network.Configuration.DSConfig + , (int)pnetwork->network.Rssi); + } else + _rtw_memset(pnb->roam_target_addr,0, ETH_ALEN); +} + +u32 rtw_wnm_btm_candidates_survey( + _adapter *padapter, u8* pframe, u32 elem_len, u8 from_btm) +{ + struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info); + struct wnm_btm_cant *pcandidate_list = NULL; + u8 nb_rpt_is_same = _TRUE; + u32 ret = _FAIL; + u32 nb_rpt_entries = 0; + + if (from_btm) { + u32 mlen = sizeof(struct wnm_btm_cant) * RTW_MAX_NB_RPT_NUM; + pcandidate_list = (struct wnm_btm_cant *)rtw_malloc(mlen); + if (pcandidate_list == NULL) + goto exit; + } + + /*clean the status set last time*/ + _rtw_memset(&pnb->nb_rpt_ch_list, 0, sizeof(pnb->nb_rpt_ch_list)); + pnb->nb_rpt_valid = _FALSE; + if (!rtw_wnm_nb_elem_parsing( + pframe, elem_len, from_btm, + &nb_rpt_entries, &nb_rpt_is_same, + pnb, pcandidate_list)) + goto exit; + + if (nb_rpt_entries != 0) { + if ((from_btm) && (rtw_wnm_btm_preference_cap(padapter))) + rtw_wnm_candidates_sorting(nb_rpt_entries, pcandidate_list); + + rtw_wnm_nb_info_update( + nb_rpt_entries, from_btm, + pnb, pcandidate_list, &nb_rpt_is_same); + } + + RTW_WNM_INFO("nb_rpt_is_same = %d, nb_rpt_entries = %d, last_nb_rpt_entries = %d\n", + nb_rpt_is_same, nb_rpt_entries, pnb->last_nb_rpt_entries); + if ((nb_rpt_is_same == _TRUE) && (nb_rpt_entries == pnb->last_nb_rpt_entries)) + pnb->nb_rpt_is_same = _TRUE; + else { + pnb->nb_rpt_is_same = _FALSE; + pnb->last_nb_rpt_entries = nb_rpt_entries; + } + + if ((from_btm) && (nb_rpt_entries != 0)) + rtw_wnm_btm_candidate_select(padapter); + + pnb->nb_rpt_valid = _TRUE; + ret = _SUCCESS; + +exit: + if (from_btm && pcandidate_list) + rtw_mfree((u8 *)pcandidate_list, sizeof(struct wnm_btm_cant) * RTW_MAX_NB_RPT_NUM); + + return ret; +} + +#endif /*defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) */ + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_xmit.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_xmit.c index 0c13550991ef..d86d11838136 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_xmit.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/rtw_xmit.c @@ -44,6 +44,9 @@ void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv) _init_txservq(&psta_xmitpriv->bk_q); _init_txservq(&psta_xmitpriv->vi_q); _init_txservq(&psta_xmitpriv->vo_q); +#ifdef CONFIG_RTW_MGMT_QUEUE + _init_txservq(&psta_xmitpriv->mgmt_q); +#endif _rtw_init_listhead(&psta_xmitpriv->legacy_dz); _rtw_init_listhead(&psta_xmitpriv->apsd); @@ -93,7 +96,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, _adapter *padapter) _rtw_init_queue(&pxmitpriv->bk_pending); _rtw_init_queue(&pxmitpriv->vi_pending); _rtw_init_queue(&pxmitpriv->vo_pending); - _rtw_init_queue(&pxmitpriv->bm_pending); + _rtw_init_queue(&pxmitpriv->mgmt_pending); /* _rtw_init_queue(&pxmitpriv->legacy_dz_queue); */ /* _rtw_init_queue(&pxmitpriv->apsd_queue); */ @@ -363,7 +366,7 @@ void rtw_mfree_xmit_priv_lock(struct xmit_priv *pxmitpriv) _rtw_spinlock_free(&pxmitpriv->bk_pending.lock); _rtw_spinlock_free(&pxmitpriv->vi_pending.lock); _rtw_spinlock_free(&pxmitpriv->vo_pending.lock); - _rtw_spinlock_free(&pxmitpriv->bm_pending.lock); + _rtw_spinlock_free(&pxmitpriv->mgmt_pending.lock); /* _rtw_spinlock_free(&pxmitpriv->legacy_dz_queue.lock); */ /* _rtw_spinlock_free(&pxmitpriv->apsd_queue.lock); */ @@ -737,7 +740,7 @@ exit: return bw_bmp; } -s16 rtw_adapter_get_oper_txpwr_max_mbm(_adapter *adapter) +s16 rtw_adapter_get_oper_txpwr_max_mbm(_adapter *adapter, bool eirp) { s16 mbm = -100 * MBM_PDBM; @@ -772,20 +775,19 @@ s16 rtw_adapter_get_oper_txpwr_max_mbm(_adapter *adapter) bmp_vht |= BIT(hw_rate - DESC_RATEVHTSS1MCS0); mbm = phy_get_txpwr_total_max_mbm(adapter - , bw, cch, ch, bmp_cck_ofdm, bmp_ht, bmp_vht); + , bw, cch, ch, bmp_cck_ofdm, bmp_ht, bmp_vht, 0, eirp); } return mbm; } -s16 rtw_get_oper_txpwr_max_mbm(struct dvobj_priv *dvobj) +s16 rtw_rfctl_get_oper_txpwr_max_mbm(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, u8 ifbmp_mod, u8 if_op, bool eirp) { - struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); + struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl); _adapter *adapter = dvobj_get_primary_adapter(dvobj); s16 mbm = -100 * MBM_PDBM; - u8 ch, bw, offset; - if (rtw_mi_get_ch_setting_union(adapter, &ch, &bw, &offset)) { + if (ch) { u8 cch = rtw_get_center_ch(ch, bw, offset); u16 bmp_cck_ofdm = 0; u32 bmp_ht = 0; @@ -793,17 +795,27 @@ s16 rtw_get_oper_txpwr_max_mbm(struct dvobj_priv *dvobj) int i; for (i = 0; i < dvobj->iface_nums; i++) { - if (dvobj->padapters[i] && MLME_IS_ASOC(dvobj->padapters[i])) { - struct mlme_ext_priv *mlmeext = &(dvobj->padapters[i]->mlmeextpriv); - u8 hw_rate = MRateToHwRate(mlmeext->tx_rate); + struct mlme_ext_priv *mlmeext; + u8 hw_rate; - if (IS_LEGACY_HRATE(hw_rate)) - bmp_cck_ofdm |= BIT(hw_rate); - else if (IS_HT_HRATE(hw_rate)) - bmp_ht |= BIT(hw_rate - DESC_RATEMCS0); - else if (IS_VHT_HRATE(hw_rate)) - bmp_vht |= BIT(hw_rate - DESC_RATEVHTSS1MCS0); - } + if (!dvobj->padapters[i]) + continue; + + if (ifbmp_mod & BIT(i)) { + if (!if_op) + continue; + } else if (!MLME_IS_ASOC(dvobj->padapters[i])) + continue; + + mlmeext = &(dvobj->padapters[i]->mlmeextpriv); + hw_rate = MRateToHwRate(mlmeext->tx_rate); + + if (IS_LEGACY_HRATE(hw_rate)) + bmp_cck_ofdm |= BIT(hw_rate); + else if (IS_HT_HRATE(hw_rate)) + bmp_ht |= BIT(hw_rate - DESC_RATEMCS0); + else if (IS_VHT_HRATE(hw_rate)) + bmp_vht |= BIT(hw_rate - DESC_RATEVHTSS1MCS0); } bmp_cck_ofdm |= rfctl->rate_bmp_cck_ofdm; @@ -813,12 +825,92 @@ s16 rtw_get_oper_txpwr_max_mbm(struct dvobj_priv *dvobj) bmp_vht |= rfctl->rate_bmp_vht_by_bw[i]; mbm = phy_get_txpwr_total_max_mbm(adapter - , bw, cch, ch, bmp_cck_ofdm, bmp_ht, bmp_vht); + , bw, cch, ch, bmp_cck_ofdm, bmp_ht, bmp_vht, 0, eirp); } return mbm; } +s16 rtw_get_oper_txpwr_max_mbm(struct dvobj_priv *dvobj, bool eirp) +{ + struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); + _adapter *adapter = dvobj_get_primary_adapter(dvobj); + s16 mbm = -100 * MBM_PDBM; + u8 ch = rfctl->op_ch, bw, offset; + + if (rtw_get_bw_offset_by_op_class_ch(rfctl->op_class, ch, &bw, &offset)) + mbm = rtw_rfctl_get_oper_txpwr_max_mbm(rfctl, ch, bw, offset, 0, 0, eirp); + + return mbm; +} + +s16 rtw_rfctl_get_reg_max_txpwr_mbm(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, bool eirp) +{ + struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl); + struct registry_priv *regsty = dvobj_to_regsty(dvobj); + _adapter *adapter = dvobj_get_primary_adapter(dvobj); + s16 mbm = -100 * MBM_PDBM; + u8 cch = rtw_get_center_ch(ch, bw, offset); + u16 bmp_cck_ofdm = 0; + u32 bmp_ht = 0; + u64 bmp_vht = 0; + + if (ch <= 14) + bmp_cck_ofdm |= RATE_BMP_CCK; + + /* TODO: NO OFDM? */ + bmp_cck_ofdm |= RATE_BMP_OFDM; + +#ifdef CONFIG_80211N_HT + if (regsty->ht_enable && is_supported_ht(regsty->wireless_mode)) { + switch (GET_HAL_TX_NSS(adapter)) { + case 1: + bmp_ht |= RATE_BMP_HT_1SS; + break; + case 2: + bmp_ht |= RATE_BMP_HT_2SS | RATE_BMP_HT_1SS; + break; + case 3: + bmp_ht |= RATE_BMP_HT_3SS | RATE_BMP_HT_2SS | RATE_BMP_HT_1SS; + break; + case 4: + bmp_ht |= RATE_BMP_HT_4SS | RATE_BMP_HT_3SS | RATE_BMP_HT_2SS | RATE_BMP_HT_1SS; + break; + default: + rtw_warn_on(1); + } + } +#endif + +#ifdef CONFIG_80211AC_VHT + if (ch > 14 && REGSTY_IS_11AC_ENABLE(regsty) && is_supported_vht(regsty->wireless_mode) + && (!rfctl->country_ent || COUNTRY_CHPLAN_EN_11AC(rfctl->country_ent)) + ) { + switch (GET_HAL_TX_NSS(adapter)) { + case 1: + bmp_vht |= RATE_BMP_VHT_1SS; + break; + case 2: + bmp_vht |= RATE_BMP_VHT_2SS | RATE_BMP_VHT_1SS; + break; + case 3: + bmp_vht |= RATE_BMP_VHT_3SS | RATE_BMP_VHT_2SS | RATE_BMP_VHT_1SS; + break; + case 4: + bmp_vht |= RATE_BMP_VHT_4SS | RATE_BMP_VHT_3SS | RATE_BMP_VHT_2SS | RATE_BMP_VHT_1SS; + break; + default: + rtw_warn_on(1); + } + } +#endif + + mbm = phy_get_txpwr_total_max_mbm(adapter + , bw, cch, ch, bmp_cck_ofdm, bmp_ht, bmp_vht, 1, eirp); + + return mbm; +} + u8 query_ra_short_GI(struct sta_info *psta, u8 bw) { u8 sgi = _FALSE, sgi_20m = _FALSE, sgi_40m = _FALSE, sgi_80m = _FALSE; @@ -848,14 +940,45 @@ u8 query_ra_short_GI(struct sta_info *psta, u8 bw) return sgi; } +/* This function references driver insmond parameters to decide vcs mode. */ +/* Driver insmond parameters: rtw_vrtl_carrier_sense and rtw_vcs_type */ +static u8 validate_vcs(_adapter *padapter, u8 mode) { + + u8 vcs_mode = NONE_VCS; + + switch(padapter->registrypriv.vrtl_carrier_sense) { + + case DISABLE_VCS: + vcs_mode = NONE_VCS; + break; + + case ENABLE_VCS: + vcs_mode = padapter->registrypriv.vcs_type; + break; + + case AUTO_VCS: + vcs_mode = mode; + break; + + default: + vcs_mode = NONE_VCS; + break; + } + + return vcs_mode; + +} + static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitframe) { u32 sz; struct pkt_attrib *pattrib = &pxmitframe->attrib; - /* struct sta_info *psta = pattrib->psta; */ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - + #ifdef RTW_FORCE_CTS_TO_SELF_UNDER_LOW_RSSI + s8 rssi = 0; + struct sta_info *psta = pattrib->psta; + #endif /* if(pattrib->psta) { @@ -922,7 +1045,6 @@ static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitf break; } - /* check ERP protection */ if (pattrib->rtsen || pattrib->cts2self) { if (pattrib->rtsen) @@ -960,8 +1082,18 @@ static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitf pattrib->vcs_mode = NONE_VCS; break; } + #ifdef RTW_FORCE_CTS_TO_SELF_UNDER_LOW_RSSI + /*RTStoCTS while let TP degree ,while enable full BW*/ + if (psta != NULL) { + rssi = psta->cmn.rssi_stat.rssi; + if ((rssi < 18) && (pattrib->vcs_mode == RTS_CTS)) + pattrib->vcs_mode = CTS_TO_SELF; + } + #endif } + pattrib->vcs_mode = validate_vcs(padapter, pattrib->vcs_mode); + /* for debug : force driver control vrtl_carrier_sense. */ if (padapter->driver_vcs_en == 1) { /* u8 driver_vcs_en; */ /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */ @@ -1077,7 +1209,7 @@ static void update_attrib_phy_info(_adapter *padapter, struct pkt_attrib *pattri pattrib->retry_ctrl = _FALSE; } -static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta) +static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta, enum eap_type eapol_type) { sint res = _SUCCESS; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -1088,7 +1220,22 @@ static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib _rtw_memset(pattrib->dot11tkiptxmickey.skey, 0, 16); pattrib->mac_id = psta->cmn.mac_id; - if (psta->ieee8021x_blocked == _TRUE) { + /* Comment by Owen at 2020/05/19 + * Issue: RTK STA sends encrypted 4-way 4/4 when AP thinks the 4-way incomplete + * In TCL pressure test, AP may resend 4-way 3/4 with new replay counter in 2 ms. + * In this situation, STA sends unencrypted 4-way 4/4 with old replay counter after more + * than 2 ms, followed by the encrypted 4-way 4/4 with new replay counter. Because the + * AP only accepts unencrypted 4-way 4/4 with a new play counter, and the STA encrypts + * each 4-way 4/4 at this time, the 4-way handshake cannot be completed. + * So we modified that after STA receives unencrypted 4-way 1/4 and 4-way 3/4, + * 4-way 2/4 and 4-way 4/4 sent by STA in the next 100 ms are not encrypted. + */ + if (psta->ieee8021x_blocked == _TRUE || + ((eapol_type == EAPOL_2_4 || eapol_type == EAPOL_4_4) && + rtw_get_passing_time_ms(psta->resp_nonenc_eapol_key_starttime) <= 100)) { + + if (eapol_type == EAPOL_2_4 || eapol_type == EAPOL_4_4) + RTW_INFO("Respond unencrypted eapol key\n"); pattrib->encrypt = 0; @@ -1355,7 +1502,7 @@ static void set_qos(_pkt *pkt, struct pkt_attrib *pattrib) null_pkt: pattrib->priority = UserPriority; - pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN; + pattrib->hdrlen = XATTRIB_GET_WDS(pattrib) ? WLAN_HDR_A4_QOS_LEN : WLAN_HDR_A3_QOS_LEN; pattrib->subtype = WIFI_QOS_DATA_TYPE; } @@ -1429,7 +1576,7 @@ s32 update_tdls_attrib(_adapter *padapter, struct pkt_attrib *pattrib) } /* TODO:_lock */ - if (update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) { + if (update_attrib_sec_info(padapter, pattrib, psta, NON_EAPOL) == _FAIL) { res = _FAIL; goto exit; } @@ -1450,7 +1597,8 @@ inline u8 rtw_get_hwseq_no(_adapter *padapter) u8 hwseq_num = 0; #ifdef CONFIG_CONCURRENT_MODE - #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) + #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) \ + || defined(CONFIG_RTL8723F) hwseq_num = padapter->iface_id; if (hwseq_num > 3) hwseq_num = 3; @@ -1500,6 +1648,7 @@ static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattr struct qos_priv *pqospriv = &pmlmepriv->qospriv; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; sint res = _SUCCESS; + enum eap_type eapol_type = NON_EAPOL; #ifdef CONFIG_LPS u8 pkt_type = 0; #endif @@ -1511,30 +1660,36 @@ static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattr pattrib->ether_type = ntohs(etherhdr.h_proto); - if (MLME_IS_MESH(padapter)) /* address resolve is done for mesh */ + if (MLME_STATE(padapter) & (WIFI_AP_STATE | WIFI_MESH_STATE)) /* address resolve is done for ap/mesh */ goto get_sta_info; _rtw_memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN); _rtw_memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN); + _rtw_memcpy(pattrib->ta, adapter_mac_addr(padapter), ETH_ALEN); if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) || (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) { _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - _rtw_memcpy(pattrib->ta, adapter_mac_addr(padapter), ETH_ALEN); DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_adhoc); } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { -#ifdef CONFIG_TDLS + #ifdef CONFIG_TDLS if (rtw_check_tdls_established(padapter, pattrib) == _TRUE) _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); /* For TDLS direct link Tx, set ra to be same to dst */ else -#endif + #endif + { _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); - _rtw_memcpy(pattrib->ta, adapter_mac_addr(padapter), ETH_ALEN); + #ifdef CONFIG_RTW_WDS + if (adapter_use_wds(padapter) + && _rtw_memcmp(pattrib->src, pattrib->ta, ETH_ALEN) == _FALSE + ) { + pattrib->wds = 1; + if (IS_MCAST(pattrib->dst)) + rtw_tx_wds_gptr_update(padapter, pattrib->src); + } + #endif + } DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_sta); - } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { - _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - _rtw_memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN); - DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_ap); } else DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_unknown); @@ -1564,6 +1719,11 @@ get_sta_info: res = _FAIL; goto exit; } + + #ifdef CONFIG_RTW_WDS + if (XATTRIB_GET_WDS(pattrib) && !(psta->flags & WLAN_STA_WDS)) + pattrib->wds = 0; + #endif } if (!(psta->state & WIFI_ASOC_STATE)) { @@ -1650,7 +1810,7 @@ get_sta_info: } } else if (0x888e == pattrib->ether_type) - parsing_eapol_packet(padapter, pktfile.cur_addr, psta, 1); + eapol_type = parsing_eapol_packet(padapter, pktfile.cur_addr, psta, 1); #if defined (DBG_ARP_DUMP) || defined (DBG_IP_R_MONITOR) else if (pattrib->ether_type == ETH_P_ARP) { u8 arp[28] = {0}; @@ -1685,7 +1845,7 @@ get_sta_info: #endif /* TODO:_lock */ - if (update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) { + if (update_attrib_sec_info(padapter, pattrib, psta, eapol_type) == _FAIL) { DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_sec); res = _FAIL; goto exit; @@ -1694,7 +1854,7 @@ get_sta_info: /* get ether_hdr_len */ pattrib->pkt_hdrlen = ETH_HLEN;/* (pattrib->ether_type == 0x8100) ? (14 + 4 ): 14; */ /* vlan tag */ - pattrib->hdrlen = WLAN_HDR_A3_LEN; + pattrib->hdrlen = XATTRIB_GET_WDS(pattrib) ? WLAN_HDR_A4_LEN : WLAN_HDR_A3_LEN; pattrib->subtype = WIFI_DATA_TYPE; pattrib->qos_en = psta->qos_option; pattrib->priority = 0; @@ -1986,23 +2146,47 @@ s32 rtw_make_wlanhdr(_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib) } else #endif /* CONFIG_TDLS */ { - /* to_ds = 1, fr_ds = 0; */ - /* 1.Data transfer to AP */ - /* 2.Arp pkt will relayed by AP */ - SetToDs(fctrl); - _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + #ifdef CONFIG_RTW_WDS + if (pattrib->wds) { + SetToDs(fctrl); + SetFrDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, pattrib->ra, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr4, pattrib->src, ETH_ALEN); + } else + #endif + { + /* to_ds = 1, fr_ds = 0; */ + /* 1.Data transfer to AP */ + /* 2.Arp pkt will relayed by AP */ + SetToDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + } if (pqospriv->qos_option) qos_option = _TRUE; } } else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)) { - /* to_ds = 0, fr_ds = 1; */ - SetFrDs(fctrl); - _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN); + #ifdef CONFIG_RTW_WDS + if (pattrib->wds) { + SetToDs(fctrl); + SetFrDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, pattrib->ra, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr4, pattrib->src, ETH_ALEN); + } else + #endif + { + /* to_ds = 0, fr_ds = 1; */ + SetFrDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN); + } if (pattrib->qos_en) qos_option = _TRUE; @@ -2141,7 +2325,11 @@ s32 rtw_txframes_pending(_adapter *padapter) return ((_rtw_queue_empty(&pxmitpriv->be_pending) == _FALSE) || (_rtw_queue_empty(&pxmitpriv->bk_pending) == _FALSE) || (_rtw_queue_empty(&pxmitpriv->vi_pending) == _FALSE) || - (_rtw_queue_empty(&pxmitpriv->vo_pending) == _FALSE)); + (_rtw_queue_empty(&pxmitpriv->vo_pending) == _FALSE) +#ifdef CONFIG_RTW_MGMT_QUEUE + || (_rtw_queue_empty(&pxmitpriv->mgmt_pending) == _FALSE) +#endif + ); } s32 rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib) @@ -3118,7 +3306,7 @@ s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame ClearPwrMgt(BIP_AAD); ClearMData(BIP_AAD); /* conscruct AAD, copy address 1 to address 3 */ - _rtw_memcpy(BIP_AAD + 2, pwlanhdr->addr1, 18); + _rtw_memcpy(BIP_AAD + 2, GetAddr1Ptr((u8 *)pwlanhdr), 18); /* copy management fram body */ _rtw_memcpy(BIP_AAD + BIP_AAD_SIZE, MGMT_body, frame_body_len); @@ -3462,7 +3650,7 @@ struct xmit_frame *__rtw_alloc_cmdxmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pcmdframe; struct xmit_buf *pxmitbuf; - pcmdframe = rtw_alloc_xmitframe(pxmitpriv); + pcmdframe = rtw_alloc_xmitframe(pxmitpriv, 0); if (pcmdframe == NULL) { RTW_INFO("%s, alloc xmitframe fail\n", __FUNCTION__); return NULL; @@ -3725,7 +3913,7 @@ Otherwise, we must use _enter/_exit critical to protect free_xmit_queue... Must be very very cautious... */ -struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* (_queue *pfree_xmit_queue) */ +struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv, u16 os_qid) { /* Please remember to use all the osdep_service api, @@ -3738,7 +3926,6 @@ struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* (_queue *p _list *plist, *phead; _queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; - _enter_critical_bh(&pfree_xmit_queue->lock, &irqL); if (_rtw_queue_empty(pfree_xmit_queue) == _TRUE) { @@ -3752,10 +3939,14 @@ struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* (_queue *p rtw_list_delete(&(pxframe->list)); pxmitpriv->free_xmitframe_cnt--; + pxframe->os_qid = os_qid; } _exit_critical_bh(&pfree_xmit_queue->lock, &irqL); + if (pxframe) + rtw_os_check_stop_queue(pxmitpriv->adapter, os_qid); + rtw_init_xmitframe(pxframe); @@ -3863,6 +4054,9 @@ s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitfram _exit_critical_bh(&queue->lock, &irqL); + if (queue == &pxmitpriv->free_xmit_queue) + rtw_os_check_wakup_queue(padapter, pxmitframe->os_qid); + check_pkt_complete: if (pndis_pkt) @@ -3874,6 +4068,76 @@ exit: return _SUCCESS; } +#ifdef CONFIG_RTW_MGMT_QUEUE +void rtw_free_mgmt_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *mgmt_queue) +{ + _irqL irqL; + _list *plist, *phead; + struct xmit_frame *pxmitframe; + + _enter_critical_bh(&(mgmt_queue->lock), &irqL); + + phead = get_list_head(mgmt_queue); + plist = get_next(phead); + + while (rtw_end_of_queue_search(phead, plist) == _FALSE) { + + pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list); + plist = get_next(plist); + + #ifdef DBG_MGMT_QUEUE + RTW_INFO("%s seq_num = %u\n", __func__, pxmitframe->attrib.seqnum); + #endif + + rtw_free_xmitbuf_ext(pxmitpriv, pxmitframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pxmitframe); + } + _exit_critical_bh(&(mgmt_queue->lock), &irqL); +} + +u8 rtw_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + struct sta_info *psta; + struct tx_servq *ptxservq; + struct pkt_attrib *pattrib = &(pxmitframe->attrib); + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct hw_xmit *phwxmits = pxmitpriv->hwxmits; + u8 mgmt_idx = pxmitpriv->hwxmit_entry - 1; + + DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class); + + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + if (pattrib->psta != psta) { + DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_sta); + RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta); + return _FAIL; + } + + if (psta == NULL) { + DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_nosta); + RTW_INFO("rtw_xmit_classifier: psta == NULL\n"); + return _FAIL; + } + + if (!(psta->state & WIFI_ASOC_STATE)) { + DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_fwlink); + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state); + return _FAIL; + } + + ptxservq = &(psta->sta_xmitpriv.mgmt_q); + + if (rtw_is_list_empty(&ptxservq->tx_pending)) + rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmits[mgmt_idx].sta_queue)); + + rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending)); + ptxservq->qcnt++; + phwxmits[mgmt_idx].accnt++; + + return _SUCCESS; +} +#endif + void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue) { _irqL irqL; @@ -3973,8 +4237,13 @@ struct xmit_frame *rtw_get_xframe(struct xmit_priv *pxmitpriv, int *num_frame) _irqL irqL0; _list *sta_plist, *sta_phead; struct hw_xmit *phwxmit_i = pxmitpriv->hwxmits; - sint entry = pxmitpriv->hwxmit_entry; - +#ifdef CONFIG_RTW_MGMT_QUEUE + /* This function gets xmit_frame from AC queue. */ + /* When mgmt queue is used, AC queue index is (hwxmit_entry - 1) */ + sint entry = pxmitpriv->hwxmit_entry - 1; +#else + sint entry = pxmitpriv->hwxmit_entry; +#endif struct hw_xmit *phwxmit; struct tx_servq *ptxservq = NULL; _queue *pframe_queue = NULL; @@ -4025,6 +4294,54 @@ exit: return pxmitframe; } +#ifdef CONFIG_RTW_MGMT_QUEUE +struct xmit_frame *rtw_dequeue_mgmt_xframe(struct xmit_priv *pxmitpriv) +{ + _irqL irqL0; + _list *sta_plist, *sta_phead; + struct hw_xmit *mgmt_hwxmit; + struct tx_servq *ptxservq = NULL; + _queue *pframe_queue = NULL; + struct xmit_frame *pxmitframe = NULL; + u8 mgmt_entry = pxmitpriv->hwxmit_entry - 1; + + _enter_critical_bh(&pxmitpriv->lock, &irqL0); + + /* management queue */ + mgmt_hwxmit = (pxmitpriv->hwxmits) + mgmt_entry; + + sta_phead = get_list_head(mgmt_hwxmit->sta_queue); + sta_plist = get_next(sta_phead); + + while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE) { + + ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending); + + pframe_queue = &ptxservq->sta_pending; + + pxmitframe = dequeue_one_xmitframe(pxmitpriv, mgmt_hwxmit, ptxservq, pframe_queue); + + #ifdef DBG_MGMT_QUEUE + RTW_INFO("%s dequeue mgmt frame (seq_num = %u) to TX\n", __func__, pxmitframe->attrib.seqnum); + #endif + + if (pxmitframe) { + mgmt_hwxmit->accnt--; + + /* Remove sta node when there is no pending packets. */ + if (_rtw_queue_empty(pframe_queue)) /* must be done after get_next and before break */ + rtw_list_delete(&ptxservq->tx_pending); + + goto exit; + } + sta_plist = get_next(sta_plist); + } +exit: + _exit_critical_bh(&pxmitpriv->lock, &irqL0); + + return pxmitframe; +} +#endif struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry) { @@ -4035,9 +4352,13 @@ struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmi _queue *pframe_queue = NULL; struct xmit_frame *pxmitframe = NULL; _adapter *padapter = pxmitpriv->adapter; - struct registry_priv *pregpriv = &padapter->registrypriv; + struct registry_priv *pregpriv = &padapter->registrypriv; int i, inx[4]; - +#ifdef CONFIG_RTW_MGMT_QUEUE + /* This function gets xmit_frame from AC queue. */ + /* When mgmt queue is used, AC queue index is (hwxmit_entry - 1) */ + entry--; +#endif inx[0] = 0; inx[1] = 1; inx[2] = 2; @@ -4104,7 +4425,6 @@ exit: return pxmitframe; } -#if 1 struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, u8 *ac) { struct tx_servq *ptxservq = NULL; @@ -4141,60 +4461,6 @@ struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, return ptxservq; } -#else -__inline static struct tx_servq *rtw_get_sta_pending -(_adapter *padapter, _queue **ppstapending, struct sta_info *psta, sint up) -{ - struct tx_servq *ptxservq; - struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; - - -#ifdef CONFIG_RTL8711 - - if (IS_MCAST(psta->cmn.mac_addr)) { - ptxservq = &(psta->sta_xmitpriv.be_q); /* we will use be_q to queue bc/mc frames in BCMC_stainfo */ - *ppstapending = &padapter->xmitpriv.bm_pending; - } else -#endif - { - switch (up) { - case 1: - case 2: - ptxservq = &(psta->sta_xmitpriv.bk_q); - *ppstapending = &padapter->xmitpriv.bk_pending; - (phwxmits + 3)->accnt++; - break; - - case 4: - case 5: - ptxservq = &(psta->sta_xmitpriv.vi_q); - *ppstapending = &padapter->xmitpriv.vi_pending; - (phwxmits + 1)->accnt++; - break; - - case 6: - case 7: - ptxservq = &(psta->sta_xmitpriv.vo_q); - *ppstapending = &padapter->xmitpriv.vo_pending; - (phwxmits + 0)->accnt++; - break; - - case 0: - case 3: - default: - ptxservq = &(psta->sta_xmitpriv.be_q); - *ppstapending = &padapter->xmitpriv.be_pending; - (phwxmits + 2)->accnt++; - break; - - } - - } - - - return ptxservq; -} -#endif /* * Will enqueue pxmitframe to the proper queue, @@ -4283,49 +4549,27 @@ void rtw_alloc_hwxmits(_adapter *padapter) hwxmits = pxmitpriv->hwxmits; - if (pxmitpriv->hwxmit_entry == 5) { - /* pxmitpriv->bmc_txqueue.head = 0; */ - /* hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue; */ - hwxmits[0] .sta_queue = &pxmitpriv->bm_pending; + rtw_warn_on(pxmitpriv->hwxmit_entry < 4); - /* pxmitpriv->vo_txqueue.head = 0; */ - /* hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; */ - hwxmits[1] .sta_queue = &pxmitpriv->vo_pending; + /* pxmitpriv->vo_txqueue.head = 0; */ + /* hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; */ + hwxmits[0].sta_queue = &pxmitpriv->vo_pending; - /* pxmitpriv->vi_txqueue.head = 0; */ - /* hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; */ - hwxmits[2] .sta_queue = &pxmitpriv->vi_pending; + /* pxmitpriv->vi_txqueue.head = 0; */ + /* hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; */ + hwxmits[1].sta_queue = &pxmitpriv->vi_pending; - /* pxmitpriv->bk_txqueue.head = 0; */ - /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */ - hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; + /* pxmitpriv->be_txqueue.head = 0; */ + /* hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; */ + hwxmits[2].sta_queue = &pxmitpriv->be_pending; - /* pxmitpriv->be_txqueue.head = 0; */ - /* hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue; */ - hwxmits[4] .sta_queue = &pxmitpriv->be_pending; - - } else if (pxmitpriv->hwxmit_entry == 4) { - - /* pxmitpriv->vo_txqueue.head = 0; */ - /* hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; */ - hwxmits[0] .sta_queue = &pxmitpriv->vo_pending; - - /* pxmitpriv->vi_txqueue.head = 0; */ - /* hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; */ - hwxmits[1] .sta_queue = &pxmitpriv->vi_pending; - - /* pxmitpriv->be_txqueue.head = 0; */ - /* hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; */ - hwxmits[2] .sta_queue = &pxmitpriv->be_pending; - - /* pxmitpriv->bk_txqueue.head = 0; */ - /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */ - hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; - } else { - - - } + /* pxmitpriv->bk_txqueue.head = 0; */ + /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */ + hwxmits[3].sta_queue = &pxmitpriv->bk_pending; +#ifdef CONFIG_RTW_MGMT_QUEUE + hwxmits[4].sta_queue = &pxmitpriv->mgmt_pending; +#endif } @@ -4884,7 +5128,7 @@ s32 rtw_xmit_posthandle(_adapter *padapter, struct xmit_frame *pxmitframe, _pkt * 0 success, hardware will handle this xmit frame(packet) * <0 fail */ -s32 rtw_xmit(_adapter *padapter, _pkt **ppkt) +s32 rtw_xmit(_adapter *padapter, _pkt **ppkt, u16 os_qid) { static systime start = 0; static u32 drop_cnt = 0; @@ -4903,7 +5147,7 @@ s32 rtw_xmit(_adapter *padapter, _pkt **ppkt) if (start == 0) start = rtw_get_current_time(); - pxmitframe = rtw_alloc_xmitframe(pxmitpriv); + pxmitframe = rtw_alloc_xmitframe(pxmitpriv, os_qid); if (rtw_get_passing_time_ms(start) > 2000) { if (drop_cnt) @@ -4920,7 +5164,7 @@ s32 rtw_xmit(_adapter *padapter, _pkt **ppkt) } #ifdef CONFIG_BR_EXT - if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) { + if (!adapter_use_wds(padapter) && check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) { void *br_port = NULL; #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) @@ -4942,17 +5186,22 @@ s32 rtw_xmit(_adapter *padapter, _pkt **ppkt) } #endif /* CONFIG_BR_EXT */ -#ifdef CONFIG_RTW_MESH - if (MLME_IS_MESH(padapter)) { +#if defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) + if (MLME_STATE(padapter) & (WIFI_AP_STATE | WIFI_MESH_STATE)) { _list b2u_list; - res = rtw_mesh_addr_resolve(padapter, pxmitframe, *ppkt, &b2u_list); + #ifdef CONFIG_RTW_MESH + if (MLME_IS_MESH(padapter)) + res = rtw_mesh_addr_resolve(padapter, os_qid, pxmitframe, *ppkt, &b2u_list); + else + #endif + res = rtw_ap_addr_resolve(padapter, os_qid, pxmitframe, *ppkt, &b2u_list); if (res == RTW_RA_RESOLVING) return 1; if (res == _FAIL) return -1; - #if CONFIG_RTW_MESH_DATA_BMC_TO_UC + #if CONFIG_RTW_DATA_BMC_TO_UC if (!rtw_is_list_empty(&b2u_list)) { _list *list = get_next(&b2u_list); struct xmit_frame *b2uframe; @@ -4973,14 +5222,14 @@ s32 rtw_xmit(_adapter *padapter, _pkt **ppkt) rtw_xmit_posthandle(padapter, b2uframe, b2uframe->pkt); } } - #endif /* CONFIG_RTW_MESH_DATA_BMC_TO_UC */ + #endif if (res == RTW_BMC_NO_NEED) { rtw_free_xmitframe(&padapter->xmitpriv, pxmitframe); return 0; } } -#endif /* CONFIG_RTW_MESH */ +#endif /* defined(CONFIG_AP_MODE) || defined(CONFIG_RTW_MESH) */ pxmitframe->pkt = NULL; /* let rtw_xmit_posthandle not to free pkt inside */ res = rtw_xmit_posthandle(padapter, pxmitframe, *ppkt); @@ -5097,6 +5346,96 @@ inline bool xmitframe_hiq_filter(struct xmit_frame *xmitframe) } #if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) +#ifdef CONFIG_RTW_MGMT_QUEUE +u8 mgmt_xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + _irqL irqL; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct sta_info *psta = pattrib->psta; + struct sta_priv *pstapriv = &padapter->stapriv; + bool update_tim = _FALSE; + u8 ret = _TRUE; + + if (is_broadcast_mac_addr(pattrib->ra) || pattrib->ps_dontq) + return _FALSE; + + if (psta == NULL) { + RTW_INFO("%s, psta==NUL, pattrib->ra:"MAC_FMT"\n", + __func__, MAC_ARG(pattrib->ra)); + return _FALSE; + } + + if (!(psta->state & WIFI_ASOC_STATE)) { + DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_link); + RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state); + return _FALSE; + } + + _enter_critical_bh(&psta->mgmt_sleep_q.lock, &irqL); + + if (psta->state & WIFI_SLEEP_STATE && + rtw_tim_map_is_set(padapter, pstapriv->sta_dz_bitmap, psta->cmn.aid)) { + + rtw_list_delete(&pxmitframe->list); + rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->mgmt_sleep_q)); + psta->mgmt_sleepq_len++; + + #ifdef DBG_MGMT_QUEUE + RTW_INFO("%s attrib->ra:"MAC_FMT" seq_num = %u, subtype = 0x%x\n", + __func__, MAC_ARG(pattrib->ra), pattrib->seqnum, pattrib->subtype); + #endif + + if (!(rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, psta->cmn.aid))) + update_tim = _TRUE; + + rtw_tim_map_set(padapter, pstapriv->tim_bitmap, psta->cmn.aid); + + /* upate BCN for TIM IE */ + if (update_tim == _TRUE) + _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0, "buffer mgmt frame"); + + ret = RTW_QUEUE_MGMT; + DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_ucast); + } + + _exit_critical_bh(&psta->mgmt_sleep_q.lock, &irqL); + + return ret; +} + +static void dequeue_mgmt_xmitframe_to_sleepq(_adapter *padapter, struct sta_info *psta, _queue *pframequeue) +{ + sint ret; + _list *plist, *phead; + struct tx_servq *ptxservq; + struct pkt_attrib *pattrib; + struct xmit_frame *pxmitframe; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct hw_xmit *phwxmits = pxmitpriv->hwxmits; + u8 mgmt_idx = pxmitpriv->hwxmit_entry - 1; + + phead = get_list_head(pframequeue); + plist = get_next(phead); + + while (rtw_end_of_queue_search(phead, plist) == _FALSE) { + pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list); + plist = get_next(plist); + + pattrib = &pxmitframe->attrib; + pattrib->triggered = 0; + + ret = mgmt_xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe); + + if (ret == RTW_QUEUE_MGMT) { + ptxservq = &(psta->sta_xmitpriv.mgmt_q); + ptxservq->qcnt--; + phwxmits[mgmt_idx].accnt--; + } else { + /* RTW_INFO("xmitframe_enqueue_for_sleeping_sta return _FALSE\n"); */ + } + } +} +#endif sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe) { @@ -5337,6 +5676,11 @@ void stop_sta_xmit(_adapter *padapter, struct sta_info *psta) #endif /* CONFIG_TDLS */ rtw_tim_map_set(padapter, pstapriv->sta_dz_bitmap, psta->cmn.aid); +#ifdef CONFIG_RTW_MGMT_QUEUE + dequeue_mgmt_xmitframe_to_sleepq(padapter, psta, &pstaxmitpriv->mgmt_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->mgmt_q.tx_pending)); +#endif + dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending); rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending)); dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending); @@ -5384,6 +5728,32 @@ void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta) /* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */ _enter_critical_bh(&pxmitpriv->lock, &irqL); +#ifdef CONFIG_RTW_MGMT_QUEUE + /* management queue */ + xmitframe_phead = get_list_head(&psta->mgmt_sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + xmitframe_plist = get_next(xmitframe_plist); + + rtw_list_delete(&pxmitframe->list); + + #ifdef DBG_MGMT_QUEUE + RTW_INFO("%s seq_num = %u, subtype = 0x%x\n", + __func__, pxmitframe->attrib.seqnum, pxmitframe->attrib.subtype); + #endif + + psta->mgmt_sleepq_len--; + + pxmitframe->attrib.triggered = 1; + + rtw_hal_mgmt_xmitframe_enqueue(padapter, pxmitframe); + } +#endif /* CONFIG_RTW_MGMT_QUEUE */ + + /* AC queue */ xmitframe_phead = get_list_head(&psta->sleep_q); xmitframe_plist = get_next(xmitframe_phead); @@ -5446,7 +5816,11 @@ void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta) } - if (psta->sleepq_len == 0) { + if (psta->sleepq_len == 0 +#ifdef CONFIG_RTW_MGMT_QUEUE + && psta->mgmt_sleepq_len == 0 +#endif + ) { #ifdef CONFIG_TDLS if (psta->tdls_sta_state & TDLS_LINKED_STATE) { if (psta->state & WIFI_SLEEP_STATE) @@ -5543,7 +5917,6 @@ _exit: else _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0, "clear UC"); } - } void xmit_delivery_enabled_frames(_adapter *padapter, struct sta_info *psta) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/wds/rtw_wds.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/wds/rtw_wds.c new file mode 100644 index 000000000000..85d139cd364d --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/wds/rtw_wds.c @@ -0,0 +1,787 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#define _RTW_WDS_C_ + +#include + +#if defined(CONFIG_RTW_WDS) +#include + +#if defined(CONFIG_AP_MODE) + +#ifdef PLATFORM_LINUX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) +static void rtw_wpath_free_rcu(struct rtw_wds_path *wpath) +{ + kfree_rcu(wpath, rcu); + rtw_mstat_update(MSTAT_TYPE_PHY, MSTAT_FREE, sizeof(struct rtw_wds_path)); +} +#else +static void rtw_wpath_free_rcu_callback(rtw_rcu_head *head) +{ + struct rtw_wds_path *wpath; + + wpath = container_of(head, struct rtw_wds_path, rcu); + rtw_mfree(wpath, sizeof(struct rtw_wds_path)); +} + +static void rtw_wpath_free_rcu(struct rtw_wds_path *wpath) +{ + call_rcu(&wpath->rcu, rtw_wpath_free_rcu_callback); +} +#endif +#endif /* PLATFORM_LINUX */ + +static void rtw_wds_path_free_rcu(struct rtw_wds_table *tbl, struct rtw_wds_path *wpath); + +static u32 rtw_wds_table_hash(const void *addr, u32 len, u32 seed) +{ + /* Use last four bytes of hw addr as hash index */ + return jhash_1word(*(u32 *)(addr+2), seed); +} + +static const rtw_rhashtable_params rtw_wds_rht_params = { + .nelem_hint = 2, + .automatic_shrinking = true, + .key_len = ETH_ALEN, + .key_offset = offsetof(struct rtw_wds_path, dst), + .head_offset = offsetof(struct rtw_wds_path, rhash), + .hashfn = rtw_wds_table_hash, +}; + +static void rtw_wds_path_rht_free(void *ptr, void *tblptr) +{ + struct rtw_wds_path *wpath = ptr; + struct rtw_wds_table *tbl = tblptr; + + rtw_wds_path_free_rcu(tbl, wpath); +} + +static struct rtw_wds_table *rtw_wds_table_alloc(void) +{ + struct rtw_wds_table *newtbl; + + newtbl = rtw_malloc(sizeof(struct rtw_wds_table)); + if (!newtbl) + return NULL; + + return newtbl; +} + +static void rtw_wds_table_free(struct rtw_wds_table *tbl) +{ + rtw_rhashtable_free_and_destroy(&tbl->rhead, + rtw_wds_path_rht_free, tbl); + rtw_mfree(tbl, sizeof(struct rtw_wds_table)); +} + +void rtw_wds_path_assign_nexthop(struct rtw_wds_path *wpath, struct sta_info *sta) +{ + rtw_rcu_assign_pointer(wpath->next_hop, sta); +} + +static struct rtw_wds_path *rtw_wpath_lookup(struct rtw_wds_table *tbl, const u8 *dst) +{ + struct rtw_wds_path *wpath; + + if (!tbl) + return NULL; + + wpath = rtw_rhashtable_lookup_fast(&tbl->rhead, dst, rtw_wds_rht_params); + + return wpath; +} + +struct rtw_wds_path *rtw_wds_path_lookup(_adapter *adapter, const u8 *dst) +{ + return rtw_wpath_lookup(adapter->wds_paths, dst); +} + +static struct rtw_wds_path * +__rtw_wds_path_lookup_by_idx(struct rtw_wds_table *tbl, int idx) +{ + int i = 0, ret; + struct rtw_wds_path *wpath = NULL; + rtw_rhashtable_iter iter; + + if (!tbl) + return NULL; + + ret = rtw_rhashtable_walk_enter(&tbl->rhead, &iter); + if (ret) + return NULL; + + ret = rtw_rhashtable_walk_start(&iter); + if (ret && ret != -EAGAIN) + goto err; + + while ((wpath = rtw_rhashtable_walk_next(&iter))) { + if (IS_ERR(wpath) && PTR_ERR(wpath) == -EAGAIN) + continue; + if (IS_ERR(wpath)) + break; + if (i++ == idx) + break; + } +err: + rtw_rhashtable_walk_stop(&iter); + rtw_rhashtable_walk_exit(&iter); + + if (IS_ERR(wpath) || !wpath) + return NULL; + + return wpath; +} + +/** + * Locking: must be called within a read rcu section. + */ +struct rtw_wds_path * +rtw_wds_path_lookup_by_idx(_adapter *adapter, int idx) +{ + return __rtw_wds_path_lookup_by_idx(adapter->wds_paths, idx); +} + +void dump_wpath(void *sel, _adapter *adapter) +{ + struct rtw_wds_path *wpath; + int idx = 0; + char dst[ETH_ALEN]; + char next_hop[ETH_ALEN]; + u32 age_ms; + + RTW_PRINT_SEL(sel, "num:%d\n", ATOMIC_READ(&adapter->wds_path_num)); + RTW_PRINT_SEL(sel, "%-17s %-17s %-6s\n" + , "dst", "next_hop", "age" + ); + + do { + rtw_rcu_read_lock(); + + wpath = rtw_wds_path_lookup_by_idx(adapter, idx); + if (wpath) { + _rtw_memcpy(dst, wpath->dst, ETH_ALEN); + _rtw_memcpy(next_hop, wpath->next_hop->cmn.mac_addr, ETH_ALEN); + age_ms = rtw_get_passing_time_ms(wpath->last_update); + } + + rtw_rcu_read_unlock(); + + if (wpath) { + RTW_PRINT_SEL(sel, MAC_FMT" "MAC_FMT" %6u\n" + , MAC_ARG(dst), MAC_ARG(next_hop) + , age_ms < 999999 ? age_ms : 999999 + ); + } + + idx++; + } while (wpath); +} + +static +struct rtw_wds_path *rtw_wds_path_new(_adapter *adapter, + const u8 *dst) +{ + struct rtw_wds_path *new_wpath; + + new_wpath = rtw_zmalloc(sizeof(struct rtw_wds_path)); + if (!new_wpath) + return NULL; + + new_wpath->adapter = adapter; + _rtw_memcpy(new_wpath->dst, dst, ETH_ALEN); + new_wpath->last_update = rtw_get_current_time(); + + return new_wpath; +} + +/** + * Returns: 0 on success + * + * State: the initial state of the new path is set to 0 + */ +struct rtw_wds_path *rtw_wds_path_add(_adapter *adapter, + const u8 *dst, struct sta_info *next_hop) +{ + struct rtw_wds_table *tbl = adapter->wds_paths; + struct rtw_wds_path *wpath, *new_wpath; + int ret; + + if (!tbl) + return ERR_PTR(-ENOTSUPP); + + if (_rtw_memcmp(dst, adapter_mac_addr(adapter), ETH_ALEN) == _TRUE) + /* never add ourselves as neighbours */ + return ERR_PTR(-ENOTSUPP); + + if (IS_MCAST(dst)) + return ERR_PTR(-ENOTSUPP); + + if (ATOMIC_INC_UNLESS(&adapter->wds_path_num, RTW_WDS_MAX_PATHS) == 0) + return ERR_PTR(-ENOSPC); + + new_wpath = rtw_wds_path_new(adapter, dst); + if (!new_wpath) + return ERR_PTR(-ENOMEM); + + do { + ret = rtw_rhashtable_lookup_insert_fast(&tbl->rhead, + &new_wpath->rhash, + rtw_wds_rht_params); + + if (ret == -EEXIST) + wpath = rtw_rhashtable_lookup_fast(&tbl->rhead, + dst, + rtw_wds_rht_params); + + } while (unlikely(ret == -EEXIST && !wpath)); + + if (ret && ret != -EEXIST) + return ERR_PTR(ret); + + /* At this point either new_wpath was added, or we found a + * matching entry already in the table; in the latter case + * free the unnecessary new entry. + */ + if (ret == -EEXIST) { + rtw_mfree(new_wpath, sizeof(struct rtw_wds_path)); + new_wpath = wpath; + } + rtw_wds_path_assign_nexthop(new_wpath, next_hop); + + return new_wpath; +} + +static void rtw_wds_path_free_rcu(struct rtw_wds_table *tbl, + struct rtw_wds_path *wpath) +{ + _adapter *adapter = wpath->adapter; + + ATOMIC_DEC(&adapter->wds_path_num); + + rtw_wpath_free_rcu(wpath); +} + +static void __rtw_wds_path_del(struct rtw_wds_table *tbl, struct rtw_wds_path *wpath) +{ + rtw_rhashtable_remove_fast(&tbl->rhead, &wpath->rhash, rtw_wds_rht_params); + rtw_wds_path_free_rcu(tbl, wpath); +} + +void rtw_wds_path_flush_by_nexthop(struct sta_info *sta) +{ + _adapter *adapter = sta->padapter; + struct rtw_wds_table *tbl = adapter->wds_paths; + struct rtw_wds_path *wpath; + rtw_rhashtable_iter iter; + int ret; + + if (!tbl) + return; + + ret = rtw_rhashtable_walk_enter(&tbl->rhead, &iter); + if (ret) + return; + + ret = rtw_rhashtable_walk_start(&iter); + if (ret && ret != -EAGAIN) + goto out; + + while ((wpath = rtw_rhashtable_walk_next(&iter))) { + if (IS_ERR(wpath) && PTR_ERR(wpath) == -EAGAIN) + continue; + if (IS_ERR(wpath)) + break; + + if (rtw_rcu_access_pointer(wpath->next_hop) == sta) + __rtw_wds_path_del(tbl, wpath); + } +out: + rtw_rhashtable_walk_stop(&iter); + rtw_rhashtable_walk_exit(&iter); +} + +static void rtw_wds_table_flush_by_iface(struct rtw_wds_table *tbl) +{ + struct rtw_wds_path *wpath; + rtw_rhashtable_iter iter; + int ret; + + if (!tbl) + return; + + ret = rtw_rhashtable_walk_enter(&tbl->rhead, &iter); + if (ret) + return; + + ret = rtw_rhashtable_walk_start(&iter); + if (ret && ret != -EAGAIN) + goto out; + + while ((wpath = rtw_rhashtable_walk_next(&iter))) { + if (IS_ERR(wpath) && PTR_ERR(wpath) == -EAGAIN) + continue; + if (IS_ERR(wpath)) + break; + __rtw_wds_path_del(tbl, wpath); + } +out: + rtw_rhashtable_walk_stop(&iter); + rtw_rhashtable_walk_exit(&iter); +} + +void rtw_wds_path_flush_by_iface(_adapter *adapter) +{ + rtw_wds_table_flush_by_iface(adapter->wds_paths); +} + +static int rtw_wds_table_path_del(struct rtw_wds_table *tbl, + const u8 *addr) +{ + struct rtw_wds_path *wpath; + + if (!tbl) + return -ENXIO; + + rtw_rcu_read_lock(); + wpath = rtw_rhashtable_lookup_fast(&tbl->rhead, addr, rtw_wds_rht_params); + if (!wpath) { + rtw_rcu_read_unlock(); + return -ENXIO; + } + + __rtw_wds_path_del(tbl, wpath); + rtw_rcu_read_unlock(); + return 0; +} + +int rtw_wds_path_del(_adapter *adapter, const u8 *addr) +{ + int err; + + err = rtw_wds_table_path_del(adapter->wds_paths, addr); + return err; +} + +int rtw_wds_pathtbl_init(_adapter *adapter) +{ + struct rtw_wds_table *tbl_path; + int ret; + + tbl_path = rtw_wds_table_alloc(); + if (!tbl_path) + return -ENOMEM; + + rtw_rhashtable_init(&tbl_path->rhead, &rtw_wds_rht_params); + + ATOMIC_SET(&adapter->wds_path_num, 0); + adapter->wds_paths = tbl_path; + + return 0; +} + +static +void rtw_wds_path_tbl_expire(_adapter *adapter, + struct rtw_wds_table *tbl) +{ + struct rtw_wds_path *wpath; + rtw_rhashtable_iter iter; + int ret; + + if (!tbl) + return; + + ret = rtw_rhashtable_walk_enter(&tbl->rhead, &iter); + if (ret) + return; + + ret = rtw_rhashtable_walk_start(&iter); + if (ret && ret != -EAGAIN) + goto out; + + while ((wpath = rtw_rhashtable_walk_next(&iter))) { + if (IS_ERR(wpath) && PTR_ERR(wpath) == -EAGAIN) + continue; + if (IS_ERR(wpath)) + break; + if (rtw_time_after(rtw_get_current_time(), wpath->last_update + RTW_WDS_PATH_EXPIRE)) + __rtw_wds_path_del(tbl, wpath); + } + +out: + rtw_rhashtable_walk_stop(&iter); + rtw_rhashtable_walk_exit(&iter); +} + +void rtw_wds_path_expire(_adapter *adapter) +{ + rtw_wds_path_tbl_expire(adapter, adapter->wds_paths); +} + +void rtw_wds_pathtbl_unregister(_adapter *adapter) +{ + if (adapter->wds_paths) { + rtw_wds_table_free(adapter->wds_paths); + adapter->wds_paths = NULL; + } +} + +int rtw_wds_nexthop_lookup(_adapter *adapter, const u8 *da, u8 *ra) +{ + struct rtw_wds_path *wpath; + struct sta_info *next_hop; + int err = -ENOENT; + + rtw_rcu_read_lock(); + wpath = rtw_wds_path_lookup(adapter, da); + + if (!wpath) + goto endlookup; + + next_hop = rtw_rcu_dereference(wpath->next_hop); + if (next_hop) { + _rtw_memcpy(ra, next_hop->cmn.mac_addr, ETH_ALEN); + err = 0; + } + +endlookup: + rtw_rcu_read_unlock(); + return err; +} + +#endif /* defined(CONFIG_AP_MODE) */ + +/* WDS group adddressed proxy TX record */ +struct rtw_wds_gptr { + u8 src[ETH_ALEN]; + systime last_update; + rtw_rhash_head rhash; + _adapter *adapter; + rtw_rcu_head rcu; +}; + +#define RTW_WDS_GPTR_EXPIRE (2 * HZ) + +/* Maximum number of gptrs per interface */ +#define RTW_WDS_MAX_GPTRS 1024 + +#ifdef PLATFORM_LINUX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) +static void rtw_wgptr_free_rcu(struct rtw_wds_gptr *wgptr) +{ + kfree_rcu(wgptr, rcu); + rtw_mstat_update(MSTAT_TYPE_PHY, MSTAT_FREE, sizeof(struct rtw_wds_gptr)); +} +#else +static void rtw_wgptr_free_rcu_callback(rtw_rcu_head *head) +{ + struct rtw_wds_gptr *wgptr; + + wgptr = container_of(head, struct rtw_wds_gptr, rcu); + rtw_mfree(wgptr, sizeof(struct rtw_wds_gptr)); +} + +static void rtw_wgptr_free_rcu(struct rtw_wds_gptr *wgptr) +{ + call_rcu(&wgptr->rcu, rtw_wgptr_free_rcu_callback); +} +#endif +#endif /* PLATFORM_LINUX */ + +static void rtw_wds_gptr_free_rcu(struct rtw_wds_gptr_table *tbl, struct rtw_wds_gptr *wgptr) +{ + _adapter *adapter = wgptr->adapter; + + ATOMIC_DEC(&adapter->wds_gpt_record_num); + + rtw_wgptr_free_rcu(wgptr); +} + +static u32 rtw_wds_gptr_table_hash(const void *addr, u32 len, u32 seed) +{ + /* Use last four bytes of hw addr as hash index */ + return jhash_1word(*(u32 *)(addr+2), seed); +} + +static const rtw_rhashtable_params rtw_wds_gptr_rht_params = { + .nelem_hint = 2, + .automatic_shrinking = true, + .key_len = ETH_ALEN, + .key_offset = offsetof(struct rtw_wds_gptr, src), + .head_offset = offsetof(struct rtw_wds_gptr, rhash), + .hashfn = rtw_wds_gptr_table_hash, +}; + +static void rtw_wds_gptr_rht_free(void *ptr, void *tblptr) +{ + struct rtw_wds_gptr *wgptr = ptr; + struct rtw_wds_gptr_table *tbl = tblptr; + + rtw_wds_gptr_free_rcu(tbl, wgptr); +} + +static struct rtw_wds_gptr_table *rtw_wds_gptr_table_alloc(void) +{ + struct rtw_wds_gptr_table *newtbl; + + newtbl = rtw_malloc(sizeof(struct rtw_wds_gptr_table)); + if (!newtbl) + return NULL; + + return newtbl; +} + +static void rtw_wds_gptr_table_free(struct rtw_wds_gptr_table *tbl) +{ + rtw_rhashtable_free_and_destroy(&tbl->rhead, + rtw_wds_gptr_rht_free, tbl); + rtw_mfree(tbl, sizeof(struct rtw_wds_gptr_table)); +} + +static struct rtw_wds_gptr *rtw_wds_gptr_lookup(_adapter *adapter, const u8 *src) +{ + struct rtw_wds_gptr_table *tbl = adapter->wds_gpt_records; + + if (!tbl) + return NULL; + + return rtw_rhashtable_lookup_fast(&tbl->rhead, src, rtw_wds_gptr_rht_params); +} + +/** + * Locking: must be called within a read rcu section. + */ +static struct rtw_wds_gptr *rtw_wds_gptr_lookup_by_idx(_adapter *adapter, int idx) +{ + int i = 0, ret; + struct rtw_wds_gptr_table *tbl = adapter->wds_gpt_records; + struct rtw_wds_gptr *wgptr = NULL; + rtw_rhashtable_iter iter; + + if (!tbl) + return NULL; + + ret = rtw_rhashtable_walk_enter(&tbl->rhead, &iter); + if (ret) + return NULL; + + ret = rtw_rhashtable_walk_start(&iter); + if (ret && ret != -EAGAIN) + goto err; + + while ((wgptr = rtw_rhashtable_walk_next(&iter))) { + if (IS_ERR(wgptr) && PTR_ERR(wgptr) == -EAGAIN) + continue; + if (IS_ERR(wgptr)) + break; + if (i++ == idx) + break; + } +err: + rtw_rhashtable_walk_stop(&iter); + rtw_rhashtable_walk_exit(&iter); + + if (IS_ERR(wgptr) || !wgptr) + return NULL; + + return wgptr; +} + +void dump_wgptr(void *sel, _adapter *adapter) +{ + struct rtw_wds_gptr *wgptr; + int idx = 0; + char src[ETH_ALEN]; + u32 age_ms; + + RTW_PRINT_SEL(sel, "num:%d\n", ATOMIC_READ(&adapter->wds_gpt_record_num)); + RTW_PRINT_SEL(sel, "%-17s %-6s\n" + , "src", "age" + ); + + do { + rtw_rcu_read_lock(); + + wgptr = rtw_wds_gptr_lookup_by_idx(adapter, idx); + if (wgptr) { + _rtw_memcpy(src, wgptr->src, ETH_ALEN); + age_ms = rtw_get_passing_time_ms(wgptr->last_update); + } + + rtw_rcu_read_unlock(); + + if (wgptr) { + RTW_PRINT_SEL(sel, MAC_FMT" %6u\n" + , MAC_ARG(src) + , age_ms < 999999 ? age_ms : 999999 + ); + } + + idx++; + } while (wgptr); +} + +static struct rtw_wds_gptr *rtw_wds_gptr_new(_adapter *adapter, const u8 *src) +{ + struct rtw_wds_gptr *new_wgptr; + + new_wgptr = rtw_zmalloc(sizeof(struct rtw_wds_gptr)); + if (!new_wgptr) + return NULL; + + new_wgptr->adapter = adapter; + _rtw_memcpy(new_wgptr->src, src, ETH_ALEN); + new_wgptr->last_update = rtw_get_current_time(); + + return new_wgptr; +} + +static struct rtw_wds_gptr *rtw_wds_gptr_add(_adapter *adapter, const u8 *src) +{ + struct rtw_wds_gptr_table *tbl = adapter->wds_gpt_records; + struct rtw_wds_gptr *wgptr, *new_wgptr; + int ret; + + if (!tbl) + return ERR_PTR(-ENOTSUPP); + + if (ATOMIC_INC_UNLESS(&adapter->wds_gpt_record_num, RTW_WDS_MAX_PATHS) == 0) + return ERR_PTR(-ENOSPC); + + new_wgptr = rtw_wds_gptr_new(adapter, src); + if (!new_wgptr) + return ERR_PTR(-ENOMEM); + + do { + ret = rtw_rhashtable_lookup_insert_fast(&tbl->rhead, + &new_wgptr->rhash, + rtw_wds_gptr_rht_params); + + if (ret == -EEXIST) + wgptr = rtw_rhashtable_lookup_fast(&tbl->rhead, + src, + rtw_wds_gptr_rht_params); + + } while (unlikely(ret == -EEXIST && !wgptr)); + + if (ret && ret != -EEXIST) + return ERR_PTR(ret); + + /* At this point either new_wgptr was added, or we found a + * matching entry already in the table; in the latter case + * free the unnecessary new entry. + */ + if (ret == -EEXIST) { + rtw_mfree(new_wgptr, sizeof(struct rtw_wds_gptr)); + new_wgptr = wgptr; + } + + return new_wgptr; +} + +bool rtw_rx_wds_gptr_check(_adapter *adapter, const u8 *src) +{ + struct rtw_wds_gptr *wgptr; + bool ret = 0; + + rtw_rcu_read_lock(); + + wgptr = rtw_wds_gptr_lookup(adapter, src); + if (wgptr) + ret = rtw_time_after(wgptr->last_update + RTW_WDS_GPTR_EXPIRE, rtw_get_current_time()); + + rtw_rcu_read_unlock(); + + return ret; +} + +void rtw_tx_wds_gptr_update(_adapter *adapter, const u8 *src) +{ + struct rtw_wds_gptr *wgptr; + + rtw_rcu_read_lock(); + wgptr = rtw_wds_gptr_lookup(adapter, src); + if (!wgptr) + rtw_wds_gptr_add(adapter, src); + else + wgptr->last_update = rtw_get_current_time(); + rtw_rcu_read_unlock(); +} + +static void __rtw_wds_gptr_del(struct rtw_wds_gptr_table *tbl, struct rtw_wds_gptr *wgptr) +{ + rtw_rhashtable_remove_fast(&tbl->rhead, &wgptr->rhash, rtw_wds_gptr_rht_params); + rtw_wds_gptr_free_rcu(tbl, wgptr); +} + +void rtw_wds_gptr_expire(_adapter *adapter) +{ + struct rtw_wds_gptr_table *tbl = adapter->wds_gpt_records; + struct rtw_wds_gptr *wgptr; + rtw_rhashtable_iter iter; + int ret; + + if (!tbl) + return; + + ret = rtw_rhashtable_walk_enter(&tbl->rhead, &iter); + if (ret) + return; + + ret = rtw_rhashtable_walk_start(&iter); + if (ret && ret != -EAGAIN) + goto out; + + while ((wgptr = rtw_rhashtable_walk_next(&iter))) { + if (IS_ERR(wgptr) && PTR_ERR(wgptr) == -EAGAIN) + continue; + if (IS_ERR(wgptr)) + break; + if (rtw_time_after(rtw_get_current_time(), wgptr->last_update + RTW_WDS_GPTR_EXPIRE)) + __rtw_wds_gptr_del(tbl, wgptr); + } + +out: + rtw_rhashtable_walk_stop(&iter); + rtw_rhashtable_walk_exit(&iter); +} + +int rtw_wds_gptr_tbl_init(_adapter *adapter) +{ + struct rtw_wds_gptr_table *tbl; + int ret; + + tbl = rtw_wds_gptr_table_alloc(); + if (!tbl) + return -ENOMEM; + + rtw_rhashtable_init(&tbl->rhead, &rtw_wds_gptr_rht_params); + + ATOMIC_SET(&adapter->wds_gpt_record_num, 0); + adapter->wds_gpt_records = tbl; + + return 0; +} + +void rtw_wds_gptr_tbl_unregister(_adapter *adapter) +{ + if (adapter->wds_gpt_records) { + rtw_wds_gptr_table_free(adapter->wds_gpt_records); + adapter->wds_gpt_records = NULL; + } +} +#endif /* defined(CONFIG_RTW_WDS) */ + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/wds/rtw_wds.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/wds/rtw_wds.h new file mode 100644 index 000000000000..2a161da88a06 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/core/wds/rtw_wds.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2019 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#ifndef __RTW_WDS_H_ +#define __RTW_WDS_H_ + +#ifdef CONFIG_AP_MODE +struct rtw_wds_path { + u8 dst[ETH_ALEN]; + rtw_rhash_head rhash; + _adapter *adapter; + struct sta_info __rcu *next_hop; + rtw_rcu_head rcu; + systime last_update; +}; + +struct rtw_wds_table { + rtw_rhashtable rhead; +}; + +#define RTW_WDS_PATH_EXPIRE (600 * HZ) + +/* Maximum number of paths per interface */ +#define RTW_WDS_MAX_PATHS 1024 + +int rtw_wds_nexthop_lookup(_adapter *adapter, const u8 *da, u8 *ra); + +struct rtw_wds_path *rtw_wds_path_lookup(_adapter *adapter, const u8 *dst); +void dump_wpath(void *sel, _adapter *adapter); + +void rtw_wds_path_expire(_adapter *adapter); + +struct rtw_wds_path *rtw_wds_path_add(_adapter *adapter, const u8 *dst, struct sta_info *next_hop); +void rtw_wds_path_assign_nexthop(struct rtw_wds_path *path, struct sta_info *sta); + +int rtw_wds_pathtbl_init(_adapter *adapter); +void rtw_wds_pathtbl_unregister(_adapter *adapter); + +void rtw_wds_path_flush_by_nexthop(struct sta_info *sta); +#endif /* CONFIG_AP_MODE */ + +struct rtw_wds_gptr_table { + rtw_rhashtable rhead; +}; + +void dump_wgptr(void *sel, _adapter *adapter); +bool rtw_rx_wds_gptr_check(_adapter *adapter, const u8 *src); +void rtw_tx_wds_gptr_update(_adapter *adapter, const u8 *src); +void rtw_wds_gptr_expire(_adapter *adapter); +int rtw_wds_gptr_tbl_init(_adapter *adapter); +void rtw_wds_gptr_tbl_unregister(_adapter *adapter); + +#endif /* __RTW_WDSH_ */ + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtc8821c1ant.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtc8821c1ant.c index 64005258c233..274cd5c3ca8f 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtc8821c1ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtc8821c1ant.c @@ -26,10 +26,10 @@ const char *const glbt_info_src_8821c_1ant[] = { "BT Info[bt auto report]", }; -u32 glcoex_ver_date_8821c_1ant = 20200414; -u32 glcoex_ver_8821c_1ant = 0x4e; -u32 glcoex_ver_btdesired_8821c_1ant = 0x4a; -u32 glcoex_ver_wldesired_8821c_1ant = 0x17000e; +u32 glcoex_ver_date_8821c_1ant = 20200730; +u32 glcoex_ver_8821c_1ant = 0x51; +u32 glcoex_ver_btdesired_8821c_1ant = 0x50; +u32 glcoex_ver_wldesired_8821c_1ant = 0x170011; #if 0 static @@ -247,7 +247,7 @@ halbtc8821c1ant_limited_rx(struct btc_coexist *btc, boolean force_exec, boolean rej_ap_agg_pkt, boolean bt_ctrl_agg_buf_size, u8 agg_buf_size) { -#if 0 +#if 1 struct coex_sta_8821c_1ant *coex_sta = &btc->coex_sta_8821c_1ant; boolean reject_rx_agg = rej_ap_agg_pkt; boolean bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size; @@ -277,12 +277,28 @@ static void halbtc8821c1ant_ccklock_action(struct btc_coexist *btc) { struct coex_sta_8821c_1ant *coex_sta = &btc->coex_sta_8821c_1ant; + struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; u8 h2c_parameter[2] = {0}; static u8 cnt; boolean wifi_busy = FALSE; btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + if (bt_link_info->a2dp_exist && coex_sta->bt_ble_hid_exist) { + if (!coex_sta->is_no_wl_5ms_extend) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], set h2c 0x69 opcode 12 to turn off 5ms WL slot extend!!\n"); + BTC_TRACE(trace_buf); + + h2c_parameter[0] = 0xc; + h2c_parameter[1] = 0x1; + btc->btc_fill_h2c(btc, 0x69, 2, h2c_parameter); + coex_sta->is_no_wl_5ms_extend = TRUE; + cnt = 0; + } + return; + } + if (!coex_sta->gl_wifi_busy || coex_sta->wl_iot_peer == BTC_IOT_PEER_CISCO) { cnt = 0; @@ -1168,15 +1184,17 @@ void halbtc8821c1ant_update_wifi_link_info(struct btc_coexist *btc, u8 reason) if (coex_sta->hid_exist || coex_sta->hid_pair_cnt > 0 || coex_sta->sco_exist) { halbtc8821c1ant_limited_tx(btc, NM_EXCU, TRUE, TRUE); - halbtc8821c1ant_limited_rx(btc, NM_EXCU, FALSE, TRUE, - 16); + if (coex_sta->bt_ble_hid_exist && + coex_sta->wl_iot_peer != BTC_IOT_PEER_ATHEROS) + halbtc8821c1ant_limited_rx(btc, NM_EXCU, FALSE, + TRUE, 4); } else { halbtc8821c1ant_limited_tx(btc, NM_EXCU, TRUE, FALSE); halbtc8821c1ant_limited_rx(btc, NM_EXCU, FALSE, TRUE, 64); } - } + } /* coex-276 P2P-Go beacon request can't release issue * Only PCIe/USB can set 0x454[6] = 1 to solve this issue, * WL SDIO/USB interface need driver support. @@ -3170,20 +3188,25 @@ void halbtc8821c1ant_action_bt_acl_busy(struct btc_coexist *btc) /* HID+A2DP */ /*4-slot will not be applied when AP is CISCO*/ - if (coex_sta->wl_iot_peer != BTC_IOT_PEER_CISCO) + if (coex_sta->wl_iot_peer == BTC_IOT_PEER_CISCO || + coex_sta->bt_ble_hid_exist) + slot_type = 0; + else slot_type = TDMA_4SLOT; if (coex_sta->connect_ap_period_cnt > 0 || !wifi_busy) { halbtc8821c1ant_table(btc, FC_EXCU, 4); halbtc8821c1ant_tdma(btc, NM_EXCU, TRUE, 26 | slot_type); - } else if (coex_sta->bt_418_hid_exist || - coex_sta->bt_ble_hid_exist) { + } else if (coex_sta->bt_418_hid_exist) { halbtc8821c1ant_table(btc, FC_EXCU, 4); halbtc8821c1ant_wltoggle_table(btc, NM_EXCU, 1, 0xaa, 0x5a, 0x5a, 0x5a); halbtc8821c1ant_tdma(btc, NM_EXCU, TRUE, 39 | slot_type); + } else if (coex_sta->bt_ble_hid_exist) { + halbtc8821c1ant_tdma(btc, NM_EXCU, TRUE, + 8 | slot_type); } else { halbtc8821c1ant_table(btc, FC_EXCU, 4); halbtc8821c1ant_tdma(btc, NM_EXCU, TRUE, @@ -3472,6 +3495,7 @@ void halbtc8821c1ant_run_coex(struct btc_coexist *btc, u8 reason) { struct coex_sta_8821c_1ant *coex_sta = &btc->coex_sta_8821c_1ant; struct coex_dm_8821c_1ant *coex_dm = &btc->coex_dm_8821c_1ant; + struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; struct wifi_link_info_8821c_1ant *wifi_link_info_ext = &btc->wifi_link_info_8821c_1ant; boolean wifi_connected = FALSE, wifi_32k = FALSE; @@ -3608,13 +3632,16 @@ void halbtc8821c1ant_run_coex(struct btc_coexist *btc, u8 reason) halbtc8821c1ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, BT_8821C_1ANT_PHASE_2G); - /*For Asus airpods 2 + HID glitch issue*/ - if (coex_sta->bt_a2dp_vendor_id == 0x4c && coex_sta->is_bt_multi_link) - halbtc8821c1ant_write_scbd(btc, BT_8821C_1ANT_SCBD_BTCQDDR, - FALSE); + /*For Asus airpods 2 + HID glitch issue (COEX-303) + For HP LE HID + A2DP issue (COEX-291)*/ + if ((coex_sta->bt_a2dp_vendor_id == 0x4c && coex_sta->is_bt_multi_link) + || (coex_sta->bt_ble_hid_exist && bt_link_info->a2dp_exist)) + halbtc8821c1ant_write_scbd(btc, BT_8821C_1ANT_SCBD_BTCQDDR, + FALSE); else - halbtc8821c1ant_write_scbd(btc, BT_8821C_1ANT_SCBD_BTCQDDR, - TRUE); + halbtc8821c1ant_write_scbd(btc, BT_8821C_1ANT_SCBD_BTCQDDR, + TRUE); + if (coex_sta->bt_disabled) { BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, @@ -5082,12 +5109,6 @@ void ex_halbtc8821c1ant_bt_info_notify(struct btc_coexist *btc, u8 *tmp_buf, if (coex_sta->hid_pair_cnt > 0 && coex_sta->hid_busy_num >= 2) { coex_sta->bt_418_hid_exist = TRUE; - } else if (coex_sta->hid_busy_num == 1 && - coex_sta->bt_ctr_ok && - (coex_sta->high_priority_rx + 100 < - coex_sta->high_priority_tx) && - coex_sta->high_priority_rx < 100) { - coex_sta->bt_ble_hid_exist = TRUE; } else if (coex_sta->hid_pair_cnt == 0 || coex_sta->hid_busy_num == 1) { coex_sta->bt_418_hid_exist = FALSE; @@ -5132,10 +5153,19 @@ void ex_halbtc8821c1ant_bt_info_notify(struct btc_coexist *btc, u8 *tmp_buf, else coex_sta->is_bt_multi_link = FALSE; - if (coex_sta->bt_info_hb1 & BIT(0)) + if (coex_sta->bt_info_lb2 & BIT(5)) { + if (coex_sta->bt_info_hb1 & BIT(0)) { + /*BLE HID*/ + coex_sta->bt_ble_hid_exist = TRUE; + coex_sta->is_hid_rcu = FALSE; + } + } else if (coex_sta->bt_info_hb1 & BIT(0)) { + /*RCU*/ coex_sta->is_hid_rcu = TRUE; - else + } else { + coex_sta->bt_ble_hid_exist = FALSE; coex_sta->is_hid_rcu = FALSE; + } if (coex_sta->bt_info_hb1 & BIT(5)) coex_sta->is_ble_scan_en = TRUE; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtc8821c2ant.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtc8821c2ant.c index 7500961970ec..0297613ecd8d 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtc8821c2ant.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtc8821c2ant.c @@ -1,5652 +1,5661 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2016 - 2017 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - *****************************************************************************/ - -#include "mp_precomp.h" - -#if (BT_SUPPORT == 1 && COEX_SUPPORT == 1) - -#if (RTL8821C_SUPPORT == 1) -static u8 *trace_buf = &gl_btc_trace_buf[0]; - -const char *const glbt_info_src_8821c_2ant[] = { - "BT Info[wifi fw]", - "BT Info[bt rsp]", - "BT Info[bt auto report]", -}; - -u32 glcoex_ver_date_8821c_2ant = 20200414; -u32 glcoex_ver_8821c_2ant = 0x4e; -u32 glcoex_ver_btdesired_8821c_2ant = 0x4a; -u32 glcoex_ver_wldesired_8821c_2ant = 0x17000e; - -static -u8 halbtc8821c2ant_bt_rssi_state(struct btc_coexist *btc, - u8 *ppre_bt_rssi_state, u8 level_num, - u8 rssi_thresh, u8 rssi_thresh1) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - s32 bt_rssi = 0; - u8 bt_rssi_state = *ppre_bt_rssi_state; - - bt_rssi = coex_sta->bt_rssi; - - if (level_num == 2) { - if ((*ppre_bt_rssi_state == BTC_RSSI_STATE_LOW) || - (*ppre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { - if (bt_rssi >= (rssi_thresh + - BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT)) - bt_rssi_state = BTC_RSSI_STATE_HIGH; - else - bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; - } else { - if (bt_rssi < rssi_thresh) - bt_rssi_state = BTC_RSSI_STATE_LOW; - else - bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; - } - } else if (level_num == 3) { - if (rssi_thresh > rssi_thresh1) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Rssi thresh error!!\n"); - BTC_TRACE(trace_buf); - return *ppre_bt_rssi_state; - } - - if ((*ppre_bt_rssi_state == BTC_RSSI_STATE_LOW) || - (*ppre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { - if (bt_rssi >= (rssi_thresh + - BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT)) - bt_rssi_state = BTC_RSSI_STATE_MEDIUM; - else - bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; - } else if ((*ppre_bt_rssi_state == BTC_RSSI_STATE_MEDIUM) || - (*ppre_bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { - if (bt_rssi >= (rssi_thresh1 + - BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT)) - bt_rssi_state = BTC_RSSI_STATE_HIGH; - else if (bt_rssi < rssi_thresh) - bt_rssi_state = BTC_RSSI_STATE_LOW; - else - bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; - } else { - if (bt_rssi < rssi_thresh1) - bt_rssi_state = BTC_RSSI_STATE_MEDIUM; - else - bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; - } - } - - *ppre_bt_rssi_state = bt_rssi_state; - - return bt_rssi_state; -} - -static -u8 halbtc8821c2ant_wifi_rssi_state(struct btc_coexist *btc, - u8 *pprewifi_rssi_state, - u8 level_num, - u8 rssi_thresh, u8 rssi_thresh1) -{ - s32 wifi_rssi = 0; - u8 wifi_rssi_state = *pprewifi_rssi_state; - - btc->btc_get(btc, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); - - if (level_num == 2) { - if ((*pprewifi_rssi_state == BTC_RSSI_STATE_LOW) || - (*pprewifi_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { - if (wifi_rssi >= (rssi_thresh + - BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT)) - wifi_rssi_state = BTC_RSSI_STATE_HIGH; - else - wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; - } else { - if (wifi_rssi < rssi_thresh) - wifi_rssi_state = BTC_RSSI_STATE_LOW; - else - wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; - } - } else if (level_num == 3) { - if (rssi_thresh > rssi_thresh1) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi RSSI thresh error!!\n"); - BTC_TRACE(trace_buf); - return *pprewifi_rssi_state; - } - - if ((*pprewifi_rssi_state == BTC_RSSI_STATE_LOW) || - (*pprewifi_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { - if (wifi_rssi >= (rssi_thresh + - BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT)) - wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; - else - wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; - } else if ((*pprewifi_rssi_state == BTC_RSSI_STATE_MEDIUM) || - (*pprewifi_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { - if (wifi_rssi >= (rssi_thresh1 + - BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT)) - wifi_rssi_state = BTC_RSSI_STATE_HIGH; - else if (wifi_rssi < rssi_thresh) - wifi_rssi_state = BTC_RSSI_STATE_LOW; - else - wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; - } else { - if (wifi_rssi < rssi_thresh1) - wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; - else - wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; - } - } - - *pprewifi_rssi_state = wifi_rssi_state; - - return wifi_rssi_state; -} - -static void -halbtc8821c2ant_limited_tx(struct btc_coexist *btc, boolean force_exec, - boolean tx_limit_en, boolean ampdu_limit_en) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct wifi_link_info_8821c_2ant *wifi_link_info_ext = - &btc->wifi_link_info_8821c_2ant; - boolean wifi_under_b_mode = FALSE; - - /* Force Max Tx retry limit = 8*/ - if (!coex_sta->wl_tx_limit_en) { - coex_sta->wl_0x430_backup = btc->btc_read_4byte(btc, 0x430); - coex_sta->wl_0x434_backup = btc->btc_read_4byte(btc, 0x434); - coex_sta->wl_0x42a_backup = btc->btc_read_2byte(btc, 0x42a); - } - - if (!coex_sta->wl_ampdu_limit_en) - coex_sta->wl_0x455_backup = btc->btc_read_1byte(btc, 0x455); - - if (!force_exec && tx_limit_en == coex_sta->wl_tx_limit_en && - ampdu_limit_en == coex_sta->wl_ampdu_limit_en) - return; - - coex_sta->wl_tx_limit_en = tx_limit_en; - coex_sta->wl_ampdu_limit_en = ampdu_limit_en; - - if (tx_limit_en) { - /* Set BT polluted packet on for Tx rate adaptive not - * including Tx retry break by PTA, 0x45c[19] =1 - * Set queue life time to avoid can't reach tx retry limit - * if tx is always break by GNT_BT. - */ - btc->btc_write_1byte_bitmask(btc, 0x45e, 0x8, 0x1); - btc->btc_write_1byte_bitmask(btc, 0x426, 0xf, 0xf); - - /* Max Tx retry limit = 8*/ - btc->btc_write_2byte(btc, 0x42a, 0x0808); - - btc->btc_get(btc, BTC_GET_BL_WIFI_UNDER_B_MODE, - &wifi_under_b_mode); - - /* Auto rate fallback step within 8 retry*/ - if (wifi_under_b_mode) { - btc->btc_write_4byte(btc, 0x430, 0x1000000); - btc->btc_write_4byte(btc, 0x434, 0x1010101); - } else { - btc->btc_write_4byte(btc, 0x430, 0x1000000); - btc->btc_write_4byte(btc, 0x434, 0x4030201); - } - } else { - /* Set BT polluted packet on for Tx rate adaptive not - *including Tx retry break by PTA, 0x45c[19] =1 - */ - btc->btc_write_1byte_bitmask(btc, 0x45e, 0x8, 0x0); - btc->btc_write_1byte_bitmask(btc, 0x426, 0xf, 0x0); - - /* Set queue life time to avoid can't reach tx retry limit - * if tx is always break by GNT_BT. - */ - if (wifi_link_info_ext->num_of_active_port == 1) - btc->btc_write_1byte_bitmask(btc, 0x426, 0xf, 0x0); - - /* Recovery Max Tx retry limit*/ - btc->btc_write_2byte(btc, 0x42a, coex_sta->wl_0x42a_backup); - btc->btc_write_4byte(btc, 0x430, coex_sta->wl_0x430_backup); - btc->btc_write_4byte(btc, 0x434, coex_sta->wl_0x434_backup); - } - - if (ampdu_limit_en) - btc->btc_write_1byte(btc, 0x455, 0x20); - else - btc->btc_write_1byte(btc, 0x455, coex_sta->wl_0x455_backup); -} - -static void -halbtc8821c2ant_limited_rx(struct btc_coexist *btc, boolean force_exec, - boolean rej_ap_agg_pkt, boolean bt_ctrl_agg_buf_size, - u8 agg_buf_size) -{ -#if 0 - struct coex_sta_8822b_2ant *coex_sta = &btc->coex_sta_8822b_2ant; - boolean reject_rx_agg = rej_ap_agg_pkt; - boolean bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size; - u8 rx_agg_size = agg_buf_size; - - if (!force_exec && - bt_ctrl_agg_buf_size == coex_sta->wl_rxagg_limit_en && - agg_buf_size == coex_sta->wl_rxagg_size) - return; - - coex_sta->wl_rxagg_limit_en = bt_ctrl_agg_buf_size; - coex_sta->wl_rxagg_size = agg_buf_size; - - /*btc->btc_set(btc, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &reject_rx_agg);*/ - /* decide BT control aggregation buf size or not */ - btc->btc_set(btc, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bt_ctrl_rx_agg_size); - /* aggregation buf size, only work when BT control Rx aggregation size*/ - btc->btc_set(btc, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size); - /* real update aggregation setting */ - btc->btc_set(btc, BTC_SET_ACT_AGGREGATE_CTRL, NULL); -#endif -} - -static void -halbtc8821c2ant_ccklock_action(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - u8 h2c_parameter[2] = {0}; - static u8 cnt; - boolean wifi_busy = FALSE; - - btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); - - if (!coex_sta->gl_wifi_busy || - coex_sta->wl_iot_peer == BTC_IOT_PEER_CISCO) { - cnt = 0; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi is not busy or CISCO AP, return!!\n"); - BTC_TRACE(trace_buf); - return; - } - - if (!coex_sta->is_no_wl_5ms_extend && coex_sta->force_lps_ctrl && - !coex_sta->cck_lock_ever) { - if (coex_sta->wl_fw_dbg_info[7] <= 5 && wifi_busy) - cnt++; - else - cnt = 0; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], 5ms WL slot extend cnt = %d!!\n", cnt); - BTC_TRACE(trace_buf); - - if (cnt == 7) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], set h2c 0x69 opcode 12 to turn off 5ms WL slot extend!!\n"); - BTC_TRACE(trace_buf); - - h2c_parameter[0] = 0xc; - h2c_parameter[1] = 0x1; - btc->btc_fill_h2c(btc, 0x69, 2, h2c_parameter); - coex_sta->is_no_wl_5ms_extend = TRUE; - cnt = 0; - } - } else if (coex_sta->is_no_wl_5ms_extend && coex_sta->cck_lock) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], set h2c 0x69 opcode 12 to turn on 5ms WL slot extend!!\n"); - BTC_TRACE(trace_buf); - - h2c_parameter[0] = 0xc; - h2c_parameter[1] = 0x0; - btc->btc_fill_h2c(btc, 0x69, 2, h2c_parameter); - coex_sta->is_no_wl_5ms_extend = FALSE; - } -} - -static void -halbtc8821c2ant_ccklock_detect(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - struct wifi_link_info_8821c_2ant *link_info_ext = - &btc->wifi_link_info_8821c_2ant; - boolean is_cck_lock_rate = FALSE; - - if (coex_dm->bt_status == BTC_BTSTATUS_INQ_PAGE || - coex_sta->is_setup_link) - return; - - if (coex_sta->wl_rx_rate <= BTC_CCK_2 || - coex_sta->wl_rts_rx_rate <= BTC_CCK_2) - is_cck_lock_rate = TRUE; - - if (link_info_ext->is_connected && coex_sta->gl_wifi_busy && - (coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_ACL_BUSY || - coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_ACL_SCO_BUSY || - coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_SCO_BUSY)) { - if (coex_sta->wl_rx_rate == BTC_CCK_5_5 || - coex_sta->wl_rx_rate == BTC_OFDM_6 || - coex_sta->wl_rx_rate == BTC_MCS_0) { - coex_sta->cck_lock_warn = TRUE; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], cck lock warning...\n"); - BTC_TRACE(trace_buf); - } else if ((coex_sta->wl_rx_rate == BTC_CCK_1) || - (coex_sta->wl_rx_rate == BTC_CCK_2) || - (coex_sta->wl_rts_rx_rate == BTC_CCK_1) || - (coex_sta->wl_rts_rx_rate == BTC_CCK_2)) { - coex_sta->cck_lock = TRUE; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], cck locking...\n"); - BTC_TRACE(trace_buf); - } else { - coex_sta->cck_lock_warn = FALSE; - coex_sta->cck_lock = FALSE; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], cck unlock...\n"); - BTC_TRACE(trace_buf); - } - } else { - coex_sta->cck_lock_warn = FALSE; - coex_sta->cck_lock = FALSE; - } -} - -static void -halbtc8821c2ant_set_tdma_timer_base(struct btc_coexist *btc, u8 type) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - u16 tbtt_interval = 100; - u8 h2c_para[2] = {0xb, 0x1}; - - btc->btc_get(btc, BTC_GET_U2_BEACON_PERIOD, &tbtt_interval); - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], tbtt_interval = %d\n", tbtt_interval); - BTC_TRACE(trace_buf); - - /* Add for JIRA coex-256 */ - if (type == 3 && tbtt_interval >= 100) { /* 50ms-slot */ - if (coex_sta->tdma_timer_base == 3) - return; - - h2c_para[1] = (tbtt_interval / 50) - 1; - h2c_para[1] = h2c_para[1] | 0xc0; /* 50ms-slot */ - coex_sta->tdma_timer_base = 3; - } else if (tbtt_interval < 80 && tbtt_interval > 0) { - if (coex_sta->tdma_timer_base == 2) - return; - h2c_para[1] = (100 / tbtt_interval); - - if (100 % tbtt_interval != 0) - h2c_para[1] = h2c_para[1] + 1; - - h2c_para[1] = h2c_para[1] & 0x3f; - coex_sta->tdma_timer_base = 2; - } else if (tbtt_interval >= 180) { - if (coex_sta->tdma_timer_base == 1) - return; - h2c_para[1] = (tbtt_interval / 100); - - if (tbtt_interval % 100 <= 80) - h2c_para[1] = h2c_para[1] - 1; - - h2c_para[1] = h2c_para[1] & 0x3f; - h2c_para[1] = h2c_para[1] | 0x80; - coex_sta->tdma_timer_base = 1; - } else { - if (coex_sta->tdma_timer_base == 0) - return; - h2c_para[1] = 0x1; - coex_sta->tdma_timer_base = 0; - } - - btc->btc_fill_h2c(btc, 0x69, 2, h2c_para); - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], %s() h2c_0x69 = 0x%x\n", __func__, h2c_para[1]); - BTC_TRACE(trace_buf); -} - -static -void halbtc8821c2ant_coex_switch_thres(struct btc_coexist *btc, - u8 isolation_measuared) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - s8 interference_wl_tx = 0, interference_bt_tx = 0; - - interference_wl_tx = BT_8821C_2ANT_WIFI_MAX_TX_POWER - - isolation_measuared; - interference_bt_tx = BT_8821C_2ANT_BT_MAX_TX_POWER - - isolation_measuared; - - coex_sta->wifi_coex_thres = BT_8821C_2ANT_WIFI_RSSI_COEXSWITCH_THRES1; - coex_sta->wifi_coex_thres2 = BT_8821C_2ANT_WIFI_RSSI_COEXSWITCH_THRES2; - - coex_sta->bt_coex_thres = BT_8821C_2ANT_BT_RSSI_COEXSWITCH_THRES1; - coex_sta->bt_coex_thres2 = BT_8821C_2ANT_BT_RSSI_COEXSWITCH_THRES2; -} - -static -void halbtc8821c2ant_low_penalty_ra(struct btc_coexist *btc, - boolean force_exec, boolean low_penalty_ra, - u8 thres) -{ - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - static u8 cur_thres; - - if (!force_exec) { - if (low_penalty_ra == coex_dm->cur_low_penalty_ra && - thres == cur_thres) - return; - } - - if (low_penalty_ra) - btc->btc_phydm_modify_RA_PCR_threshold(btc, 0, thres); - else - btc->btc_phydm_modify_RA_PCR_threshold(btc, 0, 0); - - coex_dm->cur_low_penalty_ra = low_penalty_ra; - cur_thres = thres; -} - -static -void halbtc8821c2ant_set_antdiv_hwsw(struct btc_coexist *btc, - boolean force_exec, boolean is_hw_div) -{ - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - static u8 pre_antdiv_type; - - coex_dm->cur_antdiv_type = ((is_hw_div) ? 1 : 0); - - if (!force_exec) { - if (coex_dm->cur_antdiv_type == pre_antdiv_type) - return; - } - - btc->btc_phydm_modify_antdiv_hwsw(btc, coex_dm->cur_antdiv_type); - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], %s = %d!!\n", __func__, - coex_dm->cur_antdiv_type); - BTC_TRACE(trace_buf); - - pre_antdiv_type = coex_dm->cur_antdiv_type; -} - -static boolean -halbtc8821c2ant_freerun_check(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW; - static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW; - u8 wifi_rssi_state, bt_rssi_state; - - wifi_rssi_state = - halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2, - coex_sta->wifi_coex_thres, 0); - - bt_rssi_state = - halbtc8821c2ant_bt_rssi_state(btc, &pre_bt_rssi_state, 2, - coex_sta->bt_coex_thres, 0); - - if (btc->board_info.ant_distance >= 40) - return TRUE; - - if (btc->board_info.ant_distance <= 5) - return FALSE; - - /* ant_distance = 5 ~ 40 */ - if (BTC_RSSI_HIGH(wifi_rssi_state) && - BTC_RSSI_HIGH(bt_rssi_state) && coex_sta->gl_wifi_busy) - return TRUE; - else - return FALSE; -} - -static -void halbtc8821c2ant_write_scbd(struct btc_coexist *btc, u16 bitpos, - boolean state) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - static u16 originalval = 0x8002, preval; - - if (state) - originalval = originalval | bitpos; - else - originalval = originalval & (~bitpos); - - coex_sta->score_board_WB = originalval; - - if (originalval != preval) { - preval = originalval; - btc->btc_write_2byte(btc, 0xaa, originalval); - } else { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], %s: return for nochange\n", __func__); - BTC_TRACE(trace_buf); - } -} - -static -void halbtc8821c2ant_read_scbd(struct btc_coexist *btc, u16 *score_board_val) -{ - *score_board_val = (btc->btc_read_2byte(btc, 0xaa)) & 0x7fff; -} - -static -void halbtc8821c2ant_query_bt_info(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - u8 h2c_parameter[1] = {0}; - - if (coex_sta->bt_disabled) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], No query BT info because BT is disabled!\n"); - BTC_TRACE(trace_buf); - return; - } - - h2c_parameter[0] |= BIT(0); /* trigger */ - - btc->btc_fill_h2c(btc, 0x61, 1, h2c_parameter); -} - -static -void halbtc8821c2ant_enable_gnt_to_gpio(struct btc_coexist *btc, - boolean isenable) -{ - static u8 bit_val[5] = {0, 0, 0, 0, 0}; - static boolean state; - - if (!btc->dbg_mode) - return; - - if (state == isenable) - return; - - state = isenable; - - if (isenable) { - /* enable GNT_WL, GNT_BT to GPIO for debug */ - btc->btc_write_1byte_bitmask(btc, 0x73, 0x8, 0x1); - - /* store original value */ - /*0x66[4] */ - bit_val[0] = (btc->btc_read_1byte(btc, 0x66) & BIT(4)) >> 4; - /*0x66[8] */ - bit_val[1] = (btc->btc_read_1byte(btc, 0x67) & BIT(0)); - /*0x40[19] */ - bit_val[2] = (btc->btc_read_1byte(btc, 0x42) & BIT(3)) >> 3; - /*0x64[15] */ - bit_val[3] = (btc->btc_read_1byte(btc, 0x65) & BIT(7)) >> 7; - /*0x70[18] */ - bit_val[4] = (btc->btc_read_1byte(btc, 0x72) & BIT(2)) >> 2; - - /* switch GPIO Mux */ - /*0x66[4] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x66, BIT(4), 0x0); - /*0x66[8] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x67, BIT(0), 0x0); - /*0x40[19] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x42, BIT(3), 0x0); - /*0x64[15] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x65, BIT(7), 0x0); - /*0x70[18] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x72, BIT(2), 0x0); - } else { - btc->btc_write_1byte_bitmask(btc, 0x73, 0x8, 0x0); - - /* Restore original value */ - /* switch GPIO Mux */ - /*0x66[4] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x66, BIT(4), bit_val[0]); - /*0x66[8] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x67, BIT(0), bit_val[1]); - /*0x40[19] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x42, BIT(3), bit_val[2]); - /*0x64[15] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x65, BIT(7), bit_val[3]); - /*0x70[18] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x72, BIT(2), bit_val[4]); - } -} - -static -boolean halbtc8821c2ant_monitor_bt_ctr(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - u32 reg_hp_txrx, reg_lp_txrx, u32tmp, cnt_bt_all; - u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0; - static u8 cnt_overhead; - static u32 cnt_bt_pre = 0; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; - boolean is_run_coex = FALSE; - - reg_hp_txrx = 0x770; - reg_lp_txrx = 0x774; - - u32tmp = btc->btc_read_4byte(btc, reg_hp_txrx); - reg_hp_tx = u32tmp & MASKLWORD; - reg_hp_rx = (u32tmp & MASKHWORD) >> 16; - - u32tmp = btc->btc_read_4byte(btc, reg_lp_txrx); - reg_lp_tx = u32tmp & MASKLWORD; - reg_lp_rx = (u32tmp & MASKHWORD) >> 16; - - coex_sta->high_priority_tx = reg_hp_tx; - coex_sta->high_priority_rx = reg_hp_rx; - coex_sta->low_priority_tx = reg_lp_tx; - coex_sta->low_priority_rx = reg_lp_rx; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Hi-Pri Rx/Tx: %d/%d, Lo-Pri Rx/Tx: %d/%d\n", - reg_hp_rx, reg_hp_tx, reg_lp_rx, reg_lp_tx); - - BTC_TRACE(trace_buf); - - /* reset counter */ - btc->btc_write_1byte(btc, 0x76e, 0xc); - - if (coex_sta->under_lps || coex_sta->under_ips || - (coex_sta->high_priority_tx == 65535 && - coex_sta->high_priority_rx == 65535 && - coex_sta->low_priority_tx == 65535 && - coex_sta->low_priority_rx == 65535)) - coex_sta->bt_ctr_ok = FALSE; - else - coex_sta->bt_ctr_ok = TRUE; - - if (!coex_sta->bt_ctr_ok) - return FALSE; - - if (coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE) { - if (coex_sta->high_priority_rx >= 15) { - if (cnt_overhead < 3) - cnt_overhead++; - if (cnt_overhead == 3) - coex_sta->is_hi_pri_rx_overhead = TRUE; - } else { - if (cnt_overhead > 0) - cnt_overhead--; - if (cnt_overhead == 0) - coex_sta->is_hi_pri_rx_overhead = FALSE; - } - } else { - coex_sta->is_hi_pri_rx_overhead = FALSE; - } - - if (coex_sta->low_priority_tx > 1150 && - !coex_sta->c2h_bt_inquiry_page) - coex_sta->pop_event_cnt++; - - if (coex_sta->sco_exist) { - if (coex_sta->high_priority_tx >= 400 && - coex_sta->high_priority_rx >= 400) - coex_sta->is_esco_mode = FALSE; - else - coex_sta->is_esco_mode = TRUE; - } - - if (bt_link_info->hid_only) { - if (coex_sta->low_priority_tx > 100) - coex_sta->is_hid_low_pri_tx_overhead = true; - else - coex_sta->is_hid_low_pri_tx_overhead = false; - } - - cnt_bt_all = coex_sta->high_priority_tx + - coex_sta->high_priority_rx + - coex_sta->low_priority_tx + - coex_sta->low_priority_rx; - - if ((cnt_bt_pre > (cnt_bt_all + 50) || - cnt_bt_all > (cnt_bt_pre + 50)) && - coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE) - is_run_coex = TRUE; - - cnt_bt_pre = cnt_bt_all; - - return is_run_coex; -} - -static -void halbtc8821c2ant_monitor_wifi_ctr(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - boolean wifi_busy = FALSE, wifi_scan = FALSE; - static u8 wl_noisy_count0, wl_noisy_count1 = 3, wl_noisy_count2; - u32 cnt_cck, fw_ver = 0; - static u8 cnt_ccklocking; - u8 h2c_parameter[1] = {0}; - - btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); - btc->btc_get(btc, BTC_GET_BL_WIFI_SCAN, &wifi_scan); - btc->btc_get(btc, BTC_GET_U4_WIFI_FW_VER, &fw_ver); - - /* Only enable for windows in old fw version (COEX-308) - * because 8821cu H2C 0x69 unknown fail @ linux +/****************************************************************************** + * + * Copyright(c) 2016 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#include "mp_precomp.h" + +#if (BT_SUPPORT == 1 && COEX_SUPPORT == 1) + +#if (RTL8821C_SUPPORT == 1) +static u8 *trace_buf = &gl_btc_trace_buf[0]; + +const char *const glbt_info_src_8821c_2ant[] = { + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +u32 glcoex_ver_date_8821c_2ant = 20200730; +u32 glcoex_ver_8821c_2ant = 0x51; +u32 glcoex_ver_btdesired_8821c_2ant = 0x50; +u32 glcoex_ver_wldesired_8821c_2ant = 0x170011; + +static +u8 halbtc8821c2ant_bt_rssi_state(struct btc_coexist *btc, + u8 *ppre_bt_rssi_state, u8 level_num, + u8 rssi_thresh, u8 rssi_thresh1) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + s32 bt_rssi = 0; + u8 bt_rssi_state = *ppre_bt_rssi_state; + + bt_rssi = coex_sta->bt_rssi; + + if (level_num == 2) { + if ((*ppre_bt_rssi_state == BTC_RSSI_STATE_LOW) || + (*ppre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + if (bt_rssi >= (rssi_thresh + + BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT)) + bt_rssi_state = BTC_RSSI_STATE_HIGH; + else + bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; + } else { + if (bt_rssi < rssi_thresh) + bt_rssi_state = BTC_RSSI_STATE_LOW; + else + bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + } + } else if (level_num == 3) { + if (rssi_thresh > rssi_thresh1) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Rssi thresh error!!\n"); + BTC_TRACE(trace_buf); + return *ppre_bt_rssi_state; + } + + if ((*ppre_bt_rssi_state == BTC_RSSI_STATE_LOW) || + (*ppre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + if (bt_rssi >= (rssi_thresh + + BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT)) + bt_rssi_state = BTC_RSSI_STATE_MEDIUM; + else + bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; + } else if ((*ppre_bt_rssi_state == BTC_RSSI_STATE_MEDIUM) || + (*ppre_bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { + if (bt_rssi >= (rssi_thresh1 + + BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT)) + bt_rssi_state = BTC_RSSI_STATE_HIGH; + else if (bt_rssi < rssi_thresh) + bt_rssi_state = BTC_RSSI_STATE_LOW; + else + bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; + } else { + if (bt_rssi < rssi_thresh1) + bt_rssi_state = BTC_RSSI_STATE_MEDIUM; + else + bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + } + } + + *ppre_bt_rssi_state = bt_rssi_state; + + return bt_rssi_state; +} + +static +u8 halbtc8821c2ant_wifi_rssi_state(struct btc_coexist *btc, + u8 *pprewifi_rssi_state, + u8 level_num, + u8 rssi_thresh, u8 rssi_thresh1) +{ + s32 wifi_rssi = 0; + u8 wifi_rssi_state = *pprewifi_rssi_state; + + btc->btc_get(btc, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + + if (level_num == 2) { + if ((*pprewifi_rssi_state == BTC_RSSI_STATE_LOW) || + (*pprewifi_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + if (wifi_rssi >= (rssi_thresh + + BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT)) + wifi_rssi_state = BTC_RSSI_STATE_HIGH; + else + wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; + } else { + if (wifi_rssi < rssi_thresh) + wifi_rssi_state = BTC_RSSI_STATE_LOW; + else + wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + } + } else if (level_num == 3) { + if (rssi_thresh > rssi_thresh1) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi RSSI thresh error!!\n"); + BTC_TRACE(trace_buf); + return *pprewifi_rssi_state; + } + + if ((*pprewifi_rssi_state == BTC_RSSI_STATE_LOW) || + (*pprewifi_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { + if (wifi_rssi >= (rssi_thresh + + BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT)) + wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; + else + wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; + } else if ((*pprewifi_rssi_state == BTC_RSSI_STATE_MEDIUM) || + (*pprewifi_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { + if (wifi_rssi >= (rssi_thresh1 + + BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT)) + wifi_rssi_state = BTC_RSSI_STATE_HIGH; + else if (wifi_rssi < rssi_thresh) + wifi_rssi_state = BTC_RSSI_STATE_LOW; + else + wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; + } else { + if (wifi_rssi < rssi_thresh1) + wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; + else + wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; + } + } + + *pprewifi_rssi_state = wifi_rssi_state; + + return wifi_rssi_state; +} + +static void +halbtc8821c2ant_limited_tx(struct btc_coexist *btc, boolean force_exec, + boolean tx_limit_en, boolean ampdu_limit_en) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct wifi_link_info_8821c_2ant *wifi_link_info_ext = + &btc->wifi_link_info_8821c_2ant; + boolean wifi_under_b_mode = FALSE; + + /* Force Max Tx retry limit = 8*/ + if (!coex_sta->wl_tx_limit_en) { + coex_sta->wl_0x430_backup = btc->btc_read_4byte(btc, 0x430); + coex_sta->wl_0x434_backup = btc->btc_read_4byte(btc, 0x434); + coex_sta->wl_0x42a_backup = btc->btc_read_2byte(btc, 0x42a); + } + + if (!coex_sta->wl_ampdu_limit_en) + coex_sta->wl_0x455_backup = btc->btc_read_1byte(btc, 0x455); + + if (!force_exec && tx_limit_en == coex_sta->wl_tx_limit_en && + ampdu_limit_en == coex_sta->wl_ampdu_limit_en) + return; + + coex_sta->wl_tx_limit_en = tx_limit_en; + coex_sta->wl_ampdu_limit_en = ampdu_limit_en; + + if (tx_limit_en) { + /* Set BT polluted packet on for Tx rate adaptive not + * including Tx retry break by PTA, 0x45c[19] =1 + * Set queue life time to avoid can't reach tx retry limit + * if tx is always break by GNT_BT. + */ + btc->btc_write_1byte_bitmask(btc, 0x45e, 0x8, 0x1); + btc->btc_write_1byte_bitmask(btc, 0x426, 0xf, 0xf); + + /* Max Tx retry limit = 8*/ + btc->btc_write_2byte(btc, 0x42a, 0x0808); + + btc->btc_get(btc, BTC_GET_BL_WIFI_UNDER_B_MODE, + &wifi_under_b_mode); + + /* Auto rate fallback step within 8 retry*/ + if (wifi_under_b_mode) { + btc->btc_write_4byte(btc, 0x430, 0x1000000); + btc->btc_write_4byte(btc, 0x434, 0x1010101); + } else { + btc->btc_write_4byte(btc, 0x430, 0x1000000); + btc->btc_write_4byte(btc, 0x434, 0x4030201); + } + } else { + /* Set BT polluted packet on for Tx rate adaptive not + *including Tx retry break by PTA, 0x45c[19] =1 + */ + btc->btc_write_1byte_bitmask(btc, 0x45e, 0x8, 0x0); + btc->btc_write_1byte_bitmask(btc, 0x426, 0xf, 0x0); + + /* Set queue life time to avoid can't reach tx retry limit + * if tx is always break by GNT_BT. + */ + if (wifi_link_info_ext->num_of_active_port == 1) + btc->btc_write_1byte_bitmask(btc, 0x426, 0xf, 0x0); + + /* Recovery Max Tx retry limit*/ + btc->btc_write_2byte(btc, 0x42a, coex_sta->wl_0x42a_backup); + btc->btc_write_4byte(btc, 0x430, coex_sta->wl_0x430_backup); + btc->btc_write_4byte(btc, 0x434, coex_sta->wl_0x434_backup); + } + + if (ampdu_limit_en) + btc->btc_write_1byte(btc, 0x455, 0x20); + else + btc->btc_write_1byte(btc, 0x455, coex_sta->wl_0x455_backup); +} + +static void +halbtc8821c2ant_limited_rx(struct btc_coexist *btc, boolean force_exec, + boolean rej_ap_agg_pkt, boolean bt_ctrl_agg_buf_size, + u8 agg_buf_size) +{ +#if 0 + struct coex_sta_8822b_2ant *coex_sta = &btc->coex_sta_8822b_2ant; + boolean reject_rx_agg = rej_ap_agg_pkt; + boolean bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size; + u8 rx_agg_size = agg_buf_size; + + if (!force_exec && + bt_ctrl_agg_buf_size == coex_sta->wl_rxagg_limit_en && + agg_buf_size == coex_sta->wl_rxagg_size) + return; + + coex_sta->wl_rxagg_limit_en = bt_ctrl_agg_buf_size; + coex_sta->wl_rxagg_size = agg_buf_size; + + /*btc->btc_set(btc, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &reject_rx_agg);*/ + /* decide BT control aggregation buf size or not */ + btc->btc_set(btc, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bt_ctrl_rx_agg_size); + /* aggregation buf size, only work when BT control Rx aggregation size*/ + btc->btc_set(btc, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size); + /* real update aggregation setting */ + btc->btc_set(btc, BTC_SET_ACT_AGGREGATE_CTRL, NULL); +#endif +} + +static void +halbtc8821c2ant_ccklock_action(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + u8 h2c_parameter[2] = {0}; + static u8 cnt; + boolean wifi_busy = FALSE; + + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + if (!coex_sta->gl_wifi_busy || + coex_sta->wl_iot_peer == BTC_IOT_PEER_CISCO) { + cnt = 0; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi is not busy or CISCO AP, return!!\n"); + BTC_TRACE(trace_buf); + return; + } + + if (!coex_sta->is_no_wl_5ms_extend && coex_sta->force_lps_ctrl && + !coex_sta->cck_lock_ever) { + if (coex_sta->wl_fw_dbg_info[7] <= 5 && wifi_busy) + cnt++; + else + cnt = 0; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], 5ms WL slot extend cnt = %d!!\n", cnt); + BTC_TRACE(trace_buf); + + if (cnt == 7) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], set h2c 0x69 opcode 12 to turn off 5ms WL slot extend!!\n"); + BTC_TRACE(trace_buf); + + h2c_parameter[0] = 0xc; + h2c_parameter[1] = 0x1; + btc->btc_fill_h2c(btc, 0x69, 2, h2c_parameter); + coex_sta->is_no_wl_5ms_extend = TRUE; + cnt = 0; + } + } else if (coex_sta->is_no_wl_5ms_extend && coex_sta->cck_lock) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], set h2c 0x69 opcode 12 to turn on 5ms WL slot extend!!\n"); + BTC_TRACE(trace_buf); + + h2c_parameter[0] = 0xc; + h2c_parameter[1] = 0x0; + btc->btc_fill_h2c(btc, 0x69, 2, h2c_parameter); + coex_sta->is_no_wl_5ms_extend = FALSE; + } +} + +static void +halbtc8821c2ant_ccklock_detect(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + struct wifi_link_info_8821c_2ant *link_info_ext = + &btc->wifi_link_info_8821c_2ant; + boolean is_cck_lock_rate = FALSE; + + if (coex_dm->bt_status == BTC_BTSTATUS_INQ_PAGE || + coex_sta->is_setup_link) + return; + + if (coex_sta->wl_rx_rate <= BTC_CCK_2 || + coex_sta->wl_rts_rx_rate <= BTC_CCK_2) + is_cck_lock_rate = TRUE; + + if (link_info_ext->is_connected && coex_sta->gl_wifi_busy && + (coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_ACL_BUSY || + coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_ACL_SCO_BUSY || + coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_SCO_BUSY)) { + if (coex_sta->wl_rx_rate == BTC_CCK_5_5 || + coex_sta->wl_rx_rate == BTC_OFDM_6 || + coex_sta->wl_rx_rate == BTC_MCS_0) { + coex_sta->cck_lock_warn = TRUE; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], cck lock warning...\n"); + BTC_TRACE(trace_buf); + } else if ((coex_sta->wl_rx_rate == BTC_CCK_1) || + (coex_sta->wl_rx_rate == BTC_CCK_2) || + (coex_sta->wl_rts_rx_rate == BTC_CCK_1) || + (coex_sta->wl_rts_rx_rate == BTC_CCK_2)) { + coex_sta->cck_lock = TRUE; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], cck locking...\n"); + BTC_TRACE(trace_buf); + } else { + coex_sta->cck_lock_warn = FALSE; + coex_sta->cck_lock = FALSE; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], cck unlock...\n"); + BTC_TRACE(trace_buf); + } + } else { + coex_sta->cck_lock_warn = FALSE; + coex_sta->cck_lock = FALSE; + } +} + +static void +halbtc8821c2ant_set_tdma_timer_base(struct btc_coexist *btc, u8 type) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + u16 tbtt_interval = 100; + u8 h2c_para[2] = {0xb, 0x1}; + + btc->btc_get(btc, BTC_GET_U2_BEACON_PERIOD, &tbtt_interval); + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], tbtt_interval = %d\n", tbtt_interval); + BTC_TRACE(trace_buf); + + /* Add for JIRA coex-256 */ + if (type == 3 && tbtt_interval >= 100) { /* 50ms-slot */ + if (coex_sta->tdma_timer_base == 3) + return; + + h2c_para[1] = (tbtt_interval / 50) - 1; + h2c_para[1] = h2c_para[1] | 0xc0; /* 50ms-slot */ + coex_sta->tdma_timer_base = 3; + } else if (tbtt_interval < 80 && tbtt_interval > 0) { + if (coex_sta->tdma_timer_base == 2) + return; + h2c_para[1] = (100 / tbtt_interval); + + if (100 % tbtt_interval != 0) + h2c_para[1] = h2c_para[1] + 1; + + h2c_para[1] = h2c_para[1] & 0x3f; + coex_sta->tdma_timer_base = 2; + } else if (tbtt_interval >= 180) { + if (coex_sta->tdma_timer_base == 1) + return; + h2c_para[1] = (tbtt_interval / 100); + + if (tbtt_interval % 100 <= 80) + h2c_para[1] = h2c_para[1] - 1; + + h2c_para[1] = h2c_para[1] & 0x3f; + h2c_para[1] = h2c_para[1] | 0x80; + coex_sta->tdma_timer_base = 1; + } else { + if (coex_sta->tdma_timer_base == 0) + return; + h2c_para[1] = 0x1; + coex_sta->tdma_timer_base = 0; + } + + btc->btc_fill_h2c(btc, 0x69, 2, h2c_para); + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], %s() h2c_0x69 = 0x%x\n", __func__, h2c_para[1]); + BTC_TRACE(trace_buf); +} + +static +void halbtc8821c2ant_coex_switch_thres(struct btc_coexist *btc, + u8 isolation_measuared) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + s8 interference_wl_tx = 0, interference_bt_tx = 0; + + interference_wl_tx = BT_8821C_2ANT_WIFI_MAX_TX_POWER - + isolation_measuared; + interference_bt_tx = BT_8821C_2ANT_BT_MAX_TX_POWER - + isolation_measuared; + + coex_sta->wifi_coex_thres = BT_8821C_2ANT_WIFI_RSSI_COEXSWITCH_THRES1; + coex_sta->wifi_coex_thres2 = BT_8821C_2ANT_WIFI_RSSI_COEXSWITCH_THRES2; + + coex_sta->bt_coex_thres = BT_8821C_2ANT_BT_RSSI_COEXSWITCH_THRES1; + coex_sta->bt_coex_thres2 = BT_8821C_2ANT_BT_RSSI_COEXSWITCH_THRES2; +} + +static +void halbtc8821c2ant_low_penalty_ra(struct btc_coexist *btc, + boolean force_exec, boolean low_penalty_ra, + u8 thres) +{ + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + static u8 cur_thres; + + if (!force_exec) { + if (low_penalty_ra == coex_dm->cur_low_penalty_ra && + thres == cur_thres) + return; + } + + if (low_penalty_ra) + btc->btc_phydm_modify_RA_PCR_threshold(btc, 0, thres); + else + btc->btc_phydm_modify_RA_PCR_threshold(btc, 0, 0); + + coex_dm->cur_low_penalty_ra = low_penalty_ra; + cur_thres = thres; +} + +static +void halbtc8821c2ant_set_antdiv_hwsw(struct btc_coexist *btc, + boolean force_exec, boolean is_hw_div) +{ + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + static u8 pre_antdiv_type; + + coex_dm->cur_antdiv_type = ((is_hw_div) ? 1 : 0); + + if (!force_exec) { + if (coex_dm->cur_antdiv_type == pre_antdiv_type) + return; + } + + btc->btc_phydm_modify_antdiv_hwsw(btc, coex_dm->cur_antdiv_type); + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], %s = %d!!\n", __func__, + coex_dm->cur_antdiv_type); + BTC_TRACE(trace_buf); + + pre_antdiv_type = coex_dm->cur_antdiv_type; +} + +static boolean +halbtc8821c2ant_freerun_check(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW; + static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW; + u8 wifi_rssi_state, bt_rssi_state; + + wifi_rssi_state = + halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2, + coex_sta->wifi_coex_thres, 0); + + bt_rssi_state = + halbtc8821c2ant_bt_rssi_state(btc, &pre_bt_rssi_state, 2, + coex_sta->bt_coex_thres, 0); + + if (btc->board_info.ant_distance >= 40) + return TRUE; + + if (btc->board_info.ant_distance <= 5) + return FALSE; + + /* ant_distance = 5 ~ 40 */ + if (BTC_RSSI_HIGH(wifi_rssi_state) && + BTC_RSSI_HIGH(bt_rssi_state) && coex_sta->gl_wifi_busy) + return TRUE; + else + return FALSE; +} + +static +void halbtc8821c2ant_write_scbd(struct btc_coexist *btc, u16 bitpos, + boolean state) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + static u16 originalval = 0x8002, preval; + + if (state) + originalval = originalval | bitpos; + else + originalval = originalval & (~bitpos); + + coex_sta->score_board_WB = originalval; + + if (originalval != preval) { + preval = originalval; + btc->btc_write_2byte(btc, 0xaa, originalval); + } else { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], %s: return for nochange\n", __func__); + BTC_TRACE(trace_buf); + } +} + +static +void halbtc8821c2ant_read_scbd(struct btc_coexist *btc, u16 *score_board_val) +{ + *score_board_val = (btc->btc_read_2byte(btc, 0xaa)) & 0x7fff; +} + +static +void halbtc8821c2ant_query_bt_info(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + u8 h2c_parameter[1] = {0}; + + if (coex_sta->bt_disabled) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], No query BT info because BT is disabled!\n"); + BTC_TRACE(trace_buf); + return; + } + + h2c_parameter[0] |= BIT(0); /* trigger */ + + btc->btc_fill_h2c(btc, 0x61, 1, h2c_parameter); +} + +static +void halbtc8821c2ant_enable_gnt_to_gpio(struct btc_coexist *btc, + boolean isenable) +{ + static u8 bit_val[5] = {0, 0, 0, 0, 0}; + static boolean state; + + if (!btc->dbg_mode) + return; + + if (state == isenable) + return; + + state = isenable; + + if (isenable) { + /* enable GNT_WL, GNT_BT to GPIO for debug */ + btc->btc_write_1byte_bitmask(btc, 0x73, 0x8, 0x1); + + /* store original value */ + /*0x66[4] */ + bit_val[0] = (btc->btc_read_1byte(btc, 0x66) & BIT(4)) >> 4; + /*0x66[8] */ + bit_val[1] = (btc->btc_read_1byte(btc, 0x67) & BIT(0)); + /*0x40[19] */ + bit_val[2] = (btc->btc_read_1byte(btc, 0x42) & BIT(3)) >> 3; + /*0x64[15] */ + bit_val[3] = (btc->btc_read_1byte(btc, 0x65) & BIT(7)) >> 7; + /*0x70[18] */ + bit_val[4] = (btc->btc_read_1byte(btc, 0x72) & BIT(2)) >> 2; + + /* switch GPIO Mux */ + /*0x66[4] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x66, BIT(4), 0x0); + /*0x66[8] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x67, BIT(0), 0x0); + /*0x40[19] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x42, BIT(3), 0x0); + /*0x64[15] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x65, BIT(7), 0x0); + /*0x70[18] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x72, BIT(2), 0x0); + } else { + btc->btc_write_1byte_bitmask(btc, 0x73, 0x8, 0x0); + + /* Restore original value */ + /* switch GPIO Mux */ + /*0x66[4] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x66, BIT(4), bit_val[0]); + /*0x66[8] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x67, BIT(0), bit_val[1]); + /*0x40[19] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x42, BIT(3), bit_val[2]); + /*0x64[15] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x65, BIT(7), bit_val[3]); + /*0x70[18] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x72, BIT(2), bit_val[4]); + } +} + +static +boolean halbtc8821c2ant_monitor_bt_ctr(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + u32 reg_hp_txrx, reg_lp_txrx, u32tmp, cnt_bt_all; + u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0; + static u8 cnt_overhead; + static u32 cnt_bt_pre = 0; + struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; + boolean is_run_coex = FALSE; + + reg_hp_txrx = 0x770; + reg_lp_txrx = 0x774; + + u32tmp = btc->btc_read_4byte(btc, reg_hp_txrx); + reg_hp_tx = u32tmp & MASKLWORD; + reg_hp_rx = (u32tmp & MASKHWORD) >> 16; + + u32tmp = btc->btc_read_4byte(btc, reg_lp_txrx); + reg_lp_tx = u32tmp & MASKLWORD; + reg_lp_rx = (u32tmp & MASKHWORD) >> 16; + + coex_sta->high_priority_tx = reg_hp_tx; + coex_sta->high_priority_rx = reg_hp_rx; + coex_sta->low_priority_tx = reg_lp_tx; + coex_sta->low_priority_rx = reg_lp_rx; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Hi-Pri Rx/Tx: %d/%d, Lo-Pri Rx/Tx: %d/%d\n", + reg_hp_rx, reg_hp_tx, reg_lp_rx, reg_lp_tx); + + BTC_TRACE(trace_buf); + + /* reset counter */ + btc->btc_write_1byte(btc, 0x76e, 0xc); + + if (coex_sta->under_lps || coex_sta->under_ips || + (coex_sta->high_priority_tx == 65535 && + coex_sta->high_priority_rx == 65535 && + coex_sta->low_priority_tx == 65535 && + coex_sta->low_priority_rx == 65535)) + coex_sta->bt_ctr_ok = FALSE; + else + coex_sta->bt_ctr_ok = TRUE; + + if (!coex_sta->bt_ctr_ok) + return FALSE; + + if (coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE) { + if (coex_sta->high_priority_rx >= 15) { + if (cnt_overhead < 3) + cnt_overhead++; + if (cnt_overhead == 3) + coex_sta->is_hi_pri_rx_overhead = TRUE; + } else { + if (cnt_overhead > 0) + cnt_overhead--; + if (cnt_overhead == 0) + coex_sta->is_hi_pri_rx_overhead = FALSE; + } + } else { + coex_sta->is_hi_pri_rx_overhead = FALSE; + } + + if (coex_sta->low_priority_tx > 1150 && + !coex_sta->c2h_bt_inquiry_page) + coex_sta->pop_event_cnt++; + + if (coex_sta->sco_exist) { + if (coex_sta->high_priority_tx >= 400 && + coex_sta->high_priority_rx >= 400) + coex_sta->is_esco_mode = FALSE; + else + coex_sta->is_esco_mode = TRUE; + } + + if (bt_link_info->hid_only) { + if (coex_sta->low_priority_tx > 100) + coex_sta->is_hid_low_pri_tx_overhead = true; + else + coex_sta->is_hid_low_pri_tx_overhead = false; + } + + cnt_bt_all = coex_sta->high_priority_tx + + coex_sta->high_priority_rx + + coex_sta->low_priority_tx + + coex_sta->low_priority_rx; + + if ((cnt_bt_pre > (cnt_bt_all + 50) || + cnt_bt_all > (cnt_bt_pre + 50)) && + coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE) + is_run_coex = TRUE; + + cnt_bt_pre = cnt_bt_all; + + return is_run_coex; +} + +static +void halbtc8821c2ant_monitor_wifi_ctr(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + boolean wifi_busy = FALSE, wifi_scan = FALSE; + static u8 wl_noisy_count0, wl_noisy_count1 = 3, wl_noisy_count2; + u32 cnt_cck, fw_ver = 0; + static u8 cnt_ccklocking; + u8 h2c_parameter[1] = {0}; + + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btc->btc_get(btc, BTC_GET_BL_WIFI_SCAN, &wifi_scan); + btc->btc_get(btc, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + + /* Only enable for windows in old fw version (COEX-308) + * because 8821cu H2C 0x69 unknown fail @ linux */ - if (btc->chip_interface != BTC_INTF_USB || - (fw_ver < 0x170000 && fw_ver < 0x17000c) || - (fw_ver < 0x180000 && fw_ver < 0x180009) || - (fw_ver < 0x190000 && fw_ver < 0x190002)) { + if (btc->chip_interface != BTC_INTF_USB || + (fw_ver < 0x170000 && fw_ver < 0x17000c) || + (fw_ver < 0x180000 && fw_ver < 0x180009) || + (fw_ver < 0x190000 && fw_ver < 0x190002)) { /*send h2c to query WL FW dbg info */ if (coex_dm->cur_ps_tdma_on) { h2c_parameter[0] = 0x8; btc->btc_fill_h2c(btc, 0x69, 1, h2c_parameter); } - } - - coex_sta->crc_ok_cck = - btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_CCK); - coex_sta->crc_ok_11g = - btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_LEGACY); - coex_sta->crc_ok_11n = - btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_HT); - coex_sta->crc_ok_11n_vht = - btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_VHT); - - coex_sta->crc_err_cck = - btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_CCK); - coex_sta->crc_err_11g = - btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_LEGACY); - coex_sta->crc_err_11n = - btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_HT); - coex_sta->crc_err_11n_vht = - btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_VHT); - - /* CCK lock identification */ - if (coex_sta->cck_lock) - cnt_ccklocking++; - else if (cnt_ccklocking != 0) - cnt_ccklocking--; - - if (cnt_ccklocking >= 3) { - cnt_ccklocking = 3; - coex_sta->cck_lock_ever = TRUE; - } - - /* WiFi environment noisy identification */ - cnt_cck = coex_sta->crc_ok_cck + coex_sta->crc_err_cck; - - if (!wifi_busy && !coex_sta->cck_lock) { - if (cnt_cck > 250) { - if (wl_noisy_count2 < 3) - wl_noisy_count2++; - - if (wl_noisy_count2 == 3) { - wl_noisy_count0 = 0; - wl_noisy_count1 = 0; - } - - } else if (cnt_cck < 100) { - if (wl_noisy_count0 < 3) - wl_noisy_count0++; - - if (wl_noisy_count0 == 3) { - wl_noisy_count1 = 0; - wl_noisy_count2 = 0; - } - - } else { - if (wl_noisy_count1 < 3) - wl_noisy_count1++; - - if (wl_noisy_count1 == 3) { - wl_noisy_count0 = 0; - wl_noisy_count2 = 0; - } - } - - if (wl_noisy_count2 == 3) - coex_sta->wl_noisy_level = 2; - else if (wl_noisy_count1 == 3) - coex_sta->wl_noisy_level = 1; - else - coex_sta->wl_noisy_level = 0; - } -} - -static -void halbtc8821c2ant_monitor_bt_enable(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - static u32 bt_disable_cnt; - boolean bt_active = TRUE, bt_disabled = FALSE; - u16 u16tmp; - - /* Read BT on/off status from scoreboard[1], - * enable this only if BT patch support this feature - */ - halbtc8821c2ant_read_scbd(btc, &u16tmp); - - bt_active = u16tmp & BIT(1); - - if (bt_active) { - bt_disable_cnt = 0; - bt_disabled = FALSE; - btc->btc_set(btc, BTC_SET_BL_BT_DISABLE, &bt_disabled); - } else { - bt_disable_cnt++; - if (bt_disable_cnt >= 2) { - bt_disabled = TRUE; - bt_disable_cnt = 2; - } - - btc->btc_set(btc, BTC_SET_BL_BT_DISABLE, &bt_disabled); - } - - if (coex_sta->bt_disabled != bt_disabled) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT is from %s to %s!!\n", - (coex_sta->bt_disabled ? "disabled" : "enabled"), - (bt_disabled ? "disabled" : "enabled")); - BTC_TRACE(trace_buf); - coex_sta->bt_disabled = bt_disabled; - - /*for win10 BT disable->enable trigger wifi scan issue */ - if (!coex_sta->bt_disabled) { - coex_sta->is_bt_reenable = TRUE; - coex_sta->cnt_bt_reenable = 15; - } else { - coex_sta->is_bt_reenable = FALSE; - coex_sta->cnt_bt_reenable = 0; - } - } -} - -static -boolean halbtc8821c2ant_moniter_wifibt_status(struct btc_coexist - *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct wifi_link_info_8821c_2ant *wifi_link_info_ext = - &btc->wifi_link_info_8821c_2ant; - static boolean pre_wifi_busy, pre_under_4way, - pre_bt_off, pre_bt_slave, pre_hid_low_pri_tx_overhead, - pre_wifi_under_lps, pre_bt_setup_link, - pre_cck_lock, pre_cck_lock_warn; - static u8 pre_hid_busy_num, pre_wl_noisy_level; - boolean wifi_busy = FALSE, under_4way = FALSE; - boolean wifi_connected = FALSE; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; - static u8 cnt_wifi_busytoidle; - u32 num_of_wifi_link = 0, wifi_link_mode = 0; - static u32 pre_num_of_wifi_link, pre_wifi_link_mode; - boolean miracast_plus_bt = FALSE; - - btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); - btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); - btc->btc_get(btc, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under_4way); - - if (wifi_busy) { - coex_sta->gl_wifi_busy = TRUE; - cnt_wifi_busytoidle = 6; - } else { - if (coex_sta->gl_wifi_busy && cnt_wifi_busytoidle > 0) - cnt_wifi_busytoidle--; - else if (cnt_wifi_busytoidle == 0) - coex_sta->gl_wifi_busy = FALSE; - } - - if (coex_sta->bt_disabled != pre_bt_off) { - pre_bt_off = coex_sta->bt_disabled; - - if (coex_sta->bt_disabled) - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT is disabled !!\n"); - else - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT is enabled !!\n"); - - BTC_TRACE(trace_buf); - - coex_sta->bt_coex_supported_feature = 0; - coex_sta->bt_coex_supported_version = 0; - coex_sta->bt_ble_scan_type = 0; - coex_sta->bt_ble_scan_para[0] = 0; - coex_sta->bt_ble_scan_para[1] = 0; - coex_sta->bt_ble_scan_para[2] = 0; - coex_sta->bt_reg_vendor_ac = 0xffff; - coex_sta->bt_reg_vendor_ae = 0xffff; - coex_sta->bt_a2dp_vendor_id = 0; - coex_sta->bt_a2dp_device_name = 0; - btc->bt_info.bt_get_fw_ver = 0; - return TRUE; - } - - num_of_wifi_link = wifi_link_info_ext->num_of_active_port; - - if (num_of_wifi_link != pre_num_of_wifi_link) { - pre_num_of_wifi_link = num_of_wifi_link; - - if (wifi_link_info_ext->is_p2p_connected) { - if (bt_link_info->bt_link_exist) - miracast_plus_bt = TRUE; - else - miracast_plus_bt = FALSE; - - btc->btc_set(btc, BTC_SET_BL_MIRACAST_PLUS_BT, - &miracast_plus_bt); - } - return TRUE; - } - - wifi_link_mode = btc->wifi_link_info.link_mode; - if (wifi_link_mode != pre_wifi_link_mode) { - pre_wifi_link_mode = wifi_link_mode; - return TRUE; - } - - if (wifi_connected) { - if (wifi_busy != pre_wifi_busy) { - pre_wifi_busy = wifi_busy; - return TRUE; - } - if (under_4way != pre_under_4way) { - pre_under_4way = under_4way; - return TRUE; - } - - if (coex_sta->wl_noisy_level != pre_wl_noisy_level) { - pre_wl_noisy_level = coex_sta->wl_noisy_level; - return TRUE; - } - if (coex_sta->under_lps != pre_wifi_under_lps) { - pre_wifi_under_lps = coex_sta->under_lps; - if (coex_sta->under_lps) - return TRUE; - } - if (coex_sta->cck_lock != pre_cck_lock) { - pre_cck_lock = coex_sta->cck_lock; - return TRUE; - } - if (coex_sta->cck_lock_warn != pre_cck_lock_warn) { - pre_cck_lock_warn = coex_sta->cck_lock_warn; - return TRUE; - } - } - - if (!coex_sta->bt_disabled) { -#if 0 - if (coex_sta->acl_busy != pre_bt_acl_busy) { - pre_bt_acl_busy = coex_sta->acl_busy; - btc->btc_set(btc, BTC_SET_BL_BT_LNA_CONSTRAIN_LEVEL, - &lna_lvl); - return TRUE; - } -#endif - if (coex_sta->hid_busy_num != pre_hid_busy_num) { - pre_hid_busy_num = coex_sta->hid_busy_num; - return TRUE; - } - - if (bt_link_info->slave_role != pre_bt_slave) { - pre_bt_slave = bt_link_info->slave_role; - return TRUE; - } - - if (pre_hid_low_pri_tx_overhead != - coex_sta->is_hid_low_pri_tx_overhead) { - pre_hid_low_pri_tx_overhead = - coex_sta->is_hid_low_pri_tx_overhead; - return TRUE; - } - - if (pre_bt_setup_link != coex_sta->is_setup_link) { - pre_bt_setup_link = coex_sta->is_setup_link; - return TRUE; - } - } - - return FALSE; -} - -static -void halbtc8821c2ant_update_wifi_link_info(struct btc_coexist *btc, u8 reason) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct wifi_link_info_8821c_2ant *wifi_link_info_ext = - &btc->wifi_link_info_8821c_2ant; - struct btc_wifi_link_info wifi_link_info; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - u8 wifi_central_chnl = 0, num_of_wifi_link = 0; - boolean isunder5G = FALSE, ismcc25g = FALSE, isp2pconnected = FALSE; - u32 wifi_link_status = 0; - - btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, - &wifi_link_info_ext->is_connected); - - btc->btc_get(btc, BTC_GET_U4_WIFI_LINK_STATUS, &wifi_link_status); - wifi_link_info_ext->port_connect_status = wifi_link_status & 0xffff; - - btc->btc_get(btc, BTC_GET_BL_WIFI_LINK_INFO, &wifi_link_info); - btc->wifi_link_info = wifi_link_info; - - btc->btc_get(btc, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifi_central_chnl); - coex_sta->wl_center_channel = wifi_central_chnl; - - /* Check scan/connect/special-pkt action first */ - switch (reason) { - case BT_8821C_2ANT_RSN_5GSCANSTART: - case BT_8821C_2ANT_RSN_5GSWITCHBAND: - case BT_8821C_2ANT_RSN_5GCONSTART: - isunder5G = TRUE; - break; - case BT_8821C_2ANT_RSN_2GSCANSTART: - case BT_8821C_2ANT_RSN_2GSWITCHBAND: - case BT_8821C_2ANT_RSN_2GCONSTART: - isunder5G = FALSE; - break; - case BT_8821C_2ANT_RSN_2GCONFINISH: - case BT_8821C_2ANT_RSN_5GCONFINISH: - case BT_8821C_2ANT_RSN_2GMEDIA: - case BT_8821C_2ANT_RSN_5GMEDIA: - case BT_8821C_2ANT_RSN_BTINFO: - case BT_8821C_2ANT_RSN_PERIODICAL: - case BT_8821C_2ANT_RSN_2GSPECIALPKT: - case BT_8821C_2ANT_RSN_5GSPECIALPKT: - default: - switch (wifi_link_info.link_mode) { - case BTC_LINK_5G_MCC_GO_STA: - case BTC_LINK_5G_MCC_GC_STA: - case BTC_LINK_5G_SCC_GO_STA: - case BTC_LINK_5G_SCC_GC_STA: - isunder5G = TRUE; - break; - case BTC_LINK_2G_MCC_GO_STA: - case BTC_LINK_2G_MCC_GC_STA: - case BTC_LINK_2G_SCC_GO_STA: - case BTC_LINK_2G_SCC_GC_STA: - isunder5G = FALSE; - break; - case BTC_LINK_25G_MCC_GO_STA: - case BTC_LINK_25G_MCC_GC_STA: - isunder5G = FALSE; - ismcc25g = TRUE; - break; - case BTC_LINK_ONLY_STA: - if (wifi_link_info.sta_center_channel > 14) - isunder5G = TRUE; - else - isunder5G = FALSE; - break; - case BTC_LINK_ONLY_GO: - case BTC_LINK_ONLY_GC: - case BTC_LINK_ONLY_AP: - default: - if (wifi_link_info.p2p_center_channel > 14) - isunder5G = TRUE; - else - isunder5G = FALSE; - - break; - } - break; - } - - wifi_link_info_ext->is_all_under_5g = isunder5G; - wifi_link_info_ext->is_mcc_25g = ismcc25g; - - if (wifi_link_status & WIFI_STA_CONNECTED) - num_of_wifi_link++; - - if (wifi_link_status & WIFI_AP_CONNECTED) - num_of_wifi_link++; - - if (wifi_link_status & WIFI_P2P_GO_CONNECTED) { - num_of_wifi_link++; - isp2pconnected = TRUE; - } - - if (wifi_link_status & WIFI_P2P_GC_CONNECTED) { - num_of_wifi_link++; - isp2pconnected = TRUE; - } - - wifi_link_info_ext->num_of_active_port = num_of_wifi_link; - wifi_link_info_ext->is_p2p_connected = isp2pconnected; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi_link_info: link_mode=%d, STA_Ch=%d, P2P_Ch=%d, AnyClient_Join_Go=%d !\n", - btc->wifi_link_info.link_mode, - btc->wifi_link_info.sta_center_channel, - btc->wifi_link_info.p2p_center_channel, - btc->wifi_link_info.bany_client_join_go); - BTC_TRACE(trace_buf); - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi_link_info: center_ch=%d, is_all_under_5g=%d, is_mcc_25g=%d!\n", - coex_sta->wl_center_channel, - wifi_link_info_ext->is_all_under_5g, - wifi_link_info_ext->is_mcc_25g); - BTC_TRACE(trace_buf); - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi_link_info: port_connect_status=0x%x, active_port_cnt=%d, P2P_Connect=%d!\n", - wifi_link_info_ext->port_connect_status, - wifi_link_info_ext->num_of_active_port, - wifi_link_info_ext->is_p2p_connected); - BTC_TRACE(trace_buf); - - switch (reason) { - case BT_8821C_2ANT_RSN_2GSCANSTART: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "2GSCANSTART"); - break; - case BT_8821C_2ANT_RSN_5GSCANSTART: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "5GSCANSTART"); - break; - case BT_8821C_2ANT_RSN_SCANFINISH: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "SCANFINISH"); - break; - case BT_8821C_2ANT_RSN_2GSWITCHBAND: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "2GSWITCHBAND"); - break; - case BT_8821C_2ANT_RSN_5GSWITCHBAND: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "5GSWITCHBAND"); - break; - case BT_8821C_2ANT_RSN_2GCONSTART: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "2GCONNECTSTART"); - break; - case BT_8821C_2ANT_RSN_5GCONSTART: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "5GCONNECTSTART"); - break; - case BT_8821C_2ANT_RSN_2GCONFINISH: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", - "2GCONNECTFINISH"); - break; - case BT_8821C_2ANT_RSN_5GCONFINISH: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", - "5GCONNECTFINISH"); - break; - case BT_8821C_2ANT_RSN_2GMEDIA: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "2GMEDIASTATUS"); - break; - case BT_8821C_2ANT_RSN_5GMEDIA: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "5GMEDIASTATUS"); - break; - case BT_8821C_2ANT_RSN_MEDIADISCON: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", - "MEDIADISCONNECT"); - break; - case BT_8821C_2ANT_RSN_2GSPECIALPKT: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "2GSPECIALPKT"); - break; - case BT_8821C_2ANT_RSN_5GSPECIALPKT: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "5GSPECIALPKT"); - break; - case BT_8821C_2ANT_RSN_BTINFO: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "BTINFO"); - break; - case BT_8821C_2ANT_RSN_PERIODICAL: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "PERIODICAL"); - break; - case BT_8821C_2ANT_RSN_PNP: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "PNPNotify"); - break; - default: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Update reason = %s\n", "UNKNOWN"); - break; - } - - BTC_TRACE(trace_buf); - - if (btc->manual_control || btc->stop_coex_dm) - return; - - if (wifi_link_info_ext->is_all_under_5g || num_of_wifi_link == 0 || - coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE) { - halbtc8821c2ant_low_penalty_ra(btc, NM_EXCU, FALSE, 0); - halbtc8821c2ant_limited_tx(btc, NM_EXCU, FALSE, FALSE); - halbtc8821c2ant_limited_rx(btc, NM_EXCU, FALSE, TRUE, 64); - } else if (wifi_link_info_ext->num_of_active_port > 1) { - halbtc8821c2ant_low_penalty_ra(btc, NM_EXCU, TRUE, 30); - halbtc8821c2ant_limited_tx(btc, NM_EXCU, FALSE, TRUE); - halbtc8821c2ant_limited_rx(btc, NM_EXCU, FALSE, TRUE, 16); - } else { - halbtc8821c2ant_low_penalty_ra(btc, NM_EXCU, TRUE, 15); - - if (coex_sta->hid_exist || coex_sta->hid_pair_cnt > 0 || - coex_sta->sco_exist) { - halbtc8821c2ant_limited_tx(btc, NM_EXCU, TRUE, TRUE); - halbtc8821c2ant_limited_rx(btc, NM_EXCU, FALSE, TRUE, - 16); - } else { - halbtc8821c2ant_limited_tx(btc, NM_EXCU, TRUE, FALSE); - halbtc8821c2ant_limited_rx(btc, NM_EXCU, FALSE, TRUE, - 64); - } - } - - /* coex-276 P2P-Go beacon request can't release issue - * Only PCIe/USB can set 0x454[6] = 1 to solve this issue, - * WL SDIO/USB interface need driver support. - */ -#ifdef PLATFORM_WINDOWS - if (btc->chip_interface != BTC_INTF_SDIO) - btc->btc_write_1byte_bitmask(btc, 0x454, BIT(6), 0x1); - else - btc->btc_write_1byte_bitmask(btc, 0x454, BIT(6), 0x0); -#endif -} - -static -void halbtc8821c2ant_update_bt_link_info(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; - boolean bt_busy = FALSE, increase_scan_dev_num = FALSE; - u32 val = 0; - static u8 pre_num_of_profile, cur_num_of_profile, cnt, ble_cnt; - - if (++ble_cnt >= 3) - ble_cnt = 0; - - if (coex_sta->is_ble_scan_en && ble_cnt == 0) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT ext info bit4 check, query BLE Scan type!!\n"); - BTC_TRACE(trace_buf); - coex_sta->bt_ble_scan_type = - btc->btc_get_ble_scan_type_from_bt(btc); - - if ((coex_sta->bt_ble_scan_type & 0x1) == 0x1) - coex_sta->bt_ble_scan_para[0] = - btc->btc_get_ble_scan_para_from_bt(btc, 0x1); - if ((coex_sta->bt_ble_scan_type & 0x2) == 0x2) - coex_sta->bt_ble_scan_para[1] = - btc->btc_get_ble_scan_para_from_bt(btc, 0x2); - if ((coex_sta->bt_ble_scan_type & 0x4) == 0x4) - coex_sta->bt_ble_scan_para[2] = - btc->btc_get_ble_scan_para_from_bt(btc, 0x4); - } - - coex_sta->num_of_profile = 0; - - /* set link exist status */ - if (!(coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_CONNECTION)) { - coex_sta->bt_link_exist = FALSE; - coex_sta->pan_exist = FALSE; - coex_sta->a2dp_exist = FALSE; - coex_sta->hid_exist = FALSE; - coex_sta->sco_exist = FALSE; - coex_sta->msft_mr_exist = FALSE; - } else { /* connection exists */ - coex_sta->bt_link_exist = TRUE; - if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_FTP) { - coex_sta->pan_exist = TRUE; - coex_sta->num_of_profile++; - } else { - coex_sta->pan_exist = FALSE; - } - - if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_A2DP) { - coex_sta->a2dp_exist = TRUE; - coex_sta->num_of_profile++; - } else { - coex_sta->a2dp_exist = FALSE; - } - - if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_HID) { - coex_sta->hid_exist = TRUE; - coex_sta->num_of_profile++; - } else { - coex_sta->hid_exist = FALSE; - } - - if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_ESCO) { - coex_sta->sco_exist = TRUE; - coex_sta->num_of_profile++; - } else { - coex_sta->sco_exist = FALSE; - } -#if 0 - if (coex_sta->hid_busy_num == 0 && - coex_sta->hid_pair_cnt > 0 && - coex_sta->low_priority_tx > 1000 && - coex_sta->low_priority_rx > 1000 && - !coex_sta->c2h_bt_inquiry_page) - coex_sta->msft_mr_exist = true; - else - coex_sta->msft_mr_exist = false; -#endif - } - - bt_link_info->bt_link_exist = coex_sta->bt_link_exist; - bt_link_info->sco_exist = coex_sta->sco_exist; - bt_link_info->a2dp_exist = coex_sta->a2dp_exist; - bt_link_info->pan_exist = coex_sta->pan_exist; - bt_link_info->hid_exist = coex_sta->hid_exist; - bt_link_info->acl_busy = coex_sta->acl_busy; - - /* check if Sco only */ - if (bt_link_info->sco_exist && - !bt_link_info->a2dp_exist && - !bt_link_info->pan_exist && - !bt_link_info->hid_exist) - bt_link_info->sco_only = TRUE; - else - bt_link_info->sco_only = FALSE; - - /* check if A2dp only */ - if (!bt_link_info->sco_exist && - bt_link_info->a2dp_exist && - !bt_link_info->pan_exist && - !bt_link_info->hid_exist) - bt_link_info->a2dp_only = TRUE; - else - bt_link_info->a2dp_only = FALSE; - - /* check if Pan only */ - if (!bt_link_info->sco_exist && - !bt_link_info->a2dp_exist && - bt_link_info->pan_exist && - !bt_link_info->hid_exist) - bt_link_info->pan_only = TRUE; - else - bt_link_info->pan_only = FALSE; - - /* check if Hid only */ - if (!bt_link_info->sco_exist && - !bt_link_info->a2dp_exist && - !bt_link_info->pan_exist && - bt_link_info->hid_exist) - bt_link_info->hid_only = TRUE; - else - bt_link_info->hid_only = FALSE; - - if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_INQ_PAGE) { - coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_INQ_PAGE; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BtInfoNotify(), BT Inq/page!!!\n"); - } else if (!(coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_CONNECTION)) { - coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_NCON_IDLE; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n"); - } else if (coex_sta->bt_info_lb2 == BT_INFO_8821C_2ANT_B_CONNECTION) { - /* connection exists but no busy */ - if (coex_sta->msft_mr_exist) { - coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_ACL_BUSY; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BtInfoNotify(), BT ACL busy!!\n"); - } else { - coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_CON_IDLE; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n"); - } - } else if (((coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_ESCO) || - (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_BUSY)) && - (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_ACL_BUSY)) { - coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_ACL_SCO_BUSY; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BtInfoNotify(), BT ACL SCO busy!!!\n"); - } else if ((coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_ESCO) || - (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_BUSY)) { - coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_SCO_BUSY; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); - } else if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_ACL_BUSY) { - coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_ACL_BUSY; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); - } else { - coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_MAX; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n"); - } - - BTC_TRACE(trace_buf); - - if (coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_ACL_BUSY || - coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_SCO_BUSY || - coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_ACL_SCO_BUSY) { - bt_busy = TRUE; - increase_scan_dev_num = TRUE; - } else { - bt_busy = FALSE; - increase_scan_dev_num = FALSE; - } - - btc->btc_set(btc, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); - btc->btc_set(btc, BTC_SET_BL_INC_SCAN_DEV_NUM, &increase_scan_dev_num); - - cur_num_of_profile = coex_sta->num_of_profile; - - if (cur_num_of_profile != pre_num_of_profile) - cnt = 2; - - if (btc->board_info.customer_id == RT_CID_LENOVO_CHINA) { - if (cur_num_of_profile > 0) - halbtc8821c2ant_set_antdiv_hwsw(btc, NM_EXCU, TRUE); - else - halbtc8821c2ant_set_antdiv_hwsw(btc, NM_EXCU, FALSE); - } - - if (bt_link_info->a2dp_exist && cnt > 0) { - cnt--; - if (coex_sta->bt_a2dp_vendor_id == 0 && - coex_sta->bt_a2dp_device_name == 0) { - btc->btc_get(btc, BTC_GET_U4_BT_DEVICE_INFO, &val); - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BtInfoNotify(), get BT DEVICE_INFO = %x\n", - val); - BTC_TRACE(trace_buf); - - coex_sta->bt_a2dp_vendor_id = (u8)(val & 0xff); - coex_sta->bt_a2dp_device_name = (val & 0xffffff00) >> 8; - - btc->btc_get(btc, BTC_GET_U4_BT_A2DP_FLUSH_VAL, &val); - coex_sta->bt_a2dp_flush_time = val; - } - } else if (!bt_link_info->a2dp_exist) { - coex_sta->bt_a2dp_vendor_id = 0; - coex_sta->bt_a2dp_device_name = 0; - coex_sta->bt_a2dp_flush_time = 0; - } - - pre_num_of_profile = coex_sta->num_of_profile; -} - -static -void halbtc8821c2ant_update_wifi_ch_info(struct btc_coexist *btc, u8 type) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - struct wifi_link_info_8821c_2ant *wifi_link_info_ext = - &btc->wifi_link_info_8821c_2ant; - u8 h2c_parameter[3] = {0}, i; - u32 wifi_bw; - u8 wl_ch = 0; - u8 wl_5g_ch[] = {0}; - u8 bt_skip_ch[] = {0}; - u8 bt_skip_span[] = {0}; - - if (btc->manual_control) - return; - - btc->btc_get(btc, BTC_GET_U4_WIFI_BW, &wifi_bw); - - if (btc->stop_coex_dm || btc->wl_rf_state_off) { - wl_ch = 0; - } else if (type != BTC_MEDIA_DISCONNECT || - (type == BTC_MEDIA_DISCONNECT && - wifi_link_info_ext->num_of_active_port > 0)) { - if (wifi_link_info_ext->num_of_active_port == 1) { - if (wifi_link_info_ext->is_p2p_connected) - wl_ch = btc->wifi_link_info.p2p_center_channel; - else - wl_ch = btc->wifi_link_info.sta_center_channel; - } else { /* port > 2 */ - if (btc->wifi_link_info.p2p_center_channel > 14 && - btc->wifi_link_info.sta_center_channel > 14) - wl_ch = btc->wifi_link_info.p2p_center_channel; - else if (btc->wifi_link_info.p2p_center_channel <= 14) - wl_ch = btc->wifi_link_info.p2p_center_channel; - else if (btc->wifi_link_info.sta_center_channel <= 14) - wl_ch = btc->wifi_link_info.sta_center_channel; - } - } - - if (wl_ch > 0) { - if (wl_ch <= 14) { - h2c_parameter[0] = 0x1; - h2c_parameter[1] = wl_ch; - - if (wifi_bw == BTC_WIFI_BW_HT40) - h2c_parameter[2] = 0x36; - else - h2c_parameter[2] = 0x24; - } else { /* for 5G */ -#if 0 - for (i = 0; i < ARRAY_SIZE(wl_5g_ch); i++) { - if (wl_ch == wl_5g_ch[i]) { - h2c_parameter[0] = 0x3; - h2c_parameter[1] = bt_skip_ch[i]; - h2c_parameter[2] = bt_skip_span[i]; - break; - } - } -#endif - } - } - - /* Only send mailbox if ch info change */ - if (coex_dm->wifi_chnl_info[0] != h2c_parameter[0] && - coex_dm->wifi_chnl_info[1] != h2c_parameter[1] && - coex_dm->wifi_chnl_info[2] != h2c_parameter[2]) { - - coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; - coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; - coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; - btc->btc_fill_h2c(btc, 0x66, 3, h2c_parameter); - } - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], para[0:2] = 0x%x 0x%x 0x%x\n", h2c_parameter[0], - h2c_parameter[1], h2c_parameter[2]); - BTC_TRACE(trace_buf); -} - -static -void halbtc8821c2ant_set_wl_tx_power(struct btc_coexist *btc, - boolean force_exec, u8 wl_pwr_lvl) -{ - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - - if (!force_exec) { - if (wl_pwr_lvl == coex_dm->cur_wl_pwr_lvl) - return; - } - - /* btc->btc_write_1byte_bitmask(btc, 0xc5b, 0xff, wl_pwr_lvl); */ - coex_dm->cur_wl_pwr_lvl = wl_pwr_lvl; -} - -static -void halbtc8821c2ant_set_bt_tx_power(struct btc_coexist *btc, - boolean force_exec, u8 bt_pwr_lvl) -{ - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - u8 h2c_parameter[1] = {0}; - - if (!force_exec) { - if (bt_pwr_lvl == coex_dm->cur_bt_pwr_lvl) - return; - } - - h2c_parameter[0] = 0 - bt_pwr_lvl; - btc->btc_fill_h2c(btc, 0x62, 1, h2c_parameter); - - coex_dm->cur_bt_pwr_lvl = bt_pwr_lvl; -} - -static u32 -halbtc8821c2ant_wait_indirect_reg_ready(struct btc_coexist *btc) -{ - u32 delay_count = 0; - - /* wait for ready bit before access 0x1700 */ - while (1) { - if ((btc->btc_read_1byte(btc, 0x1703) & BIT(5)) == 0) { - delay_ms(10); - if (++delay_count >= 10) - break; - } else { - break; - } - } - - return delay_count; -} - -static -u32 halbtc8821c2ant_read_indirect_reg(struct btc_coexist *btc, u16 reg_addr) -{ - u32 j = 0, delay_count = 0; - - halbtc8821c2ant_wait_indirect_reg_ready(btc); - - /* wait for ready bit before access 0x1700 */ - btc->btc_write_4byte(btc, 0x1700, 0x800F0000 | reg_addr); - - return btc->btc_read_4byte(btc, 0x1708); /* get read data */ -} - -static -void halbtc8821c2ant_write_indirect_reg(struct btc_coexist *btc, u16 reg_addr, - u32 bit_mask, u32 reg_value) -{ - u32 val, i = 0, j = 0, bitpos = 0, delay_count = 0; - - if (bit_mask == 0x0) - return; - if (bit_mask == 0xffffffff) { - /* wait for ready bit before access 0x1700/0x1704 */ - halbtc8821c2ant_wait_indirect_reg_ready(btc); - - /* put write data */ - btc->btc_write_4byte(btc, 0x1704, reg_value); - btc->btc_write_4byte(btc, 0x1700, 0xc00F0000 | reg_addr); - } else { - for (i = 0; i <= 31; i++) { - if (((bit_mask >> i) & 0x1) == 0x1) { - bitpos = i; - break; - } - } - - /* read back register value before write */ - val = halbtc8821c2ant_read_indirect_reg(btc, reg_addr); - val = (val & (~bit_mask)) | (reg_value << bitpos); - - /* wait for ready bit before access 0x1700/0x1704 */ - halbtc8821c2ant_wait_indirect_reg_ready(btc); - - /* put write data */ - btc->btc_write_4byte(btc, 0x1704, val); - btc->btc_write_4byte(btc, 0x1700, 0xc00F0000 | reg_addr); - } -} - -static -void halbtc8821c2ant_ltecoex_enable(struct btc_coexist *btc, boolean enable) -{ - u8 val; - - /* 0x38[7] */ - val = (enable) ? 1 : 0; - halbtc8821c2ant_write_indirect_reg(btc, 0x38, BIT(7), val); -} - -static -void halbtc8821c2ant_ltecoex_table(struct btc_coexist *btc, u8 table_type, - u16 val) -{ - u16 reg_addr = 0x0000; - - switch (table_type) { - case BT_8821C_2ANT_CTT_WL_VS_LTE: - reg_addr = 0xa0; - break; - case BT_8821C_2ANT_CTT_BT_VS_LTE: - reg_addr = 0xa4; - break; - } - - /* 0xa0[15:0] or 0xa4[15:0] */ - if (reg_addr != 0x0000) - halbtc8821c2ant_write_indirect_reg(btc, reg_addr, 0xffff, val); -} - -static -void halbtc8821c2ant_coex_ctrl_owner(struct btc_coexist *btc, - boolean wifi_control) -{ - u8 val; - - /* 0x70[26] */ - val = (wifi_control) ? 1 : 0; - btc->btc_write_1byte_bitmask(btc, 0x73, BIT(2), val); -} - -static void -halbtc8821c2ant_set_gnt_bt(struct btc_coexist *btc, u8 state) -{ - switch (state) { - case BTC_GNT_SET_SW_LOW: - halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0xc000, 0x1); - halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0c00, 0x1); - break; - case BTC_GNT_SET_SW_HIGH: - halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0xc000, 0x3); - halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0c00, 0x3); - break; - case BTC_GNT_SET_HW_PTA: - default: - halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0xc000, 0x0); - halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0c00, 0x0); - break; - } -} - -static void -halbtc8821c2ant_set_gnt_wl(struct btc_coexist *btc, u8 state) -{ - switch (state) { - case BTC_GNT_SET_SW_LOW: - halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x3000, 0x1); - halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0300, 0x1); - break; - case BTC_GNT_SET_SW_HIGH: - halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x3000, 0x3); - halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0300, 0x3); - break; - case BTC_GNT_SET_HW_PTA: - default: - halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x3000, 0x0); - halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0300, 0x0); - break; - } -} - -static -void halbtc8821c2ant_set_table(struct btc_coexist *btc, - boolean force_exec, u32 val0x6c0, - u32 val0x6c4, u32 val0x6c8, - u8 val0x6cc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - - if (!force_exec && !coex_sta->wl_slot_toggle_change) { - coex_dm->cur_val0x6c0 = btc->btc_read_4byte(btc, 0x6c0); - coex_dm->cur_val0x6c4 = btc->btc_read_4byte(btc, 0x6c4); - - if (val0x6c0 == coex_dm->cur_val0x6c0 && - val0x6c4 == coex_dm->cur_val0x6c4) - return; - } - - btc->btc_write_4byte(btc, 0x6c0, val0x6c0); - btc->btc_write_4byte(btc, 0x6c4, val0x6c4); - btc->btc_write_4byte(btc, 0x6c8, val0x6c8); - btc->btc_write_1byte(btc, 0x6cc, val0x6cc); - - coex_dm->cur_val0x6c8 = val0x6c8; - coex_dm->cur_val0x6cc = val0x6cc; -} - -void halbtc8821c2ant_table(struct btc_coexist *btc, boolean force_exec, u8 type) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - u32 break_table; - u8 select_table; - - coex_sta->coex_table_type = type; - - if (coex_sta->concurrent_rx_mode_on == TRUE) { - /* set WL hi-pri can break BT */ - break_table = 0xf0ffffff; - /* set Tx response = Hi-Pri (ex: Transmitting ACK,BA,CTS) */ - select_table = 0x1b; - } else { - break_table = 0xffffff; - select_table = 0x13; - } - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], ********** Table-%d **********\n", - coex_sta->coex_table_type); - BTC_TRACE(trace_buf); - - switch (type) { - case 0: - halbtc8821c2ant_set_table(btc, force_exec, 0xffffffff, - 0xffffffff, break_table, - select_table); - break; - case 1: - halbtc8821c2ant_set_table(btc, force_exec, 0x55555555, - 0xfafafafa, break_table, - select_table); - break; - case 2: - halbtc8821c2ant_set_table(btc, force_exec, 0x5a5a5a5a, - 0x5a5a5a5a, break_table, - select_table); - break; - case 3: - halbtc8821c2ant_set_table(btc, force_exec, 0x66555555, - 0x6a5a5a5a, break_table, - select_table); - break; - case 4: - halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff, - 0xfafafafa, break_table, - select_table); - break; - case 5: - halbtc8821c2ant_set_table(btc, force_exec, 0x55555555, - 0x55555555, break_table, - select_table); - break; - case 6: /* not use */ - halbtc8821c2ant_set_table(btc, force_exec, 0xaaffffaa, - 0x5afa5afa, break_table, - select_table); - break; - case 7: - halbtc8821c2ant_set_table(btc, force_exec, 0xaaffffaa, - 0xfafafafa, break_table, - select_table); - break; - case 8: - halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff, - 0xfafafafa, break_table, - select_table); - break; - case 9: - halbtc8821c2ant_set_table(btc, force_exec, 0x5a5a5a5a, - 0xaaaa5aaa, break_table, - select_table); - break; - case 10: - halbtc8821c2ant_set_table(btc, force_exec, 0xaaaaaaaa, - 0xaaaaaaaa, break_table, - select_table); - break; - case 11: - halbtc8821c2ant_set_table(btc, force_exec, 0xffffffff, - 0xfafafafa, break_table, - select_table); - break; - case 12: - halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff, - 0x5afa5afa, break_table, - select_table); - break; - case 14: - halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff, - 0xaaaaaaaa, break_table, - select_table); - break; - case 15: - halbtc8821c2ant_set_table(btc, force_exec, 0x66555555, - 0xaaaaaaaa, break_table, - select_table); - break; - case 18: - halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff, - 0xffff55ff, break_table, - select_table); - break; - default: - break; - } -} - -#if 0 -static void -halbtc8821c2ant_wltoggle_table(IN struct btc_coexist *btc, - IN boolean force_exec, IN u8 interval, - IN u8 val0x6c4_b0, IN u8 val0x6c4_b1, - IN u8 val0x6c4_b2, IN u8 val0x6c4_b3) -{ - static u8 pre_h2c_parameter[6] = {0}; - u8 cur_h2c_parameter[6] = {0}; - u8 i, match_cnt = 0; - - cur_h2c_parameter[0] = 0x7; /* op_code, 0x7= wlan toggle slot*/ - - cur_h2c_parameter[1] = interval; - cur_h2c_parameter[2] = val0x6c4_b0; - cur_h2c_parameter[3] = val0x6c4_b1; - cur_h2c_parameter[4] = val0x6c4_b2; - cur_h2c_parameter[5] = val0x6c4_b3; -#if 0 - if (!force_exec) { - for (i = 1; i <= 5; i++) { - if (cur_h2c_parameter[i] != pre_h2c_parameter[i]) - break; - - match_cnt++; - } - - if (match_cnt == 5) - return; - } -#endif - for (i = 1; i <= 5; i++) - pre_h2c_parameter[i] = cur_h2c_parameter[i]; - - btc->btc_fill_h2c(btc, 0x69, 6, cur_h2c_parameter); -} -#endif - -static -void halbtc8821c2ant_ignore_wlan_act(struct btc_coexist *btc, - boolean force_exec, boolean enable) -{ - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - u8 h2c_parameter[1] = {0}; - - if (btc->manual_control || btc->stop_coex_dm) - return; - - if (!force_exec) { - if (enable == coex_dm->cur_ignore_wlan_act) - return; - } - - if (enable) - h2c_parameter[0] |= BIT(0); /* function enable */ - - btc->btc_fill_h2c(btc, 0x63, 1, h2c_parameter); - - coex_dm->cur_ignore_wlan_act = enable; -} - -static -void halbtc8821c2ant_lps_rpwm(struct btc_coexist *btc, boolean force_exec, - u8 lps_val, u8 rpwm_val) -{ - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - - if (!force_exec) { - if (lps_val == coex_dm->cur_lps && - rpwm_val == coex_dm->cur_rpwm) - return; - } - - btc->btc_set(btc, BTC_SET_U1_LPS_VAL, &lps_val); - btc->btc_set(btc, BTC_SET_U1_RPWM_VAL, &rpwm_val); - - coex_dm->cur_lps = lps_val; - coex_dm->cur_rpwm = rpwm_val; -} - -static -void halbtc8821c2ant_tdma_check(struct btc_coexist *btc, boolean new_ps_state) -{ - u8 lps_mode = 0x0; - u8 h2c_parameter[5] = {0, 0, 0, 0x40, 0}; - - btc->btc_get(btc, BTC_GET_U1_LPS_MODE, &lps_mode); - - if (lps_mode) { /* already under LPS state */ - if (new_ps_state) { - /* keep state under LPS, do nothing. */ - } else { - /* will leave LPS state, turn off psTdma first */ - btc->btc_fill_h2c(btc, 0x60, 5, h2c_parameter); - } - } else { /* NO PS state */ - if (new_ps_state) { - /* will enter LPS state, turn off psTdma first */ - btc->btc_fill_h2c(btc, 0x60, 5, h2c_parameter); - } else { - /* keep state under NO PS state, do nothing. */ - } - } -} - -static -boolean halbtc8821c2ant_power_save_state(struct btc_coexist *btc, u8 ps_type, - u8 lps_val, u8 rpwm_val) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - boolean low_pwr_disable = FALSE, result = TRUE; - - switch (ps_type) { - case BTC_PS_WIFI_NATIVE: - coex_sta->force_lps_ctrl = FALSE; - /* recover to original 32k low power setting */ - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], %s == BTC_PS_WIFI_NATIVE\n", __func__); - BTC_TRACE(trace_buf); - - low_pwr_disable = FALSE; - /* btc->btc_set(btc, BTC_SET_ACT_DISABLE_LOW_POWER, - * &low_pwr_disable); - */ - btc->btc_set(btc, BTC_SET_ACT_PRE_NORMAL_LPS, NULL); - break; - case BTC_PS_LPS_ON: - coex_sta->force_lps_ctrl = TRUE; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], %s == BTC_PS_LPS_ON\n", __func__); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_tdma_check(btc, TRUE); - halbtc8821c2ant_lps_rpwm(btc, NM_EXCU, lps_val, rpwm_val); - /* when coex force to enter LPS, do not enter 32k low power. */ - low_pwr_disable = TRUE; - btc->btc_set(btc, BTC_SET_ACT_DISABLE_LOW_POWER, - &low_pwr_disable); - /* power save must executed before psTdma.*/ - btc->btc_set(btc, BTC_SET_ACT_ENTER_LPS, NULL); - break; - case BTC_PS_LPS_OFF: - coex_sta->force_lps_ctrl = TRUE; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], %s == BTC_PS_LPS_OFF\n", __func__); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_tdma_check(btc, FALSE); - result = btc->btc_set(btc, BTC_SET_ACT_LEAVE_LPS, NULL); - break; - default: - break; - } - - return result; -} - -static -void halbtc8821c2ant_set_tdma(struct btc_coexist *btc, u8 byte1, u8 byte2, - u8 byte3, u8 byte4, u8 byte5) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - u8 h2c_parameter[5] = {0}; - u8 real_byte1 = byte1, real_byte5 = byte5; - boolean ap_enable = FALSE, result = FALSE; - u8 ps_type = BTC_PS_WIFI_NATIVE; - - if (byte5 & BIT(2)) - coex_sta->is_tdma_btautoslot = TRUE; - else - coex_sta->is_tdma_btautoslot = FALSE; - - if (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO && - btc->wifi_link_info.bhotspot && - btc->wifi_link_info.bany_client_join_go) - ap_enable = TRUE; - - if ((ap_enable) && (byte1 & BIT(4) && !(byte1 & BIT(5)))) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], %s == FW for AP mode\n", __func__); - BTC_TRACE(trace_buf); - - real_byte1 &= ~BIT(4); - real_byte1 |= BIT(5); - - real_byte5 |= BIT(5); - real_byte5 &= ~BIT(6); - - ps_type = BTC_PS_WIFI_NATIVE; - halbtc8821c2ant_power_save_state(btc, ps_type, 0x0, 0x0); - } else if (byte1 & BIT(4) && !(byte1 & BIT(5))) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], %s == Force LPS (byte1 = 0x%x)\n", - __func__, byte1); - BTC_TRACE(trace_buf); - - ps_type = BTC_PS_LPS_OFF; - if (!halbtc8821c2ant_power_save_state(btc, ps_type, 0x50, 0x4)) - result = TRUE; - } else { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], %s == Native LPS (byte1 = 0x%x)\n", - __func__, byte1); - BTC_TRACE(trace_buf); - - ps_type = BTC_PS_WIFI_NATIVE; - halbtc8821c2ant_power_save_state(btc, ps_type, 0x0, 0x0); - } - - coex_sta->is_set_ps_state_fail = result; - - if (!coex_sta->is_set_ps_state_fail) { - h2c_parameter[0] = real_byte1; - h2c_parameter[1] = byte2; - h2c_parameter[2] = byte3; - h2c_parameter[3] = byte4; - h2c_parameter[4] = real_byte5; - - coex_dm->ps_tdma_para[0] = real_byte1; - coex_dm->ps_tdma_para[1] = byte2; - coex_dm->ps_tdma_para[2] = byte3; - coex_dm->ps_tdma_para[3] = byte4; - coex_dm->ps_tdma_para[4] = real_byte5; - - btc->btc_fill_h2c(btc, 0x60, 5, h2c_parameter); - - if (real_byte1 & BIT(2)) { - coex_sta->wl_slot_toggle = TRUE; - coex_sta->wl_slot_toggle_change = FALSE; - } else { - if (coex_sta->wl_slot_toggle) - coex_sta->wl_slot_toggle_change = TRUE; - else - coex_sta->wl_slot_toggle_change = FALSE; - coex_sta->wl_slot_toggle = FALSE; - } - } else { - coex_sta->cnt_set_ps_state_fail++; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], %s == Force Leave LPS Fail (cnt = %d)\n", - __func__, coex_sta->cnt_set_ps_state_fail); - BTC_TRACE(trace_buf); - } - - if (ps_type == BTC_PS_WIFI_NATIVE) - btc->btc_set(btc, BTC_SET_ACT_POST_NORMAL_LPS, NULL); -} - -static -void halbtc8821c2ant_tdma(struct btc_coexist *btc, - boolean force_exec, boolean turn_on, u32 tcase) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - u8 type; - boolean wifi_busy; - - btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); - - btc->btc_set_atomic(btc, &coex_dm->setting_tdma, TRUE); - - /* tcase: bit0~7 --> tdma case index - * bit8 --> for 4-slot (50ms) mode - */ - if (tcase & TDMA_4SLOT)/* 4-slot (50ms) mode */ - halbtc8821c2ant_set_tdma_timer_base(btc, 3); - else - halbtc8821c2ant_set_tdma_timer_base(btc, 0); - - type = (u8)(tcase & 0xff); - - /* To avoid TDMA H2C fail before Last LPS enter */ - if (!force_exec && coex_sta->coex_run_reason != BTC_RSN_LPS) { - if (turn_on == coex_dm->cur_ps_tdma_on && - type == coex_dm->cur_ps_tdma) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Skip TDMA because no change TDMA(%s, %d)\n", - (coex_dm->cur_ps_tdma_on ? "on" : "off"), - coex_dm->cur_ps_tdma); - BTC_TRACE(trace_buf); - - btc->btc_set_atomic(btc, &coex_dm->setting_tdma, FALSE); - return; - } - } - - if (!wifi_busy || - (coex_sta->a2dp_exist && - (coex_sta->bt_inq_page_remain || coex_sta->is_bt_multi_link))) - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_TDMA, - FALSE); - else - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_TDMA, - TRUE); - - if (turn_on) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], ********** TDMA(on, %d) **********\n", - type); - BTC_TRACE(trace_buf); - - /* enable TBTT nterrupt */ - btc->btc_write_1byte_bitmask(btc, 0x550, 0x8, 0x1); - - switch (type) { - case 1: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x91, - 0x50); - break; - case 2: - default: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x35, 0x03, 0x11, - 0x11); - break; - case 3: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x30, 0x3, 0x91, - 0x10); - break; - case 4: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x21, 0x3, 0x91, - 0x10); - break; - case 5: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x25, 0x3, 0x91, - 0x10); - break; - case 6: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x3, 0x91, - 0x10); - break; - case 7: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x20, 0x3, 0x91, - 0x10); - break; - case 8: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x15, 0x03, 0x11, - 0x11); - break; - case 10: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x30, 0x03, 0x11, - 0x10); - break; - case 11: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x35, 0x03, 0x11, - 0x10); - break; - case 12: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x35, 0x03, 0x11, - 0x11); - break; - case 13: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x20, 0x03, 0x11, - 0x10); - break; - case 14: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x20, 0x03, 0x11, - 0x11); - break; - case 15: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x11, - 0x10); - break; - case 16: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x11, - 0x11); - break; - case 17: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x08, 0x03, 0x11, - 0x14); - break; - case 21: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x30, 0x03, 0x11, - 0x10); - break; - case 22: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x25, 0x03, 0x11, - 0x10); - break; - case 23: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x11, - 0x10); - break; - case 25: - halbtc8821c2ant_set_tdma(btc, 0x51, 0x3a, 0x3, 0x11, - 0x50); - break; - case 51: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x91, - 0x10); - break; - case 101: - halbtc8821c2ant_set_tdma(btc, 0x51, 0x08, 0x03, 0x10, - 0x54); - break; - case 102: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x35, 0x03, 0x11, - 0x11); - break; - case 103: - halbtc8821c2ant_set_tdma(btc, 0x51, 0x30, 0x3, 0x10, - 0x50); - break; - case 104: - halbtc8821c2ant_set_tdma(btc, 0x51, 0x21, 0x3, 0x10, - 0x50); - break; - case 105: - halbtc8821c2ant_set_tdma(btc, 0x51, 0x45, 0x3, 0x10, - 0x50); - break; - case 106: - halbtc8821c2ant_set_tdma(btc, 0x51, 0x1a, 0x3, 0x10, - 0x50); - break; - case 107: - halbtc8821c2ant_set_tdma(btc, 0x51, 0x08, 0x7, 0x10, - 0x54); - break; - case 108: - halbtc8821c2ant_set_tdma(btc, 0x51, 0x30, 0x3, 0x10, - 0x50); - break; - case 109: - halbtc8821c2ant_set_tdma(btc, 0x51, 0x08, 0x03, 0x10, - 0x54); - break; - case 110: - halbtc8821c2ant_set_tdma(btc, 0x51, 0x30, 0x03, 0x10, - 0x50); - break; - case 111: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x25, 0x03, 0x11, - 0x11); - break; - case 112: - halbtc8821c2ant_set_tdma(btc, 0x51, 0x4a, 0x3, 0x10, - 0x50); - break; - case 113: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x45, 0x03, 0x11, - 0x10); - break; - case 115: - halbtc8821c2ant_set_tdma(btc, 0x51, 0x30, 0x03, 0x10, - 0x50); - break; - case 116: - halbtc8821c2ant_set_tdma(btc, 0x51, 0x08, 0x03, 0x10, - 0x50); - break; - case 117: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x08, 0x03, 0x11, - 0x11); - break; - case 119: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x08, 0x03, 0x10, - 0x14); - break; - case 120: - halbtc8821c2ant_set_tdma(btc, 0x61, 0x08, 0x03, 0x10, - 0x15); - break; - case 151: - halbtc8821c2ant_set_tdma(btc, 0x51, 0x10, 0x03, 0x10, - 0x50); - break; - } - } else { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], ********** TDMA(off, %d) **********\n", - type); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_TDMA, FALSE); - - /* disable PS tdma */ - switch (type) { - case 0: - halbtc8821c2ant_set_tdma(btc, 0x0, 0x0, 0x0, 0x40, 0x0); - break; - case 1: - halbtc8821c2ant_set_tdma(btc, 0x0, 0x0, 0x0, 0x48, 0x0); - break; - default: - halbtc8821c2ant_set_tdma(btc, 0x0, 0x0, 0x0, 0x40, 0x0); - break; - } - } - - coex_dm->cur_ps_tdma_on = turn_on; - coex_dm->cur_ps_tdma = type; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "change TDMA(%s, %d)\n", - (coex_dm->cur_ps_tdma_on ? "on" : "off"), - coex_dm->cur_ps_tdma); - BTC_TRACE(trace_buf); - - btc->btc_set_atomic(btc, &coex_dm->setting_tdma, FALSE); -} - -static -void halbtc8821c2ant_set_ant_switch(struct btc_coexist *btc, - boolean force_exec, u8 ctrl_type, - u8 pos_type) -{ - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - struct rfe_type_8821c_2ant *rfe_type = &btc->rfe_type_8821c_2ant; - struct btc_board_info *board_info = &btc->board_info; - boolean polarity_inverse = FALSE; - u8 val = 0; - u32 u32tmp1 = 0, u32tmp2 = 0, u32tmp3 = 0; - - if (!rfe_type->ext_ant_switch_exist) - return; - - if (!force_exec) { - if (((ctrl_type << 8) + pos_type) == - coex_dm->cur_ext_ant_switch_status) - return; - } - - coex_dm->cur_ext_ant_switch_status = (ctrl_type << 8) + pos_type; - - /* swap control polarity if use different switch control polarity - * Normal switch polarity for DPDT, - * 0xcb4[29:28] = 2b'01 => BTG to Main, WLG to Aux, - * 0xcb4[29:28] = 2b'10 => BTG to Aux, WLG to Main - * Normal switch polarity for SPDT, - * 0xcb4[29:28] = 2b'01 => Ant to BTG, - * 0xcb4[29:28] = 2b'10 => Ant to WLG - */ - if (rfe_type->ext_ant_switch_ctrl_polarity) - polarity_inverse = !polarity_inverse; - - /* swap control polarity if 1-Ant at Aux */ - if (rfe_type->ant_at_main_port == FALSE) - polarity_inverse = !polarity_inverse; - - switch (pos_type) { - default: - case BT_8821C_2ANT_TO_BT: - case BT_8821C_2ANT_TO_NOCARE: - case BT_8821C_2ANT_TO_WLA: - - break; - case BT_8821C_2ANT_TO_WLG: - if (!rfe_type->wlg_locate_at_btg) - polarity_inverse = !polarity_inverse; - - break; - } - - if (board_info->ant_div_cfg && ctrl_type == BT_8821C_2ANT_CTRL_BY_BBSW) - ctrl_type = BT_8821C_2ANT_CTRL_BY_ANTDIV; - - switch (ctrl_type) { - default: - case BT_8821C_2ANT_CTRL_BY_BBSW: - /* 0x4c[23] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0); - /* 0x4c[24] = 1 */ - btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x1); - /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as control pin */ - btc->btc_write_1byte_bitmask(btc, 0xcb4, 0xff, 0x77); - /* 0xcb4[29:28] = 2b'01 for no switch_polarity_inverse, - * DPDT_SEL_N =1, DPDT_SEL_P =0 - */ - val = (!polarity_inverse ? 0x1 : 0x2); - btc->btc_write_1byte_bitmask(btc, 0xcb7, 0x30, val); - break; - case BT_8821C_2ANT_CTRL_BY_PTA: - /* 0x4c[23] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0); - /* 0x4c[24] = 1 */ - btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x1); - /* PTA, DPDT use RFE_ctrl8 and RFE_ctrl9 as control pin */ - btc->btc_write_1byte_bitmask(btc, 0xcb4, 0xff, 0x66); - /* 0xcb4[29:28] = 2b'10 for no switch_polatiry_inverse, - * DPDT_SEL_N =1, DPDT_SEL_P =0 @ GNT_BT=1 - */ - val = (!polarity_inverse ? 0x2 : 0x1); - btc->btc_write_1byte_bitmask(btc, 0xcb7, 0x30, val); - break; - case BT_8821C_2ANT_CTRL_BY_ANTDIV: - /* 0x4c[23] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0); - /* 0x4c[24] = 1 */ - btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x1); - btc->btc_write_1byte_bitmask(btc, 0xcb4, 0xff, 0x88); - - /* no regval_0xcb7 setup required, because antenna switch - * control value by antenna diversity - */ - break; - case BT_8821C_2ANT_CTRL_BY_MAC: - /* 0x4c[23] = 1 */ - btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x1); - /* 0x64[0] = 1b'0 for no switch_polarity_inverse, - * DPDT_SEL_N =1, DPDT_SEL_P =0 - */ - val = (!polarity_inverse ? 0x0 : 0x1); - btc->btc_write_1byte_bitmask(btc, 0x64, 0x1, val); - break; - case BT_8821C_2ANT_CTRL_BY_FW: - /* 0x4c[23] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0); - /* 0x4c[24] = 1 */ - btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x1); - break; - case BT_8821C_2ANT_CTRL_BY_BT: - /* 0x4c[23] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0); - /* 0x4c[24] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x0); - /* no setup required, because antenna switch control value - * by BT vendor 0xac[1:0] - */ - break; - } - - /* PAPE, LNA_ON control by BT while WLAN off - * for current leakage issue - */ - if (ctrl_type == BT_8821C_2ANT_CTRL_BY_BT) { - /* PAPE 0x64[29] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x67, 0x20, 0x0); - /* LNA_ON 0x64[28] = 0 */ - btc->btc_write_1byte_bitmask(btc, 0x67, 0x10, 0x0); - } else { - /* PAPE 0x64[29] = 1 */ - btc->btc_write_1byte_bitmask(btc, 0x67, 0x20, 0x1); - /* LNA_ON 0x64[28] = 1 */ - btc->btc_write_1byte_bitmask(btc, 0x67, 0x10, 0x1); - } -} - -static -void halbtc8821c2ant_set_rfe_type(struct btc_coexist *btc) -{ - struct rfe_type_8821c_2ant *rfe_type = &btc->rfe_type_8821c_2ant; - struct btc_board_info *board_info = &btc->board_info; - - /* the following setup should be got from Efuse in the future */ - rfe_type->rfe_module_type = board_info->rfe_type & 0x1f; - - rfe_type->ext_ant_switch_ctrl_polarity = 0; - - switch (rfe_type->rfe_module_type) { - case 0: - case 8: - default: /*2-Ant, DPDT, WLG*/ - rfe_type->ext_ant_switch_exist = TRUE; - rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_DPDT; - rfe_type->wlg_locate_at_btg = FALSE; - rfe_type->ant_at_main_port = TRUE; - break; - case 1: - case 9: /*1-Ant, Main, WLG */ - rfe_type->ext_ant_switch_exist = TRUE; - rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_SPDT; - rfe_type->wlg_locate_at_btg = FALSE; - rfe_type->ant_at_main_port = TRUE; - break; - case 2: - case 10: /*1-Ant, Main, BTG */ - rfe_type->ext_ant_switch_exist = TRUE; - rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_SPDT; - rfe_type->wlg_locate_at_btg = TRUE; - rfe_type->ant_at_main_port = TRUE; - break; - case 3: - case 11: /*1-Ant, Aux, WLG */ - rfe_type->ext_ant_switch_exist = TRUE; - rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_DPDT; - rfe_type->wlg_locate_at_btg = FALSE; - rfe_type->ant_at_main_port = FALSE; - break; - case 4: - case 12: /*1-Ant, Aux, BTG */ - rfe_type->ext_ant_switch_exist = TRUE; - rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_DPDT; - rfe_type->wlg_locate_at_btg = TRUE; - rfe_type->ant_at_main_port = FALSE; - break; - case 5: - case 13: /*2-Ant, no switch, WLG*/ - rfe_type->ext_ant_switch_exist = FALSE; - rfe_type->ext_ant_switch_type = BT_8821C_2ANT_SWITCH_NONE; - rfe_type->wlg_locate_at_btg = FALSE; - rfe_type->ant_at_main_port = TRUE; - break; - case 6: - case 14: /*2-Ant, no antenna switch, WLG*/ - rfe_type->ext_ant_switch_exist = FALSE; - rfe_type->ext_ant_switch_type = BT_8821C_2ANT_SWITCH_NONE; - rfe_type->wlg_locate_at_btg = FALSE; - rfe_type->ant_at_main_port = TRUE; - break; - case 7: - case 15: /*2-Ant, DPDT, BTG*/ - rfe_type->ext_ant_switch_exist = TRUE; - rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_DPDT; - rfe_type->wlg_locate_at_btg = TRUE; - rfe_type->ant_at_main_port = TRUE; - break; - } -} - -static -void halbtc8821c2ant_set_ant_path(struct btc_coexist *btc, - u8 ant_pos_type, boolean force_exec, - u8 phase) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - struct btc_board_info *board_info = &btc->board_info; - u32 cnt_bt_cal_chk = 0, u32tmp1 = 0, u32tmp2 = 0; - u8 u8tmp = 0, ctrl_type, pos_type; - - if (!force_exec) { - if (coex_dm->cur_ant_pos_type == ((ant_pos_type << 8) + phase)) - return; - } - - coex_dm->cur_ant_pos_type = (ant_pos_type << 8) + phase; - - if (btc->dbg_mode) { - u32tmp1 = btc->btc_read_4byte(btc, 0xcbc); - u32tmp2 = btc->btc_read_4byte(btc, 0xcb4); - u8tmp = btc->btc_read_1byte(btc, 0x73); - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], (Before Ant Setup) 0xcb4 = 0x%x, 0xcbc = 0x%x, 0x73 = 0x%x\n", - u32tmp1, u32tmp2, u8tmp); - BTC_TRACE(trace_buf); - } - - switch (phase) { - case BT_8821C_2ANT_PHASE_POWERON: - /* set Path control owner to WL at initial step */ - halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_BTSIDE); - - if (ant_pos_type == BTC_ANT_PATH_AUTO) { - if (board_info->btdm_ant_pos == - BTC_ANTENNA_AT_MAIN_PORT) - ant_pos_type = BTC_ANT_WIFI_AT_MAIN; - else - ant_pos_type = BTC_ANT_WIFI_AT_AUX; - } - - coex_sta->run_time_state = FALSE; - break; - case BT_8821C_2ANT_PHASE_INIT: - /* Disable LTE Coex Function in WiFi side - * (this should be on if LTE coex is required) - */ - halbtc8821c2ant_ltecoex_enable(btc, 0x0); - - /* GNT_WL_LTE always = 1 - * (this should be config if LTE coex is required) - */ - halbtc8821c2ant_ltecoex_table(btc, BT_8821C_2ANT_CTT_WL_VS_LTE, - 0xffff); - - /* GNT_BT_LTE always = 1 - * (this should be config if LTE coex is required) - */ - halbtc8821c2ant_ltecoex_table(btc, BT_8821C_2ANT_CTT_BT_VS_LTE, - 0xffff); - - /* Wait If BT IQK running, because Path control owner - * is at BT during BT IQK (setup by WiFi firmware) - */ - while (cnt_bt_cal_chk <= 20) { - u8tmp = btc->btc_read_1byte(btc, 0x49c); - cnt_bt_cal_chk++; - - if (u8tmp & BIT(1)) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], ########### BT is calibrating (wait cnt=%d)\n", - cnt_bt_cal_chk); - BTC_TRACE(trace_buf); - delay_ms(10); - } else { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], ********** BT is NOT calibrating (wait cnt=%d)\n", - cnt_bt_cal_chk); - BTC_TRACE(trace_buf); - break; - } - } - - /* set Path control owner to WL at initial step */ - halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE); - - /* set GNT_BT to SW high */ - halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_SW_HIGH); - /* Set GNT_WL to SW high */ - halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_HIGH); - - coex_sta->run_time_state = FALSE; - - if (ant_pos_type == BTC_ANT_PATH_AUTO) { - if (board_info->btdm_ant_pos == - BTC_ANTENNA_AT_MAIN_PORT) - ant_pos_type = BTC_ANT_WIFI_AT_MAIN; - else - ant_pos_type = BTC_ANT_WIFI_AT_AUX; - } - break; - case BT_8821C_2ANT_PHASE_WONLY: - /* Disable LTE Coex Function in WiFi side - * (this should be on if LTE coex is required) - */ - halbtc8821c2ant_ltecoex_enable(btc, 0x0); - - /* GNT_WL_LTE always = 1 - * (this should be config if LTE coex is required) - */ - halbtc8821c2ant_ltecoex_table(btc, BT_8821C_2ANT_CTT_WL_VS_LTE, - 0xffff); - - /* GNT_BT_LTE always = 1 - * (this should be config if LTE coex is required) - */ - halbtc8821c2ant_ltecoex_table(btc, BT_8821C_2ANT_CTT_BT_VS_LTE, - 0xffff); - - /* set Path control owner to WL at initial step */ - halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE); - - /* set GNT_BT to SW Low */ - halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_SW_LOW); - /* Set GNT_WL to SW high */ - halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_HIGH); - - coex_sta->run_time_state = FALSE; - - if (ant_pos_type == BTC_ANT_PATH_AUTO) { - if (board_info->btdm_ant_pos == - BTC_ANTENNA_AT_MAIN_PORT) - ant_pos_type = BTC_ANT_WIFI_AT_MAIN; - else - ant_pos_type = BTC_ANT_WIFI_AT_AUX; - } - - break; - case BT_8821C_2ANT_PHASE_WOFF: - /* Disable LTE Coex Function in WiFi side */ - halbtc8821c2ant_ltecoex_enable(btc, 0x0); - - /* set Path control owner to BT */ - halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_BTSIDE); - - coex_sta->run_time_state = FALSE; - break; - case BT_8821C_2ANT_PHASE_2G: - while (cnt_bt_cal_chk <= 20) { - /* 0x49c[0]=1 WL IQK, 0x49c[1]=1 BT IQK*/ - u8tmp = btc->btc_read_1byte(btc, 0x49c); - - cnt_bt_cal_chk++; - if (u8tmp & BIT(0)) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], ########### WL is IQK (wait cnt=%d)\n", - cnt_bt_cal_chk); - BTC_TRACE(trace_buf); - delay_ms(10); - } else if (u8tmp & BIT(1)) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], ########### BT is IQK (wait cnt=%d)\n", - cnt_bt_cal_chk); - BTC_TRACE(trace_buf); - delay_ms(10); - } else { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], ********** WL and BT is NOT IQK (wait cnt=%d)\n", - cnt_bt_cal_chk); - BTC_TRACE(trace_buf); - break; - } - } - - /* set Path control owner to WL at runtime step */ - halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE); - - /* set GNT_BT to PTA */ - halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_HW_PTA); - - /* Set GNT_WL to PTA */ - halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_HW_PTA); - - coex_sta->run_time_state = TRUE; - - if (ant_pos_type == BTC_ANT_PATH_AUTO) { - if (board_info->btdm_ant_pos == - BTC_ANTENNA_AT_MAIN_PORT) - ant_pos_type = BTC_ANT_WIFI_AT_MAIN; - else - ant_pos_type = BTC_ANT_WIFI_AT_AUX; - } - - break; - case BT_8821C_2ANT_PHASE_5G: - /* set Path control owner to WL at runtime step */ - halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE); - - /* set GNT_BT to PTA */ - halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_HW_PTA); - - /* Set GNT_WL to SW Hi */ - halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_HIGH); - - coex_sta->run_time_state = TRUE; - - if (ant_pos_type == BTC_ANT_PATH_AUTO) { - if (board_info->btdm_ant_pos == - BTC_ANTENNA_AT_MAIN_PORT) - ant_pos_type = BTC_ANT_WIFI_AT_MAIN; - else - ant_pos_type = BTC_ANT_WIFI_AT_AUX; - } - - break; - case BT_8821C_2ANT_PHASE_BTMP: - /* Disable LTE Coex Function in WiFi side */ - halbtc8821c2ant_ltecoex_enable(btc, 0x0); - - /* set Path control owner to WL */ - halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE); - - /* set GNT_BT to SW Hi */ - halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_SW_HIGH); - - /* Set GNT_WL to SW Lo */ - halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_LOW); - - coex_sta->run_time_state = FALSE; - - if (ant_pos_type == BTC_ANT_PATH_AUTO) { - if (board_info->btdm_ant_pos == - BTC_ANTENNA_AT_MAIN_PORT) - ant_pos_type = BTC_ANT_WIFI_AT_MAIN; - else - ant_pos_type = BTC_ANT_WIFI_AT_AUX; - } - - break; - case BT_8821C_2ANT_PHASE_ANTDET: - halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE); - - /* set GNT_BT to high */ - halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_SW_HIGH); - /* Set GNT_WL to high */ - halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_HIGH); - - if (ant_pos_type == BTC_ANT_PATH_AUTO) { - if (board_info->btdm_ant_pos == - BTC_ANTENNA_AT_MAIN_PORT) - ant_pos_type = BTC_ANT_WIFI_AT_MAIN; - else - ant_pos_type = BTC_ANT_WIFI_AT_AUX; - } - - coex_sta->run_time_state = FALSE; - break; - } - - if (phase == BT_8821C_2ANT_PHASE_WOFF) { - /* Set Ext Ant Switch to BT control at wifi off step */ - ctrl_type = BT_8821C_2ANT_CTRL_BY_BT; - pos_type = BT_8821C_2ANT_TO_NOCARE; - } else { - switch (ant_pos_type) { - default: - case BTC_ANT_WIFI_AT_MAIN: - ctrl_type = BT_8821C_2ANT_CTRL_BY_BBSW; - pos_type = BT_8821C_2ANT_TO_WLG; - break; - case BTC_ANT_WIFI_AT_AUX: - ctrl_type = BT_8821C_2ANT_CTRL_BY_BBSW; - pos_type = BT_8821C_2ANT_TO_BT; - break; - case BTC_ANT_WIFI_AT_DIVERSITY: - ctrl_type = BT_8821C_2ANT_CTRL_BY_ANTDIV; - pos_type = BT_8821C_2ANT_TO_NOCARE; - break; - } - } - - halbtc8821c2ant_set_ant_switch(btc, force_exec, ctrl_type, pos_type); - - if (btc->dbg_mode) { - u32tmp1 = btc->btc_read_4byte(btc, 0xcbc); - u32tmp2 = btc->btc_read_4byte(btc, 0xcb4); - u8tmp = btc->btc_read_1byte(btc, 0x73); - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], (After Ant Setup) 0xcb4 = 0x%x, 0xcbc = 0x%x, 0x73 = 0x%x\n", - u32tmp1, u32tmp2, u8tmp); - BTC_TRACE(trace_buf); - } -} - -static -u8 halbtc8821c2ant_action_algorithm(struct btc_coexist *btc) -{ - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; - u8 algorithm = BT_8821C_2ANT_COEX_UNDEFINED; - u8 profile_map = 0; - - if (bt_link_info->sco_exist) - profile_map = profile_map | BIT(0); - - if (bt_link_info->hid_exist) - profile_map = profile_map | BIT(1); - - if (bt_link_info->a2dp_exist) - profile_map = profile_map | BIT(2); - - if (bt_link_info->pan_exist) - profile_map = profile_map | BIT(3); - - switch (profile_map) { - case 0: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], No BT link exists!!!\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_UNDEFINED; - break; - case 1: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = SCO only\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_SCO; - break; - case 2: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = HID only\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_HID; - break; - case 3: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = SCO + HID ==> HID\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_HID; - break; - case 4: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = A2DP only\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_A2DP; - break; - case 5: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = SCO + A2DP ==> HID + A2DP\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_HID_A2DP; - break; - case 6: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = HID + A2DP\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_HID_A2DP; - break; - case 7: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = SCO + HID + A2DP ==> HID + A2DP\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_HID_A2DP; - break; - case 8: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = PAN(EDR) only\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_PAN; - break; - case 9: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = SCO + PAN(EDR) ==> HID + PAN(EDR)\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_PAN_HID; - break; - case 10: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = HID + PAN(EDR)\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_PAN_HID; - break; - case 11: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = SCO + HID + PAN(EDR) ==> HID + PAN(EDR)\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_PAN_HID; - break; - case 12: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = A2DP + PAN(EDR)\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_PAN_A2DP; - break; - case 13: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> A2DP + PAN(EDR)\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_PAN_A2DP; - break; - case 14: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = HID + A2DP + PAN(EDR) ==> A2DP + PAN(EDR)\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_PAN_A2DP; - break; - case 15: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR) ==> A2DP + PAN(EDR)\n"); - BTC_TRACE(trace_buf); - algorithm = BT_8821C_2ANT_COEX_PAN_A2DP; - break; - } - - return algorithm; -} - -static void halbtc8821c2ant_action_freerun(struct btc_coexist *btc) -{ - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - halbtc8821c2ant_table(btc, NM_EXCU, 0); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); -} - -static -void halbtc8821c2ant_action_coex_all_off(struct btc_coexist *btc) -{ - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - halbtc8821c2ant_table(btc, NM_EXCU, 0); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); -} - -static -void halbtc8821c2ant_action_bt_whql_test(struct btc_coexist *btc) -{ - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - halbtc8821c2ant_table(btc, NM_EXCU, 0); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); -} - -static -void halbtc8821c2ant_action_bt_inquiry(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; - boolean wifi_connected = FALSE, wifi_busy = FALSE; - - halbtc8821c2ant_set_wl_tx_power(btc, FC_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); - btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); - - if (coex_sta->is_wifi_linkscan_process || - coex_sta->wifi_high_pri_task1 || - coex_sta->wifi_high_pri_task2) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], bt inq/page + wifi hi-pri task\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_table(btc, NM_EXCU, 8); - - if (bt_link_info->bt_link_exist) - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 15); - else if (coex_sta->wifi_high_pri_task1) - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 113); - else if (!coex_sta->bt_create_connection) - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 10); - else - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 13); - } else if (wifi_busy) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], bt inq/page + wifi busy\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_table(btc, NM_EXCU, 8); - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 151); - } else if (wifi_connected) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], bt inq/page + wifi connected\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_table(btc, NM_EXCU, 8); - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 117); - } else { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], bt inq/page + wifi not-connected\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_table(btc, NM_EXCU, 0); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); - } -} - -static -void halbtc8821c2ant_action_bt_relink(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - - if (coex_sta->gl_wifi_busy) - halbtc8821c2ant_table(btc, NM_EXCU, 18); - else - halbtc8821c2ant_table(btc, NM_EXCU, 5); - - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); -} - -static -void halbtc8821c2ant_action_bt_idle(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW; - u8 wifi_rssi_state; - - wifi_rssi_state = - halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2, - 40, 0); - - if (!coex_sta->gl_wifi_busy) { - halbtc8821c2ant_table(btc, NM_EXCU, 8); - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 14); - } else { /* if wl busy */ - if ((coex_sta->bt_ble_scan_type & 0x2) && - coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE) { - halbtc8821c2ant_table(btc, NM_EXCU, 14); - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 12); - } else { - if (BTC_RSSI_HIGH(wifi_rssi_state)) - halbtc8821c2ant_table(btc, NM_EXCU, 8); - else - halbtc8821c2ant_table(btc, NM_EXCU, 3); - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 12); - } - } - - halbtc8821c2ant_set_wl_tx_power(btc, FC_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); -} - -static -void halbtc8821c2ant_action_bt_mr(struct btc_coexist *btc) -{ - struct wifi_link_info_8821c_2ant *wifi_link_info_ext = - &btc->wifi_link_info_8821c_2ant; - - if (!wifi_link_info_ext->is_all_under_5g) { - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8821C_2ANT_PHASE_2G); - - halbtc8821c2ant_table(btc, NM_EXCU, 0); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); - } else { - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8821C_2ANT_PHASE_5G); - - halbtc8821c2ant_table(btc, NM_EXCU, 0); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); - } -} - -static -void halbtc8821c2ant_action_sco(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - if (coex_sta->is_bt_multi_link) { - halbtc8821c2ant_table(btc, NM_EXCU, 8); - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 25); - } else { - if (coex_sta->is_esco_mode) - halbtc8821c2ant_table(btc, NM_EXCU, 1); - else /* 2-Ant free run if SCO mode */ - halbtc8821c2ant_table(btc, NM_EXCU, 0); - - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 8); - } -} - -static -void halbtc8821c2ant_action_hid(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - boolean wifi_busy = FALSE; - - btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); - - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - if (coex_sta->is_hid_low_pri_tx_overhead) { - halbtc8821c2ant_table(btc, NM_EXCU, 12); - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 108); - } else if (coex_sta->is_hid_rcu) { - halbtc8821c2ant_table(btc, NM_EXCU, 12); - - if (wifi_busy) - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 113); - else - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 111); - } else { - halbtc8821c2ant_table(btc, NM_EXCU, 12); - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 111); - } -} - -static -void halbtc8821c2ant_action_a2dpsink(struct btc_coexist *btc) -{ - boolean ap_enable = FALSE; - - if (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO && - btc->wifi_link_info.bhotspot && - btc->wifi_link_info.bany_client_join_go) - ap_enable = TRUE; - - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - if (ap_enable) { - halbtc8821c2ant_table(btc, NM_EXCU, 0); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); - } else { - halbtc8821c2ant_table(btc, NM_EXCU, 8); - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 104); - } -} - -static -void halbtc8821c2ant_action_a2dp(struct btc_coexist *btc) -{ - static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW; - u8 wifi_rssi_state; - boolean wifi_busy = FALSE; - - btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); - - wifi_rssi_state = - halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2, - 45, 0); - - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - halbtc8821c2ant_table(btc, NM_EXCU, 8); - - if (!wifi_busy) - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 120 | TDMA_4SLOT); - else if (BTC_RSSI_HIGH(wifi_rssi_state)) - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 119 | TDMA_4SLOT); - else - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 101 | TDMA_4SLOT); -} - -static -void halbtc8821c2ant_action_pan(struct btc_coexist *btc) -{ - boolean wifi_busy = FALSE; - - static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW; - u8 wifi_rssi_state; - - btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); - - wifi_rssi_state = - halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2, - 58, 0); - - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - /* for Lenovo CPT_For_WiFi OPP test */ - if (btc->board_info.customer_id == RT_CID_LENOVO_CHINA && - BTC_RSSI_HIGH(wifi_rssi_state) && wifi_busy) { - halbtc8821c2ant_table(btc, NM_EXCU, 8); - - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 103); - } else { - halbtc8821c2ant_table(btc, NM_EXCU, 8); - - if (wifi_busy) - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 103); - else - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 104); - } -} - -static -void halbtc8821c2ant_action_hid_a2dp(struct btc_coexist *btc) -{ - static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW; - u8 wifi_rssi_state; - - wifi_rssi_state = - halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2, - 45, 0); - - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - halbtc8821c2ant_table(btc, NM_EXCU, 12); - - if (BTC_RSSI_HIGH(wifi_rssi_state)) - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 119 | TDMA_4SLOT); - else - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 109 | TDMA_4SLOT); -} - -static -void halbtc8821c2ant_action_pan_a2dp(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW; - u8 wifi_rssi_state; - boolean wifi_busy = FALSE; - u8 iot_peer = BTC_IOT_PEER_UNKNOWN; - - btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); - btc->btc_get(btc, BTC_GET_U1_IOT_PEER, &iot_peer); - - if (!wifi_busy) - wifi_busy = coex_sta->gl_wifi_busy; - - wifi_rssi_state = - halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2, - 42, 0); - - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - - /* for Lenovo coex test case */ - if (btc->board_info.customer_id == RT_CID_LENOVO_CHINA && - coex_sta->scan_ap_num <= 10 && - iot_peer == BTC_IOT_PEER_ATHEROS) { - /* for CPT_for_WiFi */ - if (BTC_RSSI_LOW(wifi_rssi_state)) { - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 20); - if (wifi_busy) { - halbtc8821c2ant_table(btc, NM_EXCU, 7); - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 110); - } else { - halbtc8821c2ant_table(btc, NM_EXCU, 7); - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 107); - } - } else { /* for CPT_for_BT */ - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - halbtc8821c2ant_table(btc, NM_EXCU, 8); - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 116); - } - } else { - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - halbtc8821c2ant_table(btc, NM_EXCU, 8); - - if (wifi_busy) - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 107); - else - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 106); - } -} - -static -void halbtc8821c2ant_action_pan_hid(struct btc_coexist *btc) -{ - boolean wifi_busy = FALSE; - - btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); - - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - halbtc8821c2ant_table(btc, NM_EXCU, 8); - - if (wifi_busy) - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 103); - else - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 104); -} - -static -void halbtc8821c2ant_action_hid_a2dp_pan(struct btc_coexist *btc) -{ - boolean wifi_busy = FALSE; - - btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); - - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - halbtc8821c2ant_table(btc, NM_EXCU, 12); - - if (wifi_busy) - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 107); - else - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 106); -} - -static -void halbtc8821c2ant_action_wifi_under5g(struct btc_coexist *btc) -{ - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8821C_2ANT_PHASE_5G); - /* fw all off */ - halbtc8821c2ant_table(btc, NM_EXCU, 0); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); -} - -static -void halbtc8821c2ant_action_wifi_native_lps(struct btc_coexist *btc) -{ - halbtc8821c2ant_table(btc, NM_EXCU, 4); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); -} - -static -void halbtc8821c2ant_action_wifi_linkscan(struct btc_coexist *btc) -{ - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; - - halbtc8821c2ant_set_wl_tx_power(btc, FC_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - halbtc8821c2ant_table(btc, NM_EXCU, 8); - - if (bt_link_info->pan_exist) - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 22); - else if (bt_link_info->a2dp_exist) - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 16); - else - halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 21); -} - -static -void halbtc8821c2ant_action_wifi_not_connected(struct btc_coexist *btc) -{ - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - halbtc8821c2ant_table(btc, NM_EXCU, 0); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); -} - -static -void halbtc8821c2ant_action_wifi_connected(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - - coex_dm->cur_algorithm = halbtc8821c2ant_action_algorithm(btc); - - if (halbtc8821c2ant_freerun_check(btc)) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Action 2-Ant, Frerun().\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_freerun(btc); - return; - } - - switch (coex_dm->cur_algorithm) { - case BT_8821C_2ANT_COEX_SCO: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Action 2-Ant, algorithm = SCO.\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_sco(btc); - break; - case BT_8821C_2ANT_COEX_HID: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Action 2-Ant, algorithm = HID.\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_hid(btc); - break; - case BT_8821C_2ANT_COEX_A2DP: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Action 2-Ant, algorithm = A2DP.\n"); - BTC_TRACE(trace_buf); - - /* for A2DP + OPP test but BTinfo is - * A2DP only in Lenovo test case - */ - if (coex_sta->is_bt_multi_link && coex_sta->hid_pair_cnt == 0) - halbtc8821c2ant_action_pan_a2dp(btc); - else if (coex_sta->is_bt_a2dp_sink) - halbtc8821c2ant_action_a2dpsink(btc); - else - halbtc8821c2ant_action_a2dp(btc); - break; - case BT_8821C_2ANT_COEX_PAN: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Action 2-Ant, algorithm = PAN(EDR).\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_pan(btc); - break; - case BT_8821C_2ANT_COEX_PAN_A2DP: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Action 2-Ant, algorithm = PAN+A2DP.\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_pan_a2dp(btc); - break; - case BT_8821C_2ANT_COEX_PAN_HID: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID.\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_pan_hid(btc); - break; - case BT_8821C_2ANT_COEX_HID_A2DP_PAN: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN.\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_hid_a2dp_pan(btc); - break; - case BT_8821C_2ANT_COEX_HID_A2DP: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_hid_a2dp(btc); - break; - default: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_coex_all_off(btc); - break; - } -} - -static -void halbtc8821c2ant_action_wifi_multiport25g(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_BTCQDDR, TRUE); - - if (coex_sta->is_setup_link || coex_sta->bt_relink_downcount != 0) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi_multiport25g(), BT Relink!!\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_table(btc, NM_EXCU, 0); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); - } else if (coex_sta->c2h_bt_inquiry_page) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi_multiport25g(), BT Inq-Page!!\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_table(btc, NM_EXCU, 11); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); - } else { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi_multiport25g(), BT idle or busy!!\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_table(btc, NM_EXCU, 11); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); - } -} - -static -void halbtc8821c2ant_action_wifi_multiport2g(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct btc_concurrent_setting multiport_tdma_para; - u32 traffic_dir; - - btc->btc_get(btc, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &traffic_dir); - - halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); - halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); - - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_BTCQDDR, TRUE); - - if (coex_sta->is_setup_link || coex_sta->bt_relink_downcount != 0) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi_multiport2g, BT Relink!!\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_table(btc, NM_EXCU, 0); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); - } else if (coex_sta->c2h_bt_inquiry_page) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi_multiport2g, BT Inq-Page!!\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_table(btc, NM_EXCU, 0); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); - } else if (coex_sta->num_of_profile == 0) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi_multiport2g, BT idle!!\n"); - BTC_TRACE(trace_buf); - - if (btc->chip_interface == BTC_INTF_PCI && - (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO || - btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GC)) - halbtc8821c2ant_table(btc, NM_EXCU, 10); - else - halbtc8821c2ant_table(btc, NM_EXCU, 0); - - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); - } else if (coex_sta->is_wifi_linkscan_process) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi_multiport2g, WL scan!!\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_action_wifi_linkscan(btc); - } else { - switch (btc->wifi_link_info.link_mode) { - case BTC_LINK_ONLY_GO: - case BTC_LINK_ONLY_GC: - if (btc->chip_interface == BTC_INTF_PCI && - coex_sta->a2dp_exist && !coex_sta->is_bt_multi_link) - halbtc8821c2ant_table(btc, NM_EXCU, 10); - else - halbtc8821c2ant_table(btc, NM_EXCU, 0); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); - break; - default: - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi_multiport2g, Other multi-port + BT busy!!\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_table(btc, NM_EXCU, 0); - halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); - break; - } - } -} - -static -void halbtc8821c2ant_run_coex(struct btc_coexist *btc, u8 reason) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - struct wifi_link_info_8821c_2ant *wifi_link_info_ext = - &btc->wifi_link_info_8821c_2ant; - boolean wifi_connected = FALSE, wifi_32k = FALSE; - boolean scan = FALSE, link = FALSE, roam = FALSE, under_4way = FALSE; - - btc->btc_get(btc, BTC_GET_BL_WIFI_SCAN, &scan); - btc->btc_get(btc, BTC_GET_BL_WIFI_LINK, &link); - btc->btc_get(btc, BTC_GET_BL_WIFI_ROAM, &roam); - btc->btc_get(btc, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under_4way); - btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); - btc->btc_get(btc, BTC_GET_BL_WIFI_LW_PWR_STATE, &wifi_32k); - - if (scan || link || roam || under_4way || - reason == BT_8821C_2ANT_RSN_2GSCANSTART || - reason == BT_8821C_2ANT_RSN_2GSWITCHBAND || - reason == BT_8821C_2ANT_RSN_2GCONSTART || - reason == BT_8821C_2ANT_RSN_2GSPECIALPKT) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], scan = %d, link = %d, roam = %d 4way = %d!!!\n", - scan, link, roam, under_4way); - BTC_TRACE(trace_buf); - coex_sta->is_wifi_linkscan_process = TRUE; - } else { - coex_sta->is_wifi_linkscan_process = FALSE; - } - - /* update wifi_link_info_ext variable */ - halbtc8821c2ant_update_wifi_link_info(btc, reason); - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], RunCoexistMechanism()===> reason = %d\n", - reason); - BTC_TRACE(trace_buf); - - coex_sta->coex_run_reason = reason; - - if (btc->manual_control) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n"); - BTC_TRACE(trace_buf); - return; - } - - if (btc->stop_coex_dm) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n"); - BTC_TRACE(trace_buf); - return; - } - - if (coex_sta->under_ips) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], RunCoexistMechanism(), return for wifi is under IPS !!!\n"); - BTC_TRACE(trace_buf); - return; - } - - if (coex_sta->under_lps && wifi_32k) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], RunCoexistMechanism(), return for wifi is under LPS-32K !!!\n"); - BTC_TRACE(trace_buf); - return; - } - - if (!coex_sta->run_time_state) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], return for run_time_state = FALSE !!!\n"); - BTC_TRACE(trace_buf); - return; - } - - if (coex_sta->freeze_coexrun_by_btinfo && !coex_sta->is_setup_link) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], return for freeze_coexrun_by_btinfo\n"); - BTC_TRACE(trace_buf); - return; - } - - coex_sta->coex_run_cnt++; - - if (coex_sta->msft_mr_exist && wifi_connected) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], RunCoexistMechanism(), microsoft MR!!\n"); - BTC_TRACE(trace_buf); - - coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_BTMR; - halbtc8821c2ant_action_bt_mr(btc); - return; - } - - if (wifi_link_info_ext->is_all_under_5g) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], WiFi is under 5G!!!\n"); - BTC_TRACE(trace_buf); - - coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_5G; - halbtc8821c2ant_action_wifi_under5g(btc); - return; - } - - if (wifi_link_info_ext->is_mcc_25g) { /* not iclude scan action */ - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], WiFi is under mcc dual-band!!!\n"); - BTC_TRACE(trace_buf); - - coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_25GMPORT; - halbtc8821c2ant_action_wifi_multiport25g(btc); - return; - } - - if (wifi_link_info_ext->num_of_active_port > 1 || - (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO && - !btc->wifi_link_info.bhotspot && - btc->wifi_link_info.bany_client_join_go)) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], WiFi is under scc-2g/mcc-2g/p2pGO-only!!!\n"); - BTC_TRACE(trace_buf); - - if (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO) - coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_2GGO; - else - coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_2GMPORT; - halbtc8821c2ant_action_wifi_multiport2g(btc); - return; - } - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], WiFi is single-port 2G!!!\n"); - BTC_TRACE(trace_buf); - - coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_2G1PORT; - - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, - BT_8821C_2ANT_PHASE_2G); - - /*For Asus airpods 2 + HID glitch issue*/ - if (coex_sta->bt_a2dp_vendor_id == 0x4c && coex_sta->is_bt_multi_link) - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_BTCQDDR, - FALSE); - else - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_BTCQDDR, - TRUE); - - if (coex_sta->bt_disabled) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT is disabled !!!\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_coex_all_off(btc); - return; - } - - if (coex_sta->under_lps && !coex_sta->force_lps_ctrl && - !coex_sta->acl_busy) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], RunCoexistMechanism(), wifi is under LPS !!!\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_wifi_native_lps(btc); - return; - } - - if (coex_sta->bt_whck_test) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT is under WHCK TEST!!!\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_bt_whql_test(btc); - return; - } - - if (coex_sta->is_setup_link || coex_sta->bt_relink_downcount != 0) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT is re-link !!!\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_bt_relink(btc); - return; - } - - if (coex_sta->c2h_bt_inquiry_page) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT is under inquiry/page scan !!\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_bt_inquiry(btc); - return; - } - - if ((coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE || - coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_CON_IDLE) && - wifi_link_info_ext->is_connected) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "############# [BTCoex], BT Is idle\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_bt_idle(btc); - return; - } - - if (coex_sta->is_wifi_linkscan_process) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi is under linkscan process!!\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_action_wifi_linkscan(btc); - return; - } - - if (wifi_connected) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi is under connected!!\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_action_wifi_connected(btc); - } else { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wifi is under not-connected!!\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_action_wifi_not_connected(btc); - } -} - -static void halbtc8821c2ant_init_coex_var(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - - /* Reset Coex variable */ - btc->btc_set(btc, BTC_SET_RESET_COEX_VAR, NULL); - - coex_sta->bt_reg_vendor_ac = 0xffff; - coex_sta->bt_reg_vendor_ae = 0xffff; - - coex_sta->isolation_btween_wb = BT_8821C_2ANT_DEFAULT_ISOLATION; - btc->bt_info.bt_get_fw_ver = 0; -} - -static -void halbtc8821c2ant_init_coex_dm(struct btc_coexist *btc) -{ -} - -static -void halbtc8821c2ant_init_hw_config(struct btc_coexist *btc, boolean wifi_only) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - u8 u8tmp = 0; - u32 vendor; - u32 u32tmp0 = 0, u32tmp1 = 0, u32tmp2 = 0, u32tmp3 = 0; - u8 i; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()!\n", __func__); - BTC_TRACE(trace_buf); - -#if 0 - u32tmp3 = btc->btc_read_4byte(btc, 0xcb4); - u32tmp1 = halbtc8821c2ant_read_indirect_reg(btc, 0x38); - u32tmp2 = halbtc8821c2ant_read_indirect_reg(btc, 0x54); - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], (Before Init HW config) 0xcb4 = 0x%x, 0x38= 0x%x, 0x54= 0x%x\n", - u32tmp3, u32tmp1, u32tmp2); - BTC_TRACE(trace_buf); -#endif - - halbtc8821c2ant_init_coex_var(btc); - - /* 0xf0[15:12] --> kt_ver */ - coex_sta->kt_ver = (btc->btc_read_1byte(btc, 0xf1) & 0xf0) >> 4; - - halbtc8821c2ant_coex_switch_thres(btc, coex_sta->isolation_btween_wb); - /* enable TBTT nterrupt */ - btc->btc_write_1byte_bitmask(btc, 0x550, 0x8, 0x1); - - /* BT report packet sample rate */ - btc->btc_write_1byte(btc, 0x790, 0x5); - - /* Init 0x778 = 0x1 for 2-Ant */ - btc->btc_write_1byte(btc, 0x778, 0x1); - - /* Enable PTA (3-wire function form BT side) */ - btc->btc_write_1byte_bitmask(btc, 0x40, 0x20, 0x1); - btc->btc_write_1byte_bitmask(btc, 0x41, 0x02, 0x1); - - /* Enable PTA (tx/rx signal form WiFi side) */ - btc->btc_write_1byte_bitmask(btc, 0x4c6, 0x30, 0x1); - - /* set GNT_BT=1 for coex table select both */ - btc->btc_write_1byte_bitmask(btc, 0x763, 0x10, 0x1); - - halbtc8821c2ant_enable_gnt_to_gpio(btc, TRUE); - - /* Enable counter statistics */ - /* 0x76e[3] =1, WLAN_Act control by PTA */ - btc->btc_write_1byte(btc, 0x76e, 0x4); - - if (btc->wl_rf_state_off) { - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, - BT_8821C_2ANT_PHASE_WOFF); - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ALL, FALSE); - btc->stop_coex_dm = TRUE; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], %s: RF Off\n", __func__); - BTC_TRACE(trace_buf); - } else if (wifi_only) { - coex_sta->concurrent_rx_mode_on = FALSE; - /* Path config */ - /* Set Antenna Path */ - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, - BT_8821C_2ANT_PHASE_WONLY); - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | - BT_8821C_2ANT_SCBD_ONOFF, - TRUE); - btc->stop_coex_dm = TRUE; - } else { - coex_sta->concurrent_rx_mode_on = TRUE; - /* btc->btc_write_1byte_bitmask(btc, 0x953, 0x2, 0x1); */ - - /* RF 0x1[1] = 0->Set GNT_WL_RF_Rx always = 1 - * for con-current Rx, mask Tx only - */ - btc->btc_set_rf_reg(btc, BTC_RF_A, 0x1, 0x2, 0x0); - - /* Set Antenna Path */ - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, - BT_8821C_2ANT_PHASE_INIT); - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | - BT_8821C_2ANT_SCBD_ONOFF, - TRUE); - btc->stop_coex_dm = FALSE; - } - - halbtc8821c2ant_table(btc, FC_EXCU, 0); - halbtc8821c2ant_tdma(btc, FC_EXCU, FALSE, 0); - - halbtc8821c2ant_query_bt_info(btc); -} - -void ex_halbtc8821c2ant_power_on_setting(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct btc_board_info *board_info = &btc->board_info; - u8 u8tmp = 0x0; - u16 u16tmp = 0x0; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Execute %s !!\n", __func__); - BTC_TRACE(trace_buf); - - btc->stop_coex_dm = TRUE; - btc->wl_rf_state_off = FALSE; - - /* enable BB, REG_SYS_FUNC_EN such that - * we can write BB Register correctly. - */ - u16tmp = btc->btc_read_2byte(btc, 0x2); - btc->btc_write_2byte(btc, 0x2, u16tmp | BIT(0) | BIT(1)); - - /* Local setting bit define - * BIT0: "0" for no antenna inverse; "1" for antenna inverse - * BIT1: "0" for internal switch; "1" for external switch - * BIT2: "0" for one antenna; "1" for two antenna - * NOTE: here default all internal switch and 1-antenna - * ==> BIT1=0 and BIT2=0 - */ - - /* Check efuse 0xc3[6] for Single Antenna Path */ - if (board_info->single_ant_path == 0) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Single Antenna, Antenna at Aux Port\n"); - BTC_TRACE(trace_buf); - - board_info->btdm_ant_pos = BTC_ANTENNA_AT_AUX_PORT; - u8tmp = 7; - } else if (board_info->single_ant_path == 1) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Single Antenna, Antenna at Main Port\n"); - BTC_TRACE(trace_buf); - - board_info->btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT; - u8tmp = 6; - } - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], (Power On) single_ant_path = %d, btdm_ant_pos = %d\n", - board_info->single_ant_path , board_info->btdm_ant_pos); - BTC_TRACE(trace_buf); - - /* Setup RF front end type */ - halbtc8821c2ant_set_rfe_type(btc); - - /* Set Antenna Path to BT side */ - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, - BT_8821C_2ANT_PHASE_POWERON); - - halbtc8821c2ant_table(btc, FC_EXCU, 0); - - /* Save"single antenna position" info in Local register setting - * for FW reading, because FW may not ready at power on - */ - if (btc->chip_interface == BTC_INTF_PCI) - btc->btc_write_local_reg_1byte(btc, 0x3e0, u8tmp); - else if (btc->chip_interface == BTC_INTF_USB) - btc->btc_write_local_reg_1byte(btc, 0xfe08, u8tmp); - else if (btc->chip_interface == BTC_INTF_SDIO) - btc->btc_write_local_reg_1byte(btc, 0x60, u8tmp); - - /* enable GNT_WL/GNT_BT debug signal to GPIO14/15 */ - halbtc8821c2ant_enable_gnt_to_gpio(btc, TRUE); - - if (btc->dbg_mode) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], LTE coex Reg 0x38 (Power-On) = 0x%x\n", - halbtc8821c2ant_read_indirect_reg(btc, 0x38)); - BTC_TRACE(trace_buf); - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], MACReg 0x70/ BBReg 0xcb4 (Power-On) = 0x%x/ 0x%x\n", - btc->btc_read_4byte(btc, 0x70), - btc->btc_read_4byte(btc, 0xcb4)); - BTC_TRACE(trace_buf); - } -} - -void ex_halbtc8821c2ant_pre_load_firmware(struct btc_coexist *btc) -{ - struct btc_board_info *board_info = &btc->board_info; - u8 u8tmp = 0x4; /* Set BIT2 by default since it's 2ant case */ - - /* S0 or S1 setting and Local register setting - *(By the setting fw can get ant number, S0/S1, ... info) - * Local setting bit define - * BIT0: "0" for no antenna inverse; "1" for antenna inverse - * BIT1: "0" for internal switch; "1" for external switch - * BIT2: "0" for one antenna; "1" for two antenna - * NOTE: here default all internal switch - * and 1-antenna ==> BIT1=0 and BIT2=0 - */ - if (btc->chip_interface == BTC_INTF_USB) { - /* fixed at S0 for USB interface */ - u8tmp |= 0x1; /* antenna inverse */ - btc->btc_write_local_reg_1byte(btc, 0xfe08, u8tmp); - } else { - /* for PCIE and SDIO interface, we check efuse 0xc3[6] */ - if (board_info->single_ant_path == 0) { - } else if (board_info->single_ant_path == 1) { - /* set to S0 */ - u8tmp |= 0x1; /* antenna inverse */ - } - - if (btc->chip_interface == BTC_INTF_PCI) - btc->btc_write_local_reg_1byte(btc, 0x3e0, u8tmp); - else if (btc->chip_interface == BTC_INTF_SDIO) - btc->btc_write_local_reg_1byte(btc, 0x60, u8tmp); - } -} - - -void ex_halbtc8821c2ant_init_hw_config(struct btc_coexist *btc, - boolean wifi_only) -{ - halbtc8821c2ant_init_hw_config(btc, wifi_only); -} - -void ex_halbtc8821c2ant_init_coex_dm(struct btc_coexist *btc) -{ - btc->stop_coex_dm = FALSE; - btc->auto_report = TRUE; - btc->dbg_mode = FALSE; - halbtc8821c2ant_init_coex_dm(btc); -} - -void ex_halbtc8821c2ant_display_simple_coex_info(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - struct btc_board_info *board_info = &btc->board_info; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; - - u8 *cli_buf = btc->cli_buf; - u32 bt_patch_ver = 0, bt_coex_ver = 0; - static u8 cnt; - u8 * const p = &coex_sta->bt_afh_map[0]; - - if (!coex_sta->bt_disabled && - (coex_sta->bt_coex_supported_version == 0 || - coex_sta->bt_coex_supported_version == 0xffff) && - cnt == 0) { - btc->btc_get(btc, BTC_GET_U4_SUPPORTED_FEATURE, - &coex_sta->bt_coex_supported_feature); - - btc->btc_get(btc, BTC_GET_U4_SUPPORTED_VERSION, - &coex_sta->bt_coex_supported_version); - - coex_sta->bt_reg_vendor_ac = (u16)(btc->btc_get_bt_reg(btc, 3, - 0xac) & - 0xffff); - - coex_sta->bt_reg_vendor_ae = (u16)(btc->btc_get_bt_reg(btc, 3, - 0xae) & - 0xffff); - - btc->btc_get(btc, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); - btc->bt_info.bt_get_fw_ver = bt_patch_ver; - - if (coex_sta->num_of_profile > 0) - btc->btc_get_bt_afh_map_from_bt(btc, 0, p); - } - - if (++cnt >= 3) - cnt = 0; - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n _____[BT Coexist info]____"); - CL_PRINTF(cli_buf); - - if (btc->manual_control) { - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n __[Under Manual Control]_"); - CL_PRINTF(cli_buf); - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n _________________________"); - CL_PRINTF(cli_buf); - } - - if (btc->stop_coex_dm) { - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n ____[Coex is STOPPED]____"); - CL_PRINTF(cli_buf); - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n _________________________"); - CL_PRINTF(cli_buf); - } - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %d/ %d/ %s / 0x%x", - "Ant PG Num/ Mech/ Pos/ RFE", - board_info->pg_ant_num, board_info->btdm_ant_num, - (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT - ? "Main" : "Aux"), - board_info->rfe_type); - CL_PRINTF(cli_buf); - - bt_coex_ver = (coex_sta->bt_coex_supported_version & 0xff); - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %d_%02x/ 0x%02x/ 0x%02x (%s)", - "CoexVer WL/ BT_Desired/ BT_Report", - glcoex_ver_date_8821c_2ant, glcoex_ver_8821c_2ant, - glcoex_ver_btdesired_8821c_2ant, - bt_coex_ver, - (bt_coex_ver == 0xff ? "Unknown" : - (coex_sta->bt_disabled ? "BT-disable" : - (bt_coex_ver >= glcoex_ver_btdesired_8821c_2ant ? - "Match" : "Mis-Match")))); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s ", "BT status", - ((coex_sta->bt_disabled) ? ("disabled") : - ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page") - : ((BT_8821C_2ANT_BSTATUS_NCON_IDLE == - coex_dm->bt_status) ? "non-connected idle" : - ((BT_8821C_2ANT_BSTATUS_CON_IDLE == - coex_dm->bt_status) ? "connected-idle" : "busy"))))); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", - "0x770(Hi-pri rx/tx)", - coex_sta->high_priority_rx, coex_sta->high_priority_tx); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d %s", - "0x774(Lo-pri rx/tx)", - coex_sta->low_priority_rx, coex_sta->low_priority_tx, - (bt_link_info->slave_role ? "(Slave!!)" : " ")); - CL_PRINTF(cli_buf); -} - -void ex_halbtc8821c2ant_display_coex_info(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - struct btc_board_info *board_info = &btc->board_info; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; - - u8 *cli_buf = btc->cli_buf; - u8 u8tmp[4], i, ps_tdma_case = 0; - u32 u32tmp[4]; - u16 u16tmp[4]; - u32 fa_ofdm, fa_cck, cca_ofdm, cca_cck; - u32 fw_ver = 0, bt_patch_ver = 0, bt_coex_ver = 0; - static u8 pop_report_in_10s; - u32 phyver = 0, val = 0; - boolean lte_coex_on = FALSE, is_bt_reply = FALSE; - static u8 cnt; - u32 ratio_crc, cnt_ok, cnt_err; - u8 * const p = &coex_sta->bt_afh_map[0]; - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n ============[BT Coexist info 8821C]============"); - CL_PRINTF(cli_buf); - - if (btc->manual_control) { - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n ============[Under Manual Control]============"); - CL_PRINTF(cli_buf); - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n =========================================="); - CL_PRINTF(cli_buf); - } else if (btc->stop_coex_dm) { - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n ============[Coex is STOPPED]============"); - CL_PRINTF(cli_buf); - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n =========================================="); - CL_PRINTF(cli_buf); - } else if (!coex_sta->run_time_state) { - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n ============[Run Time State = False]============"); - CL_PRINTF(cli_buf); - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n =========================================="); - CL_PRINTF(cli_buf); - } else if (coex_sta->freeze_coexrun_by_btinfo) { - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n ============[freeze_coexrun_by_btinfo]============"); - CL_PRINTF(cli_buf); - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n =========================================="); - CL_PRINTF(cli_buf); - } - - if (!coex_sta->bt_disabled && cnt == 0) { - if (coex_sta->bt_coex_supported_version == 0 || - coex_sta->bt_coex_supported_version == 0xffff) { - btc->btc_get(btc, BTC_GET_U4_SUPPORTED_VERSION, - &coex_sta->bt_coex_supported_version); - - if (coex_sta->bt_coex_supported_version > 0 && - coex_sta->bt_coex_supported_version < 0xffff) - is_bt_reply = TRUE; - } else { - is_bt_reply = TRUE; - } - - if (coex_sta->num_of_profile > 0) - btc->btc_get_bt_afh_map_from_bt(btc, 0, p); - } - - if (is_bt_reply) { - if (coex_sta->bt_coex_supported_feature == 0) - btc->btc_get(btc, BTC_GET_U4_SUPPORTED_FEATURE, - &coex_sta->bt_coex_supported_feature); - - if (coex_sta->bt_reg_vendor_ac == 0xffff) { - val = btc->btc_get_bt_reg(btc, 3, 0xac); - coex_sta->bt_reg_vendor_ac = (u16)(val & 0xffff); - } - - if (coex_sta->bt_reg_vendor_ae == 0xffff) { - val = btc->btc_get_bt_reg(btc, 3, 0xae); - coex_sta->bt_reg_vendor_ae = (u16)(val & 0xffff); - } - - if (btc->bt_info.bt_get_fw_ver == 0) { - btc->btc_get(btc, BTC_GET_U4_BT_PATCH_VER, - &bt_patch_ver); - btc->bt_info.bt_get_fw_ver = bt_patch_ver; - } - } - - if (++cnt >= 3) - cnt = 0; - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %d/ %s/ %s / 0x%x", - "Ant PG Num/ Mech/ Pos/ RFE", - board_info->pg_ant_num, - (board_info->btdm_ant_num == 1 ? "Shared" : "Non-Shared"), - (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT - ? "Main" : "Aux"), - board_info->rfe_type); - CL_PRINTF(cli_buf); - - bt_patch_ver = btc->bt_info.bt_get_fw_ver; - btc->btc_get(btc, BTC_GET_U4_WIFI_FW_VER, &fw_ver); - phyver = btc->btc_get_bt_phydm_version(btc); - bt_coex_ver = (coex_sta->bt_coex_supported_version & 0xff); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %d_%02x/ 0x%02x/ 0x%02x (%s)", - "CoexVer WL/ BT_Desired/ BT_Report", - glcoex_ver_date_8821c_2ant, glcoex_ver_8821c_2ant, - glcoex_ver_btdesired_8821c_2ant, - bt_coex_ver, - (bt_coex_ver == 0xff ? "Unknown" : - (coex_sta->bt_disabled ? "BT-disable" : - (bt_coex_ver >= glcoex_ver_btdesired_8821c_2ant ? - "Match" : "Mis-Match")))); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = 0x%x(%s)/ 0x%x/ v%d/ %c", - "W_FW/ B_FW/ Phy/ Kt", fw_ver, - (fw_ver >= glcoex_ver_wldesired_8821c_2ant ? - "Match" : - "Mis-Match"), - bt_patch_ver, phyver, coex_sta->kt_ver + 65); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %02x %02x %02x (RF-Ch = %d)", - "AFH Map to BT", - coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1], - coex_dm->wifi_chnl_info[2], coex_sta->wl_center_channel); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d ", - "Isolation/WL_Thres/BT_Thres", - coex_sta->isolation_btween_wb, - coex_sta->wifi_coex_thres, - coex_sta->bt_coex_thres); - CL_PRINTF(cli_buf); - - /* wifi status */ - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", - "============[Wifi Status]============"); - CL_PRINTF(cli_buf); - btc->btc_disp_dbg_msg(btc, BTC_DBG_DISP_WIFI_STATUS); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", - "============[BT Status]============"); - CL_PRINTF(cli_buf); - - pop_report_in_10s++; - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %s/ %ddBm/ %d/ %d", - "BT status/ rssi/ retryCnt/ popCnt", - ((coex_sta->bt_disabled) ? ("disabled") : (( - coex_sta->c2h_bt_inquiry_page) ? ("inquiry-page") - : ((BT_8821C_2ANT_BSTATUS_NCON_IDLE == - coex_dm->bt_status) ? "non-connected-idle" : - ((coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_CON_IDLE) - ? "connected-idle" : "busy")))), - coex_sta->bt_rssi - 100, coex_sta->bt_retry_cnt, - coex_sta->pop_event_cnt); - CL_PRINTF(cli_buf); - - if (pop_report_in_10s >= 5) { - coex_sta->pop_event_cnt = 0; - pop_report_in_10s = 0; - } - - if (coex_sta->num_of_profile != 0) - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %s%s%s%s%s%s (multilink = %d)", - "Profiles", ((bt_link_info->a2dp_exist) ? - ((coex_sta->is_bt_a2dp_sink) ? "A2DP sink," : - "A2DP,") : ""), - ((bt_link_info->sco_exist) ? "HFP," : ""), - ((bt_link_info->hid_exist) ? - ((coex_sta->is_hid_rcu) ? "HID(RCU)" : - ((coex_sta->hid_busy_num >= 2) ? "HID(4/18)," : - (coex_sta->bt_ble_hid_exist ? "HID(BLE)" : - "HID(2/18),"))) : ""), ((bt_link_info->pan_exist) ? - ((coex_sta->is_bt_opp_exist) ? "OPP," : "PAN,") : - ""), ((coex_sta->voice_over_HOGP) ? "Voice," : ""), - ((coex_sta->msft_mr_exist) ? "MR" : ""), - coex_sta->is_bt_multi_link); - else - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %s", "Profiles", - (coex_sta->msft_mr_exist) ? "MR" : "None"); - - CL_PRINTF(cli_buf); - - if (bt_link_info->a2dp_exist) { - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %s/ %d/ 0x%x/ 0x%x/ %d", - "CQDDR/Bitpool/V_ID/D_name/Flush", - ((coex_sta->is_A2DP_3M) ? "On" : "Off"), - coex_sta->a2dp_bit_pool, - coex_sta->bt_a2dp_vendor_id, - coex_sta->bt_a2dp_device_name, - coex_sta->bt_a2dp_flush_time); - CL_PRINTF(cli_buf); - } - - if (bt_link_info->hid_exist) { - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", - "HID PairNum", - coex_sta->hid_pair_cnt); - CL_PRINTF(cli_buf); - } - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %d/ %s/ 0x%x", - "Role/RoleSwCnt/IgnWlact/Feature", - ((bt_link_info->slave_role) ? "Slave" : "Master"), - coex_sta->cnt_role_switch, - ((coex_dm->cur_ignore_wlan_act) ? "Yes" : "No"), - coex_sta->bt_coex_supported_feature); - CL_PRINTF(cli_buf); - - if (coex_sta->is_ble_scan_en) { - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", - "BLEScan Type/TV/Init/Ble", - coex_sta->bt_ble_scan_type, - (coex_sta->bt_ble_scan_type & 0x1 ? - coex_sta->bt_ble_scan_para[0] : 0x0), - (coex_sta->bt_ble_scan_type & 0x2 ? - coex_sta->bt_ble_scan_para[1] : 0x0), - (coex_sta->bt_ble_scan_type & 0x4 ? - coex_sta->bt_ble_scan_para[2] : 0x0)); - CL_PRINTF(cli_buf); - } - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %d/ %d/ %d/ %d/ %d %s", - "ReInit/ReLink/IgnWlact/Page/NameReq", coex_sta->cnt_reinit, - coex_sta->cnt_setup_link, coex_sta->cnt_ign_wlan_act, - coex_sta->cnt_page, coex_sta->cnt_remote_name_req, - (coex_sta->is_setup_link ? "(Relink!!)" : "")); - CL_PRINTF(cli_buf); - - halbtc8821c2ant_read_scbd(btc, &u16tmp[0]); - - if (coex_sta->bt_reg_vendor_ae == 0xffff || - coex_sta->bt_reg_vendor_ac == 0xffff) - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = x/ x/ 0x%04x", - "0xae[4]/0xac[1:0]/ScBd(B->W)", u16tmp[0]); - else - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = 0x%x/ 0x%x/ 0x%04x", - "0xae[4]/0xac[1:0]/ScBd(B->W)", - (int)((coex_sta->bt_reg_vendor_ae & BIT(4)) >> 4), - coex_sta->bt_reg_vendor_ac & 0x3, u16tmp[0]); - CL_PRINTF(cli_buf); - - if (coex_sta->num_of_profile > 0) { - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x", - "AFH MAP", - coex_sta->bt_afh_map[0], - coex_sta->bt_afh_map[1], - coex_sta->bt_afh_map[2], - coex_sta->bt_afh_map[3], - coex_sta->bt_afh_map[4], - coex_sta->bt_afh_map[5], - coex_sta->bt_afh_map[6], - coex_sta->bt_afh_map[7], - coex_sta->bt_afh_map[8], - coex_sta->bt_afh_map[9]); - CL_PRINTF(cli_buf); - } - - for (i = 0; i < BT_8821C_2ANT_INFO_SRC_MAX; i++) { - if (coex_sta->bt_info_c2h_cnt[i]) { - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x (%d)", - glbt_info_src_8821c_2ant[i], - coex_sta->bt_info_c2h[i][0], - coex_sta->bt_info_c2h[i][1], - coex_sta->bt_info_c2h[i][2], - coex_sta->bt_info_c2h[i][3], - coex_sta->bt_info_c2h[i][4], - coex_sta->bt_info_c2h[i][5], - coex_sta->bt_info_c2h[i][6], - coex_sta->bt_info_c2h_cnt[i]); - CL_PRINTF(cli_buf); - } - } - - /* Sw mechanism */ - if (btc->manual_control) - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", - "============[mechanism] (before Manual)============"); - else - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", - "============[Mechanism]============"); - - CL_PRINTF(cli_buf); - - ps_tdma_case = coex_dm->cur_ps_tdma; - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %02x %02x %02x %02x %02x (case-%d, %s, Timer:%d)", - "TDMA", - coex_dm->ps_tdma_para[0], coex_dm->ps_tdma_para[1], - coex_dm->ps_tdma_para[2], coex_dm->ps_tdma_para[3], - coex_dm->ps_tdma_para[4], ps_tdma_case, - (coex_dm->cur_ps_tdma_on ? "On" : "Off"), - coex_sta->tdma_timer_base); - CL_PRINTF(cli_buf); - - switch (coex_sta->wl_coex_mode) { - case BT_8821C_2ANT_WLINK_2G1PORT: - default: - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %s", "Coex_Mode", "2G-SP"); - break; - case BT_8821C_2ANT_WLINK_2GMPORT: - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %s", "Coex_Mode", "2G-MP"); - break; - case BT_8821C_2ANT_WLINK_25GMPORT: - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %s", "Coex_Mode", "25G-MP"); - break; - case BT_8821C_2ANT_WLINK_5G: - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %s", "Coex_Mode", "5G"); - break; - case BT_8821C_2ANT_WLINK_2GGO: - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %s", "Coex_Mode", "2G-P2P"); - break; - case BT_8821C_2ANT_WLINK_BTMR: - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %s", "Coex_Mode", "BT-MR"); - break; - } - CL_PRINTF(cli_buf); - - u32tmp[0] = btc->btc_read_4byte(btc, 0x6c0); - u32tmp[1] = btc->btc_read_4byte(btc, 0x6c4); - u32tmp[2] = btc->btc_read_4byte(btc, 0x6c8); - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %d/ 0x%x/ 0x%x/ 0x%x", - "Table/0x6c0/0x6c4/0x6c8", - coex_sta->coex_table_type, u32tmp[0], u32tmp[1], u32tmp[2]); - CL_PRINTF(cli_buf); - - u8tmp[0] = btc->btc_read_1byte(btc, 0x778); - u32tmp[0] = btc->btc_read_4byte(btc, 0x6cc); - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = 0x%x/ 0x%x/ 0x%04x/ %d/ %d", - "0x778/0x6cc/ScBd(W->B)/RunCnt/Rsn", u8tmp[0], u32tmp[0], - coex_sta->score_board_WB, coex_sta->coex_run_cnt, - coex_sta->coex_run_reason); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s/ %d/ %d", - "AntDiv/BtCtrlLPS/LPRA/PsFail/g_busy", - ((board_info->ant_div_cfg) ? - ((coex_dm->cur_antdiv_type) ? "On(Hw)" : "On(Sw)") : "Off"), - ((coex_sta->force_lps_ctrl) ? "On" : "Off"), - ((coex_dm->cur_low_penalty_ra) ? "On" : "Off"), - coex_sta->cnt_set_ps_state_fail, - coex_sta->gl_wifi_busy); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", - "WL_Pwr/ BT_Pwr", coex_dm->cur_wl_pwr_lvl, - coex_dm->cur_bt_pwr_lvl); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d/ %d", - "Null All/Retry/Ack/BT_Empty/BT_Late", - coex_sta->wl_fw_dbg_info[1], - coex_sta->wl_fw_dbg_info[2], - coex_sta->wl_fw_dbg_info[3], - coex_sta->wl_fw_dbg_info[4], - coex_sta->wl_fw_dbg_info[5]); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %s/ %d", - "cnt TDMA_Togg/LK5ms/LK5ms_off/fw", - coex_sta->wl_fw_dbg_info[6], coex_sta->wl_fw_dbg_info[7], - ((coex_sta->is_no_wl_5ms_extend) ? "Yes" : "No"), - coex_sta->cnt_wl_fw_notify); - CL_PRINTF(cli_buf); - - u32tmp[0] = halbtc8821c2ant_read_indirect_reg(btc, 0x38); - lte_coex_on = ((u32tmp[0] & BIT(7)) >> 7) ? TRUE : FALSE; - - if (lte_coex_on) { - u32tmp[0] = halbtc8821c2ant_read_indirect_reg(btc, 0xa0); - u32tmp[1] = halbtc8821c2ant_read_indirect_reg(btc, 0xa4); - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", - "LTE Coex Table W_L/B_L", u32tmp[0] & 0xffff, - u32tmp[1] & 0xffff); - CL_PRINTF(cli_buf); - - u32tmp[0] = halbtc8821c2ant_read_indirect_reg(btc, 0xa8); - u32tmp[1] = halbtc8821c2ant_read_indirect_reg(btc, 0xac); - u32tmp[2] = halbtc8821c2ant_read_indirect_reg(btc, 0xb0); - u32tmp[3] = halbtc8821c2ant_read_indirect_reg(btc, 0xb4); - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", - "LTE Break Table W_L/B_L/L_W/L_B", - u32tmp[0] & 0xffff, u32tmp[1] & 0xffff, - u32tmp[2] & 0xffff, u32tmp[3] & 0xffff); - CL_PRINTF(cli_buf); - } - - /* Hw setting */ - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", - "============[Hw setting]============"); - CL_PRINTF(cli_buf); - - u32tmp[0] = halbtc8821c2ant_read_indirect_reg(btc, 0x38); - u32tmp[1] = halbtc8821c2ant_read_indirect_reg(btc, 0x54); - u8tmp[0] = btc->btc_read_1byte(btc, 0x73); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s", - "LTE Coex/Path Owner", - ((lte_coex_on) ? "On" : "Off") , - ((u8tmp[0] & BIT(2)) ? "WL" : "BT")); - CL_PRINTF(cli_buf); - - if (lte_coex_on) { - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %d/ %d/ %d/ %d", - "LTE 3Wire/OPMode/UART/UARTMode", - (int)((u32tmp[0] & BIT(6)) >> 6), - (int)((u32tmp[0] & (BIT(5) | BIT(4))) >> 4), - (int)((u32tmp[0] & BIT(3)) >> 3), - (int)(u32tmp[0] & (BIT(2) | BIT(1) | BIT(0)))); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", - "LTE_Busy/UART_Busy", - (int)((u32tmp[1] & BIT(1)) >> 1), - (int)(u32tmp[1] & BIT(0))); - CL_PRINTF(cli_buf); - } - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %s (BB:%s)/ %s (BB:%s)/ %s (gnt_err = %d)", - "GNT_WL_Ctrl/GNT_BT_Ctrl/Dbg", - ((u32tmp[0] & BIT(12)) ? "SW" : "HW"), - ((u32tmp[0] & BIT(8)) ? "SW" : "HW"), - ((u32tmp[0] & BIT(14)) ? "SW" : "HW"), - ((u32tmp[0] & BIT(10)) ? "SW" : "HW"), - ((u8tmp[0] & BIT(3)) ? "On" : "Off"), - coex_sta->gnt_error_cnt); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ 0x%x", - "GNT_WL/GNT_BT/ RF_0x1", - (int)((u32tmp[1] & BIT(2)) >> 2), - (int)((u32tmp[1] & BIT(3)) >> 3), - btc->btc_get_rf_reg(btc, BTC_RF_A, 0x1, 0xfffff)); - CL_PRINTF(cli_buf); - - u32tmp[0] = btc->btc_read_4byte(btc, 0xcb0); - u32tmp[1] = btc->btc_read_4byte(btc, 0xcb4); - u8tmp[0] = btc->btc_read_1byte(btc, 0xcba); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = 0x%04x/ 0x%04x/ 0x%02x %s", - "0xcb0/0xcb4/0xcb8[23:16]", - u32tmp[0], u32tmp[1], u8tmp[0], - ((u8tmp[0] & 0x1) == 0x1 ? "(BTG)" : "(WL_A+G)")); - CL_PRINTF(cli_buf); - - u32tmp[0] = btc->btc_read_4byte(btc, 0x430); - u32tmp[1] = btc->btc_read_4byte(btc, 0x434); - u16tmp[0] = btc->btc_read_2byte(btc, 0x42a); - u8tmp[0] = btc->btc_read_1byte(btc, 0x426); - u8tmp[1] = btc->btc_read_1byte(btc, 0x45e); - u8tmp[2] = btc->btc_read_1byte(btc, 0x455); - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x", - "430/434/42a/426/45e[3]/455", - u32tmp[0], u32tmp[1], u16tmp[0], u8tmp[0], - (int)((u8tmp[1] & BIT(3)) >> 3), u8tmp[2]); - CL_PRINTF(cli_buf); - - u32tmp[0] = btc->btc_read_4byte(btc, 0x4c); - u8tmp[2] = btc->btc_read_1byte(btc, 0x64); - u8tmp[0] = btc->btc_read_1byte(btc, 0x4c6); - u8tmp[1] = btc->btc_read_1byte(btc, 0x40); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", - "4c[24:23]/64[0]/4c6[4]/40[5]", - (int)(u32tmp[0] & (BIT(24) | BIT(23))) >> 23, - u8tmp[2] & 0x1, (int)((u8tmp[0] & BIT(4)) >> 4), - (int)((u8tmp[1] & BIT(5)) >> 5)); - CL_PRINTF(cli_buf); - - u32tmp[0] = btc->btc_read_4byte(btc, 0x550); - u8tmp[0] = btc->btc_read_1byte(btc, 0x522); - u8tmp[1] = btc->btc_read_1byte(btc, 0x953); - u8tmp[2] = btc->btc_read_1byte(btc, 0xc50); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = 0x%x/ 0x%x/ %s/ 0x%x", - "0x550/0x522/4-RxAGC/0xc50", u32tmp[0], u8tmp[0], - (u8tmp[1] & 0x2) ? "On" : "Off", u8tmp[2]); - CL_PRINTF(cli_buf); - - fa_ofdm = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_FA_OFDM); - fa_cck = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_FA_CCK); - cca_ofdm = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CCA_OFDM); - cca_cck = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CCA_CCK); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", - "CCK-CCA/CCK-FA/OFDM-CCA/OFDM-FA", - cca_cck, fa_cck, cca_ofdm, fa_ofdm); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d", - "CRC_OK CCK/11g/11n/11ac", - coex_sta->crc_ok_cck, coex_sta->crc_ok_11g, - coex_sta->crc_ok_11n, coex_sta->crc_ok_11n_vht); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d", - "CRC_Err CCK/11g/11n/11ac", - coex_sta->crc_err_cck, coex_sta->crc_err_11g, - coex_sta->crc_err_11n, coex_sta->crc_err_11n_vht); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, - "\r\n %-35s = %d/ %d/ %s-%d/ %d (Tx macid: %d)", - "Rate RxD/RxRTS/TxD/TxRetry_ratio", - coex_sta->wl_rx_rate, coex_sta->wl_rts_rx_rate, - (coex_sta->wl_tx_rate & 0x80 ? "SGI" : "LGI"), - coex_sta->wl_tx_rate & 0x7f, - coex_sta->wl_tx_retry_ratio, - coex_sta->wl_tx_macid); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s/ %s/ %d", - "HiPr/ Locking/ warn/ Locked/ Noisy", - (coex_sta->wifi_high_pri_task1 ? "Yes" : "No"), - (coex_sta->cck_lock ? "Yes" : "No"), - (coex_sta->cck_lock_warn ? "Yes" : "No"), - (coex_sta->cck_lock_ever ? "Yes" : "No"), - coex_sta->wl_noisy_level); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", - "0x770(Hi-pri rx/tx)", - coex_sta->high_priority_rx, coex_sta->high_priority_tx); - CL_PRINTF(cli_buf); - - CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d %s", - "0x774(Lo-pri rx/tx)", - coex_sta->low_priority_rx, coex_sta->low_priority_tx, - (bt_link_info->slave_role ? "(Slave!!)" : " ")); - CL_PRINTF(cli_buf); - - btc->btc_disp_dbg_msg(btc, BTC_DBG_DISP_COEX_STATISTICS); -} - -void ex_halbtc8821c2ant_ips_notify(struct btc_coexist *btc, u8 type) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - - if (btc->manual_control || btc->stop_coex_dm) - return; - - if (type == BTC_IPS_ENTER) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], IPS ENTER notify\n"); - BTC_TRACE(trace_buf); - coex_sta->under_ips = TRUE; - coex_sta->under_lps = FALSE; - - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | - BT_8821C_2ANT_SCBD_ONOFF | - BT_8821C_2ANT_SCBD_SCAN | - BT_8821C_2ANT_SCBD_UNDERTEST, - FALSE); - - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, - BT_8821C_2ANT_PHASE_WOFF); - - halbtc8821c2ant_action_coex_all_off(btc); - } else if (type == BTC_IPS_LEAVE) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], IPS LEAVE notify\n"); - BTC_TRACE(trace_buf); - coex_sta->under_ips = FALSE; - - halbtc8821c2ant_init_hw_config(btc, FALSE); - halbtc8821c2ant_init_coex_dm(btc); - halbtc8821c2ant_query_bt_info(btc); - } -} - -void ex_halbtc8821c2ant_lps_notify(struct btc_coexist *btc, u8 type) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - - if (btc->manual_control || btc->stop_coex_dm) - return; - - if (type == BTC_LPS_ENABLE) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], LPS ENABLE notify\n"); - BTC_TRACE(trace_buf); - coex_sta->under_lps = TRUE; - coex_sta->under_ips = FALSE; - - if (coex_sta->force_lps_ctrl == TRUE) { /* LPS No-32K */ - /* Write WL "Active" in Score-board for PS-TDMA */ - halbtc8821c2ant_write_scbd(btc, - BT_8821C_2ANT_SCBD_ACTIVE, - TRUE); - - } else { /* LPS-32K, need check if this h2c 0x71 can work?? (2015/08/28) */ - /* Write WL "Non-Active" in Score-board for Native-PS */ - halbtc8821c2ant_write_scbd(btc, - BT_8821C_2ANT_SCBD_ACTIVE, - FALSE); - - halbtc8821c2ant_action_wifi_native_lps(btc); - } - - } else if (type == BTC_LPS_DISABLE) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], LPS DISABLE notify\n"); - BTC_TRACE(trace_buf); - coex_sta->under_lps = FALSE; - - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE, - TRUE); - - if (!coex_sta->force_lps_ctrl) { - halbtc8821c2ant_query_bt_info(btc); - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_LPS); - } - } -} - -void ex_halbtc8821c2ant_scan_notify(struct btc_coexist *btc, u8 type) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - boolean wifi_connected = FALSE; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], SCAN notify()\n"); - BTC_TRACE(trace_buf); - - if (btc->manual_control || btc->stop_coex_dm) - return; - - btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); - - if (wifi_connected) - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], ********** WL connected before SCAN\n"); - else - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], ********** WL is not connected before SCAN\n"); - - BTC_TRACE(trace_buf); - - /* this can't be removed for RF off_on event, - * r BT would dis-connect - */ - if (type != BTC_SCAN_FINISH) { - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | - BT_8821C_2ANT_SCBD_SCAN | - BT_8821C_2ANT_SCBD_ONOFF, TRUE); - } - - if (type == BTC_SCAN_START_5G) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], SCAN START notify (5G)\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, - FC_EXCU, BT_8821C_2ANT_PHASE_5G); - - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_5GSCANSTART); - } else if (type == BTC_SCAN_START_2G || type == BTC_SCAN_START) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], SCAN START notify (2G)\n"); - BTC_TRACE(trace_buf); - - if (!wifi_connected) - coex_sta->wifi_high_pri_task2 = TRUE; - - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, - BT_8821C_2ANT_PHASE_2G); - - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GSCANSTART); - } else if (type == BTC_SCAN_FINISH) { - btc->btc_get(btc, BTC_GET_U1_AP_NUM, &coex_sta->scan_ap_num); - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], SCAN FINISH notify (Scan-AP = %d)\n", - coex_sta->scan_ap_num); - BTC_TRACE(trace_buf); - - coex_sta->wifi_high_pri_task2 = FALSE; - - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_SCANFINISH); - } -} - -void ex_halbtc8821c2ant_switchband_notify(struct btc_coexist *btc, u8 type) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - - if (btc->manual_control || btc->stop_coex_dm) - return; - - coex_sta->switch_band_notify_to = type; - - if (type == BTC_SWITCH_TO_5G) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], switchband_notify --- switch to 5G\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_5GSWITCHBAND); - } else if (type == BTC_SWITCH_TO_24G_NOFORSCAN) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], switchband_notify --- BTC_SWITCH_TO_2G (no for scan)\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GSWITCHBAND); - } else { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], switchband_notify --- switch to 2G\n"); - BTC_TRACE(trace_buf); - - ex_halbtc8821c2ant_scan_notify(btc, BTC_SCAN_START_2G); - } - - coex_sta->switch_band_notify_to = BTC_NOT_SWITCH; -} - -void ex_halbtc8821c2ant_connect_notify(struct btc_coexist *btc, - u8 type) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - - if (btc->manual_control || btc->stop_coex_dm) - return; - - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | - BT_8821C_2ANT_SCBD_SCAN | - BT_8821C_2ANT_SCBD_ONOFF, TRUE); - - if (type == BTC_ASSOCIATE_5G_START || - type == BTC_ASSOCIATE_5G_FINISH) { - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, - BT_8821C_2ANT_PHASE_5G); - - if (type == BTC_ASSOCIATE_5G_START) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], CONNECT START notify (5G)\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_run_coex(btc, - BT_8821C_2ANT_RSN_5GCONSTART); - } else { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], CONNECT FINISH notify (5G)\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_run_coex(btc, - BT_8821C_2ANT_RSN_5GCONFINISH); - } - } else if (type == BTC_ASSOCIATE_START) { - coex_sta->wifi_high_pri_task1 = TRUE; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], CONNECT START notify (2G)\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, - BT_8821C_2ANT_PHASE_2G); - - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GCONSTART); - - /* To keep TDMA case during connect process, - to avoid changed by Btinfo and runcoexmechanism */ - coex_sta->freeze_coexrun_by_btinfo = TRUE; - coex_dm->arp_cnt = 0; - } else if (type == BTC_ASSOCIATE_FINISH) { - coex_sta->wifi_high_pri_task1 = FALSE; - coex_sta->freeze_coexrun_by_btinfo = FALSE; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], CONNECT FINISH notify (2G)\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GCONFINISH); - } -} - -void ex_halbtc8821c2ant_media_status_notify(struct btc_coexist *btc, u8 type) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - boolean wifi_under_b_mode = FALSE; - u8 h2c_parameter[2] = {0}; - - if (btc->manual_control || btc->stop_coex_dm) - return; - - if (type == BTC_MEDIA_CONNECT || type == BTC_MEDIA_CONNECT_5G) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], MEDIA connect notify\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | - BT_8821C_2ANT_SCBD_ONOFF, TRUE); - - if (type == BTC_MEDIA_CONNECT_5G) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], WiFi is under 5G!!!\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, - FC_EXCU, - BT_8821C_2ANT_PHASE_5G); - - halbtc8821c2ant_run_coex(btc, - BT_8821C_2ANT_RSN_5GMEDIA); - } else { - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, - FC_EXCU, - BT_8821C_2ANT_PHASE_2G); - - btc->btc_get(btc, BTC_GET_BL_WIFI_UNDER_B_MODE, - &wifi_under_b_mode); - - /* Set CCK Tx/Rx high Pri except 11b mode */ - if (wifi_under_b_mode) - btc->btc_write_1byte_bitmask(btc, 0x6cf, BIT(4), - 0x0); - else - btc->btc_write_1byte_bitmask(btc, 0x6cf, BIT(4), - 0x1); - - /*Leak-AP protection will reopen when connecting AP*/ - h2c_parameter[0] = 0xc; - h2c_parameter[1] = 0x0; - btc->btc_fill_h2c(btc, 0x69, 2, h2c_parameter); - coex_sta->is_no_wl_5ms_extend = FALSE; - - halbtc8821c2ant_run_coex(btc, - BT_8821C_2ANT_RSN_2GMEDIA); - } - } else { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], MEDIA disconnect notify\n"); - BTC_TRACE(trace_buf); - - btc->btc_write_1byte_bitmask(btc, 0x6cf, BIT(4), 0x0); - - coex_sta->cck_lock_ever = FALSE; - coex_sta->cck_lock_warn = FALSE; - coex_sta->cck_lock = FALSE; - - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_MEDIADISCON); - } - btc->btc_get(btc, BTC_GET_U1_IOT_PEER, &coex_sta->wl_iot_peer); - halbtc8821c2ant_update_wifi_ch_info(btc, type); -} - -void ex_halbtc8821c2ant_specific_packet_notify(struct btc_coexist *btc, u8 type) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; - boolean under_4way = FALSE; - - if (btc->manual_control || btc->stop_coex_dm) - return; - - if (type & BTC_5G_BAND) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], 5g special packet notify\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_5GSPECIALPKT); - return; - } - - btc->btc_get(btc, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under_4way); - - if (under_4way) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], specific Packet ---- under_4way!!\n"); - BTC_TRACE(trace_buf); - - coex_sta->wifi_high_pri_task1 = TRUE; - coex_sta->specific_pkt_period_cnt = 2; - } else if (type == BTC_PACKET_ARP) { - coex_dm->arp_cnt++; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], specific Packet ARP notify -cnt = %d\n", - coex_dm->arp_cnt); - BTC_TRACE(trace_buf); - } else { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], specific Packet DHCP or EAPOL notify [Type = %d]\n", - type); - BTC_TRACE(trace_buf); - - coex_sta->wifi_high_pri_task1 = TRUE; - coex_sta->specific_pkt_period_cnt = 2; - } - - if (coex_sta->wifi_high_pri_task1) { - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_SCAN, TRUE); - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GSPECIALPKT); - } -} - -void ex_halbtc8821c2ant_bt_info_notify(struct btc_coexist *btc, u8 *tmp_buf, - u8 length) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; - u8 i, rsp_source = 0; - boolean wifi_connected = FALSE; - boolean wifi_busy = FALSE; - static boolean is_scoreboard_scan; - const u16 type_is_scan = BT_8821C_2ANT_SCBD_SCAN; - u8 type; - - rsp_source = tmp_buf[0] & 0xf; - if (rsp_source >= BT_8821C_2ANT_INFO_SRC_MAX) - rsp_source = BT_8821C_2ANT_INFO_SRC_WIFI_FW; - coex_sta->bt_info_c2h_cnt[rsp_source]++; - - if (rsp_source == BT_8821C_2ANT_INFO_SRC_BT_RSP || - rsp_source == BT_8821C_2ANT_INFO_SRC_BT_ACT) { - if (coex_sta->bt_disabled) { - coex_sta->bt_disabled = FALSE; - coex_sta->is_bt_reenable = TRUE; - coex_sta->cnt_bt_reenable = 15; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT enable detected by bt_info\n"); - BTC_TRACE(trace_buf); - } - } - - if (rsp_source == BT_8821C_2ANT_INFO_SRC_WIFI_FW) { -#if 0 - halbtc8821c2ant_update_bt_link_info(btc); - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_BTINFO); -#endif - return; - } - - if (length != 7) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Bt_info length = %d invalid!!\n", - length); - BTC_TRACE(trace_buf); - return; - } - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Bt_info[%d], len=%d, data=[%02x %02x %02x %02x %02x %02x]\n", - tmp_buf[0], length, tmp_buf[1], tmp_buf[2], tmp_buf[3], - tmp_buf[4], tmp_buf[5], tmp_buf[6]); - BTC_TRACE(trace_buf); - - for (i = 0; i < 7; i++) - coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i]; - - if (coex_sta->bt_info_c2h[rsp_source][1] == coex_sta->bt_info_lb2 && - coex_sta->bt_info_c2h[rsp_source][2] == coex_sta->bt_info_lb3 && - coex_sta->bt_info_c2h[rsp_source][3] == coex_sta->bt_info_hb0 && - coex_sta->bt_info_c2h[rsp_source][4] == coex_sta->bt_info_hb1 && - coex_sta->bt_info_c2h[rsp_source][5] == coex_sta->bt_info_hb2 && - coex_sta->bt_info_c2h[rsp_source][6] == coex_sta->bt_info_hb3) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Return because Btinfo duplicate!!\n"); - BTC_TRACE(trace_buf); - return; - } - - coex_sta->bt_info_lb2 = coex_sta->bt_info_c2h[rsp_source][1]; - coex_sta->bt_info_lb3 = coex_sta->bt_info_c2h[rsp_source][2]; - coex_sta->bt_info_hb0 = coex_sta->bt_info_c2h[rsp_source][3]; - coex_sta->bt_info_hb1 = coex_sta->bt_info_c2h[rsp_source][4]; - coex_sta->bt_info_hb2 = coex_sta->bt_info_c2h[rsp_source][5]; - coex_sta->bt_info_hb3 = coex_sta->bt_info_c2h[rsp_source][6]; - - /* if 0xff, it means BT is under WHCK test */ - coex_sta->bt_whck_test = - ((coex_sta->bt_info_lb2 == 0xff) ? TRUE : FALSE); - - coex_sta->bt_create_connection = - ((coex_sta->bt_info_lb3 & BIT(7)) ? TRUE : FALSE); - - /* unit: %, value-100 to translate to unit: dBm */ - coex_sta->bt_rssi = coex_sta->bt_info_hb0 * 2 + 10; - - coex_sta->c2h_bt_remote_name_req = - ((coex_sta->bt_info_lb3 & BIT(5)) ? TRUE : FALSE); - - coex_sta->is_A2DP_3M = - ((coex_sta->bt_info_lb3 & BIT(4)) ? TRUE : FALSE); - - coex_sta->acl_busy = - ((coex_sta->bt_info_lb2 & BIT(3)) ? TRUE : FALSE); - - coex_sta->voice_over_HOGP = - ((coex_sta->bt_info_hb1 & BIT(4)) ? TRUE : FALSE); - - coex_sta->c2h_bt_inquiry_page = - ((coex_sta->bt_info_lb2 & BIT(2)) ? TRUE : FALSE); - - if (coex_sta->bt_inq_page_pre != coex_sta->c2h_bt_inquiry_page) { - coex_sta->bt_inq_page_pre = coex_sta->c2h_bt_inquiry_page; - coex_sta->bt_inq_page_remain = TRUE; - - if (!coex_sta->c2h_bt_inquiry_page) - coex_sta->bt_inq_page_downcount = 2; - } - - if ((coex_sta->bt_info_lb2 & 0x49) == 0x49) - coex_sta->a2dp_bit_pool = (coex_sta->bt_info_hb3 & 0x7f); - else - coex_sta->a2dp_bit_pool = 0; - - coex_sta->is_bt_a2dp_sink = - (coex_sta->bt_info_hb3 & BIT(7)) ? TRUE : FALSE; - - coex_sta->bt_retry_cnt = coex_sta->bt_info_lb3 & 0xf; - - bt_link_info->slave_role = coex_sta->bt_info_hb2 & 0x8; - - coex_sta->bt_a2dp_active = coex_sta->bt_info_hb2 & 0x4; - - coex_sta->hid_busy_num = (coex_sta->bt_info_hb2 & 0x30) >> 4; - - coex_sta->hid_pair_cnt = (coex_sta->bt_info_hb2 & 0xc0) >> 6; - - if (coex_sta->hid_pair_cnt > 0 && coex_sta->hid_busy_num >= 2) { - coex_sta->bt_418_hid_exist = TRUE; - } else if (coex_sta->hid_busy_num == 1 && - coex_sta->bt_ctr_ok && - (coex_sta->high_priority_rx + 100 < - coex_sta->high_priority_tx) && - coex_sta->high_priority_rx < 100) { - coex_sta->bt_ble_hid_exist = TRUE; - } else if (coex_sta->hid_pair_cnt == 0 || - coex_sta->hid_busy_num == 1) { - coex_sta->bt_418_hid_exist = FALSE; - coex_sta->bt_ble_hid_exist = FALSE; - } - - coex_sta->is_bt_opp_exist = - (coex_sta->bt_info_hb2 & BIT(0)) ? TRUE : FALSE; - - if (coex_sta->bt_retry_cnt >= 1) - coex_sta->pop_event_cnt++; - - if (coex_sta->c2h_bt_remote_name_req) - coex_sta->cnt_remote_name_req++; - - if (coex_sta->bt_info_hb1 & BIT(1)) - coex_sta->cnt_reinit++; - - if ((coex_sta->bt_info_hb1 & BIT(2)) || - (coex_sta->bt_create_connection && - coex_sta->wl_pnp_wakeup_downcnt > 0)) { - coex_sta->cnt_setup_link++; - coex_sta->is_setup_link = TRUE; - - if (coex_sta->is_bt_reenable) - coex_sta->bt_relink_downcount = 6; - else - coex_sta->bt_relink_downcount = 2; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Re-Link start in BT info!!\n"); - BTC_TRACE(trace_buf); - } - - if (coex_sta->bt_info_hb1 & BIT(3)) - coex_sta->cnt_ign_wlan_act++; - - if (coex_sta->bt_info_hb1 & BIT(6)) - coex_sta->cnt_role_switch++; - - if (coex_sta->bt_info_hb1 & BIT(7)) - coex_sta->is_bt_multi_link = TRUE; - else - coex_sta->is_bt_multi_link = FALSE; - - if (coex_sta->bt_info_hb1 & BIT(0)) - coex_sta->is_hid_rcu = TRUE; - else - coex_sta->is_hid_rcu = FALSE; - - if (coex_sta->bt_info_hb1 & BIT(5)) - coex_sta->is_ble_scan_en = TRUE; - else - coex_sta->is_ble_scan_en = FALSE; - - if (coex_sta->bt_create_connection) { - coex_sta->cnt_page++; - - btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); - - if (coex_sta->is_wifi_linkscan_process || - coex_sta->wifi_high_pri_task1 || - coex_sta->wifi_high_pri_task2 || wifi_busy) { - is_scoreboard_scan = TRUE; - halbtc8821c2ant_write_scbd(btc, type_is_scan, TRUE); - } else { - halbtc8821c2ant_write_scbd(btc, type_is_scan, FALSE); - } - } else { - if (is_scoreboard_scan) { - halbtc8821c2ant_write_scbd(btc, type_is_scan, FALSE); - is_scoreboard_scan = FALSE; - } - } - - /* Here we need to resend some wifi info to BT */ - /* because bt is reset and loss of the info. */ - btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); - /* Re-Init */ - if ((coex_sta->bt_info_hb1 & BIT(1))) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n"); - BTC_TRACE(trace_buf); - if (wifi_connected) - type = BTC_MEDIA_CONNECT; - else - type = BTC_MEDIA_DISCONNECT; - halbtc8821c2ant_update_wifi_ch_info(btc, type); - } - - /* If Ignore_WLanAct && not SetUp_Link */ - if ((coex_sta->bt_info_hb1 & BIT(3)) && - (!(coex_sta->bt_info_hb1 & BIT(2)))) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n"); - BTC_TRACE(trace_buf); - halbtc8821c2ant_ignore_wlan_act(btc, FC_EXCU, FALSE); - } - - halbtc8821c2ant_update_bt_link_info(btc); - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_BTINFO); -} - -void ex_halbtc8821c2ant_wl_fwdbginfo_notify(struct btc_coexist *btc, - u8 *tmp_buf, u8 length) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - u8 i = 0; - static u8 tmp_buf_pre[10]; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], WiFi Fw Dbg info = %d %d %d %d %d %d %d %d (len = %d)\n", - tmp_buf[0], tmp_buf[1], tmp_buf[2], tmp_buf[3], tmp_buf[4], - tmp_buf[5], tmp_buf[6], tmp_buf[7], length); - BTC_TRACE(trace_buf); - - if (tmp_buf[0] == 0x8) { - for (i = 1; i <= 7; i++) { - coex_sta->wl_fw_dbg_info[i] = - (tmp_buf[i] >= tmp_buf_pre[i]) ? - (tmp_buf[i] - tmp_buf_pre[i]) : - (255 - tmp_buf_pre[i] + tmp_buf[i]); - - tmp_buf_pre[i] = tmp_buf[i]; - } - } - - coex_sta->cnt_wl_fw_notify++; - halbtc8821c2ant_ccklock_action(btc); -} - -void ex_halbtc8821c2ant_rx_rate_change_notify(struct btc_coexist *btc, - BOOLEAN is_data_frame, - u8 btc_rate_id) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - - if (is_data_frame) { - coex_sta->wl_rx_rate = btc_rate_id; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], rx_rate_change_notify data rate id = %d, RTS_Rate = %d\n", - coex_sta->wl_rx_rate, coex_sta->wl_rts_rx_rate); - BTC_TRACE(trace_buf); - } else { - coex_sta->wl_rts_rx_rate = btc_rate_id; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], rts_rate_change_notify RTS rate id = %d, RTS_Rate = %d\n", - coex_sta->wl_rts_rx_rate, coex_sta->wl_rts_rx_rate); - BTC_TRACE(trace_buf); - } - - halbtc8821c2ant_ccklock_detect(btc); -} - -void ex_halbtc8821c2ant_tx_rate_change_notify(struct btc_coexist *btc, - u8 tx_rate, u8 tx_retry_ratio, - u8 macid) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], tx_rate_change_notify Tx_Rate = %d, Tx_Retry_Ratio = %d, macid =%d\n", - tx_rate, tx_retry_ratio, macid); - BTC_TRACE(trace_buf); - - coex_sta->wl_tx_rate = tx_rate; - coex_sta->wl_tx_retry_ratio = tx_retry_ratio; - coex_sta->wl_tx_macid = macid; -} - -void ex_halbtc8821c2ant_rf_status_notify(struct btc_coexist *btc, u8 type) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], RF Status notify\n"); - BTC_TRACE(trace_buf); - - if (type == BTC_RF_ON) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], RF is turned ON!!\n"); - BTC_TRACE(trace_buf); - - btc->stop_coex_dm = FALSE; - btc->wl_rf_state_off = FALSE; - } else if (type == BTC_RF_OFF) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], RF is turned OFF!!\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | - BT_8821C_2ANT_SCBD_ONOFF | - BT_8821C_2ANT_SCBD_SCAN | - BT_8821C_2ANT_SCBD_UNDERTEST, - FALSE); - - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, - BT_8821C_2ANT_PHASE_WOFF); - - halbtc8821c2ant_action_coex_all_off(btc); - - btc->stop_coex_dm = TRUE; - btc->wl_rf_state_off = TRUE; - /* must place in the last step */ - halbtc8821c2ant_update_wifi_ch_info(btc, BTC_MEDIA_DISCONNECT); - } -} - -void ex_halbtc8821c2ant_halt_notify(struct btc_coexist *btc) -{ - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], Halt notify\n"); - BTC_TRACE(trace_buf); - - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | - BT_8821C_2ANT_SCBD_ONOFF | - BT_8821C_2ANT_SCBD_SCAN | - BT_8821C_2ANT_SCBD_UNDERTEST, - FALSE); - - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, - BT_8821C_2ANT_PHASE_WOFF); - - halbtc8821c2ant_action_coex_all_off(btc); - - btc->stop_coex_dm = TRUE; - - /* must place in the last step */ - halbtc8821c2ant_update_wifi_ch_info(btc, BTC_MEDIA_DISCONNECT); -} - -void ex_halbtc8821c2ant_pnp_notify(struct btc_coexist *btc, u8 pnp_state) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct wifi_link_info_8821c_2ant *wifi_link_info_ext = - &btc->wifi_link_info_8821c_2ant; - static u8 pre_pnp_state; - u8 phase; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], Pnp notify\n"); - BTC_TRACE(trace_buf); - - if (pnp_state == BTC_WIFI_PNP_SLEEP || - pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT) { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Pnp notify to SLEEP\n"); - BTC_TRACE(trace_buf); - - /* Sinda 20150819, workaround for driver skip - * leave IPS/LPS to speed up sleep time. - * Driver do not leave IPS/LPS when driver is going to sleep, - * so BTCoexistence think wifi is still under IPS/LPS - * BT should clear UnderIPS/UnderLPS state to avoid mismatch - * state after wakeup. - */ - coex_sta->under_ips = FALSE; - coex_sta->under_lps = FALSE; - - halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | - BT_8821C_2ANT_SCBD_ONOFF | - BT_8821C_2ANT_SCBD_SCAN | - BT_8821C_2ANT_SCBD_UNDERTEST, - FALSE); - - if (pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT) { - if (wifi_link_info_ext->is_all_under_5g) - phase = BT_8821C_2ANT_PHASE_5G; - else - phase = BT_8821C_2ANT_PHASE_2G; - } else { - phase = BT_8821C_2ANT_PHASE_WOFF; - } - - halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, - phase); - btc->stop_coex_dm = TRUE; - } else { - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Pnp notify to WAKE UP\n"); - BTC_TRACE(trace_buf); - coex_sta->wl_pnp_wakeup_downcnt = 3; - - /*WoWLAN*/ - if (pre_pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT || - pnp_state == BTC_WIFI_PNP_WOWLAN) { - coex_sta->run_time_state = TRUE; - btc->stop_coex_dm = FALSE; - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_PNP); - } - } - - pre_pnp_state = pnp_state; -} - -void ex_halbtc8821c2ant_periodical(struct btc_coexist *btc) -{ - struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; - struct btc_board_info *board_info = &btc->board_info; - boolean bt_relink_finish = FALSE, is_defreeze = FALSE, - bt_ctr_change = FALSE; - static u8 freeze_cnt; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], ************* Periodical *************\n"); - BTC_TRACE(trace_buf); - - if (!btc->auto_report) - halbtc8821c2ant_query_bt_info(btc); - - bt_ctr_change = halbtc8821c2ant_monitor_bt_ctr(btc); - halbtc8821c2ant_monitor_wifi_ctr(btc); - halbtc8821c2ant_update_wifi_link_info(btc, - BT_8821C_2ANT_RSN_PERIODICAL); - halbtc8821c2ant_monitor_bt_enable(btc); - - if (coex_sta->bt_relink_downcount != 0) { - coex_sta->bt_relink_downcount--; - if (coex_sta->bt_relink_downcount == 0) { - coex_sta->is_setup_link = FALSE; - bt_relink_finish = TRUE; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Re-Link stop by periodical count-down!!\n"); - BTC_TRACE(trace_buf); - } - } - - if (coex_sta->bt_inq_page_downcount != 0) { - coex_sta->bt_inq_page_downcount--; - if (coex_sta->bt_relink_downcount == 0) - coex_sta->bt_inq_page_remain = FALSE; - } - - if (coex_sta->freeze_coexrun_by_btinfo) { - freeze_cnt++; - - if (freeze_cnt >= 5) { - freeze_cnt = 0; - coex_sta->freeze_coexrun_by_btinfo = FALSE; - is_defreeze = TRUE; - } - } else { - freeze_cnt = 0; - } - - /* for 4-way, DHCP, EAPOL packet */ - if (coex_sta->specific_pkt_period_cnt > 0) { - coex_sta->specific_pkt_period_cnt--; - - if (!coex_sta->freeze_coexrun_by_btinfo && - coex_sta->specific_pkt_period_cnt == 0) - coex_sta->wifi_high_pri_task1 = FALSE; - - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], Hi-Pri Task = %s\n", - (coex_sta->wifi_high_pri_task1 ? "Yes" : "No")); - BTC_TRACE(trace_buf); - } - - if (coex_sta->wl_pnp_wakeup_downcnt > 0) { - coex_sta->wl_pnp_wakeup_downcnt--; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], wl_pnp_wakeup_downcnt = %d!!\n", - coex_sta->wl_pnp_wakeup_downcnt); - BTC_TRACE(trace_buf); - } - - if (coex_sta->cnt_bt_reenable > 0) { - coex_sta->cnt_bt_reenable--; - if (coex_sta->cnt_bt_reenable == 0) { - coex_sta->is_bt_reenable = FALSE; - BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, - "[BTCoex], BT renable 30s finish!!\n"); - BTC_TRACE(trace_buf); - } - } - - if (halbtc8821c2ant_moniter_wifibt_status(btc) || bt_relink_finish || - coex_sta->is_set_ps_state_fail || is_defreeze || bt_ctr_change) - halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_PERIODICAL); -} -/*#pragma optimize( "", off )*/ - -#endif - -#endif /* #if (RTL8821C_SUPPORT == 1) */ + } + + coex_sta->crc_ok_cck = + btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_CCK); + coex_sta->crc_ok_11g = + btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_LEGACY); + coex_sta->crc_ok_11n = + btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_HT); + coex_sta->crc_ok_11n_vht = + btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_VHT); + + coex_sta->crc_err_cck = + btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_CCK); + coex_sta->crc_err_11g = + btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_LEGACY); + coex_sta->crc_err_11n = + btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_HT); + coex_sta->crc_err_11n_vht = + btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_VHT); + + /* CCK lock identification */ + if (coex_sta->cck_lock) + cnt_ccklocking++; + else if (cnt_ccklocking != 0) + cnt_ccklocking--; + + if (cnt_ccklocking >= 3) { + cnt_ccklocking = 3; + coex_sta->cck_lock_ever = TRUE; + } + + /* WiFi environment noisy identification */ + cnt_cck = coex_sta->crc_ok_cck + coex_sta->crc_err_cck; + + if (!wifi_busy && !coex_sta->cck_lock) { + if (cnt_cck > 250) { + if (wl_noisy_count2 < 3) + wl_noisy_count2++; + + if (wl_noisy_count2 == 3) { + wl_noisy_count0 = 0; + wl_noisy_count1 = 0; + } + + } else if (cnt_cck < 100) { + if (wl_noisy_count0 < 3) + wl_noisy_count0++; + + if (wl_noisy_count0 == 3) { + wl_noisy_count1 = 0; + wl_noisy_count2 = 0; + } + + } else { + if (wl_noisy_count1 < 3) + wl_noisy_count1++; + + if (wl_noisy_count1 == 3) { + wl_noisy_count0 = 0; + wl_noisy_count2 = 0; + } + } + + if (wl_noisy_count2 == 3) + coex_sta->wl_noisy_level = 2; + else if (wl_noisy_count1 == 3) + coex_sta->wl_noisy_level = 1; + else + coex_sta->wl_noisy_level = 0; + } +} + +static +void halbtc8821c2ant_monitor_bt_enable(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + static u32 bt_disable_cnt; + boolean bt_active = TRUE, bt_disabled = FALSE; + u16 u16tmp; + + /* Read BT on/off status from scoreboard[1], + * enable this only if BT patch support this feature + */ + halbtc8821c2ant_read_scbd(btc, &u16tmp); + + bt_active = u16tmp & BIT(1); + + if (bt_active) { + bt_disable_cnt = 0; + bt_disabled = FALSE; + btc->btc_set(btc, BTC_SET_BL_BT_DISABLE, &bt_disabled); + } else { + bt_disable_cnt++; + if (bt_disable_cnt >= 2) { + bt_disabled = TRUE; + bt_disable_cnt = 2; + } + + btc->btc_set(btc, BTC_SET_BL_BT_DISABLE, &bt_disabled); + } + + if (coex_sta->bt_disabled != bt_disabled) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT is from %s to %s!!\n", + (coex_sta->bt_disabled ? "disabled" : "enabled"), + (bt_disabled ? "disabled" : "enabled")); + BTC_TRACE(trace_buf); + coex_sta->bt_disabled = bt_disabled; + + /*for win10 BT disable->enable trigger wifi scan issue */ + if (!coex_sta->bt_disabled) { + coex_sta->is_bt_reenable = TRUE; + coex_sta->cnt_bt_reenable = 15; + } else { + coex_sta->is_bt_reenable = FALSE; + coex_sta->cnt_bt_reenable = 0; + } + } +} + +static +boolean halbtc8821c2ant_moniter_wifibt_status(struct btc_coexist + *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct wifi_link_info_8821c_2ant *wifi_link_info_ext = + &btc->wifi_link_info_8821c_2ant; + static boolean pre_wifi_busy, pre_under_4way, + pre_bt_off, pre_bt_slave, pre_hid_low_pri_tx_overhead, + pre_wifi_under_lps, pre_bt_setup_link, + pre_cck_lock, pre_cck_lock_warn; + static u8 pre_hid_busy_num, pre_wl_noisy_level; + boolean wifi_busy = FALSE, under_4way = FALSE; + boolean wifi_connected = FALSE; + struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; + static u8 cnt_wifi_busytoidle; + u32 num_of_wifi_link = 0, wifi_link_mode = 0; + static u32 pre_num_of_wifi_link, pre_wifi_link_mode; + boolean miracast_plus_bt = FALSE; + + btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btc->btc_get(btc, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under_4way); + + if (wifi_busy) { + coex_sta->gl_wifi_busy = TRUE; + cnt_wifi_busytoidle = 6; + } else { + if (coex_sta->gl_wifi_busy && cnt_wifi_busytoidle > 0) + cnt_wifi_busytoidle--; + else if (cnt_wifi_busytoidle == 0) + coex_sta->gl_wifi_busy = FALSE; + } + + if (coex_sta->bt_disabled != pre_bt_off) { + pre_bt_off = coex_sta->bt_disabled; + + if (coex_sta->bt_disabled) + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT is disabled !!\n"); + else + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT is enabled !!\n"); + + BTC_TRACE(trace_buf); + + coex_sta->bt_coex_supported_feature = 0; + coex_sta->bt_coex_supported_version = 0; + coex_sta->bt_ble_scan_type = 0; + coex_sta->bt_ble_scan_para[0] = 0; + coex_sta->bt_ble_scan_para[1] = 0; + coex_sta->bt_ble_scan_para[2] = 0; + coex_sta->bt_reg_vendor_ac = 0xffff; + coex_sta->bt_reg_vendor_ae = 0xffff; + coex_sta->bt_a2dp_vendor_id = 0; + coex_sta->bt_a2dp_device_name = 0; + btc->bt_info.bt_get_fw_ver = 0; + return TRUE; + } + + num_of_wifi_link = wifi_link_info_ext->num_of_active_port; + + if (num_of_wifi_link != pre_num_of_wifi_link) { + pre_num_of_wifi_link = num_of_wifi_link; + + if (wifi_link_info_ext->is_p2p_connected) { + if (bt_link_info->bt_link_exist) + miracast_plus_bt = TRUE; + else + miracast_plus_bt = FALSE; + + btc->btc_set(btc, BTC_SET_BL_MIRACAST_PLUS_BT, + &miracast_plus_bt); + } + return TRUE; + } + + wifi_link_mode = btc->wifi_link_info.link_mode; + if (wifi_link_mode != pre_wifi_link_mode) { + pre_wifi_link_mode = wifi_link_mode; + return TRUE; + } + + if (wifi_connected) { + if (wifi_busy != pre_wifi_busy) { + pre_wifi_busy = wifi_busy; + return TRUE; + } + if (under_4way != pre_under_4way) { + pre_under_4way = under_4way; + return TRUE; + } + + if (coex_sta->wl_noisy_level != pre_wl_noisy_level) { + pre_wl_noisy_level = coex_sta->wl_noisy_level; + return TRUE; + } + if (coex_sta->under_lps != pre_wifi_under_lps) { + pre_wifi_under_lps = coex_sta->under_lps; + if (coex_sta->under_lps) + return TRUE; + } + if (coex_sta->cck_lock != pre_cck_lock) { + pre_cck_lock = coex_sta->cck_lock; + return TRUE; + } + if (coex_sta->cck_lock_warn != pre_cck_lock_warn) { + pre_cck_lock_warn = coex_sta->cck_lock_warn; + return TRUE; + } + } + + if (!coex_sta->bt_disabled) { +#if 0 + if (coex_sta->acl_busy != pre_bt_acl_busy) { + pre_bt_acl_busy = coex_sta->acl_busy; + btc->btc_set(btc, BTC_SET_BL_BT_LNA_CONSTRAIN_LEVEL, + &lna_lvl); + return TRUE; + } +#endif + if (coex_sta->hid_busy_num != pre_hid_busy_num) { + pre_hid_busy_num = coex_sta->hid_busy_num; + return TRUE; + } + + if (bt_link_info->slave_role != pre_bt_slave) { + pre_bt_slave = bt_link_info->slave_role; + return TRUE; + } + + if (pre_hid_low_pri_tx_overhead != + coex_sta->is_hid_low_pri_tx_overhead) { + pre_hid_low_pri_tx_overhead = + coex_sta->is_hid_low_pri_tx_overhead; + return TRUE; + } + + if (pre_bt_setup_link != coex_sta->is_setup_link) { + pre_bt_setup_link = coex_sta->is_setup_link; + return TRUE; + } + } + + return FALSE; +} + +static +void halbtc8821c2ant_update_wifi_link_info(struct btc_coexist *btc, u8 reason) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct wifi_link_info_8821c_2ant *wifi_link_info_ext = + &btc->wifi_link_info_8821c_2ant; + struct btc_wifi_link_info wifi_link_info; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + u8 wifi_central_chnl = 0, num_of_wifi_link = 0; + boolean isunder5G = FALSE, ismcc25g = FALSE, isp2pconnected = FALSE; + u32 wifi_link_status = 0; + + btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, + &wifi_link_info_ext->is_connected); + + btc->btc_get(btc, BTC_GET_U4_WIFI_LINK_STATUS, &wifi_link_status); + wifi_link_info_ext->port_connect_status = wifi_link_status & 0xffff; + + btc->btc_get(btc, BTC_GET_BL_WIFI_LINK_INFO, &wifi_link_info); + btc->wifi_link_info = wifi_link_info; + + btc->btc_get(btc, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifi_central_chnl); + coex_sta->wl_center_channel = wifi_central_chnl; + + /* Check scan/connect/special-pkt action first */ + switch (reason) { + case BT_8821C_2ANT_RSN_5GSCANSTART: + case BT_8821C_2ANT_RSN_5GSWITCHBAND: + case BT_8821C_2ANT_RSN_5GCONSTART: + isunder5G = TRUE; + break; + case BT_8821C_2ANT_RSN_2GSCANSTART: + case BT_8821C_2ANT_RSN_2GSWITCHBAND: + case BT_8821C_2ANT_RSN_2GCONSTART: + isunder5G = FALSE; + break; + case BT_8821C_2ANT_RSN_2GCONFINISH: + case BT_8821C_2ANT_RSN_5GCONFINISH: + case BT_8821C_2ANT_RSN_2GMEDIA: + case BT_8821C_2ANT_RSN_5GMEDIA: + case BT_8821C_2ANT_RSN_BTINFO: + case BT_8821C_2ANT_RSN_PERIODICAL: + case BT_8821C_2ANT_RSN_2GSPECIALPKT: + case BT_8821C_2ANT_RSN_5GSPECIALPKT: + default: + switch (wifi_link_info.link_mode) { + case BTC_LINK_5G_MCC_GO_STA: + case BTC_LINK_5G_MCC_GC_STA: + case BTC_LINK_5G_SCC_GO_STA: + case BTC_LINK_5G_SCC_GC_STA: + isunder5G = TRUE; + break; + case BTC_LINK_2G_MCC_GO_STA: + case BTC_LINK_2G_MCC_GC_STA: + case BTC_LINK_2G_SCC_GO_STA: + case BTC_LINK_2G_SCC_GC_STA: + isunder5G = FALSE; + break; + case BTC_LINK_25G_MCC_GO_STA: + case BTC_LINK_25G_MCC_GC_STA: + isunder5G = FALSE; + ismcc25g = TRUE; + break; + case BTC_LINK_ONLY_STA: + if (wifi_link_info.sta_center_channel > 14) + isunder5G = TRUE; + else + isunder5G = FALSE; + break; + case BTC_LINK_ONLY_GO: + case BTC_LINK_ONLY_GC: + case BTC_LINK_ONLY_AP: + default: + if (wifi_link_info.p2p_center_channel > 14) + isunder5G = TRUE; + else + isunder5G = FALSE; + + break; + } + break; + } + + wifi_link_info_ext->is_all_under_5g = isunder5G; + wifi_link_info_ext->is_mcc_25g = ismcc25g; + + if (wifi_link_status & WIFI_STA_CONNECTED) + num_of_wifi_link++; + + if (wifi_link_status & WIFI_AP_CONNECTED) + num_of_wifi_link++; + + if (wifi_link_status & WIFI_P2P_GO_CONNECTED) { + num_of_wifi_link++; + isp2pconnected = TRUE; + } + + if (wifi_link_status & WIFI_P2P_GC_CONNECTED) { + num_of_wifi_link++; + isp2pconnected = TRUE; + } + + wifi_link_info_ext->num_of_active_port = num_of_wifi_link; + wifi_link_info_ext->is_p2p_connected = isp2pconnected; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi_link_info: link_mode=%d, STA_Ch=%d, P2P_Ch=%d, AnyClient_Join_Go=%d !\n", + btc->wifi_link_info.link_mode, + btc->wifi_link_info.sta_center_channel, + btc->wifi_link_info.p2p_center_channel, + btc->wifi_link_info.bany_client_join_go); + BTC_TRACE(trace_buf); + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi_link_info: center_ch=%d, is_all_under_5g=%d, is_mcc_25g=%d!\n", + coex_sta->wl_center_channel, + wifi_link_info_ext->is_all_under_5g, + wifi_link_info_ext->is_mcc_25g); + BTC_TRACE(trace_buf); + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi_link_info: port_connect_status=0x%x, active_port_cnt=%d, P2P_Connect=%d!\n", + wifi_link_info_ext->port_connect_status, + wifi_link_info_ext->num_of_active_port, + wifi_link_info_ext->is_p2p_connected); + BTC_TRACE(trace_buf); + + switch (reason) { + case BT_8821C_2ANT_RSN_2GSCANSTART: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "2GSCANSTART"); + break; + case BT_8821C_2ANT_RSN_5GSCANSTART: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "5GSCANSTART"); + break; + case BT_8821C_2ANT_RSN_SCANFINISH: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "SCANFINISH"); + break; + case BT_8821C_2ANT_RSN_2GSWITCHBAND: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "2GSWITCHBAND"); + break; + case BT_8821C_2ANT_RSN_5GSWITCHBAND: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "5GSWITCHBAND"); + break; + case BT_8821C_2ANT_RSN_2GCONSTART: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "2GCONNECTSTART"); + break; + case BT_8821C_2ANT_RSN_5GCONSTART: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "5GCONNECTSTART"); + break; + case BT_8821C_2ANT_RSN_2GCONFINISH: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", + "2GCONNECTFINISH"); + break; + case BT_8821C_2ANT_RSN_5GCONFINISH: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", + "5GCONNECTFINISH"); + break; + case BT_8821C_2ANT_RSN_2GMEDIA: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "2GMEDIASTATUS"); + break; + case BT_8821C_2ANT_RSN_5GMEDIA: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "5GMEDIASTATUS"); + break; + case BT_8821C_2ANT_RSN_MEDIADISCON: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", + "MEDIADISCONNECT"); + break; + case BT_8821C_2ANT_RSN_2GSPECIALPKT: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "2GSPECIALPKT"); + break; + case BT_8821C_2ANT_RSN_5GSPECIALPKT: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "5GSPECIALPKT"); + break; + case BT_8821C_2ANT_RSN_BTINFO: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "BTINFO"); + break; + case BT_8821C_2ANT_RSN_PERIODICAL: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "PERIODICAL"); + break; + case BT_8821C_2ANT_RSN_PNP: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "PNPNotify"); + break; + default: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Update reason = %s\n", "UNKNOWN"); + break; + } + + BTC_TRACE(trace_buf); + + if (btc->manual_control || btc->stop_coex_dm) + return; + + if (wifi_link_info_ext->is_all_under_5g || num_of_wifi_link == 0 || + coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE) { + halbtc8821c2ant_low_penalty_ra(btc, NM_EXCU, FALSE, 0); + halbtc8821c2ant_limited_tx(btc, NM_EXCU, FALSE, FALSE); + halbtc8821c2ant_limited_rx(btc, NM_EXCU, FALSE, TRUE, 64); + } else if (wifi_link_info_ext->num_of_active_port > 1) { + halbtc8821c2ant_low_penalty_ra(btc, NM_EXCU, TRUE, 30); + halbtc8821c2ant_limited_tx(btc, NM_EXCU, FALSE, TRUE); + halbtc8821c2ant_limited_rx(btc, NM_EXCU, FALSE, TRUE, 16); + } else { + halbtc8821c2ant_low_penalty_ra(btc, NM_EXCU, TRUE, 15); + + if (coex_sta->hid_exist || coex_sta->hid_pair_cnt > 0 || + coex_sta->sco_exist) { + halbtc8821c2ant_limited_tx(btc, NM_EXCU, TRUE, TRUE); + halbtc8821c2ant_limited_rx(btc, NM_EXCU, FALSE, TRUE, + 16); + } else { + halbtc8821c2ant_limited_tx(btc, NM_EXCU, TRUE, FALSE); + halbtc8821c2ant_limited_rx(btc, NM_EXCU, FALSE, TRUE, + 64); + } + } + + /* coex-276 P2P-Go beacon request can't release issue + * Only PCIe/USB can set 0x454[6] = 1 to solve this issue, + * WL SDIO/USB interface need driver support. + */ +#ifdef PLATFORM_WINDOWS + if (btc->chip_interface != BTC_INTF_SDIO) + btc->btc_write_1byte_bitmask(btc, 0x454, BIT(6), 0x1); + else + btc->btc_write_1byte_bitmask(btc, 0x454, BIT(6), 0x0); +#endif +} + +static +void halbtc8821c2ant_update_bt_link_info(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; + boolean bt_busy = FALSE, increase_scan_dev_num = FALSE; + u32 val = 0; + static u8 pre_num_of_profile, cur_num_of_profile, cnt, ble_cnt; + + if (++ble_cnt >= 3) + ble_cnt = 0; + + if (coex_sta->is_ble_scan_en && ble_cnt == 0) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT ext info bit4 check, query BLE Scan type!!\n"); + BTC_TRACE(trace_buf); + coex_sta->bt_ble_scan_type = + btc->btc_get_ble_scan_type_from_bt(btc); + + if ((coex_sta->bt_ble_scan_type & 0x1) == 0x1) + coex_sta->bt_ble_scan_para[0] = + btc->btc_get_ble_scan_para_from_bt(btc, 0x1); + if ((coex_sta->bt_ble_scan_type & 0x2) == 0x2) + coex_sta->bt_ble_scan_para[1] = + btc->btc_get_ble_scan_para_from_bt(btc, 0x2); + if ((coex_sta->bt_ble_scan_type & 0x4) == 0x4) + coex_sta->bt_ble_scan_para[2] = + btc->btc_get_ble_scan_para_from_bt(btc, 0x4); + } + + coex_sta->num_of_profile = 0; + + /* set link exist status */ + if (!(coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_CONNECTION)) { + coex_sta->bt_link_exist = FALSE; + coex_sta->pan_exist = FALSE; + coex_sta->a2dp_exist = FALSE; + coex_sta->hid_exist = FALSE; + coex_sta->sco_exist = FALSE; + coex_sta->msft_mr_exist = FALSE; + } else { /* connection exists */ + coex_sta->bt_link_exist = TRUE; + if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_FTP) { + coex_sta->pan_exist = TRUE; + coex_sta->num_of_profile++; + } else { + coex_sta->pan_exist = FALSE; + } + + if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_A2DP) { + coex_sta->a2dp_exist = TRUE; + coex_sta->num_of_profile++; + } else { + coex_sta->a2dp_exist = FALSE; + } + + if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_HID) { + coex_sta->hid_exist = TRUE; + coex_sta->num_of_profile++; + } else { + coex_sta->hid_exist = FALSE; + } + + if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_ESCO) { + coex_sta->sco_exist = TRUE; + coex_sta->num_of_profile++; + } else { + coex_sta->sco_exist = FALSE; + } +#if 0 + if (coex_sta->hid_busy_num == 0 && + coex_sta->hid_pair_cnt > 0 && + coex_sta->low_priority_tx > 1000 && + coex_sta->low_priority_rx > 1000 && + !coex_sta->c2h_bt_inquiry_page) + coex_sta->msft_mr_exist = true; + else + coex_sta->msft_mr_exist = false; +#endif + } + + bt_link_info->bt_link_exist = coex_sta->bt_link_exist; + bt_link_info->sco_exist = coex_sta->sco_exist; + bt_link_info->a2dp_exist = coex_sta->a2dp_exist; + bt_link_info->pan_exist = coex_sta->pan_exist; + bt_link_info->hid_exist = coex_sta->hid_exist; + bt_link_info->acl_busy = coex_sta->acl_busy; + + /* check if Sco only */ + if (bt_link_info->sco_exist && + !bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && + !bt_link_info->hid_exist) + bt_link_info->sco_only = TRUE; + else + bt_link_info->sco_only = FALSE; + + /* check if A2dp only */ + if (!bt_link_info->sco_exist && + bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && + !bt_link_info->hid_exist) + bt_link_info->a2dp_only = TRUE; + else + bt_link_info->a2dp_only = FALSE; + + /* check if Pan only */ + if (!bt_link_info->sco_exist && + !bt_link_info->a2dp_exist && + bt_link_info->pan_exist && + !bt_link_info->hid_exist) + bt_link_info->pan_only = TRUE; + else + bt_link_info->pan_only = FALSE; + + /* check if Hid only */ + if (!bt_link_info->sco_exist && + !bt_link_info->a2dp_exist && + !bt_link_info->pan_exist && + bt_link_info->hid_exist) + bt_link_info->hid_only = TRUE; + else + bt_link_info->hid_only = FALSE; + + if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_INQ_PAGE) { + coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_INQ_PAGE; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BtInfoNotify(), BT Inq/page!!!\n"); + } else if (!(coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_CONNECTION)) { + coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_NCON_IDLE; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n"); + } else if (coex_sta->bt_info_lb2 == BT_INFO_8821C_2ANT_B_CONNECTION) { + /* connection exists but no busy */ + if (coex_sta->msft_mr_exist) { + coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_ACL_BUSY; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BtInfoNotify(), BT ACL busy!!\n"); + } else { + coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_CON_IDLE; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n"); + } + } else if (((coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_ESCO) || + (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_BUSY)) && + (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_ACL_BUSY)) { + coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_ACL_SCO_BUSY; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BtInfoNotify(), BT ACL SCO busy!!!\n"); + } else if ((coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_ESCO) || + (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_BUSY)) { + coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_SCO_BUSY; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); + } else if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_ACL_BUSY) { + coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_ACL_BUSY; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); + } else { + coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_MAX; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n"); + } + + BTC_TRACE(trace_buf); + + if (coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_ACL_BUSY || + coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_SCO_BUSY || + coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_ACL_SCO_BUSY) { + bt_busy = TRUE; + increase_scan_dev_num = TRUE; + } else { + bt_busy = FALSE; + increase_scan_dev_num = FALSE; + } + + btc->btc_set(btc, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); + btc->btc_set(btc, BTC_SET_BL_INC_SCAN_DEV_NUM, &increase_scan_dev_num); + + cur_num_of_profile = coex_sta->num_of_profile; + + if (cur_num_of_profile != pre_num_of_profile) + cnt = 2; + + if (btc->board_info.customer_id == RT_CID_LENOVO_CHINA) { + if (cur_num_of_profile > 0) + halbtc8821c2ant_set_antdiv_hwsw(btc, NM_EXCU, TRUE); + else + halbtc8821c2ant_set_antdiv_hwsw(btc, NM_EXCU, FALSE); + } + + if (bt_link_info->a2dp_exist && cnt > 0) { + cnt--; + if (coex_sta->bt_a2dp_vendor_id == 0 && + coex_sta->bt_a2dp_device_name == 0) { + btc->btc_get(btc, BTC_GET_U4_BT_DEVICE_INFO, &val); + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BtInfoNotify(), get BT DEVICE_INFO = %x\n", + val); + BTC_TRACE(trace_buf); + + coex_sta->bt_a2dp_vendor_id = (u8)(val & 0xff); + coex_sta->bt_a2dp_device_name = (val & 0xffffff00) >> 8; + + btc->btc_get(btc, BTC_GET_U4_BT_A2DP_FLUSH_VAL, &val); + coex_sta->bt_a2dp_flush_time = val; + } + } else if (!bt_link_info->a2dp_exist) { + coex_sta->bt_a2dp_vendor_id = 0; + coex_sta->bt_a2dp_device_name = 0; + coex_sta->bt_a2dp_flush_time = 0; + } + + pre_num_of_profile = coex_sta->num_of_profile; +} + +static +void halbtc8821c2ant_update_wifi_ch_info(struct btc_coexist *btc, u8 type) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + struct wifi_link_info_8821c_2ant *wifi_link_info_ext = + &btc->wifi_link_info_8821c_2ant; + u8 h2c_parameter[3] = {0}, i; + u32 wifi_bw; + u8 wl_ch = 0; + u8 wl_5g_ch[] = {0}; + u8 bt_skip_ch[] = {0}; + u8 bt_skip_span[] = {0}; + + if (btc->manual_control) + return; + + btc->btc_get(btc, BTC_GET_U4_WIFI_BW, &wifi_bw); + + if (btc->stop_coex_dm || btc->wl_rf_state_off) { + wl_ch = 0; + } else if (type != BTC_MEDIA_DISCONNECT || + (type == BTC_MEDIA_DISCONNECT && + wifi_link_info_ext->num_of_active_port > 0)) { + if (wifi_link_info_ext->num_of_active_port == 1) { + if (wifi_link_info_ext->is_p2p_connected) + wl_ch = btc->wifi_link_info.p2p_center_channel; + else + wl_ch = btc->wifi_link_info.sta_center_channel; + } else { /* port > 2 */ + if (btc->wifi_link_info.p2p_center_channel > 14 && + btc->wifi_link_info.sta_center_channel > 14) + wl_ch = btc->wifi_link_info.p2p_center_channel; + else if (btc->wifi_link_info.p2p_center_channel <= 14) + wl_ch = btc->wifi_link_info.p2p_center_channel; + else if (btc->wifi_link_info.sta_center_channel <= 14) + wl_ch = btc->wifi_link_info.sta_center_channel; + } + } + + if (wl_ch > 0) { + if (wl_ch <= 14) { + h2c_parameter[0] = 0x1; + h2c_parameter[1] = wl_ch; + + if (wifi_bw == BTC_WIFI_BW_HT40) + h2c_parameter[2] = 0x36; + else + h2c_parameter[2] = 0x24; + } else { /* for 5G */ +#if 0 + for (i = 0; i < ARRAY_SIZE(wl_5g_ch); i++) { + if (wl_ch == wl_5g_ch[i]) { + h2c_parameter[0] = 0x3; + h2c_parameter[1] = bt_skip_ch[i]; + h2c_parameter[2] = bt_skip_span[i]; + break; + } + } +#endif + } + } + + /* Only send mailbox if ch info change */ + if (coex_dm->wifi_chnl_info[0] != h2c_parameter[0] && + coex_dm->wifi_chnl_info[1] != h2c_parameter[1] && + coex_dm->wifi_chnl_info[2] != h2c_parameter[2]) { + + coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; + coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; + coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; + btc->btc_fill_h2c(btc, 0x66, 3, h2c_parameter); + } + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], para[0:2] = 0x%x 0x%x 0x%x\n", h2c_parameter[0], + h2c_parameter[1], h2c_parameter[2]); + BTC_TRACE(trace_buf); +} + +static +void halbtc8821c2ant_set_wl_tx_power(struct btc_coexist *btc, + boolean force_exec, u8 wl_pwr_lvl) +{ + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + + if (!force_exec) { + if (wl_pwr_lvl == coex_dm->cur_wl_pwr_lvl) + return; + } + + /* btc->btc_write_1byte_bitmask(btc, 0xc5b, 0xff, wl_pwr_lvl); */ + coex_dm->cur_wl_pwr_lvl = wl_pwr_lvl; +} + +static +void halbtc8821c2ant_set_bt_tx_power(struct btc_coexist *btc, + boolean force_exec, u8 bt_pwr_lvl) +{ + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + u8 h2c_parameter[1] = {0}; + + if (!force_exec) { + if (bt_pwr_lvl == coex_dm->cur_bt_pwr_lvl) + return; + } + + h2c_parameter[0] = 0 - bt_pwr_lvl; + btc->btc_fill_h2c(btc, 0x62, 1, h2c_parameter); + + coex_dm->cur_bt_pwr_lvl = bt_pwr_lvl; +} + +static u32 +halbtc8821c2ant_wait_indirect_reg_ready(struct btc_coexist *btc) +{ + u32 delay_count = 0; + + /* wait for ready bit before access 0x1700 */ + while (1) { + if ((btc->btc_read_1byte(btc, 0x1703) & BIT(5)) == 0) { + delay_ms(10); + if (++delay_count >= 10) + break; + } else { + break; + } + } + + return delay_count; +} + +static +u32 halbtc8821c2ant_read_indirect_reg(struct btc_coexist *btc, u16 reg_addr) +{ + u32 j = 0, delay_count = 0; + + halbtc8821c2ant_wait_indirect_reg_ready(btc); + + /* wait for ready bit before access 0x1700 */ + btc->btc_write_4byte(btc, 0x1700, 0x800F0000 | reg_addr); + + return btc->btc_read_4byte(btc, 0x1708); /* get read data */ +} + +static +void halbtc8821c2ant_write_indirect_reg(struct btc_coexist *btc, u16 reg_addr, + u32 bit_mask, u32 reg_value) +{ + u32 val, i = 0, j = 0, bitpos = 0, delay_count = 0; + + if (bit_mask == 0x0) + return; + if (bit_mask == 0xffffffff) { + /* wait for ready bit before access 0x1700/0x1704 */ + halbtc8821c2ant_wait_indirect_reg_ready(btc); + + /* put write data */ + btc->btc_write_4byte(btc, 0x1704, reg_value); + btc->btc_write_4byte(btc, 0x1700, 0xc00F0000 | reg_addr); + } else { + for (i = 0; i <= 31; i++) { + if (((bit_mask >> i) & 0x1) == 0x1) { + bitpos = i; + break; + } + } + + /* read back register value before write */ + val = halbtc8821c2ant_read_indirect_reg(btc, reg_addr); + val = (val & (~bit_mask)) | (reg_value << bitpos); + + /* wait for ready bit before access 0x1700/0x1704 */ + halbtc8821c2ant_wait_indirect_reg_ready(btc); + + /* put write data */ + btc->btc_write_4byte(btc, 0x1704, val); + btc->btc_write_4byte(btc, 0x1700, 0xc00F0000 | reg_addr); + } +} + +static +void halbtc8821c2ant_ltecoex_enable(struct btc_coexist *btc, boolean enable) +{ + u8 val; + + /* 0x38[7] */ + val = (enable) ? 1 : 0; + halbtc8821c2ant_write_indirect_reg(btc, 0x38, BIT(7), val); +} + +static +void halbtc8821c2ant_ltecoex_table(struct btc_coexist *btc, u8 table_type, + u16 val) +{ + u16 reg_addr = 0x0000; + + switch (table_type) { + case BT_8821C_2ANT_CTT_WL_VS_LTE: + reg_addr = 0xa0; + break; + case BT_8821C_2ANT_CTT_BT_VS_LTE: + reg_addr = 0xa4; + break; + } + + /* 0xa0[15:0] or 0xa4[15:0] */ + if (reg_addr != 0x0000) + halbtc8821c2ant_write_indirect_reg(btc, reg_addr, 0xffff, val); +} + +static +void halbtc8821c2ant_coex_ctrl_owner(struct btc_coexist *btc, + boolean wifi_control) +{ + u8 val; + + /* 0x70[26] */ + val = (wifi_control) ? 1 : 0; + btc->btc_write_1byte_bitmask(btc, 0x73, BIT(2), val); +} + +static void +halbtc8821c2ant_set_gnt_bt(struct btc_coexist *btc, u8 state) +{ + switch (state) { + case BTC_GNT_SET_SW_LOW: + halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0xc000, 0x1); + halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0c00, 0x1); + break; + case BTC_GNT_SET_SW_HIGH: + halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0xc000, 0x3); + halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0c00, 0x3); + break; + case BTC_GNT_SET_HW_PTA: + default: + halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0xc000, 0x0); + halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0c00, 0x0); + break; + } +} + +static void +halbtc8821c2ant_set_gnt_wl(struct btc_coexist *btc, u8 state) +{ + switch (state) { + case BTC_GNT_SET_SW_LOW: + halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x3000, 0x1); + halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0300, 0x1); + break; + case BTC_GNT_SET_SW_HIGH: + halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x3000, 0x3); + halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0300, 0x3); + break; + case BTC_GNT_SET_HW_PTA: + default: + halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x3000, 0x0); + halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0300, 0x0); + break; + } +} + +static +void halbtc8821c2ant_set_table(struct btc_coexist *btc, + boolean force_exec, u32 val0x6c0, + u32 val0x6c4, u32 val0x6c8, + u8 val0x6cc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + + if (!force_exec && !coex_sta->wl_slot_toggle_change) { + coex_dm->cur_val0x6c0 = btc->btc_read_4byte(btc, 0x6c0); + coex_dm->cur_val0x6c4 = btc->btc_read_4byte(btc, 0x6c4); + + if (val0x6c0 == coex_dm->cur_val0x6c0 && + val0x6c4 == coex_dm->cur_val0x6c4) + return; + } + + btc->btc_write_4byte(btc, 0x6c0, val0x6c0); + btc->btc_write_4byte(btc, 0x6c4, val0x6c4); + btc->btc_write_4byte(btc, 0x6c8, val0x6c8); + btc->btc_write_1byte(btc, 0x6cc, val0x6cc); + + coex_dm->cur_val0x6c8 = val0x6c8; + coex_dm->cur_val0x6cc = val0x6cc; +} + +void halbtc8821c2ant_table(struct btc_coexist *btc, boolean force_exec, u8 type) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + u32 break_table; + u8 select_table; + + coex_sta->coex_table_type = type; + + if (coex_sta->concurrent_rx_mode_on == TRUE) { + /* set WL hi-pri can break BT */ + break_table = 0xf0ffffff; + /* set Tx response = Hi-Pri (ex: Transmitting ACK,BA,CTS) */ + select_table = 0x1b; + } else { + break_table = 0xffffff; + select_table = 0x13; + } + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], ********** Table-%d **********\n", + coex_sta->coex_table_type); + BTC_TRACE(trace_buf); + + switch (type) { + case 0: + halbtc8821c2ant_set_table(btc, force_exec, 0xffffffff, + 0xffffffff, break_table, + select_table); + break; + case 1: + halbtc8821c2ant_set_table(btc, force_exec, 0x55555555, + 0xfafafafa, break_table, + select_table); + break; + case 2: + halbtc8821c2ant_set_table(btc, force_exec, 0x5a5a5a5a, + 0x5a5a5a5a, break_table, + select_table); + break; + case 3: + halbtc8821c2ant_set_table(btc, force_exec, 0x66555555, + 0x6a5a5a5a, break_table, + select_table); + break; + case 4: + halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff, + 0xfafafafa, break_table, + select_table); + break; + case 5: + halbtc8821c2ant_set_table(btc, force_exec, 0x55555555, + 0x55555555, break_table, + select_table); + break; + case 6: /* not use */ + halbtc8821c2ant_set_table(btc, force_exec, 0xaaffffaa, + 0x5afa5afa, break_table, + select_table); + break; + case 7: + halbtc8821c2ant_set_table(btc, force_exec, 0xaaffffaa, + 0xfafafafa, break_table, + select_table); + break; + case 8: + halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff, + 0xfafafafa, break_table, + select_table); + break; + case 9: + halbtc8821c2ant_set_table(btc, force_exec, 0x5a5a5a5a, + 0xaaaa5aaa, break_table, + select_table); + break; + case 10: + halbtc8821c2ant_set_table(btc, force_exec, 0xaaaaaaaa, + 0xaaaaaaaa, break_table, + select_table); + break; + case 11: + halbtc8821c2ant_set_table(btc, force_exec, 0xffffffff, + 0xfafafafa, break_table, + select_table); + break; + case 12: + halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff, + 0x5afa5afa, break_table, + select_table); + break; + case 14: + halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff, + 0xaaaaaaaa, break_table, + select_table); + break; + case 15: + halbtc8821c2ant_set_table(btc, force_exec, 0x66555555, + 0xaaaaaaaa, break_table, + select_table); + break; + case 18: + halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff, + 0xffff55ff, break_table, + select_table); + break; + default: + break; + } +} + +#if 0 +static void +halbtc8821c2ant_wltoggle_table(IN struct btc_coexist *btc, + IN boolean force_exec, IN u8 interval, + IN u8 val0x6c4_b0, IN u8 val0x6c4_b1, + IN u8 val0x6c4_b2, IN u8 val0x6c4_b3) +{ + static u8 pre_h2c_parameter[6] = {0}; + u8 cur_h2c_parameter[6] = {0}; + u8 i, match_cnt = 0; + + cur_h2c_parameter[0] = 0x7; /* op_code, 0x7= wlan toggle slot*/ + + cur_h2c_parameter[1] = interval; + cur_h2c_parameter[2] = val0x6c4_b0; + cur_h2c_parameter[3] = val0x6c4_b1; + cur_h2c_parameter[4] = val0x6c4_b2; + cur_h2c_parameter[5] = val0x6c4_b3; +#if 0 + if (!force_exec) { + for (i = 1; i <= 5; i++) { + if (cur_h2c_parameter[i] != pre_h2c_parameter[i]) + break; + + match_cnt++; + } + + if (match_cnt == 5) + return; + } +#endif + for (i = 1; i <= 5; i++) + pre_h2c_parameter[i] = cur_h2c_parameter[i]; + + btc->btc_fill_h2c(btc, 0x69, 6, cur_h2c_parameter); +} +#endif + +static +void halbtc8821c2ant_ignore_wlan_act(struct btc_coexist *btc, + boolean force_exec, boolean enable) +{ + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + u8 h2c_parameter[1] = {0}; + + if (btc->manual_control || btc->stop_coex_dm) + return; + + if (!force_exec) { + if (enable == coex_dm->cur_ignore_wlan_act) + return; + } + + if (enable) + h2c_parameter[0] |= BIT(0); /* function enable */ + + btc->btc_fill_h2c(btc, 0x63, 1, h2c_parameter); + + coex_dm->cur_ignore_wlan_act = enable; +} + +static +void halbtc8821c2ant_lps_rpwm(struct btc_coexist *btc, boolean force_exec, + u8 lps_val, u8 rpwm_val) +{ + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + + if (!force_exec) { + if (lps_val == coex_dm->cur_lps && + rpwm_val == coex_dm->cur_rpwm) + return; + } + + btc->btc_set(btc, BTC_SET_U1_LPS_VAL, &lps_val); + btc->btc_set(btc, BTC_SET_U1_RPWM_VAL, &rpwm_val); + + coex_dm->cur_lps = lps_val; + coex_dm->cur_rpwm = rpwm_val; +} + +static +void halbtc8821c2ant_tdma_check(struct btc_coexist *btc, boolean new_ps_state) +{ + u8 lps_mode = 0x0; + u8 h2c_parameter[5] = {0, 0, 0, 0x40, 0}; + + btc->btc_get(btc, BTC_GET_U1_LPS_MODE, &lps_mode); + + if (lps_mode) { /* already under LPS state */ + if (new_ps_state) { + /* keep state under LPS, do nothing. */ + } else { + /* will leave LPS state, turn off psTdma first */ + btc->btc_fill_h2c(btc, 0x60, 5, h2c_parameter); + } + } else { /* NO PS state */ + if (new_ps_state) { + /* will enter LPS state, turn off psTdma first */ + btc->btc_fill_h2c(btc, 0x60, 5, h2c_parameter); + } else { + /* keep state under NO PS state, do nothing. */ + } + } +} + +static +boolean halbtc8821c2ant_power_save_state(struct btc_coexist *btc, u8 ps_type, + u8 lps_val, u8 rpwm_val) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + boolean low_pwr_disable = FALSE, result = TRUE; + + switch (ps_type) { + case BTC_PS_WIFI_NATIVE: + coex_sta->force_lps_ctrl = FALSE; + /* recover to original 32k low power setting */ + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], %s == BTC_PS_WIFI_NATIVE\n", __func__); + BTC_TRACE(trace_buf); + + low_pwr_disable = FALSE; + /* btc->btc_set(btc, BTC_SET_ACT_DISABLE_LOW_POWER, + * &low_pwr_disable); + */ + btc->btc_set(btc, BTC_SET_ACT_PRE_NORMAL_LPS, NULL); + break; + case BTC_PS_LPS_ON: + coex_sta->force_lps_ctrl = TRUE; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], %s == BTC_PS_LPS_ON\n", __func__); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_tdma_check(btc, TRUE); + halbtc8821c2ant_lps_rpwm(btc, NM_EXCU, lps_val, rpwm_val); + /* when coex force to enter LPS, do not enter 32k low power. */ + low_pwr_disable = TRUE; + btc->btc_set(btc, BTC_SET_ACT_DISABLE_LOW_POWER, + &low_pwr_disable); + /* power save must executed before psTdma.*/ + btc->btc_set(btc, BTC_SET_ACT_ENTER_LPS, NULL); + break; + case BTC_PS_LPS_OFF: + coex_sta->force_lps_ctrl = TRUE; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], %s == BTC_PS_LPS_OFF\n", __func__); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_tdma_check(btc, FALSE); + result = btc->btc_set(btc, BTC_SET_ACT_LEAVE_LPS, NULL); + break; + default: + break; + } + + return result; +} + +static +void halbtc8821c2ant_set_tdma(struct btc_coexist *btc, u8 byte1, u8 byte2, + u8 byte3, u8 byte4, u8 byte5) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + u8 h2c_parameter[5] = {0}; + u8 real_byte1 = byte1, real_byte5 = byte5; + boolean ap_enable = FALSE, result = FALSE; + u8 ps_type = BTC_PS_WIFI_NATIVE; + + if (byte5 & BIT(2)) + coex_sta->is_tdma_btautoslot = TRUE; + else + coex_sta->is_tdma_btautoslot = FALSE; + + if (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO && + btc->wifi_link_info.bhotspot && + btc->wifi_link_info.bany_client_join_go) + ap_enable = TRUE; + + if ((ap_enable) && (byte1 & BIT(4) && !(byte1 & BIT(5)))) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], %s == FW for AP mode\n", __func__); + BTC_TRACE(trace_buf); + + real_byte1 &= ~BIT(4); + real_byte1 |= BIT(5); + + real_byte5 |= BIT(5); + real_byte5 &= ~BIT(6); + + ps_type = BTC_PS_WIFI_NATIVE; + halbtc8821c2ant_power_save_state(btc, ps_type, 0x0, 0x0); + } else if (byte1 & BIT(4) && !(byte1 & BIT(5))) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], %s == Force LPS (byte1 = 0x%x)\n", + __func__, byte1); + BTC_TRACE(trace_buf); + + ps_type = BTC_PS_LPS_OFF; + if (!halbtc8821c2ant_power_save_state(btc, ps_type, 0x50, 0x4)) + result = TRUE; + } else { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], %s == Native LPS (byte1 = 0x%x)\n", + __func__, byte1); + BTC_TRACE(trace_buf); + + ps_type = BTC_PS_WIFI_NATIVE; + halbtc8821c2ant_power_save_state(btc, ps_type, 0x0, 0x0); + } + + coex_sta->is_set_ps_state_fail = result; + + if (!coex_sta->is_set_ps_state_fail) { + h2c_parameter[0] = real_byte1; + h2c_parameter[1] = byte2; + h2c_parameter[2] = byte3; + h2c_parameter[3] = byte4; + h2c_parameter[4] = real_byte5; + + coex_dm->ps_tdma_para[0] = real_byte1; + coex_dm->ps_tdma_para[1] = byte2; + coex_dm->ps_tdma_para[2] = byte3; + coex_dm->ps_tdma_para[3] = byte4; + coex_dm->ps_tdma_para[4] = real_byte5; + + btc->btc_fill_h2c(btc, 0x60, 5, h2c_parameter); + + if (real_byte1 & BIT(2)) { + coex_sta->wl_slot_toggle = TRUE; + coex_sta->wl_slot_toggle_change = FALSE; + } else { + if (coex_sta->wl_slot_toggle) + coex_sta->wl_slot_toggle_change = TRUE; + else + coex_sta->wl_slot_toggle_change = FALSE; + coex_sta->wl_slot_toggle = FALSE; + } + } else { + coex_sta->cnt_set_ps_state_fail++; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], %s == Force Leave LPS Fail (cnt = %d)\n", + __func__, coex_sta->cnt_set_ps_state_fail); + BTC_TRACE(trace_buf); + } + + if (ps_type == BTC_PS_WIFI_NATIVE) + btc->btc_set(btc, BTC_SET_ACT_POST_NORMAL_LPS, NULL); +} + +static +void halbtc8821c2ant_tdma(struct btc_coexist *btc, + boolean force_exec, boolean turn_on, u32 tcase) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + u8 type; + boolean wifi_busy; + + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + btc->btc_set_atomic(btc, &coex_dm->setting_tdma, TRUE); + + /* tcase: bit0~7 --> tdma case index + * bit8 --> for 4-slot (50ms) mode + */ + if (tcase & TDMA_4SLOT)/* 4-slot (50ms) mode */ + halbtc8821c2ant_set_tdma_timer_base(btc, 3); + else + halbtc8821c2ant_set_tdma_timer_base(btc, 0); + + type = (u8)(tcase & 0xff); + + /* To avoid TDMA H2C fail before Last LPS enter */ + if (!force_exec && coex_sta->coex_run_reason != BTC_RSN_LPS) { + if (turn_on == coex_dm->cur_ps_tdma_on && + type == coex_dm->cur_ps_tdma) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Skip TDMA because no change TDMA(%s, %d)\n", + (coex_dm->cur_ps_tdma_on ? "on" : "off"), + coex_dm->cur_ps_tdma); + BTC_TRACE(trace_buf); + + btc->btc_set_atomic(btc, &coex_dm->setting_tdma, FALSE); + return; + } + } + + if (!wifi_busy || + (coex_sta->a2dp_exist && + (coex_sta->bt_inq_page_remain || coex_sta->is_bt_multi_link))) + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_TDMA, + FALSE); + else + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_TDMA, + TRUE); + + if (turn_on) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], ********** TDMA(on, %d) **********\n", + type); + BTC_TRACE(trace_buf); + + /* enable TBTT nterrupt */ + btc->btc_write_1byte_bitmask(btc, 0x550, 0x8, 0x1); + + switch (type) { + case 1: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x91, + 0x50); + break; + case 2: + default: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x35, 0x03, 0x11, + 0x11); + break; + case 3: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x30, 0x3, 0x91, + 0x10); + break; + case 4: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x21, 0x3, 0x91, + 0x10); + break; + case 5: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x25, 0x3, 0x91, + 0x10); + break; + case 6: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x3, 0x91, + 0x10); + break; + case 7: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x20, 0x3, 0x91, + 0x10); + break; + case 8: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x15, 0x03, 0x11, + 0x11); + break; + case 10: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x30, 0x03, 0x11, + 0x10); + break; + case 11: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x35, 0x03, 0x11, + 0x10); + break; + case 12: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x35, 0x03, 0x11, + 0x11); + break; + case 13: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x20, 0x03, 0x11, + 0x10); + break; + case 14: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x20, 0x03, 0x11, + 0x11); + break; + case 15: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x11, + 0x10); + break; + case 16: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x11, + 0x11); + break; + case 17: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x08, 0x03, 0x11, + 0x14); + break; + case 21: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x30, 0x03, 0x11, + 0x10); + break; + case 22: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x25, 0x03, 0x11, + 0x10); + break; + case 23: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x11, + 0x10); + break; + case 25: + halbtc8821c2ant_set_tdma(btc, 0x51, 0x3a, 0x3, 0x11, + 0x50); + break; + case 51: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x91, + 0x10); + break; + case 101: + halbtc8821c2ant_set_tdma(btc, 0x51, 0x08, 0x03, 0x10, + 0x54); + break; + case 102: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x35, 0x03, 0x11, + 0x11); + break; + case 103: + halbtc8821c2ant_set_tdma(btc, 0x51, 0x30, 0x3, 0x10, + 0x50); + break; + case 104: + halbtc8821c2ant_set_tdma(btc, 0x51, 0x21, 0x3, 0x10, + 0x50); + break; + case 105: + halbtc8821c2ant_set_tdma(btc, 0x51, 0x45, 0x3, 0x10, + 0x50); + break; + case 106: + halbtc8821c2ant_set_tdma(btc, 0x51, 0x1a, 0x3, 0x10, + 0x50); + break; + case 107: + halbtc8821c2ant_set_tdma(btc, 0x51, 0x08, 0x7, 0x10, + 0x54); + break; + case 108: + halbtc8821c2ant_set_tdma(btc, 0x51, 0x30, 0x3, 0x10, + 0x50); + break; + case 109: + halbtc8821c2ant_set_tdma(btc, 0x51, 0x08, 0x03, 0x10, + 0x54); + break; + case 110: + halbtc8821c2ant_set_tdma(btc, 0x51, 0x30, 0x03, 0x10, + 0x50); + break; + case 111: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x25, 0x03, 0x11, + 0x11); + break; + case 112: + halbtc8821c2ant_set_tdma(btc, 0x51, 0x4a, 0x3, 0x10, + 0x50); + break; + case 113: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x45, 0x03, 0x11, + 0x10); + break; + case 115: + halbtc8821c2ant_set_tdma(btc, 0x51, 0x30, 0x03, 0x10, + 0x50); + break; + case 116: + halbtc8821c2ant_set_tdma(btc, 0x51, 0x08, 0x03, 0x10, + 0x50); + break; + case 117: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x08, 0x03, 0x11, + 0x11); + break; + case 119: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x08, 0x03, 0x10, + 0x14); + break; + case 120: + halbtc8821c2ant_set_tdma(btc, 0x61, 0x08, 0x03, 0x10, + 0x15); + break; + case 151: + halbtc8821c2ant_set_tdma(btc, 0x51, 0x10, 0x03, 0x10, + 0x50); + break; + } + } else { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], ********** TDMA(off, %d) **********\n", + type); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_TDMA, FALSE); + + /* disable PS tdma */ + switch (type) { + case 0: + halbtc8821c2ant_set_tdma(btc, 0x0, 0x0, 0x0, 0x40, 0x0); + break; + case 1: + halbtc8821c2ant_set_tdma(btc, 0x0, 0x0, 0x0, 0x48, 0x0); + break; + default: + halbtc8821c2ant_set_tdma(btc, 0x0, 0x0, 0x0, 0x40, 0x0); + break; + } + } + + coex_dm->cur_ps_tdma_on = turn_on; + coex_dm->cur_ps_tdma = type; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "change TDMA(%s, %d)\n", + (coex_dm->cur_ps_tdma_on ? "on" : "off"), + coex_dm->cur_ps_tdma); + BTC_TRACE(trace_buf); + + btc->btc_set_atomic(btc, &coex_dm->setting_tdma, FALSE); +} + +static +void halbtc8821c2ant_set_ant_switch(struct btc_coexist *btc, + boolean force_exec, u8 ctrl_type, + u8 pos_type) +{ + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + struct rfe_type_8821c_2ant *rfe_type = &btc->rfe_type_8821c_2ant; + struct btc_board_info *board_info = &btc->board_info; + boolean polarity_inverse = FALSE; + u8 val = 0; + u32 u32tmp1 = 0, u32tmp2 = 0, u32tmp3 = 0; + + if (!rfe_type->ext_ant_switch_exist) + return; + + if (!force_exec) { + if (((ctrl_type << 8) + pos_type) == + coex_dm->cur_ext_ant_switch_status) + return; + } + + coex_dm->cur_ext_ant_switch_status = (ctrl_type << 8) + pos_type; + + /* swap control polarity if use different switch control polarity + * Normal switch polarity for DPDT, + * 0xcb4[29:28] = 2b'01 => BTG to Main, WLG to Aux, + * 0xcb4[29:28] = 2b'10 => BTG to Aux, WLG to Main + * Normal switch polarity for SPDT, + * 0xcb4[29:28] = 2b'01 => Ant to BTG, + * 0xcb4[29:28] = 2b'10 => Ant to WLG + */ + if (rfe_type->ext_ant_switch_ctrl_polarity) + polarity_inverse = !polarity_inverse; + + /* swap control polarity if 1-Ant at Aux */ + if (rfe_type->ant_at_main_port == FALSE) + polarity_inverse = !polarity_inverse; + + switch (pos_type) { + default: + case BT_8821C_2ANT_TO_BT: + case BT_8821C_2ANT_TO_NOCARE: + case BT_8821C_2ANT_TO_WLA: + + break; + case BT_8821C_2ANT_TO_WLG: + if (!rfe_type->wlg_locate_at_btg) + polarity_inverse = !polarity_inverse; + + break; + } + + if (board_info->ant_div_cfg && ctrl_type == BT_8821C_2ANT_CTRL_BY_BBSW) + ctrl_type = BT_8821C_2ANT_CTRL_BY_ANTDIV; + + switch (ctrl_type) { + default: + case BT_8821C_2ANT_CTRL_BY_BBSW: + /* 0x4c[23] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0); + /* 0x4c[24] = 1 */ + btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x1); + /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as control pin */ + btc->btc_write_1byte_bitmask(btc, 0xcb4, 0xff, 0x77); + /* 0xcb4[29:28] = 2b'01 for no switch_polarity_inverse, + * DPDT_SEL_N =1, DPDT_SEL_P =0 + */ + val = (!polarity_inverse ? 0x1 : 0x2); + btc->btc_write_1byte_bitmask(btc, 0xcb7, 0x30, val); + break; + case BT_8821C_2ANT_CTRL_BY_PTA: + /* 0x4c[23] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0); + /* 0x4c[24] = 1 */ + btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x1); + /* PTA, DPDT use RFE_ctrl8 and RFE_ctrl9 as control pin */ + btc->btc_write_1byte_bitmask(btc, 0xcb4, 0xff, 0x66); + /* 0xcb4[29:28] = 2b'10 for no switch_polatiry_inverse, + * DPDT_SEL_N =1, DPDT_SEL_P =0 @ GNT_BT=1 + */ + val = (!polarity_inverse ? 0x2 : 0x1); + btc->btc_write_1byte_bitmask(btc, 0xcb7, 0x30, val); + break; + case BT_8821C_2ANT_CTRL_BY_ANTDIV: + /* 0x4c[23] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0); + /* 0x4c[24] = 1 */ + btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x1); + btc->btc_write_1byte_bitmask(btc, 0xcb4, 0xff, 0x88); + + /* no regval_0xcb7 setup required, because antenna switch + * control value by antenna diversity + */ + break; + case BT_8821C_2ANT_CTRL_BY_MAC: + /* 0x4c[23] = 1 */ + btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x1); + /* 0x64[0] = 1b'0 for no switch_polarity_inverse, + * DPDT_SEL_N =1, DPDT_SEL_P =0 + */ + val = (!polarity_inverse ? 0x0 : 0x1); + btc->btc_write_1byte_bitmask(btc, 0x64, 0x1, val); + break; + case BT_8821C_2ANT_CTRL_BY_FW: + /* 0x4c[23] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0); + /* 0x4c[24] = 1 */ + btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x1); + break; + case BT_8821C_2ANT_CTRL_BY_BT: + /* 0x4c[23] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0); + /* 0x4c[24] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x0); + /* no setup required, because antenna switch control value + * by BT vendor 0xac[1:0] + */ + break; + } + + /* PAPE, LNA_ON control by BT while WLAN off + * for current leakage issue + */ + if (ctrl_type == BT_8821C_2ANT_CTRL_BY_BT) { + /* PAPE 0x64[29] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x67, 0x20, 0x0); + /* LNA_ON 0x64[28] = 0 */ + btc->btc_write_1byte_bitmask(btc, 0x67, 0x10, 0x0); + } else { + /* PAPE 0x64[29] = 1 */ + btc->btc_write_1byte_bitmask(btc, 0x67, 0x20, 0x1); + /* LNA_ON 0x64[28] = 1 */ + btc->btc_write_1byte_bitmask(btc, 0x67, 0x10, 0x1); + } +} + +static +void halbtc8821c2ant_set_rfe_type(struct btc_coexist *btc) +{ + struct rfe_type_8821c_2ant *rfe_type = &btc->rfe_type_8821c_2ant; + struct btc_board_info *board_info = &btc->board_info; + + /* the following setup should be got from Efuse in the future */ + rfe_type->rfe_module_type = board_info->rfe_type & 0x1f; + + rfe_type->ext_ant_switch_ctrl_polarity = 0; + + switch (rfe_type->rfe_module_type) { + case 0: + case 8: + default: /*2-Ant, DPDT, WLG*/ + rfe_type->ext_ant_switch_exist = TRUE; + rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_DPDT; + rfe_type->wlg_locate_at_btg = FALSE; + rfe_type->ant_at_main_port = TRUE; + break; + case 1: + case 9: /*1-Ant, Main, WLG */ + rfe_type->ext_ant_switch_exist = TRUE; + rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_SPDT; + rfe_type->wlg_locate_at_btg = FALSE; + rfe_type->ant_at_main_port = TRUE; + break; + case 2: + case 10: /*1-Ant, Main, BTG */ + rfe_type->ext_ant_switch_exist = TRUE; + rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_SPDT; + rfe_type->wlg_locate_at_btg = TRUE; + rfe_type->ant_at_main_port = TRUE; + break; + case 3: + case 11: /*1-Ant, Aux, WLG */ + rfe_type->ext_ant_switch_exist = TRUE; + rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_DPDT; + rfe_type->wlg_locate_at_btg = FALSE; + rfe_type->ant_at_main_port = FALSE; + break; + case 4: + case 12: /*1-Ant, Aux, BTG */ + rfe_type->ext_ant_switch_exist = TRUE; + rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_DPDT; + rfe_type->wlg_locate_at_btg = TRUE; + rfe_type->ant_at_main_port = FALSE; + break; + case 5: + case 13: /*2-Ant, no switch, WLG*/ + rfe_type->ext_ant_switch_exist = FALSE; + rfe_type->ext_ant_switch_type = BT_8821C_2ANT_SWITCH_NONE; + rfe_type->wlg_locate_at_btg = FALSE; + rfe_type->ant_at_main_port = TRUE; + break; + case 6: + case 14: /*2-Ant, no antenna switch, WLG*/ + rfe_type->ext_ant_switch_exist = FALSE; + rfe_type->ext_ant_switch_type = BT_8821C_2ANT_SWITCH_NONE; + rfe_type->wlg_locate_at_btg = FALSE; + rfe_type->ant_at_main_port = TRUE; + break; + case 7: + case 15: /*2-Ant, DPDT, BTG*/ + rfe_type->ext_ant_switch_exist = TRUE; + rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_DPDT; + rfe_type->wlg_locate_at_btg = TRUE; + rfe_type->ant_at_main_port = TRUE; + break; + } +} + +static +void halbtc8821c2ant_set_ant_path(struct btc_coexist *btc, + u8 ant_pos_type, boolean force_exec, + u8 phase) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + struct btc_board_info *board_info = &btc->board_info; + u32 cnt_bt_cal_chk = 0, u32tmp1 = 0, u32tmp2 = 0; + u8 u8tmp = 0, ctrl_type, pos_type; + + if (!force_exec) { + if (coex_dm->cur_ant_pos_type == ((ant_pos_type << 8) + phase)) + return; + } + + coex_dm->cur_ant_pos_type = (ant_pos_type << 8) + phase; + + if (btc->dbg_mode) { + u32tmp1 = btc->btc_read_4byte(btc, 0xcbc); + u32tmp2 = btc->btc_read_4byte(btc, 0xcb4); + u8tmp = btc->btc_read_1byte(btc, 0x73); + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], (Before Ant Setup) 0xcb4 = 0x%x, 0xcbc = 0x%x, 0x73 = 0x%x\n", + u32tmp1, u32tmp2, u8tmp); + BTC_TRACE(trace_buf); + } + + switch (phase) { + case BT_8821C_2ANT_PHASE_POWERON: + /* set Path control owner to WL at initial step */ + halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_BTSIDE); + + if (ant_pos_type == BTC_ANT_PATH_AUTO) { + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) + ant_pos_type = BTC_ANT_WIFI_AT_MAIN; + else + ant_pos_type = BTC_ANT_WIFI_AT_AUX; + } + + coex_sta->run_time_state = FALSE; + break; + case BT_8821C_2ANT_PHASE_INIT: + /* Disable LTE Coex Function in WiFi side + * (this should be on if LTE coex is required) + */ + halbtc8821c2ant_ltecoex_enable(btc, 0x0); + + /* GNT_WL_LTE always = 1 + * (this should be config if LTE coex is required) + */ + halbtc8821c2ant_ltecoex_table(btc, BT_8821C_2ANT_CTT_WL_VS_LTE, + 0xffff); + + /* GNT_BT_LTE always = 1 + * (this should be config if LTE coex is required) + */ + halbtc8821c2ant_ltecoex_table(btc, BT_8821C_2ANT_CTT_BT_VS_LTE, + 0xffff); + + /* Wait If BT IQK running, because Path control owner + * is at BT during BT IQK (setup by WiFi firmware) + */ + while (cnt_bt_cal_chk <= 20) { + u8tmp = btc->btc_read_1byte(btc, 0x49c); + cnt_bt_cal_chk++; + + if (u8tmp & BIT(1)) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], ########### BT is calibrating (wait cnt=%d)\n", + cnt_bt_cal_chk); + BTC_TRACE(trace_buf); + delay_ms(10); + } else { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], ********** BT is NOT calibrating (wait cnt=%d)\n", + cnt_bt_cal_chk); + BTC_TRACE(trace_buf); + break; + } + } + + /* set Path control owner to WL at initial step */ + halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE); + + /* set GNT_BT to SW high */ + halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_SW_HIGH); + /* Set GNT_WL to SW high */ + halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_HIGH); + + coex_sta->run_time_state = FALSE; + + if (ant_pos_type == BTC_ANT_PATH_AUTO) { + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) + ant_pos_type = BTC_ANT_WIFI_AT_MAIN; + else + ant_pos_type = BTC_ANT_WIFI_AT_AUX; + } + break; + case BT_8821C_2ANT_PHASE_WONLY: + /* Disable LTE Coex Function in WiFi side + * (this should be on if LTE coex is required) + */ + halbtc8821c2ant_ltecoex_enable(btc, 0x0); + + /* GNT_WL_LTE always = 1 + * (this should be config if LTE coex is required) + */ + halbtc8821c2ant_ltecoex_table(btc, BT_8821C_2ANT_CTT_WL_VS_LTE, + 0xffff); + + /* GNT_BT_LTE always = 1 + * (this should be config if LTE coex is required) + */ + halbtc8821c2ant_ltecoex_table(btc, BT_8821C_2ANT_CTT_BT_VS_LTE, + 0xffff); + + /* set Path control owner to WL at initial step */ + halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE); + + /* set GNT_BT to SW Low */ + halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_SW_LOW); + /* Set GNT_WL to SW high */ + halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_HIGH); + + coex_sta->run_time_state = FALSE; + + if (ant_pos_type == BTC_ANT_PATH_AUTO) { + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) + ant_pos_type = BTC_ANT_WIFI_AT_MAIN; + else + ant_pos_type = BTC_ANT_WIFI_AT_AUX; + } + + break; + case BT_8821C_2ANT_PHASE_WOFF: + /* Disable LTE Coex Function in WiFi side */ + halbtc8821c2ant_ltecoex_enable(btc, 0x0); + + /* set Path control owner to BT */ + halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_BTSIDE); + + coex_sta->run_time_state = FALSE; + break; + case BT_8821C_2ANT_PHASE_2G: + while (cnt_bt_cal_chk <= 20) { + /* 0x49c[0]=1 WL IQK, 0x49c[1]=1 BT IQK*/ + u8tmp = btc->btc_read_1byte(btc, 0x49c); + + cnt_bt_cal_chk++; + if (u8tmp & BIT(0)) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], ########### WL is IQK (wait cnt=%d)\n", + cnt_bt_cal_chk); + BTC_TRACE(trace_buf); + delay_ms(10); + } else if (u8tmp & BIT(1)) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], ########### BT is IQK (wait cnt=%d)\n", + cnt_bt_cal_chk); + BTC_TRACE(trace_buf); + delay_ms(10); + } else { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], ********** WL and BT is NOT IQK (wait cnt=%d)\n", + cnt_bt_cal_chk); + BTC_TRACE(trace_buf); + break; + } + } + + /* set Path control owner to WL at runtime step */ + halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE); + + /* set GNT_BT to PTA */ + halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_HW_PTA); + + /* Set GNT_WL to PTA */ + halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_HW_PTA); + + coex_sta->run_time_state = TRUE; + + if (ant_pos_type == BTC_ANT_PATH_AUTO) { + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) + ant_pos_type = BTC_ANT_WIFI_AT_MAIN; + else + ant_pos_type = BTC_ANT_WIFI_AT_AUX; + } + + break; + case BT_8821C_2ANT_PHASE_5G: + /* set Path control owner to WL at runtime step */ + halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE); + + /* set GNT_BT to PTA */ + halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_HW_PTA); + + /* Set GNT_WL to SW Hi */ + halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_HIGH); + + coex_sta->run_time_state = TRUE; + + if (ant_pos_type == BTC_ANT_PATH_AUTO) { + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) + ant_pos_type = BTC_ANT_WIFI_AT_MAIN; + else + ant_pos_type = BTC_ANT_WIFI_AT_AUX; + } + + break; + case BT_8821C_2ANT_PHASE_BTMP: + /* Disable LTE Coex Function in WiFi side */ + halbtc8821c2ant_ltecoex_enable(btc, 0x0); + + /* set Path control owner to WL */ + halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE); + + /* set GNT_BT to SW Hi */ + halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_SW_HIGH); + + /* Set GNT_WL to SW Lo */ + halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_LOW); + + coex_sta->run_time_state = FALSE; + + if (ant_pos_type == BTC_ANT_PATH_AUTO) { + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) + ant_pos_type = BTC_ANT_WIFI_AT_MAIN; + else + ant_pos_type = BTC_ANT_WIFI_AT_AUX; + } + + break; + case BT_8821C_2ANT_PHASE_ANTDET: + halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE); + + /* set GNT_BT to high */ + halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_SW_HIGH); + /* Set GNT_WL to high */ + halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_HIGH); + + if (ant_pos_type == BTC_ANT_PATH_AUTO) { + if (board_info->btdm_ant_pos == + BTC_ANTENNA_AT_MAIN_PORT) + ant_pos_type = BTC_ANT_WIFI_AT_MAIN; + else + ant_pos_type = BTC_ANT_WIFI_AT_AUX; + } + + coex_sta->run_time_state = FALSE; + break; + } + + if (phase == BT_8821C_2ANT_PHASE_WOFF) { + /* Set Ext Ant Switch to BT control at wifi off step */ + ctrl_type = BT_8821C_2ANT_CTRL_BY_BT; + pos_type = BT_8821C_2ANT_TO_NOCARE; + } else { + switch (ant_pos_type) { + default: + case BTC_ANT_WIFI_AT_MAIN: + ctrl_type = BT_8821C_2ANT_CTRL_BY_BBSW; + pos_type = BT_8821C_2ANT_TO_WLG; + break; + case BTC_ANT_WIFI_AT_AUX: + ctrl_type = BT_8821C_2ANT_CTRL_BY_BBSW; + pos_type = BT_8821C_2ANT_TO_BT; + break; + case BTC_ANT_WIFI_AT_DIVERSITY: + ctrl_type = BT_8821C_2ANT_CTRL_BY_ANTDIV; + pos_type = BT_8821C_2ANT_TO_NOCARE; + break; + } + } + + halbtc8821c2ant_set_ant_switch(btc, force_exec, ctrl_type, pos_type); + + if (btc->dbg_mode) { + u32tmp1 = btc->btc_read_4byte(btc, 0xcbc); + u32tmp2 = btc->btc_read_4byte(btc, 0xcb4); + u8tmp = btc->btc_read_1byte(btc, 0x73); + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], (After Ant Setup) 0xcb4 = 0x%x, 0xcbc = 0x%x, 0x73 = 0x%x\n", + u32tmp1, u32tmp2, u8tmp); + BTC_TRACE(trace_buf); + } +} + +static +u8 halbtc8821c2ant_action_algorithm(struct btc_coexist *btc) +{ + struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; + u8 algorithm = BT_8821C_2ANT_COEX_UNDEFINED; + u8 profile_map = 0; + + if (bt_link_info->sco_exist) + profile_map = profile_map | BIT(0); + + if (bt_link_info->hid_exist) + profile_map = profile_map | BIT(1); + + if (bt_link_info->a2dp_exist) + profile_map = profile_map | BIT(2); + + if (bt_link_info->pan_exist) + profile_map = profile_map | BIT(3); + + switch (profile_map) { + case 0: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], No BT link exists!!!\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_UNDEFINED; + break; + case 1: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = SCO only\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_SCO; + break; + case 2: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = HID only\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_HID; + break; + case 3: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = SCO + HID ==> HID\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_HID; + break; + case 4: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = A2DP only\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_A2DP; + break; + case 5: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = SCO + A2DP ==> HID + A2DP\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_HID_A2DP; + break; + case 6: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = HID + A2DP\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_HID_A2DP; + break; + case 7: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = SCO + HID + A2DP ==> HID + A2DP\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_HID_A2DP; + break; + case 8: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = PAN(EDR) only\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_PAN; + break; + case 9: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = SCO + PAN(EDR) ==> HID + PAN(EDR)\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_PAN_HID; + break; + case 10: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = HID + PAN(EDR)\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_PAN_HID; + break; + case 11: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = SCO + HID + PAN(EDR) ==> HID + PAN(EDR)\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_PAN_HID; + break; + case 12: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = A2DP + PAN(EDR)\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_PAN_A2DP; + break; + case 13: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> A2DP + PAN(EDR)\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_PAN_A2DP; + break; + case 14: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = HID + A2DP + PAN(EDR) ==> A2DP + PAN(EDR)\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_PAN_A2DP; + break; + case 15: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR) ==> A2DP + PAN(EDR)\n"); + BTC_TRACE(trace_buf); + algorithm = BT_8821C_2ANT_COEX_PAN_A2DP; + break; + } + + return algorithm; +} + +static void halbtc8821c2ant_action_freerun(struct btc_coexist *btc) +{ + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + halbtc8821c2ant_table(btc, NM_EXCU, 0); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); +} + +static +void halbtc8821c2ant_action_coex_all_off(struct btc_coexist *btc) +{ + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + halbtc8821c2ant_table(btc, NM_EXCU, 0); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); +} + +static +void halbtc8821c2ant_action_bt_whql_test(struct btc_coexist *btc) +{ + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + halbtc8821c2ant_table(btc, NM_EXCU, 0); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); +} + +static +void halbtc8821c2ant_action_bt_inquiry(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; + boolean wifi_connected = FALSE, wifi_busy = FALSE; + + halbtc8821c2ant_set_wl_tx_power(btc, FC_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + if (coex_sta->is_wifi_linkscan_process || + coex_sta->wifi_high_pri_task1 || + coex_sta->wifi_high_pri_task2) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], bt inq/page + wifi hi-pri task\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_table(btc, NM_EXCU, 8); + + if (bt_link_info->bt_link_exist) + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 15); + else if (coex_sta->wifi_high_pri_task1) + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 113); + else if (!coex_sta->bt_create_connection) + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 10); + else + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 13); + } else if (wifi_busy) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], bt inq/page + wifi busy\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_table(btc, NM_EXCU, 8); + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 151); + } else if (wifi_connected) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], bt inq/page + wifi connected\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_table(btc, NM_EXCU, 8); + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 117); + } else { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], bt inq/page + wifi not-connected\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_table(btc, NM_EXCU, 0); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); + } +} + +static +void halbtc8821c2ant_action_bt_relink(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + + if (coex_sta->gl_wifi_busy) + halbtc8821c2ant_table(btc, NM_EXCU, 18); + else + halbtc8821c2ant_table(btc, NM_EXCU, 5); + + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); +} + +static +void halbtc8821c2ant_action_bt_idle(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW; + u8 wifi_rssi_state; + + wifi_rssi_state = + halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2, + 40, 0); + + if (!coex_sta->gl_wifi_busy) { + halbtc8821c2ant_table(btc, NM_EXCU, 8); + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 14); + } else { /* if wl busy */ + if ((coex_sta->bt_ble_scan_type & 0x2) && + coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE) { + halbtc8821c2ant_table(btc, NM_EXCU, 14); + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 12); + } else { + if (BTC_RSSI_HIGH(wifi_rssi_state)) + halbtc8821c2ant_table(btc, NM_EXCU, 8); + else + halbtc8821c2ant_table(btc, NM_EXCU, 3); + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 12); + } + } + + halbtc8821c2ant_set_wl_tx_power(btc, FC_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); +} + +static +void halbtc8821c2ant_action_bt_mr(struct btc_coexist *btc) +{ + struct wifi_link_info_8821c_2ant *wifi_link_info_ext = + &btc->wifi_link_info_8821c_2ant; + + if (!wifi_link_info_ext->is_all_under_5g) { + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8821C_2ANT_PHASE_2G); + + halbtc8821c2ant_table(btc, NM_EXCU, 0); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); + } else { + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8821C_2ANT_PHASE_5G); + + halbtc8821c2ant_table(btc, NM_EXCU, 0); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); + } +} + +static +void halbtc8821c2ant_action_sco(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + if (coex_sta->is_bt_multi_link) { + halbtc8821c2ant_table(btc, NM_EXCU, 8); + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 25); + } else { + if (coex_sta->is_esco_mode) + halbtc8821c2ant_table(btc, NM_EXCU, 1); + else /* 2-Ant free run if SCO mode */ + halbtc8821c2ant_table(btc, NM_EXCU, 0); + + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 8); + } +} + +static +void halbtc8821c2ant_action_hid(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + boolean wifi_busy = FALSE; + + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + if (coex_sta->is_hid_low_pri_tx_overhead) { + halbtc8821c2ant_table(btc, NM_EXCU, 12); + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 108); + } else if (coex_sta->is_hid_rcu) { + halbtc8821c2ant_table(btc, NM_EXCU, 12); + + if (wifi_busy) + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 113); + else + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 111); + } else { + halbtc8821c2ant_table(btc, NM_EXCU, 12); + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 111); + } +} + +static +void halbtc8821c2ant_action_a2dpsink(struct btc_coexist *btc) +{ + boolean ap_enable = FALSE; + + if (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO && + btc->wifi_link_info.bhotspot && + btc->wifi_link_info.bany_client_join_go) + ap_enable = TRUE; + + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + if (ap_enable) { + halbtc8821c2ant_table(btc, NM_EXCU, 0); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); + } else { + halbtc8821c2ant_table(btc, NM_EXCU, 8); + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 104); + } +} + +static +void halbtc8821c2ant_action_a2dp(struct btc_coexist *btc) +{ + static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW; + u8 wifi_rssi_state; + boolean wifi_busy = FALSE; + + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + wifi_rssi_state = + halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2, + 45, 0); + + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + halbtc8821c2ant_table(btc, NM_EXCU, 8); + + if (!wifi_busy) + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 120 | TDMA_4SLOT); + else if (BTC_RSSI_HIGH(wifi_rssi_state)) + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 119 | TDMA_4SLOT); + else + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 101 | TDMA_4SLOT); +} + +static +void halbtc8821c2ant_action_pan(struct btc_coexist *btc) +{ + boolean wifi_busy = FALSE; + + static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW; + u8 wifi_rssi_state; + + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + wifi_rssi_state = + halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2, + 58, 0); + + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + /* for Lenovo CPT_For_WiFi OPP test */ + if (btc->board_info.customer_id == RT_CID_LENOVO_CHINA && + BTC_RSSI_HIGH(wifi_rssi_state) && wifi_busy) { + halbtc8821c2ant_table(btc, NM_EXCU, 8); + + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 103); + } else { + halbtc8821c2ant_table(btc, NM_EXCU, 8); + + if (wifi_busy) + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 103); + else + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 104); + } +} + +static +void halbtc8821c2ant_action_hid_a2dp(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW; + u8 wifi_rssi_state; + u32 slot_type = 0; + + wifi_rssi_state = + halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2, + 45, 0); + + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + /*BLE HID should use 2-slot to avoid HID lag issue (COEX-357)*/ + if (!coex_sta->bt_ble_hid_exist) + slot_type = TDMA_4SLOT; + + halbtc8821c2ant_table(btc, NM_EXCU, 12); + + if (BTC_RSSI_HIGH(wifi_rssi_state)) + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 119 | slot_type); + else + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 109 | slot_type); +} + +static +void halbtc8821c2ant_action_pan_a2dp(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW; + u8 wifi_rssi_state; + boolean wifi_busy = FALSE; + u8 iot_peer = BTC_IOT_PEER_UNKNOWN; + + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + btc->btc_get(btc, BTC_GET_U1_IOT_PEER, &iot_peer); + + if (!wifi_busy) + wifi_busy = coex_sta->gl_wifi_busy; + + wifi_rssi_state = + halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2, + 42, 0); + + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + + /* for Lenovo coex test case */ + if (btc->board_info.customer_id == RT_CID_LENOVO_CHINA && + coex_sta->scan_ap_num <= 10 && + iot_peer == BTC_IOT_PEER_ATHEROS) { + /* for CPT_for_WiFi */ + if (BTC_RSSI_LOW(wifi_rssi_state)) { + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 20); + if (wifi_busy) { + halbtc8821c2ant_table(btc, NM_EXCU, 7); + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 110); + } else { + halbtc8821c2ant_table(btc, NM_EXCU, 7); + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 107); + } + } else { /* for CPT_for_BT */ + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + halbtc8821c2ant_table(btc, NM_EXCU, 8); + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 116); + } + } else { + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + halbtc8821c2ant_table(btc, NM_EXCU, 8); + + if (wifi_busy) + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 107); + else + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 106); + } +} + +static +void halbtc8821c2ant_action_pan_hid(struct btc_coexist *btc) +{ + boolean wifi_busy = FALSE; + + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + halbtc8821c2ant_table(btc, NM_EXCU, 8); + + if (wifi_busy) + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 103); + else + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 104); +} + +static +void halbtc8821c2ant_action_hid_a2dp_pan(struct btc_coexist *btc) +{ + boolean wifi_busy = FALSE; + + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + halbtc8821c2ant_table(btc, NM_EXCU, 12); + + if (wifi_busy) + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 107); + else + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 106); +} + +static +void halbtc8821c2ant_action_wifi_under5g(struct btc_coexist *btc) +{ + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8821C_2ANT_PHASE_5G); + /* fw all off */ + halbtc8821c2ant_table(btc, NM_EXCU, 0); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); +} + +static +void halbtc8821c2ant_action_wifi_native_lps(struct btc_coexist *btc) +{ + halbtc8821c2ant_table(btc, NM_EXCU, 4); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); +} + +static +void halbtc8821c2ant_action_wifi_linkscan(struct btc_coexist *btc) +{ + struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; + + halbtc8821c2ant_set_wl_tx_power(btc, FC_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + halbtc8821c2ant_table(btc, NM_EXCU, 8); + + if (bt_link_info->pan_exist) + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 22); + else if (bt_link_info->a2dp_exist) + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 16); + else + halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 21); +} + +static +void halbtc8821c2ant_action_wifi_not_connected(struct btc_coexist *btc) +{ + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + halbtc8821c2ant_table(btc, NM_EXCU, 0); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); +} + +static +void halbtc8821c2ant_action_wifi_connected(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + + coex_dm->cur_algorithm = halbtc8821c2ant_action_algorithm(btc); + + if (halbtc8821c2ant_freerun_check(btc)) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Action 2-Ant, Frerun().\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_freerun(btc); + return; + } + + switch (coex_dm->cur_algorithm) { + case BT_8821C_2ANT_COEX_SCO: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Action 2-Ant, algorithm = SCO.\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_sco(btc); + break; + case BT_8821C_2ANT_COEX_HID: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Action 2-Ant, algorithm = HID.\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_hid(btc); + break; + case BT_8821C_2ANT_COEX_A2DP: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Action 2-Ant, algorithm = A2DP.\n"); + BTC_TRACE(trace_buf); + + /* for A2DP + OPP test but BTinfo is + * A2DP only in Lenovo test case + */ + if (coex_sta->is_bt_multi_link && coex_sta->hid_pair_cnt == 0) + halbtc8821c2ant_action_pan_a2dp(btc); + else if (coex_sta->is_bt_a2dp_sink) + halbtc8821c2ant_action_a2dpsink(btc); + else + halbtc8821c2ant_action_a2dp(btc); + break; + case BT_8821C_2ANT_COEX_PAN: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Action 2-Ant, algorithm = PAN(EDR).\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_pan(btc); + break; + case BT_8821C_2ANT_COEX_PAN_A2DP: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Action 2-Ant, algorithm = PAN+A2DP.\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_pan_a2dp(btc); + break; + case BT_8821C_2ANT_COEX_PAN_HID: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID.\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_pan_hid(btc); + break; + case BT_8821C_2ANT_COEX_HID_A2DP_PAN: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN.\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_hid_a2dp_pan(btc); + break; + case BT_8821C_2ANT_COEX_HID_A2DP: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_hid_a2dp(btc); + break; + default: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_coex_all_off(btc); + break; + } +} + +static +void halbtc8821c2ant_action_wifi_multiport25g(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_BTCQDDR, TRUE); + + if (coex_sta->is_setup_link || coex_sta->bt_relink_downcount != 0) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi_multiport25g(), BT Relink!!\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_table(btc, NM_EXCU, 0); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); + } else if (coex_sta->c2h_bt_inquiry_page) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi_multiport25g(), BT Inq-Page!!\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_table(btc, NM_EXCU, 11); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); + } else { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi_multiport25g(), BT idle or busy!!\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_table(btc, NM_EXCU, 11); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); + } +} + +static +void halbtc8821c2ant_action_wifi_multiport2g(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct btc_concurrent_setting multiport_tdma_para; + u32 traffic_dir; + + btc->btc_get(btc, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &traffic_dir); + + halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8); + halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0); + + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_BTCQDDR, TRUE); + + if (coex_sta->is_setup_link || coex_sta->bt_relink_downcount != 0) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi_multiport2g, BT Relink!!\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_table(btc, NM_EXCU, 0); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); + } else if (coex_sta->c2h_bt_inquiry_page) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi_multiport2g, BT Inq-Page!!\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_table(btc, NM_EXCU, 0); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); + } else if (coex_sta->num_of_profile == 0) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi_multiport2g, BT idle!!\n"); + BTC_TRACE(trace_buf); + + if (btc->chip_interface == BTC_INTF_PCI && + (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO || + btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GC)) + halbtc8821c2ant_table(btc, NM_EXCU, 10); + else + halbtc8821c2ant_table(btc, NM_EXCU, 0); + + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); + } else if (coex_sta->is_wifi_linkscan_process) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi_multiport2g, WL scan!!\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_action_wifi_linkscan(btc); + } else { + switch (btc->wifi_link_info.link_mode) { + case BTC_LINK_ONLY_GO: + case BTC_LINK_ONLY_GC: + if (btc->chip_interface == BTC_INTF_PCI && + coex_sta->a2dp_exist && !coex_sta->is_bt_multi_link) + halbtc8821c2ant_table(btc, NM_EXCU, 10); + else + halbtc8821c2ant_table(btc, NM_EXCU, 0); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); + break; + default: + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi_multiport2g, Other multi-port + BT busy!!\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_table(btc, NM_EXCU, 0); + halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0); + break; + } + } +} + +static +void halbtc8821c2ant_run_coex(struct btc_coexist *btc, u8 reason) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + struct wifi_link_info_8821c_2ant *wifi_link_info_ext = + &btc->wifi_link_info_8821c_2ant; + boolean wifi_connected = FALSE, wifi_32k = FALSE; + boolean scan = FALSE, link = FALSE, roam = FALSE, under_4way = FALSE; + + btc->btc_get(btc, BTC_GET_BL_WIFI_SCAN, &scan); + btc->btc_get(btc, BTC_GET_BL_WIFI_LINK, &link); + btc->btc_get(btc, BTC_GET_BL_WIFI_ROAM, &roam); + btc->btc_get(btc, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under_4way); + btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); + btc->btc_get(btc, BTC_GET_BL_WIFI_LW_PWR_STATE, &wifi_32k); + + if (scan || link || roam || under_4way || + reason == BT_8821C_2ANT_RSN_2GSCANSTART || + reason == BT_8821C_2ANT_RSN_2GSWITCHBAND || + reason == BT_8821C_2ANT_RSN_2GCONSTART || + reason == BT_8821C_2ANT_RSN_2GSPECIALPKT) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], scan = %d, link = %d, roam = %d 4way = %d!!!\n", + scan, link, roam, under_4way); + BTC_TRACE(trace_buf); + coex_sta->is_wifi_linkscan_process = TRUE; + } else { + coex_sta->is_wifi_linkscan_process = FALSE; + } + + /* update wifi_link_info_ext variable */ + halbtc8821c2ant_update_wifi_link_info(btc, reason); + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], RunCoexistMechanism()===> reason = %d\n", + reason); + BTC_TRACE(trace_buf); + + coex_sta->coex_run_reason = reason; + + if (btc->manual_control) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n"); + BTC_TRACE(trace_buf); + return; + } + + if (btc->stop_coex_dm) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n"); + BTC_TRACE(trace_buf); + return; + } + + if (coex_sta->under_ips) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], RunCoexistMechanism(), return for wifi is under IPS !!!\n"); + BTC_TRACE(trace_buf); + return; + } + + if (coex_sta->under_lps && wifi_32k) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], RunCoexistMechanism(), return for wifi is under LPS-32K !!!\n"); + BTC_TRACE(trace_buf); + return; + } + + if (!coex_sta->run_time_state) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], return for run_time_state = FALSE !!!\n"); + BTC_TRACE(trace_buf); + return; + } + + if (coex_sta->freeze_coexrun_by_btinfo && !coex_sta->is_setup_link) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], return for freeze_coexrun_by_btinfo\n"); + BTC_TRACE(trace_buf); + return; + } + + coex_sta->coex_run_cnt++; + + if (coex_sta->msft_mr_exist && wifi_connected) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], RunCoexistMechanism(), microsoft MR!!\n"); + BTC_TRACE(trace_buf); + + coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_BTMR; + halbtc8821c2ant_action_bt_mr(btc); + return; + } + + if (wifi_link_info_ext->is_all_under_5g) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], WiFi is under 5G!!!\n"); + BTC_TRACE(trace_buf); + + coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_5G; + halbtc8821c2ant_action_wifi_under5g(btc); + return; + } + + if (wifi_link_info_ext->is_mcc_25g) { /* not iclude scan action */ + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], WiFi is under mcc dual-band!!!\n"); + BTC_TRACE(trace_buf); + + coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_25GMPORT; + halbtc8821c2ant_action_wifi_multiport25g(btc); + return; + } + + if (wifi_link_info_ext->num_of_active_port > 1 || + (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO && + !btc->wifi_link_info.bhotspot && + btc->wifi_link_info.bany_client_join_go)) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], WiFi is under scc-2g/mcc-2g/p2pGO-only!!!\n"); + BTC_TRACE(trace_buf); + + if (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO) + coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_2GGO; + else + coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_2GMPORT; + halbtc8821c2ant_action_wifi_multiport2g(btc); + return; + } + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], WiFi is single-port 2G!!!\n"); + BTC_TRACE(trace_buf); + + coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_2G1PORT; + + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU, + BT_8821C_2ANT_PHASE_2G); + + /*For Asus airpods 2 + HID glitch issue*/ + if (coex_sta->bt_a2dp_vendor_id == 0x4c && coex_sta->is_bt_multi_link) + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_BTCQDDR, + FALSE); + else + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_BTCQDDR, + TRUE); + + if (coex_sta->bt_disabled) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT is disabled !!!\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_coex_all_off(btc); + return; + } + + if (coex_sta->under_lps && !coex_sta->force_lps_ctrl && + !coex_sta->acl_busy) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], RunCoexistMechanism(), wifi is under LPS !!!\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_wifi_native_lps(btc); + return; + } + + if (coex_sta->bt_whck_test) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT is under WHCK TEST!!!\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_bt_whql_test(btc); + return; + } + + if (coex_sta->is_setup_link || coex_sta->bt_relink_downcount != 0) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT is re-link !!!\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_bt_relink(btc); + return; + } + + if (coex_sta->c2h_bt_inquiry_page) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT is under inquiry/page scan !!\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_bt_inquiry(btc); + return; + } + + if ((coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE || + coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_CON_IDLE) && + wifi_link_info_ext->is_connected) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "############# [BTCoex], BT Is idle\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_bt_idle(btc); + return; + } + + if (coex_sta->is_wifi_linkscan_process) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi is under linkscan process!!\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_action_wifi_linkscan(btc); + return; + } + + if (wifi_connected) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi is under connected!!\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_action_wifi_connected(btc); + } else { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wifi is under not-connected!!\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_action_wifi_not_connected(btc); + } +} + +static void halbtc8821c2ant_init_coex_var(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + + /* Reset Coex variable */ + btc->btc_set(btc, BTC_SET_RESET_COEX_VAR, NULL); + + coex_sta->bt_reg_vendor_ac = 0xffff; + coex_sta->bt_reg_vendor_ae = 0xffff; + + coex_sta->isolation_btween_wb = BT_8821C_2ANT_DEFAULT_ISOLATION; + btc->bt_info.bt_get_fw_ver = 0; +} + +static +void halbtc8821c2ant_init_coex_dm(struct btc_coexist *btc) +{ +} + +static +void halbtc8821c2ant_init_hw_config(struct btc_coexist *btc, boolean wifi_only) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + u8 u8tmp = 0; + u32 vendor; + u32 u32tmp0 = 0, u32tmp1 = 0, u32tmp2 = 0, u32tmp3 = 0; + u8 i; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()!\n", __func__); + BTC_TRACE(trace_buf); + +#if 0 + u32tmp3 = btc->btc_read_4byte(btc, 0xcb4); + u32tmp1 = halbtc8821c2ant_read_indirect_reg(btc, 0x38); + u32tmp2 = halbtc8821c2ant_read_indirect_reg(btc, 0x54); + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], (Before Init HW config) 0xcb4 = 0x%x, 0x38= 0x%x, 0x54= 0x%x\n", + u32tmp3, u32tmp1, u32tmp2); + BTC_TRACE(trace_buf); +#endif + + halbtc8821c2ant_init_coex_var(btc); + + /* 0xf0[15:12] --> kt_ver */ + coex_sta->kt_ver = (btc->btc_read_1byte(btc, 0xf1) & 0xf0) >> 4; + + halbtc8821c2ant_coex_switch_thres(btc, coex_sta->isolation_btween_wb); + /* enable TBTT nterrupt */ + btc->btc_write_1byte_bitmask(btc, 0x550, 0x8, 0x1); + + /* BT report packet sample rate */ + btc->btc_write_1byte(btc, 0x790, 0x5); + + /* Init 0x778 = 0x1 for 2-Ant */ + btc->btc_write_1byte(btc, 0x778, 0x1); + + /* Enable PTA (3-wire function form BT side) */ + btc->btc_write_1byte_bitmask(btc, 0x40, 0x20, 0x1); + btc->btc_write_1byte_bitmask(btc, 0x41, 0x02, 0x1); + + /* Enable PTA (tx/rx signal form WiFi side) */ + btc->btc_write_1byte_bitmask(btc, 0x4c6, 0x30, 0x1); + + /* set GNT_BT=1 for coex table select both */ + btc->btc_write_1byte_bitmask(btc, 0x763, 0x10, 0x1); + + halbtc8821c2ant_enable_gnt_to_gpio(btc, TRUE); + + /* Enable counter statistics */ + /* 0x76e[3] =1, WLAN_Act control by PTA */ + btc->btc_write_1byte(btc, 0x76e, 0x4); + + if (btc->wl_rf_state_off) { + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, + BT_8821C_2ANT_PHASE_WOFF); + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ALL, FALSE); + btc->stop_coex_dm = TRUE; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], %s: RF Off\n", __func__); + BTC_TRACE(trace_buf); + } else if (wifi_only) { + coex_sta->concurrent_rx_mode_on = FALSE; + /* Path config */ + /* Set Antenna Path */ + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, + BT_8821C_2ANT_PHASE_WONLY); + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | + BT_8821C_2ANT_SCBD_ONOFF, + TRUE); + btc->stop_coex_dm = TRUE; + } else { + coex_sta->concurrent_rx_mode_on = TRUE; + /* btc->btc_write_1byte_bitmask(btc, 0x953, 0x2, 0x1); */ + + /* RF 0x1[1] = 0->Set GNT_WL_RF_Rx always = 1 + * for con-current Rx, mask Tx only + */ + btc->btc_set_rf_reg(btc, BTC_RF_A, 0x1, 0x2, 0x0); + + /* Set Antenna Path */ + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, + BT_8821C_2ANT_PHASE_INIT); + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | + BT_8821C_2ANT_SCBD_ONOFF, + TRUE); + btc->stop_coex_dm = FALSE; + } + + halbtc8821c2ant_table(btc, FC_EXCU, 0); + halbtc8821c2ant_tdma(btc, FC_EXCU, FALSE, 0); + + halbtc8821c2ant_query_bt_info(btc); +} + +void ex_halbtc8821c2ant_power_on_setting(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct btc_board_info *board_info = &btc->board_info; + u8 u8tmp = 0x0; + u16 u16tmp = 0x0; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Execute %s !!\n", __func__); + BTC_TRACE(trace_buf); + + btc->stop_coex_dm = TRUE; + btc->wl_rf_state_off = FALSE; + + /* enable BB, REG_SYS_FUNC_EN such that + * we can write BB Register correctly. + */ + u16tmp = btc->btc_read_2byte(btc, 0x2); + btc->btc_write_2byte(btc, 0x2, u16tmp | BIT(0) | BIT(1)); + + /* Local setting bit define + * BIT0: "0" for no antenna inverse; "1" for antenna inverse + * BIT1: "0" for internal switch; "1" for external switch + * BIT2: "0" for one antenna; "1" for two antenna + * NOTE: here default all internal switch and 1-antenna + * ==> BIT1=0 and BIT2=0 + */ + + /* Check efuse 0xc3[6] for Single Antenna Path */ + if (board_info->single_ant_path == 0) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Single Antenna, Antenna at Aux Port\n"); + BTC_TRACE(trace_buf); + + board_info->btdm_ant_pos = BTC_ANTENNA_AT_AUX_PORT; + u8tmp = 7; + } else if (board_info->single_ant_path == 1) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Single Antenna, Antenna at Main Port\n"); + BTC_TRACE(trace_buf); + + board_info->btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT; + u8tmp = 6; + } + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], (Power On) single_ant_path = %d, btdm_ant_pos = %d\n", + board_info->single_ant_path , board_info->btdm_ant_pos); + BTC_TRACE(trace_buf); + + /* Setup RF front end type */ + halbtc8821c2ant_set_rfe_type(btc); + + /* Set Antenna Path to BT side */ + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, + BT_8821C_2ANT_PHASE_POWERON); + + halbtc8821c2ant_table(btc, FC_EXCU, 0); + + /* Save"single antenna position" info in Local register setting + * for FW reading, because FW may not ready at power on + */ + if (btc->chip_interface == BTC_INTF_PCI) + btc->btc_write_local_reg_1byte(btc, 0x3e0, u8tmp); + else if (btc->chip_interface == BTC_INTF_USB) + btc->btc_write_local_reg_1byte(btc, 0xfe08, u8tmp); + else if (btc->chip_interface == BTC_INTF_SDIO) + btc->btc_write_local_reg_1byte(btc, 0x60, u8tmp); + + /* enable GNT_WL/GNT_BT debug signal to GPIO14/15 */ + halbtc8821c2ant_enable_gnt_to_gpio(btc, TRUE); + + if (btc->dbg_mode) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], LTE coex Reg 0x38 (Power-On) = 0x%x\n", + halbtc8821c2ant_read_indirect_reg(btc, 0x38)); + BTC_TRACE(trace_buf); + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], MACReg 0x70/ BBReg 0xcb4 (Power-On) = 0x%x/ 0x%x\n", + btc->btc_read_4byte(btc, 0x70), + btc->btc_read_4byte(btc, 0xcb4)); + BTC_TRACE(trace_buf); + } +} + +void ex_halbtc8821c2ant_pre_load_firmware(struct btc_coexist *btc) +{ + struct btc_board_info *board_info = &btc->board_info; + u8 u8tmp = 0x4; /* Set BIT2 by default since it's 2ant case */ + + /* S0 or S1 setting and Local register setting + *(By the setting fw can get ant number, S0/S1, ... info) + * Local setting bit define + * BIT0: "0" for no antenna inverse; "1" for antenna inverse + * BIT1: "0" for internal switch; "1" for external switch + * BIT2: "0" for one antenna; "1" for two antenna + * NOTE: here default all internal switch + * and 1-antenna ==> BIT1=0 and BIT2=0 + */ + if (btc->chip_interface == BTC_INTF_USB) { + /* fixed at S0 for USB interface */ + u8tmp |= 0x1; /* antenna inverse */ + btc->btc_write_local_reg_1byte(btc, 0xfe08, u8tmp); + } else { + /* for PCIE and SDIO interface, we check efuse 0xc3[6] */ + if (board_info->single_ant_path == 0) { + } else if (board_info->single_ant_path == 1) { + /* set to S0 */ + u8tmp |= 0x1; /* antenna inverse */ + } + + if (btc->chip_interface == BTC_INTF_PCI) + btc->btc_write_local_reg_1byte(btc, 0x3e0, u8tmp); + else if (btc->chip_interface == BTC_INTF_SDIO) + btc->btc_write_local_reg_1byte(btc, 0x60, u8tmp); + } +} + + +void ex_halbtc8821c2ant_init_hw_config(struct btc_coexist *btc, + boolean wifi_only) +{ + halbtc8821c2ant_init_hw_config(btc, wifi_only); +} + +void ex_halbtc8821c2ant_init_coex_dm(struct btc_coexist *btc) +{ + btc->stop_coex_dm = FALSE; + btc->auto_report = TRUE; + btc->dbg_mode = FALSE; + halbtc8821c2ant_init_coex_dm(btc); +} + +void ex_halbtc8821c2ant_display_simple_coex_info(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + struct btc_board_info *board_info = &btc->board_info; + struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; + + u8 *cli_buf = btc->cli_buf; + u32 bt_patch_ver = 0, bt_coex_ver = 0; + static u8 cnt; + u8 * const p = &coex_sta->bt_afh_map[0]; + + if (!coex_sta->bt_disabled && + (coex_sta->bt_coex_supported_version == 0 || + coex_sta->bt_coex_supported_version == 0xffff) && + cnt == 0) { + btc->btc_get(btc, BTC_GET_U4_SUPPORTED_FEATURE, + &coex_sta->bt_coex_supported_feature); + + btc->btc_get(btc, BTC_GET_U4_SUPPORTED_VERSION, + &coex_sta->bt_coex_supported_version); + + coex_sta->bt_reg_vendor_ac = (u16)(btc->btc_get_bt_reg(btc, 3, + 0xac) & + 0xffff); + + coex_sta->bt_reg_vendor_ae = (u16)(btc->btc_get_bt_reg(btc, 3, + 0xae) & + 0xffff); + + btc->btc_get(btc, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); + btc->bt_info.bt_get_fw_ver = bt_patch_ver; + + if (coex_sta->num_of_profile > 0) + btc->btc_get_bt_afh_map_from_bt(btc, 0, p); + } + + if (++cnt >= 3) + cnt = 0; + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n _____[BT Coexist info]____"); + CL_PRINTF(cli_buf); + + if (btc->manual_control) { + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n __[Under Manual Control]_"); + CL_PRINTF(cli_buf); + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n _________________________"); + CL_PRINTF(cli_buf); + } + + if (btc->stop_coex_dm) { + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n ____[Coex is STOPPED]____"); + CL_PRINTF(cli_buf); + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n _________________________"); + CL_PRINTF(cli_buf); + } + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %d/ %d/ %s / 0x%x", + "Ant PG Num/ Mech/ Pos/ RFE", + board_info->pg_ant_num, board_info->btdm_ant_num, + (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT + ? "Main" : "Aux"), + board_info->rfe_type); + CL_PRINTF(cli_buf); + + bt_coex_ver = (coex_sta->bt_coex_supported_version & 0xff); + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %d_%02x/ 0x%02x/ 0x%02x (%s)", + "CoexVer WL/ BT_Desired/ BT_Report", + glcoex_ver_date_8821c_2ant, glcoex_ver_8821c_2ant, + glcoex_ver_btdesired_8821c_2ant, + bt_coex_ver, + (bt_coex_ver == 0xff ? "Unknown" : + (coex_sta->bt_disabled ? "BT-disable" : + (bt_coex_ver >= glcoex_ver_btdesired_8821c_2ant ? + "Match" : "Mis-Match")))); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s ", "BT status", + ((coex_sta->bt_disabled) ? ("disabled") : + ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page") + : ((BT_8821C_2ANT_BSTATUS_NCON_IDLE == + coex_dm->bt_status) ? "non-connected idle" : + ((BT_8821C_2ANT_BSTATUS_CON_IDLE == + coex_dm->bt_status) ? "connected-idle" : "busy"))))); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", + "0x770(Hi-pri rx/tx)", + coex_sta->high_priority_rx, coex_sta->high_priority_tx); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d %s", + "0x774(Lo-pri rx/tx)", + coex_sta->low_priority_rx, coex_sta->low_priority_tx, + (bt_link_info->slave_role ? "(Slave!!)" : " ")); + CL_PRINTF(cli_buf); +} + +void ex_halbtc8821c2ant_display_coex_info(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + struct btc_board_info *board_info = &btc->board_info; + struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; + + u8 *cli_buf = btc->cli_buf; + u8 u8tmp[4], i, ps_tdma_case = 0; + u32 u32tmp[4]; + u16 u16tmp[4]; + u32 fa_ofdm, fa_cck, cca_ofdm, cca_cck; + u32 fw_ver = 0, bt_patch_ver = 0, bt_coex_ver = 0; + static u8 pop_report_in_10s; + u32 phyver = 0, val = 0; + boolean lte_coex_on = FALSE, is_bt_reply = FALSE; + static u8 cnt; + u32 ratio_crc, cnt_ok, cnt_err; + u8 * const p = &coex_sta->bt_afh_map[0]; + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n ============[BT Coexist info 8821C]============"); + CL_PRINTF(cli_buf); + + if (btc->manual_control) { + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n ============[Under Manual Control]============"); + CL_PRINTF(cli_buf); + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n =========================================="); + CL_PRINTF(cli_buf); + } else if (btc->stop_coex_dm) { + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n ============[Coex is STOPPED]============"); + CL_PRINTF(cli_buf); + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n =========================================="); + CL_PRINTF(cli_buf); + } else if (!coex_sta->run_time_state) { + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n ============[Run Time State = False]============"); + CL_PRINTF(cli_buf); + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n =========================================="); + CL_PRINTF(cli_buf); + } else if (coex_sta->freeze_coexrun_by_btinfo) { + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n ============[freeze_coexrun_by_btinfo]============"); + CL_PRINTF(cli_buf); + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n =========================================="); + CL_PRINTF(cli_buf); + } + + if (!coex_sta->bt_disabled && cnt == 0) { + if (coex_sta->bt_coex_supported_version == 0 || + coex_sta->bt_coex_supported_version == 0xffff) { + btc->btc_get(btc, BTC_GET_U4_SUPPORTED_VERSION, + &coex_sta->bt_coex_supported_version); + + if (coex_sta->bt_coex_supported_version > 0 && + coex_sta->bt_coex_supported_version < 0xffff) + is_bt_reply = TRUE; + } else { + is_bt_reply = TRUE; + } + + if (coex_sta->num_of_profile > 0) + btc->btc_get_bt_afh_map_from_bt(btc, 0, p); + } + + if (is_bt_reply) { + if (coex_sta->bt_coex_supported_feature == 0) + btc->btc_get(btc, BTC_GET_U4_SUPPORTED_FEATURE, + &coex_sta->bt_coex_supported_feature); + + if (coex_sta->bt_reg_vendor_ac == 0xffff) { + val = btc->btc_get_bt_reg(btc, 3, 0xac); + coex_sta->bt_reg_vendor_ac = (u16)(val & 0xffff); + } + + if (coex_sta->bt_reg_vendor_ae == 0xffff) { + val = btc->btc_get_bt_reg(btc, 3, 0xae); + coex_sta->bt_reg_vendor_ae = (u16)(val & 0xffff); + } + + if (btc->bt_info.bt_get_fw_ver == 0) { + btc->btc_get(btc, BTC_GET_U4_BT_PATCH_VER, + &bt_patch_ver); + btc->bt_info.bt_get_fw_ver = bt_patch_ver; + } + } + + if (++cnt >= 3) + cnt = 0; + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %d/ %s/ %s / 0x%x", + "Ant PG Num/ Mech/ Pos/ RFE", + board_info->pg_ant_num, + (board_info->btdm_ant_num == 1 ? "Shared" : "Non-Shared"), + (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT + ? "Main" : "Aux"), + board_info->rfe_type); + CL_PRINTF(cli_buf); + + bt_patch_ver = btc->bt_info.bt_get_fw_ver; + btc->btc_get(btc, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + phyver = btc->btc_get_bt_phydm_version(btc); + bt_coex_ver = (coex_sta->bt_coex_supported_version & 0xff); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %d_%02x/ 0x%02x/ 0x%02x (%s)", + "CoexVer WL/ BT_Desired/ BT_Report", + glcoex_ver_date_8821c_2ant, glcoex_ver_8821c_2ant, + glcoex_ver_btdesired_8821c_2ant, + bt_coex_ver, + (bt_coex_ver == 0xff ? "Unknown" : + (coex_sta->bt_disabled ? "BT-disable" : + (bt_coex_ver >= glcoex_ver_btdesired_8821c_2ant ? + "Match" : "Mis-Match")))); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = 0x%x(%s)/ 0x%x/ v%d/ %c", + "W_FW/ B_FW/ Phy/ Kt", fw_ver, + (fw_ver >= glcoex_ver_wldesired_8821c_2ant ? + "Match" : + "Mis-Match"), + bt_patch_ver, phyver, coex_sta->kt_ver + 65); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %02x %02x %02x (RF-Ch = %d)", + "AFH Map to BT", + coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1], + coex_dm->wifi_chnl_info[2], coex_sta->wl_center_channel); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d ", + "Isolation/WL_Thres/BT_Thres", + coex_sta->isolation_btween_wb, + coex_sta->wifi_coex_thres, + coex_sta->bt_coex_thres); + CL_PRINTF(cli_buf); + + /* wifi status */ + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", + "============[Wifi Status]============"); + CL_PRINTF(cli_buf); + btc->btc_disp_dbg_msg(btc, BTC_DBG_DISP_WIFI_STATUS); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", + "============[BT Status]============"); + CL_PRINTF(cli_buf); + + pop_report_in_10s++; + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %s/ %ddBm/ %d/ %d", + "BT status/ rssi/ retryCnt/ popCnt", + ((coex_sta->bt_disabled) ? ("disabled") : (( + coex_sta->c2h_bt_inquiry_page) ? ("inquiry-page") + : ((BT_8821C_2ANT_BSTATUS_NCON_IDLE == + coex_dm->bt_status) ? "non-connected-idle" : + ((coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_CON_IDLE) + ? "connected-idle" : "busy")))), + coex_sta->bt_rssi - 100, coex_sta->bt_retry_cnt, + coex_sta->pop_event_cnt); + CL_PRINTF(cli_buf); + + if (pop_report_in_10s >= 5) { + coex_sta->pop_event_cnt = 0; + pop_report_in_10s = 0; + } + + if (coex_sta->num_of_profile != 0) + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %s%s%s%s%s%s (multilink = %d)", + "Profiles", ((bt_link_info->a2dp_exist) ? + ((coex_sta->is_bt_a2dp_sink) ? "A2DP sink," : + "A2DP,") : ""), + ((bt_link_info->sco_exist) ? "HFP," : ""), + ((bt_link_info->hid_exist) ? + ((coex_sta->is_hid_rcu) ? "HID(RCU)" : + ((coex_sta->hid_busy_num >= 2) ? "HID(4/18)," : + (coex_sta->bt_ble_hid_exist ? "HID(BLE)" : + "HID(2/18),"))) : ""), ((bt_link_info->pan_exist) ? + ((coex_sta->is_bt_opp_exist) ? "OPP," : "PAN,") : + ""), ((coex_sta->voice_over_HOGP) ? "Voice," : ""), + ((coex_sta->msft_mr_exist) ? "MR" : ""), + coex_sta->is_bt_multi_link); + else + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %s", "Profiles", + (coex_sta->msft_mr_exist) ? "MR" : "None"); + + CL_PRINTF(cli_buf); + + if (bt_link_info->a2dp_exist) { + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %s/ %d/ 0x%x/ 0x%x/ %d", + "CQDDR/Bitpool/V_ID/D_name/Flush", + ((coex_sta->is_A2DP_3M) ? "On" : "Off"), + coex_sta->a2dp_bit_pool, + coex_sta->bt_a2dp_vendor_id, + coex_sta->bt_a2dp_device_name, + coex_sta->bt_a2dp_flush_time); + CL_PRINTF(cli_buf); + } + + if (bt_link_info->hid_exist) { + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", + "HID PairNum", + coex_sta->hid_pair_cnt); + CL_PRINTF(cli_buf); + } + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %d/ %s/ 0x%x", + "Role/RoleSwCnt/IgnWlact/Feature", + ((bt_link_info->slave_role) ? "Slave" : "Master"), + coex_sta->cnt_role_switch, + ((coex_dm->cur_ignore_wlan_act) ? "Yes" : "No"), + coex_sta->bt_coex_supported_feature); + CL_PRINTF(cli_buf); + + if (coex_sta->is_ble_scan_en) { + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", + "BLEScan Type/TV/Init/Ble", + coex_sta->bt_ble_scan_type, + (coex_sta->bt_ble_scan_type & 0x1 ? + coex_sta->bt_ble_scan_para[0] : 0x0), + (coex_sta->bt_ble_scan_type & 0x2 ? + coex_sta->bt_ble_scan_para[1] : 0x0), + (coex_sta->bt_ble_scan_type & 0x4 ? + coex_sta->bt_ble_scan_para[2] : 0x0)); + CL_PRINTF(cli_buf); + } + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %d/ %d/ %d/ %d/ %d %s", + "ReInit/ReLink/IgnWlact/Page/NameReq", coex_sta->cnt_reinit, + coex_sta->cnt_setup_link, coex_sta->cnt_ign_wlan_act, + coex_sta->cnt_page, coex_sta->cnt_remote_name_req, + (coex_sta->is_setup_link ? "(Relink!!)" : "")); + CL_PRINTF(cli_buf); + + halbtc8821c2ant_read_scbd(btc, &u16tmp[0]); + + if (coex_sta->bt_reg_vendor_ae == 0xffff || + coex_sta->bt_reg_vendor_ac == 0xffff) + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = x/ x/ 0x%04x", + "0xae[4]/0xac[1:0]/ScBd(B->W)", u16tmp[0]); + else + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = 0x%x/ 0x%x/ 0x%04x", + "0xae[4]/0xac[1:0]/ScBd(B->W)", + (int)((coex_sta->bt_reg_vendor_ae & BIT(4)) >> 4), + coex_sta->bt_reg_vendor_ac & 0x3, u16tmp[0]); + CL_PRINTF(cli_buf); + + if (coex_sta->num_of_profile > 0) { + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x", + "AFH MAP", + coex_sta->bt_afh_map[0], + coex_sta->bt_afh_map[1], + coex_sta->bt_afh_map[2], + coex_sta->bt_afh_map[3], + coex_sta->bt_afh_map[4], + coex_sta->bt_afh_map[5], + coex_sta->bt_afh_map[6], + coex_sta->bt_afh_map[7], + coex_sta->bt_afh_map[8], + coex_sta->bt_afh_map[9]); + CL_PRINTF(cli_buf); + } + + for (i = 0; i < BT_8821C_2ANT_INFO_SRC_MAX; i++) { + if (coex_sta->bt_info_c2h_cnt[i]) { + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x (%d)", + glbt_info_src_8821c_2ant[i], + coex_sta->bt_info_c2h[i][0], + coex_sta->bt_info_c2h[i][1], + coex_sta->bt_info_c2h[i][2], + coex_sta->bt_info_c2h[i][3], + coex_sta->bt_info_c2h[i][4], + coex_sta->bt_info_c2h[i][5], + coex_sta->bt_info_c2h[i][6], + coex_sta->bt_info_c2h_cnt[i]); + CL_PRINTF(cli_buf); + } + } + + /* Sw mechanism */ + if (btc->manual_control) + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", + "============[mechanism] (before Manual)============"); + else + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", + "============[Mechanism]============"); + + CL_PRINTF(cli_buf); + + ps_tdma_case = coex_dm->cur_ps_tdma; + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %02x %02x %02x %02x %02x (case-%d, %s, Timer:%d)", + "TDMA", + coex_dm->ps_tdma_para[0], coex_dm->ps_tdma_para[1], + coex_dm->ps_tdma_para[2], coex_dm->ps_tdma_para[3], + coex_dm->ps_tdma_para[4], ps_tdma_case, + (coex_dm->cur_ps_tdma_on ? "On" : "Off"), + coex_sta->tdma_timer_base); + CL_PRINTF(cli_buf); + + switch (coex_sta->wl_coex_mode) { + case BT_8821C_2ANT_WLINK_2G1PORT: + default: + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %s", "Coex_Mode", "2G-SP"); + break; + case BT_8821C_2ANT_WLINK_2GMPORT: + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %s", "Coex_Mode", "2G-MP"); + break; + case BT_8821C_2ANT_WLINK_25GMPORT: + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %s", "Coex_Mode", "25G-MP"); + break; + case BT_8821C_2ANT_WLINK_5G: + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %s", "Coex_Mode", "5G"); + break; + case BT_8821C_2ANT_WLINK_2GGO: + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %s", "Coex_Mode", "2G-P2P"); + break; + case BT_8821C_2ANT_WLINK_BTMR: + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %s", "Coex_Mode", "BT-MR"); + break; + } + CL_PRINTF(cli_buf); + + u32tmp[0] = btc->btc_read_4byte(btc, 0x6c0); + u32tmp[1] = btc->btc_read_4byte(btc, 0x6c4); + u32tmp[2] = btc->btc_read_4byte(btc, 0x6c8); + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %d/ 0x%x/ 0x%x/ 0x%x", + "Table/0x6c0/0x6c4/0x6c8", + coex_sta->coex_table_type, u32tmp[0], u32tmp[1], u32tmp[2]); + CL_PRINTF(cli_buf); + + u8tmp[0] = btc->btc_read_1byte(btc, 0x778); + u32tmp[0] = btc->btc_read_4byte(btc, 0x6cc); + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = 0x%x/ 0x%x/ 0x%04x/ %d/ %d", + "0x778/0x6cc/ScBd(W->B)/RunCnt/Rsn", u8tmp[0], u32tmp[0], + coex_sta->score_board_WB, coex_sta->coex_run_cnt, + coex_sta->coex_run_reason); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s/ %d/ %d", + "AntDiv/BtCtrlLPS/LPRA/PsFail/g_busy", + ((board_info->ant_div_cfg) ? + ((coex_dm->cur_antdiv_type) ? "On(Hw)" : "On(Sw)") : "Off"), + ((coex_sta->force_lps_ctrl) ? "On" : "Off"), + ((coex_dm->cur_low_penalty_ra) ? "On" : "Off"), + coex_sta->cnt_set_ps_state_fail, + coex_sta->gl_wifi_busy); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", + "WL_Pwr/ BT_Pwr", coex_dm->cur_wl_pwr_lvl, + coex_dm->cur_bt_pwr_lvl); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d/ %d", + "Null All/Retry/Ack/BT_Empty/BT_Late", + coex_sta->wl_fw_dbg_info[1], + coex_sta->wl_fw_dbg_info[2], + coex_sta->wl_fw_dbg_info[3], + coex_sta->wl_fw_dbg_info[4], + coex_sta->wl_fw_dbg_info[5]); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %s/ %d", + "cnt TDMA_Togg/LK5ms/LK5ms_off/fw", + coex_sta->wl_fw_dbg_info[6], coex_sta->wl_fw_dbg_info[7], + ((coex_sta->is_no_wl_5ms_extend) ? "Yes" : "No"), + coex_sta->cnt_wl_fw_notify); + CL_PRINTF(cli_buf); + + u32tmp[0] = halbtc8821c2ant_read_indirect_reg(btc, 0x38); + lte_coex_on = ((u32tmp[0] & BIT(7)) >> 7) ? TRUE : FALSE; + + if (lte_coex_on) { + u32tmp[0] = halbtc8821c2ant_read_indirect_reg(btc, 0xa0); + u32tmp[1] = halbtc8821c2ant_read_indirect_reg(btc, 0xa4); + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", + "LTE Coex Table W_L/B_L", u32tmp[0] & 0xffff, + u32tmp[1] & 0xffff); + CL_PRINTF(cli_buf); + + u32tmp[0] = halbtc8821c2ant_read_indirect_reg(btc, 0xa8); + u32tmp[1] = halbtc8821c2ant_read_indirect_reg(btc, 0xac); + u32tmp[2] = halbtc8821c2ant_read_indirect_reg(btc, 0xb0); + u32tmp[3] = halbtc8821c2ant_read_indirect_reg(btc, 0xb4); + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", + "LTE Break Table W_L/B_L/L_W/L_B", + u32tmp[0] & 0xffff, u32tmp[1] & 0xffff, + u32tmp[2] & 0xffff, u32tmp[3] & 0xffff); + CL_PRINTF(cli_buf); + } + + /* Hw setting */ + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", + "============[Hw setting]============"); + CL_PRINTF(cli_buf); + + u32tmp[0] = halbtc8821c2ant_read_indirect_reg(btc, 0x38); + u32tmp[1] = halbtc8821c2ant_read_indirect_reg(btc, 0x54); + u8tmp[0] = btc->btc_read_1byte(btc, 0x73); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s", + "LTE Coex/Path Owner", + ((lte_coex_on) ? "On" : "Off") , + ((u8tmp[0] & BIT(2)) ? "WL" : "BT")); + CL_PRINTF(cli_buf); + + if (lte_coex_on) { + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %d/ %d/ %d/ %d", + "LTE 3Wire/OPMode/UART/UARTMode", + (int)((u32tmp[0] & BIT(6)) >> 6), + (int)((u32tmp[0] & (BIT(5) | BIT(4))) >> 4), + (int)((u32tmp[0] & BIT(3)) >> 3), + (int)(u32tmp[0] & (BIT(2) | BIT(1) | BIT(0)))); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", + "LTE_Busy/UART_Busy", + (int)((u32tmp[1] & BIT(1)) >> 1), + (int)(u32tmp[1] & BIT(0))); + CL_PRINTF(cli_buf); + } + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %s (BB:%s)/ %s (BB:%s)/ %s (gnt_err = %d)", + "GNT_WL_Ctrl/GNT_BT_Ctrl/Dbg", + ((u32tmp[0] & BIT(12)) ? "SW" : "HW"), + ((u32tmp[0] & BIT(8)) ? "SW" : "HW"), + ((u32tmp[0] & BIT(14)) ? "SW" : "HW"), + ((u32tmp[0] & BIT(10)) ? "SW" : "HW"), + ((u8tmp[0] & BIT(3)) ? "On" : "Off"), + coex_sta->gnt_error_cnt); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ 0x%x", + "GNT_WL/GNT_BT/ RF_0x1", + (int)((u32tmp[1] & BIT(2)) >> 2), + (int)((u32tmp[1] & BIT(3)) >> 3), + btc->btc_get_rf_reg(btc, BTC_RF_A, 0x1, 0xfffff)); + CL_PRINTF(cli_buf); + + u32tmp[0] = btc->btc_read_4byte(btc, 0xcb0); + u32tmp[1] = btc->btc_read_4byte(btc, 0xcb4); + u8tmp[0] = btc->btc_read_1byte(btc, 0xcba); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = 0x%04x/ 0x%04x/ 0x%02x %s", + "0xcb0/0xcb4/0xcb8[23:16]", + u32tmp[0], u32tmp[1], u8tmp[0], + ((u8tmp[0] & 0x1) == 0x1 ? "(BTG)" : "(WL_A+G)")); + CL_PRINTF(cli_buf); + + u32tmp[0] = btc->btc_read_4byte(btc, 0x430); + u32tmp[1] = btc->btc_read_4byte(btc, 0x434); + u16tmp[0] = btc->btc_read_2byte(btc, 0x42a); + u8tmp[0] = btc->btc_read_1byte(btc, 0x426); + u8tmp[1] = btc->btc_read_1byte(btc, 0x45e); + u8tmp[2] = btc->btc_read_1byte(btc, 0x455); + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x", + "430/434/42a/426/45e[3]/455", + u32tmp[0], u32tmp[1], u16tmp[0], u8tmp[0], + (int)((u8tmp[1] & BIT(3)) >> 3), u8tmp[2]); + CL_PRINTF(cli_buf); + + u32tmp[0] = btc->btc_read_4byte(btc, 0x4c); + u8tmp[2] = btc->btc_read_1byte(btc, 0x64); + u8tmp[0] = btc->btc_read_1byte(btc, 0x4c6); + u8tmp[1] = btc->btc_read_1byte(btc, 0x40); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", + "4c[24:23]/64[0]/4c6[4]/40[5]", + (int)(u32tmp[0] & (BIT(24) | BIT(23))) >> 23, + u8tmp[2] & 0x1, (int)((u8tmp[0] & BIT(4)) >> 4), + (int)((u8tmp[1] & BIT(5)) >> 5)); + CL_PRINTF(cli_buf); + + u32tmp[0] = btc->btc_read_4byte(btc, 0x550); + u8tmp[0] = btc->btc_read_1byte(btc, 0x522); + u8tmp[1] = btc->btc_read_1byte(btc, 0x953); + u8tmp[2] = btc->btc_read_1byte(btc, 0xc50); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = 0x%x/ 0x%x/ %s/ 0x%x", + "0x550/0x522/4-RxAGC/0xc50", u32tmp[0], u8tmp[0], + (u8tmp[1] & 0x2) ? "On" : "Off", u8tmp[2]); + CL_PRINTF(cli_buf); + + fa_ofdm = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_FA_OFDM); + fa_cck = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_FA_CCK); + cca_ofdm = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CCA_OFDM); + cca_cck = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CCA_CCK); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", + "CCK-CCA/CCK-FA/OFDM-CCA/OFDM-FA", + cca_cck, fa_cck, cca_ofdm, fa_ofdm); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d", + "CRC_OK CCK/11g/11n/11ac", + coex_sta->crc_ok_cck, coex_sta->crc_ok_11g, + coex_sta->crc_ok_11n, coex_sta->crc_ok_11n_vht); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d", + "CRC_Err CCK/11g/11n/11ac", + coex_sta->crc_err_cck, coex_sta->crc_err_11g, + coex_sta->crc_err_11n, coex_sta->crc_err_11n_vht); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, + "\r\n %-35s = %d/ %d/ %s-%d/ %d (Tx macid: %d)", + "Rate RxD/RxRTS/TxD/TxRetry_ratio", + coex_sta->wl_rx_rate, coex_sta->wl_rts_rx_rate, + (coex_sta->wl_tx_rate & 0x80 ? "SGI" : "LGI"), + coex_sta->wl_tx_rate & 0x7f, + coex_sta->wl_tx_retry_ratio, + coex_sta->wl_tx_macid); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s/ %s/ %d", + "HiPr/ Locking/ warn/ Locked/ Noisy", + (coex_sta->wifi_high_pri_task1 ? "Yes" : "No"), + (coex_sta->cck_lock ? "Yes" : "No"), + (coex_sta->cck_lock_warn ? "Yes" : "No"), + (coex_sta->cck_lock_ever ? "Yes" : "No"), + coex_sta->wl_noisy_level); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", + "0x770(Hi-pri rx/tx)", + coex_sta->high_priority_rx, coex_sta->high_priority_tx); + CL_PRINTF(cli_buf); + + CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d %s", + "0x774(Lo-pri rx/tx)", + coex_sta->low_priority_rx, coex_sta->low_priority_tx, + (bt_link_info->slave_role ? "(Slave!!)" : " ")); + CL_PRINTF(cli_buf); + + btc->btc_disp_dbg_msg(btc, BTC_DBG_DISP_COEX_STATISTICS); +} + +void ex_halbtc8821c2ant_ips_notify(struct btc_coexist *btc, u8 type) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + + if (btc->manual_control || btc->stop_coex_dm) + return; + + if (type == BTC_IPS_ENTER) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], IPS ENTER notify\n"); + BTC_TRACE(trace_buf); + coex_sta->under_ips = TRUE; + coex_sta->under_lps = FALSE; + + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | + BT_8821C_2ANT_SCBD_ONOFF | + BT_8821C_2ANT_SCBD_SCAN | + BT_8821C_2ANT_SCBD_UNDERTEST, + FALSE); + + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, + BT_8821C_2ANT_PHASE_WOFF); + + halbtc8821c2ant_action_coex_all_off(btc); + } else if (type == BTC_IPS_LEAVE) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], IPS LEAVE notify\n"); + BTC_TRACE(trace_buf); + coex_sta->under_ips = FALSE; + + halbtc8821c2ant_init_hw_config(btc, FALSE); + halbtc8821c2ant_init_coex_dm(btc); + halbtc8821c2ant_query_bt_info(btc); + } +} + +void ex_halbtc8821c2ant_lps_notify(struct btc_coexist *btc, u8 type) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + + if (btc->manual_control || btc->stop_coex_dm) + return; + + if (type == BTC_LPS_ENABLE) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], LPS ENABLE notify\n"); + BTC_TRACE(trace_buf); + coex_sta->under_lps = TRUE; + coex_sta->under_ips = FALSE; + + if (coex_sta->force_lps_ctrl == TRUE) { /* LPS No-32K */ + /* Write WL "Active" in Score-board for PS-TDMA */ + halbtc8821c2ant_write_scbd(btc, + BT_8821C_2ANT_SCBD_ACTIVE, + TRUE); + + } else { /* LPS-32K, need check if this h2c 0x71 can work?? (2015/08/28) */ + /* Write WL "Non-Active" in Score-board for Native-PS */ + halbtc8821c2ant_write_scbd(btc, + BT_8821C_2ANT_SCBD_ACTIVE, + FALSE); + + halbtc8821c2ant_action_wifi_native_lps(btc); + } + + } else if (type == BTC_LPS_DISABLE) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], LPS DISABLE notify\n"); + BTC_TRACE(trace_buf); + coex_sta->under_lps = FALSE; + + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE, + TRUE); + + if (!coex_sta->force_lps_ctrl) { + halbtc8821c2ant_query_bt_info(btc); + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_LPS); + } + } +} + +void ex_halbtc8821c2ant_scan_notify(struct btc_coexist *btc, u8 type) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + boolean wifi_connected = FALSE; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], SCAN notify()\n"); + BTC_TRACE(trace_buf); + + if (btc->manual_control || btc->stop_coex_dm) + return; + + btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); + + if (wifi_connected) + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], ********** WL connected before SCAN\n"); + else + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], ********** WL is not connected before SCAN\n"); + + BTC_TRACE(trace_buf); + + /* this can't be removed for RF off_on event, + * r BT would dis-connect + */ + if (type != BTC_SCAN_FINISH) { + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | + BT_8821C_2ANT_SCBD_SCAN | + BT_8821C_2ANT_SCBD_ONOFF, TRUE); + } + + if (type == BTC_SCAN_START_5G) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], SCAN START notify (5G)\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, + FC_EXCU, BT_8821C_2ANT_PHASE_5G); + + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_5GSCANSTART); + } else if (type == BTC_SCAN_START_2G || type == BTC_SCAN_START) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], SCAN START notify (2G)\n"); + BTC_TRACE(trace_buf); + + if (!wifi_connected) + coex_sta->wifi_high_pri_task2 = TRUE; + + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, + BT_8821C_2ANT_PHASE_2G); + + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GSCANSTART); + } else if (type == BTC_SCAN_FINISH) { + btc->btc_get(btc, BTC_GET_U1_AP_NUM, &coex_sta->scan_ap_num); + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], SCAN FINISH notify (Scan-AP = %d)\n", + coex_sta->scan_ap_num); + BTC_TRACE(trace_buf); + + coex_sta->wifi_high_pri_task2 = FALSE; + + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_SCANFINISH); + } +} + +void ex_halbtc8821c2ant_switchband_notify(struct btc_coexist *btc, u8 type) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + + if (btc->manual_control || btc->stop_coex_dm) + return; + + coex_sta->switch_band_notify_to = type; + + if (type == BTC_SWITCH_TO_5G) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], switchband_notify --- switch to 5G\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_5GSWITCHBAND); + } else if (type == BTC_SWITCH_TO_24G_NOFORSCAN) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], switchband_notify --- BTC_SWITCH_TO_2G (no for scan)\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GSWITCHBAND); + } else { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], switchband_notify --- switch to 2G\n"); + BTC_TRACE(trace_buf); + + ex_halbtc8821c2ant_scan_notify(btc, BTC_SCAN_START_2G); + } + + coex_sta->switch_band_notify_to = BTC_NOT_SWITCH; +} + +void ex_halbtc8821c2ant_connect_notify(struct btc_coexist *btc, + u8 type) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + + if (btc->manual_control || btc->stop_coex_dm) + return; + + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | + BT_8821C_2ANT_SCBD_SCAN | + BT_8821C_2ANT_SCBD_ONOFF, TRUE); + + if (type == BTC_ASSOCIATE_5G_START || + type == BTC_ASSOCIATE_5G_FINISH) { + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, + BT_8821C_2ANT_PHASE_5G); + + if (type == BTC_ASSOCIATE_5G_START) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], CONNECT START notify (5G)\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_run_coex(btc, + BT_8821C_2ANT_RSN_5GCONSTART); + } else { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], CONNECT FINISH notify (5G)\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_run_coex(btc, + BT_8821C_2ANT_RSN_5GCONFINISH); + } + } else if (type == BTC_ASSOCIATE_START) { + coex_sta->wifi_high_pri_task1 = TRUE; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], CONNECT START notify (2G)\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, + BT_8821C_2ANT_PHASE_2G); + + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GCONSTART); + + /* To keep TDMA case during connect process, + to avoid changed by Btinfo and runcoexmechanism */ + coex_sta->freeze_coexrun_by_btinfo = TRUE; + coex_dm->arp_cnt = 0; + } else if (type == BTC_ASSOCIATE_FINISH) { + coex_sta->wifi_high_pri_task1 = FALSE; + coex_sta->freeze_coexrun_by_btinfo = FALSE; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], CONNECT FINISH notify (2G)\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GCONFINISH); + } +} + +void ex_halbtc8821c2ant_media_status_notify(struct btc_coexist *btc, u8 type) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + boolean wifi_under_b_mode = FALSE; + u8 h2c_parameter[2] = {0}; + + if (btc->manual_control || btc->stop_coex_dm) + return; + + if (type == BTC_MEDIA_CONNECT || type == BTC_MEDIA_CONNECT_5G) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], MEDIA connect notify\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | + BT_8821C_2ANT_SCBD_ONOFF, TRUE); + + if (type == BTC_MEDIA_CONNECT_5G) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], WiFi is under 5G!!!\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, + FC_EXCU, + BT_8821C_2ANT_PHASE_5G); + + halbtc8821c2ant_run_coex(btc, + BT_8821C_2ANT_RSN_5GMEDIA); + } else { + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, + FC_EXCU, + BT_8821C_2ANT_PHASE_2G); + + btc->btc_get(btc, BTC_GET_BL_WIFI_UNDER_B_MODE, + &wifi_under_b_mode); + + /* Set CCK Tx/Rx high Pri except 11b mode */ + if (wifi_under_b_mode) + btc->btc_write_1byte_bitmask(btc, 0x6cf, BIT(4), + 0x0); + else + btc->btc_write_1byte_bitmask(btc, 0x6cf, BIT(4), + 0x1); + + /*Leak-AP protection will reopen when connecting AP*/ + h2c_parameter[0] = 0xc; + h2c_parameter[1] = 0x0; + btc->btc_fill_h2c(btc, 0x69, 2, h2c_parameter); + coex_sta->is_no_wl_5ms_extend = FALSE; + + halbtc8821c2ant_run_coex(btc, + BT_8821C_2ANT_RSN_2GMEDIA); + } + } else { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], MEDIA disconnect notify\n"); + BTC_TRACE(trace_buf); + + btc->btc_write_1byte_bitmask(btc, 0x6cf, BIT(4), 0x0); + + coex_sta->cck_lock_ever = FALSE; + coex_sta->cck_lock_warn = FALSE; + coex_sta->cck_lock = FALSE; + + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_MEDIADISCON); + } + btc->btc_get(btc, BTC_GET_U1_IOT_PEER, &coex_sta->wl_iot_peer); + halbtc8821c2ant_update_wifi_ch_info(btc, type); +} + +void ex_halbtc8821c2ant_specific_packet_notify(struct btc_coexist *btc, u8 type) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant; + boolean under_4way = FALSE; + + if (btc->manual_control || btc->stop_coex_dm) + return; + + if (type & BTC_5G_BAND) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], 5g special packet notify\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_5GSPECIALPKT); + return; + } + + btc->btc_get(btc, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under_4way); + + if (under_4way) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], specific Packet ---- under_4way!!\n"); + BTC_TRACE(trace_buf); + + coex_sta->wifi_high_pri_task1 = TRUE; + coex_sta->specific_pkt_period_cnt = 2; + } else if (type == BTC_PACKET_ARP) { + coex_dm->arp_cnt++; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], specific Packet ARP notify -cnt = %d\n", + coex_dm->arp_cnt); + BTC_TRACE(trace_buf); + } else { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], specific Packet DHCP or EAPOL notify [Type = %d]\n", + type); + BTC_TRACE(trace_buf); + + coex_sta->wifi_high_pri_task1 = TRUE; + coex_sta->specific_pkt_period_cnt = 2; + } + + if (coex_sta->wifi_high_pri_task1) { + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_SCAN, TRUE); + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GSPECIALPKT); + } +} + +void ex_halbtc8821c2ant_bt_info_notify(struct btc_coexist *btc, u8 *tmp_buf, + u8 length) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct btc_bt_link_info *bt_link_info = &btc->bt_link_info; + u8 i, rsp_source = 0; + boolean wifi_connected = FALSE; + boolean wifi_busy = FALSE; + static boolean is_scoreboard_scan; + const u16 type_is_scan = BT_8821C_2ANT_SCBD_SCAN; + u8 type; + + rsp_source = tmp_buf[0] & 0xf; + if (rsp_source >= BT_8821C_2ANT_INFO_SRC_MAX) + rsp_source = BT_8821C_2ANT_INFO_SRC_WIFI_FW; + coex_sta->bt_info_c2h_cnt[rsp_source]++; + + if (rsp_source == BT_8821C_2ANT_INFO_SRC_BT_RSP || + rsp_source == BT_8821C_2ANT_INFO_SRC_BT_ACT) { + if (coex_sta->bt_disabled) { + coex_sta->bt_disabled = FALSE; + coex_sta->is_bt_reenable = TRUE; + coex_sta->cnt_bt_reenable = 15; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT enable detected by bt_info\n"); + BTC_TRACE(trace_buf); + } + } + + if (rsp_source == BT_8821C_2ANT_INFO_SRC_WIFI_FW) { +#if 0 + halbtc8821c2ant_update_bt_link_info(btc); + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_BTINFO); +#endif + return; + } + + if (length != 7) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Bt_info length = %d invalid!!\n", + length); + BTC_TRACE(trace_buf); + return; + } + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Bt_info[%d], len=%d, data=[%02x %02x %02x %02x %02x %02x]\n", + tmp_buf[0], length, tmp_buf[1], tmp_buf[2], tmp_buf[3], + tmp_buf[4], tmp_buf[5], tmp_buf[6]); + BTC_TRACE(trace_buf); + + for (i = 0; i < 7; i++) + coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i]; + + if (coex_sta->bt_info_c2h[rsp_source][1] == coex_sta->bt_info_lb2 && + coex_sta->bt_info_c2h[rsp_source][2] == coex_sta->bt_info_lb3 && + coex_sta->bt_info_c2h[rsp_source][3] == coex_sta->bt_info_hb0 && + coex_sta->bt_info_c2h[rsp_source][4] == coex_sta->bt_info_hb1 && + coex_sta->bt_info_c2h[rsp_source][5] == coex_sta->bt_info_hb2 && + coex_sta->bt_info_c2h[rsp_source][6] == coex_sta->bt_info_hb3) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Return because Btinfo duplicate!!\n"); + BTC_TRACE(trace_buf); + return; + } + + coex_sta->bt_info_lb2 = coex_sta->bt_info_c2h[rsp_source][1]; + coex_sta->bt_info_lb3 = coex_sta->bt_info_c2h[rsp_source][2]; + coex_sta->bt_info_hb0 = coex_sta->bt_info_c2h[rsp_source][3]; + coex_sta->bt_info_hb1 = coex_sta->bt_info_c2h[rsp_source][4]; + coex_sta->bt_info_hb2 = coex_sta->bt_info_c2h[rsp_source][5]; + coex_sta->bt_info_hb3 = coex_sta->bt_info_c2h[rsp_source][6]; + + /* if 0xff, it means BT is under WHCK test */ + coex_sta->bt_whck_test = + ((coex_sta->bt_info_lb2 == 0xff) ? TRUE : FALSE); + + coex_sta->bt_create_connection = + ((coex_sta->bt_info_lb3 & BIT(7)) ? TRUE : FALSE); + + /* unit: %, value-100 to translate to unit: dBm */ + coex_sta->bt_rssi = coex_sta->bt_info_hb0 * 2 + 10; + + coex_sta->c2h_bt_remote_name_req = + ((coex_sta->bt_info_lb3 & BIT(5)) ? TRUE : FALSE); + + coex_sta->is_A2DP_3M = + ((coex_sta->bt_info_lb3 & BIT(4)) ? TRUE : FALSE); + + coex_sta->acl_busy = + ((coex_sta->bt_info_lb2 & BIT(3)) ? TRUE : FALSE); + + coex_sta->voice_over_HOGP = + ((coex_sta->bt_info_hb1 & BIT(4)) ? TRUE : FALSE); + + coex_sta->c2h_bt_inquiry_page = + ((coex_sta->bt_info_lb2 & BIT(2)) ? TRUE : FALSE); + + if (coex_sta->bt_inq_page_pre != coex_sta->c2h_bt_inquiry_page) { + coex_sta->bt_inq_page_pre = coex_sta->c2h_bt_inquiry_page; + coex_sta->bt_inq_page_remain = TRUE; + + if (!coex_sta->c2h_bt_inquiry_page) + coex_sta->bt_inq_page_downcount = 2; + } + + if ((coex_sta->bt_info_lb2 & 0x49) == 0x49) + coex_sta->a2dp_bit_pool = (coex_sta->bt_info_hb3 & 0x7f); + else + coex_sta->a2dp_bit_pool = 0; + + coex_sta->is_bt_a2dp_sink = + (coex_sta->bt_info_hb3 & BIT(7)) ? TRUE : FALSE; + + coex_sta->bt_retry_cnt = coex_sta->bt_info_lb3 & 0xf; + + bt_link_info->slave_role = coex_sta->bt_info_hb2 & 0x8; + + coex_sta->bt_a2dp_active = coex_sta->bt_info_hb2 & 0x4; + + coex_sta->hid_busy_num = (coex_sta->bt_info_hb2 & 0x30) >> 4; + + coex_sta->hid_pair_cnt = (coex_sta->bt_info_hb2 & 0xc0) >> 6; + + if (coex_sta->hid_pair_cnt > 0 && coex_sta->hid_busy_num >= 2) { + coex_sta->bt_418_hid_exist = TRUE; + } else if (coex_sta->hid_pair_cnt == 0 || + coex_sta->hid_busy_num == 1) { + coex_sta->bt_418_hid_exist = FALSE; + coex_sta->bt_ble_hid_exist = FALSE; + } + + coex_sta->is_bt_opp_exist = + (coex_sta->bt_info_hb2 & BIT(0)) ? TRUE : FALSE; + + if (coex_sta->bt_retry_cnt >= 1) + coex_sta->pop_event_cnt++; + + if (coex_sta->c2h_bt_remote_name_req) + coex_sta->cnt_remote_name_req++; + + if (coex_sta->bt_info_hb1 & BIT(1)) + coex_sta->cnt_reinit++; + + if ((coex_sta->bt_info_hb1 & BIT(2)) || + (coex_sta->bt_create_connection && + coex_sta->wl_pnp_wakeup_downcnt > 0)) { + coex_sta->cnt_setup_link++; + coex_sta->is_setup_link = TRUE; + + if (coex_sta->is_bt_reenable) + coex_sta->bt_relink_downcount = 6; + else + coex_sta->bt_relink_downcount = 2; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Re-Link start in BT info!!\n"); + BTC_TRACE(trace_buf); + } + + if (coex_sta->bt_info_hb1 & BIT(3)) + coex_sta->cnt_ign_wlan_act++; + + if (coex_sta->bt_info_hb1 & BIT(6)) + coex_sta->cnt_role_switch++; + + if (coex_sta->bt_info_hb1 & BIT(7)) + coex_sta->is_bt_multi_link = TRUE; + else + coex_sta->is_bt_multi_link = FALSE; + + if (coex_sta->bt_info_lb2 & BIT(5)) { + if (coex_sta->bt_info_hb1 & BIT(0)) { + /*BLE HID*/ + coex_sta->bt_ble_hid_exist = TRUE; + coex_sta->is_hid_rcu = FALSE; + } + } else if (coex_sta->bt_info_hb1 & BIT(0)) { + /*RCU*/ + coex_sta->is_hid_rcu = TRUE; + } else { + coex_sta->bt_ble_hid_exist = FALSE; + coex_sta->is_hid_rcu = FALSE; + } + + if (coex_sta->bt_info_hb1 & BIT(5)) + coex_sta->is_ble_scan_en = TRUE; + else + coex_sta->is_ble_scan_en = FALSE; + + if (coex_sta->bt_create_connection) { + coex_sta->cnt_page++; + + btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + + if (coex_sta->is_wifi_linkscan_process || + coex_sta->wifi_high_pri_task1 || + coex_sta->wifi_high_pri_task2 || wifi_busy) { + is_scoreboard_scan = TRUE; + halbtc8821c2ant_write_scbd(btc, type_is_scan, TRUE); + } else { + halbtc8821c2ant_write_scbd(btc, type_is_scan, FALSE); + } + } else { + if (is_scoreboard_scan) { + halbtc8821c2ant_write_scbd(btc, type_is_scan, FALSE); + is_scoreboard_scan = FALSE; + } + } + + /* Here we need to resend some wifi info to BT */ + /* because bt is reset and loss of the info. */ + btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); + /* Re-Init */ + if ((coex_sta->bt_info_hb1 & BIT(1))) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n"); + BTC_TRACE(trace_buf); + if (wifi_connected) + type = BTC_MEDIA_CONNECT; + else + type = BTC_MEDIA_DISCONNECT; + halbtc8821c2ant_update_wifi_ch_info(btc, type); + } + + /* If Ignore_WLanAct && not SetUp_Link */ + if ((coex_sta->bt_info_hb1 & BIT(3)) && + (!(coex_sta->bt_info_hb1 & BIT(2)))) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n"); + BTC_TRACE(trace_buf); + halbtc8821c2ant_ignore_wlan_act(btc, FC_EXCU, FALSE); + } + + halbtc8821c2ant_update_bt_link_info(btc); + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_BTINFO); +} + +void ex_halbtc8821c2ant_wl_fwdbginfo_notify(struct btc_coexist *btc, + u8 *tmp_buf, u8 length) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + u8 i = 0; + static u8 tmp_buf_pre[10]; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], WiFi Fw Dbg info = %d %d %d %d %d %d %d %d (len = %d)\n", + tmp_buf[0], tmp_buf[1], tmp_buf[2], tmp_buf[3], tmp_buf[4], + tmp_buf[5], tmp_buf[6], tmp_buf[7], length); + BTC_TRACE(trace_buf); + + if (tmp_buf[0] == 0x8) { + for (i = 1; i <= 7; i++) { + coex_sta->wl_fw_dbg_info[i] = + (tmp_buf[i] >= tmp_buf_pre[i]) ? + (tmp_buf[i] - tmp_buf_pre[i]) : + (255 - tmp_buf_pre[i] + tmp_buf[i]); + + tmp_buf_pre[i] = tmp_buf[i]; + } + } + + coex_sta->cnt_wl_fw_notify++; + halbtc8821c2ant_ccklock_action(btc); +} + +void ex_halbtc8821c2ant_rx_rate_change_notify(struct btc_coexist *btc, + BOOLEAN is_data_frame, + u8 btc_rate_id) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + + if (is_data_frame) { + coex_sta->wl_rx_rate = btc_rate_id; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], rx_rate_change_notify data rate id = %d, RTS_Rate = %d\n", + coex_sta->wl_rx_rate, coex_sta->wl_rts_rx_rate); + BTC_TRACE(trace_buf); + } else { + coex_sta->wl_rts_rx_rate = btc_rate_id; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], rts_rate_change_notify RTS rate id = %d, RTS_Rate = %d\n", + coex_sta->wl_rts_rx_rate, coex_sta->wl_rts_rx_rate); + BTC_TRACE(trace_buf); + } + + halbtc8821c2ant_ccklock_detect(btc); +} + +void ex_halbtc8821c2ant_tx_rate_change_notify(struct btc_coexist *btc, + u8 tx_rate, u8 tx_retry_ratio, + u8 macid) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], tx_rate_change_notify Tx_Rate = %d, Tx_Retry_Ratio = %d, macid =%d\n", + tx_rate, tx_retry_ratio, macid); + BTC_TRACE(trace_buf); + + coex_sta->wl_tx_rate = tx_rate; + coex_sta->wl_tx_retry_ratio = tx_retry_ratio; + coex_sta->wl_tx_macid = macid; +} + +void ex_halbtc8821c2ant_rf_status_notify(struct btc_coexist *btc, u8 type) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], RF Status notify\n"); + BTC_TRACE(trace_buf); + + if (type == BTC_RF_ON) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], RF is turned ON!!\n"); + BTC_TRACE(trace_buf); + + btc->stop_coex_dm = FALSE; + btc->wl_rf_state_off = FALSE; + } else if (type == BTC_RF_OFF) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], RF is turned OFF!!\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | + BT_8821C_2ANT_SCBD_ONOFF | + BT_8821C_2ANT_SCBD_SCAN | + BT_8821C_2ANT_SCBD_UNDERTEST, + FALSE); + + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, + BT_8821C_2ANT_PHASE_WOFF); + + halbtc8821c2ant_action_coex_all_off(btc); + + btc->stop_coex_dm = TRUE; + btc->wl_rf_state_off = TRUE; + /* must place in the last step */ + halbtc8821c2ant_update_wifi_ch_info(btc, BTC_MEDIA_DISCONNECT); + } +} + +void ex_halbtc8821c2ant_halt_notify(struct btc_coexist *btc) +{ + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], Halt notify\n"); + BTC_TRACE(trace_buf); + + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | + BT_8821C_2ANT_SCBD_ONOFF | + BT_8821C_2ANT_SCBD_SCAN | + BT_8821C_2ANT_SCBD_UNDERTEST, + FALSE); + + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, + BT_8821C_2ANT_PHASE_WOFF); + + halbtc8821c2ant_action_coex_all_off(btc); + + btc->stop_coex_dm = TRUE; + + /* must place in the last step */ + halbtc8821c2ant_update_wifi_ch_info(btc, BTC_MEDIA_DISCONNECT); +} + +void ex_halbtc8821c2ant_pnp_notify(struct btc_coexist *btc, u8 pnp_state) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct wifi_link_info_8821c_2ant *wifi_link_info_ext = + &btc->wifi_link_info_8821c_2ant; + static u8 pre_pnp_state; + u8 phase; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], Pnp notify\n"); + BTC_TRACE(trace_buf); + + if (pnp_state == BTC_WIFI_PNP_SLEEP || + pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT) { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Pnp notify to SLEEP\n"); + BTC_TRACE(trace_buf); + + /* Sinda 20150819, workaround for driver skip + * leave IPS/LPS to speed up sleep time. + * Driver do not leave IPS/LPS when driver is going to sleep, + * so BTCoexistence think wifi is still under IPS/LPS + * BT should clear UnderIPS/UnderLPS state to avoid mismatch + * state after wakeup. + */ + coex_sta->under_ips = FALSE; + coex_sta->under_lps = FALSE; + + halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE | + BT_8821C_2ANT_SCBD_ONOFF | + BT_8821C_2ANT_SCBD_SCAN | + BT_8821C_2ANT_SCBD_UNDERTEST, + FALSE); + + if (pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT) { + if (wifi_link_info_ext->is_all_under_5g) + phase = BT_8821C_2ANT_PHASE_5G; + else + phase = BT_8821C_2ANT_PHASE_2G; + } else { + phase = BT_8821C_2ANT_PHASE_WOFF; + } + + halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU, + phase); + btc->stop_coex_dm = TRUE; + } else { + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Pnp notify to WAKE UP\n"); + BTC_TRACE(trace_buf); + coex_sta->wl_pnp_wakeup_downcnt = 3; + + /*WoWLAN*/ + if (pre_pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT || + pnp_state == BTC_WIFI_PNP_WOWLAN) { + coex_sta->run_time_state = TRUE; + btc->stop_coex_dm = FALSE; + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_PNP); + } + } + + pre_pnp_state = pnp_state; +} + +void ex_halbtc8821c2ant_periodical(struct btc_coexist *btc) +{ + struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant; + struct btc_board_info *board_info = &btc->board_info; + boolean bt_relink_finish = FALSE, is_defreeze = FALSE, + bt_ctr_change = FALSE; + static u8 freeze_cnt; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], ************* Periodical *************\n"); + BTC_TRACE(trace_buf); + + if (!btc->auto_report) + halbtc8821c2ant_query_bt_info(btc); + + bt_ctr_change = halbtc8821c2ant_monitor_bt_ctr(btc); + halbtc8821c2ant_monitor_wifi_ctr(btc); + halbtc8821c2ant_update_wifi_link_info(btc, + BT_8821C_2ANT_RSN_PERIODICAL); + halbtc8821c2ant_monitor_bt_enable(btc); + + if (coex_sta->bt_relink_downcount != 0) { + coex_sta->bt_relink_downcount--; + if (coex_sta->bt_relink_downcount == 0) { + coex_sta->is_setup_link = FALSE; + bt_relink_finish = TRUE; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Re-Link stop by periodical count-down!!\n"); + BTC_TRACE(trace_buf); + } + } + + if (coex_sta->bt_inq_page_downcount != 0) { + coex_sta->bt_inq_page_downcount--; + if (coex_sta->bt_relink_downcount == 0) + coex_sta->bt_inq_page_remain = FALSE; + } + + if (coex_sta->freeze_coexrun_by_btinfo) { + freeze_cnt++; + + if (freeze_cnt >= 5) { + freeze_cnt = 0; + coex_sta->freeze_coexrun_by_btinfo = FALSE; + is_defreeze = TRUE; + } + } else { + freeze_cnt = 0; + } + + /* for 4-way, DHCP, EAPOL packet */ + if (coex_sta->specific_pkt_period_cnt > 0) { + coex_sta->specific_pkt_period_cnt--; + + if (!coex_sta->freeze_coexrun_by_btinfo && + coex_sta->specific_pkt_period_cnt == 0) + coex_sta->wifi_high_pri_task1 = FALSE; + + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], Hi-Pri Task = %s\n", + (coex_sta->wifi_high_pri_task1 ? "Yes" : "No")); + BTC_TRACE(trace_buf); + } + + if (coex_sta->wl_pnp_wakeup_downcnt > 0) { + coex_sta->wl_pnp_wakeup_downcnt--; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], wl_pnp_wakeup_downcnt = %d!!\n", + coex_sta->wl_pnp_wakeup_downcnt); + BTC_TRACE(trace_buf); + } + + if (coex_sta->cnt_bt_reenable > 0) { + coex_sta->cnt_bt_reenable--; + if (coex_sta->cnt_bt_reenable == 0) { + coex_sta->is_bt_reenable = FALSE; + BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, + "[BTCoex], BT renable 30s finish!!\n"); + BTC_TRACE(trace_buf); + } + } + + if (halbtc8821c2ant_moniter_wifibt_status(btc) || bt_relink_finish || + coex_sta->is_set_ps_state_fail || is_defreeze || bt_ctr_change) + halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_PERIODICAL); +} +/*#pragma optimize( "", off )*/ + +#endif + +#endif /* #if (RTL8821C_SUPPORT == 1) */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtc8821c2ant.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtc8821c2ant.h index e23951049fdb..14d6a4f80922 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtc8821c2ant.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtc8821c2ant.h @@ -1,517 +1,517 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2016 - 2017 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - *****************************************************************************/ - -#if (BT_SUPPORT == 1 && COEX_SUPPORT == 1) - -#if (RTL8821C_SUPPORT == 1) - -/* ******************************************* - * The following is for 8821C 2Ant BT Co-exist definition - * ******************************************* */ -#define BT_8821C_2ANT_COEX_DBG 0 -#define BT_AUTO_REPORT_ONLY_8821C_2ANT 1 - -#define BT_INFO_8821C_2ANT_B_FTP BIT(7) -#define BT_INFO_8821C_2ANT_B_A2DP BIT(6) -#define BT_INFO_8821C_2ANT_B_HID BIT(5) -#define BT_INFO_8821C_2ANT_B_SCO_BUSY BIT(4) -#define BT_INFO_8821C_2ANT_B_ACL_BUSY BIT(3) -#define BT_INFO_8821C_2ANT_B_INQ_PAGE BIT(2) -#define BT_INFO_8821C_2ANT_B_SCO_ESCO BIT(1) -#define BT_INFO_8821C_2ANT_B_CONNECTION BIT(0) - -#define BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT 2 - -#define BT_8821C_2ANT_WIFI_RSSI_COEXSWITCH_THRES1 80 -#define BT_8821C_2ANT_BT_RSSI_COEXSWITCH_THRES1 80 -#define BT_8821C_2ANT_WIFI_RSSI_COEXSWITCH_THRES2 80 -#define BT_8821C_2ANT_BT_RSSI_COEXSWITCH_THRES2 80 -#define BT_8821C_2ANT_DEFAULT_ISOLATION 15 -#define BT_8821C_2ANT_WIFI_MAX_TX_POWER 15 -#define BT_8821C_2ANT_BT_MAX_TX_POWER 3 -#define BT_8821C_2ANT_WIFI_SIR_THRES1 -15 -#define BT_8821C_2ANT_WIFI_SIR_THRES2 -30 -#define BT_8821C_2ANT_BT_SIR_THRES1 -15 -#define BT_8821C_2ANT_BT_SIR_THRES2 -30 - -enum bt_8821c_2ant_signal_state { - BT_8821C_2ANT_GNT_SET_TO_LOW = 0x0, - BT_8821C_2ANT_GNT_SET_TO_HIGH = 0x1, - BT_8821C_2ANT_GNT_SET_BY_HW = 0x2, - BT_8821C_2ANT_GNT_SET_MAX -}; - -enum bt_8821c_2ant_path_ctrl_owner { - BT_8821C_2ANT_PCO_BTSIDE = 0x0, - BT_8821C_2ANT_PCO_WLSIDE = 0x1, - BT_8821C_2ANT_PCO_MAX -}; - -enum bt_8821c_2ant_gnt_ctrl_type { - BT_8821C_2ANT_GNT_TYPE_CTRL_BY_PTA = 0x0, - BT_8821C_2ANT_GNT_TYPE_CTRL_BY_SW = 0x1, - BT_8821C_2ANT_GNT_TYPE_MAX -}; - -enum bt_8821c_2ant_gnt_ctrl_block { - BT_8821C_2ANT_GNT_BLOCK_RFC_BB = 0x0, - BT_8821C_2ANT_GNT_BLOCK_RFC = 0x1, - BT_8821C_2ANT_GNT_BLOCK_BB = 0x2, - BT_8821C_2ANT_GNT_BLOCK_MAX -}; - -enum bt_8821c_2ant_lte_coex_table_type { - BT_8821C_2ANT_CTT_WL_VS_LTE = 0x0, - BT_8821C_2ANT_CTT_BT_VS_LTE = 0x1, - BT_8821C_2ANT_CTT_MAX -}; - -enum bt_8821c_2ant_lte_break_table_type { - BT_8821C_2ANT_LBTT_WL_BREAK_LTE = 0x0, - BT_8821C_2ANT_LBTT_BT_BREAK_LTE = 0x1, - BT_8821C_2ANT_LBTT_LTE_BREAK_WL = 0x2, - BT_8821C_2ANT_LBTT_LTE_BREAK_BT = 0x3, - BT_8821C_2ANT_LBTT_MAX -}; - -enum bt_info_src_8821c_2ant { - BT_8821C_2ANT_INFO_SRC_WIFI_FW = 0x0, - BT_8821C_2ANT_INFO_SRC_BT_RSP = 0x1, - BT_8821C_2ANT_INFO_SRC_BT_ACT = 0x2, - BT_8821C_2ANT_INFO_SRC_MAX -}; - -enum bt_8821c_2ant_bt_status { - BT_8821C_2ANT_BSTATUS_NCON_IDLE = 0x0, - BT_8821C_2ANT_BSTATUS_CON_IDLE = 0x1, - BT_8821C_2ANT_BSTATUS_INQ_PAGE = 0x2, - BT_8821C_2ANT_BSTATUS_ACL_BUSY = 0x3, - BT_8821C_2ANT_BSTATUS_SCO_BUSY = 0x4, - BT_8821C_2ANT_BSTATUS_ACL_SCO_BUSY = 0x5, - BT_8821C_2ANT_BSTATUS_MAX -}; - -enum bt_8821c_2ant_coex_algo { - BT_8821C_2ANT_COEX_UNDEFINED = 0x0, - BT_8821C_2ANT_COEX_SCO = 0x1, - BT_8821C_2ANT_COEX_HID = 0x2, - BT_8821C_2ANT_COEX_A2DP = 0x3, - BT_8821C_2ANT_COEX_A2DP_PANHS = 0x4, - BT_8821C_2ANT_COEX_PAN = 0x5, - BT_8821C_2ANT_COEX_PANHS = 0x6, - BT_8821C_2ANT_COEX_PAN_A2DP = 0x7, - BT_8821C_2ANT_COEX_PAN_HID = 0x8, - BT_8821C_2ANT_COEX_HID_A2DP_PAN = 0x9, - BT_8821C_2ANT_COEX_HID_A2DP = 0xa, - BT_8821C_2ANT_COEX_NOPROFILEBUSY = 0xb, - BT_8821C_2ANT_COEX_A2DPSINK = 0xc, - BT_8821C_2ANT_COEX_MAX -}; - -enum bt_8821c_2ant_ext_ant_switch_type { - BT_8821C_2ANT_USE_DPDT = 0x0, - BT_8821C_2ANT_USE_SPDT = 0x1, - BT_8821C_2ANT_SWITCH_NONE = 0x2, - BT_8821C_2ANT_SWITCH_MAX -}; - -enum bt_8821c_2ant_ext_ant_switch_ctrl_type { - BT_8821C_2ANT_CTRL_BY_BBSW = 0x0, - BT_8821C_2ANT_CTRL_BY_PTA = 0x1, - BT_8821C_2ANT_CTRL_BY_ANTDIV = 0x2, - BT_8821C_2ANT_CTRL_BY_MAC = 0x3, - BT_8821C_2ANT_CTRL_BY_BT = 0x4, - BT_8821C_2ANT_CTRL_BY_FW = 0x5, - BT_8821C_2ANT_CTRL_MAX -}; - -enum bt_8821c_2ant_ext_ant_switch_pos_type { - BT_8821C_2ANT_TO_BT = 0x0, - BT_8821C_2ANT_TO_WLG = 0x1, - BT_8821C_2ANT_TO_WLA = 0x2, - BT_8821C_2ANT_TO_NOCARE = 0x3, - BT_8821C_2ANT_TO_MAX -}; - -enum bt_8821c_2ant_phase { - BT_8821C_2ANT_PHASE_INIT = 0x0, - BT_8821C_2ANT_PHASE_WONLY = 0x1, - BT_8821C_2ANT_PHASE_WOFF = 0x2, - BT_8821C_2ANT_PHASE_2G = 0x3, - BT_8821C_2ANT_PHASE_5G = 0x4, - BT_8821C_2ANT_PHASE_BTMP = 0x5, - BT_8821C_2ANT_PHASE_ANTDET = 0x6, - BT_8821C_2ANT_PHASE_POWERON = 0x7, - BT_8821C_2ANT_PHASE_MAX -}; - -enum bt_8821c_2ant_scoreboard { - BT_8821C_2ANT_SCBD_ACTIVE = BIT(0), - BT_8821C_2ANT_SCBD_ONOFF = BIT(1), - BT_8821C_2ANT_SCBD_SCAN = BIT(2), - BT_8821C_2ANT_SCBD_UNDERTEST = BIT(3), - BT_8821C_2ANT_SCBD_RXGAIN = BIT(4), - BT_8821C_2ANT_SCBD_WLBUSY = BIT(6), - BT_8821C_2ANT_SCBD_TDMA = BIT(9), - BT_8821C_2ANT_SCBD_BTCQDDR = BIT(10), - BT_8821C_2ANT_SCBD_ALL = 0xffff -}; - -enum bt_8821c_2ant_RUNREASON { - BT_8821C_2ANT_RSN_2GSCANSTART = 0x0, - BT_8821C_2ANT_RSN_5GSCANSTART = 0x1, - BT_8821C_2ANT_RSN_SCANFINISH = 0x2, - BT_8821C_2ANT_RSN_2GSWITCHBAND = 0x3, - BT_8821C_2ANT_RSN_5GSWITCHBAND = 0x4, - BT_8821C_2ANT_RSN_2GCONSTART = 0x5, - BT_8821C_2ANT_RSN_5GCONSTART = 0x6, - BT_8821C_2ANT_RSN_2GCONFINISH = 0x7, - BT_8821C_2ANT_RSN_5GCONFINISH = 0x8, - BT_8821C_2ANT_RSN_2GMEDIA = 0x9, - BT_8821C_2ANT_RSN_5GMEDIA = 0xa, - BT_8821C_2ANT_RSN_MEDIADISCON = 0xb, - BT_8821C_2ANT_RSN_2GSPECIALPKT = 0xc, - BT_8821C_2ANT_RSN_5GSPECIALPKT = 0xd, - BT_8821C_2ANT_RSN_BTINFO = 0xe, - BT_8821C_2ANT_RSN_PERIODICAL = 0xf, - BT_8821C_2ANT_RSN_PNP = 0x10, - BT_8821C_2ANT_RSN_LPS = 0x11, - BT_8821C_2ANT_RSN_MAX -}; - -enum bt_8821c_2ant_WL_LINK_MODE { - BT_8821C_2ANT_WLINK_2G1PORT = 0x0, - BT_8821C_2ANT_WLINK_2GMPORT = 0x1, - BT_8821C_2ANT_WLINK_25GMPORT = 0x2, - BT_8821C_2ANT_WLINK_5G = 0x3, - BT_8821C_2ANT_WLINK_2GGO = 0x4, - BT_8821C_2ANT_WLINK_BTMR = 0x5, - BT_8821C_2ANT_WLINK_MAX -}; - -struct coex_dm_8821c_2ant { - /* hw setting */ - u32 cur_ant_pos_type; - /* fw mechanism */ - - u8 cur_bt_pwr_lvl; - u8 cur_wl_pwr_lvl; - - boolean cur_ignore_wlan_act; - - u8 cur_ps_tdma; - u8 ps_tdma_para[5]; - boolean reset_tdma_adjust; - boolean cur_ps_tdma_on; - boolean cur_bt_auto_report; - - /* sw mechanism */ - boolean cur_low_penalty_ra; - - u32 cur_val0x6c0; - u32 cur_val0x6c4; - u32 cur_val0x6c8; - u8 cur_val0x6cc; - - /* algorithm related */ - u8 cur_algorithm; - u8 bt_status; - u8 wifi_chnl_info[3]; - - u8 cur_lps; - u8 cur_rpwm; - - u32 arp_cnt; - - u32 cur_ext_ant_switch_status; - - u8 cur_antdiv_type; - u32 setting_tdma; -}; - -struct coex_sta_8821c_2ant { - boolean bt_disabled; - boolean bt_link_exist; - boolean sco_exist; - boolean a2dp_exist; - boolean hid_exist; - boolean pan_exist; - boolean msft_mr_exist; - boolean bt_a2dp_active; - - boolean under_lps; - boolean under_ips; - u32 high_priority_tx; - u32 high_priority_rx; - u32 low_priority_tx; - u32 low_priority_rx; - boolean bt_ctr_ok; - boolean is_hi_pri_rx_overhead; - u8 bt_rssi; - u8 pre_bt_rssi_state; - u8 pre_wifi_rssi_state[4]; - u8 bt_info_c2h[BT_8821C_2ANT_INFO_SRC_MAX][BTC_BTINFO_LENGTH_MAX]; - u32 bt_info_c2h_cnt[BT_8821C_2ANT_INFO_SRC_MAX]; - boolean bt_whck_test; - boolean c2h_bt_inquiry_page; - boolean bt_inq_page_pre; - boolean bt_inq_page_remain; - boolean c2h_bt_remote_name_req; - - u8 bt_info_lb2; - u8 bt_info_lb3; - u8 bt_info_hb0; - u8 bt_info_hb1; - u8 bt_info_hb2; - u8 bt_info_hb3; - - u32 pop_event_cnt; - u8 scan_ap_num; - u8 bt_retry_cnt; - - u32 crc_ok_cck; - u32 crc_ok_11g; - u32 crc_ok_11n; - u32 crc_ok_11n_vht; - u32 crc_err_cck; - u32 crc_err_11g; - u32 crc_err_11n; - u32 crc_err_11n_vht; - u32 cnt_crcok_max_in_10s; - - boolean cck_lock; - boolean cck_lock_ever; - boolean cck_lock_warn; - - u8 coex_table_type; - boolean force_lps_ctrl; - - u8 dis_ver_info_cnt; - - u8 a2dp_bit_pool; - u8 kt_ver; - - boolean concurrent_rx_mode_on; - - u16 score_board; - u8 isolation_btween_wb; /* 0~ 50 */ - u8 wifi_coex_thres; - u8 bt_coex_thres; - u8 wifi_coex_thres2; - u8 bt_coex_thres2; - - u8 num_of_profile; - boolean acl_busy; - boolean bt_create_connection; - - boolean wifi_high_pri_task1; - boolean wifi_high_pri_task2; - - u32 specific_pkt_period_cnt; - u32 bt_coex_supported_feature; - u32 bt_coex_supported_version; - - u8 bt_ble_scan_type; - u32 bt_ble_scan_para[3]; - - boolean run_time_state; - boolean freeze_coexrun_by_btinfo; - - boolean is_A2DP_3M; - boolean voice_over_HOGP; - boolean bt_418_hid_exist; - boolean bt_ble_hid_exist; - u8 forbidden_slot; - u8 hid_busy_num; - u8 hid_pair_cnt; - - u32 cnt_remote_name_req; - u32 cnt_setup_link; - u32 cnt_reinit; - u32 cnt_ign_wlan_act; - u32 cnt_page; - u32 cnt_role_switch; - u32 cnt_wl_fw_notify; - - u16 bt_reg_vendor_ac; - u16 bt_reg_vendor_ae; - - boolean is_setup_link; - u8 wl_noisy_level; - u32 gnt_error_cnt; - - u8 bt_afh_map[10]; - u8 bt_relink_downcount; - u8 bt_inq_page_downcount; - boolean is_tdma_btautoslot; - - boolean is_esco_mode; - u8 switch_band_notify_to; - - boolean is_hid_low_pri_tx_overhead; - boolean is_bt_multi_link; - boolean is_bt_a2dp_sink; - boolean is_set_ps_state_fail; - u8 cnt_set_ps_state_fail; - - u8 wl_fw_dbg_info[10]; - u8 wl_rx_rate; - u8 wl_tx_rate; - u8 wl_rts_rx_rate; - u8 wl_center_channel; - u8 wl_tx_macid; - u8 wl_tx_retry_ratio; - - u16 score_board_WB; - boolean is_hid_rcu; - u8 bt_a2dp_vendor_id; - u32 bt_a2dp_device_name; - u32 bt_a2dp_flush_time; - boolean is_ble_scan_en; - - boolean is_bt_opp_exist; - boolean gl_wifi_busy; - u8 connect_ap_period_cnt; - - boolean is_bt_reenable; - u8 cnt_bt_reenable; - boolean is_wifi_linkscan_process; - u8 wl_coex_mode; - u8 wl_pnp_wakeup_downcnt; - u32 coex_run_cnt; - boolean is_no_wl_5ms_extend; - - u16 wl_0x42a_backup; - u32 wl_0x430_backup; - u32 wl_0x434_backup; - u8 wl_0x455_backup; - - boolean wl_tx_limit_en; - boolean wl_ampdu_limit_en; - boolean wl_rxagg_limit_en; - u8 wl_rxagg_size; - u8 coex_run_reason; - - u8 tdma_timer_base; - boolean wl_slot_toggle; - boolean wl_slot_toggle_change; /* if toggle to no-toggle */ - u8 wl_iot_peer; -}; - -#define BT_8821C_2ANT_EXT_BAND_SWITCH_USE_DPDT 0 -#define BT_8821C_2ANT_EXT_BAND_SWITCH_USE_SPDT 1 - -struct rfe_type_8821c_2ant { - u8 rfe_module_type; - boolean ext_ant_switch_exist; - /* 0:DPDT, 1:SPDT */ - u8 ext_ant_switch_type; - /* iF 0: DPDT_P=0, DPDT_N=1 => BTG to Main, WL_A+G to Aux */ - u8 ext_ant_switch_ctrl_polarity; - - boolean ext_band_switch_exist; - /* 0:DPDT, 1:SPDT */ - u8 ext_band_switch_type; - u8 ext_band_switch_ctrl_polarity; - - boolean ant_at_main_port; - - /* If TRUE: WLG at BTG, If FALSE: WLG at WLAG */ - boolean wlg_locate_at_btg; - - /* If diversity on */ - boolean ext_ant_switch_diversity; -}; - -struct wifi_link_info_8821c_2ant { - u8 num_of_active_port; - u32 port_connect_status; - boolean is_all_under_5g; - boolean is_mcc_25g; - boolean is_p2p_connected; - boolean is_connected; -}; - -/* ******************************************* - * The following is interface which will notify coex module. - * ******************************************* */ -void ex_halbtc8821c2ant_power_on_setting(struct btc_coexist *btc); -void ex_halbtc8821c2ant_pre_load_firmware(struct btc_coexist *btc); -void ex_halbtc8821c2ant_init_hw_config(struct btc_coexist *btc, - boolean wifi_only); -void ex_halbtc8821c2ant_init_coex_dm(struct btc_coexist *btc); -void ex_halbtc8821c2ant_ips_notify(struct btc_coexist *btc, - u8 type); -void ex_halbtc8821c2ant_lps_notify(struct btc_coexist *btc, - u8 type); -void ex_halbtc8821c2ant_scan_notify(struct btc_coexist *btc, - u8 type); -void ex_halbtc8821c2ant_switchband_notify(struct btc_coexist *btc, - u8 type); -void ex_halbtc8821c2ant_connect_notify(struct btc_coexist *btc, - u8 type); -void ex_halbtc8821c2ant_media_status_notify(struct btc_coexist *btc, - u8 type); -void ex_halbtc8821c2ant_specific_packet_notify(struct btc_coexist *btc, - u8 type); -void ex_halbtc8821c2ant_bt_info_notify(struct btc_coexist *btc, - u8 *tmp_buf, u8 length); -void ex_halbtc8821c2ant_wl_fwdbginfo_notify(struct btc_coexist *btc, - u8 *tmp_buf, u8 length); -void ex_halbtc8821c2ant_rx_rate_change_notify(struct btc_coexist *btc, - BOOLEAN is_data_frame, - u8 btc_rate_id); -void ex_halbtc8821c2ant_tx_rate_change_notify(struct btc_coexist *btc, - u8 tx_rate, - u8 tx_retry_ratio, u8 macid); -void ex_halbtc8821c2ant_rf_status_notify(struct btc_coexist *btc, - u8 type); -void ex_halbtc8821c2ant_halt_notify(struct btc_coexist *btc); -void ex_halbtc8821c2ant_pnp_notify(struct btc_coexist *btc, - u8 pnp_state); -void ex_halbtc8821c2ant_periodical(struct btc_coexist *btc); -void ex_halbtc8821c2ant_display_simple_coex_info(struct btc_coexist *btc); -void ex_halbtc8821c2ant_display_coex_info(struct btc_coexist *btc); - -#else -#define ex_halbtc8821c2ant_power_on_setting(btc) -#define ex_halbtc8821c2ant_pre_load_firmware(btc) -#define ex_halbtc8821c2ant_init_hw_config(btc, wifi_only) -#define ex_halbtc8821c2ant_init_coex_dm(btc) -#define ex_halbtc8821c2ant_ips_notify(btc, type) -#define ex_halbtc8821c2ant_lps_notify(btc, type) -#define ex_halbtc8821c2ant_scan_notify(btc, type) -#define ex_halbtc8821c2ant_switchband_notify(btc, type) -#define ex_halbtc8821c2ant_connect_notify(btc, type) -#define ex_halbtc8821c2ant_media_status_notify(btc, type) -#define ex_halbtc8821c2ant_specific_packet_notify(btc, type) -#define ex_halbtc8821c2ant_bt_info_notify(btc, tmp_buf, length) -#define ex_halbtc8821c2ant_wl_fwdbginfo_notify(btc, tmp_buf, length) -#define ex_halbtc8821c2ant_rx_rate_change_notify(btc, is_data_frame, \ - btc_rate_id) -#define ex_halbtc8821c2ant_tx_rate_change_notify(btcoexist, tx_rate, \ - tx_retry_ratio, macid) -#define ex_halbtc8821c2ant_rf_status_notify(btc, type) -#define ex_halbtc8821c2ant_halt_notify(btc) -#define ex_halbtc8821c2ant_pnp_notify(btc, pnp_state) -#define ex_halbtc8821c2ant_periodical(btc) -#define ex_halbtc8821c2ant_display_simple_coex_info(btc) -#define ex_halbtc8821c2ant_display_coex_info(btc) -#endif - -#endif - - +/****************************************************************************** + * + * Copyright(c) 2016 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#if (BT_SUPPORT == 1 && COEX_SUPPORT == 1) + +#if (RTL8821C_SUPPORT == 1) + +/* ******************************************* + * The following is for 8821C 2Ant BT Co-exist definition + * ******************************************* */ +#define BT_8821C_2ANT_COEX_DBG 0 +#define BT_AUTO_REPORT_ONLY_8821C_2ANT 1 + +#define BT_INFO_8821C_2ANT_B_FTP BIT(7) +#define BT_INFO_8821C_2ANT_B_A2DP BIT(6) +#define BT_INFO_8821C_2ANT_B_HID BIT(5) +#define BT_INFO_8821C_2ANT_B_SCO_BUSY BIT(4) +#define BT_INFO_8821C_2ANT_B_ACL_BUSY BIT(3) +#define BT_INFO_8821C_2ANT_B_INQ_PAGE BIT(2) +#define BT_INFO_8821C_2ANT_B_SCO_ESCO BIT(1) +#define BT_INFO_8821C_2ANT_B_CONNECTION BIT(0) + +#define BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT 2 + +#define BT_8821C_2ANT_WIFI_RSSI_COEXSWITCH_THRES1 80 +#define BT_8821C_2ANT_BT_RSSI_COEXSWITCH_THRES1 80 +#define BT_8821C_2ANT_WIFI_RSSI_COEXSWITCH_THRES2 80 +#define BT_8821C_2ANT_BT_RSSI_COEXSWITCH_THRES2 80 +#define BT_8821C_2ANT_DEFAULT_ISOLATION 15 +#define BT_8821C_2ANT_WIFI_MAX_TX_POWER 15 +#define BT_8821C_2ANT_BT_MAX_TX_POWER 3 +#define BT_8821C_2ANT_WIFI_SIR_THRES1 -15 +#define BT_8821C_2ANT_WIFI_SIR_THRES2 -30 +#define BT_8821C_2ANT_BT_SIR_THRES1 -15 +#define BT_8821C_2ANT_BT_SIR_THRES2 -30 + +enum bt_8821c_2ant_signal_state { + BT_8821C_2ANT_GNT_SET_TO_LOW = 0x0, + BT_8821C_2ANT_GNT_SET_TO_HIGH = 0x1, + BT_8821C_2ANT_GNT_SET_BY_HW = 0x2, + BT_8821C_2ANT_GNT_SET_MAX +}; + +enum bt_8821c_2ant_path_ctrl_owner { + BT_8821C_2ANT_PCO_BTSIDE = 0x0, + BT_8821C_2ANT_PCO_WLSIDE = 0x1, + BT_8821C_2ANT_PCO_MAX +}; + +enum bt_8821c_2ant_gnt_ctrl_type { + BT_8821C_2ANT_GNT_TYPE_CTRL_BY_PTA = 0x0, + BT_8821C_2ANT_GNT_TYPE_CTRL_BY_SW = 0x1, + BT_8821C_2ANT_GNT_TYPE_MAX +}; + +enum bt_8821c_2ant_gnt_ctrl_block { + BT_8821C_2ANT_GNT_BLOCK_RFC_BB = 0x0, + BT_8821C_2ANT_GNT_BLOCK_RFC = 0x1, + BT_8821C_2ANT_GNT_BLOCK_BB = 0x2, + BT_8821C_2ANT_GNT_BLOCK_MAX +}; + +enum bt_8821c_2ant_lte_coex_table_type { + BT_8821C_2ANT_CTT_WL_VS_LTE = 0x0, + BT_8821C_2ANT_CTT_BT_VS_LTE = 0x1, + BT_8821C_2ANT_CTT_MAX +}; + +enum bt_8821c_2ant_lte_break_table_type { + BT_8821C_2ANT_LBTT_WL_BREAK_LTE = 0x0, + BT_8821C_2ANT_LBTT_BT_BREAK_LTE = 0x1, + BT_8821C_2ANT_LBTT_LTE_BREAK_WL = 0x2, + BT_8821C_2ANT_LBTT_LTE_BREAK_BT = 0x3, + BT_8821C_2ANT_LBTT_MAX +}; + +enum bt_info_src_8821c_2ant { + BT_8821C_2ANT_INFO_SRC_WIFI_FW = 0x0, + BT_8821C_2ANT_INFO_SRC_BT_RSP = 0x1, + BT_8821C_2ANT_INFO_SRC_BT_ACT = 0x2, + BT_8821C_2ANT_INFO_SRC_MAX +}; + +enum bt_8821c_2ant_bt_status { + BT_8821C_2ANT_BSTATUS_NCON_IDLE = 0x0, + BT_8821C_2ANT_BSTATUS_CON_IDLE = 0x1, + BT_8821C_2ANT_BSTATUS_INQ_PAGE = 0x2, + BT_8821C_2ANT_BSTATUS_ACL_BUSY = 0x3, + BT_8821C_2ANT_BSTATUS_SCO_BUSY = 0x4, + BT_8821C_2ANT_BSTATUS_ACL_SCO_BUSY = 0x5, + BT_8821C_2ANT_BSTATUS_MAX +}; + +enum bt_8821c_2ant_coex_algo { + BT_8821C_2ANT_COEX_UNDEFINED = 0x0, + BT_8821C_2ANT_COEX_SCO = 0x1, + BT_8821C_2ANT_COEX_HID = 0x2, + BT_8821C_2ANT_COEX_A2DP = 0x3, + BT_8821C_2ANT_COEX_A2DP_PANHS = 0x4, + BT_8821C_2ANT_COEX_PAN = 0x5, + BT_8821C_2ANT_COEX_PANHS = 0x6, + BT_8821C_2ANT_COEX_PAN_A2DP = 0x7, + BT_8821C_2ANT_COEX_PAN_HID = 0x8, + BT_8821C_2ANT_COEX_HID_A2DP_PAN = 0x9, + BT_8821C_2ANT_COEX_HID_A2DP = 0xa, + BT_8821C_2ANT_COEX_NOPROFILEBUSY = 0xb, + BT_8821C_2ANT_COEX_A2DPSINK = 0xc, + BT_8821C_2ANT_COEX_MAX +}; + +enum bt_8821c_2ant_ext_ant_switch_type { + BT_8821C_2ANT_USE_DPDT = 0x0, + BT_8821C_2ANT_USE_SPDT = 0x1, + BT_8821C_2ANT_SWITCH_NONE = 0x2, + BT_8821C_2ANT_SWITCH_MAX +}; + +enum bt_8821c_2ant_ext_ant_switch_ctrl_type { + BT_8821C_2ANT_CTRL_BY_BBSW = 0x0, + BT_8821C_2ANT_CTRL_BY_PTA = 0x1, + BT_8821C_2ANT_CTRL_BY_ANTDIV = 0x2, + BT_8821C_2ANT_CTRL_BY_MAC = 0x3, + BT_8821C_2ANT_CTRL_BY_BT = 0x4, + BT_8821C_2ANT_CTRL_BY_FW = 0x5, + BT_8821C_2ANT_CTRL_MAX +}; + +enum bt_8821c_2ant_ext_ant_switch_pos_type { + BT_8821C_2ANT_TO_BT = 0x0, + BT_8821C_2ANT_TO_WLG = 0x1, + BT_8821C_2ANT_TO_WLA = 0x2, + BT_8821C_2ANT_TO_NOCARE = 0x3, + BT_8821C_2ANT_TO_MAX +}; + +enum bt_8821c_2ant_phase { + BT_8821C_2ANT_PHASE_INIT = 0x0, + BT_8821C_2ANT_PHASE_WONLY = 0x1, + BT_8821C_2ANT_PHASE_WOFF = 0x2, + BT_8821C_2ANT_PHASE_2G = 0x3, + BT_8821C_2ANT_PHASE_5G = 0x4, + BT_8821C_2ANT_PHASE_BTMP = 0x5, + BT_8821C_2ANT_PHASE_ANTDET = 0x6, + BT_8821C_2ANT_PHASE_POWERON = 0x7, + BT_8821C_2ANT_PHASE_MAX +}; + +enum bt_8821c_2ant_scoreboard { + BT_8821C_2ANT_SCBD_ACTIVE = BIT(0), + BT_8821C_2ANT_SCBD_ONOFF = BIT(1), + BT_8821C_2ANT_SCBD_SCAN = BIT(2), + BT_8821C_2ANT_SCBD_UNDERTEST = BIT(3), + BT_8821C_2ANT_SCBD_RXGAIN = BIT(4), + BT_8821C_2ANT_SCBD_WLBUSY = BIT(6), + BT_8821C_2ANT_SCBD_TDMA = BIT(9), + BT_8821C_2ANT_SCBD_BTCQDDR = BIT(10), + BT_8821C_2ANT_SCBD_ALL = 0xffff +}; + +enum bt_8821c_2ant_RUNREASON { + BT_8821C_2ANT_RSN_2GSCANSTART = 0x0, + BT_8821C_2ANT_RSN_5GSCANSTART = 0x1, + BT_8821C_2ANT_RSN_SCANFINISH = 0x2, + BT_8821C_2ANT_RSN_2GSWITCHBAND = 0x3, + BT_8821C_2ANT_RSN_5GSWITCHBAND = 0x4, + BT_8821C_2ANT_RSN_2GCONSTART = 0x5, + BT_8821C_2ANT_RSN_5GCONSTART = 0x6, + BT_8821C_2ANT_RSN_2GCONFINISH = 0x7, + BT_8821C_2ANT_RSN_5GCONFINISH = 0x8, + BT_8821C_2ANT_RSN_2GMEDIA = 0x9, + BT_8821C_2ANT_RSN_5GMEDIA = 0xa, + BT_8821C_2ANT_RSN_MEDIADISCON = 0xb, + BT_8821C_2ANT_RSN_2GSPECIALPKT = 0xc, + BT_8821C_2ANT_RSN_5GSPECIALPKT = 0xd, + BT_8821C_2ANT_RSN_BTINFO = 0xe, + BT_8821C_2ANT_RSN_PERIODICAL = 0xf, + BT_8821C_2ANT_RSN_PNP = 0x10, + BT_8821C_2ANT_RSN_LPS = 0x11, + BT_8821C_2ANT_RSN_MAX +}; + +enum bt_8821c_2ant_WL_LINK_MODE { + BT_8821C_2ANT_WLINK_2G1PORT = 0x0, + BT_8821C_2ANT_WLINK_2GMPORT = 0x1, + BT_8821C_2ANT_WLINK_25GMPORT = 0x2, + BT_8821C_2ANT_WLINK_5G = 0x3, + BT_8821C_2ANT_WLINK_2GGO = 0x4, + BT_8821C_2ANT_WLINK_BTMR = 0x5, + BT_8821C_2ANT_WLINK_MAX +}; + +struct coex_dm_8821c_2ant { + /* hw setting */ + u32 cur_ant_pos_type; + /* fw mechanism */ + + u8 cur_bt_pwr_lvl; + u8 cur_wl_pwr_lvl; + + boolean cur_ignore_wlan_act; + + u8 cur_ps_tdma; + u8 ps_tdma_para[5]; + boolean reset_tdma_adjust; + boolean cur_ps_tdma_on; + boolean cur_bt_auto_report; + + /* sw mechanism */ + boolean cur_low_penalty_ra; + + u32 cur_val0x6c0; + u32 cur_val0x6c4; + u32 cur_val0x6c8; + u8 cur_val0x6cc; + + /* algorithm related */ + u8 cur_algorithm; + u8 bt_status; + u8 wifi_chnl_info[3]; + + u8 cur_lps; + u8 cur_rpwm; + + u32 arp_cnt; + + u32 cur_ext_ant_switch_status; + + u8 cur_antdiv_type; + u32 setting_tdma; +}; + +struct coex_sta_8821c_2ant { + boolean bt_disabled; + boolean bt_link_exist; + boolean sco_exist; + boolean a2dp_exist; + boolean hid_exist; + boolean pan_exist; + boolean msft_mr_exist; + boolean bt_a2dp_active; + + boolean under_lps; + boolean under_ips; + u32 high_priority_tx; + u32 high_priority_rx; + u32 low_priority_tx; + u32 low_priority_rx; + boolean bt_ctr_ok; + boolean is_hi_pri_rx_overhead; + u8 bt_rssi; + u8 pre_bt_rssi_state; + u8 pre_wifi_rssi_state[4]; + u8 bt_info_c2h[BT_8821C_2ANT_INFO_SRC_MAX][BTC_BTINFO_LENGTH_MAX]; + u32 bt_info_c2h_cnt[BT_8821C_2ANT_INFO_SRC_MAX]; + boolean bt_whck_test; + boolean c2h_bt_inquiry_page; + boolean bt_inq_page_pre; + boolean bt_inq_page_remain; + boolean c2h_bt_remote_name_req; + + u8 bt_info_lb2; + u8 bt_info_lb3; + u8 bt_info_hb0; + u8 bt_info_hb1; + u8 bt_info_hb2; + u8 bt_info_hb3; + + u32 pop_event_cnt; + u8 scan_ap_num; + u8 bt_retry_cnt; + + u32 crc_ok_cck; + u32 crc_ok_11g; + u32 crc_ok_11n; + u32 crc_ok_11n_vht; + u32 crc_err_cck; + u32 crc_err_11g; + u32 crc_err_11n; + u32 crc_err_11n_vht; + u32 cnt_crcok_max_in_10s; + + boolean cck_lock; + boolean cck_lock_ever; + boolean cck_lock_warn; + + u8 coex_table_type; + boolean force_lps_ctrl; + + u8 dis_ver_info_cnt; + + u8 a2dp_bit_pool; + u8 kt_ver; + + boolean concurrent_rx_mode_on; + + u16 score_board; + u8 isolation_btween_wb; /* 0~ 50 */ + u8 wifi_coex_thres; + u8 bt_coex_thres; + u8 wifi_coex_thres2; + u8 bt_coex_thres2; + + u8 num_of_profile; + boolean acl_busy; + boolean bt_create_connection; + + boolean wifi_high_pri_task1; + boolean wifi_high_pri_task2; + + u32 specific_pkt_period_cnt; + u32 bt_coex_supported_feature; + u32 bt_coex_supported_version; + + u8 bt_ble_scan_type; + u32 bt_ble_scan_para[3]; + + boolean run_time_state; + boolean freeze_coexrun_by_btinfo; + + boolean is_A2DP_3M; + boolean voice_over_HOGP; + boolean bt_418_hid_exist; + boolean bt_ble_hid_exist; + u8 forbidden_slot; + u8 hid_busy_num; + u8 hid_pair_cnt; + + u32 cnt_remote_name_req; + u32 cnt_setup_link; + u32 cnt_reinit; + u32 cnt_ign_wlan_act; + u32 cnt_page; + u32 cnt_role_switch; + u32 cnt_wl_fw_notify; + + u16 bt_reg_vendor_ac; + u16 bt_reg_vendor_ae; + + boolean is_setup_link; + u8 wl_noisy_level; + u32 gnt_error_cnt; + + u8 bt_afh_map[10]; + u8 bt_relink_downcount; + u8 bt_inq_page_downcount; + boolean is_tdma_btautoslot; + + boolean is_esco_mode; + u8 switch_band_notify_to; + + boolean is_hid_low_pri_tx_overhead; + boolean is_bt_multi_link; + boolean is_bt_a2dp_sink; + boolean is_set_ps_state_fail; + u8 cnt_set_ps_state_fail; + + u8 wl_fw_dbg_info[10]; + u8 wl_rx_rate; + u8 wl_tx_rate; + u8 wl_rts_rx_rate; + u8 wl_center_channel; + u8 wl_tx_macid; + u8 wl_tx_retry_ratio; + + u16 score_board_WB; + boolean is_hid_rcu; + u8 bt_a2dp_vendor_id; + u32 bt_a2dp_device_name; + u32 bt_a2dp_flush_time; + boolean is_ble_scan_en; + + boolean is_bt_opp_exist; + boolean gl_wifi_busy; + u8 connect_ap_period_cnt; + + boolean is_bt_reenable; + u8 cnt_bt_reenable; + boolean is_wifi_linkscan_process; + u8 wl_coex_mode; + u8 wl_pnp_wakeup_downcnt; + u32 coex_run_cnt; + boolean is_no_wl_5ms_extend; + + u16 wl_0x42a_backup; + u32 wl_0x430_backup; + u32 wl_0x434_backup; + u8 wl_0x455_backup; + + boolean wl_tx_limit_en; + boolean wl_ampdu_limit_en; + boolean wl_rxagg_limit_en; + u8 wl_rxagg_size; + u8 coex_run_reason; + + u8 tdma_timer_base; + boolean wl_slot_toggle; + boolean wl_slot_toggle_change; /* if toggle to no-toggle */ + u8 wl_iot_peer; +}; + +#define BT_8821C_2ANT_EXT_BAND_SWITCH_USE_DPDT 0 +#define BT_8821C_2ANT_EXT_BAND_SWITCH_USE_SPDT 1 + +struct rfe_type_8821c_2ant { + u8 rfe_module_type; + boolean ext_ant_switch_exist; + /* 0:DPDT, 1:SPDT */ + u8 ext_ant_switch_type; + /* iF 0: DPDT_P=0, DPDT_N=1 => BTG to Main, WL_A+G to Aux */ + u8 ext_ant_switch_ctrl_polarity; + + boolean ext_band_switch_exist; + /* 0:DPDT, 1:SPDT */ + u8 ext_band_switch_type; + u8 ext_band_switch_ctrl_polarity; + + boolean ant_at_main_port; + + /* If TRUE: WLG at BTG, If FALSE: WLG at WLAG */ + boolean wlg_locate_at_btg; + + /* If diversity on */ + boolean ext_ant_switch_diversity; +}; + +struct wifi_link_info_8821c_2ant { + u8 num_of_active_port; + u32 port_connect_status; + boolean is_all_under_5g; + boolean is_mcc_25g; + boolean is_p2p_connected; + boolean is_connected; +}; + +/* ******************************************* + * The following is interface which will notify coex module. + * ******************************************* */ +void ex_halbtc8821c2ant_power_on_setting(struct btc_coexist *btc); +void ex_halbtc8821c2ant_pre_load_firmware(struct btc_coexist *btc); +void ex_halbtc8821c2ant_init_hw_config(struct btc_coexist *btc, + boolean wifi_only); +void ex_halbtc8821c2ant_init_coex_dm(struct btc_coexist *btc); +void ex_halbtc8821c2ant_ips_notify(struct btc_coexist *btc, + u8 type); +void ex_halbtc8821c2ant_lps_notify(struct btc_coexist *btc, + u8 type); +void ex_halbtc8821c2ant_scan_notify(struct btc_coexist *btc, + u8 type); +void ex_halbtc8821c2ant_switchband_notify(struct btc_coexist *btc, + u8 type); +void ex_halbtc8821c2ant_connect_notify(struct btc_coexist *btc, + u8 type); +void ex_halbtc8821c2ant_media_status_notify(struct btc_coexist *btc, + u8 type); +void ex_halbtc8821c2ant_specific_packet_notify(struct btc_coexist *btc, + u8 type); +void ex_halbtc8821c2ant_bt_info_notify(struct btc_coexist *btc, + u8 *tmp_buf, u8 length); +void ex_halbtc8821c2ant_wl_fwdbginfo_notify(struct btc_coexist *btc, + u8 *tmp_buf, u8 length); +void ex_halbtc8821c2ant_rx_rate_change_notify(struct btc_coexist *btc, + BOOLEAN is_data_frame, + u8 btc_rate_id); +void ex_halbtc8821c2ant_tx_rate_change_notify(struct btc_coexist *btc, + u8 tx_rate, + u8 tx_retry_ratio, u8 macid); +void ex_halbtc8821c2ant_rf_status_notify(struct btc_coexist *btc, + u8 type); +void ex_halbtc8821c2ant_halt_notify(struct btc_coexist *btc); +void ex_halbtc8821c2ant_pnp_notify(struct btc_coexist *btc, + u8 pnp_state); +void ex_halbtc8821c2ant_periodical(struct btc_coexist *btc); +void ex_halbtc8821c2ant_display_simple_coex_info(struct btc_coexist *btc); +void ex_halbtc8821c2ant_display_coex_info(struct btc_coexist *btc); + +#else +#define ex_halbtc8821c2ant_power_on_setting(btc) +#define ex_halbtc8821c2ant_pre_load_firmware(btc) +#define ex_halbtc8821c2ant_init_hw_config(btc, wifi_only) +#define ex_halbtc8821c2ant_init_coex_dm(btc) +#define ex_halbtc8821c2ant_ips_notify(btc, type) +#define ex_halbtc8821c2ant_lps_notify(btc, type) +#define ex_halbtc8821c2ant_scan_notify(btc, type) +#define ex_halbtc8821c2ant_switchband_notify(btc, type) +#define ex_halbtc8821c2ant_connect_notify(btc, type) +#define ex_halbtc8821c2ant_media_status_notify(btc, type) +#define ex_halbtc8821c2ant_specific_packet_notify(btc, type) +#define ex_halbtc8821c2ant_bt_info_notify(btc, tmp_buf, length) +#define ex_halbtc8821c2ant_wl_fwdbginfo_notify(btc, tmp_buf, length) +#define ex_halbtc8821c2ant_rx_rate_change_notify(btc, is_data_frame, \ + btc_rate_id) +#define ex_halbtc8821c2ant_tx_rate_change_notify(btcoexist, tx_rate, \ + tx_retry_ratio, macid) +#define ex_halbtc8821c2ant_rf_status_notify(btc, type) +#define ex_halbtc8821c2ant_halt_notify(btc) +#define ex_halbtc8821c2ant_pnp_notify(btc, pnp_state) +#define ex_halbtc8821c2ant_periodical(btc) +#define ex_halbtc8821c2ant_display_simple_coex_info(btc) +#define ex_halbtc8821c2ant_display_coex_info(btc) +#endif + +#endif + + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtcoutsrc.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtcoutsrc.h index 02350e90bc06..1a8fc0d15347 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtcoutsrc.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/halbtcoutsrc.h @@ -202,6 +202,10 @@ do {\ #define TDMA_4SLOT BIT(8) +/* for 2T2R -> 2T1R coex MIMO-PS mechanism tranlation */ +#define BTC_2GTDD_MAX_TRY 3 /* the max retry count for 1R->2R */ +#define BTC_2GFDD_MAX_STAY 300 /* the max stay time at 1R if 2R try-able (unit: 2s) */ + typedef enum _BTC_POWERSAVE_TYPE { BTC_PS_WIFI_NATIVE = 0, /* wifi original power save behavior */ BTC_PS_LPS_ON = 1, @@ -240,6 +244,7 @@ typedef enum _BTC_CHIP_TYPE { BTC_CHIP_RTL8723D = 10, BTC_CHIP_RTL8703B = 11, BTC_CHIP_RTL8725A = 12, + BTC_CHIP_RTL8723F = 13, BTC_CHIP_MAX } BTC_CHIP_TYPE, *PBTC_CHIP_TYPE; @@ -406,6 +411,7 @@ enum btc_ext_ant_switch_type { BTC_SWITCH_NONE = 0x0, BTC_SWITCH_SPDT = 0x1, BTC_SWITCH_SP3T = 0x2, + BTC_SWITCH_DPDT = 0x3, BTC_SWITCH_ANTMAX }; @@ -455,13 +461,18 @@ enum btc_wl2bt_scoreboard { BTC_SCBD_EXTFEM = BIT(8), BTC_SCBD_TDMA = BIT(9), BTC_SCBD_FIX2M = BIT(10), - BTC_SCBD_ALL = 0xffff + BTC_SCBD_MAILBOX_DBG = BIT(14), + BTC_SCBD_ALL = 0xffffffff }; enum btc_bt2wl_scoreboard { BTC_SCBD_BT_ONOFF = BIT(1), BTC_SCBD_BT_LPS = BIT(7) }; +enum btc_scoreboard_bit_num { + BTC_SCBD_16_BIT = BIT(0), + BTC_SCBD_32_BIT = BIT(1) +}; enum btc_runreason { BTC_RSN_2GSCANSTART = 0x0, @@ -484,6 +495,8 @@ enum btc_runreason { BTC_RSN_LPS = 0x11, BTC_RSN_TIMERUP = 0x12, BTC_RSN_WLSTATUS = 0x13, + BTC_RSN_BTCNT = 0x14, + BTC_RSN_RFK = 0x15, BTC_RSN_MAX }; @@ -508,6 +521,9 @@ static const char *const run_reason_string[] = { "LPSNotify", "TimerUp", "WL_STATUS_CHANGE", + "BT_CNT_CHANGE", + "WL_RFK", + "Reason Max" }; enum btc_wl_link_mode { @@ -518,6 +534,7 @@ enum btc_wl_link_mode { BTC_WLINK_2GGO = 0x4, BTC_WLINK_2GGC = 0x5, BTC_WLINK_BTMR = 0x6, + BTC_WLINK_2GFREE = 0x7, BTC_WLINK_MAX }; @@ -545,6 +562,7 @@ enum btc_bt_state_cnt { BTC_CNT_BT_INFOUPDATE = 0xa, BTC_CNT_BT_IQK = 0xb, BTC_CNT_BT_IQKFAIL = 0xc, + BTC_CNT_BT_TRX = 0xd, BTC_CNT_BT_MAX }; @@ -561,8 +579,10 @@ enum btc_wl_state_cnt { BTC_CNT_WL_NOISY1 = 0x9, BTC_CNT_WL_NOISY2 = 0xa, BTC_CNT_WL_ACTIVEPORT = 0xb, - BTC_CNT_WL_5MS_NOEXTEND = 0xc, + BTC_CNT_WL_LEAKAP_NORX = 0xc, BTC_CNT_WL_FW_NOTIFY = 0xd, + BTC_CNT_WL_2G_TDDTRY = 0xe, + BTC_CNT_WL_2G_FDDSTAY = 0xf, BTC_CNT_WL_MAX }; @@ -589,6 +609,8 @@ enum btc_timer_cnt { BTC_TIMER_BT_RELINK = 0x7, BTC_TIMER_BT_REENABLE = 0x8, BTC_TIMER_BT_MULTILINK = 0x9, + BTC_TIMER_BT_INQPAGE = 0xa, + BTC_TIMER_BT_A2DP_ACT = 0xb, BTC_TIMER_MAX }; @@ -599,6 +621,8 @@ enum btc_wl_status_change { BTC_WLSTATUS_CHANGE_LINKINFO = 0x3, BTC_WLSTATUS_CHANGE_DIR = 0x4, BTC_WLSTATUS_CHANGE_NOISY = 0x5, + BTC_WLSTATUS_CHANGE_BTCNT = 0x6, + BTC_WLSTATUS_CHANGE_LOCKTRY = 0x7, BTC_WLSTATUS_CHANGE_MAX }; @@ -612,6 +636,7 @@ enum btc_commom_chip_setup { BTC_CSETUP_WL_TX_POWER = 0x6, BTC_CSETUP_WL_RX_GAIN = 0x7, BTC_CSETUP_WLAN_ACT_IPS = 0x8, + BTC_CSETUP_BT_CTRL_ACT = 0x9, BTC_CSETUP_MAX }; @@ -645,6 +670,33 @@ enum btc_wl_priority_mask { BTC_WLPRI_MAX }; +enum btc_ext_chip_id{ + BTC_EXT_CHIP_NONE, + BTC_EXT_CHIP_RF4CE, + BTC_EXT_CHIP_MAX +}; + +enum btc_ext_chip_mode{ + BTC_EXTMODE_NORMAL, + BTC_EXTMODE_VOICE, + BTC_EXTMODE_MAX +}; + +enum btc_wl_rfk_type { + BTC_PWR_TRK = 0, + BTC_IQK = 1, + BTC_LCK = 2, + BTC_DPK = 3, + BTC_TXGAPK = 4, + BTC_RFK_TYPE_MAX +}; + +enum btc_wl_rfk_state { + BTC_RFK_START = 0, + BTC_RFK_END = 1, + BTC_RFK_STATE_MAX +}; + struct btc_board_info { /* The following is some board information */ u8 bt_chip_type; @@ -666,6 +718,7 @@ struct btc_board_info { u8 customerID; u8 customer_id; u8 ant_distance; /* WL-BT antenna space for non-shared antenna */ + u8 ext_chip_id; }; struct btc_coex_dm { @@ -697,13 +750,16 @@ struct btc_coex_sta { boolean coex_freeze; boolean coex_freerun; boolean rf4ce_en; - boolean is_no_wl_5ms_extend; + boolean force_freerun; + boolean force_tdd; boolean bt_disabled; boolean bt_disabled_pre; boolean bt_link_exist; boolean bt_whck_test; boolean bt_inq_page; + boolean bt_inq_page_pre; + boolean bt_inq_page_remain; boolean bt_inq; boolean bt_page; boolean bt_ble_voice; @@ -725,11 +781,14 @@ struct btc_coex_sta { boolean bt_ble_scan_en; boolean bt_slave; boolean bt_a2dp_active; + boolean bt_a2dp_active_pre; + boolean bt_a2dp_active_remain; boolean bt_slave_latency; boolean bt_init_scan; boolean bt_418_hid_exist; boolean bt_ble_hid_exist; boolean bt_mesh; + boolean bt_ctr_ok; boolean wl_under_lps; boolean wl_under_ips; @@ -753,6 +812,9 @@ struct btc_coex_sta { boolean wl_pnp_wakeup; boolean wl_slot_toggle; boolean wl_slot_toggle_change; /* if toggle to no-toggle */ + boolean wl_leak_ap; /* !is_no_wl_5ms_extend */ + boolean wl_blacklist_ap; + boolean wl_rfk; u8 coex_table_type; u8 coex_run_reason; @@ -780,6 +842,7 @@ struct btc_coex_sta { u8 bt_sut_pwr_lvl[4]; u8 bt_golden_rx_shift[4]; u8 bt_ext_autoslot_thres; + u8 ext_chip_mode; u8 wl_pnp_state_pre; u8 wl_noisy_level; @@ -800,11 +863,13 @@ struct btc_coex_sta { u8 wl_toggle_interval; u16 score_board_BW; - u16 score_board_WB; + u32 score_board_WB; u16 bt_reg_vendor_ac; u16 bt_reg_vendor_ae; + u32 bt_reg_vendor_dac; u16 bt_reg_modem_a; u16 bt_reg_rf_2; + u16 bt_reg_rf_9; u16 wl_txlimit; u32 hi_pri_tx; @@ -1054,6 +1119,7 @@ typedef enum _BTC_GET_TYPE { BTC_GET_U1_AP_NUM, BTC_GET_U1_ANT_TYPE, BTC_GET_U1_IOT_PEER, + BTC_GET_BL_WIFI_BSSID, /* type u2Byte */ BTC_GET_U2_BEACON_PERIOD, @@ -1174,6 +1240,13 @@ typedef enum _BTC_NOTIFY_TYPE_STACK_OPERATION { BTC_STACK_OP_MAX } BTC_NOTIFY_TYPE_STACK_OPERATION, *PBTC_NOTIFY_TYPE_STACK_OPERATION; +typedef enum _BTC_LINK_CHANGE_TYPE{ + BTC_LINK_CHANGE_TYPE_NONE = 0x0, + BTC_LINK_CHANGE_TYPE_ECSA_START = 0x1, + BTC_LINK_CHANGE_TYPE_ECSA_DONE = 0x2, + BTC_LINK_CHANGE_TYPE_MAX +}BTC_LINK_CHANGE_TYPE,*PBTC_LINK_CHANGE_TYPE; + /* Bryant Add */ typedef enum _BTC_ANTENNA_POS { BTC_ANTENNA_AT_MAIN_PORT = 0x1, @@ -1408,15 +1481,15 @@ typedef u4Byte IN PVOID pBtcContext, IN u2Byte reg_addr ); -typedef u2Byte +typedef u4Byte (*BFP_BTC_R_SCBD)( IN PVOID pBtcContext, - IN pu2Byte score_board_val + IN pu4Byte score_board_val ); typedef VOID (*BFP_BTC_W_SCBD)( IN PVOID pBtcContext, - IN u2Byte bitpos, + IN u4Byte bitpos, IN BOOLEAN state ); typedef VOID @@ -1698,6 +1771,8 @@ struct btc_coexist { struct btc_coex_sta coex_sta; struct btc_rfe_type rfe_type; const struct btc_chip_para *chip_para; + u8 wifi_black_bssid[6]; + u8 wifi_bssid[6]; #ifdef CONFIG_RF4CE_COEXIST struct btc_rf4ce_info rf4ce_info; @@ -1837,6 +1912,8 @@ struct btc_chip_para { u32 para_ver; u32 bt_desired_ver; boolean scbd_support; + u32 scbd_reg; + u8 scbd_bit_num; boolean mailbox_support; boolean lte_indirect_access; boolean new_scbd10_def; /* TRUE: 1:fix 2M(8822c) */ @@ -1980,6 +2057,13 @@ EXhalbtcoutsrc_WLStatusChangeNotify( IN u4Byte change_type ); VOID +EXhalbtcoutsrc_WL_RFK_Notify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte path, + IN u1Byte type, + IN u1Byte state + ); +VOID EXhalbtcoutsrc_CoexDmSwitch( IN PBTC_COEXIST pBtCoexist ); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/mp_precomp.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/mp_precomp.h index 62797cf8ee6d..ae272ea3abc8 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/mp_precomp.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/btc/mp_precomp.h @@ -125,6 +125,11 @@ struct btc_coexist; #include "halbtc8822c.h" #endif +#ifdef CONFIG_RTL8723F +#include "halbtc8723fwifionly.h" +#include "halbtc8723f.h" +#endif + #ifdef CONFIG_RTL8192F #include "halbtc8192f.h" #endif @@ -151,6 +156,10 @@ struct btc_coexist; #include "halbtc8822cwifionly.h" #endif +#ifdef CONFIG_RTL8723F +#include "halbtc8723fwifionly.h" +#endif + #ifdef CONFIG_RTL8814B #include "halbtc8814bwifionly.h" #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/efuse/efuse_mask.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/efuse/efuse_mask.h index 7b8ec1d531d2..db4edb9f3afa 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/efuse/efuse_mask.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/efuse/efuse_mask.h @@ -77,6 +77,10 @@ #if defined(CONFIG_RTL8814B) #include "rtl8814b/HalEfuseMask8814B_USB.h" #endif + + #if defined(CONFIG_RTL8723F) + #include "rtl8723f/HalEfuseMask8723F_USB.h" + #endif #endif /*CONFIG_USB_HCI*/ #ifdef CONFIG_PCI_HCI @@ -179,4 +183,7 @@ #include "rtl8822c/HalEfuseMask8822C_SDIO.h" #endif + #if defined(CONFIG_RTL8723F) + #include "rtl8723f/HalEfuseMask8723F_SDIO.h" + #endif #endif /*CONFIG_SDIO_HCI*/ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_btcoex.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_btcoex.c index 2f9f071fdb62..dec5f8a1fb91 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_btcoex.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_btcoex.c @@ -723,6 +723,34 @@ struct btc_wifi_link_info halbtcoutsrc_getwifilinkinfo(PBTC_COEXIST pBtCoexist) wifi_link_info.link_mode = BTC_LINK_25G_MCC_GC_STA; } } + + if (sta_iface && ap_iface) { + u8 band_sta = sta_iface->mlmeextpriv.cur_channel > 14 ? BAND_ON_5G : BAND_ON_2_4G; + u8 band_ap = ap_iface->mlmeextpriv.cur_channel > 14 ? BAND_ON_5G : BAND_ON_2_4G; + + if (band_sta == band_ap) { + switch (band_sta) { + case BAND_ON_2_4G: + #ifdef CONFIG_MCC_MODE + wifi_link_info.link_mode = + mcc_en == _TRUE ? BTC_LINK_2G_MCC_GO_STA : BTC_LINK_2G_SCC_GO_STA; + #else /* !CONFIG_MCC_MODE */ + wifi_link_info.link_mode = BTC_LINK_2G_SCC_GO_STA; + #endif /* CONFIG_MCC_MODE */ + break; + case BAND_ON_5G: + #ifdef CONFIG_MCC_MODE + wifi_link_info.link_mode = + mcc_en == _TRUE ? BTC_LINK_5G_MCC_GO_STA : BTC_LINK_5G_SCC_GO_STA; + #else /* !CONFIG_MCC_MODE */ + wifi_link_info.link_mode = BTC_LINK_5G_SCC_GO_STA; + #endif /* CONFIG_MCC_MODE */ + break; + } + } else { + wifi_link_info.link_mode = BTC_LINK_25G_MCC_GO_STA; + } + } } else { if (pBtCoexist->board_info.btdm_ant_num == 1) RTW_ERR("%s do not support n_assoc_iface > 2 (ant_num == 1)", __func__); @@ -1061,6 +1089,11 @@ u32 halbtcoutsrc_GetPhydmVersion(void *pBtcContext) #ifdef CONFIG_RTL8814B return RELEASE_VERSION_8814B; #endif + +#ifdef CONFIG_RTL8723F + return RELEASE_VERSION_8723F; +#endif + } u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf) @@ -1145,6 +1178,10 @@ u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf) *pu8 = _FALSE; break; + case BTC_GET_BL_WIFI_BSSID: + _rtw_memcpy(pu8, get_bssid(&padapter->mlmepriv), ETH_ALEN); + break; + case BTC_GET_BL_WIFI_UNDER_5G: *pu8 = (pHalData->current_band_type == BAND_ON_5G) ? _TRUE : _FALSE; break; @@ -1998,7 +2035,7 @@ void halbtcoutsrc_DisplayWifiStatus(PBTC_COEXIST pBtCoexist) pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Link/ Roam/ Scan", bLink, bRoam, bScan); - CL_PRINTF(cliBuf); + CL_PRINTF(cliBuf); pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_IQK_TOTAL, &iqk_cnt_total); pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_IQK_OK, &iqk_cnt_ok); @@ -2007,9 +2044,9 @@ void halbtcoutsrc_DisplayWifiStatus(PBTC_COEXIST pBtCoexist) "IQK All/ OK/ Fail/AutoLoad/FWDL", iqk_cnt_total, iqk_cnt_ok, iqk_cnt_fail, ((halbtcoutsrc_is_autoload_fail(pBtCoexist) == _TRUE) ? "fail":"ok"), ((halbtcoutsrc_is_fw_ready(pBtCoexist) == _TRUE) ? "ok":"fail")); CL_PRINTF(cliBuf); - + if (wifiLinkStatus & WIFI_STA_CONNECTED) { - CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "IOT Peer", GLBtcIotPeerString[padapter->mlmeextpriv.mlmext_info.assoc_AP_vendor]); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ "MAC_FMT"", "IOT Peer/BSSID", GLBtcIotPeerString[padapter->mlmeextpriv.mlmext_info.assoc_AP_vendor], MAC_ARG(get_bssid(&padapter->mlmepriv))); CL_PRINTF(cliBuf); } @@ -2293,7 +2330,7 @@ void halbtcoutsrc_WriteLIndirectReg(void *pBtcContext, u16 reg_addr, u32 bit_mas } } -u16 halbtcoutsrc_Read_scbd(void *pBtcContext, u16* score_board_val) +u32 halbtcoutsrc_Read_scbd(void *pBtcContext, u32* score_board_val) { PBTC_COEXIST btc = (PBTC_COEXIST)pBtcContext; struct btc_coex_sta *coex_sta = &btc->coex_sta; @@ -2302,18 +2339,19 @@ u16 halbtcoutsrc_Read_scbd(void *pBtcContext, u16* score_board_val) if (!chip_para->scbd_support) return 0; - *score_board_val = (btc->btc_read_2byte(btc, 0xaa)) & 0x7fff; + *score_board_val = (btc->btc_read_4byte(btc, chip_para->scbd_reg)) + & 0x7fffffff; coex_sta->score_board_BW = *score_board_val; return coex_sta->score_board_BW; } -void halbtcoutsrc_Write_scbd(void *pBtcContext, u16 bitpos, u8 state) +void halbtcoutsrc_Write_scbd(void *pBtcContext, u32 bitpos, u8 state) { PBTC_COEXIST btc = (PBTC_COEXIST)pBtcContext; struct btc_coex_sta *coex_sta = &btc->coex_sta; const struct btc_chip_para *chip_para = btc->chip_para; - u16 val = 0x2; + u32 val = 0x2; u8* btc_dbg_buf = &gl_btc_trace_buf[0]; if (!chip_para->scbd_support) @@ -2338,17 +2376,20 @@ void halbtcoutsrc_Write_scbd(void *pBtcContext, u16 bitpos, u8 state) if (val != coex_sta->score_board_WB) { coex_sta->score_board_WB = val; - val = val | 0x8000; - btc->btc_write_2byte(btc, 0xaa, val); + if(chip_para->scbd_bit_num == BTC_SCBD_32_BIT) + val = val | 0x80000000; + else + val = val | 0x8000; + + btc->btc_write_4byte(btc, chip_para->scbd_reg, val); + BTC_SPRINTF(btc_dbg_buf, BT_TMP_BUF_SIZE, "[BTCoex], write scoreboard 0x%x\n", val); } else { BTC_SPRINTF(btc_dbg_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s: return for nochange\n", __func__); } - - BTC_TRACE(btc_dbg_buf); } void halbtcoutsrc_SetBbReg(void *pBtcContext, u32 RegAddr, u32 BitMask, u32 Data) @@ -2905,7 +2946,7 @@ void halbtcoutsrc_reduce_wl_tx_power(void *pBtcContext, s8 tx_power) HAL_DATA_TYPE *pHalData = GET_HAL_DATA((PADAPTER)pBtCoexist->Adapter); /* The reduction of wl tx pwr should be processed inside the set tx pwr lvl function */ - if (IS_HARDWARE_TYPE_8822C(pBtCoexist->Adapter)) + if (IS_HARDWARE_TYPE_8822C(pBtCoexist->Adapter) || IS_HARDWARE_TYPE_8723F(pBtCoexist->Adapter)) rtw_hal_set_tx_power_level(pBtCoexist->Adapter, pHalData->current_channel); } @@ -3024,6 +3065,114 @@ void BT_CoexOffloadC2hCheck(PADAPTER Adapter, u8 *Buffer, u8 Length) } #endif +#if (CONFIG_BTCOEX_SUPPORT_BTC_CMN == 1) +static void halbtcoutsrc_wl_noisy_detect(struct btc_coexist *btc) +{ + struct btc_coex_sta *coex_sta = &btc->coex_sta; + u32 cnt_cck, ok_11b, err_11b; + + ok_11b = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_CCK); + err_11b = btc->btc_phydm_query_PHY_counter(btc, + PHYDM_INFO_CRC32_ERROR_CCK); + + /* WiFi environment noisy identification */ + cnt_cck = ok_11b + err_11b; + + if (!coex_sta->wl_gl_busy && !coex_sta->wl_cck_lock) { + if (cnt_cck > 250) { + if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY2] < 5) + coex_sta->cnt_wl[BTC_CNT_WL_NOISY2]++; + + if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY2] == 5) { + coex_sta->cnt_wl[BTC_CNT_WL_NOISY0] = 0; + coex_sta->cnt_wl[BTC_CNT_WL_NOISY1] = 0; + } + } else if (cnt_cck < 100) { + if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY0] < 5) + coex_sta->cnt_wl[BTC_CNT_WL_NOISY0]++; + + if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY0] == 5) { + coex_sta->cnt_wl[BTC_CNT_WL_NOISY1] = 0; + coex_sta->cnt_wl[BTC_CNT_WL_NOISY2] = 0; + } + } else { + if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY1] < 5) + coex_sta->cnt_wl[BTC_CNT_WL_NOISY1]++; + + if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY1] == 5) { + coex_sta->cnt_wl[BTC_CNT_WL_NOISY0] = 0; + coex_sta->cnt_wl[BTC_CNT_WL_NOISY2] = 0; + } + } + + if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY2] == 5) + coex_sta->wl_noisy_level = 2; + else if (coex_sta->cnt_wl[BTC_CNT_WL_NOISY1] == 5) + coex_sta->wl_noisy_level = 1; + else + coex_sta->wl_noisy_level = 0; + + RTW_DBG("[BTC], wl_noisy_level = %d\n", + coex_sta->wl_noisy_level); + } +} + +static boolean halbtcoutsrc_btc_monitor_bt_ctr(struct btc_coexist *btc) +{ + struct btc_coex_sta *coex_sta = &btc->coex_sta; + struct btc_coex_dm *coex_dm = &btc->coex_dm; + u32 cnt_bt_hi_pri, cnt_bt_lo_pri, cnt_bt_all; + boolean is_run_coex = _FALSE; + + cnt_bt_hi_pri = btc->btc_read_4byte(btc, REG_BT_ACT_STATISTICS); + coex_sta->hi_pri_tx = cnt_bt_hi_pri & MASKLWORD; + coex_sta->hi_pri_rx = (cnt_bt_hi_pri & MASKHWORD) >> 16; + + cnt_bt_lo_pri = btc->btc_read_4byte(btc, REG_BT_ACT_STATISTICS_1); + coex_sta->lo_pri_tx = cnt_bt_lo_pri & MASKLWORD; + coex_sta->lo_pri_rx = (cnt_bt_lo_pri & MASKHWORD) >> 16; + + RTW_DBG("[BTC], Hi-Pri Rx/Tx: %d/%d, Lo-Pri Rx/Tx: %d/%d\n", + coex_sta->hi_pri_rx, coex_sta->hi_pri_tx, + coex_sta->lo_pri_rx, coex_sta->lo_pri_tx); + + /* reset counter */ + btc->btc_write_1byte(btc, 0x76e, 0xc); + + if (coex_sta->wl_under_lps || coex_sta->wl_under_ips || + (coex_sta->hi_pri_rx == 65535 && coex_sta->hi_pri_tx == 65535 && + coex_sta->lo_pri_rx == 65535 && coex_sta->lo_pri_tx == 65535)) + coex_sta->bt_ctr_ok = _FALSE; + else + coex_sta->bt_ctr_ok = _TRUE; + + if (!coex_sta->bt_ctr_ok) + return _FALSE; + + if (coex_sta->hi_pri_rx == 0 && coex_sta->hi_pri_tx == 0 && + coex_sta->lo_pri_rx == 0 && coex_sta->lo_pri_tx == 0) { + coex_sta->cnt_bt[BTC_CNT_BT_DISABLE]++; + + if (coex_sta->cnt_bt[BTC_CNT_BT_DISABLE] > 2) + coex_sta->cnt_bt[BTC_CNT_BT_DISABLE] = 2; + } else { + coex_sta->cnt_bt[BTC_CNT_BT_DISABLE] = 0; + } + + cnt_bt_all = coex_sta->hi_pri_rx + coex_sta->hi_pri_tx + + coex_sta->lo_pri_rx + coex_sta->lo_pri_tx; + + if ((coex_sta->cnt_bt[BTC_CNT_BT_TRX] > (cnt_bt_all + 50) || + cnt_bt_all > (coex_sta->cnt_bt[BTC_CNT_BT_TRX] + 50)) && + coex_dm->bt_status == BTC_BTSTATUS_NCON_IDLE) + is_run_coex = _TRUE; + + coex_sta->cnt_bt[BTC_CNT_BT_TRX] = cnt_bt_all; + + return is_run_coex; +} +#endif + /* ************************************ * Extern functions called by other module * ************************************ */ @@ -3062,6 +3211,12 @@ u8 EXhalbtcoutsrc_BindBtCoexWithAdapter(void *padapter) pBtCoexist->chip_type = BTC_CHIP_RTL8725A; pBtCoexist->chip_para = &btc_chip_para_8192f; } +#endif +#ifdef CONFIG_RTL8723F + else if (IS_HARDWARE_TYPE_8723F(padapter)) { + pBtCoexist->chip_type = BTC_CHIP_RTL8723F; + pBtCoexist->chip_para = &btc_chip_para_8723f; + } #endif else { pBtCoexist->chip_type = BTC_CHIP_UNDEF; @@ -4707,15 +4862,19 @@ u32 EXhalbtcoutsrc_CoexTimerCheck(PBTC_COEXIST pBtCoexist) u32 EXhalbtcoutsrc_WLStatusCheck(PBTC_COEXIST pBtCoexist) { struct btc_wifi_link_info link_info; + struct btc_coex_sta *coex_sta = &pBtCoexist->coex_sta; const struct btc_chip_para *chip_para = pBtCoexist->chip_para; u32 change_map = 0; static bool wl_busy_pre; - bool wl_busy = _FALSE; + bool wl_busy = _FALSE, bt_ctr_change = _FALSE; s32 wl_rssi; u32 traffic_dir; u8 i, tmp; static u8 rssi_step_pre = 5, wl_noisy_level_pre = 4; + halbtcoutsrc_wl_noisy_detect(pBtCoexist); + bt_ctr_change = halbtcoutsrc_btc_monitor_bt_ctr(pBtCoexist); + /* WL busy to idle or idle to busy */ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &wl_busy); if (wl_busy != wl_busy_pre) { @@ -4761,9 +4920,30 @@ u32 EXhalbtcoutsrc_WLStatusCheck(PBTC_COEXIST pBtCoexist) } /* Noisy Detect */ - if (pBtCoexist->coex_sta.wl_noisy_level != wl_noisy_level_pre) { + if (coex_sta->wl_noisy_level != wl_noisy_level_pre) { change_map |= BIT(BTC_WLSTATUS_CHANGE_NOISY); - wl_noisy_level_pre = pBtCoexist->coex_sta.wl_noisy_level; + wl_noisy_level_pre = coex_sta->wl_noisy_level; + } + + /* BT Counter change > 50 */ + if (bt_ctr_change) + change_map |= BIT(BTC_WLSTATUS_CHANGE_BTCNT); + + /* CCK Lock Try */ + if (coex_sta->wl_coex_mode == BTC_WLINK_2GFREE) + coex_sta->cnt_wl[BTC_CNT_WL_2G_FDDSTAY]++; + + if (coex_sta->wl_coex_mode == BTC_WLINK_2GFREE && + coex_sta->cnt_wl[BTC_CNT_WL_2G_FDDSTAY] > BTC_2GFDD_MAX_STAY && + coex_sta->cnt_wl[BTC_CNT_WL_2G_TDDTRY] < BTC_2GTDD_MAX_TRY) { + coex_sta->cnt_wl[BTC_CNT_WL_2G_TDDTRY]++; + + RTW_DBG("[BTC], Try 2.4G coex from FDD to TDD (FDD:%d, TRY:%d)\n", + coex_sta->cnt_wl[BTC_CNT_WL_2G_FDDSTAY], + coex_sta->cnt_wl[BTC_CNT_WL_2G_TDDTRY]); + + coex_sta->cnt_wl[BTC_CNT_WL_2G_FDDSTAY] = 0; + change_map |= BIT(BTC_WLSTATUS_CHANGE_LOCKTRY); } RTW_DBG("[BTC], %s(): change_map = 0x%x\n", __func__, change_map); @@ -4787,6 +4967,14 @@ void EXhalbtcoutsrc_status_monitor(PBTC_COEXIST pBtCoexist) } #endif +void EXhalbtcoutsrc_WL_RFK_Notify(PBTC_COEXIST pBtCoexist, u8 path, u8 type, u8 state) +{ + #if (CONFIG_BTCOEX_SUPPORT_BTC_CMN == 1) + rtw_btc_ex_wl_rfk_notify(pBtCoexist, path, type, state); + #endif + return; +} + void EXhalbtcoutsrc_periodical(PBTC_COEXIST pBtCoexist) { if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) @@ -5732,6 +5920,11 @@ void hal_btcoex_IQKNotify(PADAPTER padapter, u8 state) GLBtcWiFiInIQKState = state; } +void hal_btcoex_WLRFKNotify(PADAPTER padapter, u8 path, u8 type, u8 state) +{ + EXhalbtcoutsrc_WL_RFK_Notify(&GLBtCoexist, path, type, state); +} + void hal_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf) { if (GLBtcWiFiInIQKState == _TRUE) @@ -5854,6 +6047,24 @@ void hal_btcoex_SetManualControl(PADAPTER padapter, u8 bmanual) GLBtCoexist.manual_control = bmanual; } +void hal_btcoex_set_policy_control(PADAPTER padapter, u8 btc_policy) +{ + switch (btc_policy) { + case BTCOEX_POLICY_CONTROL_AUTO: + GLBtCoexist.coex_sta.force_freerun = _FALSE; + GLBtCoexist.coex_sta.force_tdd = _FALSE; + break; + case BTCOEX_POLICY_CONTROL_FORCE_FREERUN: + GLBtCoexist.coex_sta.force_freerun = _TRUE; + GLBtCoexist.coex_sta.force_tdd = _FALSE; + break; + case BTCOEX_POLICY_CONTROL_FORCE_TDMA: + GLBtCoexist.coex_sta.force_freerun = _FALSE; + GLBtCoexist.coex_sta.force_tdd = _TRUE; + break; + } +} + u8 hal_btcoex_1Ant(PADAPTER padapter) { if (hal_btcoex_IsBtExist(padapter) == _FALSE) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_btcoex_wifionly.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_btcoex_wifionly.c index ab9e60415f41..21d1d2304324 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_btcoex_wifionly.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_btcoex_wifionly.c @@ -133,6 +133,11 @@ void hal_btcoex_wifionly_switchband_notify(PADAPTER padapter) else if (IS_HARDWARE_TYPE_8814B(padapter)) ex_hal8814b_wifi_only_switchbandnotify(&GLBtCoexistWifiOnly, is_5g); #endif + +#ifdef CONFIG_RTL8723F + else if (IS_HARDWARE_TYPE_8723F(padapter)) + ex_hal8723f_wifi_only_switchbandnotify(&GLBtCoexistWifiOnly, is_5g); +#endif } void hal_btcoex_wifionly_scan_notify(PADAPTER padapter) @@ -193,6 +198,11 @@ void hal_btcoex_wifionly_connect_notify(PADAPTER padapter) else if (IS_HARDWARE_TYPE_8814B(padapter)) ex_hal8814b_wifi_only_connectnotify(&GLBtCoexistWifiOnly, is_5g); #endif + +#ifdef CONFIG_RTL8723F + else if (IS_HARDWARE_TYPE_8723F(padapter)) + ex_hal8723f_wifi_only_connectnotify(&GLBtCoexistWifiOnly, is_5g); +#endif } void hal_btcoex_wifionly_hw_config(PADAPTER padapter) @@ -224,6 +234,11 @@ void hal_btcoex_wifionly_hw_config(PADAPTER padapter) else if (IS_HARDWARE_TYPE_8814B(padapter)) ex_hal8814b_wifi_only_hw_config(pwifionlycfg); #endif + +#ifdef CONFIG_RTL8723F + else if (IS_HARDWARE_TYPE_8723F(padapter)) + ex_hal8723f_wifi_only_hw_config(pwifionlycfg); +#endif } void hal_btcoex_wifionly_initlizevariables(PADAPTER padapter) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_com.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_com.c index 0794bd84297c..1a49503d7f20 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_com.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_com.c @@ -270,6 +270,10 @@ void dump_chip_info(HAL_VERSION ChipVersion) cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192F_"); else if (IS_8822C_SERIES(ChipVersion)) cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822C_"); + else if (IS_8814B_SERIES(ChipVersion)) + cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814B_"); + else if (IS_8723F_SERIES(ChipVersion)) + cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723F_"); else cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_"); @@ -339,12 +343,14 @@ u8 rtw_hal_get_port(_adapter *adapter) rtw_warn_on(1); } } + #ifdef CONFIG_AP_MODE else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) { if (hw_port != HW_PORT0) { RTW_ERR(ADPT_FMT" @@@@@ AP / MESH port != 0 @@@@@\n", ADPT_ARG(adapter)); rtw_warn_on(1); } } + #endif if (0) RTW_INFO(ADPT_FMT" - HP:%d,CP:%d\n", ADPT_ARG(adapter), get_hw_port(adapter), get_clt_port(adapter)); #endif /*DBG_HW_PORT*/ @@ -369,7 +375,6 @@ u8 rtw_hal_get_port(_adapter *adapter) * BIT[6:0] Channel Plan * sw_alpha2 country code from HW (registry/module param) * sw_chplan channel plan from SW (registry/module param) - * def_chplan channel plan used when HW/SW both invalid * AutoLoadFail efuse autoload fail or not * */ @@ -379,7 +384,6 @@ void hal_com_config_channel_plan( u8 hw_chplan, char *sw_alpha2, u8 sw_chplan, - u8 def_chplan, BOOLEAN AutoLoadFail ) { @@ -388,6 +392,7 @@ void hal_com_config_channel_plan( u8 force_hw_chplan = _FALSE; int chplan = -1; const struct country_chplan *country_ent = NULL, *ent; + u8 def_chplan = 0x7F; /* Realtek define, used when HW, SW both invalid */ pHalData = GET_HAL_DATA(padapter); @@ -488,539 +493,333 @@ HAL_IsLegalChannel( return bLegalChannel; } -u8 MRateToHwRate(u8 rate) +static const u8 _MRateToHwRate[MGN_UNKNOWN] = { + [MGN_1M] = DESC_RATE1M, + [MGN_2M] = DESC_RATE2M, + [MGN_5_5M] = DESC_RATE5_5M, + [MGN_11M] = DESC_RATE11M, + [MGN_6M] = DESC_RATE6M, + [MGN_9M] = DESC_RATE9M, + [MGN_12M] = DESC_RATE12M, + [MGN_18M] = DESC_RATE18M, + [MGN_24M] = DESC_RATE24M, + [MGN_36M] = DESC_RATE36M, + [MGN_48M] = DESC_RATE48M, + [MGN_54M] = DESC_RATE54M, + [MGN_MCS0] = DESC_RATEMCS0, + [MGN_MCS1] = DESC_RATEMCS1, + [MGN_MCS2] = DESC_RATEMCS2, + [MGN_MCS3] = DESC_RATEMCS3, + [MGN_MCS4] = DESC_RATEMCS4, + [MGN_MCS5] = DESC_RATEMCS5, + [MGN_MCS6] = DESC_RATEMCS6, + [MGN_MCS7] = DESC_RATEMCS7, + [MGN_MCS8] = DESC_RATEMCS8, + [MGN_MCS9] = DESC_RATEMCS9, + [MGN_MCS10] = DESC_RATEMCS10, + [MGN_MCS11] = DESC_RATEMCS11, + [MGN_MCS12] = DESC_RATEMCS12, + [MGN_MCS13] = DESC_RATEMCS13, + [MGN_MCS14] = DESC_RATEMCS14, + [MGN_MCS15] = DESC_RATEMCS15, + [MGN_MCS16] = DESC_RATEMCS16, + [MGN_MCS17] = DESC_RATEMCS17, + [MGN_MCS18] = DESC_RATEMCS18, + [MGN_MCS19] = DESC_RATEMCS19, + [MGN_MCS20] = DESC_RATEMCS20, + [MGN_MCS21] = DESC_RATEMCS21, + [MGN_MCS22] = DESC_RATEMCS22, + [MGN_MCS23] = DESC_RATEMCS23, + [MGN_MCS24] = DESC_RATEMCS24, + [MGN_MCS25] = DESC_RATEMCS25, + [MGN_MCS26] = DESC_RATEMCS26, + [MGN_MCS27] = DESC_RATEMCS27, + [MGN_MCS28] = DESC_RATEMCS28, + [MGN_MCS29] = DESC_RATEMCS29, + [MGN_MCS30] = DESC_RATEMCS30, + [MGN_MCS31] = DESC_RATEMCS31, + [MGN_VHT1SS_MCS0] = DESC_RATEVHTSS1MCS0, + [MGN_VHT1SS_MCS1] = DESC_RATEVHTSS1MCS1, + [MGN_VHT1SS_MCS2] = DESC_RATEVHTSS1MCS2, + [MGN_VHT1SS_MCS3] = DESC_RATEVHTSS1MCS3, + [MGN_VHT1SS_MCS4] = DESC_RATEVHTSS1MCS4, + [MGN_VHT1SS_MCS5] = DESC_RATEVHTSS1MCS5, + [MGN_VHT1SS_MCS6] = DESC_RATEVHTSS1MCS6, + [MGN_VHT1SS_MCS7] = DESC_RATEVHTSS1MCS7, + [MGN_VHT1SS_MCS8] = DESC_RATEVHTSS1MCS8, + [MGN_VHT1SS_MCS9] = DESC_RATEVHTSS1MCS9, + [MGN_VHT2SS_MCS0] = DESC_RATEVHTSS2MCS0, + [MGN_VHT2SS_MCS1] = DESC_RATEVHTSS2MCS1, + [MGN_VHT2SS_MCS2] = DESC_RATEVHTSS2MCS2, + [MGN_VHT2SS_MCS3] = DESC_RATEVHTSS2MCS3, + [MGN_VHT2SS_MCS4] = DESC_RATEVHTSS2MCS4, + [MGN_VHT2SS_MCS5] = DESC_RATEVHTSS2MCS5, + [MGN_VHT2SS_MCS6] = DESC_RATEVHTSS2MCS6, + [MGN_VHT2SS_MCS7] = DESC_RATEVHTSS2MCS7, + [MGN_VHT2SS_MCS8] = DESC_RATEVHTSS2MCS8, + [MGN_VHT2SS_MCS9] = DESC_RATEVHTSS2MCS9, + [MGN_VHT3SS_MCS0] = DESC_RATEVHTSS3MCS0, + [MGN_VHT3SS_MCS1] = DESC_RATEVHTSS3MCS1, + [MGN_VHT3SS_MCS2] = DESC_RATEVHTSS3MCS2, + [MGN_VHT3SS_MCS3] = DESC_RATEVHTSS3MCS3, + [MGN_VHT3SS_MCS4] = DESC_RATEVHTSS3MCS4, + [MGN_VHT3SS_MCS5] = DESC_RATEVHTSS3MCS5, + [MGN_VHT3SS_MCS6] = DESC_RATEVHTSS3MCS6, + [MGN_VHT3SS_MCS7] = DESC_RATEVHTSS3MCS7, + [MGN_VHT3SS_MCS8] = DESC_RATEVHTSS3MCS8, + [MGN_VHT3SS_MCS9] = DESC_RATEVHTSS3MCS9, + [MGN_VHT4SS_MCS0] = DESC_RATEVHTSS4MCS0, + [MGN_VHT4SS_MCS1] = DESC_RATEVHTSS4MCS1, + [MGN_VHT4SS_MCS2] = DESC_RATEVHTSS4MCS2, + [MGN_VHT4SS_MCS3] = DESC_RATEVHTSS4MCS3, + [MGN_VHT4SS_MCS4] = DESC_RATEVHTSS4MCS4, + [MGN_VHT4SS_MCS5] = DESC_RATEVHTSS4MCS5, + [MGN_VHT4SS_MCS6] = DESC_RATEVHTSS4MCS6, + [MGN_VHT4SS_MCS7] = DESC_RATEVHTSS4MCS7, + [MGN_VHT4SS_MCS8] = DESC_RATEVHTSS4MCS8, + [MGN_VHT4SS_MCS9] = DESC_RATEVHTSS4MCS9, +}; + +u8 MRateToHwRate(enum MGN_RATE rate) { - u8 ret = DESC_RATE1M; + u8 hw_rate = DESC_RATE1M; /* default value, also is zero */ - switch (rate) { - case MGN_1M: - ret = DESC_RATE1M; - break; - case MGN_2M: - ret = DESC_RATE2M; - break; - case MGN_5_5M: - ret = DESC_RATE5_5M; - break; - case MGN_11M: - ret = DESC_RATE11M; - break; - case MGN_6M: - ret = DESC_RATE6M; - break; - case MGN_9M: - ret = DESC_RATE9M; - break; - case MGN_12M: - ret = DESC_RATE12M; - break; - case MGN_18M: - ret = DESC_RATE18M; - break; - case MGN_24M: - ret = DESC_RATE24M; - break; - case MGN_36M: - ret = DESC_RATE36M; - break; - case MGN_48M: - ret = DESC_RATE48M; - break; - case MGN_54M: - ret = DESC_RATE54M; - break; + if (rate < MGN_UNKNOWN) + hw_rate = _MRateToHwRate[rate]; - case MGN_MCS0: - ret = DESC_RATEMCS0; - break; - case MGN_MCS1: - ret = DESC_RATEMCS1; - break; - case MGN_MCS2: - ret = DESC_RATEMCS2; - break; - case MGN_MCS3: - ret = DESC_RATEMCS3; - break; - case MGN_MCS4: - ret = DESC_RATEMCS4; - break; - case MGN_MCS5: - ret = DESC_RATEMCS5; - break; - case MGN_MCS6: - ret = DESC_RATEMCS6; - break; - case MGN_MCS7: - ret = DESC_RATEMCS7; - break; - case MGN_MCS8: - ret = DESC_RATEMCS8; - break; - case MGN_MCS9: - ret = DESC_RATEMCS9; - break; - case MGN_MCS10: - ret = DESC_RATEMCS10; - break; - case MGN_MCS11: - ret = DESC_RATEMCS11; - break; - case MGN_MCS12: - ret = DESC_RATEMCS12; - break; - case MGN_MCS13: - ret = DESC_RATEMCS13; - break; - case MGN_MCS14: - ret = DESC_RATEMCS14; - break; - case MGN_MCS15: - ret = DESC_RATEMCS15; - break; - case MGN_MCS16: - ret = DESC_RATEMCS16; - break; - case MGN_MCS17: - ret = DESC_RATEMCS17; - break; - case MGN_MCS18: - ret = DESC_RATEMCS18; - break; - case MGN_MCS19: - ret = DESC_RATEMCS19; - break; - case MGN_MCS20: - ret = DESC_RATEMCS20; - break; - case MGN_MCS21: - ret = DESC_RATEMCS21; - break; - case MGN_MCS22: - ret = DESC_RATEMCS22; - break; - case MGN_MCS23: - ret = DESC_RATEMCS23; - break; - case MGN_MCS24: - ret = DESC_RATEMCS24; - break; - case MGN_MCS25: - ret = DESC_RATEMCS25; - break; - case MGN_MCS26: - ret = DESC_RATEMCS26; - break; - case MGN_MCS27: - ret = DESC_RATEMCS27; - break; - case MGN_MCS28: - ret = DESC_RATEMCS28; - break; - case MGN_MCS29: - ret = DESC_RATEMCS29; - break; - case MGN_MCS30: - ret = DESC_RATEMCS30; - break; - case MGN_MCS31: - ret = DESC_RATEMCS31; - break; + if (rate != MGN_1M && hw_rate == DESC_RATE1M) + RTW_WARN("Invalid rate 0x%x in %s\n", rate, __FUNCTION__); - case MGN_VHT1SS_MCS0: - ret = DESC_RATEVHTSS1MCS0; - break; - case MGN_VHT1SS_MCS1: - ret = DESC_RATEVHTSS1MCS1; - break; - case MGN_VHT1SS_MCS2: - ret = DESC_RATEVHTSS1MCS2; - break; - case MGN_VHT1SS_MCS3: - ret = DESC_RATEVHTSS1MCS3; - break; - case MGN_VHT1SS_MCS4: - ret = DESC_RATEVHTSS1MCS4; - break; - case MGN_VHT1SS_MCS5: - ret = DESC_RATEVHTSS1MCS5; - break; - case MGN_VHT1SS_MCS6: - ret = DESC_RATEVHTSS1MCS6; - break; - case MGN_VHT1SS_MCS7: - ret = DESC_RATEVHTSS1MCS7; - break; - case MGN_VHT1SS_MCS8: - ret = DESC_RATEVHTSS1MCS8; - break; - case MGN_VHT1SS_MCS9: - ret = DESC_RATEVHTSS1MCS9; - break; - case MGN_VHT2SS_MCS0: - ret = DESC_RATEVHTSS2MCS0; - break; - case MGN_VHT2SS_MCS1: - ret = DESC_RATEVHTSS2MCS1; - break; - case MGN_VHT2SS_MCS2: - ret = DESC_RATEVHTSS2MCS2; - break; - case MGN_VHT2SS_MCS3: - ret = DESC_RATEVHTSS2MCS3; - break; - case MGN_VHT2SS_MCS4: - ret = DESC_RATEVHTSS2MCS4; - break; - case MGN_VHT2SS_MCS5: - ret = DESC_RATEVHTSS2MCS5; - break; - case MGN_VHT2SS_MCS6: - ret = DESC_RATEVHTSS2MCS6; - break; - case MGN_VHT2SS_MCS7: - ret = DESC_RATEVHTSS2MCS7; - break; - case MGN_VHT2SS_MCS8: - ret = DESC_RATEVHTSS2MCS8; - break; - case MGN_VHT2SS_MCS9: - ret = DESC_RATEVHTSS2MCS9; - break; - case MGN_VHT3SS_MCS0: - ret = DESC_RATEVHTSS3MCS0; - break; - case MGN_VHT3SS_MCS1: - ret = DESC_RATEVHTSS3MCS1; - break; - case MGN_VHT3SS_MCS2: - ret = DESC_RATEVHTSS3MCS2; - break; - case MGN_VHT3SS_MCS3: - ret = DESC_RATEVHTSS3MCS3; - break; - case MGN_VHT3SS_MCS4: - ret = DESC_RATEVHTSS3MCS4; - break; - case MGN_VHT3SS_MCS5: - ret = DESC_RATEVHTSS3MCS5; - break; - case MGN_VHT3SS_MCS6: - ret = DESC_RATEVHTSS3MCS6; - break; - case MGN_VHT3SS_MCS7: - ret = DESC_RATEVHTSS3MCS7; - break; - case MGN_VHT3SS_MCS8: - ret = DESC_RATEVHTSS3MCS8; - break; - case MGN_VHT3SS_MCS9: - ret = DESC_RATEVHTSS3MCS9; - break; - case MGN_VHT4SS_MCS0: - ret = DESC_RATEVHTSS4MCS0; - break; - case MGN_VHT4SS_MCS1: - ret = DESC_RATEVHTSS4MCS1; - break; - case MGN_VHT4SS_MCS2: - ret = DESC_RATEVHTSS4MCS2; - break; - case MGN_VHT4SS_MCS3: - ret = DESC_RATEVHTSS4MCS3; - break; - case MGN_VHT4SS_MCS4: - ret = DESC_RATEVHTSS4MCS4; - break; - case MGN_VHT4SS_MCS5: - ret = DESC_RATEVHTSS4MCS5; - break; - case MGN_VHT4SS_MCS6: - ret = DESC_RATEVHTSS4MCS6; - break; - case MGN_VHT4SS_MCS7: - ret = DESC_RATEVHTSS4MCS7; - break; - case MGN_VHT4SS_MCS8: - ret = DESC_RATEVHTSS4MCS8; - break; - case MGN_VHT4SS_MCS9: - ret = DESC_RATEVHTSS4MCS9; - break; - default: - break; - } - - return ret; + return hw_rate; } -u8 hw_rate_to_m_rate(u8 rate) +const char * const _HDATA_RATE[DESC_RATE_NUM + 1] = { + [DESC_RATE1M] = "CCK_1M", + [DESC_RATE2M] = "CCK_2M", + [DESC_RATE5_5M] = "CCK5_5M", + [DESC_RATE11M] = "CCK_11M", + [DESC_RATE6M] = "OFDM_6M", + [DESC_RATE9M] = "OFDM_9M", + [DESC_RATE12M] = "OFDM_12M", + [DESC_RATE18M] = "OFDM_18M", + [DESC_RATE24M] = "OFDM_24M", + [DESC_RATE36M] = "OFDM_36M", + [DESC_RATE48M] = "OFDM_48M", + [DESC_RATE54M] = "OFDM_54M", + [DESC_RATEMCS0] = "MCS0", + [DESC_RATEMCS1] = "MCS1", + [DESC_RATEMCS2] = "MCS2", + [DESC_RATEMCS3] = "MCS3", + [DESC_RATEMCS4] = "MCS4", + [DESC_RATEMCS5] = "MCS5", + [DESC_RATEMCS6] = "MCS6", + [DESC_RATEMCS7] = "MCS7", + [DESC_RATEMCS8] = "MCS8", + [DESC_RATEMCS9] = "MCS9", + [DESC_RATEMCS10] = "MCS10", + [DESC_RATEMCS11] = "MCS11", + [DESC_RATEMCS12] = "MCS12", + [DESC_RATEMCS13] = "MCS13", + [DESC_RATEMCS14] = "MCS14", + [DESC_RATEMCS15] = "MCS15", + [DESC_RATEMCS16] = "MCS16", + [DESC_RATEMCS17] = "MCS17", + [DESC_RATEMCS18] = "MCS18", + [DESC_RATEMCS19] = "MCS19", + [DESC_RATEMCS20] = "MCS20", + [DESC_RATEMCS21] = "MCS21", + [DESC_RATEMCS22] = "MCS22", + [DESC_RATEMCS23] = "MCS23", + [DESC_RATEMCS24] = "MCS24", + [DESC_RATEMCS25] = "MCS25", + [DESC_RATEMCS26] = "MCS26", + [DESC_RATEMCS27] = "MCS27", + [DESC_RATEMCS28] = "MCS28", + [DESC_RATEMCS29] = "MCS29", + [DESC_RATEMCS30] = "MCS30", + [DESC_RATEMCS31] = "MCS31", + [DESC_RATEVHTSS1MCS0] = "VHT1SMCS0", + [DESC_RATEVHTSS1MCS1] = "VHT1SMCS1", + [DESC_RATEVHTSS1MCS2] = "VHT1SMCS2", + [DESC_RATEVHTSS1MCS3] = "VHT1SMCS3", + [DESC_RATEVHTSS1MCS4] = "VHT1SMCS4", + [DESC_RATEVHTSS1MCS5] = "VHT1SMCS5", + [DESC_RATEVHTSS1MCS6] = "VHT1SMCS6", + [DESC_RATEVHTSS1MCS7] = "VHT1SMCS7", + [DESC_RATEVHTSS1MCS8] = "VHT1SMCS8", + [DESC_RATEVHTSS1MCS9] = "VHT1SMCS9", + [DESC_RATEVHTSS2MCS0] = "VHT2SMCS0", + [DESC_RATEVHTSS2MCS1] = "VHT2SMCS1", + [DESC_RATEVHTSS2MCS2] = "VHT2SMCS2", + [DESC_RATEVHTSS2MCS3] = "VHT2SMCS3", + [DESC_RATEVHTSS2MCS4] = "VHT2SMCS4", + [DESC_RATEVHTSS2MCS5] = "VHT2SMCS5", + [DESC_RATEVHTSS2MCS6] = "VHT2SMCS6", + [DESC_RATEVHTSS2MCS7] = "VHT2SMCS7", + [DESC_RATEVHTSS2MCS8] = "VHT2SMCS8", + [DESC_RATEVHTSS2MCS9] = "VHT2SMCS9", + [DESC_RATEVHTSS3MCS0] = "VHT3SMCS0", + [DESC_RATEVHTSS3MCS1] = "VHT3SMCS1", + [DESC_RATEVHTSS3MCS2] = "VHT3SMCS2", + [DESC_RATEVHTSS3MCS3] = "VHT3SMCS3", + [DESC_RATEVHTSS3MCS4] = "VHT3SMCS4", + [DESC_RATEVHTSS3MCS5] = "VHT3SMCS5", + [DESC_RATEVHTSS3MCS6] = "VHT3SMCS6", + [DESC_RATEVHTSS3MCS7] = "VHT3SMCS7", + [DESC_RATEVHTSS3MCS8] = "VHT3SMCS8", + [DESC_RATEVHTSS3MCS9] = "VHT3SMCS9", + [DESC_RATEVHTSS4MCS0] = "VHT4SMCS0", + [DESC_RATEVHTSS4MCS1] = "VHT4SMCS1", + [DESC_RATEVHTSS4MCS2] = "VHT4SMCS2", + [DESC_RATEVHTSS4MCS3] = "VHT4SMCS3", + [DESC_RATEVHTSS4MCS4] = "VHT4SMCS4", + [DESC_RATEVHTSS4MCS5] = "VHT4SMCS5", + [DESC_RATEVHTSS4MCS6] = "VHT4SMCS6", + [DESC_RATEVHTSS4MCS7] = "VHT4SMCS7", + [DESC_RATEVHTSS4MCS8] = "VHT4SMCS8", + [DESC_RATEVHTSS4MCS9] = "VHT4SMCS9", + [DESC_RATE_NUM] = "UNKNOWN", +}; + +static const u8 _hw_rate_to_m_rate[DESC_RATE_NUM] = { + [DESC_RATE1M] = MGN_1M, + [DESC_RATE2M] = MGN_2M, + [DESC_RATE5_5M] = MGN_5_5M, + [DESC_RATE11M] = MGN_11M, + [DESC_RATE6M] = MGN_6M, + [DESC_RATE9M] = MGN_9M, + [DESC_RATE12M] = MGN_12M, + [DESC_RATE18M] = MGN_18M, + [DESC_RATE24M] = MGN_24M, + [DESC_RATE36M] = MGN_36M, + [DESC_RATE48M] = MGN_48M, + [DESC_RATE54M] = MGN_54M, + [DESC_RATEMCS0] = MGN_MCS0, + [DESC_RATEMCS1] = MGN_MCS1, + [DESC_RATEMCS2] = MGN_MCS2, + [DESC_RATEMCS3] = MGN_MCS3, + [DESC_RATEMCS4] = MGN_MCS4, + [DESC_RATEMCS5] = MGN_MCS5, + [DESC_RATEMCS6] = MGN_MCS6, + [DESC_RATEMCS7] = MGN_MCS7, + [DESC_RATEMCS8] = MGN_MCS8, + [DESC_RATEMCS9] = MGN_MCS9, + [DESC_RATEMCS10] = MGN_MCS10, + [DESC_RATEMCS11] = MGN_MCS11, + [DESC_RATEMCS12] = MGN_MCS12, + [DESC_RATEMCS13] = MGN_MCS13, + [DESC_RATEMCS14] = MGN_MCS14, + [DESC_RATEMCS15] = MGN_MCS15, + [DESC_RATEMCS16] = MGN_MCS16, + [DESC_RATEMCS17] = MGN_MCS17, + [DESC_RATEMCS18] = MGN_MCS18, + [DESC_RATEMCS19] = MGN_MCS19, + [DESC_RATEMCS20] = MGN_MCS20, + [DESC_RATEMCS21] = MGN_MCS21, + [DESC_RATEMCS22] = MGN_MCS22, + [DESC_RATEMCS23] = MGN_MCS23, + [DESC_RATEMCS24] = MGN_MCS24, + [DESC_RATEMCS25] = MGN_MCS25, + [DESC_RATEMCS26] = MGN_MCS26, + [DESC_RATEMCS27] = MGN_MCS27, + [DESC_RATEMCS28] = MGN_MCS28, + [DESC_RATEMCS29] = MGN_MCS29, + [DESC_RATEMCS30] = MGN_MCS30, + [DESC_RATEMCS31] = MGN_MCS31, + [DESC_RATEVHTSS1MCS0] = MGN_VHT1SS_MCS0, + [DESC_RATEVHTSS1MCS1] = MGN_VHT1SS_MCS1, + [DESC_RATEVHTSS1MCS2] = MGN_VHT1SS_MCS2, + [DESC_RATEVHTSS1MCS3] = MGN_VHT1SS_MCS3, + [DESC_RATEVHTSS1MCS4] = MGN_VHT1SS_MCS4, + [DESC_RATEVHTSS1MCS5] = MGN_VHT1SS_MCS5, + [DESC_RATEVHTSS1MCS6] = MGN_VHT1SS_MCS6, + [DESC_RATEVHTSS1MCS7] = MGN_VHT1SS_MCS7, + [DESC_RATEVHTSS1MCS8] = MGN_VHT1SS_MCS8, + [DESC_RATEVHTSS1MCS9] = MGN_VHT1SS_MCS9, + [DESC_RATEVHTSS2MCS0] = MGN_VHT2SS_MCS0, + [DESC_RATEVHTSS2MCS1] = MGN_VHT2SS_MCS1, + [DESC_RATEVHTSS2MCS2] = MGN_VHT2SS_MCS2, + [DESC_RATEVHTSS2MCS3] = MGN_VHT2SS_MCS3, + [DESC_RATEVHTSS2MCS4] = MGN_VHT2SS_MCS4, + [DESC_RATEVHTSS2MCS5] = MGN_VHT2SS_MCS5, + [DESC_RATEVHTSS2MCS6] = MGN_VHT2SS_MCS6, + [DESC_RATEVHTSS2MCS7] = MGN_VHT2SS_MCS7, + [DESC_RATEVHTSS2MCS8] = MGN_VHT2SS_MCS8, + [DESC_RATEVHTSS2MCS9] = MGN_VHT2SS_MCS9, + [DESC_RATEVHTSS3MCS0] = MGN_VHT3SS_MCS0, + [DESC_RATEVHTSS3MCS1] = MGN_VHT3SS_MCS1, + [DESC_RATEVHTSS3MCS2] = MGN_VHT3SS_MCS2, + [DESC_RATEVHTSS3MCS3] = MGN_VHT3SS_MCS3, + [DESC_RATEVHTSS3MCS4] = MGN_VHT3SS_MCS4, + [DESC_RATEVHTSS3MCS5] = MGN_VHT3SS_MCS5, + [DESC_RATEVHTSS3MCS6] = MGN_VHT3SS_MCS6, + [DESC_RATEVHTSS3MCS7] = MGN_VHT3SS_MCS7, + [DESC_RATEVHTSS3MCS8] = MGN_VHT3SS_MCS8, + [DESC_RATEVHTSS3MCS9] = MGN_VHT3SS_MCS9, + [DESC_RATEVHTSS4MCS0] = MGN_VHT4SS_MCS0, + [DESC_RATEVHTSS4MCS1] = MGN_VHT4SS_MCS1, + [DESC_RATEVHTSS4MCS2] = MGN_VHT4SS_MCS2, + [DESC_RATEVHTSS4MCS3] = MGN_VHT4SS_MCS3, + [DESC_RATEVHTSS4MCS4] = MGN_VHT4SS_MCS4, + [DESC_RATEVHTSS4MCS5] = MGN_VHT4SS_MCS5, + [DESC_RATEVHTSS4MCS6] = MGN_VHT4SS_MCS6, + [DESC_RATEVHTSS4MCS7] = MGN_VHT4SS_MCS7, + [DESC_RATEVHTSS4MCS8] = MGN_VHT4SS_MCS8, + [DESC_RATEVHTSS4MCS9] = MGN_VHT4SS_MCS9, +}; + +u8 hw_rate_to_m_rate(u8 hw_rate) { - u8 ret_rate = MGN_1M; + u8 rate = MGN_1M; /* default value */ - switch (rate) { + if (hw_rate < DESC_RATE_NUM) + rate = _hw_rate_to_m_rate[hw_rate]; + else + RTW_WARN("Invalid hw_rate 0x%x in %s\n", hw_rate, __FUNCTION__); - case DESC_RATE1M: - ret_rate = MGN_1M; - break; - case DESC_RATE2M: - ret_rate = MGN_2M; - break; - case DESC_RATE5_5M: - ret_rate = MGN_5_5M; - break; - case DESC_RATE11M: - ret_rate = MGN_11M; - break; - case DESC_RATE6M: - ret_rate = MGN_6M; - break; - case DESC_RATE9M: - ret_rate = MGN_9M; - break; - case DESC_RATE12M: - ret_rate = MGN_12M; - break; - case DESC_RATE18M: - ret_rate = MGN_18M; - break; - case DESC_RATE24M: - ret_rate = MGN_24M; - break; - case DESC_RATE36M: - ret_rate = MGN_36M; - break; - case DESC_RATE48M: - ret_rate = MGN_48M; - break; - case DESC_RATE54M: - ret_rate = MGN_54M; - break; - case DESC_RATEMCS0: - ret_rate = MGN_MCS0; - break; - case DESC_RATEMCS1: - ret_rate = MGN_MCS1; - break; - case DESC_RATEMCS2: - ret_rate = MGN_MCS2; - break; - case DESC_RATEMCS3: - ret_rate = MGN_MCS3; - break; - case DESC_RATEMCS4: - ret_rate = MGN_MCS4; - break; - case DESC_RATEMCS5: - ret_rate = MGN_MCS5; - break; - case DESC_RATEMCS6: - ret_rate = MGN_MCS6; - break; - case DESC_RATEMCS7: - ret_rate = MGN_MCS7; - break; - case DESC_RATEMCS8: - ret_rate = MGN_MCS8; - break; - case DESC_RATEMCS9: - ret_rate = MGN_MCS9; - break; - case DESC_RATEMCS10: - ret_rate = MGN_MCS10; - break; - case DESC_RATEMCS11: - ret_rate = MGN_MCS11; - break; - case DESC_RATEMCS12: - ret_rate = MGN_MCS12; - break; - case DESC_RATEMCS13: - ret_rate = MGN_MCS13; - break; - case DESC_RATEMCS14: - ret_rate = MGN_MCS14; - break; - case DESC_RATEMCS15: - ret_rate = MGN_MCS15; - break; - case DESC_RATEMCS16: - ret_rate = MGN_MCS16; - break; - case DESC_RATEMCS17: - ret_rate = MGN_MCS17; - break; - case DESC_RATEMCS18: - ret_rate = MGN_MCS18; - break; - case DESC_RATEMCS19: - ret_rate = MGN_MCS19; - break; - case DESC_RATEMCS20: - ret_rate = MGN_MCS20; - break; - case DESC_RATEMCS21: - ret_rate = MGN_MCS21; - break; - case DESC_RATEMCS22: - ret_rate = MGN_MCS22; - break; - case DESC_RATEMCS23: - ret_rate = MGN_MCS23; - break; - case DESC_RATEMCS24: - ret_rate = MGN_MCS24; - break; - case DESC_RATEMCS25: - ret_rate = MGN_MCS25; - break; - case DESC_RATEMCS26: - ret_rate = MGN_MCS26; - break; - case DESC_RATEMCS27: - ret_rate = MGN_MCS27; - break; - case DESC_RATEMCS28: - ret_rate = MGN_MCS28; - break; - case DESC_RATEMCS29: - ret_rate = MGN_MCS29; - break; - case DESC_RATEMCS30: - ret_rate = MGN_MCS30; - break; - case DESC_RATEMCS31: - ret_rate = MGN_MCS31; - break; - case DESC_RATEVHTSS1MCS0: - ret_rate = MGN_VHT1SS_MCS0; - break; - case DESC_RATEVHTSS1MCS1: - ret_rate = MGN_VHT1SS_MCS1; - break; - case DESC_RATEVHTSS1MCS2: - ret_rate = MGN_VHT1SS_MCS2; - break; - case DESC_RATEVHTSS1MCS3: - ret_rate = MGN_VHT1SS_MCS3; - break; - case DESC_RATEVHTSS1MCS4: - ret_rate = MGN_VHT1SS_MCS4; - break; - case DESC_RATEVHTSS1MCS5: - ret_rate = MGN_VHT1SS_MCS5; - break; - case DESC_RATEVHTSS1MCS6: - ret_rate = MGN_VHT1SS_MCS6; - break; - case DESC_RATEVHTSS1MCS7: - ret_rate = MGN_VHT1SS_MCS7; - break; - case DESC_RATEVHTSS1MCS8: - ret_rate = MGN_VHT1SS_MCS8; - break; - case DESC_RATEVHTSS1MCS9: - ret_rate = MGN_VHT1SS_MCS9; - break; - case DESC_RATEVHTSS2MCS0: - ret_rate = MGN_VHT2SS_MCS0; - break; - case DESC_RATEVHTSS2MCS1: - ret_rate = MGN_VHT2SS_MCS1; - break; - case DESC_RATEVHTSS2MCS2: - ret_rate = MGN_VHT2SS_MCS2; - break; - case DESC_RATEVHTSS2MCS3: - ret_rate = MGN_VHT2SS_MCS3; - break; - case DESC_RATEVHTSS2MCS4: - ret_rate = MGN_VHT2SS_MCS4; - break; - case DESC_RATEVHTSS2MCS5: - ret_rate = MGN_VHT2SS_MCS5; - break; - case DESC_RATEVHTSS2MCS6: - ret_rate = MGN_VHT2SS_MCS6; - break; - case DESC_RATEVHTSS2MCS7: - ret_rate = MGN_VHT2SS_MCS7; - break; - case DESC_RATEVHTSS2MCS8: - ret_rate = MGN_VHT2SS_MCS8; - break; - case DESC_RATEVHTSS2MCS9: - ret_rate = MGN_VHT2SS_MCS9; - break; - case DESC_RATEVHTSS3MCS0: - ret_rate = MGN_VHT3SS_MCS0; - break; - case DESC_RATEVHTSS3MCS1: - ret_rate = MGN_VHT3SS_MCS1; - break; - case DESC_RATEVHTSS3MCS2: - ret_rate = MGN_VHT3SS_MCS2; - break; - case DESC_RATEVHTSS3MCS3: - ret_rate = MGN_VHT3SS_MCS3; - break; - case DESC_RATEVHTSS3MCS4: - ret_rate = MGN_VHT3SS_MCS4; - break; - case DESC_RATEVHTSS3MCS5: - ret_rate = MGN_VHT3SS_MCS5; - break; - case DESC_RATEVHTSS3MCS6: - ret_rate = MGN_VHT3SS_MCS6; - break; - case DESC_RATEVHTSS3MCS7: - ret_rate = MGN_VHT3SS_MCS7; - break; - case DESC_RATEVHTSS3MCS8: - ret_rate = MGN_VHT3SS_MCS8; - break; - case DESC_RATEVHTSS3MCS9: - ret_rate = MGN_VHT3SS_MCS9; - break; - case DESC_RATEVHTSS4MCS0: - ret_rate = MGN_VHT4SS_MCS0; - break; - case DESC_RATEVHTSS4MCS1: - ret_rate = MGN_VHT4SS_MCS1; - break; - case DESC_RATEVHTSS4MCS2: - ret_rate = MGN_VHT4SS_MCS2; - break; - case DESC_RATEVHTSS4MCS3: - ret_rate = MGN_VHT4SS_MCS3; - break; - case DESC_RATEVHTSS4MCS4: - ret_rate = MGN_VHT4SS_MCS4; - break; - case DESC_RATEVHTSS4MCS5: - ret_rate = MGN_VHT4SS_MCS5; - break; - case DESC_RATEVHTSS4MCS6: - ret_rate = MGN_VHT4SS_MCS6; - break; - case DESC_RATEVHTSS4MCS7: - ret_rate = MGN_VHT4SS_MCS7; - break; - case DESC_RATEVHTSS4MCS8: - ret_rate = MGN_VHT4SS_MCS8; - break; - case DESC_RATEVHTSS4MCS9: - ret_rate = MGN_VHT4SS_MCS9; - break; - - default: - RTW_INFO("hw_rate_to_m_rate(): Non supported Rate [%x]!!!\n", rate); - break; - } - - return ret_rate; + return rate; } +#ifdef CONFIG_RTW_DEBUG +void dump_hw_rate_map_test(void *sel) +{ + RATE_SECTION rs; + u8 hw_rate; + enum MGN_RATE m_rate; + int i; + + for (rs = 0; rs < RATE_SECTION_NUM; rs++) { + for (i = 0; i < rates_by_sections[rs].rate_num; i++) { + hw_rate = MRateToHwRate(rates_by_sections[rs].rates[i]); + RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n" + , MGN_RATE_STR(rates_by_sections[rs].rates[i]), rates_by_sections[rs].rates[i] + , HDATA_RATE(hw_rate), hw_rate + ); + } + if (rs == HT_4SS) { /* show MCS32 after MCS31 */ + hw_rate = MRateToHwRate(MGN_MCS32); + RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n" + , MGN_RATE_STR(MGN_MCS32), MGN_MCS32 + , HDATA_RATE(hw_rate), hw_rate + ); + } + } + hw_rate = MRateToHwRate(MGN_UNKNOWN); + RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n" + , MGN_RATE_STR(MGN_UNKNOWN), MGN_UNKNOWN + , HDATA_RATE(hw_rate), hw_rate + ); + + for (i = DESC_RATE1M; i <= DESC_RATE_NUM; i++) { + m_rate = hw_rate_to_m_rate(i); + RTW_PRINT_SEL(sel, "hw_rate:%s(%d) to m_rate:%s(%d)\n" + , HDATA_RATE(i), i + , MGN_RATE_STR(m_rate), m_rate + ); + } +} +#endif /* CONFIG_RTW_DEBUG */ + void HalSetBrateCfg( PADAPTER Adapter, u8 *mBratesOS, @@ -1342,7 +1141,7 @@ void rtw_mi_set_mac_addr(_adapter *adapter) rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface)); } #endif - if (1) + if (0) rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter); } @@ -2177,8 +1976,12 @@ int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len) status_code = GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(data); /* action=0: report force leave null data status */ + /* action=1: report Rf on status when receiving a SetPwrMode H2C with PwrState = RFON */ switch (action) { - case 0: + case 0: + /* status code 0: success, 1: no ack, 2: timeout, 3: cancel */ + case 1: + /* status code 0: FW has already turn to RFON */ pwrpriv->lps_ack_status = status_code; if (DBG_LPS_STATUS_RPT) @@ -3466,7 +3269,7 @@ static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr) } #endif /* !RTW_HALMAC */ - RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__, + RTW_DBG("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__, ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr)); } #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/ @@ -3878,6 +3681,15 @@ void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action) #endif #endif /* CONFIG_MI_WITH_MBSSID_CAM */ +#ifdef CONFIG_RTW_MULTI_AP + if (MSTATE_AP_NUM(&mstate) + && rtw_unassoc_sta_src_chk(adapter, UNASOC_STA_SRC_RX_NMY_UC) + ) { + rcr_new |= RCR_AAP; + } else + rcr_new &= ~RCR_AAP; +#endif + if (rcr == rcr_new) return; @@ -3893,6 +3705,11 @@ void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action) rtw_hal_tsf_update_restore(adapter); } +void rtw_hal_rcr_set_chk_bssid_act_non(_adapter *adapter) +{ + rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE); +} + static void hw_var_set_rcr_am(_adapter *adapter, u8 enable) { u32 rcr = RCR_AM; @@ -4077,9 +3894,6 @@ void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_con void rtw_hal_update_tx_aclt(_adapter *adapter) { -#ifdef CONFIG_TX_MCAST2UNI - extern int rtw_mc2u_disable; -#endif struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter); u8 lt_en = 0, lt_en_ori; @@ -4087,6 +3901,24 @@ void rtw_hal_update_tx_aclt(_adapter *adapter) u32 lt, lt_ori; struct tx_aclt_conf_t *conf; int i; +#ifdef CONFIG_AP_MODE +#if CONFIG_RTW_AP_DATA_BMC_TO_UC + _adapter *iface; + u8 ap_m2u_num = 0; + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (!iface) + continue; + + if (MLME_IS_AP(iface) + && ((iface->b2u_flags_ap_src & RTW_AP_B2U_IP_MCAST) + || (iface->b2u_flags_ap_fwd & RTW_AP_B2U_IP_MCAST)) + ) + ap_m2u_num++; + } +#endif +#endif /* CONFIG_AP_MODE */ lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN); lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME); @@ -4105,11 +3937,12 @@ void rtw_hal_update_tx_aclt(_adapter *adapter) if (conf->be_bk) lt_be_bk = conf->be_bk; } - #if defined(CONFIG_TX_MCAST2UNI) || defined(CONFIG_RTW_MESH) + #ifdef CONFIG_AP_MODE + #if CONFIG_RTW_AP_DATA_BMC_TO_UC || defined(CONFIG_RTW_MESH) else if (0 - #ifdef CONFIG_TX_MCAST2UNI + #if CONFIG_RTW_AP_DATA_BMC_TO_UC || (i == TX_ACLT_CONF_AP_M2U - && !rtw_mc2u_disable + && ap_m2u_num && macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */) #endif #ifdef CONFIG_RTW_MESH @@ -4125,6 +3958,7 @@ void rtw_hal_update_tx_aclt(_adapter *adapter) lt_be_bk = conf->be_bk; } #endif + #endif /* CONFIG_AP_MODE */ } if (dvobj->tx_aclt_force_val.en != 0xFF) @@ -4708,6 +4542,49 @@ void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state) #endif /* RTW_HALMAC */ #endif /* CONFIG_P2P */ +#if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR) +static void _rtw_hal_dtp_macid_set( + _adapter *padapter, u8 opmode, u8 mac_id) +{ + struct macid_ctl_t *macid_ctl = &(padapter->dvobj->macid_ctl); + struct sta_info *psta; + u8 h2c_cmd[H2C_FW_CRC5_SEARCH_LEN] = {0}; + u8 mac_addr[ETH_ALEN] = {0}; + + if (opmode) { + psta = macid_ctl->sta[mac_id]; + if (psta) + _rtw_memcpy(mac_addr, psta->cmn.mac_addr, ETH_ALEN); + + if (rtw_check_invalid_mac_address(mac_addr, _FALSE)) + return; + } + /* else DON'T CARE H2C_FW_CRC5_SEARCH mac addr in disconnected case */ + + if (rtw_get_chip_type(padapter) == RTL8822C) { + SET_H2CCMD_FW_CRC5_SEARCH_EN(h2c_cmd, opmode); + SET_H2CCMD_FW_CRC5_SEARCH_MACID(h2c_cmd, mac_id); + SET_H2CCMD_FW_CRC5_SEARCH_MAC(&h2c_cmd[1], mac_addr); + if (rtw_hal_fill_h2c_cmd(padapter, H2C_FW_CRC5_SEARCH, + H2C_FW_CRC5_SEARCH_LEN, h2c_cmd) != _SUCCESS) + RTW_WARN("%s : set h2c - 0x%02x fail!\n", __func__, H2C_FW_CRC5_SEARCH); + } +} + +static void rtw_hal_dtp_macid_set(_adapter *padapter, u8 opmode, + bool macid_ind, u8 mac_id, u8 macid_end) +{ + int i; + + if (macid_ind == 0) { + _rtw_hal_dtp_macid_set(padapter, opmode, mac_id); + } else { + for (i = mac_id; i <= macid_end; i++) + _rtw_hal_dtp_macid_set(padapter, opmode, i); + } +} +#endif + /* * rtw_hal_set_FwMediaStatusRpt_cmd - * @@ -4731,6 +4608,10 @@ s32 rtw_hal_set_FwMediaStatusRpt_cmd(_adapter *adapter, bool opmode, bool miraca #endif u8 op_num_change_bmp = 0; +#if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR) + rtw_hal_dtp_macid_set(adapter, opmode, macid_ind, macid, macid_end); +#endif + SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode); SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind); SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast); @@ -4866,7 +4747,7 @@ void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable) void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval) { #if defined(CONFIG_RTL8192F) - rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&index)); + rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&outputval)); #else if (index <= 7) { /* config GPIO mode */ @@ -5106,6 +4987,7 @@ int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset, void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num) { +#if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG) u32 page_size = 0; u8 *buffer = NULL; u32 buf_size = 0; @@ -5131,6 +5013,7 @@ void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_nu RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n"); RTW_PRINT_SEL(sel, "==========================\n"); +#endif } #ifdef CONFIG_SUPPORT_FIFO_DUMP @@ -5710,7 +5593,31 @@ static void rtw_hal_update_sw_security_info(_adapter *adapter) _rtw_memset(psecpriv->iv_seq, 0, sz); #endif } +#ifdef CONFIG_CUSTOM_PULSE +static u8 rtw_hal_set_gpio_custom_cmd(_adapter *adapter, u8 enable) +{ + u8 H2CGpioCustomParm[H2C_GPIO_CUSTOM_LEN] = {0}; + u8 customid = 0x2, special_wakeup_reason = RX_MAGIC_PKT, custom_for_wakeup_reason=0x1; + u8 ret = _FAIL; + RTW_INFO("%s(): enable = %d\n", __func__, enable); + + if(enable) { + SET_H2CCMD_CUSTOMERID(H2CGpioCustomParm, customid); + SET_H2CCMD_SPECIAL_WAKE_REASON(H2CGpioCustomParm, special_wakeup_reason); + SET_H2CCMD_CUSTOM_WAKE_REASON(H2CGpioCustomParm, custom_for_wakeup_reason); + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_GPIO_CUSTOM, + H2C_GPIO_CUSTOM_LEN, + H2CGpioCustomParm); + RTW_DBG("%s(): H2C_cmd=%x, cmd=%02x, %02x, %02x\n", __func__, H2C_GPIO_CUSTOM, + H2CGpioCustomParm[0], H2CGpioCustomParm[1], H2CGpioCustomParm[2]); + } + + return ret; +} +#endif /* CONFIG_CUSTOM_PULSE */ static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type) { u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0}; @@ -5736,16 +5643,78 @@ static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type) return ret; } +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +static u8 rtw_hal_set_keep_alive_pattern_cmd(PADAPTER adapter, u8 enable) +{ + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter); + u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_PATTERN_LEN] = {0}; + u8 ret = _FAIL; + int i; + + /* If keep alive pattern is set, FW will use pattern for keep alive action */ + if(enable == 0 || (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_disable)) { + SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _FALSE); + SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE); + SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE); + return ret; + } + /*step1:set keep alive period*/ + SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_LOW_BIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_period & 0x00FF); + SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_HI_BIT(u1H2CKeepAliveParm, ((pwrctl->wowlan_keep_alive_period & 0xFF00)>> 8)); + + if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_tx) { + SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE); + SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE); + SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE); + SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc); + goto exit; + } + if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx) { + SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE); + SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE); + SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE); + SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc); + SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index); + SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval); + SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter); + goto exit; + } + if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx_with_ack) { + SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE); + SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE); + SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _TRUE); + SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc); + SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index); + SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_wake_pattern_index); + SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval); + SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter); + goto exit; + } +exit: + for(i=0; iregistrypriv; u8 hw_port = rtw_hal_get_port(adapter); SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable); SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt); - /* SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt); */ + if (!(pregistry->wakeup_event & BIT(2))) + SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt); SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period); SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num); #ifdef CONFIG_FW_MULTI_PORT_SUPPORT @@ -5783,7 +5752,7 @@ static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_un #ifdef CONFIG_GPIO_WAKEUP gpio_high_active = ppwrpriv->is_high_active; - gpionum = WAKEUP_GPIO_IDX; + gpionum = ppwrpriv->wowlan_gpio_index; sdio_wakeup_enable = 0; #endif /* CONFIG_GPIO_WAKEUP */ @@ -5887,6 +5856,7 @@ static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable) struct security_priv *psecuritypriv = &(adapter->securitypriv); struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter); struct registry_priv *pregistrypriv = &adapter->registrypriv; + u8 arp_en = pregistrypriv->wakeup_event & BIT(3); u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0}; u8 ret = _FAIL, count = 0, no_wake = 0; struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); @@ -5903,8 +5873,12 @@ static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable) if (!ppwrpriv->wowlan_pno_enable) { SET_H2CCMD_REMOTE_WAKECTRL_ENABLE( u1H2CRemoteWakeCtrlParm, enable); - SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN( - u1H2CRemoteWakeCtrlParm, 1); + if (arp_en) + SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN( + u1H2CRemoteWakeCtrlParm, 1); + else + SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN( + u1H2CRemoteWakeCtrlParm, 0); #ifdef CONFIG_GTK_OL if (psecuritypriv->binstallKCK_KEK == _TRUE && (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) { @@ -5946,9 +5920,10 @@ static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable) (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) { SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION( u1H2CRemoteWakeCtrlParm, 0); - } else { - SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION( - u1H2CRemoteWakeCtrlParm, 1); + } else { /* WEP etc. */ + if (arp_en) + SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION( + u1H2CRemoteWakeCtrlParm, 1); } if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) { @@ -5961,8 +5936,9 @@ static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable) IS_HARDWARE_TYPE_8812(adapter)) { SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN( u1H2CRemoteWakeCtrlParm, 0); - SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION( - u1H2CRemoteWakeCtrlParm, 1); + if (arp_en) + SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION( + u1H2CRemoteWakeCtrlParm, 1); } } @@ -5997,6 +5973,67 @@ static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable) return ret; } +#ifdef CONFIG_WAR_OFFLOAD +static u8 rtw_hal_set_war_offload_ctrl_cmd(_adapter *adapter, u8 enable) +{ + struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter); + u8 u1H2CWarOffloadParm[H2C_WAR_OFFLOAD_LEN] = {0}; + u8 ret = _FAIL; + + RTW_INFO("%s(): enable=%d\n", __func__, enable); + + if (_TRUE == ppwrpriv->wowlan_war_offload_mode) { + SET_H2CCMD_WAR_CFG_EN(u1H2CWarOffloadParm, enable); + SET_H2CCMD_WAR_CFG_ARP_RSP_EN(u1H2CWarOffloadParm, 1); + +#ifdef CONFIG_OFFLOAD_MDNS_V4 + if (WAR_MDNS_V4_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) { + SET_H2CCMD_WAR_CFG_MDNSV4_RSP_EN(u1H2CWarOffloadParm, 1); + } + if (WAR_MDNS_V4_WAKEUP_EN& ppwrpriv->wowlan_war_offload_ctrl) { + SET_H2CCMD_WAR_CFG_MDNSV4_WAKE_EN(u1H2CWarOffloadParm, 1); + } +#endif /* CONFIG_OFFLOAD_MDNS_V4 */ + +#ifdef CONFIG_OFFLOAD_MDNS_V6 + if (WAR_MDNS_V6_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) { + SET_H2CCMD_WAR_CFG_MDNSV6_RSP_EN(u1H2CWarOffloadParm, 1); + } + if (WAR_MDNS_V6_WAKEUP_EN & ppwrpriv->wowlan_war_offload_ctrl) { + SET_H2CCMD_WAR_CFG_MDNSV6_WAKE_EN(u1H2CWarOffloadParm, 1); + } +#endif /* CONFIG_OFFLOAD_MDNS_V6 */ + + } + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_WAR_OFFLOAD, + H2C_WAR_OFFLOAD_LEN, + u1H2CWarOffloadParm); + return ret; +} + +static u8 rtw_hal_set_war_offload_parm(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc) +{ + struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter); + u8 u1H2CWarOfldParm[H2C_WAROFLD_RSVDPAGE1_LEN] = {0}; + u8 ret = _FAIL; + + SET_H2CCMD_WAROFLD_RSVDPAGE1_LOC_PARM(u1H2CWarOfldParm, rsvdpageloc->LocIpParm); + RTW_INFO("%s(): LocIpParm = %d\n", __func__, rsvdpageloc->LocIpParm); + + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_WAROFLD_RSVDPAGE1, + H2C_WAROFLD_RSVDPAGE1_LEN, + u1H2CWarOfldParm); + + return ret; +} +#endif /* CONFIG_WAR_OFFLOAD */ + + + static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg) { u8 ret = _FAIL; @@ -6070,7 +6107,7 @@ void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable) psecpriv->dot11PrivacyAlgrthm); if (!(ppwrpriv->wowlan_pno_enable)) { - if (pregistry->wakeup_event & BIT(2) && !no_wake) + if (!no_wake) rtw_hal_set_disconnect_decision_cmd(padapter, enable); #ifdef CONFIG_ARP_KEEP_ALIVE @@ -6082,13 +6119,20 @@ void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable) #else pkt_type = 0; #endif /* CONFIG_ARP_KEEP_ALIVE */ - if(!no_wake) + if(!no_wake) { + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + rtw_hal_set_keep_alive_pattern_cmd(padapter,enable); + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type); + } } - rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable); #ifdef CONFIG_PNO_SUPPORT rtw_hal_check_pno_enabled(padapter); #endif /* CONFIG_PNO_SUPPORT */ +#ifdef CONFIG_WAR_OFFLOAD + rtw_hal_set_war_offload_ctrl_cmd(padapter, enable); +#endif /* CONFIG_WAR_OFFLOAD */ + } else { #if 0 { @@ -6097,9 +6141,11 @@ void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable) dump_TX_FIFO(padapter, 4, PageSize); } #endif - - rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable); } +#ifdef CONFIG_CUSTOM_PULSE + rtw_hal_set_gpio_custom_cmd(padapter, enable); +#endif /* CONFIG_CUSTOM_PULSE */ + rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable); RTW_PRINT("-%s()-\n", __func__); } #endif /* CONFIG_WOWLAN */ @@ -6118,7 +6164,7 @@ static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable) #ifdef CONFIG_GPIO_WAKEUP gpio_high_active = ppwrpriv->is_high_active; - gpionum = WAKEUP_GPIO_IDX; + gpionum = ppwrpriv->wowlan_gpio_index; sdio_wakeup_enable = 0; #endif /*CONFIG_GPIO_WAKEUP*/ @@ -6239,6 +6285,7 @@ static void rtw_hal_ap_wow_enable(_adapter *padapter) { struct security_priv *psecuritypriv = &padapter->securitypriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); struct sta_info *psta = NULL; PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); #ifdef DBG_CHECK_FW_PS_STATE @@ -6247,6 +6294,9 @@ static void rtw_hal_ap_wow_enable(_adapter *padapter) #endif /*DBG_CHECK_FW_PS_STATE*/ int res; u16 media_status_rpt; +#ifdef CONFIG_GPIO_WAKEUP + u8 val8 = 0; +#endif RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__); #ifdef DBG_CHECK_FW_PS_STATE @@ -6283,8 +6333,28 @@ static void rtw_hal_ap_wow_enable(_adapter *padapter) #endif #ifdef CONFIG_GPIO_WAKEUP - rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE); -#endif +#ifdef CONFIG_RTW_ONE_PIN_GPIO + rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE); + rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index); +#else +#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE + if (pwrctrlpriv->is_high_active == 0) + rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index); + else + rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, + GPIO_OUTPUT_LOW); +#else + val8 = (pwrpriv->is_high_active == 0) ? 1 : 0; + rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8); + rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE); + RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow suspend and %s_ACTIVE.\n", + __func__, pwrpriv->wowlan_gpio_index, + pwrpriv->wowlan_gpio_output_state ? "HIGH" : "LOW", + pwrpriv->is_high_active ? "HIGI" : "LOW"); +#endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */ +#endif /* CONFIG_RTW_ONE_PIN_GPIO */ +#endif /* CONFIG_GPIO_WAKEUP */ + /* 5. Set Enable WOWLAN H2C command. */ RTW_PRINT("Set Enable AP WOWLan cmd\n"); rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1); @@ -6310,7 +6380,6 @@ static void rtw_hal_ap_wow_disable(_adapter *padapter) struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; #endif /*DBG_CHECK_FW_PS_STATE*/ u16 media_status_rpt; - u8 val8; RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__); /* 1. Read wakeup reason*/ @@ -6340,22 +6409,24 @@ static void rtw_hal_ap_wow_disable(_adapter *padapter) #ifdef CONFIG_GPIO_WAKEUP #ifdef CONFIG_RTW_ONE_PIN_GPIO - rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX); + rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index); #else - #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE +#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE if (pwrctl->is_high_active == 0) - rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX); + rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index); else - rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, 0); - #else - val8 = (pwrctl->is_high_active == 0) ? 1 : 0; - RTW_PRINT("Set Wake GPIO to default(%d).\n", val8); - rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8); - - rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _FALSE); - #endif/*CONFIG_WAKEUP_GPIO_INPUT_MODE*/ + rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index + , GPIO_OUTPUT_LOW); +#else + rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index, + pwrctl->wowlan_gpio_output_state); + RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow resume and %s_ACTIVE.\n", + __func__, pwrctl->wowlan_gpio_index, + pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW", + pwrctl->is_high_active ? "HIGI" : "LOW"); +#endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/ #endif /* CONFIG_RTW_ONE_PIN_GPIO */ -#endif +#endif /* CONFIG_GPIO_WAKEUP */ media_status_rpt = RT_MEDIA_CONNECT; rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, @@ -8259,6 +8330,116 @@ static void rtw_hal_construct_ARPRsp( *pLength += 8; } } +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +/* + * Description: + * Construct the Keep Alive packet to support specific Keep Alive packet. + * */ +static void rtw_hal_construct_keepalive( PADAPTER padapter, + u8 *pframe, + u32 *pLength +){ + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + u32 pktlen; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + static u8 LLCHeader[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; + u8 *pKeepAlivePkt = pframe; + /* for TKIP Cal MIC */ + u8 *payload = pframe; + u8 EncryptionHeadOverhead = 0, frame_offset = 0; + int i; + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &pwlanhdr->frame_ctl; + *(fctrl) = 0; + + RTW_INFO("%s======>\n", __func__); + + + /* ------------------------------------------------------------------------- */ + /* MAC Header. */ + /* ------------------------------------------------------------------------- */ + SetFrameType(fctrl, WIFI_DATA); + /* set_frame_sub_type(fctrl, 0); */ + SetToDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pwrpriv->keep_alive_pattern+6, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3,pwrpriv->keep_alive_pattern, ETH_ALEN); + + SetSeqNum(pwlanhdr, 0); + set_duration(pwlanhdr, 0); + +#ifdef CONFIG_WAPI_SUPPORT + *pLength = sMacHdrLng; +#else + *pLength = 24; +#endif + switch (psecuritypriv->dot11PrivacyAlgrthm) { + case _WEP40_: + case _WEP104_: + EncryptionHeadOverhead = 4; + break; + case _TKIP_: + EncryptionHeadOverhead = 8; + break; + case _AES_: + EncryptionHeadOverhead = 8; + break; +#ifdef CONFIG_WAPI_SUPPORT + case _SMS4_: + EncryptionHeadOverhead = 18; + break; +#endif + default: + EncryptionHeadOverhead = 0; + } + + if (EncryptionHeadOverhead > 0) { + _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead); + *pLength += EncryptionHeadOverhead; + /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */ + SetPrivacy(fctrl); + } + + /* ------------------------------------------------------------------------- */ + /* Frame Body. */ + /* ------------------------------------------------------------------------- */ + frame_offset = *pLength; + pKeepAlivePkt = (u8 *)(pframe + frame_offset); + payload = pKeepAlivePkt; /* Get Payload pointer */ + /* LLC header */ + _rtw_memcpy(pKeepAlivePkt, LLCHeader, 6); + *pLength += 6; + + /*From protocol type*/ + pKeepAlivePkt+=6; + + _rtw_memcpy(pKeepAlivePkt,pwrpriv->keep_alive_pattern+12,pwrpriv->keep_alive_pattern_len-12); + + *pLength+=pwrpriv->keep_alive_pattern_len-12; + + if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) { + *pLength += 8; + } + + /* for debug + for (i=0; i< (*pLength) ;i++) { + RTW_INFO("KA_Pkt[0x%x]=x%0x", i,pKeepAlivePkt[i]); + if((i%8) == 7) + RTW_INFO("\n"); + } + */ + + RTW_INFO("%s <======\n", __func__); +} + +#endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ #ifdef CONFIG_IPV6 /* @@ -8616,6 +8797,270 @@ static void rtw_hal_construct_scan_info(_adapter *padapter, } #endif /* CONFIG_PNO_SUPPORT */ +#ifdef CONFIG_WAR_OFFLOAD +#ifdef CONFIG_OFFLOAD_MDNS_V4 + +/* + * Description: + * Construct the MDNS V4 response packet to support MDNS offload. + * + */ +static void rtw_hal_construct_mdns_rsp_v4( + PADAPTER padapter, + u8 *pframe, + u32 *pLength, + u8 *pIPAddress +) +{ + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + u32 pktlen; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *cur_network = &pmlmepriv->cur_network; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct security_priv *psecuritypriv = &padapter->securitypriv; + static u8 ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00}; + u8 mulicast_ipv4_addr[4] = {0xe0, 0x00, 0x00, 0xfb}; + u8 mulicast_mac_addr_for_mdns[6] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb}; + u8 *pMdnsRspPkt = pframe; + /* for TKIP Cal MIC */ + u8 EncryptionHeadOverhead = 0, mdns_offset = 0; + + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &pwlanhdr->frame_ctl; + *(fctrl) = 0; + + /* ------------------------------------------------------------------------- */ + /* MAC Header. */ + /* ------------------------------------------------------------------------- */ + SetFrameType(fctrl, WIFI_DATA); + /* set_frame_sub_type(fctrl, 0); */ + SetToDs(fctrl); + //_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN ); + + SetSeqNum(pwlanhdr, 0); + set_duration(pwlanhdr, 0); + +#ifdef CONFIG_WAPI_SUPPORT + *pLength = sMacHdrLng; +#else + *pLength = 24; +#endif + switch (psecuritypriv->dot11PrivacyAlgrthm) { + case _WEP40_: + case _WEP104_: + EncryptionHeadOverhead = 4; + break; + case _TKIP_: + EncryptionHeadOverhead = 8; + break; + case _AES_: + EncryptionHeadOverhead = 8; + break; +#ifdef CONFIG_WAPI_SUPPORT + case _SMS4_: + EncryptionHeadOverhead = 18; + break; +#endif + default: + EncryptionHeadOverhead = 0; + } + + if (EncryptionHeadOverhead > 0) { + _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead); + *pLength += EncryptionHeadOverhead; + /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */ + SetPrivacy(fctrl); + } + + /* ------------------------------------------------------------------------- */ + /* Frame Body. */ + /* ------------------------------------------------------------------------- */ + mdns_offset = *pLength; + pMdnsRspPkt = (u8 *)(pframe + mdns_offset); + /* LLC header */ + _rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8); + *pLength += 8; + + /* IP element */ + pMdnsRspPkt += 8; + SET_IPHDR_VERSION(pMdnsRspPkt, 0x45); + SET_IPHDR_DSCP(pMdnsRspPkt, 0); + SET_IPHDR_TOTAL_LEN(pMdnsRspPkt, 0); // filled by fw + SET_IPHDR_IDENTIFIER(pMdnsRspPkt, 0); // filled by fw + SET_IPHDR_FLAGS(pMdnsRspPkt, 0x40); + SET_IPHDR_FRAG_OFFSET(pMdnsRspPkt, 0); + SET_IPHDR_TTL(pMdnsRspPkt, 0x40); + SET_IPHDR_PROTOCOL(pMdnsRspPkt, 0x11); // ICMP-UDP + SET_IPHDR_HDR_CHECKSUM(pMdnsRspPkt, 0); // filled by fw + SET_IPHDR_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress); + SET_IPHDR_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv4_addr); // filled by fw + + *pLength += 20; + + if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) { + if (IS_HARDWARE_TYPE_8188E(padapter) || + IS_HARDWARE_TYPE_8812(padapter)) { + rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset); + } + *pLength += 8; + } + + /* UDP element */ + pMdnsRspPkt += 20; + SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // MDNS + SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // MDNS + SET_UDP_LEN(pMdnsRspPkt, 0); // filled by fw + SET_UDP_CHECKSUM(pMdnsRspPkt, 0); // filled by fw + *pLength += 8; + + /* MDNS Header */ + pMdnsRspPkt += 8; + SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84); + *pLength += 12; + +} + +#endif /* CONFIG_OFFLOAD_MDNS_V4 */ + +#ifdef CONFIG_OFFLOAD_MDNS_V6 + +/* + * Description: + * Construct the MDNS response V6 packet to support MDNS offload. + * + */ +static void rtw_hal_construct_mdns_rsp_v6( + PADAPTER padapter, + u8 *pframe, + u32 *pLength, + u8 *pIPAddress +) +{ + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + u32 pktlen; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *cur_network = &pmlmepriv->cur_network; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct security_priv *psecuritypriv = &padapter->securitypriv; + static u8 ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD}; + u8 mulicast_ipv6_addr[16] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb}; + u8 mulicast_mac_addr_for_mdns[6] = {0x33, 0x33, 0x00, 0x00, 0x00, 0xfb}; /* could be revise by fw */ + u8 *pMdnsRspPkt = pframe; + /* for TKIP Cal MIC */ + u8 EncryptionHeadOverhead = 0, mdns_offset = 0; + /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */ + + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &pwlanhdr->frame_ctl; + *(fctrl) = 0; + + /* ------------------------------------------------------------------------- */ + /* MAC Header. */ + /* ------------------------------------------------------------------------- */ + SetFrameType(fctrl, WIFI_DATA); + /* set_frame_sub_type(fctrl, 0); */ + SetToDs(fctrl); + //_rtw_memcpy(pwlanhdr->addr1, mulicast_mac_addr_for_mdns, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + //_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN); + + SetSeqNum(pwlanhdr, 0); + set_duration(pwlanhdr, 0); + +#ifdef CONFIG_WAPI_SUPPORT + *pLength = sMacHdrLng; +#else + *pLength = 24; +#endif + switch (psecuritypriv->dot11PrivacyAlgrthm) { + case _WEP40_: + case _WEP104_: + EncryptionHeadOverhead = 4; + break; + case _TKIP_: + EncryptionHeadOverhead = 8; + break; + case _AES_: + EncryptionHeadOverhead = 8; + break; +#ifdef CONFIG_WAPI_SUPPORT + case _SMS4_: + EncryptionHeadOverhead = 18; + break; +#endif + default: + EncryptionHeadOverhead = 0; + } + + if (EncryptionHeadOverhead > 0) { + _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead); + *pLength += EncryptionHeadOverhead; + SetPrivacy(fctrl); + } + + /* ------------------------------------------------------------------------- */ + /* Frame Body. */ + /* ------------------------------------------------------------------------- */ + mdns_offset = *pLength; + pMdnsRspPkt = (u8 *)(pframe + mdns_offset); + /* LLC header */ + _rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8); + *pLength += 8; + + /* ICMP element */ + pMdnsRspPkt += 8; + SET_IPHDRV6_VERSION(pMdnsRspPkt, 0x06); + SET_IPHDRV6_PAYLOAD_LENGTH(pMdnsRspPkt, 0); // filled by fw + SET_IPHDRV6_NEXT_HEADER(pMdnsRspPkt, 0x3A); + SET_IPHDRV6_HOP_LIMIT(pMdnsRspPkt, 0xFF); + SET_IPHDRV6_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress); // filled by fw + SET_IPHDRV6_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv6_addr); // filled by fw + + *pLength += 40; + + if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) { + if (IS_HARDWARE_TYPE_8188E(padapter) || + IS_HARDWARE_TYPE_8812(padapter)) { + rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset); + } + *pLength += 8; + } + + /* UDP element */ + pMdnsRspPkt += 40; + SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // SNMP + SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // SNMP + SET_UDP_LEN(pMdnsRspPkt, 0); // filled by fw + SET_UDP_CHECKSUM(pMdnsRspPkt, 0); // filled by fw + *pLength += 8; + + /* MDNS Header */ + pMdnsRspPkt += 8; + SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84); + *pLength += 12; + +} + +#endif /* CONFIG_OFFLOAD_MDNS_V6 */ +#endif + #ifdef CONFIG_GTK_OL static void rtw_hal_construct_GTKRsp( PADAPTER padapter, @@ -8811,6 +9256,14 @@ void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index, u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0; u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0; u8 CurtPktPageNum = 0; +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + u32 keep_alive_len=0; + int i; +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN */ +#ifdef CONFIG_WAR_OFFLOAD + u16 tmp_idx = 0; + u32 buf_len = 0; +#endif #ifdef CONFIG_GTK_OL struct sta_priv *pstapriv = &adapter->stapriv; @@ -8834,6 +9287,17 @@ void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index, RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp); +#ifdef CONFIG_WAR_OFFLOAD + if ((0 != pwrctl->wowlan_war_offload_ipv4.ip_addr[0]) && + (_FALSE == _rtw_memcmp(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4))) { + _rtw_memcpy(pmlmeinfo->ip_addr, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4); + RTW_INFO("Update IP(%d.%d.%d.%d) to arp rsvd page\n", + pmlmeinfo->ip_addr[0], pmlmeinfo->ip_addr[1], + pmlmeinfo->ip_addr[2], pmlmeinfo->ip_addr[3]); + } +#endif /* CONFIG_WAR_OFFLOAD */ + + rtw_hal_construct_ARPRsp(adapter, &pframe[index], &ARPLength, pmlmeinfo->ip_addr); @@ -8847,6 +9311,22 @@ void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index, index += (CurtPktPageNum * page_size); RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0); +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + /* Keep Alive * ? page*/ + if(pwrctl->keep_alive_pattern_len){ + rsvd_page_loc->LocKeepAlive = *page_num; + pwrctl->keep_alive_pattern_loc = rsvd_page_loc->LocKeepAlive; + RTW_INFO("pwrctl->keep_alive_pattern_loc: %d\n", pwrctl->keep_alive_pattern_loc); + rtw_hal_construct_keepalive(adapter,&pframe[index],&keep_alive_len); + rtw_hal_fill_fake_txdesc(adapter, + &pframe[index - tx_desc], + keep_alive_len, _FALSE, _FALSE, _TRUE); + CurtPktPageNum = (u8)PageNum(tx_desc + keep_alive_len, page_size); + *page_num += CurtPktPageNum; + index += (CurtPktPageNum * page_size); + RSVD_PAGE_CFG("WOW-KeepAlive:", CurtPktPageNum, *page_num, 0); + } +#endif /* CONFIG_WOW_KEEP_ALIVE_PATTERN*/ #ifdef CONFIG_IPV6 /* 2 NS offload and NDP Info*/ @@ -9007,6 +9487,271 @@ void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index, index += (CurtPktPageNum * page_size); +#ifdef CONFIG_WAR_OFFLOAD + if(_TRUE == pwrctl->wowlan_war_offload_mode) { + u8 zero_ary[16] = {0x00}; + u8 war_tmp_cnt = 0; + + /* Reserve 2 page for Ip parameters */ + /* First page + | Byte 15 -----------Byte 0 | + | IP-4 | IP-3 | IP-2 | IP-1 | + | location of each feature | mac addr | + | NetBIOS name | + | location of each feature | + Second page + | IPv6 - 1 | + | IPv6 - 2 | + | IPv6 - 3 | + | IPv6 - 4 | + | IPv6 - 5 | + | IPv6 - 6 | + | IPv6 - 7 | + | IPv6 - 8 | + */ + + /* location of each feature : Byte 22 ~ Byte 31 + * Byte22 : location of SNMP RX + * Byte23 : location of SNMP V4 + * Byte24 : location of SNMP V6 + * Byte25 : location of MDNS Param + * Byte26 : location of MDNS V4 + * Byte27 : location of MDNS V6 + * Byte28 : location of SSDP pattern + * Byte29 : location of WSD pattern + * Byte30 : location of SLP pattern + * Byte31 : location of LLMNR + */ + + /* ipv4 : 4 */ + if (0 == pwrctl->wowlan_war_offload_ipv4.ip_addr[0]) + _rtw_memcpy(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4); + for(war_tmp_cnt=0; war_tmp_cnt<4 ;war_tmp_cnt++) + _rtw_memcpy(pframe + index - tx_desc + (war_tmp_cnt*4), &pwrctl->wowlan_war_offload_ipv4.ip_addr[war_tmp_cnt], 4); + + if (is_zero_mac_addr(pwrctl->wowlan_war_offload_mac)) { + _rtw_memcpy(pwrctl->wowlan_war_offload_mac, adapter_mac_addr(adapter), 6); + } + _rtw_memcpy(pframe + index + 16 - tx_desc, pwrctl->wowlan_war_offload_mac, 6); + + + /* ipv6 : 8 */ + if (_TRUE == _rtw_memcmp(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], zero_ary, RTW_IPv6_ADDR_LEN)) + _rtw_memcpy(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], pmlmeinfo->ip6_addr, RTW_IPv6_ADDR_LEN); + + for(war_tmp_cnt=0; war_tmp_cnt<8 ;war_tmp_cnt++) + _rtw_memcpy(pframe + index + page_size - tx_desc + (war_tmp_cnt*16), pwrctl->wowlan_war_offload_ipv6.ipv6_addr[war_tmp_cnt], 16); + + rsvd_page_loc->LocIpParm = *page_num; + + tmp_idx = index; + CurtPktPageNum = 2; + *page_num += CurtPktPageNum; + *total_pkt_len = index + (page_size * CurtPktPageNum); + index += (CurtPktPageNum * page_size); + + +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) + if ( (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) || + (WAR_MDNS_V4_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl) || + (WAR_MDNS_V6_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl)) { + + struct war_mdns_service_info *psinfo = pwrctl->wowlan_war_offload_mdns_service; + u8 txt_in_ptr[31]={ 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x13, 0x09, 0x74, 0x78, 0x74, 0x76, 0x65, 0x72, 0x73, + 0x3d, 0x31, 0x08, 0x71, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x3d, 0x31}; + u16 mdns_offset = index - tx_desc; + u8 i = 0; + + rsvd_page_loc->LocMdnsPara = *page_num; + RTW_INFO("LocMdnsPara : %d\n", rsvd_page_loc->LocMdnsPara); + + /* 1. service info */ + pframe[mdns_offset] = 0x01; // TLV(T) + mdns_offset += 1; + _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_service_info_num, 1); + mdns_offset += 1; + + for(i=0; iwowlan_war_offload_mdns_service_info_num ;i++) + { + u16 srv_rsp_len = 0; + + // 1.1 : construct service name string + // : length of total service name string (service+transport+domain) + pframe[mdns_offset] = psinfo[i].service_len + psinfo[i].transport_len + psinfo[i].domain_len + 4; + mdns_offset += 1; + + // : service name + pframe[mdns_offset] = psinfo[i].service_len; + mdns_offset += 1; + _rtw_memcpy(pframe + mdns_offset, &psinfo[i].service, psinfo[i].service_len); + mdns_offset += psinfo[i].service_len; + + // : transport name + pframe[mdns_offset] = psinfo[i].transport_len; + mdns_offset += 1; + _rtw_memcpy(pframe + mdns_offset, &psinfo[i].transport, psinfo[i].transport_len); + mdns_offset += psinfo[i].transport_len; + + // : domain name + pframe[mdns_offset] = psinfo[i].domain_len; + mdns_offset += 1; + _rtw_memcpy(pframe + mdns_offset, &psinfo[i].domain, psinfo[i].domain_len); + mdns_offset += psinfo[i].domain_len; + + // : delimiter + mdns_offset += 1; + + // 1.2 : construct type srv rsp + pframe[mdns_offset] = psinfo[i].target_len + 19; // length + pframe[mdns_offset + 2] = 0x21; // rsp type (srv) + pframe[mdns_offset + 4] = 0x01; // cache flush + class + _rtw_memcpy(pframe + mdns_offset + 5, &psinfo[i].ttl, 4); // ttl + pframe[mdns_offset + 5] = (u8) ( (psinfo[i].ttl & 0xff000000) >> 24); // ttl - byte0 + pframe[mdns_offset + 6] = (u8) ( (psinfo[i].ttl & 0x00ff0000) >> 16); // ttl - byte1 + pframe[mdns_offset + 7] = (u8) ( (psinfo[i].ttl & 0x0000ff00) >> 8 ); // ttl - byte2 + pframe[mdns_offset + 8] = (u8) (psinfo[i].ttl & 0x000000ff); // ttl - byte3 + pframe[mdns_offset + 10] = psinfo[i].target_len + 9; // data length + _rtw_memcpy(pframe + mdns_offset + 15, &psinfo[i].port, 2); // port + _rtw_memcpy(pframe + mdns_offset + 17, &psinfo[i].target_len, 1); // target len + _rtw_memcpy(pframe + mdns_offset + 18, &psinfo[i].target, psinfo[i].target_len); // target + pframe[mdns_offset + 18 + psinfo[i].target_len] = 0xc0; // message compresion, offset will be filled by fw. + mdns_offset += (1 + psinfo[i].target_len + 19); + + // 1.3 : set the idx of txt rsp + pframe[mdns_offset] = psinfo[i].txt_rsp_idx; + mdns_offset += 1; + } + + /* 2. machine name */ + pframe[mdns_offset] = 0x02; // TLV(T) + mdns_offset += 1; + _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_mnane_num, 1); // NUM + mdns_offset += 1; + + for(i=0; iwowlan_war_offload_mdns_mnane_num; i++) + { + pframe[mdns_offset] = pwrctl->wowlan_war_offload_mdns_mnane[i].name_len; + _rtw_memcpy(pframe + mdns_offset + 1, pwrctl->wowlan_war_offload_mdns_mnane[i].name, + pwrctl->wowlan_war_offload_mdns_mnane[i].name_len); // machine name + mdns_offset += (1+pwrctl->wowlan_war_offload_mdns_mnane[i].name_len); + } + + /* 3. A rsp */ + pframe[mdns_offset] = 0x03; // TLV(T) + pframe[mdns_offset + 1] = 14; // TLV(L) + pframe[mdns_offset + 3] = 0x01; // rsp type (a) + pframe[mdns_offset + 5] = 0x01; // cache flush + class + pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec) + pframe[mdns_offset + 11] = 4; // length of ipv4 addr. + _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4); + mdns_offset += (2 + 14); + + /* 4. AAAA rsp */ + pframe[mdns_offset] = 0x04; // TLV(T) + pframe[mdns_offset + 1] = 26; // TLV(L) + pframe[mdns_offset + 3] = 0x1c; // rsp type (aaaa) + pframe[mdns_offset + 5] = 0x01; // cache flush + class + pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec) + pframe[mdns_offset + 11] = 16; // length of ipv6 addr. + _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], 16); + mdns_offset += (2 + 26); + + /* 5. PTR rsp */ + pframe[mdns_offset] = 0x05; // TLV(T) + pframe[mdns_offset + 1] = 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // TLV(L) + pframe[mdns_offset + 3] = 0x0c; // rsp type (aaaa) + pframe[mdns_offset + 5] = 0x01; // cache flush + class + pframe[mdns_offset + 8] = 0x1c; // ttl + pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec) + pframe[mdns_offset + 11] = 3 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // data length + pframe[mdns_offset + 12] = pwrctl->wowlan_war_offload_mdns_domain_name_len; // domain name length + _rtw_memcpy(pframe + mdns_offset + 13, &pwrctl->wowlan_war_offload_mdns_domain_name, + pwrctl->wowlan_war_offload_mdns_domain_name_len); + pframe[mdns_offset + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len] = 0xc0; // message compression + mdns_offset += (2 + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len); + + /* 6. TXT in PTR rsp */ + pframe[mdns_offset] = 0x06; // TLV(T) + pframe[mdns_offset + 1] = 31; // TLV(L) + _rtw_memcpy(pframe + mdns_offset + 2, &txt_in_ptr, 31); + mdns_offset += (2 + 31); + + /* 7. TXT rsp */ + pframe[mdns_offset] = 0x07; // TLV(T) + mdns_offset += 1; + _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_txt_rsp_num, 1); // NUM + mdns_offset += 1; + + for(i=0; iwowlan_war_offload_mdns_txt_rsp_num; i++) + { + u16 txt_rsp_len = pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len; + + if(pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len==0) + { + _rtw_memcpy(pframe + mdns_offset, &txt_rsp_len, 2); + mdns_offset += ( 2 + txt_rsp_len ); + continue; + } + + txt_rsp_len += 10; + _rtw_memcpy(pframe + mdns_offset, &txt_rsp_len, 2); + pframe[mdns_offset + 3] = 0x10; // rsp type (txt) + pframe[mdns_offset + 5] = 0x01; // cache flush + class + pframe[mdns_offset + 8] = 0x1c; // ttl + pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec) + pframe[mdns_offset + 10] = (u8) ((pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0xff00) >> 8); + pframe[mdns_offset + 11] = (u8) (pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0x00ff); + _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt, + pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len); + mdns_offset += ( 2 + txt_rsp_len ); + } + + CurtPktPageNum = (u8)PageNum(mdns_offset - index, page_size)+1; + *page_num += CurtPktPageNum; + *total_pkt_len = index + (page_size * CurtPktPageNum); + index += (CurtPktPageNum * page_size); + } +#endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */ + +#ifdef CONFIG_OFFLOAD_MDNS_V4 + if (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) { + rsvd_page_loc->LocMdnsv4 = *page_num; + RTW_INFO("LocMdnsv4: %d\n", rsvd_page_loc->LocMdnsv4); + + rtw_hal_construct_mdns_rsp_v4(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr); + rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE); + CurtPktPageNum = 16; + *page_num += CurtPktPageNum; + index += (CurtPktPageNum * page_size); + } +#endif /* CONFIG_OFFLOAD_MDNS_V4 */ + +#ifdef CONFIG_OFFLOAD_MDNS_V6 + if (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) { + rsvd_page_loc->LocMdnsv6 = *page_num; + RTW_INFO("LocMdnsv6: %d\n", rsvd_page_loc->LocMdnsv6); + + rtw_hal_construct_mdns_rsp_v6(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr); + rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE); + CurtPktPageNum = 16; + *page_num += CurtPktPageNum; + index += (CurtPktPageNum * page_size); + } +#endif /* CONFIG_OFFLOAD_MDNS_V6 */ + +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) + *(pframe+tmp_idx+25-tx_desc) = rsvd_page_loc->LocMdnsPara; + *(pframe+tmp_idx+26-tx_desc) = rsvd_page_loc->LocMdnsv4; + *(pframe+tmp_idx+27-tx_desc) = rsvd_page_loc->LocMdnsv6; +#endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */ + + } + //rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, rsvd_page_loc->LocIpParm, 46); +#endif /* CONFIG_WAR_OFFLOAD */ + + /*Reserve 1 page for AOAC report*/ rsvd_page_loc->LocAOACReport = *page_num; RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport); @@ -9244,7 +9989,30 @@ static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow return _SUCCESS; } +void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx) +{ + int j; + + RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx); + RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type); + RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc); + for (j = 0; j < 4; j++) + RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]); +} +/*bit definition of pattern match format*/ +#define WOW_VALID_BIT BIT31 +#ifndef CONFIG_WOW_PATTERN_IN_TXFIFO +#define WOW_BC_BIT BIT26 +#define WOW_MC_BIT BIT25 +#define WOW_UC_BIT BIT24 +#else +#define WOW_BC_BIT BIT18 +#define WOW_UC_BIT BIT17 +#define WOW_MC_BIT BIT16 +#endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/ + #ifndef CONFIG_WOW_PATTERN_HW_CAM +#ifndef CONFIG_WOW_PATTERN_IN_TXFIFO static void rtw_hal_reset_mac_rx(_adapter *adapter) { u8 val8 = 0; @@ -9290,7 +10058,7 @@ static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode) rtw_read16(adapter, (REG_TRXFF_BNDY + 2))); } } - +#endif /* CONFIG_WOW_PATTERN_IN_TXFIFO*/ #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx) { @@ -9436,13 +10204,13 @@ bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx, if (i == 0) { if (context->type == PATTERN_VALID) - data = BIT(31); + data = WOW_VALID_BIT; else if (context->type == PATTERN_BROADCAST) - data = BIT(31) | BIT(26); + data = WOW_VALID_BIT | WOW_BC_BIT; else if (context->type == PATTERN_MULTICAST) - data = BIT(31) | BIT(25); + data = WOW_VALID_BIT | WOW_MC_BIT; else if (context->type == PATTERN_UNICAST) - data = BIT(31) | BIT(24); + data = WOW_VALID_BIT | WOW_UC_BIT; if (context->crc != 0) data |= context->crc; @@ -9615,13 +10383,13 @@ bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx, if (i == 0) { if (context->type == PATTERN_VALID) - data_l = BIT(31); + data_l = WOW_VALID_BIT; else if (context->type == PATTERN_BROADCAST) - data_l = BIT(31) | BIT(26); + data_l = WOW_VALID_BIT | WOW_BC_BIT; else if (context->type == PATTERN_MULTICAST) - data_l = BIT(31) | BIT(25); + data_l = WOW_VALID_BIT | WOW_MC_BIT; else if (context->type == PATTERN_UNICAST) - data_l = BIT(31) | BIT(24); + data_l = WOW_VALID_BIT | WOW_UC_BIT; if (context->crc != 0) data_l |= context->crc; @@ -9634,7 +10402,7 @@ bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx, rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data_h); } - rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0xFFFF) | BIT23 | (0xff <<24)); + rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0x1FFF) | BIT23 | (0xff <<24)); count = 0; do { tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23; @@ -9805,7 +10573,7 @@ void rtw_fill_pattern(_adapter *adapter) index = i; if (!pwrpriv->bInSuspend) index += 2; - + rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i); if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE) RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i); } @@ -9818,11 +10586,6 @@ void rtw_fill_pattern(_adapter *adapter) #else /*CONFIG_WOW_PATTERN_HW_CAM*/ #define WOW_CAM_ACCESS_TIMEOUT_MS 200 -#define WOW_VALID_BIT BIT31 -#define WOW_BC_BIT BIT26 -#define WOW_MC_BIT BIT25 -#define WOW_UC_BIT BIT24 - static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr) { struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); @@ -10004,18 +10767,6 @@ void rtw_clean_pattern(_adapter *adapter) if (_FAIL == _rtw_wow_pattern_clean_cam(adapter)) RTW_ERR("rtw_clean_pattern failed\n"); } - -void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx) -{ - int j; - - RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx); - RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type); - RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc); - for (j = 0; j < 4; j++) - RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]); -} - void rtw_fill_pattern(_adapter *adapter) { int i = 0, total = 0; @@ -10094,8 +10845,13 @@ static void rtw_hal_wow_enable(_adapter *adapter) PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter); int res; u16 media_status_rpt; - u8 no_wake = 0; - + u8 no_wake = 0, i; + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + _adapter *iface; +#ifdef CONFIG_GPIO_WAKEUP + u8 val8 = 0; +#endif + #ifdef CONFIG_LPS_PG u8 lps_pg_hdl_id = 0; #endif @@ -10108,6 +10864,16 @@ static void rtw_hal_wow_enable(_adapter *adapter) RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter)); rtw_hal_gate_bb(adapter, _TRUE); + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + /* Start Usb TxDMA */ + if(iface) { + RTW_INFO(ADPT_FMT "enable TX\n", ADPT_ARG(iface)); + RTW_ENABLE_FUNC(iface, DF_TX_BIT); + } + } + #ifdef CONFIG_GTK_OL if (psecuritypriv->binstallKCK_KEK == _TRUE) rtw_hal_fw_sync_cam_id(adapter); @@ -10135,7 +10901,9 @@ static void rtw_hal_wow_enable(_adapter *adapter) #ifndef CONFIG_WOW_PATTERN_HW_CAM /* Reconfig RX_FF Boundary */ + #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO rtw_hal_set_wow_rxff_boundary(adapter, _TRUE); + #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/ #endif /* redownload wow pattern */ @@ -10156,10 +10924,11 @@ static void rtw_hal_wow_enable(_adapter *adapter) } #ifdef CONFIG_FW_MULTI_PORT_SUPPORT else { - pwrctl->current_lps_hw_port_id = get_hw_port(adapter); - if(registry_par->suspend_type == FW_IPS_WRC) - rtw_hal_set_default_port_id_cmd(adapter, pwrctl->current_lps_hw_port_id); - RTW_DBG("pwrctl->current_lps_hw_port_id = %d \n", pwrctl->current_lps_hw_port_id); + if(registry_par->suspend_type == FW_IPS_WRC) { + adapter_to_dvobj(adapter)->dft.port_id = 0xFF; + adapter_to_dvobj(adapter)->dft.mac_id = 0xFF; + rtw_hal_set_default_port_id_cmd(adapter, 0); + } } #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */ } @@ -10171,8 +10940,27 @@ static void rtw_hal_wow_enable(_adapter *adapter) RTW_PRINT("[WARNING] enable cpwm2 fail\n"); #endif #ifdef CONFIG_GPIO_WAKEUP - rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _TRUE); -#endif +#ifdef CONFIG_RTW_ONE_PIN_GPIO + rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE); + rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index); +#else +#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE + if (pwrctl->is_high_active == 0) + rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index); + else + rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, + GPIO_OUTPUT_LOW); +#else + val8 = (pwrctl->is_high_active == 0) ? 1 : 0; + rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, val8); + rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE); + RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow suspend and %s_ACTIVE.\n", + __func__, pwrctl->wowlan_gpio_index, + pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW", + pwrctl->is_high_active ? "HIGI" : "LOW"); +#endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */ +#endif /* CONFIG_RTW_ONE_PIN_GPIO */ +#endif /* CONFIG_GPIO_WAKEUP */ /* Set WOWLAN H2C command. */ RTW_PRINT("Set WOWLan cmd\n"); rtw_hal_set_fw_wow_related_cmd(adapter, 1); @@ -10261,6 +11049,12 @@ void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason) _dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle"); else if (CLK_32K_LOCK == reason) _dbg_wake_up_reason_string(adapter, "clk 32k lock"); + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + else if (WOW_KEEPALIVE_ACK_TIMEOUT == reason) + _dbg_wake_up_reason_string(adapter, "rx keep alive ack timeout"); + else if (WOW_KEEPALIVE_WAKE == reason) + _dbg_wake_up_reason_string(adapter, "rx keep alive wake pattern"); + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ else _dbg_wake_up_reason_string(adapter, "unknown reasoen"); } @@ -10275,7 +11069,6 @@ static void rtw_hal_wow_disable(_adapter *adapter) struct registry_priv *registry_par = &adapter->registrypriv; int res; u16 media_status_rpt; - u8 val8; RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__); @@ -10311,6 +11104,18 @@ static void rtw_hal_wow_disable(_adapter *adapter) res = rtw_hal_check_wow_ctrl(adapter, _FALSE); + #if defined(CONFIG_RTL8188E) + if (IS_HARDWARE_TYPE_8188E(adapter)) + rtw_hal_enable_tx_report(adapter); + #endif + + if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) && + (pwrctl->wowlan_wake_reason != RX_DEAUTH) && + (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) { + rtw_hal_get_aoac_rpt(adapter); + rtw_hal_update_sw_security_info(adapter); + } + if (res == _FALSE) { RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__); rtw_hal_force_enable_rxdma(adapter); @@ -10327,43 +11132,35 @@ static void rtw_hal_wow_disable(_adapter *adapter) #ifndef CONFIG_WOW_PATTERN_HW_CAM /* config RXFF boundary to original */ + #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO rtw_hal_set_wow_rxff_boundary(adapter, _FALSE); + #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/ #endif rtw_hal_release_rx_dma(adapter); - #if defined(CONFIG_RTL8188E) - if (IS_HARDWARE_TYPE_8188E(adapter)) - rtw_hal_enable_tx_report(adapter); - #endif - - if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) && - (pwrctl->wowlan_wake_reason != RX_DEAUTH) && - (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) { - rtw_hal_get_aoac_rpt(adapter); - rtw_hal_update_sw_security_info(adapter); - } - rtw_hal_fw_dl(adapter, _FALSE); #ifdef CONFIG_GPIO_WAKEUP #ifdef CONFIG_RTW_ONE_PIN_GPIO - rtw_hal_set_input_gpio(adapter, WAKEUP_GPIO_IDX); + rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index); #else #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE if (pwrctl->is_high_active == 0) - rtw_hal_set_input_gpio(adapter, WAKEUP_GPIO_IDX); + rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index); else - rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, 0); + rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, + GPIO_OUTPUT_LOW); #else - val8 = (pwrctl->is_high_active == 0) ? 1 : 0; - RTW_PRINT("Set Wake GPIO to default(%d).\n", val8); - - rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, val8); - rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _FALSE); -#endif + rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index + , pwrctl->wowlan_gpio_output_state); + RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow resume and %s_ACTIVE.\n", + __func__, pwrctl->wowlan_gpio_index, + pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW", + pwrctl->is_high_active ? "HIGI" : "LOW"); +#endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */ #endif /* CONFIG_RTW_ONE_PIN_GPIO */ -#endif +#endif /* CONFIG_GPIO_WAKEUP */ if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) && (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) && (pwrctl->wowlan_wake_reason != RX_DISASSOC) && @@ -10610,11 +11407,12 @@ exit: } #endif /* CONFIG_RTL8822C */ -static void rtw_hal_build_lps_pg_info_rsvd_page(_adapter *adapter, u8 *buf, u32 *buf_size) +static void rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv *dvobj, _adapter *ld_sta_iface, u8 *buf, u32 *buf_size) { #define LPS_PG_INFO_RSVD_LEN 16 if (buf) { + _adapter *adapter = dvobj_get_primary_adapter(dvobj); struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); struct sta_info *psta; #ifdef CONFIG_MBSSID_CAM @@ -10624,17 +11422,18 @@ static void rtw_hal_build_lps_pg_info_rsvd_page(_adapter *adapter, u8 *buf, u32 u8 sec_cam_num = 0; u8 drv_rsvdpage_num = 0; - psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv)); - if (!psta) { - RTW_ERR("%s [ERROR] sta is NULL\n", __func__); - rtw_warn_on(1); - goto size_chk; + if (ld_sta_iface) { + psta = rtw_get_stainfo(&ld_sta_iface->stapriv, get_bssid(&ld_sta_iface->mlmepriv)); + if (!psta) { + RTW_ERR("%s [ERROR] sta is NULL\n", __func__); + rtw_warn_on(1); + goto size_chk; + } + /*Byte 0 - used macid*/ + LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id); + RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id); } - /*Byte 0 - used macid*/ - LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id); - RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id); - #ifdef CONFIG_MBSSID_CAM /*Byte 1 - used BSSID CAM entry*/ cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id); @@ -10645,8 +11444,8 @@ static void rtw_hal_build_lps_pg_info_rsvd_page(_adapter *adapter, u8 *buf, u32 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/ /*Btye 2 - Max used Pattern Match CAM entry*/ - if (pwrpriv->wowlan_mode == _TRUE && - check_fwstate(&adapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE) { + if (pwrpriv->wowlan_mode == _TRUE + && ld_sta_iface && check_fwstate(&ld_sta_iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) { LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx); RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx); } @@ -10689,7 +11488,7 @@ static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter) int ret = _FAIL; /* get length */ - rtw_hal_build_lps_pg_info_rsvd_page(adapter, NULL, &info_len); + rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, NULL, &info_len); if (!info_len) { RTW_ERR("get %s length fail\n", cache->name); goto exit; @@ -10703,7 +11502,7 @@ static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter) } /* get content */ - rtw_hal_build_lps_pg_info_rsvd_page(adapter, info, NULL); + rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, info, NULL); if (rsvd_page_cache_update_data(cache, info, info_len)) { @@ -10803,7 +11602,7 @@ static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index if (rsvd) { if (pwrctl->lps_level != LPS_PG) pos = NULL; - rtw_hal_build_lps_pg_info_rsvd_page(ld_sta_iface, pos, &len); + rtw_hal_build_lps_pg_info_rsvd_page(adapter_to_dvobj(adapter), ld_sta_iface, pos, &len); #if (DBG_LPSPG_INFO_DUMP >= 1) if (pos) RTW_INFO_DUMP(cache->name, pos, len); @@ -10817,7 +11616,7 @@ static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index rsvd_page_cache_free(cache); } -static u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter) +u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter) { struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); struct mlme_priv *pmlmepriv = &adapter->mlmepriv; @@ -10855,9 +11654,15 @@ static u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter) SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc); #ifdef CONFIG_RTL8822C - SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc); - if (!GET_HAL_DATA(adapter)->RegIQKFWOffload) - SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc); + if (pwrpriv->bFwCurrentInPSMode == _FALSE) { + SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc); + if (!GET_HAL_DATA(adapter)->RegIQKFWOffload) + SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc); + } else { + SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, 0); + if (!GET_HAL_DATA(adapter)->RegIQKFWOffload) + SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, 0); + } #endif #if (DBG_LPSPG_INFO_DUMP >= 1) @@ -11156,7 +11961,7 @@ static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page BeaconLength = MAX_BEACON_LEN - TxDescLen; CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize); -#ifdef CONFIG_FW_HANDLE_TXBCN +#if defined(CONFIG_FW_HANDLE_TXBCN) || defined(CONFIG_PORT_BASED_TXBCN) CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM; #endif TotalPageNum += CurtPktPageNum; @@ -11278,7 +12083,7 @@ static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/ ap_iface = adapter; - #ifdef CONFIG_CONCURRENT_MODE + #if defined (CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE) if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) { /*DEV_AP_STARTING_NUM*/ ap_iface = _rtw_search_ap_iface(adapter); RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface)); @@ -11352,6 +12157,9 @@ static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket, BufIndex, TxDescLen, PageSize, &TotalPageNum, &TotalPacketLen, &RsvdPageLoc); +#ifdef CONFIG_WAR_OFFLOAD + rtw_hal_set_war_offload_parm(adapter, &RsvdPageLoc); +#endif /* CONFIG_WAR_OFFLOAD */ } #endif /* CONFIG_WOWLAN */ @@ -11451,12 +12259,43 @@ error: void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished) { +#ifdef CONFIG_AP_MODE if (finished) rtw_mi_tx_beacon_hdl(adapter); else +#endif _rtw_hal_set_fw_rsvd_page(adapter, finished, NULL); } +static u8 rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(struct _ADAPTER *adapter, u8 enable) +{ + u8 u1H2CSetPwrMode[H2C_PWRMODE_LEN] = {0}; + u8 ret = _FAIL; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_TDLS_CH_SW + if (ATOMIC_READ(&adapter->tdlsinfo.chsw_info.chsw_on) == _TRUE) + { + SET_H2CCMD_PWRMODE_PARM_RLBM(u1H2CSetPwrMode, 1); + SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CSetPwrMode, 0); + } +#endif +#endif + + SET_H2CCMD_PWRMODE_PARM_MODE(u1H2CSetPwrMode, 0); + SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CSetPwrMode, 0x0C); + SET_H2CCMD_PWRMODE_PARM_BCN_EARLY_C2H_RPT(u1H2CSetPwrMode, enable); + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_SET_PWR_MODE, + H2C_PWRMODE_LEN, + u1H2CSetPwrMode); + + RTW_PRINT("-%s()-\n", __func__); + + return ret; +} + /** * rtw_hal_get_rsvd_page_num() - Get needed reserved page number * @adapter: struct _ADAPTER* @@ -11650,10 +12489,12 @@ static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable) } #endif + #ifdef CONFIG_AP_MODE if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) { ResumeTxBeacon(adapter); rtw_mi_tx_beacon_hdl(adapter); } + #endif } } @@ -11966,6 +12807,7 @@ void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state) } } break; +#ifdef CONFIG_AP_MODE case MLME_AP_STARTED : case MLME_MESH_STARTED : { @@ -12005,6 +12847,7 @@ void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state) } } break; +#endif /* CONFIG_AP_MODE */ default : RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state); break; @@ -12098,6 +12941,7 @@ static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state) if (iface == adapter) continue; + #ifdef CONFIG_AP_MODE if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface)) && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE ) { @@ -12108,6 +12952,7 @@ static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state) , __func__, ADPT_ARG(iface), iface->hw_port); #endif /* CONFIG_TSF_RESET_OFFLOAD*/ } + #endif /* CONFIG_AP_MODE */ } } #endif /* CONFIG_CONCURRENT_MODE */ @@ -12305,8 +13150,8 @@ void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode) return; } #endif /* CONFIG_LPS_ACK */ + } } -} void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) { @@ -12362,10 +13207,10 @@ void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) { RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted); /* Set RRSR rate table. */ - temp_RRSR = rtw_read32(padapter, REG_RRSR); - temp_RRSR &=0xFFFF0000; - temp_RRSR |=BrateCfg; - rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE); + temp_RRSR = rtw_read32(padapter, REG_RRSR); + temp_RRSR &=0xFFFF0000; + temp_RRSR |=BrateCfg; + rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE); rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0); @@ -12682,6 +13527,9 @@ u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val) rtw_read8(adapter, REG_CR + 1) & ~BIT(0)); break; #endif + case HW_VAR_BCN_EARLY_C2H_RPT: + rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(adapter, *(u8 *)val); + break; default: if (0) RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n", @@ -13625,6 +14473,15 @@ int hal_efuse_macaddr_offset(_adapter *adapter) addr_offset = EEPROM_MAC_ADDR_8814BE; break; #endif /* CONFIG_RTL8814B */ + +#ifdef CONFIG_RTL8723F + case RTL8723F: + if (interface_type == RTW_USB) + addr_offset = EEPROM_MAC_ADDR_8723FU; + else if (interface_type == RTW_SDIO) + addr_offset = EEPROM_MAC_ADDR_8723FS; + break; +#endif /* CONFIG_RTL8723F */ } if (addr_offset == -1) { @@ -13678,7 +14535,7 @@ u32 Hal_readPGDataFromConfigFile(PADAPTER padapter) u32 ret = _FALSE; u32 maplen = 0; #ifdef CONFIG_MP_INCLUDED - struct mp_priv *pmp_priv = &padapter->mppriv; + struct mp_priv *pmp_priv = &padapter->mppriv; #endif EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE); @@ -13686,16 +14543,18 @@ u32 Hal_readPGDataFromConfigFile(PADAPTER padapter) if (maplen < 256 || maplen > EEPROM_MAX_SIZE) { RTW_ERR("eFuse length error :%d\n", maplen); return _FALSE; - } + } #ifdef CONFIG_MP_INCLUDED if (pmp_priv->efuse_update_file == _TRUE && (rtw_mp_mode_check(padapter))) { RTW_INFO("%s, eFuse read from file :%s\n", __func__, pmp_priv->efuse_file_path); ret = rtw_read_efuse_from_file(pmp_priv->efuse_file_path, hal_data->efuse_eeprom_data, maplen); - } else -#endif - { + pmp_priv->efuse_update_file = _FALSE; + } else +#endif + { ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen); } + hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED); if (hal_data->efuse_file_status == EFUSE_FILE_LOADED) @@ -14017,7 +14876,8 @@ void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer) #ifdef RTW_HALMAC if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter) - || IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter)) + || IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter) + || IS_HARDWARE_TYPE_8723FU(padapter)) rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL); #else /* !RTW_HALMAC */ if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */ @@ -14064,6 +14924,7 @@ void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer) /* bus-agg check for SoftAP mode */ inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel) { +#ifdef CONFIG_AP_MODE struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); u8 chk_rst = _SUCCESS; @@ -14080,8 +14941,12 @@ inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qse chk_rst = _FAIL; } return chk_rst; +#else + return _SUCCESS; +#endif /* CONFIG_AP_MODE */ } +#ifdef CONFIG_WOWLAN /* * Description: * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload @@ -14126,6 +14991,7 @@ void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size) printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148)); } } +#endif #ifdef CONFIG_GPIO_API u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num) @@ -14480,7 +15346,15 @@ void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_coun vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000); CCK_FA = phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord); OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord); - + } else if(IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)){ + cckok = phy_query_bb_reg(padapter, 0x2aac, 0xffff); + ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff); + htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff); + cckcrc = phy_query_bb_reg(padapter, 0x2aac, 0xffff0000); + ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000); + htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000); + CCK_FA = phy_query_bb_reg(padapter, 0x2aa8, 0xffff0000) + phy_query_bb_reg(padapter, 0x2aa8, 0x0000ffff); + OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord); } else { cckok = phy_query_bb_reg(padapter, 0xF88, bMaskDWord); ofdmok = phy_query_bb_reg(padapter, 0xF94, bMaskLWord); @@ -14509,7 +15383,7 @@ void rtw_reset_phy_trx_ok_counters(_adapter *padapter) if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) { phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1); phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0); - } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)) { + } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) { phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1); phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0); } else { @@ -14529,6 +15403,11 @@ void rtw_reset_phy_rx_counters(_adapter *padapter) /* reset CCK CCA counter */ phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0); phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2); + + } else if (IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) { + /* reset CCK FA and CCK CCA counter */ + phy_set_bb_reg(padapter, 0x2a44, BIT21, 0); + phy_set_bb_reg(padapter, 0x2a44, BIT21, 1); rtw_reset_phy_trx_ok_counters(padapter); } else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) { @@ -14833,6 +15712,11 @@ int hal_spec_init(_adapter *adapter) case RTL8814B: rtl8814b_init_hal_spec(adapter); break; +#endif +#ifdef CONFIG_RTL8723F + case RTL8723F: + rtl8723f_init_hal_spec(adapter); + break; #endif default: RTW_ERR("%s: unknown chip_type:%u\n" @@ -15026,8 +15910,14 @@ u8 hal_largest_bw(_adapter *adapter, u8 in_bw) #ifndef CONFIG_HAS_TX_BEACON_PAUSE void ResumeTxBeacon(_adapter *padapter) { + RTW_DBG("ResumeTxBeacon\n"); + #ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE + rtw_write8(padapter, REG_TXPAUSE, + rtw_read8(padapter, REG_TXPAUSE) & (~BIT6)); + #else rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6)); + #endif #ifdef RTW_HALMAC /* Add this for driver using HALMAC because driver doesn't have setup time init by self */ @@ -15043,8 +15933,14 @@ void ResumeTxBeacon(_adapter *padapter) void StopTxBeacon(_adapter *padapter) { + RTW_DBG("StopTxBeacon\n"); + #ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE + rtw_write8(padapter, REG_TXPAUSE, + rtw_read8(padapter, REG_TXPAUSE) | BIT6); + #else rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6)); + #endif /* TBTT hold time: 0x540[19:8] */ rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF); @@ -15227,6 +16123,7 @@ void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_B } #endif +#ifdef CONFIG_PROC_DEBUG #ifdef CONFIG_PHY_CAPABILITY_QUERY void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter) { @@ -15327,6 +16224,7 @@ void rtw_dump_phy_cap(void *sel, _adapter *adapter) rtw_dump_phy_cap_by_hal(sel, adapter); #endif } +#endif inline s16 translate_dbm_to_percentage(s16 signal) { @@ -15422,6 +16320,7 @@ void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch); SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx); SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw); + SET_H2CCMD_SINGLE_CH_SWITCH_V2_IQK_UPDATE_EN(h2c, 1); rtw_sctx_init(chsw_sctx, 10); rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c); @@ -15429,21 +16328,37 @@ void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 } #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */ -u8 phy_get_current_tx_num( - PADAPTER pAdapter, - u8 Rate -) +u8 phy_get_capable_tx_num(_adapter *adapter, enum MGN_RATE rate) { - HAL_DATA_TYPE *hal_data = GET_HAL_DATA(pAdapter); - u8 tx_num = 0; + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + u8 tx_num = 0; - if (IS_1T_RATE(Rate)) + if (IS_1T_RATE(rate)) + tx_num = hal_data->txpath_cap_num_nss[0]; + else if (IS_2T_RATE(rate)) + tx_num = hal_data->txpath_cap_num_nss[1]; + else if (IS_3T_RATE(rate)) + tx_num = hal_data->txpath_cap_num_nss[2]; + else if (IS_4T_RATE(rate)) + tx_num = hal_data->txpath_cap_num_nss[3]; + else + rtw_warn_on(1); + + return tx_num == 0 ? RF_1TX : tx_num - 1; +} + +u8 phy_get_current_tx_num(_adapter *adapter, enum MGN_RATE rate) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + u8 tx_num = 0; + + if (IS_1T_RATE(rate)) tx_num = hal_data->txpath_num_nss[0]; - else if (IS_2T_RATE(Rate)) + else if (IS_2T_RATE(rate)) tx_num = hal_data->txpath_num_nss[1]; - else if (IS_3T_RATE(Rate)) + else if (IS_3T_RATE(rate)) tx_num = hal_data->txpath_num_nss[2]; - else if (IS_4T_RATE(Rate)) + else if (IS_4T_RATE(rate)) tx_num = hal_data->txpath_num_nss[3]; else rtw_warn_on(1); @@ -15595,3 +16510,17 @@ void rtw_leave_protsel_macsleep(_adapter *padapter) rtw_leave_protsel(&padapter->dvobj->protsel_macsleep); } #endif + +void rtw_hal_bcn_early_rpt_c2h_handler(_adapter *padapter) +{ + + if(0) + RTW_INFO("Recv Bcn Early report!!\n"); + +#ifdef CONFIG_TDLS +#ifdef CONFIG_TDLS_CH_SW + if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE) + rtw_tdls_ch_sw_back_to_base_chnl(padapter); +#endif +#endif +} diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_com_c2h.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_com_c2h.h index 85be2b366ea3..66b096aec5c4 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_com_c2h.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_com_c2h.h @@ -138,4 +138,6 @@ void c2h_txpwr_idx_offload_done(_adapter *adapter, u8 *data, u8 len); int c2h_txpwr_idx_offload_wait(_adapter *adapter); #endif +void rtw_hal_bcn_early_rpt_c2h_handler(_adapter *adapter); + #endif /* __COMMON_C2H_H__ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_com_phycfg.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_com_phycfg.c index 65aed0c92173..8e919624dcdb 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_com_phycfg.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_com_phycfg.c @@ -411,6 +411,20 @@ static const struct map_t rtl8822c_pg_txpwr_def_info = ); #endif +/* todo : 8723f don't know default power */ +#ifdef CONFIG_RTL8723F +static const struct map_t rtl8723f_pg_txpwr_def_info = + MAP_ENT(0xB8, 1, 0xFF + , MAPSEG_ARRAY_ENT(0x10, 82, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x02, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x02, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x02, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x02, 0x00, 0xFF, 0xFF, 0x00, 0xFF, + 0x00, 0x00) + ); +#endif + #ifdef CONFIG_RTL8814A static const struct map_t rtl8814a_pg_txpwr_def_info = MAP_ENT(0xB8, 1, 0xFF @@ -544,6 +558,11 @@ const struct map_t *hal_pg_txpwr_def_info(_adapter *adapter) case RTL8814B: map = &rtl8814b_pg_txpwr_def_info; break; +#endif +#ifdef CONFIG_RTL8723F + case RTL8723F: + map = &rtl8723f_pg_txpwr_def_info; + break; #endif } @@ -1095,7 +1114,6 @@ int check_phy_efuse_tx_power_info_valid(_adapter *adapter) return _FALSE; } #endif - /* NOTE: TSSI offset use the same layout as TXPWR base */ for (path = 0; path < MAX_RF_PATH; path++) { @@ -1663,6 +1681,9 @@ static void phy_txpwr_by_rate_chk_for_path_dup(_adapter *adapter) } } +static s8 _phy_get_txpwr_by_rate(_adapter *adapter + , BAND_TYPE band, enum rf_path rfpath, enum MGN_RATE rate); + void phy_store_target_tx_power(PADAPTER pAdapter) { struct hal_spec_t *hal_spec = GET_HAL_SPEC(pAdapter); @@ -1692,7 +1713,7 @@ void phy_store_target_tx_power(PADAPTER pAdapter) if (regsty->target_tx_pwr_valid == _TRUE) base = hal_spec->txgi_pdbm * rtw_regsty_get_target_tx_power(pAdapter, band, path, rs); else - base = _PHY_GetTxPowerByRate(pAdapter, band, path, rate_sec_base[rs]); + base = _phy_get_txpwr_by_rate(pAdapter, band, path, rate_sec_base[rs]); phy_set_target_txpwr(pAdapter, band, path, rs, base); } } @@ -2122,7 +2143,7 @@ PHY_StoreTxPowerByRateNew( } for (i = 0; i < rateNum; ++i) { - u8 rate_idx = PHY_GetRateIndexOfTxPowerByRate(rates[i]); + u8 rate_idx = phy_get_rate_idx_of_txpwr_by_rate(rates[i]); pHalData->TxPwrByRate[Band][RfPath][rate_idx] = PwrByRateVal[i]; } @@ -2485,346 +2506,229 @@ PHY_GetTxPowerTrackingOffset( return offset; } +static const u8 _phy_get_rate_idx_of_txpwr_by_rate[MGN_UNKNOWN] = { + [MGN_1M] = 0, + [MGN_2M] = 1, + [MGN_5_5M] = 2, + [MGN_11M] = 3, + [MGN_6M] = 4, + [MGN_9M] = 5, + [MGN_12M] = 6, + [MGN_18M] = 7, + [MGN_24M] = 8, + [MGN_36M] = 9, + [MGN_48M] = 10, + [MGN_54M] = 11, + [MGN_MCS0] = 12, + [MGN_MCS1] = 13, + [MGN_MCS2] = 14, + [MGN_MCS3] = 15, + [MGN_MCS4] = 16, + [MGN_MCS5] = 17, + [MGN_MCS6] = 18, + [MGN_MCS7] = 19, + [MGN_MCS8] = 20, + [MGN_MCS9] = 21, + [MGN_MCS10] = 22, + [MGN_MCS11] = 23, + [MGN_MCS12] = 24, + [MGN_MCS13] = 25, + [MGN_MCS14] = 26, + [MGN_MCS15] = 27, + [MGN_MCS16] = 28, + [MGN_MCS17] = 29, + [MGN_MCS18] = 30, + [MGN_MCS19] = 31, + [MGN_MCS20] = 32, + [MGN_MCS21] = 33, + [MGN_MCS22] = 34, + [MGN_MCS23] = 35, + [MGN_MCS24] = 36, + [MGN_MCS25] = 37, + [MGN_MCS26] = 38, + [MGN_MCS27] = 39, + [MGN_MCS28] = 40, + [MGN_MCS29] = 41, + [MGN_MCS30] = 42, + [MGN_MCS31] = 43, + [MGN_VHT1SS_MCS0] = 44, + [MGN_VHT1SS_MCS1] = 45, + [MGN_VHT1SS_MCS2] = 46, + [MGN_VHT1SS_MCS3] = 47, + [MGN_VHT1SS_MCS4] = 48, + [MGN_VHT1SS_MCS5] = 49, + [MGN_VHT1SS_MCS6] = 50, + [MGN_VHT1SS_MCS7] = 51, + [MGN_VHT1SS_MCS8] = 52, + [MGN_VHT1SS_MCS9] = 53, + [MGN_VHT2SS_MCS0] = 54, + [MGN_VHT2SS_MCS1] = 55, + [MGN_VHT2SS_MCS2] = 56, + [MGN_VHT2SS_MCS3] = 57, + [MGN_VHT2SS_MCS4] = 58, + [MGN_VHT2SS_MCS5] = 59, + [MGN_VHT2SS_MCS6] = 60, + [MGN_VHT2SS_MCS7] = 61, + [MGN_VHT2SS_MCS8] = 62, + [MGN_VHT2SS_MCS9] = 63, + [MGN_VHT3SS_MCS0] = 64, + [MGN_VHT3SS_MCS1] = 65, + [MGN_VHT3SS_MCS2] = 66, + [MGN_VHT3SS_MCS3] = 67, + [MGN_VHT3SS_MCS4] = 68, + [MGN_VHT3SS_MCS5] = 69, + [MGN_VHT3SS_MCS6] = 70, + [MGN_VHT3SS_MCS7] = 71, + [MGN_VHT3SS_MCS8] = 72, + [MGN_VHT3SS_MCS9] = 73, + [MGN_VHT4SS_MCS0] = 74, + [MGN_VHT4SS_MCS1] = 75, + [MGN_VHT4SS_MCS2] = 76, + [MGN_VHT4SS_MCS3] = 77, + [MGN_VHT4SS_MCS4] = 78, + [MGN_VHT4SS_MCS5] = 79, + [MGN_VHT4SS_MCS6] = 80, + [MGN_VHT4SS_MCS7] = 81, + [MGN_VHT4SS_MCS8] = 82, + [MGN_VHT4SS_MCS9] = 83, +}; + /*The same as MRateToHwRate in hal_com.c*/ -u8 -PHY_GetRateIndexOfTxPowerByRate( - u8 Rate -) +u8 phy_get_rate_idx_of_txpwr_by_rate(enum MGN_RATE rate) { - u8 index = 0; - switch (Rate) { - case MGN_1M: - index = 0; - break; - case MGN_2M: - index = 1; - break; - case MGN_5_5M: - index = 2; - break; - case MGN_11M: - index = 3; - break; - case MGN_6M: - index = 4; - break; - case MGN_9M: - index = 5; - break; - case MGN_12M: - index = 6; - break; - case MGN_18M: - index = 7; - break; - case MGN_24M: - index = 8; - break; - case MGN_36M: - index = 9; - break; - case MGN_48M: - index = 10; - break; - case MGN_54M: - index = 11; - break; - case MGN_MCS0: - index = 12; - break; - case MGN_MCS1: - index = 13; - break; - case MGN_MCS2: - index = 14; - break; - case MGN_MCS3: - index = 15; - break; - case MGN_MCS4: - index = 16; - break; - case MGN_MCS5: - index = 17; - break; - case MGN_MCS6: - index = 18; - break; - case MGN_MCS7: - index = 19; - break; - case MGN_MCS8: - index = 20; - break; - case MGN_MCS9: - index = 21; - break; - case MGN_MCS10: - index = 22; - break; - case MGN_MCS11: - index = 23; - break; - case MGN_MCS12: - index = 24; - break; - case MGN_MCS13: - index = 25; - break; - case MGN_MCS14: - index = 26; - break; - case MGN_MCS15: - index = 27; - break; - case MGN_MCS16: - index = 28; - break; - case MGN_MCS17: - index = 29; - break; - case MGN_MCS18: - index = 30; - break; - case MGN_MCS19: - index = 31; - break; - case MGN_MCS20: - index = 32; - break; - case MGN_MCS21: - index = 33; - break; - case MGN_MCS22: - index = 34; - break; - case MGN_MCS23: - index = 35; - break; - case MGN_MCS24: - index = 36; - break; - case MGN_MCS25: - index = 37; - break; - case MGN_MCS26: - index = 38; - break; - case MGN_MCS27: - index = 39; - break; - case MGN_MCS28: - index = 40; - break; - case MGN_MCS29: - index = 41; - break; - case MGN_MCS30: - index = 42; - break; - case MGN_MCS31: - index = 43; - break; - case MGN_VHT1SS_MCS0: - index = 44; - break; - case MGN_VHT1SS_MCS1: - index = 45; - break; - case MGN_VHT1SS_MCS2: - index = 46; - break; - case MGN_VHT1SS_MCS3: - index = 47; - break; - case MGN_VHT1SS_MCS4: - index = 48; - break; - case MGN_VHT1SS_MCS5: - index = 49; - break; - case MGN_VHT1SS_MCS6: - index = 50; - break; - case MGN_VHT1SS_MCS7: - index = 51; - break; - case MGN_VHT1SS_MCS8: - index = 52; - break; - case MGN_VHT1SS_MCS9: - index = 53; - break; - case MGN_VHT2SS_MCS0: - index = 54; - break; - case MGN_VHT2SS_MCS1: - index = 55; - break; - case MGN_VHT2SS_MCS2: - index = 56; - break; - case MGN_VHT2SS_MCS3: - index = 57; - break; - case MGN_VHT2SS_MCS4: - index = 58; - break; - case MGN_VHT2SS_MCS5: - index = 59; - break; - case MGN_VHT2SS_MCS6: - index = 60; - break; - case MGN_VHT2SS_MCS7: - index = 61; - break; - case MGN_VHT2SS_MCS8: - index = 62; - break; - case MGN_VHT2SS_MCS9: - index = 63; - break; - case MGN_VHT3SS_MCS0: - index = 64; - break; - case MGN_VHT3SS_MCS1: - index = 65; - break; - case MGN_VHT3SS_MCS2: - index = 66; - break; - case MGN_VHT3SS_MCS3: - index = 67; - break; - case MGN_VHT3SS_MCS4: - index = 68; - break; - case MGN_VHT3SS_MCS5: - index = 69; - break; - case MGN_VHT3SS_MCS6: - index = 70; - break; - case MGN_VHT3SS_MCS7: - index = 71; - break; - case MGN_VHT3SS_MCS8: - index = 72; - break; - case MGN_VHT3SS_MCS9: - index = 73; - break; - case MGN_VHT4SS_MCS0: - index = 74; - break; - case MGN_VHT4SS_MCS1: - index = 75; - break; - case MGN_VHT4SS_MCS2: - index = 76; - break; - case MGN_VHT4SS_MCS3: - index = 77; - break; - case MGN_VHT4SS_MCS4: - index = 78; - break; - case MGN_VHT4SS_MCS5: - index = 79; - break; - case MGN_VHT4SS_MCS6: - index = 80; - break; - case MGN_VHT4SS_MCS7: - index = 81; - break; - case MGN_VHT4SS_MCS8: - index = 82; - break; - case MGN_VHT4SS_MCS9: - index = 83; - break; - default: - RTW_INFO("Invalid rate 0x%x in %s\n", Rate, __FUNCTION__); - break; - }; + u8 index = 0; + + if (rate < MGN_UNKNOWN) + index = _phy_get_rate_idx_of_txpwr_by_rate[rate]; + + if (rate != MGN_1M && index == 0) + RTW_WARN("Invalid rate 0x%x in %s\n", rate, __FUNCTION__); return index; } -s8 -_PHY_GetTxPowerByRate( - PADAPTER pAdapter, - u8 Band, - enum rf_path RFPath, - u8 Rate -) +static s8 _phy_get_txpwr_by_rate(_adapter *adapter + , BAND_TYPE band, enum rf_path rfpath, enum MGN_RATE rate) { - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter); s8 value = 0; - u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate); + u8 rate_idx = phy_get_rate_idx_of_txpwr_by_rate(rate); - if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) { - RTW_INFO("Invalid band %d in %s\n", Band, __func__); + if (band != BAND_ON_2_4G && band != BAND_ON_5G) { + RTW_INFO("Invalid band %d in %s\n", band, __func__); goto exit; } - if (RFPath > RF_PATH_D) { - RTW_INFO("Invalid RfPath %d in %s\n", RFPath, __func__); + if (rfpath > RF_PATH_D) { + RTW_INFO("Invalid RfPath %d in %s\n", rfpath, __func__); goto exit; } - if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) { - RTW_INFO("Invalid RateIndex %d in %s\n", rateIndex, __func__); + if (rate_idx >= TX_PWR_BY_RATE_NUM_RATE) { + RTW_INFO("Invalid RateIndex %d in %s\n", rate_idx, __func__); goto exit; } - value = pHalData->TxPwrByRate[Band][RFPath][rateIndex]; + value = pHalData->TxPwrByRate[band][rfpath][rate_idx]; exit: return value; } - -s8 -PHY_GetTxPowerByRate( - PADAPTER pAdapter, - u8 Band, - enum rf_path RFPath, - RATE_SECTION rs, - enum MGN_RATE rate -) +/* +* Return value in unit of TX Gain Index +*/ +s8 phy_get_txpwr_by_rate(_adapter *adapter + , BAND_TYPE band, enum rf_path rfpath, RATE_SECTION rs, enum MGN_RATE rate) { - if (phy_is_tx_power_by_rate_needed(pAdapter)) - return _PHY_GetTxPowerByRate(pAdapter, Band, RFPath, rate); - return phy_get_target_txpwr(pAdapter, Band, RFPath, rs); + if (phy_is_tx_power_by_rate_needed(adapter)) + return _phy_get_txpwr_by_rate(adapter, band, rfpath, rate); + return phy_get_target_txpwr(adapter, band, rfpath, rs); } -void -PHY_SetTxPowerByRate( - PADAPTER pAdapter, - u8 Band, - enum rf_path RFPath, - u8 Rate, - s8 Value -) +/* get txpowr in mBm for single path */ +s16 phy_get_txpwr_by_rate_single_mbm(_adapter *adapter + , BAND_TYPE band, enum rf_path rfpath, RATE_SECTION rs, enum MGN_RATE rate, bool eirp) { - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); - u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + s16 val; - if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) { - RTW_INFO("Invalid band %d in %s\n", Band, __FUNCTION__); - return; - } - if (RFPath > RF_PATH_D) { - RTW_INFO("Invalid RfPath %d in %s\n", RFPath, __FUNCTION__); - return; - } - if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) { - RTW_INFO("Invalid RateIndex %d in %s\n", rateIndex, __FUNCTION__); - return; + val = phy_get_txpwr_by_rate(adapter, band, rfpath, rs, rate); + if (val == hal_spec->txgi_max) + val = UNSPECIFIED_MBM; + else { + val = (val * MBM_PDBM) / hal_spec->txgi_pdbm; + if (eirp) + val += rfctl->antenna_gain; } - pHalData->TxPwrByRate[Band][RFPath][rateIndex] = Value; + return val; +} + +/* get txpowr in mBm with effect of N-TX */ +s16 phy_get_txpwr_by_rate_total_mbm(_adapter *adapter + , BAND_TYPE band, RATE_SECTION rs, enum MGN_RATE rate, bool cap, bool eirp) +{ + s16 val; + u8 tx_num; + + if (cap) + tx_num = phy_get_capable_tx_num(adapter, rate) + 1; + else + tx_num = phy_get_current_tx_num(adapter, rate) + 1; + + /* assume all path have same txpower target */ + val = phy_get_txpwr_by_rate_single_mbm(adapter, band, RF_PATH_A, rs, rate, eirp); + if (val != UNSPECIFIED_MBM) + val += mb_of_ntx(tx_num); + + return val; +} + +static s16 _phy_get_txpwr_by_rate_max_mbm(_adapter *adapter, BAND_TYPE band, s8 rfpath, bool cap, bool eirp) +{ + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + u8 tx_num; + RATE_SECTION rs; + int i; + s16 max = UNSPECIFIED_MBM, mbm; + + for (rs = 0; rs < RATE_SECTION_NUM; rs++) { + tx_num = rate_section_to_tx_num(rs); + if (tx_num + 1 > hal_data->tx_nss) + continue; + + if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs)) + continue; + + if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_ALL(adapter)) + continue; + + for (i = 0; i < rates_by_sections[rs].rate_num; i++) { + if (rfpath < 0) /* total */ + mbm = phy_get_txpwr_by_rate_total_mbm(adapter, band, rs, rates_by_sections[rs].rates[i], cap, eirp); + else + mbm = phy_get_txpwr_by_rate_single_mbm(adapter, band, rfpath, rs, rates_by_sections[rs].rates[i], eirp); + if (mbm == UNSPECIFIED_MBM) + continue; + if (max == UNSPECIFIED_MBM || mbm > max) + max = mbm; + } + } + + return max; +} + +/* get txpowr in mBm for single path */ +s16 phy_get_txpwr_by_rate_single_max_mbm(_adapter *adapter, BAND_TYPE band, enum rf_path rfpath, bool eirp) +{ + return _phy_get_txpwr_by_rate_max_mbm(adapter, band, rfpath, 0 /* single don't care */, eirp); +} + +/* get txpowr in mBm with effect of N-TX */ +s16 phy_get_txpwr_by_rate_total_max_mbm(_adapter *adapter, BAND_TYPE band, bool cap, bool eirp) +{ + return _phy_get_txpwr_by_rate_max_mbm(adapter, band, -1, cap, eirp); } u8 phy_check_under_survey_ch(_adapter *adapter) @@ -3077,7 +2981,7 @@ inline s8 phy_get_txpwr_lmt_diff(_adapter *adapter } /* -* May search for secondary channels for min limit +* May search for secondary channels for max/min limit * @opch: used to specify operating channel position to get * cch of every bandwidths which differ from current hal_data.cch20, 40, 80... * @@ -3087,7 +2991,7 @@ inline s8 phy_get_txpwr_lmt_diff(_adapter *adapter s8 phy_get_txpwr_lmt_sub_chs(_adapter *adapter , const char *regd_name , BAND_TYPE band, enum channel_width bw - , u8 rfpath, u8 rate, u8 ntx_idx, u8 cch, u8 opch) + , u8 rfpath, u8 rate, u8 ntx_idx, u8 cch, u8 opch, bool reg_max) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); @@ -3100,10 +3004,17 @@ s8 phy_get_txpwr_lmt_sub_chs(_adapter *adapter u8 tmp_cch = 0; u8 tmp_bw; u8 bw_bmp = 0; - s8 min_lmt = hal_spec->txgi_max; - u8 final_bw = bw, final_cch = cch; + s8 final_lmt = reg_max ? 0 : hal_spec->txgi_max; + u8 final_bw = CHANNEL_WIDTH_MAX, final_cch = cch; _irqL irqL; + if ((adapter->registrypriv.RegEnableTxPowerLimit == 2 && hal_data->EEPROMRegulatory != 1) || + adapter->registrypriv.RegEnableTxPowerLimit == 0 + ) { + final_lmt = hal_spec->txgi_max; + goto exit; + } + #ifdef CONFIG_MP_INCLUDED /* MP mode channel don't use secondary channel */ if (rtw_mp_mode_check(adapter) == _TRUE) @@ -3140,19 +3051,31 @@ s8 phy_get_txpwr_lmt_sub_chs(_adapter *adapter } /* - * find the possible tx bandwidth bmp for this rate, and then will get center channel for each bandwidth - * if no possible tx bandwidth bmp, select valid bandwidth up to current RF bandwidth into bmp + * reg_max: + * get valid full bandwidth bmp up to @bw + * + * !reg_max: + * find the possible tx bandwidth bmp for this rate + * if no possible tx bandwidth bmp, select valid bandwidth bmp up to @bw */ if (tlrs == TXPWR_LMT_RS_CCK || tlrs == TXPWR_LMT_RS_OFDM) bw_bmp = BW_CAP_20M; /* CCK, OFDM only BW 20M */ else if (tlrs == TXPWR_LMT_RS_HT) { - bw_bmp = rtw_get_tx_bw_bmp_of_ht_rate(dvobj, rate, bw); - if (bw_bmp == 0) - bw_bmp = ch_width_to_bw_cap(bw > CHANNEL_WIDTH_40 ? CHANNEL_WIDTH_40 : bw); + if (reg_max) + bw_bmp = ch_width_to_bw_cap(bw > CHANNEL_WIDTH_40 ? CHANNEL_WIDTH_40 + 1 : bw + 1) - 1; + else { + bw_bmp = rtw_get_tx_bw_bmp_of_ht_rate(dvobj, rate, bw); + if (bw_bmp == 0) + bw_bmp = ch_width_to_bw_cap(bw > CHANNEL_WIDTH_40 ? CHANNEL_WIDTH_40 : bw); + } } else if (tlrs == TXPWR_LMT_RS_VHT) { - bw_bmp = rtw_get_tx_bw_bmp_of_vht_rate(dvobj, rate, bw); - if (bw_bmp == 0) - bw_bmp = ch_width_to_bw_cap(bw > CHANNEL_WIDTH_160 ? CHANNEL_WIDTH_160 : bw); + if (reg_max) + bw_bmp = ch_width_to_bw_cap(bw > CHANNEL_WIDTH_160 ? CHANNEL_WIDTH_160 + 1 : bw + 1) - 1; + else { + bw_bmp = rtw_get_tx_bw_bmp_of_vht_rate(dvobj, rate, bw); + if (bw_bmp == 0) + bw_bmp = ch_width_to_bw_cap(bw > CHANNEL_WIDTH_160 ? CHANNEL_WIDTH_160 : bw); + } } else rtw_warn_on(1); } @@ -3162,12 +3085,13 @@ s8 phy_get_txpwr_lmt_sub_chs(_adapter *adapter _enter_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL); - /* loop for each possible tx bandwidth to find minimum limit */ + /* loop for each possible tx bandwidth to find final limit */ for (tmp_bw = CHANNEL_WIDTH_20; tmp_bw <= bw; tmp_bw++) { if (!(ch_width_to_bw_cap(tmp_bw) & bw_bmp)) continue; if (no_sc == _FALSE) { + /* get center channel for each bandwidth */ if (tmp_bw == CHANNEL_WIDTH_20) tmp_cch = cch_20; else if (tmp_bw == CHANNEL_WIDTH_40) @@ -3182,27 +3106,34 @@ s8 phy_get_txpwr_lmt_sub_chs(_adapter *adapter lmt = phy_get_txpwr_lmt(adapter, regd_name, band, tmp_bw, tlrs, ntx_idx, tmp_cch, 0); - if (min_lmt >= lmt) { - min_lmt = lmt; - final_cch = tmp_cch; - final_bw = tmp_bw; + if (final_lmt > lmt) { + if (reg_max) + continue; + } else if (final_lmt < lmt) { + if (!reg_max) + continue; + } else { /* equal */ + if (final_bw == bw) + continue; } + final_lmt = lmt; + final_cch = tmp_cch; + final_bw = tmp_bw; } _exit_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL); -exit: - if (0) { if (final_bw != bw && (IS_HT_RATE(rate) || IS_VHT_RATE(rate))) - RTW_INFO("%s min_lmt: %s ch%u -> %s ch%u\n" + RTW_INFO("%s final_lmt: %s ch%u -> %s ch%u\n" , MGN_RATE_STR(rate) , ch_width_str(bw), cch , ch_width_str(final_bw), final_cch); } - return min_lmt; +exit: + return final_lmt; } static void phy_txpwr_lmt_cck_ofdm_mt_chk(_adapter *adapter) @@ -3721,6 +3652,169 @@ phy_set_tx_power_limit( #endif } +void +phy_set_tx_power_limit_ex( + struct dm_struct *pDM_Odm, + u8 Regulation, + u8 Band, + u8 Bandwidth, + u8 RateSection, + u8 ntx, + u8 channel, + s8 powerLimit +) +{ +#if CONFIG_TXPWR_LIMIT + PADAPTER Adapter = pDM_Odm->adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(Adapter); + u8 regd; + u8 band = 0, bandwidth = 0, tlrs = 0; + u8 ntx_idx; + s8 prevPowerLimit, channelIndex; + s8 ww_lmt_val = phy_txpwr_ww_lmt_value(Adapter); + + if (0) + RTW_INFO("Index of power limit table [regulation %d][band %d][bw %d][rate section %d][ntx %d][chnl %d][val %d]\n" + , Regulation, Band, Bandwidth, RateSection, ntx, channel, powerLimit); + + if (powerLimit != ww_lmt_val) { + if (powerLimit < -hal_spec->txgi_max || powerLimit > hal_spec->txgi_max) + RTW_PRINT("Illegal power limit value [ch %d][val %d]\n", channel, powerLimit); + + if (powerLimit > hal_spec->txgi_max) + powerLimit = hal_spec->txgi_max; + else if (powerLimit < -hal_spec->txgi_max) + powerLimit = ww_lmt_val + 1; + } + + switch (Regulation) { + case PW_LMT_REGU_FCC: + regd = TXPWR_LMT_FCC; + break; + case PW_LMT_REGU_ETSI: + regd = TXPWR_LMT_ETSI; + break; + case PW_LMT_REGU_MKK: + regd = TXPWR_LMT_MKK; + break; + case PW_LMT_REGU_IC: + regd = TXPWR_LMT_IC; + break; + case PW_LMT_REGU_KCC: + regd = TXPWR_LMT_KCC; + break; + case PW_LMT_REGU_ACMA: + regd = TXPWR_LMT_ACMA; + break; + case PW_LMT_REGU_CHILE: + regd = TXPWR_LMT_CHILE; + break; + case PW_LMT_REGU_UKRAINE: + regd = TXPWR_LMT_UKRAINE; + break; + case PW_LMT_REGU_MEXICO: + regd = TXPWR_LMT_MEXICO; + break; + case PW_LMT_REGU_CN: + regd = TXPWR_LMT_CN; + break; + case PW_LMT_REGU_WW13: + default: + RTW_PRINT("Wrong regulation:%d\n", Regulation); + return; + } + + switch (RateSection) { + case PW_LMT_RS_CCK: + tlrs = TXPWR_LMT_RS_CCK; + break; + case PW_LMT_RS_OFDM: + tlrs = TXPWR_LMT_RS_OFDM; + break; + case PW_LMT_RS_HT: + tlrs = TXPWR_LMT_RS_HT; + break; + case PW_LMT_RS_VHT: + tlrs = TXPWR_LMT_RS_VHT; + break; + default: + RTW_PRINT("Wrong rate section:%d\n", RateSection); + return; + } + + switch (ntx) { + case PW_LMT_PH_1T: + ntx_idx = RF_1TX; + break; + case PW_LMT_PH_2T: + ntx_idx = RF_2TX; + break; + case PW_LMT_PH_3T: + ntx_idx = RF_3TX; + break; + case PW_LMT_PH_4T: + ntx_idx = RF_4TX; + break; + default: + RTW_PRINT("Wrong tx num:%d\n", ntx); + return; + } + + switch (Bandwidth) { + case PW_LMT_BW_20M: + bandwidth = CHANNEL_WIDTH_20; + break; + case PW_LMT_BW_40M: + bandwidth = CHANNEL_WIDTH_40; + break; + case PW_LMT_BW_80M: + bandwidth = CHANNEL_WIDTH_80; + break; + case PW_LMT_BW_160M: + bandwidth = CHANNEL_WIDTH_160; + break; + default: + RTW_PRINT("unknown bandwidth: %d\n", Bandwidth); + return; + } + + if (Band == PW_LMT_BAND_2_4G) { + band = BAND_ON_2_4G; + channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_2_4G, channel); + + if (channelIndex == -1) { + RTW_PRINT("unsupported channel: %d at 2.4G\n", channel); + return; + } + + if (bandwidth >= MAX_2_4G_BANDWIDTH_NUM) { + RTW_PRINT("unsupported bandwidth: %s at 2.4G\n", ch_width_str(bandwidth)); + return; + } + + rtw_txpwr_lmt_add(adapter_to_rfctl(Adapter), regd_str(regd), band, bandwidth, tlrs, ntx_idx, channelIndex, powerLimit); + } +#if CONFIG_IEEE80211_BAND_5GHZ + else if (Band == PW_LMT_BAND_5G) { + band = BAND_ON_5G; + channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_5G, channel); + + if (channelIndex == -1) { + RTW_PRINT("unsupported channel: %d at 5G\n", channel); + return; + } + + rtw_txpwr_lmt_add(adapter_to_rfctl(Adapter), regd_str(regd), band, bandwidth, tlrs, ntx_idx, channelIndex, powerLimit); + } +#endif + else { + RTW_PRINT("unknown/unsupported band:%d\n", Band); + return; + } +#endif +} + u8 phy_get_tx_power_index_ex(_adapter *adapter , enum rf_path rfpath, RATE_SECTION rs, enum MGN_RATE rate , enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch) @@ -3758,22 +3852,25 @@ void dump_tx_power_index_inline(void *sel, _adapter *adapter, u8 rfpath, enum ch struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); if (tic->utarget == hal_spec->txgi_max) { - RTW_PRINT_SEL(sel, "TXPWR: [%c][%s]cch:%u, %s %uT, idx:%u(0x%02x) = base(%d) + min((byr(%d) + btc(%d) + extra(%d)), lmt(%d), ulmt(%d)) + tpt(%d) + dpd(%d)\n" + RTW_PRINT_SEL(sel, "TXPWR: [%c][%s]cch:%u, %s %uT, idx:%u(0x%02x) = base(%d) + min((byr(%d) + btc(%d) + extra(%d)), rlmt(%d), lmt(%d), ulmt(%d)) + tpc(%d) + tpt(%d) + dpd(%d)\n" , rf_path_char(rfpath), ch_width_str(bw), cch , MGN_RATE_STR(rate), tic->ntx_idx + 1 , pwr_idx, pwr_idx, tic->base - , tic->by_rate, tic->btc, tic->extra, tic->limit, tic->ulimit + , tic->by_rate, tic->btc, tic->extra, tic->rlimit, tic->limit, tic->ulimit + , tic->tpc , tic->tpt, tic->dpd); } else { - RTW_PRINT_SEL(sel, "TXPWR: [%c][%s]cch:%u, %s %uT, idx:%u(0x%02x) = base(%d) + min(utgt(%d), lmt(%d), ulmt(%d)) + tpt(%d) + dpd(%d)\n" + RTW_PRINT_SEL(sel, "TXPWR: [%c][%s]cch:%u, %s %uT, idx:%u(0x%02x) = base(%d) + min(utgt(%d), rlmt(%d), lmt(%d), ulmt(%d)) + tpc(%d) + tpt(%d) + dpd(%d)\n" , rf_path_char(rfpath), ch_width_str(bw), cch , MGN_RATE_STR(rate), tic->ntx_idx + 1 , pwr_idx, pwr_idx, tic->base - , tic->utarget, tic->limit, tic->ulimit + , tic->utarget, tic->rlimit, tic->limit, tic->ulimit + , tic->tpc , tic->tpt, tic->dpd); } } +#ifdef CONFIG_PROC_DEBUG void dump_tx_power_idx_value(void *sel, _adapter *adapter, u8 rfpath, enum MGN_RATE rate, u8 pwr_idx, struct txpwr_idx_comp *tic) { struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); @@ -3783,17 +3880,19 @@ void dump_tx_power_idx_value(void *sel, _adapter *adapter, u8 rfpath, enum MGN_R if (tic->utarget == hal_spec->txgi_max) { RTW_PRINT_SEL(sel, "%4c %9s %uT %s %3u(0x%02x)" - " %4d ((%4d %3d %5d) %4d %4d) %3d %3d\n" + " %4d ((%4d %3d %5d) %4d %4d %4d) %3d %3d %3d\n" , rf_path_char(rfpath), MGN_RATE_STR(rate), tic->ntx_idx + 1 , tmp_str, pwr_idx, pwr_idx - , tic->base, tic->by_rate, tic->btc, tic->extra, tic->limit, tic->ulimit + , tic->base, tic->by_rate, tic->btc, tic->extra, tic->rlimit, tic->limit, tic->ulimit + , tic->tpc , tic->tpt, tic->dpd); } else { RTW_PRINT_SEL(sel, "%4c %9s %uT %s %3u(0x%02x)" - " %4d (%4d %4d %4d) %3d %3d\n" + " %4d (%4d %4d %4d %4d) %3d %3d %3d\n" , rf_path_char(rfpath), MGN_RATE_STR(rate), tic->ntx_idx + 1 , tmp_str, pwr_idx, pwr_idx - , tic->base, tic->utarget, tic->limit, tic->ulimit + , tic->base, tic->utarget, tic->rlimit, tic->limit, tic->ulimit + , tic->tpc , tic->tpt, tic->dpd); } } @@ -3819,15 +3918,17 @@ void dump_tx_power_idx_title(void *sel, _adapter *adapter, enum channel_width bw if (!phy_is_txpwr_user_target_specified(adapter)) { RTW_PRINT_SEL(sel, "%-4s %-9s %2s %-6s %-3s%6s" - " = %-4s + min((%-4s + %-3s + %-5s), %-4s, %-4s) + %-3s + %-3s\n" + " = %-4s + min((%-4s + %-3s + %-5s), %-4s, %-4s, %-4s) + %-3s + %-3s + %-3s\n" , "path", "rate", "", "dBm", "idx", "" - , "base", "byr", "btc", "extra", "lmt", "ulmt" + , "base", "byr", "btc", "extra", "rlmt", "lmt", "ulmt" + , "tpc" , "tpt", "dpd"); } else { RTW_PRINT_SEL(sel, "%-4s %-9s %2s %-6s %-3s%6s" - " = %-4s + min(%-4s, %-4s, %-4s) + %-3s + %-3s\n" + " = %-4s + min(%-4s, %-4s, %-4s, %-4s) + %-3s + %-3s + %-3s\n" , "path", "rate", "", "dBm", "idx", "" - , "base", "utgt", "lmt", "ulmt" + , "base", "utgt", "rlmt", "lmt", "ulmt" + , "tpc" , "tpt", "dpd"); } } @@ -3875,49 +3976,62 @@ void dump_tx_power_idx(void *sel, _adapter *adapter, enum channel_width bw, u8 c } void dump_txpwr_total_dbm_value(void *sel, _adapter *adapter, enum MGN_RATE rate, u8 ntx_idx - , s16 target, s16 byr, s16 btc, s16 extra, s16 lmt, s16 ulmt) + , s16 target, s16 byr, s16 btc, s16 extra, s16 rlmt, s16 lmt, s16 ulmt, s16 tpc) { char target_str[8]; char byr_str[8]; char btc_str[8]; char extra_str[8]; + char rlmt_str[8]; char lmt_str[8]; char ulmt_str[8]; + char tpc_str[8]; txpwr_mbm_get_dbm_str(target, 0, target_str, 8); txpwr_mbm_get_dbm_str(byr, 0, byr_str, 8); txpwr_mbm_get_dbm_str(btc, 0, btc_str, 8); txpwr_mbm_get_dbm_str(extra, 0, extra_str, 8); + txpwr_mbm_get_dbm_str(rlmt, 0, rlmt_str, 8); txpwr_mbm_get_dbm_str(lmt, 0, lmt_str, 8); txpwr_mbm_get_dbm_str(ulmt, 0, ulmt_str, 8); + txpwr_mbm_get_dbm_str(tpc, 0, tpc_str, 8); - RTW_PRINT_SEL(sel, "%9s %uT %s = ((%s %s %s), %s, %s)\n" + RTW_PRINT_SEL(sel, "%9s %uT %s = ((%s %s %s), %s, %s, %s) %s\n" , MGN_RATE_STR(rate), ntx_idx + 1 - , target_str, byr_str, btc_str, extra_str, lmt_str, ulmt_str); + , target_str, byr_str, btc_str, extra_str, rlmt_str, lmt_str, ulmt_str, tpc_str); } void dump_txpwr_total_dbm_value_utgt(void *sel, _adapter *adapter, enum MGN_RATE rate, u8 ntx_idx - , s16 target, s16 utgt, s16 lmt, s16 ulmt) + , s16 target, s16 utgt, s16 rlmt, s16 lmt, s16 ulmt, s16 tpc) { char target_str[8]; char utgt_str[8]; + char rlmt_str[8]; char lmt_str[8]; char ulmt_str[8]; + char tpc_str[8]; txpwr_mbm_get_dbm_str(target, 0, target_str, 8); txpwr_mbm_get_dbm_str(utgt, 0, utgt_str, 8); + txpwr_mbm_get_dbm_str(rlmt, 0, rlmt_str, 8); txpwr_mbm_get_dbm_str(lmt, 0, lmt_str, 8); txpwr_mbm_get_dbm_str(ulmt, 0, ulmt_str, 8); + txpwr_mbm_get_dbm_str(tpc, 0, tpc_str, 8); - RTW_PRINT_SEL(sel, "%9s %uT %s = (%s, %s, %s)\n" + RTW_PRINT_SEL(sel, "%9s %uT %s = (%s, %s, %s, %s) %s\n" , MGN_RATE_STR(rate), ntx_idx + 1 - , target_str, utgt_str, lmt_str, ulmt_str); + , target_str, utgt_str, rlmt_str, lmt_str, ulmt_str, tpc_str); } void dump_txpwr_total_dbm_title(void *sel, _adapter *adapter, enum channel_width bw, u8 cch, u8 opch) { + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + char antenna_gain_str[8]; u8 cch_20, cch_40, cch_80; + txpwr_mbm_get_dbm_str(rfctl->antenna_gain, 0, antenna_gain_str, 8); + RTW_PRINT_SEL(sel, "antenna_gain:%s\n", antenna_gain_str); + cch_80 = bw == CHANNEL_WIDTH_80 ? cch : 0; cch_40 = bw == CHANNEL_WIDTH_40 ? cch : 0; cch_20 = bw == CHANNEL_WIDTH_20 ? cch : 0; @@ -3934,11 +4048,11 @@ void dump_txpwr_total_dbm_title(void *sel, _adapter *adapter, enum channel_width _RTW_PRINT_SEL(sel, ", cch20:%u\n", cch_20); if (!phy_is_txpwr_user_target_specified(adapter)) { - RTW_PRINT_SEL(sel, "%-9s %2s %-6s = min((%-6s + %-6s + %-6s), %-6s, %-6s)\n" - , "rate", "", "target", "byr", "btc", "extra", "lmt", "ulmt"); + RTW_PRINT_SEL(sel, "%-9s %2s %-6s = min((%-6s + %-6s + %-6s), %-6s, %-6s, %-6s) + %-6s\n" + , "rate", "", "target", "byr", "btc", "extra", "rlmt", "lmt", "ulmt", "tpc"); } else { - RTW_PRINT_SEL(sel, "%-9s %2s %-6s = min(%-6s, %-6s, %-6s)\n" - , "rate", "", "target", "utgt", "lmt", "ulmt"); + RTW_PRINT_SEL(sel, "%-9s %2s %-6s = min(%-6s, %-6s, %-6s, %-6s) + %-6s\n" + , "rate", "", "target", "utgt", "rlmt", "lmt", "ulmt", "tpc"); } } @@ -3963,11 +4077,15 @@ void dump_txpwr_total_dbm_by_rs(void *sel, _adapter *adapter, u8 rs, enum channe for (i = 0; i < rates_by_sections[rs].rate_num; i++) { struct txpwr_idx_comp tic; - s16 target, byr, btc, extra, utgt, lmt, ulmt; + s16 target, byr, tpc, btc, extra, utgt, rlmt, lmt, ulmt; u8 tx_num; - target = phy_get_txpwr_total_mbm(adapter, rs, rates_by_sections[rs].rates[i], bw, cch, opch, &tic); + target = phy_get_txpwr_total_mbm(adapter, rs, rates_by_sections[rs].rates[i], bw, cch, opch, 0, 0, &tic); tx_num = tic.ntx_idx + 1; + if (tic.rlimit == hal_spec->txgi_max) + rlmt = UNSPECIFIED_MBM; + else + rlmt = ((tic.rlimit * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num); if (tic.limit == hal_spec->txgi_max) lmt = UNSPECIFIED_MBM; else @@ -3976,17 +4094,18 @@ void dump_txpwr_total_dbm_by_rs(void *sel, _adapter *adapter, u8 rs, enum channe ulmt = UNSPECIFIED_MBM; else ulmt = ((tic.ulimit * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num); + tpc = (tic.tpc * MBM_PDBM) / hal_spec->txgi_pdbm; if (tic.utarget == hal_spec->txgi_max) { byr = ((tic.by_rate * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num); btc = (tic.btc * MBM_PDBM) / hal_spec->txgi_pdbm; extra = (tic.extra * MBM_PDBM) / hal_spec->txgi_pdbm; dump_txpwr_total_dbm_value(sel, adapter, rates_by_sections[rs].rates[i], tic.ntx_idx - , target, byr, btc, extra, lmt, ulmt); + , target, byr, btc, extra, rlmt, lmt, ulmt, tpc); } else { utgt = ((tic.utarget * MBM_PDBM) / hal_spec->txgi_pdbm) + mb_of_ntx(tx_num); dump_txpwr_total_dbm_value_utgt(sel, adapter, rates_by_sections[rs].rates[i], tic.ntx_idx - , target, utgt, lmt, ulmt); + , target, utgt, rlmt, lmt, ulmt, tpc); } } } @@ -4000,6 +4119,7 @@ void dump_txpwr_total_dbm(void *sel, _adapter *adapter, enum channel_width bw, u for (rs = CCK; rs < RATE_SECTION_NUM; rs++) dump_txpwr_total_dbm_by_rs(sel, adapter, rs, bw, cch, opch); } +#endif bool phy_is_tx_power_limit_needed(_adapter *adapter) { @@ -4144,13 +4264,16 @@ void phy_load_tx_power_ext_info(_adapter *adapter, u8 chk_file) inline void phy_reload_tx_power_ext_info(_adapter *adapter) { phy_load_tx_power_ext_info(adapter, 1); + op_class_pref_apply_regulatory(adapter, REG_TXPWR_CHANGE); } inline void phy_reload_default_tx_power_ext_info(_adapter *adapter) { phy_load_tx_power_ext_info(adapter, 0); + op_class_pref_apply_regulatory(adapter, REG_TXPWR_CHANGE); } +#ifdef CONFIG_PROC_DEBUG void dump_tx_power_ext_info(void *sel, _adapter *adapter) { struct registry_priv *regsty = adapter_to_regsty(adapter); @@ -4264,7 +4387,7 @@ void dump_tx_power_by_rate(void *sel, _adapter *adapter) /* dump power by rate in db */ for (n = rate_num - 1; n >= 0; n--) { - by_rate = PHY_GetTxPowerByRate(adapter, band, path, rs, rates_by_sections[rs].rates[n]); + by_rate = phy_get_txpwr_by_rate(adapter, band, path, rs, rates_by_sections[rs].rates[n]); if (by_rate % hal_spec->txgi_pdbm) { _RTW_PRINT_SEL(sel, "%2d.%d ", by_rate / hal_spec->txgi_pdbm , (by_rate % hal_spec->txgi_pdbm) * 100 / hal_spec->txgi_pdbm); @@ -4278,7 +4401,7 @@ void dump_tx_power_by_rate(void *sel, _adapter *adapter) /* dump power by rate in offset */ for (n = rate_num - 1; n >= 0; n--) { - by_rate = PHY_GetTxPowerByRate(adapter, band, path, rs, rates_by_sections[rs].rates[n]); + by_rate = phy_get_txpwr_by_rate(adapter, band, path, rs, rates_by_sections[rs].rates[n]); base = phy_get_target_txpwr(adapter, band, path, rs); _RTW_PRINT_SEL(sel, "%3d ", by_rate - base); } @@ -4288,7 +4411,7 @@ void dump_tx_power_by_rate(void *sel, _adapter *adapter) } } } - +#endif /* * phy file path is stored in global char array rtw_phy_para_file_path * need to care about racing @@ -5655,6 +5778,36 @@ inline void phy_free_filebuf(_adapter *padapter) #endif +/* +* TX power limit of regulatory without HAL consideration +* Return value in unit of TX Gain Index +* hal_spec.txgi_max means unspecified +*/ +s8 phy_get_txpwr_regd_lmt(_adapter *adapter, struct hal_spec_t *hal_spec, u8 cch, enum channel_width bw, u8 ntx_idx) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + s16 total_mbm = UNSPECIFIED_MBM; + s8 lmt; + + if ((adapter->registrypriv.RegEnableTxPowerLimit == 2 && hal_data->EEPROMRegulatory != 1) || + adapter->registrypriv.RegEnableTxPowerLimit == 0) + goto exit; + +#ifdef CONFIG_REGD_SRC_FROM_OS + if (rfctl->regd_src == REGD_SRC_OS) + total_mbm = rtw_os_get_total_txpwr_regd_lmt_mbm(adapter, cch, bw); +#endif + +exit: + if (total_mbm != UNSPECIFIED_MBM) + lmt = (total_mbm - mb_of_ntx(ntx_idx + 1) - rfctl->antenna_gain) * hal_spec->txgi_pdbm / MBM_PDBM; + else + lmt = hal_spec->txgi_max; + + return lmt; +} + /* * check if user specified mbm is valid */ @@ -5686,6 +5839,7 @@ bool phy_is_txpwr_user_target_specified(_adapter *adapter) */ s8 phy_get_txpwr_user_target(_adapter *adapter, struct hal_spec_t *hal_spec, u8 ntx_idx) { + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); s16 total_mbm = UNSPECIFIED_MBM; s8 target; @@ -5693,7 +5847,7 @@ s8 phy_get_txpwr_user_target(_adapter *adapter, struct hal_spec_t *hal_spec, u8 total_mbm = rtw_cfg80211_dev_get_total_txpwr_target_mbm(adapter_to_dvobj(adapter)); #endif if (total_mbm != UNSPECIFIED_MBM) - target = (total_mbm - mb_of_ntx(ntx_idx + 1)) * hal_spec->txgi_pdbm / MBM_PDBM; + target = (total_mbm - mb_of_ntx(ntx_idx + 1) - rfctl->antenna_gain) * hal_spec->txgi_pdbm / MBM_PDBM; else target = hal_spec->txgi_max; @@ -5706,6 +5860,7 @@ s8 phy_get_txpwr_user_target(_adapter *adapter, struct hal_spec_t *hal_spec, u8 */ s8 phy_get_txpwr_user_lmt(_adapter *adapter, struct hal_spec_t *hal_spec, u8 ntx_idx) { + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); s16 total_mbm = UNSPECIFIED_MBM; s8 lmt; @@ -5713,32 +5868,69 @@ s8 phy_get_txpwr_user_lmt(_adapter *adapter, struct hal_spec_t *hal_spec, u8 ntx total_mbm = rtw_cfg80211_dev_get_total_txpwr_lmt_mbm(adapter_to_dvobj(adapter)); #endif if (total_mbm != UNSPECIFIED_MBM) - lmt = (total_mbm - mb_of_ntx(ntx_idx + 1)) * hal_spec->txgi_pdbm / MBM_PDBM; + lmt = (total_mbm - mb_of_ntx(ntx_idx + 1) - rfctl->antenna_gain) * hal_spec->txgi_pdbm / MBM_PDBM; else lmt = hal_spec->txgi_max; return lmt; } +/* +* Return value in unit of TX Gain Index +* 0 means unspecified +*/ +s8 phy_get_txpwr_tpc(_adapter *adapter, struct hal_spec_t *hal_spec) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + u16 cnst = 0; + + if (rfctl->tpc_mode == TPC_MODE_MANUAL) + cnst = rfctl->tpc_manual_constraint * hal_spec->txgi_pdbm / MBM_PDBM; + + return -cnst; +} + +void dump_txpwr_tpc_settings(void *sel, _adapter *adapter) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + if (rfctl->tpc_mode == TPC_MODE_DISABLE) + RTW_PRINT_SEL(sel, "mode:DISABLE(%d)\n", rfctl->tpc_mode); + else if (rfctl->tpc_mode == TPC_MODE_MANUAL) { + RTW_PRINT_SEL(sel, "mode:MANUAL(%d)\n", rfctl->tpc_mode); + RTW_PRINT_SEL(sel, "constraint:%d (mB)\n", rfctl->tpc_manual_constraint); + } +} + +void dump_txpwr_antenna_gain(void *sel, _adapter *adapter) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + RTW_PRINT_SEL(sel, "%d (mBi)\n", rfctl->antenna_gain); +} + /* * Return value in unit of TX Gain Index */ s8 phy_get_txpwr_target(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate, u8 ntx_idx - , enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch, struct txpwr_idx_comp *tic) + , enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch, bool reg_max, struct txpwr_idx_comp *tic) { HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); s8 target, by_rate = 0, btc_diff = 0, extra = 0; - s8 lmt, utgt, ulmt; + s8 lmt, rlmt, utgt, ulmt; + s8 tpc = 0; - lmt = utgt = ulmt = hal_spec->txgi_max; + rlmt = lmt = utgt = ulmt = hal_spec->txgi_max; if (band != BAND_ON_2_4G && IS_CCK_RATE(rate)) goto exit; - utgt = phy_get_txpwr_user_target(adapter, hal_spec, ntx_idx); - if (utgt != hal_spec->txgi_max) - goto get_lmt; + if (!reg_max) { + utgt = phy_get_txpwr_user_target(adapter, hal_spec, ntx_idx); + if (utgt != hal_spec->txgi_max) + goto get_lmt; + } #ifdef CONFIG_RTL8812A if (IS_HARDWARE_TYPE_8812(adapter) @@ -5746,33 +5938,44 @@ s8 phy_get_txpwr_target(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate, by_rate = phy_get_target_txpwr(adapter, band, rfpath, rs); else #endif - by_rate = PHY_GetTxPowerByRate(adapter, band, rfpath, rs, rate); + by_rate = phy_get_txpwr_by_rate(adapter, band, rfpath, rs, rate); if (by_rate == hal_spec->txgi_max) by_rate = 0; #ifdef CONFIG_BT_COEXIST - if (hal_data->EEPROMBluetoothCoexist == _TRUE) - btc_diff = -(rtw_btcoex_query_reduced_wl_pwr_lvl(adapter) * hal_spec->txgi_pdbm); + if (!reg_max) { + if (hal_data->EEPROMBluetoothCoexist == _TRUE) + btc_diff = -(rtw_btcoex_query_reduced_wl_pwr_lvl(adapter) * hal_spec->txgi_pdbm); + } #endif extra = rtw_hal_get_txpwr_target_extra_bias(adapter, rfpath, rs, rate, bw, band, cch); get_lmt: - lmt = phy_get_txpwr_lmt_sub_chs(adapter, NULL, band, bw, rfpath, rate, ntx_idx, cch, opch); - ulmt = phy_get_txpwr_user_lmt(adapter, hal_spec, ntx_idx); + rlmt = phy_get_txpwr_regd_lmt(adapter, hal_spec, cch, bw, ntx_idx); + lmt = phy_get_txpwr_lmt_sub_chs(adapter, NULL, band, bw, rfpath, rate, ntx_idx, cch, opch, reg_max); + if (!reg_max) + ulmt = phy_get_txpwr_user_lmt(adapter, hal_spec, ntx_idx); /* TODO: limit from outer source, ex: 11d */ + if (!reg_max) + tpc = phy_get_txpwr_tpc(adapter, hal_spec); + exit: if (utgt != hal_spec->txgi_max) target = utgt; else target = by_rate + btc_diff + extra; + if (target > rlmt) + target = rlmt; if (target > lmt) target = lmt; if (target > ulmt) target = ulmt; + target += tpc; + if (tic) { tic->target = target; if (utgt == hal_spec->txgi_max) { @@ -5781,8 +5984,10 @@ exit: tic->extra = extra; } tic->utarget = utgt; + tic->rlimit = rlmt; tic->limit = lmt; tic->ulimit = ulmt; + tic->tpc = tpc; } return target; @@ -5837,7 +6042,7 @@ s8 phy_get_tssi_txpwr_by_rate_ref(_adapter *adapter, enum rf_path path s8 pwr_idx; pwr_idx = phy_get_txpwr_target(adapter, path, HT_1SS, MGN_MCS7 - , ntx_idx, bw, band, cch, opch, NULL); + , ntx_idx, bw, band, cch, opch, 0, NULL); pwr_idx += phy_get_txpwr_amends(adapter, path, HT_1SS, MGN_MCS7 , ntx_idx, bw, band, cch, NULL); @@ -5860,7 +6065,7 @@ u8 hal_com_get_txpwr_idx(_adapter *adapter, enum rf_path rfpath u8 ntx_idx = phy_get_current_tx_num(adapter, rate); /* target */ - rate_target = phy_get_txpwr_target(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, opch, tic); + rate_target = phy_get_txpwr_target(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, opch, 0, tic); /* amends */ rate_amends = phy_get_txpwr_amends(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, tic); @@ -5885,6 +6090,8 @@ u8 hal_com_get_txpwr_idx(_adapter *adapter, enum rf_path rfpath tic->by_rate -= rs_target; else tic->utarget -= rs_target; + if (tic->rlimit != hal_spec->txgi_max) + tic->rlimit -= rs_target; if (tic->limit != hal_spec->txgi_max) tic->limit -= rs_target; if (tic->ulimit != hal_spec->txgi_max) @@ -5931,39 +6138,64 @@ u8 hal_com_get_txpwr_idx(_adapter *adapter, enum rf_path rfpath return power_idx; } -/* get txpowr in mBm for single path */ -s16 phy_get_txpwr_single_mbm(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate - , enum channel_width bw, u8 cch, u8 opch, struct txpwr_idx_comp *tic) +static s16 phy_get_txpwr_mbm(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate + , enum channel_width bw, u8 cch, u8 opch, bool total, bool reg_max, bool eirp, struct txpwr_idx_comp *tic) { struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); BAND_TYPE band = cch <= 14 ? BAND_ON_2_4G : BAND_ON_5G; - u8 ntx_idx = phy_get_current_tx_num(adapter, rate); - s16 val; + u8 ntx_idx_max, ntx_idx, i; + s16 val, max = UNSPECIFIED_MBM; + + if (reg_max) { + ntx_idx_max = phy_get_capable_tx_num(adapter, rate); + ntx_idx = rate_section_to_tx_num(rs); + if (ntx_idx > ntx_idx_max) { + rtw_warn_on(1); + return 0; + } + } else + ntx_idx_max = ntx_idx = phy_get_current_tx_num(adapter, rate); + + for (i = 0; ntx_idx + i <= ntx_idx_max; i++) { + val = phy_get_txpwr_target(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, opch, reg_max, tic); + val = (val * MBM_PDBM) / hal_spec->txgi_pdbm; + if (total) + val += mb_of_ntx(ntx_idx + 1); + if (eirp) + val += rfctl->antenna_gain; + + if (max == UNSPECIFIED_MBM || max < val) + max = val; + } - val = phy_get_txpwr_target(adapter, rfpath, rs, rate, ntx_idx, bw, band, cch, opch, tic); - val = (val * MBM_PDBM) / hal_spec->txgi_pdbm; if (tic) tic->ntx_idx = ntx_idx; - return val; + if (max == UNSPECIFIED_MBM) { + rtw_warn_on(1); + max = 0; + } + return max; +} + +/* get txpowr in mBm for single path */ +s16 phy_get_txpwr_single_mbm(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate + , enum channel_width bw, u8 cch, u8 opch, bool reg_max, bool eirp, struct txpwr_idx_comp *tic) +{ + return phy_get_txpwr_mbm(adapter, rfpath, rs, rate, bw, cch, opch, 0, reg_max, eirp, tic); } /* get txpowr in mBm with effect of N-TX */ s16 phy_get_txpwr_total_mbm(_adapter *adapter, RATE_SECTION rs, u8 rate - , enum channel_width bw, u8 cch, u8 opch, struct txpwr_idx_comp *tic) + , enum channel_width bw, u8 cch, u8 opch, bool reg_max, bool eirp, struct txpwr_idx_comp *tic) { - s16 val; - u8 tx_num = phy_get_current_tx_num(adapter, rate) + 1; - /* assume all path have same txpower target */ - val = phy_get_txpwr_single_mbm(adapter, RF_PATH_A, rs, rate, bw, cch, opch, tic); - val += mb_of_ntx(tx_num); - - return val; + return phy_get_txpwr_mbm(adapter, RF_PATH_A, rs, rate, bw, cch, opch, 1, reg_max, eirp, tic); } static s16 _phy_get_txpwr_max_mbm(_adapter *adapter, s8 rfpath - , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht) + , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool reg_max, bool eirp) { struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); @@ -6002,9 +6234,9 @@ static s16 _phy_get_txpwr_max_mbm(_adapter *adapter, s8 rfpath } if (rfpath < 0) /* total */ - mbm = phy_get_txpwr_total_mbm(adapter, rs, rates_by_sections[rs].rates[i], bw, cch, opch, NULL); + mbm = phy_get_txpwr_total_mbm(adapter, rs, rates_by_sections[rs].rates[i], bw, cch, opch, reg_max, eirp, NULL); else - mbm = phy_get_txpwr_single_mbm(adapter, rfpath, rs, rates_by_sections[rs].rates[i], bw, cch, opch, NULL); + mbm = phy_get_txpwr_single_mbm(adapter, rfpath, rs, rates_by_sections[rs].rates[i], bw, cch, opch, reg_max, eirp, NULL); if (max == UNSPECIFIED_MBM || mbm > max) max = mbm; @@ -6015,15 +6247,15 @@ static s16 _phy_get_txpwr_max_mbm(_adapter *adapter, s8 rfpath } s16 phy_get_txpwr_single_max_mbm(_adapter *adapter, u8 rfpath - , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht) + , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool reg_max, bool eirp) { - return _phy_get_txpwr_max_mbm(adapter, rfpath, bw, cch, opch, bmp_cck_ofdm, bmp_ht, bmp_vht); + return _phy_get_txpwr_max_mbm(adapter, rfpath, bw, cch, opch, bmp_cck_ofdm, bmp_ht, bmp_vht, reg_max, eirp); } s16 phy_get_txpwr_total_max_mbm(_adapter *adapter - , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht) + , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool reg_max, bool eirp) { - return _phy_get_txpwr_max_mbm(adapter, -1, bw, cch, opch, bmp_cck_ofdm, bmp_ht, bmp_vht); + return _phy_get_txpwr_max_mbm(adapter, -1, bw, cch, opch, bmp_cck_ofdm, bmp_ht, bmp_vht, reg_max, eirp); } s8 @@ -6036,7 +6268,7 @@ phy_get_tx_power_final_absolute_value(_adapter *adapter, u8 rfpath, u8 rate, s8 val; val = phy_get_txpwr_target(adapter, rfpath - , rs, rate, phy_get_current_tx_num(adapter, rate), bw, band, cch, 0, NULL); + , rs, rate, phy_get_current_tx_num(adapter, rate), bw, band, cch, 0, 0, NULL); val /= hal_spec->txgi_pdbm; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm.c index 3abd4aa976b1..b556c5f06ad2 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm.c @@ -87,7 +87,8 @@ void rtw_hal_update_iqk_fw_offload_cap(_adapter *adapter) } } -#if ((RTL8822B_SUPPORT == 1) || (RTL8821C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8822C_SUPPORT == 1)) +#if ((RTL8822B_SUPPORT == 1) || (RTL8821C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8822C_SUPPORT == 1) \ + || (RTL8723F_SUPPORT == 1)) void rtw_phydm_iqk_trigger(_adapter *adapter) { struct dm_struct *p_dm_odm = adapter_to_phydm(adapter); @@ -96,7 +97,7 @@ void rtw_phydm_iqk_trigger(_adapter *adapter) u8 rfk_forbidden = _FALSE; halrf_cmn_info_set(p_dm_odm, HALRF_CMNINFO_RFK_FORBIDDEN, rfk_forbidden); -#if (RTL8822C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) +#if (RTL8822C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8723F_SUPPORT == 1) /* halrf_cmn_info_set(p_dm_odm, HALRF_CMNINFO_IQK_SEGMENT, segment); to do */ halrf_rf_k_connect_trigger(p_dm_odm, _TRUE, SEGMENT_FREE); #else @@ -107,6 +108,30 @@ void rtw_phydm_iqk_trigger(_adapter *adapter) } #endif +void rtw_phydm_iqk_trigger_all(_adapter *adapter) +{ + struct dm_struct *p_dm_odm = adapter_to_phydm(adapter); + u8 clear = _TRUE; + u8 segment = _FALSE; + u8 rfk_forbidden = _FALSE; + +#if ((RTL8822B_SUPPORT == 1) || (RTL8821C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8822C_SUPPORT == 1) \ + || (RTL8723F_SUPPORT == 1)) + halrf_cmn_info_set(p_dm_odm, HALRF_CMNINFO_RFK_FORBIDDEN, rfk_forbidden); +#if (RTL8822C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8723F_SUPPORT == 1) + /* halrf_cmn_info_set(p_dm_odm, HALRF_CMNINFO_IQK_SEGMENT, segment); to do */ + halrf_rf_k_connect_trigger(p_dm_odm, _TRUE, SEGMENT_FREE); +#else + /*segment = _rtw_phydm_iqk_segment_chk(adapter);*/ + halrf_cmn_info_set(p_dm_odm, HALRF_CMNINFO_IQK_SEGMENT, segment); + halrf_segment_iqk_trigger(p_dm_odm, clear, segment); +#endif /* (RTL8822C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) (RTL8723F_SUPPORT == 1) */ +#else + halrf_iqk_trigger(p_dm_odm, _FALSE); +#endif /* ((RTL8822B_SUPPORT == 1) || (RTL8821C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8822C_SUPPORT == 1)) + (RTL8723F_SUPPORT == 1) */ +} + void rtw_phydm_iqk_trigger_dbg(_adapter *adapter, bool recovery, bool clear, bool segment) { struct dm_struct *p_dm_odm = adapter_to_phydm(adapter); @@ -123,6 +148,19 @@ void rtw_phydm_lck_trigger(_adapter *adapter) halrf_lck_trigger(p_dm_odm); } + +void rtw_hal_phydm_cal_trigger(_adapter *adapter) +{ + struct dm_struct *p_dm_odm = adapter_to_phydm(adapter); + + rtw_ps_deny(adapter, PS_DENY_IOCTL); + LeaveAllPowerSaveModeDirect(adapter); + + rtw_phydm_iqk_trigger_all(adapter); + + rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL); +} + #ifdef CONFIG_DBG_RF_CAL void rtw_hal_iqk_test(_adapter *adapter, bool recovery, bool clear, bool segment) { @@ -371,7 +409,7 @@ void Init_ODM_ComInfo(_adapter *adapter) rtw_hal_set_odm_var(adapter, HAL_ODM_REGULATION, NULL, _TRUE); #ifdef CONFIG_DFS_MASTER - odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_DFS_REGION_DOMAIN, adapter->registrypriv.dfs_region_domain); + rtw_odm_update_dfs_region(dvobj); odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_DFS_MASTER_ENABLE, &(adapter_to_rfctl(adapter)->radar_detect_enabled)); #endif @@ -1037,8 +1075,7 @@ void GetHalODMVar( #ifdef RTW_HALMAC #include "../hal_halmac.h" #endif - -int rtw_phydm_rfe_ctrl_gpio( +bool rtw_phydm_rfe_ctrl_gpio( _adapter *adapter, u8 gpio_num ) @@ -1047,8 +1084,8 @@ int rtw_phydm_rfe_ctrl_gpio( if(rtw_halmac_rfe_ctrl_cfg(adapter_to_dvobj(adapter), gpio_num)) return _TRUE; else - return _FALSE; #endif/*RTW_HALMAC*/ + return _FALSE; } enum hal_status @@ -1175,6 +1212,7 @@ rtw_phydm_cfg_phy_para( void rtw_phydm_wd_lps_lclk_hdl(_adapter *adapter) { struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter); struct sta_priv *pstapriv = &adapter->stapriv; struct sta_info *psta = NULL; @@ -1196,6 +1234,14 @@ void rtw_phydm_wd_lps_lclk_hdl(_adapter *adapter) odm_cmn_info_update(&pHalData->odmpriv, ODM_CMNINFO_LINK, is_linked); phydm_watchdog_lps_32k(&pHalData->odmpriv); + +#ifdef CONFIG_LPS_PG + if (pwrpriv->lps_level == LPS_PG) { + if (rtw_hal_set_lps_pg_info_cmd(adapter) == _FAIL) + RTW_INFO(FUNC_ADPT_FMT": Send PG H2C command Fail! \n", + FUNC_ADPT_ARG(adapter)); + } +#endif /* CONFIG_LPS_PG */ } void rtw_phydm_watchdog_in_lps_lclk(_adapter *adapter) @@ -1395,14 +1441,7 @@ void rtw_phydm_trx_cfg(_adapter *adapter, bool tx_1ss) } #endif - -/* -* trx_mode init - 8822B / 8822C / 8192F -* 1ssNTx - 8192E / 8812A / 8822B / 8822C / 8192F -* Path-diversity - 8822B / 8822C / 8192F -* PHYDM API - phydm_api_trx_mode -*/ -static u8 rtw_phydm_config_trx_path(_adapter *adapter) +u8 rtw_hal_runtime_trx_path_decision(_adapter *adapter) { HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); enum bb_path txpath; @@ -1461,13 +1500,6 @@ static u8 rtw_phydm_config_trx_path(_adapter *adapter) } else txpath_1ss = txpath; - if (phydm_api_trx_mode(adapter_to_phydm(adapter), txpath, rxpath, txpath_1ss) == FALSE) { - RTW_ERR("%s txpath=0x%x, rxpath=0x%x, txpath_1ss=0x%x fail\n", __func__ - , txpath, rxpath, txpath_1ss); - rtw_warn_on(1); - goto exit; - } - if (hal_data->txpath_nss[0] != txpath_1ss) { hal_data->txpath_nss[0] = txpath_1ss; if (txpath_1ss == BB_PATH_AUTO) @@ -1483,23 +1515,14 @@ static u8 rtw_phydm_config_trx_path(_adapter *adapter) } #elif defined(CONFIG_RTL8814B) { - if (config_phydm_trx_mode_8814b(adapter_to_phydm(adapter), txpath, rxpath) == FALSE) { - RTW_ERR("%s txpath=0x%x, rxpath=0x%x fail\n", __func__ - , txpath, rxpath); - rtw_warn_on(1); - goto exit; - } - /* 8814B is always full-TX */ tx_path_nss_set_full_tx(hal_data->txpath_nss, hal_data->txpath_num_nss, txpath); } #elif defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8192E) { #ifdef CONFIG_RTW_TX_NPATH_EN - if (adapter->registrypriv.tx_npath == 1) { - phydm_tx_2path(adapter_to_phydm(adapter)); + if (adapter->registrypriv.tx_npath == 1) tx_path_nss_set_full_tx(hal_data->txpath_nss, hal_data->txpath_num_nss, txpath); - } #endif } #endif @@ -1513,6 +1536,61 @@ exit: return rst; } +/* +* trx_mode init - 8822B / 8822C / 8192F +* 1ssNTx - 8192E / 8812A / 8822B / 8822C / 8192F +* Path-diversity - 8822B / 8822C / 8192F +* PHYDM API - phydm_api_trx_mode +*/ +static u8 rtw_phydm_config_trx_path(_adapter *adapter) +{ + u8 rst = _SUCCESS; + +#if defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8822B) ||defined(CONFIG_RTL8822C) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + enum bb_path txpath = hal_data->txpath; + enum bb_path rxpath = hal_data->rxpath; + enum bb_path txpath_1ss = hal_data->txpath_nss[0]; + + if (phydm_api_trx_mode(adapter_to_phydm(adapter), txpath, rxpath, txpath_1ss) == FALSE) { + RTW_ERR("%s txpath=0x%x, rxpath=0x%x, txpath_1ss=0x%x fail\n", __func__ + , txpath, rxpath, txpath_1ss); + rtw_warn_on(1); + rst = _FAIL; + } +} +#elif defined(CONFIG_RTL8814B) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + enum bb_path txpath = hal_data->txpath; + enum bb_path rxpath = hal_data->rxpath; + + if (txpath == BB_PATH_ABCD && rxpath == BB_PATH_ABCD) + rst = config_phydm_trx_mode_8814b(adapter_to_phydm(adapter), txpath, rxpath); + else + rst = config_phydm_trx_mode_ext_8814b(adapter_to_phydm(adapter), txpath, + rxpath, + txpath, txpath, txpath); + if (rst == FALSE) { + RTW_ERR("%s txpath=0x%x, rxpath=0x%x fail\n", __func__ + , txpath, rxpath); + rtw_warn_on(1); + rst = _FAIL; + } +} +#elif defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8192E) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + + if (hal_data->txpath_num_nss[0] == 2) + phydm_tx_2path(adapter_to_phydm(adapter)); +} +#endif + + return rst; +} + void rtw_phydm_init(_adapter *adapter) { PHAL_DATA_TYPE hal_data = GET_HAL_DATA(adapter); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm.h index 0216e86a9e72..237520eb7449 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm.h @@ -55,6 +55,7 @@ void rtw_hal_update_iqk_fw_offload_cap(_adapter *adapter); void dump_sta_info(void *sel, struct sta_info *psta); void dump_sta_traffic(void *sel, _adapter *adapter, struct sta_info *psta); +void rtw_hal_phydm_cal_trigger(_adapter *adapter); #ifdef CONFIG_DBG_RF_CAL void rtw_hal_iqk_test(_adapter *adapter, bool recovery, bool clear, bool segment); void rtw_hal_lck_test(_adapter *adapter); @@ -95,7 +96,8 @@ enum phy_cnt { CRC32_ERROR_CCK, }; u32 rtw_phydm_get_phy_cnt(_adapter *adapter, enum phy_cnt cnt); -#if ((RTL8822B_SUPPORT == 1) || (RTL8821C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8822C_SUPPORT == 1)) +#if ((RTL8822B_SUPPORT == 1) || (RTL8821C_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8822C_SUPPORT == 1) \ + || (RTL8723F_SUPPORT == 1)) void rtw_phydm_iqk_trigger(_adapter *adapter); #endif void rtw_phydm_read_efuse(_adapter *adapter); @@ -115,5 +117,6 @@ void rtw_phydm_pwr_tracking_directly(_adapter *adapter); #ifdef CONFIG_CTRL_TXSS_BY_TP void rtw_phydm_trx_cfg(_adapter *adapter, bool tx_1ss); #endif -int rtw_phydm_rfe_ctrl_gpio(_adapter *adapter, u8 gpio_num); +u8 rtw_hal_runtime_trx_path_decision(_adapter *adapter); +bool rtw_phydm_rfe_ctrl_gpio(_adapter *adapter, u8 gpio_num); #endif /* __HAL_DM_H__ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm_acs.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm_acs.c index 9b581a6059c6..831b38604f66 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm_acs.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm_acs.c @@ -88,8 +88,16 @@ u8 rtw_phydm_nhm_ratio(_adapter *adapter) { struct dm_struct *phydm = adapter_to_phydm(adapter); - return phydm_cmn_info_query(phydm, (enum phydm_info_query) PHYDM_INFO_NHM_RATIO); + return phydm_cmn_info_query(phydm, (enum phydm_info_query) PHYDM_INFO_NHM_ENV_RATIO); } + +u8 rtw_phydm_nhm_noise_pwr(_adapter *adapter) +{ + struct dm_struct *phydm = adapter_to_phydm(adapter); + + return phydm_cmn_info_query(phydm, (enum phydm_info_query) PHYDM_INFO_NHM_PWR); +} + void rtw_acs_reset(_adapter *adapter) { HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); @@ -204,7 +212,8 @@ void rtw_acs_get_rst(_adapter *adapter) (rpt.clm_rpt_stamp == hal_data->acs.trig_rpt.clm_rpt_stamp) && (rpt.nhm_rpt_stamp == hal_data->acs.trig_rpt.nhm_rpt_stamp)){ hal_data->acs.clm_ratio[chan_idx] = rpt.clm_ratio; - hal_data->acs.nhm_ratio[chan_idx] = rpt.nhm_ratio; + hal_data->acs.nhm_ratio[chan_idx] = rpt.nhm_env_ratio; + hal_data->acs.env_mntr_rpt[chan_idx] = (rpt.nhm_noise_pwr -100); _rtw_memcpy(&hal_data->acs.nhm[chan_idx][0], rpt.nhm_result, NHM_RPT_NUM); /*RTW_INFO("[ACS] get_rst success (rst = 0x%02x, clm_stamp:%d:%d, nhm_stamp:%d:%d)\n", @@ -229,6 +238,8 @@ void rtw_acs_get_rst(_adapter *adapter) #ifdef CONFIG_RTW_ACS_DBG RTW_INFO("[ACS] Result CH:%d, CLM:%d NHM:%d\n", cur_chan, hal_data->acs.clm_ratio[chan_idx], hal_data->acs.nhm_ratio[chan_idx]); + RTW_INFO("[ACS] Result NHM(dBm):%d\n", + hal_data->acs.env_mntr_rpt[chan_idx] ); #endif } @@ -247,9 +258,9 @@ void _rtw_phydm_acs_select_best_chan(_adapter *adapter) for (ch_idx = 0; ch_idx < max_chan_nums; ch_idx++) { if (pbss_nums[ch_idx]) - pinterference_time[ch_idx] = (pclm_ratio[ch_idx] / 2) + pnhm_ratio[ch_idx]; + pinterference_time[ch_idx] = (pclm_ratio[ch_idx] / 2) + (pnhm_ratio[ch_idx] / 2); else - pinterference_time[ch_idx] = pclm_ratio[ch_idx] + pnhm_ratio[ch_idx]; + pinterference_time[ch_idx] = (pclm_ratio[ch_idx] / 3) + ((pnhm_ratio[ch_idx] * 2) / 3); if (rtw_get_ch_num_by_idx(adapter, ch_idx) < 14) { if (pinterference_time[ch_idx] < min_itf_24g) { @@ -359,6 +370,18 @@ u8 rtw_acs_get_nhm_ratio_by_ch_num(_adapter *adapter, u8 chan) return hal_data->acs.nhm_ratio[chan_idx]; } +u8 rtw_acs_get_nhm_noise_pwr_by_ch_idx(_adapter *adapter, u8 ch_idx) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + + if (ch_idx >= MAX_CHANNEL_NUM) { + RTW_ERR("%s [ACS] ch_idx(%d) is invalid\n", __func__, ch_idx); + return 0; + } + + return hal_data->acs.env_mntr_rpt[ch_idx]; +} + u8 rtw_acs_get_num_ratio_by_ch_idx(_adapter *adapter, u8 ch_idx) { HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm_acs.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm_acs.h index c515deed624e..1ed0d99a3d35 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm_acs.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_dm_acs.h @@ -81,6 +81,7 @@ struct auto_chan_sel { bool triggered; u8 clm_ratio[MAX_CHANNEL_NUM]; u8 nhm_ratio[MAX_CHANNEL_NUM]; + s8 env_mntr_rpt[MAX_CHANNEL_NUM]; #if (RTK_ACS_VERSION == 3) u8 nhm[MAX_CHANNEL_NUM][NHM_RPT_NUM]; #endif @@ -125,8 +126,13 @@ void rtw_acs_adv_reset(_adapter *adapter); u8 rtw_acs_get_clm_ratio_by_ch_num(_adapter *adapter, u8 chan); u8 rtw_acs_get_clm_ratio_by_ch_idx(_adapter *adapter, u8 ch_idx); u8 rtw_acs_get_nhm_ratio_by_ch_num(_adapter *adapter, u8 chan); +u8 rtw_acs_get_nhm_noise_pwr_by_ch_idx(_adapter *adapter, u8 ch_idx); u8 rtw_acs_get_num_ratio_by_ch_idx(_adapter *adapter, u8 ch_idx); +u8 rtw_phydm_clm_ratio(_adapter *adapter); +u8 rtw_phydm_nhm_ratio(_adapter *adapter); +u8 rtw_phydm_nhm_noise_pwr(_adapter *adapter); + void rtw_acs_reset(_adapter *adapter); void rtw_acs_trigger(_adapter *adapter, u16 scan_time_ms, u8 scan_chan, enum NHM_PID pid); void rtw_acs_get_rst(_adapter *adapter); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_halmac.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_halmac.c index b3c212a5c4bc..15d2b0906ac1 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_halmac.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_halmac.c @@ -1284,9 +1284,13 @@ int rtw_halmac_init_adapter(struct dvobj_priv *d, struct halmac_platform_api *pf /* Convert clock speed unit to MHz from Hz */ info.clock_speed = RTW_DIV_ROUND_UP(rtw_sdio_get_clock(d), 1000000); info.block_size = rtw_sdio_get_block_size(d); - RTW_DBG("%s: SDIO ver=%u clock=%uMHz blk_size=%u bytes\n", + if (d->hmpriv.sdio_io_indir == 2) + info.io_indir_flag = 0; + else + info.io_indir_flag = 1; /* Default enable indirect I/O */ + RTW_DBG("%s: SDIO ver=%u clock=%uMHz blk_size=%u bytes, io_indir=%u\n", __FUNCTION__, info.spec_ver+2, info.clock_speed, - info.block_size); + info.block_size, info.io_indir_flag); status = api->halmac_sdio_hw_info(halmac, &info); if (status != HALMAC_RET_SUCCESS) { RTW_ERR("%s: halmac_sdio_hw_info fail!(status=%d)\n", @@ -3105,7 +3109,7 @@ static int _send_general_info(struct dvobj_priv *d) case HALMAC_RET_NO_DLFW: RTW_WARN("%s: halmac_send_general_info() fail because fw not dl!\n", __FUNCTION__); - /* go through */ + /* fall through */ default: return -1; } @@ -5458,6 +5462,37 @@ int rtw_halmac_pno_scanoffload(struct dvobj_priv *d, u32 enable) #ifdef CONFIG_SDIO_HCI +/** + * rtw_halmac_preinit_sdio_io_indirect() - Enable indirect I/O or not + * @d: struct dvobj_priv* + * @enable: true: enable, false: disable + * + * Enable register access using direct I/O or indirect. This function should be + * called before rtw_halmac_init_adapter(), and the life cycle is the same as + * driver until removing driver. + * + * Return 0 for OK, otherwise fail. + */ +int rtw_halmac_preinit_sdio_io_indirect(struct dvobj_priv *d, bool enable) +{ + struct halmac_adapter *halmac; + struct halmacpriv *priv; + + + halmac = dvobj_to_halmac(d); + if (halmac) { + RTW_WARN("%s: illegal operation! " + "preinit function only could be called before init!\n", + __FUNCTION__); + return -1; + } + + priv = &d->hmpriv; + priv->sdio_io_indir = (enable ? 1 : 2); + + return 0; +} + /* * Description: * Update queue allocated page number to driver diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_halmac.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_halmac.h index cbb067e46b71..70670ca199bb 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_halmac.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_halmac.h @@ -117,6 +117,9 @@ int rtw_halmac_write32(struct intf_hdl *, u32 addr, u32 value); /* Software Information */ void rtw_halmac_get_version(char *str, u32 len); +/* Software setting before Initialization */ +int rtw_halmac_preinit_sdio_io_indirect(struct dvobj_priv *d, bool enable); + /* Software Initialization */ int rtw_halmac_init_adapter(struct dvobj_priv *d, struct halmac_platform_api *pf_api); int rtw_halmac_deinit_adapter(struct dvobj_priv *); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_hci/hal_sdio.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_hci/hal_sdio.c index afc2c369d0b9..70e1e08d1fbd 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_hci/hal_sdio.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_hci/hal_sdio.c @@ -180,6 +180,12 @@ void rtw_hal_set_sdio_tx_max_length(PADAPTER padapter, u8 numHQ, u8 numNQ, u8 nu pHalData->sdio_tx_max_len[HI_QUEUE_IDX] = (lenHQ > MAX_XMITBUF_SZ) ? MAX_XMITBUF_SZ : lenHQ; pHalData->sdio_tx_max_len[MID_QUEUE_IDX] = (lenNQ > MAX_XMITBUF_SZ) ? MAX_XMITBUF_SZ : lenNQ; pHalData->sdio_tx_max_len[LOW_QUEUE_IDX] = (lenLQ > MAX_XMITBUF_SZ) ? MAX_XMITBUF_SZ : lenLQ; + #ifdef DBG_TX_FREE_PAGE + RTW_INFO("rtw_hal_set_sdio_tx_max_length div_num :%u numHQ=%u numNQ=%u numLQ=%u numPubQ=%u\n",div_num ,numHQ,numNQ,numLQ,numPubQ); + RTW_INFO("pHalData->sdio_tx_max_len[HI_QUEUE_IDX] :%u\n",pHalData->sdio_tx_max_len[HI_QUEUE_IDX] ); + RTW_INFO("pHalData->sdio_tx_max_len[MID_QUEUE_IDX] :%u\n",pHalData->sdio_tx_max_len[MID_QUEUE_IDX] ); + RTW_INFO("rtw_hal_set_sdio_tx_max_length pHalData->sdio_tx_max_len[LOW_QUEUE_IDX] :%u\n",pHalData->sdio_tx_max_len[LOW_QUEUE_IDX] ); + #endif } u32 rtw_hal_get_sdio_tx_max_length(PADAPTER padapter, u8 queue_idx) @@ -212,7 +218,7 @@ u32 rtw_hal_get_sdio_tx_max_length(PADAPTER padapter, u8 queue_idx) } #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT -#if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) || defined(CONFIG_RTL8821A) +#if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) ||defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8192F)|| defined(CONFIG_RTL8723D) void rtw_hal_sdio_avail_page_threshold_init(_adapter *adapter) { HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); @@ -220,11 +226,15 @@ void rtw_hal_sdio_avail_page_threshold_init(_adapter *adapter) hal_data->sdio_avail_int_en_q = 0xFF; rtw_write32(adapter, REG_TQPNT1, 0xFFFFFFFF); rtw_write32(adapter, REG_TQPNT2, 0xFFFFFFFF); + #ifdef CONFIG_RTL8192F + rtw_write32(adapter, REG_TQPNT3_V1_8192F, 0xFFFFFFFF); + #endif } -void rtw_hal_sdio_avail_page_threshold_en(_adapter *adapter, u8 qidx) +void rtw_hal_sdio_avail_page_threshold_en(_adapter *adapter, u8 qidx, u8 page) { HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); if (hal_data->sdio_avail_int_en_q != qidx) { u32 page_size; @@ -233,11 +243,16 @@ void rtw_hal_sdio_avail_page_threshold_en(_adapter *adapter, u8 qidx) u8 dw_shift[] = {0, 16, 0, 16}; /* H, M, L, E */ u32 threshold = 0; - rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size); - tx_max_len = hal_data->sdio_tx_max_len[qidx]; - /* use same low-high threshold as page num from tx_max_len */ - threshold = PageNum(tx_max_len, page_size); + if(dvobj->tx_aval_int_thr_mode == 0) /*default setting by requirement*/ + threshold = page; + else if (dvobj->tx_aval_int_thr_mode == 1 && dvobj->tx_aval_int_thr_value) + threshold = dvobj->tx_aval_int_thr_value; + else { + rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size); + tx_max_len = hal_data->sdio_tx_max_len[qidx]; + threshold = PageNum(tx_max_len, page_size); + } threshold |= (threshold) << 8; if (hal_data->sdio_avail_int_en_q == 0xFF) @@ -794,3 +809,78 @@ void dbg_rtw_sdio_free_xmitbuf_sema_down(struct xmit_priv *xmit, const char *cal #endif /* SDIO_FREE_XMIT_BUF_SEMA */ #endif /* !CONFIG_SDIO_TX_TASKLET */ +s32 sdio_initrecvbuf(struct recv_buf *recvbuf, _adapter *adapter) +{ + _rtw_init_listhead(&recvbuf->list); +#ifdef PLATFORM_WINDOWS + _rtw_spinlock_init(&recvbuf->recvbuf_lock); +#endif + recvbuf->adapter = adapter; + + return _SUCCESS; +} + +void sdio_freerecvbuf(struct recv_buf *recvbuf) +{ +#ifdef PLATFORM_WINDOWS + _rtw_spinlock_free(&recvbuf->recvbuf_lock); +#endif +} + +#ifdef CONFIG_SDIO_RECVBUF_PWAIT +void dump_recvbuf_pwait_conf(void *sel, struct recv_priv *recvpriv) +{ + struct rtw_pwait_conf *conf = &recvpriv->recvbuf_pwait.conf; + + RTW_PRINT_SEL(sel, "%-4s %-10s %-10s\n" + , "type", "time", "cnt_lmt"); + RTW_PRINT_SEL(sel, "%4s %10d %10d\n" + , rtw_pwait_type_str(conf->type), conf->wait_time, conf->wait_cnt_lmt); +} + +#ifdef CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST +int recvbuf_pwait_config_req(struct recv_priv *recvpriv, enum rtw_pwait_type type, s32 time, s32 cnt_lmt) +{ + struct recv_buf *rbuf; + struct rtw_pwait_conf *conf; + int ret = _FAIL; + + rbuf = rtw_malloc(sizeof(*rbuf) + sizeof(struct rtw_pwait_conf)); + if (!rbuf) + goto exit; + + sdio_initrecvbuf(rbuf, recvpriv->adapter); + rbuf->type = RBUF_TYPE_PWAIT_ADJ; + rbuf->pbuf = ((u8*)rbuf) + sizeof(*rbuf); + conf = (struct rtw_pwait_conf *)rbuf->pbuf; + conf->type = type; + conf->wait_time = time; + conf->wait_cnt_lmt = cnt_lmt; + + ret = rtw_enqueue_recvbuf(rbuf, &recvpriv->free_recv_buf_queue); + if (0 && ret == _SUCCESS) { + RTW_INFO("request recvbuf_pwait with type=%s time=%d cnt_lmt=%d\n" + , rtw_pwait_type_str(type), time, cnt_lmt); + } + +exit: + return ret; +} + +int recvbuf_pwait_config_hdl(struct recv_priv *recvpriv, struct recv_buf *rbuf) +{ + struct rtw_pwait_conf *conf = (struct rtw_pwait_conf *)rbuf->pbuf; + int ret = rtw_pwctx_config(&recvpriv->recvbuf_pwait, conf->type, conf->wait_time, conf->wait_cnt_lmt); + + if (0 && ret == _SUCCESS) { + RTW_INFO("config recvbuf_pwait with type=%s time=%d cnt_lmt=%d\n" + , rtw_pwait_type_str(conf->type), conf->wait_time, conf->wait_cnt_lmt); + } + sdio_freerecvbuf(rbuf); + rtw_mfree(rbuf, sizeof(*rbuf) + sizeof(*conf)); + + return ret; +} +#endif /* CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST */ +#endif /* CONFIG_SDIO_RECVBUF_PWAIT */ + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_intf.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_intf.c index fb3c887c2020..32dde3f025bd 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_intf.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_intf.c @@ -37,6 +37,7 @@ const u32 _chip_type_to_odm_ic_type[] = { ODM_RTL8192F, ODM_RTL8822C, ODM_RTL8814B, +/* ODM_RTL8723F, */ 0, }; @@ -253,6 +254,7 @@ void dump_hal_trx_mode(void *sel, _adapter *adapter) { struct registry_priv *regpriv = &adapter->registrypriv; PHAL_DATA_TYPE hal_data = GET_HAL_DATA(adapter); + int i; RTW_PRINT_SEL(sel, "trx_path_bmp:0x%02x(%s), NumTotalRFPath:%u, max_tx_cnt:%u\n" , hal_data->trx_path_bmp @@ -262,6 +264,9 @@ void dump_hal_trx_mode(void *sel, _adapter *adapter) ); RTW_PRINT_SEL(sel, "tx_nss:%u, rx_nss:%u\n" , hal_data->tx_nss, hal_data->rx_nss); + for (i = 0; i < hal_data->tx_nss; i++) + RTW_PRINT_SEL(sel, "txpath_cap_num_%uss:%u\n" + , i + 1, hal_data->txpath_cap_num_nss[i]); RTW_PRINT_SEL(sel, "\n"); dump_hal_runtime_trx_mode(sel, adapter); @@ -370,9 +375,9 @@ void _dump_trx_nss(void *sel, _adapter *adapter) struct registry_priv *regpriv = &adapter->registrypriv; struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); - RTW_PRINT_SEL(sel, "[TRX_Nss] HALSPEC - tx_nss :%d, rx_nss:%d\n", hal_spec->tx_nss_num, hal_spec->rx_nss_num); - RTW_PRINT_SEL(sel, "[TRX_Nss] Registry - tx_nss :%d, rx_nss:%d\n", regpriv->tx_nss, regpriv->rx_nss); - RTW_PRINT_SEL(sel, "[TRX_Nss] HALDATA - tx_nss :%d, rx_nss:%d\n", GET_HAL_TX_NSS(adapter), GET_HAL_RX_NSS(adapter)); + RTW_PRINT_SEL(sel, "[TRX_Nss] HALSPEC - tx_nss:%d, rx_nss:%d\n", hal_spec->tx_nss_num, hal_spec->rx_nss_num); + RTW_PRINT_SEL(sel, "[TRX_Nss] Registry - tx_nss:%d, rx_nss:%d\n", regpriv->tx_nss, regpriv->rx_nss); + RTW_PRINT_SEL(sel, "[TRX_Nss] HALDATA - tx_nss:%d, rx_nss:%d\n", GET_HAL_TX_NSS(adapter), GET_HAL_RX_NSS(adapter)); } #define NSS_VALID(nss) (nss > 0) @@ -383,6 +388,7 @@ u8 rtw_hal_trxnss_init(_adapter *adapter) struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); PHAL_DATA_TYPE hal_data = GET_HAL_DATA(adapter); enum rf_type rf_path = GET_HAL_RFPATH(adapter); + int i; hal_data->tx_nss = hal_spec->tx_nss_num; hal_data->rx_nss = hal_spec->rx_nss_num; @@ -394,6 +400,23 @@ u8 rtw_hal_trxnss_init(_adapter *adapter) hal_data->rx_nss = rtw_min(hal_data->rx_nss, regpriv->rx_nss); hal_data->rx_nss = rtw_min(hal_data->rx_nss, rf_type_to_rf_rx_cnt(rf_path)); + for (i = 0; i < 4; i++) { + if (hal_data->tx_nss < i + 1) + break; + + if (IS_HARDWARE_TYPE_8814B(adapter) /* 8814B is always full-TX */ + #ifdef CONFIG_RTW_TX_NPATH_EN + /* these IC is capable of full-TX when macro defined */ + || IS_HARDWARE_TYPE_8192E(adapter) || IS_HARDWARE_TYPE_8192F(adapter) + || IS_HARDWARE_TYPE_8812(adapter) || IS_HARDWARE_TYPE_8822B(adapter) + || IS_HARDWARE_TYPE_8822C(adapter) + #endif + ) + hal_data->txpath_cap_num_nss[i] = hal_data->max_tx_cnt; + else + hal_data->txpath_cap_num_nss[i] = i + 1; + } + if (1) _dump_trx_nss(RTW_DBGDUMP, adapter); @@ -832,6 +855,13 @@ u8 rtw_hal_intf_ps_func(_adapter *padapter, HAL_INTF_PS_FUNC efunc_id, u8 *val) return _FAIL; } +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtw_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + return padapter->hal_func.hal_mgmt_xmitframe_enqueue(padapter, pxmitframe); +} +#endif + s32 rtw_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe) { return padapter->hal_func.hal_xmitframe_enqueue(padapter, pxmitframe); @@ -847,9 +877,16 @@ s32 rtw_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe) */ s32 rtw_hal_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe) { +#ifdef CONFIG_RTW_MGMT_QUEUE + _irqL irqL; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); +#endif s32 ret = _FAIL; update_mgntframe_attrib_addr(padapter, pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + update_mgntframe_subtype(padapter, pmgntframe); +#endif #if defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH) if ((!MLME_IS_MESH(padapter) && SEC_IS_BIP_KEY_INSTALLED(&padapter->securitypriv) == _TRUE) @@ -860,6 +897,23 @@ s32 rtw_hal_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe) rtw_mgmt_xmitframe_coalesce(padapter, pmgntframe->pkt, pmgntframe); #endif +#ifdef CONFIG_RTW_MGMT_QUEUE + if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) { + _enter_critical_bh(&pxmitpriv->lock, &irqL); + ret = mgmt_xmitframe_enqueue_for_sleeping_sta(padapter, pmgntframe); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + + #ifdef DBG_MGMT_QUEUE + if (ret == _TRUE) + RTW_INFO("%s doesn't be queued, dattrib->ra:"MAC_FMT" seq_num = %u, subtype = 0x%x\n", + __func__, MAC_ARG(pmgntframe->attrib.ra), pmgntframe->attrib.seqnum, pmgntframe->attrib.subtype); + #endif + + if (ret == RTW_QUEUE_MGMT) + return ret; + } +#endif + ret = padapter->hal_func.mgnt_xmit(padapter, pmgntframe); return ret; } @@ -1262,13 +1316,16 @@ s32 c2h_handler(_adapter *adapter, u8 id, u8 seq, u8 plen, u8 *payload) #if defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW) case C2H_FW_CHNL_SWITCH_COMPLETE: +#ifndef CONFIG_TDLS_CH_SW_V2 rtw_tdls_chsw_oper_done(adapter); - break; - case C2H_BCN_EARLY_RPT: - rtw_tdls_ch_sw_back_to_base_chnl(adapter); +#endif break; #endif + case C2H_BCN_EARLY_RPT: + rtw_hal_bcn_early_rpt_c2h_handler(adapter); + break; + #ifdef CONFIG_MCC_MODE case C2H_MCC: rtw_hal_mcc_c2h_handler(adapter, plen, payload); @@ -1314,6 +1371,7 @@ s32 c2h_handler(_adapter *adapter, u8 id, u8 seq, u8 plen, u8 *payload) case C2H_EXTEND: sub_id = payload[0]; /* no handle, goto default */ + /* fall through */ default: if (phydm_c2H_content_parsing(adapter_to_phydm(adapter), id, plen, payload) != TRUE) @@ -1908,6 +1966,7 @@ void rtw_hal_update_txpwr_level(_adapter *adapter) HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); rtw_hal_set_tx_power_level(adapter, hal_data->current_channel); + rtw_rfctl_update_op_mode(adapter_to_rfctl(adapter), 0, 0); } void rtw_hal_set_txpwr_done(_adapter *adapter) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_mcc.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_mcc.c index c85c6470d20a..ac9893f6a4f7 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_mcc.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_mcc.c @@ -387,7 +387,7 @@ static void mcc_cfg_phdym_rf_ch (_adapter *adapter) set_channel_bwmode(adapter, mlmeext->cur_channel, mlmeext->cur_ch_offset, mlmeext->cur_bwmode); order = mccadapriv->order; - mcc_dm->mcc_rf_ch[order] = phy_query_rf_reg(adapter, RF_PATH_A, 0x18, 0xffffffff); + mcc_dm->mcc_rf_ch[order] = phy_query_rf_reg(adapter, RF_PATH_A, 0x18, 0x03ff); } static void mcc_cfg_phdym_update_macid (_adapter *adapter, u8 add, u8 mac_id) @@ -1274,6 +1274,12 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, struct hal_com_data *hal = GET_HAL_DATA(adapter); struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); struct mcc_adapter_priv *mccadapriv = NULL; +#if defined(CONFIG_RTL8822C) + struct dm_struct *phydm = adapter_to_phydm(adapter); + struct txagc_table_8822c tab; + u8 agc_buff[2][NUM_RATE_AC_2SS]; /* tatol 0x40 rate index for PATH A/B */ +#endif + u8 ret = _SUCCESS, i = 0, j =0, order = 0, CurtPktPageNum = 0; u8 *start = NULL; u8 path = RF_PATH_A; @@ -1350,7 +1356,8 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, } for (i = 0; i < MAX_MCC_NUM; i++) { - u8 center_ch = 0, band, ch = 0, bw = 0, bw_offset = 0; + u8 center_ch = 0, ch = 0, bw = 0, bw_offset = 0; + BAND_TYPE band = BAND_MAX; u8 power_index = 0; u8 rate_array_sz = 0; u8 *rates = NULL; @@ -1377,7 +1384,7 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, i, pmccobjpriv->mcc_pwr_idx_rsvd_page[i]); total_rate_offset = start; - +#if !defined(CONFIG_RTL8822C) for (path = RF_PATH_A; path < hal_spec->rf_reg_path_num; ++path) { total_rate = 0; /* PATH A for 0~63 byte, PATH B for 64~127 byte*/ @@ -1396,7 +1403,7 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, rates = rates_by_sections[CCK].rates; for (j = 0; j < rate_array_sz; ++j) { power_index = phy_get_tx_power_index_ex(iface, path, CCK, rates[j], bw, band, center_ch, ch); - rate = PHY_GetRateIndexOfTxPowerByRate(rates[j]); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); shift = rate % 4; if (shift == 0) { @@ -1438,7 +1445,7 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, rates = rates_by_sections[OFDM].rates; for (j = 0; j < rate_array_sz; ++j) { power_index = phy_get_tx_power_index_ex(iface, path, OFDM, rates[j], bw, band, center_ch, ch); - rate = PHY_GetRateIndexOfTxPowerByRate(rates[j]); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); shift = rate % 4; if (shift == 0) { @@ -1478,7 +1485,7 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, rates = rates_by_sections[HT_MCS0_MCS7].rates; for (j = 0; j < rate_array_sz; ++j) { power_index = phy_get_tx_power_index_ex(iface, path, HT_1SS, rates[j], bw, band, center_ch, ch); - rate = PHY_GetRateIndexOfTxPowerByRate(rates[j]); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); shift = rate % 4; if (shift == 0) { @@ -1518,7 +1525,7 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, rates = rates_by_sections[HT_MCS8_MCS15].rates; for (j = 0; j < rate_array_sz; ++j) { power_index = phy_get_tx_power_index_ex(iface, path, HT_2SS, rates[j], bw, band, center_ch, ch); - rate = PHY_GetRateIndexOfTxPowerByRate(rates[j]); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); shift = rate % 4; if (shift == 0) { @@ -1557,7 +1564,7 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, rates = rates_by_sections[VHT_1SSMCS0_1SSMCS9].rates; for (j = 0; j < rate_array_sz; ++j) { power_index = phy_get_tx_power_index_ex(iface, path, VHT_1SS, rates[j], bw, band, center_ch, ch); - rate = PHY_GetRateIndexOfTxPowerByRate(rates[j]); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); shift = rate % 4; if (shift == 0) { @@ -1593,7 +1600,7 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, rates = rates_by_sections[VHT_2SSMCS0_2SSMCS9].rates; for (j = 0; j < rate_array_sz; ++j) { power_index = phy_get_tx_power_index_ex(iface, path, VHT_2SS, rates[j], bw, band, center_ch, ch); - rate = PHY_GetRateIndexOfTxPowerByRate(rates[j]); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); shift = rate % 4; if (shift == 0) { @@ -1639,6 +1646,91 @@ u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index, *total_page_num += CurtPktPageNum; *index += (CurtPktPageNum * page_size); RSVD_PAGE_CFG("mcc_pwr_idx_rsvd_page", CurtPktPageNum, *total_page_num, *index); +#else /* 8822C */ + for (path = RF_PATH_A; path < hal_spec->rf_reg_path_num; ++path) { + /* CCK */ + if (ch <= 14) { + rate_array_sz = rates_by_sections[CCK].rate_num; + rates = rates_by_sections[CCK].rates; + for (j = 0; j < rate_array_sz; ++j) { + power_index = phy_get_tx_power_index_ex(iface, path, CCK, rates[j], bw, band, center_ch, ch); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); + agc_buff[path][rate] = power_index; + } + } + + /* OFDM */ + rate_array_sz = rates_by_sections[OFDM].rate_num; + rates = rates_by_sections[OFDM].rates; + for (j = 0; j < rate_array_sz; ++j) { + power_index = phy_get_tx_power_index_ex(iface, path, OFDM, rates[j], bw, band, center_ch, ch); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); + agc_buff[path][rate] = power_index; + } + /* HT */ + rate_array_sz = rates_by_sections[HT_MCS0_MCS7].rate_num; + rates = rates_by_sections[HT_MCS0_MCS7].rates; + for (j = 0; j < rate_array_sz; ++j) { + power_index = phy_get_tx_power_index_ex(iface, path, HT_1SS, rates[j], bw, band, center_ch, ch); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); + agc_buff[path][rate] = power_index; + } + + rate_array_sz = rates_by_sections[HT_MCS8_MCS15].rate_num; + rates = rates_by_sections[HT_MCS8_MCS15].rates; + for (j = 0; j < rate_array_sz; ++j) { + power_index = phy_get_tx_power_index_ex(iface, path, HT_2SS, rates[j], bw, band, center_ch, ch); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); + agc_buff[path][rate] = power_index; + } + /* VHT */ + rate_array_sz = rates_by_sections[VHT_1SSMCS0_1SSMCS9].rate_num; + rates = rates_by_sections[VHT_1SSMCS0_1SSMCS9].rates; + for (j = 0; j < rate_array_sz; ++j) { + power_index = phy_get_tx_power_index_ex(iface, path, VHT_1SS, rates[j], bw, band, center_ch, ch); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); + agc_buff[path][rate] = power_index; + } + + rate_array_sz = rates_by_sections[VHT_2SSMCS0_2SSMCS9].rate_num; + rates = rates_by_sections[VHT_2SSMCS0_2SSMCS9].rates; + for (j = 0; j < rate_array_sz; ++j) { + power_index = phy_get_tx_power_index_ex(iface, path, VHT_2SS, rates[j], bw, band, center_ch, ch); + rate = phy_get_rate_idx_of_txpwr_by_rate(rates[j]); + agc_buff[path][rate] = power_index; + } + } + phydm_get_txagc_ref_and_diff_8822c(phydm, agc_buff, NUM_RATE_AC_2SS, &tab); + *start = tab.ref_pow_cck[0]; + start++; + *start = tab.ref_pow_cck[1]; + start++; + *start = tab.ref_pow_ofdm[0]; + start++; + *start = tab.ref_pow_ofdm[1]; + start++; + _rtw_memcpy(start, tab.diff_t, sizeof(tab.diff_t)); + CurtPktPageNum = 1; + *total_page_num += CurtPktPageNum; + *index += (CurtPktPageNum * page_size); + RSVD_PAGE_CFG("mcc_pwr_idx_rsvd_page", CurtPktPageNum, *total_page_num, *index); + #ifdef DBG_PWR_IDX_RSVD_PAGE + if (1) { + u8 path_idx; + for (path_idx = 0; path_idx < 2; path_idx++) { + for (j = 0; j < NUM_RATE_AC_2SS; j++) + RTW_INFO("agc_buff[%d][%d]=%x\n", i, j, agc_buff[i][j]); + } + RTW_INFO("tab->ref_pow_cck[0]=%x\n", tab.ref_pow_cck[0]); + RTW_INFO("tab->ref_pow_cck[1]=%x\n", tab.ref_pow_cck[1]); + RTW_INFO("tab->ref_pow_ofdm[0]=%x\n", tab.ref_pow_ofdm[0]); + RTW_INFO("tab->ref_pow_ofdm[1]=%x\n", tab.ref_pow_ofdm[1]); + RTW_INFO_DUMP("diff_t ", tab.diff_t, NUM_RATE_AC_2SS); + RTW_INFO_DUMP("tab ", (u8 *)&tab, sizeof(tab)); + } + #endif + +#endif } exit: @@ -1663,6 +1755,7 @@ static void rtw_hal_set_fw_mcc_rsvd_page(PADAPTER padapter) rtw_hal_set_hwreg(port0_iface, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); +#ifdef CONFIG_AP_MODE /* Re-Download beacon */ for (i = 0; i < MAX_MCC_NUM; i++) { iface = pmccobjpriv->iface[i]; @@ -1676,6 +1769,7 @@ static void rtw_hal_set_fw_mcc_rsvd_page(PADAPTER padapter) tx_beacon_hdl(iface, NULL); } } +#endif } static void rtw_hal_set_mcc_rsvdpage_cmd(_adapter *padapter) @@ -2217,6 +2311,15 @@ static void rtw_hal_mcc_start_prehdl(PADAPTER padapter) mccadapriv = &iface->mcc_adapterpriv; mccadapriv->role = MCC_ROLE_MAX; } + +#ifdef CONFIG_RTL8822C + if (IS_HARDWARE_TYPE_8822C(padapter)) { + HAL_DATA_TYPE *hal = GET_HAL_DATA(padapter); + struct dm_struct *dm = &hal->odmpriv; + + odm_cmn_info_update(dm, ODM_CMNINFO_IS_DOWNLOAD_FW, hal->bFWReady); + } +#endif } static u8 rtw_hal_set_mcc_start_setting(PADAPTER padapter, u8 status) @@ -2382,6 +2485,15 @@ static void rtw_hal_mcc_stop_posthdl(PADAPTER padapter) #ifdef CONFIG_MCC_PHYDM_OFFLOAD rtw_hal_mcc_cfg_phydm(padapter, MCC_CFG_PHYDM_STOP, NULL); #endif + +#ifdef CONFIG_RTL8822C + if (IS_HARDWARE_TYPE_8822C(padapter)) { + HAL_DATA_TYPE *hal = GET_HAL_DATA(padapter); + struct dm_struct *dm = &hal->odmpriv; + + odm_cmn_info_update(dm, ODM_CMNINFO_IS_DOWNLOAD_FW, _FALSE); + } +#endif } static void rtw_hal_mcc_start_posthdl(PADAPTER padapter) @@ -2433,7 +2545,7 @@ static u8 rtw_hal_set_mcc_setting(PADAPTER padapter, u8 status) u8 ret = _FAIL; struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv); u8 stop = (status < MCC_SETCMD_STATUS_START_CONNECT) ? _TRUE : _FALSE; - u32 start_time = rtw_get_current_time(); + systime start_time = rtw_get_current_time(); RTW_INFO("===> "FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); @@ -2653,8 +2765,11 @@ static u8 mcc_get_reg_hdl(PADAPTER adapter, const u8 *val) _adapter *cur_iface = NULL; u8 ret = _SUCCESS; u8 cur_order = 0; - + #ifdef CONFIG_RTL8822C + u16 dbg_reg[DBG_MCC_REG_NUM] = {0x4d4,0x522,0x1d70}; + #else u16 dbg_reg[DBG_MCC_REG_NUM] = {0x4d4,0x522,0xc50,0xe50}; + #endif u16 dbg_rf_reg[DBG_MCC_RF_REG_NUM] = {0x18}; u8 i; u32 reg_val; @@ -3287,14 +3402,34 @@ u8 rtw_hal_set_mcc_setting_start_bss_network(PADAPTER padapter, u8 chbw_allow) if (MCC_EN(padapter)) { /* channel bw offset can not be allowed, start MCC */ if (chbw_allow == _FALSE) { - struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv); + struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv); - rtw_hal_mcc_restore_iqk_val(padapter); - _enter_critical_mutex(&pmccobjpriv->mcc_mutex, NULL); - ret = rtw_hal_set_mcc_setting(padapter, MCC_SETCMD_STATUS_START_CONNECT); - _exit_critical_mutex(&pmccobjpriv->mcc_mutex, NULL); + //rtw_hal_mcc_restore_iqk_val(padapter); + _enter_critical_mutex(&pmccobjpriv->mcc_mutex, NULL); + ret = rtw_hal_set_mcc_setting(padapter, MCC_SETCMD_STATUS_START_CONNECT); + _exit_critical_mutex(&pmccobjpriv->mcc_mutex, NULL); + + if (ret == _FAIL) { /* MCC Start fail, AP/GO switch to buddy's channel */ + u8 ch_to_set = 0, bw_to_set, offset_to_set; + + rtw_hal_set_mcc_status(padapter, MCC_STATUS_NEED_MCC | MCC_STATUS_DOING_MCC); + rtw_hal_set_mcc_setting_disconnect(padapter); + if (rtw_mi_get_ch_setting_union_no_self( + padapter, &ch_to_set, &bw_to_set, + &offset_to_set) != 0) { + PHAL_DATA_TYPE hal = GET_HAL_DATA(padapter); + u8 doiqk = _TRUE; + + rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk); + hal->current_channel = 0; + hal->current_channel_bw = CHANNEL_WIDTH_MAX; + set_channel_bwmode(padapter, ch_to_set, offset_to_set, bw_to_set); + doiqk = _FALSE; + rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk); + } } } + } return ret; } @@ -3364,9 +3499,17 @@ u8 rtw_hal_set_mcc_setting_join_done_chk_ch(PADAPTER padapter) _enter_critical_mutex(&pmccobjpriv->mcc_mutex, NULL); ret = rtw_hal_set_mcc_setting(padapter, MCC_SETCMD_STATUS_START_CONNECT); _exit_critical_mutex(&pmccobjpriv->mcc_mutex, NULL); + + if (ret == _FAIL) { /* MCC Start Fail, then disconenct client join */ + rtw_hal_set_mcc_status(padapter, MCC_STATUS_NEED_MCC | MCC_STATUS_DOING_MCC); + rtw_disassoc_cmd(padapter, 0, RTW_CMDF_DIRECTLY); + rtw_indicate_disconnect(padapter, 0, _FALSE); + rtw_free_assoc_resources(padapter, _TRUE); + rtw_free_network_queue(padapter, _TRUE); + } + } } } - } return ret; } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_mp.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_mp.c index e200c7a29840..1d000d9930c0 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_mp.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/hal_mp.c @@ -435,12 +435,16 @@ mpt_SetTxPower( u8 path = 0 , i = 0, MaxRate = MGN_6M; u8 StartPath = RF_PATH_A, EndPath = RF_PATH_B; + u8 tx_nss = 2; - if (IS_HARDWARE_TYPE_8814A(pAdapter) || IS_HARDWARE_TYPE_8814B(pAdapter)) + if (IS_HARDWARE_TYPE_8814A(pAdapter) || IS_HARDWARE_TYPE_8814B(pAdapter)) { EndPath = RF_PATH_D; - else if (IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8188GTV(pAdapter) - || IS_HARDWARE_TYPE_8723D(pAdapter) || IS_HARDWARE_TYPE_8821C(pAdapter)) + tx_nss = 4; + } else if (IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8188GTV(pAdapter) + || IS_HARDWARE_TYPE_8723D(pAdapter) || IS_HARDWARE_TYPE_8821C(pAdapter)) { EndPath = RF_PATH_A; + tx_nss = 1; + } switch (Rate) { case MPT_CCK: { @@ -472,14 +476,15 @@ mpt_SetTxPower( MGN_MCS25, MGN_MCS26, MGN_MCS27, MGN_MCS28, MGN_MCS29, MGN_MCS30, MGN_MCS31, }; - if (pHalData->rf_type == RF_4T4R) + if (tx_nss == 4) MaxRate = MGN_MCS31; - else if (pHalData->rf_type == RF_3T3R) + else if (tx_nss == 3) MaxRate = MGN_MCS23; - else if (pHalData->rf_type == RF_2T2R) + else if (tx_nss == 2) MaxRate = MGN_MCS15; else MaxRate = MGN_MCS7; + for (path = StartPath; path <= EndPath; path++) { for (i = 0; i < sizeof(rate); ++i) { if (rate[i] > MaxRate) @@ -500,11 +505,11 @@ mpt_SetTxPower( MGN_VHT4SS_MCS0, MGN_VHT4SS_MCS1, MGN_VHT4SS_MCS2, MGN_VHT4SS_MCS3, MGN_VHT4SS_MCS4, MGN_VHT4SS_MCS5, MGN_VHT4SS_MCS6, MGN_VHT4SS_MCS7, MGN_VHT4SS_MCS8, MGN_VHT4SS_MCS9, }; - if (pHalData->rf_type == RF_4T4R) + if (tx_nss == 4) MaxRate = MGN_VHT4SS_MCS9; - else if (pHalData->rf_type == RF_3T3R) + else if (tx_nss == 3) MaxRate = MGN_VHT3SS_MCS9; - else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R) + else if (tx_nss == 2) MaxRate = MGN_VHT2SS_MCS9; else MaxRate = MGN_VHT1SS_MCS9; @@ -861,7 +866,8 @@ void mpt_SetRFPath_8814A(PADAPTER pAdapter) } #endif /* CONFIG_RTL8814A */ -#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) +#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) \ + || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) || defined(CONFIG_RTL8723F) void mpt_SetSingleTone_8814A( PADAPTER pAdapter, @@ -2304,33 +2310,35 @@ static void mpt_StartOfdmContTx( pMptCtx->bOfdmContTx = TRUE; } /* mpt_StartOfdmContTx */ -#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) +#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) \ + || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) \ + || defined(CONFIG_RTL8723F) #ifdef PHYDM_PMAC_TX_SETTING_SUPPORT static void mpt_convert_phydm_txinfo_for_jaguar3( - RT_PMAC_TX_INFO pMacTxInfo, struct phydm_pmac_info *phydmtxinfo) + RT_PMAC_TX_INFO *pMacTxInfo, struct phydm_pmac_info *phydmtxinfo) { - phydmtxinfo->en_pmac_tx = pMacTxInfo.bEnPMacTx; - phydmtxinfo->mode = pMacTxInfo.Mode; - phydmtxinfo->tx_rate = MRateToHwRate(mpt_to_mgnt_rate(pMacTxInfo.TX_RATE)); - phydmtxinfo->tx_sc = pMacTxInfo.TX_SC; - phydmtxinfo->is_short_preamble = pMacTxInfo.bSPreamble; - phydmtxinfo->ndp_sound = pMacTxInfo.NDP_sound; - phydmtxinfo->bw = pMacTxInfo.BandWidth; - phydmtxinfo->m_stbc = pMacTxInfo.m_STBC; - phydmtxinfo->packet_period = pMacTxInfo.PacketPeriod; - phydmtxinfo->packet_count = pMacTxInfo.PacketCount; - phydmtxinfo->packet_pattern = pMacTxInfo.PacketPattern; - phydmtxinfo->sfd = pMacTxInfo.SFD; - phydmtxinfo->signal_field = pMacTxInfo.SignalField; - phydmtxinfo->service_field = pMacTxInfo.ServiceField; - phydmtxinfo->length = pMacTxInfo.LENGTH; - _rtw_memcpy(&phydmtxinfo->crc16,pMacTxInfo.CRC16, 2); - _rtw_memcpy(&phydmtxinfo->lsig , pMacTxInfo.LSIG,3); - _rtw_memcpy(&phydmtxinfo->ht_sig , pMacTxInfo.HT_SIG,6); - _rtw_memcpy(&phydmtxinfo->vht_sig_a , pMacTxInfo.VHT_SIG_A,6); - _rtw_memcpy(&phydmtxinfo->vht_sig_b , pMacTxInfo.VHT_SIG_B,4); - phydmtxinfo->vht_sig_b_crc = pMacTxInfo.VHT_SIG_B_CRC; - _rtw_memcpy(&phydmtxinfo->vht_delimiter,pMacTxInfo.VHT_Delimiter,4); + phydmtxinfo->en_pmac_tx = pMacTxInfo->bEnPMacTx; + phydmtxinfo->mode = pMacTxInfo->Mode; + phydmtxinfo->tx_rate = MRateToHwRate(mpt_to_mgnt_rate(pMacTxInfo->TX_RATE)); + phydmtxinfo->tx_sc = pMacTxInfo->TX_SC; + phydmtxinfo->is_short_preamble = pMacTxInfo->bSPreamble; + phydmtxinfo->ndp_sound = pMacTxInfo->NDP_sound; + phydmtxinfo->bw = pMacTxInfo->BandWidth; + phydmtxinfo->m_stbc = pMacTxInfo->m_STBC; + phydmtxinfo->packet_period = pMacTxInfo->PacketPeriod; + phydmtxinfo->packet_count = pMacTxInfo->PacketCount; + phydmtxinfo->packet_pattern = pMacTxInfo->PacketPattern; + phydmtxinfo->sfd = pMacTxInfo->SFD; + phydmtxinfo->signal_field = pMacTxInfo->SignalField; + phydmtxinfo->service_field = pMacTxInfo->ServiceField; + phydmtxinfo->length = pMacTxInfo->LENGTH; + _rtw_memcpy(&phydmtxinfo->crc16,pMacTxInfo->CRC16, 2); + _rtw_memcpy(&phydmtxinfo->lsig , pMacTxInfo->LSIG,3); + _rtw_memcpy(&phydmtxinfo->ht_sig , pMacTxInfo->HT_SIG,6); + _rtw_memcpy(&phydmtxinfo->vht_sig_a , pMacTxInfo->VHT_SIG_A,6); + _rtw_memcpy(&phydmtxinfo->vht_sig_b , pMacTxInfo->VHT_SIG_B,4); + phydmtxinfo->vht_sig_b_crc = pMacTxInfo->VHT_SIG_B_CRC; + _rtw_memcpy(&phydmtxinfo->vht_delimiter,pMacTxInfo->VHT_Delimiter,4); } #endif @@ -2401,7 +2409,7 @@ u8 mpt_ProSetPMacTx(PADAPTER Adapter) PMacTxInfo.TX_RATE = pMptCtx->mpt_rate_index; pMptCtx->HWTxmode = TEST_NONE; } - mpt_convert_phydm_txinfo_for_jaguar3(PMacTxInfo, &phydm_mactxinfo); + mpt_convert_phydm_txinfo_for_jaguar3(&PMacTxInfo, &phydm_mactxinfo); phydm_set_pmac_tx(p_dm_odm, &phydm_mactxinfo, pMptCtx->mpt_rf_path); #endif return status; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/halmac/halmac_88xx/halmac_efuse_88xx.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/halmac/halmac_88xx/halmac_efuse_88xx.c index 40b75e879997..34adf940320d 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/halmac/halmac_88xx/halmac_efuse_88xx.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/halmac/halmac_88xx/halmac_efuse_88xx.c @@ -34,6 +34,8 @@ #define SUPER_USB_RE_PG_CK_ZONE0_START 0x15D #define SUPER_USB_RE_PG_CK_ZONE0_END 0x164 +static u8 bt_switch = 0; + static enum halmac_cmd_construct_state efuse_cmd_cnstr_state_88xx(struct halmac_adapter *adapter); @@ -259,13 +261,23 @@ dump_efuse_map_bt_88xx(struct halmac_adapter *adapter, PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n"); return status; } + bt_switch = 1; status = read_hw_efuse_88xx(adapter, 0, size, map); if (status != HALMAC_RET_SUCCESS) { + bt_switch = 0; PLTFM_MSG_ERR("[ERR]read hw efuse\n"); return status; } + status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI); + if (status != HALMAC_RET_SUCCESS) { + bt_switch = 0; + PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n"); + return status; + } + bt_switch = 0; + if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) != HALMAC_RET_SUCCESS) return HALMAC_RET_ERROR_STATE; @@ -321,13 +333,23 @@ write_efuse_bt_88xx(struct halmac_adapter *adapter, u32 offset, u8 value, PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n"); return status; } + bt_switch = 1; status = write_hw_efuse_88xx(adapter, offset, value); if (status != HALMAC_RET_SUCCESS) { + bt_switch = 0; PLTFM_MSG_ERR("[ERR]write efuse\n"); return status; } + status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI); + if (status != HALMAC_RET_SUCCESS) { + bt_switch = 0; + PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n"); + return status; + } + bt_switch = 0; + if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) != HALMAC_RET_SUCCESS) return HALMAC_RET_ERROR_STATE; @@ -383,13 +405,23 @@ read_efuse_bt_88xx(struct halmac_adapter *adapter, u32 offset, u8 *value, PLTFM_MSG_ERR("[ERR]switch efuse bank\n"); return status; } + bt_switch = 1; status = read_efuse_88xx(adapter, offset, 1, value); if (status != HALMAC_RET_SUCCESS) { + bt_switch = 0; PLTFM_MSG_ERR("[ERR]read efuse\n"); return status; } + status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI); + if (status != HALMAC_RET_SUCCESS) { + bt_switch = 0; + PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n"); + return status; + } + bt_switch = 0; + if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) != HALMAC_RET_SUCCESS) return HALMAC_RET_ERROR_STATE; @@ -967,9 +999,11 @@ switch_efuse_bank_88xx(struct halmac_adapter *adapter, u8 reg_value; struct halmac_api *api = (struct halmac_api *)adapter->halmac_api; - if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_BUSY) != - HALMAC_RET_SUCCESS) - return HALMAC_RET_ERROR_STATE; + if (!bt_switch) { + if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_BUSY) != + HALMAC_RET_SUCCESS) + return HALMAC_RET_ERROR_STATE; + } reg_value = HALMAC_REG_R8(REG_LDO_EFUSE_CTRL + 1); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/halmac/halmac_api.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/halmac/halmac_api.h index ac4574513f63..8617cc106757 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/halmac/halmac_api.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/halmac/halmac_api.h @@ -22,13 +22,13 @@ #define HALMAC_MAJOR_VER 1 #define HALMAC_PROTOTYPE_VER 6 #define HALMAC_MINOR_VER 6 -#define HALMAC_PATCH_VER 19 +#define HALMAC_PATCH_VER 22 #define HALMAC_88XX_SUPPORT (HALMAC_8821C_SUPPORT || \ HALMAC_8822B_SUPPORT || \ - HALMAC_8822C_SUPPORT || \ - HALMAC_8812F_SUPPORT) - + HALMAC_8822C_SUPPORT || \ + HALMAC_8812F_SUPPORT) + #define HALMAC_88XX_V1_SUPPORT HALMAC_8814B_SUPPORT #include "halmac_2_platform.h" diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/ap_makefile.mk b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/ap_makefile.mk index 5bbca973daa6..8a07d244a9db 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/ap_makefile.mk +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/ap_makefile.mk @@ -123,7 +123,8 @@ ifeq ($(CONFIG_WLAN_HAL_8812FE),y) _PHYDM_FILES += \ phydm/rtl8812f/halhwimg8812f_bb.o\ phydm/rtl8812f/phydm_regconfig8812f.o\ - phydm/rtl8812f/phydm_hal_api8812f.o + phydm/rtl8812f/phydm_hal_api8812f.o\ + phydm/rtl8812f/phydm_rtl8812f.o endif endif @@ -136,7 +137,8 @@ ifeq ($(CONFIG_WLAN_HAL_8821CE),y) phydm/rtl8821c/halhwimg8821c_bb.o\ phydm/rtl8821c/halhwimg8821c_mac.o\ phydm/rtl8821c/phydm_regconfig8821c.o\ - phydm/rtl8821c/phydm_hal_api8821c.o + phydm/rtl8821c/phydm_hal_api8821c.o\ + phydm/rtl8821c/phydm_rtl8821c.o endif endif @@ -199,6 +201,7 @@ ifeq ($(CONFIG_WLAN_HAL_8814BE),y) phydm/rtl8814b/phydm_hal_api8814b.o\ phydm/rtl8814b/halhwimg8814b_bb.o\ phydm/rtl8814b/phydm_regconfig8814b.o \ + phydm/rtl8814b/phydm_extraagc8814b.o \ phydm/halrf/rtl8814b/halrf_8814b.o endif endif @@ -216,7 +219,20 @@ ifeq ($(CONFIG_WLAN_HAL_8197G),y) phydm/rtl8197g/halhwimg8197g_bb.o\ phydm/rtl8197g/halhwimg8197g_mac.o\ phydm/rtl8197g/phydm_regconfig8197g.o \ + phydm/rtl8197g/phydm_rtl8197g.o \ phydm/halrf/rtl8197g/halrf_8197g.o endif endif - +ifeq ($(CONFIG_WLAN_HAL_8723FE),y) + _PHYDM_FILES += phydm/halrf/rtl8723f/halrf_8723f.o + _PHYDM_FILES += phydm/halrf/rtl8723f/halrf_iqk_8723f.o + _PHYDM_FILES += phydm/halrf/rtl8723f/halrf_dpk_8723f.o + _PHYDM_FILES += phydm/halrf/rtl8723f/halrf_rfk_init_8723f.o + _PHYDM_FILES += phydm/halrf/rtl8723f/halhwimg8723f_rf.o + ifeq ($(CONFIG_RTL_ODM_WLAN_DRIVER),y) + _PHYDM_FILES += \ + phydm/rtl8723f/halhwimg8723f_bb.o\ + phydm/rtl8723f/phydm_regconfig8723f.o\ + phydm/rtl8723f/phydm_hal_api8723f.o + endif +endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_ap.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_ap.c index 3aedfa955fc5..9fc656644e43 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_ap.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_ap.c @@ -434,9 +434,12 @@ odm_txpowertracking_callback_thermal_meter_jaguar_series4(void *dm_void) priv->pmib->dot11RFEntry.thermal[i] == 0x0) return; } - if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F | ODM_RTL8197G)) { + if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F)) { for (i = 0; i < c.rf_path_count; i++) thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0x7e); /* 0x42: RF Reg[6:1] Thermal Trim*/ + } else if (dm->support_ic_type == ODM_RTL8197G) { + for (i = 0; i < c.rf_path_count; i++) + thermal_value[i] = (u8)odm_get_rf_reg(dm, i, RF_0xf6, 0x7E000); } else { for (i = 0; i < c.rf_path_count; i++) { thermal_value[i] = (u8)odm_get_rf_reg(dm, i, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */ @@ -597,7 +600,7 @@ odm_txpowertracking_callback_thermal_meter_jaguar_series4(void *dm_void) #endif /* Wait sacn to do IQK by RF Jenyu*/ - if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden) && dm->is_linked) { + if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden) && (dm->is_linked || *dm->mp_mode)) { /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/ if (delta_IQK >= c.threshold_iqk) { cali_info->thermal_value_iqk = thermal_value[RF_PATH_A]; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_ce.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_ce.c index 3260a12d9c40..bee1372e5084 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_ce.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_ce.c @@ -116,6 +116,10 @@ void configure_txpower_track(void *dm_void, struct txpwrtrack_cfg *config) configure_txpower_track_8814b(config); #endif +#if RTL8723F_SUPPORT + if (dm->support_ic_type == ODM_RTL8723F) + configure_txpower_track_8723f(config); +#endif } @@ -789,7 +793,7 @@ void odm_txpowertracking_callback_thermal_meter(void *adapter) /* Wait sacn to do IQK by RF Jenyu*/ if (!(*dm->is_scan_in_process) && !iqk_info->rfk_forbidden && - !cali_info->is_iqk_in_progress && (dm->is_linked || *dm->mp_mode)) { + !cali_info->is_iqk_in_progress && dm->is_linked) { if (!(dm->support_ic_type & ODM_RTL8723B)) { /*Delta temperature is equal or larger than 20 Celsius*/ /*When threshold is 8*/ @@ -861,7 +865,7 @@ odm_txpowertracking_new_callback_thermal_meter(void *dm_void) u8 thermal_value[MAX_RF_PATH] = {0}, delta[MAX_RF_PATH] = {0}; u8 delta_swing_table_idx_tup[DELTA_SWINGIDX_SIZE] = {0}; u8 delta_swing_table_idx_tdown[DELTA_SWINGIDX_SIZE] = {0}; - u8 delta_LCK = 0, delta_IQK = 0, delta_tssi = 0, i = 0, j = 0, p; + u8 delta_LCK = 0, delta_IQK = 0, i = 0, j = 0, p; u8 thermal_value_avg_count[MAX_RF_PATH] = {0}; u32 thermal_value_avg[MAX_RF_PATH] = {0}; s8 thermal_value_temp[MAX_RF_PATH] = {0}; @@ -961,17 +965,6 @@ odm_txpowertracking_new_callback_thermal_meter(void *dm_void) delta_IQK = (thermal_value[0] > cali_info->thermal_value_iqk) ? (thermal_value[0] - cali_info->thermal_value_iqk) : (cali_info->thermal_value_iqk - thermal_value[0]); } - RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "[TSSI] thermal_value[0]=%d tssi->tssi_thermal[0]=%d\n", - thermal_value[0], tssi->tssi_thermal[0]); - - delta_tssi = (thermal_value[0] > tssi->tssi_thermal[0]) ? (thermal_value[0] - tssi->tssi_thermal[0]) : (tssi->tssi_thermal[0] - thermal_value[0]); - if (delta_tssi >= 8) { - RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "[TSSI] delta_tssi >= 8 !!!!!! thermal_value[0]=%d tssi->tssi_thermal[0]=%d\n", - thermal_value[0], tssi->tssi_thermal[0]); - tssi->tssi_thermal[0] = thermal_value[0]; - tssi->retry_sacan_tssi = 1; - } - /*4 6. If necessary, do LCK.*/ for (i = 0; i < c.rf_path_count; i++) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_iot.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_iot.c index 04646ec03b2c..8ed17f31462b 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_iot.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_iot.c @@ -126,6 +126,7 @@ odm_txpowertracking_callback_thermal_meter( u8 power_tracking_type = rf->pwt_type; u8 xtal_offset_eanble = 0; s8 thermal_value_temp = 0; + u8 xtal_track_efuse = 0; struct txpwrtrack_cfg c = {0}; @@ -158,9 +159,12 @@ odm_txpowertracking_callback_thermal_meter( #endif /*for Xtal Offset*/ + odm_efuse_one_byte_read(dm, 0xf7, &xtal_track_efuse, false); + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "Read efuse 0xf7=0x%x\n", xtal_track_efuse); + xtal_track_efuse = xtal_track_efuse & 0x3; if (dm->support_ic_type == ODM_RTL8195B || dm->support_ic_type == ODM_RTL8721D || - dm->support_ic_type == ODM_RTL8710C) + (dm->support_ic_type == ODM_RTL8710C && xtal_track_efuse == 0x2)) (*c.get_delta_swing_xtal_table)(dm, (s8 **)&delta_swing_table_xtal_up, (s8 **)&delta_swing_table_xtal_down); @@ -317,7 +321,7 @@ odm_txpowertracking_callback_thermal_meter( /* JJ ADD 20161014 */ if (dm->support_ic_type == ODM_RTL8195B || dm->support_ic_type == ODM_RTL8721D || - dm->support_ic_type == ODM_RTL8710C) { + (dm->support_ic_type == ODM_RTL8710C && xtal_track_efuse == 0x2)) { /*Save xtal_offset from Xtal table*/ cali_info->xtal_offset_last = cali_info->xtal_offset; /*recording last Xtal offset*/ RF_DBG(dm, DBG_RF_TX_PWR_TRACK, @@ -372,7 +376,7 @@ odm_txpowertracking_callback_thermal_meter( if (dm->support_ic_type == ODM_RTL8195B || dm->support_ic_type == ODM_RTL8721D || - dm->support_ic_type == ODM_RTL8710C) { + (dm->support_ic_type == ODM_RTL8710C && xtal_track_efuse == 0x2)) { /*Save xtal_offset from Xtal table*/ cali_info->xtal_offset_last = cali_info->xtal_offset; /*recording last Xtal offset*/ RF_DBG(dm, DBG_RF_TX_PWR_TRACK, @@ -540,9 +544,17 @@ odm_txpowertracking_callback_thermal_meter( } #endif /* JJ ADD 20161014 */ + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "cali_info->xtal_offset_last=%d cali_info->xtal_offset=%d\n", + cali_info->xtal_offset_last, cali_info->xtal_offset); + + RF_DBG(dm, DBG_RF_TX_PWR_TRACK, + "xtal_offset_eanble=%d cali_info->txpowertrack_control=%d rf->eeprom_thermal=%d xtal_track_efuse=%d\n", + xtal_offset_eanble, cali_info->txpowertrack_control, rf->eeprom_thermal, xtal_track_efuse); + if (dm->support_ic_type == ODM_RTL8195B || dm->support_ic_type == ODM_RTL8721D || - dm->support_ic_type == ODM_RTL8710C) { + (dm->support_ic_type == ODM_RTL8710C && xtal_track_efuse == 0x2)) { if (xtal_offset_eanble != 0 && cali_info->txpowertrack_control && (rf->eeprom_thermal != 0xff)) { RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "**********Enter Xtal Tracking**********\n"); @@ -560,7 +572,7 @@ odm_txpowertracking_callback_thermal_meter( } #if (!RTL8721D_SUPPORT) /* Wait sacn to do IQK by RF Jenyu*/ - if ((!*dm->is_scan_in_process) && (!iqk_info->rfk_forbidden) && dm->is_linked) { + if ((!*dm->is_scan_in_process) && (!iqk_info->rfk_forbidden) && (dm->is_linked || *dm->mp_mode)) { /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/ if (delta_IQK >= c.threshold_iqk) { cali_info->thermal_value_iqk = thermal_value; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_win.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_win.c index 910933d729f9..124ffbca29e1 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_win.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halphyrf_win.c @@ -110,6 +110,10 @@ void configure_txpower_track( configure_txpower_track_8814b(config); #endif +#if RTL8723F_SUPPORT + if (dm->support_ic_type == ODM_RTL8723F) + configure_txpower_track_8723f(config); +#endif } @@ -701,7 +705,7 @@ odm_txpowertracking_callback_thermal_meter( #if !(DM_ODM_SUPPORT_TYPE & ODM_AP) /* Wait sacn to do IQK by RF Jenyu*/ - if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden) && (dm->is_linked || *dm->mp_mode)) { + if ((*dm->is_scan_in_process == false) && (!iqk_info->rfk_forbidden) && dm->is_linked) { if (!IS_HARDWARE_TYPE_8723B(adapter)) { /*Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/ if (delta_IQK >= c.threshold_iqk) { @@ -766,7 +770,7 @@ odm_txpowertracking_new_callback_thermal_meter(void *dm_void) u8 thermal_value[MAX_RF_PATH] = {0}, delta[MAX_RF_PATH] = {0}; u8 delta_swing_table_idx_tup[DELTA_SWINGIDX_SIZE] = {0}; u8 delta_swing_table_idx_tdown[DELTA_SWINGIDX_SIZE] = {0}; - u8 delta_LCK = 0, delta_IQK = 0, delta_tssi = 0, i = 0, j = 0, p; + u8 delta_LCK = 0, delta_IQK = 0, i = 0, j = 0, p; u8 thermal_value_avg_count[MAX_RF_PATH] = {0}; u32 thermal_value_avg[MAX_RF_PATH] = {0}; s8 thermal_value_temp[MAX_RF_PATH] = {0}; @@ -865,17 +869,6 @@ odm_txpowertracking_new_callback_thermal_meter(void *dm_void) delta_IQK = (thermal_value[0] > cali_info->thermal_value_iqk) ? (thermal_value[0] - cali_info->thermal_value_iqk) : (cali_info->thermal_value_iqk - thermal_value[0]); } - RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "[TSSI] thermal_value[0]=%d tssi->tssi_thermal[0]=%d\n", - thermal_value[0], tssi->tssi_thermal[0]); - - delta_tssi = (thermal_value[0] > tssi->tssi_thermal[0]) ? (thermal_value[0] - tssi->tssi_thermal[0]) : (tssi->tssi_thermal[0] - thermal_value[0]); - if (delta_tssi >= 8) { - RF_DBG(dm, DBG_RF_TX_PWR_TRACK, "[TSSI] delta_tssi >= 8 !!!!!! thermal_value[0]=%d tssi->tssi_thermal[0]=%d\n", - thermal_value[0], tssi->tssi_thermal[0]); - tssi->tssi_thermal[0] = thermal_value[0]; - tssi->retry_sacan_tssi = 1; - } - /*4 6. If necessary, do LCK.*/ for (i = 0; i < c.rf_path_count; i++) @@ -1044,26 +1037,39 @@ odm_iq_calibrate( if (*dm->is_fcs_mode_enable) return; #endif + if (dm->is_linked) { + RF_DBG(dm, DBG_RF_IQK, + "interval=%d ch=%d prech=%d scan=%s rfk_f =%s\n", + dm->linked_interval, *dm->channel, dm->pre_channel, + *dm->is_scan_in_process == TRUE ? "TRUE":"FALSE", + iqk_info->rfk_forbidden == TRUE ? "TRUE":"FALSE"); - if ((dm->is_linked) && (!iqk_info->rfk_forbidden)) { - RF_DBG(dm, DBG_RF_IQK, "interval=%d ch=%d prech=%d scan=%s\n", dm->linked_interval, - *dm->channel, dm->pre_channel, *dm->is_scan_in_process == TRUE ? "TRUE":"FALSE"); + if (iqk_info->rfk_forbidden) { + RF_DBG(dm, DBG_RF_IQK, "return by rfk_forbidden\n"); + return; + } + + if (*dm->is_scan_in_process) { + RF_DBG(dm, DBG_RF_IQK, "return by is_scan_in_process\n"); + return; + } if (*dm->channel != dm->pre_channel) { dm->pre_channel = *dm->channel; dm->linked_interval = 0; } - if ((dm->linked_interval < 3) && (!*dm->is_scan_in_process)) + if (dm->linked_interval < 3) dm->linked_interval++; if (dm->linked_interval == 2) PHY_IQCalibrate(adapter, false); - } else + } else { dm->linked_interval = 0; - - RF_DBG(dm, DBG_RF_IQK, "<=%s interval=%d ch=%d prech=%d scan=%s\n", __FUNCTION__, dm->linked_interval, - *dm->channel, dm->pre_channel, *dm->is_scan_in_process == TRUE?"TRUE":"FALSE"); + RF_DBG(dm, DBG_RF_IQK, "is_linked =%s, interval =%d\n", + dm->is_linked == TRUE ? "TRUE":"FALSE", + dm->linked_interval); + } } void phydm_rf_init(struct dm_struct *dm) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf.c index d62e55e1dba4..fe7a9cbfb94e 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf.c @@ -791,6 +791,16 @@ void halrf_rf_lna_setting(void *dm_void, enum halrf_lna_set type) halrf_rf_lna_setting_8821c(dm_void, type); break; #endif +#if (RTL8710C_SUPPORT == 1) + case ODM_RTL8710C: + halrf_rf_lna_setting_8710c(dm_void, type); + break; +#endif +#if (RTL8721D_SUPPORT == 1) + case ODM_RTL8721D: + halrf_rf_lna_setting_8721d(dm, type); + break; +#endif #if (RTL8814B_SUPPORT == 1) case ODM_RTL8814B: break; @@ -1024,7 +1034,6 @@ u64 halrf_cmn_info_get(void *dm_void, u32 cmn_info) /* This init variable may be changed in run time. */ struct dm_struct *dm = (struct dm_struct *)dm_void; struct _hal_rf_ *rf = &dm->rf_table; - struct _halrf_tssi_data *tssi = &rf->halrf_tssi_data; u64 return_value = 0; switch (cmn_info) { @@ -1044,9 +1053,6 @@ u64 halrf_cmn_info_get(void *dm_void, u32 cmn_info) return_value = dm->IQK_info.iqk_times; break; #endif - case HALRF_CMNINFO_TSSI_RETRY_SPECIAL_SCAN: - return_value = tssi->retry_sacan_tssi; - break; default: /* do nothing */ break; @@ -1112,7 +1118,7 @@ void halrf_supportability_init_mp(void *dm_void) #if (RTL8195B_SUPPORT == 1) case ODM_RTL8195B: rf->rf_supportability = - HAL_RF_TX_PWR_TRACK | + /*HAL_RF_TX_PWR_TRACK |*/ HAL_RF_IQK | HAL_RF_LCK | HAL_RF_DPK | @@ -1196,6 +1202,17 @@ void halrf_supportability_init_mp(void *dm_void) 0; break; #endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + rf->rf_supportability = + /*@HAL_RF_TX_PWR_TRACK |*/ + HAL_RF_IQK | + HAL_RF_LCK | + HAL_RF_DPK | + HAL_RF_DPK_TRACK | + 0; + break; +#endif default: rf->rf_supportability = @@ -1356,6 +1373,17 @@ void halrf_supportability_init(void *dm_void) 0; break; #endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + rf->rf_supportability = + /*@HAL_RF_TX_PWR_TRACK |*/ + HAL_RF_IQK | + HAL_RF_LCK | + HAL_RF_DPK | + HAL_RF_DPK_TRACK | + 0; + break; +#endif default: rf->rf_supportability = @@ -1456,6 +1484,12 @@ void halrf_reload_iqk(void *dm_void, boolean reset) iqk_reload_iqk_8822c(dm, reset); break; #endif +#if (RTL8195B_SUPPORT == 1) + case ODM_RTL8195B: + iqk_reload_iqk_8195b(dm, reset); + break; +#endif + default: break; } @@ -1466,6 +1500,9 @@ void halrf_rfk_handshake(void *dm_void, boolean is_before_k) { struct dm_struct *dm = (struct dm_struct *)dm_void; + if (!dm->mp_mode) + return; + if (*dm->mp_mode) return; @@ -1474,6 +1511,11 @@ void halrf_rfk_handshake(void *dm_void, boolean is_before_k) case ODM_RTL8822C: halrf_rfk_handshake_8822c(dm, is_before_k); break; +#endif +#if (RTL8710C_SUPPORT == 1) + case ODM_RTL8710C: + halrf_rfk_handshake_8710c(dm, is_before_k); + break; #endif default: break; @@ -1503,13 +1545,17 @@ void halrf_rf_k_connect_trigger(void *dm_void, boolean is_recovery, struct dm_dpk_info *dpk_info = &dm->dpk_info; struct _hal_rf_ *rf = &dm->rf_table; + if (!dm->mp_mode) + return; + if (dm->mp_mode && rf->is_con_tx && rf->is_single_tone && - rf->is_carrier_suppresion) { - if (*dm->mp_mode && - (*rf->is_con_tx || *rf->is_single_tone || - *rf->is_carrier_suppresion)) + rf->is_carrier_suppresion) { + if (*dm->mp_mode & + (*rf->is_con_tx || *rf->is_single_tone || + *rf->is_carrier_suppresion)) return; } + /*[TX GAP K]*/ halrf_txgapk_trigger(dm); @@ -1518,13 +1564,11 @@ void halrf_rf_k_connect_trigger(void *dm_void, boolean is_recovery, /*[TSSI Trk]*/ halrf_tssi_trigger(dm); - /*[DPK]*/ if(dpk_info->is_dpk_by_channel == true) halrf_dpk_trigger(dm); else halrf_dpk_reload(dm); - //ADDA restore to MP_UI setting; config_halrf_path_adda_setting_trigger(dm); @@ -1631,15 +1675,16 @@ void halrf_segment_iqk_trigger(void *dm_void, boolean clear, return; #endif - if (dm->mp_mode && - rf->is_con_tx && - rf->is_single_tone && - rf->is_carrier_suppresion) - if (*dm->mp_mode && - ((*rf->is_con_tx || - *rf->is_single_tone || - *rf->is_carrier_suppresion))) + if (!dm->mp_mode) + return; + + if (dm->mp_mode && rf->is_con_tx && rf->is_single_tone && + rf->is_carrier_suppresion) { + if (*dm->mp_mode & + (*rf->is_con_tx || *rf->is_single_tone || + *rf->is_carrier_suppresion)) return; + } if (!(rf->rf_supportability & HAL_RF_IQK)) return; @@ -1806,15 +1851,16 @@ void halrf_iqk_trigger(void *dm_void, boolean is_recovery) return; #endif - if (dm->mp_mode && - rf->is_con_tx && - rf->is_single_tone && - rf->is_carrier_suppresion) - if (*dm->mp_mode && - ((*rf->is_con_tx || - *rf->is_single_tone || - *rf->is_carrier_suppresion))) + if (!dm->mp_mode) + return; + + if (dm->mp_mode && rf->is_con_tx && rf->is_single_tone && + rf->is_carrier_suppresion) { + if (*dm->mp_mode & + (*rf->is_con_tx || *rf->is_single_tone || + *rf->is_carrier_suppresion)) return; + } if (!(rf->rf_supportability & HAL_RF_IQK)) return; @@ -1945,6 +1991,12 @@ void halrf_iqk_trigger(void *dm_void, boolean is_recovery) phy_iq_calibrate_8197g(dm, false, false); break; #endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + phy_iq_calibrate_8723f(dm, false, false); + break; +#endif + default: break; } @@ -1976,15 +2028,16 @@ void halrf_lck_trigger(void *dm_void) return; #endif - if (dm->mp_mode && - rf->is_con_tx && - rf->is_single_tone && - rf->is_carrier_suppresion) - if (*dm->mp_mode && - ((*rf->is_con_tx || - *rf->is_single_tone || - *rf->is_carrier_suppresion))) + if (!dm->mp_mode) + return; + + if (dm->mp_mode && rf->is_con_tx && rf->is_single_tone && + rf->is_carrier_suppresion) { + if (*dm->mp_mode & + (*rf->is_con_tx || *rf->is_single_tone || + *rf->is_carrier_suppresion)) return; + } if (!(rf->rf_supportability & HAL_RF_LCK)) return; @@ -1995,7 +2048,7 @@ void halrf_lck_trigger(void *dm_void) if (iqk_info->rfk_forbidden) return; while (*dm->is_scan_in_process) { - RF_DBG(dm, DBG_RF_IQK, "[LCK]scan is in process, bypass LCK\n"); + RF_DBG(dm, DBG_RF_LCK, "[LCK]scan is in process, bypass LCK\n"); return; } @@ -2092,6 +2145,17 @@ void halrf_lck_trigger(void *dm_void) #endif #if (RTL8814B_SUPPORT == 1) case ODM_RTL8814B: + phy_lc_calibrate_8814b(dm); + break; +#endif +#if (RTL8197G_SUPPORT == 1) + case ODM_RTL8197G: + phy_lc_calibrate_8197g(dm); + break; +#endif +#if (RTL8198F_SUPPORT == 1) + case ODM_RTL8198F: + phy_lc_calibrate_8198f(dm); break; #endif #if (RTL8710C_SUPPORT == 1) @@ -2099,12 +2163,18 @@ void halrf_lck_trigger(void *dm_void) phy_lc_calibrate_8710c(dm); break; #endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + phy_lc_calibrate_8723f(dm); + break; +#endif + default: break; } dm->rf_calibrate_info.lck_progressing_time = odm_get_progressing_time(dm, start_time); - RF_DBG(dm, DBG_RF_IQK, "[IQK]LCK progressing_time = %lld ms\n", + RF_DBG(dm, DBG_RF_LCK, "[LCK]LCK progressing_time = %lld ms\n", dm->rf_calibrate_info.lck_progressing_time); #if (RTL8822B_SUPPORT == 1 || RTL8821C_SUPPORT == 1) halrf_lck_dbg(dm); @@ -2113,8 +2183,8 @@ void halrf_lck_trigger(void *dm_void) dm->rf_calibrate_info.is_lck_in_progress = false; odm_release_spin_lock(dm, RT_IQK_SPINLOCK); } else { - RF_DBG(dm, DBG_RF_IQK, - "= Return the LCK CMD, because RFK is in Progress =\n"); + RF_DBG(dm, DBG_RF_LCK, + "[LCK]= Return the LCK CMD, because RFK is in Progress =\n"); } } @@ -2187,6 +2257,9 @@ void halrf_set_rfsupportability(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct _hal_rf_ *rf = &dm->rf_table; + if (!dm->mp_mode) + return; + if (rf->manual_rf_supportability && *rf->manual_rf_supportability != 0xffffffff) { rf->rf_supportability = *rf->manual_rf_supportability; @@ -2215,27 +2288,6 @@ void halrf_rfe_definition(struct dm_struct *dm) } } -void halrf_rfe_type_setting(struct dm_struct *dm) -{ - switch (dm->support_ic_type) { - case ODM_RTL8822C: -#if (RTL8822C_SUPPORT == 1) - if (dm->rfe_type == 21 || dm->rfe_type == 22) { - phydm_rfe_ctrl_gpio(dm, 1); - phydm_rfe_ctrl_gpio(dm, 2); - phydm_rfe_ctrl_gpio(dm, 3); - phydm_rfe_ctrl_gpio(dm, 6); - phydm_rfe_ctrl_gpio(dm, 7); - phydm_rfe_ctrl_gpio(dm, 13); - } -#endif - break; - - default: - break; - } -} - void halrf_init(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2245,10 +2297,7 @@ void halrf_init(void *dm_void) rf->aac_checked = false; halrf_init_debug_setting(dm); halrf_set_rfsupportability(dm); - - /*RF Type Setting*/ halrf_rfe_definition(dm); - halrf_rfe_type_setting(dm); #if 1 /*Init all RF funciton*/ halrf_aac_check(dm); @@ -2260,11 +2309,9 @@ void halrf_init(void *dm_void) phydm_config_new_kfree(dm); /*TSSI Init*/ - halrf_tssi_dck_scan(dm); halrf_tssi_dck(dm, true); halrf_tssi_get_efuse(dm); halrf_tssi_set_de(dm); - halrf_tssi_set_tssi_tx_counter(dm, 2, 2); /*TX Gap K*/ halrf_txgapk_write_gain_table(dm); @@ -2284,15 +2331,16 @@ void halrf_dpk_trigger(void *dm_void) return; #endif - if (dm->mp_mode && - rf->is_con_tx && - rf->is_single_tone && - rf->is_carrier_suppresion) - if (*dm->mp_mode && - ((*rf->is_con_tx || - *rf->is_single_tone || - *rf->is_carrier_suppresion))) + if (!dm->mp_mode) + return; + + if (dm->mp_mode && rf->is_con_tx && rf->is_single_tone && + rf->is_carrier_suppresion) { + if (*dm->mp_mode & + (*rf->is_con_tx || *rf->is_single_tone || + *rf->is_carrier_suppresion)) return; + } if (!(rf->rf_supportability & HAL_RF_DPK)) return; @@ -2354,6 +2402,11 @@ void halrf_dpk_trigger(void *dm_void) do_dpk_8814b(dm); break; #endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + do_dpk_8723f(dm); + break; +#endif #if (DM_ODM_SUPPORT_TYPE & (ODM_IOT)) #if (RTL8195B_SUPPORT == 1) @@ -2773,17 +2826,22 @@ void halrf_dpk_track(void *dm_void) || rf->is_txgapk_in_progress) return; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + if (*dm->is_fcs_mode_enable) + return; +#endif + switch (dm->support_ic_type) { #if (RTL8814B_SUPPORT == 1) case ODM_RTL8814B: dpk_track_8814b(dm); - break; + break; #endif #if (RTL8822C_SUPPORT == 1) case ODM_RTL8822C: dpk_track_8822c(dm); - break; + break; #endif #if (RTL8195B_SUPPORT == 1) @@ -2798,6 +2856,12 @@ void halrf_dpk_track(void *dm_void) break; #endif +#if (RTL8723F_SUPPORT == 1) + case ODM_RTL8723F: + dpk_track_8723f(dm); + break; +#endif + #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) #if (RTL8197F_SUPPORT == 1) @@ -2815,19 +2879,19 @@ void halrf_dpk_track(void *dm_void) #if (RTL8198F_SUPPORT == 1) case ODM_RTL8198F: dpk_track_8198f(dm); - break; + break; #endif #if (RTL8812F_SUPPORT == 1) case ODM_RTL8812F: dpk_track_8812f(dm); - break; + break; #endif #if (RTL8197G_SUPPORT == 1) case ODM_RTL8197G: dpk_track_8197g(dm); - break; + break; #endif #endif @@ -2934,13 +2998,13 @@ void _halrf_dpk_info_by_chip(void *dm_void, u32 *_used, char *output, u32 *_out_ #if (RTL8822C_SUPPORT == 1) case ODM_RTL8822C: dpk_info_by_8822c(dm, &used, output, &out_len); - break; + break; #endif #if (RTL8812F_SUPPORT == 1) case ODM_RTL8812F: dpk_info_by_8812f(dm, &used, output, &out_len); - break; + break; #endif #if (RTL8197G_SUPPORT == 1) @@ -2966,6 +3030,7 @@ void _halrf_display_dpk_info(void *dm_void, u32 *_used, char *output, u32 *_out_ u32 used = *_used; u32 out_len = *_out_len; char *ic_name = NULL; + u8 path; switch (dm->support_ic_type) { @@ -3031,8 +3096,11 @@ void _halrf_display_dpk_info(void *dm_void, u32 *_used, char *output, u32 *_out_ "DPK type", (dm->fw_offload_ability & PHYDM_RF_DPK_OFFLOAD) ? "FW" : "Driver", (dpk_info->is_dpk_by_channel) ? "(By channel)" : "(By group)"); + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %d (%d)\n", + "FW Ver (Sub Ver)", dm->fw_version, dm->fw_sub_version); + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %s\n", - "DPK ver", HALRF_DPK_VER); + "DPK Ver", HALRF_DPK_VER); PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %s\n", "RFK init ver", HALRF_RFK_INIT_VER); @@ -3046,11 +3114,15 @@ void _halrf_display_dpk_info(void *dm_void, u32 *_used, char *output, u32 *_out_ return; } + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %d / %d / %d\n", + "DPK Cal / OK / Reload", dpk_info->dpk_cal_cnt, dpk_info->dpk_ok_cnt, + dpk_info->dpk_reload_cnt); + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %s\n", "RFK H2C timeout", (rf->is_rfk_h2c_timeout) ? "Yes" : "No"); PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %s\n", - "DPD Reload", (dpk_info->is_reload) ? "Yes" : "No"); + "DPD Reload", (dpk_info->dpk_status & BIT(0)) ? "Yes" : "No"); PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %s\n", "DPD status", dpk_info->is_dpk_enable ? "Enable" : "Disable"); @@ -3068,10 +3140,18 @@ void _halrf_display_dpk_info(void *dm_void, u32 *_used, char *output, u32 *_out_ (dm->support_ic_type & ODM_IC_2SS) ? ((dpk_info->dpk_path_ok & BIT(1)) >> 1 ? "OK" : "Fail") : "NA", (dm->support_ic_type & ODM_IC_3SS) ? ((dpk_info->dpk_path_ok & BIT(2)) >> 2 ? "OK" : "Fail") : "NA", (dm->support_ic_type & ODM_IC_4SS) ? ((dpk_info->dpk_path_ok & BIT(3)) >> 3 ? "OK" : "Fail") : "NA"); - +#if 0 PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = %d / %d / %d / %d\n", "DPK thermal (path)", dpk_info->thermal_dpk[0], dpk_info->thermal_dpk[1], dpk_info->thermal_dpk[2], dpk_info->thermal_dpk[3]); +#endif + PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = ", + "DPK thermal (path)"); + for (path = 0; path < KPATH; path++) { + PDM_SNPF(out_len, used, output + used, out_len - used, + path == (KPATH - 1) ? "%d\n" : "%d / ", + dpk_info->thermal_dpk[path]); + } PDM_SNPF(out_len, used, output + used, out_len - used, " %-25s = 0x%x\n", "DPK bkup GNT control", dpk_info->gnt_control); @@ -3086,7 +3166,7 @@ void _halrf_display_dpk_info(void *dm_void, u32 *_used, char *output, u32 *_out_ } void halrf_dpk_debug_cmd(void *dm_void, char input[][16], u32 *_used, - char *output, u32 *_out_len) + char *output, u32 *_out_len) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct dm_dpk_info *dpk_info = &dm->dpk_info; @@ -3196,6 +3276,12 @@ void halrf_iqk_info_rsvd_page(void *dm_void, u8 *buf, u32 *buf_size) iqk_info_rsvd_page_8822c(dm, buf, buf_size); break; #endif +#if (RTL8195B_SUPPORT == 1) + case ODM_RTL8195B: + iqk_info_rsvd_page_8195b(dm, buf, buf_size); + break; +#endif + default: break; } @@ -3256,19 +3342,19 @@ halrf_config_rfk_with_header_file(void *dm_void, u32 config_type) odm_read_and_config_mp_8721d_cal_init(dm); } #endif - if (dm->fw_offload_ability & PHYDM_PHY_PARAM_OFFLOAD) { - result = phydm_set_reg_by_fw(dm, - PHYDM_HALMAC_CMD_END, - 0, - 0, - 0, - (enum rf_path)0, - 0); - - RF_DBG(dm, DBG_RF_IQK, "phy param offload end!result = %d", result); +#if (RTL8723F_SUPPORT == 1) + if (dm->support_ic_type == ODM_RTL8723F) { + if (config_type == CONFIG_BB_RF_CAL_INIT) + odm_read_and_config_mp_8723f_cal_init(dm); } +#endif - +#if 1 + if (dm->fw_offload_ability & PHYDM_PHY_PARAM_OFFLOAD) { + result = phydm_set_reg_by_fw(dm, PHYDM_HALMAC_CMD_END, 0, 0, 0, (enum rf_path)0, 0); + RF_DBG(dm, DBG_RF_IQK,"phy param offload end!result = %d", result); + } +#endif return result; } @@ -3291,12 +3377,12 @@ void halrf_txgapk_trigger(void *dm_void) #if (DM_ODM_SUPPORT_TYPE & (ODM_IOT)) #if (RTL8195B_SUPPORT == 1) case ODM_RTL8195B: - phy_txgap_calibrate_8195b(dm, false); + /*phy_txgap_calibrate_8195b(dm, false);*/ break; #endif #if (RTL8721D_SUPPORT == 1) case ODM_RTL8721D: - phy_txgap_calibrate_8721d(dm, false); + /*phy_txgap_calibrate_8721d(dm, false);*/ break; #endif @@ -3304,7 +3390,7 @@ void halrf_txgapk_trigger(void *dm_void) #if (RTL8814B_SUPPORT == 1) case ODM_RTL8814B: - phy_txgap_calibrate_8814b(dm, false); + /*phy_txgap_calibrate_8814b(dm, false);*/ break; #endif @@ -3316,7 +3402,7 @@ void halrf_txgapk_trigger(void *dm_void) default: break; - } + } halrf_rfk_power_save(dm, true); rf->is_txgapk_in_progress = false; @@ -3393,28 +3479,6 @@ void halrf_do_tssi(void *dm_void) } -void halrf_do_tssi_scan(void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - -#if (RTL8822C_SUPPORT == 1) - if (dm->support_ic_type == ODM_RTL8822C) - halrf_do_tssi_scan_8822c(dm); -#endif -} - -void halrf_tssi_set_tssi_tx_counter(void *dm_void, u8 special_scan_num, - u8 connect_ch_num) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - -#if (RTL8822C_SUPPORT == 1) - if (dm->support_ic_type == ODM_RTL8822C) - halrf_tssi_set_tssi_tx_counter_8822c(dm, special_scan_num, - connect_ch_num); -#endif -} - void halrf_set_tssi_enable(void *dm_void, boolean enable) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -3487,6 +3551,10 @@ void halrf_tssi_set_de_for_tx_verify(void *dm_void, u32 tssi_de, u8 path) halrf_tssi_set_de_for_tx_verify_8812f(dm, tssi_de, path); #endif +#if (RTL8197G_SUPPORT == 1) + if (dm->support_ic_type & ODM_RTL8197G) + halrf_tssi_set_de_for_tx_verify_8197g(dm, tssi_de, path); +#endif } @@ -3539,72 +3607,6 @@ void halrf_tssi_set_de(void *dm_void) #endif } -void halrf_tssi_scan_set_tssi_setting( - void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - -#if (RTL8822C_SUPPORT == 1) - if (dm->support_ic_type & ODM_RTL8822C) - halrf_tssi_scan_set_tssi_setting_8822c(dm); -#endif -} - -void halrf_tssi_scan_save_txagc_offset( - void *dm_void, u8 path) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - -#if (RTL8822C_SUPPORT == 1) - if (dm->support_ic_type & ODM_RTL8822C) - halrf_tssi_scan_save_txagc_offset_8822c(dm, path); -#endif -} - -void halrf_tssi_scan_reload_txagc_offset( - void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - -#if (RTL8822C_SUPPORT == 1) - if (dm->support_ic_type & ODM_RTL8822C) - halrf_tssi_scan_reload_txagc_offset_8822c(dm); -#endif -} - -void halrf_tssi_lps_get_txagc_offset( - void *dm_void, u8 *txagc_offset) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - -#if (RTL8822C_SUPPORT == 1) - if (dm->support_ic_type & ODM_RTL8822C) - halrf_tssi_lps_get_txagc_offset_8822c(dm, txagc_offset); -#endif -} - -void halrf_enable_tssi( - void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - -#if (RTL8822C_SUPPORT == 1) - if (dm->support_ic_type & ODM_RTL8822C) - halrf_enable_tssi_8822c(dm); -#endif -} - -void halrf_disable_tssi( - void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - -#if (RTL8822C_SUPPORT == 1) - if (dm->support_ic_type & ODM_RTL8822C) - halrf_disable_tssi_8822c(dm); -#endif -} - void halrf_tssi_dck(void *dm_void, u8 direct_do) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -3643,29 +3645,6 @@ void halrf_tssi_dck(void *dm_void, u8 direct_do) } -void halrf_tssi_dck_scan(void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - - halrf_rfk_handshake(dm, true); - -#if (RTL8822C_SUPPORT == 1) - if (dm->support_ic_type & ODM_RTL8822C) - halrf_tssi_dck_scan_8822c(dm); -#endif - halrf_rfk_handshake(dm, false); -} - -void halrf_set_tssi_codeword_scan(void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - -#if (RTL8822C_SUPPORT == 1) - if (dm->support_ic_type & ODM_RTL8822C) - halrf_set_tssi_codeword_scan_8822c(dm); -#endif -} - void halrf_calculate_tssi_codeword(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -3708,7 +3687,7 @@ u8 halrf_get_tssi_codeword_for_txindex(void *dm_void) #if (RTL8814B_SUPPORT == 1) if (dm->support_ic_type & ODM_RTL8814B) { #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) - return 100; + return 80; #else return 60; #endif @@ -3880,15 +3859,22 @@ void _halrf_dump_subpage(void *dm_void, u32 *_used, char *output, u32 *_out_len, PDM_SNPF(out_len, used, output + used, out_len - used, "\n===============[ Subpage_%d start]===============\n", page); + RF_DBG(dm, DBG_RF_RFK, " ===============[ Subpage_%d start]===============\n", page); + odm_set_bb_reg(dm, R_0x1b00, BIT(2) | BIT(1), page); for (addr = 0x1b00; addr < 0x1c00; addr += 0x10) { PDM_SNPF(out_len, used, output + used, out_len - used, " 0x%x : 0x%08x 0x%08x 0x%08x 0x%08x\n", addr, odm_get_bb_reg(dm, addr, MASKDWORD), - odm_get_bb_reg(dm, addr + 0x4, MASKDWORD), - odm_get_bb_reg(dm, addr + 0x8, MASKDWORD), - odm_get_bb_reg(dm, addr + 0xc, MASKDWORD)); + odm_get_bb_reg(dm, addr + 0x4, MASKDWORD), + odm_get_bb_reg(dm, addr + 0x8, MASKDWORD), + odm_get_bb_reg(dm, addr + 0xc, MASKDWORD)); + RF_DBG(dm, DBG_RF_RFK, " 0x%x : 0x%08x 0x%08x 0x%08x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD), + odm_get_bb_reg(dm, addr + 0x4, MASKDWORD), + odm_get_bb_reg(dm, addr + 0x8, MASKDWORD), + odm_get_bb_reg(dm, addr + 0xc, MASKDWORD)); } *_used = used; @@ -3911,14 +3897,24 @@ void halrf_dump_rfk_reg(void *dm_void, char input[][16], u32 *_used, if (!(dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES))) { PDM_SNPF(out_len, used, output + used, out_len - used, "CMD is Unsupported due to IC type!!!\n"); + RF_DBG(dm, DBG_RF_RFK, "[RFK] CMD is Unsupported due to IC type!!!\n"); return; } else if (rf->is_dpk_in_progress || dm->rf_calibrate_info.is_iqk_in_progress || dm->is_psd_in_process || rf->is_tssi_in_progress || rf->is_txgapk_in_progress) { - PDM_SNPF(out_len, used, output + used, out_len - used, + PDM_SNPF(out_len, used, output + used, out_len - used, "Bypass CMD due to RFK is doing!!!\n"); + RF_DBG(dm, DBG_RF_RFK, "[RFK] Bypass CMD due to RFK is doing!!!\n"); return; } +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + if (*dm->is_fcs_mode_enable) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Bypass CMD due to FCS mode!!!\n"); + RF_DBG(dm, DBG_RF_RFK, "[RFK] Bypass CMD due to FCS mode!!!\n"); + return; + } +#endif supportability = rf->rf_supportability; /*to avoid DPK track interruption*/ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf.h index 98df9d316f6e..e0eaa7f632cd 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf.h @@ -72,12 +72,12 @@ #define IQK_VER_8192F "0x01" #define IQK_VER_8723B "0x1e" #define IQK_VER_8812A "0x02" -#define IQK_VER_8821A "0x01" +#define IQK_VER_8821A "0x02" #elif (DM_ODM_SUPPORT_TYPE & (ODM_CE)) #define IQK_VER_8188E "0x01" #define IQK_VER_8192E "0x01" #define IQK_VER_8192F "0x01" -#define IQK_VER_8723B "0x1e" +#define IQK_VER_8723B "0x1f" #define IQK_VER_8812A "0x01" #define IQK_VER_8821A "0x01" #elif (DM_ODM_SUPPORT_TYPE & (ODM_AP)) @@ -101,20 +101,20 @@ #define IQK_VER_8703B "0x05" #define IQK_VER_8710B "0x01" #define IQK_VER_8723D "0x02" -#define IQK_VER_8822B "0x31" +#define IQK_VER_8822B "0x32" #define IQK_VER_8822C "0x14" #define IQK_VER_8821C "0x23" #define IQK_VER_8198F "0x0b" -#define IQK_VER_8814B "0x13" -#define IQK_VER_8812F "0x0a" -#define IQK_VER_8710C "0x05" +#define IQK_VER_8814B "0x15" +#define IQK_VER_8812F "0x0c" +#define IQK_VER_8710C "0x0a" #define IQK_VER_8197G "0x03" /*LCK version*/ -#define LCK_VER_8188E "0x01" -#define LCK_VER_8192E "0x01" +#define LCK_VER_8188E "0x02" +#define LCK_VER_8192E "0x02" #define LCK_VER_8192F "0x01" -#define LCK_VER_8723B "0x01" +#define LCK_VER_8723B "0x02" #define LCK_VER_8812A "0x01" #define LCK_VER_8821A "0x01" #define LCK_VER_8814A "0x01" @@ -126,10 +126,11 @@ #define LCK_VER_8822B "0x02" #define LCK_VER_8822C "0x00" #define LCK_VER_8821C "0x02" -#define LCK_VER_8814B "0x01" +#define LCK_VER_8814B "0x02" #define LCK_VER_8195B "0x02" -#define LCK_VER_8710C "0x01" -#define LCK_VER_8197G "0x00" +#define LCK_VER_8710C "0x02" +#define LCK_VER_8197G "0x01" +#define LCK_VER_8198F "0x01" /*power tracking version*/ #define PWRTRK_VER_8188E "0x01" @@ -163,14 +164,14 @@ #define DPK_VER_8710B "NONE" #define DPK_VER_8723D "NONE" #define DPK_VER_8822B "NONE" -#define DPK_VER_8822C "0x1f" +#define DPK_VER_8822C "0x20" #define DPK_VER_8821C "NONE" -#define DPK_VER_8192F "0x0d" +#define DPK_VER_8192F "0x0e" #define DPK_VER_8198F "0x0e" -#define DPK_VER_8814B "0x0b" +#define DPK_VER_8814B "0x0f" #define DPK_VER_8195B "0x0c" -#define DPK_VER_8812F "0x07" -#define DPK_VER_8197G "0x06" +#define DPK_VER_8812F "0x0a" +#define DPK_VER_8197G "0x09" /*RFK_INIT version*/ #define RFK_INIT_VER_8822B "0x8" @@ -178,12 +179,12 @@ #define RFK_INIT_VER_8195B "0x1" #define RFK_INIT_VER_8198F "0x8" #define RFK_INIT_VER_8814B "0xa" -#define RFK_INIT_VER_8812F "0x3" -#define RFK_INIT_VER_8197G "0x3" +#define RFK_INIT_VER_8812F "0x4" +#define RFK_INIT_VER_8197G "0x4" /*DACK version*/ #define DACK_VER_8822C "0xa" -#define DACK_VER_8814B "0x3" +#define DACK_VER_8814B "0x4" /*TXGAPK version*/ #define TXGAPK_VER_8814B "0x1" @@ -404,7 +405,7 @@ #define IQK_THRESHOLD 8 #define DPK_THRESHOLD 4 -#define HALRF_ABS(a, b) ((a > b) ? (a - b) : (b - a)) +#define HALRF_ABS(a,b) ((a>b) ? (a-b) : (b-a)) #define SN 100 #define CCK_TSSI_NUM 6 @@ -433,7 +434,8 @@ enum halrf_func_idx { /*F_XXX = PHYDM XXX function*/ RF05_DACK = 5, RF06_DPK_TRK = 6, RF07_2GBAND_SHIFT = 7, - RF08_RXDCK = 8 + RF08_RXDCK = 8, + RF09_RFK = 9 }; enum halrf_ability { @@ -461,6 +463,8 @@ enum halrf_dbg_comp { DBG_RF_DPK = BIT(RF03_DPK), DBG_RF_TXGAPK = BIT(RF04_TXGAPK), DBG_RF_DACK = BIT(RF05_DACK), + DBG_RF_DPK_TRACK = BIT(RF06_DPK_TRK), + DBG_RF_RFK = BIT(RF09_RFK), DBG_RF_MP = BIT(29), DBG_RF_TMP = BIT(30), DBG_RF_INIT = BIT(31) @@ -480,8 +484,7 @@ enum halrf_cmninfo_init { HALRF_CMNINFO_MP_PSD_AVERAGE, HALRF_CMNINFO_IQK_TIMES, HALRF_CMNINFO_MP_POWER_TRACKING_TYPE, - HALRF_CMNINFO_POWER_TRACK_CONTROL, - HALRF_CMNINFO_TSSI_RETRY_SPECIAL_SCAN + HALRF_CMNINFO_POWER_TRACK_CONTROL }; enum halrf_cmninfo_hook { @@ -514,18 +517,17 @@ enum halrf_k_segment_time { #define TSSI_EFUSE_NUM 25 #define TSSI_EFUSE_KFREE_NUM 4 - -#define TSSI_CHANNEL_NUM 70 +#define TSSI_DE_DIFF_EFUSE_NUM 10 struct _halrf_tssi_data { s32 cck_offset_patha; s32 cck_offset_pathb; - s32 power_track_offset[PHYDM_MAX_RF_PATH]; s32 tssi_trk_txagc_offset[PHYDM_MAX_RF_PATH]; s32 delta_tssi_txagc_offset[PHYDM_MAX_RF_PATH]; s16 txagc_codeword[TSSI_CODE_NUM]; u16 tssi_codeword[TSSI_CODE_NUM]; s8 tssi_efuse[PHYDM_MAX_RF_PATH][TSSI_EFUSE_NUM]; + s8 tssi_de_diff_efuse[PHYDM_MAX_RF_PATH][TSSI_DE_DIFF_EFUSE_NUM]; s8 tssi_kfree_efuse[PHYDM_MAX_RF_PATH][TSSI_EFUSE_KFREE_NUM]; u8 thermal[PHYDM_MAX_RF_PATH]; u32 index[PHYDM_MAX_RF_PATH][14]; @@ -533,12 +535,6 @@ struct _halrf_tssi_data { u8 get_thermal; u8 tssi_finish_bit[PHYDM_MAX_RF_PATH]; u8 thermal_trigger; - s8 txagc_offset[PHYDM_MAX_RF_PATH][TSSI_CHANNEL_NUM]; - u8 tssi_thermal[PHYDM_MAX_RF_PATH]; - u8 retry_sacan_tssi; - u8 special_scan_num; - u8 connect_ch_num; - u32 tssi_dck[4][PHYDM_MAX_RF_PATH]; }; struct _halrf_txgapk_info { @@ -590,7 +586,6 @@ struct _hal_rf_ { u8 ext_lna_5g; /*@with 5G external LNA NO/Yes = 0/1*/ u8 ext_pa; /*@with 2G external PNA NO/Yes = 0/1*/ u8 ext_pa_5g; /*@with 5G external PNA NO/Yes = 0/1*/ - #if !(DM_ODM_SUPPORT_TYPE & ODM_IOT) struct _halrf_psd_data halrf_psd_data; struct _halrf_tssi_data halrf_tssi_data; @@ -728,11 +723,6 @@ void halrf_tssi_get_efuse(void *dm_void); void halrf_do_tssi(void *dm_void); -void halrf_do_tssi_scan(void *dm_void); - -void halrf_tssi_set_tssi_tx_counter(void *dm_void, u8 special_scan_num, - u8 connect_ch_num); - void halrf_set_tssi_enable(void *dm_void, boolean enable); void halrf_do_thermal(void *dm_void); @@ -751,24 +741,8 @@ void halrf_thermal_cck(void *dm_void); void halrf_tssi_set_de(void *dm_void); -void halrf_tssi_scan_set_tssi_setting(void *dm_void); - -void halrf_tssi_scan_save_txagc_offset(void *dm_void, u8 path); - -void halrf_tssi_scan_reload_txagc_offset(void *dm_void); - -void halrf_tssi_lps_get_txagc_offset(void *dm_void, u8 *txagc_offset); - -void halrf_enable_tssi(void *dm_void); - -void halrf_disable_tssi(void *dm_void); - void halrf_tssi_dck(void *dm_void, u8 direct_do); -void halrf_tssi_dck_scan(void *dm_void); - -void halrf_set_tssi_codeword_scan(void *dm_void); - void halrf_calculate_tssi_codeword(void *dm_void); void halrf_set_tssi_codeword(void *dm_void); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_debug.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_debug.c index 62b9d226a9c6..ff79a5990a43 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_debug.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_debug.c @@ -174,6 +174,9 @@ void halrf_debug_trace(void *dm_void, char input[][16], u32 *_used, PDM_SNPF(out_len, used, output + used, out_len - used, "04. (( %s ))TXGAPK\n", ((rf->rf_dbg_comp & DBG_RF_TXGAPK) ? ("V") : ("."))); + PDM_SNPF(out_len, used, output + used, out_len - used, + "06. (( %s ))DPK_TRACK\n", + ((rf->rf_dbg_comp & DBG_RF_DPK_TRACK) ? ("V") : ("."))); PDM_SNPF(out_len, used, output + used, out_len - used, "29. (( %s ))MP\n", ((rf->rf_dbg_comp & DBG_RF_MP) ? ("V") : ("."))); @@ -374,15 +377,17 @@ void halrf_init_debug_setting(void *dm_void) rf->rf_dbg_comp = + DBG_RF_RFK | #if DBG #if 0 - /*DBG_RF_TX_PWR_TRACK |*/ + /*DBG_RF_TX_PWR_TRACK | */ /*DBG_RF_IQK | */ /*DBG_RF_LCK | */ /*DBG_RF_DPK | */ - /*DBG_RF_DACK | */ /*DBG_RF_TXGAPK | */ - /*DBG_RF_MP | */ + /*DBG_RF_DACK | */ + /*DBG_RF_DPK_TRACK | */ + /*DBG_RF_MP | */ /*DBG_RF_TMP | */ /*DBG_RF_INIT | */ #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_debug.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_debug.h index 15d4a6268587..765dd1726b65 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_debug.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_debug.h @@ -97,6 +97,23 @@ static __inline void RF_DBG(PDM_ODM_T dm, int comp, char *fmt, ...) #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) static __inline void RF_DBG(struct dm_struct *dm, int comp, char *fmt, ...) { +#if 0 + RT_STATUS rt_status; + va_list args; + char buf[128] = {0};/*PRINT_MAX_SIZE*/ + + if ((comp & dm->rf_table.rf_dbg_comp) == 0) + return; + + if (NULL != fmt) { + va_start(args, fmt); + rt_status = (RT_STATUS)RtlStringCbVPrintfA(buf, sizeof(buf), fmt, args); + va_end(args); + if (rt_status == RT_STATUS_SUCCESS) { + halrf_rt_trace(buf); + } + } +#endif } #else #define RF_DBG(dm, comp, fmt, args...) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_dpk.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_dpk.h index 282d15bf559b..c090e7ea508c 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_dpk.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_dpk.h @@ -44,6 +44,22 @@ #define AVG_THERMAL_NUM_DPK 8 #define THERMAL_DPK_AVG_NUM 4 +/*define RF path numer*/ +#if (RTL8198F_SUPPORT == 1 || RTL8814B_SUPPORT == 1) +#define KPATH 4 +#elif (RTL8192F_SUPPORT == 1 || RTL8197F_SUPPORT == 1 ||RTL8197G_SUPPORT == 1 ||\ + RTL8822C_SUPPORT == 1 || RTL8812F_SUPPORT == 1) +#define KPATH 2 +#else +#define KPATH 1 +#endif + +#if (RTL8814B_SUPPORT == 1 || RTL8721D_SUPPORT == 1) +#define GROUP_5G 6 +#elif (RTL8195B_SUPPORT == 1) +#define GROUP_5G 13 +#endif + /*@---------------------------End Define Parameters---------------------------*/ struct dm_dpk_info { @@ -52,19 +68,23 @@ struct dm_dpk_info { boolean is_dpk_pwr_on; boolean is_dpk_by_channel; boolean is_tssi_mode; - boolean is_reload; - u16 dpk_path_ok; + u8 dpk_status; /*bit[0]:reload;bit[1]:cal;bit[2]:cal_ok*/ + u16 dpk_path_ok; /*@BIT(15)~BIT(12) : 5G reserved, BIT(11)~BIT(8) 5G_S3~5G_S0*/ /*@BIT(7)~BIT(4) : 2G reserved, BIT(3)~BIT(0) 2G_S3~2G_S0*/ - u8 thermal_dpk[4]; /*path*/ - u8 thermal_dpk_avg[4][AVG_THERMAL_NUM_DPK]; /*path*/ - u8 pre_pwsf[4]; + u8 thermal_dpk[KPATH]; /*path*/ + u8 thermal_dpk_avg[KPATH][AVG_THERMAL_NUM_DPK]; /*path*/ + u8 pre_pwsf[KPATH]; u8 thermal_dpk_avg_index; u32 gnt_control; u32 gnt_value; u8 dpk_ch; u8 dpk_band; u8 dpk_bw; + u32 dpk_rf18[2]; + u32 dpk_cal_cnt; + u32 dpk_ok_cnt; + u32 dpk_reload_cnt; #if (RTL8822C_SUPPORT == 1 || RTL8812F_SUPPORT == 1 || RTL8197G_SUPPORT == 1) u16 dc_i[2]; /*MDPD DC I path*/ @@ -82,59 +102,49 @@ struct dm_dpk_info { #endif #if (RTL8198F_SUPPORT == 1 || RTL8192F_SUPPORT == 1 || RTL8197F_SUPPORT == 1 ||\ - RTL8814B_SUPPORT == 1 || RTL8197G_SUPPORT == 1) + RTL8814B_SUPPORT == 1 || RTL8197G_SUPPORT == 1) /*2G DPK data*/ - u8 dpk_result[4][3]; /*path/group*/ - u8 pwsf_2g[4][3]; /*path/group*/ - u32 lut_2g_even[4][3][64]; /*path/group/LUT data*/ - u32 lut_2g_odd[4][3][64]; /*path/group/LUT data*/ + u8 dpk_result[KPATH][3]; /*path/group*/ + u8 pwsf_2g[KPATH][3]; /*path/group*/ + u32 lut_2g_even[KPATH][3][64]; /*path/group/LUT data*/ + u32 lut_2g_odd[KPATH][3][64]; /*path/group/LUT data*/ s16 tmp_pas_i[32]; /*PAScan I data*/ s16 tmp_pas_q[32]; /*PAScan Q data*/ +#endif + +#if (RTL8814B_SUPPORT == 1) /*5G DPK data*/ - u8 dpk_5g_result[4][6]; /*path/group*/ - u8 pwsf_5g[4][6]; /*path/group*/ - u32 lut_5g[4][6][64]; /*path/group/LUT data*/ - u32 lut_2g[4][3][64]; /*path/group/LUT data*/ - /*8814B*/ + u8 dpk_5g_result[KPATH][GROUP_5G]; /*path/group*/ + u8 pwsf_5g[KPATH][GROUP_5G]; /*path/group*/ + u32 lut_5g[KPATH][GROUP_5G][64]; /*path/group/LUT data*/ + u32 lut_2g[KPATH][3][64]; /*path/group/LUT data*/ u8 rxbb[4]; /*path/group*/ u8 txbb[4]; /*path/group*/ u8 tx_gain; #endif -#if (RTL8195B_SUPPORT == 1) - /*2G DPK data*/ - u8 dpk_2g_result[1][3]; /*path/group*/ - u8 pwsf_2g[1][3]; /*path/group*/ - u32 lut_2g_even[1][3][16]; /*path/group/LUT data*/ - u32 lut_2g_odd[1][3][16]; /*path/group/LUT data*/ - /*5G DPK data*/ - u8 dpk_5g_result[1][13]; /*path/group*/ - u8 pwsf_5g[1][13]; /*path/group*/ - u32 lut_5g_even[1][13][16]; /*path/group/LUT data*/ - u32 lut_5g_odd[1][13][16]; /*path/group/LUT data*/ -#endif - -#if (RTL8721D_SUPPORT == 1) +#if (RTL8195B_SUPPORT == 1 || RTL8721D_SUPPORT == 1) u8 dpk_txagc; /*2G DPK data*/ - u8 dpk_2g_result[1][3]; /*path/group*/ - u8 pwsf_2g[1][3]; /*path/group*/ - u32 lut_2g_even[1][3][16]; /*path/group/LUT data*/ - u32 lut_2g_odd[1][3][16]; /*path/group/LUT data*/ + u8 dpk_2g_result[KPATH][3]; /*path/group*/ + u8 pwsf_2g[KPATH][3]; /*path/group*/ + u32 lut_2g_even[KPATH][3][16]; /*path/group/LUT data*/ + u32 lut_2g_odd[KPATH][3][16]; /*path/group/LUT data*/ /*5G DPK data*/ - u8 dpk_5g_result[1][6]; /*path/group*/ - u8 pwsf_5g[1][6]; /*path/group*/ - u32 lut_5g_even[1][6][16]; /*path/group/LUT data*/ - u32 lut_5g_odd[1][6][16]; /*path/group/LUT data*/ + u8 dpk_5g_result[KPATH][GROUP_5G]; /*path/group*/ + u8 pwsf_5g[KPATH][GROUP_5G]; /*path/group*/ + u32 lut_5g_even[KPATH][GROUP_5G][16]; /*path/group/LUT data*/ + u32 lut_5g_odd[KPATH][GROUP_5G][16]; /*path/group/LUT data*/ #endif - }; #if (RTL8822C_SUPPORT == 1) struct dm_dpk_c2h_report { - u8 path_ok[2]; /*path0_ok/path1_ok*/ + u8 result[2]; /*ch0_result/ch1_result*/ u8 therm[2][2]; /*therm0_s0/therm0_s1/therm1_s0/therm1_s1*/ u8 therm_delta[2][2]; /*therm_delta0_s0/therm_delta0_s1/therm_delta1_s0/therm_delta1_s1*/ + u32 dpk_rf18[2]; /*dpk_ch0/dpk_ch1*/ + u8 dpk_status; /*dpk_status*/ }; #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_iqk.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_iqk.h index 37e2c61793a6..2d0df4069c05 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_iqk.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_iqk.h @@ -86,10 +86,8 @@ struct dm_iqk_info { RTL8195B_SUPPORT == 1 || RTL8198F_SUPPORT == 1 ||\ RTL8814B_SUPPORT == 1 || RTL8822C_SUPPORT == 1 ||\ RTL8812F_SUPPORT == 1 || RTL8197G_SUPPORT == 1 ||\ - RTL8710C_SUPPORT == 1) + RTL8710C_SUPPORT == 1 || RTL8723F_SUPPORT == 1) u32 iqk_channel[2]; - u32 nbtxk_1b38[2]; - u32 nbrxk_1b3c[2]; boolean iqk_fail_report[2][NUM][2]; /*channel/path/TRX(TX:0, RX:1) */ /*channel / path / TRX(TX:0, RX:1) / CFIR_real*/ /*channel index = 2 is just for debug*/ @@ -102,6 +100,11 @@ struct dm_iqk_info { /*channel index = 2 is just for debug*/ u16 iqk_cfir_imag[3][2][2][17]; /*times/path*/ +#elif (RTL8195B_SUPPORT == 1) + u32 iqk_cfir_real[3][NUM][2][9]; + u32 iqk_cfir_imag[3][NUM][2][9]; + /*channel / path / TRX(TX:0, RX:1) / CFIR_imag*/ + /*channel index = 2 is just for debug*/ #else u32 iqk_cfir_real[3][NUM][2][8]; /*channel / path / TRX(TX:0, RX:1) / CFIR_imag*/ @@ -136,6 +139,8 @@ struct dm_iqk_info { u32 gs1_xym[2][6]; u32 gs2_xym[2][6]; u32 rxk1_xym[2][6]; + u32 nbtxk_1b38[2]; + u32 nbrxk_1b3c[2]; #endif #if (RTL8710C_SUPPORT == 1 || RTL8197G_SUPPORT == 1 ) u32 txxy[2][2]; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_kfree.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_kfree.c index 8adcc1001f09..3c4a939cd585 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_kfree.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_kfree.c @@ -775,6 +775,9 @@ void phydm_get_thermal_trim_offset_8198f(void *dm_void) odm_efuse_one_byte_read(dm, PPG_THERMAL_OFFSET_98F, &pg_therm, false); + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f efuse thermal trim 0x%X=0x%X\n", + PPG_THERMAL_OFFSET_98F, pg_therm); + if (pg_therm != 0) { pg_therm = pg_therm & 0x1f; if ((pg_therm & BIT(0)) == 0) @@ -798,33 +801,51 @@ void phydm_get_power_trim_offset_8198f(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u8 pg_power = 0, i, j; + u8 i, j; + u8 power_trim[6] = {0}; - odm_efuse_one_byte_read(dm, PPG_2GL_TXAB_98F, &pg_power, false); + odm_efuse_one_byte_read(dm, PPG_2GL_TXAB_98F, &power_trim[0], false); + odm_efuse_one_byte_read(dm, PPG_2GL_TXCD_98F, &power_trim[1], false); + odm_efuse_one_byte_read(dm, PPG_2GM_TXAB_98F, &power_trim[2], false); + odm_efuse_one_byte_read(dm, PPG_2GM_TXCD_98F, &power_trim[3], false); + odm_efuse_one_byte_read(dm, PPG_2GH_TXAB_98F, &power_trim[4], false); + odm_efuse_one_byte_read(dm, PPG_2GH_TXCD_98F, &power_trim[5], false); - if (pg_power != 0) { - power_trim_info->bb_gain[0][0] = pg_power & 0xf; - power_trim_info->bb_gain[0][1] = (pg_power & 0xf0) >> 4; + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f efuse Power Trim 0x%X=0x%X 0x%X=0x%X 0x%X=0x%X 0x%X=0x%X 0x%X=0x%X 0x%X=0x%X\n", + PPG_2GL_TXAB_98F, power_trim[0], + PPG_2GL_TXCD_98F, power_trim[1], + PPG_2GM_TXAB_98F, power_trim[2], + PPG_2GM_TXCD_98F, power_trim[3], + PPG_2GH_TXAB_98F, power_trim[4], + PPG_2GH_TXCD_98F, power_trim[5] + ); - odm_efuse_one_byte_read(dm, PPG_2GL_TXCD_98F, &pg_power, false); - power_trim_info->bb_gain[0][2] = pg_power & 0xf; - power_trim_info->bb_gain[0][3] = (pg_power & 0xf0) >> 4; + j = 0; + for (i = 0; i < 6; i++) { + if (power_trim[i] == 0x0) + j++; + } - odm_efuse_one_byte_read(dm, PPG_2GM_TXAB_98F, &pg_power, false); - power_trim_info->bb_gain[1][0] = pg_power & 0xf; - power_trim_info->bb_gain[1][1] = (pg_power & 0xf0) >> 4; + if (j == 6) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f Power Trim no pg\n"); + } else { + power_trim_info->bb_gain[0][0] = power_trim[0] & 0xf; + power_trim_info->bb_gain[0][1] = (power_trim[0] & 0xf0) >> 4; - odm_efuse_one_byte_read(dm, PPG_2GM_TXCD_98F, &pg_power, false); - power_trim_info->bb_gain[1][2] = pg_power & 0xf; - power_trim_info->bb_gain[1][3] = (pg_power & 0xf0) >> 4; + power_trim_info->bb_gain[0][2] = power_trim[1] & 0xf; + power_trim_info->bb_gain[0][3] = (power_trim[1] & 0xf0) >> 4; - odm_efuse_one_byte_read(dm, PPG_2GH_TXAB_98F, &pg_power, false); - power_trim_info->bb_gain[2][0] = pg_power & 0xf; - power_trim_info->bb_gain[2][1] = (pg_power & 0xf0) >> 4; + power_trim_info->bb_gain[1][0] = power_trim[2] & 0xf; + power_trim_info->bb_gain[1][1] = (power_trim[2] & 0xf0) >> 4; - odm_efuse_one_byte_read(dm, PPG_2GH_TXCD_98F, &pg_power, false); - power_trim_info->bb_gain[2][2] = pg_power & 0xf; - power_trim_info->bb_gain[2][3] = (pg_power & 0xf0) >> 4; + power_trim_info->bb_gain[1][2] = power_trim[3] & 0xf; + power_trim_info->bb_gain[1][3] = (power_trim[3] & 0xf0) >> 4; + + power_trim_info->bb_gain[2][0] = power_trim[4] & 0xf; + power_trim_info->bb_gain[2][1] = (power_trim[4] & 0xf0) >> 4; + + power_trim_info->bb_gain[2][2] = power_trim[5] & 0xf; + power_trim_info->bb_gain[2][3] = (power_trim[5] & 0xf0) >> 4; power_trim_info->flag = power_trim_info->flag | KFREE_FLAG_ON | KFREE_FLAG_ON_2G; @@ -849,23 +870,32 @@ void phydm_get_pa_bias_offset_8198f(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u8 pg_pa_bias = 0, i; + u8 i, j; + u8 pa_bias[2] = {0}; u8 tx_pa_bias[4] = {0}; - odm_efuse_one_byte_read(dm, PPG_PABIAS_2GAB_98F, &pg_pa_bias, false); + odm_efuse_one_byte_read(dm, PPG_PABIAS_2GAB_98F, &pa_bias[0], false); + odm_efuse_one_byte_read(dm, PPG_PABIAS_2GCD_98F, &pa_bias[1], false); - if (pg_pa_bias != 0) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f efuse Tx PA Bias 0x%X=0x%X 0x%X=0x%X\n", + PPG_PABIAS_2GAB_98F, pa_bias[0], PPG_PABIAS_2GCD_98F, pa_bias[1]); + + j = 0; + for (i = 0; i < 2; i++) { + if (pa_bias[i] == 0x0) + j++; + } + + if (j == 2) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f Tx PA Bias no pg\n"); + } else { /*paht ab*/ - odm_efuse_one_byte_read(dm, PPG_PABIAS_2GAB_98F, - &pg_pa_bias, false); - tx_pa_bias[0] = pg_pa_bias & 0xf; - tx_pa_bias[1] = ((pg_pa_bias & 0xf0) >> 4); + tx_pa_bias[0] = pa_bias[0] & 0xf; + tx_pa_bias[1] = ((pa_bias[0] & 0xf0) >> 4); /*paht cd*/ - odm_efuse_one_byte_read(dm, PPG_PABIAS_2GCD_98F, - &pg_pa_bias, false); - tx_pa_bias[2] = pg_pa_bias & 0xf; - tx_pa_bias[3] = ((pg_pa_bias & 0xf0) >> 4); + tx_pa_bias[2] = pa_bias[1] & 0xf; + tx_pa_bias[3] = ((pa_bias[1] & 0xf0) >> 4); for (i = RF_PATH_A; i < 4; i++) { if ((tx_pa_bias[i] & 0x1) == 1) @@ -886,8 +916,6 @@ void phydm_get_pa_bias_offset_8198f(void *dm_void) odm_set_rf_reg(dm, i, 0x60, 0x0000f000, tx_pa_bias[i]); power_trim_info->pa_bias_flag |= PA_BIAS_FLAG_ON; - } else { - RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f tx pa bias no pg\n"); } } @@ -896,34 +924,39 @@ void phydm_get_set_lna_offset_8198f(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u8 pg_pa_bias = 0, i; + u8 i, j; + u8 lna_trim[4] = {0}; u8 cg[4] = {0}, cs[4] = {0}; u32 rf_reg; - odm_efuse_one_byte_read(dm, PPG_LNA_2GA_98F, &pg_pa_bias, false); + odm_efuse_one_byte_read(dm, PPG_LNA_2GA_98F, &lna_trim[0], false); + odm_efuse_one_byte_read(dm, PPG_LNA_2GB_98F, &lna_trim[1], false); + odm_efuse_one_byte_read(dm, PPG_LNA_2GC_98F, &lna_trim[2], false); + odm_efuse_one_byte_read(dm, PPG_LNA_2GD_98F, &lna_trim[3], false); - if (pg_pa_bias != 0) { - odm_efuse_one_byte_read(dm, PPG_LNA_2GA_98F, - &pg_pa_bias, false); - cg[0] = (pg_pa_bias & 0xc) >> 2; - cs[0] = pg_pa_bias & 0x3; + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f efuse LNA Trim 0x%X=0x%X 0x%X=0x%X 0x%X=0x%X 0x%X=0x%X\n", + PPG_LNA_2GA_98F, lna_trim[0], + PPG_LNA_2GB_98F, lna_trim[1], + PPG_LNA_2GC_98F, lna_trim[2], + PPG_LNA_2GD_98F, lna_trim[3] + ); - odm_efuse_one_byte_read(dm, PPG_LNA_2GB_98F, - &pg_pa_bias, false); - cg[1] = (pg_pa_bias & 0xc) >> 2; - cs[1] = pg_pa_bias & 0x3; + j = 0; + for (i = 0; i < 4; i++) { + if (lna_trim[i] == 0x0) + j++; + } - odm_efuse_one_byte_read(dm, PPG_LNA_2GC_98F, - &pg_pa_bias, false); - cg[2] = (pg_pa_bias & 0xc) >> 2; - cs[2] = pg_pa_bias & 0x3; + if (j == 4) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f LNA no pg\n"); + } else { - odm_efuse_one_byte_read(dm, PPG_LNA_2GD_98F, - &pg_pa_bias, false); - cg[3] = (pg_pa_bias & 0xc) >> 2; - cs[3] = pg_pa_bias & 0x3; + for (i = 0; i < 4; i++) { + cg[i] = (lna_trim[i] & 0xc) >> 2; + cs[i] = lna_trim[i] & 0x3; + } - for (i = RF_PATH_A; i < 4; i++) { + for (i = RF_PATH_A; i <= RF_PATH_D; i++) { RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f lna cg[%d]=0x%x cs[%d]=0x%x\n", i, cg[i], i, cs[i]); @@ -950,8 +983,6 @@ void phydm_get_set_lna_offset_8198f(void *dm_void) } power_trim_info->lna_flag |= LNA_FLAG_ON; - } else { - RF_DBG(dm, DBG_RF_MP, "[kfree] 8198f lna no pg\n"); } } @@ -960,7 +991,7 @@ void phydm_set_kfree_to_rf_8198f(void *dm_void, u8 e_rf_path, u8 data) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u32 band, i; + u32 i; s8 pwr_offset[3]; RF_DBG(dm, DBG_RF_MP, @@ -1001,10 +1032,11 @@ void phydm_set_kfree_to_rf_8198f(void *dm_void, u8 e_rf_path, u8 data) void phydm_clear_kfree_to_rf_8198f(void *dm_void, u8 e_rf_path, u8 data) { struct dm_struct *dm = (struct dm_struct *)dm_void; +#if 0 RF_DBG(dm, DBG_RF_MP, "[kfree] %s:Clear kfree to rf 0x55\n", __func__); -#if 0 + /*power_trim based on 55[19:14]*/ odm_set_rf_reg(dm, e_rf_path, RF_0x55, BIT(5), 1); /*enable 55[14] for 0.5db step*/ @@ -1033,7 +1065,6 @@ void phydm_clear_kfree_to_rf_8198f(void *dm_void, u8 e_rf_path, u8 data) odm_set_rf_reg(dm, e_rf_path, RF_0xf5, BIT(18), 0); /*write disable*/ odm_set_rf_reg(dm, e_rf_path, RF_0xef, BIT(7), 0); -#else odm_set_rf_reg(dm, e_rf_path, RF_0xdf, BIT(7), 1); /*odm_set_rf_reg(dm, e_rf_path, RF_0xf5, BIT(18), 0);*/ @@ -1248,7 +1279,7 @@ void phydm_get_tssi_trim_offset_8822c(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u8 i, j = 0; + u8 i, j; u8 pg_power[16] = {0}; odm_efuse_one_byte_read(dm, TSSI_2GM_TXA_22C, &pg_power[0], false); @@ -1268,14 +1299,14 @@ void phydm_get_tssi_trim_offset_8822c(void *dm_void) odm_efuse_one_byte_read(dm, TSSI_5GH2_TXA_22C, &pg_power[14], false); odm_efuse_one_byte_read(dm, TSSI_5GH2_TXB_22C, &pg_power[15], false); + j = 0; for (i = 0; i < 16; i++) { if (pg_power[i] == 0xff) j++; } - if (j == 15) { + if (j == 16) { RF_DBG(dm, DBG_RF_MP, "[kfree] 8822c tssi trim no PG\n"); - return; } else { power_trim_info->tssi_trim[0][0] = (s8)pg_power[0]; power_trim_info->tssi_trim[0][1] = (s8)pg_power[1]; @@ -1411,7 +1442,7 @@ void phydm_get_set_thermal_trim_offset_8812f(void *dm_void) odm_efuse_one_byte_read(dm, PPG_THERMAL_A_OFFSET_22C, &pg_therm, false); - if (pg_therm != 0xff) { + if (pg_therm != 0xff && pg_therm != 0x0) { /*s0*/ pg_therm = pg_therm & 0x1f; @@ -1519,8 +1550,10 @@ void phydm_get_set_power_trim_offset_8812f(void *dm_void) odm_efuse_one_byte_read(dm, PPG_5GL2_TXB_22C, &pg_power4, false); odm_efuse_one_byte_read(dm, PPG_5GM1_TXA_22C, &pg_power5, false); - if (pg_power1 != 0xff || pg_power2 != 0xff || pg_power3 != 0xff || - pg_power4 != 0xff || pg_power5 != 0xff) { + if ((pg_power1 != 0xff || pg_power2 != 0xff || pg_power3 != 0xff || + pg_power4 != 0xff || pg_power5 != 0xff) && + (pg_power1 != 0x0 || pg_power2 != 0x0 || pg_power3 != 0x0 || + pg_power4 != 0x0 || pg_power5 != 0x0)) { #if 0 odm_efuse_one_byte_read(dm, PPG_2GL_TXAB_22C, &pg_power, false); if (pg_power == 0xff) @@ -1610,7 +1643,7 @@ void phydm_get_tssi_trim_offset_8812f(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u8 i, j = 0; + u8 i, j ; u8 pg_power[16] = {0}; #if 0 @@ -1632,14 +1665,14 @@ void phydm_get_tssi_trim_offset_8812f(void *dm_void) odm_efuse_one_byte_read(dm, TSSI_5GH2_TXA_22C, &pg_power[14], false); odm_efuse_one_byte_read(dm, TSSI_5GH2_TXB_22C, &pg_power[15], false); + j = 0; for (i = 4; i < 16; i++) { - if (pg_power[i] == 0xff) + if (pg_power[i] == 0xff || pg_power[i] == 0x0) j++; } if (j == 12) { RF_DBG(dm, DBG_RF_MP, "[kfree] 8812f tssi trim no PG\n"); - return; } else { #if 0 power_trim_info->tssi_trim[0][0] = (s8)pg_power[0]; @@ -1722,7 +1755,7 @@ void phydm_get_set_pa_bias_offset_8812f(void *dm_void) odm_efuse_one_byte_read(dm, PPG_PABIAS_5GA_22C, &pg_pa_bias, false); - if (pg_pa_bias != 0xff) { + if (pg_pa_bias != 0xff && pg_pa_bias != 0x0) { #if 0 /*2G s0*/ odm_efuse_one_byte_read(dm, PPG_PABIAS_2GA_22C, @@ -1799,43 +1832,48 @@ void phydm_set_power_trim_rf_8195b(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u32 band, i; - s8 pwr_offset[3]; RF_DBG(dm, DBG_RF_MP, "[kfree] %s:Set kfree to rf 0x33\n", __func__); - odm_set_rf_reg(dm, RF_PATH_A, RF_0xee, BIT(19), 1); + if (power_trim_info->flag & KFREE_FLAG_ON) { + odm_set_rf_reg(dm, RF_PATH_A, RF_0xee, BIT(19), 1); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x0); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[0][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x1); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[1][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x2); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[2][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x4); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[3][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x5); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[4][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x6); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[5][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x7); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[6][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x8); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[7][RF_PATH_A]); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0xe); - odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, - power_trim_info->bb_gain[7][RF_PATH_A]); + if (power_trim_info->flag & KFREE_FLAG_ON_2G) { + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x0); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[0][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x1); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[1][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x2); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[2][RF_PATH_A]); + } - odm_set_rf_reg(dm, RF_PATH_A, RF_0xee, BIT(19), 0); + if (power_trim_info->flag & KFREE_FLAG_ON_5G) { + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x4); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[3][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x5); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[4][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x6); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[5][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x7); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[6][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0x8); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[7][RF_PATH_A]); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, RFREGOFFSETMASK, 0xe); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, 0x0000003f, + power_trim_info->bb_gain[7][RF_PATH_A]); + } + + odm_set_rf_reg(dm, RF_PATH_A, RF_0xee, BIT(19), 0); + } } @@ -1849,6 +1887,7 @@ void phydm_get_set_power_trim_offset_8195b(void *dm_void) odm_efuse_one_byte_read(dm, PPG_2GL_TXA_95B, &pg_power, false); if (pg_power != 0xff) { + odm_efuse_one_byte_read(dm, PPG_2GL_TXA_95B, &pg_power, false); power_trim_info->bb_gain[0][0] = pg_power & 0xf; odm_efuse_one_byte_read(dm, PPG_2GM_TXA_95B, &pg_power, false); @@ -1857,6 +1896,15 @@ void phydm_get_set_power_trim_offset_8195b(void *dm_void) odm_efuse_one_byte_read(dm, PPG_2GH_TXA_95B, &pg_power, false); power_trim_info->bb_gain[2][0] = pg_power & 0xf; + power_trim_info->flag = + power_trim_info->flag | KFREE_FLAG_ON | KFREE_FLAG_ON_2G; + } + + pg_power = 0xff; + + odm_efuse_one_byte_read(dm, PPG_5GL1_TXA_95B, &pg_power, false); + + if (pg_power != 0xff) { odm_efuse_one_byte_read(dm, PPG_5GL1_TXA_95B, &pg_power, false); power_trim_info->bb_gain[3][0] = pg_power & 0x1f; @@ -1872,13 +1920,12 @@ void phydm_get_set_power_trim_offset_8195b(void *dm_void) odm_efuse_one_byte_read(dm, PPG_5GH1_TXA_95B, &pg_power, false); power_trim_info->bb_gain[7][0] = pg_power & 0x1f; - phydm_set_power_trim_rf_8195b(dm); - power_trim_info->flag = - power_trim_info->flag | - KFREE_FLAG_ON | KFREE_FLAG_ON_2G | KFREE_FLAG_ON_5G; + power_trim_info->flag | KFREE_FLAG_ON | KFREE_FLAG_ON_5G; } + phydm_set_power_trim_rf_8195b(dm); + RF_DBG(dm, DBG_RF_MP, "[kfree] 8195b power trim flag:0x%02x\n", power_trim_info->flag); @@ -1902,10 +1949,10 @@ void phydm_get_set_pa_bias_offset_8195b(void *dm_void) RF_DBG(dm, DBG_RF_MP, "======>%s\n", __func__); + /*2G*/ odm_efuse_one_byte_read(dm, PPG_PABIAS_2GA_95B, &pg_pa_bias, false); if (pg_pa_bias != 0xff) { - /*2G*/ odm_efuse_one_byte_read(dm, PPG_PABIAS_2GA_95B, &pg_pa_bias, false); pg_pa_bias = pg_pa_bias & 0xf; @@ -1913,8 +1960,16 @@ void phydm_get_set_pa_bias_offset_8195b(void *dm_void) RF_DBG(dm, DBG_RF_MP, "[kfree] 2G pa_bias=0x%x\n", pg_pa_bias); odm_set_rf_reg(dm, RF_PATH_A, 0x60, 0x0000f000, pg_pa_bias); + } else { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8195b 2G tx pa bias no pg\n"); + } - /*5G*/ + /*5G*/ + pg_pa_bias = 0xff; + + odm_efuse_one_byte_read(dm, PPG_PABIAS_5GA_95B, &pg_pa_bias, false); + + if (pg_pa_bias != 0xff) { odm_efuse_one_byte_read(dm, PPG_PABIAS_5GA_95B, &pg_pa_bias, false); pg_pa_bias = pg_pa_bias & 0xf; @@ -1925,7 +1980,7 @@ void phydm_get_set_pa_bias_offset_8195b(void *dm_void) power_trim_info->pa_bias_flag |= PA_BIAS_FLAG_ON; } else { - RF_DBG(dm, DBG_RF_MP, "[kfree] 8195b tx pa bias no pg\n"); + RF_DBG(dm, DBG_RF_MP, "[kfree] 8195b 5G tx pa bias no pg\n"); } } @@ -2092,11 +2147,12 @@ void phydm_get_set_power_trim_offset_8721d(void *dm_void) void phydm_get_set_pa_bias_offset_8721d(void *dm_void) { +#if 0 struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; u8 pg_pa_bias = 0xff; -#if 0 + RF_DBG(dm, DBG_RF_MP, "======>%s\n", __func__); odm_efuse_one_byte_read(dm, PPG_PABIAS_2GA_95B, &pg_pa_bias, false); @@ -2132,16 +2188,25 @@ void phydm_get_thermal_trim_offset_8197g(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; - u8 pg_therm = 0; + u8 pg_therm = 0xff, i; - odm_efuse_one_byte_read(dm, PPG_THERMAL_OFFSET_97G, &pg_therm, false); + odm_efuse_one_byte_read(dm, PPG_THERMAL_A_OFFSET_97G, &pg_therm, false); - if (pg_therm != 0) { - pg_therm = pg_therm & 0x1f; - if ((pg_therm & BIT(0)) == 0) - power_trim_info->thermal = (-1 * (pg_therm >> 1)); - else - power_trim_info->thermal = (pg_therm >> 1); + if (pg_therm != 0x0) { + for (i = 0; i < 2; i++) { + if (i == 0) + odm_efuse_one_byte_read(dm, PPG_THERMAL_A_OFFSET_97G, &pg_therm, false); + else if (i == 1) + odm_efuse_one_byte_read(dm, PPG_THERMAL_B_OFFSET_97G, &pg_therm, false); + + RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g Efuse thermal S%d:0x%x\n", i, pg_therm); + + pg_therm = pg_therm & 0x1f; + if ((pg_therm & BIT(0)) == 0) + power_trim_info->multi_thermal[i] = (-1 * (pg_therm >> 1)); + else + power_trim_info->multi_thermal[i] = (pg_therm >> 1); + } power_trim_info->flag |= KFREE_FLAG_THERMAL_K_ON; } @@ -2149,9 +2214,11 @@ void phydm_get_thermal_trim_offset_8197g(void *dm_void) RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g thermal trim flag:0x%02x\n", power_trim_info->flag); - if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) - RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g thermal:%d\n", - power_trim_info->thermal); + for (i = 0; i < 2; i++) { + if (power_trim_info->flag & KFREE_FLAG_THERMAL_K_ON) + RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g thermal S%d:%d\n", + i ,power_trim_info->multi_thermal[i]); + } } void phydm_set_power_trim_offset_8197g(void *dm_void) @@ -2229,6 +2296,70 @@ void phydm_get_set_power_trim_offset_8197g(void *dm_void) } } +void phydm_get_tssi_trim_offset_8197g(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u8 i, j; + u8 pg_power[4] = {0}; + + odm_efuse_one_byte_read(dm, TSSI_2GL_TXA_97G, &pg_power[0], false); + odm_efuse_one_byte_read(dm, TSSI_2GL_TXB_97G, &pg_power[1], false); + odm_efuse_one_byte_read(dm, TSSI_2GH_TXA_97G, &pg_power[2], false); + odm_efuse_one_byte_read(dm, TSSI_2GH_TXB_97G, &pg_power[3], false); + + j = 0; + for (i = 0; i < 4; i++) { + if (pg_power[i] == 0x0) + j++; + } + + if (j == 4) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8197g tssi trim no PG\n"); + } else { + power_trim_info->tssi_trim[0][0] = (s8)pg_power[0]; + power_trim_info->tssi_trim[0][1] = (s8)pg_power[1]; + power_trim_info->tssi_trim[1][0] = (s8)pg_power[0]; + power_trim_info->tssi_trim[1][1] = (s8)pg_power[1]; + power_trim_info->tssi_trim[2][0] = (s8)pg_power[2]; + power_trim_info->tssi_trim[2][1] = (s8)pg_power[3]; + + power_trim_info->flag = + power_trim_info->flag | TSSI_TRIM_FLAG_ON; + + for (i = 0; i < KFREE_BAND_NUM; i++) { + for (j = 0; j < MAX_PATH_NUM_8197G; j++) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8197g tssi_trim[%d][%d]=0x%X\n", + i, j, power_trim_info->tssi_trim[i][j]); + } + } + } +} + +s8 phydm_get_tssi_trim_de_8197g(void *dm_void, u8 path) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u8 channel = *dm->channel, group = 0; + + if (channel >= 1 && channel <= 3) + group = 0; + else if (channel >= 4 && channel <= 9) + group = 1; + else if (channel >= 10 && channel <= 14) + group = 2; + else { + RF_DBG(dm, DBG_RF_MP, "[kfree] Channel(%d) is not exist in Group\n", + channel); + return 0; + } + + return power_trim_info->tssi_trim[group][path]; +} + void phydm_get_set_pa_bias_offset_8197g(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2239,7 +2370,7 @@ void phydm_get_set_pa_bias_offset_8197g(void *dm_void) odm_efuse_one_byte_read(dm, PPG_PABIAS_2GAB_97G, &pg_pa_bias, false); - if (pg_pa_bias != 0xff) { + if (pg_pa_bias != 0x0) { /*paht ab*/ odm_efuse_one_byte_read(dm, PPG_PABIAS_2GAB_97G, &pg_pa_bias, false); @@ -2265,7 +2396,6 @@ void phydm_get_set_lna_offset_8197g(void *dm_void) struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; u8 pg_lna[2] = {0}, i, pg_lna_tmp = 0; - u32 rf_reg; u32 lna_trim_addr[2] = {0x1884, 0x4184}; odm_efuse_one_byte_read(dm, PPG_LNA_2GA_97G, &pg_lna_tmp, false); @@ -2433,6 +2563,735 @@ void phydm_get_set_pa_bias_offset_8710c(void *dm_void) } } +void phydm_set_power_trim_offset_8814b(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + u8 e_rf_path; + + for (e_rf_path = RF_PATH_A; e_rf_path < MAX_PATH_NUM_8814B; e_rf_path++) + { + if (power_trim_info->flag & KFREE_FLAG_ON) { + odm_set_rf_reg(dm, e_rf_path, RF_0xee, BIT(19), 1); + + if (power_trim_info->flag & KFREE_FLAG_ON_2G) { + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x0); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[0][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x1); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[0][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x2); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[0][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x3); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[0][e_rf_path]); + } + + if (power_trim_info->flag & KFREE_FLAG_ON_5G) { + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x4); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[3][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x5); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[4][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x6); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[5][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x7); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[6][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x8); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[7][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0x9); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[3][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0xa); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[4][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0xb); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[5][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0xc); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[6][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0xd); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[7][e_rf_path]); + odm_set_rf_reg(dm, e_rf_path, RF_0x33, RFREGOFFSETMASK, 0xe); + odm_set_rf_reg(dm, e_rf_path, RF_0x30, RFREGOFFSETMASK, + power_trim_info->bb_gain[7][e_rf_path]); + } + + odm_set_rf_reg(dm, e_rf_path, RF_0xee, BIT(19), 0); + } + } +} + +void phydm_get_set_power_trim_offset_8814b(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u8 i, j; + u8 pg_power1, pg_power2; + u8 pg_power_2g[2] = {0}, pg_power_5g[20] = {0}; + + odm_efuse_one_byte_read(dm, PPG_2GL_TXAB_14B, &pg_power_2g[0], false); + odm_efuse_one_byte_read(dm, PPG_2GL_TXCD_14B, &pg_power_2g[1], false); + + j = 0; + for (i = 0; i < 2; i++) { + if (pg_power_2g[i] == 0xff) + j++; + } + + if (j == 2) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 2G power trim no PG\n"); + } else { + power_trim_info->bb_gain[0][RF_PATH_A] = pg_power_2g[0] & 0xf; + power_trim_info->bb_gain[0][RF_PATH_B] = (pg_power_2g[0] & 0xf0) >> 4; + + power_trim_info->bb_gain[0][RF_PATH_C] = pg_power_2g[1] & 0xf; + power_trim_info->bb_gain[0][RF_PATH_D] = (pg_power_2g[1] & 0xf0) >> 4; + + power_trim_info->flag = + power_trim_info->flag | KFREE_FLAG_ON | KFREE_FLAG_ON_2G; + } + + odm_efuse_one_byte_read(dm, PPG_5GL1_TXA_14B, &pg_power_5g[0], false); + odm_efuse_one_byte_read(dm, PPG_5GL1_TXB_14B, &pg_power_5g[1], false); + odm_efuse_one_byte_read(dm, PPG_5GL1_TXC_14B, &pg_power_5g[2], false); + odm_efuse_one_byte_read(dm, PPG_5GL1_TXD_14B, &pg_power_5g[3], false); + odm_efuse_one_byte_read(dm, PPG_5GL2_TXA_14B, &pg_power_5g[4], false); + odm_efuse_one_byte_read(dm, PPG_5GL2_TXB_14B, &pg_power_5g[5], false); + odm_efuse_one_byte_read(dm, PPG_5GL2_TXC_14B, &pg_power_5g[6], false); + odm_efuse_one_byte_read(dm, PPG_5GL2_TXD_14B, &pg_power_5g[7], false); + odm_efuse_one_byte_read(dm, PPG_5GM1_TXA_14B, &pg_power_5g[8], false); + odm_efuse_one_byte_read(dm, PPG_5GM1_TXB_14B, &pg_power_5g[9], false); + odm_efuse_one_byte_read(dm, PPG_5GM1_TXC_14B, &pg_power_5g[10], false); + odm_efuse_one_byte_read(dm, PPG_5GM1_TXD_14B, &pg_power_5g[11], false); + odm_efuse_one_byte_read(dm, PPG_5GM2_TXA_14B, &pg_power_5g[12], false); + odm_efuse_one_byte_read(dm, PPG_5GM2_TXB_14B, &pg_power_5g[13], false); + odm_efuse_one_byte_read(dm, PPG_5GM2_TXC_14B, &pg_power_5g[14], false); + odm_efuse_one_byte_read(dm, PPG_5GM2_TXD_14B, &pg_power_5g[15], false); + odm_efuse_one_byte_read(dm, PPG_5GH1_TXA_14B, &pg_power_5g[16], false); + odm_efuse_one_byte_read(dm, PPG_5GH1_TXB_14B, &pg_power_5g[17], false); + odm_efuse_one_byte_read(dm, PPG_5GH1_TXC_14B, &pg_power_5g[18], false); + odm_efuse_one_byte_read(dm, PPG_5GH1_TXD_14B, &pg_power_5g[19], false); + + j = 0; + for (i = 0; i < 20; i++) { + if (pg_power_5g[i] == 0xff) + j++; + } + + if (j == 20) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 5G power trim no PG\n"); + } else { + power_trim_info->bb_gain[3][RF_PATH_A] = pg_power_5g[0] & 0x1f; + power_trim_info->bb_gain[3][RF_PATH_B] = pg_power_5g[1] & 0x1f; + power_trim_info->bb_gain[3][RF_PATH_C] = pg_power_5g[2] & 0x1f; + power_trim_info->bb_gain[3][RF_PATH_D] = pg_power_5g[3] & 0x1f; + + power_trim_info->bb_gain[4][RF_PATH_A] = pg_power_5g[4] & 0x1f; + power_trim_info->bb_gain[4][RF_PATH_B] = pg_power_5g[5] & 0x1f; + power_trim_info->bb_gain[4][RF_PATH_C] = pg_power_5g[6] & 0x1f; + power_trim_info->bb_gain[4][RF_PATH_D] = pg_power_5g[7] & 0x1f; + + power_trim_info->bb_gain[5][RF_PATH_A] = pg_power_5g[8] & 0x1f; + power_trim_info->bb_gain[5][RF_PATH_B] = pg_power_5g[9] & 0x1f; + power_trim_info->bb_gain[5][RF_PATH_C] = pg_power_5g[10] & 0x1f; + power_trim_info->bb_gain[5][RF_PATH_D] = pg_power_5g[11] & 0x1f; + + power_trim_info->bb_gain[6][RF_PATH_A] = pg_power_5g[12] & 0x1f; + power_trim_info->bb_gain[6][RF_PATH_B] = pg_power_5g[13] & 0x1f; + power_trim_info->bb_gain[6][RF_PATH_C] = pg_power_5g[14] & 0x1f; + power_trim_info->bb_gain[6][RF_PATH_D] = pg_power_5g[15] & 0x1f; + + power_trim_info->bb_gain[7][RF_PATH_A] = pg_power_5g[16] & 0x1f; + power_trim_info->bb_gain[7][RF_PATH_B] = pg_power_5g[17] & 0x1f; + power_trim_info->bb_gain[7][RF_PATH_C] = pg_power_5g[18] & 0x1f; + power_trim_info->bb_gain[7][RF_PATH_D] = pg_power_5g[19] & 0x1f; + + power_trim_info->flag = + power_trim_info->flag | KFREE_FLAG_ON | KFREE_FLAG_ON_5G; + + } + + phydm_set_power_trim_offset_8814b(dm); + + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b power trim flag:0x%02x\n", + power_trim_info->flag); + + if (power_trim_info->flag & KFREE_FLAG_ON) { + for (i = 0; i < KFREE_BAND_NUM; i++) { + for (j = 0; j < MAX_PATH_NUM_8814B; j++) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b pwr_trim->bb_gain[%d][%d]=0x%X\n", + i, j, power_trim_info->bb_gain[i][j]); + } + } + } +} + +void phydm_get_tssi_trim_offset_8814b(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u8 i, j; + u8 tssi_trim_2g[8] = {0}, tssi_trim_5g[24] = {0}; + + odm_efuse_one_byte_read(dm, TSSI_2GM_TXA_14B, &tssi_trim_2g[0], false); + odm_efuse_one_byte_read(dm, TSSI_2GM_TXB_14B, &tssi_trim_2g[1], false); + odm_efuse_one_byte_read(dm, TSSI_2GM_TXC_14B, &tssi_trim_2g[2], false); + odm_efuse_one_byte_read(dm, TSSI_2GM_TXD_14B, &tssi_trim_2g[3], false); + odm_efuse_one_byte_read(dm, TSSI_2GH_TXA_14B, &tssi_trim_2g[4], false); + odm_efuse_one_byte_read(dm, TSSI_2GH_TXB_14B, &tssi_trim_2g[5], false); + odm_efuse_one_byte_read(dm, TSSI_2GH_TXC_14B, &tssi_trim_2g[6], false); + odm_efuse_one_byte_read(dm, TSSI_2GH_TXD_14B, &tssi_trim_2g[7], false); + + j = 0; + for (i = 0; i < 8; i++) { + if (tssi_trim_2g[i] == 0xff) + j++; + } + + if (j == 8) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 2g tssi trim no PG\n"); + } else { + power_trim_info->tssi_trim[0][RF_PATH_A] = (s8)tssi_trim_2g[0]; + power_trim_info->tssi_trim[0][RF_PATH_B] = (s8)tssi_trim_2g[1]; + power_trim_info->tssi_trim[0][RF_PATH_C] = (s8)tssi_trim_2g[2]; + power_trim_info->tssi_trim[0][RF_PATH_D] = (s8)tssi_trim_2g[3]; + power_trim_info->tssi_trim[1][RF_PATH_A] = (s8)tssi_trim_2g[0]; + power_trim_info->tssi_trim[1][RF_PATH_B] = (s8)tssi_trim_2g[1]; + power_trim_info->tssi_trim[1][RF_PATH_C] = (s8)tssi_trim_2g[2]; + power_trim_info->tssi_trim[1][RF_PATH_D] = (s8)tssi_trim_2g[3]; + power_trim_info->tssi_trim[2][RF_PATH_A] = (s8)tssi_trim_2g[4]; + power_trim_info->tssi_trim[2][RF_PATH_B] = (s8)tssi_trim_2g[5]; + power_trim_info->tssi_trim[2][RF_PATH_C] = (s8)tssi_trim_2g[6]; + power_trim_info->tssi_trim[2][RF_PATH_D] = (s8)tssi_trim_2g[7]; + + power_trim_info->flag = + power_trim_info->flag | TSSI_TRIM_FLAG_ON | KFREE_FLAG_ON_2G; + + for (i = 0; i < KFREE_BAND_NUM; i++) { + for (j = 0; j < MAX_PATH_NUM_8814B; j++) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2g tssi_trim[%d][%d]=0x%X\n", + i, j, power_trim_info->tssi_trim[i][j]); + } + } + } + + odm_efuse_one_byte_read(dm, TSSI_5GL1_TXA_14B, &tssi_trim_5g[0], false); + odm_efuse_one_byte_read(dm, TSSI_5GL1_TXB_14B, &tssi_trim_5g[1], false); + odm_efuse_one_byte_read(dm, TSSI_5GL1_TXC_14B, &tssi_trim_5g[2], false); + odm_efuse_one_byte_read(dm, TSSI_5GL1_TXD_14B, &tssi_trim_5g[3], false); + odm_efuse_one_byte_read(dm, TSSI_5GL2_TXA_14B, &tssi_trim_5g[4], false); + odm_efuse_one_byte_read(dm, TSSI_5GL2_TXB_14B, &tssi_trim_5g[5], false); + odm_efuse_one_byte_read(dm, TSSI_5GL2_TXC_14B, &tssi_trim_5g[6], false); + odm_efuse_one_byte_read(dm, TSSI_5GL2_TXD_14B, &tssi_trim_5g[7], false); + odm_efuse_one_byte_read(dm, TSSI_5GM1_TXA_14B, &tssi_trim_5g[8], false); + odm_efuse_one_byte_read(dm, TSSI_5GM1_TXB_14B, &tssi_trim_5g[9], false); + odm_efuse_one_byte_read(dm, TSSI_5GM1_TXC_14B, &tssi_trim_5g[10], false); + odm_efuse_one_byte_read(dm, TSSI_5GM1_TXD_14B, &tssi_trim_5g[11], false); + odm_efuse_one_byte_read(dm, TSSI_5GM2_TXA_14B, &tssi_trim_5g[12], false); + odm_efuse_one_byte_read(dm, TSSI_5GM2_TXB_14B, &tssi_trim_5g[13], false); + odm_efuse_one_byte_read(dm, TSSI_5GM2_TXC_14B, &tssi_trim_5g[14], false); + odm_efuse_one_byte_read(dm, TSSI_5GM2_TXD_14B, &tssi_trim_5g[15], false); + odm_efuse_one_byte_read(dm, TSSI_5GH1_TXA_14B, &tssi_trim_5g[16], false); + odm_efuse_one_byte_read(dm, TSSI_5GH1_TXB_14B, &tssi_trim_5g[17], false); + odm_efuse_one_byte_read(dm, TSSI_5GH1_TXC_14B, &tssi_trim_5g[18], false); + odm_efuse_one_byte_read(dm, TSSI_5GH1_TXD_14B, &tssi_trim_5g[19], false); + odm_efuse_one_byte_read(dm, TSSI_5GH2_TXA_14B, &tssi_trim_5g[20], false); + odm_efuse_one_byte_read(dm, TSSI_5GH2_TXB_14B, &tssi_trim_5g[21], false); + odm_efuse_one_byte_read(dm, TSSI_5GH2_TXC_14B, &tssi_trim_5g[22], false); + odm_efuse_one_byte_read(dm, TSSI_5GH2_TXD_14B, &tssi_trim_5g[23], false); + + j = 0; + for (i = 0; i < 24; i++) { + if (tssi_trim_5g[i] == 0xff) + j++; + } + + if (j == 24) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 5g tssi trim no PG\n"); + } else { + power_trim_info->tssi_trim[3][RF_PATH_A] = (s8)tssi_trim_5g[0]; + power_trim_info->tssi_trim[3][RF_PATH_B] = (s8)tssi_trim_5g[1]; + power_trim_info->tssi_trim[3][RF_PATH_C] = (s8)tssi_trim_5g[2]; + power_trim_info->tssi_trim[3][RF_PATH_D] = (s8)tssi_trim_5g[3]; + power_trim_info->tssi_trim[4][RF_PATH_A] = (s8)tssi_trim_5g[4]; + power_trim_info->tssi_trim[4][RF_PATH_B] = (s8)tssi_trim_5g[5]; + power_trim_info->tssi_trim[4][RF_PATH_C] = (s8)tssi_trim_5g[6]; + power_trim_info->tssi_trim[4][RF_PATH_D] = (s8)tssi_trim_5g[7]; + power_trim_info->tssi_trim[5][RF_PATH_A] = (s8)tssi_trim_5g[8]; + power_trim_info->tssi_trim[5][RF_PATH_B] = (s8)tssi_trim_5g[9]; + power_trim_info->tssi_trim[5][RF_PATH_C] = (s8)tssi_trim_5g[10]; + power_trim_info->tssi_trim[5][RF_PATH_D] = (s8)tssi_trim_5g[11]; + power_trim_info->tssi_trim[6][RF_PATH_A] = (s8)tssi_trim_5g[12]; + power_trim_info->tssi_trim[6][RF_PATH_B] = (s8)tssi_trim_5g[13]; + power_trim_info->tssi_trim[6][RF_PATH_C] = (s8)tssi_trim_5g[14]; + power_trim_info->tssi_trim[6][RF_PATH_D] = (s8)tssi_trim_5g[15]; + power_trim_info->tssi_trim[7][RF_PATH_A] = (s8)tssi_trim_5g[16]; + power_trim_info->tssi_trim[7][RF_PATH_B] = (s8)tssi_trim_5g[17]; + power_trim_info->tssi_trim[7][RF_PATH_C] = (s8)tssi_trim_5g[18]; + power_trim_info->tssi_trim[7][RF_PATH_D] = (s8)tssi_trim_5g[19]; + power_trim_info->tssi_trim[8][RF_PATH_A] = (s8)tssi_trim_5g[20]; + power_trim_info->tssi_trim[8][RF_PATH_B] = (s8)tssi_trim_5g[21]; + power_trim_info->tssi_trim[8][RF_PATH_C] = (s8)tssi_trim_5g[22]; + power_trim_info->tssi_trim[8][RF_PATH_D] = (s8)tssi_trim_5g[23]; + + power_trim_info->flag = + power_trim_info->flag | TSSI_TRIM_FLAG_ON | KFREE_FLAG_ON_5G; + + for (i = 0; i < KFREE_BAND_NUM; i++) { + for (j = 0; j < MAX_PATH_NUM_8814B; j++) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 5g tssi_trim[%d][%d]=0x%X\n", + i, j, power_trim_info->tssi_trim[i][j]); + } + } + } +} + +s8 phydm_get_tssi_trim_de_8814b(void *dm_void, u8 path) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u8 channel = *dm->channel, group = 0; + + if (channel >= 1 && channel <= 3) + group = 0; + else if (channel >= 4 && channel <= 9) + group = 1; + else if (channel >= 10 && channel <= 14) + group = 2; + else if (channel >= 36 && channel <= 50) + group = 3; + else if (channel >= 52 && channel <= 64) + group = 4; + else if (channel >= 100 && channel <= 118) + group = 5; + else if (channel >= 120 && channel <= 144) + group = 6; + else if (channel >= 149 && channel <= 165) + group = 7; + else if (channel >= 167 && channel <= 177) + group = 8; + else { + RF_DBG(dm, DBG_RF_MP, "[kfree] Channel(%d) is not exist in Group\n", + channel); + return 0; + } + + return power_trim_info->tssi_trim[group][path]; +} + +void phydm_set_pabias_bandedge_2g_rf_8814b(void *dm_void) +{ +#if 0 + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u32 rf_reg_51 = 0, rf_reg_52 = 0, rf_reg_53 = 0, rf_reg_3f = 0; + u8 i, j; + s32 pa_bias_tmp, bandedge_tmp, reg_tmp; + +#if 0 + /*2.4G bias*/ + /*rf3f == rf53*/ +#endif + for (i = 0; i < MAX_PATH_NUM_8814B; i++) { + rf_reg_51 = odm_get_rf_reg(dm, i, RF_0x51, RFREGOFFSETMASK); + rf_reg_52 = odm_get_rf_reg(dm, i, RF_0x52, RFREGOFFSETMASK); + rf_reg_53 = odm_get_rf_reg(dm, i, RF_0x53, RFREGOFFSETMASK); + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2g rf(0x51)=0x%X rf(0x52)=0x%X rf(0x53)=0x%X path=%d\n", + rf_reg_51, rf_reg_52, rf_reg_53, i); + + /*2.4G bias*/ + rf_reg_3f = rf_reg_53; + pa_bias_tmp = rf_reg_3f & 0xf; + + reg_tmp = pa_bias_tmp + power_trim_info->pa_bias_trim[0][i]; + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2g pa bias reg_tmp(%d) = pa_bias_tmp(%d) + power_trim_info->pa_bias_trim[0][%d](%d)\n", + reg_tmp, pa_bias_tmp, i, power_trim_info->pa_bias_trim[0][i]); + +#if 0 + if (reg_tmp < 0) { + reg_tmp = 0; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 2g pa bias reg_tmp < 0. Set 0 path=%d\n", i); + } else if (reg_tmp > 7) { + reg_tmp = 7; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 2g pa bias reg_tmp > 7. Set 7 path=%d\n", i); + } +#endif + + rf_reg_3f = ((rf_reg_3f & 0xffff0) | reg_tmp); + rf_reg_3f = ((rf_reg_3f & 0x0ffff) | 0x10000); + + odm_set_rf_reg(dm, i, RF_0xef, BIT(10), 0x1); + for (j = 0; j <= 0xf; j++) { + odm_set_rf_reg(dm, i, RF_0x30, RFREGOFFSETMASK, (j << 16)); + odm_set_rf_reg(dm, i, RF_0x3f, RFREGOFFSETMASK, rf_reg_3f); + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2G pa bias write RF_0x30=0x%05x RF_0x3f=0x%x path=%d\n", + (j << 16), rf_reg_3f, i); + } + odm_set_rf_reg(dm, i, RF_0xef, BIT(10), 0x0); + +#if 0 + /*2.4G bandedge*/ + /*rf3f =>*/ + /*rf51[3:1] = rf3f[17:15]*/ + /*rf52[2:0] = rf3f[14:12]*/ + /*rf52[18] = rf3f[11]*/ + /*rf51[6:4] = rf3f[10:8]*/ + /*rf51[11:8] = rf3f[7:4]*/ + /*rf51[16:13] = rf3f[3:0]*/ +#endif + /*2.4G bandedge*/ + rf_reg_3f = (((rf_reg_51 & 0xe) >> 1) << 15) | + ((rf_reg_52 & 0x7) << 12) | + (((rf_reg_52 & 0x40000) >> 18) << 11) | + (((rf_reg_51 & 0x70) >> 4) << 8) | + (((rf_reg_51 & 0xf00) >> 8) << 4) | + ((rf_reg_51 & 0x1e000) >> 13); + + bandedge_tmp = rf_reg_3f & 0xf; + + reg_tmp = bandedge_tmp + power_trim_info->pa_bias_trim[0][i]; + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2g bandedge reg_tmp(%d) = bandedge_tmp(%d) + power_trim_info->pa_bias_trim[0][%d](%d)\n", + reg_tmp, bandedge_tmp, i, power_trim_info->pa_bias_trim[0][i]); + +#if 0 + if (reg_tmp < 0) { + reg_tmp = 0; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 2g bandedge reg_tmp < 0. Set 0 path=%d\n", i); + } else if (reg_tmp > 7) { + reg_tmp = 7; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 2g bandedge reg_tmp > 7. Set 7 path=%d\n", i); + } +#endif + + rf_reg_3f = ((rf_reg_3f & 0xffff0) | reg_tmp); + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2G bandedge RF_0x30=0x%05X RF_0x3f=0x%x path=%d\n", + 0x00001, rf_reg_3f, i); + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2G bandedge RF_0x30=0x%05X RF_0x3f=0x%x path=%d\n", + 0x0000b, rf_reg_3f, i); + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2G bandedge RF_0x30=0x%05X RF_0x3f=0x%x path=%d\n", + 0x00023, rf_reg_3f, i); + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2G bandedge RF_0x30=0x%05X RF_0x3f=0x%x path=%d\n", + 0x00029, rf_reg_3f, i); + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 2G bandedge RF_0x30=0x%05X RF_0x3f=0x%x path=%d\n", + 0x0002a, rf_reg_3f, i); + + odm_set_rf_reg(dm, i, RF_0xef, BIT(8), 0x1); + odm_set_rf_reg(dm, i, RF_0x33, RFREGOFFSETMASK, 0x00001); + odm_set_rf_reg(dm, i, RF_0x3f, RFREGOFFSETMASK, rf_reg_3f); + odm_set_rf_reg(dm, i, RF_0x33, RFREGOFFSETMASK, 0x0000b); + odm_set_rf_reg(dm, i, RF_0x3f, RFREGOFFSETMASK, rf_reg_3f); + odm_set_rf_reg(dm, i, RF_0x33, RFREGOFFSETMASK, 0x00023); + odm_set_rf_reg(dm, i, RF_0x3f, RFREGOFFSETMASK, rf_reg_3f); + odm_set_rf_reg(dm, i, RF_0x33, RFREGOFFSETMASK, 0x00029); + odm_set_rf_reg(dm, i, RF_0x3f, RFREGOFFSETMASK, rf_reg_3f); + odm_set_rf_reg(dm, i, RF_0x33, RFREGOFFSETMASK, 0x0002a); + odm_set_rf_reg(dm, i, RF_0x3f, RFREGOFFSETMASK, rf_reg_3f); + odm_set_rf_reg(dm, i, RF_0xef, BIT(8), 0x0); + + } +#endif +} + +void phydm_set_pabias_bandedge_5g_rf_8814b(void *dm_void) +{ +#if 0 + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u32 rf_reg_18[MAX_PATH_NUM_8814B] = {0}, + rf_reg_61[15][MAX_PATH_NUM_8814B] = {0}, + rf_reg_62[3][MAX_PATH_NUM_8814B] = {0}; + u8 i, j; + u32 bandedge[15][MAX_PATH_NUM_8814B] = {0}, + pa_bias[3][MAX_PATH_NUM_8814B] = {0}; + + s32 pa_bias_tmp, reg_tmp; + + + for (i = 0; i < MAX_PATH_NUM_8814B; i++) { + rf_reg_18[i] = odm_get_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK); + + for (j = 0; j < 3; j++) { + if (j == 0) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x10d24); + else if (j == 1) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x30d64); + else if (j == 2) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x50da9); + + rf_reg_62[j][i] = odm_get_rf_reg(dm, i, 0x62, RFREGOFFSETMASK); + +#if 0 + /*5G bias*/ + /*rf62[19:16] == rf30[11:8]*/ + /*rf62[15:12] == rf30[7:4]*/ + /*rf62[11:8] == rf3030[3:0]*/ +#endif + pa_bias[j][i] = (((rf_reg_62[j][i] & 0xf0000) >> 16) << 8) | + (((rf_reg_62[j][i] & 0xf000) >> 12) << 4) | + ((rf_reg_62[j][i] & 0xf00) >> 8); + } + + for (j = 0; j < 15; j++) { + if (j == 0) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x10d24);/*ch36*/ + else if (j == 1) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x11926);/*ch38*/ + else if (j == 2) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x1252a);/*ch42*/ + else if (j == 3) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x1253a);/*ch58*/ + else if (j == 4) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x1193e);/*ch62*/ + else if (j == 5) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x10d40);/*ch64*/ + else if (j == 6) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x30d64);/*ch100*/ + else if (j == 7) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x31966);/*ch102*/ + else if (j == 8) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x3256a);/*ch106*/ + else if (j == 9) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x3257a);/*ch122*/ + else if (j == 10) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x31986);/*ch134*/ + else if (j == 11) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x30d8c);/*ch140*/ + else if (j == 12) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x50d95);/*ch149*/ + else if (j == 13) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x51997);/*ch151*/ + else if (j == 14) + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, 0x5259b);/*ch155*/ + + + rf_reg_61[j][i] = odm_get_rf_reg(dm, i, RF_0x61, RFREGOFFSETMASK); +#if 0 + /*5G bandedge*/ + /*rf61[11:8] == rf30[11:8]*/ + /*rf61[7:4] == rf30[7:4]*/ + /*rf61[3:0] == rf3030[3:0]*/ +#endif + bandedge[j][i] = rf_reg_61[j][i] & 0xfff; + } + + odm_set_rf_reg(dm, i, RF_0x18, RFREGOFFSETMASK, rf_reg_18[i]); + } + + for (i = 0; i < MAX_PATH_NUM_8814B; i++) { + for (j = 0; j < 3; j++) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] pa_bias[%d][%d]=0x%x\n", j, i, pa_bias[j][i]); + } + } + + for (i = 0; i < MAX_PATH_NUM_8814B; i++) { + for (j = 0; j < 15; j++) { + RF_DBG(dm, DBG_RF_MP, + "[kfree] bandedge[%d][%d]=0x%x\n", j, i, bandedge[j][i]); + } + } + + /*5G bias*/ + for (i = 0; i < MAX_PATH_NUM_8814B; i++) { + odm_set_rf_reg(dm, i, RF_0xee, BIT(8), 0x1); + for (j = 0; j <= 0xb; j++) { + + if (j >= 0 && j <= 3) + pa_bias_tmp = pa_bias[0][i] & 0xf; + else if (j >= 4 && j <= 0x7) + pa_bias_tmp = pa_bias[1][i] & 0xf; + else if (j >= 0x8 && j <= 0xb) + pa_bias_tmp = pa_bias[2][i] & 0xf; + + reg_tmp = pa_bias_tmp + power_trim_info->pa_bias_trim[1][i]; + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 5g pa bias reg_tmp(%d) = pa_bias_tmp(%d) + power_trim_info->pa_bias_trim[1][%d](%d)\n", + reg_tmp, pa_bias_tmp, i, power_trim_info->pa_bias_trim[1][i]); +#if 0 + if (reg_tmp < 0) { + reg_tmp = 0; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 5g pa bias reg_tmp < 0. Set 0 path=%d\n", i); + } else if (reg_tmp > 7) { + reg_tmp = 7; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 5g pa bias reg_tmp > 7. Set 7 path=%d\n", i); + } +#endif + if (j >= 0 && j <= 3) + reg_tmp = ((pa_bias[0][i] & 0xffff0) | reg_tmp | (j << 12)); + else if (j >= 4 && j <= 0x7) + reg_tmp = ((pa_bias[1][i] & 0xffff0) | reg_tmp | (j << 12)); + else if (j >= 0x8 && j <= 0xb) + reg_tmp = ((pa_bias[2][i] & 0xffff0) | reg_tmp | (j << 12)); + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b write RF_0x30=0x%05x path=%d\n", + reg_tmp, i); + + odm_set_rf_reg(dm, i, RF_0x30, RFREGOFFSETMASK, reg_tmp); + } + odm_set_rf_reg(dm, i, RF_0xee, BIT(8), 0x0); + } + + /*5G bandedge*/ + for (i = 0; i < MAX_PATH_NUM_8814B; i++) { + odm_set_rf_reg(dm, i, RF_0xee, BIT(9), 0x1); + for (j = 0; j <= 0xe; j++) { + reg_tmp = bandedge[j][i] + power_trim_info->pa_bias_trim[1][i]; + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b 5g bandedge reg_tmp(%d)(0x%X) = bandedge_org(%d) + power_trim_info->pa_bias_trim[1][%d](%d)\n", + reg_tmp, reg_tmp, bandedge[j][i], i, power_trim_info->pa_bias_trim[1][i]); +#if 0 + if (reg_tmp < 0) { + reg_tmp = 0; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 5g bandedge reg_tmp < 0. Set 0 path=%d\n", i); + } else if (reg_tmp > 7) { + reg_tmp = 7; + RF_DBG(dm, DBG_RF_MP, + "[kfree] 5g bandedge reg_tmp > 7. Set 7 path=%d\n", i); + } +#endif + + reg_tmp = ((bandedge[j][i] & 0xffff0) | reg_tmp | (j << 12)); + + RF_DBG(dm, DBG_RF_MP, + "[kfree] 8814b write RF_0x30=0x%05x path=%d\n", + reg_tmp, i); + + odm_set_rf_reg(dm, i, RF_0x30, RFREGOFFSETMASK, reg_tmp); + } + odm_set_rf_reg(dm, i, RF_0xee, BIT(9), 0x0); + } + +#endif +} + + +void phydm_get_pa_bias_offset_8814b(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct odm_power_trim_data *power_trim_info = &dm->power_trim_data; + + u8 i, j, k; + u8 tssi_pa_bias_2g[2] = {0}, tssi_pa_bias_5g[2] = {0}; + + odm_efuse_one_byte_read(dm, PPG_PABIAS_2GAC_14B, &tssi_pa_bias_2g[0], false); + odm_efuse_one_byte_read(dm, PPG_PABIAS_2GBD_14B, &tssi_pa_bias_2g[1], false); + + j = 0; + for (i = 0; i < 2; i++) { + if (tssi_pa_bias_2g[i] == 0xff) + j++; + } + + if (j == 2) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 2g PA Bias K no PG\n"); + } else { + power_trim_info->pa_bias_trim[0][RF_PATH_A] = tssi_pa_bias_2g[0] & 0xf; + power_trim_info->pa_bias_trim[0][RF_PATH_C] = (tssi_pa_bias_2g[0] & 0xf0) >> 4; + power_trim_info->pa_bias_trim[0][RF_PATH_B] = tssi_pa_bias_2g[1] & 0xf; + power_trim_info->pa_bias_trim[0][RF_PATH_D] = (tssi_pa_bias_2g[1] & 0xf0) >> 4; + + for (k = 0; k < MAX_PATH_NUM_8814B; k++) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 2g PA Bias K efuse:0x%x path=%d\n", + power_trim_info->pa_bias_trim[0][k], k); + odm_set_rf_reg(dm, k, 0x60, 0x0000f000, power_trim_info->pa_bias_trim[0][k]); + } + +#if 0 + for (k = 0; k < MAX_PATH_NUM_8814B; k++) { + if ((power_trim_info->pa_bias_trim[0][k] & BIT(0)) == 0) + power_trim_info->pa_bias_trim[0][k] = (-1 * (power_trim_info->pa_bias_trim[0][k] >> 1)); + else + power_trim_info->pa_bias_trim[0][k] = (power_trim_info->pa_bias_trim[0][k] >> 1); + + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 2g PA Bias K power_trim_info->pa_bias_trim[0][%d]=0x%x\n", + k, power_trim_info->pa_bias_trim[0][k]); + } + + phydm_set_pabias_bandedge_2g_rf_8814b(dm); +#endif + } + + odm_efuse_one_byte_read(dm, PPG_PABIAS_5GAC_14B, &tssi_pa_bias_5g[0], false); + odm_efuse_one_byte_read(dm, PPG_PABIAS_5GBD_14B, &tssi_pa_bias_5g[1], false); + + j = 0; + for (i = 0; i < 2; i++) { + if (tssi_pa_bias_5g[i] == 0xff) + j++; + } + + if (j == 2) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 5g PA Bias K no PG\n"); + } else { + power_trim_info->pa_bias_trim[1][RF_PATH_A] = tssi_pa_bias_5g[0] & 0xf; + power_trim_info->pa_bias_trim[1][RF_PATH_C] = (tssi_pa_bias_5g[0] & 0xf0) >> 4; + power_trim_info->pa_bias_trim[1][RF_PATH_B] = tssi_pa_bias_5g[1] & 0xf; + power_trim_info->pa_bias_trim[1][RF_PATH_D] = (tssi_pa_bias_5g[1] & 0xf0) >> 4; + + for (k = 0; k < MAX_PATH_NUM_8814B; k++) { + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 5g PA Bias K efuse:0x%x path=%d\n", + power_trim_info->pa_bias_trim[1][k], k); + + odm_set_rf_reg(dm, k, 0x60, 0x000f0000, power_trim_info->pa_bias_trim[1][k]); + } +#if 0 + for (k = 0; k < MAX_PATH_NUM_8814B; k++) { + if ((power_trim_info->pa_bias_trim[1][k] & BIT(0)) == 0) + power_trim_info->pa_bias_trim[1][k] = (-1 * (power_trim_info->pa_bias_trim[1][k] >> 1)); + else + power_trim_info->pa_bias_trim[1][k] = (power_trim_info->pa_bias_trim[1][k] >> 1); + + RF_DBG(dm, DBG_RF_MP, "[kfree] 8814b 5g PA Bias K power_trim_info->pa_bias_trim[1][%d]=0x%x\n", + k, power_trim_info->pa_bias_trim[1][k]); + } + + phydm_set_pabias_bandedge_5g_rf_8814b(dm); +#endif + } + + +} + void phydm_get_thermal_trim_offset_8814b(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2443,7 +3302,7 @@ void phydm_get_thermal_trim_offset_8814b(void *dm_void) odm_efuse_one_byte_read(dm, PPG_THERMAL_A_OFFSET_14B, &pg_therm, false); if (pg_therm != 0xff) { - for (i = 0; i < MAX_RF_PATH; i++) { + for (i = 0; i < MAX_PATH_NUM_8814B; i++) { if (i == 0) odm_efuse_one_byte_read(dm, PPG_THERMAL_A_OFFSET_14B, &pg_therm, false); else if (i == 1) @@ -2482,6 +3341,10 @@ s8 phydm_get_tssi_trim_de(void *dm_void, u8 path) return phydm_get_tssi_trim_de_8822c(dm, path); else if (dm->support_ic_type & ODM_RTL8812F) return phydm_get_tssi_trim_de_8812f(dm, path); + else if (dm->support_ic_type & ODM_RTL8197G) + return phydm_get_tssi_trim_de_8197g(dm, path); + else if (dm->support_ic_type & ODM_RTL8814B) + return phydm_get_tssi_trim_de_8814b(dm, path); else return 0; } @@ -2516,14 +3379,16 @@ void phydm_do_new_kfree(void *dm_void) /*phydm_get_set_pa_bias_offset_8721d(dm);*/ } - if (dm->support_ic_type & ODM_RTL8198F) + if (dm->support_ic_type & ODM_RTL8198F) { + phydm_get_pa_bias_offset_8198f(dm); phydm_get_set_lna_offset_8198f(dm); + } if (dm->support_ic_type & ODM_RTL8197G) { phydm_get_thermal_trim_offset_8197g(dm); phydm_get_set_power_trim_offset_8197g(dm); phydm_get_set_pa_bias_offset_8197g(dm); - /*phydm_get_tssi_trim_offset_8197g(dm);*/ + phydm_get_tssi_trim_offset_8197g(dm); phydm_get_set_lna_offset_8197g(dm); } @@ -2535,8 +3400,9 @@ void phydm_do_new_kfree(void *dm_void) if (dm->support_ic_type & ODM_RTL8814B) { phydm_get_thermal_trim_offset_8814b(dm); - /*phydm_get_set_power_trim_offset_8814b(dm);*/ - /*phydm_get_set_pa_bias_offset_8814b(dm);*/ + phydm_get_set_power_trim_offset_8814b(dm); + phydm_get_pa_bias_offset_8814b(dm); + phydm_get_tssi_trim_offset_8814b(dm); } } @@ -2645,9 +3511,6 @@ void phydm_get_pa_bias_offset(void *dm_void) if (dm->support_ic_type & ODM_RTL8822B) phydm_get_pa_bias_offset_8822b(dm_void); - - if (dm->support_ic_type & ODM_RTL8198F) - phydm_get_pa_bias_offset_8198f(dm); } s8 phydm_get_thermal_offset(void *dm_void) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_kfree.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_kfree.h index 76a496a367a6..153dcff116a3 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_kfree.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_kfree.h @@ -165,10 +165,15 @@ #define PPG_5GH1_TXA_8721D 0x1E9 /*8197G*/ -#define PPG_THERMAL_OFFSET_97G 0x50 +#define PPG_THERMAL_A_OFFSET_97G 0x50 +#define PPG_THERMAL_B_OFFSET_97G 0x27 #define PPG_2GM_TXAB_97G 0x51 #define PPG_2GL_TXAB_97G 0x53 #define PPG_2GH_TXAB_97G 0x55 +#define TSSI_2GL_TXA_97G 0x1c +#define TSSI_2GL_TXB_97G 0x1d +#define TSSI_2GH_TXA_97G 0x1e +#define TSSI_2GH_TXB_97G 0x1f #define PPG_PABIAS_2GAB_97G 0x57 #define PPG_LNA_2GA_97G 0x21 #define PPG_LNA_2GB_97G 0x22 @@ -182,17 +187,79 @@ #define PPG_LNA_10C 0x1D0 /*8814B*/ +#define PPG_2GL_TXAB_14B 0x3ee +#define PPG_2GL_TXCD_14B 0x3ed +#define PPG_5GL1_TXA_14B 0x3ec +#define PPG_5GL1_TXB_14B 0x3eb +#define PPG_5GL1_TXC_14B 0x3ea +#define PPG_5GL1_TXD_14B 0x3e9 +#define PPG_5GL2_TXA_14B 0x3e8 +#define PPG_5GL2_TXB_14B 0x3e7 +#define PPG_5GL2_TXC_14B 0x3e6 +#define PPG_5GL2_TXD_14B 0x3e5 +#define PPG_5GM1_TXA_14B 0x3e4 +#define PPG_5GM1_TXB_14B 0x3e3 +#define PPG_5GM1_TXC_14B 0x3e2 +#define PPG_5GM1_TXD_14B 0x3e1 +#define PPG_5GM2_TXA_14B 0x3e0 +#define PPG_5GM2_TXB_14B 0x3df +#define PPG_5GM2_TXC_14B 0x3de +#define PPG_5GM2_TXD_14B 0x3dd +#define PPG_5GH1_TXA_14B 0x3dc +#define PPG_5GH1_TXB_14B 0x3db +#define PPG_5GH1_TXC_14B 0x3da +#define PPG_5GH1_TXD_14B 0x3d9 +#define PPG_PABIAS_5GAC_14B 0x3d8 +#define PPG_PABIAS_5GBD_14B 0x3d7 +#define PPG_PABIAS_2GAC_14B 0x3d6 +#define PPG_PABIAS_2GBD_14B 0x3d5 + #define PPG_THERMAL_A_OFFSET_14B 0x3D4 #define PPG_THERMAL_B_OFFSET_14B 0x3D3 #define PPG_THERMAL_C_OFFSET_14B 0x3D2 #define PPG_THERMAL_D_OFFSET_14B 0x3D1 +#define TSSI_2GM_TXA_14B 0x3c0 +#define TSSI_2GM_TXB_14B 0x3bf +#define TSSI_2GM_TXC_14B 0x3be +#define TSSI_2GM_TXD_14B 0x3bd +#define TSSI_2GH_TXA_14B 0x3bc +#define TSSI_2GH_TXB_14B 0x3bb +#define TSSI_2GH_TXC_14B 0x3ba +#define TSSI_2GH_TXD_14B 0x3b9 +#define TSSI_5GL1_TXA_14B 0x3b8 +#define TSSI_5GL1_TXB_14B 0x3b7 +#define TSSI_5GL1_TXC_14B 0x3b6 +#define TSSI_5GL1_TXD_14B 0x3b5 +#define TSSI_5GL2_TXA_14B 0x3b4 +#define TSSI_5GL2_TXB_14B 0x3b3 +#define TSSI_5GL2_TXC_14B 0x3b2 +#define TSSI_5GL2_TXD_14B 0x3b1 +#define TSSI_5GM1_TXA_14B 0x3b0 +#define TSSI_5GM1_TXB_14B 0x3af +#define TSSI_5GM1_TXC_14B 0x3ae +#define TSSI_5GM1_TXD_14B 0x3ad +#define TSSI_5GM2_TXA_14B 0x3ac +#define TSSI_5GM2_TXB_14B 0x3ab +#define TSSI_5GM2_TXC_14B 0x3aa +#define TSSI_5GM2_TXD_14B 0x3a9 +#define TSSI_5GH1_TXA_14B 0x3a8 +#define TSSI_5GH1_TXB_14B 0x3a7 +#define TSSI_5GH1_TXC_14B 0x3a6 +#define TSSI_5GH1_TXD_14B 0x3a5 +#define TSSI_5GH2_TXA_14B 0x3a4 +#define TSSI_5GH2_TXB_14B 0x3a3 +#define TSSI_5GH2_TXC_14B 0x3a2 +#define TSSI_5GH2_TXD_14B 0x3a1 + + struct odm_power_trim_data { u8 flag; u8 pa_bias_flag; u8 lna_flag; s8 bb_gain[KFREE_BAND_NUM][MAX_RF_PATH]; s8 tssi_trim[KFREE_BAND_NUM][MAX_RF_PATH]; + s8 pa_bias_trim[KFREE_BAND_NUM][MAX_RF_PATH]; s8 lna_trim[MAX_RF_PATH]; s8 thermal; s8 multi_thermal[MAX_RF_PATH]; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking.c index a46bc1bb05b2..bde6dd15765d 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking.c @@ -163,17 +163,19 @@ void halrf_set_pwr_track(void *dm_void, u8 enable) configure_txpower_track(dm, &c); if (enable) { rf->rf_supportability = rf->rf_supportability | HAL_RF_TX_PWR_TRACK; - if (cali_info->txpowertrack_control == 1 || cali_info->txpowertrack_control == 3) { - halrf_segment_iqk_trigger(dm, true, 0); - halrf_tssi_trigger(dm); - } + if (cali_info->txpowertrack_control == 1 || cali_info->txpowertrack_control == 3) + halrf_do_tssi(dm); } else { rf->rf_supportability = rf->rf_supportability & ~HAL_RF_TX_PWR_TRACK; odm_clear_txpowertracking_state(dm); halrf_do_tssi(dm); - + halrf_calculate_tssi_codeword(dm); + halrf_set_tssi_codeword(dm); + +#if !(RTL8723F_SUPPORT == 1) for (i = 0; i < c.rf_path_count; i++) (*c.odm_tx_pwr_track_set_pwr)(dm, CLEAN_MODE, i, 0); +#endif } if (cali_info->txpowertrack_control == 2 || diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ap.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ap.c index 689fd978569a..462b2f8b95f0 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ap.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ap.c @@ -928,7 +928,7 @@ odm_txpowertracking_init( { struct dm_struct *dm = (struct dm_struct *)dm_void; #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) - if (!(dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B | ODM_IC_11N_SERIES))) + if (!(dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8814B | ODM_IC_11N_SERIES))) return; #endif @@ -988,6 +988,24 @@ get_swing_index( return i; } +s8 +get_txagc_default_index( + void *dm_void +) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + s8 tmp; + +#if RTL8814B_SUPPORT + if (dm->support_ic_type == ODM_RTL8814B) { + tmp = (s8)(odm_get_bb_reg(dm, R_0x18a0, 0x7f) & 0xff); + if (tmp & BIT(6)) + tmp = tmp | 0x80; + return tmp; + } else + return 0; +#endif +} void odm_txpowertracking_thermal_meter_init( @@ -996,9 +1014,12 @@ odm_txpowertracking_thermal_meter_init( { struct dm_struct *dm = (struct dm_struct *)dm_void; struct dm_rf_calibration_struct *cali_info = &(dm->rf_calibrate_info); + struct _hal_rf_ *rf = &dm->rf_table; + struct _halrf_tssi_data *tssi = &rf->halrf_tssi_data; struct rtl8192cd_priv *priv = dm->priv; u8 p; u8 default_swing_index; + u8 i; #if (RTL8197F_SUPPORT == 1 || RTL8822B_SUPPORT == 1 || RTL8192F_SUPPORT == 1) if ((GET_CHIP_VER(priv) == VERSION_8197F) || (GET_CHIP_VER(priv) == VERSION_8822B) ||(GET_CHIP_VER(priv) == VERSION_8192F)) default_swing_index = get_swing_index(dm); @@ -1088,10 +1109,27 @@ odm_txpowertracking_thermal_meter_init( #if RTL8188E_SUPPORT - cali_info->default_cck_index = 20; /* -6 dB */ -#elif RTL8192E_SUPPORT - cali_info->default_cck_index = 8; /* -12 dB */ + if (GET_CHIP_VER(priv) == VERSION_8188E) { + cali_info->default_cck_index = 20; /* -6 dB */ + } #endif + +#if RTL8192E_SUPPORT + if (GET_CHIP_VER(priv) == VERSION_8192E) { + cali_info->default_cck_index = 8; /* -12 dB */ + } +#endif + +#if RTL8814B_SUPPORT + if (GET_CHIP_VER(priv) == VERSION_8814B) { + cali_info->default_txagc_index = get_txagc_default_index(dm); + + for (i = 0; i < MAX_PATH_NUM_8814B; i++) + tssi->tssi_trk_txagc_offset[i] = + cali_info->default_txagc_index; + } +#endif + cali_info->bb_swing_idx_ofdm_base = cali_info->default_ofdm_index; cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index; dm->rf_calibrate_info.CCK_index = cali_info->default_cck_index; @@ -1208,7 +1246,7 @@ odm_txpowertracking_check_ap( struct _hal_rf_ *rf = &dm->rf_table; struct _halrf_tssi_data *tssi = &rf->halrf_tssi_data; -#if ((RTL8188E_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8812A_SUPPORT == 1) || (RTL8881A_SUPPORT == 1) || (RTL8814A_SUPPORT == 1) || (RTL8197F_SUPPORT == 1) || (RTL8192F_SUPPORT == 1) || (RTL8198F_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8812F_SUPPORT == 1)) +#if ((RTL8188E_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8812A_SUPPORT == 1) || (RTL8881A_SUPPORT == 1) || (RTL8814A_SUPPORT == 1) || (RTL8197F_SUPPORT == 1) || (RTL8192F_SUPPORT == 1) || (RTL8198F_SUPPORT == 1) || (RTL8814B_SUPPORT == 1) || (RTL8812F_SUPPORT == 1) || (RTL8197G_SUPPORT == 1)) if (!dm->rf_calibrate_info.tm_trigger) { if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8812 | ODM_RTL8881A | ODM_RTL8814A | ODM_RTL8197F | ODM_RTL8822B | ODM_RTL8821C | ODM_RTL8192F | ODM_RTL8198F)) { odm_set_rf_reg(dm, RF_PATH_A, 0x42, (BIT(17) | BIT(16)), 0x3); @@ -1225,6 +1263,14 @@ odm_txpowertracking_check_ap( odm_set_rf_reg(dm, RF_PATH_B, 0x42, BIT(17), 0x1); odm_set_rf_reg(dm, RF_PATH_C, 0x42, BIT(17), 0x1); odm_set_rf_reg(dm, RF_PATH_D, 0x42, BIT(17), 0x1); + } else if (dm->support_ic_type & ODM_RTL8197G) { + odm_set_rf_reg(dm, RF_PATH_A, RF_0x42, BIT(17), 0x1); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x42, BIT(17), 0x0); + odm_set_rf_reg(dm, RF_PATH_A, RF_0x42, BIT(17), 0x1); + + odm_set_rf_reg(dm, RF_PATH_B, RF_0x42, BIT(17), 0x1); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x42, BIT(17), 0x0); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x42, BIT(17), 0x1); } if (dm->support_ic_type & ODM_RTL8814B) { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ap.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ap.h index b35999c13499..e81698ee11e4 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ap.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ap.h @@ -229,6 +229,7 @@ struct dm_rf_calibration_struct { u8 bb_swing_idx_cck_base; u8 default_ofdm_index; u8 default_cck_index; + s8 default_txagc_index; boolean bb_swing_flag_cck; s8 absolute_ofdm_swing_idx[MAX_RF_PATH]; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ce.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ce.c index 7a09820ead49..d2eb70e52a18 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ce.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ce.c @@ -665,6 +665,23 @@ u8 get_cck_swing_index(void *dm_void) return i; } +s8 +get_txagc_default_index( + void *dm_void +) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + s8 tmp; + + if (dm->support_ic_type == ODM_RTL8814B) { + tmp = (s8)(odm_get_bb_reg(dm, R_0x18a0, 0x7f) & 0xff); + if (tmp & BIT(6)) + tmp = tmp | 0x80; + return tmp; + } else + return 0; +} + void odm_txpowertracking_thermal_meter_init(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -718,7 +735,7 @@ void odm_txpowertracking_thermal_meter_init(void *dm_void) if (!cali_info->default_bb_swing_index_flag) { if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8723B | ODM_RTL8192E | - ODM_RTL8703B)) { + ODM_RTL8703B | ODM_RTL8821)) { if (swing_idx >= OFDM_TABLE_SIZE) cali_info->default_ofdm_index = 30; else @@ -749,6 +766,8 @@ void odm_txpowertracking_thermal_meter_init(void *dm_void) else cali_info->default_ofdm_index = swing_idx; + cali_info->default_txagc_index = get_txagc_default_index(dm); + cali_info->default_cck_index = 24; } cali_info->default_bb_swing_index_flag = true; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ce.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ce.h index 1e128700696b..871a64eb1fdf 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ce.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_ce.h @@ -200,6 +200,7 @@ struct dm_rf_calibration_struct { u8 bb_swing_idx_cck_base; u8 default_ofdm_index; u8 default_cck_index; + s8 default_txagc_index; boolean bb_swing_flag_cck; s8 absolute_ofdm_swing_idx[MAX_RF_PATH]; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_iot.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_iot.c index 543e12963cda..a6de4238ae82 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_iot.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_iot.c @@ -35,7 +35,7 @@ * ************************************************************ */ -u32 ofdm_swing_table[OFDM_TABLE_SIZE] = { +const u32 ofdm_swing_table[OFDM_TABLE_SIZE] = { 0x7f8001fe, /* 0, +6.0dB */ 0x788001e2, /* 1, +5.5dB */ 0x71c001c7, /* 2, +5.0dB*/ @@ -75,7 +75,7 @@ u32 ofdm_swing_table[OFDM_TABLE_SIZE] = { 0x10000040, /* 36, -12.0dB*/ }; -u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8] = { +const u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8] = { {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */ {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */ {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB*/ @@ -111,7 +111,7 @@ u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8] = { {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB*/ }; -u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8] = { +const u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8] = { {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */ {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */ {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */ @@ -147,7 +147,7 @@ u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8] = { {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB*/ }; -u32 ofdm_swing_table_new[OFDM_TABLE_SIZE] = { +const u32 ofdm_swing_table_new[OFDM_TABLE_SIZE] = { 0x0b40002d, /* 0, -15.0dB */ 0x0c000030, /* 1, -14.5dB*/ 0x0cc00033, /* 2, -14.0dB*/ @@ -193,7 +193,7 @@ u32 ofdm_swing_table_new[OFDM_TABLE_SIZE] = { 0x7f8001fe /* 42, +6.0dB*/ }; -u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16] = { +const u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16] = { {0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ {0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ {0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ @@ -217,7 +217,7 @@ u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16] = { {0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/ }; -u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16] = { +const u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16] = { {0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ {0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ {0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ @@ -241,7 +241,7 @@ u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16] = { {0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/ }; -u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16] = { +const u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16] = { {0x44, 0x42, 0x3C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ {0x48, 0x46, 0x3F, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ {0x4D, 0x4A, 0x43, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ @@ -265,7 +265,7 @@ u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16] = { {0xD8, 0xD1, 0xBD, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/ }; -u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8] = { +const u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8] = { {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, /* 0, -16.0dB*/ {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 1, -15.5dB*/ {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 2, -15.0dB*/ @@ -301,7 +301,7 @@ u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8] = { {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} /* 32, +0dB*/ }; -u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8] = { +const u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8] = { {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, /* 0, -16.0dB*/ {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 1, -15.5dB*/ {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 2, -15.0dB*/ @@ -337,7 +337,7 @@ u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8] = { {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} /* 32, +0dB */ }; -u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D] = { +const u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D] = { 0x0CD, /*0 , -20dB*/ 0x0D9, 0x0E6, @@ -382,7 +382,7 @@ u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D] = { }; /* JJ ADD 20161014 */ -u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B] = { +const u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B] = { 0x0CD, /*0 , -20dB*/ 0x0D9, 0x0E6, @@ -427,7 +427,7 @@ u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B] = { }; /* Winnita ADD 20171116 PathA 0xAB4[10:0],PathB 0xAB4[21:11]*/ -u32 cck_swing_table_ch1_ch14_8192f[CCK_TABLE_SIZE_8192F] = { +const u32 cck_swing_table_ch1_ch14_8192f[CCK_TABLE_SIZE_8192F] = { 0x0CD, /*0 , -20dB*/ 0x0D9, 0x0E6, @@ -472,7 +472,7 @@ u32 cck_swing_table_ch1_ch14_8192f[CCK_TABLE_SIZE_8192F] = { }; /* Winnita ADD 201805 PathA 0xAB4[10:0]*/ -u32 cck_swing_table_ch1_ch14_8721d[CCK_TABLE_SIZE_8721D] = { +const u32 cck_swing_table_ch1_ch14_8721d[CCK_TABLE_SIZE_8721D] = { 0x0CD, /*0 , -20dB*/ 0x0D9, 0x0E6, @@ -516,7 +516,7 @@ u32 cck_swing_table_ch1_ch14_8721d[CCK_TABLE_SIZE_8721D] = { 0x7FF, }; -u32 cck_swing_table_ch1_ch14_8710c[CCK_TABLE_SIZE_8710C] = { +const u32 cck_swing_table_ch1_ch14_8710c[CCK_TABLE_SIZE_8710C] = { 0x0CD, /*0 , -20dB*/ 0x0D9, 0x0E6, @@ -560,7 +560,7 @@ u32 cck_swing_table_ch1_ch14_8710c[CCK_TABLE_SIZE_8710C] = { 0x7FF, }; -u32 cck_swing_table_03db_ch1_ch14_8710c[CCK_03DB_TABLE_SIZE_8710C] = { +const u32 cck_swing_table_03db_ch1_ch14_8710c[CCK_03DB_TABLE_SIZE_8710C] = { 0x143, /*0 , -4dB*/ 0x14C, /*1 , -3.75dB*/ 0x156, /*2 , -3.5dB*/ @@ -644,7 +644,7 @@ u32 cck_swing_table_03db_ch1_ch14_8710c[CCK_03DB_TABLE_SIZE_8710C] = { 0xCA3 /*80 , +16dB*/ }; -u32 ofdm_swing_table_03DB_8710c[OFDM_03DB_TABLE_SIZE_8710C] = { +const u32 ofdm_swing_table_03DB_8710c[OFDM_03DB_TABLE_SIZE_8710C] = { 0xE4, /*0 , -7dB*/ 0xEB, /*1 , -6.75dB*/ 0xF2, /*2 , -6.5dB*/ @@ -730,7 +730,7 @@ u32 ofdm_swing_table_03DB_8710c[OFDM_03DB_TABLE_SIZE_8710C] = { -u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE] = { +const u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE] = { 0x081, /* 0, -12.0dB*/ 0x088, /* 1, -11.5dB*/ 0x090, /* 2, -11.0dB*/ @@ -793,6 +793,7 @@ get_swing_index( u32 *swing_table; u32 table_value; +#if (RTL8710C_SUPPORT == 1) if (dm->support_ic_type == ODM_RTL8710C) { bb_swing = odm_get_bb_reg(dm, R_0xcc8, 0x000007ff); @@ -801,10 +802,10 @@ get_swing_index( break; } } - +#elif (RTL8195B_SUPPORT == 1) if (dm->support_ic_type == ODM_RTL8195B) { bb_swing = odm_get_bb_reg(dm, R_0xc1c, 0xFFE00000); - swing_table = tx_scaling_table_jaguar; + swing_table = (u32*)tx_scaling_table_jaguar; swing_table_size = TXSCALE_TABLE_SIZE; for (i = 0; i < swing_table_size; i++) { @@ -815,7 +816,7 @@ get_swing_index( break; } } - +#endif return i; } @@ -829,6 +830,7 @@ get_cck_swing_index( u8 i = 0; u32 bb_cck_swing; +#if (RTL8188E_SUPPORT == 1 || RTL8723B_SUPPORT == 1 || RTL8192E_SUPPORT == 1) if (dm->support_ic_type == ODM_RTL8188E || dm->support_ic_type == ODM_RTL8723B || dm->support_ic_type == ODM_RTL8192E) { bb_cck_swing = odm_read_1byte(dm, 0xa22); @@ -837,14 +839,18 @@ get_cck_swing_index( if (bb_cck_swing == cck_swing_table_ch1_ch13_new[i][0]) break; } - } else if (dm->support_ic_type == ODM_RTL8703B) { + } +#elif (RTL8703B_SUPPORT == 1) + if (dm->support_ic_type == ODM_RTL8703B) { bb_cck_swing = odm_read_1byte(dm, 0xa22); for (i = 0; i < CCK_TABLE_SIZE_88F; i++) { if (bb_cck_swing == cck_swing_table_ch1_ch14_88f[i][0]) break; } - } else if (dm->support_ic_type == ODM_RTL8710C) { + } +#elif (RTL8710C_SUPPORT == 1) + if (dm->support_ic_type == ODM_RTL8710C) { bb_cck_swing = odm_get_bb_reg(dm, R_0xab4, 0x7ff); RF_DBG(dm, DBG_RF_TX_PWR_TRACK, @@ -855,10 +861,28 @@ get_cck_swing_index( break; } } +#endif return i; } +s8 +get_txagc_default_index( + void *dm_void +) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + s8 tmp; + + if (dm->support_ic_type == ODM_RTL8814B) { + tmp = (s8)(odm_get_bb_reg(dm, R_0x18a0, 0x7f) & 0xff); + if (tmp & BIT(6)) + tmp = tmp | 0x80; + return tmp; + } else + return 0; +} + void odm_txpowertracking_thermal_meter_init( void *dm_void diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_iot.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_iot.h index f599cddd598b..f56ab1f73b51 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_iot.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_iot.h @@ -63,26 +63,26 @@ #define IQK_MATRIX_SETTINGS_NUM (14+24+21) /* Channels_2_4G_NUM + Channels_5G_20M_NUM + Channels_5G */ #endif -extern u32 ofdm_swing_table[OFDM_TABLE_SIZE]; -extern u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8]; -extern u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8]; +extern const u32 ofdm_swing_table[OFDM_TABLE_SIZE]; +extern const u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8]; +extern const u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8]; -extern u32 ofdm_swing_table_new[OFDM_TABLE_SIZE]; -extern u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8]; -extern u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8]; -extern u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16]; -extern u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16]; -extern u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16]; -extern u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D]; +extern const u32 ofdm_swing_table_new[OFDM_TABLE_SIZE]; +extern const u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8]; +extern const u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8]; +extern const u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16]; +extern const u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16]; +extern const u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16]; +extern const u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D]; /* JJ ADD 20161014 */ -extern u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B]; -extern u32 cck_swing_table_ch1_ch14_8192f[CCK_TABLE_SIZE_8192F]; -extern u32 cck_swing_table_ch1_ch14_8721d[CCK_TABLE_SIZE_8721D]; -extern u32 cck_swing_table_ch1_ch14_8710c[CCK_TABLE_SIZE_8710C]; -extern u32 cck_swing_table_03db_ch1_ch14_8710c[CCK_03DB_TABLE_SIZE_8710C]; -extern u32 ofdm_swing_table_03DB_8710c[OFDM_03DB_TABLE_SIZE_8710C]; +extern const u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B]; +extern const u32 cck_swing_table_ch1_ch14_8192f[CCK_TABLE_SIZE_8192F]; +extern const u32 cck_swing_table_ch1_ch14_8721d[CCK_TABLE_SIZE_8721D]; +extern const u32 cck_swing_table_ch1_ch14_8710c[CCK_TABLE_SIZE_8710C]; +extern const u32 cck_swing_table_03db_ch1_ch14_8710c[CCK_03DB_TABLE_SIZE_8710C]; +extern const u32 ofdm_swing_table_03DB_8710c[OFDM_03DB_TABLE_SIZE_8710C]; -extern u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE]; +extern const u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE]; /* <20121018, Kordan> In case fail to read TxPowerTrack.txt, we use the table of 88E as the default table. */ #if (DM_ODM_SUPPORT_TYPE == ODM_CE) && defined(DM_ODM_CE_MAC80211) @@ -222,6 +222,7 @@ struct dm_rf_calibration_struct { u8 bb_swing_idx_cck_base; u8 default_ofdm_index; u8 default_cck_index; + s8 default_txagc_index; boolean bb_swing_flag_cck; s8 absolute_ofdm_swing_idx[MAX_RF_PATH]; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_win.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_win.c index b4feed1c4899..1c02d0e4a2b8 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_win.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_win.c @@ -588,6 +588,22 @@ get_cck_swing_index( return i; } +s8 +get_txagc_default_index( + void *dm_void +) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + s8 tmp; + + if (dm->support_ic_type == ODM_RTL8814B) { + tmp = (s8)(odm_get_bb_reg(dm, R_0x18a0, 0x7f) & 0xff); + if (tmp & BIT(6)) + tmp = tmp | 0x80; + return tmp; + } else + return 0; +} void odm_txpowertracking_thermal_meter_init( @@ -703,6 +719,7 @@ odm_txpowertracking_thermal_meter_init( } else { cali_info->default_ofdm_index = (default_swing_index >= TXSCALE_TABLE_SIZE) ? 24 : default_swing_index; cali_info->default_cck_index = 24; + cali_info->default_txagc_index = get_txagc_default_index(dm); } cali_info->default_bb_swing_index_flag = true; } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_win.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_win.h index 73a4d5a59178..7642e013877f 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_win.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/halrf_powertracking_win.h @@ -217,6 +217,7 @@ struct dm_rf_calibration_struct { u8 bb_swing_idx_cck_base; u8 default_ofdm_index; u8 default_cck_index; + s8 default_txagc_index; boolean bb_swing_flag_cck; s8 absolute_ofdm_swing_idx[MAX_RF_PATH]; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/rtl8821c/halhwimg8821c_rf.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/rtl8821c/halhwimg8821c_rf.c index bad3c1446183..8e1ffa7e3944 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/rtl8821c/halhwimg8821c_rf.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/rtl8821c/halhwimg8821c_rf.c @@ -24,9 +24,11 @@ * *****************************************************************************/ -/*Image2HeaderVersion: R3 1.5.8*/ +/*Image2HeaderVersion: R3 1.5.10.1*/ #include "mp_precomp.h" +#define ODM_WIN 0x08 + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) #if RT_PLATFORM == PLATFORM_MACOSX #include "phydm_precomp.h" @@ -2754,7 +2756,7 @@ odm_read_and_config_mp_8821c_radioa(struct dm_struct *dm) u32 odm_get_version_mp_8821c_radioa(void) { - return 57; + return 62; } /****************************************************************************** @@ -2907,7 +2909,7 @@ const u8 delta_swingidx_mp_5ga_n_txpwrtrk_type0x20_8821c[][D_S_SIZE] = { }; const u8 delta_swingidx_mp_5ga_p_txpwrtrk_type0x20_8821c[][D_S_SIZE] = { - {1, 1, 2, 2, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 8, + {0, 1, 2, 2, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 8, 9, 9, 10, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12}, {0, 1, 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12}, @@ -3113,1123 +3115,1123 @@ odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, ******************************************************************************/ #ifdef CONFIG_8821C -const char *array_mp_8821c_txpwr_lmt[] = { - "FCC", "2.4G", "20M", "CCK", "1T", "01", "30", - "ETSI", "2.4G", "20M", "CCK", "1T", "01", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "01", "34", - "IC", "2.4G", "20M", "CCK", "1T", "01", "30", - "KCC", "2.4G", "20M", "CCK", "1T", "01", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "01", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "01", "30", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "01", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "01", "30", - "FCC", "2.4G", "20M", "CCK", "1T", "02", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "02", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "02", "34", - "IC", "2.4G", "20M", "CCK", "1T", "02", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "02", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "02", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "02", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "02", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "02", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "03", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "03", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "03", "34", - "IC", "2.4G", "20M", "CCK", "1T", "03", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "03", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "03", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "03", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "03", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "03", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "04", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "04", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "04", "34", - "IC", "2.4G", "20M", "CCK", "1T", "04", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "04", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "04", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "04", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "04", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "04", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "05", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "05", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "05", "34", - "IC", "2.4G", "20M", "CCK", "1T", "05", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "05", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "05", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "05", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "05", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "05", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "06", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "06", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "06", "34", - "IC", "2.4G", "20M", "CCK", "1T", "06", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "06", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "06", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "06", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "06", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "06", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "07", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "07", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "07", "34", - "IC", "2.4G", "20M", "CCK", "1T", "07", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "07", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "07", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "07", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "07", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "07", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "08", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "08", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "08", "34", - "IC", "2.4G", "20M", "CCK", "1T", "08", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "08", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "08", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "08", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "08", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "08", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "09", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "09", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "09", "34", - "IC", "2.4G", "20M", "CCK", "1T", "09", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "09", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "09", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "09", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "09", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "09", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "10", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "10", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "10", "34", - "IC", "2.4G", "20M", "CCK", "1T", "10", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "10", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "10", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "10", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "10", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "10", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "11", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "11", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "11", "34", - "IC", "2.4G", "20M", "CCK", "1T", "11", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "11", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "11", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "11", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "11", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "11", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "12", "24", - "ETSI", "2.4G", "20M", "CCK", "1T", "12", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "12", "34", - "IC", "2.4G", "20M", "CCK", "1T", "12", "24", - "KCC", "2.4G", "20M", "CCK", "1T", "12", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "12", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "12", "24", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "12", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "12", "24", - "FCC", "2.4G", "20M", "CCK", "1T", "13", "16", - "ETSI", "2.4G", "20M", "CCK", "1T", "13", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "13", "34", - "IC", "2.4G", "20M", "CCK", "1T", "13", "16", - "KCC", "2.4G", "20M", "CCK", "1T", "13", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "13", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "13", "16", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "13", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "13", "16", - "FCC", "2.4G", "20M", "CCK", "1T", "14", "63", - "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63", - "MKK", "2.4G", "20M", "CCK", "1T", "14", "34", - "IC", "2.4G", "20M", "CCK", "1T", "14", "63", - "KCC", "2.4G", "20M", "CCK", "1T", "14", "63", - "ACMA", "2.4G", "20M", "CCK", "1T", "14", "63", - "CHILE", "2.4G", "20M", "CCK", "1T", "14", "63", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "14", "63", - "MEXICO", "2.4G", "20M", "CCK", "1T", "14", "63", - "FCC", "2.4G", "20M", "OFDM", "1T", "01", "30", - "ETSI", "2.4G", "20M", "OFDM", "1T", "01", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "01", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "01", "30", - "KCC", "2.4G", "20M", "OFDM", "1T", "01", "32", - "ACMA", "2.4G", "20M", "OFDM", "1T", "01", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "01", "30", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "01", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "01", "30", - "FCC", "2.4G", "20M", "OFDM", "1T", "02", "32", - "ETSI", "2.4G", "20M", "OFDM", "1T", "02", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "02", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "02", "32", - "KCC", "2.4G", "20M", "OFDM", "1T", "02", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "02", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "02", "32", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "02", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "02", "32", - "FCC", "2.4G", "20M", "OFDM", "1T", "03", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "03", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "03", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "03", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "03", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "03", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "03", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "03", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "04", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "04", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "04", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "04", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "04", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "04", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "04", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "04", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "04", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "05", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "05", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "05", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "05", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "05", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "05", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "05", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "05", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "05", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "06", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "06", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "06", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "06", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "06", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "06", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "06", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "06", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "07", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "07", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "07", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "07", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "07", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "07", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "07", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "07", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "07", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "08", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "08", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "08", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "08", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "08", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "08", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "08", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "08", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "08", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "09", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "09", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "09", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "09", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "09", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "09", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "09", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "09", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "10", "32", - "ETSI", "2.4G", "20M", "OFDM", "1T", "10", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "10", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "10", "32", - "KCC", "2.4G", "20M", "OFDM", "1T", "10", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "10", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "10", "32", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "10", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "10", "32", - "FCC", "2.4G", "20M", "OFDM", "1T", "11", "30", - "ETSI", "2.4G", "20M", "OFDM", "1T", "11", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "11", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "11", "30", - "KCC", "2.4G", "20M", "OFDM", "1T", "11", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "11", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "11", "30", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "11", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "11", "30", - "FCC", "2.4G", "20M", "OFDM", "1T", "12", "28", - "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "12", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "12", "28", - "KCC", "2.4G", "20M", "OFDM", "1T", "12", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "12", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "12", "28", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "12", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "12", "28", - "FCC", "2.4G", "20M", "OFDM", "1T", "13", "16", - "ETSI", "2.4G", "20M", "OFDM", "1T", "13", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "13", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "13", "16", - "KCC", "2.4G", "20M", "OFDM", "1T", "13", "32", - "ACMA", "2.4G", "20M", "OFDM", "1T", "13", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "13", "16", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "13", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "13", "16", - "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63", - "ETSI", "2.4G", "20M", "OFDM", "1T", "14", "63", - "MKK", "2.4G", "20M", "OFDM", "1T", "14", "63", - "IC", "2.4G", "20M", "OFDM", "1T", "14", "63", - "KCC", "2.4G", "20M", "OFDM", "1T", "14", "63", - "ACMA", "2.4G", "20M", "OFDM", "1T", "14", "63", - "CHILE", "2.4G", "20M", "OFDM", "1T", "14", "63", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "14", "63", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "14", "63", - "FCC", "2.4G", "20M", "HT", "1T", "01", "26", - "ETSI", "2.4G", "20M", "HT", "1T", "01", "30", - "MKK", "2.4G", "20M", "HT", "1T", "01", "34", - "IC", "2.4G", "20M", "HT", "1T", "01", "26", - "KCC", "2.4G", "20M", "HT", "1T", "01", "32", - "ACMA", "2.4G", "20M", "HT", "1T", "01", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "01", "26", - "UKRAINE", "2.4G", "20M", "HT", "1T", "01", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "01", "26", - "FCC", "2.4G", "20M", "HT", "1T", "02", "30", - "ETSI", "2.4G", "20M", "HT", "1T", "02", "30", - "MKK", "2.4G", "20M", "HT", "1T", "02", "34", - "IC", "2.4G", "20M", "HT", "1T", "02", "30", - "KCC", "2.4G", "20M", "HT", "1T", "02", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "02", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "02", "30", - "UKRAINE", "2.4G", "20M", "HT", "1T", "02", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "02", "30", - "FCC", "2.4G", "20M", "HT", "1T", "03", "32", - "ETSI", "2.4G", "20M", "HT", "1T", "03", "30", - "MKK", "2.4G", "20M", "HT", "1T", "03", "34", - "IC", "2.4G", "20M", "HT", "1T", "03", "32", - "KCC", "2.4G", "20M", "HT", "1T", "03", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "03", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "03", "32", - "UKRAINE", "2.4G", "20M", "HT", "1T", "03", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "03", "32", - "FCC", "2.4G", "20M", "HT", "1T", "04", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "04", "30", - "MKK", "2.4G", "20M", "HT", "1T", "04", "34", - "IC", "2.4G", "20M", "HT", "1T", "04", "34", - "KCC", "2.4G", "20M", "HT", "1T", "04", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "04", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "04", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "04", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "04", "34", - "FCC", "2.4G", "20M", "HT", "1T", "05", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "05", "30", - "MKK", "2.4G", "20M", "HT", "1T", "05", "34", - "IC", "2.4G", "20M", "HT", "1T", "05", "34", - "KCC", "2.4G", "20M", "HT", "1T", "05", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "05", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "05", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "05", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "05", "34", - "FCC", "2.4G", "20M", "HT", "1T", "06", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "06", "30", - "MKK", "2.4G", "20M", "HT", "1T", "06", "34", - "IC", "2.4G", "20M", "HT", "1T", "06", "34", - "KCC", "2.4G", "20M", "HT", "1T", "06", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "06", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "06", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "06", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "06", "34", - "FCC", "2.4G", "20M", "HT", "1T", "07", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "07", "30", - "MKK", "2.4G", "20M", "HT", "1T", "07", "34", - "IC", "2.4G", "20M", "HT", "1T", "07", "34", - "KCC", "2.4G", "20M", "HT", "1T", "07", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "07", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "07", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "07", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "07", "34", - "FCC", "2.4G", "20M", "HT", "1T", "08", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "08", "30", - "MKK", "2.4G", "20M", "HT", "1T", "08", "34", - "IC", "2.4G", "20M", "HT", "1T", "08", "34", - "KCC", "2.4G", "20M", "HT", "1T", "08", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "08", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "08", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "08", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "08", "34", - "FCC", "2.4G", "20M", "HT", "1T", "09", "32", - "ETSI", "2.4G", "20M", "HT", "1T", "09", "30", - "MKK", "2.4G", "20M", "HT", "1T", "09", "34", - "IC", "2.4G", "20M", "HT", "1T", "09", "32", - "KCC", "2.4G", "20M", "HT", "1T", "09", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "09", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "09", "32", - "UKRAINE", "2.4G", "20M", "HT", "1T", "09", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "09", "32", - "FCC", "2.4G", "20M", "HT", "1T", "10", "30", - "ETSI", "2.4G", "20M", "HT", "1T", "10", "30", - "MKK", "2.4G", "20M", "HT", "1T", "10", "34", - "IC", "2.4G", "20M", "HT", "1T", "10", "30", - "KCC", "2.4G", "20M", "HT", "1T", "10", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "10", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "10", "30", - "UKRAINE", "2.4G", "20M", "HT", "1T", "10", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "10", "30", - "FCC", "2.4G", "20M", "HT", "1T", "11", "28", - "ETSI", "2.4G", "20M", "HT", "1T", "11", "30", - "MKK", "2.4G", "20M", "HT", "1T", "11", "34", - "IC", "2.4G", "20M", "HT", "1T", "11", "28", - "KCC", "2.4G", "20M", "HT", "1T", "11", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "11", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "11", "28", - "UKRAINE", "2.4G", "20M", "HT", "1T", "11", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "11", "28", - "FCC", "2.4G", "20M", "HT", "1T", "12", "26", - "ETSI", "2.4G", "20M", "HT", "1T", "12", "30", - "MKK", "2.4G", "20M", "HT", "1T", "12", "34", - "IC", "2.4G", "20M", "HT", "1T", "12", "26", - "KCC", "2.4G", "20M", "HT", "1T", "12", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "12", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "12", "26", - "UKRAINE", "2.4G", "20M", "HT", "1T", "12", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "12", "26", - "FCC", "2.4G", "20M", "HT", "1T", "13", "12", - "ETSI", "2.4G", "20M", "HT", "1T", "13", "30", - "MKK", "2.4G", "20M", "HT", "1T", "13", "34", - "IC", "2.4G", "20M", "HT", "1T", "13", "12", - "KCC", "2.4G", "20M", "HT", "1T", "13", "32", - "ACMA", "2.4G", "20M", "HT", "1T", "13", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "13", "12", - "UKRAINE", "2.4G", "20M", "HT", "1T", "13", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "13", "12", - "FCC", "2.4G", "20M", "HT", "1T", "14", "63", - "ETSI", "2.4G", "20M", "HT", "1T", "14", "63", - "MKK", "2.4G", "20M", "HT", "1T", "14", "63", - "IC", "2.4G", "20M", "HT", "1T", "14", "63", - "KCC", "2.4G", "20M", "HT", "1T", "14", "63", - "ACMA", "2.4G", "20M", "HT", "1T", "14", "63", - "CHILE", "2.4G", "20M", "HT", "1T", "14", "63", - "UKRAINE", "2.4G", "20M", "HT", "1T", "14", "63", - "MEXICO", "2.4G", "20M", "HT", "1T", "14", "63", - "FCC", "2.4G", "40M", "HT", "1T", "01", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "01", "63", - "MKK", "2.4G", "40M", "HT", "1T", "01", "63", - "IC", "2.4G", "40M", "HT", "1T", "01", "63", - "KCC", "2.4G", "40M", "HT", "1T", "01", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "01", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "01", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "01", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "01", "63", - "FCC", "2.4G", "40M", "HT", "1T", "02", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "02", "63", - "MKK", "2.4G", "40M", "HT", "1T", "02", "63", - "IC", "2.4G", "40M", "HT", "1T", "02", "63", - "KCC", "2.4G", "40M", "HT", "1T", "02", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "02", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "02", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "02", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "02", "63", - "FCC", "2.4G", "40M", "HT", "1T", "03", "26", - "ETSI", "2.4G", "40M", "HT", "1T", "03", "30", - "MKK", "2.4G", "40M", "HT", "1T", "03", "30", - "IC", "2.4G", "40M", "HT", "1T", "03", "26", - "KCC", "2.4G", "40M", "HT", "1T", "03", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "03", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "03", "26", - "UKRAINE", "2.4G", "40M", "HT", "1T", "03", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "03", "26", - "FCC", "2.4G", "40M", "HT", "1T", "04", "26", - "ETSI", "2.4G", "40M", "HT", "1T", "04", "30", - "MKK", "2.4G", "40M", "HT", "1T", "04", "30", - "IC", "2.4G", "40M", "HT", "1T", "04", "26", - "KCC", "2.4G", "40M", "HT", "1T", "04", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "04", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "04", "26", - "UKRAINE", "2.4G", "40M", "HT", "1T", "04", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "04", "26", - "FCC", "2.4G", "40M", "HT", "1T", "05", "30", - "ETSI", "2.4G", "40M", "HT", "1T", "05", "30", - "MKK", "2.4G", "40M", "HT", "1T", "05", "30", - "IC", "2.4G", "40M", "HT", "1T", "05", "30", - "KCC", "2.4G", "40M", "HT", "1T", "05", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "05", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "05", "30", - "UKRAINE", "2.4G", "40M", "HT", "1T", "05", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "05", "30", - "FCC", "2.4G", "40M", "HT", "1T", "06", "30", - "ETSI", "2.4G", "40M", "HT", "1T", "06", "30", - "MKK", "2.4G", "40M", "HT", "1T", "06", "30", - "IC", "2.4G", "40M", "HT", "1T", "06", "30", - "KCC", "2.4G", "40M", "HT", "1T", "06", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "06", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "06", "30", - "UKRAINE", "2.4G", "40M", "HT", "1T", "06", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "06", "30", - "FCC", "2.4G", "40M", "HT", "1T", "07", "30", - "ETSI", "2.4G", "40M", "HT", "1T", "07", "30", - "MKK", "2.4G", "40M", "HT", "1T", "07", "30", - "IC", "2.4G", "40M", "HT", "1T", "07", "30", - "KCC", "2.4G", "40M", "HT", "1T", "07", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "07", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "07", "30", - "UKRAINE", "2.4G", "40M", "HT", "1T", "07", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "07", "30", - "FCC", "2.4G", "40M", "HT", "1T", "08", "26", - "ETSI", "2.4G", "40M", "HT", "1T", "08", "30", - "MKK", "2.4G", "40M", "HT", "1T", "08", "30", - "IC", "2.4G", "40M", "HT", "1T", "08", "26", - "KCC", "2.4G", "40M", "HT", "1T", "08", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "08", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "08", "26", - "UKRAINE", "2.4G", "40M", "HT", "1T", "08", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "08", "26", - "FCC", "2.4G", "40M", "HT", "1T", "09", "26", - "ETSI", "2.4G", "40M", "HT", "1T", "09", "30", - "MKK", "2.4G", "40M", "HT", "1T", "09", "30", - "IC", "2.4G", "40M", "HT", "1T", "09", "26", - "KCC", "2.4G", "40M", "HT", "1T", "09", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "09", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "09", "26", - "UKRAINE", "2.4G", "40M", "HT", "1T", "09", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "09", "26", - "FCC", "2.4G", "40M", "HT", "1T", "10", "28", - "ETSI", "2.4G", "40M", "HT", "1T", "10", "30", - "MKK", "2.4G", "40M", "HT", "1T", "10", "30", - "IC", "2.4G", "40M", "HT", "1T", "10", "28", - "KCC", "2.4G", "40M", "HT", "1T", "10", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "10", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "10", "28", - "UKRAINE", "2.4G", "40M", "HT", "1T", "10", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "10", "28", - "FCC", "2.4G", "40M", "HT", "1T", "11", "20", - "ETSI", "2.4G", "40M", "HT", "1T", "11", "30", - "MKK", "2.4G", "40M", "HT", "1T", "11", "30", - "IC", "2.4G", "40M", "HT", "1T", "11", "20", - "KCC", "2.4G", "40M", "HT", "1T", "11", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "11", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "11", "20", - "UKRAINE", "2.4G", "40M", "HT", "1T", "11", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "11", "20", - "FCC", "2.4G", "40M", "HT", "1T", "12", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "12", "63", - "MKK", "2.4G", "40M", "HT", "1T", "12", "63", - "IC", "2.4G", "40M", "HT", "1T", "12", "63", - "KCC", "2.4G", "40M", "HT", "1T", "12", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "12", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "12", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "12", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "12", "63", - "FCC", "2.4G", "40M", "HT", "1T", "13", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "13", "63", - "MKK", "2.4G", "40M", "HT", "1T", "13", "63", - "IC", "2.4G", "40M", "HT", "1T", "13", "63", - "KCC", "2.4G", "40M", "HT", "1T", "13", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "13", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "13", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "13", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "13", "63", - "FCC", "2.4G", "40M", "HT", "1T", "14", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "14", "63", - "MKK", "2.4G", "40M", "HT", "1T", "14", "63", - "IC", "2.4G", "40M", "HT", "1T", "14", "63", - "KCC", "2.4G", "40M", "HT", "1T", "14", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "14", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "14", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "14", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "14", "63", - "FCC", "5G", "20M", "OFDM", "1T", "36", "31", - "ETSI", "5G", "20M", "OFDM", "1T", "36", "32", - "MKK", "5G", "20M", "OFDM", "1T", "36", "33", - "IC", "5G", "20M", "OFDM", "1T", "36", "31", - "KCC", "5G", "20M", "OFDM", "1T", "36", "29", - "ACMA", "5G", "20M", "OFDM", "1T", "36", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "36", "31", - "UKRAINE", "5G", "20M", "OFDM", "1T", "36", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "36", "31", - "FCC", "5G", "20M", "OFDM", "1T", "40", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "40", "32", - "MKK", "5G", "20M", "OFDM", "1T", "40", "33", - "IC", "5G", "20M", "OFDM", "1T", "40", "31", - "KCC", "5G", "20M", "OFDM", "1T", "40", "28", - "ACMA", "5G", "20M", "OFDM", "1T", "40", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "40", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "40", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "40", "31", - "FCC", "5G", "20M", "OFDM", "1T", "44", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "44", "32", - "MKK", "5G", "20M", "OFDM", "1T", "44", "33", - "IC", "5G", "20M", "OFDM", "1T", "44", "31", - "KCC", "5G", "20M", "OFDM", "1T", "44", "28", - "ACMA", "5G", "20M", "OFDM", "1T", "44", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "44", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "44", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "44", "31", - "FCC", "5G", "20M", "OFDM", "1T", "48", "31", - "ETSI", "5G", "20M", "OFDM", "1T", "48", "32", - "MKK", "5G", "20M", "OFDM", "1T", "48", "33", - "IC", "5G", "20M", "OFDM", "1T", "48", "31", - "KCC", "5G", "20M", "OFDM", "1T", "48", "27", - "ACMA", "5G", "20M", "OFDM", "1T", "48", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "48", "31", - "UKRAINE", "5G", "20M", "OFDM", "1T", "48", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "48", "31", - "FCC", "5G", "20M", "OFDM", "1T", "52", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "52", "32", - "MKK", "5G", "20M", "OFDM", "1T", "52", "33", - "IC", "5G", "20M", "OFDM", "1T", "52", "32", - "KCC", "5G", "20M", "OFDM", "1T", "52", "16", - "ACMA", "5G", "20M", "OFDM", "1T", "52", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "52", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "52", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "52", "33", - "FCC", "5G", "20M", "OFDM", "1T", "56", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "56", "32", - "MKK", "5G", "20M", "OFDM", "1T", "56", "33", - "IC", "5G", "20M", "OFDM", "1T", "56", "32", - "KCC", "5G", "20M", "OFDM", "1T", "56", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "56", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "56", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "56", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "56", "33", - "FCC", "5G", "20M", "OFDM", "1T", "60", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "60", "32", - "MKK", "5G", "20M", "OFDM", "1T", "60", "33", - "IC", "5G", "20M", "OFDM", "1T", "60", "32", - "KCC", "5G", "20M", "OFDM", "1T", "60", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "60", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "60", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "60", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "60", "33", - "FCC", "5G", "20M", "OFDM", "1T", "64", "30", - "ETSI", "5G", "20M", "OFDM", "1T", "64", "32", - "MKK", "5G", "20M", "OFDM", "1T", "64", "33", - "IC", "5G", "20M", "OFDM", "1T", "64", "30", - "KCC", "5G", "20M", "OFDM", "1T", "64", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "64", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "64", "30", - "UKRAINE", "5G", "20M", "OFDM", "1T", "64", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "64", "30", - "FCC", "5G", "20M", "OFDM", "1T", "100", "30", - "ETSI", "5G", "20M", "OFDM", "1T", "100", "32", - "MKK", "5G", "20M", "OFDM", "1T", "100", "33", - "IC", "5G", "20M", "OFDM", "1T", "100", "30", - "KCC", "5G", "20M", "OFDM", "1T", "100", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "100", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "100", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "100", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "100", "30", - "FCC", "5G", "20M", "OFDM", "1T", "104", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "104", "32", - "MKK", "5G", "20M", "OFDM", "1T", "104", "33", - "IC", "5G", "20M", "OFDM", "1T", "104", "33", - "KCC", "5G", "20M", "OFDM", "1T", "104", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "104", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "104", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "104", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "104", "33", - "FCC", "5G", "20M", "OFDM", "1T", "108", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "108", "32", - "MKK", "5G", "20M", "OFDM", "1T", "108", "33", - "IC", "5G", "20M", "OFDM", "1T", "108", "33", - "KCC", "5G", "20M", "OFDM", "1T", "108", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "108", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "108", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "108", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "108", "33", - "FCC", "5G", "20M", "OFDM", "1T", "112", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "112", "32", - "MKK", "5G", "20M", "OFDM", "1T", "112", "33", - "IC", "5G", "20M", "OFDM", "1T", "112", "33", - "KCC", "5G", "20M", "OFDM", "1T", "112", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "112", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "112", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "112", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "112", "33", - "FCC", "5G", "20M", "OFDM", "1T", "116", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "116", "32", - "MKK", "5G", "20M", "OFDM", "1T", "116", "33", - "IC", "5G", "20M", "OFDM", "1T", "116", "33", - "KCC", "5G", "20M", "OFDM", "1T", "116", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "116", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "116", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "116", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "116", "33", - "FCC", "5G", "20M", "OFDM", "1T", "120", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "120", "32", - "MKK", "5G", "20M", "OFDM", "1T", "120", "33", - "IC", "5G", "20M", "OFDM", "1T", "120", "63", - "KCC", "5G", "20M", "OFDM", "1T", "120", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "120", "63", - "CHILE", "5G", "20M", "OFDM", "1T", "120", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "120", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "120", "33", - "FCC", "5G", "20M", "OFDM", "1T", "124", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "124", "32", - "MKK", "5G", "20M", "OFDM", "1T", "124", "33", - "IC", "5G", "20M", "OFDM", "1T", "124", "63", - "KCC", "5G", "20M", "OFDM", "1T", "124", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "124", "63", - "CHILE", "5G", "20M", "OFDM", "1T", "124", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "124", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "124", "33", - "FCC", "5G", "20M", "OFDM", "1T", "128", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "128", "32", - "MKK", "5G", "20M", "OFDM", "1T", "128", "33", - "IC", "5G", "20M", "OFDM", "1T", "128", "63", - "KCC", "5G", "20M", "OFDM", "1T", "128", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "128", "63", - "CHILE", "5G", "20M", "OFDM", "1T", "128", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "128", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "128", "33", - "FCC", "5G", "20M", "OFDM", "1T", "132", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "132", "32", - "MKK", "5G", "20M", "OFDM", "1T", "132", "33", - "IC", "5G", "20M", "OFDM", "1T", "132", "33", - "KCC", "5G", "20M", "OFDM", "1T", "132", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "132", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "132", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "132", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "132", "33", - "FCC", "5G", "20M", "OFDM", "1T", "136", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "136", "32", - "MKK", "5G", "20M", "OFDM", "1T", "136", "33", - "IC", "5G", "20M", "OFDM", "1T", "136", "33", - "KCC", "5G", "20M", "OFDM", "1T", "136", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "136", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "136", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "136", "63", - "MEXICO", "5G", "20M", "OFDM", "1T", "136", "33", - "FCC", "5G", "20M", "OFDM", "1T", "140", "31", - "ETSI", "5G", "20M", "OFDM", "1T", "140", "32", - "MKK", "5G", "20M", "OFDM", "1T", "140", "33", - "IC", "5G", "20M", "OFDM", "1T", "140", "31", - "KCC", "5G", "20M", "OFDM", "1T", "140", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "140", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "140", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "140", "63", - "MEXICO", "5G", "20M", "OFDM", "1T", "140", "31", - "FCC", "5G", "20M", "OFDM", "1T", "144", "30", - "ETSI", "5G", "20M", "OFDM", "1T", "144", "63", - "MKK", "5G", "20M", "OFDM", "1T", "144", "63", - "IC", "5G", "20M", "OFDM", "1T", "144", "30", - "KCC", "5G", "20M", "OFDM", "1T", "144", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "144", "63", - "CHILE", "5G", "20M", "OFDM", "1T", "144", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "144", "63", - "MEXICO", "5G", "20M", "OFDM", "1T", "144", "30", - "FCC", "5G", "20M", "OFDM", "1T", "149", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "149", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "149", "63", - "IC", "5G", "20M", "OFDM", "1T", "149", "30", - "KCC", "5G", "20M", "OFDM", "1T", "149", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "149", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "149", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "149", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "149", "33", - "FCC", "5G", "20M", "OFDM", "1T", "153", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "153", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "153", "63", - "IC", "5G", "20M", "OFDM", "1T", "153", "33", - "KCC", "5G", "20M", "OFDM", "1T", "153", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "153", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "153", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "153", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "153", "33", - "FCC", "5G", "20M", "OFDM", "1T", "157", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "157", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "157", "63", - "IC", "5G", "20M", "OFDM", "1T", "157", "33", - "KCC", "5G", "20M", "OFDM", "1T", "157", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "157", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "157", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "157", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "157", "33", - "FCC", "5G", "20M", "OFDM", "1T", "161", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "161", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "161", "63", - "IC", "5G", "20M", "OFDM", "1T", "161", "33", - "KCC", "5G", "20M", "OFDM", "1T", "161", "31", - "ACMA", "5G", "20M", "OFDM", "1T", "161", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "161", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "161", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "161", "33", - "FCC", "5G", "20M", "OFDM", "1T", "165", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "165", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "165", "63", - "IC", "5G", "20M", "OFDM", "1T", "165", "33", - "KCC", "5G", "20M", "OFDM", "1T", "165", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "165", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "165", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "165", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "165", "30", - "FCC", "5G", "20M", "HT", "1T", "36", "30", - "ETSI", "5G", "20M", "HT", "1T", "36", "32", - "MKK", "5G", "20M", "HT", "1T", "36", "33", - "IC", "5G", "20M", "HT", "1T", "36", "30", - "KCC", "5G", "20M", "HT", "1T", "36", "27", - "ACMA", "5G", "20M", "HT", "1T", "36", "32", - "CHILE", "5G", "20M", "HT", "1T", "36", "30", - "UKRAINE", "5G", "20M", "HT", "1T", "36", "27", - "MEXICO", "5G", "20M", "HT", "1T", "36", "30", - "FCC", "5G", "20M", "HT", "1T", "40", "33", - "ETSI", "5G", "20M", "HT", "1T", "40", "32", - "MKK", "5G", "20M", "HT", "1T", "40", "33", - "IC", "5G", "20M", "HT", "1T", "40", "31", - "KCC", "5G", "20M", "HT", "1T", "40", "29", - "ACMA", "5G", "20M", "HT", "1T", "40", "32", - "CHILE", "5G", "20M", "HT", "1T", "40", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "40", "27", - "MEXICO", "5G", "20M", "HT", "1T", "40", "31", - "FCC", "5G", "20M", "HT", "1T", "44", "33", - "ETSI", "5G", "20M", "HT", "1T", "44", "32", - "MKK", "5G", "20M", "HT", "1T", "44", "33", - "IC", "5G", "20M", "HT", "1T", "44", "31", - "KCC", "5G", "20M", "HT", "1T", "44", "29", - "ACMA", "5G", "20M", "HT", "1T", "44", "32", - "CHILE", "5G", "20M", "HT", "1T", "44", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "44", "27", - "MEXICO", "5G", "20M", "HT", "1T", "44", "31", - "FCC", "5G", "20M", "HT", "1T", "48", "33", - "ETSI", "5G", "20M", "HT", "1T", "48", "32", - "MKK", "5G", "20M", "HT", "1T", "48", "33", - "IC", "5G", "20M", "HT", "1T", "48", "31", - "KCC", "5G", "20M", "HT", "1T", "48", "26", - "ACMA", "5G", "20M", "HT", "1T", "48", "32", - "CHILE", "5G", "20M", "HT", "1T", "48", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "48", "27", - "MEXICO", "5G", "20M", "HT", "1T", "48", "31", - "FCC", "5G", "20M", "HT", "1T", "52", "33", - "ETSI", "5G", "20M", "HT", "1T", "52", "32", - "MKK", "5G", "20M", "HT", "1T", "52", "33", - "IC", "5G", "20M", "HT", "1T", "52", "32", - "KCC", "5G", "20M", "HT", "1T", "52", "7", - "ACMA", "5G", "20M", "HT", "1T", "52", "32", - "CHILE", "5G", "20M", "HT", "1T", "52", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "52", "27", - "MEXICO", "5G", "20M", "HT", "1T", "52", "33", - "FCC", "5G", "20M", "HT", "1T", "56", "33", - "ETSI", "5G", "20M", "HT", "1T", "56", "32", - "MKK", "5G", "20M", "HT", "1T", "56", "33", - "IC", "5G", "20M", "HT", "1T", "56", "32", - "KCC", "5G", "20M", "HT", "1T", "56", "33", - "ACMA", "5G", "20M", "HT", "1T", "56", "32", - "CHILE", "5G", "20M", "HT", "1T", "56", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "56", "27", - "MEXICO", "5G", "20M", "HT", "1T", "56", "33", - "FCC", "5G", "20M", "HT", "1T", "60", "33", - "ETSI", "5G", "20M", "HT", "1T", "60", "32", - "MKK", "5G", "20M", "HT", "1T", "60", "33", - "IC", "5G", "20M", "HT", "1T", "60", "32", - "KCC", "5G", "20M", "HT", "1T", "60", "33", - "ACMA", "5G", "20M", "HT", "1T", "60", "32", - "CHILE", "5G", "20M", "HT", "1T", "60", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "60", "27", - "MEXICO", "5G", "20M", "HT", "1T", "60", "33", - "FCC", "5G", "20M", "HT", "1T", "64", "30", - "ETSI", "5G", "20M", "HT", "1T", "64", "32", - "MKK", "5G", "20M", "HT", "1T", "64", "33", - "IC", "5G", "20M", "HT", "1T", "64", "30", - "KCC", "5G", "20M", "HT", "1T", "64", "33", - "ACMA", "5G", "20M", "HT", "1T", "64", "32", - "CHILE", "5G", "20M", "HT", "1T", "64", "30", - "UKRAINE", "5G", "20M", "HT", "1T", "64", "27", - "MEXICO", "5G", "20M", "HT", "1T", "64", "30", - "FCC", "5G", "20M", "HT", "1T", "100", "30", - "ETSI", "5G", "20M", "HT", "1T", "100", "32", - "MKK", "5G", "20M", "HT", "1T", "100", "33", - "IC", "5G", "20M", "HT", "1T", "100", "30", - "KCC", "5G", "20M", "HT", "1T", "100", "33", - "ACMA", "5G", "20M", "HT", "1T", "100", "32", - "CHILE", "5G", "20M", "HT", "1T", "100", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "100", "27", - "MEXICO", "5G", "20M", "HT", "1T", "100", "30", - "FCC", "5G", "20M", "HT", "1T", "104", "33", - "ETSI", "5G", "20M", "HT", "1T", "104", "32", - "MKK", "5G", "20M", "HT", "1T", "104", "33", - "IC", "5G", "20M", "HT", "1T", "104", "33", - "KCC", "5G", "20M", "HT", "1T", "104", "33", - "ACMA", "5G", "20M", "HT", "1T", "104", "32", - "CHILE", "5G", "20M", "HT", "1T", "104", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "104", "27", - "MEXICO", "5G", "20M", "HT", "1T", "104", "33", - "FCC", "5G", "20M", "HT", "1T", "108", "33", - "ETSI", "5G", "20M", "HT", "1T", "108", "32", - "MKK", "5G", "20M", "HT", "1T", "108", "33", - "IC", "5G", "20M", "HT", "1T", "108", "33", - "KCC", "5G", "20M", "HT", "1T", "108", "33", - "ACMA", "5G", "20M", "HT", "1T", "108", "32", - "CHILE", "5G", "20M", "HT", "1T", "108", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "108", "27", - "MEXICO", "5G", "20M", "HT", "1T", "108", "33", - "FCC", "5G", "20M", "HT", "1T", "112", "33", - "ETSI", "5G", "20M", "HT", "1T", "112", "32", - "MKK", "5G", "20M", "HT", "1T", "112", "33", - "IC", "5G", "20M", "HT", "1T", "112", "33", - "KCC", "5G", "20M", "HT", "1T", "112", "33", - "ACMA", "5G", "20M", "HT", "1T", "112", "32", - "CHILE", "5G", "20M", "HT", "1T", "112", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "112", "27", - "MEXICO", "5G", "20M", "HT", "1T", "112", "33", - "FCC", "5G", "20M", "HT", "1T", "116", "33", - "ETSI", "5G", "20M", "HT", "1T", "116", "32", - "MKK", "5G", "20M", "HT", "1T", "116", "33", - "IC", "5G", "20M", "HT", "1T", "116", "33", - "KCC", "5G", "20M", "HT", "1T", "116", "33", - "ACMA", "5G", "20M", "HT", "1T", "116", "32", - "CHILE", "5G", "20M", "HT", "1T", "116", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "116", "27", - "MEXICO", "5G", "20M", "HT", "1T", "116", "33", - "FCC", "5G", "20M", "HT", "1T", "120", "33", - "ETSI", "5G", "20M", "HT", "1T", "120", "32", - "MKK", "5G", "20M", "HT", "1T", "120", "33", - "IC", "5G", "20M", "HT", "1T", "120", "63", - "KCC", "5G", "20M", "HT", "1T", "120", "33", - "ACMA", "5G", "20M", "HT", "1T", "120", "63", - "CHILE", "5G", "20M", "HT", "1T", "120", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "120", "27", - "MEXICO", "5G", "20M", "HT", "1T", "120", "33", - "FCC", "5G", "20M", "HT", "1T", "124", "33", - "ETSI", "5G", "20M", "HT", "1T", "124", "32", - "MKK", "5G", "20M", "HT", "1T", "124", "33", - "IC", "5G", "20M", "HT", "1T", "124", "63", - "KCC", "5G", "20M", "HT", "1T", "124", "33", - "ACMA", "5G", "20M", "HT", "1T", "124", "63", - "CHILE", "5G", "20M", "HT", "1T", "124", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "124", "27", - "MEXICO", "5G", "20M", "HT", "1T", "124", "33", - "FCC", "5G", "20M", "HT", "1T", "128", "33", - "ETSI", "5G", "20M", "HT", "1T", "128", "32", - "MKK", "5G", "20M", "HT", "1T", "128", "33", - "IC", "5G", "20M", "HT", "1T", "128", "63", - "KCC", "5G", "20M", "HT", "1T", "128", "33", - "ACMA", "5G", "20M", "HT", "1T", "128", "63", - "CHILE", "5G", "20M", "HT", "1T", "128", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "128", "27", - "MEXICO", "5G", "20M", "HT", "1T", "128", "33", - "FCC", "5G", "20M", "HT", "1T", "132", "33", - "ETSI", "5G", "20M", "HT", "1T", "132", "32", - "MKK", "5G", "20M", "HT", "1T", "132", "33", - "IC", "5G", "20M", "HT", "1T", "132", "33", - "KCC", "5G", "20M", "HT", "1T", "132", "33", - "ACMA", "5G", "20M", "HT", "1T", "132", "32", - "CHILE", "5G", "20M", "HT", "1T", "132", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "132", "27", - "MEXICO", "5G", "20M", "HT", "1T", "132", "33", - "FCC", "5G", "20M", "HT", "1T", "136", "33", - "ETSI", "5G", "20M", "HT", "1T", "136", "32", - "MKK", "5G", "20M", "HT", "1T", "136", "33", - "IC", "5G", "20M", "HT", "1T", "136", "33", - "KCC", "5G", "20M", "HT", "1T", "136", "33", - "ACMA", "5G", "20M", "HT", "1T", "136", "32", - "CHILE", "5G", "20M", "HT", "1T", "136", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "136", "63", - "MEXICO", "5G", "20M", "HT", "1T", "136", "33", - "FCC", "5G", "20M", "HT", "1T", "140", "29", - "ETSI", "5G", "20M", "HT", "1T", "140", "32", - "MKK", "5G", "20M", "HT", "1T", "140", "33", - "IC", "5G", "20M", "HT", "1T", "140", "29", - "KCC", "5G", "20M", "HT", "1T", "140", "33", - "ACMA", "5G", "20M", "HT", "1T", "140", "32", - "CHILE", "5G", "20M", "HT", "1T", "140", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "140", "63", - "MEXICO", "5G", "20M", "HT", "1T", "140", "29", - "FCC", "5G", "20M", "HT", "1T", "144", "27", - "ETSI", "5G", "20M", "HT", "1T", "144", "63", - "MKK", "5G", "20M", "HT", "1T", "144", "63", - "IC", "5G", "20M", "HT", "1T", "144", "27", - "KCC", "5G", "20M", "HT", "1T", "144", "33", - "ACMA", "5G", "20M", "HT", "1T", "144", "63", - "CHILE", "5G", "20M", "HT", "1T", "144", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "144", "63", - "MEXICO", "5G", "20M", "HT", "1T", "144", "27", - "FCC", "5G", "20M", "HT", "1T", "149", "33", - "ETSI", "5G", "20M", "HT", "1T", "149", "-63", - "MKK", "5G", "20M", "HT", "1T", "149", "63", - "IC", "5G", "20M", "HT", "1T", "149", "33", - "KCC", "5G", "20M", "HT", "1T", "149", "33", - "ACMA", "5G", "20M", "HT", "1T", "149", "33", - "CHILE", "5G", "20M", "HT", "1T", "149", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "149", "27", - "MEXICO", "5G", "20M", "HT", "1T", "149", "33", - "FCC", "5G", "20M", "HT", "1T", "153", "33", - "ETSI", "5G", "20M", "HT", "1T", "153", "-63", - "MKK", "5G", "20M", "HT", "1T", "153", "63", - "IC", "5G", "20M", "HT", "1T", "153", "33", - "KCC", "5G", "20M", "HT", "1T", "153", "33", - "ACMA", "5G", "20M", "HT", "1T", "153", "33", - "CHILE", "5G", "20M", "HT", "1T", "153", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "153", "27", - "MEXICO", "5G", "20M", "HT", "1T", "153", "33", - "FCC", "5G", "20M", "HT", "1T", "157", "33", - "ETSI", "5G", "20M", "HT", "1T", "157", "-63", - "MKK", "5G", "20M", "HT", "1T", "157", "63", - "IC", "5G", "20M", "HT", "1T", "157", "33", - "KCC", "5G", "20M", "HT", "1T", "157", "33", - "ACMA", "5G", "20M", "HT", "1T", "157", "33", - "CHILE", "5G", "20M", "HT", "1T", "157", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "157", "27", - "MEXICO", "5G", "20M", "HT", "1T", "157", "33", - "FCC", "5G", "20M", "HT", "1T", "161", "33", - "ETSI", "5G", "20M", "HT", "1T", "161", "-63", - "MKK", "5G", "20M", "HT", "1T", "161", "63", - "IC", "5G", "20M", "HT", "1T", "161", "33", - "KCC", "5G", "20M", "HT", "1T", "161", "31", - "ACMA", "5G", "20M", "HT", "1T", "161", "33", - "CHILE", "5G", "20M", "HT", "1T", "161", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "161", "27", - "MEXICO", "5G", "20M", "HT", "1T", "161", "33", - "FCC", "5G", "20M", "HT", "1T", "165", "33", - "ETSI", "5G", "20M", "HT", "1T", "165", "-63", - "MKK", "5G", "20M", "HT", "1T", "165", "63", - "IC", "5G", "20M", "HT", "1T", "165", "33", - "KCC", "5G", "20M", "HT", "1T", "165", "33", - "ACMA", "5G", "20M", "HT", "1T", "165", "33", - "CHILE", "5G", "20M", "HT", "1T", "165", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "165", "27", - "MEXICO", "5G", "20M", "HT", "1T", "165", "30", - "FCC", "5G", "40M", "HT", "1T", "38", "22", - "ETSI", "5G", "40M", "HT", "1T", "38", "32", - "MKK", "5G", "40M", "HT", "1T", "38", "32", - "IC", "5G", "40M", "HT", "1T", "38", "22", - "KCC", "5G", "40M", "HT", "1T", "38", "26", - "ACMA", "5G", "40M", "HT", "1T", "38", "32", - "CHILE", "5G", "40M", "HT", "1T", "38", "22", - "UKRAINE", "5G", "40M", "HT", "1T", "38", "27", - "MEXICO", "5G", "40M", "HT", "1T", "38", "22", - "FCC", "5G", "40M", "HT", "1T", "46", "32", - "ETSI", "5G", "40M", "HT", "1T", "46", "32", - "MKK", "5G", "40M", "HT", "1T", "46", "32", - "IC", "5G", "40M", "HT", "1T", "46", "32", - "KCC", "5G", "40M", "HT", "1T", "46", "28", - "ACMA", "5G", "40M", "HT", "1T", "46", "32", - "CHILE", "5G", "40M", "HT", "1T", "46", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "46", "27", - "MEXICO", "5G", "40M", "HT", "1T", "46", "31", - "FCC", "5G", "40M", "HT", "1T", "54", "32", - "ETSI", "5G", "40M", "HT", "1T", "54", "32", - "MKK", "5G", "40M", "HT", "1T", "54", "32", - "IC", "5G", "40M", "HT", "1T", "54", "32", - "KCC", "5G", "40M", "HT", "1T", "54", "22", - "ACMA", "5G", "40M", "HT", "1T", "54", "32", - "CHILE", "5G", "40M", "HT", "1T", "54", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "54", "27", - "MEXICO", "5G", "40M", "HT", "1T", "54", "32", - "FCC", "5G", "40M", "HT", "1T", "62", "23", - "ETSI", "5G", "40M", "HT", "1T", "62", "32", - "MKK", "5G", "40M", "HT", "1T", "62", "32", - "IC", "5G", "40M", "HT", "1T", "62", "23", - "KCC", "5G", "40M", "HT", "1T", "62", "31", - "ACMA", "5G", "40M", "HT", "1T", "62", "32", - "CHILE", "5G", "40M", "HT", "1T", "62", "23", - "UKRAINE", "5G", "40M", "HT", "1T", "62", "27", - "MEXICO", "5G", "40M", "HT", "1T", "62", "23", - "FCC", "5G", "40M", "HT", "1T", "102", "21", - "ETSI", "5G", "40M", "HT", "1T", "102", "32", - "MKK", "5G", "40M", "HT", "1T", "102", "32", - "IC", "5G", "40M", "HT", "1T", "102", "21", - "KCC", "5G", "40M", "HT", "1T", "102", "31", - "ACMA", "5G", "40M", "HT", "1T", "102", "32", - "CHILE", "5G", "40M", "HT", "1T", "102", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "102", "27", - "MEXICO", "5G", "40M", "HT", "1T", "102", "21", - "FCC", "5G", "40M", "HT", "1T", "110", "32", - "ETSI", "5G", "40M", "HT", "1T", "110", "32", - "MKK", "5G", "40M", "HT", "1T", "110", "32", - "IC", "5G", "40M", "HT", "1T", "110", "32", - "KCC", "5G", "40M", "HT", "1T", "110", "32", - "ACMA", "5G", "40M", "HT", "1T", "110", "32", - "CHILE", "5G", "40M", "HT", "1T", "110", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "110", "27", - "MEXICO", "5G", "40M", "HT", "1T", "110", "32", - "FCC", "5G", "40M", "HT", "1T", "118", "32", - "ETSI", "5G", "40M", "HT", "1T", "118", "32", - "MKK", "5G", "40M", "HT", "1T", "118", "32", - "IC", "5G", "40M", "HT", "1T", "118", "63", - "KCC", "5G", "40M", "HT", "1T", "118", "32", - "ACMA", "5G", "40M", "HT", "1T", "118", "63", - "CHILE", "5G", "40M", "HT", "1T", "118", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "118", "27", - "MEXICO", "5G", "40M", "HT", "1T", "118", "32", - "FCC", "5G", "40M", "HT", "1T", "126", "32", - "ETSI", "5G", "40M", "HT", "1T", "126", "32", - "MKK", "5G", "40M", "HT", "1T", "126", "32", - "IC", "5G", "40M", "HT", "1T", "126", "63", - "KCC", "5G", "40M", "HT", "1T", "126", "32", - "ACMA", "5G", "40M", "HT", "1T", "126", "63", - "CHILE", "5G", "40M", "HT", "1T", "126", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "126", "27", - "MEXICO", "5G", "40M", "HT", "1T", "126", "32", - "FCC", "5G", "40M", "HT", "1T", "134", "32", - "ETSI", "5G", "40M", "HT", "1T", "134", "32", - "MKK", "5G", "40M", "HT", "1T", "134", "32", - "IC", "5G", "40M", "HT", "1T", "134", "32", - "KCC", "5G", "40M", "HT", "1T", "134", "32", - "ACMA", "5G", "40M", "HT", "1T", "134", "32", - "CHILE", "5G", "40M", "HT", "1T", "134", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "134", "63", - "MEXICO", "5G", "40M", "HT", "1T", "134", "32", - "FCC", "5G", "40M", "HT", "1T", "142", "29", - "ETSI", "5G", "40M", "HT", "1T", "142", "63", - "MKK", "5G", "40M", "HT", "1T", "142", "63", - "IC", "5G", "40M", "HT", "1T", "142", "29", - "KCC", "5G", "40M", "HT", "1T", "142", "32", - "ACMA", "5G", "40M", "HT", "1T", "142", "63", - "CHILE", "5G", "40M", "HT", "1T", "142", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "142", "63", - "MEXICO", "5G", "40M", "HT", "1T", "142", "29", - "FCC", "5G", "40M", "HT", "1T", "151", "32", - "ETSI", "5G", "40M", "HT", "1T", "151", "-63", - "MKK", "5G", "40M", "HT", "1T", "151", "63", - "IC", "5G", "40M", "HT", "1T", "151", "32", - "KCC", "5G", "40M", "HT", "1T", "151", "27", - "ACMA", "5G", "40M", "HT", "1T", "151", "32", - "CHILE", "5G", "40M", "HT", "1T", "151", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "151", "27", - "MEXICO", "5G", "40M", "HT", "1T", "151", "32", - "FCC", "5G", "40M", "HT", "1T", "159", "32", - "ETSI", "5G", "40M", "HT", "1T", "159", "-63", - "MKK", "5G", "40M", "HT", "1T", "159", "63", - "IC", "5G", "40M", "HT", "1T", "159", "32", - "KCC", "5G", "40M", "HT", "1T", "159", "26", - "ACMA", "5G", "40M", "HT", "1T", "159", "32", - "CHILE", "5G", "40M", "HT", "1T", "159", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "159", "27", - "MEXICO", "5G", "40M", "HT", "1T", "159", "32", - "FCC", "5G", "80M", "VHT", "1T", "42", "19", - "ETSI", "5G", "80M", "VHT", "1T", "42", "32", - "MKK", "5G", "80M", "VHT", "1T", "42", "28", - "IC", "5G", "80M", "VHT", "1T", "42", "19", - "KCC", "5G", "80M", "VHT", "1T", "42", "25", - "ACMA", "5G", "80M", "VHT", "1T", "42", "32", - "CHILE", "5G", "80M", "VHT", "1T", "42", "19", - "UKRAINE", "5G", "80M", "VHT", "1T", "42", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "42", "19", - "FCC", "5G", "80M", "VHT", "1T", "58", "22", - "ETSI", "5G", "80M", "VHT", "1T", "58", "32", - "MKK", "5G", "80M", "VHT", "1T", "58", "28", - "IC", "5G", "80M", "VHT", "1T", "58", "22", - "KCC", "5G", "80M", "VHT", "1T", "58", "28", - "ACMA", "5G", "80M", "VHT", "1T", "58", "32", - "CHILE", "5G", "80M", "VHT", "1T", "58", "22", - "UKRAINE", "5G", "80M", "VHT", "1T", "58", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "58", "22", - "FCC", "5G", "80M", "VHT", "1T", "106", "18", - "ETSI", "5G", "80M", "VHT", "1T", "106", "32", - "MKK", "5G", "80M", "VHT", "1T", "106", "32", - "IC", "5G", "80M", "VHT", "1T", "106", "18", - "KCC", "5G", "80M", "VHT", "1T", "106", "30", - "ACMA", "5G", "80M", "VHT", "1T", "106", "32", - "CHILE", "5G", "80M", "VHT", "1T", "106", "32", - "UKRAINE", "5G", "80M", "VHT", "1T", "106", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "106", "18", - "FCC", "5G", "80M", "VHT", "1T", "122", "32", - "ETSI", "5G", "80M", "VHT", "1T", "122", "32", - "MKK", "5G", "80M", "VHT", "1T", "122", "32", - "IC", "5G", "80M", "VHT", "1T", "122", "63", - "KCC", "5G", "80M", "VHT", "1T", "122", "26", - "ACMA", "5G", "80M", "VHT", "1T", "122", "63", - "CHILE", "5G", "80M", "VHT", "1T", "122", "32", - "UKRAINE", "5G", "80M", "VHT", "1T", "122", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "122", "32", - "FCC", "5G", "80M", "VHT", "1T", "138", "28", - "ETSI", "5G", "80M", "VHT", "1T", "138", "63", - "MKK", "5G", "80M", "VHT", "1T", "138", "63", - "IC", "5G", "80M", "VHT", "1T", "138", "28", - "KCC", "5G", "80M", "VHT", "1T", "138", "32", - "ACMA", "5G", "80M", "VHT", "1T", "138", "63", - "CHILE", "5G", "80M", "VHT", "1T", "138", "32", - "UKRAINE", "5G", "80M", "VHT", "1T", "138", "63", - "MEXICO", "5G", "80M", "VHT", "1T", "138", "28", - "FCC", "5G", "80M", "VHT", "1T", "155", "32", - "ETSI", "5G", "80M", "VHT", "1T", "155", "-63", - "MKK", "5G", "80M", "VHT", "1T", "155", "63", - "IC", "5G", "80M", "VHT", "1T", "155", "32", - "KCC", "5G", "80M", "VHT", "1T", "155", "27", - "ACMA", "5G", "80M", "VHT", "1T", "155", "32", - "CHILE", "5G", "80M", "VHT", "1T", "155", "32", - "UKRAINE", "5G", "80M", "VHT", "1T", "155", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "155", "32" +const struct txpwr_lmt_t_8821c array_mp_8821c_txpwr_lmt[] = { + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 24}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 24}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 24}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 24}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 28}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 28}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 28}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 20}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 20}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 20}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 20}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 31}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 29}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 31}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 16}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 31}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 29}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 29}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 7}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 29}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 29}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 29}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 27}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 22}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 22}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 22}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 22}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 22}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 23}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 23}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 23}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 23}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 21}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 21}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 21}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 29}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 29}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 29}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 28}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 25}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 22}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 28}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 22}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 22}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 22}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 18}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 18}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 18}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32} }; #endif @@ -4238,54 +4240,23 @@ odm_read_and_config_mp_8821c_txpwr_lmt(struct dm_struct *dm) { #ifdef CONFIG_8821C - u32 i = 0; -#if (DM_ODM_SUPPORT_TYPE == ODM_IOT) - u32 array_len = - sizeof(array_mp_8821c_txpwr_lmt) / sizeof(u8); - u8 *array = (u8 *)array_mp_8821c_txpwr_lmt; -#else - u32 array_len = - sizeof(array_mp_8821c_txpwr_lmt) / sizeof(u8 *); - u8 **array = (u8 **)array_mp_8821c_txpwr_lmt; -#endif - -#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) - void *adapter = dm->adapter; - HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter)); - - odm_memory_set(dm, hal_data->BufOfLinesPwrLmt, 0, - MAX_LINES_HWCONFIG_TXT * - MAX_BYTES_LINE_HWCONFIG_TXT); - hal_data->nLinesReadPwrLmt = array_len / 7; -#endif + int i = 0; + const struct txpwr_lmt_t_8821c *array = (const struct txpwr_lmt_t_8821c *)array_mp_8821c_txpwr_lmt; PHYDM_DBG(dm, ODM_COMP_INIT, "===> %s\n", __func__); - for (i = 0; i < array_len; i += 7) { -#if (DM_ODM_SUPPORT_TYPE == ODM_IOT) - u8 regulation = array[i]; - u8 band = array[i + 1]; - u8 bandwidth = array[i + 2]; - u8 rate = array[i + 3]; - u8 rf_path = array[i + 4]; - u8 chnl = array[i + 5]; - u8 val = array[i + 6]; -#else - u8 *regulation = array[i]; - u8 *band = array[i + 1]; - u8 *bandwidth = array[i + 2]; - u8 *rate = array[i + 3]; - u8 *rf_path = array[i + 4]; - u8 *chnl = array[i + 5]; - u8 *val = array[i + 6]; -#endif +#define array_len sizeof(array_mp_8821c_txpwr_lmt)/sizeof(struct txpwr_lmt_t_8821c) + for (i = 0; i < array_len; i++) { + u8 regulation = array[i].reg; + u8 band = array[i].band; + u8 bandwidth = array[i].bw; + u8 rate = array[i].rs; + u8 rf_path = array[i].ntx; + u8 chnl = array[i].ch; + s8 val = array[i].val; - odm_config_bb_txpwr_lmt_8821c(dm, regulation, band, bandwidth, + odm_config_bb_txpwr_lmt_8821c_ex(dm, regulation, band, bandwidth, rate, rf_path, chnl, val); -#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) - rsprintf((char *)hal_data->BufOfLinesPwrLmt[i / 7], 100, "\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\",", - regulation, band, bandwidth, rate, rf_path, chnl, val); -#endif } #endif @@ -4296,1123 +4267,1123 @@ odm_read_and_config_mp_8821c_txpwr_lmt(struct dm_struct *dm) ******************************************************************************/ #ifdef CONFIG_8821C_FCCSAR -const char *array_mp_8821c_txpwr_lmt_fccsar[] = { - "FCC", "2.4G", "20M", "CCK", "1T", "01", "30", - "ETSI", "2.4G", "20M", "CCK", "1T", "01", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "01", "34", - "IC", "2.4G", "20M", "CCK", "1T", "01", "30", - "KCC", "2.4G", "20M", "CCK", "1T", "01", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "01", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "01", "30", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "01", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "01", "30", - "FCC", "2.4G", "20M", "CCK", "1T", "02", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "02", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "02", "34", - "IC", "2.4G", "20M", "CCK", "1T", "02", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "02", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "02", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "02", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "02", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "02", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "03", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "03", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "03", "34", - "IC", "2.4G", "20M", "CCK", "1T", "03", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "03", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "03", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "03", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "03", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "03", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "04", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "04", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "04", "34", - "IC", "2.4G", "20M", "CCK", "1T", "04", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "04", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "04", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "04", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "04", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "04", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "05", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "05", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "05", "34", - "IC", "2.4G", "20M", "CCK", "1T", "05", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "05", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "05", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "05", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "05", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "05", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "06", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "06", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "06", "34", - "IC", "2.4G", "20M", "CCK", "1T", "06", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "06", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "06", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "06", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "06", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "06", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "07", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "07", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "07", "34", - "IC", "2.4G", "20M", "CCK", "1T", "07", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "07", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "07", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "07", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "07", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "07", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "08", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "08", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "08", "34", - "IC", "2.4G", "20M", "CCK", "1T", "08", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "08", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "08", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "08", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "08", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "08", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "09", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "09", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "09", "34", - "IC", "2.4G", "20M", "CCK", "1T", "09", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "09", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "09", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "09", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "09", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "09", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "10", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "10", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "10", "34", - "IC", "2.4G", "20M", "CCK", "1T", "10", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "10", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "10", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "10", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "10", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "10", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "11", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "11", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "11", "34", - "IC", "2.4G", "20M", "CCK", "1T", "11", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "11", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "11", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "11", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "11", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "11", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "12", "24", - "ETSI", "2.4G", "20M", "CCK", "1T", "12", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "12", "34", - "IC", "2.4G", "20M", "CCK", "1T", "12", "24", - "KCC", "2.4G", "20M", "CCK", "1T", "12", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "12", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "12", "24", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "12", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "12", "24", - "FCC", "2.4G", "20M", "CCK", "1T", "13", "16", - "ETSI", "2.4G", "20M", "CCK", "1T", "13", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "13", "34", - "IC", "2.4G", "20M", "CCK", "1T", "13", "16", - "KCC", "2.4G", "20M", "CCK", "1T", "13", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "13", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "13", "16", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "13", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "13", "16", - "FCC", "2.4G", "20M", "CCK", "1T", "14", "63", - "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63", - "MKK", "2.4G", "20M", "CCK", "1T", "14", "34", - "IC", "2.4G", "20M", "CCK", "1T", "14", "63", - "KCC", "2.4G", "20M", "CCK", "1T", "14", "63", - "ACMA", "2.4G", "20M", "CCK", "1T", "14", "63", - "CHILE", "2.4G", "20M", "CCK", "1T", "14", "63", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "14", "63", - "MEXICO", "2.4G", "20M", "CCK", "1T", "14", "63", - "FCC", "2.4G", "20M", "OFDM", "1T", "01", "30", - "ETSI", "2.4G", "20M", "OFDM", "1T", "01", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "01", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "01", "30", - "KCC", "2.4G", "20M", "OFDM", "1T", "01", "32", - "ACMA", "2.4G", "20M", "OFDM", "1T", "01", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "01", "30", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "01", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "01", "30", - "FCC", "2.4G", "20M", "OFDM", "1T", "02", "32", - "ETSI", "2.4G", "20M", "OFDM", "1T", "02", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "02", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "02", "32", - "KCC", "2.4G", "20M", "OFDM", "1T", "02", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "02", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "02", "32", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "02", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "02", "32", - "FCC", "2.4G", "20M", "OFDM", "1T", "03", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "03", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "03", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "03", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "03", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "03", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "03", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "03", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "04", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "04", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "04", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "04", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "04", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "04", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "04", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "04", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "04", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "05", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "05", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "05", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "05", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "05", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "05", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "05", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "05", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "05", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "06", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "06", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "06", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "06", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "06", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "06", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "06", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "06", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "07", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "07", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "07", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "07", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "07", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "07", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "07", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "07", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "07", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "08", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "08", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "08", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "08", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "08", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "08", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "08", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "08", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "08", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "09", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "09", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "09", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "09", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "09", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "09", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "09", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "09", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "10", "32", - "ETSI", "2.4G", "20M", "OFDM", "1T", "10", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "10", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "10", "32", - "KCC", "2.4G", "20M", "OFDM", "1T", "10", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "10", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "10", "32", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "10", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "10", "32", - "FCC", "2.4G", "20M", "OFDM", "1T", "11", "30", - "ETSI", "2.4G", "20M", "OFDM", "1T", "11", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "11", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "11", "30", - "KCC", "2.4G", "20M", "OFDM", "1T", "11", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "11", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "11", "30", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "11", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "11", "30", - "FCC", "2.4G", "20M", "OFDM", "1T", "12", "28", - "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "12", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "12", "28", - "KCC", "2.4G", "20M", "OFDM", "1T", "12", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "12", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "12", "28", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "12", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "12", "28", - "FCC", "2.4G", "20M", "OFDM", "1T", "13", "16", - "ETSI", "2.4G", "20M", "OFDM", "1T", "13", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "13", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "13", "16", - "KCC", "2.4G", "20M", "OFDM", "1T", "13", "32", - "ACMA", "2.4G", "20M", "OFDM", "1T", "13", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "13", "16", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "13", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "13", "16", - "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63", - "ETSI", "2.4G", "20M", "OFDM", "1T", "14", "63", - "MKK", "2.4G", "20M", "OFDM", "1T", "14", "63", - "IC", "2.4G", "20M", "OFDM", "1T", "14", "63", - "KCC", "2.4G", "20M", "OFDM", "1T", "14", "63", - "ACMA", "2.4G", "20M", "OFDM", "1T", "14", "63", - "CHILE", "2.4G", "20M", "OFDM", "1T", "14", "63", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "14", "63", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "14", "63", - "FCC", "2.4G", "20M", "HT", "1T", "01", "26", - "ETSI", "2.4G", "20M", "HT", "1T", "01", "30", - "MKK", "2.4G", "20M", "HT", "1T", "01", "34", - "IC", "2.4G", "20M", "HT", "1T", "01", "26", - "KCC", "2.4G", "20M", "HT", "1T", "01", "32", - "ACMA", "2.4G", "20M", "HT", "1T", "01", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "01", "26", - "UKRAINE", "2.4G", "20M", "HT", "1T", "01", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "01", "26", - "FCC", "2.4G", "20M", "HT", "1T", "02", "30", - "ETSI", "2.4G", "20M", "HT", "1T", "02", "30", - "MKK", "2.4G", "20M", "HT", "1T", "02", "34", - "IC", "2.4G", "20M", "HT", "1T", "02", "30", - "KCC", "2.4G", "20M", "HT", "1T", "02", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "02", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "02", "30", - "UKRAINE", "2.4G", "20M", "HT", "1T", "02", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "02", "30", - "FCC", "2.4G", "20M", "HT", "1T", "03", "32", - "ETSI", "2.4G", "20M", "HT", "1T", "03", "30", - "MKK", "2.4G", "20M", "HT", "1T", "03", "34", - "IC", "2.4G", "20M", "HT", "1T", "03", "32", - "KCC", "2.4G", "20M", "HT", "1T", "03", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "03", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "03", "32", - "UKRAINE", "2.4G", "20M", "HT", "1T", "03", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "03", "32", - "FCC", "2.4G", "20M", "HT", "1T", "04", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "04", "30", - "MKK", "2.4G", "20M", "HT", "1T", "04", "34", - "IC", "2.4G", "20M", "HT", "1T", "04", "34", - "KCC", "2.4G", "20M", "HT", "1T", "04", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "04", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "04", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "04", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "04", "34", - "FCC", "2.4G", "20M", "HT", "1T", "05", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "05", "30", - "MKK", "2.4G", "20M", "HT", "1T", "05", "34", - "IC", "2.4G", "20M", "HT", "1T", "05", "34", - "KCC", "2.4G", "20M", "HT", "1T", "05", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "05", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "05", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "05", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "05", "34", - "FCC", "2.4G", "20M", "HT", "1T", "06", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "06", "30", - "MKK", "2.4G", "20M", "HT", "1T", "06", "34", - "IC", "2.4G", "20M", "HT", "1T", "06", "34", - "KCC", "2.4G", "20M", "HT", "1T", "06", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "06", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "06", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "06", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "06", "34", - "FCC", "2.4G", "20M", "HT", "1T", "07", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "07", "30", - "MKK", "2.4G", "20M", "HT", "1T", "07", "34", - "IC", "2.4G", "20M", "HT", "1T", "07", "34", - "KCC", "2.4G", "20M", "HT", "1T", "07", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "07", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "07", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "07", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "07", "34", - "FCC", "2.4G", "20M", "HT", "1T", "08", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "08", "30", - "MKK", "2.4G", "20M", "HT", "1T", "08", "34", - "IC", "2.4G", "20M", "HT", "1T", "08", "34", - "KCC", "2.4G", "20M", "HT", "1T", "08", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "08", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "08", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "08", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "08", "34", - "FCC", "2.4G", "20M", "HT", "1T", "09", "32", - "ETSI", "2.4G", "20M", "HT", "1T", "09", "30", - "MKK", "2.4G", "20M", "HT", "1T", "09", "34", - "IC", "2.4G", "20M", "HT", "1T", "09", "32", - "KCC", "2.4G", "20M", "HT", "1T", "09", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "09", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "09", "32", - "UKRAINE", "2.4G", "20M", "HT", "1T", "09", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "09", "32", - "FCC", "2.4G", "20M", "HT", "1T", "10", "30", - "ETSI", "2.4G", "20M", "HT", "1T", "10", "30", - "MKK", "2.4G", "20M", "HT", "1T", "10", "34", - "IC", "2.4G", "20M", "HT", "1T", "10", "30", - "KCC", "2.4G", "20M", "HT", "1T", "10", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "10", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "10", "30", - "UKRAINE", "2.4G", "20M", "HT", "1T", "10", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "10", "30", - "FCC", "2.4G", "20M", "HT", "1T", "11", "28", - "ETSI", "2.4G", "20M", "HT", "1T", "11", "30", - "MKK", "2.4G", "20M", "HT", "1T", "11", "34", - "IC", "2.4G", "20M", "HT", "1T", "11", "28", - "KCC", "2.4G", "20M", "HT", "1T", "11", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "11", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "11", "28", - "UKRAINE", "2.4G", "20M", "HT", "1T", "11", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "11", "28", - "FCC", "2.4G", "20M", "HT", "1T", "12", "26", - "ETSI", "2.4G", "20M", "HT", "1T", "12", "30", - "MKK", "2.4G", "20M", "HT", "1T", "12", "34", - "IC", "2.4G", "20M", "HT", "1T", "12", "26", - "KCC", "2.4G", "20M", "HT", "1T", "12", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "12", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "12", "26", - "UKRAINE", "2.4G", "20M", "HT", "1T", "12", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "12", "26", - "FCC", "2.4G", "20M", "HT", "1T", "13", "12", - "ETSI", "2.4G", "20M", "HT", "1T", "13", "30", - "MKK", "2.4G", "20M", "HT", "1T", "13", "34", - "IC", "2.4G", "20M", "HT", "1T", "13", "12", - "KCC", "2.4G", "20M", "HT", "1T", "13", "32", - "ACMA", "2.4G", "20M", "HT", "1T", "13", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "13", "12", - "UKRAINE", "2.4G", "20M", "HT", "1T", "13", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "13", "12", - "FCC", "2.4G", "20M", "HT", "1T", "14", "63", - "ETSI", "2.4G", "20M", "HT", "1T", "14", "63", - "MKK", "2.4G", "20M", "HT", "1T", "14", "63", - "IC", "2.4G", "20M", "HT", "1T", "14", "63", - "KCC", "2.4G", "20M", "HT", "1T", "14", "63", - "ACMA", "2.4G", "20M", "HT", "1T", "14", "63", - "CHILE", "2.4G", "20M", "HT", "1T", "14", "63", - "UKRAINE", "2.4G", "20M", "HT", "1T", "14", "63", - "MEXICO", "2.4G", "20M", "HT", "1T", "14", "63", - "FCC", "2.4G", "40M", "HT", "1T", "01", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "01", "63", - "MKK", "2.4G", "40M", "HT", "1T", "01", "63", - "IC", "2.4G", "40M", "HT", "1T", "01", "63", - "KCC", "2.4G", "40M", "HT", "1T", "01", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "01", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "01", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "01", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "01", "63", - "FCC", "2.4G", "40M", "HT", "1T", "02", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "02", "63", - "MKK", "2.4G", "40M", "HT", "1T", "02", "63", - "IC", "2.4G", "40M", "HT", "1T", "02", "63", - "KCC", "2.4G", "40M", "HT", "1T", "02", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "02", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "02", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "02", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "02", "63", - "FCC", "2.4G", "40M", "HT", "1T", "03", "26", - "ETSI", "2.4G", "40M", "HT", "1T", "03", "30", - "MKK", "2.4G", "40M", "HT", "1T", "03", "30", - "IC", "2.4G", "40M", "HT", "1T", "03", "26", - "KCC", "2.4G", "40M", "HT", "1T", "03", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "03", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "03", "26", - "UKRAINE", "2.4G", "40M", "HT", "1T", "03", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "03", "26", - "FCC", "2.4G", "40M", "HT", "1T", "04", "26", - "ETSI", "2.4G", "40M", "HT", "1T", "04", "30", - "MKK", "2.4G", "40M", "HT", "1T", "04", "30", - "IC", "2.4G", "40M", "HT", "1T", "04", "26", - "KCC", "2.4G", "40M", "HT", "1T", "04", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "04", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "04", "26", - "UKRAINE", "2.4G", "40M", "HT", "1T", "04", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "04", "26", - "FCC", "2.4G", "40M", "HT", "1T", "05", "30", - "ETSI", "2.4G", "40M", "HT", "1T", "05", "30", - "MKK", "2.4G", "40M", "HT", "1T", "05", "30", - "IC", "2.4G", "40M", "HT", "1T", "05", "30", - "KCC", "2.4G", "40M", "HT", "1T", "05", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "05", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "05", "30", - "UKRAINE", "2.4G", "40M", "HT", "1T", "05", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "05", "30", - "FCC", "2.4G", "40M", "HT", "1T", "06", "30", - "ETSI", "2.4G", "40M", "HT", "1T", "06", "30", - "MKK", "2.4G", "40M", "HT", "1T", "06", "30", - "IC", "2.4G", "40M", "HT", "1T", "06", "30", - "KCC", "2.4G", "40M", "HT", "1T", "06", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "06", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "06", "30", - "UKRAINE", "2.4G", "40M", "HT", "1T", "06", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "06", "30", - "FCC", "2.4G", "40M", "HT", "1T", "07", "30", - "ETSI", "2.4G", "40M", "HT", "1T", "07", "30", - "MKK", "2.4G", "40M", "HT", "1T", "07", "30", - "IC", "2.4G", "40M", "HT", "1T", "07", "30", - "KCC", "2.4G", "40M", "HT", "1T", "07", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "07", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "07", "30", - "UKRAINE", "2.4G", "40M", "HT", "1T", "07", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "07", "30", - "FCC", "2.4G", "40M", "HT", "1T", "08", "26", - "ETSI", "2.4G", "40M", "HT", "1T", "08", "30", - "MKK", "2.4G", "40M", "HT", "1T", "08", "30", - "IC", "2.4G", "40M", "HT", "1T", "08", "26", - "KCC", "2.4G", "40M", "HT", "1T", "08", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "08", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "08", "26", - "UKRAINE", "2.4G", "40M", "HT", "1T", "08", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "08", "26", - "FCC", "2.4G", "40M", "HT", "1T", "09", "26", - "ETSI", "2.4G", "40M", "HT", "1T", "09", "30", - "MKK", "2.4G", "40M", "HT", "1T", "09", "30", - "IC", "2.4G", "40M", "HT", "1T", "09", "26", - "KCC", "2.4G", "40M", "HT", "1T", "09", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "09", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "09", "26", - "UKRAINE", "2.4G", "40M", "HT", "1T", "09", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "09", "26", - "FCC", "2.4G", "40M", "HT", "1T", "10", "28", - "ETSI", "2.4G", "40M", "HT", "1T", "10", "30", - "MKK", "2.4G", "40M", "HT", "1T", "10", "30", - "IC", "2.4G", "40M", "HT", "1T", "10", "28", - "KCC", "2.4G", "40M", "HT", "1T", "10", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "10", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "10", "28", - "UKRAINE", "2.4G", "40M", "HT", "1T", "10", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "10", "28", - "FCC", "2.4G", "40M", "HT", "1T", "11", "20", - "ETSI", "2.4G", "40M", "HT", "1T", "11", "30", - "MKK", "2.4G", "40M", "HT", "1T", "11", "30", - "IC", "2.4G", "40M", "HT", "1T", "11", "20", - "KCC", "2.4G", "40M", "HT", "1T", "11", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "11", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "11", "20", - "UKRAINE", "2.4G", "40M", "HT", "1T", "11", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "11", "20", - "FCC", "2.4G", "40M", "HT", "1T", "12", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "12", "63", - "MKK", "2.4G", "40M", "HT", "1T", "12", "63", - "IC", "2.4G", "40M", "HT", "1T", "12", "63", - "KCC", "2.4G", "40M", "HT", "1T", "12", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "12", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "12", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "12", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "12", "63", - "FCC", "2.4G", "40M", "HT", "1T", "13", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "13", "63", - "MKK", "2.4G", "40M", "HT", "1T", "13", "63", - "IC", "2.4G", "40M", "HT", "1T", "13", "63", - "KCC", "2.4G", "40M", "HT", "1T", "13", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "13", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "13", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "13", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "13", "63", - "FCC", "2.4G", "40M", "HT", "1T", "14", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "14", "63", - "MKK", "2.4G", "40M", "HT", "1T", "14", "63", - "IC", "2.4G", "40M", "HT", "1T", "14", "63", - "KCC", "2.4G", "40M", "HT", "1T", "14", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "14", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "14", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "14", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "14", "63", - "FCC", "5G", "20M", "OFDM", "1T", "36", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "36", "32", - "MKK", "5G", "20M", "OFDM", "1T", "36", "33", - "IC", "5G", "20M", "OFDM", "1T", "36", "31", - "KCC", "5G", "20M", "OFDM", "1T", "36", "29", - "ACMA", "5G", "20M", "OFDM", "1T", "36", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "36", "31", - "UKRAINE", "5G", "20M", "OFDM", "1T", "36", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "36", "31", - "FCC", "5G", "20M", "OFDM", "1T", "40", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "40", "32", - "MKK", "5G", "20M", "OFDM", "1T", "40", "33", - "IC", "5G", "20M", "OFDM", "1T", "40", "31", - "KCC", "5G", "20M", "OFDM", "1T", "40", "28", - "ACMA", "5G", "20M", "OFDM", "1T", "40", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "40", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "40", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "40", "31", - "FCC", "5G", "20M", "OFDM", "1T", "44", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "44", "32", - "MKK", "5G", "20M", "OFDM", "1T", "44", "33", - "IC", "5G", "20M", "OFDM", "1T", "44", "31", - "KCC", "5G", "20M", "OFDM", "1T", "44", "28", - "ACMA", "5G", "20M", "OFDM", "1T", "44", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "44", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "44", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "44", "31", - "FCC", "5G", "20M", "OFDM", "1T", "48", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "48", "32", - "MKK", "5G", "20M", "OFDM", "1T", "48", "33", - "IC", "5G", "20M", "OFDM", "1T", "48", "31", - "KCC", "5G", "20M", "OFDM", "1T", "48", "27", - "ACMA", "5G", "20M", "OFDM", "1T", "48", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "48", "31", - "UKRAINE", "5G", "20M", "OFDM", "1T", "48", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "48", "31", - "FCC", "5G", "20M", "OFDM", "1T", "52", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "52", "32", - "MKK", "5G", "20M", "OFDM", "1T", "52", "33", - "IC", "5G", "20M", "OFDM", "1T", "52", "32", - "KCC", "5G", "20M", "OFDM", "1T", "52", "16", - "ACMA", "5G", "20M", "OFDM", "1T", "52", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "52", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "52", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "52", "33", - "FCC", "5G", "20M", "OFDM", "1T", "56", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "56", "32", - "MKK", "5G", "20M", "OFDM", "1T", "56", "33", - "IC", "5G", "20M", "OFDM", "1T", "56", "32", - "KCC", "5G", "20M", "OFDM", "1T", "56", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "56", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "56", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "56", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "56", "33", - "FCC", "5G", "20M", "OFDM", "1T", "60", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "60", "32", - "MKK", "5G", "20M", "OFDM", "1T", "60", "33", - "IC", "5G", "20M", "OFDM", "1T", "60", "32", - "KCC", "5G", "20M", "OFDM", "1T", "60", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "60", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "60", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "60", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "60", "33", - "FCC", "5G", "20M", "OFDM", "1T", "64", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "64", "32", - "MKK", "5G", "20M", "OFDM", "1T", "64", "33", - "IC", "5G", "20M", "OFDM", "1T", "64", "30", - "KCC", "5G", "20M", "OFDM", "1T", "64", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "64", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "64", "30", - "UKRAINE", "5G", "20M", "OFDM", "1T", "64", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "64", "30", - "FCC", "5G", "20M", "OFDM", "1T", "100", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "100", "32", - "MKK", "5G", "20M", "OFDM", "1T", "100", "33", - "IC", "5G", "20M", "OFDM", "1T", "100", "30", - "KCC", "5G", "20M", "OFDM", "1T", "100", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "100", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "100", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "100", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "100", "30", - "FCC", "5G", "20M", "OFDM", "1T", "104", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "104", "32", - "MKK", "5G", "20M", "OFDM", "1T", "104", "33", - "IC", "5G", "20M", "OFDM", "1T", "104", "33", - "KCC", "5G", "20M", "OFDM", "1T", "104", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "104", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "104", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "104", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "104", "33", - "FCC", "5G", "20M", "OFDM", "1T", "108", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "108", "32", - "MKK", "5G", "20M", "OFDM", "1T", "108", "33", - "IC", "5G", "20M", "OFDM", "1T", "108", "33", - "KCC", "5G", "20M", "OFDM", "1T", "108", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "108", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "108", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "108", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "108", "33", - "FCC", "5G", "20M", "OFDM", "1T", "112", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "112", "32", - "MKK", "5G", "20M", "OFDM", "1T", "112", "33", - "IC", "5G", "20M", "OFDM", "1T", "112", "33", - "KCC", "5G", "20M", "OFDM", "1T", "112", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "112", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "112", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "112", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "112", "33", - "FCC", "5G", "20M", "OFDM", "1T", "116", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "116", "32", - "MKK", "5G", "20M", "OFDM", "1T", "116", "33", - "IC", "5G", "20M", "OFDM", "1T", "116", "33", - "KCC", "5G", "20M", "OFDM", "1T", "116", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "116", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "116", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "116", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "116", "33", - "FCC", "5G", "20M", "OFDM", "1T", "120", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "120", "32", - "MKK", "5G", "20M", "OFDM", "1T", "120", "33", - "IC", "5G", "20M", "OFDM", "1T", "120", "63", - "KCC", "5G", "20M", "OFDM", "1T", "120", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "120", "63", - "CHILE", "5G", "20M", "OFDM", "1T", "120", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "120", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "120", "33", - "FCC", "5G", "20M", "OFDM", "1T", "124", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "124", "32", - "MKK", "5G", "20M", "OFDM", "1T", "124", "33", - "IC", "5G", "20M", "OFDM", "1T", "124", "63", - "KCC", "5G", "20M", "OFDM", "1T", "124", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "124", "63", - "CHILE", "5G", "20M", "OFDM", "1T", "124", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "124", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "124", "33", - "FCC", "5G", "20M", "OFDM", "1T", "128", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "128", "32", - "MKK", "5G", "20M", "OFDM", "1T", "128", "33", - "IC", "5G", "20M", "OFDM", "1T", "128", "63", - "KCC", "5G", "20M", "OFDM", "1T", "128", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "128", "63", - "CHILE", "5G", "20M", "OFDM", "1T", "128", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "128", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "128", "33", - "FCC", "5G", "20M", "OFDM", "1T", "132", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "132", "32", - "MKK", "5G", "20M", "OFDM", "1T", "132", "33", - "IC", "5G", "20M", "OFDM", "1T", "132", "33", - "KCC", "5G", "20M", "OFDM", "1T", "132", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "132", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "132", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "132", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "132", "33", - "FCC", "5G", "20M", "OFDM", "1T", "136", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "136", "32", - "MKK", "5G", "20M", "OFDM", "1T", "136", "33", - "IC", "5G", "20M", "OFDM", "1T", "136", "33", - "KCC", "5G", "20M", "OFDM", "1T", "136", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "136", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "136", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "136", "63", - "MEXICO", "5G", "20M", "OFDM", "1T", "136", "33", - "FCC", "5G", "20M", "OFDM", "1T", "140", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "140", "32", - "MKK", "5G", "20M", "OFDM", "1T", "140", "33", - "IC", "5G", "20M", "OFDM", "1T", "140", "31", - "KCC", "5G", "20M", "OFDM", "1T", "140", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "140", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "140", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "140", "63", - "MEXICO", "5G", "20M", "OFDM", "1T", "140", "31", - "FCC", "5G", "20M", "OFDM", "1T", "144", "27", - "ETSI", "5G", "20M", "OFDM", "1T", "144", "63", - "MKK", "5G", "20M", "OFDM", "1T", "144", "63", - "IC", "5G", "20M", "OFDM", "1T", "144", "30", - "KCC", "5G", "20M", "OFDM", "1T", "144", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "144", "63", - "CHILE", "5G", "20M", "OFDM", "1T", "144", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "144", "63", - "MEXICO", "5G", "20M", "OFDM", "1T", "144", "30", - "FCC", "5G", "20M", "OFDM", "1T", "149", "28", - "ETSI", "5G", "20M", "OFDM", "1T", "149", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "149", "63", - "IC", "5G", "20M", "OFDM", "1T", "149", "30", - "KCC", "5G", "20M", "OFDM", "1T", "149", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "149", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "149", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "149", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "149", "33", - "FCC", "5G", "20M", "OFDM", "1T", "153", "28", - "ETSI", "5G", "20M", "OFDM", "1T", "153", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "153", "63", - "IC", "5G", "20M", "OFDM", "1T", "153", "33", - "KCC", "5G", "20M", "OFDM", "1T", "153", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "153", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "153", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "153", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "153", "33", - "FCC", "5G", "20M", "OFDM", "1T", "157", "28", - "ETSI", "5G", "20M", "OFDM", "1T", "157", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "157", "63", - "IC", "5G", "20M", "OFDM", "1T", "157", "33", - "KCC", "5G", "20M", "OFDM", "1T", "157", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "157", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "157", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "157", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "157", "33", - "FCC", "5G", "20M", "OFDM", "1T", "161", "28", - "ETSI", "5G", "20M", "OFDM", "1T", "161", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "161", "63", - "IC", "5G", "20M", "OFDM", "1T", "161", "33", - "KCC", "5G", "20M", "OFDM", "1T", "161", "31", - "ACMA", "5G", "20M", "OFDM", "1T", "161", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "161", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "161", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "161", "33", - "FCC", "5G", "20M", "OFDM", "1T", "165", "28", - "ETSI", "5G", "20M", "OFDM", "1T", "165", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "165", "63", - "IC", "5G", "20M", "OFDM", "1T", "165", "33", - "KCC", "5G", "20M", "OFDM", "1T", "165", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "165", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "165", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "165", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "165", "30", - "FCC", "5G", "20M", "HT", "1T", "36", "27", - "ETSI", "5G", "20M", "HT", "1T", "36", "32", - "MKK", "5G", "20M", "HT", "1T", "36", "33", - "IC", "5G", "20M", "HT", "1T", "36", "30", - "KCC", "5G", "20M", "HT", "1T", "36", "27", - "ACMA", "5G", "20M", "HT", "1T", "36", "32", - "CHILE", "5G", "20M", "HT", "1T", "36", "30", - "UKRAINE", "5G", "20M", "HT", "1T", "36", "27", - "MEXICO", "5G", "20M", "HT", "1T", "36", "30", - "FCC", "5G", "20M", "HT", "1T", "40", "27", - "ETSI", "5G", "20M", "HT", "1T", "40", "32", - "MKK", "5G", "20M", "HT", "1T", "40", "33", - "IC", "5G", "20M", "HT", "1T", "40", "31", - "KCC", "5G", "20M", "HT", "1T", "40", "29", - "ACMA", "5G", "20M", "HT", "1T", "40", "32", - "CHILE", "5G", "20M", "HT", "1T", "40", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "40", "27", - "MEXICO", "5G", "20M", "HT", "1T", "40", "31", - "FCC", "5G", "20M", "HT", "1T", "44", "27", - "ETSI", "5G", "20M", "HT", "1T", "44", "32", - "MKK", "5G", "20M", "HT", "1T", "44", "33", - "IC", "5G", "20M", "HT", "1T", "44", "31", - "KCC", "5G", "20M", "HT", "1T", "44", "29", - "ACMA", "5G", "20M", "HT", "1T", "44", "32", - "CHILE", "5G", "20M", "HT", "1T", "44", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "44", "27", - "MEXICO", "5G", "20M", "HT", "1T", "44", "31", - "FCC", "5G", "20M", "HT", "1T", "48", "27", - "ETSI", "5G", "20M", "HT", "1T", "48", "32", - "MKK", "5G", "20M", "HT", "1T", "48", "33", - "IC", "5G", "20M", "HT", "1T", "48", "31", - "KCC", "5G", "20M", "HT", "1T", "48", "26", - "ACMA", "5G", "20M", "HT", "1T", "48", "32", - "CHILE", "5G", "20M", "HT", "1T", "48", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "48", "27", - "MEXICO", "5G", "20M", "HT", "1T", "48", "31", - "FCC", "5G", "20M", "HT", "1T", "52", "27", - "ETSI", "5G", "20M", "HT", "1T", "52", "32", - "MKK", "5G", "20M", "HT", "1T", "52", "33", - "IC", "5G", "20M", "HT", "1T", "52", "32", - "KCC", "5G", "20M", "HT", "1T", "52", "7", - "ACMA", "5G", "20M", "HT", "1T", "52", "32", - "CHILE", "5G", "20M", "HT", "1T", "52", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "52", "27", - "MEXICO", "5G", "20M", "HT", "1T", "52", "33", - "FCC", "5G", "20M", "HT", "1T", "56", "27", - "ETSI", "5G", "20M", "HT", "1T", "56", "32", - "MKK", "5G", "20M", "HT", "1T", "56", "33", - "IC", "5G", "20M", "HT", "1T", "56", "32", - "KCC", "5G", "20M", "HT", "1T", "56", "33", - "ACMA", "5G", "20M", "HT", "1T", "56", "32", - "CHILE", "5G", "20M", "HT", "1T", "56", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "56", "27", - "MEXICO", "5G", "20M", "HT", "1T", "56", "33", - "FCC", "5G", "20M", "HT", "1T", "60", "27", - "ETSI", "5G", "20M", "HT", "1T", "60", "32", - "MKK", "5G", "20M", "HT", "1T", "60", "33", - "IC", "5G", "20M", "HT", "1T", "60", "32", - "KCC", "5G", "20M", "HT", "1T", "60", "33", - "ACMA", "5G", "20M", "HT", "1T", "60", "32", - "CHILE", "5G", "20M", "HT", "1T", "60", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "60", "27", - "MEXICO", "5G", "20M", "HT", "1T", "60", "33", - "FCC", "5G", "20M", "HT", "1T", "64", "27", - "ETSI", "5G", "20M", "HT", "1T", "64", "32", - "MKK", "5G", "20M", "HT", "1T", "64", "33", - "IC", "5G", "20M", "HT", "1T", "64", "30", - "KCC", "5G", "20M", "HT", "1T", "64", "33", - "ACMA", "5G", "20M", "HT", "1T", "64", "32", - "CHILE", "5G", "20M", "HT", "1T", "64", "30", - "UKRAINE", "5G", "20M", "HT", "1T", "64", "27", - "MEXICO", "5G", "20M", "HT", "1T", "64", "30", - "FCC", "5G", "20M", "HT", "1T", "100", "27", - "ETSI", "5G", "20M", "HT", "1T", "100", "32", - "MKK", "5G", "20M", "HT", "1T", "100", "33", - "IC", "5G", "20M", "HT", "1T", "100", "30", - "KCC", "5G", "20M", "HT", "1T", "100", "33", - "ACMA", "5G", "20M", "HT", "1T", "100", "32", - "CHILE", "5G", "20M", "HT", "1T", "100", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "100", "27", - "MEXICO", "5G", "20M", "HT", "1T", "100", "30", - "FCC", "5G", "20M", "HT", "1T", "104", "27", - "ETSI", "5G", "20M", "HT", "1T", "104", "32", - "MKK", "5G", "20M", "HT", "1T", "104", "33", - "IC", "5G", "20M", "HT", "1T", "104", "33", - "KCC", "5G", "20M", "HT", "1T", "104", "33", - "ACMA", "5G", "20M", "HT", "1T", "104", "32", - "CHILE", "5G", "20M", "HT", "1T", "104", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "104", "27", - "MEXICO", "5G", "20M", "HT", "1T", "104", "33", - "FCC", "5G", "20M", "HT", "1T", "108", "27", - "ETSI", "5G", "20M", "HT", "1T", "108", "32", - "MKK", "5G", "20M", "HT", "1T", "108", "33", - "IC", "5G", "20M", "HT", "1T", "108", "33", - "KCC", "5G", "20M", "HT", "1T", "108", "33", - "ACMA", "5G", "20M", "HT", "1T", "108", "32", - "CHILE", "5G", "20M", "HT", "1T", "108", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "108", "27", - "MEXICO", "5G", "20M", "HT", "1T", "108", "33", - "FCC", "5G", "20M", "HT", "1T", "112", "27", - "ETSI", "5G", "20M", "HT", "1T", "112", "32", - "MKK", "5G", "20M", "HT", "1T", "112", "33", - "IC", "5G", "20M", "HT", "1T", "112", "33", - "KCC", "5G", "20M", "HT", "1T", "112", "33", - "ACMA", "5G", "20M", "HT", "1T", "112", "32", - "CHILE", "5G", "20M", "HT", "1T", "112", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "112", "27", - "MEXICO", "5G", "20M", "HT", "1T", "112", "33", - "FCC", "5G", "20M", "HT", "1T", "116", "27", - "ETSI", "5G", "20M", "HT", "1T", "116", "32", - "MKK", "5G", "20M", "HT", "1T", "116", "33", - "IC", "5G", "20M", "HT", "1T", "116", "33", - "KCC", "5G", "20M", "HT", "1T", "116", "33", - "ACMA", "5G", "20M", "HT", "1T", "116", "32", - "CHILE", "5G", "20M", "HT", "1T", "116", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "116", "27", - "MEXICO", "5G", "20M", "HT", "1T", "116", "33", - "FCC", "5G", "20M", "HT", "1T", "120", "27", - "ETSI", "5G", "20M", "HT", "1T", "120", "32", - "MKK", "5G", "20M", "HT", "1T", "120", "33", - "IC", "5G", "20M", "HT", "1T", "120", "63", - "KCC", "5G", "20M", "HT", "1T", "120", "33", - "ACMA", "5G", "20M", "HT", "1T", "120", "63", - "CHILE", "5G", "20M", "HT", "1T", "120", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "120", "27", - "MEXICO", "5G", "20M", "HT", "1T", "120", "33", - "FCC", "5G", "20M", "HT", "1T", "124", "27", - "ETSI", "5G", "20M", "HT", "1T", "124", "32", - "MKK", "5G", "20M", "HT", "1T", "124", "33", - "IC", "5G", "20M", "HT", "1T", "124", "63", - "KCC", "5G", "20M", "HT", "1T", "124", "33", - "ACMA", "5G", "20M", "HT", "1T", "124", "63", - "CHILE", "5G", "20M", "HT", "1T", "124", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "124", "27", - "MEXICO", "5G", "20M", "HT", "1T", "124", "33", - "FCC", "5G", "20M", "HT", "1T", "128", "27", - "ETSI", "5G", "20M", "HT", "1T", "128", "32", - "MKK", "5G", "20M", "HT", "1T", "128", "33", - "IC", "5G", "20M", "HT", "1T", "128", "63", - "KCC", "5G", "20M", "HT", "1T", "128", "33", - "ACMA", "5G", "20M", "HT", "1T", "128", "63", - "CHILE", "5G", "20M", "HT", "1T", "128", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "128", "27", - "MEXICO", "5G", "20M", "HT", "1T", "128", "33", - "FCC", "5G", "20M", "HT", "1T", "132", "27", - "ETSI", "5G", "20M", "HT", "1T", "132", "32", - "MKK", "5G", "20M", "HT", "1T", "132", "33", - "IC", "5G", "20M", "HT", "1T", "132", "33", - "KCC", "5G", "20M", "HT", "1T", "132", "33", - "ACMA", "5G", "20M", "HT", "1T", "132", "32", - "CHILE", "5G", "20M", "HT", "1T", "132", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "132", "27", - "MEXICO", "5G", "20M", "HT", "1T", "132", "33", - "FCC", "5G", "20M", "HT", "1T", "136", "27", - "ETSI", "5G", "20M", "HT", "1T", "136", "32", - "MKK", "5G", "20M", "HT", "1T", "136", "33", - "IC", "5G", "20M", "HT", "1T", "136", "33", - "KCC", "5G", "20M", "HT", "1T", "136", "33", - "ACMA", "5G", "20M", "HT", "1T", "136", "32", - "CHILE", "5G", "20M", "HT", "1T", "136", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "136", "63", - "MEXICO", "5G", "20M", "HT", "1T", "136", "33", - "FCC", "5G", "20M", "HT", "1T", "140", "27", - "ETSI", "5G", "20M", "HT", "1T", "140", "32", - "MKK", "5G", "20M", "HT", "1T", "140", "33", - "IC", "5G", "20M", "HT", "1T", "140", "29", - "KCC", "5G", "20M", "HT", "1T", "140", "33", - "ACMA", "5G", "20M", "HT", "1T", "140", "32", - "CHILE", "5G", "20M", "HT", "1T", "140", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "140", "63", - "MEXICO", "5G", "20M", "HT", "1T", "140", "29", - "FCC", "5G", "20M", "HT", "1T", "144", "27", - "ETSI", "5G", "20M", "HT", "1T", "144", "63", - "MKK", "5G", "20M", "HT", "1T", "144", "63", - "IC", "5G", "20M", "HT", "1T", "144", "27", - "KCC", "5G", "20M", "HT", "1T", "144", "33", - "ACMA", "5G", "20M", "HT", "1T", "144", "63", - "CHILE", "5G", "20M", "HT", "1T", "144", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "144", "63", - "MEXICO", "5G", "20M", "HT", "1T", "144", "27", - "FCC", "5G", "20M", "HT", "1T", "149", "28", - "ETSI", "5G", "20M", "HT", "1T", "149", "-63", - "MKK", "5G", "20M", "HT", "1T", "149", "63", - "IC", "5G", "20M", "HT", "1T", "149", "33", - "KCC", "5G", "20M", "HT", "1T", "149", "33", - "ACMA", "5G", "20M", "HT", "1T", "149", "33", - "CHILE", "5G", "20M", "HT", "1T", "149", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "149", "27", - "MEXICO", "5G", "20M", "HT", "1T", "149", "33", - "FCC", "5G", "20M", "HT", "1T", "153", "28", - "ETSI", "5G", "20M", "HT", "1T", "153", "-63", - "MKK", "5G", "20M", "HT", "1T", "153", "63", - "IC", "5G", "20M", "HT", "1T", "153", "33", - "KCC", "5G", "20M", "HT", "1T", "153", "33", - "ACMA", "5G", "20M", "HT", "1T", "153", "33", - "CHILE", "5G", "20M", "HT", "1T", "153", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "153", "27", - "MEXICO", "5G", "20M", "HT", "1T", "153", "33", - "FCC", "5G", "20M", "HT", "1T", "157", "28", - "ETSI", "5G", "20M", "HT", "1T", "157", "-63", - "MKK", "5G", "20M", "HT", "1T", "157", "63", - "IC", "5G", "20M", "HT", "1T", "157", "33", - "KCC", "5G", "20M", "HT", "1T", "157", "33", - "ACMA", "5G", "20M", "HT", "1T", "157", "33", - "CHILE", "5G", "20M", "HT", "1T", "157", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "157", "27", - "MEXICO", "5G", "20M", "HT", "1T", "157", "33", - "FCC", "5G", "20M", "HT", "1T", "161", "28", - "ETSI", "5G", "20M", "HT", "1T", "161", "-63", - "MKK", "5G", "20M", "HT", "1T", "161", "63", - "IC", "5G", "20M", "HT", "1T", "161", "33", - "KCC", "5G", "20M", "HT", "1T", "161", "31", - "ACMA", "5G", "20M", "HT", "1T", "161", "33", - "CHILE", "5G", "20M", "HT", "1T", "161", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "161", "27", - "MEXICO", "5G", "20M", "HT", "1T", "161", "33", - "FCC", "5G", "20M", "HT", "1T", "165", "28", - "ETSI", "5G", "20M", "HT", "1T", "165", "-63", - "MKK", "5G", "20M", "HT", "1T", "165", "63", - "IC", "5G", "20M", "HT", "1T", "165", "33", - "KCC", "5G", "20M", "HT", "1T", "165", "33", - "ACMA", "5G", "20M", "HT", "1T", "165", "33", - "CHILE", "5G", "20M", "HT", "1T", "165", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "165", "27", - "MEXICO", "5G", "20M", "HT", "1T", "165", "30", - "FCC", "5G", "40M", "HT", "1T", "38", "22", - "ETSI", "5G", "40M", "HT", "1T", "38", "32", - "MKK", "5G", "40M", "HT", "1T", "38", "32", - "IC", "5G", "40M", "HT", "1T", "38", "22", - "KCC", "5G", "40M", "HT", "1T", "38", "26", - "ACMA", "5G", "40M", "HT", "1T", "38", "32", - "CHILE", "5G", "40M", "HT", "1T", "38", "22", - "UKRAINE", "5G", "40M", "HT", "1T", "38", "27", - "MEXICO", "5G", "40M", "HT", "1T", "38", "22", - "FCC", "5G", "40M", "HT", "1T", "46", "24", - "ETSI", "5G", "40M", "HT", "1T", "46", "32", - "MKK", "5G", "40M", "HT", "1T", "46", "32", - "IC", "5G", "40M", "HT", "1T", "46", "32", - "KCC", "5G", "40M", "HT", "1T", "46", "28", - "ACMA", "5G", "40M", "HT", "1T", "46", "32", - "CHILE", "5G", "40M", "HT", "1T", "46", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "46", "27", - "MEXICO", "5G", "40M", "HT", "1T", "46", "31", - "FCC", "5G", "40M", "HT", "1T", "54", "27", - "ETSI", "5G", "40M", "HT", "1T", "54", "32", - "MKK", "5G", "40M", "HT", "1T", "54", "32", - "IC", "5G", "40M", "HT", "1T", "54", "32", - "KCC", "5G", "40M", "HT", "1T", "54", "22", - "ACMA", "5G", "40M", "HT", "1T", "54", "32", - "CHILE", "5G", "40M", "HT", "1T", "54", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "54", "27", - "MEXICO", "5G", "40M", "HT", "1T", "54", "32", - "FCC", "5G", "40M", "HT", "1T", "62", "23", - "ETSI", "5G", "40M", "HT", "1T", "62", "32", - "MKK", "5G", "40M", "HT", "1T", "62", "32", - "IC", "5G", "40M", "HT", "1T", "62", "23", - "KCC", "5G", "40M", "HT", "1T", "62", "31", - "ACMA", "5G", "40M", "HT", "1T", "62", "32", - "CHILE", "5G", "40M", "HT", "1T", "62", "23", - "UKRAINE", "5G", "40M", "HT", "1T", "62", "27", - "MEXICO", "5G", "40M", "HT", "1T", "62", "23", - "FCC", "5G", "40M", "HT", "1T", "102", "21", - "ETSI", "5G", "40M", "HT", "1T", "102", "32", - "MKK", "5G", "40M", "HT", "1T", "102", "32", - "IC", "5G", "40M", "HT", "1T", "102", "21", - "KCC", "5G", "40M", "HT", "1T", "102", "31", - "ACMA", "5G", "40M", "HT", "1T", "102", "32", - "CHILE", "5G", "40M", "HT", "1T", "102", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "102", "27", - "MEXICO", "5G", "40M", "HT", "1T", "102", "21", - "FCC", "5G", "40M", "HT", "1T", "110", "27", - "ETSI", "5G", "40M", "HT", "1T", "110", "32", - "MKK", "5G", "40M", "HT", "1T", "110", "32", - "IC", "5G", "40M", "HT", "1T", "110", "32", - "KCC", "5G", "40M", "HT", "1T", "110", "32", - "ACMA", "5G", "40M", "HT", "1T", "110", "32", - "CHILE", "5G", "40M", "HT", "1T", "110", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "110", "27", - "MEXICO", "5G", "40M", "HT", "1T", "110", "32", - "FCC", "5G", "40M", "HT", "1T", "118", "27", - "ETSI", "5G", "40M", "HT", "1T", "118", "32", - "MKK", "5G", "40M", "HT", "1T", "118", "32", - "IC", "5G", "40M", "HT", "1T", "118", "63", - "KCC", "5G", "40M", "HT", "1T", "118", "32", - "ACMA", "5G", "40M", "HT", "1T", "118", "63", - "CHILE", "5G", "40M", "HT", "1T", "118", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "118", "27", - "MEXICO", "5G", "40M", "HT", "1T", "118", "32", - "FCC", "5G", "40M", "HT", "1T", "126", "27", - "ETSI", "5G", "40M", "HT", "1T", "126", "32", - "MKK", "5G", "40M", "HT", "1T", "126", "32", - "IC", "5G", "40M", "HT", "1T", "126", "63", - "KCC", "5G", "40M", "HT", "1T", "126", "32", - "ACMA", "5G", "40M", "HT", "1T", "126", "63", - "CHILE", "5G", "40M", "HT", "1T", "126", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "126", "27", - "MEXICO", "5G", "40M", "HT", "1T", "126", "32", - "FCC", "5G", "40M", "HT", "1T", "134", "27", - "ETSI", "5G", "40M", "HT", "1T", "134", "32", - "MKK", "5G", "40M", "HT", "1T", "134", "32", - "IC", "5G", "40M", "HT", "1T", "134", "32", - "KCC", "5G", "40M", "HT", "1T", "134", "32", - "ACMA", "5G", "40M", "HT", "1T", "134", "32", - "CHILE", "5G", "40M", "HT", "1T", "134", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "134", "63", - "MEXICO", "5G", "40M", "HT", "1T", "134", "32", - "FCC", "5G", "40M", "HT", "1T", "142", "27", - "ETSI", "5G", "40M", "HT", "1T", "142", "63", - "MKK", "5G", "40M", "HT", "1T", "142", "63", - "IC", "5G", "40M", "HT", "1T", "142", "29", - "KCC", "5G", "40M", "HT", "1T", "142", "32", - "ACMA", "5G", "40M", "HT", "1T", "142", "63", - "CHILE", "5G", "40M", "HT", "1T", "142", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "142", "63", - "MEXICO", "5G", "40M", "HT", "1T", "142", "29", - "FCC", "5G", "40M", "HT", "1T", "151", "28", - "ETSI", "5G", "40M", "HT", "1T", "151", "-63", - "MKK", "5G", "40M", "HT", "1T", "151", "63", - "IC", "5G", "40M", "HT", "1T", "151", "32", - "KCC", "5G", "40M", "HT", "1T", "151", "27", - "ACMA", "5G", "40M", "HT", "1T", "151", "32", - "CHILE", "5G", "40M", "HT", "1T", "151", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "151", "27", - "MEXICO", "5G", "40M", "HT", "1T", "151", "32", - "FCC", "5G", "40M", "HT", "1T", "159", "28", - "ETSI", "5G", "40M", "HT", "1T", "159", "-63", - "MKK", "5G", "40M", "HT", "1T", "159", "63", - "IC", "5G", "40M", "HT", "1T", "159", "32", - "KCC", "5G", "40M", "HT", "1T", "159", "26", - "ACMA", "5G", "40M", "HT", "1T", "159", "32", - "CHILE", "5G", "40M", "HT", "1T", "159", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "159", "27", - "MEXICO", "5G", "40M", "HT", "1T", "159", "32", - "FCC", "5G", "80M", "VHT", "1T", "42", "19", - "ETSI", "5G", "80M", "VHT", "1T", "42", "32", - "MKK", "5G", "80M", "VHT", "1T", "42", "28", - "IC", "5G", "80M", "VHT", "1T", "42", "19", - "KCC", "5G", "80M", "VHT", "1T", "42", "25", - "ACMA", "5G", "80M", "VHT", "1T", "42", "32", - "CHILE", "5G", "80M", "VHT", "1T", "42", "19", - "UKRAINE", "5G", "80M", "VHT", "1T", "42", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "42", "19", - "FCC", "5G", "80M", "VHT", "1T", "58", "22", - "ETSI", "5G", "80M", "VHT", "1T", "58", "32", - "MKK", "5G", "80M", "VHT", "1T", "58", "28", - "IC", "5G", "80M", "VHT", "1T", "58", "22", - "KCC", "5G", "80M", "VHT", "1T", "58", "28", - "ACMA", "5G", "80M", "VHT", "1T", "58", "32", - "CHILE", "5G", "80M", "VHT", "1T", "58", "22", - "UKRAINE", "5G", "80M", "VHT", "1T", "58", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "58", "22", - "FCC", "5G", "80M", "VHT", "1T", "106", "18", - "ETSI", "5G", "80M", "VHT", "1T", "106", "32", - "MKK", "5G", "80M", "VHT", "1T", "106", "32", - "IC", "5G", "80M", "VHT", "1T", "106", "18", - "KCC", "5G", "80M", "VHT", "1T", "106", "30", - "ACMA", "5G", "80M", "VHT", "1T", "106", "32", - "CHILE", "5G", "80M", "VHT", "1T", "106", "32", - "UKRAINE", "5G", "80M", "VHT", "1T", "106", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "106", "18", - "FCC", "5G", "80M", "VHT", "1T", "122", "27", - "ETSI", "5G", "80M", "VHT", "1T", "122", "32", - "MKK", "5G", "80M", "VHT", "1T", "122", "32", - "IC", "5G", "80M", "VHT", "1T", "122", "63", - "KCC", "5G", "80M", "VHT", "1T", "122", "26", - "ACMA", "5G", "80M", "VHT", "1T", "122", "63", - "CHILE", "5G", "80M", "VHT", "1T", "122", "32", - "UKRAINE", "5G", "80M", "VHT", "1T", "122", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "122", "32", - "FCC", "5G", "80M", "VHT", "1T", "138", "27", - "ETSI", "5G", "80M", "VHT", "1T", "138", "63", - "MKK", "5G", "80M", "VHT", "1T", "138", "63", - "IC", "5G", "80M", "VHT", "1T", "138", "28", - "KCC", "5G", "80M", "VHT", "1T", "138", "32", - "ACMA", "5G", "80M", "VHT", "1T", "138", "63", - "CHILE", "5G", "80M", "VHT", "1T", "138", "32", - "UKRAINE", "5G", "80M", "VHT", "1T", "138", "63", - "MEXICO", "5G", "80M", "VHT", "1T", "138", "28", - "FCC", "5G", "80M", "VHT", "1T", "155", "28", - "ETSI", "5G", "80M", "VHT", "1T", "155", "-63", - "MKK", "5G", "80M", "VHT", "1T", "155", "63", - "IC", "5G", "80M", "VHT", "1T", "155", "32", - "KCC", "5G", "80M", "VHT", "1T", "155", "27", - "ACMA", "5G", "80M", "VHT", "1T", "155", "32", - "CHILE", "5G", "80M", "VHT", "1T", "155", "32", - "UKRAINE", "5G", "80M", "VHT", "1T", "155", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "155", "32" +const struct txpwr_lmt_t_8821c array_mp_8821c_txpwr_lmt_fccsar[] = { + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 24}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 24}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 24}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 24}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 28}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 28}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 28}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 20}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 20}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 20}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 20}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 29}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 31}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 16}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 29}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 29}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 7}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 29}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 29}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 27}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 22}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 22}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 22}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 22}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 24}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 22}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 23}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 23}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 23}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 23}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 21}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 21}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 21}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 29}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 29}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 28}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 25}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 22}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 28}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 22}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 22}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 22}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 18}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 18}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 18}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32} }; #endif @@ -5421,54 +5392,23 @@ odm_read_and_config_mp_8821c_txpwr_lmt_fccsar(struct dm_struct *dm) { #ifdef CONFIG_8821C_FCCSAR - u32 i = 0; -#if (DM_ODM_SUPPORT_TYPE == ODM_IOT) - u32 array_len = - sizeof(array_mp_8821c_txpwr_lmt_fccsar) / sizeof(u8); - u8 *array = (u8 *)array_mp_8821c_txpwr_lmt_fccsar; -#else - u32 array_len = - sizeof(array_mp_8821c_txpwr_lmt_fccsar) / sizeof(u8 *); - u8 **array = (u8 **)array_mp_8821c_txpwr_lmt_fccsar; -#endif - -#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) - void *adapter = dm->adapter; - HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter)); - - odm_memory_set(dm, hal_data->BufOfLinesPwrLmt, 0, - MAX_LINES_HWCONFIG_TXT * - MAX_BYTES_LINE_HWCONFIG_TXT); - hal_data->nLinesReadPwrLmt = array_len / 7; -#endif + int i = 0; + const struct txpwr_lmt_t_8821c *array = (const struct txpwr_lmt_t_8821c *)array_mp_8821c_txpwr_lmt_fccsar; PHYDM_DBG(dm, ODM_COMP_INIT, "===> %s\n", __func__); - for (i = 0; i < array_len; i += 7) { -#if (DM_ODM_SUPPORT_TYPE == ODM_IOT) - u8 regulation = array[i]; - u8 band = array[i + 1]; - u8 bandwidth = array[i + 2]; - u8 rate = array[i + 3]; - u8 rf_path = array[i + 4]; - u8 chnl = array[i + 5]; - u8 val = array[i + 6]; -#else - u8 *regulation = array[i]; - u8 *band = array[i + 1]; - u8 *bandwidth = array[i + 2]; - u8 *rate = array[i + 3]; - u8 *rf_path = array[i + 4]; - u8 *chnl = array[i + 5]; - u8 *val = array[i + 6]; -#endif +#define array_len sizeof(array_mp_8821c_txpwr_lmt)/sizeof(struct txpwr_lmt_t_8821c) + for (i = 0; i < array_len; i++) { + u8 regulation = array[i].reg; + u8 band = array[i].band; + u8 bandwidth = array[i].bw; + u8 rate = array[i].rs; + u8 rf_path = array[i].ntx; + u8 chnl = array[i].ch; + s8 val = array[i].val; - odm_config_bb_txpwr_lmt_8821c(dm, regulation, band, bandwidth, + odm_config_bb_txpwr_lmt_8821c_ex(dm, regulation, band, bandwidth, rate, rf_path, chnl, val); -#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) - rsprintf((char *)hal_data->BufOfLinesPwrLmt[i / 7], 100, "\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\",", - regulation, band, bandwidth, rate, rf_path, chnl, val); -#endif } #endif @@ -5479,1123 +5419,1123 @@ odm_read_and_config_mp_8821c_txpwr_lmt_fccsar(struct dm_struct *dm) ******************************************************************************/ #ifdef CONFIG_8821C_ICSAR -const char *array_mp_8821c_txpwr_lmt_icsar[] = { - "FCC", "2.4G", "20M", "CCK", "1T", "01", "30", - "ETSI", "2.4G", "20M", "CCK", "1T", "01", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "01", "34", - "IC", "2.4G", "20M", "CCK", "1T", "01", "30", - "KCC", "2.4G", "20M", "CCK", "1T", "01", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "01", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "01", "30", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "01", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "01", "30", - "FCC", "2.4G", "20M", "CCK", "1T", "02", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "02", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "02", "34", - "IC", "2.4G", "20M", "CCK", "1T", "02", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "02", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "02", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "02", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "02", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "02", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "03", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "03", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "03", "34", - "IC", "2.4G", "20M", "CCK", "1T", "03", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "03", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "03", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "03", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "03", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "03", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "04", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "04", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "04", "34", - "IC", "2.4G", "20M", "CCK", "1T", "04", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "04", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "04", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "04", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "04", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "04", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "05", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "05", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "05", "34", - "IC", "2.4G", "20M", "CCK", "1T", "05", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "05", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "05", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "05", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "05", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "05", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "06", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "06", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "06", "34", - "IC", "2.4G", "20M", "CCK", "1T", "06", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "06", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "06", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "06", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "06", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "06", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "07", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "07", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "07", "34", - "IC", "2.4G", "20M", "CCK", "1T", "07", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "07", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "07", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "07", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "07", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "07", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "08", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "08", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "08", "34", - "IC", "2.4G", "20M", "CCK", "1T", "08", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "08", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "08", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "08", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "08", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "08", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "09", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "09", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "09", "34", - "IC", "2.4G", "20M", "CCK", "1T", "09", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "09", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "09", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "09", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "09", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "09", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "10", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "10", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "10", "34", - "IC", "2.4G", "20M", "CCK", "1T", "10", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "10", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "10", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "10", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "10", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "10", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "11", "32", - "ETSI", "2.4G", "20M", "CCK", "1T", "11", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "11", "34", - "IC", "2.4G", "20M", "CCK", "1T", "11", "32", - "KCC", "2.4G", "20M", "CCK", "1T", "11", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "11", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "11", "32", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "11", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "11", "32", - "FCC", "2.4G", "20M", "CCK", "1T", "12", "24", - "ETSI", "2.4G", "20M", "CCK", "1T", "12", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "12", "34", - "IC", "2.4G", "20M", "CCK", "1T", "12", "24", - "KCC", "2.4G", "20M", "CCK", "1T", "12", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "12", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "12", "24", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "12", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "12", "24", - "FCC", "2.4G", "20M", "CCK", "1T", "13", "16", - "ETSI", "2.4G", "20M", "CCK", "1T", "13", "30", - "MKK", "2.4G", "20M", "CCK", "1T", "13", "34", - "IC", "2.4G", "20M", "CCK", "1T", "13", "16", - "KCC", "2.4G", "20M", "CCK", "1T", "13", "34", - "ACMA", "2.4G", "20M", "CCK", "1T", "13", "30", - "CHILE", "2.4G", "20M", "CCK", "1T", "13", "16", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "13", "30", - "MEXICO", "2.4G", "20M", "CCK", "1T", "13", "16", - "FCC", "2.4G", "20M", "CCK", "1T", "14", "63", - "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63", - "MKK", "2.4G", "20M", "CCK", "1T", "14", "34", - "IC", "2.4G", "20M", "CCK", "1T", "14", "63", - "KCC", "2.4G", "20M", "CCK", "1T", "14", "63", - "ACMA", "2.4G", "20M", "CCK", "1T", "14", "63", - "CHILE", "2.4G", "20M", "CCK", "1T", "14", "63", - "UKRAINE", "2.4G", "20M", "CCK", "1T", "14", "63", - "MEXICO", "2.4G", "20M", "CCK", "1T", "14", "63", - "FCC", "2.4G", "20M", "OFDM", "1T", "01", "30", - "ETSI", "2.4G", "20M", "OFDM", "1T", "01", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "01", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "01", "30", - "KCC", "2.4G", "20M", "OFDM", "1T", "01", "32", - "ACMA", "2.4G", "20M", "OFDM", "1T", "01", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "01", "30", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "01", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "01", "30", - "FCC", "2.4G", "20M", "OFDM", "1T", "02", "32", - "ETSI", "2.4G", "20M", "OFDM", "1T", "02", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "02", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "02", "32", - "KCC", "2.4G", "20M", "OFDM", "1T", "02", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "02", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "02", "32", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "02", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "02", "32", - "FCC", "2.4G", "20M", "OFDM", "1T", "03", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "03", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "03", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "03", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "03", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "03", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "03", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "03", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "04", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "04", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "04", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "04", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "04", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "04", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "04", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "04", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "04", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "05", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "05", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "05", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "05", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "05", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "05", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "05", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "05", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "05", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "06", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "06", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "06", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "06", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "06", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "06", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "06", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "06", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "07", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "07", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "07", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "07", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "07", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "07", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "07", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "07", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "07", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "08", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "08", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "08", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "08", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "08", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "08", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "08", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "08", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "08", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "09", "34", - "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "09", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "09", "34", - "KCC", "2.4G", "20M", "OFDM", "1T", "09", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "09", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "09", "34", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "09", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "09", "34", - "FCC", "2.4G", "20M", "OFDM", "1T", "10", "32", - "ETSI", "2.4G", "20M", "OFDM", "1T", "10", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "10", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "10", "32", - "KCC", "2.4G", "20M", "OFDM", "1T", "10", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "10", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "10", "32", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "10", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "10", "32", - "FCC", "2.4G", "20M", "OFDM", "1T", "11", "30", - "ETSI", "2.4G", "20M", "OFDM", "1T", "11", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "11", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "11", "30", - "KCC", "2.4G", "20M", "OFDM", "1T", "11", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "11", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "11", "30", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "11", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "11", "30", - "FCC", "2.4G", "20M", "OFDM", "1T", "12", "28", - "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "12", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "12", "28", - "KCC", "2.4G", "20M", "OFDM", "1T", "12", "34", - "ACMA", "2.4G", "20M", "OFDM", "1T", "12", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "12", "28", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "12", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "12", "28", - "FCC", "2.4G", "20M", "OFDM", "1T", "13", "16", - "ETSI", "2.4G", "20M", "OFDM", "1T", "13", "30", - "MKK", "2.4G", "20M", "OFDM", "1T", "13", "34", - "IC", "2.4G", "20M", "OFDM", "1T", "13", "16", - "KCC", "2.4G", "20M", "OFDM", "1T", "13", "32", - "ACMA", "2.4G", "20M", "OFDM", "1T", "13", "30", - "CHILE", "2.4G", "20M", "OFDM", "1T", "13", "16", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "13", "30", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "13", "16", - "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63", - "ETSI", "2.4G", "20M", "OFDM", "1T", "14", "63", - "MKK", "2.4G", "20M", "OFDM", "1T", "14", "63", - "IC", "2.4G", "20M", "OFDM", "1T", "14", "63", - "KCC", "2.4G", "20M", "OFDM", "1T", "14", "63", - "ACMA", "2.4G", "20M", "OFDM", "1T", "14", "63", - "CHILE", "2.4G", "20M", "OFDM", "1T", "14", "63", - "UKRAINE", "2.4G", "20M", "OFDM", "1T", "14", "63", - "MEXICO", "2.4G", "20M", "OFDM", "1T", "14", "63", - "FCC", "2.4G", "20M", "HT", "1T", "01", "26", - "ETSI", "2.4G", "20M", "HT", "1T", "01", "30", - "MKK", "2.4G", "20M", "HT", "1T", "01", "34", - "IC", "2.4G", "20M", "HT", "1T", "01", "26", - "KCC", "2.4G", "20M", "HT", "1T", "01", "32", - "ACMA", "2.4G", "20M", "HT", "1T", "01", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "01", "26", - "UKRAINE", "2.4G", "20M", "HT", "1T", "01", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "01", "26", - "FCC", "2.4G", "20M", "HT", "1T", "02", "30", - "ETSI", "2.4G", "20M", "HT", "1T", "02", "30", - "MKK", "2.4G", "20M", "HT", "1T", "02", "34", - "IC", "2.4G", "20M", "HT", "1T", "02", "30", - "KCC", "2.4G", "20M", "HT", "1T", "02", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "02", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "02", "30", - "UKRAINE", "2.4G", "20M", "HT", "1T", "02", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "02", "30", - "FCC", "2.4G", "20M", "HT", "1T", "03", "32", - "ETSI", "2.4G", "20M", "HT", "1T", "03", "30", - "MKK", "2.4G", "20M", "HT", "1T", "03", "34", - "IC", "2.4G", "20M", "HT", "1T", "03", "32", - "KCC", "2.4G", "20M", "HT", "1T", "03", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "03", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "03", "32", - "UKRAINE", "2.4G", "20M", "HT", "1T", "03", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "03", "32", - "FCC", "2.4G", "20M", "HT", "1T", "04", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "04", "30", - "MKK", "2.4G", "20M", "HT", "1T", "04", "34", - "IC", "2.4G", "20M", "HT", "1T", "04", "34", - "KCC", "2.4G", "20M", "HT", "1T", "04", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "04", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "04", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "04", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "04", "34", - "FCC", "2.4G", "20M", "HT", "1T", "05", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "05", "30", - "MKK", "2.4G", "20M", "HT", "1T", "05", "34", - "IC", "2.4G", "20M", "HT", "1T", "05", "34", - "KCC", "2.4G", "20M", "HT", "1T", "05", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "05", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "05", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "05", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "05", "34", - "FCC", "2.4G", "20M", "HT", "1T", "06", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "06", "30", - "MKK", "2.4G", "20M", "HT", "1T", "06", "34", - "IC", "2.4G", "20M", "HT", "1T", "06", "34", - "KCC", "2.4G", "20M", "HT", "1T", "06", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "06", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "06", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "06", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "06", "34", - "FCC", "2.4G", "20M", "HT", "1T", "07", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "07", "30", - "MKK", "2.4G", "20M", "HT", "1T", "07", "34", - "IC", "2.4G", "20M", "HT", "1T", "07", "34", - "KCC", "2.4G", "20M", "HT", "1T", "07", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "07", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "07", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "07", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "07", "34", - "FCC", "2.4G", "20M", "HT", "1T", "08", "34", - "ETSI", "2.4G", "20M", "HT", "1T", "08", "30", - "MKK", "2.4G", "20M", "HT", "1T", "08", "34", - "IC", "2.4G", "20M", "HT", "1T", "08", "34", - "KCC", "2.4G", "20M", "HT", "1T", "08", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "08", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "08", "34", - "UKRAINE", "2.4G", "20M", "HT", "1T", "08", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "08", "34", - "FCC", "2.4G", "20M", "HT", "1T", "09", "32", - "ETSI", "2.4G", "20M", "HT", "1T", "09", "30", - "MKK", "2.4G", "20M", "HT", "1T", "09", "34", - "IC", "2.4G", "20M", "HT", "1T", "09", "32", - "KCC", "2.4G", "20M", "HT", "1T", "09", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "09", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "09", "32", - "UKRAINE", "2.4G", "20M", "HT", "1T", "09", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "09", "32", - "FCC", "2.4G", "20M", "HT", "1T", "10", "30", - "ETSI", "2.4G", "20M", "HT", "1T", "10", "30", - "MKK", "2.4G", "20M", "HT", "1T", "10", "34", - "IC", "2.4G", "20M", "HT", "1T", "10", "30", - "KCC", "2.4G", "20M", "HT", "1T", "10", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "10", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "10", "30", - "UKRAINE", "2.4G", "20M", "HT", "1T", "10", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "10", "30", - "FCC", "2.4G", "20M", "HT", "1T", "11", "28", - "ETSI", "2.4G", "20M", "HT", "1T", "11", "30", - "MKK", "2.4G", "20M", "HT", "1T", "11", "34", - "IC", "2.4G", "20M", "HT", "1T", "11", "28", - "KCC", "2.4G", "20M", "HT", "1T", "11", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "11", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "11", "28", - "UKRAINE", "2.4G", "20M", "HT", "1T", "11", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "11", "28", - "FCC", "2.4G", "20M", "HT", "1T", "12", "26", - "ETSI", "2.4G", "20M", "HT", "1T", "12", "30", - "MKK", "2.4G", "20M", "HT", "1T", "12", "34", - "IC", "2.4G", "20M", "HT", "1T", "12", "26", - "KCC", "2.4G", "20M", "HT", "1T", "12", "34", - "ACMA", "2.4G", "20M", "HT", "1T", "12", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "12", "26", - "UKRAINE", "2.4G", "20M", "HT", "1T", "12", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "12", "26", - "FCC", "2.4G", "20M", "HT", "1T", "13", "12", - "ETSI", "2.4G", "20M", "HT", "1T", "13", "30", - "MKK", "2.4G", "20M", "HT", "1T", "13", "34", - "IC", "2.4G", "20M", "HT", "1T", "13", "12", - "KCC", "2.4G", "20M", "HT", "1T", "13", "32", - "ACMA", "2.4G", "20M", "HT", "1T", "13", "30", - "CHILE", "2.4G", "20M", "HT", "1T", "13", "12", - "UKRAINE", "2.4G", "20M", "HT", "1T", "13", "30", - "MEXICO", "2.4G", "20M", "HT", "1T", "13", "12", - "FCC", "2.4G", "20M", "HT", "1T", "14", "63", - "ETSI", "2.4G", "20M", "HT", "1T", "14", "63", - "MKK", "2.4G", "20M", "HT", "1T", "14", "63", - "IC", "2.4G", "20M", "HT", "1T", "14", "63", - "KCC", "2.4G", "20M", "HT", "1T", "14", "63", - "ACMA", "2.4G", "20M", "HT", "1T", "14", "63", - "CHILE", "2.4G", "20M", "HT", "1T", "14", "63", - "UKRAINE", "2.4G", "20M", "HT", "1T", "14", "63", - "MEXICO", "2.4G", "20M", "HT", "1T", "14", "63", - "FCC", "2.4G", "40M", "HT", "1T", "01", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "01", "63", - "MKK", "2.4G", "40M", "HT", "1T", "01", "63", - "IC", "2.4G", "40M", "HT", "1T", "01", "63", - "KCC", "2.4G", "40M", "HT", "1T", "01", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "01", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "01", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "01", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "01", "63", - "FCC", "2.4G", "40M", "HT", "1T", "02", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "02", "63", - "MKK", "2.4G", "40M", "HT", "1T", "02", "63", - "IC", "2.4G", "40M", "HT", "1T", "02", "63", - "KCC", "2.4G", "40M", "HT", "1T", "02", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "02", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "02", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "02", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "02", "63", - "FCC", "2.4G", "40M", "HT", "1T", "03", "26", - "ETSI", "2.4G", "40M", "HT", "1T", "03", "30", - "MKK", "2.4G", "40M", "HT", "1T", "03", "30", - "IC", "2.4G", "40M", "HT", "1T", "03", "26", - "KCC", "2.4G", "40M", "HT", "1T", "03", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "03", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "03", "26", - "UKRAINE", "2.4G", "40M", "HT", "1T", "03", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "03", "26", - "FCC", "2.4G", "40M", "HT", "1T", "04", "26", - "ETSI", "2.4G", "40M", "HT", "1T", "04", "30", - "MKK", "2.4G", "40M", "HT", "1T", "04", "30", - "IC", "2.4G", "40M", "HT", "1T", "04", "26", - "KCC", "2.4G", "40M", "HT", "1T", "04", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "04", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "04", "26", - "UKRAINE", "2.4G", "40M", "HT", "1T", "04", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "04", "26", - "FCC", "2.4G", "40M", "HT", "1T", "05", "30", - "ETSI", "2.4G", "40M", "HT", "1T", "05", "30", - "MKK", "2.4G", "40M", "HT", "1T", "05", "30", - "IC", "2.4G", "40M", "HT", "1T", "05", "30", - "KCC", "2.4G", "40M", "HT", "1T", "05", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "05", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "05", "30", - "UKRAINE", "2.4G", "40M", "HT", "1T", "05", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "05", "30", - "FCC", "2.4G", "40M", "HT", "1T", "06", "30", - "ETSI", "2.4G", "40M", "HT", "1T", "06", "30", - "MKK", "2.4G", "40M", "HT", "1T", "06", "30", - "IC", "2.4G", "40M", "HT", "1T", "06", "30", - "KCC", "2.4G", "40M", "HT", "1T", "06", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "06", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "06", "30", - "UKRAINE", "2.4G", "40M", "HT", "1T", "06", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "06", "30", - "FCC", "2.4G", "40M", "HT", "1T", "07", "30", - "ETSI", "2.4G", "40M", "HT", "1T", "07", "30", - "MKK", "2.4G", "40M", "HT", "1T", "07", "30", - "IC", "2.4G", "40M", "HT", "1T", "07", "30", - "KCC", "2.4G", "40M", "HT", "1T", "07", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "07", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "07", "30", - "UKRAINE", "2.4G", "40M", "HT", "1T", "07", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "07", "30", - "FCC", "2.4G", "40M", "HT", "1T", "08", "26", - "ETSI", "2.4G", "40M", "HT", "1T", "08", "30", - "MKK", "2.4G", "40M", "HT", "1T", "08", "30", - "IC", "2.4G", "40M", "HT", "1T", "08", "26", - "KCC", "2.4G", "40M", "HT", "1T", "08", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "08", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "08", "26", - "UKRAINE", "2.4G", "40M", "HT", "1T", "08", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "08", "26", - "FCC", "2.4G", "40M", "HT", "1T", "09", "26", - "ETSI", "2.4G", "40M", "HT", "1T", "09", "30", - "MKK", "2.4G", "40M", "HT", "1T", "09", "30", - "IC", "2.4G", "40M", "HT", "1T", "09", "26", - "KCC", "2.4G", "40M", "HT", "1T", "09", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "09", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "09", "26", - "UKRAINE", "2.4G", "40M", "HT", "1T", "09", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "09", "26", - "FCC", "2.4G", "40M", "HT", "1T", "10", "28", - "ETSI", "2.4G", "40M", "HT", "1T", "10", "30", - "MKK", "2.4G", "40M", "HT", "1T", "10", "30", - "IC", "2.4G", "40M", "HT", "1T", "10", "28", - "KCC", "2.4G", "40M", "HT", "1T", "10", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "10", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "10", "28", - "UKRAINE", "2.4G", "40M", "HT", "1T", "10", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "10", "28", - "FCC", "2.4G", "40M", "HT", "1T", "11", "20", - "ETSI", "2.4G", "40M", "HT", "1T", "11", "30", - "MKK", "2.4G", "40M", "HT", "1T", "11", "30", - "IC", "2.4G", "40M", "HT", "1T", "11", "20", - "KCC", "2.4G", "40M", "HT", "1T", "11", "30", - "ACMA", "2.4G", "40M", "HT", "1T", "11", "30", - "CHILE", "2.4G", "40M", "HT", "1T", "11", "20", - "UKRAINE", "2.4G", "40M", "HT", "1T", "11", "30", - "MEXICO", "2.4G", "40M", "HT", "1T", "11", "20", - "FCC", "2.4G", "40M", "HT", "1T", "12", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "12", "63", - "MKK", "2.4G", "40M", "HT", "1T", "12", "63", - "IC", "2.4G", "40M", "HT", "1T", "12", "63", - "KCC", "2.4G", "40M", "HT", "1T", "12", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "12", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "12", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "12", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "12", "63", - "FCC", "2.4G", "40M", "HT", "1T", "13", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "13", "63", - "MKK", "2.4G", "40M", "HT", "1T", "13", "63", - "IC", "2.4G", "40M", "HT", "1T", "13", "63", - "KCC", "2.4G", "40M", "HT", "1T", "13", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "13", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "13", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "13", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "13", "63", - "FCC", "2.4G", "40M", "HT", "1T", "14", "63", - "ETSI", "2.4G", "40M", "HT", "1T", "14", "63", - "MKK", "2.4G", "40M", "HT", "1T", "14", "63", - "IC", "2.4G", "40M", "HT", "1T", "14", "63", - "KCC", "2.4G", "40M", "HT", "1T", "14", "63", - "ACMA", "2.4G", "40M", "HT", "1T", "14", "63", - "CHILE", "2.4G", "40M", "HT", "1T", "14", "63", - "UKRAINE", "2.4G", "40M", "HT", "1T", "14", "63", - "MEXICO", "2.4G", "40M", "HT", "1T", "14", "63", - "FCC", "5G", "20M", "OFDM", "1T", "36", "31", - "ETSI", "5G", "20M", "OFDM", "1T", "36", "32", - "MKK", "5G", "20M", "OFDM", "1T", "36", "33", - "IC", "5G", "20M", "OFDM", "1T", "36", "27", - "KCC", "5G", "20M", "OFDM", "1T", "36", "29", - "ACMA", "5G", "20M", "OFDM", "1T", "36", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "36", "31", - "UKRAINE", "5G", "20M", "OFDM", "1T", "36", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "36", "31", - "FCC", "5G", "20M", "OFDM", "1T", "40", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "40", "32", - "MKK", "5G", "20M", "OFDM", "1T", "40", "33", - "IC", "5G", "20M", "OFDM", "1T", "40", "27", - "KCC", "5G", "20M", "OFDM", "1T", "40", "28", - "ACMA", "5G", "20M", "OFDM", "1T", "40", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "40", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "40", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "40", "31", - "FCC", "5G", "20M", "OFDM", "1T", "44", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "44", "32", - "MKK", "5G", "20M", "OFDM", "1T", "44", "33", - "IC", "5G", "20M", "OFDM", "1T", "44", "27", - "KCC", "5G", "20M", "OFDM", "1T", "44", "28", - "ACMA", "5G", "20M", "OFDM", "1T", "44", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "44", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "44", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "44", "31", - "FCC", "5G", "20M", "OFDM", "1T", "48", "31", - "ETSI", "5G", "20M", "OFDM", "1T", "48", "32", - "MKK", "5G", "20M", "OFDM", "1T", "48", "33", - "IC", "5G", "20M", "OFDM", "1T", "48", "27", - "KCC", "5G", "20M", "OFDM", "1T", "48", "27", - "ACMA", "5G", "20M", "OFDM", "1T", "48", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "48", "31", - "UKRAINE", "5G", "20M", "OFDM", "1T", "48", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "48", "31", - "FCC", "5G", "20M", "OFDM", "1T", "52", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "52", "32", - "MKK", "5G", "20M", "OFDM", "1T", "52", "33", - "IC", "5G", "20M", "OFDM", "1T", "52", "27", - "KCC", "5G", "20M", "OFDM", "1T", "52", "16", - "ACMA", "5G", "20M", "OFDM", "1T", "52", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "52", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "52", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "52", "33", - "FCC", "5G", "20M", "OFDM", "1T", "56", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "56", "32", - "MKK", "5G", "20M", "OFDM", "1T", "56", "33", - "IC", "5G", "20M", "OFDM", "1T", "56", "27", - "KCC", "5G", "20M", "OFDM", "1T", "56", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "56", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "56", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "56", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "56", "33", - "FCC", "5G", "20M", "OFDM", "1T", "60", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "60", "32", - "MKK", "5G", "20M", "OFDM", "1T", "60", "33", - "IC", "5G", "20M", "OFDM", "1T", "60", "27", - "KCC", "5G", "20M", "OFDM", "1T", "60", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "60", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "60", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "60", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "60", "33", - "FCC", "5G", "20M", "OFDM", "1T", "64", "30", - "ETSI", "5G", "20M", "OFDM", "1T", "64", "32", - "MKK", "5G", "20M", "OFDM", "1T", "64", "33", - "IC", "5G", "20M", "OFDM", "1T", "64", "27", - "KCC", "5G", "20M", "OFDM", "1T", "64", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "64", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "64", "30", - "UKRAINE", "5G", "20M", "OFDM", "1T", "64", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "64", "30", - "FCC", "5G", "20M", "OFDM", "1T", "100", "30", - "ETSI", "5G", "20M", "OFDM", "1T", "100", "32", - "MKK", "5G", "20M", "OFDM", "1T", "100", "33", - "IC", "5G", "20M", "OFDM", "1T", "100", "27", - "KCC", "5G", "20M", "OFDM", "1T", "100", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "100", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "100", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "100", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "100", "30", - "FCC", "5G", "20M", "OFDM", "1T", "104", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "104", "32", - "MKK", "5G", "20M", "OFDM", "1T", "104", "33", - "IC", "5G", "20M", "OFDM", "1T", "104", "27", - "KCC", "5G", "20M", "OFDM", "1T", "104", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "104", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "104", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "104", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "104", "33", - "FCC", "5G", "20M", "OFDM", "1T", "108", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "108", "32", - "MKK", "5G", "20M", "OFDM", "1T", "108", "33", - "IC", "5G", "20M", "OFDM", "1T", "108", "27", - "KCC", "5G", "20M", "OFDM", "1T", "108", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "108", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "108", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "108", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "108", "33", - "FCC", "5G", "20M", "OFDM", "1T", "112", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "112", "32", - "MKK", "5G", "20M", "OFDM", "1T", "112", "33", - "IC", "5G", "20M", "OFDM", "1T", "112", "27", - "KCC", "5G", "20M", "OFDM", "1T", "112", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "112", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "112", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "112", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "112", "33", - "FCC", "5G", "20M", "OFDM", "1T", "116", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "116", "32", - "MKK", "5G", "20M", "OFDM", "1T", "116", "33", - "IC", "5G", "20M", "OFDM", "1T", "116", "27", - "KCC", "5G", "20M", "OFDM", "1T", "116", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "116", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "116", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "116", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "116", "33", - "FCC", "5G", "20M", "OFDM", "1T", "120", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "120", "32", - "MKK", "5G", "20M", "OFDM", "1T", "120", "33", - "IC", "5G", "20M", "OFDM", "1T", "120", "63", - "KCC", "5G", "20M", "OFDM", "1T", "120", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "120", "63", - "CHILE", "5G", "20M", "OFDM", "1T", "120", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "120", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "120", "33", - "FCC", "5G", "20M", "OFDM", "1T", "124", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "124", "32", - "MKK", "5G", "20M", "OFDM", "1T", "124", "33", - "IC", "5G", "20M", "OFDM", "1T", "124", "63", - "KCC", "5G", "20M", "OFDM", "1T", "124", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "124", "63", - "CHILE", "5G", "20M", "OFDM", "1T", "124", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "124", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "124", "33", - "FCC", "5G", "20M", "OFDM", "1T", "128", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "128", "32", - "MKK", "5G", "20M", "OFDM", "1T", "128", "33", - "IC", "5G", "20M", "OFDM", "1T", "128", "63", - "KCC", "5G", "20M", "OFDM", "1T", "128", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "128", "63", - "CHILE", "5G", "20M", "OFDM", "1T", "128", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "128", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "128", "33", - "FCC", "5G", "20M", "OFDM", "1T", "132", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "132", "32", - "MKK", "5G", "20M", "OFDM", "1T", "132", "33", - "IC", "5G", "20M", "OFDM", "1T", "132", "27", - "KCC", "5G", "20M", "OFDM", "1T", "132", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "132", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "132", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "132", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "132", "33", - "FCC", "5G", "20M", "OFDM", "1T", "136", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "136", "32", - "MKK", "5G", "20M", "OFDM", "1T", "136", "33", - "IC", "5G", "20M", "OFDM", "1T", "136", "27", - "KCC", "5G", "20M", "OFDM", "1T", "136", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "136", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "136", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "136", "63", - "MEXICO", "5G", "20M", "OFDM", "1T", "136", "33", - "FCC", "5G", "20M", "OFDM", "1T", "140", "31", - "ETSI", "5G", "20M", "OFDM", "1T", "140", "32", - "MKK", "5G", "20M", "OFDM", "1T", "140", "33", - "IC", "5G", "20M", "OFDM", "1T", "140", "27", - "KCC", "5G", "20M", "OFDM", "1T", "140", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "140", "32", - "CHILE", "5G", "20M", "OFDM", "1T", "140", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "140", "63", - "MEXICO", "5G", "20M", "OFDM", "1T", "140", "31", - "FCC", "5G", "20M", "OFDM", "1T", "144", "30", - "ETSI", "5G", "20M", "OFDM", "1T", "144", "63", - "MKK", "5G", "20M", "OFDM", "1T", "144", "63", - "IC", "5G", "20M", "OFDM", "1T", "144", "27", - "KCC", "5G", "20M", "OFDM", "1T", "144", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "144", "63", - "CHILE", "5G", "20M", "OFDM", "1T", "144", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "144", "63", - "MEXICO", "5G", "20M", "OFDM", "1T", "144", "30", - "FCC", "5G", "20M", "OFDM", "1T", "149", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "149", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "149", "63", - "IC", "5G", "20M", "OFDM", "1T", "149", "28", - "KCC", "5G", "20M", "OFDM", "1T", "149", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "149", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "149", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "149", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "149", "33", - "FCC", "5G", "20M", "OFDM", "1T", "153", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "153", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "153", "63", - "IC", "5G", "20M", "OFDM", "1T", "153", "28", - "KCC", "5G", "20M", "OFDM", "1T", "153", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "153", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "153", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "153", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "153", "33", - "FCC", "5G", "20M", "OFDM", "1T", "157", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "157", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "157", "63", - "IC", "5G", "20M", "OFDM", "1T", "157", "28", - "KCC", "5G", "20M", "OFDM", "1T", "157", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "157", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "157", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "157", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "157", "33", - "FCC", "5G", "20M", "OFDM", "1T", "161", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "161", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "161", "63", - "IC", "5G", "20M", "OFDM", "1T", "161", "28", - "KCC", "5G", "20M", "OFDM", "1T", "161", "31", - "ACMA", "5G", "20M", "OFDM", "1T", "161", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "161", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "161", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "161", "33", - "FCC", "5G", "20M", "OFDM", "1T", "165", "33", - "ETSI", "5G", "20M", "OFDM", "1T", "165", "-63", - "MKK", "5G", "20M", "OFDM", "1T", "165", "63", - "IC", "5G", "20M", "OFDM", "1T", "165", "28", - "KCC", "5G", "20M", "OFDM", "1T", "165", "33", - "ACMA", "5G", "20M", "OFDM", "1T", "165", "33", - "CHILE", "5G", "20M", "OFDM", "1T", "165", "33", - "UKRAINE", "5G", "20M", "OFDM", "1T", "165", "27", - "MEXICO", "5G", "20M", "OFDM", "1T", "165", "30", - "FCC", "5G", "20M", "HT", "1T", "36", "30", - "ETSI", "5G", "20M", "HT", "1T", "36", "32", - "MKK", "5G", "20M", "HT", "1T", "36", "33", - "IC", "5G", "20M", "HT", "1T", "36", "27", - "KCC", "5G", "20M", "HT", "1T", "36", "27", - "ACMA", "5G", "20M", "HT", "1T", "36", "32", - "CHILE", "5G", "20M", "HT", "1T", "36", "30", - "UKRAINE", "5G", "20M", "HT", "1T", "36", "27", - "MEXICO", "5G", "20M", "HT", "1T", "36", "30", - "FCC", "5G", "20M", "HT", "1T", "40", "33", - "ETSI", "5G", "20M", "HT", "1T", "40", "32", - "MKK", "5G", "20M", "HT", "1T", "40", "33", - "IC", "5G", "20M", "HT", "1T", "40", "27", - "KCC", "5G", "20M", "HT", "1T", "40", "29", - "ACMA", "5G", "20M", "HT", "1T", "40", "32", - "CHILE", "5G", "20M", "HT", "1T", "40", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "40", "27", - "MEXICO", "5G", "20M", "HT", "1T", "40", "31", - "FCC", "5G", "20M", "HT", "1T", "44", "33", - "ETSI", "5G", "20M", "HT", "1T", "44", "32", - "MKK", "5G", "20M", "HT", "1T", "44", "33", - "IC", "5G", "20M", "HT", "1T", "44", "27", - "KCC", "5G", "20M", "HT", "1T", "44", "29", - "ACMA", "5G", "20M", "HT", "1T", "44", "32", - "CHILE", "5G", "20M", "HT", "1T", "44", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "44", "27", - "MEXICO", "5G", "20M", "HT", "1T", "44", "31", - "FCC", "5G", "20M", "HT", "1T", "48", "33", - "ETSI", "5G", "20M", "HT", "1T", "48", "32", - "MKK", "5G", "20M", "HT", "1T", "48", "33", - "IC", "5G", "20M", "HT", "1T", "48", "27", - "KCC", "5G", "20M", "HT", "1T", "48", "26", - "ACMA", "5G", "20M", "HT", "1T", "48", "32", - "CHILE", "5G", "20M", "HT", "1T", "48", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "48", "27", - "MEXICO", "5G", "20M", "HT", "1T", "48", "31", - "FCC", "5G", "20M", "HT", "1T", "52", "33", - "ETSI", "5G", "20M", "HT", "1T", "52", "32", - "MKK", "5G", "20M", "HT", "1T", "52", "33", - "IC", "5G", "20M", "HT", "1T", "52", "27", - "KCC", "5G", "20M", "HT", "1T", "52", "7", - "ACMA", "5G", "20M", "HT", "1T", "52", "32", - "CHILE", "5G", "20M", "HT", "1T", "52", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "52", "27", - "MEXICO", "5G", "20M", "HT", "1T", "52", "33", - "FCC", "5G", "20M", "HT", "1T", "56", "33", - "ETSI", "5G", "20M", "HT", "1T", "56", "32", - "MKK", "5G", "20M", "HT", "1T", "56", "33", - "IC", "5G", "20M", "HT", "1T", "56", "27", - "KCC", "5G", "20M", "HT", "1T", "56", "33", - "ACMA", "5G", "20M", "HT", "1T", "56", "32", - "CHILE", "5G", "20M", "HT", "1T", "56", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "56", "27", - "MEXICO", "5G", "20M", "HT", "1T", "56", "33", - "FCC", "5G", "20M", "HT", "1T", "60", "33", - "ETSI", "5G", "20M", "HT", "1T", "60", "32", - "MKK", "5G", "20M", "HT", "1T", "60", "33", - "IC", "5G", "20M", "HT", "1T", "60", "27", - "KCC", "5G", "20M", "HT", "1T", "60", "33", - "ACMA", "5G", "20M", "HT", "1T", "60", "32", - "CHILE", "5G", "20M", "HT", "1T", "60", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "60", "27", - "MEXICO", "5G", "20M", "HT", "1T", "60", "33", - "FCC", "5G", "20M", "HT", "1T", "64", "30", - "ETSI", "5G", "20M", "HT", "1T", "64", "32", - "MKK", "5G", "20M", "HT", "1T", "64", "33", - "IC", "5G", "20M", "HT", "1T", "64", "27", - "KCC", "5G", "20M", "HT", "1T", "64", "33", - "ACMA", "5G", "20M", "HT", "1T", "64", "32", - "CHILE", "5G", "20M", "HT", "1T", "64", "30", - "UKRAINE", "5G", "20M", "HT", "1T", "64", "27", - "MEXICO", "5G", "20M", "HT", "1T", "64", "30", - "FCC", "5G", "20M", "HT", "1T", "100", "30", - "ETSI", "5G", "20M", "HT", "1T", "100", "32", - "MKK", "5G", "20M", "HT", "1T", "100", "33", - "IC", "5G", "20M", "HT", "1T", "100", "27", - "KCC", "5G", "20M", "HT", "1T", "100", "33", - "ACMA", "5G", "20M", "HT", "1T", "100", "32", - "CHILE", "5G", "20M", "HT", "1T", "100", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "100", "27", - "MEXICO", "5G", "20M", "HT", "1T", "100", "30", - "FCC", "5G", "20M", "HT", "1T", "104", "33", - "ETSI", "5G", "20M", "HT", "1T", "104", "32", - "MKK", "5G", "20M", "HT", "1T", "104", "33", - "IC", "5G", "20M", "HT", "1T", "104", "27", - "KCC", "5G", "20M", "HT", "1T", "104", "33", - "ACMA", "5G", "20M", "HT", "1T", "104", "32", - "CHILE", "5G", "20M", "HT", "1T", "104", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "104", "27", - "MEXICO", "5G", "20M", "HT", "1T", "104", "33", - "FCC", "5G", "20M", "HT", "1T", "108", "33", - "ETSI", "5G", "20M", "HT", "1T", "108", "32", - "MKK", "5G", "20M", "HT", "1T", "108", "33", - "IC", "5G", "20M", "HT", "1T", "108", "27", - "KCC", "5G", "20M", "HT", "1T", "108", "33", - "ACMA", "5G", "20M", "HT", "1T", "108", "32", - "CHILE", "5G", "20M", "HT", "1T", "108", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "108", "27", - "MEXICO", "5G", "20M", "HT", "1T", "108", "33", - "FCC", "5G", "20M", "HT", "1T", "112", "33", - "ETSI", "5G", "20M", "HT", "1T", "112", "32", - "MKK", "5G", "20M", "HT", "1T", "112", "33", - "IC", "5G", "20M", "HT", "1T", "112", "27", - "KCC", "5G", "20M", "HT", "1T", "112", "33", - "ACMA", "5G", "20M", "HT", "1T", "112", "32", - "CHILE", "5G", "20M", "HT", "1T", "112", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "112", "27", - "MEXICO", "5G", "20M", "HT", "1T", "112", "33", - "FCC", "5G", "20M", "HT", "1T", "116", "33", - "ETSI", "5G", "20M", "HT", "1T", "116", "32", - "MKK", "5G", "20M", "HT", "1T", "116", "33", - "IC", "5G", "20M", "HT", "1T", "116", "27", - "KCC", "5G", "20M", "HT", "1T", "116", "33", - "ACMA", "5G", "20M", "HT", "1T", "116", "32", - "CHILE", "5G", "20M", "HT", "1T", "116", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "116", "27", - "MEXICO", "5G", "20M", "HT", "1T", "116", "33", - "FCC", "5G", "20M", "HT", "1T", "120", "33", - "ETSI", "5G", "20M", "HT", "1T", "120", "32", - "MKK", "5G", "20M", "HT", "1T", "120", "33", - "IC", "5G", "20M", "HT", "1T", "120", "63", - "KCC", "5G", "20M", "HT", "1T", "120", "33", - "ACMA", "5G", "20M", "HT", "1T", "120", "63", - "CHILE", "5G", "20M", "HT", "1T", "120", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "120", "27", - "MEXICO", "5G", "20M", "HT", "1T", "120", "33", - "FCC", "5G", "20M", "HT", "1T", "124", "33", - "ETSI", "5G", "20M", "HT", "1T", "124", "32", - "MKK", "5G", "20M", "HT", "1T", "124", "33", - "IC", "5G", "20M", "HT", "1T", "124", "63", - "KCC", "5G", "20M", "HT", "1T", "124", "33", - "ACMA", "5G", "20M", "HT", "1T", "124", "63", - "CHILE", "5G", "20M", "HT", "1T", "124", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "124", "27", - "MEXICO", "5G", "20M", "HT", "1T", "124", "33", - "FCC", "5G", "20M", "HT", "1T", "128", "33", - "ETSI", "5G", "20M", "HT", "1T", "128", "32", - "MKK", "5G", "20M", "HT", "1T", "128", "33", - "IC", "5G", "20M", "HT", "1T", "128", "63", - "KCC", "5G", "20M", "HT", "1T", "128", "33", - "ACMA", "5G", "20M", "HT", "1T", "128", "63", - "CHILE", "5G", "20M", "HT", "1T", "128", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "128", "27", - "MEXICO", "5G", "20M", "HT", "1T", "128", "33", - "FCC", "5G", "20M", "HT", "1T", "132", "33", - "ETSI", "5G", "20M", "HT", "1T", "132", "32", - "MKK", "5G", "20M", "HT", "1T", "132", "33", - "IC", "5G", "20M", "HT", "1T", "132", "27", - "KCC", "5G", "20M", "HT", "1T", "132", "33", - "ACMA", "5G", "20M", "HT", "1T", "132", "32", - "CHILE", "5G", "20M", "HT", "1T", "132", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "132", "27", - "MEXICO", "5G", "20M", "HT", "1T", "132", "33", - "FCC", "5G", "20M", "HT", "1T", "136", "33", - "ETSI", "5G", "20M", "HT", "1T", "136", "32", - "MKK", "5G", "20M", "HT", "1T", "136", "33", - "IC", "5G", "20M", "HT", "1T", "136", "27", - "KCC", "5G", "20M", "HT", "1T", "136", "33", - "ACMA", "5G", "20M", "HT", "1T", "136", "32", - "CHILE", "5G", "20M", "HT", "1T", "136", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "136", "63", - "MEXICO", "5G", "20M", "HT", "1T", "136", "33", - "FCC", "5G", "20M", "HT", "1T", "140", "29", - "ETSI", "5G", "20M", "HT", "1T", "140", "32", - "MKK", "5G", "20M", "HT", "1T", "140", "33", - "IC", "5G", "20M", "HT", "1T", "140", "27", - "KCC", "5G", "20M", "HT", "1T", "140", "33", - "ACMA", "5G", "20M", "HT", "1T", "140", "32", - "CHILE", "5G", "20M", "HT", "1T", "140", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "140", "63", - "MEXICO", "5G", "20M", "HT", "1T", "140", "29", - "FCC", "5G", "20M", "HT", "1T", "144", "27", - "ETSI", "5G", "20M", "HT", "1T", "144", "63", - "MKK", "5G", "20M", "HT", "1T", "144", "63", - "IC", "5G", "20M", "HT", "1T", "144", "27", - "KCC", "5G", "20M", "HT", "1T", "144", "33", - "ACMA", "5G", "20M", "HT", "1T", "144", "63", - "CHILE", "5G", "20M", "HT", "1T", "144", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "144", "63", - "MEXICO", "5G", "20M", "HT", "1T", "144", "27", - "FCC", "5G", "20M", "HT", "1T", "149", "33", - "ETSI", "5G", "20M", "HT", "1T", "149", "-63", - "MKK", "5G", "20M", "HT", "1T", "149", "63", - "IC", "5G", "20M", "HT", "1T", "149", "28", - "KCC", "5G", "20M", "HT", "1T", "149", "33", - "ACMA", "5G", "20M", "HT", "1T", "149", "33", - "CHILE", "5G", "20M", "HT", "1T", "149", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "149", "27", - "MEXICO", "5G", "20M", "HT", "1T", "149", "33", - "FCC", "5G", "20M", "HT", "1T", "153", "33", - "ETSI", "5G", "20M", "HT", "1T", "153", "-63", - "MKK", "5G", "20M", "HT", "1T", "153", "63", - "IC", "5G", "20M", "HT", "1T", "153", "28", - "KCC", "5G", "20M", "HT", "1T", "153", "33", - "ACMA", "5G", "20M", "HT", "1T", "153", "33", - "CHILE", "5G", "20M", "HT", "1T", "153", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "153", "27", - "MEXICO", "5G", "20M", "HT", "1T", "153", "33", - "FCC", "5G", "20M", "HT", "1T", "157", "33", - "ETSI", "5G", "20M", "HT", "1T", "157", "-63", - "MKK", "5G", "20M", "HT", "1T", "157", "63", - "IC", "5G", "20M", "HT", "1T", "157", "28", - "KCC", "5G", "20M", "HT", "1T", "157", "33", - "ACMA", "5G", "20M", "HT", "1T", "157", "33", - "CHILE", "5G", "20M", "HT", "1T", "157", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "157", "27", - "MEXICO", "5G", "20M", "HT", "1T", "157", "33", - "FCC", "5G", "20M", "HT", "1T", "161", "33", - "ETSI", "5G", "20M", "HT", "1T", "161", "-63", - "MKK", "5G", "20M", "HT", "1T", "161", "63", - "IC", "5G", "20M", "HT", "1T", "161", "28", - "KCC", "5G", "20M", "HT", "1T", "161", "31", - "ACMA", "5G", "20M", "HT", "1T", "161", "33", - "CHILE", "5G", "20M", "HT", "1T", "161", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "161", "27", - "MEXICO", "5G", "20M", "HT", "1T", "161", "33", - "FCC", "5G", "20M", "HT", "1T", "165", "33", - "ETSI", "5G", "20M", "HT", "1T", "165", "-63", - "MKK", "5G", "20M", "HT", "1T", "165", "63", - "IC", "5G", "20M", "HT", "1T", "165", "28", - "KCC", "5G", "20M", "HT", "1T", "165", "33", - "ACMA", "5G", "20M", "HT", "1T", "165", "33", - "CHILE", "5G", "20M", "HT", "1T", "165", "33", - "UKRAINE", "5G", "20M", "HT", "1T", "165", "27", - "MEXICO", "5G", "20M", "HT", "1T", "165", "30", - "FCC", "5G", "40M", "HT", "1T", "38", "22", - "ETSI", "5G", "40M", "HT", "1T", "38", "32", - "MKK", "5G", "40M", "HT", "1T", "38", "32", - "IC", "5G", "40M", "HT", "1T", "38", "22", - "KCC", "5G", "40M", "HT", "1T", "38", "26", - "ACMA", "5G", "40M", "HT", "1T", "38", "32", - "CHILE", "5G", "40M", "HT", "1T", "38", "22", - "UKRAINE", "5G", "40M", "HT", "1T", "38", "27", - "MEXICO", "5G", "40M", "HT", "1T", "38", "22", - "FCC", "5G", "40M", "HT", "1T", "46", "32", - "ETSI", "5G", "40M", "HT", "1T", "46", "32", - "MKK", "5G", "40M", "HT", "1T", "46", "32", - "IC", "5G", "40M", "HT", "1T", "46", "24", - "KCC", "5G", "40M", "HT", "1T", "46", "28", - "ACMA", "5G", "40M", "HT", "1T", "46", "32", - "CHILE", "5G", "40M", "HT", "1T", "46", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "46", "27", - "MEXICO", "5G", "40M", "HT", "1T", "46", "31", - "FCC", "5G", "40M", "HT", "1T", "54", "32", - "ETSI", "5G", "40M", "HT", "1T", "54", "32", - "MKK", "5G", "40M", "HT", "1T", "54", "32", - "IC", "5G", "40M", "HT", "1T", "54", "27", - "KCC", "5G", "40M", "HT", "1T", "54", "22", - "ACMA", "5G", "40M", "HT", "1T", "54", "32", - "CHILE", "5G", "40M", "HT", "1T", "54", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "54", "27", - "MEXICO", "5G", "40M", "HT", "1T", "54", "32", - "FCC", "5G", "40M", "HT", "1T", "62", "23", - "ETSI", "5G", "40M", "HT", "1T", "62", "32", - "MKK", "5G", "40M", "HT", "1T", "62", "32", - "IC", "5G", "40M", "HT", "1T", "62", "23", - "KCC", "5G", "40M", "HT", "1T", "62", "31", - "ACMA", "5G", "40M", "HT", "1T", "62", "32", - "CHILE", "5G", "40M", "HT", "1T", "62", "23", - "UKRAINE", "5G", "40M", "HT", "1T", "62", "27", - "MEXICO", "5G", "40M", "HT", "1T", "62", "23", - "FCC", "5G", "40M", "HT", "1T", "102", "21", - "ETSI", "5G", "40M", "HT", "1T", "102", "32", - "MKK", "5G", "40M", "HT", "1T", "102", "32", - "IC", "5G", "40M", "HT", "1T", "102", "21", - "KCC", "5G", "40M", "HT", "1T", "102", "31", - "ACMA", "5G", "40M", "HT", "1T", "102", "32", - "CHILE", "5G", "40M", "HT", "1T", "102", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "102", "27", - "MEXICO", "5G", "40M", "HT", "1T", "102", "21", - "FCC", "5G", "40M", "HT", "1T", "110", "32", - "ETSI", "5G", "40M", "HT", "1T", "110", "32", - "MKK", "5G", "40M", "HT", "1T", "110", "32", - "IC", "5G", "40M", "HT", "1T", "110", "27", - "KCC", "5G", "40M", "HT", "1T", "110", "32", - "ACMA", "5G", "40M", "HT", "1T", "110", "32", - "CHILE", "5G", "40M", "HT", "1T", "110", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "110", "27", - "MEXICO", "5G", "40M", "HT", "1T", "110", "32", - "FCC", "5G", "40M", "HT", "1T", "118", "32", - "ETSI", "5G", "40M", "HT", "1T", "118", "32", - "MKK", "5G", "40M", "HT", "1T", "118", "32", - "IC", "5G", "40M", "HT", "1T", "118", "63", - "KCC", "5G", "40M", "HT", "1T", "118", "32", - "ACMA", "5G", "40M", "HT", "1T", "118", "63", - "CHILE", "5G", "40M", "HT", "1T", "118", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "118", "27", - "MEXICO", "5G", "40M", "HT", "1T", "118", "32", - "FCC", "5G", "40M", "HT", "1T", "126", "32", - "ETSI", "5G", "40M", "HT", "1T", "126", "32", - "MKK", "5G", "40M", "HT", "1T", "126", "32", - "IC", "5G", "40M", "HT", "1T", "126", "63", - "KCC", "5G", "40M", "HT", "1T", "126", "32", - "ACMA", "5G", "40M", "HT", "1T", "126", "63", - "CHILE", "5G", "40M", "HT", "1T", "126", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "126", "27", - "MEXICO", "5G", "40M", "HT", "1T", "126", "32", - "FCC", "5G", "40M", "HT", "1T", "134", "32", - "ETSI", "5G", "40M", "HT", "1T", "134", "32", - "MKK", "5G", "40M", "HT", "1T", "134", "32", - "IC", "5G", "40M", "HT", "1T", "134", "27", - "KCC", "5G", "40M", "HT", "1T", "134", "32", - "ACMA", "5G", "40M", "HT", "1T", "134", "32", - "CHILE", "5G", "40M", "HT", "1T", "134", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "134", "63", - "MEXICO", "5G", "40M", "HT", "1T", "134", "32", - "FCC", "5G", "40M", "HT", "1T", "142", "29", - "ETSI", "5G", "40M", "HT", "1T", "142", "63", - "MKK", "5G", "40M", "HT", "1T", "142", "63", - "IC", "5G", "40M", "HT", "1T", "142", "27", - "KCC", "5G", "40M", "HT", "1T", "142", "32", - "ACMA", "5G", "40M", "HT", "1T", "142", "63", - "CHILE", "5G", "40M", "HT", "1T", "142", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "142", "63", - "MEXICO", "5G", "40M", "HT", "1T", "142", "29", - "FCC", "5G", "40M", "HT", "1T", "151", "32", - "ETSI", "5G", "40M", "HT", "1T", "151", "-63", - "MKK", "5G", "40M", "HT", "1T", "151", "63", - "IC", "5G", "40M", "HT", "1T", "151", "28", - "KCC", "5G", "40M", "HT", "1T", "151", "27", - "ACMA", "5G", "40M", "HT", "1T", "151", "32", - "CHILE", "5G", "40M", "HT", "1T", "151", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "151", "27", - "MEXICO", "5G", "40M", "HT", "1T", "151", "32", - "FCC", "5G", "40M", "HT", "1T", "159", "32", - "ETSI", "5G", "40M", "HT", "1T", "159", "-63", - "MKK", "5G", "40M", "HT", "1T", "159", "63", - "IC", "5G", "40M", "HT", "1T", "159", "28", - "KCC", "5G", "40M", "HT", "1T", "159", "26", - "ACMA", "5G", "40M", "HT", "1T", "159", "32", - "CHILE", "5G", "40M", "HT", "1T", "159", "32", - "UKRAINE", "5G", "40M", "HT", "1T", "159", "27", - "MEXICO", "5G", "40M", "HT", "1T", "159", "32", - "FCC", "5G", "80M", "VHT", "1T", "42", "19", - "ETSI", "5G", "80M", "VHT", "1T", "42", "32", - "MKK", "5G", "80M", "VHT", "1T", "42", "28", - "IC", "5G", "80M", "VHT", "1T", "42", "19", - "KCC", "5G", "80M", "VHT", "1T", "42", "25", - "ACMA", "5G", "80M", "VHT", "1T", "42", "32", - "CHILE", "5G", "80M", "VHT", "1T", "42", "19", - "UKRAINE", "5G", "80M", "VHT", "1T", "42", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "42", "19", - "FCC", "5G", "80M", "VHT", "1T", "58", "22", - "ETSI", "5G", "80M", "VHT", "1T", "58", "32", - "MKK", "5G", "80M", "VHT", "1T", "58", "28", - "IC", "5G", "80M", "VHT", "1T", "58", "22", - "KCC", "5G", "80M", "VHT", "1T", "58", "28", - "ACMA", "5G", "80M", "VHT", "1T", "58", "32", - "CHILE", "5G", "80M", "VHT", "1T", "58", "22", - "UKRAINE", "5G", "80M", "VHT", "1T", "58", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "58", "22", - "FCC", "5G", "80M", "VHT", "1T", "106", "18", - "ETSI", "5G", "80M", "VHT", "1T", "106", "32", - "MKK", "5G", "80M", "VHT", "1T", "106", "32", - "IC", "5G", "80M", "VHT", "1T", "106", "18", - "KCC", "5G", "80M", "VHT", "1T", "106", "30", - "ACMA", "5G", "80M", "VHT", "1T", "106", "32", - "CHILE", "5G", "80M", "VHT", "1T", "106", "32", - "UKRAINE", "5G", "80M", "VHT", "1T", "106", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "106", "18", - "FCC", "5G", "80M", "VHT", "1T", "122", "32", - "ETSI", "5G", "80M", "VHT", "1T", "122", "32", - "MKK", "5G", "80M", "VHT", "1T", "122", "32", - "IC", "5G", "80M", "VHT", "1T", "122", "63", - "KCC", "5G", "80M", "VHT", "1T", "122", "26", - "ACMA", "5G", "80M", "VHT", "1T", "122", "63", - "CHILE", "5G", "80M", "VHT", "1T", "122", "32", - "UKRAINE", "5G", "80M", "VHT", "1T", "122", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "122", "32", - "FCC", "5G", "80M", "VHT", "1T", "138", "28", - "ETSI", "5G", "80M", "VHT", "1T", "138", "63", - "MKK", "5G", "80M", "VHT", "1T", "138", "63", - "IC", "5G", "80M", "VHT", "1T", "138", "27", - "KCC", "5G", "80M", "VHT", "1T", "138", "32", - "ACMA", "5G", "80M", "VHT", "1T", "138", "63", - "CHILE", "5G", "80M", "VHT", "1T", "138", "32", - "UKRAINE", "5G", "80M", "VHT", "1T", "138", "63", - "MEXICO", "5G", "80M", "VHT", "1T", "138", "28", - "FCC", "5G", "80M", "VHT", "1T", "155", "32", - "ETSI", "5G", "80M", "VHT", "1T", "155", "-63", - "MKK", "5G", "80M", "VHT", "1T", "155", "63", - "IC", "5G", "80M", "VHT", "1T", "155", "28", - "KCC", "5G", "80M", "VHT", "1T", "155", "27", - "ACMA", "5G", "80M", "VHT", "1T", "155", "32", - "CHILE", "5G", "80M", "VHT", "1T", "155", "32", - "UKRAINE", "5G", "80M", "VHT", "1T", "155", "27", - "MEXICO", "5G", "80M", "VHT", "1T", "155", "32" +const struct txpwr_lmt_t_8821c array_mp_8821c_txpwr_lmt_icsar[] = { + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 24}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 24}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 24}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 24}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 28}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 28}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 28}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 20}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 20}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 20}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 20}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 31}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 29}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 31}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 16}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 31}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 29}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 29}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 7}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 29}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 29}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 27}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 22}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 22}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 22}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 22}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 24}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 22}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 23}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 23}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 23}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 23}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 21}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 21}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 21}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 29}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 29}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 28}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 25}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 22}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 28}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 22}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 22}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 22}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 18}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 18}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 18}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32} }; #endif @@ -6604,54 +6544,1175 @@ odm_read_and_config_mp_8821c_txpwr_lmt_icsar(struct dm_struct *dm) { #ifdef CONFIG_8821C_ICSAR - u32 i = 0; -#if (DM_ODM_SUPPORT_TYPE == ODM_IOT) - u32 array_len = - sizeof(array_mp_8821c_txpwr_lmt_icsar) / sizeof(u8); - u8 *array = (u8 *)array_mp_8821c_txpwr_lmt_icsar; -#else - u32 array_len = - sizeof(array_mp_8821c_txpwr_lmt_icsar) / sizeof(u8 *); - u8 **array = (u8 **)array_mp_8821c_txpwr_lmt_icsar; -#endif - -#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) - void *adapter = dm->adapter; - HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter)); - - odm_memory_set(dm, hal_data->BufOfLinesPwrLmt, 0, - MAX_LINES_HWCONFIG_TXT * - MAX_BYTES_LINE_HWCONFIG_TXT); - hal_data->nLinesReadPwrLmt = array_len / 7; -#endif + int i = 0; + const struct txpwr_lmt_t_8821c *array = (const struct txpwr_lmt_t_8821c *)array_mp_8821c_txpwr_lmt_icsar; PHYDM_DBG(dm, ODM_COMP_INIT, "===> %s\n", __func__); - for (i = 0; i < array_len; i += 7) { -#if (DM_ODM_SUPPORT_TYPE == ODM_IOT) - u8 regulation = array[i]; - u8 band = array[i + 1]; - u8 bandwidth = array[i + 2]; - u8 rate = array[i + 3]; - u8 rf_path = array[i + 4]; - u8 chnl = array[i + 5]; - u8 val = array[i + 6]; -#else - u8 *regulation = array[i]; - u8 *band = array[i + 1]; - u8 *bandwidth = array[i + 2]; - u8 *rate = array[i + 3]; - u8 *rf_path = array[i + 4]; - u8 *chnl = array[i + 5]; - u8 *val = array[i + 6]; +#define array_len sizeof(array_mp_8821c_txpwr_lmt)/sizeof(struct txpwr_lmt_t_8821c) + for (i = 0; i < array_len; i++) { + u8 regulation = array[i].reg; + u8 band = array[i].band; + u8 bandwidth = array[i].bw; + u8 rate = array[i].rs; + u8 rf_path = array[i].ntx; + u8 chnl = array[i].ch; + s8 val = array[i].val; + + odm_config_bb_txpwr_lmt_8821c_ex(dm, regulation, band, bandwidth, + rate, rf_path, chnl, val); + } + +#endif +} + +/****************************************************************************** + * txpwr_lmt_lowpower.TXT + ******************************************************************************/ + +#ifdef CONFIG_8821C_LOWPOWER +const struct txpwr_lmt_t_8821c array_mp_8821c_txpwr_lmt_lowpower[] = { + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 29}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 29}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 31}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 4, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 5, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 6, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 7, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 8, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 11, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 22}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 22}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 24}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 12, 24}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 13}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 13}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_CCK, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 29}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 29}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 2, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 10, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 22}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 22}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 28}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 12, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 14}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 14}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 13, 16}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 29}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 29}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 31}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 34}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 25}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 25}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 28}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 22}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 22}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 34}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 34}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 12}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 1, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 2, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 24}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 24}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 3, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 25}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 25}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 4, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 26}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 26}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 5, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 6, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 24}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 24}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 7, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 24}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 24}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 8, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 23}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 23}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 26}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 9, 26}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 21}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 21}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 28}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 10, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 16}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 16}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 20}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 30}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 11, 20}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 12, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 13, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_2_4G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 14, 63}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 29}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 31}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 36, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 40, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 44, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 16}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 29}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 29}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 140, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 144, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_OFDM, PW_LMT_PH_1T, 165, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 36, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 29}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 40, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 29}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 44, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 48, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 7}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 52, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 56, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 60, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 64, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 100, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 104, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 108, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 112, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 116, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 120, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 124, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 128, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 132, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 136, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 140, 29}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 27}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 27}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 144, 27}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 149, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 153, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 157, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 161, 33}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 33}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_20M, PW_LMT_RS_HT, PW_LMT_PH_1T, 165, 30}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 21}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 21}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 22}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 38, 22}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 46, 31}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 22}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 54, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 21}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 21}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 23}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 62, 23}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 18}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 18}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 31}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 102, 21}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 110, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 118, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 126, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 31}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 31}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 134, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 29}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 29}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 142, 29}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 151, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_40M, PW_LMT_RS_HT, PW_LMT_PH_1T, 159, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 28}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 25}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 42, 19}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 19}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 28}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 19}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 28}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 22}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 58, 22}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 18}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 18}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 30}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 106, 18}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 63}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 26}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 122, 32}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 28}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 28}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 32}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 63}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 138, 28}, + {PW_LMT_REGU_FCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32}, + {PW_LMT_REGU_ETSI, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, -63}, + {PW_LMT_REGU_MKK, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 63}, + {PW_LMT_REGU_IC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32}, + {PW_LMT_REGU_KCC, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 27}, + {PW_LMT_REGU_ACMA, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32}, + {PW_LMT_REGU_CHILE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32}, + {PW_LMT_REGU_UKRAINE, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 27}, + {PW_LMT_REGU_MEXICO, PW_LMT_BAND_5G, PW_LMT_BW_80M, PW_LMT_RS_VHT, PW_LMT_PH_1T, 155, 32} +}; #endif - odm_config_bb_txpwr_lmt_8821c(dm, regulation, band, bandwidth, +void +odm_read_and_config_mp_8821c_txpwr_lmt_lowpower(struct dm_struct *dm) +{ +#ifdef CONFIG_8821C_LOWPOWER + + int i = 0; + const struct txpwr_lmt_t_8821c *array = (const struct txpwr_lmt_t_8821c *)array_mp_8821c_txpwr_lmt_lowpower; + + PHYDM_DBG(dm, ODM_COMP_INIT, "===> %s\n", __func__); + +#define array_len sizeof(array_mp_8821c_txpwr_lmt)/sizeof(struct txpwr_lmt_t_8821c) + for (i = 0; i < array_len; i++) { + u8 regulation = array[i].reg; + u8 band = array[i].band; + u8 bandwidth = array[i].bw; + u8 rate = array[i].rs; + u8 rf_path = array[i].ntx; + u8 chnl = array[i].ch; + s8 val = array[i].val; + + odm_config_bb_txpwr_lmt_8821c_ex(dm, regulation, band, bandwidth, rate, rf_path, chnl, val); -#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) - rsprintf((char *)hal_data->BufOfLinesPwrLmt[i / 7], 100, "\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\",", - regulation, band, bandwidth, rate, rf_path, chnl, val); -#endif } #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/rtl8821c/halhwimg8821c_rf.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/rtl8821c/halhwimg8821c_rf.h index db7d03067639..32781b16c44f 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/rtl8821c/halhwimg8821c_rf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/halrf/rtl8821c/halhwimg8821c_rf.h @@ -24,7 +24,7 @@ * *****************************************************************************/ -/*Image2HeaderVersion: R3 1.5.8*/ +/*Image2HeaderVersion: R3 1.5.10.1*/ #if (RTL8821C_SUPPORT == 1) #ifndef __INC_MP_RF_HW_IMG_8821C_H #define __INC_MP_RF_HW_IMG_8821C_H @@ -36,6 +36,7 @@ * #define CONFIG_8821C_TYPE0X28_DRV_DIS * #define CONFIG_8821C_FCCSAR_DRV_DIS * #define CONFIG_8821C_ICSAR_DRV_DIS + * #define CONFIG_8821C_LOWPOWER_DRV_DIS */ #define CONFIG_8821C @@ -63,6 +64,21 @@ #undef CONFIG_8821C_ICSAR #endif +#define CONFIG_8821C_LOWPOWER +#ifdef CONFIG_8821C_LOWPOWER_DRV_DIS + #undef CONFIG_8821C_LOWPOWER +#endif + +struct txpwr_lmt_t_8821c { + u8 reg; + u8 band:1; + u8 bw:3; + u8 rs:2; + u8 ntx:2; + u8 ch; + s8 val; +}; + /****************************************************************************** * radioa.TXT ******************************************************************************/ @@ -126,6 +142,15 @@ void odm_read_and_config_mp_8821c_txpwr_lmt_icsar(struct dm_struct *dm); u32 odm_get_version_mp_8821c_txpwr_lmt_icsar(void); +/****************************************************************************** + * txpwr_lmt_lowpower.TXT + ******************************************************************************/ + +/* tc: Test Chip, mp: mp Chip*/ +void +odm_read_and_config_mp_8821c_txpwr_lmt_lowpower(struct dm_struct *dm); +u32 odm_get_version_mp_8821c_txpwr_lmt_lowpower(void); + #endif #endif /* end of HWIMG_SUPPORT*/ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm.c index ef0198e13a86..185a237b02ef 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm.c @@ -137,6 +137,10 @@ void phydm_cck_new_agc_chk(struct dm_struct *dm) /*@1: new agc 0: old agc*/ dm->cck_new_agc = (boolean)odm_get_bb_reg(dm, new_agc_addr, BIT(17)); #endif +#if (RTL8723F_SUPPORT) + if (dm->support_ic_type & (ODM_RTL8723F)) + dm->cck_new_agc = true; +#endif } /*select 3 or 4 bit LNA */ @@ -225,6 +229,10 @@ void phydm_init_hw_info_by_rfe(struct dm_struct *dm) if (dm->support_ic_type & ODM_RTL8197F) phydm_init_hw_info_by_rfe_type_8197f(dm); #endif + #if (RTL8197G_SUPPORT) + if (dm->support_ic_type & ODM_RTL8197G) + phydm_init_hw_info_by_rfe_type_8197g(dm); + #endif } #endif @@ -313,13 +321,12 @@ void phydm_common_info_self_init(struct dm_struct *dm) dm->csi_wgt = 4; /*@-------------------------------------------------------@*/ #endif - dm->pause_lv_table.lv_cckpd = PHYDM_PAUSE_RELEASE; - dm->pause_lv_table.lv_dig = PHYDM_PAUSE_RELEASE; dm->pre_is_linked = false; dm->is_linked = false; /*dym bw thre and it can config by registry*/ if (dm->en_auto_bw_th == 0) dm->en_auto_bw_th = 20; + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) if (!(dm->is_fcs_mode_enable)) { dm->is_fcs_mode_enable = &dm->boolean_dummy; @@ -347,11 +354,21 @@ void phydm_iot_patch_id_update(void *dm_void, u32 iot_idx, boolean en) PHYDM_DBG(dm, DBG_CMN, "[IOT] patch_id_10120200 = %d\n", iot_table->patch_id_10120200); break; + case 0x40010700: + iot_table->patch_id_40010700 = en; + PHYDM_DBG(dm, DBG_CMN, "[IOT] patch_id_40010700 = %d\n", + iot_table->patch_id_40010700); + break; case 0x021f0800: iot_table->patch_id_021f0800 = en; PHYDM_DBG(dm, DBG_CMN, "[IOT] patch_id_021f0800 = %d\n", iot_table->patch_id_021f0800); break; + case 0x011f0500: + iot_table->patch_id_011f0500 = en; + PHYDM_DBG(dm, DBG_CMN, "[IOT] patch_id_011f0500 = %d\n", + iot_table->patch_id_011f0500); + break; default: pr_debug("[%s] warning!\n", __func__); break; @@ -565,6 +582,26 @@ void phydm_hw_setting(struct dm_struct *dm) phydm_hwsetting_8822c(dm); #endif +#if (RTL8197G_SUPPORT) + if (dm->support_ic_type & ODM_RTL8197G) + phydm_hwsetting_8197g(dm); +#endif + +#if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) + phydm_hwsetting_8723f(dm); +#endif + +#if (RTL8821C_SUPPORT) + if (dm->support_ic_type & ODM_RTL8821C) + phydm_hwsetting_8821c(dm); +#endif + +#if (RTL8812F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8812F) + phydm_hwsetting_8812f(dm); +#endif + #ifdef PHYDM_CCK_RX_PATHDIV_SUPPORT phydm_cck_rx_pathdiv_watchdog(dm); #endif @@ -613,6 +650,12 @@ boolean phydm_chk_bb_rf_pkg_set_valid(struct dm_struct *dm) RELEASE_VERSION_8814B, RF_RELEASE_VERSION_8814B); #endif + #if (RTL8723F_SUPPORT) + } else if (dm->support_ic_type == ODM_RTL8723F) { + valid = phydm_chk_pkg_set_valid_8723f(dm, + RELEASE_VERSION_8723F, + RF_RELEASE_VERSION_8723F); + #endif } return valid; @@ -879,6 +922,22 @@ u64 phydm_supportability_init_win( break; #endif +#if (RTL8723F_SUPPORT) + case ODM_RTL8723F: + support_ability |= + ODM_BB_DIG | + ODM_BB_RA_MASK | + /* ODM_BB_DYNAMIC_TXPWR |*/ + ODM_BB_FA_CNT | + ODM_BB_RSSI_MONITOR | + ODM_BB_CCK_PD | + /*ODM_BB_PWR_TRAIN |*/ + ODM_BB_RATE_ADAPTIVE | + ODM_BB_ADAPTIVITY | + ODM_BB_CFO_TRACKING | + ODM_BB_ENV_MONITOR; + break; +#endif default: support_ability |= ODM_BB_DIG | @@ -1110,7 +1169,7 @@ u64 phydm_supportability_init_ce(void *dm_void) support_ability |= ODM_BB_DIG | ODM_BB_RA_MASK | - /*@ODM_BB_DYNAMIC_TXPWR |*/ + ODM_BB_DYNAMIC_TXPWR | ODM_BB_FA_CNT | ODM_BB_RSSI_MONITOR | ODM_BB_CCK_PD | @@ -1157,7 +1216,22 @@ u64 phydm_supportability_init_ce(void *dm_void) /*ODM_BB_ENV_MONITOR;*/ break; #endif - +#if (RTL8723F_SUPPORT) + case ODM_RTL8723F: + support_ability |= + ODM_BB_DIG | + ODM_BB_RA_MASK | + ODM_BB_DYNAMIC_TXPWR | + ODM_BB_FA_CNT | + ODM_BB_RSSI_MONITOR | + ODM_BB_CCK_PD | + ODM_BB_RATE_ADAPTIVE | + /* ODM_BB_PATH_DIV | */ + ODM_BB_ADAPTIVITY | + ODM_BB_CFO_TRACKING | + ODM_BB_ENV_MONITOR; + break; +#endif default: support_ability |= ODM_BB_DIG | @@ -1376,8 +1450,8 @@ u64 phydm_supportability_init_ap( /*ODM_BB_PWR_TRAIN |*/ /*ODM_BB_RATE_ADAPTIVE |*/ ODM_BB_ADAPTIVITY | - ODM_BB_CFO_TRACKING; - /*ODM_BB_ENV_MONITOR;*/ + ODM_BB_CFO_TRACKING | + ODM_BB_ENV_MONITOR; break; #endif @@ -1414,6 +1488,21 @@ u64 phydm_supportability_init_ap( break; #endif +#if (RTL8723F_SUPPORT) + case ODM_RTL8723F: + support_ability |= + ODM_BB_DIG | + ODM_BB_RA_MASK | + ODM_BB_FA_CNT | + ODM_BB_RSSI_MONITOR | + ODM_BB_CCK_PD | + /*ODM_BB_PWR_TRAIN |*/ + ODM_BB_RATE_ADAPTIVE | + ODM_BB_ADAPTIVITY | + ODM_BB_CFO_TRACKING | + ODM_BB_ENV_MONITOR; + break; +#endif default: support_ability |= ODM_BB_DIG | @@ -1487,8 +1576,8 @@ u64 phydm_supportability_init_iot( /*ODM_BB_PWR_TRAIN |*/ ODM_BB_RATE_ADAPTIVE | ODM_BB_ADAPTIVITY | - ODM_BB_CFO_TRACKING; - /*ODM_BB_ENV_MONITOR*/ + ODM_BB_CFO_TRACKING | + ODM_BB_ENV_MONITOR; break; #endif @@ -1631,6 +1720,11 @@ void phydm_supportability_init(void *dm_void) if (IS_FUNC_EN(dm->en_adap_soml)) support_ability |= ODM_BB_ADAPTIVE_SOML; + /*@[DYNAMIC_TXPWR and TSSI cannot coexist]*/ + if(IS_FUNC_EN(&dm->en_tssi_mode) && + (dm->support_ic_type & ODM_RTL8822C)) + support_ability &= ~ODM_BB_DYNAMIC_TXPWR; + } dm->support_ability = support_ability; PHYDM_DBG(dm, ODM_COMP_INIT, "IC=0x%x, mp=%d, Supportability=0x%llx\n", @@ -1648,6 +1742,41 @@ void phydm_rfe_init(void *dm_void) #endif } +#ifdef CONFIG_DYNAMIC_TXCOLLISION_TH +void phydm_tx_collsion_th_init(void *dm_void) +{ + +struct dm_struct *dm = (struct dm_struct *)dm_void; + +#if (RTL8197G_SUPPORT) + if (dm->support_ic_type & ODM_RTL8197G) + phydm_tx_collsion_th_init_8197g(dm); +#endif + +#if (RTL8812F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8812F) + phydm_tx_collsion_th_init_8812f(dm); +#endif + +} + +void phydm_tx_collsion_th_set(void *dm_void, u8 val_r2t, u8 val_t2r) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + +#if (RTL8197G_SUPPORT) + if (dm->support_ic_type & ODM_RTL8197G) + phydm_tx_collsion_th_set_8197g(dm, val_r2t, val_t2r); +#endif + +#if (RTL8812F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8812F) + phydm_tx_collsion_th_set_8812f(dm, val_r2t, val_t2r); +#endif + +} +#endif + void phydm_dm_early_init(struct dm_struct *dm) { #if (DM_ODM_SUPPORT_TYPE == ODM_CE) @@ -1666,6 +1795,7 @@ enum phydm_init_result odm_dm_init(struct dm_struct *dm) halrf_init(dm); phydm_supportability_init(dm); + phydm_pause_func_init(dm); phydm_rfe_init(dm); phydm_common_info_self_init(dm); phydm_rx_phy_status_init(dm); @@ -1674,9 +1804,13 @@ enum phydm_init_result odm_dm_init(struct dm_struct *dm) #endif phydm_dig_init(dm); #ifdef PHYDM_SUPPORT_CCKPD +#ifdef PHYDM_DCC_ENHANCE + phydm_dig_cckpd_coex_init(dm); +#endif phydm_cck_pd_init(dm); #endif phydm_env_monitor_init(dm); + phydm_enhance_monitor_init(dm); phydm_adaptivity_init(dm); phydm_ra_info_init(dm); phydm_rssi_monitor_init(dm); @@ -1735,6 +1869,10 @@ enum phydm_init_result odm_dm_init(struct dm_struct *dm) phydm_mu_rsoml_init(dm); #endif +#ifdef CONFIG_DYNAMIC_TXCOLLISION_TH + phydm_tx_collsion_th_init(dm); +#endif + return result; } @@ -1758,8 +1896,7 @@ void phydm_supportability_en(void *dm_void, char input[][16], u32 *_used, u8 i; for (i = 0; i < 5; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &dm_value[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &dm_value[i]); } pre_support_ability = dm->support_ability; @@ -1830,7 +1967,6 @@ void phydm_supportability_en(void *dm_void, char input[][16], u32 *_used, PDM_SNPF(out_len, used, output + used, out_len - used, "18. (( %s ))LNA_SAT_CHK\n", ((comp & ODM_BB_LNA_SAT_CHK) ? ("V") : ("."))); - PDM_SNPF(out_len, used, output + used, out_len - used, "================================\n"); PDM_SNPF(out_len, used, output + used, out_len - used, @@ -1929,6 +2065,18 @@ void phydm_pause_dm_watchdog(void *dm_void, enum phydm_pause_type pause_type) } } +void phydm_pause_func_init(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + dm->pause_lv_table.lv_cckpd = PHYDM_PAUSE_RELEASE; + dm->pause_lv_table.lv_dig = PHYDM_PAUSE_RELEASE; + dm->pause_lv_table.lv_antdiv = PHYDM_PAUSE_RELEASE; + dm->pause_lv_table.lv_dig = PHYDM_PAUSE_RELEASE; + dm->pause_lv_table.lv_adapt = PHYDM_PAUSE_RELEASE; + dm->pause_lv_table.lv_adsl = PHYDM_PAUSE_RELEASE; +} + u8 phydm_pause_func(void *dm_void, enum phydm_func_idx pause_func, enum phydm_pause_type pause_type, enum phydm_pause_level pause_lv, u8 val_lehgth, @@ -2135,8 +2283,7 @@ void phydm_pause_func_console(void *dm_void, char input[][16], u32 *_used, } for (i = 0; i < 10; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); } func = (enum phydm_func_idx)var1[0]; @@ -2252,20 +2399,32 @@ void phydm_watchdog(struct dm_struct *dm) phydm_hw_setting(dm); - #ifdef PHYDM_TDMA_DIG_SUPPORT - if (dm->original_dig_restore == 0) +#ifdef PHYDM_TDMA_DIG_SUPPORT + if (dm->original_dig_restore == 0) { phydm_tdma_dig_timer_check(dm); - else - #endif + } else +#endif { phydm_false_alarm_counter_statistics(dm); - phydm_noisy_detection(dm); + #if (ODM_IC_11N_SERIES_SUPPORT || ODM_IC_11AC_SERIES_SUPPORT) + if (dm->support_ic_type & (ODM_IC_11N_SERIES | + ODM_IC_11AC_SERIES)) + phydm_noisy_detection(dm); + #endif + + #if defined(PHYDM_DCC_ENHANCE) && defined(PHYDM_SUPPORT_CCKPD) + phydm_dig_cckpd_coex(dm); + #else phydm_dig(dm); #ifdef PHYDM_SUPPORT_CCKPD phydm_cck_pd_th(dm); #endif + #endif } +#ifdef PHYDM_HW_IGI + phydm_hwigi(dm); +#endif #ifdef PHYDM_POWER_TRAINING_SUPPORT phydm_update_power_training_state(dm); #endif @@ -2301,6 +2460,7 @@ void phydm_watchdog(struct dm_struct *dm) #endif phydm_env_mntr_watchdog(dm); + phydm_enhance_mntr_watchdog(dm); #ifdef PHYDM_LNA_SAT_CHK_SUPPORT phydm_lna_sat_chk_watchdog(dm); @@ -2317,6 +2477,46 @@ void phydm_watchdog(struct dm_struct *dm) phydm_common_info_self_reset(dm); } +void phydm_fw_dm_ctrl_en(void *dm_void, enum phydm_func_idx fun_idx, + boolean enable) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u8 h2c_val[H2C_MAX_LENGTH] = {0}; + u8 para4[4]; /*4 bit*/ + u8 para8[4]; /*8 bit*/ + u8 i = 0; + + for (i = 0; i < 4; i++) { + para4[i] = 0; + para8[i] = 0; + } + + switch (fun_idx) { + case F00_DIG: + phydm_fill_fw_dig_info(dm, &enable, para4, para8); + break; + default: + pr_debug("[Warning] %s\n", __func__); + return; + } + + h2c_val[0] = (u8)((fun_idx & 0x3f) | (enable << 6)); + h2c_val[1] = para8[0]; + h2c_val[2] = para8[1]; + h2c_val[3] = para8[2]; + h2c_val[4] = para8[3]; + h2c_val[5] = (para4[0] & 0xf) | ((para4[1] & 0xf) << 3); + h2c_val[6] = (para4[2] & 0xf) | ((para4[3] & 0xf) << 3); + + PHYDM_DBG(dm, DBG_FW_DM, + "H2C[0x59] fun_idx=%d,en=%d,para8={%x %x %x %x},para4={%x %x %x %x}\n", + fun_idx, enable, + para8[0], para8[1], para8[2], para8[3], + para4[0], para4[1], para4[2], para4[3]); + + odm_fill_h2c_cmd(dm, PHYDM_H2C_FW_DM_CTRL, H2C_MAX_LENGTH, h2c_val); +} + /*@ * Init /.. Fixed HW value. Only init time. */ @@ -2526,6 +2726,9 @@ void odm_cmn_info_init(struct dm_struct *dm, enum odm_cmninfo cmn_info, case ODM_CMNINFO_ANTDIV_GPIO: dm->antdiv_gpio = (u8)value; break; + case ODM_CMNINFO_PEAK_DETECT_MODE: + dm->peak_detect_mode = (u8)value; + break; #endif default: break; @@ -2725,7 +2928,9 @@ void odm_cmn_info_update(struct dm_struct *dm, u32 cmn_info, u64 value) break; case ODM_CMNINFO_RSSI_MIN: +#if 0 dm->rssi_min = (u8)value; +#endif break; case ODM_CMNINFO_RSSI_MIN_BY_PATH: @@ -2784,6 +2989,12 @@ void odm_cmn_info_update(struct dm_struct *dm, u32 cmn_info, u64 value) case ODM_CMNINFO_LINKED_BF_SUPPORT: dm->linked_bf_support = (u8)value; break; + case ODM_CMNINFO_FLATNESS_TYPE: + dm->flatness_type = (u8)value; + break; + case ODM_CMNINFO_TSSI_ENABLE: + dm->en_tssi_mode = (u8)value; + break; default: break; } @@ -2875,6 +3086,11 @@ u32 phydm_cmn_info_query(struct dm_struct *dm, enum phydm_info_query info_type) return (u32)ccx_info->nhm_ratio; case PHYDM_INFO_NHM_NOISE_PWR: return (u32)ccx_info->nhm_level; + case PHYDM_INFO_NHM_PWR: + return (u32)ccx_info->nhm_pwr; + case PHYDM_INFO_NHM_ENV_RATIO: + return (u32)ccx_info->nhm_env_ratio; + default: return 0xffffffff; } @@ -3313,7 +3529,8 @@ void phydm_dc_cancellation(struct dm_struct *dm) } odm_write_dig(dm, 0x7e); /*@Disable LNA*/ - if (dm->support_ic_type & ODM_RTL8821C) + if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8721D | + ODM_RTL8710C)) halrf_rf_lna_setting(dm, HALRF_LNA_DISABLE); /*Turn off 3-wire*/ phydm_stop_3_wire(dm, PHYDM_SET); @@ -3390,7 +3607,8 @@ void phydm_dc_cancellation(struct dm_struct *dm) /* @Turn on 3-wire*/ phydm_stop_3_wire(dm, PHYDM_REVERT); /* @Enable LNA*/ - if (dm->support_ic_type & ODM_RTL8821C) + if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8721D | + ODM_RTL8710C)) halrf_rf_lna_setting(dm, HALRF_LNA_ENABLE); odm_write_dig(dm, 0x20); @@ -3500,12 +3718,18 @@ void phydm_dc_cancellation(struct dm_struct *dm) offset_i_hex[0] = (reg_value32[0] & 0xff80000) >> 19; offset_q_hex[0] = (reg_value32[0] & 0x3fe00) >> 9; - /*@Before filling into registers, - *offset should be multiplexed (-1) - */ - offset_i_hex[0] = 0x200 - offset_i_hex[0]; - offset_q_hex[0] = 0x200 - offset_q_hex[0]; - + if ((offset_i_hex[0] > 0xF && offset_i_hex[0] < 0x1F1) + || (offset_q_hex[0] > 0xF && offset_q_hex[0] < 0x1F1)) { + /*@Discard outliers*/ + offset_i_hex[0] = 0x0; + offset_q_hex[0] = 0x0; + } else { + /*@Before filling into registers, + *offset should be multiplexed (-1) + */ + offset_i_hex[0] = 0x200 - offset_i_hex[0]; + offset_q_hex[0] = 0x200 - offset_q_hex[0]; + } odm_set_bb_reg(dm, R_0x950, 0x1ff, offset_i_hex[0]); odm_set_bb_reg(dm, R_0x950, 0x1ff0000, offset_q_hex[0]); } @@ -3593,4 +3817,5 @@ void phydm_dyn_bw_indication(void *dm_void) phydm_bw_fixed_setting(dm); #endif -} \ No newline at end of file +} + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm.h index d59f38abc28a..071fbb27d61b 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm.h @@ -212,6 +212,8 @@ extern const u16 phy_rate_table[84]; #define dm_type_by_fw 0 #define dm_type_by_driver 1 +#define HW_IGI_TXINFO_TABLE_SIZE 64 + #ifdef BB_RAM_SUPPORT struct phydm_bb_ram_per_sta { @@ -231,7 +233,7 @@ struct phydm_bb_ram_per_sta { struct phydm_bb_ram_ctrl { /*@ For 98F/14B/22C/12F, each tx_pwr_ofst step will be 1dB*/ - struct phydm_bb_ram_per_sta pram_sta_ctrl[ODM_ASSOCIATE_ENTRY_NUM]; + struct phydm_bb_ram_per_sta pram_sta_ctrl[HW_IGI_TXINFO_TABLE_SIZE]; /*------------ For table2 do not set power offset by macid --------*/ /* For type == 2'b10, 0x1e70[22:16] = tx_pwr_offset_reg0, 0x1e70[23] = enable */ boolean tx_pwr_ofst_reg0_en; @@ -239,6 +241,9 @@ struct phydm_bb_ram_ctrl { /* For type == 2'b11, 0x1e70[30:24] = tx_pwr_offset_reg1, 0x1e70[31] = enable */ boolean tx_pwr_ofst_reg1_en; u8 tx_pwr_ofst_reg1; + boolean hwigi_watchdog_en; + u64 macid_is_linked; + u64 hwigi_macid_is_linked; }; #endif @@ -432,11 +437,12 @@ enum odm_cmninfo { ODM_CMNINFO_X_CAP_SETTING, ODM_CMNINFO_ADVANCE_OTA, ODM_CMNINFO_HP_HWID, - ODM_CMNINFO_TSSI_ENABLE, + ODM_CMNINFO_TSSI_ENABLE, /*also for cmn_info_update*/ ODM_CMNINFO_DIS_DPD, ODM_CMNINFO_POWER_VOLTAGE, ODM_CMNINFO_ANTDIV_GPIO, ODM_CMNINFO_EN_AUTO_BW_TH, + ODM_CMNINFO_PEAK_DETECT_MODE, /*@-----------HOOK BEFORE REG INIT-----------*/ /*@Dynamic value:*/ @@ -506,6 +512,7 @@ enum odm_cmninfo { ODM_CMNINFO_PHYDM_PATCH_ID, ODM_CMNINFO_RRSR_VAL, ODM_CMNINFO_LINKED_BF_SUPPORT, + ODM_CMNINFO_FLATNESS_TYPE, /*@------------CALL BY VALUE-------------*/ /*@Dynamic ptr array hook itms.*/ @@ -560,6 +567,9 @@ enum phydm_info_query { PHYDM_INFO_CLM_RATIO, PHYDM_INFO_NHM_RATIO, PHYDM_INFO_NHM_NOISE_PWR, + PHYDM_INFO_NHM_PWR, + PHYDM_INFO_NHM_ENV_RATIO, + }; enum phydm_api { @@ -635,7 +645,6 @@ enum phydm_dbg_comp { DBG_PRI_CCA = BIT(F16_PRI_CCA), DBG_ADPTV_SOML = BIT(F17_ADPTV_SOML), DBG_LNA_SAT_CHK = BIT(F18_LNA_SAT_CHK), - /*BIT(19)*/ /*Neet to re-arrange*/ DBG_PHY_STATUS = BIT(20), DBG_TMP = BIT(21), @@ -643,7 +652,7 @@ enum phydm_dbg_comp { DBG_TXBF = BIT(23), DBG_COMMON_FLOW = BIT(24), DBG_COMP_MCC = BIT(25), - /*BIT(26)*/ + DBG_FW_DM = BIT(26), DBG_DM_SUMMARY = BIT(27), ODM_PHY_CONFIG = BIT(28), ODM_COMP_INIT = BIT(29), @@ -719,7 +728,9 @@ struct phydm_iot_center { u8 win_patch_id; /*Customer ID*/ boolean patch_id_100f0401; boolean patch_id_10120200; + boolean patch_id_40010700; boolean patch_id_021f0800; + boolean patch_id_011f0500; u32 phydm_patch_id; /*temp for CCX IOT */ }; @@ -750,7 +761,7 @@ struct _phydm_mcc_dm_ { }; #endif -#if (RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8197G_SUPPORT) +#if (RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) struct phydm_physts { u8 cck_gi_u_bnd; u8 cck_gi_l_bnd; @@ -854,7 +865,7 @@ struct dm_struct { boolean en_dis_dpd; u16 dis_dpd_rate; u8 en_auto_bw_th; - #if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8197G_SUPPORT) + #if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) u8 txagc_buff[RF_PATH_MEM_SIZE][PHY_NUM_RATE_IDX]; u32 bp_0x9b0; #endif @@ -974,6 +985,7 @@ struct dm_struct { u32 txagc_offset_value_b; boolean is_txagc_offset_positive_b; u8 ap_total_num; + boolean flatness_type; /*@[traffic]*/ u8 traffic_load; u8 pre_traffic_load; @@ -1064,13 +1076,17 @@ struct dm_struct { boolean en_reg_mntr_mac; boolean en_reg_mntr_byte; /*@--------------------------------------------------------------*/ -#if (RTL8814B_SUPPORT || RTL8812F_SUPPORT) - /*@--- for spur detection ---------------------------------------*/ +#if (RTL8814B_SUPPORT || RTL8812F_SUPPORT || RTL8198F_SUPPORT) u8 dsde_sel; u8 nbi_path_sel; u8 csi_wgt; - /*@------------------------------------------*/ #endif +#if (RTL8814B_SUPPORT || RTL8198F_SUPPORT) + u8 csi_wgt_th_db[5]; /*@wgt 4,3,2,1,0 */ + /* ^ ^ ^ ^ ^ */ +#endif + /*@------------------------------------------*/ + /*@--- for noise detection ---------------------------------------*/ boolean is_noisy_state; boolean noisy_decision; /*@b_noisy*/ @@ -1110,7 +1126,7 @@ struct dm_struct { boolean bsomlenabled; /* @D-SoML control */ u8 no_ndp_cnts; - u8 ndp_cnt_pre; + u16 ndp_cnt_pre; boolean is_beamformed; u8 linked_bf_support; boolean bhtstfdisabled; /* @dynamic HTSTF gain control*/ @@ -1173,6 +1189,7 @@ struct dm_struct { u8 cca_cbw20_lev; u8 cca_cbw40_lev; u8 antdiv_gpio; + u8 peak_detect_mode; #endif /*@=== PHYDM Timer ========================================== (start)*/ @@ -1251,6 +1268,15 @@ struct dm_struct { struct sw_antenna_switch dm_swat_table; #endif struct phydm_dig_struct dm_dig_table; + +#ifdef PHYDM_SUPPORT_CCKPD + struct phydm_cckpd_struct dm_cckpd_table; + + #ifdef PHYDM_DCC_ENHANCE + struct phydm_dcc_struct dm_dcc_info; /*dig cckpd coex*/ + #endif +#endif + #ifdef PHYDM_LNA_SAT_CHK_SUPPORT struct phydm_lna_sat_t dm_lna_sat_info; #endif @@ -1259,10 +1285,6 @@ struct dm_struct { struct _phydm_mcc_dm_ mcc_dm; #endif -#ifdef PHYDM_SUPPORT_CCKPD - struct phydm_cckpd_struct dm_cckpd_table; -#endif - #ifdef PHYDM_PRIMARY_CCA struct phydm_pricca_struct dm_pri_cca; #endif @@ -1327,7 +1349,7 @@ struct dm_struct { #endif /*@==========================================================*/ -#if (RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8197G_SUPPORT) +#if (RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) /*@-------------------phydm_phystatus report --------------------*/ struct phydm_physts dm_physts_table; #endif @@ -1451,6 +1473,9 @@ phydm_watchdog(struct dm_struct *dm); void phydm_watchdog_mp(struct dm_struct *dm); +void +phydm_pause_func_init(void *dm_void); + u8 phydm_pause_func(void *dm_void, enum phydm_func_idx pause_func, enum phydm_pause_type pause_type, @@ -1463,6 +1488,9 @@ phydm_pause_func_console(void *dm_void, char input[][16], u32 *_used, void phydm_pause_dm_by_asso_pkt(struct dm_struct *dm, enum phydm_pause_type pause_type, u8 rssi); +void phydm_fw_dm_ctrl_en(void *dm_void, enum phydm_func_idx fun_idx, + boolean enable); + void odm_cmn_info_init(struct dm_struct *dm, enum odm_cmninfo cmn_info, u64 value); @@ -1499,6 +1527,15 @@ phydm_dyn_bw_indication(void *dm_void); void phydm_iot_patch_id_update(void *dm_void, u32 iot_idx, boolean en); + +#ifdef CONFIG_DYNAMIC_TXCOLLISION_TH +void +phydm_tx_collsion_th_init(void *dm_void); + +void +phydm_tx_collsion_th_set(void *dm_void, u8 val_r2t, u8 val_t2r); +#endif + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) void odm_init_all_work_items( diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm.mk b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm.mk index 72fd48b58336..042db19d26ba 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm.mk +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm.mk @@ -1,4 +1,3 @@ -# SPDX-License-Identifier: GPL-2.0 EXTRA_CFLAGS += -I$(src)/hal/phydm _PHYDM_FILES := hal/phydm/phydm_debug.o \ @@ -181,6 +180,7 @@ _PHYDM_FILES += hal/phydm/$(RTL871X)/halhwimg8821c_bb.o \ hal/phydm/$(RTL871X)/halhwimg8821c_mac.o \ hal/phydm/$(RTL871X)/phydm_hal_api8821c.o \ hal/phydm/$(RTL871X)/phydm_regconfig8821c.o\ + hal/phydm/$(RTL871X)/phydm_rtl8821c.o\ hal/phydm/halrf/$(RTL871X)/halhwimg8821c_rf.o \ hal/phydm/halrf/$(RTL871X)/halrf_8821c.o\ hal/phydm/halrf/$(RTL871X)/halrf_iqk_8821c.o @@ -225,10 +225,24 @@ RTL871X = rtl8814b _PHYDM_FILES += hal/phydm/$(RTL871X)/halhwimg8814b_bb.o\ hal/phydm/$(RTL871X)/phydm_hal_api8814b.o\ hal/phydm/$(RTL871X)/phydm_regconfig8814b.o\ + hal/phydm/$(RTL871X)/phydm_extraagc8814b.o\ hal/phydm/halrf/$(RTL871X)/halhwimg8814b_rf.o\ hal/phydm/halrf/$(RTL871X)/halrf_8814b.o \ hal/phydm/halrf/$(RTL871X)/halrf_iqk_8814b.o \ hal/phydm/halrf/$(RTL871X)/halrf_dpk_8814b.o\ hal/phydm/halrf/$(RTL871X)/halrf_rfk_init_8814b.o\ hal/phydm/halrf/$(RTL871X)/halrf_txgapk_8814b.o +endif +ifeq ($(CONFIG_RTL8723F), y) +RTL871X = rtl8723f +_PHYDM_FILES += hal/phydm/$(RTL871X)/halhwimg8723f_bb.o\ + hal/phydm/$(RTL871X)/phydm_hal_api8723f.o\ + hal/phydm/$(RTL871X)/phydm_regconfig8723f.o\ + hal/phydm/$(RTL871X)/phydm_rtl8723f.o\ + hal/phydm/halrf/$(RTL871X)/halrf_8723f.o\ + hal/phydm/halrf/$(RTL871X)/halrf_iqk_8723f.o\ + hal/phydm/halrf/$(RTL871X)/halrf_tssi_8723f.o\ + hal/phydm/halrf/$(RTL871X)/halrf_dpk_8723f.o\ + hal/phydm/halrf/$(RTL871X)/halrf_rfk_init_8723f.o\ + hal/phydm/halrf/$(RTL871X)/halhwimg8723f_rf.o endif \ No newline at end of file diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adaptivity.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adaptivity.c index 7df1fd5db926..519f335ba587 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adaptivity.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adaptivity.c @@ -147,6 +147,30 @@ void phydm_check_adaptivity(void *dm_void) *dm->edcca_mode = PHYDM_EDCCA_ADAPT_MODE; } +void phydm_set_l2h_th_ini_win(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + /*@ [New Format: JGR3]IGI-idx:45 = RSSI:35 = -65dBm*/ + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + if (dm->support_ic_type & ODM_RTL8822C) + dm->th_l2h_ini = 45; + else if (dm->support_ic_type & ODM_RTL8814B) + dm->th_l2h_ini = 49; + } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + /*@ [Old Format] -11+base(50) = IGI_idx:39 = RSSI:29 = -71dBm*/ + if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8812)) { + dm->th_l2h_ini = -17; + } else { + if (*dm->band_type == ODM_BAND_5G) + dm->th_l2h_ini = -14; + else if (*dm->band_type == ODM_BAND_2_4G) + dm->th_l2h_ini = -9; + } + } else { /*ODM_IC_11N_SERIES*/ + dm->th_l2h_ini = -9; + } +} #endif void phydm_dig_up_bound_lmt_en(void *dm_void) @@ -375,10 +399,8 @@ void phydm_adaptivity_debug(void *dm_void, char input[][16], u32 *_used, s8 h2l_diff = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &dm_value[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &dm_value[i]); + input_idx++; } if (strcmp(input[1], help) == 0) { PDM_SNPF(out_len, used, output + used, out_len - used, @@ -615,6 +637,9 @@ void phydm_adaptivity_info_init(void *dm_void, enum phydm_adapinfo cmn_info, case PHYDM_ADAPINFO_AP_NUM_TH: adaptivity->ap_num_th = (u8)value; break; + case PHYDM_ADAPINFO_SWITCH_TH_L2H_INI_IN_BAND: + adaptivity->switch_th_l2h_ini_in_band = (u8)value; + break; default: break; } @@ -655,7 +680,8 @@ void phydm_adaptivity_init(void *dm_void) #if (DM_ODM_SUPPORT_TYPE & ODM_WIN) if (!dm->carrier_sense_enable) { - if (dm->th_l2h_ini == 0) + if (dm->th_l2h_ini == 0 && + !adaptivity->switch_th_l2h_ini_in_band) phydm_set_l2h_th_ini(dm); } else { phydm_set_l2h_th_ini_carrier_sense(dm); @@ -778,6 +804,11 @@ void phydm_adaptivity(void *dm_void) #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) phydm_check_adaptivity(dm); /*@Check adaptivity enable*/ + + if (!dm->carrier_sense_enable && + !adapt->debug_mode && + adapt->switch_th_l2h_ini_in_band) + phydm_set_l2h_th_ini_win(dm); #endif PHYDM_DBG(dm, DBG_ADPTVTY, "%s ====>\n", __func__); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adaptivity.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adaptivity.h index c6836b3dec9f..833839c77665 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adaptivity.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adaptivity.h @@ -67,7 +67,8 @@ enum phydm_adapinfo { PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF, PHYDM_ADAPINFO_AP_NUM_TH, PHYDM_ADAPINFO_DOMAIN_CODE_2G, - PHYDM_ADAPINFO_DOMAIN_CODE_5G + PHYDM_ADAPINFO_DOMAIN_CODE_5G, + PHYDM_ADAPINFO_SWITCH_TH_L2H_INI_IN_BAND }; enum phydm_mac_edcca_type { @@ -101,6 +102,7 @@ struct phydm_adaptivity_struct { s8 th_h2l; u8 regulation_2g; u8 regulation_5g; + u8 switch_th_l2h_ini_in_band; }; #ifdef PHYDM_SUPPORT_ADAPTIVITY diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adc_sampling.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adc_sampling.c index fc7d30b28045..371cb9a2d5fb 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adc_sampling.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adc_sampling.c @@ -136,6 +136,20 @@ phydm_la_clk_en(void *dm_void, boolean enable) } #endif +#if (RTL8723F_SUPPORT) +void +phydm_la_mac_clk_en(void *dm_void, boolean enable) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u8 val = (enable) ? 1 : 0; + + if (!(dm->support_ic_type & ODM_RTL8723F)) + return; + + odm_set_mac_reg(dm, R_0x1008, BIT(1), val); +} +#endif + #if (RTL8197F_SUPPORT) void phydm_la_stop_dma_8197f(void *dm_void, enum phydm_backup_type opt) @@ -930,6 +944,11 @@ void phydm_la_set_mac_iq_dump(void *dm_void, boolean impossible_trig_condi) /*@Enable LA mode HW block*/ odm_set_mac_reg(dm, reg1, BIT(0), 1); + #if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) + phydm_la_mac_clk_en(dm, true); + #endif + if (smp->la_trig_mode == PHYDM_MAC_TRIG) { smp->la_dump_mode = LA_MAC_DBG_DUMP; /*polling bit for MAC mode*/ @@ -1131,6 +1150,9 @@ void phydm_la_set_mac_trigger_time(void *dm_void, u32 trigger_time_mu_sec) unit = 5; /*unit: 32mu sec*/ else if (trigger_time_mu_sec < 8192) unit = 6; /*unit: 64mu sec*/ + else if (trigger_time_mu_sec < 16384) + if (dm->support_ic_type & ODM_RTL8723F) + unit = 7; /*unit: 128mu sec*/ time_unit_num = (u8)(trigger_time_mu_sec >> unit); @@ -1146,6 +1168,9 @@ void phydm_la_set_mac_trigger_time(void *dm_void, u32 trigger_time_mu_sec) odm_set_mac_reg(dm, R_0x7fc, BIT(2) | BIT(1) | BIT(0), unit); odm_set_mac_reg(dm, R_0x7f0, 0x7f00, (time_unit_num & 0x7f)); #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT + } else if (dm->support_ic_type & ODM_RTL8814B) { + odm_set_mac_reg(dm, R_0x7cc, BIT(20) | BIT(19) | BIT(18), unit); + odm_set_mac_reg(dm, R_0x7c0, 0x7f00, (time_unit_num & 0x7f)); } else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { odm_set_mac_reg(dm, R_0x7cc, BIT(18) | BIT(17) | BIT(16), unit); odm_set_mac_reg(dm, R_0x7c0, 0x7f00, (time_unit_num & 0x7f)); @@ -1204,6 +1229,10 @@ void phydm_la_set_buff_mode(void *dm_void, enum la_buff_mode mode) buff_size_base = 0x4000; end_pos_tmp = 0x8000; break; + case ODM_RTL8723F: + buff_size_base = 0x20000; + end_pos_tmp = 0x60000; + break; default: pr_debug("[%s] Warning!", __func__); break; @@ -1211,7 +1240,14 @@ void phydm_la_set_buff_mode(void *dm_void, enum la_buff_mode mode) buf->buffer_size = buff_size_base; - if (dm->support_ic_type & FULL_BUFF_MODE_SUPPORT) { + if (dm->support_ic_type & ODM_RTL8814B) { + if (mode == ADCSMP_BUFF_HALF) { + odm_set_mac_reg(dm, R_0x7cc, BIT(21), 0); + } else { + buf->buffer_size = buf->buffer_size << 1; + odm_set_mac_reg(dm, R_0x7cc, BIT(21), 1); + } + } else if (dm->support_ic_type & FULL_BUFF_MODE_SUPPORT) { if (mode == ADCSMP_BUFF_HALF) { odm_set_mac_reg(dm, R_0x7cc, BIT(30), 0); } else { @@ -1236,6 +1272,7 @@ void phydm_la_adc_smp_start(void *dm_void) u8 tmp_u1b = 0; u8 i = 0; u8 polling_bit = 0; + u8 bkp_val = 0; boolean polling_ok = false; boolean impossible_trig_condi = (smp->en_fake_trig) ? true : false; @@ -1249,6 +1286,9 @@ void phydm_la_adc_smp_start(void *dm_void) smp->la_trig_mode, smp->la_dbg_port, smp->la_trigger_edge, smp->la_smp_rate, smp->la_trig_sig_sel, smp->la_dma_type); + if(dm->support_ic_type & ODM_RTL8723F) + bkp_val = (u8)odm_get_mac_reg(dm, R_0x1008, BIT(1)); + phydm_la_set_mac_trigger_time(dm, smp->la_trigger_time); phydm_la_set_bb(dm); phydm_la_set_bb_dbg_port(dm, impossible_trig_condi); @@ -1324,6 +1364,10 @@ void phydm_la_adc_smp_start(void *dm_void) #if (RTL8821C_SUPPORT || RTL8195B_SUPPORT) phydm_la_clk_en(dm, false); #endif + #if (RTL8723F_SUPPORT) + if(dm->support_ic_type & ODM_RTL8723F) + phydm_la_mac_clk_en(dm, (bkp_val == 1) ? true : false); + #endif } else { smp->la_count--; pr_debug("LA Dump more ---------->\n\n\n"); @@ -1564,6 +1608,9 @@ void phydm_la_init(void *dm_void) struct rt_adcsmp *smp = &dm->adcsmp; struct rt_adcsmp_string *buf = &smp->adc_smp_buf; + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_LA_MODE)) + return; + smp->adc_smp_state = ADCSMP_STATE_IDLE; smp->is_la_print = true; smp->en_fake_trig = false; @@ -1579,6 +1626,9 @@ void adc_smp_de_init(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_LA_MODE)) + return; + phydm_la_stop(dm); phydm_la_buffer_release(dm); } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adc_sampling.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adc_sampling.h index 804e656ce1ca..c6429f83d705 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adc_sampling.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_adc_sampling.h @@ -29,8 +29,8 @@ #if (PHYDM_LA_MODE_SUPPORT) -/* fix compile time flag*/ -#define DYNAMIC_LA_MODE "4.1" +/* 2020.07.03 [8723F] Fix SD4 compile error*/ +#define DYNAMIC_LA_MODE "4.2" /* @1 ============================================================ * 1 Definition diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_antdiv.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_antdiv.c index 5f6174b6cd1a..192e4edb74e1 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_antdiv.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_antdiv.c @@ -38,6 +38,114 @@ ***************************************************** */ #ifdef CONFIG_PHYDM_ANTENNA_DIVERSITY +#if (RTL8710C_SUPPORT == 1) +void odm_s0s1_sw_ant_div_init_8710c(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct sw_antenna_switch *swat_tab = &dm->dm_swat_table; + struct phydm_fat_struct *fat_tab = &dm->dm_fat_table; + + PHYDM_DBG(dm, DBG_ANT_DIV, + "***8710C AntDiv_Init => ant_div_type=[ S0S1_SW_AntDiv]\n"); + /*MAC setting*/ + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0xdc, HAL_READ32(SYSTEM_CTRL_BASE, R_0xdc) | BIT18 | BIT17 | BIT16); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0xac, HAL_READ32(SYSTEM_CTRL_BASE, R_0xac) | BIT24 | BIT6); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x10, 0x307); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x08, 0x80000111); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x1208, 0x800000); + + /* Status init */ + fat_tab->is_become_linked = false; + swat_tab->try_flag = SWAW_STEP_INIT; + swat_tab->double_chk_flag = 0; + swat_tab->cur_antenna = MAIN_ANT; + swat_tab->pre_ant = MAIN_ANT; + dm->antdiv_counter = CONFIG_ANTDIV_PERIOD; +} + +void odm_trx_hw_ant_div_init_8710c(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + PHYDM_DBG(dm, DBG_ANT_DIV, + "[8710C] AntDiv_Init => ant_div_type=[CG_TRX_HW_ANTDIV]\n"); + odm_set_mac_reg(dm, R_0x74, BIT(13) | BIT(12), 1); + odm_set_mac_reg(dm, R_0x74, BIT(4), 1); + + /*@BT Coexistence*/ + /*@keep antsel_map when GNT_BT = 1*/ + odm_set_bb_reg(dm, R_0x864, BIT(12), 1); + + /* @Disable hw antsw & fast_train.antsw when GNT_BT=1 */ + odm_set_bb_reg(dm, R_0x874, BIT(23), 1); + odm_set_bb_reg(dm, R_0x930, 0xF00, 8); /* RFE CTRL_2 ANTSEL0 */ + + odm_set_bb_reg(dm, R_0x870, BIT(8), 0); + odm_set_bb_reg(dm, R_0x804, BIT(8), 0); /* r_keep_rfpin */ + + /*@Mapping Table*/ + //odm_set_bb_reg(dm, R_0x864, BIT2|BIT1|BIT0, 2); + odm_set_bb_reg(dm, R_0x944, 0xFFFF, 0xffff); + odm_set_bb_reg(dm, R_0x914, MASKBYTE0, 0); + odm_set_bb_reg(dm, R_0x914, MASKBYTE1, 1); + /*@antenna training */ + odm_set_bb_reg(dm, R_0xe08, BIT(16), 0); + + //need to check!!!!!!!!!! + /* Set WLBB_SEL_RF_ON 1 if RXFIR_PWDB > 0xCcc[3:0] */ + odm_set_bb_reg(dm, R_0xccc, BIT(12), 0); + /* @Low-to-High threshold for WLBB_SEL_RF_ON when OFDM enable */ + odm_set_bb_reg(dm, R_0xccc, 0x0F, 0x01); + /* @High-to-Low threshold for WLBB_SEL_RF_ON when OFDM enable */ + odm_set_bb_reg(dm, R_0xccc, 0xF0, 0x0); + /* @b Low-to-High threshold for WLBB_SEL_RF_ON when OFDM disable (CCK)*/ + odm_set_bb_reg(dm, R_0xabc, 0xFF, 0x06); + /* @High-to-Low threshold for WLBB_SEL_RF_ON when OFDM disable (CCK) */ + odm_set_bb_reg(dm, R_0xabc, 0xFF00, 0x00); + + /*OFDM HW AntDiv Parameters*/ + odm_set_bb_reg(dm, R_0xca4, 0x7FF, 0x80); + odm_set_bb_reg(dm, R_0xca4, 0x7FF000, 0x00); + odm_set_bb_reg(dm, R_0xc5c, BIT(20) | BIT(19) | BIT(18), 0x04); + + /*@CCK HW AntDiv Parameters*/ + odm_set_bb_reg(dm, R_0xa74, BIT(7), 1); + odm_set_bb_reg(dm, R_0xa0c, BIT(4), 1); + odm_set_bb_reg(dm, R_0xaa8, BIT(8), 0); + + odm_set_bb_reg(dm, R_0xa0c, 0x0F, 0xf); + odm_set_bb_reg(dm, R_0xa14, 0x1F, 0xf); + odm_set_bb_reg(dm, R_0xa10, BIT(13), 0x1); + odm_set_bb_reg(dm, R_0xa74, BIT(8), 0x0); + odm_set_bb_reg(dm, R_0xb34, BIT(30), 0x1); +} +void odm_update_rx_idle_ant_8710c(void *dm_void, u8 ant, u32 default_ant, + u32 optional_ant) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_fat_struct *fat_tab = &dm->dm_fat_table; + void *adapter = dm->adapter; + + PHYDM_DBG(dm, DBG_ANT_DIV, + "***odm_update_rx_idle_ant_8710c!!!\n"); + if (dm->ant_div_type == S0S1_SW_ANTDIV) { + if (default_ant == 0x0) + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x1210,0x800000); + else + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x1214,0x800000); + + fat_tab->rx_idle_ant = ant; + }else if (dm->ant_div_type == CG_TRX_HW_ANTDIV) { + odm_set_bb_reg(dm, R_0x864, BIT(5) | BIT(4) | BIT(3), default_ant); + /*@Default RX*/ + odm_set_bb_reg(dm, R_0x864, BIT(8) | BIT(7) | BIT(6), optional_ant); + /*@Optional RX*/ + odm_set_bb_reg(dm, R_0x860, BIT(14) | BIT(13) | BIT(12), default_ant); + /*@Default TX*/ + fat_tab->rx_idle_ant = ant; + } +} +#endif #if (RTL8721D_SUPPORT == 1) @@ -121,6 +229,15 @@ void odm_trx_hw_ant_div_init_8721d(void *dm_void) Pinmux_Config(_PB_29, PINMUX_FUNCTION_RFE); break; } + case ANTDIV_GPIO_PB1PB2PB26:{ + PAD_CMD(_PB_1, ENABLE); + Pinmux_Config(_PB_1, PINMUX_FUNCTION_RFE); + PAD_CMD(_PB_2, ENABLE); + Pinmux_Config(_PB_2, PINMUX_FUNCTION_RFE); + PAD_CMD(_PB_26, ENABLE); + Pinmux_Config(_PB_26, PINMUX_FUNCTION_RFE); + break; + } default: { } } @@ -141,7 +258,14 @@ void odm_trx_hw_ant_div_init_8721d(void *dm_void) odm_set_bb_reg(dm, R_0x930, 0xF00, 8); odm_set_bb_reg(dm, R_0x930, 0xF000, 8); odm_set_bb_reg(dm, R_0x92c, BIT(3) | BIT(2), 2); - odm_set_bb_reg(dm, R_0x944, 0x0000000C, 0x3); + odm_set_bb_reg(dm, R_0x944, 0x0000000C, 0x3); + } + else if(dm->antdiv_gpio == ANTDIV_GPIO_PB1PB2PB26){ + /* 3 antenna diversity for AmebaD only */ + odm_set_bb_reg(dm, R_0x930, 0xF, 8); + odm_set_bb_reg(dm, R_0x930, 0xF0, 9); + odm_set_bb_reg(dm, R_0x930, 0xF00,0xa); /* set the RFE control table to select antenna*/ + odm_set_bb_reg(dm, R_0x944, 0x00000007, 0x7); } u32 sysreg208 = HAL_READ32(SYSTEM_CTRL_BASE_LP, REG_LP_FUNC_EN0); @@ -178,6 +302,11 @@ void odm_trx_hw_ant_div_init_8721d(void *dm_void) /*@Mapping Table*/ odm_set_bb_reg(dm, R_0x914, MASKBYTE0, 0); odm_set_bb_reg(dm, R_0x914, MASKBYTE1, 1); + if (dm->antdiv_gpio == ANTDIV_GPIO_PB1PB2PB26) { + odm_set_bb_reg(dm, R_0x914, 0x00000F, 0x1); + odm_set_bb_reg(dm, R_0x914, 0x000F00, 0x2); + odm_set_bb_reg(dm, R_0x914, 0x0F0000, 0x4); + } /* odm_set_bb_reg(dm, R_0x864, BIT5|BIT4|BIT3, 0); */ /* odm_set_bb_reg(dm, R_0x864, BIT8|BIT7|BIT6, 1); */ @@ -224,6 +353,9 @@ void odm_stop_antenna_switch_dm(void *dm_void) struct phydm_fat_struct *fat_tab = &dm->dm_fat_table; /* @disable ODM antenna diversity */ dm->support_ability &= ~ODM_BB_ANT_DIV; +#if (RTL8710C_SUPPORT == 1) + dm->support_ability |= ODM_BB_ANT_DIV; +#endif if (fat_tab->div_path_type == ANT_PATH_A) odm_ant_div_on_off(dm, ANTDIV_OFF, ANT_PATH_A); else if (fat_tab->div_path_type == ANT_PATH_B) @@ -347,7 +479,7 @@ void phydm_ac_on_off(void *dm_void, u8 swch, u8 path) odm_set_bb_reg(dm, R_0x800, BIT(25), swch); odm_set_bb_reg(dm, R_0xa00, BIT(15), swch); /* @CCK AntDiv function block enable */ - } else if (dm->support_ic_type == ODM_RTL8821C) { + } else { PHYDM_DBG(dm, DBG_ANT_DIV, "(Turn %s) CCK HW-AntDiv\n", (swch == ANTDIV_ON) ? "ON" : "OFF"); odm_set_bb_reg(dm, R_0x800, BIT(25), swch); @@ -537,6 +669,13 @@ void phydm_update_rx_idle_n(void *dm_void, u8 ant, u32 default_ant, odm_update_rx_idle_ant_8721d(dm, ant, default_ant, optional_ant); #endif + +#if (RTL8710C_SUPPORT == 1) + } else if (dm->support_ic_type == ODM_RTL8710C) { + odm_update_rx_idle_ant_8710c(dm, ant, default_ant, + optional_ant); +#endif + } else { /*@8188E & 8188F*/ /*@ if (dm->support_ic_type == ODM_RTL8723D) {*/ @@ -609,7 +748,7 @@ void odm_update_rx_idle_ant(void *dm_void, u8 ant) } /*PathA Resp Tx*/ if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8822B | - ODM_RTL8814A)) + ODM_RTL8814A | ODM_RTL8195B)) odm_set_mac_reg(dm, R_0x6d8, 0x7, default_tx_ant); else if (dm->support_ic_type == ODM_RTL8188E) odm_set_mac_reg(dm, R_0x6d8, 0xc0, default_tx_ant); @@ -626,6 +765,43 @@ void odm_update_rx_idle_ant(void *dm_void, u8 ant) } } +#if (RTL8721D_SUPPORT) +void odm_update_rx_idle_ant_sp3t(void *dm_void, u8 ant) /* added by Jiao Qi on May.25,2020, for AmebaD SP3T only */ +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_fat_struct *fat_tab = &dm->dm_fat_table; + u32 default_ant, optional_ant, value32, default_tx_ant; + + if (!(dm->support_ic_type & ODM_RTL8723B)) + fat_tab->rx_idle_ant = ant; + + default_ant = fat_tab->ant_idx_vec[0]-1; + optional_ant = fat_tab->ant_idx_vec[1]-1; + + if(fat_tab->b_fix_tx_ant != NO_FIX_TX_ANT) + default_tx_ant = (fat_tab->b_fix_tx_ant == + FIX_TX_AT_MAIN) ? 0 : 1; + else + default_tx_ant = default_ant; + + odm_set_bb_reg(dm, R_0x864, BIT(5) | BIT(4) | BIT(3), default_ant); + /*@Default RX*/ + odm_set_bb_reg(dm, R_0x864, BIT(8) | BIT(7) | BIT(6), optional_ant); + /*@Optional RX*/ + odm_set_bb_reg(dm, R_0x860, BIT(14) | BIT(13) | BIT(12), default_ant); + /*@Default TX*/ + + /*PathA Resp Tx*/ + if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8822B | + ODM_RTL8814A)) + odm_set_mac_reg(dm, R_0x6d8, 0x7, default_tx_ant); + else if (dm->support_ic_type == ODM_RTL8188E) + odm_set_mac_reg(dm, R_0x6d8, 0xc0, default_tx_ant); + else + odm_set_mac_reg(dm, R_0x6d8, 0x700, default_tx_ant); + +} +#endif void phydm_update_rx_idle_ant_pathb(void *dm_void, u8 ant) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -672,6 +848,9 @@ void phydm_set_antdiv_val(void *dm_void, u32 *val_buf, u8 val_len) { struct dm_struct *dm = (struct dm_struct *)dm_void; + if (!(dm->support_ability & ODM_BB_ANT_DIV)) + return; + if (val_len != 1) { PHYDM_DBG(dm, ODM_COMP_API, "[Error][antdiv]Need val_len=1\n"); return; @@ -698,7 +877,16 @@ void odm_update_tx_ant(void *dm_void, u8 ant, u32 mac_id) else tx_ant = ANT2_2G; } - +#if (RTL8721D_SUPPORT) + if (dm->antdiv_gpio != ANTDIV_GPIO_PB1PB2PB26) { + if (ant == MAIN_ANT) + tx_ant = ANT1_2G; + else + tx_ant = ANT2_2G; + } + else + tx_ant = fat_tab->ant_idx_vec[0]-1; +#endif fat_tab->antsel_a[mac_id] = tx_ant & BIT(0); fat_tab->antsel_b[mac_id] = (tx_ant & BIT(1)) >> 1; fat_tab->antsel_c[mac_id] = (tx_ant & BIT(2)) >> 2; @@ -2313,6 +2501,55 @@ void phydm_s0s1_sw_ant_div_init_8821c(void *dm_void) } #endif /* @#if (RTL8821C_SUPPORT == 1) */ +#if (RTL8195B_SUPPORT == 1) +void odm_trx_hw_ant_div_init_8195b(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + PHYDM_DBG(dm, DBG_ANT_DIV, "[%s]=====>\n", __func__); + + odm_set_bb_reg(dm, R_0xcb8, BIT(16), 0); + /*RFE control pin 0,1*/ + odm_set_bb_reg(dm, R_0xcb0, 0xF, 8); /* @DPDT_P = ANTSEL[0] */ + odm_set_bb_reg(dm, R_0xcb0, 0xF0, 8); /* @DPDT_N = ANTSEL[0] */ + odm_set_bb_reg(dm, R_0xcb4, BIT(20), 0); /* @DPDT_P non-inverse */ + odm_set_bb_reg(dm, R_0xcb4, BIT(21), 1); /* @DPDT_N inverse */ + + /* @Mapping Table */ + odm_set_bb_reg(dm, R_0xca4, MASKBYTE0, 0); + odm_set_bb_reg(dm, R_0xca4, MASKBYTE1, 1); + + /* OFDM HW AntDiv Parameters */ + odm_set_bb_reg(dm, R_0x8d4, 0x7FF, 0xA0); /* thershold */ + odm_set_bb_reg(dm, R_0x8d4, 0x7FF000, 0x10); /* @bias */ + + /* @CCK HW AntDiv Parameters */ + odm_set_bb_reg(dm, R_0xa74, BIT(7), 1); + /* patch for clk from 88M to 80M */ + odm_set_bb_reg(dm, R_0xa0c, BIT(4), 1); /* @do 64 samples */ + + odm_set_bb_reg(dm, R_0x800, BIT(25), 0); + /* @ANTSEL_CCK sent to the smart_antenna circuit */ + odm_set_bb_reg(dm, R_0xa00, BIT(15), 0); + /* @CCK AntDiv function block enable */ + + /* @BT Coexistence */ + odm_set_bb_reg(dm, R_0xcac, BIT(9), 1); + /* @keep antsel_map when GNT_BT = 1 */ + odm_set_bb_reg(dm, R_0x804, BIT(4), 1); + /* @Disable hw antsw & fast_train.antsw when GNT_BT=1 */ + + /* Timming issue */ + odm_set_bb_reg(dm, R_0x818, BIT(23) | BIT(22) | BIT(21) | BIT(20), 0); + /*@keep antidx after tx for ACK ( unit x 3.2 mu sec)*/ + odm_set_bb_reg(dm, R_0x8cc, BIT(20) | BIT(19) | BIT(18), 3); + /* settling time of antdiv by RF LNA = 100ns */ + + /* response TX ant by RX ant */ + odm_set_mac_reg(dm, R_0x668, BIT(3), 1); +} +#endif /* @#if (RTL8195B_SUPPORT == 1) */ + #if (RTL8881A_SUPPORT == 1) void odm_trx_hw_ant_div_init_8881a(void *dm_void) { @@ -3211,7 +3448,7 @@ void odm_hw_ant_div(void *dm_void) target_ant = (mian_cnt == aux_cnt) ? fat_tab->rx_idle_ant : ((mian_cnt >= aux_cnt) ? - MAIN_ANT : AUX_ANT); + fat_tab->ant_idx_vec[0]:fat_tab->ant_idx_vec[1]); /*Use counter number for OFDM*/ } else { /*@CCK only case*/ @@ -3224,9 +3461,28 @@ void odm_hw_ant_div(void *dm_void) target_ant = (main_rssi == aux_rssi) ? fat_tab->rx_idle_ant : ((main_rssi >= aux_rssi) ? - MAIN_ANT : AUX_ANT); + fat_tab->ant_idx_vec[0]:fat_tab->ant_idx_vec[1]); /*Use RSSI for CCK only case*/ } +#if (RTL8721D_SUPPORT) + if(dm->antdiv_gpio == ANTDIV_GPIO_PB1PB2PB26) { /* added by Jiao Qi on May.25,2020, only for 3 antenna diversity */ + u8 tmp; + if(target_ant == fat_tab->ant_idx_vec[0]){/* switch the second & third ant index */ + tmp = fat_tab->ant_idx_vec[1]; + fat_tab->ant_idx_vec[1] = fat_tab->ant_idx_vec[2]; + fat_tab->ant_idx_vec[2] = tmp; + }else{ + /* switch the first & second ant index */ + tmp = fat_tab->ant_idx_vec[0]; + fat_tab->ant_idx_vec[0] = fat_tab->ant_idx_vec[1]; + fat_tab->ant_idx_vec[1] = tmp; + /* switch the second & third ant index */ + tmp = fat_tab->ant_idx_vec[1]; + fat_tab->ant_idx_vec[1] = fat_tab->ant_idx_vec[2]; + fat_tab->ant_idx_vec[2] = tmp; + } + } +#endif PHYDM_DBG(dm, DBG_ANT_DIV, "*** Client[ %d ] : Main_Cnt = (( %d )) , CCK_Main_Cnt = (( %d )) , main_rssi= (( %d ))\n", @@ -3366,7 +3622,13 @@ void odm_hw_ant_div(void *dm_void) #endif odm_update_rx_idle_ant(dm, rx_idle_ant); #else - +#if (RTL8721D_SUPPORT) +if (dm->antdiv_gpio == ANTDIV_GPIO_PB1PB2PB26) { + if(odm_get_bb_reg(dm,R_0xc50,0x80) || odm_get_bb_reg(dm, R_0xa00, 0x8000)) + odm_update_rx_idle_ant_sp3t(dm, rx_idle_ant); +} +else +#endif odm_update_rx_idle_ant(dm, rx_idle_ant); #endif /* @#if(DM_ODM_SUPPORT_TYPE == ODM_AP) */ @@ -3530,7 +3792,7 @@ void phydm_sw_antdiv_decision(void *dm_void) (fat_tab->main_sum[i] / main_cnt) : 0; aux_rssi = (aux_cnt != 0) ? (fat_tab->aux_sum[i] / aux_cnt) : 0; - if (dm->support_ic_type == ODM_RTL8723D) { + if (dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8710C) { cond_23d_main = (aux_cnt > main_cnt) && ((main_rssi - aux_rssi < 5) || (aux_rssi > main_rssi)); @@ -3800,6 +4062,24 @@ void odm_s0s1_sw_ant_div(void *dm_void, u8 step) PHYDM_DBG(dm, DBG_ANT_DIV, "8723D: First link! Force antenna to %s\n", (value32 == 0x0 ? "MAIN" : "AUX")); +#endif + } + if (dm->support_ic_type == ODM_RTL8710C) { +#if (RTL8710C_SUPPORT == 1) + value32 = (HAL_READ32(SYSTEM_CTRL_BASE, R_0x121c) & 0x800000); + if (value32 == 0x0) + odm_update_rx_idle_ant_8710c(dm, + MAIN_ANT, + ANT1_2G, + ANT2_2G); + else if (value32 == 0x1) + odm_update_rx_idle_ant_8710c(dm, + AUX_ANT, + ANT2_2G, + ANT1_2G); + PHYDM_DBG(dm, DBG_ANT_DIV, + "8710C: First link! Force antenna to %s\n", + (value32 == 0x0 ? "MAIN" : "AUX")); #endif } fat_tab->is_become_linked = dm->is_linked; @@ -3922,7 +4202,8 @@ void odm_s0s1_sw_ant_div(void *dm_void, u8 step) fat_tab->rx_idle_ant = next_ant; - if (dm->support_ic_type == ODM_RTL8723D) { + if (dm->support_ic_type == ODM_RTL8723D || dm->support_ic_type == ODM_RTL8710C) { + if (fat_tab->rx_idle_ant == MAIN_ANT) { fat_tab->main_sum[0] = 0; fat_tab->main_cnt[0] = 0; @@ -4025,6 +4306,14 @@ void odm_sw_antdiv_callback(void *function_context) #endif } +#elif (DM_ODM_SUPPORT_TYPE == ODM_IOT) +void odm_sw_antdiv_callback(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + PHYDM_DBG(dm, DBG_ANT_DIV, "******AntDiv_Callback******\n"); + odm_s0s1_sw_ant_div(dm, SWAW_STEP_DETERMINE); +} #endif void odm_s0s1_sw_ant_div_by_ctrl_frame(void *dm_void, u8 step) @@ -4420,7 +4709,7 @@ void odm_ant_div_init(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_fat_struct *fat_tab = &dm->dm_fat_table; struct sw_antenna_switch *swat_tab = &dm->dm_swat_table; - + u8 i; if (!(dm->support_ability & ODM_BB_ANT_DIV)) { PHYDM_DBG(dm, DBG_ANT_DIV, "[Return!!!] Not Support Antenna Diversity Function\n"); @@ -4450,6 +4739,10 @@ void odm_ant_div_init(void *dm_void) fat_tab->is_become_linked = false; fat_tab->ant_div_on_off = 0xff; + + for(i=0;i<3;i++) + fat_tab->ant_idx_vec[i]=i+1; /* initialize ant_idx_vec for SP3T */ + /* @3 - AP - */ #if (DM_ODM_SUPPORT_TYPE == ODM_AP) @@ -4464,6 +4757,8 @@ void odm_ant_div_init(void *dm_void) #elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) swat_tab->ant_5g = MAIN_ANT; swat_tab->ant_2g = MAIN_ANT; +//#elif (DM_ODM_SUPPORT_TYPE == ODM_IOT) +// swat_tab->ant_2g = MAIN_ANT; #endif /* @2 [---Set MAIN_ANT as default antenna if Auto-ant enable---] */ @@ -4477,7 +4772,30 @@ void odm_ant_div_init(void *dm_void) dm->ant_type = ODM_AUTO_ANT; fat_tab->rx_idle_ant = 0xff; - /*to make RX-idle-antenna will be updated absolutly*/ + + if (dm->support_ic_type == ODM_RTL8710C) { + /* Soft ware*/ +#if (RTL8710C_SUPPORT == 1) + if (dm->ant_div_type == S0S1_SW_ANTDIV) { + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0xdc, HAL_READ32(SYSTEM_CTRL_BASE, R_0xdc) | BIT18 | BIT17 | BIT16); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0xac, HAL_READ32(SYSTEM_CTRL_BASE, R_0xac) | BIT24 | BIT6); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x10, 0x307);// 1: enable gpio db32 clock , 1: enable gpio pclock + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x08, 0x80000111); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0x1208, 0x800000); + } else if (dm->ant_div_type == CG_TRX_HW_ANTDIV) { + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0xdc, HAL_READ32(SYSTEM_CTRL_BASE, R_0xdc) | BIT18 | BIT17); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0xdc, HAL_READ32(SYSTEM_CTRL_BASE, R_0xdc) & (~BIT16)); + HAL_WRITE32(SYSTEM_CTRL_BASE, R_0xac, HAL_READ32(SYSTEM_CTRL_BASE, R_0xac) | BIT24 | BIT6); + } else { + PHYDM_DBG(dm, DBG_ANT_DIV, + "[Return!!!] 8710C Not Supprrt This AntDiv type\n"); + dm->support_ability &= ~(ODM_BB_ANT_DIV); + return; + } +#endif + } + + /*to make RX-idle-antenna will be updated absolutly*/ odm_update_rx_idle_ant(dm, MAIN_ANT); phydm_keep_rx_ack_ant_by_tx_ant_time(dm, 0); /* Timming issue: keep Rx ant after tx for ACK(5 x 3.2 mu = 16mu sec)*/ @@ -4645,6 +4963,25 @@ void odm_ant_div_init(void *dm_void) } } #endif +#if (RTL8710C_SUPPORT == 1) + else if (dm->support_ic_type == ODM_RTL8710C) { + if (dm->ant_div_type == CG_TRX_HW_ANTDIV) + odm_trx_hw_ant_div_init_8710c(dm); + else if(dm->ant_div_type == S0S1_SW_ANTDIV){ + if (fat_tab->p_default_s0_s1 == NULL){ + fat_tab->default_s0_s1 = 1; + fat_tab->p_default_s0_s1 = &fat_tab->default_s0_s1; + } + PHYDM_DBG(dm, DBG_ANT_DIV, "default_s0_s1 = %d\n", + *fat_tab->p_default_s0_s1); + if (*fat_tab->p_default_s0_s1 == true) + odm_update_rx_idle_ant(dm, MAIN_ANT); + else + odm_update_rx_idle_ant(dm, AUX_ANT); + odm_s0s1_sw_ant_div_init_8710c(dm); + } + } +#endif #if (RTL8721D_SUPPORT == 1) else if (dm->support_ic_type == ODM_RTL8721D) { /* @dm->ant_div_type = CG_TRX_HW_ANTDIV; */ @@ -4707,6 +5044,20 @@ void odm_ant_div_init(void *dm_void) } #endif +/* @2 [--8195B---] */ +#if (RTL8195B_SUPPORT == 1) + else if (dm->support_ic_type == ODM_RTL8195B) { + dm->ant_div_type = CG_TRX_HW_ANTDIV; + if (dm->ant_div_type != CG_TRX_HW_ANTDIV) { + PHYDM_DBG(dm, DBG_ANT_DIV, + "[Return!!!] 8821C Not Supprrt This AntDiv type\n"); + dm->support_ability &= ~(ODM_BB_ANT_DIV); + return; + } + odm_trx_hw_ant_div_init_8195b(dm); + } +#endif + /* @2 [--8881A---] */ #if (RTL8881A_SUPPORT == 1) else if (dm->support_ic_type == ODM_RTL8881A) { @@ -4786,6 +5137,9 @@ void odm_ant_div(void *dm_void) struct smt_ant_honbo *sat_tab = &dm->dm_sat_table; #endif + if (!(dm->support_ability & ODM_BB_ANT_DIV)) + return; + #ifdef ODM_EVM_ENHANCE_ANTDIV if (dm->is_linked) { PHYDM_DBG(dm, DBG_ANT_DIV, @@ -5061,6 +5415,24 @@ void odm_ant_div(void *dm_void) } } #endif +#if (RTL8710C_SUPPORT == 1) + else if (dm->support_ic_type == ODM_RTL8710C) { + if (dm->ant_div_type == S0S1_SW_ANTDIV) { + #ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY + if (dm->antdiv_counter == CONFIG_ANTDIV_PERIOD) { + odm_s0s1_sw_ant_div(dm, SWAW_STEP_PEEK); + dm->antdiv_counter--; + } else { + dm->antdiv_counter--; + } + if (dm->antdiv_counter == 0) + dm->antdiv_counter = CONFIG_ANTDIV_PERIOD; + #endif + } else if (dm->ant_div_type == CG_TRX_HW_ANTDIV) { + odm_hw_ant_div(dm); + } + } +#endif /*@ [--8821A--] */ #if (RTL8821A_SUPPORT == 1) else if (dm->support_ic_type == ODM_RTL8821) { @@ -5146,6 +5518,15 @@ void odm_ant_div(void *dm_void) } #endif +/* @ [--8195B--] */ +#if (RTL8195B_SUPPORT == 1) + else if (dm->support_ic_type == ODM_RTL8195B) { + if (dm->ant_div_type == CG_TRX_HW_ANTDIV) { + odm_hw_ant_div(dm); + } + } +#endif + /* @ [--8881A--] */ #if (RTL8881A_SUPPORT == 1) else if (dm->support_ic_type == ODM_RTL8881A) @@ -5198,7 +5579,7 @@ void odm_antsel_statistics(void *dm_void, void *phy_info_void, if (method == RSSI_METHOD) { if (is_cck_rate) { - if (antsel_tr_mux == ANT1_2G) { + if (antsel_tr_mux == fat_tab->ant_idx_vec[0]-1) { /*to prevent u16 overflow, max(RSSI)=100, 65435+100 = 65535 (u16)*/ if (fat_tab->main_sum_cck[mac_id] > 65435) return; @@ -5215,7 +5596,7 @@ void odm_antsel_statistics(void *dm_void, void *phy_info_void, } else { /*ofdm rate*/ - if (antsel_tr_mux == ANT1_2G) { + if (antsel_tr_mux == fat_tab->ant_idx_vec[0]-1) { if (fat_tab->main_sum[mac_id] > 65435) return; @@ -5315,7 +5696,7 @@ void odm_process_rssi_normal(void *dm_void, void *phy_info_void, if (dm->ant_div_type == S0S1_SW_ANTDIV) { if (pktinfo->is_cck_rate || - dm->support_ic_type == ODM_RTL8188F) { + dm->support_ic_type == ODM_RTL8188F || dm->support_ic_type == ODM_RTL8710C) { b_main = (fat_tab->rx_idle_ant == MAIN_ANT); fat_tab->antsel_rx_keep_0 = b_main ? ANT1_2G : ANT2_2G; @@ -5616,6 +5997,10 @@ void odm_set_tx_ant_by_tx_info(void *dm_void, u8 *desc, u8 mac_id) * mac_id, fat_tab->antsel_c[mac_id], fat_tab->antsel_b[mac_id], * fat_tab->antsel_a[mac_id]); */ +#endif + } else if (dm->support_ic_type == ODM_RTL8195B) { +#if (RTL8195B_SUPPORT == 1) + SET_TX_DESC_ANTSEL_A_8195B(desc, fat_tab->antsel_a[mac_id]); #endif } else if (dm->support_ic_type == ODM_RTL8822B) { #if (RTL8822B_SUPPORT == 1) @@ -5762,6 +6147,12 @@ void odm_ant_div_config(void *dm_void) if (dm->support_ic_type == ODM_RTL8721D) dm->ant_div_type = CG_TRX_HW_ANTDIV; + if (dm->support_ic_type == ODM_RTL8710C){ + if(dm->cut_version > ODM_CUT_C) + dm->ant_div_type = CG_TRX_HW_ANTDIV; + else + dm->ant_div_type = S0S1_SW_ANTDIV; + } #elif (DM_ODM_SUPPORT_TYPE & (ODM_AP)) @@ -5782,45 +6173,45 @@ void odm_ant_div_config(void *dm_void) if (dm->support_ic_type & ODM_ANTDIV_SUPPORT) dm->support_ability |= ODM_BB_ANT_DIV; if (*dm->band_type == ODM_BAND_5G) { -#if (defined(CONFIG_5G_CGCS_RX_DIVERSITY)) + #if (defined(CONFIG_5G_CGCS_RX_DIVERSITY)) dm->ant_div_type = CGCS_RX_HW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = CGCS_RX_HW_ANTDIV\n"); panic_printk("[ 5G] : AntDiv type = CGCS_RX_HW_ANTDIV\n"); -#elif (defined(CONFIG_5G_CG_TRX_DIVERSITY) ||\ - defined(CONFIG_2G5G_CG_TRX_DIVERSITY_8881A)) + #elif (defined(CONFIG_5G_CG_TRX_DIVERSITY) ||\ + defined(CONFIG_2G5G_CG_TRX_DIVERSITY_8881A)) dm->ant_div_type = CG_TRX_HW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = CG_TRX_HW_ANTDIV\n"); panic_printk("[ 5G] : AntDiv type = CG_TRX_HW_ANTDIV\n"); -#elif (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) + #elif (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) dm->ant_div_type = CG_TRX_SMART_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = CG_SMART_ANTDIV\n"); -#elif (defined(CONFIG_5G_S0S1_SW_ANT_DIVERSITY)) + #elif (defined(CONFIG_5G_S0S1_SW_ANT_DIVERSITY)) dm->ant_div_type = S0S1_SW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = S0S1_SW_ANTDIV\n"); -#endif + #endif } else if (*dm->band_type == ODM_BAND_2_4G) { -#if (defined(CONFIG_2G_CGCS_RX_DIVERSITY)) + #if (defined(CONFIG_2G_CGCS_RX_DIVERSITY)) dm->ant_div_type = CGCS_RX_HW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = CGCS_RX_HW_ANTDIV\n"); -#elif (defined(CONFIG_2G_CG_TRX_DIVERSITY) ||\ - defined(CONFIG_2G5G_CG_TRX_DIVERSITY_8881A)) + #elif (defined(CONFIG_2G_CG_TRX_DIVERSITY) ||\ + defined(CONFIG_2G5G_CG_TRX_DIVERSITY_8881A)) dm->ant_div_type = CG_TRX_HW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = CG_TRX_HW_ANTDIV\n"); -#elif (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY)) + #elif (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY)) dm->ant_div_type = CG_TRX_SMART_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = CG_SMART_ANTDIV\n"); -#elif (defined(CONFIG_2G_S0S1_SW_ANT_DIVERSITY)) + #elif (defined(CONFIG_2G_S0S1_SW_ANT_DIVERSITY)) dm->ant_div_type = S0S1_SW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = S0S1_SW_ANTDIV\n"); -#endif + #endif } /* @2 [ 5G_SUPPORT_ANTDIV ] */ @@ -5832,25 +6223,25 @@ void odm_ant_div_config(void *dm_void) if (*dm->band_type == ODM_BAND_5G) { if (dm->support_ic_type & ODM_ANTDIV_5G_SUPPORT_IC) dm->support_ability |= ODM_BB_ANT_DIV; -#if (defined(CONFIG_5G_CGCS_RX_DIVERSITY)) + #if (defined(CONFIG_5G_CGCS_RX_DIVERSITY)) dm->ant_div_type = CGCS_RX_HW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = CGCS_RX_HW_ANTDIV\n"); panic_printk("[ 5G] : AntDiv type = CGCS_RX_HW_ANTDIV\n"); -#elif (defined(CONFIG_5G_CG_TRX_DIVERSITY)) + #elif (defined(CONFIG_5G_CG_TRX_DIVERSITY)) dm->ant_div_type = CG_TRX_HW_ANTDIV; panic_printk("[ 5G] : AntDiv type = CG_TRX_HW_ANTDIV\n"); PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = CG_TRX_HW_ANTDIV\n"); -#elif (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) + #elif (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) dm->ant_div_type = CG_TRX_SMART_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = CG_SMART_ANTDIV\n"); -#elif (defined(CONFIG_5G_S0S1_SW_ANT_DIVERSITY)) + #elif (defined(CONFIG_5G_S0S1_SW_ANT_DIVERSITY)) dm->ant_div_type = S0S1_SW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 5G] : AntDiv type = S0S1_SW_ANTDIV\n"); -#endif + #endif } else if (*dm->band_type == ODM_BAND_2_4G) { PHYDM_DBG(dm, DBG_ANT_DIV, "Not Support 2G ant_div_type\n"); dm->support_ability &= ~(ODM_BB_ANT_DIV); @@ -5864,28 +6255,33 @@ void odm_ant_div_config(void *dm_void) if (*dm->band_type == ODM_BAND_2_4G) { if (dm->support_ic_type & ODM_ANTDIV_2G_SUPPORT_IC) dm->support_ability |= ODM_BB_ANT_DIV; -#if (defined(CONFIG_2G_CGCS_RX_DIVERSITY)) + #if (defined(CONFIG_2G_CGCS_RX_DIVERSITY)) dm->ant_div_type = CGCS_RX_HW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = CGCS_RX_HW_ANTDIV\n"); -#elif (defined(CONFIG_2G_CG_TRX_DIVERSITY)) + #elif (defined(CONFIG_2G_CG_TRX_DIVERSITY)) dm->ant_div_type = CG_TRX_HW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = CG_TRX_HW_ANTDIV\n"); -#elif (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY)) + #elif (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY)) dm->ant_div_type = CG_TRX_SMART_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = CG_SMART_ANTDIV\n"); -#elif (defined(CONFIG_2G_S0S1_SW_ANT_DIVERSITY)) + #elif (defined(CONFIG_2G_S0S1_SW_ANT_DIVERSITY)) dm->ant_div_type = S0S1_SW_ANTDIV; PHYDM_DBG(dm, DBG_ANT_DIV, "[ 2.4G] : AntDiv type = S0S1_SW_ANTDIV\n"); -#endif + #endif } else if (*dm->band_type == ODM_BAND_5G) { PHYDM_DBG(dm, DBG_ANT_DIV, "Not Support 5G ant_div_type\n"); dm->support_ability &= ~(ODM_BB_ANT_DIV); } #endif + + if (!(dm->support_ic_type & ODM_ANTDIV_SUPPORT_IC)) { + fat_tab->ant_div_2g_5g = 0; + dm->support_ability &= ~(ODM_BB_ANT_DIV); + } #endif PHYDM_DBG(dm, DBG_ANT_DIV, @@ -5983,10 +6379,20 @@ void phydm_antdiv_debug(void *dm_void, char input[][16], u32 *_used, "AntDiv: Auto\n"); } else if (dm_value[1] == 1) { dm->ant_type = ODM_FIX_MAIN_ANT; + + #if (RTL8710C_SUPPORT == 1) + dm->antdiv_select = 1; + #endif + PDM_SNPF(out_len, used, output + used, out_len - used, "AntDiv: Fix Main\n"); } else if (dm_value[1] == 2) { dm->ant_type = ODM_FIX_AUX_ANT; + + #if (RTL8710C_SUPPORT == 1) + dm->antdiv_select = 2; + #endif + PDM_SNPF(out_len, used, output + used, out_len - used, "AntDiv: Fix Aux\n"); } @@ -6105,6 +6511,9 @@ void odm_ant_div_reset(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + if (!(dm->support_ability & ODM_BB_ANT_DIV)) + return; + #ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY if (dm->ant_div_type == S0S1_SW_ANTDIV) odm_s0s1_sw_ant_div_reset(dm); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_antdiv.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_antdiv.h index 99bbf89dab47..0555cc8732ba 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_antdiv.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_antdiv.h @@ -85,9 +85,10 @@ #define ODM_N_ANTDIV_SUPPORT (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8723B |\ ODM_RTL8188F | ODM_RTL8723D | ODM_RTL8195A |\ - ODM_RTL8197F | ODM_RTL8721D) + ODM_RTL8197F | ODM_RTL8721D | ODM_RTL8710C) #define ODM_AC_ANTDIV_SUPPORT (ODM_RTL8821 | ODM_RTL8881A | ODM_RTL8812 |\ - ODM_RTL8821C | ODM_RTL8822B | ODM_RTL8814B) + ODM_RTL8821C | ODM_RTL8822B | ODM_RTL8814B |\ + ODM_RTL8195B) #define ODM_JGR3_ANTDIV_SUPPORT ODM_RTL8197G #define ODM_ANTDIV_SUPPORT (ODM_N_ANTDIV_SUPPORT | ODM_AC_ANTDIV_SUPPORT |\ ODM_JGR3_ANTDIV_SUPPORT) @@ -98,7 +99,9 @@ ODM_RTL8881A | ODM_RTL8188F | ODM_RTL8723D |\ ODM_RTL8197F | ODM_RTL8197G) #define ODM_ANTDIV_5G_SUPPORT_IC (ODM_RTL8821 | ODM_RTL8881A | ODM_RTL8812 |\ - ODM_RTL8821C | ODM_RTL8822B) + ODM_RTL8821C | ODM_RTL8822B | ODM_RTL8195B) + +#define ODM_ANTDIV_SUPPORT_IC (ODM_ANTDIV_2G_SUPPORT_IC | ODM_ANTDIV_5G_SUPPORT_IC) #define ODM_EVM_ANTDIV_IC (ODM_RTL8192E | ODM_RTL8197F | ODM_RTL8822B |\ ODM_RTL8197G) @@ -172,7 +175,7 @@ /*@Hong Lin Smart antenna*/ #define HL_SMTANT_2WIRE_DATA_LEN 24 -#if (RTL8723D_SUPPORT == 1) +#if (RTL8723D_SUPPORT == 1 || RTL8710C_SUPPORT == 1) #ifndef CONFIG_ANTDIV_PERIOD #define CONFIG_ANTDIV_PERIOD 1 #endif @@ -328,7 +331,7 @@ struct phydm_fat_struct { u8 pre_antdiv_rssi; u8 pre_antdiv_tp; #endif -#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE | ODM_IOT)) u32 cck_ctrl_frame_cnt_main; u32 cck_ctrl_frame_cnt_aux; u32 ofdm_ctrl_frame_cnt_main; @@ -338,6 +341,7 @@ struct phydm_fat_struct { u32 main_ctrl_cnt; u32 aux_ctrl_cnt; #endif + u8 b_fix_tx_ant; boolean fix_ant_bfee; boolean enable_ctrl_frame_antdiv; @@ -351,6 +355,9 @@ struct phydm_fat_struct { /*@A temp value, will hook to driver team's outer parameter later*/ u8 *p_default_s0_s1; u8 default_s0_s1; + u8 ant_idx_vec[3]; /* for SP3T only, added by Jiao Qi on June.6,2020*/ + + }; /* @1 ============================================================ @@ -408,6 +415,8 @@ void phydm_antdiv_reset_statistic(void *dm_void, u32 macid); void odm_update_rx_idle_ant(void *dm_void, u8 ant); +void odm_update_rx_idle_ant_sp3t(void *dm_void, u8 ant); + void phydm_update_rx_idle_ant_pathb(void *dm_void, u8 ant); void phydm_set_antdiv_val(void *dm_void, u32 *val_buf, u8 val_len); @@ -443,6 +452,10 @@ void odm_sw_antdiv_workitem_callback(void *context); void odm_sw_antdiv_callback(void *function_context); +#elif (DM_ODM_SUPPORT_TYPE == ODM_IOT) + +void odm_sw_antdiv_callback(void *dm_void); + #endif void odm_s0s1_sw_ant_div_by_ctrl_frame(void *dm_void, u8 step); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_api.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_api.c index 30c151ee94e8..3d432a7bcd76 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_api.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_api.c @@ -56,6 +56,12 @@ void phydm_reset_bb_hw_cnt(void *dm_void) /*@ Reset all counter when 1 */ if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + #if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) { + odm_set_bb_reg(dm, R_0x2a44, BIT(21), 0); + odm_set_bb_reg(dm, R_0x2a44, BIT(21), 1); + } + #endif odm_set_bb_reg(dm, R_0x1eb4, BIT(25), 1); odm_set_bb_reg(dm, R_0x1eb4, BIT(25), 0); } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { @@ -102,6 +108,11 @@ void phydm_ant_weight_dbg(void *dm_void, char input[][16], u32 *_used, u32 used = *_used; u32 out_len = *_out_len; + if (!(dm->support_ic_type & + (ODM_RTL8192F | ODM_RTL8822B | ODM_RTL8812 | ODM_RTL8197F))) { + return; + } + if ((strcmp(input[1], help) == 0)) { PDM_SNPF(out_len, used, output + used, out_len - used, "echo dis_dym_ant_weighting {0/1}\n"); @@ -349,7 +360,7 @@ void phydm_config_trx_path_v2(void *dm_void, char input[][16], u32 *_used, { #if (RTL8822B_SUPPORT || RTL8197F_SUPPORT || RTL8192F_SUPPORT ||\ RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8197G_SUPPORT ||\ - RTL8812F_SUPPORT) + RTL8812F_SUPPORT || RTL8198F_SUPPORT) struct dm_struct *dm = (struct dm_struct *)dm_void; u32 used = *_used; u32 out_len = *_out_len; @@ -361,14 +372,12 @@ void phydm_config_trx_path_v2(void *dm_void, char input[][16], u32 *_used, if (!(dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8822C | - ODM_RTL8814B | ODM_RTL8812F | ODM_RTL8197G))) + ODM_RTL8814B | ODM_RTL8812F | ODM_RTL8197G | ODM_RTL8198F))) return; for (i = 0; i < 5; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &val[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &val[i]); + input_idx++; } if (input_idx == 0) @@ -494,11 +503,11 @@ void phydm_config_trx_path(void *dm_void, char input[][16], u32 *_used, #endif } else if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8822C | ODM_RTL8812F | - ODM_RTL8197G | ODM_RTL8814B)) { + ODM_RTL8197G | ODM_RTL8814B | ODM_RTL8198F)) { #if (RTL8822B_SUPPORT || RTL8197F_SUPPORT ||\ RTL8192F_SUPPORT || RTL8822C_SUPPORT ||\ RTL8814B_SUPPORT || RTL8812F_SUPPORT ||\ - RTL8197G_SUPPORT) + RTL8197G_SUPPORT || RTL8198F_SUPPORT) phydm_config_trx_path_v2(dm, input, _used, output, _out_len); #endif } @@ -599,20 +608,22 @@ u8 phydm_stop_ic_trx(void *dm_void, u8 set_type) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_api_stuc *api = &dm->api_table; - u32 i = 0; - u8 trx_idle_success = false; + u8 i = 0; + boolean trx_idle_success = false; u32 dbg_port_value = 0; if (set_type == PHYDM_SET) { - /*@[Stop TRX]---------------------------------------------------------*/ - /*set debug port to 0x0*/ - if (!phydm_set_bb_dbg_port(dm, DBGPORT_PRI_3, 0x0)) - return PHYDM_SET_FAIL; - - for (i = 0; i < 100; i++) { - dbg_port_value = phydm_get_bb_dbg_port_val(dm); - - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + /*[Stop TRX]---------------------------------------------------------*/ + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + #if (RTL8723F_SUPPORT) + /*Judy 2020-0515*/ + /*set debug port to 0x0*/ + if (!phydm_set_bb_dbg_port(dm, DBGPORT_PRI_3, 0x0)) + return PHYDM_SET_FAIL; + #endif + for (i = 0; i < 100; i++) { + dbg_port_value = odm_get_bb_reg(dm, R_0x2db4, + MASKDWORD); /* BB idle */ if ((dbg_port_value & 0x1FFEFF3F) == 0 && (dbg_port_value & 0xC0010000) == @@ -624,10 +635,17 @@ u8 phydm_stop_ic_trx(void *dm_void, u8 set_type) trx_idle_success = true; break; } - } else { + } + } else { + /*set debug port to 0x0*/ + if (!phydm_set_bb_dbg_port(dm, DBGPORT_PRI_3, 0x0)) + return PHYDM_SET_FAIL; + for (i = 0; i < 100; i++) { + dbg_port_value = phydm_get_bb_dbg_port_val(dm); /* PHYTXON && CCA_all */ if (dm->support_ic_type & (ODM_RTL8721D | - ODM_RTL8710C)) { + ODM_RTL8710B | ODM_RTL8710C | + ODM_RTL8188F | ODM_RTL8723D)) { if ((dbg_port_value & (BIT(20) | BIT(15))) == 0) { PHYDM_DBG(dm, ODM_COMP_API, @@ -648,10 +666,10 @@ u8 phydm_stop_ic_trx(void *dm_void, u8 set_type) break; } } + ODM_delay_ms(1); } - ODM_delay_ms(1); + phydm_release_bb_dbg_port(dm); } - phydm_release_bb_dbg_port(dm); if (trx_idle_success) { api->tx_queue_bitmap = odm_read_1byte(dm, R_0x522); @@ -660,15 +678,15 @@ u8 phydm_stop_ic_trx(void *dm_void, u8 set_type) odm_set_mac_reg(dm, R_0x520, 0xff0000, 0xff); if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - /*@disable OFDM RX CCA*/ - odm_set_bb_reg(dm, R_0x1c68, BIT(24), 1); + /*disable OFDM RX CCA*/ + odm_set_bb_reg(dm, R_0x1d58, 0xff8, 0x1ff); } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - /*@disable OFDM RX CCA*/ + /*disable OFDM RX CCA*/ odm_set_bb_reg(dm, R_0x838, BIT(1), 1); } else { api->rxiqc_reg1 = odm_read_4byte(dm, R_0xc14); api->rxiqc_reg2 = odm_read_4byte(dm, R_0xc1c); - /* @[ Set IQK Matrix = 0 ] + /* [ Set IQK Matrix = 0 ] * equivalent to [ Turn off CCA] */ odm_set_bb_reg(dm, R_0xc14, MASKDWORD, 0x0); @@ -687,7 +705,7 @@ u8 phydm_stop_ic_trx(void *dm_void, u8 set_type) if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { /*@enable OFDM RX CCA*/ - odm_set_bb_reg(dm, R_0x1c68, BIT(24), 0); + odm_set_bb_reg(dm, R_0x1d58, 0xff8, 0x0); } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { /*@enable OFDM RX CCA*/ odm_set_bb_reg(dm, R_0x838, BIT(1), 0); @@ -708,12 +726,20 @@ void phydm_dis_cck_trx(void *dm_void, u8 set_type) if (set_type == PHYDM_SET) { if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - api->ccktx_path = (u8)odm_get_bb_reg(dm, R_0x1a04, - 0xf0000000); - /* @CCK RxIQ weighting = [0,0] */ - odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x3); - /* @disable CCK Tx */ - odm_set_bb_reg(dm, R_0x1a04, 0xf0000000, 0x0); + if(dm->support_ic_type & ODM_RTL8723F) { + api->ccktx_path = 1; + /* @disable CCK CCA */ + odm_set_bb_reg(dm, R_0x2a24, BIT(13), 0x1); + /* @disable CCK Tx */ + odm_set_bb_reg(dm, R_0x2a00, BIT(1), 0x1); + } else { + api->ccktx_path = (u8)odm_get_bb_reg(dm, R_0x1a04, + 0xf0000000); + /* @CCK RxIQ weighting = [0,0] */ + odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x3); + /* @disable CCK Tx */ + odm_set_bb_reg(dm, R_0x1a04, 0xf0000000, 0x0); + } } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { api->ccktx_path = (u8)odm_get_bb_reg(dm, R_0xa04, 0xf0000000); @@ -731,11 +757,18 @@ void phydm_dis_cck_trx(void *dm_void, u8 set_type) } } else if (set_type == PHYDM_REVERT) { if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - /* @CCK RxIQ weighting = [1,1] */ - odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x0); - /* @enable CCK Tx */ - odm_set_bb_reg(dm, R_0x1a04, 0xf0000000, - api->ccktx_path); + if(dm->support_ic_type & ODM_RTL8723F) { + /* @enable CCK CCA */ + odm_set_bb_reg(dm, R_0x2a24, BIT(13), 0x0); + /* @enable CCK Tx */ + odm_set_bb_reg(dm, R_0x2a00, BIT(1), 0x0); + } else { + /* @CCK RxIQ weighting = [1,1] */ + odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x0); + /* @enable CCK Tx */ + odm_set_bb_reg(dm, R_0x1a04, 0xf0000000, + api->ccktx_path); + } } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { /* @enable CCK block */ odm_set_bb_reg(dm, R_0x808, BIT(28), 1); @@ -752,13 +785,13 @@ void phydm_dis_cck_trx(void *dm_void, u8 set_type) } } -void phydm_bw_fixed_enable(void *dm_void, boolean enable) +void phydm_bw_fixed_enable(void *dm_void, u8 enable) { #ifdef CONFIG_BW_INDICATION struct dm_struct *dm = (struct dm_struct *)dm_void; boolean val = (enable == FUNC_ENABLE) ? 1 : 0; - if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8822B)) + if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8822B | ODM_RTL8195B)) odm_set_bb_reg(dm, R_0x840, BIT(4), val); else if (dm->support_ic_type & ODM_RTL8822C) odm_set_bb_reg(dm, R_0x878, BIT(28), val); @@ -776,7 +809,8 @@ void phydm_bw_fixed_setting(void *dm_void) if (!(dm->support_ic_type & ODM_DYM_BW_INDICATION_SUPPORT)) return; - if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8822B)) { + if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8822B | + ODM_RTL8195B)) { reg = R_0x840; reg_mask = 0xf; reg_value = api->pri_ch_idx; @@ -1036,7 +1070,8 @@ void phydm_nbi_enable(void *dm_void, u32 enable) odm_set_bb_reg(dm, R_0xc40, BIT(9), val); } } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C)) { + if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C | + ODM_RTL8195B)) { odm_set_bb_reg(dm, R_0x87c, BIT(13), val); odm_set_bb_reg(dm, R_0xc20, BIT(28), val); if (dm->rf_type > RF_1T1R) @@ -1203,7 +1238,164 @@ u8 phydm_csi_mask_setting(void *dm_void, u32 enable, u32 ch, u32 bw, return set_result; } +boolean phydm_spur_case_mapping(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u8 channel = *dm->channel, bw = *dm->band_width; + boolean mapping_result = false; +#if (RTL8814B_SUPPORT == 1) + if (channel == 153 && bw == CHANNEL_WIDTH_20) { + odm_set_bb_reg(dm, R_0x804, BIT(31), 0); + odm_set_bb_reg(dm, R_0xc00, BIT(25) | BIT(24), 0); + mapping_result = true; + } else if (channel == 151 && bw == CHANNEL_WIDTH_40) { + odm_set_bb_reg(dm, R_0x804, BIT(31), 0); + odm_set_bb_reg(dm, R_0xc00, BIT(25) | BIT(24), 0); + mapping_result = true; + } else if (channel == 155 && bw == CHANNEL_WIDTH_80) { + odm_set_bb_reg(dm, R_0x804, BIT(31), 0); + odm_set_bb_reg(dm, R_0xc00, BIT(25) | BIT(24), 0); + mapping_result = true; + } else { + odm_set_bb_reg(dm, R_0x804, BIT(31), 1); + odm_set_bb_reg(dm, R_0xc00, BIT(25) | BIT(24), 1); + } +#endif + return mapping_result; +} + +enum odm_rf_band phydm_ch_to_rf_band(void *dm_void, u8 central_ch) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + enum odm_rf_band rf_band = ODM_RF_BAND_5G_LOW; + + if (central_ch <= 14) + rf_band = ODM_RF_BAND_2G; + else if (central_ch >= 36 && central_ch <= 64) + rf_band = ODM_RF_BAND_5G_LOW; + else if ((central_ch >= 100) && (central_ch <= 144)) + rf_band = ODM_RF_BAND_5G_MID; + else if (central_ch >= 149) + rf_band = ODM_RF_BAND_5G_HIGH; + else + PHYDM_DBG(dm, ODM_COMP_API, "mapping channel to band fail\n"); + + return rf_band; +} + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT +u32 phydm_rf_psd_jgr3(void *dm_void, u8 path, u32 tone_idx) +{ +#if (RTL8198F_SUPPORT || RTL8814B_SUPPORT) + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 reg_1b04 = 0, reg_1b08 = 0, reg_1b0c_11_10 = 0; + u32 reg_1b14 = 0, reg_1b18 = 0, reg_1b1c = 0; + u32 reg_1b28 = 0; + u32 reg_1bcc_5_0 = 0; + u32 reg_1b2c_27_16 = 0, reg_1b34 = 0, reg_1bd4 = 0; + u32 reg_180c = 0, reg_410c = 0, reg_520c = 0, reg_530c = 0; + u32 igi = 0; + u32 i = 0; + u32 psd_val = 0, psd_val_msb = 0, psd_val_lsb = 0, psd_max = 0; + u32 psd_status_temp = 0; + u16 poll_cnt = 0; + + /*read and record the ori. value*/ + reg_1b04 = odm_get_bb_reg(dm, R_0x1b04, MASKDWORD); + reg_1b08 = odm_get_bb_reg(dm, R_0x1b08, MASKDWORD); + reg_1b0c_11_10 = odm_get_bb_reg(dm, R_0x1b0c, 0xc00); + reg_1b14 = odm_get_bb_reg(dm, R_0x1b14, MASKDWORD); + reg_1b18 = odm_get_bb_reg(dm, R_0x1b18, MASKDWORD); + reg_1b1c = odm_get_bb_reg(dm, R_0x1b1c, MASKDWORD); + reg_1b28 = odm_get_bb_reg(dm, R_0x1b28, MASKDWORD); + reg_1bcc_5_0 = odm_get_bb_reg(dm, R_0x1bcc, 0x3f); + reg_1b2c_27_16 = odm_get_bb_reg(dm, R_0x1b2c, 0xfff0000); + reg_1b34 = odm_get_bb_reg(dm, R_0x1b34, MASKDWORD); + reg_1bd4 = odm_get_bb_reg(dm, R_0x1bd4, MASKDWORD); + igi = odm_get_bb_reg(dm, R_0x1d70, MASKDWORD); + reg_180c = odm_get_bb_reg(dm, R_0x180c, 0x3); + reg_410c = odm_get_bb_reg(dm, R_0x410c, 0x3); + reg_520c = odm_get_bb_reg(dm, R_0x520c, 0x3); + reg_530c = odm_get_bb_reg(dm, R_0x530c, 0x3); + + /*rf psd reg setting*/ + odm_set_bb_reg(dm, R_0x1b00, 0x6, path); /*path is RF_path*/ + odm_set_bb_reg(dm, R_0x1b04, MASKDWORD, 0x0); + odm_set_bb_reg(dm, R_0x1b08, MASKDWORD, 0x80); + odm_set_bb_reg(dm, R_0x1b0c, 0xc00, 0x3); + odm_set_bb_reg(dm, R_0x1b14, MASKDWORD, 0x0); + odm_set_bb_reg(dm, R_0x1b18, MASKDWORD, 0x1); +/*#if (DM_ODM_SUPPORT_TYPE == ODM_AP)*/ + odm_set_bb_reg(dm, R_0x1b1c, MASKDWORD, 0x82103D21); +/*#else*/ + /*odm_set_bb_reg(dm, R_0x1b1c, MASKDWORD, 0x821A3D21);*/ +/*#endif*/ + odm_set_bb_reg(dm, R_0x1b28, MASKDWORD, 0x0); + odm_set_bb_reg(dm, R_0x1bcc, 0x3f, 0x3f); + odm_set_bb_reg(dm, R_0x8a0, 0xf, 0x0); /* AGC off */ + odm_set_bb_reg(dm, R_0x1d70, MASKDWORD, 0x20202020); + + for (i = tone_idx - 1; i <= tone_idx + 1; i++) { + /*set psd tone_idx for detection*/ + odm_set_bb_reg(dm, R_0x1b2c, 0xfff0000, i); + /*one shot for RXIQK psd*/ + odm_set_bb_reg(dm, R_0x1b34, MASKDWORD, 0x1); + odm_set_bb_reg(dm, R_0x1b34, MASKDWORD, 0x0); + + if (dm->support_ic_type & ODM_RTL8814B) + for (poll_cnt = 0; poll_cnt < 20; poll_cnt++) { + odm_set_bb_reg(dm, R_0x1bd4, 0x3f0000, 0x2b); + psd_status_temp = odm_get_bb_reg(dm, R_0x1bfc, + BIT(1)); + if (!psd_status_temp) + ODM_delay_us(10); + else + break; + } + else + ODM_delay_us(250); + + /*read RxIQK power*/ + odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, 0x00250001); + if (dm->support_ic_type & ODM_RTL8814B) + psd_val_msb = odm_get_bb_reg(dm, R_0x1bfc, 0x7ff0000); + else if (dm->support_ic_type & ODM_RTL8198F) + psd_val_msb = odm_get_bb_reg(dm, R_0x1bfc, 0x1f0000); + + odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, 0x002e0001); + psd_val_lsb = odm_get_bb_reg(dm, R_0x1bfc, MASKDWORD); + if (dm->support_ic_type & ODM_RTL8814B) + psd_val = (psd_val_msb << 21) + (psd_val_lsb >> 11); + else if (dm->support_ic_type & ODM_RTL8198F) + psd_val = (psd_val_msb << 27) + (psd_val_lsb >> 5); + + if (psd_val > psd_max) + psd_max = psd_val; + } + + /*refill the ori. value*/ + odm_set_bb_reg(dm, R_0x1b00, 0x6, path); + odm_set_bb_reg(dm, R_0x1b04, MASKDWORD, reg_1b04); + odm_set_bb_reg(dm, R_0x1b08, MASKDWORD, reg_1b08); + odm_set_bb_reg(dm, R_0x1b0c, 0xc00, reg_1b0c_11_10); + odm_set_bb_reg(dm, R_0x1b14, MASKDWORD, reg_1b14); + odm_set_bb_reg(dm, R_0x1b18, MASKDWORD, reg_1b18); + odm_set_bb_reg(dm, R_0x1b1c, MASKDWORD, reg_1b1c); + odm_set_bb_reg(dm, R_0x1b28, MASKDWORD, reg_1b28); + odm_set_bb_reg(dm, R_0x1bcc, 0x3f, reg_1bcc_5_0); + odm_set_bb_reg(dm, R_0x1b2c, 0xfff0000, reg_1b2c_27_16); + odm_set_bb_reg(dm, R_0x1b34, MASKDWORD, reg_1b34); + odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, reg_1bd4); + odm_set_bb_reg(dm, R_0x8a0, 0xf, 0xf); /* AGC on */ + odm_set_bb_reg(dm, R_0x1d70, MASKDWORD, igi); + PHYDM_DBG(dm, ODM_COMP_API, "psd_max %d\n", psd_max); + + return psd_max; +#else + return 0; +#endif +} + u8 phydm_find_intf_distance_jgr3(void *dm_void, u32 bw, u32 fc, u32 f_interference, u32 *tone_idx_tmp_in) { @@ -1225,7 +1417,8 @@ u8 phydm_find_intf_distance_jgr3(void *dm_void, u32 bw, u32 fc, if (f_interference >= bw_low && f_interference <= bw_up) { int_distance = DIFF_2(fc, f_interference); /*@10*(int_distance /0.3125)*/ - if ((dm->support_ic_type & (ODM_RTL8814B)) && channel < 15) + if (channel < 15 && + (dm->support_ic_type & (ODM_RTL8814B | ODM_RTL8198F))) tone_idx_tmp = int_distance / 312; else tone_idx_tmp = ((int_distance + 156) / 312); @@ -1238,6 +1431,7 @@ u8 phydm_find_intf_distance_jgr3(void *dm_void, u32 bw, u32 fc, return set_result; } + u8 phydm_csi_mask_setting_jgr3(void *dm_void, u32 enable, u32 ch, u32 bw, u32 f_intf, u32 sec_ch, u8 wgt) { @@ -1293,7 +1487,7 @@ void phydm_set_csi_mask_jgr3(void *dm_void, u32 tone_idx_tmp, u8 tone_direction, { struct dm_struct *dm = (struct dm_struct *)dm_void; u32 multi_tone_idx_tmp = 0; - u32 reg_tmp_value = 0; + u32 reg_tmp = 0; u32 tone_num = 64; u32 table_addr = 0; u32 addr = 0; @@ -1318,14 +1512,15 @@ void phydm_set_csi_mask_jgr3(void *dm_void, u32 tone_idx_tmp, u8 tone_direction, } table_addr = tone_idx_tmp >> 1; - reg_tmp_value = odm_read_4byte(dm, R_0x1d94); + reg_tmp = odm_read_4byte(dm, R_0x1d94); PHYDM_DBG(dm, ODM_COMP_API, "Pre Mask tone idx[%d]: Reg0x1d94 = ((0x%x))\n", - tone_idx_tmp, reg_tmp_value); + tone_idx_tmp, reg_tmp); odm_set_bb_reg(dm, R_0x1ee8, 0x3, 0x3); odm_set_bb_reg(dm, R_0x1d94, BIT(31) | BIT(30), 0x1); - if ((dm->support_ic_type & (ODM_RTL8814B)) && channel < 15) { + if (channel < 15 && + (dm->support_ic_type & (ODM_RTL8814B | ODM_RTL8198F))) { if (tone_idx_tmp % 2 == 1) { if (tone_direction == FREQ_POSITIVE) { /*===Tone 1===*/ @@ -1333,10 +1528,10 @@ void phydm_set_csi_mask_jgr3(void *dm_void, u32 tone_idx_tmp, u8 tone_direction, (table_addr & 0xff)); value = (BIT(3) | (wgt & 0x7)) << 4; odm_set_bb_reg(dm, R_0x1d94, 0xff, value); - reg_tmp_value = odm_read_4byte(dm, R_0x1d94); + reg_tmp = odm_read_4byte(dm, R_0x1d94); PHYDM_DBG(dm, ODM_COMP_API, "New Mask tone 1 idx[%d]: Reg0x1d94 = ((0x%x))\n", - tone_idx_tmp, reg_tmp_value); + tone_idx_tmp, reg_tmp); /*===Tone 2===*/ value = 0; multi_tone_idx_tmp = tone_idx_tmp + 1; @@ -1345,10 +1540,10 @@ void phydm_set_csi_mask_jgr3(void *dm_void, u32 tone_idx_tmp, u8 tone_direction, (table_addr & 0xff)); value = (BIT(3) | (wgt & 0x7)); odm_set_bb_reg(dm, R_0x1d94, 0xff, value); - reg_tmp_value = odm_read_4byte(dm, R_0x1d94); + reg_tmp = odm_read_4byte(dm, R_0x1d94); PHYDM_DBG(dm, ODM_COMP_API, "New Mask tone 2 idx[%d]: Reg0x1d94 = ((0x%x))\n", - tone_idx_tmp, reg_tmp_value); + tone_idx_tmp, reg_tmp); } else { /*===Tone 1 & 2===*/ odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, @@ -1356,10 +1551,10 @@ void phydm_set_csi_mask_jgr3(void *dm_void, u32 tone_idx_tmp, u8 tone_direction, value = ((BIT(3) | (wgt & 0x7)) << 4) | (BIT(3) | (wgt & 0x7)); odm_set_bb_reg(dm, R_0x1d94, 0xff, value); - reg_tmp_value = odm_read_4byte(dm, R_0x1d94); + reg_tmp = odm_read_4byte(dm, R_0x1d94); PHYDM_DBG(dm, ODM_COMP_API, "New Mask tone 1 & 2 idx[%d]: Reg0x1d94 = ((0x%x))\n", - tone_idx_tmp, reg_tmp_value); + tone_idx_tmp, reg_tmp); } } else { if (tone_direction == FREQ_POSITIVE) { @@ -1369,20 +1564,20 @@ void phydm_set_csi_mask_jgr3(void *dm_void, u32 tone_idx_tmp, u8 tone_direction, value = ((BIT(3) | (wgt & 0x7)) << 4) | (BIT(3) | (wgt & 0x7)); odm_set_bb_reg(dm, R_0x1d94, 0xff, value); - reg_tmp_value = odm_read_4byte(dm, R_0x1d94); + reg_tmp = odm_read_4byte(dm, R_0x1d94); PHYDM_DBG(dm, ODM_COMP_API, "New Mask tone 1 & 2 idx[%d]: Reg0x1d94 = ((0x%x))\n", - tone_idx_tmp, reg_tmp_value); + tone_idx_tmp, reg_tmp); } else { /*===Tone 1===*/ odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, (table_addr & 0xff)); value = (BIT(3) | (wgt & 0x7)); odm_set_bb_reg(dm, R_0x1d94, 0xff, value); - reg_tmp_value = odm_read_4byte(dm, R_0x1d94); + reg_tmp = odm_read_4byte(dm, R_0x1d94); PHYDM_DBG(dm, ODM_COMP_API, "New Mask tone 1 idx[%d]: Reg0x1d94 = ((0x%x))\n", - tone_idx_tmp, reg_tmp_value); + tone_idx_tmp, reg_tmp); /*===Tone 2===*/ value = 0; @@ -1392,24 +1587,84 @@ void phydm_set_csi_mask_jgr3(void *dm_void, u32 tone_idx_tmp, u8 tone_direction, (table_addr & 0xff)); value = (BIT(3) | (wgt & 0x7)) << 4; odm_set_bb_reg(dm, R_0x1d94, 0xff, value); - reg_tmp_value = odm_read_4byte(dm, R_0x1d94); + reg_tmp = odm_read_4byte(dm, R_0x1d94); PHYDM_DBG(dm, ODM_COMP_API, "New Mask tone 2 idx[%d]: Reg0x1d94 = ((0x%x))\n", - tone_idx_tmp, reg_tmp_value); + tone_idx_tmp, reg_tmp); } } } else { - odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, (table_addr & 0xff)); - if (tone_idx_tmp % 2) - value = (BIT(3) | (wgt & 0x7)) << 4; - else - value = BIT(3) | (wgt & 0x7); + if ((dm->support_ic_type & (ODM_RTL8814B)) && + phydm_spur_case_mapping(dm)) { + if (!(tone_idx_tmp % 2)) { + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, + (table_addr & 0xff)); + value = ((BIT(3) | (((wgt + 4) <= 7 ? (wgt + + 4) : 7) & 0x7)) << 4) | (BIT(3) | + (wgt & 0x7)); + odm_set_bb_reg(dm, R_0x1d94, 0xff, value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask tone idx[%d]: Reg0x1d94 = ((0x%x))\n", + tone_idx_tmp, reg_tmp); + if (tone_idx_tmp == 0) + table_addr = tone_num - 1; + else + table_addr = table_addr - 1; + if (tone_idx_tmp != tone_num) { + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, + (table_addr & 0xff)); + value = (BIT(3) | (((wgt + 4) <= 7 ? + (wgt + 4) : 7) & 0x7)) << 4; + odm_set_bb_reg(dm, R_0x1d94, 0xff, + value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask Reg0x1d94 = ((0x%x))\n", + reg_tmp); + } + } else { + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, + (table_addr & 0xff)); + value = ((BIT(3) | (wgt & 0x7)) << 4) | + (BIT(3) | (((wgt + 4) <= 7 ? (wgt + + 4) : 7) & 0x7)); + odm_set_bb_reg(dm, R_0x1d94, 0xff, value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask tone idx[%d]: Reg0x1d94 = ((0x%x))\n", + tone_idx_tmp, reg_tmp); + if (tone_idx_tmp == (tone_num << 1) - 1) + table_addr = 0; + else + table_addr = table_addr + 1; + if (tone_idx_tmp != tone_num - 1) { + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, + (table_addr & 0xff)); + value = (BIT(3) | (((wgt + 4) <= 7 ? + (wgt + 4) : 7) & 0x7)); + odm_set_bb_reg(dm, R_0x1d94, 0xff, + value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask Reg0x1d94 = ((0x%x))\n", + reg_tmp); + } + } + } else { + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, (table_addr & + 0xff)); + if (tone_idx_tmp % 2) + value = (BIT(3) | (wgt & 0x7)) << 4; + else + value = BIT(3) | (wgt & 0x7); - odm_set_bb_reg(dm, R_0x1d94, 0xff, value); - reg_tmp_value = odm_read_4byte(dm, R_0x1d94); - PHYDM_DBG(dm, ODM_COMP_API, - "New Mask tone idx[%d]: Reg0x1d94 = ((0x%x))\n", - tone_idx_tmp, reg_tmp_value); + odm_set_bb_reg(dm, R_0x1d94, 0xff, value); + reg_tmp = odm_read_4byte(dm, R_0x1d94); + PHYDM_DBG(dm, ODM_COMP_API, + "New Mask tone idx[%d]: Reg0x1d94 = ((0x%x))\n", + tone_idx_tmp, reg_tmp); + } } odm_set_bb_reg(dm, R_0x1ee8, 0x3, 0x0); } @@ -1474,15 +1729,18 @@ u8 phydm_nbi_setting_jgr3(void *dm_void, u32 enable, u32 ch, u32 bw, u32 f_intf, set_result = PHYDM_SET_SUCCESS; } else { set_result = PHYDM_SET_NO_NEED; + } } } - } if (set_result == PHYDM_SET_SUCCESS) phydm_nbi_enable_jgr3(dm, enable, path); else phydm_nbi_enable_jgr3(dm, FUNC_DISABLE, path); + if (dm->support_ic_type & ODM_RTL8814B) + odm_set_bb_reg(dm, R_0x1d3c, BIT(19), 0); + return set_result; } @@ -1514,7 +1772,11 @@ void phydm_set_nbi_reg_jgr3(void *dm_void, u32 tone_idx_tmp, u8 tone_direction, #if RTL8814B_SUPPORT if (dm->support_ic_type & ODM_RTL8814B) { odm_set_bb_reg(dm, R_0xc24, 0xff, 0xff); - odm_set_bb_reg(dm, R_0xc24, 0xff00, tone_idx_tmp); + if ((*dm->channel == 5) && + (*dm->band_width == CHANNEL_WIDTH_40)) + odm_set_bb_reg(dm, R_0xc24, 0xff00, 0x1a); + else + odm_set_bb_reg(dm, R_0xc24, 0xff00, tone_idx_tmp); } #endif switch (path) { @@ -1855,10 +2117,8 @@ void phydm_nbi_debug(void *dm_void, char input[][16], u32 *_used, char *output, else idx_lmt = 5; for (i = 0; i < idx_lmt; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); + input_idx++; } if (input_idx == 0) @@ -1947,10 +2207,8 @@ void phydm_csi_debug(void *dm_void, char input[][16], u32 *_used, char *output, idx_lmt = 5; for (i = 0; i < idx_lmt; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); + input_idx++; } if (input_idx == 0) @@ -2240,6 +2498,43 @@ phydm_api_shift_txagc(void *dm_void, u32 pwr_offset, enum rf_path path, } #endif + #if (RTL8723F_SUPPORT) + if (dm->support_ic_type & (ODM_RTL8723F)) { + if (path > RF_PATH_A) { + PHYDM_DBG(dm, ODM_PHY_CONFIG, "Unsupported path (%d)\n", + path); + return false; + } + txagc_cck = (u8)odm_get_bb_reg(dm, r_txagc_cck[path], + 0x7F0000); + txagc_ofdm = (u8)odm_get_bb_reg(dm, r_txagc_ofdm[path], + 0x1FC00); + if (is_positive) { + if (((txagc_cck + pwr_offset) > 127) || + ((txagc_ofdm + pwr_offset) > 127)) + return false; + + txagc_cck += pwr_offset; + txagc_ofdm += pwr_offset; + } else { + if (pwr_offset > txagc_cck || pwr_offset > txagc_ofdm) + return false; + + txagc_cck -= pwr_offset; + txagc_ofdm -= pwr_offset; + } + #if (RTL8723F_SUPPORT) + ret = config_phydm_write_txagc_ref_8723f(dm, (u8)txagc_cck, + path, PDM_CCK); + ret &= config_phydm_write_txagc_ref_8723f(dm, (u8)txagc_ofdm, + path, PDM_OFDM); + #endif + PHYDM_DBG(dm, ODM_PHY_CONFIG, + "%s: path-%d txagc_cck_ref=%x txagc_ofdm_ref=0x%x\n", + __func__, path, txagc_cck, txagc_ofdm); + } + #endif + return ret; } @@ -2250,7 +2545,7 @@ phydm_api_set_txagc(void *dm_void, u32 pwr_idx, enum rf_path path, struct dm_struct *dm = (struct dm_struct *)dm_void; boolean ret = false; #if (RTL8198F_SUPPORT || RTL8822C_SUPPORT || RTL8812F_SUPPORT ||\ - RTL8814B_SUPPORT || RTL8197G_SUPPORT) + RTL8814B_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) u8 base = 0; u8 txagc_tmp = 0; s8 pw_by_rate_tmp = 0; @@ -2444,6 +2739,30 @@ phydm_api_set_txagc(void *dm_void, u32 pwr_idx, enum rf_path path, __func__, path, rate, base, pw_by_rate_new); } #endif +#if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) { + if (rate < 0x4) + txagc_tmp = config_phydm_read_txagc_8723f(dm, path, + rate, + PDM_CCK); + else + txagc_tmp = config_phydm_read_txagc_8723f(dm, path, + rate, + PDM_OFDM); + + pw_by_rate_tmp = config_phydm_read_txagc_diff_8723f(dm, rate); + base = txagc_tmp - pw_by_rate_tmp; + base = base & 0x7f; + if (DIFF_2((pwr_idx & 0x7f), base) > 63 || pwr_idx > 127) + return false; + + pw_by_rate_new = (s8)(pwr_idx - base); + ret = phydm_write_txagc_1byte_8723f(dm, pw_by_rate_new, rate); + PHYDM_DBG(dm, ODM_PHY_CONFIG, + "%s: path-%d rate_idx=%x base=0x%x new_diff=0x%x\n", + __func__, path, rate, base, pw_by_rate_new); + } +#endif #if (RTL8197F_SUPPORT) if (dm->support_ic_type & ODM_RTL8197F) @@ -2521,6 +2840,18 @@ u8 phydm_api_get_txagc(void *dm_void, enum rf_path path, u8 hw_rate) } #endif +#if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) { + if (hw_rate < 0x4) { + ret = config_phydm_read_txagc_8723f(dm, path, hw_rate, + PDM_CCK); + } else { + ret = config_phydm_read_txagc_8723f(dm, path, hw_rate, + PDM_OFDM); + } + } +#endif + #if (RTL8814B_SUPPORT) if (dm->support_ic_type & ODM_RTL8814B) { if (hw_rate < 0x4) { @@ -2645,6 +2976,12 @@ phydm_api_switch_bw_channel(void *dm_void, u8 ch, u8 pri_ch, break; #endif +#if (RTL8195B_SUPPORT) + case ODM_RTL8195B: + ret = config_phydm_switch_channel_bw_8195b(dm, ch, pri_ch, bw); + break; +#endif + #if (RTL8192F_SUPPORT) case ODM_RTL8192F: ret = config_phydm_switch_channel_bw_8192f(dm, ch, pri_ch, bw); @@ -2663,6 +3000,12 @@ phydm_api_switch_bw_channel(void *dm_void, u8 ch, u8 pri_ch, break; #endif +#if (RTL8723F_SUPPORT) + case ODM_RTL8723F: + ret = config_phydm_switch_channel_bw_8723f(dm, ch, pri_ch, bw); + break; +#endif + #if (RTL8814B_SUPPORT) case ODM_RTL8814B: ret = config_phydm_switch_channel_bw_8814b(dm, ch, pri_ch, bw); @@ -2775,7 +3118,9 @@ phydm_api_trx_mode(void *dm_void, enum bb_path tx_path, enum bb_path rx_path, } return ret; } -#else +#endif + +#ifdef PHYDM_COMMON_API_NOT_SUPPORT u8 config_phydm_read_txagc_n(void *dm_void, enum rf_path path, u8 hw_rate) { struct dm_struct *dm = (struct dm_struct *)dm_void; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_api.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_api.h index 4724738747cc..0e7ce1675673 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_api.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_api.h @@ -27,8 +27,8 @@ #ifndef __PHYDM_API_H__ #define __PHYDM_API_H__ -/* 2019.03.05 add reset txagc API for jgr3 ics*/ -#define PHYDM_API_VERSION "2.1" +/* 2019.10.22 Add get/shift rxagc API for 8822C*/ +#define PHYDM_API_VERSION "2.3" /* @1 ============================================================ * 1 Definition @@ -134,7 +134,7 @@ u8 phydm_stop_ic_trx(void *dm_void, u8 set_type); void phydm_dis_cck_trx(void *dm_void, u8 set_type); -void phydm_bw_fixed_enable(void *dm_void, boolean enable); +void phydm_bw_fixed_enable(void *dm_void, u8 enable); void phydm_bw_fixed_setting(void *dm_void); @@ -158,7 +158,13 @@ void phydm_stop_ck320(void *dm_void, u8 enable); boolean phydm_set_bb_txagc_offset(void *dm_void, s8 power_offset, u8 add_half_db); + +boolean phydm_spur_case_mapping(void *dm_void); + +enum odm_rf_band phydm_ch_to_rf_band(void *dm_void, u8 central_ch); #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT +u32 phydm_rf_psd_jgr3(void *dm_void, u8 path, u32 tone_idx); + u8 phydm_csi_mask_setting_jgr3(void *dm_void, u32 enable, u32 ch, u32 bw, u32 f_intf, u32 sec_ch, u8 wgt); @@ -205,6 +211,10 @@ phydm_api_trx_mode(void *dm_void, enum bb_path tx_path, enum bb_path rx_path, #endif +#ifdef PHYDM_COMMON_API_NOT_SUPPORT +u8 config_phydm_read_txagc_n(void *dm_void, enum rf_path path, u8 hw_rate); +#endif + #ifdef CONFIG_MCC_DM #ifdef DYN_ANT_WEIGHTING_SUPPORT void phydm_dynamic_ant_weighting_mcc_8822b(void *dm_void); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_beamforming.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_beamforming.c index cb83ef54c2cf..a6093417a04c 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_beamforming.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_beamforming.c @@ -49,6 +49,9 @@ void phydm_get_txbf_device_num( u8 act_as_bfer = 0; u8 act_as_bfee = 0; + if (!(dm->support_ability & ODM_BB_ANT_DIV)) + return; + if (is_sta_active(sta)) { bf = &(sta->bf_info); } else { @@ -72,7 +75,7 @@ void phydm_get_txbf_device_num( act_as_bfee = 1; } - if (act_as_bfer)) + if (act_as_bfer) { /* Our Device act as BFer */ dm_bdc_table->w_bfee_client[macid] = true; dm_bdc_table->num_txbfee_client++; @@ -80,7 +83,7 @@ void phydm_get_txbf_device_num( else dm_bdc_table->w_bfee_client[macid] = false; - if (act_as_bfee)) + if (act_as_bfee) { /* Our Device act as BFee */ dm_bdc_table->w_bfer_client[macid] = true; dm_bdc_table->num_txbfer_client++; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_beamforming.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_beamforming.h index 98b81f44abae..02d2dc2d5ac3 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_beamforming.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_beamforming.h @@ -46,7 +46,7 @@ #define MAX_BEAMFORMEE_SU 2 #define MAX_BEAMFORMER_SU 2 -#if (RTL8822B_SUPPORT == 1) +#if ((RTL8822B_SUPPORT == 1) || (RTL8812F_SUPPORT == 1)) #define MAX_BEAMFORMEE_MU 6 #define MAX_BEAMFORMER_MU 1 #else diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cck_pd.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cck_pd.c index 622306754c40..97f81968d70a 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cck_pd.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cck_pd.c @@ -222,6 +222,101 @@ void phydm_set_cckpd_lv_type2(void *dm_void, enum cckpd_lv lv) phydm_write_cck_pd_type2(dm, pd_th, cs_ratio); } +#if 0 +void phydm_set_cckpd_lv_type2_bcn(void *dm_void, enum cckpd_lv lv) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + u8 pd_th = 0, cs_ratio = 0, cs_2r_offset = 0; + u8 cck_n_rx = 1; + u8 cs_ratio_pre = 0; + u8 bcn_cnt = dm->phy_dbg_info.beacon_cnt_in_period; //BCN CNT + u8 ofst = 0; + u8 ofst_direc = 0; //0:+, 1:- + + PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__); + PHYDM_DBG(dm, DBG_CCKPD, "lv: (%d) -> (%d)\n", cckpd_t->cck_pd_lv, lv); + + /*@r_mrx & r_cca_mrc*/ + cck_n_rx = (odm_get_bb_reg(dm, R_0xa2c, BIT(18)) && + odm_get_bb_reg(dm, R_0xa2c, BIT(22))) ? 2 : 1; + cs_ratio_pre = (u8)((odm_get_bb_reg(dm, R_0xaa8, 0x1f0000))); + PHYDM_DBG(dm, DBG_CCKPD, "BCN: %d, pre CS ratio: 0x%x\n", bcn_cnt, + cs_ratio_pre); + + if (cckpd_t->cck_pd_lv == lv && cckpd_t->cck_n_rx == cck_n_rx && + (bcn_cnt >= 10 && bcn_cnt < 14)) { + PHYDM_DBG(dm, DBG_CCKPD, "BCN ok, stay lv=%d, cs ratio=0x%x\n", + lv, cs_ratio_pre); + return; + } + + cckpd_t->cck_n_rx = cck_n_rx; + cckpd_t->cck_pd_lv = lv; + cckpd_t->cck_fa_ma = CCK_FA_MA_RESET; + + if (lv == CCK_PD_LV_4) { + cs_ratio = cckpd_t->aaa_default + 8; + cs_2r_offset = 5; + pd_th = 0xd; + } else if (lv == CCK_PD_LV_3) { + cs_ratio = cckpd_t->aaa_default + 6; + cs_2r_offset = 4; + pd_th = 0xd; + } else if (lv == CCK_PD_LV_2) { + cs_ratio = cckpd_t->aaa_default + 4; + cs_2r_offset = 3; + pd_th = 0xd; + } else if (lv == CCK_PD_LV_1) { + cs_ratio = cckpd_t->aaa_default + 2; + cs_2r_offset = 1; + pd_th = 0x7; + } else if (lv == CCK_PD_LV_0) { + cs_ratio = cckpd_t->aaa_default; + cs_2r_offset = 0; + pd_th = 0x3; + } + + if (cckpd_t->cck_n_rx == 2) { + if (cs_ratio >= cs_2r_offset) + cs_ratio = cs_ratio - cs_2r_offset; + else + cs_ratio = 0; + } + + if (bcn_cnt >= 18) { + ofst_direc = 0; + ofst = 0x2; + } else if (bcn_cnt >= 14) { + ofst_direc = 0; + ofst = 0x1; + } else if (bcn_cnt >= 10) { + ofst_direc = 0; + ofst = 0x0; + } else if (bcn_cnt >= 5) { + ofst_direc = 1; + ofst = 0x3; + } else { + ofst_direc = 1; + ofst = 0x4; + } + PHYDM_DBG(dm, DBG_CCKPD, "bcn:(%d), ofst:(%s%d)\n", bcn_cnt, + ((ofst_direc) ? "-" : "+"), ofst); + + if (ofst_direc == 0) + cs_ratio = cs_ratio + ofst; + else + cs_ratio = cs_ratio - ofst; + + if (cs_ratio == cs_ratio_pre) { + PHYDM_DBG(dm, DBG_CCKPD, "Same cs ratio, lv=%d cs_ratio=0x%x\n", + lv, cs_ratio); + return; + } + phydm_write_cck_pd_type2(dm, pd_th, cs_ratio); +} +#endif + void phydm_cckpd_type2(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -672,6 +767,9 @@ void phydm_read_cckpd_para_type4(void *dm_void) u32 reg2 = 0; u32 reg3 = 0; + if (!(dm->debug_components & DBG_CCKPD)) + return; + bw = (u8)odm_get_bb_reg(dm, R_0x9b0, 0xc); n_rx = (u8)odm_get_bb_reg(dm, R_0x1a2c, 0x60000) + 1; @@ -697,7 +795,7 @@ void phydm_read_cckpd_para_type4(void *dm_void) curr_cck_pd_t[1][2][0] = (u8)((reg1 & 0x00ff0000) >> 16); curr_cck_pd_t[0][2][1] = (u8)((reg2 & 0x00007C00) >> 10); curr_cck_pd_t[1][2][1] = (u8)((reg2 & 0xC0000000) >> 30) | - (u8)((reg3 & 0x00000007) << 3); + (u8)((reg3 & 0x00000007) << 2); } #endif #if (defined(PHYDM_COMPILE_ABOVE_4SS)) @@ -728,6 +826,29 @@ void phydm_cckpd_type4(void *dm_void) if (dm->is_linked) { PHYDM_DBG(dm, DBG_CCKPD, "Linked!!!\n"); + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) + if (dm->rssi_min > 40) { + lv = CCK_PD_LV_4; + PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n"); + } else if (dm->rssi_min > 32) { + lv = CCK_PD_LV_3; + PHYDM_DBG(dm, DBG_CCKPD, "Order 2\n"); + } else if (dm->rssi_min > 24) { + lv = CCK_PD_LV_2; + PHYDM_DBG(dm, DBG_CCKPD, "Order 3\n"); + } else { + if (cckpd_t->cck_fa_ma > 1000) { + lv = CCK_PD_LV_1; + PHYDM_DBG(dm, DBG_CCKPD, "Order 4-1\n"); + } else if (cckpd_t->cck_fa_ma < 500) { + lv = CCK_PD_LV_0; + PHYDM_DBG(dm, DBG_CCKPD, "Order 4-2\n"); + } else { + is_update = false; + PHYDM_DBG(dm, DBG_CCKPD, "Order 4-3\n"); + } + } + #else /*ODM_AP*/ if (igi > 0x38 && dm->rssi_min > 32) { lv = CCK_PD_LV_4; PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n"); @@ -749,6 +870,7 @@ void phydm_cckpd_type4(void *dm_void) PHYDM_DBG(dm, DBG_CCKPD, "Order 4-3\n"); } } + #endif } else { PHYDM_DBG(dm, DBG_CCKPD, "UnLinked!!!\n"); if (cckpd_t->cck_fa_ma > 1000) { @@ -783,7 +905,8 @@ void phydm_cck_pd_init_type4(void *dm_void) u32 reg1 = 0; u32 reg2 = 0; u32 reg3 = 0; - u8 pd_step = 0; + u8 pw_step = 0; + u8 cs_step = 0; u8 cck_bw = 0; /*r_RX_RF_BW*/ u8 cck_n_rx = 0; u8 val = 0; @@ -834,72 +957,94 @@ void phydm_cck_pd_init_type4(void *dm_void) reg3 = odm_get_bb_reg(dm, R_0x1ad4, MASKDWORD); for (i = 0 ; i < CCK_PD_LV_MAX ; i++) { - pd_step = i * 2; + pw_step = i * 2; + cs_step = i * 2; #if (RTL8197G_SUPPORT) - if (dm->support_ic_type & ODM_RTL8197G){ - pd_step = i; - if (i>CCK_PD_LV_3) - pd_step = 3; + if (dm->support_ic_type & ODM_RTL8197G) { + pw_step = i; + cs_step = i; + if (i > CCK_PD_LV_3) { + pw_step = 3; + cs_step = 3; + } + } + #endif + + #if (RTL8822C_SUPPORT) + if (dm->support_ic_type & ODM_RTL8822C) { + if (i == CCK_PD_LV_1) { + pw_step = 9; /*IGI-19.2:0x11=d'17*/ + cs_step = 0; + } else if (i == CCK_PD_LV_2) { + pw_step = 12; /*IGI-15.5:0x14=d'20*/ + cs_step = 1; + } else if (i == CCK_PD_LV_3) { + pw_step = 14; /*IGI-14:0x16=d'22*/ + cs_step = 1; + } else if (i == CCK_PD_LV_4) { + pw_step = 17; /*IGI-12:0x19=d'25*/ + cs_step = 1; + } } #endif - val = (u8)(reg0 & 0x000000ff) + pd_step; + val = (u8)(reg0 & 0x000000ff) + pw_step; PHYDM_DBG(dm, DBG_CCKPD, "lvl %d val = %x\n\n", i, val); cckpd_t->cckpd_jgr3[0][0][0][i] = val; - val = (u8)(reg1 & 0x000000ff) + pd_step; + val = (u8)(reg1 & 0x000000ff) + pw_step; cckpd_t->cckpd_jgr3[1][0][0][i] = val; - val = (u8)(reg2 & 0x0000001F) + pd_step; + val = (u8)(reg2 & 0x0000001f) + cs_step; cckpd_t->cckpd_jgr3[0][0][1][i] = val; - val = (u8)((reg2 & 0x01F00000) >> 20) + pd_step; + val = (u8)((reg2 & 0x01f00000) >> 20) + cs_step; cckpd_t->cckpd_jgr3[1][0][1][i] = val; #ifdef PHYDM_COMPILE_ABOVE_2SS if (dm->support_ic_type & PHYDM_IC_ABOVE_2SS) { - val = (u8)((reg0 & 0x0000ff00) >> 8) + pd_step; + val = (u8)((reg0 & 0x0000ff00) >> 8) + pw_step; cckpd_t->cckpd_jgr3[0][1][0][i] = val; - val = (u8)((reg1 & 0x0000ff00) >> 8) + pd_step; + val = (u8)((reg1 & 0x0000ff00) >> 8) + pw_step; cckpd_t->cckpd_jgr3[1][1][0][i] = val; - val = (u8)((reg2 & 0x000003E0) >> 5) + pd_step; + val = (u8)((reg2 & 0x000003e0) >> 5) + cs_step; cckpd_t->cckpd_jgr3[0][1][1][i] = val; - val = (u8)((reg2 & 0x3E000000) >> 25) + pd_step; + val = (u8)((reg2 & 0x3e000000) >> 25) + cs_step; cckpd_t->cckpd_jgr3[1][1][1][i] = val; } #endif #ifdef PHYDM_COMPILE_ABOVE_3SS if (dm->support_ic_type & PHYDM_IC_ABOVE_3SS) { - val = (u8)((reg0 & 0x00ff0000) >> 16) + pd_step; + val = (u8)((reg0 & 0x00ff0000) >> 16) + pw_step; cckpd_t->cckpd_jgr3[0][2][0][i] = val; - val = (u8)((reg1 & 0x00ff0000) >> 16) + pd_step; + val = (u8)((reg1 & 0x00ff0000) >> 16) + pw_step; cckpd_t->cckpd_jgr3[1][2][0][i] = val; - val = (u8)((reg2 & 0x00007C00) >> 10) + pd_step; + val = (u8)((reg2 & 0x00007c00) >> 10) + cs_step; cckpd_t->cckpd_jgr3[0][2][1][i] = val; - val = (u8)(((reg2 & 0xC0000000) >> 30) | - ((reg3 & 0x7) << 3)) + pd_step; + val = (u8)(((reg2 & 0xc0000000) >> 30) | + ((reg3 & 0x7) << 3)) + cs_step; cckpd_t->cckpd_jgr3[1][2][1][i] = val; } #endif #ifdef PHYDM_COMPILE_ABOVE_4SS if (dm->support_ic_type & PHYDM_IC_ABOVE_4SS) { - val = (u8)((reg0 & 0xff000000) >> 24) + pd_step; + val = (u8)((reg0 & 0xff000000) >> 24) + pw_step; cckpd_t->cckpd_jgr3[0][3][0][i] = val; - val = (u8)((reg1 & 0xff000000) >> 24) + pd_step; + val = (u8)((reg1 & 0xff000000) >> 24) + pw_step; cckpd_t->cckpd_jgr3[1][3][0][i] = val; - val = (u8)((reg2 & 0x000F8000) >> 15) + pd_step; + val = (u8)((reg2 & 0x000f8000) >> 15) + cs_step; cckpd_t->cckpd_jgr3[0][3][1][i] = val; - val = (u8)((reg3 & 0x000000F8) >> 3) + pd_step; + val = (u8)((reg3 & 0x000000f8) >> 3) + cs_step; cckpd_t->cckpd_jgr3[1][3][1][i] = val; } #endif @@ -931,13 +1076,26 @@ void phydm_invalid_cckpd_type4(void *dm_void) } } - #if (RTL8822C_SUPPORT) - if (dm->support_ic_type & ODM_RTL8822C) { - val = cckpd_t->cckpd_jgr3[1][1][1][i]; - if (i == CCK_PD_LV_3 && val > 0x16) - cckpd_t->cckpd_jgr3[1][1][1][i] = 0x16; - else if (i == CCK_PD_LV_4 && val > 0x17) - cckpd_t->cckpd_jgr3[1][1][1][i] = 0x17; + #if (RTL8198F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8198F) { + val = cckpd_t->cckpd_jgr3[0][3][1][i]; + if (i == CCK_PD_LV_1 && val > 0x10) + cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10; + else if (i == CCK_PD_LV_2 && val > 0x10) + cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10; + else if (i == CCK_PD_LV_3 && val > 0x10) + cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10; + else if (i == CCK_PD_LV_4 && val > 0x10) + cckpd_t->cckpd_jgr3[0][3][1][i] = 0x10; + val = cckpd_t->cckpd_jgr3[1][3][1][i]; + if (i == CCK_PD_LV_1 && val > 0xF) + cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF; + else if (i == CCK_PD_LV_2 && val > 0xF) + cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF; + else if (i == CCK_PD_LV_3 && val > 0xF) + cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF; + else if (i == CCK_PD_LV_4 && val > 0xF) + cckpd_t->cckpd_jgr3[1][3][1][i] = 0xF; } #endif } @@ -945,6 +1103,440 @@ void phydm_invalid_cckpd_type4(void *dm_void) #endif /*#ifdef PHYDM_COMPILE_CCKPD_TYPE4*/ + +#ifdef PHYDM_COMPILE_CCKPD_TYPE5 +void phydm_write_cck_pd_type5(void *dm_void, enum cckpd_lv lv, + enum cckpd_mode mode) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + u32 val = 0; + + PHYDM_DBG(dm, DBG_CCKPD, "write CCK CCA parameters(CS_ratio & PD)\n"); + switch (mode) { + case CCK_BW20_1R: /*RFBW20_1R*/ + { + val = cckpd_t->cck_pd_table_jgr3[0][0][0][lv]; + odm_set_bb_reg(dm, R_0x1a30, 0x1f, val); + val = cckpd_t->cck_pd_table_jgr3[0][0][1][lv]; + odm_set_bb_reg(dm, R_0x1a20, 0x1f, val); + } break; + case CCK_BW40_1R: /*RFBW40_1R*/ + { + val = cckpd_t->cck_pd_table_jgr3[1][0][0][lv]; + odm_set_bb_reg(dm, R_0x1a34, 0x1f, val); + val = cckpd_t->cck_pd_table_jgr3[1][0][1][lv]; + odm_set_bb_reg(dm, R_0x1a24, 0x1f, val); + } break; + #if (defined(PHYDM_COMPILE_ABOVE_2SS)) + case CCK_BW20_2R: /*RFBW20_2R*/ + { + val = cckpd_t->cck_pd_table_jgr3[0][1][0][lv]; + odm_set_bb_reg(dm, R_0x1a30, 0x3e0, val); + val = cckpd_t->cck_pd_table_jgr3[0][1][1][lv]; + odm_set_bb_reg(dm, R_0x1a20, 0x3e0, val); + } break; + case CCK_BW40_2R: /*RFBW40_2R*/ + { + val = cckpd_t->cck_pd_table_jgr3[1][1][0][lv]; + odm_set_bb_reg(dm, R_0x1a34, 0x3e0, val); + val = cckpd_t->cck_pd_table_jgr3[1][1][1][lv]; + odm_set_bb_reg(dm, R_0x1a24, 0x3e0, val); + } break; + #endif + #if (defined(PHYDM_COMPILE_ABOVE_3SS)) + case CCK_BW20_3R: /*RFBW20_3R*/ + { + val = cckpd_t->cck_pd_table_jgr3[0][2][0][lv]; + odm_set_bb_reg(dm, R_0x1a30, 0x7c00, val); + val = cckpd_t->cck_pd_table_jgr3[0][2][1][lv]; + odm_set_bb_reg(dm, R_0x1a20, 0x7c00, val); + } break; + case CCK_BW40_3R: /*RFBW40_3R*/ + { + val = cckpd_t->cck_pd_table_jgr3[1][2][0][lv]; + odm_set_bb_reg(dm, R_0x1a34, 0x7c00, val); + val = cckpd_t->cck_pd_table_jgr3[1][2][1][lv]; + odm_set_bb_reg(dm, R_0x1a24, 0x7c00, val); + } break; + #endif + #if (defined(PHYDM_COMPILE_ABOVE_4SS)) + case CCK_BW20_4R: /*RFBW20_4R*/ + { + val = cckpd_t->cck_pd_table_jgr3[0][3][0][lv]; + odm_set_bb_reg(dm, R_0x1a30, 0xF8000, val); + val = cckpd_t->cck_pd_table_jgr3[0][3][1][lv]; + odm_set_bb_reg(dm, R_0x1a20, 0xF8000, val); + } break; + case CCK_BW40_4R: /*RFBW40_4R*/ + { + val = cckpd_t->cck_pd_table_jgr3[1][3][0][lv]; + odm_set_bb_reg(dm, R_0x1a34, 0xF8000, val); + val = cckpd_t->cck_pd_table_jgr3[1][3][1][lv]; + odm_set_bb_reg(dm, R_0x1a24, 0xF8000, val); + } break; + #endif + default: + /*@pr_debug("[%s] warning!\n", __func__);*/ + break; + } +} + + +void phydm_set_cck_pd_lv_type5(void *dm_void, enum cckpd_lv lv) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + enum cckpd_mode cck_mode = CCK_BW20_1R; + enum channel_width cck_bw = CHANNEL_WIDTH_20; + u8 cck_n_rx = 0; + u32 val = 0; + /*u32 val_dbg = 0;*/ + + PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__); + PHYDM_DBG(dm, DBG_CCKPD, "lv: (%d) -> (%d)\n", cckpd_t->cck_pd_lv, lv); + + /*[Check Nrx] for 8723F*/ + cck_n_rx = 1; + + /*[Check BW]*/ + val = odm_get_bb_reg(dm, R_0x9b0, 0xc); + if (val == 0) + cck_bw = CHANNEL_WIDTH_20; + else if (val == 1) + cck_bw = CHANNEL_WIDTH_40; + else + cck_bw = CHANNEL_WIDTH_80; + + /*[Check LV]*/ + if (cckpd_t->cck_pd_lv == lv && + cckpd_t->cck_n_rx == cck_n_rx && + cckpd_t->cck_bw == cck_bw) { + PHYDM_DBG(dm, DBG_CCKPD, "stay in lv=%d\n", lv); + return; + } + cckpd_t->cck_bw = cck_bw; + cckpd_t->cck_n_rx = cck_n_rx; + cckpd_t->cck_pd_lv = lv; + cckpd_t->cck_fa_ma = CCK_FA_MA_RESET; + + switch (cck_n_rx) { + case 1: /*1R*/ + { + if (cck_bw == CHANNEL_WIDTH_20) + cck_mode = CCK_BW20_1R; + else if (cck_bw == CHANNEL_WIDTH_40) + cck_mode = CCK_BW40_1R; + } break; + #if (defined(PHYDM_COMPILE_ABOVE_2SS)) + case 2: /*2R*/ + { + if (cck_bw == CHANNEL_WIDTH_20) + cck_mode = CCK_BW20_2R; + else if (cck_bw == CHANNEL_WIDTH_40) + cck_mode = CCK_BW40_2R; + } break; + #endif + #if (defined(PHYDM_COMPILE_ABOVE_3SS)) + case 3: /*3R*/ + { + if (cck_bw == CHANNEL_WIDTH_20) + cck_mode = CCK_BW20_3R; + else if (cck_bw == CHANNEL_WIDTH_40) + cck_mode = CCK_BW40_3R; + } break; + #endif + #if (defined(PHYDM_COMPILE_ABOVE_4SS)) + case 4: /*4R*/ + { + if (cck_bw == CHANNEL_WIDTH_20) + cck_mode = CCK_BW20_4R; + else if (cck_bw == CHANNEL_WIDTH_40) + cck_mode = CCK_BW40_4R; + } break; + #endif + default: + /*@pr_debug("[%s] warning!\n", __func__);*/ + break; + } + + + +phydm_write_cck_pd_type5(dm, lv, cck_mode); +} + +void phydm_read_cckpd_para_type5(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + u8 bw = 0; /*r_RX_RF_BW*/ + u8 n_rx = 0; + u8 curr_cck_pd_t[2][4][2]; + u32 reg0 = 0; + u32 reg1 = 0; + u32 reg2 = 0; + u32 reg3 = 0; + + bw = (u8)odm_get_bb_reg(dm, R_0x9b0, 0xc); + + reg0 = odm_get_bb_reg(dm, R_0x1a30, MASKDWORD); + reg1 = odm_get_bb_reg(dm, R_0x1a34, MASKDWORD); + reg2 = odm_get_bb_reg(dm, R_0x1a20, MASKDWORD); + reg3 = odm_get_bb_reg(dm, R_0x1a24, MASKDWORD); + curr_cck_pd_t[0][0][0] = (u8)(reg0 & 0x0000001f); + curr_cck_pd_t[1][0][0] = (u8)(reg1 & 0x0000001f); + curr_cck_pd_t[0][0][1] = (u8)(reg2 & 0x0000001f); + curr_cck_pd_t[1][0][1] = (u8)(reg3 & 0x0000001f); + n_rx = 1; + #if (defined(PHYDM_COMPILE_ABOVE_2SS)) + if (dm->support_ic_type & PHYDM_IC_ABOVE_2SS) { + curr_cck_pd_t[0][1][0] = (u8)((reg0 & 0x000003E0) >> 5); + curr_cck_pd_t[1][1][0] = (u8)((reg1 & 0x000003E0) >> 5); + curr_cck_pd_t[0][1][1] = (u8)((reg2 & 0x000003E0) >> 5); + curr_cck_pd_t[1][1][1] = (u8)((reg3 & 0x000003E0) >> 5); + n_rx = 2; + } + #endif + #if (defined(PHYDM_COMPILE_ABOVE_3SS)) + if (dm->support_ic_type & PHYDM_IC_ABOVE_3SS) { + curr_cck_pd_t[0][2][0] = (u8)((reg0 & 0x00007C00) >> 10); + curr_cck_pd_t[1][2][0] = (u8)((reg1 & 0x00007C00) >> 10); + curr_cck_pd_t[0][2][1] = (u8)((reg2 & 0x00007C00) >> 10); + curr_cck_pd_t[1][2][1] = (u8)((reg3 & 0x00007C00) >> 10); + n_rx = 3; + } + #endif + #if (defined(PHYDM_COMPILE_ABOVE_4SS)) + if (dm->support_ic_type & PHYDM_IC_ABOVE_4SS) { + curr_cck_pd_t[0][3][0] = (u8)((reg0 & 0x000F8000) >> 15); + curr_cck_pd_t[1][3][0] = (u8)((reg1 & 0x000F8000) >> 15); + curr_cck_pd_t[0][3][1] = (u8)((reg2 & 0x000F8000) >> 15); + curr_cck_pd_t[1][3][1] = (u8)((reg3 & 0x000F8000) >> 15); + n_rx = 4; + } + #endif + + PHYDM_DBG(dm, DBG_CCKPD, "bw=%dM, Nrx=%d\n", 20 << bw, n_rx); + PHYDM_DBG(dm, DBG_CCKPD, "lv=%d, readback CS_th=0x%x, PD th=0x%x\n", + cckpd_t->cck_pd_lv, + curr_cck_pd_t[bw][n_rx - 1][1], + curr_cck_pd_t[bw][n_rx - 1][0]); +} + +void phydm_cckpd_type5(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + u8 igi = dm->dm_dig_table.cur_ig_value; + enum cckpd_lv lv = 0; + boolean is_update = true; + + PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__); + + if (dm->is_linked) { + PHYDM_DBG(dm, DBG_CCKPD, "Linked!!!\n"); + if (dm->rssi_min > 40) { + lv = CCK_PD_LV_4; + PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n"); + } else if (dm->rssi_min > 32) { + lv = CCK_PD_LV_3; + PHYDM_DBG(dm, DBG_CCKPD, "Order 2\n"); + } else if (dm->rssi_min > 24) { + lv = CCK_PD_LV_2; + PHYDM_DBG(dm, DBG_CCKPD, "Order 3\n"); + } else { + if (cckpd_t->cck_fa_ma > 1000) { + lv = CCK_PD_LV_1; + PHYDM_DBG(dm, DBG_CCKPD, "Order 4-1\n"); + } else if (cckpd_t->cck_fa_ma < 500) { + lv = CCK_PD_LV_0; + PHYDM_DBG(dm, DBG_CCKPD, "Order 4-2\n"); + } else { + is_update = false; + PHYDM_DBG(dm, DBG_CCKPD, "Order 4-3\n"); + } + } + } else { + PHYDM_DBG(dm, DBG_CCKPD, "UnLinked!!!\n"); + if (cckpd_t->cck_fa_ma > 1000) { + lv = CCK_PD_LV_1; + PHYDM_DBG(dm, DBG_CCKPD, "Order 1\n"); + } else if (cckpd_t->cck_fa_ma < 500) { + lv = CCK_PD_LV_0; + PHYDM_DBG(dm, DBG_CCKPD, "Order 2\n"); + } else { + is_update = false; + PHYDM_DBG(dm, DBG_CCKPD, "Order 3\n"); + } + } + + if (is_update) { + phydm_set_cck_pd_lv_type5(dm, lv); + + PHYDM_DBG(dm, DBG_CCKPD, "setting CS_th = 0x%x, PD th = 0x%x\n", + cckpd_t->cck_pd_table_jgr3[cckpd_t->cck_bw] + [cckpd_t->cck_n_rx - 1][1][lv], + cckpd_t->cck_pd_table_jgr3[cckpd_t->cck_bw] + [cckpd_t->cck_n_rx - 1][0][lv]); + } + + phydm_read_cckpd_para_type5(dm); +} + +void phydm_cck_pd_init_type5(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + u32 reg0 = 0; + u32 reg1 = 0; + u32 reg2 = 0; + u32 reg3 = 0; + u8 pw_step = 0; + u8 cs_step = 0; + u8 cck_bw = 0; /*r_RX_RF_BW*/ + u8 cck_n_rx = 0; + u8 val = 0; + u8 i = 0; + + PHYDM_DBG(dm, DBG_CCKPD, "[%s]======>\n", __func__); + #if 0 + /*@ + *cckpd_t[0][0][0][0] = 1a30[4:0] r_PD_lim_RFBW20_1R + *cckpd_t[0][1][0][0] = 1a30[9:5] r_PD_lim_RFBW20_2R + *cckpd_t[0][2][0][0] = 1a30[14:10] r_PD_lim_RFBW20_3R + *cckpd_t[0][3][0][0] = 1a30[19:15] r_PD_lim_RFBW20_4R + *cckpd_t[1][0][0][0] = 1a34[4:0] r_PD_lim_RFBW40_1R + *cckpd_t[1][1][0][0] = 1a34[9:5] r_PD_lim_RFBW40_2R + *cckpd_t[1][2][0][0] = 1a34[14:10] r_PD_lim_RFBW40_3R + *cckpd_t[1][3][0][0] = 1a34[19:15] r_PD_lim_RFBW40_4R + * + * + *cckpd_t[0][0][1][0] = 1a20[4:0] r_CS_ratio_RFBW20_1R + *cckpd_t[0][1][1][0] = 1a20[9:5] r_CS_ratio_RFBW20_2R + *cckpd_t[0][2][1][0] = 1a20[14:10] r_CS_ratio_RFBW20_3R + *cckpd_t[0][3][1][0] = 1a20[19:15] r_CS_ratio_RFBW20_4R + *cckpd_t[1][0][1][0] = 1a24[4:0] r_CS_ratio_RFBW40_1R + *cckpd_t[1][1][1][0] = 1a24[9:5] r_CS_ratio_RFBW40_2R + *cckpd_t[1][2][1][0] = 1a24[14:10] r_CS_ratio_RFBW40_3R + *cckpd_t[1][3][1][0] = 1a24[19:15] r_CS_ratio_RFBW40_4R + */ + #endif + /*[Check Nrx]*/ + cck_n_rx = 1; + + /*[Check BW]*/ + val = (u8)odm_get_bb_reg(dm, R_0x9b0, 0xc); + if (val == 0) + cck_bw = CHANNEL_WIDTH_20; + else if (val == 1) + cck_bw = CHANNEL_WIDTH_40; + else + cck_bw = CHANNEL_WIDTH_80; + + cckpd_t->cck_bw = cck_bw; + reg0 = odm_get_bb_reg(dm, R_0x1a30, MASKDWORD); + reg1 = odm_get_bb_reg(dm, R_0x1a34, MASKDWORD); + reg2 = odm_get_bb_reg(dm, R_0x1a20, MASKDWORD); + reg3 = odm_get_bb_reg(dm, R_0x1a24, MASKDWORD); + + for (i = 0 ; i < CCK_PD_LV_MAX ; i++) { + pw_step = i * 2; + cs_step = i * 2; + + #if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) { + if (i == CCK_PD_LV_1) { + pw_step = 9; /*IGI-19.2:0x11=d'17*/ + cs_step = 0; + } else if (i == CCK_PD_LV_2) { + pw_step = 12; /*IGI-15.5:0x14=d'20*/ + cs_step = 1; + } else if (i == CCK_PD_LV_3) { + pw_step = 14; /*IGI-14:0x16=d'22*/ + cs_step = 1; + } else if (i == CCK_PD_LV_4) { + pw_step = 17; /*IGI-12:0x19=d'25*/ + cs_step = 1; + } + } + #endif + val = (u8)(reg0 & 0x0000001F) + pw_step; + PHYDM_DBG(dm, DBG_CCKPD, "lvl %d val = %x\n\n", i, val); + cckpd_t->cck_pd_table_jgr3[0][0][0][i] = val; + + val = (u8)(reg1 & 0x0000001F) + pw_step; + cckpd_t->cck_pd_table_jgr3[1][0][0][i] = val; + + val = (u8)(reg2 & 0x0000001F) + cs_step; + cckpd_t->cck_pd_table_jgr3[0][0][1][i] = val; + + val = (u8)(reg3 & 0x0000001F) + cs_step; + cckpd_t->cck_pd_table_jgr3[1][0][1][i] = val; + + #ifdef PHYDM_COMPILE_ABOVE_2SS + if (dm->support_ic_type & PHYDM_IC_ABOVE_2SS) { + val = (u8)((reg0 & 0x000003E0) >> 5) + pw_step; + cckpd_t->cck_pd_table_jgr3[0][1][0][i] = val; + + val = (u8)((reg1 & 0x000003E0) >> 5) + pw_step; + cckpd_t->cck_pd_table_jgr3[1][1][0][i] = val; + + val = (u8)((reg2 & 0x000003E0) >> 5) + cs_step; + cckpd_t->cck_pd_table_jgr3[0][1][1][i] = val; + + val = (u8)((reg3 & 0x000003E0) >> 5) + cs_step; + cckpd_t->cck_pd_table_jgr3[1][1][1][i] = val; + + cck_n_rx = 2; + } + #endif + #ifdef PHYDM_COMPILE_ABOVE_3SS + if (dm->support_ic_type & PHYDM_IC_ABOVE_3SS) { + val = (u8)((reg0 & 0x00007C00) >> 10) + pw_step; + cckpd_t->cck_pd_table_jgr3[0][2][0][i] = val; + + val = (u8)((reg1 & 0x00007C00) >> 10) + pw_step; + cckpd_t->cck_pd_table_jgr3[1][2][0][i] = val; + + val = (u8)((reg2 & 0x00007C00) >> 10) + cs_step; + cckpd_t->cck_pd_table_jgr3[0][2][1][i] = val; + + val = (u8)((reg3 & 0x00007C00) >> 10) + cs_step; + cckpd_t->cck_pd_table_jgr3[1][2][1][i] = val; + + cck_n_rx = 3; + } + #endif + + #ifdef PHYDM_COMPILE_ABOVE_4SS + if (dm->support_ic_type & PHYDM_IC_ABOVE_4SS) { + val = (u8)((reg0 & 0x000F8000) >> 15) + pw_step; + cckpd_t->cck_pd_table_jgr3[0][3][0][i] = val; + + val = (u8)((reg1 & 0x000F8000) >> 15) + pw_step; + cckpd_t->cck_pd_table_jgr3[1][3][0][i] = val; + + val = (u8)((reg2 & 0x000F8000) >> 15) + cs_step; + cckpd_t->cck_pd_table_jgr3[0][3][1][i] = val; + + val = (u8)((reg3 & 0x000F8000) >> 15) + cs_step; + cckpd_t->cck_pd_table_jgr3[1][3][1][i] = val; + + cck_n_rx = 4; + } + #endif + } + cckpd_t->cck_n_rx = cck_n_rx; +} + + + + +#endif /*#ifdef PHYDM_COMPILE_CCKPD_TYPE5*/ + + + + void phydm_set_cckpd_val(void *dm_void, u32 *val_buf, u8 val_len) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -984,6 +1576,11 @@ void phydm_set_cckpd_val(void *dm_void, u32 *val_buf, u8 val_len) phydm_set_cck_pd_lv_type4(dm, lv); break; #endif + #ifdef PHYDM_COMPILE_CCKPD_TYPE5 + case 5: + phydm_set_cck_pd_lv_type5(dm, lv); + break; + #endif default: pr_debug("[%s]warning\n", __func__); break; @@ -1068,7 +1665,17 @@ void phydm_cck_pd_th(void *dm_void) #endif #ifdef PHYDM_COMPILE_CCKPD_TYPE4 case 4: - phydm_cckpd_type4(dm); + #ifdef PHYDM_DCC_ENHANCE + if (dm->dm_dcc_info.dcc_en) + phydm_cckpd_type4_dcc(dm); + else + #endif + phydm_cckpd_type4(dm); + break; + #endif + #ifdef PHYDM_COMPILE_CCKPD_TYPE5 + case 5: + phydm_cckpd_type5(dm); break; #endif default: @@ -1094,36 +1701,46 @@ void phydm_cck_pd_init(void *dm_void) else if (dm->support_ic_type & CCK_PD_IC_TYPE4) cckpd_t->cckpd_hw_type = 4; + if (dm->support_ic_type & CCK_PD_IC_TYPE5) + cckpd_t->cckpd_hw_type = 5; + PHYDM_DBG(dm, DBG_CCKPD, "[%s] cckpd_hw_type=%d\n", __func__, cckpd_t->cckpd_hw_type); cckpd_t->cck_pd_lv = CCK_PD_LV_INIT; cckpd_t->cck_n_rx = 0xff; cckpd_t->cck_bw = CHANNEL_WIDTH_MAX; + cckpd_t->cck_fa_th[1] = 400; + cckpd_t->cck_fa_th[0] = 200; switch (cckpd_t->cckpd_hw_type) { #ifdef PHYDM_COMPILE_CCKPD_TYPE1 case 1: - phydm_set_cckpd_lv_type1(dm, CCK_PD_LV_0); + phydm_set_cckpd_lv_type1(dm, CCK_PD_LV_1); break; #endif #ifdef PHYDM_COMPILE_CCKPD_TYPE2 case 2: cckpd_t->aaa_default = odm_read_1byte(dm, 0xaaa) & 0x1f; - phydm_set_cckpd_lv_type2(dm, CCK_PD_LV_0); + phydm_set_cckpd_lv_type2(dm, CCK_PD_LV_1); break; #endif #ifdef PHYDM_COMPILE_CCKPD_TYPE3 case 3: phydm_cck_pd_init_type3(dm); - phydm_set_cckpd_lv_type3(dm, CCK_PD_LV_0); + phydm_set_cckpd_lv_type3(dm, CCK_PD_LV_1); break; #endif #ifdef PHYDM_COMPILE_CCKPD_TYPE4 case 4: phydm_cck_pd_init_type4(dm); phydm_invalid_cckpd_type4(dm); - phydm_set_cck_pd_lv_type4(dm, CCK_PD_LV_0); + phydm_set_cck_pd_lv_type4(dm, CCK_PD_LV_1); + break; + #endif + #ifdef PHYDM_COMPILE_CCKPD_TYPE5 + case 5: + phydm_cck_pd_init_type5(dm); break; #endif default: @@ -1131,5 +1748,160 @@ void phydm_cck_pd_init(void *dm_void) break; } } + +#ifdef PHYDM_DCC_ENHANCE + +void phydm_cckpd_type4_dcc(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + enum cckpd_lv lv_curr = cckpd_t->cck_pd_lv; + enum phydm_cck_pd_trend trend = CCKPD_STABLE; + u8 th_ofst = 0; + u16 lv_up_th, lv_down_th; + + PHYDM_DBG(dm, DBG_CCKPD, "%s ======>\n", __func__); + + if (!dm->is_linked) + th_ofst = 1; + + lv_up_th = (cckpd_t->cck_fa_th[1]) << th_ofst; + lv_down_th = (cckpd_t->cck_fa_th[0]) << th_ofst; + + PHYDM_DBG(dm, DBG_CCKPD, "th{Up, Down}: {%d, %d}\n", + lv_up_th, lv_down_th); + + if (cckpd_t->cck_fa_ma > lv_up_th) { + if (lv_curr <= CCK_PD_LV_3) { + lv_curr++; + trend = CCKPD_INCREASING; + } else { + lv_curr = CCK_PD_LV_4; + } + } else if (cckpd_t->cck_fa_ma < lv_down_th) { + if (lv_curr >= CCK_PD_LV_1) { + lv_curr--; + trend = CCKPD_DECREASING; + } else { + lv_curr = CCK_PD_LV_0; + } + } + + PHYDM_DBG(dm, DBG_CCKPD, "lv: %d->%d\n", cckpd_t->cck_pd_lv, lv_curr); +#if 1 + if (trend != CCKPD_STABLE) { + phydm_set_cck_pd_lv_type4(dm, lv_curr); + + PHYDM_DBG(dm, DBG_CCKPD, "setting CS_th = 0x%x, PD th = 0x%x\n", + cckpd_t->cckpd_jgr3[cckpd_t->cck_bw] + [cckpd_t->cck_n_rx - 1][1][lv_curr], + cckpd_t->cckpd_jgr3[cckpd_t->cck_bw] + [cckpd_t->cck_n_rx - 1][0][lv_curr]); + } + phydm_read_cckpd_para_type4(dm); +#endif +} + +boolean phydm_do_cckpd(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_dig_struct *dig_t = &dm->dm_dig_table; + + if (dig_t->igi_trend == DIG_INCREASING) + return false; + + return true; +} + +void phydm_dig_cckpd_coex(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_dcc_struct *dcc = &dm->dm_dcc_info; + + if (*dm->channel > 36) { + phydm_dig(dm); + return; + } else if (!dcc->dcc_en) { + phydm_dig(dm); + phydm_cck_pd_th(dm); + return; + } + + dcc->dig_execute_cnt++; + PHYDM_DBG(dm, DBG_CCKPD, "DCC_cnt: %d\n", dcc->dig_execute_cnt); + + if (dcc->dig_execute_cnt % dcc->dcc_ratio) { + PHYDM_DBG(dm, DBG_CCKPD, "DCC: DIG\n"); + phydm_dig(dm); + } else { + if (phydm_do_cckpd(dm)) { + PHYDM_DBG(dm, DBG_CCKPD, "DCC: CCKPD\n"); + dcc->dcc_mode = DCC_CCK_PD; + phydm_cck_pd_th(dm); + } else { + PHYDM_DBG(dm, DBG_CCKPD, "DCC: Boost_DIG\n"); + dcc->dcc_mode = DCC_DIG; + phydm_dig(dm); + } + } +} + +void phydm_dig_cckpd_coex_init(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_dig_struct *dig_t = &dm->dm_dig_table; + struct phydm_dcc_struct *dcc = &dm->dm_dcc_info; + + dcc->dcc_mode = DCC_DIG; + dcc->dcc_en = false; + dcc->dig_execute_cnt = 0; + dcc->dcc_ratio = 2; +} + +void phydm_dig_cckpd_coex_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_cckpd_struct *cckpd_t = &dm->dm_cckpd_table; + struct phydm_dcc_struct *dcc = &dm->dm_dcc_info; + char help[] = "-h"; + u32 var[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 i = 0; + + for (i = 0; i < 3; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var[i]); + } + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Enable: en {0/1}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "DCC_ratio: ratio {x}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "threshold: th {Down_th} {Up_th}\n"); + } else if ((strcmp(input[1], "en") == 0)) { + dcc->dcc_en = (var[1]) ? true : false; + PDM_SNPF(out_len, used, output + used, out_len - used, + "en=%d\n", dcc->dcc_en); + } else if ((strcmp(input[1], "ratio") == 0)) { + dcc->dcc_ratio = (u8)var[1]; + PDM_SNPF(out_len, used, output + used, out_len - used, + "Ratio=%d\n", dcc->dcc_ratio); + } else if ((strcmp(input[1], "th") == 0)) { + cckpd_t->cck_fa_th[1] = (u16)var[2]; + cckpd_t->cck_fa_th[0] = (u16)var[1]; + PDM_SNPF(out_len, used, output + used, out_len - used, + "th{Down, Up}: {%d, %d}\n", + cckpd_t->cck_fa_th[0], cckpd_t->cck_fa_th[1]); + } + + *_used = used; + *_out_len = out_len; +} + +#endif #endif /*#ifdef PHYDM_SUPPORT_CCKPD*/ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cck_pd.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cck_pd.h index d87be4aa49ad..00ed6980de8d 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cck_pd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cck_pd.h @@ -27,8 +27,8 @@ #ifndef __PHYDM_CCK_PD_H__ #define __PHYDM_CCK_PD_H__ -/* 2019.05.09 Modify the return criterion of supportability of CCK_PD*/ -#define CCK_PD_VERSION "3.5" +/* 2019.12.25 decrease CS_ratio in 8822C due to Lenovo test result(PCIE-5136).*/ +#define CCK_PD_VERSION "4.0" /*@ * 1 ============================================================ @@ -53,6 +53,7 @@ /*@extend for different bw & path*/ #define CCK_PD_IC_TYPE4 ODM_IC_JGR3_SERIES /*@extend for different bw & path*/ +#define CCK_PD_IC_TYPE5 (ODM_RTL8723F) /*@extend for different CR*/ /*@Compile time flag of CCK_PD HW type*/ #if (RTL8188E_SUPPORT || RTL8812A_SUPPORT || RTL8821A_SUPPORT ||\ @@ -74,6 +75,10 @@ #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT #define PHYDM_COMPILE_CCKPD_TYPE4 /*@extend for different bw & path*/ #endif +#if (RTL8723F_SUPPORT) + #define PHYDM_COMPILE_CCKPD_TYPE5 /*@extend for different & path*/ +#endif + /*@ * 1 ============================================================ * 1 enumeration @@ -100,6 +105,17 @@ enum cckpd_mode { CCK_BW40_4R = 7 }; +enum dcc_mode { + DCC_DIG = 0, + DCC_CCK_PD = 1 +}; + +enum phydm_cck_pd_trend { + CCKPD_STABLE = 0, + CCKPD_INCREASING = 1, + CCKPD_DECREASING = 2 +}; + /*@ * 1 ============================================================ * 1 structure @@ -107,6 +123,16 @@ enum cckpd_mode { */ #ifdef PHYDM_SUPPORT_CCKPD + +#ifdef PHYDM_DCC_ENHANCE +struct phydm_dcc_struct { /*DIG CCK_PD coexistence*/ + boolean dcc_en; + enum dcc_mode dcc_mode; + u32 dig_execute_cnt; + u8 dcc_ratio; +}; +#endif + struct phydm_cckpd_struct { u8 cckpd_hw_type; u8 cur_cck_cca_thres; /*@current cck_pd value 0xa0a*/ @@ -114,6 +140,7 @@ struct phydm_cckpd_struct { u32 rvrt_val; /*all rvrt_val for pause API must set to u32*/ u8 pause_lv; u8 cck_n_rx; + u16 cck_fa_th[2]; enum channel_width cck_bw; enum cckpd_lv cck_pd_lv; #ifdef PHYDM_COMPILE_CCKPD_TYPE2 @@ -144,6 +171,10 @@ struct phydm_cckpd_struct { /*@[bw][nrx][0:PD/1:CS][lv]*/ u8 cckpd_jgr3[2][4][2][CCK_PD_LV_MAX]; #endif + #ifdef PHYDM_COMPILE_CCKPD_TYPE5 + /*@[bw][nrx][0:PD/1:CS][lv]*/ + u8 cck_pd_table_jgr3[2][4][2][CCK_PD_LV_MAX]; + #endif }; #endif @@ -157,4 +188,15 @@ void phydm_set_cckpd_val(void *dm_void, u32 *val_buf, u8 val_len); void phydm_cck_pd_th(void *dm_void); void phydm_cck_pd_init(void *dm_void); + +#ifdef PHYDM_DCC_ENHANCE +void phydm_cckpd_type4_dcc(void *dm_void); + +void phydm_dig_cckpd_coex(void *dm_void); + +void phydm_dig_cckpd_coex_init(void *dm_void); + +void phydm_dig_cckpd_coex_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); +#endif #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cck_rx_pathdiv.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cck_rx_pathdiv.c index bd74f0f0476a..733c33793465 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cck_rx_pathdiv.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cck_rx_pathdiv.c @@ -132,8 +132,7 @@ void phydm_cck_rx_pathdiv_dbg(void *dm_void, char input[][16], u32 *_used, return; for (i = 0; i < 3; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); } if ((strcmp(input[1], help) == 0)) { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_ccx.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_ccx.c index 69fb4137a7dd..1f0dc5d2b77b 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_ccx.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_ccx.c @@ -51,281 +51,725 @@ void phydm_ccx_hw_restart(void *dm_void) #ifdef FAHM_SUPPORT -u16 phydm_hw_divider(void *dm_void, u16 numerator, u16 denumerator) +void phydm_fahm_racing_release(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; - u16 result = DEVIDER_ERROR; - u32 tmp_u32 = ((numerator << 16) | denumerator); - u32 reg_devider_input; - u32 reg; - u8 i; + struct ccx_info *ccx = &dm->dm_ccx_info; + u32 value32 = 0; PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm_racing_release : lv:(%d)->(0)\n", + ccx->fahm_set_lv); - if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - reg_devider_input = 0x1cbc; - reg = 0x1f98; - } else { - reg_devider_input = 0x980; - reg = 0x9f0; - } + ccx->fahm_ongoing = false; + ccx->fahm_set_lv = FAHM_RELEASE; - odm_set_bb_reg(dm, reg_devider_input, MASKDWORD, tmp_u32); + if (!(ccx->fahm_app == FAHM_BACKGROUND || ccx->fahm_app == FAHM_ACS)) + phydm_pause_func(dm, F00_DIG, PHYDM_RESUME, + PHYDM_PAUSE_LEVEL_1, 1, &value32); - for (i = 0; i < 10; i++) { - ODM_delay_ms(1); - if (odm_get_bb_reg(dm, reg, BIT(24))) { - /*@Chk HW rpt is ready*/ - - result = (u16)odm_get_bb_reg(dm, reg, MASKBYTE2); - break; - } - } - return result; + ccx->fahm_app = FAHM_BACKGROUND; } -void phydm_fahm_trigger(void *dm_void, u16 tgr_period) +u8 phydm_fahm_racing_ctrl(void *dm_void, enum phydm_fahm_level lv) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 set_result = PHYDM_SET_SUCCESS; + /*acquire to control FAHM API*/ + + PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm_ongoing=%d, lv:(%d)->(%d)\n", + ccx->fahm_ongoing, ccx->fahm_set_lv, lv); + if (ccx->fahm_ongoing) { + if (lv <= ccx->fahm_set_lv) { + set_result = PHYDM_SET_FAIL; + } else { + phydm_ccx_hw_restart(dm); + ccx->fahm_ongoing = false; + } + } + + if (set_result) + ccx->fahm_set_lv = lv; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm racing success=%d\n", set_result); + return set_result; +} + +void phydm_fahm_trigger(void *dm_void) { /*@unit (4us)*/ struct dm_struct *dm = (struct dm_struct *)dm_void; - u32 fahm_reg1; - - if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - odm_set_bb_reg(dm, R_0x1cf8, 0xffff00, tgr_period); - - fahm_reg1 = 0x994; - } else { - odm_set_bb_reg(dm, R_0x978, 0xff000000, (tgr_period & 0xff)); - odm_set_bb_reg(dm, R_0x97c, 0xff, (tgr_period & 0xff00) >> 8); - - fahm_reg1 = 0x890; - } - - odm_set_bb_reg(dm, fahm_reg1, BIT(2), 0); - odm_set_bb_reg(dm, fahm_reg1, BIT(2), 1); -} - -void phydm_fahm_set_valid_cnt(void *dm_void, u8 numerator_sel, - u8 denominator_sel) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct ccx_info *ccx_info = &dm->dm_ccx_info; - u32 fahm_reg1; + struct ccx_info *ccx = &dm->dm_ccx_info; + u32 reg = 0; PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); - if (ccx_info->fahm_nume_sel == numerator_sel && - ccx_info->fahm_denom_sel == denominator_sel) { - PHYDM_DBG(dm, DBG_ENV_MNTR, "no need to update\n"); - return; + switch (dm->ic_ip_series) { + case PHYDM_IC_JGR3: + reg = R_0x1e60; + break; + case PHYDM_IC_AC: + reg = R_0x994; + break; + case PHYDM_IC_N: + reg = R_0x890; + break; + default: + break; } - ccx_info->fahm_nume_sel = numerator_sel; - ccx_info->fahm_denom_sel = denominator_sel; + odm_set_bb_reg(dm, reg, BIT(2), 0); + odm_set_bb_reg(dm, reg, BIT(2), 1); - if (dm->support_ic_type & ODM_IC_11AC_SERIES) - fahm_reg1 = 0x994; - else - fahm_reg1 = 0x890; - - odm_set_bb_reg(dm, fahm_reg1, 0xe0, numerator_sel); - odm_set_bb_reg(dm, fahm_reg1, 0x7000, denominator_sel); + ccx->fahm_trigger_time = dm->phydm_sys_up_time; + ccx->fahm_rpt_stamp++; + ccx->fahm_ongoing = true; } -void phydm_fahm_get_result(void *dm_void) +boolean +phydm_fahm_check_rdy(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; - u16 fahm_cnt[12]; /*packet count*/ - u16 fahm_rpt[12]; /*percentage*/ - u16 denominator; /*@fahm_denominator packet count*/ - u32 reg_rpt, reg_rpt_2; - u32 reg_tmp; boolean is_ready = false; - u8 i; + u32 reg = 0, reg_bit = 0; + + switch (dm->ic_ip_series) { + case PHYDM_IC_JGR3: + reg = R_0x2d84; + reg_bit = 31; + break; + case PHYDM_IC_AC: + reg = R_0x1f98; + reg_bit = 31; + break; + case PHYDM_IC_N: + reg = R_0x9f0; + reg_bit = 31; + break; + default: + break; + } + + if (odm_get_bb_reg(dm, reg, BIT(reg_bit))) + is_ready = true; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "FAHM rdy=%d\n", is_ready); + + return is_ready; +} + +u8 phydm_fahm_cal_wgt_avg(void *dm_void, u8 start_i, u8 end_i, u16 r_sum, + u16 period) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 i = 0; + u32 pwr_tmp = 0; + u8 pwr = 0; + u32 fahm_valid = 0; PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); - if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - reg_rpt = 0x1f80; - reg_rpt_2 = 0x1f98; + if (r_sum == 0) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "rpt_sum = 0, don't need to update\n"); + return 0x0; + } else if (end_i > NHM_RPT_NUM - 1) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[WARNING]end_i is larger than 11!!\n"); + return 0x0; + } + + for (i = start_i; i <= end_i; i++) { + if (i == 0) + pwr_tmp += ccx->fahm_result[0] * + MAX_2(ccx->fahm_th[0] - 2, 0); + else if (i == (NHM_RPT_NUM - 1)) + pwr_tmp += ccx->fahm_result[NHM_RPT_NUM - 1] * + (ccx->fahm_th[NHM_TH_NUM - 1] + 2); + else + pwr_tmp += ccx->fahm_result[i] * + (ccx->fahm_th[i - 1] + ccx->fahm_th[i]) >> 1; + } + + /* protection for the case of minus pwr(RSSI)*/ + pwr = (u8)(NTH_TH_2_RSSI(MAX_2(PHYDM_DIV(pwr_tmp, r_sum), 20))); + fahm_valid = PHYDM_DIV(r_sum * 100, period); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "valid: ((%d)) percent, pwr(RSSI)=((%d))\n", + fahm_valid, pwr); + + return pwr; +} + +void phydm_fahm_get_utility(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + + if (ccx->fahm_rpt_sum >= ccx->fahm_result[0]) { + ccx->fahm_pwr = phydm_fahm_cal_wgt_avg(dm, 0, NHM_RPT_NUM - 1, + ccx->fahm_rpt_sum, + ccx->fahm_period); } else { - reg_rpt = 0x9d8; - reg_rpt_2 = 0x9f0; + PHYDM_DBG(dm, DBG_ENV_MNTR, "[warning] fahm_rpt_sum invalid\n"); + ccx->fahm_pwr = 0; } - for (i = 0; i < 3; i++) { - if (odm_get_bb_reg(dm, reg_rpt_2, BIT(31))) { - /*@Chk HW rpt is ready*/ - is_ready = true; - break; - } - ODM_delay_ms(1); + PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm_pwr=%d\n", ccx->fahm_pwr); +} + +boolean +phydm_fahm_get_result(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u32 value32 = 0; + u16 denom; /*fahm_denominator packet count*/ + u32 reg1 = 0; + u32 reg2 = 0; + u8 i = 0; + u32 fahm_rpt_sum_tmp = 0; + + switch (dm->ic_ip_series) { + case PHYDM_IC_JGR3: + reg1 = R_0x2d6c; + reg2 = R_0x2d84; + break; + case PHYDM_IC_AC: + reg1 = R_0x1f80; + reg2 = R_0x1f98; + break; + case PHYDM_IC_N: + reg1 = R_0x9d8; + reg2 = R_0x9f0; + break; + default: + break; } - if (!is_ready) - return; + if (!(phydm_fahm_check_rdy(dm))) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "Get FAHM report Fail\n"); + phydm_fahm_racing_release(dm); + return false; + } /*@Get FAHM Denominator*/ - denominator = (u16)odm_get_bb_reg(dm, reg_rpt_2, MASKLWORD); + denom = (u16)odm_get_bb_reg(dm, reg2, MASKLWORD); - PHYDM_DBG(dm, DBG_ENV_MNTR, "Reg[0x%x] fahm_denmrtr = %d\n", reg_rpt_2, - denominator); + if (ccx->fahm_period >= 65530) + PHYDM_DBG(dm, DBG_ENV_MNTR, + "FAHM denominator = %d, valid: %d percent\n", denom, + (denom * 100) >> 16); - /*@Get FAHM nemerator*/ + /*Get FAHM numerator and sum all fahm_result*/ for (i = 0; i < 6; i++) { - reg_tmp = odm_get_bb_reg(dm, reg_rpt + (i << 2), MASKDWORD); - - PHYDM_DBG(dm, DBG_ENV_MNTR, "Reg[0x%x] fahm_denmrtr = %d\n", - reg_rpt + (i * 4), reg_tmp); - - fahm_cnt[i * 2] = (u16)(reg_tmp & MASKLWORD); - fahm_cnt[i * 2 + 1] = (u16)((reg_tmp & MASKHWORD) >> 16); + value32 = odm_get_bb_reg(dm, reg1 + (i << 2), MASKDWORD); + ccx->fahm_result[i * 2] = (u16)(value32 & MASKLWORD); + ccx->fahm_result[i * 2 + 1] = (u16)((value32 & MASKHWORD) >> 16); + fahm_rpt_sum_tmp = (u32)(fahm_rpt_sum_tmp + + ccx->fahm_result[i * 2] + + ccx->fahm_result[i * 2 + 1]); } - for (i = 0; i < 12; i++) - fahm_rpt[i] = phydm_hw_divider(dm, fahm_cnt[i], denominator); + ccx->fahm_rpt_sum = (u16)fahm_rpt_sum_tmp; PHYDM_DBG(dm, DBG_ENV_MNTR, - "FAHM_RPT_cnt[10:0]=[%d, %d, %d, %d, %d(IGI), %d, %d, %d, %d, %d, %d, %d]\n", - fahm_cnt[11], fahm_cnt[10], fahm_cnt[9], - fahm_cnt[8], fahm_cnt[7], fahm_cnt[6], - fahm_cnt[5], fahm_cnt[4], fahm_cnt[3], - fahm_cnt[2], fahm_cnt[1], fahm_cnt[0]); + "FAHM_Rpt[%d](H->L)[%d %d %d %d %d %d %d %d %d %d %d %d]\n", + ccx->fahm_rpt_stamp, ccx->fahm_result[11], + ccx->fahm_result[10], ccx->fahm_result[9], + ccx->fahm_result[8], ccx->fahm_result[7], ccx->fahm_result[6], + ccx->fahm_result[5], ccx->fahm_result[4], ccx->fahm_result[3], + ccx->fahm_result[2], ccx->fahm_result[1], + ccx->fahm_result[0]); - PHYDM_DBG(dm, DBG_ENV_MNTR, - "FAHM_RPT[10:0]=[%d, %d, %d, %d, %d(IGI), %d, %d, %d, %d, %d, %d, %d]\n", - fahm_rpt[11], fahm_rpt[10], fahm_rpt[9], fahm_rpt[8], - fahm_rpt[7], fahm_rpt[6], fahm_rpt[5], fahm_rpt[4], - fahm_rpt[3], fahm_rpt[2], fahm_rpt[1], fahm_rpt[0]); + phydm_fahm_racing_release(dm); + + if (fahm_rpt_sum_tmp > 0xffff) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[Warning] Invalid FAHM RPT, total=%d\n", + fahm_rpt_sum_tmp); + return false; + } + + return true; } -void phydm_fahm_set_th_by_igi(void *dm_void, u8 igi) +void phydm_fahm_set_th_reg(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; - struct ccx_info *ccx_info = &dm->dm_ccx_info; + struct ccx_info *ccx = &dm->dm_ccx_info; u32 val = 0; - u8 f_th[11]; /*@FAHM Threshold*/ - u8 rssi_th[11]; /*@in RSSI scale*/ - u8 th_gap = 2 * IGI_TO_NHM_TH_MULTIPLIER; /*unit is 0.5dB for FAHM*/ - u8 i; + + /*Set FAHM threshold*/ /*Unit: PWdB U(8,1)*/ + switch (dm->ic_ip_series) { + case PHYDM_IC_JGR3: + val = BYTE_2_DWORD(ccx->fahm_th[3], ccx->fahm_th[2], + ccx->fahm_th[1], ccx->fahm_th[0]); + odm_set_bb_reg(dm, R_0x1e50, MASKDWORD, val); + val = BYTE_2_DWORD(ccx->fahm_th[7], ccx->fahm_th[6], + ccx->fahm_th[5], ccx->fahm_th[4]); + odm_set_bb_reg(dm, R_0x1e54, MASKDWORD, val); + val = BYTE_2_DWORD(0, ccx->fahm_th[10], ccx->fahm_th[9], + ccx->fahm_th[8]); + odm_set_bb_reg(dm, R_0x1e58, 0xffffff, val); + break; + case PHYDM_IC_AC: + val = BYTE_2_DWORD(0, ccx->fahm_th[2], ccx->fahm_th[1], + ccx->fahm_th[0]); + odm_set_bb_reg(dm, R_0x1c38, 0xffffff00, val); + val = BYTE_2_DWORD(0, ccx->fahm_th[5], ccx->fahm_th[4], + ccx->fahm_th[3]); + odm_set_bb_reg(dm, R_0x1c78, 0xffffff00, val); + val = BYTE_2_DWORD(0, 0, ccx->fahm_th[7], ccx->fahm_th[6]); + odm_set_bb_reg(dm, R_0x1c7c, 0xffff0000, val); + val = BYTE_2_DWORD(0, ccx->fahm_th[10], ccx->fahm_th[9], + ccx->fahm_th[8]); + odm_set_bb_reg(dm, R_0x1cb8, 0xffffff00, val); + break; + case PHYDM_IC_N: + val = BYTE_2_DWORD(ccx->fahm_th[3], ccx->fahm_th[2], + ccx->fahm_th[1], ccx->fahm_th[0]); + odm_set_bb_reg(dm, R_0x970, MASKDWORD, val); + val = BYTE_2_DWORD(ccx->fahm_th[7], ccx->fahm_th[6], + ccx->fahm_th[5], ccx->fahm_th[4]); + odm_set_bb_reg(dm, R_0x974, MASKDWORD, val); + val = BYTE_2_DWORD(0, ccx->fahm_th[10], ccx->fahm_th[9], + ccx->fahm_th[8]); + odm_set_bb_reg(dm, R_0x978, 0xffffff, val); + break; + default: + break; + } + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Update FAHM_th[H->L]=[%d %d %d %d %d %d %d %d %d %d %d]\n", + ccx->fahm_th[10], ccx->fahm_th[9], ccx->fahm_th[8], + ccx->fahm_th[7], ccx->fahm_th[6], ccx->fahm_th[5], + ccx->fahm_th[4], ccx->fahm_th[3], ccx->fahm_th[2], + ccx->fahm_th[1], ccx->fahm_th[0]); +} + +boolean +phydm_fahm_th_update_chk(void *dm_void, enum fahm_application fahm_app, + u8 *fahm_th, u32 *igi_new, boolean en_1db_mode, + u8 fahm_th0_manual) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + boolean is_update = false; + u8 igi_curr = phydm_get_igi(dm, BB_PATH_A); + u8 i = 0; + u8 th_tmp = igi_curr - CCA_CAP; + u8 th_step = 2; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "fahm_th_update_chk : App=%d, fahm_igi=0x%x, igi_curr=0x%x\n", + fahm_app, ccx->fahm_igi, igi_curr); + + if (igi_curr < 0x10) /* Protect for invalid IGI*/ + return false; + + switch (fahm_app) { + case FAHM_BACKGROUND: /*Get IGI from driver parameter(cur_ig_value)*/ + if (ccx->fahm_igi != igi_curr || ccx->fahm_app != fahm_app) { + is_update = true; + *igi_new = (u32)igi_curr; + + fahm_th[0] = (u8)IGI_2_NHM_TH(th_tmp); + + for (i = 1; i <= 10; i++) + fahm_th[i] = fahm_th[0] + + IGI_2_NHM_TH(th_step * i); + + } + break; + case FAHM_ACS: + if (ccx->fahm_igi != igi_curr || ccx->fahm_app != fahm_app) { + is_update = true; + *igi_new = (u32)igi_curr; + fahm_th[0] = (u8)IGI_2_NHM_TH(igi_curr - CCA_CAP); + for (i = 1; i <= 10; i++) + fahm_th[i] = fahm_th[0] + IGI_2_NHM_TH(2 * i); + } + break; + case FAHM_DBG: /*Get IGI from register*/ + igi_curr = phydm_get_igi(dm, BB_PATH_A); + if (ccx->fahm_igi != igi_curr || ccx->fahm_app != fahm_app) { + is_update = true; + *igi_new = (u32)igi_curr; + if (en_1db_mode) { + fahm_th[0] = (u8)IGI_2_NHM_TH(fahm_th0_manual + + 10); + th_step = 1; + } else { + fahm_th[0] = (u8)IGI_2_NHM_TH(igi_curr - + CCA_CAP); + } + + for (i = 1; i <= 10; i++) + fahm_th[i] = fahm_th[0] + + IGI_2_NHM_TH(th_step * i); + } + break; + } + + if (is_update) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "[Update FAHM_TH] igi_RSSI=%d\n", + IGI_2_RSSI(*igi_new)); + + for (i = 0; i < NHM_TH_NUM; i++) + PHYDM_DBG(dm, DBG_ENV_MNTR, "FAHM_th[%d](RSSI) = %d\n", + i, NTH_TH_2_RSSI(fahm_th[i])); + } else { + PHYDM_DBG(dm, DBG_ENV_MNTR, "No need to update FAHM_TH\n"); + } + return is_update; +} + +void phydm_fahm_set(void *dm_void, enum fahm_opt_fa inclu_fa, + enum fahm_opt_crc32_ok inclu_crc32_ok, + enum fahm_opt_crc32_err inclu_crc32_err, + enum fahm_application app, u16 period, boolean en_1db_mode, + u8 th0_manual) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 fahm_th[NHM_TH_NUM] = {0}; + u32 igi = 0x20; + u32 reg1 = 0, reg2 = 0, reg3 = 0; + u32 val_tmp = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "incld{fa, crc32_ok, crc32_err}={%d, %d, %d}, period=%d\n", + inclu_fa, inclu_crc32_ok, inclu_crc32_err, period); + + switch (dm->ic_ip_series) { + case PHYDM_IC_JGR3: + reg1 = R_0x1e60; + reg2 = R_0x1e58; + reg3 = R_0x1e5c; + break; + case PHYDM_IC_AC: + reg1 = R_0x994; + reg2 = R_0x1cf8; + break; + case PHYDM_IC_N: + reg1 = R_0x890; + reg2 = R_0x978; + reg3 = R_0x97c; + break; + default: + break; + } + + /*Set enable fa, ignore crc32 ok, ignore crc32 err*/ + if (inclu_fa != ccx->fahm_incld_fa || + inclu_crc32_ok != ccx->fahm_incld_crc32_ok || + inclu_crc32_err != ccx->fahm_incld_crc32_err) { + val_tmp = (u32)((inclu_crc32_err << 2) | (inclu_crc32_ok << 1) | + inclu_fa); + odm_set_bb_reg(dm, reg1, 0xe0, val_tmp); + ccx->fahm_incld_fa = inclu_fa; + ccx->fahm_incld_crc32_ok = inclu_crc32_ok; + ccx->fahm_incld_crc32_err = inclu_crc32_err; + } + + /*Set FAHM period*/ + if (period != ccx->fahm_period) { + switch (dm->ic_ip_series) { + case PHYDM_IC_AC: + odm_set_bb_reg(dm, reg2, 0xffff00, period); + break; + case PHYDM_IC_JGR3: + case PHYDM_IC_N: + odm_set_bb_reg(dm, reg2, 0xff000000, (period & 0xff)); + odm_set_bb_reg(dm, reg3, 0xff, (period & 0xff00) >> 8); + break; + default: + break; + } + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Update FAHM period ((%d)) -> ((%d))\n", + ccx->fahm_period, period); + + ccx->fahm_period = period; + } + + /*Set FAHM threshold*/ + if (phydm_fahm_th_update_chk(dm, app, &fahm_th[0], &igi, en_1db_mode, + th0_manual)) { + /*Pause IGI*/ + if (app == FAHM_BACKGROUND || app == FAHM_ACS) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "DIG Free Run\n"); + } else if (phydm_pause_func(dm, F00_DIG, PHYDM_PAUSE, + PHYDM_PAUSE_LEVEL_1, 1, &igi) + == PAUSE_FAIL) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "pause DIG Fail\n"); + return; + } else { + PHYDM_DBG(dm, DBG_ENV_MNTR, "pause DIG=0x%x\n", igi); + } + ccx->fahm_app = app; + ccx->fahm_igi = (u8)igi; + odm_move_memory(dm, &ccx->fahm_th[0], &fahm_th, NHM_TH_NUM); + + /*Set FAHM th*/ + phydm_fahm_set_th_reg(dm); + } +} + +boolean +phydm_fahm_mntr_set(void *dm_void, struct fahm_para_info *para) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u16 fahm_time = 0; /*unit: 4us*/ PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); - if (ccx_info->env_mntr_igi == igi) { - PHYDM_DBG(dm, DBG_ENV_MNTR, - "No need to update FAHM_th, IGI=0x%x\n", - ccx_info->env_mntr_igi); - return; + if (para->mntr_time == 0) + return false; + + if (para->lv >= FAHM_MAX_NUM) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "Wrong LV=%d\n", para->lv); + return false; } - ccx_info->env_mntr_igi = igi; /*@bkp IGI*/ + if (phydm_fahm_racing_ctrl(dm, para->lv) == PHYDM_SET_FAIL) + return false; - if (igi >= CCA_CAP) - f_th[0] = (igi - CCA_CAP) * IGI_TO_NHM_TH_MULTIPLIER; + if (para->mntr_time >= 262) + fahm_time = NHM_PERIOD_MAX; else - f_th[0] = 0; + fahm_time = para->mntr_time * MS_TO_4US_RATIO; - rssi_th[0] = igi - 10 - CCA_CAP; + phydm_fahm_set(dm, para->incld_fa, para->incld_crc32_ok, + para->incld_crc32_err, para->app, fahm_time, + para->en_1db_mode, para->th0_manual); - for (i = 1; i <= 10; i++) { - f_th[i] = f_th[0] + th_gap * i; - rssi_th[i] = rssi_th[0] + (i << 1); + return true; +} + +boolean +phydm_fahm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + struct fahm_para_info para = {0}; + boolean fahm_chk_result = false; + boolean fahm_polling_result = false; + u32 sys_return_time = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + if (ccx->fahm_manual_ctrl) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "FAHM in manual ctrl\n"); + return fahm_chk_result; + } + sys_return_time = ccx->fahm_trigger_time + MAX_ENV_MNTR_TIME; + if (ccx->fahm_app != FAHM_BACKGROUND && + (sys_return_time > dm->phydm_sys_up_time)) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "fahm_app=%d, trigger_time %d, sys_time=%d\n", + ccx->fahm_app, ccx->fahm_trigger_time, + dm->phydm_sys_up_time); + + return fahm_chk_result; } - PHYDM_DBG(dm, DBG_ENV_MNTR, - "FAHM_RSSI_th[10:0]=[%d, %d, %d, (IGI)%d, %d, %d, %d, %d, %d, %d, %d]\n", - rssi_th[10], rssi_th[9], rssi_th[8], rssi_th[7], rssi_th[6], - rssi_th[5], rssi_th[4], rssi_th[3], rssi_th[2], rssi_th[1], - rssi_th[0]); - - if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - val = BYTE_2_DWORD(0, f_th[2], f_th[1], f_th[0]); - odm_set_bb_reg(dm, R_0x1c38, 0xffffff00, val); - val = BYTE_2_DWORD(0, f_th[5], f_th[4], f_th[3]); - odm_set_bb_reg(dm, R_0x1c78, 0xffffff00, val); - val = BYTE_2_DWORD(0, 0, f_th[7], f_th[6]); - odm_set_bb_reg(dm, R_0x1c7c, 0xffff0000, val); - val = BYTE_2_DWORD(0, f_th[10], f_th[9], f_th[8]); - odm_set_bb_reg(dm, R_0x1cb8, 0xffffff00, val); - } else { - val = BYTE_2_DWORD(f_th[3], f_th[2], f_th[1], f_th[0]); - odm_set_bb_reg(dm, R_0x970, MASKDWORD, val); - val = BYTE_2_DWORD(f_th[7], f_th[6], f_th[5], f_th[4]); - odm_set_bb_reg(dm, R_0x974, MASKDWORD, val); - val = BYTE_2_DWORD(0, f_th[10], f_th[9], f_th[8]); - odm_set_bb_reg(dm, R_0x978, 0xffffff, val); + /*[FAHM get result & calculate Utility]---------------------------*/ + fahm_polling_result = phydm_fahm_get_result(dm); + if (fahm_polling_result) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "Get FAHM_rpt success\n"); + phydm_fahm_get_utility(dm); } + + /*[FAHM trigger setting]------------------------------------------*/ + para.incld_fa = FAHM_INCLUDE_FA; + para.incld_crc32_ok = FAHM_EXCLUDE_CRC32_OK; + para.incld_crc32_err = FAHM_EXCLUDE_CRC32_ERR; + para.app = FAHM_BACKGROUND; + para.lv = FAHM_LV_1; + para.en_1db_mode = false; + para.mntr_time = monitor_time; + + fahm_chk_result = phydm_fahm_mntr_set(dm, ¶); + + return fahm_chk_result; } void phydm_fahm_init(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; - struct ccx_info *ccx_info = &dm->dm_ccx_info; - u32 fahm_reg1; - u8 denumerator_sel = 0; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 denum_sel = 0; + u32 reg = 0; + + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM)) + return; PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); - PHYDM_DBG(dm, DBG_ENV_MNTR, "IGI=0x%x\n", - dm->dm_dig_table.cur_ig_value); - if (dm->support_ic_type & ODM_IC_11AC_SERIES) - fahm_reg1 = 0x994; - else - fahm_reg1 = 0x890; + ccx->fahm_app = FAHM_BACKGROUND; + ccx->fahm_igi = 0xff; - ccx_info->fahm_period = 65535; + /*Set FAHM threshold*/ + ccx->fahm_ongoing = false; + ccx->fahm_set_lv = FAHM_RELEASE; - odm_set_bb_reg(dm, fahm_reg1, 0x6, 3); /*@FAHM HW block enable*/ + if (phydm_fahm_th_update_chk(dm, ccx->fahm_app, &ccx->fahm_th[0], + (u32 *)&ccx->fahm_igi, false, 0)) + phydm_fahm_set_th_reg(dm); - denumerator_sel = FAHM_INCLD_FA | FAHM_INCLD_CRC_OK | FAHM_INCLD_CRC_ER; - phydm_fahm_set_valid_cnt(dm, FAHM_INCLD_FA, denumerator_sel); - phydm_fahm_set_th_by_igi(dm, dm->dm_dig_table.cur_ig_value); + ccx->fahm_period = 0; + + ccx->fahm_incld_fa = FAHM_FA_INIT; + ccx->fahm_incld_crc32_ok = FAHM_CRC32_OK_INIT; + ccx->fahm_incld_crc32_err = FAHM_CRC32_ERR_INIT; + + ccx->fahm_manual_ctrl = 0; + ccx->fahm_rpt_stamp = 0; + + switch (dm->ic_ip_series) { + case PHYDM_IC_JGR3: + reg = R_0x1e60; + break; + case PHYDM_IC_AC: + reg = R_0x994; + break; + case PHYDM_IC_N: + reg = R_0x890; + break; + default: + break; + } + + /*enable CCK/OFDM CRC32 check*/ + odm_set_bb_reg(dm, reg, 0x18, 0x3); + /*denominator:FA/CRC32_OK/CRC32_ERR*/ + odm_set_bb_reg(dm, reg, 0x7000, 0x7); } void phydm_fahm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len) { struct dm_struct *dm = (struct dm_struct *)dm_void; - struct ccx_info *ccx_info = &dm->dm_ccx_info; + struct ccx_info *ccx = &dm->dm_ccx_info; + struct fahm_para_info para = {0}; char help[] = "-h"; u32 var1[10] = {0}; u32 used = *_used; u32 out_len = *_out_len; - u32 i; + u16 result_tmp = 0; + u8 i = 0; - for (i = 0; i < 2; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); - } + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM)) + return; + + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); if ((strcmp(input[1], help) == 0)) { PDM_SNPF(out_len, used, output + used, out_len - used, - "{1: trigger, 2:get result}\n"); - PDM_SNPF(out_len, used, output + used, out_len - used, - "{3: MNTR mode sel} {1: driver, 2. FW}\n"); - return; - } else if (var1[0] == 1) { /* Set & trigger CLM */ + "FAHM Basic-Trigger 262ms: {1}\n"); - phydm_fahm_set_th_by_igi(dm, dm->dm_dig_table.cur_ig_value); - phydm_fahm_trigger(dm, ccx_info->fahm_period); PDM_SNPF(out_len, used, output + used, out_len - used, - "Monitor FAHM for %d * 4us\n", ccx_info->fahm_period); + "FAHM Adv-Trigger: {2} {Include FA} {Include CRC32 ok} {Include CRC32 Err}\n {App:1 for dbg} {LV:1~4} {0~262ms}, 1dB mode :{en} {t[0](RSSI)}\n"); - } else if (var1[0] == 2) { /* @Get CLM results */ - - phydm_fahm_get_result(dm); PDM_SNPF(out_len, used, output + used, out_len - used, - "FAHM_result=%d us\n", (ccx_info->clm_result << 2)); - - } else { + "FAHM Get Result: {100}\n"); + } else if (var1[0] == 100) { /*Get FAHM results*/ PDM_SNPF(out_len, used, output + used, out_len - used, - "Error\n"); + "IGI=0x%x, rpt_stamp=%d\n", ccx->fahm_igi, + ccx->fahm_rpt_stamp); + + if (phydm_fahm_get_result(dm)) { + for (i = 0; i < NHM_RPT_NUM; i++) { + result_tmp = ccx->fahm_result[i]; + PDM_SNPF(out_len, used, output + used, + out_len - used, + "fahm_rpt[%d] = %d (%d percent)\n", + i, result_tmp, + (((result_tmp * 100) + 32768) >> 16)); + } + phydm_fahm_get_utility(dm); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "fahm_pwr=%d\n", ccx->fahm_pwr); + } else { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Get FAHM_rpt Fail\n"); + } + ccx->fahm_manual_ctrl = 0; + } else { /*FAMH trigger*/ + ccx->fahm_manual_ctrl = 1; + + for (i = 1; i < 9; i++) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + + if (var1[0] == 1) { + para.incld_fa = FAHM_INCLUDE_FA; + para.incld_crc32_ok = FAHM_EXCLUDE_CRC32_OK; + para.incld_crc32_err = FAHM_EXCLUDE_CRC32_ERR; + para.app = FAHM_DBG; + para.lv = FAHM_LV_4; + para.mntr_time = 262; + para.en_1db_mode = false; + para.th0_manual = 0; + } else { + para.incld_fa = (enum fahm_opt_fa)var1[1]; + para.incld_crc32_ok = (enum fahm_opt_crc32_ok)var1[2]; + para.incld_crc32_err = (enum fahm_opt_crc32_err)var1[3]; + para.app = (enum fahm_application)var1[4]; + para.lv = (enum phydm_fahm_level)var1[5]; + para.mntr_time = (u16)var1[6]; + para.en_1db_mode = (boolean)var1[7]; + para.th0_manual = (u8)var1[8]; + } + + PDM_SNPF(out_len, used, output + used, out_len - used, + "fa=%d, crc32_ok=%d, crc32_err=%d, app=%d, lv=%d, time=%d ms\n", + para.incld_fa, para.incld_crc32_ok, + para.incld_crc32_err, para.app, para.lv, + para.mntr_time); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "en_1db_mode=%d, th0(for 1db mode)=%d\n", + para.en_1db_mode, para.th0_manual); + + if (phydm_fahm_mntr_set(dm, ¶)) + phydm_fahm_trigger(dm); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "IGI=0x%x, rpt_stamp=%d\n", ccx->fahm_igi, + ccx->fahm_rpt_stamp); + + for (i = 0; i < NHM_TH_NUM; i++) + PDM_SNPF(out_len, used, output + used, out_len - used, + "FAHM_th[%d] RSSI = %d\n", i, + NTH_TH_2_RSSI(ccx->fahm_th[i])); } *_used = used; *_out_len = out_len; } -#endif /*@#ifdef FAHM_SUPPORT*/ +void phydm_fahm_watchdog(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + boolean fahm_chk_ok = false; + + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM)) + return; + + fahm_chk_ok = phydm_fahm_mntr_chk(dm, 262); + + if (fahm_chk_ok) + phydm_fahm_trigger(dm); +} + + +#endif /*#ifdef FAHM_SUPPORT*/ #ifdef NHM_SUPPORT @@ -429,7 +873,23 @@ phydm_nhm_check_rdy(void *dm_void) return is_ready; } -u8 phydm_nhm_cal_noise(void *dm_void, u8 start_i, u8 end_i, u8 n_sum) +void phydm_nhm_cal_wgt(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 i = 0; + + for (i = 0; i < NHM_RPT_NUM; i++) { + if (i == 0) + ccx->nhm_wgt[0] = (u8)(MAX_2(ccx->nhm_th[0] - 2, 0)); + else if (i == (NHM_RPT_NUM - 1)) + ccx->nhm_wgt[NHM_RPT_NUM - 1] = (u8)(ccx->nhm_th[NHM_TH_NUM - 1] + 2); + else + ccx->nhm_wgt[i] = (u8)((ccx->nhm_th[i - 1] + ccx->nhm_th[i]) >> 1); + } +} + +u8 phydm_nhm_cal_wgt_avg(void *dm_void, u8 start_i, u8 end_i, u8 n_sum) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; @@ -438,8 +898,6 @@ u8 phydm_nhm_cal_noise(void *dm_void, u8 start_i, u8 end_i, u8 n_sum) u8 noise = 0; u32 nhm_valid = 0; - PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); - if (n_sum == 0) { PHYDM_DBG(dm, DBG_ENV_MNTR, "n_sum = 0, don't need to update noise\n"); @@ -450,48 +908,86 @@ u8 phydm_nhm_cal_noise(void *dm_void, u8 start_i, u8 end_i, u8 n_sum) return 0x0; } - for (i = start_i; i <= end_i; i++) { - if (i == 0) - noise_tmp += ccx->nhm_result[0] * - MAX_2(ccx->nhm_th[0] - 2, 0); - else if (i == (NHM_RPT_NUM - 1)) - noise_tmp += ccx->nhm_result[NHM_RPT_NUM - 1] * - (ccx->nhm_th[NHM_TH_NUM - 1] + 2); - else - noise_tmp += ccx->nhm_result[i] * - (ccx->nhm_th[i - 1] + ccx->nhm_th[i]) >> 1; - } + for (i = start_i; i <= end_i; i++) + noise_tmp += ccx->nhm_result[i] * ccx->nhm_wgt[i]; /* protection for the case of minus noise(RSSI)*/ noise = (u8)(NTH_TH_2_RSSI(MAX_2(PHYDM_DIV(noise_tmp, n_sum), 20))); nhm_valid = (n_sum * 100) >> 8; PHYDM_DBG(dm, DBG_ENV_MNTR, - "valid: ((%d)) percent, noise(RSSI)=((%d))\n", + "cal wgt_avg : valid: ((%d)) percent, noise(RSSI)=((%d))\n", nhm_valid, noise); return noise; } +u8 phydm_nhm_cal_nhm_env(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 first_idx = 0; + u8 nhm_env = 0; + u8 i = 0; + + nhm_env = ccx->nhm_rpt_sum; + + /*search first cluster*/ + for (i = 0; i < NHM_RPT_NUM; i++) { + if (ccx->nhm_result[i]) { + first_idx = i; + break; + } + } + + /*exclude first cluster under -80dBm*/ + for (i = 0; i < 4; i++) { + if (((first_idx + i) < NHM_RPT_NUM) && + (ccx->nhm_wgt[first_idx + i] <= NHM_IC_NOISE_TH)) + nhm_env -= ccx->nhm_result[first_idx + i]; + } + + /*exclude nhm_rpt[0] above -80dBm*/ + if (ccx->nhm_wgt[0] > NHM_IC_NOISE_TH) + nhm_env -= ccx->nhm_result[0]; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "cal nhm_env: first_idx=%d, nhm_env=%d\n", + first_idx, nhm_env); + + return nhm_env; +} + void phydm_nhm_get_utility(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; u8 nhm_rpt_non_0 = 0; u8 nhm_rpt_non_11 = 0; + u8 nhm_env = 0; if (ccx->nhm_rpt_sum >= ccx->nhm_result[0]) { + phydm_nhm_cal_wgt(dm); + nhm_rpt_non_0 = ccx->nhm_rpt_sum - ccx->nhm_result[0]; nhm_rpt_non_11 = ccx->nhm_rpt_sum - ccx->nhm_result[11]; + /*exclude nhm_r[0] above -80dBm or first cluster under -80dBm*/ + nhm_env = phydm_nhm_cal_nhm_env(dm); ccx->nhm_ratio = (nhm_rpt_non_0 * 100) >> 8; + ccx->nhm_env_ratio = (nhm_env * 100) >> 8; ccx->nhm_level_valid = (nhm_rpt_non_11 * 100) >> 8; - ccx->nhm_level = phydm_nhm_cal_noise(dm, 0, NHM_RPT_NUM - 2, + ccx->nhm_level = phydm_nhm_cal_wgt_avg(dm, 0, NHM_RPT_NUM - 2, nhm_rpt_non_11); + ccx->nhm_pwr = phydm_nhm_cal_wgt_avg(dm, 0, NHM_RPT_NUM - 1, + ccx->nhm_rpt_sum); } else { PHYDM_DBG(dm, DBG_ENV_MNTR, "[warning] nhm_rpt_sum invalid\n"); ccx->nhm_ratio = 0; + ccx->nhm_env_ratio = 0; } - PHYDM_DBG(dm, DBG_ENV_MNTR, "nhm_ratio=%d\n", ccx->nhm_ratio); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "nhm_ratio=%d, nhm_env_ratio=%d, nhm_level=%d, nhm_pwr=%d\n", + ccx->nhm_ratio, ccx->nhm_env_ratio, ccx->nhm_level, + ccx->nhm_pwr); } boolean @@ -503,6 +999,7 @@ phydm_nhm_get_result(void *dm_void) u8 i = 0; u32 nhm_reg1 = 0; u16 nhm_rpt_sum_tmp = 0; + u16 nhm_duration = 0; if (dm->support_ic_type & ODM_IC_11AC_SERIES) nhm_reg1 = R_0x994; @@ -515,7 +1012,7 @@ phydm_nhm_get_result(void *dm_void) PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); if (!(dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F | - ODM_RTL8197G))) + ODM_RTL8197G | ODM_RTL8723F))) pdm_set_reg(dm, nhm_reg1, BIT(1), 0); if (!(phydm_nhm_check_rdy(dm))) { @@ -536,7 +1033,7 @@ phydm_nhm_get_result(void *dm_void) /*@Get NHM duration*/ value32 = odm_read_4byte(dm, R_0xfb4); - ccx->nhm_duration = (u16)(value32 & MASKLWORD); + nhm_duration = (u16)(value32 & MASKLWORD); #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT } else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { value32 = odm_read_4byte(dm, R_0x2d40); @@ -550,7 +1047,7 @@ phydm_nhm_get_result(void *dm_void) /*@Get NHM duration*/ value32 = odm_read_4byte(dm, R_0x2d4c); - ccx->nhm_duration = (u16)(value32 & MASKLWORD); + nhm_duration = (u16)(value32 & MASKLWORD); #endif } else { value32 = odm_read_4byte(dm, R_0x8d8); @@ -568,19 +1065,17 @@ phydm_nhm_get_result(void *dm_void) ccx->nhm_result[11] = (u8)((value32 & MASKBYTE3) >> 24); /*@Get NHM duration*/ - ccx->nhm_duration = (u16)(value32 & MASKLWORD); + nhm_duration = (u16)(value32 & MASKLWORD); } /* sum all nhm_result */ - if (ccx->nhm_period >= 65530) { - value32 = (ccx->nhm_duration * 100) >> 16; + if (ccx->nhm_period >= 65530) PHYDM_DBG(dm, DBG_ENV_MNTR, "NHM valid time = %d, valid: %d percent\n", - ccx->nhm_duration, value32); - } + nhm_duration, (nhm_duration * 100) >> 16); for (i = 0; i < NHM_RPT_NUM; i++) - nhm_rpt_sum_tmp += (u16)ccx->nhm_result[i]; + nhm_rpt_sum_tmp = (u16)(nhm_rpt_sum_tmp + ccx->nhm_result[i]); ccx->nhm_rpt_sum = (u8)nhm_rpt_sum_tmp; @@ -854,7 +1349,8 @@ void phydm_nhm_set(void *dm_void, enum nhm_option_txon_all include_tx, } } -u8 phydm_nhm_mntr_set(void *dm_void, struct nhm_para_info *nhm_para) +boolean +phydm_nhm_mntr_set(void *dm_void, struct nhm_para_info *nhm_para) { struct dm_struct *dm = (struct dm_struct *)dm_void; u16 nhm_time = 0; /*unit: 4us*/ @@ -862,15 +1358,15 @@ u8 phydm_nhm_mntr_set(void *dm_void, struct nhm_para_info *nhm_para) PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); if (nhm_para->mntr_time == 0) - return PHYDM_SET_FAIL; + return false; if (nhm_para->nhm_lv >= NHM_MAX_NUM) { PHYDM_DBG(dm, DBG_ENV_MNTR, "Wrong LV=%d\n", nhm_para->nhm_lv); - return PHYDM_SET_FAIL; + return false; } if (phydm_nhm_racing_ctrl(dm, nhm_para->nhm_lv) == PHYDM_SET_FAIL) - return PHYDM_SET_FAIL; + return false; if (nhm_para->mntr_time >= 262) nhm_time = NHM_PERIOD_MAX; @@ -881,7 +1377,7 @@ u8 phydm_nhm_mntr_set(void *dm_void, struct nhm_para_info *nhm_para) nhm_para->div_opt, nhm_para->nhm_app, nhm_time, nhm_para->en_1db_mode, nhm_para->nhm_th0_manual); - return PHYDM_SET_SUCCESS; + return true; } #ifdef NHM_DYM_PW_TH_SUPPORT @@ -969,7 +1465,7 @@ phydm_nhm_dym_pw_th(void *dm_void) if (n_sum >= ccx->nhm_sl_pw_th) { PHYDM_DBG(dm, DBG_ENV_MNTR, "Do sl[%d:%d]\n", i, i + 3); chk_succ = true; - noise = phydm_nhm_cal_noise(dm, i, i + 3, n_sum); + noise = phydm_nhm_cal_wgt_avg(dm, i, i + 3, n_sum); break; } } @@ -987,24 +1483,25 @@ phydm_nhm_dym_pw_th_en(void *dm_void) struct ccx_info *ccx = &dm->dm_ccx_info; struct phydm_iot_center *iot_table = &dm->iot_table; - if (!ccx->dym_pwth_manual_ctrl) - ccx->nhm_dym_pw_th_en = false; - if (!(dm->support_ic_type & ODM_RTL8822C)) - ccx->nhm_dym_pw_th_en = false; + return false; + + if (ccx->dym_pwth_manual_ctrl) + return true; if (dm->iot_table.phydm_patch_id == 0x100f0401 || iot_table->patch_id_100f0401) { - ccx->nhm_dym_pw_th_en = true; + return true; } else if (ccx->nhm_dym_pw_th_en) { phydm_nhm_restore_pw_th(dm); - ccx->nhm_dym_pw_th_en = false; + return false; + } else { + return false; } - return ccx->nhm_dym_pw_th_en; } #endif -/*@Environment Monitor*/ +/*Environment Monitor*/ boolean phydm_nhm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/) { @@ -1040,7 +1537,8 @@ phydm_nhm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/) } #ifdef NHM_DYM_PW_TH_SUPPORT - if (phydm_nhm_dym_pw_th_en(dm)) { + ccx->nhm_dym_pw_th_en = phydm_nhm_dym_pw_th_en(dm); + if (ccx->nhm_dym_pw_th_en) { if (nhm_polling_result) phydm_nhm_dym_pw_th(dm); else @@ -1048,12 +1546,13 @@ phydm_nhm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/) } #endif - /*@[NHM trigger setting]------------------------------------------*/ + /*[NHM trigger setting]------------------------------------------*/ nhm_para.incld_txon = NHM_EXCLUDE_TXON; nhm_para.incld_cca = NHM_EXCLUDE_CCA; nhm_para.div_opt = NHM_CNT_ALL; nhm_para.nhm_app = NHM_BACKGROUND; nhm_para.nhm_lv = NHM_LV_1; + nhm_para.en_1db_mode = false; nhm_para.mntr_time = monitor_time; #ifdef NHM_DYM_PW_TH_SUPPORT @@ -1115,7 +1614,7 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, { struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; - struct nhm_para_info nhm_para; + struct nhm_para_info nhm_para = {0}; char help[] = "-h"; u32 var1[10] = {0}; u32 used = *_used; @@ -1130,7 +1629,7 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, "NHM Basic-Trigger 262ms: {1}\n"); PDM_SNPF(out_len, used, output + used, out_len - used, - "NHM Adv-Trigger: {2} {Include TXON} {Include CCA}\n{0:Cnt_all, 1:Cnt valid} {App} {LV:1~4} {0~262ms}, 1dB mode :{en} {t[0](RSSI)}\n"); + "NHM Adv-Trigger: {2} {Include TXON} {Include CCA}\n{0:Cnt_all, 1:Cnt valid} {App:5 for dbg} {LV:1~4} {0~262ms}, 1dB mode :{en} {t[0](RSSI)}\n"); #ifdef NHM_DYM_PW_TH_SUPPORT if (dm->support_ic_type & ODM_RTL8822C) { PDM_SNPF(out_len, used, output + used, out_len - used, @@ -1144,14 +1643,14 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, PDM_SNPF(out_len, used, output + used, out_len - used, "NHM Get Result: {100}\n"); - } else if (var1[0] == 100) { /*@Get NHM results*/ + } else if (var1[0] == 100) { /*Get NHM results*/ PDM_SNPF(out_len, used, output + used, out_len - used, "IGI=0x%x, rpt_stamp=%d\n", ccx->nhm_igi, ccx->nhm_rpt_stamp); if (phydm_nhm_get_result(dm)) { - for (i = 0; i <= 11; i++) { + for (i = 0; i < NHM_RPT_NUM; i++) { result_tmp = ccx->nhm_result[i]; PDM_SNPF(out_len, used, output + used, out_len - used, @@ -1162,8 +1661,13 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, phydm_nhm_get_utility(dm); PDM_SNPF(out_len, used, output + used, out_len - used, - "[NHM] valid: %d percent, noise(RSSI) = %d\n", + "NHM_noise: valid: %d percent, noise(RSSI) = %d\n", ccx->nhm_level_valid, ccx->nhm_level); + PDM_SNPF(out_len, used, output + used, out_len - used, + "NHM_pwr: nhm_pwr (RSSI) = %d\n", ccx->nhm_pwr); + PDM_SNPF(out_len, used, output + used, out_len - used, + "ratio: nhm_ratio=%d, nhm_env_ratio=%d\n", + ccx->nhm_ratio, ccx->nhm_env_ratio); } else { PDM_SNPF(out_len, used, output + used, out_len - used, "Get NHM_rpt Fail\n"); @@ -1173,10 +1677,8 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, } else if (var1[0] == 3) { /*NMH dym_pw_th*/ if (dm->support_ic_type & ODM_RTL8822C) { for (i = 1; i < 7; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, - &var1[i]); - } + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); } if (var1[1] == 1) { @@ -1199,14 +1701,11 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, } #endif } else { /*NMH trigger*/ - ccx->nhm_manual_ctrl = 1; for (i = 1; i < 9; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, - &var1[i]); - } + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); } if (var1[0] == 1) { @@ -1216,6 +1715,8 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, nhm_para.nhm_app = NHM_DBG; nhm_para.nhm_lv = NHM_LV_4; nhm_para.mntr_time = 262; + nhm_para.en_1db_mode = false; + nhm_para.nhm_th0_manual = 0; } else { nhm_para.incld_txon = (enum nhm_option_txon_all)var1[1]; nhm_para.incld_cca = (enum nhm_option_cca_all)var1[2]; @@ -1226,7 +1727,7 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, nhm_para.en_1db_mode = (boolean)var1[7]; nhm_para.nhm_th0_manual = (u8)var1[8]; - /* some old ic is not supported on NHM divider option */ + /*some old ic is not supported on NHM divider option */ if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8723B | ODM_RTL8195A | ODM_RTL8192E)) { nhm_para.div_opt = NHM_CNT_ALL; @@ -1240,17 +1741,17 @@ void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, nhm_para.nhm_lv, nhm_para.mntr_time); PDM_SNPF(out_len, used, output + used, out_len - used, - "en_1db_mode =%d, th0(for 1db mode)=%d\n", + "en_1db_mode=%d, th0(for 1db mode)=%d\n", nhm_para.en_1db_mode, nhm_para.nhm_th0_manual); - if (phydm_nhm_mntr_set(dm, &nhm_para) == PHYDM_SET_SUCCESS) + if (phydm_nhm_mntr_set(dm, &nhm_para)) phydm_nhm_trigger(dm); PDM_SNPF(out_len, used, output + used, out_len - used, "IGI=0x%x, rpt_stamp=%d\n", ccx->nhm_igi, ccx->nhm_rpt_stamp); - for (i = 0; i <= 10; i++) { + for (i = 0; i < NHM_TH_NUM; i++) { PDM_SNPF(out_len, used, output + used, out_len - used, "NHM_th[%d] RSSI = %d\n", i, NTH_TH_2_RSSI(ccx->nhm_th[i])); @@ -1473,7 +1974,7 @@ phydm_clm_get_result(void *dm_void) else reg1 = R_0x890; if (!(dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8812F | - ODM_RTL8197G))) + ODM_RTL8197G | ODM_RTL8723F))) odm_set_bb_reg(dm, reg1, BIT(0), 0x0); if (!(phydm_clm_check_rdy(dm))) { PHYDM_DBG(dm, DBG_ENV_MNTR, "Get CLM report Fail\n"); @@ -1530,7 +2031,8 @@ void phydm_clm_mntr_fw(void *dm_void, u16 monitor_time /*unit ms*/) phydm_clm_h2c(dm, ccx->clm_period, true); } -u8 phydm_clm_mntr_set(void *dm_void, struct clm_para_info *clm_para) +boolean +phydm_clm_mntr_set(void *dm_void, struct clm_para_info *clm_para) { /*@Driver Monitor CLM*/ struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -1538,16 +2040,16 @@ u8 phydm_clm_mntr_set(void *dm_void, struct clm_para_info *clm_para) u16 clm_period = 0; if (clm_para->mntr_time == 0) - return PHYDM_SET_FAIL; + return false; if (clm_para->clm_lv >= CLM_MAX_NUM) { PHYDM_DBG(dm, DBG_ENV_MNTR, "[WARNING] Wrong LV=%d\n", clm_para->clm_lv); - return PHYDM_SET_FAIL; + return false; } if (phydm_clm_racing_ctrl(dm, clm_para->clm_lv) == PHYDM_SET_FAIL) - return PHYDM_SET_FAIL; + return false; if (clm_para->mntr_time >= 262) clm_period = CLM_PERIOD_MAX; @@ -1557,7 +2059,7 @@ u8 phydm_clm_mntr_set(void *dm_void, struct clm_para_info *clm_para) ccx->clm_app = clm_para->clm_app; phydm_clm_setting(dm, clm_period); - return PHYDM_SET_SUCCESS; + return true; } boolean @@ -1596,7 +2098,7 @@ phydm_clm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/) } /*@[CLM trigger]----------------------------------------------*/ - if (phydm_clm_mntr_set(dm, &clm_para) == PHYDM_SET_SUCCESS) + if (phydm_clm_mntr_set(dm, &clm_para)) clm_chk_result = true; } else { phydm_clm_mntr_fw(dm, monitor_time); @@ -1619,7 +2121,7 @@ void phydm_set_clm_mntr_mode(void *dm_void, enum clm_monitor_mode mode) phydm_ccx_hw_restart(dm); if (mode == CLM_DRIVER_MNTR) - phydm_clm_h2c(dm, 0, 0); + phydm_clm_h2c(dm, CLM_PERIOD_MAX, 0); } } @@ -1650,8 +2152,7 @@ void phydm_clm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, u32 i; for (i = 0; i < 4; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); } if ((strcmp(input[1], help) == 0)) { @@ -1703,7 +2204,7 @@ void phydm_clm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, ((ccx->clm_mntr_mode == CLM_FW_MNTR) ? "FW" : "driver"), clm_para.mntr_time); - if (phydm_clm_mntr_set(dm, &clm_para) == PHYDM_SET_SUCCESS) + if (phydm_clm_mntr_set(dm, &clm_para)) phydm_clm_trigger(dm); PDM_SNPF(out_len, used, output + used, out_len - used, @@ -1720,12 +2221,12 @@ u8 phydm_env_mntr_trigger(void *dm_void, struct nhm_para_info *nhm_para, struct clm_para_info *clm_para, struct env_trig_rpt *trig_rpt) { + u8 trigger_result = 0; #if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT)) struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; boolean nhm_set_ok = false; boolean clm_set_ok = false; - u8 trigger_result = 0; PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__); @@ -1758,17 +2259,16 @@ u8 phydm_env_mntr_trigger(void *dm_void, struct nhm_para_info *nhm_para, PHYDM_DBG(dm, DBG_ENV_MNTR, "nhm_rpt_stamp=%d, clm_rpt_stamp=%d,\n\n", trig_rpt->nhm_rpt_stamp, trig_rpt->clm_rpt_stamp); - - return trigger_result; #endif + return trigger_result; } u8 phydm_env_mntr_result(void *dm_void, struct env_mntr_rpt *rpt) { + u8 env_mntr_rpt = 0; #if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT)) struct dm_struct *dm = (struct dm_struct *)dm_void; struct ccx_info *ccx = &dm->dm_ccx_info; - u8 env_mntr_rpt = 0; u64 progressing_time = 0; u32 val_tmp = 0; @@ -1782,13 +2282,16 @@ u8 phydm_env_mntr_result(void *dm_void, struct env_mntr_rpt *rpt) PHYDM_DBG(dm, DBG_ENV_MNTR, "Get NHM_rpt success\n"); phydm_nhm_get_utility(dm); rpt->nhm_ratio = ccx->nhm_ratio; + rpt->nhm_env_ratio = ccx->nhm_env_ratio; rpt->nhm_noise_pwr = ccx->nhm_level; + rpt->nhm_pwr = ccx->nhm_pwr; env_mntr_rpt |= NHM_SUCCESS; odm_move_memory(dm, &rpt->nhm_result[0], &ccx->nhm_result[0], NHM_RPT_NUM); } else { rpt->nhm_ratio = ENV_MNTR_FAIL; + rpt->nhm_env_ratio = ENV_MNTR_FAIL; } /*@Get CLM result*/ @@ -1825,12 +2328,11 @@ u8 phydm_env_mntr_result(void *dm_void, struct env_mntr_rpt *rpt) rpt->clm_rpt_stamp = ccx->clm_rpt_stamp; PHYDM_DBG(dm, DBG_ENV_MNTR, - "IGI=0x%x, nhm_ratio=%d, clm_ratio=%d, nhm_rpt_stamp=%d, clm_rpt_stamp=%d\n\n", - ccx->nhm_igi, rpt->nhm_ratio, rpt->clm_ratio, - rpt->nhm_rpt_stamp, rpt->clm_rpt_stamp); - - return env_mntr_rpt; + "IGI=0x%x, nhm_ratio=%d, nhm_env_ratio=%d, clm_ratio=%d, nhm_rpt_stamp=%d, clm_rpt_stamp=%d\n\n", + ccx->nhm_igi, rpt->nhm_ratio, rpt->nhm_env_ratio, + rpt->clm_ratio, rpt->nhm_rpt_stamp, rpt->clm_rpt_stamp); #endif + return env_mntr_rpt; } /*@Environment Monitor*/ @@ -1861,6 +2363,10 @@ void phydm_env_mntr_watchdog(void *dm_void) PHYDM_DBG(dm, DBG_ENV_MNTR, "Summary: nhm_ratio=((%d)) clm_ratio=((%d))\n\n", ccx->nhm_ratio, ccx->clm_ratio); + + #ifdef FAHM_SUPPORT + phydm_fahm_watchdog(dm); + #endif #endif } @@ -1869,13 +2375,12 @@ void phydm_env_monitor_init(void *dm_void) #if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT)) struct dm_struct *dm = (struct dm_struct *)dm_void; - if (!(dm->support_ability & ODM_BB_ENV_MONITOR)) - return; - - PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); phydm_ccx_hw_restart(dm); phydm_nhm_init(dm); phydm_clm_init(dm); + #ifdef FAHM_SUPPORT + phydm_fahm_init(dm); + #endif #endif } @@ -1906,9 +2411,9 @@ void phydm_env_mntr_dbg(void *dm_void, char input[][16], u32 *_used, set_result = phydm_env_mntr_result(dm, &rpt); PDM_SNPF(out_len, used, output + used, out_len - used, - "Set Result=%d\n nhm_ratio=%d clm_ratio=%d\n nhm_rpt_stamp=%d, clm_rpt_stamp=%d,\n", - set_result, rpt.nhm_ratio, rpt.clm_ratio, - rpt.nhm_rpt_stamp, rpt.clm_rpt_stamp); + "Set Result=%d\n nhm_ratio=%d nhm_env_ratio=%d clm_ratio=%d\n nhm_rpt_stamp=%d, clm_rpt_stamp=%d,\n", + set_result, rpt.nhm_ratio, rpt.nhm_env_ratio, + rpt.clm_ratio, rpt.nhm_rpt_stamp, rpt.clm_rpt_stamp); for (i = 0; i <= 11; i++) { PDM_SNPF(out_len, used, output + used, out_len - used, @@ -1927,6 +2432,7 @@ void phydm_env_mntr_dbg(void *dm_void, char input[][16], u32 *_used, nhm_para.nhm_app = NHM_ACS; nhm_para.nhm_lv = NHM_LV_2; nhm_para.mntr_time = 262; + nhm_para.en_1db_mode = false; /*clm para*/ clm_para.clm_app = CLM_ACS; @@ -1946,3 +2452,840 @@ void phydm_env_mntr_dbg(void *dm_void, char input[][16], u32 *_used, *_out_len = out_len; } +#ifdef IFS_CLM_SUPPORT +void phydm_ifs_clm_restart(void *dm_void) + /*Will Restart IFS CLM simultaneously*/ +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 reg1 = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + /*restart IFS_CLM*/ + odm_set_bb_reg(dm, R_0x1ee4, BIT(29), 0x0); + odm_set_bb_reg(dm, R_0x1ee4, BIT(29), 0x1); +} + +void phydm_ifs_clm_racing_release(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + PHYDM_DBG(dm, DBG_ENV_MNTR, "ifs clm lv:(%d)->(0)\n", + ccx->ifs_clm_set_lv); + + ccx->ifs_clm_ongoing = false; + ccx->ifs_clm_set_lv = IFS_CLM_RELEASE; + ccx->ifs_clm_app = IFS_CLM_BACKGROUND; +} + +u8 phydm_ifs_clm_racing_ctrl(void *dm_void, enum phydm_ifs_clm_level ifs_clm_lv) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 set_result = PHYDM_SET_SUCCESS; + /*acquire to control IFS CLM API*/ + + PHYDM_DBG(dm, DBG_ENV_MNTR, "ifs clm_ongoing=%d, lv:(%d)->(%d)\n", + ccx->ifs_clm_ongoing, ccx->ifs_clm_set_lv, ifs_clm_lv); + if (ccx->ifs_clm_ongoing) { + if (ifs_clm_lv <= ccx->ifs_clm_set_lv) { + set_result = PHYDM_SET_FAIL; + } else { + phydm_ifs_clm_restart(dm); + ccx->ifs_clm_ongoing = false; + } + } + + if (set_result) + ccx->ifs_clm_set_lv = ifs_clm_lv; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "ifs clm racing success=%d\n", set_result); + return set_result; +} + +void phydm_ifs_clm_trigger(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + /*Trigger IFS_CLM*/ + pdm_set_reg(dm, R_0x1ee4, BIT(29), 0); + pdm_set_reg(dm, R_0x1ee4, BIT(29), 1); + ccx->ifs_clm_trigger_time = dm->phydm_sys_up_time; + ccx->ifs_clm_rpt_stamp++; + ccx->ifs_clm_ongoing = true; +} + +void phydm_ifs_clm_get_utility(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u32 numerator = 0; + u16 denominator = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + denominator = ccx->ifs_clm_period; + numerator = ccx->ifs_clm_tx * 100; + ccx->ifs_clm_tx_ratio = (u8)PHYDM_DIV(numerator, denominator); + numerator = ccx->ifs_clm_edcca_excl_cca * 100; + ccx->ifs_clm_edcca_excl_cca_ratio = (u8)PHYDM_DIV(numerator, + denominator); + numerator = (ccx->ifs_clm_cckfa + ccx->ifs_clm_ofdmfa) * 100; + ccx->ifs_clm_fa_ratio = (u8)PHYDM_DIV(numerator, denominator); + numerator = (ccx->ifs_clm_cckcca_excl_fa + + ccx->ifs_clm_ofdmcca_excl_fa) * 100; + ccx->ifs_clm_cca_excl_fa_ratio = (u8)PHYDM_DIV(numerator, denominator); + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Tx_ratio = %d, EDCCA_exclude_CCA_ratio = %d \n", + ccx->ifs_clm_tx_ratio, ccx->ifs_clm_edcca_excl_cca_ratio); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "FA_ratio = %d, CCA_exclude_FA_ratio = %d \n", + ccx->ifs_clm_fa_ratio, ccx->ifs_clm_cca_excl_fa_ratio); +} + +void phydm_ifs_clm_get_result(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u32 value32 = 0; + u8 i = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + /*Enhance CLM result*/ + value32 = odm_get_bb_reg(dm, R_0x2e60, MASKDWORD); + ccx->ifs_clm_tx = (u16)(value32 & MASKLWORD); + ccx->ifs_clm_edcca_excl_cca = (u16)((value32 & MASKHWORD) >> 16); + value32 = odm_get_bb_reg(dm, R_0x2e64, MASKDWORD); + ccx->ifs_clm_ofdmfa = (u16)(value32 & MASKLWORD); + ccx->ifs_clm_ofdmcca_excl_fa = (u16)((value32 & MASKHWORD) >> 16); + value32 = odm_get_bb_reg(dm, R_0x2e68, MASKDWORD); + ccx->ifs_clm_cckfa = (u16)(value32 & MASKLWORD); + ccx->ifs_clm_cckcca_excl_fa = (u16)((value32 & MASKHWORD) >> 16); + value32 = odm_get_bb_reg(dm, R_0x2e6c, MASKDWORD); + ccx->ifs_clm_total_cca = (u16)(value32 & MASKLWORD); + + /* IFS result */ + value32 = odm_get_bb_reg(dm, R_0x2e70, MASKDWORD); + odm_move_memory(dm, &ccx->ifs_clm_his[0], &value32, 4); + value32 = odm_get_bb_reg(dm, R_0x2e74, MASKDWORD); + ccx->ifs_clm_avg[0] = (u16)(value32 & MASKLWORD); + ccx->ifs_clm_avg[1] = (u16)((value32 & MASKHWORD) >> 16); + value32 = odm_get_bb_reg(dm, R_0x2e78, MASKDWORD); + ccx->ifs_clm_avg[2] = (u16)(value32 & MASKLWORD); + ccx->ifs_clm_avg[3] = (u16)((value32 & MASKHWORD) >> 16); + value32 = odm_get_bb_reg(dm, R_0x2e7c, MASKDWORD); + ccx->ifs_clm_avg_cca[0] = (u16)(value32 & MASKLWORD); + ccx->ifs_clm_avg_cca[1] = (u16)((value32 & MASKHWORD) >> 16); + value32 = odm_get_bb_reg(dm, R_0x2e80, MASKDWORD); + ccx->ifs_clm_avg_cca[2] = (u16)(value32 & MASKLWORD); + ccx->ifs_clm_avg_cca[3] = (u16)((value32 & MASKHWORD) >> 16); + + /* Print Result */ + PHYDM_DBG(dm, DBG_ENV_MNTR, + "ECLM_Rpt[%d]: \nTx = %d, EDCCA_exclude_CCA = %d \n", + ccx->ifs_clm_rpt_stamp, ccx->ifs_clm_tx, + ccx->ifs_clm_edcca_excl_cca); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[FA_cnt] {CCK, OFDM} = {%d, %d}\n", + ccx->ifs_clm_cckfa, ccx->ifs_clm_ofdmfa); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[CCA_exclude_FA_cnt] {CCK, OFDM} = {%d, %d}\n", + ccx->ifs_clm_cckcca_excl_fa, ccx->ifs_clm_ofdmcca_excl_fa); + PHYDM_DBG(dm, DBG_ENV_MNTR, "CCATotal = %d\n", ccx->ifs_clm_total_cca); + PHYDM_DBG(dm, DBG_ENV_MNTR, "Time:[his, avg, avg_cca]\n"); + for (i = 0; i < IFS_CLM_NUM; i++) + PHYDM_DBG(dm, DBG_ENV_MNTR, + "T%d:[%d, %d, %d]\n", i + 1, + ccx->ifs_clm_his[i], ccx->ifs_clm_avg[i], + ccx->ifs_clm_avg_cca[i]); + + phydm_ifs_clm_racing_release(dm); + + return; +} + +void phydm_ifs_clm_set_th_reg(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 i = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + /*Set IFS period TH*/ + odm_set_bb_reg(dm, R_0x1ed4, BIT(31), ccx->ifs_clm_th_en[0]); + odm_set_bb_reg(dm, R_0x1ed8, BIT(31), ccx->ifs_clm_th_en[1]); + odm_set_bb_reg(dm, R_0x1edc, BIT(31), ccx->ifs_clm_th_en[2]); + odm_set_bb_reg(dm, R_0x1ee0, BIT(31), ccx->ifs_clm_th_en[3]); + odm_set_bb_reg(dm, R_0x1ed4, 0x7fff0000, ccx->ifs_clm_th_low[0]); + odm_set_bb_reg(dm, R_0x1ed8, 0x7fff0000, ccx->ifs_clm_th_low[1]); + odm_set_bb_reg(dm, R_0x1edc, 0x7fff0000, ccx->ifs_clm_th_low[2]); + odm_set_bb_reg(dm, R_0x1ee0, 0x7fff0000, ccx->ifs_clm_th_low[3]); + odm_set_bb_reg(dm, R_0x1ed4, MASKLWORD, ccx->ifs_clm_th_high[0]); + odm_set_bb_reg(dm, R_0x1ed8, MASKLWORD, ccx->ifs_clm_th_high[1]); + odm_set_bb_reg(dm, R_0x1edc, MASKLWORD, ccx->ifs_clm_th_high[2]); + odm_set_bb_reg(dm, R_0x1ee0, MASKLWORD, ccx->ifs_clm_th_high[3]); + + for (i = 0; i < IFS_CLM_NUM; i++) + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Update IFS_CLM_th%d[High Low] : [%d %d]\n", i + 1, + ccx->ifs_clm_th_high[i], ccx->ifs_clm_th_low[i]); +} + +boolean phydm_ifs_clm_th_update_chk(void *dm_void, + enum ifs_clm_application ifs_clm_app, + boolean *ifs_clm_th_en, u16 *ifs_clm_th_low, + u16 *ifs_clm_th_high, s16 th_shift) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + boolean is_update = false; + u16 ifs_clm_th_low_bg[IFS_CLM_NUM] = {12, 5, 2, 0}; + u16 ifs_clm_th_high_bg[IFS_CLM_NUM] = {64, 12, 5, 2}; + u8 i = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + PHYDM_DBG(dm, DBG_ENV_MNTR, "App=%d, th_shift=%d\n", ifs_clm_app, + th_shift); + + switch (ifs_clm_app) { + case IFS_CLM_BACKGROUND: + case IFS_CLM_ACS: + case IFS_CLM_HP_TAS: + if (ccx->ifs_clm_app != ifs_clm_app || th_shift != 0) { + is_update = true; + + for (i = 0; i < IFS_CLM_NUM; i++) { + ifs_clm_th_en[i] = true; + ifs_clm_th_low[i] = ifs_clm_th_low_bg[i]; + ifs_clm_th_high[i] = ifs_clm_th_high_bg[i]; + } + } + break; + case IFS_CLM_DBG: + if (ccx->ifs_clm_app != ifs_clm_app || th_shift != 0) { + is_update = true; + + for (i = 0; i < IFS_CLM_NUM; i++) { + ifs_clm_th_en[i] = true; + ifs_clm_th_low[i] = MAX_2(ccx->ifs_clm_th_low[i] + + th_shift, 0); + ifs_clm_th_high[i] = MAX_2(ccx->ifs_clm_th_high[i] + + th_shift, 0); + } + } + break; + default: + break; + } + + if (is_update) + PHYDM_DBG(dm, DBG_ENV_MNTR, "[Update IFS_TH]\n"); + else + PHYDM_DBG(dm, DBG_ENV_MNTR, "No need to update IFS_TH\n"); + + return is_update; +} + +void phydm_ifs_clm_set(void *dm_void, enum ifs_clm_application ifs_clm_app, + u16 period, u8 ctrl_unit, s16 th_shift) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + boolean ifs_clm_th_en[IFS_CLM_NUM] = {0}; + u16 ifs_clm_th_low[IFS_CLM_NUM] = {0}; + u16 ifs_clm_th_high[IFS_CLM_NUM] = {0}; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + PHYDM_DBG(dm, DBG_ENV_MNTR, "period=%d, ctrl_unit=%d\n", period, + ctrl_unit); + + /*Set Unit*/ + if (ctrl_unit != ccx->ifs_clm_ctrl_unit) { + odm_set_bb_reg(dm, R_0x1ee4, 0xc0000000, ctrl_unit); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Update IFS_CLM unit ((%d)) -> ((%d))\n", + ccx->ifs_clm_ctrl_unit, ctrl_unit); + ccx->ifs_clm_ctrl_unit = ctrl_unit; + } + + /*Set Duration*/ + if (period != ccx->ifs_clm_period) { + odm_set_bb_reg(dm, R_0x1eec, 0xc0000000, (period & 0x3)); + odm_set_bb_reg(dm, R_0x1ef0, 0xfe000000, ((period >> 2) & + 0x7f)); + odm_set_bb_reg(dm, R_0x1ef4, 0xc0000000, ((period >> 9) & + 0x3)); + odm_set_bb_reg(dm, R_0x1ef8, 0x3e000000, ((period >> 11) & + 0x1f)); + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Update IFS_CLM period ((%d)) -> ((%d))\n", + ccx->ifs_clm_period, period); + ccx->ifs_clm_period = period; + } + + /*Set IFS CLM threshold*/ + if (phydm_ifs_clm_th_update_chk(dm, ifs_clm_app, &ifs_clm_th_en[0], + &ifs_clm_th_low[0], &ifs_clm_th_high[0], + th_shift)) { + + ccx->ifs_clm_app = ifs_clm_app; + odm_move_memory(dm, &ccx->ifs_clm_th_en[0], &ifs_clm_th_en, + IFS_CLM_NUM); + odm_move_memory(dm, &ccx->ifs_clm_th_low[0], &ifs_clm_th_low, + IFS_CLM_NUM); + odm_move_memory(dm, &ccx->ifs_clm_th_high[0], &ifs_clm_th_high, + IFS_CLM_NUM); + + phydm_ifs_clm_set_th_reg(dm); + } +} + +boolean +phydm_ifs_clm_mntr_set(void *dm_void, struct ifs_clm_para_info *ifs_clm_para) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u16 ifs_clm_time = 0; /*unit: 4/8/12/16us*/ + u8 unit = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + if (ifs_clm_para->mntr_time == 0) + return false; + + if (ifs_clm_para->ifs_clm_lv >= IFS_CLM_MAX_NUM) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "Wrong LV=%d\n", + ifs_clm_para->ifs_clm_lv); + return false; + } + + if (phydm_ifs_clm_racing_ctrl(dm, ifs_clm_para->ifs_clm_lv) == PHYDM_SET_FAIL) + return false; + + if (ifs_clm_para->mntr_time >= 1048) { + unit = IFS_CLM_16; + ifs_clm_time = IFS_CLM_PERIOD_MAX; /*65535 * 16us = 1048ms*/ + } else if (ifs_clm_para->mntr_time >= 786) {/*65535 * 12us = 786 ms*/ + unit = IFS_CLM_16; + ifs_clm_time = PHYDM_DIV(ifs_clm_para->mntr_time * MS_TO_US, 16); + } else if (ifs_clm_para->mntr_time >= 524) { + unit = IFS_CLM_12; + ifs_clm_time = PHYDM_DIV(ifs_clm_para->mntr_time * MS_TO_US, 12); + } else if (ifs_clm_para->mntr_time >= 262) { + unit = IFS_CLM_8; + ifs_clm_time = PHYDM_DIV(ifs_clm_para->mntr_time * MS_TO_US, 8); + } else { + unit = IFS_CLM_4; + ifs_clm_time = PHYDM_DIV(ifs_clm_para->mntr_time * MS_TO_US, 4); + } + + phydm_ifs_clm_set(dm, ifs_clm_para->ifs_clm_app, ifs_clm_time, unit, + ifs_clm_para->th_shift); + + return true; +} + +boolean +phydm_ifs_clm_mntr_chk(void *dm_void, u16 monitor_time /*unit ms*/) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + struct ifs_clm_para_info ifs_clm_para = {0}; + boolean ifs_clm_chk_result = false; + u32 sys_return_time = 0; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + if (ccx->ifs_clm_manual_ctrl) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "IFS CLM in manual ctrl\n"); + return ifs_clm_chk_result; + } + + sys_return_time = ccx->ifs_clm_trigger_time + MAX_ENV_MNTR_TIME; + if (ccx->ifs_clm_app != IFS_CLM_BACKGROUND && + (sys_return_time > dm->phydm_sys_up_time)) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "ifs_clm_app=%d, trigger_time %d, sys_time=%d\n", + ccx->ifs_clm_app, ccx->ifs_clm_trigger_time, + dm->phydm_sys_up_time); + + return ifs_clm_chk_result; + } + + /*[IFS CLM get result ------------------------------------]*/ + phydm_ifs_clm_get_result(dm); + phydm_ifs_clm_get_utility(dm); + + /*[IFS CLM trigger setting]------------------------------------------*/ + ifs_clm_para.ifs_clm_app = IFS_CLM_BACKGROUND; + ifs_clm_para.ifs_clm_lv = IFS_CLM_LV_1; + ifs_clm_para.mntr_time = monitor_time; + ifs_clm_para.th_shift = 0; + + ifs_clm_chk_result = phydm_ifs_clm_mntr_set(dm, &ifs_clm_para); + + return ifs_clm_chk_result; +} + +void phydm_ifs_clm_init(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + + ccx->ifs_clm_app = IFS_CLM_BACKGROUND; + + /*Set IFS threshold*/ + ccx->ifs_clm_ongoing = false; + ccx->ifs_clm_set_lv = IFS_CLM_RELEASE; + + if (phydm_ifs_clm_th_update_chk(dm, ccx->ifs_clm_app, + &ccx->ifs_clm_th_en[0], + &ccx->ifs_clm_th_low[0], + &ccx->ifs_clm_th_high[0], 0xffff)) + phydm_ifs_clm_set_th_reg(dm); + + ccx->ifs_clm_period = 0; + ccx->ifs_clm_ctrl_unit = IFS_CLM_INIT; + ccx->ifs_clm_manual_ctrl = 0; + ccx->ifs_clm_rpt_stamp = 0; +} + +void phydm_ifs_clm_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + struct ifs_clm_para_info ifs_clm_para; + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 result_tmp = 0; + u8 i = 0; + u16 th_shift = 0; + + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM)) + return; + + for (i = 0; i < 5; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + } + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "IFS_CLM Basic-Trigger 960ms: {1}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "IFS_CLM Adv-Trigger: {2} {App:3 for dbg} {LV:1~4} {0~2096ms} {th_shift}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "IFS_CLM Get Result: {100}\n"); + } else if (var1[0] == 100) { /*Get IFS_CLM results*/ + phydm_ifs_clm_get_result(dm); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "ECLM_Rpt[%d]: \nTx = %d \nEDCCA_exclude_CCA = %d\n", + ccx->ifs_clm_rpt_stamp, ccx->ifs_clm_tx, + ccx->ifs_clm_edcca_excl_cca); + PDM_SNPF(out_len, used, output + used, out_len - used, + "[FA_cnt] {CCK, OFDM} = {%d, %d}\n", + ccx->ifs_clm_cckfa, ccx->ifs_clm_ofdmfa); + PDM_SNPF(out_len, used, output + used, out_len - used, + "[CCA_exclude_FA_cnt] {CCK, OFDM} = {%d, %d}\n", + ccx->ifs_clm_cckcca_excl_fa, + ccx->ifs_clm_ofdmcca_excl_fa); + PDM_SNPF(out_len, used, output + used, out_len - used, + "CCATotal = %d\n", ccx->ifs_clm_total_cca); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Time:[his, avg, avg_cca]\n"); + for (i = 0; i < IFS_CLM_NUM; i++) + PDM_SNPF(out_len, used, output + used, out_len - used, + "T%d:[%d, %d, %d]\n", i + 1, + ccx->ifs_clm_his[i], ccx->ifs_clm_avg[i], + ccx->ifs_clm_avg_cca[i]); + + phydm_ifs_clm_get_utility(dm); + + ccx->ifs_clm_manual_ctrl = 0; + } else { /*IFS_CLM trigger*/ + ccx->ifs_clm_manual_ctrl = 1; + + if (var1[0] == 1) { + ifs_clm_para.ifs_clm_app = IFS_CLM_DBG; + ifs_clm_para.ifs_clm_lv = IFS_CLM_LV_4; + ifs_clm_para.mntr_time = 960; + ifs_clm_para.th_shift = 0; + } else { + ifs_clm_para.ifs_clm_app = (enum ifs_clm_application)var1[1]; + ifs_clm_para.ifs_clm_lv = (enum phydm_ifs_clm_level)var1[2]; + ifs_clm_para.mntr_time = (u16)var1[3]; + ifs_clm_para.th_shift = (s16)var1[4]; + } + + PDM_SNPF(out_len, used, output + used, out_len - used, + "app=%d, lv=%d, time=%d ms, th_shift=%s%d\n", + ifs_clm_para.ifs_clm_app, ifs_clm_para.ifs_clm_lv, + ifs_clm_para.mntr_time, + (ifs_clm_para.th_shift > 0) ? "+" : "-", + ifs_clm_para.th_shift); + + if (phydm_ifs_clm_mntr_set(dm, &ifs_clm_para) == PHYDM_SET_SUCCESS) + phydm_ifs_clm_trigger(dm); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "rpt_stamp=%d\n", ccx->ifs_clm_rpt_stamp); + for (i = 0; i < IFS_CLM_NUM; i++) + PDM_SNPF(out_len, used, output + used, out_len - used, + "IFS_CLM_th%d[High Low] : [%d %d]\n", i + 1, + ccx->ifs_clm_th_high[i], + ccx->ifs_clm_th_low[i]); + } + + *_used = used; + *_out_len = out_len; +} +#endif + +u8 phydm_enhance_mntr_trigger(void *dm_void, struct nhm_para_info *nhm_para, + struct clm_para_info *clm_para, + struct fahm_para_info *fahm_para, + struct ifs_clm_para_info *ifs_clm_para, + struct enhance_mntr_trig_rpt *trig_rpt) +{ + u8 trigger_result = 0; +#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT) && defined(FAHM_SUPPORT) && defined(IFS_CLM_SUPPORT)) + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + boolean nhm_set_ok = false; + boolean clm_set_ok = false; + boolean fahm_set_ok = false; + boolean ifs_clm_set_ok = false; + + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM) || + !(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM)) + return trigger_result; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__); + + nhm_set_ok = phydm_nhm_mntr_set(dm, nhm_para); + + if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) { + clm_set_ok = phydm_clm_mntr_set(dm, clm_para); + } else if (ccx->clm_mntr_mode == CLM_FW_MNTR) { + phydm_clm_h2c(dm, CLM_PERIOD_MAX, true); + trigger_result |= CLM_SUCCESS; + } + + fahm_set_ok = phydm_fahm_mntr_set(dm, fahm_para); + + ifs_clm_set_ok = phydm_ifs_clm_mntr_set(dm, ifs_clm_para); + + if (nhm_set_ok) { + phydm_nhm_trigger(dm); + trigger_result |= NHM_SUCCESS; + } + + if (clm_set_ok) { + phydm_clm_trigger(dm); + trigger_result |= CLM_SUCCESS; + } + + if (fahm_set_ok) { + phydm_fahm_trigger(dm); + trigger_result |= FAHM_SUCCESS; + } + + if (ifs_clm_set_ok) { + phydm_ifs_clm_trigger(dm); + trigger_result |= IFS_CLM_SUCCESS; + } + + /*monitor for the test duration*/ + ccx->start_time = odm_get_current_time(dm); + + trig_rpt->nhm_rpt_stamp = ccx->nhm_rpt_stamp; + trig_rpt->clm_rpt_stamp = ccx->clm_rpt_stamp; + trig_rpt->fahm_rpt_stamp = ccx->fahm_rpt_stamp; + trig_rpt->ifs_clm_rpt_stamp = ccx->ifs_clm_rpt_stamp; + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "rpt_stamp{NHM, CLM, FAHM, IFS_CLM}={%d, %d, %d, %d}\n\n", + trig_rpt->nhm_rpt_stamp, trig_rpt->clm_rpt_stamp, + trig_rpt->fahm_rpt_stamp, trig_rpt->ifs_clm_rpt_stamp); + +#endif + return trigger_result; +} + +u8 phydm_enhance_mntr_result(void *dm_void, struct enhance_mntr_rpt *rpt) +{ + u8 enhance_mntr_rpt = 0; +#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT) && defined(FAHM_SUPPORT) && defined(IFS_CLM_SUPPORT)) + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + u64 progressing_time = 0; + u32 val_tmp = 0; + + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM) || + !(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM)) + return enhance_mntr_rpt; + + /*monitor for the test duration*/ + progressing_time = odm_get_progressing_time(dm, ccx->start_time); + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s] ======>\n", __func__); + PHYDM_DBG(dm, DBG_ENV_MNTR, "enhance_mntr_time=%lld\n", + progressing_time); + + /*Get NHM result*/ + if (phydm_nhm_get_result(dm)) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "Get NHM_rpt success\n"); + phydm_nhm_get_utility(dm); + rpt->nhm_ratio = ccx->nhm_ratio; + rpt->nhm_env_ratio = ccx->nhm_env_ratio; + rpt->nhm_noise_pwr = ccx->nhm_level; + rpt->nhm_pwr = ccx->nhm_pwr; + enhance_mntr_rpt |= NHM_SUCCESS; + + odm_move_memory(dm, &rpt->nhm_result[0], + &ccx->nhm_result[0], NHM_RPT_NUM); + } else { + rpt->nhm_ratio = ENV_MNTR_FAIL; + rpt->nhm_env_ratio = ENV_MNTR_FAIL; + } + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[NHM]rpt_stamp=%d, IGI=0x%x, ratio=%d, env_ratio=%d, noise_pwr=%d, pwr=%d\n", + rpt->nhm_rpt_stamp, ccx->nhm_igi, rpt->nhm_ratio, + rpt->nhm_env_ratio, rpt->nhm_noise_pwr, rpt->nhm_pwr); + + /*Get CLM result*/ + if (ccx->clm_mntr_mode == CLM_DRIVER_MNTR) { + if (phydm_clm_get_result(dm)) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "Get CLM_rpt success\n"); + phydm_clm_get_utility(dm); + enhance_mntr_rpt |= CLM_SUCCESS; + rpt->clm_ratio = ccx->clm_ratio; + } else { + rpt->clm_ratio = ENV_MNTR_FAIL; + } + } else { + if (ccx->clm_fw_result_cnt != 0) { + val_tmp = ccx->clm_fw_result_acc + / ccx->clm_fw_result_cnt; + ccx->clm_ratio = (u8)val_tmp; + } else { + ccx->clm_ratio = 0; + } + rpt->clm_ratio = ccx->clm_ratio; + PHYDM_DBG(dm, DBG_ENV_MNTR, + "clm_fw_result_acc=%d, clm_fw_result_cnt=%d\n", + ccx->clm_fw_result_acc, ccx->clm_fw_result_cnt); + + ccx->clm_fw_result_acc = 0; + ccx->clm_fw_result_cnt = 0; + enhance_mntr_rpt |= CLM_SUCCESS; + } + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[CLM]rpt_stamp=%d, ratio=%d\n", + rpt->clm_rpt_stamp, rpt->clm_ratio); + + /*Get FAHM result*/ + if (phydm_fahm_get_result(dm)) { + PHYDM_DBG(dm, DBG_ENV_MNTR, "Get FAHM_rpt success\n"); + phydm_fahm_get_utility(dm); + rpt->fahm_pwr = ccx->fahm_pwr; + enhance_mntr_rpt |= FAHM_SUCCESS; + + odm_move_memory(dm, &rpt->fahm_result[0], + &ccx->fahm_result[0], NHM_RPT_NUM * 2); + } else { + rpt->fahm_pwr = 0; + } + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[FAHM]rpt_stamp=%d, IGI=0x%x, pwr=%d\n", + rpt->fahm_rpt_stamp, ccx->fahm_igi, rpt->fahm_pwr); + + /*Get IFS_CLM result*/ + phydm_ifs_clm_get_result(dm); + phydm_ifs_clm_get_utility(dm); + rpt->ifs_clm_tx_ratio = ccx->ifs_clm_tx_ratio; + rpt->ifs_clm_edcca_excl_cca_ratio = ccx->ifs_clm_edcca_excl_cca_ratio; + rpt->ifs_clm_fa_ratio = ccx->ifs_clm_fa_ratio; + rpt->ifs_clm_cca_excl_fa_ratio = ccx->ifs_clm_cca_excl_fa_ratio; + rpt->ifs_clm_rpt_stamp = ccx->ifs_clm_rpt_stamp; + enhance_mntr_rpt |= IFS_CLM_SUCCESS; + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "[IFS_CLM]rpt_stamp = %d, Tx_ratio = %d, EDCCA_exclude_CCA_ratio = %d\n", + ccx->ifs_clm_rpt_stamp, ccx->ifs_clm_tx_ratio, + ccx->ifs_clm_edcca_excl_cca_ratio); + + PHYDM_DBG(dm, DBG_ENV_MNTR, + "FA_ratio = %d, CCA_exclude_FA_ratio = %d\n", + ccx->ifs_clm_fa_ratio, ccx->ifs_clm_cca_excl_fa_ratio); + + rpt->nhm_rpt_stamp = ccx->nhm_rpt_stamp; + rpt->clm_rpt_stamp = ccx->clm_rpt_stamp; + rpt->fahm_rpt_stamp = ccx->fahm_rpt_stamp; + rpt->ifs_clm_rpt_stamp = ccx->ifs_clm_rpt_stamp; +#endif + return enhance_mntr_rpt; +} + +void phydm_enhance_mntr_watchdog(void *dm_void) +{ +#ifdef IFS_CLM_SUPPORT + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ccx_info *ccx = &dm->dm_ccx_info; + boolean ifs_clm_chk_ok = false; + + if (!(dm->support_ability & ODM_BB_ENV_MONITOR)) + return; + + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM)) + return; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + ifs_clm_chk_ok = phydm_ifs_clm_mntr_chk(dm, 960); /*monitor 960ms*/ + + if (ifs_clm_chk_ok) + phydm_ifs_clm_trigger(dm); +#endif +} + +void phydm_enhance_monitor_init(void *dm_void) +{ +#ifdef IFS_CLM_SUPPORT + struct dm_struct *dm = (struct dm_struct *)dm_void; + + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM)) + return; + + PHYDM_DBG(dm, DBG_ENV_MNTR, "[%s]===>\n", __func__); + phydm_ifs_clm_restart(dm); + phydm_ifs_clm_init(dm); +#endif +} + +void phydm_enhance_mntr_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ +#if (defined(NHM_SUPPORT) && defined(CLM_SUPPORT) && defined(FAHM_SUPPORT) && defined(IFS_CLM_SUPPORT)) + struct dm_struct *dm = (struct dm_struct *)dm_void; + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + struct nhm_para_info nhm_para = {0}; + struct clm_para_info clm_para = {0}; + struct fahm_para_info fahm_para = {0}; + struct ifs_clm_para_info ifs_clm_para = {0}; + struct enhance_mntr_rpt rpt = {0}; + struct enhance_mntr_trig_rpt trig_rpt = {0}; + struct ccx_info *ccx = &dm->dm_ccx_info; + u8 set_result = 0; + u8 i = 0; + + if (!(dm->support_ic_type & PHYDM_IC_SUPPORT_FAHM) || + !(dm->support_ic_type & PHYDM_IC_SUPPORT_IFS_CLM)) + return; + + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Basic-Trigger 960ms for ifs_clm, 262ms for others: {1}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Get Result: {100}\n"); + } else if (var1[0] == 100) { /* Get results */ + set_result = phydm_enhance_mntr_result(dm, &rpt); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "Set Result=%d, rpt_stamp{NHM, CLM, FAHM, IFS_CLM}={%d, %d, %d, %d}\n", + set_result, rpt.nhm_rpt_stamp, rpt.clm_rpt_stamp, + rpt.fahm_rpt_stamp, rpt.ifs_clm_rpt_stamp); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "nhm_IGI=0x%x, nhm_ratio=%d, ,nhm_env_ratio=%d, noise_pwr=%d, pwr=%d\n", + ccx->nhm_igi, rpt.nhm_ratio, rpt.nhm_env_ratio, + rpt.nhm_noise_pwr, rpt.nhm_pwr); + + for (i = 0; i <= 11; i++) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "nhm_rpt[%d] = %d (%d percent)\n", i, + rpt.nhm_result[i], + (((rpt.nhm_result[i] * 100) + 128) >> 8)); + } + + PDM_SNPF(out_len, used, output + used, out_len - used, + "clm_ratio=%d, fahm_IGI=0x%x, fahm_pwr=%d\n", + rpt.clm_ratio, ccx->fahm_igi, rpt.fahm_pwr); + + for (i = 0; i <= 11; i++) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "fahm_rpt[%d] = %d (%d percent)\n", i, + rpt.fahm_result[i], + (((rpt.fahm_result[i] * 100) + 32768) >> 16)); + } + + PDM_SNPF(out_len, used, output + used, out_len - used, + "ifs_clm_Tx_ratio = %d, ifs_clm_EDCCA_exclude_CCA_ratio = %d \n", + rpt.ifs_clm_tx_ratio, + rpt.ifs_clm_edcca_excl_cca_ratio); + PDM_SNPF(out_len, used, output + used, out_len - used, + "ifs_clm_FA_ratio = %d, ifs_clm_CCA_exclude_FA_ratio = %d \n", + rpt.ifs_clm_fa_ratio, rpt.ifs_clm_cca_excl_fa_ratio); + } else { /* Set & trigger*/ + /*nhm para*/ + nhm_para.incld_txon = NHM_EXCLUDE_TXON; + nhm_para.incld_cca = NHM_EXCLUDE_CCA; + nhm_para.div_opt = NHM_CNT_ALL; + nhm_para.nhm_app = NHM_ACS; + nhm_para.nhm_lv = NHM_LV_2; + nhm_para.mntr_time = 262; + nhm_para.en_1db_mode = false; + + /*clm para*/ + clm_para.clm_app = CLM_ACS; + clm_para.clm_lv = CLM_LV_2; + clm_para.mntr_time = 262; + + /*fahm para*/ + fahm_para.incld_fa = FAHM_INCLUDE_FA; + fahm_para.incld_crc32_ok = FAHM_EXCLUDE_CRC32_OK; + fahm_para.incld_crc32_err = FAHM_EXCLUDE_CRC32_ERR; + fahm_para.app = FAHM_ACS; + fahm_para.lv = FAHM_LV_2; + fahm_para.mntr_time = 262; + fahm_para.en_1db_mode = false; + + ifs_clm_para.ifs_clm_app = IFS_CLM_ACS; + ifs_clm_para.ifs_clm_lv = IFS_CLM_LV_2; + ifs_clm_para.mntr_time = 960; + ifs_clm_para.th_shift = 0; + + set_result = phydm_enhance_mntr_trigger(dm, &nhm_para, + &clm_para, &fahm_para, + &ifs_clm_para, + &trig_rpt); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "Set Result=%d, rpt_stamp{NHM, CLM, FAHM, IFS_CLM}={%d, %d ,%d, %d}\n", + set_result, trig_rpt.nhm_rpt_stamp, + trig_rpt.clm_rpt_stamp, trig_rpt.fahm_rpt_stamp, + trig_rpt.ifs_clm_rpt_stamp); + } + *_used = used; + *_out_len = out_len; +#endif +} + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_ccx.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_ccx.h index 5e2fde1236c5..5f0ec4f145b4 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_ccx.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_ccx.h @@ -27,8 +27,8 @@ #ifndef __PHYDMCCX_H__ #define __PHYDMCCX_H__ -/* 2019.07.01 Modify nhm cmd*/ -#define CCX_VERSION "3.1" +/* 2020.07.21 Fix 8723F compile warning and remove 8723f in dym_pw_th(this machanism is WA patch only for 8822C ASUS)*/ +#define CCX_VERSION "4.4" /* @1 ============================================================ * 1 Definition @@ -37,30 +37,28 @@ #define CCX_EN 1 #define MAX_ENV_MNTR_TIME 8 /*second*/ -#define IGI_TO_NHM_TH_MULTIPLIER 2 +#define MS_TO_US 1000 #define MS_TO_4US_RATIO 250 #define CCA_CAP 14 #define CLM_MAX_REPORT_TIME 10 -#define DEVIDER_ERROR 0xffff -#define CLM_PERIOD_MAX 65535 -#define NHM_PERIOD_MAX 65534 -#define NHM_TH_NUM 11 /*threshold number of NHM*/ +#define CLM_PERIOD_MAX 65535 +#define IFS_CLM_PERIOD_MAX 65535 +#define NHM_PERIOD_MAX 65534 +#define NHM_TH_NUM 11 /*threshold number of NHM/FAHM*/ #define NHM_RPT_NUM 12 +#define NHM_IC_NOISE_TH 60 /*60/2 - 10 = 20 = -80 dBm*/ +#define IFS_CLM_NUM 4 #ifdef NHM_DYM_PW_TH_SUPPORT #define DYM_PWTH_CCA_CAP 24 #endif -#define IGI_2_NHM_TH(igi) ((igi) << 1)/*NHM_threshold = IGI * 2*/ +#define IGI_2_NHM_TH(igi) ((igi) << 1)/*NHM/FAHM threshold = IGI * 2*/ #define NTH_TH_2_RSSI(th) ((th >> 1) - 10) -/*@FAHM*/ -#define FAHM_INCLD_FA BIT(0) -#define FAHM_INCLD_CRC_OK BIT(1) -#define FAHM_INCLD_CRC_ER BIT(2) - #define NHM_SUCCESS BIT(0) #define CLM_SUCCESS BIT(1) #define FAHM_SUCCESS BIT(2) +#define IFS_CLM_SUCCESS BIT(3) #define ENV_MNTR_FAIL 0xff /* @1 ============================================================ @@ -85,6 +83,24 @@ enum phydm_nhm_level { NHM_MAX_NUM = 5 }; +enum phydm_fahm_level { + FAHM_RELEASE = 0, + FAHM_LV_1 = 1, /* Low Priority function */ + FAHM_LV_2 = 2, /* Middle Priority function */ + FAHM_LV_3 = 3, /* High priority function (ex: Check hang function) */ + FAHM_LV_4 = 4, /* Debug function (the highest priority) */ + FAHM_MAX_NUM = 5 +}; + +enum phydm_ifs_clm_level { + IFS_CLM_RELEASE = 0, + IFS_CLM_LV_1 = 1, /* @Low Priority function */ + IFS_CLM_LV_2 = 2, /* @Middle Priority function */ + IFS_CLM_LV_3 = 3, /* @High priority function (ex: Check hang function) */ + IFS_CLM_LV_4 = 4, /* @Debug function (the highest priority) */ + IFS_CLM_MAX_NUM = 5 +}; + enum nhm_divider_opt_all { NHM_CNT_ALL = 0, /*nhm SUM report <= 255*/ NHM_VALID = 1, /*nhm SUM report = 255*/ @@ -123,11 +139,50 @@ enum clm_application { CLM_ACS = 1, }; +enum fahm_opt_fa { + FAHM_EXCLUDE_FA = 0, + FAHM_INCLUDE_FA = 1, + FAHM_FA_INIT +}; + +enum fahm_opt_crc32_ok { + FAHM_EXCLUDE_CRC32_OK = 0, + FAHM_INCLUDE_CRC32_OK = 1, + FAHM_CRC32_OK_INIT +}; + +enum fahm_opt_crc32_err { + FAHM_EXCLUDE_CRC32_ERR = 0, + FAHM_INCLUDE_CRC32_ERR = 1, + FAHM_CRC32_ERR_INIT +}; + +enum fahm_application { + FAHM_BACKGROUND = 0,/*default*/ + FAHM_ACS = 1, + FAHM_DBG = 2, /*manual trigger*/ +}; + +enum ifs_clm_application { + IFS_CLM_BACKGROUND = 0,/*default*/ + IFS_CLM_ACS = 1, + IFS_CLM_HP_TAS = 2, + IFS_CLM_DBG = 3, +}; + enum clm_monitor_mode { CLM_DRIVER_MNTR = 1, CLM_FW_MNTR = 2 }; +enum phydm_ifs_clm_unit { + IFS_CLM_4 = 0, /*4us*/ + IFS_CLM_8 = 1, /*8us*/ + IFS_CLM_12 = 2, /*12us*/ + IFS_CLM_16 = 3, /*16us*/ + IFS_CLM_INIT +}; + /* @1 ============================================================ * 1 structure * 1 ============================================================ @@ -137,14 +192,41 @@ struct env_trig_rpt { u8 clm_rpt_stamp; }; - struct env_mntr_rpt { u8 nhm_ratio; + u8 nhm_env_ratio; /*exclude nhm_r[0] above -80dBm or first cluster under -80dBm*/ u8 nhm_result[NHM_RPT_NUM]; u8 clm_ratio; u8 nhm_rpt_stamp; u8 clm_rpt_stamp; - u8 nhm_noise_pwr; + u8 nhm_noise_pwr; /*including r[0]~r[10]*/ + u8 nhm_pwr; /*including r[0]~r[11]*/ +}; + +struct enhance_mntr_trig_rpt { + u8 nhm_rpt_stamp; + u8 clm_rpt_stamp; + u8 fahm_rpt_stamp; + u8 ifs_clm_rpt_stamp; +}; + +struct enhance_mntr_rpt { + u8 nhm_ratio; + u8 nhm_env_ratio; /*exclude nhm_r[0] above -80dBm or first cluster under -80dBm*/ + u8 nhm_result[NHM_RPT_NUM]; + u8 clm_ratio; + u8 nhm_rpt_stamp; + u8 clm_rpt_stamp; + u8 nhm_noise_pwr; /*including r[0]~r[10]*/ + u8 nhm_pwr; /*including r[0]~r[11]*/ + u16 fahm_result[NHM_RPT_NUM]; + u8 fahm_rpt_stamp; + u8 fahm_pwr; + u8 ifs_clm_rpt_stamp; + u8 ifs_clm_tx_ratio; + u8 ifs_clm_edcca_excl_cca_ratio; + u8 ifs_clm_fa_ratio; + u8 ifs_clm_cca_excl_fa_ratio; }; struct nhm_para_info { @@ -164,9 +246,33 @@ struct clm_para_info { u16 mntr_time; /*@0~262 unit ms*/ }; +struct fahm_para_info { + enum fahm_opt_fa incld_fa; + enum fahm_opt_crc32_ok incld_crc32_ok; + enum fahm_opt_crc32_err incld_crc32_err; + enum fahm_application app; + enum phydm_fahm_level lv; + u16 mntr_time; /*0~262 unit ms*/ + boolean en_1db_mode; + u8 th0_manual;/* for 1-db mode*/ +}; + +struct ifs_clm_para_info { + enum ifs_clm_application ifs_clm_app; + enum phydm_ifs_clm_level ifs_clm_lv; + enum phydm_ifs_clm_unit ifs_clm_ctrl_unit; /*unit*/ + u16 mntr_time; /*ms*/ + boolean ifs_clm_th_en[IFS_CLM_NUM]; + u16 ifs_clm_th_low[IFS_CLM_NUM]; + u16 ifs_clm_th_high[IFS_CLM_NUM]; + s16 th_shift; +}; + struct ccx_info { u32 nhm_trigger_time; u32 clm_trigger_time; + u32 fahm_trigger_time; + u32 ifs_clm_trigger_time; u64 start_time; /*@monitor for the test duration*/ #ifdef NHM_SUPPORT enum nhm_application nhm_app; @@ -176,17 +282,19 @@ struct ccx_info { /*Report*/ u8 nhm_th[NHM_TH_NUM]; u8 nhm_result[NHM_RPT_NUM]; + u8 nhm_wgt[NHM_RPT_NUM]; u16 nhm_period; /* @4us per unit */ u8 nhm_igi; u8 nhm_manual_ctrl; u8 nhm_ratio; /*@1% per nuit, it means the interference igi can't overcome.*/ + u8 nhm_env_ratio; /*exclude nhm_r[0] above -80dBm or first cluster under -80dBm*/ u8 nhm_rpt_sum; - u16 nhm_duration; /*@Real time of NHM_VALID */ u8 nhm_set_lv; boolean nhm_ongoing; u8 nhm_rpt_stamp; - u8 nhm_level; + u8 nhm_level; /*including r[0]~r[10]*/ u8 nhm_level_valid; + u8 nhm_pwr; /*including r[0]~r[11]*/ #ifdef NHM_DYM_PW_TH_SUPPORT boolean nhm_dym_pw_th_en; boolean dym_pwth_manual_ctrl; @@ -212,11 +320,51 @@ struct ccx_info { u8 clm_rpt_stamp; #endif #ifdef FAHM_SUPPORT + enum fahm_application fahm_app; + enum fahm_opt_fa fahm_incld_fa; + enum fahm_opt_crc32_ok fahm_incld_crc32_ok; + enum fahm_opt_crc32_err fahm_incld_crc32_err; boolean fahm_ongoing; - u8 env_mntr_igi; u8 fahm_nume_sel; /*@fahm_numerator_sel: select {FA, CRCOK, CRC_fail} */ u8 fahm_denom_sel; /*@fahm_denominator_sel: select {FA, CRCOK, CRC_fail} */ + u8 fahm_th[NHM_TH_NUM]; + u16 fahm_result[NHM_RPT_NUM]; u16 fahm_period; /*unit: 4us*/ + u8 fahm_igi; + u8 fahm_manual_ctrl; + u16 fahm_rpt_sum; + u8 fahm_set_lv; + u8 fahm_rpt_stamp; + u8 fahm_pwr; /*including r[0]~r[11]*/ +#endif +#ifdef IFS_CLM_SUPPORT + enum ifs_clm_application ifs_clm_app; + /*Control*/ + enum phydm_ifs_clm_unit ifs_clm_ctrl_unit; /*4,8,12,16us per unit*/ + u16 ifs_clm_period; + boolean ifs_clm_th_en[IFS_CLM_NUM]; + u16 ifs_clm_th_low[IFS_CLM_NUM]; + u16 ifs_clm_th_high[IFS_CLM_NUM]; + /*Flow control*/ + u8 ifs_clm_set_lv; + u8 ifs_clm_manual_ctrl; + boolean ifs_clm_ongoing; + /*Report*/ + u8 ifs_clm_rpt_stamp; + u16 ifs_clm_tx; + u16 ifs_clm_edcca_excl_cca; + u16 ifs_clm_ofdmfa; + u16 ifs_clm_ofdmcca_excl_fa; + u16 ifs_clm_cckfa; + u16 ifs_clm_cckcca_excl_fa; + u8 ifs_clm_his[IFS_CLM_NUM]; /*trx_neg_edge to CCA/FA posedge per times*/ + u16 ifs_clm_total_cca; + u16 ifs_clm_avg[IFS_CLM_NUM]; /*4,8,12,16us per unit*/ + u16 ifs_clm_avg_cca[IFS_CLM_NUM]; /*4,8,12,16us per unit*/ + u8 ifs_clm_tx_ratio; + u8 ifs_clm_edcca_excl_cca_ratio; + u8 ifs_clm_fa_ratio; + u8 ifs_clm_cca_excl_fa_ratio; #endif }; @@ -232,14 +380,12 @@ void phydm_fahm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len); #endif -/*@NHM*/ #ifdef NHM_SUPPORT void phydm_nhm_dbg(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len); u8 phydm_get_igi(void *dm_void, enum bb_path path); #endif -/*@CLM*/ #ifdef CLM_SUPPORT void phydm_clm_c2h_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len); @@ -259,4 +405,25 @@ void phydm_env_monitor_init(void *dm_void); void phydm_env_mntr_dbg(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len); + +#ifdef IFS_CLM_SUPPORT +void phydm_ifs_clm_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); +#endif + +u8 phydm_enhance_mntr_trigger(void *dm_void, + struct nhm_para_info *nhm_para, + struct clm_para_info *clm_para, + struct fahm_para_info *fahm_para, + struct ifs_clm_para_info *ifs_clm_para, + struct enhance_mntr_trig_rpt *trig_rpt); + +u8 phydm_enhance_mntr_result(void *dm_void, struct enhance_mntr_rpt *rpt); + +void phydm_enhance_mntr_watchdog(void *dm_void); + +void phydm_enhance_monitor_init(void *dm_void); + +void phydm_enhance_mntr_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cfotracking.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cfotracking.c index dd8685e21f3c..6eb3384b4ba3 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cfotracking.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_cfotracking.c @@ -212,7 +212,7 @@ phydm_set_crystal_cap_reg(void *dm_void, u8 crystal_cap) u32 reg_val = 0; if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | - ODM_RTL8195B | ODM_RTL8812F | ODM_RTL8721D | ODM_RTL8710C)) { + ODM_RTL8195B | ODM_RTL8812F | ODM_RTL8721D | ODM_RTL8710C|ODM_RTL8723F)) { crystal_cap &= 0x7F; reg_val = crystal_cap | (crystal_cap << 7); } else { @@ -250,9 +250,9 @@ phydm_set_crystal_cap_reg(void *dm_void, u8 crystal_cap) } #endif #if (RTL8822B_SUPPORT || RTL8821C_SUPPORT || RTL8197F_SUPPORT ||\ - RTL8192F_SUPPORT || RTL8197G_SUPPORT) + RTL8192F_SUPPORT || RTL8197G_SUPPORT || RTL8198F_SUPPORT) else if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C | - ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8197G)) { + ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8197G | ODM_RTL8198F)) { /* write 0x24[30:25] = 0x28[6:1] = crystal_cap */ odm_set_mac_reg(dm, R_0x24, 0x7e000000, crystal_cap); odm_set_mac_reg(dm, R_0x28, 0x7e, crystal_cap); @@ -290,7 +290,12 @@ phydm_set_crystal_cap_reg(void *dm_void, u8 crystal_cap) phydm_set_crystalcap(dm, (u8)(reg_val & 0x7f)); } #endif - + #if (RTL8723F_SUPPORT) + else if (dm->support_ic_type & ODM_RTL8723F) { + /* write 0x103c[23:17] = 0x103c[16:10] = crystal_cap */ + odm_set_mac_reg(dm, R_0x103c, 0x00FFFC00, reg_val); + } + #endif #if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8812F_SUPPORT) else if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8812F)) { @@ -326,7 +331,7 @@ void phydm_cfo_tracking_reset(void *dm_void) PHYDM_DBG(dm, DBG_CFO_TRK, "%s ======>\n", __func__); if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8195B | - ODM_RTL8812F)) + ODM_RTL8812F|ODM_RTL8723F)) cfo_track->def_x_cap = cfo_track->crystal_cap_default & 0x7f; else cfo_track->def_x_cap = cfo_track->crystal_cap_default & 0x3f; @@ -367,7 +372,7 @@ void phydm_cfo_tracking_init(void *dm_void) PHYDM_DBG(dm, DBG_CFO_TRK, "[%s]=========>\n", __func__); if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8195B | - ODM_RTL8812F)) + ODM_RTL8812F|ODM_RTL8723F)) cfo_track->crystal_cap = cfo_track->crystal_cap_default & 0x7f; else cfo_track->crystal_cap = cfo_track->crystal_cap_default & 0x3f; @@ -482,7 +487,7 @@ void phydm_cfo_tracking(void *dm_void) crystal_cap -= 1; if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | - ODM_RTL8195B | ODM_RTL8812F)) { + ODM_RTL8195B | ODM_RTL8812F|ODM_RTL8723F)) { if (crystal_cap > 0x7F) crystal_cap = 0x7F; } else { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_debug.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_debug.c index 1d0b0f83ff91..56a15cfe1b59 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_debug.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_debug.c @@ -142,7 +142,6 @@ u8 phydm_set_bb_dbg_port(void *dm_void, u8 curr_dbg_priority, u32 debug_port) odm_set_bb_reg(dm, R_0x8fc, MASKDWORD, debug_port); } else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { odm_set_bb_reg(dm, R_0x1c3c, 0xfff00, debug_port); - } else { /*@if (dm->support_ic_type & ODM_IC_11N_SERIES)*/ odm_set_bb_reg(dm, R_0x908, MASKDWORD, debug_port); } @@ -746,10 +745,15 @@ void phydm_bb_hw_dbg_info_jgr3(void *dm_void, u32 *_used, char *output, "\r\n %-35s %s", "mode", tmp_string); /*@ [RX counter Info] ===============================================*/ - PDM_SNPF(out_len, used, output + used, out_len - used, - "\r\n %-35s = %d", "CCK CCA cnt", - odm_get_bb_reg(dm, R_0x2c08, 0xFFFF)); - + if (dm->support_ic_type & ODM_RTL8723F) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "\r\n %-35s = %d", "CCK CCA cnt", + odm_get_bb_reg(dm, R_0x2aa0, 0xFFFF)); + } else { + PDM_SNPF(out_len, used, output + used, out_len - used, + "\r\n %-35s = %d", "CCK CCA cnt", + odm_get_bb_reg(dm, R_0x2c08, 0xFFFF)); + } PDM_SNPF(out_len, used, output + used, out_len - used, "\r\n %-35s = %d", "OFDM CCA cnt", odm_get_bb_reg(dm, R_0x2c08, 0xFFFF0000)); @@ -1491,15 +1495,14 @@ void phydm_basic_dbg_msg_cli_win(void *dm_void, char *buf) fa_t->cnt_fast_fsync, fa_t->cnt_sb_search_fail); RT_PRINT(buf); - RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, - "\r\n [HT FA] HT_CRC8=%d, HT_MCS=%d", + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "\r\n [HT FA] CRC8=%d, MCS=%d", fa_t->cnt_crc8_fail, fa_t->cnt_mcs_fail); RT_PRINT(buf); #if (ODM_IC_11AC_SERIES_SUPPORT || defined(PHYDM_IC_JGR3_SERIES_SUPPORT)) if (dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES)) { RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, - "\r\n [VHT FA] VHT_SIGA_CRC8=%d, VHT_SIGB_CRC8=%d, VHT_MCS=%d", + "\r\n [VHT FA] SIGA_CRC8=%d, SIGB_CRC8=%d, MCS=%d", fa_t->cnt_crc8_fail_vhta, fa_t->cnt_crc8_fail_vhtb, fa_t->cnt_mcs_fail_vht); RT_PRINT(buf); @@ -1515,49 +1518,56 @@ void phydm_basic_dbg_msg_cli_win(void *dm_void, char *buf) RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, "\r\n [CRC32 Err Cnt] {CCK, OFDM, HT, VHT, Total} = {%d, %d, %d, %d, %d}", - fa_t->cnt_cck_crc32_error, - fa_t->cnt_ofdm_crc32_error, + fa_t->cnt_cck_crc32_error, fa_t->cnt_ofdm_crc32_error, fa_t->cnt_ht_crc32_error, fa_t->cnt_vht_crc32_error, fa_t->cnt_crc32_error_all); RT_PRINT(buf); + if (fa_t->ofdm2_rate_idx) { + phydm_print_rate_2_buff(dm, fa_t->ofdm2_rate_idx, + dbg_buf, PHYDM_SNPRINT_SIZE); + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, + "\r\n [OFDM:%s CRC32 Cnt] {error, ok}= {%d, %d} (%d percent)", + dbg_buf, fa_t->cnt_ofdm2_crc32_error, + fa_t->cnt_ofdm2_crc32_ok, fa_t->ofdm2_pcr); + RT_PRINT(buf); + } + + if (fa_t->ht2_rate_idx) { + phydm_print_rate_2_buff(dm, fa_t->ht2_rate_idx, dbg_buf, + PHYDM_SNPRINT_SIZE); + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, + "\r\n [HT :%s CRC32 Cnt] {error, ok}= {%d, %d} (%d percent)", + dbg_buf, fa_t->cnt_ht2_crc32_error, + fa_t->cnt_ht2_crc32_ok, fa_t->ht2_pcr); + RT_PRINT(buf); + } + #if (ODM_IC_11AC_SERIES_SUPPORT || defined(PHYDM_IC_JGR3_SERIES_SUPPORT)) if (dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES)) { - if (fa_t->ofdm2_rate_idx) { - phydm_print_rate_2_buff(dm, fa_t->ofdm2_rate_idx, - dbg_buf, PHYDM_SNPRINT_SIZE); - RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, - "\r\n [OFDM:%s CRC32 Cnt] {error, ok}= {%d, %d}", - dbg_buf, fa_t->cnt_ofdm2_crc32_error, - fa_t->cnt_ofdm2_crc32_ok); - RT_PRINT(buf); - } - - if (fa_t->ht2_rate_idx) { - phydm_print_rate_2_buff(dm, fa_t->ht2_rate_idx, dbg_buf, - PHYDM_SNPRINT_SIZE); - RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, - "\r\n [HT :%s CRC32 Cnt] {error, ok}= {%d, %d}", - dbg_buf, fa_t->cnt_ht2_crc32_error, - fa_t->cnt_ht2_crc32_ok); - RT_PRINT(buf); - } - if (fa_t->vht2_rate_idx) { phydm_print_rate_2_buff(dm, fa_t->vht2_rate_idx, dbg_buf, PHYDM_SNPRINT_SIZE); RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, - "\r\n [VHT :%s CRC32 Cnt] {error, ok}= {%d, %d}", + "\r\n [VHT :%s CRC32 Cnt] {error, ok}= {%d, %d} (%d percent)", dbg_buf, fa_t->cnt_vht2_crc32_error, - fa_t->cnt_vht2_crc32_ok); + fa_t->cnt_vht2_crc32_ok, fa_t->vht2_pcr); RT_PRINT(buf); } } #endif - RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, - "\r\n is_linked = %d, Num_client = %d, rssi_min = %d, IGI = 0x%x, bNoisy=%d\n", - dm->is_linked, dm->number_linked_client, dm->rssi_min, - dm->dm_dig_table.cur_ig_value, dm->noisy_decision); + + if (dm->support_ic_type & (ODM_IC_11N_SERIES | ODM_IC_11AC_SERIES)) + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, + "\r\n is_linked = %d, Num_client = %d, rssi_min = %d, IGI = 0x%x, bNoisy=%d\n", + dm->is_linked, dm->number_linked_client, dm->rssi_min, + dm->dm_dig_table.cur_ig_value, dm->noisy_decision); + else + RT_SPRINTF(buf, DBGM_CLI_BUF_SIZE, + "\r\n is_linked = %d, Num_client = %d, rssi_min = %d, IGI = 0x%x\n", + dm->is_linked, dm->number_linked_client, dm->rssi_min, + dm->dm_dig_table.cur_ig_value); + RT_PRINT(buf); phydm_dm_summary_cli_win(dm, buf, target_macid); @@ -2211,7 +2221,7 @@ void phydm_get_avg_phystatus_val(void *dm_void) if (dbg_s->rssi_cck_cnt) { dbg_avg->rssi_cck_avg = (u8)(dbg_s->rssi_cck_sum / dbg_s->rssi_cck_cnt); - #ifdef PHYSTS_3RD_TYPE_SUPPORT + #if (defined(PHYSTS_3RD_TYPE_SUPPORT) && defined(PHYDM_COMPILE_ABOVE_2SS)) if (dm->support_ic_type & PHYSTS_3RD_TYPE_IC) { for (i = 0; i < dm->num_rf_path - 1; i++) { avg_tmp = dbg_s->rssi_cck_sum_abv_2ss[i] / @@ -2310,7 +2320,8 @@ void phydm_basic_dbg_msg_linked(void *dm_void) #ifdef ODM_IC_11N_SERIES_SUPPORT #ifdef PHYDM_PRIMARY_CCA if (((*dm->channel <= 14) && (*dm->band_width == CHANNEL_WIDTH_40)) && - (dm->support_ic_type & ODM_IC_11N_SERIES)) { + (dm->support_ic_type & ODM_IC_11N_SERIES) && + (dm->support_ability & ODM_BB_PRIMARY_CCA)) { PHYDM_DBG(dm, DBG_CMN, "Primary CCA at ((%s SB))\n", ((*dm->sec_ch_offset == SECOND_CH_AT_LSB) ? "U" : "L")); @@ -2420,9 +2431,9 @@ void phydm_basic_dbg_msg_linked(void *dm_void) (dbg_t->is_stbc_pkt) ? "Y" : "N"); #endif -#if (RTL8822C_SUPPORT) +#if (RTL8822C_SUPPORT || RTL8723F_SUPPORT) /*Beamformed pkt*/ - if (dm->support_ic_type == ODM_RTL8822C) + if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8723F)) PHYDM_DBG(dm, DBG_CMN, "Beamformed=((%s))\n", (dm->is_beamformed) ? "Y" : "N"); #endif @@ -2609,13 +2620,12 @@ void phydm_basic_dbg_message(void *dm_void) "[OFDM FA] Parity=%d, Rate=%d, Fast_Fsync=%d, SBD=%d\n", fa_t->cnt_parity_fail, fa_t->cnt_rate_illegal, fa_t->cnt_fast_fsync, fa_t->cnt_sb_search_fail); - PHYDM_DBG(dm, DBG_CMN, - "[HT FA] HT_CRC8=%d, HT_MCS=%d\n", + PHYDM_DBG(dm, DBG_CMN, "[HT FA] CRC8=%d, MCS=%d\n", fa_t->cnt_crc8_fail, fa_t->cnt_mcs_fail); #if (ODM_IC_11AC_SERIES_SUPPORT || defined(PHYDM_IC_JGR3_SERIES_SUPPORT)) if (dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES)) { PHYDM_DBG(dm, DBG_CMN, - "[VHT FA] VHT_SIGA_CRC8=%d, VHT_SIGB_CRC8=%d, VHT_MCS=%d\n", + "[VHT FA] SIGA_CRC8=%d, SIGB_CRC8=%d, MCS=%d\n", fa_t->cnt_crc8_fail_vhta, fa_t->cnt_crc8_fail_vhtb, fa_t->cnt_mcs_fail_vht); } @@ -2631,10 +2641,16 @@ void phydm_basic_dbg_message(void *dm_void) fa_t->cnt_ht_crc32_error, fa_t->cnt_vht_crc32_error, fa_t->cnt_crc32_error_all); - PHYDM_DBG(dm, DBG_CMN, - "is_linked = %d, Num_client = %d, rssi_min = %d, IGI = 0x%x, bNoisy=%d\n", - dm->is_linked, dm->number_linked_client, dm->rssi_min, - dm->dm_dig_table.cur_ig_value, dm->noisy_decision); + if (dm->support_ic_type & (ODM_IC_11N_SERIES | ODM_IC_11AC_SERIES)) + PHYDM_DBG(dm, DBG_CMN, + "is_linked = %d, Num_client = %d, rssi_min = %d, IGI = 0x%x, bNoisy=%d\n", + dm->is_linked, dm->number_linked_client, dm->rssi_min, + dm->dm_dig_table.cur_ig_value, dm->noisy_decision); + else + PHYDM_DBG(dm, DBG_CMN, + "is_linked = %d, Num_client = %d, rssi_min = %d, IGI = 0x%x\n", + dm->is_linked, dm->number_linked_client, dm->rssi_min, + dm->dm_dig_table.cur_ig_value); #ifdef NHM_SUPPORT if (dm->support_ability & ODM_BB_ENV_MONITOR) { @@ -2812,6 +2828,14 @@ void phydm_basic_profile(void *dm_void, u32 *_used, char *output, u32 *_out_len) } #endif +#if (RTL8723F_SUPPORT) + else if (dm->support_ic_type == ODM_RTL8723F) { + ic_type = "RTL8723F"; + date = RELEASE_DATE_8723F; + commit_by = COMMIT_BY_8723F; + release_ver = RELEASE_VERSION_8723F; + } +#endif #if (RTL8812F_SUPPORT) else if (dm->support_ic_type == ODM_RTL8812F) { ic_type = "RTL8812F"; @@ -2900,6 +2924,10 @@ void phydm_basic_profile(void *dm_void, u32 *_used, char *output, u32 *_out_len) "% PHYDM version %"); PDM_SNPF(out_len, used, output + used, out_len - used, " %-35s: %s\n", "Code base", PHYDM_CODE_BASE); +#ifdef PHYDM_SVN_REV + PDM_SNPF(out_len, used, output + used, out_len - used, " %-35s: %s\n", + "PHYDM SVN Ver", PHYDM_SVN_REV); +#endif PDM_SNPF(out_len, used, output + used, out_len - used, " %-35s: %s\n", "Release Date", PHYDM_RELEASE_DATE); PDM_SNPF(out_len, used, output + used, out_len - used, " %-35s: %s\n", @@ -3185,6 +3213,10 @@ void phydm_set_txagc(void *dm_void, u32 *const val, u32 *_used, pow = (val[3] & 0x3f); for (i = 0; i <= ODM_RATEMCS7; i++) rpt &= phydm_api_set_txagc(dm, pow, path, i, 0); + } else if (dm->support_ic_type &(ODM_RTL8723F)) { + pow = (val[3] & 0x7f); + for (i = 0; i <= ODM_RATEMCS7; i++) + rpt &= phydm_api_set_txagc(dm, pow, path, i, 0); } if (rpt) @@ -3294,7 +3326,7 @@ void phydm_shift_txagc(void *dm_void, u32 *const val, u32 *_used, char *output, } } else if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | - ODM_RTL8812F | ODM_RTL8197G)) { + ODM_RTL8812F | ODM_RTL8197G | ODM_RTL8723F)) { rpt &= phydm_api_shift_txagc(dm, val[3], path, 1); } } @@ -3326,10 +3358,8 @@ void phydm_set_txagc_dbg(void *dm_void, char input[][16], u32 *_used, u8 i = 0, input_idx = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + input_idx++; } if ((strcmp(input[1], help) == 0)) { @@ -3437,7 +3467,6 @@ void phydm_debug_trace(void *dm_void, char input[][16], u32 *_used, u8 i = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); } comp = dm->debug_components; @@ -3587,10 +3616,8 @@ void phydm_fw_debug_trace(void *dm_void, char input[][16], u32 *_used, u32 comp = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); + input_idx++; } if (input_idx == 0) @@ -3735,10 +3762,34 @@ void phydm_dump_bb_reg_jgr3(void *dm_void, u32 *_used, char *output, out_len - used, "0x%04x 0x%08x\n", addr, odm_get_bb_reg(dm, addr, MASKDWORD)); + #if (defined(RTL8723F_SUPPORT)) + if (dm->support_ic_type & ODM_RTL8723F) { + for (addr = 0x2a00; addr < 0x2a5c; addr += 4) { + PDM_VAST_SNPF(out_len, used, output + used, + out_len - used, "0x%04x 0x%08x\n", + addr, + odm_get_bb_reg(dm, addr, + MASKDWORD)); + } + } + #endif + for (addr = 0x4000; addr < 0x41ff; addr += 4) PDM_VAST_SNPF(out_len, used, output + used, out_len - used, "0x%04x 0x%08x\n", addr, odm_get_bb_reg(dm, addr, MASKDWORD)); + + #if (defined(RTL8723F_SUPPORT)) + if (dm->support_ic_type & ODM_RTL8723F) { + for (addr = 0x4300; addr < 0x43bf; addr += 4) { + PDM_VAST_SNPF(out_len, used, output + used, + out_len - used, "0x%04x 0x%08x\n", + addr, + odm_get_bb_reg(dm, addr, + MASKDWORD)); + } + } + #endif } *_used = used; *_out_len = out_len; @@ -3765,9 +3816,22 @@ void phydm_dump_bb_reg2_jgr3(void *dm_void, u32 *_used, char *output, } } #endif + /* @Do not change the order of page-2C/2D*/ PDM_VAST_SNPF(out_len, used, output + used, out_len - used, "------ BB report-register start ------\n"); + + #if (defined(RTL8723F_SUPPORT)) + if (dm->support_ic_type & ODM_RTL8723F) { + for (addr = 0x2aa0; addr < 0x2aff; addr += 4) { + PDM_VAST_SNPF(out_len, used, output + used, + out_len - used, "0x%04x 0x%08x\n", + addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + } + } + #endif + for (addr = 0x2c00; addr < 0x2dff; addr += 4) { PDM_VAST_SNPF(out_len, used, output + used, out_len - used, "0x%04x 0x%08x\n", @@ -3836,6 +3900,47 @@ void phydm_get_per_path_anapar_jgr3(void *dm_void, u8 path, u32 *_used, *_out_len = out_len; } +void phydm_get_csi_table_jgr3(void *dm_void, u32 *_used, char *output, + u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u8 table_idx = 0; + u8 table_val = 0; + u32 used = *_used; + u32 out_len = *_out_len; + u32 dbgport_idx = 0x39e; + u32 dbgport_val = 0; + + /*enable clk*/ + odm_set_bb_reg(dm, R_0x1ee8, 0x3, 0x3); + /*enable read table*/ + odm_set_bb_reg(dm, R_0x1d94, BIT(31) | BIT(30), 0x2); + + for (table_idx = 0; table_idx < 128; table_idx++) { + odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, table_idx); + if (phydm_set_bb_dbg_port(dm, DBGPORT_PRI_3, dbgport_idx)) { + dbgport_val = phydm_get_bb_dbg_port_val(dm); + phydm_release_bb_dbg_port(dm); + } else { + PDM_VAST_SNPF(out_len, used, output + used, + out_len - used, + "table_idx:0x%x = read dbg_port error!\n", + table_idx); + } + table_val = dbgport_val >> 24; + PDM_VAST_SNPF(out_len, used, output + used, out_len - used, + "table_idx: 0x%x = 0x%x\n", + table_idx, table_val); + } + /*enable write table*/ + odm_set_bb_reg(dm, R_0x1d94, BIT(31) | BIT(30), 0x1); + /*disable clk*/ + odm_set_bb_reg(dm, R_0x1ee8, 0x3, 0x0); + + *_used = used; + *_out_len = out_len; +} + #endif void phydm_dump_bb_reg(void *dm_void, u32 *_used, char *output, u32 *_out_len) @@ -3975,8 +4080,7 @@ void phydm_dump_reg(void *dm_void, char input[][16], u32 *_used, char *output, u32 out_len = *_out_len; u32 addr = 0; - if (input[1]) - PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); if ((strcmp(input[1], help) == 0)) { #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT @@ -4054,7 +4158,7 @@ void phydm_show_rx_rate(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len) { #if (RTL8822B_SUPPORT || RTL8821C_SUPPORT || RTL8814B_SUPPORT ||\ - RTL8195B_SUPPORT || RTL8822C_SUPPORT) + RTL8195B_SUPPORT || RTL8822C_SUPPORT || RTL8723F_SUPPORT) struct dm_struct *dm = (struct dm_struct *)dm_void; struct odm_phy_dbg_info *dbg = &dm->phy_dbg_info; u32 used = *_used; @@ -4064,10 +4168,8 @@ void phydm_show_rx_rate(void *dm_void, char input[][16], u32 *_used, u8 i, input_idx = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + input_idx++; } if (input_idx == 0) @@ -4157,8 +4259,7 @@ void phydm_per_tone_evm(void *dm_void, char input[][16], u32 *_used, } for (i = 0; i < 4; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); } avg_num = var1[0]; @@ -4379,8 +4480,7 @@ void phydm_bw_ch_adjust(void *dm_void, char input[][16], } for (i = 0; i < 4; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); } is_enable_dbg_mode = (boolean)var1[0]; @@ -4411,10 +4511,8 @@ void phydm_ext_rf_element_ctrl(void *dm_void, char input[][16], u32 *_used, u8 i = 0, input_idx = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &val[i]); + input_idx++; } if (input_idx == 0) @@ -4496,6 +4594,27 @@ void phydm_get_anapar_table(void *dm_void, u32 *_used, char *output, *_out_len = out_len; } +void phydm_get_csi_table(void *dm_void, u32 *_used, char *output, + u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 used = *_used; + u32 out_len = *_out_len; + +#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT + if (!(dm->support_ic_type & ODM_IC_JGR3_SERIES)) + return; + + PDM_VAST_SNPF(out_len, used, output + used, out_len - used, + "------ CSI Table Parsing start ------\n"); + + phydm_get_csi_table_jgr3(dm, &used, output, &out_len); +#endif + + *_used = used; + *_out_len = out_len; +} + void phydm_dd_dbg_dump(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len) { @@ -4837,8 +4956,7 @@ void phydm_reg_monitor(void *dm_void, char input[][16], u32 *_used, u8 i = 0; for (i = 0; i < 7; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); } if ((strcmp(input[1], help) == 0)) { @@ -4912,8 +5030,7 @@ void phydm_get_rxagc_table_dbg(void *dm_void, char input[][16], u32 *_used, "get rxagc table : {0:ori, 1:modified} {table:0~15} {mp_gain_idx:0~63, all:0xff}\n"); } else { for (i = 0; i < 3; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); } is_modified = (boolean)var1[0]; @@ -4969,9 +5086,8 @@ void phydm_shift_rxagc_table_dbg(void *dm_void, char input[][16], u32 *_used, "shift rxagc table : {0:-, 1:+} {value(0~63, unit:2dB)}\n"); } else { for (i = 0; i < 3; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, - &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); } if ((u8)var1[1] > 63) { @@ -4990,7 +5106,7 @@ void phydm_shift_rxagc_table_dbg(void *dm_void, char input[][16], u32 *_used, #endif } -#if RTL8814B_SUPPORT +#if (RTL8814B_SUPPORT || RTL8198F_SUPPORT) void phydm_spur_detect_dbg(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len) { @@ -5008,10 +5124,13 @@ void phydm_spur_detect_dbg(void *dm_void, char input[][16], u32 *_used, "2: CSI always On/ NBI Auto, 3: Disable, 4: CSI & NBI ON}\n"); PDM_SNPF(out_len, used, output + used, out_len - used, "{If CSI always ON (Mode 2 or 4) -> CSI wgt manual(0~7)}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "{5: Adjust CSI weight threshold} {0:-,1:+} {th offset}\n"); } else { for (i = 0; i < 10; i++) { if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); } if (var1[0] == 1) { @@ -5024,13 +5143,31 @@ void phydm_spur_detect_dbg(void *dm_void, char input[][16], u32 *_used, dm->dsde_sel = DET_CSI_NBI_EN; } else if (var1[0] == 0) { dm->dsde_sel = DET_AUTO; + } else if (var1[0] == 5) { + if (var1[1] == 0) + for (i = 0; i < 5; i++) + dm->csi_wgt_th_db[i] -= (u8)var1[2]; + else if (var1[1] == 1) + for (i = 0; i < 5; i++) + dm->csi_wgt_th_db[i] += (u8)var1[2]; + PDM_SNPF(out_len, used, output + used, out_len - used, "current csi weight threshold:\n"); + for (i = 0; i < 5; i++) + PDM_SNPF(out_len, used, output + used, + out_len - used, "----%2d", + dm->csi_wgt_th_db[i]); + PDM_SNPF(out_len, used, output + used, out_len - used, "\n"); + for (i = 0; i < 5; i++) + PDM_SNPF(out_len, used, output + used, + out_len - used, "--%d--|", i); + PDM_SNPF(out_len, used, output + used, out_len - used, "\n"); } else { PDM_SNPF(out_len, used, output + used, out_len - used, "Spur detection mode invalid!\n"); return; } - PDM_SNPF(out_len, used, output + used, out_len - used, - "spur detect mode = %d\n", dm->dsde_sel); + if (var1[0] < 5) + PDM_SNPF(out_len, used, output + used, out_len - used, + "spur detect mode = %d\n", dm->dsde_sel); if (dm->dsde_sel == DET_CSI_NBI_EN) { if (var1[1] < 8) { @@ -5114,9 +5251,20 @@ enum PHYDM_CMD_ID { PHYDM_SPUR_DETECT, #endif PHYDM_PHY_STATUS, - PHYDM_FA_CNT, + PHYDM_CRC32_CNT, + PHYDM_DCC, +#ifdef PHYDM_HW_IGI + PHYDM_HWIGI, +#endif +#ifdef PHYDM_HW_SWITCH_AGC_TAB + PHYDM_HW_AGCTAB, +#endif + PHYDM_PMAC_TX, PHYDM_GET_RXAGC, - PHYDM_SHIFT_RXAGC + PHYDM_SHIFT_RXAGC, + PHYDM_IFS_CLM, + PHYDM_ENHANCE_MNTR, + PHYDM_CSI_DBG }; struct phydm_command phy_dm_ary[] = { @@ -5176,9 +5324,22 @@ struct phydm_command phy_dm_ary[] = { {"spur_detect", PHYDM_SPUR_DETECT}, #endif {"physts", PHYDM_PHY_STATUS}, - {"fa_cnt", PHYDM_FA_CNT}, + {"crc32_cnt", PHYDM_CRC32_CNT}, +#ifdef PHYDM_PMAC_TX_SETTING_SUPPORT + {"pmac_tx", PHYDM_PMAC_TX}, +#endif +#ifdef PHYDM_HW_IGI + {"hwigi", PHYDM_HWIGI}, +#endif +#ifdef PHYDM_HW_SWITCH_AGC_TAB + {"hw_agctab", PHYDM_HW_AGCTAB}, +#endif + {"dcc", PHYDM_DCC}, {"get_rxagc", PHYDM_GET_RXAGC}, - {"shift_rxagc", PHYDM_SHIFT_RXAGC} + {"shift_rxagc", PHYDM_SHIFT_RXAGC}, + {"ifs_clm", PHYDM_IFS_CLM}, + {"enh_mntr", PHYDM_ENHANCE_MNTR}, + {"csi_dbg", PHYDM_CSI_DBG} }; #endif /*@#ifdef CONFIG_PHYDM_DEBUG_FUNCTION*/ @@ -5451,8 +5612,7 @@ void phydm_cmd_parser(struct dm_struct *dm, char input[][MAX_ARGV], break; case PHYDM_DIS_HTSTF_CONTROL: { - if (input[1]) - PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); if (var1[0] == 1) { /* setting being false is for debug */ @@ -5538,18 +5698,49 @@ void phydm_cmd_parser(struct dm_struct *dm, char input[][MAX_ARGV], phydm_spur_detect_dbg(dm, input, &used, output, &out_len); break; #endif - case PHYDM_FA_CNT: - phydm_fa_cnt_dbg(dm, input, &used, output, &out_len); + case PHYDM_CRC32_CNT: + phydm_crc32_cnt_dbg(dm, input, &used, output, &out_len); break; case PHYDM_PHY_STATUS: phydm_physts_dbg(dm, input, &used, output, &out_len); break; +#ifdef PHYDM_DCC_ENHANCE + case PHYDM_DCC: + phydm_dig_cckpd_coex_dbg(dm, input, &used, output, &out_len); + break; +#endif +#ifdef PHYDM_PMAC_TX_SETTING_SUPPORT + case PHYDM_PMAC_TX: + phydm_pmac_tx_dbg(dm, input, &used, output, &out_len); + break; +#endif +#ifdef PHYDM_HW_IGI + case PHYDM_HWIGI: + phydm_hwigi_dbg(dm, input, &used, output, &out_len); + break; +#endif +#ifdef PHYDM_HW_SWITCH_AGC_TAB + case PHYDM_HW_AGCTAB: + phydm_auto_agc_tab_debug(dm, input, &used, output, &out_len); + break; +#endif case PHYDM_GET_RXAGC: phydm_get_rxagc_table_dbg(dm, input, &used, output, &out_len); break; case PHYDM_SHIFT_RXAGC: phydm_shift_rxagc_table_dbg(dm, input, &used, output, &out_len); break; + case PHYDM_IFS_CLM: + #ifdef IFS_CLM_SUPPORT + phydm_ifs_clm_dbg(dm, input, &used, output, &out_len); + #endif + break; + case PHYDM_ENHANCE_MNTR: + phydm_enhance_mntr_dbg(dm, input, &used, output, &out_len); + break; + case PHYDM_CSI_DBG: + phydm_get_csi_table(dm, &used, output, &out_len); + break; default: PDM_SNPF(out_len, used, output + used, out_len - used, "Do not support this command\n"); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_debug.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_debug.h index daf52a644e23..25ae1da827d3 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_debug.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_debug.h @@ -32,8 +32,8 @@ /*#define DEBUG_VERSION "1.3"*/ /*2016.04.28 YuChen*/ /*#define DEBUG_VERSION "1.4"*/ /*2017.03.13 Dino*/ /*#define DEBUG_VERSION "2.0"*/ /*2018.01.10 Dino*/ -/* 2019.07.01 Move location of nhm_level msg in win_cli*/ -#define DEBUG_VERSION "3.8" +/*2020.07.03 fix cck report bug due to 8723F coding error*/ +#define DEBUG_VERSION "4.6" /*@ * ============================================================ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dfs.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dfs.c index cc5703d5a2c0..ab7ee27f3782 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dfs.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dfs.c @@ -74,7 +74,7 @@ void phydm_radar_detect_reset(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8822C | ODM_RTL8812F | - ODM_RTL8197G)) { + ODM_RTL8197G | ODM_RTL8723F)) { odm_set_bb_reg(dm, R_0xa40, BIT(15), 0); odm_set_bb_reg(dm, R_0xa40, BIT(15), 1); #if (RTL8721D_SUPPORT) @@ -101,7 +101,7 @@ void phydm_radar_detect_disable(void *dm_void) struct dm_struct *dm = (struct dm_struct *)dm_void; if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8822C | ODM_RTL8812F | - ODM_RTL8197G)) + ODM_RTL8197G | ODM_RTL8723F)) odm_set_bb_reg(dm, R_0xa40, BIT(15), 0); else if (dm->support_ic_type & (ODM_RTL8814B)) { if (dm->seg1_dfs_flag == 1) { @@ -636,7 +636,7 @@ void phydm_dfs_parameter_init(void *dm_void) /*@for dynamic dfs*/ dfs->pwdb_th = 8; - dfs->fa_mask_th = 30 * (dfs->dfs_polling_time / 100); + dfs->fa_mask_th = 30 * (dfs->dfs_polling_time) / 100; dfs->st_l2h_min = 0x20; dfs->st_l2h_max = 0x4e; dfs->pwdb_scalar_factor = 12; @@ -900,7 +900,7 @@ phydm_radar_detect_dm_check( index = 5 + dfs->mask_idx - 2; if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8822C | ODM_RTL8812F | - ODM_RTL8197G)) { + ODM_RTL8197G| ODM_RTL8723F)) { radar_rpt_reg_value = odm_get_bb_reg(dm, R_0x2e00, 0xffffffff); short_pulse_cnt_cur = (u16)((radar_rpt_reg_value & 0x000ff800) >> 11); @@ -1059,7 +1059,7 @@ phydm_radar_detect_dm_check( fa_mask_th = dfs->fa_mask_th; } if (total_fa_in_hist >= fa_mask_th || dfs->igi_cur >= 0x30) { - st_l2h_new = dfs->st_l2h_max; + /* st_l2h_new = dfs->st_l2h_max; */ dfs->radar_det_mask_hist[index] = 1; if (dfs->pulse_flag_hist[index] == 1) { dfs->pulse_flag_hist[index] = 0; @@ -1951,9 +1951,8 @@ void phydm_dfs_hist_dbg(void *dm_void, char input[][16], u32 *_used, PHYDM_SSCANF(input[1], DCMD_DECIMAL, &argv[0]); for (i = 1; i < 5; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, - &argv[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &argv[i]); } if (argv[0] == 0) { dfs->pri_hist_th = (u8)argv[1]; @@ -2112,10 +2111,8 @@ void phydm_dfs_debug(void *dm_void, char input[][16], u32 *_used, u8 i, input_idx = 0; for (i = 0; i < 7; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &argv[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &argv[i]); + input_idx++; } if (input_idx == 0) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dig.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dig.c index 63b1ea00b8dd..e35ecbf849d1 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dig.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dig.c @@ -348,7 +348,10 @@ void phydm_fa_cnt_statistics_jgr3(void *dm_void) fa_t->cnt_mcs_fail = ret_value & 0xffff; /* read CCK CRC32 counter */ - ret_value = odm_get_bb_reg(dm, R_0x2c04, MASKDWORD); + if (dm->support_ic_type & ODM_RTL8723F) + ret_value = odm_get_bb_reg(dm, R_0x2aac, MASKDWORD); + else + ret_value = odm_get_bb_reg(dm, R_0x2c04, MASKDWORD); fa_t->cnt_cck_crc32_ok = ret_value & 0xffff; fa_t->cnt_cck_crc32_error = (ret_value & 0xffff0000) >> 16; @@ -408,15 +411,26 @@ void phydm_fa_cnt_statistics_jgr3(void *dm_void) fa_t->cnt_mcs_fail_vht + fa_t->cnt_crc8_fail_vhta; /* Read CCK FA counter */ - fa_t->cnt_cck_fail = odm_get_bb_reg(dm, R_0x1a5c, MASKLWORD); + if (dm->support_ic_type & ODM_RTL8723F){ + ret_value= odm_get_bb_reg(dm, R_0x2aa8, MASKLWORD); + fa_t->cnt_cck_fail=(ret_value&0xffff)+((ret_value&0xffff0000)>>16); + } + else + fa_t->cnt_cck_fail = odm_get_bb_reg(dm, R_0x1a5c, MASKLWORD); /* read CCK/OFDM CCA counter */ ret_value = odm_get_bb_reg(dm, R_0x2c08, MASKDWORD); fa_t->cnt_ofdm_cca = ((ret_value & 0xffff0000) >> 16); + if (dm->support_ic_type & ODM_RTL8723F) + ret_value = odm_get_bb_reg(dm, R_0x2aa0, MASKDWORD); fa_t->cnt_cck_cca = ret_value & 0xffff; /* @CCK RxIQ weighting = 1 => 0x1a14[9:8]=0x0 */ - cck_enable = odm_get_bb_reg(dm, R_0x1a14, 0x300); + if (dm->support_ic_type & ODM_RTL8723F) + cck_enable = odm_get_bb_reg(dm, R_0x2a24, BIT(13)); + else + cck_enable = odm_get_bb_reg(dm, R_0x1a14, 0x300); + if (cck_enable == 0x0) { /* @if(*dm->band_type == ODM_BAND_2_4G) */ fa_t->cnt_all = fa_t->cnt_ofdm_fail + fa_t->cnt_cck_fail; fa_t->cnt_cca_all = fa_t->cnt_cck_cca + fa_t->cnt_ofdm_cca; @@ -482,6 +496,16 @@ void phydm_write_dig_reg(void *dm_void, u8 igi) } #endif + if (igi == dig_t->cur_ig_value) + dig_t->igi_trend = DIG_STABLE; + else if (igi > dig_t->cur_ig_value) + dig_t->igi_trend = DIG_INCREASING; + else + dig_t->igi_trend = DIG_DECREASING; + + PHYDM_DBG(dm, DBG_DIG, "Update IGI:0x%x -> 0x%x\n", + dig_t->cur_ig_value, igi); + dig_t->cur_ig_value = igi; } @@ -542,9 +566,14 @@ void odm_write_dig(void *dm_void, u8 new_igi) } } phydm_write_dig_reg(dm, new_igi); + } else { + dig_t->igi_trend = DIG_STABLE; } - PHYDM_DBG(dm, DBG_DIG, "New_igi=((0x%x))\n\n", new_igi); + PHYDM_DBG(dm, DBG_DIG, "[%s]New_igi=((0x%x))\n\n", + ((dig_t->igi_trend == DIG_STABLE) ? "=" : + ((dig_t->igi_trend == DIG_INCREASING) ? "+" : "-")), + new_igi); } u8 phydm_get_igi_reg_val(void *dm_void, enum bb_path path) @@ -664,6 +693,11 @@ phydm_dig_abort(void *dm_void) return true; } + if (dm->dm_dig_table.fw_dig_enable) { + PHYDM_DBG(dm, DBG_DIG, "Return: FW DIG enable\n"); + return true; + } + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) #if OS_WIN_FROM_WIN7(OS_VERSION) if (IsAPModeExist(adapter) && ((PADAPTER)(adapter))->bInHctTest) { @@ -676,6 +710,274 @@ phydm_dig_abort(void *dm_void) return false; } +#ifdef PHYDM_HW_IGI +#ifdef BB_RAM_SUPPORT +void phydm_rd_hwigi_pre_setting(void *dm_void, u32 *_used, char *output, + u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 used = *_used; + u32 out_len = *_out_len; + u8 igi_ofst = 0x0; + u32 t1, t2, t3 = 0x0; + + igi_ofst = (u8)odm_get_bb_reg(dm, R_0x1e80, MASKBYTE0); + t1 = odm_get_bb_reg(dm, R_0x1e80, MASKBYTE1) * 400; + t2 = odm_get_bb_reg(dm, R_0x1e80, MASKBYTE2) * 400; + t3 = odm_get_bb_reg(dm, R_0x1e80, MASKBYTE3) * 400; + + PDM_SNPF(out_len, used, output + used, out_len - used, + "igi_offset:0x%x, t1:%d(ns), t2:%d(ns), t3:%d(ns)\n", + igi_ofst, t1, t2, t3); +} + +void phydm_set_hwigi_pre_setting(void *dm_void, u8 igi_ofst, u8 t1, u8 t2, + u8 t3) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 reg_0x1e80 = 0; + + reg_0x1e80 = igi_ofst + (t1 << 8) + (t2 << 16) + (t3 << 24); + odm_set_bb_reg(dm, R_0x1e80, MASKDWORD, reg_0x1e80); +} + +void phydm_rd_hwigi_table(void *dm_void, u8 macid, u32 *_used, char *output, + u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 used = *_used; + u32 out_len = *_out_len; + boolean hwigi_en = false; + u8 hwigi = 0x0; + u8 hwigi_rx_offset = 0x0; + u32 reg_0x1e84 = 0x0; + + reg_0x1e84 |= (macid & 0x3f) << 24; /*macid*/ + reg_0x1e84 |= BIT(31); /*read_en*/ + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, reg_0x1e84); + + hwigi_en = (boolean)odm_get_bb_reg(dm, R_0x2de8, BIT(15)); + hwigi = (u8)odm_get_bb_reg(dm, R_0x2de8, 0x7f00); + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, 0x0); /* disable rd/wt*/ + + PDM_SNPF(out_len, used, output + used, out_len - used, + "(macid:%d) hwigi_en:%d, hwigi:0x%x\n", macid, hwigi_en, + hwigi); + + *_used = used; + *_out_len = out_len; +} + +void phydm_wt_hwigi_table(void *dm_void, u8 macid, boolean hwigi_en, u8 hwigi) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_bb_ram_per_sta *dm_ram_per_sta = NULL; + u32 reg_0x1e84 = 0; + + if (macid > 63) + macid = 63; + + dm_ram_per_sta = &dm->p_bb_ram_ctrl.pram_sta_ctrl[macid]; + dm_ram_per_sta->hw_igi_en = hwigi_en; + dm_ram_per_sta->hw_igi = hwigi; + + reg_0x1e84 = (dm_ram_per_sta->tx_pwr_offset0_en << 15) + + ((dm_ram_per_sta->tx_pwr_offset0 & 0x7f) << 8) + + (dm_ram_per_sta->tx_pwr_offset1_en << 23) + + ((dm_ram_per_sta->tx_pwr_offset1 & 0x7f) << 16); + + reg_0x1e84 |= (hwigi_en << 7) + (hwigi & 0x7f); + reg_0x1e84 |= (macid & 0x3f) << 24;/*macid*/ + reg_0x1e84 |= BIT(30); /*write_en*/ + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, reg_0x1e84); + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, 0x80000000); /*read_en*/ + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, 0x0); /*disable rd/wt*/ +} + +void phydm_rst_hwigi(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_bb_ram_per_sta *dm_ram_per_sta = NULL; + u32 reg_0x1e84 = 0; + u8 i = 0; + + PHYDM_DBG(dm, DBG_DIG, "reset hwigi!\n"); + + for (i = 0; i < 64; i++) { + dm_ram_per_sta = &dm->p_bb_ram_ctrl.pram_sta_ctrl[i]; + dm_ram_per_sta->hw_igi_en = false; + dm_ram_per_sta->hw_igi = 0x0; + + reg_0x1e84 = (dm_ram_per_sta->tx_pwr_offset0_en << 15) + + ((dm_ram_per_sta->tx_pwr_offset0 & 0x7f) << 8) + + (dm_ram_per_sta->tx_pwr_offset1_en << 23) + + ((dm_ram_per_sta->tx_pwr_offset1 & 0x7f) << 16); + + reg_0x1e84 |= (i & 0x3f) << 24; + reg_0x1e84 |= BIT(30); + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, reg_0x1e84); + } + + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, 0x80000000); + odm_set_bb_reg(dm, R_0x1e84, MASKDWORD, 0x0); +} + +void phydm_hwigi_init(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_bb_ram_ctrl *bb_ctrl = &dm->p_bb_ram_ctrl; + u8 igi_ofst = 0x0; + u8 t1 = 0x0; + u8 t2 = 0x0; + u8 t3 = 0x0; + + t1 = 0x55; /*34 us*/ + t3 = 0x55; /*34 us*/ + + bb_ctrl->hwigi_watchdog_en = false; + phydm_set_hwigi_pre_setting(dm, igi_ofst, t1, t2, t3); +} + +void phydm_hwigi(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct cmn_sta_info *sta = NULL; + struct phydm_bb_ram_per_sta *dm_ram_per_sta = NULL; + struct rssi_info *rssi = NULL; + struct phydm_dig_struct *dig_t = &dm->dm_dig_table; + struct phydm_bb_ram_ctrl *bb_ctrl = &dm->p_bb_ram_ctrl; + u8 sta_cnt = 0; + u8 i = 0; + u8 hwigi = 0x0; + u8 macid = 0; + u8 macid_cnt = 0; + u64 macid_cur = 0; + u64 macid_diff = 0; + u64 macid_mask = 0; + + if (!(bb_ctrl->hwigi_watchdog_en)) { + return; + } + + for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { + sta = dm->phydm_sta_info[i]; + if (is_sta_active(sta)) { + sta_cnt++; + + if (sta->mac_id > 63) + macid = 63; + else + macid = sta->mac_id; + + dm_ram_per_sta = &bb_ctrl->pram_sta_ctrl[macid]; + rssi = &sta->rssi_stat; + macid_mask = (u64)BIT(sta->mac_id); + bb_ctrl->hwigi_macid_is_linked |= macid_mask; + macid_cur |= macid_mask; + PHYDM_DBG(dm, DBG_DIG, + "STA_id=%d, MACID=%d, RSSI=%d, hwigi_en=%d, hwigi=0x%x\n", + i, sta->mac_id, rssi->rssi, + dm_ram_per_sta->hw_igi_en, + dm_ram_per_sta->hw_igi); + + hwigi = MAX_2((u8)(rssi->rssi + 10), + dig_t->cur_ig_value); + + if (hwigi > DIG_MAX_PERFORMANCE_MODE) + hwigi = DIG_MAX_PERFORMANCE_MODE; + else if (hwigi < DIG_MIN_PERFORMANCE) + hwigi = DIG_MIN_PERFORMANCE; + + if (dm_ram_per_sta->hw_igi == hwigi) { + PHYDM_DBG(dm, DBG_DIG, + "hwigi not change!\n"); + } else { + + PHYDM_DBG(dm, DBG_DIG, + "hwigi update: ((0x%x)) -> ((0x%x))\n", + dm_ram_per_sta->hw_igi, hwigi); + + phydm_wt_hwigi_table(dm, sta->mac_id, true, hwigi); + } + + if (sta_cnt == dm->number_linked_client) + break; + } + } + macid_diff = bb_ctrl->hwigi_macid_is_linked ^ macid_cur; + if (macid_diff) + bb_ctrl->hwigi_macid_is_linked &= ~macid_diff; + while (macid_diff) { + if (macid_diff & 0x1) + phydm_wt_hwigi_table(dm, macid_cnt, false, 0x0); + macid_cnt++; + macid_diff >>= 1; + } +} + +void phydm_hwigi_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_bb_ram_ctrl *bb_ctrl = &dm->p_bb_ram_ctrl; + char help[] = "-h"; + u32 used = *_used; + u32 out_len = *_out_len; + u32 var1[7] = {0}; + u8 i = 0; + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "Disable/Enable watchdog : {0/1}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Set hwigi pre-setting: {2} {IGI offset} {T1(after data tx)} {T2(after Rx)} {T3(after rsp tx)}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Set hwigi table: {3} {en} {value} {macid}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Read hwigi : {4} {macid(0~63), 255:all}\n"); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Reset all hwigi : {5}\n"); + } else { + for (i = 0; i < 7; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + } + switch (var1[0]) { + case 0: + case 1: + bb_ctrl->hwigi_watchdog_en = (var1[0]) ? true : false; + break; + case 2: + phydm_set_hwigi_pre_setting(dm, (u8)var1[1], + (u8)var1[2], (u8)var1[3], + (u8)var1[4]); + break; + case 3: + phydm_wt_hwigi_table(dm, (u8)var1[3], (boolean)var1[1], + (boolean)var1[2]); + break; + case 4: + phydm_rd_hwigi_pre_setting(dm, &used, output, &out_len); + if ((u8)var1[1] == 0xff) + for (i = 0; i < 64; i++) + phydm_rd_hwigi_table(dm, i, &used, + output, &out_len); + else + phydm_rd_hwigi_table(dm, (u8)var1[1], &used, + output, &out_len); + break; + case 5: + phydm_rst_hwigi(dm); + break; + } + } + *_used = used; + *_out_len = out_len; +} +#endif +#endif + void phydm_dig_init(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -696,6 +998,9 @@ void phydm_dig_init(void *dm_void) dig_t->fa_th[1] = 500; dig_t->fa_th[2] = 750; dig_t->is_dbg_fa_th = false; + dig_t->igi_dyn_up_hit = false; + dig_t->fw_dig_enable = false; + #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) /* @For RTL8881A */ false_alm_cnt->cnt_ofdm_fail_pre = 0; @@ -705,18 +1010,19 @@ void phydm_dig_init(void *dm_void) dig_t->rx_gain_range_min = dig_t->cur_ig_value; #if (RTL8822B_SUPPORT || RTL8197F_SUPPORT || RTL8192F_SUPPORT) - dig_t->enable_adjust_big_jump = 1; - if (dm->support_ic_type & ODM_RTL8822B) - ret_value = odm_get_bb_reg(dm, R_0x8c8, MASKLWORD); - else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F)) - ret_value = odm_get_bb_reg(dm, R_0xc74, MASKLWORD); - - dig_t->big_jump_step1 = (u8)(ret_value & 0xe) >> 1; - dig_t->big_jump_step2 = (u8)(ret_value & 0x30) >> 4; - dig_t->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6; - if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8192F)) { + dig_t->enable_adjust_big_jump = 1; + + if (dm->support_ic_type & ODM_RTL8822B) + ret_value = odm_get_bb_reg(dm, R_0x8c8, MASKLWORD); + else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F)) + ret_value = odm_get_bb_reg(dm, R_0xc74, MASKLWORD); + + dig_t->big_jump_step1 = (u8)(ret_value & 0xe) >> 1; + dig_t->big_jump_step2 = (u8)(ret_value & 0x30) >> 4; + dig_t->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6; + for (i = 0; i < sizeof(dig_t->big_jump_lmt); i++) { if (dig_t->big_jump_lmt[i] == 0) dig_t->big_jump_lmt[i] = 0x64; @@ -731,11 +1037,17 @@ void phydm_dig_init(void *dm_void) dm->tdma_dig_state_number = DIG_NUM_OF_TDMA_STATES; dm->tdma_dig_timer_ms = DIG_TIMER_MS; #endif + dig_t->tdma_force_l_igi = 0xff; + dig_t->tdma_force_h_igi = 0xff; #endif #ifdef CFG_DIG_DAMPING_CHK phydm_dig_recorder_reset(dm); dig_t->dig_dl_en = 1; #endif + +#ifdef PHYDM_HW_IGI + phydm_hwigi_init(dm); +#endif } void phydm_dig_abs_boundary_decision(struct dm_struct *dm, boolean is_dfs_band) { @@ -743,12 +1055,21 @@ void phydm_dig_abs_boundary_decision(struct dm_struct *dm, boolean is_dfs_band) struct phydm_adaptivity_struct *adapt = &dm->adaptivity; if (is_dfs_band) { - if (*dm->band_width == CHANNEL_WIDTH_20) - dig_t->dm_dig_min = DIG_MIN_DFS + 2; + if (*dm->band_width == CHANNEL_WIDTH_20){ + if (dm->support_ic_type & + (ODM_RTL8814A | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8822B)){ + if (odm_get_bb_reg(dm, R_0x8d8, BIT(27)) == 1) + dig_t->dm_dig_min = DIG_MIN_DFS + 2; + else + dig_t->dm_dig_min = DIG_MIN_DFS; + } + else + dig_t->dm_dig_min = DIG_MIN_DFS; + } else dig_t->dm_dig_min = DIG_MIN_DFS; - dig_t->dig_max_of_min = DIG_MAX_OF_MIN_BALANCE_MODE; + dig_t->dig_max_of_min = DIG_MIN_DFS; dig_t->dm_dig_max = DIG_MAX_BALANCE_MODE; } else if (!dm->is_linked) { dig_t->dm_dig_max = DIG_MAX_COVERAGR; @@ -884,12 +1205,11 @@ void phydm_dig_abnormal_case(struct dm_struct *dm) u8 phydm_new_igi_by_fa(struct dm_struct *dm, u8 igi, u32 fa_cnt, u8 *step_size) { - boolean dig_go_up_check = true; struct phydm_dig_struct *dig_t = &dm->dm_dig_table; - if (fa_cnt > dig_t->fa_th[2] && dig_go_up_check) + if (fa_cnt > dig_t->fa_th[2]) igi = igi + step_size[0]; - else if ((fa_cnt > dig_t->fa_th[1]) && dig_go_up_check) + else if (fa_cnt > dig_t->fa_th[1]) igi = igi + step_size[1]; else if (fa_cnt < dig_t->fa_th[0]) igi = igi - step_size[2]; @@ -949,7 +1269,8 @@ u8 phydm_get_new_igi(struct dm_struct *dm, u8 igi, u32 fa_cnt, #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) if (dm->phy_dbg_info.num_qry_beacon_pkt < 5 && fa_cnt < DM_DIG_FA_TH1 && dm->bsta_state && - dm->support_ic_type != ODM_RTL8723D) { + dm->support_ic_type != ODM_RTL8723D && + dm->support_ic_type != ODM_RTL8822C) { dig_t->rx_gain_range_min = 0x1c; igi = dig_t->rx_gain_range_min; PHYDM_DBG(dm, DBG_DIG, "Beacon_num=%d,force igi=0x%x\n", @@ -980,8 +1301,14 @@ u8 phydm_get_new_igi(struct dm_struct *dm, u8 igi, u32 fa_cnt, if (igi < dig_t->rx_gain_range_min) igi = dig_t->rx_gain_range_min; - if (igi > dig_t->rx_gain_range_max) + if (igi >= dig_t->rx_gain_range_max) { igi = dig_t->rx_gain_range_max; + dig_t->igi_dyn_up_hit = true; + } else { + dig_t->igi_dyn_up_hit = false; + } + PHYDM_DBG(dm, DBG_DIG, "igi_dyn_up_hit=%d\n", + dig_t->igi_dyn_up_hit); PHYDM_DBG(dm, DBG_DIG, "fa_cnt = %d, IGI: 0x%x -> 0x%x\n", fa_cnt, dig_t->cur_ig_value, igi); @@ -1011,15 +1338,20 @@ void phydm_dig(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_dig_struct *dig_t = &dm->dm_dig_table; - struct phydm_fa_struct *falm_cnt = &dm->false_alm_cnt; + struct phydm_fa_struct *fa = &dm->false_alm_cnt; #ifdef PHYDM_TDMA_DIG_SUPPORT struct phydm_fa_acc_struct *falm_cnt_acc = &dm->false_alm_cnt_acc; #endif u8 igi = dig_t->cur_ig_value; u8 new_igi = 0x20; - u32 fa_cnt = falm_cnt->cnt_all; + u32 fa_cnt = fa->cnt_all; boolean dfs_mode_en = false; +#ifdef PHYDM_DCC_ENHANCE + if (dm->dm_dcc_info.dcc_en) + fa_cnt = fa->cnt_ofdm_fail; /*OFDM FA only*/ +#endif + #ifdef PHYDM_TDMA_DIG_SUPPORT if (!(dm->original_dig_restore)) { if (dig_t->cur_ig_value_tdma == 0) @@ -1136,6 +1468,31 @@ void phydm_dig_by_rssi_lps(void *dm_void) #endif } +void phydm_get_dig_coverage(void *dm_void, u8 *max, u8 *min) +{ + *min = DIG_MIN_COVERAGE; + *max = DIG_MAX_PERFORMANCE_MODE; +} + +u8 phydm_get_igi_for_target_pin_scan(void *dm_void, u8 rssi) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u8 igi = 0; + u8 max = 0; + u8 min = 0; + + igi = rssi + 10; + + phydm_get_dig_coverage(dm, &max, &min); + + if (igi > max) + igi = max; + else if (igi < min) + igi = min; + + return igi; +} + /* @3============================================================ * 3 FASLE ALARM CHECK * 3============================================================ @@ -1164,6 +1521,11 @@ void phydm_false_alarm_counter_reg_reset(void *dm_void) #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + if (dm->support_ic_type & ODM_RTL8723F) { + /* @reset CCK FA and CCA counter */ + odm_set_bb_reg(dm, R_0x2a44, BIT(21), 0); + odm_set_bb_reg(dm, R_0x2a44, BIT(21), 1); + } else { /* @reset CCK FA counter */ odm_set_bb_reg(dm, R_0x1a2c, BIT(15) | BIT(14), 0); odm_set_bb_reg(dm, R_0x1a2c, BIT(15) | BIT(14), 2); @@ -1171,7 +1533,7 @@ void phydm_false_alarm_counter_reg_reset(void *dm_void) /* @reset CCK CCA counter */ odm_set_bb_reg(dm, R_0x1a2c, BIT(13) | BIT(12), 0); odm_set_bb_reg(dm, R_0x1a2c, BIT(13) | BIT(12), 2); - + } /* @Disable common rx clk gating => WLANBB-1106*/ odm_set_bb_reg(dm, R_0x1d2c, BIT(31), 0); /* @reset OFDM CCA counter, OFDM FA counter*/ @@ -1240,6 +1602,9 @@ void phydm_false_alarm_counter_reg_hold(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + if (dm->support_ic_type & ODM_RTL8723F) + return; + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { /* @hold cck counter */ odm_set_bb_reg(dm, R_0x1a2c, BIT(12), 1); @@ -1299,11 +1664,21 @@ void phydm_fa_cnt_statistics_n(void *dm_void) fa_t->cnt_ofdm_crc32_error = (reg & 0xffff0000) >> 16; fa_t->cnt_ofdm_crc32_ok = reg & 0xffff; + /* read OFDM2 CRC32 counter */ + reg = odm_get_bb_reg(dm, R_0xf9c, MASKDWORD); + fa_t->cnt_ofdm_crc32_error = (reg & 0xffff0000) >> 16; + fa_t->cnt_ofdm2_crc32_ok = reg & 0xffff; + /* read HT CRC32 counter */ reg = odm_get_bb_reg(dm, ODM_REG_HT_CRC32_CNT_11N, MASKDWORD); fa_t->cnt_ht_crc32_error = (reg & 0xffff0000) >> 16; fa_t->cnt_ht_crc32_ok = reg & 0xffff; + /* read HT2 CRC32 counter */ + reg = odm_get_bb_reg(dm, R_0xf98, MASKDWORD); + fa_t->cnt_ht_crc32_error = (reg & 0xffff0000) >> 16; + fa_t->cnt_ht2_crc32_ok = reg & 0xffff; + /* read VHT CRC32 counter */ fa_t->cnt_vht_crc32_error = 0; fa_t->cnt_vht_crc32_ok = 0; @@ -1345,12 +1720,6 @@ void phydm_fa_cnt_statistics_n(void *dm_void) fa_t->cnt_cck_fail; fa_t->cnt_cca_all = fa_t->cnt_ofdm_cca + fa_t->cnt_cck_cca; - - PHYDM_DBG(dm, DBG_FA_CNT, - "[OFDM FA Detail] Parity_Fail=((%d)), Rate_Illegal=((%d)), CRC8_fail=((%d)), Mcs_fail=((%d)), Fast_Fsync=(( %d )), SBD_fail=((%d))\n", - fa_t->cnt_parity_fail, fa_t->cnt_rate_illegal, - fa_t->cnt_crc8_fail, fa_t->cnt_mcs_fail, fa_t->cnt_fast_fsync, - fa_t->cnt_sb_search_fail); } #endif @@ -1462,23 +1831,13 @@ void phydm_fa_cnt_statistics_ac(void *dm_void) } #endif -void phydm_get_dbg_port_info(void *dm_void) +u32 phydm_get_edcca_report(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_fa_struct *fa_t = &dm->false_alm_cnt; u32 dbg_port = dm->adaptivity.adaptivity_dbg_port; u32 val = 0; - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - fa_t->dbg_port0 = odm_get_bb_reg(dm, R_0x2db4, MASKDWORD); - } else { - /*set debug port to 0x0*/ - if (phydm_set_bb_dbg_port(dm, DBGPORT_PRI_1, 0x0)) { - fa_t->dbg_port0 = phydm_get_bb_dbg_port_val(dm); - phydm_release_bb_dbg_port(dm); - } - } - if (dm->support_ic_type & ODM_RTL8723D) { val = odm_get_bb_reg(dm, R_0x9a0, BIT(29)); } else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { @@ -1491,17 +1850,100 @@ void phydm_get_dbg_port_info(void *dm_void) phydm_release_bb_dbg_port(dm); } - fa_t->edcca_flag = (boolean)val; + return val; +} + +void phydm_get_dbg_port_info(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_fa_struct *fa_t = &dm->false_alm_cnt; + + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + fa_t->dbg_port0 = odm_get_bb_reg(dm, R_0x2db4, MASKDWORD); + } else { + /*set debug port to 0x0*/ + if (phydm_set_bb_dbg_port(dm, DBGPORT_PRI_1, 0x0)) { + fa_t->dbg_port0 = phydm_get_bb_dbg_port_val(dm); + phydm_release_bb_dbg_port(dm); + } + } + + fa_t->edcca_flag = (boolean)phydm_get_edcca_report(dm); PHYDM_DBG(dm, DBG_FA_CNT, "FA_Cnt: Dbg port 0x0 = 0x%x, EDCCA = %d\n", fa_t->dbg_port0, fa_t->edcca_flag); } +void phydm_set_crc32_cnt2_rate(void *dm_void, u8 rate_idx) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_fa_struct *fa_t = &dm->false_alm_cnt; + boolean is_ofdm_rate = phydm_is_ofdm_rate(dm, rate_idx); + boolean is_ht_rate = phydm_is_ht_rate(dm, rate_idx); + boolean is_vht_rate = phydm_is_vht_rate(dm, rate_idx); + u32 reg_addr = 0x0; + u32 ofdm_rate_bitmask = 0x0; + u32 ht_mcs_bitmask = 0x0; + u32 vht_mcs_bitmask = 0x0; + u32 vht_ss_bitmask = 0x0; + u8 rate = 0x0; + u8 ss = 0x0; + + if (!is_ofdm_rate && !is_ht_rate && !is_vht_rate) + PHYDM_DBG(dm, DBG_FA_CNT, + "[FA CNT] rate_idx = (0x%x) is not supported !\n", + rate_idx); + + switch (dm->ic_ip_series) { + case PHYDM_IC_N: + reg_addr = R_0xf04; + ofdm_rate_bitmask = 0x0000f000; + ht_mcs_bitmask = 0x007f0000; + break; + case PHYDM_IC_AC: + reg_addr = R_0xb04; + ofdm_rate_bitmask = 0x0000f000; + ht_mcs_bitmask = 0x007f0000; + vht_mcs_bitmask = 0x0f000000; + vht_ss_bitmask = 0x30000000; + break; + case PHYDM_IC_JGR3: + reg_addr = R_0x1eb8; + ofdm_rate_bitmask = 0x00000f00; + ht_mcs_bitmask = 0x007f0000; + vht_mcs_bitmask = 0x0000f000; + vht_ss_bitmask = 0x000000c0; + break; + default: + break; + } + + if (is_ofdm_rate) { + rate = phydm_legacy_rate_2_spec_rate(dm, rate_idx); + + odm_set_bb_reg(dm, reg_addr, ofdm_rate_bitmask, rate); + fa_t->ofdm2_rate_idx = rate_idx; + } else if (is_ht_rate) { + rate = phydm_rate_2_rate_digit(dm, rate_idx); + + odm_set_bb_reg(dm, reg_addr, ht_mcs_bitmask, rate); + fa_t->ht2_rate_idx = rate_idx; + } else if (is_vht_rate) { + rate = phydm_rate_2_rate_digit(dm, rate_idx); + ss = phydm_rate_to_num_ss(dm, rate_idx); + + odm_set_bb_reg(dm, reg_addr, vht_mcs_bitmask, rate); + odm_set_bb_reg(dm, reg_addr, vht_ss_bitmask, ss - 1); + fa_t->vht2_rate_idx = rate_idx; + } +} + void phydm_false_alarm_counter_statistics(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_fa_struct *fa_t = &dm->false_alm_cnt; char dbg_buf[PHYDM_SNPRINT_SIZE] = {0}; + u32 tmp = 0; if (!(dm->support_ability & ODM_BB_FA_CNT)) return; @@ -1555,13 +1997,16 @@ void phydm_false_alarm_counter_statistics(void *dm_void) "[OFDM FA] Parity=%d, Rate=%d, Fast_Fsync=%d, SBD=%d\n", fa_t->cnt_parity_fail, fa_t->cnt_rate_illegal, fa_t->cnt_fast_fsync, fa_t->cnt_sb_search_fail); - PHYDM_DBG(dm, DBG_FA_CNT, - "[HT FA] HT_CRC8=%d, HT_MCS=%d\n", + PHYDM_DBG(dm, DBG_FA_CNT, "[HT FA] CRC8=%d, MCS=%d\n", fa_t->cnt_crc8_fail, fa_t->cnt_mcs_fail); - PHYDM_DBG(dm, DBG_FA_CNT, - "[VHT FA] VHT_SIGA_CRC8=%d, VHT_SIGB_CRC8=%d, VHT_MCS=%d\n", - fa_t->cnt_crc8_fail_vhta, fa_t->cnt_crc8_fail_vhtb, - fa_t->cnt_mcs_fail_vht); +#if (ODM_IC_11AC_SERIES_SUPPORT || defined(PHYDM_IC_JGR3_SERIES_SUPPORT)) + if (dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES)) { + PHYDM_DBG(dm, DBG_FA_CNT, + "[VHT FA] SIGA_CRC8=%d, SIGB_CRC8=%d, MCS=%d\n", + fa_t->cnt_crc8_fail_vhta, fa_t->cnt_crc8_fail_vhtb, + fa_t->cnt_mcs_fail_vht); + } +#endif PHYDM_DBG(dm, DBG_FA_CNT, "[CRC32 OK Cnt] {CCK, OFDM, HT, VHT, Total} = {%d, %d, %d, %d, %d}\n", @@ -1573,92 +2018,69 @@ void phydm_false_alarm_counter_statistics(void *dm_void) fa_t->cnt_cck_crc32_error, fa_t->cnt_ofdm_crc32_error, fa_t->cnt_ht_crc32_error, fa_t->cnt_vht_crc32_error, fa_t->cnt_crc32_error_all); + + if (fa_t->ofdm2_rate_idx) { + tmp = fa_t->cnt_ofdm2_crc32_error + fa_t->cnt_ofdm2_crc32_ok; + fa_t->ofdm2_pcr = (u8)PHYDM_DIV(fa_t->cnt_ofdm2_crc32_ok * 100, + tmp); + phydm_print_rate_2_buff(dm, fa_t->ofdm2_rate_idx, dbg_buf, + PHYDM_SNPRINT_SIZE); + PHYDM_DBG(dm, DBG_FA_CNT, + "[OFDM:%s CRC32 Cnt] {error, ok}= {%d, %d} (%d percent)\n", + dbg_buf, fa_t->cnt_ofdm2_crc32_error, + fa_t->cnt_ofdm2_crc32_ok, fa_t->ofdm2_pcr); + } else { + phydm_set_crc32_cnt2_rate(dm, ODM_RATE6M); + } + + if (fa_t->ht2_rate_idx) { + tmp = fa_t->cnt_ht2_crc32_error + fa_t->cnt_ht2_crc32_ok; + fa_t->ht2_pcr = (u8)PHYDM_DIV(fa_t->cnt_ht2_crc32_ok * 100, + tmp); + phydm_print_rate_2_buff(dm, fa_t->ht2_rate_idx, dbg_buf, + PHYDM_SNPRINT_SIZE); + PHYDM_DBG(dm, DBG_FA_CNT, + "[HT:%s CRC32 Cnt] {error, ok}= {%d, %d} (%d percent)\n", + dbg_buf, fa_t->cnt_ht2_crc32_error, + fa_t->cnt_ht2_crc32_ok, fa_t->ht2_pcr); + } else { + phydm_set_crc32_cnt2_rate(dm, ODM_RATEMCS0); + } + #if (ODM_IC_11AC_SERIES_SUPPORT || defined(PHYDM_IC_JGR3_SERIES_SUPPORT)) if (dm->support_ic_type & (ODM_IC_11AC_SERIES | ODM_IC_JGR3_SERIES)) { - if (fa_t->ofdm2_rate_idx) { - phydm_print_rate_2_buff(dm, fa_t->ofdm2_rate_idx, - dbg_buf, PHYDM_SNPRINT_SIZE); - PHYDM_DBG(dm, DBG_FA_CNT, - "[OFDM:%s CRC32 Cnt] {error, ok}= {%d, %d}\n", - dbg_buf, fa_t->cnt_ofdm2_crc32_error, - fa_t->cnt_ofdm2_crc32_ok); - } - if (fa_t->ht2_rate_idx) { - phydm_print_rate_2_buff(dm, fa_t->ht2_rate_idx, dbg_buf, - PHYDM_SNPRINT_SIZE); - PHYDM_DBG(dm, DBG_FA_CNT, - "[HT:%s CRC32 Cnt] {error, ok}= {%d, %d}\n", - dbg_buf, fa_t->cnt_ht2_crc32_error, - fa_t->cnt_ht2_crc32_ok); - } if (fa_t->vht2_rate_idx) { + tmp = fa_t->cnt_vht2_crc32_error + + fa_t->cnt_vht2_crc32_ok; + fa_t->vht2_pcr = (u8)PHYDM_DIV(fa_t->cnt_vht2_crc32_ok * + 100, tmp); phydm_print_rate_2_buff(dm, fa_t->vht2_rate_idx, dbg_buf, PHYDM_SNPRINT_SIZE); PHYDM_DBG(dm, DBG_FA_CNT, - "[VHT:%s CRC32 Cnt] {error, ok}= {%d, %d}\n", + "[VHT:%s CRC32 Cnt] {error, ok}= {%d, %d} (%d percent)\n", dbg_buf, fa_t->cnt_vht2_crc32_error, - fa_t->cnt_vht2_crc32_ok); + fa_t->cnt_vht2_crc32_ok, fa_t->vht2_pcr); + } else { + phydm_set_crc32_cnt2_rate(dm, ODM_RATEVHTSS1MCS0); } } #endif } -void phydm_fa_cnt_set_crc32_cnt2_rate(void *dm_void, u8 rate_idx) -{ +void phydm_fill_fw_dig_info(void *dm_void, boolean *enable, + u8 *para4, u8 *para8) { struct dm_struct *dm = (struct dm_struct *)dm_void; - struct phydm_fa_struct *fa_t = &dm->false_alm_cnt; - boolean is_ofdm_rate = phydm_is_ofdm_rate(dm, rate_idx); - boolean is_ht_rate = phydm_is_ht_rate(dm, rate_idx); - boolean is_vht_rate = phydm_is_vht_rate(dm, rate_idx); - u32 reg_addr = 0x0; - u32 ofdm_rate_bitmask = 0x0; - u32 ht_mcs_bitmask = 0x0; - u32 vht_mcs_bitmask = 0x0; - u32 vht_ss_bitmask = 0x0; - u8 rate = 0x0; - u8 ss = 0x0; + struct phydm_dig_struct *dig_t = &dm->dm_dig_table; - if (!is_ofdm_rate && !is_ht_rate && !is_vht_rate) - PHYDM_DBG(dm, DBG_FA_CNT, - "[FA CNT] rate_idx = (0x%x) is not supported !\n", - rate_idx); - - if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - reg_addr = R_0xb04; - ofdm_rate_bitmask = 0x0000f000; - ht_mcs_bitmask = 0x007f0000; - vht_mcs_bitmask = 0x0f000000; - vht_ss_bitmask = 0x30000000; - } else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - reg_addr = R_0x1eb8; - ofdm_rate_bitmask = 0x00000f00; - ht_mcs_bitmask = 0x007f0000; - vht_mcs_bitmask = 0x0000f000; - vht_ss_bitmask = 0x000000c0; - } - - if (is_ofdm_rate) { - rate = phydm_legacy_rate_2_spec_rate(dm, rate_idx); - - odm_set_bb_reg(dm, reg_addr, ofdm_rate_bitmask, rate); - fa_t->ofdm2_rate_idx = rate_idx; - } else if (is_ht_rate) { - rate = phydm_rate_2_rate_digit(dm, rate_idx); - - odm_set_bb_reg(dm, reg_addr, ht_mcs_bitmask, rate); - fa_t->ht2_rate_idx = rate_idx; - } else if (is_vht_rate) { - rate = phydm_rate_2_rate_digit(dm, rate_idx); - ss = phydm_rate_to_num_ss(dm, rate_idx); - - odm_set_bb_reg(dm, reg_addr, vht_mcs_bitmask, rate); - odm_set_bb_reg(dm, reg_addr, vht_ss_bitmask, ss - 1); - fa_t->vht2_rate_idx = rate_idx; - } + dig_t->fw_dig_enable = *enable; + para8[0] = dig_t->rx_gain_range_max; + para8[1] = dig_t->rx_gain_range_min; + para8[2] = dm->number_linked_client; + para4[0] = (u8)DIG_LPS_MODE; } -void phydm_fa_cnt_dbg(void *dm_void, char input[][16], u32 *_used, char *output, - u32 *_out_len) +void phydm_crc32_cnt_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_dig_struct *dig_t = &dm->dm_dig_table; @@ -1669,16 +2091,9 @@ void phydm_fa_cnt_dbg(void *dm_void, char input[][16], u32 *_used, char *output, u8 i = 0; u8 rate = 0x0; - if (!(dm->support_ic_type & (ODM_IC_JGR3_SERIES | - ODM_IC_11AC_SERIES))) { - PDM_SNPF(out_len, used, output + used, out_len - used, - "Not Support !\n"); - return; - } - if ((strcmp(input[1], help) == 0)) { PDM_SNPF(out_len, used, output + used, out_len - used, - "[FA Cnt] CRC32: {rate_idx}\n"); + "[CRC32 Cnt] {rate_idx}\n"); } else { PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); rate = (u8)var1[0]; @@ -1686,7 +2101,7 @@ void phydm_fa_cnt_dbg(void *dm_void, char input[][16], u32 *_used, char *output, PDM_SNPF(out_len, used, output + used, out_len - used, "{rate}={0x%x}", rate); - phydm_fa_cnt_set_crc32_cnt2_rate(dm, rate); + phydm_set_crc32_cnt2_rate(dm, rate); } *_used = used; *_out_len = out_len; @@ -1747,7 +2162,7 @@ void phydm_tdma_dig_timer_check(void *dm_void) if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B | ODM_RTL8812F | ODM_RTL8822B | ODM_RTL8192F | ODM_RTL8821C | ODM_RTL8197G | ODM_RTL8822C | - ODM_RTL8723D)) { + ODM_RTL8723D| ODM_RTL8723F)) { PHYDM_DBG(dm, DBG_DIG, "Check fail, Restart timer\n\n"); phydm_false_alarm_counter_reset(dm); @@ -2182,6 +2597,30 @@ u8 get_new_igi_bound(struct dm_struct *dm, u8 igi, u32 fa_cnt, u8 *rx_gain_max, return igi; } +void phydm_write_tdma_dig(void *dm_void, u8 new_igi) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_dig_struct *dig_t = &dm->dm_dig_table; + struct phydm_adaptivity_struct *adaptivity = &dm->adaptivity; + + PHYDM_DBG(dm, DBG_DIG, "%s===>\n", __func__); +#if 0 + /* @1 Check IGI by upper bound */ + if (adaptivity->igi_lmt_en && + new_igi > adaptivity->adapt_igi_up && dm->is_linked) { + new_igi = adaptivity->adapt_igi_up; + + PHYDM_DBG(dm, DBG_DIG, "Force Adaptivity Up-bound=((0x%x))\n", + new_igi); + } +#endif + phydm_write_dig_reg(dm, new_igi); + + PHYDM_DBG(dm, DBG_DIG, "New %s-IGI=((0x%x))\n", + (dig_t->tdma_dig_state == TDMA_DIG_LOW_STATE) ? "L" : "H", + new_igi); +} + void phydm_tdma_dig_new(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2328,9 +2767,9 @@ void phydm_tdma_dig_cbk(void *dm_void) */ if (dig_t->tdma_dig_state == TDMA_DIG_LOW_STATE) - odm_write_dig(dm, dig_t->low_ig_value); + phydm_write_tdma_dig(dm, dig_t->low_ig_value); else if (dig_t->tdma_dig_state >= TDMA_DIG_HIGH_STATE) - odm_write_dig(dm, dig_t->cur_ig_value_tdma); + phydm_write_tdma_dig(dm, dig_t->cur_ig_value_tdma); odm_set_timer(dm, &dm->tdma_dig_timer, dm->tdma_dig_timer_ms); } @@ -2494,9 +2933,18 @@ void phydm_tdma_low_dig(void *dm_void) dig_t->dm_dig_min = DIG_MIN_PERFORMANCE; //0x20 dig_t->dig_max_of_min = DIG_MAX_OF_MIN_COVERAGE; //0x22 - if (dfs_mode_en) { - if (*dm->band_width == CHANNEL_WIDTH_20) - dig_t->dm_dig_min = DIG_MIN_DFS + 2; + if (dm->is_dfs_band) { + if (*dm->band_width == CHANNEL_WIDTH_20){ + if (dm->support_ic_type & + (ODM_RTL8814A | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8822B)){ + if (odm_get_bb_reg(dm, R_0x8d8, BIT(27)) == 1) + dig_t->dm_dig_min = DIG_MIN_DFS + 2; + else + dig_t->dm_dig_min = DIG_MIN_DFS; + } + else + dig_t->dm_dig_min = DIG_MIN_DFS; + } else dig_t->dm_dig_min = DIG_MIN_DFS; @@ -2527,7 +2975,8 @@ void phydm_tdma_low_dig(void *dm_void) /* @DIG lower bound in L-state*/ tdma_l_dym_min = dig_t->dm_dig_min; - + if (dm->is_dfs_band) + tdma_l_dym_min = DIG_MIN_DFS; /*@ *#ifdef CFG_DIG_DAMPING_CHK *@Limit Dyn min by damping @@ -2597,7 +3046,10 @@ void phydm_tdma_low_dig(void *dm_void) /*Update status*/ if (!(dm->original_dig_restore)) { - dig_t->low_ig_value = tdma_l_igi; + if (dig_t->tdma_force_l_igi == 0xff) + dig_t->low_ig_value = tdma_l_igi; + else + dig_t->low_ig_value = dig_t->tdma_force_l_igi; dig_t->tdma_rx_gain_min[TDMA_DIG_LOW_STATE] = tdma_l_dym_min; dig_t->tdma_rx_gain_max[TDMA_DIG_LOW_STATE] = tdma_l_dym_max; #if 0 @@ -2650,9 +3102,18 @@ void phydm_tdma_high_dig(void *dm_void) if (!dm->is_linked) { dig_t->dm_dig_max = DIG_MAX_COVERAGR; dig_t->dm_dig_min = DIG_MIN_PERFORMANCE; // 0x20 - } else if (dfs_mode_en) { - if (*dm->band_width == CHANNEL_WIDTH_20) - dig_t->dm_dig_min = DIG_MIN_DFS + 2; + } else if (dm->is_dfs_band) { + if (*dm->band_width == CHANNEL_WIDTH_20){ + if (dm->support_ic_type & + (ODM_RTL8814A | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8822B)){ + if (odm_get_bb_reg(dm, R_0x8d8, BIT(27)) == 1) + dig_t->dm_dig_min = DIG_MIN_DFS + 2; + else + dig_t->dm_dig_min = DIG_MIN_DFS; + } + else + dig_t->dm_dig_min = DIG_MIN_DFS; + } else dig_t->dm_dig_min = DIG_MIN_DFS; @@ -2699,7 +3160,9 @@ void phydm_tdma_high_dig(void *dm_void) dm->rssi_min, offset); /* @DIG lower bound in H-state*/ - if (rssi_min < dig_t->dm_dig_min) + if (dm->is_dfs_band) + tdma_h_dym_min = DIG_MIN_DFS; + else if (rssi_min < dig_t->dm_dig_min) tdma_h_dym_min = dig_t->dm_dig_min; else tdma_h_dym_min = rssi_min; // turbo not considered yet @@ -2771,7 +3234,10 @@ void phydm_tdma_high_dig(void *dm_void) /*Update status*/ if (!(dm->original_dig_restore)) { - dig_t->cur_ig_value_tdma = tdma_h_igi; + if (dig_t->tdma_force_h_igi == 0xff) + dig_t->cur_ig_value_tdma = tdma_h_igi; + else + dig_t->cur_ig_value_tdma = dig_t->tdma_force_h_igi; dig_t->tdma_rx_gain_min[TDMA_DIG_HIGH_STATE] = tdma_h_dym_min; dig_t->tdma_rx_gain_max[TDMA_DIG_HIGH_STATE] = tdma_h_dym_max; #if 0 @@ -2898,7 +3364,12 @@ void phydm_dig_debug(void *dm_void, char input[][16], u32 *_used, char *output, PDM_SNPF(out_len, used, output + used, out_len - used, "{4} {tdma_dig_state_number = %d}\n", dm->tdma_dig_state_number); + PDM_SNPF(out_len, used, output + used, out_len - used, + "{5} {0:L-state,1:H-state} {force IGI} (L,H)=(%2x,%2x)\n", + dig_t->tdma_force_l_igi, dig_t->tdma_force_h_igi); #endif + PDM_SNPF(out_len, used, output + used, out_len - used, + "{6} {fw_dig_en}\n"); } else { PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); @@ -2940,6 +3411,21 @@ void phydm_dig_debug(void *dm_void, char input[][16], u32 *_used, char *output, PDM_SNPF(out_len, used, output + used, out_len - used, "tdma_dig_state_number = %d\n", dm->tdma_dig_state_number); + } else if (var1[0] == 5) { + PHYDM_SSCANF(input[3], DCMD_HEX, &var1[2]); + if (var1[1] == 0) { + dig_t->tdma_force_l_igi = (u8)var1[2]; + PDM_SNPF(out_len, used, output + used, + out_len - used, + "force L-state IGI = %2x\n", + dig_t->tdma_force_l_igi); + } else if (var1[1] == 1) { + dig_t->tdma_force_h_igi = (u8)var1[2]; + PDM_SNPF(out_len, used, output + used, + out_len - used, + "force H-state IGI = %2x\n", + dig_t->tdma_force_h_igi); + } #endif } @@ -2949,13 +3435,18 @@ void phydm_dig_debug(void *dm_void, char input[][16], u32 *_used, char *output, /*@*/ } #endif + else if (var1[0] == 6) { + phydm_fw_dm_ctrl_en(dm, F00_DIG, (boolean)var1[1]); + PDM_SNPF(out_len, used, output + used, out_len - used, + "fw_dig_enable = %2x\n", dig_t->fw_dig_enable); + } } *_used = used; *_out_len = out_len; } #ifdef CONFIG_MCC_DM -#if (RTL8822B_SUPPORT || RTL8822C_SUPPORT) +#if (RTL8822B_SUPPORT || RTL8822C_SUPPORT|| RTL8723F_SUPPORT) void phydm_mcc_igi_clr(void *dm_void, u8 clr_port) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -2998,13 +3489,26 @@ void phydm_mcc_igi_cal(void *dm_void) phydm_mcc_igi_chk(dm); igi_val0 = mcc_dm->mcc_rssi[0] - shift; igi_val1 = mcc_dm->mcc_rssi[1] - shift; + + if (igi_val0 < DIG_MIN_PERFORMANCE) + igi_val0 = DIG_MIN_PERFORMANCE; + + if (igi_val1 < DIG_MIN_PERFORMANCE) + igi_val1 = DIG_MIN_PERFORMANCE; + + switch (dm->ic_ip_series) { #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT - phydm_fill_mcccmd(dm, 0, R_0x1d70, igi_val0, igi_val1); - phydm_fill_mcccmd(dm, 1, R_0x1d70 + 1, igi_val0, igi_val1); - #else - phydm_fill_mcccmd(dm, 0, 0xc50, igi_val0, igi_val1); - phydm_fill_mcccmd(dm, 1, 0xe50, igi_val0, igi_val1); + case PHYDM_IC_JGR3: + phydm_fill_mcccmd(dm, 0, R_0x1d70, igi_val0, igi_val1); + phydm_fill_mcccmd(dm, 1, R_0x1d70 + 1, igi_val0, igi_val1); + break; #endif + default: + phydm_fill_mcccmd(dm, 0, R_0xc50, igi_val0, igi_val1); + phydm_fill_mcccmd(dm, 1, R_0xe50, igi_val0, igi_val1); + break; + } + PHYDM_DBG(dm, DBG_COMP_MCC, "RSSI_min: %d %d, MCC_igi: %d %d\n", mcc_dm->mcc_rssi[0], mcc_dm->mcc_rssi[1], mcc_dm->mcc_dm_val[0][0], mcc_dm->mcc_dm_val[0][1]); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dig.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dig.h index aba918a71742..205263c9a667 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dig.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dig.h @@ -27,11 +27,11 @@ #ifndef __PHYDMDIG_H__ #define __PHYDMDIG_H__ -/*20190701 Refine FA cnt code structure*/ -#define DIG_VERSION "2.8" +/* 2019.10.25 remove redundant code*/ +#define DIG_VERSION "3.7" #define DIG_HW 0 -#define DIG_LIMIT_PERIOD 60 /*@60 sec*/ +#define DIG_LIMIT_PERIOD 60 /*60 sec*/ /*@--------------------Define ---------------------------------------*/ @@ -83,17 +83,23 @@ #define DIG_RECORD_NUM 4 /*@--------------------Enum-----------------------------------*/ -enum dig_goupcheck_level { - DIG_GOUPCHECK_LEVEL_0, - DIG_GOUPCHECK_LEVEL_1, - DIG_GOUPCHECK_LEVEL_2 -}; - enum phydm_dig_mode { PHYDM_DIG_PERFORAMNCE_MODE = 0, PHYDM_DIG_COVERAGE_MODE = 1, }; +enum phydm_dig_trend { + DIG_STABLE = 0, + DIG_INCREASING = 1, + DIG_DECREASING = 2 +}; + +enum phydm_fw_dig_mode_e { + DIG_PERFORMANCE_MODE = 0, + DIG_COVERAGE_MODE = 1, + DIG_LPS_MODE = 2 +}; + #ifdef PHYDM_TDMA_DIG_SUPPORT enum upd_type { ENABLE_TDMA, @@ -143,8 +149,11 @@ struct phydm_dig_struct { struct phydm_dig_recorder_strcut dig_recorder_t; u8 dig_dl_en; /*@damping limit function enable*/ #endif + boolean fw_dig_enable; boolean is_dbg_fa_th; u8 cur_ig_value; + boolean igi_dyn_up_hit; + u8 igi_trend; u32 rvrt_val; /*all rvrt_val for pause API must set to u32*/ u8 igi_backup; u8 rx_gain_range_max; /*@dig_dynamic_max*/ @@ -154,12 +163,12 @@ struct phydm_dig_struct { u8 dig_max_of_min; /*@Absolutly max of min*/ u32 ant_div_rssi_max; u8 *is_p2p_in_process; - enum dig_goupcheck_level go_up_chk_lv; u16 fa_th[3]; #if (RTL8822B_SUPPORT || RTL8197F_SUPPORT || RTL8821C_SUPPORT ||\ RTL8198F_SUPPORT || RTL8192F_SUPPORT || RTL8195B_SUPPORT ||\ RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8721D_SUPPORT ||\ - RTL8710C_SUPPORT || RTL8812F_SUPPORT || RTL8197G_SUPPORT) + RTL8710C_SUPPORT || RTL8812F_SUPPORT || RTL8197G_SUPPORT ||\ + RTL8723F_SUPPORT) u8 rf_gain_idx; u8 agc_table_idx; u8 big_jump_lmt[16]; @@ -191,6 +200,8 @@ struct phydm_dig_struct { u8 tdma_rx_gain_min[DIG_NUM_OF_TDMA_STATES]; /*To distinguish current state(L-sate or H-state)*/ #endif + u8 tdma_force_l_igi; + u8 tdma_force_h_igi; #endif }; @@ -235,12 +246,15 @@ struct phydm_fa_struct { u8 ofdm2_rate_idx; u32 cnt_ofdm2_crc32_error; u32 cnt_ofdm2_crc32_ok; + u8 ofdm2_pcr; u8 ht2_rate_idx; u32 cnt_ht2_crc32_error; u32 cnt_ht2_crc32_ok; + u8 ht2_pcr; u8 vht2_rate_idx; u32 cnt_vht2_crc32_error; u32 cnt_vht2_crc32_ok; + u8 vht2_pcr; }; @@ -289,6 +303,13 @@ void phydm_set_dig_val(void *dm_void, u32 *val_buf, u8 val_len); void odm_pause_dig(void *dm_void, enum phydm_pause_type pause_type, enum phydm_pause_level pause_level, u8 igi_value); +#ifdef PHYDM_HW_IGI +void phydm_hwigi(void *dm_void); + +void phydm_hwigi_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); +#endif + void phydm_dig_init(void *dm_void); void phydm_dig(void *dm_void); @@ -297,8 +318,14 @@ void phydm_dig_lps_32k(void *dm_void); void phydm_dig_by_rssi_lps(void *dm_void); +void phydm_get_dig_coverage(void *dm_void, u8 *max, u8 *min); + +u8 phydm_get_igi_for_target_pin_scan(void *dm_void, u8 rssi); + void phydm_false_alarm_counter_statistics(void *dm_void); +u32 phydm_get_edcca_report(void * dm_void); + #ifdef PHYDM_TDMA_DIG_SUPPORT void phydm_set_tdma_dig_timer(void *dm_void); @@ -341,12 +368,14 @@ void phydm_set_ofdm_agc_tab(void *dm_void, u8 tab_sel); void phydm_dig_debug(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len); -void phydm_fa_cnt_dbg(void *dm_void, char input[][16], u32 *_used, char *output, - u32 *_out_len); +void phydm_fill_fw_dig_info(void *dm_void, boolean *enable, + u8 *para4, u8 *para8); + +void phydm_crc32_cnt_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); #ifdef CONFIG_MCC_DM void phydm_mcc_igi_cal(void *dm_void); #endif - #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dynamictxpower.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dynamictxpower.c index 710d3406c0c1..d3708becd54e 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dynamictxpower.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dynamictxpower.c @@ -319,15 +319,14 @@ phydm_check_paths(void *dm_void) return max_path; } -#ifndef PHYDM_COMMON_API_SUPPORT +#ifdef PHYDM_COMMON_API_NOT_SUPPORT u8 phydm_dtp_get_txagc(void *dm_void, enum rf_path path, u8 hw_rate) { struct dm_struct *dm = (struct dm_struct *)dm_void; u8 ret = 0xff; -#if (RTL8192E_SUPPORT) ret = config_phydm_read_txagc_n(dm, path, hw_rate); -#endif + return ret; } #endif @@ -338,21 +337,27 @@ u8 phydm_search_min_power_index(void *dm_void) enum rf_path path; enum rf_path max_path; u8 min_gain_index = 0x3f; - u8 gain_index; - u8 rate_idx; + u8 gain_index = 0; + u8 i; PHYDM_DBG(dm, DBG_DYN_TXPWR, "%s\n", __func__); max_path = phydm_check_paths(dm); for (path = 0; path <= max_path; path++) - for (rate_idx = 0; rate_idx < 84; rate_idx++) - if (phydm_check_rates(dm, rate_idx)) { -#ifdef PHYDM_COMMON_API_SUPPORT - /*This is for API support IC : 97F,8822B,92F,8821C*/ - gain_index = phydm_api_get_txagc(dm, path, rate_idx); -#else - /*This is for API non-support IC : 92E */ - gain_index = phydm_dtp_get_txagc(dm, path, rate_idx); -#endif + for (i = 0; i < 84; i++) + if (phydm_check_rates(dm, i)) { + + if (dm->support_ic_type & PHYDM_COMMON_API_IC) { + #ifdef PHYDM_COMMON_API_SUPPORT + /*97F,8822B,92F,8821C*/ + gain_index = phydm_api_get_txagc(dm, path, i); + #endif + } else { + /*92E*/ + #ifdef PHYDM_COMMON_API_NOT_SUPPORT + gain_index = phydm_dtp_get_txagc(dm, path, i); + #endif + } + if (gain_index == 0xff) { min_gain_index = 0x20; PHYDM_DBG(dm, DBG_DYN_TXPWR, @@ -362,7 +367,7 @@ u8 phydm_search_min_power_index(void *dm_void) } PHYDM_DBG(dm, DBG_DYN_TXPWR, "Support Rate: ((%d)) -> Gain idx: ((%d))\n", - rate_idx, gain_index); + i, gain_index); if (gain_index < min_gain_index) min_gain_index = gain_index; } @@ -419,34 +424,45 @@ void phydm_noisy_enhance_hp_th(void *dm_void, u8 noisy_state) dm->enhance_pwr_th[2]); } -u8 phydm_pwr_lvl_check(void *dm_void, u8 input_rssi) +u8 phydm_pwr_lvl_check(void *dm_void, u8 input_rssi, u8 last_pwr_lv) { struct dm_struct *dm = (struct dm_struct *)dm_void; - u8 th0, th1, th2; + u8 th[DTP_POWER_LEVEL_SIZE]; + u8 i; if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - th2 = dm->set_pwr_th[2]; - th1 = dm->set_pwr_th[1]; - th0 = dm->set_pwr_th[0]; + for (i = 0; i < DTP_POWER_LEVEL_SIZE; i++) + th[i] = dm->set_pwr_th[i]; + PHYDM_DBG(dm, DBG_DYN_TXPWR, - "DTP th: Lv1_th = %d, Lv2_th = %d, Lv3_th = %d\n", - th0, th1, th2); + "Ori-DTP th: Lv1_th = %d, Lv2_th = %d, Lv3_th = %d\n", + th[0], th[1], th[2]); + + for (i = 0; i < DTP_POWER_LEVEL_SIZE; i++) { + if (i >= (last_pwr_lv)) + th[i] += DTP_FLOOR_UP_GAP; + } + + PHYDM_DBG(dm, DBG_DYN_TXPWR, + "Mod-DTP th: Lv1_th = %d, Lv2_th = %d, Lv3_th = %d\n", + th[0], th[1], th[2]); } else { - th2 = dm->enhance_pwr_th[2]; - th1 = dm->enhance_pwr_th[1]; - th0 = dm->enhance_pwr_th[0]; + for (i = 0; i < DTP_POWER_LEVEL_SIZE; i++) + th[i] = dm->enhance_pwr_th[i]; + for (i = 0; i < DTP_POWER_LEVEL_SIZE; i++) { + if (i >= (last_pwr_lv)) + th[i] += DTP_FLOOR_UP_GAP; + } } - if (input_rssi >= th2) + if (input_rssi >= th[2]) return tx_high_pwr_level_level3; - else if (input_rssi < (th2 - 3) && input_rssi >= th1) + else if (input_rssi < th[2] && input_rssi >= th[1]) return tx_high_pwr_level_level2; - else if (input_rssi < (th1 - 3) && input_rssi >= th0) + else if (input_rssi < th[1] && input_rssi >= th[0]) return tx_high_pwr_level_level1; - else if (input_rssi < (th0 - 3)) - return tx_high_pwr_level_normal; else - return tx_high_pwr_level_unchange; + return tx_high_pwr_level_normal; } u8 phydm_pwr_lv_mapping(u8 tx_pwr_lv) @@ -469,8 +485,7 @@ void phydm_dynamic_response_power(void *dm_void) if (!(dm->support_ability & ODM_BB_DYNAMIC_TXPWR)) return; - if (dm->dynamic_tx_high_power_lvl == tx_high_pwr_level_unchange) { - dm->dynamic_tx_high_power_lvl = dm->last_dtp_lvl; + if (dm->dynamic_tx_high_power_lvl == dm->last_dtp_lvl) { PHYDM_DBG(dm, DBG_DYN_TXPWR, "RespPwr not change\n"); return; } @@ -507,10 +522,15 @@ void phydm_dtp_per_sta(void *dm_void) struct cmn_sta_info *sta = NULL; struct dtp_info *dtp = NULL; struct rssi_info *rssi = NULL; + struct phydm_bb_ram_ctrl *bb_ctrl = &dm->p_bb_ram_ctrl; u8 sta_cnt = 0; u8 i = 0; u8 curr_pwr_lv = 0; u8 last_pwr_lv = 0; + u8 mac_id_cnt = 0; + u64 macid_cur = 0; + u64 macid_diff = 0; + u64 macid_mask = 0; for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { sta = dm->phydm_sta_info[i]; @@ -519,43 +539,64 @@ void phydm_dtp_per_sta(void *dm_void) dtp = &sta->dtp_stat; rssi = &sta->rssi_stat; + macid_mask = (u64)BIT(sta->mac_id); + if (!(bb_ctrl->macid_is_linked & macid_mask)) + dtp->sta_last_dtp_lvl = tx_high_pwr_level_normal; + last_pwr_lv = dtp->sta_last_dtp_lvl; - curr_pwr_lv = phydm_pwr_lvl_check(dm, rssi->rssi); + curr_pwr_lv = phydm_pwr_lvl_check(dm, rssi->rssi, + last_pwr_lv); dtp->sta_tx_high_power_lvl = curr_pwr_lv; PHYDM_DBG(dm, DBG_DYN_TXPWR, "STA_id=%d, MACID=%d , RSSI: %d , GetPwrLv: %d\n", i, sta->mac_id, rssi->rssi, curr_pwr_lv); - if (curr_pwr_lv == tx_high_pwr_level_unchange || - curr_pwr_lv == last_pwr_lv) { + bb_ctrl->macid_is_linked |= macid_mask; + macid_cur |= macid_mask; + PHYDM_DBG(dm, DBG_DYN_TXPWR, + "macid_is_linked: (0x%llx), macid_cur: (0x%llx)\n", + bb_ctrl->macid_is_linked, macid_cur); + + if (curr_pwr_lv == last_pwr_lv && dtp->sta_is_alive) { dtp->sta_tx_high_power_lvl = last_pwr_lv; PHYDM_DBG(dm, DBG_DYN_TXPWR, "DTP_lv not change: ((%d))\n", curr_pwr_lv); - return; - } + } else { + PHYDM_DBG(dm, DBG_DYN_TXPWR, + "DTP_lv update: ((%d)) -> ((%d))\n", + last_pwr_lv, curr_pwr_lv); - PHYDM_DBG(dm, DBG_DYN_TXPWR, - "DTP_lv update: ((%d)) -> ((%d))\n", - last_pwr_lv, curr_pwr_lv); + dtp->sta_last_dtp_lvl = curr_pwr_lv; - dtp->sta_last_dtp_lvl = curr_pwr_lv; - - switch (dm->ic_ip_series) { - #ifdef BB_RAM_SUPPORT - case PHYDM_IC_JGR3: - phydm_dtp_fill_cmninfo_2nd(dm, i, curr_pwr_lv); - break; - #endif - default: - phydm_dtp_fill_cmninfo(dm, i, curr_pwr_lv); - break; + switch (dm->ic_ip_series) { + #ifdef BB_RAM_SUPPORT + case PHYDM_IC_JGR3: + phydm_dtp_fill_cmninfo_2nd(dm, i, curr_pwr_lv); + break; + #endif + default: + phydm_dtp_fill_cmninfo(dm, i, curr_pwr_lv); + break; + } + if(!dtp->sta_is_alive) + dtp->sta_is_alive = true; } if (sta_cnt == dm->number_linked_client) break; } } + + macid_diff = bb_ctrl->macid_is_linked ^ macid_cur; + if (macid_diff) + bb_ctrl->macid_is_linked &= ~macid_diff; + while (macid_diff) { + if (macid_diff & 0x1) + phydm_pwr_lv_ctrl(dm, mac_id_cnt, tx_high_pwr_level_normal); + mac_id_cnt++; + macid_diff >>= 1; + } } void odm_set_dyntxpwr(void *dm_void, u8 *desc, u8 sta_id) @@ -691,7 +732,8 @@ void phydm_dynamic_tx_power(void *dm_void) phydm_noisy_enhance_hp_th(dm, dm->noisy_decision); /* Response Power */ dm->dynamic_tx_high_power_lvl = phydm_pwr_lvl_check(dm, - rssi_min); + rssi_min, + dm->last_dtp_lvl); phydm_dynamic_response_power(dm); } /* Per STA Tx power */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dynamictxpower.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dynamictxpower.h index 2973b79a0ea6..75b460d43280 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dynamictxpower.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_dynamictxpower.h @@ -33,9 +33,11 @@ * ============================================================ */ -/* 2019.6.14, Modify per sta API to fix the AP problem of early return*/ +/* 2020.6.23, Let gain_idx be initialized to 0 for linux compile warning*/ #define DYNAMIC_TXPWR_VERSION "2.1" +#define DTP_POWER_LEVEL_SIZE 3 + #if (DM_ODM_SUPPORT_TYPE == ODM_AP) #define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 #define TX_POWER_NEAR_FIELD_THRESH_LVL1 60 @@ -49,9 +51,9 @@ #endif #if (DM_ODM_SUPPORT_TYPE == ODM_AP) -#define TX_PWR_NEAR_FIELD_TH_JGR3_LVL3 255 -#define TX_PWR_NEAR_FIELD_TH_JGR3_LVL2 74 -#define TX_PWR_NEAR_FIELD_TH_JGR3_LVL1 60 +#define TX_PWR_NEAR_FIELD_TH_JGR3_LVL3 80 +#define TX_PWR_NEAR_FIELD_TH_JGR3_LVL2 63 +#define TX_PWR_NEAR_FIELD_TH_JGR3_LVL1 55 #elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) #define TX_PWR_NEAR_FIELD_TH_JGR3_LVL3 90 #define TX_PWR_NEAR_FIELD_TH_JGR3_LVL2 85 @@ -67,6 +69,7 @@ #define tx_high_pwr_level_level2 2 #define tx_high_pwr_level_level3 3 #define tx_high_pwr_level_unchange 4 +#define DTP_FLOOR_UP_GAP 3 /* @============================================================ * enumrate diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features.h index 839edba32e59..9ea49d2fea17 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features.h @@ -40,6 +40,7 @@ #define ODM_DYM_BW_INDICATION_SUPPORT (ODM_RTL8821C | \ ODM_RTL8822B | \ ODM_RTL8822C) + /*@20170103 YuChen add for FW API*/ #define PHYDM_FW_API_ENABLE_8822B 1 #define PHYDM_FW_API_FUNC_ENABLE_8822B 1 @@ -57,6 +58,8 @@ #define PHYDM_FW_API_FUNC_ENABLE_8812F 1 #define PHYDM_FW_API_ENABLE_8197G 1 #define PHYDM_FW_API_FUNC_ENABLE_8197G 1 +#define PHYDM_FW_API_ENABLE_8723F 1 +#define PHYDM_FW_API_FUNC_ENABLE_8723F 1 #define CONFIG_POWERSAVING 0 diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_ap.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_ap.h index 95ed232f0dc4..4a531a928fcc 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_ap.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_ap.h @@ -20,7 +20,7 @@ #if (RTL8814A_SUPPORT || RTL8821C_SUPPORT || RTL8822B_SUPPORT ||\ RTL8197F_SUPPORT || RTL8192F_SUPPORT || RTL8198F_SUPPORT ||\ RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8814B_SUPPORT ||\ - RTL8197G_SUPPORT) + RTL8197G_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_LA_MODE_SUPPORT 1 #else #define PHYDM_LA_MODE_SUPPORT 0 @@ -31,9 +31,14 @@ #define DYN_ANT_WEIGHTING_SUPPORT #endif -#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT) +#if (RTL8822B_SUPPORT || RTL8198F_SUPPORT || RTL8814B_SUPPORT ||\ + RTL8197G_SUPPORT || RTL8812F_SUPPORT || RTL8723F_SUPPORT) #define FAHM_SUPPORT #endif + +#if (RTL8197G_SUPPORT || RTL8812F_SUPPORT || RTL8723F_SUPPORT) + #define IFS_CLM_SUPPORT +#endif #define NHM_SUPPORT #define CLM_SUPPORT @@ -46,7 +51,7 @@ #endif #if (RTL8198F_SUPPORT || RTL8814B_SUPPORT || RTL8812F_SUPPORT ||\ - RTL8197G_SUPPORT) + RTL8197G_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_TDMA_DIG_SUPPORT 1 #ifdef PHYDM_TDMA_DIG_SUPPORT #define IS_USE_NEW_TDMA /*new tdma dig test*/ @@ -77,12 +82,12 @@ #endif #if (RTL8814B_SUPPORT || RTL8198F_SUPPORT || RTL8822C_SUPPORT ||\ - RTL8812F_SUPPORT || RTL8197G_SUPPORT) + RTL8812F_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_PMAC_TX_SETTING_SUPPORT #endif #if (RTL8814B_SUPPORT || RTL8198F_SUPPORT || RTL8822C_SUPPORT ||\ - RTL8812F_SUPPORT || RTL8197G_SUPPORT) + RTL8812F_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_MP_SUPPORT #endif @@ -124,6 +129,14 @@ #define CONFIG_DYNAMIC_TX_TWR #endif +#if (RTL8197G_SUPPORT || RTL8812F_SUPPORT) + #define PHYDM_HW_IGI +#endif + +#if (RTL8197G_SUPPORT || RTL8812F_SUPPORT) + #define CONFIG_DYNAMIC_TXCOLLISION_TH +#endif + /*#define CONFIG_PSD_TOOL*/ #define PHYDM_SUPPORT_CCKPD #define PHYDM_SUPPORT_ADAPTIVITY @@ -145,7 +158,7 @@ #endif #endif -#if defined(CONFIG_RTL_8881A_ANT_SWITCH) || defined(CONFIG_SLOT_0_ANT_SWITCH) || defined(CONFIG_SLOT_1_ANT_SWITCH) || defined(CONFIG_RTL_8197F_ANT_SWITCH) +#if defined(CONFIG_RTL_8881A_ANT_SWITCH) || defined(CONFIG_SLOT_0_ANT_SWITCH) || defined(CONFIG_SLOT_1_ANT_SWITCH) || defined(CONFIG_RTL_8197F_ANT_SWITCH) || defined(CONFIG_RTL_8197G_ANT_SWITCH) #define CONFIG_PHYDM_ANTENNA_DIVERSITY #define ODM_EVM_ENHANCE_ANTDIV /*#define SKIP_EVM_ANTDIV_TRAINING_PATCH*/ @@ -159,6 +172,15 @@ #define CONFIG_2G_CG_TRX_DIVERSITY #endif + /*----------*/ + #ifdef CONFIG_NO_2G_DIVERSITY_8197G + #define CONFIG_NO_2G_DIVERSITY + #elif defined(CONFIG_2G_CGCS_RX_DIVERSITY_8197G) + #define CONFIG_2G_CGCS_RX_DIVERSITY + #elif defined(CONFIG_2G_CG_TRX_DIVERSITY_8197G) + #define CONFIG_2G_CG_TRX_DIVERSITY + #endif + #if (!defined(CONFIG_NO_2G_DIVERSITY) && !defined(CONFIG_2G5G_CG_TRX_DIVERSITY_8881A) && !defined(CONFIG_2G_CGCS_RX_DIVERSITY) && !defined(CONFIG_2G_CG_TRX_DIVERSITY) && !defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY)) #define CONFIG_NO_2G_DIVERSITY #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_ce.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_ce.h index 90ae1d5e9c87..90637316c55f 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_ce.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_ce.h @@ -29,7 +29,7 @@ #if (RTL8814A_SUPPORT || RTL8821C_SUPPORT || RTL8822B_SUPPORT ||\ RTL8197F_SUPPORT || RTL8192F_SUPPORT || RTL8198F_SUPPORT ||\ - RTL8822C_SUPPORT) + RTL8822C_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_LA_MODE_SUPPORT 1 #else #define PHYDM_LA_MODE_SUPPORT 0 @@ -40,9 +40,14 @@ #define DYN_ANT_WEIGHTING_SUPPORT #endif -#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT) +#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT || RTL8822C_SUPPORT ||\ + RTL8814B_SUPPORT || RTL8723F_SUPPORT) #define FAHM_SUPPORT #endif + +#if (RTL8822C_SUPPORT || RTL8723F_SUPPORT) + #define IFS_CLM_SUPPORT +#endif #define NHM_SUPPORT #define CLM_SUPPORT @@ -57,7 +62,7 @@ /*@#define PHYDM_TDMA_DIG_SUPPORT*/ #if (RTL8822B_SUPPORT || RTL8192F_SUPPORT || RTL8821C_SUPPORT ||\ - RTL8822C_SUPPORT || RTL8723D_SUPPORT) + RTL8822C_SUPPORT || RTL8723D_SUPPORT ) #ifdef CONFIG_TDMADIG #define PHYDM_TDMA_DIG_SUPPORT #ifdef PHYDM_TDMA_DIG_SUPPORT @@ -91,15 +96,15 @@ #endif #endif -#if (RTL8822B_SUPPORT || RTL8192F_SUPPORT) +#if (RTL8822B_SUPPORT || RTL8192F_SUPPORT || RTL8723D_SUPPORT) #define PHYDM_POWER_TRAINING_SUPPORT #endif -#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT) +#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_PMAC_TX_SETTING_SUPPORT #endif -#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT) +#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_MP_SUPPORT #endif @@ -143,6 +148,9 @@ #ifdef CONFIG_SUPPORT_DYNAMIC_TXPWR #define CONFIG_DYNAMIC_TX_TWR #endif +#if (RTL8822C_SUPPORT) +#define PHYDM_HW_IGI +#endif #define PHYDM_SUPPORT_CCKPD #define PHYDM_SUPPORT_ADAPTIVITY diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_iot.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_iot.h index a97596c0f8e8..4b1e162d53ad 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_iot.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_iot.h @@ -115,10 +115,14 @@ #ifdef CONFIG_PHYDM_ANTENNA_DIVERSITY #if (RTL8723B_SUPPORT || RTL8821A_SUPPORT ||\ - RTL8188F_SUPPORT || RTL8821C_SUPPORT) + RTL8188F_SUPPORT || RTL8821C_SUPPORT || RTL8195B_SUPPORT) #define CONFIG_S0S1_SW_ANTENNA_DIVERSITY #endif - + + #if (RTL8710C_SUPPORT) + //#define CONFIG_S0S1_SW_ANTENNA_DIVERSITY + #endif + #if (RTL8821A_SUPPORT) /*#define CONFIG_HL_SMART_ANTENNA_TYPE1*/ #endif @@ -151,7 +155,9 @@ /*#define CONFIG_PATH_DIVERSITY*/ /*#define CONFIG_RA_DYNAMIC_RTY_LIMIT*/ //#define CONFIG_BB_TXBF_API +#if DBG #define CONFIG_PHYDM_DEBUG_FUNCTION +#endif #ifdef CONFIG_BT_COEXIST #define ODM_CONFIG_BT_COEXIST diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_win.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_win.h index 19e42e5a3746..30a5f94e140a 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_win.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_features_win.h @@ -19,7 +19,7 @@ #if (RTL8814A_SUPPORT || RTL8821C_SUPPORT || RTL8822B_SUPPORT ||\ RTL8197F_SUPPORT || RTL8192F_SUPPORT || RTL8198F_SUPPORT ||\ - RTL8822C_SUPPORT || RTL8814B_SUPPORT) + RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_LA_MODE_SUPPORT 1 #else #define PHYDM_LA_MODE_SUPPORT 0 @@ -30,9 +30,14 @@ #define DYN_ANT_WEIGHTING_SUPPORT #endif -#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT) +#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT || RTL8822C_SUPPORT ||\ + RTL8814B_SUPPORT || RTL8723F_SUPPORT) #define FAHM_SUPPORT #endif + +#if (RTL8822C_SUPPORT || RTL8723F_SUPPORT) + #define IFS_CLM_SUPPORT +#endif #define NHM_SUPPORT #define CLM_SUPPORT @@ -76,11 +81,11 @@ #define PHYDM_POWER_TRAINING_SUPPORT #endif -#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT) +#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_PMAC_TX_SETTING_SUPPORT #endif -#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT) +#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_MP_SUPPORT #endif @@ -169,9 +174,15 @@ /* #ifdef CONFIG_SUPPORT_DYNAMIC_TXPWR */ #define CONFIG_DYNAMIC_TX_TWR /* #endif */ +#if (RTL8822C_SUPPORT) +#define PHYDM_HW_IGI +#endif #define CONFIG_PSD_TOOL #define PHYDM_SUPPORT_ADAPTIVITY #define PHYDM_SUPPORT_CCKPD +#if (defined(PHYDM_SUPPORT_CCKPD) && RTL8822C_SUPPORT) + #define PHYDM_DCC_ENHANCE +#endif /*#define CONFIG_RA_DYNAMIC_RTY_LIMIT*/ #define CONFIG_ANT_DETECTION #define CONFIG_BB_TXBF_API diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_hwconfig.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_hwconfig.c index 1fca9f1b9a98..ea73396793cc 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_hwconfig.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_hwconfig.c @@ -252,6 +252,8 @@ odm_config_rf_with_header_file(struct dm_struct *dm, READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type17); else if (dm->rfe_type == 18) READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type18); + //else if (dm->rfe_type == 19) + //READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type19); else READ_AND_CONFIG_MP(8822b, _txpwr_lmt); } @@ -427,10 +429,25 @@ odm_config_rf_with_header_file(struct dm_struct *dm, else if (e_rf_path == RF_PATH_B) READ_AND_CONFIG_MP(8822c, _radiob); } else if (config_type == CONFIG_RF_TXPWR_LMT) { - READ_AND_CONFIG_MP(8822c, _txpwr_lmt); + if (dm->rfe_type == 5) + READ_AND_CONFIG_MP(8822c, _txpwr_lmt_type5); + else + READ_AND_CONFIG_MP(8822c, _txpwr_lmt); } } #endif +#if (RTL8723F_SUPPORT) + if (dm->support_ic_type == ODM_RTL8723F) { + if (config_type == CONFIG_RF_RADIO) { + if (e_rf_path == RF_PATH_A) + READ_AND_CONFIG_MP(8723f, _radioa); + if (e_rf_path == RF_PATH_B) + READ_AND_CONFIG_MP(8723f, _radiob); + } else if (config_type == CONFIG_RF_TXPWR_LMT) { + READ_AND_CONFIG_MP(8723f, _txpwr_lmt); + } + } +#endif #if (RTL8812F_SUPPORT) if (dm->support_ic_type == ODM_RTL8812F) { if (config_type == CONFIG_RF_RADIO) { @@ -664,6 +681,8 @@ odm_config_rf_with_tx_pwr_track_header_file(struct dm_struct *dm) READ_AND_CONFIG_MP(8822b, _txpowertrack_type17); else if (dm->rfe_type == 18) READ_AND_CONFIG_MP(8822b, _txpowertrack_type18); + //else if (dm->rfe_type == 19) + //READ_AND_CONFIG_MP(8822b, _txpowertrack_type19); else READ_AND_CONFIG_MP(8822b, _txpowertrack); } @@ -823,6 +842,10 @@ odm_config_rf_with_tx_pwr_track_header_file(struct dm_struct *dm) } #endif +#if (RTL8723F_SUPPORT) + if (dm->support_ic_type == ODM_RTL8723F) + READ_AND_CONFIG_MP(8723f, _txpowertrack); +#endif #if (RTL8812F_SUPPORT) if (dm->support_ic_type == ODM_RTL8812F) { if (dm->rfe_type == 0) @@ -1072,6 +1095,8 @@ odm_config_bb_with_header_file(struct dm_struct *dm, READ_AND_CONFIG_MP(8822b, _phy_reg_pg_type17); else if (dm->rfe_type == 18) READ_AND_CONFIG_MP(8822b, _phy_reg_pg_type18); + //else if (dm->rfe_type == 19) + //READ_AND_CONFIG_MP(8822b, _phy_reg_pg_type19); else READ_AND_CONFIG_MP(8822b, _phy_reg_pg); } @@ -1230,12 +1255,18 @@ odm_config_bb_with_header_file(struct dm_struct *dm, #endif #if (RTL8195B_SUPPORT == 1) if (dm->support_ic_type == ODM_RTL8195B) { - if (config_type == CONFIG_BB_PHY_REG) + if (config_type == CONFIG_BB_PHY_REG) { READ_AND_CONFIG(8195b, _phy_reg); - else if (config_type == CONFIG_BB_AGC_TAB) + } else if (config_type == CONFIG_BB_AGC_TAB) { READ_AND_CONFIG(8195b, _agc_tab); - else if (config_type == CONFIG_BB_PHY_REG_PG) + } else if (config_type == CONFIG_BB_PHY_REG_PG) { READ_AND_CONFIG(8195b, _phy_reg_pg); + } else if (config_type == CONFIG_BB_PHY_REG_MP) { + if (dm->package_type == 1) + odm_set_bb_reg(dm, R_0xaa8, 0x1f0000, 0x10); + else + odm_set_bb_reg(dm, R_0xaa8, 0x1f0000, 0x12); + } } #endif #if (RTL8198F_SUPPORT == 1) @@ -1270,6 +1301,16 @@ odm_config_bb_with_header_file(struct dm_struct *dm, READ_AND_CONFIG(8822c, _phy_reg_pg); } #endif +#if (RTL8723F_SUPPORT) + if (dm->support_ic_type == ODM_RTL8723F) { + if (config_type == CONFIG_BB_PHY_REG) + READ_AND_CONFIG_MP(8723f, _phy_reg); + else if (config_type == CONFIG_BB_AGC_TAB) + READ_AND_CONFIG_MP(8723f, _agc_tab); + else if (config_type == CONFIG_BB_PHY_REG_PG) + READ_AND_CONFIG(8723f, _phy_reg_pg); + } +#endif #if (RTL8812F_SUPPORT) if (dm->support_ic_type == ODM_RTL8812F) { if (config_type == CONFIG_BB_PHY_REG) @@ -1319,9 +1360,8 @@ odm_config_mac_with_header_file(struct dm_struct *dm) "support_platform: 0x%X, support_interface: 0x%X, board_type: 0x%X\n", dm->support_platform, dm->support_interface, dm->board_type); -#if (RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8814B_SUPPORT) - if (dm->support_ic_type & - (ODM_RTL8822C | ODM_RTL8812F | ODM_RTL8814B)) { +#ifdef PHYDM_IC_HALMAC_PARAM_SUPPORT + if (dm->support_ic_type & PHYDM_IC_SUPPORT_HALMAC_PARAM_OFFLOAD) { PHYDM_DBG(dm, ODM_COMP_INIT, "MAC para-package in HALMAC\n"); return result; } @@ -1543,6 +1583,11 @@ u32 odm_get_hw_img_version(struct dm_struct *dm) version = odm_get_version_mp_8197g_phy_reg(); break; #endif +#if (RTL8723F_SUPPORT) + case ODM_RTL8723F: + version = odm_get_version_mp_8723f_phy_reg(); + break; +#endif #if (RTL8814B_SUPPORT) case ODM_RTL8814B: version = odm_get_version_mp_8814b_phy_reg(); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_interface.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_interface.c index 5acc70a78e54..b867fdd7f73b 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_interface.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_interface.c @@ -791,7 +791,7 @@ u8 phydm_trans_h2c_id(struct dm_struct *dm, u8 phydm_h2c_id) #elif (DM_ODM_SUPPORT_TYPE & ODM_AP) #if ((RTL8881A_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8814A_SUPPORT == 1) || (RTL8822B_SUPPORT == 1) || (RTL8197F_SUPPORT == 1) || (RTL8192F_SUPPORT == 1)) /*@jj add 20170822*/ - if (dm->support_ic_type == ODM_RTL8881A || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type & PHYDM_IC_3081_SERIES) + if (dm->support_ic_type & (ODM_RTL8881A | ODM_RTL8192E | ODM_RTL8192F | PHYDM_IC_3081_SERIES)) platform_h2c_id = H2C_88XX_RSSI_REPORT; else #endif @@ -853,7 +853,7 @@ u8 phydm_trans_h2c_id(struct dm_struct *dm, u8 phydm_h2c_id) #elif (DM_ODM_SUPPORT_TYPE & ODM_AP) #if ((RTL8881A_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8814A_SUPPORT == 1) || (RTL8822B_SUPPORT == 1) || (RTL8197F_SUPPORT == 1) || (RTL8192F_SUPPORT == 1)) /*@jj add 20170822*/ - if (dm->support_ic_type == ODM_RTL8881A || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type & PHYDM_IC_3081_SERIES) + if (dm->support_ic_type & (ODM_RTL8881A | ODM_RTL8192E | ODM_RTL8192F | PHYDM_IC_3081_SERIES)) platform_h2c_id = H2C_88XX_RA_PARA_ADJUST; else #endif @@ -904,7 +904,7 @@ u8 phydm_trans_h2c_id(struct dm_struct *dm, u8 phydm_h2c_id) #elif (DM_ODM_SUPPORT_TYPE & ODM_AP) #if ((RTL8881A_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8814A_SUPPORT == 1) || (RTL8822B_SUPPORT == 1) || (RTL8197F_SUPPORT == 1) || (RTL8192F_SUPPORT == 1)) /*@jj add 20170822*/ - if (dm->support_ic_type == ODM_RTL8881A || dm->support_ic_type == ODM_RTL8192E || dm->support_ic_type & PHYDM_IC_3081_SERIES) + if (dm->support_ic_type & (ODM_RTL8881A | ODM_RTL8192E | ODM_RTL8192F | PHYDM_IC_3081_SERIES)) platform_h2c_id = H2C_88XX_FW_TRACE_EN; else #endif @@ -922,7 +922,8 @@ u8 phydm_trans_h2c_id(struct dm_struct *dm, u8 phydm_h2c_id) case PHYDM_H2C_TXBF: #if ((RTL8192E_SUPPORT == 1) || (RTL8812A_SUPPORT == 1)) - platform_h2c_id = 0x41; /*@H2C_TxBF*/ + if (dm->support_ic_type & (ODM_RTL8192E | ODM_RTL8812)) + platform_h2c_id = 0x41; /*@H2C_TxBF*/ #endif break; @@ -1270,7 +1271,7 @@ odm_dpk_by_fw(struct dm_struct *dm) #if (DM_ODM_SUPPORT_TYPE & ODM_WIN) struct _ADAPTER *adapter = dm->adapter; - if (HAL_MAC_FWDPK_Trigger(&GET_HAL_MAC_INFO(adapter)) == 0) + if (hal_mac_fwdpk_trigger(&GET_HAL_MAC_INFO(adapter)) == 0) dpk_result = HAL_STATUS_SUCCESS; #else dpk_result = rtw_phydm_fw_dpk(dm); @@ -1440,6 +1441,25 @@ u8 phydm_get_tx_power_dbm(struct dm_struct *dm, u8 rf_path, return tx_power_dbm; } +s16 phydm_get_tx_power_mdbm(struct dm_struct *dm, u8 rf_path, + u8 rate, u8 bandwidth, u8 channel) +{ + s16 tx_power_dbm = 0; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + struct _ADAPTER *adapter = dm->adapter; + tx_power_dbm = PHY_GetTxPowerFinalAbsoluteValuemdBm(adapter, rf_path, rate, bandwidth, channel); +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + tx_power_dbm = rtw_odm_get_tx_power_mbm(dm, rf_path, rate, bandwidth, channel); +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + tx_power_dbm = PHY_GetTxPowerFinalAbsoluteValuembm(dm, rf_path, rate, bandwidth, channel); +#endif + return tx_power_dbm; +} + u32 phydm_rfe_ctrl_gpio(struct dm_struct *dm, u8 gpio_num) { #if (DM_ODM_SUPPORT_TYPE == ODM_CE) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_interface.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_interface.h index e890c49279ea..72a1c00a3bd6 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_interface.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_interface.h @@ -49,6 +49,7 @@ enum phydm_h2c_cmd { PHYDM_H2C_MCC = 0x4f, PHYDM_H2C_RESP_TX_PATH_CTRL = 0x50, PHYDM_H2C_RESP_TX_ANT_CTRL = 0x51, + PHYDM_H2C_FW_DM_CTRL = 0x55, ODM_MAX_H2CCMD }; @@ -318,6 +319,9 @@ u8 phydm_get_tx_rate(struct dm_struct *dm); u8 phydm_get_tx_power_dbm(struct dm_struct *dm, u8 rf_path, u8 rate, u8 bandwidth, u8 channel); +s16 phydm_get_tx_power_mdbm(struct dm_struct *dm, u8 rf_path, + u8 rate, u8 bandwidth, u8 channel); + u32 phydm_rfe_ctrl_gpio(struct dm_struct *dm, u8 gpio_num); u64 phydm_division64(u64 x, u64 y); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_lna_sat.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_lna_sat.c index aa333219f498..12c3c802bdbb 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_lna_sat.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_lna_sat.c @@ -56,8 +56,7 @@ void phydm_lna_sat_chk_init( lna_info->pre_timer_check_cnt = 0; #if (RTL8198F_SUPPORT || RTL8814B_SUPPORT) - if (dm->support_ic_type & - (ODM_RTL8198F | ODM_RTL8814B)) + if (dm->support_ic_type & (ODM_RTL8198F | ODM_RTL8814B)) phydm_lna_sat_chk_bb_init(dm); #endif } @@ -520,7 +519,7 @@ void phydm_lna_sat_chk_watchdog_type1( u8 rssi_min = dm->rssi_min; - PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "\n%s ==>\n", __func__); + PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__); if (!(dm->support_ability & ODM_BB_LNA_SAT_CHK)) { PHYDM_DBG(dm, DBG_LNA_SAT_CHK, @@ -541,13 +540,6 @@ void phydm_lna_sat_chk_watchdog_type1( return; } - if (!(dm->support_ic_type & - (ODM_RTL8197F | ODM_RTL8198F | ODM_RTL8814B))) { - PHYDM_DBG(dm, DBG_LNA_SAT_CHK, - "support_ic_type not 97F/98F/14B, return\n"); - return; - } - if (rssi_min == 0 || rssi_min == 0xff) { /*@adapt agc table 0 */ phydm_set_ofdm_agc_tab(dm, OFDM_AGC_TAB_0); @@ -1157,16 +1149,365 @@ void phydm_lna_sat_type2_sm( return; } } - - #endif /*@#ifdef PHYDM_LNA_SAT_CHK_TYPE2*/ -void phydm_lna_sat_debug( - void *dm_void, - char input[][16], - u32 *_used, - char *output, - u32 *_out_len) +#ifdef PHYDM_HW_SWITCH_AGC_TAB +u32 phydm_get_lna_pd_reg(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 rf_pd_reg = RF_0x8b; + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) { + if (*dm->channel <= 14) + rf_pd_reg = RF_0x87; + else + rf_pd_reg = RF_0x8b; + } +#endif + return rf_pd_reg; +} + +u32 phydm_get_lna_pd_en_mask(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 rf_pd_en_msk = BIT(2); + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) { + if (*dm->channel <= 14) + rf_pd_en_msk = BIT(4); + else + rf_pd_en_msk = BIT(2); + } +#endif + return rf_pd_en_msk; +} + +boolean phydm_get_lna_pd_en(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 rf_pd_reg = RF_0x8b; + u32 rf_pd_en_msk = BIT(2); + u32 pd_en = 0; + + rf_pd_reg = phydm_get_lna_pd_reg(dm); + rf_pd_en_msk = phydm_get_lna_pd_en_mask(dm); + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) + pd_en = config_phydm_read_rf_reg_8814b(dm, RF_PATH_A, + rf_pd_reg, + rf_pd_en_msk); +#endif + return (boolean)pd_en; +} + +void phydm_set_lna_pd_en(void *dm_void, boolean lna_pd_en) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + enum rf_path i = RF_PATH_A; + u32 rf_pd_reg = RF_0x8b; + u32 rf_pd_en_msk = BIT(2); + + rf_pd_reg = phydm_get_lna_pd_reg(dm); + rf_pd_en_msk = phydm_get_lna_pd_en_mask(dm); + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) + for (i = RF_PATH_A; i < MAX_PATH_NUM_8814B; i++) + config_phydm_write_rf_reg_8814b(dm, i, + rf_pd_reg, + rf_pd_en_msk, + (u8)lna_pd_en); +#endif +} + +u32 phydm_get_lna_pd_th_mask(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 rf_pd_th_msk = 0x3; + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) + rf_pd_th_msk = 0x3; +#endif + return rf_pd_th_msk; +} + +enum lna_pd_th_level phydm_get_lna_pd_th_lv(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 rf_pd_reg = RF_0x8b; + u32 rf_pd_th_msk = 0x3; + u32 pd_th_lv = 0x0; + + rf_pd_reg = phydm_get_lna_pd_reg(dm); + rf_pd_th_msk = phydm_get_lna_pd_th_mask(dm); + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) + pd_th_lv = config_phydm_read_rf_reg_8814b(dm, RF_PATH_A, + rf_pd_reg, + rf_pd_th_msk); +#endif + return (enum lna_pd_th_level)pd_th_lv; +} + +void phydm_set_lna_pd_th_lv(void *dm_void, + enum lna_pd_th_level lna_pd_th_lv) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + enum rf_path i = RF_PATH_A; + u32 rf_pd_reg = RF_0x8b; + u32 rf_pd_th_msk = 0x3; + + rf_pd_reg = phydm_get_lna_pd_reg(dm); + rf_pd_th_msk = phydm_get_lna_pd_th_mask(dm); + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) + for (i = RF_PATH_A; i < MAX_PATH_NUM_8814B; i++) + config_phydm_write_rf_reg_8814b(dm, i, + rf_pd_reg, + rf_pd_th_msk, + lna_pd_th_lv); +#endif +} + +u32 phydm_get_sat_agc_tab_version(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) + return odm_get_version_mp_8814b_extra_agc_tab(); +#endif + return 0; +} + +boolean phydm_get_auto_agc_config(void *dm_void, + enum agc_tab_switch_state state_sel) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 state_en = 0; +#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT + switch (state_sel) { + case AGC_SWH_IDLE: + state_en = odm_get_bb_reg(dm, R_0x18ac, BIT(16)); + break; + case AGC_SWH_OFDM: + state_en = odm_get_bb_reg(dm, R_0x18ac, BIT(17)); + break; + case AGC_SWH_CCK: + state_en = odm_get_bb_reg(dm, R_0x18ac, BIT(18)); + break; + default: + state_en = 0; + break; + } +#endif + return (boolean)state_en; +} + +boolean phydm_is_auto_agc_on(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + boolean state_on = false; + + state_on = ((phydm_get_auto_agc_config(dm, AGC_SWH_IDLE) || + phydm_get_auto_agc_config(dm, AGC_SWH_CCK) || + phydm_get_auto_agc_config(dm, AGC_SWH_OFDM)) && + phydm_get_lna_pd_en(dm)); + + return state_on; +} + +void phydm_config_auto_agc(void *dm_void, + boolean idle_en, + boolean cck_cca_en, + boolean ofdm_cca_en) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + u32 hwagc_opt = 0; +#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT + if (dm->support_ic_type & ~ODM_RTL8814B) + return; + + if (idle_en) + hwagc_opt |= BIT(0); + else + hwagc_opt &= ~BIT(0); + if (ofdm_cca_en) + hwagc_opt |= BIT(1); + else + hwagc_opt &= ~BIT(1); + if (cck_cca_en) + hwagc_opt |= BIT(2); + else + hwagc_opt &= ~BIT(2); + + odm_set_bb_reg(dm, R_0x18ac, BIT(18) | BIT(17) | BIT(16), hwagc_opt); +#ifdef PHYDM_COMPILE_ABOVE_2SS + odm_set_bb_reg(dm, R_0x41ac, BIT(18) | BIT(17) | BIT(16), hwagc_opt); +#endif +#ifdef PHYDM_COMPILE_ABOVE_3SS + odm_set_bb_reg(dm, R_0x52ac, BIT(18) | BIT(17) | BIT(16), hwagc_opt); +#endif +#ifdef PHYDM_COMPILE_ABOVE_4SS + odm_set_bb_reg(dm, R_0x53ac, BIT(18) | BIT(17) | BIT(16), hwagc_opt); +#endif +#endif +} + +void phydm_auto_agc_tab_reset(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + phydm_set_lna_pd_th_lv(dm, 0x0); + phydm_config_auto_agc(dm, true, false, true); + phydm_set_lna_pd_en(dm, true); +} + +void phydm_auto_agc_tab_off(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + phydm_config_auto_agc(dm, false, false, false); + phydm_set_lna_pd_en(dm, false); +} + +void phydm_switch_sat_agc_by_band(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info; + +#if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) + odm_config_mp_8814b_extra_agc_tab(dm, lna_sat->cur_rf_band); +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + pr_debug("%s ==> switch to band%d\n", __func__, lna_sat->cur_rf_band); +#else + PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==> switch to band%d\n", + __func__, lna_sat->cur_rf_band); +#endif +} + +void phydm_auto_agc_tab_init(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info; + u8 channel = *dm->channel; + + lna_sat->cur_rf_band = phydm_ch_to_rf_band(dm, channel); + phydm_switch_sat_agc_by_band(dm); + + if ((dm->support_ability & ODM_BB_LNA_SAT_CHK)) { + phydm_auto_agc_tab_reset(dm); + lna_sat->hw_swh_tab_on = true; + } else { + phydm_auto_agc_tab_off(dm); + lna_sat->hw_swh_tab_on = false; + } +} + +void phydm_auto_agc_tab_watchdog(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info; + boolean hw_swh_on = false; + + PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__); + + if (!(dm->support_ability & ODM_BB_LNA_SAT_CHK)) { + if (lna_sat->hw_swh_tab_on) { + phydm_auto_agc_tab_off(dm); + lna_sat->hw_swh_tab_on = false; + } + PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "Disabled LNA sat. check\n"); + return; + } + + if (!lna_sat->hw_swh_tab_on) + PHYDM_DBG(dm, DBG_LNA_SAT_CHK, + "[WARNING] HW switch AGC Tab not fully enabled\n"); +} + +void phydm_auto_agc_tab_debug(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info; + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 i; + u8 agc_tab = 0; + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "LNA sat. AGC Tab version : %d\n", + phydm_get_sat_agc_tab_version(dm)); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Enable LNA peak detector : {0} {lna_pd_en = %d}\n", + phydm_get_lna_pd_en(dm)); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Set LNA peak detector lv : {1} {lna_pd_th_lv = %d}\n", + phydm_get_lna_pd_th_lv(dm)); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Config hw switch AGC tab : {2} {hw_swh_en_rx_idle} {hw_swh_en_cck_cca} {hw_swh_en_ofdm_cca} = (%d, %d, %d)\n", + phydm_get_auto_agc_config(dm, AGC_SWH_IDLE), + phydm_get_auto_agc_config(dm, AGC_SWH_CCK), + phydm_get_auto_agc_config(dm, AGC_SWH_OFDM)); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Reset to default setting : {3}\n", + phydm_get_auto_agc_config(dm, AGC_SWH_IDLE), + phydm_get_auto_agc_config(dm, AGC_SWH_CCK), + phydm_get_auto_agc_config(dm, AGC_SWH_OFDM)); + + } else { + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + for (i = 1; i < 10; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + } + + if (var1[0] == 0) { + phydm_set_lna_pd_en(dm, (boolean)var1[1]); + PDM_SNPF(out_len, used, output + used, out_len - used, + "set lna_pd_en = %d\n", + (u8)phydm_get_lna_pd_en(dm)); + } else if (var1[0] == 1) { + phydm_set_lna_pd_th_lv(dm, (u8)var1[1]); + PDM_SNPF(out_len, used, output + used, out_len - used, + "set lna_pd_th_lv = %d\n", + phydm_get_lna_pd_th_lv(dm)); + } else if (var1[0] == 2) { + phydm_config_auto_agc(dm, (boolean)var1[1], + (boolean)var1[2], + (boolean)var1[3]); + PDM_SNPF(out_len, used, output + used, out_len - used, + "set hw switch agc tab en: (rx_idle, cck_cca, ofdm_cca) = (%d, %d, %d)\n", + phydm_get_auto_agc_config(dm, AGC_SWH_IDLE), + phydm_get_auto_agc_config(dm, AGC_SWH_CCK), + phydm_get_auto_agc_config(dm, AGC_SWH_OFDM)); + } else if (var1[0] == 3) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "reset to default settings\n"); + phydm_auto_agc_tab_reset(dm); + } + lna_sat->hw_swh_tab_on = phydm_is_auto_agc_on(dm); + } + *_used = used; + *_out_len = out_len; +} +#endif /*@#ifdef PHYDM_HW_SWITCH_AGC_TAB*/ + +void phydm_lna_sat_debug(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_lna_sat_t *lna_t = &dm->dm_lna_sat_info; @@ -1261,8 +1602,7 @@ void phydm_lna_sat_debug( *_out_len = out_len; } -void phydm_lna_sat_chk_watchdog( - void *dm_void) +void phydm_lna_sat_chk_watchdog(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info; @@ -1270,29 +1610,40 @@ void phydm_lna_sat_chk_watchdog( PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "%s ==>\n", __func__); if (lna_sat->lna_sat_type == LNA_SAT_WITH_PEAK_DET) { + #ifdef PHYDM_HW_SWITCH_AGC_TAB + if (dm->support_ic_type & ODM_RTL8814B) { + phydm_auto_agc_tab_watchdog(dm); + return; + } + #endif #ifdef PHYDM_LNA_SAT_CHK_TYPE1 - phydm_lna_sat_chk_watchdog_type1(dm); + if (dm->support_ic_type & + (ODM_RTL8197F | ODM_RTL8198F | ODM_RTL8814B)) { + phydm_lna_sat_chk_watchdog_type1(dm); + return; + } #endif } else if (lna_sat->lna_sat_type == LNA_SAT_WITH_TRAIN) { #ifdef PHYDM_LNA_SAT_CHK_TYPE2 - + return; #endif } + PHYDM_DBG(dm, DBG_LNA_SAT_CHK, "support_ic_type match fail, return\n"); } -void phydm_lna_sat_config( - void *dm_void) +void phydm_lna_sat_config(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info; + lna_sat->lna_sat_type = 0; #if (RTL8822B_SUPPORT == 1) if (dm->support_ic_type & (ODM_RTL8822B)) lna_sat->lna_sat_type = LNA_SAT_WITH_TRAIN; #endif - #if (RTL8197F_SUPPORT || RTL8192F_SUPPORT ||\ + #if (RTL8197F_SUPPORT || RTL8192F_SUPPORT || \ RTL8198F_SUPPORT || RTL8814B_SUPPORT) if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8198F | ODM_RTL8814B)) @@ -1303,15 +1654,11 @@ void phydm_lna_sat_config( __func__, lna_sat->lna_sat_type); } -void phydm_lna_sat_check_init( - void *dm_void) +void phydm_lna_sat_check_init(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_lna_sat_t *lna_sat = &dm->dm_lna_sat_info; - if ((dm->support_ability & ODM_BB_LNA_SAT_CHK)) - return; - /*@2018.04.17 Johnson*/ phydm_lna_sat_config(dm); #ifdef PHYDM_LNA_SAT_CHK_TYPE1 @@ -1323,6 +1670,12 @@ void phydm_lna_sat_check_init( /*@2018.04.17 Johnson end*/ if (lna_sat->lna_sat_type == LNA_SAT_WITH_PEAK_DET) { + #ifdef PHYDM_HW_SWITCH_AGC_TAB + if (dm->support_ic_type & ODM_RTL8814B) { + phydm_auto_agc_tab_init(dm); + return; + } + #endif #ifdef PHYDM_LNA_SAT_CHK_TYPE1 phydm_lna_sat_chk_init(dm); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_lna_sat.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_lna_sat.h index 10d21feb4526..c2fbe79431fa 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_lna_sat.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_lna_sat.h @@ -32,7 +32,7 @@ * 1 ============================================================ */ -#define LNA_SAT_VERSION "1.0" +#define LNA_SAT_VERSION "1.1" /*@LNA saturation check*/ #define OFDM_AGC_TAB_0 0 @@ -78,6 +78,21 @@ enum lna_sat_type { LNA_SAT_WITH_TRAIN = 2, /*type2*/ }; +#ifdef PHYDM_HW_SWITCH_AGC_TAB +enum lna_pd_th_level { + LNA_PD_TH_LEVEL0 = 0, + LNA_PD_TH_LEVEL1 = 1, + LNA_PD_TH_LEVEL2 = 2, + LNA_PD_TH_LEVEL3 = 3 +}; + +enum agc_tab_switch_state { + AGC_SWH_IDLE, + AGC_SWH_CCK, + AGC_SWH_OFDM +}; +#endif + /* @1 ============================================================ * 1 structure * 1 ============================================================ @@ -131,6 +146,10 @@ struct phydm_lna_sat_t { u32 check_time; boolean pre_sat_status; boolean cur_sat_status; +#ifdef PHYDM_HW_SWITCH_AGC_TAB + boolean hw_swh_tab_on; + enum odm_rf_band cur_rf_band; +#endif struct phydm_timer_list phydm_lna_sat_chk_timer; u32 cur_timer_check_cnt; u32 pre_timer_check_cnt; @@ -170,5 +189,9 @@ void phydm_lna_sat_chk_watchdog(void *dm_void); void phydm_lna_sat_check_init(void *dm_void); +#ifdef PHYDM_HW_SWITCH_AGC_TAB +void phydm_auto_agc_tab_debug(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); +#endif #endif /*@#if (PHYDM_LNA_SAT_CHK_SUPPORT == 1)*/ #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_math_lib.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_math_lib.c index 3d8ab7a861d5..4e9f125d5d60 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_math_lib.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_math_lib.c @@ -160,27 +160,32 @@ u32 odm_convert_to_db(u64 value) break; } + /*special cases*/ if (j == 0 && i == 0) goto end; + if (i == 3 && j == 0) { + if (db_invert_table[3][0] - value > + value - (db_invert_table[2][7] >> FRAC_BITS)) { + i = 2; + j = 7; + } + goto end; + } + + if (i < 3) + value = value << FRAC_BITS; /*@elements of row 0~2 shift left*/ + + /*compare difference to get precise dB*/ if (j == 0) { - if (i != 3) { - if (db_invert_table[i][0] - value > - value - db_invert_table[i - 1][7]) { - i = i - 1; - j = 7; - } - } else { - if (db_invert_table[3][0] - value > - value - db_invert_table[2][7]) { - i = 2; - j = 7; - } + if (db_invert_table[i][j] - value > + value - db_invert_table[i - 1][7]) { + i = i - 1; + j = 7; } } else { if (db_invert_table[i][j] - value > value - db_invert_table[i][j - 1]) { - i = i + 0; j = j - 1; } } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_mp.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_mp.c index ed26896341d9..aeff71499b77 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_mp.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_mp.c @@ -41,6 +41,8 @@ void phydm_mp_set_single_tone_jgr3(void *dm_void, boolean is_single_tone, struct phydm_mp *mp = &dm->dm_mp_table; u8 start = RF_PATH_A, end = RF_PATH_A; u8 i = 0; + u8 central_ch = 0; + boolean is_2g_ch = false; switch (path) { case RF_PATH_A: @@ -54,7 +56,7 @@ void phydm_mp_set_single_tone_jgr3(void *dm_void, boolean is_single_tone, start = RF_PATH_A; end = RF_PATH_B; break; -#if (RTL8814B_SUPPORT == 1 || RTL8198F_SUPPORT == 1) +#if (defined(PHYDM_COMPILE_IC_4SS)) case RF_PATH_AC: start = RF_PATH_A; end = RF_PATH_C; @@ -97,62 +99,115 @@ void phydm_mp_set_single_tone_jgr3(void *dm_void, boolean is_single_tone, break; #endif } + + central_ch = (u8)odm_get_rf_reg(dm, RF_PATH_A, RF_0x18, 0xff); + is_2g_ch = (central_ch <= 14) ? true : false; + if (is_single_tone) { - mp->rf_reg0 = odm_get_rf_reg(dm, RF_PATH_A, RF_0x00, 0xfffff); -#if 0 - mp->rfe_sel_a_0 = odm_get_bb_reg(dm, R_0x1840, MASKDWORD); - mp->rfe_sel_b_0 = odm_get_bb_reg(dm, R_0x4140, MASKDWORD); - mp->rfe_sel_c_0 = odm_get_bb_reg(dm, R_0x5240, MASKDWORD); - mp->rfe_sel_d_0 = odm_get_bb_reg(dm, R_0x5340, MASKDWORD); - mp->rfe_sel_a_1 = odm_get_bb_reg(dm, R_0x1844, MASKDWORD); - mp->rfe_sel_b_1 = odm_get_bb_reg(dm, R_0x4144, MASKDWORD); - mp->rfe_sel_c_1 = odm_get_bb_reg(dm, R_0x5244, MASKDWORD); - mp->rfe_sel_d_1 = odm_get_bb_reg(dm, R_0x5344, MASKDWORD); -#endif - /* Disable CCK and OFDM */ - odm_set_bb_reg(dm, R_0x1c3c, 0x3, 0x0); - for (i = start; i <= end; i++) { - /* @Tx mode: RF0x00[19:16]=4'b0010 */ - odm_set_rf_reg(dm, i, RF_0x0, 0xF0000, 0x2); - /* @Lowest RF gain index: RF_0x0[4:0] = 0*/ - odm_set_rf_reg(dm, i, RF_0x0, 0x1F, 0x0); - /* @RF LO enabled */ - odm_set_rf_reg(dm, i, RF_0x58, BIT(1), 0x1); + /*Disable CCA*/ + if (is_2g_ch) { /*CCK RxIQ weighting = [0,0]*/ + if(dm->support_ic_type & ODM_RTL8723F) { + odm_set_bb_reg(dm, R_0x2a24, BIT(13), 0x1); /*CCK*/ + } else { + odm_set_bb_reg(dm, R_0x1a9c, BIT(20), 0x0); + odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x3); + } } + odm_set_bb_reg(dm, R_0x1d58, 0xff8, 0x1ff); /*OFDM*/ + if (dm->support_ic_type & ODM_RTL8723F) { + odm_set_rf_reg(dm, RF_PATH_A, RF_0x5, BIT(0), 0x0); + for (i = start; i <= end; i++) { + mp->rf0[i] = odm_get_rf_reg(dm, i, RF_0x0, RFREG_MASK); + /*Tx mode: RF0x00[19:16]=4'b0010 */ + odm_set_rf_reg(dm, i, RF_0x0, 0xF0000, 0x2); + /*Lowest RF gain index: RF_0x1[5:0] TX power*/ + mp->rf1[i] = odm_get_rf_reg(dm, i, RF_0x1, RFREG_MASK); + odm_set_rf_reg(dm, i, RF_0x1, 0x3f, 0x0);//TX power + /*RF LO enabled */ + odm_set_rf_reg(dm, i, RF_0x58, BIT(1), 0x1); + } + } else { + for (i = start; i <= end; i++) { + mp->rf0[i] = odm_get_rf_reg(dm, i, RF_0x0, RFREG_MASK); + /*Tx mode: RF0x00[19:16]=4'b0010 */ + odm_set_rf_reg(dm, i, RF_0x0, 0xF0000, 0x2); + /*Lowest RF gain index: RF_0x0[4:0] = 0*/ + odm_set_rf_reg(dm, i, RF_0x0, 0x1f, 0x0); + /*RF LO enabled */ + odm_set_rf_reg(dm, i, RF_0x58, BIT(1), 0x1); + } + } + #if (RTL8814B_SUPPORT) if (dm->support_ic_type & ODM_RTL8814B) { - /* @Tx mode: RF0x00[19:16]=4'b0010 */ + mp->rf0_syn[RF_SYN0] = config_phydm_read_syn_reg_8814b( + dm, RF_SYN0, RF_0x0, RFREG_MASK); + /*Lowest RF gain index: RF_0x0[4:0] = 0x0*/ config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x0, - 0xF0000, 0x2); - /* @Lowest RF gain index: RF_0x0[4:0] = 0*/ - config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x0, - 0x1F, 0x0); - /* @RF LO enabled */ + 0x1f, 0x0); + /*RF LO enabled */ config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x58, BIT(1), 0x1); + /*SYN1*/ + if (*dm->band_width == CHANNEL_WIDTH_80_80) { + mp->rf0_syn[RF_SYN1] = config_phydm_read_syn_reg_8814b( + dm, RF_SYN1, RF_0x0, + RFREG_MASK); + config_phydm_write_rf_syn_8814b(dm, RF_SYN1, + RF_0x0, 0x1f, + 0x0); + config_phydm_write_rf_syn_8814b(dm, RF_SYN1, + RF_0x58, BIT(1), + 0x1); + } } #endif } else { - /* Eable CCK and OFDM */ - odm_set_bb_reg(dm, R_0x1c3c, 0x3, 0x3); - if (!(dm->support_ic_type & ODM_RTL8814B)) { + /*Enable CCA*/ + if (is_2g_ch) { /*CCK RxIQ weighting = [1,1]*/ + if(dm->support_ic_type & ODM_RTL8723F) { + odm_set_bb_reg(dm, R_0x2a24, BIT(13), 0x0); /*CCK*/ + } else { + odm_set_bb_reg(dm, R_0x1a9c, BIT(20), 0x1); + odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x0); + } + } + odm_set_bb_reg(dm, R_0x1d58, 0xff8, 0x0); /*OFDM*/ + + if(dm->support_ic_type & ODM_RTL8723F) { for (i = start; i <= end; i++) { - odm_set_rf_reg(dm, i, RF_0x00, 0xfffff, - mp->rf_reg0); - /* RF LO disabled */ + odm_set_rf_reg(dm, i, RF_0x0, RFREG_MASK, mp->rf0[i]); + odm_set_rf_reg(dm, i, RF_0x1, RFREG_MASK, mp->rf1[i]); + /*RF LO disabled */ + odm_set_rf_reg(dm, i, RF_0x58, BIT(1), 0x0); + } + odm_set_rf_reg(dm, RF_PATH_A, RF_0x5, BIT(0), 0x1); + } else { + for (i = start; i <= end; i++) { + odm_set_rf_reg(dm, i, RF_0x0, RFREG_MASK, mp->rf0[i]); + /*RF LO disabled */ odm_set_rf_reg(dm, i, RF_0x58, BIT(1), 0x0); } } -#if 0 - odm_set_bb_reg(dm, R_0x1840, MASKDWORD, mp->rfe_sel_a_0); - odm_set_bb_reg(dm, R_0x4140, MASKDWORD, mp->rfe_sel_b_0); - odm_set_bb_reg(dm, R_0x5240, MASKDWORD, mp->rfe_sel_c_0); - odm_set_bb_reg(dm, R_0x5340, MASKDWORD, mp->rfe_sel_d_0); - odm_set_bb_reg(dm, R_0x1844, MASKDWORD, mp->rfe_sel_a_1); - odm_set_bb_reg(dm, R_0x4144, MASKDWORD, mp->rfe_sel_b_1); - odm_set_bb_reg(dm, R_0x5244, MASKDWORD, mp->rfe_sel_c_1); - odm_set_bb_reg(dm, R_0x5344, MASKDWORD, mp->rfe_sel_d_1); -#endif + #if (RTL8814B_SUPPORT) + if (dm->support_ic_type & ODM_RTL8814B) { + config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x0, + RFREG_MASK, + mp->rf0_syn[RF_SYN0]); + config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x58, + BIT(1), 0x0); + /*SYN1*/ + if (*dm->band_width == CHANNEL_WIDTH_80_80) { + config_phydm_write_rf_syn_8814b(dm, RF_SYN1, + RF_0x0, + RFREG_MASK, + mp->rf0_syn[RF_SYN1]); + config_phydm_write_rf_syn_8814b(dm, RF_SYN1, + RF_0x58, BIT(1), + 0x0); + } + } + #endif } } @@ -164,34 +219,140 @@ void phydm_mp_set_carrier_supp_jgr3(void *dm_void, boolean is_carrier_supp, if (is_carrier_supp) { if (phydm_is_cck_rate(dm, (u8)rate_index)) { - /* @if CCK block on? */ + /*if CCK block on? */ if (!odm_get_bb_reg(dm, R_0x1c3c, BIT(1))) odm_set_bb_reg(dm, R_0x1c3c, BIT(1), 1); - /* @Turn Off All Test mode */ - odm_set_bb_reg(dm, R_0x1ca4, 0x7, 0x0); - - /* @transmit mode */ - odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x2); - /* @turn off scramble setting */ - odm_set_bb_reg(dm, R_0x1a00, 0x8, 0x0); - /* @Set CCK Tx Test Rate, set FTxRate to 1Mbps */ - odm_set_bb_reg(dm, R_0x1a00, 0x3000, 0x0); + if(dm->support_ic_type & ODM_RTL8723F){ + /* @Carrier suppress tx */ + odm_set_bb_reg(dm, R_0x2a08, BIT(18), 0x1); + /*turn off scramble setting */ + odm_set_bb_reg(dm, R_0x2a04, BIT(5), 0x1); + /*Set CCK Tx Test Rate, set TxRate to 2Mbps */ + odm_set_bb_reg(dm, R_0x2a08, 0x300000, 0x1); + /* BB and PMAC cont tx */ + odm_set_bb_reg(dm, R_0x2a08, BIT(17), 0x1); + odm_set_bb_reg(dm, R_0x2a00, BIT(28), 0x1); + /* TX CCK ON */ + odm_set_bb_reg(dm, R_0x2a08, BIT(31), 0x0); + odm_set_bb_reg(dm, R_0x2a08, BIT(31), 0x1); + } + else { + /*Turn Off All Test mode */ + odm_set_bb_reg(dm, R_0x1ca4, 0x7, 0x0); + + /*transmit mode */ + odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x2); + /*turn off scramble setting */ + odm_set_bb_reg(dm, R_0x1a00, BIT(3), 0x0); + /*Set CCK Tx Test Rate, set TxRate to 1Mbps */ + odm_set_bb_reg(dm, R_0x1a00, 0x3000, 0x0); + } } - } else { /* @Stop Carrier Suppression. */ + } else { /*Stop Carrier Suppression. */ if (phydm_is_cck_rate(dm, (u8)rate_index)) { - /* @normal mode */ - odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x0); - /* @turn on scramble setting */ - odm_set_bb_reg(dm, R_0x1a00, 0x8, 0x1); - /* @BB Reset */ - odm_set_bb_reg(dm, R_0x1d0c, 0x10000, 0x0); - odm_set_bb_reg(dm, R_0x1d0c, 0x10000, 0x1); + if(dm->support_ic_type & ODM_RTL8723F) { + /* TX Stop */ + odm_set_bb_reg(dm, R_0x2a00, BIT(0), 0x1); + /* Clear BB cont tx */ + odm_set_bb_reg(dm, R_0x2a00, BIT(28), 0x0); + /* Clear PMAC cont tx */ + odm_set_bb_reg(dm, R_0x2a08, BIT(17), 0x0); + /* Clear TX Stop */ + odm_set_bb_reg(dm, R_0x2a00, BIT(0), 0x0); + /* normal mode */ + odm_set_bb_reg(dm, R_0x2a08, BIT(18), 0x0); + /* turn on scramble setting */ + odm_set_bb_reg(dm, R_0x2a04, BIT(5), 0x0); + } + else { + /*normal mode */ + odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x0); + /*turn on scramble setting */ + odm_set_bb_reg(dm, R_0x1a00, BIT(3), 0x1); + } + /*BB Reset */ + odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x0); + odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x1); } } } -#endif +void phydm_mp_set_single_carrier_jgr3(void *dm_void, boolean is_single_carrier) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_mp *mp = &dm->dm_mp_table; + + if (is_single_carrier) { + /*1. if OFDM block on? */ + if (!odm_get_bb_reg(dm, R_0x1c3c, BIT(0))) + odm_set_bb_reg(dm, R_0x1c3c, BIT(0), 1); + + if (dm->support_ic_type & ODM_RTL8723F) { + /*3. turn on scramble setting */ + odm_set_bb_reg(dm, R_0x2a04, BIT(5), 0); + /*4. Turn On single carrier. */ + odm_set_bb_reg(dm, R_0x1ca4, 0x7, OFDM_SINGLE_CARRIER); + } + else { + /*2. set CCK test mode off, set to CCK normal mode */ + odm_set_bb_reg(dm, R_0x1a00, 0x3, 0); + /*3. turn on scramble setting */ + odm_set_bb_reg(dm, R_0x1a00, BIT(3), 1); + /*4. Turn On single carrier. */ + odm_set_bb_reg(dm, R_0x1ca4, 0x7, OFDM_SINGLE_CARRIER); + } + } else { + /*Turn off all test modes. */ + odm_set_bb_reg(dm, R_0x1ca4, 0x7, OFDM_OFF); + + /*Delay 10 ms */ + ODM_delay_ms(10); + + /*BB Reset*/ + odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x0); + odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x1); + } +} + +void phydm_mp_get_tx_ok_jgr3(void *dm_void, u32 rate_index) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_mp *mp = &dm->dm_mp_table; + + if (phydm_is_cck_rate(dm, (u8)rate_index)) + mp->tx_phy_ok_cnt = odm_get_bb_reg(dm, R_0x2de4, MASKLWORD); + else + mp->tx_phy_ok_cnt = odm_get_bb_reg(dm, R_0x2de0, MASKLWORD); +} + +void phydm_mp_get_rx_ok_jgr3(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_mp *mp = &dm->dm_mp_table; + + u32 cck_ok = 0, ofdm_ok = 0, ht_ok = 0, vht_ok = 0; + u32 cck_err = 0, ofdm_err = 0, ht_err = 0, vht_err = 0; + if(dm->support_ic_type & ODM_RTL8723F) + cck_ok = odm_get_bb_reg(dm, R_0x2aac, MASKLWORD); + else + cck_ok = odm_get_bb_reg(dm, R_0x2c04, MASKLWORD); + ofdm_ok = odm_get_bb_reg(dm, R_0x2c14, MASKLWORD); + ht_ok = odm_get_bb_reg(dm, R_0x2c10, MASKLWORD); + vht_ok = odm_get_bb_reg(dm, R_0x2c0c, MASKLWORD); + if(dm->support_ic_type & ODM_RTL8723F) + cck_err = odm_get_bb_reg(dm, R_0x2aac, MASKHWORD); + else + cck_err = odm_get_bb_reg(dm, R_0x2c04, MASKHWORD); + ofdm_err = odm_get_bb_reg(dm, R_0x2c14, MASKHWORD); + ht_err = odm_get_bb_reg(dm, R_0x2c10, MASKHWORD); + vht_err = odm_get_bb_reg(dm, R_0x2c0c, MASKHWORD); + + mp->rx_phy_ok_cnt = cck_ok + ofdm_ok + ht_ok + vht_ok; + mp->rx_phy_crc_err_cnt = cck_err + ofdm_err + ht_err + vht_err; + mp->io_value = (u32)mp->rx_phy_ok_cnt; +} +#endif void phydm_mp_set_crystal_cap(void *dm_void, u8 crystal_cap) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -219,61 +380,9 @@ void phydm_mp_set_carrier_supp(void *dm_void, boolean is_carrier_supp, void phydm_mp_set_single_carrier(void *dm_void, boolean is_single_carrier) { struct dm_struct *dm = (struct dm_struct *)dm_void; - struct phydm_mp *mp = &dm->dm_mp_table; - if (is_single_carrier) { - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - /* @1. if OFDM block on? */ - if (!odm_get_bb_reg(dm, R_0x1c3c, BIT(0))) - odm_set_bb_reg(dm, R_0x1c3c, BIT(0), 1); - - /* @2. set CCK test mode off, set to CCK normal mode */ - odm_set_bb_reg(dm, R_0x1a00, 0x3, 0); - - /* @3. turn on scramble setting */ - odm_set_bb_reg(dm, R_0x1a00, 0x8, 1); - - /* @4. Turn On single carrier. */ - odm_set_bb_reg(dm, R_0x1ca4, 0x7, OFDM_SINGLE_CARRIER); - } else { - /* @1. if OFDM block on? */ - if (!odm_get_bb_reg(dm, R_0x800, 0x2000000)) - odm_set_bb_reg(dm, R_0x800, 0x2000000, 1); - - /* @2. set CCK test mode off, set to CCK normal mode */ - odm_set_bb_reg(dm, R_0xa00, 0x3, 0); - - /* @3. turn on scramble setting */ - odm_set_bb_reg(dm, R_0xa00, 0x8, 1); - - /* @4. Turn On single carrier. */ - if (dm->support_ic_type & ODM_IC_11AC_SERIES) - odm_set_bb_reg(dm, R_0x914, 0x70000, - OFDM_SINGLE_CARRIER); - else if (dm->support_ic_type & ODM_IC_11N_SERIES) - odm_set_bb_reg(dm, R_0xd00, 0x70000000, - OFDM_SINGLE_CARRIER); - } - } else { /* @Stop Single Carrier. */ - /* @Turn off all test modes. */ - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) - odm_set_bb_reg(dm, R_0x1ca4, 0x7, OFDM_OFF); - else if (dm->support_ic_type & ODM_IC_11AC_SERIES) - odm_set_bb_reg(dm, R_0x914, 0x70000, OFDM_OFF); - else if (dm->support_ic_type & ODM_IC_11N_SERIES) - odm_set_bb_reg(dm, R_0xd00, 0x70000000, OFDM_OFF); - /* @Delay 10 ms */ - ODM_delay_ms(10); - - /* @BB Reset */ - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - odm_set_bb_reg(dm, R_0x1d0c, 0x10000, 0x0); - odm_set_bb_reg(dm, R_0x1d0c, 0x10000, 0x1); - } else { - odm_set_bb_reg(dm, R_0x100, 0x100, 0x0); - odm_set_bb_reg(dm, R_0x100, 0x100, 0x1); - } - } + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) + phydm_mp_set_single_carrier_jgr3(dm, is_single_carrier); } void phydm_mp_reset_rx_counters_phy(void *dm_void) { @@ -285,65 +394,16 @@ void phydm_mp_reset_rx_counters_phy(void *dm_void) void phydm_mp_get_tx_ok(void *dm_void, u32 rate_index) { struct dm_struct *dm = (struct dm_struct *)dm_void; - struct phydm_mp *mp = &dm->dm_mp_table; - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - if (phydm_is_cck_rate(dm, (u8)rate_index)) - mp->tx_phy_ok_cnt = odm_get_bb_reg(dm, R_0x2de4, - 0xffff); - else - mp->tx_phy_ok_cnt = odm_get_bb_reg(dm, R_0x2de0, - 0xffff); - } else { - if (phydm_is_cck_rate(dm, (u8)rate_index)) - mp->tx_phy_ok_cnt = odm_get_bb_reg(dm, R_0xf50, - 0xffff); - else - mp->tx_phy_ok_cnt = odm_get_bb_reg(dm, R_0xf50, - 0xffff0000); - } + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) + phydm_mp_get_tx_ok_jgr3(dm, rate_index); } void phydm_mp_get_rx_ok(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; - struct phydm_mp *mp = &dm->dm_mp_table; - u32 cck_ok = 0, ofdm_ok = 0, ht_ok = 0, vht_ok = 0; - u32 cck_err = 0, ofdm_err = 0, ht_err = 0, vht_err = 0; - - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { - cck_ok = odm_get_bb_reg(dm, R_0x2c04, 0xffff); - ofdm_ok = odm_get_bb_reg(dm, R_0x2c14, 0xffff); - ht_ok = odm_get_bb_reg(dm, R_0x2c10, 0xffff); - vht_ok = odm_get_bb_reg(dm, R_0x2c0c, 0xffff); - - cck_err = odm_get_bb_reg(dm, R_0x2c04, 0xffff0000); - ofdm_err = odm_get_bb_reg(dm, R_0x2c14, 0xffff0000); - ht_err = odm_get_bb_reg(dm, R_0x2c10, 0xffff0000); - vht_err = odm_get_bb_reg(dm, R_0x2c0c, 0xffff0000); - } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { - cck_ok = odm_get_bb_reg(dm, R_0xf04, 0x3FFF); - ofdm_ok = odm_get_bb_reg(dm, R_0xf14, 0x3FFF); - ht_ok = odm_get_bb_reg(dm, R_0xf10, 0x3FFF); - vht_ok = odm_get_bb_reg(dm, R_0xf0c, 0x3FFF); - - cck_err = odm_get_bb_reg(dm, R_0xf04, 0x3FFF0000); - ofdm_err = odm_get_bb_reg(dm, R_0xf14, 0x3FFF0000); - ht_err = odm_get_bb_reg(dm, R_0xf10, 0x3FFF0000); - vht_err = odm_get_bb_reg(dm, R_0xf0c, 0x3FFF0000); - } else if (dm->support_ic_type & ODM_IC_11N_SERIES) { - cck_ok = odm_get_bb_reg(dm, R_0xf88, MASKDWORD); - ofdm_ok = odm_get_bb_reg(dm, R_0xf94, 0xffff); - ht_ok = odm_get_bb_reg(dm, R_0xf90, 0xffff); - - cck_err = odm_get_bb_reg(dm, R_0xf84, MASKDWORD); - ofdm_err = odm_get_bb_reg(dm, R_0xf94, 0xffff0000); - ht_err = odm_get_bb_reg(dm, R_0xf90, 0xffff0000); - } - - mp->rx_phy_ok_cnt = cck_ok + ofdm_ok + ht_ok + vht_ok; - mp->rx_phy_crc_err_cnt = cck_err + ofdm_err + ht_err + vht_err; - mp->io_value = (u32)mp->rx_phy_ok_cnt; + if (dm->support_ic_type & ODM_IC_JGR3_SERIES) + phydm_mp_get_rx_ok_jgr3(dm); } #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_mp.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_mp.h index f4cbcd032d84..b45c631c2512 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_mp.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_mp.h @@ -27,7 +27,8 @@ #ifndef __PHYDM_MP_H__ #define __PHYDM_MP_H__ -#define MP_VERSION "1.3" +/*2020.04.27 Refine single tone Tx flow*/ +#define MP_VERSION "1.5" /* @1 ============================================================ * 1 Definition @@ -38,22 +39,18 @@ * 1 ============================================================ */ struct phydm_mp { - /* @Rx OK count, statistics used in Mass Production Test.*/ + /*Rx OK count, statistics used in Mass Production Test.*/ u64 tx_phy_ok_cnt; u64 rx_phy_ok_cnt; - /* @Rx CRC32 error count, statistics used in Mass Production Test.*/ + /*Rx CRC32 error count, statistics used in Mass Production Test.*/ u64 rx_phy_crc_err_cnt; - /* @The Value of IO operation is depend of MptActType.*/ + /*The Value of IO operation is depend of MptActType.*/ u32 io_value; - u32 rf_reg0; - /* @u32 rfe_sel_a_0;*/ - /* @u32 rfe_sel_b_0;*/ - /* @u32 rfe_sel_c_0;*/ - /* @u32 rfe_sel_d_0;*/ - /* @u32 rfe_sel_a_1;*/ - /* @u32 rfe_sel_b_1;*/ - /* @u32 rfe_sel_c_1;*/ - /* @u32 rfe_sel_d_1;*/ + u32 rf0[RF_PATH_MEM_SIZE]; + #if (RTL8814B_SUPPORT) + u32 rf0_syn[2]; + #endif + u32 rf1[RF_PATH_MEM_SIZE]; }; /* @1 ============================================================ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_noisemonitor.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_noisemonitor.c index ddcab0c39969..da94aedaf56f 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_noisemonitor.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_noisemonitor.c @@ -259,7 +259,8 @@ s16 odm_inband_noise_monitor_ac(struct dm_struct *dm, u8 pause_dig, u8 igi, s32 value32, pwdb_A = 0, sval, noise, sum = 0; boolean pd_flag; u8 valid_cnt = 0; - u64 start = 0, func_start = 0, func_end = 0; + u8 invalid_cnt = 0; + u64 start = 0, func_start = 0, func_end = 0, proc_time = 0; s32 val_s32 = 0; s16 rpt = 0; u8 val_u8 = 0; @@ -351,6 +352,15 @@ s16 odm_inband_noise_monitor_ac(struct dm_struct *dm, u8 pause_dig, u8 igi, "After divided, sum = %d\n", sum); break; } + } else { + /*Invalid sval and return -110 dBm*/ + invalid_cnt++; + PHYDM_DBG(dm, DBG_ENV_MNTR, "Invalid sval\n"); + if (invalid_cnt >= VALID_CNT + 5) { + PHYDM_DBG(dm, DBG_ENV_MNTR, + "Invalid count > TH, Return -110, Break!!\n"); + return -110; + } } } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pathdiv.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pathdiv.c index a544d629cc9e..f8135e912877 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pathdiv.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pathdiv.c @@ -1041,10 +1041,8 @@ void phydm_pathdiv_debug(void *dm_void, char input[][16], u32 *_used, u8 i, input_idx = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &val[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &val[i]); + input_idx++; } if (input_idx == 0) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_phystatus.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_phystatus.c index 7aeccd38818b..429a1e5c8056 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_phystatus.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_phystatus.c @@ -238,7 +238,7 @@ void phydm_avg_rssi_evm_snr(void *dm_void, if (pktinfo->data_rate <= ODM_RATE11M) { /*RSSI*/ dbg_s->rssi_cck_sum += rssi[0]; - #ifdef PHYSTS_3RD_TYPE_SUPPORT + #if (defined(PHYSTS_3RD_TYPE_SUPPORT) && defined(PHYDM_COMPILE_ABOVE_2SS)) if (dm->support_ic_type & PHYSTS_3RD_TYPE_IC) { for (i = 1; i < dm->num_rf_path; i++) dbg_s->rssi_cck_sum_abv_2ss[i - 1] += rssi[i]; @@ -951,6 +951,9 @@ void phydm_phy_sts_n_parsing(struct dm_struct *dm, * value to positive one, then the dbm value * (which is supposed to be negative) is not correct anymore. */ + if (i >= PHYDM_MAX_RF_PATH_N) + break; + EVM = phydm_evm_2_percent(phy_sts->stream_rxevm[i]); /*@Fill value in RFD, Get the 1st spatial stream only*/ @@ -1355,7 +1358,8 @@ void phydm_process_rssi_for_dm(struct dm_struct *dm, /* @--------------Statistic for antenna/path diversity--------------- */ #ifdef ODM_EVM_ENHANCE_ANTDIV - phydm_rx_rate_for_antdiv(dm, pktinfo); + if (dm->antdiv_evm_en) + phydm_rx_rate_for_antdiv(dm, pktinfo); #endif #if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) @@ -1671,6 +1675,8 @@ void phydm_print_phystat_jgr3(struct dm_struct *dm, u8 *phy_sts, struct phy_sts_rpt_jgr3_type2_3 *rpt2 = NULL; struct phy_sts_rpt_jgr3_type4 *rpt3 = NULL; struct phy_sts_rpt_jgr3_type5 *rpt4 = NULL; + struct phy_sts_rpt_jgr3_type6 *rpt5 = NULL; + struct odm_phy_dbg_info *dbg = &dm->phy_dbg_info; u8 phy_status_page_num = (*phy_sts & 0xf); u32 *phy_status_tmp = NULL; @@ -1686,6 +1692,13 @@ void phydm_print_phystat_jgr3(struct dm_struct *dm, u8 *phy_sts, rpt3 = (struct phy_sts_rpt_jgr3_type4 *)phy_sts; rpt4 = (struct phy_sts_rpt_jgr3_type5 *)phy_sts; + if (dm->support_ic_type & ODM_RTL8723F) { + rpt5 = (struct phy_sts_rpt_jgr3_type6 *)phy_sts; + + if (pktinfo->is_cck_rate) + phy_status_page_num = 0; + } + phy_status_tmp = (u32 *)phy_sts; if (dbg->show_phy_sts_all_pkt == 0) { @@ -1714,32 +1727,51 @@ void phydm_print_phystat_jgr3(struct dm_struct *dm, u8 *phy_sts, ((4 * i) + 3), (4 * i), phy_status_tmp[i]); if (phy_status_page_num == 0) { /* @CCK(default) */ - pr_debug("[0] Pkt_cnt=%d, Channel_msb=%d, Pwdb_a=%d, Gain_a=%d, TRSW=%d, AGC_table_b=%d, AGC_table_c=%d,\n", - rpt0->pkt_cnt, rpt0->channel_msb, rpt0->pwdb_a, - rpt0->gain_a, rpt0->trsw, rpt0->agc_table_b, - rpt0->agc_table_c); - pr_debug("[4] Path_Sel_o=%d, Gnt_BT_keep_cnt=%d, HW_AntSW_occur_keep_cck=%d,\n Band=%d, Channel=%d, AGC_table_a=%d, l_RXSC=%d, AGC_table_d=%d\n", - rpt0->path_sel_o, rpt0->gnt_bt_keep_cck, - rpt0->hw_antsw_occur_keep_cck, rpt0->band, - rpt0->channel, rpt0->agc_table_a, rpt0->l_rxsc, - rpt0->agc_table_d); - pr_debug("[8] AntIdx={%d, %d, %d, %d}, Length=%d\n", - rpt0->antidx_d, rpt0->antidx_c, rpt0->antidx_b, - rpt0->antidx_a, rpt0->length); - pr_debug("[12] MF_off=%d, SQloss=%d, lockbit=%d, raterr=%d, rxrate=%d, lna_h_a=%d, CCK_BB_power_a=%d, lna_l_a=%d, vga_a=%d, sq=%d\n", - rpt0->mf_off, rpt0->sqloss, rpt0->lockbit, - rpt0->raterr, rpt0->rxrate, rpt0->lna_h_a, - rpt0->bb_power_a, rpt0->lna_l_a, rpt0->vga_a, - rpt0->signal_quality); - pr_debug("[16] Gain_b=%d, lna_h_b=%d, CCK_BB_power_b=%d, lna_l_b=%d, vga_b=%d, Pwdb_b=%d\n", - rpt0->gain_b, rpt0->lna_h_b, rpt0->bb_power_b, - rpt0->lna_l_b, rpt0->vga_b, rpt0->pwdb_b); - pr_debug("[20] Gain_c=%d, lna_h_c=%d, CCK_BB_power_c=%d, lna_l_c=%d, vga_c=%d, Pwdb_c=%d\n", - rpt0->gain_c, rpt0->lna_h_c, rpt0->bb_power_c, - rpt0->lna_l_c, rpt0->vga_c, rpt0->pwdb_c); - pr_debug("[24] Gain_d=%d, lna_h_d=%d, CCK_BB_power_d=%d, lna_l_d=%d, vga_d=%d, Pwdb_d=%d\n", - rpt0->gain_c, rpt0->lna_h_c, rpt0->bb_power_c, - rpt0->lna_l_c, rpt0->vga_c, rpt0->pwdb_c); + if (dm->support_ic_type & ODM_RTL8723F) { + #if (RTL8723F_SUPPORT) + pr_debug("[0] Pop_idx=%d, Pkt_cnt=%d, Channel_msb=%d, AGC_table_path0=%d, TRSW_mux_keep=%d, HW_AntSW_occur_keep_cck=%d, Gnt_BT_keep_cnt=%d,Rssi_msb=%d\n", + rpt5->pop_idx, rpt5->pkt_cnt, + rpt5->channel_msb, rpt5->agc_table_a, + rpt5->trsw, rpt5->hw_antsw_occur_keep_cck, + rpt5->gnt_bt_keep_cck, rpt5->rssi_msb); + pr_debug("[4] Channel=%d, Antidx_CCK_keep=%d, Cck_mp_gain_idx_keep=%d\n", + rpt5->channel, rpt5->antidx_a, + rpt5->mp_gain_idx_a); + pr_debug("[8] Rssi=%d\n",rpt5->rssi); + pr_debug("[12] Avg_cfo=%d\n",rpt5->avg_cfo); + pr_debug("[16] Coarse_cfo=%d, Coarse_cfo_msb=%d, Avg_cfo_msb=%d, Evm_hdr=%d\n", + rpt5->coarse_cfo, rpt5->coarse_cfo_msb, + rpt5->avg_cfo_msb, rpt5->evm_hdr); + pr_debug("[20] Evm_pld=%d\n",rpt5->evm_pld); + #endif + } else { + pr_debug("[0] Pkt_cnt=%d, Channel_msb=%d, Pwdb_a=%d, Gain_a=%d, TRSW=%d, AGC_table_b=%d, AGC_table_c=%d,\n", + rpt0->pkt_cnt, rpt0->channel_msb, rpt0->pwdb_a, + rpt0->gain_a, rpt0->trsw, rpt0->agc_table_b, + rpt0->agc_table_c); + pr_debug("[4] Path_Sel_o=%d, Gnt_BT_keep_cnt=%d, HW_AntSW_occur_keep_cck=%d,\n Band=%d, Channel=%d, AGC_table_a=%d, l_RXSC=%d, AGC_table_d=%d\n", + rpt0->path_sel_o, rpt0->gnt_bt_keep_cck, + rpt0->hw_antsw_occur_keep_cck, rpt0->band, + rpt0->channel, rpt0->agc_table_a, rpt0->l_rxsc, + rpt0->agc_table_d); + pr_debug("[8] AntIdx={%d, %d, %d, %d}, Length=%d\n", + rpt0->antidx_d, rpt0->antidx_c, rpt0->antidx_b, + rpt0->antidx_a, rpt0->length); + pr_debug("[12] MF_off=%d, SQloss=%d, lockbit=%d, raterr=%d, rxrate=%d, lna_h_a=%d, CCK_BB_power_a=%d, lna_l_a=%d, vga_a=%d, sq=%d\n", + rpt0->mf_off, rpt0->sqloss, rpt0->lockbit, + rpt0->raterr, rpt0->rxrate, rpt0->lna_h_a, + rpt0->bb_power_a, rpt0->lna_l_a, rpt0->vga_a, + rpt0->signal_quality); + pr_debug("[16] Gain_b=%d, lna_h_b=%d, CCK_BB_power_b=%d, lna_l_b=%d, vga_b=%d, Pwdb_b=%d\n", + rpt0->gain_b, rpt0->lna_h_b, rpt0->bb_power_b, + rpt0->lna_l_b, rpt0->vga_b, rpt0->pwdb_b); + pr_debug("[20] Gain_c=%d, lna_h_c=%d, CCK_BB_power_c=%d, lna_l_c=%d, vga_c=%d, Pwdb_c=%d\n", + rpt0->gain_c, rpt0->lna_h_c, rpt0->bb_power_c, + rpt0->lna_l_c, rpt0->vga_c, rpt0->pwdb_c); + pr_debug("[24] Gain_d=%d, lna_h_d=%d, CCK_BB_power_d=%d, lna_l_d=%d, vga_d=%d, Pwdb_d=%d\n", + rpt0->gain_c, rpt0->lna_h_c, rpt0->bb_power_c, + rpt0->lna_l_c, rpt0->vga_c, rpt0->pwdb_c); + } } else if (phy_status_page_num == 1) { pr_debug("[0] pwdb[C:A]={%d, %d, %d}, Channel_pri_msb=%d, Pkt_cnt=%d,\n", rpt1->pwdb_c, rpt1->pwdb_b, rpt1->pwdb_a, @@ -1939,7 +1971,9 @@ void phydm_get_physts_0_jgr3(struct dm_struct *dm, u8 *phy_status_inf, if (dm->support_ic_type & ODM_RTL8197G) { if (dm->rx_ant_status == BB_PATH_B) { phy_sts->pwdb_b = phy_sts->pwdb_a; + phy_sts->gain_b = phy_sts->gain_a; phy_sts->pwdb_a = 0; + phy_sts->gain_a = 0; } } #endif @@ -2021,9 +2055,10 @@ void phydm_get_physts_0_jgr3(struct dm_struct *dm, u8 *phy_status_inf, dbg_i->is_ldpc_pkt = false; dbg_i->is_stbc_pkt = false; + /*cck channel has hw bug, [WLANBB-1429]*/ + phy_info->channel = 0; phy_info->rx_power = rx_pwr_db_max; phy_info->recv_signal_power = rx_pwr_db_max; - phy_info->channel = phy_sts->channel; phy_info->is_beamformed = false; phy_info->is_mu_packet = false; phy_info->rxsc = phy_sts->l_rxsc; @@ -2139,7 +2174,78 @@ void phydm_get_physts_5_others_jgr3(struct dm_struct *dm, u8 *phy_status_inf, struct phy_sts_rpt_jgr3_type5 *phy_sts = NULL; } +#if (RTL8723F_SUPPORT) +void phydm_get_physts_6_jgr3(struct dm_struct *dm, u8 *phy_status_inf, + struct phydm_perpkt_info_struct *pktinfo, + struct phydm_phyinfo_struct *phy_info) +{ + /* type 0 is used for cck packet */ + struct phy_sts_rpt_jgr3_type6 *phy_sts = NULL; + struct odm_phy_dbg_info *dbg_i = &dm->phy_dbg_info; + u8 sq = 0, i, rx_cnt = 0; + s8 rx_power[4], pwdb; + s8 rx_pwr_db_max = -120; + u8 evm = 0; + phy_sts = (struct phy_sts_rpt_jgr3_type6 *)phy_status_inf; + /* judy_add_8723F_0512 */ + /* rssi S(11,3) */ + rx_power[0] = (s8)((phy_sts->rssi_msb << 5) + (phy_sts->rssi >> 3)); + /* @Update per-path information */ + for (i = RF_PATH_A; i < dm->num_rf_path; i++) { + if ((dm->rx_ant_status & BIT(i)) == 0) + continue; + rx_cnt++; /* @check the number of the ant */ + + if (rx_cnt > dm->num_rf_path) + break; + + if (pktinfo->is_to_self) + dm->ofdm_agc_idx[i] = rx_power[i]+110; + + /* @Setting the RX power: agc_idx dBm*/ + pwdb = rx_power[i]; + + phy_info->rx_pwr[i] = pwdb; + phy_info->rx_mimo_signal_strength[i] = phydm_pw_2_percent(pwdb); + + /* search maximum pwdb */ + if (pwdb > rx_pwr_db_max) + rx_pwr_db_max = pwdb; + } + + /* @Calculate EVM U(8,2)*/ + evm = phy_sts->evm_pld >> 2; + if (pktinfo->data_rate > ODM_RATE2M) + phy_info->rx_cck_evm = (u8)(evm - 10);/* @5_5M/11M*/ + else + phy_info->rx_cck_evm = (u8)(evm - 12);/* @1M/2M*/ + + sq = (phy_info->rx_cck_evm >= 34) ? 100 : phy_info->rx_cck_evm * 3; + phy_info->signal_quality = sq; + /*@CCK no STBC and LDPC*/ + dbg_i->is_ldpc_pkt = false; + dbg_i->is_stbc_pkt = false; + + /*cck channel has hw bug, [WLANBB-1429]*/ + phy_info->channel = 0; + phy_info->rx_power = rx_pwr_db_max; + phy_info->recv_signal_power = rx_pwr_db_max; + phy_info->is_beamformed = false; + phy_info->is_mu_packet = false; + phy_info->rx_pwdb_all = phydm_pw_2_percent(rx_pwr_db_max); + phy_info->band_width = CHANNEL_WIDTH_20; + + //phydm_parsing_cfo(dm, pktinfo, phy_sts->avg_cfo, pktinfo->rate_ss); + + #ifdef CONFIG_PHYDM_ANTENNA_DIVERSITY + dm->dm_fat_table.antsel_rx_keep_0 = phy_sts->antidx_a; + dm->dm_fat_table.antsel_rx_keep_1 = 0; + dm->dm_fat_table.antsel_rx_keep_2 = 0; + dm->dm_fat_table.antsel_rx_keep_3 = 0; + #endif +} +#endif void phydm_get_physts_ofdm_cmn_jgr3(struct dm_struct *dm, u8 *phy_status_inf, struct phydm_perpkt_info_struct *pktinfo, struct phydm_phyinfo_struct *phy_info) @@ -2288,7 +2394,10 @@ void phydm_rx_physts_jgr3(void *dm_void, u8 *phy_sts, { struct dm_struct *dm = (struct dm_struct *)dm_void; u8 phy_status_type = (*phy_sts & 0xf); - + if (dm->support_ic_type & ODM_RTL8723F) { + if (pktinfo->data_rate <= ODM_RATE11M) + phy_status_type = 6; + } /*@[Step 2]*/ /*phydm_reset_phy_info_jgr3(dm, phy_info);*/ /* @Memory reset */ @@ -2309,10 +2418,16 @@ void phydm_rx_physts_jgr3(void *dm_void, u8 *phy_sts, case 4: phydm_get_physts_ofdm_cmn_jgr3(dm, phy_sts, pktinfo, phy_info); phydm_get_physts_4_others_jgr3(dm, phy_sts, pktinfo, phy_info); + break; case 5: phydm_get_physts_ofdm_cmn_jgr3(dm, phy_sts, pktinfo, phy_info); phydm_get_physts_5_others_jgr3(dm, phy_sts, pktinfo, phy_info); break; +#if (RTL8723F_SUPPORT) + case 6: + phydm_get_physts_6_jgr3(dm, phy_sts, pktinfo, phy_info); + break; +#endif default: break; } @@ -3109,8 +3224,7 @@ void phydm_physts_dbg(void *dm_void, char input[][16], u32 *_used, u8 i = 0; for (i = 0; i < 3; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var[i]); } if ((strcmp(input[1], help) == 0)) { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_phystatus.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_phystatus.h index d4a27fc82c83..52c3cdfe582d 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_phystatus.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_phystatus.h @@ -27,8 +27,8 @@ #ifndef __PHYDM_PHYSTATUS_H__ #define __PHYDM_PHYSTATUS_H__ -/* 2019.06.24 remove the condition of is_packet_beacon for basic dbg msg*/ -#define PHYSTS_VERSION "1.0" +/* 2020.07.03 fix cck report bug due to 8723F coding error*/ +#define PHYSTS_VERSION "1.2" /*@--------------------------Define ------------------------------------------*/ #define CCK_RSSI_INIT_COUNT 5 @@ -649,7 +649,79 @@ __PACK struct phy_sts_rpt_jgr3_type0 { u8 gain_d : 6; #endif }; +#if(RTL8723F_SUPPORT) +__PACK struct phy_sts_rpt_jgr3_type6 { + /* judy_add_8723F_0512 */ +/* @DW0 : Offset 0 */ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 pop_idx : 4; + u8 pkt_cnt : 2; + u8 channel_msb : 2; +#else + u8 channel_msb : 2; + u8 pkt_cnt : 2; + u8 pop_idx : 4; +#endif +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 agc_table_a : 4; + u8 rsvd_0 : 4; +#else + u8 rsvd_0 : 4; + u8 agc_table_a : 4; +#endif + u8 rsvd_1 : 8; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 trsw : 1; + u8 hw_antsw_occur_keep_cck : 1; + u8 gnt_bt_keep_cck : 1; + u8 rssi_msb : 3; + u8 rsvd_2 : 2; +#else + u8 rsvd_2 : 2; + u8 rssi_msb : 3; + u8 gnt_bt_keep_cck : 1; + u8 hw_antsw_occur_keep_cck : 1; + u8 trsw : 1; +#endif + +/* @DW1 : Offset 4 */ + u8 channel; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 antidx_a : 4; + u8 rsvd_2_1 : 4; +#else + u8 rsvd_2_1 : 4; + u8 antidx_a : 4; +#endif + u8 rsvd_2_2; + u8 mp_gain_idx_a; + +/* @DW2 : Offset 8 */ + u16 rsvd_3_1; + u8 rsvd_4_1; + u8 rssi; + +/* @DW3 : Offset 12 */ + u16 rsvd_4_2; + u8 rsvd_5_1; + u8 avg_cfo; +/* @DW4 : Offset 16 */ + u8 coarse_cfo; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 coarse_cfo_msb : 4; + u8 avg_cfo_msb : 4; +#else + u8 avg_cfo_msb : 4; + u8 coarse_cfo_msb : 4; +#endif + u8 evm_hdr; + u8 evm_pld; +/* @DW5 : Offset 20 */ + u32 rsvd_6_1; + u32 rsvd_7_1; +}; +#endif __PACK struct phy_sts_rpt_jgr3_type1 { /* @DW0 : Offset 0 */ #if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pmac_tx_setting.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pmac_tx_setting.c index 3cba20e1cdae..4583eb068155 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pmac_tx_setting.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pmac_tx_setting.c @@ -33,7 +33,6 @@ #ifdef PHYDM_PMAC_TX_SETTING_SUPPORT #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT - void phydm_start_cck_cont_tx_jgr3(void *dm_void, struct phydm_pmac_info *tx_info) { @@ -43,14 +42,17 @@ void phydm_start_cck_cont_tx_jgr3(void *dm_void, /* if CCK block on? */ if (!odm_get_bb_reg(dm, R_0x1c3c, BIT(1))) - odm_set_bb_reg(dm, R_0x1c3c, BIT(1), 1); - + odm_set_bb_reg(dm, R_0x1c3c, BIT(1), 0x1); + if (dm->support_ic_type & ODM_RTL8723F) { + odm_set_bb_reg(dm, R_0x2a08, BIT(21)|BIT(20), rate); + odm_set_bb_reg(dm, R_0x2a04, BIT(5), 0x0); /* turn on scrambler*/ + } else { /* Turn Off All Test mode */ odm_set_bb_reg(dm, R_0x1ca4, 0x7, 0x0); odm_set_bb_reg(dm, R_0x1a00, 0x3000, rate); odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x2); /* transmit mode */ - odm_set_bb_reg(dm, R_0x1a00, BIT(3), 0x1); /* turn on scramble*/ + odm_set_bb_reg(dm, R_0x1a00, BIT(3), 0x1); /* turn on scrambler*/ /* Fix rate selection issue */ odm_set_bb_reg(dm, R_0x1a70, BIT(14), 0x1); @@ -58,7 +60,7 @@ void phydm_start_cck_cont_tx_jgr3(void *dm_void, odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x3); /* set loopback mode */ odm_set_bb_reg(dm, R_0x1c3c, BIT(4), 0x1); - + } pmac_tx->cck_cont_tx = true; pmac_tx->ofdm_cont_tx = false; } @@ -71,13 +73,18 @@ void phydm_stop_cck_cont_tx_jgr3(void *dm_void) pmac_tx->cck_cont_tx = false; pmac_tx->ofdm_cont_tx = false; - odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x0); /* normal mode */ - odm_set_bb_reg(dm, R_0x1a00, BIT(3), 0x1); /* turn on scramble*/ + if (dm->support_ic_type & ODM_RTL8723F) { + /* @Disable pmac tx_en*/ + odm_set_bb_reg(dm, R_0x2a04, BIT(5), 0x0); /* turn on scrambler*/ + } else { + odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x0); /* normal mode */ + odm_set_bb_reg(dm, R_0x1a00, BIT(3), 0x1); /* turn on scrambler*/ - /* back to default */ - odm_set_bb_reg(dm, R_0x1a70, BIT(14), 0x0); - odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x0); - odm_set_bb_reg(dm, R_0x1c3c, BIT(4), 0x0); + /* back to default */ + odm_set_bb_reg(dm, R_0x1a70, BIT(14), 0x0); + odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x0); + odm_set_bb_reg(dm, R_0x1c3c, BIT(4), 0x0); + } /* BB Reset */ odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x0); odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x1); @@ -90,14 +97,15 @@ void phydm_start_ofdm_cont_tx_jgr3(void *dm_void) /* 1. if OFDM block on */ if (!odm_get_bb_reg(dm, R_0x1c3c, BIT(0))) - odm_set_bb_reg(dm, R_0x1c3c, BIT(0), 1); + odm_set_bb_reg(dm, R_0x1c3c, BIT(0), 0x1); + if (!(dm->support_ic_type & ODM_RTL8723F)) { - /* 2. set CCK test mode off, set to CCK normal mode */ - odm_set_bb_reg(dm, R_0x1a00, 0x3, 0); - - /* 3. turn on scramble setting */ - odm_set_bb_reg(dm, R_0x1a00, BIT(3), 1); + /* 2. set CCK test mode off, set to CCK normal mode */ + odm_set_bb_reg(dm, R_0x1a00, 0x3, 0x0); + /* 3. turn on scramble setting */ + odm_set_bb_reg(dm, R_0x1a00, BIT(3), 0x1); + } /* 4. Turn On Continue Tx and turn off the other test modes. */ odm_set_bb_reg(dm, R_0x1ca4, 0x7, 0x1); @@ -124,145 +132,45 @@ void phydm_stop_ofdm_cont_tx_jgr3(void *dm_void) odm_set_bb_reg(dm, R_0x1d0c, BIT(16), 0x1); } -void phydm_set_single_tone_jgr3(void *dm_void, boolean is_single_tone, - boolean en_pmac_tx, u8 path) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - struct phydm_pmac_tx *pmac_tx = &dm->dm_pmac_tx_table; - u8 start = RF_PATH_A, end = RF_PATH_A; - u8 i = 0; - - switch (path) { - case RF_PATH_A: - case RF_PATH_B: - case RF_PATH_C: - case RF_PATH_D: - start = path; - end = path; - break; - case RF_PATH_AB: - start = RF_PATH_A; - end = RF_PATH_B; - break; -#if (RTL8814B_SUPPORT || RTL8198F_SUPPORT) - case RF_PATH_AC: - start = RF_PATH_A; - end = RF_PATH_C; - break; - case RF_PATH_AD: - start = RF_PATH_A; - end = RF_PATH_D; - break; - case RF_PATH_BC: - start = RF_PATH_B; - end = RF_PATH_C; - break; - case RF_PATH_BD: - start = RF_PATH_B; - end = RF_PATH_D; - break; - case RF_PATH_CD: - start = RF_PATH_C; - end = RF_PATH_D; - break; - case RF_PATH_ABC: - start = RF_PATH_A; - end = RF_PATH_C; - break; - case RF_PATH_ABD: - start = RF_PATH_A; - end = RF_PATH_D; - break; - case RF_PATH_ACD: - start = RF_PATH_A; - end = RF_PATH_D; - break; - case RF_PATH_BCD: - start = RF_PATH_B; - end = RF_PATH_D; - break; - case RF_PATH_ABCD: - start = RF_PATH_A; - end = RF_PATH_D; - break; -#endif - } - - if (is_single_tone) { - pmac_tx->tx_scailing = odm_get_bb_reg(dm, R_0x81c, MASKDWORD); - - if (!en_pmac_tx) { - phydm_start_ofdm_cont_tx_jgr3(dm); - /*SendPSPoll(pAdapter);*/ - } - - odm_set_bb_reg(dm, R_0x1c68, BIT(24), 0x1); /* Disable CCA */ - - for (i = start; i <= end; i++) { - /* Tx mode: RF0x00[19:16]=4'b0010 */ - /* odm_set_rf_reg(dm, i, RF_0x0, 0xF0000, 0x2); */ - /* Lowest RF gain index: RF_0x0[4:0] = 0*/ - odm_set_rf_reg(dm, i, RF_0x0, 0x1F, 0x0); - /* RF LO enabled */ - odm_set_rf_reg(dm, i, RF_0x58, BIT(1), 0x1); - } - #if (RTL8814B_SUPPORT) - if (dm->support_ic_type & ODM_RTL8814B) { - /* Tx mode: RF0x00[19:16]=4'b0010 */ - /* config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x0, - * 0xF0000, 0x2); - */ - /* Lowest RF gain index: RF_0x0[4:0] = 0*/ - config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x0, - 0x1F, 0x0); - /* RF LO enabled */ - config_phydm_write_rf_syn_8814b(dm, RF_SYN0, RF_0x58, - BIT(1), 0x1); - } - #endif - odm_set_bb_reg(dm, R_0x81c, 0x001FC000, 0); - } else { - for (i = start; i <= end; i++) { - /* RF LO disabled */ - odm_set_rf_reg(dm, i, RF_0x58, BIT(1), 0x0); - } - odm_set_bb_reg(dm, R_0x1c68, BIT(24), 0x0); /* Enable CCA */ - - if (!en_pmac_tx) - phydm_stop_ofdm_cont_tx_jgr3(dm); - - odm_set_bb_reg(dm, R_0x81c, MASKDWORD, pmac_tx->tx_scailing); - } -} - void phydm_stop_pmac_tx_jgr3(void *dm_void, struct phydm_pmac_info *tx_info) { struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_pmac_tx *pmac_tx = &dm->dm_pmac_tx_table; u32 tmp = 0; - if (tx_info->mode == CONT_TX) { - odm_set_bb_reg(dm, R_0x1e70, 0xf, 0x2); /* TX Stop */ + odm_set_bb_reg(dm, R_0x1e70, 0xf, 0x2); /* TX Stop */ + if (dm->support_ic_type & ODM_RTL8723F) { + if (tx_info->mode == CONT_TX) { + if (pmac_tx->is_cck_rate) { + /* TX Stop */ + odm_set_bb_reg(dm, R_0x2a00, BIT(0), 0x1); + /* Clear BB cont tx */ + odm_set_bb_reg(dm, R_0x2a00, BIT(28), 0x0); + /* Clear PMAC cont tx */ + odm_set_bb_reg(dm, R_0x2a08, BIT(17), 0x0); + /* Clear TX Stop */ + odm_set_bb_reg(dm, R_0x2a00, BIT(0), 0x0); + phydm_stop_cck_cont_tx_jgr3(dm); + } else + phydm_stop_ofdm_cont_tx_jgr3(dm); + } else { + if (pmac_tx->is_cck_rate) { + /* packet_count = 0x1 */ + odm_set_bb_reg(dm, R_0x2a04, 0x03ff0000, 0x1); + /* @Disable pmac tx_en*/ + odm_set_bb_reg(dm, R_0x2a08, BIT(31), 0x0); + /* @Enable pmac tx_en*/ + odm_set_bb_reg(dm, R_0x2a08, BIT(31), 0x1); + phydm_stop_cck_cont_tx_jgr3(dm); + } + } + }else { + if (tx_info->mode == CONT_TX) { if (pmac_tx->is_cck_rate) phydm_stop_cck_cont_tx_jgr3(dm); else phydm_stop_ofdm_cont_tx_jgr3(dm); - } else { - if (pmac_tx->is_cck_rate) { - tmp = odm_get_bb_reg(dm, R_0x2de4, MASKLWORD); - odm_set_bb_reg(dm, R_0x1e64, MASKLWORD, tmp + 50); } - odm_set_bb_reg(dm, R_0x1e70, 0xf, 0x2); /* TX Stop */ - } - - if (tx_info->mode == OFDM_SINGLE_TONE_TX) { - /* Stop HW TX -> Stop Continuous TX -> Stop RF Setting */ - if (pmac_tx->is_cck_rate) - phydm_stop_cck_cont_tx_jgr3(dm); - else - phydm_stop_ofdm_cont_tx_jgr3(dm); - - phydm_set_single_tone_jgr3(dm, false, true, pmac_tx->path); } } @@ -273,41 +181,39 @@ void phydm_set_mac_phy_txinfo_jgr3(void *dm_void, struct phydm_pmac_tx *pmac_tx = &dm->dm_pmac_tx_table; u32 tmp = 0; - odm_set_bb_reg(dm, R_0xa58, 0x003F8000, tx_info->tx_rate); + odm_set_bb_reg(dm, R_0xa58, 0x003f8000, tx_info->tx_rate); - /* 0x900[1] ndp_sound */ + /*0x900[1] ndp_sound */ odm_set_bb_reg(dm, R_0x900, BIT(1), tx_info->ndp_sound); #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) tx_info->m_stbc = tx_info->m_stbc - 1; #endif - - /* 0x900[27:24] txsc [29:28] bw [31:30] m_stbc */ + /*0x900[27:24] txsc [29:28] bw [31:30] m_stbc */ tmp = (tx_info->tx_sc) | ((tx_info->bw) << 4) | ((tx_info->m_stbc) << 6); + odm_set_bb_reg(dm, R_0x900, 0xff000000, tmp); - if (tx_info->tx_sc == 1) /* upper*/ + if (tx_info->tx_sc == 1) /*upper*/ odm_set_bb_reg(dm, R_0x1ae0, 0x7000, 0x5); - else if (tx_info->tx_sc == 2) /* lower*/ + else if (tx_info->tx_sc == 2) /*lower*/ odm_set_bb_reg(dm, R_0x1ae0, 0x7000, 0x6); else /* duplicate*/ odm_set_bb_reg(dm, R_0x1ae0, 0x7000, 0x0); - odm_set_bb_reg(dm, R_0x900, 0xFF000000, tmp); - - if (pmac_tx->is_ofdm_rate) { - odm_set_bb_reg(dm, R_0x900, BIT(0), 0); - odm_set_bb_reg(dm, R_0x900, BIT(2), 0); - } else if (pmac_tx->is_ht_rate) { - odm_set_bb_reg(dm, R_0x900, BIT(0), 1); - odm_set_bb_reg(dm, R_0x900, BIT(2), 0); + if (pmac_tx->is_ht_rate) { + odm_set_bb_reg(dm, R_0x900, BIT(0), 0x1); + odm_set_bb_reg(dm, R_0x900, BIT(2), 0x0); } else if (pmac_tx->is_vht_rate) { - odm_set_bb_reg(dm, R_0x900, BIT(0), 0); - odm_set_bb_reg(dm, R_0x900, BIT(2), 1); + odm_set_bb_reg(dm, R_0x900, BIT(0), 0x0); + odm_set_bb_reg(dm, R_0x900, BIT(2), 0x1); + } else { + odm_set_bb_reg(dm, R_0x900, BIT(0), 0x0); + odm_set_bb_reg(dm, R_0x900, BIT(2), 0x0); } - tmp = tx_info->packet_period; /* for TX interval */ - odm_set_bb_reg(dm, R_0x9b8, 0xffff0000, tmp); + /* for TX interval */ + odm_set_bb_reg(dm, R_0x9b8, MASKHWORD, tx_info->packet_period); } void phydm_set_sig_jgr3(void *dm_void, struct phydm_pmac_info *tx_info) @@ -319,24 +225,12 @@ void phydm_set_sig_jgr3(void *dm_void, struct phydm_pmac_info *tx_info) if (pmac_tx->is_cck_rate) return; - /* L-SIG */ odm_set_bb_reg(dm, R_0x1eb4, 0xfffff, tx_info->packet_count); + /* L-SIG */ tmp = BYTE_2_DWORD(0, tx_info->lsig[2], tx_info->lsig[1], tx_info->lsig[0]); odm_set_bb_reg(dm, R_0x908, 0xffffff, tmp); -#if 0 - /* @0x924[7:0] = Data init octet */ - tmp = tx_info->packet_pattern; - odm_set_bb_reg(dm, R_0x924, 0xff, tmp); - - if (tx_info->packet_pattern == RANDOM_BY_PN32) - tmp = 0x3; - else - tmp = 0x0; - - odm_set_bb_reg(dm, R_0x914, 0x60000000, tmp); -#endif if (pmac_tx->is_ht_rate) { /* HT SIG */ tmp = BYTE_2_DWORD(0, tx_info->ht_sig[2], tx_info->ht_sig[1], @@ -358,10 +252,8 @@ void phydm_set_sig_jgr3(void *dm_void, struct phydm_pmac_info *tx_info) tmp = BYTE_2_DWORD(tx_info->vht_sig_b[3], tx_info->vht_sig_b[2], tx_info->vht_sig_b[1], tx_info->vht_sig_b[0]); - odm_set_bb_reg(dm, R_0x914, 0x1FFFFFFF, tmp); - - tmp = tx_info->vht_sig_b_crc; - odm_set_bb_reg(dm, R_0x938, 0xff00, tmp); + odm_set_bb_reg(dm, R_0x914, 0x1fffffff, tmp); + odm_set_bb_reg(dm, R_0x938, 0xff00, tx_info->vht_sig_b_crc); tmp = BYTE_2_DWORD(tx_info->vht_delimiter[3], tx_info->vht_delimiter[2], @@ -377,22 +269,39 @@ void phydm_set_cck_preamble_hdr_jgr3(void *dm_void, struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_pmac_tx *pmac_tx = &dm->dm_pmac_tx_table; u32 tmp = 0; + u8 rate = tx_info->tx_rate; /* HW rate */ if (!pmac_tx->is_cck_rate) return; - tmp = tx_info->packet_count | (tx_info->sfd << 16); - odm_set_bb_reg(dm, R_0x1e64, MASKDWORD, tmp); - tmp = tx_info->signal_field | (tx_info->service_field << 8) | - (tx_info->length << 16); - odm_set_bb_reg(dm, R_0x1e68, MASKDWORD, tmp); - tmp = BYTE_2_DWORD(0, 0, tx_info->crc16[1], tx_info->crc16[0]); - odm_set_bb_reg(dm, R_0x1e6c, 0xffff, tmp); + if (dm->support_ic_type & ODM_RTL8723F) { + #if (RTL8723F_SUPPORT) + odm_set_bb_reg(dm, R_0x2a04, 0x03ff0000, tx_info->packet_count); + odm_set_bb_reg(dm, R_0x2a08, BIT(22), tx_info->service_field_bit2); + odm_set_bb_reg(dm, R_0x2a08, BIT(21) | BIT(20), rate); + odm_set_bb_reg(dm, R_0x2a08, 0x1ffff, tx_info->packet_length); + /* turn on scrambler */ + odm_set_bb_reg(dm, R_0x2a04, BIT(5), 0x0); - if (tx_info->is_short_preamble) - odm_set_bb_reg(dm, R_0x1e6c, BIT(16), 0); - else - odm_set_bb_reg(dm, R_0x1e6c, BIT(16), 1); + if (tx_info->is_short_preamble) + odm_set_bb_reg(dm, R_0x2a08, BIT(19), 0x1); + else + odm_set_bb_reg(dm, R_0x2a08, BIT(19), 0x0); + #endif + } else { + tmp = tx_info->packet_count | (tx_info->sfd << 16); + odm_set_bb_reg(dm, R_0x1e64, MASKDWORD, tmp); + tmp = tx_info->signal_field | (tx_info->service_field << 8) | + (tx_info->length << 16); + odm_set_bb_reg(dm, R_0x1e68, MASKDWORD, tmp); + tmp = BYTE_2_DWORD(0, 0, tx_info->crc16[1], tx_info->crc16[0]); + odm_set_bb_reg(dm, R_0x1e6c, MASKLWORD, tmp); + + if (tx_info->is_short_preamble) + odm_set_bb_reg(dm, R_0x1e6c, BIT(16), 0x0); + else + odm_set_bb_reg(dm, R_0x1e6c, BIT(16), 0x1); + } } void phydm_set_mode_jgr3(void *dm_void, struct phydm_pmac_info *tx_info, @@ -404,14 +313,6 @@ void phydm_set_mode_jgr3(void *dm_void, struct phydm_pmac_info *tx_info, if (mode == CONT_TX) { tx_info->packet_count = 1; - if (pmac_tx->is_cck_rate) - phydm_start_cck_cont_tx_jgr3(dm, tx_info); - else - phydm_start_ofdm_cont_tx_jgr3(dm); - } else if (mode == OFDM_SINGLE_TONE_TX) { - /* Continuous TX -> HW TX -> RF Setting */ - tx_info->packet_count = 1; - if (pmac_tx->is_cck_rate) phydm_start_cck_cont_tx_jgr3(dm, tx_info); else @@ -424,24 +325,37 @@ void phydm_set_pmac_txon_jgr3(void *dm_void, struct phydm_pmac_info *tx_info) struct dm_struct *dm = (struct dm_struct *)dm_void; struct phydm_pmac_tx *pmac_tx = &dm->dm_pmac_tx_table; - odm_set_bb_reg(dm, R_0x1d08, BIT(0), 1); /* Turn on PMAC */ + odm_set_bb_reg(dm, R_0x1d08, BIT(0), 0x1); /*Turn on PMAC */ - /* mac scramble seed setting, only in 8198F */ - #if (RTL8198F_SUPPORT) - if (dm->support_ic_type & ODM_RTL8198F) - if (!odm_get_bb_reg(dm, R_0x1d10, BIT(16))) - odm_set_bb_reg(dm, R_0x1d10, BIT(16), 1); - #endif - - if (pmac_tx->is_cck_rate) { - odm_set_bb_reg(dm, R_0x1e70, 0xf, 8); /* TX CCK ON */ - odm_set_bb_reg(dm, R_0x1a84, BIT(31), 0); + if (dm->support_ic_type & ODM_RTL8723F) { + if (pmac_tx->is_cck_rate) { + if (tx_info->mode == CONT_TX) { + /* BB and PMAC cont tx */ + odm_set_bb_reg(dm, R_0x2a08, BIT(17), 0x1); + odm_set_bb_reg(dm, R_0x2a00, BIT(28), 0x1); + } + /* TX CCK ON */ + odm_set_bb_reg(dm, R_0x2a08, BIT(31), 0x0); + odm_set_bb_reg(dm, R_0x2a08, BIT(31), 0x1); + } else { + odm_set_bb_reg(dm, R_0x1e70, 0xf, 0x0); /*TX Ofdm OFF */ + odm_set_bb_reg(dm, R_0x1e70, 0xf, 0x4); /*TX Ofdm ON */ + } } else { - odm_set_bb_reg(dm, R_0x1e70, 0xf, 4); /* TX Ofdm ON */ + /*mac scramble seed setting, only in 8198F */ + #if (RTL8198F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8198F) + if (!odm_get_bb_reg(dm, R_0x1d10, BIT(16))) + odm_set_bb_reg(dm, R_0x1d10, BIT(16), 0x1); + #endif + + if (pmac_tx->is_cck_rate){ + odm_set_bb_reg(dm, R_0x1e70, 0xf, 0x8); /*TX CCK ON */ + odm_set_bb_reg(dm, R_0x1a84, BIT(31), 0x0); + } else { + odm_set_bb_reg(dm, R_0x1e70, 0xf, 0x4); /*TX Ofdm ON */ + } } - - if (tx_info->mode == OFDM_SINGLE_TONE_TX) - phydm_set_single_tone_jgr3(dm, true, true, pmac_tx->path); } void phydm_set_pmac_tx_jgr3(void *dm_void, struct phydm_pmac_info *tx_info, @@ -478,18 +392,20 @@ void phydm_set_tmac_tx_jgr3(void *dm_void) /* Turn on TMAC */ if (odm_get_bb_reg(dm, R_0x1d08, BIT(0))) - odm_set_bb_reg(dm, R_0x1d08, BIT(0), 0); + odm_set_bb_reg(dm, R_0x1d08, BIT(0), 0x0); /* mac scramble seed setting, only in 8198F */ #if (RTL8198F_SUPPORT) if (dm->support_ic_type & ODM_RTL8198F) if (odm_get_bb_reg(dm, R_0x1d10, BIT(16))) - odm_set_bb_reg(dm, R_0x1d10, BIT(16), 0); + odm_set_bb_reg(dm, R_0x1d10, BIT(16), 0x0); #endif /* Turn on TMAC CCK */ - if ((odm_get_bb_reg(dm, R_0x1a84, BIT(31))) == 0) - odm_set_bb_reg(dm, R_0x1a84, BIT(31), 1); + if (!(dm->support_ic_type & ODM_RTL8723F)) { + if (!odm_get_bb_reg(dm, R_0x1a84, BIT(31))) + odm_set_bb_reg(dm, R_0x1a84, BIT(31), 0x1); + } } #endif @@ -497,42 +413,40 @@ void phydm_start_cck_cont_tx(void *dm_void, struct phydm_pmac_info *tx_info) { struct dm_struct *dm = (struct dm_struct *)dm_void; + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT if (dm->support_ic_type & ODM_IC_JGR3_SERIES) phydm_start_cck_cont_tx_jgr3(dm, tx_info); + #endif } void phydm_stop_cck_cont_tx(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT if (dm->support_ic_type & ODM_IC_JGR3_SERIES) phydm_stop_cck_cont_tx_jgr3(dm); + #endif } void phydm_start_ofdm_cont_tx(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT if (dm->support_ic_type & ODM_IC_JGR3_SERIES) phydm_start_ofdm_cont_tx_jgr3(dm); + #endif } void phydm_stop_ofdm_cont_tx(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT if (dm->support_ic_type & ODM_IC_JGR3_SERIES) phydm_stop_ofdm_cont_tx_jgr3(dm); -} - -void phydm_set_single_tone(void *dm_void, boolean is_single_tone, - boolean en_pmac_tx, u8 path) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) - phydm_set_single_tone_jgr3(dm, is_single_tone, - en_pmac_tx, path); + #endif } void phydm_set_pmac_tx(void *dm_void, struct phydm_pmac_info *tx_info, @@ -540,16 +454,132 @@ void phydm_set_pmac_tx(void *dm_void, struct phydm_pmac_info *tx_info, { struct dm_struct *dm = (struct dm_struct *)dm_void; + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT if (dm->support_ic_type & ODM_IC_JGR3_SERIES) phydm_set_pmac_tx_jgr3(dm, tx_info, mpt_rf_path); + #endif } void phydm_set_tmac_tx(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; + #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT if (dm->support_ic_type & ODM_IC_JGR3_SERIES) phydm_set_tmac_tx_jgr3(dm); + #endif } -#endif +void phydm_pmac_tx_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_pmac_info tx_info; + char help[] = "-h"; + char dbg_buf[PHYDM_SNPRINT_SIZE] = {0}; + u32 var[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 i = 0; + u32 tx_cnt = 0x0; + u8 poll_cnt = 0x0; + + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var[0]); + + if (!(dm->support_ic_type & ODM_IC_JGR3_SERIES)) + return; + + if ((strcmp(input[1], help) == 0)) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "[pmac_tx] basic : {1} {rate_idx}(only 1M & 6M) {count}\n"); + } else { + for (i = 1; i < 7; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var[i]); + } + } + + tx_info.en_pmac_tx = true; + tx_info.mode = PKTS_TX; + tx_info.ndp_sound = false; + tx_info.bw = CHANNEL_WIDTH_20; + tx_info.tx_sc = 0x0; /*duplicate*/ + tx_info.m_stbc = 0x0; /*disable*/ + tx_info.packet_period = 2000; /*d'500 us*/ + tx_info.tx_rate = (u8)var[1]; + tx_info.packet_count = (u32)var[2]; + + if (tx_info.tx_rate == ODM_RATE1M) { + tx_info.signal_field = 0xa; /*rate = 1M*/ + tx_info.service_field = 0x0; + if (dm->support_ic_type & ODM_RTL8723F) { + tx_info.service_field_bit2= 0x1; + tx_info.packet_length = 1000; /*1000 bytes*/ + } + tx_info.length = 8000; /*d'8000 us=1000 bytes*/ + tx_info.crc16[0] = 0x60; + tx_info.crc16[1] = 0x8e; + /*long preamble*/ + tx_info.is_short_preamble = false; + tx_info.sfd = 0xf3a0; + } else if (tx_info.tx_rate == ODM_RATE6M) { + /*l-sig[3:0] = rate = 6M = 0xb*/ + /*l-sig[16:5] = length = 1000 bytes*/ + /*l-sig[17] = parity = 1*/ + tx_info.lsig[0] = 0xb; + tx_info.lsig[1] = 0x7d; + tx_info.lsig[2] = 0x2; + } + phydm_print_rate_2_buff(dm, tx_info.tx_rate, dbg_buf, + PHYDM_SNPRINT_SIZE); + PDM_SNPF(out_len, used, output + used, out_len - used, + "rate=%s, count=%d, pkt_interval=500(us), length=1000(bytes)\n", + dbg_buf, tx_info.packet_count); + + if (phydm_stop_ic_trx(dm, PHYDM_SET) == PHYDM_SET_FAIL) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "check trx idle failed, please try again.\n"); + return; + } + + phydm_reset_bb_hw_cnt(dm); + phydm_set_pmac_tx_jgr3(dm, &tx_info, RF_PATH_A); + + PDM_SNPF(out_len, used, output + used, out_len - used, + "pmac_tx enabled, please wait for tx_cnt = %d\n", + tx_info.packet_count); + while (1) { + if (phydm_is_cck_rate(dm, tx_info.tx_rate)) + tx_cnt = odm_get_bb_reg(dm, R_0x2de4, + MASKLWORD); + else + tx_cnt = odm_get_bb_reg(dm, R_0x2de0, + MASKLWORD); + + if (tx_cnt >= tx_info.packet_count || poll_cnt >= 10) + break; + + ODM_delay_ms(100); + poll_cnt++; + } + + if (tx_cnt < tx_info.packet_count) + PDM_SNPF(out_len, used, output + used, out_len - used, + "polling time out(1s), tx_cnt = %d\n", tx_cnt); + else + PDM_SNPF(out_len, used, output + used, out_len - used, + "pmac_tx finished, poll_cnt = %d\n", poll_cnt); + + tx_info.en_pmac_tx = false; + phydm_set_pmac_tx(dm, &tx_info, RF_PATH_A); + phydm_set_tmac_tx(dm); + PDM_SNPF(out_len, used, output + used, out_len - used, + "Stop pmac_tx and turn on true mac mode.\n"); + + phydm_stop_ic_trx(dm, PHYDM_REVERT); + } + *_used = used; + *_out_len = out_len; +} +#endif \ No newline at end of file diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pmac_tx_setting.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pmac_tx_setting.h index 6c884483c60f..392d3a45b8da 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pmac_tx_setting.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pmac_tx_setting.h @@ -27,14 +27,14 @@ #ifndef __PHYDM_PMAC_TX_SETTING_H__ #define __PHYDM_PMAC_TX_SETTING_H__ -/* 2019.06.10 Modify STBC setting for different OS*/ -#define PMAC_TX_SETTING_VERSION "1.6" +/*2020.03.16 Fix TxInfo content in B mode*/ +#define PMAC_TX_SETTING_VERSION "2.1" /* 1 ============================================================ * 1 Definition * 1 ============================================================ */ -#define RANDOM_BY_PN32 0x12 + /* 1 ============================================================ * 1 structure * 1 ============================================================ @@ -42,24 +42,20 @@ struct phydm_pmac_info { u8 en_pmac_tx:1; /*0: disable pmac 1: enable pmac */ u8 mode:3; /*0: Packet TX 3:Continuous TX */ - /* u8 Ntx:4; */ - u8 tx_rate; /* @should be HW rate*/ - /* u8 TX_RATE_HEX; */ + u8 tx_rate; /*should be HW rate*/ u8 tx_sc; - /* u8 bSGI:1; */ u8 is_short_preamble:1; - /* u8 bSTBC:1; */ - /* u8 bLDPC:1; */ u8 ndp_sound:1; u8 bw:3; /* 0:20 1:40 2:80Mhz */ u8 m_stbc; /* bSTBC + 1 for WIN/CE, bSTBC for others*/ u16 packet_period; u32 packet_count; - /* u32 PacketLength; */ + u32 packet_length; u8 packet_pattern; u16 sfd; u8 signal_field; u8 service_field; + u8 service_field_bit2:1; u16 length; u8 crc16[2]; u8 lsig[3]; @@ -68,7 +64,6 @@ struct phydm_pmac_info { u8 vht_sig_b[4]; u8 vht_sig_b_crc; u8 vht_delimiter[4]; - /* u8 mac_addr[6]; */ }; struct phydm_pmac_tx { @@ -79,7 +74,6 @@ struct phydm_pmac_tx { boolean cck_cont_tx; boolean ofdm_cont_tx; u8 path; - u32 tx_scailing; }; /* 1 ============================================================ @@ -108,12 +102,11 @@ void phydm_start_ofdm_cont_tx(void *dm_void); void phydm_stop_ofdm_cont_tx(void *dm_void); -void phydm_set_single_tone(void *dm_void, boolean is_single_tone, - boolean en_pmac_tx, u8 path); - void phydm_set_pmac_tx(void *dm_void, struct phydm_pmac_info *tx_info, enum rf_path mpt_rf_path); void phydm_set_tmac_tx(void *dm_void); +void phydm_pmac_tx_dbg(void *dm_void, char input[][16], u32 *_used, + char *output, u32 *_out_len); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pre_define.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pre_define.h index 17f8c0ca2256..8e29d5c467ae 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pre_define.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_pre_define.h @@ -33,8 +33,8 @@ * 1 ============================================================ ***************************************************************/ -#define PHYDM_CODE_BASE "PHYDM_V042" -#define PHYDM_RELEASE_DATE "20190702.0" +#define PHYDM_CODE_BASE "PHYDM_V049" +#define PHYDM_RELEASE_DATE "20200720.0" /*PHYDM API status*/ #define PHYDM_SET_FAIL 0 @@ -60,6 +60,7 @@ #define MAX_PATH_NUM_8197G 2 #define MAX_PATH_NUM_8721D 1 #define MAX_PATH_NUM_8710C 1 +#define MAX_PATH_NUM_8723F 2 /*@AC-IC*/ #define MAX_PATH_NUM_8821A 1 @@ -357,7 +358,7 @@ enum phydm_legacy_spec_rate { /*[N-1SS]*/ #elif (RTL8723B_SUPPORT || RTL8703B_SUPPORT || RTL8188E_SUPPORT || \ RTL8188F_SUPPORT || RTL8723D_SUPPORT || RTL8195A_SUPPORT ||\ - RTL8710B_SUPPORT || RTL8721D_SUPPORT || RTL8710C_SUPPORT) + RTL8710B_SUPPORT || RTL8721D_SUPPORT || RTL8710C_SUPPORT || RTL8723F_SUPPORT) #define PHY_NUM_RATE_IDX NUM_RATE_N_1SS #else #define PHY_NUM_RATE_IDX NUM_RATE_AC_4SS @@ -412,7 +413,8 @@ enum phydm_ic { ODM_RTL8812F = BIT(20), ODM_RTL8197G = BIT(21), ODM_RTL8721D = BIT(22), - ODM_RTL8710C = BIT(23) + ODM_RTL8710C = BIT(23), + ODM_RTL8723F = BIT(24) }; #define ODM_IC_N_1SS (ODM_RTL8188E | ODM_RTL8188F | ODM_RTL8723B |\ @@ -428,7 +430,7 @@ enum phydm_ic { #define ODM_IC_AC_3SS 0 #define ODM_IC_AC_4SS (ODM_RTL8814A) -#define ODM_IC_JGR3_1SS 0 +#define ODM_IC_JGR3_1SS (ODM_RTL8723F) #define ODM_IC_JGR3_2SS (ODM_RTL8822C | ODM_RTL8812F | ODM_RTL8197G) #define ODM_IC_JGR3_3SS 0 #define ODM_IC_JGR3_4SS (ODM_RTL8198F | ODM_RTL8814B) @@ -462,7 +464,7 @@ enum phydm_ic { ODM_RTL8821C | ODM_RTL8710B | ODM_RTL8195B |\ ODM_RTL8192F | ODM_RTL8721D | ODM_RTL8710C) #define PHYSTS_3RD_TYPE_IC (ODM_RTL8198F | ODM_RTL8814B | ODM_RTL8822C |\ - ODM_RTL8812F | ODM_RTL8197G) + ODM_RTL8812F | ODM_RTL8197G | ODM_RTL8723F) /*@[FW Type]*/ #define PHYDM_IC_8051_SERIES (ODM_RTL8881A | ODM_RTL8812 | ODM_RTL8821 |\ ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8703B |\ @@ -471,12 +473,12 @@ enum phydm_ic { #define PHYDM_IC_3081_SERIES (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8197F |\ ODM_RTL8821C | ODM_RTL8195B | ODM_RTL8198F |\ ODM_RTL8822C | ODM_RTL8812F | ODM_RTL8814B |\ - ODM_RTL8197G) + ODM_RTL8197G | ODM_RTL8723F) /*@[LA mode]*/ #define PHYDM_IC_SUPPORT_LA_MODE (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8197F |\ ODM_RTL8821C | ODM_RTL8195B | ODM_RTL8198F |\ ODM_RTL8192F | ODM_RTL8822C | ODM_RTL8812F |\ - ODM_RTL8195B | ODM_RTL8814B | ODM_RTL8197G) + ODM_RTL8195B | ODM_RTL8814B | ODM_RTL8197G | ODM_RTL8723F) /*@[BF]*/ #define ODM_IC_TXBF_SUPPORT (ODM_RTL8192E | ODM_RTL8812 | ODM_RTL8821 |\ ODM_RTL8814A | ODM_RTL8881A | ODM_RTL8822B |\ @@ -485,7 +487,7 @@ enum phydm_ic { ODM_RTL8814B | ODM_RTL8197G) #define PHYDM_IC_SUPPORT_MU_BFEE (ODM_RTL8822B | ODM_RTL8821C | ODM_RTL8814B |\ ODM_RTL8195B | ODM_RTL8198F | ODM_RTL8822C |\ - ODM_RTL8812F) + ODM_RTL8812F | ODM_RTL8723F) #define PHYDM_IC_SUPPORT_MU_BFER (ODM_RTL8822B | ODM_RTL8814B | ODM_RTL8198F |\ ODM_RTL8822C | ODM_RTL8812F) @@ -495,23 +497,43 @@ enum phydm_ic { #define CMN_API_SUPPORT_IC (ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8192F |\ ODM_RTL8821C | ODM_RTL8195B | ODM_RTL8822C |\ ODM_RTL8198F | ODM_RTL8812F | ODM_RTL8814B |\ - ODM_RTL8197G | ODM_RTL8721D | ODM_RTL8710C) + ODM_RTL8197G | ODM_RTL8721D | ODM_RTL8710C | ODM_RTL8723F) /* fw offload ability*/ #define PHYDM_IC_SUPPORT_FW_PARAM_OFFLOAD (ODM_RTL8814A | ODM_RTL8822B |\ ODM_RTL8821C | ODM_RTL8822C) +/* halmac offload ability*/ +#define PHYDM_IC_SUPPORT_HALMAC_PARAM_OFFLOAD (ODM_RTL8822C | ODM_RTL8812F |\ + ODM_RTL8814B | ODM_RTL8723F) + +/*[CCX]*/ +#define PHYDM_IC_SUPPORT_FAHM (ODM_RTL8822B | ODM_RTL8821C | ODM_RTL8198F |\ + ODM_RTL8814B | ODM_RTL8822C | ODM_RTL8812F |\ + ODM_RTL8197G | ODM_RTL8723F) +#define PHYDM_IC_SUPPORT_IFS_CLM (ODM_RTL8822C | ODM_RTL8812F | ODM_RTL8197G | ODM_RTL8723F) + +/*[ARFR]*/ +/*for MAC HW control rate_id=0~12 and 2.4g vht mode(1ss/2ss) support*/ +#define PHYDM_IC_RATEID_IDX_TYPE2 (ODM_RTL8822B | ODM_RTL8822C | ODM_RTL8195B |\ + ODM_RTL8821C) + /*@========[Compile time IC flag] ========================*/ /*@========[AC-3/AC/N Support] ===========================*/ #if (RTL8814B_SUPPORT || RTL8198F_SUPPORT || RTL8822C_SUPPORT ||\ - RTL8812F_SUPPORT || RTL8197G_SUPPORT) + RTL8812F_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_IC_JGR3_SERIES_SUPPORT #if (RTL8814B_SUPPORT || RTL8822C_SUPPORT || RTL8812F_SUPPORT) #define PHYDM_IC_JGR3_80M_SUPPORT #endif #endif +#if (RTL8822C_SUPPORT || RTL8812F_SUPPORT || RTL8814B_SUPPORT ||\ + RTL8723F_SUPPORT) + #define PHYDM_IC_HALMAC_PARAM_SUPPORT +#endif + #if (DM_ODM_SUPPORT_TYPE == ODM_AP) #ifdef RTK_AC_SUPPORT @@ -556,7 +578,7 @@ enum phydm_ic { RTL8703B_SUPPORT || RTL8723D_SUPPORT || RTL8881A_SUPPORT ||\ RTL8821A_SUPPORT || RTL8821C_SUPPORT || RTL8195A_SUPPORT ||\ RTL8710B_SUPPORT || RTL8195B_SUPPORT || RTL8721D_SUPPORT ||\ - RTL8710C_SUPPORT) + RTL8710C_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_COMPILE_IC_1SS #endif @@ -615,7 +637,7 @@ enum phydm_ic { #endif #if (RTL8198F_SUPPORT || RTL8814B_SUPPORT || RTL8822C_SUPPORT ||\ - RTL8812F_SUPPORT || RTL8197G_SUPPORT) + RTL8812F_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) #define PHYSTS_3RD_TYPE_SUPPORT #endif @@ -624,7 +646,7 @@ enum phydm_ic { #endif #if (RTL8198F_SUPPORT || RTL8814B_SUPPORT || RTL8822C_SUPPORT ||\ - RTL8812F_SUPPORT || RTL8197G_SUPPORT) + RTL8812F_SUPPORT || RTL8197G_SUPPORT || RTL8723F_SUPPORT) #define BB_RAM_SUPPORT #endif @@ -638,14 +660,14 @@ enum phydm_ic { #define CONFIG_MU_JAGUAR_2 #endif -#if (RTL8814B_SUPPORT || RTL8822C_SUPPORT) +#if (RTL8814B_SUPPORT || RTL8822C_SUPPORT || RTL8812F_SUPPORT) #define CONFIG_MU_JAGUAR_3 #endif #if (defined(CONFIG_MU_JAGUAR_2) || defined(CONFIG_MU_JAGUAR_3)) #if (RTL8814B_SUPPORT) #define MU_EX_MACID 76 - #elif (RTL8822B_SUPPORT || RTL8822C_SUPPORT) + #elif (RTL8822B_SUPPORT || RTL8822C_SUPPORT || RTL8812F_SUPPORT) #define MU_EX_MACID 30 #endif #endif @@ -654,11 +676,21 @@ enum phydm_ic { #if (RTL8822B_SUPPORT || RTL8197F_SUPPORT || RTL8821C_SUPPORT ||\ RTL8192F_SUPPORT || RTL8195B_SUPPORT || RTL8822C_SUPPORT ||\ RTL8198F_SUPPORT || RTL8812F_SUPPORT || RTL8814B_SUPPORT ||\ - RTL8197G_SUPPORT || RTL8721D_SUPPORT || RTL8710C_SUPPORT) + RTL8197G_SUPPORT || RTL8721D_SUPPORT || RTL8710C_SUPPORT || RTL8723F_SUPPORT) #define PHYDM_COMMON_API_SUPPORT #endif -#if (RTL8821C_SUPPORT || RTL8197F_SUPPORT) +#define PHYDM_COMMON_API_IC (ODM_IC_JGR3_SERIES | ODM_RTL8822B |\ + ODM_RTL8197F | ODM_RTL8821C | ODM_RTL8192F | ODM_RTL8195B |\ + ODM_RTL8721D | ODM_RTL8710C) + +#if (RTL8188E_SUPPORT || RTL8192E_SUPPORT || RTL8821A_SUPPORT ||\ + RTL8812A_SUPPORT || RTL8723B_SUPPORT || RTL8703B_SUPPORT ||\ + RTL8195A_SUPPORT || RTL8814A_SUPPORT) +#define PHYDM_COMMON_API_NOT_SUPPORT +#endif + +#if (RTL8821C_SUPPORT || RTL8197F_SUPPORT || RTL8197G_SUPPORT) #define CONFIG_RFE_BY_HW_INFO #endif @@ -694,6 +726,17 @@ enum phydm_ic { #define LOW_BW_RATE_NUM VHT_RATE_NUM +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +#define SECOND_CH_AT_LSB 2 /*@primary CH @ MSB, SD4: HAL_PRIME_CHNL_OFFSET_UPPER*/ +#define SECOND_CH_AT_USB 1 /*@primary CH @ LSB, SD4: HAL_PRIME_CHNL_OFFSET_LOWER*/ +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#define SECOND_CH_AT_LSB 2 /*@primary CH @ MSB, SD7: HAL_PRIME_CHNL_OFFSET_UPPER*/ +#define SECOND_CH_AT_USB 1 /*@primary CH @ LSB, SD7: HAL_PRIME_CHNL_OFFSET_LOWER*/ +#else /*if (DM_ODM_SUPPORT_TYPE == ODM_AP)*/ +#define SECOND_CH_AT_LSB 1 /*@primary CH @ MSB, SD8: HT_2NDCH_OFFSET_BELOW*/ +#define SECOND_CH_AT_USB 2 /*@primary CH @ LSB, SD8: HT_2NDCH_OFFSET_ABOVE*/ +#endif + enum phydm_ic_ip { PHYDM_IC_N = 0, PHYDM_IC_AC = 1, @@ -787,6 +830,13 @@ enum odm_band_type { #endif }; +enum odm_rf_band { + ODM_RF_BAND_2G = 0, + ODM_RF_BAND_5G_LOW = 1, + ODM_RF_BAND_5G_MID = 2, + ODM_RF_BAND_5G_HIGH = 3, +}; + /* ODM_CMNINFO_SEC_CHNL_OFFSET */ enum phydm_sec_chnl_offset { PHYDM_DONT_CARE = 0, @@ -920,6 +970,15 @@ enum odm_antdiv_gpio { ANTDIV_GPIO_PA16PA17 = 4, ANTDIV_GPIO_PB1PB2 = 5, ANTDIV_GPIO_PB26PB29 = 6, + ANTDIV_GPIO_PB1PB2PB26 = 7, // add by Jiao Qi for AmebaD SP3T only +}; + +/* ODM_CMNINFO_PEAK_DETECT_MODE */ +enum odm_peak_detect_mode { + ODM_PD_DIS = 0, + ODM_PD_ENG = 1, + ODM_PD_ENA = 2, + ODM_PD_ENALL = 3, }; #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_precomp.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_precomp.h index c8320cb5f21a..06c8badae056 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_precomp.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_precomp.h @@ -170,7 +170,9 @@ #ifndef RTL8710C_SUPPORT #define RTL8710C_SUPPORT 0 #endif - +#ifndef RTL8723F_SUPPORT + #define RTL8723F_SUPPORT 0 +#endif #if (DM_ODM_SUPPORT_TYPE & ODM_CE) && \ (!defined(DM_ODM_CE_MAC80211) && !defined(DM_ODM_CE_MAC80211_V2)) @@ -184,6 +186,10 @@ void phy_set_tx_power_limit( u8 *channel, u8 *power_limit); +void phy_set_tx_power_limit_ex(struct dm_struct *dm, u8 regulation, u8 band, + u8 bandwidth, u8 rate_section, u8 rf_path, + u8 channel, s8 power_limit); + enum hal_status rtw_phydm_fw_iqk( struct dm_struct *dm, @@ -469,6 +475,7 @@ rtw_phydm_cfg_phy_para( #include "rtl8821c/halhwimg8821c_mac.h" #include "rtl8821c/halhwimg8821c_bb.h" #include "rtl8821c/phydm_regconfig8821c.h" + #include "rtl8821c/phydm_rtl8821c.h" #include "halrf/rtl8821c/halrf_8821c.h" #include "halrf/rtl8821c/halhwimg8821c_rf.h" #include "halrf/rtl8821c/version_rtl8821c_rf.h" @@ -594,6 +601,7 @@ rtw_phydm_cfg_phy_para( #include "halrf/rtl8814b/version_rtl8814b_rf.h" #include "rtl8814b/phydm_hal_api8814b.h" #include "rtl8814b/version_rtl8814b.h" + #include "rtl8814b/phydm_extraagc8814b.h" #if (DM_ODM_SUPPORT_TYPE == ODM_CE) #include /* @struct HAL_DATA_TYPE */ #include /* @RX_SMOOTH_FACTOR, reg definition and etc.*/ @@ -607,6 +615,7 @@ rtw_phydm_cfg_phy_para( #include "halrf/rtl8812f/version_rtl8812f_rf.h" #include "rtl8812f/phydm_hal_api8812f.h" #include "rtl8812f/version_rtl8812f.h" + #include "rtl8812f/phydm_rtl8812f.h" #endif #if (RTL8197G_SUPPORT) #include "rtl8197g/halhwimg8197g_bb.h" @@ -617,5 +626,27 @@ rtw_phydm_cfg_phy_para( #include "halrf/rtl8197g/version_rtl8197g_rf.h" #include "rtl8197g/phydm_hal_api8197g.h" #include "rtl8197g/version_rtl8197g.h" + #include "rtl8197g/phydm_rtl8197g.h" +#endif +#if (RTL8723F_SUPPORT) + #include "rtl8723f/halhwimg8723f_bb.h" + #include "rtl8723f/halhwimg8723f_mac.h" + #include "rtl8723f/phydm_regconfig8723f.h" + #include "halrf/rtl8723f/halrf_8723f.h" + #include "halrf/rtl8723f/halhwimg8723f_rf.h" + #include "halrf/rtl8723f/version_rtl8723f_rf.h" + #include "halrf/rtl8723f/halrf_iqk_8723f.h" + #include "halrf/rtl8723f/halrf_dpk_8723f.h" + #include "halrf/rtl8723f/halrf_tssi_8723f.h" + #include "halrf/rtl8723f/halrf_rfk_init_8723f.h" + #include "rtl8723f/phydm_hal_api8723f.h" + #include "rtl8723f/version_rtl8723f.h" + #include "rtl8723f/phydm_rtl8723f.h" + #if (DM_ODM_SUPPORT_TYPE == ODM_CE) + /* @struct HAL_DATA_TYPE */ + #include + /* @RX_SMOOTH_FACTOR, reg definition and etc.*/ + #include + #endif #endif #endif /* @__ODM_PRECOMP_H__ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_primary_cca.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_primary_cca.h index 867d69fd5f3c..e13741617a9f 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_primary_cca.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_primary_cca.h @@ -34,17 +34,6 @@ /*@Definition */ /*@============================================================*/ -#if (DM_ODM_SUPPORT_TYPE == ODM_CE) -#define SECOND_CH_AT_LSB 2 /*@primary CH @ MSB, SD4: HAL_PRIME_CHNL_OFFSET_UPPER*/ -#define SECOND_CH_AT_USB 1 /*@primary CH @ LSB, SD4: HAL_PRIME_CHNL_OFFSET_LOWER*/ -#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) -#define SECOND_CH_AT_LSB 2 /*@primary CH @ MSB, SD7: HAL_PRIME_CHNL_OFFSET_UPPER*/ -#define SECOND_CH_AT_USB 1 /*@primary CH @ LSB, SD7: HAL_PRIME_CHNL_OFFSET_LOWER*/ -#else /*if (DM_ODM_SUPPORT_TYPE == ODM_AP)*/ -#define SECOND_CH_AT_LSB 1 /*@primary CH @ MSB, SD8: HT_2NDCH_OFFSET_BELOW*/ -#define SECOND_CH_AT_USB 2 /*@primary CH @ LSB, SD8: HT_2NDCH_OFFSET_ABOVE*/ -#endif - #define OFDMCCA_TH 500 #define bw_ind_bias 500 #define PRI_CCA_MONITOR_TIME 30 diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_psd.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_psd.c index 1e14df1a5a01..49c848b59b31 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_psd.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_psd.c @@ -38,6 +38,16 @@ u32 phydm_get_psd_data(void *dm_void, u32 psd_tone_idx, u32 igi) u32 psd_report = 0; if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + #if(RTL8723F_SUPPORT) + if (dm->support_ic_type & (ODM_RTL8723F)) { + odm_set_bb_reg(dm, dm_psd_table->psd_reg, 0x3ff80000, psd_tone_idx & 0x7ff); + /*PSD trigger start*/ + odm_set_bb_reg(dm, dm_psd_table->psd_reg, BIT(16), 1); + ODM_delay_us(10 << (dm_psd_table->fft_smp_point >> 7)); + /*PSD trigger stop*/ + odm_set_bb_reg(dm, dm_psd_table->psd_reg, BIT(16), 0); + } + #endif #if 0 odm_set_bb_reg(dm, R_0x1e8c, 0x3ff, psd_tone_idx & 0x3ff); odm_set_bb_reg(dm, R_0x1e88, BIT(27) | BIT(26), @@ -72,6 +82,12 @@ u32 phydm_get_psd_data(void *dm_void, u32 psd_tone_idx, u32 igi) 0xffffff); psd_report = psd_report >> 5; } else if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + #if(RTL8723F_SUPPORT) + if (dm->support_ic_type & (ODM_RTL8723F)) { + psd_report = odm_get_bb_reg(dm, dm_psd_table->psd_report_reg, + 0x1ffffff); + } + #endif #if 0 psd_report = odm_get_bb_reg(dm, dm_psd_table->psd_report_reg, 0xffffff); @@ -153,6 +169,13 @@ u8 phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point) else if (psd_fc_channel > 140) ag_rf_mode_reg = 0x5; #endif + } else if (dm->support_ic_type & ODM_RTL8723F) { + if (psd_fc_channel < 80) + ag_rf_mode_reg = 0x1; + else if (psd_fc_channel >= 80 && psd_fc_channel <= 144) + ag_rf_mode_reg = 0x5; + else if (psd_fc_channel > 144) + ag_rf_mode_reg = 0x9; } else if (dm->support_ic_type == ODM_RTL8721D) { if (psd_fc_channel >= 36 && psd_fc_channel <= 64) ag_rf_mode_reg = 0x1; @@ -189,6 +212,27 @@ u8 phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point) odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, 0x70000, ag_rf_mode_reg); #endif + } else if (dm->support_ic_type & ODM_RTL8723F) { + /* @2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ + odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, 0x1c00, + dm_psd_table->psd_bw_rf_reg); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, 0x1c00, + dm_psd_table->psd_bw_rf_reg); + /* Set RF ag fc mode*/ + odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, 0x30000, 1); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, 0x30000, 1); + if(ag_rf_mode_reg == 1) { + odm_set_rf_reg(dm, RF_PATH_A, RF_0x19, 0xc0000, 0); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x19, 0xc0000, 0); + } + else if(ag_rf_mode_reg == 5){ + odm_set_rf_reg(dm, RF_PATH_A, RF_0x19, 0xc0000, 1); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x19, 0xc0000, 1); + } + else { + odm_set_rf_reg(dm, RF_PATH_A, RF_0x19, 0xc0000, 2); + odm_set_rf_reg(dm, RF_PATH_B, RF_0x19, 0xc0000, 2); + } } else { /* @2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ if (dm->support_ic_type == ODM_RTL8721D) { @@ -196,7 +240,7 @@ u8 phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point) dm_psd_table->psd_bw_rf_reg); #if (RTL8710C_SUPPORT == 1) } else if (dm->support_ic_type == ODM_RTL8710C) { - config_phydm_write_rf_reg_8710c(dm, RF_PATH_A, + odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, 0x1c00, dm_psd_table->psd_bw_rf_reg); #endif @@ -213,12 +257,14 @@ u8 phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point) ag_rf_mode_reg); } - #if 0 - if (dm->support_ic_type & ODM_IC_JGR3_SERIES) + if (dm->support_ic_type & ODM_IC_JGR3_SERIES){ + if (dm->support_ic_type & ODM_RTL8723F) { PHYDM_DBG(dm, ODM_COMP_API, "0x1d70=((0x%x))\n", odm_get_bb_reg(dm, R_0x1d70, MASKDWORD)); - else - #endif + PHYDM_DBG(dm, ODM_COMP_API, "RF0x19=((0x%x))\n", + odm_get_rf_reg(dm, RF_PATH_A, RF_0x19, RFREG_MASK)); + } + } else PHYDM_DBG(dm, ODM_COMP_API, "0xc50=((0x%x))\n", odm_get_bb_reg(dm, R_0xc50, MASKDWORD)); @@ -315,17 +361,34 @@ void phydm_psd_para_setting(void *dm_void, u8 sw_avg_time, u8 hw_avg_time, dm_psd_table->sw_avg_time = sw_avg_time; dm_psd_table->psd_fc_channel = channel; dm_psd_table->noise_k_en = noise_k_en; - - if (fft_smp_point == 128) - fft_smp_point_idx = 0; - else if (fft_smp_point == 256) - fft_smp_point_idx = 1; - else if (fft_smp_point == 512) - fft_smp_point_idx = 2; - else if (fft_smp_point == 1024) - fft_smp_point_idx = 3; - + if (dm->support_ic_type & ODM_RTL8723F) { + if (fft_smp_point == 128) + fft_smp_point_idx = 3; + else if (fft_smp_point == 256) + fft_smp_point_idx = 2; + else if (fft_smp_point == 512) + fft_smp_point_idx = 1; + else if (fft_smp_point == 1024) + fft_smp_point_idx = 0; + } + else { + if (fft_smp_point == 128) + fft_smp_point_idx = 0; + else if (fft_smp_point == 256) + fft_smp_point_idx = 1; + else if (fft_smp_point == 512) + fft_smp_point_idx = 2; + else if (fft_smp_point == 1024) + fft_smp_point_idx = 3; + } if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + #if (RTL8723F_SUPPORT) + odm_set_bb_reg(dm, R_0x1e8c, BIT(12) | BIT(11), hw_avg_time); + odm_set_bb_reg(dm, R_0x1e8c, BIT(14) | BIT(13), + fft_smp_point_idx); + odm_set_bb_reg(dm, R_0x1e8c, BIT(18) | BIT(17), ant_sel); + odm_set_bb_reg(dm, R_0x1e88, BIT(25) | BIT(24), psd_input); + #else #if 0 odm_set_bb_reg(dm, R_0x1e8c, BIT(11) | BIT(10), i_q_setting); odm_set_bb_reg(dm, R_0x1e8c, BIT(13) | BIT(12), hw_avg_time); @@ -342,6 +405,7 @@ void phydm_psd_para_setting(void *dm_void, u8 sw_avg_time, u8 hw_avg_time, odm_set_bb_reg(dm, R_0x1e8c, BIT(17) | BIT(16), ant_sel); odm_set_bb_reg(dm, R_0x1e8c, BIT(23) | BIT(22), psd_input); #endif + #endif } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { odm_set_bb_reg(dm, R_0x910, BIT(11) | BIT(10), i_q_setting); odm_set_bb_reg(dm, R_0x910, BIT(13) | BIT(12), hw_avg_time); @@ -375,6 +439,15 @@ void phydm_psd_init(void *dm_void) dm_psd_table->psd_in_progress = false; if (dm->support_ic_type & ODM_IC_JGR3_SERIES) { + #if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) { + dm_psd_table->psd_reg = R_0x1e8c; + dm_psd_table->psd_report_reg = R_0x2d90; + + /*@2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ + dm_psd_table->psd_bw_rf_reg = 2; + } + #else #if 0 dm_psd_table->psd_reg = R_0x1e8c; dm_psd_table->psd_report_reg = R_0x2d90; @@ -384,6 +457,7 @@ void phydm_psd_init(void *dm_void) #endif return; + #endif } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) { dm_psd_table->psd_reg = R_0x910; dm_psd_table->psd_report_reg = R_0xf44; @@ -420,6 +494,11 @@ void phydm_psd_debug(void *dm_void, char input[][16], u32 *_used, if ((strcmp(input[1], help) == 0)) { #ifdef PHYDM_IC_JGR3_SERIES_SUPPORT + #if (RTL8723F_SUPPORT) + if (dm->support_ic_type & ODM_RTL8723F) + PDM_SNPF(out_len, used, output + used, out_len - used, + "{0} {sw_avg} {hw_avg 0:3} {1:I,2:Q,3:IQ} {fft_point: 128*(1:4)}\n{path_sel 0~3} {0:ADC, 1:rxdata_fir_in, 2:rx_nbi_nf_stage2} {CH} {noise_k}\n\n"); + #endif #if 0 if (dm->support_ic_type & ODM_IC_JGR3_SERIES) PDM_SNPF(out_len, used, output + used, out_len - used, @@ -439,9 +518,8 @@ void phydm_psd_debug(void *dm_void, char input[][16], u32 *_used, if (var1[0] == 0) { for (i = 1; i < 10; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, - &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); } PDM_SNPF(out_len, used, output + used, out_len - used, "sw_avg_time=((%d)), hw_avg_time=((%d)), IQ=((%d)), fft=((%d)), path=((%d)), input =((%d)) ch=((%d)), noise_k=((%d))\n", diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rainfo.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rainfo.c index d2d52b5e0aa8..a1b9428f1165 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rainfo.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rainfo.c @@ -60,7 +60,8 @@ u8 phydm_legacy_rate_2_spec_rate(void *dm_void, u8 rate) PHYDM_SPEC_RATE_24M, PHYDM_SPEC_RATE_36M, PHYDM_SPEC_RATE_48M, PHYDM_SPEC_RATE_54M}; - rate_idx = rate - ODM_RATE6M; + if ((rate >= ODM_RATE6M) && (rate <= ODM_RATE54M)) + rate_idx = rate - ODM_RATE6M; return legacy_spec_rate_t[rate_idx]; } @@ -138,10 +139,8 @@ void phydm_h2C_debug(void *dm_void, char input[][16], u32 *_used, u8 phydm_h2c_id = 0; for (i = 0; i < 8; i++) { - if (input[i + 1]) { - PHYDM_SSCANF(input[i + 1], DCMD_HEX, &dm_value[i]); - input_idx++; - } + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &dm_value[i]); + input_idx++; } if (input_idx == 0) @@ -203,11 +202,11 @@ void phydm_ra_debug(void *dm_void, char input[][16], u32 *_used, char *output, char help[] = "-h"; u32 var[5] = {0}; u8 macid = 0, bw = 0, rate = 0; + u8 tx_cls_en = 0, tx_cls_th = 0, tmp = 0; u8 i = 0; for (i = 0; i < 5; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var[i]); } if ((strcmp(input[1], help) == 0)) { @@ -219,7 +218,12 @@ void phydm_ra_debug(void *dm_void, char input[][16], u32 *_used, char *output, "{2} {en} {macid} {bw} {rate}: fw fix rate\n"); PDM_SNPF(out_len, used, output + used, out_len - used, "{3} {en}: Dynamic RRSR\n"); - + PDM_SNPF(out_len, used, output + used, out_len - used, + "{4} {0:pkt RA, 1:TBTT RA, 100:query RA mode}\n"); +#ifdef CONFIG_DYNAMIC_TXCOLLISION_TH + PDM_SNPF(out_len, used, output + used, out_len - used, + "{5} {0:dis, 1:en}{th; 255:auto, xx:dB}: Tx CLS\n"); +#endif } else if (var[0] == 1) { /*@Adjust PCR offset*/ if (var[1] == 100) { @@ -250,10 +254,46 @@ void phydm_ra_debug(void *dm_void, char input[][16], u32 *_used, char *output, var[1], macid, bw, rate); phydm_fw_fix_rate(dm, (u8)var[1], macid, bw, rate); - } else if (var[0] == 3) { /*@FW fix rate*/ + } else if (var[0] == 3) { /*@Dynamic RRSR*/ ra_tab->dynamic_rrsr_en = (boolean)var[1]; PDM_SNPF(out_len, used, output + used, out_len - used, "[Dynamic RRSR] enable=%d", ra_tab->dynamic_rrsr_en); + } else if (var[0] == 4) { /*@RA trigger mode*/ + if (var[1] == 0 || var[1] == 1) + ra_tab->ra_trigger_mode = (u8)var[1]; + PDM_SNPF(out_len, used, output + used, out_len - used, + "[RA trigger] mode=%d\n", ra_tab->ra_trigger_mode); +#ifdef CONFIG_DYNAMIC_TXCOLLISION_TH + } else if (var[0] == 5) { /*@Tx Collision Detection*/ + tx_cls_en = (u8)var[1]; + ra_tab->ra_tx_cls_th = (u8)var[2]; + tmp = (u8)var[2]; + tx_cls_th = (tmp < 50) ? 0 : (tmp > 81) ? 31 : tmp - 50; + if (tx_cls_en) { + odm_set_bb_reg(dm, R_0x8f8, BIT(16), 1); + if (ra_tab->ra_tx_cls_th != 255) { + phydm_tx_collsion_th_set(dm, tx_cls_th, + tx_cls_th); + } + + } else { + odm_set_bb_reg(dm, R_0x8f8, BIT(16), 0); + } + + if (tx_cls_en & ra_tab->ra_tx_cls_th != 255) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "[Tx Collision Detec] {en, th}={%d, %d}\n", + tx_cls_en, tx_cls_th + 50); + } else if (tx_cls_en & ra_tab->ra_tx_cls_th == 255) { + PDM_SNPF(out_len, used, output + used, out_len - used, + "[Tx Collision Detec] {en, th}={%d, auto}\n", + tx_cls_en); + } else { + PDM_SNPF(out_len, used, output + used, out_len - used, + "[Tx Collision Detec] {en, th}={%d, xx}\n", + tx_cls_en); + } +#endif } else { PDM_SNPF(out_len, used, output + used, out_len - used, "[Set] Error\n"); @@ -262,9 +302,31 @@ void phydm_ra_debug(void *dm_void, char input[][16], u32 *_used, char *output, *_out_len = out_len; } +void phydm_ra_mask_report_h2c_trigger(void *dm_void, + struct ra_mask_rpt_trig *trig_rpt) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + + phydm_fw_trace_en_h2c(dm, true, 1, 2, trig_rpt->macid); + + trig_rpt->ra_mask_rpt_stamp = ra_tab->ra_mask_rpt_stamp; +} +void phydm_ra_mask_report_c2h_result(void *dm_void, struct ra_mask_rpt *rpt) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + u8 i = 0; + + rpt->ra_mask_rpt_stamp = ra_tab->ra_mask_rpt_stamp; + + odm_move_memory(dm, &rpt->ra_mask_buf[0], &ra_tab->ra_mask_buf[0], 8); +} + void odm_c2h_ra_para_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) { struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; u8 mode = cmd_buf[0]; /*Retry Penalty, NH, NL*/ u8 i; @@ -327,6 +389,9 @@ void odm_c2h_ra_para_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) for (i = 4; i <= 11; i++) PHYDM_DBG(dm, DBG_FW_TRACE, "RAMASK = 0x%x\n", cmd_buf[i]); + + odm_move_memory(dm, &ra_tab->ra_mask_buf[0], &cmd_buf[4], 8); + ra_tab->ra_mask_rpt_stamp++; } else { PHYDM_DBG(dm, DBG_FW_TRACE, "%5s %x%x %x%x %x%x %x%x\n", "RA Mask:", @@ -434,6 +499,7 @@ void phydm_c2h_ra_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) u8 rate_idx = rate & 0x7f; /*remove bit7 SGI*/ u8 rate_order; u8 gid_index = 0; + u8 txcls_rate = 0; char dbg_buf[PHYDM_SNPRINT_SIZE] = {0}; #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) @@ -442,10 +508,16 @@ void phydm_c2h_ra_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) sta = dm->phydm_sta_info[macid]; #endif - if (cmd_len >= 7) { + if (cmd_len == 7) { ra_ratio = cmd_buf[5]; curr_bw = cmd_buf[6]; PHYDM_DBG(dm, DBG_RA, "[%d] PER=%d\n", macid, ra_ratio); + } else if (cmd_len == 8) { + ra_ratio = cmd_buf[5]; + curr_bw = cmd_buf[6]; + txcls_rate = cmd_buf[7]; + PHYDM_DBG(dm, DBG_RA, "[%d] PER=%d TxCLS=%d\n", macid, ra_ratio, + txcls_rate); } if (cmd_buf[3] != 0) { @@ -470,6 +542,8 @@ void phydm_c2h_ra_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) gid_index = macid - 128; ra_tab->mu1_rate[gid_index] = rate; } + if (macid >= ODM_ASSOCIATE_ENTRY_NUM) + return; #endif if (is_sta_active(sta)) { sta->ra_info.curr_tx_rate = rate; @@ -863,10 +937,14 @@ u8 phydm_get_tx_stream_num(void *dm_void, enum rf_type type) u64 phydm_get_bb_mod_ra_mask(void *dm_void, u8 sta_idx) { struct dm_struct *dm = (struct dm_struct *)dm_void; + struct phydm_iot_center *iot_table = &dm->iot_table; struct cmn_sta_info *sta = dm->phydm_sta_info[sta_idx]; struct ra_sta_info *ra = NULL; enum channel_width bw = 0; enum wireless_set wrls_mode = 0; +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + struct rtl8192cd_priv *priv = dm->priv; +#endif u8 tx_stream_num = 1; u8 rssi_lv = 0; u64 ra_mask_bitmap = 0; @@ -978,8 +1056,21 @@ u64 phydm_get_bb_mod_ra_mask(void *dm_void, u8 sta_idx) PHYDM_DBG(dm, DBG_RA, "Mod by mode=0x%llx\n", ra_mask_bitmap); +#if ((DM_ODM_SUPPORT_TYPE == ODM_AP) && defined(PHYDM_IC_JGR3_SERIES_SUPPORT)) + if (priv->pshare->veriwave_sta_num > 0) { + PHYDM_DBG(dm, DBG_RA, "Mod by RSSI=0x%llx\n", ra_mask_bitmap); + return ra_mask_bitmap; + } +#endif /*@[Modify RA Mask by RSSI level]*/ if (wrls_mode != WIRELESS_CCK) { + if (iot_table->patch_id_40010700) { + ra_mask_bitmap &= (rssi_lv == 0 ? + 0xffffffffffffffff : + 0xfffffffffffffff0); + return ra_mask_bitmap; + } + if (rssi_lv == 0) ra_mask_bitmap &= 0xffffffffffffffff; else if (rssi_lv == 1) @@ -1133,14 +1224,21 @@ u8 phydm_get_rate_id(void *dm_void, u8 sta_idx) else if (tx_stream_num == 4) rate_id_idx = PHYDM_ARFR6_AC_4SS; } else { - if (tx_stream_num == 1) - rate_id_idx = PHYDM_ARFR2_AC_2G_1SS; - else if (tx_stream_num == 2) - rate_id_idx = PHYDM_ARFR3_AC_2G_2SS; - else if (tx_stream_num == 3) + if (tx_stream_num == 1) { + if (dm->support_ic_type & PHYDM_IC_RATEID_IDX_TYPE2) + rate_id_idx = PHYDM_TYPE2_ARFR5_AC_2G_1SS; + else + rate_id_idx = PHYDM_ARFR2_AC_2G_1SS; + } else if (tx_stream_num == 2) { + if (dm->support_ic_type & PHYDM_IC_RATEID_IDX_TYPE2) + rate_id_idx = PHYDM_TYPE2_ARFR3_AC_2G_2SS; + else + rate_id_idx = PHYDM_ARFR3_AC_2G_2SS; + } else if (tx_stream_num == 3) { rate_id_idx = PHYDM_ARFR4_AC_3SS; - else if (tx_stream_num == 4) + } else if (tx_stream_num == 4) { rate_id_idx = PHYDM_ARFR6_AC_4SS; + } } } else { PHYDM_DBG(dm, DBG_RA, "[Warrning] No rate_id is found\n"); @@ -1152,6 +1250,24 @@ u8 phydm_get_rate_id(void *dm_void, u8 sta_idx) return rate_id_idx; } +#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT +void phydm_ra_mode_selection(void *dm_void, u8 mode) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + u8 pre_mode = ra_tab->ra_trigger_mode; /* 0:pkt RA, 1:TBTT RA */ + + if (mode >= 2) { + PHYDM_DBG(dm, DBG_RA, "RA mode selection Fail\n"); + } else { + ra_tab->ra_trigger_mode = mode; + PHYDM_DBG(dm, DBG_RA, "RA mode, 0:pkt RA, 1:TBTT RA\n"); + PHYDM_DBG(dm, DBG_RA, "PreMode=%d,CurMode=%d\n", pre_mode, + mode); + } +} +#endif + void phydm_ra_h2c(void *dm_void, u8 sta_idx, u8 dis_ra, u8 dis_pt, u8 no_update_bw, u8 init_ra_lv, u64 ra_mask) { @@ -1159,6 +1275,7 @@ void phydm_ra_h2c(void *dm_void, u8 sta_idx, u8 dis_ra, u8 dis_pt, struct cmn_sta_info *sta = dm->phydm_sta_info[sta_idx]; struct ra_sta_info *ra = NULL; u8 h2c_val[H2C_MAX_LENGTH] = {0}; + u8 rate_id_idx = 0; if (is_sta_active(sta)) { ra = &sta->ra_info; @@ -1170,14 +1287,29 @@ void phydm_ra_h2c(void *dm_void, u8 sta_idx, u8 dis_ra, u8 dis_pt, PHYDM_DBG(dm, DBG_RA, "%s ======>\n", __func__); PHYDM_DBG(dm, DBG_RA, "MACID=%d\n", sta->mac_id); - - if (dm->is_disable_power_training) - dis_pt = true; - else if (!dm->is_disable_power_training) + +#ifdef PHYDM_POWER_TRAINING_SUPPORT + if ((dm->support_ability & ODM_BB_PWR_TRAIN) && !dm->is_disable_power_training) dis_pt = false; + else + dis_pt = true; + +#else + dis_pt= true; +#endif + + rate_id_idx = ra->rate_id; + + /*for compatibility issues with FW RA [PHYDM-405]*/ + if (dm->support_ic_type & PHYDM_IC_RATEID_IDX_TYPE2) { + if (rate_id_idx == PHYDM_TYPE2_ARFR5_AC_2G_1SS) + rate_id_idx = PHYDM_ARFR2_AC_2G_1SS; + else if (rate_id_idx == PHYDM_TYPE2_ARFR3_AC_2G_2SS) + rate_id_idx = PHYDM_ARFR3_AC_2G_2SS; + } h2c_val[0] = sta->mac_id; - h2c_val[1] = (ra->rate_id & 0x1f) | ((init_ra_lv & 0x3) << 5) | + h2c_val[1] = (rate_id_idx & 0x1f) | ((init_ra_lv & 0x3) << 5) | (ra->is_support_sgi << 7); h2c_val[2] = (u8)((ra->ra_bw_mode) | (((sta->ldpc_en) ? 1 : 0) << 2) | ((no_update_bw & 0x1) << 3) | @@ -1884,6 +2016,21 @@ void phydm_rrsr_en(void *dm_void, boolean en_rrsr) ra_tab->dynamic_rrsr_en = en_rrsr; } +void phydm_arfr_table_init(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + if (dm->support_ic_type & PHYDM_IC_RATEID_IDX_TYPE2) { + /*ARFR table3(2.4g ac 2ss) for rate_id = 16*/ + odm_set_mac_reg(dm, R_0x494, MASKDWORD, 0xfe01f015); + odm_set_mac_reg(dm, R_0x498, MASKDWORD, 0x40000000); + + /*ARFR table5(2.4g ac 1ss) for rate_id = 18*/ + odm_set_mac_reg(dm, R_0x4a4, MASKDWORD, 0x3ff015); + odm_set_mac_reg(dm, R_0x4a8, MASKDWORD, 0x40000000); + } +} + void phydm_ra_info_init(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -1894,7 +2041,9 @@ void phydm_ra_info_init(void *dm_void) ra_tab->ra_th_ofst = 0; ra_tab->ra_ofst_direc = 0; ra_tab->rrsr_val_init = odm_get_mac_reg(dm, R_0x440, MASKDWORD); - + ra_tab->dynamic_rrsr_en = false; + ra_tab->ra_trigger_mode = 1; // default TBTT RA + ra_tab->ra_tx_cls_th = 255; #if (RTL8822B_SUPPORT == 1) if (dm->support_ic_type == ODM_RTL8822B) { u32 ret_value; @@ -1912,6 +2061,8 @@ void phydm_ra_info_init(void *dm_void) phydm_ra_dynamic_rate_id_init(dm); #endif + phydm_arfr_table_init(dm); + phydm_rate_adaptive_mask_init(dm); } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rainfo.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rainfo.h index 04b0dabcdd14..1359af7a7659 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rainfo.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rainfo.h @@ -27,8 +27,8 @@ #ifndef __PHYDMRAINFO_H__ #define __PHYDMRAINFO_H__ -/* 2019.06.28 Add legacy rate 2 spec rate API*/ -#define RAINFO_VERSION "8.5" +/* 2020.08.05 Fix ARFR bug due to rate_id error for 2.4G VHT mode*/ +#define RAINFO_VERSION "8.8" #define FORCED_UPDATE_RAMASK_PERIOD 5 @@ -111,6 +111,16 @@ enum phydm_rateid_idx { PHYDM_ARFR6_AC_4SS = 16 }; +/*ARFR4(0x49c/0x4a0) can not be used because FW BT would use.*/ +enum phydm_rateid_idx_type_2 { + PHYDM_TYPE2_AC_2SS = 9, + PHYDM_TYPE2_AC_1SS = 10, + PHYDM_TYPE2_MIX_1SS = 11, + PHYDM_TYPE2_MIX_2SS = 12, + PHYDM_TYPE2_ARFR3_AC_2G_2SS = 16, /*0x494/0x498*/ + PHYDM_TYPE2_ARFR5_AC_2G_1SS = 18 /*0x4a4/0x4a8*/ +}; + enum phydm_qam_order { PHYDM_QAM_CCK = 0, PHYDM_QAM_BPSK = 1, @@ -193,6 +203,8 @@ struct ra_table { u32 rrsr_val_init; /*0x440*/ u32 rrsr_val_curr; /*0x440*/ boolean dynamic_rrsr_en; + u8 ra_trigger_mode; /*0: pkt RA, 1: TBTT RA*/ + u8 ra_tx_cls_th; /*255: auto, xx: in dB*/ #if 0 /*@CONFIG_RA_DYNAMIC_RTY_LIMIT*/ u8 per_rate_retrylimit_20M[PHY_NUM_RATE_IDX]; u8 per_rate_retrylimit_40M[PHY_NUM_RATE_IDX]; @@ -203,6 +215,18 @@ struct ra_table { u8 ldpc_thres; /* @if RSSI > ldpc_th => switch from LPDC to BCC */ void (*record_ra_info)(void *dm_void, u8 macid, struct cmn_sta_info *sta, u64 ra_mask); + u8 ra_mask_rpt_stamp; + u8 ra_mask_buf[8]; +}; + +struct ra_mask_rpt_trig { + u8 ra_mask_rpt_stamp; + u8 macid; +}; + +struct ra_mask_rpt { + u8 ra_mask_rpt_stamp; + u8 ra_mask_buf[8]; }; /* @1 ============================================================ @@ -231,6 +255,11 @@ void phydm_h2C_debug(void *dm_void, char input[][16], u32 *_used, void phydm_ra_debug(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len); +void phydm_ra_mask_report_h2c_trigger(void *dm_void, + struct ra_mask_rpt_trig *trig_rpt); + +void phydm_ra_mask_report_c2h_result(void *dm_void, struct ra_mask_rpt *rpt); + void odm_c2h_ra_para_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len); void phydm_print_rate(void *dm_void, u8 rate, u32 dbg_component); @@ -297,4 +326,9 @@ void phydm_ra_mask_watchdog(void *dm_void); void odm_refresh_basic_rate_mask( void *dm_void); #endif + +#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT +void phydm_ra_mode_selection(void *dm_void, u8 mode); +#endif + #endif /*@#ifndef __PHYDMRAINFO_H__*/ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_regtable.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_regtable.h index 2e1071c8f232..8376d4adb73d 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_regtable.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_regtable.h @@ -25,6 +25,7 @@ #define R_0x0 0x0 #define R_0x00 0x00 +#define R_0x08 0x08 #define R_0x0106 0x0106 #define R_0x0140 0x0140 #define R_0x0144 0x0144 @@ -32,11 +33,17 @@ #define R_0x040 0x040 #define R_0x10 0x10 #define R_0x100 0x100 +#define R_0x1008 0x1008 #define R_0x1038 0x1038 #define R_0x103c 0x103c #define R_0x1040 0x1040 #define R_0x1048 0x1048 #define R_0x1080 0x1080 +#define R_0x1208 0x1208 +#define R_0x1210 0x1210 +#define R_0x1214 0x1214 +#define R_0x1218 0x1218 +#define R_0x121c 0x121c #define R_0x14 0x14 #define R_0x14c0 0x14c0 #define R_0x14c4 0x14c4 @@ -113,12 +120,18 @@ #define R_0x1a00 0x1a00 #define R_0x1a04 0x1a04 #define R_0x1a08 0x1a08 +#define R_0x1a0c 0x1a0c #define R_0x1a10 0x1a10 #define R_0x1a14 0x1a14 +#define R_0x1a18 0x1a18 +#define R_0x1a1c 0x1a1c #define R_0x1a20 0x1a20 #define R_0x1a24 0x1a24 #define R_0x1a28 0x1a28 #define R_0x1a2c 0x1a2c +#define R_0x1a30 0x1a30 +#define R_0x1a34 0x1a34 +#define R_0x1a38 0x1a38 #define R_0x1a5c 0x1a5c #define R_0x1a70 0x1a70 #define R_0x1a74 0x1a74 @@ -205,6 +218,7 @@ #define R_0x1bd6 0x1bd6 #define R_0x1bd8 0x1bd8 #define R_0x1bdc 0x1bdc +#define R_0x1be3 0x1be3 #define R_0x1be4 0x1be4 #define R_0x1be8 0x1be8 #define R_0x1beb 0x1beb @@ -238,8 +252,10 @@ #define R_0x1ca4 0x1ca4 #define R_0x1cb0 0x1cb0 #define R_0x1cb8 0x1cb8 +#define R_0x1cbc 0x1cbc #define R_0x1cc0 0x1cc0 #define R_0x1cd0 0x1cd0 +#define R_0x1cd8 0x1cd8 #define R_0x1ce4 0x1ce4 #define R_0x1ce8 0x1ce8 #define R_0x1cec 0x1cec @@ -253,6 +269,7 @@ #define R_0x1d2c 0x1d2c #define R_0x1d30 0x1d30 #define R_0x1d3c 0x1d3c +#define R_0x1d40 0x1d40 #define R_0x1d44 0x1d44 #define R_0x1d48 0x1d48 #define R_0x1d58 0x1d58 @@ -276,6 +293,10 @@ #define R_0x1e40 0x1e40 #define R_0x1e44 0x1e44 #define R_0x1e48 0x1e48 +#define R_0x1e4c 0x1e4c +#define R_0x1e50 0x1e50 +#define R_0x1e54 0x1e54 +#define R_0x1e58 0x1e58 #define R_0x1e5c 0x1e5c #define R_0x1e60 0x1e60 #define R_0x1e64 0x1e64 @@ -283,19 +304,39 @@ #define R_0x1e6c 0x1e6c #define R_0x1e70 0x1e70 #define R_0x1e7c 0x1e7c +#define R_0x1e80 0x1e80 #define R_0x1e84 0x1e84 #define R_0x1e88 0x1e88 #define R_0x1e8c 0x1e8c #define R_0x1ea4 0x1ea4 #define R_0x1eb4 0x1eb4 #define R_0x1eb8 0x1eb8 +#define R_0x1ed4 0x1ed4 +#define R_0x1ed8 0x1ed8 +#define R_0x1edc 0x1edc +#define R_0x1ee0 0x1ee0 +#define R_0x1ee4 0x1ee4 #define R_0x1ee8 0x1ee8 #define R_0x1eec 0x1eec #define R_0x1ef0 0x1ef0 #define R_0x1ef4 0x1ef4 +#define R_0x1ef8 0x1ef8 #define R_0x1efc 0x1efc +#define R_0x1f80 0x1f80 +#define R_0x1f98 0x1f98 #define R_0x24 0x24 #define R_0x28 0x28 +#define R_0x2a00 0x2a00 +#define R_0x2a04 0x2a04 +#define R_0x2a08 0x2a08 +#define R_0x2a24 0x2a24 +#define R_0x2a38 0x2a38 +#define R_0x2a3c 0x2a3c +#define R_0x2a44 0x2a44 +#define R_0x2aa0 0x2aa0 +#define R_0x2aa8 0x2aa8 +#define R_0x2aac 0x2aac +#define R_0x2ad0 0x2ad0 #define R_0x2c 0x2c #define R_0x28a4 0x28a4 #define R_0x2c04 0x2c04 @@ -321,6 +362,8 @@ #define R_0x2d44 0x2d44 #define R_0x2d48 0x2d48 #define R_0x2d4c 0x2d4c +#define R_0x2d6c 0x2d6c +#define R_0x2d84 0x2d84 #define R_0x2d88 0x2d88 #define R_0x2d90 0x2d90 #define R_0x2d9c 0x2d9c @@ -332,6 +375,15 @@ #define R_0x2de8 0x2de8 #define R_0x2e00 0x2e00 #define R_0x2e20 0x2e20 +#define R_0x2e60 0x2e60 +#define R_0x2e64 0x2e64 +#define R_0x2e68 0x2e68 +#define R_0x2e6c 0x2e6c +#define R_0x2e70 0x2e70 +#define R_0x2e74 0x2e74 +#define R_0x2e78 0x2e78 +#define R_0x2e7c 0x2e7c +#define R_0x2e80 0x2e80 #define R_0x300 0x300 #define R_0x38 0x38 #define R_0x3a00 0x3a00 @@ -419,12 +471,63 @@ #define R_0x42 0x42 #define R_0x430 0x430 #define R_0x434 0x434 +#define R_0x42b0 0x42b0 +#define R_0x42b4 0x42b4 +#define R_0x4300 0x4300 +#define R_0x4304 0x4304 +#define R_0x4308 0x4308 +#define R_0x430c 0x430c +#define R_0x4310 0x4310 +#define R_0x4314 0x4314 +#define R_0x4318 0x4318 +#define R_0x431c 0x431c +#define R_0x4320 0x4320 +#define R_0x4324 0x4324 +#define R_0x4328 0x4328 +#define R_0x432c 0x432c +#define R_0x4330 0x4330 +#define R_0x4334 0x4334 +#define R_0x4338 0x4338 +#define R_0x433c 0x433c +#define R_0x4340 0x4340 +#define R_0x4344 0x4344 +#define R_0x4348 0x4348 +#define R_0x434c 0x434c +#define R_0x4350 0x4350 +#define R_0x4354 0x4354 +#define R_0x4358 0x4358 +#define R_0x435c 0x435c +#define R_0x4360 0x4360 +#define R_0x4364 0x4364 +#define R_0x4368 0x4368 +#define R_0x436c 0x436c +#define R_0x4370 0x4370 +#define R_0x4374 0x4374 +#define R_0x4378 0x4378 +#define R_0x437c 0x437c +#define R_0x4380 0x4380 +#define R_0x4384 0x4384 +#define R_0x4388 0x4388 +#define R_0x438c 0x438c +#define R_0x4390 0x4390 +#define R_0x4394 0x4394 +#define R_0x4398 0x4398 +#define R_0x439c 0x439c +#define R_0x43a0 0x43a0 +#define R_0x43a4 0x43a4 +#define R_0x43a8 0x43a8 +#define R_0x43ac 0x43ac +#define R_0x43b0 0x43b0 +#define R_0x43b4 0x43b4 +#define R_0x43b8 0x43b8 #define R_0x44 0x44 #define R_0x440 0x440 #define R_0x444 0x444 #define R_0x448 0x448 #define R_0x450 0x450 #define R_0x454 0x454 +#define R_0x494 0x494 +#define R_0x498 0x498 #define R_0x49c 0x49c #define R_0x4a0 0x4a0 #define R_0x4a4 0x4a4 @@ -601,6 +704,7 @@ #define R_0x974 0x974 #define R_0x978 0x978 #define R_0x97c 0x97c +#define R_0x980 0x980 #define R_0x988 0x988 #define R_0x98c 0x98c #define R_0x990 0x990 @@ -615,6 +719,7 @@ #define R_0x9b8 0x9b8 #define R_0x9cc 0x9cc #define R_0x9d0 0x9d0 +#define R_0x9d8 0x9d8 #define R_0x9e4 0x9e4 #define R_0x9e8 0x9e8 #define R_0x9f0 0x9f0 @@ -651,6 +756,7 @@ #define R_0xaac 0xaac #define R_0xab4 0xab4 #define R_0xabc 0xabc +#define R_0xac 0xac #define R_0xac8 0xac8 #define R_0xacc 0xacc #define R_0xad0 0xad0 @@ -731,6 +837,7 @@ #define R_0xc24 0xc24 #define R_0xc2c 0xc2c #define R_0xc30 0xc30 +#define R_0xc34 0xc34 #define R_0xc38 0xc38 #define R_0xc3c 0xc3c #define R_0xc40 0xc40 @@ -799,6 +906,7 @@ #define R_0xdb4 0xdb4 #define R_0xdb8 0xdb8 #define R_0xdbc 0xdbc +#define R_0xdc 0xdc #define R_0xdcc 0xdcc #define R_0xdd0 0xdd0 #define R_0xdd4 0xdd4 @@ -871,6 +979,7 @@ #define R_0xf18 0xf18 #define R_0xf1c 0xf1c #define R_0xf20 0xf20 +#define R_0xf24 0xf24 #define R_0xf2c 0xf2c #define R_0xf30 0xf30 #define R_0xf34 0xf34 @@ -892,6 +1001,7 @@ #define R_0xf90 0xf90 #define R_0xf94 0xf94 #define R_0xf98 0xf98 +#define R_0xf9c 0xf9c #define R_0xfa0 0xfa0 #define R_0xfa4 0xfa4 #define R_0xfa8 0xfa8 @@ -909,6 +1019,7 @@ #define RF_0x0 0x0 #define RF_0x00 0x00 #define RF_0x08 0x08 +#define RF_0x09 0x09 #define RF_0x0c 0x0c #define RF_0x0d 0x0d #define RF_0x1 0x1 @@ -918,6 +1029,9 @@ #define RF_0x1bf0 0x1bf0 #define RF_0x2 0x2 #define RF_0x3 0x3 +#define RF_0x1e 0x1e +#define RF_0x1f 0x1f +#define RF_0x20 0x20 #define RF_0x30 0x30 #define RF_0x31 0x31 #define RF_0x32 0x32 @@ -928,6 +1042,7 @@ #define RF_0x4 0x4 #define RF_0x42 0x42 #define RF_0x43 0x43 +#define RF_0x5 0x5 #define RF_0x51 0x51 #define RF_0x52 0x52 #define RF_0x53 0x53 @@ -938,12 +1053,14 @@ #define RF_0x58 0x58 #define RF_0x5c 0x5c #define RF_0x5d 0x5d +#define RF_0x60 0x60 #define RF_0x61 0x61 #define RF_0x63 0x63 #define RF_0x64 0x64 #define RF_0x65 0x65 #define RF_0x66 0x66 #define RF_0x67 0x67 +#define RF_0x6d 0x6d #define RF_0x6e 0x6e #define RF_0x6f 0x6f #define RF_0x75 0x75 @@ -960,11 +1077,14 @@ #define RF_0x86 0x86 #define RF_0x87 0x87 #define RF_0x8a 0x8a +#define RF_0x8b 0x8b #define RF_0x8c 0x8c #define RF_0x8d 0x8d #define RF_0x8f 0x8f #define RF_0x93 0x93 #define RF_0x9e 0x9e +#define RF_0x9f 0x9f +#define RF_0xa3 0xa3 #define RF_0xa9 0xa9 #define RF_0xae 0xae #define RF_0xb0 0xb0 @@ -974,6 +1094,7 @@ #define RF_0xbc 0xbc #define RF_0xbe 0xbe #define RF_0xc4 0xc4 +#define RF_0xc8 0xc8 #define RF_0xc9 0xc9 #define RF_0xca 0xca #define RF_0xcc 0xcc diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rssi_monitor.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rssi_monitor.c index f260daa99ca3..da93ad84b0e3 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rssi_monitor.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rssi_monitor.c @@ -81,7 +81,7 @@ void phydm_rssi_monitor_h2c(void *dm_void, u8 macid) h2c[4] = (ra_t->ra_th_ofst & 0x7f) | ((ra_t->ra_ofst_direc & 0x1) << 7); h2c[5] = 0; - h2c[6] = 0; + h2c[6] = ((ra_t->ra_trigger_mode) << 2); PHYDM_DBG(dm, DBG_RSSI_MNTR, "PHYDM h2c[0x42]=0x%x %x %x %x %x %x %x\n", h2c[6], h2c[5], h2c[4], h2c[3], h2c[2], h2c[1], h2c[0]); @@ -96,6 +96,22 @@ void phydm_rssi_monitor_h2c(void *dm_void, u8 macid) } } +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +void phydm_sta_rssi_init(void *dm_void, u8 macid, u8 init_rssi) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + struct cmn_sta_info *sta = NULL; + struct rssi_info *rssi_t = NULL; + + PHYDM_DBG(dm, DBG_RSSI_MNTR, "%s ======>\n", __func__); + + sta = dm->phydm_sta_info[macid]; + rssi_t = &sta->rssi_stat; + + rssi_t->rssi_acc = (init_rssi << RSSI_MA); + rssi_t->rssi = init_rssi; +} +#endif void phydm_calculate_rssi_min_max(void *dm_void) { struct dm_struct *dm = (struct dm_struct *)dm_void; @@ -134,6 +150,10 @@ void phydm_calculate_rssi_min_max(void *dm_void) } dm->pre_rssi_min = dm->rssi_min; +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + if (dm->number_linked_client == 0) + return; +#endif dm->rssi_max = (u8)rssi_max_tmp; dm->rssi_min = (u8)rssi_min_tmp; } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rssi_monitor.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rssi_monitor.h index e7d7d2a48c72..0d28c76a9f3c 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rssi_monitor.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_rssi_monitor.h @@ -52,5 +52,8 @@ void phydm_rssi_monitor_check(void *dm_void); void phydm_rssi_monitor_init(void *dm_void); +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +void phydm_sta_rssi_init(void *dm_void, u8 macid, u8 init_rssi); +#endif #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_soml.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_soml.c index 687383683502..d3d16b471ac2 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_soml.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_soml.c @@ -313,6 +313,9 @@ void phydm_soml_debug(void *dm_void, char input[][16], u32 *_used, u32 dm_value[10] = {0}; u8 i = 0, input_idx = 0; + if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML)) + return; + for (i = 0; i < 5; i++) { if (input[i + 1]) { PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &dm_value[i]); @@ -561,10 +564,6 @@ void phydm_adsl_init_state(void *dm_void) } soml_tab->is_soml_method_enable = 1; - #if (DM_ODM_SUPPORT_TYPE == ODM_AP) - odm_set_mac_reg(dm, R_0x608, BIT(8), 1); - /*RCR accepts CRC32-Error packets*/ - #endif soml_tab->get_stats = false; soml_tab->soml_state_cnt++; next_on_off = (soml_tab->soml_on_off == SOML_ON) ? SOML_ON : SOML_OFF; @@ -680,10 +679,6 @@ void phydm_adsl_decision_state(void *dm_void) pr_debug("%s: mismatch IC type %x\n", __func__, dm->support_ic_type); soml_tab->get_stats = false; - #if (DM_ODM_SUPPORT_TYPE == ODM_AP) - odm_set_mac_reg(dm, R_0x608, BIT(8), 0); - /* NOT Accept CRC32 Error packets. */ - #endif PHYDM_DBG(dm, DBG_ADPTV_SOML, "[Decisoin state ]\n"); phydm_soml_statistics(dm, soml_tab->soml_on_off); if (*dm->channel <= 14) { @@ -1150,6 +1145,9 @@ void phydm_set_adsl_val(void *dm_void, u32 *val_buf, u8 val_len) { struct dm_struct *dm = (struct dm_struct *)dm_void; + if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML)) + return; + if (val_len != 1) { PHYDM_DBG(dm, ODM_COMP_API, "[Error][ADSL]Need val_len=1\n"); return; @@ -1164,6 +1162,9 @@ void phydm_soml_crc_acq(void *dm_void, u8 rate_id, boolean crc32, u32 length) struct adaptive_soml *soml_tab = &dm->dm_soml_table; u8 offset = 0; + if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML)) + return; + if (!soml_tab->get_stats) return; if (length < 1400) @@ -1208,6 +1209,8 @@ void phydm_soml_bytes_acq(void *dm_void, u8 rate_id, u32 length) struct adaptive_soml *soml_tab = &dm->dm_soml_table; u8 offset = 0; + if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML)) + return; if (rate_id >= ODM_RATEMCS0 && rate_id <= ODM_RATEMCS31) { offset = rate_id - ODM_RATEMCS0; @@ -1271,6 +1274,9 @@ void phydm_adaptive_soml_timers(void *dm_void, u8 state) struct dm_struct *dm = (struct dm_struct *)dm_void; struct adaptive_soml *soml_tab = &dm->dm_soml_table; + if (!(dm->support_ic_type & PHYDM_ADAPTIVE_SOML_IC)) + return; + #if defined(CONFIG_RTL_TRIBAND_SUPPORT) && defined(CONFIG_USB_HCI) struct rtl8192cd_priv *priv = dm->priv; @@ -1302,6 +1308,10 @@ void phydm_adaptive_soml_init(void *dm_void) return; } #endif + + if (!(dm->support_ic_type & PHYDM_ADAPTIVE_SOML_IC)) + return; + PHYDM_DBG(dm, DBG_ADPTV_SOML, "%s\n", __func__); soml_tab->soml_state_cnt = 0; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_types.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_types.h index 91c07fcabff3..a6ed8dacb338 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_types.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/phydm_types.h @@ -159,6 +159,46 @@ enum rt_spinlock_type { #define phydm_timer_list _RT_TIMER + // for power limit table + enum odm_pw_lmt_regulation_type { + PW_LMT_REGU_FCC = 0, + PW_LMT_REGU_ETSI = 1, + PW_LMT_REGU_MKK = 2, + PW_LMT_REGU_WW13 = 3, + PW_LMT_REGU_IC = 4, + PW_LMT_REGU_KCC = 5, + PW_LMT_REGU_ACMA = 6, + PW_LMT_REGU_CHILE = 7, + PW_LMT_REGU_UKRAINE = 8, + PW_LMT_REGU_MEXICO = 9, + PW_LMT_REGU_CN = 10 + }; + + enum odm_pw_lmt_band_type { + PW_LMT_BAND_2_4G = 0, + PW_LMT_BAND_5G = 1 + }; + + enum odm_pw_lmt_bandwidth_type { + PW_LMT_BW_20M = 0, + PW_LMT_BW_40M = 1, + PW_LMT_BW_80M = 2, + PW_LMT_BW_160M = 3 + }; + + enum odm_pw_lmt_ratesection_type { + PW_LMT_RS_CCK = 0, + PW_LMT_RS_OFDM = 1, + PW_LMT_RS_HT = 2, + PW_LMT_RS_VHT = 3 + }; + + enum odm_pw_lmt_rfpath_type { + PW_LMT_PH_1T = 0, + PW_LMT_PH_2T = 1, + PW_LMT_PH_3T = 2, + PW_LMT_PH_4T = 3 + }; #elif (DM_ODM_SUPPORT_TYPE == ODM_AP) #include "../typedef.h" @@ -254,6 +294,47 @@ enum rt_spinlock_type { #define phydm_timer_list rtw_timer_list + // for power limit table + enum odm_pw_lmt_regulation_type { + PW_LMT_REGU_FCC = 0, + PW_LMT_REGU_ETSI = 1, + PW_LMT_REGU_MKK = 2, + PW_LMT_REGU_WW13 = 3, + PW_LMT_REGU_IC = 4, + PW_LMT_REGU_KCC = 5, + PW_LMT_REGU_ACMA = 6, + PW_LMT_REGU_CHILE = 7, + PW_LMT_REGU_UKRAINE = 8, + PW_LMT_REGU_MEXICO = 9, + PW_LMT_REGU_CN = 10 + }; + + enum odm_pw_lmt_band_type { + PW_LMT_BAND_2_4G = 0, + PW_LMT_BAND_5G = 1 + }; + + enum odm_pw_lmt_bandwidth_type { + PW_LMT_BW_20M = 0, + PW_LMT_BW_40M = 1, + PW_LMT_BW_80M = 2, + PW_LMT_BW_160M = 3 + }; + + enum odm_pw_lmt_ratesection_type { + PW_LMT_RS_CCK = 0, + PW_LMT_RS_OFDM = 1, + PW_LMT_RS_HT = 2, + PW_LMT_RS_VHT = 3 + }; + + enum odm_pw_lmt_rfpath_type { + PW_LMT_PH_1T = 0, + PW_LMT_PH_2T = 1, + PW_LMT_PH_3T = 2, + PW_LMT_PH_4T = 3 + }; + #elif (DM_ODM_SUPPORT_TYPE == ODM_IOT) #define boolean bool #define true _TRUE diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_bb.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_bb.c index f45af64e0364..c55b7ee8bc61 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_bb.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_bb.c @@ -24,7 +24,7 @@ * *****************************************************************************/ -/*Image2HeaderVersion: R3 1.5.8*/ +/*Image2HeaderVersion: R3 1.5.10.1*/ #include "mp_precomp.h" #include "../phydm_precomp.h" @@ -241,6 +241,71 @@ const u32 array_mp_8821c_agc_tab[] = { 0x81C, 0x017A0003, 0x81C, 0x017C0003, 0x81C, 0x017E0003, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000003, + 0x81C, 0xFA020003, + 0x81C, 0xF9040003, + 0x81C, 0xF8060003, + 0x81C, 0xF7080003, + 0x81C, 0xF60A0003, + 0x81C, 0xF50C0003, + 0x81C, 0xF40E0003, + 0x81C, 0xF3100003, + 0x81C, 0xF2120003, + 0x81C, 0xF1140003, + 0x81C, 0xF0160003, + 0x81C, 0xEF180003, + 0x81C, 0xEE1A0003, + 0x81C, 0xED1C0003, + 0x81C, 0xEC1E0003, + 0x81C, 0xEB200003, + 0x81C, 0xEA220003, + 0x81C, 0xE9240003, + 0x81C, 0xE8260003, + 0x81C, 0xE7280003, + 0x81C, 0xE62A0003, + 0x81C, 0xCA2C0003, + 0x81C, 0xC92E0003, + 0x81C, 0xC8300003, + 0x81C, 0xC7320003, + 0x81C, 0xC6340003, + 0x81C, 0xC5360003, + 0x81C, 0xC4380003, + 0x81C, 0xC33A0003, + 0x81C, 0xC23C0003, + 0x81C, 0xC13E0003, + 0x81C, 0x88400003, + 0x81C, 0x87420003, + 0x81C, 0x86440003, + 0x81C, 0x85460003, + 0x81C, 0x84480003, + 0x81C, 0x834A0003, + 0x81C, 0x674C0003, + 0x81C, 0x664E0003, + 0x81C, 0x65500003, + 0x81C, 0x64520003, + 0x81C, 0x63540003, + 0x81C, 0x62560003, + 0x81C, 0x61580003, + 0x81C, 0x455A0003, + 0x81C, 0x445C0003, + 0x81C, 0x435E0003, + 0x81C, 0x42600003, + 0x81C, 0x41620003, + 0x81C, 0x25640003, + 0x81C, 0x24660003, + 0x81C, 0x23680003, + 0x81C, 0x226A0003, + 0x81C, 0x216C0003, + 0x81C, 0x016E0003, + 0x81C, 0x01700003, + 0x81C, 0x01720003, + 0x81C, 0x01740003, + 0x81C, 0x01760003, + 0x81C, 0x01780003, + 0x81C, 0x017A0003, + 0x81C, 0x017C0003, + 0x81C, 0x017E0003, 0xA0000000, 0x00000000, 0x81C, 0xFB000003, 0x81C, 0xFA020003, @@ -437,6 +502,71 @@ const u32 array_mp_8821c_agc_tab[] = { 0x81C, 0x007A0103, 0x81C, 0x007C0103, 0x81C, 0x007E0103, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000103, + 0x81C, 0xFC020103, + 0x81C, 0xFB040103, + 0x81C, 0xFA060103, + 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, + 0x81C, 0xF70C0103, + 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, + 0x81C, 0xF4120103, + 0x81C, 0xF3140103, + 0x81C, 0xF2160103, + 0x81C, 0xF1180103, + 0x81C, 0xF01A0103, + 0x81C, 0xEF1C0103, + 0x81C, 0xEE1E0103, + 0x81C, 0xED200103, + 0x81C, 0xEC220103, + 0x81C, 0xEB240103, + 0x81C, 0xEA260103, + 0x81C, 0xE9280103, + 0x81C, 0xE82A0103, + 0x81C, 0xE72C0103, + 0x81C, 0xE62E0103, + 0x81C, 0xE5300103, + 0x81C, 0xE4320103, + 0x81C, 0xE3340103, + 0x81C, 0xE2360103, + 0x81C, 0xE1380103, + 0x81C, 0xE03A0103, + 0x81C, 0xA83C0103, + 0x81C, 0xA73E0103, + 0x81C, 0xA6400103, + 0x81C, 0xA5420103, + 0x81C, 0xA4440103, + 0x81C, 0xA3460103, + 0x81C, 0xA2480103, + 0x81C, 0xA14A0103, + 0x81C, 0x834C0103, + 0x81C, 0x824E0103, + 0x81C, 0x81500103, + 0x81C, 0x63520103, + 0x81C, 0x62540103, + 0x81C, 0x61560103, + 0x81C, 0x25580103, + 0x81C, 0x245A0103, + 0x81C, 0x235C0103, + 0x81C, 0x225E0103, + 0x81C, 0x04600103, + 0x81C, 0x03620103, + 0x81C, 0x02640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, 0xA0000000, 0x00000000, 0x81C, 0xFD000103, 0x81C, 0xFC020103, @@ -633,6 +763,71 @@ const u32 array_mp_8821c_agc_tab[] = { 0x81C, 0x007A0203, 0x81C, 0x007C0203, 0x81C, 0x007E0203, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, + 0x81C, 0xED1E0203, + 0x81C, 0xEC200203, + 0x81C, 0xEB220203, + 0x81C, 0xEA240203, + 0x81C, 0xE9260203, + 0x81C, 0xE8280203, + 0x81C, 0xE72A0203, + 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, + 0x81C, 0xE4300203, + 0x81C, 0xE3320203, + 0x81C, 0xE2340203, + 0x81C, 0xE1360203, + 0x81C, 0xC5380203, + 0x81C, 0xC43A0203, + 0x81C, 0xC33C0203, + 0x81C, 0xC23E0203, + 0x81C, 0xA6400203, + 0x81C, 0xA5420203, + 0x81C, 0xA4440203, + 0x81C, 0xA3460203, + 0x81C, 0xA2480203, + 0x81C, 0x844A0203, + 0x81C, 0x834C0203, + 0x81C, 0x824E0203, + 0x81C, 0x64500203, + 0x81C, 0x63520203, + 0x81C, 0x62540203, + 0x81C, 0x61560203, + 0x81C, 0x60580203, + 0x81C, 0x235A0203, + 0x81C, 0x225C0203, + 0x81C, 0x215E0203, + 0x81C, 0x04600203, + 0x81C, 0x03620203, + 0x81C, 0x02640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, 0xA0000000, 0x00000000, 0x81C, 0xFC000203, 0x81C, 0xFB020203, @@ -829,6 +1024,71 @@ const u32 array_mp_8821c_agc_tab[] = { 0x81C, 0x007A0303, 0x81C, 0x007C0303, 0x81C, 0x007E0303, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000303, + 0x81C, 0xFB020303, + 0x81C, 0xFA040303, + 0x81C, 0xF9060303, + 0x81C, 0xF8080303, + 0x81C, 0xF70A0303, + 0x81C, 0xF60C0303, + 0x81C, 0xF50E0303, + 0x81C, 0xF4100303, + 0x81C, 0xF3120303, + 0x81C, 0xF2140303, + 0x81C, 0xF1160303, + 0x81C, 0xF0180303, + 0x81C, 0xEF1A0303, + 0x81C, 0xEE1C0303, + 0x81C, 0xED1E0303, + 0x81C, 0xEC200303, + 0x81C, 0xEB220303, + 0x81C, 0xEA240303, + 0x81C, 0xE9260303, + 0x81C, 0xE8280303, + 0x81C, 0xE72A0303, + 0x81C, 0xE62C0303, + 0x81C, 0xE52E0303, + 0x81C, 0xE4300303, + 0x81C, 0xE3320303, + 0x81C, 0xE2340303, + 0x81C, 0xE1360303, + 0x81C, 0xE0380303, + 0x81C, 0xC53A0303, + 0x81C, 0xC43C0303, + 0x81C, 0xC33E0303, + 0x81C, 0xA5400303, + 0x81C, 0xA4420303, + 0x81C, 0xA3440303, + 0x81C, 0xA2460303, + 0x81C, 0xA1480303, + 0x81C, 0x834A0303, + 0x81C, 0x824C0303, + 0x81C, 0x814E0303, + 0x81C, 0x64500303, + 0x81C, 0x63520303, + 0x81C, 0x62540303, + 0x81C, 0x61560303, + 0x81C, 0x24580303, + 0x81C, 0x235A0303, + 0x81C, 0x225C0303, + 0x81C, 0x215E0303, + 0x81C, 0x04600303, + 0x81C, 0x03620303, + 0x81C, 0x02640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, 0xA0000000, 0x00000000, 0x81C, 0xFC000303, 0x81C, 0xFB020303, @@ -1025,6 +1285,71 @@ const u32 array_mp_8821c_agc_tab[] = { 0x81C, 0x017A0803, 0x81C, 0x017C0803, 0x81C, 0x017E0803, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000803, + 0x81C, 0xFB020803, + 0x81C, 0xFA040803, + 0x81C, 0xF9060803, + 0x81C, 0xF8080803, + 0x81C, 0xF70A0803, + 0x81C, 0xF60C0803, + 0x81C, 0xF50E0803, + 0x81C, 0xF4100803, + 0x81C, 0xF3120803, + 0x81C, 0xF2140803, + 0x81C, 0xF1160803, + 0x81C, 0xF0180803, + 0x81C, 0xEF1A0803, + 0x81C, 0xEE1C0803, + 0x81C, 0xED1E0803, + 0x81C, 0xB5200803, + 0x81C, 0xB4220803, + 0x81C, 0xB3240803, + 0x81C, 0xB2260803, + 0x81C, 0xB1280803, + 0x81C, 0xB02A0803, + 0x81C, 0xAF2C0803, + 0x81C, 0xAE2E0803, + 0x81C, 0xAD300803, + 0x81C, 0xAC320803, + 0x81C, 0xAB340803, + 0x81C, 0xAA360803, + 0x81C, 0xA9380803, + 0x81C, 0xA83A0803, + 0x81C, 0xA73C0803, + 0x81C, 0xA63E0803, + 0x81C, 0x88400803, + 0x81C, 0x87420803, + 0x81C, 0x86440803, + 0x81C, 0x85460803, + 0x81C, 0x84480803, + 0x81C, 0x834A0803, + 0x81C, 0x674C0803, + 0x81C, 0x664E0803, + 0x81C, 0x65500803, + 0x81C, 0x64520803, + 0x81C, 0x63540803, + 0x81C, 0x62560803, + 0x81C, 0x61580803, + 0x81C, 0x455A0803, + 0x81C, 0x445C0803, + 0x81C, 0x435E0803, + 0x81C, 0x42600803, + 0x81C, 0x41620803, + 0x81C, 0x25640803, + 0x81C, 0x24660803, + 0x81C, 0x23680803, + 0x81C, 0x226A0803, + 0x81C, 0x216C0803, + 0x81C, 0x016E0803, + 0x81C, 0x01700803, + 0x81C, 0x01720803, + 0x81C, 0x01740803, + 0x81C, 0x01760803, + 0x81C, 0x01780803, + 0x81C, 0x017A0803, + 0x81C, 0x017C0803, + 0x81C, 0x017E0803, 0xA0000000, 0x00000000, 0x81C, 0xFC000803, 0x81C, 0xFB020803, @@ -1221,6 +1546,71 @@ const u32 array_mp_8821c_agc_tab[] = { 0x81C, 0x017A0903, 0x81C, 0x017C0903, 0x81C, 0x017E0903, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000913, + 0x81C, 0xFE020913, + 0x81C, 0xFD040913, + 0x81C, 0xFC060913, + 0x81C, 0xFB080913, + 0x81C, 0xFA0A0913, + 0x81C, 0xF90C0913, + 0x81C, 0xF80E0913, + 0x81C, 0xF7100913, + 0x81C, 0xF6120913, + 0x81C, 0xF5140913, + 0x81C, 0xF4160913, + 0x81C, 0xF3180913, + 0x81C, 0xF21A0913, + 0x81C, 0xF11C0913, + 0x81C, 0x941E0913, + 0x81C, 0x93200913, + 0x81C, 0x92220913, + 0x81C, 0x91240913, + 0x81C, 0x90260913, + 0x81C, 0x8F280913, + 0x81C, 0x8E2A0913, + 0x81C, 0x8D2C0913, + 0x81C, 0x8C2E0913, + 0x81C, 0x8B300913, + 0x81C, 0x8A320913, + 0x81C, 0x89340913, + 0x81C, 0x88360913, + 0x81C, 0x87380913, + 0x81C, 0x863A0913, + 0x81C, 0x853C0913, + 0x81C, 0x843E0913, + 0x81C, 0x83400913, + 0x81C, 0x82420913, + 0x81C, 0x81440913, + 0x81C, 0x07460913, + 0x81C, 0x06480913, + 0x81C, 0x054A0913, + 0x81C, 0x044C0913, + 0x81C, 0x034E0913, + 0x81C, 0x02500913, + 0x81C, 0x01520913, + 0x81C, 0x88540903, + 0x81C, 0x87560903, + 0x81C, 0x86580903, + 0x81C, 0x855A0903, + 0x81C, 0x845C0903, + 0x81C, 0x835E0903, + 0x81C, 0x82600903, + 0x81C, 0x81620903, + 0x81C, 0x07640903, + 0x81C, 0x06660903, + 0x81C, 0x05680903, + 0x81C, 0x046A0903, + 0x81C, 0x036C0903, + 0x81C, 0x026E0903, + 0x81C, 0x01700903, + 0x81C, 0x01720903, + 0x81C, 0x01740903, + 0x81C, 0x01760903, + 0x81C, 0x01780903, + 0x81C, 0x017A0903, + 0x81C, 0x017C0903, + 0x81C, 0x017E0903, 0xA0000000, 0x00000000, 0x81C, 0xFF000913, 0x81C, 0xFE020913, @@ -1292,7 +1682,10 @@ const u32 array_mp_8821c_agc_tab[] = { 0xC50, 0x00000020, 0x90001005, 0x00000000, 0x40000000, 0x00000000, 0xC50, 0x00000022, + 0xC50, 0x00000020, + 0x90000400, 0x00000000, 0x40000000, 0x00000000, 0xC50, 0x00000022, + 0xC50, 0x00000020, 0xA0000000, 0x00000000, 0xC50, 0x00000022, 0xC50, 0x00000020, @@ -1363,7 +1756,7 @@ odm_read_and_config_mp_8821c_agc_tab(struct dm_struct *dm) u32 odm_get_version_mp_8821c_agc_tab(void) { - return 57; + return 62; } /****************************************************************************** @@ -2214,7 +2607,7 @@ odm_read_and_config_mp_8821c_agc_tab_diff(struct dm_struct *dm, u32 odm_get_version_mp_8821c_agc_tab_diff(void) { - return 57; + return 62; } /****************************************************************************** @@ -2353,7 +2746,7 @@ const u32 array_mp_8821c_phy_reg[] = { 0x9F0, 0x00000000, 0x9F4, 0x00000000, 0x9F8, 0x00000000, - 0x9FC, 0xEFFFF7FF, + 0x9FC, 0xEFFFE7FF, 0xA00, 0x00D040C8, 0xA04, 0x80FF800C, 0xA08, 0x9C838300, @@ -2462,10 +2855,8 @@ const u32 array_mp_8821c_phy_reg[] = { 0xCAC, 0x00000000, 0x80001005, 0x00000000, 0x40000000, 0x00000000, 0xCB0, 0x77777717, - 0xCB4, 0x00000073, 0xA0000000, 0x00000000, 0xCB0, 0x77775747, - 0xCB4, 0x10000077, 0xB0000000, 0x00000000, 0xCB8, 0x00000000, 0xCBC, 0x00000000, @@ -3966,7 +4357,7 @@ odm_read_and_config_mp_8821c_phy_reg(struct dm_struct *dm) u32 odm_get_version_mp_8821c_phy_reg(void) { - return 57; + return 62; } /****************************************************************************** @@ -4042,7 +4433,7 @@ odm_read_and_config_mp_8821c_phy_reg_mp(struct dm_struct *dm) u32 odm_get_version_mp_8821c_phy_reg_mp(void) { - return 57; + return 62; } /****************************************************************************** diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_bb.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_bb.h index 72dddf074a4b..f3439f8cbf8e 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_bb.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_bb.h @@ -24,7 +24,7 @@ * *****************************************************************************/ -/*Image2HeaderVersion: R3 1.5.8*/ +/*Image2HeaderVersion: R3 1.5.10.1*/ #if (RTL8821C_SUPPORT == 1) #ifndef __INC_MP_BB_HW_IMG_8821C_H #define __INC_MP_BB_HW_IMG_8821C_H diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_mac.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_mac.c index db21fe61ec98..91fbc6798880 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_mac.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_mac.c @@ -24,7 +24,7 @@ * *****************************************************************************/ -/*Image2HeaderVersion: R3 1.5.8*/ +/*Image2HeaderVersion: R3 1.5.10.1*/ #include "mp_precomp.h" #include "../phydm_precomp.h" @@ -315,7 +315,7 @@ odm_read_and_config_mp_8821c_mac_reg(struct dm_struct *dm) u32 odm_get_version_mp_8821c_mac_reg(void) { - return 57; + return 62; } #endif /* end of HWIMG_SUPPORT*/ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_mac.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_mac.h index 29a9a3b773a6..718a8813b676 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_mac.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/halhwimg8821c_mac.h @@ -24,7 +24,7 @@ * *****************************************************************************/ -/*Image2HeaderVersion: R3 1.5.8*/ +/*Image2HeaderVersion: R3 1.5.10.1*/ #if (RTL8821C_SUPPORT == 1) #ifndef __INC_MP_MAC_HW_IMG_8821C_H #define __INC_MP_MAC_HW_IMG_8821C_H diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_hal_api8821c.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_hal_api8821c.c index 6b4a4247a330..197cffc7d116 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_hal_api8821c.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_hal_api8821c.c @@ -364,6 +364,14 @@ void phydm_init_hw_info_by_rfe_type_8821c(struct dm_struct *dm) else dm->default_ant_num_8821c = SWITCH_TO_ANT1; + if (dm->package_type == 1 && dm->rfe_type_expand <= 0x2f && + dm->rfe_type_expand >= 0x28) + odm_set_bb_reg(dm, R_0xcb4, MASKDWORD, 0x00000073); + else if (dm->rfe_type_expand == 4) + odm_set_bb_reg(dm, R_0xcb4, MASKDWORD, 0x20000077); + else + odm_set_bb_reg(dm, R_0xcb4, MASKDWORD, 0x10000077); + dm->is_init_hw_info_by_rfe = true; PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s: RFE type (%d), rf set (%s)\n", __FUNCTION__, dm->rfe_type_expand, diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_regconfig8821c.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_regconfig8821c.c index eeeb0400ebcc..70f41f4f25fb 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_regconfig8821c.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_regconfig8821c.c @@ -233,6 +233,20 @@ void odm_config_bb_phy_8821c(struct dm_struct *dm, u32 addr, u32 bitmask, addr, data); } +void odm_config_bb_txpwr_lmt_8821c_ex(struct dm_struct *dm, u8 regulation, + u8 band, u8 bandwidth, u8 rate_section, + u8 rf_path, u8 channel, s8 power_limit) +{ + +#if (DM_ODM_SUPPORT_TYPE & ODM_CE) + phy_set_tx_power_limit_ex(dm, regulation, band, bandwidth, rate_section, + rf_path, channel, power_limit); +#endif +#if 0 + PHY_SetTxPowerLimit_ex(dm, regulation, band, bandwidth, rate_section, + rf_path, channel, power_limit); +#endif +} void odm_config_bb_txpwr_lmt_8821c(struct dm_struct *dm, u8 *regulation, u8 *band, u8 *bandwidth, u8 *rate_section, u8 *rf_path, u8 *channel, u8 *power_limit) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_regconfig8821c.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_regconfig8821c.h index de60f93bbac3..0c403d9bb373 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_regconfig8821c.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_regconfig8821c.h @@ -43,9 +43,13 @@ void odm_config_bb_phy_reg_pg_8821c(struct dm_struct *dm, u32 band, u32 rf_path, void odm_config_bb_phy_8821c(struct dm_struct *dm, u32 addr, u32 bitmask, u32 data); +void odm_config_bb_txpwr_lmt_8821c_ex(struct dm_struct *dm, u8 regulation, + u8 band, u8 bandwidth, u8 rate_section, + u8 rf_path, u8 channel, s8 power_limit); + void odm_config_bb_txpwr_lmt_8821c(struct dm_struct *dm, u8 *regulation, u8 *band, u8 *bandwidth, u8 *rate_section, u8 *rf_path, u8 *channel, u8 *power_limit); #endif -#endif /* RTL8822B_SUPPORT == 1*/ +#endif /* RTL8821C_SUPPORT == 1*/ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_rtl8821c.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_rtl8821c.c new file mode 100644 index 000000000000..76359e37d4be --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_rtl8821c.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#include "mp_precomp.h" +#include "../phydm_precomp.h" + +#if (RTL8821C_SUPPORT) +void phydm_dynamic_switch_htstf_agc_8821c(struct dm_struct *dm) +{ + u16 ndp_valid_cnt = 0; + + if (dm->bhtstfdisabled) + return; + + /*This count will be reset every 2 seconds*/ + ndp_valid_cnt = (u16)odm_get_bb_reg(dm, R_0xf24, MASKLWORD); + + if (dm->total_tp == 0 || ndp_valid_cnt != 0) { + odm_set_bb_reg(dm, R_0x8d8, BIT(17), 0x1); + dm->no_ndp_cnts = 0; + } else { + dm->no_ndp_cnts++; + + if (dm->no_ndp_cnts == 3) { + odm_set_bb_reg(dm, R_0x8d8, BIT(17), 0x0); + dm->no_ndp_cnts = 0; + } + } + dm->ndp_cnt_pre = ndp_valid_cnt; +} + +void phydm_hwsetting_8821c(struct dm_struct *dm) +{ + /*phydm_dynamic_switch_htstf_agc_8821c(dm);*/ +} +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_rtl8821c.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_rtl8821c.h new file mode 100644 index 000000000000..373f88be5a91 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/phydm_rtl8821c.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#if (RTL8821C_SUPPORT) +#ifndef __ODM_RTL8821C_H__ +#define __ODM_RTL8821C_H__ + +void phydm_hwsetting_8821c(struct dm_struct *dm); +#endif +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/version_rtl8821c.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/version_rtl8821c.h index c2a970b5ae34..8c4a6258e2ec 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/version_rtl8821c.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/rtl8821c/version_rtl8821c.h @@ -30,6 +30,6 @@ You do not need to fill up the version.h anymore, only the maintenance supervisor fills it before formal release. */ -#define RELEASE_DATE_8821C 20191008 -#define COMMIT_BY_8821C "Coiln" -#define RELEASE_VERSION_8821C 57 +#define RELEASE_DATE_8821C 20200908 +#define COMMIT_BY_8821C "WeiChi" +#define RELEASE_VERSION_8821C 62 diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/sd4_phydm_2_kernel.mk b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/sd4_phydm_2_kernel.mk index 324d0ee12cad..f11c6ac90bf5 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/sd4_phydm_2_kernel.mk +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/sd4_phydm_2_kernel.mk @@ -1,4 +1,3 @@ -# SPDX-License-Identifier: GPL-2.0 EXTRA_CFLAGS += -I$(src)/hal/phydm _PHYDM_FILES := hal/phydm/phydm_debug.o \ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/txbf/phydm_hal_txbf_api.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/txbf/phydm_hal_txbf_api.c index e56c88c9e055..a6cb1e1b7f29 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/txbf/phydm_hal_txbf_api.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/txbf/phydm_hal_txbf_api.c @@ -18,7 +18,7 @@ #include "phydm_precomp.h" #if (defined(CONFIG_BB_TXBF_API)) -#if (RTL8822B_SUPPORT == 1 || RTL8192F_SUPPORT == 1 ||\ +#if (RTL8822B_SUPPORT == 1 || RTL8192F_SUPPORT == 1 || RTL8812F_SUPPORT == 1 ||\ RTL8822C_SUPPORT == 1 || RTL8198F_SUPPORT == 1 || RTL8814B_SUPPORT == 1) /*@Add by YuChen for 8822B MU-MIMO API*/ @@ -122,7 +122,6 @@ u8 beamforming_get_htndp_tx_rate(void *dm_void, u8 bfer_str_num) if (dm->support_ic_type & ODM_RTL8814A) nr_index = tx_bf_nr(hal_txbf_8814a_get_ntx(dm), bfer_str_num); else -#endif nr_index = tx_bf_nr(1, bfer_str_num); switch (nr_index) { @@ -142,6 +141,9 @@ u8 beamforming_get_htndp_tx_rate(void *dm_void, u8 bfer_str_num) ndp_tx_rate = ODM_MGN_MCS8; break; } +#else + ndp_tx_rate = ODM_MGN_MCS8; +#endif return ndp_tx_rate; } @@ -156,7 +158,6 @@ u8 beamforming_get_vht_ndp_tx_rate(void *dm_void, u8 bfer_str_num) if (dm->support_ic_type & ODM_RTL8814A) nr_index = tx_bf_nr(hal_txbf_8814a_get_ntx(dm), bfer_str_num); else -#endif nr_index = tx_bf_nr(1, bfer_str_num); switch (nr_index) { @@ -176,6 +177,9 @@ u8 beamforming_get_vht_ndp_tx_rate(void *dm_void, u8 bfer_str_num) ndp_tx_rate = ODM_MGN_VHT2SS_MCS0; break; } +#else + ndp_tx_rate = ODM_MGN_VHT2SS_MCS0; +#endif return ndp_tx_rate; } @@ -339,16 +343,16 @@ void phydm_txbf_rfmode(void *dm_void, u8 su_bfee_cnt, u8 mu_bfee_cnt) /* logic mapping */ /* TX BF logic map and TX path en for Nsts = 1~4 */ - odm_set_bb_reg(dm, R_0x820, 0xffff0000, 0xffff); + //odm_set_bb_reg(dm, R_0x820, 0xffff0000, 0xffff); /*verification path-AC*/ - odm_set_bb_reg(dm, R_0x1e30, 0xffffffff, 0xe4e4e4e4); + //odm_set_bb_reg(dm, R_0x1e30, 0xffffffff, 0xe4e4e4e4); } else { /*@Disable BB TxBF ant mapping register*/ odm_set_bb_reg(dm, R_0x1e24, BIT(28) | BIT29, 0x0); odm_set_bb_reg(dm, R_0x1e24, BIT(31), 0); /*@1SS~4ss A, AB, ABC, ABCD*/ - odm_set_bb_reg(dm, R_0x820, 0xffff, 0xf731); - odm_set_bb_reg(dm, R_0x1e2c, 0xffffffff, 0xe4240400); + //odm_set_bb_reg(dm, R_0x820, 0xffff, 0xf731); + //odm_set_bb_reg(dm, R_0x1e2c, 0xffffffff, 0xe4240400); } } #endif @@ -575,13 +579,6 @@ void phydm_mu_rsoml_decision(void *dm_void) phydm_mu_rsoml_reset(dm); } -void phydm_txbf_avoid_hang(void *dm_void) -{ - struct dm_struct *dm = (struct dm_struct *)dm_void; - - /* avoid CCK CCA hang when the BF mode */ - odm_set_bb_reg(dm, R_0x1e6c, 0x100000, 0x1); -} #if (RTL8814B_SUPPORT == 1) void phydm_txbf_80p80_rfmode(void *dm_void, u8 su_bfee_cnt, u8 mu_bfee_cnt) @@ -669,6 +666,21 @@ void phydm_txbf_80p80_rfmode(void *dm_void, u8 su_bfee_cnt, u8 mu_bfee_cnt) #endif #endif /*PHYSTS_3RD_TYPE_IC*/ +void phydm_txbf_avoid_hang(void *dm_void) +{ + struct dm_struct *dm = (struct dm_struct *)dm_void; + + /* avoid CCK CCA hang when the BF mode */ +#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT + odm_set_bb_reg(dm, R_0x1e6c, 0x100000, 0x1); +#endif + + /* avoid CCK CCA hang when the BFee mode for 92F */ +#if (RTL8192F_SUPPORT == 1) + odm_set_bb_reg(dm, R_0xa70, 0xffff0000, 0x80ff); +#endif +} + void phydm_bf_debug(void *dm_void, char input[][16], u32 *_used, char *output, u32 *_out_len) { @@ -687,8 +699,7 @@ void phydm_bf_debug(void *dm_void, char input[][16], u32 *_used, char *output, return; } for (i = 0; i < 3; i++) { - if (input[i + 1]) - PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); } if (var1[0] == 0) { #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/txbf/phydm_hal_txbf_api.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/txbf/phydm_hal_txbf_api.h index 8e95bc81d4dd..2f53bf028dc4 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/txbf/phydm_hal_txbf_api.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/phydm/txbf/phydm_hal_txbf_api.h @@ -45,8 +45,7 @@ u8 beamforming_get_vht_ndp_tx_rate(void *dm_void, u8 bfer_str_num); #endif #if (RTL8822B_SUPPORT == 1 || RTL8822C_SUPPORT == 1 || RTL8192F_SUPPORT == 1 ||\ - RTL8814B_SUPPORT == 1 || RTL8198F_SUPPORT == 1) - + RTL8814B_SUPPORT == 1 || RTL8198F_SUPPORT == 1 || RTL8812F_SUPPORT == 1) u8 phydm_get_beamforming_sounding_info(void *dm_void, u16 *throughput, u8 total_bfee_num, u8 *tx_rate); u8 phydm_get_ndpa_rate(void *dm_void); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c.h index 90a28b27688f..dc4ba62fcf4f 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c.h @@ -86,8 +86,13 @@ void rtl8821c_query_rx_desc(union recv_frame *, u8 *pdesc); /* rtl8821c_cmd.c */ s32 rtl8821c_fillh2ccmd(PADAPTER, u8 id, u32 buf_len, u8 *pbuf); -void rtl8821c_set_FwPwrMode_cmd(PADAPTER, u8 psmode); +void _rtl8821c_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode, u8 rfon_ctrl); +void rtl8821c_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode); +void rtl8821c_set_FwPwrMode_rfon_ctrl_cmd(PADAPTER adapter, u8 rfon_ctrl); void rtl8821c_set_FwPwrModeInIPS_cmd(PADAPTER adapter, u8 cmd_param); +#ifdef CONFIG_WOWLAN +void rtl8821c_set_fw_pwrmode_inips_cmd_wowlan(PADAPTER padapter, u8 ps_mode); +#endif /* CONFIG_WOWLAN */ void c2h_handler_rtl8821c(_adapter *adapter, u8 *pbuf, u16 length); void c2h_pre_handler_rtl8821c(_adapter *adapter, u8 *pbuf, s32 length); #ifdef CONFIG_BT_COEXIST diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_cmd.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_cmd.c index 473262da7641..02c8fcace8e5 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_cmd.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_cmd.c @@ -82,7 +82,7 @@ exit: #define SET_PWR_MODE_SET_ADOPT_BCN_RECEIVING_TIME(h2c_pkt, value) \ SET_BITS_TO_LE_4BYTE(h2c_pkt + 0X04, 31, 1, value) -void rtl8821c_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode) +void _rtl8821c_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode, u8 rfon_ctrl) { u8 mode = 0, smart_ps = 0; struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); @@ -103,12 +103,14 @@ void rtl8821c_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode) #endif /* CONFIG_P2P */ u8 hw_port = rtw_hal_get_port(adapter); - if (pwrpriv->dtim > 0) - RTW_INFO(FUNC_ADPT_FMT ": dtim=%d, HW port id=%d\n", FUNC_ADPT_ARG(adapter), - pwrpriv->dtim, psmode == PS_MODE_ACTIVE ? pwrpriv->current_lps_hw_port_id : hw_port); - else - RTW_INFO(FUNC_ADPT_FMT ": HW port id=%d\n", FUNC_ADPT_ARG(adapter), - psmode == PS_MODE_ACTIVE ? pwrpriv->current_lps_hw_port_id : hw_port); + if (pwrpriv->pwr_mode != psmode) { + if (pwrpriv->dtim > 0) + RTW_INFO(FUNC_ADPT_FMT ": dtim=%d, HW port id=%d\n", FUNC_ADPT_ARG(adapter), + pwrpriv->dtim, psmode == PS_MODE_ACTIVE ? pwrpriv->current_lps_hw_port_id : hw_port); + else + RTW_INFO(FUNC_ADPT_FMT ": HW port id=%d\n", FUNC_ADPT_ARG(adapter), + psmode == PS_MODE_ACTIVE ? pwrpriv->current_lps_hw_port_id : hw_port); + } smart_ps = pwrpriv->smart_ps; switch (psmode) { @@ -181,21 +183,30 @@ void rtl8821c_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode) PowerState = rtw_btcoex_RpwmVal(adapter); else #endif /* CONFIG_BT_COEXIST */ - PowerState = 0x00; /* AllON(0x0C), RFON(0x04), RFOFF(0x00) */ + { + if (rfon_ctrl == rf_on) + PowerState = 0x04; /* AllON(0x0C), RFON(0x04), RFOFF(0x00) */ + else + PowerState = 0x00; /* AllON(0x0C), RFON(0x04), RFOFF(0x00) */ + } } else PowerState = 0x0C; /* AllON(0x0C), RFON(0x04), RFOFF(0x00) */ - if (mode == 0) - fw_psmode_str = "ACTIVE"; - else if (mode == 1) - fw_psmode_str = "LPS"; - else if (mode == 2) - fw_psmode_str = "WMMPS"; - else - fw_psmode_str = "UNSPECIFIED"; + if (pwrpriv->pwr_mode != psmode) { + if (mode == 0) + fw_psmode_str = "ACTIVE"; + else if (mode == 1) + fw_psmode_str = "LPS"; + else if (mode == 2) + fw_psmode_str = "WMMPS"; + else + fw_psmode_str = "UNSPECIFIED"; - RTW_INFO(FUNC_ADPT_FMT": fw ps mode = %s, drv ps mode = %d, rlbm = %d , smart_ps = %d, allQueueUAPSD = %d\n", - FUNC_ADPT_ARG(adapter), fw_psmode_str, psmode, rlbm, smart_ps, allQueueUAPSD); + RTW_INFO(FUNC_ADPT_FMT": fw ps mode = %s, drv ps mode = %d, rlbm = %d ," + "smart_ps = %d, allQueueUAPSD = %d, PowerState = %d\n", + FUNC_ADPT_ARG(adapter), fw_psmode_str, psmode, rlbm, smart_ps, + allQueueUAPSD, PowerState); + } SET_PWR_MODE_SET_CMD_ID(h2c, CMD_ID_SET_PWR_MODE); SET_PWR_MODE_SET_CLASS(h2c, CLASS_SET_PWR_MODE); @@ -237,6 +248,18 @@ void rtl8821c_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode) rtw_halmac_send_h2c(adapter_to_dvobj(adapter), h2c); } +void rtl8821c_set_FwPwrMode_cmd(PADAPTER adapter, u8 psmode) +{ + return _rtl8821c_set_FwPwrMode_cmd(adapter, psmode, rf_off); +} + +void rtl8821c_set_FwPwrMode_rfon_ctrl_cmd(PADAPTER adapter, u8 rfon_ctrl) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + + return _rtl8821c_set_FwPwrMode_cmd(adapter, pwrpriv->power_mgnt, rfon_ctrl); +} + void rtl8821c_set_FwPwrModeInIPS_cmd(PADAPTER adapter, u8 cmd_param) { u8 h2c[RTW_HALMAC_H2C_MAX_SIZE] = {0}; @@ -253,6 +276,33 @@ void rtl8821c_set_FwPwrModeInIPS_cmd(PADAPTER adapter, u8 cmd_param) rtw_halmac_send_h2c(adapter_to_dvobj(adapter), h2c); } +#ifdef CONFIG_WOWLAN +void rtl8821c_set_fw_pwrmode_inips_cmd_wowlan(PADAPTER padapter, u8 ps_mode) +{ + struct registry_priv *registry_par = &padapter->registrypriv; + u8 param[H2C_INACTIVE_PS_LEN] = {0}; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + RTW_INFO("%s, ps_mode: %d\n", __func__, ps_mode); + if (ps_mode == PS_MODE_ACTIVE) { + SET_H2CCMD_INACTIVE_PS_EN(param, 0); + } + else { + SET_H2CCMD_INACTIVE_PS_EN(param, 1); + if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) + SET_H2CCMD_INACTIVE_DISBBRF(param, 1); + if(registry_par->suspend_type == FW_IPS_WRC) { + SET_H2CCMD_INACTIVE_PERIOD_SCAN_EN(param, 1); + SET_H2CCMD_INACTIVE_PS_FREQ(param, 3); + SET_H2CCMD_INACTIVE_PS_DURATION(param, 1); + SET_H2CCMD_INACTIVE_PS_PERIOD_SCAN_TIME(param, 3); + } + } + + rtl8821c_fillh2ccmd(padapter, H2C_INACTIVE_PS_, sizeof(param), param); +} +#endif /* CONFIG_WOWLAN */ + #ifdef CONFIG_BT_COEXIST void rtl8821c_download_BTCoex_AP_mode_rsvd_page(PADAPTER adapter) { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_dm.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_dm.c index 129da1c904f3..f4cc7b17cffc 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_dm.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_dm.c @@ -146,47 +146,14 @@ static void init_phydm_cominfo(PADAPTER adapter) { PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter); struct dm_struct *pDM_Odm = &hal->odmpriv; - u8 cut_ver = ODM_CUT_A, fab_ver = ODM_TSMC; Init_ODM_ComInfo(adapter); odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_PACKAGE_TYPE, hal->PackageType); - if (IS_CHIP_VENDOR_TSMC(hal->version_id)) - fab_ver = ODM_TSMC; - else if (IS_CHIP_VENDOR_UMC(hal->version_id)) - fab_ver = ODM_UMC; - else if (IS_CHIP_VENDOR_SMIC(hal->version_id)) - fab_ver = ODM_UMC + 1; - else - RTW_INFO("%s: unknown Fv=%d !!\n", - __FUNCTION__, GET_CVID_MANUFACTUER(hal->version_id)); - - if (IS_A_CUT(hal->version_id)) - cut_ver = ODM_CUT_A; - else if (IS_B_CUT(hal->version_id)) - cut_ver = ODM_CUT_B; - else if (IS_C_CUT(hal->version_id)) - cut_ver = ODM_CUT_C; - else if (IS_D_CUT(hal->version_id)) - cut_ver = ODM_CUT_D; - else if (IS_E_CUT(hal->version_id)) - cut_ver = ODM_CUT_E; - else if (IS_F_CUT(hal->version_id)) - cut_ver = ODM_CUT_F; - else if (IS_I_CUT(hal->version_id)) - cut_ver = ODM_CUT_I; - else if (IS_J_CUT(hal->version_id)) - cut_ver = ODM_CUT_J; - else if (IS_K_CUT(hal->version_id)) - cut_ver = ODM_CUT_K; - else - RTW_INFO("%s: unknown Cv=%d !!\n", - __FUNCTION__, GET_CVID_CUT_VERSION(hal->version_id)); - - RTW_INFO("%s: Fv=%d Cv=%d\n", __FUNCTION__, fab_ver, cut_ver); - odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_FAB_VER, fab_ver); - odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_CUT_VER, cut_ver); + RTW_INFO("%s: Fv=%d Cv=%d\n", __FUNCTION__, hal->version_id.VendorType, hal->version_id.CUTVersion); + odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_FAB_VER, hal->version_id.VendorType); + odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_CUT_VER, hal->version_id.CUTVersion); } @@ -241,7 +208,6 @@ void rtl8821c_phy_haldm_watchdog(PADAPTER Adapter) BOOLEAN bFwCurrentInPSMode = _FALSE; u8 bFwPSAwake = _TRUE; struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(Adapter); - u8 lps_changed = _FALSE; u8 in_lps = _FALSE; PADAPTER current_lps_iface = NULL, iface = NULL; struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter); @@ -272,20 +238,22 @@ void rtl8821c_phy_haldm_watchdog(PADAPTER Adapter) } #ifdef CONFIG_LPS - if (pwrpriv->bLeisurePs && bFwCurrentInPSMode && pwrpriv->pwr_mode != PS_MODE_ACTIVE -#ifdef CONFIG_WMMPS_STA - && !rtw_is_wmmps_mode(Adapter) -#endif /* CONFIG_WMMPS_STA */ - ) { + if (pwrpriv->bLeisurePs && bFwCurrentInPSMode && pwrpriv->pwr_mode != PS_MODE_ACTIVE) { + in_lps = _TRUE; + for (i = 0; i < dvobj->iface_nums; i++) { iface = dvobj->padapters[i]; - if (pwrpriv->current_lps_hw_port_id == rtw_hal_get_port(iface)) + if (pwrpriv->current_lps_hw_port_id == rtw_hal_get_port(iface)) { current_lps_iface = iface; + rtw_lps_rfon_ctrl(current_lps_iface, rf_on); + break; + } } - lps_changed = _TRUE; - in_lps = _TRUE; - LPS_Leave(current_lps_iface, LPS_CTRL_PHYDM); + if (!current_lps_iface) { + RTW_WARN("Can't find a adapter with LPS to enable RFON function !\n"); + goto skip_dm; + } } #endif @@ -306,8 +274,8 @@ void rtl8821c_phy_haldm_watchdog(PADAPTER Adapter) skip_dm: #ifdef CONFIG_LPS - if (lps_changed) - LPS_Enter(current_lps_iface, LPS_CTRL_PHYDM); + if (current_lps_iface) + rtw_lps_rfon_ctrl(current_lps_iface, rf_off); #endif #ifdef CONFIG_SUPPORT_HW_WPS_PBC /* Check GPIO to determine current Pbc status.*/ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_halinit.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_halinit.c index 0c89638659d0..82c9cd44acb7 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_halinit.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_halinit.c @@ -55,9 +55,7 @@ void init_hal_spec_rtl8821c(PADAPTER adapter) | WL_FUNC_TDLS ; -#if CONFIG_TX_AC_LIFETIME hal_spec->tx_aclt_unit_factor = 8; -#endif hal_spec->rx_tsf_filter = 1; @@ -331,9 +329,6 @@ void rtl8821c_init_default_value(PADAPTER adapter) /* init default value */ hal->fw_ractrl = _FALSE; - if (!adapter_to_pwrctl(adapter)->bkeepfwalive) - hal->LastHMEBoxNum = 0; - /* init phydm default value */ hal->bIQKInitialized = _FALSE; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_ops.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_ops.c index 4fd06ae1e8e4..9e0b9eae198d 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_ops.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/rtl8821c_ops.c @@ -142,7 +142,7 @@ static void Hal_EfuseParseBTCoexistInfo(PADAPTER adapter, u8 *map, u8 mapvalid) if ((mapvalid == _TRUE) && (map[EEPROM_RF_BOARD_OPTION_8821C] != 0xFF)) { tmp_u32 = rtw_read32(adapter, REG_WL_BT_PWR_CTRL_8821C); - /* 0xc1[7:5] = 0x01 */ + /* 0xc1[7:5] = 0x01 (Combo card) */ if ((((map[EEPROM_RF_BOARD_OPTION_8821C] & 0xe0) >> 5) == 0x01) && (tmp_u32 & BIT_BT_FUNC_EN_8821C)) hal->EEPROMBluetoothCoexist = _TRUE; else @@ -154,8 +154,10 @@ static void Hal_EfuseParseBTCoexistInfo(PADAPTER adapter, u8 *map, u8 mapvalid) setting = map[EEPROM_RF_BT_SETTING_8821C]; if ((_TRUE == mapvalid) && (setting != 0xFF)) { - /*Bit[0]: Total antenna number - 0: 2-Antenna / 1: 1-Antenna */ + /* Bit[0]: Total antenna number + * 0: 2-Antenna (WL BT not share Ant, concurrent mode) + * 1: 1-Antenna (WL BT share Ant, TDMA mode) + */ hal->EEPROMBluetoothAntNum = setting & BIT(0); /* * Bit[6]: One-Ant structure use Ant2(aux.) path or Ant1(main) path @@ -181,7 +183,6 @@ static void Hal_EfuseParseChnlPlan(PADAPTER adapter, u8 *map, u8 autoloadfail) map ? map[EEPROM_CHANNEL_PLAN_8821C] : 0xFF, adapter->registrypriv.alpha2, adapter->registrypriv.channel_plan, - RTW_CHPLAN_REALTEK_DEFINE, autoloadfail ); } @@ -222,7 +223,7 @@ static void Hal_EfuseParseAntennaDiversity(PADAPTER adapter, u8 *map, u8 mapvali struct registry_priv *registry_par = &adapter->registrypriv; - if (hal->EEPROMBluetoothAntNum == Ant_x1) + if (hal->EEPROMBluetoothCoexist == _TRUE && hal->EEPROMBluetoothAntNum == Ant_x1) hal->AntDivCfg = 0; else { if (registry_par->antdiv_cfg == 2)/* 0:OFF , 1:ON, 2:By EFUSE */ @@ -233,7 +234,7 @@ static void Hal_EfuseParseAntennaDiversity(PADAPTER adapter, u8 *map, u8 mapvali /*hal->TRxAntDivType = S0S1_TRX_HW_ANTDIV;*/ hal->with_extenal_ant_switch = ((map[EEPROM_RF_BT_SETTING_8821C] & BIT7) >> 7); - RTW_INFO("%s:EEPROM AntDivCfg=%d, AntDivType=%d, extenal_ant_switch:%d\n", + RTW_INFO("%s:EEPROM AntDivCfg=%d, AntDivType=%d, external_ant_switch:%d\n", __func__, hal->AntDivCfg, hal->TRxAntDivType, hal->with_extenal_ant_switch); #endif /* CONFIG_ANTENNA_DIVERSITY */ } @@ -611,14 +612,11 @@ static void xmit_status_check(PADAPTER p) else { diff_time = rtw_get_passing_time_ms(psrtpriv->last_tx_complete_time); if (diff_time > 4000) { - u32 ability = 0; - - ability = rtw_phydm_ability_get(p); RTW_INFO("%s tx hang %s\n", __FUNCTION__, - (ability & ODM_BB_ADAPTIVITY) ? "ODM_BB_ADAPTIVITY" : ""); + (rtw_odm_adaptivity_needed(p)) ? "ODM_BB_ADAPTIVITY" : ""); - if (!(ability & ODM_BB_ADAPTIVITY)) { + if (!rtw_odm_adaptivity_needed(p)) { psrtpriv->self_dect_tx_cnt++; psrtpriv->self_dect_case = 1; rtw_hal_sreset_reset(p); @@ -1342,10 +1340,12 @@ static void hw_var_set_mlme_sitesurvey(PADAPTER adapter, u8 enable) rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE); + #ifdef CONFIG_AP_MODE if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) { ResumeTxBeacon(adapter); rtw_mi_tx_beacon_hdl(adapter); } + #endif } } static void hw_var_set_mlme_join(PADAPTER adapter, u8 type) @@ -1476,6 +1476,23 @@ static void hw_var_set_acm_ctrl(PADAPTER adapter, u8 ctrl) rtw_write8(adapter, REG_ACMHWCTRL_8821C, hwctrl); } +void hw_var_lps_rfon_chk(_adapter *adapter, u8 rfon_ctrl) +{ +#ifdef CONFIG_LPS_ACK + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + + if (rfon_ctrl == rf_on) { + if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) { + if (pwrpriv->lps_ack_status > 0) + RTW_INFO(FUNC_ADPT_FMT" RF_ON function is not ready !!!\n", FUNC_ADPT_ARG(adapter)); + } else { + RTW_WARN("LPS RFON sctx query timeout, operation abort!!\n"); + } + pwrpriv->lps_ack_status = -1; + } +#endif +} + static void hw_var_set_sec_cfg(PADAPTER adapter, u8 cfg) { u16 reg_scr_ori; @@ -1659,6 +1676,53 @@ static void rtl8821c_set_h2c_fw_joinbssrpt(PADAPTER adapter, u8 mstatus) rtl8821c_dl_rsvd_page(adapter, RT_MEDIA_CONNECT); } +#ifdef CONFIG_WOWLAN +static void hw_var_vendor_wow_mode(_adapter *adapter, u8 en) +{ +#ifdef CONFIG_CONCURRENT_MODE + _adapter *iface = NULL; + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + u8 igi = 0, mac_addr[ETH_ALEN]; + + RTW_INFO("%s: en(%d)--->\n", __func__, en); + if (en) { + rtw_hal_get_hwreg(adapter, HW_VAR_MAC_ADDR, mac_addr); + /* RTW_INFO("suspend mac addr: "MAC_FMT"\n", MAC_ARG(mac_addr)); */ + rtw_halmac_set_bssid(dvobj, HW_PORT4, mac_addr); + dvobj->rxfltmap2_bf_suspend = rtw_read16(adapter, REG_RXFLTMAP2); + dvobj->bcn_ctrl_clint3_bf_suspend = rtw_read8(adapter, REG_BCN_CTRL_CLINT3); + dvobj->rcr_bf_suspend = rtw_read32(adapter, REG_RCR); + dvobj->cr_ext_bf_suspend = rtw_read32(adapter, REG_CR_EXT); + /*RTW_INFO("RCR: 0x%02x, REG_CR_EXT: 0x%02x , REG_BCN_CTRL_CLINT3: 0x%02x, REG_RXFLTMAP2:0x%02x, REG_MACID_DROP0_8822B:0x%02x\n" + , rtw_read32(adapter, REG_RCR), rtw_read8(adapter, REG_CR_EXT), rtw_read8(adapter, REG_BCN_CTRL_CLINT3) + , rtw_read32(adapter, REG_RXFLTMAP2), rtw_read8(adapter, REG_MACID_DROP0_8822B)); */ + rtw_write32(adapter, REG_RCR, (rtw_read32(adapter, REG_RCR) & (~(RCR_AM))) | RCR_CBSSID_DATA | RCR_CBSSID_BCN); + /* set PORT4 to ad hoc mode to filter not necessary Beacons */ + rtw_write8(adapter, REG_CR_EXT, (rtw_read8(adapter, REG_CR_EXT)& (~BIT5)) | BIT4); + rtw_write8(adapter, REG_BCN_CTRL_CLINT3, rtw_read8(adapter, REG_BCN_CTRL_CLINT3) | BIT3); + rtw_write16(adapter, REG_RXFLTMAP2, 0xffff); + /* RTW_INFO("RCR: 0x%02x, REG_CR_EXT: 0x%02x , REG_BCN_CTRL_CLINT3: 0x%02x, REG_RXFLTMAP2:0x%02x, REG_MACID_DROP0_8822B:0x%02x\n" + , rtw_read32(adapter, REG_RCR), rtw_read8(adapter, REG_CR_EXT), rtw_read8(adapter, REG_BCN_CTRL_CLINT3) + , rtw_read32(adapter, REG_RXFLTMAP2), rtw_read8(adapter, REG_MACID_DROP0_8822B)); */ + + /* The WRC's RSSI is weak. Set the IGI to lower */ + odm_write_dig(adapter_to_phydm(adapter), 0x24); + } else { + /* restore the rcr, port ctrol setting */ + rtw_write32(adapter, REG_CR_EXT, dvobj->cr_ext_bf_suspend); + rtw_write32(adapter, REG_RCR, dvobj->rcr_bf_suspend); + rtw_write8(adapter, REG_BCN_CTRL_CLINT3, dvobj->bcn_ctrl_clint3_bf_suspend); + rtw_write16(adapter, REG_RXFLTMAP2, dvobj->rxfltmap2_bf_suspend); + + /* RTW_INFO("RCR: 0x%02x, REG_CR_EXT: 0x%02x , REG_BCN_CTRL_CLINT3: 0x%02x, REG_RXFLTMAP2:0x%02x, REG_MACID_DROP0_8822B:0x%02x\n" + , rtw_read32(adapter, REG_RCR), rtw_read8(adapter, REG_CR_EXT), rtw_read8(adapter, REG_BCN_CTRL_CLINT3) + , rtw_read32(adapter, REG_RXFLTMAP2), rtw_read8(adapter, REG_MACID_DROP0_8822B)); */ + } +#endif /* CONFIG_CONCURRENT_MODE */ +} +#endif /* CONFIG_WOWLAN */ + /* * Parameters: * adapter @@ -1809,6 +1873,14 @@ u8 rtl8821c_sethwreg(PADAPTER adapter, u8 variable, u8 *val) case HW_VAR_H2C_FW_PWRMODE: rtl8821c_set_FwPwrMode_cmd(adapter, *val); break; + + case HW_VAR_H2C_FW_PWRMODE_RFON_CTRL: + rtl8821c_set_FwPwrMode_rfon_ctrl_cmd(adapter, *val); + break; + + case HW_VAR_LPS_RFON_CHK : + hw_var_lps_rfon_chk(adapter, *val); + break; /* case HW_VAR_H2C_PS_TUNE_PARAM: break; @@ -1816,6 +1888,15 @@ u8 rtl8821c_sethwreg(PADAPTER adapter, u8 variable, u8 *val) case HW_VAR_H2C_FW_JOINBSSRPT: rtl8821c_set_h2c_fw_joinbssrpt(adapter, *val); break; + case HW_VAR_H2C_INACTIVE_IPS: +#ifdef CONFIG_WOWLAN + rtl8821c_set_fw_pwrmode_inips_cmd_wowlan(adapter, *val); +#endif /* CONFIG_WOWLAN */ +#ifdef CONFIG_WOWLAN + case HW_VAR_VENDOR_WOW_MODE: + hw_var_vendor_wow_mode(adapter, *(u8 *)val); + break; +#endif /* CONFIG_WOWLAN */ case HW_VAR_DL_RSVD_PAGE: #ifdef CONFIG_BT_COEXIST if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) @@ -2007,11 +2088,12 @@ u8 rtl8821c_sethwreg(PADAPTER adapter, u8 variable, u8 *val) */ #ifdef CONFIG_GPIO_WAKEUP case HW_SET_GPIO_WL_CTRL: { + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); u8 enable = *val; u8 value = 0; u8 addr = REG_PAD_CTRL1_8821C + 3; - if (WAKEUP_GPIO_IDX == 6) { + if (pwrpriv->wowlan_gpio_index == 6) { value = rtw_read8(adapter, addr); if (enable == _TRUE && (value & BIT(1))) @@ -2125,6 +2207,7 @@ u8 rtl8821c_sethwreg(PADAPTER adapter, u8 variable, u8 *val) return ret; } +#ifdef CONFIG_PROC_DEBUG struct qinfo { u32 head:11; u32 tail:11; @@ -2227,6 +2310,7 @@ static void dump_mac_txfifo(void *sel, _adapter *adapter) RTW_PRINT_SEL(sel, "HPQ: %d, LPQ: %d, NPQ: %d, EPQ: %d, PUBQ: %d\n" , hpq, lpq, npq, epq, pubq); } +#endif static u8 hw_var_get_bcn_valid(PADAPTER adapter) { @@ -2421,7 +2505,7 @@ void rtl8821c_gethwreg(PADAPTER adapter, u8 variable, u8 *val) /* driver read REG_SYS_CFG5 - BIT_LPS_STATUS REG_1070[3] to get hw ps state */ *((u16 *)val) = rtw_read8(adapter, REG_SYS_CFG5); break; - +#ifdef CONFIG_PROC_DEBUG case HW_VAR_DUMP_MAC_QUEUE_INFO: dump_mac_qinfo(val, adapter); break; @@ -2429,6 +2513,7 @@ void rtl8821c_gethwreg(PADAPTER adapter, u8 variable, u8 *val) case HW_VAR_DUMP_MAC_TXFIFO: dump_mac_txfifo(val, adapter); break; +#endif /* case HW_VAR_ASIX_IOT: case HW_VAR_H2C_BT_MP_OPER: @@ -2439,6 +2524,10 @@ void rtl8821c_gethwreg(PADAPTER adapter, u8 variable, u8 *val) *((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port); break; + case HW_VAR_FREECNT: + *val = rtw_read8(adapter, REG_MISC_CTRL)&BIT_EN_FREECNT; + break; + default: GetHwReg(adapter, variable, val); break; @@ -3315,6 +3404,7 @@ static void fill_fake_txdesc(PADAPTER adapter, u8 *pDesc, u32 BufferLen, case _GCMP_: case _GCMP_256_: SET_TX_DESC_SEC_TYPE_8821C(pDesc, 0x2); + break; default: SET_TX_DESC_SEC_TYPE_8821C(pDesc, 0x0); break; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_io.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_io.c index e6e8a7a43f07..2a098e765ae2 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_io.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_io.c @@ -684,6 +684,7 @@ void sd_int_hdl(PADAPTER adapter) return; } + /*pHalData->sdio_hisr = rtl8821cs_get_interrupt(adapter);*/ rtw_read_mem(adapter, REG_SDIO_HISR_8821C, 8, data); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_ops.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_ops.c index 2d51c687a7fc..b68afb067ff7 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_ops.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_ops.c @@ -461,6 +461,9 @@ u8 rtl8821cs_set_hal_ops(PADAPTER adapter) ops_func->free_xmit_priv = rtl8821cs_free_xmit_priv; ops_func->hal_xmit = rtl8821cs_hal_xmit; ops_func->mgnt_xmit = rtl8821cs_mgnt_xmit; +#ifdef CONFIG_RTW_MGMT_QUEUE + ops_func->hal_mgmt_xmitframe_enqueue = rtl8821cs_hal_mgmt_xmit_enqueue; +#endif ops_func->hal_xmitframe_enqueue = rtl8821cs_hal_xmit_enqueue; #ifdef CONFIG_XMIT_THREAD_MODE ops_func->xmit_thread_handler = rtl8821cs_xmit_buf_handler; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_recv.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_recv.c index ff9a1a7d2090..52d2972486b2 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_recv.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_recv.c @@ -21,22 +21,6 @@ #include "../rtl8821c.h" /* rtl8821c_rxdesc2attribute(), rtl8821c_c2h_handler_no_io() */ #include "rtl8821cs_recv.h" /* MAX_RECVBUF_SZ */ - -static s32 initrecvbuf(struct recv_buf *precvbuf, PADAPTER adapter) -{ - _rtw_init_listhead(&precvbuf->list); - _rtw_spinlock_init(&precvbuf->recvbuf_lock); - - precvbuf->adapter = adapter; - - return _SUCCESS; -} - -static void freerecvbuf(struct recv_buf *precvbuf) -{ - _rtw_spinlock_free(&precvbuf->recvbuf_lock); -} - #if 0 /* * Return: @@ -840,6 +824,7 @@ static void rtl8821c_recv_tasklet(void *priv) */ s32 rtl8821cs_init_recv_priv(PADAPTER adapter) { + struct registry_priv *regsty = adapter_to_regsty(adapter); s32 res; u32 i, n; struct recv_priv *precvpriv; @@ -853,7 +838,7 @@ s32 rtl8821cs_init_recv_priv(PADAPTER adapter) _rtw_init_queue(&precvpriv->free_recv_buf_queue); _rtw_init_queue(&precvpriv->recv_buf_pending_queue); - n = NR_RECVBUFF * sizeof(struct recv_buf) + 4; + n = regsty->recvbuf_nr * sizeof(struct recv_buf) + 4; precvpriv->pallocated_recv_buf = rtw_zmalloc(n); if (precvpriv->pallocated_recv_buf == NULL) { res = _FAIL; @@ -864,46 +849,21 @@ s32 rtl8821cs_init_recv_priv(PADAPTER adapter) /* init each recv buffer */ precvbuf = (struct recv_buf *)precvpriv->precv_buf; - for (i = 0; i < NR_RECVBUFF; i++) { - res = initrecvbuf(precvbuf, adapter); + for (i = 0; i < regsty->recvbuf_nr; i++) { + res = sdio_initrecvbuf(precvbuf, adapter); if (res == _FAIL) break; - res = rtw_os_recvbuf_resource_alloc(adapter, precvbuf); + res = rtw_os_recvbuf_resource_alloc(adapter, precvbuf, MAX_RECVBUF_SZ); if (res == _FAIL) { - freerecvbuf(precvbuf); + sdio_freerecvbuf(precvbuf); break; } -#ifdef CONFIG_SDIO_RX_COPY - if (precvbuf->pskb == NULL) { - SIZE_PTR tmpaddr = 0; - SIZE_PTR alignment = 0; - - precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); - - if (precvbuf->pskb) { - precvbuf->pskb->dev = adapter->pnetdev; - - tmpaddr = (SIZE_PTR)precvbuf->pskb->data; - alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); - skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); - - precvbuf->phead = precvbuf->pskb->head; - precvbuf->pdata = precvbuf->pskb->data; - precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); - precvbuf->pend = skb_end_pointer(precvbuf->pskb); - precvbuf->len = 0; - } - - if (precvbuf->pskb == NULL) - RTW_INFO("%s: alloc_skb fail!\n", __FUNCTION__); - } -#endif #if 0 res = os_recvbuf_resource_alloc(adapter, precvbuf); if (res == _FAIL) { - freerecvbuf(precvbuf); + sdio_freerecvbuf(precvbuf); break; } #endif @@ -933,14 +893,14 @@ initbuferror: for (i = 0; i < n ; i++) { rtw_list_delete(&precvbuf->list); rtw_os_recvbuf_resource_free(adapter, precvbuf); - freerecvbuf(precvbuf); + sdio_freerecvbuf(precvbuf); precvbuf++; } precvpriv->precv_buf = NULL; } if (precvpriv->pallocated_recv_buf) { - n = NR_RECVBUFF * sizeof(struct recv_buf) + 4; + n = regsty->recvbuf_nr * sizeof(struct recv_buf) + 4; rtw_mfree(precvpriv->pallocated_recv_buf, n); precvpriv->pallocated_recv_buf = NULL; } @@ -956,6 +916,7 @@ exit: */ void rtl8821cs_free_recv_priv(PADAPTER adapter) { + struct registry_priv *regsty = &adapter->registrypriv; u32 i, n; struct recv_priv *precvpriv; struct recv_buf *precvbuf; @@ -971,19 +932,19 @@ void rtl8821cs_free_recv_priv(PADAPTER adapter) /* 2. free all recv buffers */ precvbuf = (struct recv_buf *)precvpriv->precv_buf; if (precvbuf) { - n = NR_RECVBUFF; + n = regsty->recvbuf_nr; precvpriv->free_recv_buf_queue_cnt = 0; for (i = 0; i < n ; i++) { rtw_list_delete(&precvbuf->list); rtw_os_recvbuf_resource_free(adapter, precvbuf); - freerecvbuf(precvbuf); + sdio_freerecvbuf(precvbuf); precvbuf++; } precvpriv->precv_buf = NULL; } if (precvpriv->pallocated_recv_buf) { - n = NR_RECVBUFF * sizeof(struct recv_buf) + 4; + n = regsty->recvbuf_nr * sizeof(struct recv_buf) + 4; rtw_mfree(precvpriv->pallocated_recv_buf, n); precvpriv->pallocated_recv_buf = NULL; } diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_xmit.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_xmit.c index 4a35975bb4d2..b9e303ec557d 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_xmit.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_xmit.c @@ -271,6 +271,17 @@ static s32 xmit_xmitframes(PADAPTER adapter, struct xmit_priv *pxmitpriv) rtw_halmac_get_tx_desc_size(adapter_to_dvobj(adapter), &txdesc_size); rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size); +#ifdef CONFIG_RTW_MGMT_QUEUE + /* dump management frame directly */ + do { + pxmitframe = rtw_dequeue_mgmt_xframe(pxmitpriv); + if (pxmitframe) + adapter->hal_func.mgnt_xmit(adapter, pxmitframe); + } while (pxmitframe != NULL); + + hwentry--; +#endif + if (adapter->registrypriv.wifi_spec == 1) { for (idx = 0; idx < 4; idx++) inx[idx] = pxmitpriv->wmm_para_seq[idx]; @@ -625,6 +636,39 @@ s32 rtl8821cs_mgnt_xmit(PADAPTER adapter, struct xmit_frame *pmgntframe) return ret; } +/* + * Description: + * Enqueue management xmitframe + * + * Return: + * _TRUE enqueue ok + * _FALSE fail + */ +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtl8821cs_hal_mgmt_xmit_enqueue(PADAPTER adapter, struct xmit_frame *pxmitframe) +{ + struct xmit_priv *pxmitpriv; + s32 ret; + + pxmitpriv = &adapter->xmitpriv; + + ret = rtw_mgmt_xmitframe_enqueue(adapter, pxmitframe); + if (ret != _SUCCESS) { + rtw_free_xmitframe(pxmitpriv, pxmitframe); + pxmitpriv->tx_drop++; + return _FALSE; + } + +#ifdef CONFIG_SDIO_TX_TASKLET + tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); +#else + _rtw_up_sema(&pxmitpriv->SdioXmitSema); +#endif + + return _TRUE; +} +#endif + /* * Description: * Enqueue xmitframe diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_xmit.h index cd063475151f..af03f12368a9 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/hal/rtl8821c/sdio/rtl8821cs_xmit.h @@ -20,6 +20,9 @@ s32 rtl8821cs_init_xmit_priv(PADAPTER); void rtl8821cs_free_xmit_priv(PADAPTER); +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtl8821cs_hal_mgmt_xmit_enqueue(PADAPTER, struct xmit_frame *); +#endif s32 rtl8821cs_hal_xmit_enqueue(PADAPTER, struct xmit_frame *); s32 rtl8821cs_hal_xmit(PADAPTER, struct xmit_frame *); s32 rtl8821cs_mgnt_xmit(PADAPTER, struct xmit_frame *); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/halmac.mk b/drivers/net/wireless/rockchip_wlan/rtl8821cs/halmac.mk index 2c2a7b6ff2fb..e330dcf269c9 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/halmac.mk +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/halmac.mk @@ -6,8 +6,6 @@ # Base directory path_hm := hal/halmac -# Level 1 directory -path_hm_d1 := $(path_hm)/halmac_88xx ifeq ($(CONFIG_PCI_HCI), y) pci := y @@ -20,23 +18,30 @@ usb := y endif ifeq ($(CONFIG_RTL8822B), y) +series := 88xx ic := 8822b endif ifeq ($(CONFIG_RTL8822C), y) +series := 88xx ic := 8822c endif ifeq ($(CONFIG_RTL8821C), y) +series := 88xx ic := 8821c endif ifeq ($(CONFIG_RTL8814B), y) -v1 := _v1 +series := 88xx_v1 ic := 8814b endif -ifeq ($(v1), _v1) +ifeq ($(CONFIG_RTL8723F), y) +series := 87xx +ic := 8723f +endif +ifeq ($(series), 88xx_v1) d2all := else d2all := y @@ -45,27 +50,27 @@ endif halmac-y += $(path_hm)/halmac_api.o halmac-y += $(path_hm)/halmac_dbg.o -# Modify level 1 directory if needed -path_hm_d1 := $(path_hm_d1)$(v1) -halmac-y += $(path_hm_d1)/halmac_bb_rf_88xx$(v1).o \ - $(path_hm_d1)/halmac_cfg_wmac_88xx$(v1).o \ - $(path_hm_d1)/halmac_common_88xx$(v1).o \ - $(path_hm_d1)/halmac_efuse_88xx$(v1).o \ - $(path_hm_d1)/halmac_flash_88xx$(v1).o \ - $(path_hm_d1)/halmac_fw_88xx$(v1).o \ - $(path_hm_d1)/halmac_gpio_88xx$(v1).o \ - $(path_hm_d1)/halmac_init_88xx$(v1).o \ - $(path_hm_d1)/halmac_mimo_88xx$(v1).o -halmac-$(pci) += $(path_hm_d1)/halmac_pcie_88xx$(v1).o -halmac-$(sdio) += $(path_hm_d1)/halmac_sdio_88xx$(v1).o -halmac-$(usb) += $(path_hm_d1)/halmac_usb_88xx$(v1).o +# Level 1 directory +path_hm_d1 := $(path_hm)/halmac_$(series) +halmac-y += $(path_hm_d1)/halmac_bb_rf_$(series).o \ + $(path_hm_d1)/halmac_cfg_wmac_$(series).o \ + $(path_hm_d1)/halmac_common_$(series).o \ + $(path_hm_d1)/halmac_efuse_$(series).o \ + $(path_hm_d1)/halmac_flash_$(series).o \ + $(path_hm_d1)/halmac_fw_$(series).o \ + $(path_hm_d1)/halmac_gpio_$(series).o \ + $(path_hm_d1)/halmac_init_$(series).o \ + $(path_hm_d1)/halmac_mimo_$(series).o +halmac-$(pci) += $(path_hm_d1)/halmac_pcie_$(series).o +halmac-$(sdio) += $(path_hm_d1)/halmac_sdio_$(series).o +halmac-$(usb) += $(path_hm_d1)/halmac_usb_$(series).o # Level 2 directory path_hm_d2 := $(path_hm_d1)/halmac_$(ic) halmac-$(d2all) += $(path_hm_d2)/halmac_cfg_wmac_$(ic).o \ $(path_hm_d2)/halmac_common_$(ic).o -halmac-y += $(path_hm_d2)/halmac_gpio_$(ic).o \ +halmac-y += $(path_hm_d2)/halmac_gpio_$(ic).o \ $(path_hm_d2)/halmac_init_$(ic).o \ $(path_hm_d2)/halmac_phy_$(ic).o \ $(path_hm_d2)/halmac_pwr_seq_$(ic).o diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/HalVerDef.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/HalVerDef.h index 3a7831849f3f..64d556785a45 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/HalVerDef.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/HalVerDef.h @@ -42,6 +42,7 @@ typedef enum tag_HAL_IC_Type_Definition { CHIP_8188GTV = 18, CHIP_8822C = 19, CHIP_8814B = 20, + CHIP_8723F = 21, } HAL_IC_TYPE_E; /* HAL_CHIP_TYPE_E */ @@ -131,6 +132,7 @@ typedef struct tag_HAL_VERSION { #define IS_8710B_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8710B) ? TRUE : FALSE) #define IS_8822C_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8822C) ? TRUE : FALSE) #define IS_8814B_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8814B) ? TRUE : FALSE) +#define IS_8723F_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8723F) ? TRUE : FALSE) #define IS_8192F_SERIES(version)\ ((GET_CVID_IC_TYPE(version) == CHIP_8192F) ? TRUE : FALSE) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/autoconf.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/autoconf.h index 6d31beda6055..3a877a728cb3 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/autoconf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/autoconf.h @@ -83,7 +83,6 @@ #define CONFIG_SET_SCAN_DENY_TIMER #endif /* CONFIG_IOCTL_CFG80211 */ -#define CONFIG_AP_MODE #ifdef CONFIG_AP_MODE #define CONFIG_INTERRUPT_BASED_TXBCN /* Tx Beacon when driver receive related interrupt*/ #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_INTERRUPT_BASED_TXBCN) @@ -100,9 +99,6 @@ /*#define CONFIG_FIND_BEST_CHANNEL*/ #endif - -#define CONFIG_P2P - #ifdef CONFIG_P2P #define CONFIG_WFD /* Wi-Fi display */ #define CONFIG_P2P_REMOVE_GROUP_INFO @@ -133,9 +129,6 @@ /*#define CONFIG_RTW_80211K*/ -#define CONFIG_LAYER2_ROAMING -#define CONFIG_LAYER2_ROAMING_RESUME - /* * Hareware/Firmware Related Config */ @@ -299,7 +292,7 @@ #define CONFIG_HW_ANTENNA_DIVERSITY #endif /* CONFIG_ANTENNA_DIVERSITY */ -#ifdef RTK_129X_PLATFORM +#ifdef CONFIG_PLATFORM_RTK129X #ifdef CONFIG_REDUCE_TX_CPU_LOADING #undef CONFIG_REDUCE_TX_CPU_LOADING #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/cmn_info/rtw_sta_info.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/cmn_info/rtw_sta_info.h index 8007fe517541..273046c25193 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/cmn_info/rtw_sta_info.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/cmn_info/rtw_sta_info.h @@ -86,6 +86,14 @@ enum rf_type { RF_3T3R = 5, RF_3T4R = 6, RF_4T4R = 7, + RF_4T3R = 8, + RF_4T2R = 9, + RF_4T1R = 10, + RF_3T2R = 11, + RF_3T1R = 12, + RF_2T1R = 13, + RF_1T4R = 14, + RF_1T3R = 15, RF_TYPE_MAX, }; @@ -192,6 +200,7 @@ struct ra_sta_info { struct dtp_info { u8 dyn_tx_power; /*Dynamic Tx power offset*/ u8 last_tx_power; + boolean sta_is_alive; u8 sta_tx_high_power_lvl:4; u8 sta_last_dtp_lvl:4; }; @@ -249,6 +258,7 @@ struct phydm_phyinfo_struct { u8 cnt_pw2cca; u8 cnt_cca2agc_rdy; /*ODM_PHY_STATUS_NEW_TYPE_SUPPORT*/ + u8 rx_cck_evm; }; struct phydm_perpkt_info_struct { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/drv_conf.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/drv_conf.h index 762655581d3d..91393eb350c8 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/drv_conf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/drv_conf.h @@ -42,9 +42,10 @@ #define CONFIG_RTW_REPEATER_SON_ID 0x02040608 #endif //#define CONFIG_RTW_REPEATER_SON_ROOT - #ifndef CONFIG_RTW_REPEATER_SON_ROOT - #define CONFIG_LAYER2_ROAMING_ACTIVE - #endif + #ifndef CONFIG_RTW_REPEATER_SON_ROOT + #undef CONFIG_ROAMING_FLAG + #define CONFIG_ROAMING_FLAG 0x7 + #endif #undef CONFIG_POWER_SAVING #endif @@ -93,11 +94,11 @@ #endif #endif - #if (CONFIG_RTW_ANDROID <= 7) - #ifdef RTW_SINGLE_WIPHY - #undef RTW_SINGLE_WIPHY - #endif - #endif + #if (CONFIG_RTW_ANDROID <= 7) + #ifdef RTW_SINGLE_WIPHY + #undef RTW_SINGLE_WIPHY + #endif + #endif #if (CONFIG_RTW_ANDROID >= 8) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) @@ -116,9 +117,11 @@ #ifndef CONFIG_RTW_CFGVENDOR_LLSTATS #define CONFIG_RTW_CFGVENDOR_LLSTATS #endif + #if (CONFIG_RTW_ANDROID < 11) #ifndef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI #define CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI #endif + #endif #ifndef CONFIG_RTW_CFGVENDOR_RSSIMONITOR #define CONFIG_RTW_CFGVENDOR_RSSIMONITOR #endif @@ -129,6 +132,15 @@ #ifndef CONFIG_RTW_CFGVENDOR_WIFI_OFFLOAD //#define CONFIG_RTW_CFGVENDOR_WIFI_OFFLOAD #endif + #ifndef CONFIG_RTW_HOSTAPD_ACS + #define CONFIG_RTW_HOSTAPD_ACS + #endif + #ifndef CONFIG_KERNEL_PATCH_EXTERNAL_AUTH + #define CONFIG_KERNEL_PATCH_EXTERNAL_AUTH + #endif + #ifndef CONFIG_RTW_ABORT_SCAN + #define CONFIG_RTW_ABORT_SCAN + #endif #endif #endif // CONFIG_RTW_WIFI_HAL @@ -194,9 +206,47 @@ #endif #endif +#ifndef CONFIG_RTW_DATA_BMC_TO_UC +#define CONFIG_RTW_DATA_BMC_TO_UC 0 +#endif + #ifdef CONFIG_AP_MODE #define CONFIG_LIMITED_AP_NUM 1 - #define CONFIG_TX_MCAST2UNI /* AP mode support IP multicast->unicast */ + + #ifndef CONFIG_RTW_AP_DATA_BMC_TO_UC + #define CONFIG_RTW_AP_DATA_BMC_TO_UC 1 + #endif + #if CONFIG_RTW_AP_DATA_BMC_TO_UC + #undef CONFIG_RTW_DATA_BMC_TO_UC + #define CONFIG_RTW_DATA_BMC_TO_UC 1 + #endif + #ifndef CONFIG_RTW_AP_SRC_B2U_FLAGS + #define CONFIG_RTW_AP_SRC_B2U_FLAGS 0x8 /* see RTW_AP_B2U_XXX */ + #endif + #ifndef CONFIG_RTW_AP_FWD_B2U_FLAGS + #define CONFIG_RTW_AP_FWD_B2U_FLAGS 0x8 /* see RTW_AP_B2U_XXX */ + #endif +#endif + +#ifdef CONFIG_RTW_MULTI_AP + #ifndef CONFIG_AP_MODE + #error "enable CONFIG_RTW_MULTI_AP without CONFIG_AP_MODE" + #endif + #ifndef CONFIG_RTW_WDS + #define CONFIG_RTW_WDS + #endif + #ifndef CONFIG_RTW_UNASOC_STA_MODE_OF_STYPE + #define CONFIG_RTW_UNASOC_STA_MODE_OF_STYPE {2, 1} /* BMC:2 for all, NMY_UC:1 for interested target */ + #endif + #ifndef CONFIG_RTW_NLRTW + #define CONFIG_RTW_NLRTW + #endif + #ifndef CONFIG_RTW_WNM + #define CONFIG_RTW_WNM + #endif + #ifndef CONFIG_RTW_80211K + #define CONFIG_RTW_80211K + #endif #endif #ifdef CONFIG_RTW_MESH @@ -231,6 +281,16 @@ #ifndef CONFIG_RTW_MESH_DATA_BMC_TO_UC #define CONFIG_RTW_MESH_DATA_BMC_TO_UC 1 #endif + #if CONFIG_RTW_MESH_DATA_BMC_TO_UC + #undef CONFIG_RTW_DATA_BMC_TO_UC + #define CONFIG_RTW_DATA_BMC_TO_UC 1 + #endif + #ifndef CONFIG_RTW_MSRC_B2U_FLAGS + #define CONFIG_RTW_MSRC_B2U_FLAGS 0x0 /* see RTW_MESH_B2U_XXX */ + #endif + #ifndef CONFIG_RTW_MFWD_B2U_FLAGS + #define CONFIG_RTW_MFWD_B2U_FLAGS 0x2 /* see RTW_MESH_B2U_XXX */ + #endif #endif #if !defined(CONFIG_SCAN_BACKOP) && defined(CONFIG_AP_MODE) @@ -284,7 +344,7 @@ #ifndef CONFIG_IEEE80211_BAND_5GHZ #if defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8821C) \ || defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8822C) \ - || defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8814B) + || defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8814B) || defined(CONFIG_RTL8723F) #define CONFIG_IEEE80211_BAND_5GHZ 1 #else #define CONFIG_IEEE80211_BAND_5GHZ 0 @@ -342,6 +402,9 @@ #endif #if RTW_DEF_MODULE_REGULATORY_CERT + #ifdef CONFIG_REGD_SRC_FROM_OS + #error "CONFIG_REGD_SRC_FROM_OS is not supported when enable RTW_DEF_MODULE_REGULATORY_CERT" + #endif /* force enable TX power by rate and TX power limit */ #undef CONFIG_TXPWR_BY_RATE_EN #undef CONFIG_TXPWR_LIMIT_EN @@ -354,12 +417,22 @@ #define CONFIG_TXPWR_LIMIT 1 #endif +#ifndef CONFIG_RTW_REGD_SRC +#define CONFIG_RTW_REGD_SRC 1 /* 0:RTK_PRIV, 1:OS */ +#endif + +#define CONFIG_IOCTL_WEXT + #ifdef CONFIG_RTW_IPCAM_APPLICATION #undef CONFIG_TXPWR_BY_RATE_EN #define CONFIG_TXPWR_BY_RATE_EN 1 #define CONFIG_RTW_CUSTOMIZE_BEEDCA 0x0000431C #define CONFIG_RTW_CUSTOMIZE_BWMODE 0x00 #define CONFIG_RTW_CUSTOMIZE_RLSTA 0x30 + #define CONFIG_CHECK_SPECIFIC_IE_CONTENT + #ifdef CONFIG_CUSTOMER_EZVIZ_CHIME2 + #undef CONFIG_ACTIVE_KEEP_ALIVE_CHECK + #endif #if defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8822B) #define CONFIG_RTW_TX_NPATH_EN /* mutually incompatible with STBC_TX & Beamformer */ #endif @@ -420,6 +493,10 @@ #define CONFIG_RTW_TARGET_TX_PWR_5G_D {-1, -1, -1, -1, -1, -1, -1, -1, -1} #endif +#ifndef CONFIG_RTW_ANTENNA_GAIN +#define CONFIG_RTW_ANTENNA_GAIN 0x7FFF /* == UNSPECIFIED_MBM */ +#endif + #ifndef CONFIG_RTW_AMPLIFIER_TYPE_2G #define CONFIG_RTW_AMPLIFIER_TYPE_2G 0 #endif @@ -463,7 +540,8 @@ defined(CONFIG_RTL8188GTV) || defined(CONFIG_RTL8192F) || \ defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8710B) || \ defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) #define CONFIG_HWMPCAP_GEN1 -#elif defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) /*|| defined(CONFIG_RTL8814A)*/ +#elif defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || \ +defined(CONFIG_RTL8723F) /*|| defined(CONFIG_RTL8814A)*/ #define CONFIG_HWMPCAP_GEN2 #elif defined(CONFIG_RTL8814B) /*Address CAM - 128*/ #define CONFIG_HWMPCAP_GEN3 @@ -493,7 +571,9 @@ defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) #endif #if (CONFIG_IFACE_NUMBER > 2) - #define CONFIG_MI_WITH_MBSSID_CAM + #ifndef CONFIG_HWMPCAP_GEN3 + #define CONFIG_MI_WITH_MBSSID_CAM + #endif #ifdef CONFIG_MI_WITH_MBSSID_CAM #define CONFIG_MBSSID_CAM @@ -522,6 +602,17 @@ defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) #endif #endif /*CONFIG_HWMPCAP_GEN2*/ + + #ifdef CONFIG_HWMPCAP_GEN3 + #define CONFIG_PORT_BASED_TXBCN + #undef CONFIG_SUPPORT_MULTI_BCN + #undef CONFIG_SWTIMER_BASED_TXBCN + #undef CONFIG_LIMITED_AP_NUM + #define CONFIG_LIMITED_AP_NUM 4 + #ifdef CONFIG_PCI_HCI + #define CONFIG_PORT_BASED_HIQ /* 8814BU doesn't support */ + #endif + #endif #endif /*CONFIG_AP_MODE*/ #ifdef CONFIG_HWMPCAP_GEN2 /*CONFIG_RTL8822B/CONFIG_RTL8821C/CONFIG_RTL8822C*/ @@ -530,6 +621,15 @@ defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) #endif/*CONFIG_HWMPCAP_GEN2*/ #endif/*(CONFIG_IFACE_NUMBER > 2)*/ +#if defined(CONFIG_MI_UNIQUE_MACADDR_BIT) + #if !defined(CONFIG_MI_WITH_MBSSID_CAM) + #error "CONFIG_MI_UNIQUE_MACADDR_BIT should not be used without multiple interface !!" + #endif + #if (CONFIG_MI_UNIQUE_MACADDR_BIT < 24) || ( 47 < CONFIG_MI_UNIQUE_MACADDR_BIT) + #error "CONFIG_MI_UNIQUE_MACADDR_BIT should be the bit in NIC specific mac address(BIT[24:47] !!" + #endif +#endif + #define MACID_NUM_SW_LIMIT 32 #define SEC_CAM_ENT_NUM_SW_LIMIT 32 @@ -577,20 +677,8 @@ defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) #endif /* CONFIG_SDIO_HCI || CONFIG_USB_RX_AGGREGATION */ #ifdef CONFIG_RTW_HOSTAPD_ACS - #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) - #ifndef CONFIG_FIND_BEST_CHANNEL - #define CONFIG_FIND_BEST_CHANNEL - #endif - #else - #ifdef CONFIG_FIND_BEST_CHANNEL - #undef CONFIG_FIND_BEST_CHANNEL - #endif - #ifndef CONFIG_RTW_ACS - #define CONFIG_RTW_ACS - #endif - #ifndef CONFIG_BACKGROUND_NOISE_MONITOR - #define CONFIG_BACKGROUND_NOISE_MONITOR - #endif + #ifndef CONFIG_RTW_ACS + #define CONFIG_RTW_ACS #endif #endif @@ -670,12 +758,31 @@ defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) #endif #endif +#ifdef CONFIG_WAR_OFFLOAD +#ifndef CONFIG_WOWLAN + #error "WAR OFFLOAD is part of WOWLAN" +#endif +#endif + +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) +#ifndef CONFIG_WOWLAN + #error "mDNS OFFLOAD is part of WOWLAN" +#endif +#ifndef CONFIG_WAR_OFFLOAD + #define CONFIG_WAR_OFFLOAD +#endif +#endif + #define CONFIG_RTW_TPT_MODE #ifdef CONFIG_PCI_BCN_POLLING #define CONFIG_BCN_ICF #endif +#ifndef CONFIG_RTW_MGMT_QUEUE + #define CONFIG_RTW_MGMT_QUEUE +#endif + #ifndef CONFIG_PCI_MSI #define CONFIG_RTW_PCI_MSI_DISABLE #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/drv_types.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/drv_types.h index 4870d242add0..870e6100b5e6 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/drv_types.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/drv_types.h @@ -93,6 +93,15 @@ typedef struct _ADAPTER _adapter, ADAPTER, *PADAPTER; #include "../hal/hal_dm.h" #include #include +#ifdef CONFIG_RTW_80211R +#include +#endif +#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) +#include +#endif +#ifdef CONFIG_RTW_MBO +#include +#endif #include #include #include @@ -106,6 +115,9 @@ typedef struct _ADAPTER _adapter, ADAPTER, *PADAPTER; #include #include #include +#ifdef CONFIG_RTW_WDS +#include "../core/wds/rtw_wds.h" +#endif #ifdef CONFIG_RTW_MESH #include "../core/mesh/rtw_mesh.h" #endif @@ -160,6 +172,8 @@ typedef struct _ADAPTER _adapter, ADAPTER, *PADAPTER; #include #endif /*CONFIG_RTW_REPEATER_SON */ +#include + #define SPEC_DEV_ID_NONE BIT(0) #define SPEC_DEV_ID_DISABLE_HT BIT(1) #define SPEC_DEV_ID_ENABLE_PS BIT(2) @@ -252,7 +266,19 @@ struct registry_priv { u8 tx_bw_mode; #ifdef CONFIG_AP_MODE u8 bmc_tx_rate; + #if CONFIG_RTW_AP_DATA_BMC_TO_UC + u8 ap_src_b2u_flags; + u8 ap_fwd_b2u_flags; + #endif #endif + +#ifdef CONFIG_RTW_MESH + #if CONFIG_RTW_MESH_DATA_BMC_TO_UC + u8 msrc_b2u_flags; + u8 mfwd_b2u_flags; + #endif +#endif + #ifdef CONFIG_80211N_HT u8 ht_enable; /* 0: 20 MHz, 1: 40 MHz, 2: 80 MHz, 3: 160MHz */ @@ -296,12 +322,11 @@ struct registry_priv { #ifdef CONFIG_80211AC_VHT u8 vht_enable; /* 0:disable, 1:enable, 2:auto */ + u8 vht_24g_enable; /* 0:disable, 1:enable */ u8 ampdu_factor; u8 vht_rx_mcs_map[2]; #endif /* CONFIG_80211AC_VHT */ - u8 lowrate_two_xmit; - u8 low_power ; u8 wifi_spec;/* !turbo_mode */ @@ -312,6 +337,9 @@ struct registry_priv { u8 tx_nss; u8 rx_nss; +#ifdef CONFIG_REGD_SRC_FROM_OS + enum regd_src_t regd_src; +#endif char alpha2[2]; u8 channel_plan; u8 excl_chs[MAX_CHANNEL_NUM]; @@ -374,6 +402,7 @@ struct registry_priv { #if CONFIG_IEEE80211_BAND_5GHZ s8 target_tx_pwr_5g[RF_PATH_MAX][RATE_SECTION_NUM - 1]; #endif + s16 antenna_gain; u8 tsf_update_pause_factor; u8 tsf_update_restore_factor; @@ -458,6 +487,8 @@ struct registry_priv { u8 suspend_type; #endif + u8 recvbuf_nr; + #ifdef CONFIG_SUPPORT_TRX_SHARED u8 trx_share_mode; #endif @@ -525,6 +556,10 @@ struct registry_priv { #ifdef CONFIG_RTL8822C_XCAP_NEW_POLICY u8 rtw_8822c_xcap_overwrite; #endif +#ifdef CONFIG_RTW_MULTI_AP + u8 unassoc_sta_mode_of_stype[UNASOC_STA_SRC_NUM]; + u16 max_unassoc_sta_cnt; +#endif }; /* For registry parameters */ @@ -558,8 +593,21 @@ struct registry_priv { #define REGSTY_IS_BW_2G_SUPPORT(regsty, bw) (REGSTY_BW_2G((regsty)) >= (bw)) #define REGSTY_IS_BW_5G_SUPPORT(regsty, bw) (REGSTY_BW_5G((regsty)) >= (bw)) +#ifdef CONFIG_80211AC_VHT #define REGSTY_IS_11AC_ENABLE(regsty) ((regsty)->vht_enable != 0) #define REGSTY_IS_11AC_AUTO(regsty) ((regsty)->vht_enable == 2) +#define REGSTY_IS_11AC_24G_ENABLE(regsty) ((regsty)->vht_24g_enable != 0) +#else +#define REGSTY_IS_11AC_ENABLE(regsty) 0 +#define REGSTY_IS_11AC_AUTO(regsty) 0 +#define REGSTY_IS_11AC_24G_ENABLE(regsty) 0 +#endif + +#ifdef CONFIG_REGD_SRC_FROM_OS +#define REGSTY_REGD_SRC_FROM_OS(regsty) ((regsty)->regd_src == REGD_SRC_OS) +#else +#define REGSTY_REGD_SRC_FROM_OS(regsty) 0 +#endif typedef struct rtw_if_operations { int __must_check (*read)(struct dvobj_priv *d, unsigned int addr, void *buf, @@ -790,6 +838,7 @@ struct rtw_traffic_statistics { #define SEC_CAP_CHK_BMC BIT0 #define SEC_CAP_CHK_EXTRA_SEC BIT1 /* 256 bit */ +#define SEC_CAP_CHK_WRITE_CAM_NEW_RULE BIT2 #define MACID_DROP BIT0 #define MACID_DROP_INDIRECT BIT1 @@ -954,12 +1003,34 @@ struct macid_ctl_t { #define OFFCHS_LEAVE_OP 2 #define OFFCHS_BACKING_OP 3 +#define TPC_MODE_DISABLE 0 +#define TPC_MODE_MANUAL 1 +#define TPC_MODE_INVALID 2 /* keep last */ + +#define TPC_MANUAL_CONSTRAINT_MAX 600 /* mB */ + struct rf_ctl_t { + enum regd_src_t regd_src; const struct country_chplan *country_ent; u8 ChannelPlan; u8 max_chan_nums; RT_CHANNEL_INFO channel_set[MAX_CHANNEL_NUM]; + struct op_class_pref_t **spt_op_class_ch; + u8 cap_spt_op_class_num; + u8 reg_spt_op_class_num; + u8 cur_spt_op_class_num; struct p2p_channels channel_list; +#ifdef CONFIG_RTW_MBO + struct npref_ch_rtp ch_rtp; +#endif + + s16 antenna_gain; /* mBi */ + + u8 op_class; + u8 op_ch; + s16 op_txpwr_max; /* EIRP in mBm */ + u8 if_op_class[CONFIG_IFACE_NUMBER]; + u8 if_op_ch[CONFIG_IFACE_NUMBER]; _mutex offch_mutex; u8 offch_state; @@ -986,13 +1057,21 @@ struct rf_ctl_t { u8 txpwr_lmt_5g_20_40_ref; #endif #endif + u8 tpc_mode; + u16 tpc_manual_constraint; /* mB */ bool ch_sel_within_same_band; #if CONFIG_DFS u8 csa_ch; + u8 csa_switch_cnt; + u8 csa_ch_offset; + u8 csa_ch_width; + u8 csa_ch_freq_seg0; /* Channel Center Frequency Segment 0 */ + u8 csa_ch_freq_seg1; /* Channel Center Frequency Segment 1 */ #ifdef CONFIG_DFS_MASTER + u8 dfs_region_domain; _timer radar_detect_timer; bool radar_detect_by_others; u8 radar_detect_enabled; @@ -1009,6 +1088,7 @@ struct rf_ctl_t { #if CONFIG_DFS_SLAVE_WITH_RADAR_DETECT u8 dfs_slave_with_rd; #endif + u8 dfs_ch_sel_e_flags; u8 dfs_ch_sel_d_flags; u8 dbg_dfs_fake_radar_detect_cnt; @@ -1069,6 +1149,13 @@ struct halmac_indicator { struct halmacpriv { /* flags */ +#ifdef CONFIG_SDIO_HCI + /* + * Indirect Access for SDIO, + * 0:default, 1:enable, 2:disable + */ + u8 sdio_io_indir; +#endif /* CONFIG_SDIO_HCI */ /* For asynchronous functions */ struct halmac_indicator *indicator; @@ -1154,6 +1241,14 @@ struct dvobj_priv { unsigned char oper_ch_offset;/* PRIME_CHNL_OFFSET */ systime on_oper_ch_time; + u8 union_ch; + u8 union_bw; + u8 union_offset; + /* backup values when union_ch is set to 0 */ + u8 union_ch_bak; + u8 union_bw_bak; + u8 union_offset_bak; + _adapter *padapters[CONFIG_IFACE_NUMBER];/*IFACE_ID_MAX*/ u8 iface_nums; /* total number of ifaces used runtime */ struct mi_state iface_state; @@ -1258,6 +1353,11 @@ struct dvobj_priv { INTF_OPS intf_ops; #endif +#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT + u8 tx_aval_int_thr_mode;/* if 0=>threhold set by reques(default) ;if 1=>fixed by proc; if 2: fixed by sdio_tx_max_len */ + u8 tx_aval_int_thr_value; +#endif/*CONFIG_SDIO_TX_ENABLE_AVAL_INT*/ + /*-------- below is for USB INTERFACE --------*/ #ifdef CONFIG_USB_HCI @@ -1307,7 +1407,7 @@ struct dvobj_priv { /* PCI IO map */ unsigned long pci_base_addr; /* device I/O address */ -#ifdef RTK_129X_PLATFORM +#ifdef CONFIG_PLATFORM_RTK129X unsigned long ctrl_start; /* PCI MASK addr */ unsigned long mask_addr; @@ -1354,6 +1454,14 @@ struct dvobj_priv { #ifdef CONFIG_PROTSEL_MACSLEEP struct protsel protsel_macsleep; #endif +#ifdef CONFIG_WOWLAN + u8 bcn_ctrl_clint3_bf_suspend; + u16 rxfltmap2_bf_suspend; + u8 lifetime_en; + u32 pkt_lifetime; + u32 rcr_bf_suspend; + u32 cr_ext_bf_suspend; +#endif /* CONFIG_WOWLAN */ }; #define DEV_STA_NUM(_dvobj) MSTATE_STA_NUM(&((_dvobj)->iface_state)) @@ -1374,9 +1482,10 @@ struct dvobj_priv { #define DEV_WPS_NUM(_dvobj) MSTATE_WPS_NUM(&((_dvobj)->iface_state)) #define DEV_ROCH_NUM(_dvobj) MSTATE_ROCH_NUM(&((_dvobj)->iface_state)) #define DEV_MGMT_TX_NUM(_dvobj) MSTATE_MGMT_TX_NUM(&((_dvobj)->iface_state)) -#define DEV_U_CH(_dvobj) MSTATE_U_CH(&((_dvobj)->iface_state)) -#define DEV_U_BW(_dvobj) MSTATE_U_BW(&((_dvobj)->iface_state)) -#define DEV_U_OFFSET(_dvobj) MSTATE_U_OFFSET(&((_dvobj)->iface_state)) + +#define DEV_U_CH(_dvobj) ((_dvobj)->union_ch) +#define DEV_U_BW(_dvobj) ((_dvobj)->union_bw) +#define DEV_U_OFFSET(_dvobj) ((_dvobj)->union_offset) #define dvobj_to_pwrctl(dvobj) (&(dvobj->pwrctl_priv)) #define pwrctl_to_dvobj(pwrctl) container_of(pwrctl, struct dvobj_priv, pwrctl_priv) @@ -1535,11 +1644,10 @@ struct _ADAPTER { struct hostapd_priv *phostapdpriv; #endif -#ifdef CONFIG_IOCTL_CFG80211 -#ifdef CONFIG_P2P - struct cfg80211_wifidirect_info cfg80211_wdinfo; -#endif /* CONFIG_P2P */ -#endif /* CONFIG_IOCTL_CFG80211 */ +#if defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE) || defined(CONFIG_IOCTL_CFG80211) + struct roch_info rochinfo; +#endif + u32 setband; ATOMIC_T bandskip; @@ -1607,15 +1715,6 @@ struct _ADAPTER { #ifdef PLATFORM_LINUX _nic_hdl pnetdev; char old_ifname[IFNAMSIZ]; - - /* used by rtw_rereg_nd_name related function */ - struct rereg_nd_name_data { - _nic_hdl old_pnetdev; - char old_ifname[IFNAMSIZ]; - u8 old_ips_mode; - u8 old_bRegUseLed; - } rereg_nd_name_priv; - u8 ndev_unregistering; int bup; struct net_device_stats stats; @@ -1637,6 +1736,12 @@ struct _ADAPTER { #endif /* CONFIG_IOCTL_CFG80211 */ +#ifdef CONFIG_PLATFORM_CMAP_INTFS + void *cmap_bss_status_evt; + u32 cmap_bss_status_evt_len; + u8 cmap_unassoc_sta_measure_en; +#endif + #endif /* PLATFORM_LINUX */ #ifdef PLATFORM_FREEBSD @@ -1697,6 +1802,10 @@ struct _ADAPTER { #endif #ifdef CONFIG_AP_MODE u8 bmc_tx_rate; + #if CONFIG_RTW_AP_DATA_BMC_TO_UC + u8 b2u_flags_ap_src; + u8 b2u_flags_ap_fwd; + #endif #endif /* for debug purpose */ @@ -1744,6 +1853,25 @@ struct _ADAPTER { struct mcc_adapter_priv mcc_adapterpriv; #endif /* CONFIG_MCC_MODE */ +#ifdef CONFIG_RTW_WDS + bool use_wds; /* for STA, AP mode */ + + /* for STA mode */ + struct rtw_wds_gptr_table *wds_gpt_records; + ATOMIC_T wds_gpt_record_num; + + /* for AP mode */ + #ifdef CONFIG_AP_MODE + struct rtw_wds_table *wds_paths; + ATOMIC_T wds_path_num; + #endif +#endif /* CONFIG_RTW_WDS */ + +#ifdef CONFIG_RTW_MULTI_AP + u8 multi_ap; + u8 ch_util_threshold; +#endif + #ifdef CONFIG_RTW_MESH struct rtw_mesh_cfg mesh_cfg; struct rtw_mesh_info mesh_info; @@ -1760,6 +1888,10 @@ struct _ADAPTER { u8 tbtx_capability; u32 tbtx_duration; #endif /* CONFIG_RTW_TOKEN_BASED_XMIT */ + +#ifdef RTW_SIMPLE_CONFIG + u8 rtw_simple_config; +#endif }; #define adapter_to_dvobj(adapter) ((adapter)->dvobj) @@ -1775,6 +1907,16 @@ struct _ADAPTER { #define adapter_to_rfctl(adapter) dvobj_to_rfctl(adapter_to_dvobj((adapter))) #define adapter_to_macidctl(adapter) dvobj_to_macidctl(adapter_to_dvobj((adapter))) +#ifdef CONFIG_RTW_WDS +#define adapter_use_wds(adapter) (adapter->use_wds) +#define adapter_set_use_wds(adapter, en) do { \ + (adapter)->use_wds = (en) ? 1 : 0; \ + RTW_INFO(FUNC_ADPT_FMT" set use_wds=%d\n", FUNC_ADPT_ARG(adapter), (adapter)->use_wds); \ + } while (0) +#else +#define adapter_use_wds(adapter) 0 +#endif + #define adapter_mac_addr(adapter) (adapter->mac_addr) #ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI #define adapter_pno_mac_addr(adapter) \ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_btcoex.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_btcoex.h index 8756a046d8e8..0989629dd2aa 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_btcoex.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_btcoex.h @@ -50,6 +50,7 @@ void hal_btcoex_ConnectNotify(PADAPTER padapter, u8 action); void hal_btcoex_MediaStatusNotify(PADAPTER padapter, u8 mediaStatus); void hal_btcoex_SpecialPacketNotify(PADAPTER padapter, u8 pktType); void hal_btcoex_IQKNotify(PADAPTER padapter, u8 state); +void hal_btcoex_WLRFKNotify(PADAPTER padapter, u8 path, u8 type, u8 state); void hal_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf); void hal_btcoex_BtMpRptNotify(PADAPTER padapter, u8 length, u8 *tmpBuf); void hal_btcoex_SuspendNotify(PADAPTER padapter, u8 state); @@ -62,6 +63,7 @@ s32 hal_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter); s32 hal_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER padapter); u32 hal_btcoex_GetAMPDUSize(PADAPTER padapter); void hal_btcoex_SetManualControl(PADAPTER padapter, u8 bmanual); +void hal_btcoex_set_policy_control(PADAPTER padapter, u8 btc_policy); u8 hal_btcoex_1Ant(PADAPTER padapter); u8 hal_btcoex_IsBtControlLps(PADAPTER); u8 hal_btcoex_IsLpsOn(PADAPTER); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_btcoex_wifionly.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_btcoex_wifionly.h index 3f00061a0933..38e54ff61464 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_btcoex_wifionly.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_btcoex_wifionly.h @@ -20,14 +20,15 @@ #include /* Define the ICs that support wifi only cfg in coex. codes */ -#if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) +#if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) \ +|| defined(CONFIG_RTL8723F) #define CONFIG_BTCOEX_SUPPORT_WIFI_ONLY_CFG 1 #else #define CONFIG_BTCOEX_SUPPORT_WIFI_ONLY_CFG 0 #endif /* Define the ICs that support hal btc common file structure */ -#if defined(CONFIG_RTL8822C) || (defined(CONFIG_RTL8192F) && defined(CONFIG_BT_COEXIST)) +#if defined(CONFIG_RTL8822C) || (defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8723F)&& defined(CONFIG_BT_COEXIST)) #define CONFIG_BTCOEX_SUPPORT_BTC_CMN 1 #else #define CONFIG_BTCOEX_SUPPORT_BTC_CMN 0 diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com.h index 9e071c6f5098..bec4a66a2550 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com.h @@ -119,6 +119,7 @@ #define DESC_RATEVHTSS4MCS7 0x51 #define DESC_RATEVHTSS4MCS8 0x52 #define DESC_RATEVHTSS4MCS9 0x53 +#define DESC_RATE_NUM 0x54 #define IS_CCK_HRATE(_rate) ((_rate) <= DESC_RATE11M) #define IS_OFDM_HRATE(_rate) ((_rate) >= DESC_RATE6M && (_rate) <= DESC_RATE54M) @@ -143,92 +144,8 @@ #define HRARE_SS_NUM(_rate) (IS_1SS_HRATE(_rate) ? 1 : (IS_2SS_HRATE(_rate) ? 2 : (IS_3SS_HRATE(_rate) ? 3 : (IS_4SS_HRATE(_rate) ? 4 : 0)))) -#define HDATA_RATE(rate)\ - (rate == DESC_RATE1M) ? "CCK_1M" :\ - (rate == DESC_RATE2M) ? "CCK_2M" :\ - (rate == DESC_RATE5_5M) ? "CCK5_5M" :\ - (rate == DESC_RATE11M) ? "CCK_11M" :\ - (rate == DESC_RATE6M) ? "OFDM_6M" :\ - (rate == DESC_RATE9M) ? "OFDM_9M" :\ - (rate == DESC_RATE12M) ? "OFDM_12M" :\ - (rate == DESC_RATE18M) ? "OFDM_18M" :\ - (rate == DESC_RATE24M) ? "OFDM_24M" :\ - (rate == DESC_RATE36M) ? "OFDM_36M" :\ - (rate == DESC_RATE48M) ? "OFDM_48M" :\ - (rate == DESC_RATE54M) ? "OFDM_54M" :\ - (rate == DESC_RATEMCS0) ? "MCS0" :\ - (rate == DESC_RATEMCS1) ? "MCS1" :\ - (rate == DESC_RATEMCS2) ? "MCS2" :\ - (rate == DESC_RATEMCS3) ? "MCS3" :\ - (rate == DESC_RATEMCS4) ? "MCS4" :\ - (rate == DESC_RATEMCS5) ? "MCS5" :\ - (rate == DESC_RATEMCS6) ? "MCS6" :\ - (rate == DESC_RATEMCS7) ? "MCS7" :\ - (rate == DESC_RATEMCS8) ? "MCS8" :\ - (rate == DESC_RATEMCS9) ? "MCS9" :\ - (rate == DESC_RATEMCS10) ? "MCS10" :\ - (rate == DESC_RATEMCS11) ? "MCS11" :\ - (rate == DESC_RATEMCS12) ? "MCS12" :\ - (rate == DESC_RATEMCS13) ? "MCS13" :\ - (rate == DESC_RATEMCS14) ? "MCS14" :\ - (rate == DESC_RATEMCS15) ? "MCS15" :\ - (rate == DESC_RATEMCS16) ? "MCS16" :\ - (rate == DESC_RATEMCS17) ? "MCS17" :\ - (rate == DESC_RATEMCS18) ? "MCS18" :\ - (rate == DESC_RATEMCS19) ? "MCS19" :\ - (rate == DESC_RATEMCS20) ? "MCS20" :\ - (rate == DESC_RATEMCS21) ? "MCS21" :\ - (rate == DESC_RATEMCS22) ? "MCS22" :\ - (rate == DESC_RATEMCS23) ? "MCS23" :\ - (rate == DESC_RATEMCS24) ? "MCS24" :\ - (rate == DESC_RATEMCS25) ? "MCS25" :\ - (rate == DESC_RATEMCS26) ? "MCS26" :\ - (rate == DESC_RATEMCS27) ? "MCS27" :\ - (rate == DESC_RATEMCS28) ? "MCS28" :\ - (rate == DESC_RATEMCS29) ? "MCS29" :\ - (rate == DESC_RATEMCS30) ? "MCS30" :\ - (rate == DESC_RATEMCS31) ? "MCS31" :\ - (rate == DESC_RATEVHTSS1MCS0) ? "VHTSS1MCS0" :\ - (rate == DESC_RATEVHTSS1MCS1) ? "VHTSS1MCS1" :\ - (rate == DESC_RATEVHTSS1MCS2) ? "VHTSS1MCS2" :\ - (rate == DESC_RATEVHTSS1MCS3) ? "VHTSS1MCS3" :\ - (rate == DESC_RATEVHTSS1MCS4) ? "VHTSS1MCS4" :\ - (rate == DESC_RATEVHTSS1MCS5) ? "VHTSS1MCS5" :\ - (rate == DESC_RATEVHTSS1MCS6) ? "VHTSS1MCS6" :\ - (rate == DESC_RATEVHTSS1MCS7) ? "VHTSS1MCS7" :\ - (rate == DESC_RATEVHTSS1MCS8) ? "VHTSS1MCS8" :\ - (rate == DESC_RATEVHTSS1MCS9) ? "VHTSS1MCS9" :\ - (rate == DESC_RATEVHTSS2MCS0) ? "VHTSS2MCS0" :\ - (rate == DESC_RATEVHTSS2MCS1) ? "VHTSS2MCS1" :\ - (rate == DESC_RATEVHTSS2MCS2) ? "VHTSS2MCS2" :\ - (rate == DESC_RATEVHTSS2MCS3) ? "VHTSS2MCS3" :\ - (rate == DESC_RATEVHTSS2MCS4) ? "VHTSS2MCS4" :\ - (rate == DESC_RATEVHTSS2MCS5) ? "VHTSS2MCS5" :\ - (rate == DESC_RATEVHTSS2MCS6) ? "VHTSS2MCS6" :\ - (rate == DESC_RATEVHTSS2MCS7) ? "VHTSS2MCS7" :\ - (rate == DESC_RATEVHTSS2MCS8) ? "VHTSS2MCS8" :\ - (rate == DESC_RATEVHTSS2MCS9) ? "VHTSS2MCS9" :\ - (rate == DESC_RATEVHTSS3MCS0) ? "VHTSS3MCS0" :\ - (rate == DESC_RATEVHTSS3MCS1) ? "VHTSS3MCS1" :\ - (rate == DESC_RATEVHTSS3MCS2) ? "VHTSS3MCS2" :\ - (rate == DESC_RATEVHTSS3MCS3) ? "VHTSS3MCS3" :\ - (rate == DESC_RATEVHTSS3MCS4) ? "VHTSS3MCS4" :\ - (rate == DESC_RATEVHTSS3MCS5) ? "VHTSS3MCS5" :\ - (rate == DESC_RATEVHTSS3MCS6) ? "VHTSS3MCS6" :\ - (rate == DESC_RATEVHTSS3MCS7) ? "VHTSS3MCS7" :\ - (rate == DESC_RATEVHTSS3MCS8) ? "VHTSS3MCS8" :\ - (rate == DESC_RATEVHTSS3MCS9) ? "VHTSS3MCS9" :\ - (rate == DESC_RATEVHTSS4MCS0) ? "VHTSS4MCS0" :\ - (rate == DESC_RATEVHTSS4MCS1) ? "VHTSS4MCS1" :\ - (rate == DESC_RATEVHTSS4MCS2) ? "VHTSS4MCS2" :\ - (rate == DESC_RATEVHTSS4MCS3) ? "VHTSS4MCS3" :\ - (rate == DESC_RATEVHTSS4MCS4) ? "VHTSS4MCS4" :\ - (rate == DESC_RATEVHTSS4MCS5) ? "VHTSS4MCS5" :\ - (rate == DESC_RATEVHTSS4MCS6) ? "VHTSS4MCS6" :\ - (rate == DESC_RATEVHTSS4MCS7) ? "VHTSS4MCS7" :\ - (rate == DESC_RATEVHTSS4MCS8) ? "VHTSS4MCS8" :\ - (rate == DESC_RATEVHTSS4MCS9) ? "VHTSS4MCS9" :\ - "UNKNOWN" +extern const char * const _HDATA_RATE[]; +#define HDATA_RATE(rate) ((rate) >= DESC_RATE_NUM ? _HDATA_RATE[DESC_RATE_NUM] : _HDATA_RATE[rate]) enum { UP_LINK, @@ -269,11 +186,20 @@ typedef enum _WAKEUP_REASON{ RTIME_FAIL_DMA_IDLE = 0x42, RTIME_FAIL_DMA_PAUSE = 0x43, RX_PNO = 0x55, + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + WOW_KEEPALIVE_ACK_TIMEOUT = 0x60, + WOW_KEEPALIVE_WAKE = 0x61, + #endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ AP_OFFLOAD_WAKEUP = 0x66, CLK_32K_UNLOCK = 0xFD, CLK_32K_LOCK = 0xFE }WAKEUP_REASON; +typedef enum _BCN_EARLY_INT_CASE{ + TDLS_BCN_ERLY_ON, + TDLS_BCN_ERLY_OFF +}BCN_EARLY_INT_CASE; + /* * Queue Select Value in TxDesc * */ @@ -311,7 +237,7 @@ struct dbg_rx_counter { u8 rtw_hal_get_port(_adapter *adapter); #ifdef CONFIG_MBSSID_CAM - #define DBG_MBID_CAM_DUMP + /*#define DBG_MBID_CAM_DUMP*/ void rtw_mbid_cam_init(struct dvobj_priv *dvobj); void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj); @@ -402,7 +328,6 @@ void hal_com_config_channel_plan( u8 hw_chplan, char *sw_alpha2, u8 sw_chplan, - u8 def_chplan, BOOLEAN AutoLoadFail ); @@ -418,9 +343,12 @@ HAL_IsLegalChannel( u32 Channel ); -u8 MRateToHwRate(u8 rate); +u8 MRateToHwRate(enum MGN_RATE rate); -u8 hw_rate_to_m_rate(u8 rate); +u8 hw_rate_to_m_rate(u8 hw_rate); +#ifdef CONFIG_RTW_DEBUG +void dump_hw_rate_map_test(void *sel); +#endif void HalSetBrateCfg( PADAPTER Adapter, @@ -470,6 +398,7 @@ u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit); u8 rtw_hal_rcr_add(_adapter *adapter, u32 add); u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear); void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action); +void rtw_hal_rcr_set_chk_bssid_act_non(_adapter *adapter); void rtw_iface_enable_tsf_update(_adapter *adapter); void rtw_iface_disable_tsf_update(_adapter *adapter); @@ -619,9 +548,11 @@ void rtw_hal_ch_sw_iqk_info_backup(_adapter *adapter); void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case); #ifdef CONFIG_GPIO_WAKEUP - void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable); - void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval); - void rtw_hal_set_input_gpio(_adapter *padapter, u8 index); +void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable); +void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval); +void rtw_hal_set_input_gpio(_adapter *padapter, u8 index); +#define GPIO_OUTPUT_LOW 0 +#define GPIO_OUTPUT_HIGH 1 #endif #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE @@ -670,6 +601,7 @@ enum lps_pg_hdl_id { LPS_PG_PHYDM_EN, }; +u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter); u8 rtw_hal_set_lps_pg_info(_adapter *adapter); #endif @@ -687,9 +619,9 @@ struct rtl_wow_pattern { }; void rtw_wow_pattern_cam_dump(_adapter *adapter); +void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx); #ifdef CONFIG_WOW_PATTERN_HW_CAM void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context); -void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx); #endif struct rtw_ndp_info { @@ -711,7 +643,9 @@ struct rtw_ndp_info { SET_BITS_TO_LE_4BYTE(target + 2, 0, 8, _value) #endif /*CONFIG_WOWLAN*/ +#ifdef CONFIG_PROC_DEBUG void rtw_dump_phy_cap(void *sel, _adapter *adapter); +#endif void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num); #ifdef CONFIG_SUPPORT_FIFO_DUMP void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size); @@ -766,7 +700,8 @@ void rtw_hal_beamforming_config_csirate(PADAPTER adapter); #endif #endif -u8 phy_get_current_tx_num(PADAPTER pAdapter, u8 Rate); +u8 phy_get_capable_tx_num(_adapter *adapter, enum MGN_RATE rate); +u8 phy_get_current_tx_num(_adapter *adapter, enum MGN_RATE rate); #ifdef CONFIG_RTL8812A u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com_h2c.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com_h2c.h index 7ca79e0f0a4c..90581fdfa761 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com_h2c.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com_h2c.h @@ -110,10 +110,19 @@ enum h2c_cmd { H2C_D0_SCAN_OFFLOAD_INFO = 0x86, H2C_CHNL_SWITCH_OFFLOAD = 0x87, H2C_AOAC_RSVDPAGE3 = 0x88, + H2C_GPIO_CUSTOM = 0x89, H2C_P2P_OFFLOAD_RSVD_PAGE = 0x8A, H2C_P2P_OFFLOAD = 0x8B, + H2C_WAR_OFFLOAD = 0x8D, + H2C_WAROFLD_RSVDPAGE1 = 0x8E, +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + H2C_UDP_KEEPALIVE = 0x90, +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ #ifdef CONFIG_FW_HANDLE_TXBCN H2C_FW_BCN_OFFLOAD = 0xBA, +#endif +#ifdef CONFIG_SUPPORT_DYNAMIC_TXPWR + H2C_FW_CRC5_SEARCH = 0xBB, #endif H2C_RESET_TSF = 0xC0, #ifdef CONFIG_FW_CORRECT_BCN @@ -122,6 +131,7 @@ enum h2c_cmd { H2C_CUSTOMER_STR_W1 = 0xC6, H2C_CUSTOMER_STR_W2 = 0xC7, H2C_CUSTOMER_STR_W3 = 0xC8, + H2C_BT_UNKNOWN_DEVICE_WA = 0xD1, #ifdef DBG_FW_DEBUG_MSG_PKT H2C_FW_DBG_MSG_PKT = 0xE1, #endif /*DBG_FW_DEBUG_MSG_PKT*/ @@ -136,7 +146,11 @@ enum h2c_cmd { #else #define H2C_MEDIA_STATUS_RPT_LEN 3 #endif +#define H2C_GPIO_CUSTOM_LEN 3 #define H2C_KEEP_ALIVE_CTRL_LEN 2 +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +#define H2C_KEEP_ALIVE_PATTERN_LEN 7 +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ #define H2C_DISCON_DECISION_LEN 3 #define H2C_AP_OFFLOAD_LEN 3 #define H2C_AP_WOW_GPIO_CTRL_LEN 4 @@ -191,11 +205,23 @@ enum h2c_cmd { #define H2C_FW_DBG_MSG_PKT_LEN 2 #endif /*DBG_FW_DEBUG_MSG_PKT*/ -#define H2C_SINGLE_CHANNELSWITCH_V2_LEN 2 +#define H2C_SINGLE_CHANNELSWITCH_V2_LEN 3 +#define H2C_BT_UNKNOWN_DEVICE_WA_LEN 1 + +#ifdef CONFIG_SUPPORT_DYNAMIC_TXPWR +#define H2C_FW_CRC5_SEARCH_LEN 7 +#endif + +#ifdef CONFIG_WAR_OFFLOAD +#define H2C_WAR_OFFLOAD_LEN 3 +#define H2C_WAROFLD_RSVDPAGE1_LEN 6 +#endif /* CONFIG_WAR_OFFLOAD */ + #define eq_mac_addr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1 : 0) #define cp_mac_addr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5]) #define cpIpAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3]) +#define cpIpv6Addr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5], (des)[6] = (src)[6], (des)[7] = (src)[7], (des)[8] = (src)[8], (des)[9] = (src)[9], (des)[10] = (src)[10], (des)[11] = (src)[11], (des)[12] = (src)[12], (des)[13] = (src)[13], (des)[14] = (src)[14], (des)[15] = (src)[15]) #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) @@ -250,6 +276,40 @@ enum h2c_cmd { #define GET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(__pH2CCmd) LE_BITS_TO_1BYTE(((u8 *)(__pH2CCmd)), 3, 1) #define GET_H2CCMD_MSRRPT_PARM_ROLE(__pH2CCmd) LE_BITS_TO_1BYTE(((u8 *)(__pH2CCmd)), 4, 4) +#ifdef CONFIG_WAR_OFFLOAD +#define SET_IPHDR_VERSION(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 0, __Value) +#define SET_IPHDR_DSCP(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 1, __Value) +#define SET_IPHDR_TOTAL_LEN(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 2, __Value) +#define SET_IPHDR_IDENTIFIER(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 4, __Value) +#define SET_IPHDR_FLAGS(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 6, __Value) +#define SET_IPHDR_FRAG_OFFSET(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 7, __Value) +#define SET_IPHDR_TTL(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 8, __Value) +#define SET_IPHDR_PROTOCOL(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 9, __Value) +#define SET_IPHDR_HDR_CHECKSUM(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 10, __Value) +#define SET_IPHDR_SRC_IP_ADDR(__pHeader, __Value) cpIpAddr(((u8 *)(__pHeader))+12, (u8 *)(__Value)) +#define SET_IPHDR_DST_IP_ADDR(__pHeader, __Value) cpIpAddr(((u8 *)(__pHeader))+16, (u8 *)(__Value)) +#define SET_UDP_SRC_PORT(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 0, __Value) +#define SET_UDP_DST_PORT(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 2, __Value) +#define SET_UDP_LEN(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 4, __Value) +#define SET_UDP_CHECKSUM(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 6, __Value) + +#define SET_MDNS_HDR_FLAG(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 2, __Value) + +#endif /* CONFIG_WAR_OFFLOAD */ + +#ifdef CONFIG_OFFLOAD_MDNS_V6 +#define SET_IPHDRV6_VERSION(__pHeader, __Value) SET_BITS_TO_LE_1BYTE(__pHeader, 4, 4, __Value) +#define SET_IPHDRV6_TRAFFIC_CLASS(__pHeader, __Value) SET_BITS_TO_LE_2BYTE(__pHeader, 4, 8, __Value) +#define SET_IPHDRV6_FLOW_LABEL(__pHeader, __Value) SET_BITS_TO_LE_4BYTE(__pHeader, 12, 20, __Value) +#define SET_IPHDRV6_PAYLOAD_LENGTH(__pHeader, __Value) SET_BITS_TO_LE_2BYTE(((u8 *)(__pHeader)) + 4, 0, 16, __Value) +#define SET_IPHDRV6_NEXT_HEADER(__pHeader, __Value) SET_BITS_TO_LE_1BYTE((__pHeader) + 6, 0, 8, __Value) +#define SET_IPHDRV6_HOP_LIMIT(__pHeader, __Value) SET_BITS_TO_LE_1BYTE((__pHeader) + 7, 0, 8, __Value) +#define SET_IPHDRV6_SRC_IP_ADDR(__pHeader, __Value) cpIpv6Addr((u8 *)(__pHeader) + 8, (u8 *)(__Value)) +#define SET_IPHDRV6_DST_IP_ADDR(__pHeader, __Value) cpIpv6Addr((u8 *)(__pHeader) + 24, (u8 *)(__Value)) +#endif + + + #define H2C_MSR_ROLE_RSVD 0 #define H2C_MSR_ROLE_STA 1 #define H2C_MSR_ROLE_AP 2 @@ -290,6 +350,26 @@ s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool #define SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 8, __Value) #define SET_H2CCMD_DISCONDECISION_PARM_TRY_OK_BCN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) +/*UDP_KEEP_ALIVE 0x90*/ +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +/*data 0*/ +#define SET_H2CCMD_UDP_KEEP_ALIVE_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value); +#define SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 7, __Value); +/*data 1*/ +#define SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 7, 1, __Value); +#define SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 7, __Value); +/*data 2*/ +#define SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 7, 1, __Value); +#define SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_PATTERN_idx(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 7, __Value); +/*data3*/ +#define SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_LOW_BIT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value); +/*data4*/ +#define SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_HI_BIT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+4, 0, 8, __Value); +/*data5*/ +#define SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+5, 0, 8, __Value); +/*data6*/ +#define SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+6, 0, 8, __Value); +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ #ifdef CONFIG_RTW_CUSTOMER_STR #define RTW_CUSTOMER_STR_LEN 16 #define RTW_CUSTOMER_STR_FMT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" @@ -322,10 +402,11 @@ s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs); #endif /* CONFIG_RTW_CUSTOMER_STR */ #ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX -#define H2C_TXPWR_IDX_OFFLOAD_LEN 3 +#define H2C_TXPWR_IDX_OFFLOAD_LEN 4 #define SET_H2CCMD_TXPWR_IDX_CCK(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) #define SET_H2CCMD_TXPWR_IDX_OFDM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd + 1, 0, 8, __Value) -#define SET_H2CCMD_TXPWR_IDX_HT1SS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd + 2, 0, 8, __Value) +#define SET_H2CCMD_TXPWR_IDX_HT1SS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd + 2, 0, 8, __Value) +#define SET_H2CCMD_TXPWR_IDX_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd + 3, 0, 1, __Value) #endif /* _AP_Offload 0x08 */ @@ -335,6 +416,18 @@ s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs); /* _Probersp_RsvdPage 0x0a */ #define SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) /* _Probersp_RsvdPage 0x13 */ + +#define SET_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_H2CCMD_PWRMODE_PARM_RLBM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 4, __Value) +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 4, 4, __Value) +#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_H2CCMD_PWRMODE_PARM_BCN_EARLY_C2H_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 2, 1, __Value) +#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) + +#define GET_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd) LE_BITS_TO_1BYTE(__pH2CCmd, 0, 8) +/* _PWR_MOD_CMD_0x20 */ + #define SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value) #define SET_H2CCMD_AP_WOW_GPIO_CTRL_C2H_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value) #define SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value) @@ -476,7 +569,9 @@ s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs); #define SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) #define SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd) + 1, 0, 4, __Value) #define SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd) + 1, 4, 4, __Value) - +#define SET_H2CCMD_SINGLE_CH_SWITCH_V2_PWR_IDX_UPDATE_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd) + 2, 0, 1, __Value) +#define SET_H2CCMD_SINGLE_CH_SWITCH_V2_IQK_UPDATE_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd) + 2, 1, 1, __Value) +#define SET_H2CCMD_SINGLE_CH_SWITCH_V2_CH_IDX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd) + 2, 4, 4, __Value) #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT) #define SET_H2CCMD_BTC_WL_PORT_ID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value) @@ -556,6 +651,11 @@ s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs); #define SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) #endif /* CONFIG_PNO_SUPPORT */ +/* _GPIO_CUSTOM_CMD_0x89 */ +#define SET_H2CCMD_CUSTOMERID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_H2CCMD_SPECIAL_WAKE_REASON(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_H2CCMD_CUSTOM_WAKE_REASON(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 1, __Value) + #ifdef CONFIG_P2P_WOWLAN /* P2P_RsvdPage_0x8a */ #define SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) @@ -577,6 +677,43 @@ s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs); #define SET_H2CCMD_LPSPG_IQK_INFO_LOC(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd) + 3, 0, 8, __Value)/*Loc_IQK_result*/ #endif +#if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR) +#define SET_H2CCMD_FW_CRC5_SEARCH_EN(cmd, v) \ + SET_BITS_TO_LE_1BYTE((cmd), 0, 1, (v)); +#define SET_H2CCMD_FW_CRC5_SEARCH_MACID(cmd, v) \ + SET_BITS_TO_LE_1BYTE((cmd), 1, 7, (v)); +#define SET_H2CCMD_FW_CRC5_SEARCH_MAC(cmd, mac) \ + do { \ + int __offset = 0; \ + for (__offset = 0; __offset < ETH_ALEN; __offset++) \ + SET_BITS_TO_LE_1BYTE((u8 *)(cmd + __offset), 0, 8, *((u8 *)(mac + __offset))); \ + } while(0) +#endif + +#ifdef CONFIG_WAR_OFFLOAD +/* WarOffload_Info_0x8D */ +#define SET_H2CCMD_WAR_CFG_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_H2CCMD_WAR_CFG_ARP_RSP_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_H2CCMD_WAR_CFG_MDNSV4_RSP_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 2, 1, __Value) +#define SET_H2CCMD_WAR_CFG_MDNSV6_RSP_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 3, 1, __Value) +#define SET_H2CCMD_WAR_CFG_MDNSV4_WAKE_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 6, 1, __Value) +#define SET_H2CCMD_WAR_CFG_MDNSV6_WAKE_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 7, 1, __Value) + +/* H2C_WAROFLD_RSVDPAGE1 */ +#define SET_H2CCMD_WAROFLD_RSVDPAGE1_LOC_PARM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd), 0, 8, __Value) +#endif /* CONFIG_WAR_OFFLOAD */ + + +/* BT_UNKNOWN_DEVICE_WA_0xD1 */ +#define SET_H2CCMD_BT_UNKNOWN_DEVICE_WA_HANG_CHK_EN(__pH2CCmd, __Value) \ + SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_H2CCMD_BT_UNKNOWN_DEVICE_WA_FORCE_IB_EN(__pH2CCmd, __Value) \ + SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_H2CCMD_BT_UNKNOWN_DEVICE_WA_HWID_CHK_EN(__pH2CCmd, __Value) \ + SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#define SET_H2CCMD_BT_UNKNOWN_DEVICE_WA_ONE_TIME_CHK(__pH2CCmd, __Value) \ + SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value) + #ifdef DBG_FW_DEBUG_MSG_PKT #define SET_H2CCMD_FW_DBG_MSG_PKT_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)/*sniffer_dbg_en*/ #define SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) /*loc_debug_packet*/ @@ -618,6 +755,18 @@ typedef struct _RSVDPAGE_LOC { u8 LocSSIDInfo; u8 LocProbePacket; #endif /* CONFIG_PNO_SUPPORT */ +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + u8 LocKeepAlive; +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ +#ifdef CONFIG_WAR_OFFLOAD + u8 LocIpParm; +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) + u8 LocMdnsPara; + u8 LocMdnsv4; + u8 LocMdnsv6; +#endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */ +#endif /* CONFIG_WAR_OFFLOAD */ + #endif /* CONFIG_WOWLAN */ u8 LocApOffloadBCN; #ifdef CONFIG_P2P_WOWLAN @@ -648,7 +797,9 @@ void rsvd_page_cache_free_data(struct rsvd_page_cache_t *cache); void rsvd_page_cache_free(struct rsvd_page_cache_t *cache); #endif +#ifdef CONFIG_WOWLAN void dump_TX_FIFO(PADAPTER padapter, u8 page_num, u16 page_size); +#endif u8 rtw_hal_set_fw_media_status_cmd(_adapter *adapter, u8 mstatus, u8 macid); #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) /* WOW command function */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com_phycfg.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com_phycfg.h index ffaa2abd376d..39afa46cc3c6 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com_phycfg.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com_phycfg.h @@ -88,10 +88,7 @@ PHY_GetRateValuesOfTxPowerByRate( u8 *RateNum ); -u8 -PHY_GetRateIndexOfTxPowerByRate( - u8 Rate -); +u8 phy_get_rate_idx_of_txpwr_by_rate(enum MGN_RATE rate); void phy_set_tx_power_index_by_rate_section( @@ -101,31 +98,16 @@ phy_set_tx_power_index_by_rate_section( u8 RateSection ); -s8 -_PHY_GetTxPowerByRate( - PADAPTER pAdapter, - u8 Band, - enum rf_path RFPath, - u8 RateIndex -); +s8 phy_get_txpwr_by_rate(_adapter *adapter + , BAND_TYPE band, enum rf_path rfpath, RATE_SECTION rs, enum MGN_RATE rate); -s8 -PHY_GetTxPowerByRate( - PADAPTER pAdapter, - u8 Band, - enum rf_path RFPath, - RATE_SECTION rs, - enum MGN_RATE rate -); +s16 phy_get_txpwr_by_rate_single_mbm(_adapter *adapter + , BAND_TYPE band, enum rf_path rfpath, RATE_SECTION rs, enum MGN_RATE rate, bool eirp); +s16 phy_get_txpwr_by_rate_total_mbm(_adapter *adapter + , BAND_TYPE band, RATE_SECTION rs, enum MGN_RATE rate, bool cap, bool eirp); -void -PHY_SetTxPowerByRate( - PADAPTER pAdapter, - u8 Band, - enum rf_path RFPath, - u8 Rate, - s8 Value -); +s16 phy_get_txpwr_by_rate_single_max_mbm(_adapter *adapter, BAND_TYPE band, enum rf_path rfpath, bool eirp); +s16 phy_get_txpwr_by_rate_total_max_mbm(_adapter *adapter, BAND_TYPE band, bool cap, bool eirp); void phy_set_tx_power_level_by_path( @@ -179,16 +161,19 @@ s8 phy_get_txpwr_lmt_diff(_adapter *adapter s8 phy_get_txpwr_lmt_sub_chs(_adapter *adapter , const char *regd_name , BAND_TYPE band, enum channel_width bw - , u8 rfpath, u8 rate, u8 ntx_idx, u8 cch, u8 opch + , u8 rfpath, u8 rate, u8 ntx_idx, u8 cch, u8 opch, bool reg_max ); #else #define phy_get_txpwr_lmt(adapter, regd_name, band, bw, tlrs, ntx_idx, cch, lock) (GET_HAL_SPEC(adapter)->txgi_max) #define phy_get_txpwr_lmt_diff(adapter, regd_name, band, bw, rfpath, rs, tlrs, ntx_idx, cch, lock) (GET_HAL_SPEC(adapter)->txgi_max) -#define phy_get_txpwr_lmt_sub_chs(adapter, regd_name, band, bw, rfpath, rate, ntx_idx, cch, opch) (GET_HAL_SPEC(adapter)->txgi_max) +#define phy_get_txpwr_lmt_sub_chs(adapter, regd_name, band, bw, rfpath, rate, ntx_idx, cch, opch, reg_max) (GET_HAL_SPEC(adapter)->txgi_max) #endif /* CONFIG_TXPWR_LIMIT */ +void dump_txpwr_tpc_settings(void *sel, _adapter *adapter); +void dump_txpwr_antenna_gain(void *sel, _adapter *adapter); + s8 phy_get_txpwr_target(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate, u8 ntx_idx - , enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch, struct txpwr_idx_comp *tic); + , enum channel_width bw, BAND_TYPE band, u8 cch, u8 opch, bool reg_max, struct txpwr_idx_comp *tic); s8 phy_get_txpwr_amends(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate, u8 ntx_idx , enum channel_width bw, BAND_TYPE band, u8 cch, struct txpwr_idx_comp *tic); #ifdef CONFIG_TXPWR_PG_WITH_TSSI_OFFSET @@ -200,14 +185,14 @@ u8 hal_com_get_txpwr_idx(_adapter *adapter, enum rf_path rfpath , struct txpwr_idx_comp *tic); s16 phy_get_txpwr_single_mbm(_adapter *adapter, u8 rfpath, RATE_SECTION rs, u8 rate - , enum channel_width bw, u8 cch, u8 opch, struct txpwr_idx_comp *tic); + , enum channel_width bw, u8 cch, u8 opch, bool reg_max, bool eirp, struct txpwr_idx_comp *tic); s16 phy_get_txpwr_total_mbm(_adapter *adapter, RATE_SECTION rs, u8 rate - , enum channel_width bw, u8 cch, u8 opch, struct txpwr_idx_comp *tic); + , enum channel_width bw, u8 cch, u8 opch, bool reg_max, bool eirp, struct txpwr_idx_comp *tic); s16 phy_get_txpwr_single_max_mbm(_adapter *adapter, u8 rfpath - , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht); + , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool reg_max, bool eirp); s16 phy_get_txpwr_total_max_mbm(_adapter *adapter - , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht); + , enum channel_width bw, u8 cch, u8 opch, u16 bmp_cck_ofdm, u32 bmp_ht, u64 bmp_vht, bool reg_max, bool eirp); s8 phy_get_tx_power_final_absolute_value(_adapter *adapter, u8 rfpath, u8 rate, @@ -230,8 +215,10 @@ struct txpwr_idx_comp { s8 btc; s8 extra; s8 utarget; - s8 limit; - s8 ulimit; + s8 rlimit; /* regulatory limit w/o HAL consideration */ + s8 limit; /* limit from RTK private (regulatory limit w/ HAL consideration) */ + s8 ulimit; /* user limit */ + s8 tpc; /* for amends */ s8 tpt; @@ -264,6 +251,7 @@ bool phy_is_txpwr_user_target_specified(_adapter *adapter); void dump_tx_power_index_inline(void *sel, _adapter *adapter, u8 rfpath , enum channel_width bw, u8 cch, enum MGN_RATE rate, u8 pwr_idx, struct txpwr_idx_comp *tic); +#ifdef CONFIG_PROC_DEBUG void dump_tx_power_idx_title(void *sel, _adapter *adapter , enum channel_width bw, u8 cch, u8 opch); void dump_tx_power_idx_by_path_rs(void *sel, _adapter *adapter, u8 rfpath @@ -276,6 +264,7 @@ void dump_txpwr_total_dbm_by_rs(void *sel, _adapter *adapter, u8 rs , enum channel_width bw, u8 cch, u8 opch); void dump_txpwr_total_dbm(void *sel, _adapter *adapter , enum channel_width bw, u8 cch, u8 opch); +#endif bool phy_is_tx_power_limit_needed(_adapter *adapter); bool phy_is_tx_power_by_rate_needed(_adapter *adapter); @@ -300,9 +289,11 @@ void dump_hal_txpwr_info_5g(void *sel, _adapter *adapter, u8 rfpath_num, u8 max_ void hal_load_txpwr_info(_adapter *adapter); #endif +#ifdef CONFIG_PROC_DEBUG void dump_tx_power_ext_info(void *sel, _adapter *adapter); void dump_target_tx_power(void *sel, _adapter *adapter); void dump_tx_power_by_rate(void *sel, _adapter *adapter); +#endif int rtw_get_phy_file_path(_adapter *adapter, const char *file_name); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com_reg.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com_reg.h index fb283488e301..fe16ef64ff5a 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com_reg.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_com_reg.h @@ -512,9 +512,12 @@ #define REG_WLAN_ACT_MASK_CTRL_1 0x076C /* GPIO Control */ -#define REG_SW_GPIO_SHARE_CTRL 0x1038 +#define REG_SW_GPIO_SHARE_CTRL_0 0x1038 +#define REG_SW_GPIO_SHARE_CTRL_1 0x103C #define REG_SW_GPIO_A_OUT 0x1040 #define REG_SW_GPIO_A_OEN 0x1044 +#define REG_SW_GPIO_B_OEN 0x1058 +#define REG_SW_GPIO_B_OUT 0x105C /* Hardware Port 2 */ #define REG_MACID2 0x1620 @@ -1254,10 +1257,14 @@ Current IOREG MAP /* 2 REG_LED_CFG (Offset 0x004C) */ #define BIT_SW_SPDT_SEL BIT(22) -/* 2 REG_SW_GPIO_SHARE_CTRL (Offset 0x1038) */ +/* 2 REG_SW_GPIO_SHARE_CTRL_0 (Offset 0x1038) */ #define BIT_BTGP_WAKE_LOC (BIT(10) | BIT(11)) #define BIT_SW_GPIO_FUNC BIT(0) +/* 2 REG_SW_GPIO_SHARE_CTRL_1 (Offset 0x103C) */ +#define BIT_WLMAC_DBG_LOC (BIT(9) | BIT(10)) +#define BIT_WL_GPIO_SEL (BIT(30) | BIT(31)) + /* 2 8051FWDL * 2 MCUFWDL */ #define MCUFWDL_EN BIT(0) @@ -1866,6 +1873,7 @@ Current IOREG MAP #define LAST_ENTRY_OF_TX_PKT_BUFFER_8723D 255 #define LAST_ENTRY_OF_TX_PKT_BUFFER_8710B 255 #define LAST_ENTRY_OF_TX_PKT_BUFFER_8192F 255 +#define LAST_ENTRY_OF_TX_PKT_BUFFER_8723F 255 #define POLLING_LLT_THRESHOLD 20 #if defined(CONFIG_RTL8723B) && defined(CONFIG_PCI_HCI) #define POLLING_READY_TIMEOUT_COUNT 6000 diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_data.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_data.h index a9de95f16eed..516836580c4a 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_data.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_data.h @@ -250,9 +250,7 @@ struct hal_spec_t { u8 wl_func; /* value of WL_FUNC_XXX */ -#if CONFIG_TX_AC_LIFETIME u8 tx_aclt_unit_factor; /* how many 32us */ -#endif u8 rx_tsf_filter:1; @@ -411,6 +409,7 @@ typedef struct hal_com_data { u8 max_tx_cnt; u8 tx_nss; /*tx Spatial Streams - GET_HAL_TX_NSS*/ u8 rx_nss; /*rx Spatial Streams - GET_HAL_RX_NSS*/ + u8 txpath_cap_num_nss[4]; /* capable path num for NSS TX, [0] for 1SS, [3] for 4SS */ u8 PackageType; u8 antenna_test; @@ -529,7 +528,8 @@ typedef struct hal_com_data { bool set_entire_txpwr; -#if defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) +#if defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B) \ + || defined(CONFIG_RTL8723F) u32 txagc_set_buf; #endif @@ -673,7 +673,7 @@ typedef struct hal_com_data { /* SDIO Rx FIFO related. */ /* */ u8 SdioRxFIFOCnt; -#ifdef CONFIG_RTL8822C +#if defined (CONFIG_RTL8822C) || defined (CONFIG_RTL8192F) u32 SdioRxFIFOSize; #else u16 SdioRxFIFOSize; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_ic_cfg.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_ic_cfg.h index 8fb94d1c38f4..add47e7ee04e 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_ic_cfg.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_ic_cfg.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************** * - * Copyright(c) 2007 - 2017 Realtek Corporation. + * Copyright(c) 2007 - 2019 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -21,6 +21,7 @@ #define RTL8821A_SUPPORT 0 #define RTL8723B_SUPPORT 0 #define RTL8723D_SUPPORT 0 +#define RTL8723F_SUPPORT 0 #define RTL8192E_SUPPORT 0 #define RTL8192F_SUPPORT 0 #define RTL8814A_SUPPORT 0 @@ -139,6 +140,7 @@ #ifndef CONFIG_TXPWR_PG_WITH_PWR_IDX #define CONFIG_TXPWR_PG_WITH_PWR_IDX #endif + #define CONFIG_STOP_RESUME_BCN_BY_TXPAUSE /*to fixed no bcn issue*/ #endif #ifdef CONFIG_RTL8723B @@ -243,6 +245,10 @@ #ifndef CONFIG_TXPWR_PG_WITH_PWR_IDX #define CONFIG_TXPWR_PG_WITH_PWR_IDX #endif + + #if defined(CONFIG_USB_HCI) && !defined(CONFIG_FW_OFFLOAD_SET_TXPWR_IDX) + #define CONFIG_FW_OFFLOAD_SET_TXPWR_IDX + #endif #endif #ifdef CONFIG_RTL8822B @@ -327,7 +333,7 @@ #define CONFIG_RTS_FULL_BW #ifdef CONFIG_LPS - /* #define CONFIG_LPS_ACK */ /* Supported after FW v30 */ + #define CONFIG_LPS_ACK /* Supported after FW v30 & v27.9 */ #endif #ifndef CONFIG_TXPWR_PG_WITH_PWR_IDX @@ -389,6 +395,7 @@ #ifdef CONFIG_MCC_MODE #define CONFIG_MCC_MODE_V2 + #define CONFIG_MCC_PHYDM_OFFLOAD #endif /* CONFIG_MCC_MODE */ #if defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW) @@ -435,6 +442,8 @@ #endif #define CONFIG_RTL8822C_XCAP_NEW_POLICY + + #define CONFIG_SUPPORT_DYNAMIC_TXPWR #endif /* CONFIG_RTL8822C */ #ifdef CONFIG_RTL8821C @@ -524,7 +533,6 @@ #ifdef CONFIG_CONCURRENT_MODE /*#define CONFIG_AP_PORT_SWAP*/ #define CONFIG_FW_MULTI_PORT_SUPPORT - #define CONFIG_SUPPORT_AP_PORT1 #endif /* CONFIG_CONCURRENT_MODE */ /* @@ -600,5 +608,104 @@ #define CONFIG_TXPWR_PG_WITH_TSSI_OFFSET #endif #endif /* CONFIG_RTL8814B */ +#ifdef CONFIG_RTL8723F + #undef RTL8723F_SUPPORT + #define RTL8723F_SUPPORT 1 + /* Use HALMAC architecture, necessary for 8723F */ + #define RTW_HALMAC + + /*#define DBG_LA_MODE*/ + + #ifndef CONFIG_FW_C2H_PKT + #define CONFIG_FW_C2H_PKT + #endif /* CONFIG_FW_C2H_PKT */ + + #define RTW_TX_PA_BIAS /* Adjust TX PA Bias from eFuse */ + + #ifdef CONFIG_WOWLAN + #define CONFIG_WOW_PATTERN_IN_TXFIFO + #endif + +#if 0 /* todo: 8723F , need to check in the future */ + #ifdef CONFIG_WOWLAN + #define CONFIG_GTK_OL + /*#define CONFIG_ARP_KEEP_ALIVE*/ + + #ifdef CONFIG_GPIO_WAKEUP + #ifndef WAKEUP_GPIO_IDX + #define WAKEUP_GPIO_IDX 6 /* WIFI Chip Side */ + #endif /* !WAKEUP_GPIO_IDX */ + #endif /* CONFIG_GPIO_WAKEUP */ + #endif /* CONFIG_WOWLAN */ +#endif + + #ifdef CONFIG_CONCURRENT_MODE + #define CONFIG_AP_PORT_SWAP + #define CONFIG_FW_MULTI_PORT_SUPPORT + #endif /* CONFIG_CONCURRENT_MODE */ + + #ifdef CONFIG_NO_FW + #ifdef CONFIG_RTW_MAC_HIDDEN_RPT + #undef CONFIG_RTW_MAC_HIDDEN_RPT + #endif + #else + #ifndef CONFIG_RTW_MAC_HIDDEN_RPT + #define CONFIG_RTW_MAC_HIDDEN_RPT + #endif + #endif + + #ifndef DBG_RX_DFRAME_RAW_DATA + #define DBG_RX_DFRAME_RAW_DATA + #endif /* DBG_RX_DFRAME_RAW_DATA */ + + /*#define RTW_IQK_FW_OFFLOAD*/ + #define CONFIG_ADVANCE_OTA + + #ifdef CONFIG_MCC_MODE + #define CONFIG_MCC_MODE_V2 + #define CONFIG_MCC_PHYDM_OFFLOAD + #endif /* CONFIG_MCC_MODE */ + + #if defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW) + #define CONFIG_TDLS_CH_SW_V2 + #endif + + #ifndef RTW_CHANNEL_SWITCH_OFFLOAD + #ifdef CONFIG_TDLS_CH_SW_V2 + #define RTW_CHANNEL_SWITCH_OFFLOAD + #endif + #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */ + + #if defined(CONFIG_RTW_MESH) && !defined(RTW_PER_CMD_SUPPORT_FW) + /* Supported since fw v22.1 */ + #define RTW_PER_CMD_SUPPORT_FW + #endif /* RTW_PER_CMD_SUPPORT_FW */ + #define CONFIG_SUPPORT_FIFO_DUMP + #define CONFIG_HW_P0_TSF_SYNC + #define CONFIG_BCN_RECV_TIME + + /*#define CONFIG_TCP_CSUM_OFFLOAD_TX*/ + #if defined(CONFIG_TCP_CSUM_OFFLOAD_TX) && !defined(CONFIG_RTW_NETIF_SG) + #define CONFIG_RTW_NETIF_SG + #endif + #define CONFIG_TCP_CSUM_OFFLOAD_RX + + #ifdef CONFIG_P2P_PS + #define CONFIG_P2P_PS_NOA_USE_MACID_SLEEP + #endif + + #define CONFIG_RTS_FULL_BW + + #ifdef CONFIG_LPS + #define CONFIG_LPS_ACK + #endif + + #ifndef CONFIG_TXPWR_PG_WITH_PWR_IDX + #define CONFIG_TXPWR_PG_WITH_PWR_IDX + #endif + #ifndef CONFIG_TXPWR_PG_WITH_TSSI_OFFSET + #define CONFIG_TXPWR_PG_WITH_TSSI_OFFSET + #endif +#endif /* CONFIG_RTL8723F */ #endif /*__HAL_IC_CFG_H__*/ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_intf.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_intf.h index f3cd4c8e6a81..05bf4c574b59 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_intf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_intf.h @@ -43,6 +43,7 @@ enum _CHIP_TYPE { RTL8192F, RTL8822C, RTL8814B, + RTL8723F, MAX_CHIP_TYPE }; @@ -109,6 +110,7 @@ typedef enum _HW_VARIABLES { HW_VAR_SET_RPWM, HW_VAR_CPWM, HW_VAR_H2C_FW_PWRMODE, + HW_VAR_H2C_FW_PWRMODE_RFON_CTRL, HW_VAR_H2C_INACTIVE_IPS, HW_VAR_H2C_PS_TUNE_PARAM, HW_VAR_H2C_FW_JOINBSSRPT, @@ -198,11 +200,8 @@ typedef enum _HW_VARIABLES { HW_VAR_MDIO, HW_VAR_L1OFF_CAPABILITY, HW_VAR_L1OFF_NIC_SUPPORT, -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW - HW_VAR_TDLS_BCN_EARLY_C2H_RPT, -#endif -#endif + HW_VAR_BCN_EARLY_C2H_RPT, + HW_VAR_SET_DRV_ERLY_INT, HW_VAR_DUMP_MAC_TXFIFO, HW_VAR_PWR_CMD, #ifdef CONFIG_FW_HANDLE_TXBCN @@ -212,12 +211,16 @@ typedef enum _HW_VARIABLES { HW_VAR_ENABLE_RX_BAR, HW_VAR_TSF_AUTO_SYNC, HW_VAR_LPS_STATE_CHK, + HW_VAR_LPS_RFON_CHK, #ifdef CONFIG_RTS_FULL_BW HW_VAR_SET_RTS_BW, #endif #if defined(CONFIG_PCI_HCI) HW_VAR_ENSWBCN, #endif +#ifdef CONFIG_WOWLAN + HW_VAR_VENDOR_WOW_MODE, +#endif /* CONFIG_WOWLAN */ } HW_VARIABLES; typedef enum _HAL_DEF_VARIABLE { @@ -301,6 +304,9 @@ struct hal_ops { * mgnt_xmit should be implemented to run in interrupt context */ s32(*mgnt_xmit)(_adapter *padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32(*hal_mgmt_xmitframe_enqueue)(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32(*hal_xmitframe_enqueue)(_adapter *padapter, struct xmit_frame *pxmitframe); #ifdef CONFIG_XMIT_THREAD_MODE s32(*xmit_thread_handler)(_adapter *padapter); @@ -519,6 +525,8 @@ typedef enum _HARDWARE_TYPE { HARDWARE_TYPE_RTL8814BE, HARDWARE_TYPE_RTL8814BU, HARDWARE_TYPE_RTL8814BS, + HARDWARE_TYPE_RTL8723FU, + HARDWARE_TYPE_RTL8723FS, HARDWARE_TYPE_MAX, } HARDWARE_TYPE; @@ -651,6 +659,11 @@ typedef enum _HARDWARE_TYPE { #define IS_HARDWARE_TYPE_8814B(_Adapter) \ (IS_HARDWARE_TYPE_8814BE(_Adapter) || IS_HARDWARE_TYPE_8814BU(_Adapter) || IS_HARDWARE_TYPE_8814BS(_Adapter)) +#define IS_HARDWARE_TYPE_8723FU(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8723FU) +#define IS_HARDWARE_TYPE_8723FS(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8723FS) +#define IS_HARDWARE_TYPE_8723F(_Adapter) \ + (IS_HARDWARE_TYPE_8723FU(_Adapter) || IS_HARDWARE_TYPE_8723FS(_Adapter)) + #define IS_HARDWARE_TYPE_JAGUAR2(_Adapter) \ (IS_HARDWARE_TYPE_8814A(_Adapter) || IS_HARDWARE_TYPE_8821B(_Adapter) || IS_HARDWARE_TYPE_8822B(_Adapter) || IS_HARDWARE_TYPE_8821C(_Adapter)) @@ -660,6 +673,8 @@ typedef enum _HARDWARE_TYPE { #define IS_HARDWARE_TYPE_JAGUAR3(_Adapter) \ (IS_HARDWARE_TYPE_8814B(_Adapter) || IS_HARDWARE_TYPE_8822C(_Adapter)) +#define IS_HARDWARE_TYPE_JAGUAR3_11N(_Adapter) IS_HARDWARE_TYPE_8723F(_Adapter) + #define IS_HARDWARE_TYPE_JAGUAR_ALL(_Adapter) \ (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(_Adapter) || IS_HARDWARE_TYPE_JAGUAR3(_Adapter)) @@ -742,6 +757,9 @@ u8 rtw_hal_pci_l1off_capability(_adapter *padapter); u8 rtw_hal_intf_ps_func(_adapter *padapter, HAL_INTF_PS_FUNC efunc_id, u8 *val); +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtw_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtw_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtw_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtw_hal_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_pg.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_pg.h index b995ae255bc5..8d91a64e8575 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_pg.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_pg.h @@ -741,6 +741,47 @@ #define EEPROM_PID_8814BU 0x152 #define EEPROM_USB_OPTIONAL_FUNCTION0_8814BU 0x154 +/* + * ==================================================== + * EEPROM/Efuse PG Offset for 8723F + * ==================================================== + */ +#define EEPROM_TX_PWR_INX_8723F 0x10 +#define EEPROM_ChannelPlan_8723F 0xB8 +#define EEPROM_XTAL_B9_8723F 0xB9 +#define EEPROM_THERMAL_METER_8723F 0xBA +#define EEPROM_IQK_LCK_8723F 0xBB +#define EEPROM_2G_5G_PA_TYPE_8723F 0xBC +/* PATH A & PATH B */ +#define EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8723F 0xBD +/* PATH C & PATH D */ +#define EEPROM_2G_LNA_TYPE_GAIN_SEL_CD_8723F 0xBE +/* PATH A & PATH B */ +#define EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8723F 0xBF +/* PATH C & PATH D */ +#define EEPROM_5G_LNA_TYPE_GAIN_SEL_CD_8723F 0xC0 + +#define EEPROM_RF_BOARD_OPTION_8723F 0xC1 +#define EEPROM_FEATURE_OPTION_8723F 0xC2 +#define EEPROM_RF_BT_SETTING_8723F 0xC3 +#define EEPROM_VERSION_8723F 0xC4 +#define EEPROM_CustomID_8723F 0xC5 +#define EEPROM_TX_BBSWING_2G_8723F 0xC6 +#define EEPROM_TX_PWR_CALIBRATE_RATE_8723F 0xC8 +#define EEPROM_RF_ANTENNA_OPT_8723F 0xC9 +#define EEPROM_RFE_OPTION_8723F 0xCA +#define EEPROM_COUNTRY_CODE_8723F 0xCB + +/* RTL8723FU */ +#define EEPROM_MAC_ADDR_8723FU 0x108 +#define EEPROM_VID_8723FU 0x100 +#define EEPROM_PID_8723FU 0x102 +#define EEPROM_USB_OPTIONAL_FUNCTION0_8723FU 0x104 +#define EEPROM_USB_MODE_8723FU 0x03 + +/* RTL8723FS */ +#define EEPROM_MAC_ADDR_8723FS 0x11A + /* **************************************************** * EEPROM/Efuse Value Type * **************************************************** */ @@ -807,6 +848,7 @@ #define EEPROM_Default_CrystalCap_8723B 0x20 #define EEPROM_Default_CrystalCap_8703B 0x20 #define EEPROM_Default_CrystalCap_8723D 0x20 +#define EEPROM_Default_CrystalCap_8723F 0x3F #define EEPROM_Default_CrystalCap_8188F 0x20 #define EEPROM_Default_CrystalCap_8188GTV 0x20 #define EEPROM_Default_CrystalCap_8192F 0x20 @@ -944,6 +986,7 @@ typedef enum _BT_CoType { BT_RTL8192F = 16, BT_RTL8822C = 17, BT_RTL8814B = 18, + BT_RTL8723F = 19, } BT_CoType, *PBT_CoType; typedef enum _BT_RadioShared { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_sdio.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_sdio.h index b096d70fa401..51df612fa2a7 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_sdio.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/hal_sdio.h @@ -31,9 +31,9 @@ u32 rtw_hal_get_sdio_tx_max_length(PADAPTER padapter, u8 queue_idx); bool sdio_power_on_check(PADAPTER padapter); #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT -#if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) || defined(CONFIG_RTL8821A) +#if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) ||defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8723D) void rtw_hal_sdio_avail_page_threshold_init(_adapter *adapter); -void rtw_hal_sdio_avail_page_threshold_en(_adapter *adapter, u8 qidx); +void rtw_hal_sdio_avail_page_threshold_en(_adapter *adapter, u8 qidx, u8 pg_num); #endif #endif /* CONFIG_SDIO_TX_ENABLE_AVAL_INT */ @@ -41,7 +41,7 @@ void rtw_hal_sdio_avail_page_threshold_en(_adapter *adapter, u8 qidx); void sd_c2h_hisr_hdl(_adapter *adapter); #endif -#if defined(CONFIG_RTL8188F) || defined (CONFIG_RTL8188GTV) || defined (CONFIG_RTL8192F) +#if defined(CONFIG_RTL8188F) || defined (CONFIG_RTL8188GTV) || defined (CONFIG_RTL8192F) || defined(CONFIG_RTL8723D) #define SDIO_LOCAL_CMD_ADDR(addr) ((SDIO_LOCAL_DEVICE_ID << 13) | ((addr) & SDIO_LOCAL_MSK)) #endif @@ -82,4 +82,15 @@ void dbg_rtw_sdio_free_xmitbuf_sema_down(struct xmit_priv *xmit, const char *cal #endif /* SDIO_FREE_XMIT_BUF_SEMA */ #endif /* !CONFIG_SDIO_TX_TASKLET */ +s32 sdio_initrecvbuf(struct recv_buf *recvbuf, _adapter *adapter); +void sdio_freerecvbuf(struct recv_buf *recvbuf); + +#ifdef CONFIG_SDIO_RECVBUF_PWAIT +void dump_recvbuf_pwait_conf(void *sel, struct recv_priv *recvpriv); +#ifdef CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST +int recvbuf_pwait_config_req(struct recv_priv *recvpriv, enum rtw_pwait_type type, s32 time, s32 cnt_lmt); +int recvbuf_pwait_config_hdl(struct recv_priv *recvpriv, struct recv_buf *rbuf); +#endif /* CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST */ +#endif /* CONFIG_SDIO_RECVBUF_PWAIT */ + #endif /* __HAL_SDIO_H_ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/ieee80211.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/ieee80211.h index 9a0c5f02a242..0beaa14b5bb8 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/ieee80211.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/ieee80211.h @@ -27,7 +27,7 @@ #ifdef CONFIG_AP_MODE -#define RTL_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 28) +#define RTL_IOCTL_HOSTAPD (SIOCDEVPRIVATE + 2) /* RTL871X_IOCTL_HOSTAPD ioctl() cmd: */ enum { @@ -56,6 +56,7 @@ enum { RTL871X_HOSTAPD_ACL_ADD_STA = 22, RTL871X_HOSTAPD_ACL_REMOVE_STA = 23, }; +#endif /* CONFIG_AP_MODE */ /* STA flags */ #define WLAN_STA_AUTH BIT(0) @@ -73,10 +74,10 @@ enum { #define WLAN_STA_WPS BIT(12) #define WLAN_STA_MAYBE_WPS BIT(13) #define WLAN_STA_VHT BIT(14) +#define WLAN_STA_WDS BIT(15) +#define WLAN_STA_MULTI_AP BIT(16) #define WLAN_STA_NONERP BIT(31) -#endif - #define IEEE_CMD_SET_WPA_PARAM 1 #define IEEE_CMD_SET_WPA_IE 2 #define IEEE_CMD_SET_ENCRYPTION 3 @@ -500,12 +501,21 @@ struct rtw_ieee80211s_hdr { } __attribute__((packed)); #endif +/* Some IEEE 802.11x packet types are corresponding to parsing_eapol_packet() */ enum eap_type { EAP_PACKET = 0, + NON_EAPOL, EAPOL_START, EAPOL_LOGOFF, EAPOL_KEY, - EAPOL_ENCAP_ASF_ALERT + EAPOL_ENCAP_ASF_ALERT, + EAPOL_PACKET, + EAPOL_WPA_GROUP_KEY_1_2, + EAPOL_WPA_GROUP_KEY_2_2, + EAPOL_1_4, + EAPOL_2_4, + EAPOL_3_4, + EAPOL_4_4, }; #define IEEE80211_3ADDR_LEN 24 @@ -751,6 +761,8 @@ struct ieee80211_snap_hdr { #define WLAN_EID_GENERIC (WLAN_EID_VENDOR_SPECIFIC) #define WLAN_EID_VHT_CAPABILITY 191 #define WLAN_EID_VHT_OPERATION 192 +#define WLAN_EID_WIDE_BANDWIDTH_CHANNEL_SWITCH 194 +#define WLAN_EID_CHANNEL_SWITCH_WRAPPER 196 #define WLAN_EID_VHT_OP_MODE_NOTIFY 199 #define WLAN_EID_EXTENSION 255 #define WLAN_EID_EXT_OWE_DH_PARAM 32 @@ -942,92 +954,7 @@ enum MGN_RATE { #define IS_3T_RATE(_rate) (IS_HT3SS_RATE((_rate)) || IS_VHT3SS_RATE((_rate))) #define IS_4T_RATE(_rate) (IS_HT4SS_RATE((_rate)) || IS_VHT4SS_RATE((_rate))) -#define MGN_RATE_STR(_rate) \ - (_rate == MGN_1M) ? "CCK_1M" : \ - (_rate == MGN_2M) ? "CCK_2M" : \ - (_rate == MGN_5_5M) ? "CCK_5.5M" : \ - (_rate == MGN_11M) ? "CCK_11M" : \ - (_rate == MGN_6M) ? "OFDM_6M" : \ - (_rate == MGN_9M) ? "OFDM_9M" : \ - (_rate == MGN_12M) ? "OFDM_12M" : \ - (_rate == MGN_18M) ? "OFDM_18M" : \ - (_rate == MGN_24M) ? "OFDM_24M" : \ - (_rate == MGN_36M) ? "OFDM_36M" : \ - (_rate == MGN_48M) ? "OFDM_48M" : \ - (_rate == MGN_54M) ? "OFDM_54M" : \ - (_rate == MGN_MCS32) ? "MCS32" : \ - (_rate == MGN_MCS0) ? "MCS0" : \ - (_rate == MGN_MCS1) ? "MCS1" : \ - (_rate == MGN_MCS2) ? "MCS2" : \ - (_rate == MGN_MCS3) ? "MCS3" : \ - (_rate == MGN_MCS4) ? "MCS4" : \ - (_rate == MGN_MCS5) ? "MCS5" : \ - (_rate == MGN_MCS6) ? "MCS6" : \ - (_rate == MGN_MCS7) ? "MCS7" : \ - (_rate == MGN_MCS8) ? "MCS8" : \ - (_rate == MGN_MCS9) ? "MCS9" : \ - (_rate == MGN_MCS10) ? "MCS10" : \ - (_rate == MGN_MCS11) ? "MCS11" : \ - (_rate == MGN_MCS12) ? "MCS12" : \ - (_rate == MGN_MCS13) ? "MCS13" : \ - (_rate == MGN_MCS14) ? "MCS14" : \ - (_rate == MGN_MCS15) ? "MCS15" : \ - (_rate == MGN_MCS16) ? "MCS16" : \ - (_rate == MGN_MCS17) ? "MCS17" : \ - (_rate == MGN_MCS18) ? "MCS18" : \ - (_rate == MGN_MCS19) ? "MCS19" : \ - (_rate == MGN_MCS20) ? "MCS20" : \ - (_rate == MGN_MCS21) ? "MCS21" : \ - (_rate == MGN_MCS22) ? "MCS22" : \ - (_rate == MGN_MCS23) ? "MCS23" : \ - (_rate == MGN_MCS24) ? "MCS24" : \ - (_rate == MGN_MCS25) ? "MCS25" : \ - (_rate == MGN_MCS26) ? "MCS26" : \ - (_rate == MGN_MCS27) ? "MCS27" : \ - (_rate == MGN_MCS28) ? "MCS28" : \ - (_rate == MGN_MCS29) ? "MCS29" : \ - (_rate == MGN_MCS30) ? "MCS30" : \ - (_rate == MGN_MCS31) ? "MCS31" : \ - (_rate == MGN_VHT1SS_MCS0) ? "VHT1SMCS0" : \ - (_rate == MGN_VHT1SS_MCS1) ? "VHT1SMCS1" : \ - (_rate == MGN_VHT1SS_MCS2) ? "VHT1SMCS2" : \ - (_rate == MGN_VHT1SS_MCS3) ? "VHT1SMCS3" : \ - (_rate == MGN_VHT1SS_MCS4) ? "VHT1SMCS4" : \ - (_rate == MGN_VHT1SS_MCS5) ? "VHT1SMCS5" : \ - (_rate == MGN_VHT1SS_MCS6) ? "VHT1SMCS6" : \ - (_rate == MGN_VHT1SS_MCS7) ? "VHT1SMCS7" : \ - (_rate == MGN_VHT1SS_MCS8) ? "VHT1SMCS8" : \ - (_rate == MGN_VHT1SS_MCS9) ? "VHT1SMCS9" : \ - (_rate == MGN_VHT2SS_MCS0) ? "VHT2SMCS0" : \ - (_rate == MGN_VHT2SS_MCS1) ? "VHT2SMCS1" : \ - (_rate == MGN_VHT2SS_MCS2) ? "VHT2SMCS2" : \ - (_rate == MGN_VHT2SS_MCS3) ? "VHT2SMCS3" : \ - (_rate == MGN_VHT2SS_MCS4) ? "VHT2SMCS4" : \ - (_rate == MGN_VHT2SS_MCS5) ? "VHT2SMCS5" : \ - (_rate == MGN_VHT2SS_MCS6) ? "VHT2SMCS6" : \ - (_rate == MGN_VHT2SS_MCS7) ? "VHT2SMCS7" : \ - (_rate == MGN_VHT2SS_MCS8) ? "VHT2SMCS8" : \ - (_rate == MGN_VHT2SS_MCS9) ? "VHT2SMCS9" : \ - (_rate == MGN_VHT3SS_MCS0) ? "VHT3SMCS0" : \ - (_rate == MGN_VHT3SS_MCS1) ? "VHT3SMCS1" : \ - (_rate == MGN_VHT3SS_MCS2) ? "VHT3SMCS2" : \ - (_rate == MGN_VHT3SS_MCS3) ? "VHT3SMCS3" : \ - (_rate == MGN_VHT3SS_MCS4) ? "VHT3SMCS4" : \ - (_rate == MGN_VHT3SS_MCS5) ? "VHT3SMCS5" : \ - (_rate == MGN_VHT3SS_MCS6) ? "VHT3SMCS6" : \ - (_rate == MGN_VHT3SS_MCS7) ? "VHT3SMCS7" : \ - (_rate == MGN_VHT3SS_MCS8) ? "VHT3SMCS8" : \ - (_rate == MGN_VHT3SS_MCS9) ? "VHT3SMCS9" : \ - (_rate == MGN_VHT4SS_MCS0) ? "VHT4SMCS0" : \ - (_rate == MGN_VHT4SS_MCS1) ? "VHT4SMCS1" : \ - (_rate == MGN_VHT4SS_MCS2) ? "VHT4SMCS2" : \ - (_rate == MGN_VHT4SS_MCS3) ? "VHT4SMCS3" : \ - (_rate == MGN_VHT4SS_MCS4) ? "VHT4SMCS4" : \ - (_rate == MGN_VHT4SS_MCS5) ? "VHT4SMCS5" : \ - (_rate == MGN_VHT4SS_MCS6) ? "VHT4SMCS6" : \ - (_rate == MGN_VHT4SS_MCS7) ? "VHT4SMCS7" : \ - (_rate == MGN_VHT4SS_MCS8) ? "VHT4SMCS8" : \ - (_rate == MGN_VHT4SS_MCS9) ? "VHT4SMCS9" : "UNKNOWN" +const char *MGN_RATE_STR(enum MGN_RATE rate); typedef enum _RATE_SECTION { CCK = 0, @@ -1597,6 +1524,24 @@ enum _PUBLIC_ACTION { ACT_PUBLIC_GAS_COMEBACK_RSP = 13, ACT_PUBLIC_TDLS_DISCOVERY_RSP = 14, ACT_PUBLIC_LOCATION_TRACK = 15, + ACT_PUBLIC_QAB_REQ, + ACT_PUBLIC_QAB_RSP, + ACT_PUBLIC_QMF_POLICY, + ACT_PUBLIC_QMF_POLICY_CHANGE, + ACT_PUBLIC_QLOAD_REQ, + ACT_PUBLIC_QLOAD_REPORT, + ACT_PUBLIC_HCCA_TXOP_ADV, + ACT_PUBLIC_HCCA_TXOP_RSP, + ACT_PUBLIC_PUBLIC_KEY, + ACT_PUBLIC_CH_AVAILABILITY_QUERY, + ACT_PUBLIC_CH_SCHEDULE_MGMT, + ACT_PUBLIC_CONTACT_VERI_SIGNAL, + ACT_PUBLIC_GDD_ENABLE_REQ, + ACT_PUBLIC_GDD_ENABLE_RSP, + ACT_PUBLIC_NETWORK_CH_CONTROL, + ACT_PUBLIC_WHITE_SPACE_MAP_ANN, + ACT_PUBLIC_FTM_REQ, + ACT_PUBLIC_FTM, ACT_PUBLIC_MAX }; @@ -1660,26 +1605,6 @@ enum rtw_ieee80211_vht_actioncode { RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION = 2, }; -/*IEEE 802.11r action code*/ -#ifdef CONFIG_RTW_80211R -enum rtw_ieee80211_ft_actioncode { - RTW_WLAN_ACTION_FT_RESV, - RTW_WLAN_ACTION_FT_REQ, - RTW_WLAN_ACTION_FT_RSP, - RTW_WLAN_ACTION_FT_CONF, - RTW_WLAN_ACTION_FT_ACK, - RTW_WLAN_ACTION_FT_MAX, -}; -#endif - -#ifdef CONFIG_RTW_WNM -enum rtw_ieee80211_wnm_actioncode { - RTW_WLAN_ACTION_WNM_BTM_QUERY = 6, - RTW_WLAN_ACTION_WNM_BTM_REQ = 7, - RTW_WLAN_ACTION_WNM_BTM_RSP = 8, -}; -#endif - #define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) * 00:50:F2 */ #ifndef PLATFORM_FREEBSD /* Baron BSD has defined */ @@ -1977,6 +1902,7 @@ u8 *rtw_get_owe_ie(const u8 *in_ie, uint in_len, u8 *owe_ie, uint *owe_ielen); for (ie = (void *)buf; (((u8 *)ie) - ((u8 *)buf) + 1) < buf_len; ie = (void *)(((u8 *)ie) + *(((u8 *)ie)+1) + 2)) void dump_ies(void *sel, const u8 *buf, u32 buf_len); +#ifdef CONFIG_RTW_DEBUG #ifdef CONFIG_80211N_HT #define HT_SC_OFFSET_MAX 4 @@ -1987,6 +1913,7 @@ void dump_ht_cap_ie_content(void *sel, const u8 *buf, u32 buf_len); #endif void dump_wps_ie(void *sel, const u8 *ie, u32 ie_len); +#endif /* CONFIG_RTW_DEBUG */ void rtw_ies_get_chbw(u8 *ies, int ies_len, u8 *ch, u8 *bw, u8 *offset, u8 ht, u8 vht); @@ -1997,9 +1924,12 @@ bool rtw_is_chbw_grouped(u8 ch_a, u8 bw_a, u8 offset_a void rtw_sync_chbw(u8 *req_ch, u8 *req_bw, u8 *req_offset , u8 *g_ch, u8 *g_bw, u8 *g_offset); +#ifdef CONFIG_P2P u32 rtw_get_p2p_merged_ies_len(u8 *in_ie, u32 in_len); int rtw_p2p_merge_ies(u8 *in_ie, u32 in_len, u8 *merge_ie); +#ifdef CONFIG_RTW_DEBUG void dump_p2p_ie(void *sel, const u8 *ie, u32 ie_len); +#endif u8 *rtw_get_p2p_ie(const u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen); u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id, u8 *buf_attr, u32 *len_attr); u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id, u8 *buf_content, uint *len_content); @@ -2009,16 +1939,32 @@ uint rtw_del_p2p_attr(u8 *ie, uint ielen_ori, u8 attr_id); u8 *rtw_bss_ex_get_p2p_ie(WLAN_BSSID_EX *bss_ex, u8 *p2p_ie, uint *p2p_ielen); void rtw_bss_ex_del_p2p_ie(WLAN_BSSID_EX *bss_ex); void rtw_bss_ex_del_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id); +#endif /* CONFIG_P2P */ +uint rtw_del_wfd_ie(u8 *ies, uint ies_len_ori, const char *msg); +void rtw_bss_ex_del_wfd_ie(WLAN_BSSID_EX *bss_ex); +#ifdef CONFIG_WFD +#ifdef CONFIG_RTW_DEBUG void dump_wfd_ie(void *sel, const u8 *ie, u32 ie_len); +#endif u8 *rtw_get_wfd_ie(const u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen); u8 *rtw_get_wfd_attr(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id, u8 *buf_attr, u32 *len_attr); u8 *rtw_get_wfd_attr_content(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id, u8 *buf_content, uint *len_content); -uint rtw_del_wfd_ie(u8 *ies, uint ies_len_ori, const char *msg); uint rtw_del_wfd_attr(u8 *ie, uint ielen_ori, u8 attr_id); u8 *rtw_bss_ex_get_wfd_ie(WLAN_BSSID_EX *bss_ex, u8 *wfd_ie, uint *wfd_ielen); -void rtw_bss_ex_del_wfd_ie(WLAN_BSSID_EX *bss_ex); void rtw_bss_ex_del_wfd_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id); +#endif + +#define MULTI_AP_SUB_ELEM_TYPE 0x06 +#define MULTI_AP_TEAR_DOWN BIT(4) +#define MULTI_AP_FRONTHAUL_BSS BIT(5) +#define MULTI_AP_BACKHAUL_BSS BIT(6) +#define MULTI_AP_BACKHAUL_STA BIT(7) +#ifdef CONFIG_RTW_MULTI_AP +void dump_multi_ap_ie(void *sel, const u8 *ie, u32 ie_len); +u8 rtw_get_multi_ap_ie_ext(const u8 *ies, int ies_len); +u8 *rtw_set_multi_ap_ie_ext(u8 *pbuf, uint *frlen, u8 val); +#endif uint rtw_get_rateset_len(u8 *rateset); @@ -2039,6 +1985,8 @@ void rtw_macaddr_cfg(u8 *out, const u8 *hw_mac_addr); u16 rtw_ht_mcs_rate(u8 bw_40MHz, u8 short_GI, unsigned char *MCS_rate); u8 rtw_ht_mcsset_to_nss(u8 *supp_mcs_set); u32 rtw_ht_mcs_set_to_bitmap(u8 *mcs_set, u8 nss); +u8 rtw_ht_cap_get_rx_nss(u8 *ht_cap); +u8 rtw_ht_cap_get_tx_nss(u8 *ht_cap); int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, u8 *action); const char *action_public_str(u8 action); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/osdep_intf.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/osdep_intf.h index 293977cb7d39..335826534cc0 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/osdep_intf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/osdep_intf.h @@ -91,9 +91,7 @@ void rtw_os_ndevs_unregister(struct dvobj_priv *dvobj); int rtw_os_ndevs_init(struct dvobj_priv *dvobj); void rtw_os_ndevs_deinit(struct dvobj_priv *dvobj); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) -u16 rtw_recv_select_queue(struct sk_buff *skb); -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) */ +u16 rtw_os_recv_select_queue(u8 *msdu, enum rtw_rx_llc_hdl llc_hdl); int rtw_ndev_notifier_register(void); void rtw_ndev_notifier_unregister(void); @@ -101,6 +99,10 @@ void rtw_inetaddr_notifier_register(void); void rtw_inetaddr_notifier_unregister(void); #include "../os_dep/linux/rtw_proc.h" +#include "../os_dep/linux/nlrtw.h" +#ifdef CONFIG_PLATFORM_CMAP_INTFS +#include "../os_dep/linux/custom_multiap_intfs/custom_multiap_intfs.h" +#endif #ifdef CONFIG_IOCTL_CFG80211 #include "../os_dep/linux/ioctl_cfg80211.h" diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/osdep_service.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/osdep_service.h index 4e08de4a4f99..4af2f6303d1c 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/osdep_service.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/osdep_service.h @@ -31,6 +31,7 @@ #define RTW_XBUF_UNAVAIL 11 #define RTW_TX_BALANCE 12 #define RTW_TX_WAIT_MORE_FRAME 13 +#define RTW_QUEUE_MGMT 14 /* #define RTW_STATUS_TIMEDOUT -110 */ @@ -385,6 +386,30 @@ extern bool _rtw_time_after(systime a, systime b); #define rtw_time_before(a,b) _rtw_time_after(b,a) #endif +sysptime rtw_sptime_get(void); +sysptime rtw_sptime_set(s64 secs, const u32 nsecs); +sysptime rtw_sptime_zero(void); + +int rtw_sptime_cmp(const sysptime cmp1, const sysptime cmp2); +bool rtw_sptime_eql(const sysptime cmp1, const sysptime cmp2); +bool rtw_sptime_is_zero(const sysptime sptime); +sysptime rtw_sptime_sub(const sysptime lhs, const sysptime rhs); +sysptime rtw_sptime_add(const sysptime lhs, const sysptime rhs); + +s64 rtw_sptime_to_ms(const sysptime sptime); +sysptime rtw_ms_to_sptime(u64 ms); +s64 rtw_sptime_to_us(const sysptime sptime); +sysptime rtw_us_to_sptime(u64 us); +s64 rtw_sptime_to_ns(const sysptime sptime); +sysptime rtw_ns_to_sptime(u64 ns); + +s64 rtw_sptime_diff_ms(const sysptime start, const sysptime end); +s64 rtw_sptime_pass_ms(const sysptime start); +s64 rtw_sptime_diff_us(const sysptime start, const sysptime end); +s64 rtw_sptime_pass_us(const sysptime start); +s64 rtw_sptime_diff_ns(const sysptime start, const sysptime end); +s64 rtw_sptime_pass_ns(const sysptime start); + extern void rtw_sleep_schedulable(int ms); extern void rtw_msleep_os(int ms); @@ -404,6 +429,39 @@ extern void rtw_udelay_os(int us); extern void rtw_yield_os(void); +enum rtw_pwait_type { + RTW_PWAIT_TYPE_MSLEEP, + RTW_PWAIT_TYPE_USLEEP, + RTW_PWAIT_TYPE_YIELD, + RTW_PWAIT_TYPE_MDELAY, + RTW_PWAIT_TYPE_UDELAY, + + RTW_PWAIT_TYPE_NUM, +}; + +#define RTW_PWAIT_TYPE_VALID(type) (type < RTW_PWAIT_TYPE_NUM) + +struct rtw_pwait_conf { + enum rtw_pwait_type type; + s32 wait_time; + s32 wait_cnt_lmt; +}; + +struct rtw_pwait_ctx { + struct rtw_pwait_conf conf; + s32 wait_cnt; + void (*wait_hdl)(int us); +}; + +extern const char *_rtw_pwait_type_str[]; +#define rtw_pwait_type_str(type) (RTW_PWAIT_TYPE_VALID(type) ? _rtw_pwait_type_str[type] : _rtw_pwait_type_str[RTW_PWAIT_TYPE_NUM]) + +#define rtw_pwctx_reset(pwctx) (pwctx)->wait_cnt = 0 +#define rtw_pwctx_wait(pwctx) do { (pwctx)->wait_hdl((pwctx)->conf.wait_time); (pwctx)->wait_cnt++; } while(0) +#define rtw_pwctx_waited(pwctx) ((pwctx)->wait_cnt) +#define rtw_pwctx_exceed(pwctx) ((pwctx)->conf.wait_cnt_lmt >= 0 && (pwctx)->wait_cnt >= (pwctx)->conf.wait_cnt_lmt) + +int rtw_pwctx_config(struct rtw_pwait_ctx *pwctx, enum rtw_pwait_type type, s32 time, s32 cnt_lmt); extern void rtw_init_timer(_timer *ptimer, void *padapter, void *pfunc, void *ctx); @@ -794,11 +852,13 @@ struct blacklist_ent { systime exp_time; }; +#ifdef CONFIG_RTW_MESH int rtw_blacklist_add(_queue *blist, const u8 *addr, u32 timeout_ms); int rtw_blacklist_del(_queue *blist, const u8 *addr); int rtw_blacklist_search(_queue *blist, const u8 *addr); void rtw_blacklist_flush(_queue *blist); void dump_blacklist(void *sel, _queue *blist, const char *title); +#endif /* String handler */ @@ -814,6 +874,8 @@ int hex2num_i(char c); int hex2byte_i(const char *hex); int hexstr2bin(const char *hex, u8 *buf, size_t len); +int hwaddr_aton_i(const char *txt, u8 *addr); + /* * Write formatted output to sized buffer */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/osdep_service_linux.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/osdep_service_linux.h index 544f9dd2a666..12d28be69aea 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/osdep_service_linux.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/osdep_service_linux.h @@ -57,6 +57,10 @@ #include #include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) + #include +#endif + #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 5, 41)) #include #endif @@ -93,6 +97,10 @@ #ifdef CONFIG_IOCTL_CFG80211 /* #include */ #include +#else + #ifdef CONFIG_REGD_SRC_FROM_OS + #error "CONFIG_REGD_SRC_FROM_OS requires CONFIG_IOCTL_CFG80211" + #endif #endif /* CONFIG_IOCTL_CFG80211 */ @@ -214,6 +222,7 @@ typedef void *timer_hdl_context; #endif typedef unsigned long systime; +typedef ktime_t sysptime; typedef struct tasklet_struct _tasklet; #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)) @@ -382,6 +391,11 @@ __inline static void _cancel_timer(_timer *ptimer, u8 *bcancelled) *bcancelled = del_timer_sync(&ptimer->timer) == 1 ? 1 : 0; } +__inline static void _cancel_timer_async(_timer *ptimer) +{ + del_timer(&ptimer->timer); +} + static inline void _init_workitem(_workitem *pwork, void *pfunc, void *cntx) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/pci_osintf.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/pci_osintf.h index b8582b5d64e3..9db032a0fa7b 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/pci_osintf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/pci_osintf.h @@ -16,7 +16,7 @@ #ifndef __PCI_OSINTF_H #define __PCI_OSINTF_H -#ifdef RTK_129X_PLATFORM +#ifdef CONFIG_PLATFORM_RTK129X #define PCIE_SLOT1_MEM_START 0x9804F000 #define PCIE_SLOT1_MEM_LEN 0x1000 #define PCIE_SLOT1_CTRL_START 0x9804EC00 @@ -39,9 +39,6 @@ void PlatformClearPciPMEStatus(PADAPTER Adapter); void rtw_pci_aspm_config(_adapter *padapter); void rtw_pci_aspm_config_l1off_general(_adapter *padapter, u8 eanble); -#ifdef CONFIG_64BIT_DMA - u8 PlatformEnableDMA64(PADAPTER Adapter); -#endif #ifdef CONFIG_PCI_DYNAMIC_ASPM void rtw_pci_set_aspm_lnkctl(_adapter *padapter, u8 mode); void rtw_pci_set_l1_latency(_adapter *padapter, u8 mode); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/recv_osdep.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/recv_osdep.h index 0aa27a2162d7..8d7218bfa108 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/recv_osdep.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/recv_osdep.h @@ -48,10 +48,11 @@ int rtw_os_recvframe_duplicate_skb(_adapter *padapter, union recv_frame *pclonef void rtw_os_free_recvframe(union recv_frame *precvframe); -int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf); +int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf, u32 size); int rtw_os_recvbuf_resource_free(_adapter *padapter, struct recv_buf *precvbuf); -_pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, const u8 *da, const u8 *sa, u8 *msdu ,u16 msdu_len); +_pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, const u8 *da, const u8 *sa + , u8 *msdu ,u16 msdu_len, enum rtw_rx_llc_hdl llc_hdl); void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, union recv_frame *rframe); void rtw_os_read_port(_adapter *padapter, struct recv_buf *precvbuf); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188e_hal.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188e_hal.h index 63d1e3f8a910..8bb69e9fd117 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188e_hal.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188e_hal.h @@ -139,8 +139,13 @@ typedef struct _RT_8188E_FIRMWARE_HDR { /* For WoWLan , more reserved page */ #ifdef CONFIG_WOWLAN + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + #define WOWLAN_KEEP_ALIVE_PAGE 0x02 /*for keep alive packet*/ + #else + #define WOWLAN_KEEP_ALIVE_PAGE 0x00 + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ /* 1 ArpRsp + 2 NbrAdv + 2 NDPInfo + 1 RCI + 1 AOAC = 7 pages */ - #define WOWLAN_PAGE_NUM_88E 0x07 + #define WOWLAN_PAGE_NUM_88E (0x07+ WOWLAN_KEEP_ALIVE_PAGE) #else #define WOWLAN_PAGE_NUM_88E 0x00 #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188e_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188e_xmit.h index 21ef1caf4801..e86f481abcb2 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188e_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188e_xmit.h @@ -246,6 +246,9 @@ void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, struct tx_desc *ptx void rtl8188es_free_xmit_priv(PADAPTER padapter); s32 rtl8188es_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8188es_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8188es_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8188es_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); thread_return rtl8188es_xmit_thread(thread_context context); s32 rtl8188es_xmit_buf_handler(PADAPTER padapter); @@ -260,6 +263,9 @@ void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, struct tx_desc *ptx void rtl8188eu_free_xmit_priv(PADAPTER padapter); s32 rtl8188eu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8188eu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8188eu_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8188eu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8188eu_xmit_buf_handler(PADAPTER padapter); void rtl8188eu_xmit_tasklet(void *priv); @@ -272,6 +278,9 @@ void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, struct tx_desc *ptx void rtl8188ee_xmitframe_resume(_adapter *padapter); s32 rtl8188ee_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8188ee_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8188ee_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8188ee_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8188ee_xmit_tasklet(void *priv); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188f_cmd.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188f_cmd.h index eb9ca3d525b5..42f52b3df1c8 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188f_cmd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188f_cmd.h @@ -190,12 +190,6 @@ void rtl8188f_download_rsvd_page(PADAPTER padapter, u8 mstatus); void rtl8188f_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); #endif /* CONFIG_P2P */ -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW -void rtl8188f_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); -#endif -#endif - #ifdef CONFIG_P2P_WOWLAN void rtl8188f_set_p2p_wowlan_offload_cmd(PADAPTER padapter); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188f_recv.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188f_recv.h index f95cfada8b59..f97aca291fa8 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188f_recv.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188f_recv.h @@ -22,9 +22,7 @@ #ifdef CONFIG_MINIMAL_MEMORY_USAGE #define MAX_RECVBUF_SZ (4000) /* about 4K */ #else - #ifdef CONFIG_PLATFORM_MSTAR - #define MAX_RECVBUF_SZ (8192) /* 8K */ - #elif defined(CONFIG_PLATFORM_HISILICON) + #ifdef CONFIG_PLATFORM_HISILICON #define MAX_RECVBUF_SZ (16384) /* 16k */ #else #define MAX_RECVBUF_SZ (32768) /* 32k */ @@ -38,7 +36,8 @@ #elif defined(CONFIG_PCI_HCI) #define MAX_RECVBUF_SZ (4000) /* about 4K */ #elif defined(CONFIG_SDIO_HCI) - #define MAX_RECVBUF_SZ (RX_DMA_BOUNDARY_8188F + 1) + /* minmum 4K, multiple of 8-byte is required, multiple of sdio block size is prefered */ + #define MAX_RECVBUF_SZ _RND(RX_DMA_BOUNDARY_8188F + 1, 8) #endif /* CONFIG_SDIO_HCI */ /* Rx smooth factor */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188f_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188f_xmit.h index 1d787b361fc5..6909796ae8be 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188f_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8188f_xmit.h @@ -295,6 +295,9 @@ s32 rtl8188fs_init_xmit_priv(PADAPTER padapter); void rtl8188fs_free_xmit_priv(PADAPTER padapter); s32 rtl8188fs_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8188fs_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtl8188fs_hal_mgmt_xmitframe_enqueue(PADAPTER, struct xmit_frame *); +#endif s32 rtl8188fs_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8188fs_xmit_buf_handler(PADAPTER padapter); thread_return rtl8188fs_xmit_thread(thread_context context); @@ -311,6 +314,9 @@ s32 rtl8188fu_init_xmit_priv(PADAPTER padapter); void rtl8188fu_free_xmit_priv(PADAPTER padapter); s32 rtl8188fu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8188fu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtl8188fu_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8188fu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); /* s32 rtl8812au_xmit_buf_handler(PADAPTER padapter); */ void rtl8188fu_xmit_tasklet(void *priv); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192e_cmd.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192e_cmd.h index e9ff31c3ef11..91b2c4c228b8 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192e_cmd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192e_cmd.h @@ -127,12 +127,6 @@ s32 c2h_handler_8192e(_adapter *adapter, u8 id, u8 seq, u8 plen, u8 *payload); void rtl8192e_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); #endif /* CONFIG_P2P */ -#ifdef CONFIG_TDLS - #ifdef CONFIG_TDLS_CH_SW - void rtl8192e_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); - #endif -#endif - /* / TX Feedback Content */ #define USEC_UNIT_FOR_8192E_C2H_TX_RPT_QUEUE_TIME 256 diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192e_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192e_xmit.h index 38694f606ec1..3668352c5b8b 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192e_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192e_xmit.h @@ -359,6 +359,9 @@ void rtl8192e_cal_txdesc_chksum(u8 *ptxdesc); void rtl8192eu_free_xmit_priv(PADAPTER padapter); s32 rtl8192eu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8192eu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8192eu_hal_mgmt_xmitframe_enqueue(PADAPTER padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8192eu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8192eu_xmit_buf_handler(PADAPTER padapter); #define hal_xmit_handler rtl8192eu_xmit_buf_handler @@ -370,6 +373,9 @@ void rtl8192e_cal_txdesc_chksum(u8 *ptxdesc); s32 rtl8192ee_init_xmit_priv(PADAPTER padapter); void rtl8192ee_free_xmit_priv(PADAPTER padapter); struct xmit_buf *rtl8192ee_dequeue_xmitbuf(struct rtw_tx_ring *ring); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8192ee_hal_mgmt_xmitframe_enqueue(PADAPTER padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8192ee_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8192ee_xmitframe_resume(_adapter *padapter); s32 rtl8192ee_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); @@ -383,6 +389,9 @@ void rtl8192e_cal_txdesc_chksum(u8 *ptxdesc); s32 rtl8192es_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8192es_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8192es_hal_mgmt_xmitframe_enqueue(PADAPTER padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8192es_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); thread_return rtl8192es_xmit_thread(thread_context context); s32 rtl8192es_xmit_buf_handler(PADAPTER padapter); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_cmd.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_cmd.h index 9d51f13f1f48..69abb2208910 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_cmd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_cmd.h @@ -180,16 +180,35 @@ void rtl8192f_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter); void rtl8192f_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); #endif /* CONFIG_P2P */ -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW -void rtl8192f_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); -#endif -#endif - #ifdef CONFIG_P2P_WOWLAN void rtl8192f_set_p2p_wowlan_offload_cmd(PADAPTER padapter); #endif +/* AP_REQ_TXREP_CMD 0x43 */ +#define SET_8192F_H2CCMD_TXREP_PARM_STA1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8192F_H2CCMD_TXREP_PARM_STA2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_8192F_H2CCMD_TXREP_PARM_RTY(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 2, __Value) + +/* C2H_AP_REQ_TXRPT */ +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_MACID1(_Header) LE_BITS_TO_1BYTE((_Header + 0), 0, 8) +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_TXOK1(_Header) LE_BITS_TO_2BYTE((_Header + 1), 0, 16) +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_TXFAIL1(_Header) LE_BITS_TO_2BYTE((_Header + 3), 0, 16) +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_INIRATE1(_Header) LE_BITS_TO_1BYTE((_Header + 5), 0, 8) +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_MACID2(_Header) LE_BITS_TO_1BYTE((_Header + 6), 0, 8) +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_TXOK2(_Header) LE_BITS_TO_2BYTE((_Header + 7), 0, 16) +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_TXFAIL2(_Header) LE_BITS_TO_2BYTE((_Header + 9), 0, 16) +#define GET_8192F_C2H_TC2H_APREQ_TXRPT_INIRATE2(_Header) LE_BITS_TO_1BYTE((_Header + 11), 0, 8) + +/* C2H_SPC_STAT */ +#define GET_8192F_C2H_SPC_STAT_IDX(_Header) LE_BITS_TO_1BYTE((_Header + 0), 0, 8) + /* Tip :TYPE_A data3 is msb and data0 is lsb */ +#define GET_8192F_C2H_SPC_STAT_TYPEA_RETRY(_Header) LE_BITS_TO_4BYTE((_Header + 1), 0, 32) +#define GET_8192F_C2H_SPC_STAT_TYPEB_PKT1(_Header) LE_BITS_TO_2BYTE((_Header + 1), 0, 16) +#define GET_8192F_C2H_SPC_STAT_TYPEB_RETRY1(_Header) LE_BITS_TO_2BYTE((_Header + 3), 0, 16) +#define GET_8192F_C2H_SPC_STAT_TYPEB_PKT2(_Header) LE_BITS_TO_2BYTE((_Header + 5), 0, 16) +#define GET_8192F_C2H_SPC_STAT_TYPEB_RETRY2(_Header) LE_BITS_TO_2BYTE((_Header + 7), 0, 16) + +void rtl8192f_req_txrpt_cmd(PADAPTER, u8 macid); s32 FillH2CCmd8192F(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); u8 GetTxBufferRsvdPageNum8192F(_adapter *padapter, bool wowlan); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_hal.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_hal.h index 51344b2d8b50..acb8950cb075 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_hal.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_hal.h @@ -118,8 +118,13 @@ typedef struct _RT_8192F_FIRMWARE_HDR { * NS offload: 2 NDP info: 1 */ #ifdef CONFIG_WOWLAN + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + #define WOWLAN_KEEP_ALIVE_PAGE 0x02 /*for keep alive packet*/ + #else + #define WOWLAN_KEEP_ALIVE_PAGE 0x00 + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ /* 7 pages for wow rsvd page + 2 pages for pattern */ - #define WOWLAN_PAGE_NUM_8192F 0x09 + #define WOWLAN_PAGE_NUM_8192F (0x09 + WOWLAN_KEEP_ALIVE_PAGE) #else #define WOWLAN_PAGE_NUM_8192F 0x00 #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_led.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_led.h index f86442f1ce8a..5b68b56a3272 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_led.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_led.h @@ -25,6 +25,23 @@ * Interface to manipulate LED objects. * ******************************************************************************** */ #ifdef CONFIG_USB_HCI +/** REG_LED_CFG (0x4C) **/ +/* LED0 GPIO Enable, 0: disable, 1: enable*/ +#define LED0_GPIO_ENABLE_8192FU (BIT21) +/* LED0 Disabled for analog signal usage, 0:Enable (output mode), 1: disable (input mode) */ +#define LED0_DISABLE_ANALOGSIGNAL_8192FU (BIT7) +/* LED0 software value, 0: turn off, 1:turn on */ +#define LED0_SW_VALUE_8192FU (BIT3) + +/** REG_GPIO_MUXCFG (0x40) **/ +/* Enable LED[1:0] for RFE CTRL[7:6], 0: BT, 1: Wi-Fi */ +#define ENABLE_LED0_AND_LED1_CTRL_BY_WIFI_8192FU (BIT3) + +/** REG_SW_GPIO_SHARE_CTRL_0 (0x1038) **/ +/* LED Output PIN Location, 0: GPIOA_0, 1:GPIOB_4*/ +#define LED_OUTPUT_PIN_LOCATION_8192FU (BIT16) + +u8 rtl8192fu_CfgLed0Hw(PADAPTER padapter); void rtl8192fu_InitSwLeds(PADAPTER padapter); void rtl8192fu_DeInitSwLeds(PADAPTER padapter); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_rf.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_rf.h index 9c6cb1d4467e..11c314c2364f 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_rf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_rf.h @@ -22,9 +22,6 @@ #define CONFIG_8192F_TYPE3_DRV_DIS #define CONFIG_8192F_TYPE4_DRV_DIS /*unused*/ -#define CONFIG_8192F_TYPE15_DRV_DIS -#define CONFIG_8192F_TYPE16_DRV_DIS -#define CONFIG_8192F_TYPE17_DRV_DIS #define CONFIG_8192F_TYPE18_DRV_DIS #define CONFIG_8192F_TYPE19_DRV_DIS #define CONFIG_8192F_TYPE20_DRV_DIS @@ -55,6 +52,9 @@ #define CONFIG_8192F_TYPE8_DRV_DIS #define CONFIG_8192F_TYPE9_DRV_DIS #define CONFIG_8192F_TYPE12_DRV_DIS +#define CONFIG_8192F_TYPE15_DRV_DIS +#define CONFIG_8192F_TYPE16_DRV_DIS +#define CONFIG_8192F_TYPE17_DRV_DIS #endif/*CONFIG_SDIO_HCI*/ #ifdef CONFIG_USB_HCI @@ -68,6 +68,9 @@ #define CONFIG_8192F_TYPE8_DRV_DIS #define CONFIG_8192F_TYPE9_DRV_DIS #define CONFIG_8192F_TYPE12_DRV_DIS +#define CONFIG_8192F_TYPE15_DRV_DIS +#define CONFIG_8192F_TYPE16_DRV_DIS +#define CONFIG_8192F_TYPE17_DRV_DIS #endif/*CONFIG_USB_HCI*/ #ifdef CONFIG_PCI_HCI diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_spec.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_spec.h index 08acb1762af6..01828bbf4531 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_spec.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_spec.h @@ -145,6 +145,7 @@ #define REG_RQPN_NPQ_8192F 0x0214 #define REG_DWBCN1_CTRL_8192F 0x0228 #define REG_RQPN_EXQ1_EXQ2 0x0230 +#define REG_TQPNT3_V1_8192F 0x0234 /* ----------------------------------------------------- * @@ -398,7 +399,8 @@ #define REG_LTR_ACTIVE_LATENCY_V1_8192F 0x079C /* GPIO Control */ -#define REG_SW_GPIO_SHARE_CTRL_8192F 0x1038 +#define REG_SW_GPIO_SHARE_CTRL_8192F_0 0x1038 +#define REG_SW_GPIO_SHARE_CTRL_8192F_1 0x103c #define REG_SW_GPIO_A_OUT_8192F 0x1040 #define REG_SW_GPIO_A_OEN_8192F 0x1044 diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_xmit.h index 0cbc2eb6ba14..8c00b4ad7065 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8192f_xmit.h @@ -494,6 +494,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8192fs_free_xmit_priv(PADAPTER padapter); s32 rtl8192fs_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8192fs_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8192fs_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8192fs_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8192fs_xmit_buf_handler(PADAPTER padapter); thread_return rtl8192fs_xmit_thread(thread_context context); @@ -505,6 +508,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8192fu_free_xmit_priv(PADAPTER padapter); s32 rtl8192fu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8192fu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8192fu_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8192fu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8192fu_xmit_buf_handler(PADAPTER padapter); #define hal_xmit_handler rtl8192fu_xmit_buf_handler @@ -520,6 +526,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8192fe_xmitframe_resume(_adapter *padapter); s32 rtl8192fe_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8192fe_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8192fe_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8192fe_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8192fe_xmit_tasklet(void *priv); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8703b_cmd.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8703b_cmd.h index 12ff9a1491b1..cf29f03261bd 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8703b_cmd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8703b_cmd.h @@ -189,12 +189,6 @@ void rtl8703b_download_rsvd_page(PADAPTER padapter, u8 mstatus); void rtl8703b_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); #endif /* CONFIG_P2P */ -#ifdef CONFIG_TDLS - #ifdef CONFIG_TDLS_CH_SW - void rtl8703b_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); - #endif -#endif - #ifdef CONFIG_P2P_WOWLAN void rtl8703b_set_p2p_wowlan_offload_cmd(PADAPTER padapter); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8703b_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8703b_xmit.h index 29863cbca708..0c608ba56cd9 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8703b_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8703b_xmit.h @@ -295,6 +295,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8703bs_free_xmit_priv(PADAPTER padapter); s32 rtl8703bs_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8703bs_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8703bs_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8703bs_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8703bs_xmit_buf_handler(PADAPTER padapter); thread_return rtl8703bs_xmit_thread(thread_context context); @@ -310,6 +313,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8703bu_free_xmit_priv(PADAPTER padapter); s32 rtl8703bu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8703bu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8703bu_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8703bu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); /* s32 rtl8812au_xmit_buf_handler(PADAPTER padapter); */ void rtl8703bu_xmit_tasklet(void *priv); @@ -324,6 +330,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8703be_xmitframe_resume(_adapter *padapter); s32 rtl8703be_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8703be_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8703be_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8703be_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8703be_xmit_tasklet(void *priv); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8710b_cmd.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8710b_cmd.h index e6f96c717be6..ebddcf18e5dc 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8710b_cmd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8710b_cmd.h @@ -161,12 +161,6 @@ void rtl8710b_download_rsvd_page(PADAPTER padapter, u8 mstatus); void rtl8710b_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); #endif /* CONFIG_P2P */ -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW -void rtl8710b_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); -#endif -#endif - #ifdef CONFIG_P2P_WOWLAN void rtl8710b_set_p2p_wowlan_offload_cmd(PADAPTER padapter); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8710b_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8710b_xmit.h index 5fc6921bab7b..e3e2198d44dc 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8710b_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8710b_xmit.h @@ -498,6 +498,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8710bu_free_xmit_priv(PADAPTER padapter); s32 rtl8710bu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8710bu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8710bu_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8710bu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8710bu_xmit_tasklet(void *priv); s32 rtl8710bu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723b_cmd.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723b_cmd.h index 758e5124ab0d..a53fdd4faf7b 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723b_cmd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723b_cmd.h @@ -189,12 +189,6 @@ void rtl8723b_download_rsvd_page(PADAPTER padapter, u8 mstatus); void rtl8723b_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); #endif /* CONFIG_P2P */ -#ifdef CONFIG_TDLS - #ifdef CONFIG_TDLS_CH_SW - void rtl8723b_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); - #endif -#endif - #ifdef CONFIG_P2P_WOWLAN void rtl8723b_set_p2p_wowlan_offload_cmd(PADAPTER padapter); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723b_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723b_xmit.h index 865c8f077b41..8c0b360a06be 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723b_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723b_xmit.h @@ -295,6 +295,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8723bs_free_xmit_priv(PADAPTER padapter); s32 rtl8723bs_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8723bs_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8723bs_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8723bs_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8723bs_xmit_buf_handler(PADAPTER padapter); thread_return rtl8723bs_xmit_thread(thread_context context); @@ -310,6 +313,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8723bu_free_xmit_priv(PADAPTER padapter); s32 rtl8723bu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8723bu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8723bu_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8723bu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); /* s32 rtl8812au_xmit_buf_handler(PADAPTER padapter); */ void rtl8723bu_xmit_tasklet(void *priv); @@ -324,6 +330,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8723be_xmitframe_resume(_adapter *padapter); s32 rtl8723be_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8723be_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8723be_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8723be_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8723be_xmit_tasklet(void *priv); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723d_cmd.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723d_cmd.h index d1e1a714113f..1a32731b26ed 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723d_cmd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723d_cmd.h @@ -175,12 +175,6 @@ void rtl8723d_download_rsvd_page(PADAPTER padapter, u8 mstatus); void rtl8723d_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); #endif /* CONFIG_P2P */ -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW -void rtl8723d_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); -#endif -#endif - #ifdef CONFIG_P2P_WOWLAN void rtl8723d_set_p2p_wowlan_offload_cmd(PADAPTER padapter); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723d_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723d_xmit.h index 91bffaec6a9a..918e4e6f403e 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723d_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723d_xmit.h @@ -486,6 +486,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8723ds_free_xmit_priv(PADAPTER padapter); s32 rtl8723ds_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8723ds_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8723ds_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8723ds_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8723ds_xmit_buf_handler(PADAPTER padapter); thread_return rtl8723ds_xmit_thread(thread_context context); @@ -499,6 +502,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8723du_free_xmit_priv(PADAPTER padapter); s32 rtl8723du_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8723du_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8723du_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8723du_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8723du_xmit_tasklet(void *priv); s32 rtl8723du_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); @@ -512,6 +518,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8723de_xmitframe_resume(_adapter *padapter); s32 rtl8723de_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8723de_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8723de_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8723de_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8723de_xmit_tasklet(void *priv); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723f_hal.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723f_hal.h new file mode 100644 index 000000000000..664b62a53900 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723f_hal.h @@ -0,0 +1,263 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2019 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#ifndef _RTL8723F_HAL_H_ +#define _RTL8723F_HAL_H_ + +#include /* BIT(x) */ +#include /* PADAPTER */ +#include "../hal/halmac/halmac_api.h" /* MAC REG definition */ + +#define MAX_RECVBUF_SZ 16384 /* 16KB (RX_FIFO_SIZE_8723F), TX: 32KB */ + +/* + * MAC Register definition + */ +#define REG_LEDCFG0 REG_LED_CFG_8723F /* rtw_mp.c */ +#define MSR (REG_CR_8723F + 2) /* rtw_mp.c & hal_com.c */ +#define MSR1 REG_CR_EXT_8723F /* rtw_mp.c & hal_com.c */ +#define REG_C2HEVT_MSG_NORMAL 0x1A0 /* hal_com.c */ +#define REG_C2HEVT_CLEAR 0x1AF /* hal_com.c */ +#define REG_BCN_CTRL_1 REG_BCN_CTRL_CLINT0_8723F /* hal_com.c */ + +#define REG_WOWLAN_WAKE_REASON 0x01C7 /* hal_com.c */ +#define REG_GPIO_PIN_CTRL_2 REG_GPIO_EXT_CTRL_8723F /* hal_com.c */ +#define REG_FIFOPAGE REG_FIFOPAGE_INFO_8723F /* hal_com.c */ +#define REG_RXPKTBUF_CTRL REG_PKTBUF_DBG_CTRL_8723F /* hal_com.c */ +#define REG_WKFMCAM_NUM REG_WKFMCAM_CMD_8723F /* hal_com.c */ +#define REG_RSV_CTRL REG_REG_ACCESS_CTRL_8723F /* hal_com.c */ +#define REG_CAMCMD REG_KEYCAMCMD_8723F /* hal_com.c */ +#define REG_CAMWRITE REG_KEYCAM_WD_8723F /* hal_com.c */ + +#define BIT_AUTO_SYNC_BY_TBTT BIT_EN_TSFAUTO_SYNC_8723F /* hal_com.c */ +#define BIT_DIS_ATIM_ROOT_8723F 23 /* REG_HIQ_NO_LMT_EN_V2[23], disable ATIM ROOT */ +#define BIT_SECCAM_POLLING_8723F BIT_KEYCAM_POLLING_8723F /* rtl8723f_ops.c */ +#define BIT_GET_NETYPE2 BIT_GET_P2_NETSTATE_8723F /* hal_halmac.c */ +#define BIT_GET_NETYPE3 BIT_GET_P3_NETSTATE_8723F /* hal_halmac.c */ +#define BIT_GET_NETYPE4 BIT_GET_P4_NETSTATE_8723F /* hal_halmac.c */ + +#ifdef CONFIG_WOW_PATTERN_IN_TXFIFO +/* todo: 8723F , need to check in the future */ +#define REG_TXBUF_WKCAM_OFFSET 0x1B4 //BIT_TXBUF_WKCAM_OFFSET [24:12] +#define REG_PKT_BUFF_ACCESS_CTRL 0x106 /* hal_com.c */ +#endif + +/* RXERR_RPT, for rtw_mp.c */ +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 2 +#define RXERR_TYPE_OFDM_MPDU_OK 0 +#define RXERR_TYPE_OFDM_MPDU_FAIL 1 +#define RXERR_TYPE_CCK_PPDU 3 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 3 +#define RXERR_TYPE_CCK_MPDU_FAIL 4 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 6 +#define RXERR_TYPE_HT_MPDU_OK 6 +#define RXERR_TYPE_HT_MPDU_FAIL 7 +#define RXERR_TYPE_RX_FULL_DROP 10 + +#define RXERR_COUNTER_MASK BIT_MASK_RPT_COUNTER_8723F +#define RXERR_RPT_RST BIT_RXERR_RPT_RST_8723F +#define _RXERR_RPT_SEL(type) (BIT_RXERR_RPT_SEL_V1_3_0_8723F(type) \ + | ((type & 0x10) ? BIT_RXERR_RPT_SEL_V1_4_8723F : 0)) + +/* + * BB Register definition + */ +#define rPMAC_Reset 0x100 /* hal_mp.c */ + +#define rFPGA0_RFMOD 0x800 +#define rFPGA0_TxInfo 0x804 +#define rOFDMCCKEN_Jaguar 0x808 /* hal_mp.c */ +#define rFPGA0_TxGainStage 0x80C /* phydm only */ +#define rFPGA0_XA_HSSIParameter1 0x820 /* hal_mp.c */ +#define rFPGA0_XA_HSSIParameter2 0x824 /* hal_mp.c */ +#define rFPGA0_XB_HSSIParameter1 0x828 /* hal_mp.c */ +#define rFPGA0_XB_HSSIParameter2 0x82C /* hal_mp.c */ +#define rTxAGC_B_Rate18_06 0x830 +#define rTxAGC_B_Rate54_24 0x834 +#define rTxAGC_B_CCK1_55_Mcs32 0x838 +#define rCCAonSec_Jaguar 0x838 /* hal_mp.c */ +#define rTxAGC_B_Mcs03_Mcs00 0x83C +#define rTxAGC_B_Mcs07_Mcs04 0x848 +#define rTxAGC_B_Mcs11_Mcs08 0x84C +#define rFPGA0_XA_RFInterfaceOE 0x860 +#define rFPGA0_XB_RFInterfaceOE 0x864 +#define rTxAGC_B_Mcs15_Mcs12 0x868 +#define rTxAGC_B_CCK11_A_CCK2_11 0x86C +#define rFPGA0_XAB_RFInterfaceSW 0x870 +#define rFPGA0_XAB_RFParameter 0x878 +#define rFPGA0_AnalogParameter4 0x88C /* hal_mp.c & phydm */ +#define rFPGA0_XB_LSSIReadBack 0x8A4 /* phydm */ +#define rHSSIRead_Jaguar 0x8B0 /* RF read addr (rtl8723f_phy.c) */ + +#define rC_TxScale_Jaguar2 0x181C /* Pah_C TX scaling factor (hal_mp.c) */ +#define rC_IGI_Jaguar2 0x1850 /* Initial Gain for path-C (hal_mp.c) */ + +#define rFPGA1_TxInfo 0x90C /* hal_mp.c */ +#define rSingleTone_ContTx_Jaguar 0x914 /* hal_mp.c */ +/* TX BeamForming */ +#define REG_BB_TX_PATH_SEL_1_8723F 0x93C /* rtl8723f_phy.c */ +#define REG_BB_TX_PATH_SEL_2_8723F 0x940 /* rtl8723f_phy.c */ + +/* TX BeamForming */ +#define REG_BB_TXBF_ANT_SET_BF1_8723F 0x19AC /* rtl8723f_phy.c */ +#define REG_BB_TXBF_ANT_SET_BF0_8723F 0x19B4 /* rtl8723f_phy.c */ + +#define rCCK0_System 0xA00 +#define rCCK0_AFESetting 0xA04 + +#define rCCK0_DSPParameter2 0xA1C +#define rCCK0_TxFilter1 0xA20 +#define rCCK0_TxFilter2 0xA24 +#define rCCK0_DebugPort 0xA28 +#define rCCK0_FalseAlarmReport 0xA2C + +#define rD_TxScale_Jaguar2 0x1A1C /* Path_D TX scaling factor (hal_mp.c) */ +#define rD_IGI_Jaguar2 0x1A50 /* Initial Gain for path-D (hal_mp.c) */ + +#define rOFDM0_TRxPathEnable 0xC04 +#define rOFDM0_TRMuxPar 0xC08 +#define rA_TxScale_Jaguar 0xC1C /* Pah_A TX scaling factor (hal_mp.c) */ +#define rOFDM0_RxDetector1 0xC30 /* rtw_mp.c */ +#define rOFDM0_ECCAThreshold 0xC4C /* phydm only */ +#define rOFDM0_XAAGCCore1 0xC50 /* phydm only */ +#define rA_IGI_Jaguar 0xC50 /* Initial Gain for path-A (hal_mp.c) */ +#define rOFDM0_XBAGCCore1 0xC58 /* phydm only */ +#define rOFDM0_XATxIQImbalance 0xC80 /* phydm only */ +#define rA_LSSIWrite_Jaguar 0xC90 /* RF write addr, LSSI Parameter (rtl8822b_phy.c) */ + +#define rOFDM1_LSTF 0xD00 +#define rOFDM1_TRxPathEnable 0xD04 /* hal_mp.c */ +#define rA_PIRead_Jaguar 0xD04 /* RF readback with PI (rtl8723f_phy.c) */ +#define rA_SIRead_Jaguar 0xD08 /* RF readback with SI (rtl8723f_phy.c) */ +#define rB_PIRead_Jaguar 0xD44 /* RF readback with PI (rtl8723f_phy.c) */ +#define rB_SIRead_Jaguar 0xD48 /* RF readback with SI (rtl8723f_phy.c) */ + +#define rTxAGC_A_Rate18_06 0xE00 +#define rTxAGC_A_Rate54_24 0xE04 +#define rTxAGC_A_CCK1_Mcs32 0xE08 +#define rTxAGC_A_Mcs03_Mcs00 0xE10 +#define rTxAGC_A_Mcs07_Mcs04 0xE14 +#define rTxAGC_A_Mcs11_Mcs08 0xE18 +#define rTxAGC_A_Mcs15_Mcs12 0xE1C +#define rB_TxScale_Jaguar 0xE1C /* Path_B TX scaling factor (hal_mp.c) */ +#define rB_IGI_Jaguar 0xE50 /* Initial Gain for path-B (hal_mp.c) */ +#define rB_LSSIWrite_Jaguar 0xE90 /* RF write addr, LSSI Parameter (rtl8822b_phy.c) */ +/* RFE */ +#define rA_RFE_Pinmux_Jaguar 0xCB0 /* hal_mp.c */ +#define rB_RFE_Pinmux_Jaguar 0xEB0 /* Path_B RFE control pinmux */ +#define rA_RFE_Inv_Jaguar 0xCB4 /* Path_A RFE cotrol */ +#define rB_RFE_Inv_Jaguar 0xEB4 /* Path_B RFE control */ +#define rA_RFE_Jaguar 0xCB8 /* Path_A RFE cotrol */ +#define rB_RFE_Jaguar 0xEB8 /* Path_B RFE control */ +#define rA_RFE_Inverse_Jaguar 0xCBC /* Path_A RFE control inverse */ +#define rB_RFE_Inverse_Jaguar 0xEBC /* Path_B RFE control inverse */ +#define r_ANTSEL_SW_Jaguar 0x900 /* ANTSEL SW Control */ +#define bMask_RFEInv_Jaguar 0x3FF00000 +#define bMask_AntselPathFollow_Jaguar 0x00030000 + +#define rC_RFE_Pinmux_Jaguar 0x18B4 /* Path_C RFE cotrol pinmux*/ +#define rD_RFE_Pinmux_Jaguar 0x1AB4 /* Path_D RFE cotrol pinmux*/ +#define rA_RFE_Sel_Jaguar2 0x1990 + +/* Page1(0x100) */ +#define bBBResetB 0x100 + +/* Page8(0x800) */ +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 +/* Reg 0x80C rFPGA0_TxGainStage */ +#define bXBTxAGC 0xF00 +#define bXCTxAGC 0xF000 +#define bXDTxAGC 0xF0000 + +/* PageA(0xA00) */ +#define bCCKBBMode 0x3 + +#define bCCKScramble 0x8 +#define bCCKTxRate 0x3000 + +/* General */ +#define bMaskByte0 0xFF /* mp, rtw_odm.c & phydm */ +#define bMaskByte1 0xFF00 /* hal_mp.c & phydm */ +#define bMaskByte2 0xFF0000 /* hal_mp.c & phydm */ +#define bMaskByte3 0xFF000000 /* hal_mp.c & phydm */ +#define bMaskHWord 0xFFFF0000 /* hal_com.c, rtw_mp.c */ +#define bMaskLWord 0x0000FFFF /* mp, hal_com.c & phydm */ +#define bMaskDWord 0xFFFFFFFF /* mp, hal, rtw_odm.c & phydm */ + +#define bEnable 0x1 /* hal_mp.c, rtw_mp.c */ +#define bDisable 0x0 /* rtw_mp.c */ + +#define MAX_STALL_TIME 50 /* unit: us, hal_com_phycfg.c */ + +#define Rx_Smooth_Factor 20 /* phydm only */ + +/* + * RF Register definition + */ +#define RF_AC 0x00 +#define RF_AC_Jaguar 0x00 /* hal_mp.c */ +#define RF_CHNLBW 0x18 /* rtl8723f_phy.c */ +#define RF_ModeTableAddr 0x30 /* rtl8723f_phy.c */ +#define RF_ModeTableData0 0x31 /* rtl8723f_phy.c */ +#define RF_ModeTableData1 0x32 /* rtl8723f_phy.c */ +#define RF_0x52 0x52 +#define RF_WeLut_Jaguar 0xEF /* rtl8723f_phy.c */ + +/* rtw_lps_state_chk() @hal_com.c */ +#define BIT_PWRBIT_OW_EN BIT_WMAC_TCR_PWRMGT_CTL_8723F + + +/* +* Structure +*/ +struct qinfo_8723f { + u32 head:8; + u32 pkt_num:7; + u32 tail:8; + u32 ac:2; + u32 macid:7; +}; + +struct bcn_qinfo_8723f { + u16 head:8; + u16 pkt_num:8; +}; + + +/* +* General Functions +*/ +void rtl8723f_init_hal_spec(PADAPTER); /* hal/hal_com.c */ + +#ifdef CONFIG_MP_INCLUDED +/* MP Functions */ +#include /* struct mp_priv */ +void rtl8723f_prepare_mp_txdesc(PADAPTER, struct mp_priv *); /* rtw_mp.c */ +void rtl8723f_mp_config_rfpath(PADAPTER); /* hal_mp.c */ +#endif +void hw_var_set_dl_rsvd_page(PADAPTER adapter, u8 mstatus); + +#ifdef CONFIG_USB_HCI +#include +#elif defined(CONFIG_SDIO_HCI) +#include +#endif + +#endif /* _RTL8723F_HAL_H_ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723fs_hal.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723fs_hal.h new file mode 100644 index 000000000000..bd69ff116aae --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723fs_hal.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2019 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#ifndef _RTL8723FS_HAL_H_ +#define _RTL8723FS_HAL_H_ + +#include /* PADAPTER */ + +/* rtl8723fs_ops.c */ +void rtl8723fs_set_hal_ops(PADAPTER); + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +void rtl8723fs_disable_interrupt_but_cpwm2(PADAPTER adapter); +#endif + +/* rtl8723fs_xmit.c */ +s32 rtl8723fs_dequeue_writeport(PADAPTER); +#define _dequeue_writeport(a) rtl8723fs_dequeue_writeport(a) + +#endif /* _RTL8723FS_HAL_H_ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723fu_hal.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723fu_hal.h new file mode 100644 index 000000000000..d74829ffd48f --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8723fu_hal.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2019 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#ifndef _RTL8723FU_HAL_H_ +#define _RTL8723FU_HAL_H_ + +#ifdef CONFIG_USB_HCI + #include /* PADAPTER */ + + #ifdef CONFIG_USB_HCI + #ifdef USB_PACKET_OFFSET_SZ + #define PACKET_OFFSET_SZ (USB_PACKET_OFFSET_SZ) + #else + #define PACKET_OFFSET_SZ (8) + #endif + #define TXDESC_OFFSET (TXDESC_SIZE + PACKET_OFFSET_SZ) + #endif + + /* undefine MAX_RECVBUF_SZ from rtl8723f_hal.h */ + #ifdef MAX_RECVBUF_SZ + #undef MAX_RECVBUF_SZ + #endif + + /* recv_buffer must be large than usb agg size */ + #ifndef MAX_RECVBUF_SZ + #ifndef CONFIG_MINIMAL_MEMORY_USAGE + #ifdef CONFIG_PLATFORM_NOVATEK_NT72668 + #define MAX_RECVBUF_SZ (15360) /* 15k */ + #elif defined(CONFIG_PLATFORM_HISILICON) + /* use 16k to workaround for HISILICON platform */ + #define MAX_RECVBUF_SZ (16384) + #else + #define MAX_RECVBUF_SZ (32768) + #endif + #else + #define MAX_RECVBUF_SZ (4000) + #endif + #endif /* !MAX_RECVBUF_SZ */ + + /* rtl8723fu_ops.c */ + void rtl8723fu_set_hal_ops(PADAPTER padapter); + void rtl8723fu_set_hw_type(struct dvobj_priv *pdvobj); + + /* rtl8723fu_io.c */ + void rtl8723fu_set_intf_ops(struct _io_ops *pops); + +#endif /* CONFIG_USB_HCI */ + + +#endif /* _RTL8723FU_HAL_H_ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8812a_cmd.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8812a_cmd.h index 6c540a613a0e..f9286cc72352 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8812a_cmd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8812a_cmd.h @@ -119,12 +119,6 @@ void rtl8812_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); void rtl8812_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param); #endif -#ifdef CONFIG_TDLS -#ifdef CONFIG_TDLS_CH_SW -void rtl8812_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); -#endif -#endif - /* ------------------------------------ * C2H format * ------------------------------------ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8812a_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8812a_xmit.h index 06c113a0a054..35254ddcee76 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8812a_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8812a_xmit.h @@ -327,6 +327,9 @@ s32 rtl8812au_init_xmit_priv(PADAPTER padapter); void rtl8812au_free_xmit_priv(PADAPTER padapter); s32 rtl8812au_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8812au_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtl8812au_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8812au_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8812au_xmit_buf_handler(PADAPTER padapter); void rtl8812au_xmit_tasklet(void *priv); @@ -340,6 +343,9 @@ struct xmit_buf *rtl8812ae_dequeue_xmitbuf(struct rtw_tx_ring *ring); void rtl8812ae_xmitframe_resume(_adapter *padapter); s32 rtl8812ae_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8812ae_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtl8812ae_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8812ae_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8812ae_xmit_tasklet(void *priv); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8814a_cmd.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8814a_cmd.h index cea72bd8d377..a52e108940d6 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8814a_cmd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8814a_cmd.h @@ -142,11 +142,6 @@ void rtl8814_set_FwPwrMode_cmd(PADAPTER padapter, u8 PSMode); u8 GetTxBufferRsvdPageNum8814(_adapter *padapter, bool wowlan); void rtl8814_req_txrpt_cmd(PADAPTER padapter, u8 macid); -#ifdef CONFIG_TDLS - #ifdef CONFIG_TDLS_CH_SW - void rtl8814_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable); - #endif -#endif void rtl8814a_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param); void diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8814a_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8814a_xmit.h index e8166e995d67..0a9af96b68ec 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8814a_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8814a_xmit.h @@ -273,6 +273,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8814au_free_xmit_priv(PADAPTER padapter); s32 rtl8814au_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8814au_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8814au_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8814au_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); s32 rtl8814au_xmit_buf_handler(PADAPTER padapter); void rtl8814au_xmit_tasklet(void *priv); @@ -286,6 +289,9 @@ void fill_txdesc_bmc_tx_rate(struct pkt_attrib *pattrib, u8 *ptxdesc); void rtl8814ae_xmitframe_resume(_adapter *padapter); s32 rtl8814ae_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 rtl8814ae_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE + s32 rtl8814ae_hal_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif s32 rtl8814ae_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); void rtl8814ae_xmit_tasklet(void *priv); #ifdef CONFIG_XMIT_THREAD_MODE diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8821a_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8821a_xmit.h index b457d15adb41..024cca979019 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8821a_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtl8821a_xmit.h @@ -141,6 +141,9 @@ s32 InitXmitPriv8821AS(PADAPTER padapter); void FreeXmitPriv8821AS(PADAPTER padapter); s32 XmitBufHandler8821AS(PADAPTER padapter); s32 MgntXmit8821AS(PADAPTER padapter, struct xmit_frame *pmgntframe); +#ifdef CONFIG_RTW_MGMT_QUEUE +s32 rtl8821as_hal_mgmt_xmit_enqueue(PADAPTER adapter, struct xmit_frame *pxmitframe); +#endif s32 HalXmitNoLock8821AS(PADAPTER padapter, struct xmit_frame *pxmitframe); s32 HalXmit8821AS(PADAPTER padapter, struct xmit_frame *pxmitframe); #ifndef CONFIG_SDIO_TX_TASKLET diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_ap.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_ap.h index aeacb9bb3424..ac7e7181921c 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_ap.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_ap.h @@ -74,7 +74,7 @@ void stop_ap_mode(_adapter *padapter); void rtw_ap_update_bss_chbw(_adapter *adapter, WLAN_BSSID_EX *bss, u8 ch, u8 bw, u8 offset); u8 rtw_ap_chbw_decision(_adapter *adapter, u8 ifbmp, u8 excl_ifbmp - , s16 req_ch, s8 req_bw, s8 req_offset, u8 *ch, u8 *bw, u8 *offset, u8 *chbw_allow); + , s16 req_ch, s8 req_bw, s8 req_offset, u8 *ch, u8 *bw, u8 *offset, u8 *chbw_allow, bool *set_u_ch); #ifdef CONFIG_AUTO_AP_MODE void rtw_auto_ap_rx_msg_dump(_adapter *padapter, union recv_frame *precv_frame, u8 *ehdr_pos); @@ -87,6 +87,35 @@ u16 rtw_ap_parse_sta_security_ie(_adapter *adapter, struct sta_info *sta, struct void rtw_ap_parse_sta_wmm_ie(_adapter *adapter, struct sta_info *sta, u8 *tlv_ies, u16 tlv_ies_len); void rtw_ap_parse_sta_ht_ie(_adapter *adapter, struct sta_info *sta, struct rtw_ieee802_11_elems *elems); void rtw_ap_parse_sta_vht_ie(_adapter *adapter, struct sta_info *sta, struct rtw_ieee802_11_elems *elems); +void rtw_ap_parse_sta_multi_ap_ie(_adapter *adapter, struct sta_info *sta, u8 *ies, int ies_len); + +/* b2u flags */ +#define RTW_AP_B2U_ALL BIT0 +#define RTW_AP_B2U_GA_UCAST BIT1 /* WDS group addressed unicast frame, forward only */ +#define RTW_AP_B2U_BCAST BIT2 +#define RTW_AP_B2U_IP_MCAST BIT3 + +#define rtw_ap_src_b2u_policy_chk(flags, da) ( \ + (flags & RTW_AP_B2U_ALL) \ + || ((flags & RTW_AP_B2U_BCAST) && is_broadcast_mac_addr(da)) \ + || ((flags & RTW_AP_B2U_IP_MCAST) && (IP_MCAST_MAC(da) || ICMPV6_MCAST_MAC(da))) \ + ) + +#define rtw_ap_fwd_b2u_policy_chk(flags, da, gaucst) ( \ + (flags & RTW_AP_B2U_ALL) \ + || ((flags & RTW_AP_B2U_GA_UCAST) && gaucst) \ + || ((flags & RTW_AP_B2U_BCAST) && is_broadcast_mac_addr(da)) \ + || ((flags & RTW_AP_B2U_IP_MCAST) && (IP_MCAST_MAC(da) || ICMPV6_MCAST_MAC(da))) \ + ) + +void dump_ap_b2u_flags(void *sel, _adapter *adapter); + +int rtw_ap_addr_resolve(_adapter *adapter, u16 os_qid, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list); +int rtw_ap_rx_data_validate_hdr(_adapter *adapter, union recv_frame *rframe, struct sta_info **sta); +int rtw_ap_rx_msdu_act_check(union recv_frame *rframe + , const u8 *da, const u8 *sa + , u8 *msdu, enum rtw_rx_llc_hdl llc_hdl + , struct xmit_frame **fwd_frame, _list *b2u_list); void update_bmc_sta(_adapter *padapter); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_btcoex.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_btcoex.h index 80166e408ef0..48c908d5f480 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_btcoex.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_btcoex.h @@ -58,6 +58,12 @@ typedef enum _BTCOEX_SUSPEND_STATE { BTCOEX_SUSPEND_STATE_MAX } BTCOEX_SUSPEND_STATE, *PBTCOEX_SUSPEND_STATE; +typedef enum _BTCOEX_POLICY_CONTROL { + BTCOEX_POLICY_CONTROL_AUTO, + BTCOEX_POLICY_CONTROL_FORCE_FREERUN, + BTCOEX_POLICY_CONTROL_FORCE_TDMA +} BTCOEX_POLICY_CONTROL, *PBTCOEX_POLICY_CONTROL; + #define SET_BT_MP_OPER_RET(OpCode, StatusCode) ((OpCode << 8) | StatusCode) #define GET_OP_CODE_FROM_BT_MP_OPER_RET(RetCode) ((RetCode & 0xF0) >> 8) #define GET_STATUS_CODE_FROM_BT_MP_OPER_RET(RetCode) (RetCode & 0x0F) @@ -377,6 +383,7 @@ void rtw_btcoex_ScanNotify(PADAPTER, u8 type); void rtw_btcoex_MediaStatusNotify(PADAPTER, u8 mediaStatus); void rtw_btcoex_SpecialPacketNotify(PADAPTER, u8 pktType); void rtw_btcoex_IQKNotify(PADAPTER padapter, u8 state); +void rtw_btcoex_WLRFKNotify(PADAPTER padapter, u8 path, u8 type, u8 state); void rtw_btcoex_BtInfoNotify(PADAPTER, u8 length, u8 *tmpBuf); void rtw_btcoex_BtMpRptNotify(PADAPTER, u8 length, u8 *tmpBuf); void rtw_btcoex_SuspendNotify(PADAPTER, u8 state); @@ -392,6 +399,7 @@ s32 rtw_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter); s32 rtw_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER); u32 rtw_btcoex_GetAMPDUSize(PADAPTER); void rtw_btcoex_SetManualControl(PADAPTER, u8 bmanual); +void rtw_btcoex_set_policy_control(PADAPTER, u8 btc_policy); u8 rtw_btcoex_1Ant(PADAPTER); u8 rtw_btcoex_IsBtControlLps(PADAPTER); u8 rtw_btcoex_IsLpsOn(PADAPTER); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_cmd.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_cmd.h index 5518ff0213ae..1e2436feef30 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_cmd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_cmd.h @@ -184,9 +184,10 @@ extern void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv); extern void rtw_evt_notify_isr(struct evt_priv *pevtpriv); #ifdef CONFIG_P2P u8 p2p_protocol_wk_cmd(_adapter *padapter, int intCmdType); +#endif /* CONFIG_P2P */ #ifdef CONFIG_IOCTL_CFG80211 -struct p2p_roch_parm { +struct rtw_roch_parm { u64 cookie; struct wireless_dev *wdev; struct ieee80211_channel ch; @@ -194,18 +195,15 @@ struct p2p_roch_parm { unsigned int duration; }; -u8 p2p_roch_cmd(_adapter *adapter +u8 rtw_roch_cmd(_adapter *adapter , u64 cookie, struct wireless_dev *wdev , struct ieee80211_channel *ch, enum nl80211_channel_type ch_type , unsigned int duration , u8 flags ); -u8 p2p_cancel_roch_cmd(_adapter *adapter, u64 cookie, struct wireless_dev *wdev, u8 flags); -#endif /* CONFIG_IOCTL_CFG80211 */ -#endif /* CONFIG_P2P */ +u8 rtw_cancel_roch_cmd(_adapter *adapter, u64 cookie, struct wireless_dev *wdev, u8 flags); -#ifdef CONFIG_IOCTL_CFG80211 u8 rtw_mgnt_tx_cmd(_adapter *adapter, u8 tx_ch, u8 no_cck, const u8 *buf, size_t len, int wait_ack, u8 flags); struct mgnt_tx_parm { u8 tx_ch; @@ -249,6 +247,7 @@ enum rtw_drvextra_cmd_id { #ifdef CONFIG_RTW_REPEATER_SON RSON_SCAN_WK_CID, #endif + ROCH_WK_CID, MGNT_TX_WK_CID, REQ_PER_CMD_WK_CID, SSMPS_WK_CID, @@ -541,10 +540,15 @@ struct set_ch_parm { }; struct SetChannelPlan_param { + enum regd_src_t regd_src; const struct country_chplan *country_ent; u8 channel_plan; }; +struct get_channel_plan_param { + struct get_chplan_resp **resp; +}; + struct LedBlink_param { void *pLed; }; @@ -590,8 +594,10 @@ Result: void rtw_init_sitesurvey_parm(_adapter *padapter, struct sitesurvey_parm *pparm); u8 rtw_sitesurvey_cmd(_adapter *padapter, struct sitesurvey_parm *pparm); +#ifdef CONFIG_AP_MODE u8 rtw_create_ibss_cmd(_adapter *adapter, int flags); u8 rtw_startbss_cmd(_adapter *adapter, int flags); +#endif #define REQ_CH_NONE -1 #define REQ_CH_INT_INFO -2 @@ -599,9 +605,6 @@ u8 rtw_startbss_cmd(_adapter *adapter, int flags); #define REQ_BW_ORI -2 #define REQ_OFFSET_NONE -1 -u8 rtw_change_bss_chbw_cmd(_adapter *adapter, int flags - , u8 ifbmp, u8 excl_ifbmp, s16 req_ch, s8 req_bw, s8 req_offset); - struct sta_info; extern u8 rtw_setstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 key_type, bool enqueue); extern u8 rtw_clearstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 enqueue); @@ -609,6 +612,8 @@ extern u8 rtw_clearstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 enque extern u8 rtw_joinbss_cmd(_adapter *padapter, struct wlan_network *pnetwork); u8 rtw_disassoc_cmd(_adapter *padapter, u32 deauth_timeout_ms, int flags); #ifdef CONFIG_AP_MODE +u8 rtw_change_bss_chbw_cmd(_adapter *adapter, int flags + , u8 ifbmp, u8 excl_ifbmp, s16 req_ch, s8 req_bw, s8 req_offset); u8 rtw_stop_ap_cmd(_adapter *adapter, u8 flags); #endif #ifdef CONFIG_RTW_TOKEN_BASED_XMIT @@ -668,9 +673,14 @@ u8 rtw_enable_hw_update_tsf_cmd(_adapter *padapter); u8 rtw_periodic_tsf_update_end_cmd(_adapter *adapter); u8 rtw_set_chbw_cmd(_adapter *padapter, u8 ch, u8 bw, u8 ch_offset, u8 flags); +u8 rtw_iqk_cmd(_adapter *padapter, u8 flags); u8 rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, u8 swconfig); u8 rtw_set_country_cmd(_adapter *adapter, int flags, const char *country_code, u8 swconfig); +#ifdef CONFIG_REGD_SRC_FROM_OS +u8 rtw_sync_os_regd_cmd(_adapter *adapter, int flags, const char *country_code, u8 dfs_region); +#endif +u8 rtw_get_chplan_cmd(_adapter *adapter, int flags, struct get_chplan_resp **resp); extern u8 rtw_led_blink_cmd(_adapter *padapter, void *pLed); extern u8 rtw_set_csa_cmd(_adapter *adapter); @@ -767,6 +777,8 @@ enum rtw_cmd_id { CMD_ADD_BARSP, /*19*/ CMD_RM_POST_EVENT, /*20*/ CMD_SET_MESH_PLINK_STATE, /* 21 */ + CMD_DO_IQK, /* 22 */ + CMD_GET_CHANPLAN, /*23*/ CMD_ID_MAX }; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_debug.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_debug.h index c028dd201514..029bf4a1475c 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_debug.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_debug.h @@ -285,7 +285,6 @@ extern uint rtw_drv_log_level; void dump_drv_version(void *sel); void dump_log_level(void *sel); -void dump_drv_cfg(void *sel); #ifdef CONFIG_SDIO_HCI void sd_f0_reg_dump(void *sel, _adapter *adapter); @@ -307,8 +306,10 @@ void dump_tx_rate_bmp(void *sel, struct dvobj_priv *dvobj); void dump_adapters_status(void *sel, struct dvobj_priv *dvobj); struct sec_cam_ent; +#if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG) void dump_sec_cam_ent(void *sel, struct sec_cam_ent *ent, int id); void dump_sec_cam_ent_title(void *sel, u8 has_id); +#endif void dump_sec_cam(void *sel, _adapter *adapter); void dump_sec_cam_cache(void *sel, _adapter *adapter); @@ -328,7 +329,7 @@ u16 rtw_ap_linking_test_force_asoc_fail(void); ssize_t proc_set_write_reg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); int proc_get_read_reg(struct seq_file *m, void *v); ssize_t proc_set_read_reg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); - +void dump_drv_cfg(void *sel); int proc_get_fwstate(struct seq_file *m, void *v); int proc_get_sec_info(struct seq_file *m, void *v); int proc_get_mlmext_state(struct seq_file *m, void *v); @@ -339,10 +340,6 @@ int proc_get_roam_param(struct seq_file *m, void *v); ssize_t proc_set_roam_param(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); ssize_t proc_set_roam_tgt_addr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); #endif /* CONFIG_LAYER2_ROAMING */ -#ifdef CONFIG_RTW_80211R -int proc_get_ft_flags(struct seq_file *m, void *v); -ssize_t proc_set_ft_flags(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); -#endif int proc_get_qos_option(struct seq_file *m, void *v); int proc_get_ht_option(struct seq_file *m, void *v); int proc_get_rf_info(struct seq_file *m, void *v); @@ -444,6 +441,10 @@ ssize_t proc_set_ldpc_cap(struct file *file, const char __user *buffer, size_t c int proc_get_txbf_cap(struct seq_file *m, void *v); ssize_t proc_set_txbf_cap(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); #endif +#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT +int proc_get_tx_aval_th(struct seq_file *m, void *v); +ssize_t proc_set_tx_aval_th(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#endif /*CONFIG_SDIO_TX_ENABLE_AVAL_INT*/ int proc_get_rx_ampdu_factor(struct seq_file *m, void *v); ssize_t proc_set_rx_ampdu_factor(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); @@ -466,6 +467,11 @@ ssize_t proc_set_tx_amsdu_rate(struct file *file, const char __user *buffer, siz #endif #endif /* CONFIG_80211N_HT */ +#ifdef CONFIG_80211AC_VHT +int proc_get_vht_24g_enable(struct seq_file *m, void *v); +ssize_t proc_set_vht_24g_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#endif + ssize_t proc_set_dyn_rrsr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); int proc_get_dyn_rrsr(struct seq_file *m, void *v); @@ -530,8 +536,29 @@ int proc_get_wakeup_event(struct seq_file *m, void *v); ssize_t proc_set_wakeup_event(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); int proc_get_wakeup_reason(struct seq_file *m, void *v); +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +int proc_dump_wow_keep_alive_info(struct seq_file *m, void *v); +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ #endif +#ifdef CONFIG_WAR_OFFLOAD +int proc_get_war_offload_enable(struct seq_file *m, void *v); +ssize_t proc_set_war_offload_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_war_offload_ipv4_addr(struct seq_file *m, void *v); +ssize_t proc_set_war_offload_ipv4_addr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_war_offload_ipv6_addr(struct seq_file *m, void *v); +ssize_t proc_set_war_offload_ipv6_addr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_war_offload_mdns_domain_name(struct seq_file *m, void *v); +ssize_t proc_set_war_offload_mdns_domain_name(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_war_offload_mdns_machine_name(struct seq_file *m, void *v); +ssize_t proc_set_war_offload_mdns_machine_name(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_war_offload_mdns_txt_rsp(struct seq_file *m, void *v); +ssize_t proc_set_war_offload_mdns_txt_rsp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_war_offload_mdns_service_info(struct seq_file *m, void *v); +ssize_t proc_set_war_offload_mdns_service_info(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#endif /* CONFIG_WAR_OFFLOAD */ + + #ifdef CONFIG_GPIO_WAKEUP int proc_get_wowlan_gpio_info(struct seq_file *m, void *v); ssize_t proc_set_wowlan_gpio_info(struct file *file, const char __user *buffer, @@ -563,6 +590,11 @@ int proc_get_tdls_info(struct seq_file *m, void *v); int proc_get_monitor(struct seq_file *m, void *v); ssize_t proc_set_monitor(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#ifdef RTW_SIMPLE_CONFIG +int proc_get_simple_config(struct seq_file *m, void *v); +ssize_t proc_set_simple_config(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#endif + #ifdef DBG_XMIT_BLOCK int proc_get_xmit_block(struct seq_file *m, void *v); ssize_t proc_set_xmit_block(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_efuse.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_efuse.h index b40c6ff739ae..e47e12896d8e 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_efuse.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_efuse.h @@ -54,17 +54,25 @@ enum _EFUSE_DEF_TYPE { /*RTL8822B 8821C BT EFUSE Define 1 BANK 128 size logical map 1024*/ #ifdef RTW_HALMAC #define BANK_NUM 1 -#define EFUSE_BT_REAL_BANK_CONTENT_LEN 128 +#if defined(CONFIG_RTL8723F) +#define EFUSE_BT_REAL_BANK_CONTENT_LEN 512 +#else +#define EFUSE_BT_REAL_BANK_CONTENT_LEN 128 +#endif + #define EFUSE_BT_REAL_CONTENT_LEN (EFUSE_BT_REAL_BANK_CONTENT_LEN * BANK_NUM) #define EFUSE_BT_MAP_LEN 1024 /* 1k bytes */ #define EFUSE_BT_MAX_SECTION (EFUSE_BT_MAP_LEN / 8) -#ifdef CONFIG_RTL8822C + +#if defined(CONFIG_RTL8822C) #define EFUSE_PROTECT_BYTES_BANK 54 +#elif defined(CONFIG_RTL8723F) +#define EFUSE_PROTECT_BYTES_BANK 40 #else #define EFUSE_PROTECT_BYTES_BANK 16 #endif #define AVAILABLE_EFUSE_ADDR(addr) (addr < EFUSE_BT_REAL_CONTENT_LEN - EFUSE_PROTECT_BYTES_BANK) -#endif +#endif /* #ifdef RTW_HALMAC */ #define EXT_HEADER(header) ((header & 0x1F) == 0x0F) #define ALL_WORDS_DISABLED(wde) ((wde & 0x0F) == 0x0F) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_event.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_event.h index 36ff005822a3..517dc8f2690c 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_event.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_event.h @@ -37,6 +37,7 @@ bss_cnt indicates the number of bss that has been reported. */ struct surveydone_event { unsigned int bss_cnt; + u8 activate_ch_cnt; bool acs; /* aim to trigger channel selection */ }; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_ft.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_ft.h new file mode 100644 index 000000000000..db1c4af4e187 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_ft.h @@ -0,0 +1,184 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#ifndef __RTW_FT_H_ +#define __RTW_FT_H_ + +enum rtw_ieee80211_ft_actioncode { + RTW_WLAN_ACTION_FT_RESV, + RTW_WLAN_ACTION_FT_REQ, + RTW_WLAN_ACTION_FT_RSP, + RTW_WLAN_ACTION_FT_CONF, + RTW_WLAN_ACTION_FT_ACK, + RTW_WLAN_ACTION_FT_MAX, +}; + +enum _rtw_ft_sta_status { + RTW_FT_UNASSOCIATED_STA = 0, + RTW_FT_AUTHENTICATING_STA, + RTW_FT_AUTHENTICATED_STA, + RTW_FT_ASSOCIATING_STA, + RTW_FT_ASSOCIATED_STA, + RTW_FT_REQUESTING_STA, + RTW_FT_REQUESTED_STA, + RTW_FT_CONFIRMED_STA, + RTW_FT_UNSPECIFIED_STA +}; + +#define RTW_FT_ACTION_REQ_LMT 4 + +#define RTW_FT_MAX_IE_SZ 256 + +#define rtw_ft_chk_status(a, s) \ + ((a)->mlmepriv.ft_roam.ft_status == (s)) + +#define rtw_ft_roam_status(a, s) \ + ((rtw_to_roam(a) > 0) && rtw_ft_chk_status(a, s)) + +#define rtw_ft_authed_sta(a) \ + ((rtw_ft_chk_status(a, RTW_FT_AUTHENTICATED_STA)) || \ + (rtw_ft_chk_status(a, RTW_FT_ASSOCIATING_STA)) || \ + (rtw_ft_chk_status(a, RTW_FT_ASSOCIATED_STA))) + +#define rtw_ft_set_status(a, s) \ + do { \ + ((a)->mlmepriv.ft_roam.ft_status = (s)); \ + } while (0) + +#define rtw_ft_lock_set_status(a, s, irq) \ + do { \ + _enter_critical_bh(&(a)->mlmepriv.lock, ((_irqL *)(irq))); \ + ((a)->mlmepriv.ft_roam.ft_status = (s)); \ + _exit_critical_bh(&(a)->mlmepriv.lock, ((_irqL *)(irq))); \ + } while (0) + +#define rtw_ft_reset_status(a) \ + do { \ + ((a)->mlmepriv.ft_roam.ft_status = RTW_FT_UNASSOCIATED_STA); \ + } while (0) + +enum rtw_ft_capability { + RTW_FT_EN = BIT0, + RTW_FT_OTD_EN = BIT1, + RTW_FT_PEER_EN = BIT2, + RTW_FT_PEER_OTD_EN = BIT3, + RTW_FT_BTM_ROAM = BIT4, + RTW_FT_TEST_RSSI_ROAM = BIT7, +}; + +#define rtw_ft_chk_flags(a, f) \ + ((a)->mlmepriv.ft_roam.ft_flags & (f)) + +#define rtw_ft_set_flags(a, f) \ + do { \ + ((a)->mlmepriv.ft_roam.ft_flags |= (f)); \ + } while (0) + +#define rtw_ft_clr_flags(a, f) \ + do { \ + ((a)->mlmepriv.ft_roam.ft_flags &= ~(f)); \ + } while (0) + +#define rtw_ft_roam(a) \ + ((rtw_to_roam(a) > 0) && rtw_ft_chk_flags(a, RTW_FT_PEER_EN)) + +#define rtw_ft_valid_akm(a, t) \ + ((rtw_ft_chk_flags(a, RTW_FT_EN)) && \ + (((t) == 3) || ((t) == 4))) + +#define rtw_ft_roam_expired(a, r) \ + ((rtw_chk_roam_flags(a, RTW_ROAM_ON_EXPIRED)) \ + && (r == WLAN_REASON_ACTIVE_ROAM)) + +#define rtw_ft_otd_roam_en(a) \ + ((rtw_ft_chk_flags(a, RTW_FT_OTD_EN)) \ + && ((a)->mlmepriv.ft_roam.ft_roam_on_expired == _FALSE) \ + && ((a)->mlmepriv.ft_roam.ft_cap & 0x01)) + +#define rtw_ft_otd_roam(a) \ + rtw_ft_chk_flags(a, RTW_FT_PEER_OTD_EN) + +#define rtw_ft_valid_otd_candidate(a, p) \ + ((rtw_ft_chk_flags(a, RTW_FT_OTD_EN)) \ + && ((rtw_ft_chk_flags(a, RTW_FT_PEER_OTD_EN) \ + && ((*((p)+4) & 0x01) == 0)) \ + || ((rtw_ft_chk_flags(a, RTW_FT_PEER_OTD_EN) == 0) \ + && (*((p)+4) & 0x01)))) + +struct ft_roam_info { + u16 mdid; + u8 ft_cap; + /*b0: FT over DS, b1: Resource Req Protocol Cap, b2~b7: Reserved*/ + u8 updated_ft_ies[RTW_FT_MAX_IE_SZ]; + u16 updated_ft_ies_len; + u8 ft_action[RTW_FT_MAX_IE_SZ]; + u16 ft_action_len; + struct cfg80211_ft_event_params ft_event; + u8 ft_roam_on_expired; + u8 ft_flags; + u32 ft_status; + u32 ft_req_retry_cnt; + bool ft_updated_bcn; +}; + +void rtw_ft_info_init(struct ft_roam_info *pft); + +int rtw_ft_proc_flags_get(struct seq_file *m, void *v); + +ssize_t rtw_ft_proc_flags_set(struct file *file, const char __user *buffer, + size_t count, loff_t *pos, void *data); + +u8 rtw_ft_chk_roaming_candidate( + _adapter *padapter, struct wlan_network *competitor); + +void rtw_ft_update_stainfo(_adapter *padapter, WLAN_BSSID_EX *pnetwork); + +void rtw_ft_reassoc_event_callback(_adapter *padapter, u8 *pbuf); + +void rtw_ft_validate_akm_type(_adapter *padapter, + struct wlan_network *pnetwork); + +void rtw_ft_update_bcn(_adapter *padapter, union recv_frame *precv_frame); + +void rtw_ft_start_clnt_join(_adapter *padapter); + +u8 rtw_ft_update_rsnie( + _adapter *padapter, u8 bwrite, + struct pkt_attrib *pattrib, u8 **pframe); + +void rtw_ft_build_auth_req_ies(_adapter *padapter, + struct pkt_attrib *pattrib, u8 **pframe); + +void rtw_ft_build_assoc_req_ies(_adapter *padapter, + u8 is_reassoc, struct pkt_attrib *pattrib, u8 **pframe); + +u8 rtw_ft_update_auth_rsp_ies(_adapter *padapter, u8 *pframe, u32 len); + +void rtw_ft_start_roam(_adapter *padapter, u8 *pTargetAddr); + +void rtw_ft_issue_action_req(_adapter *padapter, u8 *pTargetAddr); + +void rtw_ft_report_evt(_adapter *padapter); + +void rtw_ft_report_reassoc_evt(_adapter *padapter, u8 *pMacAddr); + +void rtw_ft_link_timer_hdl(void *ctx); + +void rtw_ft_roam_timer_hdl(void *ctx); + +void rtw_ft_roam_status_reset(_adapter *padapter); + +#endif /* __RTW_FT_H_ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mbo.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mbo.h new file mode 100644 index 000000000000..2c8a6a7e6ae5 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mbo.h @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#ifndef __RTW_MBO_H_ +#define __RTW_MBO_H_ + +#define rtw_mbo_wifi_logo_test(a) ((a->registrypriv.wifi_spec) == 1) + +#define rtw_mbo_set_ext_cap_internw(_pEleStart, _val) \ + SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart))+3, 7, 1, _val) + +#define rtw_mbo_wnm_notification_req(c, a) \ + (((c) == RTW_WLAN_CATEGORY_WNM) && \ + (((a) == RTW_WLAN_ACTION_WNM_NOTIF_REQ))) + +/* IEEE Std 802.11-2016 Table 9-46 - Status codes */ +#define RTW_ASSOC_DENIED_NO_MORE_STAS 17 +#define RTW_ASSOC_REFUSED_TEMPORARILY 30 + +/* MBO-OCE Information Element */ +#define RTW_MBO_EID WLAN_EID_VENDOR_SPECIFIC +#define RTW_MBO_OUI 0x506F9A +#define RTW_MBO_OUI_TYPE 0x16 + +/* Non-preferred Channel Report */ +#define RTW_MBO_ATTR_NPREF_CH_RPT_ID 0x2 +/* Cellular Data Capabilities */ +#define RTW_MBO_ATTR_CELL_DATA_CAP_ID 0x3 +/* Association Disallowed */ +#define RTW_MBO_ATTR_ASSOC_DISABLED_ID 0x4 +/* Transition Reason Code */ +#define RTW_MBO_ATTR_TRANS_RES_ID 0x6 +/* Transition Rejection Reason Code */ +#define RTW_MBO_ATTR_TRANS_REJ_ID 0x7 +/* Association Retry Delay */ +#define RTW_MBO_ATTR_TASSOC_RETRY_ID 0x8 + +#define RTW_MBO_MAX_CH_LIST_NUM MAX_CHANNEL_NUM + +#define RTW_MBO_MAX_CH_RPT_NUM 32 + +struct npref_ch { + u8 op_class; + u8 chs[RTW_MBO_MAX_CH_LIST_NUM]; + size_t nm_of_ch; + u8 preference; + u8 reason; +}; + +struct npref_ch_rtp { + struct npref_ch ch_rpt[RTW_MBO_MAX_CH_RPT_NUM]; + size_t nm_of_rpt; +}; + +void rtw_mbo_build_cell_data_cap_attr( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib); + +void rtw_mbo_update_ie_data( + _adapter *padapter, u8 *pie, u32 ie_len); + +void rtw_mbo_build_supp_op_class_elem( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib); + +void rtw_mbo_build_npref_ch_rpt_attr( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib); + +void rtw_mbo_build_trans_reject_reason_attr( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib, u8 *pres); + +u8 rtw_mbo_disallowed_network(struct wlan_network *pnetwork); + +void rtw_mbo_build_exented_cap( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib); + +ssize_t rtw_mbo_proc_non_pref_chans_set( + struct file *pfile, const char __user *buffer, + size_t count, loff_t *pos, void *pdata); + +int rtw_mbo_proc_non_pref_chans_get( + struct seq_file *m, void *v); + +ssize_t rtw_mbo_proc_cell_data_set( + struct file *pfile, const char __user *buffer, + size_t count, loff_t *pos, void *pdata); + +int rtw_mbo_proc_cell_data_get( + struct seq_file *m, void *v); + +void rtw_mbo_wnm_notification_parsing( + _adapter *padapter, const u8 *pdata, size_t data_len); + +void rtw_mbo_build_wnm_notification( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib); + +void rtw_mbo_build_probe_req_ies( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib); + +void rtw_mbo_build_assoc_req_ies( + _adapter *padapter, u8 **pframe, struct pkt_attrib *pattrib); + +#endif /* __RTW_MBO_H_ */ + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mcc.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mcc.h index 769c14468072..d895b5893ff2 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mcc.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mcc.h @@ -55,7 +55,11 @@ #define MCC_SINGLE_TX_CRITERIA 5 /* Mbps */ #define MAX_MCC_NUM 2 +#ifdef CONFIG_RTL8822C +#define DBG_MCC_REG_NUM 3 +#else #define DBG_MCC_REG_NUM 4 +#endif #define DBG_MCC_RF_REG_NUM 1 #define MCC_STOP(adapter) (adapter->mcc_adapterpriv.mcc_tx_stop) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mem.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mem.h index a225a5bb2b1f..ec1bdc399cb6 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mem.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mem.h @@ -20,18 +20,6 @@ #include #include -#ifdef CONFIG_SDIO_HCI -#define MAX_RTKM_RECVBUF_SZ MAX_RECVBUF_SZ -#define MAX_RTKM_NR_PREALLOC_RECV_SKB NR_RECVBUFF -#else /* !CONFIG_SDIO_HCI */ -#ifdef CONFIG_PLATFORM_MSTAR_HIGH - #define MAX_RTKM_RECVBUF_SZ (31744) /* 31k */ -#else - #define MAX_RTKM_RECVBUF_SZ (15360) /* 15k */ -#endif /* CONFIG_PLATFORM_MSTAR_HIGH */ -#define MAX_RTKM_NR_PREALLOC_RECV_SKB 16 -#endif /* !CONFIG_SDIO_HCI */ - u16 rtw_rtkm_get_buff_size(void); u8 rtw_rtkm_get_nr_recv_skb(void); struct u8 *rtw_alloc_revcbuf_premem(void); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mi.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mi.h index 63634d22d844..f535eb224813 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mi.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mi.h @@ -46,9 +46,7 @@ struct mi_state { u8 scan_enter_num; /* WIFI_UNDER_SURVEY && !SCAN_DISABLE && !SCAN_BACK_OP */ u8 uwps_num; /* WIFI_UNDER_WPS */ #ifdef CONFIG_IOCTL_CFG80211 - #ifdef CONFIG_P2P u8 roch_num; - #endif u8 mgmt_tx_num; #endif #ifdef CONFIG_P2P @@ -56,9 +54,6 @@ struct mi_state { u8 p2p_gc; u8 p2p_go; #endif - u8 union_ch; - u8 union_bw; - u8 union_offset; }; #define MSTATE_STA_NUM(_mstate) ((_mstate)->sta_num) @@ -96,7 +91,7 @@ struct mi_state { #define MSTATE_SCAN_ENTER_NUM(_mstate) ((_mstate)->scan_enter_num) #define MSTATE_WPS_NUM(_mstate) ((_mstate)->uwps_num) -#if defined(CONFIG_IOCTL_CFG80211) && defined(CONFIG_P2P) +#if defined(CONFIG_IOCTL_CFG80211) #define MSTATE_ROCH_NUM(_mstate) ((_mstate)->roch_num) #else #define MSTATE_ROCH_NUM(_mstate) 0 @@ -118,13 +113,9 @@ struct mi_state { #define MSTATE_MGMT_TX_NUM(_mstate) 0 #endif -#define MSTATE_U_CH(_mstate) ((_mstate)->union_ch) -#define MSTATE_U_BW(_mstate) ((_mstate)->union_bw) -#define MSTATE_U_OFFSET(_mstate) ((_mstate)->union_offset) - -#define rtw_mi_get_union_chan(adapter) adapter_to_dvobj(adapter)->iface_state.union_ch -#define rtw_mi_get_union_bw(adapter) adapter_to_dvobj(adapter)->iface_state.union_bw -#define rtw_mi_get_union_offset(adapter) adapter_to_dvobj(adapter)->iface_state.union_offset +#define rtw_mi_get_union_chan(adapter) ((adapter_to_dvobj(adapter)->union_ch) ? (adapter_to_dvobj(adapter)->union_ch) : (adapter_to_dvobj(adapter)->union_ch_bak)) +#define rtw_mi_get_union_bw(adapter) ((adapter_to_dvobj(adapter)->union_ch) ? (adapter_to_dvobj(adapter)->union_bw) : (adapter_to_dvobj(adapter)->union_bw_bak)) +#define rtw_mi_get_union_offset(adapter) ((adapter_to_dvobj(adapter)->union_ch) ? (adapter_to_dvobj(adapter)->union_offset) : (adapter_to_dvobj(adapter)->union_offset_bak)) #define rtw_mi_get_assoced_sta_num(adapter) DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) #define rtw_mi_get_ap_num(adapter) DEV_AP_NUM(adapter_to_dvobj(adapter)) @@ -249,6 +240,8 @@ u8 rtw_mi_buddy_check_pending_xmitbuf(_adapter *padapter); #include #elif defined(CONFIG_RTL8822C) #include +#elif defined(CONFIG_RTL8723F) + #include #else extern s32 _dequeue_writeport(PADAPTER padapter); #endif @@ -276,15 +269,17 @@ extern void sreset_start_adapter(_adapter *padapter); extern void sreset_stop_adapter(_adapter *padapter); u8 rtw_mi_sreset_adapter_hdl(_adapter *padapter, u8 bstart); u8 rtw_mi_buddy_sreset_adapter_hdl(_adapter *padapter, u8 bstart); + +#ifdef CONFIG_AP_MODE #if defined(DBG_CONFIG_ERROR_RESET) && defined(CONFIG_CONCURRENT_MODE) void rtw_mi_ap_info_restore(_adapter *adapter); #endif - u8 rtw_mi_tx_beacon_hdl(_adapter *padapter); u8 rtw_mi_buddy_tx_beacon_hdl(_adapter *padapter); u8 rtw_mi_set_tx_beacon_cmd(_adapter *padapter); u8 rtw_mi_buddy_set_tx_beacon_cmd(_adapter *padapter); +#endif /* CONFIG_AP_MODE */ #ifdef CONFIG_P2P u8 rtw_mi_p2p_chk_state(_adapter *padapter, enum P2P_STATE p2p_state); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mlme.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mlme.h index 22d7caa7c4d8..6e39dd6d9f00 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mlme.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mlme.h @@ -26,6 +26,9 @@ * Increase the scanning timeout because of increasing the SURVEY_TO value. */ #define SCANQUEUE_LIFETIME 20000 /* 20sec, unit:msec */ +#define MAX_UNASSOC_STA_CNT 128 +#define UNASSOC_STA_LIFETIME_MS 60000 + /*pmlmepriv->fw_state*/ #define WIFI_NULL_STATE 0x00000000 #define WIFI_ASOC_STATE 0x00000001 /* Linked */ @@ -58,7 +61,7 @@ /*#define WIFI_UNDEFINED_STATE 0x08000000*/ /*#define WIFI_UNDEFINED_STATE 0x10000000*/ /*#define WIFI_UNDEFINED_STATE 0x20000000*/ -/*#define WIFI_UNDEFINED_STATE 0x40000000*/ +#define WIFI_CSA_UPDATE_BEACON 0x40000000 #define WIFI_MONITOR_STATE 0x80000000 @@ -104,7 +107,7 @@ void rtw_wfd_st_switch(struct sta_info *sta, bool on); #define MLME_IS_OPCH_SW(adapter) CHK_MLME_STATE(adapter, WIFI_OP_CH_SWITCHING) #define MLME_IS_WPS(adapter) CHK_MLME_STATE(adapter, WIFI_UNDER_WPS) -#if defined(CONFIG_IOCTL_CFG80211) && defined(CONFIG_P2P) +#ifdef CONFIG_IOCTL_CFG80211 #define MLME_IS_ROCH(adapter) (rtw_cfg80211_get_is_roch(adapter) == _TRUE) #else #define MLME_IS_ROCH(adapter) 0 @@ -157,7 +160,14 @@ enum { MLME_MESH_STOPPED, MLME_OPCH_SWITCH, }; - +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +enum MODE_WOW_KEEP_ALIVE_PATTERN { + wow_keep_alive_pattern_disable = 0, + wow_keep_alive_pattern_tx, + wow_keep_alive_pattern_trx, + wow_keep_alive_pattern_trx_with_ack +}; +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ enum dot11AuthAlgrthmNum { dot11AuthAlgrthm_Open = 0, dot11AuthAlgrthm_Shared, @@ -345,20 +355,6 @@ struct scan_limit_info { #endif /* CONFIG_P2P_OP_CHK_SOCIAL_CH */ }; -#ifdef CONFIG_IOCTL_CFG80211 -struct cfg80211_wifidirect_info { - _timer remain_on_ch_timer; - u8 restore_channel; - struct ieee80211_channel remain_on_ch_channel; - enum nl80211_channel_type remain_on_ch_type; - ATOMIC_T ro_ch_cookie_gen; - u64 remain_on_ch_cookie; - bool is_ro_ch; - struct wireless_dev *ro_ch_wdev; - systime last_ro_ch_time; /* this will be updated at the beginning and end of ro_ch */ -}; -#endif /* CONFIG_IOCTL_CFG80211 */ - #ifdef CONFIG_P2P_WOWLAN enum P2P_WOWLAN_RECV_FRAME_TYPE { @@ -388,10 +384,7 @@ struct wifidirect_info { _timer pre_tx_scan_timer; _timer reset_ch_sitesurvey; _timer reset_ch_sitesurvey2; /* Just for resetting the scan limit function by using p2p nego */ -#ifdef CONFIG_CONCURRENT_MODE - /* Used to switch the channel between legacy AP and listen state. */ - _timer ap_p2p_switch_timer; -#endif + struct tx_provdisc_req_info tx_prov_disc_info; struct rx_provdisc_req_info rx_prov_disc_info; struct tx_invite_req_info invitereq_info; @@ -500,6 +493,7 @@ struct tdls_ch_switch { u8 addr[ETH_ALEN]; u8 off_ch_num; u8 ch_offset; + u8 bcn_early_reg_bkp; u32 cur_time; u8 delay_switch_back; u8 dump_stack; @@ -551,212 +545,27 @@ enum { RTW_ROAM_ACTIVE = BIT2, }; -#ifdef CONFIG_RTW_80211R -#define RTW_FT_ACTION_REQ_LMT 4 -#define RTW_FT_MAX_IE_SZ 256 +#define UNASOC_STA_SRC_RX_BMC 0 +#define UNASOC_STA_SRC_RX_NMY_UC 1 +#define UNASOC_STA_SRC_NUM 2 -enum _rtw_ft_sta_status { - RTW_FT_UNASSOCIATED_STA = 0, - RTW_FT_AUTHENTICATING_STA, - RTW_FT_AUTHENTICATED_STA, - RTW_FT_ASSOCIATING_STA, - RTW_FT_ASSOCIATED_STA, - RTW_FT_REQUESTING_STA, - RTW_FT_REQUESTED_STA, - RTW_FT_CONFIRMED_STA, - RTW_FT_UNSPECIFIED_STA +#define UNASOC_STA_MODE_DISABLED 0 +#define UNASOC_STA_MODE_INTERESTED 1 +#define UNASOC_STA_MODE_ALL 2 +#define UNASOC_STA_MODE_NUM 3 + +#define UNASOC_STA_DEL_CHK_SKIP 0 +#define UNASOC_STA_DEL_CHK_ALIVE 1 +#define UNASOC_STA_DEL_CHK_DELETED 2 + +#ifdef CONFIG_RTW_MULTI_AP +struct unassoc_sta_info { + _list list; + u8 addr[ETH_ALEN]; + u8 interested; + s8 recv_signal_power; + systime time; }; - -#define rtw_ft_chk_status(a, s) \ - ((a)->mlmepriv.ft_roam.ft_status == (s)) - -#define rtw_ft_roam_status(a, s) \ - ((rtw_to_roam(a) > 0) && rtw_ft_chk_status(a, s)) - -#define rtw_ft_authed_sta(a) \ - ((rtw_ft_chk_status(a, RTW_FT_AUTHENTICATED_STA)) || \ - (rtw_ft_chk_status(a, RTW_FT_ASSOCIATING_STA)) || \ - (rtw_ft_chk_status(a, RTW_FT_ASSOCIATED_STA))) - -#define rtw_ft_set_status(a, s) \ - do { \ - ((a)->mlmepriv.ft_roam.ft_status = (s)); \ - } while (0) - -#define rtw_ft_lock_set_status(a, s, irq) \ - do { \ - _enter_critical_bh(&(a)->mlmepriv.lock, ((_irqL *)(irq))); \ - ((a)->mlmepriv.ft_roam.ft_status = (s)); \ - _exit_critical_bh(&(a)->mlmepriv.lock, ((_irqL *)(irq))); \ - } while (0) - -#define rtw_ft_reset_status(a) \ - do { \ - ((a)->mlmepriv.ft_roam.ft_status = RTW_FT_UNASSOCIATED_STA); \ - } while (0) - -enum rtw_ft_capability { - RTW_FT_EN = BIT0, - RTW_FT_OTD_EN = BIT1, - RTW_FT_PEER_EN = BIT2, - RTW_FT_PEER_OTD_EN = BIT3, - RTW_FT_BTM_ROAM = BIT4, -}; - -#define rtw_ft_chk_flags(a, f) \ - ((a)->mlmepriv.ft_roam.ft_flags & (f)) - -#define rtw_ft_set_flags(a, f) \ - do { \ - ((a)->mlmepriv.ft_roam.ft_flags |= (f)); \ - } while (0) - -#define rtw_ft_clr_flags(a, f) \ - do { \ - ((a)->mlmepriv.ft_roam.ft_flags &= ~(f)); \ - } while (0) - -#define rtw_ft_roam(a) \ - ((rtw_to_roam(a) > 0) && rtw_ft_chk_flags(a, RTW_FT_PEER_EN)) - -#define rtw_ft_valid_akm(a, t) \ - ((rtw_ft_chk_flags(a, RTW_FT_EN)) && \ - (((t) == 3) || ((t) == 4))) - -#define rtw_ft_roam_expired(a, r) \ - ((rtw_chk_roam_flags(a, RTW_ROAM_ON_EXPIRED)) \ - && (r == WLAN_REASON_ACTIVE_ROAM)) - -#define rtw_ft_otd_roam_en(a) \ - ((rtw_ft_chk_flags(a, RTW_FT_OTD_EN)) \ - && ((a)->mlmepriv.ft_roam.ft_roam_on_expired == _FALSE) \ - && ((a)->mlmepriv.ft_roam.ft_cap & 0x01)) - -#define rtw_ft_otd_roam(a) \ - rtw_ft_chk_flags(a, RTW_FT_PEER_OTD_EN) - -#define rtw_ft_valid_otd_candidate(a, p) \ - ((rtw_ft_chk_flags(a, RTW_FT_OTD_EN)) \ - && ((rtw_ft_chk_flags(a, RTW_FT_PEER_OTD_EN) \ - && ((*((p)+4) & 0x01) == 0)) \ - || ((rtw_ft_chk_flags(a, RTW_FT_PEER_OTD_EN) == 0) \ - && (*((p)+4) & 0x01)))) - -struct ft_roam_info { - u16 mdid; - u8 ft_cap; - /*b0: FT over DS, b1: Resource Req Protocol Cap, b2~b7: Reserved*/ - u8 updated_ft_ies[RTW_FT_MAX_IE_SZ]; - u16 updated_ft_ies_len; - u8 ft_action[RTW_FT_MAX_IE_SZ]; - u16 ft_action_len; - struct cfg80211_ft_event_params ft_event; - u8 ft_roam_on_expired; - u8 ft_flags; - u32 ft_status; - u32 ft_req_retry_cnt; - bool ft_updated_bcn; -}; -#endif - -#ifdef CONFIG_LAYER2_ROAMING -#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) -#define RTW_RRM_NB_RPT_EN BIT(1) -#define RTW_MAX_NB_RPT_NUM 8 - -#define rtw_roam_busy_scan(a, nb) \ - (((a)->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE) && \ - (((a)->mlmepriv.ch_cnt) < ((nb)->nb_rpt_ch_list_num))) - -#define rtw_wnm_btm_preference_cap(a) \ - ((a)->mlmepriv.nb_info.preference_en == _TRUE) - -#define rtw_wnm_btm_diff_bss(a) \ - ((rtw_wnm_btm_preference_cap(a)) && \ - (is_zero_mac_addr((a)->mlmepriv.nb_info.roam_target_addr) == _FALSE) && \ - (_rtw_memcmp((a)->mlmepriv.nb_info.roam_target_addr,\ - (a)->mlmepriv.cur_network.network.MacAddress, ETH_ALEN) == _FALSE)) - -#define rtw_wnm_btm_roam_candidate(a, c) \ - ((rtw_wnm_btm_preference_cap(a)) && \ - (is_zero_mac_addr((a)->mlmepriv.nb_info.roam_target_addr) == _FALSE) && \ - (_rtw_memcmp((a)->mlmepriv.nb_info.roam_target_addr,\ - (c)->network.MacAddress, ETH_ALEN))) - -#define rtw_wnm_set_ext_cap_btm(_pEleStart, _val) \ - SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart))+2, 3, 1, _val) - -#define wnm_btm_bss_term_inc(p) (*((u8 *)((p)+3)) & BSS_TERMINATION_INCLUDED) - -#define wnm_btm_ess_disassoc_im(p) (*((u8 *)((p)+3)) & ESS_DISASSOC_IMMINENT) - -#define wnm_btm_req_mode(p) (*((u8 *)((p)+3))) - -#define wnm_btm_disassoc_timer(p) (*((u16 *)((p)+4))) - -#define wnm_btm_valid_interval(p) (*((u8 *)((p)+6))) - -#define wnm_btm_term_duration_offset(p) ((p)+7) - -/*IEEE Std 80211k Figure 7-95b Neighbor Report element format*/ -struct nb_rpt_hdr { - u8 id; /*0x34: Neighbor Report Element ID*/ - u8 len; - u8 bssid[ETH_ALEN]; - u32 bss_info; - u8 reg_class; - u8 ch_num; - u8 phy_type; -}; - -/*IEEE Std 80211v, Figure 7-95e2¡XBSS Termination Duration subelement field format */ -struct btm_term_duration { - u8 id; - u8 len; - u64 tsf; - u16 duration; -}; - -/*IEEE Std 80211v, Figure 7-101n8¡XBSS Transition Management Request frame body format */ -struct btm_req_hdr { - u8 req_mode; - u16 disassoc_timer; - u8 validity_interval; - struct btm_term_duration term_duration; -}; - -/*IEEE Std 80211v, Table 7-43b Optional Subelement IDs for Neighbor Report*/ -/* BSS Transition Candidate Preference */ -#define WNM_BTM_CAND_PREF_SUBEID 0x03 - -/* BSS Termination Duration */ -#define WNM_BTM_TERM_DUR_SUBEID 0x04 - -struct wnm_btm_cant { - struct nb_rpt_hdr nb_rpt; - u8 preference; /* BSS Transition Candidate Preference */ -}; - -enum rtw_btm_req_mod { - PREFERRED_CANDIDATE_LIST_INCLUDED = BIT0, - ABRIDGED = BIT1, - DISASSOC_IMMINENT = BIT2, - BSS_TERMINATION_INCLUDED = BIT3, - ESS_DISASSOC_IMMINENT = BIT4, -}; - -struct roam_nb_info { - struct nb_rpt_hdr nb_rpt[RTW_MAX_NB_RPT_NUM]; - struct rtw_ieee80211_channel nb_rpt_ch_list[RTW_MAX_NB_RPT_NUM]; - bool nb_rpt_valid; - u8 nb_rpt_ch_list_num; - u8 preference_en; - u8 roam_target_addr[ETH_ALEN]; - u32 last_nb_rpt_entries; - bool nb_rpt_is_same; - _timer roam_scan_timer; -}; -#endif /* defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) */ #endif struct mlme_priv { @@ -916,12 +725,14 @@ struct mlme_priv { u8 *auth_rsp; u32 auth_rsp_len; #endif +#endif /* CONFIG_AP_MODE and CONFIG_NATIVEAP_MLME */ + u8 *assoc_req; u32 assoc_req_len; - u8 *assoc_rsp; u32 assoc_rsp_len; +#if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) /* u8 *wps_probe_req_ie; */ /* u32 wps_probe_req_ie_len; */ @@ -985,6 +796,11 @@ struct mlme_priv { u32 wfd_assoc_resp_ie_len; #endif +#ifdef CONFIG_RTW_MBO + u8 *pcell_data_cap_ie; + u32 cell_data_cap_len; +#endif + #ifdef RTK_DMP_PLATFORM /* DMP kobject_hotplug function signal need in passive level */ _workitem Linkup_workitem; @@ -1004,6 +820,19 @@ struct mlme_priv { u8 vendor_ie[WLAN_MAX_VENDOR_IE_NUM][WLAN_MAX_VENDOR_IE_LEN]; u32 vendor_ielen[WLAN_MAX_VENDOR_IE_NUM]; #endif +#ifdef CONFIG_RTW_MULTI_AP + u8 unassoc_sta_mode_of_stype[UNASOC_STA_SRC_NUM]; + _queue unassoc_sta_queue; + _queue free_unassoc_sta_queue; + u8 *free_unassoc_sta_buf; + u32 interested_unassoc_sta_cnt; + u32 max_unassoc_sta_cnt; +#ifdef CONFIG_PLATFORM_CMAP_INTFS + struct unassoc_sta_info cmap_unassoc_sta[CMAP_UNASSOC_METRICS_STA_MAX]; + u8 cmap_unassoc_sta_cnt; + _timer cmap_unassoc_sta_timer; +#endif +#endif }; #define mlme_set_scan_to_timer(mlme, ms) \ @@ -1054,17 +883,6 @@ extern void rtw_wmm_event_callback(PADAPTER padapter, u8 *pbuf); #ifdef CONFIG_IEEE80211W void rtw_sta_timeout_event_callback(_adapter *adapter, u8 *pbuf); #endif /* CONFIG_IEEE80211W */ -#ifdef CONFIG_RTW_80211R -void rtw_ft_info_init(struct ft_roam_info *pft); -u8 rtw_ft_chk_roaming_candidate(_adapter *padapter, - struct wlan_network *competitor); -void rtw_ft_update_stainfo(_adapter *padapter, WLAN_BSSID_EX *pnetwork); -void rtw_ft_reassoc_event_callback(_adapter *padapter, u8 *pbuf); -#endif -#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) -void rtw_roam_nb_info_init(_adapter *padapter); -#endif - thread_return event_thread(thread_context context); extern void rtw_free_network_queue(_adapter *adapter, u8 isfreeall); @@ -1338,6 +1156,19 @@ struct sta_media_status_rpt_cmd_parm { bool connected; }; +#ifdef CONFIG_RTW_MULTI_AP +void rtw_unassoc_sta_set_mode(_adapter *adapter, u8 stype, u8 mode); +bool rtw_unassoc_sta_src_chk(_adapter *adapter, u8 stype); +void dump_unassoc_sta(void *sel, _adapter *adapter); +void rtw_del_unassoc_sta_queue(_adapter *adapter); +void rtw_del_unassoc_sta(_adapter *adapter, u8 *addr); +void rtw_rx_add_unassoc_sta(_adapter *adapter, u8 stype, u8 *addr, s8 recv_signal_power); +void rtw_add_interested_unassoc_sta(_adapter *adapter, u8 *addr); +void rtw_undo_interested_unassoc_sta(_adapter *adapter, u8 *addr); +void rtw_undo_all_interested_unassoc_sta(_adapter *adapter); +u8 rtw_search_unassoc_sta(_adapter *adapter, u8 *addr, struct unassoc_sta_info *ret_sta); +#endif + void rtw_sta_media_status_rpt(_adapter *adapter, struct sta_info *sta, bool connected); u8 rtw_sta_media_status_rpt_cmd(_adapter *adapter, struct sta_info *sta, bool connected); void rtw_sta_media_status_rpt_cmd_hdl(_adapter *adapter, struct sta_media_status_rpt_cmd_parm *parm); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mlme_ext.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mlme_ext.h index 26336d925051..05eaab784f5b 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mlme_ext.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mlme_ext.h @@ -92,6 +92,7 @@ extern unsigned char WMM_OUI[]; extern unsigned char WPS_OUI[]; extern unsigned char WFD_OUI[]; extern unsigned char P2P_OUI[]; +extern unsigned char MULTI_AP_OUI[]; extern unsigned char WMM_INFO_OUI[]; extern unsigned char WMM_PARA_OUI[]; @@ -191,10 +192,9 @@ struct ss_res { u8 state; u8 next_state; /* will set to state on next cmd hdl */ int bss_cnt; + u8 activate_ch_cnt; int channel_idx; -#if CONFIG_IEEE80211_BAND_5GHZ && CONFIG_DFS - u8 dfs_ch_ssid_scan; -#endif + u8 force_ssid_scan; int scan_mode; u16 scan_ch_ms; u32 scan_timeout_ms; @@ -275,6 +275,9 @@ enum TDLS_option { #if defined(CONFIG_ATMEL_RC_PATCH) #define RTW_SCAN_NUM_OF_CH 2 #define RTW_BACK_OP_CH_MS 200 +#elseif defined(CONFIG_CUSTOMER_EZVIZ_CHIME2) + #define RTW_SCAN_NUM_OF_CH 1 + #define RTW_BACK_OP_CH_MS 200 #else #define RTW_SCAN_NUM_OF_CH 3 #define RTW_BACK_OP_CH_MS 400 @@ -340,10 +343,28 @@ struct mlme_ext_info { #endif /* ROKU_PRIVATE */ }; +enum { + RTW_CHF_NO_IR = BIT0, + RTW_CHF_DFS = BIT1, + RTW_CHF_LONG_CAC = BIT2, + RTW_CHF_NON_OCP = BIT3, + RTW_CHF_NO_HT40U = BIT4, + RTW_CHF_NO_HT40L = BIT5, + RTW_CHF_NO_80MHZ = BIT6, + RTW_CHF_NO_160MHZ = BIT7, +}; + /* The channel information about this channel including joining, scanning, and power constraints. */ typedef struct _RT_CHANNEL_INFO { u8 ChannelNum; /* The channel number. */ - RT_SCAN_TYPE ScanType; /* Scan type such as passive or active scan. */ + + /* + * Bitmap and its usage: + * RTW_CHF_NO_IR, RTW_CHF_DFS: is used to check for status + * RTW_CHF_NO_HT40U, RTW_CHF_NO_HT40L, RTW_CHF_NO_80MHZ, RTW_CHF_NO_160MHZ: extra bandwidth limitation (ex: from regulatory) + * RTW_CHF_NON_OCP: is only used to record if event is reported, status check is still done using non_ocp_end_time + */ + u8 flags; /* u16 ScanPeriod; */ /* Listen time in millisecond in this channel. */ /* s32 MaxTxPwrDbm; */ /* Max allowed tx power. */ /* u32 ExInfo; */ /* Extended Information for this channel. */ @@ -354,7 +375,11 @@ typedef struct _RT_CHANNEL_INFO { #ifdef CONFIG_DFS_MASTER systime non_ocp_end_time; #endif +#endif u8 hidden_bss_cnt; /* per scan count */ + +#ifdef CONFIG_IOCTL_CFG80211 + void *os_chan; #endif } RT_CHANNEL_INFO, *PRT_CHANNEL_INFO; @@ -365,8 +390,13 @@ typedef struct _RT_CHANNEL_INFO { #if CONFIG_TXPWR_LIMIT void rtw_txpwr_init_regd(struct rf_ctl_t *rfctl); #endif -void rtw_rfctl_init(_adapter *adapter); +int rtw_rfctl_init(_adapter *adapter); void rtw_rfctl_deinit(_adapter *adapter); +void rtw_rfctl_chplan_init(_adapter *adapter); +void rtw_rfctl_update_op_mode(struct rf_ctl_t *rfctl, u8 ifbmp_mod, u8 if_op); + +u8 rtw_rfctl_get_dfs_domain(struct rf_ctl_t *rfctl); +u8 rtw_rfctl_dfs_domain_unknown(struct rf_ctl_t *rfctl); #ifdef CONFIG_DFS_MASTER struct rf_ctl_t; @@ -377,8 +407,9 @@ bool rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl); bool rtw_rfctl_is_tx_blocked_by_ch_waiting(struct rf_ctl_t *rfctl); bool rtw_chset_is_chbw_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset); bool rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch); -void rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset); -void rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms); +bool rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset); +bool rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms); +void rtw_chset_chk_non_ocp_finish(struct rf_ctl_t *rfctl); u32 rtw_get_ch_waiting_ms(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, u32 *r_non_ocp_ms, u32 *r_cac_ms); void rtw_reset_cac(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset); u32 rtw_force_stop_cac(struct rf_ctl_t *rfctl, u32 timeout_ms); @@ -389,27 +420,35 @@ u32 rtw_force_stop_cac(struct rf_ctl_t *rfctl, u32 timeout_ms); #define rtw_rfctl_is_tx_blocked_by_ch_waiting(rfctl) _FALSE #endif -enum { - RTW_CHF_2G = BIT0, - RTW_CHF_5G = BIT1, - RTW_CHF_DFS = BIT2, - RTW_CHF_LONG_CAC = BIT3, - RTW_CHF_NON_DFS = BIT4, - RTW_CHF_NON_LONG_CAC = BIT5, - RTW_CHF_NON_OCP = BIT6, -}; - bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw , u8 *dec_ch, u8 *dec_bw, u8 *dec_offset - , u8 d_flags, u8 cur_ch, bool by_int_info, u8 mesh_only); + , u8 e_flags, u8 d_flags, u8 cur_ch, bool by_int_info, u8 mesh_only); -void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set); +struct get_chplan_resp { + enum regd_src_t regd_src; + bool has_country; + struct country_chplan country_ent; + u8 channel_plan; +#if CONFIG_TXPWR_LIMIT + const char *regd_name; +#endif +#ifdef CONFIG_DFS_MASTER + u8 dfs_domain; +#endif + u8 chset_num; + RT_CHANNEL_INFO chset[0]; +}; + +#ifdef CONFIG_PROC_DEBUG +void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set, u8 chset_num); void dump_cur_chset(void *sel, struct rf_ctl_t *rfctl); +#endif int rtw_chset_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch); -u8 rtw_chset_is_chbw_valid(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset); +u8 rtw_chset_is_chbw_valid(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset + , bool allow_primary_passive, bool allow_passive); void rtw_chset_sync_chbw(RT_CHANNEL_INFO *ch_set, u8 *req_ch, u8 *req_bw, u8 *req_offset - , u8 *g_ch, u8 *g_bw, u8 *g_offset); + , u8 *g_ch, u8 *g_bw, u8 *g_offset, bool allow_primary_passive, bool allow_passive); bool rtw_mlme_band_check(_adapter *adapter, const u32 ch); @@ -553,6 +592,9 @@ struct mlme_ext_priv { bool txss_1ss; u8 txss_momi_type_bk; #endif +#ifdef CONFIG_DFS + _timer csa_timer; +#endif /* CONFIG_DFS */ }; struct support_rate_handler { @@ -661,6 +703,7 @@ void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch); void Set_MSR(_adapter *padapter, u8 type); + void rtw_set_external_auth_status(_adapter *padapter, const void *data, int len); u8 rtw_get_oper_ch(_adapter *adapter); @@ -669,14 +712,13 @@ u8 rtw_get_oper_bw(_adapter *adapter); void rtw_set_oper_bw(_adapter *adapter, u8 bw); u8 rtw_get_oper_choffset(_adapter *adapter); void rtw_set_oper_choffset(_adapter *adapter, u8 offset); -u8 rtw_get_center_ch(u8 channel, u8 chnl_bw, u8 chnl_offset); systime rtw_get_on_oper_ch_time(_adapter *adapter); systime rtw_get_on_cur_ch_time(_adapter *adapter); -u8 rtw_get_offset_by_chbw(u8 ch, u8 bw, u8 *r_offset); - void set_channel_bwmode(_adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode); +void csa_timer_hdl(void *FunctionContext); + unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval); void _clear_cam_entry(_adapter *padapter, u8 entry); @@ -745,7 +787,10 @@ void ERP_IE_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); void VCS_update(_adapter *padapter, struct sta_info *psta); void update_ldpc_stbc_cap(struct sta_info *psta); +#ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT bool rtw_validate_value(u16 EID, u8 *p, u16 len); +#endif /* CONFIG_CHECK_SPECIFIC_IE_CONTENT */ + bool is_hidden_ssid(char *ssid, int len); bool hidden_ssid_ap(WLAN_BSSID_EX *snetwork); void rtw_absorb_ssid_ifneed(_adapter *padapter, WLAN_BSSID_EX *bssid, u8 *pframe); @@ -787,7 +832,7 @@ unsigned int is_ap_in_tkip(_adapter *padapter); unsigned int is_ap_in_wep(_adapter *padapter); unsigned int should_forbid_n_rate(_adapter *padapter); -void parsing_eapol_packet(_adapter *padapter, u8 *key_payload, struct sta_info *psta, u8 trx_type); +enum eap_type parsing_eapol_packet(_adapter *padapter, u8 *key_payload, struct sta_info *psta, u8 trx_type); bool _rtw_camctl_chk_cap(_adapter *adapter, u8 cap); void _rtw_camctl_set_flags(_adapter *adapter, u32 flags); @@ -870,6 +915,9 @@ extern u8 set_tx_beacon_cmd(_adapter *padapter, u8 flags); unsigned int setup_beacon_frame(_adapter *padapter, unsigned char *beacon_frame); void update_mgnt_tx_rate(_adapter *padapter, u8 rate); void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib); +#ifdef CONFIG_RTW_MGMT_QUEUE +void update_mgntframe_subtype(_adapter *padapter, struct xmit_frame *pmgntframe); +#endif void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib); void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe); void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe); @@ -919,8 +967,9 @@ unsigned int send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid, u8 force); unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr); +#ifdef CONFIG_AP_MODE unsigned int send_beacon(_adapter *padapter); - +#endif void start_clnt_assoc(_adapter *padapter); void start_clnt_auth(_adapter *padapter); void start_clnt_join(_adapter *padapter); @@ -978,38 +1027,11 @@ unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame); unsigned int OnAction_tbtx_token(_adapter *padapter, union recv_frame *precv_frame); #endif -#ifdef CONFIG_RTW_80211R -void rtw_ft_update_bcn(_adapter *padapter, union recv_frame *precv_frame); -void rtw_ft_start_clnt_join(_adapter *padapter); -u8 rtw_ft_update_rsnie(_adapter *padapter, u8 bwrite, - struct pkt_attrib *pattrib, u8 **pframe); -void rtw_ft_build_auth_req_ies(_adapter *padapter, - struct pkt_attrib *pattrib, u8 **pframe); -void rtw_ft_build_assoc_req_ies(_adapter *padapter, - u8 is_reassoc, struct pkt_attrib *pattrib, u8 **pframe); -u8 rtw_ft_update_auth_rsp_ies(_adapter *padapter, u8 *pframe, u32 len); -void rtw_ft_start_roam(_adapter *padapter, u8 *pTargetAddr); -void rtw_ft_issue_action_req(_adapter *padapter, u8 *pTargetAddr); -void rtw_ft_report_evt(_adapter *padapter); -void rtw_ft_report_reassoc_evt(_adapter *padapter, u8 *pMacAddr); -void rtw_ft_link_timer_hdl(void *ctx); -void rtw_ft_roam_timer_hdl(void *ctx); -void rtw_ft_roam_status_reset(_adapter *padapter); -#endif #ifdef CONFIG_RTW_TOKEN_BASED_XMIT void rtw_issue_action_token_req(_adapter *padapter, struct sta_info *pstat); void rtw_issue_action_token_rel(_adapter *padapter); #endif -#ifdef CONFIG_RTW_WNM -void rtw_wnm_roam_scan_hdl(void *ctx); -void rtw_wnm_process_btm_req(_adapter *padapter, u8* pframe, u32 frame_len); -void rtw_wnm_reset_btm_candidate(struct roam_nb_info *pnb); -void rtw_wnm_reset_btm_state(_adapter *padapter); -void rtw_wnm_issue_action(_adapter *padapter, u8 action, u8 reason); -#endif -#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K) -u32 rtw_wnm_btm_candidates_survey(_adapter *padapter, u8* pframe, u32 elem_len, u8 is_preference); -#endif + void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res); void mlmeext_sta_del_event_callback(_adapter *padapter); void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta); @@ -1119,7 +1141,9 @@ u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf); u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf); u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf); u8 rtw_set_chbw_hdl(_adapter *padapter, u8 *pbuf); -u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf); +u8 rtw_iqk_hdl(_adapter *padapter, unsigned char *pbuf); +u8 rtw_set_chplan_hdl(_adapter *padapter, unsigned char *pbuf); +u8 rtw_get_chplan_hdl(_adapter *padapter, unsigned char *pbuf); u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf); u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf); /* Kurt: Handling DFS channel switch announcement ie. */ u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf); @@ -1127,7 +1151,14 @@ u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf); int rtw_sae_preprocess(_adapter *adapter, const u8 *buf, u32 len, u8 tx); -#define GEN_MLME_EXT_HANDLER(cmd, callback) {cmd, callback}, +u32 rtw_desc_rate_to_bitrate(u8 bw, u8 rate_idx, u8 sgi); + +#ifdef CONFIG_RTW_MULTI_AP +u8 rtw_get_ch_utilization(_adapter *adapter); +void rtw_ch_util_rpt(_adapter *adapter); +#endif + +#define GEN_MLME_EXT_HANDLER(cmd, callback_func) {.cmd_hdl = cmd, .callback = callback_func}, struct rtw_cmd { u8(*cmd_hdl)(_adapter *padapter, u8 *pbuf); @@ -1155,7 +1186,7 @@ struct rtw_cmd wlancmds[] = { GEN_MLME_EXT_HANDLER(tx_beacon_hdl, NULL) /*CMD_TX_BEACON*/ GEN_MLME_EXT_HANDLER(mlme_evt_hdl, NULL) /*CMD_SET_MLME_EVT*/ GEN_MLME_EXT_HANDLER(rtw_drvextra_cmd_hdl, NULL) /*CMD_SET_DRV_EXTRA*/ - GEN_MLME_EXT_HANDLER(set_chplan_hdl, NULL) /*CMD_SET_CHANPLAN*/ + GEN_MLME_EXT_HANDLER(rtw_set_chplan_hdl, NULL) /*CMD_SET_CHANPLAN*/ GEN_MLME_EXT_HANDLER(led_blink_hdl, NULL) /*CMD_LEDBLINK*/ GEN_MLME_EXT_HANDLER(set_csa_hdl, NULL) /*CMD_SET_CHANSWITCH*/ GEN_MLME_EXT_HANDLER(tdls_hdl, NULL) /*CMD_TDLS*/ @@ -1164,6 +1195,8 @@ struct rtw_cmd wlancmds[] = { GEN_MLME_EXT_HANDLER(add_ba_rsp_hdl, NULL) /*CMD_ADD_BARSP*/ GEN_MLME_EXT_HANDLER(rm_post_event_hdl, NULL) /*CMD_RM_POST_EVENT*/ GEN_MLME_EXT_HANDLER(rtw_mesh_set_plink_state_cmd_hdl, NULL) /*CMD_SET_MESH_PLINK_STATE*/ + GEN_MLME_EXT_HANDLER(rtw_iqk_hdl, NULL) /*CMD_DO_IQK*/ + GEN_MLME_EXT_HANDLER(rtw_get_chplan_hdl, NULL) /* CMD_GET_CHANPLAN */ }; #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mp.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mp.h index 81adf708695c..5fb634a79960 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mp.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_mp.h @@ -301,6 +301,10 @@ enum { #ifdef CONFIG_WOWLAN MP_WOW_ENABLE, MP_WOW_SET_PATTERN, +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + MP_WOW_SET_KEEP_ALIVE_PATTERN, +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + #endif #ifdef CONFIG_AP_WOWLAN MP_AP_WOW_ENABLE, diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_odm.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_odm.h index ecbb6518f5d4..3c94ed8b0441 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_odm.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_odm.h @@ -83,13 +83,15 @@ void rtw_odm_get_perpkt_rssi(void *sel, _adapter *adapter); void rtw_odm_acquirespinlock(_adapter *adapter, enum rt_spinlock_type type); void rtw_odm_releasespinlock(_adapter *adapter, enum rt_spinlock_type type); -u8 rtw_odm_get_dfs_domain(struct dvobj_priv *dvobj); -u8 rtw_odm_dfs_domain_unknown(struct dvobj_priv *dvobj); +struct dm_struct; +s16 rtw_odm_get_tx_power_mbm(struct dm_struct *dm, u8 rfpath, u8 rate, u8 bw, u8 cch); + #ifdef CONFIG_DFS_MASTER void rtw_odm_radar_detect_reset(_adapter *adapter); void rtw_odm_radar_detect_disable(_adapter *adapter); void rtw_odm_radar_detect_enable(_adapter *adapter); BOOLEAN rtw_odm_radar_detect(_adapter *adapter); +void rtw_odm_update_dfs_region(struct dvobj_priv *dvobj); u8 rtw_odm_radar_detect_polling_int_ms(struct dvobj_priv *dvobj); #endif /* CONFIG_DFS_MASTER */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_p2p.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_p2p.h index 697b2fcaae31..acab5e6190f2 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_p2p.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_p2p.h @@ -71,8 +71,6 @@ u8 p2p_ps_wk_cmd(_adapter *padapter, u8 p2p_ps_state, u8 enqueue); #endif /* CONFIG_P2P_PS */ #ifdef CONFIG_IOCTL_CFG80211 -u8 roch_stay_in_cur_chan(_adapter *padapter); -void rtw_init_cfg80211_wifidirect_info(_adapter *padapter); int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx); #endif /* CONFIG_IOCTL_CFG80211 */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_pwrctrl.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_pwrctrl.h index 39d405098d99..e7de3eed7171 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_pwrctrl.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_pwrctrl.h @@ -39,6 +39,7 @@ #ifdef CONFIG_BT_COEXIST #define BTCOEX_ALIVE BIT(4) #endif /* CONFIG_BT_COEXIST */ +#define LPS_ALIVE BIT(5) #ifdef CONFIG_WOWLAN #ifdef CONFIG_PLATFORM_ANDROID_INTEL_X86 @@ -57,6 +58,7 @@ #define MAX_WKFM_SIZE 16 /* (16 bytes for WKFM bit mask, 16*8 = 128 bits) */ #define MAX_WKFM_PATTERN_SIZE 128 +#define MAX_IN_PATTERN_SIZE 512 /* * MAX_WKFM_PATTERN_STR_LEN : the max. length of wow pattern string @@ -234,6 +236,38 @@ typedef enum _PS_DENY_REASON { PS_DENY_OTHERS = 31 } PS_DENY_REASON; +#ifdef CONFIG_WAR_OFFLOAD +/* only support mDNS V4/V6 rsp now */ +enum { + WAR_ARP_RSP_EN = 0x0000001, + WAR_ICMPV6_NS_RSP_EN = 0x00000002, + WAR_ICMPV4_ECHO_RSP_EN = 0x00000004, + WAR_ICMPV6_ECHO_RSP_EN = 0x00000008, + WAR_NETBIOS_RSP_EN = 0x00000010, + WAR_LLMNR_V4_RSP_EN = 0x00000020, + WAR_LLMNR_V6_RSP_EN = 0x00000040, + WAR_SNMP_V4_RSP_EN = 0x00000080, + WAR_SNMP_V6_RSP_EN = 0x00000100, + WAR_SNMP_V4_WAKEUP_EN = 0x00000200, + WAR_SNMP_V6_WAKEUP_EN = 0x00000400, + WAR_SSDP_V4_WAKEUP_EN = 0x00000800, + WAR_SSDP_V6_WAKEUP_EN = 0x00001000, + WAR_WSD_V4_WAKEUP_EN = 0x00002000, + WAR_WSD_V6_WAKEUP_EN = 0x00004000, + WAR_SLP_V4_WAKEUP_EN = 0x00008000, + WAR_SLP_V6_WAKEUP_EN = 0x00010000, + WAR_MDNS_V4_RSP_EN = 0x00020000, + WAR_MDNS_V6_RSP_EN = 0x00040000, + WAR_DESIGNATED_MAC_EN = 0x00080000, + WAR_LLTD_WAKEUP_EN = 0x00100000, + WAR_ARP_WAKEUP_EN = 0x00200000, + WAR_MAGIC_WAKEUP_EN = 0x00400000, + WAR_MDNS_V4_WAKEUP_EN = 0x000800000, + WAR_MDNS_V6_WAKEUP_EN = 0x001000000 +}; + +#endif /* CONFIG_WAR_OFFLOAD */ + #ifdef CONFIG_PNO_SUPPORT typedef struct pno_nlo_info { u32 fast_scan_period; /* Fast scan period */ @@ -309,6 +343,72 @@ struct aoac_report { u8 rxgtk_iv[4][8]; }; +#ifdef CONFIG_WAR_OFFLOAD + +struct war_ipv4_fmt { + u32 ip_addr[4]; + u32 ip_subnet[4]; + u32 ip_gateway[4]; +}; + +struct war_ipv6_fmt { + u8 ipv6_addr[8][16]; +}; + +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) +/* limitation of mDNS parameter : length and number */ +#define MAX_MDNS_SERVICE_NAME_LEN 15 +#define MAX_MDNS_TRANS_LEN 4 /* _tcp or _udp */ +#define MAX_MDNS_DOMAIN_LEN 5 /* local only for mdns */ +#define MAX_MDNS_MACHINE_NAME_LEN (63+1) /* +1 for the length byte used by the DNS format */ +#define MAX_MDNS_TARGET_LEN 63 +#define MAX_MDNS_DOMAIN_NAME_LEN 63 +#define MAX_MDNS_TXT_LEN 1536 +#define MAX_MDNS_TXT_SINGLE_LEN 255 + + +#define MAX_MDNS_SERVICE_NUM 10 +#define MAX_MDNS_TXT_NUM 8 +#define MAX_MDNS_MACHINE_NAME_NUM 3 + +/* for monitor rsvd page using */ +#define MAX_MDNS_PARA_SIZE 1700 // 14*128 = 1792 +#define MAX_MDNS_TXT_TOTAL_SIZE 10*MAX_MDNS_TXT_LEN +#define MAX_MDNS_RSP_PKT_SIZE 760 // 6*128 = 768 + +#define RTW_MDNS_SRV_INFO(sname, sname_len, tname, tname_len, dname, dname_len, port0, port1, ttlv, tar, tar_len, idx) \ + { .service=sname, .service_len=sname_len, .transport=tname, .transport_len=tname_len, \ + .domain=dname , .domain_len=dname_len , .port[0]=port0, .port[1]=port1, .ttl=ttlv, \ + .target=tar, .target_len=tar_len, .txt_rsp_idx=idx } + + +struct war_mdns_service_info { + u8 service[MAX_MDNS_SERVICE_NAME_LEN+1]; + u8 service_len; + u8 transport[MAX_MDNS_TRANS_LEN+1]; + u8 transport_len; + u8 domain[MAX_MDNS_DOMAIN_LEN+1]; + u8 domain_len; + u8 port[2]; + u32 ttl; + u8 target[MAX_MDNS_TARGET_LEN+1]; + u8 target_len; + s8 txt_rsp_idx; +}; + +struct war_mdns_machine_name { + u8 name[MAX_MDNS_MACHINE_NAME_LEN]; + u8 name_len; +}; + +struct war_mdns_txt_rsp { + u8 txt[MAX_MDNS_TXT_LEN]; + u16 txt_len; +}; +#endif +#endif /* CONFIG_WAR_OFFLOAD */ + + struct rsvd_page_cache_t; struct pwrctrl_priv { @@ -400,6 +500,8 @@ struct pwrctrl_priv { #ifdef CONFIG_GPIO_WAKEUP u8 is_high_active; + u8 wowlan_gpio_index; + u8 wowlan_gpio_output_state; #endif /* CONFIG_GPIO_WAKEUP */ u8 hst2dev_high_active; #ifdef CONFIG_WOWLAN @@ -427,6 +529,45 @@ struct pwrctrl_priv { #ifdef CONFIG_LPS_1T1R u8 wowlan_lps_1t1r; #endif + + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + /*data 0,rsv page location*/ + u8 wowlan_keep_alive_mode; + u8 keep_alive_pattern_loc; + /*data 1 ,cam id, rx udp packet*/ + u8 wowlan_keep_alive_ack_index; + /*data 2 ,cam id, pattern match packet*/ + u8 wowlan_wake_pattern_index; + /*data3,unit: TBTT*/ + u16 wowlan_keep_alive_period; + /*data4,unit: TBTT*/ + u8 wowlan_keep_alive_retry_interval; + /*data5*/ + u8 wowlan_keep_alive_retry_counter; + /*from echo*/ + u8 keep_alive_pattern[WLAN_MAX_KEEP_ALIVE_IE_LEN]; + u32 keep_alive_pattern_len; + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + +#ifdef CONFIG_WAR_OFFLOAD + u8 wowlan_war_offload_mode; + u32 wowlan_war_offload_ctrl; + struct war_ipv4_fmt wowlan_war_offload_ipv4; + struct war_ipv6_fmt wowlan_war_offload_ipv6; + u8 wowlan_war_offload_mac[6]; +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) + struct war_mdns_machine_name wowlan_war_offload_mdns_mnane[MAX_MDNS_MACHINE_NAME_NUM]; + struct war_mdns_service_info wowlan_war_offload_mdns_service[MAX_MDNS_SERVICE_NUM]; + struct war_mdns_txt_rsp wowlan_war_offload_mdns_txt_rsp[MAX_MDNS_TXT_NUM]; + u8 wowlan_war_offload_mdns_mnane_num; + u8 wowlan_war_offload_mdns_service_info_num; + u8 wowlan_war_offload_mdns_txt_rsp_num; + u8 wowlan_war_offload_mdns_domain_name[MAX_MDNS_DOMAIN_NAME_LEN+1]; + u8 wowlan_war_offload_mdns_domain_name_len; + u32 wowlan_war_offload_mdns_para_cur_size; + u32 wowlan_war_offload_mdns_rsp_cur_size; +#endif /* CONFIG_OFFLOAD_MDNS_V4 || CONFIG_OFFLOAD_MDNS_V6 */ +#endif /* CONFIG_WAR_OFFLOAD */ #endif /* CONFIG_WOWLAN */ _timer pwr_state_check_timer; int pwr_state_check_interval; @@ -551,7 +692,8 @@ int rtw_fw_ps_state(PADAPTER padapter); extern const char * const LPS_CTRL_PHYDM; void LPS_Enter(PADAPTER padapter, const char *msg); void LPS_Leave(PADAPTER padapter, const char *msg); -void rtw_leave_lps_and_chk(_adapter *padapter, u8 ps_mode); +void rtw_exec_lps(_adapter *padapter, u8 ps_mode); +void rtw_lps_rfon_ctrl(_adapter *padapter, u8 rfon_ctrl); #ifdef CONFIG_CHECK_LEAVE_LPS #ifdef CONFIG_LPS_CHK_BY_TP void traffic_check_for_leave_lps_by_tp(PADAPTER padapter, u8 tx, struct sta_info *sta); @@ -616,6 +758,15 @@ bool rtw_wowlan_parser_pattern_cmd(u8 *input, char *pattern, void rtw_wow_pattern_sw_reset(_adapter *adapter); u8 rtw_set_default_pattern(_adapter *adapter); void rtw_wow_pattern_sw_dump(_adapter *adapter); +#ifdef CONFIG_WAR_OFFLOAD +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) +void rtw_wow_war_mdns_dump_buf(struct seq_file *m, u8 *title, u8 *buf, u32 len); +void rtw_wow_war_mdns_dump_txt(struct seq_file *m, u8 *title, u8 *buf, u32 len); +bool rtw_wow_war_mdns_parser_pattern(u8 *input, char *target, u32 *target_len, u32 max_len); +void rtw_wow_war_mdns_parms_reset(_adapter *adapter, u8 is_set_default); +#endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */ +#endif /* CONFIG_WAR_OFFLOAD */ + #endif /* CONFIG_WOWLAN */ void rtw_ssmps_enter(_adapter *adapter, struct sta_info *sta); void rtw_ssmps_leave(_adapter *adapter, struct sta_info *sta); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_recv.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_recv.h index 035db045a135..aeb1ddfe1b11 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_recv.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_recv.h @@ -173,8 +173,6 @@ struct rx_pkt_attrib { u8 crc_err; u8 icv_err; - u16 eth_type; - u8 dst[ETH_ALEN]; u8 src[ETH_ALEN]; u8 ta[ETH_ALEN]; @@ -407,6 +405,15 @@ struct recv_priv { _queue recv_buf_pending_queue; #endif +#if defined(CONFIG_SDIO_HCI) +#ifdef CONFIG_SDIO_RECVBUF_PWAIT + struct rtw_pwait_ctx recvbuf_pwait; +#endif +#ifdef CONFIG_SDIO_RECVBUF_AGGREGATION + bool recvbuf_agg; +#endif +#endif /* CONFIG_SDIO_HCI */ + #ifdef CONFIG_PCI_HCI /* Rx */ struct rtw_rx_ring rx_ring[PCI_MAX_RX_QUEUE]; @@ -443,6 +450,15 @@ struct recv_priv { BOOLEAN store_law_data_flag; }; +#ifdef CONFIG_SDIO_RECVBUF_AGGREGATION +#define recv_buf_agg(recvpriv) recvpriv->recvbuf_agg +#ifndef CONFIG_SDIO_RECVBUF_AGGREGATION_EN +#define CONFIG_SDIO_RECVBUF_AGGREGATION_EN 1 +#endif +#else +#define recv_buf_agg(recvpriv) 0 +#endif + #define RX_BH_STG_UNKNOWN 0 #define RX_BH_STG_HDL_ENTER 1 #define RX_BH_STG_HDL_EXIT 2 @@ -491,10 +507,20 @@ struct sta_recv_priv { }; +#define RBUF_TYPE_PREALLOC 0 +#define RBUF_TYPE_TMP 1 +#define RBUF_TYPE_PWAIT_ADJ 2 + struct recv_buf { _list list; +#ifdef PLATFORM_WINDOWS _lock recvbuf_lock; +#endif + +#ifdef CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST + u8 type; +#endif u32 ref_cnt; @@ -525,6 +551,11 @@ struct recv_buf { #endif }; +#ifdef CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST +#define RBUF_IS_PREALLOC(rbuf) ((rbuf)->type == RBUF_TYPE_PREALLOC) +#else +#define RBUF_IS_PREALLOC(rbuf) 1 +#endif /* head -----> @@ -591,6 +622,12 @@ union recv_frame { }; +enum rtw_rx_llc_hdl { + RTW_RX_LLC_KEEP = 0, + RTW_RX_LLC_REMOVE = 1, + RTW_RX_LLC_VLAN = 2, +}; + bool rtw_rframe_del_wfd_ie(union recv_frame *rframe, u8 ies_offset); typedef enum _RX_PACKET_TYPE { @@ -617,6 +654,9 @@ sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue); sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue); struct recv_buf *rtw_dequeue_recvbuf(_queue *queue); +void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *psta); +void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *psta); + #if defined(CONFIG_80211N_HT) && defined(CONFIG_RECV_REORDERING_CTRL) void rtw_reordering_ctrl_timeout_handler(void *pcontext); #endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rf.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rf.h index bb349361e44c..f3fdf8defb0c 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rf.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rf.h @@ -35,6 +35,7 @@ #define MAX_CHANNEL_NUM_2G CENTER_CH_2G_NUM #define MAX_CHANNEL_NUM_5G CENTER_CH_5G_20M_NUM #define MAX_CHANNEL_NUM (MAX_CHANNEL_NUM_2G + MAX_CHANNEL_NUM_5G) +#define MAX_CHANNEL_NUM_OF_BAND rtw_max(MAX_CHANNEL_NUM_2G, MAX_CHANNEL_NUM_5G) extern u8 center_ch_2g[CENTER_CH_2G_NUM]; extern u8 center_ch_2g_40m[CENTER_CH_2G_40M_NUM]; @@ -56,6 +57,9 @@ u8 rtw_get_scch_by_cch_opch(u8 cch, u8 bw, u8 opch); u8 rtw_get_op_chs_by_cch_bw(u8 cch, u8 bw, u8 **op_chs, u8 *op_ch_num); +u8 rtw_get_offset_by_chbw(u8 ch, u8 bw, u8 *r_offset); +u8 rtw_get_center_ch(u8 ch, u8 bw, u8 offset); + u8 rtw_get_ch_group(u8 ch, u8 *group, u8 *cck_group); typedef enum _CAPABILITY { @@ -117,6 +121,60 @@ extern const char *const _ch_width_str[]; extern const u8 _ch_width_to_bw_cap[]; #define ch_width_to_bw_cap(bw) (((bw) < CHANNEL_WIDTH_MAX) ? _ch_width_to_bw_cap[(bw)] : 0) +enum opc_bw { + OPC_BW20 = 0, + OPC_BW40PLUS = 1, + OPC_BW40MINUS = 2, + OPC_BW80 = 3, + OPC_BW160 = 4, + OPC_BW80P80 = 5, + OPC_BW_NUM, +}; + +extern const char *const _opc_bw_str[OPC_BW_NUM]; +#define opc_bw_str(bw) (((bw) < OPC_BW_NUM) ? _opc_bw_str[(bw)] : "N/A") + +extern const u8 _opc_bw_to_ch_width[OPC_BW_NUM]; +#define opc_bw_to_ch_width(bw) (((bw) < OPC_BW_NUM) ? _opc_bw_to_ch_width[(bw)] : CHANNEL_WIDTH_MAX) + +/* global op class APIs */ +bool is_valid_global_op_class_id(u8 gid); +s16 get_sub_op_class(u8 gid, u8 ch); +void dump_global_op_class(void *sel); +u8 rtw_get_op_class_by_chbw(u8 ch, u8 bw, u8 offset); +u8 rtw_get_bw_offset_by_op_class_ch(u8 gid, u8 ch, u8 *bw, u8 *offset); + +struct op_ch_t { + u8 ch; + u8 static_non_op:1; /* not in channel list */ + u8 no_ir:1; + s16 max_txpwr; /* mBm */ +}; + +struct op_class_pref_t { + u8 class_id; + BAND_TYPE band; + enum opc_bw bw; + u8 ch_num; /* number of chs */ + u8 op_ch_num; /* channel number which is not static non operable */ + u8 ir_ch_num; /* channel number which can init radiation */ + struct op_ch_t chs[MAX_CHANNEL_NUM_OF_BAND]; /* zero(ch) terminated array */ +}; + +int op_class_pref_init(_adapter *adapter); +void op_class_pref_deinit(_adapter *adapter); + +#define REG_BEACON_HINT 0 +#define REG_TXPWR_CHANGE 1 +#define REG_CHANGE 2 + +void op_class_pref_apply_regulatory(_adapter *adapter, u8 reason); + +struct rf_ctl_t; +void dump_cap_spt_op_class_ch(void *sel, struct rf_ctl_t *rfctl, bool detail); +void dump_reg_spt_op_class_ch(void *sel, struct rf_ctl_t *rfctl, bool detail); +void dump_cur_spt_op_class_ch(void *sel, struct rf_ctl_t *rfctl, bool detail); + /* * Represent Extention Channel Offset in HT Capabilities * This is available only in 40Mhz mode. @@ -182,10 +240,13 @@ typedef enum _REGULATION_TXPWR_LMT { TXPWR_LMT_ETSI = 3, TXPWR_LMT_IC = 4, TXPWR_LMT_KCC = 5, - TXPWR_LMT_ACMA = 6, - TXPWR_LMT_CHILE = 7, - TXPWR_LMT_MEXICO = 8, - TXPWR_LMT_WW = 9, /* smallest of all available limit, keep last */ + TXPWR_LMT_NCC = 6, + TXPWR_LMT_ACMA = 7, + TXPWR_LMT_CHILE = 8, + TXPWR_LMT_UKRAINE = 9, + TXPWR_LMT_MEXICO = 10, + TXPWR_LMT_CN = 11, + TXPWR_LMT_WW, /* smallest of all available limit, keep last */ } REGULATION_TXPWR_LMT; extern const char *const _regd_str[]; @@ -260,9 +321,6 @@ void rtw_rf_apply_tx_gain_offset(_adapter *adapter, u8 ch); || (rtw_is_5g_band3(a) && rtw_is_5g_band3(b)) \ || (rtw_is_5g_band4(a) && rtw_is_5g_band4(b))) -u8 rtw_is_dfs_range(u32 hi, u32 lo); -u8 rtw_is_dfs_ch(u8 ch); -u8 rtw_is_dfs_chbw(u8 ch, u8 bw, u8 offset); bool rtw_is_long_cac_range(u32 hi, u32 lo, u8 dfs_region); bool rtw_is_long_cac_ch(u8 ch, u8 bw, u8 offset, u8 dfs_region); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rm.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rm.h index 840015d6b44a..3ffc4c6ff02b 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rm.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rm.h @@ -68,10 +68,18 @@ struct rm_priv { u8 rm_en_cap_def[5]; u8 rm_en_cap_assoc[5]; + u8 meas_token; /* rm debug */ void *prm_sel; }; +#define MAX_CH_NUM_IN_OP_CLASS 11 +typedef struct _RT_OPERATING_CLASS { + int global_op_class; + int Len; + u8 Channel[MAX_CH_NUM_IN_OP_CLASS]; +} RT_OPERATING_CLASS, *PRT_OPERATING_CLASS; + int rtw_init_rm(_adapter *padapter); int rtw_free_rm_priv(_adapter *padapter); @@ -85,5 +93,14 @@ void rm_handler(_adapter *padapter, struct rm_event *pev); u8 rm_add_nb_req(_adapter *padapter, struct sta_info *psta); +/* from ioctl */ +int rm_send_bcn_reqs(_adapter *padapter, u8 *sta_addr, u8 op_class, u8 ch, + u16 measure_duration, u8 measure_mode, u8 *bssid, u8 *ssid, + u8 reporting_detail, + u8 n_ap_ch_rpt, struct _RT_OPERATING_CLASS *rpt, + u8 n_elem_id, u8 *elem_id_list); +void indicate_beacon_report(u8 *sta_addr, + u8 n_measure_rpt, u32 elem_len, u8 *elem); + #endif /*CONFIG_RTW_80211K */ #endif /* __RTW_RM_H_ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rm_fsm.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rm_fsm.h index 0a365d54b99c..71fbe7a0d4c3 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rm_fsm.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rm_fsm.h @@ -56,13 +56,6 @@ #define RM_GET_AID(rmid) ((rmid&0xffff0000)>>16) #define RM_IS_ID_FOR_ALL(rmid) (rmid&RM_ALL_MEAS) -#define MAX_OP_CHANNEL_SET_NUM 11 -typedef struct _RT_OPERATING_CLASS { - int global_op_class; - int Len; - u16 Channel[MAX_OP_CHANNEL_SET_NUM]; -} RT_OPERATING_CLASS, *PRT_OPERATING_CLASS; - /* IEEE 802.11-2012 Table 8-59 Measurement Type definitions * for measurement request * modify rm_meas_type_req_name() when adding new type @@ -113,7 +106,7 @@ enum bcn_req_opt_sub_id{ bcn_req_rep_info = 1, /* len 2 */ bcn_req_rep_detail = 2, /* len 1 */ bcn_req_req = 10, /* len 0-237 */ - bcn_req_ac_ch_rep = 51 /* len 1-237 */ + bcn_req_ap_ch_rep = 51 /* len 1-237 */ }; /* IEEE 802.11-2012 Table 8-66 Reporting condition of Beacon Report */ @@ -132,16 +125,23 @@ struct opt_rep_info { }; #define BCN_REQ_OPT_MAX_NUM 16 +#define BCN_REQ_REQ_OPT_MAX_NUM 16 +#define BCN_REQ_OPT_AP_CH_RPT_MAX_NUM 12 struct bcn_req_opt { /* all req cmd id */ u8 opt_id[BCN_REQ_OPT_MAX_NUM]; u8 opt_id_num; + u8 req_id_num; + u8 req_id[BCN_REQ_REQ_OPT_MAX_NUM]; u8 rep_detail; NDIS_802_11_SSID ssid; /* bcn report condition */ struct opt_rep_info rep_cond; + u8 ap_ch_rpt_num; + struct _RT_OPERATING_CLASS *ap_ch_rpt[BCN_REQ_OPT_AP_CH_RPT_MAX_NUM]; + /* 0:default(Report to be issued after each measurement) */ u8 *req_start; /*id : 10 request;start */ u8 req_len; /*id : 10 request;length */ @@ -231,7 +231,7 @@ struct rm_meas_req { struct meas_req_opt nhm; }opt; - struct rtw_ieee80211_channel ch_set[MAX_OP_CHANNEL_SET_NUM]; + struct rtw_ieee80211_channel ch_set[RTW_CHANNEL_SCAN_AMOUNT]; u8 ch_set_ch_amount; s8 rx_pwr; /* in dBm */ u8 rx_bw; @@ -285,8 +285,10 @@ struct rm_obj { u64 meas_end_time; int wait_busy; u8 poll_mode; + u8 free_run_counter_valid; /* valid:_SUCCESS/invalid:_FAIL */ struct data_buf buf[MAX_BUF_NUM]; + bool from_ioctl; _list list; }; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rm_util.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rm_util.h index e652793bad3c..0650c4792f2a 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rm_util.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_rm_util.h @@ -29,11 +29,16 @@ u8 rm_get_oper_class_via_ch(u8 ch); u8 rm_get_ch_set( struct rtw_ieee80211_channel *pch_set, u8 op_class, u8 ch_num); +u8 rm_get_ch_set_from_bcn_req_opt( + struct rtw_ieee80211_channel *pch_set, struct bcn_req_opt *opt); u8 rm_get_bcn_rsni(struct rm_obj *prm, struct wlan_network *pnetwork); u8 rm_get_bcn_rcpi(struct rm_obj *prm, struct wlan_network *pnetwork); u8 rm_get_frame_rsni(struct rm_obj *prm, union recv_frame *pframe); u8 translate_percentage_to_rcpi(u32 SignalStrengthIndex); u8 translate_dbm_to_rcpi(s8 SignalPower); +u8 rm_gen_dialog_token(_adapter *padapter); +u8 rm_gen_meas_token(_adapter *padapter); +u32 rm_gen_rmid(_adapter *padapter, struct rm_obj *prm, u8 role); int is_wildcard_bssid(u8 *bssid); int rm_get_path_a_max_tx_power(_adapter *adapter, s8 *path_a); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_roch.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_roch.h new file mode 100644 index 000000000000..bc0551de1a7a --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_roch.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2020 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#ifndef __RTW_ROCH_H__ +#define __RTW_ROCH_H__ + +#include + +struct rtw_roch_parm; + +#if (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) +struct roch_info { +#ifdef CONFIG_CONCURRENT_MODE + _timer ap_roch_ch_switch_timer; /* Used to switch the channel between legacy AP and listen state. */ +#ifdef CONFIG_IOCTL_CFG80211 + u32 min_home_dur; /* min duration for traffic, home_time */ + u32 max_away_dur; /* max acceptable away duration, home_away_time */ +#endif +#endif + +#ifdef CONFIG_IOCTL_CFG80211 + _timer remain_on_ch_timer; + u8 restore_channel; + struct ieee80211_channel remain_on_ch_channel; + enum nl80211_channel_type remain_on_ch_type; + ATOMIC_T ro_ch_cookie_gen; + u64 remain_on_ch_cookie; + bool is_ro_ch; + struct wireless_dev *ro_ch_wdev; + systime last_ro_ch_time; /* this will be updated at the beginning and end of ro_ch */ +#endif +}; +#endif + +#ifdef CONFIG_IOCTL_CFG80211 +u8 rtw_roch_stay_in_cur_chan(_adapter *padapter); +#endif + +#if (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) +s32 rtw_roch_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf); +u8 rtw_roch_wk_cmd(_adapter *padapter, int intCmdType, struct rtw_roch_parm *roch_parm, u8 flags); + +#ifdef CONFIG_CONCURRENT_MODE +void rtw_concurrent_handler(_adapter *padapter); +#endif + +void rtw_init_roch_info(_adapter *padapter); +#endif /* (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) */ + +#endif diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_security.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_security.h index ca264a99f1cb..8d938fd20209 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_security.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_security.h @@ -171,8 +171,8 @@ struct security_priv { unsigned int wpa_pairwise_cipher; unsigned int wpa2_pairwise_cipher; unsigned int akmp; /* An authentication and key management protocol */ - u8 mfp_opt; #endif + u8 mfp_opt; u8 dot118021x_bmc_cam_id; /*IEEE802.11-2012 Std. Table 8-101 AKM Suite Selectors*/ u32 rsn_akm_suite_type; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_version.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_version.h index 880f0f521e34..b58594cce887 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_version.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_version.h @@ -1,3 +1,3 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#define DRIVERVERSION "v5.9.2_36984.20200615_COEX20200414-4e4e" -#define BTCOEXVERSION "COEX20200414-4e4e" +#define DRIVERVERSION "v5.12.0-8-g39bbb8dd2.20201015_COEX20200730-5151" +#define BTCOEXVERSION "COEX20200730-5151" diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_vht.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_vht.h index dd52816e0916..725db4f98945 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_vht.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_vht.h @@ -47,7 +47,7 @@ #define SET_VHT_CAPABILITY_ELE_TXOP_PS(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+2, 5, 1, _val) #define SET_VHT_CAPABILITY_ELE_HTC_VHT(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+2, 6, 1, _val) #define SET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(_pEleStart, _val) SET_BITS_TO_LE_2BYTE((_pEleStart)+2, 7, 3, _val) /* B23~B25 */ -#define SET_VHT_CAPABILITY_ELE_LINK_ADAPTION(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+2, 2, 2, _val) +#define SET_VHT_CAPABILITY_ELE_LINK_ADAPTION(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+3, 2, 2, _val) #define SET_VHT_CAPABILITY_ELE_MCS_RX_MAP(_pEleStart, _val) SET_BITS_TO_LE_2BYTE((_pEleStart)+4, 0, 16, _val) /* B0~B15 indicate Rx MCS MAP, we write 0 to indicate MCS0~7. by page */ #define SET_VHT_CAPABILITY_ELE_MCS_RX_HIGHEST_RATE(_pEleStart, _val) SET_BITS_TO_LE_2BYTE((_pEleStart)+6, 0, 13, _val) #define SET_VHT_CAPABILITY_ELE_MCS_TX_MAP(_pEleStart, _val) SET_BITS_TO_LE_2BYTE((_pEleStart)+8, 0, 16, _val) /* B0~B15 indicate Tx MCS MAP, we write 0 to indicate MCS0~7. by page */ @@ -104,10 +104,12 @@ extern const u16 _vht_max_mpdu_len[]; #define VHT_SUP_CH_WIDTH_SET_MAX 3 extern const u8 _vht_sup_ch_width_set_to_bw_cap[]; #define vht_sup_ch_width_set_to_bw_cap(set) (((set) >= VHT_SUP_CH_WIDTH_SET_MAX) ? _vht_sup_ch_width_set_to_bw_cap[VHT_SUP_CH_WIDTH_SET_MAX] : _vht_sup_ch_width_set_to_bw_cap[(set)]) +#define VHT_MAX_AMPDU_LEN(f) ((1 << (13 + f)) - 1) + +#ifdef CONFIG_RTW_DEBUG extern const char *const _vht_sup_ch_width_set_str[]; #define vht_sup_ch_width_set_str(set) (((set) >= VHT_SUP_CH_WIDTH_SET_MAX) ? _vht_sup_ch_width_set_str[VHT_SUP_CH_WIDTH_SET_MAX] : _vht_sup_ch_width_set_str[(set)]) -#define VHT_MAX_AMPDU_LEN(f) ((1 << (13 + f)) - 1) void dump_vht_cap_ie(void *sel, const u8 *ie, u32 ie_len); #define VHT_OP_CH_WIDTH_MAX 4 @@ -115,6 +117,7 @@ extern const char *const _vht_op_ch_width_str[]; #define vht_op_ch_width_str(ch_width) (((ch_width) >= VHT_OP_CH_WIDTH_MAX) ? _vht_op_ch_width_str[VHT_OP_CH_WIDTH_MAX] : _vht_op_ch_width_str[(ch_width)]) void dump_vht_op_ie(void *sel, const u8 *ie, u32 ie_len); +#endif struct vht_bf_cap { u8 is_mu_bfer; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_wnm.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_wnm.h new file mode 100644 index 000000000000..eddaf4ef8c9b --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_wnm.h @@ -0,0 +1,210 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2017 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ + +#ifndef __RTW_WNM_H_ +#define __RTW_WNM_H_ + +#define RTW_RRM_NB_RPT_EN BIT(1) +#define RTW_MAX_NB_RPT_NUM 8 + +#define RTW_WNM_FEATURE_BTM_REQ_EN BIT(0) + +#define rtw_roam_busy_scan(a, nb) \ + (((a)->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE) && \ + (((a)->mlmepriv.ch_cnt) < ((nb)->nb_rpt_ch_list_num))) + +#define rtw_wnm_btm_preference_cap(a) \ + ((a)->mlmepriv.nb_info.preference_en == _TRUE) + +#define rtw_wnm_btm_roam_triggered(a) \ + (((a)->mlmepriv.nb_info.preference_en == _TRUE) \ + && (rtw_ft_chk_flags((a), RTW_FT_BTM_ROAM)) \ + ) + +#define rtw_wnm_btm_diff_bss(a) \ + ((rtw_wnm_btm_preference_cap(a)) && \ + (is_zero_mac_addr((a)->mlmepriv.nb_info.roam_target_addr) == _FALSE) && \ + (_rtw_memcmp((a)->mlmepriv.nb_info.roam_target_addr,\ + (a)->mlmepriv.cur_network.network.MacAddress, ETH_ALEN) == _FALSE)) + +#define rtw_wnm_btm_roam_candidate(a, c) \ + ((rtw_wnm_btm_preference_cap(a)) && \ + (is_zero_mac_addr((a)->mlmepriv.nb_info.roam_target_addr) == _FALSE) && \ + (_rtw_memcmp((a)->mlmepriv.nb_info.roam_target_addr,\ + (c)->network.MacAddress, ETH_ALEN))) + +#define rtw_wnm_set_ext_cap_btm(_pEleStart, _val) \ + SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart))+2, 3, 1, _val) + +#define wnm_btm_bss_term_inc(p) (*((u8 *)((p)+3)) & BSS_TERMINATION_INCLUDED) + +#define wnm_btm_ess_disassoc_im(p) (*((u8 *)((p)+3)) & ESS_DISASSOC_IMMINENT) + +#define wnm_btm_dialog_token(p) (*((u8 *)((p)+2))) + +#define wnm_btm_req_mode(p) (*((u8 *)((p)+3))) + +#define wnm_btm_disassoc_timer(p) (*((u16 *)((p)+4))) + +#define wnm_btm_valid_interval(p) (*((u8 *)((p)+6))) + +#define wnm_btm_term_duration_offset(p) ((p)+7) + +#define wnm_btm_rsp_status(p) (*((u8 *)((p)+3))) + +#define wnm_btm_rsp_term_delay(p) (*((u8 *)((p)+4))) + +#define RTW_WLAN_ACTION_WNM_NB_RPT_ELEM 0x34 + +enum rtw_ieee80211_wnm_actioncode { + RTW_WLAN_ACTION_WNM_BTM_QUERY = 6, + RTW_WLAN_ACTION_WNM_BTM_REQ = 7, + RTW_WLAN_ACTION_WNM_BTM_RSP = 8, + RTW_WLAN_ACTION_WNM_NOTIF_REQ = 26, + RTW_WLAN_ACTION_WNM_NOTIF_RSP = 27, +}; + +/*IEEE Std 80211k Figure 7-95b Neighbor Report element format*/ +struct nb_rpt_hdr { + u8 id; /*0x34: Neighbor Report Element ID*/ + u8 len; + u8 bssid[ETH_ALEN]; + u32 bss_info; + u8 reg_class; + u8 ch_num; + u8 phy_type; +}; + +/*IEEE Std 80211v, Figure 7-9 BSS Termination Duration subelement field format */ +struct btm_term_duration { + u8 id; + u8 len; + u64 tsf; /* value of the TSF counter when BSS termination will occur in the future */ + u16 duration; /* number of minutes for which the BSS is not present*/ +}; + +/*IEEE Std 80211v, Figure 7-10 BSS Transition Management Request frame body format */ +struct btm_req_hdr { + u8 dialog_token; + u8 req_mode; + /* number of TBTTs until the AP sends a Disassociation frame to this STA */ + u16 disassoc_timer; + /* number of TBTTs until the BSS transition candidate list is no longer valid */ + u8 validity_interval; + struct btm_term_duration term_duration; +}; + +struct btm_rsp_hdr { + u8 dialog_token; + u8 status; + /* the number of minutes that + the responding STA requests the BSS to delay termination */ + u8 termination_delay; + u8 bssid[ETH_ALEN]; + u8 *pcandidates; + u32 candidates_num; +}; + +struct btm_rpt_cache { + u8 dialog_token; + u8 req_mode; + u16 disassoc_timer; + u8 validity_interval; + struct btm_term_duration term_duration; + + /* from BTM req */ + u32 validity_time; + u32 disassoc_time; + + systime req_stime; +}; + +/*IEEE Std 80211v, Table 7-43b Optional Subelement IDs for Neighbor Report*/ +/* BSS Transition Candidate Preference */ +#define WNM_BTM_CAND_PREF_SUBEID 0x03 + +/* BSS Termination Duration */ +#define WNM_BTM_TERM_DUR_SUBEID 0x04 + +struct wnm_btm_cant { + struct nb_rpt_hdr nb_rpt; + u8 preference; /* BSS Transition Candidate Preference */ +}; + +enum rtw_btm_req_mod { + PREFERRED_CANDIDATE_LIST_INCLUDED = BIT0, + ABRIDGED = BIT1, + DISASSOC_IMMINENT = BIT2, + BSS_TERMINATION_INCLUDED = BIT3, + ESS_DISASSOC_IMMINENT = BIT4, +}; + +struct roam_nb_info { + struct nb_rpt_hdr nb_rpt[RTW_MAX_NB_RPT_NUM]; + struct rtw_ieee80211_channel nb_rpt_ch_list[RTW_MAX_NB_RPT_NUM]; + struct btm_rpt_cache btm_cache; + bool nb_rpt_valid; + u8 nb_rpt_ch_list_num; + u8 preference_en; + u8 roam_target_addr[ETH_ALEN]; + u32 last_nb_rpt_entries; + u8 nb_rpt_is_same; + s8 disassoc_waiting; + _timer roam_scan_timer; + _timer disassoc_chk_timer; + + u32 features; +}; + +u8 rtw_wnm_btm_reassoc_req(_adapter *padapter); + +void rtw_wnm_roam_scan_hdl(void *ctx); + +void rtw_wnm_disassoc_chk_hdl(void *ctx); + +u8 rtw_wnm_try_btm_roam_imnt(_adapter *padapter); + +void rtw_wnm_process_btm_req(_adapter *padapter, u8* pframe, u32 frame_len); + +void rtw_wnm_reset_btm_candidate(struct roam_nb_info *pnb); + +void rtw_wnm_reset_btm_state(_adapter *padapter); + +u32 rtw_wnm_btm_rsp_candidates_sz_get( + _adapter *padapter, u8* pframe, u32 frame_len); + +void rtw_wnm_process_btm_rsp(_adapter *padapter, + u8* pframe, u32 frame_len, struct btm_rsp_hdr *prsp); + +void rtw_wnm_issue_btm_req(_adapter *padapter, + u8 *pmac, struct btm_req_hdr *phdr, u8 *purl, u32 url_len, + u8 *pcandidates, u8 candidate_cnt); + +void rtw_wnm_reset_btm_cache(_adapter *padapter); + +void rtw_wnm_issue_action(_adapter *padapter, u8 action, u8 reason, u8 dialog); + +void rtw_wnm_update_reassoc_req_ie(_adapter *padapter); + +void rtw_roam_nb_info_init(_adapter *padapter); + +u8 rtw_roam_nb_scan_list_set(_adapter *padapter, + struct sitesurvey_parm *pparm); + +u32 rtw_wnm_btm_candidates_survey(_adapter *padapter, + u8* pframe, u32 elem_len, u8 is_preference); +#endif /* __RTW_WNM_H_ */ + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_xmit.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_xmit.h index 6aa451cbcbf4..3e94d2297d95 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_xmit.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_xmit.h @@ -99,6 +99,8 @@ #define MAX_CMDBUF_SZ (512 * 18) #elif defined(CONFIG_RTL8723D) && defined(CONFIG_LPS_POFF) #define MAX_CMDBUF_SZ (128*70) /*(8960)*/ +#elif defined(CONFIG_RTL8822C) && defined(CONFIG_WAR_OFFLOAD) + #define MAX_CMDBUF_SZ (128*128) /*(16k) */ #else #define MAX_CMDBUF_SZ (5120) /* (4096) */ #endif @@ -118,10 +120,16 @@ #define BK_QUEUE_INX 3 #define BCN_QUEUE_INX 4 #define MGT_QUEUE_INX 5 -#define HIGH_QUEUE_INX 6 -#define TXCMD_QUEUE_INX 7 +#define TXCMD_QUEUE_INX 6 +#define HIGH_QUEUE_INX 7 +/* keep high queue to be the last one, so we can extend HIQ to port 1, 2, ... */ +#ifndef CONFIG_PORT_BASED_HIQ #define HW_QUEUE_ENTRY 8 +#else +#define HI_QUEUE_INX(n) (HIGH_QUEUE_INX + (n)) +#define HW_QUEUE_ENTRY (8 + CONFIG_IFACE_NUMBER - 1) +#endif #ifdef CONFIG_PCI_HCI #ifdef CONFIG_TRX_BD_ARCH @@ -182,7 +190,11 @@ #define IS_AMSDU_AMPDU_VALID(pattrib)\ !((pattrib->ampdu_en == _TRUE) && (pattrib->amsdu_ampdu_en == _FALSE)) -#define HWXMIT_ENTRY 4 +#ifdef CONFIG_RTW_MGMT_QUEUE +#define HWXMIT_ENTRY 5 +#else +#define HWXMIT_ENTRY 4 +#endif /* For Buffer Descriptor ring architecture */ #if defined(BUF_DESC_ARCH) || defined(CONFIG_TRX_BD_ARCH) @@ -199,7 +211,8 @@ defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8192E) ||\ defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8703B) ||\ defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) || defined(CONFIG_RTL8723D) ||\ - defined(CONFIG_RTL8710B) || defined(CONFIG_RTL8192F) + defined(CONFIG_RTL8710B) || defined(CONFIG_RTL8192F) ||\ + defined(CONFIG_RTL8723F) #define TXDESC_SIZE 40 #elif defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8822C) #define TXDESC_SIZE 48 /* HALMAC_TX_DESC_SIZE_8822B */ @@ -256,7 +269,7 @@ enum TXDESC_SC { #endif #elif defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8723B) \ || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) || defined(CONFIG_RTL8723D) \ - || defined(CONFIG_RTL8192F) + || defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8723F) #define TXDESC_40_BYTES #endif @@ -321,7 +334,7 @@ union txdesc { #endif #ifdef CONFIG_PCI_HCI -#define PCI_MAX_TX_QUEUE_COUNT 8 /* == HW_QUEUE_ENTRY */ +#define PCI_MAX_TX_QUEUE_COUNT HW_QUEUE_ENTRY struct rtw_tx_ring { unsigned char qid; @@ -365,54 +378,6 @@ struct hw_xmit { int accnt; }; -#if 0 -struct pkt_attrib { - u8 type; - u8 subtype; - u8 bswenc; - u8 dhcp_pkt; - u16 ether_type; - int pktlen; /* the original 802.3 pkt raw_data len (not include ether_hdr data) */ - int pkt_hdrlen; /* the original 802.3 pkt header len */ - int hdrlen; /* the WLAN Header Len */ - int nr_frags; - int last_txcmdsz; - int encrypt; /* when 0 indicate no encrypt. when non-zero, indicate the encrypt algorith */ - u8 iv[8]; - int iv_len; - u8 icv[8]; - int icv_len; - int priority; - int ack_policy; - int mac_id; - int vcs_mode; /* virtual carrier sense method */ - - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; - u8 ta[ETH_ALEN]; - u8 ra[ETH_ALEN]; - - u8 key_idx; - - u8 qos_en; - u8 ht_en; - u8 raid;/* rate adpative id */ - u8 bwmode; - u8 ch_offset;/* PRIME_CHNL_OFFSET */ - u8 sgi;/* short GI */ - u8 ampdu_en;/* tx ampdu enable */ - u8 mdata;/* more data bit */ - u8 eosp; - - u8 triggered;/* for ap mode handling Power Saving sta */ - - u32 qsel; - u16 seqnum; - - struct sta_info *psta; -}; -#else -/* reduce size */ struct pkt_attrib { u8 type; u8 subtype; @@ -440,6 +405,9 @@ struct pkt_attrib { u8 src[ETH_ALEN]; u8 ta[ETH_ALEN]; u8 ra[ETH_ALEN]; +#ifdef CONFIG_RTW_WDS + u8 wds; +#endif #ifdef CONFIG_RTW_MESH u8 mda[ETH_ALEN]; /* mesh da */ u8 msa[ETH_ALEN]; /* mesh sa */ @@ -511,7 +479,15 @@ struct pkt_attrib { u8 bf_pkt_type; #endif +#ifdef CONFIG_RTW_MGMT_QUEUE + u8 ps_dontq; /* 1: this frame can't be queued at PS state */ +#endif }; + +#ifdef CONFIG_RTW_WDS +#define XATTRIB_GET_WDS(xattrib) ((xattrib)->wds) +#else +#define XATTRIB_GET_WDS(xattrib) 0 #endif #ifdef CONFIG_RTW_MESH @@ -650,6 +626,7 @@ struct xmit_frame { struct pkt_attrib attrib; + u16 os_qid; _pkt *pkt; int frame_tag; @@ -699,6 +676,10 @@ struct sta_xmit_priv { struct tx_servq bk_q; /* priority == 1,2 */ struct tx_servq vi_q; /* priority == 4,5 */ struct tx_servq vo_q; /* priority == 6,7 */ +#ifdef CONFIG_RTW_MGMT_QUEUE + struct tx_servq mgmt_q; +#endif + _list legacy_dz; _list apsd; @@ -747,7 +728,7 @@ struct xmit_priv { _queue bk_pending; _queue vi_pending; _queue vo_pending; - _queue bm_pending; + _queue mgmt_pending; /* _queue legacy_dz_queue; */ /* _queue apsd_queue; */ @@ -854,6 +835,9 @@ struct xmit_priv { _mutex ack_tx_mutex; struct submit_ctx ack_tx_ops; u8 seq_no; +#ifdef CONFIG_REMOVE_DUP_TX_STATE + u8 retry_count; +#endif #endif #ifdef CONFIG_TX_AMSDU @@ -944,13 +928,20 @@ extern void rtw_update_protection(_adapter *padapter, u8 *ie, uint ie_len); extern s32 rtw_make_wlanhdr(_adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib); extern s32 rtw_put_snap(u8 *data, u16 h_proto); -extern struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv); +extern struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv, u16 os_qid); struct xmit_frame *rtw_alloc_xmitframe_ext(struct xmit_priv *pxmitpriv); struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv); extern s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe); extern void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue); struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, u8 *ac); extern s32 rtw_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); + +#ifdef CONFIG_RTW_MGMT_QUEUE +void rtw_free_mgmt_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *mgmt_queue); +u8 rtw_mgmt_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +struct xmit_frame *rtw_dequeue_mgmt_xframe(struct xmit_priv *pxmitpriv); +#endif /* CONFIG_RTW_MGMT_QUEUE */ + extern struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry); extern s32 rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe); @@ -987,9 +978,12 @@ void rtw_xmit_dequeue_callback(_workitem *work); void rtw_xmit_queue_set(struct sta_info *sta); void rtw_xmit_queue_clear(struct sta_info *sta); s32 rtw_xmit_posthandle(_adapter *padapter, struct xmit_frame *pxmitframe, _pkt *pkt); -s32 rtw_xmit(_adapter *padapter, _pkt **pkt); +s32 rtw_xmit(_adapter *padapter, _pkt **pkt, u16 os_qid); bool xmitframe_hiq_filter(struct xmit_frame *xmitframe); #if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) +#ifdef CONFIG_RTW_MGMT_QUEUE +u8 mgmt_xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe); void stop_sta_xmit(_adapter *padapter, struct sta_info *psta); void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta); @@ -1001,8 +995,10 @@ u8 rtw_get_tx_bw_mode(_adapter *adapter, struct sta_info *sta); void rtw_update_tx_rate_bmp(struct dvobj_priv *dvobj); u8 rtw_get_tx_bw_bmp_of_ht_rate(struct dvobj_priv *dvobj, u8 rate, u8 max_bw); u8 rtw_get_tx_bw_bmp_of_vht_rate(struct dvobj_priv *dvobj, u8 rate, u8 max_bw); -s16 rtw_adapter_get_oper_txpwr_max_mbm(_adapter *adapter); -s16 rtw_get_oper_txpwr_max_mbm(struct dvobj_priv *dvobj); +s16 rtw_adapter_get_oper_txpwr_max_mbm(_adapter *adapter, bool eirp); +s16 rtw_rfctl_get_oper_txpwr_max_mbm(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, u8 ifbmp_mod, u8 if_op, bool eirp); +s16 rtw_get_oper_txpwr_max_mbm(struct dvobj_priv *dvobj, bool erip); +s16 rtw_rfctl_get_reg_max_txpwr_mbm(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, bool eirp); u8 query_ra_short_GI(struct sta_info *psta, u8 bw); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/sdio_ops.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/sdio_ops.h index 57e6ec0680b8..7d1c88016dc7 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/sdio_ops.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/sdio_ops.h @@ -74,7 +74,8 @@ void ClearInterrupt8821AS(PADAPTER padapter); #endif /* CONFIG_RTL8821A */ #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) -#if defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8822C) +#if defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8822C) \ + || defined(CONFIG_RTL8723F) u8 rtw_hal_enable_cpwm2(_adapter *adapter); #endif extern u8 RecvOnePkt(PADAPTER padapter); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/sta_info.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/sta_info.h index ecad75c37172..2cb41a1bbf51 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/sta_info.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/sta_info.h @@ -22,7 +22,11 @@ #define NUM_STA MACID_NUM_SW_LIMIT #ifndef CONFIG_RTW_MACADDR_ACL + #ifdef CONFIG_AP_MODE #define CONFIG_RTW_MACADDR_ACL 1 + #else + #define CONFIG_RTW_MACADDR_ACL 0 + #endif #endif #ifndef CONFIG_RTW_PRE_LINK_STA @@ -279,6 +283,10 @@ struct sta_info { #endif _queue sleep_q; unsigned int sleepq_len; +#ifdef CONFIG_RTW_MGMT_QUEUE + _queue mgmt_sleep_q; + unsigned int mgmt_sleepq_len; +#endif uint state; uint qos_option; @@ -289,6 +297,7 @@ struct sta_info { u8 rm_diag_token; #endif /* CONFIG_RTW_80211K */ + systime resp_nonenc_eapol_key_starttime; uint ieee8021x_blocked; /* 0: allowed, 1:blocked */ uint dot118021XPrivacy; /* aes, tkip... */ union Keytype dot11tkiptxmickey; @@ -384,6 +393,10 @@ struct sta_info { unsigned int expire_to; + int flags; + + u8 bpairwise_key_installed; + #ifdef CONFIG_AP_MODE _list asoc_list; @@ -394,7 +407,6 @@ struct sta_info { unsigned char chg_txt[128]; u16 capability; - int flags; int dot8021xalg;/* 0:disable, 1:psk, 2:802.1x */ int wpa_psk;/* 0:disable, bit(0): WPA, bit(1):WPA2 */ @@ -405,7 +417,6 @@ struct sta_info { u32 akm_suite_type; - u8 bpairwise_key_installed; #ifdef CONFIG_RTW_80211R u8 ft_pairwise_key_installed; #endif @@ -458,9 +469,9 @@ struct sta_info { u8 op_wfd_mode; #endif -#ifdef CONFIG_TX_MCAST2UNI +#if !defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && defined(CONFIG_80211N_HT) u8 under_exist_checking; -#endif /* CONFIG_TX_MCAST2UNI */ +#endif u8 keep_alive_trycnt; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/wifi.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/wifi.h index ae2af0f39df9..01d04acd2c74 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/wifi.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/wifi.h @@ -65,6 +65,10 @@ #endif #endif +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +#define WLAN_MAX_KEEP_ALIVE_IE_LEN 256 +#endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + #define P80211CAPTURE_VERSION 0x80211001 /* This value is tested by WiFi 11n Test Plan 5.2.3. @@ -301,7 +305,7 @@ enum WIFI_REG_DOMAIN { *(unsigned short *)(pbuf) &= (~cpu_to_le16(_FROM_DS_)); \ } while (0) -#define get_tofr_ds(pframe) ((GetToDs(pframe) << 1) | GetFrDs(pframe)) +#define get_tofr_ds(pframe) ((GetFrDs(pframe) << 1) | GetToDs(pframe)) #define SetMFrag(pbuf) \ @@ -477,18 +481,18 @@ __inline static unsigned char *get_ta(unsigned char *pframe) __inline static unsigned char *get_da(unsigned char *pframe) { unsigned char *da; - unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + unsigned int to_fr_ds = (GetFrDs(pframe) << 1) | GetToDs(pframe); switch (to_fr_ds) { case 0x00: /* ToDs=0, FromDs=0 */ da = GetAddr1Ptr(pframe); break; - case 0x01: /* ToDs=0, FromDs=1 */ - da = GetAddr1Ptr(pframe); - break; - case 0x02: /* ToDs=1, FromDs=0 */ + case 0x01: /* ToDs=1, FromDs=0 */ da = GetAddr3Ptr(pframe); break; + case 0x02: /* ToDs=0, FromDs=1 */ + da = GetAddr1Ptr(pframe); + break; default: /* ToDs=1, FromDs=1 */ da = GetAddr3Ptr(pframe); break; @@ -501,18 +505,18 @@ __inline static unsigned char *get_da(unsigned char *pframe) __inline static unsigned char *get_sa(unsigned char *pframe) { unsigned char *sa; - unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + unsigned int to_fr_ds = (GetFrDs(pframe) << 1) | GetToDs(pframe); switch (to_fr_ds) { case 0x00: /* ToDs=0, FromDs=0 */ sa = get_addr2_ptr(pframe); break; - case 0x01: /* ToDs=0, FromDs=1 */ - sa = GetAddr3Ptr(pframe); - break; - case 0x02: /* ToDs=1, FromDs=0 */ + case 0x01: /* ToDs=1, FromDs=0 */ sa = get_addr2_ptr(pframe); break; + case 0x02: /* ToDs=0, FromDs=1 */ + sa = GetAddr3Ptr(pframe); + break; default: /* ToDs=1, FromDs=1 */ sa = GetAddr4Ptr(pframe); break; @@ -524,25 +528,25 @@ __inline static unsigned char *get_sa(unsigned char *pframe) /* can't apply to mesh mode */ __inline static unsigned char *get_hdr_bssid(unsigned char *pframe) { - unsigned char *sa = NULL; - unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + unsigned char *bssid= NULL; + unsigned int to_fr_ds = (GetFrDs(pframe) << 1) | GetToDs(pframe); switch (to_fr_ds) { case 0x00: /* ToDs=0, FromDs=0 */ - sa = GetAddr3Ptr(pframe); + bssid = GetAddr3Ptr(pframe); break; - case 0x01: /* ToDs=0, FromDs=1 */ - sa = get_addr2_ptr(pframe); + case 0x01: /* ToDs=1, FromDs=0 */ + bssid = GetAddr1Ptr(pframe); break; - case 0x02: /* ToDs=1, FromDs=0 */ - sa = GetAddr1Ptr(pframe); + case 0x02: /* ToDs=0, FromDs=1 */ + bssid = get_addr2_ptr(pframe); break; case 0x03: /* ToDs=1, FromDs=1 */ - sa = GetAddr1Ptr(pframe); + bssid = GetAddr1Ptr(pframe); break; } - return sa; + return bssid; } @@ -735,19 +739,24 @@ typedef enum _ELEMENT_ID { #define WLAN_ETHCONV_ENCAP 1 #define WLAN_ETHCONV_RFC1042 2 -#define WLAN_ETHCONV_8021h 3 +#define WLAN_ETHCONV_8021h 3 -#define cap_ESS BIT(0) -#define cap_IBSS BIT(1) -#define cap_CFPollable BIT(2) -#define cap_CFRequest BIT(3) -#define cap_Privacy BIT(4) -#define cap_ShortPremble BIT(5) -#define cap_PBCC BIT(6) -#define cap_ChAgility BIT(7) -#define cap_SpecMgmt BIT(8) -#define cap_QoS BIT(9) -#define cap_ShortSlot BIT(10) +#define cap_ESS BIT(0) +#define cap_IBSS BIT(1) +#define cap_CFPollable BIT(2) +#define cap_CFRequest BIT(3) +#define cap_Privacy BIT(4) +#define cap_ShortPremble BIT(5) +#define cap_PBCC BIT(6) +#define cap_ChAgility BIT(7) +#define cap_SpecMgmt BIT(8) +#define cap_QoS BIT(9) +#define cap_ShortSlot BIT(10) +#define cap_APSD BIT(11) +#define cap_RM BIT(12) +#define cap_DSSSOFDM BIT(13) +#define cap_DelayedBACK BIT(14) +#define cap_ImmediateBACK BIT(15) /*----------------------------------------------------------------------------- Below is the definition for 802.11i / 802.1x @@ -1275,9 +1284,6 @@ enum P2P_PROTO_WK_ID { P2P_PRE_TX_PROVDISC_PROCESS_WK = 2, P2P_PRE_TX_NEGOREQ_PROCESS_WK = 3, P2P_PRE_TX_INVITEREQ_PROCESS_WK = 4, - P2P_AP_P2P_CH_SWITCH_PROCESS_WK = 5, - P2P_RO_CH_WK = 6, - P2P_CANCEL_RO_CH_WK = 7, }; #ifdef CONFIG_P2P_PS @@ -1320,6 +1326,12 @@ enum P2P_PS_MODE { #define IP_MCAST_MAC(mac) ((mac[0] == 0x01) && (mac[1] == 0x00) && (mac[2] == 0x5e)) #define ICMPV6_MCAST_MAC(mac) ((mac[0] == 0x33) && (mac[1] == 0x33) && (mac[2] != 0xff)) +enum RTW_ROCH_WK_ID{ + ROCH_RO_CH_WK, + ROCH_CANCEL_RO_CH_WK, + ROCH_AP_ROCH_CH_SWITCH_PROCESS_WK, +}; + #ifdef CONFIG_IOCTL_CFG80211 /* Regulatroy Domain */ struct regd_pair_mapping { diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/xmit_osdep.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/xmit_osdep.h index 1a400c961e73..3efbacd6e69c 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/xmit_osdep.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/xmit_osdep.h @@ -88,6 +88,8 @@ extern sint rtw_endofpktfile(struct pkt_file *pfile); extern void rtw_os_pkt_complete(_adapter *padapter, _pkt *pkt); extern void rtw_os_xmit_complete(_adapter *padapter, struct xmit_frame *pxframe); +void rtw_os_check_wakup_queue(_adapter *adapter, u16 os_qid); +bool rtw_os_check_stop_queue(_adapter *adapter, u16 os_qid); void rtw_os_wake_queue_at_free_stainfo(_adapter *padapter, int *qcnt_freed); void dump_os_queue(void *sel, _adapter *padapter); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_cfg80211.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_cfg80211.c index 2de4a6506daf..1a201ddddbae 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_cfg80211.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_cfg80211.c @@ -44,8 +44,6 @@ #define STATION_INFO_ASSOC_REQ_IES 0 #endif /* Linux kernel >= 4.0.0 */ -#include - #define RTW_MAX_MGMT_TX_CNT (8) #define RTW_MAX_MGMT_TX_MS_GAS (500) @@ -127,7 +125,7 @@ static const u32 rtw_cipher_suites[] = { .hw_value = (_channel), \ .flags = (_flags), \ .max_antenna_gain = 0, \ - .max_power = 30, \ + .max_power = 0, \ } #define CHAN5G(_channel, _flags) { \ @@ -136,7 +134,7 @@ static const u32 rtw_cipher_suites[] = { .hw_value = (_channel), \ .flags = (_flags), \ .max_antenna_gain = 0, \ - .max_power = 30, \ + .max_power = 0, \ } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) @@ -215,6 +213,8 @@ static u8 rtw_chbw_to_cfg80211_chan_def(struct wiphy *wiphy, struct cfg80211_cha struct ieee80211_channel *chan; u8 ret = _FAIL; + _rtw_memset(chdef, 0, sizeof(*chdef)); + freq = rtw_ch2freq(ch); if (!freq) goto exit; @@ -251,7 +251,6 @@ static u8 rtw_chbw_to_cfg80211_chan_def(struct wiphy *wiphy, struct cfg80211_cha chdef->chan = chan; chdef->center_freq1 = cfreq; - chdef->center_freq2 = 0; ret = _SUCCESS; @@ -441,7 +440,8 @@ bool rtw_cfg80211_allow_ch_switch_notify(_adapter *adapter) return 1; } -u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, u8 ht) +u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, + u8 ht, bool started) { struct wiphy *wiphy = adapter_to_wiphy(adapter); u8 ret = _SUCCESS; @@ -449,13 +449,20 @@ u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, u8 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) struct cfg80211_chan_def chdef; - if (!rtw_cfg80211_allow_ch_switch_notify(adapter)) - goto exit; - ret = rtw_chbw_to_cfg80211_chan_def(wiphy, &chdef, ch, bw, offset, ht); if (ret != _SUCCESS) goto exit; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) + if (started) { + cfg80211_ch_switch_started_notify(adapter->pnetdev, &chdef, 0); + goto exit; + } +#endif + + if (!rtw_cfg80211_allow_ch_switch_notify(adapter)) + goto exit; + cfg80211_ch_switch_notify(adapter->pnetdev, &chdef); #else @@ -531,18 +538,7 @@ struct ieee80211_supported_band *rtw_spt_band_alloc(BAND_TYPE band) spt_band->n_channels = n_channels; spt_band->n_bitrates = n_bitrates; - if (band == BAND_ON_2_4G) { - rtw_2g_channels_init(spt_band->channels); - rtw_2g_rates_init(spt_band->bitrates); - } else if (band == BAND_ON_5G) { - rtw_5g_channels_init(spt_band->channels); - rtw_5g_rates_init(spt_band->bitrates); - } - - /* spt_band.ht_cap */ - exit: - return spt_band; } @@ -2730,6 +2726,15 @@ static int cfg80211_rtw_change_iface(struct wiphy *wiphy, if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE) rtw_indicate_connect(padapter); #endif + + #if defined(CONFIG_RTW_WDS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) + if (params->use_4addr != -1) { + RTW_INFO(FUNC_NDEV_FMT" use_4addr=%d\n" + , FUNC_NDEV_ARG(ndev), params->use_4addr); + adapter_set_use_wds(padapter, params->use_4addr); + } + #endif + exit: RTW_INFO(FUNC_NDEV_FMT" ret:%d\n", FUNC_NDEV_ARG(ndev), ret); @@ -2741,7 +2746,7 @@ void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted) struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); _irqL irqL; -#if (KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE) struct cfg80211_scan_info info; memset(&info, 0, sizeof(info)); @@ -2758,7 +2763,7 @@ void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted) if (pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy) RTW_INFO("error wiphy compare\n"); else -#if (KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE) cfg80211_scan_done(pwdev_priv->scan_request, &info); #else cfg80211_scan_done(pwdev_priv->scan_request, aborted); @@ -2897,7 +2902,7 @@ static void _rtw_cfg80211_surveydone_event_callback(_adapter *padapter, struct c && rtw_mlme_band_check(padapter, ch) == _TRUE && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid)) && (!IS_DFS_SLAVE_WITH_RD(rfctl) - || rtw_odm_dfs_domain_unknown(rfctl_to_dvobj(rfctl)) + || rtw_rfctl_dfs_domain_unknown(rfctl) || !rtw_chset_is_ch_non_ocp(chset, ch)) ) { if (target_wps_scan) @@ -3019,6 +3024,10 @@ static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, in return -EINVAL; } #endif /* CONFIG_WFD */ + + #ifdef CONFIG_RTW_MBO + rtw_mbo_update_ie_data(padapter, buf, len); + #endif } return ret; @@ -3479,7 +3488,7 @@ bypass_p2p_chk: check_need_indicate_scan_done: if (_TRUE == need_indicate_scan_done) { -#if (KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE) struct cfg80211_scan_info info; memset(&info, 0, sizeof(info)); @@ -3489,7 +3498,7 @@ check_need_indicate_scan_done: rtw_msleep_os(1); _rtw_cfg80211_surveydone_event_callback(padapter, request); -#if (KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE) cfg80211_scan_done(request, &info); #else cfg80211_scan_done(request, 0); @@ -3508,6 +3517,22 @@ exit: return ret; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) && \ + defined(CONFIG_RTW_ABORT_SCAN) +static void cfg80211_rtw_abort_scan(struct wiphy *wiphy, + struct wireless_dev *wdev) +{ + _adapter *padapter = wiphy_to_adapter(wiphy); + + RTW_INFO("=>"FUNC_ADPT_FMT" - Abort Scan\n", FUNC_ADPT_ARG(padapter)); + if (wdev->iftype != NL80211_IFTYPE_STATION) { + RTW_ERR("abort scan ignored, iftype(%d)\n", wdev->iftype); + return; + } + rtw_scan_abort(padapter); +} +#endif + static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed) { #if 0 @@ -3957,6 +3982,12 @@ static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen) } #endif /* CONFIG_WFD */ + #ifdef CONFIG_RTW_MULTI_AP + padapter->multi_ap = rtw_get_multi_ap_ie_ext(buf, ielen) & MULTI_AP_BACKHAUL_STA; + if (padapter->multi_ap) + adapter_set_use_wds(padapter, 1); + #endif + /* TKIP and AES disallow multicast packets until installing group key */ if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_ || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_ @@ -4140,7 +4171,8 @@ static int _rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev) return 0; } -#if (KERNEL_VERSION(4, 17, 0) > LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 17, 0) > LINUX_VERSION_CODE) \ + && !defined(CONFIG_KERNEL_PATCH_EXTERNAL_AUTH) static bool rtw_check_connect_sae_compat(struct cfg80211_connect_params *sme) { struct rtw_ieee802_11_elems elems; @@ -4394,6 +4426,10 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, /* rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */ +#ifdef CONFIG_RTW_MBO + rtw_mbo_update_ie_data(padapter, (u8 *)sme->ie, sme->ie_len); +#endif + if (rtw_set_802_11_connect(padapter, (u8 *)sme->bssid, &ndis_ssid, \ sme->channel ? sme->channel->hw_value : 0) == _FALSE) { ret = -1; @@ -4462,6 +4498,7 @@ static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev, } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) +#ifdef CONFIG_RTW_DEBUG static const char *nl80211_tx_power_setting_str(int type) { switch (type) { @@ -4475,6 +4512,7 @@ static const char *nl80211_tx_power_setting_str(int type) return "UNKNOWN"; }; } +#endif /* CONFIG_RTW_DEBUG */ static int cfg80211_rtw_set_txpower(struct wiphy *wiphy, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) @@ -4550,12 +4588,12 @@ static int cfg80211_rtw_get_txpower(struct wiphy *wiphy, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) if (wdev && wdev_to_ndev(wdev)) { _adapter *adapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev)); - mbm = rtw_adapter_get_oper_txpwr_max_mbm(adapter); + mbm = rtw_adapter_get_oper_txpwr_max_mbm(adapter, 1); RTW_INFO(FUNC_ADPT_FMT" total max: %d mbm\n", FUNC_ADPT_ARG(adapter), mbm); } else #endif { - mbm = rtw_get_oper_txpwr_max_mbm(dvobj); + mbm = rtw_get_oper_txpwr_max_mbm(dvobj, 1); RTW_INFO(FUNC_WIPHY_FMT" total max: %d mbm\n", FUNC_WIPHY_ARG(wiphy), mbm); } @@ -4568,7 +4606,9 @@ static int cfg80211_rtw_get_txpower(struct wiphy *wiphy, inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter) { struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(adapter); - return rtw_wdev_priv->power_mgmt; + struct wireless_dev *wdev = rtw_wdev_priv->rtw_wdev; + + return wdev->ps; } static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy, @@ -4576,13 +4616,10 @@ static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy, bool enabled, int timeout) { _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); - struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(padapter); RTW_INFO(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev), enabled, timeout); - rtw_wdev_priv->power_mgmt = enabled; - #ifdef CONFIG_LPS if (!enabled) rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE_CFG80211_PWRMGMT, 0); @@ -4644,11 +4681,6 @@ static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy, if (_rtw_memcmp((u8 *)pmksa->bssid, strZeroMacAddress, ETH_ALEN) == _TRUE) return -EINVAL; - if (check_fwstate(mlme, WIFI_ASOC_STATE) == _FALSE && !sae_auth) { - RTW_INFO(FUNC_NDEV_FMT" not set pmksa cause not in linked state\n", FUNC_NDEV_ARG(ndev)); - return -EINVAL; - } - _rtw_set_pmksa(ndev, (u8 *)pmksa->bssid, (u8 *)pmksa->pmkid); if (sae_auth && @@ -4706,114 +4738,6 @@ static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy, return 0; } -#ifdef CONFIG_AP_MODE -void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len) -{ -#if !defined(RTW_USE_CFG80211_STA_EVENT) && !defined(COMPAT_KERNEL_RELEASE) - s32 freq; - int channel; - struct wireless_dev *pwdev = padapter->rtw_wdev; - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); -#endif - struct net_device *ndev = padapter->pnetdev; - - RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); - -#if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE) - { - struct station_info sinfo; - u8 ie_offset; - if (get_frame_sub_type(pmgmt_frame) == WIFI_ASSOCREQ) - ie_offset = _ASOCREQ_IE_OFFSET_; - else /* WIFI_REASSOCREQ */ - ie_offset = _REASOCREQ_IE_OFFSET_; - - memset(&sinfo, 0, sizeof(sinfo)); - sinfo.filled = STATION_INFO_ASSOC_REQ_IES; - sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset; - sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset; - cfg80211_new_sta(ndev, get_addr2_ptr(pmgmt_frame), &sinfo, GFP_ATOMIC); - } -#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ - channel = pmlmeext->cur_channel; - freq = rtw_ch2freq(channel); - - #ifdef COMPAT_KERNEL_RELEASE - rtw_cfg80211_rx_mgmt(pwdev, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); - #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) - rtw_cfg80211_rx_mgmt(pwdev, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); - #else /* COMPAT_KERNEL_RELEASE */ - { - /* to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc() */ - #ifndef CONFIG_PLATFORM_MSTAR - pwdev->iftype = NL80211_IFTYPE_STATION; - #endif /* CONFIG_PLATFORM_MSTAR */ - RTW_INFO("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype); - rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len); - RTW_INFO("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype); - pwdev->iftype = NL80211_IFTYPE_AP; - /* cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC); */ - } - #endif /* COMPAT_KERNEL_RELEASE */ -#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ - -} - -void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, const u8 *da, unsigned short reason) -{ -#if !defined(RTW_USE_CFG80211_STA_EVENT) && !defined(COMPAT_KERNEL_RELEASE) - s32 freq; - int channel; - u8 *pmgmt_frame; - uint frame_len; - struct rtw_ieee80211_hdr *pwlanhdr; - unsigned short *fctrl; - u8 mgmt_buf[128] = {0}; - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); - struct wireless_dev *wdev = padapter->rtw_wdev; -#endif - struct net_device *ndev = padapter->pnetdev; - - RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); - -#if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE) - cfg80211_del_sta(ndev, da, GFP_ATOMIC); -#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ - channel = pmlmeext->cur_channel; - freq = rtw_ch2freq(channel); - - pmgmt_frame = mgmt_buf; - pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame; - - fctrl = &(pwlanhdr->frame_ctl); - *(fctrl) = 0; - - _rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN); - _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); - - SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); - pmlmeext->mgnt_seq++; - set_frame_sub_type(pmgmt_frame, WIFI_DEAUTH); - - pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr); - frame_len = sizeof(struct rtw_ieee80211_hdr_3addr); - - reason = cpu_to_le16(reason); - pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len); - - #ifdef COMPAT_KERNEL_RELEASE - rtw_cfg80211_rx_mgmt(wdev, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC); - #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) - rtw_cfg80211_rx_mgmt(wdev, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC); - #else /* COMPAT_KERNEL_RELEASE */ - cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len); - /* cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC); */ - #endif /* COMPAT_KERNEL_RELEASE */ -#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ -} - static int rtw_cfg80211_monitor_if_open(struct net_device *ndev) { int ret = 0; @@ -4975,7 +4899,6 @@ dump: pattrib->seqnum = pmlmeext->mgnt_seq; pmlmeext->mgnt_seq++; - pattrib->last_txcmdsz = pattrib->pktlen; dump_mgntframe(padapter, pmgntframe); @@ -5103,167 +5026,112 @@ out: return ret; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) -static struct wireless_dev * -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE) -static struct net_device * -#else -static int -#endif - cfg80211_rtw_add_virtual_intf( - struct wiphy *wiphy, - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) - const char *name, - #else - char *name, - #endif - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) - unsigned char name_assign_type, - #endif - enum nl80211_iftype type, - #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) - u32 *flags, - #endif - struct vif_params *params) +#ifdef CONFIG_AP_MODE +void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len) { - int ret = 0; - struct wireless_dev *wdev = NULL; - struct net_device *ndev = NULL; - _adapter *padapter; - struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy); - - rtw_set_rtnl_lock_holder(dvobj, current); - - RTW_INFO(FUNC_WIPHY_FMT" name:%s, type:%d\n", FUNC_WIPHY_ARG(wiphy), name, type); - - switch (type) { - case NL80211_IFTYPE_MONITOR: - padapter = wiphy_to_adapter(wiphy); /* TODO: get ap iface ? */ - ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev); - if (ret == 0) - wdev = ndev->ieee80211_ptr; - break; - -#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) - case NL80211_IFTYPE_P2P_CLIENT: - case NL80211_IFTYPE_P2P_GO: +#if !defined(RTW_USE_CFG80211_STA_EVENT) && !defined(COMPAT_KERNEL_RELEASE) + s32 freq; + int channel; + struct wireless_dev *pwdev = padapter->rtw_wdev; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); #endif - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_AP: -#ifdef CONFIG_RTW_MESH - case NL80211_IFTYPE_MESH_POINT: -#endif - padapter = dvobj_get_unregisterd_adapter(dvobj); - if (!padapter) { - RTW_WARN("adapter pool empty!\n"); - ret = -ENODEV; - break; - } + struct net_device *ndev = padapter->pnetdev; - #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) - #if defined(CONFIG_P2P) && ((KERNEL_VERSION(2, 6, 37) <= LINUX_VERSION_CODE) || defined(COMPAT_KERNEL_RELEASE)) - if ((type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO) && (padapter->iface_id != padapter->registrypriv.sel_p2p_iface)) { - RTW_ERR("%s, iface_id:%d is not P2P interface!\n", __func__, padapter->iface_id); - ret = -EOPNOTSUPP; - break; - } - #endif - #endif + RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); - if (rtw_os_ndev_init(padapter, name) != _SUCCESS) { - RTW_WARN("ndev init fail!\n"); - ret = -ENODEV; - break; - } - #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) - if (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO) - rtw_p2p_enable(padapter, P2P_ROLE_DEVICE); - #endif - ndev = padapter->pnetdev; - wdev = ndev->ieee80211_ptr; - break; +#if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE) + { + struct station_info sinfo; + u8 ie_offset; + if (get_frame_sub_type(pmgmt_frame) == WIFI_ASSOCREQ) + ie_offset = _ASOCREQ_IE_OFFSET_; + else /* WIFI_REASSOCREQ */ + ie_offset = _REASOCREQ_IE_OFFSET_; -#if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE) - case NL80211_IFTYPE_P2P_DEVICE: - ret = rtw_pd_iface_alloc(wiphy, name, &wdev); - break; -#endif - - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_WDS: - default: - ret = -ENODEV; - RTW_INFO("Unsupported interface type\n"); - break; + memset(&sinfo, 0, sizeof(sinfo)); + sinfo.filled = STATION_INFO_ASSOC_REQ_IES; + sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset; + sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset; + cfg80211_new_sta(ndev, get_addr2_ptr(pmgmt_frame), &sinfo, GFP_ATOMIC); } +#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ + channel = pmlmeext->cur_channel; + freq = rtw_ch2freq(channel); - if (ndev) - RTW_INFO(FUNC_WIPHY_FMT" ndev:%p, ret:%d\n", FUNC_WIPHY_ARG(wiphy), ndev, ret); - else - RTW_INFO(FUNC_WIPHY_FMT" wdev:%p, ret:%d\n", FUNC_WIPHY_ARG(wiphy), wdev, ret); + #ifdef COMPAT_KERNEL_RELEASE + rtw_cfg80211_rx_mgmt(pwdev, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + rtw_cfg80211_rx_mgmt(pwdev, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); + #else /* COMPAT_KERNEL_RELEASE */ + { + /* to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc() */ + #ifndef CONFIG_PLATFORM_MSTAR + pwdev->iftype = NL80211_IFTYPE_STATION; + #endif /* CONFIG_PLATFORM_MSTAR */ + RTW_INFO("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype); + rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len); + RTW_INFO("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype); + pwdev->iftype = NL80211_IFTYPE_AP; + /* cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC); */ + } + #endif /* COMPAT_KERNEL_RELEASE */ +#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ - rtw_set_rtnl_lock_holder(dvobj, NULL); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) - return wdev ? wdev : ERR_PTR(ret); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE) - return ndev ? ndev : ERR_PTR(ret); -#else - return ret; -#endif } -static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) - struct wireless_dev *wdev -#else - struct net_device *ndev -#endif -) +void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, const u8 *da, unsigned short reason) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) - struct net_device *ndev = wdev_to_ndev(wdev); +#if !defined(RTW_USE_CFG80211_STA_EVENT) && !defined(COMPAT_KERNEL_RELEASE) + s32 freq; + int channel; + u8 *pmgmt_frame; + uint frame_len; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + u8 mgmt_buf[128] = {0}; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct wireless_dev *wdev = padapter->rtw_wdev; #endif - int ret = 0; - struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy); - _adapter *adapter; - struct rtw_wdev_priv *pwdev_priv; + struct net_device *ndev = padapter->pnetdev; - rtw_set_rtnl_lock_holder(dvobj, current); + RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); - if (ndev) { - adapter = (_adapter *)rtw_netdev_priv(ndev); - pwdev_priv = adapter_wdev_data(adapter); +#if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE) + cfg80211_del_sta(ndev, da, GFP_ATOMIC); +#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ + channel = pmlmeext->cur_channel; + freq = rtw_ch2freq(channel); - if (ndev == pwdev_priv->pmon_ndev) { - unregister_netdevice(ndev); - pwdev_priv->pmon_ndev = NULL; - pwdev_priv->ifname_mon[0] = '\0'; - RTW_INFO(FUNC_NDEV_FMT" remove monitor ndev\n", FUNC_NDEV_ARG(ndev)); - } else { - RTW_INFO(FUNC_NDEV_FMT" unregister ndev\n", FUNC_NDEV_ARG(ndev)); - rtw_os_ndev_unregister(adapter); - } - } else -#if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE) - if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) { - if (wdev == wiphy_to_pd_wdev(wiphy)) - rtw_pd_iface_free(wiphy); - else { - RTW_ERR(FUNC_WIPHY_FMT" unknown P2P Device wdev:%p\n", FUNC_WIPHY_ARG(wiphy), wdev); - rtw_warn_on(1); - } - } else -#endif - { - ret = -EINVAL; - goto exit; - } + pmgmt_frame = mgmt_buf; + pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame; -exit: - rtw_set_rtnl_lock_holder(dvobj, NULL); - return ret; + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + _rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + set_frame_sub_type(pmgmt_frame, WIFI_DEAUTH); + + pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr); + frame_len = sizeof(struct rtw_ieee80211_hdr_3addr); + + reason = cpu_to_le16(reason); + pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len); + + #ifdef COMPAT_KERNEL_RELEASE + rtw_cfg80211_rx_mgmt(wdev, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC); + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + rtw_cfg80211_rx_mgmt(wdev, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC); + #else /* COMPAT_KERNEL_RELEASE */ + cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len); + /* cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC); */ + #endif /* COMPAT_KERNEL_RELEASE */ +#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ } static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len) @@ -5943,6 +5811,7 @@ static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev if (psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE) { RTW_INFO("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__); + #ifdef CONFIG_AP_MODE if (MLME_IS_AP(padapter)) { rtw_list_delete(&psta->asoc_list); pstapriv->asoc_list_cnt--; @@ -5956,6 +5825,7 @@ static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev psta = NULL; break; } + #endif } else { RTW_INFO("free psta=%p, aid=%d\n", psta, psta->cmn.aid); @@ -6316,7 +6186,576 @@ static int cfg80211_rtw_set_channel(struct wiphy *wiphy } #endif /*#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))*/ +/* +static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_auth_request *req) +{ + RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + return 0; +} + +static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_assoc_request *req) +{ + RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + return 0; +} +*/ + +static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len) +{ + int ret = 0; + uint wps_ielen = 0; + u8 *wps_ie; + u32 p2p_ielen = 0; + u8 wps_oui[8] = {0x0, 0x50, 0xf2, 0x04}; + u8 *p2p_ie; + u32 wfd_ielen = 0; + u8 *wfd_ie; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + + RTW_INFO(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len); + + if (len > 0) { + wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen); + if (wps_ie) { + #ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("bcn_wps_ielen=%d\n", wps_ielen); + #endif + + if (pmlmepriv->wps_beacon_ie) { + u32 free_len = pmlmepriv->wps_beacon_ie_len; + pmlmepriv->wps_beacon_ie_len = 0; + rtw_mfree(pmlmepriv->wps_beacon_ie, free_len); + pmlmepriv->wps_beacon_ie = NULL; + } + + pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen); + if (pmlmepriv->wps_beacon_ie == NULL) { + RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + + _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen); + pmlmepriv->wps_beacon_ie_len = wps_ielen; + + update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE, RTW_CMDF_WAIT_ACK); + + } + + /* buf += wps_ielen; */ + /* len -= wps_ielen; */ + + #ifdef CONFIG_P2P + p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen); + if (p2p_ie) { + #ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("bcn_p2p_ielen=%d\n", p2p_ielen); + #endif + + if (pmlmepriv->p2p_beacon_ie) { + u32 free_len = pmlmepriv->p2p_beacon_ie_len; + pmlmepriv->p2p_beacon_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len); + pmlmepriv->p2p_beacon_ie = NULL; + } + + pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen); + if (pmlmepriv->p2p_beacon_ie == NULL) { + RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + + _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_beacon_ie_len = p2p_ielen; + + } + #endif /* CONFIG_P2P */ + + + #ifdef CONFIG_WFD + wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen); + if (wfd_ie) { + #ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("bcn_wfd_ielen=%d\n", wfd_ielen); + #endif + + if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_BEACON_IE, wfd_ie, wfd_ielen) != _SUCCESS) + return -EINVAL; + } + #endif /* CONFIG_WFD */ + + pmlmeext->bstart_bss = _TRUE; + + } + + return ret; + +} + +static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len) +{ + int ret = 0; + uint wps_ielen = 0; + u8 *wps_ie; + u32 p2p_ielen = 0; + u8 *p2p_ie; + u32 wfd_ielen = 0; + u8 *wfd_ie; + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + +#ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("%s, ielen=%d\n", __func__, len); +#endif + + if (len > 0) { + wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen); + if (wps_ie) { + uint attr_contentlen = 0; + u16 uconfig_method, *puconfig_method = NULL; + + #ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("probe_resp_wps_ielen=%d\n", wps_ielen); + #endif + + if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) { + u8 sr = 0; + rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL); + + if (sr != 0) + RTW_INFO("%s, got sr\n", __func__); + else { + RTW_INFO("GO mode process WPS under site-survey, sr no set\n"); + return ret; + } + } + + if (pmlmepriv->wps_probe_resp_ie) { + u32 free_len = pmlmepriv->wps_probe_resp_ie_len; + pmlmepriv->wps_probe_resp_ie_len = 0; + rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len); + pmlmepriv->wps_probe_resp_ie = NULL; + } + + pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen); + if (pmlmepriv->wps_probe_resp_ie == NULL) { + RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + + /* add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode */ + puconfig_method = (u16 *)rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen); + if (puconfig_method != NULL) { + /* struct registry_priv *pregistrypriv = &padapter->registrypriv; */ + struct wireless_dev *wdev = padapter->rtw_wdev; + + #ifdef CONFIG_DEBUG_CFG80211 + /* printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method)); */ + #endif + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) + /* for WIFI-DIRECT LOGO 4.2.2, AUTO GO can't set PUSH_BUTTON flags */ + if (wdev->iftype == NL80211_IFTYPE_P2P_GO) { + uconfig_method = WPS_CM_PUSH_BUTTON; + uconfig_method = cpu_to_be16(uconfig_method); + + *puconfig_method &= ~uconfig_method; + } + #endif + } + + _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen); + pmlmepriv->wps_probe_resp_ie_len = wps_ielen; + + } + + /* buf += wps_ielen; */ + /* len -= wps_ielen; */ + + #ifdef CONFIG_P2P + p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen); + if (p2p_ie) { + u8 is_GO = _FALSE; + u32 attr_contentlen = 0; + u16 cap_attr = 0; + + #ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("probe_resp_p2p_ielen=%d\n", p2p_ielen); + #endif + + /* Check P2P Capability ATTR */ + if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&cap_attr, (uint *) &attr_contentlen)) { + u8 grp_cap = 0; + /* RTW_INFO( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ ); */ + cap_attr = le16_to_cpu(cap_attr); + grp_cap = (u8)((cap_attr >> 8) & 0xff); + + is_GO = (grp_cap & BIT(0)) ? _TRUE : _FALSE; + + if (is_GO) + RTW_INFO("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap); + } + + + if (is_GO == _FALSE) { + if (pmlmepriv->p2p_probe_resp_ie) { + u32 free_len = pmlmepriv->p2p_probe_resp_ie_len; + pmlmepriv->p2p_probe_resp_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len); + pmlmepriv->p2p_probe_resp_ie = NULL; + } + + pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen); + if (pmlmepriv->p2p_probe_resp_ie == NULL) { + RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen; + } else { + if (pmlmepriv->p2p_go_probe_resp_ie) { + u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len; + pmlmepriv->p2p_go_probe_resp_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len); + pmlmepriv->p2p_go_probe_resp_ie = NULL; + } + + pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen); + if (pmlmepriv->p2p_go_probe_resp_ie == NULL) { + RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen; + } + + } + #endif /* CONFIG_P2P */ + + + #ifdef CONFIG_WFD + wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen); + #ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("probe_resp_wfd_ielen=%d\n", wfd_ielen); + #endif + + if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_PROBE_RESP_IE, wfd_ie, wfd_ielen) != _SUCCESS) + return -EINVAL; + #endif /* CONFIG_WFD */ + + } + + return ret; + +} + +static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len) +{ + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 *ie; + u32 ie_len; + + RTW_INFO("%s, ielen=%d\n", __func__, len); + + if (len <= 0) + goto exit; + + ie = rtw_get_wps_ie(buf, len, NULL, &ie_len); + if (ie && ie_len) { + if (pmlmepriv->wps_assoc_resp_ie) { + u32 free_len = pmlmepriv->wps_assoc_resp_ie_len; + + pmlmepriv->wps_assoc_resp_ie_len = 0; + rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len); + pmlmepriv->wps_assoc_resp_ie = NULL; + } + + pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len); + if (pmlmepriv->wps_assoc_resp_ie == NULL) { + RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, ie, ie_len); + pmlmepriv->wps_assoc_resp_ie_len = ie_len; + } +#ifdef CONFIG_P2P + ie = rtw_get_p2p_ie(buf, len, NULL, &ie_len); + if (ie && ie_len) { + if (pmlmepriv->p2p_assoc_resp_ie) { + u32 free_len = pmlmepriv->p2p_assoc_resp_ie_len; + + pmlmepriv->p2p_assoc_resp_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_assoc_resp_ie, free_len); + pmlmepriv->p2p_assoc_resp_ie = NULL; + } + + pmlmepriv->p2p_assoc_resp_ie = rtw_malloc(ie_len); + if (pmlmepriv->p2p_assoc_resp_ie == NULL) { + RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + _rtw_memcpy(pmlmepriv->p2p_assoc_resp_ie, ie, ie_len); + pmlmepriv->p2p_assoc_resp_ie_len = ie_len; + } +#endif +#ifdef CONFIG_WFD + ie = rtw_get_wfd_ie(buf, len, NULL, &ie_len); + if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_ASSOC_RESP_IE, ie, ie_len) != _SUCCESS) + return -EINVAL; +#endif + +exit: + return ret; +} + +int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len, + int type) +{ + int ret = 0; + uint wps_ielen = 0; + u32 p2p_ielen = 0; + +#ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO("%s, ielen=%d\n", __func__, len); +#endif + + if ((rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen > 0)) + #ifdef CONFIG_P2P + || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen > 0)) + #endif + ) { + if (net != NULL) { + switch (type) { + case 0x1: /* BEACON */ + ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len); + break; + case 0x2: /* PROBE_RESP */ + ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len); + #ifdef CONFIG_P2P + if (ret == 0) + adapter_wdev_data((_adapter *)rtw_netdev_priv(net))->probe_resp_ie_update_time = rtw_get_current_time(); + #endif + break; + case 0x4: /* ASSOC_RESP */ + ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len); + break; + } + } + } + + return ret; + +} +#endif /* CONFIG_AP_MODE */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) +static struct wireless_dev * +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE) +static struct net_device * +#else +static int +#endif + cfg80211_rtw_add_virtual_intf( + struct wiphy *wiphy, + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) + const char *name, + #else + char *name, + #endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + unsigned char name_assign_type, + #endif + enum nl80211_iftype type, + #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)) + u32 *flags, + #endif + struct vif_params *params) +{ + int ret = 0; + struct wireless_dev *wdev = NULL; + struct net_device *ndev = NULL; + _adapter *padapter; + struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy); + + rtw_set_rtnl_lock_holder(dvobj, current); + + RTW_INFO(FUNC_WIPHY_FMT" name:%s, type:%d\n", FUNC_WIPHY_ARG(wiphy), name, type); + + switch (type) { + case NL80211_IFTYPE_MONITOR: + padapter = wiphy_to_adapter(wiphy); /* TODO: get ap iface ? */ + ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev); + if (ret == 0) + wdev = ndev->ieee80211_ptr; + break; + +#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_P2P_GO: +#endif + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_AP: +#ifdef CONFIG_RTW_MESH + case NL80211_IFTYPE_MESH_POINT: +#endif + padapter = dvobj_get_unregisterd_adapter(dvobj); + if (!padapter) { + RTW_WARN("adapter pool empty!\n"); + ret = -ENODEV; + break; + } + + #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) + #if defined(CONFIG_P2P) && ((KERNEL_VERSION(2, 6, 37) <= LINUX_VERSION_CODE) || defined(COMPAT_KERNEL_RELEASE)) + if ((type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO) && (padapter->iface_id != padapter->registrypriv.sel_p2p_iface)) { + RTW_ERR("%s, iface_id:%d is not P2P interface!\n", __func__, padapter->iface_id); + ret = -EOPNOTSUPP; + break; + } + #endif + #endif + + if (rtw_os_ndev_init(padapter, name) != _SUCCESS) { + RTW_WARN("ndev init fail!\n"); + ret = -ENODEV; + break; + } + #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) + if (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO) + rtw_p2p_enable(padapter, P2P_ROLE_DEVICE); + #endif + ndev = padapter->pnetdev; + wdev = ndev->ieee80211_ptr; + break; + +#if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE) + case NL80211_IFTYPE_P2P_DEVICE: + ret = rtw_pd_iface_alloc(wiphy, name, &wdev); + break; +#endif + + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_WDS: + default: + ret = -ENODEV; + RTW_INFO("Unsupported interface type\n"); + break; + } + + if (ndev) + RTW_INFO(FUNC_WIPHY_FMT" ndev:%p, ret:%d\n", FUNC_WIPHY_ARG(wiphy), ndev, ret); + else + RTW_INFO(FUNC_WIPHY_FMT" wdev:%p, ret:%d\n", FUNC_WIPHY_ARG(wiphy), wdev, ret); + + rtw_set_rtnl_lock_holder(dvobj, NULL); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + return wdev ? wdev : ERR_PTR(ret); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE) + return ndev ? ndev : ERR_PTR(ret); +#else + return ret; +#endif +} + +static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + struct wireless_dev *wdev +#else + struct net_device *ndev +#endif +) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + struct net_device *ndev = wdev_to_ndev(wdev); +#endif + int ret = 0; + struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy); + _adapter *adapter; + struct rtw_wdev_priv *pwdev_priv; + + rtw_set_rtnl_lock_holder(dvobj, current); + + if (ndev) { + adapter = (_adapter *)rtw_netdev_priv(ndev); + pwdev_priv = adapter_wdev_data(adapter); + + if (ndev == pwdev_priv->pmon_ndev) { + unregister_netdevice(ndev); + pwdev_priv->pmon_ndev = NULL; + pwdev_priv->ifname_mon[0] = '\0'; + RTW_INFO(FUNC_NDEV_FMT" remove monitor ndev\n", FUNC_NDEV_ARG(ndev)); + } else { + RTW_INFO(FUNC_NDEV_FMT" unregister ndev\n", FUNC_NDEV_ARG(ndev)); + rtw_os_ndev_unregister(adapter); + } + } else +#if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE) + if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) { + if (wdev == wiphy_to_pd_wdev(wiphy)) + rtw_pd_iface_free(wiphy); + else { + RTW_ERR(FUNC_WIPHY_FMT" unknown P2P Device wdev:%p\n", FUNC_WIPHY_ARG(wiphy), wdev); + rtw_warn_on(1); + } + } else +#endif + { + ret = -EINVAL; + goto exit; + } + +exit: + rtw_set_rtnl_lock_holder(dvobj, NULL); + return ret; +} + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) +static int cfg80211_rtw_get_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct cfg80211_chan_def *chandef) +{ + _adapter *padapter = wiphy_to_adapter(wiphy); + struct mlme_ext_priv *mlmeext = &(padapter->mlmeextpriv); + u8 ht_option = 0; + u8 report = 0; + int retval = 1; + + if (MLME_IS_ASOC(padapter)) { +#ifdef CONFIG_80211N_HT + ht_option = padapter->mlmepriv.htpriv.ht_option; +#endif /* CONFIG_80211N_HT */ + report = 1; + } else if (MLME_IS_MONITOR(padapter)) { + /* monitor mode always set to HT + we don't support sniffer No HT */ + ht_option = 1; + report = 1; + } + + if (report) { + rtw_chbw_to_cfg80211_chan_def(wiphy, chandef, + mlmeext->cur_channel, mlmeext->cur_bwmode, + mlmeext->cur_ch_offset, ht_option); + retval = 0; + } + + return retval; +} + static void rtw_get_chbwoff_from_cfg80211_chan_def( struct cfg80211_chan_def *chandef, u8 *ht, u8 *ch, u8 *bw, u8 *offset) @@ -6329,7 +6768,7 @@ static void rtw_get_chbwoff_from_cfg80211_chan_def( switch (chandef->width) { case NL80211_CHAN_WIDTH_20_NOHT: *ht = 0; - /* passthrought */ + /* fall through */ case NL80211_CHAN_WIDTH_20: *bw = CHANNEL_WIDTH_20; *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; @@ -6419,59 +6858,6 @@ static int cfg80211_rtw_set_monitor_channel(struct wiphy *wiphy return 0; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) -static int cfg80211_rtw_get_channel(struct wiphy *wiphy, - struct wireless_dev *wdev, - struct cfg80211_chan_def *chandef) -{ - _adapter *padapter = wiphy_to_adapter(wiphy); - struct mlme_ext_priv *mlmeext = &(padapter->mlmeextpriv); - u8 ht_option = 0; - u8 report = 0; - int retval = 1; - - if (MLME_IS_ASOC(padapter)) { -#ifdef CONFIG_80211N_HT - ht_option = padapter->mlmepriv.htpriv.ht_option; -#endif /* CONFIG_80211N_HT */ - report = 1; - } else if (MLME_IS_MONITOR(padapter)) { - /* monitor mode always set to HT - we don't support sniffer No HT */ - ht_option = 1; - report = 1; - } - - if (report) { - rtw_chbw_to_cfg80211_chan_def(wiphy, chandef, - mlmeext->cur_channel, mlmeext->cur_bwmode, - mlmeext->cur_ch_offset, ht_option); - retval = 0; - } - - return retval; -} -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) */ - -/* -static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev, - struct cfg80211_auth_request *req) -{ - RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); - - return 0; -} - -static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev, - struct cfg80211_assoc_request *req) -{ - RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); - - return 0; -} -*/ -#endif /* CONFIG_AP_MODE */ - void rtw_cfg80211_external_auth_request(_adapter *padapter, union recv_frame *rframe) { struct rtw_external_auth_params params; @@ -6488,11 +6874,8 @@ void rtw_cfg80211_external_auth_request(_adapter *padapter, union recv_frame *rf freq = rtw_ch2freq(pmlmeext->cur_channel); -#ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO(FUNC_ADPT_FMT": freq(%d, %d)\n", FUNC_ADPT_ARG(padapter), freq); -#endif - -#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) \ + || defined(CONFIG_KERNEL_PATCH_EXTERNAL_AUTH) params.action = EXTERNAL_AUTH_START; _rtw_memcpy(params.bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); params.ssid.ssid_len = pmlmeinfo->network.Ssid.SsidLength; @@ -7005,34 +7388,35 @@ static s32 cfg80211_rtw_update_ft_ies(struct wiphy *wiphy, return 0; } #endif +#endif /* CONFIG_P2P */ inline void rtw_cfg80211_set_is_roch(_adapter *adapter, bool val) { - adapter->cfg80211_wdinfo.is_ro_ch = val; + adapter->rochinfo.is_ro_ch = val; rtw_mi_update_iface_status(&(adapter->mlmepriv), 0); } inline bool rtw_cfg80211_get_is_roch(_adapter *adapter) { - return adapter->cfg80211_wdinfo.is_ro_ch; + return adapter->rochinfo.is_ro_ch; } inline bool rtw_cfg80211_is_ro_ch_once(_adapter *adapter) { - return adapter->cfg80211_wdinfo.last_ro_ch_time ? 1 : 0; + return adapter->rochinfo.last_ro_ch_time ? 1 : 0; } inline void rtw_cfg80211_set_last_ro_ch_time(_adapter *adapter) { - adapter->cfg80211_wdinfo.last_ro_ch_time = rtw_get_current_time(); + adapter->rochinfo.last_ro_ch_time = rtw_get_current_time(); - if (!adapter->cfg80211_wdinfo.last_ro_ch_time) - adapter->cfg80211_wdinfo.last_ro_ch_time++; + if (!adapter->rochinfo.last_ro_ch_time) + adapter->rochinfo.last_ro_ch_time++; } inline s32 rtw_cfg80211_get_last_ro_ch_passing_ms(_adapter *adapter) { - return rtw_get_passing_time_ms(adapter->cfg80211_wdinfo.last_ro_ch_time); + return rtw_get_passing_time_ms(adapter->rochinfo.last_ro_ch_time); } static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, @@ -7051,11 +7435,13 @@ static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq); _adapter *padapter = NULL; struct rtw_wdev_priv *pwdev_priv; + struct roch_info *prochinfo; +#ifdef CONFIG_P2P struct wifidirect_info *pwdinfo; - struct cfg80211_wifidirect_info *pcfg80211_wdinfo; #ifdef CONFIG_CONCURRENT_MODE u8 is_p2p_find = _FALSE; #endif +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) #if defined(RTW_DEDICATED_P2P_DEVICE) @@ -7081,13 +7467,15 @@ static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, #endif pwdev_priv = adapter_wdev_data(padapter); + prochinfo = &padapter->rochinfo; +#ifdef CONFIG_P2P pwdinfo = &padapter->wdinfo; - pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; #ifdef CONFIG_CONCURRENT_MODE is_p2p_find = (duration < (pwdinfo->ext_listen_interval)) ? _TRUE : _FALSE; +#endif #endif - *cookie = ATOMIC_INC_RETURN(&pcfg80211_wdinfo->ro_ch_cookie_gen); + *cookie = ATOMIC_INC_RETURN(&prochinfo->ro_ch_cookie_gen); RTW_INFO(FUNC_ADPT_FMT"%s ch:%u duration:%d, cookie:0x%llx\n" , FUNC_ADPT_ARG(padapter), wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : "" @@ -7113,17 +7501,18 @@ static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, } rtw_scan_abort(padapter); -#ifdef CONFIG_CONCURRENT_MODE +#if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) /*don't scan_abort during p2p_listen.*/ if (is_p2p_find) rtw_mi_buddy_scan_abort(padapter, _TRUE); -#endif /*CONFIG_CONCURRENT_MODE*/ +#endif /* defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) */ if (rtw_cfg80211_get_is_roch(padapter) == _TRUE) { - _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer); - p2p_cancel_roch_cmd(padapter, 0, NULL, RTW_CMDF_WAIT_ACK); + _cancel_timer_ex(&padapter->rochinfo.remain_on_ch_timer); + rtw_cancel_roch_cmd(padapter, 0, NULL, RTW_CMDF_WAIT_ACK); } +#ifdef CONFIG_P2P /* if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) */ if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) @@ -7151,32 +7540,31 @@ static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, } rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); +#endif /* CONFIG_P2P */ #ifdef RTW_ROCH_DURATION_ENLARGE if (duration < 400) duration = duration * 3; /* extend from exper */ #endif -#if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) +#if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) if (rtw_mi_check_status(padapter, MI_LINKED)) { if (is_p2p_find) /* p2p_find , duration<1000 */ duration = duration + pwdinfo->ext_listen_interval; - else /* p2p_listen, duration=5000 */ - duration = pwdinfo->ext_listen_interval + (pwdinfo->ext_listen_interval / 4); } -#endif /*defined (RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) */ +#endif /* defined (RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_P2P) */ rtw_cfg80211_set_is_roch(padapter, _TRUE); - pcfg80211_wdinfo->ro_ch_wdev = wdev; - pcfg80211_wdinfo->remain_on_ch_cookie = *cookie; + prochinfo->ro_ch_wdev = wdev; + prochinfo->remain_on_ch_cookie = *cookie; rtw_cfg80211_set_last_ro_ch_time(padapter); - _rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel)); + _rtw_memcpy(&prochinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel)); #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) - pcfg80211_wdinfo->remain_on_ch_type = channel_type; + prochinfo->remain_on_ch_type = channel_type; #endif - pcfg80211_wdinfo->restore_channel = rtw_get_oper_ch(padapter); + prochinfo->restore_channel = rtw_get_oper_ch(padapter); - p2p_roch_cmd(padapter, *cookie, wdev, channel, pcfg80211_wdinfo->remain_on_ch_type, + rtw_roch_cmd(padapter, *cookie, wdev, channel, prochinfo->remain_on_ch_type, duration, RTW_CMDF_WAIT_ACK); rtw_cfg80211_ready_on_channel(wdev, *cookie, channel, channel_type, duration, GFP_KERNEL); @@ -7195,8 +7583,10 @@ static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy, s32 err = 0; _adapter *padapter; struct rtw_wdev_priv *pwdev_priv; + struct roch_info *prochinfo; +#ifdef CONFIG_P2P struct wifidirect_info *pwdinfo; - struct cfg80211_wifidirect_info *pcfg80211_wdinfo; +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) #if defined(RTW_DEDICATED_P2P_DEVICE) @@ -7222,22 +7612,25 @@ static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy, #endif pwdev_priv = adapter_wdev_data(padapter); + prochinfo = &padapter->rochinfo; +#ifdef CONFIG_P2P pwdinfo = &padapter->wdinfo; - pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; +#endif RTW_INFO(FUNC_ADPT_FMT"%s cookie:0x%llx\n" , FUNC_ADPT_ARG(padapter), wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : "" , cookie); if (rtw_cfg80211_get_is_roch(padapter) == _TRUE) { - _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer); - p2p_cancel_roch_cmd(padapter, cookie, wdev, RTW_CMDF_WAIT_ACK); + _cancel_timer_ex(&padapter->rochinfo.remain_on_ch_timer); + rtw_cancel_roch_cmd(padapter, cookie, wdev, RTW_CMDF_WAIT_ACK); } exit: return err; } +#ifdef CONFIG_P2P inline int rtw_cfg80211_iface_has_p2p_group_cap(_adapter *adapter) { #if RTW_P2P_GROUP_INTERFACE @@ -7444,11 +7837,9 @@ static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, u8 no_cck, const struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); u8 u_ch = rtw_mi_get_union_chan(padapter); u8 leave_op = 0; -#ifdef CONFIG_P2P - struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; - #ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#if defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE) struct wifidirect_info *pwdinfo = &padapter->wdinfo; - #endif #endif rtw_cfg80211_set_is_mgmt_tx(padapter, 1); @@ -7462,7 +7853,7 @@ static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, u8 no_cck, const #ifdef CONFIG_CONCURRENT_MODE if (!check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) { RTW_INFO("%s, extend ro ch time\n", __func__); - _set_timer(&padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period); + _set_timer(&padapter->rochinfo.remain_on_ch_timer, pwdinfo->ext_listen_period); } #endif /* CONFIG_CONCURRENT_MODE */ } @@ -7481,22 +7872,6 @@ static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, u8 no_cck, const ) { rtw_leave_opch(padapter); leave_op = 1; - - #if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE) - if (rtw_cfg80211_get_is_roch(padapter) - && ATOMIC_READ(&pwdev_priv->switch_ch_to) == 1 - ) { - u16 ext_listen_period; - - if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) - ext_listen_period = 500; - else - ext_listen_period = pwdinfo->ext_listen_period; - ATOMIC_SET(&pwdev_priv->switch_ch_to, 0); - _set_timer(&pwdinfo->ap_p2p_switch_timer, ext_listen_period); - RTW_INFO("%s, set switch ch timer, period=%d\n", __func__, ext_listen_period); - } - #endif /* RTW_ROCH_BACK_OP && CONFIG_P2P && CONFIG_CONCURRENT_MODE */ } if (tx_ch != rtw_get_oper_ch(padapter)) @@ -7568,18 +7943,15 @@ issue_mgmt_frame: } exit: - #ifdef CONFIG_P2P if (rtw_cfg80211_get_is_roch(padapter) - && !roch_stay_in_cur_chan(padapter) - && pcfg80211_wdinfo->remain_on_ch_channel.hw_value != u_ch + && !rtw_roch_stay_in_cur_chan(padapter) + && prochinfo->remain_on_ch_channel.hw_value != u_ch ) { /* roch is ongoing, switch back to rch */ - if (pcfg80211_wdinfo->remain_on_ch_channel.hw_value != tx_ch) - set_channel_bwmode(padapter, pcfg80211_wdinfo->remain_on_ch_channel.hw_value + if (prochinfo->remain_on_ch_channel.hw_value != tx_ch) + set_channel_bwmode(padapter, prochinfo->remain_on_ch_channel.hw_value , HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - } else - #endif - if (leave_op) { + } else if (leave_op) { if (rtw_mi_check_status(padapter, MI_LINKED)) { u8 u_bw = rtw_mi_get_union_bw(padapter); u8 u_offset = rtw_mi_get_union_offset(padapter); @@ -7890,6 +8262,7 @@ exit: return ret; } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) struct wireless_dev *wdev, @@ -7902,7 +8275,6 @@ static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, struct net_device *ndev = wdev_to_ndev(wdev); #endif _adapter *adapter; - struct rtw_wdev_priv *pwdev_priv; if (ndev == NULL) @@ -7919,22 +8291,22 @@ static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, switch (frame_type) { case IEEE80211_STYPE_AUTH: /* 0x00B0 */ if (reg > 0) - SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_AUTH, reg); + SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_AUTH); else - CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_AUTH, reg); + CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_AUTH); break; #ifdef not_yet case IEEE80211_STYPE_PROBE_REQ: /* 0x0040 */ if (reg > 0) - SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_PROBE_REQ, reg); + SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_PROBE_REQ); else - CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_PROBE_REQ, reg); + CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_PROBE_REQ); break; case IEEE80211_STYPE_ACTION: /* 0x00D0 */ if (reg > 0) - SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_ACTION, reg); + SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_ACTION); else - CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_ACTION, reg); + CLR_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_ACTION); break; #endif default: @@ -7944,6 +8316,46 @@ static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, exit: return; } +#else +static void cfg80211_rtw_update_mgmt_frame_register( + struct wiphy *wiphy, + struct wireless_dev *wdev, + struct mgmt_frame_regs *upd) +{ + struct net_device *ndev; + _adapter *padapter; + struct rtw_wdev_priv *pwdev_priv; + u32 rtw_stypes_mask = 0; + u32 rtw_mstypes_mask = 0; + + ndev = wdev_to_ndev(wdev); + + if (ndev == NULL) + goto exit; + + padapter = (_adapter *)rtw_netdev_priv(ndev); + pwdev_priv = adapter_wdev_data(padapter); + + rtw_stypes_mask = BIT(IEEE80211_STYPE_AUTH >> 4); + +#ifdef CONFIG_DEBUG_CFG80211 + RTW_INFO(FUNC_ADPT_FMT " global_stypes:0x%08x interface_stypes:0x%08x\n", + FUNC_ADPT_ARG(padapter), upd->global_stypes, upd->interface_stypes); + RTW_INFO(FUNC_ADPT_FMT " global_mcast_stypes:0x%08x interface_mcast_stypes:0x%08x\n", + FUNC_ADPT_ARG(padapter), upd->global_mcast_stypes, upd->interface_mcast_stypes); + RTW_INFO(FUNC_ADPT_FMT " old_regs:0x%08x new_regs:0x%08x\n", + FUNC_ADPT_ARG(padapter), pwdev_priv->mgmt_regs, + (upd->interface_stypes & rtw_stypes_mask)); +#endif + if (pwdev_priv->mgmt_regs != + (upd->interface_stypes & rtw_stypes_mask)) { + pwdev_priv->mgmt_regs = (upd->interface_stypes & rtw_stypes_mask); + } + +exit: + return; +} +#endif #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy, @@ -9243,361 +9655,6 @@ int cfg80211_rtw_resume(struct wiphy *wiphy) { } #endif /* CONFIG_PNO_SUPPORT */ -static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len) -{ - int ret = 0; - uint wps_ielen = 0; - u8 *wps_ie; - u32 p2p_ielen = 0; - u8 wps_oui[8] = {0x0, 0x50, 0xf2, 0x04}; - u8 *p2p_ie; - u32 wfd_ielen = 0; - u8 *wfd_ie; - _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - - RTW_INFO(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len); - - if (len > 0) { - wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen); - if (wps_ie) { - #ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("bcn_wps_ielen=%d\n", wps_ielen); - #endif - - if (pmlmepriv->wps_beacon_ie) { - u32 free_len = pmlmepriv->wps_beacon_ie_len; - pmlmepriv->wps_beacon_ie_len = 0; - rtw_mfree(pmlmepriv->wps_beacon_ie, free_len); - pmlmepriv->wps_beacon_ie = NULL; - } - - pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen); - if (pmlmepriv->wps_beacon_ie == NULL) { - RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); - return -EINVAL; - - } - - _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen); - pmlmepriv->wps_beacon_ie_len = wps_ielen; - - update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE, RTW_CMDF_WAIT_ACK); - - } - - /* buf += wps_ielen; */ - /* len -= wps_ielen; */ - - #ifdef CONFIG_P2P - p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen); - if (p2p_ie) { - #ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("bcn_p2p_ielen=%d\n", p2p_ielen); - #endif - - if (pmlmepriv->p2p_beacon_ie) { - u32 free_len = pmlmepriv->p2p_beacon_ie_len; - pmlmepriv->p2p_beacon_ie_len = 0; - rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len); - pmlmepriv->p2p_beacon_ie = NULL; - } - - pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen); - if (pmlmepriv->p2p_beacon_ie == NULL) { - RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); - return -EINVAL; - - } - - _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen); - pmlmepriv->p2p_beacon_ie_len = p2p_ielen; - - } - #endif /* CONFIG_P2P */ - - - #ifdef CONFIG_WFD - wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen); - if (wfd_ie) { - #ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("bcn_wfd_ielen=%d\n", wfd_ielen); - #endif - - if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_BEACON_IE, wfd_ie, wfd_ielen) != _SUCCESS) - return -EINVAL; - } - #endif /* CONFIG_WFD */ - - pmlmeext->bstart_bss = _TRUE; - - } - - return ret; - -} - -static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len) -{ - int ret = 0; - uint wps_ielen = 0; - u8 *wps_ie; - u32 p2p_ielen = 0; - u8 *p2p_ie; - u32 wfd_ielen = 0; - u8 *wfd_ie; - _adapter *padapter = (_adapter *)rtw_netdev_priv(net); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - -#ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("%s, ielen=%d\n", __func__, len); -#endif - - if (len > 0) { - wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen); - if (wps_ie) { - uint attr_contentlen = 0; - u16 uconfig_method, *puconfig_method = NULL; - - #ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("probe_resp_wps_ielen=%d\n", wps_ielen); - #endif - - if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) { - u8 sr = 0; - rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL); - - if (sr != 0) - RTW_INFO("%s, got sr\n", __func__); - else { - RTW_INFO("GO mode process WPS under site-survey, sr no set\n"); - return ret; - } - } - - if (pmlmepriv->wps_probe_resp_ie) { - u32 free_len = pmlmepriv->wps_probe_resp_ie_len; - pmlmepriv->wps_probe_resp_ie_len = 0; - rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len); - pmlmepriv->wps_probe_resp_ie = NULL; - } - - pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen); - if (pmlmepriv->wps_probe_resp_ie == NULL) { - RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); - return -EINVAL; - - } - - /* add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode */ - puconfig_method = (u16 *)rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen); - if (puconfig_method != NULL) { - /* struct registry_priv *pregistrypriv = &padapter->registrypriv; */ - struct wireless_dev *wdev = padapter->rtw_wdev; - - #ifdef CONFIG_DEBUG_CFG80211 - /* printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method)); */ - #endif - - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) - /* for WIFI-DIRECT LOGO 4.2.2, AUTO GO can't set PUSH_BUTTON flags */ - if (wdev->iftype == NL80211_IFTYPE_P2P_GO) { - uconfig_method = WPS_CM_PUSH_BUTTON; - uconfig_method = cpu_to_be16(uconfig_method); - - *puconfig_method &= ~uconfig_method; - } - #endif - } - - _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen); - pmlmepriv->wps_probe_resp_ie_len = wps_ielen; - - } - - /* buf += wps_ielen; */ - /* len -= wps_ielen; */ - - #ifdef CONFIG_P2P - p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen); - if (p2p_ie) { - u8 is_GO = _FALSE; - u32 attr_contentlen = 0; - u16 cap_attr = 0; - - #ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("probe_resp_p2p_ielen=%d\n", p2p_ielen); - #endif - - /* Check P2P Capability ATTR */ - if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&cap_attr, (uint *) &attr_contentlen)) { - u8 grp_cap = 0; - /* RTW_INFO( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ ); */ - cap_attr = le16_to_cpu(cap_attr); - grp_cap = (u8)((cap_attr >> 8) & 0xff); - - is_GO = (grp_cap & BIT(0)) ? _TRUE : _FALSE; - - if (is_GO) - RTW_INFO("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap); - } - - - if (is_GO == _FALSE) { - if (pmlmepriv->p2p_probe_resp_ie) { - u32 free_len = pmlmepriv->p2p_probe_resp_ie_len; - pmlmepriv->p2p_probe_resp_ie_len = 0; - rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len); - pmlmepriv->p2p_probe_resp_ie = NULL; - } - - pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen); - if (pmlmepriv->p2p_probe_resp_ie == NULL) { - RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); - return -EINVAL; - - } - _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen); - pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen; - } else { - if (pmlmepriv->p2p_go_probe_resp_ie) { - u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len; - pmlmepriv->p2p_go_probe_resp_ie_len = 0; - rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len); - pmlmepriv->p2p_go_probe_resp_ie = NULL; - } - - pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen); - if (pmlmepriv->p2p_go_probe_resp_ie == NULL) { - RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); - return -EINVAL; - - } - _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen); - pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen; - } - - } - #endif /* CONFIG_P2P */ - - - #ifdef CONFIG_WFD - wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen); - #ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("probe_resp_wfd_ielen=%d\n", wfd_ielen); - #endif - - if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_PROBE_RESP_IE, wfd_ie, wfd_ielen) != _SUCCESS) - return -EINVAL; - #endif /* CONFIG_WFD */ - - } - - return ret; - -} - -static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len) -{ - int ret = 0; - _adapter *padapter = (_adapter *)rtw_netdev_priv(net); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - u8 *ie; - u32 ie_len; - - RTW_INFO("%s, ielen=%d\n", __func__, len); - - if (len <= 0) - goto exit; - - ie = rtw_get_wps_ie(buf, len, NULL, &ie_len); - if (ie && ie_len) { - if (pmlmepriv->wps_assoc_resp_ie) { - u32 free_len = pmlmepriv->wps_assoc_resp_ie_len; - - pmlmepriv->wps_assoc_resp_ie_len = 0; - rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len); - pmlmepriv->wps_assoc_resp_ie = NULL; - } - - pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len); - if (pmlmepriv->wps_assoc_resp_ie == NULL) { - RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); - return -EINVAL; - } - _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, ie, ie_len); - pmlmepriv->wps_assoc_resp_ie_len = ie_len; - } - - ie = rtw_get_p2p_ie(buf, len, NULL, &ie_len); - if (ie && ie_len) { - if (pmlmepriv->p2p_assoc_resp_ie) { - u32 free_len = pmlmepriv->p2p_assoc_resp_ie_len; - - pmlmepriv->p2p_assoc_resp_ie_len = 0; - rtw_mfree(pmlmepriv->p2p_assoc_resp_ie, free_len); - pmlmepriv->p2p_assoc_resp_ie = NULL; - } - - pmlmepriv->p2p_assoc_resp_ie = rtw_malloc(ie_len); - if (pmlmepriv->p2p_assoc_resp_ie == NULL) { - RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); - return -EINVAL; - } - _rtw_memcpy(pmlmepriv->p2p_assoc_resp_ie, ie, ie_len); - pmlmepriv->p2p_assoc_resp_ie_len = ie_len; - } - -#ifdef CONFIG_WFD - ie = rtw_get_wfd_ie(buf, len, NULL, &ie_len); - if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_ASSOC_RESP_IE, ie, ie_len) != _SUCCESS) - return -EINVAL; -#endif - -exit: - return ret; -} - -int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len, - int type) -{ - int ret = 0; - uint wps_ielen = 0; - u32 p2p_ielen = 0; - -#ifdef CONFIG_DEBUG_CFG80211 - RTW_INFO("%s, ielen=%d\n", __func__, len); -#endif - - if ((rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen > 0)) - #ifdef CONFIG_P2P - || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen > 0)) - #endif - ) { - if (net != NULL) { - switch (type) { - case 0x1: /* BEACON */ - ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len); - break; - case 0x2: /* PROBE_RESP */ - ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len); - #ifdef CONFIG_P2P - if (ret == 0) - adapter_wdev_data((_adapter *)rtw_netdev_priv(net))->probe_resp_ie_update_time = rtw_get_current_time(); - #endif - break; - case 0x4: /* ASSOC_RESP */ - ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len); - break; - } - } - } - - return ret; - -} - #ifdef CONFIG_80211N_HT static void rtw_cfg80211_init_ht_capab_ex(_adapter *padapter , struct ieee80211_sta_ht_cap *ht_cap, BAND_TYPE band, u8 rf_type) @@ -9659,9 +9716,21 @@ static void rtw_cfg80211_init_ht_capab(_adapter *padapter ht_cap->ht_supported = 1; - ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | - IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; + ht_cap->cap = IEEE80211_HT_CAP_MAX_AMSDU; + + if (TEST_FLAG(regsty->short_gi, BIT0)) + ht_cap->cap |= IEEE80211_HT_CAP_SGI_20; + if (hal_is_bw_support(padapter, CHANNEL_WIDTH_40) + && ((band == BAND_ON_2_4G && REGSTY_IS_BW_2G_SUPPORT(regsty, CHANNEL_WIDTH_40)) + || (band == BAND_ON_5G && REGSTY_IS_BW_5G_SUPPORT(regsty, CHANNEL_WIDTH_40))) + ) { + ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; + if (band == BAND_ON_2_4G) + ht_cap->cap |= IEEE80211_HT_CAP_DSSSCCK40; + if (TEST_FLAG(regsty->short_gi, BIT1)) + ht_cap->cap |= IEEE80211_HT_CAP_SGI_40; + } + rtw_cfg80211_init_ht_capab_ex(padapter, ht_cap, band, rf_type); /* @@ -9736,43 +9805,89 @@ void rtw_cfg80211_init_wdev_data(_adapter *padapter) #endif } -void rtw_cfg80211_init_wiphy(_adapter *padapter) +static int rtw_cfg80211_init_wiphy_band(_adapter *padapter, struct wiphy *wiphy) { u8 rf_type; struct ieee80211_supported_band *band; - struct wireless_dev *pwdev = padapter->rtw_wdev; - struct wiphy *wiphy = pwdev->wiphy; + int ret = _FAIL; rf_type = GET_HAL_RFPATH(padapter); RTW_INFO("%s:rf_type=%d\n", __func__, rf_type); if (IsSupported24G(padapter->registrypriv.wireless_mode)) { - band = wiphy->bands[NL80211_BAND_2GHZ]; - if (band) { - #if defined(CONFIG_80211N_HT) - rtw_cfg80211_init_ht_capab(padapter, &band->ht_cap, BAND_ON_2_4G, rf_type); - #endif - } + band = wiphy->bands[NL80211_BAND_2GHZ] = rtw_spt_band_alloc(BAND_ON_2_4G); + if (!band) + goto exit; + rtw_2g_channels_init(band->channels); + rtw_2g_rates_init(band->bitrates); + #if defined(CONFIG_80211N_HT) + rtw_cfg80211_init_ht_capab(padapter, &band->ht_cap, BAND_ON_2_4G, rf_type); + #endif } #if CONFIG_IEEE80211_BAND_5GHZ if (is_supported_5g(padapter->registrypriv.wireless_mode)) { - band = wiphy->bands[NL80211_BAND_5GHZ]; - if (band) { - #if defined(CONFIG_80211N_HT) - rtw_cfg80211_init_ht_capab(padapter, &band->ht_cap, BAND_ON_5G, rf_type); - #endif - #if defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) - rtw_cfg80211_init_vht_capab(padapter, &band->vht_cap, BAND_ON_5G, rf_type); - #endif + band = wiphy->bands[NL80211_BAND_5GHZ] = rtw_spt_band_alloc(BAND_ON_5G); + if (!band) { + if (wiphy->bands[NL80211_BAND_2GHZ]) { + rtw_spt_band_free(wiphy->bands[NL80211_BAND_2GHZ]); + wiphy->bands[NL80211_BAND_2GHZ] = NULL; + } + goto exit; } + rtw_5g_channels_init(band->channels); + rtw_5g_rates_init(band->bitrates); + #if defined(CONFIG_80211N_HT) + rtw_cfg80211_init_ht_capab(padapter, &band->ht_cap, BAND_ON_5G, rf_type); + #endif + #if defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + rtw_cfg80211_init_vht_capab(padapter, &band->vht_cap, BAND_ON_5G, rf_type); + #endif } #endif - /* copy mac_addr to wiphy */ - _rtw_memcpy(wiphy->perm_addr, adapter_mac_addr(padapter), ETH_ALEN); + ret = _SUCCESS; +exit: + return ret; } +#if !defined(CONFIG_REGD_SRC_FROM_OS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) +void rtw_cfg80211_update_wiphy_max_txpower(_adapter *adapter, struct wiphy *wiphy) +{ + struct ieee80211_supported_band *band; + struct ieee80211_channel *channel; + s16 max_txpwr; + int i; + + if (IsSupported24G(adapter->registrypriv.wireless_mode)) { + band = wiphy->bands[NL80211_BAND_2GHZ]; + if (band) { + max_txpwr = phy_get_txpwr_by_rate_total_max_mbm(adapter, BAND_ON_2_4G, 1, 1); + if (max_txpwr != UNSPECIFIED_MBM) { + for (i = 0; i < band->n_channels; i++) { + channel = &band->channels[i]; + channel->max_power = max_txpwr / MBM_PDBM; + } + } + } + } +#if CONFIG_IEEE80211_BAND_5GHZ + if (is_supported_5g(adapter->registrypriv.wireless_mode)) { + band = wiphy->bands[NL80211_BAND_5GHZ]; + if (band) { + max_txpwr = phy_get_txpwr_by_rate_total_max_mbm(adapter, BAND_ON_5G, 1, 1); + if (max_txpwr != UNSPECIFIED_MBM) { + for (i = 0; i < band->n_channels; i++) { + channel = &band->channels[i]; + channel->max_power = max_txpwr / MBM_PDBM; + } + } + } + } +#endif +} +#endif /* defined(CONFIG_REGD_SRC_FROM_OS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) */ + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) && defined(RTW_SINGLE_WIPHY) && (CONFIG_IFACE_NUMBER >= 2) struct ieee80211_iface_limit rtw_limits[] = { { @@ -9819,10 +9934,14 @@ struct ieee80211_iface_combination rtw_combinations[] = { }; #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) */ -static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) +static int rtw_cfg80211_init_wiphy(_adapter *adapter, struct wiphy *wiphy) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); struct registry_priv *regsty = dvobj_to_regsty(dvobj); + int ret = _FAIL; + + /* copy mac_addr to wiphy */ + _rtw_memcpy(wiphy->perm_addr, adapter_mac_addr(adapter), ETH_ALEN); wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; @@ -9839,13 +9958,13 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) #endif wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) - | BIT(NL80211_IFTYPE_ADHOC) -#ifdef CONFIG_AP_MODE + #ifdef CONFIG_AP_MODE + | BIT(NL80211_IFTYPE_ADHOC) /* todo : AD-HOC task group will refine it */ | BIT(NL80211_IFTYPE_AP) + #endif #ifdef CONFIG_WIFI_MONITOR | BIT(NL80211_IFTYPE_MONITOR) #endif -#endif #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) | BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) @@ -9866,9 +9985,7 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) -#ifdef CONFIG_AP_MODE wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes; -#endif /* CONFIG_AP_MODE */ #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) @@ -9896,13 +10013,13 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) #endif } - if (IsSupported24G(adapter->registrypriv.wireless_mode)) - wiphy->bands[NL80211_BAND_2GHZ] = rtw_spt_band_alloc(BAND_ON_2_4G); - -#if CONFIG_IEEE80211_BAND_5GHZ - if (is_supported_5g(adapter->registrypriv.wireless_mode)) - wiphy->bands[NL80211_BAND_5GHZ] = rtw_spt_band_alloc(BAND_ON_5G); -#endif + if (rtw_cfg80211_init_wiphy_band(adapter, wiphy) != _SUCCESS) { + RTW_ERR("rtw_cfg80211_init_wiphy_band fail\n"); + goto exit; + } + #if !defined(CONFIG_REGD_SRC_FROM_OS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) + rtw_cfg80211_update_wiphy_max_txpower(adapter, wiphy); + #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)) wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS; @@ -9942,15 +10059,23 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) #endif /* CONFIG_TDLS_DRIVER_SETUP */ #endif /* CONFIG_TDLS */ - if (regsty->power_mgnt != PS_MODE_ACTIVE) +#ifdef CONFIG_LPS wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; - else +#else wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) /* wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; */ #endif +#ifdef CONFIG_RTW_WDS + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) + wiphy->flags |= WIPHY_FLAG_4ADDR_AP; + wiphy->flags |= WIPHY_FLAG_4ADDR_STATION; + #endif +#endif + #ifdef CONFIG_RTW_MESH wiphy->flags |= 0 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) @@ -9970,6 +10095,10 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) */ #endif /* CONFIG_RTW_MESH */ +#if defined(CONFIG_RTW_80211K) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)) + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_RRM); +#endif + #if (KERNEL_VERSION(3, 8, 0) <= LINUX_VERSION_CODE) wiphy->features |= NL80211_FEATURE_SAE; #endif @@ -9980,6 +10109,11 @@ static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; #endif #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) */ + + ret = _SUCCESS; + +exit: + return ret; } #ifdef CONFIG_RFKILL_POLL @@ -10026,53 +10160,7 @@ static void cfg80211_rtw_rfkill_poll(struct wiphy *wiphy) #define SURVEY_INFO_TIME_TX SURVEY_INFO_CHANNEL_TIME_TX #endif -#ifdef CONFIG_FIND_BEST_CHANNEL -static void rtw_cfg80211_set_survey_info_with_find_best_channel(struct wiphy *wiphy - , struct net_device *netdev, int idx, struct survey_info *info) -{ - _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev); - struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); - RT_CHANNEL_INFO *ch_set = rfctl->channel_set; - u8 ch_num = rfctl->max_chan_nums; - u32 total_rx_cnt = 0; - int i; - - s8 noise = -50; /*channel noise in dBm. This and all following fields are optional */ - u64 time = 100; /*amount of time in ms the radio was turn on (on the channel)*/ - u64 time_busy = 0; /*amount of time the primary channel was sensed busy*/ - - info->filled = SURVEY_INFO_NOISE_DBM - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) - | SURVEY_INFO_TIME | SURVEY_INFO_TIME_BUSY - #endif - ; - - for (i = 0; i < ch_num; i++) - total_rx_cnt += ch_set[i].rx_count; - - time_busy = ch_set[idx].rx_count * time / total_rx_cnt; - noise += ch_set[idx].rx_count * 50 / total_rx_cnt; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) - #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) - info->channel_time = time; - info->channel_time_busy = time_busy; - #else - info->time = time; - info->time_busy = time_busy; - #endif -#endif - info->noise = noise; - - /* reset if final channel is got */ - if (idx == ch_num - 1) { - for (i = 0; i < ch_num; i++) - ch_set[i].rx_count = 0; - } -} -#endif /* CONFIG_FIND_BEST_CHANNEL */ - -#if defined(CONFIG_RTW_ACS) && defined(CONFIG_BACKGROUND_NOISE_MONITOR) +#ifdef CONFIG_RTW_ACS static void rtw_cfg80211_set_survey_info_with_clm(PADAPTER padapter, int idx, struct survey_info *pinfo) { s8 noise = -50; /*channel noise in dBm. This and all following fields are optional */ @@ -10090,7 +10178,7 @@ static void rtw_cfg80211_set_survey_info_with_clm(PADAPTER padapter, int idx, st ; time_busy = rtw_acs_get_clm_ratio_by_ch_idx(padapter, chan); - noise = rtw_noise_query_by_chan_idx(padapter, chan); + noise = rtw_acs_get_nhm_noise_pwr_by_ch_idx(padapter, chan); /* RTW_INFO("%s: ch-idx:%d time=%llu(ms), time_busy=%llu(ms), noise=%d(dbm)\n", __func__, idx, time, time_busy, noise); */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) @@ -10104,9 +10192,9 @@ static void rtw_cfg80211_set_survey_info_with_clm(PADAPTER padapter, int idx, st #endif pinfo->noise = noise; } -#endif +#endif /* CONFIG_RTW_ACS */ -int rtw_hostapd_acs_dump_survey(struct wiphy *wiphy, struct net_device *netdev, int idx, struct survey_info *info) +static int rtw_hostapd_acs_dump_survey(struct wiphy *wiphy, struct net_device *netdev, int idx, struct survey_info *info) { PADAPTER padapter = (_adapter *)rtw_netdev_priv(netdev); struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); @@ -10141,19 +10229,18 @@ int rtw_hostapd_acs_dump_survey(struct wiphy *wiphy, struct net_device *netdev, if (info->channel->flags == IEEE80211_CHAN_DISABLED) return ret; -#ifdef CONFIG_FIND_BEST_CHANNEL - rtw_cfg80211_set_survey_info_with_find_best_channel(wiphy, netdev, idx, info); -#elif defined(CONFIG_RTW_ACS) && defined(CONFIG_BACKGROUND_NOISE_MONITOR) +#ifdef CONFIG_RTW_ACS rtw_cfg80211_set_survey_info_with_clm(padapter, idx, info); #else - RTW_ERR("%s: unknown acs operation!\n", __func__); + RTW_ERR("%s: unknown acs operation!\n", __func__); #endif return ret; } #endif /* defined(CONFIG_RTW_HOSTAPD_ACS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) */ -#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) \ + || defined(CONFIG_KERNEL_PATCH_EXTERNAL_AUTH) int cfg80211_rtw_external_auth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_external_auth_params *params) { @@ -10191,6 +10278,7 @@ void rtw_cfg80211_external_auth_status(struct wiphy *wiphy, struct net_device *d psta = rtw_get_stainfo(pstapriv, params->bssid); if (psta && (params->status == WLAN_STATUS_SUCCESS)) { +#ifdef CONFIG_AP_MODE /* AP mode */ RTW_INFO("station match\n"); @@ -10235,6 +10323,7 @@ void rtw_cfg80211_external_auth_status(struct wiphy *wiphy, struct net_device *d buf = NULL; len = 0; } +#endif } else { /* STA mode */ psecuritypriv->extauth_status = params->status; @@ -10255,6 +10344,10 @@ static struct cfg80211_ops rtw_cfg80211_ops = { #endif /*CONFIG_GTK_OL*/ .get_station = cfg80211_rtw_get_station, .scan = cfg80211_rtw_scan, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) && \ + defined(CONFIG_RTW_ABORT_SCAN) + .abort_scan = cfg80211_rtw_abort_scan, +#endif .set_wiphy_params = cfg80211_rtw_set_wiphy_params, .connect = cfg80211_rtw_connect, .disconnect = cfg80211_rtw_disconnect, @@ -10269,10 +10362,10 @@ static struct cfg80211_ops rtw_cfg80211_ops = { .del_pmksa = cfg80211_rtw_del_pmksa, .flush_pmksa = cfg80211_rtw_flush_pmksa, -#ifdef CONFIG_AP_MODE .add_virtual_intf = cfg80211_rtw_add_virtual_intf, .del_virtual_intf = cfg80211_rtw_del_virtual_intf, +#ifdef CONFIG_AP_MODE #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE) .add_beacon = cfg80211_rtw_add_beacon, .set_beacon = cfg80211_rtw_set_beacon, @@ -10327,14 +10420,13 @@ static struct cfg80211_ops rtw_cfg80211_ops = { .get_channel = cfg80211_rtw_get_channel, #endif -#ifdef CONFIG_P2P .remain_on_channel = cfg80211_rtw_remain_on_channel, .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel, - #if defined(RTW_DEDICATED_P2P_DEVICE) + +#if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE) .start_p2p_device = cfg80211_rtw_start_p2p_device, .stop_p2p_device = cfg80211_rtw_stop_p2p_device, - #endif -#endif /* CONFIG_P2P */ +#endif #ifdef CONFIG_RTW_80211R .update_ft_ies = cfg80211_rtw_update_ft_ies, @@ -10342,7 +10434,11 @@ static struct cfg80211_ops rtw_cfg80211_ops = { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) .mgmt_tx = cfg80211_rtw_mgmt_tx, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, +#else + .update_mgmt_frame_registrations = cfg80211_rtw_update_mgmt_frame_register, +#endif #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) .action = cfg80211_rtw_mgmt_tx, #endif @@ -10364,7 +10460,8 @@ static struct cfg80211_ops rtw_cfg80211_ops = { #if defined(CONFIG_RTW_HOSTAPD_ACS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) .dump_survey = rtw_hostapd_acs_dump_survey, #endif -#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) +#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE) \ + || defined(CONFIG_KERNEL_PATCH_EXTERNAL_AUTH) .external_auth = cfg80211_rtw_external_auth, #endif }; @@ -10377,7 +10474,7 @@ struct wiphy *rtw_wiphy_alloc(_adapter *padapter, struct device *dev) /* wiphy */ wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wiphy_data)); if (!wiphy) { - RTW_INFO("Couldn't allocate wiphy device\n"); + RTW_ERR("Couldn't allocate wiphy device\n"); goto exit; } set_wiphy_dev(wiphy, dev); @@ -10391,7 +10488,11 @@ struct wiphy *rtw_wiphy_alloc(_adapter *padapter, struct device *dev) wiphy_data->txpwr_total_lmt_mbm = UNSPECIFIED_MBM; wiphy_data->txpwr_total_target_mbm = UNSPECIFIED_MBM; - rtw_cfg80211_preinit_wiphy(padapter, wiphy); + if (rtw_cfg80211_init_wiphy(padapter, wiphy) != _SUCCESS) { + rtw_wiphy_free(wiphy); + wiphy = NULL; + goto exit; + } RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy)); @@ -10422,7 +10523,8 @@ int rtw_wiphy_register(struct wiphy *wiphy) { RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy)); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT) +#if ( (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) \ + || defined(RTW_VENDOR_EXT_SUPPORT) ) rtw_cfgvendor_attach(wiphy); #endif @@ -10435,7 +10537,8 @@ void rtw_wiphy_unregister(struct wiphy *wiphy) { RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy)); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT) +#if ( (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) \ + || defined(RTW_VENDOR_EXT_SUPPORT) ) rtw_cfgvendor_detach(wiphy); #endif @@ -10487,11 +10590,6 @@ int rtw_wdev_alloc(_adapter *padapter, struct wiphy *wiphy) pwdev_priv->bandroid_scan = _FALSE; - if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE) - pwdev_priv->power_mgmt = _TRUE; - else - pwdev_priv->power_mgmt = _FALSE; - _rtw_mutex_init(&pwdev_priv->roch_mutex); #ifdef CONFIG_CONCURRENT_MODE @@ -10607,6 +10705,7 @@ void rtw_cfg80211_ndev_res_free(_adapter *adapter) #endif } + int rtw_cfg80211_ndev_res_register(_adapter *adapter) { #if !defined(RTW_SINGLE_WIPHY) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_cfg80211.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_cfg80211.h index e0c30c33c2ce..7e32d47afae1 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_cfg80211.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_cfg80211.h @@ -167,10 +167,15 @@ struct rtw_wdev_priv { u8 bandroid_scan; bool block; bool block_scan; - bool power_mgmt; - /* report mgmt_frame registered */ - u16 report_mgmt; + /** + * mgmt_regs: bitmap of management frame subtypes registered for the + * given interface + * mcast_mgmt_regs: mcast RX is needed on this interface for these + * subtypes + */ + u32 mgmt_regs; + /* u32 mcast_mgmt_regs; */ u8 is_mgmt_tx; u16 mgmt_tx_cookie; @@ -241,8 +246,8 @@ struct rtw_wiphy_data { struct wireless_dev *pd_wdev; /* P2P device wdev */ #endif - s16 txpwr_total_lmt_mbm; - s16 txpwr_total_target_mbm; + s16 txpwr_total_lmt_mbm; /* EIRP */ + s16 txpwr_total_target_mbm; /* EIRP */ }; #define rtw_wiphy_priv(wiphy) ((struct rtw_wiphy_data *)wiphy_priv(wiphy)) @@ -264,9 +269,13 @@ struct rtw_wiphy_data { #define FUNC_WIPHY_FMT "%s("WIPHY_FMT")" #define FUNC_WIPHY_ARG(wiphy) __func__, WIPHY_ARG(wiphy) -#define SET_CFG80211_REPORT_MGMT(w, t, v) (w->report_mgmt |= BIT(t >> 4)) -#define CLR_CFG80211_REPORT_MGMT(w, t, v) (w->report_mgmt &= (~BIT(t >> 4))) -#define GET_CFG80211_REPORT_MGMT(w, t) ((w->report_mgmt & BIT(t >> 4)) > 0) +#define SET_CFG80211_MGMT_REGS(w, t) (w |= BIT(t >> 4)) +#define CLR_CFG80211_MGMT_REGS(w, t) (w &= (~BIT(t >> 4))) +#define GET_CFG80211_MGMT_REGS(w, t) ((w & BIT(t >> 4)) > 0) + +#define SET_CFG80211_REPORT_MGMT(w, t) (SET_CFG80211_MGMT_REGS(w->mgmt_regs, t)) +#define CLR_CFG80211_REPORT_MGMT(w, t) (CLR_CFG80211_MGMT_REGS(w->mgmt_regs, t)) +#define GET_CFG80211_REPORT_MGMT(w, t) (GET_CFG80211_MGMT_REGS(w->mgmt_regs, t)) struct wiphy *rtw_wiphy_alloc(_adapter *padapter, struct device *dev); void rtw_wiphy_free(struct wiphy *wiphy); @@ -290,7 +299,6 @@ s16 rtw_cfg80211_dev_get_total_txpwr_lmt_mbm(struct dvobj_priv *dvobj); s16 rtw_cfg80211_dev_get_total_txpwr_target_mbm(struct dvobj_priv *dvobj); void rtw_cfg80211_init_wdev_data(_adapter *padapter); -void rtw_cfg80211_init_wiphy(_adapter *padapter); void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork); void rtw_cfg80211_surveydone_event_callback(_adapter *padapter); @@ -310,15 +318,16 @@ void rtw_cfg80211_indicate_scan_done_for_buddy(_adapter *padapter, bool bscan_ab #ifdef CONFIG_AP_MODE void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len); void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, const u8 *da, unsigned short reason); +int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len, int type); #endif /* CONFIG_AP_MODE */ -#ifdef CONFIG_P2P void rtw_cfg80211_set_is_roch(_adapter *adapter, bool val); bool rtw_cfg80211_get_is_roch(_adapter *adapter); bool rtw_cfg80211_is_ro_ch_once(_adapter *adapter); void rtw_cfg80211_set_last_ro_ch_time(_adapter *adapter); s32 rtw_cfg80211_get_last_ro_ch_passing_ms(_adapter *adapter); +#ifdef CONFIG_P2P int rtw_cfg80211_iface_has_p2p_group_cap(_adapter *adapter); int rtw_cfg80211_is_p2p_scan(_adapter *adapter); #if defined(RTW_DEDICATED_P2P_DEVICE) @@ -345,8 +354,6 @@ void rtw_cfg80211_external_auth_request(_adapter *padapter, union recv_frame *rf void rtw_cfg80211_external_auth_status(struct wiphy *wiphy, struct net_device *dev, struct rtw_external_auth_params *params); -int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len, int type); - bool rtw_cfg80211_pwr_mgmt(_adapter *adapter); #ifdef CONFIG_RTW_80211K void rtw_cfg80211_rx_rrm_action(_adapter *adapter, union recv_frame *rframe); @@ -415,7 +422,12 @@ void rtw_cfg80211_deinit_rfkill(struct wiphy *wiphy); #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) -u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, u8 ht); +u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, u8 ht, bool started); +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) +#define IEEE80211_CHAN_NO_HT40PLUS IEEE80211_CHAN_NO_FAT_ABOVE +#define IEEE80211_CHAN_NO_HT40MINUS IEEE80211_CHAN_NO_FAT_BELOW #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0)) @@ -437,6 +449,7 @@ u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset, u8 #define NL80211_TX_POWER_FIXED TX_POWER_FIXED #endif +#include "wifi_regd.h" #include "rtw_cfgvendor.h" #endif /* __IOCTL_CFG80211_H__ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_linux.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_linux.c index 5cfbf7da84af..2e07282f64fa 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_linux.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_linux.c @@ -32,6 +32,7 @@ extern int rtw_ht_enable; #endif + #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV+30) #define SCAN_ITEM_SIZE 768 @@ -65,32 +66,6 @@ extern u8 convert_ip_addr(u8 hch, u8 mch, u8 lch); u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000, 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000}; -/** - * hwaddr_aton - Convert ASCII string to MAC address - * @txt: MAC address as a string (e.g., "00:11:22:33:44:55") - * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) - * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) - */ -static int hwaddr_aton_i(const char *txt, u8 *addr) -{ - int i; - - for (i = 0; i < 6; i++) { - int a, b; - - a = hex2num_i(*txt++); - if (a < 0) - return -1; - b = hex2num_i(*txt++); - if (b < 0) - return -1; - *addr++ = (a << 4) | b; - if (i < 5 && *txt++ != ':') - return -1; - } - - return 0; -} #ifdef CONFIG_RTW_ANDROID static void indicate_wx_custom_event(_adapter *padapter, char *msg) { @@ -263,6 +238,7 @@ uint rtw_is_cckratesonly_included(u8 *rate) } */ +#ifdef CONFIG_IOCTL_WEXT static int search_p2p_wfd_ie(_adapter *padapter, struct iw_request_info *info, struct wlan_network *pnetwork, char *start, char *stop) @@ -1177,6 +1153,12 @@ static int rtw_set_wpa_ie(_adapter *padapter, char *pie, unsigned short ielen) } } } + + #ifdef CONFIG_RTW_MULTI_AP + padapter->multi_ap = rtw_get_multi_ap_ie_ext(buf, ielen) & MULTI_AP_BACKHAUL_STA; + if (padapter->multi_ap) + adapter_set_use_wds(padapter, 1); + #endif } /* TKIP and AES disallow multicast packets until installing group key */ @@ -2265,7 +2247,7 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, && rtw_mlme_band_check(padapter, ch) == _TRUE && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid)) && (!IS_DFS_SLAVE_WITH_RD(rfctl) - || rtw_odm_dfs_domain_unknown(rfctl_to_dvobj(rfctl)) + || rtw_rfctl_dfs_domain_unknown(rfctl) || !rtw_chset_is_ch_non_ocp(chset, ch)) ) ev = translate_scan(padapter, a, pnetwork, ev, stop); @@ -3260,6 +3242,7 @@ static int rtw_wx_get_nick(struct net_device *dev, return 0; } +#endif static int rtw_wx_read32(struct net_device *dev, struct iw_request_info *info, @@ -3434,6 +3417,7 @@ static int rtw_wx_priv_rrm(struct net_device *dev, struct iw_request_info *a, } #endif +#ifdef CONFIG_IOCTL_WEXT static int dummy(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { @@ -3445,6 +3429,7 @@ static int dummy(struct net_device *dev, struct iw_request_info *a, return -1; } +#endif static int rtw_wx_set_channel_plan(struct net_device *dev, struct iw_request_info *info, @@ -3761,7 +3746,6 @@ static int rtw_get_ap_info(struct net_device *dev, pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); - /* if(hwaddr_aton_i(pdata->pointer, bssid)) */ if (hwaddr_aton_i(data, bssid)) { RTW_INFO("Invalid BSSID '%s'.\n", (u8 *)data); _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); @@ -3882,6 +3866,9 @@ static int rtw_wext_p2p_enable(struct net_device *dev, struct wifidirect_info *pwdinfo = &(padapter->wdinfo); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; enum P2P_ROLE init_role = P2P_ROLE_DISABLE; +#ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#endif if (*extra == '0') init_role = P2P_ROLE_DISABLE; @@ -3912,7 +3899,7 @@ static int rtw_wext_p2p_enable(struct net_device *dev, #ifdef CONFIG_CONCURRENT_MODE else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) { - _set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval); + _set_timer(&prochinfo->ap_roch_ch_switch_timer, pwdinfo->ext_listen_interval); channel = rtw_mi_get_union_chan(padapter); ch_offset = rtw_mi_get_union_offset(padapter); @@ -4735,6 +4722,9 @@ static int rtw_p2p_connect(struct net_device *dev, _queue *queue = &(pmlmepriv->scanned_queue); struct wlan_network *pnetwork = NULL; uint uintPeerChannel = 0; +#ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#endif /* Commented by Albert 20110304 */ /* The input data contains two informations. */ @@ -4788,7 +4778,7 @@ static int rtw_p2p_connect(struct net_device *dev, if (uintPeerChannel) { #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_check_status(padapter, MI_LINKED)) - _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer); + _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer); #endif /* CONFIG_CONCURRENT_MODE */ _rtw_memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info)); @@ -4856,6 +4846,9 @@ static int rtw_p2p_invite_req(struct net_device *dev, uint p2pielen = 0, attr_contentlen = 0; _irqL irqL; struct tx_invite_req_info *pinvite_req_info = &pwdinfo->invitereq_info; +#ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#endif /* Commented by Albert 20120321 */ /* The input data contains two informations. */ @@ -4967,7 +4960,7 @@ static int rtw_p2p_invite_req(struct net_device *dev, if (uintPeerChannel) { #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_check_status(padapter, MI_LINKED)) - _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer); + _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer); #endif /* CONFIG_CONCURRENT_MODE */ /* Store the GO's bssid */ @@ -5337,6 +5330,9 @@ static int rtw_p2p_prov_disc(struct net_device *dev, u8 *p2pie; uint p2pielen = 0, attr_contentlen = 0; _irqL irqL; +#ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; +#endif /* Commented by Albert 20110301 */ /* The input data contains two informations. */ @@ -5466,7 +5462,7 @@ static int rtw_p2p_prov_disc(struct net_device *dev, RTW_INFO("[%s] peer channel: %d!\n", __FUNCTION__, uintPeerChannel); #ifdef CONFIG_CONCURRENT_MODE if (rtw_mi_check_status(padapter, MI_LINKED)) - _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer); + _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer); #endif /* CONFIG_CONCURRENT_MODE */ _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN); _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN); @@ -5759,68 +5755,6 @@ static int rtw_cta_test_start(struct net_device *dev, return ret; } #endif -extern int rtw_change_ifname(_adapter *padapter, const char *ifname); -static int rtw_rereg_nd_name(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - _adapter *padapter = rtw_netdev_priv(dev); - struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); - struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv; - char new_ifname[IFNAMSIZ]; - - if (rereg_priv->old_ifname[0] == 0) { - char *reg_ifname; -#ifdef CONFIG_CONCURRENT_MODE - if (padapter->isprimary) - reg_ifname = padapter->registrypriv.ifname; - else -#endif - reg_ifname = padapter->registrypriv.if2name; - - strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ); - rereg_priv->old_ifname[IFNAMSIZ - 1] = 0; - } - - /* RTW_INFO("%s wrqu->data.length:%d\n", __FUNCTION__, wrqu->data.length); */ - if (wrqu->data.length > IFNAMSIZ) - return -EFAULT; - - if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ)) - return -EFAULT; - - if (0 == strcmp(rereg_priv->old_ifname, new_ifname)) - return ret; - - RTW_INFO("%s new_ifname:%s\n", __FUNCTION__, new_ifname); - rtw_set_rtnl_lock_holder(dvobj, current); - ret = rtw_change_ifname(padapter, new_ifname); - rtw_set_rtnl_lock_holder(dvobj, NULL); - if (0 != ret) - goto exit; - - if (_rtw_memcmp(rereg_priv->old_ifname, "disable%d", 9) == _TRUE) { - /* rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode); */ - } - - strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ); - rereg_priv->old_ifname[IFNAMSIZ - 1] = 0; - - if (_rtw_memcmp(new_ifname, "disable%d", 9) == _TRUE) { - - RTW_INFO("%s disable\n", __FUNCTION__); - /* free network queue for Android's timming issue */ - rtw_free_network_queue(padapter, _TRUE); - - /* the interface is being "disabled", we can do deeper IPS */ - /* rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv); */ - /* rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL); */ - } -exit: - return ret; - -} #ifdef CONFIG_IOL #include @@ -5836,8 +5770,9 @@ static int rtw_dbg_port(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - _irqL irqL; int ret = 0; +#ifdef CONFIG_RTW_DEBUG + _irqL irqL; u8 major_cmd, minor_cmd; u16 arg; u32 extra_arg, *pdata, val32; @@ -6657,11 +6592,12 @@ static int rtw_dbg_port(struct net_device *dev, break; } - +#endif return ret; } +#ifdef CONFIG_IOCTL_WEXT static int wpa_set_param(struct net_device *dev, u8 name, u32 value) { uint ret = 0; @@ -7798,7 +7734,7 @@ out: return ret; } -#endif +#endif /* CONFIG_AP_MODE */ static int rtw_wx_set_priv(struct net_device *dev, struct iw_request_info *info, @@ -7969,6 +7905,8 @@ FREE_EXT: return ret; } +#endif /*CONFIG_IOCTL_WEXT*/ + #ifdef CONFIG_WOWLAN static int rtw_wowlan_ctrl(struct net_device *dev, struct iw_request_info *info, @@ -8050,7 +7988,7 @@ static int rtw_wowlan_set_pattern(struct net_device *dev, struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wowlan_ioctl_param poidparam; int ret = 0; - u8 input[wrqu->data.length]; + u8 input[MAX_IN_PATTERN_SIZE]; u8 index = 0; poidparam.subcode = 0; @@ -8062,9 +8000,9 @@ static int rtw_wowlan_set_pattern(struct net_device *dev, goto _rtw_wowlan_set_pattern_exit; } - if (wrqu->data.length <= 0) { + if ((wrqu->data.length <= 0) || (wrqu->data.length > MAX_IN_PATTERN_SIZE)) { ret = -EFAULT; - RTW_INFO("ERROR: parameter length <= 0\n"); + RTW_INFO("ERROR: parameter length error, len=%d\n", wrqu->data.length); goto _rtw_wowlan_set_pattern_exit; } else { /* set pattern */ @@ -8074,7 +8012,7 @@ static int rtw_wowlan_set_pattern(struct net_device *dev, /* leave PS first */ rtw_ps_deny(padapter, PS_DENY_IOCTL); LeaveAllPowerSaveModeDirect(padapter); - if (strncmp(input, "pattern=", 8) == 0) { + if ((strncmp(input, "pattern=", 8) == 0) ||(strncmp(input, "ack_pattern=", 12) == 0)) { if (pwrpriv->wowlan_pattern_idx >= MAX_WKFM_CAM_NUM) { RTW_INFO("WARNING: priv-pattern is full(idx: %d)\n", pwrpriv->wowlan_pattern_idx); @@ -8088,11 +8026,25 @@ static int rtw_wowlan_set_pattern(struct net_device *dev, &pwrpriv->patterns[index].len, pwrpriv->patterns[index].mask); - if (ret == _TRUE) + if (ret == _TRUE) { + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + if(strncmp(input, "ack_pattern=", 12) == 0) + pwrpriv->wowlan_keep_alive_ack_index = index; + else + pwrpriv->wowlan_wake_pattern_index = index; + RTW_INFO("pwrpriv->wowlan_keep_alive_ack_index =%d\n",pwrpriv->wowlan_keep_alive_ack_index); + RTW_INFO("pwrpriv->wowlan_wake_pattern_index =%d\n",pwrpriv->wowlan_wake_pattern_index); + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ pwrpriv->wowlan_pattern_idx++; + } } } else if (strncmp(input, "clean", 5) == 0) { poidparam.subcode = WOWLAN_PATTERN_CLEAN; + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + pwrpriv->wowlan_wake_pattern_index = 0xFF; + pwrpriv->wowlan_keep_alive_ack_index = 0xFF; + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + rtw_hal_set_hwreg(padapter, HW_VAR_WOWLAN, (u8 *)&poidparam); } else if (strncmp(input, "show", 4) == 0) { @@ -8107,6 +8059,105 @@ static int rtw_wowlan_set_pattern(struct net_device *dev, _rtw_wowlan_set_pattern_exit: return ret; } + +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN +static int rtw_wowlan_set_keep_alive_pattern(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + + int ret = 0,totoal_len=0,i=0,len=0; + char *cp = NULL; + u32 mode = 0xFF; /*para1*/ + u16 period = 15*10; /* para2;units:100ms,default 15s*/ + char tx_pattern[512]; /*para3*/ + u32 retry_intervel = 2*10; /* para4;units:100ms,default 2s*/ + u32 retry_limit_count = 5; /*para5*/ + + ret = sscanf(extra, "%d %hu %s %d %d", &mode , &period, tx_pattern, &retry_intervel, &retry_limit_count); + pwrpriv->wowlan_keep_alive_mode = mode; + + RTW_INFO("[%s] ret =%d \n", __func__ ,ret); + totoal_len = strlen(tx_pattern); + RTW_INFO("[%s] totoal_len=%d \n", __func__ ,totoal_len); + + if (mode && (ret < 3)) + return -EINVAL; + + if (((mode ==2) ||(mode ==3)) && ((retry_intervel*retry_limit_count) > period)) { + RTW_INFO("[%s] retry_intervel*retry_limit_count need smaller than period\n", __func__ ); + return -EINVAL; + } + + switch(mode){ + case wow_keep_alive_pattern_disable: + /*disable this feature*/ + pwrpriv->keep_alive_pattern_loc = 0; + pwrpriv->keep_alive_pattern_len = 0; + pwrpriv->wowlan_keep_alive_period = 0; + pwrpriv->wowlan_keep_alive_ack_index = 0xFF; + pwrpriv->wowlan_wake_pattern_index = 0xFF; + pwrpriv->wowlan_keep_alive_retry_interval = 0; + pwrpriv->wowlan_keep_alive_retry_counter = 0; + _rtw_memset(pwrpriv->keep_alive_pattern,0,WLAN_MAX_KEEP_ALIVE_IE_LEN); + RTW_INFO("[%s] clear pattern \n", __func__ ); + ret = _SUCCESS; + break; + case wow_keep_alive_pattern_tx: + /*only tx udp packet*/ + pwrpriv->wowlan_keep_alive_period = period; + pwrpriv->wowlan_keep_alive_retry_interval = 0; + pwrpriv->wowlan_keep_alive_retry_counter = 0; + RTW_INFO("[%s] wow_keep_alive_pattern_tx \n", __func__ ); + break; + case wow_keep_alive_pattern_trx: + /*trx+no need wakeup*/ + pwrpriv->wowlan_keep_alive_period = period; + pwrpriv->wowlan_keep_alive_retry_interval = retry_intervel; + pwrpriv->wowlan_keep_alive_retry_counter = retry_limit_count; + RTW_INFO("[%s] wow_keep_alive_pattern_trx \n", __func__ ); + break; + case wow_keep_alive_pattern_trx_with_ack: + /*trx+need wakeup*/ + pwrpriv->wowlan_keep_alive_period = period; + pwrpriv->wowlan_keep_alive_retry_interval = retry_intervel; + pwrpriv->wowlan_keep_alive_retry_counter = retry_limit_count; + RTW_INFO("[%s] wow_keep_alive_pattern_trx_with_ack \n", __func__ ); + break; + default: + RTW_INFO("[%s] please setting valid mode \n", __func__ ); + ret = -EINVAL; + break; + + } + + if((mode == 0) || (mode > 4)) + return ret; + + totoal_len = strlen(tx_pattern); + RTW_INFO("[%s] totoal_len=%d \n", __func__ ,totoal_len); + if (totoal_len > WLAN_MAX_KEEP_ALIVE_IE_LEN*2) { + RTW_INFO("[%s] Fail , not support ie length extend %d\n", __func__ , WLAN_MAX_KEEP_ALIVE_IE_LEN); + return -EFAULT; + } + RTW_INFO("[%s] period = %hu ,ie = %s , len = %d\n", __func__ , period , tx_pattern , totoal_len); + + + if (totoal_len > 0) { + RTW_INFO("[%s] pwrpriv->keep_alive_pattern==========> \n", __func__ ); + for (i = 0 ; i keep_alive_pattern[len] = key_2char2num(tx_pattern[i], tx_pattern[i + 1]); + RTW_INFO("[0x%x] ",pwrpriv->keep_alive_pattern[len]); + len++; + } + RTW_INFO(" \n" ); + pwrpriv->keep_alive_pattern_len = len; + } + + return ret; +} +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + #endif /* CONFIG_WOWLAN */ #ifdef CONFIG_AP_WOWLAN @@ -9819,7 +9870,8 @@ static int rtw_mp_efuse_set(struct net_device *dev, RTW_INFO("%s: MAC address=%s\n", __FUNCTION__, tmp[1]); for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) - pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]); + if ((addr + jj) < EFUSE_MAX_MAP_LEN) + pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]); _rtw_memset(extra, '\0', strlen(extra)); sprintf(extra, "write mac addr to fake map OK\n"); @@ -9830,11 +9882,10 @@ static int rtw_mp_efuse_set(struct net_device *dev, strcpy(pmp_priv->efuse_file_path , tmp[1]); RTW_INFO("Got file path %s\n", pmp_priv->efuse_file_path); } - /*step read efuse/eeprom data and get mac_addr*/ if (padapter->hal_func.read_adapter_info(padapter)) { - _rtw_memset(extra, '\0', strlen(extra)); - sprintf(extra, "eFuse Update OK\n"); + _rtw_memset(extra, '\0', strlen(extra)); + sprintf(extra, "eFuse Update OK\n"); RTW_INFO("eFuse Update OK\n"); } else { _rtw_memset(extra, '\0', strlen(extra)); @@ -9843,7 +9894,6 @@ static int rtw_mp_efuse_set(struct net_device *dev, } pmp_priv->efuse_update_file = _FALSE; RTW_INFO("To Use new eFuse map done ver3\n"); - } else if (strcmp(tmp[0], "analyze") == 0) { rtw_efuse_analyze(padapter, EFUSE_WIFI, 0); @@ -10419,6 +10469,13 @@ static int rtw_priv_set(struct net_device *dev, RTW_INFO("set case MP_WOW_SET_PATTERN: %s\n", extra); rtw_wowlan_set_pattern(dev, info, wdata, extra); break; + #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + case MP_WOW_SET_KEEP_ALIVE_PATTERN: + RTW_INFO("set case MP_WOW_SET_KEEP_ALIVE_PATTERN: %s\n", extra); + rtw_wowlan_set_keep_alive_pattern(dev, info, wdata, extra); + break; + #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + #endif #ifdef CONFIG_AP_WOWLAN case MP_AP_WOW_ENABLE: @@ -10453,8 +10510,6 @@ static int rtw_priv_get(struct net_device *dev, struct dm_iqk_info *p_iqk_info = &p_dm->IQK_info; u32 i = 100; - if (padapter == NULL) - return -ENETDOWN; if (padapter->bup == _FALSE) { RTW_INFO(" %s fail =>(padapter->bup == _FALSE )\n", __FUNCTION__); @@ -10734,6 +10789,9 @@ static int rtw_tdls_ch_switch(struct net_device *dev, rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk); if (take_care_iqk == _TRUE) { +#ifdef CONFIG_TDLS_CH_SW_V2 + rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_PREPARE); +#else u8 central_chnl; u8 bw_mode; @@ -10743,6 +10801,7 @@ static int rtw_tdls_ch_switch(struct net_device *dev, rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START); else rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_PREPARE); +#endif } else rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START); @@ -11366,7 +11425,7 @@ static int rtw_tdls_get(struct net_device *dev, #if defined(CONFIG_RTL8188E) #include extern void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc); -#define cal_txdesc_chksum rtl8188e_cal_txdesc_chksum +#define cal_txdesc_chksum(padapter, desc) rtl8188e_cal_txdesc_chksum(desc) #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI) extern void rtl8188es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); #define fill_default_txdesc rtl8188es_fill_default_txdesc @@ -11374,33 +11433,33 @@ extern void rtl8188es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbu #endif /* CONFIG_RTL8188E */ #if defined(CONFIG_RTL8723B) extern void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc); -#define cal_txdesc_chksum rtl8723b_cal_txdesc_chksum +#define cal_txdesc_chksum(padapter, desc) rtl8723b_cal_txdesc_chksum(desc) extern void rtl8723b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); #define fill_default_txdesc rtl8723b_fill_default_txdesc #endif /* CONFIG_RTL8723B */ #if defined(CONFIG_RTL8703B) /* extern void rtl8703b_cal_txdesc_chksum(struct tx_desc *ptxdesc); */ -#define cal_txdesc_chksum rtl8703b_cal_txdesc_chksum +#define cal_txdesc_chksum(padapter, desc) rtl8703b_cal_txdesc_chksum(desc) /* extern void rtl8703b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */ #define fill_default_txdesc rtl8703b_fill_default_txdesc #endif /* CONFIG_RTL8703B */ #if defined(CONFIG_RTL8723D) /* extern void rtl8723d_cal_txdesc_chksum(struct tx_desc *ptxdesc); */ -#define cal_txdesc_chksum rtl8723d_cal_txdesc_chksum +#define cal_txdesc_chksum(padapter, desc) rtl8723d_cal_txdesc_chksum(desc) /* extern void rtl8723d_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */ #define fill_default_txdesc rtl8723d_fill_default_txdesc #endif /* CONFIG_RTL8723D */ #if defined(CONFIG_RTL8710B) -#define cal_txdesc_chksum rtl8710b_cal_txdesc_chksum +#define cal_txdesc_chksum(padapter, desc) rtl8710b_cal_txdesc_chksum(desc) #define fill_default_txdesc rtl8710b_fill_default_txdesc #endif /* CONFIG_RTL8710B */ #if defined(CONFIG_RTL8192E) extern void rtl8192e_cal_txdesc_chksum(struct tx_desc *ptxdesc); -#define cal_txdesc_chksum rtl8192e_cal_txdesc_chksum +#define cal_txdesc_chksum(padapter, desc) rtl8192e_cal_txdesc_chksum(desc) #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI) extern void rtl8192es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); #define fill_default_txdesc rtl8192es_fill_default_txdesc @@ -11409,16 +11468,46 @@ extern void rtl8192es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbu #if defined(CONFIG_RTL8192F) /* extern void rtl8192f_cal_txdesc_chksum(struct tx_desc *ptxdesc); */ -#define cal_txdesc_chksum rtl8192f_cal_txdesc_chksum +#define cal_txdesc_chksum(padapter, desc) rtl8192f_cal_txdesc_chksum(desc) /* extern void rtl8192f_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */ #define fill_default_txdesc rtl8192f_fill_default_txdesc #endif /* CONFIG_RTL8192F */ +#ifdef CONFIG_RTL8723F +#include <../../hal/rtl8723f/rtl8723f.h> + +#define REG_LOOPBACK_ENABLE 0x0103 +#define LOOKBACK_ENABLE_VALUE 0x0b +#define cal_txdesc_chksum(padapter, desc) rtl8723f_cal_txdesc_chksum(padapter, desc) +#define dump_txdesc_data(padapter, desc) rtl8723f_dbg_dump_tx_desc(padapter, DATA_FRAMETAG, desc); +#define get_rx_desc(rx_desc, rxbuf) rtl8723f_rxdesc2attribute(rx_desc, rxbuf) +#define hal_init rtl8723f_hal_init +#endif /* CONFIG_RTL8723F */ + +void dbg_dump_pkt(char *s, u8 *buf, u8 len) +{ + u8 i, j = 1; + + RTW_INFO("%s size = %u\n", s, len); + + for (i = 0; (i + 4) < len; i += 4) { + if (j % 4 == 1) + RTW_PRINT("idx:%u:", i); + _RTW_PRINT(" 0x%02x 0x%02x 0x%02x 0x%02x", buf[i], buf[i+1], buf[i+2], buf[i+3]); + if ((j++) % 4 == 0) + _RTW_PRINT("\n"); + } + + for (; i < len ; i++) { + _RTW_PRINT(" 0x%02x", buf[i]); + } + _RTW_PRINT("\n ================================\n"); +} + static s32 initLoopback(PADAPTER padapter) { PLOOPBACKDATA ploopback; - if (padapter->ploopback == NULL) { ploopback = (PLOOPBACKDATA)rtw_zmalloc(sizeof(LOOPBACKDATA)); if (ploopback == NULL) @@ -11440,7 +11529,6 @@ static void freeLoopback(PADAPTER padapter) { PLOOPBACKDATA ploopback; - ploopback = padapter->ploopback; if (ploopback) { rtw_mfree((u8 *)ploopback, sizeof(LOOPBACKDATA)); @@ -11476,7 +11564,6 @@ static s32 createpseudoadhoc(PADAPTER padapter) s32 err; _irqL irqL; - pmlmepriv = &padapter->mlmepriv; authmode = Ndis802_11AuthModeOpen; @@ -11558,7 +11645,7 @@ static struct xmit_frame *createloopbackpkt(PADAPTER padapter, u32 size) pframe = NULL; /* 2 1. allocate xmit frame */ - pframe = rtw_alloc_xmitframe(pxmitpriv); + pframe = rtw_alloc_xmitframe(pxmitpriv, 0); if (pframe == NULL) return NULL; pframe->padapter = padapter; @@ -11618,6 +11705,7 @@ static struct xmit_frame *createloopbackpkt(PADAPTER padapter, u32 size) fill_default_txdesc(pframe, (u8 *)desc); +#if 0 /* Hw set sequence number */ ((PTXDESC)desc)->hwseq_en = 0; /* HWSEQ_EN, 0:disable, 1:enable * ((PTXDESC)desc)->hwseq_sel = 0; */ /* HWSEQ_SEL */ @@ -11642,9 +11730,11 @@ static struct xmit_frame *createloopbackpkt(PADAPTER padapter, u32 size) desc->txdw13 = cpu_to_le32(desc->txdw13); desc->txdw14 = cpu_to_le32(desc->txdw14); desc->txdw15 = cpu_to_le32(desc->txdw15); +#endif #endif - cal_txdesc_chksum(desc); + cal_txdesc_chksum(padapter, (u8*)desc); + /* dump_txdesc_data(padapter, (u8*)desc); */ /* 2 5. coalesce */ pkt_start = pframe->buf_addr + TXDESC_SIZE; @@ -11662,7 +11752,11 @@ static struct xmit_frame *createloopbackpkt(PADAPTER padapter, u32 size) get_random_bytes(ptr, pkt_end - ptr); pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz; +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) pxmitbuf->ptail += pxmitbuf->len; +#endif + + dbg_dump_pkt("TX packet", pxmitbuf->pbuf, pxmitbuf->len); return pframe; } @@ -11672,7 +11766,6 @@ static void freeloopbackpkt(PADAPTER padapter, struct xmit_frame *pframe) struct xmit_priv *pxmitpriv; struct xmit_buf *pxmitbuf; - pxmitpriv = &padapter->xmitpriv; pxmitbuf = pframe->pxmitbuf; @@ -11684,7 +11777,6 @@ static void printdata(u8 *pbuf, u32 len) { u32 i, val; - for (i = 0; (i + 4) <= len; i += 4) { printk("%08X", *(u32 *)(pbuf + i)); if ((i + 4) & 0x1F) @@ -11719,15 +11811,23 @@ static void printdata(u8 *pbuf, u32 len) static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz) { - PHAL_DATA_TYPE phal; + struct rx_pkt_attrib rx_desc; +#if 0 struct recv_stat *prxstat; struct recv_stat report; PRXREPORT prxreport; - u32 drvinfosize; +#endif u32 rxpktsize; - u8 fcssize; + u8 drvinfosize; + u8 shiftsize; u8 ret = _FALSE; + u8 skip_len = 4; /* Don't compare the frame control and duration field */ + get_rx_desc(&rx_desc, rxbuf); + rxpktsize = rx_desc.pkt_len; + drvinfosize = rx_desc.drvinfo_sz; + shiftsize = rx_desc.shift_sz; +#if 0 prxstat = (struct recv_stat *)rxbuf; report.rxdw0 = le32_to_cpu(prxstat->rxdw0); report.rxdw1 = le32_to_cpu(prxstat->rxdw1); @@ -11739,21 +11839,19 @@ static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz) prxreport = (PRXREPORT)&report; drvinfosize = prxreport->drvinfosize << 3; rxpktsize = prxreport->pktlen; +#endif - phal = GET_HAL_DATA(padapter); if (rtw_hal_rcr_check(padapter, RCR_APPFCS)) - fcssize = IEEE80211_FCS_LEN; - else - fcssize = 0; + rxpktsize -= IEEE80211_FCS_LEN; - if ((txsz - TXDESC_SIZE) != (rxpktsize - fcssize)) { + if ((txsz - TXDESC_SIZE) != rxpktsize) { RTW_INFO("%s: ERROR! size not match tx/rx=%d/%d !\n", - __func__, txsz - TXDESC_SIZE, rxpktsize - fcssize); + __func__, txsz - TXDESC_SIZE, rxpktsize); ret = _FALSE; } else { - ret = _rtw_memcmp(txbuf + TXDESC_SIZE, \ - rxbuf + RXDESC_SIZE + drvinfosize, \ - txsz - TXDESC_SIZE); + ret = _rtw_memcmp(txbuf + TXDESC_SIZE + skip_len, \ + rxbuf + RXDESC_SIZE + skip_len + drvinfosize, \ + txsz - TXDESC_SIZE - skip_len); if (ret == _FALSE) RTW_INFO("%s: ERROR! pkt content mismatch!\n", __func__); } @@ -11761,23 +11859,17 @@ static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz) if (ret == _FALSE) { RTW_INFO("\n%s: TX PKT total=%d, desc=%d, content=%d\n", __func__, txsz, TXDESC_SIZE, txsz - TXDESC_SIZE); - RTW_INFO("%s: TX DESC size=%d\n", __func__, TXDESC_SIZE); - printdata(txbuf, TXDESC_SIZE); - RTW_INFO("%s: TX content size=%d\n", __func__, txsz - TXDESC_SIZE); - printdata(txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE); + dbg_dump_pkt("TX DESC", txbuf, TXDESC_SIZE); + dbg_dump_pkt("TX content", txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE); RTW_INFO("\n%s: RX PKT read=%d offset=%d(%d,%d) content=%d\n", __func__, rxsz, RXDESC_SIZE + drvinfosize, RXDESC_SIZE, drvinfosize, rxpktsize); if (rxpktsize != 0) { - RTW_INFO("%s: RX DESC size=%d\n", __func__, RXDESC_SIZE); - printdata(rxbuf, RXDESC_SIZE); - RTW_INFO("%s: RX drvinfo size=%d\n", __func__, drvinfosize); - printdata(rxbuf + RXDESC_SIZE, drvinfosize); - RTW_INFO("%s: RX content size=%d\n", __func__, rxpktsize); - printdata(rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize); + dbg_dump_pkt("RX DESC", rxbuf, RXDESC_SIZE); + dbg_dump_pkt("RX drvinfo", rxbuf + RXDESC_SIZE, drvinfosize); + dbg_dump_pkt("RX packet content", rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize); } else { RTW_INFO("%s: RX data size=%d\n", __func__, rxsz); - printdata(rxbuf, rxsz); } } @@ -11794,7 +11886,6 @@ thread_return lbk_thread(thread_context context) u32 pktsize; u32 ff_hwaddr; - padapter = (PADAPTER)context; ploopback = padapter->ploopback; if (ploopback == NULL) @@ -11803,7 +11894,8 @@ thread_return lbk_thread(thread_context context) ok = 0; fail = 0; - daemonize("%s", "RTW_LBK_THREAD"); + thread_enter("RTW_LBK_THREAD"); + /* daemonize("%s", "RTW_LBK_THREAD"); */ allow_signal(SIGTERM); do { @@ -11824,10 +11916,13 @@ thread_return lbk_thread(thread_context context) ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe); cnt++; RTW_INFO("%s: wirte port cnt=%d size=%d\n", __func__, cnt, ploopback->txsize); +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) pxmitframe->pxmitbuf->pdata = ploopback->txbuf; +#endif rtw_write_port(padapter, ff_hwaddr, ploopback->txsize, (u8 *)pxmitframe->pxmitbuf); /* wait for rx pkt */ + RTW_INFO("%s: wait for rx packet\n", __func__); _rtw_down_sema(&ploopback->sema); err = pktcmp(padapter, ploopback->txbuf, ploopback->txsize, ploopback->rxbuf, ploopback->rxsize); @@ -11871,7 +11966,6 @@ static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8 *pmsg) u32 len; s32 err; - ploopback = padapter->ploopback; if (ploopback) { @@ -11886,6 +11980,7 @@ static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8 *pmsg) break; rtw_msleep_os(1); } while (1); + RTW_INFO("Free loopback, end the test.\n"); _rtw_memcpy(pmsg, ploopback->msg, len + 1); freeLoopback(padapter); @@ -11893,8 +11988,10 @@ static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8 *pmsg) } /* disable dynamic algorithm */ +#ifndef CONFIG_NO_PHYDM rtw_phydm_ability_backup(padapter); rtw_phydm_func_disable_all(padapter); +#endif /* create pseudo ad-hoc connection */ err = initpseudoadhoc(padapter); @@ -11921,7 +12018,7 @@ static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8 *pmsg) ploopback->cnt = cnt; ploopback->size = size; ploopback->lbkthread = kthread_run(lbk_thread, padapter, "RTW_LBK_THREAD"); - if (IS_ERR(padapter->lbkthread)) { + if (IS_ERR(ploopback->lbkthread)) { freeLoopback(padapter); ploopback->lbkthread = NULL; sprintf(pmsg, "loopback start FAIL! cnt=%d", cnt); @@ -11972,7 +12069,19 @@ static int rtw_test( } #ifdef CONFIG_MAC_LOOPBACK_DRIVER - if (strcmp(pch, "loopback") == 0) { + if (strcmp(pch, "init") == 0) { + u8 status; + + rtw_clr_drv_stopped(padapter); /* should clear drv_stopped, otherwise driver can't trx */ + + status = hal_init(padapter); + RTW_INFO("HAL_INIT %s\n", status ? "SUCCESS" : "FAIL"); + + rtw_write8(padapter, REG_LOOPBACK_ENABLE, LOOKBACK_ENABLE_VALUE); + RTW_INFO("Write 0x%03x to 0x%02x, enable loopback\n", + REG_LOOPBACK_ENABLE, LOOKBACK_ENABLE_VALUE); + + } else if (strcmp(pch, "loopback") == 0) { s32 cnt = 0; u32 size = 64; @@ -12011,6 +12120,15 @@ static int rtw_test( } else if (strcmp(pch, "btoff") == 0) { rtw_btcoex_SetManualControl(padapter, _TRUE); goto free_buf; + } else if (strcmp(pch, "coex_auto") == 0) { + rtw_btcoex_set_policy_control(padapter, BTCOEX_POLICY_CONTROL_AUTO); + goto free_buf; + } else if (strcmp(pch, "coex_force_freerun") == 0) { + rtw_btcoex_set_policy_control(padapter, BTCOEX_POLICY_CONTROL_FORCE_FREERUN); + goto free_buf; + } else if (strcmp(pch, "coex_force_tdma") == 0) { + rtw_btcoex_set_policy_control(padapter, BTCOEX_POLICY_CONTROL_FORCE_TDMA); + goto free_buf; } #endif @@ -12051,12 +12169,18 @@ static int rtw_test( goto free_buf; } + if (strcmp(pch, "dump_mac_reg") == 0) { + mac_reg_dump(RTW_DBGDUMP, padapter); + goto free_buf; + } + free_buf: rtw_mfree(pbuf, len); return 0; } static iw_handler rtw_handlers[] = { +#ifdef CONFIG_IOCTL_WEXT NULL, /* SIOCSIWCOMMIT */ rtw_wx_get_name, /* SIOCGIWNAME */ dummy, /* SIOCSIWNWID */ @@ -12113,6 +12237,7 @@ static iw_handler rtw_handlers[] = { NULL, /* SIOCGIWENCODEEXT */ rtw_wx_set_pmkid, /* SIOCSIWPMKSA */ NULL, /*---hole---*/ +#endif }; @@ -12216,7 +12341,13 @@ static const struct iw_priv_args rtw_private_args[] = { #else {SIOCIWFIRSTPRIV + 0x17, IW_PRIV_TYPE_CHAR | 1024 , 0 , "NULL"}, #endif - {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"}, + +#ifdef CONFIG_PLATFORM_CMAP_INTFS + {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | 1024 , 0 , "cmap_intfs"}, +#else + {SIOCIWFIRSTPRIV + 0x18, 0, 0, "NULL"}, +#endif + #ifdef CONFIG_MP_INCLUDED {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"}, {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL"}, @@ -12244,7 +12375,11 @@ static const struct iw_priv_args rtw_private_args[] = { #ifdef CONFIG_WOWLAN { MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_mode" }, { MP_WOW_SET_PATTERN , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_set_pattern" }, +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + { MP_WOW_SET_KEEP_ALIVE_PATTERN ,IW_PRIV_TYPE_CHAR | 1024 , 0 , "wow_keep_alive"}, +#endif /* defined (CONFIG_KEEP_ALIVE_PATTERN)*/ #endif + #ifdef CONFIG_AP_WOWLAN { MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_mode" }, /* set */ #endif @@ -12361,7 +12496,11 @@ static iw_handler rtw_private_handler[] = { #else rtw_wx_priv_null, /* 0x17 */ #endif - rtw_rereg_nd_name, /* 0x18 */ +#ifdef CONFIG_PLATFORM_CMAP_INTFS + cmap_intfs_ioctl, /* 0x18 */ +#else + NULL, /* 0x18 */ +#endif rtw_wx_priv_null, /* 0x19 */ #ifdef CONFIG_MP_INCLUDED rtw_wx_priv_null, /* 0x1A */ @@ -12374,6 +12513,7 @@ static iw_handler rtw_private_handler[] = { rtw_test, /* 0x1D */ }; +#ifdef CONFIG_WIRELESS_EXT #if WIRELESS_EXT >= 17 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) { @@ -12430,7 +12570,6 @@ static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) } #endif -#ifdef CONFIG_WIRELESS_EXT struct iw_handler_def rtw_handlers_def = { .standard = rtw_handlers, .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler), @@ -12886,6 +13025,7 @@ int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) int ret = 0; switch (cmd) { +#ifdef CONFIG_IOCTL_WEXT case RTL_IOCTL_WPA_SUPPLICANT: ret = wpa_supplicant_ioctl(dev, &wrq->u.data); break; @@ -12899,6 +13039,7 @@ int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; #endif #endif /* CONFIG_AP_MODE */ +#endif /* CONFIG_IOCTL_WEXT */ case SIOCDEVPRIVATE: ret = rtw_ioctl_wext_private(dev, rq); break; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_mp.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_mp.c index d9ec3e4621bf..45b85a5911ab 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_mp.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/ioctl_mp.c @@ -25,6 +25,18 @@ #include #endif +#define RTW_IWD_MAX_LEN 128 +inline u8 rtw_do_mp_iwdata_len_chk(const char *caller, u32 len) +{ + u8 is_illegal = _FALSE; + if (len >= RTW_IWD_MAX_LEN) { + RTW_ERR("%s : iw data len(%u) > RTW_IWD_MAX_LEN(%u)", + caller, len, RTW_IWD_MAX_LEN); + is_illegal = _TRUE; + } + return is_illegal; +} + /* * Input Format: %s,%d,%d * %s is width, could be @@ -44,7 +56,10 @@ int rtw_mp_write_reg(struct net_device *dev, u32 addr, data; int ret; PADAPTER padapter = rtw_netdev_priv(dev); - char input[wrqu->length + 1]; + char input[RTW_IWD_MAX_LEN]; + + if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) + return -EFAULT; _rtw_memset(input, 0, sizeof(input)); @@ -128,7 +143,7 @@ int rtw_mp_read_reg(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrqu, char *extra) { - char input[wrqu->length + 1]; + char input[RTW_IWD_MAX_LEN]; char *pch, *pnext; char *width_str; char width; @@ -138,6 +153,9 @@ int rtw_mp_read_reg(struct net_device *dev, PADAPTER padapter = rtw_netdev_priv(dev); char *pextra = extra; + if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) + return -EFAULT; + if (wrqu->length > 128) return -EFAULT; @@ -262,8 +280,10 @@ int rtw_mp_write_rf(struct net_device *dev, int ret; PADAPTER padapter = rtw_netdev_priv(dev); struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); - char input[wrqu->length]; + char input[RTW_IWD_MAX_LEN]; + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + return -EFAULT; _rtw_memset(input, 0, wrqu->length); if (copy_from_user(input, wrqu->pointer, wrqu->length)) @@ -304,7 +324,7 @@ int rtw_mp_read_rf(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrqu, char *extra) { - char input[wrqu->length]; + char input[RTW_IWD_MAX_LEN]; char *pch, *pnext; char data[20], tmp[20]; u32 path, addr, strtou; @@ -313,6 +333,9 @@ int rtw_mp_read_rf(struct net_device *dev, struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); char *pextra = extra; + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + return -EFAULT; + if (wrqu->length > 128) return -EFAULT; _rtw_memset(input, 0, wrqu->length); @@ -424,12 +447,15 @@ int rtw_mp_rate(struct net_device *dev, { u32 rate = MPT_RATE_1M; u8 err = 0; - u8 input[wrqu->length + 1]; + u8 input[RTW_IWD_MAX_LEN]; PADAPTER padapter = rtw_netdev_priv(dev); PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx); struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); struct mp_priv *pmppriv = &padapter->mppriv; + if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) + return -EFAULT; + _rtw_memset(input, 0, sizeof(input)); if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; @@ -493,8 +519,12 @@ int rtw_mp_channel(struct net_device *dev, PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); - u8 input[wrqu->length + 1]; - u32 channel = 1; + u8 input[RTW_IWD_MAX_LEN]; + u8 channel = 1; + struct mp_priv *pmppriv = &padapter->mppriv; + + if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) + return -EFAULT; _rtw_memset(input, 0, sizeof(input)); if (copy_from_user(input, wrqu->pointer, wrqu->length)) @@ -507,6 +537,7 @@ int rtw_mp_channel(struct net_device *dev, sprintf(extra, "Change channel %d to channel %d", padapter->mppriv.channel , channel); padapter->mppriv.channel = channel; rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0); + rtw_adjust_chbw(padapter, channel, &pmppriv->bandwidth, &pmppriv->prime_channel_offset); SetChannel(padapter); pHalData->current_channel = channel; @@ -521,8 +552,12 @@ int rtw_mp_ch_offset(struct net_device *dev, { PADAPTER padapter = rtw_netdev_priv(dev); - u8 input[wrqu->length + 1]; + u8 input[RTW_IWD_MAX_LEN]; u32 ch_offset = 0; + char *pch; + + if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) + return -EFAULT; _rtw_memset(input, 0, sizeof(input)); if (copy_from_user(input, wrqu->pointer, wrqu->length)) @@ -532,7 +567,8 @@ int rtw_mp_ch_offset(struct net_device *dev, ch_offset = rtw_atoi(input); /*RTW_INFO("%s: channel=%d\n", __func__, channel);*/ _rtw_memset(extra, 0, wrqu->length); - sprintf(extra, "Change prime channel offset %d to %d", padapter->mppriv.prime_channel_offset , ch_offset); + pch = extra; + pch += sprintf(pch, "Change prime channel offset %d to %d", padapter->mppriv.prime_channel_offset , ch_offset); padapter->mppriv.prime_channel_offset = ch_offset; SetChannel(padapter); @@ -545,23 +581,22 @@ int rtw_mp_bandwidth(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrqu, char *extra) { - u32 bandwidth = 0, sg = 0; + u8 bandwidth = 0, sg = 0; PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); - u8 input[wrqu->length]; + struct mp_priv *pmppriv = &padapter->mppriv; + u8 input[RTW_IWD_MAX_LEN]; + + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + return -EFAULT; if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; - if (sscanf(input, "40M=%d,shortGI=%d", &bandwidth, &sg) > 0) - RTW_INFO("%s: bw=%d sg=%d\n", __func__, bandwidth , sg); + if (sscanf(input, "40M=%hhd,shortGI=%hhd", &bandwidth, &sg) > 0) + RTW_INFO("%s: bw=%hhd sg=%hhd\n", __func__, bandwidth , sg); - if (bandwidth == 1 && hal_chk_bw_cap(padapter, BW_CAP_40M)) - bandwidth = CHANNEL_WIDTH_40; - else if (bandwidth == 2 && hal_chk_bw_cap(padapter, BW_CAP_80M)) - bandwidth = CHANNEL_WIDTH_80; - else - bandwidth = CHANNEL_WIDTH_20; + rtw_adjust_chbw(padapter, pmppriv->channel, &bandwidth, &pmppriv->prime_channel_offset); padapter->mppriv.bandwidth = (u8)bandwidth; padapter->mppriv.preamble = sg; @@ -583,11 +618,14 @@ int rtw_mp_txpower_index(struct net_device *dev, { PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *phal_data = GET_HAL_DATA(padapter); - char input[wrqu->length + 1]; + char input[RTW_IWD_MAX_LEN]; u32 rfpath = 0 ; u32 txpower_inx = 0, tarpowerdbm = 0; char *pextra = extra; + if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) + return -EFAULT; + if (wrqu->length > 128) return -EFAULT; @@ -656,12 +694,15 @@ int rtw_mp_txpower(struct net_device *dev, { u32 idx_a = 0, idx_b = 0, idx_c = 0, idx_d = 0; int MsetPower = 1; - u8 input[wrqu->length]; + u8 input[RTW_IWD_MAX_LEN]; u8 res = 0; PADAPTER padapter = rtw_netdev_priv(dev); PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx); + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + return -EFAULT; + if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; @@ -704,11 +745,14 @@ int rtw_mp_ant_tx(struct net_device *dev, struct iw_point *wrqu, char *extra) { u8 i; - u8 input[wrqu->length + 1]; + u8 input[RTW_IWD_MAX_LEN]; u16 antenna = 0; PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) + return -EFAULT; + _rtw_memset(input, 0, sizeof(input)); if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; @@ -758,10 +802,13 @@ int rtw_mp_ant_rx(struct net_device *dev, { u8 i; u16 antenna = 0; - u8 input[wrqu->length + 1]; + u8 input[RTW_IWD_MAX_LEN]; PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) + return -EFAULT; + _rtw_memset(input, 0, sizeof(input)); if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; @@ -988,9 +1035,12 @@ int rtw_mp_disable_bt_coexist(struct net_device *dev, PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev); #endif - u8 input[wrqu->data.length + 1]; + u8 input[RTW_IWD_MAX_LEN]; u32 bt_coexist; + if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->data.length + 1))) + return -EFAULT; + _rtw_memset(input, 0, sizeof(input)); if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) @@ -1026,13 +1076,16 @@ int rtw_mp_arx(struct net_device *dev, { int bStartRx = 0, bStopRx = 0, bQueryPhy = 0, bQueryMac = 0, bSetBssid = 0, bSetRxframe = 0; int bmac_filter = 0, bmon = 0, bSmpCfg = 0; - u8 input[wrqu->length]; + u8 input[RTW_IWD_MAX_LEN]; char *pch, *token, *tmp[2] = {0x00, 0x00}; u32 i = 0, jj = 0, kk = 0, cnts = 0, ret; PADAPTER padapter = rtw_netdev_priv(dev); struct mp_priv *pmppriv = &padapter->mppriv; struct dbg_rx_counter rx_counter; + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + return -EFAULT; + if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; @@ -1216,7 +1269,10 @@ int rtw_mp_pwrtrk(struct net_device *dev, u32 thermal; s32 ret; PADAPTER padapter = rtw_netdev_priv(dev); - u8 input[wrqu->length]; + u8 input[RTW_IWD_MAX_LEN]; + + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + return -EFAULT; if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; @@ -1254,7 +1310,10 @@ int rtw_mp_psd(struct net_device *dev, struct iw_point *wrqu, char *extra) { PADAPTER padapter = rtw_netdev_priv(dev); - u8 input[wrqu->length + 1]; + u8 input[RTW_IWD_MAX_LEN]; + + if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1))) + return -EFAULT; _rtw_memset(input, 0, sizeof(input)); if (copy_from_user(input, wrqu->pointer, wrqu->length)) @@ -1327,6 +1386,9 @@ int rtw_mp_thermal(struct net_device *dev, ther_path_addr[2] = EEPROM_THERMAL_METER_C_8814B; ther_path_addr[3] = EEPROM_THERMAL_METER_D_8814B; #endif +#ifdef CONFIG_RTL8723F + ther_path_addr[0] = EEPROM_THERMAL_METER_8723F; +#endif if (copy_from_user(extra, wrqu->pointer, wrqu->length)) return -EFAULT; @@ -1413,11 +1475,14 @@ int rtw_mp_dump(struct net_device *dev, struct iw_point *wrqu, char *extra) { struct mp_priv *pmp_priv; - u8 input[wrqu->length]; + u8 input[RTW_IWD_MAX_LEN]; PADAPTER padapter = rtw_netdev_priv(dev); pmp_priv = &padapter->mppriv; + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + return -EFAULT; + if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; @@ -1437,10 +1502,12 @@ int rtw_mp_phypara(struct net_device *dev, PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); - char input[wrqu->length]; + char input[RTW_IWD_MAX_LEN]; u32 invalxcap = 0, ret = 0, bwrite_xcap = 0, hwxtaladdr = 0; u16 pgval; + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + return -EFAULT; if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; @@ -1492,12 +1559,15 @@ int rtw_mp_SetRFPath(struct net_device *dev, struct iw_point *wrqu, char *extra) { PADAPTER padapter = rtw_netdev_priv(dev); - char input[wrqu->length]; + char input[RTW_IWD_MAX_LEN]; int bMain = 1, bTurnoff = 1; #ifdef CONFIG_ANTENNA_DIVERSITY u8 ret = _TRUE; #endif + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + return -EFAULT; + RTW_INFO("%s:iwpriv in=%s\n", __func__, input); if (copy_from_user(input, wrqu->pointer, wrqu->length)) @@ -1543,10 +1613,13 @@ int rtw_mp_switch_rf_path(struct net_device *dev, { PADAPTER padapter = rtw_netdev_priv(dev); struct mp_priv *pmp_priv; - char input[wrqu->length]; + char input[RTW_IWD_MAX_LEN]; + char *pch; int bwlg = 1, bwla = 1, btg = 1, bbt=1; u8 ret = 0; + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + return -EFAULT; if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; @@ -1555,25 +1628,27 @@ int rtw_mp_switch_rf_path(struct net_device *dev, RTW_INFO("%s: in=%s\n", __func__, input); + _rtw_memset(extra, '\0', wrqu->length); + pch = extra; #ifdef CONFIG_RTL8821C /* only support for 8821c wlg/wla/btg/bt RF switch path */ if ((strncmp(input, "WLG", 3) == 0) || (strncmp(input, "1", 1) == 0)) { pmp_priv->rf_path_cfg = SWITCH_TO_WLG; - sprintf(extra, "switch rf path WLG\n"); + pch += sprintf(pch, "switch rf path WLG\n"); } else if ((strncmp(input, "WLA", 3) == 0) || (strncmp(input, "2", 1) == 0)) { pmp_priv->rf_path_cfg = SWITCH_TO_WLA; - sprintf(extra, "switch rf path WLA\n"); + pch += sprintf(pch, "switch rf path WLA\n"); } else if ((strncmp(input, "BTG", 3) == 0) || (strncmp(input, "0", 1) == 0)) { pmp_priv->rf_path_cfg = SWITCH_TO_BTG; - sprintf(extra, "switch rf path BTG\n"); + pch += sprintf(pch, "switch rf path BTG\n"); } else if ((strncmp(input, "BT", 3) == 0) || (strncmp(input, "3", 1) == 0)) { pmp_priv->rf_path_cfg = SWITCH_TO_BT; - sprintf(extra, "switch rf path BT\n"); + pch += sprintf(pch, "switch rf path BT\n"); } else { pmp_priv->rf_path_cfg = SWITCH_TO_WLG; - sprintf(extra, "Error input, default set WLG\n"); + pch += sprintf(pch, "Error input, default set WLG\n"); return -EFAULT; } @@ -1589,11 +1664,14 @@ int rtw_mp_QueryDrv(struct net_device *dev, union iwreq_data *wrqu, char *extra) { PADAPTER padapter = rtw_netdev_priv(dev); - char input[wrqu->data.length]; + char input[RTW_IWD_MAX_LEN]; int qAutoLoad = 1; PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->data.length)) + return -EFAULT; + if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) return -EFAULT; RTW_INFO("%s:iwpriv in=%s\n", __func__, input); @@ -1618,15 +1696,18 @@ int rtw_mp_PwrCtlDM(struct net_device *dev, struct iw_point *wrqu, char *extra) { PADAPTER padapter = rtw_netdev_priv(dev); - u8 input[wrqu->length]; + u8 input[RTW_IWD_MAX_LEN]; u8 pwrtrk_state = 0; u8 pwtk_type[5][25] = {"Thermal tracking off","Thermal tracking on", "TSSI tracking off","TSSI tracking on","TSSI calibration"}; + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + return -EFAULT; + if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; - input[wrqu->length] = '\0'; + input[wrqu->length - 1] = '\0'; RTW_INFO("%s: in=%s\n", __func__, input); if (wrqu->length == 2) { @@ -1659,7 +1740,7 @@ int rtw_mp_PwrCtlDM(struct net_device *dev, pwrtrk_state = 4; sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]); } else { - sprintf(extra, "Error input !!! \n" + sprintf(extra, "Error input !!!\n" " thertrk off : Thermal tracking off\n thertrk on : Thermal tracking on\n" " tssitrk off : TSSI tracking off\n tssitrk on : TSSI tracking on\n tssik : TSSI calibration\n\n" " 0 : Thermal tracking off\n 1 : Thermal tracking on\n 2 : TSSI tracking off\n" @@ -1704,6 +1785,7 @@ int rtw_mp_dpk(struct net_device *dev, HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct dm_struct *pDM_Odm = &pHalData->odmpriv; struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + char *pch; u8 ips_mode = IPS_NUM; /* init invalid value */ u8 lps_mode = PS_MODE_NUM; /* init invalid value */ @@ -1712,16 +1794,17 @@ int rtw_mp_dpk(struct net_device *dev, return -EFAULT; *(extra + wrqu->data.length) = '\0'; + pch = extra; if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) { pDM_Odm->dpk_info.is_dpk_enable = 0; halrf_dpk_enable_disable(pDM_Odm); - sprintf(extra, "set dpk off\n"); + pch += sprintf(pch, "set dpk off\n"); } else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) { pDM_Odm->dpk_info.is_dpk_enable = 1; halrf_dpk_enable_disable(pDM_Odm); - sprintf(extra, "set dpk on\n"); + pch += sprintf(pch, "set dpk on\n"); } else { #ifdef CONFIG_LPS lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */ @@ -1741,7 +1824,7 @@ int rtw_mp_dpk(struct net_device *dev, rtw_pm_set_lps(padapter, lps_mode); #endif /* CONFIG_LPS */ } - sprintf(extra, "set dpk trigger\n"); + pch += sprintf(pch, "set dpk trigger\n"); } wrqu->data.length = strlen(extra); @@ -1756,10 +1839,29 @@ int rtw_mp_get_tsside(struct net_device *dev, PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct dm_struct *pDM_Odm = &pHalData->odmpriv; - char input[wrqu->length + 1]; + char input[RTW_IWD_MAX_LEN]; u8 rfpath; u32 tssi_de; + u8 legal_param_num = 1; + int param_num; + char pout_str_buf[7]; + u8 signed_flag = 0; + int integer_num; + u32 decimal_num; + s32 pout; + char *pextra; + int i; + + #ifdef CONFIG_RTL8723F + /* + * rtwpriv wlan0 mp_get_tsside rf_path pout + * rf_path : 0 ~ 1 + * pout : -15.000 ~ 25.000 + * ex : rtwpriv wlan0 mp_get_tsside 0 -12.123 + */ + legal_param_num = 2; + #endif if (wrqu->length > 128) return -EFAULT; @@ -1768,25 +1870,60 @@ int rtw_mp_get_tsside(struct net_device *dev, if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; - input[wrqu->length] = '\0'; + param_num = sscanf(input, "%hhu %7s", &rfpath, pout_str_buf); - if (wrqu->length == 2) { - rfpath = rtw_atoi(input); - if (rfpath >= 0 && rfpath <= 3) { - tssi_de = halrf_tssi_get_de(pDM_Odm, rfpath); - if (rfpath == 0) - sprintf(extra, "patha=%d", tssi_de); - else if (rfpath == 1) - sprintf(extra, "pathb=%d", tssi_de); - else if (rfpath == 2) - sprintf(extra, "pathc=%d", tssi_de); - else if (rfpath == 3) - sprintf(extra, "pathd=%d", tssi_de); - } else - sprintf(extra, "Invalid command format, please indicate RF path 0/1/2/3"); - } else - sprintf(extra, "Invalid command format, please indicate RF path 0/1/2/3"); + /* Check parameter format*/ + if(param_num != legal_param_num) + goto invalid_param_format; + if(rfpath <0 || 3 < rfpath) + goto invalid_param_format; + +#ifdef CONFIG_RTL8723F + /* Convert pout from floating-point to integer + * For Floating-Point Precision, pout*1000 + */ + if(pout_str_buf[0] == '-') + signed_flag = 1; + i = sscanf(pout_str_buf, "%d.%3u", &integer_num, &decimal_num); + pout = integer_num * 1000; + if(i == 2) { + /* Convert decimal number + * ex : 0.1 => 100, -0.1 => 100 + */ + decimal_num = (decimal_num < 10) ? decimal_num * 100 : decimal_num; + decimal_num = (decimal_num < 100) ? decimal_num * 10 : decimal_num; + pout += ((pout < 0 || signed_flag == 1) ? -decimal_num : decimal_num); + } + if(pout < -15000 || 25000 < pout) + goto invalid_param_format; +#endif + +#ifdef CONFIG_RTL8723F + /* For Floating-Point Precision, pout */ + tssi_de = halrf_get_online_tssi_de(pDM_Odm, rfpath, pout); +#else + tssi_de = halrf_tssi_get_de(pDM_Odm, rfpath); +#endif + + if (rfpath == 0) + sprintf(extra, "patha=%d", tssi_de); + else if (rfpath == 1) + sprintf(extra, "pathb=%d", tssi_de); + else if (rfpath == 2) + sprintf(extra, "pathc=%d", tssi_de); + else if (rfpath == 3) + sprintf(extra, "pathd=%d", tssi_de); + + wrqu->length = strlen(extra); + return 0; + +invalid_param_format: + sprintf(extra, "Invalid command format, please indicate RF path 0/1/2/3"); +#ifdef CONFIG_RTL8723F + pextra = extra + strlen(extra); + sprintf(pextra, " and pout value : -15.000 ~ 25.000\n"); +#endif wrqu->length = strlen(extra); return 0; @@ -1797,12 +1934,15 @@ int rtw_mp_set_tsside(struct net_device *dev, struct iw_point *wrqu, char *extra) { u32 tsside_a = 0, tsside_b = 0, tsside_c = 0, tsside_d = 0; - char input[wrqu->length]; + char input[RTW_IWD_MAX_LEN]; PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct dm_struct *pDM_Odm = &pHalData->odmpriv; + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + return -EFAULT; + if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; @@ -2449,7 +2589,9 @@ int rtw_mp_hwtx(struct net_device *dev, PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx); char *pch; -#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) +#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) \ + || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8723F) +/* todo: 8723F */ if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) return -EFAULT; *(extra + wrqu->data.length) = '\0'; @@ -2472,6 +2614,7 @@ int rtw_mp_hwtx(struct net_device *dev, wrqu->data.length = strlen(extra); #endif return 0; + } int rtw_mp_pwrlmt(struct net_device *dev, @@ -2480,25 +2623,26 @@ int rtw_mp_pwrlmt(struct net_device *dev, { PADAPTER padapter = rtw_netdev_priv(dev); struct registry_priv *registry_par = &padapter->registrypriv; - u8 pwrlimtstat = 0; + char *pch; if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) return -EFAULT; *(extra + wrqu->data.length) = '\0'; + pch = extra; + #if CONFIG_TXPWR_LIMIT - pwrlimtstat = registry_par->RegEnableTxPowerLimit; if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) { padapter->registrypriv.RegEnableTxPowerLimit = 0; - sprintf(extra, "Turn off Power Limit\n"); + pch += sprintf(pch, "Turn off Power Limit\n"); } else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) { padapter->registrypriv.RegEnableTxPowerLimit = 1; - sprintf(extra, "Turn on Power Limit\n"); + pch += sprintf(pch, "Turn on Power Limit\n"); } else #endif - sprintf(extra, "Get Power Limit Status:%s\n", (pwrlimtstat == 1) ? "ON" : "OFF"); + pch += sprintf(pch, "Get Power Limit Status:%s\n", (registry_par->RegEnableTxPowerLimit == 1) ? "ON" : "OFF"); wrqu->data.length = strlen(extra); @@ -2539,20 +2683,21 @@ int rtw_mp_dpk_track(struct net_device *dev, PADAPTER padapter = rtw_netdev_priv(dev); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct dm_struct *pDM_Odm = &pHalData->odmpriv; - + char *pch; if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) return -EFAULT; *(extra + wrqu->data.length) = '\0'; + pch = extra; if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) { halrf_set_dpk_track(pDM_Odm, FALSE); - sprintf(extra, "set dpk track off\n"); + pch += sprintf(pch, "set dpk track off\n"); } else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) { halrf_set_dpk_track(pDM_Odm, TRUE); - sprintf(extra, "set dpk track on\n"); + pch += sprintf(pch, "set dpk track on\n"); } wrqu->data.length = strlen(extra); @@ -2565,6 +2710,8 @@ int rtw_bt_efuse_mask_file(struct net_device *dev, union iwreq_data *wrqu, char *extra) { char *rtw_efuse_mask_file_path; + u8 *pch; + char *ptmp, tmp; u8 Status; PADAPTER padapter = rtw_netdev_priv(dev); @@ -2574,14 +2721,12 @@ int rtw_bt_efuse_mask_file(struct net_device *dev, return -EFAULT; *(extra + wrqu->data.length) = '\0'; + ptmp = extra; if (strncmp(extra, "data,", 5) == 0) { - u8 *pch; - char *ptmp, tmp; u8 count = 0; u8 i = 0; - ptmp = extra; pch = strsep(&ptmp, ","); if ((pch == NULL) || (strlen(pch) == 0)) { @@ -2612,7 +2757,7 @@ int rtw_bt_efuse_mask_file(struct net_device *dev, padapter->registrypriv.bBTFileMaskEfuse = _TRUE; - sprintf(ptmp, "\nLoad BT Efuse Mask data %d hex ok\n", count); + ptmp += sprintf(ptmp, "\nLoad BT Efuse Mask data %d hex ok\n", count); wrqu->data.length = strlen(extra); return 0; } @@ -2621,17 +2766,18 @@ int rtw_bt_efuse_mask_file(struct net_device *dev, if (rtw_is_file_readable(rtw_efuse_mask_file_path) == _TRUE) { RTW_INFO("%s do rtw_is_file_readable = %s! ,sizeof BT maskfileBuffer %zu\n", __func__, rtw_efuse_mask_file_path, sizeof(btmaskfileBuffer)); Status = rtw_efuse_file_read(padapter, rtw_efuse_mask_file_path, btmaskfileBuffer, sizeof(btmaskfileBuffer)); + _rtw_memset(extra, '\0' , strlen(extra)); if (Status == _TRUE) { padapter->registrypriv.bBTFileMaskEfuse = _TRUE; - sprintf(extra, "BT efuse mask file read OK\n"); + ptmp += sprintf(ptmp, "BT efuse mask file read OK\n"); } else { padapter->registrypriv.bBTFileMaskEfuse = _FALSE; - sprintf(extra, "read BT efuse mask file FAIL\n"); + ptmp += sprintf(ptmp, "read BT efuse mask file FAIL\n"); RTW_INFO("%s rtw_efuse_file_read BT mask fail!\n", __func__); } } else { padapter->registrypriv.bBTFileMaskEfuse = _FALSE; - sprintf(extra, "BT efuse mask file readable FAIL\n"); + ptmp += sprintf(ptmp, "BT efuse mask file readable FAIL\n"); RTW_INFO("%s rtw_is_file_readable BT Mask file fail!\n", __func__); } wrqu->data.length = strlen(extra); @@ -2859,7 +3005,7 @@ int rtw_mp_link(struct net_device *dev, { PADAPTER padapter = rtw_netdev_priv(dev); struct mp_priv *pmp_priv; - char input[wrqu->length]; + char input[RTW_IWD_MAX_LEN]; int bgetrxdata = 0, btxdata = 0, bsetbt = 0; u8 err = 0; u32 i = 0, datalen = 0,jj, kk, waittime = 0; @@ -2870,6 +3016,9 @@ int rtw_mp_link(struct net_device *dev, pmp_priv = &padapter->mppriv; + if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length)) + return -EFAULT; + if (copy_from_user(input, wrqu->pointer, wrqu->length)) return -EFAULT; @@ -2884,7 +3033,7 @@ int rtw_mp_link(struct net_device *dev, if (bgetrxdata) { RTW_INFO("%s: in= 1 \n", __func__); if (pmp_priv->mplink_brx == _TRUE) { - + pch = extra; while (waittime < 100 && pmp_priv->mplink_brx == _FALSE) { if (pmp_priv->mplink_brx == _FALSE) rtw_msleep_os(10); @@ -2893,10 +3042,10 @@ int rtw_mp_link(struct net_device *dev, waittime++; } if (pmp_priv->mplink_brx == _TRUE) { - sprintf(extra, "\n"); - pextra = extra + strlen(extra); + pch += sprintf(pch, "\n"); + for (i = 0; i < pmp_priv->mplink_rx_len; i ++) { - pextra += sprintf(pextra, "%02x:", pmp_priv->mplink_buf[i]); + pch += sprintf(pch, "%02x:", pmp_priv->mplink_buf[i]); } _rtw_memset(pmp_priv->mplink_buf, '\0' , sizeof(pmp_priv->mplink_buf)); pmp_priv->mplink_brx = _FALSE; @@ -3015,12 +3164,13 @@ int rtw_mp_link(struct net_device *dev, if (tmp[2] != NULL) { _rtw_memset(extra, 0, wrqu->length); + pch = extra; ret = rtw_btcoex_btset_testmode(padapter, val); if (!CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(ret, BT_STATUS_BT_OP_SUCCESS)) { RTW_INFO("%s: BT_OP fail = 0x%x!\n", __FUNCTION__, val); - sprintf(extra, "BT_OP fail 0x%x!\n", val); + pch += sprintf(pch, "BT_OP fail 0x%x!\n", val); } else - sprintf(extra, "Set BT_OP 0x%x done!\n", val); + pch += sprintf(pch, "Set BT_OP 0x%x done!\n", val); } } @@ -3063,6 +3213,7 @@ int rtw_mp_SetBT(struct net_device *dev, return -EFAULT; *(extra + wrqu->data.length) = '\0'; + pch = extra; if (strlen(extra) < 1) return -EFAULT; @@ -3085,7 +3236,7 @@ int rtw_mp_SetBT(struct net_device *dev, BTStatus = rtw_read8(padapter, 0xa0); RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __func__, BTStatus); if (BTStatus != 0x04) { - sprintf(extra, "BT Status not Active DLFW FAIL\n"); + pch += sprintf(pch, "BT Status not Active DLFW FAIL\n"); goto exit; } @@ -3130,11 +3281,11 @@ int rtw_mp_SetBT(struct net_device *dev, if ((pMptCtx->mptOutBuf[4] == 0x00) && (pMptCtx->mptOutBuf[5] == 0x00)) { if (padapter->mppriv.bTxBufCkFail == _TRUE) - sprintf(extra, "check TxBuf Fail.\n"); + pch += sprintf(pch, "check TxBuf Fail.\n"); else - sprintf(extra, "download FW Fail.\n"); + pch += sprintf(pch, "download FW Fail.\n"); } else { - sprintf(extra, "download FW OK.\n"); + pch += sprintf(pch, "download FW OK.\n"); goto exit; } goto exit; @@ -3146,7 +3297,7 @@ int rtw_mp_SetBT(struct net_device *dev, BTStatus = rtw_read8(padapter, 0xa0); RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __func__, BTStatus); if (BTStatus != 0x04) { - sprintf(extra, "BT Status not Active DLFW FAIL\n"); + pch += sprintf(pch, "BT Status not Active DLFW FAIL\n"); goto exit; } @@ -3200,15 +3351,15 @@ int rtw_mp_SetBT(struct net_device *dev, RTW_INFO("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4], pMptCtx->mptOutBuf[5]); if ((pMptCtx->mptOutBuf[4] == 0x00) && (pMptCtx->mptOutBuf[5] == 0x00)) { if (padapter->mppriv.bTxBufCkFail == _TRUE) - sprintf(extra, "check TxBuf Fail.\n"); + pch += sprintf(pch, "check TxBuf Fail.\n"); else - sprintf(extra, "download FW Fail.\n"); + pch += sprintf(pch, "download FW Fail.\n"); } else { #ifdef CONFIG_BT_COEXIST rtw_btcoex_SwitchBtTRxMask(padapter); #endif rtw_msleep_os(200); - sprintf(extra, "download FW OK.\n"); + pch += sprintf(pch, "download FW OK.\n"); goto exit; } goto exit; @@ -3277,7 +3428,6 @@ int rtw_mp_SetBT(struct net_device *dev, goto todo; } - pch = extra; i = 0; while ((token = strsep(&pch, ",")) != NULL) { if (i > 1) @@ -3351,23 +3501,23 @@ todo: _rtw_memset(extra, '\0', wrqu->data.length); if (pHalData->bBTFWReady == _FALSE) { - sprintf(extra, "BTFWReady = FALSE.\n"); + pch += sprintf(pch, "BTFWReady = FALSE.\n"); goto exit; } mptbt_BtControlProcess(padapter, &BtReq); if (readtherm == 0) { - sprintf(extra, "BT thermal="); + pch += sprintf(pch, "BT thermal="); for (i = 4; i < pMptCtx->mptOutLen; i++) { if ((pMptCtx->mptOutBuf[i] == 0x00) && (pMptCtx->mptOutBuf[i + 1] == 0x00)) goto exit; - sprintf(extra, "%s %d ", extra, (pMptCtx->mptOutBuf[i] & 0x1f)); + pch += sprintf(pch, " %d ", (pMptCtx->mptOutBuf[i] & 0x1f)); } } else { for (i = 4; i < pMptCtx->mptOutLen; i++) - sprintf(extra, "%s 0x%x ", extra, pMptCtx->mptOutBuf[i]); + pch += sprintf(pch, " 0x%x ", pMptCtx->mptOutBuf[i]); } exit: diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/nlrtw.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/nlrtw.c new file mode 100644 index 000000000000..b0a3fdafbd15 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/nlrtw.c @@ -0,0 +1,584 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2020 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#define _RTW_NLRTW_C_ + +#include +#include "nlrtw.h" + +#ifdef CONFIG_RTW_NLRTW + +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) +#include +#endif + + +enum nlrtw_cmds { + NLRTW_CMD_UNSPEC, + + NLRTW_CMD_CHANNEL_UTILIZATION, + NLRTW_CMD_REG_CHANGE, + NLRTW_CMD_REG_BEACON_HINT, + NLRTW_CMD_RADAR_EVENT, + NLRTW_CMD_RADIO_OPMODE, + + __NLRTW_CMD_AFTER_LAST, + NLRTW_CMD_MAX = __NLRTW_CMD_AFTER_LAST - 1 +}; + +enum nlrtw_attrs { + NLRTW_ATTR_UNSPEC, + + NLRTW_ATTR_WIPHY_NAME, + NLRTW_ATTR_CHANNEL_UTILIZATIONS, + NLRTW_ATTR_CHANNEL_UTILIZATION_THRESHOLD, + NLRTW_ATTR_CHANNEL_CENTER, + NLRTW_ATTR_CHANNEL_WIDTH, + NLRTW_ATTR_RADAR_EVENT, + NLRTW_ATTR_OP_CLASS, + NLRTW_ATTR_OP_CHANNEL, + NLRTW_ATTR_OP_TXPWR_MAX, + NLRTW_ATTR_IF_OPMODES, + + __NLRTW_ATTR_AFTER_LAST, + NUM_NLRTW_ATTR = __NLRTW_ATTR_AFTER_LAST, + NLRTW_ATTR_MAX = __NLRTW_ATTR_AFTER_LAST - 1 +}; + +enum nlrtw_ch_util_attrs { + __NLRTW_ATTR_CHANNEL_UTILIZATION_INVALID, + + NLRTW_ATTR_CHANNEL_UTILIZATION_VALUE, + NLRTW_ATTR_CHANNEL_UTILIZATION_BSSID, + + __NLRTW_ATTR_CHANNEL_UTILIZATION_AFTER_LAST, + NUM_NLRTW_ATTR_CHANNEL_UTILIZATION = __NLRTW_ATTR_CHANNEL_UTILIZATION_AFTER_LAST, + NLRTW_ATTR_CHANNEL_UTILIZATION_MAX = __NLRTW_ATTR_CHANNEL_UTILIZATION_AFTER_LAST - 1 +}; + +enum nlrtw_radar_event { + NLRTW_RADAR_DETECTED, + NLRTW_RADAR_CAC_FINISHED, + NLRTW_RADAR_CAC_ABORTED, + NLRTW_RADAR_NOP_FINISHED, + NLRTW_RADAR_NOP_STARTED, /* NON_OCP started not by local radar detection */ +}; + +enum nlrtw_if_opmode_attrs { + NLRTW_IF_OPMODE_UNSPEC, + + NLRTW_IF_OPMODE_MACADDR, + NLRTW_IF_OPMODE_OP_CLASS, + NLRTW_IF_OPMODE_OP_CHANNEL, + + __NLRTW_IF_OPMODE_ATTR_AFTER_LAST, + NUM_NLRTW_IF_OPMODE_ATTR = __NLRTW_IF_OPMODE_ATTR_AFTER_LAST, + NLRTW_IF_OPMODE_ATTR_MAX = __NLRTW_IF_OPMODE_ATTR_AFTER_LAST - 1 +}; + +static int nlrtw_ch_util_set(struct sk_buff *skb, struct genl_info *info) +{ + unsigned int msg; + + if (!info->attrs[NLRTW_ATTR_CHANNEL_UTILIZATION_THRESHOLD]) + return -EINVAL; + msg = nla_get_u8(info->attrs[NLRTW_ATTR_CHANNEL_UTILIZATION_THRESHOLD]); + + return 0; +} + +static struct nla_policy nlrtw_genl_policy[NUM_NLRTW_ATTR] = { + [NLRTW_ATTR_CHANNEL_UTILIZATION_THRESHOLD] = { .type = NLA_U8 }, +}; + +static struct genl_ops nlrtw_genl_ops[] = { + { + .cmd = NLRTW_CMD_CHANNEL_UTILIZATION, + .flags = 0, +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) + .policy = nlrtw_genl_policy, +#endif + .doit = nlrtw_ch_util_set, + .dumpit = NULL, + }, +}; + +enum nlrtw_multicast_groups { + NLRTW_MCGRP_DEFAULT, +}; +static struct genl_multicast_group nlrtw_genl_mcgrp[] = { + [NLRTW_MCGRP_DEFAULT] = { .name = "nlrtw_default" }, +}; + +/* family definition */ +static struct genl_family nlrtw_genl_family = { + .hdrsize = 0, + .name = "nlrtw_"DRV_NAME, + .version = 1, + .maxattr = NLRTW_ATTR_MAX, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) + .policy = nlrtw_genl_policy, +#endif + .netnsok = true, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 12) + .module = THIS_MODULE, +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) + .ops = nlrtw_genl_ops, + .n_ops = ARRAY_SIZE(nlrtw_genl_ops), + .mcgrps = nlrtw_genl_mcgrp, + .n_mcgrps = ARRAY_SIZE(nlrtw_genl_mcgrp), +#endif +}; + +static inline int nlrtw_multicast(const struct genl_family *family, + struct sk_buff *skb, u32 portid, + unsigned int group, gfp_t flags) +{ + int ret; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) + ret = genlmsg_multicast(&nlrtw_genl_family, skb, portid, group, flags); +#else + ret = genlmsg_multicast(skb, portid, nlrtw_genl_mcgrp[group].id, flags); +#endif + return ret; +} + +int rtw_nlrtw_ch_util_rpt(_adapter *adapter, u8 n_rpts, u8 *val, u8 **mac_addr) +{ + struct sk_buff *skb = NULL; + void *msg_header = NULL; + struct nlattr *nl_ch_util, *nl_ch_utils; + struct wiphy *wiphy; + u8 i; + int ret; + + wiphy = adapter_to_wiphy(adapter); + if (!wiphy) + return -EINVAL; + + /* allocate memory */ + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) { + nlmsg_free(skb); + return -ENOMEM; + } + + /* create the message headers */ + msg_header = genlmsg_put(skb, 0, 0, &nlrtw_genl_family, 0, + NLRTW_CMD_CHANNEL_UTILIZATION); + if (!msg_header) { + ret = -ENOMEM; + goto err_out; + } + + /* add attributes */ + ret = nla_put_string(skb, NLRTW_ATTR_WIPHY_NAME, wiphy_name(wiphy)); + + nl_ch_utils = nla_nest_start(skb, NLRTW_ATTR_CHANNEL_UTILIZATIONS); + if (!nl_ch_utils) { + ret = -EMSGSIZE; + goto err_out; + } + + for (i = 0; i < n_rpts; i++) { + nl_ch_util = nla_nest_start(skb, i); + if (!nl_ch_util) { + ret = -EMSGSIZE; + goto err_out; + } + + ret = nla_put(skb, NLRTW_ATTR_CHANNEL_UTILIZATION_BSSID, ETH_ALEN, *(mac_addr + i)); + if (ret != 0) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_ATTR_CHANNEL_UTILIZATION_VALUE, *(val + i)); + if (ret != 0) + goto err_out; + + nla_nest_end(skb, nl_ch_util); + } + + nla_nest_end(skb, nl_ch_utils); + + /* finalize the message */ + genlmsg_end(skb, msg_header); + + ret = nlrtw_multicast(&nlrtw_genl_family, skb, 0, NLRTW_MCGRP_DEFAULT, GFP_KERNEL); + if (ret == -ESRCH) { + RTW_INFO("[%s] return ESRCH(No such process)." + " Maybe no process waits for this msg\n", __func__); + return ret; + } else if (ret != 0) { + RTW_INFO("[%s] ret = %d\n", __func__, ret); + return ret; + } + + return 0; +err_out: + nlmsg_free(skb); + return ret; +} + +int rtw_nlrtw_reg_change_event(_adapter *adapter) +{ + struct sk_buff *skb = NULL; + void *msg_header = NULL; + struct wiphy *wiphy; + u8 i; + int ret; + + wiphy = adapter_to_wiphy(adapter); + if (!wiphy) { + ret = -EINVAL; + goto err_out; + } + + /* allocate memory */ + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) { + ret = -ENOMEM; + goto err_out; + } + + /* create the message headers */ + msg_header = genlmsg_put(skb, 0, 0, &nlrtw_genl_family, 0, NLRTW_CMD_REG_CHANGE); + if (!msg_header) { + ret = -ENOMEM; + goto err_out; + } + + /* add attributes */ + ret = nla_put_string(skb, NLRTW_ATTR_WIPHY_NAME, wiphy_name(wiphy)); + if (ret) + goto err_out; + + /* finalize the message */ + genlmsg_end(skb, msg_header); + + ret = nlrtw_multicast(&nlrtw_genl_family, skb, 0, NLRTW_MCGRP_DEFAULT, GFP_KERNEL); + if (ret == -ESRCH) { + RTW_DBG(FUNC_WIPHY_FMT" return -ESRCH(No such process)." + " Maybe no process waits for this msg\n", FUNC_WIPHY_ARG(wiphy)); + return ret; + } else if (ret != 0) { + RTW_WARN(FUNC_WIPHY_FMT" return %d\n", FUNC_WIPHY_ARG(wiphy), ret); + return ret; + } + + return 0; + +err_out: + if (skb) + nlmsg_free(skb); + return ret; +} + +int rtw_nlrtw_reg_beacon_hint_event(_adapter *adapter) +{ + struct sk_buff *skb = NULL; + void *msg_header = NULL; + struct wiphy *wiphy; + u8 i; + int ret; + + wiphy = adapter_to_wiphy(adapter); + if (!wiphy) { + ret = -EINVAL; + goto err_out; + } + + /* allocate memory */ + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) { + ret = -ENOMEM; + goto err_out; + } + + /* create the message headers */ + msg_header = genlmsg_put(skb, 0, 0, &nlrtw_genl_family, 0, NLRTW_CMD_REG_BEACON_HINT); + if (!msg_header) { + ret = -ENOMEM; + goto err_out; + } + + /* add attributes */ + ret = nla_put_string(skb, NLRTW_ATTR_WIPHY_NAME, wiphy_name(wiphy)); + if (ret) + goto err_out; + + /* finalize the message */ + genlmsg_end(skb, msg_header); + + ret = nlrtw_multicast(&nlrtw_genl_family, skb, 0, NLRTW_MCGRP_DEFAULT, GFP_KERNEL); + if (ret == -ESRCH) { + RTW_DBG(FUNC_WIPHY_FMT" return -ESRCH(No such process)." + " Maybe no process waits for this msg\n", FUNC_WIPHY_ARG(wiphy)); + return ret; + } else if (ret != 0) { + RTW_WARN(FUNC_WIPHY_FMT" return %d\n", FUNC_WIPHY_ARG(wiphy), ret); + return ret; + } + + return 0; + +err_out: + if (skb) + nlmsg_free(skb); + return ret; +} + +#ifdef CONFIG_DFS_MASTER +static int _rtw_nlrtw_radar_event(_adapter *adapter, enum nlrtw_radar_event evt_type, u8 cch, u8 bw) +{ + struct sk_buff *skb = NULL; + void *msg_header = NULL; + struct wiphy *wiphy; + u8 i; + int ret; + + wiphy = adapter_to_wiphy(adapter); + if (!wiphy) { + ret = -EINVAL; + goto err_out; + } + + /* allocate memory */ + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) { + ret = -ENOMEM; + goto err_out; + } + + /* create the message headers */ + msg_header = genlmsg_put(skb, 0, 0, &nlrtw_genl_family, 0, NLRTW_CMD_RADAR_EVENT); + if (!msg_header) { + ret = -ENOMEM; + goto err_out; + } + + /* add attributes */ + ret = nla_put_string(skb, NLRTW_ATTR_WIPHY_NAME, wiphy_name(wiphy)); + if (ret) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_ATTR_RADAR_EVENT, (uint8_t)evt_type); + if (ret != 0) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_ATTR_CHANNEL_CENTER, cch); + if (ret != 0) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_ATTR_CHANNEL_WIDTH, bw); + if (ret != 0) + goto err_out; + + /* finalize the message */ + genlmsg_end(skb, msg_header); + + ret = nlrtw_multicast(&nlrtw_genl_family, skb, 0, NLRTW_MCGRP_DEFAULT, GFP_KERNEL); + if (ret == -ESRCH) { + RTW_DBG(FUNC_WIPHY_FMT" return -ESRCH(No such process)." + " Maybe no process waits for this msg\n", FUNC_WIPHY_ARG(wiphy)); + return ret; + } else if (ret != 0) { + RTW_WARN(FUNC_WIPHY_FMT" return %d\n", FUNC_WIPHY_ARG(wiphy), ret); + return ret; + } + + return 0; + +err_out: + if (skb) + nlmsg_free(skb); + return ret; +} + +int rtw_nlrtw_radar_detect_event(_adapter *adapter, u8 cch, u8 bw) +{ + return _rtw_nlrtw_radar_event(adapter, NLRTW_RADAR_DETECTED, cch, bw); +} + +int rtw_nlrtw_cac_finish_event(_adapter *adapter, u8 cch, u8 bw) +{ + return _rtw_nlrtw_radar_event(adapter, NLRTW_RADAR_CAC_FINISHED, cch, bw); +} + +int rtw_nlrtw_cac_abort_event(_adapter *adapter, u8 cch, u8 bw) +{ + return _rtw_nlrtw_radar_event(adapter, NLRTW_RADAR_CAC_ABORTED, cch, bw); +} + +int rtw_nlrtw_nop_finish_event(_adapter *adapter, u8 cch, u8 bw) +{ + return _rtw_nlrtw_radar_event(adapter, NLRTW_RADAR_NOP_FINISHED, cch, bw); +} + +int rtw_nlrtw_nop_start_event(_adapter *adapter, u8 cch, u8 bw) +{ + return _rtw_nlrtw_radar_event(adapter, NLRTW_RADAR_NOP_STARTED, cch, bw); +} +#endif /* CONFIG_DFS_MASTER */ + +int rtw_nlrtw_radio_opmode_notify(struct rf_ctl_t *rfctl) +{ + struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl); + _adapter *iface; + struct sk_buff *skb = NULL; + void *msg_header = NULL; + struct nlattr *nl_if_opmodes, *nl_if_opmode; + struct wiphy *wiphy; + u16 op_txpwr_max_u16; + u8 i; + int ret; + + wiphy = dvobj_to_wiphy(dvobj); + if (!wiphy) { + ret = -EINVAL; + goto err_out; + } + + /* allocate memory */ + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) { + ret = -ENOMEM; + goto err_out; + } + + /* create the message headers */ + msg_header = genlmsg_put(skb, 0, 0, &nlrtw_genl_family, 0, NLRTW_CMD_RADIO_OPMODE); + if (!msg_header) { + ret = -ENOBUFS; + goto err_out; + } + + /* add attributes */ + ret = nla_put_string(skb, NLRTW_ATTR_WIPHY_NAME, wiphy_name(wiphy)); + if (ret) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_ATTR_OP_CLASS, rfctl->op_class); + if (ret != 0) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_ATTR_OP_CHANNEL, rfctl->op_ch); + if (ret != 0) + goto err_out; + + *((s16 *)&op_txpwr_max_u16) = rfctl->op_txpwr_max; + ret = nla_put_u16(skb, NLRTW_ATTR_OP_TXPWR_MAX, op_txpwr_max_u16); + if (ret != 0) + goto err_out; + + if (0) + RTW_INFO("radio: %u,%u %d\n", rfctl->op_class, rfctl->op_ch, rfctl->op_txpwr_max); + + nl_if_opmodes = nla_nest_start(skb, NLRTW_ATTR_IF_OPMODES); + if (!nl_if_opmodes) { + ret = -ENOBUFS; + goto err_out; + } + + for (i = 0; i < dvobj->iface_nums; i++) { + if (!dvobj->padapters[i]) + continue; + iface = dvobj->padapters[i]; + + if (!rfctl->if_op_class[i] || !rfctl->if_op_ch[i]) + continue; + + if (0) + RTW_INFO(ADPT_FMT": %u,%u\n", ADPT_ARG(iface), rfctl->if_op_class[i], rfctl->if_op_ch[i]); + + nl_if_opmode = nla_nest_start(skb, i + 1); + if (!nl_if_opmode) { + ret = -ENOBUFS; + goto err_out; + } + + ret = nla_put(skb, NLRTW_IF_OPMODE_MACADDR, ETH_ALEN, adapter_mac_addr(iface)); + if (ret != 0) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_IF_OPMODE_OP_CLASS, rfctl->if_op_class[i]); + if (ret != 0) + goto err_out; + + ret = nla_put_u8(skb, NLRTW_IF_OPMODE_OP_CHANNEL, rfctl->if_op_ch[i]); + if (ret != 0) + goto err_out; + + nla_nest_end(skb, nl_if_opmode); + } + + nla_nest_end(skb, nl_if_opmodes); + + /* finalize the message */ + genlmsg_end(skb, msg_header); + + ret = nlrtw_multicast(&nlrtw_genl_family, skb, 0, NLRTW_MCGRP_DEFAULT, GFP_KERNEL); + if (ret == -ESRCH) { + RTW_DBG(FUNC_WIPHY_FMT" return -ESRCH(No such process)." + " Maybe no process waits for this msg\n", FUNC_WIPHY_ARG(wiphy)); + return ret; + } else if (ret != 0) { + RTW_WARN(FUNC_WIPHY_FMT" return %d\n", FUNC_WIPHY_ARG(wiphy), ret); + return ret; + } + + return 0; + +err_out: + if (skb) + nlmsg_free(skb); + return ret; +} + +int rtw_nlrtw_init(void) +{ + int err; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) + err = genl_register_family(&nlrtw_genl_family); + if (err) + return err; +#else + err = genl_register_family_with_ops(&nlrtw_genl_family, nlrtw_genl_ops, ARRAY_SIZE(nlrtw_genl_ops)); + if (err) + return err; + + err = genl_register_mc_group(&nlrtw_genl_family, &nlrtw_genl_mcgrp[0]); + if (err) { + genl_unregister_family(&nlrtw_genl_family); + return err; + } +#endif + RTW_INFO("[%s] %s\n", __func__, nlrtw_genl_family.name); + return 0; +} + +int rtw_nlrtw_deinit(void) +{ + int err; + + err = genl_unregister_family(&nlrtw_genl_family); + RTW_INFO("[%s] err = %d\n", __func__, err); + + return err; +} +#endif /* CONFIG_RTW_NLRTW */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/nlrtw.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/nlrtw.h new file mode 100644 index 000000000000..97ed7955e300 --- /dev/null +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/nlrtw.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/****************************************************************************** + * + * Copyright(c) 2007 - 2020 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + *****************************************************************************/ +#ifndef __RTW_NLRTW_H_ +#define __RTW_NLRTW_H_ + +#ifdef CONFIG_RTW_NLRTW +int rtw_nlrtw_init(void); +int rtw_nlrtw_deinit(void); +int rtw_nlrtw_ch_util_rpt(_adapter *adapter, u8 n_rpts, u8 *val, u8 **mac_addr); +int rtw_nlrtw_reg_change_event(_adapter *adapter); +int rtw_nlrtw_reg_beacon_hint_event(_adapter *adapter); +int rtw_nlrtw_radio_opmode_notify(struct rf_ctl_t *rfctl); +#else +static inline int rtw_nlrtw_init(void) {return _FAIL;} +static inline int rtw_nlrtw_deinit(void) {return _FAIL;} +static inline int rtw_nlrtw_ch_util_rpt(_adapter *adapter, u8 n_rpts, u8 *val, u8 **mac_addr) {return _FAIL;} +static inline int rtw_nlrtw_reg_change_event(_adapter *adapter) {return _FAIL;} +static inline int rtw_nlrtw_reg_beacon_hint_event(_adapter *adapter) {return _FAIL;} +static inline int rtw_nlrtw_radio_opmode_notify(struct rf_ctl_t *rfctl) {return _FAIL;} +#endif /* CONFIG_RTW_NLRTW */ + +#if defined(CONFIG_RTW_NLRTW) && defined(CONFIG_DFS_MASTER) +int rtw_nlrtw_radar_detect_event(_adapter *adapter, u8 cch, u8 bw); +int rtw_nlrtw_cac_finish_event(_adapter *adapter, u8 cch, u8 bw); +int rtw_nlrtw_cac_abort_event(_adapter *adapter, u8 cch, u8 bw); +int rtw_nlrtw_nop_finish_event(_adapter *adapter, u8 cch, u8 bw); +int rtw_nlrtw_nop_start_event(_adapter *adapter, u8 cch, u8 bw); +#else +static inline int rtw_nlrtw_radar_detect_event(_adapter *adapter, u8 cch, u8 bw) {return _FAIL;} +static inline int rtw_nlrtw_cac_finish_event(_adapter *adapter, u8 cch, u8 bw) {return _FAIL;} +static inline int rtw_nlrtw_cac_abort_event(_adapter *adapter, u8 cch, u8 bw) {return _FAIL;} +static inline int rtw_nlrtw_nop_finish_event(_adapter *adapter, u8 cch, u8 bw) {return _FAIL;} +static inline int rtw_nlrtw_nop_start_event(_adapter *adapter, u8 cch, u8 bw) {return _FAIL;} +#endif /* defined(CONFIG_RTW_NLRTW) && defined(CONFIG_DFS_MASTER) */ + +#endif /* __RTW_NLRTW_H_ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/os_intfs.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/os_intfs.c index e6452db81056..4c20e113d673 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/os_intfs.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/os_intfs.c @@ -210,12 +210,14 @@ static uint rtw_tx_aclt_conf_default_num = 0; module_param_array(rtw_tx_aclt_conf_default, uint, &rtw_tx_aclt_conf_default_num, 0644); MODULE_PARM_DESC(rtw_tx_aclt_conf_default, "device TX AC queue lifetime config for default status"); -#ifdef CONFIG_TX_MCAST2UNI +#ifdef CONFIG_AP_MODE +#if CONFIG_RTW_AP_DATA_BMC_TO_UC static uint rtw_tx_aclt_conf_ap_m2u[3] = CONFIG_TX_ACLT_CONF_AP_M2U; static uint rtw_tx_aclt_conf_ap_m2u_num = 0; module_param_array(rtw_tx_aclt_conf_ap_m2u, uint, &rtw_tx_aclt_conf_ap_m2u_num, 0644); MODULE_PARM_DESC(rtw_tx_aclt_conf_ap_m2u, "device TX AC queue lifetime config for AP mode M2U status"); #endif +#endif /* CONFIG_AP_MODE */ #ifdef CONFIG_RTW_MESH static uint rtw_tx_aclt_conf_mesh[3] = CONFIG_TX_ACLT_CONF_MESH; @@ -291,8 +293,12 @@ int rtw_short_gi = 0xf; /* BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx */ int rtw_ldpc_cap = 0x33; /* BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx */ +#ifdef CONFIG_RTL8192F +int rtw_stbc_cap = 0x30; +#else int rtw_stbc_cap = 0x13; - +#endif +module_param(rtw_stbc_cap, int, 0644); /* * BIT0: Enable VHT SU Beamformer * BIT1: Enable VHT SU Beamformee @@ -311,6 +317,9 @@ int rtw_bfee_rf_number = 0; /*BeamformeeCapRfNum Rf path number, 0 for auto, ot int rtw_vht_enable = 1; /* 0:disable, 1:enable, 2:force auto enable */ module_param(rtw_vht_enable, int, 0644); +int rtw_vht_24g_enable = 1; /* 0:disable, 1:enable */ +module_param(rtw_vht_24g_enable, int, 0644); + int rtw_ampdu_factor = 7; uint rtw_vht_rx_mcs_map = 0xaaaa; @@ -318,8 +327,6 @@ module_param(rtw_vht_rx_mcs_map, uint, 0644); MODULE_PARM_DESC(rtw_vht_rx_mcs_map, "VHT RX MCS map"); #endif /* CONFIG_80211AC_VHT */ -int rtw_lowrate_two_xmit = 1;/* Use 2 path Tx to transmit MCS0~7 and legacy mode */ - /* 0: not check in watch dog, 1: check in watch dog */ int rtw_check_hw_status = 0; @@ -352,6 +359,12 @@ module_param(rtw_rx_path_lmt, int, 0644); /* limit of RX path number, 0: not spe module_param(rtw_tx_nss, int, 0644); module_param(rtw_rx_nss, int, 0644); +#ifdef CONFIG_REGD_SRC_FROM_OS +static uint rtw_regd_src = CONFIG_RTW_REGD_SRC; +module_param(rtw_regd_src, uint, 0644); +MODULE_PARM_DESC(rtw_regd_src, "The default regd source selection, 0:Realtek defined, 1: OS"); +#endif + char rtw_country_unspecified[] = {0xFF, 0xFF, 0x00}; char *rtw_country_code = rtw_country_unspecified; module_param(rtw_country_code, charp, 0644); @@ -421,10 +434,6 @@ int rtw_hw_wps_pbc = 1; int rtw_hw_wps_pbc = 0; #endif -#ifdef CONFIG_TX_MCAST2UNI -int rtw_mc2u_disable = 0; -#endif /* CONFIG_TX_MCAST2UNI */ - #ifdef CONFIG_80211D int rtw_80211d = 0; #endif @@ -503,16 +512,41 @@ char *rtw_initmac = 0; /* temp mac address if users want to use instead of the #endif #ifdef CONFIG_P2P + + #ifdef CONFIG_SEL_P2P_IFACE + int rtw_sel_p2p_iface = CONFIG_SEL_P2P_IFACE; + #else int rtw_sel_p2p_iface = IFACE_ID1; + #endif module_param(rtw_sel_p2p_iface, int, 0644); #endif #endif + #ifdef CONFIG_AP_MODE u8 rtw_bmc_tx_rate = MGN_UNKNOWN; -#endif + +#if CONFIG_RTW_AP_DATA_BMC_TO_UC +int rtw_ap_src_b2u_flags = CONFIG_RTW_AP_SRC_B2U_FLAGS; +module_param(rtw_ap_src_b2u_flags, int, 0644); + +int rtw_ap_fwd_b2u_flags = CONFIG_RTW_AP_FWD_B2U_FLAGS; +module_param(rtw_ap_fwd_b2u_flags, int, 0644); +#endif /* CONFIG_RTW_AP_DATA_BMC_TO_UC */ +#endif /* CONFIG_AP_MODE */ + +#ifdef CONFIG_RTW_MESH +#if CONFIG_RTW_MESH_DATA_BMC_TO_UC +int rtw_msrc_b2u_flags = CONFIG_RTW_MSRC_B2U_FLAGS; +module_param(rtw_msrc_b2u_flags, int, 0644); + +int rtw_mfwd_b2u_flags = CONFIG_RTW_MFWD_B2U_FLAGS; +module_param(rtw_mfwd_b2u_flags, int, 0644); +#endif /* CONFIG_RTW_MESH_DATA_BMC_TO_UC */ +#endif /* CONFIG_RTW_MESH */ + #ifdef RTW_WOW_STA_MIX int rtw_wowlan_sta_mix_mode = 1; #else @@ -550,7 +584,6 @@ module_param(rtw_quick_addba_req, int, 0644); #ifdef CONFIG_BEAMFORMING module_param(rtw_beamform_cap, int, 0644); #endif -module_param(rtw_lowrate_two_xmit, int, 0644); module_param(rtw_power_mgnt, int, 0644); module_param(rtw_smart_ps, int, 0644); @@ -614,10 +647,6 @@ MODULE_PARM_DESC(rtw_fw_mp_bt_file_path, "The path of fw for MP-BT image"); #endif /* CONFIG_MP_INCLUDED */ #endif /* CONFIG_FILE_FWIMG */ -#ifdef CONFIG_TX_MCAST2UNI -module_param(rtw_mc2u_disable, int, 0644); -#endif /* CONFIG_TX_MCAST2UNI */ - #ifdef CONFIG_80211D module_param(rtw_80211d, int, 0644); MODULE_PARM_DESC(rtw_80211d, "Enable 802.11d mechanism"); @@ -658,7 +687,7 @@ MODULE_PARM_DESC(rtw_adaptivity_th_edcca_hl_diff, "th_edcca_hl_diff for Adaptivi #ifdef CONFIG_DFS_MASTER uint rtw_dfs_region_domain = CONFIG_RTW_DFS_REGION_DOMAIN; module_param(rtw_dfs_region_domain, uint, 0644); -MODULE_PARM_DESC(rtw_dfs_region_domain, "0:UNKNOWN, 1:FCC, 2:MKK, 3:ETSI"); +MODULE_PARM_DESC(rtw_dfs_region_domain, "0:NONE, 1:FCC, 2:MKK, 3:ETSI"); #endif uint rtw_amplifier_type_2g = CONFIG_RTW_AMPLIFIER_TYPE_2G; @@ -769,6 +798,10 @@ module_param_array(rtw_target_tx_pwr_5g_d, int, &rtw_target_tx_pwr_5g_d_num, 064 MODULE_PARM_DESC(rtw_target_tx_pwr_5g_d, "5G target tx power (unit:dBm) of RF path D for each rate section, should match the real calibrate power, -1: undefined"); #endif /* CONFIG_IEEE80211_BAND_5GHZ */ +int rtw_antenna_gain = CONFIG_RTW_ANTENNA_GAIN; +module_param(rtw_antenna_gain, int, 0644); +MODULE_PARM_DESC(rtw_antenna_gain, "Antenna gain in mBi. 0x7FFF: unspecifed"); + #ifdef CONFIG_RTW_TX_NPATH_EN /*0:disable ,1: 2path*/ int rtw_tx_npath_enable = 1; @@ -812,6 +845,10 @@ module_param(rtw_decrypt_phy_file, int, 0644); MODULE_PARM_DESC(rtw_decrypt_phy_file, "Enable Decrypt PHY File"); #endif +uint rtw_recvbuf_nr = NR_RECVBUFF; +module_param(rtw_recvbuf_nr, int, 0644); +MODULE_PARM_DESC(rtw_recvbuf_nr, "Preallocated number of struct recv_buf"); + #ifdef CONFIG_SUPPORT_TRX_SHARED #ifdef DFT_TRX_SHARE_MODE int rtw_trx_share_mode = DFT_TRX_SHARE_MODE; @@ -990,6 +1027,15 @@ uint rtw_8822c_xcap_overwrite = 1; module_param(rtw_8822c_xcap_overwrite, uint, 0644); #endif +#ifdef CONFIG_RTW_MULTI_AP +static int rtw_unassoc_sta_mode_of_stype[UNASOC_STA_SRC_NUM] = CONFIG_RTW_UNASOC_STA_MODE_OF_STYPE; +static int rtw_unassoc_sta_mode_of_stype_num = 0; +module_param_array(rtw_unassoc_sta_mode_of_stype, int, &rtw_unassoc_sta_mode_of_stype_num, 0644); + +uint rtw_max_unassoc_sta_cnt = 0; +module_param(rtw_max_unassoc_sta_cnt, uint, 0644); +#endif + #if CONFIG_TX_AC_LIFETIME static void rtw_regsty_load_tx_ac_lifetime(struct registry_priv *regsty) { @@ -1003,10 +1049,12 @@ static void rtw_regsty_load_tx_ac_lifetime(struct registry_priv *regsty) conf = ®sty->tx_aclt_confs[i]; if (i == TX_ACLT_CONF_DEFAULT) parm = rtw_tx_aclt_conf_default; - #ifdef CONFIG_TX_MCAST2UNI + #ifdef CONFIG_AP_MODE + #if CONFIG_RTW_AP_DATA_BMC_TO_UC else if (i == TX_ACLT_CONF_AP_M2U) parm = rtw_tx_aclt_conf_ap_m2u; #endif + #endif /* CONFIG_AP_MODE */ #ifdef CONFIG_RTW_MESH else if (i == TX_ACLT_CONF_MESH) parm = rtw_tx_aclt_conf_mesh; @@ -1094,6 +1142,18 @@ inline void rtw_regsty_init_rx_ampdu_sz_limit(struct registry_priv *regsty) } #endif /* CONFIG_80211N_HT */ +#ifdef CONFIG_RTW_MULTI_AP +inline void rtw_regsty_init_unassoc_sta_param(struct registry_priv *regsty) +{ + int i; + + for (i = 0; i < UNASOC_STA_SRC_NUM; i++) + regsty->unassoc_sta_mode_of_stype[i] = rtw_unassoc_sta_mode_of_stype[i]; + + regsty->max_unassoc_sta_cnt = (u16) rtw_max_unassoc_sta_cnt; +} +#endif + uint loadparam(_adapter *padapter) { uint status = _SUCCESS; @@ -1236,6 +1296,7 @@ uint loadparam(_adapter *padapter) #ifdef CONFIG_80211AC_VHT registry_par->vht_enable = (u8)rtw_vht_enable; + registry_par->vht_24g_enable = (u8)rtw_vht_24g_enable; registry_par->ampdu_factor = (u8)rtw_ampdu_factor; registry_par->vht_rx_mcs_map[0] = (u8)(rtw_vht_rx_mcs_map & 0xFF); registry_par->vht_rx_mcs_map[1] = (u8)((rtw_vht_rx_mcs_map & 0xFF00) >> 8); @@ -1244,7 +1305,6 @@ uint loadparam(_adapter *padapter) #ifdef CONFIG_TX_EARLY_MODE registry_par->early_mode = (u8)rtw_early_mode; #endif - registry_par->lowrate_two_xmit = (u8)rtw_lowrate_two_xmit; registry_par->trx_path_bmp = (u8)rtw_trx_path_bmp; registry_par->tx_path_lmt = (u8)rtw_tx_path_lmt; registry_par->rx_path_lmt = (u8)rtw_rx_path_lmt; @@ -1256,6 +1316,15 @@ uint loadparam(_adapter *padapter) registry_par->wifi_spec = (u8)rtw_wifi_spec; +#ifdef CONFIG_REGD_SRC_FROM_OS + if (regd_src_is_valid(rtw_regd_src)) + registry_par->regd_src = (u8)rtw_regd_src; + else { + RTW_WARN("%s invalid rtw_regd_src(%u), use REGD_SRC_RTK_PRIV instead\n", __func__, rtw_regd_src); + registry_par->regd_src = REGD_SRC_RTK_PRIV; + } +#endif + if (strlen(rtw_country_code) != 2 || is_alpha(rtw_country_code[0]) == _FALSE || is_alpha(rtw_country_code[1]) == _FALSE @@ -1332,6 +1401,8 @@ uint loadparam(_adapter *padapter) rtw_regsty_load_target_tx_power(registry_par); + registry_par->antenna_gain = (s16)rtw_antenna_gain; + registry_par->tsf_update_pause_factor = (u8)rtw_tsf_update_pause_factor; registry_par->tsf_update_restore_factor = (u8)rtw_tsf_update_restore_factor; @@ -1382,6 +1453,12 @@ uint loadparam(_adapter *padapter) #ifdef CONFIG_DFS_MASTER registry_par->dfs_region_domain = (u8)rtw_dfs_region_domain; + #ifdef CONFIG_REGD_SRC_FROM_OS + if (rtw_regd_src == REGD_SRC_OS && registry_par->dfs_region_domain != RTW_DFS_REGD_NONE) { + RTW_WARN("%s force disable radar detection capability when regd_src is OS\n", __func__); + registry_par->dfs_region_domain = RTW_DFS_REGD_NONE; + } + #endif #endif #ifdef CONFIG_MCC_MODE @@ -1405,6 +1482,14 @@ uint loadparam(_adapter *padapter) registry_par->suspend_type = rtw_suspend_type; #endif +#if defined(CONFIG_SDIO_HCI) && defined(CONFIG_PREALLOC_RX_SKB_BUFFER) + if (rtw_recvbuf_nr != NR_RECVBUFF) { + RTW_WARN("CONFIG_PREALLOC_RX_SKB_BUFFER && CONFIG_SDIO_HCI, force recvbuf_nr to NR_RECVBUFF(%d)\n", NR_RECVBUFF); + rtw_recvbuf_nr = NR_RECVBUFF; + } +#endif + registry_par->recvbuf_nr = rtw_recvbuf_nr; + #ifdef CONFIG_SUPPORT_TRX_SHARED registry_par->trx_share_mode = rtw_trx_share_mode; #endif @@ -1444,7 +1529,19 @@ uint loadparam(_adapter *padapter) #endif #ifdef CONFIG_AP_MODE registry_par->bmc_tx_rate = rtw_bmc_tx_rate; -#endif + #if CONFIG_RTW_AP_DATA_BMC_TO_UC + registry_par->ap_src_b2u_flags = rtw_ap_src_b2u_flags; + registry_par->ap_fwd_b2u_flags = rtw_ap_fwd_b2u_flags; + #endif +#endif /* CONFIG_AP_MODE */ + +#ifdef CONFIG_RTW_MESH + #if CONFIG_RTW_MESH_DATA_BMC_TO_UC + registry_par->msrc_b2u_flags = rtw_msrc_b2u_flags; + registry_par->mfwd_b2u_flags = rtw_mfwd_b2u_flags; + #endif +#endif /* CONFIG_RTW_MESH */ + #ifdef CONFIG_FW_HANDLE_TXBCN registry_par->fw_tbtt_rpt = rtw_tbtt_rpt; #endif @@ -1462,6 +1559,10 @@ uint loadparam(_adapter *padapter) registry_par->rtw_8822c_xcap_overwrite = (u8)rtw_8822c_xcap_overwrite; #endif +#ifdef CONFIG_RTW_MULTI_AP + rtw_regsty_init_unassoc_sta_param(registry_par); +#endif + return status; } @@ -1608,7 +1709,7 @@ static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb #else , void *accel_priv #endif - #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) + #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0))) , select_queue_fallback_t fallback #endif #endif @@ -1624,36 +1725,29 @@ static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb return rtw_1d_to_queue[skb->priority]; } +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) */ -u16 rtw_recv_select_queue(struct sk_buff *skb) +u16 rtw_os_recv_select_queue(u8 *msdu, enum rtw_rx_llc_hdl llc_hdl) { - struct iphdr *piphdr; - unsigned int dscp; - u16 eth_type; - u32 priority; - u8 *pdata = skb->data; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) + u32 priority = 0; - _rtw_memcpy(ð_type, pdata + (ETH_ALEN << 1), 2); + if (llc_hdl == RTW_RX_LLC_REMOVE) { + u16 eth_type = RTW_GET_BE16(msdu + SNAP_SIZE); - switch (eth_type) { - case htons(ETH_P_IP): + if (eth_type == ETH_P_IP) { + struct iphdr *iphdr = (struct iphdr *)(msdu + SNAP_SIZE + 2); + unsigned int dscp = iphdr->tos & 0xfc; - piphdr = (struct iphdr *)(pdata + ETH_HLEN); - - dscp = piphdr->tos & 0xfc; - - priority = dscp >> 5; - - break; - default: - priority = 0; + priority = dscp >> 5; + } } return rtw_1d_to_queue[priority]; - -} - +#else + return 0; #endif +} static u8 is_rtw_ndev(struct net_device *ndev) { @@ -1914,18 +2008,122 @@ void rtw_os_ndev_free(_adapter *adapter) rtw_cfg80211_ndev_res_free(adapter); #endif - /* free the old_pnetdev */ - if (adapter->rereg_nd_name_priv.old_pnetdev) { - rtw_free_netdev(adapter->rereg_nd_name_priv.old_pnetdev); - adapter->rereg_nd_name_priv.old_pnetdev = NULL; - } - if (adapter->pnetdev) { rtw_free_netdev(adapter->pnetdev); adapter->pnetdev = NULL; } } +/* For ethtool +++ */ +#ifdef CONFIG_IOCTL_CFG80211 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 8)) +static void rtw_ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct wireless_dev *wdev = NULL; + _adapter *padapter = NULL; + HAL_DATA_TYPE *hal_data = NULL; + + wdev = dev->ieee80211_ptr; + if (wdev) { + strlcpy(info->driver, wiphy_dev(wdev->wiphy)->driver->name, + sizeof(info->driver)); + } else { + strlcpy(info->driver, "N/A", sizeof(info->driver)); + } + + strlcpy(info->version, DRIVERVERSION, sizeof(info->version)); + + padapter = (_adapter *)rtw_netdev_priv(dev); + if (padapter) { + hal_data = GET_HAL_DATA(padapter); + } + + if (hal_data) { + scnprintf(info->fw_version, sizeof(info->fw_version), "%d.%d", + hal_data->firmware_version, hal_data->firmware_sub_version); + } else { + strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); + } + + strlcpy(info->bus_info, dev_name(wiphy_dev(wdev->wiphy)), + sizeof(info->bus_info)); +} + +static const char rtw_ethtool_gstrings_sta_stats[][ETH_GSTRING_LEN] = { + "rx_packets", "rx_bytes", "rx_dropped", + "tx_packets", "tx_bytes", "tx_dropped", +}; + +#define RTW_ETHTOOL_STATS_LEN ARRAY_SIZE(rtw_ethtool_gstrings_sta_stats) + +static int rtw_ethtool_get_sset_count(struct net_device *dev, int sset) +{ + int rv = 0; + + if (sset == ETH_SS_STATS) + rv += RTW_ETHTOOL_STATS_LEN; + + if (rv == 0) + return -EOPNOTSUPP; + + return rv; +} + +static void rtw_ethtool_get_strings(struct net_device *dev, u32 sset, u8 *data) +{ + int sz_sta_stats = 0; + + if (sset == ETH_SS_STATS) { + sz_sta_stats = sizeof(rtw_ethtool_gstrings_sta_stats); + memcpy(data, rtw_ethtool_gstrings_sta_stats, sz_sta_stats); + } +} + +static void rtw_ethtool_get_stats(struct net_device *dev, + struct ethtool_stats *stats, + u64 *data) +{ + int i = 0; + _adapter *padapter = NULL; + struct xmit_priv *pxmitpriv = NULL; + struct recv_priv *precvpriv = NULL; + + memset(data, 0, sizeof(u64) * RTW_ETHTOOL_STATS_LEN); + + padapter = (_adapter *)rtw_netdev_priv(dev); + if (padapter) { + pxmitpriv = &(padapter->xmitpriv); + precvpriv = &(padapter->recvpriv); + + data[i++] = precvpriv->rx_pkts; + data[i++] = precvpriv->rx_bytes; + data[i++] = precvpriv->rx_drop; + + data[i++] = pxmitpriv->tx_pkts; + data[i++] = pxmitpriv->tx_bytes; + data[i++] = pxmitpriv->tx_drop; + } else { + data[i++] = 0; + data[i++] = 0; + data[i++] = 0; + + data[i++] = 0; + data[i++] = 0; + data[i++] = 0; + } +} + +static const struct ethtool_ops rtw_ethtool_ops = { + .get_drvinfo = rtw_ethtool_get_drvinfo, + .get_link = ethtool_op_get_link, + .get_strings = rtw_ethtool_get_strings, + .get_ethtool_stats = rtw_ethtool_get_stats, + .get_sset_count = rtw_ethtool_get_sset_count, +}; +#endif // LINUX_VERSION_CODE >= 3.7.8 +#endif /* CONFIG_IOCTL_CFG80211 */ +/* For ethtool --- */ + int rtw_os_ndev_register(_adapter *adapter, const char *name) { struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); @@ -1943,6 +2141,10 @@ int rtw_os_ndev_register(_adapter *adapter, const char *name) ret = _FAIL; goto exit; } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 8)) + netdev_set_default_ethtool_ops(ndev, &rtw_ethtool_ops); +#endif /* LINUX_VERSION_CODE >= 3.7.8 */ #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && defined(CONFIG_PCI_HCI) ndev->gro_flush_timeout = 100000; @@ -2319,6 +2521,10 @@ u8 rtw_init_default_value(_adapter *padapter) padapter->rsvd_page_num = 0; #ifdef CONFIG_AP_MODE padapter->bmc_tx_rate = pregistrypriv->bmc_tx_rate; + #if CONFIG_RTW_AP_DATA_BMC_TO_UC + padapter->b2u_flags_ap_src = pregistrypriv->ap_src_b2u_flags; + padapter->b2u_flags_ap_fwd = pregistrypriv->ap_fwd_b2u_flags; + #endif #endif padapter->driver_tx_bw_mode = pregistrypriv->tx_bw_mode; @@ -2412,7 +2618,7 @@ struct dvobj_priv *devobj_init(void) #endif _rtw_spinlock_init(&pdvobj->cam_ctl.lock); _rtw_mutex_init(&pdvobj->cam_ctl.sec_cam_access_mutex); -#if defined(RTK_129X_PLATFORM) && defined(CONFIG_PCI_HCI) +#if defined(CONFIG_PLATFORM_RTK129X) && defined(CONFIG_PCI_HCI) _rtw_spinlock_init(&pdvobj->io_reg_lock); #endif #ifdef CONFIG_MBSSID_CAM @@ -2509,7 +2715,7 @@ void devobj_deinit(struct dvobj_priv *pdvobj) _rtw_spinlock_free(&pdvobj->cam_ctl.lock); _rtw_mutex_free(&pdvobj->cam_ctl.sec_cam_access_mutex); -#if defined(RTK_129X_PLATFORM) && defined(CONFIG_PCI_HCI) +#if defined(CONFIG_PLATFORM_RTK129X) && defined(CONFIG_PCI_HCI) _rtw_spinlock_free(&pdvobj->io_reg_lock); #endif #ifdef CONFIG_MBSSID_CAM @@ -2631,6 +2837,11 @@ u8 rtw_init_drv_sw(_adapter *padapter) dvobj->cam_ctl.num = rtw_min(hal_spec->sec_cam_ent_num, SEC_CAM_ENT_NUM_SW_LIMIT); dvobj->wow_ctl.wow_cap = hal_spec->wow_cap; + + #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT + dvobj->tx_aval_int_thr_mode = 2; /*setting by max tx length*/ + dvobj->tx_aval_int_thr_value = 0; + #endif /*CONFIG_SDIO_TX_ENABLE_AVAL_INT*/ #if CONFIG_TX_AC_LIFETIME { @@ -2669,9 +2880,6 @@ u8 rtw_init_drv_sw(_adapter *padapter) goto exit; } - if (is_primary_adapter(padapter)) - rtw_rfctl_init(padapter); - if (is_primary_adapter(padapter)) { if (rtw_hal_rfpath_init(padapter) == _FAIL) { ret8 = _FAIL; @@ -2681,6 +2889,14 @@ u8 rtw_init_drv_sw(_adapter *padapter) ret8 = _FAIL; goto exit; } + if (rtw_hal_runtime_trx_path_decision(padapter) == _FAIL) { + ret8 = _FAIL; + goto exit; + } + if (rtw_rfctl_init(padapter) == _FAIL) { + ret8 = _FAIL; + goto exit; + } } if (rtw_init_mlme_priv(padapter) == _FAIL) { @@ -2688,13 +2904,14 @@ u8 rtw_init_drv_sw(_adapter *padapter) goto exit; } +#if (defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)) || defined(CONFIG_IOCTL_CFG80211) + rtw_init_roch_info(padapter); +#endif + #ifdef CONFIG_P2P rtw_init_wifidirect_timers(padapter); init_wifidirect_info(padapter, P2P_ROLE_DISABLE); reset_global_wifidirect_info(padapter); - #ifdef CONFIG_IOCTL_CFG80211 - rtw_init_cfg80211_wifidirect_info(padapter); - #endif #ifdef CONFIG_WFD if (rtw_init_wifi_display_info(padapter) == _FAIL) RTW_ERR("Can't init init_wifi_display_info\n"); @@ -2768,6 +2985,10 @@ u8 rtw_init_drv_sw(_adapter *padapter) #endif rtw_hal_dm_init(padapter); + + if (is_primary_adapter(padapter)) + rtw_rfctl_chplan_init(padapter); + #ifdef CONFIG_RTW_SW_LED rtw_hal_sw_led_init(padapter); #endif @@ -2844,9 +3065,7 @@ void rtw_cancel_all_timer(_adapter *padapter) #endif #ifdef CONFIG_IOCTL_CFG80211 -#ifdef CONFIG_P2P - _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer); -#endif /* CONFIG_P2P */ + _cancel_timer_ex(&padapter->rochinfo.remain_on_ch_timer); #endif /* CONFIG_IOCTL_CFG80211 */ #ifdef CONFIG_SET_SCAN_DENY_TIMER @@ -2888,12 +3107,15 @@ u8 rtw_free_drv_sw(_adapter *padapter) #ifdef CONFIG_P2P { struct wifidirect_info *pwdinfo = &padapter->wdinfo; + #ifdef CONFIG_CONCURRENT_MODE + struct roch_info *prochinfo = &padapter->rochinfo; + #endif if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { _cancel_timer_ex(&pwdinfo->find_phase_timer); _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer); _cancel_timer_ex(&pwdinfo->pre_tx_scan_timer); #ifdef CONFIG_CONCURRENT_MODE - _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer); + _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer); #endif /* CONFIG_CONCURRENT_MODE */ rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE); } @@ -2935,6 +3157,13 @@ u8 rtw_free_drv_sw(_adapter *padapter) rtw_free_pwrctrl_priv(padapter); +#ifdef CONFIG_PLATFORM_CMAP_INTFS + if (padapter->cmap_bss_status_evt) { + cmap_intfs_mfree(padapter->cmap_bss_status_evt, padapter->cmap_bss_status_evt_len); + padapter->cmap_bss_status_evt = NULL; + } +#endif + /* rtw_mfree((void *)padapter, sizeof (padapter)); */ rtw_hal_free_data(padapter); @@ -3017,7 +3246,6 @@ int _netdev_vir_if_open(struct net_device *pnetdev) #endif #ifdef CONFIG_IOCTL_CFG80211 - rtw_cfg80211_init_wiphy(padapter); rtw_cfg80211_init_wdev_data(padapter); #endif @@ -3139,6 +3367,10 @@ _adapter *rtw_drv_add_vir_if(_adapter *primary_padapter, _adapter *padapter = NULL; struct dvobj_priv *pdvobjpriv; u8 mac[ETH_ALEN]; +#ifdef CONFIG_MI_UNIQUE_MACADDR_BIT + u32 mi_unique_macaddr_bit = 0; + u8 i; +#endif /****** init adapter ******/ padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter)); @@ -3162,6 +3394,8 @@ _adapter *rtw_drv_add_vir_if(_adapter *primary_padapter, #ifdef CONFIG_MI_WITH_MBSSID_CAM padapter->hw_port = HW_PORT0; +#elif defined(CONFIG_PORT_BASED_TXBCN) + padapter->hw_port = adapter_to_dvobj(padapter)->iface_nums; #else padapter->hw_port = HW_PORT1; #endif @@ -3188,6 +3422,27 @@ _adapter *rtw_drv_add_vir_if(_adapter *primary_padapter, /*get mac address from primary_padapter*/ _rtw_memcpy(mac, adapter_mac_addr(primary_padapter), ETH_ALEN); +#ifdef CONFIG_MI_UNIQUE_MACADDR_BIT + mi_unique_macaddr_bit = BIT(CONFIG_MI_UNIQUE_MACADDR_BIT) >> 24; + /* Find out CONFIG_MI_UNIQUE_MACADDR_BIT in which nic specific byte */ + for(i=3;i<6;i++) { + if((mi_unique_macaddr_bit >> 8) == 0) + break; + + mi_unique_macaddr_bit >>= 8; + } + + if((mac[i] & (u8)mi_unique_macaddr_bit)== 0) { + RTW_INFO("%s() "MAC_FMT" : BIT%u is zero\n", __func__, MAC_ARG(mac), CONFIG_MI_UNIQUE_MACADDR_BIT); + /* IFACE_ID1/IFACE_ID3 : set locally administered bit */ + if(padapter->iface_id & BIT(0)) + mac[0] |= BIT(1); + /* IFACE_ID2/IFACE_ID3 : set bit(CONFIG_MI_UNIQUE_MACADDR_BIT) */ + if(padapter->iface_id >> 1) + mac[i] |= (u8)mi_unique_macaddr_bit; + } else +#endif + { /* * If the BIT1 is 0, the address is universally administered. * If it is 1, the address is locally administered @@ -3195,6 +3450,7 @@ _adapter *rtw_drv_add_vir_if(_adapter *primary_padapter, mac[0] |= BIT(1); if (padapter->iface_id > IFACE_ID1) mac[0] ^= ((padapter->iface_id)<<2); + } _rtw_memcpy(adapter_mac_addr(padapter), mac, ETH_ALEN); /* update mac-address to mbsid-cam cache*/ @@ -3646,7 +3902,6 @@ int _netdev_open(struct net_device *pnetdev) #endif #ifdef CONFIG_IOCTL_CFG80211 - rtw_cfg80211_init_wiphy(padapter); rtw_cfg80211_init_wdev_data(padapter); #endif /* rtw_netif_carrier_on(pnetdev); */ /* call this func when rtw_joinbss_event_callback return success */ @@ -3748,7 +4003,6 @@ int _netdev_open(struct net_device *pnetdev) #endif /* !RTW_HALMAC */ #ifdef CONFIG_IOCTL_CFG80211 - rtw_cfg80211_init_wiphy(padapter); rtw_cfg80211_init_wdev_data(padapter); #endif @@ -4515,7 +4769,7 @@ void rtw_dev_unload(PADAPTER padapter) #ifdef CONFIG_GPIO_WAKEUP /*default wake up pin change to BT*/ RTW_INFO("%s:default wake up pin change to BT\n", __FUNCTION__); - rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _FALSE); + rtw_hal_switch_gpio_wl_ctrl(padapter, pwrctl->wowlan_gpio_index, _FALSE); #endif /* CONFIG_GPIO_WAKEUP */ #endif /* CONFIG_WOWLAN */ @@ -4635,6 +4889,11 @@ int rtw_suspend_wow(_adapter *padapter) struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); struct wowlan_ioctl_param poidparam; int ret = _SUCCESS; + u8 en = _TRUE, i; + struct registry_priv *registry_par = &padapter->registrypriv; + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + _adapter *iface = NULL; + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); RTW_INFO("==> "FUNC_ADPT_FMT" entry....\n", FUNC_ADPT_ARG(padapter)); @@ -4661,7 +4920,28 @@ int rtw_suspend_wow(_adapter *padapter) /* 2.1 clean interrupt */ rtw_hal_clear_interrupt(padapter); #endif /* CONFIG_SDIO_HCI */ - + + /* enable ac lifetime during scan to avoid txfifo not empty. */ + dvobj->lifetime_en = rtw_read8(padapter, 0x426); + dvobj->pkt_lifetime = rtw_read32(padapter, 0x4c0); + rtw_write8(padapter, 0x426, rtw_read8(padapter, 0x426) | 0x0f); + if(hal_spec->tx_aclt_unit_factor == 1) { + rtw_write16(padapter, 0x4c0, 0x1000); // unit: 32us. 131ms + rtw_write16(padapter, 0x4c0 + 2 , 0x1000); // unit: 32us. 131ms + } else { + rtw_write16(padapter, 0x4c0, 0x0200); // unit: 256us. 131ms + rtw_write16(padapter, 0x4c0 + 2 , 0x0200); // unit: 256us. 131ms + } + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if ((iface) && rtw_is_adapter_up(iface)) { + rtw_write_port_cancel(iface); + RTW_INFO(ADPT_FMT " write port cancel\n", ADPT_ARG(iface)); + } + } + RTW_INFO("lifetime_en=%x, pkt_lifetime=%x\n", rtw_read8(padapter, 0x426), rtw_read32(padapter, 0x4c0)); + rtw_msleep_os(200); + /* 1. stop thread */ rtw_set_drv_stopped(padapter); /*for stop thread*/ rtw_mi_stop_drv_threads(padapter); @@ -4685,8 +4965,11 @@ int rtw_suspend_wow(_adapter *padapter) rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL); } #endif - + if(registry_par->suspend_type == FW_IPS_WRC) + rtw_hal_set_hwreg(padapter, HW_VAR_VENDOR_WOW_MODE, &en); +#ifdef CONFIG_LPS rtw_wow_lps_level_decide(padapter, _TRUE); +#endif poidparam.subcode = WOWLAN_ENABLE; rtw_hal_set_hwreg(padapter, HW_VAR_WOWLAN, (u8 *)&poidparam); if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) { @@ -4710,7 +4993,6 @@ int rtw_suspend_wow(_adapter *padapter) clr_fwstate(pmlmepriv, WIFI_UNDER_SURVEY); } -#if 1 if (rtw_mi_check_status(padapter, MI_LINKED)) { ch = rtw_mi_get_union_chan(padapter); bw = rtw_mi_get_union_bw(padapter); @@ -4719,14 +5001,7 @@ int rtw_suspend_wow(_adapter *padapter) FUNC_ADPT_ARG(padapter), ch, bw, offset); set_channel_bwmode(padapter, ch, offset, bw); } -#else - if (rtw_mi_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { - RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", - FUNC_ADPT_ARG(padapter), ch, bw, offset); - set_channel_bwmode(padapter, ch, offset, bw); - rtw_mi_update_union_chan_inf(padapter, ch, offset, bw); - } -#endif + #ifdef CONFIG_CONCURRENT_MODE rtw_mi_buddy_suspend_free_assoc_resource(padapter); #endif @@ -4808,7 +5083,7 @@ int rtw_suspend_ap_wow(_adapter *padapter) rtw_hal_set_hwreg(padapter, HW_VAR_WOWLAN, (u8 *)&poidparam); RTW_PRINT("%s: wowmode suspending\n", __func__); -#if 1 + if (rtw_mi_check_status(padapter, MI_LINKED)) { ch = rtw_mi_get_union_chan(padapter); bw = rtw_mi_get_union_bw(padapter); @@ -4816,13 +5091,6 @@ int rtw_suspend_ap_wow(_adapter *padapter) RTW_INFO("back to linked/linking union - ch:%u, bw:%u, offset:%u\n", ch, bw, offset); set_channel_bwmode(padapter, ch, offset, bw); } -#else - if (rtw_mi_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { - RTW_INFO("back to linked/linking union - ch:%u, bw:%u, offset:%u\n", ch, bw, offset); - set_channel_bwmode(padapter, ch, offset, bw); - rtw_mi_update_union_chan_inf(padapter, ch, offset, bw); - } -#endif /*FOR ONE AP - TODO :Multi-AP*/ { @@ -4853,7 +5121,7 @@ int rtw_suspend_ap_wow(_adapter *padapter) RTW_INFO("<== "FUNC_ADPT_FMT" exit....\n", FUNC_ADPT_ARG(padapter)); return ret; } -#endif /* #ifdef CONFIG_AP_WOWLAN */ +#endif /* CONFIG_AP_WOWLAN */ int rtw_suspend_normal(_adapter *padapter) @@ -4996,6 +5264,7 @@ int rtw_resume_process_wow(_adapter *padapter) struct sta_info *psta = NULL; struct registry_priv *registry_par = &padapter->registrypriv; int ret = _SUCCESS; + u8 en = _FALSE; RTW_INFO("==> "FUNC_ADPT_FMT" entry....\n", FUNC_ADPT_ARG(padapter)); @@ -5031,6 +5300,9 @@ int rtw_resume_process_wow(_adapter *padapter) } #endif /* CONFIG_LPS */ + rtw_write8(padapter, 0x426, psdpriv->lifetime_en); + rtw_write32(padapter, 0x4c0, psdpriv->pkt_lifetime); + pwrpriv->bFwCurrentInPSMode = _FALSE; #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_PCI_HCI) @@ -5062,7 +5334,10 @@ int rtw_resume_process_wow(_adapter *padapter) rtw_clr_drv_stopped(padapter); RTW_INFO("%s: wowmode resuming, DriverStopped:%s\n", __func__, rtw_is_drv_stopped(padapter) ? "True" : "False"); - + + if(registry_par->suspend_type == FW_IPS_WRC) + rtw_hal_set_hwreg(padapter, HW_VAR_VENDOR_WOW_MODE, &en); + rtw_mi_start_drv_threads(padapter); rtw_mi_intf_start(padapter); @@ -5202,7 +5477,6 @@ int rtw_resume_process_ap_wow(_adapter *padapter) rtw_mi_start_drv_threads(padapter); -#if 1 if (rtw_mi_check_status(padapter, MI_LINKED)) { ch = rtw_mi_get_union_chan(padapter); bw = rtw_mi_get_union_bw(padapter); @@ -5210,13 +5484,6 @@ int rtw_resume_process_ap_wow(_adapter *padapter) RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", FUNC_ADPT_ARG(padapter), ch, bw, offset); set_channel_bwmode(padapter, ch, offset, bw); } -#else - if (rtw_mi_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { - RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", FUNC_ADPT_ARG(padapter), ch, bw, offset); - set_channel_bwmode(padapter, ch, offset, bw); - rtw_mi_update_union_chan_inf(padapter, ch, offset, bw); - } -#endif /*FOR ONE AP - TODO :Multi-AP*/ { @@ -5288,10 +5555,14 @@ void rtw_mi_resume_process_normal(_adapter *padapter) if (rtw_chk_roam_flags(iface, RTW_ROAM_ON_RESUME)) rtw_roaming(iface, NULL); - } else if (MLME_IS_AP(iface) || MLME_IS_MESH(iface)) { + } +#ifdef CONFIG_AP_MODE + else if (MLME_IS_AP(iface) || MLME_IS_MESH(iface)) { RTW_INFO(FUNC_ADPT_FMT" %s\n", FUNC_ADPT_ARG(iface), MLME_IS_AP(iface) ? "AP" : "MESH"); rtw_ap_restore_network(iface); - } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) + } +#endif + else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(iface), get_fwstate(pmlmepriv)); else RTW_INFO(FUNC_ADPT_FMT" fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(iface), get_fwstate(pmlmepriv)); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/recv_linux.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/recv_linux.c index 1c2a56541b9d..e0f7fe1976de 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/recv_linux.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/recv_linux.c @@ -209,8 +209,52 @@ void rtw_os_recv_resource_free(struct recv_priv *precvpriv) } } +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +#if !defined(CONFIG_RTL8822B) && !defined(CONFIG_RTL8822C) +#ifdef CONFIG_SDIO_RX_COPY +static int sdio_init_recvbuf_with_skb(struct recv_priv *recvpriv, struct recv_buf *rbuf, u32 size) +{ +#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER + if (RBUF_IS_PREALLOC(rbuf)) { + rbuf->pskb = rtw_alloc_skb_premem(size); + if (!rbuf->pskb) { + RTW_WARN("%s: Fail to get pre-alloc skb! size=%d\n", __func__, size); + return _FAIL; + } + skb_set_tail_pointer(rbuf->pskb, 0); /* TODO: do this in RTKM */ + } else +#else + { + SIZE_PTR tmpaddr = 0; + SIZE_PTR alignment = 0; + + rbuf->pskb = rtw_skb_alloc(size + RECVBUFF_ALIGN_SZ); + if (!rbuf->pskb) + return _FAIL; + + tmpaddr = (SIZE_PTR)rbuf->pskb->data; + alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); + skb_reserve(rbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); + } +#endif + + rbuf->pskb->dev = recvpriv->adapter->pnetdev; + + /* init recvbuf */ + rbuf->phead = rbuf->pskb->head; + rbuf->pdata = rbuf->pskb->data; + rbuf->ptail = skb_tail_pointer(rbuf->pskb); + rbuf->pend = skb_end_pointer(rbuf->pskb); + rbuf->len = 0; + + return _SUCCESS; +} +#endif /* CONFIG_SDIO_RX_COPY */ +#endif /* !defined(CONFIG_RTL8822B) && !defined(CONFIG_RTL8822C) */ +#endif /* defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) */ + /* alloc os related resource in struct recv_buf */ -int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf) +int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf, u32 size) { int res = _SUCCESS; @@ -236,13 +280,20 @@ int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf) precvbuf->len = 0; #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX - precvbuf->pallocated_buf = rtw_usb_buffer_alloc(pusbd, (size_t)precvbuf->alloc_sz, &precvbuf->dma_transfer_addr); + precvbuf->pallocated_buf = rtw_usb_buffer_alloc(pusbd, (size_t)size, &precvbuf->dma_transfer_addr); precvbuf->pbuf = precvbuf->pallocated_buf; if (precvbuf->pallocated_buf == NULL) return _FAIL; #endif /* CONFIG_USE_USB_BUFFER_ALLOC_RX */ -#endif /* CONFIG_USB_HCI */ +#elif defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + #if !defined(CONFIG_RTL8822B) && !defined(CONFIG_RTL8822C) + #ifdef CONFIG_SDIO_RX_COPY + res = sdio_init_recvbuf_with_skb(&padapter->recvpriv, precvbuf, size); + #endif + #endif + +#endif /* CONFIG_XXX_HCI */ return res; } @@ -283,9 +334,9 @@ int rtw_os_recvbuf_resource_free(_adapter *padapter, struct recv_buf *precvbuf) } -_pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, const u8 *da, const u8 *sa, u8 *msdu ,u16 msdu_len) +_pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, const u8 *da, const u8 *sa + , u8 *msdu ,u16 msdu_len, enum rtw_rx_llc_hdl llc_hdl) { - u16 eth_type; u8 *data_ptr; _pkt *sub_skb; struct rx_pkt_attrib *pattrib; @@ -312,13 +363,7 @@ _pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, const u8 *da, const u8 *s } } - eth_type = RTW_GET_BE16(&sub_skb->data[6]); - - if (sub_skb->len >= 8 - && ((_rtw_memcmp(sub_skb->data, rtw_rfc1042_header, SNAP_SIZE) - && eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) - || _rtw_memcmp(sub_skb->data, rtw_bridge_tunnel_header, SNAP_SIZE)) - ) { + if (llc_hdl) { /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ skb_pull(sub_skb, SNAP_SIZE); _rtw_memcpy(skb_push(sub_skb, ETH_ALEN), sa, ETH_ALEN); @@ -355,7 +400,12 @@ static int napi_recv(_adapter *padapter, int budget) rx_ok = _FALSE; #ifdef CONFIG_RTW_GRO - if (pregistrypriv->en_gro) { + /* + cloned SKB use dataref to avoid kernel release it. + But dataref changed in napi_gro_receive. + So, we should prevent cloned SKB go into napi_gro_receive. + */ + if (pregistrypriv->en_gro && !skb_cloned(pskb)) { if (rtw_napi_gro_receive(&padapter->napi, pskb) != GRO_DROP) rx_ok = _TRUE; goto next; @@ -434,52 +484,8 @@ void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, union recv_frame *r DBG_COUNTER(padapter->rx_logs.os_indicate); - if (MLME_IS_AP(padapter) && !pmlmepriv->ap_isolate) { - _pkt *pskb2 = NULL; - struct sta_info *psta = NULL; - struct sta_priv *pstapriv = &padapter->stapriv; - int bmcast = IS_MCAST(ehdr->h_dest); - - /* RTW_INFO("bmcast=%d\n", bmcast); */ - - if (_rtw_memcmp(ehdr->h_dest, adapter_mac_addr(padapter), ETH_ALEN) == _FALSE) { - /* RTW_INFO("not ap psta=%p, addr=%pM\n", psta, ehdr->h_dest); */ - - if (bmcast) { - psta = rtw_get_bcmc_stainfo(padapter); - pskb2 = rtw_skb_clone(pkt); - } else - psta = rtw_get_stainfo(pstapriv, ehdr->h_dest); - - if (psta) { - struct net_device *pnetdev = (struct net_device *)padapter->pnetdev; - - /* RTW_INFO("directly forwarding to the rtw_xmit_entry\n"); */ - - /* skb->ip_summed = CHECKSUM_NONE; */ - pkt->dev = pnetdev; - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) - skb_set_queue_mapping(pkt, rtw_recv_select_queue(pkt)); - #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) */ - - _rtw_xmit_entry(pkt, pnetdev); - - if (bmcast && (pskb2 != NULL)) { - pkt = pskb2; - DBG_COUNTER(padapter->rx_logs.os_indicate_ap_mcast); - } else { - DBG_COUNTER(padapter->rx_logs.os_indicate_ap_forward); - return; - } - } - } else { /* to APself */ - /* RTW_INFO("to APSelf\n"); */ - DBG_COUNTER(padapter->rx_logs.os_indicate_ap_self); - } - } - #ifdef CONFIG_BR_EXT - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) { + if (!adapter_use_wds(padapter) && check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) { /* Insert NAT2.5 RX here! */ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) br_port = padapter->pnetdev->br_port; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_android.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_android.c index a535e636ae23..98fe38ab054e 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_android.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_android.c @@ -829,11 +829,13 @@ int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) break; #ifdef CONFIG_IOCTL_CFG80211 + #ifdef CONFIG_AP_MODE case ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE: { int skip = strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE]) + 3; bytes_written = rtw_cfg80211_set_mgnt_wpsp2pie(net, command + skip, priv_cmd.total_len - skip, *(command + skip - 2) - '0'); break; } + #endif #endif /* CONFIG_IOCTL_CFG80211 */ #ifdef CONFIG_WFD @@ -1149,6 +1151,7 @@ extern PADAPTER g_test_adapter; static void shutdown_card(void) { + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(g_test_adapter); u32 addr; u8 tmp8, cnt = 0; @@ -1165,7 +1168,7 @@ static void shutdown_card(void) #ifdef CONFIG_GPIO_WAKEUP /*default wake up pin change to BT*/ RTW_INFO("%s:default wake up pin change to BT\n", __FUNCTION__); - rtw_hal_switch_gpio_wl_ctrl(g_test_adapter, WAKEUP_GPIO_IDX, _FALSE); + rtw_hal_switch_gpio_wl_ctrl(g_test_adapter, pwrpriv->wowlan_gpio_index, _FALSE); #endif /* CONFIG_GPIO_WAKEUP */ #endif /* CONFIG_WOWLAN */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_cfgvendor.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_cfgvendor.c index 4fb0b0576cd9..a0e9d7380637 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_cfgvendor.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_cfgvendor.c @@ -281,7 +281,9 @@ int rtw_dev_get_feature_set(struct net_device *dev) #ifdef CONFIG_RTW_WIFI_HAL feature_set |= WIFI_FEATURE_CONFIG_NDO; +#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI feature_set |= WIFI_FEATURE_SCAN_RAND; +#endif #endif return feature_set; @@ -1880,6 +1882,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LSTATS_SUBCMD_GET_INFO }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_lstats_get_info }, { @@ -1888,6 +1893,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LSTATS_SUBCMD_SET_INFO }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_lstats_set_info }, { @@ -1896,6 +1904,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LSTATS_SUBCMD_CLEAR_INFO }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_lstats_clear_info }, #endif /* CONFIG_RTW_CFGVENDOR_LLSTATS */ @@ -1906,6 +1917,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_SUBCMD_SET_RSSI_MONITOR }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_set_rssi_monitor }, #endif /* CONFIG_RTW_CFGVENDOR_RSSIMONITOR */ @@ -1916,6 +1930,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_START_LOGGING }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_start_logging }, { @@ -1924,6 +1941,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_GET_FEATURE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_get_feature }, { @@ -1932,6 +1952,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_GET_VER }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_get_version }, { @@ -1940,6 +1963,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_GET_RING_STATUS }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_get_ring_status }, { @@ -1948,6 +1974,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_GET_RING_DATA }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_get_ring_data }, { @@ -1956,6 +1985,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_TRIGGER_MEM_DUMP }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_get_firmware_memory_dump }, { @@ -1964,6 +1996,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_START_PKT_FATE_MONITORING }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_start_pkt_fate_monitoring }, { @@ -1972,6 +2007,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_GET_TX_PKT_FATES }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_get_tx_pkt_fates }, { @@ -1980,6 +2018,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = LOGGER_GET_RX_PKT_FATES }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_logger_get_rx_pkt_fates }, #endif /* CONFIG_RTW_CFGVENDOR_WIFI_LOGGER */ @@ -1991,6 +2032,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_set_rand_mac_oui }, #endif @@ -2001,6 +2045,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_start_mkeep_alive }, { @@ -2009,6 +2056,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_stop_mkeep_alive }, #endif @@ -2018,6 +2068,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_SUBCMD_NODFS_SET }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_set_nodfs_flag }, @@ -2027,6 +2080,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_set_country }, { @@ -2035,6 +2091,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_SUBCMD_CONFIG_ND_OFFLOAD }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_set_nd_offload }, #endif /* CONFIG_RTW_WIFI_HAL */ @@ -2044,6 +2103,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_SUBCMD_GET_FEATURE_SET }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_get_feature_set }, { @@ -2052,6 +2114,9 @@ static const struct wiphy_vendor_command rtw_vendor_cmds[] = { .subcmd = WIFI_SUBCMD_GET_FEATURE_SET_MATRIX }, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) + .policy = VENDOR_CMD_RAW_DATA, +#endif .doit = rtw_cfgvendor_get_feature_set_matrix } }; diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_proc.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_proc.c index b551b776d42b..f260455ecfee 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_proc.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_proc.c @@ -82,7 +82,7 @@ inline struct proc_dir_entry *rtw_proc_create_dir(const char *name, struct proc_ } inline struct proc_dir_entry *rtw_proc_create_entry(const char *name, struct proc_dir_entry *parent, - const struct file_operations *fops, void * data) + const struct rtw_proc_ops *fops, void * data) { struct proc_dir_entry *entry; @@ -174,11 +174,13 @@ static int proc_get_chplan_id_list(struct seq_file *m, void *v) return 0; } +#ifdef CONFIG_RTW_DEBUG static int proc_get_chplan_test(struct seq_file *m, void *v) { dump_chplan_test(m); return 0; } +#endif static int proc_get_chplan_ver(struct seq_file *m, void *v) { @@ -186,6 +188,20 @@ static int proc_get_chplan_ver(struct seq_file *m, void *v) return 0; } +static int proc_get_global_op_class(struct seq_file *m, void *v) +{ + dump_global_op_class(m); + return 0; +} + +#ifdef CONFIG_RTW_DEBUG +static int proc_get_hw_rate_map_test(struct seq_file *m, void *v) +{ + dump_hw_rate_map_test(m); + return 0; +} +#endif + #ifdef RTW_HALMAC extern void rtw_halmac_get_version(char *str, u32 len); @@ -214,8 +230,14 @@ const struct rtw_proc_hdl drv_proc_hdls[] = { #endif /* DBG_MEM_ALLOC */ RTW_PROC_HDL_SSEQ("country_chplan_map", proc_get_country_chplan_map, NULL), RTW_PROC_HDL_SSEQ("chplan_id_list", proc_get_chplan_id_list, NULL), +#ifdef CONFIG_RTW_DEBUG RTW_PROC_HDL_SSEQ("chplan_test", proc_get_chplan_test, NULL), +#endif RTW_PROC_HDL_SSEQ("chplan_ver", proc_get_chplan_ver, NULL), + RTW_PROC_HDL_SSEQ("global_op_class", proc_get_global_op_class, NULL), +#ifdef CONFIG_RTW_DEBUG + RTW_PROC_HDL_SSEQ("hw_rate_map_test", proc_get_hw_rate_map_test, NULL), +#endif #ifdef RTW_HALMAC RTW_PROC_HDL_SSEQ("halmac_info", proc_get_halmac_info, NULL), #endif /* RTW_HALMAC */ @@ -262,22 +284,38 @@ static ssize_t rtw_drv_proc_write(struct file *file, const char __user *buffer, return -EROFS; } -static const struct file_operations rtw_drv_proc_seq_fops = { +static const struct rtw_proc_ops rtw_drv_proc_seq_fops = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) + .proc_open = rtw_drv_proc_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = seq_release, + .proc_write = rtw_drv_proc_write, +#else .owner = THIS_MODULE, .open = rtw_drv_proc_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release, .write = rtw_drv_proc_write, +#endif }; -static const struct file_operations rtw_drv_proc_sseq_fops = { +static const struct rtw_proc_ops rtw_drv_proc_sseq_fops = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) + .proc_open = rtw_drv_proc_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = single_release, + .proc_write = rtw_drv_proc_write, +#else .owner = THIS_MODULE, .open = rtw_drv_proc_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, .write = rtw_drv_proc_write, +#endif }; int rtw_drv_proc_init(void) @@ -425,6 +463,100 @@ static int proc_get_sdio_card_info(struct seq_file *m, void *v) return 0; } +#ifdef CONFIG_SDIO_RECVBUF_AGGREGATION +int proc_get_sdio_recvbuf_aggregation(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = GET_PRIMARY_ADAPTER((_adapter *)rtw_netdev_priv(dev)); + struct recv_priv *recvpriv = &adapter->recvpriv; + + RTW_PRINT_SEL(m, "%d\n", recvpriv->recvbuf_agg); + + return 0; +} + +ssize_t proc_set_sdio_recvbuf_aggregation(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = GET_PRIMARY_ADAPTER((_adapter *)rtw_netdev_priv(dev)); + struct recv_priv *recvpriv = &adapter->recvpriv; + + char tmp[32]; + u8 enable; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhu", &enable); + + if (num >= 1) + recvpriv->recvbuf_agg = enable ? 1 : 0; + } + + return count; +} +#endif /* CONFIG_SDIO_RECVBUF_AGGREGATION */ + +#ifdef CONFIG_SDIO_RECVBUF_PWAIT +int proc_get_sdio_recvbuf_pwait(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = GET_PRIMARY_ADAPTER((_adapter *)rtw_netdev_priv(dev)); + struct recv_priv *recvpriv = &adapter->recvpriv; + + dump_recvbuf_pwait_conf(m, recvpriv); + + return 0; +} + +ssize_t proc_set_sdio_recvbuf_pwait(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ +#ifdef CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST + struct net_device *dev = data; + _adapter *adapter = GET_PRIMARY_ADAPTER((_adapter *)rtw_netdev_priv(dev)); + struct recv_priv *recvpriv = &adapter->recvpriv; + + char tmp[64]; + char type[64]; + s32 time; + s32 cnt_lmt; + + if (count < 3) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%s %d %d", type, &time, &cnt_lmt); + int i; + + if (num < 3) + return -EINVAL; + + for (i = 0; i < RTW_PWAIT_TYPE_NUM; i++) + if (strncmp(_rtw_pwait_type_str[i], type, strlen(_rtw_pwait_type_str[i])) == 0) + break; + + if (i < RTW_PWAIT_TYPE_NUM && recvbuf_pwait_config_req(recvpriv, i, time, cnt_lmt) != _SUCCESS) + return -EINVAL; + } + return count; +#else + return -EFAULT; +#endif /* CONFIG_SDIO_RECVBUF_PWAIT_RUNTIME_ADJUST */ +} +#endif /* CONFIG_SDIO_RECVBUF_PWAIT */ + #ifdef DBG_SDIO static int proc_get_sdio_dbg(struct seq_file *m, void *v) { @@ -722,6 +854,46 @@ ssize_t proc_set_ap_isolate(struct file *file, const char __user *buffer, size_t return count; } + +#if CONFIG_RTW_AP_DATA_BMC_TO_UC +static int proc_get_ap_b2u_flags(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = rtw_netdev_priv(dev); + + if (MLME_IS_AP(adapter)) + dump_ap_b2u_flags(m, adapter); + + return 0; +} + +static ssize_t proc_set_ap_b2u_flags(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = rtw_netdev_priv(dev); + char tmp[32]; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + u8 src, fwd; + int num = sscanf(tmp, "%hhx %hhx", &src, &fwd); + + if (num >= 1) + adapter->b2u_flags_ap_src = src; + if (num >= 2) + adapter->b2u_flags_ap_fwd = fwd; + } + + return count; +} +#endif /* CONFIG_RTW_AP_DATA_BMC_TO_UC */ #endif /* CONFIG_AP_MODE */ static int proc_get_dump_tx_rate_bmp(struct seq_file *m, void *v) @@ -1325,7 +1497,6 @@ static int proc_get_chan_plan(struct seq_file *m, void *v) _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); dump_cur_chset(m, adapter_to_rfctl(adapter)); - return 0; } @@ -1403,6 +1574,111 @@ exit: return count; } +static int cap_spt_op_class_ch_detail = 0; + +static int proc_get_cap_spt_op_class_ch(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_cap_spt_op_class_ch(m , adapter_to_rfctl(adapter), cap_spt_op_class_ch_detail); + return 0; +} + +static ssize_t proc_set_cap_spt_op_class_ch(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + int num; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (!buffer || copy_from_user(tmp, buffer, count)) + goto exit; + + num = sscanf(tmp, "%d", &cap_spt_op_class_ch_detail); + +exit: + return count; +} + +static int reg_spt_op_class_ch_detail = 0; + +static int proc_get_reg_spt_op_class_ch(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_reg_spt_op_class_ch(m , adapter_to_rfctl(adapter), reg_spt_op_class_ch_detail); + return 0; +} + +static ssize_t proc_set_reg_spt_op_class_ch(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + int num; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (!buffer || copy_from_user(tmp, buffer, count)) + goto exit; + + num = sscanf(tmp, "%d", ®_spt_op_class_ch_detail); + +exit: + return count; +} + +static int cur_spt_op_class_ch_detail = 0; + +static int proc_get_cur_spt_op_class_ch(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_cur_spt_op_class_ch(m , adapter_to_rfctl(adapter), cur_spt_op_class_ch_detail); + return 0; +} + +static ssize_t proc_set_cur_spt_op_class_ch(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + int num; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (!buffer || copy_from_user(tmp, buffer, count)) + goto exit; + + num = sscanf(tmp, "%d", &cur_spt_op_class_ch_detail); + +exit: + return count; +} + #if CONFIG_RTW_MACADDR_ACL static int proc_get_macaddr_acl(struct seq_file *m, void *v) { @@ -1722,6 +1998,7 @@ ssize_t proc_set_update_non_ocp(struct file *file, const char __user *buffer, si char tmp[32]; u8 ch, bw = CHANNEL_WIDTH_20, offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; int ms = -1; + bool updated = 0; if (count < 1) return -EFAULT; @@ -1739,11 +2016,17 @@ ssize_t proc_set_update_non_ocp(struct file *file, const char __user *buffer, si goto exit; if (bw == CHANNEL_WIDTH_20) - rtw_chset_update_non_ocp_ms(rfctl->channel_set + updated = rtw_chset_update_non_ocp_ms(rfctl->channel_set , ch, bw, HAL_PRIME_CHNL_OFFSET_DONT_CARE, ms); else - rtw_chset_update_non_ocp_ms(rfctl->channel_set + updated = rtw_chset_update_non_ocp_ms(rfctl->channel_set , ch, bw, offset, ms); + + if (updated) { + u8 cch = rtw_get_center_ch(ch, bw, offset); + + rtw_nlrtw_nop_start_event(adapter, cch, bw); + } } exit: @@ -1780,6 +2063,47 @@ exit: return count; } +static int proc_get_dfs_ch_sel_e_flags(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + RTW_PRINT_SEL(m, "0x%02x\n", rfctl->dfs_ch_sel_e_flags); + + return 0; +} + +static ssize_t proc_set_dfs_ch_sel_e_flags(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + char tmp[32]; + u8 e_flags; + int num; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (!buffer || copy_from_user(tmp, buffer, count)) + goto exit; + + num = sscanf(tmp, "%hhx", &e_flags); + if (num != 1) + goto exit; + + rfctl->dfs_ch_sel_e_flags = e_flags; + +exit: + return count; +} + static int proc_get_dfs_ch_sel_d_flags(struct seq_file *m, void *v) { struct net_device *dev = m->private; @@ -2165,6 +2489,7 @@ static int proc_get_sec_cam_cache(struct seq_file *m, void *v) return 0; } +#ifdef CONFIG_AP_MODE static ssize_t proc_set_change_bss_chbw(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { struct net_device *dev = data; @@ -2212,6 +2537,7 @@ static ssize_t proc_set_change_bss_chbw(struct file *file, const char __user *bu exit: return count; } +#endif #if CONFIG_TX_AC_LIFETIME static int proc_get_tx_aclt_force_val(struct seq_file *m, void *v) @@ -2454,6 +2780,92 @@ static int proc_get_tx_power_limit(struct seq_file *m, void *v) } #endif /* CONFIG_TXPWR_LIMIT */ +static int proc_get_tpc_settings(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_txpwr_tpc_settings(m, adapter); + + return 0; +} + +static ssize_t proc_set_tpc_settings(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + char tmp[32] = {0}; + u8 mode; + u16 m_constraint; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhu %hu", &mode, &m_constraint); + + if (num < 1) + return count; + + if (mode >= TPC_MODE_INVALID) + return count; + + if (mode == TPC_MODE_MANUAL && num >= 2) + rfctl->tpc_manual_constraint = rtw_min(m_constraint, TPC_MANUAL_CONSTRAINT_MAX); + rfctl->tpc_mode = mode; + + if (rtw_get_hw_init_completed(adapter)) + rtw_run_in_thread_cmd_wait(adapter, ((void *)(rtw_hal_update_txpwr_level)), adapter, 2000); + } + + return count; +} + +static int proc_get_antenna_gain(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_txpwr_antenna_gain(m, adapter); + + return 0; +} + +static ssize_t proc_set_antenna_gain(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + char tmp[32] = {0}; + s16 gain; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hd", &gain); + + if (num < 1) + return count; + + rfctl->antenna_gain = gain; + + if (rtw_get_hw_init_completed(adapter)) + rtw_run_in_thread_cmd_wait(adapter, ((void *)(rtw_hal_update_txpwr_level)), adapter, 2000); + } + + return count; +} + static int proc_get_tx_power_ext_info(struct seq_file *m, void *v) { struct net_device *dev = m->private; @@ -3674,6 +4086,406 @@ static int proc_get_dynamic_agg_enable(struct seq_file *m, void *v) return 0; } +#ifdef CONFIG_RTW_WDS +static int proc_get_wds_en(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = rtw_netdev_priv(dev); + + if (MLME_STATE(adapter) & (WIFI_AP_STATE | WIFI_STATION_STATE)) + RTW_PRINT_SEL(m, "%d\n", adapter_use_wds(adapter)); + + return 0; +} + +static ssize_t proc_set_wds_en(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = rtw_netdev_priv(dev); + char tmp[32]; + + if (!(MLME_STATE(adapter) & (WIFI_AP_STATE | WIFI_STATION_STATE))) + return -EFAULT; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + u8 enable; + int num = sscanf(tmp, "%hhu", &enable); + + if (num >= 1) + adapter_set_use_wds(adapter, enable); + } + + return count; +} + +static ssize_t proc_set_sta_wds_en(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = rtw_netdev_priv(dev); + char tmp[32]; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + u8 enable; + u8 addr[ETH_ALEN]; + struct sta_info *sta; + int num = sscanf(tmp, "%hhu "MAC_SFMT, &enable, MAC_SARG(addr)); + + if (num != 7) + return -EINVAL; + + if (IS_MCAST(addr) || _rtw_memcmp(adapter_mac_addr(adapter), addr, ETH_ALEN)) + return -EINVAL; + + sta = rtw_get_stainfo(&adapter->stapriv, addr); + if (!sta) + return -EINVAL; + + if (enable) + sta->flags |= WLAN_STA_WDS; + else + sta->flags &= ~WLAN_STA_WDS; + } + + return count; +} + +static int proc_get_wds_gptr(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = rtw_netdev_priv(dev); + + if (MLME_IS_STA(adapter) && MLME_IS_ASOC(adapter)) + dump_wgptr(m, adapter); + + return 0; +} + +#ifdef CONFIG_AP_MODE +static int proc_get_wds_path(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = rtw_netdev_priv(dev); + + if (MLME_IS_AP(adapter) && MLME_IS_ASOC(adapter)) + dump_wpath(m, adapter); + + return 0; +} +#endif /* CONFIG_AP_MODE */ +#endif /* CONFIG_RTW_WDS */ + +#ifdef CONFIG_RTW_MULTI_AP +static int proc_get_multi_ap_opmode(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = rtw_netdev_priv(dev); + + if (MLME_STATE(adapter) & (WIFI_AP_STATE | WIFI_STATION_STATE)) + RTW_PRINT_SEL(m, "0x%02x\n", adapter->multi_ap); + + return 0; +} + +static ssize_t proc_set_multi_ap_opmode(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = rtw_netdev_priv(dev); + char tmp[32]; + + if (!(MLME_STATE(adapter) & (WIFI_AP_STATE | WIFI_STATION_STATE))) + return -EFAULT; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + u8 mode; + int num = sscanf(tmp, "%hhx", &mode); + + if (num >= 1) { + if (MLME_IS_AP(adapter)) + adapter->multi_ap = mode & (MULTI_AP_FRONTHAUL_BSS | MULTI_AP_BACKHAUL_BSS); + else + adapter->multi_ap = mode & MULTI_AP_BACKHAUL_STA; + if (adapter->multi_ap & (MULTI_AP_BACKHAUL_BSS | MULTI_AP_BACKHAUL_STA)) + adapter_set_use_wds(adapter, 1); + } + } + + return count; +} + +static int proc_get_unassoc_sta(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = GET_PRIMARY_ADAPTER(rtw_netdev_priv(dev)); + + dump_unassoc_sta(m, adapter); + + return 0; +} + +ssize_t proc_set_unassoc_sta(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = GET_PRIMARY_ADAPTER(rtw_netdev_priv(dev)); + char tmp[17 * 10 + 32] = {0}; + char cmd[32]; + u8 mode; + u8 stype = 0; + u8 addr[ETH_ALEN]; + +#define UNASOC_STA_CMD_MODE 0 +#define UNASOC_STA_CMD_ADD 1 +#define UNASOC_STA_CMD_DEL 2 +#define UNASOC_STA_CMD_CLR 3 +#define UNASOC_STA_CMD_UNINT 4 +#define UNASOC_STA_CMD_NUM 5 + + static const char * const unasoc_sta_cmd_str[] = { + "mode", + "add", + "del", + "clr", + "uninterest", + }; + u8 cmd_id = UNASOC_STA_CMD_NUM; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + RTW_WARN(FUNC_ADPT_FMT" input string too long\n", FUNC_ADPT_ARG(adapter)); + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + /* + * mode , + * add [] + * del [] + * clr + */ + char *c, *next; + int i; + u8 is_bcast; + + next = tmp; + c = strsep(&next, " \t"); + if (!c || sscanf(c, "%s", cmd) != 1) + goto exit; + + for (i = 0; i < UNASOC_STA_CMD_NUM; i++) + if (strcmp(unasoc_sta_cmd_str[i], cmd) == 0) + cmd_id = i; + + switch (cmd_id) { + case UNASOC_STA_CMD_MODE: + c = strsep(&next, " \t"); + if (!c || sscanf(c, "%hhu,%hhu", &stype, &mode) != 2) { + RTW_WARN(FUNC_ADPT_FMT" invalid arguments of mode cmd\n", FUNC_ADPT_ARG(adapter)); + goto exit; + } + if (stype >= UNASOC_STA_SRC_NUM) { + RTW_WARN(FUNC_ADPT_FMT" invalid stype:%u\n", FUNC_ADPT_ARG(adapter), stype); + goto exit; + } + if (mode >= UNASOC_STA_MODE_NUM) { + RTW_WARN(FUNC_ADPT_FMT" invalid mode:%u\n", FUNC_ADPT_ARG(adapter), mode); + goto exit; + } + rtw_unassoc_sta_set_mode(adapter, stype, mode); + break; + + case UNASOC_STA_CMD_ADD: + case UNASOC_STA_CMD_DEL: + case UNASOC_STA_CMD_UNINT: + /* check for macaddr list */ + c = strsep(&next, " \t"); + while (c != NULL) { + if (sscanf(c, MAC_SFMT, MAC_SARG(addr)) != 6) + break; + + is_bcast = is_broadcast_mac_addr(addr); + if (is_bcast + || rtw_check_invalid_mac_address(addr, 0) == _FALSE + ) { + if (cmd_id == UNASOC_STA_CMD_DEL) { + if (is_bcast) { + rtw_del_unassoc_sta_queue(adapter); + break; + } else + rtw_del_unassoc_sta(adapter, addr); + } else if (cmd_id == UNASOC_STA_CMD_UNINT) { + if (is_bcast) { + rtw_undo_all_interested_unassoc_sta(adapter); + break; + } else + rtw_undo_interested_unassoc_sta(adapter, addr); + } else if (!is_bcast) + rtw_add_interested_unassoc_sta(adapter, addr); + } + + c = strsep(&next, " \t"); + } + break; + + case UNASOC_STA_CMD_CLR: + /* clear sta list */ + rtw_del_unassoc_sta_queue(adapter); + goto exit; + + default: + RTW_WARN(FUNC_ADPT_FMT" invalid cmd:\"%s\"\n", FUNC_ADPT_ARG(adapter), cmd); + goto exit; + } + } + +exit: + return count; +} + +#ifdef CONFIG_IOCTL_CFG80211 +static u8 assoc_req_mac_addr[6]; +int proc_get_sta_assoc_req_frame_body(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + if (MLME_IS_AP(adapter)) { + struct sta_info *psta; + _irqL irqL; + u8 *passoc_req = NULL; + u32 assoc_req_len = 0; + + psta = rtw_get_stainfo(&adapter->stapriv, assoc_req_mac_addr); + if (psta == NULL) { + RTW_PRINT(FUNC_ADPT_FMT" sta("MAC_FMT") not found\n", + FUNC_ADPT_ARG(adapter), MAC_ARG(assoc_req_mac_addr)); + return 0; + } + RTW_PRINT(FUNC_ADPT_FMT" sta("MAC_FMT") found\n", + FUNC_ADPT_ARG(adapter), MAC_ARG(assoc_req_mac_addr)); + _enter_critical_bh(&psta->lock, &irqL); + if (psta->passoc_req && psta->assoc_req_len > 0) { + passoc_req = rtw_zmalloc(psta->assoc_req_len); + if (passoc_req) { + assoc_req_len = psta->assoc_req_len; + _rtw_memcpy(passoc_req, psta->passoc_req, assoc_req_len); + } + } + _exit_critical_bh(&psta->lock, &irqL); + if (passoc_req && assoc_req_len > IEEE80211_3ADDR_LEN) { + u8 *body = passoc_req + IEEE80211_3ADDR_LEN; + u32 body_len = assoc_req_len - IEEE80211_3ADDR_LEN; + u16 i; + + for (i = 0; i < body_len; i++) + _RTW_PRINT_SEL(m, "%02X", body[i]); + _RTW_PRINT_SEL(m, "\n"); + } + if (passoc_req && assoc_req_len > 0) + rtw_mfree(passoc_req, assoc_req_len); + } + + return 0; +} + +ssize_t proc_set_sta_assoc_req_frame_body(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[18] = {0}; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + if (sscanf(tmp, MAC_SFMT, MAC_SARG(assoc_req_mac_addr)) != 6) { + _rtw_memset(assoc_req_mac_addr, 0, 6); + RTW_PRINT(FUNC_ADPT_FMT" Invalid format\n", + FUNC_ADPT_ARG(adapter)); + } + + } + + return count; +} +#endif /* CONFIG_IOCTL_CFG80211 */ + +static int proc_get_ch_util_threshold(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = GET_PRIMARY_ADAPTER(rtw_netdev_priv(dev)); + + RTW_PRINT_SEL(m, "%hhu\n", adapter->ch_util_threshold); + + return 0; +} + +static ssize_t proc_set_ch_util_threshold(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = GET_PRIMARY_ADAPTER(rtw_netdev_priv(dev)); + char tmp[4]; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + u8 threshold; + int num = sscanf(tmp, "%hhu", &threshold); + + if (num == 1) + adapter->ch_util_threshold = threshold; + } + + return count; +} + +static int proc_get_ch_utilization(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + RTW_PRINT_SEL(m, "%hhu\n", rtw_get_ch_utilization(adapter)); + + return 0; +} +#endif /* CONFIG_RTW_MULTI_AP */ + #ifdef CONFIG_RTW_MESH static int proc_get_mesh_peer_sel_policy(struct seq_file *m, void *v) { @@ -4412,15 +5224,24 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { RTW_PROC_HDL_SSEQ("roam_param", proc_get_roam_param, proc_set_roam_param), RTW_PROC_HDL_SSEQ("roam_tgt_addr", NULL, proc_set_roam_tgt_addr), #endif /* CONFIG_LAYER2_ROAMING */ - +#ifdef CONFIG_RTW_MBO + RTW_PROC_HDL_SSEQ("non_pref_ch", rtw_mbo_proc_non_pref_chans_get, rtw_mbo_proc_non_pref_chans_set), + RTW_PROC_HDL_SSEQ("cell_data", rtw_mbo_proc_cell_data_get, rtw_mbo_proc_cell_data_set), +#endif #ifdef CONFIG_RTW_80211R - RTW_PROC_HDL_SSEQ("ft_flags", proc_get_ft_flags, proc_set_ft_flags), + RTW_PROC_HDL_SSEQ("ft_flags", rtw_ft_proc_flags_get, rtw_ft_proc_flags_set), #endif RTW_PROC_HDL_SSEQ("defs_param", proc_get_defs_param, proc_set_defs_param), #ifdef CONFIG_SDIO_HCI RTW_PROC_HDL_SSEQ("sd_f0_reg_dump", proc_get_sd_f0_reg_dump, NULL), RTW_PROC_HDL_SSEQ("sdio_local_reg_dump", proc_get_sdio_local_reg_dump, NULL), RTW_PROC_HDL_SSEQ("sdio_card_info", proc_get_sdio_card_info, NULL), + #ifdef CONFIG_SDIO_RECVBUF_AGGREGATION + RTW_PROC_HDL_SSEQ("sdio_recvbuf_aggregation", proc_get_sdio_recvbuf_aggregation, proc_set_sdio_recvbuf_aggregation), + #endif + #ifdef CONFIG_SDIO_RECVBUF_PWAIT + RTW_PROC_HDL_SSEQ("sdio_recvbuf_pwait", proc_get_sdio_recvbuf_pwait, proc_set_sdio_recvbuf_pwait), + #endif #ifdef DBG_SDIO RTW_PROC_HDL_SSEQ("sdio_dbg", proc_get_sdio_dbg, proc_set_sdio_dbg), #endif /* DBG_SDIO */ @@ -4448,6 +5269,9 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { RTW_PROC_HDL_SSEQ("ap_isolate", proc_get_ap_isolate, proc_set_ap_isolate), RTW_PROC_HDL_SSEQ("all_sta_info", proc_get_all_sta_info, NULL), RTW_PROC_HDL_SSEQ("bmc_tx_rate", proc_get_bmc_tx_rate, proc_set_bmc_tx_rate), + #if CONFIG_RTW_AP_DATA_BMC_TO_UC + RTW_PROC_HDL_SSEQ("ap_b2u_flags", proc_get_ap_b2u_flags, proc_set_ap_b2u_flags), + #endif #endif /* CONFIG_AP_MODE */ #ifdef DBG_MEMORY_LEAK @@ -4478,6 +5302,15 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { RTW_PROC_HDL_SSEQ("tx_amsdu_rate", proc_get_tx_amsdu_rate, proc_set_tx_amsdu_rate), #endif #endif /* CONFIG_80211N_HT */ + +#ifdef CONFIG_80211AC_VHT + RTW_PROC_HDL_SSEQ("vht_24g_enable", proc_get_vht_24g_enable, proc_set_vht_24g_enable), +#endif + + #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT + RTW_PROC_HDL_SSEQ("tx_aval_int_threshold", proc_get_tx_aval_th, proc_set_tx_aval_th), + #endif + RTW_PROC_HDL_SSEQ("dynamic_rrsr", proc_get_dyn_rrsr, proc_set_dyn_rrsr), RTW_PROC_HDL_SSEQ("en_fwps", proc_get_en_fwps, proc_set_en_fwps), @@ -4555,6 +5388,10 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { #ifdef CONFIG_WOW_PATTERN_HW_CAM RTW_PROC_HDL_SSEQ("wow_pattern_cam", proc_dump_pattern_cam, NULL), #endif +#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN + RTW_PROC_HDL_SSEQ("wow_keep_alive_info", proc_dump_wow_keep_alive_info, NULL), +#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/ + #endif #ifdef CONFIG_GPIO_WAKEUP @@ -4565,6 +5402,9 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { #endif RTW_PROC_HDL_SSEQ("country_code", proc_get_country_code, proc_set_country_code), RTW_PROC_HDL_SSEQ("chan_plan", proc_get_chan_plan, proc_set_chan_plan), + RTW_PROC_HDL_SSEQ("cap_spt_op_class_ch", proc_get_cap_spt_op_class_ch, proc_set_cap_spt_op_class_ch), + RTW_PROC_HDL_SSEQ("reg_spt_op_class_ch", proc_get_reg_spt_op_class_ch, proc_set_reg_spt_op_class_ch), + RTW_PROC_HDL_SSEQ("cur_spt_op_class_ch", proc_get_cur_spt_op_class_ch, proc_set_cur_spt_op_class_ch), #if CONFIG_RTW_MACADDR_ACL RTW_PROC_HDL_SSEQ("macaddr_acl", proc_get_macaddr_acl, proc_set_macaddr_acl), #endif @@ -4576,6 +5416,7 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { RTW_PROC_HDL_SSEQ("dfs_test_case", proc_get_dfs_test_case, proc_set_dfs_test_case), RTW_PROC_HDL_SSEQ("update_non_ocp", NULL, proc_set_update_non_ocp), RTW_PROC_HDL_SSEQ("radar_detect", NULL, proc_set_radar_detect), + RTW_PROC_HDL_SSEQ("dfs_ch_sel_e_flags", proc_get_dfs_ch_sel_e_flags, proc_set_dfs_ch_sel_e_flags), RTW_PROC_HDL_SSEQ("dfs_ch_sel_d_flags", proc_get_dfs_ch_sel_d_flags, proc_set_dfs_ch_sel_d_flags), #if CONFIG_DFS_SLAVE_WITH_RADAR_DETECT RTW_PROC_HDL_SSEQ("dfs_slave_with_rd", proc_get_dfs_slave_with_rd, proc_set_dfs_slave_with_rd), @@ -4588,7 +5429,9 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { #ifdef DBG_RX_COUNTER_DUMP RTW_PROC_HDL_SSEQ("dump_rx_cnt_mode", proc_get_rx_cnt_dump, proc_set_rx_cnt_dump), #endif +#ifdef CONFIG_AP_MODE RTW_PROC_HDL_SSEQ("change_bss_chbw", NULL, proc_set_change_bss_chbw), +#endif #if CONFIG_TX_AC_LIFETIME RTW_PROC_HDL_SSEQ("tx_aclt_force_val", proc_get_tx_aclt_force_val, proc_set_tx_aclt_force_val), RTW_PROC_HDL_SSEQ("tx_aclt_flags", proc_get_tx_aclt_flags, proc_set_tx_aclt_flags), @@ -4601,6 +5444,8 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { #if CONFIG_TXPWR_LIMIT RTW_PROC_HDL_SSEQ("tx_power_limit", proc_get_tx_power_limit, NULL), #endif + RTW_PROC_HDL_SSEQ("tpc_settings", proc_get_tpc_settings, proc_set_tpc_settings), + RTW_PROC_HDL_SSEQ("antenna_gain", proc_get_antenna_gain, proc_set_antenna_gain), RTW_PROC_HDL_SSEQ("tx_power_ext_info", proc_get_tx_power_ext_info, proc_set_tx_power_ext_info), RTW_PROC_HDL_SEQ("tx_power_idx", &seq_ops_tx_power_idx, proc_set_tx_power_idx_dump), RTW_PROC_HDL_SEQ("txpwr_total_dbm", &seq_ops_txpwr_total_dbm, proc_set_txpwr_total_dbm_dump), @@ -4621,6 +5466,9 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { RTW_PROC_HDL_SSEQ("tdls_enable", proc_get_tdls_enable, proc_set_tdls_enable), #endif RTW_PROC_HDL_SSEQ("monitor", proc_get_monitor, proc_set_monitor), +#ifdef RTW_SIMPLE_CONFIG + RTW_PROC_HDL_SSEQ("rtw_simple_config", proc_get_simple_config, proc_set_simple_config), +#endif #ifdef CONFIG_RTW_ACS RTW_PROC_HDL_SSEQ("acs", proc_get_best_chan, proc_set_acs), @@ -4691,6 +5539,25 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { RTW_PROC_HDL_SSEQ("dynamic_agg_enable", proc_get_dynamic_agg_enable, proc_set_dynamic_agg_enable), RTW_PROC_HDL_SSEQ("fw_offload", proc_get_fw_offload, proc_set_fw_offload), +#ifdef CONFIG_RTW_WDS + RTW_PROC_HDL_SSEQ("wds_en", proc_get_wds_en, proc_set_wds_en), + RTW_PROC_HDL_SSEQ("sta_wds_en", NULL, proc_set_sta_wds_en), + RTW_PROC_HDL_SSEQ("wds_gptr", proc_get_wds_gptr, NULL), + #ifdef CONFIG_AP_MODE + RTW_PROC_HDL_SSEQ("wds_path", proc_get_wds_path, NULL), + #endif +#endif + +#ifdef CONFIG_RTW_MULTI_AP + RTW_PROC_HDL_SSEQ("multi_ap_opmode", proc_get_multi_ap_opmode, proc_set_multi_ap_opmode), + RTW_PROC_HDL_SSEQ("unassoc_sta", proc_get_unassoc_sta, proc_set_unassoc_sta), +#ifdef CONFIG_IOCTL_CFG80211 + RTW_PROC_HDL_SSEQ("sta_assoc_req_frame_body", proc_get_sta_assoc_req_frame_body, proc_set_sta_assoc_req_frame_body), +#endif + RTW_PROC_HDL_SSEQ("ch_util_threshold", proc_get_ch_util_threshold, proc_set_ch_util_threshold), + RTW_PROC_HDL_SSEQ("ch_utilization", proc_get_ch_utilization, NULL), +#endif + #ifdef CONFIG_RTW_MESH #if CONFIG_RTW_MESH_ACNODE_PREVENT RTW_PROC_HDL_SSEQ("mesh_acnode_prevent", proc_get_mesh_acnode_prevent, proc_set_mesh_acnode_prevent), @@ -4746,6 +5613,19 @@ const struct rtw_proc_hdl adapter_proc_hdls[] = { #endif RTW_PROC_HDL_SSEQ("cur_beacon_keys", proc_get_cur_beacon_keys, NULL), + +#ifdef CONFIG_WAR_OFFLOAD + RTW_PROC_HDL_SSEQ("war_offload_enable", proc_get_war_offload_enable, proc_set_war_offload_enable), + RTW_PROC_HDL_SSEQ("war_offload_ipv4_addr", NULL, proc_set_war_offload_ipv4_addr), + RTW_PROC_HDL_SSEQ("war_offload_ipv6_addr", NULL, proc_set_war_offload_ipv6_addr), +#if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) + RTW_PROC_HDL_SSEQ("war_offload_mdns_domain_name", proc_get_war_offload_mdns_domain_name, proc_set_war_offload_mdns_domain_name), + RTW_PROC_HDL_SSEQ("war_offload_mdns_machine_name", proc_get_war_offload_mdns_machine_name, proc_set_war_offload_mdns_machine_name), + RTW_PROC_HDL_SSEQ("war_offload_mdns_service_info", proc_get_war_offload_mdns_service_info, proc_set_war_offload_mdns_service_info), + RTW_PROC_HDL_SSEQ("war_offload_mdns_service_info_txt_rsp", proc_get_war_offload_mdns_txt_rsp, proc_set_war_offload_mdns_txt_rsp), +#endif /* CONFIG_OFFLOAD_MDNS_V4 || CONFIG_OFFLOAD_MDNS_V6 */ +#endif /* CONFIG_WAR_OFFLOAD */ + }; const int adapter_proc_hdls_num = sizeof(adapter_proc_hdls) / sizeof(struct rtw_proc_hdl); @@ -4788,22 +5668,38 @@ static ssize_t rtw_adapter_proc_write(struct file *file, const char __user *buff return -EROFS; } -static const struct file_operations rtw_adapter_proc_seq_fops = { +static const struct rtw_proc_ops rtw_adapter_proc_seq_fops = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) + .proc_open = rtw_adapter_proc_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = seq_release, + .proc_write = rtw_adapter_proc_write, +#else .owner = THIS_MODULE, .open = rtw_adapter_proc_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release, .write = rtw_adapter_proc_write, +#endif }; -static const struct file_operations rtw_adapter_proc_sseq_fops = { +static const struct rtw_proc_ops rtw_adapter_proc_sseq_fops = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) + .proc_open = rtw_adapter_proc_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = single_release, + .proc_write = rtw_adapter_proc_write, +#else .owner = THIS_MODULE, .open = rtw_adapter_proc_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, .write = rtw_adapter_proc_write, +#endif }; int proc_get_odm_adaptivity(struct seq_file *m, void *v) @@ -4961,22 +5857,38 @@ static ssize_t rtw_odm_proc_write(struct file *file, const char __user *buffer, return -EROFS; } -static const struct file_operations rtw_odm_proc_seq_fops = { +static const struct rtw_proc_ops rtw_odm_proc_seq_fops = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) + .proc_open = rtw_odm_proc_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = seq_release, + .proc_write = rtw_odm_proc_write, +#else .owner = THIS_MODULE, .open = rtw_odm_proc_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release, .write = rtw_odm_proc_write, +#endif }; -static const struct file_operations rtw_odm_proc_sseq_fops = { +static const struct rtw_proc_ops rtw_odm_proc_sseq_fops = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) + .proc_open = rtw_odm_proc_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = single_release, + .proc_write = rtw_odm_proc_write, +#else .owner = THIS_MODULE, .open = rtw_odm_proc_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, .write = rtw_odm_proc_write, +#endif }; struct proc_dir_entry *rtw_odm_proc_init(struct net_device *dev) @@ -5110,22 +6022,38 @@ static ssize_t rtw_mcc_proc_write(struct file *file, const char __user *buffer, return -EROFS; } -static const struct file_operations rtw_mcc_proc_seq_fops = { +static const struct rtw_proc_ops rtw_mcc_proc_seq_fops = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) + .proc_open = rtw_mcc_proc_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = seq_release, + .proc_write = rtw_mcc_proc_write, +#else .owner = THIS_MODULE, .open = rtw_mcc_proc_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release, .write = rtw_mcc_proc_write, +#endif }; -static const struct file_operations rtw_mcc_proc_sseq_fops = { +static const struct rtw_proc_ops rtw_mcc_proc_sseq_fops = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) + .proc_open = rtw_mcc_proc_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = single_release, + .proc_write = rtw_mcc_proc_write, +#else .owner = THIS_MODULE, .open = rtw_mcc_proc_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, .write = rtw_mcc_proc_write, +#endif }; struct proc_dir_entry *rtw_mcc_proc_init(struct net_device *dev) diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_proc.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_proc.h index ba01b4eb3c8f..0f1b6a30bc74 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_proc.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_proc.h @@ -46,6 +46,12 @@ struct rtw_proc_hdl { #define RTW_PROC_HDL_SZSEQ(_name, _show, _write, _size) \ { .name = _name, .type = RTW_PROC_HDL_TYPE_SZSEQ, .u.sz.show = _show, .write = _write, .u.sz.size = _size} +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) +#define rtw_proc_ops proc_ops +#else +#define rtw_proc_ops file_operations +#endif + #ifdef CONFIG_PROC_DEBUG int rtw_drv_proc_init(void); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_rhashtable.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_rhashtable.c index 2fd62d33aaa7..cb997e36108a 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_rhashtable.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_rhashtable.c @@ -14,10 +14,10 @@ * *****************************************************************************/ -#ifdef CONFIG_RTW_MESH /* for now, only promised for kernel versions we support mesh */ - #include +#if defined(CONFIG_RTW_WDS) || defined(CONFIG_RTW_MESH) /* for now, only promised for kernel versions we support mesh */ + int rtw_rhashtable_walk_enter(rtw_rhashtable *ht, rtw_rhashtable_iter *iter) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) @@ -74,5 +74,5 @@ void kvfree(const void *addr) #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) */ -#endif /* CONFIG_RTW_MESH */ +#endif /* defined(CONFIG_RTW_WDS) || defined(CONFIG_RTW_MESH) */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_rhashtable.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_rhashtable.h index 8d6ec4e3730b..64e52beedf5d 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_rhashtable.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/rtw_rhashtable.h @@ -16,7 +16,7 @@ #ifndef __RTW_RHASHTABLE_H__ #define __RTW_RHASHTABLE_H__ -#ifdef CONFIG_RTW_MESH /* for now, only promised for kernel versions we support mesh */ +#if defined(CONFIG_RTW_WDS) || defined(CONFIG_RTW_MESH) /* for now, only promised for kernel versions we support mesh */ /* directly reference rhashtable in kernel */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) @@ -28,6 +28,14 @@ #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) #define NULLS_MARKER(value) (1UL | (((long)value) << 1)) #endif +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) +static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) +{ + if (size != 0 && n > ULONG_MAX / size) + return NULL; + return __kmalloc(n * size, flags); +} +#endif #include "rhashtable.h" #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) */ @@ -54,7 +62,7 @@ int rtw_rhashtable_walk_enter(rtw_rhashtable *ht, rtw_rhashtable_iter *iter); #define rtw_rhashtable_lookup_insert_fast(ht, obj, params) rhashtable_lookup_insert_fast((ht), (obj), (params)) #define rtw_rhashtable_remove_fast(ht, obj, params) rhashtable_remove_fast((ht), (obj), (params)) -#endif /* CONFIG_RTW_MESH */ +#endif /* defined(CONFIG_RTW_WDS) || defined(CONFIG_RTW_MESH) */ #endif /* __RTW_RHASHTABLE_H__ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/sdio_intf.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/sdio_intf.c index 3382563af19d..4eca7948a317 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/sdio_intf.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/sdio_intf.c @@ -31,6 +31,10 @@ #include #endif /* CONFIG_RTL8822C */ +#ifdef CONFIG_RTL8723F +#include /* rtl8723fs_set_hal_ops() */ +#endif /* CONFIG_RTL8723F */ + #ifdef CONFIG_PLATFORM_INTEL_BYT #ifdef CONFIG_ACPI #include @@ -91,6 +95,7 @@ static const struct sdio_device_id sdio_ids[] = { {SDIO_DEVICE(0x024C, 0xB821), .driver_data = RTL8821C}, {SDIO_DEVICE(0x024C, 0xC821), .driver_data = RTL8821C}, {SDIO_DEVICE(0x024C, 0x8733), .driver_data = RTL8821C}, /* 8733AS */ + {SDIO_DEVICE(0x024C, 0xC80C), .driver_data = RTL8821C}, /* 8821CSH-VQ */ #endif #ifdef CONFIG_RTL8822C @@ -98,6 +103,10 @@ static const struct sdio_device_id sdio_ids[] = { {SDIO_DEVICE(0x024c, 0xD821), .class = SDIO_CLASS_WLAN, .driver_data = RTL8822C}, /* 8821DS */ #endif +#ifdef CONFIG_RTL8723F + {SDIO_DEVICE(0x024c, 0xB733), .class = SDIO_CLASS_WLAN, .driver_data = RTL8723F}, +#endif + #if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) /* temporarily add this to accept all sdio wlan id */ { SDIO_DEVICE_CLASS(SDIO_CLASS_WLAN) }, #endif @@ -639,6 +648,12 @@ static void rtw_decide_chip_type_by_device_id(struct dvobj_priv *dvobj, const st } #endif +#if defined(CONFIG_RTL8723F) + if (dvobj->chip_type == RTL8723F) { + dvobj->HardwareType = HARDWARE_TYPE_RTL8723FS; + RTW_INFO("CHIP TYPE: RTL8723F\n"); + } +#endif } static struct dvobj_priv *sdio_dvobj_init(struct sdio_func *func, const struct sdio_device_id *pdid) @@ -761,6 +776,11 @@ u8 rtw_set_hal_ops(PADAPTER padapter) rtl8822cs_set_hal_ops(padapter); #endif +#if defined(CONFIG_RTL8723F) + if (rtw_get_chip_type(padapter) == RTL8723F) + rtl8723fs_set_hal_ops(padapter); +#endif + if (rtw_hal_ops_check(padapter) == _FAIL) return _FAIL; @@ -1258,7 +1278,7 @@ static int rtw_sdio_resume(struct device *dev) pdbgpriv->dbg_resume_cnt++; -#ifdef CONFIG_PLATFORM_INTEL_BYT +#ifdef CONFIG_PLATFORM_ROCKCHIPS if (0) #else if (pwrpriv->wowlan_mode || pwrpriv->wowlan_ap_mode) @@ -1311,6 +1331,10 @@ static int rtw_drv_entry(void) sdio_drvpriv.drv_registered = _TRUE; rtw_suspend_lock_init(); rtw_drv_proc_init(); + rtw_nlrtw_init(); +#ifdef CONFIG_PLATFORM_CMAP_INTFS + cmap_intfs_init(); +#endif rtw_ndev_notifier_register(); rtw_inetaddr_notifier_register(); @@ -1319,6 +1343,10 @@ static int rtw_drv_entry(void) sdio_drvpriv.drv_registered = _FALSE; rtw_suspend_lock_uninit(); rtw_drv_proc_deinit(); + rtw_nlrtw_deinit(); +#ifdef CONFIG_PLATFORM_CMAP_INTFS + cmap_intfs_deinit(); +#endif rtw_ndev_notifier_unregister(); rtw_inetaddr_notifier_unregister(); RTW_INFO("%s: register driver failed!!(%d)\n", __FUNCTION__, ret); @@ -1349,6 +1377,10 @@ static void rtw_drv_halt(void) rtw_suspend_lock_uninit(); rtw_drv_proc_deinit(); + rtw_nlrtw_deinit(); +#ifdef CONFIG_PLATFORM_CMAP_INTFS + cmap_intfs_deinit(); +#endif rtw_ndev_notifier_unregister(); rtw_inetaddr_notifier_unregister(); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/wifi_regd.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/wifi_regd.c index d83c9ba9dd8d..2ad754df1039 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/wifi_regd.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/wifi_regd.c @@ -17,251 +17,10 @@ #include #ifdef CONFIG_IOCTL_CFG80211 - -#include - -/* - *Only these channels all allow active - *scan on all world regulatory domains - */ - -/* 2G chan 01 - chan 11 */ -#define RTW_2GHZ_CH01_11 \ - REG_RULE(2412-10, 2462+10, 40, 0, 20, 0) - -/* - *We enable active scan on these a case - *by case basis by regulatory domain - */ - -/* 2G chan 12 - chan 13, PASSIV SCAN */ -#define RTW_2GHZ_CH12_13 \ - REG_RULE(2467-10, 2472+10, 40, 0, 20, \ - NL80211_RRF_PASSIVE_SCAN) - -/* 5G chan 36 - chan 165 */ -#define RTW_5GHZ_5150_5850 \ - REG_RULE(5150-10, 5850+10, 40, 0, 30, \ - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) - -static const struct ieee80211_regdomain rtw_regdom_rd = { - .n_reg_rules = 3, - .alpha2 = "99", - .reg_rules = { - RTW_2GHZ_CH01_11, - RTW_2GHZ_CH12_13, - RTW_5GHZ_5150_5850, - } -}; - -#if 0 -/* - * REG_RULE(freq start, freq end, bandwidth, max gain, eirp, reg_flags) - */ - -static struct country_code_to_enum_rd allCountries[] = { - {COUNTRY_CODE_USER, "RD"}, -}; - -/* 2G chan 14, PASSIVS SCAN, NO OFDM (B only) */ -#define RTW_2GHZ_CH14 \ - REG_RULE(2484-10, 2484+10, 40, 0, 20, \ - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM) - -/* 5G chan 36 - chan 64 */ -#define RTW_5GHZ_5150_5350 \ - REG_RULE(5150-10, 5350+10, 40, 0, 30, \ - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) - -/* 5G chan 100 - chan 165 */ -#define RTW_5GHZ_5470_5850 \ - REG_RULE(5470-10, 5850+10, 40, 0, 30, \ - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) - -/* 5G chan 149 - chan 165 */ -#define RTW_5GHZ_5725_5850 \ - REG_RULE(5725-10, 5850+10, 40, 0, 30, \ - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) - - -static const struct ieee80211_regdomain rtw_regdom_11 = { - .n_reg_rules = 1, - .alpha2 = "99", - .reg_rules = { - RTW_2GHZ_CH01_11, - } -}; - -static const struct ieee80211_regdomain rtw_regdom_12_13 = { - .n_reg_rules = 2, - .alpha2 = "99", - .reg_rules = { - RTW_2GHZ_CH01_11, - RTW_2GHZ_CH12_13, - } -}; - -static const struct ieee80211_regdomain rtw_regdom_no_midband = { - .n_reg_rules = 3, - .alpha2 = "99", - .reg_rules = { - RTW_2GHZ_CH01_11, - RTW_5GHZ_5150_5350, - RTW_5GHZ_5725_5850, - } -}; - -static const struct ieee80211_regdomain rtw_regdom_60_64 = { - .n_reg_rules = 3, - .alpha2 = "99", - .reg_rules = { - RTW_2GHZ_CH01_11, - RTW_2GHZ_CH12_13, - RTW_5GHZ_5725_5850, - } -}; - -static const struct ieee80211_regdomain rtw_regdom_14_60_64 = { - .n_reg_rules = 4, - .alpha2 = "99", - .reg_rules = { - RTW_2GHZ_CH01_11, - RTW_2GHZ_CH12_13, - RTW_2GHZ_CH14, - RTW_5GHZ_5725_5850, - } -}; - -static const struct ieee80211_regdomain rtw_regdom_14 = { - .n_reg_rules = 3, - .alpha2 = "99", - .reg_rules = { - RTW_2GHZ_CH01_11, - RTW_2GHZ_CH12_13, - RTW_2GHZ_CH14, - } -}; - - -static struct rtw_regulatory *rtw_regd; -#endif - -#if 0 /* not_yet */ -static void _rtw_reg_apply_beaconing_flags(struct wiphy *wiphy, - enum nl80211_reg_initiator initiator) +static void rtw_regd_overide_flags(struct wiphy *wiphy, struct rf_ctl_t *rfctl) { - enum nl80211_band band; - struct ieee80211_supported_band *sband; - const struct ieee80211_reg_rule *reg_rule; - struct ieee80211_channel *ch; - unsigned int i; - u32 bandwidth = 0; - int r; - - for (band = 0; band < NUM_NL80211_BANDS; band++) { - - if (!wiphy->bands[band]) - continue; - - sband = wiphy->bands[band]; - - for (i = 0; i < sband->n_channels; i++) { - ch = &sband->channels[i]; - if (rtw_is_dfs_ch(ch->hw_value) || - (ch->flags & IEEE80211_CHAN_RADAR)) - continue; - if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { - r = freq_reg_info(wiphy, ch->center_freq, - bandwidth, ®_rule); - if (r) - continue; - - /* - *If 11d had a rule for this channel ensure - *we enable adhoc/beaconing if it allows us to - *use it. Note that we would have disabled it - *by applying our static world regdomain by - *default during init, prior to calling our - *regulatory_hint(). - */ - - if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) - ch->flags &= ~IEEE80211_CHAN_NO_IBSS; - if (! - (reg_rule->flags & - NL80211_RRF_PASSIVE_SCAN)) - ch->flags &= - ~IEEE80211_CHAN_PASSIVE_SCAN; - } else { - if (ch->beacon_found) - ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN); - } - } - } -} - -/* Allows active scan scan on Ch 12 and 13 */ -static void _rtw_reg_apply_active_scan_flags(struct wiphy *wiphy, - enum nl80211_reg_initiator - initiator) -{ - struct ieee80211_supported_band *sband; - struct ieee80211_channel *ch; - const struct ieee80211_reg_rule *reg_rule; - u32 bandwidth = 0; - int r; - - if (!wiphy->bands[NL80211_BAND_2GHZ]) - return; - sband = wiphy->bands[NL80211_BAND_2GHZ]; - - /* - * If no country IE has been received always enable active scan - * on these channels. This is only done for specific regulatory SKUs - */ - if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { - ch = &sband->channels[11]; /* CH 12 */ - if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) - ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; - ch = &sband->channels[12]; /* CH 13 */ - if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) - ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; - return; - } - - /* - * If a country IE has been received check its rule for this - * channel first before enabling active scan. The passive scan - * would have been enforced by the initial processing of our - * custom regulatory domain. - */ - - ch = &sband->channels[11]; /* CH 12 */ - r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); - if (!r) { - if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) - if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) - ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; - } - - ch = &sband->channels[12]; /* CH 13 */ - r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); - if (!r) { - if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) - if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) - ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; - } -} -#endif - -void rtw_regd_apply_flags(struct wiphy *wiphy) -{ - struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy); - struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); RT_CHANNEL_INFO *channel_set = rfctl->channel_set; u8 max_chan_nums = rfctl->max_chan_nums; - struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; unsigned int i, j; @@ -271,14 +30,13 @@ void rtw_regd_apply_flags(struct wiphy *wiphy) /* all channels disable */ for (i = 0; i < NUM_NL80211_BANDS; i++) { sband = wiphy->bands[i]; - - if (sband) { - for (j = 0; j < sband->n_channels; j++) { - ch = &sband->channels[j]; - - if (ch) - ch->flags = IEEE80211_CHAN_DISABLED; - } + if (!sband) + continue; + for (j = 0; j < sband->n_channels; j++) { + ch = &sband->channels[j]; + if (!ch) + continue; + ch->flags = IEEE80211_CHAN_DISABLED; } } @@ -286,76 +44,342 @@ void rtw_regd_apply_flags(struct wiphy *wiphy) for (i = 0; i < max_chan_nums; i++) { channel = channel_set[i].ChannelNum; freq = rtw_ch2freq(channel); - ch = ieee80211_get_channel(wiphy, freq); - if (!ch) + if (!ch) { + rtw_warn_on(1); continue; + } - if (channel_set[i].ScanType == SCAN_PASSIVE - #if defined(CONFIG_DFS_MASTER) - && rtw_odm_dfs_domain_unknown(dvobj) - #endif - ) { - #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) - ch->flags = (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN); - #else - ch->flags = IEEE80211_CHAN_NO_IR; - #endif - } else - ch->flags = 0; + /* enable */ + ch->flags = 0; - #if CONFIG_IEEE80211_BAND_5GHZ && CONFIG_DFS - if (rtw_is_dfs_ch(ch->hw_value) - #if defined(CONFIG_DFS_MASTER) - && rtw_odm_dfs_domain_unknown(dvobj) - #endif - ) { - ch->flags |= IEEE80211_CHAN_RADAR; + if (channel_set[i].flags & RTW_CHF_DFS) { + /* + * before integrating with nl80211 flow + * bypass IEEE80211_CHAN_RADAR when configured with radar detection + * to prevent from hostapd blocking DFS channels + */ + if (rtw_rfctl_dfs_domain_unknown(rfctl)) + ch->flags |= IEEE80211_CHAN_RADAR; + } + + if (channel_set[i].flags & RTW_CHF_NO_IR) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) - ch->flags |= (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN); + ch->flags |= IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN; #else ch->flags |= IEEE80211_CHAN_NO_IR; #endif } - #endif /* CONFIG_IEEE80211_BAND_5GHZ && CONFIG_DFS */ } } -static const struct ieee80211_regdomain *_rtw_regdomain_select(struct - rtw_regulatory - *reg) +#ifdef CONFIG_REGD_SRC_FROM_OS +static void rtw_regd_apply_dfs_flags(struct rf_ctl_t *rfctl) { -#if 0 - switch (reg->country_code) { - case COUNTRY_CODE_USER: - default: - return &rtw_regdom_rd; + RT_CHANNEL_INFO *channel_set = rfctl->channel_set; + u8 max_chan_nums = rfctl->max_chan_nums; + unsigned int i; + struct ieee80211_channel *chan; + + /* channels apply by channel plans. */ + for (i = 0; i < max_chan_nums; i++) { + chan = channel_set[i].os_chan; + if (channel_set[i].flags & RTW_CHF_DFS) { + /* + * before integrating with nl80211 flow + * clear IEEE80211_CHAN_RADAR when configured with radar detection + * to prevent from hostapd blocking DFS channels + */ + if (!rtw_rfctl_dfs_domain_unknown(rfctl)) + chan->flags &= ~IEEE80211_CHAN_RADAR; + } } -#else - return &rtw_regdom_rd; -#endif } +#endif + +void rtw_regd_apply_flags(struct wiphy *wiphy) +{ + struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy); + struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); + + if (rfctl->regd_src == REGD_SRC_RTK_PRIV) + rtw_regd_overide_flags(wiphy, rfctl); +#ifdef CONFIG_REGD_SRC_FROM_OS + else if (rfctl->regd_src == REGD_SRC_OS) + rtw_regd_apply_dfs_flags(rfctl); +#endif + else + rtw_warn_on(1); +} + +#ifdef CONFIG_REGD_SRC_FROM_OS +/* init_channel_set_from_wiphy */ +u8 rtw_os_init_channel_set(_adapter *padapter, RT_CHANNEL_INFO *channel_set) +{ + struct wiphy *wiphy = adapter_to_wiphy(padapter); + struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); + struct registry_priv *regsty = adapter_to_regsty(padapter); + struct ieee80211_channel *chan; + u8 chanset_size = 0; + int i, j; + + _rtw_memset(channel_set, 0, sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM); + + for (i = NL80211_BAND_2GHZ; i <= NL80211_BAND_5GHZ; i++) { + if (!wiphy->bands[i]) + continue; + for (j = 0; j < wiphy->bands[i]->n_channels; j++) { + chan = &wiphy->bands[i]->channels[j]; + if (chan->flags & IEEE80211_CHAN_DISABLED) + continue; + if (rtw_regsty_is_excl_chs(regsty, chan->hw_value)) + continue; + + if (chanset_size >= MAX_CHANNEL_NUM) { + RTW_WARN("chset size can't exceed MAX_CHANNEL_NUM(%u)\n", MAX_CHANNEL_NUM); + i = NL80211_BAND_5GHZ + 1; + break; + } + + channel_set[chanset_size].ChannelNum = chan->hw_value; + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) + if (chan->flags & (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN)) + #else + if (chan->flags & IEEE80211_CHAN_NO_IR) + #endif + channel_set[chanset_size].flags |= RTW_CHF_NO_IR; + if (chan->flags & IEEE80211_CHAN_RADAR) + channel_set[chanset_size].flags |= RTW_CHF_DFS; + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) + if (chan->flags & IEEE80211_CHAN_NO_HT40PLUS) + channel_set[chanset_size].flags |= RTW_CHF_NO_HT40U; + if (chan->flags & IEEE80211_CHAN_NO_HT40MINUS) + channel_set[chanset_size].flags |= RTW_CHF_NO_HT40L; + #endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) + if (chan->flags & IEEE80211_CHAN_NO_80MHZ) + channel_set[chanset_size].flags |= RTW_CHF_NO_80MHZ; + if (chan->flags & IEEE80211_CHAN_NO_160MHZ) + channel_set[chanset_size].flags |= RTW_CHF_NO_160MHZ; + #endif + channel_set[chanset_size].os_chan = chan; + chanset_size++; + } + } + +#if CONFIG_IEEE80211_BAND_5GHZ + #ifdef CONFIG_DFS_MASTER + for (i = 0; i < chanset_size; i++) + channel_set[i].non_ocp_end_time = rtw_get_current_time(); + #endif +#endif /* CONFIG_IEEE80211_BAND_5GHZ */ + + if (chanset_size) + RTW_INFO(FUNC_ADPT_FMT" ch num:%d\n" + , FUNC_ADPT_ARG(padapter), chanset_size); + else + RTW_WARN(FUNC_ADPT_FMT" final chset has no channel\n" + , FUNC_ADPT_ARG(padapter)); + + return chanset_size; +} + +s16 rtw_os_get_total_txpwr_regd_lmt_mbm(_adapter *adapter, u8 cch, enum channel_width bw) +{ + struct wiphy *wiphy = adapter_to_wiphy(adapter); + s16 mbm = UNSPECIFIED_MBM; + u8 *op_chs; + u8 op_ch_num; + u8 i; + u32 freq; + struct ieee80211_channel *ch; + + if (!rtw_get_op_chs_by_cch_bw(cch, bw, &op_chs, &op_ch_num)) + goto exit; + + for (i = 0; i < op_ch_num; i++) { + freq = rtw_ch2freq(op_chs[i]); + ch = ieee80211_get_channel(wiphy, freq); + if (!ch) { + rtw_warn_on(1); + continue; + } + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) + mbm = rtw_min(mbm, ch->max_reg_power * MBM_PDBM); + #else + /* require max_power == 0 (therefore orig_mpwr set to 0) when wiphy registration */ + mbm = rtw_min(mbm, ch->max_power * MBM_PDBM); + #endif + } + +exit: + return mbm; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) +static enum rtw_dfs_regd nl80211_dfs_regions_to_rtw_dfs_region(enum nl80211_dfs_regions region) +{ + switch (region) { + case NL80211_DFS_FCC: + return RTW_DFS_REGD_FCC; + case NL80211_DFS_ETSI: + return RTW_DFS_REGD_ETSI; + case NL80211_DFS_JP: + return RTW_DFS_REGD_MKK; + case NL80211_DFS_UNSET: + default: + return RTW_DFS_REGD_NONE; + } +}; +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) */ +#endif /* CONFIG_REGD_SRC_FROM_OS */ + +#ifdef CONFIG_RTW_DEBUG +static const char *nl80211_reg_initiator_str(enum nl80211_reg_initiator initiator) +{ + switch (initiator) { + case NL80211_REGDOM_SET_BY_DRIVER: + return "DRIVER"; + case NL80211_REGDOM_SET_BY_CORE: + return "CORE"; + case NL80211_REGDOM_SET_BY_USER: + return "USER"; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + return "COUNTRY_IE"; + } + rtw_warn_on(1); + return "UNKNOWN"; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) +static const char *nl80211_user_reg_hint_type_str(enum nl80211_user_reg_hint_type type) +{ + switch (type) { + case NL80211_USER_REG_HINT_USER: + return "USER"; + case NL80211_USER_REG_HINT_CELL_BASE: + return "CELL_BASE"; + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)) + case NL80211_USER_REG_HINT_INDOOR: + return "INDOOR"; + #endif + } + rtw_warn_on(1); + return "UNKNOWN"; +} +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) +static const char *nl80211_dfs_regions_str(enum nl80211_dfs_regions region) +{ + switch (region) { + case NL80211_DFS_UNSET: + return "UNSET"; + case NL80211_DFS_FCC: + return "FCC"; + case NL80211_DFS_ETSI: + return "ETSI"; + case NL80211_DFS_JP: + return "JP"; + } + rtw_warn_on(1); + return "UNKNOWN"; +}; +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) */ + +static const char *environment_cap_str(enum environment_cap cap) +{ + switch (cap) { + case ENVIRON_ANY: + return "ANY"; + case ENVIRON_INDOOR: + return "INDOOR"; + case ENVIRON_OUTDOOR: + return "OUTDOOR"; + } + rtw_warn_on(1); + return "UNKNOWN"; +} + +static void dump_requlatory_request(void *sel, struct regulatory_request *request) +{ + u8 alpha2_len; + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)) + alpha2_len = 3; + #else + alpha2_len = 2; + #endif + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + RTW_PRINT_SEL(sel, "initiator:%s, wiphy_idx:%d, type:%s\n" + , nl80211_reg_initiator_str(request->initiator) + , request->wiphy_idx + , nl80211_user_reg_hint_type_str(request->user_reg_hint_type)); + #else + RTW_PRINT_SEL(sel, "initiator:%s, wiphy_idx:%d\n" + , nl80211_reg_initiator_str(request->initiator) + , request->wiphy_idx); + #endif + + RTW_PRINT_SEL(sel, "alpha2:%.*s\n", alpha2_len, request->alpha2); + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) + RTW_PRINT_SEL(sel, "dfs_region:%s\n", nl80211_dfs_regions_str(request->dfs_region)); + #endif + + RTW_PRINT_SEL(sel, "intersect:%d\n", request->intersect); + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) + RTW_PRINT_SEL(sel, "processed:%d\n", request->processed); + #endif + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)) + RTW_PRINT_SEL(sel, "country_ie_checksum:0x%08x\n", request->country_ie_checksum); + #endif + + RTW_PRINT_SEL(sel, "country_ie_env:%s\n", environment_cap_str(request->country_ie_env)); +} +#endif /* CONFIG_RTW_DEBUG */ static void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) { - switch (request->initiator) { - case NL80211_REGDOM_SET_BY_DRIVER: - RTW_INFO("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_DRIVER"); - break; - case NL80211_REGDOM_SET_BY_CORE: - RTW_INFO("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_CORE"); - break; - case NL80211_REGDOM_SET_BY_USER: - RTW_INFO("%s: %s alpha2:%c%c\n", __func__, "NL80211_REGDOM_SET_BY_USER" - , request->alpha2[0], request->alpha2[1]); - rtw_set_country(wiphy_to_adapter(wiphy), request->alpha2); - break; - case NL80211_REGDOM_SET_BY_COUNTRY_IE: - RTW_INFO("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_COUNTRY_IE"); - break; - } + struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy); + struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); + struct registry_priv *regsty = dvobj_to_regsty(dvobj); - rtw_regd_apply_flags(wiphy); +#ifdef CONFIG_RTW_DEBUG + if (rtw_drv_log_level >= _DRV_INFO_) { + RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy)); + dump_requlatory_request(RTW_DBGDUMP, request); + } +#endif + +#ifdef CONFIG_REGD_SRC_FROM_OS + if (REGSTY_REGD_SRC_FROM_OS(regsty)) { + enum rtw_dfs_regd dfs_region = RTW_DFS_REGD_NONE; + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) + dfs_region = nl80211_dfs_regions_to_rtw_dfs_region(request->dfs_region); + #endif + + /* trigger command to sync regulatory form OS */ + rtw_sync_os_regd_cmd(wiphy_to_adapter(wiphy), RTW_CMDF_WAIT_ACK, request->alpha2, dfs_region); + } else +#endif + { + /* use alpha2 as input to select the corresponding channel plan settings defined by Realtek */ + switch (request->initiator) { + case NL80211_REGDOM_SET_BY_DRIVER: + break; + case NL80211_REGDOM_SET_BY_CORE: + break; + case NL80211_REGDOM_SET_BY_USER: + rtw_set_country(wiphy_to_adapter(wiphy), request->alpha2); + break; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + break; + } + + rtw_regd_apply_flags(wiphy); + } } #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)) @@ -366,10 +390,8 @@ static int rtw_reg_notifier_return(struct wiphy *wiphy, struct regulatory_reques } #endif -static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg, struct wiphy *wiphy) +int rtw_regd_init(struct wiphy *wiphy) { - const struct ieee80211_regdomain *regd; - #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)) wiphy->reg_notifier = rtw_reg_notifier_return; #else @@ -377,40 +399,13 @@ static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg, struct wiphy *wiphy #endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) - wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY; wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS; #else - wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; #endif - regd = _rtw_regdomain_select(reg); - wiphy_apply_custom_regulatory(wiphy, regd); - - rtw_regd_apply_flags(wiphy); -} - -int rtw_regd_init(struct wiphy *wiphy) -{ -#if 0 - if (rtw_regd == NULL) { - rtw_regd = (struct rtw_regulatory *) - rtw_malloc(sizeof(struct rtw_regulatory)); - - rtw_regd->alpha2[0] = '9'; - rtw_regd->alpha2[1] = '9'; - - rtw_regd->country_code = COUNTRY_CODE_USER; - } - - RTW_INFO("%s: Country alpha2 being used: %c%c\n", - __func__, rtw_regd->alpha2[0], rtw_regd->alpha2[1]); -#endif - - _rtw_regd_init_wiphy(NULL, wiphy); - return 0; } #endif /* CONFIG_IOCTL_CFG80211 */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_wifi_regd.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/wifi_regd.h similarity index 71% rename from drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_wifi_regd.h rename to drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/wifi_regd.h index b5c5d62ff76e..d87be171a890 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/include/rtw_wifi_regd.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/wifi_regd.h @@ -14,22 +14,15 @@ * *****************************************************************************/ -#ifndef __RTW_WIFI_REGD_H__ -#define __RTW_WIFI_REGD_H__ - -struct country_code_to_enum_rd { - u16 countrycode; - const char *iso_name; -}; - -enum country_code_type_t { - COUNTRY_CODE_USER = 0, - - /*add new channel plan above this line */ - COUNTRY_CODE_MAX -}; +#ifndef __WIFI_REGD_H__ +#define __WIFI_REGD_H__ void rtw_regd_apply_flags(struct wiphy *wiphy); +#ifdef CONFIG_REGD_SRC_FROM_OS +struct _RT_CHANNEL_INFO; +u8 rtw_os_init_channel_set(_adapter *padapter, struct _RT_CHANNEL_INFO *channel_set); +s16 rtw_os_get_total_txpwr_regd_lmt_mbm(_adapter *adapter, u8 cch, enum channel_width bw); +#endif int rtw_regd_init(struct wiphy *wiphy); -#endif /* __RTW_WIFI_REGD_H__ */ +#endif /* __WIFI_REGD_H__ */ diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/xmit_linux.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/xmit_linux.c index 4fb6885a7935..3e1f28b0377f 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/xmit_linux.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/linux/xmit_linux.c @@ -200,13 +200,13 @@ void dump_os_queue(void *sel, _adapter *padapter) #define WMM_XMIT_THRESHOLD (NR_XMITFRAME*2/5) -static inline bool rtw_os_need_wake_queue(_adapter *padapter, u16 qidx) +static inline bool rtw_os_need_wake_queue(_adapter *padapter, u16 os_qid) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) struct xmit_priv *pxmitpriv = &padapter->xmitpriv; if (padapter->registrypriv.wifi_spec) { - if (pxmitpriv->hwxmits[qidx].accnt < WMM_XMIT_THRESHOLD) + if (pxmitpriv->hwxmits[os_qid].accnt < WMM_XMIT_THRESHOLD) return _TRUE; #ifdef DBG_CONFIG_ERROR_DETECT #ifdef DBG_CONFIG_ERROR_RESET @@ -237,13 +237,13 @@ static inline bool rtw_os_need_wake_queue(_adapter *padapter, u16 qidx) #endif } -static inline bool rtw_os_need_stop_queue(_adapter *padapter, u16 qidx) +static inline bool rtw_os_need_stop_queue(_adapter *padapter, u16 os_qid) { struct xmit_priv *pxmitpriv = &padapter->xmitpriv; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) if (padapter->registrypriv.wifi_spec) { /* No free space for Tx, tx_worker is too slow */ - if (pxmitpriv->hwxmits[qidx].accnt > WMM_XMIT_THRESHOLD) + if (pxmitpriv->hwxmits[os_qid].accnt > WMM_XMIT_THRESHOLD) return _TRUE; } else { if (pxmitpriv->free_xmitframe_cnt <= 4) @@ -258,23 +258,6 @@ static inline bool rtw_os_need_stop_queue(_adapter *padapter, u16 qidx) void rtw_os_pkt_complete(_adapter *padapter, _pkt *pkt) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) - u16 qidx; - - qidx = skb_get_queue_mapping(pkt); - if (rtw_os_need_wake_queue(padapter, qidx)) { - if (DBG_DUMP_OS_QUEUE_CTL) - RTW_INFO(FUNC_ADPT_FMT": netif_wake_subqueue[%d]\n", FUNC_ADPT_ARG(padapter), qidx); - netif_wake_subqueue(padapter->pnetdev, qidx); - } -#else - if (rtw_os_need_wake_queue(padapter, 0)) { - if (DBG_DUMP_OS_QUEUE_CTL) - RTW_INFO(FUNC_ADPT_FMT": netif_wake_queue\n", FUNC_ADPT_ARG(padapter)); - netif_wake_queue(padapter->pnetdev); - } -#endif - rtw_skb_free(pkt); } @@ -324,24 +307,39 @@ void rtw_os_xmit_schedule(_adapter *padapter) #endif } -static bool rtw_check_xmit_resource(_adapter *padapter, _pkt *pkt) +void rtw_os_check_wakup_queue(_adapter *adapter, u16 os_qid) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) + if (rtw_os_need_wake_queue(adapter, os_qid)) { + if (DBG_DUMP_OS_QUEUE_CTL) + RTW_INFO(FUNC_ADPT_FMT": netif_wake_subqueue[%d]\n", FUNC_ADPT_ARG(adapter), os_qid); + netif_wake_subqueue(adapter->pnetdev, os_qid); + } +#else + if (rtw_os_need_wake_queue(adapter, 0)) { + if (DBG_DUMP_OS_QUEUE_CTL) + RTW_INFO(FUNC_ADPT_FMT": netif_wake_queue\n", FUNC_ADPT_ARG(adapter)); + netif_wake_queue(adapter->pnetdev); + } +#endif +} + +bool rtw_os_check_stop_queue(_adapter *adapter, u16 os_qid) { bool busy = _FALSE; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) - u16 qidx; - qidx = skb_get_queue_mapping(pkt); - if (rtw_os_need_stop_queue(padapter, qidx)) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) + if (rtw_os_need_stop_queue(adapter, os_qid)) { if (DBG_DUMP_OS_QUEUE_CTL) - RTW_INFO(FUNC_ADPT_FMT": netif_stop_subqueue[%d]\n", FUNC_ADPT_ARG(padapter), qidx); - netif_stop_subqueue(padapter->pnetdev, qidx); + RTW_INFO(FUNC_ADPT_FMT": netif_stop_subqueue[%d]\n", FUNC_ADPT_ARG(adapter), os_qid); + netif_stop_subqueue(adapter->pnetdev, os_qid); busy = _TRUE; } #else - if (rtw_os_need_stop_queue(padapter, 0)) { + if (rtw_os_need_stop_queue(adapter, 0)) { if (DBG_DUMP_OS_QUEUE_CTL) - RTW_INFO(FUNC_ADPT_FMT": netif_stop_queue\n", FUNC_ADPT_ARG(padapter)); - rtw_netif_stop_queue(padapter->pnetdev); + RTW_INFO(FUNC_ADPT_FMT": netif_stop_queue\n", FUNC_ADPT_ARG(adapter)); + rtw_netif_stop_queue(adapter->pnetdev); busy = _TRUE; } #endif @@ -374,97 +372,16 @@ void rtw_os_wake_queue_at_free_stainfo(_adapter *padapter, int *qcnt_freed) #endif } -#ifdef CONFIG_TX_MCAST2UNI -int rtw_mlcst2unicst(_adapter *padapter, struct sk_buff *skb) -{ - struct sta_priv *pstapriv = &padapter->stapriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - _irqL irqL; - _list *phead, *plist; - struct sk_buff *newskb; - struct sta_info *psta = NULL; - u8 chk_alive_num = 0; - char chk_alive_list[NUM_STA]; - u8 bc_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - u8 null_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - int i; - s32 res; - - DBG_COUNTER(padapter->tx_logs.os_tx_m2u); - - _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); - phead = &pstapriv->asoc_list; - plist = get_next(phead); - - /* free sta asoc_queue */ - while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { - int stainfo_offset; - psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); - plist = get_next(plist); - - stainfo_offset = rtw_stainfo_offset(pstapriv, psta); - if (stainfo_offset_valid(stainfo_offset)) - chk_alive_list[chk_alive_num++] = stainfo_offset; - } - _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); - - for (i = 0; i < chk_alive_num; i++) { - psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]); - if (!(psta->state & WIFI_ASOC_STATE)) { - DBG_COUNTER(padapter->tx_logs.os_tx_m2u_ignore_fw_linked); - continue; - } - - /* avoid come from STA1 and send back STA1 */ - if (_rtw_memcmp(psta->cmn.mac_addr, &skb->data[6], ETH_ALEN) == _TRUE - || _rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN) == _TRUE - || _rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) == _TRUE - ) { - DBG_COUNTER(padapter->tx_logs.os_tx_m2u_ignore_self); - continue; - } - - DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry); - - newskb = rtw_skb_copy(skb); - - if (newskb) { - _rtw_memcpy(newskb->data, psta->cmn.mac_addr, ETH_ALEN); - res = rtw_xmit(padapter, &newskb); - if (res < 0) { - DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry_err_xmit); - RTW_INFO("%s()-%d: rtw_xmit() return error! res=%d\n", __FUNCTION__, __LINE__, res); - pxmitpriv->tx_drop++; - rtw_skb_free(newskb); - } - } else { - DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry_err_skb); - RTW_INFO("%s-%d: rtw_skb_copy() failed!\n", __FUNCTION__, __LINE__); - pxmitpriv->tx_drop++; - /* rtw_skb_free(skb); */ - return _FALSE; /* Caller shall tx this multicast frame via normal way. */ - } - } - - rtw_skb_free(skb); - return _TRUE; -} -#endif /* CONFIG_TX_MCAST2UNI */ - - int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) { _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; -#ifdef CONFIG_TX_MCAST2UNI - extern int rtw_mc2u_disable; -#endif /* CONFIG_TX_MCAST2UNI */ #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX struct sk_buff *skb = pkt; struct sk_buff *segs, *nskb; netdev_features_t features = padapter->pnetdev->features; #endif + u16 os_qid = 0; s32 res = 0; if (padapter->registrypriv.mp_mode) { @@ -481,30 +398,9 @@ int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) goto drop_packet; } - rtw_check_xmit_resource(padapter, pkt); - -#ifdef CONFIG_TX_MCAST2UNI - if (!rtw_mc2u_disable - && MLME_IS_AP(padapter) - && (IP_MCAST_MAC(pkt->data) - || ICMPV6_MCAST_MAC(pkt->data) - #ifdef CONFIG_TX_BCAST2UNI - || is_broadcast_mac_addr(pkt->data) - #endif - ) - && (padapter->registrypriv.wifi_spec == 0) - ) { - if (pxmitpriv->free_xmitframe_cnt > (NR_XMITFRAME / 4)) { - res = rtw_mlcst2unicst(padapter, pkt); - if (res == _TRUE) - goto exit; - } else { - /* RTW_INFO("Stop M2U(%d, %d)! ", pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmitbuf_cnt); */ - /* RTW_INFO("!m2u ); */ - DBG_COUNTER(padapter->tx_logs.os_tx_m2u_stop); - } - } -#endif /* CONFIG_TX_MCAST2UNI */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) + os_qid = skb_get_queue_mapping(pkt); +#endif #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX if (skb_shinfo(skb)->gso_size) { @@ -519,7 +415,7 @@ int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) segs = segs->next; nskb->next = NULL; rtw_mstat_update( MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, nskb->truesize); - res = rtw_xmit(padapter, &nskb); + res = rtw_xmit(padapter, &nskb, os_qid); if (res < 0) { #ifdef DBG_TX_DROP_FRAME RTW_INFO("DBG_TX_DROP_FRAME %s rtw_xmit fail\n", __FUNCTION__); @@ -533,7 +429,7 @@ int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) } #endif - res = rtw_xmit(padapter, &pkt); + res = rtw_xmit(padapter, &pkt, os_qid); if (res < 0) { #ifdef DBG_TX_DROP_FRAME RTW_INFO("DBG_TX_DROP_FRAME %s rtw_xmit fail\n", __FUNCTION__); diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/osdep_service.c b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/osdep_service.c index e72ce6e05a81..c08776c7d870 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/osdep_service.c +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/os_dep/osdep_service.c @@ -1629,6 +1629,231 @@ inline bool _rtw_time_after(systime a, systime b) #endif } +sysptime rtw_sptime_get(void) +{ + /* CLOCK_MONOTONIC */ +#ifdef PLATFORM_LINUX + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) + struct timespec64 cur; + + ktime_get_ts64(&cur); + return timespec64_to_ktime(cur); + #else + struct timespec cur; + + ktime_get_ts(&cur); + return timespec_to_ktime(cur); + #endif +#else + #error "TBD\n" +#endif +} + +sysptime rtw_sptime_set(s64 secs, const u32 nsecs) +{ +#ifdef PLATFORM_LINUX + return ktime_set(secs, nsecs); +#else + #error "TBD\n" +#endif +} + +sysptime rtw_sptime_zero(void) +{ +#ifdef PLATFORM_LINUX + return ktime_set(0, 0); +#else + #error "TBD\n" +#endif +} + +/* + * cmp1 < cmp2: return <0 + * cmp1 == cmp2: return 0 + * cmp1 > cmp2: return >0 + */ +int rtw_sptime_cmp(const sysptime cmp1, const sysptime cmp2) +{ +#ifdef PLATFORM_LINUX + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) + return ktime_compare(cmp1, cmp2); + #else + if (cmp1.tv64 < cmp2.tv64) + return -1; + if (cmp1.tv64 > cmp2.tv64) + return 1; + return 0; + #endif +#else + #error "TBD\n" +#endif +} + +bool rtw_sptime_eql(const sysptime cmp1, const sysptime cmp2) +{ +#ifdef PLATFORM_LINUX + return rtw_sptime_cmp(cmp1, cmp2) == 0; +#else + #error "TBD\n" +#endif +} + +bool rtw_sptime_is_zero(const sysptime sptime) +{ +#ifdef PLATFORM_LINUX + return rtw_sptime_cmp(sptime, rtw_sptime_zero()) == 0; +#else + #error "TBD\n" +#endif +} + +/* + * sub = lhs - rhs, in normalized form + */ +sysptime rtw_sptime_sub(const sysptime lhs, const sysptime rhs) +{ +#ifdef PLATFORM_LINUX + return ktime_sub(lhs, rhs); +#else + #error "TBD\n" +#endif +} + +/* + * add = lhs + rhs, in normalized form + */ +sysptime rtw_sptime_add(const sysptime lhs, const sysptime rhs) +{ +#ifdef PLATFORM_LINUX + return ktime_add(lhs, rhs); +#else + #error "TBD\n" +#endif +} + +s64 rtw_sptime_to_ms(const sysptime sptime) +{ +#ifdef PLATFORM_LINUX + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) + return ktime_to_ms(sptime); + #else + struct timeval tv = ktime_to_timeval(sptime); + + return (s64) tv.tv_sec * MSEC_PER_SEC + tv.tv_usec / USEC_PER_MSEC; + #endif +#else + #error "TBD\n" +#endif +} + +sysptime rtw_ms_to_sptime(u64 ms) +{ +#ifdef PLATFORM_LINUX + return ns_to_ktime(ms * NSEC_PER_MSEC); +#else + #error "TBD\n" +#endif +} + +s64 rtw_sptime_to_us(const sysptime sptime) +{ +#ifdef PLATFORM_LINUX + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)) + return ktime_to_us(sptime); + #else + struct timeval tv = ktime_to_timeval(sptime); + + return (s64) tv.tv_sec * USEC_PER_SEC + tv.tv_usec; + #endif +#else + #error "TBD\n" +#endif +} + +sysptime rtw_us_to_sptime(u64 us) +{ +#ifdef PLATFORM_LINUX + return ns_to_ktime(us * NSEC_PER_USEC); +#else + #error "TBD\n" +#endif +} + +s64 rtw_sptime_to_ns(const sysptime sptime) +{ +#ifdef PLATFORM_LINUX + return ktime_to_ns(sptime); +#else + #error "TBD\n" +#endif +} + +sysptime rtw_ns_to_sptime(u64 ns) +{ +#ifdef PLATFORM_LINUX + return ns_to_ktime(ns); +#else + #error "TBD\n" +#endif +} + +s64 rtw_sptime_diff_ms(const sysptime start, const sysptime end) +{ + sysptime diff; + + diff = rtw_sptime_sub(end, start); + + return rtw_sptime_to_ms(diff); +} + +s64 rtw_sptime_pass_ms(const sysptime start) +{ + sysptime cur, diff; + + cur = rtw_sptime_get(); + diff = rtw_sptime_sub(cur, start); + + return rtw_sptime_to_ms(diff); +} + +s64 rtw_sptime_diff_us(const sysptime start, const sysptime end) +{ + sysptime diff; + + diff = rtw_sptime_sub(end, start); + + return rtw_sptime_to_us(diff); +} + +s64 rtw_sptime_pass_us(const sysptime start) +{ + sysptime cur, diff; + + cur = rtw_sptime_get(); + diff = rtw_sptime_sub(cur, start); + + return rtw_sptime_to_us(diff); +} + +s64 rtw_sptime_diff_ns(const sysptime start, const sysptime end) +{ + sysptime diff; + + diff = rtw_sptime_sub(end, start); + + return rtw_sptime_to_ns(diff); +} + +s64 rtw_sptime_pass_ns(const sysptime start) +{ + sysptime cur, diff; + + cur = rtw_sptime_get(); + diff = rtw_sptime_sub(cur, start); + + return rtw_sptime_to_ns(diff); +} + void rtw_sleep_schedulable(int ms) { @@ -1823,6 +2048,46 @@ void rtw_yield_os(void) #endif } +const char *_rtw_pwait_type_str[] = { + [RTW_PWAIT_TYPE_MSLEEP] = "MS", + [RTW_PWAIT_TYPE_USLEEP] = "US", + [RTW_PWAIT_TYPE_YIELD] = "Y", + [RTW_PWAIT_TYPE_MDELAY] = "MD", + [RTW_PWAIT_TYPE_UDELAY] = "UD", + [RTW_PWAIT_TYPE_NUM] = "unknown", +}; + +static void rtw_pwctx_yield(int us) +{ + rtw_yield_os(); +} + +static void (*const rtw_pwait_hdl[])(int)= { + [RTW_PWAIT_TYPE_MSLEEP] = rtw_msleep_os, + [RTW_PWAIT_TYPE_USLEEP] = rtw_usleep_os, + [RTW_PWAIT_TYPE_YIELD] = rtw_pwctx_yield, + [RTW_PWAIT_TYPE_MDELAY] = rtw_mdelay_os, + [RTW_PWAIT_TYPE_UDELAY] = rtw_udelay_os, +}; + +int rtw_pwctx_config(struct rtw_pwait_ctx *pwctx, enum rtw_pwait_type type, s32 time, s32 cnt_lmt) +{ + int ret = _FAIL; + + if (!RTW_PWAIT_TYPE_VALID(type)) + goto exit; + + pwctx->conf.type = type; + pwctx->conf.wait_time = time; + pwctx->conf.wait_cnt_lmt = cnt_lmt; + pwctx->wait_hdl = rtw_pwait_hdl[type]; + + ret = _SUCCESS; + +exit: + return ret; +} + bool rtw_macaddr_is_larger(const u8 *a, const u8 *b) { u32 va, vb; @@ -2519,65 +2784,6 @@ RETURN: return; } -int rtw_change_ifname(_adapter *padapter, const char *ifname) -{ - struct dvobj_priv *dvobj; - struct net_device *pnetdev; - struct net_device *cur_pnetdev; - struct rereg_nd_name_data *rereg_priv; - int ret; - u8 rtnl_lock_needed; - - if (!padapter) - goto error; - - dvobj = adapter_to_dvobj(padapter); - cur_pnetdev = padapter->pnetdev; - rereg_priv = &padapter->rereg_nd_name_priv; - - /* free the old_pnetdev */ - if (rereg_priv->old_pnetdev) { - free_netdev(rereg_priv->old_pnetdev); - rereg_priv->old_pnetdev = NULL; - } - - rtnl_lock_needed = rtw_rtnl_lock_needed(dvobj); - - if (rtnl_lock_needed) - unregister_netdev(cur_pnetdev); - else - unregister_netdevice(cur_pnetdev); - - rereg_priv->old_pnetdev = cur_pnetdev; - - pnetdev = rtw_init_netdev(padapter); - if (!pnetdev) { - ret = -1; - goto error; - } - - SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter))); - - rtw_init_netdev_name(pnetdev, ifname); - - _rtw_memcpy(pnetdev->dev_addr, adapter_mac_addr(padapter), ETH_ALEN); - - if (rtnl_lock_needed) - ret = register_netdev(pnetdev); - else - ret = register_netdevice(pnetdev); - - if (ret != 0) { - goto error; - } - - return 0; - -error: - - return -1; - -} #endif #ifdef PLATFORM_FREEBSD @@ -2932,6 +3138,7 @@ exit: return val; } +#ifdef CONFIG_RTW_MESH int rtw_blacklist_add(_queue *blist, const u8 *addr, u32 timeout_ms) { struct blacklist_ent *ent; @@ -3089,6 +3296,7 @@ void dump_blacklist(void *sel, _queue *blist, const char *title) } exit_critical_bh(&blist->lock); } +#endif /** * is_null - @@ -3219,3 +3427,30 @@ int hexstr2bin(const char *hex, u8 *buf, size_t len) return 0; } +/** + * hwaddr_aton - Convert ASCII string to MAC address + * @txt: MAC address as a string (e.g., "00:11:22:33:44:55") + * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) + * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) + */ +int hwaddr_aton_i(const char *txt, u8 *addr) +{ + int i; + + for (i = 0; i < 6; i++) { + int a, b; + + a = hex2num_i(*txt++); + if (a < 0) + return -1; + b = hex2num_i(*txt++); + if (b < 0) + return -1; + *addr++ = (a << 4) | b; + if (i < 5 && *txt++ != ':') + return -1; + } + + return 0; +} + diff --git a/drivers/net/wireless/rockchip_wlan/rtl8821cs/platform/custom_country_chplan.h b/drivers/net/wireless/rockchip_wlan/rtl8821cs/platform/custom_country_chplan.h index 30322fa85a6b..dfe139612178 100644 --- a/drivers/net/wireless/rockchip_wlan/rtl8821cs/platform/custom_country_chplan.h +++ b/drivers/net/wireless/rockchip_wlan/rtl8821cs/platform/custom_country_chplan.h @@ -18,6 +18,6 @@ #error "Before removing these error notifications, please make sure regulatory certification requirements of your target markets" static const struct country_chplan CUSTOMIZED_country_chplan_map[] = { - COUNTRY_CHPLAN_ENT("TW", 0x76, 1, 0x3FF), /* Taiwan */ + COUNTRY_CHPLAN_ENT("TW", 0x76, 1), /* Taiwan */ };