[PATCH 3/7] staging: rtl8188eu: introduce new hal dir for RTL8188eu driver

From: Phillip Potter
Date: Thu Jul 22 2021 - 20:43:26 EST


This patchset is split in order to keep the file sizes down. This hal
directory is part of the newer/better driver from GitHub modified by
Larry Finger. Import this as the basis for all future work going
forward.

Suggested-by: Larry Finger <Larry.Finger@xxxxxxxxxxxx>
Signed-off-by: Phillip Potter <phil@xxxxxxxxxxxxxxxx>
---
.../staging/rtl8188eu/hal/Hal8188EPwrSeq.c | 71 +
.../rtl8188eu/hal/HalEfuseMask8188E_USB.c | 84 +
.../rtl8188eu/hal/HalEfuseMask8188E_USB.h | 23 +
drivers/staging/rtl8188eu/hal/HalPwrSeqCmd.c | 145 +
.../staging/rtl8188eu/hal/btc/halbtcoutsrc.h | 997 ++
.../staging/rtl8188eu/hal/btc/mp_precomp.h | 49 +
drivers/staging/rtl8188eu/hal/efuse_mask.h | 2 +
drivers/staging/rtl8188eu/hal/hal8188e_s_fw.c | 7283 +++++++++++
drivers/staging/rtl8188eu/hal/hal8188e_s_fw.h | 26 +
drivers/staging/rtl8188eu/hal/hal8188e_t_fw.c | 7730 ++++++++++++
drivers/staging/rtl8188eu/hal/hal8188e_t_fw.h | 25 +
.../rtl8188eu/hal/hal8188erateadaptive.c | 1022 ++
.../rtl8188eu/hal/hal8188erateadaptive.h | 65 +
drivers/staging/rtl8188eu/hal/hal8188ereg.h | 48 +
drivers/staging/rtl8188eu/hal/hal_btcoex.c | 3786 ++++++
.../rtl8188eu/hal/hal_btcoex_wifionly.c | 131 +
drivers/staging/rtl8188eu/hal/hal_com.c | 10540 ++++++++++++++++
drivers/staging/rtl8188eu/hal/hal_com_c2h.h | 103 +
.../staging/rtl8188eu/hal/hal_com_phycfg.c | 5150 ++++++++
drivers/staging/rtl8188eu/hal/hal_dm.c | 186 +
drivers/staging/rtl8188eu/hal/hal_dm.h | 9 +
drivers/staging/rtl8188eu/hal/hal_intf.c | 1279 ++
drivers/staging/rtl8188eu/hal/hal_mcc.c | 1862 +++
drivers/staging/rtl8188eu/hal/hal_mp.c | 883 ++
drivers/staging/rtl8188eu/hal/hal_phy.c | 244 +
drivers/staging/rtl8188eu/hal/hal_usb.c | 452 +
drivers/staging/rtl8188eu/hal/hal_usb_led.c | 4235 +++++++
drivers/staging/rtl8188eu/hal/halcomtxbf.h | 135 +
drivers/staging/rtl8188eu/hal/halhwimg.h | 78 +
.../staging/rtl8188eu/hal/halhwimg8188e_bb.c | 1730 +++
.../staging/rtl8188eu/hal/halhwimg8188e_bb.h | 42 +
.../staging/rtl8188eu/hal/halhwimg8188e_mac.c | 272 +
.../staging/rtl8188eu/hal/halhwimg8188e_mac.h | 22 +
.../staging/rtl8188eu/hal/halhwimg8188e_rf.c | 2183 ++++
.../staging/rtl8188eu/hal/halhwimg8188e_rf.h | 112 +
.../staging/rtl8188eu/hal/halphyrf_8188e_ce.c | 1973 +++
.../staging/rtl8188eu/hal/halphyrf_8188e_ce.h | 92 +
drivers/staging/rtl8188eu/hal/halphyrf_ap.h | 76 +
drivers/staging/rtl8188eu/hal/halphyrf_ce.c | 635 +
drivers/staging/rtl8188eu/hal/halphyrf_ce.h | 81 +
.../staging/rtl8188eu/hal/haltxbfinterface.h | 14 +
drivers/staging/rtl8188eu/hal/haltxbfjaguar.h | 74 +
drivers/staging/rtl8188eu/hal/mp_precomp.h | 3 +
drivers/staging/rtl8188eu/hal/phydm.c | 2341 ++++
drivers/staging/rtl8188eu/hal/phydm.h | 1069 ++
drivers/staging/rtl8188eu/hal/phydm_acs.c | 167 +
drivers/staging/rtl8188eu/hal/phydm_acs.h | 50 +
.../staging/rtl8188eu/hal/phydm_adaptivity.c | 823 ++
.../staging/rtl8188eu/hal/phydm_adaptivity.h | 159 +
.../rtl8188eu/hal/phydm_adc_sampling.c | 594 +
.../rtl8188eu/hal/phydm_adc_sampling.h | 123 +
drivers/staging/rtl8188eu/hal/phydm_antdect.c | 847 ++
drivers/staging/rtl8188eu/hal/phydm_antdect.h | 78 +
drivers/staging/rtl8188eu/hal/phydm_antdiv.c | 3194 +++++
drivers/staging/rtl8188eu/hal/phydm_antdiv.h | 516 +
.../staging/rtl8188eu/hal/phydm_beamforming.h | 27 +
drivers/staging/rtl8188eu/hal/phydm_ccx.c | 389 +
drivers/staging/rtl8188eu/hal/phydm_ccx.h | 102 +
.../staging/rtl8188eu/hal/phydm_cfotracking.c | 297 +
.../staging/rtl8188eu/hal/phydm_cfotracking.h | 53 +
drivers/staging/rtl8188eu/hal/phydm_debug.c | 2357 ++++
drivers/staging/rtl8188eu/hal/phydm_debug.h | 294 +
drivers/staging/rtl8188eu/hal/phydm_dfs.c | 241 +
drivers/staging/rtl8188eu/hal/phydm_dfs.h | 59 +
drivers/staging/rtl8188eu/hal/phydm_dig.c | 1305 ++
drivers/staging/rtl8188eu/hal/phydm_dig.h | 292 +
.../rtl8188eu/hal/phydm_dynamic_rx_path.c | 271 +
.../rtl8188eu/hal/phydm_dynamic_rx_path.h | 93 +
.../hal/phydm_dynamicbbpowersaving.c | 90 +
.../hal/phydm_dynamicbbpowersaving.h | 41 +
.../rtl8188eu/hal/phydm_dynamictxpower.c | 132 +
.../rtl8188eu/hal/phydm_dynamictxpower.h | 69 +
.../rtl8188eu/hal/phydm_edcaturbocheck.c | 192 +
.../rtl8188eu/hal/phydm_edcaturbocheck.h | 49 +
.../staging/rtl8188eu/hal/phydm_features.h | 38 +
.../rtl8188eu/hal/phydm_hal_txbf_api.c | 72 +
.../rtl8188eu/hal/phydm_hal_txbf_api.h | 28 +
.../staging/rtl8188eu/hal/phydm_hwconfig.c | 2102 +++
.../staging/rtl8188eu/hal/phydm_hwconfig.h | 547 +
.../staging/rtl8188eu/hal/phydm_interface.c | 451 +
.../staging/rtl8188eu/hal/phydm_interface.h | 351 +
drivers/staging/rtl8188eu/hal/phydm_iqk.h | 49 +
drivers/staging/rtl8188eu/hal/phydm_kfree.c | 164 +
drivers/staging/rtl8188eu/hal/phydm_kfree.h | 29 +
.../rtl8188eu/hal/phydm_noisemonitor.c | 270 +
.../rtl8188eu/hal/phydm_noisemonitor.h | 31 +
drivers/staging/rtl8188eu/hal/phydm_pathdiv.c | 95 +
drivers/staging/rtl8188eu/hal/phydm_pathdiv.h | 136 +
.../rtl8188eu/hal/phydm_powertracking_ce.c | 646 +
.../rtl8188eu/hal/phydm_powertracking_ce.h | 285 +
.../staging/rtl8188eu/hal/phydm_pre_define.h | 578 +
drivers/staging/rtl8188eu/hal/phydm_precomp.h | 60 +
drivers/staging/rtl8188eu/hal/phydm_rainfo.c | 2198 ++++
drivers/staging/rtl8188eu/hal/phydm_rainfo.h | 484 +
drivers/staging/rtl8188eu/hal/phydm_reg.h | 116 +
.../rtl8188eu/hal/phydm_regconfig8188e.c | 184 +
.../rtl8188eu/hal/phydm_regconfig8188e.h | 79 +
.../rtl8188eu/hal/phydm_regdefine11ac.h | 77 +
.../rtl8188eu/hal/phydm_regdefine11n.h | 196 +
.../staging/rtl8188eu/hal/phydm_rtl8188e.c | 56 +
.../staging/rtl8188eu/hal/phydm_rtl8188e.h | 51 +
drivers/staging/rtl8188eu/hal/phydm_types.h | 142 +
drivers/staging/rtl8188eu/hal/rtchnlplan.c | 287 +
drivers/staging/rtl8188eu/hal/rtchnlplan.h | 615 +
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c | 790 ++
drivers/staging/rtl8188eu/hal/rtl8188e_dm.c | 275 +
.../staging/rtl8188eu/hal/rtl8188e_hal_init.c | 4629 +++++++
.../staging/rtl8188eu/hal/rtl8188e_phycfg.c | 1713 +++
.../staging/rtl8188eu/hal/rtl8188e_rf6052.c | 245 +
.../staging/rtl8188eu/hal/rtl8188e_rxdesc.c | 76 +
.../staging/rtl8188eu/hal/rtl8188e_sreset.c | 84 +
drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c | 290 +
drivers/staging/rtl8188eu/hal/rtl8188eu_led.c | 144 +
.../staging/rtl8188eu/hal/rtl8188eu_recv.c | 17 +
.../staging/rtl8188eu/hal/rtl8188eu_xmit.c | 1261 ++
drivers/staging/rtl8188eu/hal/usb_halinit.c | 2135 ++++
drivers/staging/rtl8188eu/hal/usb_ops_linux.c | 246 +
.../staging/rtl8188eu/hal/version_rtl8188e.h | 10 +
118 files changed, 92598 insertions(+)
create mode 100644 drivers/staging/rtl8188eu/hal/Hal8188EPwrSeq.c
create mode 100644 drivers/staging/rtl8188eu/hal/HalEfuseMask8188E_USB.c
create mode 100644 drivers/staging/rtl8188eu/hal/HalEfuseMask8188E_USB.h
create mode 100644 drivers/staging/rtl8188eu/hal/HalPwrSeqCmd.c
create mode 100644 drivers/staging/rtl8188eu/hal/btc/halbtcoutsrc.h
create mode 100644 drivers/staging/rtl8188eu/hal/btc/mp_precomp.h
create mode 100644 drivers/staging/rtl8188eu/hal/efuse_mask.h
create mode 100644 drivers/staging/rtl8188eu/hal/hal8188e_s_fw.c
create mode 100644 drivers/staging/rtl8188eu/hal/hal8188e_s_fw.h
create mode 100644 drivers/staging/rtl8188eu/hal/hal8188e_t_fw.c
create mode 100644 drivers/staging/rtl8188eu/hal/hal8188e_t_fw.h
create mode 100644 drivers/staging/rtl8188eu/hal/hal8188erateadaptive.c
create mode 100644 drivers/staging/rtl8188eu/hal/hal8188erateadaptive.h
create mode 100644 drivers/staging/rtl8188eu/hal/hal8188ereg.h
create mode 100644 drivers/staging/rtl8188eu/hal/hal_btcoex.c
create mode 100644 drivers/staging/rtl8188eu/hal/hal_btcoex_wifionly.c
create mode 100644 drivers/staging/rtl8188eu/hal/hal_com.c
create mode 100644 drivers/staging/rtl8188eu/hal/hal_com_c2h.h
create mode 100644 drivers/staging/rtl8188eu/hal/hal_com_phycfg.c
create mode 100644 drivers/staging/rtl8188eu/hal/hal_dm.c
create mode 100644 drivers/staging/rtl8188eu/hal/hal_dm.h
create mode 100644 drivers/staging/rtl8188eu/hal/hal_intf.c
create mode 100644 drivers/staging/rtl8188eu/hal/hal_mcc.c
create mode 100644 drivers/staging/rtl8188eu/hal/hal_mp.c
create mode 100644 drivers/staging/rtl8188eu/hal/hal_phy.c
create mode 100644 drivers/staging/rtl8188eu/hal/hal_usb.c
create mode 100644 drivers/staging/rtl8188eu/hal/hal_usb_led.c
create mode 100644 drivers/staging/rtl8188eu/hal/halcomtxbf.h
create mode 100644 drivers/staging/rtl8188eu/hal/halhwimg.h
create mode 100644 drivers/staging/rtl8188eu/hal/halhwimg8188e_bb.c
create mode 100644 drivers/staging/rtl8188eu/hal/halhwimg8188e_bb.h
create mode 100644 drivers/staging/rtl8188eu/hal/halhwimg8188e_mac.c
create mode 100644 drivers/staging/rtl8188eu/hal/halhwimg8188e_mac.h
create mode 100644 drivers/staging/rtl8188eu/hal/halhwimg8188e_rf.c
create mode 100644 drivers/staging/rtl8188eu/hal/halhwimg8188e_rf.h
create mode 100644 drivers/staging/rtl8188eu/hal/halphyrf_8188e_ce.c
create mode 100644 drivers/staging/rtl8188eu/hal/halphyrf_8188e_ce.h
create mode 100644 drivers/staging/rtl8188eu/hal/halphyrf_ap.h
create mode 100644 drivers/staging/rtl8188eu/hal/halphyrf_ce.c
create mode 100644 drivers/staging/rtl8188eu/hal/halphyrf_ce.h
create mode 100644 drivers/staging/rtl8188eu/hal/haltxbfinterface.h
create mode 100644 drivers/staging/rtl8188eu/hal/haltxbfjaguar.h
create mode 100644 drivers/staging/rtl8188eu/hal/mp_precomp.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_acs.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_acs.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_adaptivity.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_adaptivity.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_adc_sampling.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_adc_sampling.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_antdect.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_antdect.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_antdiv.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_antdiv.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_beamforming.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_ccx.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_ccx.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_cfotracking.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_cfotracking.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_debug.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_debug.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_dfs.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_dfs.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_dig.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_dig.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_dynamic_rx_path.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_dynamic_rx_path.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_dynamicbbpowersaving.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_dynamicbbpowersaving.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_dynamictxpower.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_dynamictxpower.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_edcaturbocheck.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_edcaturbocheck.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_features.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_hal_txbf_api.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_hal_txbf_api.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_hwconfig.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_hwconfig.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_interface.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_interface.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_iqk.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_kfree.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_kfree.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_noisemonitor.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_noisemonitor.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_pathdiv.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_pathdiv.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_powertracking_ce.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_powertracking_ce.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_pre_define.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_precomp.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_rainfo.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_rainfo.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_reg.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_regconfig8188e.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_regconfig8188e.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_regdefine11ac.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_regdefine11n.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_rtl8188e.c
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_rtl8188e.h
create mode 100644 drivers/staging/rtl8188eu/hal/phydm_types.h
create mode 100644 drivers/staging/rtl8188eu/hal/rtchnlplan.c
create mode 100644 drivers/staging/rtl8188eu/hal/rtchnlplan.h
create mode 100644 drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
create mode 100644 drivers/staging/rtl8188eu/hal/rtl8188e_dm.c
create mode 100644 drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
create mode 100644 drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c
create mode 100644 drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c
create mode 100644 drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c
create mode 100644 drivers/staging/rtl8188eu/hal/rtl8188e_sreset.c
create mode 100644 drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c
create mode 100644 drivers/staging/rtl8188eu/hal/rtl8188eu_led.c
create mode 100644 drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c
create mode 100644 drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
create mode 100644 drivers/staging/rtl8188eu/hal/usb_halinit.c
create mode 100644 drivers/staging/rtl8188eu/hal/usb_ops_linux.c
create mode 100644 drivers/staging/rtl8188eu/hal/version_rtl8188e.h

diff --git a/drivers/staging/rtl8188eu/hal/Hal8188EPwrSeq.c b/drivers/staging/rtl8188eu/hal/Hal8188EPwrSeq.c
new file mode 100644
index 000000000000..38ca0bc5458b
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/Hal8188EPwrSeq.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#include "Hal8188EPwrSeq.h"
+#include <rtl8188e_hal.h>
+
+/*
+ drivers should parse below arrays and do the corresponding actions
+*/
+/* 3 Power on Array */
+WLAN_PWR_CFG rtl8188E_power_on_flow[RTL8188E_TRANS_CARDEMU_TO_ACT_STEPS + RTL8188E_TRANS_END_STEPS] = {
+ RTL8188E_TRANS_CARDEMU_TO_ACT
+ RTL8188E_TRANS_END
+};
+
+/* 3Radio off Array */
+WLAN_PWR_CFG rtl8188E_radio_off_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_END_STEPS] = {
+ RTL8188E_TRANS_ACT_TO_CARDEMU
+ RTL8188E_TRANS_END
+};
+
+/* 3Card Disable Array */
+WLAN_PWR_CFG rtl8188E_card_disable_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS + RTL8188E_TRANS_END_STEPS] = {
+ RTL8188E_TRANS_ACT_TO_CARDEMU
+ RTL8188E_TRANS_CARDEMU_TO_CARDDIS
+ RTL8188E_TRANS_END
+};
+
+/* 3 Card Enable Array */
+WLAN_PWR_CFG rtl8188E_card_enable_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS + RTL8188E_TRANS_END_STEPS] = {
+ RTL8188E_TRANS_CARDDIS_TO_CARDEMU
+ RTL8188E_TRANS_CARDEMU_TO_ACT
+ RTL8188E_TRANS_END
+};
+
+/* 3Suspend Array */
+WLAN_PWR_CFG rtl8188E_suspend_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS + RTL8188E_TRANS_END_STEPS] = {
+ RTL8188E_TRANS_ACT_TO_CARDEMU
+ RTL8188E_TRANS_CARDEMU_TO_SUS
+ RTL8188E_TRANS_END
+};
+
+/* 3 Resume Array */
+WLAN_PWR_CFG rtl8188E_resume_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS + RTL8188E_TRANS_END_STEPS] = {
+ RTL8188E_TRANS_SUS_TO_CARDEMU
+ RTL8188E_TRANS_CARDEMU_TO_ACT
+ RTL8188E_TRANS_END
+};
+
+
+/* 3HWPDN Array */
+WLAN_PWR_CFG rtl8188E_hwpdn_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS + RTL8188E_TRANS_END_STEPS] = {
+ RTL8188E_TRANS_ACT_TO_CARDEMU
+ RTL8188E_TRANS_CARDEMU_TO_PDN
+ RTL8188E_TRANS_END
+};
+
+/* 3 Enter LPS */
+WLAN_PWR_CFG rtl8188E_enter_lps_flow[RTL8188E_TRANS_ACT_TO_LPS_STEPS + RTL8188E_TRANS_END_STEPS] = {
+ /* FW behavior */
+ RTL8188E_TRANS_ACT_TO_LPS
+ RTL8188E_TRANS_END
+};
+
+/* 3 Leave LPS */
+WLAN_PWR_CFG rtl8188E_leave_lps_flow[RTL8188E_TRANS_LPS_TO_ACT_STEPS + RTL8188E_TRANS_END_STEPS] = {
+ /* FW behavior */
+ RTL8188E_TRANS_LPS_TO_ACT
+ RTL8188E_TRANS_END
+};
diff --git a/drivers/staging/rtl8188eu/hal/HalEfuseMask8188E_USB.c b/drivers/staging/rtl8188eu/hal/HalEfuseMask8188E_USB.c
new file mode 100644
index 000000000000..a86c83a656a7
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/HalEfuseMask8188E_USB.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* #include "Mp_Precomp.h" */
+/* #include "../odm_precomp.h" */
+
+#include <drv_types.h>
+
+#include "HalEfuseMask8188E_USB.h"
+
+
+/******************************************************************************
+* MUSB.TXT
+******************************************************************************/
+
+static u8 Array_MP_8188E_MUSB[] = {
+ 0xFF,
+ 0xF3,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x0F,
+ 0xF1,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xF7,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+
+};
+
+u16
+EFUSE_GetArrayLen_MP_8188E_MUSB(void)
+{
+ return sizeof(Array_MP_8188E_MUSB) / sizeof(u8);
+}
+
+void
+EFUSE_GetMaskArray_MP_8188E_MUSB(
+ u8 * Array
+)
+{
+ u16 len = EFUSE_GetArrayLen_MP_8188E_MUSB(), i = 0;
+
+ for (i = 0; i < len; ++i)
+ Array[i] = Array_MP_8188E_MUSB[i];
+}
+bool
+EFUSE_IsAddressMasked_MP_8188E_MUSB(
+ u16 Offset
+)
+{
+ int r = Offset / 16;
+ int c = (Offset % 16) / 2;
+ int result = 0;
+
+ if (c < 4) /* Upper double word */
+ result = (Array_MP_8188E_MUSB[r] & (0x10 << c));
+ else
+ result = (Array_MP_8188E_MUSB[r] & (0x01 << (c - 4)));
+
+ return (result > 0) ? 0 : 1;
+}
diff --git a/drivers/staging/rtl8188eu/hal/HalEfuseMask8188E_USB.h b/drivers/staging/rtl8188eu/hal/HalEfuseMask8188E_USB.h
new file mode 100644
index 000000000000..700d5d88107b
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/HalEfuseMask8188E_USB.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+
+
+/******************************************************************************
+* MUSB.TXT
+******************************************************************************/
+
+
+u16
+EFUSE_GetArrayLen_MP_8188E_MUSB(void);
+
+void
+EFUSE_GetMaskArray_MP_8188E_MUSB(
+ u8 * Array
+);
+
+bool
+EFUSE_IsAddressMasked_MP_8188E_MUSB(/* TC: Test Chip, MP: MP Chip */
+ u16 Offset
+);
diff --git a/drivers/staging/rtl8188eu/hal/HalPwrSeqCmd.c b/drivers/staging/rtl8188eu/hal/HalPwrSeqCmd.c
new file mode 100644
index 000000000000..c42e44e79ef2
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/HalPwrSeqCmd.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+/*++
+Copyright (c) Realtek Semiconductor Corp. All rights reserved.
+
+Module Name:
+ HalPwrSeqCmd.c
+
+Abstract:
+ Implement HW Power sequence configuration CMD handling routine for Realtek devices.
+
+Major Change History:
+ When Who What
+ ---------- --------------- -------------------------------
+ 2011-10-26 Lucas Modify to be compatible with SD4-CE driver.
+ 2011-07-07 Roger Create.
+
+--*/
+#include <HalPwrSeqCmd.h>
+
+
+/*
+ * Description:
+ * This routine deal with the Power Configuration CMDs parsing for RTL8723/RTL8188E Series IC.
+ *
+ * Assumption:
+ * We should follow specific format which was released from HW SD.
+ *
+ * 2011.07.07, added by Roger.
+ * */
+u8 HalPwrSeqCmdParsing(
+ PADAPTER padapter,
+ u8 CutVersion,
+ u8 FabVersion,
+ u8 InterfaceType,
+ WLAN_PWR_CFG PwrSeqCmd[])
+{
+ WLAN_PWR_CFG PwrCfgCmd = {0};
+ u8 bPollingBit = false;
+ u32 AryIdx = 0;
+ u8 value = 0;
+ u32 offset = 0;
+ u32 pollingCount = 0; /* polling autoload done. */
+ u32 maxPollingCnt = 5000;
+
+ do {
+ PwrCfgCmd = PwrSeqCmd[AryIdx];
+
+
+ /* 2 Only Handle the command whose FAB, CUT, and Interface are matched */
+ if ((GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) &&
+ (GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) &&
+ (GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType)) {
+ switch (GET_PWR_CFG_CMD(PwrCfgCmd)) {
+ case PWR_CMD_READ:
+ break;
+
+ case PWR_CMD_WRITE:
+ offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
+
+#ifdef CONFIG_SDIO_HCI
+ /* */
+ /* <Roger_Notes> We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface */
+ /* 2011.07.07. */
+ /* */
+ if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) {
+ /* Read Back SDIO Local value */
+ value = SdioLocalCmd52Read1Byte(padapter, offset);
+
+ value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd));
+ value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd));
+
+ /* Write Back SDIO Local value */
+ SdioLocalCmd52Write1Byte(padapter, offset, value);
+ } else
+#endif
+ {
+#ifdef CONFIG_GSPI_HCI
+ if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
+ offset = SPI_LOCAL_OFFSET | offset;
+#endif
+ /* Read the value from system register */
+ value = rtw_read8(padapter, offset);
+
+ value = value & (~(GET_PWR_CFG_MASK(PwrCfgCmd)));
+ value = value | (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd));
+
+ /* Write the value back to sytem register */
+ rtw_write8(padapter, offset, value);
+ }
+ break;
+
+ case PWR_CMD_POLLING:
+
+ bPollingBit = false;
+ offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
+#ifdef CONFIG_GSPI_HCI
+ if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
+ offset = SPI_LOCAL_OFFSET | offset;
+#endif
+ do {
+#ifdef CONFIG_SDIO_HCI
+ if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO)
+ value = SdioLocalCmd52Read1Byte(padapter, offset);
+ else
+#endif
+ value = rtw_read8(padapter, offset);
+
+ value = value & GET_PWR_CFG_MASK(PwrCfgCmd);
+ if (value == (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd)))
+ bPollingBit = true;
+ else
+ rtw_udelay_os(10);
+
+ if (pollingCount++ > maxPollingCnt) {
+ RTW_ERR("HalPwrSeqCmdParsing: Fail to polling Offset[%#x]=%02x\n", offset, value);
+ return false;
+ }
+ } while (!bPollingBit);
+
+ break;
+
+ case PWR_CMD_DELAY:
+ if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US)
+ rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd));
+ else
+ rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd) * 1000);
+ break;
+
+ case PWR_CMD_END:
+ /* When this command is parsed, end the process */
+ return true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ AryIdx++;/* Add Array Index */
+ } while (1);
+
+ return true;
+}
diff --git a/drivers/staging/rtl8188eu/hal/btc/halbtcoutsrc.h b/drivers/staging/rtl8188eu/hal/btc/halbtcoutsrc.h
new file mode 100644
index 000000000000..0f25098cdda4
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/btc/halbtcoutsrc.h
@@ -0,0 +1,997 @@
+#ifndef __HALBTC_OUT_SRC_H__
+#define __HALBTC_OUT_SRC_H__
+
+
+#define BTC_COEX_OFFLOAD 0
+#define BTC_TMP_BUF_SHORT 20
+
+extern u8 gl_btc_trace_buf[];
+#define BTC_SPRINTF rsprintf
+#define BTC_TRACE(_MSG_)\
+do {\
+ if (GLBtcDbgType[COMP_COEX] & BIT(DBG_LOUD)) {\
+ RTW_INFO("%s", _MSG_);\
+ } \
+} while (0)
+#define BT_PrintData(adapter, _MSG_, len, data) RTW_DBG_DUMP((_MSG_), data, len)
+
+
+#define NORMAL_EXEC FALSE
+#define FORCE_EXEC TRUE
+
+#define BTC_RF_OFF 0x0
+#define BTC_RF_ON 0x1
+
+#define BTC_RF_A 0x0
+#define BTC_RF_B 0x1
+#define BTC_RF_C 0x2
+#define BTC_RF_D 0x3
+
+#define BTC_SMSP SINGLEMAC_SINGLEPHY
+#define BTC_DMDP DUALMAC_DUALPHY
+#define BTC_DMSP DUALMAC_SINGLEPHY
+#define BTC_MP_UNKNOWN 0xff
+
+#define BT_COEX_ANT_TYPE_PG 0
+#define BT_COEX_ANT_TYPE_ANTDIV 1
+#define BT_COEX_ANT_TYPE_DETECTED 2
+
+#define BTC_MIMO_PS_STATIC 0 /* 1ss */
+#define BTC_MIMO_PS_DYNAMIC 1 /* 2ss */
+
+#define BTC_RATE_DISABLE 0
+#define BTC_RATE_ENABLE 1
+
+/* single Antenna definition */
+#define BTC_ANT_PATH_WIFI 0
+#define BTC_ANT_PATH_BT 1
+#define BTC_ANT_PATH_PTA 2
+#define BTC_ANT_PATH_WIFI5G 3
+#define BTC_ANT_PATH_AUTO 4
+/* dual Antenna definition */
+#define BTC_ANT_WIFI_AT_MA 0
+#define BTC_ANT_WIFI_AT_AUX 1
+#define BTC_ANT_WIFI_AT_DIVERSITY 2
+/* coupler Antenna definition */
+#define BTC_ANT_WIFI_AT_CPL_MA0
+#define BTC_ANT_WIFI_AT_CPL_AUX 1
+
+typedef enum _BTC_POWERSAVE_TYPE {
+ BTC_PS_WIFI_NATIVE = 0, /* wifi original power save behavior */
+ BTC_PS_LPS_ON = 1,
+ BTC_PS_LPS_OFF = 2,
+ BTC_PS_MAX
+} BTC_POWERSAVE_TYPE, *PBTC_POWERSAVE_TYPE;
+
+typedef enum _BTC_BT_REG_TYPE {
+ BTC_BT_REG_RF = 0,
+ BTC_BT_REG_MODEM = 1,
+ BTC_BT_REG_BLUEWIZE = 2,
+ BTC_BT_REG_VENDOR = 3,
+ BTC_BT_REG_LE = 4,
+ BTC_BT_REG_MAX
+} BTC_BT_REG_TYPE, *PBTC_BT_REG_TYPE;
+
+typedef enum _BTC_CHIP_INTERFACE {
+ BTC_INTF_UNKNOWN = 0,
+ BTC_INTF_PCI = 1,
+ BTC_INTF_USB = 2,
+ BTC_INTF_SDIO = 3,
+ BTC_INTF_MAX
+} BTC_CHIP_INTERFACE, *PBTC_CHIP_INTERFACE;
+
+typedef enum _BTC_CHIP_TYPE {
+ BTC_CHIP_UNDEF = 0,
+ BTC_CHIP_CSR_BC4 = 1,
+ BTC_CHIP_CSR_BC8 = 2,
+ BTC_CHIP_RTL8723A = 3,
+ BTC_CHIP_RTL8821 = 4,
+ BTC_CHIP_RTL8723B = 5,
+ BTC_CHIP_MAX
+} BTC_CHIP_TYPE, *PBTC_CHIP_TYPE;
+
+/* following is for wifi link status */
+#define WIFI_STA_CONNECTED BIT0
+#define WIFI_AP_CONNECTED BIT1
+#define WIFI_HS_CONNECTED BIT2
+#define WIFI_P2P_GO_CONNECTED BIT3
+#define WIFI_P2P_GC_CONNECTED BIT4
+
+/* following is for command line utility */
+#define CL_SPRINTF rsprintf
+#define CL_PRINTF DCMD_Printf
+
+struct btc_board_info {
+ /* The following is some board information */
+ u8 bt_chip_type;
+ u8 pg_ant_num; /* pg ant number */
+ u8 btdm_ant_num; /* ant number for btdm */
+ u8 btdm_ant_num_by_ant_det; /* ant number for btdm after antenna detection */
+ u8 btdm_ant_pos; /* Bryant Add to indicate Antenna Position for (pg_ant_num = 2) && (btdm_ant_num =1) (DPDT+1Ant case) */
+ u8 single_ant_path; /* current used for 8723b only, 1=>s0, 0=>s1 */
+ bool tfbga_package; /* for Antenna detect threshold */
+ bool btdm_ant_det_finish;
+ bool btdm_ant_det_already_init_phydm;
+ u8 ant_type;
+ u8 rfe_type;
+ u8 ant_div_cfg;
+ bool btdm_ant_det_complete_fail;
+ u8 ant_det_result;
+ bool ant_det_result_five_complete;
+ u32 antdetval;
+};
+
+typedef enum _BTC_DBG_OPCODE {
+ BTC_DBG_SET_COEX_NORMAL = 0x0,
+ BTC_DBG_SET_COEX_WIFI_ONLY = 0x1,
+ BTC_DBG_SET_COEX_BT_ONLY = 0x2,
+ BTC_DBG_SET_COEX_DEC_BT_PWR = 0x3,
+ BTC_DBG_SET_COEX_BT_AFH_MAP = 0x4,
+ BTC_DBG_SET_COEX_BT_IGNORE_WLAN_ACT = 0x5,
+ BTC_DBG_SET_COEX_MANUAL_CTRL = 0x6,
+ BTC_DBG_MAX
+} BTC_DBG_OPCODE, *PBTC_DBG_OPCODE;
+
+typedef enum _BTC_RSSI_STATE {
+ BTC_RSSI_STATE_HIGH = 0x0,
+ BTC_RSSI_STATE_MEDIUM = 0x1,
+ BTC_RSSI_STATE_LOW = 0x2,
+ BTC_RSSI_STATE_STAY_HIGH = 0x3,
+ BTC_RSSI_STATE_STAY_MEDIUM = 0x4,
+ BTC_RSSI_STATE_STAY_LOW = 0x5,
+ BTC_RSSI_MAX
+} BTC_RSSI_STATE, *PBTC_RSSI_STATE;
+#define BTC_RSSI_HIGH(_rssi_) ((_rssi_ == BTC_RSSI_STATE_HIGH || _rssi_ == BTC_RSSI_STATE_STAY_HIGH) ? TRUE:FALSE)
+#define BTC_RSSI_MEDIUM(_rssi_) ((_rssi_ == BTC_RSSI_STATE_MEDIUM || _rssi_ == BTC_RSSI_STATE_STAY_MEDIUM) ? TRUE:FALSE)
+#define BTC_RSSI_LOW(_rssi_) ((_rssi_ == BTC_RSSI_STATE_LOW || _rssi_ == BTC_RSSI_STATE_STAY_LOW) ? TRUE:FALSE)
+
+typedef enum _BTC_WIFI_ROLE {
+ BTC_ROLE_STATION = 0x0,
+ BTC_ROLE_AP = 0x1,
+ BTC_ROLE_IBSS = 0x2,
+ BTC_ROLE_HS_MODE = 0x3,
+ BTC_ROLE_MAX
+} BTC_WIFI_ROLE, *PBTC_WIFI_ROLE;
+
+typedef enum _BTC_WIRELESS_FREQ {
+ BTC_FREQ_2_4G = 0x0,
+ BTC_FREQ_5G = 0x1,
+ BTC_FREQ_MAX
+} BTC_WIRELESS_FREQ, *PBTC_WIRELESS_FREQ;
+
+typedef enum _BTC_WIFI_BW_MODE {
+ BTC_WIFI_BW_LEGACY = 0x0,
+ BTC_WIFI_BW_HT20 = 0x1,
+ BTC_WIFI_BW_HT40 = 0x2,
+ BTC_WIFI_BW_HT80 = 0x3,
+ BTC_WIFI_BW_HT160 = 0x4,
+ BTC_WIFI_BW_MAX
+} BTC_WIFI_BW_MODE, *PBTC_WIFI_BW_MODE;
+
+typedef enum _BTC_WIFI_TRAFFIC_DIR {
+ BTC_WIFI_TRAFFIC_TX = 0x0,
+ BTC_WIFI_TRAFFIC_RX = 0x1,
+ BTC_WIFI_TRAFFIC_MAX
+} BTC_WIFI_TRAFFIC_DIR, *PBTC_WIFI_TRAFFIC_DIR;
+
+typedef enum _BTC_WIFI_PNP {
+ BTC_WIFI_PNP_WAKE_UP = 0x0,
+ BTC_WIFI_PNP_SLEEP = 0x1,
+ BTC_WIFI_PNP_SLEEP_KEEP_ANT = 0x2,
+ BTC_WIFI_PNP_MAX
+} BTC_WIFI_PNP, *PBTC_WIFI_PNP;
+
+typedef enum _BTC_IOT_PEER {
+ BTC_IOT_PEER_UNKNOWN = 0,
+ BTC_IOT_PEER_REALTEK = 1,
+ BTC_IOT_PEER_REALTEK_92SE = 2,
+ BTC_IOT_PEER_BROADCOM = 3,
+ BTC_IOT_PEER_RALINK = 4,
+ BTC_IOT_PEER_ATHEROS = 5,
+ BTC_IOT_PEER_CISCO = 6,
+ BTC_IOT_PEER_MERU = 7,
+ BTC_IOT_PEER_MARVELL = 8,
+ BTC_IOT_PEER_REALTEK_SOFTAP = 9, /* peer is RealTek SOFT_AP, by Bohn, 2009.12.17 */
+ BTC_IOT_PEER_SELF_SOFTAP = 10, /* Self is SoftAP */
+ BTC_IOT_PEER_AIRGO = 11,
+ BTC_IOT_PEER_INTEL = 12,
+ BTC_IOT_PEER_RTK_APCLIENT = 13,
+ BTC_IOT_PEER_REALTEK_81XX = 14,
+ BTC_IOT_PEER_REALTEK_WOW = 15,
+ BTC_IOT_PEER_REALTEK_JAGUAR_BCUTAP = 16,
+ BTC_IOT_PEER_REALTEK_JAGUAR_CCUTAP = 17,
+ BTC_IOT_PEER_MAX,
+} BTC_IOT_PEER, *PBTC_IOT_PEER;
+
+/* for 8723b-d cut large current issue */
+typedef enum _BTC_WIFI_COEX_STATE {
+ BTC_WIFI_STAT_INIT,
+ BTC_WIFI_STAT_IQK,
+ BTC_WIFI_STAT_NORMAL_OFF,
+ BTC_WIFI_STAT_MP_OFF,
+ BTC_WIFI_STAT_NORMAL,
+ BTC_WIFI_STAT_ANT_DIV,
+ BTC_WIFI_STAT_MAX
+} BTC_WIFI_COEX_STATE, *PBTC_WIFI_COEX_STATE;
+
+typedef enum _BTC_ANT_TYPE {
+ BTC_ANT_TYPE_0,
+ BTC_ANT_TYPE_1,
+ BTC_ANT_TYPE_2,
+ BTC_ANT_TYPE_3,
+ BTC_ANT_TYPE_4,
+ BTC_ANT_TYPE_MAX
+} BTC_ANT_TYPE, *PBTC_ANT_TYPE;
+
+typedef enum _BTC_VENDOR {
+ BTC_VENDOR_LENOVO,
+ BTC_VENDOR_ASUS,
+ BTC_VENDOR_OTHER
+} BTC_VENDOR, *PBTC_VENDOR;
+
+
+/* defined for BFP_BTC_GET */
+typedef enum _BTC_GET_TYPE {
+ /* type bool */
+ BTC_GET_BL_HS_OPERATION,
+ BTC_GET_BL_HS_CONNECTING,
+ BTC_GET_BL_WIFI_FW_READY,
+ BTC_GET_BL_WIFI_CONNECTED,
+ BTC_GET_BL_WIFI_BUSY,
+ BTC_GET_BL_WIFI_SCAN,
+ BTC_GET_BL_WIFI_LINK,
+ BTC_GET_BL_WIFI_ROAM,
+ BTC_GET_BL_WIFI_4_WAY_PROGRESS,
+ BTC_GET_BL_WIFI_UNDER_5G,
+ BTC_GET_BL_WIFI_AP_MODE_ENABLE,
+ BTC_GET_BL_WIFI_ENABLE_ENCRYPTION,
+ BTC_GET_BL_WIFI_UNDER_B_MODE,
+ BTC_GET_BL_EXT_SWITCH,
+ BTC_GET_BL_WIFI_IS_IN_MP_MODE,
+ BTC_GET_BL_IS_ASUS_8723B,
+
+ /* type s4Byte */
+ BTC_GET_S4_WIFI_RSSI,
+ BTC_GET_S4_HS_RSSI,
+
+ /* type u32 */
+ BTC_GET_U4_WIFI_BW,
+ BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
+ BTC_GET_U4_WIFI_FW_VER,
+ BTC_GET_U4_WIFI_LINK_STATUS,
+ BTC_GET_U4_BT_PATCH_VER,
+ BTC_GET_U4_VENDOR,
+ BTC_GET_U4_SUPPORTED_VERSION,
+ BTC_GET_U4_SUPPORTED_FEATURE,
+ BTC_GET_U4_WIFI_IQK_TOTAL,
+ BTC_GET_U4_WIFI_IQK_OK,
+ BTC_GET_U4_WIFI_IQK_FAIL,
+
+ /* type u8 */
+ BTC_GET_U1_WIFI_DOT11_CHNL,
+ BTC_GET_U1_WIFI_CENTRAL_CHNL,
+ BTC_GET_U1_WIFI_HS_CHNL,
+ BTC_GET_U1_WIFI_P2P_CHNL,
+ BTC_GET_U1_MAC_PHY_MODE,
+ BTC_GET_U1_AP_NUM,
+ BTC_GET_U1_ANT_TYPE,
+ BTC_GET_U1_IOT_PEER,
+
+ /*===== for 1Ant ======*/
+ BTC_GET_U1_LPS_MODE,
+
+ BTC_GET_MAX
+} BTC_GET_TYPE, *PBTC_GET_TYPE;
+
+/* defined for BFP_BTC_SET */
+typedef enum _BTC_SET_TYPE {
+ /* type bool */
+ BTC_SET_BL_BT_DISABLE,
+ BTC_SET_BL_BT_ENABLE_DISABLE_CHANGE,
+ BTC_SET_BL_BT_TRAFFIC_BUSY,
+ BTC_SET_BL_BT_LIMITED_DIG,
+ BTC_SET_BL_FORCE_TO_ROAM,
+ BTC_SET_BL_TO_REJ_AP_AGG_PKT,
+ BTC_SET_BL_BT_CTRL_AGG_SIZE,
+ BTC_SET_BL_INC_SCAN_DEV_NUM,
+ BTC_SET_BL_BT_TX_RX_MASK,
+ BTC_SET_BL_MIRACAST_PLUS_BT,
+
+ /* type u8 */
+ BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON,
+ BTC_SET_U1_AGG_BUF_SIZE,
+
+ /* type trigger some action */
+ BTC_SET_ACT_GET_BT_RSSI,
+ BTC_SET_ACT_AGGREGATE_CTRL,
+ BTC_SET_ACT_ANTPOSREGRISTRY_CTRL,
+ /*===== for 1Ant ======*/
+ /* type bool */
+
+ /* type u8 */
+ BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE,
+ BTC_SET_U1_LPS_VAL,
+ BTC_SET_U1_RPWM_VAL,
+ /* type trigger some action */
+ BTC_SET_ACT_LEAVE_LPS,
+ BTC_SET_ACT_ENTER_LPS,
+ BTC_SET_ACT_NORMAL_LPS,
+ BTC_SET_ACT_DISABLE_LOW_POWER,
+ BTC_SET_ACT_UPDATE_RAMASK,
+ BTC_SET_ACT_SEND_MIMO_PS,
+ /* BT Coex related */
+ BTC_SET_ACT_CTRL_BT_INFO,
+ BTC_SET_ACT_CTRL_BT_COEX,
+ BTC_SET_ACT_CTRL_8723B_ANT,
+ /*=================*/
+ BTC_SET_MAX
+} BTC_SET_TYPE, *PBTC_SET_TYPE;
+
+typedef enum _BTC_DBG_DISP_TYPE {
+ BTC_DBG_DISP_COEX_STATISTICS = 0x0,
+ BTC_DBG_DISP_BT_LINK_INFO = 0x1,
+ BTC_DBG_DISP_WIFI_STATUS = 0x2,
+ BTC_DBG_DISP_MAX
+} BTC_DBG_DISP_TYPE, *PBTC_DBG_DISP_TYPE;
+
+typedef enum _BTC_NOTIFY_TYPE_IPS {
+ BTC_IPS_LEAVE = 0x0,
+ BTC_IPS_ENTER = 0x1,
+ BTC_IPS_MAX
+} BTC_NOTIFY_TYPE_IPS, *PBTC_NOTIFY_TYPE_IPS;
+typedef enum _BTC_NOTIFY_TYPE_LPS {
+ BTC_LPS_DISABLE = 0x0,
+ BTC_LPS_ENABLE = 0x1,
+ BTC_LPS_MAX
+} BTC_NOTIFY_TYPE_LPS, *PBTC_NOTIFY_TYPE_LPS;
+typedef enum _BTC_NOTIFY_TYPE_SCAN {
+ BTC_SCAN_FINISH = 0x0,
+ BTC_SCAN_START = 0x1,
+ BTC_SCAN_START_2G = 0x2,
+ BTC_SCAN_MAX
+} BTC_NOTIFY_TYPE_SCAN, *PBTC_NOTIFY_TYPE_SCAN;
+typedef enum _BTC_NOTIFY_TYPE_SWITCHBAND {
+ BTC_NOT_SWITCH = 0x0,
+ BTC_SWITCH_TO_24G = 0x1,
+ BTC_SWITCH_TO_5G = 0x2,
+ BTC_SWITCH_TO_24G_NOFORSCAN = 0x3,
+ BTC_SWITCH_MAX
+} BTC_NOTIFY_TYPE_SWITCHBAND, *PBTC_NOTIFY_TYPE_SWITCHBAND;
+typedef enum _BTC_NOTIFY_TYPE_ASSOCIATE {
+ BTC_ASSOCIATE_FINISH = 0x0,
+ BTC_ASSOCIATE_START = 0x1,
+ BTC_ASSOCIATE_5G_FINISH = 0x2,
+ BTC_ASSOCIATE_5G_START = 0x3,
+ BTC_ASSOCIATE_MAX
+} BTC_NOTIFY_TYPE_ASSOCIATE, *PBTC_NOTIFY_TYPE_ASSOCIATE;
+typedef enum _BTC_NOTIFY_TYPE_MEDIA_STATUS {
+ BTC_MEDIA_DISCONNECT = 0x0,
+ BTC_MEDIA_CONNECT = 0x1,
+ BTC_MEDIA_MAX
+} BTC_NOTIFY_TYPE_MEDIA_STATUS, *PBTC_NOTIFY_TYPE_MEDIA_STATUS;
+typedef enum _BTC_NOTIFY_TYPE_SPECIFIC_PACKET {
+ BTC_PACKET_UNKNOWN = 0x0,
+ BTC_PACKET_DHCP = 0x1,
+ BTC_PACKET_ARP = 0x2,
+ BTC_PACKET_EAPOL = 0x3,
+ BTC_PACKET_MAX
+} BTC_NOTIFY_TYPE_SPECIFIC_PACKET, *PBTC_NOTIFY_TYPE_SPECIFIC_PACKET;
+typedef enum _BTC_NOTIFY_TYPE_STACK_OPERATION {
+ BTC_STACK_OP_NONE = 0x0,
+ BTC_STACK_OP_INQ_PAGE_PAIR_START = 0x1,
+ BTC_STACK_OP_INQ_PAGE_PAIR_FINISH = 0x2,
+ BTC_STACK_OP_MAX
+} BTC_NOTIFY_TYPE_STACK_OPERATION, *PBTC_NOTIFY_TYPE_STACK_OPERATION;
+
+/* Bryant Add */
+typedef enum _BTC_ANTENNA_POS {
+ BTC_ANTENNA_AT_MAIN_PORT = 0x1,
+ BTC_ANTENNA_AT_AUX_PORT = 0x2,
+} BTC_ANTENNA_POS, *PBTC_ANTENNA_POS;
+
+/* Bryant Add */
+typedef enum _BTC_BT_OFFON {
+ BTC_BT_OFF = 0x0,
+ BTC_BT_ON = 0x1,
+} BTC_BTOFFON, *PBTC_BT_OFFON;
+
+/*==================================================
+For following block is for coex offload
+==================================================*/
+typedef struct _COL_H2C {
+ u8 opcode;
+ u8 opcode_ver:4;
+ u8 req_num:4;
+ u8 buf[1];
+} COL_H2C, *PCOL_H2C;
+
+#define COL_C2H_ACK_HDR_LEN 3
+typedef struct _COL_C2H_ACK {
+ u8 status;
+ u8 opcode_ver:4;
+ u8 req_num:4;
+ u8 ret_len;
+ u8 buf[1];
+} COL_C2H_ACK, *PCOL_C2H_ACK;
+
+#define COL_C2H_IND_HDR_LEN 3
+typedef struct _COL_C2H_IND {
+ u8 type;
+ u8 version;
+ u8 length;
+ u8 data[1];
+} COL_C2H_IND, *PCOL_C2H_IND;
+
+/*============================================
+NOTE: for debug message, the following define should match
+the strings in coexH2cResultString.
+============================================*/
+typedef enum _COL_H2C_STATUS {
+ /* c2h status */
+ COL_STATUS_C2H_OK = 0x00, /* Wifi received H2C request and check content ok. */
+ COL_STATUS_C2H_UNKNOWN = 0x01, /* Not handled routine */
+ COL_STATUS_C2H_UNKNOWN_OPCODE = 0x02, /* Invalid OP code, It means that wifi firmware received an undefiend OP code. */
+ COL_STATUS_C2H_OPCODE_VER_MISMATCH = 0x03, /* Wifi firmware and wifi driver mismatch, need to update wifi driver or wifi or. */
+ COL_STATUS_C2H_PARAMETER_ERROR = 0x04, /* Error paraneter.(ex: parameters = NULL but it should have values) */
+ COL_STATUS_C2H_PARAMETER_OUT_OF_RANGE = 0x05, /* Wifi firmware needs to check the parameters from H2C request and return the status.(ex: ch = 500, it's wrong) */
+ /* other COL status start from here */
+ COL_STATUS_C2H_REQ_NUM_MISMATCH , /* c2h req_num mismatch, means this c2h is not we expected. */
+ COL_STATUS_H2C_HALMAC_FAIL , /* HALMAC return fail. */
+ COL_STATUS_H2C_TIMT , /* not received the c2h response from fw */
+ COL_STATUS_INVALID_C2H_LEN , /* invalid coex offload c2h ack length, must >= 3 */
+ COL_STATUS_COEX_DATA_OVERFLOW , /* coex returned length over the c2h ack length. */
+ COL_STATUS_MAX
+} COL_H2C_STATUS, *PCOL_H2C_STATUS;
+
+#define COL_MAX_H2C_REQ_NUM 16
+
+#define COL_H2C_BUF_LEN 20
+typedef enum _COL_OPCODE {
+ COL_OP_WIFI_STATUS_NOTIFY = 0x0,
+ COL_OP_WIFI_PROGRESS_NOTIFY = 0x1,
+ COL_OP_WIFI_INFO_NOTIFY = 0x2,
+ COL_OP_WIFI_POWER_STATE_NOTIFY = 0x3,
+ COL_OP_SET_CONTROL = 0x4,
+ COL_OP_GET_CONTROL = 0x5,
+ COL_OP_WIFI_OPCODE_MAX
+} COL_OPCODE, *PCOL_OPCODE;
+
+typedef enum _COL_IND_TYPE {
+ COL_IND_BT_INFO = 0x0,
+ COL_IND_PSTDMA = 0x1,
+ COL_IND_LIMITED_TX_RX = 0x2,
+ COL_IND_COEX_TABLE = 0x3,
+ COL_IND_REQ = 0x4,
+ COL_IND_MAX
+} COL_IND_TYPE, *PCOL_IND_TYPE;
+
+typedef struct _COL_SINGLE_H2C_RECORD {
+ u8 h2c_buf[COL_H2C_BUF_LEN]; /* the latest sent h2c buffer */
+ u32 h2c_len;
+ u8 c2h_ack_buf[COL_H2C_BUF_LEN]; /* the latest received c2h buffer */
+ u32 c2h_ack_len;
+ u32 count; /* the total number of the sent h2c command */
+ u32 status[COL_STATUS_MAX]; /* the c2h status for the sent h2c command */
+} COL_SINGLE_H2C_RECORD, *PCOL_SINGLE_H2C_RECORD;
+
+typedef struct _COL_SINGLE_C2H_IND_RECORD {
+ u8 ind_buf[COL_H2C_BUF_LEN]; /* the latest received c2h indication buffer */
+ u32 ind_len;
+ u32 count; /* the total number of the rcvd c2h indication */
+ u32 status[COL_STATUS_MAX]; /* the c2h indication verified status */
+} COL_SINGLE_C2H_IND_RECORD, *PCOL_SINGLE_C2H_IND_RECORD;
+
+typedef struct _BTC_OFFLOAD {
+ /* H2C command related */
+ u8 h2c_req_num;
+ u32 cnt_h2c_sent;
+ COL_SINGLE_H2C_RECORD h2c_record[COL_OP_WIFI_OPCODE_MAX];
+
+ /* C2H Ack related */
+ u32 cnt_c2h_ack;
+ u32 status[COL_STATUS_MAX];
+ struct completion c2h_event[COL_MAX_H2C_REQ_NUM]; /* for req_num = 1~COL_MAX_H2C_REQ_NUM */
+ u8 c2h_ack_buf[COL_MAX_H2C_REQ_NUM][COL_H2C_BUF_LEN];
+ u8 c2h_ack_len[COL_MAX_H2C_REQ_NUM];
+
+ /* C2H Indication related */
+ u32 cnt_c2h_ind;
+ COL_SINGLE_C2H_IND_RECORD c2h_ind_record[COL_IND_MAX];
+ u32 c2h_ind_status[COL_STATUS_MAX];
+ u8 c2h_ind_buf[COL_H2C_BUF_LEN];
+ u8 c2h_ind_len;
+} BTC_OFFLOAD, *PBTC_OFFLOAD;
+extern BTC_OFFLOAD gl_coex_offload;
+/*==================================================*/
+
+typedef u8
+(*BFP_BTC_R1)(
+ void * pBtcContext,
+ u32 RegAddr
+ );
+typedef u16
+(*BFP_BTC_R2)(
+ void * pBtcContext,
+ u32 RegAddr
+ );
+typedef u32
+(*BFP_BTC_R4)(
+ void * pBtcContext,
+ u32 RegAddr
+ );
+typedef void
+(*BFP_BTC_W1)(
+ void * pBtcContext,
+ u32 RegAddr,
+ u8 Data
+ );
+typedef void
+(*BFP_BTC_W1_BIT_MASK)(
+ void * pBtcContext,
+ u32 regAddr,
+ u8 bitMask,
+ u8 data1b
+ );
+typedef void
+(*BFP_BTC_W2)(
+ void * pBtcContext,
+ u32 RegAddr,
+ u16 Data
+ );
+typedef void
+(*BFP_BTC_W4)(
+ void * pBtcContext,
+ u32 RegAddr,
+ u32 Data
+ );
+typedef void
+(*BFP_BTC_LOCAL_REG_W1)(
+ void * pBtcContext,
+ u32 RegAddr,
+ u8 Data
+ );
+typedef void
+(*BFP_BTC_SET_BB_REG)(
+ void * pBtcContext,
+ u32 RegAddr,
+ u32 BitMask,
+ u32 Data
+ );
+typedef u32
+(*BFP_BTC_GET_BB_REG)(
+ void * pBtcContext,
+ u32 RegAddr,
+ u32 BitMask
+ );
+typedef void
+(*BFP_BTC_SET_RF_REG)(
+ void * pBtcContext,
+ u8 eRFPath,
+ u32 RegAddr,
+ u32 BitMask,
+ u32 Data
+ );
+typedef u32
+(*BFP_BTC_GET_RF_REG)(
+ void * pBtcContext,
+ u8 eRFPath,
+ u32 RegAddr,
+ u32 BitMask
+ );
+typedef void
+(*BFP_BTC_FILL_H2C)(
+ void * pBtcContext,
+ u8 elementId,
+ u32 cmdLen,
+ u8 * pCmdBuffer
+ );
+
+typedef bool
+(*BFP_BTC_GET)(
+ void * pBtCoexist,
+ u8 getType,
+ void * pOutBuf
+ );
+
+typedef bool
+(*BFP_BTC_SET)(
+ void * pBtCoexist,
+ u8 setType,
+ void * pInBuf
+ );
+typedef u16
+(*BFP_BTC_SET_BT_REG)(
+ void * pBtcContext,
+ u8 regType,
+ u32 offset,
+ u32 value
+ );
+typedef bool
+(*BFP_BTC_SET_BT_ANT_DETECTION)(
+ void * pBtcContext,
+ u8 txTime,
+ u8 btChnl
+ );
+
+typedef bool
+(*BFP_BTC_SET_BT_TRX_MASK)(
+ void * pBtcContext,
+ u8 bt_trx_mask
+ );
+
+typedef u32
+(*BFP_BTC_GET_BT_REG)(
+ void * pBtcContext,
+ u8 regType,
+ u32 offset
+ );
+typedef void
+(*BFP_BTC_DISP_DBG_MSG)(
+ void * pBtCoexist,
+ u8 dispType
+ );
+
+typedef COL_H2C_STATUS
+(*BFP_BTC_COEX_H2C_PROCESS)(
+ void * pBtCoexist,
+ u8 opcode,
+ u8 opcode_ver,
+ u8 * ph2c_par,
+ u8 h2c_par_len
+ );
+
+typedef u32
+(*BFP_BTC_GET_BT_COEX_SUPPORTED_FEATURE)(
+ void * pBtcContext
+ );
+
+typedef u32
+(*BFP_BTC_GET_BT_COEX_SUPPORTED_VERSION)(
+ void * pBtcContext
+ );
+
+typedef u32
+(*BFP_BTC_GET_PHYDM_VERSION)(
+ void * pBtcContext
+ );
+
+typedef void
+(*BTC_PHYDM_MODIFY_RA_PCR_THRESHLOD)(
+ void * pDM_Odm,
+ u8 RA_offset_direction,
+ u8 RA_threshold_offset
+ );
+
+typedef u32
+(*BTC_PHYDM_CMNINFOQUERY)(
+ void * pDM_Odm,
+ u8 info_type
+ );
+
+typedef u8
+(*BFP_BTC_GET_ANT_DET_VAL_FROM_BT)(
+
+ void * pBtcContext
+ );
+
+typedef u8
+(*BFP_BTC_GET_BLE_SCAN_TYPE_FROM_BT)(
+ void * pBtcContext
+ );
+
+typedef u32
+(*BFP_BTC_GET_BLE_SCAN_PARA_FROM_BT)(
+ void * pBtcContext,
+ u8 scanType
+ );
+
+typedef bool
+(*BFP_BTC_GET_BT_AFH_MAP_FROM_BT)(
+ void * pBtcContext,
+ u8 mapType,
+ u8 * afhMap
+ );
+
+struct btc_bt_info {
+ bool bt_disabled;
+ bool bt_enable_disable_change;
+ u8 rssi_adjust_for_agc_table_on;
+ u8 rssi_adjust_for_1ant_coex_type;
+ bool pre_bt_ctrl_agg_buf_size;
+ bool bt_ctrl_agg_buf_size;
+ bool pre_reject_agg_pkt;
+ bool reject_agg_pkt;
+ bool increase_scan_dev_num;
+ bool bt_tx_rx_mask;
+ u8 pre_agg_buf_size;
+ u8 agg_buf_size;
+ bool bt_busy;
+ bool limited_dig;
+ u16 bt_hci_ver;
+ u16 bt_real_fw_ver;
+ u8 bt_fw_ver;
+ u32 get_bt_fw_ver_cnt;
+ u32 bt_get_fw_ver;
+ bool miracast_plus_bt;
+
+ bool bt_disable_low_pwr;
+
+ bool bt_ctrl_lps;
+ bool bt_lps_on;
+ bool force_to_roam; /* for 1Ant solution */
+ u8 lps_val;
+ u8 rpwm_val;
+ u32 ra_mask;
+};
+
+struct btc_stack_info {
+ bool profile_notified;
+ u16 hci_version; /* stack hci version */
+ u8 num_of_link;
+ bool bt_link_exist;
+ bool sco_exist;
+ bool acl_exist;
+ bool a2dp_exist;
+ bool hid_exist;
+ u8 num_of_hid;
+ bool pan_exist;
+ bool unknown_acl_exist;
+ s8 min_bt_rssi;
+};
+
+struct btc_bt_link_info {
+ bool bt_link_exist;
+ bool bt_hi_pri_link_exist;
+ bool sco_exist;
+ bool sco_only;
+ bool a2dp_exist;
+ bool a2dp_only;
+ bool hid_exist;
+ bool hid_only;
+ bool pan_exist;
+ bool pan_only;
+ bool slave_role;
+ bool acl_busy;
+};
+
+struct btc_statistics {
+ u32 cnt_bind;
+ u32 cnt_power_on;
+ u32 cnt_pre_load_firmware;
+ u32 cnt_init_hw_config;
+ u32 cnt_init_coex_dm;
+ u32 cnt_ips_notify;
+ u32 cnt_lps_notify;
+ u32 cnt_scan_notify;
+ u32 cnt_connect_notify;
+ u32 cnt_media_status_notify;
+ u32 cnt_specific_packet_notify;
+ u32 cnt_bt_info_notify;
+ u32 cnt_rf_status_notify;
+ u32 cnt_periodical;
+ u32 cnt_coex_dm_switch;
+ u32 cnt_stack_operation_notify;
+ u32 cnt_dbg_ctrl;
+};
+
+struct btc_coexist {
+ bool bBinded; /*make sure only one adapter can bind the data context*/
+ void * Adapter; /*default adapter*/
+ struct btc_board_info board_info;
+ struct btc_bt_info bt_info; /*some bt info referenced by non-bt module*/
+ struct btc_stack_info stack_info;
+ struct btc_bt_link_info bt_link_info;
+ BTC_CHIP_INTERFACE chip_interface;
+ void * odm_priv;
+
+ bool initilized;
+ bool stop_coex_dm;
+ bool manual_control;
+ bool bdontenterLPS;
+ u8 * cli_buf;
+ struct btc_statistics statistics;
+ u8 pwrModeVal[10];
+
+ /* function pointers */
+ /* io related */
+ BFP_BTC_R1 btc_read_1byte;
+ BFP_BTC_W1 btc_write_1byte;
+ BFP_BTC_W1_BIT_MASK btc_write_1byte_bitmask;
+ BFP_BTC_R2 btc_read_2byte;
+ BFP_BTC_W2 btc_write_2byte;
+ BFP_BTC_R4 btc_read_4byte;
+ BFP_BTC_W4 btc_write_4byte;
+ BFP_BTC_LOCAL_REG_W1 btc_write_local_reg_1byte;
+ /* read/write bb related */
+ BFP_BTC_SET_BB_REG btc_set_bb_reg;
+ BFP_BTC_GET_BB_REG btc_get_bb_reg;
+
+ /* read/write rf related */
+ BFP_BTC_SET_RF_REG btc_set_rf_reg;
+ BFP_BTC_GET_RF_REG btc_get_rf_reg;
+
+ /* fill h2c related */
+ BFP_BTC_FILL_H2C btc_fill_h2c;
+ /* other */
+ BFP_BTC_DISP_DBG_MSG btc_disp_dbg_msg;
+ /* normal get/set related */
+ BFP_BTC_GET btc_get;
+ BFP_BTC_SET btc_set;
+
+ BFP_BTC_GET_BT_REG btc_get_bt_reg;
+ BFP_BTC_SET_BT_REG btc_set_bt_reg;
+
+ BFP_BTC_SET_BT_ANT_DETECTION btc_set_bt_ant_detection;
+
+ BFP_BTC_COEX_H2C_PROCESS btc_coex_h2c_process;
+ BFP_BTC_SET_BT_TRX_MASK btc_set_bt_trx_mask;
+ BFP_BTC_GET_BT_COEX_SUPPORTED_FEATURE btc_get_bt_coex_supported_feature;
+ BFP_BTC_GET_BT_COEX_SUPPORTED_VERSION btc_get_bt_coex_supported_version;
+ BFP_BTC_GET_PHYDM_VERSION btc_get_bt_phydm_version;
+ BTC_PHYDM_MODIFY_RA_PCR_THRESHLOD btc_phydm_modify_RA_PCR_threshold;
+ BTC_PHYDM_CMNINFOQUERY btc_phydm_query_PHY_counter;
+ BFP_BTC_GET_ANT_DET_VAL_FROM_BT btc_get_ant_det_val_from_bt;
+ BFP_BTC_GET_BLE_SCAN_TYPE_FROM_BT btc_get_ble_scan_type_from_bt;
+ BFP_BTC_GET_BLE_SCAN_PARA_FROM_BT btc_get_ble_scan_para_from_bt;
+ BFP_BTC_GET_BT_AFH_MAP_FROM_BT btc_get_bt_afh_map_from_bt;
+};
+typedef struct btc_coexist *PBTC_COEXIST;
+
+extern struct btc_coexist GLBtCoexist;
+
+bool
+EXhalbtcoutsrc_InitlizeVariables(
+ void * Adapter
+ );
+void
+EXhalbtcoutsrc_PowerOnSetting(
+ PBTC_COEXIST pBtCoexist
+ );
+void
+EXhalbtcoutsrc_PreLoadFirmware(
+ PBTC_COEXIST pBtCoexist
+ );
+void
+EXhalbtcoutsrc_InitHwConfig(
+ PBTC_COEXIST pBtCoexist,
+ bool bWifiOnly
+ );
+void
+EXhalbtcoutsrc_InitCoexDm(
+ PBTC_COEXIST pBtCoexist
+ );
+void
+EXhalbtcoutsrc_IpsNotify(
+ PBTC_COEXIST pBtCoexist,
+ u8 type
+ );
+void
+EXhalbtcoutsrc_LpsNotify(
+ PBTC_COEXIST pBtCoexist,
+ u8 type
+ );
+void
+EXhalbtcoutsrc_ScanNotify(
+ PBTC_COEXIST pBtCoexist,
+ u8 type
+ );
+void
+EXhalbtcoutsrc_SetAntennaPathNotify(
+ PBTC_COEXIST pBtCoexist,
+ u8 type
+ );
+void
+EXhalbtcoutsrc_ConnectNotify(
+ PBTC_COEXIST pBtCoexist,
+ u8 action
+ );
+void
+EXhalbtcoutsrc_MediaStatusNotify(
+ PBTC_COEXIST pBtCoexist,
+ RT_MEDIA_STATUS mediaStatus
+ );
+void
+EXhalbtcoutsrc_SpecificPacketNotify(
+ PBTC_COEXIST pBtCoexist,
+ u8 pktType
+ );
+void
+EXhalbtcoutsrc_BtInfoNotify(
+ PBTC_COEXIST pBtCoexist,
+ u8 * tmpBuf,
+ u8 length
+ );
+void
+EXhalbtcoutsrc_RfStatusNotify(
+ PBTC_COEXIST pBtCoexist,
+ u8 type
+ );
+void
+EXhalbtcoutsrc_StackOperationNotify(
+ PBTC_COEXIST pBtCoexist,
+ u8 type
+ );
+void
+EXhalbtcoutsrc_HaltNotify(
+ PBTC_COEXIST pBtCoexist
+ );
+void
+EXhalbtcoutsrc_PnpNotify(
+ PBTC_COEXIST pBtCoexist,
+ u8 pnpState
+ );
+void
+EXhalbtcoutsrc_CoexDmSwitch(
+ PBTC_COEXIST pBtCoexist
+ );
+void
+EXhalbtcoutsrc_Periodical(
+ PBTC_COEXIST pBtCoexist
+ );
+void
+EXhalbtcoutsrc_DbgControl(
+ PBTC_COEXIST pBtCoexist,
+ u8 opCode,
+ u8 opLen,
+ u8 * pData
+ );
+void
+EXhalbtcoutsrc_AntennaDetection(
+ PBTC_COEXIST pBtCoexist,
+ u32 centFreq,
+ u32 offset,
+ u32 span,
+ u32 seconds
+ );
+void
+EXhalbtcoutsrc_StackUpdateProfileInfo(
+ void
+ );
+void
+EXhalbtcoutsrc_SetHciVersion(
+ u16 hciVersion
+ );
+void
+EXhalbtcoutsrc_SetBtPatchVersion(
+ u16 btHciVersion,
+ u16 btPatchVersion
+ );
+void
+EXhalbtcoutsrc_UpdateMinBtRssi(
+ s8 btRssi
+ );
+void
+EXhalbtcoutsrc_SetChipType(
+ u8 chipType
+ );
+void
+EXhalbtcoutsrc_SetAntNum(
+ u8 type,
+ u8 antNum
+ );
+void
+EXhalbtcoutsrc_SetSingleAntPath(
+ u8 singleAntPath
+ );
+void
+EXhalbtcoutsrc_DisplayBtCoexInfo(
+ PBTC_COEXIST pBtCoexist
+ );
+void
+EXhalbtcoutsrc_DisplayAntDetection(
+ PBTC_COEXIST pBtCoexist
+ );
+
+#define MASKBYTE0 0xff
+#define MASKBYTE1 0xff00
+#define MASKBYTE2 0xff0000
+#define MASKBYTE3 0xff000000
+#define MASKHWORD 0xffff0000
+#define MASKLWORD 0x0000ffff
+#define MASKDWORD 0xffffffff
+#define MASK12BITS 0xfff
+#define MASKH4BITS 0xf0000000
+#define MASKOFDM_D 0xffc00000
+#define MASKCCK 0x3f3f3f3f
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/btc/mp_precomp.h b/drivers/staging/rtl8188eu/hal/btc/mp_precomp.h
new file mode 100644
index 000000000000..17412fd54810
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/btc/mp_precomp.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#ifndef __MP_PRECOMP_H__
+#define __MP_PRECOMP_H__
+
+#include <drv_types.h>
+#include <hal_data.h>
+
+#define BT_TMP_BUF_SIZE 100
+
+#define rsprintf snprintf
+
+#define DCMD_Printf DBG_BT_INFO
+
+#define delay_ms(ms) rtw_mdelay_os(ms)
+
+#ifdef bEnable
+#undef bEnable
+#endif
+
+#define WPP_SOFTWARE_TRACE 0
+
+typedef enum _BTC_MSG_COMP_TYPE {
+ COMP_COEX = 0,
+ COMP_MAX
+} BTC_MSG_COMP_TYPE;
+extern u32 GLBtcDbgType[];
+
+#define DBG_OFF 0
+#define DBG_SEC 1
+#define DBG_SERIOUS 2
+#define DBG_WARNING 3
+#define DBG_LOUD 4
+#define DBG_TRACE 5
+
+#ifdef CONFIG_BT_COEXIST
+#define BT_SUPPORT 1
+#define COEX_SUPPORT 1
+#define HS_SUPPORT 1
+#else
+#define BT_SUPPORT 0
+#define COEX_SUPPORT 0
+#define HS_SUPPORT 0
+#endif
+
+#include "halbtcoutsrc.h"
+
+#endif /* __MP_PRECOMP_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/efuse_mask.h b/drivers/staging/rtl8188eu/hal/efuse_mask.h
new file mode 100644
index 000000000000..0669c2ef1b64
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/efuse_mask.h
@@ -0,0 +1,2 @@
+
+ #include "HalEfuseMask8188E_USB.h"
diff --git a/drivers/staging/rtl8188eu/hal/hal8188e_s_fw.c b/drivers/staging/rtl8188eu/hal/hal8188e_s_fw.c
new file mode 100644
index 000000000000..23930e112b82
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal8188e_s_fw.c
@@ -0,0 +1,7283 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#include "drv_types.h"
+
+#ifdef CONFIG_SFW_SUPPORTED
+
+#ifdef LOAD_FW_HEADER_FROM_DRIVER
+
+#if (defined(CONFIG_AP_WOWLAN))
+
+u8 array_mp_8188e_s_fw_ap[] = {
+0xE3, 0x88, 0x20, 0x00, 0x1C, 0x00, 0x00, 0x00,
+0x05, 0x04, 0x22, 0x24, 0x96, 0x3E, 0x02, 0x00,
+0xA5, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x47, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x48, 0x84, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x57, 0xFA, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xE1, 0xFB, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x4F, 0xF7, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xC2, 0xAF, 0x80, 0xFE, 0x32, 0x12, 0x43, 0x04,
+0x85, 0xD0, 0x0B, 0x75, 0xD0, 0x08, 0xAA, 0xE0,
+0xC2, 0x8C, 0xE5, 0x8A, 0x24, 0x67, 0xF5, 0x8A,
+0xE5, 0x8C, 0x34, 0x79, 0xF5, 0x8C, 0xD2, 0x8C,
+0xEC, 0x24, 0x87, 0xF8, 0xE6, 0xBC, 0x02, 0x02,
+0x74, 0xFF, 0xC3, 0x95, 0x81, 0xB4, 0x40, 0x00,
+0x40, 0xCE, 0x79, 0x03, 0x78, 0x80, 0x16, 0xE6,
+0x08, 0x70, 0x0B, 0xC2, 0xAF, 0xE6, 0x30, 0xE1,
+0x03, 0x44, 0x18, 0xF6, 0xD2, 0xAF, 0x08, 0xD9,
+0xED, 0xEA, 0x8B, 0xD0, 0x22, 0xE5, 0x0C, 0xFF,
+0x23, 0x24, 0x81, 0xF8, 0x0F, 0x08, 0x08, 0xBF,
+0x03, 0x04, 0x7F, 0x00, 0x78, 0x81, 0xE6, 0x30,
+0xE4, 0xF2, 0x00, 0xE5, 0x0C, 0xC3, 0x9F, 0x50,
+0x20, 0x05, 0x0C, 0x74, 0x86, 0x25, 0x0C, 0xF8,
+0xE6, 0xFD, 0xA6, 0x81, 0x08, 0xE6, 0xAE, 0x0C,
+0xBE, 0x02, 0x02, 0x74, 0xFF, 0xCD, 0xF8, 0xE8,
+0x6D, 0x60, 0xE0, 0x08, 0xE6, 0xC0, 0xE0, 0x80,
+0xF6, 0xE5, 0x0C, 0xD3, 0x9F, 0x40, 0x27, 0xE5,
+0x0C, 0x24, 0x87, 0xF8, 0xE6, 0xAE, 0x0C, 0xBE,
+0x02, 0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xCD,
+0xF8, 0xE5, 0x81, 0x6D, 0x60, 0x06, 0xD0, 0xE0,
+0xF6, 0x18, 0x80, 0xF5, 0xE5, 0x0C, 0x24, 0x86,
+0xC8, 0xF6, 0x15, 0x0C, 0x80, 0xD3, 0xE5, 0x0C,
+0x23, 0x24, 0x81, 0xF8, 0x7F, 0x04, 0xC2, 0xAF,
+0xE6, 0x30, 0xE0, 0x03, 0x10, 0xE2, 0x0C, 0x7F,
+0x00, 0x30, 0xE1, 0x07, 0x30, 0xE3, 0x04, 0x7F,
+0x08, 0x54, 0xF4, 0x54, 0x7C, 0xC6, 0xD2, 0xAF,
+0x54, 0x80, 0x42, 0x07, 0x22, 0x78, 0x86, 0xA6,
+0x81, 0x74, 0x02, 0x60, 0x06, 0xFF, 0x08, 0x76,
+0xFF, 0xDF, 0xFB, 0x7F, 0x03, 0xE4, 0x78, 0x80,
+0xF6, 0x08, 0xF6, 0x08, 0xDF, 0xFA, 0x78, 0x81,
+0x76, 0x30, 0x90, 0x47, 0xF5, 0x74, 0x01, 0x93,
+0xC0, 0xE0, 0xE4, 0x93, 0xC0, 0xE0, 0x43, 0x89,
+0x01, 0x75, 0x8A, 0x60, 0x75, 0x8C, 0x79, 0xD2,
+0x8C, 0xD2, 0xAF, 0x22, 0x02, 0xEF, 0xD3, 0x94,
+0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0x74, 0x81,
+0x2F, 0x2F, 0xF8, 0xE6, 0x20, 0xE5, 0xF4, 0xC2,
+0xAF, 0xE6, 0x44, 0x30, 0xF6, 0xD2, 0xAF, 0xAE,
+0x0C, 0xEE, 0xC3, 0x9F, 0x50, 0x21, 0x0E, 0x74,
+0x86, 0x2E, 0xF8, 0xE6, 0xF9, 0x08, 0xE6, 0x18,
+0xBE, 0x02, 0x02, 0x74, 0xFF, 0xFD, 0xED, 0x69,
+0x60, 0x09, 0x09, 0xE7, 0x19, 0x19, 0xF7, 0x09,
+0x09, 0x80, 0xF3, 0x16, 0x16, 0x80, 0xDA, 0xEE,
+0xD3, 0x9F, 0x40, 0x04, 0x05, 0x81, 0x05, 0x81,
+0xEE, 0xD3, 0x9F, 0x40, 0x22, 0x74, 0x86, 0x2E,
+0xF8, 0x08, 0xE6, 0xF9, 0xEE, 0xB5, 0x0C, 0x02,
+0xA9, 0x81, 0x18, 0x06, 0x06, 0xE6, 0xFD, 0xED,
+0x69, 0x60, 0x09, 0x19, 0x19, 0xE7, 0x09, 0x09,
+0xF7, 0x19, 0x80, 0xF3, 0x1E, 0x80, 0xD9, 0xEF,
+0x24, 0x86, 0xF8, 0xE6, 0x04, 0xF8, 0xEF, 0x2F,
+0x04, 0x90, 0x47, 0xF5, 0x93, 0xF6, 0x08, 0xEF,
+0x2F, 0x93, 0xF6, 0x7F, 0x00, 0x22, 0xEF, 0xD3,
+0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0xEF,
+0x23, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE5, 0xF4,
+0xC2, 0xAF, 0xE6, 0x54, 0x8C, 0xF6, 0xD2, 0xAF,
+0xE5, 0x0C, 0xB5, 0x07, 0x0A, 0x74, 0x86, 0x2F,
+0xF8, 0xE6, 0xF5, 0x81, 0x02, 0x43, 0x4D, 0x50,
+0x2E, 0x74, 0x87, 0x2F, 0xF8, 0xE6, 0xBF, 0x02,
+0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xF9, 0x74,
+0x86, 0x2F, 0xF8, 0xFB, 0xE6, 0xFC, 0xE9, 0x6C,
+0x60, 0x08, 0xA8, 0x05, 0xE7, 0xF6, 0x1D, 0x19,
+0x80, 0xF4, 0xA8, 0x03, 0xA6, 0x05, 0x1F, 0xE5,
+0x0C, 0xB5, 0x07, 0xE3, 0x7F, 0x00, 0x22, 0x74,
+0x87, 0x2F, 0xF8, 0xE6, 0xFD, 0x18, 0x86, 0x01,
+0x0F, 0x74, 0x86, 0x2F, 0xF8, 0xA6, 0x01, 0x08,
+0x86, 0x04, 0xE5, 0x0C, 0xB5, 0x07, 0x02, 0xAC,
+0x81, 0xED, 0x6C, 0x60, 0x08, 0x0D, 0x09, 0xA8,
+0x05, 0xE6, 0xF7, 0x80, 0xF4, 0xE5, 0x0C, 0xB5,
+0x07, 0xDE, 0x89, 0x81, 0x7F, 0x00, 0x22, 0xEF,
+0xD3, 0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22,
+0xEF, 0x23, 0x24, 0x81, 0xF8, 0xC2, 0xAF, 0xE6,
+0x30, 0xE5, 0x05, 0x30, 0xE0, 0x02, 0xD2, 0xE4,
+0xD2, 0xE2, 0xC6, 0xD2, 0xAF, 0x7F, 0x00, 0x30,
+0xE2, 0x01, 0x0F, 0x02, 0x43, 0x4C, 0x8F, 0xF0,
+0xE4, 0xFF, 0xFE, 0xE5, 0x0C, 0x23, 0x24, 0x80,
+0xF8, 0xC2, 0xA9, 0x30, 0xF7, 0x0D, 0x7F, 0x08,
+0xE6, 0x60, 0x0B, 0x2D, 0xF6, 0x60, 0x30, 0x50,
+0x2E, 0x80, 0x07, 0x30, 0xF1, 0x06, 0xED, 0xF6,
+0x60, 0x25, 0x7E, 0x02, 0x08, 0x30, 0xF0, 0x10,
+0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x23, 0x0E, 0x30,
+0xE2, 0x0C, 0xD2, 0xAF, 0x7F, 0x04, 0x80, 0x12,
+0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x13, 0x54, 0xEC,
+0x4E, 0xF6, 0xD2, 0xAF, 0x02, 0x43, 0x4D, 0x7F,
+0x08, 0x08, 0xEF, 0x44, 0x83, 0xF4, 0xC2, 0xAF,
+0x56, 0xC6, 0xD2, 0xAF, 0x54, 0x80, 0x4F, 0xFF,
+0x22, 0xE7, 0x09, 0xF6, 0x08, 0xDF, 0xFA, 0x80,
+0x46, 0xE7, 0x09, 0xF2, 0x08, 0xDF, 0xFA, 0x80,
+0x3E, 0x88, 0x82, 0x8C, 0x83, 0xE7, 0x09, 0xF0,
+0xA3, 0xDF, 0xFA, 0x80, 0x32, 0xE3, 0x09, 0xF6,
+0x08, 0xDF, 0xFA, 0x80, 0x78, 0xE3, 0x09, 0xF2,
+0x08, 0xDF, 0xFA, 0x80, 0x70, 0x88, 0x82, 0x8C,
+0x83, 0xE3, 0x09, 0xF0, 0xA3, 0xDF, 0xFA, 0x80,
+0x64, 0x89, 0x82, 0x8A, 0x83, 0xE0, 0xA3, 0xF6,
+0x08, 0xDF, 0xFA, 0x80, 0x58, 0x89, 0x82, 0x8A,
+0x83, 0xE0, 0xA3, 0xF2, 0x08, 0xDF, 0xFA, 0x80,
+0x4C, 0x80, 0xD2, 0x80, 0xFA, 0x80, 0xC6, 0x80,
+0xD4, 0x80, 0x69, 0x80, 0xF2, 0x80, 0x33, 0x80,
+0x10, 0x80, 0xA6, 0x80, 0xEA, 0x80, 0x9A, 0x80,
+0xA8, 0x80, 0xDA, 0x80, 0xE2, 0x80, 0xCA, 0x80,
+0x33, 0x89, 0x82, 0x8A, 0x83, 0xEC, 0xFA, 0xE4,
+0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC, 0xC5,
+0x83, 0xCC, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8,
+0xCC, 0xC5, 0x83, 0xCC, 0xDF, 0xE9, 0xDE, 0xE7,
+0x80, 0x0D, 0x89, 0x82, 0x8A, 0x83, 0xE4, 0x93,
+0xA3, 0xF6, 0x08, 0xDF, 0xF9, 0xEC, 0xFA, 0xA9,
+0xF0, 0xED, 0xFB, 0x22, 0x89, 0x82, 0x8A, 0x83,
+0xEC, 0xFA, 0xE0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8,
+0xCC, 0xC5, 0x83, 0xCC, 0xF0, 0xA3, 0xC8, 0xC5,
+0x82, 0xC8, 0xCC, 0xC5, 0x83, 0xCC, 0xDF, 0xEA,
+0xDE, 0xE8, 0x80, 0xDB, 0x89, 0x82, 0x8A, 0x83,
+0xE4, 0x93, 0xA3, 0xF2, 0x08, 0xDF, 0xF9, 0x80,
+0xCC, 0x88, 0xF0, 0xEF, 0x60, 0x01, 0x0E, 0x4E,
+0x60, 0xC3, 0x88, 0xF0, 0xED, 0x24, 0x02, 0xB4,
+0x04, 0x00, 0x50, 0xB9, 0xF5, 0x82, 0xEB, 0x24,
+0x02, 0xB4, 0x04, 0x00, 0x50, 0xAF, 0x23, 0x23,
+0x45, 0x82, 0x23, 0x90, 0x45, 0xF9, 0x73, 0xC5,
+0xF0, 0xF8, 0xA3, 0xE0, 0x28, 0xF0, 0xC5, 0xF0,
+0xF8, 0xE5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15,
+0x83, 0xE0, 0x38, 0xF0, 0x22, 0xEF, 0x4B, 0xFF,
+0xEE, 0x4A, 0xFE, 0xED, 0x49, 0xFD, 0xEC, 0x48,
+0xFC, 0x22, 0xEB, 0x9F, 0xF5, 0xF0, 0xEA, 0x9E,
+0x42, 0xF0, 0xE9, 0x9D, 0x42, 0xF0, 0xE8, 0x9C,
+0x45, 0xF0, 0x22, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD,
+0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0xA4,
+0x25, 0x82, 0xF5, 0x82, 0xE5, 0xF0, 0x35, 0x83,
+0xF5, 0x83, 0x22, 0xE0, 0xFB, 0xA3, 0xE0, 0xFA,
+0xA3, 0xE0, 0xF9, 0x22, 0xEB, 0xF0, 0xA3, 0xEA,
+0xF0, 0xA3, 0xE9, 0xF0, 0x22, 0xD0, 0x83, 0xD0,
+0x82, 0xF8, 0xE4, 0x93, 0x70, 0x12, 0x74, 0x01,
+0x93, 0x70, 0x0D, 0xA3, 0xA3, 0x93, 0xF8, 0x74,
+0x01, 0x93, 0xF5, 0x82, 0x88, 0x83, 0xE4, 0x73,
+0x74, 0x02, 0x93, 0x68, 0x60, 0xEF, 0xA3, 0xA3,
+0xA3, 0x80, 0xDF, 0xEF, 0x4E, 0x60, 0x12, 0xEF,
+0x60, 0x01, 0x0E, 0xED, 0xBB, 0x01, 0x0B, 0x89,
+0x82, 0x8A, 0x83, 0xF0, 0xA3, 0xDF, 0xFC, 0xDE,
+0xFA, 0x22, 0x89, 0xF0, 0x50, 0x07, 0xF7, 0x09,
+0xDF, 0xFC, 0xA9, 0xF0, 0x22, 0xBB, 0xFE, 0xFC,
+0xF3, 0x09, 0xDF, 0xFC, 0xA9, 0xF0, 0x22, 0x02,
+0x47, 0x8D, 0x02, 0x43, 0xDD, 0xE4, 0x93, 0xA3,
+0xF8, 0xE4, 0x93, 0xA3, 0x40, 0x03, 0xF6, 0x80,
+0x01, 0xF2, 0x08, 0xDF, 0xF4, 0x80, 0x29, 0xE4,
+0x93, 0xA3, 0xF8, 0x54, 0x07, 0x24, 0x0C, 0xC8,
+0xC3, 0x33, 0xC4, 0x54, 0x0F, 0x44, 0x20, 0xC8,
+0x83, 0x40, 0x04, 0xF4, 0x56, 0x80, 0x01, 0x46,
+0xF6, 0xDF, 0xE4, 0x80, 0x0B, 0x01, 0x02, 0x04,
+0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x47, 0xD2,
+0xE4, 0x7E, 0x01, 0x93, 0x60, 0xBC, 0xA3, 0xFF,
+0x54, 0x3F, 0x30, 0xE5, 0x09, 0x54, 0x1F, 0xFE,
+0xE4, 0x93, 0xA3, 0x60, 0x01, 0x0E, 0xCF, 0x54,
+0xC0, 0x25, 0xE0, 0x60, 0xA8, 0x40, 0xB8, 0xE4,
+0x93, 0xA3, 0xFA, 0xE4, 0x93, 0xA3, 0xF8, 0xE4,
+0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5,
+0x83, 0xCA, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8,
+0xCA, 0xC5, 0x83, 0xCA, 0xDF, 0xE9, 0xDE, 0xE7,
+0x80, 0xBE, 0x41, 0x83, 0x27, 0x00, 0x41, 0x83,
+0x28, 0x00, 0x41, 0x83, 0x35, 0x00, 0x41, 0x83,
+0x38, 0x00, 0x44, 0x82, 0xF9, 0x41, 0x4E, 0x59,
+0x00, 0x44, 0x82, 0xF5, 0x61, 0x6E, 0x79, 0x00,
+0x41, 0x83, 0x39, 0x00, 0x00, 0x60, 0x03, 0x61,
+0x0A, 0x66, 0x68, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0,
+0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00,
+0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03,
+0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07,
+0x90, 0x01, 0xC4, 0x74, 0xFB, 0xF0, 0x74, 0x47,
+0xA3, 0xF0, 0x11, 0x4A, 0x74, 0xFB, 0x04, 0x90,
+0x01, 0xC4, 0xF0, 0x74, 0x47, 0xA3, 0xF0, 0xD0,
+0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0,
+0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0,
+0xE0, 0x32, 0x90, 0x00, 0x54, 0xE0, 0x55, 0x35,
+0xF5, 0x39, 0xA3, 0xE0, 0x55, 0x36, 0xF5, 0x3A,
+0xA3, 0xE0, 0x55, 0x37, 0xF5, 0x3B, 0xA3, 0xE0,
+0x55, 0x38, 0xF5, 0x3C, 0xAD, 0x39, 0x7F, 0x54,
+0x12, 0x32, 0x1E, 0xAD, 0x3A, 0x7F, 0x55, 0x12,
+0x32, 0x1E, 0xAD, 0x3B, 0x7F, 0x56, 0x12, 0x32,
+0x1E, 0xAD, 0x3C, 0x7F, 0x57, 0x12, 0x32, 0x1E,
+0x53, 0x91, 0xEF, 0x22, 0xC0, 0xE0, 0xC0, 0xF0,
+0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0,
+0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0,
+0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0,
+0x07, 0x90, 0x01, 0xC4, 0x74, 0x84, 0xF0, 0x74,
+0x48, 0xA3, 0xF0, 0x12, 0x71, 0x3D, 0xE5, 0x41,
+0x30, 0xE3, 0x03, 0x12, 0x71, 0x9A, 0xE5, 0x41,
+0x30, 0xE4, 0x02, 0x31, 0x31, 0xE5, 0x43, 0x30,
+0xE0, 0x02, 0xF1, 0x81, 0xE5, 0x43, 0x30, 0xE1,
+0x03, 0x12, 0x71, 0xE3, 0xE5, 0x43, 0x30, 0xE2,
+0x03, 0x12, 0x73, 0x19, 0xE5, 0x43, 0x30, 0xE3,
+0x02, 0x91, 0xA4, 0xE5, 0x43, 0x30, 0xE4, 0x03,
+0x12, 0x62, 0x8A, 0xE5, 0x43, 0x30, 0xE5, 0x03,
+0x12, 0x62, 0x1B, 0xE5, 0x43, 0x30, 0xE6, 0x03,
+0x12, 0x61, 0x56, 0xE5, 0x43, 0x30, 0xE7, 0x03,
+0x12, 0x72, 0xBC, 0xE5, 0x44, 0x30, 0xE0, 0x03,
+0x12, 0x72, 0xB4, 0xE5, 0x44, 0x30, 0xE1, 0x03,
+0x12, 0x67, 0xD1, 0x74, 0x84, 0x04, 0x90, 0x01,
+0xC4, 0xF0, 0x74, 0x48, 0xA3, 0xF0, 0xD0, 0x07,
+0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03,
+0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0,
+0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0,
+0x32, 0x31, 0x44, 0x7F, 0x02, 0x8F, 0x0F, 0x7F,
+0x02, 0x12, 0x45, 0x27, 0x90, 0x80, 0x01, 0xE0,
+0x45, 0x0F, 0xF0, 0x22, 0x90, 0x01, 0xCC, 0xE0,
+0x54, 0x0F, 0x90, 0x83, 0x29, 0xF0, 0x90, 0x83,
+0x29, 0xE0, 0xFD, 0x70, 0x02, 0x41, 0x3E, 0x90,
+0x80, 0x60, 0xE0, 0xFF, 0x70, 0x06, 0xA3, 0xE0,
+0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90,
+0x80, 0x61, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01,
+0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x08, 0x90,
+0x01, 0xC1, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90,
+0x83, 0x27, 0x12, 0x70, 0xCE, 0x80, 0x05, 0xC3,
+0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF,
+0x5D, 0x70, 0x02, 0x41, 0x20, 0xE4, 0x90, 0x83,
+0x2A, 0xF0, 0x90, 0x83, 0x2A, 0xE0, 0xF9, 0xC3,
+0x94, 0x04, 0x50, 0x31, 0x71, 0x18, 0xA4, 0xFF,
+0xE9, 0xFD, 0x7C, 0x00, 0x2F, 0xFF, 0xEC, 0x35,
+0xF0, 0xFE, 0x74, 0xD0, 0x71, 0xF6, 0x90, 0x80,
+0x10, 0x71, 0xD5, 0x71, 0x18, 0xA4, 0x2D, 0xFF,
+0xEC, 0x35, 0xF0, 0xFE, 0x74, 0xF0, 0x71, 0xF6,
+0x90, 0x80, 0x14, 0x71, 0xD5, 0x90, 0x83, 0x2A,
+0xE0, 0x04, 0xF0, 0x80, 0xC5, 0x90, 0x83, 0x29,
+0xE0, 0xFF, 0x90, 0x83, 0x27, 0xE0, 0xFE, 0x74,
+0x01, 0xA8, 0x06, 0x08, 0x80, 0x02, 0xC3, 0x33,
+0xD8, 0xFC, 0xF4, 0x5F, 0x90, 0x83, 0x29, 0xF0,
+0x90, 0x83, 0x27, 0x51, 0x45, 0x80, 0x02, 0xC3,
+0x33, 0xD8, 0xFC, 0x90, 0x01, 0xCC, 0xF0, 0x90,
+0x83, 0x27, 0xE0, 0x04, 0xF0, 0xE0, 0x54, 0x03,
+0xF0, 0x90, 0x80, 0x61, 0x12, 0x66, 0x61, 0xB4,
+0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x70, 0x02, 0x21,
+0x4E, 0xE4, 0x90, 0x80, 0x61, 0xF0, 0x21, 0x4E,
+0x90, 0x01, 0xC0, 0xE0, 0x44, 0x02, 0xF0, 0x90,
+0x83, 0x27, 0xE0, 0x44, 0x80, 0x90, 0x00, 0x8A,
+0xF0, 0x71, 0x18, 0x90, 0x01, 0xD0, 0x12, 0x46,
+0xDF, 0xE0, 0x90, 0x01, 0xC3, 0xF0, 0x22, 0x12,
+0x32, 0x1E, 0x90, 0x83, 0x2B, 0xE0, 0xFF, 0x74,
+0x01, 0xA8, 0x07, 0x08, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x83, 0x2C, 0xED,
+0xF0, 0x90, 0x83, 0x2B, 0xEF, 0xF0, 0xD3, 0x94,
+0x07, 0x50, 0x4B, 0x51, 0x45, 0x80, 0x02, 0xC3,
+0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x47,
+0xE0, 0x5F, 0xFD, 0x7F, 0x47, 0x51, 0x3F, 0x80,
+0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xFF, 0x90, 0x00,
+0x46, 0xE0, 0x4F, 0xFD, 0x7F, 0x46, 0x71, 0xC1,
+0x60, 0x10, 0x51, 0x42, 0x80, 0x02, 0xC3, 0x33,
+0xD8, 0xFC, 0xFF, 0x90, 0x00, 0x45, 0xE0, 0x4F,
+0x80, 0x0F, 0x51, 0x42, 0x80, 0x02, 0xC3, 0x33,
+0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x45, 0xE0,
+0x5F, 0xFD, 0x7F, 0x45, 0x80, 0x62, 0x90, 0x83,
+0x2B, 0xE0, 0x24, 0xF8, 0xF0, 0xE0, 0x24, 0x04,
+0x51, 0x46, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC,
+0xF4, 0xFF, 0x90, 0x00, 0x43, 0xE0, 0x5F, 0xFD,
+0x7F, 0x43, 0x51, 0x3F, 0x80, 0x02, 0xC3, 0x33,
+0xD8, 0xFC, 0xFF, 0x90, 0x00, 0x43, 0xE0, 0x4F,
+0xFD, 0x7F, 0x43, 0x71, 0xC1, 0x60, 0x19, 0x90,
+0x83, 0x2B, 0xE0, 0x24, 0x04, 0x51, 0x46, 0x80,
+0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xFF, 0x90, 0x00,
+0x42, 0xE0, 0x4F, 0xFD, 0x7F, 0x42, 0x80, 0x18,
+0x90, 0x83, 0x2B, 0xE0, 0x24, 0x04, 0x51, 0x46,
+0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF,
+0x90, 0x00, 0x42, 0xE0, 0x5F, 0xFD, 0x7F, 0x42,
+0x12, 0x32, 0x1E, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x90, 0x83, 0x27, 0xE0, 0x75, 0xF0, 0x04, 0x22,
+0xAD, 0x07, 0x90, 0x82, 0x21, 0xE0, 0x75, 0xF0,
+0x20, 0xA4, 0xFF, 0x90, 0x83, 0x09, 0xE5, 0xF0,
+0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x82, 0x22, 0xE0,
+0x75, 0xF0, 0x08, 0xA4, 0xAE, 0xF0, 0x90, 0x83,
+0x0B, 0xF0, 0xEE, 0xA3, 0xF0, 0x71, 0xB9, 0x90,
+0x83, 0x0D, 0xF0, 0xEE, 0xA3, 0xF0, 0xED, 0x64,
+0x01, 0x60, 0x5E, 0x90, 0x82, 0x1F, 0xE0, 0xFE,
+0xF1, 0xF0, 0x30, 0xE0, 0x54, 0xEE, 0x71, 0xEA,
+0x20, 0xE0, 0x02, 0x7D, 0x01, 0x71, 0xB2, 0xFE,
+0x54, 0x0F, 0xFF, 0xEE, 0xC4, 0x13, 0x13, 0x54,
+0x01, 0xFD, 0x71, 0xB2, 0xC4, 0x13, 0x54, 0x07,
+0x30, 0xE0, 0x21, 0xA3, 0xE0, 0x30, 0xE0, 0x0D,
+0x90, 0x83, 0x0E, 0xE0, 0xF5, 0x1D, 0x90, 0x83,
+0x0D, 0x71, 0xC9, 0x80, 0x0F, 0x71, 0xB9, 0xFF,
+0x12, 0x32, 0xAA, 0x71, 0xE5, 0x20, 0xE0, 0x02,
+0x7D, 0x01, 0x51, 0x4D, 0x90, 0x82, 0x1F, 0xE0,
+0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x0B, 0x90, 0x83,
+0x0C, 0xE0, 0xF5, 0x1D, 0x90, 0x83, 0x0B, 0x71,
+0xC9, 0x22, 0x51, 0x4D, 0x90, 0x82, 0x1F, 0xE0,
+0x22, 0x90, 0x83, 0x09, 0xE0, 0xFE, 0xA3, 0xE0,
+0x22, 0x12, 0x32, 0x1E, 0x90, 0x83, 0x2C, 0xE0,
+0x22, 0xE0, 0xF5, 0x1E, 0xE4, 0xFB, 0xFD, 0x7F,
+0x58, 0x7E, 0x01, 0x80, 0x67, 0x12, 0x46, 0xDF,
+0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE4, 0x35, 0x83,
+0xF5, 0x83, 0xEF, 0xF0, 0x22, 0x90, 0x82, 0x1F,
+0xE0, 0xFE, 0x54, 0x0F, 0xFF, 0xEE, 0xC4, 0x13,
+0x13, 0x54, 0x03, 0x7D, 0x00, 0x22, 0x2F, 0xF5,
+0x82, 0x74, 0x01, 0x3E, 0xF5, 0x83, 0xE0, 0xFF,
+0x90, 0x80, 0x61, 0xE0, 0x75, 0xF0, 0x08, 0x22,
+0x90, 0x82, 0x1F, 0xF1, 0xEE, 0x30, 0xE0, 0x1A,
+0xEF, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x03, 0x12,
+0x65, 0x1F, 0x90, 0x82, 0x20, 0xE0, 0x30, 0xE0,
+0x09, 0x71, 0xE5, 0x20, 0xE0, 0x02, 0x7D, 0x01,
+0x51, 0x4D, 0x22, 0xF0, 0xE4, 0xF5, 0x1D, 0x90,
+0x82, 0x03, 0xE0, 0xF5, 0x1E, 0xE4, 0xFB, 0xFD,
+0x7F, 0x54, 0x7E, 0x01, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x8E, 0x19, 0x8F, 0x1A, 0xE5,
+0x1E, 0x54, 0x07, 0xC4, 0x33, 0x54, 0xE0, 0x85,
+0x19, 0x83, 0x85, 0x1A, 0x82, 0xF0, 0xE5, 0x1D,
+0x91, 0x9C, 0xE5, 0x1E, 0x13, 0x13, 0x13, 0x54,
+0x1F, 0x4F, 0xA3, 0xF0, 0xEB, 0x91, 0x9C, 0xE5,
+0x1D, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x4F, 0x91,
+0x93, 0xF0, 0xBD, 0x01, 0x0D, 0x85, 0x1A, 0x82,
+0x8E, 0x83, 0xA3, 0xA3, 0xA3, 0x74, 0x03, 0xF0,
+0x80, 0x06, 0x91, 0x93, 0xA3, 0x74, 0x01, 0xF0,
+0x91, 0x93, 0xA3, 0x74, 0x05, 0xF0, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0x85, 0x1A, 0x82, 0x85, 0x19,
+0x83, 0xA3, 0xA3, 0x22, 0x54, 0x07, 0xC4, 0x33,
+0x54, 0xE0, 0xFF, 0x22, 0xF1, 0xC8, 0x70, 0x12,
+0x90, 0x81, 0x30, 0xE0, 0x60, 0x0C, 0x90, 0x81,
+0x34, 0xE0, 0x20, 0xE4, 0x05, 0x12, 0x7D, 0xFD,
+0x91, 0x2B, 0x22, 0x90, 0x81, 0x34, 0xE0, 0x44,
+0x10, 0xF0, 0x90, 0x81, 0x39, 0xE0, 0x60, 0x04,
+0x64, 0x01, 0x70, 0x15, 0xE4, 0xF5, 0x1D, 0x90,
+0x81, 0x39, 0xE0, 0xFF, 0x90, 0x81, 0x38, 0xE0,
+0x2F, 0x91, 0x33, 0x90, 0x81, 0x39, 0xE0, 0x80,
+0x0F, 0xE4, 0xF5, 0x1D, 0x91, 0xFB, 0xFF, 0x90,
+0x81, 0x38, 0xE0, 0x2F, 0x91, 0x33, 0x91, 0xFB,
+0xFF, 0x90, 0x81, 0x38, 0xE0, 0x2F, 0x90, 0x81,
+0x49, 0xF0, 0x22, 0x90, 0x81, 0x39, 0xE0, 0x75,
+0xF0, 0x03, 0xA4, 0x24, 0xFE, 0x22, 0x90, 0x82,
+0x09, 0xE0, 0x30, 0xE0, 0x49, 0xC4, 0x54, 0x0F,
+0x20, 0xE0, 0x17, 0xE4, 0xF5, 0x1D, 0x90, 0x82,
+0x0B, 0x91, 0x32, 0xD1, 0x90, 0xF1, 0xD1, 0x30,
+0xE0, 0x06, 0x7D, 0x0C, 0x7F, 0x01, 0xB1, 0x57,
+0xE1, 0xDE, 0x90, 0x82, 0x09, 0xE0, 0xC4, 0x54,
+0x0F, 0x30, 0xE0, 0x22, 0xE4, 0xF5, 0x1D, 0x90,
+0x82, 0x0C, 0x91, 0x32, 0x90, 0x82, 0x09, 0xE0,
+0x54, 0xEF, 0xF0, 0xE0, 0xC3, 0x13, 0x30, 0xE0,
+0x06, 0x7D, 0x04, 0x7F, 0x01, 0x80, 0x08, 0x7B,
+0x31, 0xF1, 0xD8, 0x12, 0x69, 0x66, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xAC, 0x07,
+0xEF, 0x14, 0x60, 0x15, 0x14, 0x60, 0x19, 0x24,
+0x02, 0x70, 0x1A, 0xED, 0x54, 0x01, 0xFE, 0x90,
+0x81, 0x2B, 0xE0, 0x54, 0xFE, 0x4E, 0xF0, 0x80,
+0x0C, 0x90, 0x81, 0x33, 0xED, 0xF0, 0x80, 0x05,
+0x90, 0x81, 0x32, 0xED, 0xF0, 0x90, 0x00, 0x8F,
+0xE0, 0x30, 0xE4, 0x2E, 0xEC, 0x14, 0x60, 0x07,
+0x14, 0x60, 0x1D, 0x24, 0x02, 0x70, 0x23, 0x90,
+0x81, 0x2B, 0xE0, 0x54, 0x01, 0xC4, 0x33, 0x33,
+0x33, 0x54, 0x80, 0xFF, 0x90, 0x81, 0x33, 0xE0,
+0x54, 0x7F, 0x4F, 0xFD, 0x7F, 0x88, 0x80, 0x07,
+0x90, 0x81, 0x32, 0xE0, 0xFD, 0x7F, 0x89, 0x12,
+0x32, 0x1E, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7E,
+0x00, 0x7F, 0xD7, 0x7D, 0x00, 0x7B, 0x01, 0x7A,
+0x81, 0x79, 0x2B, 0x12, 0x47, 0x23, 0x90, 0x81,
+0x2F, 0x74, 0x02, 0xF0, 0x90, 0x81, 0x36, 0x14,
+0xF0, 0xA3, 0xF0, 0xA3, 0x74, 0x10, 0xF0, 0x90,
+0x81, 0x3C, 0xE4, 0xF0, 0xA3, 0x74, 0x05, 0xD1,
+0x6B, 0xE4, 0xFD, 0xFF, 0xB1, 0x57, 0x7D, 0x0C,
+0x7F, 0x02, 0xB1, 0x57, 0x7D, 0x0C, 0x7F, 0x01,
+0xB1, 0x57, 0x90, 0x80, 0x07, 0xE0, 0xFF, 0xB4,
+0x01, 0x08, 0x90, 0x81, 0x3B, 0x74, 0x99, 0xF0,
+0x80, 0x29, 0xEF, 0xB4, 0x03, 0x08, 0x90, 0x81,
+0x3B, 0x74, 0x90, 0xF0, 0x80, 0x1D, 0x90, 0x81,
+0x3B, 0x74, 0x40, 0xF0, 0x90, 0x00, 0x2C, 0xE0,
+0x54, 0x0F, 0xFF, 0xBF, 0x05, 0x08, 0x90, 0x81,
+0x4D, 0x74, 0x02, 0xF0, 0x80, 0x05, 0xE4, 0x90,
+0x81, 0x4D, 0xF0, 0x90, 0x82, 0x02, 0x74, 0x02,
+0xF0, 0xA3, 0x74, 0x0F, 0xF0, 0xA3, 0xE0, 0x54,
+0x01, 0x44, 0x28, 0xF0, 0xA3, 0x74, 0x07, 0xD1,
+0x6B, 0x7E, 0x00, 0x7F, 0x02, 0x7D, 0x00, 0x7B,
+0x01, 0x7A, 0x82, 0x79, 0x06, 0x12, 0x47, 0x23,
+0xF1, 0xE6, 0x12, 0x7E, 0x8C, 0x7B, 0x56, 0xE4,
+0xFD, 0x7F, 0xFF, 0xD1, 0x97, 0xE4, 0x90, 0x82,
+0x08, 0xF0, 0x22, 0xF0, 0x90, 0x81, 0x4D, 0xE0,
+0x24, 0x05, 0x90, 0x81, 0x48, 0xF0, 0xA3, 0x74,
+0x10, 0xF0, 0x22, 0x90, 0x83, 0x33, 0xEF, 0xF0,
+0xD1, 0xED, 0x90, 0x83, 0x33, 0xE0, 0x60, 0x02,
+0xD1, 0x92, 0x7D, 0x04, 0x7F, 0x01, 0xA1, 0x57,
+0xD1, 0xED, 0xE4, 0xFB, 0xFD, 0x7F, 0xFF, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x05,
+0x22, 0xED, 0xF0, 0x90, 0x80, 0x05, 0xEB, 0xF0,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x81, 0x2C,
+0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x04, 0x7D, 0x0C,
+0x80, 0x05, 0x12, 0x75, 0x72, 0x7D, 0x04, 0x7F,
+0x01, 0xB1, 0x57, 0xE4, 0xFB, 0xFD, 0x7F, 0xFF,
+0x80, 0xCD, 0x90, 0x81, 0x2C, 0xE0, 0x90, 0x06,
+0x04, 0x20, 0xE0, 0x08, 0xE0, 0x44, 0x40, 0xF0,
+0x7D, 0x04, 0x80, 0x06, 0xE0, 0x54, 0x7F, 0xF0,
+0x7D, 0x0C, 0x7F, 0x01, 0xB1, 0x57, 0xE4, 0xFB,
+0xFD, 0x7F, 0xFF, 0x80, 0xAA, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x01, 0x01, 0xE0,
+0x44, 0x02, 0xF0, 0x90, 0x01, 0x00, 0x74, 0xFF,
+0xF0, 0x90, 0x06, 0xB7, 0x74, 0x09, 0xF0, 0x90,
+0x06, 0xB4, 0x74, 0x86, 0xF0, 0x12, 0x6A, 0xA3,
+0x54, 0x7F, 0xFC, 0x90, 0x83, 0x1C, 0x12, 0x20,
+0xCE, 0x90, 0x83, 0x1C, 0x12, 0x68, 0xD5, 0x7F,
+0x7C, 0xF1, 0x6E, 0x12, 0x20, 0xDA, 0xCC, 0xC0,
+0x00, 0xC0, 0xF1, 0x6C, 0x12, 0x20, 0xDA, 0x00,
+0xC0, 0x00, 0x14, 0x12, 0x6A, 0xAC, 0x12, 0x20,
+0xDA, 0x00, 0x03, 0x3E, 0x60, 0xE4, 0xFD, 0xFF,
+0x12, 0x6A, 0x10, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x90, 0x82, 0x09, 0xE0, 0x30, 0xE0, 0x14, 0x90,
+0x01, 0x57, 0xE4, 0xF0, 0xD1, 0x90, 0xF1, 0xD1,
+0x30, 0xE0, 0x06, 0x7D, 0x0C, 0x7F, 0x01, 0xB1,
+0x57, 0xF1, 0xDE, 0x22, 0xD1, 0x90, 0x7D, 0x0C,
+0x7F, 0x01, 0xA1, 0x57, 0x7F, 0x8C, 0x7E, 0x08,
+0x12, 0x2E, 0xA2, 0x90, 0x85, 0xBB, 0x22, 0xF1,
+0xE6, 0xD1, 0x92, 0x7D, 0x0C, 0x7F, 0x01, 0xA1,
+0x57, 0x12, 0x72, 0xCD, 0xF1, 0x97, 0xE4, 0xFF,
+0x12, 0x50, 0x9C, 0x90, 0x80, 0xFC, 0xE0, 0x30,
+0xE0, 0x03, 0x12, 0x5C, 0x41, 0x80, 0xB1, 0xE4,
+0xF5, 0x51, 0x90, 0x81, 0x30, 0xE0, 0x60, 0x27,
+0xF1, 0xC8, 0x70, 0x23, 0x12, 0x55, 0x27, 0x60,
+0x0C, 0x90, 0x81, 0x2C, 0xE0, 0xC4, 0x13, 0x13,
+0x54, 0x03, 0x20, 0xE0, 0x03, 0x75, 0x51, 0x01,
+0xE5, 0x51, 0x60, 0x0B, 0x12, 0x7E, 0x18, 0x20,
+0xE2, 0x03, 0x12, 0x51, 0x4D, 0x91, 0xBB, 0x22,
+0xE4, 0xFF, 0x12, 0x53, 0x4B, 0xEF, 0x64, 0x01,
+0x22, 0x90, 0x82, 0x09, 0xE0, 0xC3, 0x13, 0x22,
+0x7D, 0xFF, 0x7F, 0xFF, 0xC1, 0x97, 0x90, 0x82,
+0x09, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0x90, 0x06,
+0x04, 0xE0, 0x54, 0x7F, 0xF0, 0x22, 0xE0, 0xFF,
+0xC4, 0x13, 0x13, 0x13, 0x54, 0x01, 0x22, 0xC0,
+0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0,
+0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01,
+0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05,
+0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74,
+0xF7, 0xF0, 0x74, 0x4F, 0xA3, 0xF0, 0x12, 0x71,
+0x6A, 0xE5, 0x49, 0x30, 0xE1, 0x02, 0x11, 0xD1,
+0xE5, 0x49, 0x30, 0xE2, 0x03, 0x12, 0x61, 0xD7,
+0xE5, 0x49, 0x30, 0xE3, 0x03, 0x12, 0x6E, 0xBB,
+0xE5, 0x49, 0x30, 0xE4, 0x02, 0xB1, 0xB7, 0xE5,
+0x4A, 0x30, 0xE0, 0x03, 0x12, 0x6D, 0x0E, 0xE5,
+0x4B, 0x30, 0xE5, 0x03, 0x12, 0x6F, 0x22, 0xE5,
+0x4C, 0x30, 0xE1, 0x05, 0x7F, 0x04, 0x12, 0x49,
+0x35, 0xE5, 0x4C, 0x30, 0xE4, 0x02, 0x11, 0x96,
+0xE5, 0x4C, 0x30, 0xE5, 0x03, 0x12, 0x62, 0xAC,
+0xE5, 0x4C, 0x30, 0xE6, 0x03, 0x12, 0x62, 0xD6,
+0x74, 0xF7, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74,
+0x4F, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0,
+0x05, 0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0,
+0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0,
+0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x71, 0x76,
+0x11, 0xE2, 0x7F, 0x01, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x81, 0x2D, 0xE0, 0xFE,
+0xC3, 0x13, 0x30, 0xE0, 0x1F, 0x90, 0x82, 0xDC,
+0x74, 0x1E, 0xF0, 0x90, 0x82, 0xEA, 0x74, 0x01,
+0xF0, 0x90, 0x82, 0xDE, 0xEF, 0xF0, 0x7B, 0x01,
+0x7A, 0x82, 0x79, 0xDC, 0x12, 0x65, 0x3B, 0x7F,
+0x04, 0x12, 0x49, 0x35, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x90, 0x81, 0x30, 0xE0, 0x60, 0x02, 0x91,
+0xB3, 0x02, 0x4D, 0x06, 0x7D, 0x01, 0x7F, 0x02,
+0x11, 0xE6, 0x7D, 0x02, 0x7F, 0x02, 0x74, 0x3D,
+0x2F, 0xF8, 0xE6, 0x4D, 0xFE, 0xF6, 0x74, 0x30,
+0x81, 0x9A, 0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFB,
+0xF0, 0xE4, 0x90, 0x81, 0x39, 0xF0, 0xA3, 0xF0,
+0x90, 0x81, 0x34, 0xF0, 0x90, 0x81, 0x2C, 0xE0,
+0x54, 0xF7, 0xF0, 0x54, 0xBF, 0xF0, 0x11, 0xDC,
+0x7D, 0x10, 0x7F, 0x03, 0x81, 0x92, 0x90, 0x01,
+0x36, 0x74, 0x78, 0xF0, 0xA3, 0x74, 0x02, 0xF0,
+0x7D, 0x78, 0xFF, 0x11, 0xE6, 0x7D, 0x02, 0x7F,
+0x03, 0x11, 0xE6, 0x90, 0x06, 0x0A, 0xE0, 0x44,
+0x07, 0x12, 0x7E, 0x2E, 0xE4, 0xFF, 0x71, 0x4B,
+0xBF, 0x01, 0x0F, 0xB1, 0x1F, 0x90, 0x81, 0x33,
+0xE0, 0x20, 0xE2, 0x08, 0x7D, 0x01, 0x7F, 0x04,
+0x80, 0x07, 0xF1, 0xDA, 0x22, 0x7D, 0x01, 0x7F,
+0x04, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x90, 0x83, 0x34, 0xED, 0xF0, 0x90, 0x81, 0x2B,
+0xE0, 0xFE, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30,
+0xE0, 0x02, 0x41, 0xA4, 0xEE, 0x12, 0x4F, 0xF0,
+0x30, 0xE0, 0x02, 0x41, 0xA4, 0x90, 0x81, 0x33,
+0xE0, 0xFE, 0x6F, 0x70, 0x02, 0x41, 0xA4, 0xEF,
+0x70, 0x02, 0x41, 0x15, 0x24, 0xFE, 0x70, 0x02,
+0x41, 0x50, 0x24, 0xFE, 0x60, 0x4C, 0x24, 0xFC,
+0x70, 0x02, 0x41, 0x8E, 0x24, 0xFC, 0x60, 0x02,
+0x41, 0x9D, 0xEE, 0xB4, 0x0E, 0x03, 0x12, 0x4E,
+0xAD, 0x90, 0x81, 0x33, 0xE0, 0x70, 0x05, 0x7F,
+0x01, 0x12, 0x4E, 0x7B, 0x90, 0x81, 0x33, 0xE0,
+0xB4, 0x06, 0x03, 0x12, 0x4E, 0xCA, 0x90, 0x81,
+0x33, 0xE0, 0xB4, 0x04, 0x0E, 0x90, 0x83, 0x34,
+0xE0, 0xFF, 0x60, 0x04, 0xB1, 0x7E, 0x80, 0x03,
+0x12, 0x4F, 0x77, 0x90, 0x81, 0x33, 0xE0, 0x64,
+0x08, 0x60, 0x02, 0x41, 0x9D, 0x12, 0x4F, 0x64,
+0x41, 0x9D, 0x90, 0x81, 0x33, 0xE0, 0x70, 0x05,
+0x7F, 0x01, 0x12, 0x4E, 0x7B, 0x90, 0x81, 0x33,
+0xE0, 0xB4, 0x06, 0x03, 0x12, 0x4E, 0xCA, 0x90,
+0x81, 0x33, 0xE0, 0xB4, 0x0E, 0x08, 0x51, 0xA9,
+0xBF, 0x01, 0x03, 0x12, 0x4E, 0xAD, 0x90, 0x81,
+0x33, 0xE0, 0x64, 0x0C, 0x60, 0x02, 0x41, 0x9D,
+0x51, 0xA9, 0xEF, 0x64, 0x01, 0x60, 0x02, 0x41,
+0x9D, 0x71, 0x00, 0x41, 0x9D, 0x90, 0x81, 0x33,
+0xE0, 0xB4, 0x0E, 0x08, 0x51, 0xA9, 0xBF, 0x01,
+0x03, 0x12, 0x4E, 0xAD, 0x90, 0x81, 0x33, 0xE0,
+0xB4, 0x06, 0x03, 0x12, 0x4E, 0xCA, 0x90, 0x81,
+0x33, 0xE0, 0xB4, 0x0C, 0x07, 0x51, 0xA9, 0xBF,
+0x01, 0x02, 0x71, 0x00, 0x90, 0x81, 0x33, 0xE0,
+0x64, 0x04, 0x70, 0x59, 0x12, 0x73, 0xE4, 0xEF,
+0x64, 0x01, 0x70, 0x51, 0x71, 0x2E, 0x80, 0x4D,
+0x90, 0x81, 0x33, 0xE0, 0xB4, 0x0E, 0x08, 0x51,
+0xA9, 0xBF, 0x01, 0x03, 0x12, 0x4E, 0xAD, 0x90,
+0x81, 0x33, 0xE0, 0xB4, 0x06, 0x03, 0x12, 0x4E,
+0xCA, 0x90, 0x81, 0x33, 0xE0, 0xB4, 0x0C, 0x07,
+0x51, 0xA9, 0xBF, 0x01, 0x02, 0x71, 0x00, 0x90,
+0x81, 0x33, 0xE0, 0x70, 0x05, 0x7F, 0x01, 0x12,
+0x4E, 0x7B, 0x90, 0x81, 0x33, 0xE0, 0xB4, 0x04,
+0x14, 0x12, 0x74, 0xE4, 0x80, 0x0F, 0x90, 0x81,
+0x33, 0xE0, 0xB4, 0x0C, 0x08, 0xB1, 0x37, 0x30,
+0xE0, 0x03, 0x12, 0x6A, 0xB7, 0x90, 0x81, 0x33,
+0x12, 0x7E, 0x54, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x12, 0x73, 0xCB, 0xEF, 0x64, 0x01, 0x60, 0x05,
+0x75, 0x1F, 0x01, 0x80, 0x30, 0x12, 0x67, 0xDA,
+0x30, 0xE0, 0x05, 0x75, 0x1F, 0x02, 0x80, 0x25,
+0x90, 0x81, 0x32, 0xE0, 0xD3, 0x94, 0x04, 0x40,
+0x05, 0x75, 0x1F, 0x08, 0x80, 0x17, 0x90, 0x82,
+0x09, 0xE0, 0x30, 0xE0, 0x0B, 0xC4, 0x54, 0x0F,
+0x30, 0xE0, 0x05, 0x75, 0x1F, 0x11, 0x80, 0x05,
+0x12, 0x74, 0x4B, 0x80, 0x0E, 0x90, 0x01, 0xB9,
+0x74, 0x02, 0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x1F,
+0xF0, 0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x12, 0x4F, 0xC8, 0x70, 0x28, 0x90, 0x81, 0x2C,
+0xE0, 0x54, 0xFD, 0xF0, 0x7B, 0x2C, 0x12, 0x74,
+0xEF, 0x7D, 0x08, 0x7F, 0x01, 0xD1, 0x0B, 0xBF,
+0x01, 0x0E, 0x90, 0x81, 0x2B, 0xE0, 0x44, 0x80,
+0xF0, 0x7D, 0x0E, 0x7F, 0x01, 0x02, 0x4D, 0x57,
+0x12, 0x63, 0x0B, 0x04, 0xF0, 0x22, 0x7B, 0x2D,
+0x12, 0x4F, 0xD8, 0x12, 0x6A, 0x32, 0x90, 0x01,
+0x37, 0x74, 0x02, 0xF0, 0xFD, 0x7F, 0x03, 0x11,
+0xE6, 0x12, 0x69, 0x66, 0xE4, 0xFD, 0x7F, 0x01,
+0x02, 0x4D, 0x57, 0x12, 0x6D, 0xE8, 0xFE, 0xEF,
+0x54, 0x07, 0xFF, 0x74, 0x22, 0x2E, 0x12, 0x70,
+0xC5, 0xFD, 0x7C, 0x00, 0x12, 0x70, 0xD0, 0x80,
+0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9,
+0xFF, 0xEE, 0x5C, 0xFE, 0xEF, 0x5D, 0x4E, 0x7F,
+0x00, 0x60, 0x02, 0x7F, 0x01, 0x22, 0xE4, 0x90,
+0x82, 0x27, 0xF0, 0x90, 0x81, 0x30, 0xE0, 0x60,
+0x21, 0x12, 0x4F, 0xC8, 0x70, 0x1C, 0xF1, 0xEA,
+0xF0, 0x90, 0x82, 0x27, 0x74, 0x01, 0xF0, 0xE4,
+0x90, 0x81, 0x37, 0xF0, 0x04, 0x60, 0x0B, 0x12,
+0x7E, 0x18, 0x20, 0xE2, 0x02, 0x31, 0x4D, 0x12,
+0x4C, 0xBB, 0x22, 0xEF, 0x70, 0x37, 0x7D, 0x78,
+0x7F, 0x02, 0x91, 0xA9, 0x7D, 0x02, 0x7F, 0x03,
+0x91, 0xA9, 0x7D, 0xC8, 0x7F, 0x02, 0x91, 0x92,
+0x12, 0x7D, 0xFD, 0xF0, 0xE4, 0xFF, 0x71, 0x4B,
+0xEF, 0x70, 0x0E, 0x12, 0x4E, 0xED, 0x12, 0x4F,
+0x77, 0x12, 0x75, 0x6A, 0x54, 0x7F, 0xF0, 0x80,
+0x06, 0x7D, 0x01, 0x7F, 0x0C, 0x31, 0x51, 0x12,
+0x67, 0x98, 0x02, 0x7E, 0x8C, 0x21, 0x16, 0x12,
+0x4F, 0xC8, 0x60, 0x02, 0x81, 0x8D, 0x90, 0x81,
+0x30, 0xE0, 0x70, 0x02, 0x81, 0x8D, 0x90, 0x06,
+0xA9, 0xE0, 0xFF, 0x12, 0x7D, 0xFD, 0xF0, 0x90,
+0x81, 0x34, 0xE0, 0x54, 0xED, 0xF0, 0x12, 0x61,
+0x75, 0xB1, 0x27, 0x64, 0x01, 0x70, 0x27, 0x90,
+0x06, 0xAB, 0xE0, 0x90, 0x81, 0x37, 0xF0, 0x90,
+0x06, 0xAA, 0xE0, 0x60, 0x05, 0xE0, 0x90, 0x81,
+0x36, 0xF0, 0x90, 0x81, 0x37, 0xE0, 0xFF, 0x70,
+0x08, 0x90, 0x81, 0x36, 0xE0, 0xFE, 0xFF, 0x80,
+0x00, 0x90, 0x81, 0x37, 0xEF, 0xF0, 0xE4, 0x90,
+0x81, 0x39, 0xF0, 0xA3, 0x12, 0x7E, 0x2E, 0x90,
+0x81, 0x2C, 0x12, 0x6F, 0xE3, 0x30, 0xE0, 0x4B,
+0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x20, 0xE0,
+0x1F, 0xB1, 0x2F, 0x6F, 0x70, 0x3D, 0x90, 0x81,
+0x2C, 0xE0, 0x44, 0x40, 0xF0, 0xF1, 0xEA, 0xB1,
+0x41, 0x12, 0x73, 0xA5, 0xF1, 0xD4, 0x91, 0xA5,
+0x90, 0x81, 0x37, 0xE0, 0x14, 0xF0, 0x80, 0x23,
+0xB1, 0x27, 0x64, 0x01, 0x70, 0x1D, 0xB1, 0x2F,
+0xFE, 0x6F, 0x60, 0x17, 0x90, 0x05, 0x73, 0xE0,
+0xFF, 0xEE, 0x6F, 0x60, 0x0E, 0xB1, 0x37, 0x30,
+0xE0, 0x09, 0xEF, 0x54, 0xBF, 0xB1, 0x41, 0x91,
+0x92, 0x11, 0xDC, 0xF1, 0xDA, 0x22, 0x7D, 0x10,
+0xE4, 0xFF, 0x74, 0x45, 0xF1, 0xF2, 0xFE, 0xF6,
+0x74, 0x38, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x01,
+0xF5, 0x83, 0xEE, 0xF0, 0x22, 0x7D, 0x02, 0x7F,
+0x02, 0x74, 0x3D, 0xF1, 0xF2, 0xFE, 0xF6, 0x74,
+0x30, 0x80, 0xE7, 0x90, 0x81, 0x2C, 0x12, 0x6F,
+0xE3, 0x30, 0xE0, 0x0B, 0xEF, 0xC4, 0x13, 0x13,
+0x54, 0x03, 0x30, 0xE0, 0x02, 0x91, 0xA5, 0x90,
+0x81, 0x2B, 0xB1, 0x3A, 0x30, 0xE0, 0x08, 0xEF,
+0x12, 0x7E, 0x47, 0x70, 0x49, 0x80, 0x44, 0x90,
+0x81, 0x39, 0xE0, 0x04, 0xF0, 0x90, 0x81, 0x34,
+0xE0, 0x54, 0xEF, 0xF0, 0x90, 0x82, 0x02, 0xE0,
+0xFF, 0x90, 0x81, 0x39, 0xE0, 0xD3, 0x9F, 0x40,
+0x2A, 0x12, 0x4F, 0xC8, 0x70, 0x28, 0x12, 0x62,
+0x5F, 0x70, 0x02, 0x80, 0x22, 0x90, 0x81, 0x3A,
+0xE0, 0x04, 0xF0, 0xE0, 0xD3, 0x94, 0x02, 0x40,
+0x09, 0xB1, 0x1F, 0xE4, 0x90, 0x81, 0x3A, 0xF0,
+0x80, 0x03, 0x12, 0x61, 0xC4, 0xE4, 0x90, 0x81,
+0x39, 0xF0, 0x22, 0x12, 0x61, 0x4C, 0x22, 0x90,
+0x81, 0x2C, 0xE0, 0x54, 0xFB, 0xF0, 0x22, 0x90,
+0x81, 0x2E, 0xE0, 0xC4, 0x54, 0x0F, 0x22, 0x90,
+0x81, 0x36, 0xE0, 0xFF, 0xA3, 0xE0, 0x22, 0x90,
+0x81, 0x2C, 0xE0, 0xFF, 0x13, 0x13, 0x54, 0x3F,
+0x22, 0xF0, 0x90, 0x01, 0x3F, 0x74, 0x10, 0xF0,
+0xFD, 0x7F, 0x03, 0x22, 0x90, 0x82, 0x46, 0x12,
+0x46, 0xF4, 0x11, 0xF2, 0x90, 0x81, 0x30, 0xE0,
+0xFF, 0x71, 0xA3, 0x90, 0x81, 0x30, 0xE0, 0x60,
+0x1C, 0x90, 0x82, 0x46, 0x12, 0x5F, 0x27, 0x54,
+0x0F, 0xFF, 0x12, 0x5F, 0xD4, 0xFD, 0x12, 0x74,
+0xB7, 0x12, 0x6D, 0x9E, 0x90, 0x83, 0x23, 0x74,
+0x01, 0xF0, 0x12, 0x6C, 0x2E, 0x22, 0xEF, 0x60,
+0x35, 0x12, 0x4F, 0xC8, 0x70, 0x30, 0x90, 0x81,
+0x2C, 0xE0, 0x54, 0xFE, 0xF0, 0x7B, 0x2B, 0x7D,
+0x0F, 0x7F, 0xFF, 0x12, 0x4E, 0x97, 0x90, 0x06,
+0x04, 0xE0, 0x54, 0xBF, 0xF0, 0xD1, 0x07, 0xBF,
+0x01, 0x0E, 0x90, 0x81, 0x2B, 0xE0, 0x44, 0x40,
+0xF0, 0x7D, 0x06, 0x7F, 0x01, 0x02, 0x4D, 0x57,
+0x12, 0x63, 0x0B, 0x74, 0x08, 0xF0, 0x22, 0x12,
+0x4F, 0xD1, 0x30, 0xE0, 0x0A, 0x30, 0xE0, 0x46,
+0x90, 0x81, 0x2B, 0xE0, 0x30, 0xE0, 0x3F, 0x90,
+0x81, 0x1E, 0xE0, 0x60, 0x2F, 0x90, 0x01, 0x63,
+0xE4, 0xF0, 0x90, 0x81, 0x1F, 0xE0, 0x60, 0x08,
+0xF5, 0x2D, 0xE4, 0xF5, 0x2E, 0xFB, 0x80, 0x11,
+0x90, 0x81, 0x20, 0xE0, 0xFB, 0x60, 0x07, 0xE4,
+0xF5, 0x2D, 0xF5, 0x2E, 0x80, 0x03, 0x12, 0x7D,
+0xB8, 0x7D, 0x01, 0x7F, 0x60, 0x7E, 0x01, 0x12,
+0x31, 0x21, 0x80, 0x07, 0x91, 0x8E, 0x90, 0x01,
+0x63, 0xE4, 0xF0, 0x12, 0x6E, 0x74, 0x22, 0x7D,
+0x08, 0xE4, 0xFF, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x83, 0x0F, 0xEF, 0xF0, 0xA3,
+0xED, 0xF0, 0x90, 0x80, 0x03, 0xE0, 0x04, 0xF0,
+0x90, 0x04, 0x1D, 0xE0, 0x60, 0x28, 0x90, 0x05,
+0x22, 0xE0, 0x90, 0x83, 0x13, 0xF0, 0x7B, 0x26,
+0x12, 0x6A, 0x9C, 0x12, 0x6A, 0x32, 0xEF, 0x64,
+0x01, 0x70, 0x02, 0xD1, 0x87, 0x90, 0x83, 0x13,
+0xE0, 0xFD, 0x7B, 0x27, 0xE4, 0xFF, 0x12, 0x4E,
+0x97, 0x12, 0x75, 0x07, 0x80, 0x05, 0x12, 0x75,
+0x07, 0xD1, 0x87, 0x12, 0x62, 0x57, 0x7F, 0x01,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF1, 0xBD, 0x54,
+0x3F, 0xF0, 0xBF, 0x01, 0x02, 0x80, 0x16, 0xEF,
+0x70, 0x02, 0x80, 0x07, 0x90, 0x81, 0x33, 0xE0,
+0x30, 0xE3, 0x0A, 0xF1, 0xB0, 0x54, 0xEF, 0xF1,
+0xBC, 0x44, 0x40, 0xF0, 0x22, 0xF1, 0xB0, 0x44,
+0x10, 0xF1, 0xBC, 0x44, 0x80, 0xF0, 0x22, 0x90,
+0x80, 0x0B, 0xE0, 0xFF, 0x90, 0x83, 0x10, 0xE0,
+0xFB, 0x90, 0x83, 0x1B, 0x74, 0x0A, 0xF0, 0x7D,
+0x01, 0xF1, 0x19, 0x90, 0x83, 0x11, 0xEE, 0xF0,
+0xFC, 0xA3, 0xEF, 0xF0, 0xFD, 0x90, 0x83, 0x0F,
+0xE0, 0xFF, 0xD1, 0x5D, 0x90, 0x83, 0x11, 0xE0,
+0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x04, 0x80, 0xE0,
+0x54, 0x0F, 0xFD, 0xAC, 0x07, 0x12, 0x7E, 0x6E,
+0x44, 0x01, 0xF0, 0x12, 0x7E, 0x6E, 0x54, 0xFB,
+0xF0, 0xAC, 0x07, 0x74, 0x16, 0x2C, 0xF1, 0xCC,
+0xE0, 0x44, 0xFA, 0xF0, 0x74, 0x15, 0x2C, 0xF5,
+0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44,
+0x1F, 0xF0, 0xAC, 0x07, 0x74, 0x06, 0x2C, 0xF5,
+0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44,
+0x0F, 0xF0, 0x90, 0x04, 0x53, 0xE4, 0xF0, 0x90,
+0x04, 0x52, 0xF0, 0x90, 0x04, 0x51, 0x74, 0xFF,
+0xF0, 0x90, 0x04, 0x50, 0x74, 0xFD, 0xF0, 0x74,
+0x14, 0x2C, 0xF1, 0xE2, 0xE0, 0x54, 0xC0, 0x4D,
+0xFD, 0x74, 0x14, 0x2F, 0xF1, 0xE2, 0xED, 0xF0,
+0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x90, 0x83, 0x19, 0xED, 0xF0, 0xA3, 0xEB, 0xF0,
+0x90, 0x83, 0x18, 0xEF, 0xF0, 0xE4, 0xFD, 0xFC,
+0x12, 0x75, 0x8A, 0x7C, 0x00, 0xAD, 0x07, 0x90,
+0x83, 0x18, 0xE0, 0x90, 0x04, 0x25, 0xF0, 0x90,
+0x83, 0x19, 0xE0, 0x60, 0x0E, 0x74, 0x0F, 0x2F,
+0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0,
+0x44, 0x80, 0xF0, 0xAF, 0x05, 0x74, 0x08, 0x2F,
+0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE4,
+0xF0, 0x74, 0x09, 0x2F, 0xF5, 0x82, 0xE4, 0x34,
+0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xF0, 0xF0, 0xAF,
+0x05, 0xF1, 0xC9, 0xE0, 0x20, 0xE1, 0x15, 0x54,
+0x01, 0xFE, 0x90, 0x83, 0x1A, 0xE0, 0x25, 0xE0,
+0x25, 0xE0, 0xFB, 0xEE, 0x44, 0x02, 0x4B, 0xFE,
+0xF1, 0xC9, 0xEE, 0xF0, 0x90, 0x83, 0x1B, 0xE0,
+0xFF, 0xAE, 0x05, 0x74, 0x1E, 0x2E, 0xF5, 0x82,
+0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xEF, 0xF0, 0x74,
+0x21, 0x2E, 0xF1, 0xB3, 0x54, 0xF7, 0xF0, 0xAE,
+0x04, 0xAF, 0x05, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x74, 0x21, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC,
+0xF5, 0x83, 0xE0, 0x22, 0xF0, 0x74, 0x1F, 0x2D,
+0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0,
+0x22, 0x74, 0x16, 0x2F, 0xF5, 0x82, 0xE4, 0x34,
+0xFC, 0xF5, 0x83, 0x22, 0x7D, 0x01, 0x7F, 0x02,
+0x81, 0xA9, 0x90, 0x81, 0x2C, 0xE0, 0x44, 0x04,
+0xF0, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5,
+0x83, 0x22, 0x90, 0x81, 0x36, 0xE0, 0x90, 0x05,
+0x73, 0x22, 0x2F, 0xF8, 0xE6, 0xFE, 0xED, 0xF4,
+0x5E, 0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82,
+0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x05, 0xC0,
+0x07, 0x7D, 0xFA, 0x90, 0x01, 0xC4, 0xED, 0xF0,
+0x74, 0x57, 0xFF, 0xA3, 0xF0, 0xED, 0x04, 0x90,
+0x01, 0xC4, 0xF0, 0xA3, 0xEF, 0xF0, 0xD0, 0x07,
+0xD0, 0x05, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83,
+0xD0, 0xE0, 0x32, 0x90, 0x00, 0xF7, 0xE0, 0x20,
+0xE7, 0x09, 0xE0, 0x7F, 0x01, 0x20, 0xE6, 0x0C,
+0x7F, 0x02, 0x22, 0x90, 0x00, 0xF7, 0xE0, 0x30,
+0xE6, 0x02, 0x7F, 0x03, 0x22, 0x11, 0x2B, 0x90,
+0x80, 0x07, 0xEF, 0xF0, 0x11, 0x65, 0x90, 0x01,
+0x64, 0x74, 0x01, 0xF0, 0x90, 0x00, 0x12, 0xE0,
+0x54, 0xC7, 0x44, 0x20, 0xFD, 0x7F, 0x12, 0x12,
+0x32, 0x1E, 0x02, 0x2D, 0xA7, 0x90, 0x00, 0x08,
+0xE0, 0x54, 0xEF, 0xF0, 0x11, 0x9E, 0x11, 0xD6,
+0x12, 0x70, 0xD8, 0x12, 0x70, 0xF7, 0xE4, 0xF5,
+0x35, 0xF5, 0x37, 0xF5, 0x36, 0xF5, 0x37, 0x75,
+0x38, 0x80, 0xAD, 0x35, 0x7F, 0x50, 0x12, 0x32,
+0x1E, 0xAD, 0x36, 0x7F, 0x51, 0x12, 0x32, 0x1E,
+0xAD, 0x37, 0x7F, 0x52, 0x12, 0x32, 0x1E, 0xAD,
+0x38, 0x7F, 0x53, 0x02, 0x32, 0x1E, 0x90, 0x01,
+0x30, 0xE4, 0x11, 0xCE, 0x90, 0x01, 0x38, 0x11,
+0xCE, 0xFD, 0x7F, 0x50, 0x12, 0x32, 0x1E, 0xE4,
+0xFD, 0x7F, 0x51, 0x12, 0x32, 0x1E, 0xE4, 0xFD,
+0x7F, 0x52, 0x12, 0x32, 0x1E, 0xE4, 0xFD, 0x7F,
+0x53, 0x02, 0x32, 0x1E, 0xE4, 0x90, 0x82, 0x4B,
+0xF0, 0x90, 0x82, 0xB6, 0xF0, 0xA3, 0xF0, 0xA3,
+0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x01,
+0x34, 0x74, 0xFF, 0x11, 0xCE, 0x90, 0x01, 0x3C,
+0x11, 0xCE, 0xFD, 0x7F, 0x54, 0x12, 0x32, 0x1E,
+0x7D, 0xFF, 0x7F, 0x55, 0x12, 0x32, 0x1E, 0x7D,
+0xFF, 0x7F, 0x56, 0x12, 0x32, 0x1E, 0x7D, 0xFF,
+0x7F, 0x57, 0x02, 0x32, 0x1E, 0x90, 0x80, 0xFC,
+0xE0, 0x54, 0xFE, 0x71, 0x9A, 0x90, 0x80, 0xFC,
+0xE0, 0x54, 0xFD, 0xF0, 0x54, 0xFB, 0xF0, 0x54,
+0xF7, 0xF0, 0x54, 0xEF, 0xF0, 0xE4, 0x90, 0x80,
+0xFF, 0x11, 0xCC, 0x11, 0xCF, 0x90, 0x81, 0x1E,
+0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x82,
+0xC6, 0x51, 0xF7, 0xE4, 0x11, 0xCF, 0xFC, 0xA3,
+0xF0, 0x31, 0xD3, 0x90, 0x82, 0xCB, 0xEF, 0xF0,
+0x51, 0xAE, 0xA3, 0xE0, 0x04, 0xFD, 0x31, 0xD3,
+0xAC, 0x07, 0x90, 0x82, 0xCB, 0xE0, 0x30, 0xE7,
+0x08, 0x90, 0x82, 0xC9, 0x74, 0x02, 0xF0, 0x80,
+0x05, 0xE4, 0x90, 0x82, 0xC9, 0xF0, 0xEC, 0x30,
+0xE6, 0x34, 0x51, 0xAE, 0x7D, 0x02, 0x31, 0xD3,
+0xEF, 0x54, 0x70, 0xC4, 0x54, 0x0F, 0x90, 0x82,
+0xCC, 0xF0, 0x14, 0x60, 0x11, 0x14, 0x60, 0x16,
+0x24, 0xFE, 0x60, 0x12, 0x14, 0x60, 0x07, 0x14,
+0x60, 0x04, 0x24, 0x06, 0x80, 0x10, 0x90, 0x82,
+0xCA, 0x74, 0x04, 0xF0, 0x80, 0x0D, 0x90, 0x82,
+0xCA, 0x74, 0x08, 0xF0, 0x80, 0x05, 0xE4, 0x90,
+0x82, 0xCA, 0xF0, 0x90, 0x82, 0xC9, 0xE0, 0x24,
+0x18, 0xFF, 0xA3, 0xE0, 0x2F, 0xFF, 0x22, 0x90,
+0x82, 0xC2, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3,
+0xED, 0xF0, 0x31, 0x26, 0x90, 0x82, 0xC5, 0xEF,
+0xF0, 0x90, 0x82, 0xC4, 0xE0, 0xFD, 0x90, 0x82,
+0xC3, 0xE0, 0x2D, 0xFD, 0x90, 0x82, 0xC2, 0xE0,
+0x34, 0x00, 0xFC, 0x7E, 0x00, 0xED, 0x2F, 0xFF,
+0xEE, 0x3C, 0xCF, 0x24, 0x06, 0xCF, 0x34, 0x00,
+0xFE, 0xE4, 0xFD, 0xAB, 0x07, 0xAA, 0x06, 0xED,
+0x2B, 0xFB, 0xE4, 0x3A, 0xFA, 0xC3, 0x90, 0x80,
+0xFB, 0xE0, 0x9B, 0x90, 0x80, 0xFA, 0xE0, 0x9A,
+0x50, 0x0A, 0xA3, 0x12, 0x7D, 0xC8, 0xEB, 0x9F,
+0xFB, 0xEA, 0x9E, 0xFA, 0xEA, 0x90, 0xFD, 0x11,
+0xF0, 0xAF, 0x03, 0x74, 0x00, 0x2F, 0x12, 0x7E,
+0x7A, 0xFF, 0x22, 0x31, 0x9F, 0xEF, 0x64, 0x08,
+0x70, 0x34, 0x51, 0x41, 0x24, 0x07, 0x31, 0xCD,
+0xEF, 0x70, 0x2B, 0x51, 0x41, 0x24, 0x1D, 0x31,
+0xCD, 0xBF, 0x44, 0x0B, 0x51, 0x41, 0x24, 0x1F,
+0x31, 0xCD, 0xEF, 0x64, 0x43, 0x60, 0x14, 0x51,
+0x41, 0x24, 0x1D, 0x31, 0xCD, 0xEF, 0x64, 0x43,
+0x70, 0x0C, 0x51, 0x41, 0x24, 0x1F, 0x31, 0xCD,
+0xBF, 0x44, 0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00,
+0x22, 0x90, 0x82, 0xC4, 0xE0, 0xFF, 0x90, 0x82,
+0xC3, 0xE0, 0x2F, 0xFF, 0x90, 0x82, 0xC2, 0xE0,
+0x34, 0x00, 0xFE, 0x90, 0x82, 0xC5, 0xE0, 0x7C,
+0x00, 0x2F, 0xFF, 0xEC, 0x3E, 0xCF, 0x22, 0x31,
+0x9F, 0xEF, 0x64, 0x08, 0x70, 0x20, 0x51, 0x41,
+0x24, 0x07, 0x31, 0xCD, 0xEF, 0x64, 0x06, 0x70,
+0x15, 0x51, 0x41, 0x24, 0x0E, 0x31, 0xCD, 0xEF,
+0x70, 0x0C, 0x51, 0x41, 0x24, 0x0F, 0x31, 0xCD,
+0xBF, 0x01, 0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00,
+0x22, 0x24, 0x0A, 0xFC, 0xED, 0x2C, 0xFD, 0x31,
+0xD3, 0x90, 0x82, 0x43, 0xA3, 0xE0, 0xFE, 0x90,
+0x82, 0x49, 0xE0, 0x2E, 0x24, 0x24, 0xF5, 0x82,
+0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xEF, 0xF0, 0x90,
+0x82, 0x49, 0xE0, 0x04, 0xF0, 0x22, 0x90, 0x82,
+0xC6, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0x90,
+0x82, 0xC2, 0x51, 0xF7, 0x31, 0xD3, 0xEF, 0x54,
+0x0C, 0x64, 0x08, 0x70, 0x2F, 0x90, 0x82, 0xC5,
+0xF0, 0x90, 0x82, 0xC5, 0xE0, 0xFD, 0xC3, 0x94,
+0x06, 0x50, 0x21, 0x90, 0x82, 0xC2, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0xA3, 0xE0, 0x24, 0x10, 0xFC,
+0xED, 0x2C, 0xFD, 0x31, 0xD3, 0xEF, 0xF4, 0x60,
+0x03, 0x7F, 0x01, 0x22, 0x90, 0x82, 0xC5, 0xE0,
+0x04, 0xF0, 0x80, 0xD5, 0x7F, 0x00, 0x22, 0xEE,
+0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x22,
+0xFD, 0x31, 0xD3, 0x90, 0x82, 0x4A, 0xE0, 0x22,
+0x24, 0x1A, 0xFC, 0xED, 0x2C, 0xFD, 0x31, 0xD3,
+0x90, 0x82, 0x49, 0xE0, 0x24, 0x61, 0xF5, 0x82,
+0xE4, 0x34, 0x82, 0x22, 0x71, 0x38, 0x12, 0x70,
+0x00, 0x12, 0x4D, 0xBF, 0x12, 0x74, 0xF6, 0x71,
+0x8A, 0x12, 0x75, 0xD6, 0x11, 0xFD, 0x12, 0x73,
+0xAE, 0x90, 0x82, 0x1E, 0x74, 0x01, 0xF0, 0x22,
+0xE4, 0xFD, 0xFF, 0x12, 0x6D, 0xE8, 0xFE, 0xEF,
+0x54, 0x07, 0xFF, 0xED, 0x70, 0x14, 0x71, 0x81,
+0xF5, 0x83, 0xC0, 0x83, 0xC0, 0x82, 0x71, 0x79,
+0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5E,
+0x80, 0x11, 0x71, 0x81, 0xF5, 0x83, 0xC0, 0x83,
+0xC0, 0x82, 0x71, 0x79, 0x80, 0x02, 0xC3, 0x33,
+0xD8, 0xFC, 0x4E, 0xD0, 0x82, 0xD0, 0x83, 0xF0,
+0x12, 0x70, 0x72, 0x90, 0x81, 0x2A, 0xEF, 0xF0,
+0x22, 0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x07, 0x08,
+0x22, 0x74, 0x22, 0x2E, 0xF5, 0x82, 0xE4, 0x34,
+0x81, 0x22, 0x90, 0x82, 0x12, 0xE0, 0x54, 0xFE,
+0xF0, 0x54, 0x7F, 0xF0, 0x54, 0xFB, 0xF0, 0xA3,
+0x74, 0x0A, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0,
+0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x90, 0x83, 0x14, 0xEE, 0xF0, 0xA3, 0xEF, 0x71,
+0x9A, 0x90, 0x83, 0x14, 0xE0, 0xFE, 0xA3, 0xE0,
+0xF5, 0x82, 0x8E, 0x83, 0xE0, 0x60, 0x23, 0xC3,
+0x90, 0x83, 0x17, 0xE0, 0x94, 0xE8, 0x90, 0x83,
+0x16, 0xE0, 0x94, 0x03, 0x40, 0x0B, 0x90, 0x01,
+0xC0, 0xE0, 0x44, 0x80, 0xF0, 0x7F, 0x00, 0x80,
+0x0B, 0x90, 0x83, 0x16, 0x91, 0x3A, 0xF1, 0x20,
+0x80, 0xCF, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x90, 0x82, 0x3B, 0xEF, 0x71, 0x9A, 0x90,
+0x01, 0x09, 0xE0, 0x7F, 0x00, 0x30, 0xE7, 0x02,
+0x7F, 0x01, 0x90, 0x82, 0x3B, 0xE0, 0x6F, 0x60,
+0x35, 0xC3, 0x90, 0x82, 0x3D, 0xE0, 0x94, 0x88,
+0x90, 0x82, 0x3C, 0xE0, 0x94, 0x13, 0x40, 0x08,
+0x90, 0x01, 0xC0, 0xE0, 0x44, 0x10, 0xF0, 0x22,
+0x90, 0x82, 0x3C, 0x91, 0x3A, 0x12, 0x60, 0xBC,
+0xD3, 0x90, 0x82, 0x3D, 0xE0, 0x94, 0x32, 0x90,
+0x82, 0x3C, 0xE0, 0x94, 0x00, 0x40, 0xC0, 0x90,
+0x01, 0xC6, 0xE0, 0x30, 0xE0, 0xB9, 0x22, 0x90,
+0x82, 0xC0, 0xE4, 0x75, 0xF0, 0x01, 0x02, 0x46,
+0x9F, 0xE4, 0xFD, 0xFB, 0xFA, 0xF1, 0x19, 0x30,
+0xE0, 0x73, 0x90, 0x00, 0xB6, 0xE0, 0xFC, 0x90,
+0x00, 0xBF, 0xE0, 0xFE, 0x90, 0x00, 0xBE, 0xE0,
+0x24, 0x00, 0xFB, 0xEA, 0x3E, 0xFA, 0xC4, 0xF8,
+0x54, 0xF0, 0xC8, 0xEB, 0xC4, 0x54, 0x0F, 0x48,
+0x54, 0x1E, 0xFF, 0xEC, 0xC4, 0x54, 0x01, 0x4F,
+0x90, 0x82, 0x25, 0xF0, 0xF1, 0xEB, 0xEC, 0x30,
+0xE4, 0x0A, 0x90, 0x81, 0x14, 0xE0, 0xFD, 0x12,
+0x6F, 0x0A, 0x80, 0x35, 0xEB, 0x30, 0xE5, 0x09,
+0x90, 0x81, 0x15, 0xB1, 0x0A, 0x04, 0xF0, 0x80,
+0x28, 0xEB, 0x30, 0xE6, 0x0A, 0x90, 0x81, 0x16,
+0xB1, 0x0A, 0x74, 0x02, 0xF0, 0x80, 0x1A, 0xEB,
+0x30, 0xE7, 0x0A, 0x90, 0x81, 0x17, 0xB1, 0x0A,
+0x74, 0x03, 0xF0, 0x80, 0x0C, 0xEA, 0x30, 0xE0,
+0x08, 0x90, 0x81, 0x18, 0xB1, 0x0A, 0x74, 0x04,
+0xF0, 0xAF, 0x05, 0x80, 0x56, 0x90, 0x81, 0x07,
+0xE0, 0xFD, 0x7C, 0x00, 0xA3, 0xE0, 0xFE, 0xA3,
+0xE0, 0xFF, 0x12, 0x20, 0x30, 0xED, 0x4C, 0x70,
+0x05, 0x90, 0x81, 0x14, 0x80, 0x2A, 0xED, 0x64,
+0x01, 0x4C, 0x70, 0x05, 0x90, 0x81, 0x15, 0x80,
+0x1F, 0xED, 0x64, 0x02, 0x4C, 0x70, 0x05, 0x90,
+0x81, 0x16, 0x80, 0x14, 0xED, 0x64, 0x03, 0x4C,
+0x70, 0x05, 0x90, 0x81, 0x17, 0x80, 0x09, 0xED,
+0x64, 0x04, 0x4C, 0x70, 0x0C, 0x90, 0x81, 0x18,
+0xE0, 0xFF, 0xB1, 0x13, 0x90, 0x81, 0x08, 0x91,
+0x3A, 0x22, 0xE0, 0xFD, 0x90, 0x81, 0x08, 0xE4,
+0xF0, 0xA3, 0x22, 0x90, 0x04, 0x24, 0xEF, 0xF0,
+0x22, 0x12, 0x73, 0x2B, 0x90, 0x81, 0x3B, 0xE0,
+0x20, 0xE0, 0x0C, 0x90, 0x00, 0x26, 0xE0, 0x54,
+0x7F, 0xFD, 0x7F, 0x26, 0x12, 0x32, 0x1E, 0x90,
+0x00, 0x08, 0xE0, 0x54, 0xEF, 0xFD, 0x7F, 0x08,
+0x12, 0x32, 0x1E, 0xE4, 0xFF, 0x61, 0xE9, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x73,
+0x48, 0xB1, 0x19, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x90, 0x81, 0x33, 0xE0, 0xFF, 0x60, 0x03, 0xB4,
+0x08, 0x0E, 0x12, 0x74, 0x71, 0xBF, 0x01, 0x08,
+0xB1, 0x3F, 0x90, 0x01, 0xE5, 0xE0, 0x04, 0xF0,
+0x22, 0xE4, 0x90, 0x83, 0x2D, 0xF0, 0xA3, 0xF0,
+0x90, 0x02, 0x86, 0xE0, 0x20, 0xE1, 0x22, 0xC3,
+0x90, 0x83, 0x2E, 0xE0, 0x94, 0xD0, 0x90, 0x83,
+0x2D, 0xE0, 0x94, 0x07, 0x40, 0x0A, 0x90, 0x01,
+0xC1, 0xE0, 0x44, 0x04, 0xF0, 0x7F, 0x00, 0x22,
+0x90, 0x83, 0x2D, 0x91, 0x3A, 0xF1, 0x20, 0x80,
+0xD7, 0x7F, 0x01, 0x22, 0x90, 0x01, 0x17, 0xE0,
+0xFE, 0x90, 0x01, 0x16, 0x12, 0x7E, 0x83, 0x90,
+0x80, 0xFA, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x02,
+0x86, 0xE0, 0x44, 0x04, 0xF1, 0xE2, 0x30, 0xE0,
+0x2B, 0x90, 0x01, 0xC7, 0xE4, 0xF0, 0xB1, 0x69,
+0x90, 0x80, 0xFC, 0xE0, 0xBF, 0x01, 0x05, 0x54,
+0xEF, 0xF0, 0x80, 0x03, 0x44, 0x10, 0xF0, 0x90,
+0x80, 0xFF, 0xE0, 0xFF, 0x60, 0x0E, 0xE4, 0xF5,
+0x1D, 0x8F, 0x1E, 0xFB, 0xFD, 0x7F, 0x5C, 0x7E,
+0x01, 0x12, 0x4C, 0x3C, 0x90, 0x80, 0xFC, 0xE0,
+0x44, 0x01, 0xF0, 0x7D, 0x08, 0xE4, 0xFF, 0x12,
+0x50, 0xE6, 0x90, 0x05, 0x52, 0xE0, 0x54, 0x07,
+0x04, 0x90, 0x81, 0x07, 0x71, 0x9A, 0x90, 0x04,
+0x22, 0xE0, 0x54, 0xEF, 0xF0, 0xF1, 0x19, 0x30,
+0xE0, 0x02, 0xF1, 0xEB, 0x22, 0x12, 0x67, 0xC8,
+0xFC, 0x54, 0x02, 0xFE, 0x90, 0x80, 0xFC, 0xE0,
+0x54, 0xFD, 0x4E, 0xF0, 0xE0, 0xFF, 0xC3, 0x13,
+0x30, 0xE0, 0x08, 0xF1, 0x13, 0xF1, 0x75, 0x90,
+0x80, 0xFF, 0xF0, 0xEC, 0x30, 0xE0, 0x18, 0xB1,
+0x9C, 0x90, 0x01, 0xC7, 0xE4, 0xF0, 0x90, 0x80,
+0x07, 0xE0, 0x64, 0x01, 0x70, 0x2E, 0x90, 0xFE,
+0x10, 0xE0, 0x44, 0x04, 0xF0, 0x80, 0x25, 0x12,
+0x54, 0x8E, 0x90, 0x01, 0x3C, 0xE0, 0x30, 0xE4,
+0x03, 0x74, 0x10, 0xF0, 0x90, 0x01, 0x63, 0xE4,
+0xF0, 0x12, 0x6E, 0xD6, 0xF1, 0x19, 0x30, 0xE0,
+0x0B, 0x90, 0x02, 0x86, 0xE0, 0x30, 0xE2, 0x04,
+0xE0, 0x54, 0xFB, 0xF0, 0x90, 0x82, 0x43, 0xF1,
+0x27, 0x90, 0x80, 0xFD, 0xF1, 0xD3, 0x90, 0x80,
+0xFE, 0xF1, 0xE2, 0x30, 0xE0, 0x2A, 0xF1, 0x13,
+0x12, 0x7E, 0x61, 0x90, 0x80, 0xFC, 0x12, 0x6F,
+0xD7, 0x4E, 0x12, 0x65, 0xFA, 0x90, 0x81, 0x00,
+0xF0, 0x70, 0x03, 0x74, 0x14, 0xF0, 0xF1, 0x13,
+0x90, 0x00, 0x05, 0x12, 0x1F, 0xBD, 0x90, 0x81,
+0x01, 0x12, 0x67, 0xA1, 0x90, 0x81, 0x02, 0xF0,
+0x90, 0x80, 0xFD, 0xE0, 0x54, 0x01, 0x90, 0x81,
+0x0A, 0xF0, 0x90, 0x80, 0xFD, 0xE0, 0x54, 0x02,
+0x90, 0x81, 0x0B, 0xF0, 0x90, 0x80, 0xFD, 0xE0,
+0x54, 0x04, 0x90, 0x81, 0x0C, 0xF0, 0x90, 0x80,
+0xFD, 0xE0, 0x54, 0x08, 0x90, 0x81, 0x0D, 0xF0,
+0x90, 0x80, 0xFD, 0xE0, 0x54, 0x10, 0x90, 0x81,
+0x0E, 0xF0, 0x90, 0x80, 0xFE, 0xE0, 0x54, 0x01,
+0x90, 0x81, 0x0F, 0xF0, 0x90, 0x80, 0xFE, 0xE0,
+0x54, 0x02, 0x90, 0x81, 0x10, 0xF0, 0x90, 0x80,
+0xFE, 0xE0, 0x54, 0x04, 0x90, 0x81, 0x11, 0xF0,
+0x90, 0x80, 0xFE, 0xE0, 0x54, 0x08, 0x90, 0x81,
+0x12, 0xF0, 0x90, 0x80, 0xFE, 0xE0, 0x54, 0x10,
+0x90, 0x81, 0x13, 0xF0, 0x22, 0x90, 0x82, 0x43,
+0x12, 0x46, 0xF4, 0x90, 0x82, 0x43, 0x02, 0x46,
+0xEB, 0x90, 0x80, 0xFC, 0xE0, 0xC3, 0x13, 0x22,
+0x7F, 0x0A, 0x7E, 0x00, 0x02, 0x32, 0xAA, 0x12,
+0x46, 0xEB, 0x90, 0x00, 0x01, 0x02, 0x1F, 0xBD,
+0x90, 0x82, 0x43, 0x12, 0x46, 0xF4, 0x12, 0x75,
+0xD6, 0xF1, 0x13, 0x12, 0x67, 0xB8, 0xF1, 0x7B,
+0x4E, 0xF0, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x2B,
+0xF1, 0x2A, 0x90, 0x82, 0x17, 0xF1, 0xD3, 0x90,
+0x82, 0x18, 0xF0, 0x12, 0x1F, 0xA4, 0xFF, 0x54,
+0x04, 0xFE, 0x90, 0x82, 0x16, 0xE0, 0x54, 0xFB,
+0x4E, 0xF1, 0x74, 0x90, 0x82, 0x19, 0xF0, 0xEF,
+0x54, 0x08, 0xFF, 0x90, 0x82, 0x16, 0xE0, 0x54,
+0xF7, 0x4F, 0xF0, 0x22, 0xF0, 0x90, 0x00, 0x03,
+0x02, 0x1F, 0xBD, 0x90, 0x82, 0x16, 0xE0, 0x54,
+0xFE, 0x22, 0x90, 0x82, 0x16, 0xE0, 0xFD, 0x30,
+0xE0, 0x47, 0x90, 0x82, 0x1B, 0xE0, 0xFC, 0x60,
+0x40, 0x12, 0x70, 0xD0, 0x80, 0x05, 0xC3, 0x33,
+0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x04,
+0xE0, 0xE0, 0xFB, 0xEF, 0x5B, 0x60, 0x0B, 0xE4,
+0x90, 0x82, 0x1B, 0xF0, 0x90, 0x82, 0x1D, 0x04,
+0xF0, 0x22, 0x90, 0x82, 0x18, 0xE0, 0xD3, 0x9C,
+0x50, 0x14, 0xED, 0x13, 0x13, 0x13, 0x54, 0x1F,
+0x30, 0xE0, 0x04, 0xF1, 0xDA, 0x80, 0x03, 0x12,
+0x6E, 0x68, 0xF1, 0x7B, 0xF0, 0x22, 0x12, 0x7E,
+0x39, 0x22, 0x4F, 0xF0, 0x90, 0x00, 0x02, 0x02,
+0x1F, 0xBD, 0xE4, 0xFD, 0xFF, 0x71, 0x3B, 0xE4,
+0xFF, 0x22, 0xF0, 0x90, 0x80, 0xFC, 0xE0, 0xFF,
+0xC3, 0x13, 0x22, 0x90, 0x00, 0xB6, 0x74, 0x10,
+0xF0, 0x90, 0x00, 0xBE, 0x74, 0xE0, 0xF0, 0xA3,
+0x74, 0x01, 0xF0, 0x22, 0x75, 0xE8, 0x03, 0x75,
+0xA8, 0x84, 0x22, 0x90, 0x00, 0x80, 0xE0, 0x44,
+0x80, 0xFD, 0x7F, 0x80, 0x12, 0x32, 0x1E, 0x90,
+0xFD, 0x00, 0xE0, 0x54, 0xBF, 0xF0, 0x11, 0xCD,
+0x12, 0x32, 0x77, 0x11, 0xDA, 0x11, 0xB5, 0x7F,
+0x01, 0x12, 0x44, 0x15, 0x90, 0x82, 0x11, 0x74,
+0x02, 0xF0, 0xFF, 0x12, 0x44, 0x15, 0x90, 0x82,
+0x11, 0xE0, 0x04, 0xF0, 0x12, 0x58, 0x45, 0x12,
+0x5B, 0x1C, 0x90, 0x01, 0xCC, 0x74, 0x0F, 0xF0,
+0x90, 0x00, 0x80, 0xE0, 0x44, 0x40, 0xFD, 0x7F,
+0x80, 0x12, 0x32, 0x1E, 0x75, 0x20, 0xFF, 0x12,
+0x5F, 0xFC, 0x11, 0x5B, 0x11, 0xC3, 0xE4, 0xFF,
+0x02, 0x44, 0x9E, 0xE4, 0x90, 0x82, 0x36, 0xF0,
+0xA3, 0xF0, 0x90, 0x01, 0x98, 0xE0, 0x7F, 0x00,
+0x30, 0xE4, 0x02, 0x7F, 0x01, 0xEF, 0x64, 0x01,
+0x60, 0x3C, 0xC3, 0x90, 0x82, 0x37, 0xE0, 0x94,
+0x88, 0x90, 0x82, 0x36, 0xE0, 0x94, 0x13, 0x40,
+0x0F, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x10, 0xF0,
+0x90, 0x01, 0xC7, 0x74, 0xFD, 0xF0, 0x80, 0x1E,
+0x90, 0x82, 0x36, 0x12, 0x5C, 0x3A, 0x11, 0xBC,
+0xD3, 0x90, 0x82, 0x37, 0xE0, 0x94, 0x32, 0x90,
+0x82, 0x36, 0xE0, 0x94, 0x00, 0x40, 0xBB, 0x90,
+0x01, 0xC6, 0xE0, 0x30, 0xE3, 0xB4, 0x90, 0x01,
+0xC7, 0x74, 0xFE, 0xF0, 0x22, 0xE4, 0x90, 0x80,
+0x01, 0x02, 0x58, 0xCC, 0x7F, 0x14, 0x7E, 0x00,
+0x02, 0x32, 0xAA, 0x90, 0x01, 0xE4, 0x74, 0x1C,
+0xF0, 0xA3, 0xE4, 0xF0, 0x22, 0x90, 0x01, 0x94,
+0xE0, 0x44, 0x01, 0xF0, 0x90, 0x01, 0xC7, 0xE4,
+0xF0, 0x22, 0x90, 0x01, 0x01, 0xE0, 0x44, 0x04,
+0xF0, 0x90, 0x01, 0x9C, 0x74, 0x7E, 0xF0, 0xA3,
+0x74, 0x92, 0xF0, 0xA3, 0x74, 0xA0, 0xF0, 0xA3,
+0x74, 0x24, 0xF0, 0x90, 0x01, 0x9B, 0x74, 0x49,
+0xF0, 0x90, 0x01, 0x9A, 0x74, 0xE0, 0xF0, 0x90,
+0x01, 0x99, 0xE4, 0xF0, 0x90, 0x01, 0x98, 0x04,
+0xF0, 0x22, 0xE4, 0x90, 0x82, 0x38, 0xF0, 0xA3,
+0xF0, 0xA3, 0xF0, 0x90, 0x82, 0x38, 0xE0, 0x64,
+0x01, 0xF0, 0x24, 0x0A, 0x90, 0x01, 0xC4, 0xF0,
+0x74, 0x61, 0xA3, 0xF0, 0x90, 0x81, 0x30, 0xE0,
+0x60, 0x0E, 0x90, 0x81, 0x33, 0xE0, 0xFF, 0x90,
+0x81, 0x32, 0xE0, 0x6F, 0x60, 0x02, 0x31, 0x4C,
+0xC2, 0xAF, 0x12, 0x71, 0x16, 0xBF, 0x01, 0x02,
+0xF1, 0xE4, 0xD2, 0xAF, 0x31, 0x4B, 0x12, 0x43,
+0x4D, 0x80, 0xC8, 0x22, 0x90, 0x81, 0x32, 0xE0,
+0xFF, 0x7D, 0x01, 0x02, 0x51, 0x51, 0xE4, 0xFF,
+0x12, 0x53, 0x4B, 0xBF, 0x01, 0x0E, 0x90, 0x81,
+0x30, 0xE0, 0x60, 0x08, 0x31, 0x6D, 0x54, 0x07,
+0x70, 0x02, 0x31, 0x4C, 0x22, 0x90, 0x81, 0x34,
+0xE0, 0x54, 0xFE, 0xF0, 0x22, 0x90, 0x06, 0xA9,
+0xE0, 0xF5, 0x4E, 0x54, 0xC0, 0x70, 0x07, 0x31,
+0x6D, 0x54, 0xFD, 0xF0, 0x80, 0xC6, 0xE5, 0x4E,
+0x30, 0xE6, 0x1C, 0x90, 0x81, 0x30, 0xE0, 0x64,
+0x01, 0x70, 0x16, 0x90, 0x81, 0x34, 0xE0, 0x44,
+0x01, 0x51, 0x5E, 0x64, 0x02, 0x60, 0x04, 0x51,
+0x34, 0x80, 0x06, 0x31, 0xC4, 0x80, 0x02, 0x31,
+0x6D, 0xE5, 0x4E, 0x90, 0x81, 0x34, 0x30, 0xE7,
+0x0E, 0xE0, 0x44, 0x02, 0x12, 0x4C, 0x2B, 0x90,
+0x81, 0x2B, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0xE0,
+0x54, 0xFD, 0xF0, 0x22, 0x31, 0xEF, 0x90, 0x81,
+0x33, 0xE0, 0x64, 0x0C, 0x60, 0x08, 0x51, 0x83,
+0x12, 0x4E, 0x92, 0x12, 0x56, 0x07, 0x22, 0x90,
+0x81, 0x30, 0xE0, 0x60, 0x0F, 0x90, 0x06, 0x92,
+0xE0, 0x30, 0xE1, 0x04, 0x31, 0xEF, 0x80, 0x04,
+0xF1, 0x98, 0x31, 0x4C, 0x02, 0x4C, 0x08, 0xF1,
+0xDA, 0x30, 0xE0, 0x05, 0x90, 0x01, 0x5B, 0xE4,
+0xF0, 0x90, 0x06, 0x92, 0x74, 0x02, 0xF0, 0x90,
+0x01, 0x3C, 0x74, 0x04, 0xF0, 0xE4, 0xF5, 0x1D,
+0x90, 0x82, 0x04, 0xE0, 0xC3, 0x13, 0x54, 0x7F,
+0x12, 0x4B, 0xCA, 0x90, 0x81, 0x2B, 0xE0, 0x44,
+0x08, 0xF0, 0x22, 0xE4, 0xFF, 0x12, 0x53, 0x4B,
+0xBF, 0x01, 0x10, 0x90, 0x81, 0x30, 0xE0, 0x60,
+0x0A, 0x51, 0x5F, 0x64, 0x02, 0x60, 0x02, 0x80,
+0x03, 0x31, 0xC4, 0x22, 0x90, 0x04, 0x1D, 0xE0,
+0x70, 0x1C, 0x90, 0x80, 0x0A, 0xE0, 0xFF, 0x90,
+0x83, 0x1B, 0x74, 0x09, 0xF0, 0x7B, 0x18, 0xE4,
+0xFD, 0x12, 0x57, 0x19, 0x90, 0x82, 0x25, 0xEE,
+0xF0, 0xA3, 0xEF, 0xF0, 0x51, 0x57, 0x22, 0x90,
+0x04, 0x1F, 0x74, 0x20, 0xF0, 0x22, 0xF0, 0x90,
+0x81, 0x2E, 0xE0, 0x54, 0x0F, 0x22, 0x90, 0x81,
+0x30, 0xE0, 0x64, 0x01, 0x70, 0x14, 0x51, 0x5F,
+0x60, 0x07, 0x51, 0x83, 0x12, 0x4E, 0x92, 0x21,
+0xEF, 0x90, 0x81, 0x33, 0xE0, 0x70, 0x03, 0x12,
+0x51, 0x4D, 0x22, 0xE4, 0xFD, 0x7F, 0x0C, 0x02,
+0x51, 0x51, 0x12, 0x4F, 0xC8, 0x70, 0x1C, 0x90,
+0x81, 0x30, 0xE0, 0x60, 0x16, 0x90, 0x81, 0x34,
+0xE0, 0x20, 0xE4, 0x0F, 0x12, 0x7D, 0xFD, 0xF0,
+0x90, 0x81, 0x2B, 0xE0, 0x12, 0x7E, 0x47, 0x70,
+0x02, 0x31, 0x4C, 0x22, 0x90, 0x81, 0x2B, 0xE0,
+0xFF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, 0xE0,
+0x18, 0xEF, 0x54, 0xBF, 0x71, 0x01, 0x30, 0xE0,
+0x06, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x08, 0xE0,
+0x54, 0xFE, 0x71, 0x0A, 0x74, 0x04, 0xF0, 0x31,
+0x4C, 0xE4, 0xFF, 0x02, 0x5F, 0x82, 0x90, 0x81,
+0x2B, 0x12, 0x4F, 0xEE, 0x30, 0xE0, 0x1D, 0xEF,
+0x54, 0x7F, 0x71, 0x01, 0x30, 0xE1, 0x06, 0xE0,
+0x44, 0x02, 0xF0, 0x80, 0x07, 0xE0, 0x54, 0xFD,
+0x71, 0x0A, 0x04, 0xF0, 0x90, 0x81, 0x30, 0xE0,
+0x60, 0x02, 0x31, 0x4C, 0x7F, 0x01, 0x02, 0x5F,
+0x82, 0xF0, 0x90, 0x04, 0xE0, 0xE0, 0x90, 0x81,
+0x2C, 0x22, 0xF0, 0x90, 0x01, 0xB9, 0x74, 0x01,
+0xF0, 0x90, 0x01, 0xB8, 0x22, 0xF1, 0xC8, 0xFF,
+0x54, 0x7F, 0x90, 0x81, 0x30, 0xF0, 0xEF, 0x12,
+0x4F, 0xF0, 0xA3, 0xF0, 0x12, 0x5F, 0x2A, 0xFD,
+0x54, 0xF0, 0xC4, 0x54, 0x0F, 0xFF, 0x90, 0x81,
+0x2E, 0xE0, 0x54, 0xF0, 0x4F, 0x12, 0x5F, 0x74,
+0xFC, 0x54, 0x01, 0x25, 0xE0, 0xFF, 0x90, 0x81,
+0x2B, 0xE0, 0x54, 0xFD, 0x4F, 0xF0, 0xEC, 0x54,
+0x04, 0xC3, 0x13, 0xFF, 0x90, 0x81, 0x2D, 0xE0,
+0x54, 0xFD, 0x4F, 0xF0, 0xED, 0x54, 0x0F, 0xC4,
+0x54, 0xF0, 0xFF, 0xA3, 0xE0, 0x54, 0x0F, 0x12,
+0x5F, 0xD2, 0x90, 0x81, 0x2F, 0xB1, 0xFA, 0xFD,
+0x7F, 0x02, 0x12, 0x4D, 0x57, 0x12, 0x5F, 0x13,
+0x12, 0x55, 0x4C, 0x71, 0x0B, 0xF0, 0x90, 0x81,
+0x30, 0x12, 0x7E, 0x54, 0x51, 0x5E, 0x90, 0x01,
+0xBE, 0xF0, 0x22, 0x90, 0x82, 0x40, 0x12, 0x46,
+0xF4, 0x90, 0x82, 0x3F, 0xEF, 0xF0, 0x12, 0x46,
+0xFD, 0x63, 0xC2, 0x00, 0x63, 0xC6, 0x01, 0x63,
+0xCA, 0x03, 0x63, 0xCE, 0x04, 0x63, 0xD3, 0x08,
+0x63, 0xD8, 0x09, 0x63, 0xDC, 0x0A, 0x63, 0xE0,
+0x12, 0x63, 0xE4, 0x13, 0x63, 0xE9, 0x14, 0x63,
+0xEE, 0x20, 0x63, 0xF2, 0x25, 0x63, 0xF6, 0x26,
+0x63, 0xFB, 0xC2, 0x63, 0xFF, 0xC4, 0x00, 0x00,
+0x64, 0x04, 0x91, 0x14, 0xA1, 0xB7, 0x91, 0x14,
+0xE1, 0x30, 0x91, 0x14, 0xA1, 0x98, 0x91, 0x14,
+0x02, 0x5F, 0x30, 0x91, 0x14, 0x02, 0x5E, 0x0D,
+0x91, 0x14, 0x80, 0x3E, 0x91, 0x14, 0x80, 0x46,
+0x91, 0x14, 0x80, 0x5A, 0x91, 0x14, 0x02, 0x6A,
+0xD4, 0x91, 0x14, 0x02, 0x6B, 0x4E, 0x91, 0x14,
+0x61, 0x15, 0x91, 0x14, 0xE1, 0xA8, 0x91, 0x14,
+0x02, 0x6B, 0x5D, 0x91, 0x14, 0xE1, 0xB0, 0x91,
+0x14, 0x02, 0x6F, 0xEB, 0x90, 0x01, 0xC0, 0xE0,
+0x44, 0x01, 0xF0, 0x90, 0x82, 0x3F, 0xE0, 0x90,
+0x01, 0xC2, 0xF0, 0x22, 0x90, 0x82, 0x40, 0x02,
+0x46, 0xEB, 0x12, 0x5F, 0x0D, 0x91, 0x32, 0x7A,
+0x81, 0x79, 0x14, 0x02, 0x2B, 0xED, 0x12, 0x5F,
+0x0D, 0x91, 0x32, 0x7A, 0x81, 0x79, 0x19, 0x02,
+0x2B, 0xED, 0x8B, 0x13, 0x8A, 0x14, 0x89, 0x15,
+0x75, 0x16, 0x05, 0x7B, 0x01, 0x22, 0x12, 0x1F,
+0xA4, 0xFF, 0x90, 0x81, 0x21, 0xF0, 0xBF, 0x01,
+0x07, 0x91, 0x51, 0xE4, 0x90, 0x81, 0x21, 0xF0,
+0x22, 0xB1, 0x18, 0x7F, 0xF5, 0x7E, 0x00, 0x12,
+0x2B, 0x27, 0xBF, 0x01, 0x06, 0x90, 0x82, 0x43,
+0xE0, 0xA3, 0xF0, 0xB1, 0x18, 0x7F, 0xF6, 0x7E,
+0x00, 0x12, 0x2B, 0x27, 0xBF, 0x01, 0x08, 0x90,
+0x82, 0x43, 0xE0, 0x90, 0x82, 0x45, 0xF0, 0xB1,
+0x18, 0x7F, 0xF4, 0x7E, 0x00, 0x12, 0x2B, 0x27,
+0xBF, 0x01, 0x08, 0x90, 0x82, 0x43, 0xE0, 0x90,
+0x82, 0x46, 0xF0, 0xB1, 0x18, 0x7F, 0xF3, 0x7E,
+0x00, 0x12, 0x2B, 0x27, 0xBF, 0x01, 0x08, 0x90,
+0x82, 0x43, 0xE0, 0x90, 0x82, 0x47, 0xF0, 0xB1,
+0x18, 0x7F, 0xF2, 0x7E, 0x00, 0x12, 0x2B, 0x27,
+0xBF, 0x01, 0x08, 0x90, 0x82, 0x43, 0xE0, 0x90,
+0x82, 0x48, 0xF0, 0x90, 0x82, 0x44, 0xE0, 0xFF,
+0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFB, 0xA3, 0xE0,
+0x90, 0x82, 0x4C, 0xF0, 0x90, 0x82, 0x48, 0xE0,
+0x90, 0x82, 0x4D, 0xF0, 0x90, 0x82, 0x4E, 0x74,
+0x12, 0xF0, 0x90, 0x82, 0x5C, 0x74, 0x05, 0xF0,
+0x90, 0x82, 0x50, 0xEF, 0xF0, 0xA3, 0xED, 0xF0,
+0xA3, 0xEB, 0xF0, 0x90, 0x82, 0x4C, 0xE0, 0x90,
+0x82, 0x53, 0xF0, 0x90, 0x82, 0x4D, 0xE0, 0x90,
+0x82, 0x54, 0xF0, 0x7B, 0x01, 0x7A, 0x82, 0x79,
+0x4E, 0xB1, 0x3B, 0x7F, 0x04, 0x90, 0x83, 0x2F,
+0xEF, 0xF0, 0x7F, 0x02, 0x12, 0x45, 0x27, 0x90,
+0x80, 0x01, 0xE0, 0xFF, 0x90, 0x83, 0x2F, 0xE0,
+0xFE, 0xEF, 0x4E, 0x90, 0x80, 0x01, 0xF0, 0x22,
+0x7B, 0x01, 0x7A, 0x82, 0x79, 0x43, 0x22, 0xE4,
+0x90, 0x82, 0x29, 0xF0, 0x90, 0x82, 0x27, 0x74,
+0x14, 0xF0, 0x90, 0x82, 0x35, 0x74, 0x01, 0xF0,
+0xFB, 0x7A, 0x82, 0x79, 0x27, 0xB1, 0x3B, 0x7F,
+0x04, 0x80, 0xC2, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x80, 0xF8, 0xE0, 0xFF, 0x70,
+0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF,
+0x14, 0xFF, 0x90, 0x80, 0xF9, 0xE0, 0xB5, 0x07,
+0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF,
+0x60, 0x09, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x02,
+0xF0, 0x80, 0x28, 0xC0, 0x01, 0x90, 0x80, 0xF9,
+0xE0, 0xF1, 0x24, 0xA8, 0x01, 0xFC, 0x7D, 0x01,
+0xD0, 0x01, 0x7E, 0x00, 0x7F, 0x0F, 0x12, 0x46,
+0x79, 0x90, 0x80, 0xF9, 0xD1, 0x61, 0xB4, 0x0A,
+0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90,
+0x80, 0xF9, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0xF1, 0xB8, 0x90, 0x82, 0x12, 0xF1, 0xC0, 0x54,
+0x04, 0xFF, 0xEE, 0x54, 0xFB, 0x4F, 0xF0, 0x12,
+0x1F, 0xA4, 0xC3, 0x13, 0x30, 0xE0, 0x07, 0x12,
+0x5F, 0x2A, 0x90, 0x82, 0x13, 0xF0, 0x22, 0x90,
+0x02, 0x09, 0xE0, 0xF5, 0x55, 0x12, 0x1F, 0xA4,
+0x25, 0x55, 0x90, 0x80, 0x09, 0xF0, 0x12, 0x5F,
+0x2A, 0x25, 0x55, 0x90, 0x80, 0x0A, 0x12, 0x5F,
+0xD3, 0x25, 0x55, 0x90, 0x80, 0x0B, 0x12, 0x5F,
+0x74, 0x25, 0x55, 0x90, 0x80, 0x0C, 0xB1, 0xFA,
+0x25, 0x55, 0x90, 0x80, 0x0D, 0xF0, 0x90, 0x00,
+0x05, 0x12, 0x1F, 0xBD, 0x25, 0x55, 0x90, 0x80,
+0x0E, 0xF1, 0xA1, 0x25, 0x55, 0x90, 0x80, 0x0F,
+0xF0, 0x22, 0xF0, 0x90, 0x00, 0x04, 0x02, 0x1F,
+0xBD, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x90, 0x80, 0x61, 0xE0, 0xFF, 0x90, 0x80, 0x60,
+0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02,
+0x7F, 0x00, 0xEF, 0x70, 0x3F, 0x90, 0x80, 0x60,
+0xE0, 0xFE, 0x75, 0xF0, 0x08, 0x90, 0x80, 0x10,
+0x12, 0x46, 0xDF, 0xE0, 0xFD, 0xEE, 0x75, 0xF0,
+0x08, 0xA4, 0x24, 0x11, 0xF9, 0x74, 0x80, 0x35,
+0xF0, 0xFA, 0x7B, 0x01, 0xAF, 0x05, 0x71, 0x83,
+0x90, 0x80, 0x60, 0xD1, 0x61, 0xB4, 0x0A, 0x02,
+0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x80,
+0x60, 0xF0, 0x12, 0x49, 0x44, 0x90, 0x80, 0x01,
+0xE0, 0x44, 0x02, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0xE0, 0x04, 0xF0, 0xE0, 0x7F, 0x00, 0x22,
+0xE4, 0xFB, 0xFA, 0xFD, 0x7F, 0x01, 0x12, 0x45,
+0x4E, 0x90, 0x82, 0x3E, 0xEF, 0xF0, 0x60, 0xF0,
+0x90, 0x80, 0x01, 0xE0, 0xFF, 0x70, 0x04, 0xA3,
+0xE0, 0x60, 0xE5, 0xC2, 0xAF, 0xEF, 0x30, 0xE1,
+0x09, 0x90, 0x80, 0x01, 0xE0, 0x54, 0xFD, 0xF0,
+0xD1, 0x01, 0xD1, 0xB3, 0xFF, 0x30, 0xE2, 0x05,
+0x54, 0xFB, 0xF0, 0xD1, 0xBC, 0xD1, 0xB3, 0xFF,
+0x30, 0xE5, 0x0C, 0x54, 0xDF, 0xF0, 0x12, 0x5D,
+0x69, 0xBF, 0x01, 0x03, 0x12, 0x76, 0x55, 0xD2,
+0xAF, 0x80, 0xC5, 0xD2, 0xAF, 0xC2, 0xAF, 0x90,
+0x80, 0x01, 0xE0, 0x22, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0xE4, 0xFF, 0x90, 0x80, 0xF9,
+0xE0, 0xFE, 0x90, 0x80, 0xF8, 0xE0, 0xFD, 0xB5,
+0x06, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00,
+0xEE, 0x64, 0x01, 0x60, 0x42, 0x90, 0x01, 0xAF,
+0xE0, 0x70, 0x0B, 0xED, 0xF1, 0x24, 0xFA, 0x7B,
+0x01, 0x12, 0x70, 0x0E, 0x7F, 0x01, 0xEF, 0x60,
+0x2E, 0x90, 0x80, 0xF8, 0xD1, 0x61, 0xB4, 0x0A,
+0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90,
+0x80, 0xF8, 0xF0, 0x90, 0x80, 0xF9, 0xE0, 0xFF,
+0x90, 0x80, 0xF8, 0xE0, 0xB5, 0x07, 0x04, 0x7F,
+0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70, 0x07,
+0x90, 0x80, 0x01, 0xE0, 0x44, 0x04, 0xF0, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x75, 0xF0, 0x0F, 0xA4,
+0x24, 0x62, 0xF9, 0x74, 0x80, 0x35, 0xF0, 0x22,
+0x8B, 0x55, 0x8A, 0x56, 0x89, 0x57, 0x12, 0x5F,
+0x2A, 0xFF, 0xF5, 0x59, 0x12, 0x1F, 0xA4, 0xFE,
+0xC3, 0x13, 0x30, 0xE0, 0x07, 0x12, 0x5F, 0xD4,
+0xF5, 0x5A, 0x80, 0x02, 0x8F, 0x5A, 0x85, 0x59,
+0x58, 0xE5, 0x58, 0xD3, 0x95, 0x5A, 0x50, 0x26,
+0xAB, 0x55, 0xAA, 0x56, 0xA9, 0x57, 0x12, 0x1F,
+0xA4, 0x54, 0x01, 0xFD, 0xAF, 0x58, 0x12, 0x5B,
+0x3B, 0xAF, 0x58, 0x12, 0x53, 0x4B, 0xEF, 0xAF,
+0x58, 0x70, 0x05, 0x12, 0x5F, 0xE1, 0x80, 0x02,
+0xF1, 0xA0, 0x05, 0x58, 0x80, 0xD3, 0xE5, 0x59,
+0x70, 0x15, 0xFF, 0x12, 0x53, 0x4B, 0xEF, 0x70,
+0x0E, 0x12, 0x4E, 0xED, 0x12, 0x4F, 0x77, 0xF1,
+0x98, 0x54, 0xBF, 0xF0, 0x54, 0x7F, 0xF0, 0x22,
+0x90, 0x81, 0x2B, 0xE0, 0x54, 0xF7, 0xF0, 0x22,
+0x22, 0xF0, 0x90, 0x00, 0x06, 0x02, 0x1F, 0xBD,
+0x12, 0x1F, 0xA4, 0x90, 0x82, 0x08, 0xF0, 0x22,
+0x12, 0x1F, 0xA4, 0x90, 0x82, 0x1E, 0xF0, 0x22,
+0x12, 0x1F, 0xA4, 0xFF, 0x54, 0x01, 0xFE, 0x22,
+0xE0, 0x54, 0xFE, 0x4E, 0xFE, 0xF0, 0xEF, 0x22,
+0x90, 0x82, 0x43, 0x12, 0x46, 0xF4, 0x02, 0x1F,
+0xA4, 0x90, 0x81, 0x30, 0xE0, 0x60, 0x02, 0x51,
+0x66, 0x22, 0x90, 0x81, 0x2B, 0xE0, 0x13, 0x13,
+0x13, 0x54, 0x1F, 0x22, 0x90, 0x81, 0x2B, 0xE0,
+0x30, 0xE0, 0x03, 0x12, 0x5D, 0x50, 0x22, 0x90,
+0x82, 0xCD, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xA3,
+0x12, 0x20, 0xDA, 0x00, 0x00, 0x00, 0x00, 0xE4,
+0x90, 0x82, 0xDB, 0xF0, 0x7F, 0x24, 0x7E, 0x08,
+0x12, 0x2D, 0x5C, 0x90, 0x82, 0xD3, 0x12, 0x20,
+0xCE, 0x90, 0x82, 0xCD, 0xE0, 0xFB, 0x70, 0x08,
+0x90, 0x82, 0xD3, 0x12, 0x46, 0xD3, 0x80, 0x06,
+0xEB, 0x11, 0xDE, 0x12, 0x2D, 0x5C, 0x90, 0x82,
+0xD7, 0x12, 0x20, 0xCE, 0x90, 0x82, 0xCE, 0xE0,
+0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x17, 0x31,
+0x5A, 0x90, 0x82, 0xD7, 0x12, 0x46, 0xD3, 0xED,
+0x54, 0x7F, 0xFD, 0xEC, 0x54, 0x80, 0xFC, 0x12,
+0x46, 0xB5, 0xEC, 0x44, 0x80, 0xFC, 0x90, 0x82,
+0xD7, 0x12, 0x20, 0xCE, 0x11, 0xF1, 0x54, 0x7F,
+0xFC, 0x11, 0xD8, 0x11, 0xF9, 0x11, 0xDE, 0xC0,
+0x06, 0xC0, 0x07, 0x90, 0x82, 0xD7, 0x11, 0xD5,
+0xD0, 0x07, 0xD0, 0x06, 0x12, 0x2E, 0xA2, 0x11,
+0xF1, 0x44, 0x80, 0xFC, 0x11, 0xD8, 0x11, 0xF9,
+0x70, 0x04, 0x7F, 0x20, 0x80, 0x09, 0x90, 0x82,
+0xCD, 0xE0, 0xB4, 0x01, 0x16, 0x7F, 0x28, 0x7E,
+0x08, 0x12, 0x2D, 0x5C, 0x78, 0x08, 0x12, 0x20,
+0xA8, 0xEF, 0x54, 0x01, 0xFF, 0xE4, 0x90, 0x82,
+0xDB, 0xEF, 0xF0, 0x90, 0x82, 0xDB, 0xE0, 0x90,
+0x82, 0xCD, 0x60, 0x0E, 0xE0, 0x75, 0xF0, 0x08,
+0xA4, 0x24, 0x66, 0xF5, 0x82, 0xE4, 0x34, 0x87,
+0x80, 0x0C, 0xE0, 0x75, 0xF0, 0x08, 0xA4, 0x24,
+0x64, 0xF5, 0x82, 0xE4, 0x34, 0x87, 0x11, 0xE9,
+0x12, 0x2D, 0x5C, 0xED, 0x54, 0x0F, 0xFD, 0xE4,
+0xFC, 0x90, 0x82, 0xCF, 0x12, 0x20, 0xCE, 0x90,
+0x82, 0xCF, 0x02, 0x46, 0xD3, 0x12, 0x46, 0xD3,
+0x90, 0x85, 0xBB, 0x02, 0x20, 0xCE, 0x75, 0xF0,
+0x08, 0xA4, 0x24, 0x62, 0xF5, 0x82, 0xE4, 0x34,
+0x87, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
+0x22, 0x90, 0x82, 0xD3, 0x12, 0x46, 0xD3, 0xEC,
+0x22, 0x7F, 0x24, 0x7E, 0x08, 0x12, 0x2E, 0xA2,
+0x90, 0x82, 0xCD, 0xE0, 0x22, 0x90, 0x82, 0xEB,
+0xEF, 0xF0, 0xAB, 0x05, 0x90, 0x82, 0xF1, 0x12,
+0x20, 0xDA, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x03,
+0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x14, 0x31, 0x5A,
+0x90, 0x82, 0xED, 0x12, 0x46, 0xD3, 0xED, 0x54,
+0x0F, 0xFD, 0xE4, 0xFC, 0x12, 0x46, 0xB5, 0xEC,
+0x54, 0x0F, 0xFC, 0x90, 0x82, 0xF1, 0x12, 0x20,
+0xCE, 0x90, 0x82, 0xEB, 0xE0, 0x75, 0xF0, 0x08,
+0xA4, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34, 0x87,
+0x11, 0xE9, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x82,
+0xF1, 0x11, 0xD5, 0xD0, 0x07, 0xD0, 0x06, 0x02,
+0x2E, 0xA2, 0x12, 0x20, 0xBB, 0xA8, 0x04, 0xA9,
+0x05, 0xAA, 0x06, 0xAB, 0x07, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0x90, 0x83,
+0x03, 0xF0, 0xA3, 0xF0, 0x51, 0x32, 0x90, 0x85,
+0xBB, 0x12, 0x20, 0xDA, 0xCC, 0xF0, 0x00, 0xC0,
+0x12, 0x4F, 0x6C, 0x12, 0x20, 0xDA, 0x00, 0x00,
+0x00, 0x14, 0x51, 0xAC, 0x12, 0x20, 0xDA, 0x00,
+0x00, 0x00, 0x00, 0xE4, 0xFD, 0xFF, 0x51, 0x10,
+0x7F, 0xE8, 0x7E, 0x08, 0x12, 0x2D, 0x5C, 0xEF,
+0x54, 0x0E, 0xFF, 0xE4, 0xFE, 0xED, 0x54, 0xF4,
+0xFD, 0xEC, 0x54, 0x03, 0xFC, 0xE4, 0xFB, 0xFA,
+0xF9, 0xF8, 0xC3, 0x12, 0x46, 0xC2, 0x60, 0x18,
+0xD3, 0x51, 0x03, 0x40, 0x09, 0x90, 0x01, 0xC3,
+0xE0, 0x44, 0x02, 0xF0, 0x80, 0x0A, 0x51, 0x95,
+0x90, 0x83, 0x03, 0x12, 0x5C, 0x3A, 0x80, 0xC8,
+0xC3, 0x51, 0x03, 0x50, 0x17, 0x51, 0xA3, 0x44,
+0x80, 0xFC, 0x90, 0x83, 0x05, 0x12, 0x20, 0xCE,
+0x90, 0x83, 0x05, 0x11, 0xD5, 0x7F, 0x7C, 0x7E,
+0x08, 0x12, 0x2E, 0xA2, 0x90, 0x01, 0x00, 0x74,
+0x3F, 0xF0, 0xA3, 0xE0, 0x54, 0xFD, 0xF0, 0x90,
+0x05, 0x53, 0xE0, 0x44, 0x20, 0xF0, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0x90, 0x83, 0x04, 0xE0, 0x94,
+0xE8, 0x90, 0x83, 0x03, 0xE0, 0x94, 0x03, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xC0,
+0x07, 0xC0, 0x05, 0x90, 0x82, 0xFF, 0x12, 0x46,
+0xD3, 0x90, 0x82, 0xED, 0x12, 0x20, 0xCE, 0xD0,
+0x05, 0xD0, 0x07, 0x31, 0x05, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0xE4, 0x90, 0x83, 0x24, 0xF0, 0xA3,
+0xF0, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x83, 0x26,
+0xF0, 0x7B, 0x47, 0x51, 0x9C, 0x90, 0x05, 0xF8,
+0xE0, 0x70, 0x1B, 0xA3, 0xE0, 0x70, 0x17, 0xA3,
+0xE0, 0x70, 0x13, 0xA3, 0xE0, 0x70, 0x0F, 0x90,
+0x83, 0x26, 0xE0, 0xFD, 0x7B, 0x48, 0xE4, 0xFF,
+0x12, 0x4E, 0x97, 0x7F, 0x01, 0x22, 0xD3, 0x90,
+0x83, 0x25, 0xE0, 0x94, 0xE8, 0x90, 0x83, 0x24,
+0xE0, 0x94, 0x03, 0x40, 0x16, 0x90, 0x01, 0xC0,
+0xE0, 0x44, 0x20, 0xF0, 0x90, 0x83, 0x26, 0xE0,
+0xFD, 0x7B, 0x5B, 0xE4, 0xFF, 0x12, 0x4E, 0x97,
+0x7F, 0x00, 0x22, 0x51, 0x95, 0x90, 0x83, 0x24,
+0x12, 0x5C, 0x3A, 0x80, 0xB0, 0x7F, 0x32, 0x7E,
+0x00, 0x02, 0x32, 0xAA, 0x7D, 0xFF, 0xE4, 0xFF,
+0x02, 0x4E, 0x97, 0x7F, 0x7C, 0x7E, 0x08, 0x12,
+0x2D, 0x5C, 0xEC, 0x22, 0x7F, 0x70, 0x7E, 0x0E,
+0x12, 0x2E, 0xA2, 0x90, 0x82, 0xFF, 0x22, 0x7B,
+0x2F, 0x12, 0x4F, 0xD8, 0x31, 0x66, 0x7D, 0x08,
+0x7F, 0x01, 0x02, 0x4D, 0x57, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x67, 0xEF, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x12, 0x1F, 0xA4, 0xFF,
+0x54, 0x80, 0xFE, 0x90, 0x82, 0x1F, 0xE0, 0x54,
+0x7F, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x40, 0xFF,
+0xEE, 0x54, 0xBF, 0x4F, 0xFF, 0xF0, 0x12, 0x1F,
+0xA4, 0xFE, 0x54, 0x20, 0xFD, 0xEF, 0x54, 0xDF,
+0x4D, 0xFF, 0x90, 0x82, 0x1F, 0xF0, 0xEE, 0x54,
+0x10, 0xFE, 0xEF, 0x54, 0xEF, 0x4E, 0xFF, 0xF0,
+0x12, 0x1F, 0xA4, 0x54, 0x0F, 0xFE, 0xEF, 0x54,
+0xF0, 0x4E, 0x90, 0x82, 0x1F, 0xF0, 0x12, 0x5F,
+0x2A, 0xFF, 0x54, 0x7F, 0x90, 0x82, 0x21, 0xF0,
+0xEF, 0x54, 0x80, 0x12, 0x4F, 0xF0, 0xFF, 0x90,
+0x82, 0x20, 0xE0, 0x54, 0xFE, 0x12, 0x5F, 0xD2,
+0x90, 0x82, 0x22, 0x12, 0x5F, 0x74, 0x54, 0x01,
+0x25, 0xE0, 0xFF, 0x90, 0x82, 0x20, 0xE0, 0x54,
+0xFD, 0x4F, 0xF0, 0x12, 0x4B, 0xE5, 0x20, 0xE0,
+0x02, 0x7D, 0x01, 0x02, 0x4A, 0x4D, 0x12, 0x1F,
+0xA4, 0x54, 0x01, 0xFF, 0x90, 0x82, 0x24, 0xE0,
+0x54, 0xFE, 0x4F, 0xF0, 0x22, 0x12, 0x67, 0xC8,
+0xFF, 0x54, 0x01, 0xFE, 0x90, 0x82, 0x09, 0x12,
+0x67, 0xC0, 0x54, 0x02, 0xFF, 0xEE, 0x54, 0xFD,
+0x4F, 0xFF, 0xF0, 0x12, 0x7E, 0x61, 0x90, 0x82,
+0x09, 0xF1, 0xD7, 0x4E, 0xFF, 0xF0, 0x12, 0x1F,
+0xA4, 0x54, 0x10, 0x25, 0xE0, 0x25, 0xE0, 0xFE,
+0xEF, 0x54, 0xBF, 0x4E, 0x90, 0x82, 0x09, 0xF0,
+0x90, 0x05, 0x52, 0xE0, 0x54, 0x07, 0xFF, 0x90,
+0x82, 0x43, 0x60, 0x13, 0x12, 0x5F, 0x27, 0xFD,
+0x90, 0x05, 0x56, 0xE0, 0xC3, 0x9D, 0x90, 0x82,
+0x0B, 0xF0, 0xA3, 0xED, 0xF0, 0x80, 0x23, 0x12,
+0x5F, 0x27, 0xFB, 0xFF, 0x90, 0x05, 0x54, 0xE0,
+0xC3, 0x9F, 0xFF, 0xE4, 0x94, 0x00, 0xFE, 0x7C,
+0x00, 0x7D, 0x05, 0x12, 0x20, 0x30, 0x90, 0x82,
+0x0B, 0xEF, 0xF0, 0xEB, 0x75, 0xF0, 0x05, 0x84,
+0xA3, 0xF0, 0x12, 0x5F, 0x13, 0x12, 0x1F, 0xA4,
+0x20, 0xE0, 0x0A, 0x12, 0x4E, 0x90, 0x90, 0x01,
+0x57, 0xE4, 0xF0, 0x80, 0x0A, 0x7D, 0x0C, 0x7F,
+0x01, 0x12, 0x4D, 0x57, 0x12, 0x4F, 0xDE, 0xF1,
+0xE0, 0x20, 0xE0, 0x04, 0xEF, 0x44, 0x20, 0xF0,
+0x12, 0x4F, 0xD1, 0x30, 0xE0, 0x18, 0x90, 0x81,
+0x30, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x81, 0x32,
+0xF0, 0x12, 0x57, 0xDA, 0xB1, 0x9E, 0x90, 0x83,
+0x23, 0x74, 0x06, 0xF0, 0x80, 0x18, 0xE4, 0x90,
+0x81, 0x30, 0xF0, 0x90, 0x81, 0x32, 0x74, 0x0C,
+0xF0, 0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFE, 0xF0,
+0xA3, 0xE0, 0x54, 0xFB, 0xF0, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xAC, 0x07, 0x90,
+0x81, 0x2C, 0xE0, 0x12, 0x4F, 0xF0, 0x30, 0xE0,
+0x02, 0x81, 0xEE, 0x90, 0x81, 0x2B, 0xE0, 0x30,
+0xE0, 0x16, 0x90, 0x81, 0x4D, 0xE0, 0x24, 0x05,
+0x90, 0x81, 0x45, 0xF0, 0x90, 0x81, 0x4D, 0xE0,
+0x24, 0x03, 0x90, 0x81, 0x44, 0xF0, 0x80, 0x0E,
+0x90, 0x81, 0x45, 0x74, 0x05, 0xF0, 0x90, 0x81,
+0x44, 0x14, 0xF0, 0x04, 0x2B, 0xFB, 0x90, 0x81,
+0x44, 0xE0, 0xFA, 0x90, 0x81, 0x43, 0xE0, 0xD3,
+0x9A, 0x50, 0x12, 0x90, 0x81, 0x38, 0xEB, 0xF0,
+0x90, 0x81, 0x45, 0xE0, 0xC3, 0x9D, 0x2C, 0x90,
+0x81, 0x48, 0xF0, 0x80, 0x1C, 0xC3, 0xED, 0x9A,
+0x2B, 0x90, 0x81, 0x38, 0xF0, 0x90, 0x81, 0x44,
+0xE0, 0xFF, 0xA3, 0xE0, 0xC3, 0x9F, 0x90, 0x81,
+0x48, 0xF0, 0xE4, 0x90, 0x81, 0xEE, 0xF0, 0xA3,
+0xF0, 0x90, 0x81, 0x45, 0x91, 0xFA, 0x90, 0x81,
+0x48, 0xB1, 0x03, 0x40, 0x04, 0xEF, 0x24, 0x0A,
+0xF0, 0x90, 0x81, 0x48, 0x91, 0xFA, 0x90, 0x81,
+0x38, 0xB1, 0x03, 0x40, 0x04, 0xEF, 0x24, 0x0A,
+0xF0, 0x90, 0x81, 0x48, 0xE0, 0xFF, 0x7E, 0x00,
+0x90, 0x81, 0x3C, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0,
+0x90, 0x05, 0x58, 0xE0, 0x6F, 0x70, 0x01, 0xE4,
+0x60, 0x03, 0x12, 0x7E, 0x2F, 0x90, 0x81, 0x2D,
+0xE0, 0x54, 0xFE, 0xF0, 0x80, 0x07, 0x90, 0x81,
+0x2D, 0xE0, 0x44, 0x01, 0xF0, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0xE0, 0xFF, 0x24, 0x0A, 0xFD, 0xE4,
+0x33, 0xFC, 0x22, 0xE0, 0xD3, 0x9D, 0xEC, 0x64,
+0x80, 0xF8, 0x74, 0x80, 0x98, 0x22, 0xB1, 0xAC,
+0x90, 0x82, 0x27, 0xEF, 0xF0, 0x30, 0xE0, 0x05,
+0x7D, 0x01, 0xE4, 0x80, 0x02, 0xE4, 0xFD, 0xFF,
+0x12, 0x4D, 0x57, 0x90, 0x82, 0x27, 0xE0, 0x30,
+0xE6, 0x11, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7,
+0x04, 0xE4, 0xF0, 0x80, 0x06, 0x90, 0x01, 0x2F,
+0x74, 0x80, 0xF0, 0x90, 0x81, 0x2B, 0xE0, 0x30,
+0xE0, 0x2E, 0xB1, 0x96, 0x30, 0xE1, 0x0D, 0xE0,
+0x44, 0x04, 0xF0, 0x90, 0x04, 0xEC, 0xE0, 0x54,
+0xFD, 0xF0, 0x80, 0x04, 0xE0, 0x54, 0xFB, 0xF0,
+0xB1, 0x96, 0x30, 0xE5, 0x0D, 0xE0, 0x44, 0x08,
+0xF0, 0x90, 0x04, 0xEC, 0xE0, 0x54, 0xDF, 0xF0,
+0x80, 0x22, 0xE0, 0x54, 0xF7, 0xF0, 0x80, 0x1C,
+0x90, 0x81, 0x2D, 0x12, 0x55, 0x3A, 0x30, 0xE0,
+0x07, 0x90, 0x04, 0xEC, 0xE0, 0x44, 0x02, 0xF0,
+0xB1, 0xE8, 0x30, 0xE0, 0x07, 0x90, 0x04, 0xEC,
+0xE0, 0x44, 0x20, 0xF0, 0xB1, 0x9E, 0x90, 0x83,
+0x23, 0x74, 0x02, 0xF0, 0x81, 0x2E, 0x90, 0x04,
+0xEC, 0xE0, 0x90, 0x81, 0x2D, 0x22, 0x90, 0x81,
+0x42, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0x90, 0x81,
+0x49, 0xE0, 0xFB, 0x22, 0xE4, 0x90, 0x82, 0x29,
+0xF0, 0xA3, 0xF0, 0x90, 0x00, 0x83, 0xE0, 0x90,
+0x82, 0x28, 0xF0, 0x90, 0x00, 0x83, 0xE0, 0xFE,
+0x90, 0x82, 0x28, 0xE0, 0xFF, 0xB5, 0x06, 0x01,
+0x22, 0xC3, 0x90, 0x82, 0x2A, 0xE0, 0x94, 0x64,
+0x90, 0x82, 0x29, 0xE0, 0x94, 0x00, 0x40, 0x08,
+0xF1, 0xCF, 0x90, 0x82, 0x28, 0xE0, 0xFF, 0x22,
+0x90, 0x82, 0x29, 0x12, 0x5C, 0x3A, 0x80, 0xCB,
+0xEF, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x22, 0x90,
+0x82, 0x16, 0xE0, 0x30, 0xE0, 0x71, 0x90, 0x82,
+0x1A, 0xE0, 0x04, 0xF0, 0x90, 0x82, 0x1D, 0xE0,
+0x64, 0x01, 0x70, 0x2F, 0x90, 0x82, 0x16, 0x12,
+0x55, 0x3A, 0x30, 0xE0, 0x26, 0x90, 0x82, 0x1C,
+0xE0, 0x70, 0x20, 0x90, 0x82, 0x19, 0xE0, 0xFE,
+0xA3, 0xE0, 0xC3, 0x9E, 0x40, 0x15, 0xB1, 0xE8,
+0x30, 0xE0, 0x09, 0x12, 0x5F, 0xDA, 0x12, 0x5F,
+0x7B, 0xF0, 0x80, 0x07, 0xD1, 0x68, 0x12, 0x5F,
+0x7B, 0xF0, 0x22, 0x90, 0x82, 0x1A, 0xE0, 0xFF,
+0x90, 0x82, 0x17, 0xE0, 0xD3, 0x9F, 0x50, 0x27,
+0x90, 0x06, 0x92, 0xE0, 0x20, 0xE2, 0x11, 0x90,
+0x82, 0x1C, 0xE0, 0x70, 0x0B, 0x12, 0x7E, 0x39,
+0x90, 0x82, 0x15, 0xE0, 0x04, 0xF0, 0x80, 0x06,
+0x90, 0x06, 0x92, 0x74, 0x04, 0xF0, 0xE4, 0x90,
+0x82, 0x1A, 0xF0, 0x90, 0x82, 0x1C, 0xF0, 0x22,
+0x90, 0x01, 0xC7, 0x74, 0x10, 0xF0, 0x7F, 0x01,
+0x80, 0x0A, 0xD1, 0xD6, 0x90, 0x01, 0xC7, 0x74,
+0x66, 0xF0, 0xE4, 0xFF, 0x90, 0x83, 0x37, 0xEF,
+0xF0, 0x90, 0x80, 0x07, 0xE0, 0xB4, 0x02, 0x12,
+0x90, 0x83, 0x37, 0xE0, 0xFF, 0x64, 0x01, 0x60,
+0x25, 0x90, 0x01, 0x4D, 0xE0, 0x64, 0x80, 0xF0,
+0x80, 0x19, 0x90, 0x01, 0x00, 0x74, 0xFF, 0xF0,
+0x7F, 0x64, 0x7E, 0x00, 0x12, 0x32, 0xAA, 0x90,
+0x06, 0x90, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x83,
+0x37, 0xE0, 0xFF, 0x12, 0x4B, 0x20, 0x12, 0x5F,
+0x7B, 0xF0, 0x22, 0x12, 0x5F, 0xE3, 0x30, 0xE0,
+0x14, 0xE4, 0x90, 0x80, 0xFF, 0xF0, 0x90, 0x80,
+0xFC, 0xE0, 0x30, 0xE0, 0x08, 0xC4, 0x54, 0x0F,
+0x30, 0xE0, 0x02, 0xD1, 0x72, 0x22, 0xE4, 0x90,
+0x82, 0xC2, 0xF0, 0x90, 0x80, 0xFC, 0xE0, 0xFE,
+0x54, 0x01, 0x90, 0x82, 0xC2, 0xF0, 0xEE, 0x54,
+0xFE, 0x90, 0x80, 0xFC, 0xF0, 0x7D, 0x08, 0xE4,
+0xFF, 0x12, 0x54, 0xA9, 0x90, 0x82, 0xC2, 0xE0,
+0x60, 0x10, 0x90, 0x02, 0x09, 0xE0, 0x90, 0x04,
+0x24, 0xF0, 0x90, 0x02, 0x09, 0xE0, 0x90, 0x04,
+0x25, 0xF0, 0xE4, 0x90, 0x81, 0x08, 0xF0, 0xA3,
+0xF0, 0x22, 0x90, 0x80, 0xFF, 0xE0, 0x60, 0x08,
+0x90, 0x80, 0xFC, 0xE0, 0x44, 0x10, 0xF0, 0x22,
+0xC1, 0x72, 0xF1, 0x71, 0x90, 0x82, 0x27, 0xEE,
+0xF0, 0xA3, 0xEF, 0x12, 0x5F, 0xE2, 0x30, 0xE0,
+0x14, 0x90, 0x82, 0x28, 0xE0, 0x20, 0xE0, 0x0D,
+0xD1, 0xD6, 0x90, 0x02, 0x86, 0xE0, 0x30, 0xE2,
+0x04, 0xE0, 0x54, 0xFB, 0xF0, 0x22, 0x12, 0x5F,
+0xE3, 0x30, 0xE0, 0x24, 0xEF, 0x30, 0xE0, 0x20,
+0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x18,
+0x90, 0x81, 0x00, 0xE0, 0x70, 0x0C, 0xD1, 0xD6,
+0x90, 0x01, 0xC7, 0x74, 0x66, 0xF0, 0xE4, 0xFF,
+0xC1, 0x7C, 0x90, 0x81, 0x00, 0xE0, 0x14, 0xF0,
+0x22, 0xE4, 0x90, 0x82, 0x2B, 0xF0, 0xA3, 0xF0,
+0x90, 0x00, 0x9E, 0xE0, 0x90, 0x82, 0x2D, 0xF0,
+0x90, 0x00, 0x9F, 0xE0, 0x90, 0x82, 0x2E, 0xF0,
+0xE0, 0xFD, 0xFE, 0x90, 0x82, 0x2D, 0xE0, 0xFC,
+0xFB, 0xEB, 0xFF, 0x90, 0x82, 0x29, 0xEE, 0xF0,
+0xA3, 0xEF, 0xF0, 0x90, 0x00, 0x9E, 0xE0, 0xFF,
+0xEC, 0xB5, 0x07, 0x09, 0xA3, 0xE0, 0xFF, 0xED,
+0xB5, 0x07, 0x02, 0x80, 0x11, 0xC3, 0x90, 0x82,
+0x2C, 0xE0, 0x94, 0x64, 0x90, 0x82, 0x2B, 0xE0,
+0x94, 0x00, 0x40, 0x0B, 0xF1, 0xCF, 0x90, 0x82,
+0x29, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0x90,
+0x82, 0x2B, 0x12, 0x5C, 0x3A, 0x80, 0xA9, 0x90,
+0x01, 0xC0, 0xE0, 0x44, 0x40, 0xF0, 0x22, 0xF0,
+0xEE, 0x54, 0x08, 0xFE, 0xEF, 0x54, 0xF7, 0x22,
+0x90, 0x82, 0x09, 0xE0, 0xFF, 0x13, 0x13, 0x13,
+0x54, 0x1F, 0x22, 0x12, 0x1F, 0xA4, 0x90, 0x81,
+0x1E, 0xF0, 0x12, 0x5F, 0x2A, 0x90, 0x81, 0x1F,
+0x12, 0x5F, 0xD3, 0x90, 0x81, 0x20, 0xF0, 0x22,
+0xE4, 0x90, 0x80, 0xF8, 0xF0, 0xA3, 0xF0, 0x90,
+0x80, 0x60, 0xF0, 0xA3, 0xF0, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x82, 0x3F,
+0x12, 0x46, 0xF4, 0x90, 0x83, 0x28, 0xE0, 0xFF,
+0x04, 0xF0, 0x90, 0x00, 0x01, 0xEF, 0x12, 0x1F,
+0xFC, 0x7F, 0xAF, 0x7E, 0x01, 0x12, 0x5B, 0xA1,
+0xEF, 0x60, 0x3A, 0x90, 0x82, 0x3F, 0x12, 0x46,
+0xEB, 0x8B, 0x13, 0x8A, 0x14, 0x89, 0x15, 0x90,
+0x00, 0x0E, 0x12, 0x1F, 0xBD, 0x24, 0x02, 0xF5,
+0x16, 0x7B, 0x01, 0x7A, 0x01, 0x79, 0xA0, 0x12,
+0x2B, 0xED, 0x90, 0x82, 0x3F, 0x12, 0x46, 0xEB,
+0x90, 0x00, 0x0E, 0x12, 0x1F, 0xBD, 0x90, 0x01,
+0xAE, 0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0x90, 0x01,
+0xCB, 0xE0, 0x64, 0x80, 0xF0, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x7D, 0x08, 0xED, 0x14, 0xF9, 0x24, 0x22,
+0x11, 0xC5, 0x60, 0x38, 0x7C, 0x08, 0xEC, 0x14,
+0x90, 0x83, 0x30, 0xF0, 0x74, 0x22, 0x29, 0x11,
+0xC5, 0xFB, 0x7A, 0x00, 0x90, 0x83, 0x30, 0x11,
+0xCE, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE,
+0xD8, 0xF9, 0xFF, 0xEE, 0x5A, 0xFE, 0xEF, 0x5B,
+0x4E, 0x60, 0x0F, 0xE9, 0x75, 0xF0, 0x08, 0xA4,
+0xFF, 0x90, 0x83, 0x30, 0xE0, 0x2F, 0x04, 0xFF,
+0x80, 0x06, 0xDC, 0xCA, 0xDD, 0xBD, 0x7F, 0x00,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF5, 0x82, 0xE4,
+0x34, 0x81, 0xF5, 0x83, 0xE0, 0x22, 0xE0, 0xFF,
+0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x22,
+0x75, 0x3D, 0x10, 0xE4, 0xF5, 0x3E, 0x75, 0x3F,
+0x87, 0x75, 0x40, 0x03, 0x90, 0x01, 0x30, 0xE5,
+0x3D, 0xF0, 0xA3, 0xE5, 0x3E, 0xF0, 0xA3, 0xE5,
+0x3F, 0xF0, 0xA3, 0xE5, 0x40, 0xF0, 0x22, 0x75,
+0x45, 0x0F, 0x75, 0x46, 0x01, 0x75, 0x47, 0x23,
+0x75, 0x48, 0x62, 0x90, 0x01, 0x38, 0xE5, 0x45,
+0xF0, 0xA3, 0xE5, 0x46, 0xF0, 0xA3, 0xE5, 0x47,
+0xF0, 0xA3, 0xE5, 0x48, 0xF0, 0x22, 0x7F, 0x02,
+0x90, 0x82, 0x11, 0xE0, 0xFE, 0xEF, 0xC3, 0x9E,
+0x50, 0x18, 0xEF, 0x25, 0xE0, 0x24, 0x81, 0xF8,
+0xE6, 0x30, 0xE4, 0x0B, 0x90, 0x01, 0xB8, 0x74,
+0x08, 0xF0, 0xA3, 0xF0, 0x7F, 0x00, 0x22, 0x0F,
+0x80, 0xDE, 0x7F, 0x01, 0x22, 0x90, 0x01, 0x34,
+0xE0, 0x55, 0x3D, 0xF5, 0x41, 0xA3, 0xE0, 0x55,
+0x3E, 0xF5, 0x42, 0xA3, 0xE0, 0x55, 0x3F, 0xF5,
+0x43, 0xA3, 0xE0, 0x55, 0x40, 0xF5, 0x44, 0x90,
+0x01, 0x34, 0xE5, 0x41, 0xF0, 0xA3, 0xE5, 0x42,
+0xF0, 0xA3, 0xE5, 0x43, 0xF0, 0xA3, 0xE5, 0x44,
+0xF0, 0x22, 0x90, 0x01, 0x3C, 0xE0, 0x55, 0x45,
+0xF5, 0x49, 0xA3, 0xE0, 0x55, 0x46, 0xF5, 0x4A,
+0xA3, 0xE0, 0x55, 0x47, 0xF5, 0x4B, 0xA3, 0xE0,
+0x55, 0x48, 0xF5, 0x4C, 0x90, 0x01, 0x3C, 0xE5,
+0x49, 0xF0, 0xA3, 0xE5, 0x4A, 0xF0, 0xA3, 0xE5,
+0x4B, 0xF0, 0xA3, 0xE5, 0x4C, 0xF0, 0x53, 0x91,
+0xDF, 0x22, 0x90, 0x80, 0xFC, 0xE0, 0x30, 0xE0,
+0x05, 0x7F, 0x20, 0x12, 0x49, 0x35, 0x22, 0x90,
+0x01, 0xCF, 0xE0, 0x90, 0x83, 0x32, 0xF0, 0xE0,
+0xFF, 0x30, 0xE0, 0x07, 0x90, 0x01, 0xCF, 0xE0,
+0x54, 0xFE, 0xF0, 0xEF, 0x30, 0xE5, 0x23, 0x90,
+0x01, 0xCF, 0xE0, 0x54, 0xDF, 0xF0, 0x90, 0x01,
+0x34, 0x74, 0x20, 0xF0, 0xE4, 0xF5, 0xA8, 0xF5,
+0xE8, 0x12, 0x58, 0x9E, 0x90, 0x00, 0x03, 0xE0,
+0x54, 0xFB, 0xFD, 0x7F, 0x03, 0x12, 0x32, 0x1E,
+0x80, 0xFE, 0x22, 0x51, 0xCD, 0x90, 0x81, 0x30,
+0xE0, 0x60, 0x2D, 0x90, 0x81, 0x2C, 0x12, 0x67,
+0xDD, 0x30, 0xE0, 0x0D, 0x90, 0x01, 0x3B, 0xE0,
+0x30, 0xE4, 0x06, 0x12, 0x54, 0xA5, 0x12, 0x57,
+0xD4, 0x90, 0x83, 0x31, 0xE0, 0x04, 0xF0, 0xE0,
+0xC3, 0x94, 0x80, 0x40, 0x0B, 0x90, 0x01, 0x98,
+0xE0, 0x54, 0xFE, 0xF0, 0xE0, 0x44, 0x01, 0xF0,
+0x51, 0xAC, 0xBF, 0x03, 0x14, 0x90, 0x82, 0x1E,
+0xE0, 0xB4, 0x01, 0x0D, 0x90, 0x01, 0xB8, 0xE0,
+0x04, 0xF0, 0x90, 0x05, 0x21, 0xE0, 0x44, 0x80,
+0xF0, 0x12, 0x6D, 0xEF, 0x51, 0x69, 0xE4, 0x90,
+0x82, 0x15, 0xF0, 0x12, 0x6F, 0x46, 0x90, 0x82,
+0x09, 0xE0, 0x30, 0xE0, 0x0C, 0xE4, 0xF5, 0x1D,
+0x90, 0x82, 0x0B, 0x12, 0x4C, 0x32, 0x12, 0x4F,
+0xDE, 0x90, 0x80, 0x07, 0xE0, 0xB4, 0x01, 0x10,
+0x12, 0x6F, 0xE0, 0x20, 0xE0, 0x0A, 0xEF, 0xC4,
+0x13, 0x54, 0x07, 0x30, 0xE0, 0x02, 0x51, 0xDD,
+0x22, 0x90, 0x82, 0x12, 0xE0, 0x30, 0xE0, 0x34,
+0x12, 0x4F, 0xC8, 0x70, 0x2F, 0x90, 0x83, 0x38,
+0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x0A, 0x0B, 0x90,
+0x82, 0x14, 0xE0, 0x04, 0xF0, 0xE4, 0x90, 0x83,
+0x38, 0xF0, 0x90, 0x82, 0x14, 0xE0, 0xFF, 0x90,
+0x82, 0x13, 0xE0, 0xD3, 0x9F, 0x50, 0x0D, 0x90,
+0x82, 0x15, 0xE0, 0x70, 0x07, 0xE4, 0x90, 0x82,
+0x14, 0xF0, 0x51, 0xA5, 0x22, 0x7D, 0x08, 0x7F,
+0x02, 0x02, 0x56, 0x0B, 0x90, 0x01, 0x02, 0xE0,
+0x54, 0x03, 0xFF, 0x22, 0x51, 0xAC, 0xBF, 0x03,
+0x02, 0x51, 0xD5, 0x22, 0x51, 0xCD, 0x90, 0x05,
+0x50, 0xE0, 0x44, 0x01, 0xF0, 0x51, 0xAC, 0xBF,
+0x03, 0x02, 0x51, 0xD5, 0x22, 0xE4, 0xF5, 0x4E,
+0xF5, 0x4F, 0xF5, 0x50, 0x22, 0x90, 0x05, 0x21,
+0xE0, 0x54, 0x7F, 0xF0, 0x22, 0x90, 0x82, 0x09,
+0xE0, 0x30, 0xE0, 0x34, 0xC4, 0x13, 0x54, 0x07,
+0x30, 0xE0, 0x2D, 0x90, 0x83, 0x35, 0xE0, 0x04,
+0xF0, 0xE0, 0xD3, 0x94, 0xC8, 0x40, 0x21, 0x90,
+0x82, 0x09, 0xE0, 0x54, 0xDF, 0xF0, 0xE4, 0x90,
+0x83, 0x35, 0xF0, 0x90, 0x82, 0x09, 0xE0, 0x13,
+0x30, 0xE0, 0x0D, 0x90, 0x81, 0x2B, 0xE0, 0x44,
+0x01, 0xF0, 0x90, 0x81, 0x3B, 0x74, 0xD0, 0xF0,
+0x22, 0x90, 0x82, 0x1C, 0xE0, 0x04, 0xF0, 0x90,
+0x81, 0x33, 0xE0, 0x64, 0x02, 0x60, 0x03, 0x12,
+0x53, 0xDF, 0x22, 0x90, 0x01, 0xC4, 0x74, 0x2B,
+0xF0, 0x74, 0x73, 0xA3, 0xF0, 0x90, 0x00, 0x90,
+0xE0, 0x20, 0xE0, 0xF9, 0x74, 0x2B, 0x04, 0x90,
+0x01, 0xC4, 0xF0, 0x74, 0x73, 0xA3, 0xF0, 0x22,
+0x90, 0x81, 0x3B, 0xE0, 0xFD, 0x7F, 0x93, 0x12,
+0x32, 0x1E, 0x90, 0x81, 0x31, 0xE0, 0x60, 0x12,
+0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x05, 0x74,
+0x10, 0xF0, 0x80, 0x06, 0x90, 0x01, 0x2F, 0x74,
+0x90, 0xF0, 0x90, 0x00, 0x08, 0xE0, 0x44, 0x10,
+0xFD, 0x7F, 0x08, 0x12, 0x32, 0x1E, 0x7F, 0x01,
+0x12, 0x5B, 0xE9, 0x90, 0x81, 0x3B, 0xE0, 0x20,
+0xE0, 0x0C, 0x90, 0x00, 0x26, 0xE0, 0x44, 0x80,
+0xFD, 0x7F, 0x26, 0x12, 0x32, 0x1E, 0x90, 0x00,
+0x90, 0xE0, 0x44, 0x01, 0xFD, 0x7F, 0x90, 0x12,
+0x32, 0x1E, 0x7F, 0x14, 0x7E, 0x00, 0x02, 0x32,
+0xAA, 0x7D, 0x10, 0xE4, 0xFF, 0x74, 0x45, 0x2F,
+0xF8, 0xE6, 0x4D, 0x02, 0x54, 0x96, 0x90, 0x82,
+0x1F, 0xE0, 0x54, 0x7F, 0xF0, 0x54, 0xBF, 0xF0,
+0x54, 0xDF, 0xF0, 0x54, 0xF0, 0xF0, 0xE4, 0x90,
+0x82, 0x21, 0xF0, 0x90, 0x82, 0x1F, 0xE0, 0x54,
+0xEF, 0xF0, 0x22, 0x90, 0x04, 0x1A, 0xE0, 0xF4,
+0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x04, 0x1B,
+0xE0, 0x54, 0x07, 0x64, 0x07, 0x7F, 0x01, 0x60,
+0x02, 0x7F, 0x00, 0x22, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x71, 0xCB, 0xEF, 0x64, 0x01,
+0x60, 0x05, 0x75, 0x0D, 0x01, 0x80, 0x41, 0x90,
+0x81, 0x34, 0xE0, 0xFF, 0x54, 0x03, 0x60, 0x05,
+0x75, 0x0D, 0x02, 0x80, 0x33, 0xEF, 0x30, 0xE2,
+0x05, 0x75, 0x0D, 0x08, 0x80, 0x2A, 0x90, 0x81,
+0x34, 0xE0, 0x30, 0xE4, 0x05, 0x75, 0x0D, 0x10,
+0x80, 0x1E, 0x12, 0x55, 0x37, 0x20, 0xE0, 0x05,
+0x75, 0x0D, 0x20, 0x80, 0x13, 0x91, 0x53, 0x8F,
+0x0E, 0xE5, 0x0E, 0x64, 0x01, 0x60, 0x05, 0x85,
+0x0E, 0x0D, 0x80, 0x04, 0x91, 0x4B, 0x80, 0x0E,
+0x90, 0x01, 0xB9, 0x74, 0x04, 0xF0, 0x90, 0x01,
+0xB8, 0xE5, 0x0D, 0xF0, 0x7F, 0x00, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0x90, 0x01, 0xB8, 0xE4, 0xF0,
+0x7F, 0x01, 0x22, 0x90, 0x81, 0x32, 0xE0, 0xD3,
+0x94, 0x00, 0x40, 0x06, 0x75, 0x55, 0x04, 0x7F,
+0xFF, 0x22, 0x90, 0x82, 0x08, 0xE0, 0x60, 0x06,
+0x75, 0x55, 0x80, 0x7F, 0xFF, 0x22, 0x7F, 0x01,
+0x22, 0x90, 0x02, 0x87, 0xE0, 0x60, 0x02, 0x80,
+0x08, 0x90, 0x01, 0x00, 0xE0, 0x64, 0x3F, 0x60,
+0x05, 0x75, 0x54, 0x01, 0x80, 0x22, 0x90, 0x02,
+0x96, 0xE0, 0x60, 0x05, 0x75, 0x54, 0x10, 0x80,
+0x17, 0x90, 0x02, 0x86, 0xE0, 0x20, 0xE1, 0x02,
+0x80, 0x07, 0x90, 0x02, 0x86, 0xE0, 0x30, 0xE3,
+0x05, 0x75, 0x54, 0x04, 0x80, 0x02, 0x80, 0xA3,
+0x90, 0x01, 0xB9, 0x74, 0x08, 0xF0, 0x90, 0x01,
+0xB8, 0xE5, 0x54, 0xF0, 0x7F, 0x00, 0x22, 0xEF,
+0x24, 0xFE, 0x60, 0x0B, 0x04, 0x70, 0x24, 0x90,
+0x81, 0x36, 0x74, 0x02, 0xF0, 0x80, 0x13, 0xED,
+0x70, 0x06, 0x90, 0x82, 0x05, 0xE0, 0x80, 0x02,
+0xED, 0x14, 0x90, 0x81, 0x36, 0xF0, 0x90, 0x81,
+0x36, 0xE0, 0xA3, 0xF0, 0x90, 0x81, 0x2C, 0xE0,
+0x44, 0x08, 0xF0, 0x22, 0x7B, 0x2E, 0x91, 0xEF,
+0x7D, 0x02, 0x7F, 0x01, 0x02, 0x4D, 0x57, 0x7D,
+0x6F, 0x7F, 0xFF, 0x02, 0x4E, 0x97, 0x90, 0x82,
+0x09, 0xE0, 0x54, 0xFE, 0xF0, 0x54, 0xFD, 0xF0,
+0x54, 0xEF, 0xF0, 0x44, 0x08, 0xF0, 0x22, 0x90,
+0x83, 0x0F, 0xE0, 0xFF, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x83, 0x36, 0xEF, 0xF0,
+0xC3, 0x94, 0x02, 0x50, 0x48, 0x90, 0x80, 0x0B,
+0xE0, 0xFF, 0x90, 0x04, 0x1C, 0xE0, 0x6F, 0x70,
+0x3C, 0x90, 0x81, 0x33, 0xE0, 0x64, 0x0E, 0x70,
+0x19, 0x90, 0x83, 0x36, 0xE0, 0x70, 0x2E, 0x90,
+0x81, 0x2B, 0xE0, 0x54, 0x7F, 0xF0, 0x12, 0x4F,
+0xE6, 0x7D, 0x0C, 0x7F, 0x01, 0x12, 0x4D, 0x57,
+0x80, 0x18, 0x90, 0x81, 0x33, 0xE0, 0x64, 0x06,
+0x70, 0x13, 0x90, 0x83, 0x36, 0xE0, 0x60, 0x0D,
+0xB1, 0x6A, 0xB1, 0x72, 0x90, 0x81, 0x33, 0x74,
+0x04, 0xF0, 0x12, 0x4E, 0x92, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0x90, 0x81, 0x2B, 0xE0, 0x54, 0xBF,
+0xF0, 0x22, 0x90, 0x06, 0x04, 0xE0, 0x44, 0x40,
+0xF0, 0xE0, 0x44, 0x80, 0xF0, 0x22, 0x74, 0xA2,
+0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83,
+0xE0, 0xFF, 0xE4, 0xFE, 0xEF, 0xC3, 0x13, 0xFD,
+0xEF, 0x30, 0xE0, 0x02, 0x7E, 0x80, 0x90, 0xFD,
+0x10, 0xED, 0xF0, 0xAF, 0x06, 0x22, 0x90, 0x82,
+0x3F, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x02,
+0x84, 0xEF, 0xF0, 0xEE, 0xA3, 0xF0, 0xA3, 0xE0,
+0x44, 0x01, 0xF0, 0x22, 0x7D, 0x7F, 0xEF, 0x5D,
+0xC3, 0x60, 0x0A, 0xB1, 0xC9, 0x24, 0x80, 0xFF,
+0xE4, 0x3E, 0xFE, 0x80, 0x03, 0xB1, 0xC9, 0xFF,
+0x22, 0x74, 0xFF, 0x9D, 0xFD, 0x74, 0xFF, 0x94,
+0x00, 0x5E, 0xFE, 0xED, 0x5F, 0x22, 0x7E, 0x00,
+0x7F, 0x08, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x82,
+0x79, 0x16, 0x12, 0x47, 0x23, 0x90, 0x82, 0x17,
+0x74, 0x08, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0x22,
+0x90, 0x82, 0xC2, 0x12, 0x46, 0xF4, 0xE4, 0xFF,
+0x90, 0x82, 0xC8, 0xE0, 0xFE, 0xEF, 0xC3, 0x9E,
+0x50, 0x1E, 0x90, 0x82, 0xC5, 0x12, 0x46, 0xEB,
+0x8F, 0x82, 0xD1, 0x39, 0xFE, 0x90, 0x82, 0xC2,
+0x12, 0x46, 0xEB, 0x8F, 0x82, 0xD1, 0x39, 0x6E,
+0x60, 0x03, 0x7F, 0x00, 0x22, 0x0F, 0x80, 0xD8,
+0x7F, 0x01, 0x22, 0x75, 0xF0, 0x03, 0xA4, 0x24,
+0x93, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83,
+0x12, 0x46, 0xEB, 0x90, 0x82, 0x49, 0xE0, 0xF5,
+0x82, 0x75, 0x83, 0x00, 0x02, 0x1F, 0xBD, 0x74,
+0x03, 0xF0, 0x7A, 0x82, 0x79, 0xF9, 0xB1, 0xF0,
+0xEF, 0x22, 0x74, 0x03, 0xF0, 0x7A, 0x82, 0x79,
+0xF5, 0xB1, 0xF0, 0xEF, 0x22, 0x12, 0x5F, 0x19,
+0x30, 0xE0, 0x0A, 0xE0, 0xC4, 0x54, 0x0F, 0x30,
+0xE0, 0x03, 0x02, 0x7C, 0xE4, 0x90, 0x81, 0x19,
+0xE0, 0x90, 0x82, 0xA2, 0xF0, 0x90, 0x81, 0x1A,
+0xE0, 0x90, 0x82, 0xA3, 0xF0, 0x90, 0x81, 0x1B,
+0xE0, 0x90, 0x82, 0xA4, 0xF0, 0x90, 0x81, 0x1C,
+0xE0, 0x90, 0x82, 0xA5, 0xF0, 0x90, 0x81, 0x1D,
+0xE0, 0x90, 0x82, 0xA6, 0xF0, 0x90, 0x81, 0x0A,
+0xE0, 0x90, 0x82, 0xA7, 0xF0, 0x90, 0x81, 0x0B,
+0xE0, 0x90, 0x82, 0xA8, 0xF0, 0x90, 0x81, 0x0C,
+0xE0, 0x90, 0x82, 0xA9, 0xF0, 0x90, 0x81, 0x0D,
+0xE0, 0x90, 0x82, 0xAA, 0xF0, 0x90, 0x81, 0x0E,
+0xE0, 0x90, 0x82, 0xAB, 0xF0, 0x90, 0x81, 0x0F,
+0xE0, 0x90, 0x82, 0xAC, 0xF0, 0x90, 0x81, 0x10,
+0xE0, 0x90, 0x82, 0xAD, 0xF0, 0x90, 0x81, 0x11,
+0xE0, 0x90, 0x82, 0xAE, 0xF0, 0x90, 0x81, 0x12,
+0xE0, 0x90, 0x82, 0xAF, 0xF0, 0x90, 0x81, 0x13,
+0xE0, 0x90, 0x82, 0xB0, 0xF0, 0x12, 0x58, 0xC4,
+0x90, 0x82, 0x4A, 0xF0, 0x12, 0x7D, 0x00, 0x50,
+0x05, 0x12, 0x7D, 0x0D, 0x80, 0xF6, 0x90, 0x01,
+0x1F, 0xE0, 0xFE, 0x90, 0x01, 0x1E, 0x12, 0x7E,
+0x83, 0x90, 0x82, 0x3F, 0xF0, 0xA3, 0x12, 0x7D,
+0xC0, 0x12, 0x7D, 0x00, 0x50, 0x57, 0xB1, 0x7E,
+0x90, 0x82, 0x4A, 0xE0, 0xFE, 0x24, 0xB1, 0xF5,
+0x82, 0xE4, 0x34, 0x82, 0x12, 0x7E, 0x08, 0x24,
+0x45, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0xE0, 0xFF, 0x74, 0x4C, 0x2E, 0xF5, 0x82, 0xE4,
+0x34, 0x82, 0x12, 0x7E, 0x08, 0x24, 0x46, 0xF9,
+0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0xEE, 0x12,
+0x7D, 0x6F, 0x12, 0x46, 0xF4, 0x12, 0x7E, 0x0C,
+0x24, 0x30, 0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0xEE,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0x93, 0xF5, 0x82,
+0xE4, 0x34, 0x82, 0xF5, 0x83, 0x12, 0x46, 0xF4,
+0x12, 0x7D, 0x1A, 0x80, 0xA4, 0x90, 0x02, 0x87,
+0xE0, 0x70, 0x03, 0x02, 0x7C, 0xE4, 0x90, 0x80,
+0xFC, 0xE0, 0x20, 0xE0, 0x03, 0x02, 0x7C, 0xE4,
+0xC3, 0x13, 0x30, 0xE0, 0x0A, 0xE0, 0xC4, 0x54,
+0x0F, 0x30, 0xE0, 0x03, 0x02, 0x7C, 0xE4, 0xE4,
+0x90, 0x82, 0xBB, 0x12, 0x58, 0xCC, 0x90, 0x82,
+0x3F, 0xE0, 0xFF, 0xA3, 0xE0, 0xA3, 0xCF, 0xF0,
+0xA3, 0xEF, 0xF0, 0x90, 0x82, 0x41, 0xE0, 0xFC,
+0xA3, 0xE0, 0xFD, 0xEC, 0x90, 0xFD, 0x11, 0xF0,
+0x74, 0x01, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB,
+0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x00, 0x2D, 0x12,
+0x7E, 0x7A, 0x7A, 0x00, 0x24, 0x00, 0xFF, 0xEA,
+0x3E, 0x54, 0x3F, 0x90, 0x82, 0x43, 0xF0, 0xA3,
+0xEF, 0xF0, 0x74, 0x02, 0x2D, 0xF5, 0x82, 0xE4,
+0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x54, 0x0F, 0x33,
+0x33, 0x33, 0x54, 0xF8, 0x90, 0x82, 0x46, 0xF0,
+0xFC, 0x74, 0x07, 0x2D, 0xF5, 0x82, 0xE4, 0x34,
+0xFB, 0xF5, 0x83, 0xE0, 0x54, 0xC0, 0x90, 0x82,
+0x48, 0xF0, 0xEC, 0x24, 0x18, 0x90, 0x82, 0x45,
+0xF0, 0xFD, 0x90, 0x82, 0x41, 0xE0, 0xFE, 0xA3,
+0xE0, 0xFF, 0x12, 0x59, 0xD3, 0xEF, 0x54, 0xFC,
+0x90, 0x82, 0x47, 0xF0, 0x90, 0x82, 0x46, 0xE0,
+0x24, 0x18, 0xFF, 0xE4, 0x33, 0x90, 0x82, 0x43,
+0x8F, 0xF0, 0x12, 0x46, 0x9F, 0x90, 0x82, 0x43,
+0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x75, 0xB4,
+0x90, 0x82, 0x3F, 0xEE, 0x8F, 0xF0, 0x12, 0x46,
+0x9F, 0x90, 0x80, 0xFA, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0x90, 0x82, 0x3F, 0xE0, 0xFC, 0xA3, 0xE0,
+0xFD, 0xD3, 0x9F, 0xEC, 0x9E, 0x40, 0x11, 0x90,
+0x80, 0xFB, 0xB1, 0xC8, 0xED, 0x9F, 0xFF, 0xEC,
+0x9E, 0x90, 0x82, 0x3F, 0xF0, 0xA3, 0xEF, 0xF0,
+0x12, 0x5F, 0x19, 0x20, 0xE0, 0x02, 0x41, 0x76,
+0xE4, 0x90, 0x82, 0x4B, 0xF0, 0x90, 0x82, 0x4A,
+0xF0, 0xB1, 0x00, 0x50, 0x36, 0x12, 0x75, 0x7E,
+0xE4, 0x90, 0x82, 0x49, 0xF0, 0xB1, 0x26, 0x94,
+0x06, 0x50, 0x15, 0x91, 0xE5, 0x24, 0x04, 0xFC,
+0xED, 0x2C, 0x12, 0x5B, 0x00, 0x12, 0x76, 0x23,
+0xB5, 0x07, 0x05, 0x12, 0x5A, 0xA7, 0x80, 0xE5,
+0x90, 0x82, 0x49, 0xE0, 0xB4, 0x06, 0x08, 0x90,
+0x82, 0x4B, 0x74, 0x01, 0xF0, 0x80, 0x04, 0xB1,
+0x1A, 0x80, 0xC6, 0x90, 0x82, 0x47, 0xE0, 0x24,
+0x60, 0x70, 0x02, 0x41, 0x21, 0x24, 0xFC, 0x70,
+0x02, 0x41, 0x21, 0x24, 0xF4, 0x70, 0x02, 0x41,
+0x16, 0x24, 0xF0, 0x70, 0x02, 0x41, 0x21, 0x24,
+0x80, 0x60, 0x02, 0x41, 0x35, 0x91, 0xE5, 0x24,
+0x18, 0xFD, 0x12, 0x59, 0xD3, 0xEF, 0x60, 0x02,
+0x61, 0xCE, 0x91, 0xE5, 0x24, 0x19, 0xFD, 0x12,
+0x59, 0xD3, 0x90, 0x82, 0x60, 0xB1, 0x5E, 0xB1,
+0x21, 0x9F, 0x50, 0x0A, 0x91, 0xE5, 0x12, 0x5B,
+0x08, 0x12, 0x5A, 0xA3, 0x80, 0xF1, 0x90, 0x82,
+0x60, 0xE0, 0x70, 0x02, 0x21, 0x6E, 0xE4, 0x90,
+0x82, 0x4A, 0xF0, 0xB1, 0x00, 0x50, 0x5F, 0x12,
+0x75, 0x7E, 0xB1, 0xA0, 0x70, 0x1D, 0xB1, 0x6E,
+0x12, 0x46, 0xEB, 0xC0, 0x03, 0xC0, 0x02, 0xC0,
+0x01, 0xB1, 0x2D, 0xED, 0xF0, 0xD0, 0x01, 0xD0,
+0x02, 0xD0, 0x03, 0x12, 0x75, 0xF0, 0xEF, 0x60,
+0x02, 0x80, 0x26, 0x90, 0x82, 0x60, 0xE0, 0x64,
+0x03, 0x70, 0x29, 0xB1, 0x2D, 0x12, 0x76, 0x3F,
+0x70, 0x07, 0xB1, 0x2D, 0x12, 0x76, 0x4A, 0x60,
+0x17, 0xB1, 0x7D, 0x60, 0x02, 0x80, 0x05, 0xB1,
+0x44, 0xE0, 0x60, 0x05, 0x74, 0xBB, 0x2F, 0x80,
+0x0D, 0x91, 0xF2, 0x74, 0x01, 0xF0, 0x80, 0x0A,
+0xB1, 0x3D, 0x80, 0x02, 0xB1, 0x3D, 0x91, 0xF8,
+0xE4, 0xF0, 0xB1, 0x1A, 0x80, 0x9D, 0x90, 0x82,
+0xBB, 0xE0, 0x70, 0x50, 0xA3, 0xE0, 0x70, 0x4C,
+0xA3, 0xE0, 0x70, 0x48, 0xA3, 0xE0, 0x70, 0x44,
+0xA3, 0xE0, 0x70, 0x40, 0x61, 0xCE, 0xE4, 0x90,
+0x82, 0x4A, 0xF0, 0xB1, 0x00, 0x50, 0x1D, 0x74,
+0xA7, 0x2E, 0xB1, 0x4B, 0xE0, 0x60, 0x09, 0x74,
+0xBB, 0x2E, 0x91, 0xF8, 0xE4, 0xF0, 0x80, 0x08,
+0x74, 0xBB, 0x2E, 0x91, 0xF8, 0x74, 0x01, 0xF0,
+0xB1, 0x1A, 0x80, 0xDF, 0x90, 0x82, 0xBB, 0xE0,
+0x70, 0x12, 0xA3, 0xE0, 0x70, 0x0E, 0xA3, 0xE0,
+0x70, 0x0A, 0xA3, 0xE0, 0x70, 0x06, 0xA3, 0xE0,
+0x70, 0x02, 0x61, 0xCE, 0xE4, 0x90, 0x82, 0x4A,
+0xF0, 0xB1, 0x00, 0x40, 0x02, 0x61, 0xCE, 0x12,
+0x75, 0x7E, 0x91, 0xF2, 0xE0, 0x60, 0x53, 0x90,
+0x82, 0x09, 0xE0, 0x30, 0xE0, 0x06, 0xC4, 0x54,
+0x0F, 0x30, 0xE0, 0x46, 0xB1, 0x66, 0x90, 0x04,
+0x1D, 0xE0, 0x60, 0x1B, 0xD3, 0x90, 0x82, 0xC1,
+0xE0, 0x94, 0x28, 0x90, 0x82, 0xC0, 0xE0, 0x94,
+0x00, 0x50, 0x0C, 0x7F, 0xFA, 0x7E, 0x00, 0x12,
+0x32, 0xAA, 0x12, 0x5C, 0x37, 0x80, 0xDF, 0x90,
+0x04, 0x1D, 0xE0, 0x70, 0x1D, 0xB1, 0x8D, 0x74,
+0x0A, 0xF0, 0xE4, 0xFB, 0xB1, 0x53, 0xB1, 0x26,
+0x94, 0x06, 0x50, 0x07, 0x91, 0xE5, 0x12, 0x5A,
+0x89, 0x80, 0xF3, 0x12, 0x62, 0x57, 0x90, 0x06,
+0x35, 0xF0, 0xB1, 0x1A, 0x80, 0x9B, 0x90, 0x82,
+0x4B, 0xE0, 0xB4, 0x01, 0x02, 0x80, 0x4F, 0x81,
+0xDE, 0x90, 0x82, 0x4B, 0xE0, 0xB4, 0x01, 0x0B,
+0x90, 0x80, 0xFC, 0x12, 0x55, 0x3A, 0x30, 0xE0,
+0x02, 0x80, 0x3B, 0x81, 0xDE, 0x90, 0x82, 0x48,
+0xE0, 0x70, 0x12, 0x90, 0x82, 0x4B, 0xE0, 0xB4,
+0x01, 0x0B, 0x90, 0x80, 0xFC, 0xE0, 0x13, 0x13,
+0x54, 0x3F, 0x20, 0xE0, 0x02, 0x81, 0xDE, 0x91,
+0xE5, 0xFD, 0x12, 0x5A, 0xB7, 0xEF, 0x60, 0x02,
+0x80, 0x14, 0x91, 0xE5, 0xFD, 0x12, 0x5A, 0x5F,
+0xEF, 0x60, 0x02, 0x80, 0x09, 0x91, 0xE5, 0xFD,
+0x12, 0x5A, 0x03, 0xEF, 0x60, 0x06, 0x12, 0x6F,
+0x12, 0x02, 0x77, 0x5D, 0x81, 0xDE, 0x90, 0x82,
+0x47, 0xE0, 0x24, 0xC0, 0x60, 0x02, 0x61, 0xDA,
+0x91, 0xE5, 0x24, 0x18, 0xFD, 0x12, 0x59, 0xD3,
+0xEF, 0x60, 0x02, 0x61, 0xCE, 0x91, 0xE5, 0x24,
+0x19, 0xFD, 0x12, 0x59, 0xD3, 0x90, 0x82, 0x60,
+0xB1, 0x5E, 0xB1, 0x21, 0x9F, 0x50, 0x0A, 0x91,
+0xE5, 0x12, 0x5B, 0x08, 0x12, 0x5A, 0xA3, 0x80,
+0xF1, 0x90, 0x82, 0x60, 0xE0, 0x70, 0x02, 0x61,
+0x31, 0xE4, 0x90, 0x82, 0x4A, 0xF0, 0xB1, 0x00,
+0x50, 0x5F, 0x12, 0x75, 0x7E, 0xB1, 0xA0, 0x70,
+0x1D, 0xB1, 0x6E, 0x12, 0x46, 0xEB, 0xC0, 0x03,
+0xC0, 0x02, 0xC0, 0x01, 0xB1, 0x2D, 0xED, 0xF0,
+0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x75,
+0xF0, 0xEF, 0x60, 0x02, 0x80, 0x26, 0x90, 0x82,
+0x60, 0xE0, 0x64, 0x03, 0x70, 0x29, 0xB1, 0x2D,
+0x12, 0x76, 0x3F, 0x70, 0x07, 0xB1, 0x2D, 0x12,
+0x76, 0x4A, 0x60, 0x17, 0xB1, 0x7D, 0x60, 0x02,
+0x80, 0x05, 0xB1, 0x44, 0xE0, 0x60, 0x05, 0x74,
+0xBB, 0x2F, 0x80, 0x0D, 0x91, 0xF2, 0x74, 0x01,
+0xF0, 0x80, 0x0A, 0xB1, 0x3D, 0x80, 0x02, 0xB1,
+0x3D, 0x91, 0xF8, 0xE4, 0xF0, 0xB1, 0x1A, 0x80,
+0x9D, 0x90, 0x82, 0xBB, 0xE0, 0x70, 0x4E, 0xA3,
+0xE0, 0x70, 0x4A, 0xA3, 0xE0, 0x70, 0x46, 0xA3,
+0xE0, 0x70, 0x42, 0xA3, 0xE0, 0x70, 0x3E, 0x61,
+0xCE, 0xE4, 0x90, 0x82, 0x4A, 0xF0, 0xB1, 0x00,
+0x50, 0x1D, 0x74, 0xA7, 0x2E, 0xB1, 0x4B, 0xE0,
+0x60, 0x09, 0x74, 0xBB, 0x2E, 0x91, 0xF8, 0xE4,
+0xF0, 0x80, 0x08, 0x74, 0xBB, 0x2E, 0x91, 0xF8,
+0x74, 0x01, 0xF0, 0xB1, 0x1A, 0x80, 0xDF, 0x90,
+0x82, 0xBB, 0xE0, 0x70, 0x10, 0xA3, 0xE0, 0x70,
+0x0C, 0xA3, 0xE0, 0x70, 0x08, 0xA3, 0xE0, 0x70,
+0x04, 0xA3, 0xE0, 0x60, 0x61, 0xE4, 0x90, 0x82,
+0x4A, 0xF0, 0xB1, 0x00, 0x50, 0x58, 0x12, 0x75,
+0x7E, 0x91, 0xF2, 0xE0, 0x60, 0x4C, 0x90, 0x82,
+0x09, 0xE0, 0x30, 0xE0, 0x06, 0xC4, 0x54, 0x0F,
+0x30, 0xE0, 0x3F, 0xB1, 0x66, 0x90, 0x04, 0x1D,
+0xE0, 0x60, 0x14, 0xD3, 0x90, 0x82, 0xC1, 0xE0,
+0x94, 0xE8, 0x90, 0x82, 0xC0, 0xE0, 0x94, 0x03,
+0x50, 0x05, 0x12, 0x5C, 0x37, 0x80, 0xE6, 0x90,
+0x04, 0x1D, 0xE0, 0x70, 0x1D, 0xB1, 0x8D, 0x74,
+0x06, 0xF0, 0x7B, 0x08, 0xB1, 0x53, 0xB1, 0x26,
+0x94, 0x06, 0x50, 0x07, 0x91, 0xE5, 0x12, 0x5A,
+0x89, 0x80, 0xF3, 0x12, 0x62, 0x57, 0x90, 0x06,
+0x35, 0xF0, 0xB1, 0x1A, 0x80, 0xA4, 0x12, 0x75,
+0x9E, 0x90, 0x06, 0x36, 0x74, 0xDD, 0xF0, 0x02,
+0x77, 0x5D, 0x90, 0x82, 0x48, 0xE0, 0x60, 0x02,
+0x81, 0xDE, 0x91, 0xE5, 0x24, 0x16, 0xFD, 0x12,
+0x59, 0xD3, 0x90, 0x06, 0x34, 0xEF, 0xF0, 0x91,
+0xE5, 0x24, 0x17, 0xFD, 0x12, 0x59, 0xD3, 0x90,
+0x06, 0x37, 0xB1, 0xC0, 0xB1, 0x00, 0x50, 0x34,
+0x12, 0x75, 0x7E, 0xE4, 0x90, 0x82, 0x49, 0xF0,
+0xB1, 0x26, 0x94, 0x06, 0x50, 0x22, 0x91, 0xE5,
+0x24, 0x04, 0x2D, 0x12, 0x5B, 0x00, 0xFE, 0x12,
+0x76, 0x23, 0x6F, 0x60, 0x0E, 0x74, 0xB6, 0x2E,
+0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0xE4,
+0xF0, 0x80, 0x05, 0x12, 0x5A, 0xA7, 0x80, 0xD8,
+0xB1, 0x1A, 0x80, 0xC8, 0x90, 0x82, 0xB6, 0xE0,
+0x64, 0x01, 0x60, 0x17, 0xA3, 0xE0, 0x64, 0x01,
+0x60, 0x11, 0xA3, 0xE0, 0x64, 0x01, 0x60, 0x0B,
+0xA3, 0xE0, 0x64, 0x01, 0x60, 0x05, 0xA3, 0xE0,
+0xB4, 0x01, 0x06, 0x90, 0x82, 0x4B, 0x74, 0x01,
+0xF0, 0x90, 0x82, 0x4B, 0xE0, 0x64, 0x01, 0x70,
+0x6E, 0x12, 0x6E, 0xD6, 0x12, 0x4F, 0xD1, 0x30,
+0xE0, 0x0D, 0xE0, 0xC3, 0x13, 0x30, 0xE0, 0x3F,
+0x90, 0x81, 0x2B, 0xE0, 0x30, 0xE0, 0x38, 0x12,
+0x6E, 0x74, 0x90, 0x81, 0x1E, 0xE0, 0x70, 0x03,
+0x02, 0x77, 0x5D, 0x90, 0x01, 0x3C, 0xE0, 0x30,
+0xE4, 0x03, 0x74, 0x10, 0xF0, 0x12, 0x73, 0xA1,
+0x90, 0x81, 0x1F, 0xE0, 0x60, 0x07, 0xF5, 0x2D,
+0xE4, 0xF5, 0x2E, 0x80, 0x25, 0x90, 0x81, 0x20,
+0xE0, 0x60, 0x08, 0xFB, 0xE4, 0xF5, 0x2D, 0xF5,
+0x2E, 0x80, 0x18, 0xB1, 0xB8, 0x80, 0x14, 0x90,
+0x01, 0x3C, 0xE0, 0x30, 0xE4, 0x03, 0x74, 0x10,
+0xF0, 0x12, 0x73, 0xA1, 0xE4, 0xF5, 0x2D, 0x75,
+0x2E, 0x9C, 0xFB, 0x7D, 0x01, 0x7F, 0x60, 0x7E,
+0x01, 0x12, 0x31, 0x21, 0x02, 0x77, 0x5D, 0x12,
+0x58, 0xC4, 0x90, 0x82, 0x4A, 0xF0, 0xB1, 0x00,
+0x50, 0x04, 0xB1, 0x0D, 0x80, 0xF8, 0x12, 0x75,
+0x9E, 0x02, 0x77, 0x5D, 0x22, 0x90, 0x82, 0x41,
+0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x82, 0x45,
+0xE0, 0x22, 0x90, 0x82, 0x4A, 0xE0, 0x24, 0xBB,
+0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0x22,
+0x90, 0x81, 0x07, 0xE0, 0xFF, 0x90, 0x82, 0x4A,
+0xE0, 0xFE, 0xC3, 0x9F, 0x22, 0x74, 0xB6, 0x2E,
+0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0x74,
+0x01, 0xF0, 0x90, 0x82, 0x4A, 0xE0, 0x04, 0xF0,
+0x22, 0x90, 0x82, 0x60, 0xE0, 0xFF, 0x90, 0x82,
+0x49, 0xE0, 0xFD, 0xC3, 0x22, 0x7B, 0x01, 0x7A,
+0x82, 0x79, 0x61, 0x90, 0x82, 0xC5, 0x12, 0x46,
+0xF4, 0x90, 0x82, 0xC8, 0x22, 0x90, 0x82, 0x4A,
+0xE0, 0x24, 0xBB, 0x22, 0x90, 0x82, 0x4A, 0xE0,
+0xFF, 0x24, 0xA7, 0xF5, 0x82, 0xE4, 0x34, 0x82,
+0xF5, 0x83, 0x22, 0x7D, 0x01, 0x12, 0x57, 0x19,
+0x90, 0x82, 0x43, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0,
+0xE4, 0x90, 0x82, 0x49, 0xF0, 0x22, 0xE4, 0x90,
+0x82, 0xC0, 0xF0, 0xA3, 0xF0, 0x22, 0xEF, 0x75,
+0xF0, 0x03, 0xA4, 0x24, 0x51, 0xF5, 0x82, 0xE4,
+0x34, 0x82, 0xF5, 0x83, 0x22, 0x90, 0x82, 0x4A,
+0xE0, 0xFF, 0x24, 0xAC, 0xF5, 0x82, 0xE4, 0x34,
+0x82, 0xF5, 0x83, 0xE0, 0x22, 0x90, 0x82, 0x4A,
+0xE0, 0x24, 0xA2, 0xF5, 0x82, 0xE4, 0x34, 0x82,
+0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x83, 0x1B, 0x22,
+0x90, 0x82, 0x4A, 0xE0, 0xFF, 0x24, 0x4C, 0xF5,
+0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0xE0, 0xFE,
+0x90, 0x82, 0x60, 0xE0, 0xFD, 0xEE, 0x6D, 0x22,
+0x75, 0x2D, 0x20, 0xE4, 0xF5, 0x2E, 0xFB, 0x22,
+0xEF, 0xF0, 0xE4, 0x90, 0x82, 0x4A, 0xF0, 0x22,
+0xE0, 0x24, 0x01, 0xFF, 0x90, 0x80, 0xFA, 0xE0,
+0x34, 0x00, 0xFE, 0xC3, 0x22, 0xEF, 0x30, 0xE7,
+0x04, 0x7E, 0x02, 0x80, 0x02, 0xE4, 0xFE, 0xED,
+0x30, 0xE6, 0x12, 0xEB, 0x20, 0xE0, 0x07, 0x90,
+0x81, 0x01, 0xE0, 0xFC, 0x80, 0x09, 0x90, 0x81,
+0x02, 0xE0, 0xFC, 0x80, 0x02, 0xE4, 0xFC, 0xEE,
+0x24, 0x18, 0x2C, 0xFF, 0x22, 0x90, 0x01, 0x57,
+0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0x22,
+0xF5, 0x83, 0xEF, 0xF0, 0x74, 0xB1, 0x2E, 0xF5,
+0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0xE0, 0x22,
+0x90, 0x81, 0xEF, 0xE0, 0x24, 0x01, 0xFF, 0x90,
+0x81, 0xEE, 0xE0, 0x34, 0x00, 0xFE, 0x12, 0x32,
+0xAA, 0x90, 0x81, 0x33, 0xE0, 0x22, 0xF0, 0x90,
+0x81, 0x3C, 0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0,
+0x22, 0x7D, 0x08, 0x7F, 0x02, 0x12, 0x56, 0x0B,
+0x90, 0x82, 0x1B, 0xE0, 0x04, 0xF0, 0x22, 0x54,
+0xFB, 0xF0, 0x90, 0x81, 0x34, 0xE0, 0x54, 0xFD,
+0xF0, 0x54, 0x07, 0x22, 0xE0, 0x90, 0x01, 0xBA,
+0xF0, 0x90, 0x81, 0x32, 0xE0, 0x90, 0x01, 0xBB,
+0x22, 0x12, 0x1F, 0xA4, 0xFE, 0x54, 0x04, 0xFD,
+0xEF, 0x54, 0xFB, 0x4D, 0xFF, 0x22, 0x74, 0x11,
+0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0xE0, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5,
+0x83, 0xE0, 0x22, 0xE0, 0x7C, 0x00, 0x24, 0x00,
+0xFF, 0xEC, 0x3E, 0x22, 0x90, 0x06, 0x0A, 0xE0,
+0x54, 0xF8, 0xF0, 0x22, 0x81, 0xA3
+};
+
+u32 array_length_mp_8188e_s_fw_ap = 16054;
+
+#endif /*defined(CONFIG_AP_WOWLAN) */
+
+u8 array_mp_8188e_s_fw_nic[] = {
+0xE3, 0x88, 0x10, 0x00, 0x1C, 0x00, 0x00, 0x00,
+0x05, 0x04, 0x22, 0x24, 0xE6, 0x4A, 0x02, 0x00,
+0xA5, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x48, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x49, 0x78, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x57, 0xFB, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x48, 0xEF, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x4F, 0xFD, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x06, 0x05,
+0x04, 0x03, 0x00, 0x04, 0x06, 0x05, 0x04, 0x02,
+0x00, 0x04, 0x08, 0x07, 0x06, 0x04, 0x00, 0x06,
+0x0A, 0x09, 0x08, 0x06, 0x00, 0x08, 0x0A, 0x09,
+0x08, 0x04, 0x00, 0x08, 0x0A, 0x09, 0x08, 0x02,
+0x00, 0x08, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x08,
+0x12, 0x11, 0x10, 0x08, 0x00, 0x10, 0x1A, 0x19,
+0x18, 0x10, 0x00, 0x18, 0x22, 0x21, 0x20, 0x18,
+0x00, 0x20, 0x22, 0x21, 0x20, 0x10, 0x00, 0x20,
+0x22, 0x21, 0x20, 0x08, 0x00, 0x20, 0x22, 0x21,
+0x1C, 0x08, 0x00, 0x20, 0x22, 0x21, 0x14, 0x08,
+0x00, 0x20, 0x22, 0x20, 0x18, 0x08, 0x00, 0x20,
+0x31, 0x30, 0x20, 0x10, 0x00, 0x30, 0x31, 0x30,
+0x18, 0x00, 0x00, 0x30, 0x31, 0x2F, 0x10, 0x10,
+0x00, 0x30, 0x31, 0x2C, 0x10, 0x10, 0x00, 0x30,
+0x31, 0x28, 0x10, 0x00, 0x00, 0x30, 0x31, 0x20,
+0x10, 0x00, 0x00, 0x30, 0x31, 0x10, 0x10, 0x00,
+0x00, 0x30, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04,
+0x05, 0x07, 0x07, 0x07, 0x08, 0x0A, 0x04, 0x04,
+0x04, 0x04, 0x06, 0x0A, 0x0B, 0x0D, 0x05, 0x05,
+0x07, 0x07, 0x08, 0x0B, 0x0D, 0x0F, 0x04, 0x04,
+0x04, 0x05, 0x07, 0x07, 0x09, 0x09, 0x0C, 0x0E,
+0x10, 0x12, 0x07, 0x07, 0x08, 0x08, 0x0B, 0x0F,
+0x10, 0x12, 0x09, 0x09, 0x09, 0x09, 0x0C, 0x0E,
+0x11, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x24, 0x26, 0x2A, 0x18, 0x1A,
+0x1D, 0x1F, 0x21, 0x27, 0x29, 0x2A, 0x00, 0x00,
+0x00, 0x1F, 0x23, 0x28, 0x2A, 0x2C, 0x00, 0x04,
+0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x18,
+0x00, 0x24, 0x00, 0x30, 0x00, 0x48, 0x00, 0x60,
+0x00, 0x90, 0x00, 0xC0, 0x00, 0xD8, 0x00, 0x50,
+0x00, 0x64, 0x00, 0xA0, 0x00, 0xDC, 0x01, 0x18,
+0x01, 0x90, 0x01, 0xE0, 0x02, 0x30, 0x01, 0x2C,
+0x01, 0x40, 0x01, 0xE0, 0x02, 0xD0, 0x03, 0xE8,
+0x04, 0xB0, 0x06, 0x40, 0x07, 0xD0, 0x00, 0x02,
+0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C,
+0x00, 0x12, 0x00, 0x18, 0x00, 0x24, 0x00, 0x30,
+0x00, 0x48, 0x00, 0x60, 0x00, 0x6C, 0x00, 0x28,
+0x00, 0x32, 0x00, 0x50, 0x00, 0x6E, 0x00, 0x8C,
+0x00, 0xC8, 0x00, 0xF0, 0x01, 0x18, 0x00, 0x64,
+0x00, 0xA0, 0x00, 0xF0, 0x01, 0x68, 0x01, 0xF4,
+0x02, 0x58, 0x03, 0x20, 0x03, 0xE8, 0x02, 0x02,
+0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04,
+0x05, 0x07, 0x04, 0x05, 0x08, 0x08, 0x0C, 0x0E,
+0x10, 0x12, 0x05, 0x07, 0x07, 0x08, 0x0B, 0x12,
+0x24, 0x3C, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02,
+0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x05, 0x06,
+0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x20, 0x1E,
+0x1C, 0x18, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xC2, 0xAF, 0x80, 0xFE, 0x32, 0x12, 0x43, 0x04,
+0x85, 0xD0, 0x0B, 0x75, 0xD0, 0x08, 0xAA, 0xE0,
+0xC2, 0x8C, 0xE5, 0x8A, 0x24, 0x67, 0xF5, 0x8A,
+0xE5, 0x8C, 0x34, 0x79, 0xF5, 0x8C, 0xD2, 0x8C,
+0xEC, 0x24, 0x87, 0xF8, 0xE6, 0xBC, 0x02, 0x02,
+0x74, 0xFF, 0xC3, 0x95, 0x81, 0xB4, 0x40, 0x00,
+0x40, 0xCE, 0x79, 0x03, 0x78, 0x80, 0x16, 0xE6,
+0x08, 0x70, 0x0B, 0xC2, 0xAF, 0xE6, 0x30, 0xE1,
+0x03, 0x44, 0x18, 0xF6, 0xD2, 0xAF, 0x08, 0xD9,
+0xED, 0xEA, 0x8B, 0xD0, 0x22, 0xE5, 0x0C, 0xFF,
+0x23, 0x24, 0x81, 0xF8, 0x0F, 0x08, 0x08, 0xBF,
+0x03, 0x04, 0x7F, 0x00, 0x78, 0x81, 0xE6, 0x30,
+0xE4, 0xF2, 0x00, 0xE5, 0x0C, 0xC3, 0x9F, 0x50,
+0x20, 0x05, 0x0C, 0x74, 0x86, 0x25, 0x0C, 0xF8,
+0xE6, 0xFD, 0xA6, 0x81, 0x08, 0xE6, 0xAE, 0x0C,
+0xBE, 0x02, 0x02, 0x74, 0xFF, 0xCD, 0xF8, 0xE8,
+0x6D, 0x60, 0xE0, 0x08, 0xE6, 0xC0, 0xE0, 0x80,
+0xF6, 0xE5, 0x0C, 0xD3, 0x9F, 0x40, 0x27, 0xE5,
+0x0C, 0x24, 0x87, 0xF8, 0xE6, 0xAE, 0x0C, 0xBE,
+0x02, 0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xCD,
+0xF8, 0xE5, 0x81, 0x6D, 0x60, 0x06, 0xD0, 0xE0,
+0xF6, 0x18, 0x80, 0xF5, 0xE5, 0x0C, 0x24, 0x86,
+0xC8, 0xF6, 0x15, 0x0C, 0x80, 0xD3, 0xE5, 0x0C,
+0x23, 0x24, 0x81, 0xF8, 0x7F, 0x04, 0xC2, 0xAF,
+0xE6, 0x30, 0xE0, 0x03, 0x10, 0xE2, 0x0C, 0x7F,
+0x00, 0x30, 0xE1, 0x07, 0x30, 0xE3, 0x04, 0x7F,
+0x08, 0x54, 0xF4, 0x54, 0x7C, 0xC6, 0xD2, 0xAF,
+0x54, 0x80, 0x42, 0x07, 0x22, 0x78, 0x86, 0xA6,
+0x81, 0x74, 0x02, 0x60, 0x06, 0xFF, 0x08, 0x76,
+0xFF, 0xDF, 0xFB, 0x7F, 0x03, 0xE4, 0x78, 0x80,
+0xF6, 0x08, 0xF6, 0x08, 0xDF, 0xFA, 0x78, 0x81,
+0x76, 0x30, 0x90, 0x48, 0xE9, 0x74, 0x01, 0x93,
+0xC0, 0xE0, 0xE4, 0x93, 0xC0, 0xE0, 0x43, 0x89,
+0x01, 0x75, 0x8A, 0x60, 0x75, 0x8C, 0x79, 0xD2,
+0x8C, 0xD2, 0xAF, 0x22, 0x02, 0xEF, 0xD3, 0x94,
+0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0x74, 0x81,
+0x2F, 0x2F, 0xF8, 0xE6, 0x20, 0xE5, 0xF4, 0xC2,
+0xAF, 0xE6, 0x44, 0x30, 0xF6, 0xD2, 0xAF, 0xAE,
+0x0C, 0xEE, 0xC3, 0x9F, 0x50, 0x21, 0x0E, 0x74,
+0x86, 0x2E, 0xF8, 0xE6, 0xF9, 0x08, 0xE6, 0x18,
+0xBE, 0x02, 0x02, 0x74, 0xFF, 0xFD, 0xED, 0x69,
+0x60, 0x09, 0x09, 0xE7, 0x19, 0x19, 0xF7, 0x09,
+0x09, 0x80, 0xF3, 0x16, 0x16, 0x80, 0xDA, 0xEE,
+0xD3, 0x9F, 0x40, 0x04, 0x05, 0x81, 0x05, 0x81,
+0xEE, 0xD3, 0x9F, 0x40, 0x22, 0x74, 0x86, 0x2E,
+0xF8, 0x08, 0xE6, 0xF9, 0xEE, 0xB5, 0x0C, 0x02,
+0xA9, 0x81, 0x18, 0x06, 0x06, 0xE6, 0xFD, 0xED,
+0x69, 0x60, 0x09, 0x19, 0x19, 0xE7, 0x09, 0x09,
+0xF7, 0x19, 0x80, 0xF3, 0x1E, 0x80, 0xD9, 0xEF,
+0x24, 0x86, 0xF8, 0xE6, 0x04, 0xF8, 0xEF, 0x2F,
+0x04, 0x90, 0x48, 0xE9, 0x93, 0xF6, 0x08, 0xEF,
+0x2F, 0x93, 0xF6, 0x7F, 0x00, 0x22, 0xEF, 0xD3,
+0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0xEF,
+0x23, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE5, 0xF4,
+0xC2, 0xAF, 0xE6, 0x54, 0x8C, 0xF6, 0xD2, 0xAF,
+0xE5, 0x0C, 0xB5, 0x07, 0x0A, 0x74, 0x86, 0x2F,
+0xF8, 0xE6, 0xF5, 0x81, 0x02, 0x43, 0x4D, 0x50,
+0x2E, 0x74, 0x87, 0x2F, 0xF8, 0xE6, 0xBF, 0x02,
+0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xF9, 0x74,
+0x86, 0x2F, 0xF8, 0xFB, 0xE6, 0xFC, 0xE9, 0x6C,
+0x60, 0x08, 0xA8, 0x05, 0xE7, 0xF6, 0x1D, 0x19,
+0x80, 0xF4, 0xA8, 0x03, 0xA6, 0x05, 0x1F, 0xE5,
+0x0C, 0xB5, 0x07, 0xE3, 0x7F, 0x00, 0x22, 0x74,
+0x87, 0x2F, 0xF8, 0xE6, 0xFD, 0x18, 0x86, 0x01,
+0x0F, 0x74, 0x86, 0x2F, 0xF8, 0xA6, 0x01, 0x08,
+0x86, 0x04, 0xE5, 0x0C, 0xB5, 0x07, 0x02, 0xAC,
+0x81, 0xED, 0x6C, 0x60, 0x08, 0x0D, 0x09, 0xA8,
+0x05, 0xE6, 0xF7, 0x80, 0xF4, 0xE5, 0x0C, 0xB5,
+0x07, 0xDE, 0x89, 0x81, 0x7F, 0x00, 0x22, 0xEF,
+0xD3, 0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22,
+0xEF, 0x23, 0x24, 0x81, 0xF8, 0xC2, 0xAF, 0xE6,
+0x30, 0xE5, 0x05, 0x30, 0xE0, 0x02, 0xD2, 0xE4,
+0xD2, 0xE2, 0xC6, 0xD2, 0xAF, 0x7F, 0x00, 0x30,
+0xE2, 0x01, 0x0F, 0x02, 0x43, 0x4C, 0x8F, 0xF0,
+0xE4, 0xFF, 0xFE, 0xE5, 0x0C, 0x23, 0x24, 0x80,
+0xF8, 0xC2, 0xA9, 0x30, 0xF7, 0x0D, 0x7F, 0x08,
+0xE6, 0x60, 0x0B, 0x2D, 0xF6, 0x60, 0x30, 0x50,
+0x2E, 0x80, 0x07, 0x30, 0xF1, 0x06, 0xED, 0xF6,
+0x60, 0x25, 0x7E, 0x02, 0x08, 0x30, 0xF0, 0x10,
+0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x23, 0x0E, 0x30,
+0xE2, 0x0C, 0xD2, 0xAF, 0x7F, 0x04, 0x80, 0x12,
+0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x13, 0x54, 0xEC,
+0x4E, 0xF6, 0xD2, 0xAF, 0x02, 0x43, 0x4D, 0x7F,
+0x08, 0x08, 0xEF, 0x44, 0x83, 0xF4, 0xC2, 0xAF,
+0x56, 0xC6, 0xD2, 0xAF, 0x54, 0x80, 0x4F, 0xFF,
+0x22, 0xE7, 0x09, 0xF6, 0x08, 0xDF, 0xFA, 0x80,
+0x46, 0xE7, 0x09, 0xF2, 0x08, 0xDF, 0xFA, 0x80,
+0x3E, 0x88, 0x82, 0x8C, 0x83, 0xE7, 0x09, 0xF0,
+0xA3, 0xDF, 0xFA, 0x80, 0x32, 0xE3, 0x09, 0xF6,
+0x08, 0xDF, 0xFA, 0x80, 0x78, 0xE3, 0x09, 0xF2,
+0x08, 0xDF, 0xFA, 0x80, 0x70, 0x88, 0x82, 0x8C,
+0x83, 0xE3, 0x09, 0xF0, 0xA3, 0xDF, 0xFA, 0x80,
+0x64, 0x89, 0x82, 0x8A, 0x83, 0xE0, 0xA3, 0xF6,
+0x08, 0xDF, 0xFA, 0x80, 0x58, 0x89, 0x82, 0x8A,
+0x83, 0xE0, 0xA3, 0xF2, 0x08, 0xDF, 0xFA, 0x80,
+0x4C, 0x80, 0xD2, 0x80, 0xFA, 0x80, 0xC6, 0x80,
+0xD4, 0x80, 0x69, 0x80, 0xF2, 0x80, 0x33, 0x80,
+0x10, 0x80, 0xA6, 0x80, 0xEA, 0x80, 0x9A, 0x80,
+0xA8, 0x80, 0xDA, 0x80, 0xE2, 0x80, 0xCA, 0x80,
+0x33, 0x89, 0x82, 0x8A, 0x83, 0xEC, 0xFA, 0xE4,
+0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC, 0xC5,
+0x83, 0xCC, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8,
+0xCC, 0xC5, 0x83, 0xCC, 0xDF, 0xE9, 0xDE, 0xE7,
+0x80, 0x0D, 0x89, 0x82, 0x8A, 0x83, 0xE4, 0x93,
+0xA3, 0xF6, 0x08, 0xDF, 0xF9, 0xEC, 0xFA, 0xA9,
+0xF0, 0xED, 0xFB, 0x22, 0x89, 0x82, 0x8A, 0x83,
+0xEC, 0xFA, 0xE0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8,
+0xCC, 0xC5, 0x83, 0xCC, 0xF0, 0xA3, 0xC8, 0xC5,
+0x82, 0xC8, 0xCC, 0xC5, 0x83, 0xCC, 0xDF, 0xEA,
+0xDE, 0xE8, 0x80, 0xDB, 0x89, 0x82, 0x8A, 0x83,
+0xE4, 0x93, 0xA3, 0xF2, 0x08, 0xDF, 0xF9, 0x80,
+0xCC, 0x88, 0xF0, 0xEF, 0x60, 0x01, 0x0E, 0x4E,
+0x60, 0xC3, 0x88, 0xF0, 0xED, 0x24, 0x02, 0xB4,
+0x04, 0x00, 0x50, 0xB9, 0xF5, 0x82, 0xEB, 0x24,
+0x02, 0xB4, 0x04, 0x00, 0x50, 0xAF, 0x23, 0x23,
+0x45, 0x82, 0x23, 0x90, 0x45, 0xF9, 0x73, 0xC5,
+0xF0, 0xF8, 0xA3, 0xE0, 0x28, 0xF0, 0xC5, 0xF0,
+0xF8, 0xE5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15,
+0x83, 0xE0, 0x38, 0xF0, 0x22, 0xBB, 0x01, 0x0A,
+0x89, 0x82, 0x8A, 0x83, 0xE0, 0xF5, 0xF0, 0xA3,
+0xE0, 0x22, 0x50, 0x06, 0x87, 0xF0, 0x09, 0xE7,
+0x19, 0x22, 0xBB, 0xFE, 0x07, 0xE3, 0xF5, 0xF0,
+0x09, 0xE3, 0x19, 0x22, 0x89, 0x82, 0x8A, 0x83,
+0xE4, 0x93, 0xF5, 0xF0, 0x74, 0x01, 0x93, 0x22,
+0xBB, 0x01, 0x10, 0xE5, 0x82, 0x29, 0xF5, 0x82,
+0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE0, 0xF5, 0xF0,
+0xA3, 0xE0, 0x22, 0x50, 0x09, 0xE9, 0x25, 0x82,
+0xF8, 0x86, 0xF0, 0x08, 0xE6, 0x22, 0xBB, 0xFE,
+0x0A, 0xE9, 0x25, 0x82, 0xF8, 0xE2, 0xF5, 0xF0,
+0x08, 0xE2, 0x22, 0xE5, 0x83, 0x2A, 0xF5, 0x83,
+0xE9, 0x93, 0xF5, 0xF0, 0xA3, 0xE9, 0x93, 0x22,
+0xBB, 0x01, 0x0A, 0x89, 0x82, 0x8A, 0x83, 0xF0,
+0xE5, 0xF0, 0xA3, 0xF0, 0x22, 0x50, 0x06, 0xF7,
+0x09, 0xA7, 0xF0, 0x19, 0x22, 0xBB, 0xFE, 0x06,
+0xF3, 0xE5, 0xF0, 0x09, 0xF3, 0x19, 0x22, 0xF8,
+0xBB, 0x01, 0x11, 0xE5, 0x82, 0x29, 0xF5, 0x82,
+0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE8, 0xF0, 0xE5,
+0xF0, 0xA3, 0xF0, 0x22, 0x50, 0x09, 0xE9, 0x25,
+0x82, 0xC8, 0xF6, 0x08, 0xA6, 0xF0, 0x22, 0xBB,
+0xFE, 0x09, 0xE9, 0x25, 0x82, 0xC8, 0xF2, 0xE5,
+0xF0, 0x08, 0xF2, 0x22, 0xC3, 0xEF, 0x9B, 0xFF,
+0xEE, 0x9A, 0xFE, 0xED, 0x99, 0xFD, 0xEC, 0x98,
+0xFC, 0x22, 0xEF, 0x5B, 0xFF, 0xEE, 0x5A, 0xFE,
+0xED, 0x59, 0xFD, 0xEC, 0x58, 0xFC, 0x22, 0xEF,
+0x4B, 0xFF, 0xEE, 0x4A, 0xFE, 0xED, 0x49, 0xFD,
+0xEC, 0x48, 0xFC, 0x22, 0xEB, 0x9F, 0xF5, 0xF0,
+0xEA, 0x9E, 0x42, 0xF0, 0xE9, 0x9D, 0x42, 0xF0,
+0xE8, 0x9C, 0x45, 0xF0, 0x22, 0xE0, 0xFC, 0xA3,
+0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
+0x22, 0xE2, 0xFC, 0x08, 0xE2, 0xFD, 0x08, 0xE2,
+0xFE, 0x08, 0xE2, 0xFF, 0x22, 0xE0, 0xF8, 0xA3,
+0xE0, 0xF9, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xFB,
+0x22, 0xE2, 0xFB, 0x08, 0xE2, 0xF9, 0x08, 0xE2,
+0xFA, 0x08, 0xE2, 0xCB, 0xF8, 0x22, 0xEC, 0xF2,
+0x08, 0xED, 0xF2, 0x08, 0xEE, 0xF2, 0x08, 0xEF,
+0xF2, 0x22, 0xA4, 0x25, 0x82, 0xF5, 0x82, 0xE5,
+0xF0, 0x35, 0x83, 0xF5, 0x83, 0x22, 0xE0, 0xFB,
+0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xF9, 0x22, 0xEB,
+0xF0, 0xA3, 0xEA, 0xF0, 0xA3, 0xE9, 0xF0, 0x22,
+0xD0, 0x83, 0xD0, 0x82, 0xF8, 0xE4, 0x93, 0x70,
+0x12, 0x74, 0x01, 0x93, 0x70, 0x0D, 0xA3, 0xA3,
+0x93, 0xF8, 0x74, 0x01, 0x93, 0xF5, 0x82, 0x88,
+0x83, 0xE4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60,
+0xEF, 0xA3, 0xA3, 0xA3, 0x80, 0xDF, 0xEF, 0x4E,
+0x60, 0x12, 0xEF, 0x60, 0x01, 0x0E, 0xED, 0xBB,
+0x01, 0x0B, 0x89, 0x82, 0x8A, 0x83, 0xF0, 0xA3,
+0xDF, 0xFC, 0xDE, 0xFA, 0x22, 0x89, 0xF0, 0x50,
+0x07, 0xF7, 0x09, 0xDF, 0xFC, 0xA9, 0xF0, 0x22,
+0xBB, 0xFE, 0xFC, 0xF3, 0x09, 0xDF, 0xFC, 0xA9,
+0xF0, 0x22, 0x02, 0x48, 0x88, 0x02, 0x43, 0xDD,
+0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0x40,
+0x03, 0xF6, 0x80, 0x01, 0xF2, 0x08, 0xDF, 0xF4,
+0x80, 0x29, 0xE4, 0x93, 0xA3, 0xF8, 0x54, 0x07,
+0x24, 0x0C, 0xC8, 0xC3, 0x33, 0xC4, 0x54, 0x0F,
+0x44, 0x20, 0xC8, 0x83, 0x40, 0x04, 0xF4, 0x56,
+0x80, 0x01, 0x46, 0xF6, 0xDF, 0xE4, 0x80, 0x0B,
+0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+0x90, 0x48, 0xCD, 0xE4, 0x7E, 0x01, 0x93, 0x60,
+0xBC, 0xA3, 0xFF, 0x54, 0x3F, 0x30, 0xE5, 0x09,
+0x54, 0x1F, 0xFE, 0xE4, 0x93, 0xA3, 0x60, 0x01,
+0x0E, 0xCF, 0x54, 0xC0, 0x25, 0xE0, 0x60, 0xA8,
+0x40, 0xB8, 0xE4, 0x93, 0xA3, 0xFA, 0xE4, 0x93,
+0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0xC8, 0xC5, 0x82,
+0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xF0, 0xA3, 0xC8,
+0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xDF,
+0xE9, 0xDE, 0xE7, 0x80, 0xBE, 0x41, 0x83, 0x68,
+0x00, 0x41, 0x83, 0x69, 0x00, 0x48, 0x95, 0x43,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x41, 0x83, 0x73, 0x00, 0x41, 0x83, 0x75, 0x00,
+0x00, 0x68, 0xC7, 0x6F, 0xF0, 0x77, 0xDF, 0xC0,
+0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0,
+0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01,
+0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05,
+0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74,
+0xEF, 0xF0, 0x74, 0x48, 0xA3, 0xF0, 0x31, 0x3E,
+0x74, 0xEF, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74,
+0x48, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0,
+0x05, 0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0,
+0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0,
+0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x90, 0x00,
+0x54, 0xE0, 0x55, 0x35, 0xF5, 0x39, 0xA3, 0xE0,
+0x55, 0x36, 0xF5, 0x3A, 0xA3, 0xE0, 0x55, 0x37,
+0xF5, 0x3B, 0xA3, 0xE0, 0x55, 0x38, 0xF5, 0x3C,
+0xAD, 0x39, 0x7F, 0x54, 0x12, 0x32, 0x1E, 0xAD,
+0x3A, 0x7F, 0x55, 0x12, 0x32, 0x1E, 0xAD, 0x3B,
+0x7F, 0x56, 0x12, 0x32, 0x1E, 0xAD, 0x3C, 0x7F,
+0x57, 0x12, 0x32, 0x1E, 0x53, 0x91, 0xEF, 0x22,
+0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82,
+0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0,
+0x01, 0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0,
+0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4,
+0x74, 0x78, 0xF0, 0x74, 0x49, 0xA3, 0xF0, 0x12,
+0x84, 0x73, 0xE5, 0x41, 0x30, 0xE4, 0x03, 0x12,
+0x7A, 0x25, 0xE5, 0x41, 0x30, 0xE6, 0x03, 0x12,
+0x85, 0x0C, 0xE5, 0x43, 0x30, 0xE0, 0x03, 0x12,
+0x7D, 0x76, 0xE5, 0x43, 0x30, 0xE1, 0x02, 0x51,
+0x1F, 0xE5, 0x43, 0x30, 0xE2, 0x03, 0x12, 0x82,
+0x24, 0xE5, 0x43, 0x30, 0xE3, 0x03, 0x12, 0x6A,
+0xA9, 0xE5, 0x43, 0x30, 0xE4, 0x03, 0x12, 0x6A,
+0xC8, 0xE5, 0x43, 0x30, 0xE5, 0x03, 0x12, 0x6F,
+0x9B, 0xE5, 0x43, 0x30, 0xE6, 0x03, 0x12, 0x6C,
+0x10, 0xE5, 0x44, 0x30, 0xE1, 0x03, 0x12, 0x81,
+0x21, 0xE5, 0x44, 0x30, 0xE5, 0x03, 0x12, 0x7C,
+0x2D, 0x74, 0x78, 0x04, 0x90, 0x01, 0xC4, 0xF0,
+0x74, 0x49, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06,
+0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02,
+0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82,
+0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x90,
+0x81, 0x83, 0xE0, 0x30, 0xE0, 0x06, 0x90, 0x81,
+0x85, 0x74, 0x01, 0xF0, 0x90, 0x81, 0x8D, 0xE0,
+0x70, 0x02, 0x41, 0xCB, 0x90, 0x81, 0xA4, 0xE0,
+0x04, 0xF0, 0x90, 0x05, 0x61, 0x71, 0x11, 0x78,
+0x08, 0x12, 0x74, 0x5C, 0x90, 0x05, 0x60, 0x71,
+0x11, 0x12, 0x47, 0x7F, 0xC0, 0x04, 0xC0, 0x05,
+0xC0, 0x06, 0xC0, 0x07, 0x90, 0x05, 0x62, 0x71,
+0x11, 0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0, 0x03,
+0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x47,
+0x7F, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0,
+0x07, 0xA3, 0x71, 0x11, 0x78, 0x18, 0x12, 0x20,
+0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0,
+0x00, 0x12, 0x47, 0x7F, 0x90, 0x82, 0x4D, 0x12,
+0x20, 0xCE, 0x90, 0x81, 0x89, 0xE0, 0x54, 0x7F,
+0xF0, 0xA3, 0xE0, 0x30, 0xE0, 0x0C, 0x12, 0x85,
+0x63, 0x74, 0x05, 0xF0, 0x12, 0x5B, 0x02, 0x12,
+0x8A, 0x9E, 0x90, 0x81, 0x89, 0x12, 0x5A, 0xE1,
+0x30, 0xE0, 0x09, 0x90, 0x01, 0x3B, 0xE0, 0x30,
+0xE4, 0x02, 0xB1, 0xC8, 0x90, 0x83, 0x6E, 0xE0,
+0x04, 0xF0, 0xE0, 0xC3, 0x94, 0x80, 0x40, 0x0B,
+0x90, 0x01, 0x98, 0xE0, 0x54, 0xFE, 0xF0, 0xE0,
+0x44, 0x01, 0xF0, 0x7F, 0x01, 0x12, 0x7A, 0x29,
+0x12, 0x88, 0xBD, 0x90, 0x82, 0x6E, 0xE0, 0x30,
+0xE0, 0x09, 0x90, 0x01, 0x3B, 0xE0, 0x30, 0xE4,
+0x02, 0xB1, 0xC8, 0x22, 0x90, 0x82, 0xA3, 0xE0,
+0x24, 0xB5, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5,
+0x83, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78,
+0x08, 0x12, 0x20, 0xBB, 0xA8, 0x04, 0xA9, 0x05,
+0xAA, 0x06, 0xAB, 0x07, 0x90, 0x82, 0xA3, 0xE0,
+0x24, 0xB4, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5,
+0x83, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x22,
+0xE4, 0x90, 0x82, 0xA3, 0xF0, 0x90, 0x87, 0x5F,
+0xE0, 0x90, 0x82, 0xA2, 0xF0, 0xE4, 0x90, 0x82,
+0xAF, 0xF0, 0x90, 0x82, 0x9F, 0xF0, 0x90, 0x82,
+0x9F, 0xE0, 0xFF, 0xC3, 0x94, 0x40, 0x50, 0x11,
+0x74, 0xB2, 0x2F, 0x12, 0x8A, 0xDC, 0x74, 0xFF,
+0xF0, 0x90, 0x82, 0x9F, 0xE0, 0x04, 0xF0, 0x80,
+0xE5, 0xE4, 0x90, 0x82, 0x9F, 0xF0, 0x90, 0x82,
+0xA2, 0xE0, 0xFF, 0x90, 0x82, 0x9F, 0xE0, 0xFE,
+0xC3, 0x9F, 0x40, 0x02, 0x81, 0x19, 0x74, 0xDF,
+0x2E, 0xF9, 0xE4, 0x34, 0x86, 0xB1, 0xFC, 0x75,
+0x16, 0x0A, 0x7B, 0x01, 0x7A, 0x82, 0x79, 0x94,
+0x12, 0x2B, 0xED, 0x90, 0x82, 0x95, 0xE0, 0xFF,
+0x12, 0x2F, 0x27, 0xEF, 0x04, 0x90, 0x82, 0xAF,
+0xF0, 0x90, 0x82, 0x94, 0xE0, 0xFF, 0xA3, 0xE0,
+0xFD, 0x12, 0x31, 0xEA, 0xEF, 0x24, 0xC8, 0x90,
+0x82, 0xB1, 0xF0, 0x75, 0xF0, 0x08, 0xA4, 0xF0,
+0x90, 0x82, 0x95, 0xE0, 0x54, 0x0F, 0x90, 0x82,
+0xB0, 0xF0, 0xE4, 0x90, 0x82, 0x9E, 0xF0, 0x90,
+0x82, 0xA0, 0xF0, 0x90, 0x82, 0xA0, 0xE0, 0xFF,
+0xC3, 0x94, 0x04, 0x50, 0x57, 0x90, 0x82, 0xB0,
+0xE0, 0xFE, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3,
+0x13, 0xD8, 0xFC, 0x20, 0xE0, 0x3E, 0x90, 0x82,
+0xA0, 0xE0, 0x25, 0xE0, 0xFF, 0x90, 0x82, 0xB1,
+0xE0, 0x2F, 0x24, 0xB2, 0xF9, 0xE4, 0x34, 0x82,
+0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x01, 0x90,
+0x82, 0x9E, 0xE0, 0x75, 0xF0, 0x02, 0xA4, 0x24,
+0x96, 0xF9, 0x74, 0x82, 0x35, 0xF0, 0x8B, 0x13,
+0xF5, 0x14, 0x89, 0x15, 0x75, 0x16, 0x02, 0xD0,
+0x01, 0xD0, 0x03, 0x12, 0x2B, 0xED, 0x90, 0x82,
+0x9E, 0xE0, 0x04, 0xF0, 0x90, 0x82, 0xA0, 0xE0,
+0x04, 0xF0, 0x80, 0x9F, 0x90, 0x82, 0xAF, 0xE0,
+0xFF, 0x90, 0x82, 0x9F, 0xE0, 0x2F, 0xF0, 0x61,
+0x4E, 0xE4, 0x90, 0x82, 0xA3, 0xF0, 0x90, 0x82,
+0xA3, 0xE0, 0xC3, 0x94, 0x40, 0x40, 0x02, 0xA1,
+0xC7, 0xE0, 0xFF, 0x24, 0xB2, 0x12, 0x8A, 0xDC,
+0xE0, 0x90, 0x82, 0xA5, 0xF0, 0xE0, 0xFE, 0x54,
+0xF0, 0xC4, 0x54, 0x0F, 0xFD, 0x90, 0x82, 0xA4,
+0xF0, 0xEE, 0x54, 0x0F, 0xFE, 0xA3, 0xF0, 0x74,
+0xB3, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5,
+0x83, 0xE0, 0x90, 0x82, 0xA6, 0xF0, 0xFC, 0xEE,
+0xFE, 0xEC, 0xFB, 0xEB, 0xFF, 0x90, 0x82, 0xAB,
+0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xED, 0x12, 0x47,
+0xF8, 0x4C, 0x8E, 0x00, 0x4C, 0xC0, 0x01, 0x4D,
+0x2E, 0x02, 0x4D, 0xB8, 0x03, 0x4D, 0x39, 0x04,
+0x4D, 0x4A, 0x05, 0x4D, 0x4A, 0x06, 0x4D, 0x4A,
+0x07, 0x4D, 0x4A, 0x08, 0x4D, 0x93, 0x09, 0x4D,
+0xA5, 0x0A, 0x00, 0x00, 0x4D, 0xC7, 0x90, 0x82,
+0xA3, 0xE0, 0xFD, 0x24, 0xB5, 0xF5, 0x82, 0xE4,
+0x34, 0x82, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0xB4,
+0x2D, 0xB1, 0xE9, 0xE0, 0xFD, 0xED, 0xFF, 0x90,
+0x82, 0xAD, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF, 0xF0,
+0x90, 0x82, 0xA6, 0xE0, 0xFF, 0x12, 0x2F, 0x96,
+0x90, 0x82, 0xA1, 0x74, 0x02, 0xF0, 0xA1, 0xB8,
+0x51, 0xE4, 0x12, 0x47, 0x7F, 0xC0, 0x04, 0xC0,
+0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x82, 0xA3,
+0xE0, 0x24, 0xB6, 0xF5, 0x82, 0xE4, 0x34, 0x82,
+0x71, 0x0F, 0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12,
+0x47, 0x7F, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06,
+0xC0, 0x07, 0x90, 0x82, 0xA3, 0xE0, 0x24, 0xB7,
+0xF5, 0x82, 0xE4, 0x34, 0x82, 0x71, 0x0F, 0x78,
+0x18, 0x12, 0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02,
+0xD0, 0x01, 0xD0, 0x00, 0x12, 0x8A, 0x85, 0x90,
+0x82, 0xA7, 0x12, 0x47, 0x9D, 0x90, 0x85, 0x96,
+0x12, 0x20, 0xCE, 0x90, 0x82, 0xAB, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0x12, 0x2E, 0xE4, 0x90, 0x82,
+0xA1, 0x74, 0x04, 0xF0, 0xA1, 0xB8, 0xB1, 0xDE,
+0xE0, 0xFB, 0xE4, 0xFF, 0x12, 0x30, 0xC7, 0x80,
+0x09, 0xB1, 0xDE, 0xE0, 0xFB, 0xE4, 0xFF, 0x12,
+0x30, 0x6A, 0x90, 0x82, 0xA1, 0x74, 0x01, 0xF0,
+0x80, 0x6E, 0x90, 0x82, 0xA1, 0x74, 0x02, 0xF0,
+0x51, 0xE4, 0x12, 0x47, 0x7F, 0xC0, 0x04, 0xC0,
+0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x82, 0xA5,
+0x71, 0x11, 0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12,
+0x8A, 0x85, 0x90, 0x82, 0xA4, 0xE0, 0x24, 0xFB,
+0xFF, 0xC0, 0x07, 0x90, 0x82, 0xA7, 0x12, 0x47,
+0x9D, 0x90, 0x83, 0x42, 0x12, 0x20, 0xCE, 0x90,
+0x82, 0xA6, 0xE0, 0xFD, 0xD0, 0x07, 0x12, 0x77,
+0x52, 0x80, 0x25, 0x90, 0x82, 0xA1, 0x74, 0x01,
+0xB1, 0xF1, 0x75, 0x16, 0x01, 0x12, 0x89, 0x7E,
+0xF0, 0x7B, 0x04, 0x80, 0x10, 0x90, 0x82, 0xA1,
+0x74, 0x04, 0xB1, 0xF1, 0x75, 0x16, 0x04, 0x12,
+0x89, 0x7E, 0xF0, 0x7B, 0x06, 0x12, 0x75, 0x7C,
+0x90, 0x82, 0xA1, 0xE0, 0x24, 0x02, 0xFF, 0x90,
+0x82, 0xA3, 0xE0, 0x2F, 0xF0, 0x81, 0x1E, 0x22,
+0x7D, 0x02, 0x7F, 0x02, 0xB1, 0xD2, 0x7D, 0x01,
+0x7F, 0x02, 0x74, 0x3D, 0x12, 0x8A, 0xBE, 0xFE,
+0xF6, 0x74, 0x30, 0x02, 0x6E, 0x33, 0x90, 0x82,
+0xA6, 0xE0, 0xFD, 0x90, 0x82, 0xA3, 0xE0, 0x24,
+0xB4, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83,
+0x22, 0xF0, 0x90, 0x82, 0xA3, 0xE0, 0x24, 0xB4,
+0xF9, 0xE4, 0x34, 0x82, 0x75, 0x13, 0x01, 0xF5,
+0x14, 0x89, 0x15, 0x22, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x8B, 0x56, 0x8A, 0x57, 0x89,
+0x58, 0x90, 0x05, 0x27, 0xE0, 0xF5, 0x59, 0x8B,
+0x13, 0x8A, 0x14, 0x89, 0x15, 0x75, 0x16, 0x01,
+0x7B, 0x01, 0x7A, 0x81, 0x79, 0x83, 0x12, 0x2B,
+0xED, 0x12, 0x8A, 0x7C, 0xFF, 0xC3, 0x13, 0x20,
+0xE0, 0x02, 0xC1, 0xC4, 0x90, 0x81, 0x83, 0xE0,
+0x30, 0xE0, 0x77, 0x12, 0x6E, 0x3E, 0x75, 0x59,
+0x21, 0x90, 0x81, 0x83, 0xE0, 0x13, 0x13, 0x54,
+0x3F, 0x30, 0xE0, 0x05, 0x12, 0x89, 0xD2, 0x80,
+0x0C, 0xE4, 0x90, 0x81, 0x84, 0xF0, 0xA3, 0xF0,
+0x7D, 0x40, 0xFF, 0xB1, 0xD2, 0x12, 0x8A, 0xD4,
+0x13, 0x54, 0x1F, 0x30, 0xE0, 0x03, 0x43, 0x59,
+0x12, 0xEF, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x03,
+0x43, 0x59, 0x14, 0x90, 0x81, 0x83, 0xE0, 0xC4,
+0x13, 0x54, 0x07, 0x30, 0xE0, 0x03, 0x43, 0x59,
+0x80, 0x12, 0x89, 0xFE, 0x20, 0xE0, 0x03, 0x43,
+0x59, 0x40, 0xF1, 0x76, 0x90, 0x81, 0x86, 0xE0,
+0x70, 0x05, 0x7F, 0x01, 0x12, 0x7D, 0xC6, 0x12,
+0x80, 0xE3, 0x30, 0xE0, 0x04, 0x7F, 0x04, 0x80,
+0x0C, 0x12, 0x6B, 0x88, 0xEF, 0x60, 0x04, 0x7F,
+0x01, 0x80, 0x02, 0x7F, 0x02, 0x12, 0x7D, 0xC6,
+0xE1, 0x3D, 0xF1, 0x73, 0x90, 0x81, 0x86, 0xE0,
+0x64, 0x04, 0x60, 0x02, 0xE1, 0x6E, 0xFF, 0x12,
+0x7D, 0xC6, 0xE1, 0x6E, 0x90, 0x81, 0x83, 0xE0,
+0x30, 0xE0, 0x7A, 0x12, 0x6E, 0x3E, 0x43, 0x59,
+0x31, 0x90, 0x81, 0x83, 0xE0, 0x13, 0x13, 0x54,
+0x3F, 0x30, 0xE0, 0x05, 0x12, 0x89, 0xD2, 0x80,
+0x06, 0x7D, 0x40, 0xE4, 0xFF, 0xB1, 0xD2, 0x12,
+0x8A, 0xD4, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x03,
+0x43, 0x59, 0x02, 0xEF, 0xC4, 0x54, 0x0F, 0x30,
+0xE0, 0x03, 0x43, 0x59, 0x04, 0xF1, 0x76, 0x12,
+0x80, 0xE3, 0x30, 0xE0, 0x0B, 0x12, 0x81, 0x05,
+0x60, 0x33, 0xE4, 0xFD, 0x7F, 0x02, 0x80, 0x20,
+0x12, 0x7F, 0xC9, 0xF0, 0x90, 0x81, 0x87, 0xE0,
+0xB4, 0x02, 0x1A, 0x12, 0x88, 0x3A, 0x12, 0x6B,
+0x88, 0xBF, 0x01, 0x09, 0x90, 0x81, 0x8F, 0xE0,
+0xFF, 0x7D, 0x01, 0x80, 0x03, 0xE4, 0xFD, 0xFF,
+0x12, 0x52, 0x54, 0x80, 0x08, 0x90, 0x81, 0x90,
+0xE0, 0x90, 0x81, 0x87, 0xF0, 0x90, 0x05, 0x40,
+0x74, 0x22, 0xF0, 0x80, 0x29, 0xF1, 0x73, 0x90,
+0x81, 0x87, 0xE0, 0xB4, 0x02, 0x06, 0x7D, 0x01,
+0x7F, 0x04, 0x80, 0x0B, 0x90, 0x81, 0x87, 0xE0,
+0xB4, 0x08, 0x07, 0x7D, 0x01, 0x7F, 0x0C, 0x12,
+0x52, 0x54, 0x12, 0x81, 0x65, 0x90, 0x81, 0x8F,
+0x12, 0x6C, 0x09, 0x12, 0x69, 0xD9, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0x75, 0x59, 0x01, 0x90, 0x05,
+0x27, 0xE5, 0x59, 0xF0, 0x22, 0xEF, 0x70, 0x3F,
+0x7D, 0x78, 0x7F, 0x02, 0xB1, 0xD2, 0x7D, 0x02,
+0x7F, 0x03, 0xB1, 0xD2, 0x7D, 0xC8, 0x7F, 0x02,
+0x12, 0x6E, 0x2A, 0x12, 0x6C, 0x63, 0xF0, 0xE4,
+0xFF, 0x12, 0x69, 0xF6, 0xEF, 0x70, 0x0E, 0x12,
+0x55, 0x60, 0x12, 0x55, 0x4A, 0x12, 0x8A, 0x96,
+0x54, 0x7F, 0xF0, 0x80, 0x07, 0x7D, 0x01, 0x7F,
+0x0C, 0x12, 0x52, 0x54, 0x12, 0x82, 0x91, 0x90,
+0x06, 0x0A, 0xE0, 0x54, 0xF8, 0xF0, 0x22, 0x90,
+0x01, 0x36, 0x74, 0x78, 0xF0, 0xA3, 0x74, 0x02,
+0xF0, 0x7D, 0x78, 0xFF, 0x12, 0x6D, 0xAB, 0x7D,
+0x02, 0x7F, 0x03, 0x12, 0x6D, 0xAB, 0x90, 0x06,
+0x0A, 0xE0, 0x44, 0x07, 0x12, 0x89, 0xAC, 0xE4,
+0xFF, 0x12, 0x69, 0xF6, 0xBF, 0x01, 0x11, 0x12,
+0x6B, 0xF3, 0x90, 0x81, 0x90, 0xE0, 0x20, 0xE2,
+0x0B, 0x7D, 0x01, 0x7F, 0x04, 0x02, 0x52, 0x54,
+0x12, 0x6D, 0x71, 0xF0, 0x22, 0xC0, 0xE0, 0xC0,
+0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75,
+0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02,
+0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06,
+0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0xFD, 0xF0,
+0x74, 0x4F, 0xA3, 0xF0, 0x12, 0x84, 0xA0, 0xE5,
+0x49, 0x30, 0xE1, 0x02, 0x11, 0xA5, 0xE5, 0x49,
+0x30, 0xE2, 0x03, 0x12, 0x82, 0x7C, 0xE5, 0x4A,
+0x30, 0xE0, 0x03, 0x12, 0x85, 0x19, 0xE5, 0x4A,
+0x30, 0xE4, 0x03, 0x12, 0x86, 0x04, 0xE5, 0x4B,
+0x30, 0xE1, 0x03, 0x12, 0x86, 0x1A, 0xE5, 0x4B,
+0x30, 0xE0, 0x03, 0x12, 0x82, 0x99, 0xE5, 0x4B,
+0x30, 0xE4, 0x02, 0xF1, 0xF4, 0xE5, 0x4C, 0x30,
+0xE1, 0x05, 0x7F, 0x04, 0x12, 0x7A, 0x29, 0xE5,
+0x4C, 0x30, 0xE4, 0x03, 0x12, 0x6D, 0xB7, 0xE5,
+0x4C, 0x30, 0xE5, 0x03, 0x12, 0x80, 0xBB, 0xE5,
+0x4C, 0x30, 0xE6, 0x03, 0x12, 0x7D, 0x46, 0x74,
+0xFD, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x4F,
+0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05,
+0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01,
+0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83,
+0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x90, 0x81, 0x8D,
+0xE0, 0x60, 0x03, 0x12, 0x6B, 0x94, 0x90, 0x82,
+0x66, 0xE0, 0x30, 0xE0, 0x47, 0xC4, 0x54, 0x0F,
+0x20, 0xE0, 0x15, 0xE4, 0xF5, 0x1D, 0x90, 0x82,
+0x68, 0x31, 0x07, 0x91, 0x6B, 0x12, 0x8A, 0x64,
+0x30, 0xE0, 0x02, 0x31, 0xC5, 0x02, 0x88, 0xE9,
+0x90, 0x82, 0x66, 0xE0, 0xC4, 0x54, 0x0F, 0x30,
+0xE0, 0x22, 0xE4, 0xF5, 0x1D, 0x90, 0x82, 0x69,
+0x31, 0x07, 0x90, 0x82, 0x66, 0xE0, 0x54, 0xEF,
+0xF0, 0xE0, 0xC3, 0x13, 0x30, 0xE0, 0x06, 0x7D,
+0x04, 0x7F, 0x01, 0x21, 0xC9, 0x7B, 0x31, 0xF1,
+0xF5, 0x12, 0x7E, 0xD9, 0x22, 0xE0, 0x44, 0x02,
+0xF0, 0xE4, 0xF5, 0x1D, 0x90, 0x82, 0x60, 0xE0,
+0xF5, 0x1E, 0xE4, 0xFB, 0xFD, 0x7F, 0x54, 0x7E,
+0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x8E, 0x19, 0x8F, 0x1A, 0xE5, 0x1E, 0x31, 0x66,
+0x85, 0x19, 0x83, 0x85, 0x1A, 0x82, 0xF0, 0xE5,
+0x1D, 0x31, 0x66, 0xFF, 0xE5, 0x1E, 0x13, 0x13,
+0x13, 0x54, 0x1F, 0x4F, 0xA3, 0xF0, 0xEB, 0x31,
+0x66, 0xFF, 0xE5, 0x1D, 0x13, 0x13, 0x13, 0x54,
+0x1F, 0x4F, 0x31, 0x6D, 0xF0, 0xBD, 0x01, 0x0D,
+0x85, 0x1A, 0x82, 0x8E, 0x83, 0xA3, 0xA3, 0xA3,
+0x74, 0x03, 0xF0, 0x80, 0x06, 0x31, 0x6D, 0xA3,
+0x74, 0x01, 0xF0, 0x31, 0x6D, 0xA3, 0x74, 0x05,
+0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x54, 0x07,
+0xC4, 0x33, 0x54, 0xE0, 0x22, 0x85, 0x1A, 0x82,
+0x85, 0x19, 0x83, 0xA3, 0xA3, 0x22, 0x90, 0x81,
+0x91, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x81, 0x96,
+0xE0, 0x60, 0x04, 0x64, 0x01, 0x70, 0x11, 0xE4,
+0xF5, 0x1D, 0x90, 0x81, 0x96, 0xE0, 0x31, 0xBA,
+0x31, 0x08, 0x90, 0x81, 0x96, 0xE0, 0x80, 0x11,
+0xE4, 0xF5, 0x1D, 0x31, 0xB0, 0x31, 0x08, 0x90,
+0x81, 0x96, 0xE0, 0x75, 0xF0, 0x03, 0xA4, 0x24,
+0xFE, 0x31, 0xBA, 0x90, 0x81, 0xA6, 0xF0, 0x22,
+0x90, 0x81, 0x96, 0xE0, 0x75, 0xF0, 0x03, 0xA4,
+0x24, 0xFE, 0xFF, 0x90, 0x81, 0x95, 0xE0, 0x2F,
+0x22, 0xE0, 0x54, 0x7F, 0xF0, 0x7D, 0x0C, 0x7F,
+0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0xAC, 0x07, 0xEF, 0x14, 0x60, 0x15, 0x14, 0x60,
+0x19, 0x24, 0x02, 0x70, 0x1A, 0xED, 0x54, 0x01,
+0xFE, 0x90, 0x81, 0x88, 0xE0, 0x54, 0xFE, 0x4E,
+0xF0, 0x80, 0x0C, 0x90, 0x81, 0x90, 0xED, 0xF0,
+0x80, 0x05, 0x90, 0x81, 0x8F, 0xED, 0xF0, 0x90,
+0x00, 0x8F, 0xE0, 0x30, 0xE4, 0x2E, 0xEC, 0x14,
+0x60, 0x07, 0x14, 0x60, 0x1D, 0x24, 0x02, 0x70,
+0x23, 0x90, 0x81, 0x88, 0xE0, 0x54, 0x01, 0xC4,
+0x33, 0x33, 0x33, 0x54, 0x80, 0xFF, 0x90, 0x81,
+0x90, 0xE0, 0x54, 0x7F, 0x4F, 0xFD, 0x7F, 0x88,
+0x80, 0x07, 0x90, 0x81, 0x8F, 0xE0, 0xFD, 0x7F,
+0x89, 0x12, 0x32, 0x1E, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x90, 0x81, 0x89, 0xE0, 0xC3, 0x13, 0x20,
+0xE0, 0x04, 0x31, 0xC5, 0x80, 0x0B, 0x12, 0x8A,
+0x36, 0x12, 0x88, 0x49, 0x44, 0x80, 0x12, 0x88,
+0x41, 0xE4, 0xFB, 0xFD, 0x7F, 0xFF, 0x81, 0x72,
+0x7D, 0x01, 0x7F, 0x04, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x83, 0x71, 0xED, 0xF0,
+0x90, 0x81, 0x88, 0xE0, 0xFE, 0xC4, 0x13, 0x13,
+0x54, 0x03, 0x30, 0xE0, 0x02, 0x61, 0x9A, 0xEE,
+0x12, 0x7D, 0x36, 0x30, 0xE0, 0x02, 0x61, 0x9A,
+0x90, 0x81, 0x90, 0xE0, 0xFE, 0x6F, 0x70, 0x02,
+0x61, 0x9A, 0xEF, 0x70, 0x02, 0x61, 0x10, 0x24,
+0xFE, 0x70, 0x02, 0x61, 0x4A, 0x24, 0xFE, 0x60,
+0x47, 0x24, 0xFC, 0x70, 0x02, 0x61, 0x84, 0x24,
+0xFC, 0x60, 0x02, 0x61, 0x93, 0xEE, 0xB4, 0x0E,
+0x02, 0x51, 0x31, 0x90, 0x81, 0x90, 0xE0, 0x70,
+0x04, 0x7F, 0x01, 0x91, 0x22, 0x90, 0x81, 0x90,
+0xE0, 0xB4, 0x06, 0x02, 0x71, 0xF6, 0x90, 0x81,
+0x90, 0xE0, 0xB4, 0x04, 0x0D, 0x90, 0x83, 0x71,
+0xE0, 0xFF, 0x60, 0x04, 0xB1, 0xEF, 0x80, 0x02,
+0xB1, 0x4A, 0x90, 0x81, 0x90, 0xE0, 0x64, 0x08,
+0x60, 0x02, 0x61, 0x93, 0xB1, 0x55, 0x61, 0x93,
+0x90, 0x81, 0x90, 0xE0, 0x70, 0x04, 0x7F, 0x01,
+0x91, 0x22, 0x90, 0x81, 0x90, 0xE0, 0xB4, 0x06,
+0x02, 0x71, 0xF6, 0x90, 0x81, 0x90, 0xE0, 0xB4,
+0x0E, 0x07, 0x71, 0x9F, 0xBF, 0x01, 0x02, 0x51,
+0x31, 0x90, 0x81, 0x90, 0xE0, 0x64, 0x0C, 0x60,
+0x02, 0x61, 0x93, 0x71, 0x9F, 0xEF, 0x64, 0x01,
+0x60, 0x02, 0x61, 0x93, 0x91, 0x39, 0x61, 0x93,
+0x90, 0x81, 0x90, 0xE0, 0xB4, 0x0E, 0x07, 0x71,
+0x9F, 0xBF, 0x01, 0x02, 0x51, 0x31, 0x90, 0x81,
+0x90, 0xE0, 0xB4, 0x06, 0x02, 0x71, 0xF6, 0x90,
+0x81, 0x90, 0xE0, 0xB4, 0x0C, 0x07, 0x71, 0x9F,
+0xBF, 0x01, 0x02, 0x91, 0x39, 0x90, 0x81, 0x90,
+0xE0, 0x64, 0x04, 0x70, 0x56, 0x12, 0x81, 0x86,
+0xEF, 0x64, 0x01, 0x70, 0x4E, 0x12, 0x88, 0x16,
+0x80, 0x49, 0x90, 0x81, 0x90, 0xE0, 0xB4, 0x0E,
+0x07, 0x71, 0x9F, 0xBF, 0x01, 0x02, 0x51, 0x31,
+0x90, 0x81, 0x90, 0xE0, 0xB4, 0x06, 0x02, 0x71,
+0xF6, 0x90, 0x81, 0x90, 0xE0, 0xB4, 0x0C, 0x07,
+0x71, 0x9F, 0xBF, 0x01, 0x02, 0x91, 0x39, 0x90,
+0x81, 0x90, 0xE0, 0x70, 0x04, 0x7F, 0x01, 0x91,
+0x22, 0x90, 0x81, 0x90, 0xE0, 0xB4, 0x04, 0x13,
+0xB1, 0xBE, 0x80, 0x0F, 0x90, 0x81, 0x90, 0xE0,
+0xB4, 0x0C, 0x08, 0x12, 0x6D, 0x80, 0x30, 0xE0,
+0x02, 0xD1, 0x30, 0x90, 0x81, 0x90, 0x12, 0x81,
+0xF9, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x81,
+0x6D, 0xEF, 0x64, 0x01, 0x60, 0x05, 0x75, 0x1F,
+0x01, 0x80, 0x30, 0x12, 0x5A, 0xDE, 0x30, 0xE0,
+0x05, 0x75, 0x1F, 0x02, 0x80, 0x25, 0x90, 0x81,
+0x8F, 0xE0, 0xD3, 0x94, 0x04, 0x40, 0x05, 0x75,
+0x1F, 0x08, 0x80, 0x17, 0x90, 0x82, 0x66, 0xE0,
+0x30, 0xE0, 0x0B, 0xC4, 0x54, 0x0F, 0x30, 0xE0,
+0x05, 0x75, 0x1F, 0x11, 0x80, 0x05, 0x12, 0x77,
+0x83, 0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74, 0x02,
+0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x1F, 0xF0, 0x7F,
+0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x81,
+0x89, 0xE0, 0x90, 0x06, 0x04, 0x20, 0xE0, 0x0C,
+0xE0, 0x44, 0x40, 0xF0, 0x7D, 0x04, 0x7F, 0x01,
+0x31, 0xC9, 0x80, 0x0F, 0x31, 0xC1, 0x90, 0x05,
+0x27, 0xE0, 0x54, 0x7F, 0xF0, 0x90, 0x81, 0x87,
+0x74, 0x0C, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0xFF,
+0x80, 0x50, 0x90, 0x83, 0x70, 0xEF, 0xF0, 0xB1,
+0x60, 0x90, 0x83, 0x70, 0xE0, 0x60, 0x02, 0x91,
+0x6D, 0x7D, 0x04, 0xD1, 0x28, 0x74, 0x04, 0xF0,
+0x22, 0x12, 0x6A, 0xC0, 0x70, 0x2C, 0x90, 0x81,
+0x89, 0xE0, 0x54, 0xFD, 0xF0, 0x7B, 0x2C, 0x7D,
+0x6F, 0x7F, 0xFF, 0x91, 0x72, 0x7D, 0x08, 0x7F,
+0x01, 0xD1, 0x43, 0xBF, 0x01, 0x0F, 0x90, 0x81,
+0x88, 0xE0, 0x44, 0x80, 0xF0, 0x7D, 0x0E, 0xD1,
+0x28, 0x74, 0x0E, 0xF0, 0x22, 0x12, 0x80, 0xB1,
+0x04, 0xF0, 0x22, 0xB1, 0x60, 0xE4, 0xFB, 0xFD,
+0x7F, 0xFF, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x90, 0x05, 0x22, 0xED, 0xF0, 0x90, 0x80,
+0x40, 0xEB, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x7E, 0x00, 0x7F, 0xD7, 0x7D, 0x00, 0x7B, 0x01,
+0x7A, 0x81, 0x79, 0x88, 0x12, 0x48, 0x1E, 0x12,
+0x8A, 0x08, 0x12, 0x48, 0x1E, 0x90, 0x81, 0x8C,
+0x74, 0x02, 0xF0, 0x90, 0x81, 0x93, 0x14, 0xF0,
+0xA3, 0xF0, 0xA3, 0x74, 0x10, 0xF0, 0x90, 0x81,
+0x99, 0xE4, 0xF0, 0xA3, 0x74, 0x02, 0x12, 0x89,
+0xB7, 0x12, 0x88, 0x55, 0xE4, 0xFD, 0xFF, 0x31,
+0xC9, 0x7D, 0x0C, 0x7F, 0x02, 0x31, 0xC9, 0x31,
+0xC5, 0x90, 0x80, 0x42, 0xE0, 0xFF, 0xB4, 0x01,
+0x08, 0x90, 0x81, 0x98, 0x74, 0x99, 0xF0, 0x80,
+0x29, 0xEF, 0xB4, 0x03, 0x08, 0x90, 0x81, 0x98,
+0x74, 0x90, 0xF0, 0x80, 0x1D, 0x90, 0x81, 0x98,
+0x74, 0x40, 0xF0, 0x90, 0x00, 0x2C, 0xE0, 0x54,
+0x0F, 0xFF, 0xBF, 0x05, 0x08, 0x90, 0x81, 0xAA,
+0x74, 0x02, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x81,
+0xAA, 0xF0, 0x90, 0x82, 0x5F, 0x74, 0x02, 0xF0,
+0xA3, 0x74, 0x0F, 0xF0, 0xA3, 0xE0, 0x54, 0x01,
+0x44, 0x28, 0xF0, 0xA3, 0x74, 0x07, 0x12, 0x89,
+0xB7, 0x7F, 0x01, 0x12, 0x88, 0x6F, 0x90, 0x05,
+0x58, 0x74, 0x02, 0xF0, 0x7E, 0x00, 0xFF, 0x7D,
+0x00, 0x7B, 0x01, 0x7A, 0x82, 0x79, 0x63, 0x12,
+0x48, 0x1E, 0x12, 0x8A, 0x8E, 0x90, 0x06, 0x0A,
+0xE0, 0x54, 0xF8, 0xF0, 0x7B, 0x56, 0xE4, 0xFD,
+0x7F, 0xFF, 0x91, 0x72, 0xE4, 0x90, 0x82, 0x65,
+0xF0, 0x22, 0x12, 0x8A, 0x8E, 0x91, 0x6D, 0x7D,
+0x0C, 0x7F, 0x01, 0x21, 0xC9, 0x91, 0x6B, 0x31,
+0xC5, 0x90, 0x81, 0x87, 0x74, 0x0C, 0xF0, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
+0x01, 0x01, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x01,
+0x00, 0x74, 0xFF, 0xF0, 0x90, 0x06, 0xB7, 0x74,
+0x09, 0xF0, 0x90, 0x06, 0xB4, 0x74, 0x86, 0xF0,
+0x12, 0x8A, 0xCD, 0xEC, 0x54, 0x7F, 0xFC, 0x90,
+0x83, 0x59, 0x12, 0x20, 0xCE, 0x90, 0x83, 0x59,
+0x12, 0x75, 0x61, 0x7F, 0x7C, 0x12, 0x89, 0xC9,
+0x12, 0x20, 0xDA, 0xCC, 0xC0, 0x00, 0xC0, 0x12,
+0x89, 0xC7, 0x12, 0x20, 0xDA, 0x00, 0xC0, 0x00,
+0x14, 0x12, 0x8A, 0x59, 0x12, 0x20, 0xDA, 0x00,
+0x03, 0x3E, 0x60, 0xE4, 0xFD, 0xFF, 0x12, 0x77,
+0x52, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7B, 0x2E,
+0x7D, 0x6F, 0x7F, 0xFF, 0x91, 0x72, 0x7D, 0x02,
+0x12, 0x88, 0x4B, 0x54, 0xBF, 0xF0, 0x90, 0x81,
+0x87, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x82, 0x66,
+0xE0, 0x30, 0xE0, 0x12, 0x90, 0x01, 0x57, 0xE4,
+0xF0, 0x91, 0x6B, 0x12, 0x8A, 0x64, 0x30, 0xE0,
+0x02, 0x31, 0xC5, 0x12, 0x88, 0xE9, 0x22, 0xEF,
+0x60, 0x35, 0x12, 0x6A, 0xC0, 0x70, 0x30, 0x90,
+0x81, 0x89, 0xE0, 0x54, 0xFE, 0xF0, 0x7B, 0x2B,
+0x7D, 0x0F, 0x7F, 0xFF, 0x91, 0x72, 0x90, 0x06,
+0x04, 0xE0, 0x54, 0xBF, 0xF0, 0xD1, 0x3F, 0xBF,
+0x01, 0x0F, 0x90, 0x81, 0x88, 0xE0, 0x44, 0x40,
+0xF0, 0x7D, 0x06, 0xD1, 0x28, 0x74, 0x06, 0xF0,
+0x22, 0x12, 0x80, 0xB1, 0x74, 0x08, 0xF0, 0x22,
+0x7F, 0x01, 0x31, 0xC9, 0x90, 0x81, 0x87, 0x22,
+0x7B, 0x2F, 0xF1, 0xF5, 0x12, 0x7E, 0xD9, 0x7D,
+0x08, 0xD1, 0x28, 0x74, 0x08, 0xF0, 0x22, 0x7D,
+0x08, 0xE4, 0xFF, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x83, 0x4C, 0xEF, 0xF0, 0xA3,
+0xED, 0xF0, 0x90, 0x80, 0x3E, 0xE0, 0x04, 0xF0,
+0x90, 0x04, 0x1D, 0xE0, 0x60, 0x2A, 0x90, 0x05,
+0x22, 0xE0, 0x90, 0x83, 0x50, 0xF0, 0x7B, 0x26,
+0xF1, 0xEE, 0xF1, 0x8C, 0xEF, 0x64, 0x01, 0x70,
+0x03, 0x12, 0x87, 0x07, 0x90, 0x83, 0x50, 0xE0,
+0xFD, 0x7B, 0x27, 0xE4, 0xFF, 0x91, 0x72, 0x90,
+0x83, 0x4C, 0xE0, 0xFF, 0xD1, 0x9C, 0x80, 0x0A,
+0x90, 0x83, 0x4C, 0xE0, 0xFF, 0xD1, 0x9C, 0x12,
+0x87, 0x07, 0x12, 0x8A, 0x6B, 0x7F, 0x01, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x83, 0x74, 0xEF, 0xF0,
+0xC3, 0x94, 0x02, 0x50, 0x44, 0x90, 0x80, 0x88,
+0xE0, 0xFF, 0x90, 0x04, 0x1C, 0xE0, 0x6F, 0x70,
+0x38, 0x90, 0x81, 0x90, 0xE0, 0x64, 0x0E, 0x70,
+0x14, 0x90, 0x83, 0x74, 0xE0, 0x70, 0x2A, 0x90,
+0x81, 0x88, 0xE0, 0x54, 0x7F, 0xF0, 0x90, 0x06,
+0x04, 0x31, 0xC1, 0x80, 0x1A, 0x90, 0x81, 0x90,
+0xE0, 0x64, 0x06, 0x70, 0x14, 0x90, 0x83, 0x74,
+0xE0, 0x60, 0x0E, 0x12, 0x8A, 0x96, 0x12, 0x8A,
+0x36, 0x90, 0x81, 0x90, 0x74, 0x04, 0xF0, 0x91,
+0x6D, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x80,
+0x89, 0xE0, 0xFF, 0x90, 0x83, 0x58, 0x74, 0x0B,
+0xF0, 0x7B, 0x08, 0x7D, 0x01, 0x12, 0x86, 0x63,
+0x90, 0x83, 0x62, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF,
+0xF0, 0xFD, 0x90, 0x83, 0x61, 0xE0, 0xFF, 0xF1,
+0x44, 0x54, 0x3F, 0xF0, 0xBF, 0x01, 0x02, 0x80,
+0x17, 0xEF, 0x70, 0x02, 0x80, 0x07, 0x90, 0x81,
+0x90, 0xE0, 0x30, 0xE3, 0x0B, 0x12, 0x87, 0xAC,
+0x54, 0xEF, 0xF1, 0x43, 0x44, 0x40, 0xF0, 0x22,
+0x12, 0x87, 0xAC, 0x44, 0x10, 0xF1, 0x43, 0x44,
+0x80, 0xF0, 0x22, 0xF0, 0x74, 0x1F, 0x2D, 0xF5,
+0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
+0x83, 0x61, 0xEF, 0xF0, 0x90, 0x04, 0x1D, 0xE0,
+0x60, 0x20, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x83,
+0x64, 0xF0, 0x7B, 0x29, 0xF1, 0xEE, 0xF1, 0x8C,
+0xBF, 0x01, 0x02, 0xD1, 0xF6, 0x90, 0x83, 0x64,
+0xE0, 0xFD, 0x7B, 0x2A, 0xE4, 0xFF, 0x91, 0x72,
+0x80, 0x02, 0xD1, 0xF6, 0x12, 0x8A, 0x6B, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0xE4, 0x90, 0x83, 0x65,
+0xF0, 0xA3, 0xF0, 0x90, 0x05, 0x22, 0xE0, 0x90,
+0x83, 0x67, 0xF0, 0x7B, 0x47, 0xF1, 0xEE, 0x90,
+0x05, 0xF8, 0xE0, 0x70, 0x1A, 0xA3, 0xE0, 0x70,
+0x16, 0xA3, 0xE0, 0x70, 0x12, 0xA3, 0xE0, 0x70,
+0x0E, 0x90, 0x83, 0x67, 0xE0, 0xFD, 0x7B, 0x48,
+0xE4, 0xFF, 0x91, 0x72, 0x7F, 0x01, 0x22, 0xD3,
+0x90, 0x83, 0x66, 0xE0, 0x94, 0xE8, 0x90, 0x83,
+0x65, 0xE0, 0x94, 0x03, 0x40, 0x15, 0x90, 0x01,
+0xC0, 0xE0, 0x44, 0x20, 0xF0, 0x90, 0x83, 0x67,
+0xE0, 0xFD, 0x7B, 0x5B, 0xE4, 0xFF, 0x91, 0x72,
+0x7F, 0x00, 0x22, 0x12, 0x8A, 0xC6, 0x90, 0x83,
+0x65, 0x12, 0x77, 0x75, 0x80, 0xB1, 0x7D, 0xFF,
+0xE4, 0xFF, 0x81, 0x72, 0x22, 0x7D, 0xFF, 0x7F,
+0xFF, 0x81, 0x72, 0xC0, 0xE0, 0xC0, 0x83, 0xC0,
+0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x05,
+0xC0, 0x07, 0x7D, 0xFB, 0x90, 0x01, 0xC4, 0xED,
+0xF0, 0x74, 0x57, 0xFF, 0xA3, 0xF0, 0xED, 0x04,
+0x90, 0x01, 0xC4, 0xF0, 0xA3, 0xEF, 0xF0, 0xD0,
+0x07, 0xD0, 0x05, 0xD0, 0xD0, 0xD0, 0x82, 0xD0,
+0x83, 0xD0, 0xE0, 0x32, 0x90, 0x01, 0xC8, 0xE4,
+0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x7B, 0x01, 0x7A,
+0x82, 0x79, 0x88, 0x7F, 0xFF, 0xFE, 0x12, 0x2B,
+0x27, 0xBF, 0x01, 0x09, 0x90, 0x82, 0x88, 0xE0,
+0x64, 0x03, 0x60, 0x03, 0x22, 0x01, 0xEA, 0xE4,
+0x90, 0x82, 0x8D, 0xF0, 0x90, 0x82, 0x8D, 0xE0,
+0xFF, 0xC3, 0x94, 0x02, 0x40, 0x02, 0x21, 0x25,
+0xC3, 0x74, 0xFE, 0x31, 0x2E, 0x7B, 0x01, 0x7A,
+0x82, 0x79, 0x89, 0x12, 0x2B, 0x27, 0xEF, 0x64,
+0x01, 0x70, 0x77, 0x90, 0x82, 0x89, 0xE0, 0xFF,
+0x54, 0xC0, 0xFE, 0x60, 0x05, 0xEF, 0x54, 0x0C,
+0x70, 0x16, 0x90, 0x82, 0x89, 0xE0, 0xFF, 0x54,
+0x30, 0x60, 0x67, 0xEF, 0x54, 0x03, 0x60, 0x62,
+0x90, 0x82, 0x8A, 0x74, 0x01, 0xF0, 0x80, 0x05,
+0xE4, 0x90, 0x82, 0x8A, 0xF0, 0x90, 0x82, 0x8A,
+0xE0, 0x90, 0x82, 0x89, 0x70, 0x16, 0xE0, 0xFF,
+0xEE, 0x13, 0x13, 0x54, 0x3F, 0x90, 0x82, 0x8B,
+0xF0, 0xEF, 0x54, 0x0C, 0x13, 0x13, 0x54, 0x3F,
+0xA3, 0xF0, 0x80, 0x0D, 0xE0, 0xFE, 0x54, 0x30,
+0x90, 0x82, 0x8B, 0xF0, 0xEE, 0x54, 0x03, 0xA3,
+0xF0, 0x90, 0x82, 0x8B, 0xE0, 0x64, 0x30, 0x70,
+0x54, 0xA3, 0xE0, 0x64, 0x02, 0x70, 0x4E, 0x90,
+0x00, 0xF5, 0xE0, 0x54, 0x40, 0x90, 0x82, 0x8E,
+0xF0, 0xE0, 0x70, 0x41, 0xA3, 0x74, 0x02, 0xF0,
+0x80, 0x10, 0x90, 0x82, 0x8F, 0x74, 0x01, 0xF0,
+0x80, 0x08, 0x90, 0x82, 0x8D, 0xE0, 0x04, 0xF0,
+0x01, 0x54, 0x90, 0x01, 0xC4, 0x74, 0x2C, 0xF0,
+0x74, 0x58, 0xA3, 0xF0, 0x90, 0x82, 0x8F, 0xE0,
+0x90, 0x01, 0xC8, 0xF0, 0x90, 0x82, 0x89, 0xE0,
+0x90, 0x01, 0xC9, 0xF0, 0x90, 0x82, 0x8A, 0xE0,
+0x90, 0x01, 0xCA, 0xF0, 0xE4, 0xFD, 0x7F, 0x1F,
+0x12, 0x32, 0x1E, 0x80, 0xD5, 0x22, 0x90, 0x81,
+0xA5, 0xE0, 0xFF, 0xC3, 0x74, 0x0A, 0x9F, 0xFF,
+0xE4, 0x94, 0x00, 0xFE, 0x22, 0x90, 0x82, 0x55,
+0x12, 0x47, 0x9D, 0x90, 0x82, 0x51, 0x12, 0x47,
+0xB5, 0xC3, 0x12, 0x47, 0x8C, 0x50, 0x02, 0x21,
+0xED, 0x90, 0x82, 0x55, 0x12, 0x47, 0xB5, 0x90,
+0x82, 0x51, 0x12, 0x47, 0x9D, 0x12, 0x47, 0x64,
+0x78, 0x07, 0x12, 0x20, 0xA8, 0xC0, 0x07, 0x90,
+0x82, 0x59, 0xE0, 0xFB, 0xE4, 0xFA, 0xF9, 0xF8,
+0xD0, 0x07, 0x12, 0x47, 0x64, 0xEE, 0x54, 0x07,
+0xFE, 0xAD, 0x07, 0xAC, 0x06, 0x90, 0x81, 0x88,
+0xE0, 0x30, 0xE0, 0x31, 0x31, 0x26, 0xEF, 0x78,
+0x03, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9,
+0x2D, 0xFD, 0xEE, 0x3C, 0xFC, 0x90, 0x81, 0xAA,
+0xE0, 0x24, 0x05, 0xFF, 0xE4, 0x33, 0xFE, 0xEF,
+0x78, 0x03, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8,
+0xF9, 0x2D, 0xFF, 0xEC, 0x3E, 0xCF, 0x24, 0xFA,
+0xCF, 0x34, 0xFF, 0x80, 0x16, 0x31, 0x26, 0xEF,
+0x78, 0x03, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8,
+0xF9, 0x2D, 0xFF, 0xEE, 0x3C, 0xCF, 0x24, 0x10,
+0xCF, 0x34, 0x00, 0x90, 0x82, 0x76, 0xF0, 0xA3,
+0xEF, 0xF0, 0x90, 0x82, 0x76, 0xE0, 0xFE, 0xA3,
+0xE0, 0xFF, 0xC3, 0x94, 0xA0, 0xEE, 0x94, 0x00,
+0x50, 0x13, 0x74, 0xAB, 0x2F, 0xF5, 0x82, 0xE4,
+0x34, 0x81, 0xF5, 0x83, 0xE0, 0x04, 0xF0, 0x90,
+0x81, 0xA3, 0xE0, 0x04, 0xF0, 0x90, 0x81, 0xA3,
+0xE0, 0xFF, 0xD3, 0x90, 0x82, 0x5C, 0xE0, 0x9F,
+0x90, 0x82, 0x5B, 0xE0, 0x94, 0x00, 0x40, 0x02,
+0x41, 0xDD, 0xE4, 0xFF, 0xFE, 0x51, 0xEF, 0xEF,
+0xD3, 0x9D, 0x40, 0x07, 0x90, 0x82, 0x78, 0xEE,
+0xF0, 0x80, 0x05, 0x0E, 0xEE, 0xB4, 0xA0, 0xED,
+0xE4, 0xFF, 0xFE, 0x51, 0xEF, 0xC3, 0x90, 0x82,
+0x5C, 0xE0, 0x9D, 0xFD, 0x90, 0x82, 0x5B, 0xE0,
+0x94, 0x00, 0xFC, 0xEF, 0xD3, 0x9D, 0xE4, 0x9C,
+0x40, 0x07, 0x90, 0x82, 0x79, 0xEE, 0xF0, 0x80,
+0x05, 0x0E, 0xEE, 0xB4, 0xA0, 0xDD, 0x90, 0x82,
+0x78, 0xE0, 0x90, 0x81, 0xA8, 0xF0, 0x90, 0x82,
+0x79, 0xE0, 0x90, 0x81, 0xA9, 0x51, 0xE8, 0xC3,
+0x94, 0x50, 0x40, 0x20, 0xEF, 0x24, 0xB0, 0x90,
+0x81, 0xA0, 0xF0, 0xE4, 0x90, 0x81, 0x9F, 0xF0,
+0xA3, 0xE0, 0x54, 0x07, 0x75, 0xF0, 0x80, 0xA4,
+0xFF, 0x90, 0x82, 0x4B, 0xE5, 0xF0, 0xF0, 0xA3,
+0xEF, 0xF0, 0x80, 0x11, 0xE4, 0x90, 0x81, 0xA0,
+0x51, 0xE8, 0xC3, 0x74, 0x50, 0x9F, 0x90, 0x81,
+0x9F, 0x12, 0x85, 0xA2, 0xF0, 0x90, 0x81, 0xA8,
+0x51, 0xE1, 0xF0, 0xA3, 0x51, 0xE1, 0xF0, 0x90,
+0x81, 0xA0, 0x51, 0xE1, 0xF0, 0x90, 0x81, 0x9F,
+0x51, 0xE1, 0x51, 0xE8, 0xA3, 0xE0, 0xC3, 0x9F,
+0x90, 0x81, 0xA6, 0xF0, 0x90, 0x81, 0x88, 0xE0,
+0x30, 0xE0, 0x07, 0x90, 0x82, 0x59, 0x51, 0xE1,
+0x80, 0x04, 0x90, 0x82, 0x5A, 0xE0, 0x04, 0xFF,
+0x90, 0x81, 0xA6, 0xE0, 0x2F, 0xF0, 0x90, 0x81,
+0xA6, 0xE0, 0xC3, 0x94, 0x10, 0x50, 0x03, 0x74,
+0x10, 0xF0, 0x90, 0x81, 0xA6, 0xE0, 0x24, 0x02,
+0x12, 0x85, 0x62, 0x74, 0x03, 0xF0, 0x71, 0x02,
+0xE4, 0xFF, 0x12, 0x88, 0x6F, 0x22, 0x90, 0x81,
+0x88, 0xE0, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x22,
+0xF0, 0x90, 0x81, 0xA8, 0xE0, 0xFF, 0x22, 0x74,
+0xAB, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5,
+0x83, 0xE0, 0x2F, 0xFF, 0x90, 0x82, 0x5D, 0xE0,
+0xFD, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0xAC, 0x07, 0x90, 0x81, 0x89, 0x12, 0x7D,
+0x35, 0x30, 0xE0, 0x02, 0x61, 0xBA, 0x90, 0x81,
+0x88, 0xE0, 0x30, 0xE0, 0x16, 0x90, 0x81, 0xAA,
+0xE0, 0x24, 0x05, 0x90, 0x81, 0xA2, 0xF0, 0x90,
+0x81, 0xAA, 0xE0, 0x24, 0x03, 0x90, 0x81, 0xA1,
+0xF0, 0x80, 0x0D, 0x90, 0x81, 0xA2, 0x74, 0x02,
+0xF0, 0x90, 0x81, 0xA1, 0x14, 0xF0, 0x0B, 0x0B,
+0x90, 0x81, 0xA1, 0xE0, 0xFA, 0x90, 0x81, 0xA0,
+0xE0, 0xD3, 0x9A, 0x50, 0x12, 0x90, 0x81, 0x95,
+0xEB, 0xF0, 0x90, 0x81, 0xA2, 0xE0, 0xC3, 0x9D,
+0x2C, 0x90, 0x81, 0xA5, 0xF0, 0x80, 0x18, 0xC3,
+0xED, 0x9A, 0x2B, 0x90, 0x81, 0x95, 0xF0, 0x90,
+0x81, 0xA1, 0xE0, 0xFF, 0xA3, 0xE0, 0xC3, 0x9F,
+0x90, 0x81, 0xA5, 0x12, 0x85, 0xA2, 0xF0, 0x90,
+0x81, 0xA2, 0x71, 0xC6, 0xFC, 0x90, 0x81, 0xA5,
+0x71, 0xCE, 0x40, 0x04, 0xEF, 0x24, 0x0A, 0xF0,
+0x90, 0x81, 0xA5, 0x71, 0xC6, 0xFC, 0x90, 0x81,
+0x95, 0x71, 0xCE, 0x40, 0x04, 0xEF, 0x24, 0x0A,
+0xF0, 0x90, 0x81, 0xA5, 0xE0, 0xFF, 0x7E, 0x00,
+0x90, 0x81, 0x99, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0,
+0x90, 0x05, 0x58, 0xE0, 0x6F, 0x70, 0x01, 0xE4,
+0x60, 0x03, 0x12, 0x89, 0xAD, 0x12, 0x8A, 0x9E,
+0x80, 0x07, 0x90, 0x81, 0x8A, 0xE0, 0x44, 0x01,
+0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE0, 0xFF,
+0x24, 0x0A, 0xFD, 0xE4, 0x33, 0x22, 0xE0, 0xD3,
+0x9D, 0xEC, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x98,
+0x22, 0x12, 0x81, 0xEE, 0x54, 0x01, 0xFE, 0x90,
+0x82, 0x66, 0x12, 0x89, 0xF0, 0x4F, 0xFF, 0xF0,
+0x12, 0x1F, 0xA4, 0xFE, 0x54, 0x04, 0xFD, 0xEF,
+0x54, 0xFB, 0x4D, 0xFF, 0x90, 0x82, 0x66, 0xF0,
+0xEE, 0x54, 0x08, 0xFE, 0xEF, 0x54, 0xF7, 0x4E,
+0xFF, 0xF0, 0x12, 0x1F, 0xA4, 0x54, 0x10, 0x25,
+0xE0, 0x25, 0xE0, 0xFE, 0xEF, 0x54, 0xBF, 0x4E,
+0x90, 0x82, 0x66, 0xF0, 0x90, 0x05, 0x52, 0xE0,
+0x54, 0x07, 0xFF, 0x90, 0x82, 0xFB, 0x60, 0x12,
+0xB1, 0x30, 0xFD, 0x90, 0x05, 0x56, 0xE0, 0xC3,
+0x9D, 0x90, 0x82, 0x68, 0xF0, 0xA3, 0xED, 0xF0,
+0x80, 0x1E, 0xB1, 0x30, 0xFB, 0xFF, 0x90, 0x05,
+0x54, 0xE0, 0xC3, 0x31, 0x2E, 0x7C, 0x00, 0x7D,
+0x05, 0x12, 0x20, 0x30, 0x90, 0x82, 0x68, 0xEF,
+0xF0, 0xEB, 0x75, 0xF0, 0x05, 0x84, 0xA3, 0xF0,
+0x90, 0x82, 0xFB, 0x12, 0x67, 0x59, 0x20, 0xE0,
+0x0A, 0x12, 0x54, 0x6B, 0x90, 0x01, 0x57, 0xE4,
+0xF0, 0x80, 0x06, 0x12, 0x51, 0xC5, 0x12, 0x88,
+0xE9, 0x12, 0x88, 0xF1, 0x13, 0x54, 0x1F, 0x20,
+0xE0, 0x04, 0xEF, 0x44, 0x20, 0xF0, 0x12, 0x8A,
+0x64, 0x30, 0xE0, 0x16, 0x90, 0x81, 0x8D, 0x74,
+0x01, 0xF0, 0xE4, 0x90, 0x81, 0x8F, 0xF0, 0x12,
+0x6D, 0x71, 0x12, 0x85, 0x62, 0x74, 0x06, 0xF0,
+0x61, 0x02, 0xE4, 0x90, 0x81, 0x8D, 0xF0, 0x90,
+0x81, 0x8F, 0x74, 0x0C, 0xF0, 0x90, 0x81, 0x88,
+0xE0, 0x54, 0xFE, 0xF0, 0xA3, 0xE0, 0x54, 0xFB,
+0xF0, 0x22, 0x90, 0x82, 0xF8, 0x12, 0x47, 0xEF,
+0x90, 0x82, 0xF7, 0xEF, 0xF0, 0x12, 0x47, 0xF8,
+0x5C, 0xE0, 0x00, 0x5C, 0xE5, 0x01, 0x5C, 0xEA,
+0x12, 0x5C, 0xEF, 0x14, 0x5C, 0xF4, 0x20, 0x5C,
+0xF9, 0x24, 0x5C, 0xFE, 0x25, 0x5D, 0x03, 0x26,
+0x5D, 0x07, 0x27, 0x5D, 0x0C, 0x40, 0x5D, 0x10,
+0x42, 0x5D, 0x15, 0xC0, 0x00, 0x00, 0x5D, 0x1A,
+0xB1, 0x2A, 0x02, 0x7F, 0xD0, 0xB1, 0x2A, 0x02,
+0x6A, 0x18, 0xB1, 0x2A, 0x02, 0x80, 0x1B, 0xB1,
+0x2A, 0x02, 0x80, 0x2F, 0xB1, 0x2A, 0x02, 0x80,
+0x3E, 0xB1, 0x2A, 0x02, 0x4E, 0x04, 0xB1, 0x2A,
+0x02, 0x82, 0xE0, 0xB1, 0x2A, 0x61, 0xD9, 0xB1,
+0x2A, 0x02, 0x6E, 0x6E, 0xB1, 0x2A, 0xE1, 0x97,
+0xB1, 0x2A, 0x02, 0x6A, 0x7D, 0xB1, 0x2A, 0x02,
+0x82, 0xE8, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x01,
+0xF0, 0x90, 0x82, 0xF7, 0xE0, 0x90, 0x01, 0xC2,
+0xF0, 0x22, 0x90, 0x82, 0xF8, 0x02, 0x47, 0xE6,
+0x12, 0x47, 0xE6, 0x90, 0x00, 0x01, 0x02, 0x1F,
+0xBD, 0xE4, 0x90, 0x82, 0xF7, 0xF0, 0x90, 0x81,
+0x82, 0xE0, 0xFE, 0x90, 0x82, 0xF7, 0xE0, 0xFF,
+0xC3, 0x9E, 0x40, 0x02, 0xE1, 0x60, 0x12, 0x69,
+0xF6, 0xEF, 0x70, 0x02, 0xE1, 0x58, 0x90, 0x82,
+0xF7, 0x12, 0x8A, 0x42, 0x12, 0x7D, 0x35, 0x30,
+0xE0, 0x02, 0xE1, 0x58, 0x12, 0x7C, 0x20, 0xE0,
+0xFE, 0xA3, 0xE0, 0xD3, 0x94, 0x00, 0xEE, 0x94,
+0x00, 0x50, 0x02, 0xE1, 0x58, 0x90, 0x82, 0xF7,
+0xE0, 0x75, 0xF0, 0x0A, 0xA4, 0x24, 0x00, 0xF9,
+0x74, 0x8D, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0x90,
+0x82, 0xFC, 0x12, 0x47, 0xEF, 0x90, 0x82, 0xF7,
+0xE0, 0xFF, 0x12, 0x7C, 0x21, 0xE0, 0xFD, 0xA3,
+0xE0, 0x90, 0x83, 0x01, 0xCD, 0xF0, 0xA3, 0xED,
+0xF0, 0xEF, 0x12, 0x8A, 0x2A, 0xE0, 0xFF, 0xA3,
+0xE0, 0x90, 0x83, 0x03, 0xCF, 0xF0, 0xA3, 0xEF,
+0xF0, 0x90, 0x82, 0xF7, 0xE0, 0xFD, 0x24, 0xB0,
+0x12, 0x65, 0x99, 0xE0, 0x54, 0x3F, 0x90, 0x82,
+0xF8, 0xF0, 0xE0, 0xFF, 0x54, 0x1F, 0xFE, 0x75,
+0xF0, 0x08, 0xED, 0x12, 0x66, 0x1D, 0xE0, 0xFD,
+0x90, 0x82, 0xF7, 0xE0, 0xF9, 0x24, 0x8C, 0x12,
+0x8A, 0xB6, 0xE0, 0xC3, 0x94, 0x05, 0x40, 0x02,
+0xC1, 0xF5, 0xEE, 0x9D, 0x40, 0x0B, 0xAE, 0x05,
+0xEF, 0x54, 0x40, 0x90, 0x82, 0xF8, 0xF0, 0x4D,
+0xF0, 0xEE, 0x90, 0x41, 0x82, 0x93, 0xFF, 0x74,
+0xCB, 0x29, 0x12, 0x8A, 0xAE, 0xE0, 0xC3, 0x9F,
+0xEE, 0x40, 0x05, 0x90, 0x41, 0x4A, 0x80, 0x03,
+0x90, 0x41, 0x66, 0x93, 0x90, 0x83, 0x05, 0xF0,
+0x90, 0x83, 0x05, 0xE0, 0x75, 0xF0, 0x06, 0xA4,
+0x24, 0xC0, 0xF9, 0x74, 0x40, 0x35, 0xF0, 0xFA,
+0x7B, 0xFF, 0x90, 0x82, 0xF9, 0x12, 0x47, 0xEF,
+0x90, 0x82, 0xF8, 0xE0, 0x90, 0x42, 0x2A, 0x93,
+0xFF, 0xD3, 0x90, 0x83, 0x04, 0xE0, 0x9F, 0x90,
+0x83, 0x03, 0xE0, 0x94, 0x00, 0x40, 0x02, 0xC1,
+0xEB, 0x90, 0x82, 0xF7, 0xE0, 0x12, 0x65, 0xCE,
+0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x82, 0xFF, 0xCF,
+0xF0, 0xA3, 0xEF, 0xF0, 0xF1, 0x7F, 0x12, 0x1F,
+0xA4, 0xF1, 0x64, 0x12, 0x46, 0xB5, 0xF1, 0x70,
+0xB1, 0x33, 0xF1, 0x64, 0x90, 0x00, 0x02, 0xF1,
+0x6D, 0x90, 0x00, 0x02, 0xF1, 0x61, 0x90, 0x00,
+0x04, 0xF1, 0x6D, 0x90, 0x00, 0x03, 0xF1, 0x61,
+0x90, 0x00, 0x06, 0xF1, 0x6D, 0x90, 0x00, 0x04,
+0xF1, 0x61, 0x90, 0x00, 0x08, 0xF1, 0x6D, 0x12,
+0x80, 0x15, 0xFF, 0x7E, 0x00, 0x90, 0x83, 0x01,
+0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0x12, 0x20, 0x1E,
+0xF1, 0x8B, 0x40, 0x0C, 0xA3, 0xE0, 0x9F, 0xF0,
+0x90, 0x82, 0xFF, 0xE0, 0x9E, 0xF0, 0x80, 0x07,
+0xE4, 0x90, 0x82, 0xFF, 0xF0, 0xA3, 0xF0, 0x90,
+0x82, 0xFF, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0x90,
+0x82, 0xF7, 0xE0, 0xFF, 0x12, 0x65, 0xCE, 0xEC,
+0xF0, 0xA3, 0xED, 0xF0, 0x12, 0x7A, 0xC8, 0x90,
+0x82, 0xF8, 0xE0, 0x12, 0x67, 0x6F, 0x12, 0x67,
+0x4F, 0xF1, 0x8B, 0x40, 0x0A, 0x90, 0x82, 0xF7,
+0xE0, 0xFF, 0x12, 0x63, 0x73, 0x80, 0x16, 0x90,
+0x82, 0xF8, 0xE0, 0x12, 0x67, 0x46, 0xC3, 0xF1,
+0x8C, 0x50, 0x0A, 0x90, 0x82, 0xF7, 0xE0, 0xFF,
+0x7D, 0x01, 0x12, 0x64, 0xAE, 0xF1, 0x67, 0xE4,
+0xF5, 0xF0, 0x12, 0x47, 0x18, 0xF1, 0x67, 0x90,
+0x00, 0x02, 0xF1, 0x85, 0x90, 0x00, 0x04, 0xF1,
+0x85, 0x90, 0x00, 0x06, 0xF1, 0x85, 0x90, 0x00,
+0x08, 0xF1, 0x85, 0x90, 0x82, 0xF7, 0xE0, 0xFF,
+0x12, 0x67, 0x0C, 0x12, 0x8A, 0x22, 0xF5, 0x83,
+0xE4, 0xF0, 0xA3, 0xF0, 0x90, 0x82, 0xF8, 0xE0,
+0xFF, 0x25, 0xE0, 0x24, 0xD6, 0xF5, 0x82, 0xE4,
+0x34, 0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFC, 0x74,
+0x01, 0x93, 0xFD, 0xEF, 0x12, 0x67, 0x6F, 0xF5,
+0x83, 0x74, 0x01, 0x93, 0x2D, 0xFF, 0xE4, 0x93,
+0x3C, 0x12, 0x67, 0xDC, 0x90, 0x82, 0xF7, 0xE0,
+0x12, 0x65, 0xCE, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0,
+0x90, 0x82, 0xF7, 0xE0, 0x04, 0xF0, 0xA1, 0x3E,
+0x22, 0x12, 0x1F, 0xBD, 0xFF, 0x7E, 0x00, 0x90,
+0x82, 0xFC, 0x02, 0x47, 0xE6, 0x12, 0x46, 0xE0,
+0xFD, 0xAC, 0xF0, 0x12, 0x20, 0x1E, 0x90, 0x82,
+0xFF, 0xEE, 0x8F, 0xF0, 0x12, 0x46, 0x9F, 0x90,
+0x82, 0xF9, 0x02, 0x47, 0xE6, 0xE4, 0xF5, 0xF0,
+0x02, 0x47, 0x37, 0xD3, 0x90, 0x83, 0x00, 0xE0,
+0x9F, 0x90, 0x82, 0xFF, 0xE0, 0x9E, 0x22, 0x12,
+0x1F, 0xA4, 0x54, 0x3F, 0xFF, 0xB1, 0x33, 0x54,
+0x80, 0x12, 0x7D, 0x36, 0xFE, 0xFD, 0x90, 0x82,
+0xFB, 0x12, 0x77, 0x7C, 0x12, 0x47, 0xEF, 0xB1,
+0x33, 0x54, 0x0F, 0x90, 0x83, 0x00, 0x12, 0x6A,
+0x76, 0x54, 0x40, 0xC4, 0x13, 0x13, 0x54, 0x03,
+0x90, 0x83, 0x01, 0xF0, 0x90, 0x82, 0xFB, 0xE0,
+0x12, 0x89, 0xE2, 0xFA, 0x7B, 0x01, 0x90, 0x83,
+0x02, 0x12, 0x8A, 0x4D, 0x90, 0x83, 0x05, 0x12,
+0x47, 0xEF, 0x12, 0x65, 0xDA, 0x90, 0x00, 0x06,
+0x12, 0x1F, 0xBD, 0xFF, 0x90, 0x83, 0x05, 0x12,
+0x63, 0x3F, 0x12, 0x65, 0xDA, 0x12, 0x80, 0x15,
+0xFF, 0x90, 0x83, 0x05, 0x12, 0x63, 0x5A, 0x12,
+0x65, 0xDA, 0x12, 0x67, 0xEB, 0xFF, 0x90, 0x83,
+0x02, 0x71, 0x3F, 0xB1, 0xDA, 0xF1, 0xE4, 0xFF,
+0x90, 0x83, 0x02, 0x71, 0x5A, 0x90, 0x83, 0x00,
+0xE0, 0xFF, 0x90, 0x82, 0xFB, 0xE0, 0xFE, 0x24,
+0x81, 0xF1, 0x3D, 0xEF, 0xF0, 0x90, 0x82, 0xFC,
+0xE0, 0x54, 0x01, 0xC4, 0x33, 0x54, 0xE0, 0xFF,
+0x75, 0xF0, 0x08, 0xEE, 0xF1, 0x35, 0x54, 0xDF,
+0x4F, 0xF0, 0x90, 0x83, 0x01, 0xE0, 0x54, 0x01,
+0xC4, 0x33, 0x33, 0x54, 0xC0, 0xFE, 0x90, 0x82,
+0xFB, 0x12, 0x8A, 0x42, 0xE0, 0x54, 0xBF, 0x4E,
+0xF0, 0x8F, 0x56, 0xEF, 0x75, 0xF0, 0x02, 0xA4,
+0xFF, 0xAE, 0xF0, 0x24, 0x0C, 0xF9, 0x74, 0x98,
+0x3E, 0xFA, 0x7B, 0x01, 0x90, 0x83, 0x09, 0x12,
+0x47, 0xEF, 0x74, 0x01, 0x2F, 0xF9, 0x74, 0x92,
+0x3E, 0xFA, 0x90, 0x83, 0x0C, 0x12, 0x47, 0xEF,
+0xE5, 0x56, 0x12, 0x89, 0xE2, 0xFA, 0x90, 0x83,
+0x0F, 0x12, 0x8A, 0x4D, 0x90, 0x83, 0x12, 0x12,
+0x47, 0xEF, 0x74, 0x81, 0x25, 0x56, 0xF1, 0x3D,
+0xE0, 0x12, 0x47, 0xF8, 0x60, 0xB1, 0x00, 0x60,
+0xBB, 0x01, 0x60, 0xC5, 0x02, 0x60, 0xCF, 0x03,
+0x60, 0xE2, 0x04, 0x60, 0xEC, 0x05, 0x60, 0xF6,
+0x06, 0x61, 0x06, 0x0C, 0x61, 0x24, 0x0D, 0x61,
+0x42, 0x0E, 0x61, 0x60, 0x0F, 0x00, 0x00, 0x61,
+0x83, 0x71, 0x31, 0x74, 0xF0, 0xF0, 0xA3, 0x74,
+0x15, 0x80, 0x1B, 0x71, 0x31, 0x74, 0xF0, 0xF0,
+0xA3, 0x74, 0x10, 0x80, 0x11, 0x71, 0x31, 0x74,
+0xF0, 0xF0, 0xA3, 0x74, 0x05, 0x80, 0x07, 0x71,
+0x31, 0x74, 0xF0, 0xF0, 0xA3, 0xE4, 0xF0, 0x71,
+0x47, 0x74, 0x0F, 0xF0, 0xA3, 0x74, 0x8F, 0xF0,
+0x21, 0x83, 0x71, 0x31, 0x74, 0x0F, 0xF0, 0xA3,
+0x74, 0xF5, 0x80, 0x11, 0x71, 0x31, 0x74, 0x0F,
+0xF0, 0xA3, 0x74, 0xF0, 0x80, 0x07, 0x71, 0x31,
+0xE4, 0xF0, 0xA3, 0x74, 0x0D, 0xF0, 0x71, 0x47,
+0xE4, 0xF0, 0xA3, 0xF0, 0x80, 0x7D, 0x90, 0x04,
+0x47, 0xE0, 0xFF, 0x90, 0x83, 0x0C, 0x71, 0x3F,
+0x90, 0x04, 0x46, 0x71, 0x55, 0x90, 0x04, 0x45,
+0xE0, 0xFF, 0x90, 0x83, 0x09, 0x71, 0x3F, 0x90,
+0x04, 0x44, 0x80, 0x58, 0x90, 0x04, 0x4B, 0xE0,
+0xFF, 0x90, 0x83, 0x0C, 0x71, 0x3F, 0x90, 0x04,
+0x4A, 0x71, 0x55, 0x90, 0x04, 0x49, 0xE0, 0xFF,
+0x90, 0x83, 0x09, 0x71, 0x3F, 0x90, 0x04, 0x48,
+0x80, 0x3A, 0x90, 0x04, 0x4F, 0xE0, 0xFF, 0x90,
+0x83, 0x0C, 0x71, 0x3F, 0x90, 0x04, 0x4E, 0x71,
+0x55, 0x90, 0x04, 0x4D, 0xE0, 0xFF, 0x90, 0x83,
+0x09, 0x71, 0x3F, 0x90, 0x04, 0x4C, 0x80, 0x1C,
+0x90, 0x04, 0x53, 0xE0, 0xFF, 0x90, 0x83, 0x0C,
+0x71, 0x3F, 0x90, 0x04, 0x52, 0x71, 0x55, 0x90,
+0x04, 0x51, 0xE0, 0xFF, 0x90, 0x83, 0x09, 0x71,
+0x3F, 0x90, 0x04, 0x50, 0xE0, 0xFF, 0x90, 0x83,
+0x09, 0x71, 0x5A, 0x90, 0x83, 0x0C, 0x12, 0x47,
+0xE6, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0xF1,
+0x67, 0xF1, 0x59, 0x5F, 0xD0, 0x01, 0xD0, 0x02,
+0xD0, 0x03, 0x12, 0x1F, 0xEA, 0x90, 0x83, 0x0C,
+0xF1, 0xC9, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01,
+0xF1, 0x67, 0x12, 0x5D, 0x30, 0x5F, 0xD0, 0x01,
+0xD0, 0x02, 0xD0, 0x03, 0x12, 0x1F, 0xEA, 0x90,
+0x83, 0x09, 0x12, 0x47, 0xE6, 0xC0, 0x03, 0xC0,
+0x02, 0xC0, 0x01, 0xF1, 0x5F, 0xF1, 0x59, 0x5F,
+0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x1F,
+0xEA, 0x90, 0x83, 0x09, 0xF1, 0xC9, 0xC0, 0x03,
+0xC0, 0x02, 0xC0, 0x01, 0xF1, 0x5F, 0x12, 0x5D,
+0x30, 0x5F, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03,
+0x12, 0x1F, 0xEA, 0x71, 0x47, 0xE0, 0xFE, 0xA3,
+0xE0, 0x4E, 0x60, 0x2D, 0x90, 0x83, 0x08, 0x74,
+0x0B, 0xF0, 0x71, 0x64, 0x94, 0x00, 0x40, 0x5A,
+0x91, 0xA6, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33,
+0xCE, 0xD8, 0xF9, 0x71, 0x46, 0x71, 0x6B, 0x60,
+0x08, 0x90, 0x83, 0x08, 0xE0, 0x24, 0x10, 0x80,
+0x3D, 0x90, 0x83, 0x08, 0xE0, 0x14, 0xF0, 0x80,
+0xD9, 0x71, 0x31, 0xE0, 0xFE, 0xA3, 0xE0, 0x4E,
+0x60, 0x2B, 0x90, 0x83, 0x08, 0x74, 0x0F, 0xF0,
+0x71, 0x64, 0x94, 0x00, 0x40, 0x24, 0x91, 0xA6,
+0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8,
+0xF9, 0x71, 0x30, 0x71, 0x6B, 0x60, 0x06, 0x90,
+0x83, 0x08, 0xE0, 0x80, 0x09, 0x90, 0x83, 0x08,
+0xE0, 0x14, 0xF0, 0x80, 0xDB, 0xE4, 0x90, 0x83,
+0x15, 0xF0, 0x71, 0x31, 0xE0, 0xFE, 0xA3, 0xE0,
+0x4E, 0x60, 0x2A, 0xE4, 0x90, 0x83, 0x08, 0xF0,
+0x71, 0x64, 0x94, 0x10, 0x50, 0x59, 0x91, 0xA6,
+0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8,
+0xF9, 0x71, 0x30, 0x71, 0x6B, 0x60, 0x06, 0x90,
+0x83, 0x08, 0xE0, 0x80, 0x3E, 0x90, 0x83, 0x08,
+0xE0, 0x04, 0xF0, 0x80, 0xDB, 0x71, 0x47, 0xE0,
+0xFE, 0xA3, 0xE0, 0x4E, 0x60, 0x2C, 0xE4, 0x90,
+0x83, 0x08, 0xF0, 0x71, 0x64, 0x94, 0x0C, 0x50,
+0x26, 0x91, 0xA6, 0x80, 0x05, 0xC3, 0x33, 0xCE,
+0x33, 0xCE, 0xD8, 0xF9, 0x71, 0x46, 0x71, 0x6B,
+0x60, 0x08, 0x90, 0x83, 0x08, 0xE0, 0x24, 0x10,
+0x80, 0x09, 0x90, 0x83, 0x08, 0xE0, 0x04, 0xF0,
+0x80, 0xD9, 0xE4, 0x90, 0x83, 0x16, 0xF0, 0x90,
+0x83, 0x15, 0xE0, 0xFF, 0x75, 0xF0, 0x08, 0xE5,
+0x56, 0xD1, 0x1D, 0xEF, 0xF0, 0x90, 0x83, 0x16,
+0xE0, 0xFE, 0x75, 0xF0, 0x08, 0xE5, 0x56, 0xF1,
+0x2F, 0xEE, 0xF0, 0x90, 0x81, 0x82, 0xE0, 0xFD,
+0xE5, 0x56, 0xC3, 0x9D, 0x50, 0x28, 0x74, 0xB0,
+0x25, 0x56, 0xB1, 0x99, 0xE0, 0xD3, 0x9F, 0x40,
+0x02, 0x80, 0x13, 0x74, 0xB0, 0x25, 0x56, 0xB1,
+0x99, 0xE0, 0xC3, 0x9E, 0x50, 0x08, 0x90, 0x83,
+0x16, 0xE0, 0xA3, 0xF0, 0x80, 0x08, 0x90, 0x83,
+0x15, 0xE0, 0x90, 0x83, 0x17, 0xF0, 0x90, 0x83,
+0x17, 0xE0, 0xFD, 0xAF, 0x56, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x74, 0xB0, 0x2F, 0xB1,
+0x99, 0xED, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0xFF, 0xE5, 0x56, 0x25, 0xE0, 0x24, 0x0C, 0xF5,
+0x82, 0xE4, 0x34, 0x98, 0xF5, 0x83, 0x22, 0x12,
+0x47, 0xE6, 0xEF, 0x02, 0x1F, 0xEA, 0xFF, 0xE5,
+0x56, 0x25, 0xE0, 0x24, 0x01, 0xF5, 0x82, 0xE4,
+0x34, 0x92, 0xF5, 0x83, 0x22, 0xE0, 0xFF, 0x90,
+0x83, 0x0C, 0x12, 0x47, 0xE6, 0x90, 0x00, 0x01,
+0xEF, 0x02, 0x1F, 0xFC, 0x90, 0x83, 0x08, 0xE0,
+0xFF, 0xC3, 0x22, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0,
+0x5F, 0x4E, 0x22, 0xB1, 0x94, 0xE0, 0x54, 0x7F,
+0x90, 0x83, 0x06, 0xF0, 0xE0, 0x54, 0x1F, 0xFD,
+0xD1, 0x19, 0xE0, 0xFF, 0x90, 0x83, 0x07, 0xF0,
+0xE9, 0x71, 0x49, 0xE0, 0xFB, 0xA3, 0xE0, 0x90,
+0x83, 0x08, 0xCB, 0xF0, 0xA3, 0xEB, 0xF0, 0xE9,
+0x71, 0x33, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x83,
+0x0A, 0xCB, 0xF0, 0xA3, 0xEB, 0xF0, 0xED, 0xF1,
+0x6F, 0xF5, 0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01,
+0x93, 0xFB, 0xB1, 0xCD, 0xEA, 0xF0, 0xA3, 0xEB,
+0xF0, 0xED, 0xC3, 0x9F, 0x50, 0x75, 0xB1, 0xE0,
+0xED, 0xF0, 0x04, 0xFC, 0x90, 0x83, 0x07, 0xE0,
+0xFF, 0xEC, 0xD3, 0x9F, 0x40, 0x02, 0x81, 0x5F,
+0xEC, 0xC3, 0x94, 0x10, 0x40, 0x14, 0xEC, 0x91,
+0xA3, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE,
+0xD8, 0xF9, 0xFF, 0x90, 0x83, 0x08, 0x71, 0x6B,
+0x70, 0x1E, 0xEC, 0xC3, 0x94, 0x10, 0x50, 0x40,
+0x74, 0x01, 0x7E, 0x00, 0xA8, 0x04, 0x08, 0x80,
+0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9,
+0xFF, 0x90, 0x83, 0x0A, 0x71, 0x6B, 0x60, 0x28,
+0xEC, 0xB4, 0x11, 0x09, 0x90, 0x83, 0x09, 0xE0,
+0x30, 0xE7, 0x02, 0x7C, 0x17, 0xEC, 0x64, 0x13,
+0x60, 0x04, 0xEC, 0xB4, 0x12, 0x09, 0x90, 0x83,
+0x08, 0xE0, 0x30, 0xE0, 0x02, 0x7C, 0x18, 0xAD,
+0x04, 0x90, 0x83, 0x06, 0xED, 0xF0, 0x80, 0x2F,
+0x0C, 0x80, 0x91, 0x90, 0x83, 0x07, 0xE0, 0xFC,
+0x6D, 0x70, 0x2E, 0xB1, 0xE0, 0xED, 0xF0, 0x75,
+0xF0, 0x08, 0xE9, 0xF1, 0x35, 0xC4, 0x13, 0x54,
+0x07, 0x30, 0xE0, 0x0D, 0x90, 0x83, 0x06, 0xE0,
+0x20, 0xE6, 0x06, 0xED, 0x44, 0x40, 0xF0, 0x80,
+0x06, 0x90, 0x83, 0x06, 0xE0, 0xFF, 0x22, 0xED,
+0xB1, 0xA1, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x80,
+0x20, 0xED, 0xD3, 0x9C, 0x40, 0x1B, 0x90, 0x83,
+0x07, 0xE0, 0xFF, 0xB1, 0xE0, 0xEF, 0xF0, 0xAD,
+0x07, 0x90, 0x83, 0x06, 0xEF, 0xF0, 0xFC, 0xB1,
+0xA1, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xAF, 0x04,
+0x22, 0x74, 0x01, 0x29, 0xF1, 0x7C, 0xE4, 0xF0,
+0xAF, 0x01, 0x90, 0x83, 0x06, 0xE0, 0x44, 0x80,
+0xFD, 0x71, 0x1D, 0x90, 0x83, 0x06, 0xE0, 0x44,
+0x80, 0xFF, 0x22, 0x24, 0xF0, 0xFF, 0x74, 0x01,
+0x7E, 0x00, 0xA8, 0x07, 0x08, 0x22, 0xB1, 0x94,
+0xE0, 0x54, 0x7F, 0xFC, 0x54, 0x1F, 0xFF, 0x75,
+0xF0, 0x08, 0xE9, 0xF1, 0x2F, 0xE0, 0x90, 0x83,
+0x08, 0xF0, 0xD1, 0x19, 0xE0, 0xFE, 0xE9, 0x71,
+0x33, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x83, 0x09,
+0xCB, 0xF0, 0xA3, 0xEB, 0xF0, 0xE9, 0x71, 0x49,
+0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x83, 0x0B, 0xCB,
+0xF0, 0xA3, 0xEB, 0xF0, 0xEF, 0xD3, 0x9E, 0x40,
+0x04, 0xAF, 0x06, 0xAC, 0x06, 0xED, 0x70, 0x02,
+0xA1, 0x81, 0x90, 0x83, 0x07, 0xED, 0xF0, 0xEC,
+0x30, 0xE6, 0x05, 0xAC, 0x07, 0xE0, 0x14, 0xF0,
+0x90, 0x83, 0x07, 0xE0, 0x60, 0x7B, 0xEF, 0xD3,
+0x94, 0x00, 0x40, 0x75, 0xE4, 0x90, 0x83, 0x06,
+0xF0, 0xEF, 0x14, 0xFD, 0x90, 0x83, 0x08, 0xE0,
+0xFF, 0xED, 0xD3, 0x9F, 0x40, 0x4C, 0xED, 0x94,
+0x10, 0x40, 0x14, 0xED, 0x91, 0xA3, 0x80, 0x05,
+0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF,
+0x90, 0x83, 0x0B, 0x71, 0x6B, 0x70, 0x1E, 0xED,
+0xC3, 0x94, 0x10, 0x50, 0x2A, 0x74, 0x01, 0x7E,
+0x00, 0xA8, 0x05, 0x08, 0x80, 0x05, 0xC3, 0x33,
+0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x83,
+0x09, 0x71, 0x6B, 0x60, 0x12, 0xAC, 0x05, 0x90,
+0x83, 0x06, 0xE0, 0x04, 0xF0, 0xA3, 0xE0, 0xFF,
+0x90, 0x83, 0x06, 0xE0, 0x6F, 0x60, 0x03, 0x1D,
+0x80, 0xAA, 0x90, 0x83, 0x07, 0xE0, 0xFF, 0x90,
+0x83, 0x06, 0xE0, 0xC3, 0x9F, 0x50, 0x0A, 0x90,
+0x83, 0x08, 0xE0, 0xFF, 0xB5, 0x05, 0x02, 0xAC,
+0x07, 0xF1, 0x45, 0xEC, 0xB1, 0xB4, 0xEE, 0xF0,
+0xA3, 0xEF, 0xF0, 0xAF, 0x01, 0xAD, 0x04, 0x71,
+0x1D, 0xAF, 0x04, 0x22, 0xA9, 0x07, 0x74, 0xB0,
+0x29, 0xF5, 0x82, 0xE4, 0x34, 0x02, 0xF5, 0x83,
+0x22, 0x25, 0xE0, 0x24, 0xD6, 0xF5, 0x82, 0xE4,
+0x34, 0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFE, 0x74,
+0x01, 0x93, 0xFF, 0xED, 0x25, 0xE0, 0x24, 0x9E,
+0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0x74,
+0x01, 0x93, 0x2F, 0xFF, 0xE4, 0x93, 0x3E, 0xC3,
+0x13, 0xFE, 0xEF, 0x13, 0xFF, 0xE9, 0x25, 0xE0,
+0x24, 0xC1, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5,
+0x83, 0x22, 0x90, 0x82, 0xFD, 0x02, 0x47, 0xE6,
+0x74, 0xCD, 0x29, 0xF5, 0x82, 0xE4, 0x34, 0x98,
+0xF5, 0x83, 0x22, 0xAD, 0x07, 0x75, 0xF0, 0x08,
+0xED, 0xD1, 0x1D, 0xE0, 0xFF, 0x74, 0xCD, 0x2D,
+0xB1, 0xE3, 0xE0, 0x54, 0x1F, 0xFC, 0xD3, 0x9F,
+0x40, 0x02, 0xAC, 0x07, 0xF1, 0x45, 0xEC, 0xF1,
+0x6F, 0xF5, 0x83, 0xF1, 0xD4, 0xED, 0xB1, 0xCE,
+0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xAF, 0x05, 0xA1,
+0x8D, 0x75, 0xF0, 0x08, 0xE9, 0x90, 0x93, 0x43,
+0x02, 0x47, 0xDA, 0x90, 0x04, 0x44, 0x74, 0x11,
+0xF0, 0xA3, 0x74, 0xF0, 0xF0, 0xA3, 0x74, 0x0F,
+0xF0, 0xA3, 0xE4, 0xF0, 0x90, 0x82, 0x88, 0xF0,
+0x90, 0x81, 0x82, 0xE0, 0xFF, 0x90, 0x82, 0x88,
+0xE0, 0xC3, 0x9F, 0x40, 0x02, 0xC1, 0xFF, 0xE0,
+0xFF, 0x75, 0xF0, 0x0A, 0x90, 0x8D, 0x00, 0xF1,
+0x00, 0x90, 0x8D, 0x02, 0xF1, 0x00, 0x90, 0x8D,
+0x04, 0xF1, 0x00, 0x90, 0x8D, 0x06, 0xF1, 0x00,
+0x90, 0x8D, 0x08, 0x12, 0x47, 0xDA, 0xE4, 0xF0,
+0xA3, 0xF0, 0xEF, 0xF1, 0x0C, 0x24, 0x4B, 0xF5,
+0x82, 0xE4, 0x34, 0x96, 0xF1, 0x25, 0x12, 0x8A,
+0x22, 0xF1, 0x25, 0x24, 0x0C, 0xF5, 0x82, 0xE4,
+0x34, 0x97, 0xF1, 0x25, 0x24, 0x8C, 0xF5, 0x82,
+0xE4, 0x34, 0x97, 0xF5, 0x83, 0xE4, 0xF0, 0xA3,
+0xF0, 0x74, 0x8C, 0x2F, 0x12, 0x8A, 0xB6, 0xE4,
+0xF0, 0x90, 0x41, 0xFC, 0xF1, 0x52, 0x90, 0x41,
+0xC4, 0xF1, 0xD4, 0x90, 0x82, 0x88, 0xE0, 0xFD,
+0xB1, 0xCE, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x75,
+0xF0, 0x08, 0xED, 0xF1, 0x35, 0x44, 0x20, 0xF0,
+0x74, 0x81, 0x2D, 0xF1, 0x3D, 0x74, 0x0C, 0xF0,
+0x75, 0xF0, 0x08, 0xED, 0x90, 0x93, 0x49, 0x12,
+0x47, 0xDA, 0x74, 0xFF, 0xF0, 0xA3, 0xF0, 0x75,
+0xF0, 0x08, 0xED, 0x90, 0x93, 0x47, 0x12, 0x47,
+0xDA, 0xE4, 0xF0, 0xA3, 0x74, 0x0F, 0xF0, 0x75,
+0xF0, 0x08, 0xED, 0xD1, 0x1D, 0x74, 0x13, 0xF0,
+0x75, 0xF0, 0x08, 0xED, 0xF1, 0x2F, 0xE4, 0xF0,
+0x74, 0xB0, 0x2D, 0xB1, 0x99, 0xE4, 0xF0, 0x90,
+0x82, 0x88, 0xE0, 0x04, 0xF0, 0xC1, 0x38, 0x22,
+0x12, 0x47, 0xDA, 0xE4, 0xF0, 0xA3, 0xF0, 0x75,
+0xF0, 0x0A, 0xEF, 0x22, 0x25, 0xE0, 0x24, 0x80,
+0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0xE4,
+0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0x4B,
+0xF5, 0x82, 0xE4, 0x34, 0x95, 0xF5, 0x83, 0xE4,
+0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x22, 0x90,
+0x93, 0x44, 0x02, 0x47, 0xDA, 0x90, 0x93, 0x45,
+0x12, 0x47, 0xDA, 0xE0, 0x22, 0xF5, 0x82, 0xE4,
+0x34, 0x92, 0xF5, 0x83, 0x22, 0xEC, 0x25, 0xE0,
+0x24, 0xD6, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5,
+0x83, 0xE4, 0x93, 0xFE, 0x74, 0x01, 0x93, 0xFF,
+0x22, 0x12, 0x47, 0xE6, 0x02, 0x1F, 0xA4, 0x12,
+0x1F, 0xA4, 0xFF, 0x90, 0x83, 0x0F, 0x22, 0x12,
+0x1F, 0xA4, 0xFF, 0x90, 0x83, 0x12, 0x22, 0x25,
+0xE0, 0x24, 0x9E, 0xF5, 0x82, 0xE4, 0x34, 0x41,
+0x22, 0x74, 0x01, 0x2A, 0xF5, 0x82, 0xE4, 0x34,
+0x91, 0xF5, 0x83, 0x22, 0xAA, 0x07, 0xED, 0x54,
+0x1F, 0x90, 0x82, 0x82, 0xF0, 0xF1, 0x79, 0xE0,
+0x90, 0x82, 0x80, 0xF0, 0x90, 0x82, 0x83, 0x74,
+0x01, 0xF0, 0xEB, 0xC3, 0x94, 0x01, 0x40, 0x02,
+0xA1, 0xEB, 0x90, 0x82, 0x80, 0xE0, 0x25, 0x51,
+0xFF, 0xA3, 0xF0, 0xA3, 0xE0, 0x90, 0x42, 0x0E,
+0x93, 0xFE, 0xEF, 0xD3, 0x9E, 0x40, 0x08, 0xF1,
+0x79, 0xE4, 0xF0, 0xAF, 0x02, 0x61, 0x1D, 0x90,
+0x82, 0x81, 0xE0, 0xFF, 0xF1, 0x79, 0xEF, 0xF0,
+0x22, 0x12, 0x47, 0xE6, 0xE9, 0x24, 0x01, 0xF9,
+0xE4, 0x3A, 0xFA, 0x22, 0x74, 0x01, 0x93, 0x2F,
+0xFF, 0xE4, 0x93, 0x3E, 0xC3, 0x13, 0xFE, 0xEF,
+0x13, 0xFF, 0x22, 0xF0, 0x90, 0x00, 0x03, 0x02,
+0x1F, 0xBD, 0xF0, 0x90, 0x00, 0x04, 0x02, 0x1F,
+0xBD, 0x90, 0x00, 0xF7, 0xE0, 0x20, 0xE7, 0x09,
+0xE0, 0x7F, 0x01, 0x20, 0xE6, 0x0C, 0x7F, 0x02,
+0x22, 0x90, 0x00, 0xF7, 0xE0, 0x30, 0xE6, 0x02,
+0x7F, 0x03, 0x22, 0x12, 0x67, 0xF1, 0x90, 0x80,
+0x42, 0xEF, 0xF0, 0x11, 0x2C, 0x90, 0x01, 0x64,
+0x74, 0x01, 0xF0, 0x90, 0x00, 0x12, 0xE0, 0x54,
+0xC7, 0x44, 0x20, 0xFD, 0x7F, 0x12, 0x12, 0x32,
+0x1E, 0x02, 0x2D, 0xA7, 0x90, 0x00, 0x08, 0xE0,
+0x54, 0xEF, 0xF0, 0x11, 0x65, 0x11, 0x95, 0x12,
+0x83, 0x65, 0x12, 0x83, 0x84, 0xE4, 0xF5, 0x35,
+0xF5, 0x37, 0xF5, 0x36, 0xF5, 0x37, 0x75, 0x38,
+0x80, 0xAD, 0x35, 0x7F, 0x50, 0x12, 0x32, 0x1E,
+0xAD, 0x36, 0x7F, 0x51, 0x12, 0x32, 0x1E, 0xAD,
+0x37, 0x7F, 0x52, 0x12, 0x32, 0x1E, 0xAD, 0x38,
+0x7F, 0x53, 0x02, 0x32, 0x1E, 0x90, 0x01, 0x30,
+0xE4, 0x11, 0x8E, 0xF0, 0x90, 0x01, 0x38, 0x11,
+0x8E, 0xF0, 0xFD, 0x7F, 0x50, 0x12, 0x32, 0x1E,
+0xE4, 0xFD, 0x7F, 0x51, 0x12, 0x32, 0x1E, 0xE4,
+0xFD, 0x7F, 0x52, 0x12, 0x32, 0x1E, 0xE4, 0xFD,
+0x7F, 0x53, 0x02, 0x32, 0x1E, 0xA3, 0xF0, 0xA3,
+0xF0, 0xA3, 0xF0, 0xA3, 0x22, 0x90, 0x01, 0x34,
+0x74, 0xFF, 0x11, 0x8E, 0xF0, 0x90, 0x01, 0x3C,
+0x11, 0x8E, 0xF0, 0xFD, 0x7F, 0x54, 0x12, 0x32,
+0x1E, 0x7D, 0xFF, 0x7F, 0x55, 0x12, 0x32, 0x1E,
+0x7D, 0xFF, 0x7F, 0x56, 0x12, 0x32, 0x1E, 0x7D,
+0xFF, 0x7F, 0x57, 0x02, 0x32, 0x1E, 0xE4, 0x90,
+0x80, 0x3C, 0xF0, 0x11, 0x8D, 0xF0, 0x22, 0x90,
+0x00, 0x80, 0xE0, 0x44, 0x80, 0xFD, 0x7F, 0x80,
+0x12, 0x32, 0x1E, 0x90, 0xFD, 0x00, 0xE0, 0x54,
+0xBF, 0xF0, 0x12, 0x58, 0x2C, 0x12, 0x83, 0xA6,
+0x12, 0x32, 0x77, 0x12, 0x83, 0xB3, 0x11, 0xBE,
+0x7F, 0x01, 0x12, 0x44, 0x15, 0x90, 0x82, 0x72,
+0x74, 0x02, 0xF0, 0xFF, 0x12, 0x44, 0x15, 0x90,
+0x82, 0x72, 0xE0, 0x04, 0xF0, 0x11, 0x0B, 0x31,
+0x23, 0x90, 0x01, 0xCC, 0x74, 0x0F, 0xF0, 0x90,
+0x00, 0x80, 0xE0, 0x44, 0x40, 0xFD, 0x7F, 0x80,
+0x12, 0x32, 0x1E, 0x75, 0x20, 0xFF, 0xF1, 0xE9,
+0x12, 0x83, 0xE3, 0x12, 0x84, 0x69, 0xE4, 0xFF,
+0x02, 0x44, 0x9E, 0x31, 0x39, 0x12, 0x82, 0xF7,
+0x12, 0x66, 0x23, 0x31, 0xD9, 0x12, 0x54, 0x88,
+0x12, 0x88, 0xAC, 0x12, 0x8A, 0x08, 0x02, 0x48,
+0x1E, 0xE4, 0xFD, 0xFF, 0x51, 0x9D, 0xED, 0x70,
+0x12, 0x31, 0x77, 0xC0, 0x83, 0xC0, 0x82, 0x31,
+0x6F, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4,
+0x5E, 0x80, 0x0F, 0x31, 0x77, 0xC0, 0x83, 0xC0,
+0x82, 0x31, 0x6F, 0x80, 0x02, 0xC3, 0x33, 0xD8,
+0xFC, 0x4E, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0x31,
+0x82, 0x90, 0x81, 0x82, 0xEF, 0xF0, 0x22, 0xE0,
+0xFE, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x22, 0x74,
+0x7A, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5,
+0x83, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x7D, 0x08, 0xED, 0x14, 0xF9, 0x24, 0x7A,
+0x31, 0x7A, 0xE0, 0x60, 0x3B, 0x7C, 0x08, 0xEC,
+0x14, 0x90, 0x83, 0x6D, 0xF0, 0x74, 0x7A, 0x29,
+0x31, 0x7A, 0xE0, 0xFB, 0x7A, 0x00, 0x90, 0x83,
+0x6D, 0xE0, 0x12, 0x64, 0xA5, 0x80, 0x05, 0xC3,
+0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEE,
+0x5A, 0xFE, 0xEF, 0x5B, 0x4E, 0x60, 0x0F, 0xE9,
+0x75, 0xF0, 0x08, 0xA4, 0xFF, 0x90, 0x83, 0x6D,
+0xE0, 0x2F, 0x04, 0xFF, 0x80, 0x06, 0xDC, 0xC7,
+0xDD, 0xB9, 0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x7E, 0x00, 0x7F, 0x01, 0x7D, 0x00, 0x7B,
+0x01, 0x7A, 0x81, 0x79, 0x83, 0x12, 0x48, 0x1E,
+0x90, 0x81, 0x83, 0xE0, 0x54, 0xFD, 0xF0, 0xE4,
+0x11, 0x8D, 0x74, 0x0C, 0xF0, 0x22, 0x51, 0x9D,
+0x31, 0x77, 0xE0, 0xFD, 0x7C, 0x00, 0x12, 0x64,
+0xA6, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE,
+0xD8, 0xF9, 0xFF, 0xEE, 0x5C, 0xFE, 0xEF, 0x5D,
+0x4E, 0x7F, 0x00, 0x60, 0x02, 0x7F, 0x01, 0x22,
+0x8B, 0x56, 0x8A, 0x57, 0x89, 0x58, 0x12, 0x5D,
+0x33, 0xFF, 0xF5, 0x5A, 0x12, 0x1F, 0xA4, 0xFE,
+0xC3, 0x13, 0x30, 0xE0, 0x06, 0x51, 0x77, 0xF5,
+0x5B, 0x80, 0x02, 0x8F, 0x5B, 0x85, 0x5A, 0x59,
+0xE5, 0x59, 0xD3, 0x95, 0x5B, 0x50, 0x1D, 0x12,
+0x8A, 0x7C, 0x54, 0x01, 0xFD, 0xAF, 0x59, 0x31,
+0x3C, 0xAF, 0x59, 0x31, 0xF6, 0xEF, 0xAF, 0x59,
+0x70, 0x04, 0xF1, 0xE0, 0x80, 0x02, 0xF1, 0xDF,
+0x05, 0x59, 0x80, 0xDC, 0xE5, 0x5A, 0x70, 0x15,
+0xFF, 0x31, 0xF6, 0xEF, 0x70, 0x0F, 0x12, 0x55,
+0x60, 0x12, 0x55, 0x4A, 0x12, 0x82, 0x91, 0x54,
+0xBF, 0xF0, 0x54, 0x7F, 0xF0, 0x22, 0xF0, 0x90,
+0x00, 0x02, 0x02, 0x1F, 0xBD, 0x12, 0x1F, 0xA4,
+0xFF, 0xC3, 0x94, 0x40, 0x50, 0x0C, 0x51, 0x77,
+0xFE, 0x74, 0xCB, 0x2F, 0x12, 0x8A, 0xAE, 0xEE,
+0xF0, 0x22, 0xEF, 0xB4, 0x40, 0x06, 0x51, 0x77,
+0x90, 0x93, 0x41, 0xF0, 0x22, 0xEF, 0x13, 0x13,
+0x13, 0x54, 0x1F, 0xFE, 0xEF, 0x54, 0x07, 0xFF,
+0x22, 0x51, 0xC0, 0x70, 0x12, 0x90, 0x81, 0x8D,
+0xE0, 0x60, 0x0C, 0x90, 0x81, 0x91, 0xE0, 0x20,
+0xE4, 0x05, 0x91, 0x63, 0x12, 0x51, 0x00, 0x22,
+0xE4, 0xFF, 0x31, 0xF6, 0xEF, 0x64, 0x01, 0x22,
+0x51, 0xC0, 0x70, 0x1C, 0x90, 0x81, 0x8D, 0xE0,
+0x60, 0x16, 0x90, 0x81, 0x91, 0xE0, 0x20, 0xE4,
+0x0F, 0x91, 0x63, 0xF0, 0x90, 0x81, 0x88, 0xE0,
+0xB1, 0x96, 0x54, 0x07, 0x70, 0x02, 0x71, 0xFB,
+0x22, 0xE4, 0xF5, 0x4E, 0x90, 0x81, 0x8D, 0xE0,
+0x60, 0x45, 0x51, 0xC0, 0x70, 0x41, 0x12, 0x89,
+0x56, 0x90, 0x81, 0x8B, 0xE0, 0xFF, 0xC4, 0x54,
+0x0F, 0x60, 0x09, 0x90, 0x81, 0x89, 0x12, 0x80,
+0xE6, 0x20, 0xE0, 0x03, 0x75, 0x4E, 0x01, 0x90,
+0x81, 0x83, 0xE0, 0x30, 0xE0, 0x11, 0x90, 0x81,
+0x87, 0xE0, 0xB4, 0x02, 0x03, 0xE4, 0xF5, 0x4E,
+0x71, 0x88, 0xEF, 0x70, 0x02, 0xF5, 0x4E, 0xE5,
+0x4E, 0x60, 0x0C, 0x12, 0x89, 0x96, 0x20, 0xE2,
+0x03, 0x12, 0x52, 0x50, 0x12, 0x51, 0x76, 0x22,
+0xE4, 0x90, 0x82, 0x84, 0xF0, 0x90, 0x81, 0x8D,
+0xE0, 0x60, 0x44, 0x51, 0xC0, 0x70, 0x40, 0x12,
+0x8A, 0xA6, 0xF0, 0x12, 0x89, 0x56, 0x90, 0x82,
+0x84, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x81, 0x94,
+0xF0, 0x90, 0x81, 0x83, 0xE0, 0x30, 0xE0, 0x15,
+0x90, 0x81, 0x87, 0xE0, 0xB4, 0x02, 0x05, 0xE4,
+0x90, 0x82, 0x84, 0xF0, 0x71, 0x88, 0xEF, 0x70,
+0x04, 0x90, 0x82, 0x84, 0xF0, 0x90, 0x82, 0x84,
+0xE0, 0x60, 0x0C, 0x12, 0x89, 0x96, 0x20, 0xE2,
+0x03, 0x12, 0x52, 0x50, 0x12, 0x51, 0x76, 0x22,
+0x90, 0x05, 0x43, 0xE0, 0x7F, 0x00, 0x30, 0xE7,
+0x02, 0x7F, 0x01, 0x22, 0x90, 0x81, 0x89, 0xE0,
+0xFF, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0,
+0x10, 0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30,
+0xE0, 0x07, 0x7D, 0x02, 0x7F, 0x02, 0x12, 0x4D,
+0xD2, 0x90, 0x81, 0x88, 0xB1, 0x83, 0x30, 0xE0,
+0x08, 0xB1, 0x95, 0x54, 0x07, 0x70, 0x33, 0x80,
+0x2F, 0x12, 0x85, 0xAA, 0x40, 0x2A, 0x51, 0xC0,
+0x70, 0x28, 0x12, 0x85, 0x74, 0xF1, 0x14, 0x70,
+0x02, 0x80, 0x20, 0x90, 0x81, 0x97, 0xE0, 0x04,
+0xF0, 0xE0, 0xD3, 0x94, 0x02, 0x40, 0x09, 0x71,
+0xF3, 0xE4, 0x90, 0x81, 0x97, 0xF0, 0x80, 0x02,
+0xF1, 0x86, 0xE4, 0x90, 0x81, 0x96, 0xF0, 0x22,
+0x71, 0xFB, 0x22, 0x90, 0x81, 0x89, 0xE0, 0x54,
+0xFB, 0xF0, 0x22, 0x90, 0x81, 0x83, 0xE0, 0x90,
+0x81, 0x8F, 0x30, 0xE0, 0x04, 0xE0, 0xFF, 0x80,
+0x1E, 0xE0, 0xFF, 0x7D, 0x01, 0x02, 0x52, 0x54,
+0xE4, 0xFF, 0x31, 0xF6, 0xBF, 0x01, 0x0F, 0x90,
+0x81, 0x8D, 0xE0, 0x60, 0x09, 0xF1, 0x06, 0xF0,
+0x54, 0x07, 0x70, 0x02, 0x71, 0xFB, 0x22, 0xAE,
+0x07, 0x71, 0x88, 0xBF, 0x01, 0x10, 0x12, 0x89,
+0xFE, 0x20, 0xE0, 0x0A, 0xAF, 0x06, 0x7D, 0x01,
+0x12, 0x52, 0x54, 0x7F, 0x01, 0x22, 0x7F, 0x00,
+0x22, 0x90, 0x01, 0x57, 0xE0, 0x60, 0x1B, 0x91,
+0x66, 0xF0, 0x90, 0x81, 0x88, 0xB1, 0x83, 0x30,
+0xE0, 0x02, 0xA1, 0x95, 0x12, 0x85, 0xAA, 0x40,
+0x09, 0xE4, 0xFF, 0x31, 0xF6, 0xBF, 0x01, 0x02,
+0x71, 0xF3, 0x22, 0x90, 0x01, 0x57, 0xE4, 0xF0,
+0x90, 0x01, 0x3C, 0x74, 0x02, 0x22, 0x51, 0xC0,
+0x60, 0x02, 0xA1, 0x64, 0x90, 0x81, 0x8D, 0xE0,
+0x70, 0x02, 0xA1, 0x64, 0x90, 0x81, 0x83, 0xE0,
+0x20, 0xE0, 0x05, 0x90, 0x06, 0xA9, 0xE0, 0xFF,
+0x90, 0x05, 0x63, 0xE0, 0x90, 0x82, 0x51, 0xF0,
+0x90, 0x05, 0x62, 0xE0, 0x90, 0x82, 0x52, 0xF0,
+0x90, 0x05, 0x61, 0xE0, 0x90, 0x82, 0x53, 0xF0,
+0x90, 0x05, 0x60, 0xE0, 0x90, 0x82, 0x54, 0xF0,
+0x91, 0x63, 0xF0, 0x90, 0x81, 0x91, 0xE0, 0x54,
+0xED, 0xF0, 0x90, 0x81, 0x83, 0xE0, 0x30, 0xE0,
+0x04, 0xF1, 0x1B, 0x80, 0x02, 0xD1, 0xC4, 0x90,
+0x81, 0x8B, 0xE0, 0xFF, 0xC4, 0x54, 0x0F, 0x64,
+0x01, 0x70, 0x27, 0x90, 0x06, 0xAB, 0xE0, 0x90,
+0x81, 0x94, 0xF0, 0x90, 0x06, 0xAA, 0xE0, 0x60,
+0x05, 0xE0, 0x90, 0x81, 0x93, 0xF0, 0x90, 0x81,
+0x94, 0xE0, 0xFF, 0x70, 0x08, 0x90, 0x81, 0x93,
+0xE0, 0xFE, 0xFF, 0x80, 0x00, 0x90, 0x81, 0x94,
+0xEF, 0xF0, 0x12, 0x59, 0x35, 0xE4, 0x90, 0x81,
+0x96, 0xF0, 0xA3, 0x12, 0x89, 0xAC, 0x90, 0x81,
+0x89, 0xE0, 0xFF, 0x13, 0x13, 0x13, 0x54, 0x1F,
+0x30, 0xE0, 0x56, 0xEF, 0xC4, 0x13, 0x13, 0x54,
+0x03, 0x20, 0xE0, 0x25, 0xB1, 0x78, 0x6F, 0x70,
+0x48, 0x90, 0x81, 0x89, 0xE0, 0x44, 0x40, 0xF0,
+0x12, 0x8A, 0xA6, 0xB1, 0x8A, 0xD1, 0x42, 0x12,
+0x4D, 0xCE, 0x7D, 0x02, 0x7F, 0x02, 0x12, 0x4D,
+0xD2, 0x90, 0x81, 0x94, 0xE0, 0x14, 0xF0, 0x80,
+0x28, 0x90, 0x81, 0x8B, 0xE0, 0xC4, 0x54, 0x0F,
+0x64, 0x01, 0x70, 0x1D, 0xB1, 0x78, 0xFE, 0x6F,
+0x60, 0x17, 0x90, 0x05, 0x73, 0xE0, 0xFF, 0xEE,
+0x6F, 0x60, 0x0E, 0xB1, 0x80, 0x30, 0xE0, 0x09,
+0xEF, 0x54, 0xBF, 0xB1, 0x8A, 0xD1, 0x2A, 0xB1,
+0xA1, 0xB1, 0x71, 0xF0, 0x90, 0x81, 0x83, 0xE0,
+0xC3, 0x13, 0x20, 0xE0, 0x03, 0xB1, 0x71, 0xF0,
+0x22, 0x90, 0x81, 0x89, 0xE0, 0x44, 0x04, 0x22,
+0x90, 0x81, 0x93, 0xE0, 0xFF, 0xA3, 0xE0, 0x22,
+0x90, 0x81, 0x89, 0xE0, 0xFF, 0x13, 0x13, 0x54,
+0x3F, 0x22, 0xF0, 0x90, 0x01, 0x3F, 0x74, 0x10,
+0xF0, 0xFD, 0x7F, 0x03, 0x22, 0xEF, 0x54, 0xFB,
+0xF0, 0x90, 0x81, 0x91, 0xE0, 0x54, 0xFD, 0xF0,
+0x22, 0x7D, 0x01, 0x7F, 0x02, 0xB1, 0xAB, 0x7D,
+0x02, 0x7F, 0x02, 0x74, 0x3D, 0x2F, 0xF8, 0xE6,
+0x4D, 0xFE, 0xF6, 0x74, 0x30, 0x80, 0x7C, 0x71,
+0x38, 0xB1, 0xA7, 0x7F, 0x01, 0x12, 0x7A, 0x38,
+0x90, 0x82, 0x6E, 0xE0, 0x30, 0xE0, 0x15, 0xF1,
+0xE1, 0xF0, 0x90, 0x82, 0x71, 0xE0, 0x60, 0x05,
+0x14, 0xF0, 0x02, 0x56, 0x30, 0x12, 0x8A, 0x72,
+0xE4, 0xFF, 0xB1, 0xDD, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x01, 0x3F, 0x74,
+0x10, 0xF0, 0xEF, 0x64, 0x01, 0x70, 0x1B, 0x90,
+0x82, 0x70, 0xE0, 0x7D, 0x10, 0x7F, 0x03, 0x60,
+0x07, 0xD1, 0x42, 0xF1, 0xE1, 0xF0, 0x80, 0x05,
+0xD1, 0x2A, 0x12, 0x4D, 0xC8, 0x12, 0x56, 0x30,
+0x80, 0x1B, 0x90, 0x82, 0x70, 0xE0, 0x7D, 0x10,
+0x7F, 0x03, 0x60, 0x04, 0xD1, 0x42, 0x80, 0x02,
+0xD1, 0x2A, 0xB1, 0xA7, 0x7D, 0x01, 0x7F, 0x02,
+0xB1, 0xAB, 0x12, 0x55, 0x55, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0x74, 0x45, 0x12, 0x8A, 0xBE, 0xFE,
+0xF6, 0x74, 0x38, 0x2F, 0xF5, 0x82, 0xE4, 0x34,
+0x01, 0xF5, 0x83, 0xEE, 0xF0, 0x22, 0x7D, 0x03,
+0x7F, 0x02, 0x74, 0x45, 0x2F, 0xF8, 0xE6, 0x4D,
+0x80, 0xE5, 0x90, 0x81, 0x88, 0xE0, 0x54, 0xFB,
+0xF0, 0xE4, 0x90, 0x81, 0x96, 0xF0, 0xA3, 0xF0,
+0x90, 0x81, 0x91, 0xF0, 0x90, 0x81, 0x89, 0xE0,
+0x54, 0xF7, 0xF0, 0x54, 0xBF, 0xF0, 0xB1, 0xA1,
+0x7D, 0x10, 0x7F, 0x03, 0x80, 0xBC, 0x12, 0x1F,
+0xA4, 0xFF, 0x54, 0x01, 0xFE, 0x90, 0x82, 0x6E,
+0x12, 0x89, 0xF0, 0x4F, 0xF0, 0x12, 0x5D, 0x33,
+0x90, 0x82, 0x6F, 0x51, 0x76, 0x90, 0x82, 0x70,
+0xF0, 0x12, 0x8A, 0x72, 0x90, 0x82, 0x6E, 0xE0,
+0x54, 0x01, 0xFF, 0xA1, 0xDD, 0x90, 0x82, 0xFE,
+0x12, 0x47, 0xEF, 0xD1, 0x4A, 0x90, 0x81, 0x8D,
+0xE0, 0xFF, 0x12, 0x4F, 0x7D, 0x90, 0x81, 0x8D,
+0xE0, 0x60, 0x18, 0x90, 0x82, 0xFE, 0x12, 0x5D,
+0x30, 0x54, 0x0F, 0xFF, 0x51, 0x77, 0xFD, 0x12,
+0x87, 0xE9, 0x12, 0x85, 0x63, 0x74, 0x01, 0xF0,
+0x12, 0x5B, 0x02, 0x22, 0x90, 0x06, 0xA9, 0xE0,
+0xF5, 0x4E, 0x54, 0xC0, 0x70, 0x08, 0xF1, 0x06,
+0xF0, 0x54, 0xFD, 0xF0, 0x61, 0xFB, 0xE5, 0x4E,
+0x30, 0xE6, 0x16, 0x90, 0x81, 0x8D, 0xE0, 0x64,
+0x01, 0x70, 0x11, 0xF1, 0x0D, 0x64, 0x02, 0x60,
+0x04, 0xF1, 0xB3, 0x80, 0x07, 0xF1, 0x86, 0x80,
+0x03, 0xF1, 0x06, 0xF0, 0xE5, 0x4E, 0x90, 0x81,
+0x91, 0x30, 0xE7, 0x05, 0x12, 0x50, 0xFD, 0xE1,
+0xD7, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90, 0x81,
+0x91, 0xE0, 0x54, 0xFE, 0x22, 0x90, 0x81, 0x91,
+0xE0, 0x44, 0x01, 0xF0, 0x90, 0x81, 0x8B, 0xE0,
+0x54, 0x0F, 0x22, 0x90, 0x06, 0xA9, 0xE0, 0x90,
+0x82, 0x76, 0xF0, 0xE0, 0xFD, 0x54, 0xC0, 0x70,
+0x05, 0xF1, 0x06, 0xF0, 0x80, 0x54, 0xED, 0x30,
+0xE6, 0x3D, 0x90, 0x81, 0x8D, 0xE0, 0x64, 0x02,
+0x70, 0x27, 0x90, 0x81, 0x88, 0xE0, 0xFF, 0xC3,
+0x13, 0x20, 0xE0, 0x09, 0x90, 0x81, 0x91, 0xE0,
+0x44, 0x01, 0xF0, 0x80, 0x1A, 0xF1, 0x14, 0x64,
+0x01, 0x70, 0x1F, 0x90, 0x81, 0x91, 0xE0, 0x44,
+0x04, 0xF0, 0x7F, 0x01, 0x12, 0x57, 0x50, 0x80,
+0x11, 0xF1, 0x0D, 0x64, 0x02, 0x60, 0x04, 0xF1,
+0xB3, 0x80, 0x07, 0xF1, 0x86, 0x80, 0x03, 0xF1,
+0x06, 0xF0, 0x90, 0x82, 0x76, 0xE0, 0x90, 0x81,
+0x91, 0x30, 0xE7, 0x05, 0x12, 0x50, 0xFD, 0x80,
+0x56, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x12, 0x82,
+0x46, 0x90, 0x81, 0x90, 0xE0, 0x64, 0x0C, 0x60,
+0x09, 0x12, 0x81, 0x5E, 0x12, 0x54, 0x6D, 0x12,
+0x56, 0x3F, 0x22, 0xE4, 0xFF, 0x31, 0xF6, 0xBF,
+0x01, 0x10, 0x90, 0x81, 0x8D, 0xE0, 0x60, 0x0A,
+0xF1, 0x14, 0x64, 0x02, 0x60, 0x02, 0x80, 0x03,
+0xF1, 0x86, 0x22, 0x90, 0x04, 0x1D, 0xE0, 0x70,
+0x1D, 0x90, 0x80, 0x87, 0xE0, 0xFF, 0x90, 0x83,
+0x58, 0x74, 0x09, 0xF0, 0x7B, 0x18, 0xE4, 0xFD,
+0x12, 0x86, 0x63, 0x90, 0x82, 0x77, 0xEE, 0xF0,
+0xA3, 0xEF, 0xF0, 0x12, 0x8A, 0x6B, 0x22, 0x90,
+0x81, 0x88, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0x22,
+0x22, 0x90, 0x82, 0x70, 0xE0, 0x90, 0x05, 0x73,
+0x22, 0x75, 0xE8, 0x03, 0x75, 0xA8, 0x84, 0x22,
+0xE4, 0x90, 0x82, 0x90, 0xF0, 0xA3, 0xF0, 0xA3,
+0xF0, 0x90, 0x82, 0x90, 0xE0, 0x64, 0x01, 0xF0,
+0x24, 0xF0, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x6F,
+0xA3, 0xF0, 0x90, 0x81, 0x8D, 0xE0, 0x60, 0x0F,
+0x90, 0x81, 0x90, 0xE0, 0xFF, 0x90, 0x81, 0x8F,
+0xE0, 0x6F, 0x60, 0x03, 0x12, 0x6B, 0xFB, 0xC2,
+0xAF, 0x12, 0x84, 0x42, 0xBF, 0x01, 0x02, 0x11,
+0x3A, 0xD2, 0xAF, 0xF1, 0x74, 0x12, 0x32, 0x9E,
+0xBF, 0x01, 0x02, 0x31, 0x9F, 0x12, 0x43, 0x4D,
+0x80, 0xBF, 0x90, 0x81, 0x88, 0xE0, 0x30, 0xE0,
+0x19, 0x90, 0x81, 0x83, 0xE0, 0xFF, 0x30, 0xE0,
+0x0F, 0xC3, 0x13, 0x30, 0xE0, 0x08, 0x12, 0x89,
+0x49, 0xBF, 0x01, 0x06, 0x80, 0x02, 0x80, 0x00,
+0x11, 0x5B, 0x22, 0x90, 0x81, 0x90, 0xE0, 0xFF,
+0x60, 0x03, 0xB4, 0x08, 0x0D, 0x11, 0xF8, 0xBF,
+0x01, 0x08, 0x11, 0x73, 0x90, 0x01, 0xE5, 0xE0,
+0x04, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x31, 0x47, 0x11, 0x83, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0x12, 0x87, 0xCC, 0x90, 0x81,
+0x98, 0xE0, 0x20, 0xE0, 0x0C, 0x90, 0x00, 0x26,
+0xE0, 0x54, 0x7F, 0xFD, 0x7F, 0x26, 0x12, 0x32,
+0x1E, 0x90, 0x00, 0x08, 0xE0, 0x54, 0xEF, 0xFD,
+0x7F, 0x08, 0x12, 0x32, 0x1E, 0xE4, 0xFF, 0x90,
+0x82, 0x93, 0xF1, 0x8B, 0x90, 0x01, 0x09, 0xE0,
+0x7F, 0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01, 0x90,
+0x82, 0x93, 0xE0, 0x6F, 0x60, 0x39, 0xC3, 0x90,
+0x82, 0x95, 0xE0, 0x94, 0x88, 0x90, 0x82, 0x94,
+0xE0, 0x94, 0x13, 0x40, 0x08, 0x90, 0x01, 0xC0,
+0xE0, 0x44, 0x10, 0xF0, 0x22, 0x90, 0x82, 0x94,
+0xF1, 0x75, 0x7F, 0x14, 0x7E, 0x00, 0x12, 0x32,
+0xAA, 0xD3, 0x90, 0x82, 0x95, 0xE0, 0x94, 0x32,
+0x90, 0x82, 0x94, 0xE0, 0x94, 0x00, 0x40, 0xBC,
+0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE0, 0xB5, 0x22,
+0x90, 0x82, 0x6E, 0xE0, 0xC3, 0x13, 0x20, 0xE0,
+0x35, 0x90, 0x02, 0x87, 0xE0, 0x60, 0x02, 0x80,
+0x08, 0x90, 0x01, 0x00, 0xE0, 0x64, 0x3F, 0x60,
+0x05, 0x75, 0x53, 0x01, 0x80, 0x22, 0x90, 0x02,
+0x96, 0xE0, 0x60, 0x05, 0x75, 0x53, 0x10, 0x80,
+0x17, 0x90, 0x02, 0x86, 0xE0, 0x20, 0xE1, 0x02,
+0x80, 0x07, 0x90, 0x02, 0x86, 0xE0, 0x30, 0xE3,
+0x05, 0x75, 0x53, 0x04, 0x80, 0x02, 0xE1, 0x83,
+0x90, 0x01, 0xB9, 0x74, 0x08, 0xF0, 0x90, 0x01,
+0xB8, 0xE5, 0x53, 0xF0, 0x7F, 0x00, 0x22, 0x90,
+0x81, 0x98, 0xE0, 0xFD, 0x7F, 0x93, 0x12, 0x32,
+0x1E, 0x90, 0x81, 0x8E, 0xE0, 0x60, 0x12, 0x90,
+0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x05, 0x74, 0x10,
+0xF0, 0x80, 0x06, 0x90, 0x01, 0x2F, 0x74, 0x90,
+0xF0, 0x90, 0x00, 0x08, 0xE0, 0x44, 0x10, 0xFD,
+0x7F, 0x08, 0x12, 0x32, 0x1E, 0x7F, 0x01, 0x11,
+0xA7, 0x90, 0x81, 0x98, 0xE0, 0x20, 0xE0, 0x0C,
+0x90, 0x00, 0x26, 0xE0, 0x44, 0x80, 0xFD, 0x7F,
+0x26, 0x12, 0x32, 0x1E, 0x90, 0x00, 0x90, 0xE0,
+0x44, 0x01, 0xFD, 0x7F, 0x90, 0x12, 0x32, 0x1E,
+0x7F, 0x14, 0x7E, 0x00, 0x02, 0x32, 0xAA, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x2D,
+0xA7, 0xE4, 0xF5, 0x55, 0x12, 0x32, 0x9E, 0xEF,
+0x60, 0x72, 0x63, 0x55, 0x01, 0xE5, 0x55, 0x24,
+0x9F, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x71, 0xA3,
+0xF0, 0x90, 0x00, 0x88, 0xE0, 0xF5, 0x53, 0xF5,
+0x54, 0x54, 0x0F, 0x60, 0xDF, 0xE5, 0x53, 0x30,
+0xE0, 0x0B, 0x20, 0xE4, 0x03, 0x12, 0x29, 0xC5,
+0x53, 0x54, 0xEE, 0x80, 0x3E, 0xE5, 0x53, 0x30,
+0xE1, 0x16, 0x20, 0xE5, 0x0E, 0x12, 0x11, 0xBD,
+0xEF, 0x70, 0x03, 0x43, 0x54, 0x20, 0x90, 0x01,
+0x06, 0xE4, 0xF0, 0x53, 0x54, 0xFD, 0x80, 0x23,
+0xE5, 0x53, 0x30, 0xE2, 0x0B, 0x20, 0xE6, 0x03,
+0x12, 0x4B, 0x18, 0x53, 0x54, 0xFB, 0x80, 0x13,
+0xE5, 0x53, 0x30, 0xE3, 0x0E, 0x20, 0xE7, 0x08,
+0x51, 0x29, 0xEF, 0x70, 0x03, 0x43, 0x54, 0x80,
+0x53, 0x54, 0xF7, 0xAD, 0x54, 0x7F, 0x88, 0x12,
+0x32, 0x1E, 0x80, 0x88, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x78, 0x10, 0x74, 0x01, 0xF2, 0x90, 0x02,
+0x09, 0xE0, 0x78, 0x00, 0xF2, 0x08, 0x74, 0x20,
+0xF2, 0x18, 0xE2, 0xFF, 0x30, 0xE0, 0x05, 0x08,
+0xE2, 0x24, 0x80, 0xF2, 0xEF, 0xC3, 0x13, 0x90,
+0xFD, 0x10, 0xF0, 0x78, 0x01, 0xE2, 0x91, 0x51,
+0x78, 0x03, 0xF2, 0x64, 0x04, 0x60, 0x0D, 0xE2,
+0xFF, 0x64, 0x08, 0x60, 0x07, 0xEF, 0x64, 0x0C,
+0x60, 0x02, 0x81, 0x47, 0xE4, 0x78, 0x02, 0xF2,
+0x78, 0x03, 0xE2, 0xFF, 0x18, 0xE2, 0xC3, 0x9F,
+0x50, 0x25, 0xE2, 0xFD, 0x18, 0xE2, 0x2D, 0x90,
+0x82, 0x93, 0xF0, 0xE0, 0xFF, 0x91, 0x51, 0xFE,
+0x74, 0x04, 0x2D, 0xF8, 0xEE, 0xF2, 0xEF, 0xB4,
+0xFF, 0x06, 0x90, 0xFD, 0x10, 0xE0, 0x04, 0xF0,
+0x78, 0x02, 0xE2, 0x04, 0xF2, 0x80, 0xD1, 0x78,
+0x04, 0xE2, 0x78, 0x12, 0xF2, 0xFF, 0x78, 0x05,
+0xE2, 0x78, 0x11, 0xF2, 0x78, 0x06, 0xE2, 0x78,
+0x13, 0xF2, 0x78, 0x07, 0xE2, 0x78, 0x14, 0xF2,
+0x78, 0x08, 0xE2, 0x78, 0x33, 0xF2, 0x78, 0x09,
+0xE2, 0x78, 0x34, 0xF2, 0x78, 0x0A, 0xE2, 0x78,
+0x35, 0xF2, 0x78, 0x0B, 0xE2, 0x78, 0x36, 0xF2,
+0x78, 0x0C, 0xE2, 0x78, 0x37, 0xF2, 0x78, 0x0D,
+0xE2, 0x78, 0x38, 0xF2, 0x78, 0x0E, 0xE2, 0x78,
+0x39, 0xF2, 0x78, 0x0F, 0xE2, 0x78, 0x3A, 0xF2,
+0xE4, 0x78, 0x15, 0xF2, 0xEF, 0x24, 0xF8, 0x60,
+0x56, 0x24, 0xFC, 0x60, 0x4D, 0x24, 0x08, 0x60,
+0x02, 0x81, 0x29, 0x78, 0x11, 0xE2, 0xB4, 0x01,
+0x05, 0x12, 0x29, 0xC5, 0x81, 0x2E, 0x78, 0x11,
+0xE2, 0xB4, 0x02, 0x05, 0x12, 0x11, 0xBD, 0x81,
+0x2E, 0x78, 0x11, 0xE2, 0xB4, 0x03, 0x05, 0x12,
+0x4B, 0x18, 0x81, 0x2E, 0x78, 0x11, 0xE2, 0xB4,
+0x10, 0x07, 0x91, 0x68, 0x12, 0x32, 0xAA, 0x81,
+0x2E, 0x78, 0x11, 0xE2, 0xB4, 0x11, 0x07, 0x91,
+0x68, 0x12, 0x32, 0x06, 0x81, 0x2E, 0x78, 0x11,
+0xE2, 0xF4, 0x60, 0x02, 0x81, 0x2E, 0x18, 0xF2,
+0x81, 0x2E, 0x78, 0x15, 0x74, 0x01, 0xF2, 0x78,
+0x11, 0xE2, 0x64, 0x07, 0x60, 0x02, 0x81, 0x13,
+0x78, 0x34, 0x91, 0x4A, 0x78, 0x08, 0x12, 0x20,
+0xBB, 0xC0, 0x04, 0x91, 0x61, 0x78, 0x33, 0x91,
+0x4A, 0xD0, 0x00, 0x12, 0x47, 0x7F, 0xC0, 0x04,
+0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x78, 0x35,
+0x91, 0x4A, 0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12,
+0x47, 0x7F, 0x78, 0x18, 0x12, 0x47, 0xCE, 0x78,
+0x15, 0xE2, 0x60, 0x79, 0x18, 0xE2, 0xFF, 0x18,
+0xE2, 0xFD, 0xF1, 0x44, 0x78, 0x1C, 0x12, 0x47,
+0xCE, 0x78, 0x38, 0x91, 0x4A, 0x78, 0x08, 0x12,
+0x20, 0xBB, 0xC0, 0x04, 0x91, 0x61, 0x78, 0x37,
+0x91, 0x4A, 0xD0, 0x00, 0x12, 0x47, 0x7F, 0xC0,
+0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x78,
+0x39, 0x91, 0x4A, 0x78, 0x10, 0x12, 0x20, 0xBB,
+0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00,
+0x12, 0x47, 0x7F, 0x78, 0x20, 0x12, 0x47, 0xCE,
+0x78, 0x20, 0x12, 0x47, 0xA9, 0x12, 0x20, 0x9B,
+0x78, 0x1C, 0x12, 0x47, 0xC1, 0x12, 0x47, 0x72,
+0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07,
+0x78, 0x18, 0x12, 0x47, 0xA9, 0x78, 0x20, 0x12,
+0x47, 0xC1, 0x12, 0x47, 0x72, 0xD0, 0x03, 0xD0,
+0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x47, 0x7F,
+0x78, 0x18, 0x12, 0x47, 0xCE, 0x78, 0x18, 0x12,
+0x47, 0xA9, 0x90, 0x83, 0x42, 0x12, 0x20, 0xCE,
+0x78, 0x13, 0xE2, 0xFD, 0x08, 0xE2, 0xFF, 0xF1,
+0x52, 0x80, 0x1B, 0x78, 0x13, 0xE2, 0xFF, 0x08,
+0xE2, 0xFD, 0x78, 0x11, 0xE2, 0xFB, 0x78, 0x15,
+0xE2, 0x90, 0x82, 0xF5, 0xF0, 0xB1, 0x7C, 0x80,
+0x05, 0x78, 0x10, 0x74, 0x02, 0xF2, 0x78, 0x10,
+0xE2, 0xFF, 0xC3, 0x94, 0x02, 0x50, 0x10, 0xEF,
+0x60, 0x0A, 0x78, 0x02, 0xE2, 0xFF, 0x18, 0xE2,
+0x2F, 0xF2, 0x41, 0x4B, 0x7F, 0x01, 0x22, 0x7F,
+0x00, 0x22, 0xE2, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE,
+0x22, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0xFC,
+0xF5, 0x83, 0xE0, 0x22, 0x12, 0x20, 0xBB, 0xA8,
+0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB, 0x07, 0x22,
+0x78, 0x14, 0xE2, 0xFE, 0x18, 0xE2, 0xFD, 0xED,
+0xFF, 0x78, 0x16, 0xEE, 0xF2, 0xFE, 0x08, 0xEF,
+0xF2, 0xFF, 0x22, 0x90, 0x83, 0x18, 0xF1, 0x7C,
+0x12, 0x20, 0xDA, 0x00, 0x00, 0x00, 0x00, 0xE4,
+0x90, 0x83, 0x26, 0xF0, 0x7F, 0x24, 0x7E, 0x08,
+0x12, 0x2D, 0x5C, 0x90, 0x83, 0x1E, 0x12, 0x20,
+0xCE, 0x90, 0x83, 0x18, 0xE0, 0xFB, 0x70, 0x04,
+0xB1, 0x5B, 0x80, 0x07, 0xEB, 0xB1, 0x6A, 0xFF,
+0x12, 0x2D, 0x5C, 0x90, 0x83, 0x22, 0x12, 0x20,
+0xCE, 0x90, 0x83, 0x19, 0x12, 0x4B, 0x11, 0x78,
+0x17, 0x91, 0x5C, 0x90, 0x83, 0x22, 0x12, 0x47,
+0x9D, 0xED, 0x54, 0x7F, 0xFD, 0xEC, 0x54, 0x80,
+0xFC, 0x12, 0x47, 0x7F, 0xEC, 0x44, 0x80, 0xFC,
+0x90, 0x83, 0x22, 0x12, 0x20, 0xCE, 0xB1, 0x5B,
+0xEC, 0x54, 0x7F, 0xFC, 0xB1, 0x64, 0xD1, 0xC3,
+0xB1, 0x6A, 0xFF, 0xC0, 0x06, 0xC0, 0x07, 0x90,
+0x83, 0x22, 0xB1, 0x61, 0xD0, 0x07, 0xD0, 0x06,
+0x12, 0x2E, 0xA2, 0xB1, 0x5B, 0xEC, 0x44, 0x80,
+0xFC, 0xB1, 0x64, 0xD1, 0xC3, 0x70, 0x04, 0x7F,
+0x20, 0x80, 0x09, 0x90, 0x83, 0x18, 0xE0, 0xB4,
+0x01, 0x16, 0x7F, 0x28, 0x7E, 0x08, 0x12, 0x2D,
+0x5C, 0x78, 0x08, 0x12, 0x20, 0xA8, 0xEF, 0x54,
+0x01, 0xFF, 0xE4, 0x90, 0x83, 0x26, 0xEF, 0xF0,
+0x90, 0x83, 0x26, 0xE0, 0x90, 0x83, 0x18, 0x60,
+0x0E, 0xE0, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x66,
+0xF5, 0x82, 0xE4, 0x34, 0x87, 0x80, 0x0C, 0xE0,
+0x75, 0xF0, 0x08, 0xA4, 0x24, 0x64, 0xF5, 0x82,
+0xE4, 0x34, 0x87, 0xB1, 0x75, 0xFF, 0x12, 0x2D,
+0x5C, 0xED, 0x54, 0x0F, 0xFD, 0xE4, 0xFC, 0x90,
+0x83, 0x1A, 0x12, 0x20, 0xCE, 0x90, 0x83, 0x1A,
+0x02, 0x47, 0x9D, 0x90, 0x83, 0x1E, 0x02, 0x47,
+0x9D, 0x12, 0x47, 0x9D, 0x90, 0x85, 0xBB, 0x02,
+0x20, 0xCE, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x62,
+0xF5, 0x82, 0xE4, 0x34, 0x87, 0xF5, 0x83, 0xE0,
+0xFE, 0xA3, 0xE0, 0x22, 0xAC, 0x07, 0xED, 0xAD,
+0x04, 0x78, 0x24, 0xF2, 0xED, 0x08, 0xF2, 0xEB,
+0xB4, 0x04, 0x07, 0x78, 0x27, 0x74, 0x01, 0xF2,
+0x80, 0x0E, 0xEB, 0x78, 0x27, 0xB4, 0x05, 0x05,
+0x74, 0x02, 0xF2, 0x80, 0x03, 0x74, 0x04, 0xF2,
+0xD1, 0xBB, 0xE2, 0x94, 0x00, 0x50, 0x44, 0xE4,
+0x78, 0x26, 0xF2, 0xD1, 0x94, 0x40, 0x02, 0xC1,
+0x93, 0xD1, 0x9E, 0x60, 0x1F, 0x74, 0x37, 0x2E,
+0xF8, 0xE2, 0x78, 0x32, 0xF2, 0xEE, 0xFF, 0x78,
+0x25, 0xE2, 0x2F, 0xFF, 0x18, 0xE2, 0x34, 0x00,
+0x8F, 0x82, 0xF5, 0x83, 0xE0, 0x78, 0x29, 0xF2,
+0x78, 0x32, 0xD1, 0xDD, 0x78, 0x24, 0x08, 0xE2,
+0xFF, 0x08, 0xE2, 0x2F, 0xFF, 0x78, 0x28, 0xE2,
+0xFD, 0x12, 0x32, 0x1E, 0x78, 0x26, 0xE2, 0x04,
+0xF2, 0x80, 0xC0, 0xD1, 0xBB, 0xE2, 0x94, 0x07,
+0x50, 0x2F, 0xE4, 0x78, 0x26, 0xF2, 0xD1, 0x94,
+0x40, 0x02, 0xC1, 0x93, 0xD1, 0x9E, 0x60, 0x14,
+0x78, 0x26, 0xE2, 0xFF, 0xD1, 0xCF, 0xE0, 0x78,
+0x29, 0xF2, 0x74, 0x37, 0x2F, 0xF8, 0xE2, 0x78,
+0x32, 0xF2, 0xD1, 0xDD, 0xD1, 0xB3, 0xD1, 0xCF,
+0xEF, 0xF0, 0x78, 0x26, 0xE2, 0x04, 0xF2, 0x80,
+0xD5, 0x90, 0x82, 0xF5, 0xE0, 0x60, 0x0A, 0xD1,
+0xAB, 0x12, 0x2D, 0x5C, 0x78, 0x2E, 0x12, 0x47,
+0xCE, 0xE4, 0x78, 0x26, 0xF2, 0xD1, 0x94, 0x50,
+0x4E, 0xD1, 0x9E, 0x60, 0x2B, 0x78, 0x2E, 0x12,
+0x47, 0xA9, 0x78, 0x26, 0xE2, 0xFB, 0x75, 0xF0,
+0x08, 0xA4, 0xF9, 0xF8, 0x12, 0x20, 0xA8, 0x78,
+0x29, 0xEF, 0xF2, 0x74, 0x37, 0x2B, 0xF8, 0xE2,
+0x78, 0x32, 0xF2, 0xE2, 0xFE, 0xF4, 0x5F, 0xFF,
+0x78, 0x28, 0xE2, 0xFD, 0xEE, 0x5D, 0x4F, 0xF2,
+0xD1, 0xB3, 0xFD, 0xC3, 0x74, 0x03, 0x9D, 0xFD,
+0xE4, 0x94, 0x00, 0xFC, 0x7B, 0xFE, 0x74, 0x2A,
+0x2D, 0xF9, 0x74, 0x80, 0x3C, 0xFA, 0xEF, 0x12,
+0x1F, 0xEA, 0xE2, 0x04, 0xF2, 0x80, 0xAE, 0x78,
+0x2A, 0x12, 0x47, 0xA9, 0xB1, 0x64, 0xD1, 0xAB,
+0x12, 0x2E, 0xA2, 0x22, 0x78, 0x27, 0xE2, 0xFF,
+0x18, 0xE2, 0xFE, 0xC3, 0x9F, 0x22, 0x74, 0x33,
+0x2E, 0xF8, 0xE2, 0x78, 0x28, 0xF2, 0x90, 0x82,
+0xF5, 0xE0, 0x22, 0x78, 0x24, 0xE2, 0xFE, 0x08,
+0xE2, 0xFF, 0x22, 0x78, 0x28, 0xE2, 0xFF, 0x78,
+0x26, 0xE2, 0x22, 0xD3, 0x78, 0x25, 0xE2, 0x94,
+0xFF, 0x18, 0x22, 0x7F, 0x24, 0x7E, 0x08, 0x12,
+0x2E, 0xA2, 0x90, 0x83, 0x18, 0xE0, 0x22, 0xFD,
+0x18, 0xE2, 0x2D, 0xFD, 0x18, 0xE2, 0x34, 0x00,
+0x8D, 0x82, 0xF5, 0x83, 0x22, 0xE2, 0xFF, 0xF4,
+0xFE, 0x78, 0x29, 0xE2, 0x5E, 0xFE, 0x18, 0xE2,
+0xFD, 0xEF, 0x5D, 0x4E, 0xF2, 0x22, 0x90, 0x83,
+0x36, 0xEF, 0xF0, 0xAB, 0x05, 0x90, 0x83, 0x3C,
+0x12, 0x20, 0xDA, 0x00, 0x00, 0x00, 0x00, 0xAF,
+0x03, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x14, 0x91,
+0x5C, 0x90, 0x83, 0x38, 0x12, 0x47, 0x9D, 0xED,
+0x54, 0x0F, 0xFD, 0xE4, 0xFC, 0x12, 0x47, 0x7F,
+0xEC, 0x54, 0x0F, 0xFC, 0x90, 0x83, 0x3C, 0x12,
+0x20, 0xCE, 0x90, 0x83, 0x36, 0xE0, 0x75, 0xF0,
+0x08, 0xA4, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34,
+0x87, 0xB1, 0x75, 0xFF, 0xC0, 0x06, 0xC0, 0x07,
+0x90, 0x83, 0x3C, 0xB1, 0x61, 0xD0, 0x07, 0xD0,
+0x06, 0x02, 0x2E, 0xA2, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x91, 0x7B, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0xC0, 0x07, 0xC0, 0x05, 0x90, 0x83, 0x42,
+0x12, 0x47, 0x9D, 0x90, 0x83, 0x38, 0x12, 0x20,
+0xCE, 0xD0, 0x05, 0xD0, 0x07, 0xD1, 0xEE, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x22, 0xE4, 0x75, 0xF0,
+0x01, 0x02, 0x46, 0x9F, 0xEF, 0xF0, 0xA3, 0xED,
+0xF0, 0xA3, 0x22, 0x90, 0x01, 0xB8, 0xE4, 0xF0,
+0x7F, 0x01, 0x22, 0xEF, 0xF0, 0xE4, 0xA3, 0xF0,
+0xA3, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x83, 0x51, 0xEE, 0xF0, 0xA3,
+0xF1, 0x8B, 0x90, 0x83, 0x51, 0xE0, 0xFE, 0xA3,
+0xE0, 0xF5, 0x82, 0x8E, 0x83, 0xE0, 0x60, 0x28,
+0xC3, 0x90, 0x83, 0x54, 0xE0, 0x94, 0xE8, 0x90,
+0x83, 0x53, 0xE0, 0x94, 0x03, 0x40, 0x0B, 0x90,
+0x01, 0xC0, 0xE0, 0x44, 0x80, 0xF0, 0x7F, 0x00,
+0x80, 0x10, 0x90, 0x83, 0x53, 0xF1, 0x75, 0x7F,
+0x0A, 0x7E, 0x00, 0x12, 0x32, 0xAA, 0x80, 0xCA,
+0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4,
+0xFB, 0xFA, 0xFD, 0x7F, 0x01, 0x12, 0x45, 0x4E,
+0x90, 0x82, 0xF6, 0xEF, 0xF0, 0x60, 0xF0, 0x90,
+0x80, 0x3C, 0xE0, 0xFF, 0x70, 0x04, 0xA3, 0xE0,
+0x60, 0xE5, 0xC2, 0xAF, 0xEF, 0x30, 0xE0, 0x0A,
+0x90, 0x80, 0x3C, 0xE0, 0x54, 0xFE, 0xF0, 0x12,
+0x5D, 0x39, 0x11, 0x22, 0x30, 0xE1, 0x05, 0x54,
+0xFD, 0xF0, 0x11, 0x2C, 0x11, 0x22, 0x30, 0xE2,
+0x05, 0x54, 0xFB, 0xF0, 0x31, 0xBD, 0xD2, 0xAF,
+0x80, 0xCD, 0xD2, 0xAF, 0xC2, 0xAF, 0x90, 0x80,
+0x3C, 0xE0, 0xFF, 0x22, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x80, 0xDE, 0xE0, 0xFF,
+0x90, 0x80, 0xDD, 0xE0, 0xB5, 0x07, 0x04, 0x7F,
+0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70, 0x3F,
+0x90, 0x80, 0xDD, 0xE0, 0xFE, 0x75, 0xF0, 0x08,
+0x90, 0x80, 0x8D, 0x12, 0x47, 0xDA, 0xE0, 0xFD,
+0xEE, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x8E, 0xF9,
+0x74, 0x80, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0xAF,
+0x05, 0x12, 0x5C, 0xAA, 0x90, 0x80, 0xDD, 0x31,
+0xB6, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60,
+0x05, 0xE4, 0x90, 0x80, 0xDD, 0xF0, 0x11, 0x8C,
+0x90, 0x80, 0x3C, 0xE0, 0x44, 0x02, 0xF0, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x90, 0x01, 0xCC, 0xE0,
+0x54, 0x0F, 0x90, 0x83, 0x6A, 0xF0, 0x90, 0x83,
+0x6A, 0xE0, 0xFD, 0x70, 0x02, 0x21, 0x8B, 0x90,
+0x80, 0xDD, 0xE0, 0xFF, 0x70, 0x06, 0xA3, 0xE0,
+0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90,
+0x80, 0xDE, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01,
+0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x08, 0x90,
+0x01, 0xC1, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90,
+0x83, 0x68, 0xE0, 0x12, 0x64, 0xA5, 0x80, 0x05,
+0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF,
+0xEF, 0x5D, 0x70, 0x02, 0x21, 0x6D, 0xE4, 0x90,
+0x83, 0x6B, 0xF0, 0x90, 0x83, 0x6B, 0xE0, 0xF9,
+0xC3, 0x94, 0x04, 0x50, 0x31, 0x31, 0x8C, 0xA4,
+0xFF, 0xE9, 0xFD, 0x7C, 0x00, 0x2F, 0xFF, 0xEC,
+0x35, 0xF0, 0xFE, 0x74, 0xD0, 0x31, 0xA4, 0x90,
+0x80, 0x8D, 0x31, 0x94, 0x31, 0x8C, 0xA4, 0x2D,
+0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74, 0xF0, 0x31,
+0xA4, 0x90, 0x80, 0x91, 0x31, 0x94, 0x90, 0x83,
+0x6B, 0xE0, 0x04, 0xF0, 0x80, 0xC5, 0x90, 0x83,
+0x6A, 0xE0, 0xFF, 0x90, 0x83, 0x68, 0xE0, 0xFE,
+0x74, 0x01, 0xA8, 0x06, 0x08, 0x80, 0x02, 0xC3,
+0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0x90, 0x83, 0x6A,
+0xF0, 0x90, 0x83, 0x68, 0xE0, 0xFF, 0x74, 0x01,
+0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8,
+0xFC, 0x90, 0x01, 0xCC, 0xF0, 0x90, 0x83, 0x68,
+0xE0, 0x04, 0xF0, 0xE0, 0x54, 0x03, 0xF0, 0x90,
+0x80, 0xDE, 0x31, 0xB6, 0xB4, 0x0A, 0x02, 0x7F,
+0x01, 0xEF, 0x70, 0x02, 0x01, 0x96, 0xE4, 0x90,
+0x80, 0xDE, 0xF0, 0x01, 0x96, 0x90, 0x01, 0xC0,
+0xE0, 0x44, 0x02, 0xF0, 0x90, 0x83, 0x68, 0xE0,
+0x44, 0x80, 0x90, 0x00, 0x8A, 0xF0, 0x31, 0x8C,
+0x90, 0x01, 0xD0, 0x12, 0x47, 0xDA, 0xE0, 0x90,
+0x01, 0xC3, 0xF0, 0x22, 0x90, 0x83, 0x68, 0xE0,
+0x75, 0xF0, 0x04, 0x22, 0x12, 0x47, 0xDA, 0xE5,
+0x82, 0x29, 0xF5, 0x82, 0xE4, 0x35, 0x83, 0xF5,
+0x83, 0xEF, 0xF0, 0x22, 0x2F, 0xF5, 0x82, 0x74,
+0x01, 0x3E, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x80,
+0xDE, 0xE0, 0x75, 0xF0, 0x08, 0x22, 0xE0, 0x04,
+0xF0, 0xE0, 0x7F, 0x00, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFF, 0x90, 0x81,
+0x76, 0xE0, 0xFE, 0x90, 0x81, 0x75, 0xE0, 0xFD,
+0xB5, 0x06, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E,
+0x00, 0xEE, 0x64, 0x01, 0x60, 0x42, 0x90, 0x01,
+0xAF, 0xE0, 0x70, 0x0B, 0xED, 0x91, 0x14, 0xFA,
+0x7B, 0x01, 0x12, 0x83, 0x05, 0x7F, 0x01, 0xEF,
+0x60, 0x2E, 0x90, 0x81, 0x75, 0x31, 0xB6, 0xB4,
+0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4,
+0x90, 0x81, 0x75, 0xF0, 0x90, 0x81, 0x76, 0xE0,
+0xFF, 0x90, 0x81, 0x75, 0xE0, 0xB5, 0x07, 0x04,
+0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70,
+0x07, 0x90, 0x80, 0x3C, 0xE0, 0x44, 0x04, 0xF0,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x11, 0x8C, 0x7F,
+0x02, 0x8F, 0x0F, 0x7F, 0x02, 0x12, 0x45, 0x27,
+0x90, 0x80, 0x3C, 0xE0, 0x45, 0x0F, 0xF0, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
+0x81, 0x8A, 0xE0, 0xFE, 0xC3, 0x13, 0x30, 0xE0,
+0x1D, 0x90, 0x83, 0x27, 0x74, 0x1E, 0xF0, 0x90,
+0x83, 0x35, 0x74, 0x01, 0xF0, 0x90, 0x83, 0x29,
+0xEF, 0xF0, 0x7B, 0x01, 0x7A, 0x83, 0x79, 0x27,
+0x51, 0x6B, 0x7F, 0x04, 0x51, 0x29, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x81, 0x75, 0xE0, 0xFF, 0x70,
+0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF,
+0x14, 0xFF, 0x90, 0x81, 0x76, 0xE0, 0xB5, 0x07,
+0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF,
+0x60, 0x09, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x02,
+0xF0, 0x80, 0x28, 0xC0, 0x01, 0x90, 0x81, 0x76,
+0xE0, 0x91, 0x14, 0xA8, 0x01, 0xFC, 0x7D, 0x01,
+0xD0, 0x01, 0x7E, 0x00, 0x7F, 0x0F, 0x12, 0x46,
+0x79, 0x90, 0x81, 0x76, 0x31, 0xB6, 0xB4, 0x0A,
+0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90,
+0x81, 0x76, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0xAD, 0x07, 0x90, 0x83, 0x06, 0x74, 0x13, 0xF0,
+0x90, 0x83, 0x14, 0x74, 0x0C, 0xF0, 0x90, 0x83,
+0x08, 0xED, 0xF0, 0x12, 0x65, 0xCE, 0x71, 0x4D,
+0x90, 0x83, 0x09, 0xF0, 0xA3, 0xEB, 0xF0, 0xED,
+0x91, 0x21, 0x71, 0x4D, 0x90, 0x83, 0x0B, 0x71,
+0x54, 0x90, 0x8D, 0x00, 0x71, 0x4A, 0x90, 0x83,
+0x0D, 0x71, 0x54, 0x90, 0x8D, 0x02, 0x71, 0x4A,
+0x90, 0x83, 0x0F, 0x71, 0x54, 0x90, 0x8D, 0x04,
+0x12, 0x47, 0xDA, 0xE0, 0x90, 0x83, 0x11, 0xF0,
+0x75, 0xF0, 0x0A, 0xED, 0x90, 0x8D, 0x06, 0x12,
+0x47, 0xDA, 0xE0, 0x90, 0x83, 0x12, 0xF0, 0x75,
+0xF0, 0x0A, 0xEF, 0x90, 0x8D, 0x08, 0x12, 0x47,
+0xDA, 0xE0, 0x90, 0x83, 0x13, 0x91, 0x08, 0x90,
+0x83, 0x6C, 0xEF, 0xF0, 0x7F, 0x02, 0x12, 0x45,
+0x27, 0x90, 0x80, 0x3C, 0xE0, 0xFF, 0x90, 0x83,
+0x6C, 0xE0, 0xFE, 0xEF, 0x4E, 0x90, 0x80, 0x3C,
+0xF0, 0x22, 0x12, 0x47, 0xDA, 0xE0, 0xFA, 0xA3,
+0xE0, 0xFB, 0xEA, 0x22, 0xF0, 0xA3, 0xEB, 0xF0,
+0x75, 0xF0, 0x0A, 0xED, 0x22, 0x90, 0x83, 0x06,
+0x74, 0x12, 0xF0, 0x90, 0x83, 0x14, 0x74, 0x05,
+0xF0, 0x90, 0x83, 0x08, 0x12, 0x77, 0x7C, 0xEB,
+0xF0, 0x90, 0x83, 0x04, 0xE0, 0x90, 0x83, 0x0B,
+0xF0, 0x90, 0x83, 0x05, 0xE0, 0x90, 0x83, 0x0C,
+0x91, 0x08, 0x80, 0xAB, 0x91, 0x01, 0x7F, 0xF5,
+0x7E, 0x00, 0x12, 0x2B, 0x27, 0xBF, 0x01, 0x06,
+0x90, 0x82, 0xFB, 0xE0, 0xA3, 0xF0, 0x91, 0x01,
+0x7F, 0xF6, 0x7E, 0x00, 0x12, 0x2B, 0x27, 0xBF,
+0x01, 0x08, 0x90, 0x82, 0xFB, 0xE0, 0x90, 0x82,
+0xFD, 0xF0, 0x91, 0x01, 0x7F, 0xF4, 0x7E, 0x00,
+0x12, 0x2B, 0x27, 0xBF, 0x01, 0x08, 0x90, 0x82,
+0xFB, 0xE0, 0x90, 0x82, 0xFE, 0xF0, 0x91, 0x01,
+0x7F, 0xF3, 0x7E, 0x00, 0x12, 0x2B, 0x27, 0xBF,
+0x01, 0x08, 0x90, 0x82, 0xFB, 0xE0, 0x90, 0x82,
+0xFF, 0xF0, 0x91, 0x01, 0x7F, 0xF2, 0x7E, 0x00,
+0x12, 0x2B, 0x27, 0xBF, 0x01, 0x08, 0x90, 0x82,
+0xFB, 0xE0, 0x90, 0x83, 0x00, 0xF0, 0x90, 0x82,
+0xFC, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0,
+0xFB, 0xA3, 0xE0, 0x90, 0x83, 0x04, 0xF0, 0x90,
+0x83, 0x00, 0xE0, 0x90, 0x83, 0x05, 0xF0, 0x61,
+0x5D, 0x7B, 0x01, 0x7A, 0x82, 0x79, 0xFB, 0x22,
+0xF0, 0x7B, 0x01, 0x7A, 0x83, 0x79, 0x06, 0x51,
+0x6B, 0x7F, 0x04, 0x22, 0x75, 0xF0, 0x0F, 0xA4,
+0x24, 0xDF, 0xF9, 0x74, 0x80, 0x35, 0xF0, 0x22,
+0xEF, 0x25, 0xE0, 0x24, 0x80, 0xF5, 0x82, 0xE4,
+0x34, 0x90, 0xF5, 0x83, 0x22, 0x90, 0x82, 0x76,
+0xE5, 0xD1, 0xF0, 0xA3, 0xE5, 0xD2, 0xF0, 0xA3,
+0xE5, 0xD3, 0xF0, 0xA3, 0xE5, 0xD4, 0xF0, 0xA3,
+0xE5, 0xD5, 0xF0, 0xA3, 0xE5, 0xD6, 0xF0, 0xA3,
+0xE5, 0xD7, 0xF0, 0xA3, 0xE5, 0xD9, 0xF0, 0x75,
+0x13, 0x01, 0x75, 0x14, 0x82, 0x75, 0x15, 0x76,
+0x75, 0x16, 0x08, 0x7B, 0x01, 0x7A, 0x95, 0x79,
+0x43, 0x12, 0x2B, 0xED, 0x90, 0x95, 0x44, 0xE0,
+0xFF, 0xB1, 0x36, 0x30, 0xE0, 0x02, 0xA1, 0x2C,
+0xEF, 0x54, 0x3F, 0xFF, 0x90, 0x82, 0x7E, 0xF0,
+0x90, 0x95, 0x45, 0xE0, 0x54, 0x3F, 0xFE, 0x90,
+0x82, 0x7F, 0xB1, 0x2D, 0xFD, 0x91, 0x20, 0xE4,
+0x8D, 0xF0, 0x12, 0x46, 0x9F, 0xEE, 0xD3, 0x94,
+0x04, 0x40, 0x06, 0x90, 0x82, 0x7F, 0x74, 0x04,
+0xF0, 0x90, 0x95, 0x44, 0x12, 0x8A, 0x01, 0x30,
+0xE0, 0x6C, 0x90, 0x82, 0x7E, 0xE0, 0xB1, 0x3D,
+0xC0, 0x83, 0xC0, 0x82, 0x90, 0x82, 0x7F, 0xE0,
+0xD0, 0x82, 0xD0, 0x83, 0x75, 0xF0, 0x02, 0x12,
+0x47, 0xDA, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xB1,
+0x2E, 0x2F, 0xFF, 0xE4, 0x3E, 0xFE, 0x90, 0x82,
+0x7E, 0xE0, 0xFC, 0xB1, 0x3D, 0xC0, 0x83, 0xC0,
+0x82, 0x90, 0x82, 0x7F, 0xE0, 0xFB, 0xD0, 0x82,
+0xD0, 0x83, 0x75, 0xF0, 0x02, 0x12, 0x47, 0xDA,
+0xEE, 0xF0, 0xA3, 0xEF, 0xB1, 0x2D, 0xFA, 0xFF,
+0xEC, 0x25, 0xE0, 0x12, 0x8A, 0x22, 0xF5, 0x83,
+0xE4, 0x8F, 0xF0, 0x12, 0x46, 0x9F, 0x90, 0x95,
+0x46, 0xE0, 0xFD, 0xB1, 0x36, 0x30, 0xE0, 0x2C,
+0x90, 0x82, 0x7E, 0xE0, 0xFF, 0xED, 0x54, 0x7F,
+0xFD, 0x8A, 0x51, 0x02, 0x67, 0x84, 0xB1, 0x2E,
+0xFD, 0x90, 0x82, 0x7E, 0xE0, 0xFE, 0x12, 0x8A,
+0x2A, 0xE4, 0x8D, 0xF0, 0x12, 0x46, 0x9F, 0x90,
+0x95, 0x46, 0xB1, 0x35, 0x30, 0xE0, 0x05, 0xAF,
+0x06, 0x12, 0x65, 0xEB, 0x22, 0xF0, 0x90, 0x95,
+0x47, 0xE0, 0x54, 0x1F, 0x22, 0xE0, 0xC4, 0x13,
+0x13, 0x13, 0x54, 0x01, 0x22, 0x75, 0xF0, 0x0A,
+0x90, 0x8D, 0x00, 0x02, 0x47, 0xDA, 0x90, 0x81,
+0x88, 0xE0, 0xFF, 0xB1, 0x36, 0x30, 0xE0, 0x25,
+0xEF, 0x54, 0x7F, 0xF0, 0x90, 0x04, 0xE0, 0xE0,
+0x90, 0x81, 0x89, 0x30, 0xE1, 0x06, 0xE0, 0x44,
+0x02, 0xF0, 0x80, 0x08, 0xE0, 0x54, 0xFD, 0x12,
+0x80, 0xB0, 0x04, 0xF0, 0x90, 0x81, 0x8D, 0xE0,
+0x60, 0x03, 0x12, 0x6B, 0xFB, 0x22, 0x90, 0x82,
+0x74, 0xE0, 0x60, 0x0F, 0xE4, 0xF0, 0x90, 0x05,
+0x53, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x05, 0xFC,
+0xE0, 0x04, 0xF0, 0x90, 0x81, 0x83, 0xE0, 0x30,
+0xE0, 0x10, 0xA3, 0x74, 0x01, 0xF0, 0x90, 0x81,
+0x83, 0xE0, 0xFF, 0xC3, 0x13, 0x30, 0xE0, 0x02,
+0xB1, 0xAC, 0x12, 0x6A, 0xE9, 0xE4, 0xFF, 0x51,
+0x38, 0x02, 0x55, 0xD5, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x12, 0x6B, 0x88, 0xBF, 0x01,
+0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x02, 0xB1,
+0xC6, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x81, 0x86,
+0xE0, 0xF5, 0x5C, 0xE5, 0x5C, 0x6F, 0x70, 0x02,
+0xC1, 0xA2, 0xEF, 0x14, 0x60, 0x38, 0x14, 0x60,
+0x58, 0x14, 0x60, 0x78, 0x14, 0x70, 0x02, 0xC1,
+0x80, 0x24, 0x04, 0x60, 0x02, 0xC1, 0xA2, 0xE5,
+0x5C, 0xB4, 0x04, 0x04, 0xF1, 0xA3, 0xC1, 0xA2,
+0xE5, 0x5C, 0xB4, 0x02, 0x04, 0xF1, 0xB7, 0xC1,
+0xA2, 0xE5, 0x5C, 0xB4, 0x03, 0x04, 0xF1, 0xC5,
+0xC1, 0xA2, 0xE5, 0x5C, 0x64, 0x01, 0x60, 0x02,
+0xC1, 0xA2, 0xF1, 0xA5, 0xC1, 0xA2, 0xE5, 0x5C,
+0xB4, 0x04, 0x04, 0xF1, 0x7F, 0xC1, 0xA2, 0xE5,
+0x5C, 0xB4, 0x02, 0x04, 0xF1, 0xB2, 0x80, 0x7A,
+0xE5, 0x5C, 0xB4, 0x03, 0x04, 0xF1, 0xC0, 0x80,
+0x71, 0xE5, 0x5C, 0x70, 0x6D, 0xD1, 0xA7, 0x80,
+0x69, 0xE5, 0x5C, 0xB4, 0x04, 0x04, 0xF1, 0x87,
+0x80, 0x60, 0xE5, 0x5C, 0xB4, 0x01, 0x04, 0xD1,
+0xC9, 0x80, 0x57, 0xE5, 0x5C, 0xB4, 0x03, 0x04,
+0xD1, 0xD7, 0x80, 0x4E, 0xE5, 0x5C, 0x70, 0x4A,
+0xD1, 0xC7, 0x80, 0x46, 0xE5, 0x5C, 0xB4, 0x04,
+0x05, 0x12, 0x89, 0x35, 0x80, 0x3C, 0xE5, 0x5C,
+0xB4, 0x01, 0x04, 0xF1, 0x97, 0x80, 0x33, 0xE5,
+0x5C, 0xB4, 0x02, 0x04, 0xF1, 0xBB, 0x80, 0x2A,
+0xE5, 0x5C, 0x70, 0x26, 0xF1, 0x95, 0x80, 0x22,
+0xE5, 0x5C, 0xB4, 0x03, 0x04, 0xF1, 0x91, 0x80,
+0x19, 0xE5, 0x5C, 0xB4, 0x01, 0x04, 0xD1, 0xB0,
+0x80, 0x10, 0xE5, 0x5C, 0xB4, 0x02, 0x05, 0x12,
+0x89, 0x41, 0x80, 0x06, 0xE5, 0x5C, 0x70, 0x02,
+0xD1, 0xAE, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90,
+0x81, 0x86, 0x74, 0x01, 0xF0, 0x22, 0xD1, 0xA7,
+0x7B, 0x1F, 0x7D, 0x6F, 0x7F, 0xFF, 0x12, 0x54,
+0x72, 0x90, 0x05, 0x27, 0xE0, 0x54, 0xBF, 0xF0,
+0x90, 0x81, 0x86, 0x74, 0x04, 0xF0, 0x22, 0xD1,
+0xA7, 0x7B, 0x20, 0x12, 0x57, 0xF5, 0xD1, 0xD9,
+0x90, 0x81, 0x86, 0x74, 0x02, 0xF0, 0x22, 0x80,
+0xF5, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0xE4, 0x90, 0x83, 0x46, 0xF0, 0xA3, 0xF0, 0x12,
+0x57, 0x8C, 0x90, 0x85, 0xBB, 0x12, 0x20, 0xDA,
+0xCC, 0xF0, 0x00, 0xC0, 0x12, 0x89, 0xC7, 0x12,
+0x20, 0xDA, 0x00, 0x00, 0x00, 0x14, 0x12, 0x8A,
+0x59, 0x12, 0x20, 0xDA, 0x00, 0x00, 0x00, 0x00,
+0xE4, 0xFD, 0xFF, 0x12, 0x77, 0x52, 0x7F, 0xE8,
+0x7E, 0x08, 0x12, 0x2D, 0x5C, 0xEF, 0x54, 0x0E,
+0xFF, 0xE4, 0xFE, 0xED, 0x54, 0xF4, 0xFD, 0xEC,
+0x54, 0x03, 0xFC, 0xE4, 0xFB, 0xFA, 0xF9, 0xF8,
+0xC3, 0x12, 0x47, 0x8C, 0x60, 0x1A, 0xD3, 0x12,
+0x8A, 0x15, 0x40, 0x09, 0x90, 0x01, 0xC3, 0xE0,
+0x44, 0x02, 0xF0, 0x80, 0x0B, 0x12, 0x8A, 0xC6,
+0x90, 0x83, 0x46, 0x12, 0x77, 0x75, 0x80, 0xC6,
+0xC3, 0x12, 0x8A, 0x15, 0x50, 0x1A, 0x12, 0x8A,
+0xCD, 0xEC, 0x44, 0x80, 0xFC, 0x90, 0x83, 0x48,
+0x12, 0x20, 0xCE, 0x90, 0x83, 0x48, 0x12, 0x75,
+0x61, 0x7F, 0x7C, 0x7E, 0x08, 0x12, 0x2E, 0xA2,
+0x90, 0x01, 0x00, 0x74, 0x3F, 0xF0, 0xA3, 0xE0,
+0x54, 0xFD, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44,
+0x20, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12,
+0x54, 0x6D, 0xF1, 0xC9, 0xF0, 0xC1, 0xA7, 0xF1,
+0xC9, 0xF0, 0x7B, 0x23, 0x12, 0x57, 0xF5, 0xC1,
+0xCE, 0x7B, 0x25, 0xC1, 0xB2, 0xD1, 0xA7, 0x7B,
+0x21, 0x12, 0x57, 0xF5, 0x90, 0x81, 0x86, 0x74,
+0x03, 0xF0, 0x22, 0xF1, 0x7F, 0x90, 0x05, 0x27,
+0xE0, 0x54, 0xBF, 0xF0, 0xE4, 0x90, 0x81, 0x86,
+0xF0, 0x22, 0x12, 0x54, 0x6B, 0xC1, 0xA7, 0xF1,
+0xB2, 0x80, 0xEA, 0x12, 0x55, 0x60, 0x80, 0xDC,
+0x12, 0x54, 0x6D, 0xC1, 0xA7, 0xF1, 0xC0, 0x80,
+0xDC, 0x90, 0x05, 0x27, 0xE0, 0x44, 0x40, 0x22,
+0x90, 0x02, 0x09, 0xE0, 0xF5, 0x56, 0x12, 0x1F,
+0xA4, 0x25, 0x56, 0x90, 0x80, 0x86, 0xF0, 0x12,
+0x5D, 0x33, 0x25, 0x56, 0x90, 0x80, 0x87, 0x12,
+0x6A, 0x76, 0x25, 0x56, 0x90, 0x80, 0x88, 0x12,
+0x67, 0xE3, 0x25, 0x56, 0x90, 0x80, 0x89, 0x12,
+0x67, 0xEA, 0x25, 0x56, 0x90, 0x80, 0x8A, 0xF0,
+0x11, 0x15, 0x25, 0x56, 0x90, 0x80, 0x8B, 0xF0,
+0x90, 0x00, 0x06, 0x12, 0x1F, 0xBD, 0x25, 0x56,
+0x90, 0x80, 0x8C, 0xF0, 0x22, 0x90, 0x00, 0x05,
+0x02, 0x1F, 0xBD, 0x12, 0x1F, 0xA4, 0xFF, 0x90,
+0x81, 0x79, 0xF0, 0xBF, 0x01, 0x08, 0x12, 0x7B,
+0x84, 0xE4, 0x90, 0x81, 0x79, 0xF0, 0x22, 0x12,
+0x1F, 0xA4, 0x54, 0x01, 0xFF, 0x90, 0x82, 0x75,
+0xE0, 0x54, 0xFE, 0x4F, 0xF0, 0x22, 0x31, 0xEE,
+0x54, 0x7F, 0x90, 0x81, 0x8D, 0xF0, 0xEF, 0x12,
+0x7D, 0x36, 0xA3, 0xF0, 0x12, 0x5D, 0x33, 0xFD,
+0x54, 0xF0, 0xC4, 0x54, 0x0F, 0xFF, 0x90, 0x81,
+0x8B, 0xE0, 0x54, 0xF0, 0x4F, 0x12, 0x67, 0xE3,
+0xFC, 0x54, 0x01, 0x25, 0xE0, 0xFF, 0x90, 0x81,
+0x88, 0xE0, 0x54, 0xFD, 0x4F, 0xF0, 0xEC, 0x54,
+0x04, 0xC3, 0x13, 0xFF, 0x90, 0x81, 0x8A, 0xE0,
+0x54, 0xFD, 0x4F, 0xF0, 0xED, 0x54, 0x0F, 0xC4,
+0x54, 0xF0, 0xFF, 0xA3, 0xE0, 0x54, 0x0F, 0x4F,
+0x12, 0x6A, 0x76, 0x90, 0x81, 0x8C, 0x12, 0x67,
+0xEA, 0xFD, 0x7F, 0x02, 0x12, 0x51, 0xC9, 0x90,
+0x82, 0xFB, 0x12, 0x47, 0xE6, 0x12, 0x6E, 0x95,
+0x11, 0xB1, 0xF0, 0x90, 0x81, 0x8D, 0x31, 0xF9,
+0x12, 0x6F, 0x13, 0x90, 0x01, 0xBE, 0xF0, 0x22,
+0xF0, 0x90, 0x01, 0xB9, 0x74, 0x01, 0xF0, 0x90,
+0x01, 0xB8, 0x22, 0x90, 0x81, 0x88, 0x11, 0xE6,
+0x30, 0xE0, 0x1F, 0xEF, 0x54, 0xBF, 0xF0, 0x90,
+0x04, 0xE0, 0xE0, 0x90, 0x81, 0x89, 0x30, 0xE0,
+0x06, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x08, 0xE0,
+0x54, 0xFE, 0x11, 0xB0, 0x74, 0x04, 0xF0, 0x12,
+0x6B, 0xFB, 0x22, 0x90, 0x81, 0x83, 0xE0, 0xFF,
+0xC4, 0x13, 0x13, 0x54, 0x03, 0x22, 0x11, 0xE3,
+0x30, 0xE0, 0x0B, 0x31, 0x05, 0x60, 0x07, 0x7D,
+0x01, 0x7F, 0x02, 0x12, 0x52, 0x54, 0x31, 0x05,
+0x60, 0x02, 0x31, 0x0C, 0x22, 0x90, 0x81, 0x87,
+0xE0, 0x64, 0x02, 0x22, 0x90, 0x81, 0x8D, 0xE0,
+0x64, 0x02, 0x60, 0x0C, 0x12, 0x6F, 0x14, 0x60,
+0x07, 0x31, 0x6D, 0xEF, 0x70, 0x02, 0x31, 0x5F,
+0x22, 0x90, 0x81, 0x8D, 0xE0, 0x70, 0x07, 0x90,
+0x81, 0x83, 0xE0, 0x30, 0xE0, 0x11, 0x90, 0x81,
+0x83, 0xE0, 0x30, 0xE0, 0x08, 0x12, 0x6B, 0x88,
+0xBF, 0x01, 0x04, 0x80, 0xCF, 0x31, 0x40, 0x22,
+0x90, 0x81, 0x8D, 0xE0, 0x64, 0x01, 0x70, 0x15,
+0x12, 0x6F, 0x14, 0x60, 0x07, 0x31, 0x5E, 0x12,
+0x54, 0x6D, 0x41, 0x46, 0x90, 0x81, 0x90, 0xE0,
+0x70, 0x03, 0x12, 0x52, 0x50, 0x22, 0xE4, 0xFD,
+0x7F, 0x0C, 0x02, 0x52, 0x54, 0x31, 0x6D, 0xEF,
+0x70, 0x02, 0x31, 0x40, 0x22, 0x90, 0x04, 0x1A,
+0xE0, 0xF4, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90,
+0x04, 0x1B, 0xE0, 0x54, 0x07, 0x64, 0x07, 0x7F,
+0x01, 0x60, 0x02, 0x7F, 0x00, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x31, 0x6D, 0xEF,
+0x64, 0x01, 0x60, 0x05, 0x75, 0x0D, 0x01, 0x80,
+0x42, 0x90, 0x81, 0x91, 0xE0, 0xFF, 0x54, 0x03,
+0x60, 0x05, 0x75, 0x0D, 0x02, 0x80, 0x34, 0xEF,
+0x30, 0xE2, 0x05, 0x75, 0x0D, 0x08, 0x80, 0x2B,
+0x90, 0x81, 0x91, 0xE0, 0x30, 0xE4, 0x05, 0x75,
+0x0D, 0x10, 0x80, 0x1F, 0x12, 0x6D, 0x80, 0x20,
+0xE0, 0x05, 0x75, 0x0D, 0x20, 0x80, 0x14, 0x51,
+0x06, 0x8F, 0x0E, 0xE5, 0x0E, 0x64, 0x01, 0x60,
+0x05, 0x85, 0x0E, 0x0D, 0x80, 0x05, 0x12, 0x77,
+0x83, 0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74, 0x04,
+0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x0D, 0xF0, 0x7F,
+0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x82,
+0xFB, 0x12, 0x47, 0xEF, 0x12, 0x1F, 0xA4, 0xFF,
+0x22, 0xE0, 0x90, 0x01, 0xBA, 0xF0, 0x90, 0x81,
+0x8F, 0xE0, 0x90, 0x01, 0xBB, 0x22, 0x90, 0x81,
+0x8F, 0xE0, 0xD3, 0x94, 0x00, 0x40, 0x06, 0x75,
+0x5A, 0x04, 0x7F, 0xFF, 0x22, 0x90, 0x82, 0x65,
+0xE0, 0x60, 0x06, 0x75, 0x5A, 0x80, 0x7F, 0xFF,
+0x22, 0x7F, 0x01, 0x22, 0x90, 0x81, 0x83, 0xE0,
+0xFF, 0x30, 0xE0, 0x04, 0x31, 0x05, 0x60, 0x15,
+0x90, 0x81, 0x8D, 0xE0, 0x70, 0x04, 0xEF, 0x30,
+0xE0, 0x0B, 0x90, 0x81, 0x90, 0xE0, 0x64, 0x02,
+0x60, 0x03, 0x12, 0x6C, 0x6E, 0x22, 0x12, 0x5A,
+0xDE, 0x30, 0xE0, 0x05, 0x90, 0x01, 0x5B, 0xE4,
+0xF0, 0x90, 0x06, 0x92, 0x74, 0x02, 0xF0, 0x90,
+0x01, 0x3C, 0x74, 0x04, 0xF0, 0xE4, 0xF5, 0x1D,
+0x90, 0x82, 0x61, 0xE0, 0xC3, 0x13, 0x54, 0x7F,
+0xF5, 0x1E, 0xE4, 0xFB, 0xFD, 0x7F, 0x58, 0x7E,
+0x01, 0x12, 0x51, 0x11, 0x90, 0x81, 0x88, 0xE0,
+0x44, 0x08, 0xF0, 0x22, 0x90, 0x81, 0x8D, 0xE0,
+0x60, 0x0E, 0x90, 0x06, 0x92, 0xE0, 0x30, 0xE1,
+0x02, 0x80, 0xBB, 0x51, 0x91, 0x12, 0x6B, 0xFB,
+0x22, 0x90, 0x81, 0x88, 0xE0, 0x54, 0xF7, 0xF0,
+0x22, 0x90, 0x81, 0x83, 0xE0, 0xFF, 0x30, 0xE0,
+0x3E, 0x90, 0x81, 0x87, 0xE0, 0x7E, 0x00, 0xB4,
+0x02, 0x02, 0x7E, 0x01, 0x90, 0x81, 0x86, 0xE0,
+0x7D, 0x00, 0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED,
+0x4E, 0x70, 0x24, 0xEF, 0xC3, 0x13, 0x30, 0xE0,
+0x03, 0x02, 0x7D, 0xAC, 0x11, 0xEE, 0x90, 0x81,
+0x87, 0xE0, 0xB4, 0x08, 0x06, 0xE4, 0xFD, 0x7F,
+0x0C, 0x80, 0x09, 0x90, 0x81, 0x87, 0xE0, 0x70,
+0x06, 0xFD, 0x7F, 0x04, 0x12, 0x52, 0x54, 0x22,
+0x12, 0x1F, 0xA4, 0x90, 0x82, 0x65, 0xF0, 0x22,
+0x12, 0x1F, 0xA4, 0x90, 0x82, 0x73, 0xF0, 0x12,
+0x5D, 0x33, 0x90, 0x82, 0x74, 0xF0, 0x22, 0xE4,
+0x90, 0x81, 0x75, 0xF0, 0xA3, 0xF0, 0x90, 0x80,
+0xDD, 0xF0, 0xA3, 0xF0, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x82, 0xF7, 0x12,
+0x47, 0xEF, 0x90, 0x83, 0x69, 0xE0, 0xFF, 0x04,
+0xF0, 0x12, 0x63, 0x5D, 0x7F, 0xAF, 0x7E, 0x01,
+0x12, 0x77, 0x93, 0xEF, 0x60, 0x3A, 0x90, 0x82,
+0xF7, 0x12, 0x47, 0xE6, 0x8B, 0x13, 0x8A, 0x14,
+0x89, 0x15, 0x90, 0x00, 0x0E, 0x12, 0x1F, 0xBD,
+0x24, 0x02, 0xF5, 0x16, 0x7B, 0x01, 0x7A, 0x01,
+0x79, 0xA0, 0x12, 0x2B, 0xED, 0x90, 0x82, 0xF7,
+0x12, 0x47, 0xE6, 0x90, 0x00, 0x0E, 0x12, 0x1F,
+0xBD, 0x90, 0x01, 0xAE, 0xF0, 0xA3, 0x74, 0xFF,
+0xF0, 0x90, 0x01, 0xCB, 0xE0, 0x64, 0x80, 0xF0,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x75, 0x3D, 0x10,
+0xE4, 0xF5, 0x3E, 0x75, 0x3F, 0x07, 0x75, 0x40,
+0x22, 0x90, 0x01, 0x30, 0xE5, 0x3D, 0xF0, 0xA3,
+0xE5, 0x3E, 0xF0, 0xA3, 0xE5, 0x3F, 0xF0, 0xA3,
+0xE5, 0x40, 0xF0, 0x22, 0x75, 0x45, 0x07, 0x75,
+0x46, 0x01, 0x43, 0x46, 0x10, 0x75, 0x47, 0x03,
+0x75, 0x48, 0x62, 0x90, 0x01, 0x38, 0xE5, 0x45,
+0xF0, 0xA3, 0xE5, 0x46, 0xF0, 0xA3, 0xE5, 0x47,
+0xF0, 0xA3, 0xE5, 0x48, 0xF0, 0x22, 0x90, 0x01,
+0x94, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x01, 0xC7,
+0xE4, 0xF0, 0x22, 0x90, 0x01, 0x01, 0xE0, 0x44,
+0x04, 0xF0, 0x90, 0x01, 0x9C, 0x74, 0x7E, 0xF0,
+0xA3, 0x74, 0x92, 0xF0, 0xA3, 0x74, 0xA0, 0xF0,
+0xA3, 0x74, 0x24, 0xF0, 0x90, 0x01, 0x9B, 0x74,
+0x49, 0xF0, 0x90, 0x01, 0x9A, 0x74, 0xE0, 0xF0,
+0x90, 0x01, 0x99, 0xE4, 0xF0, 0x90, 0x01, 0x98,
+0x04, 0xF0, 0x22, 0xE4, 0x90, 0x82, 0x88, 0xF0,
+0xA3, 0xF0, 0x90, 0x01, 0x98, 0xE0, 0x7F, 0x00,
+0x30, 0xE4, 0x02, 0x7F, 0x01, 0xEF, 0x64, 0x01,
+0x60, 0x41, 0xC3, 0x90, 0x82, 0x89, 0xE0, 0x94,
+0x88, 0x90, 0x82, 0x88, 0xE0, 0x94, 0x13, 0x40,
+0x0F, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x10, 0xF0,
+0x90, 0x01, 0xC7, 0x74, 0xFD, 0xF0, 0x80, 0x23,
+0x90, 0x82, 0x88, 0x12, 0x77, 0x75, 0x7F, 0x14,
+0x7E, 0x00, 0x12, 0x32, 0xAA, 0xD3, 0x90, 0x82,
+0x89, 0xE0, 0x94, 0x32, 0x90, 0x82, 0x88, 0xE0,
+0x94, 0x00, 0x40, 0xB6, 0x90, 0x01, 0xC6, 0xE0,
+0x30, 0xE3, 0xAF, 0x90, 0x01, 0xC7, 0x74, 0xFE,
+0xF0, 0x22, 0x7F, 0x02, 0x90, 0x82, 0x72, 0xE0,
+0xFE, 0xEF, 0xC3, 0x9E, 0x50, 0x18, 0xEF, 0x25,
+0xE0, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE4, 0x0B,
+0x90, 0x01, 0xB8, 0x74, 0x08, 0xF0, 0xA3, 0xF0,
+0x7F, 0x00, 0x22, 0x0F, 0x80, 0xDE, 0x7F, 0x01,
+0x22, 0x90, 0x01, 0xE4, 0x74, 0x1C, 0xF0, 0xA3,
+0xE4, 0xF0, 0x22, 0x90, 0x01, 0x34, 0xE0, 0x55,
+0x3D, 0xF5, 0x41, 0xA3, 0xE0, 0x55, 0x3E, 0xF5,
+0x42, 0xA3, 0xE0, 0x55, 0x3F, 0xF5, 0x43, 0xA3,
+0xE0, 0x55, 0x40, 0xF5, 0x44, 0x90, 0x01, 0x34,
+0xE5, 0x41, 0xF0, 0xA3, 0xE5, 0x42, 0xF0, 0xA3,
+0xE5, 0x43, 0xF0, 0xA3, 0xE5, 0x44, 0xF0, 0x22,
+0x90, 0x01, 0x3C, 0xE0, 0x55, 0x45, 0xF5, 0x49,
+0xA3, 0xE0, 0x55, 0x46, 0xF5, 0x4A, 0xA3, 0xE0,
+0x55, 0x47, 0xF5, 0x4B, 0xA3, 0xE0, 0x55, 0x48,
+0xF5, 0x4C, 0x90, 0x01, 0x3C, 0xE5, 0x49, 0xF0,
+0xA3, 0xE5, 0x4A, 0xF0, 0xA3, 0xE5, 0x4B, 0xF0,
+0xA3, 0xE5, 0x4C, 0xF0, 0x53, 0x91, 0xDF, 0x22,
+0x90, 0x01, 0xCF, 0xE0, 0x90, 0x83, 0x6F, 0xF0,
+0xE0, 0xFF, 0x30, 0xE0, 0x07, 0x90, 0x01, 0xCF,
+0xE0, 0x54, 0xFE, 0xF0, 0xEF, 0x30, 0xE5, 0x23,
+0x90, 0x01, 0xCF, 0xE0, 0x54, 0xDF, 0xF0, 0x90,
+0x01, 0x34, 0x74, 0x20, 0xF0, 0xE4, 0xF5, 0xA8,
+0xF5, 0xE8, 0x12, 0x68, 0x65, 0x90, 0x00, 0x03,
+0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x03, 0x12, 0x32,
+0x1E, 0x80, 0xFE, 0x22, 0x90, 0x81, 0x83, 0xE0,
+0x30, 0xE0, 0x05, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0,
+0x22, 0xB1, 0xC3, 0x90, 0x82, 0x84, 0xEF, 0xF0,
+0x30, 0xE0, 0x05, 0x7D, 0x01, 0xE4, 0x80, 0x02,
+0xE4, 0xFD, 0xFF, 0x12, 0x51, 0xC9, 0x90, 0x82,
+0x84, 0xE0, 0x30, 0xE6, 0x11, 0x90, 0x01, 0x2F,
+0xE0, 0x30, 0xE7, 0x04, 0xE4, 0xF0, 0x80, 0x06,
+0x90, 0x01, 0x2F, 0x74, 0x80, 0xF0, 0x90, 0x81,
+0x88, 0xE0, 0x90, 0x04, 0xEC, 0x30, 0xE0, 0x06,
+0xE0, 0x54, 0xDD, 0xF0, 0x80, 0x04, 0xE0, 0x44,
+0x22, 0xF0, 0xB1, 0x63, 0x74, 0x02, 0xF0, 0x02,
+0x5B, 0x02, 0xF0, 0x90, 0x81, 0x9F, 0xE0, 0xFF,
+0xA3, 0xE0, 0xFD, 0x90, 0x81, 0xA6, 0xE0, 0xFB,
+0x90, 0x83, 0x60, 0x22, 0xB1, 0xB7, 0x40, 0x29,
+0x90, 0x81, 0xA7, 0xE0, 0x04, 0xF0, 0x90, 0x82,
+0x5E, 0xE0, 0xFF, 0x90, 0x81, 0xA7, 0xE0, 0xD3,
+0x9F, 0x50, 0x16, 0x90, 0x81, 0x9F, 0xE0, 0x04,
+0xF0, 0x12, 0x51, 0xB0, 0x90, 0x81, 0xA6, 0xB1,
+0xA2, 0xB1, 0x62, 0x74, 0x04, 0xF0, 0x12, 0x5B,
+0x02, 0x22, 0xF0, 0xE4, 0x90, 0x82, 0x4B, 0xF0,
+0xA3, 0x22, 0x90, 0x81, 0x96, 0xE0, 0x04, 0xF0,
+0x90, 0x81, 0x91, 0xE0, 0x54, 0xEF, 0xF0, 0x90,
+0x82, 0x5F, 0xE0, 0xFF, 0x90, 0x81, 0x96, 0xE0,
+0xD3, 0x9F, 0x22, 0xE4, 0x90, 0x82, 0x86, 0xF0,
+0xA3, 0xF0, 0x90, 0x00, 0x83, 0xE0, 0x90, 0x82,
+0x85, 0xF0, 0x90, 0x00, 0x83, 0xE0, 0xFE, 0x90,
+0x82, 0x85, 0xE0, 0xFF, 0xB5, 0x06, 0x01, 0x22,
+0xC3, 0x90, 0x82, 0x87, 0xE0, 0x94, 0x64, 0x90,
+0x82, 0x86, 0xE0, 0x94, 0x00, 0x40, 0x0D, 0x90,
+0x01, 0xC0, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0x82,
+0x85, 0xE0, 0xFF, 0x22, 0x90, 0x82, 0x86, 0x12,
+0x77, 0x75, 0x80, 0xC6, 0x90, 0x82, 0x73, 0xE0,
+0x60, 0x0F, 0xE4, 0xF0, 0x90, 0x05, 0x53, 0xE0,
+0x44, 0x01, 0xF0, 0x90, 0x05, 0xFD, 0xE0, 0x04,
+0xF0, 0x22, 0x90, 0x81, 0x83, 0xE0, 0xFF, 0x30,
+0xE0, 0x40, 0x90, 0x81, 0x87, 0xE0, 0x7E, 0x00,
+0xB4, 0x02, 0x02, 0x7E, 0x01, 0x90, 0x81, 0x86,
+0xE0, 0x7D, 0x00, 0xB4, 0x04, 0x02, 0x7D, 0x01,
+0xED, 0x4E, 0x70, 0x26, 0xEF, 0xC3, 0x13, 0x30,
+0xE0, 0x03, 0x02, 0x7D, 0xAC, 0x12, 0x6C, 0x41,
+0x90, 0x81, 0x87, 0xE0, 0xB4, 0x0C, 0x06, 0xE4,
+0xFD, 0x7F, 0x08, 0x80, 0x0A, 0x90, 0x81, 0x87,
+0xE0, 0xB4, 0x04, 0x06, 0xE4, 0xFD, 0xFF, 0x12,
+0x52, 0x54, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x83, 0x56, 0xED, 0xF0, 0xA3,
+0xEB, 0xF0, 0x90, 0x83, 0x55, 0xEF, 0xF0, 0xE4,
+0xFD, 0xFC, 0xF1, 0xB8, 0x7C, 0x00, 0xAD, 0x07,
+0x90, 0x83, 0x55, 0xE0, 0x90, 0x04, 0x25, 0xF0,
+0x90, 0x83, 0x56, 0xE0, 0x60, 0x0E, 0x74, 0x0F,
+0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0xE0, 0x44, 0x80, 0xF0, 0xAF, 0x05, 0x74, 0x08,
+0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0xE4, 0xF0, 0x74, 0x09, 0x2F, 0xF5, 0x82, 0xE4,
+0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xF0, 0xF0,
+0xAF, 0x05, 0x74, 0x16, 0x2F, 0xD1, 0xFF, 0xE0,
+0x20, 0xE1, 0x18, 0x54, 0x01, 0xFE, 0x90, 0x83,
+0x57, 0xE0, 0x25, 0xE0, 0x25, 0xE0, 0xFB, 0xEE,
+0x44, 0x02, 0x4B, 0xFE, 0x74, 0x16, 0x2F, 0xD1,
+0xFF, 0xEE, 0xF0, 0x90, 0x83, 0x58, 0xE0, 0xFF,
+0xAE, 0x05, 0x74, 0x1E, 0x2E, 0xF5, 0x82, 0xE4,
+0x34, 0xFC, 0xF5, 0x83, 0xEF, 0xF0, 0x74, 0x21,
+0x2E, 0xF1, 0xAF, 0x54, 0xF7, 0xF0, 0xAE, 0x04,
+0xAF, 0x05, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF5,
+0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x90,
+0x80, 0x88, 0xE0, 0xFF, 0x90, 0x83, 0x4D, 0xE0,
+0xFB, 0x90, 0x83, 0x58, 0x74, 0x0A, 0xF0, 0x7D,
+0x01, 0xD1, 0x63, 0x90, 0x83, 0x4E, 0xEE, 0xF0,
+0xFC, 0xA3, 0xEF, 0xF0, 0xFD, 0x90, 0x83, 0x4C,
+0xE0, 0xFF, 0x12, 0x57, 0x17, 0x90, 0x83, 0x4E,
+0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x04, 0x80,
+0xE0, 0x54, 0x0F, 0xFD, 0xAC, 0x07, 0xF1, 0xA0,
+0x44, 0x01, 0xF0, 0xF1, 0xA0, 0x54, 0xFB, 0xF0,
+0xAC, 0x07, 0x74, 0x16, 0x2C, 0xD1, 0xFF, 0xE0,
+0x44, 0xFA, 0xF0, 0x74, 0x15, 0x2C, 0xF5, 0x82,
+0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x1F,
+0xF0, 0xAC, 0x07, 0x74, 0x06, 0x2C, 0xF5, 0x82,
+0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x0F,
+0xF0, 0x90, 0x04, 0x53, 0xE4, 0xF0, 0x90, 0x04,
+0x52, 0xF0, 0x90, 0x04, 0x51, 0x74, 0xFF, 0xF0,
+0x90, 0x04, 0x50, 0x74, 0xFD, 0xF0, 0x74, 0x14,
+0x2C, 0xF1, 0x98, 0xE0, 0x54, 0xC0, 0x4D, 0xFD,
+0x74, 0x14, 0x2F, 0xF1, 0x98, 0xED, 0xF0, 0x22,
+0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22,
+0x74, 0x11, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC,
+0xF5, 0x83, 0xE0, 0x22, 0x74, 0x21, 0x2D, 0xF5,
+0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22,
+0xE4, 0xFE, 0xEF, 0xC3, 0x13, 0xFD, 0xEF, 0x30,
+0xE0, 0x02, 0x7E, 0x80, 0x90, 0xFD, 0x10, 0xED,
+0xF0, 0xAF, 0x06, 0x22, 0x90, 0x01, 0xC4, 0x74,
+0xCC, 0xF0, 0x74, 0x87, 0xA3, 0xF0, 0x90, 0x00,
+0x90, 0xE0, 0x20, 0xE0, 0xF9, 0x74, 0xCC, 0x04,
+0x90, 0x01, 0xC4, 0xF0, 0x74, 0x87, 0xA3, 0xF0,
+0x22, 0xEF, 0x24, 0xFE, 0x60, 0x0B, 0x04, 0x70,
+0x24, 0x90, 0x81, 0x93, 0x74, 0x02, 0xF0, 0x80,
+0x13, 0xED, 0x70, 0x06, 0x90, 0x82, 0x62, 0xE0,
+0x80, 0x02, 0xED, 0x14, 0x90, 0x81, 0x93, 0xF0,
+0x90, 0x81, 0x93, 0xE0, 0xA3, 0xF0, 0x90, 0x81,
+0x89, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x7B, 0x2D,
+0x12, 0x57, 0xF5, 0x12, 0x57, 0x8C, 0x90, 0x01,
+0x37, 0x74, 0x02, 0xF0, 0xFD, 0x7F, 0x03, 0x12,
+0x6D, 0xAB, 0x12, 0x7E, 0xD9, 0xE4, 0xFD, 0x7F,
+0x01, 0x12, 0x51, 0xC9, 0xE4, 0x90, 0x81, 0x87,
+0xF0, 0x22, 0x12, 0x54, 0x6D, 0x11, 0x49, 0x44,
+0x40, 0xF0, 0x90, 0x81, 0x87, 0x74, 0x04, 0xF0,
+0x22, 0x7D, 0x04, 0x7F, 0x01, 0x12, 0x51, 0xC9,
+0x90, 0x05, 0x27, 0xE0, 0x22, 0x90, 0x82, 0x59,
+0x74, 0x18, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0xA3,
+0xE4, 0xF0, 0xA3, 0x74, 0x64, 0xF0, 0xA3, 0x74,
+0x01, 0xF0, 0xA3, 0x74, 0x05, 0xF0, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x83,
+0x72, 0xEF, 0xF0, 0x7E, 0x00, 0x7F, 0xA0, 0x7D,
+0x00, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0xAB, 0x12,
+0x48, 0x1E, 0xE4, 0x90, 0x81, 0xA4, 0xF0, 0x90,
+0x81, 0xA3, 0xF0, 0x90, 0x81, 0xA7, 0xF0, 0x90,
+0x83, 0x72, 0xE0, 0xB4, 0x01, 0x09, 0x90, 0x81,
+0xA8, 0x74, 0x14, 0xF0, 0xE4, 0xA3, 0xF0, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x90, 0x82, 0x66, 0xE0,
+0x54, 0xFE, 0xF0, 0x54, 0xFD, 0xF0, 0x54, 0xEF,
+0xF0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x82, 0x66,
+0xE0, 0x30, 0xE0, 0x0B, 0xE4, 0xF5, 0x1D, 0x90,
+0x82, 0x68, 0x12, 0x51, 0x07, 0x11, 0xE9, 0x90,
+0x80, 0x42, 0xE0, 0xB4, 0x01, 0x12, 0x11, 0xF1,
+0x13, 0x54, 0x1F, 0x20, 0xE0, 0x0A, 0xEF, 0xC4,
+0x13, 0x54, 0x07, 0x30, 0xE0, 0x02, 0x11, 0xF9,
+0x22, 0x90, 0x82, 0x66, 0xE0, 0x44, 0x10, 0xF0,
+0x22, 0x90, 0x82, 0x66, 0xE0, 0xFF, 0x13, 0x13,
+0x22, 0x90, 0x82, 0x66, 0xE0, 0x30, 0xE0, 0x34,
+0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0, 0x2D, 0x90,
+0x83, 0x73, 0xE0, 0x04, 0xF0, 0xE0, 0xD3, 0x94,
+0xC8, 0x40, 0x21, 0x90, 0x82, 0x66, 0xE0, 0x54,
+0xDF, 0xF0, 0xE4, 0x90, 0x83, 0x73, 0xF0, 0x90,
+0x82, 0x66, 0xE0, 0x13, 0x30, 0xE0, 0x0D, 0x90,
+0x81, 0x88, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x81,
+0x98, 0x74, 0xD0, 0xF0, 0x22, 0x7B, 0x22, 0x12,
+0x57, 0xF5, 0x12, 0x7F, 0xC9, 0xF0, 0x02, 0x7F,
+0x9C, 0x12, 0x55, 0x60, 0x7B, 0x24, 0x02, 0x7E,
+0xB2, 0x90, 0x81, 0x86, 0xE0, 0x64, 0x02, 0x7F,
+0x01, 0x60, 0x02, 0x7F, 0x00, 0x22, 0x90, 0x05,
+0x63, 0xE0, 0x90, 0x82, 0x55, 0xF0, 0x90, 0x05,
+0x62, 0xE0, 0x90, 0x82, 0x56, 0xF0, 0x90, 0x05,
+0x61, 0xE0, 0x90, 0x82, 0x57, 0xF0, 0x90, 0x05,
+0x60, 0xE0, 0x90, 0x82, 0x58, 0xF0, 0x90, 0x81,
+0x89, 0xE0, 0x44, 0x80, 0xF0, 0x22, 0x7B, 0xFE,
+0x7A, 0x80, 0x79, 0x33, 0x12, 0x2B, 0xED, 0x90,
+0x82, 0xA6, 0xE0, 0xFF, 0x90, 0x82, 0xA5, 0xE0,
+0xFD, 0xE4, 0x90, 0x82, 0xF5, 0x22, 0x90, 0x82,
+0x4C, 0xE0, 0x24, 0x01, 0xFF, 0x90, 0x82, 0x4B,
+0xE0, 0x34, 0x00, 0xFE, 0x12, 0x32, 0xAA, 0x90,
+0x81, 0x90, 0xE0, 0x22, 0xF0, 0x90, 0x81, 0x99,
+0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0, 0x22, 0xF0,
+0x90, 0x81, 0xAA, 0xE0, 0x24, 0x05, 0x90, 0x81,
+0xA5, 0xF0, 0xA3, 0x74, 0x10, 0xF0, 0x22, 0x7F,
+0x8C, 0x7E, 0x08, 0x12, 0x2E, 0xA2, 0x90, 0x85,
+0xBB, 0x22, 0x90, 0x01, 0x34, 0x74, 0x40, 0xF0,
+0xFD, 0xE4, 0xFF, 0x12, 0x6D, 0xAB, 0x43, 0x59,
+0x08, 0x22, 0x75, 0xF0, 0x08, 0xA4, 0xFF, 0xAE,
+0xF0, 0x24, 0x49, 0xF9, 0x74, 0x93, 0x3E, 0x22,
+0xE0, 0x54, 0xFE, 0x4E, 0xFE, 0xF0, 0xEF, 0x54,
+0x02, 0xFF, 0xEE, 0x54, 0xFD, 0x22, 0x90, 0x81,
+0x83, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x22,
+0x7E, 0x00, 0x7F, 0x04, 0x7D, 0x00, 0x7B, 0x01,
+0x7A, 0x82, 0x79, 0x6E, 0x22, 0x90, 0x83, 0x47,
+0xE0, 0x94, 0xE8, 0x90, 0x83, 0x46, 0xE0, 0x94,
+0x03, 0x22, 0x24, 0xCB, 0xF5, 0x82, 0xE4, 0x34,
+0x95, 0x22, 0x25, 0xE0, 0x24, 0x4B, 0xF5, 0x82,
+0xE4, 0x34, 0x95, 0xF5, 0x83, 0x22, 0x90, 0x06,
+0x04, 0xE0, 0x44, 0x40, 0xF0, 0xE0, 0x44, 0x80,
+0xF0, 0x22, 0xE0, 0xFF, 0x75, 0xF0, 0x08, 0x90,
+0x93, 0x46, 0x02, 0x47, 0xDA, 0x12, 0x47, 0xEF,
+0x74, 0x47, 0x2F, 0xF9, 0x74, 0x93, 0x3E, 0xFA,
+0x22, 0x7F, 0x70, 0x7E, 0x0E, 0x12, 0x2E, 0xA2,
+0x90, 0x83, 0x42, 0x22, 0x90, 0x82, 0x66, 0xE0,
+0xC3, 0x13, 0x22, 0x90, 0x04, 0x1F, 0x74, 0x20,
+0xF0, 0x22, 0x90, 0x82, 0x6F, 0xE0, 0x14, 0x90,
+0x82, 0x71, 0xF0, 0x22, 0xAB, 0x56, 0xAA, 0x57,
+0xA9, 0x58, 0x02, 0x1F, 0xA4, 0x12, 0x47, 0x7F,
+0x90, 0x82, 0xA7, 0x02, 0x20, 0xCE, 0x90, 0x06,
+0x04, 0xE0, 0x54, 0x7F, 0xF0, 0x22, 0x90, 0x81,
+0x88, 0xE0, 0x54, 0xBF, 0xF0, 0x22, 0x90, 0x81,
+0x8A, 0xE0, 0x54, 0xFE, 0xF0, 0x22, 0x90, 0x81,
+0x93, 0xE0, 0x90, 0x05, 0x73, 0x22, 0xF5, 0x82,
+0xE4, 0x34, 0x96, 0xF5, 0x83, 0x22, 0xF5, 0x82,
+0xE4, 0x34, 0x98, 0xF5, 0x83, 0x22, 0x2F, 0xF8,
+0xE6, 0xFE, 0xED, 0xF4, 0x5E, 0x22, 0x7F, 0x32,
+0x7E, 0x00, 0x02, 0x32, 0xAA, 0x7F, 0x7C, 0x7E,
+0x08, 0x02, 0x2D, 0x5C, 0x90, 0x81, 0x83, 0xE0,
+0xFF, 0x13, 0x13, 0x22, 0xF5, 0x82, 0xE4, 0x34,
+0x82, 0xF5, 0x83, 0x22, 0x66, 0x1A
+};
+
+u32 array_length_mp_8188e_s_fw_nic = 19206;
+
+#ifdef CONFIG_WOWLAN
+
+u8 array_mp_8188e_s_fw_wowlan[] = {
+0xE3, 0x88, 0x30, 0x00, 0x1C, 0x00, 0x00, 0x00,
+0x05, 0x04, 0x22, 0x24, 0x96, 0x58, 0x02, 0x00,
+0xA5, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x49, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x4A, 0x43, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x57, 0xF7, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x49, 0xBA, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x4F, 0xFA, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xE7, 0x09, 0xF6, 0x08, 0xDF, 0xFA, 0x80, 0x46,
+0xE7, 0x09, 0xF2, 0x08, 0xDF, 0xFA, 0x80, 0x3E,
+0x88, 0x82, 0x8C, 0x83, 0xE7, 0x09, 0xF0, 0xA3,
+0xDF, 0xFA, 0x80, 0x32, 0xE3, 0x09, 0xF6, 0x08,
+0xDF, 0xFA, 0x80, 0x78, 0xE3, 0x09, 0xF2, 0x08,
+0xDF, 0xFA, 0x80, 0x70, 0x88, 0x82, 0x8C, 0x83,
+0xE3, 0x09, 0xF0, 0xA3, 0xDF, 0xFA, 0x80, 0x64,
+0x89, 0x82, 0x8A, 0x83, 0xE0, 0xA3, 0xF6, 0x08,
+0xDF, 0xFA, 0x80, 0x58, 0x89, 0x82, 0x8A, 0x83,
+0xE0, 0xA3, 0xF2, 0x08, 0xDF, 0xFA, 0x80, 0x4C,
+0x80, 0xD2, 0x80, 0xFA, 0x80, 0xC6, 0x80, 0xD4,
+0x80, 0x69, 0x80, 0xF2, 0x80, 0x33, 0x80, 0x10,
+0x80, 0xA6, 0x80, 0xEA, 0x80, 0x9A, 0x80, 0xA8,
+0x80, 0xDA, 0x80, 0xE2, 0x80, 0xCA, 0x80, 0x33,
+0x89, 0x82, 0x8A, 0x83, 0xEC, 0xFA, 0xE4, 0x93,
+0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC, 0xC5, 0x83,
+0xCC, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC,
+0xC5, 0x83, 0xCC, 0xDF, 0xE9, 0xDE, 0xE7, 0x80,
+0x0D, 0x89, 0x82, 0x8A, 0x83, 0xE4, 0x93, 0xA3,
+0xF6, 0x08, 0xDF, 0xF9, 0xEC, 0xFA, 0xA9, 0xF0,
+0xED, 0xFB, 0x22, 0x89, 0x82, 0x8A, 0x83, 0xEC,
+0xFA, 0xE0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC,
+0xC5, 0x83, 0xCC, 0xF0, 0xA3, 0xC8, 0xC5, 0x82,
+0xC8, 0xCC, 0xC5, 0x83, 0xCC, 0xDF, 0xEA, 0xDE,
+0xE8, 0x80, 0xDB, 0x89, 0x82, 0x8A, 0x83, 0xE4,
+0x93, 0xA3, 0xF2, 0x08, 0xDF, 0xF9, 0x80, 0xCC,
+0x88, 0xF0, 0xEF, 0x60, 0x01, 0x0E, 0x4E, 0x60,
+0xC3, 0x88, 0xF0, 0xED, 0x24, 0x02, 0xB4, 0x04,
+0x00, 0x50, 0xB9, 0xF5, 0x82, 0xEB, 0x24, 0x02,
+0xB4, 0x04, 0x00, 0x50, 0xAF, 0x23, 0x23, 0x45,
+0x82, 0x23, 0x90, 0x43, 0x50, 0x73, 0xC5, 0xF0,
+0xF8, 0xA3, 0xE0, 0x28, 0xF0, 0xC5, 0xF0, 0xF8,
+0xE5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83,
+0xE0, 0x38, 0xF0, 0x22, 0xEF, 0x2B, 0xFF, 0xEE,
+0x3A, 0xFE, 0xED, 0x39, 0xFD, 0xEC, 0x38, 0xFC,
+0x22, 0xC3, 0xEF, 0x9B, 0xFF, 0xEE, 0x9A, 0xFE,
+0xED, 0x99, 0xFD, 0xEC, 0x98, 0xFC, 0x22, 0xEF,
+0x4B, 0xFF, 0xEE, 0x4A, 0xFE, 0xED, 0x49, 0xFD,
+0xEC, 0x48, 0xFC, 0x22, 0xEB, 0x9F, 0xF5, 0xF0,
+0xEA, 0x9E, 0x42, 0xF0, 0xE9, 0x9D, 0x42, 0xF0,
+0xE8, 0x9C, 0x45, 0xF0, 0x22, 0xE0, 0xFC, 0xA3,
+0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
+0x22, 0xE0, 0xF8, 0xA3, 0xE0, 0xF9, 0xA3, 0xE0,
+0xFA, 0xA3, 0xE0, 0xFB, 0x22, 0xA4, 0x25, 0x82,
+0xF5, 0x82, 0xE5, 0xF0, 0x35, 0x83, 0xF5, 0x83,
+0x22, 0xE0, 0xFB, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0,
+0xF9, 0x22, 0xEB, 0xF0, 0xA3, 0xEA, 0xF0, 0xA3,
+0xE9, 0xF0, 0x22, 0xD0, 0x83, 0xD0, 0x82, 0xF8,
+0xE4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70,
+0x0D, 0xA3, 0xA3, 0x93, 0xF8, 0x74, 0x01, 0x93,
+0xF5, 0x82, 0x88, 0x83, 0xE4, 0x73, 0x74, 0x02,
+0x93, 0x68, 0x60, 0xEF, 0xA3, 0xA3, 0xA3, 0x80,
+0xDF, 0xE3, 0xF5, 0xF0, 0x09, 0xE2, 0x08, 0xB5,
+0xF0, 0x6B, 0xDF, 0xF5, 0x80, 0x67, 0xE3, 0xF5,
+0xF0, 0x09, 0xE6, 0x08, 0xB5, 0xF0, 0x5E, 0xDF,
+0xF5, 0x80, 0x5A, 0x87, 0xF0, 0x09, 0xE6, 0x08,
+0xB5, 0xF0, 0x52, 0xDF, 0xF6, 0x80, 0x4E, 0x87,
+0xF0, 0x09, 0xE2, 0x08, 0xB5, 0xF0, 0x46, 0xDF,
+0xF6, 0x80, 0x42, 0x88, 0x82, 0x8C, 0x83, 0x87,
+0xF0, 0x09, 0xE0, 0xA3, 0xB5, 0xF0, 0x36, 0xDF,
+0xF6, 0x80, 0x32, 0x88, 0x82, 0x8C, 0x83, 0x87,
+0xF0, 0x09, 0xE4, 0x93, 0xA3, 0xB5, 0xF0, 0x25,
+0xDF, 0xF5, 0x80, 0x21, 0x88, 0x82, 0x8C, 0x83,
+0xE3, 0xF5, 0xF0, 0x09, 0xE0, 0xA3, 0xB5, 0xF0,
+0x14, 0xDF, 0xF5, 0x80, 0x10, 0x88, 0x82, 0x8C,
+0x83, 0xE3, 0xF5, 0xF0, 0x09, 0xE4, 0x93, 0xA3,
+0xB5, 0xF0, 0x02, 0xDF, 0xF4, 0x02, 0x45, 0xD0,
+0x80, 0x87, 0x80, 0xE9, 0x80, 0x90, 0x80, 0xD4,
+0x80, 0x3E, 0x80, 0x15, 0x80, 0x6E, 0x80, 0x7E,
+0x80, 0x9D, 0x80, 0xB7, 0x80, 0x8D, 0x80, 0xA3,
+0x80, 0x51, 0x80, 0x74, 0x80, 0x3C, 0x02, 0x45,
+0xDC, 0x89, 0x82, 0x8A, 0x83, 0xEC, 0xFA, 0xE4,
+0x93, 0xF5, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8,
+0xCC, 0xC5, 0x83, 0xCC, 0xE4, 0x93, 0xA3, 0xC8,
+0xC5, 0x82, 0xC8, 0xCC, 0xC5, 0x83, 0xCC, 0xB5,
+0xF0, 0x76, 0xDF, 0xE3, 0xDE, 0xE1, 0x80, 0x70,
+0x89, 0x82, 0x8A, 0x83, 0xE4, 0x93, 0xF5, 0xF0,
+0xA3, 0xE2, 0x08, 0xB5, 0xF0, 0x62, 0xDF, 0xF4,
+0x80, 0x5E, 0x89, 0x82, 0x8A, 0x83, 0xE0, 0xF5,
+0xF0, 0xA3, 0xE6, 0x08, 0xB5, 0xF0, 0x51, 0xDF,
+0xF5, 0x80, 0x4D, 0x89, 0x82, 0x8A, 0x83, 0xE0,
+0xF5, 0xF0, 0xA3, 0xE2, 0x08, 0xB5, 0xF0, 0x40,
+0xDF, 0xF5, 0x80, 0x3C, 0x89, 0x82, 0x8A, 0x83,
+0xE4, 0x93, 0xF5, 0xF0, 0xA3, 0xE6, 0x08, 0xB5,
+0xF0, 0x2E, 0xDF, 0xF4, 0x80, 0x2A, 0x80, 0x02,
+0x80, 0x57, 0x89, 0x82, 0x8A, 0x83, 0xEC, 0xFA,
+0xE4, 0x93, 0xF5, 0xF0, 0xA3, 0xC8, 0xC5, 0x82,
+0xC8, 0xCC, 0xC5, 0x83, 0xCC, 0xE0, 0xA3, 0xC8,
+0xC5, 0x82, 0xC8, 0xCC, 0xC5, 0x83, 0xCC, 0xB5,
+0xF0, 0x06, 0xDF, 0xE4, 0xDE, 0xE2, 0x80, 0x00,
+0x7F, 0xFF, 0xB5, 0xF0, 0x02, 0x0F, 0x22, 0x40,
+0x02, 0x7F, 0x01, 0x22, 0x89, 0x82, 0x8A, 0x83,
+0xEC, 0xFA, 0xE0, 0xF5, 0xF0, 0xA3, 0xC8, 0xC5,
+0x82, 0xC8, 0xCC, 0xC5, 0x83, 0xCC, 0xE0, 0xA3,
+0xC8, 0xC5, 0x82, 0xC8, 0xCC, 0xC5, 0x83, 0xCC,
+0xB5, 0xF0, 0xD5, 0xDF, 0xE5, 0xDE, 0xE3, 0x80,
+0xCF, 0x89, 0x82, 0x8A, 0x83, 0xEC, 0xFA, 0xE0,
+0xF5, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC,
+0xC5, 0x83, 0xCC, 0xE4, 0x93, 0xA3, 0xC8, 0xC5,
+0x82, 0xC8, 0xCC, 0xC5, 0x83, 0xCC, 0xB5, 0xF0,
+0xAF, 0xDF, 0xE4, 0xDE, 0xE2, 0x80, 0xA9, 0x88,
+0xF0, 0xEF, 0x60, 0x01, 0x0E, 0x4E, 0x60, 0xAB,
+0xED, 0x24, 0x02, 0xB4, 0x04, 0x00, 0x50, 0x98,
+0xF5, 0x82, 0xEB, 0x24, 0x02, 0xB4, 0x04, 0x00,
+0x50, 0x8E, 0x23, 0x23, 0x45, 0x82, 0x23, 0x90,
+0x45, 0x18, 0x73, 0xEF, 0x4E, 0x60, 0x12, 0xEF,
+0x60, 0x01, 0x0E, 0xED, 0xBB, 0x01, 0x0B, 0x89,
+0x82, 0x8A, 0x83, 0xF0, 0xA3, 0xDF, 0xFC, 0xDE,
+0xFA, 0x22, 0x89, 0xF0, 0x50, 0x07, 0xF7, 0x09,
+0xDF, 0xFC, 0xA9, 0xF0, 0x22, 0xBB, 0xFE, 0xFC,
+0xF3, 0x09, 0xDF, 0xFC, 0xA9, 0xF0, 0x22, 0xC2,
+0xAF, 0x80, 0xFE, 0x32, 0x12, 0x46, 0x7B, 0x85,
+0xD0, 0x0B, 0x75, 0xD0, 0x08, 0xAA, 0xE0, 0xC2,
+0x8C, 0xE5, 0x8A, 0x24, 0x67, 0xF5, 0x8A, 0xE5,
+0x8C, 0x34, 0x79, 0xF5, 0x8C, 0xD2, 0x8C, 0xEC,
+0x24, 0x87, 0xF8, 0xE6, 0xBC, 0x02, 0x02, 0x74,
+0xFF, 0xC3, 0x95, 0x81, 0xB4, 0x40, 0x00, 0x40,
+0xCE, 0x79, 0x03, 0x78, 0x80, 0x16, 0xE6, 0x08,
+0x70, 0x0B, 0xC2, 0xAF, 0xE6, 0x30, 0xE1, 0x03,
+0x44, 0x18, 0xF6, 0xD2, 0xAF, 0x08, 0xD9, 0xED,
+0xEA, 0x8B, 0xD0, 0x22, 0xE5, 0x0C, 0xFF, 0x23,
+0x24, 0x81, 0xF8, 0x0F, 0x08, 0x08, 0xBF, 0x03,
+0x04, 0x7F, 0x00, 0x78, 0x81, 0xE6, 0x30, 0xE4,
+0xF2, 0x00, 0xE5, 0x0C, 0xC3, 0x9F, 0x50, 0x20,
+0x05, 0x0C, 0x74, 0x86, 0x25, 0x0C, 0xF8, 0xE6,
+0xFD, 0xA6, 0x81, 0x08, 0xE6, 0xAE, 0x0C, 0xBE,
+0x02, 0x02, 0x74, 0xFF, 0xCD, 0xF8, 0xE8, 0x6D,
+0x60, 0xE0, 0x08, 0xE6, 0xC0, 0xE0, 0x80, 0xF6,
+0xE5, 0x0C, 0xD3, 0x9F, 0x40, 0x27, 0xE5, 0x0C,
+0x24, 0x87, 0xF8, 0xE6, 0xAE, 0x0C, 0xBE, 0x02,
+0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xCD, 0xF8,
+0xE5, 0x81, 0x6D, 0x60, 0x06, 0xD0, 0xE0, 0xF6,
+0x18, 0x80, 0xF5, 0xE5, 0x0C, 0x24, 0x86, 0xC8,
+0xF6, 0x15, 0x0C, 0x80, 0xD3, 0xE5, 0x0C, 0x23,
+0x24, 0x81, 0xF8, 0x7F, 0x04, 0xC2, 0xAF, 0xE6,
+0x30, 0xE0, 0x03, 0x10, 0xE2, 0x0C, 0x7F, 0x00,
+0x30, 0xE1, 0x07, 0x30, 0xE3, 0x04, 0x7F, 0x08,
+0x54, 0xF4, 0x54, 0x7C, 0xC6, 0xD2, 0xAF, 0x54,
+0x80, 0x42, 0x07, 0x22, 0x78, 0x86, 0xA6, 0x81,
+0x74, 0x02, 0x60, 0x06, 0xFF, 0x08, 0x76, 0xFF,
+0xDF, 0xFB, 0x7F, 0x03, 0xE4, 0x78, 0x80, 0xF6,
+0x08, 0xF6, 0x08, 0xDF, 0xFA, 0x78, 0x81, 0x76,
+0x30, 0x90, 0x49, 0xB4, 0x74, 0x01, 0x93, 0xC0,
+0xE0, 0xE4, 0x93, 0xC0, 0xE0, 0x43, 0x89, 0x01,
+0x75, 0x8A, 0x60, 0x75, 0x8C, 0x79, 0xD2, 0x8C,
+0xD2, 0xAF, 0x22, 0x02, 0xEF, 0xD3, 0x94, 0x02,
+0x40, 0x03, 0x7F, 0xFF, 0x22, 0x74, 0x81, 0x2F,
+0x2F, 0xF8, 0xE6, 0x20, 0xE5, 0xF4, 0xC2, 0xAF,
+0xE6, 0x44, 0x30, 0xF6, 0xD2, 0xAF, 0xAE, 0x0C,
+0xEE, 0xC3, 0x9F, 0x50, 0x21, 0x0E, 0x74, 0x86,
+0x2E, 0xF8, 0xE6, 0xF9, 0x08, 0xE6, 0x18, 0xBE,
+0x02, 0x02, 0x74, 0xFF, 0xFD, 0xED, 0x69, 0x60,
+0x09, 0x09, 0xE7, 0x19, 0x19, 0xF7, 0x09, 0x09,
+0x80, 0xF3, 0x16, 0x16, 0x80, 0xDA, 0xEE, 0xD3,
+0x9F, 0x40, 0x04, 0x05, 0x81, 0x05, 0x81, 0xEE,
+0xD3, 0x9F, 0x40, 0x22, 0x74, 0x86, 0x2E, 0xF8,
+0x08, 0xE6, 0xF9, 0xEE, 0xB5, 0x0C, 0x02, 0xA9,
+0x81, 0x18, 0x06, 0x06, 0xE6, 0xFD, 0xED, 0x69,
+0x60, 0x09, 0x19, 0x19, 0xE7, 0x09, 0x09, 0xF7,
+0x19, 0x80, 0xF3, 0x1E, 0x80, 0xD9, 0xEF, 0x24,
+0x86, 0xF8, 0xE6, 0x04, 0xF8, 0xEF, 0x2F, 0x04,
+0x90, 0x49, 0xB4, 0x93, 0xF6, 0x08, 0xEF, 0x2F,
+0x93, 0xF6, 0x7F, 0x00, 0x22, 0xEF, 0xD3, 0x94,
+0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0xEF, 0x23,
+0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE5, 0xF4, 0xC2,
+0xAF, 0xE6, 0x54, 0x8C, 0xF6, 0xD2, 0xAF, 0xE5,
+0x0C, 0xB5, 0x07, 0x0A, 0x74, 0x86, 0x2F, 0xF8,
+0xE6, 0xF5, 0x81, 0x02, 0x46, 0xC4, 0x50, 0x2E,
+0x74, 0x87, 0x2F, 0xF8, 0xE6, 0xBF, 0x02, 0x02,
+0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xF9, 0x74, 0x86,
+0x2F, 0xF8, 0xFB, 0xE6, 0xFC, 0xE9, 0x6C, 0x60,
+0x08, 0xA8, 0x05, 0xE7, 0xF6, 0x1D, 0x19, 0x80,
+0xF4, 0xA8, 0x03, 0xA6, 0x05, 0x1F, 0xE5, 0x0C,
+0xB5, 0x07, 0xE3, 0x7F, 0x00, 0x22, 0x74, 0x87,
+0x2F, 0xF8, 0xE6, 0xFD, 0x18, 0x86, 0x01, 0x0F,
+0x74, 0x86, 0x2F, 0xF8, 0xA6, 0x01, 0x08, 0x86,
+0x04, 0xE5, 0x0C, 0xB5, 0x07, 0x02, 0xAC, 0x81,
+0xED, 0x6C, 0x60, 0x08, 0x0D, 0x09, 0xA8, 0x05,
+0xE6, 0xF7, 0x80, 0xF4, 0xE5, 0x0C, 0xB5, 0x07,
+0xDE, 0x89, 0x81, 0x7F, 0x00, 0x22, 0xEF, 0xD3,
+0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0xEF,
+0x23, 0x24, 0x81, 0xF8, 0xC2, 0xAF, 0xE6, 0x30,
+0xE5, 0x05, 0x30, 0xE0, 0x02, 0xD2, 0xE4, 0xD2,
+0xE2, 0xC6, 0xD2, 0xAF, 0x7F, 0x00, 0x30, 0xE2,
+0x01, 0x0F, 0x02, 0x46, 0xC3, 0x8F, 0xF0, 0xE4,
+0xFF, 0xFE, 0xE5, 0x0C, 0x23, 0x24, 0x80, 0xF8,
+0xC2, 0xA9, 0x30, 0xF7, 0x0D, 0x7F, 0x08, 0xE6,
+0x60, 0x0B, 0x2D, 0xF6, 0x60, 0x30, 0x50, 0x2E,
+0x80, 0x07, 0x30, 0xF1, 0x06, 0xED, 0xF6, 0x60,
+0x25, 0x7E, 0x02, 0x08, 0x30, 0xF0, 0x10, 0xC2,
+0xAF, 0xE6, 0x10, 0xE7, 0x23, 0x0E, 0x30, 0xE2,
+0x0C, 0xD2, 0xAF, 0x7F, 0x04, 0x80, 0x12, 0xC2,
+0xAF, 0xE6, 0x10, 0xE7, 0x13, 0x54, 0xEC, 0x4E,
+0xF6, 0xD2, 0xAF, 0x02, 0x46, 0xC4, 0x7F, 0x08,
+0x08, 0xEF, 0x44, 0x83, 0xF4, 0xC2, 0xAF, 0x56,
+0xC6, 0xD2, 0xAF, 0x54, 0x80, 0x4F, 0xFF, 0x22,
+0x02, 0x49, 0x5E, 0x02, 0x47, 0x54, 0xE4, 0x93,
+0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0x40, 0x03, 0xF6,
+0x80, 0x01, 0xF2, 0x08, 0xDF, 0xF4, 0x80, 0x29,
+0xE4, 0x93, 0xA3, 0xF8, 0x54, 0x07, 0x24, 0x0C,
+0xC8, 0xC3, 0x33, 0xC4, 0x54, 0x0F, 0x44, 0x20,
+0xC8, 0x83, 0x40, 0x04, 0xF4, 0x56, 0x80, 0x01,
+0x46, 0xF6, 0xDF, 0xE4, 0x80, 0x0B, 0x01, 0x02,
+0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x49,
+0xA3, 0xE4, 0x7E, 0x01, 0x93, 0x60, 0xBC, 0xA3,
+0xFF, 0x54, 0x3F, 0x30, 0xE5, 0x09, 0x54, 0x1F,
+0xFE, 0xE4, 0x93, 0xA3, 0x60, 0x01, 0x0E, 0xCF,
+0x54, 0xC0, 0x25, 0xE0, 0x60, 0xA8, 0x40, 0xB8,
+0xE4, 0x93, 0xA3, 0xFA, 0xE4, 0x93, 0xA3, 0xF8,
+0xE4, 0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA,
+0xC5, 0x83, 0xCA, 0xF0, 0xA3, 0xC8, 0xC5, 0x82,
+0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xDF, 0xE9, 0xDE,
+0xE7, 0x80, 0xBE, 0x41, 0x8A, 0x56, 0x00, 0x41,
+0x8A, 0x57, 0x00, 0x41, 0x8A, 0x67, 0x00, 0x41,
+0x8A, 0x68, 0x00, 0x00, 0x68, 0x00, 0x77, 0xF0,
+0x7E, 0xCE, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83,
+0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0,
+0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03, 0xC0,
+0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90,
+0x01, 0xC4, 0x74, 0xBA, 0xF0, 0x74, 0x49, 0xA3,
+0xF0, 0x51, 0x09, 0x74, 0xBA, 0x04, 0x90, 0x01,
+0xC4, 0xF0, 0x74, 0x49, 0xA3, 0xF0, 0xD0, 0x07,
+0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03,
+0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0,
+0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0,
+0x32, 0x90, 0x00, 0x54, 0xE0, 0x55, 0x35, 0xF5,
+0x39, 0xA3, 0xE0, 0x55, 0x36, 0xF5, 0x3A, 0xA3,
+0xE0, 0x55, 0x37, 0xF5, 0x3B, 0xA3, 0xE0, 0x55,
+0x38, 0xF5, 0x3C, 0xAD, 0x39, 0x7F, 0x54, 0x12,
+0x32, 0x1E, 0xAD, 0x3A, 0x7F, 0x55, 0x12, 0x32,
+0x1E, 0xAD, 0x3B, 0x7F, 0x56, 0x12, 0x32, 0x1E,
+0xAD, 0x3C, 0x7F, 0x57, 0x12, 0x32, 0x1E, 0x53,
+0x91, 0xEF, 0x22, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0,
+0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00,
+0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03,
+0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07,
+0x90, 0x01, 0xC4, 0x74, 0x43, 0xF0, 0x74, 0x4A,
+0xA3, 0xF0, 0x12, 0x8D, 0x69, 0xE5, 0x41, 0x30,
+0xE3, 0x03, 0x12, 0x8D, 0xC6, 0xE5, 0x41, 0x30,
+0xE4, 0x03, 0x12, 0x50, 0xDD, 0xE5, 0x43, 0x30,
+0xE0, 0x03, 0x12, 0x50, 0xC7, 0xE5, 0x43, 0x30,
+0xE1, 0x02, 0x51, 0xE2, 0xE5, 0x43, 0x30, 0xE2,
+0x03, 0x12, 0x8E, 0x0F, 0xE5, 0x43, 0x30, 0xE3,
+0x03, 0x12, 0x6B, 0x5C, 0xE5, 0x43, 0x30, 0xE4,
+0x03, 0x12, 0x6B, 0x72, 0xE5, 0x43, 0x30, 0xE5,
+0x03, 0x12, 0x6F, 0x87, 0xE5, 0x43, 0x30, 0xE6,
+0x03, 0x12, 0x6F, 0x69, 0xE5, 0x44, 0x30, 0xE1,
+0x03, 0x12, 0x8E, 0x21, 0x74, 0x43, 0x04, 0x90,
+0x01, 0xC4, 0xF0, 0x74, 0x4A, 0xA3, 0xF0, 0xD0,
+0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0,
+0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0,
+0xE0, 0x32, 0x90, 0x81, 0x0A, 0xE0, 0x70, 0x02,
+0x61, 0x87, 0x90, 0x81, 0x21, 0xE0, 0x04, 0xF0,
+0x90, 0x05, 0x61, 0x71, 0xEB, 0x78, 0x08, 0xB1,
+0x59, 0xAB, 0x07, 0x90, 0x05, 0x60, 0x71, 0xEB,
+0x12, 0x44, 0x27, 0xC0, 0x04, 0xC0, 0x05, 0xC0,
+0x06, 0xC0, 0x07, 0x90, 0x05, 0x62, 0x71, 0xEB,
+0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0, 0x03, 0xD0,
+0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x44, 0x27,
+0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07,
+0xA3, 0x71, 0xEB, 0x78, 0x18, 0x12, 0x20, 0xBB,
+0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00,
+0x12, 0x44, 0x27, 0x90, 0x81, 0xCA, 0x12, 0x20,
+0xCE, 0x90, 0x81, 0x06, 0xE0, 0x54, 0x7F, 0xF0,
+0xA3, 0xE0, 0x30, 0xE0, 0x0F, 0x12, 0x7F, 0x84,
+0x90, 0x8A, 0x52, 0x74, 0x05, 0xF0, 0x12, 0x88,
+0xF3, 0x12, 0x8A, 0x14, 0x90, 0x81, 0x06, 0x12,
+0x6E, 0x71, 0x30, 0xE0, 0x0B, 0x90, 0x01, 0x3B,
+0xE0, 0x30, 0xE4, 0x04, 0xB1, 0x69, 0xB1, 0x63,
+0x90, 0x8A, 0x60, 0xE0, 0x04, 0xF0, 0xE0, 0xC3,
+0x94, 0x80, 0x40, 0x0B, 0x90, 0x01, 0x98, 0xE0,
+0x54, 0xFE, 0xF0, 0xE0, 0x44, 0x01, 0xF0, 0x12,
+0x70, 0x14, 0x12, 0x6C, 0xB6, 0xE4, 0x90, 0x84,
+0x92, 0xF0, 0x12, 0x5F, 0xDF, 0x30, 0xE0, 0x52,
+0x90, 0x84, 0x26, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
+0x7C, 0x00, 0x7D, 0x64, 0x12, 0x20, 0x30, 0x90,
+0x84, 0x7A, 0xE0, 0x6E, 0x70, 0x03, 0xA3, 0xE0,
+0x6F, 0x60, 0x0A, 0x90, 0x84, 0x7A, 0xE4, 0x75,
+0xF0, 0x01, 0x02, 0x43, 0xF6, 0x90, 0x84, 0x2A,
+0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x84, 0x38,
+0xE0, 0xB5, 0x06, 0x14, 0xA3, 0xE0, 0xB5, 0x07,
+0x0F, 0xEF, 0x4E, 0x60, 0x0B, 0x90, 0x01, 0xC7,
+0x74, 0x31, 0xF0, 0x7F, 0x01, 0x02, 0x70, 0x9D,
+0x12, 0x86, 0x8F, 0xE4, 0x90, 0x84, 0x7A, 0xF0,
+0xA3, 0xF0, 0x22, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD,
+0xFE, 0x22, 0x90, 0x84, 0xB3, 0xEF, 0xF0, 0xA3,
+0xED, 0xF0, 0xA3, 0x12, 0x20, 0xDA, 0x00, 0x00,
+0x00, 0x00, 0xE4, 0x90, 0x84, 0xC1, 0xF0, 0x7F,
+0x24, 0x7E, 0x08, 0x12, 0x2D, 0x5C, 0x90, 0x84,
+0xB9, 0x12, 0x20, 0xCE, 0x90, 0x84, 0xB3, 0xE0,
+0xFB, 0x70, 0x04, 0x91, 0xD4, 0x80, 0x06, 0xEB,
+0x91, 0xE3, 0x12, 0x2D, 0x5C, 0x90, 0x84, 0xBD,
+0x12, 0x20, 0xCE, 0x90, 0x84, 0xB4, 0x71, 0xEB,
+0x78, 0x17, 0xB1, 0x59, 0xAB, 0x07, 0x90, 0x84,
+0xBD, 0x12, 0x44, 0x45, 0xED, 0x54, 0x7F, 0xFD,
+0xEC, 0x54, 0x80, 0xFC, 0x12, 0x44, 0x27, 0xEC,
+0x44, 0x80, 0xFC, 0x90, 0x84, 0xBD, 0x12, 0x20,
+0xCE, 0x91, 0xD4, 0xEC, 0x54, 0x7F, 0xFC, 0x91,
+0xDD, 0x91, 0xF6, 0x91, 0xE3, 0xC0, 0x06, 0xC0,
+0x07, 0x90, 0x84, 0xBD, 0x91, 0xDA, 0xD0, 0x07,
+0xD0, 0x06, 0x12, 0x2E, 0xA2, 0x91, 0xD4, 0xEC,
+0x44, 0x80, 0xFC, 0x91, 0xDD, 0x91, 0xF6, 0x70,
+0x04, 0x7F, 0x20, 0x80, 0x09, 0x90, 0x84, 0xB3,
+0xE0, 0xB4, 0x01, 0x16, 0x7F, 0x28, 0x7E, 0x08,
+0x12, 0x2D, 0x5C, 0x78, 0x08, 0x12, 0x20, 0xA8,
+0xEF, 0x54, 0x01, 0xFF, 0xE4, 0x90, 0x84, 0xC1,
+0xEF, 0xF0, 0x90, 0x84, 0xC1, 0xE0, 0x90, 0x84,
+0xB3, 0x60, 0x0E, 0xE0, 0x75, 0xF0, 0x08, 0xA4,
+0x24, 0x66, 0xF5, 0x82, 0xE4, 0x34, 0x87, 0x80,
+0x0C, 0xE0, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x64,
+0xF5, 0x82, 0xE4, 0x34, 0x87, 0x91, 0xEE, 0x12,
+0x2D, 0x5C, 0xED, 0x54, 0x0F, 0xFD, 0xE4, 0xFC,
+0x90, 0x84, 0xB5, 0x12, 0x20, 0xCE, 0x90, 0x84,
+0xB5, 0x02, 0x44, 0x45, 0x90, 0x84, 0xB9, 0x02,
+0x44, 0x45, 0x12, 0x44, 0x45, 0x90, 0x85, 0xBB,
+0x02, 0x20, 0xCE, 0x75, 0xF0, 0x08, 0xA4, 0x24,
+0x62, 0xF5, 0x82, 0xE4, 0x34, 0x87, 0xF5, 0x83,
+0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0x7F, 0x24,
+0x7E, 0x08, 0x12, 0x2E, 0xA2, 0x90, 0x84, 0xB3,
+0xE0, 0x22, 0x90, 0x84, 0xEB, 0xEF, 0xF0, 0xAB,
+0x05, 0x90, 0x84, 0xF1, 0x12, 0x20, 0xDA, 0x00,
+0x00, 0x00, 0x00, 0xAF, 0x03, 0xE4, 0xFC, 0xFD,
+0xFE, 0x78, 0x14, 0xB1, 0x59, 0xAB, 0x07, 0x90,
+0x84, 0xED, 0x12, 0x44, 0x45, 0xED, 0x54, 0x0F,
+0xFD, 0xE4, 0xFC, 0x12, 0x44, 0x27, 0xEC, 0x54,
+0x0F, 0xFC, 0x90, 0x84, 0xF1, 0x12, 0x20, 0xCE,
+0x90, 0x84, 0xEB, 0xE0, 0x75, 0xF0, 0x08, 0xA4,
+0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34, 0x87, 0x91,
+0xEE, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x84, 0xF1,
+0x91, 0xDA, 0xD0, 0x07, 0xD0, 0x06, 0x02, 0x2E,
+0xA2, 0x12, 0x20, 0xBB, 0xA8, 0x04, 0xA9, 0x05,
+0xAA, 0x06, 0x22, 0x7D, 0x01, 0x7F, 0x02, 0x80,
+0x04, 0x7D, 0x02, 0x7F, 0x02, 0x74, 0x3D, 0x12,
+0x98, 0x8C, 0xFE, 0xF6, 0x74, 0x30, 0x02, 0x6E,
+0xEC, 0xEF, 0x70, 0x3E, 0x7D, 0x78, 0x7F, 0x02,
+0xB1, 0x6D, 0x7D, 0x02, 0x7F, 0x03, 0xB1, 0x6D,
+0x7D, 0xC8, 0x7F, 0x02, 0x12, 0x6E, 0xE3, 0x12,
+0x6E, 0x79, 0xF0, 0xE4, 0xFF, 0x12, 0x6A, 0x8A,
+0xEF, 0x70, 0x0E, 0x12, 0x80, 0x18, 0x12, 0x6B,
+0x11, 0x12, 0x91, 0xCB, 0x54, 0x7F, 0xF0, 0x80,
+0x06, 0x7D, 0x01, 0x7F, 0x0C, 0xB1, 0xFA, 0x12,
+0x8E, 0x94, 0x90, 0x06, 0x0A, 0xE0, 0x54, 0xF8,
+0xF0, 0x22, 0x90, 0x01, 0x36, 0x74, 0x78, 0xF0,
+0xA3, 0x74, 0x02, 0xF0, 0x7D, 0x78, 0xFF, 0x12,
+0x6E, 0x99, 0x7D, 0x02, 0x7F, 0x03, 0x12, 0x6E,
+0x99, 0x90, 0x06, 0x0A, 0xE0, 0x44, 0x07, 0x12,
+0x8A, 0x3A, 0xE4, 0xFF, 0x12, 0x6A, 0x8A, 0xBF,
+0x01, 0x10, 0x12, 0x6D, 0x55, 0x90, 0x81, 0x0D,
+0xE0, 0x20, 0xE2, 0x09, 0x7D, 0x01, 0x7F, 0x04,
+0x80, 0x08, 0x12, 0x98, 0x84, 0x22, 0x7D, 0x01,
+0x7F, 0x04, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x90, 0x8A, 0x63, 0xED, 0xF0, 0x90, 0x81,
+0x05, 0xE0, 0xFE, 0xC4, 0x13, 0x13, 0x54, 0x03,
+0x30, 0xE0, 0x02, 0xE1, 0x4B, 0xEE, 0x12, 0x5F,
+0xD8, 0x30, 0xE0, 0x02, 0xE1, 0x4B, 0x90, 0x81,
+0x0D, 0xE0, 0xFE, 0x6F, 0x70, 0x02, 0xE1, 0x4B,
+0xEF, 0x70, 0x02, 0xC1, 0xBA, 0x24, 0xFE, 0x70,
+0x02, 0xC1, 0xF5, 0x24, 0xFE, 0x60, 0x4A, 0x24,
+0xFC, 0x70, 0x02, 0xE1, 0x31, 0x24, 0xFC, 0x60,
+0x02, 0xE1, 0x41, 0xEE, 0xB4, 0x0E, 0x02, 0xF1,
+0x97, 0x90, 0x81, 0x0D, 0xE0, 0x70, 0x04, 0x7F,
+0x01, 0xF1, 0xDB, 0x90, 0x81, 0x0D, 0xE0, 0xB4,
+0x06, 0x02, 0xF1, 0xB6, 0x90, 0x81, 0x0D, 0xE0,
+0xB4, 0x04, 0x0F, 0x90, 0x8A, 0x63, 0xE0, 0xFF,
+0x60, 0x05, 0x12, 0x6B, 0x1C, 0x80, 0x03, 0x12,
+0x6B, 0x11, 0x90, 0x81, 0x0D, 0xE0, 0x64, 0x08,
+0x60, 0x02, 0xE1, 0x41, 0x12, 0x91, 0x64, 0xE1,
+0x41, 0x90, 0x81, 0x0D, 0xE0, 0x70, 0x04, 0x7F,
+0x01, 0xF1, 0xDB, 0x90, 0x81, 0x0D, 0xE0, 0xB4,
+0x06, 0x02, 0xF1, 0xB6, 0x90, 0x81, 0x0D, 0xE0,
+0xB4, 0x0E, 0x07, 0xF1, 0x50, 0xBF, 0x01, 0x02,
+0xF1, 0x97, 0x90, 0x81, 0x0D, 0xE0, 0x64, 0x0C,
+0x60, 0x02, 0xE1, 0x41, 0xF1, 0x50, 0xEF, 0x64,
+0x01, 0x60, 0x02, 0xE1, 0x41, 0x12, 0x69, 0xBD,
+0xE1, 0x41, 0x90, 0x81, 0x0D, 0xE0, 0xB4, 0x0E,
+0x07, 0xF1, 0x50, 0xBF, 0x01, 0x02, 0xF1, 0x97,
+0x90, 0x81, 0x0D, 0xE0, 0xB4, 0x06, 0x02, 0xF1,
+0xB6, 0x90, 0x81, 0x0D, 0xE0, 0xB4, 0x0C, 0x08,
+0xF1, 0x50, 0xBF, 0x01, 0x03, 0x12, 0x69, 0xBD,
+0x90, 0x81, 0x0D, 0xE0, 0x64, 0x04, 0x70, 0x59,
+0x12, 0x90, 0x0B, 0xEF, 0x64, 0x01, 0x70, 0x51,
+0x12, 0x6E, 0xA5, 0x80, 0x4C, 0x90, 0x81, 0x0D,
+0xE0, 0xB4, 0x0E, 0x07, 0xF1, 0x50, 0xBF, 0x01,
+0x02, 0xF1, 0x97, 0x90, 0x81, 0x0D, 0xE0, 0xB4,
+0x06, 0x02, 0xF1, 0xB6, 0x90, 0x81, 0x0D, 0xE0,
+0xB4, 0x0C, 0x08, 0xF1, 0x50, 0xBF, 0x01, 0x03,
+0x12, 0x69, 0xBD, 0x90, 0x81, 0x0D, 0xE0, 0x70,
+0x04, 0x7F, 0x01, 0xF1, 0xDB, 0x90, 0x81, 0x0D,
+0xE0, 0xB4, 0x04, 0x15, 0x12, 0x90, 0xFD, 0x80,
+0x10, 0x90, 0x81, 0x0D, 0xE0, 0xB4, 0x0C, 0x09,
+0x12, 0x6F, 0xEC, 0x30, 0xE0, 0x03, 0x12, 0x81,
+0xCC, 0x90, 0x81, 0x0D, 0x12, 0x8A, 0x25, 0x90,
+0x01, 0xBB, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12,
+0x8F, 0xF2, 0xEF, 0x64, 0x01, 0x60, 0x05, 0x75,
+0x1F, 0x01, 0x80, 0x20, 0x90, 0x81, 0x05, 0xF1,
+0xF3, 0x30, 0xE0, 0x05, 0x75, 0x1F, 0x02, 0x80,
+0x13, 0x90, 0x81, 0x0C, 0xE0, 0xD3, 0x94, 0x04,
+0x40, 0x05, 0x75, 0x1F, 0x08, 0x80, 0x05, 0x12,
+0x90, 0x73, 0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74,
+0x02, 0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x1F, 0xF0,
+0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90,
+0x81, 0x06, 0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x04,
+0x7D, 0x0C, 0x80, 0x05, 0x12, 0x91, 0xD3, 0x7D,
+0x04, 0x7F, 0x01, 0x12, 0x69, 0x45, 0xE4, 0xFB,
+0xFD, 0x7F, 0xFF, 0x02, 0x66, 0x73, 0x90, 0x81,
+0x06, 0xE0, 0x90, 0x06, 0x04, 0x20, 0xE0, 0x08,
+0xE0, 0x44, 0x40, 0xF0, 0x7D, 0x04, 0x80, 0x06,
+0xE0, 0x54, 0x7F, 0xF0, 0x7D, 0x0C, 0x7F, 0x01,
+0x12, 0x69, 0x45, 0xE4, 0xFB, 0xFD, 0x7F, 0xFF,
+0x02, 0x66, 0x73, 0x90, 0x8A, 0x62, 0xEF, 0xF0,
+0x12, 0x80, 0x18, 0x90, 0x8A, 0x62, 0xE0, 0x60,
+0x03, 0x12, 0x66, 0x6E, 0x7D, 0x04, 0x7F, 0x01,
+0x02, 0x69, 0x45, 0xE0, 0x13, 0x13, 0x13, 0x54,
+0x1F, 0x22, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83,
+0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0,
+0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03, 0xC0,
+0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90,
+0x01, 0xC4, 0x74, 0xFA, 0xF0, 0x74, 0x4F, 0xA3,
+0xF0, 0x12, 0x8D, 0x96, 0xE5, 0x49, 0x30, 0xE1,
+0x02, 0x11, 0x81, 0xE5, 0x49, 0x30, 0xE2, 0x03,
+0x12, 0x8E, 0x7F, 0xE5, 0x4A, 0x30, 0xE0, 0x03,
+0x12, 0x89, 0xC8, 0xE5, 0x4C, 0x30, 0xE1, 0x04,
+0x7F, 0x04, 0x11, 0xCE, 0xE5, 0x4C, 0x30, 0xE4,
+0x02, 0x11, 0x8B, 0xE5, 0x4C, 0x30, 0xE5, 0x03,
+0x12, 0x8A, 0x72, 0xE5, 0x4C, 0x30, 0xE6, 0x03,
+0x12, 0x8A, 0x9F, 0x74, 0xFA, 0x04, 0x90, 0x01,
+0xC4, 0xF0, 0x74, 0x4F, 0xA3, 0xF0, 0xD0, 0x07,
+0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03,
+0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0,
+0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0,
+0x32, 0x90, 0x81, 0x0A, 0xE0, 0x60, 0x03, 0x12,
+0x6C, 0xF1, 0x22, 0x12, 0x6B, 0x94, 0x12, 0x6E,
+0x95, 0x7F, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x81, 0x07, 0xE0, 0xFE, 0xC3,
+0x13, 0x30, 0xE0, 0x1E, 0x90, 0x84, 0xC2, 0x74,
+0x1E, 0xF0, 0x90, 0x84, 0xD0, 0x74, 0x01, 0xF0,
+0x90, 0x84, 0xC4, 0xEF, 0xF0, 0x7B, 0x01, 0x7A,
+0x84, 0x79, 0xC2, 0x12, 0x8C, 0x5C, 0x7F, 0x04,
+0x11, 0xCE, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12,
+0x6B, 0xC4, 0xE4, 0xFF, 0x80, 0xC5, 0x8F, 0x0F,
+0x7F, 0x02, 0x12, 0x48, 0x9E, 0x90, 0x80, 0x01,
+0xE0, 0x45, 0x0F, 0xF0, 0x22, 0x11, 0xE3, 0x7F,
+0x02, 0x80, 0xEB, 0x90, 0x01, 0xCC, 0xE0, 0x54,
+0x0F, 0x90, 0x8A, 0x58, 0xF0, 0x90, 0x8A, 0x58,
+0xE0, 0xFD, 0x70, 0x02, 0x21, 0xE4, 0x90, 0x80,
+0x60, 0xE0, 0xFF, 0x70, 0x06, 0xA3, 0xE0, 0x64,
+0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90, 0x80,
+0x61, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80,
+0x02, 0x7F, 0x00, 0xEF, 0x60, 0x08, 0x90, 0x01,
+0xC1, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90, 0x8A,
+0x56, 0x12, 0x97, 0x99, 0x80, 0x05, 0xC3, 0x33,
+0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D,
+0x70, 0x02, 0x21, 0xC6, 0xE4, 0x90, 0x8A, 0x59,
+0xF0, 0x90, 0x8A, 0x59, 0xE0, 0xF9, 0xC3, 0x94,
+0x04, 0x50, 0x35, 0xF1, 0x2A, 0xA4, 0xFF, 0xE9,
+0xFD, 0x7C, 0x00, 0x2F, 0xFF, 0xEC, 0x35, 0xF0,
+0xFE, 0x74, 0xD0, 0x12, 0x97, 0xA3, 0x90, 0x80,
+0x10, 0x12, 0x97, 0xD0, 0xF1, 0x2A, 0xA4, 0x2D,
+0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74, 0xF0, 0x12,
+0x97, 0xA3, 0x90, 0x80, 0x14, 0x12, 0x97, 0xD0,
+0x90, 0x8A, 0x59, 0xE0, 0x04, 0xF0, 0x80, 0xC1,
+0x90, 0x8A, 0x58, 0xE0, 0xFF, 0x90, 0x8A, 0x56,
+0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x06, 0x08, 0x80,
+0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0x90,
+0x8A, 0x58, 0xF0, 0x90, 0x8A, 0x56, 0x31, 0xEB,
+0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x90, 0x01,
+0xCC, 0xF0, 0x90, 0x8A, 0x56, 0xE0, 0x04, 0xF0,
+0xE0, 0x54, 0x03, 0xF0, 0x90, 0x80, 0x61, 0xE0,
+0x04, 0xF0, 0xE0, 0x7F, 0x00, 0xB4, 0x0A, 0x02,
+0x7F, 0x01, 0xEF, 0x70, 0x02, 0x01, 0xED, 0xE4,
+0x90, 0x80, 0x61, 0xF0, 0x01, 0xED, 0x90, 0x01,
+0xC0, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x8A, 0x56,
+0xE0, 0x44, 0x80, 0x90, 0x00, 0x8A, 0xF0, 0xF1,
+0x2A, 0x90, 0x01, 0xD0, 0x12, 0x44, 0x5D, 0xE0,
+0x90, 0x01, 0xC3, 0xF0, 0x22, 0x12, 0x32, 0x1E,
+0x90, 0x8A, 0x5A, 0xE0, 0xFF, 0x74, 0x01, 0xA8,
+0x07, 0x08, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x8A, 0x5B, 0xED, 0xF0, 0x90,
+0x8A, 0x5A, 0xEF, 0xF0, 0xD3, 0x94, 0x07, 0x50,
+0x4B, 0x31, 0xEB, 0x80, 0x02, 0xC3, 0x33, 0xD8,
+0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x47, 0xE0, 0x5F,
+0xFD, 0x7F, 0x47, 0x31, 0xE5, 0x80, 0x02, 0xC3,
+0x33, 0xD8, 0xFC, 0xFF, 0x90, 0x00, 0x46, 0xE0,
+0x4F, 0xFD, 0x7F, 0x46, 0xF1, 0xE7, 0x60, 0x10,
+0x31, 0xE8, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC,
+0xFF, 0x90, 0x00, 0x45, 0xE0, 0x4F, 0x80, 0x0F,
+0x31, 0xE8, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC,
+0xF4, 0xFF, 0x90, 0x00, 0x45, 0xE0, 0x5F, 0xFD,
+0x7F, 0x45, 0x80, 0x62, 0x90, 0x8A, 0x5A, 0xE0,
+0x24, 0xF8, 0xF0, 0xE0, 0x24, 0x04, 0x31, 0xEC,
+0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF,
+0x90, 0x00, 0x43, 0xE0, 0x5F, 0xFD, 0x7F, 0x43,
+0x31, 0xE5, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC,
+0xFF, 0x90, 0x00, 0x43, 0xE0, 0x4F, 0xFD, 0x7F,
+0x43, 0xF1, 0xE7, 0x60, 0x19, 0x90, 0x8A, 0x5A,
+0xE0, 0x24, 0x04, 0x31, 0xEC, 0x80, 0x02, 0xC3,
+0x33, 0xD8, 0xFC, 0xFF, 0x90, 0x00, 0x42, 0xE0,
+0x4F, 0xFD, 0x7F, 0x42, 0x80, 0x18, 0x90, 0x8A,
+0x5A, 0xE0, 0x24, 0x04, 0x31, 0xEC, 0x80, 0x02,
+0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00,
+0x42, 0xE0, 0x5F, 0xFD, 0x7F, 0x42, 0x12, 0x32,
+0x1E, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x89,
+0x34, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x89,
+0x37, 0xEB, 0xF0, 0x90, 0x89, 0x36, 0xED, 0xF0,
+0x60, 0x15, 0x90, 0x89, 0x34, 0x12, 0x5F, 0x76,
+0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xF0,
+0xEE, 0x90, 0x89, 0x34, 0xF0, 0x80, 0x19, 0xF1,
+0xD7, 0x78, 0x06, 0xC3, 0x33, 0xCE, 0x33, 0xCE,
+0xD8, 0xF9, 0xF0, 0xEE, 0x90, 0x89, 0x34, 0xF0,
+0x74, 0xFF, 0x75, 0xF0, 0xD0, 0x12, 0x43, 0xF6,
+0x71, 0x9F, 0x54, 0x07, 0x7D, 0x00, 0x20, 0xE0,
+0x02, 0x7D, 0x01, 0x31, 0xF3, 0x71, 0x9F, 0x54,
+0x01, 0xFD, 0x31, 0xF3, 0x90, 0x89, 0x38, 0xE0,
+0x60, 0x57, 0x71, 0x92, 0x54, 0x07, 0x7D, 0x00,
+0x20, 0xE0, 0x02, 0x7D, 0x01, 0x31, 0xF3, 0x90,
+0x89, 0x39, 0xE0, 0x60, 0x1D, 0x90, 0x81, 0xE6,
+0xE0, 0x30, 0xE0, 0x3D, 0x90, 0x01, 0xC6, 0xE0,
+0x20, 0xE4, 0x36, 0x71, 0x72, 0x54, 0x07, 0x7D,
+0x00, 0x20, 0xE0, 0x02, 0x7D, 0x01, 0x31, 0xF3,
+0x80, 0xE3, 0xE4, 0x90, 0x89, 0x3A, 0xF0, 0x90,
+0x89, 0x37, 0xE0, 0xFF, 0x90, 0x89, 0x3A, 0xE0,
+0xC3, 0x9F, 0x50, 0x15, 0x71, 0x72, 0x54, 0x07,
+0x7D, 0x00, 0x20, 0xE0, 0x02, 0x7D, 0x01, 0x31,
+0xF3, 0x90, 0x89, 0x3A, 0xE0, 0x04, 0xF0, 0x80,
+0xDE, 0x22, 0x90, 0x89, 0x34, 0xE0, 0xFE, 0xA3,
+0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0x71, 0xAE, 0x90,
+0x81, 0xE7, 0xE0, 0x54, 0x7F, 0xFF, 0x90, 0x81,
+0xE6, 0xE0, 0xFE, 0xC4, 0x13, 0x54, 0x01, 0xFD,
+0x31, 0xF3, 0x90, 0x89, 0x34, 0xE0, 0xFE, 0xA3,
+0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0x71, 0xAE, 0x90,
+0x81, 0xE7, 0xE0, 0x54, 0x7F, 0xFF, 0x90, 0x81,
+0xE6, 0xE0, 0xFE, 0xC4, 0x13, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8E, 0x0D, 0x8F,
+0x0E, 0xBD, 0x01, 0x05, 0x12, 0x32, 0x06, 0x80,
+0x07, 0xAF, 0x0E, 0xAE, 0x0D, 0x12, 0x32, 0xAA,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x8A, 0x1C, 0x20,
+0xE0, 0x1E, 0x54, 0x01, 0xFF, 0x90, 0x81, 0xE6,
+0xE0, 0x54, 0xFE, 0x4F, 0xF0, 0xA3, 0x71, 0xA2,
+0x54, 0x07, 0x7D, 0x00, 0x20, 0xE0, 0x02, 0x7D,
+0x01, 0x31, 0xF3, 0x12, 0x86, 0x0A, 0xA1, 0x09,
+0x12, 0x92, 0x04, 0xFE, 0x90, 0x81, 0xE6, 0xF1,
+0xBB, 0x12, 0x87, 0x88, 0xFF, 0x90, 0x81, 0xE6,
+0x12, 0x87, 0xBA, 0xF1, 0xC9, 0x12, 0x87, 0x78,
+0xFF, 0x90, 0x81, 0xE6, 0x12, 0x85, 0x50, 0xF1,
+0xC9, 0x12, 0x87, 0x80, 0xFF, 0x90, 0x81, 0xE6,
+0x12, 0x87, 0xB0, 0xD1, 0x94, 0x54, 0x80, 0xFF,
+0x90, 0x81, 0xE7, 0xE0, 0x54, 0x7F, 0x4F, 0xB1,
+0x9B, 0xFF, 0x54, 0x02, 0xFE, 0x90, 0x81, 0xEA,
+0xE0, 0x54, 0xFD, 0x4E, 0xFE, 0xF0, 0xEF, 0x54,
+0x08, 0xFF, 0xEE, 0x54, 0xF7, 0x4F, 0xF0, 0x90,
+0x00, 0x05, 0x12, 0x1F, 0xBD, 0x90, 0x81, 0xEB,
+0xB1, 0x9B, 0x54, 0x10, 0xFF, 0x90, 0x81, 0xEA,
+0xE0, 0x54, 0xEF, 0x4F, 0xF0, 0x12, 0x1F, 0xA4,
+0xFF, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x07,
+0x90, 0x06, 0x90, 0xE0, 0x44, 0x04, 0xF0, 0xEF,
+0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x07,
+0x90, 0x06, 0x90, 0xE0, 0x44, 0x08, 0xF0, 0x90,
+0x80, 0x07, 0xE0, 0xB4, 0x02, 0x09, 0x90, 0x81,
+0xE7, 0x12, 0x5F, 0xD7, 0x20, 0xE0, 0x57, 0x90,
+0x89, 0x19, 0x12, 0x44, 0x69, 0xD1, 0x95, 0x54,
+0x7F, 0xFF, 0x90, 0x81, 0xE7, 0xE0, 0x54, 0x80,
+0x4F, 0xF1, 0x74, 0xFF, 0x54, 0x7F, 0xFE, 0x90,
+0x81, 0xE8, 0xE0, 0x54, 0x80, 0xF1, 0xB3, 0xFE,
+0x54, 0x01, 0xFD, 0x90, 0x81, 0xE9, 0x12, 0x87,
+0xA8, 0x54, 0xFE, 0xFE, 0xED, 0x54, 0x01, 0x4E,
+0xB1, 0x9B, 0x54, 0x04, 0xFE, 0x90, 0x81, 0xEA,
+0xE0, 0x54, 0xFB, 0x4E, 0xF0, 0xEF, 0x54, 0x80,
+0xFF, 0x90, 0x81, 0xE8, 0xE0, 0x54, 0x7F, 0x4F,
+0xF0, 0x71, 0x9F, 0x54, 0x07, 0x7D, 0x00, 0x20,
+0xE0, 0x02, 0x7D, 0x01, 0x31, 0xF3, 0x90, 0x80,
+0x07, 0xE0, 0xB4, 0x01, 0x07, 0x90, 0xFE, 0x10,
+0xE0, 0x44, 0x04, 0xF0, 0x90, 0x84, 0x22, 0x74,
+0x05, 0xF0, 0x7E, 0x00, 0x7F, 0x08, 0x7D, 0x00,
+0x7B, 0x01, 0x7A, 0x83, 0x79, 0x01, 0x12, 0x46,
+0x4B, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x89,
+0x16, 0x12, 0x44, 0x72, 0x90, 0x89, 0x15, 0xEF,
+0xF0, 0x12, 0x44, 0x7B, 0x55, 0x47, 0x00, 0x55,
+0x4C, 0x01, 0x55, 0x51, 0x03, 0x55, 0x56, 0x04,
+0x55, 0x5B, 0x14, 0x55, 0x60, 0x20, 0x55, 0x65,
+0x25, 0x55, 0x6E, 0x80, 0x55, 0x69, 0x81, 0x55,
+0x72, 0x82, 0x55, 0x77, 0x83, 0x55, 0x7B, 0x84,
+0x55, 0x80, 0x88, 0x00, 0x00, 0x55, 0x85, 0xB1,
+0x95, 0x02, 0x87, 0xF7, 0xB1, 0x95, 0x02, 0x6A,
+0xAD, 0xB1, 0x95, 0x02, 0x91, 0xDF, 0xB1, 0x95,
+0x02, 0x92, 0x11, 0xB1, 0x95, 0x02, 0x88, 0x3B,
+0xB1, 0x95, 0x02, 0x88, 0x4A, 0xB1, 0x95, 0xE1,
+0xEF, 0xB1, 0x95, 0x02, 0x84, 0x53, 0xB1, 0x95,
+0x61, 0xCD, 0xB1, 0x95, 0x02, 0x95, 0x13, 0xB1,
+0x95, 0xE1, 0x7B, 0xB1, 0x95, 0x02, 0x95, 0x21,
+0xB1, 0x95, 0x02, 0x95, 0x75, 0x90, 0x01, 0xC0,
+0xE0, 0x44, 0x01, 0xF0, 0x90, 0x89, 0x15, 0xE0,
+0x90, 0x01, 0xC2, 0xF0, 0x22, 0x90, 0x89, 0x16,
+0x02, 0x44, 0x69, 0xF0, 0x90, 0x00, 0x04, 0x02,
+0x1F, 0xBD, 0x90, 0x84, 0xDE, 0x12, 0x44, 0x72,
+0x90, 0x84, 0xE2, 0xE0, 0xFE, 0x64, 0x04, 0x70,
+0x0C, 0xD1, 0x8D, 0x12, 0x1F, 0xA4, 0x90, 0x84,
+0xE3, 0xD1, 0x94, 0x80, 0x10, 0xEE, 0x64, 0x02,
+0x70, 0x2F, 0xD1, 0x8D, 0xF1, 0x75, 0x90, 0x84,
+0xE3, 0xF0, 0x12, 0x1F, 0xA4, 0x90, 0x84, 0xE4,
+0xB1, 0x9B, 0x90, 0x84, 0xE5, 0xF0, 0x90, 0x00,
+0x05, 0x12, 0x1F, 0xBD, 0x90, 0x84, 0xE6, 0xF1,
+0xD0, 0x90, 0x84, 0xE7, 0xF0, 0x90, 0x00, 0x07,
+0x12, 0x1F, 0xBD, 0x90, 0x84, 0xE8, 0xF1, 0xB4,
+0xFF, 0xED, 0x70, 0x19, 0xFE, 0xF1, 0x32, 0xE0,
+0xB4, 0xFF, 0x06, 0xF1, 0x32, 0xE4, 0xF0, 0x80,
+0x07, 0xF1, 0x32, 0xE0, 0x04, 0xF0, 0x80, 0x05,
+0x0E, 0xEE, 0xB4, 0x06, 0xE8, 0x90, 0x84, 0xE2,
+0xE0, 0xFE, 0xB4, 0x04, 0x18, 0xA3, 0xE0, 0xFD,
+0xD1, 0x8D, 0xED, 0xF1, 0xDF, 0xFD, 0xD1, 0x8D,
+0x90, 0x00, 0x01, 0xED, 0x12, 0x1F, 0xFC, 0x90,
+0x00, 0x02, 0xE4, 0x80, 0x20, 0xEE, 0xB4, 0x02,
+0x1F, 0x90, 0x84, 0xE4, 0xD1, 0x8B, 0xEE, 0xF1,
+0xDF, 0x44, 0x20, 0x54, 0x7F, 0xD1, 0x8C, 0x90,
+0x00, 0x01, 0xEE, 0x12, 0x1F, 0xFC, 0x90, 0x84,
+0xE3, 0xE0, 0x90, 0x00, 0x02, 0x12, 0x1F, 0xFC,
+0xD1, 0x8D, 0xE9, 0x24, 0x03, 0xF9, 0xE4, 0x3A,
+0xFA, 0x12, 0x1F, 0xA4, 0x44, 0x20, 0x12, 0x1F,
+0xEA, 0x90, 0x84, 0xE5, 0xD1, 0x8B, 0x90, 0x00,
+0x04, 0xEE, 0x12, 0x1F, 0xFC, 0x90, 0x84, 0xE6,
+0xE0, 0x90, 0x00, 0x05, 0x12, 0x1F, 0xFC, 0x90,
+0x84, 0xE7, 0xE0, 0x90, 0x00, 0x06, 0x12, 0x1F,
+0xFC, 0x90, 0x84, 0xE8, 0xE0, 0x90, 0x00, 0x07,
+0x02, 0x1F, 0xFC, 0xE0, 0xFE, 0x90, 0x84, 0xDE,
+0x02, 0x44, 0x69, 0xFE, 0xF0, 0x90, 0x00, 0x01,
+0x02, 0x1F, 0xBD, 0x90, 0x8A, 0x3B, 0xED, 0xF0,
+0x90, 0x8A, 0x38, 0x12, 0x44, 0x72, 0xE4, 0x90,
+0x8A, 0x3C, 0xF0, 0xA3, 0xF0, 0x12, 0x1F, 0xA4,
+0xFF, 0xD1, 0x95, 0xFD, 0xB1, 0x9C, 0xFB, 0x12,
+0x86, 0x6E, 0x90, 0x8A, 0x3C, 0xEF, 0xF0, 0x90,
+0x8A, 0x38, 0x12, 0x44, 0x69, 0xB1, 0x9C, 0xFF,
+0x12, 0x93, 0xED, 0x90, 0x8A, 0x3D, 0xEF, 0xF0,
+0x90, 0x84, 0x23, 0xE0, 0x24, 0xFE, 0x60, 0x16,
+0x24, 0xFE, 0x60, 0x12, 0x14, 0x60, 0x07, 0x14,
+0x60, 0x04, 0x24, 0x05, 0x70, 0x43, 0x12, 0x97,
+0xF3, 0x12, 0x96, 0x74, 0x80, 0x0D, 0x12, 0x97,
+0xF3, 0x90, 0x84, 0x23, 0xE0, 0x90, 0x84, 0xE2,
+0xF0, 0xB1, 0xA2, 0x90, 0x8A, 0x3D, 0xE0, 0xFF,
+0x90, 0x8A, 0x38, 0x12, 0x44, 0x69, 0x90, 0x8A,
+0x3C, 0xE0, 0x7C, 0x00, 0x29, 0xF9, 0xEC, 0x3A,
+0xFA, 0xC3, 0xE9, 0x9F, 0xF9, 0xEA, 0x94, 0x00,
+0xFA, 0x75, 0x13, 0x01, 0x75, 0x14, 0x83, 0x75,
+0x15, 0xF2, 0xA3, 0xE0, 0xF5, 0x16, 0x12, 0x2B,
+0xED, 0x22, 0x90, 0x8A, 0x56, 0xE0, 0x75, 0xF0,
+0x04, 0x22, 0x74, 0xE3, 0x2E, 0xF5, 0x82, 0xE4,
+0x34, 0x84, 0xF5, 0x83, 0x22, 0xFF, 0x90, 0x89,
+0xA9, 0xF0, 0x7B, 0x01, 0x7A, 0x89, 0x79, 0xAA,
+0x12, 0x1F, 0xA4, 0x90, 0x06, 0x74, 0xD1, 0x94,
+0x90, 0x06, 0x75, 0xF1, 0x74, 0x90, 0x06, 0x76,
+0xF1, 0xB4, 0x90, 0x06, 0x77, 0xF0, 0x90, 0x06,
+0x70, 0xEF, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0x04,
+0xF0, 0xA3, 0x74, 0x80, 0xF0, 0x7F, 0x01, 0x7E,
+0x00, 0x02, 0x32, 0xAA, 0xF0, 0x90, 0x00, 0x02,
+0x02, 0x1F, 0xBD, 0x12, 0x95, 0x67, 0x90, 0x84,
+0x7E, 0xD1, 0x94, 0xFF, 0xED, 0x2F, 0x90, 0x84,
+0x7F, 0xF1, 0x74, 0xFF, 0xED, 0x2F, 0x90, 0x84,
+0x80, 0xF1, 0xB4, 0xFF, 0xED, 0x2F, 0x90, 0x84,
+0x81, 0xB1, 0x9B, 0xFF, 0xED, 0x2F, 0x90, 0x84,
+0x82, 0x12, 0x95, 0x5C, 0x90, 0x84, 0x83, 0xF1,
+0xD0, 0xFF, 0xAE, 0x05, 0xED, 0x2F, 0x90, 0x84,
+0x84, 0xF0, 0x22, 0x4E, 0xF0, 0x90, 0x00, 0x03,
+0x02, 0x1F, 0xBD, 0xE0, 0x54, 0xFE, 0x4E, 0xFE,
+0xF0, 0xEF, 0x54, 0x02, 0xFF, 0xEE, 0x54, 0xFD,
+0x4F, 0xFF, 0xF0, 0x12, 0x1F, 0xA4, 0xFE, 0x22,
+0xF0, 0x90, 0x00, 0x06, 0x02, 0x1F, 0xBD, 0x90,
+0x89, 0x34, 0xE0, 0xFE, 0xA3, 0xE0, 0x22, 0x12,
+0x1F, 0xEA, 0x90, 0x84, 0xE4, 0xE0, 0x22, 0x12,
+0x32, 0x1E, 0x90, 0x8A, 0x5B, 0xE0, 0x22, 0x12,
+0x1F, 0xA4, 0x90, 0x81, 0xE2, 0xF0, 0x22, 0xC0,
+0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75,
+0xD0, 0x00, 0xC0, 0x05, 0xC0, 0x07, 0x7D, 0xF7,
+0x90, 0x01, 0xC4, 0xED, 0xF0, 0x74, 0x57, 0xFF,
+0xA3, 0xF0, 0xED, 0x04, 0x90, 0x01, 0xC4, 0xF0,
+0xA3, 0xEF, 0xF0, 0xD0, 0x07, 0xD0, 0x05, 0xD0,
+0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32,
+0x90, 0x00, 0xF7, 0xE0, 0x20, 0xE7, 0x09, 0xE0,
+0x7F, 0x01, 0x20, 0xE6, 0x0C, 0x7F, 0x02, 0x22,
+0x90, 0x00, 0xF7, 0xE0, 0x30, 0xE6, 0x02, 0x7F,
+0x03, 0x22, 0x11, 0x28, 0x90, 0x80, 0x07, 0xEF,
+0xF0, 0x11, 0x62, 0x90, 0x01, 0x64, 0x74, 0x01,
+0xF0, 0x90, 0x00, 0x12, 0xE0, 0x54, 0xC7, 0x44,
+0x20, 0xFD, 0x7F, 0x12, 0x12, 0x32, 0x1E, 0x02,
+0x2D, 0xA7, 0x90, 0x00, 0x08, 0xE0, 0x54, 0xEF,
+0xF0, 0x11, 0x9C, 0x12, 0x8C, 0xBD, 0x12, 0x8C,
+0xE6, 0x12, 0x8D, 0x05, 0xE4, 0xF5, 0x35, 0xF5,
+0x37, 0xF5, 0x36, 0xF5, 0x37, 0x75, 0x38, 0x80,
+0xAD, 0x35, 0x7F, 0x50, 0x12, 0x32, 0x1E, 0xAD,
+0x36, 0x7F, 0x51, 0x12, 0x32, 0x1E, 0xAD, 0x37,
+0x7F, 0x52, 0x12, 0x32, 0x1E, 0xAD, 0x38, 0x7F,
+0x53, 0x02, 0x32, 0x1E, 0x90, 0x01, 0x30, 0xE4,
+0x11, 0xC4, 0x90, 0x01, 0x38, 0x11, 0xC4, 0xFD,
+0x7F, 0x50, 0x12, 0x32, 0x1E, 0xE4, 0xFD, 0x7F,
+0x51, 0x12, 0x32, 0x1E, 0xE4, 0xFD, 0x7F, 0x52,
+0x12, 0x32, 0x1E, 0xE4, 0xFD, 0x7F, 0x53, 0x02,
+0x32, 0x1E, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3,
+0xF0, 0xA3, 0xF0, 0x22, 0x12, 0x70, 0xEB, 0xE4,
+0x90, 0x84, 0x88, 0x11, 0xC4, 0x90, 0x84, 0x26,
+0x11, 0xC2, 0xA3, 0x11, 0xC2, 0x90, 0x84, 0x38,
+0xF0, 0xA3, 0xF0, 0x90, 0x84, 0x7A, 0xF0, 0xA3,
+0xF0, 0x22, 0x90, 0x89, 0xA4, 0xEF, 0xF0, 0xA3,
+0xED, 0xF0, 0xA3, 0x12, 0x44, 0x72, 0x90, 0x89,
+0xA6, 0x12, 0x66, 0x5D, 0x31, 0x6F, 0x24, 0x02,
+0x12, 0x57, 0x3D, 0x31, 0x84, 0x24, 0x04, 0x31,
+0x66, 0x24, 0x03, 0x12, 0x57, 0x3D, 0x31, 0x84,
+0x24, 0x08, 0x31, 0x66, 0x24, 0x04, 0x12, 0x57,
+0x3D, 0x31, 0x84, 0x24, 0x0C, 0x31, 0x66, 0x24,
+0x05, 0x12, 0x57, 0x3D, 0x90, 0x89, 0xA5, 0xE0,
+0xFD, 0xB4, 0x02, 0x08, 0x90, 0x89, 0xA4, 0xE0,
+0x44, 0x48, 0x80, 0x0A, 0xED, 0xB4, 0x04, 0x0A,
+0x90, 0x89, 0xA4, 0xE0, 0x44, 0x50, 0x90, 0x89,
+0xAA, 0xF0, 0x90, 0x89, 0xAB, 0x74, 0x80, 0xF0,
+0xA3, 0x74, 0xFF, 0xF0, 0xA3, 0xF0, 0x31, 0x7B,
+0x12, 0x57, 0x3D, 0x90, 0x89, 0xAA, 0x74, 0xFF,
+0x11, 0xC4, 0x31, 0x7B, 0x04, 0x12, 0x57, 0x3D,
+0x90, 0x06, 0x72, 0xE4, 0xF0, 0x22, 0xF9, 0xE4,
+0x3A, 0x8B, 0x13, 0xF5, 0x14, 0x89, 0x15, 0x75,
+0x16, 0x04, 0x7B, 0x01, 0x7A, 0x89, 0x79, 0xAA,
+0x12, 0x2B, 0xED, 0x90, 0x89, 0xA4, 0xE0, 0x75,
+0xF0, 0x08, 0xA4, 0x22, 0x90, 0x89, 0xA6, 0x12,
+0x44, 0x69, 0xE9, 0x22, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x89, 0x1F, 0x74, 0x08,
+0xF0, 0xE4, 0x11, 0xC3, 0x90, 0x89, 0x26, 0xF0,
+0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x1F, 0xE0,
+0xFE, 0x90, 0x01, 0x1E, 0x12, 0x81, 0xF8, 0x90,
+0x89, 0x15, 0x12, 0x93, 0x77, 0xE0, 0x90, 0x89,
+0x1E, 0xF0, 0x90, 0x81, 0xE3, 0xE0, 0x20, 0xE0,
+0x02, 0x81, 0xE0, 0xE4, 0x90, 0x89, 0x1D, 0xF0,
+0x90, 0x89, 0x1E, 0xE0, 0xFF, 0x90, 0x89, 0x1D,
+0xE0, 0xC3, 0x9F, 0x40, 0x02, 0x81, 0xE0, 0xF1,
+0x6B, 0xFD, 0xEC, 0xFF, 0x90, 0xFD, 0x11, 0xF0,
+0xAE, 0x05, 0xAA, 0x06, 0x90, 0x89, 0x21, 0xEF,
+0xF0, 0x74, 0x02, 0x2A, 0x12, 0x93, 0x9E, 0xFF,
+0x74, 0x03, 0x2A, 0x12, 0x93, 0x87, 0xFE, 0xEF,
+0x24, 0x18, 0x2E, 0x90, 0x89, 0x26, 0xF0, 0xE0,
+0xFF, 0x2A, 0x90, 0x89, 0x19, 0xF0, 0x7E, 0x00,
+0xF1, 0x6B, 0x2F, 0xFF, 0xEE, 0x3C, 0x90, 0x89,
+0x1A, 0x12, 0x93, 0x6F, 0xE0, 0xFD, 0x24, 0x00,
+0xF1, 0xA2, 0xFE, 0x54, 0xFC, 0x90, 0x89, 0x1C,
+0xF0, 0xAF, 0x06, 0x12, 0x93, 0x30, 0xFD, 0x90,
+0x89, 0x19, 0xE0, 0x12, 0x98, 0x65, 0x12, 0x86,
+0x6A, 0x90, 0x89, 0x20, 0xEF, 0xF0, 0x74, 0x01,
+0x2A, 0x12, 0x93, 0x33, 0xFE, 0x74, 0x00, 0x2A,
+0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0x12,
+0x81, 0xF8, 0x54, 0x3F, 0xFE, 0x90, 0x89, 0x22,
+0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x89, 0x26, 0xE0,
+0x2F, 0xFF, 0xEC, 0x3E, 0xFE, 0x12, 0x93, 0x3C,
+0x90, 0x89, 0x17, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0,
+0x90, 0x89, 0x1C, 0xE0, 0x64, 0x80, 0x70, 0x5F,
+0x74, 0x0C, 0x2A, 0xF5, 0x82, 0xE4, 0x34, 0xFB,
+0xF5, 0x83, 0xE0, 0x54, 0x1F, 0x14, 0x60, 0x08,
+0x24, 0xFD, 0x60, 0x18, 0x24, 0x04, 0x70, 0x31,
+0xF1, 0x73, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8,
+0xF9, 0xF1, 0x86, 0xCE, 0xC3, 0x13, 0xCE, 0x13,
+0xD8, 0xF9, 0x80, 0x2F, 0xF1, 0x73, 0xC3, 0x33,
+0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x7C, 0x00,
+0x7D, 0x06, 0x12, 0x20, 0x30, 0xEF, 0xF1, 0x86,
+0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x80,
+0x12, 0xF1, 0x73, 0xC3, 0x33, 0xCE, 0x33, 0xCE,
+0xD8, 0xF9, 0xF1, 0x86, 0xCE, 0xC3, 0x13, 0xCE,
+0x13, 0xD8, 0xF9, 0x90, 0x81, 0xD6, 0xF0, 0x74,
+0x0F, 0x2A, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5,
+0x83, 0xE0, 0xFF, 0x90, 0x89, 0x17, 0xE0, 0xFC,
+0xA3, 0xE0, 0xFD, 0x90, 0x89, 0x15, 0xEC, 0x8D,
+0xF0, 0x12, 0x93, 0x67, 0xFC, 0xA3, 0xE0, 0xFD,
+0x90, 0x89, 0x15, 0xE0, 0xFA, 0xA3, 0xE0, 0xD3,
+0x9D, 0xEA, 0x9C, 0x40, 0x1D, 0xF1, 0x6B, 0xFD,
+0x90, 0x80, 0xFA, 0xE0, 0xFA, 0xA3, 0xE0, 0x24,
+0x01, 0xFB, 0xE4, 0x3A, 0xFA, 0xC3, 0xED, 0x9B,
+0xFD, 0xEC, 0x9A, 0x90, 0x89, 0x15, 0xF0, 0xA3,
+0xED, 0xF0, 0xEF, 0x30, 0xE7, 0x08, 0x91, 0xE6,
+0x90, 0x01, 0xC7, 0x74, 0x21, 0xF0, 0xEF, 0x30,
+0xE6, 0x08, 0x91, 0xE6, 0x90, 0x01, 0xC7, 0x74,
+0x22, 0xF0, 0xEF, 0x30, 0xE5, 0x08, 0x91, 0xE6,
+0x90, 0x01, 0xC7, 0x74, 0x23, 0xF0, 0x90, 0x89,
+0x1C, 0xE0, 0x24, 0xF8, 0x60, 0x2A, 0x24, 0x80,
+0x60, 0x26, 0x24, 0xC8, 0x60, 0x06, 0x24, 0x20,
+0x60, 0x02, 0x81, 0x75, 0x90, 0x81, 0xE6, 0xE0,
+0xFF, 0xF1, 0xD8, 0x20, 0xE0, 0x02, 0x81, 0x75,
+0xF1, 0xE9, 0x70, 0x02, 0x81, 0x75, 0x90, 0x89,
+0x1C, 0xE0, 0xFF, 0x12, 0x93, 0xDB, 0x81, 0x75,
+0xF1, 0xDF, 0x30, 0xE0, 0x5B, 0x90, 0x89, 0x20,
+0xE0, 0xFF, 0x90, 0x89, 0x19, 0xE0, 0x2F, 0xFF,
+0xE4, 0x33, 0xCF, 0x24, 0x08, 0xCF, 0x34, 0x00,
+0x90, 0x89, 0x24, 0xF0, 0xA3, 0xEF, 0xF0, 0x24,
+0x00, 0xF1, 0xA2, 0x64, 0x45, 0x70, 0x39, 0x91,
+0xFC, 0x12, 0x96, 0xD8, 0xEF, 0x64, 0x01, 0x70,
+0x2F, 0x91, 0xFC, 0x12, 0x96, 0xFC, 0xEF, 0x64,
+0x01, 0x70, 0x25, 0x90, 0x89, 0x28, 0x04, 0xF0,
+0x91, 0xFC, 0x90, 0x89, 0x21, 0xE0, 0xFD, 0x12,
+0x8F, 0x5C, 0x90, 0x89, 0x21, 0xE0, 0xFD, 0x90,
+0xFD, 0x11, 0xF0, 0x91, 0xFC, 0x12, 0x8F, 0x10,
+0x90, 0x89, 0x21, 0xE0, 0x90, 0xFD, 0x11, 0xF0,
+0xF1, 0xE9, 0x60, 0x37, 0x91, 0xEE, 0x90, 0x89,
+0x1F, 0xE0, 0xFB, 0x90, 0x89, 0x21, 0xE0, 0x90,
+0x89, 0x2D, 0xF0, 0xD1, 0x53, 0xEF, 0x60, 0x06,
+0x90, 0x89, 0x28, 0x74, 0x01, 0xF0, 0x90, 0x81,
+0xE4, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0,
+0x12, 0x91, 0xEE, 0x90, 0x89, 0x1F, 0xE0, 0xFB,
+0xB1, 0x05, 0xEF, 0x60, 0x06, 0x90, 0x89, 0x28,
+0x74, 0x01, 0xF0, 0x90, 0x81, 0xE3, 0xE0, 0xC3,
+0x13, 0x30, 0xE0, 0x0E, 0x91, 0xEE, 0x12, 0x60,
+0x2B, 0xEF, 0x60, 0x06, 0x90, 0x89, 0x28, 0x74,
+0x01, 0xF0, 0x90, 0x81, 0xE3, 0xE0, 0x13, 0x13,
+0x54, 0x3F, 0x30, 0xE0, 0x18, 0x90, 0x89, 0x19,
+0xE0, 0xFF, 0x7E, 0x00, 0x90, 0x89, 0x20, 0xE0,
+0xFD, 0x12, 0x61, 0xAE, 0xEF, 0x60, 0x06, 0x90,
+0x89, 0x28, 0x74, 0x01, 0xF0, 0x90, 0x81, 0xE3,
+0xF1, 0xD7, 0x30, 0xE0, 0x15, 0x90, 0x89, 0x28,
+0xE0, 0x70, 0x0F, 0x91, 0xEE, 0xF1, 0xBC, 0xEF,
+0x60, 0x08, 0x91, 0xE6, 0x90, 0x01, 0xC7, 0x74,
+0x22, 0xF0, 0x91, 0xEE, 0xB1, 0xA3, 0xEF, 0x60,
+0x0C, 0x90, 0x81, 0xEE, 0xE0, 0x54, 0xFE, 0xF0,
+0x90, 0x01, 0xC7, 0xE4, 0xF0, 0x90, 0x81, 0xEE,
+0xE0, 0x30, 0xE0, 0x1A, 0x90, 0x80, 0x07, 0xE0,
+0xB4, 0x01, 0x0E, 0x90, 0xFD, 0x01, 0xE0, 0x20,
+0xE6, 0x07, 0x90, 0xFD, 0x00, 0xE0, 0x44, 0x10,
+0xF0, 0x7F, 0x01, 0x12, 0x70, 0x9D, 0x12, 0x93,
+0xC4, 0xEF, 0x64, 0x01, 0x70, 0x42, 0x12, 0x93,
+0xAE, 0x90, 0x89, 0x27, 0xEF, 0xF0, 0x64, 0x01,
+0x60, 0x23, 0x91, 0xE6, 0x90, 0x89, 0x27, 0xE0,
+0xFF, 0xB4, 0x02, 0x08, 0x90, 0x01, 0xC7, 0x74,
+0x42, 0xF0, 0x80, 0x0A, 0xEF, 0xB4, 0x04, 0x06,
+0x90, 0x01, 0xC7, 0x74, 0x43, 0xF0, 0x7F, 0x01,
+0x12, 0x70, 0x9D, 0x80, 0x13, 0x90, 0x89, 0x15,
+0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x92, 0x6F,
+0x90, 0x89, 0x1D, 0xE0, 0x04, 0xF0, 0x21, 0xC8,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF0, 0x90, 0x81,
+0xEE, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90, 0x89,
+0x1A, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x89,
+0x20, 0xE0, 0xFD, 0x22, 0x90, 0x89, 0x24, 0xE0,
+0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0xF1, 0xAB, 0xE4,
+0x90, 0x89, 0x2D, 0xF0, 0xA3, 0xF1, 0x91, 0x70,
+0x41, 0xD1, 0x4A, 0xA3, 0xE0, 0xD1, 0xCF, 0x64,
+0x88, 0x70, 0x37, 0xD1, 0x4A, 0xF1, 0x7D, 0x64,
+0x8E, 0x70, 0x2F, 0x90, 0x89, 0x2D, 0xD1, 0x48,
+0xD1, 0xC4, 0x04, 0xFD, 0xB1, 0x7A, 0xEF, 0x70,
+0x21, 0xD1, 0x4A, 0xD1, 0xC4, 0x24, 0x04, 0xFD,
+0xB1, 0x7A, 0xEF, 0x64, 0x01, 0x70, 0x13, 0xD1,
+0x4A, 0xD1, 0xC4, 0x24, 0x08, 0xFD, 0xB1, 0x7A,
+0xBF, 0x01, 0x07, 0x90, 0x01, 0xC7, 0x74, 0x0B,
+0x91, 0xE5, 0x90, 0x89, 0x2D, 0xE0, 0xFF, 0x22,
+0x90, 0x89, 0x2B, 0xE0, 0xFD, 0x90, 0x89, 0x2A,
+0xE0, 0x2D, 0xFD, 0x90, 0x89, 0x29, 0xE0, 0x34,
+0x00, 0xCD, 0x24, 0x10, 0xCD, 0x34, 0x00, 0xFC,
+0x7E, 0x00, 0xED, 0x2F, 0xFF, 0xEE, 0x3C, 0xFE,
+0xE4, 0xFD, 0xAB, 0x07, 0xAA, 0x06, 0xED, 0x2B,
+0xFB, 0xE4, 0x3A, 0xFA, 0xC3, 0x90, 0x80, 0xFB,
+0xE0, 0x9B, 0x90, 0x80, 0xFA, 0xE0, 0x9A, 0x50,
+0x0B, 0xA3, 0x12, 0x93, 0x92, 0xC3, 0xEB, 0x9F,
+0xFB, 0xEA, 0x9E, 0xFA, 0x12, 0x93, 0x7F, 0xF1,
+0x9F, 0xFF, 0x22, 0x90, 0x89, 0x2B, 0xED, 0xF1,
+0xB2, 0xF1, 0xF2, 0xEF, 0x70, 0x02, 0xC1, 0x45,
+0xD1, 0x4A, 0xF1, 0xD0, 0x70, 0x02, 0xC1, 0x45,
+0x12, 0x61, 0x9C, 0xCF, 0x24, 0x08, 0xCF, 0x34,
+0x00, 0x90, 0x89, 0x2E, 0xF0, 0xA3, 0xEF, 0xF0,
+0x90, 0x81, 0xE4, 0xE0, 0xC4, 0x54, 0x0F, 0x30,
+0xE0, 0x2F, 0xD1, 0xBB, 0x7D, 0x09, 0xB1, 0x7A,
+0xEF, 0x64, 0x06, 0x70, 0x24, 0xD1, 0xBB, 0x7D,
+0x14, 0xB1, 0x7A, 0xEF, 0x70, 0x1B, 0xD1, 0xBB,
+0x7D, 0x15, 0xB1, 0x7A, 0xEF, 0x64, 0x50, 0x70,
+0x10, 0xD1, 0xBB, 0x7D, 0x21, 0xB1, 0x7A, 0xEF,
+0x20, 0xE0, 0x03, 0x30, 0xE2, 0x03, 0x7F, 0x01,
+0x22, 0x90, 0x81, 0xE4, 0xE0, 0x13, 0x13, 0x54,
+0x3F, 0x30, 0xE0, 0x39, 0xD1, 0xBB, 0x7D, 0x09,
+0xB1, 0x7A, 0xEF, 0x64, 0x11, 0x70, 0x2E, 0x90,
+0x89, 0x2F, 0xE0, 0x24, 0x14, 0xFF, 0x90, 0x89,
+0x2E, 0xE0, 0x34, 0x00, 0xFE, 0x90, 0x89, 0x2C,
+0xF0, 0xA3, 0xEF, 0xF0, 0x7D, 0x02, 0xB1, 0x7A,
+0xEF, 0x70, 0x12, 0x90, 0x89, 0x2C, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0x7D, 0x03, 0xB1, 0x7A, 0xBF,
+0x89, 0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22,
+0x04, 0xF0, 0x90, 0x89, 0x29, 0xE0, 0xFE, 0xA3,
+0xE0, 0xFF, 0x22, 0xF1, 0xAB, 0xE4, 0x90, 0x89,
+0x2E, 0xF0, 0x90, 0x89, 0x2D, 0xF1, 0x91, 0x70,
+0x54, 0xD1, 0x4A, 0xA3, 0xE0, 0xD1, 0xCF, 0x64,
+0x88, 0x70, 0x4A, 0xD1, 0x4A, 0xF1, 0x7D, 0x64,
+0x8E, 0x70, 0x42, 0x90, 0x89, 0x2E, 0xD1, 0x48,
+0xD1, 0xC4, 0x04, 0xFD, 0xB1, 0x7A, 0xEF, 0x64,
+0x03, 0x70, 0x32, 0xD1, 0x4A, 0xD1, 0xC4, 0xD1,
+0xCF, 0x30, 0xE3, 0x07, 0x90, 0x01, 0xC7, 0x74,
+0x01, 0x80, 0x20, 0x90, 0x81, 0xE3, 0x12, 0x4F,
+0xF3, 0x30, 0xE0, 0x0A, 0xD1, 0x4A, 0xA3, 0xE0,
+0xFD, 0x12, 0x70, 0xF3, 0x80, 0x0F, 0x90, 0x81,
+0xE6, 0xF1, 0xE2, 0x30, 0xE0, 0x07, 0x90, 0x01,
+0xC7, 0x74, 0x02, 0x91, 0xE5, 0x90, 0x89, 0x2E,
+0xE0, 0xFF, 0x22, 0x90, 0x89, 0x2E, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0x22, 0x90, 0x89, 0x2C, 0xE0,
+0xFD, 0x90, 0x89, 0x2B, 0xE0, 0x2D, 0x22, 0x24,
+0x06, 0xFD, 0xB1, 0x7A, 0xEF, 0x22, 0xFF, 0x90,
+0x89, 0x32, 0xE0, 0x34, 0x00, 0xFE, 0xE4, 0xFD,
+0xA1, 0x7A, 0x90, 0x89, 0x30, 0x12, 0x94, 0xCB,
+0x78, 0x34, 0x7C, 0x89, 0x7D, 0x01, 0x7B, 0xFF,
+0x7A, 0x40, 0x79, 0xFA, 0x12, 0x97, 0xE0, 0x90,
+0x89, 0x32, 0xE0, 0xFF, 0x90, 0x89, 0x31, 0xE0,
+0x2F, 0xFF, 0x90, 0x89, 0x30, 0xE0, 0x34, 0x00,
+0xFE, 0x90, 0x89, 0x38, 0xF0, 0xA3, 0xEF, 0xF0,
+0x24, 0x06, 0xFF, 0xE4, 0x3E, 0xD1, 0xDD, 0xEF,
+0x64, 0x08, 0x70, 0x4E, 0x90, 0x89, 0x39, 0xE0,
+0x24, 0x07, 0xFF, 0x90, 0x89, 0x38, 0xD1, 0xDA,
+0xEF, 0x70, 0x3F, 0x90, 0x89, 0x33, 0xF0, 0x90,
+0x89, 0x33, 0xE0, 0xFF, 0xC3, 0x94, 0x04, 0x50,
+0x21, 0x90, 0x89, 0x39, 0xE0, 0x24, 0x18, 0xFD,
+0x90, 0x89, 0x38, 0xE0, 0xB1, 0x6D, 0x90, 0x89,
+0x33, 0xE0, 0x24, 0x34, 0xF5, 0x82, 0xE4, 0x34,
+0x89, 0xF5, 0x83, 0x12, 0x72, 0x59, 0x04, 0xF0,
+0x80, 0xD5, 0x78, 0x34, 0x7C, 0x89, 0x12, 0x67,
+0xF0, 0x12, 0x96, 0xF3, 0x7F, 0x00, 0x70, 0x02,
+0x7F, 0x01, 0x22, 0x90, 0x89, 0x15, 0xE0, 0xFC,
+0xA3, 0xE0, 0x22, 0x90, 0x89, 0x22, 0xE0, 0xFE,
+0xA3, 0xE0, 0x78, 0x03, 0x22, 0xA3, 0xE0, 0x24,
+0x07, 0xFD, 0xB1, 0x7A, 0xEF, 0x22, 0x24, 0x63,
+0xFF, 0xEE, 0x34, 0x01, 0xFE, 0xEF, 0x78, 0x07,
+0x22, 0xF0, 0xFD, 0xB1, 0x7A, 0xEF, 0x54, 0x0C,
+0x64, 0x08, 0x22, 0xF5, 0x83, 0xE0, 0xFE, 0x74,
+0x00, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5,
+0x83, 0xE0, 0x22, 0x90, 0x89, 0x2B, 0xED, 0xF0,
+0xA3, 0xEB, 0xF0, 0x90, 0x89, 0x29, 0xEE, 0xF0,
+0xA3, 0xEF, 0xF0, 0x22, 0x90, 0x89, 0x2B, 0xED,
+0xF1, 0xB2, 0xF1, 0xF2, 0xEF, 0x60, 0x08, 0xD1,
+0x4A, 0xF1, 0xD0, 0x60, 0x02, 0x7F, 0x01, 0x22,
+0xA3, 0xE0, 0xFD, 0xD1, 0xE2, 0xEF, 0x22, 0xE0,
+0xC4, 0x13, 0x13, 0x13, 0x54, 0x01, 0x22, 0x90,
+0x81, 0xE3, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x03,
+0x22, 0x90, 0x89, 0x19, 0xE0, 0xFF, 0xF1, 0xF2,
+0xEF, 0x22, 0xE4, 0xFE, 0xEF, 0x2E, 0x12, 0x98,
+0x65, 0xF5, 0x83, 0xE0, 0xFD, 0x74, 0x30, 0x2E,
+0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xED,
+0xF0, 0x0E, 0xEE, 0xB4, 0x06, 0xE6, 0x78, 0xEF,
+0x7C, 0x81, 0x7D, 0x01, 0x7B, 0x01, 0x7A, 0x89,
+0x79, 0x30, 0x11, 0x24, 0xEF, 0x7F, 0x00, 0x70,
+0x02, 0x7F, 0x01, 0x22, 0x7E, 0x00, 0x7F, 0x06,
+0x02, 0x46, 0x27, 0x12, 0x5F, 0xB3, 0xA3, 0xED,
+0xF0, 0x78, 0x32, 0x7C, 0x89, 0x7D, 0x01, 0x7B,
+0xFF, 0x7A, 0x40, 0x79, 0xC0, 0xF1, 0xDB, 0x78,
+0x38, 0x7C, 0x89, 0x7D, 0x01, 0x7B, 0xFF, 0x7A,
+0x40, 0x79, 0xC6, 0x12, 0x97, 0xE0, 0x78, 0x3C,
+0x7C, 0x89, 0x7D, 0x01, 0x7B, 0xFF, 0x7A, 0x40,
+0x79, 0xCA, 0x12, 0x97, 0xE0, 0xE4, 0x90, 0x89,
+0x41, 0xF0, 0x31, 0x9C, 0xCF, 0x24, 0x06, 0xCF,
+0x12, 0x5E, 0xDB, 0xEF, 0x64, 0x08, 0x60, 0x02,
+0x21, 0x8B, 0x31, 0x9C, 0xCF, 0x24, 0x07, 0xCF,
+0x12, 0x5E, 0xDB, 0xEF, 0x64, 0x06, 0x60, 0x02,
+0x21, 0x8B, 0x90, 0x89, 0x41, 0x04, 0xF0, 0xE4,
+0x90, 0x89, 0x40, 0xF0, 0x90, 0x89, 0x40, 0xE0,
+0xFF, 0xC3, 0x94, 0x06, 0x50, 0x1D, 0x90, 0x89,
+0x2A, 0xE0, 0x24, 0x0A, 0xFD, 0x90, 0x89, 0x29,
+0xE0, 0x12, 0x5D, 0x6D, 0x90, 0x89, 0x40, 0xE0,
+0x24, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0x31,
+0x91, 0x80, 0xD9, 0x78, 0x2C, 0x7C, 0x89, 0x7D,
+0x01, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0xF5, 0x11,
+0x24, 0xEF, 0x60, 0x02, 0x21, 0x8B, 0x90, 0x89,
+0x40, 0xF0, 0x90, 0x89, 0x40, 0xE0, 0xFF, 0xC3,
+0x94, 0x04, 0x50, 0x19, 0x71, 0x94, 0x31, 0xA7,
+0xCD, 0x24, 0x20, 0x12, 0x5D, 0x6C, 0x90, 0x89,
+0x40, 0xE0, 0x24, 0x3C, 0xF5, 0x82, 0xE4, 0x34,
+0x89, 0x31, 0x91, 0x80, 0xDD, 0x78, 0x3C, 0x7C,
+0x89, 0xF1, 0xF0, 0x12, 0x96, 0xF3, 0x60, 0x02,
+0x21, 0x82, 0x90, 0x06, 0x30, 0xE0, 0x44, 0x01,
+0x54, 0xDF, 0xF0, 0x90, 0x81, 0xE5, 0xE0, 0x30,
+0xE0, 0x02, 0x80, 0x10, 0x90, 0x84, 0x7C, 0xE0,
+0xB4, 0x02, 0x13, 0x90, 0x81, 0xE4, 0x12, 0x4F,
+0xF3, 0x20, 0xE0, 0x0A, 0x90, 0x01, 0xC7, 0x74,
+0x09, 0x12, 0x5C, 0xE5, 0x80, 0x65, 0xE4, 0x90,
+0x89, 0x40, 0xF0, 0x90, 0x89, 0x40, 0xE0, 0xFF,
+0xC3, 0x94, 0x06, 0x50, 0x12, 0x12, 0x5D, 0x58,
+0x90, 0x89, 0x40, 0xE0, 0x24, 0x32, 0xF5, 0x82,
+0xE4, 0x34, 0x89, 0x31, 0x91, 0x80, 0xE4, 0xE4,
+0x90, 0x89, 0x40, 0xF0, 0x90, 0x89, 0x40, 0xE0,
+0xFF, 0xC3, 0x94, 0x04, 0x50, 0x19, 0x71, 0x94,
+0x31, 0xA7, 0xCD, 0x24, 0x16, 0x12, 0x5D, 0x6C,
+0x90, 0x89, 0x40, 0xE0, 0x24, 0x38, 0xF5, 0x82,
+0xE4, 0x34, 0x89, 0x31, 0x91, 0x80, 0xDD, 0x7B,
+0x01, 0x7A, 0x89, 0x79, 0x32, 0x12, 0x97, 0xE7,
+0xA3, 0xF0, 0x7A, 0x89, 0x79, 0x38, 0xB1, 0x30,
+0x80, 0x09, 0x90, 0x06, 0x30, 0xE0, 0x44, 0x21,
+0x54, 0xEF, 0xF0, 0x90, 0x89, 0x41, 0xE0, 0xFF,
+0x22, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x89, 0x40,
+0xE0, 0x04, 0xF0, 0x22, 0x90, 0x89, 0x2B, 0xE0,
+0xFF, 0x90, 0x89, 0x2A, 0xE0, 0x2F, 0xFF, 0x90,
+0x89, 0x29, 0xE0, 0x34, 0x00, 0x22, 0x12, 0x5F,
+0xB3, 0xA3, 0xED, 0xF0, 0x78, 0x2C, 0x7C, 0x89,
+0x7D, 0x01, 0x7B, 0xFF, 0x7A, 0x40, 0x79, 0xD4,
+0xF1, 0xDB, 0x78, 0x32, 0x7C, 0x89, 0x7D, 0x01,
+0x7B, 0xFF, 0x7A, 0x40, 0x79, 0xDA, 0x12, 0x98,
+0x7D, 0x78, 0x42, 0x7C, 0x89, 0x7D, 0x01, 0x7B,
+0xFF, 0x7A, 0x40, 0x79, 0xEA, 0x12, 0x98, 0x7D,
+0xE4, 0x90, 0x89, 0x55, 0x12, 0x5E, 0x49, 0xA3,
+0xE0, 0xFD, 0x12, 0x94, 0x97, 0xEF, 0x64, 0x01,
+0x60, 0x02, 0x61, 0x8E, 0x31, 0x9C, 0xCF, 0x24,
+0x0E, 0xCF, 0x12, 0x5E, 0xDB, 0xEF, 0x64, 0x3A,
+0x60, 0x02, 0x61, 0x8E, 0x31, 0x9C, 0xCF, 0x24,
+0x30, 0xCF, 0x12, 0x5E, 0xDB, 0xEF, 0x64, 0x87,
+0x60, 0x02, 0x61, 0x8E, 0x90, 0x89, 0x55, 0x04,
+0xF0, 0xE4, 0x90, 0x89, 0x52, 0xF0, 0xF1, 0xE9,
+0x94, 0x10, 0x50, 0x1A, 0x71, 0x94, 0x31, 0xA7,
+0xCD, 0x24, 0x38, 0x12, 0x5D, 0x6C, 0x90, 0x89,
+0x52, 0xE0, 0x24, 0x42, 0xF5, 0x82, 0xE4, 0x34,
+0x89, 0x12, 0x97, 0x8E, 0x80, 0xE0, 0xE4, 0x90,
+0x89, 0x53, 0xF0, 0x90, 0x89, 0x53, 0xE0, 0xFF,
+0xC3, 0x94, 0x02, 0x40, 0x02, 0x61, 0x8E, 0x75,
+0xF0, 0x38, 0xEF, 0x12, 0x98, 0x75, 0x20, 0xE0,
+0x02, 0x61, 0x8E, 0xE4, 0x90, 0x89, 0x54, 0xF0,
+0x90, 0x89, 0x53, 0xE0, 0xFF, 0x75, 0xF0, 0x38,
+0x90, 0x82, 0x1F, 0x12, 0x44, 0x5D, 0xE0, 0xFE,
+0x90, 0x89, 0x54, 0xE0, 0xC3, 0x9E, 0x40, 0x02,
+0x61, 0x86, 0xEF, 0x75, 0xF0, 0x38, 0xA4, 0x24,
+0x36, 0xF9, 0x74, 0x82, 0x35, 0xF0, 0xFA, 0x7B,
+0x01, 0xE0, 0x75, 0xF0, 0x10, 0xA4, 0x29, 0xF9,
+0xEA, 0x35, 0xF0, 0xFA, 0x78, 0x42, 0x7C, 0x89,
+0x12, 0x98, 0x2C, 0x60, 0x02, 0x61, 0x77, 0x90,
+0x06, 0x33, 0xE0, 0x44, 0x01, 0x54, 0xFB, 0xF0,
+0xE4, 0x90, 0x89, 0x52, 0xF0, 0xF1, 0xE9, 0x94,
+0x06, 0x50, 0x1A, 0x71, 0x94, 0x31, 0xA7, 0xCD,
+0x24, 0x4A, 0x12, 0x5D, 0x6C, 0x90, 0x89, 0x52,
+0xE0, 0x24, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x89,
+0x12, 0x97, 0x8E, 0x80, 0xE0, 0xE4, 0x90, 0x89,
+0x52, 0xF0, 0xF1, 0xE9, 0x94, 0x10, 0x50, 0x13,
+0x12, 0x5D, 0x58, 0x90, 0x89, 0x52, 0xE0, 0x24,
+0x32, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0x12, 0x97,
+0x8E, 0x80, 0xE7, 0x90, 0x89, 0x53, 0xE0, 0xFF,
+0x75, 0xF0, 0x38, 0x12, 0x98, 0x75, 0xFE, 0xC3,
+0x13, 0x30, 0xE0, 0x29, 0xEF, 0x75, 0xF0, 0x38,
+0xA4, 0x24, 0x26, 0xF9, 0x74, 0x82, 0x35, 0xF0,
+0xFA, 0x7B, 0x01, 0x78, 0x32, 0x7C, 0x89, 0x12,
+0x98, 0x2C, 0x70, 0x6A, 0x90, 0x84, 0x7C, 0xE0,
+0xB4, 0x02, 0x08, 0x12, 0x6E, 0x6E, 0x20, 0xE0,
+0x1B, 0x80, 0x0F, 0x80, 0x17, 0x90, 0x84, 0x7C,
+0xE0, 0xB4, 0x02, 0x10, 0x12, 0x6E, 0x6E, 0x20,
+0xE0, 0x0A, 0x90, 0x01, 0xC7, 0x74, 0x0A, 0x12,
+0x5C, 0xE5, 0x80, 0x52, 0x7B, 0x01, 0x7A, 0x89,
+0x79, 0x2C, 0x90, 0x89, 0x59, 0x12, 0x44, 0x72,
+0x7A, 0x89, 0x79, 0x42, 0x90, 0x89, 0x5C, 0x12,
+0x44, 0x72, 0x90, 0x89, 0x53, 0xE0, 0x75, 0xF0,
+0x38, 0xA4, 0x24, 0x20, 0xF9, 0x74, 0x82, 0x35,
+0xF0, 0xFA, 0x90, 0x89, 0x5F, 0x12, 0x44, 0x72,
+0xE4, 0x90, 0x89, 0x62, 0xF0, 0xA3, 0xF0, 0x7A,
+0x89, 0x79, 0x32, 0x71, 0xA0, 0x80, 0x07, 0x90,
+0x06, 0x33, 0xE0, 0x44, 0x05, 0xF0, 0x90, 0x89,
+0x54, 0xE0, 0x04, 0xF0, 0x41, 0x60, 0x90, 0x89,
+0x53, 0xE0, 0x04, 0xF0, 0x41, 0x43, 0x90, 0x89,
+0x55, 0xE0, 0xFF, 0x22, 0x90, 0x89, 0x2B, 0xE0,
+0xFD, 0x90, 0x89, 0x2A, 0xE0, 0x2D, 0xFD, 0x22,
+0x90, 0x89, 0x56, 0x12, 0x44, 0x72, 0x90, 0x05,
+0x22, 0xE0, 0x90, 0x89, 0x67, 0xF0, 0x90, 0x04,
+0x1D, 0xE0, 0x60, 0x0B, 0x7B, 0x39, 0xD1, 0x89,
+0xEF, 0x64, 0x01, 0x70, 0x1C, 0x80, 0x00, 0x90,
+0x84, 0x80, 0xE0, 0xFF, 0x90, 0x8A, 0x4A, 0x74,
+0x11, 0xF0, 0x7B, 0x18, 0x7D, 0x01, 0x12, 0x82,
+0xD7, 0x90, 0x89, 0x64, 0xEE, 0xF0, 0xA3, 0xEF,
+0xF0, 0x90, 0x89, 0x64, 0x12, 0x86, 0x48, 0x90,
+0x89, 0x66, 0xEF, 0xF0, 0x90, 0x89, 0x64, 0x12,
+0x87, 0xD0, 0x90, 0x89, 0x62, 0xE0, 0xFD, 0x12,
+0x56, 0x9B, 0x90, 0x89, 0x63, 0xE0, 0x60, 0x02,
+0x81, 0x82, 0xD1, 0xF5, 0xC0, 0x03, 0xC0, 0x02,
+0xC0, 0x01, 0x90, 0x89, 0x59, 0xD1, 0x5D, 0x75,
+0x16, 0x06, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03,
+0xB1, 0x23, 0x12, 0x97, 0xC6, 0xC0, 0x03, 0xC0,
+0x02, 0xC0, 0x01, 0x90, 0x89, 0x56, 0xD1, 0x5D,
+0x75, 0x16, 0x10, 0xD0, 0x01, 0xD0, 0x02, 0xD0,
+0x03, 0xB1, 0x23, 0xD1, 0xF8, 0xC0, 0x03, 0xC0,
+0x02, 0xC0, 0x01, 0x90, 0x89, 0x5C, 0xD1, 0x5D,
+0x75, 0x16, 0x10, 0xD0, 0x01, 0xD0, 0x02, 0xD0,
+0x03, 0xB1, 0x23, 0x24, 0x58, 0xF9, 0xE4, 0x34,
+0xFC, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02,
+0xC0, 0x01, 0x90, 0x89, 0x5C, 0xD1, 0x5D, 0x75,
+0x16, 0x10, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03,
+0xB1, 0x23, 0x24, 0x6A, 0xF9, 0xE4, 0x34, 0xFC,
+0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0,
+0x01, 0x90, 0x89, 0x5F, 0xD1, 0x5D, 0x75, 0x16,
+0x06, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12,
+0x2B, 0xED, 0x90, 0x89, 0x5C, 0x12, 0x44, 0x69,
+0x90, 0x89, 0x93, 0x12, 0x44, 0x72, 0x90, 0x89,
+0x96, 0x12, 0x20, 0xDA, 0x00, 0x00, 0x00, 0x20,
+0x90, 0x89, 0x9A, 0x74, 0x3A, 0xF0, 0x90, 0x89,
+0x56, 0x12, 0x44, 0x69, 0x12, 0x94, 0xD4, 0xB1,
+0x26, 0x24, 0x28, 0xF9, 0xE4, 0x34, 0xFC, 0xF1,
+0xD3, 0x75, 0x16, 0x28, 0x7B, 0x01, 0x7A, 0x89,
+0x79, 0x68, 0xB1, 0x23, 0x12, 0x98, 0x42, 0xC0,
+0x03, 0x8B, 0x13, 0x75, 0x14, 0x82, 0x75, 0x15,
+0x8E, 0x75, 0x16, 0x28, 0xD0, 0x03, 0x12, 0x2B,
+0xED, 0x90, 0x89, 0x66, 0xE0, 0xFF, 0x90, 0x89,
+0x65, 0xE0, 0x2F, 0xFF, 0x90, 0x89, 0x64, 0xE0,
+0x34, 0x00, 0xCF, 0x24, 0x28, 0xFD, 0xE4, 0x3F,
+0xFC, 0x90, 0x84, 0x80, 0xE0, 0xFB, 0x7F, 0x3A,
+0x12, 0x75, 0x52, 0xB1, 0x26, 0x12, 0x98, 0x42,
+0xC0, 0x03, 0x8B, 0x13, 0x75, 0x14, 0x89, 0x75,
+0x15, 0x68, 0x75, 0x16, 0x28, 0xD0, 0x03, 0x12,
+0x2B, 0xED, 0x90, 0x06, 0x33, 0xE0, 0x44, 0x02,
+0xF0, 0x90, 0x89, 0x67, 0xE0, 0xFD, 0x7B, 0x3A,
+0xE4, 0xFF, 0xD1, 0x73, 0x90, 0x04, 0x1F, 0x74,
+0x20, 0xF0, 0x22, 0x12, 0x2B, 0xED, 0x90, 0x89,
+0x64, 0xA3, 0xE0, 0xFF, 0xA3, 0xE0, 0x2F, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
+0x84, 0xA1, 0x12, 0x44, 0x72, 0x78, 0xAD, 0x7C,
+0x84, 0x7D, 0x01, 0x7B, 0xFF, 0x7A, 0x40, 0x79,
+0xCE, 0xF1, 0xDB, 0x90, 0x05, 0x22, 0xE0, 0x90,
+0x84, 0xAC, 0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60,
+0x0B, 0x7B, 0x33, 0xD1, 0x89, 0xEF, 0x64, 0x01,
+0x70, 0x1C, 0x80, 0x00, 0x90, 0x84, 0x7F, 0xE0,
+0xFF, 0x90, 0x8A, 0x4A, 0x74, 0x10, 0xF0, 0x7B,
+0x18, 0x7D, 0x01, 0x12, 0x82, 0xD7, 0x90, 0x84,
+0xA9, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x84,
+0xA9, 0x12, 0x86, 0x48, 0x90, 0x84, 0xAB, 0xEF,
+0xF0, 0x90, 0x84, 0xA9, 0x12, 0x87, 0xD0, 0x90,
+0x84, 0xA7, 0xE0, 0xFD, 0x12, 0x56, 0x9B, 0x90,
+0x84, 0xA8, 0xE0, 0x70, 0x56, 0xD1, 0xF5, 0xC0,
+0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x84, 0xA4,
+0xD1, 0x5D, 0x75, 0x16, 0x06, 0xD0, 0x01, 0xD0,
+0x02, 0xD0, 0x03, 0x12, 0x2B, 0xED, 0x90, 0x84,
+0xA9, 0xB1, 0x29, 0xF1, 0xE2, 0xFA, 0x7B, 0x01,
+0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x84,
+0xA4, 0xD1, 0x5D, 0x75, 0x16, 0x06, 0xD0, 0x01,
+0xD0, 0x02, 0xD0, 0x03, 0x12, 0x2B, 0xED, 0x90,
+0x84, 0xA9, 0xB1, 0x29, 0x12, 0x97, 0xC6, 0xC0,
+0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x84, 0xA1,
+0xD1, 0x5D, 0x75, 0x16, 0x04, 0xD0, 0x01, 0xD0,
+0x02, 0x80, 0x4D, 0x90, 0x84, 0xA8, 0xE0, 0x64,
+0x01, 0x70, 0x4A, 0xD1, 0xF5, 0xC0, 0x03, 0x8B,
+0x13, 0x75, 0x14, 0x82, 0x75, 0x15, 0x0A, 0x75,
+0x16, 0x06, 0xD0, 0x03, 0x12, 0x2B, 0xED, 0x90,
+0x84, 0xA9, 0xB1, 0x29, 0xF1, 0xE2, 0xFA, 0x7B,
+0x01, 0xC0, 0x03, 0x8B, 0x13, 0x75, 0x14, 0x82,
+0x75, 0x15, 0x14, 0x75, 0x16, 0x06, 0xD0, 0x03,
+0x12, 0x2B, 0xED, 0x90, 0x84, 0xA9, 0xB1, 0x29,
+0x12, 0x97, 0xC6, 0xC0, 0x03, 0x8B, 0x13, 0x75,
+0x14, 0x82, 0x75, 0x15, 0x1A, 0x75, 0x16, 0x04,
+0xD0, 0x03, 0x12, 0x2B, 0xED, 0x90, 0x06, 0x30,
+0xE0, 0x44, 0x10, 0xF0, 0x90, 0x84, 0xAC, 0xE0,
+0xFD, 0x7B, 0x34, 0xB1, 0x18, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0x90, 0x89, 0xDA, 0x12, 0x44, 0x69,
+0x8B, 0x13, 0x8A, 0x14, 0x89, 0x15, 0x22, 0xE4,
+0xFD, 0x7F, 0x0C, 0x12, 0x4D, 0xFA, 0xE4, 0xFB,
+0xFD, 0x7F, 0xFF, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x05, 0x22, 0xED, 0xF0, 0x90,
+0x80, 0x05, 0xEB, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x7D, 0xFF, 0xE4, 0xFF, 0xD1, 0x73, 0xE4,
+0x90, 0x84, 0xFD, 0xF0, 0xA3, 0xF0, 0x90, 0x05,
+0x22, 0xE0, 0x90, 0x84, 0xFF, 0xF0, 0x7B, 0x47,
+0x7D, 0xFF, 0xE4, 0xFF, 0xD1, 0x73, 0x90, 0x05,
+0xF8, 0xE0, 0x70, 0x1A, 0xA3, 0xE0, 0x70, 0x16,
+0xA3, 0xE0, 0x70, 0x12, 0xA3, 0xE0, 0x70, 0x0E,
+0x90, 0x84, 0xFF, 0xE0, 0xFD, 0x7B, 0x48, 0xE4,
+0xFF, 0xD1, 0x73, 0x7F, 0x01, 0x22, 0xD3, 0x90,
+0x84, 0xFE, 0xE0, 0x94, 0xE8, 0x90, 0x84, 0xFD,
+0xE0, 0x94, 0x03, 0x40, 0x15, 0x90, 0x01, 0xC0,
+0xE0, 0x44, 0x20, 0xF0, 0x90, 0x84, 0xFF, 0xE0,
+0xFD, 0x7B, 0x5B, 0xE4, 0xFF, 0xD1, 0x73, 0x7F,
+0x00, 0x22, 0x12, 0x87, 0x71, 0x90, 0x84, 0xFD,
+0x12, 0x78, 0xE3, 0x80, 0xB1, 0xA3, 0xA3, 0xE0,
+0x24, 0x30, 0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0x7B,
+0x01, 0x22, 0x7D, 0x08, 0xE4, 0xFF, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8A, 0x3E,
+0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x80, 0x03,
+0xE0, 0x04, 0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60,
+0x29, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x8A, 0x42,
+0xF0, 0x7B, 0x26, 0xD1, 0x89, 0xEF, 0x64, 0x01,
+0x70, 0x03, 0x12, 0x83, 0xA4, 0x90, 0x8A, 0x42,
+0xE0, 0xFD, 0x7B, 0x27, 0xE4, 0xFF, 0xD1, 0x73,
+0x90, 0x8A, 0x3E, 0xE0, 0xFF, 0x12, 0x91, 0x71,
+0x80, 0x0B, 0x90, 0x8A, 0x3E, 0xE0, 0xFF, 0x12,
+0x91, 0x71, 0x12, 0x83, 0xA4, 0xB1, 0x1C, 0x7F,
+0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x82,
+0xC3, 0x90, 0x8A, 0x53, 0xE4, 0xF0, 0xA3, 0xEF,
+0xF0, 0x90, 0x8A, 0x53, 0x12, 0x86, 0x48, 0x90,
+0x8A, 0x55, 0xEF, 0xF0, 0x90, 0x8A, 0x53, 0xA3,
+0xE0, 0x24, 0x30, 0xF9, 0xE4, 0x34, 0xFC, 0xF1,
+0xD3, 0x75, 0x16, 0x06, 0x7B, 0x01, 0x7A, 0x82,
+0x79, 0x0A, 0x12, 0x98, 0x56, 0xB1, 0x29, 0x24,
+0x36, 0xF9, 0xE4, 0x34, 0xFC, 0xF1, 0xD3, 0x75,
+0x16, 0x04, 0xF1, 0xF2, 0x12, 0x98, 0x56, 0xB1,
+0x29, 0xF1, 0xE2, 0xF1, 0xD3, 0x75, 0x16, 0x06,
+0x7B, 0x01, 0x7A, 0x82, 0x79, 0x14, 0x12, 0x98,
+0x56, 0xB1, 0x29, 0x24, 0x40, 0xF9, 0xE4, 0x34,
+0xFC, 0xF1, 0xD3, 0x75, 0x16, 0x04, 0x7B, 0x01,
+0x7A, 0x82, 0x79, 0x1A, 0x02, 0x2B, 0xED, 0x12,
+0x82, 0xC3, 0x7E, 0x00, 0x74, 0x00, 0x2F, 0xF9,
+0xE4, 0x34, 0xFC, 0x75, 0x13, 0x01, 0xF5, 0x14,
+0x89, 0x15, 0x22, 0x7E, 0x00, 0x7F, 0x06, 0x02,
+0x43, 0xD0, 0x24, 0x3A, 0xF9, 0xE4, 0x34, 0xFC,
+0x22, 0x90, 0x89, 0x52, 0xE0, 0xFF, 0xC3, 0x22,
+0x7D, 0x01, 0x7B, 0x01, 0x7A, 0x82, 0x79, 0x10,
+0x22, 0x75, 0xE8, 0x03, 0x75, 0xA8, 0x84, 0x22,
+0x90, 0x00, 0x80, 0xE0, 0x44, 0x80, 0xFD, 0x7F,
+0x80, 0x12, 0x32, 0x1E, 0x90, 0xFD, 0x00, 0xE0,
+0x54, 0xBF, 0xF0, 0x12, 0x8D, 0x24, 0x12, 0x32,
+0x77, 0xF1, 0xE4, 0x12, 0x8D, 0x58, 0x7F, 0x01,
+0x12, 0x47, 0x8C, 0x90, 0x84, 0x8E, 0x74, 0x02,
+0xF0, 0xFF, 0x12, 0x47, 0x8C, 0x90, 0x84, 0x8E,
+0xE0, 0x04, 0xF0, 0x12, 0x58, 0x42, 0x11, 0x5A,
+0x90, 0x01, 0xCC, 0x74, 0x0F, 0xF0, 0x90, 0x00,
+0x80, 0xE0, 0x44, 0x40, 0xFD, 0x7F, 0x80, 0x12,
+0x32, 0x1E, 0x75, 0x20, 0xFF, 0x12, 0x67, 0xF9,
+0xF1, 0xE5, 0x12, 0x8D, 0x5F, 0xE4, 0xFF, 0x02,
+0x48, 0x15, 0x31, 0xEA, 0x12, 0x8B, 0x79, 0x11,
+0x87, 0x12, 0x81, 0x92, 0x12, 0x7F, 0x92, 0x12,
+0x92, 0x55, 0x90, 0x84, 0x9B, 0xE0, 0x54, 0x7F,
+0xF0, 0x54, 0xBF, 0xF0, 0x54, 0xDF, 0xF0, 0x54,
+0xF0, 0xF0, 0xE4, 0x90, 0x84, 0x9D, 0xF0, 0x90,
+0x84, 0x9B, 0xE0, 0x54, 0xEF, 0xF0, 0x22, 0x7E,
+0x00, 0x7F, 0xD7, 0x7D, 0x00, 0x7B, 0x01, 0x7A,
+0x81, 0x79, 0x05, 0x12, 0x46, 0x4B, 0x90, 0x81,
+0x09, 0x74, 0x02, 0xF0, 0x90, 0x81, 0x10, 0x14,
+0xF0, 0xA3, 0xF0, 0xA3, 0x74, 0x10, 0xF0, 0x90,
+0x81, 0x16, 0xE4, 0xF0, 0xA3, 0x74, 0x02, 0x31,
+0xAD, 0x12, 0x91, 0x0F, 0xE4, 0xFD, 0xFF, 0x31,
+0x45, 0x7D, 0x0C, 0x7F, 0x02, 0x31, 0x45, 0x31,
+0x41, 0x90, 0x80, 0x07, 0xE0, 0xFF, 0xB4, 0x01,
+0x08, 0x90, 0x81, 0x15, 0x74, 0x99, 0xF0, 0x80,
+0x29, 0xEF, 0xB4, 0x03, 0x08, 0x90, 0x81, 0x15,
+0x74, 0x90, 0xF0, 0x80, 0x1D, 0x90, 0x81, 0x15,
+0x74, 0x40, 0xF0, 0x90, 0x00, 0x2C, 0xE0, 0x54,
+0x0F, 0xFF, 0xBF, 0x05, 0x08, 0x90, 0x81, 0x27,
+0x74, 0x02, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x81,
+0x27, 0xF0, 0x90, 0x81, 0xDC, 0x74, 0x03, 0xF0,
+0xA3, 0x74, 0x0F, 0xF0, 0xA3, 0xE0, 0x54, 0x01,
+0x44, 0x28, 0xF0, 0xA3, 0x74, 0x07, 0x31, 0xAD,
+0x7F, 0x01, 0x12, 0x91, 0x27, 0x90, 0x05, 0x58,
+0x74, 0x02, 0xF0, 0x7E, 0x00, 0xFF, 0x7D, 0x00,
+0x7B, 0x01, 0x7A, 0x81, 0x79, 0xE0, 0x12, 0x46,
+0x4B, 0xF1, 0xBB, 0x90, 0x06, 0x0A, 0xE0, 0x54,
+0xF8, 0xF0, 0x7B, 0x56, 0xE4, 0xFD, 0x7F, 0xFF,
+0x12, 0x66, 0x73, 0xE4, 0x90, 0x81, 0xE2, 0xF0,
+0x22, 0x7D, 0x0C, 0x7F, 0x01, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0xAC, 0x07, 0xEF, 0x14,
+0x60, 0x15, 0x14, 0x60, 0x19, 0x24, 0x02, 0x70,
+0x1A, 0xED, 0x54, 0x01, 0xFE, 0x90, 0x81, 0x05,
+0xE0, 0x54, 0xFE, 0x4E, 0xF0, 0x80, 0x0C, 0x90,
+0x81, 0x0D, 0xED, 0xF0, 0x80, 0x05, 0x90, 0x81,
+0x0C, 0xED, 0xF0, 0x90, 0x00, 0x8F, 0xE0, 0x30,
+0xE4, 0x2E, 0xEC, 0x14, 0x60, 0x07, 0x14, 0x60,
+0x1D, 0x24, 0x02, 0x70, 0x23, 0x90, 0x81, 0x05,
+0xE0, 0x54, 0x01, 0xC4, 0x33, 0x33, 0x33, 0x54,
+0x80, 0xFF, 0x90, 0x81, 0x0D, 0xE0, 0x54, 0x7F,
+0x4F, 0xFD, 0x7F, 0x88, 0x80, 0x07, 0x90, 0x81,
+0x0C, 0xE0, 0xFD, 0x7F, 0x89, 0x12, 0x32, 0x1E,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF0, 0x90, 0x81,
+0x27, 0xE0, 0x24, 0x05, 0x90, 0x81, 0x22, 0xF0,
+0xA3, 0x74, 0x10, 0xF0, 0x22, 0x71, 0x54, 0x70,
+0x28, 0x90, 0x81, 0x06, 0xE0, 0x54, 0xFD, 0xF0,
+0x7B, 0x2C, 0x12, 0x91, 0x08, 0x7D, 0x08, 0x7F,
+0x01, 0x12, 0x67, 0x06, 0xBF, 0x01, 0x0D, 0x90,
+0x81, 0x05, 0xE0, 0x44, 0x80, 0xF0, 0x7D, 0x0E,
+0x7F, 0x01, 0x21, 0x45, 0x12, 0x8A, 0x30, 0x04,
+0xF0, 0x22, 0xE4, 0xFD, 0xFF, 0x12, 0x98, 0x0B,
+0xED, 0x70, 0x12, 0x51, 0x29, 0xC0, 0x83, 0xC0,
+0x82, 0x51, 0x21, 0x80, 0x02, 0xC3, 0x33, 0xD8,
+0xFC, 0xF4, 0x5E, 0x80, 0x0F, 0x51, 0x29, 0xC0,
+0x83, 0xC0, 0x82, 0x51, 0x21, 0x80, 0x02, 0xC3,
+0x33, 0xD8, 0xFC, 0x4E, 0xD0, 0x82, 0xD0, 0x83,
+0xF0, 0x51, 0x34, 0x90, 0x81, 0x04, 0xEF, 0xF0,
+0x22, 0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x07, 0x08,
+0x22, 0x74, 0xFC, 0x2E, 0xF5, 0x82, 0xE4, 0x34,
+0x80, 0xF5, 0x83, 0x22, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x7D, 0x08, 0xED, 0x14, 0xF9,
+0x24, 0xFC, 0x51, 0x2C, 0xE0, 0x60, 0x3A, 0x7C,
+0x08, 0xEC, 0x14, 0x90, 0x8A, 0x5F, 0xF0, 0x74,
+0xFC, 0x29, 0x51, 0x2C, 0xE0, 0xFB, 0x7A, 0x00,
+0x90, 0x8A, 0x5F, 0x12, 0x97, 0x99, 0x80, 0x05,
+0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF,
+0xEE, 0x5A, 0xFE, 0xEF, 0x5B, 0x4E, 0x60, 0x0F,
+0xE9, 0x75, 0xF0, 0x08, 0xA4, 0xFF, 0x90, 0x8A,
+0x5F, 0xE0, 0x2F, 0x04, 0xFF, 0x80, 0x06, 0xDC,
+0xC8, 0xDD, 0xBA, 0x7F, 0x00, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0x12, 0x98, 0x0B, 0x51, 0x29, 0xE0,
+0xFD, 0x7C, 0x00, 0x12, 0x97, 0x9B, 0x80, 0x05,
+0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF,
+0xEE, 0x5C, 0xFE, 0xEF, 0x5D, 0x4E, 0x7F, 0x00,
+0x60, 0x02, 0x7F, 0x01, 0x22, 0x8B, 0x52, 0x8A,
+0x53, 0x89, 0x54, 0x12, 0x56, 0x95, 0xFF, 0xF5,
+0x56, 0x12, 0x1F, 0xA4, 0xFE, 0xC3, 0x13, 0x30,
+0xE0, 0x07, 0x12, 0x57, 0x75, 0xF5, 0x57, 0x80,
+0x02, 0x8F, 0x57, 0x85, 0x56, 0x55, 0xE5, 0x55,
+0xD3, 0x95, 0x57, 0x50, 0x23, 0xAB, 0x52, 0xAA,
+0x53, 0xA9, 0x54, 0x12, 0x1F, 0xA4, 0x54, 0x01,
+0xFD, 0xAF, 0x55, 0x31, 0xED, 0xAF, 0x55, 0x51,
+0x8A, 0xEF, 0xAF, 0x55, 0x70, 0x04, 0xF1, 0xDA,
+0x80, 0x02, 0xF1, 0xE3, 0x05, 0x55, 0x80, 0xD6,
+0xE5, 0x56, 0x70, 0x14, 0xFF, 0x51, 0x8A, 0xEF,
+0x70, 0x0E, 0x12, 0x80, 0x18, 0x71, 0x11, 0x12,
+0x8E, 0x94, 0x54, 0xBF, 0xF0, 0x54, 0x7F, 0xF0,
+0x22, 0xF1, 0xBB, 0x12, 0x66, 0x6E, 0x7D, 0x0C,
+0x7F, 0x01, 0x21, 0x45, 0xEF, 0x60, 0x34, 0x71,
+0x54, 0x70, 0x30, 0x90, 0x81, 0x06, 0xE0, 0x54,
+0xFE, 0xF0, 0x7B, 0x2B, 0x7D, 0x0F, 0x7F, 0xFF,
+0x12, 0x66, 0x73, 0x90, 0x06, 0x04, 0xE0, 0x54,
+0xBF, 0xF0, 0x12, 0x67, 0x02, 0xBF, 0x01, 0x0D,
+0x90, 0x81, 0x05, 0xE0, 0x44, 0x40, 0xF0, 0x7D,
+0x06, 0x7F, 0x01, 0x21, 0x45, 0x12, 0x8A, 0x30,
+0x74, 0x08, 0xF0, 0x22, 0xE4, 0xFF, 0x51, 0x8A,
+0xEF, 0x64, 0x01, 0x22, 0x71, 0x54, 0x70, 0x11,
+0x90, 0x81, 0x0A, 0xE0, 0x60, 0x0B, 0x90, 0x81,
+0x0E, 0xE0, 0x20, 0xE4, 0x04, 0xD1, 0x79, 0x91,
+0x2F, 0x22, 0x71, 0x54, 0x70, 0x1D, 0x90, 0x81,
+0x0A, 0xE0, 0x60, 0x17, 0x90, 0x81, 0x0E, 0xE0,
+0x20, 0xE4, 0x10, 0xD1, 0x79, 0xF0, 0x90, 0x81,
+0x05, 0xE0, 0x12, 0x98, 0x37, 0x54, 0x07, 0x70,
+0x02, 0xF1, 0x4D, 0x22, 0xE4, 0x90, 0x89, 0x07,
+0xF0, 0x90, 0x81, 0x0A, 0xE0, 0x60, 0x24, 0x71,
+0x54, 0x70, 0x20, 0xF1, 0xCB, 0xF0, 0x12, 0x97,
+0x3F, 0x90, 0x89, 0x07, 0x74, 0x01, 0xF0, 0xE4,
+0x90, 0x81, 0x11, 0xF0, 0x04, 0x60, 0x0C, 0x12,
+0x97, 0x67, 0xE0, 0x20, 0xE2, 0x03, 0x12, 0x4D,
+0xF6, 0x71, 0xF5, 0x22, 0xE4, 0xF5, 0x4E, 0x90,
+0x81, 0x0A, 0xE0, 0x60, 0x27, 0x71, 0x54, 0x70,
+0x23, 0x12, 0x97, 0x3F, 0xF1, 0xC3, 0x60, 0x09,
+0x90, 0x81, 0x06, 0x12, 0x5F, 0xE2, 0x20, 0xE0,
+0x03, 0x75, 0x4E, 0x01, 0xE5, 0x4E, 0x60, 0x0C,
+0x12, 0x97, 0x67, 0xE0, 0x20, 0xE2, 0x03, 0x12,
+0x4D, 0xF6, 0x71, 0xF5, 0x22, 0x90, 0x81, 0x0E,
+0xE0, 0x44, 0x10, 0xF0, 0x90, 0x81, 0x13, 0xE0,
+0x60, 0x04, 0x64, 0x01, 0x70, 0x11, 0xE4, 0xF5,
+0x1D, 0x90, 0x81, 0x13, 0xE0, 0x91, 0xAF, 0x91,
+0x37, 0x90, 0x81, 0x13, 0xE0, 0x80, 0x11, 0xE4,
+0xF5, 0x1D, 0x91, 0xA5, 0x91, 0x37, 0x90, 0x81,
+0x13, 0xE0, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xFE,
+0x91, 0xAF, 0x90, 0x81, 0x23, 0xF0, 0x22, 0xF0,
+0xE4, 0xF5, 0x1D, 0x90, 0x81, 0xDD, 0xE0, 0xF5,
+0x1E, 0xE4, 0xFB, 0xFD, 0x7F, 0x54, 0x7E, 0x01,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8E,
+0x19, 0x8F, 0x1A, 0xE5, 0x1E, 0x91, 0x95, 0x85,
+0x19, 0x83, 0x85, 0x1A, 0x82, 0xF0, 0xE5, 0x1D,
+0x91, 0x95, 0xFF, 0xE5, 0x1E, 0x13, 0x13, 0x13,
+0x54, 0x1F, 0x4F, 0xA3, 0xF0, 0xEB, 0x91, 0x95,
+0xFF, 0xE5, 0x1D, 0x13, 0x13, 0x13, 0x54, 0x1F,
+0x4F, 0x91, 0x9C, 0xF0, 0xBD, 0x01, 0x0D, 0x85,
+0x1A, 0x82, 0x8E, 0x83, 0xA3, 0xA3, 0xA3, 0x74,
+0x03, 0xF0, 0x80, 0x06, 0x91, 0x9C, 0xA3, 0x74,
+0x01, 0xF0, 0x91, 0x9C, 0xA3, 0x74, 0x05, 0xF0,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x54, 0x07, 0xC4,
+0x33, 0x54, 0xE0, 0x22, 0x85, 0x1A, 0x82, 0x85,
+0x19, 0x83, 0xA3, 0xA3, 0x22, 0x90, 0x81, 0x13,
+0xE0, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xFE, 0xFF,
+0x90, 0x81, 0x12, 0xE0, 0x2F, 0x22, 0x90, 0x84,
+0x8F, 0xE0, 0x30, 0xE0, 0x33, 0x71, 0x54, 0x70,
+0x2F, 0x90, 0x8A, 0x67, 0xE0, 0x04, 0xF0, 0xE0,
+0xB4, 0x0A, 0x0B, 0x90, 0x84, 0x91, 0xE0, 0x04,
+0xF0, 0xE4, 0x90, 0x8A, 0x67, 0xF0, 0x90, 0x84,
+0x91, 0xE0, 0xFF, 0x90, 0x84, 0x90, 0xE0, 0xD3,
+0x9F, 0x50, 0x0D, 0x90, 0x84, 0x92, 0xE0, 0x70,
+0x07, 0xE4, 0x90, 0x84, 0x91, 0xF0, 0xF1, 0xF6,
+0x22, 0x90, 0x81, 0x06, 0xD1, 0x71, 0x30, 0xE0,
+0x0C, 0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30,
+0xE0, 0x03, 0x12, 0x4D, 0x69, 0x90, 0x81, 0x05,
+0xF1, 0xEF, 0x30, 0xE0, 0x0A, 0xEF, 0x12, 0x98,
+0x37, 0x54, 0x07, 0x70, 0x3F, 0x80, 0x3B, 0x90,
+0x81, 0x13, 0xE0, 0x04, 0xF0, 0x90, 0x81, 0x0E,
+0xE0, 0x54, 0xEF, 0xF0, 0x12, 0x97, 0xFF, 0x40,
+0x29, 0x71, 0x54, 0x70, 0x27, 0xB1, 0x5D, 0xF1,
+0x80, 0x70, 0x02, 0x80, 0x20, 0x90, 0x81, 0x14,
+0xE0, 0x04, 0xF0, 0xE0, 0xD3, 0x94, 0x02, 0x40,
+0x09, 0xB1, 0x55, 0xE4, 0x90, 0x81, 0x14, 0xF0,
+0x80, 0x02, 0xF1, 0x57, 0xE4, 0x90, 0x81, 0x13,
+0xF0, 0x22, 0xF1, 0x4D, 0x22, 0x90, 0x81, 0x06,
+0xE0, 0x54, 0xFB, 0xF0, 0x22, 0x12, 0x97, 0xFF,
+0x40, 0x2D, 0x90, 0x81, 0x24, 0xE0, 0x04, 0xF0,
+0x90, 0x81, 0xDB, 0xE0, 0xFF, 0x90, 0x81, 0x24,
+0xE0, 0xD3, 0x9F, 0x50, 0x1A, 0x90, 0x81, 0x1C,
+0xE0, 0x04, 0xF0, 0x91, 0xA5, 0x90, 0x81, 0x23,
+0x12, 0x7F, 0x7B, 0x12, 0x7F, 0x83, 0x90, 0x8A,
+0x52, 0x74, 0x04, 0xF0, 0x12, 0x88, 0xF3, 0x22,
+0x71, 0x54, 0x60, 0x02, 0xC1, 0x65, 0x90, 0x81,
+0x0A, 0xE0, 0x70, 0x02, 0xC1, 0x65, 0x90, 0x06,
+0xA9, 0xE0, 0xFF, 0x90, 0x05, 0x63, 0xE0, 0x90,
+0x81, 0xCE, 0xF0, 0x90, 0x05, 0x62, 0xE0, 0x90,
+0x81, 0xCF, 0xF0, 0x90, 0x05, 0x61, 0xE0, 0x90,
+0x81, 0xD0, 0xF0, 0x90, 0x05, 0x60, 0xE0, 0x90,
+0x81, 0xD1, 0xF0, 0xD1, 0x79, 0xF0, 0x90, 0x81,
+0x0E, 0xE0, 0x54, 0xED, 0xF0, 0xD1, 0xF7, 0x90,
+0x81, 0x08, 0xE0, 0xFF, 0xC4, 0x54, 0x0F, 0x64,
+0x01, 0x70, 0x27, 0x90, 0x06, 0xAB, 0xE0, 0x90,
+0x81, 0x11, 0xF0, 0x90, 0x06, 0xAA, 0xE0, 0x60,
+0x05, 0xE0, 0x90, 0x81, 0x10, 0xF0, 0x90, 0x81,
+0x11, 0xE0, 0xFF, 0x70, 0x08, 0x90, 0x81, 0x10,
+0xE0, 0xFE, 0xFF, 0x80, 0x00, 0x90, 0x81, 0x11,
+0xEF, 0xF0, 0x12, 0x7C, 0x73, 0xE4, 0x90, 0x81,
+0x13, 0xF0, 0xA3, 0x12, 0x8A, 0x3A, 0x90, 0x81,
+0x06, 0xD1, 0x71, 0x30, 0xE0, 0x4C, 0xEF, 0xC4,
+0x13, 0x13, 0x54, 0x03, 0x20, 0xE0, 0x20, 0xD1,
+0x66, 0x6F, 0x70, 0x3E, 0x90, 0x81, 0x06, 0xE0,
+0x44, 0x40, 0xF0, 0xF1, 0xCB, 0xD1, 0x84, 0xF1,
+0xDB, 0x12, 0x4D, 0x63, 0x12, 0x4D, 0x69, 0x90,
+0x81, 0x11, 0xE0, 0x14, 0xF0, 0x80, 0x23, 0xF1,
+0xC3, 0x64, 0x01, 0x70, 0x1D, 0xD1, 0x66, 0xFE,
+0x6F, 0x60, 0x17, 0x90, 0x05, 0x73, 0xE0, 0xFF,
+0xEE, 0x6F, 0x60, 0x0E, 0xF1, 0xEC, 0x30, 0xE0,
+0x09, 0xEF, 0x54, 0xBF, 0xD1, 0x84, 0xD1, 0xE3,
+0xD1, 0x8F, 0x12, 0x98, 0x84, 0x22, 0x90, 0x81,
+0x10, 0xE0, 0xFF, 0xA3, 0xE0, 0x22, 0x90, 0x81,
+0xE4, 0xE0, 0xFF, 0x13, 0x13, 0x13, 0x54, 0x1F,
+0x22, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01,
+0x3C, 0x74, 0x02, 0x22, 0xF0, 0x90, 0x01, 0x3F,
+0x74, 0x10, 0xF0, 0xFD, 0x7F, 0x03, 0x22, 0x7D,
+0x01, 0x7F, 0x02, 0xD1, 0x99, 0x7D, 0x02, 0x7F,
+0x02, 0x74, 0x3D, 0x2F, 0xF8, 0xE6, 0x4D, 0xFE,
+0xF6, 0x74, 0x30, 0x80, 0x47, 0x7B, 0x2D, 0x12,
+0x81, 0xD9, 0x12, 0x66, 0x8F, 0x90, 0x01, 0x37,
+0x74, 0x02, 0xF0, 0xFD, 0x7F, 0x03, 0xD1, 0x99,
+0x12, 0x80, 0x7D, 0xE4, 0xFD, 0x7F, 0x01, 0x21,
+0x45, 0x90, 0x81, 0x05, 0xE0, 0x54, 0xFB, 0xF0,
+0xE4, 0x90, 0x81, 0x13, 0xF0, 0xA3, 0xF0, 0x90,
+0x81, 0x0E, 0xF0, 0x90, 0x81, 0x06, 0xE0, 0x54,
+0xF7, 0xF0, 0x54, 0xBF, 0xF0, 0xD1, 0x8F, 0x7D,
+0x10, 0x7F, 0x03, 0x74, 0x45, 0x12, 0x98, 0x8C,
+0xFE, 0xF6, 0x74, 0x38, 0x2F, 0xF5, 0x82, 0xE4,
+0x34, 0x01, 0xF5, 0x83, 0xEE, 0xF0, 0x22, 0x90,
+0x06, 0xA9, 0xE0, 0xF5, 0x4E, 0x54, 0xC0, 0x70,
+0x07, 0xF1, 0x45, 0x54, 0xFD, 0xF0, 0x80, 0x45,
+0xE5, 0x4E, 0x30, 0xE6, 0x1C, 0x90, 0x81, 0x0A,
+0xE0, 0x64, 0x01, 0x70, 0x16, 0x90, 0x81, 0x0E,
+0xE0, 0x44, 0x01, 0xF1, 0x7F, 0x64, 0x02, 0x60,
+0x04, 0xF1, 0x9F, 0x80, 0x06, 0xF1, 0x57, 0x80,
+0x02, 0xF1, 0x45, 0xE5, 0x4E, 0x90, 0x81, 0x0E,
+0x30, 0xE7, 0x0D, 0xE0, 0x44, 0x02, 0x91, 0x2F,
+0x90, 0x81, 0x05, 0xE0, 0x44, 0x04, 0xF0, 0x22,
+0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90, 0x81, 0x0E,
+0xE0, 0x54, 0xFE, 0xF0, 0x22, 0x90, 0x81, 0x0C,
+0xE0, 0xFF, 0x7D, 0x01, 0x02, 0x4D, 0xFA, 0x12,
+0x8E, 0x46, 0x90, 0x81, 0x0D, 0xE0, 0x64, 0x0C,
+0x60, 0x06, 0x12, 0x66, 0x67, 0x12, 0x67, 0x02,
+0x22, 0xE4, 0xFF, 0x51, 0x8A, 0xBF, 0x01, 0x0E,
+0x90, 0x81, 0x0A, 0xE0, 0x60, 0x08, 0xF1, 0x45,
+0x54, 0x07, 0x70, 0x02, 0xF1, 0x4D, 0x22, 0xF0,
+0x90, 0x81, 0x08, 0xE0, 0x54, 0x0F, 0x22, 0xE4,
+0xFF, 0x51, 0x8A, 0xBF, 0x01, 0x10, 0x90, 0x81,
+0x0A, 0xE0, 0x60, 0x0A, 0xF1, 0x80, 0x64, 0x02,
+0x60, 0x02, 0x80, 0x03, 0xF1, 0x57, 0x22, 0x90,
+0x04, 0x1D, 0xE0, 0x70, 0x15, 0x90, 0x80, 0x0A,
+0xE0, 0xFF, 0x90, 0x8A, 0x4A, 0x74, 0x09, 0xF0,
+0x7B, 0x18, 0xE4, 0xFD, 0x12, 0x87, 0x18, 0x12,
+0x65, 0x1C, 0x22, 0x90, 0x06, 0x04, 0xE0, 0x54,
+0x7F, 0xF0, 0x22, 0x90, 0x81, 0x08, 0xE0, 0xC4,
+0x54, 0x0F, 0x22, 0x90, 0x81, 0x10, 0xE0, 0x90,
+0x05, 0x73, 0x22, 0xE4, 0xFD, 0xFF, 0x31, 0xED,
+0xE4, 0xFF, 0x22, 0x74, 0x45, 0x2F, 0xF8, 0xE6,
+0x4D, 0xC1, 0xE8, 0x22, 0x22, 0x90, 0x01, 0xC7,
+0x74, 0xFE, 0xF0, 0x22, 0x90, 0x81, 0x06, 0xE0,
+0xFF, 0x13, 0x13, 0x54, 0x3F, 0x22, 0x90, 0x84,
+0x8F, 0xF1, 0xEF, 0x30, 0xE0, 0x0F, 0x7B, 0x00,
+0x7A, 0x00, 0x79, 0x00, 0x12, 0x97, 0xE7, 0xA3,
+0x04, 0xF0, 0x02, 0x65, 0x30, 0x7D, 0x08, 0x7F,
+0x02, 0x02, 0x67, 0x06, 0x90, 0x84, 0x93, 0xE0,
+0x30, 0xE0, 0x72, 0x90, 0x84, 0x97, 0xE0, 0x04,
+0xF0, 0x90, 0x84, 0x9A, 0xE0, 0x64, 0x01, 0x70,
+0x31, 0x90, 0x84, 0x93, 0x12, 0x6F, 0xEF, 0x30,
+0xE0, 0x28, 0x90, 0x84, 0x99, 0xE0, 0x70, 0x22,
+0x90, 0x84, 0x96, 0xE0, 0xFE, 0xA3, 0xE0, 0xC3,
+0x9E, 0x40, 0x17, 0xEF, 0x13, 0x13, 0x13, 0x54,
+0x1F, 0x30, 0xE0, 0x08, 0x12, 0x6F, 0xD3, 0x11,
+0x8E, 0xF0, 0x80, 0x06, 0x11, 0x95, 0x11, 0x8E,
+0xF0, 0x22, 0x90, 0x84, 0x97, 0xE0, 0xFF, 0x90,
+0x84, 0x94, 0xE0, 0xD3, 0x9F, 0x50, 0x26, 0x90,
+0x06, 0x92, 0xE0, 0x20, 0xE2, 0x10, 0x90, 0x84,
+0x99, 0xE0, 0x70, 0x0A, 0x51, 0xC1, 0x90, 0x84,
+0x92, 0xE0, 0x04, 0xF0, 0x80, 0x06, 0x90, 0x06,
+0x92, 0x74, 0x04, 0xF0, 0xE4, 0x90, 0x84, 0x97,
+0xF0, 0x90, 0x84, 0x99, 0xF0, 0x22, 0x90, 0x84,
+0x93, 0xE0, 0x54, 0xFE, 0x22, 0x90, 0x01, 0xC7,
+0x74, 0x10, 0xF0, 0x7F, 0x01, 0x90, 0x8A, 0x66,
+0xEF, 0xF0, 0x90, 0x80, 0x07, 0xE0, 0x64, 0x02,
+0x70, 0x22, 0x90, 0x8A, 0x66, 0xE0, 0xFD, 0x64,
+0x01, 0x70, 0x35, 0x12, 0x5C, 0xE6, 0x90, 0x81,
+0xE7, 0x12, 0x5F, 0xD7, 0x30, 0xE0, 0x09, 0x90,
+0x01, 0x4D, 0xE0, 0x64, 0x80, 0xF0, 0x80, 0x20,
+0xAF, 0x05, 0x80, 0x19, 0x90, 0x01, 0x00, 0x74,
+0xFF, 0xF0, 0x7F, 0x64, 0x7E, 0x00, 0x12, 0x32,
+0xAA, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x01, 0xF0,
+0x90, 0x8A, 0x66, 0xE0, 0xFF, 0x12, 0x8F, 0xBB,
+0x11, 0x8E, 0xF0, 0x90, 0x81, 0xE3, 0xE0, 0x54,
+0xBF, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x06, 0x31, 0xE0, 0x54, 0xEF,
+0x44, 0x08, 0xF0, 0xED, 0x2F, 0xFF, 0xE4, 0x3E,
+0xFE, 0x7C, 0x00, 0xEF, 0x24, 0x08, 0xFF, 0xEC,
+0x3E, 0x90, 0x89, 0x32, 0xF0, 0xA3, 0xEF, 0xF0,
+0x7E, 0x00, 0x7F, 0xE3, 0x7D, 0x00, 0x7B, 0x01,
+0x7A, 0x82, 0x79, 0xF8, 0x12, 0x46, 0x4B, 0x90,
+0x89, 0x33, 0xE0, 0x24, 0x01, 0x12, 0x5E, 0xD6,
+0x90, 0x82, 0xF9, 0x51, 0x59, 0x24, 0x04, 0x12,
+0x5E, 0xD6, 0x90, 0x82, 0xFC, 0x51, 0x59, 0x24,
+0x05, 0x12, 0x5E, 0xD6, 0x90, 0x82, 0xFD, 0x51,
+0x59, 0x24, 0x06, 0x12, 0x5E, 0xD6, 0x90, 0x82,
+0xFE, 0x51, 0x59, 0x24, 0x07, 0x12, 0x5E, 0xD6,
+0x90, 0x82, 0xFF, 0x51, 0x59, 0x24, 0x08, 0x12,
+0x5E, 0xD6, 0x90, 0x83, 0x00, 0xEF, 0xF0, 0xE4,
+0x90, 0x89, 0x31, 0xF0, 0x51, 0x6B, 0x94, 0x08,
+0x50, 0x1D, 0x90, 0x89, 0x33, 0xE0, 0x24, 0x09,
+0xFD, 0x90, 0x89, 0x32, 0xE0, 0x12, 0x5D, 0x6D,
+0x90, 0x89, 0x31, 0xE0, 0x24, 0x01, 0xF5, 0x82,
+0xE4, 0x34, 0x83, 0x51, 0x60, 0x80, 0xDD, 0xE4,
+0x90, 0x89, 0x31, 0xF0, 0x51, 0x6B, 0x94, 0x02,
+0x50, 0x1D, 0x90, 0x89, 0x33, 0xE0, 0x24, 0x61,
+0xFD, 0x90, 0x89, 0x32, 0xE0, 0x12, 0x5D, 0x6D,
+0x90, 0x89, 0x31, 0xE0, 0x24, 0x59, 0xF5, 0x82,
+0xE4, 0x34, 0x83, 0x51, 0x60, 0x80, 0xDD, 0xE4,
+0x90, 0x89, 0x31, 0xF0, 0x51, 0x6B, 0x94, 0x10,
+0x50, 0x1D, 0x90, 0x89, 0x33, 0xE0, 0x24, 0x31,
+0xFD, 0x90, 0x89, 0x32, 0xE0, 0x12, 0x5D, 0x6D,
+0x90, 0x89, 0x31, 0xE0, 0x24, 0x29, 0xF5, 0x82,
+0xE4, 0x34, 0x83, 0x51, 0x60, 0x80, 0xDD, 0xE4,
+0x90, 0x89, 0x31, 0xF0, 0x90, 0x83, 0x5A, 0xE0,
+0xFF, 0x90, 0x89, 0x31, 0xE0, 0xFE, 0xC3, 0x9F,
+0x50, 0x24, 0x90, 0x89, 0x33, 0xE0, 0x24, 0x63,
+0xFD, 0x90, 0x89, 0x32, 0xE0, 0x34, 0x00, 0xFC,
+0xEE, 0x7E, 0x00, 0x2D, 0x12, 0x5D, 0x74, 0x90,
+0x89, 0x31, 0xE0, 0x24, 0x5B, 0xF5, 0x82, 0xE4,
+0x34, 0x83, 0x51, 0x60, 0x80, 0xCE, 0x90, 0x82,
+0xFD, 0x12, 0x96, 0x6C, 0x90, 0x89, 0x2F, 0xEE,
+0xF0, 0xA3, 0xEF, 0xF0, 0x30, 0xE3, 0x0C, 0x90,
+0x01, 0xC7, 0x74, 0x03, 0xF0, 0x7F, 0x01, 0x11,
+0x9D, 0x80, 0x1F, 0x7E, 0x00, 0x90, 0x89, 0x30,
+0xE0, 0x54, 0x07, 0xFF, 0x64, 0x01, 0x60, 0x05,
+0xEF, 0x64, 0x02, 0x70, 0x0D, 0xE4, 0xFD, 0x51,
+0xCF, 0x90, 0x06, 0x31, 0xE0, 0x54, 0xF7, 0x44,
+0x10, 0xF0, 0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0xEF, 0xF0, 0x90, 0x89, 0x33, 0xE0, 0x22,
+0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x89, 0x31, 0xE0,
+0x04, 0xF0, 0x22, 0x90, 0x89, 0x31, 0xE0, 0xFF,
+0xC3, 0x22, 0x90, 0x84, 0x93, 0xE0, 0xFD, 0x30,
+0xE0, 0x46, 0x90, 0x84, 0x98, 0xE0, 0xFC, 0x60,
+0x3F, 0x12, 0x97, 0x9B, 0x80, 0x05, 0xC3, 0x33,
+0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x04,
+0xE0, 0xE0, 0xFB, 0xEF, 0x5B, 0x60, 0x0B, 0xE4,
+0x90, 0x84, 0x98, 0xF0, 0x90, 0x84, 0x9A, 0x04,
+0xF0, 0x22, 0x90, 0x84, 0x95, 0xE0, 0xD3, 0x9C,
+0x50, 0x14, 0xED, 0x13, 0x13, 0x13, 0x54, 0x1F,
+0x30, 0xE0, 0x05, 0x12, 0x6F, 0xD3, 0x80, 0x02,
+0x11, 0x95, 0x11, 0x8E, 0xF0, 0x22, 0x51, 0xC1,
+0x22, 0x7D, 0x08, 0x7F, 0x02, 0x12, 0x67, 0x06,
+0x90, 0x84, 0x98, 0xE0, 0x04, 0xF0, 0x22, 0x90,
+0x89, 0x34, 0x12, 0x94, 0xCB, 0xF1, 0xDF, 0x12,
+0x57, 0xD7, 0xFF, 0x12, 0x95, 0x87, 0x12, 0x57,
+0xD7, 0xFF, 0xA3, 0xE0, 0xFD, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x89, 0x37, 0x12,
+0x94, 0xCB, 0x90, 0x89, 0x4F, 0x74, 0x18, 0xF0,
+0x7E, 0x00, 0x7F, 0x80, 0x7D, 0x00, 0x7B, 0x01,
+0x7A, 0x89, 0x79, 0x57, 0x12, 0x46, 0x4B, 0x90,
+0x01, 0xC4, 0x74, 0xE5, 0xF0, 0x74, 0x72, 0xA3,
+0xF0, 0x90, 0x84, 0x81, 0xE0, 0xFF, 0x12, 0x82,
+0xC3, 0x90, 0x89, 0x4E, 0xEF, 0xF0, 0xF9, 0xE0,
+0xFE, 0x24, 0x21, 0x12, 0x83, 0x63, 0x74, 0x41,
+0xF0, 0xEE, 0x24, 0x20, 0xFD, 0xE4, 0x33, 0xFC,
+0x90, 0x89, 0x4F, 0xE0, 0x7A, 0x00, 0x2D, 0xFE,
+0xEA, 0x3C, 0x90, 0x89, 0x53, 0xF0, 0xA3, 0xCE,
+0xF0, 0x74, 0x20, 0x29, 0x12, 0x87, 0xD4, 0x90,
+0x89, 0x39, 0xE0, 0xFD, 0x12, 0x56, 0x9B, 0x12,
+0x97, 0x2B, 0x90, 0x89, 0x53, 0xE0, 0xFF, 0xA3,
+0xE0, 0x90, 0x89, 0x51, 0xCF, 0xF0, 0xA3, 0xEF,
+0xF0, 0x90, 0x89, 0x57, 0x74, 0x01, 0xF0, 0xA3,
+0x74, 0x03, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0x74,
+0x5F, 0xF0, 0x90, 0x89, 0x53, 0xE4, 0x75, 0xF0,
+0x04, 0x12, 0x43, 0xF6, 0x90, 0x82, 0xFC, 0xE0,
+0xFF, 0x7E, 0x02, 0xB4, 0xFE, 0x02, 0x7E, 0xFE,
+0x90, 0x89, 0x53, 0xA3, 0xE0, 0xFD, 0xB1, 0x48,
+0xEE, 0xF0, 0x74, 0x00, 0x2D, 0xB1, 0x4A, 0xE0,
+0x90, 0x89, 0x5B, 0xF0, 0x90, 0x89, 0x53, 0x12,
+0x78, 0xE3, 0x90, 0x83, 0xF1, 0xE0, 0x90, 0x89,
+0x37, 0xB4, 0x01, 0x0B, 0xE0, 0x44, 0x03, 0xFC,
+0xA3, 0xE0, 0x44, 0x10, 0xFD, 0x80, 0x09, 0xE0,
+0x44, 0x03, 0xFC, 0xA3, 0xE0, 0x44, 0x20, 0xFD,
+0x90, 0x89, 0x55, 0xEC, 0xF0, 0xA3, 0xED, 0xF0,
+0x90, 0x89, 0x37, 0xE0, 0x70, 0x04, 0xA3, 0xE0,
+0x64, 0x01, 0x90, 0x89, 0x53, 0x70, 0x15, 0xB1,
+0x45, 0x74, 0x03, 0xF1, 0x15, 0x74, 0x01, 0xF0,
+0x90, 0x89, 0x5C, 0x74, 0x03, 0xF0, 0xA3, 0x74,
+0x01, 0xF0, 0x80, 0x11, 0xB1, 0x45, 0x74, 0x03,
+0xF1, 0x15, 0x74, 0x02, 0xF0, 0x90, 0x89, 0x5C,
+0x04, 0xF0, 0xA3, 0x14, 0xF0, 0x12, 0x98, 0x17,
+0xEF, 0x64, 0xFE, 0x90, 0x89, 0x53, 0x70, 0x23,
+0xA3, 0xE0, 0x24, 0x00, 0xF1, 0xE8, 0xC0, 0x03,
+0x8B, 0x13, 0x12, 0x98, 0x4C, 0xD0, 0x03, 0x12,
+0x2B, 0xED, 0x75, 0x13, 0x01, 0x12, 0x98, 0x4C,
+0x7B, 0x01, 0x7A, 0x89, 0x79, 0x5E, 0x12, 0x2B,
+0xED, 0x80, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
+0x24, 0x00, 0xF5, 0x82, 0x74, 0xFC, 0x3E, 0xF5,
+0x83, 0xE4, 0xF0, 0x74, 0x01, 0x2F, 0xF5, 0x82,
+0x74, 0xFC, 0x3E, 0xF5, 0x83, 0xE4, 0xF0, 0x90,
+0x89, 0x5E, 0xF0, 0xA3, 0xF0, 0x12, 0x98, 0x17,
+0xE4, 0x90, 0x89, 0x50, 0xF0, 0x12, 0x97, 0xB5,
+0x90, 0x89, 0x53, 0xA3, 0xE0, 0xFD, 0xEF, 0x2D,
+0xB1, 0x48, 0xEE, 0xF0, 0x12, 0x97, 0xB5, 0x74,
+0x60, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5,
+0x83, 0xEE, 0x12, 0x98, 0x5D, 0xE0, 0xB4, 0x08,
+0xDC, 0x12, 0x97, 0x35, 0x90, 0x89, 0x53, 0xE4,
+0x75, 0xF0, 0x20, 0x12, 0x43, 0xF6, 0x90, 0x89,
+0x53, 0x12, 0x7B, 0x74, 0x12, 0x97, 0x2B, 0x7B,
+0x01, 0x7A, 0x89, 0x79, 0x57, 0x90, 0x89, 0xDE,
+0x12, 0x44, 0x72, 0x90, 0x89, 0xE1, 0x74, 0x63,
+0xF0, 0x7A, 0x89, 0x79, 0x3A, 0xA3, 0x12, 0x44,
+0x72, 0x7A, 0x82, 0x79, 0xB8, 0x7D, 0x10, 0x12,
+0x78, 0xEA, 0xE4, 0x90, 0x89, 0x50, 0xF0, 0x90,
+0x89, 0x50, 0xE0, 0xFF, 0xC3, 0x94, 0x10, 0x50,
+0x3C, 0x90, 0x89, 0x54, 0xE0, 0x2F, 0xFF, 0x90,
+0x89, 0x53, 0xE0, 0x34, 0x00, 0xFE, 0x90, 0x89,
+0xD7, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x84, 0x81,
+0xE0, 0xFD, 0x12, 0x8E, 0xCA, 0x90, 0x89, 0x4E,
+0xEF, 0xF0, 0x90, 0x89, 0x50, 0xE0, 0x24, 0x3A,
+0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0,
+0xFF, 0x90, 0x89, 0x4E, 0xE0, 0xB1, 0x48, 0xEF,
+0x12, 0x98, 0x5D, 0x80, 0xBA, 0x90, 0x04, 0x1D,
+0xE0, 0x60, 0x21, 0x90, 0x05, 0x22, 0xE0, 0x90,
+0x89, 0xD9, 0xF0, 0x7B, 0x1D, 0x12, 0x66, 0x89,
+0xBF, 0x01, 0x03, 0x12, 0x85, 0xB8, 0x90, 0x89,
+0xD9, 0xE0, 0xFD, 0x7B, 0x1E, 0xE4, 0xFF, 0x12,
+0x66, 0x73, 0x80, 0x03, 0x12, 0x85, 0xB8, 0x12,
+0x65, 0x1C, 0x90, 0x81, 0x0D, 0xE0, 0x70, 0x05,
+0x7F, 0x01, 0x12, 0x4F, 0xDB, 0x74, 0xE5, 0x04,
+0x90, 0x01, 0xC4, 0xF0, 0x74, 0x72, 0xA3, 0xF0,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xA3, 0xE0, 0xFE,
+0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5,
+0x83, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x90, 0x84, 0xD1, 0xEC, 0xF0, 0xA3, 0xED,
+0xF0, 0xA3, 0xEB, 0xF0, 0xAA, 0x07, 0x90, 0x84,
+0xD8, 0x12, 0x20, 0xDA, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x98, 0x21, 0xEA, 0x24, 0xEF, 0x60, 0x30,
+0x24, 0xD7, 0x70, 0x02, 0xC1, 0xA9, 0x24, 0x3A,
+0x60, 0x02, 0xC1, 0xDC, 0xF1, 0xAE, 0x24, 0x0A,
+0xF1, 0x00, 0xE4, 0xF0, 0xFE, 0x74, 0x00, 0x2F,
+0x12, 0x98, 0x6D, 0x7D, 0x14, 0xD1, 0xF5, 0x7B,
+0x00, 0x7A, 0x00, 0x79, 0x00, 0x12, 0x97, 0x7C,
+0x7D, 0x14, 0x7C, 0x00, 0xE4, 0xFF, 0xC1, 0xA4,
+0x90, 0x84, 0xD1, 0xE4, 0x75, 0xF0, 0x14, 0x12,
+0x43, 0xF6, 0x90, 0x84, 0xD1, 0xA3, 0xE0, 0xFB,
+0xFF, 0x24, 0x06, 0xFC, 0xE4, 0x33, 0x90, 0x84,
+0xDC, 0xF0, 0xA3, 0xCC, 0xF0, 0x90, 0x84, 0xDC,
+0xA3, 0xE0, 0xF1, 0x0A, 0xE4, 0xF0, 0x74, 0x04,
+0x2F, 0xF1, 0xE0, 0xE0, 0xFE, 0xA9, 0x03, 0x74,
+0x05, 0x29, 0xF1, 0xD7, 0x12, 0x81, 0xF8, 0xFE,
+0x90, 0x84, 0xD6, 0xF0, 0xA3, 0xEF, 0xF0, 0x90,
+0x84, 0xD1, 0xE0, 0xFC, 0xA3, 0xE0, 0x2F, 0xFF,
+0xEC, 0x3E, 0xFE, 0xD3, 0xEF, 0x94, 0x00, 0xEE,
+0x94, 0x01, 0x90, 0x84, 0xD1, 0x40, 0x67, 0xE0,
+0xFE, 0xA3, 0xE0, 0xFF, 0xE9, 0x7C, 0x00, 0x24,
+0x00, 0xF9, 0xEC, 0x34, 0xFC, 0xFA, 0x7B, 0x01,
+0xC3, 0xE4, 0x9F, 0xFD, 0x74, 0x01, 0x9E, 0xFC,
+0xD1, 0xF7, 0x90, 0x84, 0xD3, 0xE0, 0x24, 0x01,
+0xFF, 0xE4, 0x33, 0xA2, 0xE7, 0x13, 0xEF, 0x13,
+0x90, 0xFD, 0x10, 0xF0, 0xF1, 0xD1, 0xC0, 0x00,
+0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03, 0x7B, 0x01,
+0x7A, 0xFC, 0x79, 0x00, 0x90, 0x84, 0xD1, 0x12,
+0x7B, 0x6A, 0xE4, 0x9F, 0xFF, 0x74, 0x01, 0x9E,
+0xFE, 0xF1, 0xB5, 0xC3, 0x9F, 0xFD, 0xEC, 0x9E,
+0xFC, 0x12, 0x24, 0xE4, 0xD0, 0x03, 0xD0, 0x02,
+0xD0, 0x01, 0xD0, 0x00, 0x12, 0x44, 0x0C, 0xD1,
+0xFA, 0x12, 0x98, 0x21, 0x80, 0x0E, 0xA3, 0xE0,
+0x7E, 0x00, 0x24, 0x00, 0x12, 0x98, 0x6D, 0xF1,
+0xB5, 0xFD, 0xD1, 0xF7, 0x90, 0x84, 0xD1, 0x74,
+0xFF, 0x75, 0xF0, 0xEC, 0x12, 0x43, 0xF6, 0xF1,
+0xAE, 0x7E, 0x00, 0x24, 0x0C, 0xF9, 0xEE, 0x34,
+0xFC, 0xFA, 0x7B, 0x01, 0xC0, 0x02, 0xC0, 0x01,
+0x74, 0x10, 0x2F, 0xF9, 0xEE, 0x34, 0xFC, 0xFA,
+0x12, 0x97, 0x7C, 0xF1, 0xB5, 0xFD, 0xD0, 0x01,
+0xD0, 0x02, 0x7F, 0x11, 0x12, 0x1C, 0x34, 0x80,
+0x2B, 0xF1, 0xAE, 0x24, 0x2A, 0xF1, 0x00, 0xE4,
+0xF0, 0x74, 0x00, 0x2F, 0xF1, 0xE8, 0x7D, 0x48,
+0xD1, 0xF5, 0xF1, 0xC6, 0x12, 0x44, 0x0C, 0xE4,
+0xFD, 0xFC, 0xD1, 0xFA, 0xF1, 0xC6, 0x12, 0x44,
+0x0C, 0xD1, 0xFA, 0x90, 0x84, 0xD8, 0x12, 0x44,
+0x45, 0x12, 0x20, 0x9B, 0x90, 0x84, 0xD4, 0xEE,
+0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x84, 0xD4, 0xE0,
+0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0xFF, 0x90, 0x84,
+0xDC, 0xB1, 0x45, 0xEF, 0xF1, 0x15, 0xED, 0xF0,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7C, 0x00, 0x12,
+0x24, 0xE4, 0x90, 0x84, 0xD8, 0x02, 0x20, 0xCE,
+0xFD, 0xE4, 0x33, 0x90, 0x84, 0xDC, 0xF0, 0xA3,
+0xED, 0xF0, 0xFE, 0x24, 0x00, 0xF5, 0x82, 0xE4,
+0x34, 0xFC, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x01,
+0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0x22, 0xE4, 0xFD, 0xFC, 0x90, 0x84, 0x88, 0x12,
+0x85, 0x84, 0xAB, 0x05, 0x74, 0x01, 0x2B, 0xF1,
+0x19, 0xE0, 0xFE, 0x74, 0x00, 0x2B, 0xB1, 0x4A,
+0xE0, 0x12, 0x93, 0x5F, 0x90, 0x84, 0x26, 0xF0,
+0xA3, 0xEF, 0xF0, 0x74, 0x03, 0x2B, 0xF5, 0x82,
+0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFE, 0x74,
+0x02, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF1,
+0xBD, 0x90, 0x84, 0x28, 0xF0, 0xA3, 0xEF, 0xF0,
+0x74, 0x05, 0x2B, 0xF1, 0xD7, 0xE0, 0xFE, 0x74,
+0x04, 0x2B, 0xF1, 0xE0, 0xF1, 0xBF, 0x90, 0x84,
+0x2A, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x07, 0x2B,
+0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0,
+0xFE, 0x74, 0x06, 0x2B, 0xF5, 0x82, 0xE4, 0x34,
+0xFC, 0xF1, 0xBD, 0x90, 0x84, 0x2C, 0xF0, 0xA3,
+0xEF, 0xF0, 0x74, 0x09, 0x2B, 0x12, 0x87, 0x98,
+0xE0, 0xFE, 0x74, 0x08, 0x2B, 0x12, 0x87, 0x90,
+0xE0, 0x24, 0x00, 0xFF, 0xEC, 0x3E, 0x90, 0x84,
+0x2E, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x90, 0x84,
+0xD1, 0xA3, 0xE0, 0xFF, 0x22, 0x90, 0x84, 0xD6,
+0xE0, 0xFC, 0xA3, 0xE0, 0x22, 0xF5, 0x83, 0xE0,
+0x24, 0x00, 0xFF, 0xEA, 0x3E, 0x22, 0x90, 0x84,
+0xD8, 0x12, 0x44, 0x45, 0x78, 0x10, 0x12, 0x20,
+0xA8, 0x90, 0x84, 0xD8, 0x02, 0x44, 0x51, 0xF5,
+0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x22,
+0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22,
+0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0x22,
+0xE4, 0x90, 0x89, 0x0E, 0xF0, 0xA3, 0xF0, 0xA3,
+0xF0, 0x90, 0x89, 0x0E, 0xE0, 0x64, 0x01, 0xF0,
+0x24, 0xF0, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x77,
+0xA3, 0xF0, 0x90, 0x81, 0x0A, 0xE0, 0x60, 0x0F,
+0x90, 0x81, 0x0D, 0xE0, 0xFF, 0x90, 0x81, 0x0C,
+0xE0, 0x6F, 0x60, 0x03, 0x12, 0x6F, 0x4D, 0xC2,
+0xAF, 0x12, 0x8D, 0x31, 0xBF, 0x01, 0x02, 0x11,
+0x32, 0xD2, 0xAF, 0xF1, 0x7A, 0x12, 0x46, 0xC4,
+0x80, 0xC7, 0x90, 0x81, 0x05, 0xE0, 0x30, 0xE0,
+0x02, 0x11, 0x3C, 0x22, 0x90, 0x81, 0x0D, 0xE0,
+0xFF, 0x60, 0x03, 0xB4, 0x08, 0x0E, 0x12, 0x90,
+0x99, 0xBF, 0x01, 0x08, 0x11, 0x55, 0x90, 0x01,
+0xE5, 0xE0, 0x04, 0xF0, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0xF1, 0x22, 0x11, 0x65,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF1, 0xA4, 0x90,
+0x81, 0x15, 0xE0, 0x20, 0xE0, 0x0C, 0x90, 0x00,
+0x26, 0xE0, 0x54, 0x7F, 0xFD, 0x7F, 0x26, 0x12,
+0x32, 0x1E, 0x90, 0x00, 0x08, 0xE0, 0x54, 0xEF,
+0xFD, 0x7F, 0x08, 0x12, 0x32, 0x1E, 0xE4, 0xFF,
+0x90, 0x89, 0x11, 0xD1, 0xC6, 0x90, 0x01, 0x09,
+0xE0, 0x7F, 0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01,
+0x90, 0x89, 0x11, 0xE0, 0x6F, 0x60, 0x39, 0xC3,
+0x90, 0x89, 0x13, 0xE0, 0x94, 0x88, 0x90, 0x89,
+0x12, 0xE0, 0x94, 0x13, 0x40, 0x08, 0x90, 0x01,
+0xC0, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0x90, 0x89,
+0x12, 0x11, 0xE3, 0x7F, 0x14, 0x7E, 0x00, 0x12,
+0x32, 0xAA, 0xD3, 0x90, 0x89, 0x13, 0xE0, 0x94,
+0x32, 0x90, 0x89, 0x12, 0xE0, 0x94, 0x00, 0x40,
+0xBC, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE0, 0xB5,
+0x22, 0x7F, 0x01, 0x7E, 0x00, 0x12, 0x32, 0xAA,
+0x90, 0x8A, 0x2A, 0xE4, 0x75, 0xF0, 0x01, 0x02,
+0x43, 0xF6, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x90, 0x89, 0xDA, 0x12, 0x44, 0x72, 0x90,
+0x89, 0xDD, 0xED, 0xF0, 0xE4, 0x90, 0x8A, 0x29,
+0xF0, 0x90, 0x8A, 0x29, 0xE0, 0xFF, 0xC3, 0x94,
+0x40, 0x50, 0x07, 0x51, 0xBF, 0x71, 0x47, 0xF0,
+0x80, 0xEF, 0x12, 0x66, 0x5A, 0x71, 0x99, 0x51,
+0xF2, 0x94, 0x40, 0x50, 0x0A, 0x51, 0xBF, 0xE0,
+0x64, 0x36, 0xF0, 0x51, 0xB8, 0x80, 0xF0, 0x51,
+0xA7, 0x90, 0x89, 0xE1, 0x71, 0x5F, 0x74, 0x80,
+0x12, 0x1F, 0xFC, 0xEF, 0x75, 0xF0, 0x08, 0xA4,
+0x24, 0x00, 0xFF, 0xE5, 0xF0, 0x34, 0x02, 0xFC,
+0x90, 0x00, 0x7E, 0x12, 0x1F, 0xFC, 0xEF, 0x90,
+0x00, 0x7F, 0x71, 0x7B, 0x71, 0x67, 0x94, 0xC0,
+0xEE, 0x94, 0x00, 0x50, 0x5D, 0x71, 0x57, 0x50,
+0x0D, 0x71, 0xAE, 0x24, 0xF2, 0xF9, 0xE4, 0x34,
+0x89, 0xFA, 0x7B, 0x01, 0x80, 0x04, 0x71, 0xF6,
+0x71, 0x4F, 0x71, 0x86, 0x51, 0xAD, 0x90, 0x01,
+0x8C, 0xE0, 0x30, 0xE4, 0x0A, 0x51, 0xCA, 0x94,
+0x03, 0x50, 0x04, 0x11, 0xD9, 0x80, 0xEF, 0x51,
+0xE3, 0x40, 0x08, 0x90, 0x06, 0x31, 0xE0, 0x44,
+0x01, 0x51, 0xDC, 0x90, 0x8A, 0x27, 0xE0, 0x54,
+0x3F, 0x64, 0x30, 0x70, 0x19, 0x51, 0xAE, 0x90,
+0x01, 0x8C, 0xE0, 0x20, 0xE5, 0x0A, 0x51, 0xCA,
+0x94, 0x03, 0x50, 0x04, 0x11, 0xD9, 0x80, 0xEF,
+0x51, 0xE3, 0x40, 0x02, 0x51, 0xD6, 0x71, 0x71,
+0x80, 0x9A, 0x51, 0xF9, 0x7D, 0x84, 0x12, 0x2A,
+0x8F, 0xE4, 0x90, 0x8A, 0x29, 0xF0, 0x90, 0x8A,
+0x29, 0xE0, 0xFF, 0xC3, 0x94, 0x40, 0x50, 0x07,
+0x51, 0xBF, 0x71, 0x47, 0xF0, 0x80, 0xEF, 0x12,
+0x66, 0x5A, 0x71, 0x99, 0x51, 0xF2, 0x94, 0x40,
+0x50, 0x0A, 0x51, 0xBF, 0xE0, 0x64, 0x5C, 0xF0,
+0x51, 0xB8, 0x80, 0xF0, 0xE4, 0x90, 0x89, 0xE5,
+0xF0, 0x71, 0x41, 0x90, 0x89, 0xE5, 0x71, 0x5F,
+0x12, 0x1F, 0xBD, 0xFE, 0x51, 0xA7, 0x8F, 0x82,
+0x75, 0x83, 0x00, 0xEE, 0x51, 0xB5, 0xE0, 0xB4,
+0x14, 0xE7, 0x51, 0xA7, 0x90, 0x00, 0x14, 0x74,
+0x80, 0x12, 0x1F, 0xFC, 0x90, 0x89, 0xE5, 0x74,
+0x15, 0xF0, 0x51, 0xF2, 0x94, 0x3E, 0x50, 0x0C,
+0x51, 0xA7, 0x8F, 0x82, 0x75, 0x83, 0x00, 0xE4,
+0x51, 0xB5, 0x80, 0xEE, 0x51, 0xA7, 0x90, 0x00,
+0x3E, 0x74, 0x02, 0x12, 0x1F, 0xFC, 0x90, 0x00,
+0x3F, 0x74, 0xA0, 0x71, 0x7B, 0x71, 0x67, 0x94,
+0x80, 0xEE, 0x94, 0x00, 0x50, 0x5D, 0x71, 0x57,
+0x50, 0x0D, 0x71, 0xAE, 0x24, 0xF2, 0xF9, 0xE4,
+0x34, 0x89, 0xFA, 0x7B, 0x01, 0x80, 0x04, 0x71,
+0xF6, 0x71, 0x4F, 0x71, 0x86, 0x51, 0xAD, 0x90,
+0x01, 0x8C, 0xE0, 0x30, 0xE4, 0x0A, 0x51, 0xCA,
+0x94, 0x03, 0x50, 0x04, 0x11, 0xD9, 0x80, 0xEF,
+0x51, 0xE3, 0x40, 0x08, 0x90, 0x06, 0x31, 0xE0,
+0x44, 0x01, 0x51, 0xDC, 0x90, 0x8A, 0x27, 0xE0,
+0x54, 0x3F, 0x64, 0x30, 0x70, 0x19, 0x51, 0xAE,
+0x90, 0x01, 0x8C, 0xE0, 0x20, 0xE5, 0x0A, 0x51,
+0xCA, 0x94, 0x03, 0x50, 0x04, 0x11, 0xD9, 0x80,
+0xEF, 0x51, 0xE3, 0x40, 0x02, 0x51, 0xD6, 0x71,
+0x71, 0x80, 0x9A, 0x51, 0xF9, 0x7D, 0x84, 0x12,
+0x2A, 0x8F, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90,
+0x89, 0xDE, 0x02, 0x44, 0x69, 0xE4, 0x90, 0x8A,
+0x2A, 0xF0, 0xA3, 0xF0, 0x22, 0x12, 0x1F, 0xFC,
+0x90, 0x89, 0xE5, 0xE0, 0x04, 0xF0, 0x22, 0x74,
+0xE6, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5,
+0x83, 0x22, 0xC3, 0x90, 0x8A, 0x2B, 0xE0, 0x94,
+0xE8, 0x90, 0x8A, 0x2A, 0xE0, 0x22, 0x90, 0x06,
+0x31, 0xE0, 0x44, 0x02, 0xF0, 0xEE, 0x90, 0x06,
+0x36, 0xF0, 0x22, 0x90, 0x8A, 0x2A, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0xC3, 0x94, 0xE8, 0xEE, 0x94,
+0x03, 0x22, 0x90, 0x89, 0xE5, 0xE0, 0xFF, 0xC3,
+0x22, 0x90, 0x89, 0xE2, 0x12, 0x44, 0x69, 0xE9,
+0x24, 0x10, 0xF9, 0xE4, 0x3A, 0xFA, 0x7D, 0x80,
+0x12, 0x2A, 0x8F, 0x90, 0x89, 0xE2, 0x12, 0x44,
+0x69, 0xE9, 0x24, 0x0C, 0xF9, 0xE4, 0x3A, 0xFA,
+0x7D, 0x81, 0x12, 0x2A, 0x8F, 0x90, 0x89, 0xE2,
+0x12, 0x44, 0x69, 0xE9, 0x24, 0x08, 0xF9, 0xE4,
+0x3A, 0xFA, 0x7D, 0x82, 0x12, 0x2A, 0x8F, 0x90,
+0x89, 0xE2, 0x12, 0x44, 0x69, 0xE9, 0x24, 0x04,
+0xF9, 0xE4, 0x3A, 0xFA, 0x7D, 0x83, 0x12, 0x2A,
+0x8F, 0x90, 0x89, 0xE2, 0x02, 0x44, 0x69, 0xE4,
+0xF0, 0x90, 0x8A, 0x29, 0xE0, 0x04, 0x22, 0x24,
+0xCC, 0xF9, 0xEA, 0x34, 0xFF, 0xFA, 0x22, 0xC3,
+0xEF, 0x94, 0x40, 0xEE, 0x94, 0x00, 0x22, 0xE0,
+0xFF, 0xF5, 0x82, 0x75, 0x83, 0x00, 0x22, 0x90,
+0x8A, 0x26, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3,
+0x22, 0x90, 0x8A, 0x26, 0xE4, 0x75, 0xF0, 0x10,
+0x02, 0x43, 0xF6, 0x12, 0x1F, 0xFC, 0xE4, 0x90,
+0x8A, 0x26, 0xF0, 0xA3, 0xF0, 0x22, 0xA3, 0xE0,
+0x44, 0x8B, 0xFD, 0x12, 0x28, 0x08, 0x90, 0x8A,
+0x28, 0xE0, 0x44, 0x90, 0x90, 0x01, 0x8C, 0xF0,
+0x22, 0x90, 0x89, 0xDD, 0xE0, 0xF5, 0x16, 0x7B,
+0x01, 0x7A, 0x89, 0x79, 0xE6, 0x12, 0x2B, 0xED,
+0xE4, 0x90, 0x89, 0xE5, 0xF0, 0x22, 0xA3, 0x74,
+0x40, 0xF0, 0x74, 0xE6, 0x2F, 0xF9, 0xE4, 0x34,
+0x89, 0xFA, 0x7B, 0x01, 0x74, 0x40, 0x44, 0x88,
+0xFD, 0x12, 0x28, 0x08, 0x90, 0x8A, 0x26, 0xA3,
+0xE0, 0x24, 0xEA, 0xF9, 0xE4, 0x34, 0x89, 0xFA,
+0x7B, 0x01, 0xA3, 0xE0, 0x44, 0x89, 0xFD, 0x12,
+0x28, 0x08, 0x90, 0x8A, 0x26, 0xA3, 0xE0, 0x24,
+0xEE, 0xF9, 0xE4, 0x34, 0x89, 0xFA, 0x7B, 0x01,
+0xA3, 0xE0, 0x44, 0x8A, 0xFD, 0x12, 0x28, 0x08,
+0x90, 0x8A, 0x26, 0xA3, 0xE0, 0x22, 0xE4, 0x90,
+0x8A, 0x28, 0xF0, 0x90, 0x89, 0xDE, 0x12, 0x44,
+0x69, 0x90, 0x8A, 0x26, 0xE0, 0xFE, 0xA3, 0xE0,
+0x29, 0xF9, 0xEA, 0x3E, 0xFA, 0xE9, 0x24, 0xC0,
+0xF9, 0xEA, 0x34, 0xFF, 0xFA, 0x74, 0x88, 0xFD,
+0x12, 0x28, 0x08, 0x90, 0x89, 0xDE, 0x12, 0x44,
+0x69, 0x90, 0x8A, 0x26, 0xE0, 0xFE, 0xA3, 0xE0,
+0x29, 0xF9, 0xEA, 0x3E, 0xFA, 0xE9, 0x24, 0xC4,
+0xF9, 0xEA, 0x34, 0xFF, 0xFA, 0xA3, 0xE0, 0x44,
+0x89, 0xFD, 0x12, 0x28, 0x08, 0x90, 0x89, 0xDE,
+0x12, 0x44, 0x69, 0x90, 0x8A, 0x26, 0xE0, 0xFE,
+0xA3, 0xE0, 0x29, 0xF9, 0xEA, 0x3E, 0xFA, 0xE9,
+0x24, 0xC8, 0xF9, 0xEA, 0x34, 0xFF, 0xFA, 0xA3,
+0xE0, 0x44, 0x8A, 0xFD, 0x12, 0x28, 0x08, 0x90,
+0x89, 0xDE, 0x12, 0x44, 0x69, 0x90, 0x8A, 0x26,
+0xE0, 0xFE, 0xA3, 0xE0, 0x29, 0xF9, 0xEA, 0x3E,
+0xFA, 0xE9, 0x22, 0x90, 0x81, 0xD2, 0x12, 0x44,
+0x45, 0x90, 0x81, 0xCE, 0x12, 0x44, 0x51, 0xC3,
+0x12, 0x44, 0x34, 0x50, 0x02, 0xA1, 0x21, 0x90,
+0x81, 0xD2, 0x12, 0x44, 0x51, 0x90, 0x81, 0xCE,
+0x12, 0x44, 0x45, 0x12, 0x44, 0x19, 0x78, 0x07,
+0x12, 0x20, 0xA8, 0xC0, 0x07, 0x90, 0x81, 0xD6,
+0xE0, 0xFB, 0xE4, 0xFA, 0xF9, 0xF8, 0xD0, 0x07,
+0x12, 0x44, 0x19, 0xEE, 0x54, 0x07, 0xFE, 0xAD,
+0x07, 0xAC, 0x06, 0x90, 0x81, 0x05, 0xE0, 0x30,
+0xE0, 0x2E, 0xD1, 0x20, 0xC3, 0x33, 0xCE, 0x33,
+0xCE, 0xD8, 0xF9, 0x2D, 0xFD, 0xEE, 0x3C, 0xFC,
+0x90, 0x81, 0x27, 0xE0, 0x24, 0x05, 0xFF, 0xE4,
+0x33, 0xFE, 0xEF, 0x78, 0x03, 0xC3, 0x33, 0xCE,
+0x33, 0xCE, 0xD8, 0xF9, 0x2D, 0xFF, 0xEC, 0x3E,
+0xCF, 0x24, 0xFA, 0xCF, 0x34, 0xFF, 0x80, 0x13,
+0xD1, 0x20, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8,
+0xF9, 0x2D, 0xFF, 0xEE, 0x3C, 0xCF, 0x24, 0x10,
+0xCF, 0x34, 0x00, 0x90, 0x89, 0x00, 0xF0, 0xA3,
+0xEF, 0xF0, 0x90, 0x89, 0x00, 0x71, 0x6A, 0x94,
+0xA0, 0xEE, 0x94, 0x00, 0x50, 0x13, 0x74, 0x28,
+0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83,
+0xE0, 0x04, 0xF0, 0x90, 0x81, 0x20, 0xE0, 0x04,
+0xF0, 0x90, 0x81, 0x20, 0xE0, 0xFF, 0xD3, 0x90,
+0x81, 0xD9, 0xE0, 0x9F, 0x90, 0x81, 0xD8, 0xE0,
+0x94, 0x00, 0x40, 0x02, 0xC1, 0x18, 0xE4, 0xFF,
+0xFE, 0xD1, 0x32, 0xEF, 0xD3, 0x9D, 0x40, 0x07,
+0x90, 0x89, 0x02, 0xEE, 0xF0, 0x80, 0x05, 0x0E,
+0xEE, 0xB4, 0xA0, 0xED, 0xE4, 0xFF, 0xFE, 0xD1,
+0x32, 0xC3, 0x90, 0x81, 0xD9, 0xE0, 0x9D, 0xFD,
+0x90, 0x81, 0xD8, 0xE0, 0x94, 0x00, 0xFC, 0xEF,
+0xD3, 0x9D, 0xE4, 0x9C, 0x40, 0x07, 0x90, 0x89,
+0x03, 0xEE, 0xF0, 0x80, 0x05, 0x0E, 0xEE, 0xB4,
+0xA0, 0xDD, 0x90, 0x89, 0x02, 0xE0, 0x90, 0x81,
+0x25, 0xF0, 0x90, 0x89, 0x03, 0xE0, 0x90, 0x81,
+0x26, 0xD1, 0x19, 0xC3, 0x94, 0x50, 0x40, 0x20,
+0xEF, 0x24, 0xB0, 0x90, 0x81, 0x1D, 0xF0, 0xE4,
+0x90, 0x81, 0x1C, 0xF0, 0xA3, 0xE0, 0x54, 0x07,
+0x75, 0xF0, 0x80, 0xA4, 0xFF, 0x90, 0x81, 0xC8,
+0xE5, 0xF0, 0xF0, 0xA3, 0xEF, 0xF0, 0x80, 0x10,
+0xE4, 0x90, 0x81, 0x1D, 0xD1, 0x19, 0xC3, 0x74,
+0x50, 0x9F, 0x90, 0x81, 0x1C, 0xF1, 0x7B, 0xF0,
+0x90, 0x81, 0x25, 0x12, 0x4F, 0xF3, 0xF0, 0xA3,
+0x12, 0x4F, 0xF3, 0xF0, 0x90, 0x81, 0x1D, 0x12,
+0x4F, 0xF3, 0xF0, 0x90, 0x81, 0x1C, 0x12, 0x4F,
+0xF3, 0xD1, 0x19, 0xA3, 0xE0, 0xC3, 0x9F, 0x90,
+0x81, 0x23, 0xF0, 0x90, 0x81, 0x05, 0xE0, 0x30,
+0xE0, 0x08, 0x90, 0x81, 0xD6, 0x12, 0x4F, 0xF3,
+0x80, 0x04, 0x90, 0x81, 0xD7, 0xE0, 0x04, 0xFF,
+0x90, 0x81, 0x23, 0xE0, 0x2F, 0xF0, 0x90, 0x81,
+0x23, 0xE0, 0xC3, 0x94, 0x10, 0x50, 0x03, 0x74,
+0x10, 0xF0, 0x90, 0x81, 0x23, 0xE0, 0x24, 0x02,
+0xF1, 0x83, 0x90, 0x8A, 0x52, 0x74, 0x03, 0xF0,
+0x12, 0x88, 0xF3, 0xE4, 0xFF, 0x12, 0x91, 0x27,
+0x22, 0xF0, 0x90, 0x81, 0x25, 0xE0, 0xFF, 0x22,
+0x90, 0x81, 0x22, 0xE0, 0xFF, 0xC3, 0x74, 0x0A,
+0x9F, 0xFF, 0xE4, 0x94, 0x00, 0xFE, 0xEF, 0x78,
+0x03, 0x22, 0x74, 0x28, 0x2E, 0xF5, 0x82, 0xE4,
+0x34, 0x81, 0xF5, 0x83, 0xE0, 0x2F, 0xFF, 0x90,
+0x81, 0xDA, 0xE0, 0xFD, 0x22, 0xE4, 0x90, 0x8A,
+0x5C, 0xF0, 0xA3, 0xF0, 0x90, 0x02, 0x86, 0xE0,
+0x20, 0xE1, 0x22, 0xC3, 0x90, 0x8A, 0x5D, 0xE0,
+0x94, 0xD0, 0x90, 0x8A, 0x5C, 0xE0, 0x94, 0x07,
+0x40, 0x0A, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x04,
+0xF0, 0x7F, 0x00, 0x22, 0x90, 0x8A, 0x5C, 0x11,
+0xE3, 0xD1, 0xBF, 0x80, 0xD7, 0x7F, 0x01, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
+0x8A, 0x43, 0xEE, 0xF0, 0xA3, 0xD1, 0xC6, 0x90,
+0x8A, 0x43, 0xE0, 0xFE, 0xA3, 0xE0, 0xF5, 0x82,
+0x8E, 0x83, 0xE0, 0x60, 0x23, 0xC3, 0x90, 0x8A,
+0x46, 0xE0, 0x94, 0xE8, 0x90, 0x8A, 0x45, 0xE0,
+0x94, 0x03, 0x40, 0x0B, 0x90, 0x01, 0xC0, 0xE0,
+0x44, 0x80, 0xF0, 0x7F, 0x00, 0x80, 0x0B, 0x90,
+0x8A, 0x45, 0x11, 0xE3, 0xD1, 0xBF, 0x80, 0xCF,
+0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7F,
+0x0A, 0x7E, 0x00, 0x02, 0x32, 0xAA, 0xEF, 0xF0,
+0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0xE4, 0xFB,
+0xFA, 0xFD, 0x7F, 0x01, 0x12, 0x48, 0xC5, 0x90,
+0x89, 0x14, 0xEF, 0xF0, 0x60, 0xF0, 0x90, 0x80,
+0x01, 0xE0, 0xFF, 0x70, 0x04, 0xA3, 0xE0, 0x60,
+0xE5, 0xC2, 0xAF, 0xEF, 0x30, 0xE1, 0x0A, 0x90,
+0x80, 0x01, 0xE0, 0x54, 0xFD, 0xF0, 0x12, 0x8B,
+0x14, 0xF1, 0x18, 0x30, 0xE2, 0x06, 0x54, 0xFB,
+0xF0, 0x12, 0x8B, 0xE5, 0xF1, 0x18, 0x30, 0xE4,
+0x0B, 0x54, 0xEF, 0xF0, 0xD1, 0x45, 0xBF, 0x01,
+0x03, 0x12, 0x59, 0x8C, 0xD2, 0xAF, 0x80, 0xC6,
+0xD2, 0xAF, 0xC2, 0xAF, 0x90, 0x80, 0x01, 0xE0,
+0xFF, 0x22, 0x90, 0x81, 0x15, 0xE0, 0xFD, 0x7F,
+0x93, 0x12, 0x32, 0x1E, 0x90, 0x81, 0x0B, 0xE0,
+0x60, 0x12, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7,
+0x05, 0x74, 0x10, 0xF0, 0x80, 0x06, 0x90, 0x01,
+0x2F, 0x74, 0x90, 0xF0, 0x90, 0x00, 0x08, 0xE0,
+0x44, 0x10, 0xFD, 0x7F, 0x08, 0x12, 0x32, 0x1E,
+0x7F, 0x01, 0x11, 0x88, 0x90, 0x81, 0x15, 0xE0,
+0x20, 0xE0, 0x0C, 0x90, 0x00, 0x26, 0xE0, 0x44,
+0x80, 0xFD, 0x7F, 0x26, 0x12, 0x32, 0x1E, 0x90,
+0x00, 0x90, 0xE0, 0x44, 0x01, 0xFD, 0x7F, 0x90,
+0x12, 0x32, 0x1E, 0x7F, 0x14, 0x7E, 0x00, 0x02,
+0x32, 0xAA, 0x22, 0xF0, 0xE4, 0x90, 0x81, 0xC8,
+0xF0, 0xA3, 0x22, 0xF0, 0x90, 0x81, 0x1C, 0xE0,
+0xFF, 0xA3, 0xE0, 0xFD, 0x90, 0x81, 0x23, 0xE0,
+0xFB, 0x22, 0x90, 0x84, 0x8F, 0xE0, 0x54, 0xFE,
+0xF0, 0x54, 0x7F, 0xF0, 0x54, 0xFB, 0xF0, 0xA3,
+0x74, 0x0A, 0xC1, 0xC7, 0x90, 0x01, 0xC4, 0x74,
+0xA4, 0xF0, 0x74, 0x7F, 0xA3, 0xF0, 0x90, 0x00,
+0x90, 0xE0, 0x20, 0xE0, 0xF9, 0x74, 0xA4, 0x04,
+0x90, 0x01, 0xC4, 0xF0, 0x74, 0x7F, 0xA3, 0xF0,
+0x22, 0xAD, 0x07, 0x90, 0x84, 0x30, 0x11, 0xE3,
+0x90, 0x84, 0x30, 0xE0, 0xFF, 0xAE, 0x05, 0x74,
+0x04, 0x2E, 0x12, 0x77, 0xE0, 0xEF, 0xF0, 0x90,
+0x84, 0x30, 0xA3, 0xE0, 0xFF, 0x74, 0x05, 0x2E,
+0x12, 0x77, 0xD7, 0xEF, 0xF0, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x4B, 0xF2,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0xC0, 0x07, 0xC0, 0x05,
+0x90, 0x8A, 0x2E, 0x12, 0x44, 0x45, 0x90, 0x84,
+0xED, 0x12, 0x20, 0xCE, 0xD0, 0x05, 0xD0, 0x07,
+0x12, 0x4D, 0x02, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
+0x01, 0x01, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x01,
+0x00, 0x74, 0xFF, 0xF0, 0x90, 0x06, 0xB7, 0x74,
+0x09, 0xF0, 0x90, 0x06, 0xB4, 0x74, 0x86, 0xF0,
+0x31, 0xBA, 0xEC, 0x54, 0x7F, 0xFC, 0x90, 0x8A,
+0x4B, 0x12, 0x20, 0xCE, 0x90, 0x8A, 0x4B, 0x12,
+0x4C, 0xDA, 0x7F, 0x7C, 0x11, 0x74, 0x12, 0x20,
+0xDA, 0xCC, 0xC0, 0x00, 0xC0, 0x11, 0x72, 0x12,
+0x20, 0xDA, 0x00, 0xC0, 0x00, 0x14, 0x31, 0xC1,
+0x12, 0x20, 0xDA, 0x00, 0x03, 0x3E, 0x60, 0xE4,
+0xFD, 0xFF, 0x12, 0x7F, 0xF5, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0x7F, 0x8C, 0x7E, 0x08, 0x12, 0x2E,
+0xA2, 0x90, 0x85, 0xBB, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0x90, 0x8A, 0x32,
+0xF0, 0xA3, 0xF0, 0x12, 0x66, 0x8F, 0x90, 0x85,
+0xBB, 0x12, 0x20, 0xDA, 0xCC, 0xF0, 0x00, 0xC0,
+0x11, 0x72, 0x12, 0x20, 0xDA, 0x00, 0x00, 0x00,
+0x14, 0x31, 0xC1, 0x12, 0x20, 0xDA, 0x00, 0x00,
+0x00, 0x00, 0xE4, 0xFD, 0xFF, 0x12, 0x7F, 0xF5,
+0x7F, 0xE8, 0x7E, 0x08, 0x12, 0x2D, 0x5C, 0xEF,
+0x54, 0x0E, 0xFF, 0xE4, 0xFE, 0xED, 0x54, 0xF4,
+0xFD, 0xEC, 0x54, 0x03, 0xFC, 0xE4, 0xFB, 0xFA,
+0xF9, 0xF8, 0xC3, 0x12, 0x44, 0x34, 0x60, 0x1A,
+0xD3, 0x31, 0x21, 0x94, 0x03, 0x40, 0x09, 0x90,
+0x01, 0xC3, 0xE0, 0x44, 0x02, 0xF0, 0x80, 0x0A,
+0xF1, 0x71, 0x90, 0x8A, 0x32, 0x12, 0x78, 0xE3,
+0x80, 0xC6, 0xC3, 0x31, 0x21, 0x94, 0x03, 0x50,
+0x19, 0x31, 0xBA, 0xEC, 0x44, 0x80, 0xFC, 0x90,
+0x8A, 0x34, 0x12, 0x20, 0xCE, 0x90, 0x8A, 0x34,
+0x12, 0x4C, 0xDA, 0x7F, 0x7C, 0x7E, 0x08, 0x12,
+0x2E, 0xA2, 0x90, 0x01, 0x00, 0x74, 0x3F, 0xF0,
+0xA3, 0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x05, 0x53,
+0xE0, 0x44, 0x20, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x90, 0x8A, 0x33, 0xE0, 0x94, 0xE8, 0x90,
+0x8A, 0x32, 0xE0, 0x22, 0xEF, 0x60, 0x43, 0x90,
+0x04, 0xEC, 0xE0, 0x54, 0xDD, 0xF0, 0x90, 0x84,
+0x7E, 0xE0, 0xFF, 0x60, 0x02, 0x31, 0xE0, 0x90,
+0x01, 0xC7, 0xE4, 0x31, 0xEF, 0xB1, 0x8D, 0x90,
+0x06, 0x09, 0xE0, 0x54, 0xFE, 0xF0, 0x7B, 0x35,
+0x31, 0xD9, 0x11, 0x7D, 0x90, 0x02, 0x86, 0xE0,
+0x44, 0x04, 0xF0, 0xF1, 0x23, 0x31, 0xAD, 0x11,
+0x18, 0x12, 0x66, 0x6E, 0xB1, 0xD7, 0x90, 0x01,
+0x34, 0x74, 0x08, 0xF0, 0xFD, 0xE4, 0xFF, 0x02,
+0x6E, 0x99, 0x90, 0x04, 0xEC, 0xE0, 0x44, 0x22,
+0xF0, 0x7D, 0x08, 0xE4, 0xFF, 0x12, 0x4D, 0x6D,
+0x90, 0x06, 0x90, 0xE0, 0x54, 0xF0, 0xF0, 0x90,
+0x02, 0x86, 0xE0, 0x54, 0xFB, 0xF0, 0xD1, 0x0A,
+0x31, 0xAE, 0x7E, 0x00, 0x7F, 0x27, 0x7D, 0x00,
+0x7B, 0x01, 0x7A, 0x81, 0x79, 0xE3, 0x12, 0x46,
+0x4B, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x20, 0xF0,
+0xD1, 0x35, 0x02, 0x58, 0xCC, 0x22, 0x90, 0x81,
+0xE3, 0xF1, 0xA0, 0x30, 0xE0, 0x03, 0x12, 0x58,
+0xCC, 0x22, 0x7F, 0x7C, 0x7E, 0x08, 0x02, 0x2D,
+0x5C, 0x7F, 0x70, 0x7E, 0x0E, 0x12, 0x2E, 0xA2,
+0x90, 0x8A, 0x2E, 0x22, 0x7B, 0x2F, 0x31, 0xD9,
+0x11, 0x7D, 0x7D, 0x08, 0x7F, 0x01, 0x02, 0x69,
+0x45, 0x7D, 0xFF, 0x7F, 0xFF, 0x02, 0x66, 0x73,
+0x12, 0x67, 0xC7, 0x75, 0x16, 0x08, 0x7B, 0x01,
+0x7A, 0x83, 0x79, 0xF2, 0x02, 0x2B, 0xED, 0xF0,
+0x90, 0x01, 0x17, 0xE0, 0xFE, 0x90, 0x01, 0x16,
+0xE0, 0x7C, 0x00, 0x24, 0x00, 0xFF, 0xEC, 0x3E,
+0x22, 0x90, 0x84, 0x89, 0x51, 0xB9, 0xE0, 0xFE,
+0x24, 0x20, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5,
+0x83, 0xE0, 0xFF, 0x74, 0x21, 0x2E, 0x71, 0x63,
+0xE0, 0xFD, 0x90, 0x89, 0x19, 0xE0, 0x24, 0x24,
+0xD1, 0x65, 0x90, 0x89, 0x19, 0xE0, 0x2F, 0x24,
+0x28, 0xA3, 0xF0, 0xE0, 0xFD, 0x24, 0x04, 0x12,
+0x77, 0xE0, 0xE0, 0xFE, 0x74, 0x05, 0x2D, 0x12,
+0x77, 0xD7, 0x31, 0xF8, 0x90, 0x84, 0x30, 0xF0,
+0xA3, 0xEF, 0xF0, 0x90, 0x89, 0x1A, 0xE0, 0x24,
+0x0C, 0xF9, 0xE4, 0x34, 0xFC, 0x12, 0x67, 0xD3,
+0x75, 0x16, 0x04, 0x7B, 0x01, 0x7A, 0x84, 0x79,
+0x32, 0x12, 0x2B, 0xED, 0x90, 0x89, 0x1A, 0xE0,
+0x24, 0x14, 0xF0, 0xE0, 0xFD, 0x24, 0x01, 0x12,
+0x77, 0x19, 0xE0, 0xFE, 0x74, 0x00, 0x2D, 0x12,
+0x75, 0x4A, 0x31, 0xF8, 0x90, 0x84, 0x36, 0xF0,
+0xA3, 0xEF, 0xF0, 0x90, 0x84, 0x8A, 0x51, 0xB9,
+0x90, 0x84, 0x2C, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
+0x4E, 0x60, 0x14, 0x90, 0x89, 0x19, 0xE0, 0x24,
+0x00, 0x12, 0x67, 0xCF, 0x8F, 0x16, 0x7B, 0x01,
+0x7A, 0x84, 0x79, 0x3A, 0x12, 0x2B, 0xED, 0x90,
+0x84, 0x8B, 0x51, 0xB9, 0x24, 0x00, 0x12, 0x67,
+0xCF, 0x90, 0x84, 0x2E, 0xA3, 0xE0, 0xF5, 0x16,
+0x7B, 0x01, 0x7A, 0x84, 0x79, 0x5A, 0x02, 0x2B,
+0xED, 0xE0, 0xFF, 0x51, 0xC3, 0x90, 0x89, 0x19,
+0xEF, 0xF0, 0x22, 0xE4, 0xFE, 0xEF, 0xC3, 0x13,
+0xFD, 0xEF, 0x30, 0xE0, 0x02, 0x7E, 0x80, 0x90,
+0xFD, 0x10, 0xED, 0xF0, 0xAF, 0x06, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8A,
+0x48, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x8A,
+0x47, 0xEF, 0xF0, 0xE4, 0xFD, 0xFC, 0xB1, 0x86,
+0x90, 0x8A, 0x47, 0xE0, 0x90, 0x04, 0x25, 0xF0,
+0x90, 0x8A, 0x48, 0xE0, 0x60, 0x0E, 0x74, 0x0F,
+0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0xE0, 0x44, 0x80, 0xF0, 0xAF, 0x05, 0x74, 0x08,
+0x2F, 0xF1, 0x90, 0xE4, 0xF0, 0x74, 0x09, 0x2F,
+0xF1, 0x98, 0xE0, 0x54, 0xF0, 0xF0, 0xAF, 0x05,
+0x91, 0x34, 0xE0, 0x20, 0xE1, 0x15, 0x54, 0x01,
+0xFE, 0x90, 0x8A, 0x49, 0xE0, 0x25, 0xE0, 0x25,
+0xE0, 0xFB, 0xEE, 0x44, 0x02, 0x4B, 0xFE, 0x91,
+0x34, 0xEE, 0xF0, 0x90, 0x8A, 0x4A, 0xE0, 0xFF,
+0xAE, 0x05, 0x74, 0x1E, 0x2E, 0xF5, 0x82, 0xE4,
+0x34, 0xFC, 0xF5, 0x83, 0xEF, 0xF0, 0x74, 0x21,
+0x2E, 0x71, 0x63, 0xE0, 0x54, 0xF7, 0xF0, 0xAE,
+0x04, 0xAF, 0x05, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x74, 0x21, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC,
+0xF5, 0x83, 0x22, 0x71, 0x98, 0x54, 0x3F, 0xF0,
+0xBF, 0x01, 0x02, 0x80, 0x17, 0xEF, 0x70, 0x02,
+0x80, 0x07, 0x90, 0x81, 0x0D, 0xE0, 0x30, 0xE3,
+0x0B, 0x71, 0x60, 0xE0, 0x54, 0xEF, 0x71, 0x97,
+0x44, 0x40, 0xF0, 0x22, 0x71, 0x60, 0xE0, 0x44,
+0x10, 0x71, 0x97, 0x44, 0x80, 0xF0, 0x22, 0xF0,
+0x74, 0x1F, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC,
+0xF5, 0x83, 0xE0, 0x22, 0x90, 0x80, 0x0B, 0xE0,
+0xFF, 0x90, 0x8A, 0x3F, 0xE0, 0xFB, 0x90, 0x8A,
+0x4A, 0x74, 0x0A, 0xF0, 0x7D, 0x01, 0x51, 0xD7,
+0x90, 0x8A, 0x40, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF,
+0xF0, 0xFD, 0x90, 0x8A, 0x3E, 0xE0, 0xFF, 0x71,
+0x6B, 0x90, 0x8A, 0x40, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0x90, 0x04, 0x80, 0xE0, 0x54, 0x0F, 0xFD,
+0xAC, 0x07, 0x91, 0x47, 0x44, 0x01, 0xF0, 0x91,
+0x47, 0x54, 0xFB, 0xF0, 0xAC, 0x07, 0x74, 0x16,
+0x2C, 0x91, 0x37, 0xE0, 0x44, 0xFA, 0xF0, 0x74,
+0x15, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5,
+0x83, 0xE0, 0x44, 0x1F, 0xF0, 0xAC, 0x07, 0x74,
+0x06, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5,
+0x83, 0xE0, 0x44, 0x0F, 0xF0, 0x90, 0x04, 0x53,
+0xE4, 0xF0, 0x90, 0x04, 0x52, 0xF0, 0x90, 0x04,
+0x51, 0x74, 0xFF, 0xF0, 0x90, 0x04, 0x50, 0x74,
+0xFD, 0xF0, 0x74, 0x14, 0x2C, 0x91, 0x3F, 0xE0,
+0x54, 0xC0, 0x4D, 0xFD, 0x74, 0x14, 0x2F, 0x91,
+0x3F, 0xED, 0xF0, 0x22, 0x74, 0x16, 0x2F, 0xF5,
+0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0xF5,
+0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x74,
+0x11, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5,
+0x83, 0xE0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x12, 0x92, 0x0A, 0xFE, 0x90, 0x81,
+0xE3, 0x12, 0x57, 0xBB, 0xF1, 0x88, 0xFF, 0x90,
+0x81, 0xE3, 0xF1, 0xBA, 0x12, 0x57, 0xC9, 0xF1,
+0x78, 0xFF, 0x90, 0x81, 0xE3, 0xB1, 0x50, 0x12,
+0x57, 0xC9, 0xF1, 0x80, 0xFF, 0x90, 0x81, 0xE3,
+0xF1, 0xB0, 0x12, 0x57, 0x74, 0xFF, 0x54, 0x01,
+0xFE, 0x90, 0x81, 0xE5, 0xE0, 0x54, 0xFE, 0x4E,
+0x12, 0x56, 0x94, 0xFE, 0x54, 0x01, 0xFD, 0x90,
+0x81, 0xE4, 0xF1, 0xA8, 0x54, 0x04, 0xFE, 0xED,
+0x54, 0xFB, 0x4E, 0x12, 0x56, 0x93, 0xFD, 0x54,
+0x08, 0xFC, 0xEE, 0x54, 0xF7, 0x4C, 0xFE, 0x90,
+0x81, 0xE4, 0xF0, 0xED, 0x54, 0x10, 0xFD, 0xEE,
+0x54, 0xEF, 0x4D, 0x12, 0x56, 0x93, 0xFD, 0x54,
+0x20, 0xFC, 0xEE, 0x54, 0xDF, 0x4C, 0x90, 0x81,
+0xE4, 0xF0, 0xEF, 0x54, 0x10, 0xFF, 0xA3, 0xE0,
+0x54, 0xEF, 0x4F, 0xFF, 0x12, 0x57, 0x74, 0xB1,
+0x52, 0x90, 0x81, 0xE5, 0xF0, 0xED, 0x54, 0x02,
+0xFF, 0x90, 0x81, 0xE4, 0xE0, 0x54, 0xFD, 0x4F,
+0x31, 0xEF, 0xB1, 0x8D, 0x90, 0x81, 0xE3, 0xE0,
+0xC3, 0x13, 0x54, 0x01, 0xFF, 0xF1, 0xC4, 0x90,
+0x81, 0xE3, 0xE0, 0x13, 0x13, 0x54, 0x01, 0xFF,
+0xB1, 0x9E, 0x90, 0x81, 0xE4, 0x12, 0x4F, 0xF3,
+0x30, 0xE0, 0x1F, 0x90, 0x81, 0xE3, 0x12, 0x6E,
+0x71, 0x20, 0xE0, 0x0E, 0xEF, 0xC3, 0x13, 0x20,
+0xE0, 0x08, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30,
+0xE0, 0x04, 0x7F, 0x01, 0x80, 0x0E, 0x7F, 0x00,
+0x80, 0x0A, 0x90, 0x81, 0xE3, 0xE0, 0x13, 0x13,
+0x13, 0x54, 0x01, 0xFF, 0xB1, 0x5A, 0x90, 0x81,
+0xE3, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x01, 0xFF,
+0xB1, 0x95, 0x90, 0x81, 0xE3, 0xE0, 0x54, 0x01,
+0xFF, 0x31, 0x2C, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0xF0, 0xEE, 0x54, 0x20, 0xFE, 0xEF, 0x54, 0xDF,
+0x4E, 0x22, 0xE4, 0xFD, 0xFC, 0xEF, 0x60, 0x23,
+0x90, 0x84, 0x82, 0xB1, 0x84, 0x74, 0x00, 0x2F,
+0x12, 0x77, 0xE8, 0x90, 0x89, 0x19, 0x12, 0x44,
+0x72, 0x90, 0x89, 0x19, 0x12, 0x66, 0x5D, 0x75,
+0x16, 0x42, 0x7B, 0x01, 0x7A, 0x82, 0x79, 0xB6,
+0x12, 0x2B, 0xED, 0x22, 0xE0, 0xFF, 0x51, 0xC3,
+0x7C, 0x00, 0xAD, 0x07, 0x22, 0x90, 0x80, 0xFA,
+0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0xEF, 0x60, 0x05,
+0x12, 0x77, 0x21, 0x51, 0x01, 0x22, 0xEF, 0x60,
+0x07, 0x90, 0x84, 0x84, 0xE0, 0xFF, 0xB1, 0xA9,
+0x22, 0x12, 0x67, 0xC7, 0x75, 0x16, 0x70, 0x7B,
+0x01, 0x7A, 0x82, 0x79, 0x1E, 0x02, 0x2B, 0xED,
+0x90, 0x84, 0x81, 0xE0, 0xFF, 0x90, 0x8A, 0x4A,
+0x74, 0x08, 0xF0, 0x7B, 0x18, 0x7D, 0x01, 0x51,
+0xD7, 0x90, 0x89, 0x4E, 0xEF, 0xF0, 0x90, 0x84,
+0x81, 0xE0, 0x90, 0x04, 0x25, 0xF0, 0x22, 0xE4,
+0xFF, 0x74, 0x18, 0xB1, 0xFF, 0x74, 0xF5, 0x2F,
+0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0xEE,
+0xF0, 0x74, 0x10, 0xB1, 0xFF, 0x74, 0xEF, 0x2F,
+0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0xEE,
+0xF0, 0x0F, 0xEF, 0xB4, 0x06, 0xDB, 0x22, 0x2F,
+0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0,
+0xFE, 0x22, 0xD1, 0x35, 0x90, 0x84, 0x8D, 0xE0,
+0xFF, 0x12, 0x94, 0x2C, 0x90, 0x01, 0x3F, 0x74,
+0x04, 0xF0, 0x90, 0x80, 0x07, 0xE0, 0xFF, 0xB4,
+0x01, 0x07, 0x90, 0xFD, 0x00, 0xE0, 0x54, 0xEF,
+0xF0, 0xEF, 0xB4, 0x01, 0x07, 0x90, 0xFE, 0x10,
+0xE0, 0x54, 0xFB, 0xF0, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFD, 0x7F, 0x8F,
+0x12, 0x32, 0x1E, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0xA3, 0xE0, 0xFE, 0x24, 0x20, 0xF5, 0x82, 0xE4,
+0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFF, 0x74, 0x21,
+0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0xE0, 0xFD, 0x74, 0x24, 0x2E, 0xF5, 0x82, 0xE4,
+0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFB, 0xE4, 0xFE,
+0xEF, 0x30, 0xE7, 0x04, 0x7C, 0x02, 0x80, 0x02,
+0xE4, 0xFC, 0xED, 0x30, 0xE6, 0x09, 0xAF, 0x03,
+0x12, 0x93, 0xED, 0xAE, 0x07, 0x80, 0x02, 0xE4,
+0xFE, 0xEC, 0x24, 0x18, 0x2E, 0xFF, 0x22, 0xE4,
+0x90, 0x89, 0x03, 0xF0, 0xA3, 0xF0, 0x90, 0x06,
+0x32, 0xE0, 0x44, 0x20, 0xF0, 0x12, 0x8E, 0x9C,
+0xEF, 0x64, 0x01, 0x70, 0x6A, 0x90, 0x84, 0x89,
+0xE0, 0xFF, 0x90, 0x8A, 0x4A, 0x74, 0x0D, 0xF0,
+0x7B, 0x08, 0x7D, 0x01, 0xF1, 0x18, 0x90, 0x89,
+0x00, 0xD1, 0x48, 0x90, 0x89, 0x02, 0xEF, 0xF0,
+0x90, 0x89, 0x00, 0xF1, 0xD0, 0xE4, 0xFD, 0x12,
+0x56, 0x9B, 0x90, 0x89, 0x02, 0xE0, 0xFF, 0x90,
+0x89, 0x01, 0xE0, 0x2F, 0xFF, 0x90, 0x89, 0x00,
+0xE0, 0x34, 0x00, 0xCF, 0x24, 0x28, 0xCF, 0x34,
+0x00, 0xFE, 0x90, 0x89, 0x03, 0xF0, 0xA3, 0xEF,
+0xF0, 0x12, 0x7F, 0xC1, 0xF1, 0x10, 0xFD, 0x90,
+0x84, 0x89, 0xE0, 0xFB, 0xE4, 0xFF, 0x12, 0x75,
+0x52, 0xF1, 0x10, 0xFD, 0x90, 0x84, 0x85, 0xE0,
+0xFB, 0x7F, 0x11, 0x12, 0x75, 0x52, 0x12, 0x65,
+0x1C, 0x90, 0x84, 0x38, 0x12, 0x78, 0xE3, 0x22,
+0x90, 0x89, 0x03, 0xE0, 0xFC, 0xA3, 0xE0, 0x22,
+0x51, 0xD7, 0x90, 0x89, 0x00, 0xEE, 0xF0, 0xA3,
+0xEF, 0xF0, 0x22, 0x12, 0x93, 0xAE, 0xAD, 0x07,
+0x90, 0x01, 0xC4, 0x74, 0x23, 0xF0, 0x74, 0x87,
+0xA3, 0xF0, 0xED, 0x64, 0x01, 0x60, 0x1E, 0x12,
+0x5C, 0xE6, 0xED, 0xB4, 0x02, 0x08, 0x90, 0x01,
+0xC7, 0x74, 0x40, 0xF0, 0x80, 0x0A, 0xED, 0xB4,
+0x04, 0x06, 0x90, 0x01, 0xC7, 0x74, 0x41, 0xF0,
+0x7F, 0x01, 0x02, 0x70, 0x9D, 0x12, 0x92, 0x7D,
+0x90, 0x02, 0x87, 0xE0, 0x70, 0xF7, 0x90, 0x06,
+0x90, 0xE0, 0x44, 0x02, 0xF0, 0x74, 0x23, 0x04,
+0x90, 0x01, 0xC4, 0xF0, 0x74, 0x87, 0xA3, 0xF0,
+0x22, 0x7F, 0x32, 0x7E, 0x00, 0x02, 0x32, 0xAA,
+0x54, 0x10, 0xFD, 0xEF, 0x54, 0xEF, 0x4D, 0x22,
+0x54, 0x40, 0xFD, 0xEF, 0x54, 0xBF, 0x4D, 0x22,
+0x54, 0x04, 0xFD, 0xEF, 0x54, 0xFB, 0x4D, 0x22,
+0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22,
+0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22,
+0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x22,
+0xE0, 0x54, 0xFE, 0x4D, 0xFD, 0xF0, 0xEE, 0x22,
+0xF0, 0xEE, 0x54, 0x80, 0xFE, 0xEF, 0x54, 0x7F,
+0x4E, 0x22, 0xF0, 0xEE, 0x54, 0x08, 0xFE, 0xEF,
+0x54, 0xF7, 0x4E, 0x22, 0xEF, 0x60, 0x08, 0x90,
+0x84, 0x7F, 0xE0, 0xFF, 0x12, 0x67, 0x5E, 0x22,
+0xA3, 0xE0, 0x24, 0x20, 0xF9, 0xE4, 0x34, 0xFC,
+0xFA, 0x7B, 0x01, 0x22, 0x90, 0x8A, 0x5E, 0xEF,
+0xF0, 0x7F, 0x02, 0x12, 0x48, 0x9E, 0x90, 0x80,
+0x01, 0xE0, 0xFF, 0x90, 0x8A, 0x5E, 0xE0, 0xFE,
+0xEF, 0x4E, 0x90, 0x80, 0x01, 0xF0, 0x22, 0x90,
+0x02, 0x09, 0xE0, 0xF5, 0x52, 0x12, 0x1F, 0xA4,
+0x25, 0x52, 0x90, 0x80, 0x09, 0x12, 0x56, 0x94,
+0x25, 0x52, 0x90, 0x80, 0x0A, 0x12, 0x57, 0x74,
+0x25, 0x52, 0x90, 0x80, 0x0B, 0x12, 0x57, 0xB4,
+0x25, 0x52, 0x90, 0x80, 0x0C, 0x12, 0x55, 0x9B,
+0x25, 0x52, 0x90, 0x80, 0x0D, 0xF0, 0x90, 0x00,
+0x05, 0x12, 0x1F, 0xBD, 0x25, 0x52, 0x90, 0x80,
+0x0E, 0x12, 0x57, 0xD0, 0x25, 0x52, 0x90, 0x80,
+0x0F, 0xF0, 0x22, 0x12, 0x1F, 0xA4, 0x54, 0x01,
+0xFF, 0x90, 0x84, 0xA0, 0xE0, 0x54, 0xFE, 0x4F,
+0xF0, 0x22, 0x51, 0x1C, 0xFF, 0x54, 0x7F, 0x90,
+0x81, 0x0A, 0xF0, 0xEF, 0x12, 0x5F, 0xD8, 0xA3,
+0x12, 0x56, 0x94, 0xFD, 0x54, 0xF0, 0xC4, 0x54,
+0x0F, 0xFF, 0x90, 0x81, 0x08, 0xE0, 0x54, 0xF0,
+0x4F, 0x12, 0x57, 0xB4, 0xFC, 0x54, 0x01, 0x25,
+0xE0, 0xFF, 0x90, 0x81, 0x05, 0xE0, 0x54, 0xFD,
+0x4F, 0xF0, 0xEC, 0x54, 0x04, 0xC3, 0x13, 0xFF,
+0x90, 0x81, 0x07, 0xE0, 0x54, 0xFD, 0x4F, 0xF0,
+0xED, 0x54, 0x0F, 0xC4, 0x54, 0xF0, 0xFF, 0xA3,
+0xE0, 0x54, 0x0F, 0x4F, 0x12, 0x57, 0x74, 0x90,
+0x81, 0x09, 0x12, 0x55, 0x9B, 0xFD, 0x7F, 0x02,
+0x12, 0x69, 0x45, 0x90, 0x89, 0x19, 0x12, 0x44,
+0x69, 0x11, 0xBE, 0x51, 0x30, 0xF0, 0x90, 0x81,
+0x0A, 0x51, 0x25, 0x90, 0x01, 0xBB, 0x12, 0x6F,
+0x7F, 0x90, 0x01, 0xBE, 0xF0, 0x22, 0x90, 0x89,
+0x1C, 0x12, 0x44, 0x72, 0x12, 0x6E, 0xC1, 0x90,
+0x81, 0x0A, 0xE0, 0xFF, 0x12, 0x4D, 0x79, 0x90,
+0x81, 0x0A, 0xE0, 0x60, 0x1D, 0x90, 0x89, 0x1C,
+0x12, 0x44, 0x69, 0x12, 0x56, 0x95, 0x54, 0x0F,
+0xFF, 0x12, 0x57, 0x75, 0xFD, 0x51, 0x45, 0x12,
+0x7F, 0x84, 0x90, 0x8A, 0x52, 0x74, 0x01, 0xF0,
+0x11, 0xF3, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0xAC, 0x07, 0x90, 0x81, 0x06, 0x12,
+0x5F, 0xD7, 0x30, 0xE0, 0x02, 0x21, 0xA9, 0x90,
+0x81, 0x05, 0xE0, 0x30, 0xE0, 0x16, 0x90, 0x81,
+0x27, 0xE0, 0x24, 0x05, 0x90, 0x81, 0x1F, 0xF0,
+0x90, 0x81, 0x27, 0xE0, 0x24, 0x03, 0x90, 0x81,
+0x1E, 0xF0, 0x80, 0x0D, 0x90, 0x81, 0x1F, 0x74,
+0x02, 0xF0, 0x90, 0x81, 0x1E, 0x14, 0xF0, 0x0B,
+0x0B, 0x90, 0x81, 0x1E, 0xE0, 0xFA, 0x90, 0x81,
+0x1D, 0xE0, 0xD3, 0x9A, 0x50, 0x12, 0x90, 0x81,
+0x12, 0xEB, 0xF0, 0x90, 0x81, 0x1F, 0xE0, 0xC3,
+0x9D, 0x2C, 0x90, 0x81, 0x22, 0xF0, 0x80, 0x18,
+0xC3, 0xED, 0x9A, 0x2B, 0x90, 0x81, 0x12, 0xF0,
+0x90, 0x81, 0x1E, 0xE0, 0xFF, 0xA3, 0xE0, 0xC3,
+0x9F, 0x90, 0x81, 0x22, 0x12, 0x7F, 0x7B, 0xF0,
+0x90, 0x81, 0x1F, 0x31, 0xB5, 0xFC, 0x90, 0x81,
+0x22, 0x31, 0xBD, 0x40, 0x04, 0xEF, 0x24, 0x0A,
+0xF0, 0x90, 0x81, 0x22, 0x31, 0xB5, 0xFC, 0x90,
+0x81, 0x12, 0x31, 0xBD, 0x40, 0x04, 0xEF, 0x24,
+0x0A, 0xF0, 0x90, 0x81, 0x22, 0xE0, 0xFF, 0x7E,
+0x00, 0x90, 0x81, 0x16, 0xEE, 0xF0, 0xA3, 0xEF,
+0xF0, 0x90, 0x05, 0x58, 0xE0, 0x6F, 0x70, 0x01,
+0xE4, 0x60, 0x02, 0x51, 0x3B, 0x51, 0x14, 0x80,
+0x07, 0x90, 0x81, 0x07, 0xE0, 0x44, 0x01, 0xF0,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE0, 0xFF, 0x24,
+0x0A, 0xFD, 0xE4, 0x33, 0x22, 0xE0, 0xD3, 0x9D,
+0xEC, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x98, 0x22,
+0x51, 0xD3, 0x90, 0x89, 0x07, 0xEF, 0xF0, 0x30,
+0xE0, 0x05, 0x7D, 0x01, 0xE4, 0x80, 0x02, 0xE4,
+0xFD, 0xFF, 0x12, 0x69, 0x45, 0x90, 0x89, 0x07,
+0xE0, 0x30, 0xE6, 0x11, 0x90, 0x01, 0x2F, 0xE0,
+0x30, 0xE7, 0x04, 0xE4, 0xF0, 0x80, 0x06, 0x90,
+0x01, 0x2F, 0x74, 0x80, 0xF0, 0x90, 0x81, 0x05,
+0xE0, 0x90, 0x04, 0xEC, 0x30, 0xE0, 0x06, 0xE0,
+0x54, 0xDD, 0xF0, 0x80, 0x04, 0xE0, 0x44, 0x22,
+0xF0, 0x12, 0x7F, 0x84, 0x90, 0x8A, 0x52, 0x74,
+0x02, 0xF0, 0x01, 0xF3, 0x90, 0x81, 0x07, 0xE0,
+0x54, 0xFE, 0xF0, 0x22, 0x90, 0x89, 0x19, 0x12,
+0x44, 0x72, 0x02, 0x1F, 0xA4, 0xE0, 0x90, 0x01,
+0xBA, 0xF0, 0x90, 0x81, 0x0C, 0xE0, 0x22, 0xF0,
+0x90, 0x01, 0xB9, 0x74, 0x01, 0xF0, 0x90, 0x01,
+0xB8, 0x22, 0xF0, 0x90, 0x81, 0x16, 0xA3, 0xE0,
+0x90, 0x05, 0x58, 0xF0, 0x22, 0xEF, 0x24, 0xFE,
+0x60, 0x0B, 0x04, 0x70, 0x24, 0x90, 0x81, 0x10,
+0x74, 0x02, 0xF0, 0x80, 0x13, 0xED, 0x70, 0x06,
+0x90, 0x81, 0xDF, 0xE0, 0x80, 0x02, 0xED, 0x14,
+0x90, 0x81, 0x10, 0xF0, 0x90, 0x81, 0x10, 0xE0,
+0xA3, 0xF0, 0x90, 0x81, 0x06, 0xE0, 0x44, 0x08,
+0xF0, 0x22, 0x90, 0x81, 0x05, 0x12, 0x87, 0xA0,
+0x30, 0xE0, 0x1F, 0xEF, 0x54, 0xBF, 0xF0, 0x90,
+0x04, 0xE0, 0xE0, 0x90, 0x81, 0x06, 0x30, 0xE0,
+0x06, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x08, 0xE0,
+0x54, 0xFE, 0x51, 0x2F, 0x74, 0x04, 0xF0, 0x12,
+0x6F, 0x4D, 0xE4, 0xFF, 0x02, 0x72, 0x72, 0x90,
+0x81, 0x05, 0xE0, 0xFF, 0x12, 0x5F, 0xD8, 0x30,
+0xE0, 0x24, 0xEF, 0x54, 0x7F, 0xF0, 0x90, 0x04,
+0xE0, 0xE0, 0x90, 0x81, 0x06, 0x30, 0xE1, 0x06,
+0xE0, 0x44, 0x02, 0xF0, 0x80, 0x07, 0xE0, 0x54,
+0xFD, 0x51, 0x2F, 0x04, 0xF0, 0x90, 0x81, 0x0A,
+0xE0, 0x60, 0x03, 0x12, 0x6F, 0x4D, 0x7F, 0x01,
+0x02, 0x72, 0x72, 0xE4, 0x90, 0x89, 0x09, 0xF0,
+0xA3, 0xF0, 0x90, 0x00, 0x83, 0xE0, 0x90, 0x89,
+0x08, 0xF0, 0x90, 0x00, 0x83, 0xE0, 0xFE, 0x90,
+0x89, 0x08, 0xE0, 0xFF, 0xB5, 0x06, 0x01, 0x22,
+0xC3, 0x90, 0x89, 0x0A, 0xE0, 0x94, 0x64, 0x90,
+0x89, 0x09, 0xE0, 0x94, 0x00, 0x40, 0x0D, 0x90,
+0x01, 0xC0, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0x89,
+0x08, 0xE0, 0xFF, 0x22, 0x90, 0x89, 0x09, 0x12,
+0x78, 0xE3, 0x80, 0xC6, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x80, 0x61, 0xE0, 0xFF,
+0x90, 0x80, 0x60, 0xE0, 0xB5, 0x07, 0x04, 0x7F,
+0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70, 0x44,
+0x90, 0x80, 0x60, 0xE0, 0xFE, 0x75, 0xF0, 0x08,
+0x90, 0x80, 0x10, 0x12, 0x44, 0x5D, 0xE0, 0xFD,
+0xEE, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x11, 0xF9,
+0x74, 0x80, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0xAF,
+0x05, 0x12, 0x55, 0x0E, 0x90, 0x80, 0x60, 0xE0,
+0x04, 0xF0, 0xE0, 0x7F, 0x00, 0xB4, 0x0A, 0x02,
+0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x80,
+0x60, 0xF0, 0x12, 0x50, 0xE3, 0x90, 0x80, 0x01,
+0xE0, 0x44, 0x02, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0xE4, 0x90, 0x80, 0xF8, 0xF0, 0xA3, 0xF0,
+0x90, 0x80, 0x60, 0xF0, 0xA3, 0xF0, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x89,
+0x15, 0x12, 0x44, 0x72, 0x90, 0x8A, 0x57, 0xE0,
+0xFF, 0x04, 0xF0, 0x90, 0x00, 0x01, 0xEF, 0x12,
+0x1F, 0xFC, 0x7F, 0xAF, 0x7E, 0x01, 0x12, 0x7E,
+0x78, 0xEF, 0x60, 0x34, 0x90, 0x89, 0x15, 0x12,
+0x66, 0x5D, 0x90, 0x00, 0x0E, 0x12, 0x1F, 0xBD,
+0x24, 0x02, 0xF5, 0x16, 0x7B, 0x01, 0x7A, 0x01,
+0x79, 0xA0, 0x12, 0x2B, 0xED, 0x90, 0x89, 0x15,
+0x12, 0x44, 0x69, 0x90, 0x00, 0x0E, 0x12, 0x1F,
+0xBD, 0x90, 0x01, 0xAE, 0xF0, 0xA3, 0x74, 0xFF,
+0xF0, 0x90, 0x01, 0xCB, 0xE0, 0x64, 0x80, 0xF0,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFF, 0x90, 0x80,
+0xF9, 0xE0, 0xFE, 0x90, 0x80, 0xF8, 0xE0, 0xFD,
+0xB5, 0x06, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E,
+0x00, 0xEE, 0x64, 0x01, 0x60, 0x45, 0x90, 0x01,
+0xAF, 0xE0, 0x70, 0x0A, 0xED, 0x91, 0x50, 0xFA,
+0x7B, 0x01, 0x71, 0x87, 0x7F, 0x01, 0xEF, 0x60,
+0x32, 0x90, 0x80, 0xF8, 0xE0, 0x04, 0xF0, 0xE0,
+0x7F, 0x00, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF,
+0x60, 0x05, 0xE4, 0x90, 0x80, 0xF8, 0xF0, 0x90,
+0x80, 0xF9, 0xE0, 0xFF, 0x90, 0x80, 0xF8, 0xE0,
+0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F,
+0x00, 0xEF, 0x70, 0x07, 0x90, 0x80, 0x01, 0xE0,
+0x44, 0x04, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x75, 0xF0, 0x0F, 0xA4, 0x24, 0x62, 0xF9, 0x74,
+0x80, 0x35, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x80, 0xF8, 0xE0, 0xFF,
+0x70, 0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A,
+0xEF, 0x14, 0xFF, 0x90, 0x80, 0xF9, 0xE0, 0xB5,
+0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00,
+0xEF, 0x60, 0x09, 0x90, 0x01, 0xC1, 0xE0, 0x44,
+0x02, 0xF0, 0x80, 0x2C, 0xC0, 0x01, 0x90, 0x80,
+0xF9, 0xE0, 0x91, 0x50, 0xA8, 0x01, 0xFC, 0x7D,
+0x01, 0xD0, 0x01, 0x7E, 0x00, 0x7F, 0x0F, 0x12,
+0x43, 0xD0, 0x90, 0x80, 0xF9, 0xE0, 0x04, 0xF0,
+0xE0, 0x7F, 0x00, 0xB4, 0x0A, 0x02, 0x7F, 0x01,
+0xEF, 0x60, 0x05, 0xE4, 0x90, 0x80, 0xF9, 0xF0,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x01, 0x34,
+0x74, 0xFF, 0x12, 0x58, 0xC4, 0x90, 0x01, 0x3C,
+0x12, 0x58, 0xC4, 0xFD, 0x7F, 0x54, 0x12, 0x32,
+0x1E, 0x7D, 0xFF, 0x7F, 0x55, 0x12, 0x32, 0x1E,
+0x7D, 0xFF, 0x7F, 0x56, 0x12, 0x32, 0x1E, 0x7D,
+0xFF, 0x7F, 0x57, 0x02, 0x32, 0x1E, 0x75, 0x3D,
+0x10, 0xE4, 0xF5, 0x3E, 0x75, 0x3F, 0x07, 0x75,
+0x40, 0x02, 0x90, 0x01, 0x30, 0xE5, 0x3D, 0xF0,
+0xA3, 0xE5, 0x3E, 0xF0, 0xA3, 0xE5, 0x3F, 0xF0,
+0xA3, 0xE5, 0x40, 0xF0, 0x22, 0x75, 0x45, 0x07,
+0x75, 0x46, 0x01, 0x75, 0x47, 0x03, 0x75, 0x48,
+0x62, 0x90, 0x01, 0x38, 0xE5, 0x45, 0xF0, 0xA3,
+0xE5, 0x46, 0xF0, 0xA3, 0xE5, 0x47, 0xF0, 0xA3,
+0xE5, 0x48, 0xF0, 0x22, 0x90, 0x01, 0x94, 0xE0,
+0x44, 0x01, 0xF0, 0x90, 0x01, 0xC7, 0xE4, 0xF0,
+0x22, 0x7F, 0x02, 0x90, 0x84, 0x8E, 0xE0, 0xFE,
+0xEF, 0xC3, 0x9E, 0x50, 0x18, 0xEF, 0x25, 0xE0,
+0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE4, 0x0B, 0x90,
+0x01, 0xB8, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x7F,
+0x00, 0x22, 0x0F, 0x80, 0xDE, 0x7F, 0x01, 0x22,
+0xE4, 0x90, 0x80, 0x01, 0x02, 0x58, 0xC2, 0x90,
+0x01, 0xE4, 0x74, 0x1C, 0xF0, 0xA3, 0xE4, 0xF0,
+0x22, 0x90, 0x01, 0x34, 0xE0, 0x55, 0x3D, 0xF5,
+0x41, 0xA3, 0xE0, 0x55, 0x3E, 0xF5, 0x42, 0xA3,
+0xE0, 0x55, 0x3F, 0xF5, 0x43, 0xA3, 0xE0, 0x55,
+0x40, 0xF5, 0x44, 0x90, 0x01, 0x34, 0xE5, 0x41,
+0xF0, 0xA3, 0xE5, 0x42, 0xF0, 0xA3, 0xE5, 0x43,
+0xF0, 0xA3, 0xE5, 0x44, 0xF0, 0x22, 0x90, 0x01,
+0x3C, 0xE0, 0x55, 0x45, 0xF5, 0x49, 0xA3, 0xE0,
+0x55, 0x46, 0xF5, 0x4A, 0xA3, 0xE0, 0x55, 0x47,
+0xF5, 0x4B, 0xA3, 0xE0, 0x55, 0x48, 0xF5, 0x4C,
+0x90, 0x01, 0x3C, 0xE5, 0x49, 0xF0, 0xA3, 0xE5,
+0x4A, 0xF0, 0xA3, 0xE5, 0x4B, 0xF0, 0xA3, 0xE5,
+0x4C, 0xF0, 0x53, 0x91, 0xDF, 0x22, 0x90, 0x81,
+0xE3, 0xE0, 0x30, 0xE0, 0x05, 0x7F, 0x10, 0x12,
+0x50, 0xCE, 0x22, 0x90, 0x01, 0xCF, 0xE0, 0x90,
+0x8A, 0x61, 0xF0, 0xE0, 0xFF, 0x30, 0xE0, 0x07,
+0x90, 0x01, 0xCF, 0xE0, 0x54, 0xFE, 0xF0, 0xEF,
+0x30, 0xE5, 0x23, 0x90, 0x01, 0xCF, 0xE0, 0x54,
+0xDF, 0xF0, 0x90, 0x01, 0x34, 0x74, 0x20, 0xF0,
+0xE4, 0xF5, 0xA8, 0xF5, 0xE8, 0x12, 0x58, 0x9C,
+0x90, 0x00, 0x03, 0xE0, 0x54, 0xFB, 0xFD, 0x7F,
+0x03, 0x12, 0x32, 0x1E, 0x80, 0xFE, 0x22, 0x90,
+0x84, 0x99, 0xE0, 0x04, 0xF0, 0x90, 0x81, 0x0D,
+0xE0, 0x64, 0x02, 0x60, 0x03, 0x12, 0x6D, 0x90,
+0x22, 0x90, 0x81, 0x0A, 0xE0, 0x60, 0x02, 0xD1,
+0x2A, 0x22, 0x90, 0x81, 0x0A, 0xE0, 0x64, 0x01,
+0x70, 0x13, 0x12, 0x6F, 0x80, 0x60, 0x05, 0x12,
+0x66, 0x67, 0x80, 0x0A, 0x90, 0x81, 0x0D, 0xE0,
+0x70, 0x03, 0x12, 0x4D, 0xF6, 0x22, 0x90, 0x81,
+0x05, 0x12, 0x4F, 0xF3, 0x30, 0xE0, 0x05, 0x90,
+0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x06, 0x92, 0x74,
+0x02, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x04, 0xF0,
+0xE4, 0xF5, 0x1D, 0x90, 0x81, 0xDE, 0xE0, 0xC3,
+0x13, 0x54, 0x7F, 0xF5, 0x1E, 0xE4, 0xFB, 0xFD,
+0x7F, 0x58, 0x7E, 0x01, 0x12, 0x6C, 0x40, 0x90,
+0x81, 0x05, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90,
+0x81, 0x0A, 0xE0, 0x60, 0x0E, 0x90, 0x06, 0x92,
+0xE0, 0x30, 0xE1, 0x02, 0x80, 0xB8, 0xD1, 0x94,
+0x12, 0x6F, 0x4D, 0x22, 0x90, 0x81, 0x05, 0xE0,
+0x54, 0xF7, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x04, 0x1D, 0xE0, 0x60,
+0x1A, 0x90, 0x05, 0x22, 0xE0, 0x54, 0x90, 0x60,
+0x07, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x08, 0xF0,
+0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE1, 0xE4, 0x7F,
+0x00, 0x80, 0x02, 0x7F, 0x01, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0xC3, 0xEE, 0x94, 0x01, 0x40, 0x0A,
+0x0D, 0xED, 0x13, 0x90, 0xFD, 0x10, 0xF0, 0xE4,
+0x2F, 0xFF, 0x22, 0xC3, 0xEE, 0x94, 0x01, 0x40,
+0x1E, 0x90, 0xFD, 0x11, 0xE0, 0xB5, 0x05, 0x14,
+0x90, 0x01, 0x17, 0xE0, 0xB5, 0x05, 0x07, 0x90,
+0xFD, 0x11, 0xE4, 0xF0, 0x80, 0x06, 0xED, 0x04,
+0x90, 0xFD, 0x11, 0xF0, 0xE4, 0x2F, 0xFF, 0x22,
+0xFF, 0xEE, 0x3C, 0xFE, 0x90, 0x89, 0x2B, 0xE0,
+0xFD, 0xD1, 0xDB, 0x90, 0x89, 0x2C, 0xE0, 0x22,
+0x12, 0x5F, 0xB3, 0xA3, 0xED, 0xF0, 0xE4, 0xA3,
+0xF0, 0x90, 0x89, 0x2C, 0xE0, 0xFF, 0xC3, 0x94,
+0x02, 0x50, 0x21, 0xF1, 0xB3, 0x12, 0x61, 0xA7,
+0xFC, 0x7E, 0x00, 0xED, 0x2F, 0xF1, 0x00, 0x24,
+0x5A, 0xF5, 0x82, 0xE4, 0x34, 0x84, 0x12, 0x5F,
+0x9B, 0xB5, 0x06, 0x1D, 0x90, 0x89, 0x2C, 0xE0,
+0x04, 0xF0, 0x80, 0xD5, 0x90, 0x06, 0x32, 0xE0,
+0x44, 0x80, 0xF0, 0x90, 0x01, 0xC7, 0x74, 0x30,
+0xF0, 0x7F, 0x01, 0x12, 0x70, 0x9D, 0x7F, 0x01,
+0x22, 0x7F, 0x00, 0x22, 0x12, 0x5F, 0xB3, 0xA3,
+0xED, 0xF0, 0x90, 0x84, 0x2C, 0xE0, 0x70, 0x02,
+0xA3, 0xE0, 0x60, 0x33, 0xE4, 0x90, 0x89, 0x2C,
+0xF0, 0x90, 0x89, 0x2C, 0xE0, 0xFE, 0xC3, 0x94,
+0x02, 0x50, 0x27, 0xF1, 0xB3, 0x12, 0x61, 0xA7,
+0xFC, 0xEE, 0x7E, 0x00, 0x2D, 0xF1, 0x00, 0x24,
+0x3A, 0xF5, 0x82, 0xE4, 0x34, 0x84, 0x12, 0x5F,
+0x9B, 0x6E, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90,
+0x89, 0x2C, 0xE0, 0x04, 0xF0, 0x80, 0xD2, 0x7F,
+0x00, 0x22, 0x90, 0x06, 0x32, 0xE0, 0x44, 0x40,
+0xF0, 0xE4, 0x90, 0x84, 0x38, 0xF0, 0xA3, 0xF0,
+0x7F, 0x01, 0x22, 0x90, 0x89, 0x2A, 0xE0, 0x24,
+0x1C, 0xFD, 0x22, 0xEF, 0x64, 0x01, 0x70, 0x31,
+0x90, 0x81, 0xE8, 0xE0, 0xFA, 0x54, 0x7F, 0xFF,
+0x7E, 0x00, 0xC0, 0x07, 0x90, 0x81, 0xEA, 0xE0,
+0x13, 0x13, 0x54, 0x01, 0xFD, 0x90, 0x81, 0xE9,
+0xE0, 0xF9, 0xC3, 0x13, 0x54, 0x7F, 0xFB, 0xE9,
+0x54, 0x01, 0x90, 0x89, 0x38, 0xF0, 0xEA, 0x12,
+0x5F, 0xD8, 0xA3, 0xF0, 0xD0, 0x07, 0x12, 0x52,
+0xBE, 0x22, 0x90, 0x04, 0x1A, 0xE0, 0xF4, 0x60,
+0x03, 0x7F, 0x00, 0x22, 0x90, 0x04, 0x1B, 0xE0,
+0x54, 0x07, 0x64, 0x07, 0x7F, 0x01, 0x60, 0x02,
+0x7F, 0x00, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x12, 0x8F, 0xF2, 0xEF, 0x64, 0x01,
+0x60, 0x05, 0x75, 0x58, 0x01, 0x80, 0x41, 0x90,
+0x81, 0x0E, 0xE0, 0xFF, 0x54, 0x03, 0x60, 0x05,
+0x75, 0x58, 0x02, 0x80, 0x33, 0xEF, 0x30, 0xE2,
+0x05, 0x75, 0x58, 0x08, 0x80, 0x2A, 0x90, 0x81,
+0x0E, 0xE0, 0x30, 0xE4, 0x05, 0x75, 0x58, 0x10,
+0x80, 0x1E, 0x12, 0x6F, 0xEC, 0x20, 0xE0, 0x05,
+0x75, 0x58, 0x20, 0x80, 0x13, 0x11, 0x7B, 0x8F,
+0x59, 0xE5, 0x59, 0x64, 0x01, 0x60, 0x05, 0x85,
+0x59, 0x58, 0x80, 0x04, 0x11, 0x73, 0x80, 0x0E,
+0x90, 0x01, 0xB9, 0x74, 0x04, 0xF0, 0x90, 0x01,
+0xB8, 0xE5, 0x58, 0xF0, 0x7F, 0x00, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0x90, 0x01, 0xB8, 0xE4, 0xF0,
+0x7F, 0x01, 0x22, 0x90, 0x81, 0x0C, 0xE0, 0xD3,
+0x94, 0x00, 0x40, 0x06, 0x75, 0x52, 0x04, 0x7F,
+0xFF, 0x22, 0x90, 0x81, 0xE2, 0xE0, 0x60, 0x06,
+0x75, 0x52, 0x80, 0x7F, 0xFF, 0x22, 0x7F, 0x01,
+0x22, 0x90, 0x02, 0x87, 0xE0, 0x60, 0x02, 0x80,
+0x08, 0x90, 0x01, 0x00, 0xE0, 0x64, 0x3F, 0x60,
+0x05, 0x75, 0x51, 0x01, 0x80, 0x40, 0x90, 0x81,
+0xE3, 0xE0, 0x30, 0xE0, 0x0B, 0x90, 0x02, 0x82,
+0xE0, 0x60, 0x05, 0x75, 0x51, 0x02, 0x80, 0x2E,
+0x90, 0x81, 0xEE, 0xE0, 0x30, 0xE0, 0x05, 0x75,
+0x51, 0x08, 0x80, 0x22, 0x90, 0x02, 0x86, 0xE0,
+0x20, 0xE1, 0x02, 0x80, 0x07, 0x90, 0x02, 0x86,
+0xE0, 0x30, 0xE3, 0x05, 0x75, 0x51, 0x04, 0x80,
+0x0D, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x05, 0x75,
+0x51, 0x40, 0x80, 0x02, 0x80, 0x85, 0x90, 0x01,
+0xB9, 0x74, 0x08, 0xF0, 0x90, 0x01, 0xB8, 0xE5,
+0x51, 0xF0, 0x7F, 0x00, 0x22, 0x7B, 0x2E, 0x31,
+0x08, 0x7D, 0x02, 0x7F, 0x01, 0x02, 0x69, 0x45,
+0x7D, 0x6F, 0x7F, 0xFF, 0x02, 0x66, 0x73, 0x90,
+0x81, 0xD6, 0x74, 0x18, 0xF0, 0xA3, 0x74, 0x03,
+0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0x74, 0x64, 0xF0,
+0xA3, 0x74, 0x05, 0xF0, 0xA3, 0xF0, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8A,
+0x64, 0xEF, 0xF0, 0x7E, 0x00, 0x7F, 0xA0, 0x7D,
+0x00, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0x28, 0x12,
+0x46, 0x4B, 0xE4, 0x90, 0x81, 0x21, 0xF0, 0x90,
+0x81, 0x20, 0xF0, 0x90, 0x81, 0x24, 0xF0, 0x90,
+0x8A, 0x64, 0xE0, 0xB4, 0x01, 0x09, 0x90, 0x81,
+0x25, 0x74, 0x14, 0xF0, 0xE4, 0xA3, 0xF0, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x12, 0x80, 0x18, 0x12,
+0x66, 0x6E, 0x7D, 0x0C, 0x7F, 0x01, 0x02, 0x69,
+0x45, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x90, 0x8A, 0x65, 0xEF, 0xF0, 0xC3, 0x94, 0x02,
+0x50, 0x44, 0x90, 0x80, 0x0B, 0xE0, 0xFF, 0x90,
+0x04, 0x1C, 0xE0, 0x6F, 0x70, 0x38, 0x90, 0x81,
+0x0D, 0xE0, 0x64, 0x0E, 0x70, 0x15, 0x90, 0x8A,
+0x65, 0xE0, 0x70, 0x2A, 0x90, 0x81, 0x05, 0xE0,
+0x54, 0x7F, 0xF0, 0x12, 0x6F, 0xBB, 0x12, 0x69,
+0x41, 0x80, 0x18, 0x90, 0x81, 0x0D, 0xE0, 0x64,
+0x06, 0x70, 0x13, 0x90, 0x8A, 0x65, 0xE0, 0x60,
+0x0D, 0x31, 0xCB, 0x31, 0xD3, 0x90, 0x81, 0x0D,
+0x74, 0x04, 0xF0, 0x12, 0x66, 0x6E, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0x90, 0x81, 0x05, 0xE0, 0x54,
+0xBF, 0xF0, 0x22, 0x90, 0x06, 0x04, 0xE0, 0x44,
+0x40, 0xF0, 0xE0, 0x44, 0x80, 0xF0, 0x22, 0x51,
+0x0A, 0xFE, 0x90, 0x84, 0x8F, 0xE0, 0x54, 0xFE,
+0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x04, 0xFF, 0xEE,
+0x54, 0xFB, 0x4F, 0xF0, 0x12, 0x1F, 0xA4, 0xC3,
+0x13, 0x30, 0xE0, 0x07, 0x12, 0x56, 0x95, 0x90,
+0x84, 0x90, 0xF0, 0x22, 0x90, 0x89, 0x19, 0x12,
+0x44, 0x69, 0x12, 0x1F, 0xA4, 0xFF, 0x54, 0x01,
+0x22, 0x90, 0x89, 0x19, 0x12, 0x44, 0x72, 0x51,
+0x55, 0x51, 0x04, 0xFE, 0x12, 0x70, 0x8E, 0x4E,
+0xF0, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x2D, 0x12,
+0x56, 0x95, 0x90, 0x84, 0x94, 0x12, 0x57, 0x74,
+0x90, 0x84, 0x95, 0xF0, 0x12, 0x1F, 0xA4, 0xFF,
+0x54, 0x04, 0xFE, 0x90, 0x84, 0x93, 0xE0, 0x54,
+0xFB, 0x12, 0x57, 0xB3, 0x90, 0x84, 0x96, 0xF0,
+0xEF, 0x54, 0x08, 0xFF, 0x90, 0x84, 0x93, 0xE0,
+0x54, 0xF7, 0x4F, 0xF0, 0x22, 0x7E, 0x00, 0x7F,
+0x08, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x84, 0x79,
+0x93, 0x12, 0x46, 0x4B, 0x90, 0x84, 0x94, 0x74,
+0x08, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0x22, 0x90,
+0x02, 0x84, 0xEF, 0xF0, 0xEE, 0xA3, 0xF0, 0xA3,
+0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90, 0x01, 0x1F,
+0xE0, 0xFE, 0x90, 0x01, 0x1E, 0x12, 0x81, 0xF8,
+0x90, 0x89, 0x19, 0x71, 0x77, 0xE0, 0x90, 0x89,
+0x1D, 0xF0, 0x90, 0x81, 0xE3, 0xE0, 0x20, 0xE0,
+0x02, 0x61, 0x2F, 0x90, 0x89, 0x1D, 0xE0, 0xFF,
+0xEC, 0xC3, 0x9F, 0x40, 0x02, 0x61, 0x2F, 0x90,
+0x89, 0x19, 0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0x71,
+0x7F, 0xAD, 0x07, 0x74, 0x02, 0x2D, 0x71, 0x9E,
+0xF9, 0x71, 0x30, 0xFE, 0x74, 0x00, 0x2D, 0x12,
+0x5F, 0xA2, 0x71, 0x5F, 0x54, 0x3F, 0x90, 0x89,
+0x1B, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x03, 0x2D,
+0x71, 0x87, 0xFF, 0x7E, 0x00, 0xAD, 0x01, 0xED,
+0x24, 0x18, 0xFB, 0xEA, 0x33, 0xCB, 0x2F, 0xFF,
+0xEE, 0x3B, 0x90, 0x89, 0x1B, 0x8F, 0xF0, 0x12,
+0x43, 0xF6, 0x90, 0x89, 0x1B, 0xE0, 0xFE, 0xA3,
+0xE0, 0xFF, 0x71, 0x3C, 0x90, 0x89, 0x1B, 0xEE,
+0x71, 0x6F, 0xEE, 0x8F, 0xF0, 0x71, 0x67, 0xFE,
+0xA3, 0xE0, 0xFF, 0xD3, 0x90, 0x89, 0x1A, 0xE0,
+0x9F, 0x90, 0x89, 0x19, 0xE0, 0x9E, 0x40, 0x12,
+0x90, 0x80, 0xFB, 0x71, 0x92, 0xC3, 0x90, 0x89,
+0x1A, 0xE0, 0x9F, 0xF0, 0x90, 0x89, 0x19, 0xE0,
+0x9E, 0xF0, 0x90, 0x89, 0x19, 0xE0, 0xFE, 0xA3,
+0xE0, 0xFF, 0x51, 0x6F, 0x0C, 0x41, 0x9B, 0x22,
+0x74, 0x01, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB,
+0xF5, 0x83, 0xE0, 0x22, 0x7D, 0x7F, 0xEF, 0x5D,
+0xC3, 0x60, 0x0B, 0x71, 0x53, 0x5F, 0x24, 0x80,
+0xFF, 0xE4, 0x3E, 0xFE, 0x80, 0x04, 0x71, 0x53,
+0x5F, 0xFF, 0x22, 0x74, 0xFF, 0x9D, 0xFD, 0x74,
+0xFF, 0x94, 0x00, 0x5E, 0xFE, 0xED, 0x22, 0x7A,
+0x00, 0x24, 0x00, 0xFF, 0xEA, 0x3E, 0x22, 0x12,
+0x43, 0xF6, 0x90, 0x80, 0xFA, 0xE0, 0x22, 0xF0,
+0xA3, 0xEF, 0xF0, 0x90, 0x89, 0x19, 0x22, 0xF0,
+0xA3, 0xEF, 0xF0, 0x90, 0x02, 0x87, 0x22, 0xEA,
+0x90, 0xFD, 0x11, 0xF0, 0xAF, 0x03, 0x22, 0xF5,
+0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x54,
+0x03, 0x22, 0xE0, 0x24, 0x01, 0xFF, 0x90, 0x80,
+0xFA, 0xE0, 0x34, 0x00, 0xFE, 0x22, 0xF5, 0x82,
+0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x54, 0x0F,
+0x33, 0x33, 0x33, 0x54, 0xF8, 0x22, 0x90, 0x02,
+0x86, 0xE0, 0x20, 0xE2, 0x03, 0x7F, 0x04, 0x22,
+0x90, 0x02, 0x86, 0xE0, 0x7F, 0x01, 0x20, 0xE1,
+0x02, 0x7F, 0x02, 0x22, 0x90, 0x81, 0xEE, 0xE0,
+0x30, 0xE0, 0x0D, 0x90, 0x81, 0xE6, 0xE0, 0xC4,
+0x54, 0x0F, 0x20, 0xE0, 0x03, 0x7F, 0x00, 0x22,
+0x7F, 0x01, 0x22, 0xEF, 0x90, 0x01, 0xC7, 0xB4,
+0xA0, 0x05, 0x74, 0x04, 0xF0, 0x80, 0x03, 0x74,
+0x08, 0xF0, 0x02, 0x5C, 0xE6, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0xEF, 0x20, 0xE0, 0x05,
+0x90, 0x84, 0x7C, 0x80, 0x03, 0x90, 0x84, 0x7D,
+0xE0, 0x90, 0x84, 0x23, 0xF0, 0x90, 0x84, 0x23,
+0xE0, 0x14, 0x60, 0x13, 0x14, 0x60, 0x14, 0x24,
+0xFE, 0x60, 0x10, 0x14, 0x60, 0x09, 0x14, 0x60,
+0x06, 0x24, 0x06, 0xE4, 0xFE, 0x80, 0x06, 0x7E,
+0x04, 0x80, 0x02, 0x7E, 0x08, 0xAF, 0x06, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x90, 0x89, 0x1C, 0xEF,
+0xF0, 0xE4, 0xFF, 0x74, 0xF2, 0x2F, 0xF5, 0x82,
+0xE4, 0x34, 0x83, 0xF5, 0x83, 0xE0, 0xFE, 0x74,
+0xA4, 0x12, 0x6E, 0xEC, 0x0F, 0xEF, 0xB4, 0x08,
+0xEA, 0x90, 0x84, 0x22, 0xE0, 0x90, 0x04, 0x4C,
+0xF0, 0x90, 0x84, 0x24, 0xE0, 0x90, 0x04, 0x4D,
+0xF0, 0x75, 0x13, 0x01, 0x75, 0x14, 0x83, 0x75,
+0x15, 0x01, 0x75, 0x16, 0x08, 0x7B, 0x01, 0x7A,
+0x83, 0x79, 0xFA, 0x12, 0x2B, 0xED, 0x90, 0x84,
+0x8D, 0xE0, 0x60, 0x22, 0x90, 0x89, 0x1C, 0xE0,
+0xFF, 0x12, 0x82, 0xC3, 0x7E, 0x00, 0x74, 0x00,
+0x2F, 0x12, 0x77, 0xE8, 0xC0, 0x03, 0x8B, 0x13,
+0x75, 0x14, 0x83, 0x75, 0x15, 0xF2, 0x75, 0x16,
+0x34, 0xD0, 0x03, 0x12, 0x2B, 0xED, 0x22, 0x90,
+0x89, 0x56, 0x91, 0xCB, 0x2F, 0xFF, 0xE4, 0x3E,
+0xCF, 0x24, 0x06, 0xCF, 0x12, 0x5E, 0xDB, 0xBF,
+0x86, 0x1E, 0x90, 0x89, 0x58, 0xE0, 0xFF, 0x90,
+0x89, 0x57, 0xE0, 0x2F, 0xFF, 0x90, 0x89, 0x56,
+0xE0, 0x34, 0x00, 0xCF, 0x24, 0x07, 0xCF, 0x12,
+0x5E, 0xDB, 0xBF, 0xDD, 0x03, 0x7F, 0x01, 0x22,
+0x7F, 0x00, 0x22, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0,
+0xA3, 0xED, 0xF0, 0x22, 0x90, 0x89, 0x90, 0x12,
+0x44, 0x72, 0x90, 0x89, 0x93, 0x12, 0x66, 0x5D,
+0x75, 0x16, 0x10, 0x7B, 0x01, 0x7A, 0x82, 0x79,
+0x8E, 0x12, 0x2B, 0xED, 0x90, 0x89, 0x90, 0x12,
+0x66, 0x5D, 0x75, 0x16, 0x10, 0x7B, 0x01, 0x7A,
+0x82, 0x79, 0x9E, 0x12, 0x2B, 0xED, 0x90, 0x89,
+0x96, 0x12, 0x44, 0x45, 0x90, 0x82, 0xAE, 0x12,
+0x20, 0xCE, 0x90, 0x89, 0x9A, 0xE0, 0x90, 0x82,
+0xB5, 0xF0, 0x22, 0x12, 0x1F, 0xA4, 0x90, 0x84,
+0x7C, 0x12, 0x56, 0x94, 0x90, 0x84, 0x7D, 0xF0,
+0x22, 0xB1, 0x67, 0x90, 0x84, 0x85, 0x12, 0x56,
+0x94, 0xFF, 0xED, 0x2F, 0x90, 0x84, 0x86, 0x12,
+0x57, 0x74, 0xFF, 0xED, 0x2F, 0x90, 0x84, 0x87,
+0x12, 0x57, 0xB4, 0xFF, 0xED, 0x2F, 0x90, 0x84,
+0x88, 0x12, 0x55, 0x9B, 0xFF, 0xED, 0x2F, 0x90,
+0x84, 0x89, 0xB1, 0x5C, 0x90, 0x84, 0x8A, 0x12,
+0x57, 0xD0, 0xFF, 0xAE, 0x05, 0xED, 0x2F, 0x90,
+0x84, 0x8B, 0xF0, 0x22, 0xF0, 0x90, 0x00, 0x05,
+0x12, 0x1F, 0xBD, 0xFF, 0xED, 0x2F, 0x22, 0x90,
+0x02, 0x09, 0xE0, 0xFD, 0x12, 0x1F, 0xA4, 0xFE,
+0xAF, 0x05, 0xED, 0x2E, 0x22, 0xB1, 0x67, 0x90,
+0x84, 0x8C, 0x12, 0x56, 0x94, 0xFF, 0xAE, 0x05,
+0xED, 0x2F, 0x90, 0x84, 0x8D, 0xF0, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x84,
+0x7D, 0xE0, 0xFD, 0xB4, 0x02, 0x07, 0xD1, 0x64,
+0x74, 0x08, 0xF0, 0x80, 0x09, 0xED, 0xB4, 0x04,
+0x05, 0xD1, 0x64, 0x74, 0x10, 0xF0, 0xEF, 0x64,
+0x02, 0x4E, 0x60, 0x08, 0xEF, 0x64, 0x01, 0x4E,
+0x60, 0x02, 0xC1, 0x5F, 0x90, 0x82, 0xF9, 0xE0,
+0xFF, 0x64, 0xFE, 0x70, 0x02, 0xC1, 0x5F, 0xEF,
+0x64, 0x02, 0x60, 0x07, 0xEF, 0x64, 0x03, 0x60,
+0x02, 0xC1, 0x5F, 0x90, 0x83, 0x59, 0xD1, 0x6C,
+0x90, 0x89, 0x82, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0,
+0x7E, 0x00, 0x7F, 0x28, 0x7D, 0x00, 0x7B, 0x01,
+0x7A, 0x89, 0x79, 0x58, 0x12, 0x46, 0x4B, 0x7B,
+0x01, 0x7A, 0x83, 0x79, 0x5B, 0x90, 0x86, 0x67,
+0x12, 0x44, 0x72, 0x7A, 0x89, 0x79, 0x58, 0x90,
+0x86, 0x6A, 0x12, 0x44, 0x72, 0x7A, 0x82, 0x79,
+0xC8, 0x7D, 0x03, 0x12, 0x02, 0x00, 0x75, 0x13,
+0x01, 0x75, 0x14, 0x89, 0x75, 0x15, 0x60, 0x75,
+0x16, 0x20, 0x7B, 0x01, 0x7A, 0x89, 0x79, 0x37,
+0x12, 0x2B, 0xED, 0x90, 0x89, 0x5E, 0xE0, 0x54,
+0x03, 0x90, 0x89, 0x57, 0xF0, 0xC3, 0x94, 0x04,
+0x50, 0x1C, 0xE0, 0x90, 0x84, 0x22, 0xF0, 0x75,
+0x13, 0x01, 0x75, 0x14, 0x89, 0x75, 0x15, 0x37,
+0x75, 0x16, 0x20, 0x7B, 0x01, 0x7A, 0x84, 0x79,
+0x02, 0x12, 0x2B, 0xED, 0x80, 0x06, 0x90, 0x84,
+0x22, 0x74, 0x05, 0xF0, 0x90, 0x89, 0x57, 0xE0,
+0xFF, 0x90, 0x84, 0x7D, 0xE0, 0xFD, 0x7B, 0x01,
+0x7A, 0x89, 0x79, 0x37, 0x12, 0x58, 0xEA, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x90, 0x89, 0x80, 0x74,
+0x80, 0xF0, 0xA3, 0x22, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFD, 0xED, 0xFF, 0x22, 0x90, 0x84, 0xF8, 0xED,
+0xF0, 0x90, 0x84, 0xF5, 0x12, 0x44, 0x72, 0x12,
+0x57, 0xB5, 0x90, 0x84, 0xFC, 0xF0, 0x90, 0x84,
+0xF5, 0x12, 0x66, 0x5D, 0x75, 0x16, 0x03, 0x7B,
+0x01, 0x7A, 0x84, 0x79, 0xF9, 0x12, 0x2B, 0xED,
+0x90, 0x84, 0xF8, 0xE0, 0x70, 0x2E, 0xFF, 0xD1,
+0xCD, 0xE0, 0xB4, 0xFF, 0x06, 0xD1, 0xCD, 0xE4,
+0xF0, 0x80, 0x07, 0xD1, 0xCD, 0xE0, 0x04, 0xF0,
+0x80, 0x05, 0x0F, 0xEF, 0xB4, 0x03, 0xE8, 0x75,
+0x13, 0x01, 0x75, 0x14, 0x84, 0x75, 0x15, 0xF9,
+0x75, 0x16, 0x03, 0x90, 0x84, 0xF5, 0x12, 0x44,
+0x69, 0x12, 0x2B, 0xED, 0x22, 0x74, 0xF9, 0x2F,
+0xF5, 0x82, 0xE4, 0x34, 0x84, 0xF5, 0x83, 0x22,
+0x74, 0x10, 0x2F, 0xF9, 0xE4, 0x34, 0xFB, 0xA8,
+0x01, 0xFC, 0x7D, 0x01, 0x7B, 0x01, 0x7A, 0x84,
+0x79, 0x32, 0xD1, 0xF3, 0x7F, 0x01, 0x60, 0x02,
+0x7F, 0x00, 0x22, 0x7E, 0x00, 0x7F, 0x04, 0x12,
+0x46, 0x27, 0xEF, 0x22, 0xAD, 0x07, 0xAB, 0x05,
+0x74, 0x17, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFB,
+0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x16, 0x2B, 0xF5,
+0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0x12, 0x81,
+0xF8, 0xFE, 0x90, 0x84, 0x36, 0xE0, 0x6E, 0x70,
+0x03, 0xA3, 0xE0, 0x6F, 0x7F, 0x01, 0x60, 0x02,
+0x7F, 0x00, 0x22, 0x90, 0x89, 0x53, 0xE4, 0x75,
+0xF0, 0x08, 0x12, 0x43, 0xF6, 0x90, 0x89, 0x53,
+0xE4, 0x75, 0xF0, 0x08, 0x02, 0x43, 0xF6, 0x90,
+0x05, 0x63, 0xE0, 0x90, 0x81, 0xD2, 0xF0, 0x90,
+0x05, 0x62, 0xE0, 0x90, 0x81, 0xD3, 0xF0, 0x90,
+0x05, 0x61, 0xE0, 0x90, 0x81, 0xD4, 0xF0, 0x90,
+0x05, 0x60, 0xE0, 0x90, 0x81, 0xD5, 0xF0, 0x90,
+0x81, 0x06, 0xE0, 0x44, 0x80, 0xF0, 0x22, 0x90,
+0x81, 0xC9, 0xE0, 0x24, 0x01, 0xFF, 0x90, 0x81,
+0xC8, 0xE0, 0x34, 0x00, 0xFE, 0x12, 0x32, 0xAA,
+0x90, 0x81, 0x0D, 0x22, 0x90, 0x86, 0x55, 0x12,
+0x44, 0x72, 0x90, 0x84, 0xD8, 0x12, 0x44, 0x45,
+0x90, 0x86, 0x58, 0x02, 0x20, 0xCE, 0xF5, 0x83,
+0xEF, 0xF0, 0x90, 0x89, 0x52, 0xE0, 0x04, 0xF0,
+0x22, 0xE0, 0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8,
+0x07, 0x08, 0x22, 0x2F, 0xF5, 0x82, 0x74, 0x01,
+0x3E, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x80, 0x61,
+0xE0, 0x75, 0xF0, 0x08, 0x22, 0x90, 0x89, 0x50,
+0xE0, 0xFF, 0x24, 0x01, 0xF5, 0x82, 0xE4, 0x34,
+0x83, 0xF5, 0x83, 0xE0, 0xFE, 0x22, 0x24, 0x40,
+0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0x22,
+0x12, 0x44, 0x5D, 0xE5, 0x82, 0x29, 0xF5, 0x82,
+0xE4, 0x35, 0x83, 0xF5, 0x83, 0xEF, 0xF0, 0x22,
+0x7E, 0x00, 0x7F, 0x04, 0x02, 0x43, 0xD0, 0x90,
+0x84, 0xA4, 0x12, 0x44, 0x72, 0xE4, 0x90, 0x84,
+0xA7, 0xF0, 0x22, 0x7B, 0x01, 0x7A, 0x83, 0x79,
+0xF2, 0x90, 0x8A, 0x3B, 0xE0, 0xFD, 0x22, 0x90,
+0x81, 0xDC, 0xE0, 0xFF, 0x90, 0x81, 0x13, 0xE0,
+0xD3, 0x9F, 0x22, 0xEF, 0x13, 0x13, 0x13, 0x54,
+0x1F, 0xFE, 0xEF, 0x54, 0x07, 0xFF, 0x22, 0x90,
+0x89, 0x53, 0xE4, 0x75, 0xF0, 0x02, 0x02, 0x43,
+0xF6, 0x90, 0x84, 0xD3, 0xE0, 0xC3, 0x13, 0x90,
+0xFD, 0x10, 0xF0, 0x22, 0x7D, 0x01, 0x7E, 0x00,
+0x7F, 0x10, 0x12, 0x46, 0x27, 0xEF, 0x22, 0x54,
+0xFB, 0xF0, 0x90, 0x81, 0x0E, 0xE0, 0x54, 0xFD,
+0xF0, 0x22, 0x24, 0x28, 0xF9, 0xE4, 0x34, 0xFC,
+0xFA, 0x7B, 0x01, 0x22, 0x75, 0x14, 0x82, 0x75,
+0x15, 0xFF, 0x75, 0x16, 0x02, 0x22, 0x12, 0x2B,
+0xED, 0x90, 0x8A, 0x53, 0x22, 0xF0, 0x90, 0x89,
+0x50, 0xE0, 0x04, 0xF0, 0x22, 0x24, 0x04, 0xF5,
+0x82, 0xE4, 0x34, 0xFB, 0x22, 0xF9, 0xEE, 0x34,
+0xFC, 0xFA, 0x7B, 0x01, 0x22, 0x90, 0x82, 0x1E,
+0x12, 0x44, 0x5D, 0xE0, 0x22, 0x7E, 0x00, 0x7F,
+0x10, 0x02, 0x43, 0xD0, 0x90, 0x81, 0x06, 0xE0,
+0x44, 0x04, 0xF0, 0x22, 0x2F, 0xF8, 0xE6, 0xFE,
+0xED, 0xF4, 0x5E, 0x22, 0xCD, 0x91
+};
+
+u32 array_length_mp_8188e_s_fw_wowlan = 22710;
+
+#endif /*CONFIG_WOWLAN*/
+
+#endif /* end of LOAD_FW_HEADER_FROM_DRIVER */
+
+#endif /* end of CONFIG_SFW_SUPPORTED */
diff --git a/drivers/staging/rtl8188eu/hal/hal8188e_s_fw.h b/drivers/staging/rtl8188eu/hal/hal8188e_s_fw.h
new file mode 100644
index 000000000000..71b0ecac0c01
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal8188e_s_fw.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef _FW_HEADER_8188E_S_H
+#define _FW_HEADER_8188E_S_H
+
+#ifdef CONFIG_SFW_SUPPORTED
+
+#ifdef LOAD_FW_HEADER_FROM_DRIVER
+#if defined(CONFIG_AP_WOWLAN)
+extern u8 array_mp_8188e_s_fw_ap[16054];
+extern u32 array_length_mp_8188e_s_fw_ap;
+#endif
+
+extern u8 array_mp_8188e_s_fw_nic[19206];
+extern u32 array_length_mp_8188e_s_fw_nic;
+#ifdef CONFIG_WOWLAN
+extern u8 array_mp_8188e_s_fw_wowlan[22710];
+extern u32 array_length_mp_8188e_s_fw_wowlan;
+#endif /*CONFIG_WOWLAN*/
+#endif /* end of LOAD_FW_HEADER_FROM_DRIVER */
+#endif /* end of CONFIG_SFW_SUPPORTED */
+
+#endif
+
diff --git a/drivers/staging/rtl8188eu/hal/hal8188e_t_fw.c b/drivers/staging/rtl8188eu/hal/hal8188e_t_fw.c
new file mode 100644
index 000000000000..6c5d7dd2278e
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal8188e_t_fw.c
@@ -0,0 +1,7730 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#include "drv_types.h"
+#include "hal8188e_t_fw.h"
+
+#ifdef LOAD_FW_HEADER_FROM_DRIVER
+
+#if (defined(CONFIG_AP_WOWLAN))
+
+u8 array_mp_8188e_t_fw_ap[] = {
+0xE1, 0x88, 0x20, 0x00, 0x1C, 0x00, 0x00, 0x00,
+0x05, 0x05, 0x14, 0x27, 0x6E, 0x3C, 0x00, 0x00,
+0xA5, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x45, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xC1, 0x84, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xA1, 0xFB, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xE1, 0xF3, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xC2, 0xAF, 0x80, 0xFE, 0x32, 0x12, 0x41, 0x04,
+0x85, 0xD0, 0x0B, 0x75, 0xD0, 0x08, 0xAA, 0xE0,
+0xC2, 0x8C, 0xE5, 0x8A, 0x24, 0x67, 0xF5, 0x8A,
+0xE5, 0x8C, 0x34, 0x79, 0xF5, 0x8C, 0xD2, 0x8C,
+0xEC, 0x24, 0x87, 0xF8, 0xE6, 0xBC, 0x02, 0x02,
+0x74, 0xFF, 0xC3, 0x95, 0x81, 0xB4, 0x40, 0x00,
+0x40, 0xCE, 0x79, 0x03, 0x78, 0x80, 0x16, 0xE6,
+0x08, 0x70, 0x0B, 0xC2, 0xAF, 0xE6, 0x30, 0xE1,
+0x03, 0x44, 0x18, 0xF6, 0xD2, 0xAF, 0x08, 0xD9,
+0xED, 0xEA, 0x8B, 0xD0, 0x22, 0xE5, 0x0C, 0xFF,
+0x23, 0x24, 0x81, 0xF8, 0x0F, 0x08, 0x08, 0xBF,
+0x03, 0x04, 0x7F, 0x00, 0x78, 0x81, 0xE6, 0x30,
+0xE4, 0xF2, 0x00, 0xE5, 0x0C, 0xC3, 0x9F, 0x50,
+0x20, 0x05, 0x0C, 0x74, 0x86, 0x25, 0x0C, 0xF8,
+0xE6, 0xFD, 0xA6, 0x81, 0x08, 0xE6, 0xAE, 0x0C,
+0xBE, 0x02, 0x02, 0x74, 0xFF, 0xCD, 0xF8, 0xE8,
+0x6D, 0x60, 0xE0, 0x08, 0xE6, 0xC0, 0xE0, 0x80,
+0xF6, 0xE5, 0x0C, 0xD3, 0x9F, 0x40, 0x27, 0xE5,
+0x0C, 0x24, 0x87, 0xF8, 0xE6, 0xAE, 0x0C, 0xBE,
+0x02, 0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xCD,
+0xF8, 0xE5, 0x81, 0x6D, 0x60, 0x06, 0xD0, 0xE0,
+0xF6, 0x18, 0x80, 0xF5, 0xE5, 0x0C, 0x24, 0x86,
+0xC8, 0xF6, 0x15, 0x0C, 0x80, 0xD3, 0xE5, 0x0C,
+0x23, 0x24, 0x81, 0xF8, 0x7F, 0x04, 0xC2, 0xAF,
+0xE6, 0x30, 0xE0, 0x03, 0x10, 0xE2, 0x0C, 0x7F,
+0x00, 0x30, 0xE1, 0x07, 0x30, 0xE3, 0x04, 0x7F,
+0x08, 0x54, 0xF4, 0x54, 0x7C, 0xC6, 0xD2, 0xAF,
+0x54, 0x80, 0x42, 0x07, 0x22, 0x78, 0x86, 0xA6,
+0x81, 0x74, 0x02, 0x60, 0x06, 0xFF, 0x08, 0x76,
+0xFF, 0xDF, 0xFB, 0x7F, 0x03, 0xE4, 0x78, 0x80,
+0xF6, 0x08, 0xF6, 0x08, 0xDF, 0xFA, 0x78, 0x81,
+0x76, 0x30, 0x90, 0x45, 0xF5, 0x74, 0x01, 0x93,
+0xC0, 0xE0, 0xE4, 0x93, 0xC0, 0xE0, 0x43, 0x89,
+0x01, 0x75, 0x8A, 0x60, 0x75, 0x8C, 0x79, 0xD2,
+0x8C, 0xD2, 0xAF, 0x22, 0x02, 0xEF, 0xD3, 0x94,
+0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0x74, 0x81,
+0x2F, 0x2F, 0xF8, 0xE6, 0x20, 0xE5, 0xF4, 0xC2,
+0xAF, 0xE6, 0x44, 0x30, 0xF6, 0xD2, 0xAF, 0xAE,
+0x0C, 0xEE, 0xC3, 0x9F, 0x50, 0x21, 0x0E, 0x74,
+0x86, 0x2E, 0xF8, 0xE6, 0xF9, 0x08, 0xE6, 0x18,
+0xBE, 0x02, 0x02, 0x74, 0xFF, 0xFD, 0xED, 0x69,
+0x60, 0x09, 0x09, 0xE7, 0x19, 0x19, 0xF7, 0x09,
+0x09, 0x80, 0xF3, 0x16, 0x16, 0x80, 0xDA, 0xEE,
+0xD3, 0x9F, 0x40, 0x04, 0x05, 0x81, 0x05, 0x81,
+0xEE, 0xD3, 0x9F, 0x40, 0x22, 0x74, 0x86, 0x2E,
+0xF8, 0x08, 0xE6, 0xF9, 0xEE, 0xB5, 0x0C, 0x02,
+0xA9, 0x81, 0x18, 0x06, 0x06, 0xE6, 0xFD, 0xED,
+0x69, 0x60, 0x09, 0x19, 0x19, 0xE7, 0x09, 0x09,
+0xF7, 0x19, 0x80, 0xF3, 0x1E, 0x80, 0xD9, 0xEF,
+0x24, 0x86, 0xF8, 0xE6, 0x04, 0xF8, 0xEF, 0x2F,
+0x04, 0x90, 0x45, 0xF5, 0x93, 0xF6, 0x08, 0xEF,
+0x2F, 0x93, 0xF6, 0x7F, 0x00, 0x22, 0xEF, 0xD3,
+0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0xEF,
+0x23, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE5, 0xF4,
+0xC2, 0xAF, 0xE6, 0x54, 0x8C, 0xF6, 0xD2, 0xAF,
+0xE5, 0x0C, 0xB5, 0x07, 0x0A, 0x74, 0x86, 0x2F,
+0xF8, 0xE6, 0xF5, 0x81, 0x02, 0x41, 0x4D, 0x50,
+0x2E, 0x74, 0x87, 0x2F, 0xF8, 0xE6, 0xBF, 0x02,
+0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xF9, 0x74,
+0x86, 0x2F, 0xF8, 0xFB, 0xE6, 0xFC, 0xE9, 0x6C,
+0x60, 0x08, 0xA8, 0x05, 0xE7, 0xF6, 0x1D, 0x19,
+0x80, 0xF4, 0xA8, 0x03, 0xA6, 0x05, 0x1F, 0xE5,
+0x0C, 0xB5, 0x07, 0xE3, 0x7F, 0x00, 0x22, 0x74,
+0x87, 0x2F, 0xF8, 0xE6, 0xFD, 0x18, 0x86, 0x01,
+0x0F, 0x74, 0x86, 0x2F, 0xF8, 0xA6, 0x01, 0x08,
+0x86, 0x04, 0xE5, 0x0C, 0xB5, 0x07, 0x02, 0xAC,
+0x81, 0xED, 0x6C, 0x60, 0x08, 0x0D, 0x09, 0xA8,
+0x05, 0xE6, 0xF7, 0x80, 0xF4, 0xE5, 0x0C, 0xB5,
+0x07, 0xDE, 0x89, 0x81, 0x7F, 0x00, 0x22, 0xEF,
+0xD3, 0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22,
+0xEF, 0x23, 0x24, 0x81, 0xF8, 0xC2, 0xAF, 0xE6,
+0x30, 0xE5, 0x05, 0x30, 0xE0, 0x02, 0xD2, 0xE4,
+0xD2, 0xE2, 0xC6, 0xD2, 0xAF, 0x7F, 0x00, 0x30,
+0xE2, 0x01, 0x0F, 0x02, 0x41, 0x4C, 0x8F, 0xF0,
+0xE4, 0xFF, 0xFE, 0xE5, 0x0C, 0x23, 0x24, 0x80,
+0xF8, 0xC2, 0xA9, 0x30, 0xF7, 0x0D, 0x7F, 0x08,
+0xE6, 0x60, 0x0B, 0x2D, 0xF6, 0x60, 0x30, 0x50,
+0x2E, 0x80, 0x07, 0x30, 0xF1, 0x06, 0xED, 0xF6,
+0x60, 0x25, 0x7E, 0x02, 0x08, 0x30, 0xF0, 0x10,
+0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x23, 0x0E, 0x30,
+0xE2, 0x0C, 0xD2, 0xAF, 0x7F, 0x04, 0x80, 0x12,
+0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x13, 0x54, 0xEC,
+0x4E, 0xF6, 0xD2, 0xAF, 0x02, 0x41, 0x4D, 0x7F,
+0x08, 0x08, 0xEF, 0x44, 0x83, 0xF4, 0xC2, 0xAF,
+0x56, 0xC6, 0xD2, 0xAF, 0x54, 0x80, 0x4F, 0xFF,
+0x22, 0xE7, 0x09, 0xF6, 0x08, 0xDF, 0xFA, 0x80,
+0x46, 0xE7, 0x09, 0xF2, 0x08, 0xDF, 0xFA, 0x80,
+0x3E, 0x88, 0x82, 0x8C, 0x83, 0xE7, 0x09, 0xF0,
+0xA3, 0xDF, 0xFA, 0x80, 0x32, 0xE3, 0x09, 0xF6,
+0x08, 0xDF, 0xFA, 0x80, 0x78, 0xE3, 0x09, 0xF2,
+0x08, 0xDF, 0xFA, 0x80, 0x70, 0x88, 0x82, 0x8C,
+0x83, 0xE3, 0x09, 0xF0, 0xA3, 0xDF, 0xFA, 0x80,
+0x64, 0x89, 0x82, 0x8A, 0x83, 0xE0, 0xA3, 0xF6,
+0x08, 0xDF, 0xFA, 0x80, 0x58, 0x89, 0x82, 0x8A,
+0x83, 0xE0, 0xA3, 0xF2, 0x08, 0xDF, 0xFA, 0x80,
+0x4C, 0x80, 0xD2, 0x80, 0xFA, 0x80, 0xC6, 0x80,
+0xD4, 0x80, 0x69, 0x80, 0xF2, 0x80, 0x33, 0x80,
+0x10, 0x80, 0xA6, 0x80, 0xEA, 0x80, 0x9A, 0x80,
+0xA8, 0x80, 0xDA, 0x80, 0xE2, 0x80, 0xCA, 0x80,
+0x33, 0x89, 0x82, 0x8A, 0x83, 0xEC, 0xFA, 0xE4,
+0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC, 0xC5,
+0x83, 0xCC, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8,
+0xCC, 0xC5, 0x83, 0xCC, 0xDF, 0xE9, 0xDE, 0xE7,
+0x80, 0x0D, 0x89, 0x82, 0x8A, 0x83, 0xE4, 0x93,
+0xA3, 0xF6, 0x08, 0xDF, 0xF9, 0xEC, 0xFA, 0xA9,
+0xF0, 0xED, 0xFB, 0x22, 0x89, 0x82, 0x8A, 0x83,
+0xEC, 0xFA, 0xE0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8,
+0xCC, 0xC5, 0x83, 0xCC, 0xF0, 0xA3, 0xC8, 0xC5,
+0x82, 0xC8, 0xCC, 0xC5, 0x83, 0xCC, 0xDF, 0xEA,
+0xDE, 0xE8, 0x80, 0xDB, 0x89, 0x82, 0x8A, 0x83,
+0xE4, 0x93, 0xA3, 0xF2, 0x08, 0xDF, 0xF9, 0x80,
+0xCC, 0x88, 0xF0, 0xEF, 0x60, 0x01, 0x0E, 0x4E,
+0x60, 0xC3, 0x88, 0xF0, 0xED, 0x24, 0x02, 0xB4,
+0x04, 0x00, 0x50, 0xB9, 0xF5, 0x82, 0xEB, 0x24,
+0x02, 0xB4, 0x04, 0x00, 0x50, 0xAF, 0x23, 0x23,
+0x45, 0x82, 0x23, 0x90, 0x43, 0xF9, 0x73, 0xC5,
+0xF0, 0xF8, 0xA3, 0xE0, 0x28, 0xF0, 0xC5, 0xF0,
+0xF8, 0xE5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15,
+0x83, 0xE0, 0x38, 0xF0, 0x22, 0xEF, 0x4B, 0xFF,
+0xEE, 0x4A, 0xFE, 0xED, 0x49, 0xFD, 0xEC, 0x48,
+0xFC, 0x22, 0xEB, 0x9F, 0xF5, 0xF0, 0xEA, 0x9E,
+0x42, 0xF0, 0xE9, 0x9D, 0x42, 0xF0, 0xE8, 0x9C,
+0x45, 0xF0, 0x22, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD,
+0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0xA4,
+0x25, 0x82, 0xF5, 0x82, 0xE5, 0xF0, 0x35, 0x83,
+0xF5, 0x83, 0x22, 0xE0, 0xFB, 0xA3, 0xE0, 0xFA,
+0xA3, 0xE0, 0xF9, 0x22, 0xEB, 0xF0, 0xA3, 0xEA,
+0xF0, 0xA3, 0xE9, 0xF0, 0x22, 0xD0, 0x83, 0xD0,
+0x82, 0xF8, 0xE4, 0x93, 0x70, 0x12, 0x74, 0x01,
+0x93, 0x70, 0x0D, 0xA3, 0xA3, 0x93, 0xF8, 0x74,
+0x01, 0x93, 0xF5, 0x82, 0x88, 0x83, 0xE4, 0x73,
+0x74, 0x02, 0x93, 0x68, 0x60, 0xEF, 0xA3, 0xA3,
+0xA3, 0x80, 0xDF, 0xEF, 0x4E, 0x60, 0x12, 0xEF,
+0x60, 0x01, 0x0E, 0xED, 0xBB, 0x01, 0x0B, 0x89,
+0x82, 0x8A, 0x83, 0xF0, 0xA3, 0xDF, 0xFC, 0xDE,
+0xFA, 0x22, 0x89, 0xF0, 0x50, 0x07, 0xF7, 0x09,
+0xDF, 0xFC, 0xA9, 0xF0, 0x22, 0xBB, 0xFE, 0xFC,
+0xF3, 0x09, 0xDF, 0xFC, 0xA9, 0xF0, 0x22, 0x02,
+0x45, 0x8D, 0x02, 0x41, 0xDD, 0xE4, 0x93, 0xA3,
+0xF8, 0xE4, 0x93, 0xA3, 0x40, 0x03, 0xF6, 0x80,
+0x01, 0xF2, 0x08, 0xDF, 0xF4, 0x80, 0x29, 0xE4,
+0x93, 0xA3, 0xF8, 0x54, 0x07, 0x24, 0x0C, 0xC8,
+0xC3, 0x33, 0xC4, 0x54, 0x0F, 0x44, 0x20, 0xC8,
+0x83, 0x40, 0x04, 0xF4, 0x56, 0x80, 0x01, 0x46,
+0xF6, 0xDF, 0xE4, 0x80, 0x0B, 0x01, 0x02, 0x04,
+0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x45, 0xD2,
+0xE4, 0x7E, 0x01, 0x93, 0x60, 0xBC, 0xA3, 0xFF,
+0x54, 0x3F, 0x30, 0xE5, 0x09, 0x54, 0x1F, 0xFE,
+0xE4, 0x93, 0xA3, 0x60, 0x01, 0x0E, 0xCF, 0x54,
+0xC0, 0x25, 0xE0, 0x60, 0xA8, 0x40, 0xB8, 0xE4,
+0x93, 0xA3, 0xFA, 0xE4, 0x93, 0xA3, 0xF8, 0xE4,
+0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5,
+0x83, 0xCA, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8,
+0xCA, 0xC5, 0x83, 0xCA, 0xDF, 0xE9, 0xDE, 0xE7,
+0x80, 0xBE, 0x41, 0x82, 0xB4, 0x00, 0x41, 0x82,
+0xB5, 0x00, 0x41, 0x82, 0xC2, 0x00, 0x41, 0x82,
+0xC5, 0x00, 0x44, 0x82, 0x86, 0x41, 0x4E, 0x59,
+0x00, 0x44, 0x82, 0x82, 0x61, 0x6E, 0x79, 0x00,
+0x41, 0x82, 0xC6, 0x00, 0x00, 0x57, 0xFC, 0x58,
+0xFD, 0x5F, 0xE3, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0,
+0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00,
+0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03,
+0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07,
+0x90, 0x01, 0xC4, 0x74, 0xFB, 0xF0, 0x74, 0x45,
+0xA3, 0xF0, 0xD1, 0x4A, 0x74, 0xFB, 0x04, 0x90,
+0x01, 0xC4, 0xF0, 0x74, 0x45, 0xA3, 0xF0, 0xD0,
+0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0,
+0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0,
+0xE0, 0x32, 0x90, 0x00, 0x54, 0xE0, 0x55, 0x35,
+0xF5, 0x39, 0xA3, 0xE0, 0x55, 0x36, 0xF5, 0x3A,
+0xA3, 0xE0, 0x55, 0x37, 0xF5, 0x3B, 0xA3, 0xE0,
+0x55, 0x38, 0xF5, 0x3C, 0xAD, 0x39, 0x7F, 0x54,
+0x12, 0x32, 0x1E, 0xAD, 0x3A, 0x7F, 0x55, 0x12,
+0x32, 0x1E, 0xAD, 0x3B, 0x7F, 0x56, 0x12, 0x32,
+0x1E, 0xAD, 0x3C, 0x7F, 0x57, 0x12, 0x32, 0x1E,
+0x53, 0x91, 0xEF, 0x22, 0xC0, 0xE0, 0xC0, 0xF0,
+0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0,
+0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0,
+0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0,
+0x07, 0x90, 0x01, 0xC4, 0x74, 0x84, 0xF0, 0x74,
+0x46, 0xA3, 0xF0, 0x12, 0x70, 0x04, 0xE5, 0x41,
+0x30, 0xE3, 0x02, 0xF1, 0x51, 0xE5, 0x41, 0x30,
+0xE4, 0x02, 0xF1, 0x2D, 0xE5, 0x43, 0x30, 0xE0,
+0x03, 0x12, 0x54, 0xEB, 0xE5, 0x43, 0x30, 0xE1,
+0x03, 0x12, 0x68, 0x7D, 0xE5, 0x43, 0x30, 0xE2,
+0x02, 0xF1, 0x5D, 0xE5, 0x43, 0x30, 0xE3, 0x03,
+0x12, 0x4F, 0xCE, 0xE5, 0x43, 0x30, 0xE4, 0x03,
+0x12, 0x6A, 0xA0, 0xE5, 0x43, 0x30, 0xE5, 0x02,
+0xF1, 0xC9, 0xE5, 0x43, 0x30, 0xE6, 0x03, 0x12,
+0x59, 0x4A, 0xE5, 0x43, 0x30, 0xE7, 0x02, 0xF1,
+0x6F, 0xE5, 0x44, 0x30, 0xE0, 0x02, 0xF1, 0x40,
+0xE5, 0x44, 0x30, 0xE1, 0x02, 0xF1, 0x48, 0x74,
+0x84, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x46,
+0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05,
+0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01,
+0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83,
+0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x12, 0x5C, 0xD8,
+0x7F, 0x02, 0x8F, 0x0F, 0x7F, 0x02, 0x71, 0x27,
+0x90, 0x80, 0x01, 0xE0, 0x45, 0x0F, 0xF0, 0x22,
+0xF1, 0x80, 0xBF, 0x03, 0x02, 0xF1, 0x88, 0x22,
+0x90, 0x81, 0x30, 0xE0, 0x60, 0x02, 0xF1, 0x90,
+0x22, 0x90, 0x80, 0xFC, 0xE0, 0x30, 0xE0, 0x04,
+0x7F, 0x20, 0xF1, 0x32, 0x22, 0x90, 0x81, 0xA7,
+0xE0, 0x04, 0xF0, 0x90, 0x81, 0x33, 0xE0, 0x64,
+0x02, 0x60, 0x03, 0x12, 0x69, 0x14, 0x22, 0xF1,
+0xEB, 0x90, 0x05, 0x50, 0xE0, 0x44, 0x01, 0xF0,
+0xF1, 0x80, 0xBF, 0x03, 0x02, 0xF1, 0x88, 0x22,
+0x90, 0x01, 0x02, 0xE0, 0x54, 0x03, 0xFF, 0x22,
+0x90, 0x05, 0x21, 0xE0, 0x54, 0x7F, 0xF0, 0x22,
+0x90, 0x81, 0x30, 0xE0, 0x64, 0x01, 0x70, 0x15,
+0xF1, 0xE4, 0x60, 0x08, 0xF1, 0xAE, 0x12, 0x4C,
+0x7F, 0x02, 0x5B, 0x92, 0x90, 0x81, 0x33, 0xE0,
+0x70, 0x03, 0x12, 0x49, 0xED, 0x22, 0xE4, 0xFD,
+0x7F, 0x0C, 0x02, 0x49, 0xF1, 0x12, 0x5B, 0x92,
+0x90, 0x81, 0x33, 0xE0, 0x64, 0x0C, 0x60, 0x08,
+0xF1, 0xAE, 0x12, 0x4C, 0x7F, 0x12, 0x5E, 0xE9,
+0x22, 0xE4, 0xFF, 0x12, 0x4E, 0x80, 0xBF, 0x01,
+0x11, 0x90, 0x81, 0x30, 0xE0, 0x60, 0x0B, 0xF1,
+0xE4, 0x64, 0x02, 0x60, 0x03, 0x02, 0x72, 0x16,
+0xF1, 0xB5, 0x22, 0xF0, 0x90, 0x81, 0x2E, 0xE0,
+0x54, 0x0F, 0x22, 0xE4, 0xF5, 0x4E, 0xF5, 0x4F,
+0xF5, 0x50, 0x22, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0,
+0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00,
+0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03,
+0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07,
+0x90, 0x01, 0xC4, 0x74, 0xF3, 0xF0, 0x74, 0x47,
+0xA3, 0xF0, 0x12, 0x70, 0x31, 0xE5, 0x49, 0x30,
+0xE1, 0x02, 0x11, 0xCF, 0xE5, 0x49, 0x30, 0xE2,
+0x03, 0x12, 0x59, 0xBB, 0xE5, 0x49, 0x30, 0xE3,
+0x03, 0x12, 0x6D, 0x9D, 0xE5, 0x49, 0x30, 0xE4,
+0x03, 0x12, 0x6B, 0x59, 0xE5, 0x4A, 0x30, 0xE0,
+0x03, 0x12, 0x6C, 0x6C, 0xE5, 0x4B, 0x30, 0xE5,
+0x03, 0x12, 0x6B, 0x35, 0xE5, 0x4C, 0x30, 0xE1,
+0x05, 0x7F, 0x04, 0x12, 0x47, 0x32, 0xE5, 0x4C,
+0x30, 0xE4, 0x02, 0x11, 0x93, 0xE5, 0x4C, 0x30,
+0xE5, 0x03, 0x12, 0x5C, 0xB4, 0xE5, 0x4C, 0x30,
+0xE6, 0x03, 0x12, 0x5C, 0x3E, 0x74, 0xF3, 0x04,
+0x90, 0x01, 0xC4, 0xF0, 0x74, 0x47, 0xA3, 0xF0,
+0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04,
+0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00,
+0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0,
+0xD0, 0xE0, 0x32, 0x12, 0x6E, 0x2E, 0xF1, 0xB5,
+0x7F, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x90, 0x81, 0x2D, 0xE0, 0xFE, 0xC3, 0x13,
+0x30, 0xE0, 0x1F, 0x90, 0x82, 0x69, 0x74, 0x1E,
+0xF0, 0x90, 0x82, 0x77, 0x74, 0x01, 0xF0, 0x90,
+0x82, 0x6B, 0xEF, 0xF0, 0x7B, 0x01, 0x7A, 0x82,
+0x79, 0x69, 0x12, 0x60, 0xAB, 0x7F, 0x04, 0x12,
+0x47, 0x32, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90,
+0x81, 0x30, 0xE0, 0x60, 0x03, 0x12, 0x69, 0xF5,
+0x90, 0x81, 0x94, 0xE0, 0x30, 0xE0, 0x49, 0xC4,
+0x54, 0x0F, 0x20, 0xE0, 0x17, 0xE4, 0xF5, 0x1D,
+0x90, 0x81, 0x96, 0x31, 0x30, 0x91, 0x7D, 0xF1,
+0xE5, 0x30, 0xE0, 0x06, 0x7D, 0x0C, 0x7F, 0x01,
+0x71, 0xE8, 0xE1, 0xF3, 0x90, 0x81, 0x94, 0xE0,
+0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x22, 0xE4, 0xF5,
+0x1D, 0x90, 0x81, 0x97, 0x31, 0x30, 0x90, 0x81,
+0x94, 0xE0, 0x54, 0xEF, 0xF0, 0xE0, 0xC3, 0x13,
+0x30, 0xE0, 0x06, 0x7D, 0x04, 0x7F, 0x01, 0x61,
+0xE8, 0x7B, 0x31, 0xF1, 0xED, 0x12, 0x64, 0x11,
+0x22, 0xF0, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0x8E,
+0xE0, 0xF5, 0x1E, 0xE4, 0xFB, 0xFD, 0x7F, 0x54,
+0x7E, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x8E, 0x19, 0x8F, 0x1A, 0xE5, 0x1E, 0x54,
+0x07, 0xC4, 0x33, 0x54, 0xE0, 0x85, 0x19, 0x83,
+0x85, 0x1A, 0x82, 0xF0, 0xE5, 0x1D, 0x31, 0x9A,
+0xE5, 0x1E, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x4F,
+0xA3, 0xF0, 0xEB, 0x31, 0x9A, 0xE5, 0x1D, 0x13,
+0x13, 0x13, 0x54, 0x1F, 0x4F, 0x31, 0x91, 0xF0,
+0xBD, 0x01, 0x0D, 0x85, 0x1A, 0x82, 0x8E, 0x83,
+0xA3, 0xA3, 0xA3, 0x74, 0x03, 0xF0, 0x80, 0x06,
+0x31, 0x91, 0xA3, 0x74, 0x01, 0xF0, 0x31, 0x91,
+0xA3, 0x74, 0x05, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x85, 0x1A, 0x82, 0x85, 0x19, 0x83, 0xA3,
+0xA3, 0x22, 0x54, 0x07, 0xC4, 0x33, 0x54, 0xE0,
+0xFF, 0x22, 0x90, 0x81, 0x34, 0xE0, 0x44, 0x10,
+0xF0, 0x90, 0x81, 0x39, 0xE0, 0x60, 0x04, 0x64,
+0x01, 0x70, 0x15, 0xE4, 0xF5, 0x1D, 0x90, 0x81,
+0x39, 0xE0, 0xFF, 0x90, 0x81, 0x38, 0xE0, 0x2F,
+0x31, 0x31, 0x90, 0x81, 0x39, 0xE0, 0x80, 0x11,
+0xE4, 0xF5, 0x1D, 0x12, 0x7C, 0x46, 0xFF, 0x90,
+0x81, 0x38, 0xE0, 0x2F, 0x31, 0x31, 0x12, 0x7C,
+0x46, 0xFF, 0x90, 0x81, 0x38, 0xE0, 0x2F, 0x90,
+0x81, 0x49, 0xF0, 0x90, 0x81, 0x33, 0xE0, 0x20,
+0xE2, 0x02, 0x31, 0xED, 0x22, 0x7D, 0x01, 0x7F,
+0x04, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x90, 0x82, 0xC1, 0xED, 0xF0, 0x90, 0x81, 0x2B,
+0xE0, 0xFE, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30,
+0xE0, 0x02, 0x61, 0x39, 0xEE, 0x12, 0x5C, 0x37,
+0x30, 0xE0, 0x02, 0x61, 0x39, 0x90, 0x81, 0x33,
+0xE0, 0xFE, 0x6F, 0x70, 0x02, 0x61, 0x39, 0xEF,
+0x70, 0x02, 0x41, 0xAD, 0x24, 0xFE, 0x70, 0x02,
+0x41, 0xE7, 0x24, 0xFE, 0x60, 0x47, 0x24, 0xFC,
+0x70, 0x02, 0x61, 0x22, 0x24, 0xFC, 0x60, 0x02,
+0x61, 0x32, 0xEE, 0xB4, 0x0E, 0x02, 0x71, 0x95,
+0x90, 0x81, 0x33, 0xE0, 0x70, 0x04, 0x7F, 0x01,
+0x71, 0xD5, 0x90, 0x81, 0x33, 0xE0, 0xB4, 0x06,
+0x02, 0x71, 0xB2, 0x90, 0x81, 0x33, 0xE0, 0xB4,
+0x04, 0x0D, 0x90, 0x82, 0xC1, 0xE0, 0xFF, 0x60,
+0x04, 0xB1, 0xD5, 0x80, 0x02, 0xB1, 0xAE, 0x90,
+0x81, 0x33, 0xE0, 0x64, 0x08, 0x60, 0x02, 0x61,
+0x32, 0xB1, 0x49, 0x61, 0x32, 0x90, 0x81, 0x33,
+0xE0, 0x70, 0x04, 0x7F, 0x01, 0x71, 0xD5, 0x90,
+0x81, 0x33, 0xE0, 0xB4, 0x06, 0x02, 0x71, 0xB2,
+0x90, 0x81, 0x33, 0xE0, 0xB4, 0x0E, 0x07, 0x71,
+0x3E, 0xBF, 0x01, 0x02, 0x71, 0x95, 0x90, 0x81,
+0x33, 0xE0, 0x64, 0x0C, 0x60, 0x02, 0x61, 0x32,
+0x71, 0x3E, 0xEF, 0x64, 0x01, 0x60, 0x02, 0x61,
+0x32, 0x91, 0x50, 0x61, 0x32, 0x90, 0x81, 0x33,
+0xE0, 0xB4, 0x0E, 0x07, 0x71, 0x3E, 0xBF, 0x01,
+0x02, 0x71, 0x95, 0x90, 0x81, 0x33, 0xE0, 0xB4,
+0x06, 0x02, 0x71, 0xB2, 0x90, 0x81, 0x33, 0xE0,
+0xB4, 0x0C, 0x07, 0x71, 0x3E, 0xBF, 0x01, 0x02,
+0x91, 0x50, 0x90, 0x81, 0x33, 0xE0, 0x64, 0x04,
+0x70, 0x58, 0x12, 0x6C, 0x06, 0xEF, 0x64, 0x01,
+0x70, 0x50, 0x12, 0x64, 0xC5, 0x80, 0x4B, 0x90,
+0x81, 0x33, 0xE0, 0xB4, 0x0E, 0x07, 0x71, 0x3E,
+0xBF, 0x01, 0x02, 0x71, 0x95, 0x90, 0x81, 0x33,
+0xE0, 0xB4, 0x06, 0x02, 0x71, 0xB2, 0x90, 0x81,
+0x33, 0xE0, 0xB4, 0x0C, 0x07, 0x71, 0x3E, 0xBF,
+0x01, 0x02, 0x91, 0x50, 0x90, 0x81, 0x33, 0xE0,
+0x70, 0x04, 0x7F, 0x01, 0x71, 0xD5, 0x90, 0x81,
+0x33, 0xE0, 0xB4, 0x04, 0x15, 0x12, 0x72, 0xCC,
+0x80, 0x10, 0x90, 0x81, 0x33, 0xE0, 0xB4, 0x0C,
+0x09, 0x12, 0x69, 0xEB, 0x30, 0xE0, 0x03, 0x12,
+0x65, 0x90, 0x90, 0x81, 0x33, 0x12, 0x7C, 0x39,
+0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x6D, 0x84,
+0xEF, 0x64, 0x01, 0x60, 0x05, 0x75, 0x1F, 0x01,
+0x80, 0x30, 0x12, 0x6D, 0x69, 0x30, 0xE0, 0x05,
+0x75, 0x1F, 0x02, 0x80, 0x25, 0x90, 0x81, 0x32,
+0xE0, 0xD3, 0x94, 0x04, 0x40, 0x05, 0x75, 0x1F,
+0x08, 0x80, 0x17, 0x90, 0x81, 0x94, 0xE0, 0x30,
+0xE0, 0x0B, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x05,
+0x75, 0x1F, 0x11, 0x80, 0x05, 0x12, 0x6D, 0x48,
+0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74, 0x02, 0xF0,
+0x90, 0x01, 0xB8, 0xE5, 0x1F, 0xF0, 0x7F, 0x00,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x81, 0x2C,
+0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x04, 0x7D, 0x0C,
+0x80, 0x05, 0x12, 0x73, 0x6C, 0x7D, 0x04, 0x7F,
+0x01, 0x71, 0xE8, 0xE4, 0xFB, 0xFD, 0x7F, 0xFF,
+0x81, 0x84, 0x90, 0x81, 0x2C, 0xE0, 0x90, 0x06,
+0x04, 0x20, 0xE0, 0x08, 0xE0, 0x44, 0x40, 0xF0,
+0x7D, 0x04, 0x80, 0x06, 0xE0, 0x54, 0x7F, 0xF0,
+0x7D, 0x0C, 0x7F, 0x01, 0x71, 0xE8, 0xE4, 0xFB,
+0xFD, 0x7F, 0xFF, 0x81, 0x84, 0x90, 0x82, 0xC0,
+0xEF, 0xF0, 0xB1, 0x51, 0x90, 0x82, 0xC0, 0xE0,
+0x60, 0x02, 0x91, 0x7F, 0x7D, 0x04, 0x7F, 0x01,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xAC,
+0x07, 0xEF, 0x14, 0x60, 0x15, 0x14, 0x60, 0x19,
+0x24, 0x02, 0x70, 0x1A, 0xED, 0x54, 0x01, 0xFE,
+0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFE, 0x4E, 0xF0,
+0x80, 0x0C, 0x90, 0x81, 0x33, 0xED, 0xF0, 0x80,
+0x05, 0x90, 0x81, 0x32, 0xED, 0xF0, 0x90, 0x00,
+0x8F, 0xE0, 0x30, 0xE4, 0x2E, 0xEC, 0x14, 0x60,
+0x07, 0x14, 0x60, 0x1D, 0x24, 0x02, 0x70, 0x23,
+0x90, 0x81, 0x2B, 0xE0, 0x54, 0x01, 0xC4, 0x33,
+0x33, 0x33, 0x54, 0x80, 0xFF, 0x90, 0x81, 0x33,
+0xE0, 0x54, 0x7F, 0x4F, 0xFD, 0x7F, 0x88, 0x80,
+0x07, 0x90, 0x81, 0x32, 0xE0, 0xFD, 0x7F, 0x89,
+0x12, 0x32, 0x1E, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0xF1, 0xC6, 0x70, 0x28, 0x90, 0x81, 0x2C, 0xE0,
+0x54, 0xFD, 0xF0, 0x7B, 0x2C, 0x12, 0x72, 0xD7,
+0x7D, 0x08, 0x7F, 0x01, 0x12, 0x5E, 0xED, 0xBF,
+0x01, 0x0D, 0x90, 0x81, 0x2B, 0xE0, 0x44, 0x80,
+0xF0, 0x7D, 0x0E, 0x7F, 0x01, 0x61, 0xE8, 0x12,
+0x5E, 0x0F, 0x04, 0xF0, 0x22, 0xB1, 0x51, 0xE4,
+0xFB, 0xFD, 0x7F, 0xFF, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x05, 0x22, 0xED, 0xF0,
+0x90, 0x80, 0x05, 0xEB, 0xF0, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0x7E, 0x00, 0x7F, 0x62, 0x7D, 0x00,
+0x7B, 0x01, 0x7A, 0x81, 0x79, 0x2B, 0x12, 0x45,
+0x23, 0x90, 0x81, 0x2F, 0x74, 0x02, 0xF0, 0x90,
+0x81, 0x36, 0x14, 0xF0, 0xA3, 0xF0, 0xA3, 0x74,
+0x10, 0xF0, 0x90, 0x81, 0x3C, 0xE4, 0xF0, 0xA3,
+0x74, 0x05, 0x12, 0x7C, 0x1C, 0xE4, 0xFD, 0xFF,
+0x71, 0xE8, 0x7D, 0x0C, 0x7F, 0x02, 0x71, 0xE8,
+0x7D, 0x0C, 0x7F, 0x01, 0x71, 0xE8, 0x90, 0x80,
+0x07, 0xE0, 0xFF, 0xB4, 0x01, 0x08, 0x90, 0x81,
+0x3B, 0x74, 0x99, 0xF0, 0x80, 0x29, 0xEF, 0xB4,
+0x03, 0x08, 0x90, 0x81, 0x3B, 0x74, 0x90, 0xF0,
+0x80, 0x1D, 0x90, 0x81, 0x3B, 0x74, 0x40, 0xF0,
+0x90, 0x00, 0x2C, 0xE0, 0x54, 0x0F, 0xFF, 0xBF,
+0x05, 0x08, 0x90, 0x81, 0x4D, 0x74, 0x02, 0xF0,
+0x80, 0x05, 0xE4, 0x90, 0x81, 0x4D, 0xF0, 0x90,
+0x81, 0x8D, 0x74, 0x02, 0xF0, 0xA3, 0x74, 0x0F,
+0xF0, 0xA3, 0xE0, 0x54, 0x01, 0x44, 0x28, 0xF0,
+0xA3, 0x74, 0x07, 0x12, 0x7C, 0x1C, 0x7E, 0x00,
+0x7F, 0x02, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x81,
+0x79, 0x91, 0x12, 0x45, 0x23, 0x12, 0x73, 0x5C,
+0x12, 0x7C, 0x63, 0x7B, 0x56, 0xE4, 0xFD, 0x7F,
+0xFF, 0x91, 0x84, 0xE4, 0x90, 0x81, 0x93, 0xF0,
+0x22, 0x91, 0x7D, 0x7D, 0x0C, 0x7F, 0x01, 0x61,
+0xE8, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x90, 0x01, 0x01, 0xE0, 0x44, 0x02, 0xF0, 0x90,
+0x01, 0x00, 0x74, 0xFF, 0xF0, 0x90, 0x06, 0xB7,
+0x74, 0x09, 0xF0, 0x90, 0x06, 0xB4, 0x74, 0x86,
+0xF0, 0x12, 0x65, 0x6E, 0x54, 0x7F, 0xFC, 0x90,
+0x82, 0xA9, 0x12, 0x20, 0xCE, 0x90, 0x82, 0xA9,
+0x12, 0x63, 0x80, 0x7F, 0x7C, 0x12, 0x64, 0xBC,
+0x12, 0x20, 0xDA, 0xCC, 0xC0, 0x00, 0xC0, 0x12,
+0x64, 0xBA, 0x12, 0x20, 0xDA, 0x00, 0xC0, 0x00,
+0x14, 0x12, 0x65, 0x77, 0x12, 0x20, 0xDA, 0x00,
+0x03, 0x3E, 0x60, 0xE4, 0xFD, 0xFF, 0x12, 0x65,
+0x4C, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x73,
+0x5C, 0x91, 0x7F, 0x7D, 0x0C, 0x7F, 0x01, 0x61,
+0xE8, 0x90, 0x81, 0x94, 0xE0, 0x30, 0xE0, 0x14,
+0x90, 0x01, 0x57, 0xE4, 0xF0, 0x91, 0x7D, 0xF1,
+0xE5, 0x30, 0xE0, 0x06, 0x7D, 0x0C, 0x7F, 0x01,
+0x71, 0xE8, 0xF1, 0xF3, 0x22, 0xEF, 0x60, 0x33,
+0xF1, 0xC6, 0x70, 0x2F, 0x90, 0x81, 0x2C, 0xE0,
+0x54, 0xFE, 0xF0, 0x7B, 0x2B, 0x7D, 0x0F, 0x7F,
+0xFF, 0x91, 0x84, 0x90, 0x06, 0x04, 0xE0, 0x54,
+0xBF, 0xF0, 0x12, 0x5E, 0xE9, 0xBF, 0x01, 0x0D,
+0x90, 0x81, 0x2B, 0xE0, 0x44, 0x40, 0xF0, 0x7D,
+0x06, 0x7F, 0x01, 0x61, 0xE8, 0x12, 0x5E, 0x0F,
+0x74, 0x08, 0xF0, 0x22, 0xEF, 0x70, 0x38, 0x7D,
+0x78, 0x7F, 0x02, 0x12, 0x69, 0x0A, 0x7D, 0x02,
+0x7F, 0x03, 0x12, 0x69, 0x0A, 0x7D, 0xC8, 0x7F,
+0x02, 0x12, 0x6A, 0x79, 0x12, 0x6A, 0xC3, 0xF0,
+0xE4, 0xFF, 0xD1, 0x80, 0xEF, 0x70, 0x0C, 0xB1,
+0x51, 0xB1, 0xAE, 0x12, 0x73, 0x64, 0x54, 0x7F,
+0xF0, 0x80, 0x06, 0x7D, 0x01, 0x7F, 0x0C, 0x31,
+0xF1, 0x12, 0x5F, 0xD3, 0x02, 0x7C, 0x63, 0x90,
+0x01, 0x36, 0x74, 0x78, 0xF0, 0xA3, 0x74, 0x02,
+0xF0, 0x7D, 0x78, 0xFF, 0xF1, 0xB9, 0x7D, 0x02,
+0x7F, 0x03, 0xF1, 0xB9, 0x90, 0x06, 0x0A, 0xE0,
+0x44, 0x07, 0x12, 0x67, 0xAA, 0xE4, 0xFF, 0xD1,
+0x80, 0xBF, 0x01, 0x10, 0x12, 0x6A, 0x62, 0x90,
+0x81, 0x33, 0xE0, 0x20, 0xE2, 0x09, 0x7D, 0x01,
+0x7F, 0x04, 0x21, 0xF1, 0x12, 0x67, 0x7D, 0x22,
+0x12, 0x6C, 0xFD, 0xFE, 0xEF, 0x54, 0x07, 0xFF,
+0x74, 0x22, 0x2E, 0x12, 0x6F, 0x96, 0xFD, 0x7C,
+0x00, 0x12, 0x5E, 0x06, 0x80, 0x05, 0xC3, 0x33,
+0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEE, 0x5C,
+0xFE, 0xEF, 0x5D, 0x4E, 0x7F, 0x00, 0x60, 0x02,
+0x7F, 0x01, 0x22, 0x8B, 0x55, 0x8A, 0x56, 0x89,
+0x57, 0x12, 0x57, 0x38, 0xFF, 0xF5, 0x59, 0x12,
+0x1F, 0xA4, 0xFE, 0xC3, 0x13, 0x30, 0xE0, 0x07,
+0x12, 0x57, 0x92, 0xF5, 0x5A, 0x80, 0x02, 0x8F,
+0x5A, 0x85, 0x59, 0x58, 0xE5, 0x58, 0xD3, 0x95,
+0x5A, 0x50, 0x25, 0xAB, 0x55, 0xAA, 0x56, 0xA9,
+0x57, 0x12, 0x1F, 0xA4, 0x54, 0x01, 0xFD, 0xAF,
+0x58, 0x12, 0x53, 0x0C, 0xAF, 0x58, 0xD1, 0x80,
+0xEF, 0xAF, 0x58, 0x70, 0x05, 0x12, 0x68, 0x03,
+0x80, 0x02, 0xF1, 0xEC, 0x05, 0x58, 0x80, 0xD4,
+0xE5, 0x59, 0x70, 0x13, 0xFF, 0xD1, 0x80, 0xEF,
+0x70, 0x0D, 0xB1, 0x51, 0xB1, 0xAE, 0x12, 0x5F,
+0xD3, 0x54, 0xBF, 0xF0, 0x54, 0x7F, 0xF0, 0x22,
+0x90, 0x81, 0xCD, 0x12, 0x44, 0xF4, 0x90, 0x81,
+0xCC, 0xEF, 0xF0, 0x12, 0x44, 0xFD, 0x4F, 0x4F,
+0x00, 0x4F, 0x54, 0x01, 0x4F, 0x58, 0x03, 0x4F,
+0x5D, 0x04, 0x4F, 0x62, 0x08, 0x4F, 0x67, 0x09,
+0x4F, 0x6C, 0x0A, 0x4F, 0x71, 0x12, 0x4F, 0x76,
+0x13, 0x4F, 0x7B, 0x14, 0x4F, 0x80, 0x20, 0x4F,
+0x85, 0x25, 0x4F, 0x8A, 0x26, 0x4F, 0x8F, 0xC2,
+0x4F, 0x94, 0xC4, 0x00, 0x00, 0x4F, 0x99, 0xF1,
+0xA9, 0x02, 0x57, 0x98, 0xF1, 0xA9, 0xC1, 0xAB,
+0xF1, 0xA9, 0x02, 0x73, 0x78, 0xF1, 0xA9, 0x02,
+0x57, 0x3E, 0xF1, 0xA9, 0x02, 0x56, 0x1D, 0xF1,
+0xA9, 0x02, 0x65, 0x9E, 0xF1, 0xA9, 0x02, 0x65,
+0xB6, 0xF1, 0xA9, 0x02, 0x61, 0xC1, 0xF1, 0xA9,
+0x02, 0x5B, 0xBE, 0xF1, 0xA9, 0x02, 0x65, 0xC2,
+0xF1, 0xA9, 0x02, 0x5E, 0x19, 0xF1, 0xA9, 0x02,
+0x65, 0xD1, 0xF1, 0xA9, 0x02, 0x65, 0xD9, 0xF1,
+0xA9, 0x02, 0x67, 0xD0, 0xF1, 0xA9, 0x02, 0x67,
+0xD8, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x01, 0xF0,
+0x90, 0x81, 0xCC, 0xE0, 0x90, 0x01, 0xC2, 0xF0,
+0x22, 0x90, 0x81, 0xCD, 0x02, 0x44, 0xEB, 0x7D,
+0x01, 0x7F, 0x02, 0xF1, 0xB9, 0x7D, 0x02, 0x7F,
+0x02, 0x74, 0x3D, 0x2F, 0xF8, 0xE6, 0x4D, 0xFE,
+0xF6, 0x74, 0x30, 0x02, 0x6A, 0x81, 0xE4, 0xFF,
+0xD1, 0x80, 0xEF, 0x64, 0x01, 0x22, 0xF1, 0xC6,
+0x70, 0x12, 0x90, 0x81, 0x30, 0xE0, 0x60, 0x0C,
+0x90, 0x81, 0x34, 0xE0, 0x20, 0xE4, 0x05, 0x12,
+0x6A, 0xC3, 0x31, 0x29, 0x22, 0x90, 0x81, 0x94,
+0xE0, 0xC3, 0x13, 0x22, 0x22, 0x7D, 0xFF, 0x7F,
+0xFF, 0x81, 0x84, 0x90, 0x81, 0x94, 0xE0, 0x44,
+0x10, 0xF0, 0x22, 0x90, 0x00, 0xF7, 0xE0, 0x20,
+0xE7, 0x09, 0xE0, 0x7F, 0x01, 0x20, 0xE6, 0x0C,
+0x7F, 0x02, 0x22, 0x90, 0x00, 0xF7, 0xE0, 0x30,
+0xE6, 0x02, 0x7F, 0x03, 0x22, 0x12, 0x4F, 0xFB,
+0x90, 0x80, 0x07, 0xEF, 0xF0, 0x11, 0x36, 0x90,
+0x01, 0x64, 0x74, 0x01, 0xF0, 0x90, 0x00, 0x12,
+0xE0, 0x54, 0xC7, 0x44, 0x20, 0xFD, 0x7F, 0x12,
+0x12, 0x32, 0x1E, 0x02, 0x2D, 0xA7, 0x90, 0x00,
+0x08, 0xE0, 0x54, 0xEF, 0xF0, 0x11, 0x6F, 0x11,
+0xA7, 0x12, 0x6F, 0x9F, 0x12, 0x6F, 0xBE, 0xE4,
+0xF5, 0x35, 0xF5, 0x37, 0xF5, 0x36, 0xF5, 0x37,
+0x75, 0x38, 0x80, 0xAD, 0x35, 0x7F, 0x50, 0x12,
+0x32, 0x1E, 0xAD, 0x36, 0x7F, 0x51, 0x12, 0x32,
+0x1E, 0xAD, 0x37, 0x7F, 0x52, 0x12, 0x32, 0x1E,
+0xAD, 0x38, 0x7F, 0x53, 0x02, 0x32, 0x1E, 0x90,
+0x01, 0x30, 0xE4, 0x11, 0x9F, 0x90, 0x01, 0x38,
+0x11, 0x9F, 0xFD, 0x7F, 0x50, 0x12, 0x32, 0x1E,
+0xE4, 0xFD, 0x7F, 0x51, 0x12, 0x32, 0x1E, 0xE4,
+0xFD, 0x7F, 0x52, 0x12, 0x32, 0x1E, 0xE4, 0xFD,
+0x7F, 0x53, 0x02, 0x32, 0x1E, 0xE4, 0x90, 0x81,
+0xD8, 0xF0, 0x90, 0x82, 0x43, 0xF0, 0xA3, 0xF0,
+0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0x90,
+0x01, 0x34, 0x74, 0xFF, 0x11, 0x9F, 0x90, 0x01,
+0x3C, 0x11, 0x9F, 0xFD, 0x7F, 0x54, 0x12, 0x32,
+0x1E, 0x7D, 0xFF, 0x7F, 0x55, 0x12, 0x32, 0x1E,
+0x7D, 0xFF, 0x7F, 0x56, 0x12, 0x32, 0x1E, 0x7D,
+0xFF, 0x7F, 0x57, 0x02, 0x32, 0x1E, 0x90, 0x80,
+0xFC, 0xE0, 0x54, 0xFE, 0x71, 0x6B, 0x90, 0x80,
+0xFC, 0xE0, 0x54, 0xFD, 0xF0, 0x54, 0xFB, 0xF0,
+0x54, 0xF7, 0xF0, 0x54, 0xEF, 0xF0, 0xE4, 0x90,
+0x80, 0xFF, 0x11, 0x9D, 0x11, 0xA0, 0x90, 0x81,
+0x1E, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0x90,
+0x82, 0x53, 0x51, 0xC8, 0xE4, 0x11, 0xA0, 0xFC,
+0xA3, 0xF0, 0x31, 0xA4, 0x90, 0x82, 0x58, 0xEF,
+0xF0, 0x51, 0x7F, 0xA3, 0xE0, 0x04, 0xFD, 0x31,
+0xA4, 0xAC, 0x07, 0x90, 0x82, 0x58, 0xE0, 0x30,
+0xE7, 0x08, 0x90, 0x82, 0x56, 0x74, 0x02, 0xF0,
+0x80, 0x05, 0xE4, 0x90, 0x82, 0x56, 0xF0, 0xEC,
+0x30, 0xE6, 0x34, 0x51, 0x7F, 0x7D, 0x02, 0x31,
+0xA4, 0xEF, 0x54, 0x70, 0xC4, 0x54, 0x0F, 0x90,
+0x82, 0x59, 0xF0, 0x14, 0x60, 0x11, 0x14, 0x60,
+0x16, 0x24, 0xFE, 0x60, 0x12, 0x14, 0x60, 0x07,
+0x14, 0x60, 0x04, 0x24, 0x06, 0x80, 0x10, 0x90,
+0x82, 0x57, 0x74, 0x04, 0xF0, 0x80, 0x0D, 0x90,
+0x82, 0x57, 0x74, 0x08, 0xF0, 0x80, 0x05, 0xE4,
+0x90, 0x82, 0x57, 0xF0, 0x90, 0x82, 0x56, 0xE0,
+0x24, 0x18, 0xFF, 0xA3, 0xE0, 0x2F, 0xFF, 0x22,
+0x90, 0x82, 0x4F, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0,
+0xA3, 0xED, 0xF0, 0x11, 0xF7, 0x90, 0x82, 0x52,
+0xEF, 0xF0, 0x90, 0x82, 0x51, 0xE0, 0xFD, 0x90,
+0x82, 0x50, 0xE0, 0x2D, 0xFD, 0x90, 0x82, 0x4F,
+0xE0, 0x34, 0x00, 0xFC, 0x7E, 0x00, 0xED, 0x2F,
+0xFF, 0xEE, 0x3C, 0xCF, 0x24, 0x06, 0xCF, 0x34,
+0x00, 0xFE, 0xE4, 0xFD, 0xAB, 0x07, 0xAA, 0x06,
+0xED, 0x2B, 0xFB, 0xE4, 0x3A, 0xFA, 0xC3, 0x90,
+0x80, 0xFB, 0xE0, 0x9B, 0x90, 0x80, 0xFA, 0xE0,
+0x9A, 0x50, 0x0A, 0xA3, 0x12, 0x7C, 0x2C, 0xEB,
+0x9F, 0xFB, 0xEA, 0x9E, 0xFA, 0xEA, 0x90, 0xFD,
+0x11, 0xF0, 0xAF, 0x03, 0x74, 0x00, 0x2F, 0x12,
+0x7C, 0x51, 0xFF, 0x22, 0x31, 0x70, 0xEF, 0x64,
+0x08, 0x70, 0x34, 0x51, 0x12, 0x24, 0x07, 0x31,
+0x9E, 0xEF, 0x70, 0x2B, 0x51, 0x12, 0x24, 0x1D,
+0x31, 0x9E, 0xBF, 0x44, 0x0B, 0x51, 0x12, 0x24,
+0x1F, 0x31, 0x9E, 0xEF, 0x64, 0x43, 0x60, 0x14,
+0x51, 0x12, 0x24, 0x1D, 0x31, 0x9E, 0xEF, 0x64,
+0x43, 0x70, 0x0C, 0x51, 0x12, 0x24, 0x1F, 0x31,
+0x9E, 0xBF, 0x44, 0x03, 0x7F, 0x01, 0x22, 0x7F,
+0x00, 0x22, 0x90, 0x82, 0x51, 0xE0, 0xFF, 0x90,
+0x82, 0x50, 0xE0, 0x2F, 0xFF, 0x90, 0x82, 0x4F,
+0xE0, 0x34, 0x00, 0xFE, 0x90, 0x82, 0x52, 0xE0,
+0x7C, 0x00, 0x2F, 0xFF, 0xEC, 0x3E, 0xCF, 0x22,
+0x31, 0x70, 0xEF, 0x64, 0x08, 0x70, 0x20, 0x51,
+0x12, 0x24, 0x07, 0x31, 0x9E, 0xEF, 0x64, 0x06,
+0x70, 0x15, 0x51, 0x12, 0x24, 0x0E, 0x31, 0x9E,
+0xEF, 0x70, 0x0C, 0x51, 0x12, 0x24, 0x0F, 0x31,
+0x9E, 0xBF, 0x01, 0x03, 0x7F, 0x01, 0x22, 0x7F,
+0x00, 0x22, 0x24, 0x0A, 0xFC, 0xED, 0x2C, 0xFD,
+0x31, 0xA4, 0x90, 0x81, 0xD0, 0xA3, 0xE0, 0xFE,
+0x90, 0x81, 0xD6, 0xE0, 0x2E, 0x24, 0x24, 0xF5,
+0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xEF, 0xF0,
+0x90, 0x81, 0xD6, 0xE0, 0x04, 0xF0, 0x22, 0x90,
+0x82, 0x53, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22,
+0x90, 0x82, 0x4F, 0x51, 0xC8, 0x31, 0xA4, 0xEF,
+0x54, 0x0C, 0x64, 0x08, 0x70, 0x2F, 0x90, 0x82,
+0x52, 0xF0, 0x90, 0x82, 0x52, 0xE0, 0xFD, 0xC3,
+0x94, 0x06, 0x50, 0x21, 0x90, 0x82, 0x4F, 0xE0,
+0xFE, 0xA3, 0xE0, 0xFF, 0xA3, 0xE0, 0x24, 0x10,
+0xFC, 0xED, 0x2C, 0xFD, 0x31, 0xA4, 0xEF, 0xF4,
+0x60, 0x03, 0x7F, 0x01, 0x22, 0x90, 0x82, 0x52,
+0xE0, 0x04, 0xF0, 0x80, 0xD5, 0x7F, 0x00, 0x22,
+0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xED, 0xF0,
+0x22, 0xFD, 0x31, 0xA4, 0x90, 0x81, 0xD7, 0xE0,
+0x22, 0x24, 0x1A, 0xFC, 0xED, 0x2C, 0xFD, 0x31,
+0xA4, 0x90, 0x81, 0xD6, 0xE0, 0x24, 0xEE, 0xF5,
+0x82, 0xE4, 0x34, 0x81, 0x22, 0x71, 0x09, 0x12,
+0x67, 0xED, 0x12, 0x4C, 0x9A, 0x12, 0x72, 0xE9,
+0x71, 0x5B, 0x12, 0x73, 0xD8, 0x11, 0xCE, 0x12,
+0x72, 0xAF, 0x90, 0x81, 0xA9, 0x74, 0x01, 0xF0,
+0x22, 0xE4, 0xFD, 0xFF, 0x12, 0x6C, 0xFD, 0xFE,
+0xEF, 0x54, 0x07, 0xFF, 0xED, 0x70, 0x14, 0x71,
+0x52, 0xF5, 0x83, 0xC0, 0x83, 0xC0, 0x82, 0x71,
+0x4A, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4,
+0x5E, 0x80, 0x11, 0x71, 0x52, 0xF5, 0x83, 0xC0,
+0x83, 0xC0, 0x82, 0x71, 0x4A, 0x80, 0x02, 0xC3,
+0x33, 0xD8, 0xFC, 0x4E, 0xD0, 0x82, 0xD0, 0x83,
+0xF0, 0x12, 0x6F, 0x42, 0x90, 0x81, 0x2A, 0xEF,
+0xF0, 0x22, 0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x07,
+0x08, 0x22, 0x74, 0x22, 0x2E, 0xF5, 0x82, 0xE4,
+0x34, 0x81, 0x22, 0x90, 0x81, 0x9D, 0xE0, 0x54,
+0xFE, 0xF0, 0x54, 0x7F, 0xF0, 0x54, 0xFB, 0xF0,
+0xA3, 0x74, 0x0A, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3,
+0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x90, 0x82, 0xA1, 0xEE, 0xF0, 0xA3, 0xEF,
+0x71, 0x6B, 0x90, 0x82, 0xA1, 0xE0, 0xFE, 0xA3,
+0xE0, 0xF5, 0x82, 0x8E, 0x83, 0xE0, 0x60, 0x23,
+0xC3, 0x90, 0x82, 0xA4, 0xE0, 0x94, 0xE8, 0x90,
+0x82, 0xA3, 0xE0, 0x94, 0x03, 0x40, 0x0B, 0x90,
+0x01, 0xC0, 0xE0, 0x44, 0x80, 0xF0, 0x7F, 0x00,
+0x80, 0x0B, 0x90, 0x82, 0xA3, 0x71, 0xBD, 0xF1,
+0x2E, 0x80, 0xCF, 0x7F, 0x01, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0x90, 0x82, 0x4D, 0xE4, 0x75, 0xF0,
+0x01, 0x02, 0x44, 0x9F, 0x90, 0x81, 0xC8, 0xEF,
+0x71, 0x6B, 0x90, 0x01, 0x09, 0xE0, 0x7F, 0x00,
+0x30, 0xE7, 0x02, 0x7F, 0x01, 0x90, 0x81, 0xC8,
+0xE0, 0x6F, 0x60, 0x35, 0xC3, 0x90, 0x81, 0xCA,
+0xE0, 0x94, 0x88, 0x90, 0x81, 0xC9, 0xE0, 0x94,
+0x13, 0x40, 0x08, 0x90, 0x01, 0xC0, 0xE0, 0x44,
+0x10, 0xF0, 0x22, 0x90, 0x81, 0xC9, 0x71, 0xBD,
+0x12, 0x58, 0xAF, 0xD3, 0x90, 0x81, 0xCA, 0xE0,
+0x94, 0x32, 0x90, 0x81, 0xC9, 0xE0, 0x94, 0x00,
+0x40, 0xC0, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE0,
+0xB9, 0x22, 0xE4, 0xFD, 0xFB, 0xFA, 0xF1, 0x27,
+0x30, 0xE0, 0x74, 0x90, 0x00, 0xB6, 0xE0, 0xFC,
+0x90, 0x00, 0xBF, 0xE0, 0xFE, 0x90, 0x00, 0xBE,
+0xE0, 0x24, 0x00, 0xFB, 0xEA, 0x3E, 0xFA, 0xC4,
+0xF8, 0x54, 0xF0, 0xC8, 0xEB, 0xC4, 0x54, 0x0F,
+0x48, 0x54, 0x1E, 0xFF, 0xEC, 0xC4, 0x54, 0x01,
+0x4F, 0x90, 0x81, 0xB0, 0xF0, 0x12, 0x7C, 0x0B,
+0xEC, 0x30, 0xE4, 0x0A, 0x90, 0x81, 0x14, 0xE0,
+0xFD, 0x12, 0x6B, 0x2D, 0x80, 0x35, 0xEB, 0x30,
+0xE5, 0x09, 0x90, 0x81, 0x15, 0x91, 0xDC, 0x04,
+0xF0, 0x80, 0x28, 0xEB, 0x30, 0xE6, 0x0A, 0x90,
+0x81, 0x16, 0x91, 0xDC, 0x74, 0x02, 0xF0, 0x80,
+0x1A, 0xEB, 0x30, 0xE7, 0x0A, 0x90, 0x81, 0x17,
+0x91, 0xDC, 0x74, 0x03, 0xF0, 0x80, 0x0C, 0xEA,
+0x30, 0xE0, 0x08, 0x90, 0x81, 0x18, 0x91, 0xDC,
+0x74, 0x04, 0xF0, 0xAF, 0x05, 0x80, 0x56, 0x90,
+0x81, 0x07, 0xE0, 0xFD, 0x7C, 0x00, 0xA3, 0xE0,
+0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x20, 0x30, 0xED,
+0x4C, 0x70, 0x05, 0x90, 0x81, 0x14, 0x80, 0x2A,
+0xED, 0x64, 0x01, 0x4C, 0x70, 0x05, 0x90, 0x81,
+0x15, 0x80, 0x1F, 0xED, 0x64, 0x02, 0x4C, 0x70,
+0x05, 0x90, 0x81, 0x16, 0x80, 0x14, 0xED, 0x64,
+0x03, 0x4C, 0x70, 0x05, 0x90, 0x81, 0x17, 0x80,
+0x09, 0xED, 0x64, 0x04, 0x4C, 0x70, 0x0C, 0x90,
+0x81, 0x18, 0xE0, 0xFF, 0x91, 0xE5, 0x90, 0x81,
+0x08, 0x71, 0xBD, 0x22, 0xE0, 0xFD, 0x90, 0x81,
+0x08, 0xE4, 0xF0, 0xA3, 0x22, 0x90, 0x04, 0x24,
+0xEF, 0xF0, 0x22, 0x12, 0x47, 0xEB, 0xB1, 0x51,
+0xE4, 0xFF, 0x12, 0x48, 0x9A, 0x90, 0x80, 0xFC,
+0xE0, 0x30, 0xE0, 0x02, 0x91, 0x12, 0x02, 0x4D,
+0xB9, 0x12, 0x72, 0x39, 0x90, 0x81, 0x3B, 0xE0,
+0x20, 0xE0, 0x0C, 0x90, 0x00, 0x26, 0xE0, 0x54,
+0x7F, 0xFD, 0x7F, 0x26, 0x12, 0x32, 0x1E, 0x90,
+0x00, 0x08, 0xE0, 0x54, 0xEF, 0xFD, 0x7F, 0x08,
+0x12, 0x32, 0x1E, 0xE4, 0xFF, 0x61, 0xC4, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x72,
+0x56, 0xB1, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x90, 0x81, 0x33, 0xE0, 0xFF, 0x60, 0x03, 0xB4,
+0x08, 0x0E, 0x12, 0x6E, 0xFC, 0xBF, 0x01, 0x08,
+0xB1, 0x27, 0x90, 0x01, 0xE5, 0xE0, 0x04, 0xF0,
+0x22, 0xE4, 0xF5, 0x51, 0x90, 0x81, 0x30, 0xE0,
+0x60, 0x1D, 0x12, 0x4F, 0xC6, 0x70, 0x18, 0x12,
+0x6D, 0x60, 0x60, 0x09, 0x90, 0x81, 0x2C, 0x12,
+0x5F, 0xDB, 0x20, 0xE0, 0x03, 0x75, 0x51, 0x01,
+0xE5, 0x51, 0x60, 0x03, 0x12, 0x49, 0xA2, 0x22,
+0xE4, 0x90, 0x82, 0xBA, 0xF0, 0xA3, 0xF0, 0x90,
+0x02, 0x86, 0xE0, 0x20, 0xE1, 0x22, 0xC3, 0x90,
+0x82, 0xBB, 0xE0, 0x94, 0xD0, 0x90, 0x82, 0xBA,
+0xE0, 0x94, 0x07, 0x40, 0x0A, 0x90, 0x01, 0xC1,
+0xE0, 0x44, 0x04, 0xF0, 0x7F, 0x00, 0x22, 0x90,
+0x82, 0xBA, 0x71, 0xBD, 0xF1, 0x2E, 0x80, 0xD7,
+0x7F, 0x01, 0x22, 0x90, 0x01, 0x17, 0xE0, 0xFE,
+0x90, 0x01, 0x16, 0x12, 0x7C, 0x5A, 0x90, 0x80,
+0xFA, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x02, 0x86,
+0xE0, 0x44, 0x04, 0xF1, 0xEC, 0x30, 0xE0, 0x2B,
+0x90, 0x01, 0xC7, 0xE4, 0xF0, 0xB1, 0x78, 0x90,
+0x80, 0xFC, 0xE0, 0xBF, 0x01, 0x05, 0x54, 0xEF,
+0xF0, 0x80, 0x03, 0x44, 0x10, 0xF0, 0x90, 0x80,
+0xFF, 0xE0, 0xFF, 0x60, 0x0E, 0xE4, 0xF5, 0x1D,
+0x8F, 0x1E, 0xFB, 0xFD, 0x7F, 0x5C, 0x7E, 0x01,
+0x12, 0x49, 0x3A, 0x90, 0x80, 0xFC, 0xE0, 0x44,
+0x01, 0xF0, 0x7D, 0x08, 0xE4, 0xFF, 0x12, 0x4F,
+0xB9, 0x90, 0x05, 0x52, 0xE0, 0x54, 0x07, 0x04,
+0x90, 0x81, 0x07, 0x71, 0x6B, 0x90, 0x04, 0x22,
+0xE0, 0x54, 0xEF, 0xF0, 0xF1, 0x27, 0x30, 0xE0,
+0x03, 0x12, 0x7C, 0x0B, 0x22, 0x12, 0x67, 0x8D,
+0xFC, 0x54, 0x02, 0xFE, 0x90, 0x80, 0xFC, 0xE0,
+0x54, 0xFD, 0x4E, 0xF0, 0xE0, 0xFF, 0xC3, 0x13,
+0x30, 0xE0, 0x08, 0xF1, 0x21, 0xF1, 0x83, 0x90,
+0x80, 0xFF, 0xF0, 0xEC, 0x30, 0xE0, 0x18, 0xB1,
+0xAB, 0x90, 0x01, 0xC7, 0xE4, 0xF0, 0x90, 0x80,
+0x07, 0xE0, 0x64, 0x01, 0x70, 0x2E, 0x90, 0xFE,
+0x10, 0xE0, 0x44, 0x04, 0xF0, 0x80, 0x25, 0x12,
+0x6A, 0x75, 0x90, 0x01, 0x3C, 0xE0, 0x30, 0xE4,
+0x03, 0x74, 0x10, 0xF0, 0x90, 0x01, 0x63, 0xE4,
+0xF0, 0x12, 0x6A, 0xFA, 0xF1, 0x27, 0x30, 0xE0,
+0x0B, 0x90, 0x02, 0x86, 0xE0, 0x30, 0xE2, 0x04,
+0xE0, 0x54, 0xFB, 0xF0, 0x90, 0x81, 0xD0, 0xF1,
+0x35, 0x90, 0x80, 0xFD, 0xF1, 0x91, 0x90, 0x80,
+0xFE, 0xF1, 0xEC, 0x30, 0xE0, 0x28, 0xF1, 0x21,
+0x12, 0x67, 0xB5, 0x90, 0x80, 0xFC, 0x12, 0x67,
+0x96, 0x4E, 0xF1, 0xD8, 0x90, 0x81, 0x00, 0xF0,
+0x70, 0x03, 0x74, 0x14, 0xF0, 0xF1, 0x21, 0x90,
+0x00, 0x05, 0x12, 0x1F, 0xBD, 0x90, 0x81, 0x01,
+0xF1, 0xDF, 0x90, 0x81, 0x02, 0xF0, 0x90, 0x80,
+0xFD, 0xE0, 0x54, 0x01, 0x90, 0x81, 0x0A, 0xF0,
+0x90, 0x80, 0xFD, 0xE0, 0x54, 0x02, 0x90, 0x81,
+0x0B, 0xF0, 0x90, 0x80, 0xFD, 0xE0, 0x54, 0x04,
+0x90, 0x81, 0x0C, 0xF0, 0x90, 0x80, 0xFD, 0xE0,
+0x54, 0x08, 0x90, 0x81, 0x0D, 0xF0, 0x90, 0x80,
+0xFD, 0xE0, 0x54, 0x10, 0x90, 0x81, 0x0E, 0xF0,
+0x90, 0x80, 0xFE, 0xE0, 0x54, 0x01, 0x90, 0x81,
+0x0F, 0xF0, 0x90, 0x80, 0xFE, 0xE0, 0x54, 0x02,
+0x90, 0x81, 0x10, 0xF0, 0x90, 0x80, 0xFE, 0xE0,
+0x54, 0x04, 0x90, 0x81, 0x11, 0xF0, 0x90, 0x80,
+0xFE, 0xE0, 0x54, 0x08, 0x90, 0x81, 0x12, 0xF0,
+0x90, 0x80, 0xFE, 0xE0, 0x54, 0x10, 0x90, 0x81,
+0x13, 0xF0, 0x22, 0x90, 0x81, 0xD0, 0x12, 0x44,
+0xF4, 0x90, 0x81, 0xD0, 0x02, 0x44, 0xEB, 0x90,
+0x80, 0xFC, 0xE0, 0xC3, 0x13, 0x22, 0x7F, 0x0A,
+0x7E, 0x00, 0x02, 0x32, 0xAA, 0x12, 0x44, 0xEB,
+0x90, 0x00, 0x01, 0x02, 0x1F, 0xBD, 0x90, 0x81,
+0xD0, 0x12, 0x44, 0xF4, 0x12, 0x73, 0xD8, 0xF1,
+0x21, 0x12, 0x73, 0x98, 0xF1, 0x89, 0x4E, 0xF0,
+0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x2B, 0xF1, 0x38,
+0x90, 0x81, 0xA2, 0xF1, 0x91, 0x90, 0x81, 0xA3,
+0xF0, 0x12, 0x1F, 0xA4, 0xFF, 0x54, 0x04, 0xFE,
+0x90, 0x81, 0xA1, 0xE0, 0x54, 0xFB, 0x4E, 0xF1,
+0x82, 0x90, 0x81, 0xA4, 0xF0, 0xEF, 0x54, 0x08,
+0xFF, 0x90, 0x81, 0xA1, 0xE0, 0x54, 0xF7, 0x4F,
+0xF0, 0x22, 0xF0, 0x90, 0x00, 0x03, 0x02, 0x1F,
+0xBD, 0x90, 0x81, 0xA1, 0xE0, 0x54, 0xFE, 0x22,
+0x4F, 0xF0, 0x90, 0x00, 0x02, 0x02, 0x1F, 0xBD,
+0x90, 0x02, 0x09, 0xE0, 0xF5, 0x55, 0x12, 0x1F,
+0xA4, 0x25, 0x55, 0x90, 0x80, 0x09, 0xF0, 0xF1,
+0x38, 0x25, 0x55, 0x90, 0x80, 0x0A, 0xF1, 0x91,
+0x25, 0x55, 0x90, 0x80, 0x0B, 0xF1, 0x82, 0x25,
+0x55, 0x90, 0x80, 0x0C, 0xF1, 0xD8, 0x25, 0x55,
+0x90, 0x80, 0x0D, 0xF0, 0x90, 0x00, 0x05, 0x12,
+0x1F, 0xBD, 0x25, 0x55, 0x90, 0x80, 0x0E, 0xF1,
+0xDF, 0x25, 0x55, 0x90, 0x80, 0x0F, 0xF0, 0x22,
+0xF0, 0x90, 0x00, 0x04, 0x02, 0x1F, 0xBD, 0xF0,
+0x90, 0x00, 0x06, 0x02, 0x1F, 0xBD, 0xE4, 0x90,
+0x80, 0x01, 0x01, 0x9D, 0xF0, 0x90, 0x80, 0xFC,
+0xE0, 0xFF, 0xC3, 0x13, 0x22, 0x75, 0xE8, 0x03,
+0x75, 0xA8, 0x84, 0x22, 0x90, 0x00, 0x80, 0xE0,
+0x44, 0x80, 0xFD, 0x7F, 0x80, 0x12, 0x32, 0x1E,
+0x90, 0xFD, 0x00, 0xE0, 0x54, 0xBF, 0xF0, 0x11,
+0xC0, 0x12, 0x32, 0x77, 0x11, 0xCD, 0x12, 0x57,
+0xE6, 0x7F, 0x01, 0x12, 0x42, 0x15, 0x90, 0x81,
+0x9C, 0x74, 0x02, 0xF0, 0xFF, 0x12, 0x42, 0x15,
+0x90, 0x81, 0x9C, 0xE0, 0x04, 0xF0, 0x12, 0x50,
+0x15, 0x12, 0x52, 0xED, 0x90, 0x01, 0xCC, 0x74,
+0x0F, 0xF0, 0x90, 0x00, 0x80, 0xE0, 0x44, 0x40,
+0xFD, 0x7F, 0x80, 0x12, 0x32, 0x1E, 0x75, 0x20,
+0xFF, 0x12, 0x57, 0xF5, 0x11, 0x55, 0x11, 0xB6,
+0xE4, 0xFF, 0x02, 0x42, 0x9E, 0xE4, 0x90, 0x81,
+0xC3, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x98, 0xE0,
+0x7F, 0x00, 0x30, 0xE4, 0x02, 0x7F, 0x01, 0xEF,
+0x64, 0x01, 0x60, 0x3C, 0xC3, 0x90, 0x81, 0xC4,
+0xE0, 0x94, 0x88, 0x90, 0x81, 0xC3, 0xE0, 0x94,
+0x13, 0x40, 0x0F, 0x90, 0x01, 0xC1, 0xE0, 0x44,
+0x10, 0xF0, 0x90, 0x01, 0xC7, 0x74, 0xFD, 0xF0,
+0x80, 0x1E, 0x90, 0x81, 0xC3, 0x12, 0x53, 0xBD,
+0x11, 0xAF, 0xD3, 0x90, 0x81, 0xC4, 0xE0, 0x94,
+0x32, 0x90, 0x81, 0xC3, 0xE0, 0x94, 0x00, 0x40,
+0xBB, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE3, 0xB4,
+0x90, 0x01, 0xC7, 0x74, 0xFE, 0xF0, 0x22, 0x7F,
+0x14, 0x7E, 0x00, 0x02, 0x32, 0xAA, 0x90, 0x01,
+0xE4, 0x74, 0x1C, 0xF0, 0xA3, 0xE4, 0xF0, 0x22,
+0x90, 0x01, 0x94, 0xE0, 0x44, 0x01, 0xF0, 0x90,
+0x01, 0xC7, 0xE4, 0xF0, 0x22, 0x90, 0x01, 0x01,
+0xE0, 0x44, 0x04, 0xF0, 0x90, 0x01, 0x9C, 0x74,
+0x7E, 0xF0, 0xA3, 0x74, 0x92, 0xF0, 0xA3, 0x74,
+0xA0, 0xF0, 0xA3, 0x74, 0x24, 0xF0, 0x90, 0x01,
+0x9B, 0x74, 0x49, 0xF0, 0x90, 0x01, 0x9A, 0x74,
+0xE0, 0xF0, 0x90, 0x01, 0x99, 0xE4, 0xF0, 0x90,
+0x01, 0x98, 0x04, 0xF0, 0x22, 0xE4, 0x90, 0x81,
+0xC5, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x81,
+0xC5, 0xE0, 0x64, 0x01, 0xF0, 0x24, 0xFD, 0x90,
+0x01, 0xC4, 0xF0, 0x74, 0x58, 0xA3, 0xF0, 0x90,
+0x81, 0x30, 0xE0, 0x60, 0x0E, 0x90, 0x81, 0x33,
+0xE0, 0xFF, 0x90, 0x81, 0x32, 0xE0, 0x6F, 0x60,
+0x02, 0x31, 0x40, 0xC2, 0xAF, 0x12, 0x6F, 0xDD,
+0xBF, 0x01, 0x03, 0x12, 0x72, 0xDE, 0xD2, 0xAF,
+0x31, 0x3F, 0x12, 0x41, 0x4D, 0x80, 0xC7, 0x22,
+0x90, 0x81, 0x32, 0xE0, 0xFF, 0x7D, 0x01, 0x02,
+0x49, 0xF1, 0xE4, 0xFF, 0x12, 0x4E, 0x80, 0xBF,
+0x01, 0x0E, 0x90, 0x81, 0x30, 0xE0, 0x60, 0x08,
+0x31, 0x61, 0x54, 0x07, 0x70, 0x02, 0x31, 0x40,
+0x22, 0x90, 0x81, 0x34, 0xE0, 0x54, 0xFE, 0xF0,
+0x22, 0x90, 0x06, 0xA9, 0xE0, 0xF5, 0x4E, 0x54,
+0xC0, 0x70, 0x07, 0x31, 0x61, 0x54, 0xFD, 0xF0,
+0x80, 0xC6, 0xE5, 0x4E, 0x30, 0xE6, 0x1F, 0x90,
+0x81, 0x30, 0xE0, 0x64, 0x01, 0x70, 0x19, 0x90,
+0x81, 0x34, 0xE0, 0x44, 0x01, 0x12, 0x47, 0xE3,
+0x64, 0x02, 0x60, 0x05, 0x12, 0x72, 0x16, 0x80,
+0x07, 0x12, 0x47, 0xB5, 0x80, 0x02, 0x31, 0x61,
+0xE5, 0x4E, 0x90, 0x81, 0x34, 0x30, 0xE7, 0x0E,
+0xE0, 0x44, 0x02, 0x12, 0x49, 0x29, 0x90, 0x81,
+0x2B, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0xE0, 0x54,
+0xFD, 0xF0, 0x22, 0x90, 0x81, 0x30, 0xE0, 0x60,
+0x0F, 0x90, 0x06, 0x92, 0xE0, 0x30, 0xE1, 0x04,
+0x71, 0x92, 0x80, 0x04, 0xF1, 0xD3, 0x31, 0x40,
+0x90, 0x81, 0xAA, 0x91, 0x35, 0x30, 0xE0, 0x19,
+0xEF, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x02, 0xF1,
+0x82, 0x90, 0x81, 0xAB, 0xE0, 0x30, 0xE0, 0x09,
+0x71, 0x64, 0x20, 0xE0, 0x02, 0x7D, 0x01, 0x31,
+0xF2, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x90, 0x82, 0xB9, 0xED, 0xF0, 0x90, 0x82,
+0xB8, 0xEF, 0xF0, 0xD3, 0x94, 0x07, 0x50, 0x4B,
+0x51, 0xC3, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC,
+0xF4, 0xFF, 0x90, 0x00, 0x47, 0xE0, 0x5F, 0xFD,
+0x7F, 0x47, 0x51, 0xBD, 0x80, 0x02, 0xC3, 0x33,
+0xD8, 0xFC, 0xFF, 0x90, 0x00, 0x46, 0xE0, 0x4F,
+0xFD, 0x7F, 0x46, 0x71, 0x7D, 0x60, 0x10, 0x51,
+0xC0, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xFF,
+0x90, 0x00, 0x45, 0xE0, 0x4F, 0x80, 0x0F, 0x51,
+0xC0, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4,
+0xFF, 0x90, 0x00, 0x45, 0xE0, 0x5F, 0xFD, 0x7F,
+0x45, 0x80, 0x62, 0x90, 0x82, 0xB8, 0xE0, 0x24,
+0xF8, 0xF0, 0xE0, 0x24, 0x04, 0x51, 0xC4, 0x80,
+0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90,
+0x00, 0x43, 0xE0, 0x5F, 0xFD, 0x7F, 0x43, 0x51,
+0xBD, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xFF,
+0x90, 0x00, 0x43, 0xE0, 0x4F, 0xFD, 0x7F, 0x43,
+0x71, 0x7D, 0x60, 0x19, 0x90, 0x82, 0xB8, 0xE0,
+0x24, 0x04, 0x51, 0xC4, 0x80, 0x02, 0xC3, 0x33,
+0xD8, 0xFC, 0xFF, 0x90, 0x00, 0x42, 0xE0, 0x4F,
+0xFD, 0x7F, 0x42, 0x80, 0x18, 0x90, 0x82, 0xB8,
+0xE0, 0x24, 0x04, 0x51, 0xC4, 0x80, 0x02, 0xC3,
+0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x42,
+0xE0, 0x5F, 0xFD, 0x7F, 0x42, 0x12, 0x32, 0x1E,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x32, 0x1E,
+0x90, 0x82, 0xB8, 0xE0, 0xFF, 0x74, 0x01, 0xA8,
+0x07, 0x08, 0x22, 0xAD, 0x07, 0x90, 0x81, 0xAC,
+0xE0, 0x75, 0xF0, 0x20, 0xA4, 0xFF, 0x90, 0x82,
+0x96, 0xE5, 0xF0, 0xF0, 0xA3, 0xEF, 0xF0, 0x90,
+0x81, 0xAD, 0xE0, 0x75, 0xF0, 0x08, 0xA4, 0xAE,
+0xF0, 0x90, 0x82, 0x98, 0xF0, 0xEE, 0xA3, 0xF0,
+0x71, 0x75, 0x90, 0x82, 0x9A, 0xF0, 0xEE, 0xA3,
+0xF0, 0xED, 0x64, 0x01, 0x60, 0x5E, 0x90, 0x81,
+0xAA, 0xE0, 0xFE, 0x91, 0x37, 0x30, 0xE0, 0x54,
+0xEE, 0x71, 0x69, 0x20, 0xE0, 0x02, 0x7D, 0x01,
+0x71, 0x5D, 0xFE, 0x54, 0x0F, 0xFF, 0xEE, 0xC4,
+0x13, 0x13, 0x54, 0x01, 0xFD, 0x71, 0x5D, 0xC4,
+0x13, 0x54, 0x07, 0x30, 0xE0, 0x21, 0xA3, 0xE0,
+0x30, 0xE0, 0x0D, 0x90, 0x82, 0x9B, 0xE0, 0xF5,
+0x1D, 0x90, 0x82, 0x9A, 0x71, 0x85, 0x80, 0x0F,
+0x71, 0x75, 0xFF, 0x12, 0x32, 0xAA, 0x71, 0x64,
+0x20, 0xE0, 0x02, 0x7D, 0x01, 0x31, 0xF2, 0x90,
+0x81, 0xAA, 0xE0, 0xC4, 0x54, 0x0F, 0x30, 0xE0,
+0x0B, 0x90, 0x82, 0x99, 0xE0, 0xF5, 0x1D, 0x90,
+0x82, 0x98, 0x71, 0x85, 0x22, 0x31, 0xF2, 0x90,
+0x81, 0xAA, 0xE0, 0x22, 0x90, 0x81, 0xAA, 0xE0,
+0xFE, 0x54, 0x0F, 0xFF, 0xEE, 0xC4, 0x13, 0x13,
+0x54, 0x03, 0x7D, 0x00, 0x22, 0x90, 0x82, 0x96,
+0xE0, 0xFE, 0xA3, 0xE0, 0x22, 0x12, 0x32, 0x1E,
+0x90, 0x82, 0xB9, 0xE0, 0x22, 0xE0, 0xF5, 0x1E,
+0xE4, 0xFB, 0xFD, 0x7F, 0x58, 0x7E, 0x01, 0x02,
+0x49, 0x3A, 0x12, 0x6D, 0x69, 0x30, 0xE0, 0x05,
+0x90, 0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x06, 0x92,
+0x74, 0x02, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x04,
+0xF0, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0x8F, 0xE0,
+0xC3, 0x13, 0x54, 0x7F, 0x71, 0x86, 0x90, 0x81,
+0x2B, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x12, 0x1F,
+0xA4, 0xFF, 0x54, 0x80, 0xFE, 0x90, 0x81, 0xAA,
+0xE0, 0x54, 0x7F, 0x4E, 0xFE, 0xF0, 0xEF, 0x54,
+0x40, 0xFF, 0xEE, 0x54, 0xBF, 0x4F, 0xFF, 0xF0,
+0x12, 0x1F, 0xA4, 0xFE, 0x54, 0x20, 0xFD, 0xEF,
+0x54, 0xDF, 0x4D, 0xFF, 0x90, 0x81, 0xAA, 0xF0,
+0xEE, 0x54, 0x10, 0xFE, 0xEF, 0x54, 0xEF, 0x4E,
+0xFF, 0xF0, 0x12, 0x1F, 0xA4, 0x54, 0x0F, 0xFE,
+0xEF, 0x54, 0xF0, 0x4E, 0x90, 0x81, 0xAA, 0xF0,
+0x12, 0x57, 0x38, 0xFF, 0x54, 0x7F, 0x90, 0x81,
+0xAC, 0xF0, 0xEF, 0x54, 0x80, 0x91, 0x37, 0xFF,
+0x90, 0x81, 0xAB, 0xE0, 0x54, 0xFE, 0x12, 0x57,
+0x90, 0x90, 0x81, 0xAD, 0x12, 0x57, 0x82, 0x54,
+0x01, 0x25, 0xE0, 0xFF, 0x90, 0x81, 0xAB, 0xE0,
+0x54, 0xFD, 0x4F, 0xF0, 0x71, 0x64, 0x20, 0xE0,
+0x02, 0x7D, 0x01, 0x21, 0xF2, 0xE0, 0xFF, 0xC4,
+0x13, 0x13, 0x13, 0x54, 0x01, 0x22, 0x90, 0x81,
+0x2B, 0x91, 0x35, 0x30, 0xE0, 0x1D, 0xEF, 0x54,
+0x7F, 0xB1, 0xFB, 0x30, 0xE1, 0x06, 0xE0, 0x44,
+0x02, 0xF0, 0x80, 0x07, 0xE0, 0x54, 0xFD, 0xD1,
+0x0E, 0x04, 0xF0, 0x90, 0x81, 0x30, 0xE0, 0x60,
+0x02, 0x31, 0x40, 0x7F, 0x01, 0x90, 0x81, 0xA1,
+0xE0, 0xFD, 0x30, 0xE0, 0x46, 0x90, 0x81, 0xA6,
+0xE0, 0xFC, 0x60, 0x3F, 0xD1, 0x06, 0x80, 0x05,
+0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF,
+0x90, 0x04, 0xE0, 0xE0, 0xFB, 0xEF, 0x5B, 0x60,
+0x0B, 0xE4, 0x90, 0x81, 0xA6, 0xF0, 0x90, 0x81,
+0xA8, 0x04, 0xF0, 0x22, 0x90, 0x81, 0xA3, 0xE0,
+0xD3, 0x9C, 0x50, 0x15, 0xED, 0x13, 0x13, 0x13,
+0x54, 0x1F, 0x30, 0xE0, 0x05, 0x12, 0x67, 0xFB,
+0x80, 0x02, 0xD1, 0x89, 0x12, 0x57, 0x89, 0xF0,
+0x22, 0xD1, 0xDC, 0x22, 0x90, 0x81, 0x2B, 0xF1,
+0xDB, 0x30, 0xE0, 0x18, 0xEF, 0x54, 0xBF, 0xB1,
+0xFB, 0x30, 0xE0, 0x06, 0xE0, 0x44, 0x01, 0xF0,
+0x80, 0x08, 0xE0, 0x54, 0xFE, 0xD1, 0x0E, 0x74,
+0x04, 0xF0, 0x31, 0x40, 0xE4, 0xFF, 0x80, 0x8D,
+0x90, 0x01, 0xCC, 0xE0, 0x54, 0x0F, 0x90, 0x82,
+0xB6, 0xF0, 0x90, 0x82, 0xB6, 0xE0, 0xFD, 0x70,
+0x02, 0xA1, 0xD0, 0x90, 0x80, 0x60, 0xE0, 0xFF,
+0x70, 0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A,
+0xEF, 0x14, 0xFF, 0x90, 0x80, 0x61, 0xE0, 0xB5,
+0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00,
+0xEF, 0x60, 0x08, 0x90, 0x01, 0xC1, 0xE0, 0x44,
+0x01, 0xF0, 0x22, 0x90, 0x82, 0xB4, 0xD1, 0x04,
+0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8,
+0xF9, 0xFF, 0xEF, 0x5D, 0x70, 0x02, 0xA1, 0xB2,
+0xE4, 0x90, 0x82, 0xB7, 0xF0, 0x90, 0x82, 0xB7,
+0xE0, 0xF9, 0xC3, 0x94, 0x04, 0x50, 0x31, 0xB1,
+0xD1, 0xA4, 0xFF, 0xE9, 0xFD, 0x7C, 0x00, 0x2F,
+0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74, 0xD0, 0xB1,
+0xE9, 0x90, 0x80, 0x10, 0xB1, 0xD9, 0xB1, 0xD1,
+0xA4, 0x2D, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74,
+0xF0, 0xB1, 0xE9, 0x90, 0x80, 0x14, 0xB1, 0xD9,
+0x90, 0x82, 0xB7, 0xE0, 0x04, 0xF0, 0x80, 0xC5,
+0x90, 0x82, 0xB6, 0xE0, 0xFF, 0x90, 0x82, 0xB4,
+0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x06, 0x08, 0x80,
+0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0x90,
+0x82, 0xB6, 0xF0, 0x90, 0x82, 0xB4, 0x51, 0xC3,
+0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x90, 0x01,
+0xCC, 0xF0, 0x90, 0x82, 0xB4, 0xE0, 0x04, 0xF0,
+0xE0, 0x54, 0x03, 0xF0, 0x90, 0x80, 0x61, 0xF1,
+0xC5, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x70,
+0x02, 0x81, 0xE2, 0xE4, 0x90, 0x80, 0x61, 0xF0,
+0x81, 0xE2, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x02,
+0xF0, 0x90, 0x82, 0xB4, 0xE0, 0x44, 0x80, 0x90,
+0x00, 0x8A, 0xF0, 0xB1, 0xD1, 0x90, 0x01, 0xD0,
+0x12, 0x44, 0xDF, 0xE0, 0x90, 0x01, 0xC3, 0xF0,
+0x22, 0x90, 0x82, 0xB4, 0xE0, 0x75, 0xF0, 0x04,
+0x22, 0x12, 0x44, 0xDF, 0xE5, 0x82, 0x29, 0xF5,
+0x82, 0xE4, 0x35, 0x83, 0xF5, 0x83, 0xEF, 0xF0,
+0x22, 0x2F, 0xF5, 0x82, 0x74, 0x01, 0x3E, 0xF5,
+0x83, 0xE0, 0xFF, 0x90, 0x80, 0x61, 0xE0, 0x75,
+0xF0, 0x08, 0x22, 0xF0, 0x90, 0x04, 0xE0, 0xE0,
+0x90, 0x81, 0x2C, 0x22, 0xE0, 0xFF, 0x74, 0x01,
+0x7E, 0x00, 0xA8, 0x07, 0x08, 0x22, 0xF0, 0x90,
+0x01, 0xB9, 0x74, 0x01, 0xF0, 0x90, 0x01, 0xB8,
+0x22, 0x12, 0x67, 0x8D, 0xFF, 0x54, 0x7F, 0x90,
+0x81, 0x30, 0xF0, 0xEF, 0x91, 0x37, 0xA3, 0xF0,
+0x12, 0x57, 0x38, 0xFD, 0x54, 0xF0, 0xC4, 0x54,
+0x0F, 0xFF, 0x90, 0x81, 0x2E, 0xE0, 0x54, 0xF0,
+0x4F, 0x12, 0x57, 0x82, 0xFC, 0x54, 0x01, 0x25,
+0xE0, 0xFF, 0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFD,
+0x4F, 0xF0, 0xEC, 0x54, 0x04, 0xC3, 0x13, 0xFF,
+0x90, 0x81, 0x2D, 0xE0, 0x54, 0xFD, 0x4F, 0xF0,
+0xED, 0x54, 0x0F, 0xC4, 0x54, 0xF0, 0xFF, 0xA3,
+0xE0, 0x54, 0x0F, 0x12, 0x57, 0x90, 0x90, 0x81,
+0x2F, 0x12, 0x57, 0xD8, 0xFD, 0x7F, 0x02, 0x12,
+0x4B, 0xE8, 0x12, 0x57, 0x21, 0x12, 0x6D, 0xFC,
+0xD1, 0x0F, 0xF0, 0x90, 0x81, 0x30, 0x12, 0x7C,
+0x39, 0x12, 0x47, 0xE3, 0x90, 0x01, 0xBE, 0xF0,
+0x22, 0x90, 0x01, 0xC7, 0x74, 0x10, 0xF0, 0x7F,
+0x01, 0x80, 0x0B, 0x12, 0x6A, 0xFA, 0x90, 0x01,
+0xC7, 0x74, 0x66, 0xF0, 0xE4, 0xFF, 0x90, 0x82,
+0xC4, 0xEF, 0xF0, 0x90, 0x80, 0x07, 0xE0, 0xB4,
+0x02, 0x12, 0x90, 0x82, 0xC4, 0xE0, 0xFF, 0x64,
+0x01, 0x60, 0x24, 0x90, 0x01, 0x4D, 0xE0, 0x64,
+0x80, 0xF0, 0x80, 0x19, 0x90, 0x01, 0x00, 0x74,
+0xFF, 0xF0, 0x7F, 0x64, 0x7E, 0x00, 0x12, 0x32,
+0xAA, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x01, 0xF0,
+0x90, 0x82, 0xC4, 0xE0, 0xFF, 0x51, 0xCB, 0x12,
+0x57, 0x89, 0xF0, 0x22, 0x7D, 0x08, 0x7F, 0x02,
+0xD1, 0xED, 0x90, 0x81, 0xA6, 0xE0, 0x04, 0xF0,
+0x22, 0x7D, 0x08, 0xE4, 0xFF, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x82, 0x9C, 0xEF,
+0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x80, 0x03, 0xE0,
+0x04, 0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x28,
+0x90, 0x05, 0x22, 0xE0, 0x90, 0x82, 0xA0, 0xF0,
+0x7B, 0x26, 0xF1, 0xCC, 0x12, 0x64, 0xE1, 0xEF,
+0x64, 0x01, 0x70, 0x03, 0x12, 0x71, 0x5F, 0x90,
+0x82, 0xA0, 0xE0, 0xFD, 0x7B, 0x27, 0xE4, 0xFF,
+0x12, 0x4C, 0x84, 0x12, 0x72, 0xFA, 0x80, 0x06,
+0x12, 0x72, 0xFA, 0x12, 0x71, 0x5F, 0xF1, 0xBE,
+0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF1,
+0x6A, 0x54, 0x3F, 0xF0, 0xBF, 0x01, 0x02, 0x80,
+0x16, 0xEF, 0x70, 0x02, 0x80, 0x07, 0x90, 0x81,
+0x33, 0xE0, 0x30, 0xE3, 0x0A, 0xF1, 0x76, 0x54,
+0xEF, 0xF1, 0x69, 0x44, 0x40, 0xF0, 0x22, 0xF1,
+0x76, 0x44, 0x10, 0xF1, 0x69, 0x44, 0x80, 0xF0,
+0x22, 0xF0, 0x74, 0x1F, 0x2D, 0xF5, 0x82, 0xE4,
+0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0x74, 0x21,
+0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0xE0, 0x22, 0xE4, 0x90, 0x81, 0xB6, 0xF0, 0x90,
+0x81, 0xB4, 0x74, 0x14, 0xF0, 0x90, 0x81, 0xC2,
+0x74, 0x01, 0xF0, 0xFB, 0x7A, 0x81, 0x79, 0xB4,
+0x12, 0x60, 0xAB, 0x7F, 0x04, 0x90, 0x82, 0xBC,
+0xEF, 0xF0, 0x7F, 0x02, 0x12, 0x43, 0x27, 0x90,
+0x80, 0x01, 0xE0, 0xFF, 0x90, 0x82, 0xBC, 0xE0,
+0xFE, 0xEF, 0x4E, 0x90, 0x80, 0x01, 0xF0, 0x22,
+0x7D, 0x08, 0x7F, 0x02, 0xC1, 0xED, 0x90, 0x04,
+0x1F, 0x74, 0x20, 0xF0, 0x22, 0xE0, 0x04, 0xF0,
+0xE0, 0x7F, 0x00, 0x22, 0x7D, 0xFF, 0xE4, 0xFF,
+0x02, 0x4C, 0x84, 0x90, 0x81, 0x2B, 0xE0, 0x54,
+0xF7, 0xF0, 0x22, 0xE0, 0xFF, 0xC4, 0x13, 0x13,
+0x54, 0x03, 0x22, 0xE4, 0xFB, 0xFA, 0xFD, 0x7F,
+0x01, 0x12, 0x43, 0x4E, 0x90, 0x81, 0xCB, 0xEF,
+0xF0, 0x60, 0xF0, 0x90, 0x80, 0x01, 0xE0, 0xFF,
+0x70, 0x04, 0xA3, 0xE0, 0x60, 0xE5, 0xC2, 0xAF,
+0xEF, 0x30, 0xE1, 0x09, 0x90, 0x80, 0x01, 0xE0,
+0x54, 0xFD, 0xF0, 0x31, 0xD4, 0x11, 0x2E, 0xFF,
+0x30, 0xE2, 0x05, 0x54, 0xFB, 0xF0, 0x11, 0x37,
+0x11, 0x2E, 0xFF, 0x30, 0xE5, 0x0C, 0x54, 0xDF,
+0xF0, 0x12, 0x55, 0x78, 0xBF, 0x01, 0x03, 0x12,
+0x74, 0x57, 0xD2, 0xAF, 0x80, 0xC5, 0xD2, 0xAF,
+0xC2, 0xAF, 0x90, 0x80, 0x01, 0xE0, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFF,
+0x90, 0x80, 0xF9, 0xE0, 0xFE, 0x90, 0x80, 0xF8,
+0xE0, 0xFD, 0xB5, 0x06, 0x04, 0x7E, 0x01, 0x80,
+0x02, 0x7E, 0x00, 0xEE, 0x64, 0x01, 0x60, 0x42,
+0x90, 0x01, 0xAF, 0xE0, 0x70, 0x0A, 0xED, 0x11,
+0x9F, 0xFA, 0x7B, 0x01, 0x51, 0x36, 0x7F, 0x01,
+0xEF, 0x60, 0x2F, 0x90, 0x80, 0xF8, 0x12, 0x5F,
+0xC5, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60,
+0x05, 0xE4, 0x90, 0x80, 0xF8, 0xF0, 0x90, 0x80,
+0xF9, 0xE0, 0xFF, 0x90, 0x80, 0xF8, 0xE0, 0xB5,
+0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00,
+0xEF, 0x70, 0x07, 0x90, 0x80, 0x01, 0xE0, 0x44,
+0x04, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x75,
+0xF0, 0x0F, 0xA4, 0x24, 0x62, 0xF9, 0x74, 0x80,
+0x35, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x80, 0xF8, 0xE0, 0xFF, 0x70,
+0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF,
+0x14, 0xFF, 0x90, 0x80, 0xF9, 0xE0, 0xB5, 0x07,
+0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF,
+0x60, 0x09, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x02,
+0xF0, 0x80, 0x29, 0xC0, 0x01, 0x90, 0x80, 0xF9,
+0xE0, 0x11, 0x9F, 0xA8, 0x01, 0xFC, 0x7D, 0x01,
+0xD0, 0x01, 0x7E, 0x00, 0x7F, 0x0F, 0x12, 0x44,
+0x79, 0x90, 0x80, 0xF9, 0x12, 0x5F, 0xC5, 0xB4,
+0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4,
+0x90, 0x80, 0xF9, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x90, 0x81, 0xDB, 0x74, 0x12, 0xF0, 0x90,
+0x81, 0xE9, 0x74, 0x05, 0xF0, 0x90, 0x81, 0xDD,
+0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xA3, 0xEB, 0xF0,
+0x90, 0x81, 0xD9, 0xE0, 0x90, 0x81, 0xE0, 0xF0,
+0x90, 0x81, 0xDA, 0xE0, 0x90, 0x81, 0xE1, 0xF0,
+0x7B, 0x01, 0x7A, 0x81, 0x79, 0xDB, 0x11, 0xAB,
+0x7F, 0x04, 0x02, 0x5F, 0x9D, 0x31, 0xBA, 0x7F,
+0xF5, 0x7E, 0x00, 0x12, 0x2B, 0x27, 0xBF, 0x01,
+0x06, 0x90, 0x81, 0xD0, 0xE0, 0xA3, 0xF0, 0x31,
+0xBA, 0x7F, 0xF6, 0x7E, 0x00, 0x12, 0x2B, 0x27,
+0xBF, 0x01, 0x08, 0x90, 0x81, 0xD0, 0xE0, 0x90,
+0x81, 0xD2, 0xF0, 0x31, 0xBA, 0x7F, 0xF4, 0x7E,
+0x00, 0x12, 0x2B, 0x27, 0xBF, 0x01, 0x08, 0x90,
+0x81, 0xD0, 0xE0, 0x90, 0x81, 0xD3, 0xF0, 0x31,
+0xBA, 0x7F, 0xF3, 0x7E, 0x00, 0x12, 0x2B, 0x27,
+0xBF, 0x01, 0x08, 0x90, 0x81, 0xD0, 0xE0, 0x90,
+0x81, 0xD4, 0xF0, 0x31, 0xBA, 0x7F, 0xF2, 0x7E,
+0x00, 0x12, 0x2B, 0x27, 0xBF, 0x01, 0x08, 0x90,
+0x81, 0xD0, 0xE0, 0x90, 0x81, 0xD5, 0xF0, 0x90,
+0x81, 0xD1, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0xA3,
+0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x81, 0xD9, 0xF0,
+0x90, 0x81, 0xD5, 0xE0, 0x90, 0x81, 0xDA, 0xF0,
+0x21, 0x09, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0xD0,
+0x22, 0x12, 0x1F, 0xA4, 0xFF, 0x90, 0x81, 0x21,
+0xF0, 0xBF, 0x01, 0x07, 0x31, 0x3D, 0xE4, 0x90,
+0x81, 0x21, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x80, 0x61, 0xE0, 0xFF,
+0x90, 0x80, 0x60, 0xE0, 0xB5, 0x07, 0x04, 0x7F,
+0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70, 0x41,
+0x90, 0x80, 0x60, 0xE0, 0xFE, 0x75, 0xF0, 0x08,
+0x90, 0x80, 0x10, 0x12, 0x44, 0xDF, 0xE0, 0xFD,
+0xEE, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x11, 0xF9,
+0x74, 0x80, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0xAF,
+0x05, 0x12, 0x4F, 0x10, 0x90, 0x80, 0x60, 0x12,
+0x5F, 0xC5, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF,
+0x60, 0x05, 0xE4, 0x90, 0x80, 0x60, 0xF0, 0x12,
+0x5C, 0xD8, 0x90, 0x80, 0x01, 0xE0, 0x44, 0x02,
+0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x81, 0xCC,
+0x12, 0x44, 0xF4, 0x90, 0x82, 0xB5, 0xE0, 0xFF,
+0x04, 0xF0, 0x90, 0x00, 0x01, 0xEF, 0x12, 0x1F,
+0xFC, 0x7F, 0xAF, 0x7E, 0x01, 0x12, 0x53, 0x72,
+0xEF, 0x60, 0x3A, 0x90, 0x81, 0xCC, 0x12, 0x44,
+0xEB, 0x8B, 0x13, 0x8A, 0x14, 0x89, 0x15, 0x90,
+0x00, 0x0E, 0x12, 0x1F, 0xBD, 0x24, 0x02, 0xF5,
+0x16, 0x7B, 0x01, 0x7A, 0x01, 0x79, 0xA0, 0x12,
+0x2B, 0xED, 0x90, 0x81, 0xCC, 0x12, 0x44, 0xEB,
+0x90, 0x00, 0x0E, 0x12, 0x1F, 0xBD, 0x90, 0x01,
+0xAE, 0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0x90, 0x01,
+0xCB, 0xE0, 0x64, 0x80, 0xF0, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0x90, 0x82, 0x5A, 0xEF, 0xF0, 0xA3,
+0xED, 0xF0, 0xA3, 0x12, 0x20, 0xDA, 0x00, 0x00,
+0x00, 0x00, 0xE4, 0x90, 0x82, 0x68, 0xF0, 0x7F,
+0x24, 0x7E, 0x08, 0x12, 0x2D, 0x5C, 0x90, 0x82,
+0x60, 0x12, 0x20, 0xCE, 0x90, 0x82, 0x5A, 0xE0,
+0xFB, 0x70, 0x08, 0x90, 0x82, 0x60, 0x12, 0x44,
+0xD3, 0x80, 0x06, 0xEB, 0x71, 0x89, 0x12, 0x2D,
+0x5C, 0x90, 0x82, 0x64, 0x12, 0x20, 0xCE, 0x90,
+0x82, 0x5B, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE,
+0x78, 0x17, 0x91, 0x05, 0x90, 0x82, 0x64, 0x12,
+0x44, 0xD3, 0xED, 0x54, 0x7F, 0xFD, 0xEC, 0x54,
+0x80, 0xFC, 0x12, 0x44, 0xB5, 0xEC, 0x44, 0x80,
+0xFC, 0x90, 0x82, 0x64, 0x12, 0x20, 0xCE, 0x71,
+0x9C, 0x54, 0x7F, 0xFC, 0x71, 0x83, 0x71, 0xA4,
+0x71, 0x89, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x82,
+0x64, 0x71, 0x80, 0xD0, 0x07, 0xD0, 0x06, 0x12,
+0x2E, 0xA2, 0x71, 0x9C, 0x44, 0x80, 0xFC, 0x71,
+0x83, 0x71, 0xA4, 0x70, 0x04, 0x7F, 0x20, 0x80,
+0x09, 0x90, 0x82, 0x5A, 0xE0, 0xB4, 0x01, 0x16,
+0x7F, 0x28, 0x7E, 0x08, 0x12, 0x2D, 0x5C, 0x78,
+0x08, 0x12, 0x20, 0xA8, 0xEF, 0x54, 0x01, 0xFF,
+0xE4, 0x90, 0x82, 0x68, 0xEF, 0xF0, 0x90, 0x82,
+0x68, 0xE0, 0x90, 0x82, 0x5A, 0x60, 0x0E, 0xE0,
+0x75, 0xF0, 0x08, 0xA4, 0x24, 0x66, 0xF5, 0x82,
+0xE4, 0x34, 0x87, 0x80, 0x0C, 0xE0, 0x75, 0xF0,
+0x08, 0xA4, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34,
+0x87, 0x71, 0x94, 0x12, 0x2D, 0x5C, 0xED, 0x54,
+0x0F, 0xFD, 0xE4, 0xFC, 0x90, 0x82, 0x5C, 0x12,
+0x20, 0xCE, 0x90, 0x82, 0x5C, 0x02, 0x44, 0xD3,
+0x12, 0x44, 0xD3, 0x90, 0x85, 0xBB, 0x02, 0x20,
+0xCE, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x62, 0xF5,
+0x82, 0xE4, 0x34, 0x87, 0xF5, 0x83, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0x22, 0x90, 0x82, 0x60, 0x12,
+0x44, 0xD3, 0xEC, 0x22, 0x7F, 0x24, 0x7E, 0x08,
+0x12, 0x2E, 0xA2, 0x90, 0x82, 0x5A, 0xE0, 0x22,
+0x90, 0x82, 0x78, 0xEF, 0xF0, 0xAB, 0x05, 0x90,
+0x82, 0x7E, 0x12, 0x20, 0xDA, 0x00, 0x00, 0x00,
+0x00, 0xAF, 0x03, 0xE4, 0xFC, 0xFD, 0xFE, 0x78,
+0x14, 0x91, 0x05, 0x90, 0x82, 0x7A, 0x12, 0x44,
+0xD3, 0xED, 0x54, 0x0F, 0xFD, 0xE4, 0xFC, 0x12,
+0x44, 0xB5, 0xEC, 0x54, 0x0F, 0xFC, 0x90, 0x82,
+0x7E, 0x12, 0x20, 0xCE, 0x90, 0x82, 0x78, 0xE0,
+0x75, 0xF0, 0x08, 0xA4, 0x24, 0x60, 0xF5, 0x82,
+0xE4, 0x34, 0x87, 0x71, 0x94, 0xC0, 0x06, 0xC0,
+0x07, 0x90, 0x82, 0x7E, 0x71, 0x80, 0xD0, 0x07,
+0xD0, 0x06, 0x02, 0x2E, 0xA2, 0x12, 0x20, 0xBB,
+0xA8, 0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB, 0x07,
+0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0xE4, 0x90, 0x82, 0x90, 0xF0, 0xA3, 0xF0, 0x91,
+0xE1, 0x90, 0x85, 0xBB, 0x12, 0x20, 0xDA, 0xCC,
+0xF0, 0x00, 0xC0, 0x91, 0xBA, 0x12, 0x20, 0xDA,
+0x00, 0x00, 0x00, 0x14, 0xB1, 0x77, 0x12, 0x20,
+0xDA, 0x00, 0x00, 0x00, 0x00, 0xE4, 0xFD, 0xFF,
+0xB1, 0x4C, 0x7F, 0xE8, 0x7E, 0x08, 0x12, 0x2D,
+0x5C, 0xEF, 0x54, 0x0E, 0xFF, 0xE4, 0xFE, 0xED,
+0x54, 0xF4, 0xFD, 0xEC, 0x54, 0x03, 0xFC, 0xE4,
+0xFB, 0xFA, 0xF9, 0xF8, 0xC3, 0x12, 0x44, 0xC2,
+0x60, 0x18, 0xD3, 0x91, 0xAD, 0x40, 0x09, 0x90,
+0x01, 0xC3, 0xE0, 0x44, 0x02, 0xF0, 0x80, 0x0A,
+0xB1, 0x45, 0x90, 0x82, 0x90, 0x12, 0x53, 0xBD,
+0x80, 0xC8, 0xC3, 0x91, 0xAD, 0x50, 0x17, 0xB1,
+0x6E, 0x44, 0x80, 0xFC, 0x90, 0x82, 0x92, 0x12,
+0x20, 0xCE, 0x90, 0x82, 0x92, 0x71, 0x80, 0x7F,
+0x7C, 0x7E, 0x08, 0x12, 0x2E, 0xA2, 0x90, 0x01,
+0x00, 0x74, 0x3F, 0xF0, 0xA3, 0xE0, 0x54, 0xFD,
+0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44, 0x20, 0xF0,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x82, 0x91,
+0xE0, 0x94, 0xE8, 0x90, 0x82, 0x90, 0xE0, 0x94,
+0x03, 0x22, 0x7F, 0x8C, 0x7E, 0x08, 0x12, 0x2E,
+0xA2, 0x90, 0x85, 0xBB, 0x22, 0x7B, 0x2D, 0x12,
+0x4F, 0xED, 0x91, 0xE1, 0x90, 0x01, 0x37, 0x74,
+0x02, 0xF0, 0xFD, 0x7F, 0x03, 0x12, 0x4F, 0xB9,
+0x91, 0x11, 0xE4, 0xFD, 0x7F, 0x01, 0x02, 0x4B,
+0xE8, 0xE4, 0x90, 0x82, 0xB1, 0xF0, 0xA3, 0xF0,
+0x90, 0x05, 0x22, 0xE0, 0x90, 0x82, 0xB3, 0xF0,
+0x7B, 0x47, 0x12, 0x5F, 0xCC, 0x90, 0x05, 0xF8,
+0xE0, 0x70, 0x1B, 0xA3, 0xE0, 0x70, 0x17, 0xA3,
+0xE0, 0x70, 0x13, 0xA3, 0xE0, 0x70, 0x0F, 0x90,
+0x82, 0xB3, 0xE0, 0xFD, 0x7B, 0x48, 0xE4, 0xFF,
+0x12, 0x4C, 0x84, 0x7F, 0x01, 0x22, 0xD3, 0x90,
+0x82, 0xB2, 0xE0, 0x94, 0xE8, 0x90, 0x82, 0xB1,
+0xE0, 0x94, 0x03, 0x40, 0x16, 0x90, 0x01, 0xC0,
+0xE0, 0x44, 0x20, 0xF0, 0x90, 0x82, 0xB3, 0xE0,
+0xFD, 0x7B, 0x5B, 0xE4, 0xFF, 0x12, 0x4C, 0x84,
+0x7F, 0x00, 0x22, 0xB1, 0x45, 0x90, 0x82, 0xB1,
+0x12, 0x53, 0xBD, 0x80, 0xB0, 0x7F, 0x32, 0x7E,
+0x00, 0x02, 0x32, 0xAA, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0xC0, 0x07, 0xC0, 0x05, 0x90,
+0x82, 0x8C, 0x12, 0x44, 0xD3, 0x90, 0x82, 0x7A,
+0x12, 0x20, 0xCE, 0xD0, 0x05, 0xD0, 0x07, 0x71,
+0xB0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7F, 0x7C,
+0x7E, 0x08, 0x12, 0x2D, 0x5C, 0xEC, 0x22, 0x7F,
+0x70, 0x7E, 0x0E, 0x12, 0x2E, 0xA2, 0x90, 0x82,
+0x8C, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x51, 0x9A, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x7B, 0x2F, 0x12, 0x4F, 0xED, 0x91, 0x11, 0x7D,
+0x08, 0x7F, 0x01, 0x02, 0x4B, 0xE8, 0x12, 0x57,
+0x1B, 0xB1, 0xAA, 0x7A, 0x81, 0x79, 0x14, 0x02,
+0x2B, 0xED, 0x8B, 0x13, 0x8A, 0x14, 0x89, 0x15,
+0x75, 0x16, 0x05, 0x7B, 0x01, 0x22, 0x12, 0x57,
+0x1B, 0xB1, 0xAA, 0x7A, 0x81, 0x79, 0x19, 0x02,
+0x2B, 0xED, 0x12, 0x1F, 0xA4, 0x54, 0x01, 0xFF,
+0x90, 0x81, 0xAF, 0xE0, 0x54, 0xFE, 0x4F, 0xF0,
+0x22, 0x12, 0x1F, 0xA4, 0x90, 0x81, 0x93, 0xF0,
+0x22, 0xF1, 0x8D, 0xFF, 0x54, 0x01, 0xFE, 0x90,
+0x81, 0x94, 0xF1, 0x85, 0x54, 0x02, 0xFF, 0xEE,
+0x54, 0xFD, 0x4F, 0xFF, 0xF0, 0xF1, 0xB5, 0x90,
+0x81, 0x94, 0xF1, 0x96, 0x4E, 0xFF, 0xF0, 0x12,
+0x1F, 0xA4, 0x54, 0x10, 0x25, 0xE0, 0x25, 0xE0,
+0xFE, 0xEF, 0x54, 0xBF, 0x4E, 0x90, 0x81, 0x94,
+0xF0, 0x90, 0x05, 0x52, 0xE0, 0x54, 0x07, 0xFF,
+0x90, 0x81, 0xD0, 0x60, 0x13, 0x12, 0x57, 0x35,
+0xFD, 0x90, 0x05, 0x56, 0xE0, 0xC3, 0x9D, 0x90,
+0x81, 0x96, 0xF0, 0xA3, 0xED, 0xF0, 0x80, 0x23,
+0x12, 0x57, 0x35, 0xFB, 0xFF, 0x90, 0x05, 0x54,
+0xE0, 0xC3, 0x9F, 0xFF, 0xE4, 0x94, 0x00, 0xFE,
+0x7C, 0x00, 0x7D, 0x05, 0x12, 0x20, 0x30, 0x90,
+0x81, 0x96, 0xEF, 0xF0, 0xEB, 0x75, 0xF0, 0x05,
+0x84, 0xA3, 0xF0, 0x12, 0x57, 0x21, 0x12, 0x1F,
+0xA4, 0x20, 0xE0, 0x0A, 0x12, 0x4C, 0x7D, 0x90,
+0x01, 0x57, 0xE4, 0xF0, 0x80, 0x0A, 0x7D, 0x0C,
+0x7F, 0x01, 0x12, 0x4B, 0xE8, 0x12, 0x4F, 0xF3,
+0xF1, 0x9F, 0x20, 0xE0, 0x04, 0xEF, 0x44, 0x20,
+0xF0, 0x12, 0x4F, 0xE5, 0x30, 0xE0, 0x17, 0x90,
+0x81, 0x30, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x81,
+0x32, 0xF0, 0xF1, 0x7D, 0xF1, 0xC2, 0x90, 0x82,
+0xB0, 0x74, 0x06, 0xF0, 0x80, 0x18, 0xE4, 0x90,
+0x81, 0x30, 0xF0, 0x90, 0x81, 0x32, 0x74, 0x0C,
+0xF0, 0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFE, 0xF0,
+0xA3, 0xE0, 0x54, 0xFB, 0xF0, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xAC, 0x07, 0x90,
+0x81, 0x2C, 0xE0, 0x12, 0x5C, 0x37, 0x30, 0xE0,
+0x02, 0xE1, 0x66, 0x90, 0x81, 0x2B, 0xE0, 0x30,
+0xE0, 0x16, 0x90, 0x81, 0x4D, 0xE0, 0x24, 0x05,
+0x90, 0x81, 0x45, 0xF0, 0x90, 0x81, 0x4D, 0xE0,
+0x24, 0x03, 0x90, 0x81, 0x44, 0xF0, 0x80, 0x0E,
+0x90, 0x81, 0x45, 0x74, 0x05, 0xF0, 0x90, 0x81,
+0x44, 0x14, 0xF0, 0x04, 0x2B, 0xFB, 0x90, 0x81,
+0x44, 0xE0, 0xFA, 0x90, 0x81, 0x43, 0xE0, 0xD3,
+0x9A, 0x50, 0x0E, 0x90, 0x81, 0x38, 0xEB, 0xF0,
+0x90, 0x81, 0x45, 0xE0, 0xC3, 0x9D, 0x2C, 0x80,
+0x11, 0xC3, 0xED, 0x9A, 0x2B, 0x90, 0x81, 0x38,
+0xF0, 0x90, 0x81, 0x44, 0xE0, 0xFF, 0xA3, 0xE0,
+0xC3, 0x9F, 0x90, 0x81, 0x48, 0xF0, 0x90, 0x81,
+0x45, 0xE0, 0xFF, 0x24, 0x0A, 0xFD, 0xE4, 0x33,
+0xFC, 0x90, 0x81, 0x48, 0xF1, 0x72, 0x40, 0x04,
+0xEF, 0x24, 0x0A, 0xF0, 0x90, 0x81, 0x48, 0xE0,
+0xFF, 0x24, 0x23, 0xFD, 0xE4, 0x33, 0xFC, 0x90,
+0x81, 0x38, 0xF1, 0x72, 0x40, 0x04, 0xEF, 0x24,
+0x23, 0xF0, 0x90, 0x81, 0x48, 0xE0, 0xFF, 0x7E,
+0x00, 0x90, 0x81, 0x3C, 0xEE, 0xF0, 0xA3, 0xEF,
+0xF0, 0x90, 0x05, 0x58, 0xE0, 0x6F, 0x70, 0x01,
+0xE4, 0x60, 0x02, 0xF1, 0xAB, 0x90, 0x81, 0x2D,
+0xE0, 0x54, 0xFE, 0xF0, 0x80, 0x07, 0x90, 0x81,
+0x2D, 0xE0, 0x44, 0x01, 0xF0, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0xE0, 0xD3, 0x9D, 0xEC, 0x64, 0x80,
+0xF8, 0x74, 0x80, 0x98, 0x22, 0x90, 0x81, 0x2C,
+0xE0, 0x44, 0x04, 0xF0, 0x22, 0xE0, 0x54, 0xFE,
+0x4E, 0xFE, 0xF0, 0xEF, 0x22, 0x90, 0x81, 0xD0,
+0x12, 0x44, 0xF4, 0x02, 0x1F, 0xA4, 0xF0, 0xEE,
+0x54, 0x08, 0xFE, 0xEF, 0x54, 0xF7, 0x22, 0x90,
+0x81, 0x94, 0xE0, 0xFF, 0x13, 0x13, 0x13, 0x54,
+0x1F, 0x22, 0xF0, 0x90, 0x81, 0x3C, 0xA3, 0xE0,
+0x90, 0x05, 0x58, 0xF0, 0x22, 0x12, 0x1F, 0xA4,
+0xFE, 0x54, 0x04, 0xFD, 0xEF, 0x54, 0xFB, 0x4D,
+0xFF, 0x22, 0x90, 0x81, 0x42, 0xE0, 0xFF, 0xA3,
+0xE0, 0xFD, 0x90, 0x81, 0x49, 0xE0, 0xFB, 0x22,
+0x12, 0x1F, 0xA4, 0x90, 0x81, 0xA9, 0xF0, 0x22,
+0x12, 0x1F, 0xA4, 0x90, 0x81, 0x1E, 0xF0, 0x12,
+0x57, 0x38, 0x90, 0x81, 0x1F, 0x12, 0x57, 0x91,
+0x90, 0x81, 0x20, 0xF0, 0x22, 0xE4, 0x90, 0x80,
+0xF8, 0xF0, 0xA3, 0xF0, 0x90, 0x80, 0x60, 0xF0,
+0xA3, 0xF0, 0x22, 0xE4, 0xFD, 0xFF, 0x12, 0x53,
+0x0C, 0xE4, 0xFF, 0x22, 0x90, 0x81, 0xA1, 0xE0,
+0x30, 0xE0, 0x71, 0x90, 0x81, 0xA5, 0xE0, 0x04,
+0xF0, 0x90, 0x81, 0xA8, 0xE0, 0x64, 0x01, 0x70,
+0x2F, 0x90, 0x81, 0xA1, 0x31, 0xEE, 0x30, 0xE0,
+0x27, 0x90, 0x81, 0xA7, 0xE0, 0x70, 0x21, 0x90,
+0x81, 0xA4, 0xE0, 0xFE, 0xA3, 0xE0, 0xC3, 0x9E,
+0x40, 0x16, 0x91, 0xFD, 0x30, 0xE0, 0x09, 0x12,
+0x67, 0xFB, 0x12, 0x57, 0x89, 0xF0, 0x80, 0x08,
+0x12, 0x5E, 0x89, 0x12, 0x57, 0x89, 0xF0, 0x22,
+0x90, 0x81, 0xA5, 0xE0, 0xFF, 0x90, 0x81, 0xA2,
+0xE0, 0xD3, 0x9F, 0x50, 0x27, 0x90, 0x06, 0x92,
+0xE0, 0x20, 0xE2, 0x11, 0x90, 0x81, 0xA7, 0xE0,
+0x70, 0x0B, 0x12, 0x5E, 0xDC, 0x90, 0x81, 0xA0,
+0xE0, 0x04, 0xF0, 0x80, 0x06, 0x90, 0x06, 0x92,
+0x74, 0x04, 0xF0, 0xE4, 0x90, 0x81, 0xA5, 0xF0,
+0x90, 0x81, 0xA7, 0xF0, 0x22, 0x12, 0x47, 0xEB,
+0x90, 0x81, 0x30, 0xE0, 0x60, 0x2A, 0x90, 0x81,
+0x2C, 0xB1, 0x6C, 0x30, 0xE0, 0x0B, 0x90, 0x01,
+0x3B, 0xE0, 0x30, 0xE4, 0x04, 0x31, 0x06, 0x31,
+0x00, 0x90, 0x82, 0xBE, 0xE0, 0x04, 0xF0, 0xE0,
+0xC3, 0x94, 0x80, 0x40, 0x0B, 0x90, 0x01, 0x98,
+0xE0, 0x54, 0xFE, 0xF0, 0xE0, 0x44, 0x01, 0xF0,
+0x12, 0x47, 0x80, 0xBF, 0x03, 0x14, 0x90, 0x81,
+0xA9, 0xE0, 0xB4, 0x01, 0x0D, 0x90, 0x01, 0xB8,
+0xE0, 0x04, 0xF0, 0x90, 0x05, 0x21, 0xE0, 0x44,
+0x80, 0xF0, 0x11, 0x04, 0xD1, 0xBF, 0xE4, 0x90,
+0x81, 0xA0, 0xF0, 0x51, 0xCE, 0x90, 0x81, 0x94,
+0xE0, 0x30, 0xE0, 0x0C, 0xE4, 0xF5, 0x1D, 0x90,
+0x81, 0x96, 0x12, 0x49, 0x30, 0x12, 0x4F, 0xF3,
+0x90, 0x80, 0x07, 0xE0, 0xB4, 0x01, 0x10, 0x12,
+0x67, 0x9F, 0x20, 0xE0, 0x0A, 0xEF, 0xC4, 0x13,
+0x54, 0x07, 0x30, 0xE0, 0x02, 0xD1, 0x83, 0x22,
+0x7D, 0x01, 0x7F, 0x02, 0x80, 0x04, 0x7D, 0x02,
+0x7F, 0x02, 0x74, 0x3D, 0x51, 0x98, 0xFE, 0xF6,
+0x74, 0x30, 0x41, 0x81, 0x90, 0x05, 0x62, 0xE0,
+0xFE, 0x90, 0x05, 0x61, 0xE0, 0xFD, 0xED, 0x78,
+0x02, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9,
+0xFF, 0x90, 0x81, 0xB0, 0xEE, 0xF0, 0xA3, 0xEF,
+0xF0, 0x12, 0x4F, 0xC6, 0x60, 0x02, 0x21, 0xD7,
+0x90, 0x81, 0x30, 0xE0, 0x70, 0x02, 0x21, 0xD7,
+0xB1, 0x60, 0x64, 0x01, 0x70, 0x22, 0x90, 0x06,
+0xAB, 0xE0, 0x90, 0x81, 0x37, 0xF0, 0x90, 0x06,
+0xAA, 0xE0, 0x90, 0x81, 0x36, 0xF0, 0xA3, 0xE0,
+0xFF, 0x70, 0x08, 0x90, 0x81, 0x36, 0xE0, 0xFE,
+0xFF, 0x80, 0x00, 0x90, 0x81, 0x37, 0xEF, 0xF0,
+0xE4, 0x90, 0x81, 0x39, 0xF0, 0xA3, 0x12, 0x67,
+0xAA, 0x51, 0xC3, 0x51, 0x6C, 0x54, 0xEF, 0xF0,
+0x12, 0x59, 0x69, 0x90, 0x81, 0x2C, 0x12, 0x67,
+0xA2, 0x30, 0xE0, 0x50, 0xEF, 0xC4, 0x13, 0x13,
+0x54, 0x03, 0x20, 0xE0, 0x1E, 0x31, 0xD8, 0x6F,
+0x70, 0x42, 0x90, 0x81, 0x2C, 0xE0, 0x44, 0x40,
+0xF0, 0xB1, 0x58, 0x31, 0xE0, 0x51, 0x90, 0x31,
+0x00, 0x31, 0x06, 0x90, 0x81, 0x37, 0xE0, 0x14,
+0xF0, 0x80, 0x29, 0x90, 0x81, 0x2E, 0xE0, 0xC4,
+0x54, 0x0F, 0x64, 0x01, 0x70, 0x1E, 0x31, 0xD8,
+0xFE, 0x6F, 0x60, 0x18, 0x90, 0x05, 0x73, 0xE0,
+0xFF, 0xEE, 0x6F, 0x60, 0x0F, 0x31, 0xEB, 0x30,
+0xE0, 0x0A, 0xEF, 0x54, 0xBF, 0x31, 0xE0, 0x51,
+0x79, 0x12, 0x4F, 0xAF, 0x12, 0x67, 0x7D, 0x22,
+0x90, 0x81, 0x36, 0xE0, 0xFF, 0xA3, 0xE0, 0x22,
+0xF0, 0x90, 0x01, 0x3F, 0x74, 0x10, 0xF0, 0xFD,
+0x7F, 0x03, 0x22, 0x90, 0x81, 0x2C, 0xE0, 0xFF,
+0x13, 0x13, 0x54, 0x3F, 0x22, 0x90, 0x81, 0x2C,
+0x12, 0x67, 0xA2, 0x30, 0xE0, 0x0B, 0xEF, 0xC4,
+0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, 0x02, 0x31,
+0x06, 0x90, 0x81, 0x2B, 0x31, 0xEE, 0x30, 0xE0,
+0x09, 0xEF, 0x51, 0x6A, 0x54, 0x07, 0x70, 0x49,
+0x80, 0x44, 0x90, 0x81, 0x39, 0xE0, 0x04, 0xF0,
+0x90, 0x81, 0x34, 0xE0, 0x54, 0xEF, 0xF0, 0x90,
+0x81, 0x8D, 0xE0, 0xFF, 0x90, 0x81, 0x39, 0xE0,
+0xD3, 0x9F, 0x40, 0x2A, 0x12, 0x4F, 0xC6, 0x70,
+0x28, 0x12, 0x47, 0xE4, 0x70, 0x02, 0x80, 0x22,
+0x90, 0x81, 0x3A, 0xE0, 0x04, 0xF0, 0xE0, 0xD3,
+0x94, 0x02, 0x40, 0x09, 0x51, 0x62, 0xE4, 0x90,
+0x81, 0x3A, 0xF0, 0x80, 0x03, 0x12, 0x47, 0xB5,
+0xE4, 0x90, 0x81, 0x39, 0xF0, 0x22, 0x12, 0x59,
+0x40, 0x22, 0x90, 0x81, 0x2C, 0xE0, 0x54, 0xFB,
+0xF0, 0x22, 0x54, 0xFB, 0xF0, 0x90, 0x81, 0x34,
+0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x7D, 0x10, 0xE4,
+0xFF, 0x74, 0x45, 0x51, 0x98, 0xFE, 0xF6, 0x74,
+0x38, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x01, 0xF5,
+0x83, 0xEE, 0xF0, 0x22, 0x7D, 0x10, 0xE4, 0xFF,
+0x74, 0x45, 0x2F, 0xF8, 0xE6, 0x4D, 0x80, 0xE5,
+0x2F, 0xF8, 0xE6, 0xFE, 0xED, 0xF4, 0x5E, 0x22,
+0x12, 0x4F, 0xC6, 0x70, 0x1D, 0x90, 0x81, 0x30,
+0xE0, 0x60, 0x17, 0x90, 0x81, 0x34, 0xE0, 0x20,
+0xE4, 0x10, 0x51, 0xC3, 0xF0, 0x90, 0x81, 0x2B,
+0xE0, 0x51, 0x6A, 0x54, 0x07, 0x70, 0x03, 0x12,
+0x59, 0x40, 0x22, 0x90, 0x01, 0x57, 0xE4, 0xF0,
+0x90, 0x01, 0x3C, 0x74, 0x02, 0x22, 0x12, 0x57,
+0xED, 0x30, 0xE0, 0x25, 0xEF, 0x30, 0xE0, 0x21,
+0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x19,
+0x90, 0x81, 0x00, 0xE0, 0x70, 0x0D, 0x51, 0xFA,
+0x90, 0x01, 0xC7, 0x74, 0x66, 0xF0, 0xE4, 0xFF,
+0x02, 0x5E, 0x9E, 0x90, 0x81, 0x00, 0xE0, 0x14,
+0xF0, 0x22, 0xE4, 0x90, 0x82, 0x4F, 0xF0, 0x90,
+0x80, 0xFC, 0xE0, 0xFE, 0x54, 0x01, 0x90, 0x82,
+0x4F, 0xF0, 0xEE, 0x54, 0xFE, 0x90, 0x80, 0xFC,
+0xF0, 0x7D, 0x08, 0xE4, 0xFF, 0x31, 0x0A, 0x90,
+0x82, 0x4F, 0xE0, 0x60, 0x10, 0x90, 0x02, 0x09,
+0xE0, 0x90, 0x04, 0x24, 0xF0, 0x90, 0x02, 0x09,
+0xE0, 0x90, 0x04, 0x25, 0xF0, 0xE4, 0x90, 0x81,
+0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x71, 0xA8, 0x90,
+0x81, 0xB4, 0xEE, 0xF0, 0xA3, 0xEF, 0x12, 0x57,
+0xEC, 0x30, 0xE0, 0x14, 0x90, 0x81, 0xB5, 0xE0,
+0x20, 0xE0, 0x0D, 0x51, 0xFA, 0x90, 0x02, 0x86,
+0xE0, 0x30, 0xE2, 0x04, 0xE0, 0x54, 0xFB, 0xF0,
+0x22, 0x12, 0x4F, 0xE5, 0x30, 0xE0, 0x0A, 0x30,
+0xE0, 0x45, 0x90, 0x81, 0x2B, 0xE0, 0x30, 0xE0,
+0x3E, 0x90, 0x81, 0x1E, 0xE0, 0x60, 0x2E, 0x90,
+0x01, 0x63, 0xE4, 0xF0, 0x90, 0x81, 0x1F, 0xE0,
+0x60, 0x08, 0xF5, 0x2D, 0xE4, 0xF5, 0x2E, 0xFB,
+0x80, 0x10, 0x90, 0x81, 0x20, 0xE0, 0xFB, 0x60,
+0x07, 0xE4, 0xF5, 0x2D, 0xF5, 0x2E, 0x80, 0x02,
+0xB1, 0x50, 0x7D, 0x01, 0x7F, 0x60, 0x7E, 0x01,
+0x12, 0x31, 0x21, 0x80, 0x07, 0x51, 0x75, 0x90,
+0x01, 0x63, 0xE4, 0xF0, 0x12, 0x5E, 0x96, 0x22,
+0xE4, 0x90, 0x81, 0xB8, 0xF0, 0xA3, 0xF0, 0x90,
+0x00, 0x9E, 0xE0, 0x90, 0x81, 0xBA, 0xF0, 0x90,
+0x00, 0x9F, 0xE0, 0x90, 0x81, 0xBB, 0xF0, 0xE0,
+0xFD, 0xFE, 0x90, 0x81, 0xBA, 0xE0, 0xFC, 0xFB,
+0xEB, 0xFF, 0x90, 0x81, 0xB6, 0xEE, 0xF0, 0xA3,
+0xEF, 0xF0, 0x90, 0x00, 0x9E, 0xE0, 0xFF, 0xEC,
+0xB5, 0x07, 0x09, 0xA3, 0xE0, 0xFF, 0xED, 0xB5,
+0x07, 0x02, 0x80, 0x11, 0xC3, 0x90, 0x81, 0xB9,
+0xE0, 0x94, 0x64, 0x90, 0x81, 0xB8, 0xE0, 0x94,
+0x00, 0x40, 0x0B, 0xB1, 0x40, 0x90, 0x81, 0xB6,
+0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0x90, 0x81,
+0xB8, 0x12, 0x53, 0xBD, 0x80, 0xA9, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xB1, 0x84, 0xEF,
+0x64, 0x01, 0x60, 0x05, 0x75, 0x0D, 0x01, 0x80,
+0x40, 0x90, 0x81, 0x34, 0xE0, 0xFF, 0x54, 0x03,
+0x60, 0x05, 0x75, 0x0D, 0x02, 0x80, 0x32, 0xEF,
+0x30, 0xE2, 0x05, 0x75, 0x0D, 0x08, 0x80, 0x29,
+0x90, 0x81, 0x34, 0xE0, 0x30, 0xE4, 0x05, 0x75,
+0x0D, 0x10, 0x80, 0x1D, 0x31, 0xEB, 0x20, 0xE0,
+0x05, 0x75, 0x0D, 0x20, 0x80, 0x13, 0xB1, 0xB9,
+0x8F, 0x0E, 0xE5, 0x0E, 0x64, 0x01, 0x60, 0x05,
+0x85, 0x0E, 0x0D, 0x80, 0x04, 0xB1, 0x48, 0x80,
+0x0E, 0x90, 0x01, 0xB9, 0x74, 0x04, 0xF0, 0x90,
+0x01, 0xB8, 0xE5, 0x0D, 0xF0, 0x7F, 0x00, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0xB1, 0x04, 0x90, 0x81,
+0xB4, 0xEF, 0xF0, 0x30, 0xE0, 0x05, 0x7D, 0x01,
+0xE4, 0x80, 0x02, 0xE4, 0xFD, 0xFF, 0x12, 0x4B,
+0xE8, 0x90, 0x81, 0xB4, 0xE0, 0x30, 0xE6, 0x11,
+0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x04, 0xE4,
+0xF0, 0x80, 0x06, 0x90, 0x01, 0x2F, 0x74, 0x80,
+0xF0, 0x90, 0x81, 0x2B, 0xE0, 0x30, 0xE0, 0x2E,
+0x91, 0xF5, 0x30, 0xE1, 0x0D, 0xE0, 0x44, 0x04,
+0xF0, 0x90, 0x04, 0xEC, 0xE0, 0x54, 0xFD, 0xF0,
+0x80, 0x04, 0xE0, 0x54, 0xFB, 0xF0, 0x91, 0xF5,
+0x30, 0xE5, 0x0D, 0xE0, 0x44, 0x08, 0xF0, 0x90,
+0x04, 0xEC, 0xE0, 0x54, 0xDF, 0xF0, 0x80, 0x21,
+0xE0, 0x54, 0xF7, 0xF0, 0x80, 0x1B, 0x90, 0x81,
+0x2D, 0x31, 0xEE, 0x30, 0xE0, 0x07, 0x90, 0x04,
+0xEC, 0xE0, 0x44, 0x02, 0xF0, 0x91, 0xFD, 0x30,
+0xE0, 0x07, 0x90, 0x04, 0xEC, 0xE0, 0x44, 0x20,
+0xF0, 0x12, 0x67, 0xC2, 0x90, 0x82, 0xB0, 0x74,
+0x02, 0xF0, 0x02, 0x66, 0xA6, 0x90, 0x04, 0xEC,
+0xE0, 0x90, 0x81, 0x2D, 0x22, 0xEF, 0x13, 0x13,
+0x13, 0x54, 0x1F, 0x22, 0xE4, 0x90, 0x81, 0xB6,
+0xF0, 0xA3, 0xF0, 0x90, 0x00, 0x83, 0xE0, 0x90,
+0x81, 0xB5, 0xF0, 0x90, 0x00, 0x83, 0xE0, 0xFE,
+0x90, 0x81, 0xB5, 0xE0, 0xFF, 0xB5, 0x06, 0x01,
+0x22, 0xC3, 0x90, 0x81, 0xB7, 0xE0, 0x94, 0x64,
+0x90, 0x81, 0xB6, 0xE0, 0x94, 0x00, 0x40, 0x08,
+0xB1, 0x40, 0x90, 0x81, 0xB5, 0xE0, 0xFF, 0x22,
+0x90, 0x81, 0xB6, 0x12, 0x53, 0xBD, 0x80, 0xCB,
+0x90, 0x01, 0xC0, 0xE0, 0x44, 0x40, 0xF0, 0x22,
+0x90, 0x01, 0xB8, 0xE4, 0xF0, 0x7F, 0x01, 0x22,
+0x75, 0x2D, 0x20, 0xE4, 0xF5, 0x2E, 0xFB, 0x22,
+0x90, 0x81, 0x36, 0xE0, 0x90, 0x05, 0x73, 0x22,
+0x90, 0x81, 0x2E, 0xE0, 0xFF, 0xC4, 0x54, 0x0F,
+0x22, 0x90, 0x81, 0x2B, 0xE0, 0x13, 0x13, 0x13,
+0x54, 0x1F, 0x22, 0x90, 0x80, 0xFF, 0xE0, 0x60,
+0x08, 0x90, 0x80, 0xFC, 0xE0, 0x44, 0x10, 0xF0,
+0x22, 0x02, 0x5E, 0x93, 0x90, 0x04, 0x1A, 0xE0,
+0xF4, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x04,
+0x1B, 0xE0, 0x54, 0x07, 0x64, 0x07, 0x7F, 0x01,
+0x60, 0x02, 0x7F, 0x00, 0x22, 0x12, 0x57, 0xED,
+0x30, 0xE0, 0x15, 0xE4, 0x90, 0x80, 0xFF, 0xF0,
+0x90, 0x80, 0xFC, 0xE0, 0x30, 0xE0, 0x09, 0xC4,
+0x54, 0x0F, 0x30, 0xE0, 0x03, 0x12, 0x5E, 0x93,
+0x22, 0x90, 0x81, 0x32, 0xE0, 0xD3, 0x94, 0x00,
+0x40, 0x06, 0x75, 0x55, 0x04, 0x7F, 0xFF, 0x22,
+0x90, 0x81, 0x93, 0xE0, 0x60, 0x06, 0x75, 0x55,
+0x80, 0x7F, 0xFF, 0x22, 0x7F, 0x01, 0x22, 0x90,
+0x81, 0x2B, 0xE0, 0x54, 0xFB, 0xF0, 0xE4, 0x90,
+0x81, 0x39, 0xF0, 0xA3, 0xF0, 0x90, 0x81, 0x34,
+0xF0, 0x90, 0x81, 0x2C, 0xE0, 0x54, 0xF7, 0xF0,
+0x54, 0xBF, 0xF0, 0x12, 0x4F, 0xAF, 0x7D, 0x10,
+0x7F, 0x03, 0x41, 0x79, 0x90, 0x81, 0xD3, 0x12,
+0x44, 0xF4, 0xB1, 0xD7, 0x90, 0x81, 0x30, 0xE0,
+0xFF, 0x12, 0x4E, 0x0C, 0x90, 0x81, 0x30, 0xE0,
+0x60, 0x1B, 0x90, 0x81, 0xD3, 0x12, 0x57, 0x35,
+0x54, 0x0F, 0xFF, 0x12, 0x57, 0x92, 0xFD, 0xD1,
+0x56, 0x12, 0x67, 0xC2, 0x90, 0x82, 0xB0, 0x74,
+0x01, 0xF0, 0x12, 0x66, 0xA6, 0x22, 0xE4, 0x90,
+0x81, 0xB4, 0xF0, 0x90, 0x81, 0x30, 0xE0, 0x60,
+0x1C, 0xE4, 0xFF, 0x12, 0x4E, 0x80, 0xBF, 0x01,
+0x14, 0xB1, 0x58, 0xF0, 0x90, 0x81, 0xB4, 0x74,
+0x01, 0xF0, 0xE4, 0x90, 0x81, 0x37, 0xF0, 0x04,
+0x60, 0x03, 0x12, 0x49, 0xA2, 0x22, 0xEF, 0x24,
+0xFE, 0x60, 0x0B, 0x04, 0x70, 0x24, 0x90, 0x81,
+0x36, 0x74, 0x02, 0xF0, 0x80, 0x13, 0xED, 0x70,
+0x06, 0x90, 0x81, 0x90, 0xE0, 0x80, 0x02, 0xED,
+0x14, 0x90, 0x81, 0x36, 0xF0, 0x90, 0x81, 0x36,
+0xE0, 0xA3, 0xF0, 0x90, 0x81, 0x2C, 0xE0, 0x44,
+0x08, 0xF0, 0x22, 0x90, 0x81, 0x94, 0xE0, 0x30,
+0xE0, 0x34, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0,
+0x2D, 0x90, 0x82, 0xC2, 0xE0, 0x04, 0xF0, 0xE0,
+0xD3, 0x94, 0xC8, 0x40, 0x21, 0x90, 0x81, 0x94,
+0xE0, 0x54, 0xDF, 0xF0, 0xE4, 0x90, 0x82, 0xC2,
+0xF0, 0x90, 0x81, 0x94, 0xE0, 0x13, 0x30, 0xE0,
+0x0D, 0x90, 0x81, 0x2B, 0xE0, 0x44, 0x01, 0xF0,
+0x90, 0x81, 0x3B, 0x74, 0xD0, 0xF0, 0x22, 0x90,
+0x81, 0x9D, 0xE0, 0x30, 0xE0, 0x35, 0x12, 0x4F,
+0xC6, 0x70, 0x30, 0x90, 0x82, 0xC5, 0xE0, 0x04,
+0xF0, 0xE0, 0xB4, 0x0A, 0x0B, 0x90, 0x81, 0x9F,
+0xE0, 0x04, 0xF0, 0xE4, 0x90, 0x82, 0xC5, 0xF0,
+0x90, 0x81, 0x9F, 0xE0, 0xFF, 0x90, 0x81, 0x9E,
+0xE0, 0xD3, 0x9F, 0x50, 0x0E, 0x90, 0x81, 0xA0,
+0xE0, 0x70, 0x08, 0xE4, 0x90, 0x81, 0x9F, 0xF0,
+0x12, 0x5F, 0xB8, 0x22, 0x90, 0x02, 0x87, 0xE0,
+0x60, 0x02, 0x80, 0x08, 0x90, 0x01, 0x00, 0xE0,
+0x64, 0x3F, 0x60, 0x05, 0x75, 0x54, 0x01, 0x80,
+0x22, 0x90, 0x02, 0x96, 0xE0, 0x60, 0x05, 0x75,
+0x54, 0x10, 0x80, 0x17, 0x90, 0x02, 0x86, 0xE0,
+0x20, 0xE1, 0x02, 0x80, 0x07, 0x90, 0x02, 0x86,
+0xE0, 0x30, 0xE3, 0x05, 0x75, 0x54, 0x04, 0x80,
+0x02, 0xA1, 0x48, 0x90, 0x01, 0xB9, 0x74, 0x08,
+0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x54, 0xF0, 0x7F,
+0x00, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x7D, 0x08, 0xED, 0x14, 0xF9, 0x24, 0x22,
+0xF1, 0x96, 0x60, 0x39, 0x7C, 0x08, 0xEC, 0x14,
+0x90, 0x82, 0xBD, 0xF0, 0x74, 0x22, 0x29, 0xF1,
+0x96, 0xFB, 0x7A, 0x00, 0x90, 0x82, 0xBD, 0x12,
+0x5E, 0x04, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33,
+0xCE, 0xD8, 0xF9, 0xFF, 0xEE, 0x5A, 0xFE, 0xEF,
+0x5B, 0x4E, 0x60, 0x0F, 0xE9, 0x75, 0xF0, 0x08,
+0xA4, 0xFF, 0x90, 0x82, 0xBD, 0xE0, 0x2F, 0x04,
+0xFF, 0x80, 0x06, 0xDC, 0xC9, 0xDD, 0xBC, 0x7F,
+0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF5, 0x82,
+0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, 0x22, 0x75,
+0x3D, 0x10, 0xE4, 0xF5, 0x3E, 0x75, 0x3F, 0x87,
+0x75, 0x40, 0x03, 0x90, 0x01, 0x30, 0xE5, 0x3D,
+0xF0, 0xA3, 0xE5, 0x3E, 0xF0, 0xA3, 0xE5, 0x3F,
+0xF0, 0xA3, 0xE5, 0x40, 0xF0, 0x22, 0x75, 0x45,
+0x0F, 0x75, 0x46, 0x01, 0x75, 0x47, 0x23, 0x75,
+0x48, 0x62, 0x90, 0x01, 0x38, 0xE5, 0x45, 0xF0,
+0xA3, 0xE5, 0x46, 0xF0, 0xA3, 0xE5, 0x47, 0xF0,
+0xA3, 0xE5, 0x48, 0xF0, 0x22, 0x7F, 0x02, 0x90,
+0x81, 0x9C, 0xE0, 0xFE, 0xEF, 0xC3, 0x9E, 0x50,
+0x18, 0xEF, 0x25, 0xE0, 0x24, 0x81, 0xF8, 0xE6,
+0x30, 0xE4, 0x0B, 0x90, 0x01, 0xB8, 0x74, 0x08,
+0xF0, 0xA3, 0xF0, 0x7F, 0x00, 0x22, 0x0F, 0x80,
+0xDE, 0x7F, 0x01, 0x22, 0x90, 0x01, 0x34, 0xE0,
+0x55, 0x3D, 0xF5, 0x41, 0xA3, 0xE0, 0x55, 0x3E,
+0xF5, 0x42, 0xA3, 0xE0, 0x55, 0x3F, 0xF5, 0x43,
+0xA3, 0xE0, 0x55, 0x40, 0xF5, 0x44, 0x90, 0x01,
+0x34, 0xE5, 0x41, 0xF0, 0xA3, 0xE5, 0x42, 0xF0,
+0xA3, 0xE5, 0x43, 0xF0, 0xA3, 0xE5, 0x44, 0xF0,
+0x22, 0x90, 0x01, 0x3C, 0xE0, 0x55, 0x45, 0xF5,
+0x49, 0xA3, 0xE0, 0x55, 0x46, 0xF5, 0x4A, 0xA3,
+0xE0, 0x55, 0x47, 0xF5, 0x4B, 0xA3, 0xE0, 0x55,
+0x48, 0xF5, 0x4C, 0x90, 0x01, 0x3C, 0xE5, 0x49,
+0xF0, 0xA3, 0xE5, 0x4A, 0xF0, 0xA3, 0xE5, 0x4B,
+0xF0, 0xA3, 0xE5, 0x4C, 0xF0, 0x53, 0x91, 0xDF,
+0x22, 0x90, 0x01, 0xCF, 0xE0, 0x90, 0x82, 0xBF,
+0xF0, 0xE0, 0xFF, 0x30, 0xE0, 0x07, 0x90, 0x01,
+0xCF, 0xE0, 0x54, 0xFE, 0xF0, 0xEF, 0x30, 0xE5,
+0x23, 0x90, 0x01, 0xCF, 0xE0, 0x54, 0xDF, 0xF0,
+0x90, 0x01, 0x34, 0x74, 0x20, 0xF0, 0xE4, 0xF5,
+0xA8, 0xF5, 0xE8, 0x12, 0x50, 0x6F, 0x90, 0x00,
+0x03, 0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x03, 0x12,
+0x32, 0x1E, 0x80, 0xFE, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x82, 0xA6, 0xED,
+0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x82, 0xA5, 0xEF,
+0xF0, 0xE4, 0xFD, 0xFC, 0x31, 0x40, 0x7C, 0x00,
+0xAD, 0x07, 0x90, 0x82, 0xA5, 0xE0, 0x90, 0x04,
+0x25, 0xF0, 0x90, 0x82, 0xA6, 0xE0, 0x60, 0x0E,
+0x74, 0x0F, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC,
+0xF5, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0xAF, 0x05,
+0x74, 0x08, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC,
+0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x09, 0x2F, 0xF5,
+0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54,
+0xF0, 0xF0, 0xAF, 0x05, 0x31, 0x54, 0xE0, 0x20,
+0xE1, 0x15, 0x54, 0x01, 0xFE, 0x90, 0x82, 0xA7,
+0xE0, 0x25, 0xE0, 0x25, 0xE0, 0xFB, 0xEE, 0x44,
+0x02, 0x4B, 0xFE, 0x31, 0x54, 0xEE, 0xF0, 0x90,
+0x82, 0xA8, 0xE0, 0xFF, 0xAE, 0x05, 0x74, 0x1E,
+0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0xEF, 0xF0, 0x74, 0x21, 0x2E, 0x12, 0x5F, 0x79,
+0x54, 0xF7, 0xF0, 0xAE, 0x04, 0xAF, 0x05, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x74, 0x2F, 0x2E, 0xF5,
+0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0xE0, 0xFF,
+0xE4, 0xFE, 0xEF, 0xC3, 0x13, 0xFD, 0xEF, 0x30,
+0xE0, 0x02, 0x7E, 0x80, 0x90, 0xFD, 0x10, 0xED,
+0xF0, 0xAF, 0x06, 0x22, 0x74, 0x16, 0x2F, 0xF5,
+0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x90,
+0x80, 0x0B, 0xE0, 0xFF, 0x90, 0x82, 0x9D, 0xE0,
+0xFB, 0x90, 0x82, 0xA8, 0x74, 0x0A, 0xF0, 0x7D,
+0x01, 0x11, 0x9D, 0x90, 0x82, 0x9E, 0xEE, 0xF0,
+0xFC, 0xA3, 0xEF, 0xF0, 0xFD, 0x90, 0x82, 0x9C,
+0xE0, 0xFF, 0x12, 0x5F, 0x3F, 0x90, 0x82, 0x9E,
+0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x04, 0x80,
+0xE0, 0x54, 0x0F, 0xFD, 0xAC, 0x07, 0x31, 0xF8,
+0x44, 0x01, 0xF0, 0x31, 0xF8, 0x54, 0xFB, 0xF0,
+0xAC, 0x07, 0x74, 0x16, 0x2C, 0x31, 0x57, 0xE0,
+0x44, 0xFA, 0xF0, 0x74, 0x15, 0x2C, 0xF5, 0x82,
+0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x1F,
+0xF0, 0xAC, 0x07, 0x74, 0x06, 0x2C, 0xF5, 0x82,
+0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x0F,
+0xF0, 0x90, 0x04, 0x53, 0xE4, 0xF0, 0x90, 0x04,
+0x52, 0xF0, 0x90, 0x04, 0x51, 0x74, 0xFF, 0xF0,
+0x90, 0x04, 0x50, 0x74, 0xFD, 0xF0, 0x74, 0x14,
+0x2C, 0x31, 0xF0, 0xE0, 0x54, 0xC0, 0x4D, 0xFD,
+0x74, 0x14, 0x2F, 0x31, 0xF0, 0xED, 0xF0, 0x22,
+0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22,
+0x74, 0x11, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC,
+0xF5, 0x83, 0xE0, 0x22, 0x7D, 0x01, 0x11, 0x9D,
+0x90, 0x81, 0xD0, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0,
+0xE4, 0x90, 0x81, 0xD6, 0xF0, 0x22, 0x90, 0x04,
+0x1D, 0xE0, 0x70, 0x1C, 0x90, 0x80, 0x0A, 0xE0,
+0xFF, 0x90, 0x82, 0xA8, 0x74, 0x09, 0xF0, 0x7B,
+0x18, 0xE4, 0xFD, 0x11, 0x9D, 0x90, 0x81, 0xB2,
+0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0x5F, 0xBE,
+0x22, 0x90, 0x01, 0xC4, 0x74, 0x39, 0xF0, 0x74,
+0x72, 0xA3, 0xF0, 0x90, 0x00, 0x90, 0xE0, 0x20,
+0xE0, 0xF9, 0x74, 0x39, 0x04, 0x90, 0x01, 0xC4,
+0xF0, 0x74, 0x72, 0xA3, 0xF0, 0x22, 0x90, 0x81,
+0x3B, 0xE0, 0xFD, 0x7F, 0x93, 0x12, 0x32, 0x1E,
+0x90, 0x81, 0x31, 0xE0, 0x60, 0x12, 0x90, 0x01,
+0x2F, 0xE0, 0x30, 0xE7, 0x05, 0x74, 0x10, 0xF0,
+0x80, 0x06, 0x90, 0x01, 0x2F, 0x74, 0x90, 0xF0,
+0x90, 0x00, 0x08, 0xE0, 0x44, 0x10, 0xFD, 0x7F,
+0x08, 0x12, 0x32, 0x1E, 0x7F, 0x01, 0x12, 0x53,
+0xC4, 0x90, 0x81, 0x3B, 0xE0, 0x20, 0xE0, 0x0C,
+0x90, 0x00, 0x26, 0xE0, 0x44, 0x80, 0xFD, 0x7F,
+0x26, 0x12, 0x32, 0x1E, 0x90, 0x00, 0x90, 0xE0,
+0x44, 0x01, 0xFD, 0x7F, 0x90, 0x12, 0x32, 0x1E,
+0x7F, 0x14, 0x7E, 0x00, 0x02, 0x32, 0xAA, 0x90,
+0x81, 0xAA, 0xE0, 0x54, 0x7F, 0xF0, 0x54, 0xBF,
+0xF0, 0x54, 0xDF, 0xF0, 0x54, 0xF0, 0xF0, 0xE4,
+0x90, 0x81, 0xAC, 0xF0, 0x90, 0x81, 0xAA, 0xE0,
+0x54, 0xEF, 0xF0, 0x22, 0x7B, 0x2E, 0x51, 0xD7,
+0x7D, 0x02, 0x7F, 0x01, 0x02, 0x4B, 0xE8, 0x7D,
+0x6F, 0x7F, 0xFF, 0x02, 0x4C, 0x84, 0x90, 0x81,
+0x2B, 0xE0, 0x30, 0xE0, 0x03, 0x12, 0x55, 0x38,
+0x22, 0x90, 0x81, 0x94, 0xE0, 0x54, 0xFE, 0xF0,
+0x54, 0xFD, 0xF0, 0x54, 0xEF, 0xF0, 0x44, 0x08,
+0xF0, 0x22, 0x90, 0x82, 0x9C, 0xE0, 0xFF, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x82,
+0xC3, 0xEF, 0xF0, 0xC3, 0x94, 0x02, 0x50, 0x47,
+0x90, 0x80, 0x0B, 0xE0, 0xFF, 0x90, 0x04, 0x1C,
+0xE0, 0x6F, 0x70, 0x3B, 0x90, 0x81, 0x33, 0xE0,
+0x64, 0x0E, 0x70, 0x18, 0x90, 0x82, 0xC3, 0xE0,
+0x70, 0x2D, 0x90, 0x81, 0x2B, 0xE0, 0x54, 0x7F,
+0xF0, 0x71, 0x5C, 0x7D, 0x0C, 0x7F, 0x01, 0x12,
+0x4B, 0xE8, 0x80, 0x18, 0x90, 0x81, 0x33, 0xE0,
+0x64, 0x06, 0x70, 0x13, 0x90, 0x82, 0xC3, 0xE0,
+0x60, 0x0D, 0x71, 0x64, 0x71, 0x6C, 0x90, 0x81,
+0x33, 0x74, 0x04, 0xF0, 0x12, 0x4C, 0x7F, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x90, 0x06, 0x04, 0xE0,
+0x54, 0x7F, 0xF0, 0x22, 0x90, 0x81, 0x2B, 0xE0,
+0x54, 0xBF, 0xF0, 0x22, 0x90, 0x06, 0x04, 0xE0,
+0x44, 0x40, 0xF0, 0xE0, 0x44, 0x80, 0xF0, 0x22,
+0x71, 0x98, 0x90, 0x81, 0x9D, 0x12, 0x67, 0x85,
+0x54, 0x04, 0xFF, 0xEE, 0x54, 0xFB, 0x4F, 0xF0,
+0x12, 0x1F, 0xA4, 0xC3, 0x13, 0x30, 0xE0, 0x07,
+0x12, 0x57, 0x38, 0x90, 0x81, 0x9E, 0xF0, 0x22,
+0x12, 0x1F, 0xA4, 0xFF, 0x54, 0x01, 0xFE, 0x22,
+0x90, 0x81, 0xCC, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
+0x90, 0x02, 0x84, 0xEF, 0xF0, 0xEE, 0xA3, 0xF0,
+0xA3, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x7D, 0x7F,
+0xEF, 0x5D, 0xC3, 0x60, 0x0A, 0x71, 0xCB, 0x24,
+0x80, 0xFF, 0xE4, 0x3E, 0xFE, 0x80, 0x03, 0x71,
+0xCB, 0xFF, 0x22, 0x74, 0xFF, 0x9D, 0xFD, 0x74,
+0xFF, 0x94, 0x00, 0x5E, 0xFE, 0xED, 0x5F, 0x22,
+0x7E, 0x00, 0x7F, 0x08, 0x7D, 0x00, 0x7B, 0x01,
+0x7A, 0x81, 0x79, 0xA1, 0x12, 0x45, 0x23, 0x90,
+0x81, 0xA2, 0x74, 0x08, 0xF0, 0xA3, 0x74, 0x03,
+0xF0, 0x22, 0x90, 0x82, 0x4F, 0x12, 0x44, 0xF4,
+0xE4, 0xFF, 0x90, 0x82, 0x55, 0xE0, 0xFE, 0xEF,
+0xC3, 0x9E, 0x50, 0x1E, 0x90, 0x82, 0x52, 0x12,
+0x44, 0xEB, 0x8F, 0x82, 0x91, 0x3B, 0xFE, 0x90,
+0x82, 0x4F, 0x12, 0x44, 0xEB, 0x8F, 0x82, 0x91,
+0x3B, 0x6E, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x0F,
+0x80, 0xD8, 0x7F, 0x01, 0x22, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0x20, 0xF5, 0x82, 0xE4, 0x34, 0x82,
+0xF5, 0x83, 0x12, 0x44, 0xEB, 0x90, 0x81, 0xD6,
+0xE0, 0xF5, 0x82, 0x75, 0x83, 0x00, 0x02, 0x1F,
+0xBD, 0x74, 0x03, 0xF0, 0x7A, 0x82, 0x79, 0x86,
+0x71, 0xF2, 0xEF, 0x22, 0x74, 0x03, 0xF0, 0x7A,
+0x82, 0x79, 0x82, 0x71, 0xF2, 0xEF, 0x22, 0x12,
+0x57, 0x27, 0x30, 0xE0, 0x0A, 0xE0, 0xC4, 0x54,
+0x0F, 0x30, 0xE0, 0x03, 0x02, 0x7B, 0x0A, 0x90,
+0x81, 0x19, 0xE0, 0x90, 0x82, 0x2F, 0xF0, 0x90,
+0x81, 0x1A, 0xE0, 0x90, 0x82, 0x30, 0xF0, 0x90,
+0x81, 0x1B, 0xE0, 0x90, 0x82, 0x31, 0xF0, 0x90,
+0x81, 0x1C, 0xE0, 0x90, 0x82, 0x32, 0xF0, 0x90,
+0x81, 0x1D, 0xE0, 0x90, 0x82, 0x33, 0xF0, 0x90,
+0x81, 0x0A, 0xE0, 0x90, 0x82, 0x34, 0xF0, 0x90,
+0x81, 0x0B, 0xE0, 0x90, 0x82, 0x35, 0xF0, 0x90,
+0x81, 0x0C, 0xE0, 0x90, 0x82, 0x36, 0xF0, 0x90,
+0x81, 0x0D, 0xE0, 0x90, 0x82, 0x37, 0xF0, 0x90,
+0x81, 0x0E, 0xE0, 0x90, 0x82, 0x38, 0xF0, 0x90,
+0x81, 0x0F, 0xE0, 0x90, 0x82, 0x39, 0xF0, 0x90,
+0x81, 0x10, 0xE0, 0x90, 0x82, 0x3A, 0xF0, 0x90,
+0x81, 0x11, 0xE0, 0x90, 0x82, 0x3B, 0xF0, 0x90,
+0x81, 0x12, 0xE0, 0x90, 0x82, 0x3C, 0xF0, 0x90,
+0x81, 0x13, 0xE0, 0x90, 0x82, 0x3D, 0xF0, 0x12,
+0x50, 0x95, 0x90, 0x81, 0xD7, 0xF0, 0x12, 0x7B,
+0x2C, 0x50, 0x05, 0x12, 0x7B, 0x18, 0x80, 0xF6,
+0x90, 0x01, 0x1F, 0xE0, 0xFE, 0x90, 0x01, 0x1E,
+0x12, 0x7C, 0x5A, 0x90, 0x81, 0xCC, 0xF0, 0xA3,
+0x12, 0x7B, 0x94, 0x12, 0x7B, 0x2C, 0x50, 0x57,
+0x31, 0x34, 0x90, 0x81, 0xD7, 0xE0, 0xFE, 0x24,
+0x3E, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0x12, 0x7B,
+0xFB, 0x24, 0x45, 0xF5, 0x82, 0xE4, 0x34, 0xFC,
+0xF5, 0x83, 0xE0, 0xFF, 0x74, 0xD9, 0x2E, 0xF5,
+0x82, 0xE4, 0x34, 0x81, 0x12, 0x7B, 0xFB, 0x24,
+0x46, 0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01,
+0xEE, 0x12, 0x7B, 0x9D, 0x12, 0x44, 0xF4, 0x12,
+0x7B, 0xFF, 0x24, 0x30, 0xF9, 0xE4, 0x34, 0xFC,
+0xFA, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x20,
+0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0x12,
+0x44, 0xF4, 0x12, 0x7B, 0x25, 0x80, 0xA4, 0x90,
+0x02, 0x87, 0xE0, 0x70, 0x03, 0x02, 0x7B, 0x0A,
+0x90, 0x80, 0xFC, 0xE0, 0x20, 0xE0, 0x03, 0x02,
+0x7B, 0x0A, 0xC3, 0x13, 0x30, 0xE0, 0x0A, 0xE0,
+0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x03, 0x02, 0x7B,
+0x0A, 0xE4, 0x90, 0x82, 0x48, 0x12, 0x50, 0x9D,
+0x90, 0x81, 0xCC, 0xE0, 0xFF, 0xA3, 0xE0, 0xA3,
+0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x81, 0xCE,
+0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0x90, 0xFD,
+0x11, 0xF0, 0x74, 0x01, 0x2D, 0xF5, 0x82, 0xE4,
+0x34, 0xFB, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x00,
+0x2D, 0x12, 0x7C, 0x51, 0x7A, 0x00, 0x24, 0x00,
+0xFF, 0xEA, 0x3E, 0x54, 0x3F, 0x90, 0x81, 0xD0,
+0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x02, 0x2D, 0xF5,
+0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x54,
+0x0F, 0x33, 0x33, 0x33, 0x54, 0xF8, 0x90, 0x81,
+0xD3, 0xF0, 0xFC, 0x74, 0x07, 0x2D, 0xF5, 0x82,
+0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x54, 0xC0,
+0x90, 0x81, 0xD5, 0xF0, 0xEC, 0x24, 0x18, 0x90,
+0x81, 0xD2, 0xF0, 0xFD, 0x90, 0x81, 0xCE, 0xE0,
+0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x51, 0xA4, 0xEF,
+0x54, 0xFC, 0x90, 0x81, 0xD4, 0xF0, 0x90, 0x81,
+0xD3, 0xE0, 0x24, 0x18, 0xFF, 0xE4, 0x33, 0x90,
+0x81, 0xD0, 0x8F, 0xF0, 0x12, 0x44, 0x9F, 0x90,
+0x81, 0xD0, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x71,
+0xB6, 0x90, 0x81, 0xCC, 0xEE, 0x8F, 0xF0, 0x12,
+0x44, 0x9F, 0x90, 0x80, 0xFA, 0xE0, 0xFE, 0xA3,
+0xE0, 0xFF, 0x90, 0x81, 0xCC, 0xE0, 0xFC, 0xA3,
+0xE0, 0xFD, 0xD3, 0x9F, 0xEC, 0x9E, 0x40, 0x12,
+0x90, 0x80, 0xFB, 0x12, 0x7C, 0x2C, 0xED, 0x9F,
+0xFF, 0xEC, 0x9E, 0x90, 0x81, 0xCC, 0xF0, 0xA3,
+0xEF, 0xF0, 0x12, 0x57, 0x27, 0x20, 0xE0, 0x03,
+0x02, 0x78, 0x99, 0xE4, 0x90, 0x81, 0xD8, 0xF0,
+0x90, 0x81, 0xD7, 0xF0, 0x12, 0x7B, 0x2C, 0x50,
+0x37, 0x31, 0x34, 0xE4, 0x90, 0x81, 0xD6, 0xF0,
+0x12, 0x7B, 0x4C, 0x94, 0x06, 0x50, 0x15, 0x12,
+0x7B, 0x0B, 0x24, 0x04, 0xFC, 0xED, 0x2C, 0x12,
+0x52, 0xD1, 0x91, 0x25, 0xB5, 0x07, 0x05, 0x12,
+0x52, 0x78, 0x80, 0xE4, 0x90, 0x81, 0xD6, 0xE0,
+0xB4, 0x06, 0x08, 0x90, 0x81, 0xD8, 0x74, 0x01,
+0xF0, 0x80, 0x05, 0x12, 0x7B, 0x25, 0x80, 0xC4,
+0x90, 0x81, 0xD4, 0xE0, 0x24, 0x60, 0x70, 0x03,
+0x02, 0x78, 0x44, 0x24, 0xFC, 0x70, 0x03, 0x02,
+0x78, 0x44, 0x24, 0xF4, 0x70, 0x03, 0x02, 0x78,
+0x39, 0x24, 0xF0, 0x70, 0x03, 0x02, 0x78, 0x44,
+0x24, 0x80, 0x60, 0x03, 0x02, 0x78, 0x58, 0x12,
+0x7B, 0x0B, 0x24, 0x18, 0xFD, 0x12, 0x51, 0xA4,
+0xEF, 0x60, 0x03, 0x02, 0x79, 0xF3, 0x12, 0x7B,
+0x0B, 0x24, 0x19, 0xFD, 0x12, 0x51, 0xA4, 0x90,
+0x81, 0xED, 0x51, 0x0E, 0x12, 0x7B, 0x47, 0x9F,
+0x50, 0x0B, 0x12, 0x7B, 0x0B, 0x12, 0x52, 0xD9,
+0x12, 0x52, 0x74, 0x80, 0xEF, 0x90, 0x81, 0xED,
+0xE0, 0x70, 0x02, 0xE1, 0x87, 0xE4, 0x90, 0x81,
+0xD7, 0xF0, 0x12, 0x7B, 0x2C, 0x50, 0x67, 0x31,
+0x34, 0x12, 0x7B, 0xBB, 0x70, 0x1E, 0x12, 0x7B,
+0x9C, 0x12, 0x44, 0xEB, 0xC0, 0x03, 0xC0, 0x02,
+0xC0, 0x01, 0x12, 0x7B, 0x53, 0xED, 0xF0, 0xD0,
+0x01, 0xD0, 0x02, 0xD0, 0x03, 0x71, 0xF2, 0xEF,
+0x60, 0x02, 0x80, 0x28, 0x90, 0x81, 0xED, 0xE0,
+0x64, 0x03, 0x70, 0x2D, 0x12, 0x7B, 0x53, 0x91,
+0x41, 0x70, 0x07, 0x12, 0x7B, 0x53, 0x91, 0x4C,
+0x60, 0x1A, 0x12, 0x7B, 0xAB, 0x60, 0x02, 0x80,
+0x06, 0x12, 0x7B, 0x6A, 0xE0, 0x60, 0x05, 0x74,
+0x48, 0x2F, 0x80, 0x10, 0x12, 0x7B, 0x39, 0x74,
+0x01, 0xF0, 0x80, 0x0D, 0x12, 0x7B, 0x63, 0x80,
+0x03, 0x12, 0x7B, 0x63, 0x12, 0x7B, 0x3F, 0xE4,
+0xF0, 0x12, 0x7B, 0x25, 0x80, 0x94, 0x90, 0x82,
+0x48, 0xE0, 0x70, 0x57, 0xA3, 0xE0, 0x70, 0x53,
+0xA3, 0xE0, 0x70, 0x4F, 0xA3, 0xE0, 0x70, 0x4B,
+0xA3, 0xE0, 0x70, 0x47, 0x02, 0x79, 0xF3, 0xE4,
+0x90, 0x81, 0xD7, 0xF0, 0x12, 0x7B, 0x2C, 0x50,
+0x21, 0x74, 0x34, 0x2E, 0x12, 0x7B, 0x71, 0xE0,
+0x60, 0x0A, 0x74, 0x48, 0x2E, 0x12, 0x7B, 0x3F,
+0xE4, 0xF0, 0x80, 0x09, 0x74, 0x48, 0x2E, 0x12,
+0x7B, 0x3F, 0x74, 0x01, 0xF0, 0x12, 0x7B, 0x25,
+0x80, 0xDA, 0x90, 0x82, 0x48, 0xE0, 0x70, 0x13,
+0xA3, 0xE0, 0x70, 0x0F, 0xA3, 0xE0, 0x70, 0x0B,
+0xA3, 0xE0, 0x70, 0x07, 0xA3, 0xE0, 0x70, 0x03,
+0x02, 0x79, 0xF3, 0xE4, 0x90, 0x81, 0xD7, 0xF0,
+0x12, 0x7B, 0x2C, 0x40, 0x03, 0x02, 0x79, 0xF3,
+0x31, 0x34, 0x12, 0x7B, 0x39, 0xE0, 0x60, 0x55,
+0x90, 0x81, 0x94, 0xE0, 0x30, 0xE0, 0x06, 0xC4,
+0x54, 0x0F, 0x30, 0xE0, 0x48, 0x12, 0x7B, 0x79,
+0x90, 0x04, 0x1D, 0xE0, 0x60, 0x1B, 0xD3, 0x90,
+0x82, 0x4E, 0xE0, 0x94, 0x28, 0x90, 0x82, 0x4D,
+0xE0, 0x94, 0x00, 0x50, 0x0C, 0x7F, 0xFA, 0x7E,
+0x00, 0x12, 0x32, 0xAA, 0x12, 0x53, 0xBA, 0x80,
+0xDF, 0x90, 0x04, 0x1D, 0xE0, 0x70, 0x1E, 0x71,
+0x81, 0x74, 0x0A, 0xF0, 0xE4, 0xFB, 0x12, 0x72,
+0x04, 0x71, 0x4C, 0x94, 0x06, 0x50, 0x07, 0x71,
+0x0B, 0x12, 0x52, 0x5A, 0x80, 0xF3, 0x12, 0x5F,
+0xBE, 0x90, 0x06, 0x35, 0xF0, 0x71, 0x25, 0x80,
+0x97, 0x90, 0x81, 0xD8, 0xE0, 0xB4, 0x01, 0x02,
+0x80, 0x4F, 0x61, 0x04, 0x90, 0x81, 0xD8, 0xE0,
+0xB4, 0x01, 0x0B, 0x90, 0x80, 0xFC, 0x12, 0x69,
+0xEE, 0x30, 0xE0, 0x02, 0x80, 0x3B, 0x61, 0x04,
+0x90, 0x81, 0xD5, 0xE0, 0x70, 0x12, 0x90, 0x81,
+0xD8, 0xE0, 0xB4, 0x01, 0x0B, 0x90, 0x80, 0xFC,
+0xE0, 0x13, 0x13, 0x54, 0x3F, 0x20, 0xE0, 0x02,
+0x61, 0x04, 0x71, 0x0B, 0xFD, 0x12, 0x52, 0x88,
+0xEF, 0x60, 0x02, 0x80, 0x14, 0x71, 0x0B, 0xFD,
+0x12, 0x52, 0x30, 0xEF, 0x60, 0x02, 0x80, 0x09,
+0x71, 0x0B, 0xFD, 0x12, 0x51, 0xD4, 0xEF, 0x60,
+0x06, 0x12, 0x6D, 0x73, 0x02, 0x75, 0x5F, 0x61,
+0x04, 0x90, 0x81, 0xD4, 0xE0, 0x24, 0xC0, 0x60,
+0x02, 0x21, 0xFF, 0x71, 0x0B, 0x24, 0x18, 0xFD,
+0x12, 0x51, 0xA4, 0xEF, 0x60, 0x02, 0x21, 0xF3,
+0x71, 0x0B, 0x24, 0x19, 0xFD, 0x12, 0x51, 0xA4,
+0x90, 0x81, 0xED, 0x12, 0x72, 0x0E, 0x71, 0x47,
+0x9F, 0x50, 0x0A, 0x71, 0x0B, 0x12, 0x52, 0xD9,
+0x12, 0x52, 0x74, 0x80, 0xF1, 0x90, 0x81, 0xED,
+0xE0, 0x70, 0x02, 0x21, 0x55, 0xE4, 0x90, 0x81,
+0xD7, 0xF0, 0x71, 0x2C, 0x50, 0x5F, 0x12, 0x71,
+0x34, 0x71, 0xBB, 0x70, 0x1D, 0x71, 0x9C, 0x12,
+0x44, 0xEB, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01,
+0x71, 0x53, 0xED, 0xF0, 0xD0, 0x01, 0xD0, 0x02,
+0xD0, 0x03, 0x12, 0x73, 0xF2, 0xEF, 0x60, 0x02,
+0x80, 0x26, 0x90, 0x81, 0xED, 0xE0, 0x64, 0x03,
+0x70, 0x29, 0x71, 0x53, 0x12, 0x74, 0x41, 0x70,
+0x07, 0x71, 0x53, 0x12, 0x74, 0x4C, 0x60, 0x17,
+0x71, 0xAB, 0x60, 0x02, 0x80, 0x05, 0x71, 0x6A,
+0xE0, 0x60, 0x05, 0x74, 0x48, 0x2F, 0x80, 0x0D,
+0x71, 0x39, 0x74, 0x01, 0xF0, 0x80, 0x0A, 0x71,
+0x63, 0x80, 0x02, 0x71, 0x63, 0x71, 0x3F, 0xE4,
+0xF0, 0x71, 0x25, 0x80, 0x9D, 0x90, 0x82, 0x48,
+0xE0, 0x70, 0x4E, 0xA3, 0xE0, 0x70, 0x4A, 0xA3,
+0xE0, 0x70, 0x46, 0xA3, 0xE0, 0x70, 0x42, 0xA3,
+0xE0, 0x70, 0x3E, 0x21, 0xF3, 0xE4, 0x90, 0x81,
+0xD7, 0xF0, 0x71, 0x2C, 0x50, 0x1D, 0x74, 0x34,
+0x2E, 0x71, 0x71, 0xE0, 0x60, 0x09, 0x74, 0x48,
+0x2E, 0x71, 0x3F, 0xE4, 0xF0, 0x80, 0x08, 0x74,
+0x48, 0x2E, 0x71, 0x3F, 0x74, 0x01, 0xF0, 0x71,
+0x25, 0x80, 0xDF, 0x90, 0x82, 0x48, 0xE0, 0x70,
+0x10, 0xA3, 0xE0, 0x70, 0x0C, 0xA3, 0xE0, 0x70,
+0x08, 0xA3, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x60,
+0x62, 0xE4, 0x90, 0x81, 0xD7, 0xF0, 0x71, 0x2C,
+0x50, 0x59, 0x12, 0x71, 0x34, 0x71, 0x39, 0xE0,
+0x60, 0x4D, 0x90, 0x81, 0x94, 0xE0, 0x30, 0xE0,
+0x06, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x40, 0x71,
+0x79, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x14, 0xD3,
+0x90, 0x82, 0x4E, 0xE0, 0x94, 0xE8, 0x90, 0x82,
+0x4D, 0xE0, 0x94, 0x03, 0x50, 0x05, 0x12, 0x53,
+0xBA, 0x80, 0xE6, 0x90, 0x04, 0x1D, 0xE0, 0x70,
+0x1E, 0x71, 0x81, 0x74, 0x06, 0xF0, 0x7B, 0x08,
+0x12, 0x72, 0x04, 0x71, 0x4C, 0x94, 0x06, 0x50,
+0x07, 0x71, 0x0B, 0x12, 0x52, 0x5A, 0x80, 0xF3,
+0x12, 0x5F, 0xBE, 0x90, 0x06, 0x35, 0xF0, 0x71,
+0x25, 0x80, 0xA3, 0x12, 0x73, 0xA0, 0x90, 0x06,
+0x36, 0x74, 0xDD, 0xF0, 0x02, 0x75, 0x5F, 0x90,
+0x81, 0xD5, 0xE0, 0x60, 0x02, 0x61, 0x04, 0x71,
+0x0B, 0x24, 0x16, 0xFD, 0x12, 0x51, 0xA4, 0x90,
+0x06, 0x34, 0xEF, 0xF0, 0x71, 0x0B, 0x24, 0x17,
+0xFD, 0x12, 0x51, 0xA4, 0x90, 0x06, 0x37, 0x71,
+0x94, 0x71, 0x2C, 0x50, 0x34, 0x12, 0x71, 0x34,
+0xE4, 0x90, 0x81, 0xD6, 0xF0, 0x71, 0x4C, 0x94,
+0x06, 0x50, 0x22, 0x71, 0x0B, 0x24, 0x04, 0x2D,
+0x12, 0x52, 0xD1, 0xFE, 0x12, 0x74, 0x25, 0x6F,
+0x60, 0x0E, 0x74, 0x43, 0x2E, 0xF5, 0x82, 0xE4,
+0x34, 0x82, 0xF5, 0x83, 0xE4, 0xF0, 0x80, 0x05,
+0x12, 0x52, 0x78, 0x80, 0xD8, 0x71, 0x25, 0x80,
+0xC8, 0x90, 0x82, 0x43, 0xE0, 0x64, 0x01, 0x60,
+0x17, 0xA3, 0xE0, 0x64, 0x01, 0x60, 0x11, 0xA3,
+0xE0, 0x64, 0x01, 0x60, 0x0B, 0xA3, 0xE0, 0x64,
+0x01, 0x60, 0x05, 0xA3, 0xE0, 0xB4, 0x01, 0x06,
+0x90, 0x81, 0xD8, 0x74, 0x01, 0xF0, 0x90, 0x81,
+0xD8, 0xE0, 0x64, 0x01, 0x70, 0x6F, 0x12, 0x6A,
+0xFA, 0x12, 0x4F, 0xE5, 0x30, 0xE0, 0x0D, 0xE0,
+0xC3, 0x13, 0x30, 0xE0, 0x40, 0x90, 0x81, 0x2B,
+0xE0, 0x30, 0xE0, 0x39, 0x12, 0x5E, 0x96, 0x90,
+0x81, 0x1E, 0xE0, 0x70, 0x03, 0x02, 0x75, 0x5F,
+0x90, 0x01, 0x3C, 0xE0, 0x30, 0xE4, 0x03, 0x74,
+0x10, 0xF0, 0x12, 0x6A, 0x8C, 0x90, 0x81, 0x1F,
+0xE0, 0x60, 0x07, 0xF5, 0x2D, 0xE4, 0xF5, 0x2E,
+0x80, 0x26, 0x90, 0x81, 0x20, 0xE0, 0x60, 0x08,
+0xFB, 0xE4, 0xF5, 0x2D, 0xF5, 0x2E, 0x80, 0x19,
+0x12, 0x6D, 0x50, 0x80, 0x14, 0x90, 0x01, 0x3C,
+0xE0, 0x30, 0xE4, 0x03, 0x74, 0x10, 0xF0, 0x12,
+0x6A, 0x8C, 0xE4, 0xF5, 0x2D, 0x75, 0x2E, 0x9C,
+0xFB, 0x7D, 0x01, 0x7F, 0x60, 0x7E, 0x01, 0x12,
+0x31, 0x21, 0x02, 0x75, 0x5F, 0x12, 0x50, 0x95,
+0x90, 0x81, 0xD7, 0xF0, 0x71, 0x2C, 0x50, 0x04,
+0x71, 0x18, 0x80, 0xF8, 0x12, 0x73, 0xA0, 0x02,
+0x75, 0x5F, 0x22, 0x90, 0x81, 0xCE, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0x90, 0x81, 0xD2, 0xE0, 0x22,
+0x74, 0x43, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x82,
+0xF5, 0x83, 0x74, 0x01, 0xF0, 0x90, 0x81, 0xD7,
+0xE0, 0x04, 0xF0, 0x22, 0x90, 0x81, 0x07, 0xE0,
+0xFF, 0x90, 0x81, 0xD7, 0xE0, 0xFE, 0xC3, 0x9F,
+0x22, 0x90, 0x81, 0xD7, 0xE0, 0x24, 0x48, 0xF5,
+0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0x22, 0x90,
+0x81, 0xED, 0xE0, 0xFF, 0x90, 0x81, 0xD6, 0xE0,
+0xFD, 0xC3, 0x22, 0x7B, 0x01, 0x7A, 0x81, 0x79,
+0xEE, 0x90, 0x82, 0x52, 0x12, 0x44, 0xF4, 0x90,
+0x82, 0x55, 0x22, 0x90, 0x81, 0xD7, 0xE0, 0x24,
+0x48, 0x22, 0x90, 0x81, 0xD7, 0xE0, 0xFF, 0x24,
+0x34, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83,
+0x22, 0xE4, 0x90, 0x82, 0x4D, 0xF0, 0xA3, 0xF0,
+0x22, 0x90, 0x81, 0xD7, 0xE0, 0x24, 0x2F, 0xF5,
+0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0xE0, 0xFF,
+0x90, 0x82, 0xA8, 0x22, 0xEF, 0xF0, 0xE4, 0x90,
+0x81, 0xD7, 0xF0, 0x22, 0xEF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0xDE, 0xF5, 0x82, 0xE4, 0x34, 0x81,
+0xF5, 0x83, 0x22, 0x90, 0x81, 0xD7, 0xE0, 0xFF,
+0x24, 0x39, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5,
+0x83, 0xE0, 0x22, 0x90, 0x81, 0xD7, 0xE0, 0xFF,
+0x24, 0xD9, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5,
+0x83, 0xE0, 0xFE, 0x90, 0x81, 0xED, 0xE0, 0xFD,
+0xEE, 0x6D, 0x22, 0xEF, 0x30, 0xE7, 0x04, 0x7E,
+0x02, 0x80, 0x02, 0xE4, 0xFE, 0xED, 0x30, 0xE6,
+0x12, 0xEB, 0x20, 0xE0, 0x07, 0x90, 0x81, 0x01,
+0xE0, 0xFC, 0x80, 0x09, 0x90, 0x81, 0x02, 0xE0,
+0xFC, 0x80, 0x02, 0xE4, 0xFC, 0xEE, 0x24, 0x18,
+0x2C, 0xFF, 0x22, 0xF5, 0x83, 0xEF, 0xF0, 0x74,
+0x3E, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5,
+0x83, 0xE0, 0x22, 0x90, 0x00, 0xB6, 0x74, 0x10,
+0xF0, 0x90, 0x00, 0xBE, 0x74, 0xE0, 0xF0, 0xA3,
+0x74, 0x01, 0xF0, 0x22, 0xF0, 0x90, 0x81, 0x4D,
+0xE0, 0x24, 0x05, 0x90, 0x81, 0x48, 0xF0, 0xA3,
+0x74, 0x10, 0xF0, 0x22, 0xE0, 0x24, 0x01, 0xFF,
+0x90, 0x80, 0xFA, 0xE0, 0x34, 0x00, 0xFE, 0xC3,
+0x22, 0xE0, 0x90, 0x01, 0xBA, 0xF0, 0x90, 0x81,
+0x32, 0xE0, 0x90, 0x01, 0xBB, 0x22, 0x90, 0x81,
+0x39, 0xE0, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xFE,
+0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83,
+0xE0, 0x22, 0xE0, 0x7C, 0x00, 0x24, 0x00, 0xFF,
+0xEC, 0x3E, 0x22, 0x90, 0x06, 0x0A, 0xE0, 0x54,
+0xF8, 0xF0, 0x22, 0x00, 0xBB, 0x50
+};
+
+u32 array_length_mp_8188e_t_fw_ap = 15502;
+
+#endif /*defined(CONFIG_AP_WOWLAN)*/
+
+u8 array_mp_8188e_t_fw_nic[] = {
+0xE1, 0x88, 0x10, 0x00, 0x1C, 0x00, 0x00, 0x00,
+0x05, 0x05, 0x14, 0x27, 0x7E, 0x3B, 0x00, 0x00,
+0xA5, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x45, 0x9B, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xC1, 0xBE, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xC1, 0x35, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xE1, 0xF6, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xC2, 0xAF, 0x80, 0xFE, 0x32, 0x12, 0x41, 0x04,
+0x85, 0xD0, 0x0B, 0x75, 0xD0, 0x08, 0xAA, 0xE0,
+0xC2, 0x8C, 0xE5, 0x8A, 0x24, 0x67, 0xF5, 0x8A,
+0xE5, 0x8C, 0x34, 0x79, 0xF5, 0x8C, 0xD2, 0x8C,
+0xEC, 0x24, 0x87, 0xF8, 0xE6, 0xBC, 0x02, 0x02,
+0x74, 0xFF, 0xC3, 0x95, 0x81, 0xB4, 0x40, 0x00,
+0x40, 0xCE, 0x79, 0x03, 0x78, 0x80, 0x16, 0xE6,
+0x08, 0x70, 0x0B, 0xC2, 0xAF, 0xE6, 0x30, 0xE1,
+0x03, 0x44, 0x18, 0xF6, 0xD2, 0xAF, 0x08, 0xD9,
+0xED, 0xEA, 0x8B, 0xD0, 0x22, 0xE5, 0x0C, 0xFF,
+0x23, 0x24, 0x81, 0xF8, 0x0F, 0x08, 0x08, 0xBF,
+0x03, 0x04, 0x7F, 0x00, 0x78, 0x81, 0xE6, 0x30,
+0xE4, 0xF2, 0x00, 0xE5, 0x0C, 0xC3, 0x9F, 0x50,
+0x20, 0x05, 0x0C, 0x74, 0x86, 0x25, 0x0C, 0xF8,
+0xE6, 0xFD, 0xA6, 0x81, 0x08, 0xE6, 0xAE, 0x0C,
+0xBE, 0x02, 0x02, 0x74, 0xFF, 0xCD, 0xF8, 0xE8,
+0x6D, 0x60, 0xE0, 0x08, 0xE6, 0xC0, 0xE0, 0x80,
+0xF6, 0xE5, 0x0C, 0xD3, 0x9F, 0x40, 0x27, 0xE5,
+0x0C, 0x24, 0x87, 0xF8, 0xE6, 0xAE, 0x0C, 0xBE,
+0x02, 0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xCD,
+0xF8, 0xE5, 0x81, 0x6D, 0x60, 0x06, 0xD0, 0xE0,
+0xF6, 0x18, 0x80, 0xF5, 0xE5, 0x0C, 0x24, 0x86,
+0xC8, 0xF6, 0x15, 0x0C, 0x80, 0xD3, 0xE5, 0x0C,
+0x23, 0x24, 0x81, 0xF8, 0x7F, 0x04, 0xC2, 0xAF,
+0xE6, 0x30, 0xE0, 0x03, 0x10, 0xE2, 0x0C, 0x7F,
+0x00, 0x30, 0xE1, 0x07, 0x30, 0xE3, 0x04, 0x7F,
+0x08, 0x54, 0xF4, 0x54, 0x7C, 0xC6, 0xD2, 0xAF,
+0x54, 0x80, 0x42, 0x07, 0x22, 0x78, 0x86, 0xA6,
+0x81, 0x74, 0x02, 0x60, 0x06, 0xFF, 0x08, 0x76,
+0xFF, 0xDF, 0xFB, 0x7F, 0x03, 0xE4, 0x78, 0x80,
+0xF6, 0x08, 0xF6, 0x08, 0xDF, 0xFA, 0x78, 0x81,
+0x76, 0x30, 0x90, 0x46, 0x2F, 0x74, 0x01, 0x93,
+0xC0, 0xE0, 0xE4, 0x93, 0xC0, 0xE0, 0x43, 0x89,
+0x01, 0x75, 0x8A, 0x60, 0x75, 0x8C, 0x79, 0xD2,
+0x8C, 0xD2, 0xAF, 0x22, 0x02, 0xEF, 0xD3, 0x94,
+0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0x74, 0x81,
+0x2F, 0x2F, 0xF8, 0xE6, 0x20, 0xE5, 0xF4, 0xC2,
+0xAF, 0xE6, 0x44, 0x30, 0xF6, 0xD2, 0xAF, 0xAE,
+0x0C, 0xEE, 0xC3, 0x9F, 0x50, 0x21, 0x0E, 0x74,
+0x86, 0x2E, 0xF8, 0xE6, 0xF9, 0x08, 0xE6, 0x18,
+0xBE, 0x02, 0x02, 0x74, 0xFF, 0xFD, 0xED, 0x69,
+0x60, 0x09, 0x09, 0xE7, 0x19, 0x19, 0xF7, 0x09,
+0x09, 0x80, 0xF3, 0x16, 0x16, 0x80, 0xDA, 0xEE,
+0xD3, 0x9F, 0x40, 0x04, 0x05, 0x81, 0x05, 0x81,
+0xEE, 0xD3, 0x9F, 0x40, 0x22, 0x74, 0x86, 0x2E,
+0xF8, 0x08, 0xE6, 0xF9, 0xEE, 0xB5, 0x0C, 0x02,
+0xA9, 0x81, 0x18, 0x06, 0x06, 0xE6, 0xFD, 0xED,
+0x69, 0x60, 0x09, 0x19, 0x19, 0xE7, 0x09, 0x09,
+0xF7, 0x19, 0x80, 0xF3, 0x1E, 0x80, 0xD9, 0xEF,
+0x24, 0x86, 0xF8, 0xE6, 0x04, 0xF8, 0xEF, 0x2F,
+0x04, 0x90, 0x46, 0x2F, 0x93, 0xF6, 0x08, 0xEF,
+0x2F, 0x93, 0xF6, 0x7F, 0x00, 0x22, 0xEF, 0xD3,
+0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0xEF,
+0x23, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE5, 0xF4,
+0xC2, 0xAF, 0xE6, 0x54, 0x8C, 0xF6, 0xD2, 0xAF,
+0xE5, 0x0C, 0xB5, 0x07, 0x0A, 0x74, 0x86, 0x2F,
+0xF8, 0xE6, 0xF5, 0x81, 0x02, 0x41, 0x4D, 0x50,
+0x2E, 0x74, 0x87, 0x2F, 0xF8, 0xE6, 0xBF, 0x02,
+0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xF9, 0x74,
+0x86, 0x2F, 0xF8, 0xFB, 0xE6, 0xFC, 0xE9, 0x6C,
+0x60, 0x08, 0xA8, 0x05, 0xE7, 0xF6, 0x1D, 0x19,
+0x80, 0xF4, 0xA8, 0x03, 0xA6, 0x05, 0x1F, 0xE5,
+0x0C, 0xB5, 0x07, 0xE3, 0x7F, 0x00, 0x22, 0x74,
+0x87, 0x2F, 0xF8, 0xE6, 0xFD, 0x18, 0x86, 0x01,
+0x0F, 0x74, 0x86, 0x2F, 0xF8, 0xA6, 0x01, 0x08,
+0x86, 0x04, 0xE5, 0x0C, 0xB5, 0x07, 0x02, 0xAC,
+0x81, 0xED, 0x6C, 0x60, 0x08, 0x0D, 0x09, 0xA8,
+0x05, 0xE6, 0xF7, 0x80, 0xF4, 0xE5, 0x0C, 0xB5,
+0x07, 0xDE, 0x89, 0x81, 0x7F, 0x00, 0x22, 0xEF,
+0xD3, 0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22,
+0xEF, 0x23, 0x24, 0x81, 0xF8, 0xC2, 0xAF, 0xE6,
+0x30, 0xE5, 0x05, 0x30, 0xE0, 0x02, 0xD2, 0xE4,
+0xD2, 0xE2, 0xC6, 0xD2, 0xAF, 0x7F, 0x00, 0x30,
+0xE2, 0x01, 0x0F, 0x02, 0x41, 0x4C, 0x8F, 0xF0,
+0xE4, 0xFF, 0xFE, 0xE5, 0x0C, 0x23, 0x24, 0x80,
+0xF8, 0xC2, 0xA9, 0x30, 0xF7, 0x0D, 0x7F, 0x08,
+0xE6, 0x60, 0x0B, 0x2D, 0xF6, 0x60, 0x30, 0x50,
+0x2E, 0x80, 0x07, 0x30, 0xF1, 0x06, 0xED, 0xF6,
+0x60, 0x25, 0x7E, 0x02, 0x08, 0x30, 0xF0, 0x10,
+0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x23, 0x0E, 0x30,
+0xE2, 0x0C, 0xD2, 0xAF, 0x7F, 0x04, 0x80, 0x12,
+0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x13, 0x54, 0xEC,
+0x4E, 0xF6, 0xD2, 0xAF, 0x02, 0x41, 0x4D, 0x7F,
+0x08, 0x08, 0xEF, 0x44, 0x83, 0xF4, 0xC2, 0xAF,
+0x56, 0xC6, 0xD2, 0xAF, 0x54, 0x80, 0x4F, 0xFF,
+0x22, 0xE7, 0x09, 0xF6, 0x08, 0xDF, 0xFA, 0x80,
+0x46, 0xE7, 0x09, 0xF2, 0x08, 0xDF, 0xFA, 0x80,
+0x3E, 0x88, 0x82, 0x8C, 0x83, 0xE7, 0x09, 0xF0,
+0xA3, 0xDF, 0xFA, 0x80, 0x32, 0xE3, 0x09, 0xF6,
+0x08, 0xDF, 0xFA, 0x80, 0x78, 0xE3, 0x09, 0xF2,
+0x08, 0xDF, 0xFA, 0x80, 0x70, 0x88, 0x82, 0x8C,
+0x83, 0xE3, 0x09, 0xF0, 0xA3, 0xDF, 0xFA, 0x80,
+0x64, 0x89, 0x82, 0x8A, 0x83, 0xE0, 0xA3, 0xF6,
+0x08, 0xDF, 0xFA, 0x80, 0x58, 0x89, 0x82, 0x8A,
+0x83, 0xE0, 0xA3, 0xF2, 0x08, 0xDF, 0xFA, 0x80,
+0x4C, 0x80, 0xD2, 0x80, 0xFA, 0x80, 0xC6, 0x80,
+0xD4, 0x80, 0x69, 0x80, 0xF2, 0x80, 0x33, 0x80,
+0x10, 0x80, 0xA6, 0x80, 0xEA, 0x80, 0x9A, 0x80,
+0xA8, 0x80, 0xDA, 0x80, 0xE2, 0x80, 0xCA, 0x80,
+0x33, 0x89, 0x82, 0x8A, 0x83, 0xEC, 0xFA, 0xE4,
+0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC, 0xC5,
+0x83, 0xCC, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8,
+0xCC, 0xC5, 0x83, 0xCC, 0xDF, 0xE9, 0xDE, 0xE7,
+0x80, 0x0D, 0x89, 0x82, 0x8A, 0x83, 0xE4, 0x93,
+0xA3, 0xF6, 0x08, 0xDF, 0xF9, 0xEC, 0xFA, 0xA9,
+0xF0, 0xED, 0xFB, 0x22, 0x89, 0x82, 0x8A, 0x83,
+0xEC, 0xFA, 0xE0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8,
+0xCC, 0xC5, 0x83, 0xCC, 0xF0, 0xA3, 0xC8, 0xC5,
+0x82, 0xC8, 0xCC, 0xC5, 0x83, 0xCC, 0xDF, 0xEA,
+0xDE, 0xE8, 0x80, 0xDB, 0x89, 0x82, 0x8A, 0x83,
+0xE4, 0x93, 0xA3, 0xF2, 0x08, 0xDF, 0xF9, 0x80,
+0xCC, 0x88, 0xF0, 0xEF, 0x60, 0x01, 0x0E, 0x4E,
+0x60, 0xC3, 0x88, 0xF0, 0xED, 0x24, 0x02, 0xB4,
+0x04, 0x00, 0x50, 0xB9, 0xF5, 0x82, 0xEB, 0x24,
+0x02, 0xB4, 0x04, 0x00, 0x50, 0xAF, 0x23, 0x23,
+0x45, 0x82, 0x23, 0x90, 0x43, 0xF9, 0x73, 0xC5,
+0xF0, 0xF8, 0xA3, 0xE0, 0x28, 0xF0, 0xC5, 0xF0,
+0xF8, 0xE5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15,
+0x83, 0xE0, 0x38, 0xF0, 0x22, 0xC3, 0xEF, 0x9B,
+0xFF, 0xEE, 0x9A, 0xFE, 0xED, 0x99, 0xFD, 0xEC,
+0x98, 0xFC, 0x22, 0xEF, 0x5B, 0xFF, 0xEE, 0x5A,
+0xFE, 0xED, 0x59, 0xFD, 0xEC, 0x58, 0xFC, 0x22,
+0xEF, 0x4B, 0xFF, 0xEE, 0x4A, 0xFE, 0xED, 0x49,
+0xFD, 0xEC, 0x48, 0xFC, 0x22, 0xEB, 0x9F, 0xF5,
+0xF0, 0xEA, 0x9E, 0x42, 0xF0, 0xE9, 0x9D, 0x42,
+0xF0, 0xE8, 0x9C, 0x45, 0xF0, 0x22, 0xE0, 0xFC,
+0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0x22, 0xE2, 0xFC, 0x08, 0xE2, 0xFD, 0x08,
+0xE2, 0xFE, 0x08, 0xE2, 0xFF, 0x22, 0xE0, 0xF8,
+0xA3, 0xE0, 0xF9, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0,
+0xFB, 0x22, 0xE2, 0xFB, 0x08, 0xE2, 0xF9, 0x08,
+0xE2, 0xFA, 0x08, 0xE2, 0xCB, 0xF8, 0x22, 0xEC,
+0xF2, 0x08, 0xED, 0xF2, 0x08, 0xEE, 0xF2, 0x08,
+0xEF, 0xF2, 0x22, 0xA4, 0x25, 0x82, 0xF5, 0x82,
+0xE5, 0xF0, 0x35, 0x83, 0xF5, 0x83, 0x22, 0xE0,
+0xFB, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xF9, 0x22,
+0xEB, 0xF0, 0xA3, 0xEA, 0xF0, 0xA3, 0xE9, 0xF0,
+0x22, 0xD0, 0x83, 0xD0, 0x82, 0xF8, 0xE4, 0x93,
+0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0D, 0xA3,
+0xA3, 0x93, 0xF8, 0x74, 0x01, 0x93, 0xF5, 0x82,
+0x88, 0x83, 0xE4, 0x73, 0x74, 0x02, 0x93, 0x68,
+0x60, 0xEF, 0xA3, 0xA3, 0xA3, 0x80, 0xDF, 0xEF,
+0x4E, 0x60, 0x12, 0xEF, 0x60, 0x01, 0x0E, 0xED,
+0xBB, 0x01, 0x0B, 0x89, 0x82, 0x8A, 0x83, 0xF0,
+0xA3, 0xDF, 0xFC, 0xDE, 0xFA, 0x22, 0x89, 0xF0,
+0x50, 0x07, 0xF7, 0x09, 0xDF, 0xFC, 0xA9, 0xF0,
+0x22, 0xBB, 0xFE, 0xFC, 0xF3, 0x09, 0xDF, 0xFC,
+0xA9, 0xF0, 0x22, 0x02, 0x45, 0xD9, 0x02, 0x41,
+0xDD, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3,
+0x40, 0x03, 0xF6, 0x80, 0x01, 0xF2, 0x08, 0xDF,
+0xF4, 0x80, 0x29, 0xE4, 0x93, 0xA3, 0xF8, 0x54,
+0x07, 0x24, 0x0C, 0xC8, 0xC3, 0x33, 0xC4, 0x54,
+0x0F, 0x44, 0x20, 0xC8, 0x83, 0x40, 0x04, 0xF4,
+0x56, 0x80, 0x01, 0x46, 0xF6, 0xDF, 0xE4, 0x80,
+0x0B, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
+0x80, 0x90, 0x46, 0x1E, 0xE4, 0x7E, 0x01, 0x93,
+0x60, 0xBC, 0xA3, 0xFF, 0x54, 0x3F, 0x30, 0xE5,
+0x09, 0x54, 0x1F, 0xFE, 0xE4, 0x93, 0xA3, 0x60,
+0x01, 0x0E, 0xCF, 0x54, 0xC0, 0x25, 0xE0, 0x60,
+0xA8, 0x40, 0xB8, 0xE4, 0x93, 0xA3, 0xFA, 0xE4,
+0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0xC8, 0xC5,
+0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xF0, 0xA3,
+0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA,
+0xDF, 0xE9, 0xDE, 0xE7, 0x80, 0xBE, 0x41, 0x82,
+0xA5, 0x00, 0x41, 0x82, 0xA6, 0x00, 0x41, 0x82,
+0xB0, 0x00, 0x41, 0x82, 0xB2, 0x00, 0x00, 0x50,
+0xF6, 0x61, 0x1E, 0x67, 0xDE, 0xC0, 0xE0, 0xC0,
+0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75,
+0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02,
+0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06,
+0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0x35, 0xF0,
+0x74, 0x46, 0xA3, 0xF0, 0xD1, 0x84, 0x74, 0x35,
+0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x46, 0xA3,
+0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0,
+0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0,
+0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0,
+0xF0, 0xD0, 0xE0, 0x32, 0x90, 0x00, 0x54, 0xE0,
+0x55, 0x35, 0xF5, 0x39, 0xA3, 0xE0, 0x55, 0x36,
+0xF5, 0x3A, 0xA3, 0xE0, 0x55, 0x37, 0xF5, 0x3B,
+0xA3, 0xE0, 0x55, 0x38, 0xF5, 0x3C, 0xAD, 0x39,
+0x7F, 0x54, 0x12, 0x32, 0x1E, 0xAD, 0x3A, 0x7F,
+0x55, 0x12, 0x32, 0x1E, 0xAD, 0x3B, 0x7F, 0x56,
+0x12, 0x32, 0x1E, 0xAD, 0x3C, 0x7F, 0x57, 0x12,
+0x32, 0x1E, 0x53, 0x91, 0xEF, 0x22, 0xC0, 0xE0,
+0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0,
+0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0,
+0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0,
+0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0xBE,
+0xF0, 0x74, 0x46, 0xA3, 0xF0, 0x12, 0x75, 0x11,
+0xE5, 0x41, 0x30, 0xE4, 0x02, 0xF1, 0x5A, 0xE5,
+0x41, 0x30, 0xE6, 0x03, 0x12, 0x75, 0x6E, 0xE5,
+0x43, 0x30, 0xE0, 0x03, 0x12, 0x6B, 0x93, 0xE5,
+0x43, 0x30, 0xE1, 0x03, 0x12, 0x55, 0xC7, 0xE5,
+0x43, 0x30, 0xE2, 0x03, 0x12, 0x75, 0x7B, 0xE5,
+0x43, 0x30, 0xE3, 0x02, 0xF1, 0x6D, 0xE5, 0x43,
+0x30, 0xE4, 0x02, 0xF1, 0xB0, 0xE5, 0x43, 0x30,
+0xE5, 0x03, 0x12, 0x75, 0x9E, 0xE5, 0x43, 0x30,
+0xE6, 0x02, 0xF1, 0xDE, 0xE5, 0x44, 0x30, 0xE1,
+0x03, 0x12, 0x75, 0xBA, 0x74, 0xBE, 0x04, 0x90,
+0x01, 0xC4, 0xF0, 0x74, 0x46, 0xA3, 0xF0, 0xD0,
+0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0,
+0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0,
+0xE0, 0x32, 0x12, 0x68, 0x7D, 0x7F, 0x02, 0x8F,
+0x0F, 0x7F, 0x02, 0x71, 0x27, 0x90, 0x80, 0x3C,
+0xE0, 0x45, 0x0F, 0xF0, 0x22, 0xF1, 0x84, 0x70,
+0x12, 0x90, 0x81, 0x4B, 0xE0, 0x60, 0x0C, 0x90,
+0x81, 0x4F, 0xE0, 0x20, 0xE4, 0x05, 0xF1, 0xD3,
+0x12, 0x48, 0xFB, 0x22, 0xE4, 0xFF, 0xF1, 0x8C,
+0xEF, 0x64, 0x01, 0x22, 0x12, 0x7B, 0x2D, 0x12,
+0x51, 0xB6, 0xE0, 0xFD, 0x7C, 0x00, 0x12, 0x6B,
+0x30, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE,
+0xD8, 0xF9, 0xFF, 0xEE, 0x5C, 0xFE, 0xEF, 0x5D,
+0x4E, 0x7F, 0x00, 0x60, 0x02, 0x7F, 0x01, 0x22,
+0xF1, 0x84, 0x70, 0x1E, 0x90, 0x81, 0x4B, 0xE0,
+0x60, 0x18, 0x90, 0x81, 0x4F, 0xE0, 0x20, 0xE4,
+0x11, 0xF1, 0xD3, 0xF0, 0x90, 0x81, 0x46, 0xE0,
+0x12, 0x67, 0x97, 0x54, 0x07, 0x70, 0x03, 0x12,
+0x61, 0x68, 0x22, 0x90, 0x01, 0x57, 0xE4, 0xF0,
+0x90, 0x01, 0x3C, 0x74, 0x02, 0x22, 0xE4, 0xFF,
+0xF1, 0x8C, 0xBF, 0x01, 0x10, 0x90, 0x81, 0x4B,
+0xE0, 0x60, 0x0A, 0x12, 0x63, 0x7F, 0x54, 0x07,
+0x70, 0x03, 0x12, 0x61, 0x68, 0x22, 0xC0, 0xE0,
+0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0,
+0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0,
+0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0,
+0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0xF6,
+0xF0, 0x74, 0x47, 0xA3, 0xF0, 0x12, 0x75, 0x3E,
+0xE5, 0x49, 0x30, 0xE1, 0x02, 0x11, 0x9E, 0xE5,
+0x49, 0x30, 0xE2, 0x03, 0x12, 0x61, 0x7D, 0xE5,
+0x4A, 0x30, 0xE0, 0x03, 0x12, 0x6D, 0xC3, 0xE5,
+0x4A, 0x30, 0xE4, 0x03, 0x12, 0x76, 0xE7, 0xE5,
+0x4B, 0x30, 0xE1, 0x03, 0x12, 0x6C, 0x2E, 0xE5,
+0x4B, 0x30, 0xE0, 0x03, 0x12, 0x6E, 0x60, 0xE5,
+0x4B, 0x30, 0xE4, 0x02, 0xF1, 0xF1, 0xE5, 0x4C,
+0x30, 0xE1, 0x05, 0x7F, 0x04, 0x12, 0x47, 0x5F,
+0xE5, 0x4C, 0x30, 0xE4, 0x03, 0x12, 0x6B, 0x6C,
+0xE5, 0x4C, 0x30, 0xE5, 0x03, 0x12, 0x62, 0x6E,
+0xE5, 0x4C, 0x30, 0xE6, 0x03, 0x12, 0x62, 0x96,
+0x74, 0xF6, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74,
+0x47, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0,
+0x05, 0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0,
+0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0,
+0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x90, 0x81,
+0x4B, 0xE0, 0x60, 0x03, 0x12, 0x63, 0xF2, 0x90,
+0x81, 0xAF, 0xE0, 0x30, 0xE0, 0x49, 0xC4, 0x54,
+0x0F, 0x20, 0xE0, 0x17, 0xE4, 0xF5, 0x1D, 0x90,
+0x81, 0xB1, 0x31, 0x02, 0xB1, 0x15, 0x12, 0x67,
+0xC9, 0x30, 0xE0, 0x02, 0x31, 0xCA, 0x12, 0x67,
+0xC2, 0xF0, 0x22, 0x90, 0x81, 0xAF, 0xE0, 0xC4,
+0x54, 0x0F, 0x30, 0xE0, 0x22, 0xE4, 0xF5, 0x1D,
+0x90, 0x81, 0xB2, 0x31, 0x02, 0x90, 0x81, 0xAF,
+0xE0, 0x54, 0xEF, 0xF0, 0xE0, 0xC3, 0x13, 0x30,
+0xE0, 0x06, 0x7D, 0x04, 0x7F, 0x01, 0x21, 0xCE,
+0x7B, 0x31, 0xF1, 0x9C, 0x12, 0x57, 0xE3, 0x22,
+0xE0, 0x44, 0x02, 0xF0, 0xE4, 0xF5, 0x1D, 0x90,
+0x81, 0xA9, 0xE0, 0xF5, 0x1E, 0xE4, 0xFB, 0xFD,
+0x7F, 0x54, 0x7E, 0x01, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x8E, 0x19, 0x8F, 0x1A, 0xE5,
+0x1E, 0x31, 0x61, 0x85, 0x19, 0x83, 0x85, 0x1A,
+0x82, 0xF0, 0xE5, 0x1D, 0x31, 0x61, 0xFF, 0xE5,
+0x1E, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x4F, 0xA3,
+0xF0, 0xEB, 0x31, 0x61, 0xFF, 0xE5, 0x1D, 0x13,
+0x13, 0x13, 0x54, 0x1F, 0x4F, 0x31, 0x68, 0xF0,
+0xBD, 0x01, 0x0D, 0x85, 0x1A, 0x82, 0x8E, 0x83,
+0xA3, 0xA3, 0xA3, 0x74, 0x03, 0xF0, 0x80, 0x06,
+0x31, 0x68, 0xA3, 0x74, 0x01, 0xF0, 0x31, 0x68,
+0xA3, 0x74, 0x05, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x54, 0x07, 0xC4, 0x33, 0x54, 0xE0, 0x22,
+0x85, 0x1A, 0x82, 0x85, 0x19, 0x83, 0xA3, 0xA3,
+0x22, 0x90, 0x81, 0x4F, 0xE0, 0x44, 0x10, 0xF0,
+0x90, 0x81, 0x54, 0xE0, 0x60, 0x04, 0x64, 0x01,
+0x70, 0x11, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0x54,
+0xE0, 0x31, 0xBF, 0x31, 0x03, 0x90, 0x81, 0x54,
+0xE0, 0x80, 0x11, 0xE4, 0xF5, 0x1D, 0x31, 0xB5,
+0x31, 0x03, 0x90, 0x81, 0x54, 0xE0, 0x75, 0xF0,
+0x03, 0xA4, 0x24, 0xFE, 0x31, 0xBF, 0x90, 0x81,
+0x64, 0xF0, 0x90, 0x81, 0x4E, 0xE0, 0x20, 0xE2,
+0x03, 0x12, 0x67, 0xD7, 0x22, 0x90, 0x81, 0x54,
+0xE0, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xFE, 0xFF,
+0x90, 0x81, 0x53, 0xE0, 0x2F, 0x22, 0xE0, 0x54,
+0x7F, 0xF0, 0x7D, 0x0C, 0x7F, 0x01, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xAC, 0x07, 0xEF,
+0x14, 0x60, 0x15, 0x14, 0x60, 0x19, 0x24, 0x02,
+0x70, 0x1A, 0xED, 0x54, 0x01, 0xFE, 0x90, 0x81,
+0x46, 0xE0, 0x54, 0xFE, 0x4E, 0xF0, 0x80, 0x0C,
+0x90, 0x81, 0x4E, 0xED, 0xF0, 0x80, 0x05, 0x90,
+0x81, 0x4D, 0xED, 0xF0, 0x90, 0x00, 0x8F, 0xE0,
+0x30, 0xE4, 0x2E, 0xEC, 0x14, 0x60, 0x07, 0x14,
+0x60, 0x1D, 0x24, 0x02, 0x70, 0x23, 0x90, 0x81,
+0x46, 0xE0, 0x54, 0x01, 0xC4, 0x33, 0x33, 0x33,
+0x54, 0x80, 0xFF, 0x90, 0x81, 0x4E, 0xE0, 0x54,
+0x7F, 0x4F, 0xFD, 0x7F, 0x88, 0x80, 0x07, 0x90,
+0x81, 0x4D, 0xE0, 0xFD, 0x7F, 0x89, 0x12, 0x32,
+0x1E, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7E, 0x00,
+0x7F, 0x62, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x81,
+0x79, 0x46, 0x12, 0x45, 0x6F, 0x12, 0x7B, 0x13,
+0x12, 0x45, 0x6F, 0x90, 0x81, 0x4A, 0x74, 0x02,
+0xF0, 0x90, 0x81, 0x51, 0x14, 0xF0, 0xA3, 0xF0,
+0xA3, 0x74, 0x10, 0xF0, 0x90, 0x81, 0x57, 0xE4,
+0xF0, 0xA3, 0x74, 0x02, 0x51, 0xF8, 0xF0, 0x12,
+0x77, 0xDC, 0xE4, 0xFD, 0xFF, 0x31, 0xCE, 0x7D,
+0x0C, 0x7F, 0x02, 0x31, 0xCE, 0x31, 0xCA, 0x90,
+0x80, 0x42, 0xE0, 0xFF, 0xB4, 0x01, 0x08, 0x90,
+0x81, 0x56, 0x74, 0x99, 0xF0, 0x80, 0x29, 0xEF,
+0xB4, 0x03, 0x08, 0x90, 0x81, 0x56, 0x74, 0x90,
+0xF0, 0x80, 0x1D, 0x90, 0x81, 0x56, 0x74, 0x40,
+0xF0, 0x90, 0x00, 0x2C, 0xE0, 0x54, 0x0F, 0xFF,
+0xBF, 0x05, 0x08, 0x90, 0x81, 0x68, 0x74, 0x02,
+0xF0, 0x80, 0x05, 0xE4, 0x90, 0x81, 0x68, 0xF0,
+0x90, 0x81, 0xA8, 0x74, 0x02, 0xF0, 0xA3, 0x74,
+0x0F, 0xF0, 0xA3, 0xE0, 0x54, 0x01, 0x44, 0x28,
+0xF0, 0xA3, 0x74, 0x07, 0x51, 0xF8, 0xF0, 0x7F,
+0x01, 0x12, 0x79, 0x8B, 0x90, 0x05, 0x58, 0x74,
+0x02, 0xF0, 0x7E, 0x00, 0xFF, 0x7D, 0x00, 0x7B,
+0x01, 0x7A, 0x81, 0x79, 0xAC, 0x12, 0x45, 0x6F,
+0x12, 0x7B, 0x4D, 0x90, 0x06, 0x0A, 0xE0, 0x54,
+0xF8, 0xF0, 0x7B, 0x56, 0xE4, 0xFD, 0x7F, 0xFF,
+0xB1, 0x1C, 0xE4, 0x90, 0x81, 0xAE, 0xF0, 0x22,
+0xF0, 0x90, 0x81, 0x68, 0xE0, 0x24, 0x04, 0x90,
+0x81, 0x63, 0xF0, 0xA3, 0x74, 0x10, 0x22, 0x90,
+0x82, 0xAD, 0xEF, 0xF0, 0xB1, 0x77, 0x90, 0x82,
+0xAD, 0xE0, 0x60, 0x02, 0xB1, 0x17, 0x7D, 0x04,
+0xD1, 0x2F, 0x74, 0x04, 0xF0, 0x22, 0xFD, 0x7F,
+0x0C, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x90, 0x82, 0xAE, 0xED, 0xF0, 0x90, 0x81, 0x46,
+0xE0, 0xFE, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30,
+0xE0, 0x02, 0x81, 0x69, 0xEE, 0x12, 0x67, 0x7E,
+0x30, 0xE0, 0x02, 0x81, 0x69, 0x90, 0x81, 0x4E,
+0xE0, 0xFE, 0x6F, 0x70, 0x02, 0x81, 0x69, 0xEF,
+0x70, 0x02, 0x61, 0xDD, 0x24, 0xFE, 0x70, 0x02,
+0x81, 0x16, 0x24, 0xFE, 0x60, 0x47, 0x24, 0xFC,
+0x70, 0x02, 0x81, 0x51, 0x24, 0xFC, 0x60, 0x02,
+0x81, 0x62, 0xEE, 0xB4, 0x0E, 0x02, 0x91, 0xEC,
+0x90, 0x81, 0x4E, 0xE0, 0x70, 0x04, 0x7F, 0x01,
+0x71, 0x07, 0x90, 0x81, 0x4E, 0xE0, 0xB4, 0x06,
+0x02, 0x91, 0xC5, 0x90, 0x81, 0x4E, 0xE0, 0xB4,
+0x04, 0x0D, 0x90, 0x82, 0xAE, 0xE0, 0xFF, 0x60,
+0x04, 0xB1, 0xF6, 0x80, 0x02, 0xB1, 0x61, 0x90,
+0x81, 0x4E, 0xE0, 0x64, 0x08, 0x60, 0x02, 0x81,
+0x62, 0xB1, 0x6C, 0x81, 0x62, 0x90, 0x81, 0x4E,
+0xE0, 0x70, 0x04, 0x7F, 0x01, 0x71, 0x07, 0x90,
+0x81, 0x4E, 0xE0, 0xB4, 0x06, 0x02, 0x91, 0xC5,
+0x90, 0x81, 0x4E, 0xE0, 0xB4, 0x0E, 0x07, 0x91,
+0x6E, 0xBF, 0x01, 0x02, 0x91, 0xEC, 0x90, 0x81,
+0x4E, 0xE0, 0x64, 0x0C, 0x60, 0x02, 0x81, 0x62,
+0x91, 0x6E, 0xEF, 0x64, 0x01, 0x60, 0x02, 0x81,
+0x62, 0xB1, 0x32, 0x81, 0x62, 0x90, 0x81, 0x4E,
+0xE0, 0xB4, 0x0E, 0x07, 0x91, 0x6E, 0xBF, 0x01,
+0x02, 0x91, 0xEC, 0x90, 0x81, 0x4E, 0xE0, 0xB4,
+0x06, 0x02, 0x91, 0xC5, 0x90, 0x81, 0x4E, 0xE0,
+0xB4, 0x0C, 0x07, 0x91, 0x6E, 0xBF, 0x01, 0x02,
+0xB1, 0x32, 0x90, 0x81, 0x4E, 0xE0, 0x64, 0x04,
+0x70, 0x58, 0x12, 0x76, 0x09, 0xEF, 0x64, 0x01,
+0x70, 0x50, 0xF1, 0xD0, 0x80, 0x4C, 0x90, 0x81,
+0x4E, 0xE0, 0xB4, 0x0E, 0x07, 0x91, 0x6E, 0xBF,
+0x01, 0x02, 0x91, 0xEC, 0x90, 0x81, 0x4E, 0xE0,
+0xB4, 0x06, 0x02, 0x91, 0xC5, 0x90, 0x81, 0x4E,
+0xE0, 0xB4, 0x0C, 0x07, 0x91, 0x6E, 0xBF, 0x01,
+0x02, 0xB1, 0x32, 0x90, 0x81, 0x4E, 0xE0, 0x70,
+0x04, 0x7F, 0x01, 0x71, 0x07, 0x90, 0x81, 0x4E,
+0xE0, 0xB4, 0x04, 0x16, 0x12, 0x77, 0xC6, 0x80,
+0x11, 0x90, 0x81, 0x4E, 0xE0, 0xB4, 0x0C, 0x0A,
+0x12, 0x65, 0xB9, 0x54, 0x3F, 0x30, 0xE0, 0x02,
+0xD1, 0x37, 0x90, 0x81, 0x4E, 0x12, 0x7B, 0x20,
+0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x75, 0xF0,
+0xEF, 0x64, 0x01, 0x60, 0x05, 0x75, 0x1F, 0x01,
+0x80, 0x30, 0x12, 0x7B, 0x43, 0x30, 0xE0, 0x05,
+0x75, 0x1F, 0x02, 0x80, 0x25, 0x90, 0x81, 0x4D,
+0xE0, 0xD3, 0x94, 0x04, 0x40, 0x05, 0x75, 0x1F,
+0x08, 0x80, 0x17, 0x90, 0x81, 0xAF, 0xE0, 0x30,
+0xE0, 0x0B, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x05,
+0x75, 0x1F, 0x11, 0x80, 0x05, 0x12, 0x76, 0x72,
+0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74, 0x02, 0xF0,
+0x90, 0x01, 0xB8, 0xE5, 0x1F, 0xF0, 0x7F, 0x00,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x81, 0x47,
+0xE0, 0x90, 0x06, 0x04, 0x20, 0xE0, 0x07, 0xE0,
+0x44, 0x40, 0xF1, 0xA2, 0x80, 0x0F, 0x31, 0xC6,
+0x90, 0x05, 0x27, 0xE0, 0x54, 0x7F, 0xF0, 0x90,
+0x81, 0x45, 0x74, 0x0C, 0xF0, 0xE4, 0xFB, 0xFD,
+0x7F, 0xFF, 0x80, 0x30, 0x90, 0x81, 0x47, 0xE0,
+0xC3, 0x13, 0x20, 0xE0, 0x04, 0x31, 0xCA, 0x80,
+0x15, 0x12, 0x7B, 0x64, 0xE0, 0x44, 0x80, 0xF1,
+0xA2, 0x90, 0x05, 0x27, 0xE0, 0x44, 0x80, 0xF0,
+0x90, 0x81, 0x45, 0x74, 0x04, 0xF0, 0xE4, 0xFB,
+0xFD, 0x7F, 0xFF, 0x80, 0x07, 0xB1, 0x77, 0xE4,
+0xFB, 0xFD, 0x7F, 0xFF, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x05, 0x22, 0xED, 0xF0,
+0x90, 0x80, 0x40, 0xEB, 0xF0, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0x12, 0x47, 0x84, 0x70, 0x29, 0x90,
+0x81, 0x47, 0xE0, 0x54, 0xFD, 0xF0, 0x7B, 0x2C,
+0x12, 0x7B, 0x55, 0x7D, 0x08, 0x7F, 0x01, 0xD1,
+0xC7, 0xBF, 0x01, 0x0F, 0x90, 0x81, 0x46, 0xE0,
+0x44, 0x80, 0xF0, 0x7D, 0x0E, 0xD1, 0x2F, 0x74,
+0x0E, 0xF0, 0x22, 0x12, 0x62, 0xC5, 0x04, 0xF0,
+0x22, 0x12, 0x7B, 0x4D, 0xB1, 0x17, 0x7D, 0x0C,
+0x7F, 0x01, 0x21, 0xCE, 0xB1, 0x15, 0x31, 0xCA,
+0x90, 0x81, 0x45, 0x74, 0x0C, 0xF0, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x01,
+0x01, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x01, 0x00,
+0x74, 0xFF, 0xF0, 0x90, 0x06, 0xB7, 0x74, 0x09,
+0xF0, 0x90, 0x06, 0xB4, 0x74, 0x86, 0xF0, 0x12,
+0x5F, 0xD2, 0xEC, 0x54, 0x7F, 0xFC, 0x90, 0x82,
+0x96, 0x12, 0x20, 0xCE, 0x90, 0x82, 0x96, 0x12,
+0x44, 0xEE, 0x12, 0x58, 0x97, 0x7F, 0x7C, 0xF1,
+0xB0, 0x12, 0x20, 0xDA, 0xCC, 0xC0, 0x00, 0xC0,
+0x7F, 0x8C, 0xF1, 0xB0, 0x12, 0x20, 0xDA, 0x00,
+0xC0, 0x00, 0x14, 0x12, 0x5F, 0xD9, 0x90, 0x82,
+0x7F, 0x12, 0x20, 0xDA, 0x00, 0x03, 0x3E, 0x60,
+0xE4, 0xFD, 0xFF, 0x12, 0x5D, 0xB7, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0x90, 0x81, 0xAF, 0xE0, 0x30,
+0xE0, 0x13, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0xB1,
+0x15, 0x12, 0x67, 0xC9, 0x30, 0xE0, 0x02, 0x31,
+0xCA, 0x12, 0x67, 0xC2, 0xF0, 0x22, 0xEF, 0x60,
+0x35, 0x12, 0x47, 0x84, 0x70, 0x30, 0x90, 0x81,
+0x47, 0xE0, 0x54, 0xFE, 0xF0, 0x7B, 0x2B, 0x7D,
+0x0F, 0x7F, 0xFF, 0xB1, 0x1C, 0x90, 0x06, 0x04,
+0xE0, 0x54, 0xBF, 0xF0, 0xD1, 0xC3, 0xBF, 0x01,
+0x0F, 0x90, 0x81, 0x46, 0xE0, 0x44, 0x40, 0xF0,
+0x7D, 0x06, 0xD1, 0x2F, 0x74, 0x06, 0xF0, 0x22,
+0x12, 0x62, 0xC5, 0x74, 0x08, 0xF0, 0x22, 0x7F,
+0x01, 0x31, 0xCE, 0x90, 0x81, 0x45, 0x22, 0x7B,
+0x2F, 0xF1, 0x9C, 0x12, 0x57, 0xE3, 0x7D, 0x08,
+0xD1, 0x2F, 0x74, 0x08, 0xF0, 0x22, 0xEF, 0x70,
+0x3E, 0x7D, 0x78, 0x7F, 0x02, 0x12, 0x56, 0x83,
+0x7D, 0x02, 0x7F, 0x03, 0x12, 0x56, 0x83, 0x7D,
+0xC8, 0x7F, 0x02, 0x12, 0x56, 0xFD, 0x12, 0x47,
+0xD3, 0xF0, 0xE4, 0xFF, 0x12, 0x47, 0x8C, 0xEF,
+0x70, 0x0C, 0xB1, 0x77, 0xB1, 0x61, 0x12, 0x7B,
+0x6C, 0x54, 0x7F, 0xF0, 0x80, 0x06, 0x7D, 0x01,
+0x7F, 0x0C, 0x71, 0x21, 0x12, 0x74, 0x12, 0x90,
+0x06, 0x0A, 0xE0, 0x54, 0xF8, 0xF0, 0x22, 0x90,
+0x01, 0x36, 0x74, 0x78, 0xF0, 0xA3, 0x74, 0x02,
+0xF0, 0x7D, 0x78, 0xFF, 0xF1, 0xC3, 0x7D, 0x02,
+0x7F, 0x03, 0xF1, 0xC3, 0x90, 0x06, 0x0A, 0xE0,
+0x44, 0x07, 0x12, 0x6E, 0x14, 0xE4, 0xFF, 0x12,
+0x47, 0x8C, 0xBF, 0x01, 0x11, 0x12, 0x64, 0x4B,
+0xF0, 0x90, 0x81, 0x4E, 0xE0, 0x20, 0xE2, 0x0A,
+0x7D, 0x01, 0x7F, 0x04, 0x61, 0x21, 0x12, 0x65,
+0xC1, 0xF0, 0x22, 0x7D, 0x08, 0xE4, 0xFF, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x82,
+0x89, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x80,
+0x3E, 0xE0, 0x04, 0xF0, 0x90, 0x04, 0x1D, 0xE0,
+0x60, 0x2C, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x82,
+0x8D, 0xF0, 0x7B, 0x26, 0x12, 0x5F, 0x97, 0x12,
+0x5D, 0xF1, 0xEF, 0x64, 0x01, 0x70, 0x03, 0x12,
+0x7A, 0x58, 0x90, 0x82, 0x8D, 0xE0, 0xFD, 0x7B,
+0x27, 0xE4, 0xFF, 0xB1, 0x1C, 0x90, 0x82, 0x89,
+0xE0, 0xFF, 0xF1, 0x22, 0x80, 0x0A, 0x90, 0x82,
+0x89, 0xE0, 0xFF, 0xF1, 0x22, 0x12, 0x7A, 0x58,
+0x12, 0x5F, 0xCB, 0x7F, 0x01, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x90, 0x82, 0xB1, 0xEF, 0xF0, 0xC3, 0x94,
+0x02, 0x50, 0x48, 0x90, 0x80, 0x46, 0xE0, 0xFF,
+0x90, 0x04, 0x1C, 0xE0, 0x6F, 0x70, 0x3C, 0x90,
+0x81, 0x4E, 0xE0, 0x64, 0x0E, 0x70, 0x14, 0x90,
+0x82, 0xB1, 0xE0, 0x70, 0x2E, 0x90, 0x81, 0x46,
+0xE0, 0x54, 0x7F, 0xF0, 0x90, 0x06, 0x04, 0x31,
+0xC6, 0x80, 0x1E, 0x90, 0x81, 0x4E, 0xE0, 0x64,
+0x06, 0x70, 0x18, 0x90, 0x82, 0xB1, 0xE0, 0x60,
+0x12, 0x12, 0x7B, 0x6C, 0x12, 0x7B, 0x64, 0xE0,
+0x44, 0x80, 0xF0, 0x90, 0x81, 0x4E, 0x74, 0x04,
+0xF0, 0xB1, 0x17, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x12, 0x62, 0xCF, 0x90, 0x81, 0x4E, 0xE0, 0x64,
+0x0C, 0x60, 0x07, 0xE4, 0x71, 0x1E, 0xB1, 0x17,
+0xD1, 0xC3, 0x22, 0xB1, 0x15, 0x90, 0x81, 0x44,
+0x74, 0x01, 0xF0, 0x22, 0x7D, 0xFF, 0x7F, 0xFF,
+0xA1, 0x1C, 0xF0, 0x7D, 0x04, 0x7F, 0x01, 0x21,
+0xCE, 0xB1, 0x17, 0x12, 0x57, 0x96, 0x80, 0xE5,
+0x7E, 0x08, 0x12, 0x2E, 0xA2, 0x90, 0x85, 0xBB,
+0x22, 0x7D, 0x01, 0x7F, 0x02, 0xF1, 0xC3, 0x7D,
+0x02, 0x7F, 0x02, 0x74, 0x3D, 0x2F, 0xF8, 0xE6,
+0x4D, 0xFE, 0xF6, 0x74, 0x30, 0x02, 0x56, 0xA7,
+0x7B, 0x2D, 0xF1, 0x9C, 0x12, 0x5D, 0xF1, 0x90,
+0x01, 0x37, 0x74, 0x02, 0xF0, 0xFD, 0x7F, 0x03,
+0xF1, 0xC3, 0x12, 0x57, 0xE3, 0xE4, 0xFD, 0x7F,
+0x01, 0x31, 0xCE, 0xE4, 0x90, 0x81, 0x45, 0xF0,
+0x22, 0x22, 0x80, 0xA1, 0xB1, 0x17, 0x80, 0x9D,
+0x90, 0x01, 0xC8, 0xE4, 0xF0, 0xA3, 0xF0, 0xA3,
+0xF0, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0xC8, 0x7F,
+0xFF, 0xFE, 0x12, 0x2B, 0x27, 0xBF, 0x01, 0x09,
+0x90, 0x81, 0xC8, 0xE0, 0x64, 0x03, 0x60, 0x03,
+0x22, 0x01, 0xBA, 0xE4, 0x90, 0x81, 0xCD, 0xF0,
+0x90, 0x81, 0xCD, 0xE0, 0xFF, 0xC3, 0x94, 0x02,
+0x40, 0x02, 0x01, 0xF5, 0xC3, 0x74, 0xFE, 0x9F,
+0xFF, 0xE4, 0x94, 0x00, 0xFE, 0x7B, 0x01, 0x7A,
+0x81, 0x79, 0xC9, 0x12, 0x2B, 0x27, 0xEF, 0x64,
+0x01, 0x70, 0x77, 0x90, 0x81, 0xC9, 0xE0, 0xFF,
+0x54, 0xC0, 0xFE, 0x60, 0x05, 0xEF, 0x54, 0x0C,
+0x70, 0x16, 0x90, 0x81, 0xC9, 0xE0, 0xFF, 0x54,
+0x30, 0x60, 0x67, 0xEF, 0x54, 0x03, 0x60, 0x62,
+0x90, 0x81, 0xCA, 0x74, 0x01, 0xF0, 0x80, 0x05,
+0xE4, 0x90, 0x81, 0xCA, 0xF0, 0x90, 0x81, 0xCA,
+0xE0, 0x90, 0x81, 0xC9, 0x70, 0x16, 0xE0, 0xFF,
+0xEE, 0x13, 0x13, 0x54, 0x3F, 0x90, 0x81, 0xCB,
+0xF0, 0xEF, 0x54, 0x0C, 0x13, 0x13, 0x54, 0x3F,
+0xA3, 0xF0, 0x80, 0x0D, 0xE0, 0xFE, 0x54, 0x30,
+0x90, 0x81, 0xCB, 0xF0, 0xEE, 0x54, 0x03, 0xA3,
+0xF0, 0x90, 0x81, 0xCB, 0xE0, 0x64, 0x30, 0x70,
+0x54, 0xA3, 0xE0, 0x64, 0x02, 0x70, 0x4E, 0x90,
+0x00, 0xF5, 0xE0, 0x54, 0x40, 0x90, 0x81, 0xCE,
+0xF0, 0xE0, 0x70, 0x41, 0xA3, 0x74, 0x02, 0xF0,
+0x80, 0x10, 0x90, 0x81, 0xCF, 0x74, 0x01, 0xF0,
+0x80, 0x08, 0x90, 0x81, 0xCD, 0xE0, 0x04, 0xF0,
+0x01, 0x20, 0x90, 0x01, 0xC4, 0x74, 0xF8, 0xF0,
+0x74, 0x4F, 0xA3, 0xF0, 0x90, 0x81, 0xCF, 0xE0,
+0x90, 0x01, 0xC8, 0xF0, 0x90, 0x81, 0xC9, 0xE0,
+0x90, 0x01, 0xC9, 0xF0, 0x90, 0x81, 0xCA, 0xE0,
+0x90, 0x01, 0xCA, 0xF0, 0xE4, 0xFD, 0x7F, 0x1F,
+0x12, 0x32, 0x1E, 0x80, 0xD5, 0x22, 0x90, 0x00,
+0x80, 0xE0, 0x44, 0x80, 0xFD, 0x7F, 0x80, 0x12,
+0x32, 0x1E, 0x90, 0xFD, 0x00, 0xE0, 0x54, 0xBF,
+0xF0, 0x12, 0x4F, 0xF8, 0x12, 0x74, 0x48, 0x12,
+0x32, 0x77, 0x12, 0x74, 0x55, 0x31, 0x53, 0x7F,
+0x01, 0x12, 0x42, 0x15, 0x90, 0x81, 0xBB, 0x74,
+0x02, 0xF0, 0xFF, 0x12, 0x42, 0x15, 0x90, 0x81,
+0xBB, 0xE0, 0x04, 0xF0, 0x12, 0x5F, 0xFA, 0x31,
+0x64, 0x90, 0x01, 0xCC, 0x74, 0x0F, 0xF0, 0x90,
+0x00, 0x80, 0xE0, 0x44, 0x40, 0xFD, 0x7F, 0x80,
+0x12, 0x32, 0x1E, 0x75, 0x20, 0xFF, 0xF1, 0xCF,
+0x12, 0x74, 0x85, 0x12, 0x75, 0x07, 0xE4, 0xFF,
+0x02, 0x42, 0x9E, 0xE4, 0x90, 0x80, 0x3C, 0x31,
+0x5C, 0xA3, 0xF0, 0x22, 0xF0, 0xA3, 0xF0, 0xA3,
+0xF0, 0xA3, 0xF0, 0x22, 0x31, 0x77, 0x12, 0x74,
+0x3A, 0x51, 0x17, 0x12, 0x4A, 0x36, 0x12, 0x79,
+0xC8, 0x12, 0x7B, 0x13, 0x02, 0x45, 0x6F, 0xE4,
+0xFD, 0xFF, 0x12, 0x7B, 0x2D, 0xED, 0x70, 0x12,
+0x31, 0xB6, 0xC0, 0x83, 0xC0, 0x82, 0x31, 0xAE,
+0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5E,
+0x80, 0x0F, 0x31, 0xB6, 0xC0, 0x83, 0xC0, 0x82,
+0x31, 0xAE, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC,
+0x4E, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0x31, 0xC1,
+0x90, 0x81, 0x40, 0xEF, 0xF0, 0x22, 0xE0, 0xFE,
+0x74, 0x01, 0xA8, 0x07, 0x08, 0x22, 0x74, 0x38,
+0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83,
+0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x7D, 0x08, 0xED, 0x14, 0xF9, 0x24, 0x38, 0x31,
+0xB9, 0xE0, 0x60, 0x3A, 0x7C, 0x08, 0xEC, 0x14,
+0x90, 0x82, 0xAA, 0xF0, 0x74, 0x38, 0x29, 0x31,
+0xB9, 0xE0, 0xFB, 0x7A, 0x00, 0x90, 0x82, 0xAA,
+0x12, 0x6B, 0x2E, 0x80, 0x05, 0xC3, 0x33, 0xCE,
+0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEE, 0x5A, 0xFE,
+0xEF, 0x5B, 0x4E, 0x60, 0x0F, 0xE9, 0x75, 0xF0,
+0x08, 0xA4, 0xFF, 0x90, 0x82, 0xAA, 0xE0, 0x2F,
+0x04, 0xFF, 0x80, 0x06, 0xDC, 0xC8, 0xDD, 0xBA,
+0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7E,
+0x00, 0x7F, 0x01, 0x7D, 0x00, 0x7B, 0x01, 0x7A,
+0x81, 0x79, 0x41, 0x12, 0x45, 0x6F, 0x90, 0x81,
+0x41, 0xE0, 0x54, 0xFD, 0xF0, 0xE4, 0x31, 0x5D,
+0xA3, 0x74, 0x0C, 0xF0, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x8B, 0x54, 0x8A, 0x55,
+0x89, 0x56, 0x90, 0x05, 0x27, 0xE0, 0xF5, 0x57,
+0x8B, 0x13, 0x8A, 0x14, 0x89, 0x15, 0x75, 0x16,
+0x01, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0x41, 0x12,
+0x2B, 0xED, 0x12, 0x74, 0x1A, 0xFF, 0xC3, 0x13,
+0x20, 0xE0, 0x02, 0x41, 0xF3, 0x90, 0x81, 0x41,
+0xE0, 0x30, 0xE0, 0x73, 0xD1, 0x99, 0x75, 0x57,
+0x21, 0x90, 0x81, 0x41, 0xE0, 0x13, 0x13, 0x54,
+0x3F, 0x30, 0xE0, 0x07, 0xD1, 0x8D, 0x43, 0x57,
+0x08, 0x80, 0x0C, 0xE4, 0x90, 0x81, 0x42, 0xF0,
+0xA3, 0xF0, 0x7D, 0x40, 0xFF, 0xD1, 0x83, 0x91,
+0x88, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x03, 0x43,
+0x57, 0x12, 0xEF, 0xC4, 0x54, 0x0F, 0x30, 0xE0,
+0x03, 0x43, 0x57, 0x14, 0x90, 0x81, 0x41, 0xE0,
+0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0, 0x03, 0x43,
+0x57, 0x80, 0x12, 0x7B, 0x39, 0x20, 0xE0, 0x03,
+0x43, 0x57, 0x40, 0x71, 0x9E, 0x90, 0x81, 0x44,
+0xE0, 0x70, 0x04, 0x7F, 0x01, 0x71, 0xA5, 0x91,
+0x90, 0x30, 0xE0, 0x04, 0x7F, 0x04, 0x80, 0x0B,
+0x91, 0x9B, 0xEF, 0x60, 0x04, 0x7F, 0x01, 0x80,
+0x02, 0x7F, 0x02, 0x71, 0xA5, 0x61, 0x66, 0x75,
+0x57, 0x01, 0x71, 0x9E, 0x90, 0x81, 0x44, 0xE0,
+0x64, 0x04, 0x60, 0x02, 0x61, 0x99, 0xFF, 0x71,
+0xA5, 0x61, 0x99, 0x90, 0x81, 0x41, 0xE0, 0x30,
+0xE0, 0x74, 0xD1, 0x99, 0x43, 0x57, 0x31, 0x90,
+0x81, 0x41, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30,
+0xE0, 0x07, 0xD1, 0x8D, 0x43, 0x57, 0x08, 0x80,
+0x06, 0x7D, 0x40, 0xE4, 0xFF, 0xD1, 0x83, 0x91,
+0x88, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x03, 0x43,
+0x57, 0x02, 0xEF, 0xC4, 0x54, 0x0F, 0x30, 0xE0,
+0x03, 0x43, 0x57, 0x04, 0x71, 0x9E, 0x91, 0x90,
+0x30, 0xE0, 0x0A, 0xF1, 0x70, 0x60, 0x2F, 0xE4,
+0xFD, 0x7F, 0x02, 0x80, 0x1C, 0xF1, 0x96, 0x90,
+0x81, 0x45, 0xE0, 0xB4, 0x02, 0x18, 0xF1, 0xAF,
+0x91, 0x9B, 0xBF, 0x01, 0x09, 0x90, 0x81, 0x4D,
+0xE0, 0xFF, 0x7D, 0x01, 0x80, 0x03, 0xE4, 0xFD,
+0xFF, 0x12, 0x4B, 0x21, 0x80, 0x08, 0x90, 0x81,
+0x4E, 0xE0, 0x90, 0x81, 0x45, 0xF0, 0x90, 0x05,
+0x40, 0x74, 0x22, 0xF0, 0x80, 0x2B, 0x75, 0x57,
+0x01, 0x71, 0x9E, 0x90, 0x81, 0x45, 0xE0, 0xB4,
+0x02, 0x06, 0x7D, 0x01, 0x7F, 0x04, 0x80, 0x0B,
+0x90, 0x81, 0x45, 0xE0, 0xB4, 0x08, 0x07, 0x7D,
+0x01, 0x7F, 0x0C, 0x12, 0x4B, 0x21, 0x12, 0x63,
+0x26, 0x90, 0x81, 0x4D, 0x12, 0x61, 0x76, 0x51,
+0x17, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x05,
+0x27, 0xE5, 0x57, 0xF0, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x81, 0x44, 0xE0,
+0xF5, 0x5A, 0xE5, 0x5A, 0x6F, 0x70, 0x02, 0x81,
+0x83, 0xEF, 0x14, 0x60, 0x38, 0x14, 0x60, 0x5C,
+0x14, 0x60, 0x7C, 0x14, 0x70, 0x02, 0x81, 0x62,
+0x24, 0x04, 0x60, 0x02, 0x81, 0x83, 0xE5, 0x5A,
+0xB4, 0x04, 0x04, 0xF1, 0x55, 0x81, 0x83, 0xE5,
+0x5A, 0xB4, 0x02, 0x04, 0xF1, 0x61, 0x81, 0x83,
+0xE5, 0x5A, 0xB4, 0x03, 0x04, 0xF1, 0x6B, 0x81,
+0x83, 0xE5, 0x5A, 0x64, 0x01, 0x60, 0x02, 0x81,
+0x83, 0xF1, 0x58, 0x81, 0x83, 0xE5, 0x5A, 0xB4,
+0x04, 0x05, 0x12, 0x4F, 0xA9, 0x81, 0x83, 0xE5,
+0x5A, 0xB4, 0x02, 0x05, 0x12, 0x4F, 0x93, 0x80,
+0x7A, 0xE5, 0x5A, 0xB4, 0x03, 0x05, 0x12, 0x4F,
+0xF4, 0x80, 0x70, 0xE5, 0x5A, 0x70, 0x6C, 0x12,
+0x4F, 0xF2, 0x80, 0x67, 0xE5, 0x5A, 0xB4, 0x04,
+0x04, 0xF1, 0x3B, 0x80, 0x5E, 0xE5, 0x5A, 0xB4,
+0x01, 0x04, 0xF1, 0x2A, 0x80, 0x55, 0xE5, 0x5A,
+0xB4, 0x03, 0x04, 0xF1, 0x1A, 0x80, 0x4C, 0xE5,
+0x5A, 0x70, 0x48, 0xF1, 0x27, 0x80, 0x44, 0xE5,
+0x5A, 0xB4, 0x04, 0x04, 0xF1, 0x9E, 0x80, 0x3B,
+0xE5, 0x5A, 0xB4, 0x01, 0x04, 0xF1, 0x49, 0x80,
+0x32, 0xE5, 0x5A, 0xB4, 0x02, 0x04, 0xF1, 0x66,
+0x80, 0x29, 0xE5, 0x5A, 0x70, 0x25, 0xF1, 0x46,
+0x80, 0x21, 0xE5, 0x5A, 0xB4, 0x03, 0x04, 0xF1,
+0x1E, 0x80, 0x18, 0xE5, 0x5A, 0xB4, 0x01, 0x04,
+0xF1, 0x03, 0x80, 0x0F, 0xE5, 0x5A, 0xB4, 0x02,
+0x04, 0xF1, 0x8F, 0x80, 0x06, 0xE5, 0x5A, 0x70,
+0x02, 0xF1, 0x22, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x90, 0x81, 0x41, 0xE0, 0xFF, 0x13, 0x13, 0x22,
+0x90, 0x81, 0x41, 0xE0, 0xFF, 0xC4, 0x13, 0x13,
+0x54, 0x03, 0x22, 0x90, 0x05, 0x43, 0xE0, 0x7F,
+0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01, 0x22, 0xE4,
+0xF5, 0x4E, 0x90, 0x81, 0x4B, 0xE0, 0x60, 0x75,
+0x12, 0x47, 0x84, 0x70, 0x70, 0xB1, 0x27, 0x12,
+0x44, 0xD0, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06,
+0xC0, 0x07, 0x90, 0x05, 0x62, 0xB1, 0x40, 0x78,
+0x10, 0x12, 0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02,
+0xD0, 0x01, 0xD0, 0x00, 0x12, 0x44, 0xD0, 0xC0,
+0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xA3,
+0xB1, 0x40, 0x78, 0x18, 0x12, 0x20, 0xBB, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xF1,
+0xBE, 0x90, 0x81, 0x49, 0xE0, 0xFF, 0xC4, 0x54,
+0x0F, 0x60, 0x08, 0x90, 0x81, 0x47, 0x91, 0x93,
+0x20, 0xE0, 0x03, 0x75, 0x4E, 0x01, 0x90, 0x81,
+0x41, 0xE0, 0x30, 0xE0, 0x11, 0x90, 0x81, 0x45,
+0xE0, 0xB4, 0x02, 0x03, 0xE4, 0xF5, 0x4E, 0x91,
+0x9B, 0xEF, 0x70, 0x02, 0xF5, 0x4E, 0xE5, 0x4E,
+0x60, 0x03, 0x12, 0x49, 0x71, 0x22, 0xF0, 0x90,
+0x05, 0x61, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE,
+0x78, 0x08, 0x12, 0x20, 0xBB, 0xA8, 0x04, 0xA9,
+0x05, 0xAA, 0x06, 0xAB, 0x07, 0x90, 0x05, 0x60,
+0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x22, 0xE4,
+0x90, 0x81, 0xC4, 0xF0, 0x90, 0x81, 0x4B, 0xE0,
+0x60, 0x74, 0x12, 0x47, 0x84, 0x70, 0x6F, 0x12,
+0x7B, 0x74, 0xB1, 0x26, 0x12, 0x44, 0xD0, 0xC0,
+0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90,
+0x05, 0x62, 0xB1, 0x40, 0x78, 0x10, 0x12, 0x20,
+0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0,
+0x00, 0x12, 0x44, 0xD0, 0xC0, 0x04, 0xC0, 0x05,
+0xC0, 0x06, 0xC0, 0x07, 0xA3, 0xB1, 0x40, 0x78,
+0x18, 0x12, 0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02,
+0xD0, 0x01, 0xD0, 0x00, 0xF1, 0xBE, 0x90, 0x81,
+0xC4, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x81, 0x52,
+0xF0, 0x90, 0x81, 0x41, 0xE0, 0x30, 0xE0, 0x15,
+0x90, 0x81, 0x45, 0xE0, 0xB4, 0x02, 0x05, 0xE4,
+0x90, 0x81, 0xC4, 0xF0, 0x91, 0x9B, 0xEF, 0x70,
+0x04, 0x90, 0x81, 0xC4, 0xF0, 0x90, 0x81, 0xC4,
+0xE0, 0x60, 0x03, 0x12, 0x49, 0x71, 0x22, 0x90,
+0x81, 0x41, 0xE0, 0x30, 0xE0, 0x06, 0x90, 0x81,
+0x43, 0x74, 0x01, 0xF0, 0x90, 0x81, 0x4B, 0xE0,
+0x70, 0x02, 0xC1, 0x65, 0x90, 0x81, 0x62, 0xE0,
+0x04, 0xB1, 0x26, 0x12, 0x44, 0xD0, 0xC0, 0x04,
+0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x05,
+0x62, 0xB1, 0x40, 0x78, 0x10, 0x12, 0x20, 0xBB,
+0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00,
+0x12, 0x44, 0xD0, 0xC0, 0x04, 0xC0, 0x05, 0xC0,
+0x06, 0xC0, 0x07, 0xA3, 0xB1, 0x40, 0x78, 0x18,
+0x12, 0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0,
+0x01, 0xD0, 0x00, 0x12, 0x44, 0xD0, 0x90, 0x81,
+0x96, 0x12, 0x20, 0xCE, 0x90, 0x81, 0x47, 0xE0,
+0x54, 0x7F, 0xF0, 0xA3, 0xE0, 0x30, 0xE0, 0x0C,
+0x12, 0x67, 0xB0, 0x74, 0x05, 0xF0, 0x12, 0x6C,
+0xF1, 0x12, 0x6E, 0x0C, 0x12, 0x65, 0xB9, 0x13,
+0x54, 0x1F, 0x30, 0xE0, 0x09, 0x90, 0x01, 0x3B,
+0xE0, 0x30, 0xE4, 0x02, 0xD1, 0x79, 0x90, 0x82,
+0xAB, 0xE0, 0x04, 0xF0, 0xE0, 0xC3, 0x94, 0x80,
+0x40, 0x0B, 0x90, 0x01, 0x98, 0xE0, 0x54, 0xFE,
+0xF0, 0xE0, 0x44, 0x01, 0xF0, 0x12, 0x79, 0xD9,
+0x90, 0x81, 0xB7, 0xE0, 0x30, 0xE0, 0x09, 0x90,
+0x01, 0x3B, 0xE0, 0x30, 0xE4, 0x02, 0xD1, 0x79,
+0x22, 0x7D, 0x02, 0x7F, 0x02, 0xD1, 0x83, 0x7D,
+0x01, 0x7F, 0x02, 0x74, 0x3D, 0xF1, 0xA7, 0xFE,
+0xF6, 0x74, 0x30, 0x80, 0x1A, 0x90, 0x01, 0x34,
+0x74, 0x40, 0xF0, 0xFD, 0xE4, 0xFF, 0x02, 0x4F,
+0xC3, 0x7D, 0x03, 0x7F, 0x02, 0x74, 0x45, 0x2F,
+0xF8, 0xE6, 0x4D, 0xFE, 0xF6, 0x74, 0x38, 0x2F,
+0xF5, 0x82, 0xE4, 0x34, 0x01, 0xF5, 0x83, 0xEE,
+0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0xF1, 0xD6, 0xEF, 0x64, 0x01, 0x70, 0x1B,
+0x90, 0x81, 0xB9, 0xE0, 0x7D, 0x10, 0x7F, 0x03,
+0x60, 0x08, 0xD1, 0x9D, 0x12, 0x6B, 0xC9, 0xF0,
+0x80, 0x04, 0xD1, 0xFD, 0xD1, 0x79, 0x12, 0x4E,
+0x37, 0x80, 0x1D, 0x90, 0x81, 0xB9, 0xE0, 0x7D,
+0x10, 0x7F, 0x03, 0x60, 0x04, 0xD1, 0x9D, 0x80,
+0x02, 0xD1, 0xFD, 0x12, 0x4F, 0xBF, 0x7D, 0x01,
+0x7F, 0x02, 0x12, 0x4F, 0xC3, 0x12, 0x4D, 0x6C,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x74, 0x45, 0xF1,
+0xA7, 0x80, 0xA0, 0x7B, 0x1F, 0x7D, 0x6F, 0x7F,
+0xFF, 0x12, 0x4D, 0x1C, 0x90, 0x05, 0x27, 0xE0,
+0x54, 0xBF, 0xF0, 0x90, 0x81, 0x44, 0x74, 0x04,
+0xF0, 0x22, 0xF1, 0x33, 0xF0, 0x22, 0x7B, 0x25,
+0x80, 0xE3, 0x12, 0x4F, 0xF2, 0x80, 0xDC, 0x12,
+0x4F, 0xF2, 0x7B, 0x20, 0x12, 0x4F, 0x9C, 0xF1,
+0x33, 0xF0, 0x22, 0xF1, 0xE3, 0x90, 0x81, 0x44,
+0x74, 0x02, 0x22, 0xF1, 0x96, 0x7B, 0x23, 0x12,
+0x4F, 0x9C, 0xF1, 0x33, 0xF0, 0x22, 0x12, 0x4F,
+0xF2, 0x7B, 0x21, 0x12, 0x4F, 0x9C, 0x90, 0x81,
+0x44, 0x74, 0x03, 0xF0, 0x22, 0x12, 0x4F, 0xA9,
+0x12, 0x7B, 0x5C, 0xE4, 0x90, 0x81, 0x44, 0xF0,
+0x22, 0x12, 0x4F, 0x93, 0x80, 0xF2, 0x12, 0x4D,
+0x77, 0x80, 0xE3, 0x12, 0x4F, 0xF4, 0x80, 0xE8,
+0x90, 0x81, 0x45, 0xE0, 0x64, 0x02, 0x22, 0x91,
+0x90, 0x30, 0xE0, 0x0B, 0xF1, 0x70, 0x60, 0x07,
+0x7D, 0x01, 0x7F, 0x02, 0x12, 0x4B, 0x21, 0xF1,
+0x70, 0x60, 0x03, 0x12, 0x75, 0xDA, 0x22, 0x12,
+0x4D, 0x77, 0x7B, 0x24, 0xE1, 0x05, 0x90, 0x05,
+0x27, 0xE0, 0x44, 0x40, 0xF0, 0x22, 0x7B, 0x22,
+0x12, 0x4F, 0x9C, 0xF1, 0x96, 0x80, 0xA7, 0x2F,
+0xF8, 0xE6, 0xFE, 0xED, 0xF4, 0x5E, 0x22, 0x12,
+0x4D, 0x17, 0x12, 0x4F, 0xA3, 0xF1, 0x96, 0x90,
+0x81, 0x45, 0x74, 0x04, 0xF0, 0x22, 0x12, 0x44,
+0xD0, 0x90, 0x81, 0x9E, 0x12, 0x20, 0xCE, 0x90,
+0x81, 0x47, 0xE0, 0x44, 0x80, 0xF0, 0x22, 0x75,
+0xE8, 0x03, 0x75, 0xA8, 0x84, 0x22, 0x90, 0x01,
+0x3F, 0x74, 0x10, 0xF0, 0x22, 0x7D, 0x02, 0x7F,
+0x02, 0xC1, 0x83, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0xE4, 0x90, 0x82, 0x83, 0xF0, 0xA3,
+0xF0, 0x12, 0x5D, 0xF1, 0x90, 0x85, 0xBB, 0x12,
+0x20, 0xDA, 0xCC, 0xF0, 0x00, 0xC0, 0x7F, 0x8C,
+0x12, 0x4F, 0xB0, 0x12, 0x20, 0xDA, 0x00, 0x00,
+0x00, 0x14, 0xF1, 0xD9, 0x90, 0x82, 0x7F, 0x12,
+0x20, 0xDA, 0x00, 0x00, 0x00, 0x00, 0xE4, 0xFD,
+0xFF, 0xB1, 0xB7, 0x7F, 0xE8, 0x7E, 0x08, 0x12,
+0x2D, 0x5C, 0xEF, 0x54, 0x0E, 0xFF, 0xE4, 0xFE,
+0xED, 0x54, 0xF4, 0xFD, 0xEC, 0x54, 0x03, 0xFC,
+0xE4, 0xFB, 0xFA, 0xF9, 0xF8, 0xC3, 0x12, 0x44,
+0xDD, 0x60, 0x17, 0xD3, 0x11, 0x89, 0x40, 0x09,
+0x90, 0x01, 0xC3, 0xE0, 0x44, 0x02, 0xF0, 0x80,
+0x09, 0xD1, 0x5A, 0x90, 0x82, 0x83, 0xD1, 0x53,
+0x80, 0xC9, 0xC3, 0x11, 0x89, 0x50, 0x1B, 0xF1,
+0xD2, 0xEC, 0x44, 0x80, 0xFC, 0x90, 0x82, 0x85,
+0x12, 0x20, 0xCE, 0x90, 0x82, 0x85, 0x12, 0x44,
+0xEE, 0x11, 0x97, 0x7F, 0x7C, 0x7E, 0x08, 0x12,
+0x2E, 0xA2, 0x90, 0x01, 0x00, 0x74, 0x3F, 0xF0,
+0xA3, 0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x05, 0x53,
+0xE0, 0x44, 0x20, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x90, 0x82, 0x84, 0xE0, 0x94, 0xE8, 0x90,
+0x82, 0x83, 0xE0, 0x94, 0x03, 0x22, 0xFC, 0x90,
+0x85, 0xBB, 0x02, 0x20, 0xCE, 0x90, 0x82, 0x55,
+0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xA3, 0x12, 0x20,
+0xDA, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x90, 0x82,
+0x63, 0xF0, 0x7F, 0x24, 0x7E, 0x08, 0x12, 0x2D,
+0x5C, 0x90, 0x82, 0x5B, 0x12, 0x20, 0xCE, 0x90,
+0x82, 0x55, 0xE0, 0xFB, 0x70, 0x04, 0x31, 0x81,
+0x80, 0x06, 0xEB, 0x31, 0x87, 0x12, 0x2D, 0x5C,
+0x90, 0x82, 0x5F, 0x12, 0x20, 0xCE, 0x90, 0x82,
+0x56, 0x12, 0x55, 0x40, 0x78, 0x17, 0xB1, 0xD9,
+0xAB, 0x07, 0x90, 0x82, 0x5F, 0x12, 0x44, 0xEE,
+0xED, 0x54, 0x7F, 0xFD, 0xEC, 0x54, 0x80, 0xFC,
+0x12, 0x44, 0xD0, 0xEC, 0x44, 0x80, 0xFC, 0x90,
+0x82, 0x5F, 0x12, 0x20, 0xCE, 0x31, 0x81, 0xEC,
+0x54, 0x7F, 0x11, 0x96, 0x31, 0x9A, 0x31, 0x87,
+0xC0, 0x06, 0xC0, 0x07, 0x90, 0x82, 0x5F, 0x12,
+0x44, 0xEE, 0x11, 0x97, 0xD0, 0x07, 0xD0, 0x06,
+0x12, 0x2E, 0xA2, 0x31, 0x81, 0xEC, 0x44, 0x80,
+0x11, 0x96, 0x31, 0x9A, 0x70, 0x04, 0x7F, 0x20,
+0x80, 0x09, 0x90, 0x82, 0x55, 0xE0, 0xB4, 0x01,
+0x16, 0x7F, 0x28, 0x7E, 0x08, 0x12, 0x2D, 0x5C,
+0x78, 0x08, 0x12, 0x20, 0xA8, 0xEF, 0x54, 0x01,
+0xFF, 0xE4, 0x90, 0x82, 0x63, 0xEF, 0xF0, 0x90,
+0x82, 0x63, 0xE0, 0x90, 0x82, 0x55, 0x60, 0x0E,
+0xE0, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x66, 0xF5,
+0x82, 0xE4, 0x34, 0x87, 0x80, 0x0C, 0xE0, 0x75,
+0xF0, 0x08, 0xA4, 0x24, 0x64, 0xF5, 0x82, 0xE4,
+0x34, 0x87, 0x31, 0x92, 0x12, 0x2D, 0x5C, 0xED,
+0x54, 0x0F, 0xFD, 0xE4, 0xFC, 0x90, 0x82, 0x57,
+0x12, 0x20, 0xCE, 0x90, 0x82, 0x57, 0x02, 0x44,
+0xEE, 0x90, 0x82, 0x5B, 0x02, 0x44, 0xEE, 0x75,
+0xF0, 0x08, 0xA4, 0x24, 0x62, 0xF5, 0x82, 0xE4,
+0x34, 0x87, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0x22, 0x7F, 0x24, 0x7E, 0x08, 0x12, 0x2E,
+0xA2, 0x90, 0x82, 0x55, 0xE0, 0x22, 0x90, 0x82,
+0x73, 0xEF, 0xF0, 0xAB, 0x05, 0x90, 0x82, 0x79,
+0x12, 0x20, 0xDA, 0x00, 0x00, 0x00, 0x00, 0xAF,
+0x03, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x14, 0xB1,
+0xD9, 0xAB, 0x07, 0x90, 0x82, 0x75, 0x12, 0x44,
+0xEE, 0xED, 0x54, 0x0F, 0xFD, 0xE4, 0xFC, 0x12,
+0x44, 0xD0, 0xEC, 0x54, 0x0F, 0xFC, 0x90, 0x82,
+0x79, 0x12, 0x20, 0xCE, 0x90, 0x82, 0x73, 0xE0,
+0x75, 0xF0, 0x08, 0xA4, 0x24, 0x60, 0xF5, 0x82,
+0xE4, 0x34, 0x87, 0x31, 0x92, 0xC0, 0x06, 0xC0,
+0x07, 0x90, 0x82, 0x79, 0x12, 0x44, 0xEE, 0x11,
+0x97, 0xD0, 0x07, 0xD0, 0x06, 0x02, 0x2E, 0xA2,
+0xAC, 0x07, 0xED, 0xAD, 0x04, 0x78, 0x24, 0xF2,
+0xED, 0x08, 0xF2, 0xEB, 0xB4, 0x04, 0x07, 0x78,
+0x27, 0x74, 0x01, 0xF2, 0x80, 0x0E, 0xEB, 0x78,
+0x27, 0xB4, 0x05, 0x05, 0x74, 0x02, 0xF2, 0x80,
+0x03, 0x74, 0x04, 0xF2, 0xB1, 0x73, 0xE2, 0x94,
+0x00, 0x50, 0x45, 0xE4, 0x78, 0x26, 0xF2, 0x71,
+0x1B, 0x9F, 0x40, 0x02, 0x61, 0x1A, 0x71, 0x24,
+0x60, 0x1F, 0x74, 0x37, 0x2E, 0xF8, 0xE2, 0x78,
+0x32, 0xF2, 0xEE, 0xFF, 0x78, 0x25, 0xE2, 0x2F,
+0xFF, 0x18, 0xE2, 0x34, 0x00, 0x8F, 0x82, 0xF5,
+0x83, 0xE0, 0x78, 0x29, 0xF2, 0x78, 0x32, 0xB1,
+0x93, 0x78, 0x24, 0x08, 0xE2, 0xFF, 0x08, 0xE2,
+0x2F, 0xFF, 0x78, 0x28, 0xE2, 0xFD, 0x12, 0x32,
+0x1E, 0x78, 0x26, 0xE2, 0x04, 0xF2, 0x80, 0xBF,
+0xB1, 0x73, 0xE2, 0x94, 0x07, 0x50, 0x30, 0xE4,
+0x78, 0x26, 0xF2, 0x71, 0x1B, 0x9F, 0x40, 0x02,
+0x61, 0x1A, 0x71, 0x24, 0x60, 0x14, 0x78, 0x26,
+0xE2, 0xFF, 0xB1, 0x85, 0xE0, 0x78, 0x29, 0xF2,
+0x74, 0x37, 0x2F, 0xF8, 0xE2, 0x78, 0x32, 0xF2,
+0xB1, 0x93, 0xB1, 0x6B, 0xB1, 0x85, 0xEF, 0xF0,
+0x78, 0x26, 0xE2, 0x04, 0xF2, 0x80, 0xD4, 0x90,
+0x82, 0x35, 0xE0, 0x60, 0x0A, 0xB1, 0x63, 0x12,
+0x2D, 0x5C, 0x78, 0x2E, 0x12, 0x45, 0x1F, 0xE4,
+0x78, 0x26, 0xF2, 0x71, 0x1B, 0x9F, 0x50, 0x4E,
+0x71, 0x24, 0x60, 0x2B, 0x78, 0x2E, 0x12, 0x44,
+0xFA, 0x78, 0x26, 0xE2, 0xFB, 0x75, 0xF0, 0x08,
+0xA4, 0xF9, 0xF8, 0x12, 0x20, 0xA8, 0x78, 0x29,
+0xEF, 0xF2, 0x74, 0x37, 0x2B, 0xF8, 0xE2, 0x78,
+0x32, 0xF2, 0xE2, 0xFE, 0xF4, 0x5F, 0xFF, 0x78,
+0x28, 0xE2, 0xFD, 0xEE, 0x5D, 0x4F, 0xF2, 0xB1,
+0x6B, 0xFD, 0xC3, 0x74, 0x03, 0x9D, 0xFD, 0xE4,
+0x94, 0x00, 0xFC, 0x7B, 0xFE, 0x74, 0x2A, 0x2D,
+0xF9, 0x74, 0x80, 0x3C, 0xFA, 0xEF, 0x12, 0x1F,
+0xEA, 0xE2, 0x04, 0xF2, 0x80, 0xAD, 0x78, 0x2A,
+0x12, 0x44, 0xFA, 0x11, 0x97, 0xB1, 0x63, 0x12,
+0x2E, 0xA2, 0x22, 0x78, 0x27, 0xE2, 0xFF, 0x18,
+0xE2, 0xFE, 0xC3, 0x22, 0x74, 0x33, 0x2E, 0xF8,
+0xE2, 0x78, 0x28, 0xF2, 0x90, 0x82, 0x35, 0xE0,
+0x22, 0x78, 0x10, 0x74, 0x01, 0xF2, 0x90, 0x02,
+0x09, 0xE0, 0x78, 0x00, 0xF2, 0x08, 0x74, 0x20,
+0xF2, 0x18, 0xE2, 0xFF, 0x30, 0xE0, 0x05, 0x08,
+0xE2, 0x24, 0x80, 0xF2, 0xEF, 0xC3, 0x13, 0x90,
+0xFD, 0x10, 0xF0, 0x78, 0x01, 0xE2, 0xB1, 0x7B,
+0xE0, 0x78, 0x03, 0xF2, 0x64, 0x04, 0x60, 0x0D,
+0xE2, 0xFF, 0x64, 0x08, 0x60, 0x07, 0xEF, 0x64,
+0x0C, 0x60, 0x02, 0xA1, 0x59, 0xE4, 0x78, 0x02,
+0xF2, 0x78, 0x03, 0xE2, 0xFF, 0x18, 0xE2, 0xC3,
+0x9F, 0x50, 0x26, 0xE2, 0xFD, 0x18, 0xE2, 0x2D,
+0x90, 0x81, 0xD3, 0xF0, 0xE0, 0xFF, 0xB1, 0x7B,
+0xE0, 0xFE, 0x74, 0x04, 0x2D, 0xF8, 0xEE, 0xF2,
+0xEF, 0xB4, 0xFF, 0x06, 0x90, 0xFD, 0x10, 0xE0,
+0x04, 0xF0, 0x78, 0x02, 0xE2, 0x04, 0xF2, 0x80,
+0xD0, 0x78, 0x04, 0xE2, 0x78, 0x12, 0xF2, 0xFF,
+0x78, 0x05, 0xE2, 0x78, 0x11, 0xF2, 0x78, 0x06,
+0xE2, 0x78, 0x13, 0xF2, 0x78, 0x07, 0xE2, 0x78,
+0x14, 0xF2, 0x78, 0x08, 0xE2, 0x78, 0x33, 0xF2,
+0x78, 0x09, 0xE2, 0x78, 0x34, 0xF2, 0x78, 0x0A,
+0xE2, 0x78, 0x35, 0xF2, 0x78, 0x0B, 0xE2, 0x78,
+0x36, 0xF2, 0x78, 0x0C, 0xE2, 0x78, 0x37, 0xF2,
+0x78, 0x0D, 0xE2, 0x78, 0x38, 0xF2, 0x78, 0x0E,
+0xE2, 0x78, 0x39, 0xF2, 0x78, 0x0F, 0xE2, 0x78,
+0x3A, 0xF2, 0xE4, 0x78, 0x15, 0xF2, 0xEF, 0x24,
+0xF8, 0x60, 0x56, 0x24, 0xFC, 0x60, 0x4D, 0x24,
+0x08, 0x60, 0x02, 0xA1, 0x3B, 0x78, 0x11, 0xE2,
+0xB4, 0x01, 0x05, 0x12, 0x29, 0xC5, 0xA1, 0x40,
+0x78, 0x11, 0xE2, 0xB4, 0x02, 0x05, 0x12, 0x11,
+0xBD, 0xA1, 0x40, 0x78, 0x11, 0xE2, 0xB4, 0x03,
+0x05, 0x12, 0x6F, 0x9D, 0xA1, 0x40, 0x78, 0x11,
+0xE2, 0xB4, 0x10, 0x07, 0xB1, 0xA4, 0x12, 0x32,
+0xAA, 0xA1, 0x40, 0x78, 0x11, 0xE2, 0xB4, 0x11,
+0x07, 0xB1, 0xA4, 0x12, 0x32, 0x06, 0xA1, 0x40,
+0x78, 0x11, 0xE2, 0xF4, 0x60, 0x02, 0xA1, 0x40,
+0x18, 0xF2, 0xA1, 0x40, 0x78, 0x15, 0x74, 0x01,
+0xF2, 0x78, 0x11, 0xE2, 0x64, 0x07, 0x60, 0x02,
+0xA1, 0x25, 0x78, 0x34, 0xB1, 0x5C, 0x78, 0x08,
+0x12, 0x20, 0xBB, 0xC0, 0x04, 0xA9, 0x05, 0xAA,
+0x06, 0xAB, 0x07, 0x78, 0x33, 0xB1, 0x5C, 0xD0,
+0x00, 0x12, 0x44, 0xD0, 0xC0, 0x04, 0xC0, 0x05,
+0xC0, 0x06, 0xC0, 0x07, 0x78, 0x35, 0xB1, 0x5C,
+0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0, 0x03, 0xD0,
+0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x44, 0xD0,
+0x78, 0x18, 0x12, 0x45, 0x1F, 0x78, 0x15, 0xE2,
+0x60, 0x7D, 0x18, 0xE2, 0xFF, 0x18, 0xE2, 0xFD,
+0xB1, 0xE3, 0x78, 0x1C, 0x12, 0x45, 0x1F, 0x78,
+0x38, 0xB1, 0x5C, 0x78, 0x08, 0x12, 0x20, 0xBB,
+0xC0, 0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB, 0x07,
+0x78, 0x37, 0xB1, 0x5C, 0xD0, 0x00, 0x12, 0x44,
+0xD0, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0,
+0x07, 0x78, 0x39, 0xB1, 0x5C, 0x78, 0x10, 0x12,
+0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01,
+0xD0, 0x00, 0x12, 0x44, 0xD0, 0x78, 0x20, 0x12,
+0x45, 0x1F, 0x78, 0x20, 0x12, 0x44, 0xFA, 0x12,
+0x20, 0x9B, 0x78, 0x1C, 0x12, 0x45, 0x12, 0x12,
+0x44, 0xC3, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06,
+0xC0, 0x07, 0x78, 0x18, 0x12, 0x44, 0xFA, 0x78,
+0x20, 0x12, 0x45, 0x12, 0x12, 0x44, 0xC3, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12,
+0x44, 0xD0, 0x78, 0x18, 0x12, 0x45, 0x1F, 0x78,
+0x18, 0x12, 0x44, 0xFA, 0x90, 0x82, 0x7F, 0x12,
+0x20, 0xCE, 0x78, 0x13, 0xE2, 0xFD, 0x08, 0xE2,
+0xFF, 0xB1, 0xB7, 0x80, 0x1B, 0x78, 0x13, 0xE2,
+0xFF, 0x08, 0xE2, 0xFD, 0x78, 0x11, 0xE2, 0xFB,
+0x78, 0x15, 0xE2, 0x90, 0x82, 0x35, 0xF0, 0x51,
+0x00, 0x80, 0x05, 0x78, 0x10, 0x74, 0x02, 0xF2,
+0x78, 0x10, 0xE2, 0xFF, 0xC3, 0x94, 0x02, 0x50,
+0x10, 0xEF, 0x60, 0x0A, 0x78, 0x02, 0xE2, 0xFF,
+0x18, 0xE2, 0x2F, 0xF2, 0x61, 0x53, 0x7F, 0x01,
+0x22, 0x7F, 0x00, 0x22, 0xE2, 0xFF, 0xE4, 0xFC,
+0xFD, 0xFE, 0x22, 0x78, 0x24, 0xE2, 0xFE, 0x08,
+0xE2, 0xFF, 0x22, 0x78, 0x28, 0xE2, 0xFF, 0x78,
+0x26, 0xE2, 0x22, 0xD3, 0x78, 0x25, 0xE2, 0x94,
+0xFF, 0x18, 0x22, 0x24, 0x00, 0xF5, 0x82, 0xE4,
+0x34, 0xFC, 0xF5, 0x83, 0x22, 0xFD, 0x18, 0xE2,
+0x2D, 0xFD, 0x18, 0xE2, 0x34, 0x00, 0x8D, 0x82,
+0xF5, 0x83, 0x22, 0xE2, 0xFF, 0xF4, 0xFE, 0x78,
+0x29, 0xE2, 0x5E, 0xFE, 0x18, 0xE2, 0xFD, 0xEF,
+0x5D, 0x4E, 0xF2, 0x22, 0x78, 0x14, 0xE2, 0xFE,
+0x18, 0xE2, 0xFD, 0xED, 0xFF, 0x78, 0x16, 0xEE,
+0xF2, 0xFE, 0x08, 0xEF, 0xF2, 0xFF, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xC0, 0x07,
+0xC0, 0x05, 0x90, 0x82, 0x7F, 0x12, 0x44, 0xEE,
+0x90, 0x82, 0x75, 0x12, 0x20, 0xCE, 0xD0, 0x05,
+0xD0, 0x07, 0x31, 0xA6, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x12, 0x20, 0xBB, 0xA8, 0x04, 0xA9, 0x05,
+0xAA, 0x06, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x11, 0x9D, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0xE4, 0x90, 0x82, 0xA2, 0xF0, 0xA3, 0xF0,
+0x90, 0x05, 0x22, 0xE0, 0x90, 0x82, 0xA4, 0xF0,
+0x7B, 0x47, 0xF1, 0x97, 0x90, 0x05, 0xF8, 0xE0,
+0x70, 0x1B, 0xA3, 0xE0, 0x70, 0x17, 0xA3, 0xE0,
+0x70, 0x13, 0xA3, 0xE0, 0x70, 0x0F, 0x90, 0x82,
+0xA4, 0xE0, 0xFD, 0x7B, 0x48, 0xE4, 0xFF, 0x12,
+0x4D, 0x1C, 0x7F, 0x01, 0x22, 0xD3, 0x90, 0x82,
+0xA3, 0xE0, 0x94, 0xE8, 0x90, 0x82, 0xA2, 0xE0,
+0x94, 0x03, 0x40, 0x16, 0x90, 0x01, 0xC0, 0xE0,
+0x44, 0x20, 0xF0, 0x90, 0x82, 0xA4, 0xE0, 0xFD,
+0x7B, 0x5B, 0xE4, 0xFF, 0x12, 0x4D, 0x1C, 0x7F,
+0x00, 0x22, 0xD1, 0x5A, 0x90, 0x82, 0xA2, 0xD1,
+0x53, 0x80, 0xB1, 0xE4, 0x75, 0xF0, 0x01, 0x02,
+0x44, 0x9F, 0x7F, 0x32, 0x7E, 0x00, 0x02, 0x32,
+0xAA, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x90, 0x82, 0x9E, 0xEF, 0xF0, 0x90, 0x04, 0x1D,
+0xE0, 0x60, 0x21, 0x90, 0x05, 0x22, 0xE0, 0x90,
+0x82, 0xA1, 0xF0, 0x7B, 0x29, 0xF1, 0x97, 0xB1,
+0xF1, 0xBF, 0x01, 0x02, 0xD1, 0x9D, 0x90, 0x82,
+0xA1, 0xE0, 0xFD, 0x7B, 0x2A, 0xE4, 0xFF, 0x12,
+0x4D, 0x1C, 0x80, 0x02, 0xD1, 0x9D, 0xF1, 0xCB,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x80, 0x47,
+0xE0, 0xFF, 0x90, 0x82, 0x95, 0x74, 0x0B, 0xF0,
+0x7B, 0x08, 0x7D, 0x01, 0xD1, 0xE7, 0x90, 0x82,
+0x9F, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF, 0xF0, 0xFD,
+0x90, 0x82, 0x9E, 0xE0, 0xFF, 0xF1, 0x8B, 0x54,
+0x3F, 0xF0, 0xBF, 0x01, 0x02, 0x80, 0x16, 0xEF,
+0x70, 0x02, 0x80, 0x07, 0x90, 0x81, 0x4E, 0xE0,
+0x30, 0xE3, 0x0A, 0xF1, 0x7E, 0x54, 0xEF, 0xF1,
+0x8A, 0x44, 0x40, 0xF0, 0x22, 0xF1, 0x7E, 0x44,
+0x10, 0xF1, 0x8A, 0x44, 0x80, 0xF0, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x82,
+0x93, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x82,
+0x92, 0xEF, 0xF0, 0xE4, 0xFD, 0xFC, 0x12, 0x7A,
+0xFF, 0x7C, 0x00, 0xAD, 0x07, 0x90, 0x82, 0x92,
+0xE0, 0x90, 0x04, 0x25, 0xF0, 0x90, 0x82, 0x93,
+0xE0, 0x60, 0x0E, 0x74, 0x0F, 0x2F, 0xF5, 0x82,
+0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x80,
+0xF0, 0xAF, 0x05, 0x74, 0x08, 0x2F, 0xF5, 0x82,
+0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE4, 0xF0, 0x74,
+0x09, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5,
+0x83, 0xE0, 0x54, 0xF0, 0xF0, 0xAF, 0x05, 0xF1,
+0x9E, 0xE0, 0x20, 0xE1, 0x15, 0x54, 0x01, 0xFE,
+0x90, 0x82, 0x94, 0xE0, 0x25, 0xE0, 0x25, 0xE0,
+0xFB, 0xEE, 0x44, 0x02, 0x4B, 0xFE, 0xF1, 0x9E,
+0xEE, 0xF0, 0x90, 0x82, 0x95, 0xE0, 0xFF, 0xAE,
+0x05, 0x74, 0x1E, 0x2E, 0xF5, 0x82, 0xE4, 0x34,
+0xFC, 0xF5, 0x83, 0xEF, 0xF0, 0x74, 0x21, 0x2E,
+0xF1, 0x81, 0x54, 0xF7, 0xF0, 0xAE, 0x04, 0xAF,
+0x05, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x74, 0x21,
+0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0xE0, 0x22, 0xF0, 0x74, 0x1F, 0x2D, 0xF5, 0x82,
+0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0x7D,
+0xFF, 0xE4, 0xFF, 0x02, 0x4D, 0x1C, 0x74, 0x16,
+0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0x22, 0x90, 0x04, 0x1D, 0xE0, 0x70, 0x1B, 0x90,
+0x80, 0x45, 0xE0, 0xFF, 0x90, 0x82, 0x95, 0x74,
+0x09, 0xF0, 0x7B, 0x18, 0xE4, 0xFD, 0xD1, 0xE7,
+0x90, 0x81, 0xC2, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0,
+0xF1, 0xCB, 0x22, 0x90, 0x04, 0x1F, 0x74, 0x20,
+0xF0, 0x22, 0x7F, 0x7C, 0x7E, 0x08, 0x02, 0x2D,
+0x5C, 0x7F, 0x70, 0x7E, 0x0E, 0x02, 0x2E, 0xA2,
+0x90, 0x00, 0xF7, 0xE0, 0x20, 0xE7, 0x09, 0xE0,
+0x7F, 0x01, 0x20, 0xE6, 0x0C, 0x7F, 0x02, 0x22,
+0x90, 0x00, 0xF7, 0xE0, 0x30, 0xE6, 0x02, 0x7F,
+0x03, 0x22, 0xF1, 0xE0, 0x90, 0x80, 0x42, 0xEF,
+0xF0, 0x11, 0x1A, 0x90, 0x01, 0x64, 0x74, 0x01,
+0xF0, 0x90, 0x00, 0x12, 0xE0, 0x54, 0xC7, 0x44,
+0x20, 0xFD, 0x7F, 0x12, 0x12, 0x32, 0x1E, 0x02,
+0x2D, 0xA7, 0x90, 0x00, 0x08, 0xE0, 0x54, 0xEF,
+0xF0, 0x11, 0x92, 0x11, 0xBA, 0x11, 0x51, 0x11,
+0x70, 0xE4, 0xF5, 0x35, 0xF5, 0x37, 0xF5, 0x36,
+0xF5, 0x37, 0x75, 0x38, 0x80, 0xAD, 0x35, 0x7F,
+0x50, 0x12, 0x32, 0x1E, 0xAD, 0x36, 0x7F, 0x51,
+0x12, 0x32, 0x1E, 0xAD, 0x37, 0x7F, 0x52, 0x12,
+0x32, 0x1E, 0xAD, 0x38, 0x7F, 0x53, 0x02, 0x32,
+0x1E, 0x75, 0x3D, 0x10, 0xE4, 0xF5, 0x3E, 0x75,
+0x3F, 0x07, 0x75, 0x40, 0x02, 0x90, 0x01, 0x30,
+0xE5, 0x3D, 0xF0, 0xA3, 0xE5, 0x3E, 0xF0, 0xA3,
+0xE5, 0x3F, 0xF0, 0xA3, 0xE5, 0x40, 0xF0, 0x22,
+0x75, 0x45, 0x07, 0x75, 0x46, 0x01, 0x43, 0x46,
+0x10, 0x75, 0x47, 0x03, 0x75, 0x48, 0x62, 0x90,
+0x01, 0x38, 0xE5, 0x45, 0xF0, 0xA3, 0xE5, 0x46,
+0xF0, 0xA3, 0xE5, 0x47, 0xF0, 0xA3, 0xE5, 0x48,
+0xF0, 0x22, 0x90, 0x01, 0x30, 0xE4, 0x12, 0x51,
+0x5C, 0x90, 0x01, 0x38, 0x12, 0x51, 0x5C, 0xFD,
+0x7F, 0x50, 0x12, 0x32, 0x1E, 0xE4, 0xFD, 0x7F,
+0x51, 0x12, 0x32, 0x1E, 0xE4, 0xFD, 0x7F, 0x52,
+0x12, 0x32, 0x1E, 0xE4, 0xFD, 0x7F, 0x53, 0x02,
+0x32, 0x1E, 0x90, 0x01, 0x34, 0x74, 0xFF, 0x12,
+0x51, 0x5C, 0x90, 0x01, 0x3C, 0x12, 0x51, 0x5C,
+0xFD, 0x7F, 0x54, 0x12, 0x32, 0x1E, 0x7D, 0xFF,
+0x7F, 0x55, 0x12, 0x32, 0x1E, 0x7D, 0xFF, 0x7F,
+0x56, 0x12, 0x32, 0x1E, 0x7D, 0xFF, 0x7F, 0x57,
+0x02, 0x32, 0x1E, 0x90, 0x01, 0xCF, 0xE0, 0x90,
+0x82, 0xAC, 0xF0, 0xE0, 0xFF, 0x30, 0xE0, 0x07,
+0x90, 0x01, 0xCF, 0xE0, 0x54, 0xFE, 0xF0, 0xEF,
+0x30, 0xE5, 0x22, 0x90, 0x01, 0xCF, 0xE0, 0x54,
+0xDF, 0xF0, 0x90, 0x01, 0x34, 0x74, 0x20, 0xF0,
+0xE4, 0xF5, 0xA8, 0xF5, 0xE8, 0x11, 0x92, 0x90,
+0x00, 0x03, 0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x03,
+0x12, 0x32, 0x1E, 0x80, 0xFE, 0x22, 0xE4, 0x90,
+0x81, 0xD0, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90,
+0x81, 0xD0, 0xE0, 0x64, 0x01, 0xF0, 0x24, 0x1E,
+0x90, 0x01, 0xC4, 0xF0, 0x74, 0x61, 0xA3, 0xF0,
+0x90, 0x81, 0x4B, 0xE0, 0x60, 0x0E, 0x90, 0x81,
+0x4E, 0xE0, 0xFF, 0x90, 0x81, 0x4D, 0xE0, 0x6F,
+0x60, 0x02, 0x31, 0x68, 0xC2, 0xAF, 0x12, 0x74,
+0xE0, 0xBF, 0x01, 0x02, 0x31, 0xAD, 0xD2, 0xAF,
+0xF1, 0xC1, 0x12, 0x32, 0x9E, 0xBF, 0x01, 0x03,
+0x12, 0x72, 0xCA, 0x12, 0x41, 0x4D, 0x80, 0xBF,
+0x90, 0x81, 0x41, 0xE0, 0x90, 0x81, 0x4D, 0x30,
+0xE0, 0x04, 0xE0, 0xFF, 0x80, 0x1C, 0xE0, 0xFF,
+0x7D, 0x01, 0x02, 0x4B, 0x21, 0x90, 0x81, 0x4B,
+0xE0, 0x60, 0x0E, 0x90, 0x06, 0x92, 0xE0, 0x30,
+0xE1, 0x02, 0x41, 0xCF, 0x12, 0x74, 0x12, 0x31,
+0x68, 0x22, 0xAE, 0x07, 0x12, 0x54, 0x9B, 0xBF,
+0x01, 0x10, 0x12, 0x7B, 0x39, 0x20, 0xE0, 0x0A,
+0xAF, 0x06, 0x7D, 0x01, 0x12, 0x4B, 0x21, 0x7F,
+0x01, 0x22, 0x7F, 0x00, 0x22, 0x90, 0x81, 0x46,
+0xE0, 0x30, 0xE0, 0x19, 0x90, 0x81, 0x41, 0xE0,
+0xFF, 0x30, 0xE0, 0x0F, 0xC3, 0x13, 0x30, 0xE0,
+0x08, 0x12, 0x7A, 0x4B, 0xBF, 0x01, 0x06, 0x80,
+0x02, 0x80, 0x00, 0x31, 0xCE, 0x22, 0x90, 0x81,
+0x4E, 0xE0, 0xFF, 0x60, 0x03, 0xB4, 0x08, 0x0E,
+0x12, 0x76, 0x98, 0xBF, 0x01, 0x08, 0x31, 0xE7,
+0x90, 0x01, 0xE5, 0xE0, 0x04, 0xF0, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x77,
+0x1A, 0x31, 0xF8, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x12, 0x76, 0xFD, 0x90, 0x81, 0x56, 0xE0, 0x20,
+0xE0, 0x0C, 0x90, 0x00, 0x26, 0xE0, 0x54, 0x7F,
+0xFD, 0x7F, 0x26, 0x12, 0x32, 0x1E, 0x90, 0x00,
+0x08, 0xE0, 0x54, 0xEF, 0xFD, 0x7F, 0x08, 0x12,
+0x32, 0x1E, 0xE4, 0xFF, 0x90, 0x81, 0xD3, 0xEF,
+0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x01,
+0x09, 0xE0, 0x7F, 0x00, 0x30, 0xE7, 0x02, 0x7F,
+0x01, 0x90, 0x81, 0xD3, 0xE0, 0x6F, 0x60, 0x35,
+0xC3, 0x90, 0x81, 0xD5, 0xE0, 0x94, 0x88, 0x90,
+0x81, 0xD4, 0xE0, 0x94, 0x13, 0x40, 0x08, 0x90,
+0x01, 0xC0, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0x90,
+0x81, 0xD4, 0x12, 0x5E, 0x53, 0xF1, 0xD0, 0xD3,
+0x90, 0x81, 0xD5, 0xE0, 0x94, 0x32, 0x90, 0x81,
+0xD4, 0xE0, 0x94, 0x00, 0x40, 0xC0, 0x90, 0x01,
+0xC6, 0xE0, 0x30, 0xE0, 0xB9, 0x22, 0x90, 0x81,
+0x46, 0x12, 0x54, 0x93, 0x30, 0xE0, 0x1E, 0xEF,
+0x54, 0xBF, 0xF0, 0x90, 0x04, 0xE0, 0xE0, 0x90,
+0x81, 0x47, 0x30, 0xE0, 0x06, 0xE0, 0x44, 0x01,
+0xF0, 0x80, 0x08, 0xE0, 0x54, 0xFE, 0x51, 0xC4,
+0x74, 0x04, 0xF0, 0x31, 0x68, 0x22, 0x90, 0x81,
+0x46, 0xE0, 0xFF, 0xF1, 0x7E, 0x30, 0xE0, 0x23,
+0xEF, 0x54, 0x7F, 0xF0, 0x90, 0x04, 0xE0, 0xE0,
+0x90, 0x81, 0x47, 0x30, 0xE1, 0x06, 0xE0, 0x44,
+0x02, 0xF0, 0x80, 0x07, 0xE0, 0x54, 0xFD, 0x51,
+0xC4, 0x04, 0xF0, 0x90, 0x81, 0x4B, 0xE0, 0x60,
+0x02, 0x31, 0x68, 0x22, 0xF0, 0x90, 0x01, 0xB9,
+0x74, 0x01, 0xF0, 0x90, 0x01, 0xB8, 0x22, 0x12,
+0x7B, 0x43, 0x30, 0xE0, 0x05, 0x90, 0x01, 0x5B,
+0xE4, 0xF0, 0x90, 0x06, 0x92, 0x74, 0x02, 0xF0,
+0x90, 0x01, 0x3C, 0x74, 0x04, 0xF0, 0xE4, 0xF5,
+0x1D, 0x90, 0x81, 0xAA, 0xE0, 0xC3, 0x13, 0x54,
+0x7F, 0xF5, 0x1E, 0xE4, 0xFB, 0xFD, 0x7F, 0x58,
+0x7E, 0x01, 0x12, 0x49, 0x0C, 0x90, 0x81, 0x46,
+0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x81, 0x4B,
+0xE0, 0x64, 0x01, 0x70, 0x18, 0x71, 0x36, 0x60,
+0x0C, 0xE4, 0xFD, 0x7F, 0x0C, 0x12, 0x4B, 0x21,
+0x12, 0x4D, 0x17, 0x80, 0xB2, 0x90, 0x81, 0x4E,
+0xE0, 0x70, 0x02, 0xF1, 0xD7, 0x22, 0x12, 0x75,
+0xF0, 0xEF, 0x70, 0x02, 0x71, 0x05, 0x22, 0x90,
+0x81, 0x4F, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x81,
+0x49, 0xE0, 0x54, 0x0F, 0x22, 0x90, 0x06, 0xA9,
+0xE0, 0xF5, 0x4E, 0x54, 0xC0, 0x70, 0x07, 0x71,
+0x7F, 0x54, 0xFD, 0xF0, 0x21, 0x68, 0xE5, 0x4E,
+0x30, 0xE6, 0x18, 0x90, 0x81, 0x4B, 0xE0, 0x64,
+0x01, 0x70, 0x12, 0x71, 0x2F, 0x64, 0x02, 0x60,
+0x05, 0x12, 0x5F, 0xA9, 0x80, 0x07, 0x12, 0x4F,
+0x80, 0x80, 0x02, 0x71, 0x7F, 0xE5, 0x4E, 0x90,
+0x81, 0x4F, 0x30, 0xE7, 0x05, 0x12, 0x48, 0xF8,
+0xE1, 0x85, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90,
+0x81, 0x4F, 0xE0, 0x54, 0xFE, 0xF0, 0x22, 0x90,
+0x06, 0xA9, 0xE0, 0x90, 0x81, 0xC1, 0xF0, 0xE0,
+0xFD, 0x54, 0xC0, 0x70, 0x04, 0x71, 0x7F, 0x80,
+0x55, 0xED, 0x30, 0xE6, 0x3F, 0x90, 0x81, 0x4B,
+0xE0, 0x64, 0x02, 0x70, 0x27, 0x90, 0x81, 0x46,
+0xE0, 0xFF, 0xC3, 0x13, 0x20, 0xE0, 0x09, 0x90,
+0x81, 0x4F, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x1A,
+0x71, 0x36, 0x64, 0x01, 0x70, 0x20, 0x90, 0x81,
+0x4F, 0xE0, 0x44, 0x04, 0xF0, 0x7F, 0x01, 0x12,
+0x5E, 0x61, 0x80, 0x12, 0x71, 0x2F, 0x64, 0x02,
+0x60, 0x05, 0x12, 0x5F, 0xA9, 0x80, 0x07, 0x12,
+0x4F, 0x80, 0x80, 0x02, 0x71, 0x7F, 0x90, 0x81,
+0xC1, 0xE0, 0x90, 0x81, 0x4F, 0x30, 0xE7, 0x05,
+0x12, 0x48, 0xF8, 0xE1, 0x85, 0xE0, 0x54, 0xFD,
+0xF0, 0x22, 0xB1, 0xB9, 0x13, 0x54, 0x1F, 0x30,
+0xE0, 0x0C, 0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03,
+0x30, 0xE0, 0x03, 0x12, 0x57, 0xDD, 0x12, 0x6C,
+0x98, 0x30, 0xE0, 0x08, 0xF1, 0x96, 0x54, 0x07,
+0x70, 0x38, 0x80, 0x34, 0x12, 0x6C, 0xA2, 0x40,
+0x2F, 0x12, 0x47, 0x84, 0x70, 0x2C, 0x12, 0x6C,
+0xBB, 0x71, 0x36, 0x70, 0x04, 0x91, 0x4B, 0xF0,
+0x22, 0x90, 0x81, 0x55, 0xE0, 0x04, 0xF0, 0xE0,
+0xD3, 0x94, 0x02, 0x40, 0x0A, 0x91, 0x4B, 0xF0,
+0xE4, 0x90, 0x81, 0x55, 0xF0, 0x80, 0x03, 0x12,
+0x4F, 0x80, 0xE4, 0x90, 0x81, 0x54, 0xF0, 0x22,
+0x31, 0x68, 0x22, 0x90, 0x81, 0x47, 0xE0, 0x54,
+0xFB, 0x22, 0xF1, 0x8D, 0xFF, 0x54, 0x7F, 0x90,
+0x81, 0x4B, 0xF0, 0xEF, 0xF1, 0x7E, 0xA3, 0xB1,
+0xD0, 0xFD, 0x54, 0xF0, 0xC4, 0x54, 0x0F, 0xFF,
+0x90, 0x81, 0x49, 0xE0, 0x54, 0xF0, 0x4F, 0x12,
+0x73, 0xA6, 0xFC, 0x54, 0x01, 0x25, 0xE0, 0xFF,
+0x90, 0x81, 0x46, 0xE0, 0x54, 0xFD, 0x4F, 0xF0,
+0xEC, 0x54, 0x04, 0xC3, 0x13, 0xFF, 0x90, 0x81,
+0x48, 0xE0, 0x54, 0xFD, 0x4F, 0xF0, 0xED, 0x54,
+0x0F, 0xC4, 0x54, 0xF0, 0xFF, 0xA3, 0xE0, 0x54,
+0x0F, 0x4F, 0xF0, 0x90, 0x00, 0x02, 0x12, 0x1F,
+0xBD, 0x90, 0x81, 0x4A, 0x12, 0x73, 0x9F, 0xFD,
+0x7F, 0x02, 0x12, 0x49, 0xCE, 0x90, 0x82, 0x3B,
+0x12, 0x45, 0x37, 0xD1, 0xB2, 0x51, 0xC5, 0xF0,
+0x90, 0x81, 0x4B, 0x12, 0x7B, 0x20, 0x71, 0x35,
+0x90, 0x01, 0xBE, 0xF0, 0x22, 0x90, 0x05, 0x62,
+0xE0, 0xFE, 0x90, 0x05, 0x61, 0xE0, 0xFD, 0xED,
+0x78, 0x02, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8,
+0xF9, 0xFF, 0x90, 0x81, 0xBF, 0xEE, 0xF0, 0xA3,
+0xEF, 0xF0, 0x12, 0x47, 0x84, 0x60, 0x02, 0xA1,
+0xAC, 0x90, 0x81, 0x4B, 0xE0, 0x70, 0x02, 0xA1,
+0xAC, 0x90, 0x81, 0x49, 0xE0, 0xFF, 0xC4, 0x54,
+0x0F, 0x64, 0x01, 0x70, 0x22, 0x90, 0x06, 0xAB,
+0xE0, 0x90, 0x81, 0x52, 0xF0, 0x90, 0x06, 0xAA,
+0xE0, 0x90, 0x81, 0x51, 0xF0, 0xA3, 0xE0, 0xFF,
+0x70, 0x08, 0x90, 0x81, 0x51, 0xE0, 0xFE, 0xFF,
+0x80, 0x00, 0x90, 0x81, 0x52, 0xEF, 0xF0, 0x12,
+0x77, 0xF5, 0xE4, 0x90, 0x81, 0x54, 0xF0, 0xA3,
+0x12, 0x6E, 0x14, 0x12, 0x47, 0xD3, 0xF1, 0x99,
+0x54, 0xEF, 0xF0, 0x90, 0x81, 0x41, 0xE0, 0x30,
+0xE0, 0x04, 0x71, 0x87, 0x80, 0x02, 0x71, 0x3D,
+0xB1, 0xB9, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x61,
+0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x20, 0xE0,
+0x27, 0xB1, 0xC8, 0x6F, 0x70, 0x53, 0x90, 0x81,
+0x47, 0xE0, 0x44, 0x40, 0xF0, 0x12, 0x7B, 0x74,
+0xF0, 0x12, 0x57, 0xD6, 0xFD, 0x7F, 0x03, 0x12,
+0x56, 0x9D, 0x12, 0x56, 0x7F, 0x12, 0x57, 0xDD,
+0x90, 0x81, 0x52, 0xE0, 0x14, 0xF0, 0x80, 0x31,
+0x90, 0x81, 0x49, 0xE0, 0xC4, 0x54, 0x0F, 0x64,
+0x01, 0x70, 0x26, 0xB1, 0xC8, 0xFE, 0x6F, 0x60,
+0x20, 0x90, 0x05, 0x73, 0xE0, 0xFF, 0xEE, 0x6F,
+0x60, 0x17, 0xB1, 0xB9, 0x54, 0x3F, 0x30, 0xE0,
+0x10, 0xEF, 0x54, 0xBF, 0xF0, 0x12, 0x57, 0xD6,
+0xFD, 0x7F, 0x03, 0x12, 0x56, 0xFD, 0x12, 0x4F,
+0xB9, 0xB1, 0xC1, 0xF0, 0x90, 0x81, 0x41, 0xE0,
+0xC3, 0x13, 0x20, 0xE0, 0x03, 0xB1, 0xC1, 0xF0,
+0x22, 0x90, 0x81, 0x47, 0xE0, 0xFF, 0x13, 0x13,
+0x22, 0x90, 0x81, 0x47, 0xE0, 0x44, 0x04, 0x22,
+0x90, 0x81, 0x51, 0xE0, 0xFF, 0xA3, 0xE0, 0x22,
+0xF0, 0x90, 0x00, 0x01, 0x02, 0x1F, 0xBD, 0xF1,
+0x8D, 0xFF, 0x54, 0x01, 0xFE, 0x90, 0x81, 0xAF,
+0x12, 0x6C, 0x04, 0xFF, 0xF0, 0x12, 0x1F, 0xA4,
+0xFE, 0x54, 0x04, 0xFD, 0xEF, 0x54, 0xFB, 0x4D,
+0xFF, 0x90, 0x81, 0xAF, 0xF0, 0xEE, 0x54, 0x08,
+0xFE, 0xEF, 0x54, 0xF7, 0x4E, 0xFF, 0xF0, 0x12,
+0x1F, 0xA4, 0x54, 0x10, 0x25, 0xE0, 0x25, 0xE0,
+0xFE, 0xEF, 0x54, 0xBF, 0x4E, 0x90, 0x81, 0xAF,
+0xF0, 0x90, 0x05, 0x52, 0xE0, 0x54, 0x07, 0xFF,
+0x90, 0x82, 0x3B, 0x60, 0x15, 0x12, 0x45, 0x37,
+0xB1, 0xD1, 0xFD, 0x90, 0x05, 0x56, 0xE0, 0xC3,
+0x9D, 0x90, 0x81, 0xB1, 0xF0, 0xA3, 0xED, 0xF0,
+0x80, 0x25, 0x12, 0x45, 0x37, 0xB1, 0xD1, 0xFB,
+0xFF, 0x90, 0x05, 0x54, 0xE0, 0xC3, 0x9F, 0xFF,
+0xE4, 0x94, 0x00, 0xFE, 0x7C, 0x00, 0x7D, 0x05,
+0x12, 0x20, 0x30, 0x90, 0x81, 0xB1, 0xEF, 0xF0,
+0xEB, 0x75, 0xF0, 0x05, 0x84, 0xA3, 0xF0, 0x90,
+0x82, 0x3B, 0x12, 0x45, 0x37, 0x12, 0x1F, 0xA4,
+0x20, 0xE0, 0x0A, 0x12, 0x4D, 0x15, 0x90, 0x01,
+0x57, 0xE4, 0xF0, 0x80, 0x06, 0x12, 0x49, 0xCA,
+0xF1, 0xC2, 0xF0, 0x12, 0x7A, 0x07, 0x13, 0x54,
+0x1F, 0x20, 0xE0, 0x04, 0xEF, 0x44, 0x20, 0xF0,
+0xF1, 0xC9, 0x30, 0xE0, 0x15, 0x90, 0x81, 0x4B,
+0x74, 0x01, 0xF0, 0xE4, 0x90, 0x81, 0x4D, 0xF0,
+0xB1, 0xC1, 0xF1, 0xAF, 0x74, 0x06, 0xF0, 0x02,
+0x6C, 0xF1, 0xE4, 0x90, 0x81, 0x4B, 0xF0, 0x90,
+0x81, 0x4D, 0x74, 0x0C, 0xF0, 0x90, 0x81, 0x46,
+0xE0, 0x54, 0xFE, 0xF0, 0xA3, 0xE0, 0x54, 0xFB,
+0xF0, 0x22, 0x90, 0x82, 0x3E, 0x12, 0x45, 0x40,
+0x12, 0x77, 0x73, 0x90, 0x81, 0x4B, 0xE0, 0xFF,
+0x12, 0x4E, 0x46, 0x90, 0x81, 0x4B, 0xE0, 0x60,
+0x1D, 0x90, 0x82, 0x3E, 0x12, 0x45, 0x37, 0xB1,
+0xD1, 0x54, 0x0F, 0xFF, 0x90, 0x00, 0x02, 0x12,
+0x1F, 0xBD, 0xFD, 0x12, 0x77, 0x99, 0xF1, 0xB0,
+0x74, 0x01, 0xF0, 0x12, 0x6C, 0xF1, 0x22, 0x90,
+0x82, 0x38, 0x12, 0x45, 0x40, 0x90, 0x82, 0x37,
+0xEF, 0xF0, 0x12, 0x45, 0x49, 0x67, 0x17, 0x00,
+0x67, 0x20, 0x01, 0x67, 0x29, 0x12, 0x67, 0x32,
+0x14, 0x67, 0x3B, 0x20, 0x67, 0x43, 0x24, 0x67,
+0x4C, 0x25, 0x67, 0x55, 0x26, 0x67, 0x5D, 0x27,
+0x67, 0x66, 0xC0, 0x00, 0x00, 0x67, 0x6E, 0x90,
+0x82, 0x38, 0x12, 0x45, 0x37, 0x02, 0x73, 0x55,
+0x90, 0x82, 0x38, 0x12, 0x45, 0x37, 0x02, 0x73,
+0xAD, 0x90, 0x82, 0x38, 0x12, 0x45, 0x37, 0x02,
+0x6F, 0x8A, 0x90, 0x82, 0x38, 0x12, 0x45, 0x37,
+0x02, 0x74, 0x23, 0x90, 0x82, 0x38, 0x12, 0x45,
+0x37, 0x81, 0x52, 0x90, 0x82, 0x38, 0x12, 0x45,
+0x37, 0x02, 0x52, 0x35, 0x90, 0x82, 0x38, 0x12,
+0x45, 0x37, 0x02, 0x74, 0x32, 0x90, 0x82, 0x38,
+0x12, 0x45, 0x37, 0xA1, 0xD7, 0x90, 0x82, 0x38,
+0x12, 0x45, 0x37, 0x02, 0x6B, 0xDB, 0x90, 0x82,
+0x38, 0x12, 0x45, 0x37, 0x80, 0x34, 0x90, 0x01,
+0xC0, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x82, 0x37,
+0xE0, 0x90, 0x01, 0xC2, 0xF0, 0x22, 0xC4, 0x13,
+0x13, 0x13, 0x54, 0x01, 0x22, 0x90, 0x81, 0x46,
+0xE0, 0x44, 0x04, 0xF0, 0x22, 0x90, 0x82, 0x3B,
+0x12, 0x45, 0x40, 0x02, 0x1F, 0xA4, 0xEF, 0x54,
+0xFB, 0xF0, 0x90, 0x81, 0x4F, 0xE0, 0x54, 0xFD,
+0xF0, 0x22, 0x12, 0x1F, 0xA4, 0x90, 0x81, 0xBC,
+0xB1, 0xD0, 0x90, 0x81, 0xBD, 0xF0, 0x22, 0xF0,
+0x90, 0x81, 0x5D, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD,
+0x90, 0x81, 0x64, 0xE0, 0xFB, 0x90, 0x82, 0x9D,
+0x22, 0x22, 0x90, 0x81, 0xAF, 0xE0, 0x44, 0x10,
+0x22, 0x90, 0x81, 0xAF, 0xE0, 0xC3, 0x13, 0x22,
+0x7F, 0x14, 0x7E, 0x00, 0x02, 0x32, 0xAA, 0x7D,
+0x01, 0x7F, 0x04, 0x02, 0x4B, 0x21, 0xE4, 0xFB,
+0xFA, 0xFD, 0x7F, 0x01, 0x12, 0x43, 0x4E, 0x90,
+0x82, 0x36, 0xEF, 0xF0, 0x60, 0xF0, 0x90, 0x80,
+0x3C, 0xE0, 0xFF, 0x70, 0x04, 0xA3, 0xE0, 0x60,
+0xE5, 0xC2, 0xAF, 0xEF, 0x30, 0xE1, 0x09, 0x90,
+0x80, 0x3C, 0xE0, 0x54, 0xFD, 0xF0, 0x11, 0x1D,
+0xD2, 0xAF, 0xC2, 0xAF, 0x90, 0x80, 0x3C, 0xE0,
+0xFF, 0x30, 0xE2, 0x05, 0x54, 0xFB, 0xF0, 0x31,
+0xAF, 0xD2, 0xAF, 0x80, 0xD1, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x80, 0x9C, 0xE0,
+0xFF, 0x90, 0x80, 0x9B, 0xE0, 0xB5, 0x07, 0x04,
+0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70,
+0x3F, 0x90, 0x80, 0x9B, 0xE0, 0xFE, 0x75, 0xF0,
+0x08, 0x90, 0x80, 0x4B, 0x12, 0x45, 0x2B, 0xE0,
+0xFD, 0xEE, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x4C,
+0xF9, 0x74, 0x80, 0x35, 0xF0, 0xFA, 0x7B, 0x01,
+0xAF, 0x05, 0x12, 0x66, 0xE7, 0x90, 0x80, 0x9B,
+0x31, 0xA8, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF,
+0x60, 0x05, 0xE4, 0x90, 0x80, 0x9B, 0xF0, 0x11,
+0x7D, 0x90, 0x80, 0x3C, 0xE0, 0x44, 0x02, 0xF0,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x01, 0xCC,
+0xE0, 0x54, 0x0F, 0x90, 0x82, 0xA7, 0xF0, 0x90,
+0x82, 0xA7, 0xE0, 0xFD, 0x70, 0x02, 0x21, 0x80,
+0x90, 0x80, 0x9B, 0xE0, 0xFF, 0x70, 0x06, 0xA3,
+0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF,
+0x90, 0x80, 0x9C, 0xE0, 0xB5, 0x07, 0x04, 0x7F,
+0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x08,
+0x90, 0x01, 0xC1, 0xE0, 0x44, 0x01, 0xF0, 0x22,
+0x90, 0x82, 0xA5, 0x71, 0x2E, 0x80, 0x05, 0xC3,
+0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF,
+0x5D, 0x70, 0x02, 0x21, 0x63, 0xE4, 0x90, 0x82,
+0xA8, 0xF0, 0x90, 0x82, 0xA8, 0xE0, 0xF9, 0xC3,
+0x94, 0x04, 0x50, 0x38, 0x31, 0x82, 0xA4, 0xFF,
+0xE9, 0xFD, 0x7C, 0x00, 0x2F, 0xFF, 0xEC, 0x35,
+0xF0, 0xFE, 0x74, 0xD0, 0x31, 0x99, 0x75, 0xF0,
+0x08, 0x90, 0x80, 0x4B, 0x31, 0x8A, 0x31, 0x81,
+0xA4, 0x2D, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74,
+0xF0, 0x31, 0x99, 0x75, 0xF0, 0x08, 0x90, 0x80,
+0x4F, 0x31, 0x8A, 0xF0, 0x90, 0x82, 0xA8, 0xE0,
+0x04, 0xF0, 0x80, 0xBE, 0x90, 0x82, 0xA7, 0xE0,
+0xFF, 0x90, 0x82, 0xA5, 0xE0, 0xFE, 0x74, 0x01,
+0xA8, 0x06, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8,
+0xFC, 0xF4, 0x5F, 0x90, 0x82, 0xA7, 0xF0, 0x90,
+0x82, 0xA5, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07,
+0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x90,
+0x01, 0xCC, 0xF0, 0x90, 0x82, 0xA5, 0xE0, 0x04,
+0xF0, 0xE0, 0x54, 0x03, 0xF0, 0x90, 0x80, 0x9C,
+0x31, 0xA8, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF,
+0x70, 0x02, 0x01, 0x87, 0xE4, 0x90, 0x80, 0x9C,
+0xF0, 0x01, 0x87, 0x90, 0x01, 0xC0, 0xE0, 0x44,
+0x02, 0xF0, 0x90, 0x82, 0xA5, 0xE0, 0x44, 0x80,
+0x90, 0x00, 0x8A, 0x31, 0x81, 0x90, 0x01, 0xD0,
+0x12, 0x45, 0x2B, 0xE0, 0x90, 0x01, 0xC3, 0xF0,
+0x22, 0xF0, 0x90, 0x82, 0xA5, 0xE0, 0x75, 0xF0,
+0x04, 0x22, 0x12, 0x45, 0x2B, 0xE5, 0x82, 0x29,
+0xF5, 0x82, 0xE4, 0x35, 0x83, 0xF5, 0x83, 0xEF,
+0x22, 0x2F, 0xF5, 0x82, 0x74, 0x01, 0x3E, 0xF5,
+0x83, 0xE0, 0xFF, 0x90, 0x80, 0x9C, 0xE0, 0x22,
+0xE0, 0x04, 0xF0, 0xE0, 0x7F, 0x00, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFF,
+0x90, 0x81, 0x34, 0xE0, 0xFE, 0x90, 0x81, 0x33,
+0xE0, 0xFD, 0xB5, 0x06, 0x04, 0x7E, 0x01, 0x80,
+0x02, 0x7E, 0x00, 0xEE, 0x64, 0x01, 0x60, 0x41,
+0x90, 0x01, 0xAF, 0xE0, 0x70, 0x0A, 0xED, 0x51,
+0x73, 0xFA, 0x7B, 0x01, 0x51, 0xCB, 0x7F, 0x01,
+0xEF, 0x60, 0x2E, 0x90, 0x81, 0x33, 0x31, 0xA8,
+0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05,
+0xE4, 0x90, 0x81, 0x33, 0xF0, 0x90, 0x81, 0x34,
+0xE0, 0xFF, 0x90, 0x81, 0x33, 0xE0, 0xB5, 0x07,
+0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF,
+0x70, 0x07, 0x90, 0x80, 0x3C, 0xE0, 0x44, 0x04,
+0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x81, 0x33,
+0xE0, 0xFF, 0x70, 0x06, 0xA3, 0xE0, 0x64, 0x09,
+0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90, 0x81, 0x34,
+0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02,
+0x7F, 0x00, 0xEF, 0x60, 0x09, 0x90, 0x01, 0xC1,
+0xE0, 0x44, 0x02, 0xF0, 0x80, 0x28, 0xC0, 0x01,
+0x90, 0x81, 0x34, 0xE0, 0x51, 0x73, 0xA8, 0x01,
+0xFC, 0x7D, 0x01, 0xD0, 0x01, 0x7E, 0x00, 0x7F,
+0x0F, 0x12, 0x44, 0x79, 0x90, 0x81, 0x34, 0x31,
+0xA8, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60,
+0x05, 0xE4, 0x90, 0x81, 0x34, 0xF0, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0x75, 0xF0, 0x0F, 0xA4, 0x24,
+0x9D, 0xF9, 0x74, 0x80, 0x35, 0xF0, 0x22, 0x90,
+0x82, 0x46, 0x74, 0x12, 0xF0, 0x90, 0x82, 0x54,
+0x74, 0x05, 0xF0, 0x90, 0x82, 0x48, 0xEF, 0xF0,
+0xA3, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x82,
+0x44, 0xE0, 0x90, 0x82, 0x4B, 0xF0, 0x90, 0x82,
+0x45, 0xE0, 0x90, 0x82, 0x4C, 0xF0, 0x7B, 0x01,
+0x7A, 0x82, 0x79, 0x46, 0x51, 0x16, 0x7F, 0x04,
+0x90, 0x82, 0xA9, 0xEF, 0xF0, 0x7F, 0x02, 0x12,
+0x43, 0x27, 0x90, 0x80, 0x3C, 0xE0, 0xFF, 0x90,
+0x82, 0xA9, 0xE0, 0xFE, 0xEF, 0x4E, 0x90, 0x80,
+0x3C, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x82, 0x37, 0x12, 0x45, 0x40,
+0x90, 0x82, 0xA6, 0xE0, 0xFF, 0x04, 0xF0, 0x90,
+0x00, 0x01, 0xEF, 0x12, 0x1F, 0xFC, 0x7F, 0xAF,
+0x7E, 0x01, 0xD1, 0xA7, 0xEF, 0x60, 0x3A, 0x90,
+0x82, 0x37, 0x12, 0x45, 0x37, 0x8B, 0x13, 0x8A,
+0x14, 0x89, 0x15, 0x90, 0x00, 0x0E, 0x12, 0x1F,
+0xBD, 0x24, 0x02, 0xF5, 0x16, 0x7B, 0x01, 0x7A,
+0x01, 0x79, 0xA0, 0x12, 0x2B, 0xED, 0x90, 0x82,
+0x37, 0x12, 0x45, 0x37, 0x90, 0x00, 0x0E, 0x12,
+0x1F, 0xBD, 0x90, 0x01, 0xAE, 0xF0, 0xA3, 0x74,
+0xFF, 0xF0, 0x90, 0x01, 0xCB, 0xE0, 0x64, 0x80,
+0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE0, 0xFF,
+0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
+0x81, 0x48, 0xE0, 0xFE, 0xC3, 0x13, 0x30, 0xE0,
+0x1E, 0x90, 0x82, 0x64, 0x74, 0x1E, 0xF0, 0x90,
+0x82, 0x72, 0x74, 0x01, 0xF0, 0x90, 0x82, 0x66,
+0xEF, 0xF0, 0x7B, 0x01, 0x7A, 0x82, 0x79, 0x64,
+0x51, 0x16, 0x7F, 0x04, 0x12, 0x47, 0x5F, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x12, 0x55, 0x47, 0x12,
+0x4F, 0xBF, 0x7F, 0x01, 0x71, 0x38, 0x90, 0x81,
+0xB7, 0xE0, 0x30, 0xE0, 0x15, 0x71, 0xC9, 0xF0,
+0x90, 0x81, 0xBA, 0xE0, 0x60, 0x05, 0x14, 0xF0,
+0x02, 0x4E, 0x37, 0x71, 0xD1, 0xE4, 0xFF, 0x12,
+0x56, 0xB2, 0x22, 0x90, 0x81, 0xBD, 0xE0, 0x60,
+0x0F, 0xE4, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44,
+0x02, 0xF0, 0x90, 0x05, 0xFC, 0xE0, 0x04, 0xF0,
+0x90, 0x81, 0x41, 0xE0, 0x30, 0xE0, 0x10, 0xA3,
+0x74, 0x01, 0xF0, 0x90, 0x81, 0x41, 0xE0, 0xFF,
+0xC3, 0x13, 0x30, 0xE0, 0x02, 0x91, 0x13, 0x12,
+0x54, 0xA7, 0xE4, 0xFF, 0x71, 0x38, 0x02, 0x4D,
+0xDB, 0x90, 0x81, 0xB9, 0xE0, 0x90, 0x05, 0x73,
+0x22, 0x90, 0x81, 0xB8, 0xE0, 0x14, 0x90, 0x81,
+0xBA, 0xF0, 0x22, 0x12, 0x1F, 0xA4, 0xFF, 0x54,
+0x01, 0xFE, 0x90, 0x81, 0xB7, 0x91, 0x04, 0x12,
+0x65, 0xD0, 0x90, 0x81, 0xB8, 0xF0, 0x90, 0x00,
+0x02, 0x12, 0x1F, 0xBD, 0x90, 0x81, 0xB9, 0xF0,
+0x71, 0xD1, 0x90, 0x81, 0xB7, 0xE0, 0x54, 0x01,
+0xFF, 0x02, 0x56, 0xB2, 0xE0, 0x54, 0xFE, 0x4E,
+0xFE, 0xF0, 0xEF, 0x54, 0x02, 0xFF, 0xEE, 0x54,
+0xFD, 0x4F, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x12, 0x54, 0x9B, 0xBF, 0x01, 0x04,
+0x7F, 0x01, 0x80, 0x02, 0x7F, 0x02, 0x12, 0x53,
+0xA5, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x81,
+0x41, 0xE0, 0xFF, 0x30, 0xE0, 0x3E, 0x90, 0x81,
+0x45, 0xE0, 0x7E, 0x00, 0xB4, 0x02, 0x02, 0x7E,
+0x01, 0x90, 0x81, 0x44, 0xE0, 0x7D, 0x00, 0xB4,
+0x04, 0x02, 0x7D, 0x01, 0xED, 0x4E, 0x70, 0x24,
+0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x02, 0x80, 0xBB,
+0x91, 0x75, 0x90, 0x81, 0x45, 0xE0, 0xB4, 0x0C,
+0x06, 0xE4, 0xFD, 0x7F, 0x08, 0x80, 0x0A, 0x90,
+0x81, 0x45, 0xE0, 0xB4, 0x04, 0x06, 0xE4, 0xFD,
+0xFF, 0x12, 0x4B, 0x21, 0x22, 0x90, 0x01, 0x57,
+0xE0, 0x60, 0x1C, 0x12, 0x47, 0xD6, 0xF0, 0x91,
+0x98, 0x30, 0xE0, 0x03, 0x02, 0x67, 0x96, 0x91,
+0xA2, 0x40, 0x0C, 0xE4, 0xFF, 0x12, 0x47, 0x8C,
+0xBF, 0x01, 0x04, 0x12, 0x64, 0x4B, 0xF0, 0x22,
+0x90, 0x81, 0x46, 0xE0, 0xFF, 0x13, 0x13, 0x54,
+0x3F, 0x22, 0x90, 0x81, 0x54, 0xE0, 0x04, 0xF0,
+0x90, 0x81, 0x4F, 0xE0, 0x54, 0xEF, 0xF0, 0x90,
+0x81, 0xA8, 0xE0, 0xFF, 0x90, 0x81, 0x54, 0xE0,
+0xD3, 0x9F, 0x22, 0x91, 0xAF, 0x40, 0x31, 0x90,
+0x81, 0x65, 0xE0, 0x04, 0xF0, 0x90, 0x81, 0xA7,
+0xE0, 0xFF, 0x90, 0x81, 0x65, 0xE0, 0xD3, 0x9F,
+0x50, 0x1E, 0x90, 0x81, 0x5D, 0xE0, 0x04, 0xF0,
+0x12, 0x49, 0xB5, 0x90, 0x81, 0x64, 0xF0, 0xFB,
+0x90, 0x81, 0x5D, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD,
+0x90, 0x82, 0x9D, 0x74, 0x04, 0xF0, 0x91, 0xF1,
+0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0xAC, 0x07, 0x90, 0x81, 0x47, 0xE0, 0x12, 0x67,
+0x7E, 0x30, 0xE0, 0x02, 0xA1, 0xAD, 0x90, 0x81,
+0x46, 0xE0, 0x30, 0xE0, 0x16, 0x90, 0x81, 0x68,
+0xE0, 0x24, 0x04, 0x90, 0x81, 0x60, 0xF0, 0x90,
+0x81, 0x68, 0xE0, 0x24, 0x03, 0x90, 0x81, 0x5F,
+0xF0, 0x80, 0x0D, 0x90, 0x81, 0x60, 0x74, 0x02,
+0xF0, 0x90, 0x81, 0x5F, 0x14, 0xF0, 0x0B, 0x0B,
+0x90, 0x81, 0x5F, 0xE0, 0xFA, 0x90, 0x81, 0x5E,
+0xE0, 0xD3, 0x9A, 0x50, 0x0E, 0x90, 0x81, 0x53,
+0xEB, 0xF0, 0x90, 0x81, 0x60, 0xE0, 0xC3, 0x9D,
+0x2C, 0x80, 0x11, 0xC3, 0xED, 0x9A, 0x2B, 0x90,
+0x81, 0x53, 0xF0, 0x90, 0x81, 0x5F, 0xE0, 0xFF,
+0xA3, 0xE0, 0xC3, 0x9F, 0x90, 0x81, 0x63, 0xF0,
+0x90, 0x81, 0x60, 0xE0, 0xFF, 0x24, 0x0A, 0xFD,
+0xE4, 0x33, 0xFC, 0x90, 0x81, 0x63, 0xB1, 0xB9,
+0x98, 0x40, 0x04, 0xEF, 0x24, 0x0A, 0xF0, 0x90,
+0x81, 0x63, 0xE0, 0xFF, 0x24, 0x23, 0xFD, 0xE4,
+0x33, 0xFC, 0x90, 0x81, 0x53, 0xB1, 0xB9, 0x98,
+0x40, 0x04, 0xEF, 0x24, 0x23, 0xF0, 0x90, 0x81,
+0x63, 0xE0, 0xFF, 0x7E, 0x00, 0x90, 0x81, 0x57,
+0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x05, 0x58,
+0xE0, 0x6F, 0x70, 0x01, 0xE4, 0x60, 0x02, 0xD1,
+0x15, 0xD1, 0x0C, 0x80, 0x07, 0x90, 0x81, 0x48,
+0xE0, 0x44, 0x01, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0xE0, 0xD3, 0x9D, 0xEC, 0x64, 0x80, 0xF8,
+0x74, 0x80, 0x22, 0xD1, 0x1F, 0x90, 0x81, 0xC4,
+0xEF, 0xF0, 0x30, 0xE0, 0x05, 0x7D, 0x01, 0xE4,
+0x80, 0x02, 0xE4, 0xFD, 0xFF, 0x12, 0x49, 0xCE,
+0x90, 0x81, 0xC4, 0xE0, 0x30, 0xE6, 0x11, 0x90,
+0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x04, 0xE4, 0xF0,
+0x80, 0x06, 0x90, 0x01, 0x2F, 0x74, 0x80, 0xF0,
+0x90, 0x81, 0x46, 0xE0, 0x90, 0x04, 0xEC, 0x30,
+0xE0, 0x06, 0xE0, 0x54, 0xDD, 0xF0, 0x80, 0x04,
+0xE0, 0x44, 0x22, 0xF0, 0x12, 0x67, 0xB0, 0x74,
+0x02, 0xF0, 0x81, 0xF1, 0x90, 0x81, 0x48, 0xE0,
+0x54, 0xFE, 0xF0, 0x22, 0xF0, 0x90, 0x81, 0x57,
+0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0, 0x22, 0xE4,
+0x90, 0x81, 0xC6, 0xF0, 0xA3, 0xF0, 0x90, 0x00,
+0x83, 0xE0, 0x90, 0x81, 0xC5, 0xF0, 0x90, 0x00,
+0x83, 0xE0, 0xFE, 0x90, 0x81, 0xC5, 0xE0, 0xFF,
+0xB5, 0x06, 0x01, 0x22, 0xC3, 0x90, 0x81, 0xC7,
+0xE0, 0x94, 0x64, 0x90, 0x81, 0xC6, 0xE0, 0x94,
+0x00, 0x40, 0x0D, 0x90, 0x01, 0xC0, 0xE0, 0x44,
+0x40, 0xF0, 0x90, 0x81, 0xC5, 0xE0, 0xFF, 0x22,
+0x90, 0x81, 0xC6, 0x12, 0x5E, 0x53, 0x80, 0xC6,
+0x90, 0x81, 0x41, 0xE0, 0xFF, 0x30, 0xE0, 0x3E,
+0x90, 0x81, 0x45, 0xE0, 0x7E, 0x00, 0xB4, 0x02,
+0x02, 0x7E, 0x01, 0x90, 0x81, 0x44, 0xE0, 0x7D,
+0x00, 0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED, 0x4E,
+0x70, 0x24, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x02,
+0x81, 0x13, 0x12, 0x57, 0x77, 0x90, 0x81, 0x45,
+0xE0, 0xB4, 0x08, 0x06, 0xE4, 0xFD, 0x7F, 0x0C,
+0x80, 0x09, 0x90, 0x81, 0x45, 0xE0, 0x70, 0x06,
+0xFD, 0x7F, 0x04, 0x12, 0x4B, 0x21, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x82,
+0x8E, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xA3,
+0xF0, 0xA3, 0xF0, 0x90, 0x82, 0x8E, 0xE0, 0xFE,
+0xA3, 0xE0, 0xF5, 0x82, 0x8E, 0x83, 0xE0, 0x60,
+0x29, 0xC3, 0x90, 0x82, 0x91, 0xE0, 0x94, 0xE8,
+0x90, 0x82, 0x90, 0xE0, 0x94, 0x03, 0x40, 0x0B,
+0x90, 0x01, 0xC0, 0xE0, 0x44, 0x80, 0xF0, 0x7F,
+0x00, 0x80, 0x11, 0x90, 0x82, 0x90, 0x12, 0x5E,
+0x53, 0x7F, 0x0A, 0x7E, 0x00, 0x12, 0x32, 0xAA,
+0x80, 0xC9, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x7B, 0x01, 0x7A, 0x82, 0x79, 0x3B, 0x7F,
+0xF5, 0x7E, 0x00, 0x12, 0x2B, 0x27, 0xBF, 0x01,
+0x06, 0x90, 0x82, 0x3B, 0xE0, 0xA3, 0xF0, 0x7B,
+0x01, 0x7A, 0x82, 0x79, 0x3B, 0x7F, 0xF6, 0x7E,
+0x00, 0x12, 0x2B, 0x27, 0xBF, 0x01, 0x08, 0x90,
+0x82, 0x3B, 0xE0, 0x90, 0x82, 0x3D, 0xF0, 0x7B,
+0x01, 0x7A, 0x82, 0x79, 0x3B, 0x7F, 0xF4, 0x7E,
+0x00, 0x12, 0x2B, 0x27, 0xBF, 0x01, 0x08, 0x90,
+0x82, 0x3B, 0xE0, 0x90, 0x82, 0x3E, 0xF0, 0x7B,
+0x01, 0x7A, 0x82, 0x79, 0x3B, 0x7F, 0xF3, 0x7E,
+0x00, 0x12, 0x2B, 0x27, 0xBF, 0x01, 0x08, 0x90,
+0x82, 0x3B, 0xE0, 0x90, 0x82, 0x3F, 0xF0, 0x7B,
+0x01, 0x7A, 0x82, 0x79, 0x3B, 0x7F, 0xF2, 0x7E,
+0x00, 0x12, 0x2B, 0x27, 0xBF, 0x01, 0x08, 0x90,
+0x82, 0x3B, 0xE0, 0x90, 0x82, 0x40, 0xF0, 0x90,
+0x82, 0x3C, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0xA3,
+0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x82, 0x44, 0xF0,
+0x90, 0x82, 0x40, 0xE0, 0x90, 0x82, 0x45, 0xF0,
+0x41, 0x7F, 0x12, 0x1F, 0xA4, 0xFF, 0x90, 0x81,
+0x37, 0xF0, 0xBF, 0x01, 0x07, 0xD1, 0xF9, 0xE4,
+0x90, 0x81, 0x37, 0xF0, 0x22, 0xE4, 0x90, 0x81,
+0xE3, 0xF0, 0x90, 0x87, 0x5F, 0xE0, 0x90, 0x81,
+0xE2, 0xF0, 0xE4, 0x90, 0x81, 0xEF, 0xF0, 0x90,
+0x81, 0xDF, 0xF0, 0x90, 0x81, 0xDF, 0xE0, 0xFF,
+0xC3, 0x94, 0x40, 0x50, 0x11, 0x74, 0xF2, 0x2F,
+0x12, 0x72, 0xC2, 0x74, 0xFF, 0xF0, 0x90, 0x81,
+0xDF, 0xE0, 0x04, 0xF0, 0x80, 0xE5, 0xE4, 0x90,
+0x81, 0xDF, 0xF0, 0x90, 0x81, 0xE2, 0xE0, 0xFF,
+0x90, 0x81, 0xDF, 0xE0, 0xFE, 0xC3, 0x9F, 0x40,
+0x03, 0x02, 0x70, 0xA1, 0x74, 0xDF, 0x2E, 0xF9,
+0xE4, 0x34, 0x86, 0x12, 0x72, 0x99, 0x75, 0x16,
+0x0A, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0xD4, 0x12,
+0x2B, 0xED, 0x90, 0x81, 0xD5, 0xE0, 0xFF, 0x12,
+0x2F, 0x27, 0xEF, 0x04, 0x90, 0x81, 0xEF, 0xF0,
+0x90, 0x81, 0xD4, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD,
+0x12, 0x31, 0xEA, 0xEF, 0x24, 0xC8, 0x90, 0x81,
+0xF1, 0xF0, 0x75, 0xF0, 0x08, 0xA4, 0xF0, 0x90,
+0x81, 0xD5, 0xE0, 0x54, 0x0F, 0x90, 0x81, 0xF0,
+0xF0, 0xE4, 0x90, 0x81, 0xDE, 0xF0, 0x90, 0x81,
+0xE0, 0xF0, 0x90, 0x81, 0xE0, 0xE0, 0xFF, 0xC3,
+0x94, 0x04, 0x50, 0x57, 0x90, 0x81, 0xF0, 0xE0,
+0xFE, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x13,
+0xD8, 0xFC, 0x20, 0xE0, 0x3E, 0x90, 0x81, 0xE0,
+0xE0, 0x25, 0xE0, 0xFF, 0x90, 0x81, 0xF1, 0xE0,
+0x2F, 0x24, 0xF2, 0xF9, 0xE4, 0x34, 0x81, 0xFA,
+0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x01, 0x90, 0x81,
+0xDE, 0xE0, 0x75, 0xF0, 0x02, 0xA4, 0x24, 0xD6,
+0xF9, 0x74, 0x81, 0x35, 0xF0, 0x8B, 0x13, 0xF5,
+0x14, 0x89, 0x15, 0x75, 0x16, 0x02, 0xD0, 0x01,
+0xD0, 0x03, 0x12, 0x2B, 0xED, 0x90, 0x81, 0xDE,
+0xE0, 0x04, 0xF0, 0x90, 0x81, 0xE0, 0xE0, 0x04,
+0xF0, 0x80, 0x9F, 0x90, 0x81, 0xEF, 0xE0, 0xFF,
+0x90, 0x81, 0xDF, 0xE0, 0x2F, 0xF0, 0x02, 0x6F,
+0xD3, 0xE4, 0x90, 0x81, 0xE3, 0xF0, 0x90, 0x81,
+0xE3, 0xE0, 0xC3, 0x94, 0x40, 0x40, 0x02, 0x41,
+0x64, 0xE0, 0xFF, 0x24, 0xF2, 0x51, 0xC2, 0xE0,
+0x90, 0x81, 0xE5, 0xF0, 0xE0, 0xFE, 0x54, 0xF0,
+0xC4, 0x54, 0x0F, 0xFD, 0x90, 0x81, 0xE4, 0xF0,
+0xEE, 0x54, 0x0F, 0xFE, 0xA3, 0xF0, 0x74, 0xF3,
+0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83,
+0xE0, 0x90, 0x81, 0xE6, 0xF0, 0xFC, 0xEE, 0xFE,
+0xEC, 0xFB, 0xEB, 0xFF, 0x90, 0x81, 0xEB, 0xEE,
+0xF0, 0xA3, 0xEF, 0xF0, 0xED, 0x12, 0x45, 0x49,
+0x71, 0x15, 0x00, 0x71, 0x40, 0x01, 0x71, 0xBB,
+0x02, 0x72, 0x55, 0x03, 0x71, 0xCB, 0x04, 0x71,
+0xE1, 0x05, 0x71, 0xE1, 0x06, 0x71, 0xE1, 0x07,
+0x71, 0xE1, 0x08, 0x72, 0x32, 0x09, 0x72, 0x43,
+0x0A, 0x00, 0x00, 0x72, 0x64, 0x90, 0x81, 0xE3,
+0xE0, 0xFD, 0x51, 0x84, 0xE0, 0xFE, 0x74, 0xF4,
+0x2D, 0x51, 0x78, 0xE0, 0xFD, 0xED, 0xFF, 0x90,
+0x81, 0xED, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF, 0xF0,
+0x90, 0x81, 0xE6, 0xE0, 0xFF, 0x12, 0x2F, 0x96,
+0x90, 0x81, 0xE1, 0x74, 0x02, 0xF0, 0x41, 0x55,
+0x51, 0x80, 0x12, 0x55, 0x40, 0x51, 0x65, 0x12,
+0x55, 0x40, 0x12, 0x44, 0xD0, 0xC0, 0x04, 0xC0,
+0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x81, 0xE3,
+0xE0, 0x24, 0xF6, 0xF5, 0x82, 0xE4, 0x34, 0x81,
+0xF5, 0x83, 0x12, 0x55, 0x40, 0x78, 0x10, 0x12,
+0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01,
+0xD0, 0x00, 0x12, 0x44, 0xD0, 0xC0, 0x04, 0xC0,
+0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x81, 0xE3,
+0xE0, 0x24, 0xF7, 0xF5, 0x82, 0xE4, 0x34, 0x81,
+0xF5, 0x83, 0x12, 0x55, 0x40, 0x78, 0x18, 0x12,
+0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01,
+0xD0, 0x00, 0x51, 0xA1, 0x90, 0x81, 0xE7, 0x12,
+0x44, 0xEE, 0x90, 0x85, 0x96, 0x12, 0x20, 0xCE,
+0x90, 0x81, 0xEB, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
+0x12, 0x2E, 0xE4, 0x90, 0x81, 0xE1, 0x74, 0x04,
+0xF0, 0x41, 0x55, 0x90, 0x81, 0xE6, 0xE0, 0xFD,
+0x51, 0x72, 0xE0, 0xFB, 0xE4, 0xFF, 0x12, 0x30,
+0xC7, 0x80, 0x0E, 0x90, 0x81, 0xE6, 0xE0, 0xFD,
+0x51, 0x72, 0xE0, 0xFB, 0xE4, 0xFF, 0x12, 0x30,
+0x6A, 0x90, 0x81, 0xE1, 0x74, 0x01, 0xF0, 0x80,
+0x74, 0x90, 0x81, 0xE1, 0x74, 0x02, 0xF0, 0x51,
+0x80, 0x12, 0x55, 0x40, 0x51, 0x65, 0x12, 0x55,
+0x40, 0x12, 0x44, 0xD0, 0xC0, 0x04, 0xC0, 0x05,
+0xC0, 0x06, 0xC0, 0x07, 0x90, 0x81, 0xE5, 0x12,
+0x55, 0x40, 0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x51,
+0xA1, 0x90, 0x81, 0xE4, 0xE0, 0x24, 0xFB, 0xFF,
+0xC0, 0x07, 0x90, 0x81, 0xE7, 0x12, 0x44, 0xEE,
+0x90, 0x82, 0x7F, 0x12, 0x20, 0xCE, 0x90, 0x81,
+0xE6, 0xE0, 0xFD, 0xD0, 0x07, 0x12, 0x5D, 0xB7,
+0x80, 0x23, 0x90, 0x81, 0xE1, 0x74, 0x01, 0x51,
+0x8E, 0x75, 0x16, 0x01, 0x51, 0xAA, 0xF0, 0x7B,
+0x04, 0x80, 0x0F, 0x90, 0x81, 0xE1, 0x74, 0x04,
+0x51, 0x8E, 0x75, 0x16, 0x04, 0x51, 0xAA, 0xF0,
+0x7B, 0x06, 0x12, 0x5A, 0x00, 0x90, 0x81, 0xE1,
+0xE0, 0x24, 0x02, 0xFF, 0x90, 0x81, 0xE3, 0xE0,
+0x2F, 0xF0, 0x01, 0xA6, 0x22, 0x78, 0x08, 0x12,
+0x20, 0xBB, 0xA8, 0x04, 0xA9, 0x05, 0xAA, 0x06,
+0xAB, 0x07, 0x90, 0x81, 0xE3, 0xE0, 0x24, 0xF4,
+0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0x22,
+0x90, 0x81, 0xE3, 0xE0, 0x24, 0xF5, 0xF5, 0x82,
+0xE4, 0x34, 0x81, 0xF5, 0x83, 0x22, 0xF0, 0x90,
+0x81, 0xE3, 0xE0, 0x24, 0xF4, 0xF9, 0xE4, 0x34,
+0x81, 0x75, 0x13, 0x01, 0xF5, 0x14, 0x89, 0x15,
+0x22, 0x12, 0x44, 0xD0, 0x90, 0x81, 0xE7, 0x02,
+0x20, 0xCE, 0x7B, 0xFE, 0x7A, 0x80, 0x79, 0x33,
+0x12, 0x2B, 0xED, 0x90, 0x81, 0xE6, 0xE0, 0xFF,
+0x90, 0x81, 0xE5, 0xE0, 0xFD, 0xE4, 0x90, 0x82,
+0x35, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5,
+0x83, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x12, 0x2D, 0xA7, 0xE4, 0xF5, 0x53, 0x12,
+0x32, 0x9E, 0xEF, 0x60, 0x73, 0x63, 0x53, 0x01,
+0xE5, 0x53, 0x24, 0xCA, 0x90, 0x01, 0xC4, 0xF0,
+0x74, 0x72, 0xA3, 0xF0, 0x90, 0x00, 0x88, 0xE0,
+0xF5, 0x51, 0xF5, 0x52, 0x54, 0x0F, 0x60, 0xDF,
+0xE5, 0x51, 0x30, 0xE0, 0x0B, 0x20, 0xE4, 0x03,
+0x12, 0x29, 0xC5, 0x53, 0x52, 0xEE, 0x80, 0x3F,
+0xE5, 0x51, 0x30, 0xE1, 0x16, 0x20, 0xE5, 0x0E,
+0x12, 0x11, 0xBD, 0xEF, 0x70, 0x03, 0x43, 0x52,
+0x20, 0x90, 0x01, 0x06, 0xE4, 0xF0, 0x53, 0x52,
+0xFD, 0x80, 0x24, 0xE5, 0x51, 0x30, 0xE2, 0x0B,
+0x20, 0xE6, 0x03, 0x12, 0x6F, 0x9D, 0x53, 0x52,
+0xFB, 0x80, 0x14, 0xE5, 0x51, 0x30, 0xE3, 0x0F,
+0x20, 0xE7, 0x09, 0x12, 0x5B, 0x31, 0xEF, 0x70,
+0x03, 0x43, 0x52, 0x80, 0x53, 0x52, 0xF7, 0xAD,
+0x52, 0x7F, 0x88, 0x12, 0x32, 0x1E, 0x80, 0x87,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x02, 0x09,
+0xE0, 0xF5, 0x54, 0x12, 0x1F, 0xA4, 0x25, 0x54,
+0x90, 0x80, 0x44, 0x12, 0x65, 0xD0, 0x25, 0x54,
+0x90, 0x80, 0x45, 0xF0, 0x90, 0x00, 0x02, 0x12,
+0x1F, 0xBD, 0x25, 0x54, 0x90, 0x80, 0x46, 0x71,
+0xA6, 0x25, 0x54, 0x90, 0x80, 0x47, 0x71, 0x9F,
+0x25, 0x54, 0x90, 0x80, 0x48, 0xF0, 0x90, 0x00,
+0x05, 0x12, 0x1F, 0xBD, 0x25, 0x54, 0x90, 0x80,
+0x49, 0xF0, 0x90, 0x00, 0x06, 0x12, 0x1F, 0xBD,
+0x25, 0x54, 0x90, 0x80, 0x4A, 0xF0, 0x22, 0xF0,
+0x90, 0x00, 0x04, 0x02, 0x1F, 0xBD, 0xF0, 0x90,
+0x00, 0x03, 0x02, 0x1F, 0xBD, 0x8B, 0x54, 0x8A,
+0x55, 0x89, 0x56, 0x12, 0x65, 0xD1, 0xFF, 0xF5,
+0x58, 0x12, 0x1F, 0xA4, 0xFE, 0xC3, 0x13, 0x30,
+0xE0, 0x0A, 0x90, 0x00, 0x02, 0x12, 0x1F, 0xBD,
+0xF5, 0x59, 0x80, 0x02, 0x8F, 0x59, 0x85, 0x58,
+0x57, 0xE5, 0x57, 0xD3, 0x95, 0x59, 0x50, 0x1E,
+0x91, 0x1A, 0x54, 0x01, 0xFD, 0xAF, 0x57, 0x12,
+0x51, 0x7A, 0xAF, 0x57, 0x12, 0x47, 0x8C, 0xEF,
+0xAF, 0x57, 0x70, 0x04, 0x91, 0x11, 0x80, 0x02,
+0x91, 0x10, 0x05, 0x57, 0x80, 0xDB, 0xE5, 0x58,
+0x70, 0x15, 0xFF, 0x12, 0x47, 0x8C, 0xEF, 0x70,
+0x0E, 0x12, 0x4D, 0x77, 0x12, 0x4D, 0x61, 0x91,
+0x12, 0x54, 0xBF, 0xF0, 0x54, 0x7F, 0xF0, 0x22,
+0x22, 0x22, 0x90, 0x81, 0x46, 0xE0, 0x54, 0xF7,
+0xF0, 0x22, 0xAB, 0x54, 0xAA, 0x55, 0xA9, 0x56,
+0x02, 0x1F, 0xA4, 0x12, 0x1F, 0xA4, 0x54, 0x01,
+0xFF, 0x90, 0x81, 0xBE, 0xE0, 0x54, 0xFE, 0x4F,
+0xF0, 0x22, 0x12, 0x1F, 0xA4, 0x90, 0x81, 0xAE,
+0xF0, 0x22, 0xE4, 0x90, 0x81, 0x33, 0xF0, 0xA3,
+0xF0, 0x90, 0x80, 0x9B, 0xF0, 0xA3, 0xF0, 0x22,
+0x90, 0x01, 0x94, 0xE0, 0x44, 0x01, 0xF0, 0x90,
+0x01, 0xC7, 0xE4, 0xF0, 0x22, 0x90, 0x01, 0x01,
+0xE0, 0x44, 0x04, 0xF0, 0x90, 0x01, 0x9C, 0x74,
+0x7E, 0xF0, 0xA3, 0x74, 0x92, 0xF0, 0xA3, 0x74,
+0xA0, 0xF0, 0xA3, 0x74, 0x24, 0xF0, 0x90, 0x01,
+0x9B, 0x74, 0x49, 0xF0, 0x90, 0x01, 0x9A, 0x74,
+0xE0, 0xF0, 0x90, 0x01, 0x99, 0xE4, 0xF0, 0x90,
+0x01, 0x98, 0x04, 0xF0, 0x22, 0xE4, 0x90, 0x81,
+0xC8, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x98, 0xE0,
+0x7F, 0x00, 0x30, 0xE4, 0x02, 0x7F, 0x01, 0xEF,
+0x64, 0x01, 0x60, 0x3D, 0xC3, 0x90, 0x81, 0xC9,
+0xE0, 0x94, 0x88, 0x90, 0x81, 0xC8, 0xE0, 0x94,
+0x13, 0x40, 0x0F, 0x90, 0x01, 0xC1, 0xE0, 0x44,
+0x10, 0xF0, 0x90, 0x01, 0xC7, 0x74, 0xFD, 0xF0,
+0x80, 0x1F, 0x90, 0x81, 0xC8, 0x12, 0x5E, 0x53,
+0x12, 0x67, 0xD0, 0xD3, 0x90, 0x81, 0xC9, 0xE0,
+0x94, 0x32, 0x90, 0x81, 0xC8, 0xE0, 0x94, 0x00,
+0x40, 0xBA, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE3,
+0xB3, 0x90, 0x01, 0xC7, 0x74, 0xFE, 0xF0, 0x22,
+0x7F, 0x02, 0x90, 0x81, 0xBB, 0xE0, 0xFE, 0xEF,
+0xC3, 0x9E, 0x50, 0x18, 0xEF, 0x25, 0xE0, 0x24,
+0x81, 0xF8, 0xE6, 0x30, 0xE4, 0x0B, 0x90, 0x01,
+0xB8, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x7F, 0x00,
+0x22, 0x0F, 0x80, 0xDE, 0x7F, 0x01, 0x22, 0x90,
+0x01, 0xE4, 0x74, 0x1C, 0xF0, 0xA3, 0xE4, 0xF0,
+0x22, 0x90, 0x01, 0x34, 0xE0, 0x55, 0x3D, 0xF5,
+0x41, 0xA3, 0xE0, 0x55, 0x3E, 0xF5, 0x42, 0xA3,
+0xE0, 0x55, 0x3F, 0xF5, 0x43, 0xA3, 0xE0, 0x55,
+0x40, 0xF5, 0x44, 0x90, 0x01, 0x34, 0xE5, 0x41,
+0xF0, 0xA3, 0xE5, 0x42, 0xF0, 0xA3, 0xE5, 0x43,
+0xF0, 0xA3, 0xE5, 0x44, 0xF0, 0x22, 0x90, 0x01,
+0x3C, 0xE0, 0x55, 0x45, 0xF5, 0x49, 0xA3, 0xE0,
+0x55, 0x46, 0xF5, 0x4A, 0xA3, 0xE0, 0x55, 0x47,
+0xF5, 0x4B, 0xA3, 0xE0, 0x55, 0x48, 0xF5, 0x4C,
+0x90, 0x01, 0x3C, 0xE5, 0x49, 0xF0, 0xA3, 0xE5,
+0x4A, 0xF0, 0xA3, 0xE5, 0x4B, 0xF0, 0xA3, 0xE5,
+0x4C, 0xF0, 0x53, 0x91, 0xDF, 0x22, 0x90, 0x81,
+0x41, 0xE0, 0x30, 0xE0, 0x05, 0xE4, 0xA3, 0xF0,
+0xA3, 0xF0, 0x22, 0x90, 0x81, 0x41, 0xE0, 0xFF,
+0x30, 0xE0, 0x05, 0x12, 0x57, 0x70, 0x60, 0x15,
+0x90, 0x81, 0x4B, 0xE0, 0x70, 0x04, 0xEF, 0x30,
+0xE0, 0x0B, 0x90, 0x81, 0x4E, 0xE0, 0x64, 0x02,
+0x60, 0x03, 0x12, 0x64, 0xC5, 0x22, 0xE4, 0xFF,
+0x12, 0x47, 0x8C, 0xBF, 0x01, 0x13, 0x90, 0x81,
+0x4B, 0xE0, 0x60, 0x0D, 0x12, 0x63, 0x36, 0x64,
+0x02, 0x60, 0x03, 0x02, 0x5F, 0xA9, 0x12, 0x4F,
+0x80, 0x22, 0x90, 0x81, 0x4B, 0xE0, 0x70, 0x07,
+0x90, 0x81, 0x41, 0xE0, 0x30, 0xE0, 0x12, 0x90,
+0x81, 0x41, 0xE0, 0x30, 0xE0, 0x08, 0x12, 0x54,
+0x9B, 0xBF, 0x01, 0x05, 0x80, 0x04, 0x12, 0x63,
+0x05, 0x22, 0x90, 0x81, 0x4B, 0xE0, 0x64, 0x02,
+0x60, 0x0D, 0x12, 0x63, 0x36, 0x60, 0x08, 0xB1,
+0xF0, 0xEF, 0x70, 0x03, 0x12, 0x4B, 0x1E, 0x22,
+0x90, 0x04, 0x1A, 0xE0, 0xF4, 0x60, 0x03, 0x7F,
+0x00, 0x22, 0x90, 0x04, 0x1B, 0xE0, 0x54, 0x07,
+0x64, 0x07, 0x7F, 0x01, 0x60, 0x02, 0x7F, 0x00,
+0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0xB1, 0xF0, 0xEF, 0x64, 0x01, 0x60, 0x05, 0x75,
+0x0D, 0x01, 0x80, 0x43, 0x90, 0x81, 0x4F, 0xE0,
+0xFF, 0x54, 0x03, 0x60, 0x05, 0x75, 0x0D, 0x02,
+0x80, 0x35, 0xEF, 0x30, 0xE2, 0x05, 0x75, 0x0D,
+0x08, 0x80, 0x2C, 0x90, 0x81, 0x4F, 0xE0, 0x30,
+0xE4, 0x05, 0x75, 0x0D, 0x10, 0x80, 0x20, 0x12,
+0x65, 0xB9, 0x54, 0x3F, 0x20, 0xE0, 0x05, 0x75,
+0x0D, 0x20, 0x80, 0x13, 0xD1, 0x7A, 0x8F, 0x0E,
+0xE5, 0x0E, 0x64, 0x01, 0x60, 0x05, 0x85, 0x0E,
+0x0D, 0x80, 0x04, 0xD1, 0x72, 0x80, 0x0E, 0x90,
+0x01, 0xB9, 0x74, 0x04, 0xF0, 0x90, 0x01, 0xB8,
+0xE5, 0x0D, 0xF0, 0x7F, 0x00, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0x90, 0x01, 0xB8, 0xE4, 0xF0, 0x7F,
+0x01, 0x22, 0x90, 0x81, 0x4D, 0xE0, 0xD3, 0x94,
+0x00, 0x40, 0x06, 0x75, 0x58, 0x04, 0x7F, 0xFF,
+0x22, 0x90, 0x81, 0xAE, 0xE0, 0x60, 0x06, 0x75,
+0x58, 0x80, 0x7F, 0xFF, 0x22, 0x7F, 0x01, 0x22,
+0x90, 0x81, 0xB7, 0xE0, 0xC3, 0x13, 0x20, 0xE0,
+0x35, 0x90, 0x02, 0x87, 0xE0, 0x60, 0x02, 0x80,
+0x08, 0x90, 0x01, 0x00, 0xE0, 0x64, 0x3F, 0x60,
+0x05, 0x75, 0x51, 0x01, 0x80, 0x22, 0x90, 0x02,
+0x96, 0xE0, 0x60, 0x05, 0x75, 0x51, 0x10, 0x80,
+0x17, 0x90, 0x02, 0x86, 0xE0, 0x20, 0xE1, 0x02,
+0x80, 0x07, 0x90, 0x02, 0x86, 0xE0, 0x30, 0xE3,
+0x05, 0x75, 0x51, 0x04, 0x80, 0x02, 0x80, 0x9A,
+0x90, 0x01, 0xB9, 0x74, 0x08, 0xF0, 0x90, 0x01,
+0xB8, 0xE5, 0x51, 0xF0, 0x7F, 0x00, 0x22, 0x90,
+0x81, 0xBC, 0xE0, 0x60, 0x0F, 0xE4, 0xF0, 0x90,
+0x05, 0x53, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x05,
+0xFD, 0xE0, 0x04, 0xF0, 0x22, 0x90, 0x01, 0xC4,
+0x74, 0xFD, 0xF0, 0x74, 0x76, 0xA3, 0xF0, 0x90,
+0x00, 0x90, 0xE0, 0x20, 0xE0, 0xF9, 0x74, 0xFD,
+0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x76, 0xA3,
+0xF0, 0x22, 0x90, 0x81, 0x56, 0xE0, 0xFD, 0x7F,
+0x93, 0x12, 0x32, 0x1E, 0x90, 0x81, 0x4C, 0xE0,
+0x60, 0x12, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7,
+0x05, 0x74, 0x10, 0xF0, 0x80, 0x06, 0x90, 0x01,
+0x2F, 0x74, 0x90, 0xF0, 0x90, 0x00, 0x08, 0xE0,
+0x44, 0x10, 0xFD, 0x7F, 0x08, 0x12, 0x32, 0x1E,
+0x7F, 0x01, 0x12, 0x62, 0x1C, 0x90, 0x81, 0x56,
+0xE0, 0x20, 0xE0, 0x0C, 0x90, 0x00, 0x26, 0xE0,
+0x44, 0x80, 0xFD, 0x7F, 0x26, 0x12, 0x32, 0x1E,
+0x90, 0x00, 0x90, 0xE0, 0x44, 0x01, 0xFD, 0x7F,
+0x90, 0x12, 0x32, 0x1E, 0x7F, 0x14, 0x7E, 0x00,
+0x02, 0x32, 0xAA, 0x90, 0x81, 0x46, 0xE0, 0x54,
+0xFB, 0xF0, 0xE4, 0x90, 0x81, 0x54, 0xF0, 0xA3,
+0xF0, 0x90, 0x81, 0x4F, 0xF0, 0x90, 0x81, 0x47,
+0xE0, 0x54, 0xF7, 0xF0, 0x54, 0xBF, 0xF0, 0x12,
+0x4F, 0xB9, 0x7D, 0x10, 0x7F, 0x03, 0x02, 0x56,
+0xFD, 0xEF, 0x24, 0xFE, 0x60, 0x0B, 0x04, 0x70,
+0x24, 0x90, 0x81, 0x51, 0x74, 0x02, 0xF0, 0x80,
+0x13, 0xED, 0x70, 0x06, 0x90, 0x81, 0xAB, 0xE0,
+0x80, 0x02, 0xED, 0x14, 0x90, 0x81, 0x51, 0xF0,
+0x90, 0x81, 0x51, 0xE0, 0xA3, 0xF0, 0x90, 0x81,
+0x47, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x7B, 0x2E,
+0x12, 0x7B, 0x55, 0x7D, 0x02, 0x7F, 0x01, 0x12,
+0x49, 0xCE, 0x12, 0x7B, 0x5C, 0x90, 0x81, 0x45,
+0x74, 0x02, 0xF0, 0x22, 0x90, 0x81, 0xA2, 0x74,
+0x04, 0xF0, 0xA3, 0x14, 0xF0, 0xA3, 0xE4, 0xF0,
+0xA3, 0x74, 0x64, 0xF0, 0xA3, 0x74, 0x01, 0xF0,
+0xA3, 0x74, 0x05, 0xF0, 0x22, 0x12, 0x55, 0x27,
+0x12, 0x44, 0xD0, 0xC0, 0x04, 0xC0, 0x05, 0xC0,
+0x06, 0xC0, 0x07, 0x90, 0x05, 0x62, 0x12, 0x55,
+0x40, 0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0, 0x03,
+0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x44,
+0xD0, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0,
+0x07, 0xA3, 0x12, 0x55, 0x40, 0x78, 0x18, 0x12,
+0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01,
+0xD0, 0x00, 0x12, 0x44, 0xD0, 0x90, 0x81, 0x9A,
+0x12, 0x20, 0xCE, 0x90, 0x81, 0x9E, 0x12, 0x44,
+0xEE, 0x90, 0x81, 0x9A, 0x12, 0x45, 0x06, 0xC3,
+0x12, 0x44, 0xDD, 0x40, 0x44, 0x90, 0x81, 0x46,
+0xE0, 0x90, 0x81, 0x9E, 0x30, 0xE0, 0x0F, 0x31,
+0x6E, 0x90, 0x81, 0x68, 0xE0, 0x24, 0x04, 0x2F,
+0xFF, 0x90, 0x81, 0xA2, 0x80, 0x05, 0x31, 0x6E,
+0x90, 0x81, 0xA3, 0xE0, 0xFE, 0xC3, 0xEF, 0x9E,
+0x90, 0x81, 0xC1, 0xF0, 0x90, 0x81, 0xC1, 0xE0,
+0xFF, 0xC3, 0x94, 0x2D, 0x50, 0x13, 0x74, 0x69,
+0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83,
+0xE0, 0x04, 0xF0, 0x90, 0x81, 0x61, 0xE0, 0x04,
+0xF0, 0x90, 0x81, 0x61, 0xE0, 0xFF, 0xD3, 0x90,
+0x81, 0xA5, 0xE0, 0x9F, 0x90, 0x81, 0xA4, 0xE0,
+0x94, 0x00, 0x40, 0x02, 0x21, 0x52, 0xE4, 0xFF,
+0xFE, 0x31, 0x5B, 0xEF, 0xD3, 0x9D, 0x40, 0x07,
+0x90, 0x81, 0xC2, 0xEE, 0xF0, 0x80, 0x05, 0x0E,
+0xEE, 0xB4, 0x2D, 0xED, 0xE4, 0xFF, 0xFE, 0x31,
+0x5B, 0xC3, 0x90, 0x81, 0xA5, 0xE0, 0x9D, 0xFD,
+0x90, 0x81, 0xA4, 0xE0, 0x94, 0x00, 0xFC, 0xEF,
+0xD3, 0x9D, 0xE4, 0x9C, 0x40, 0x07, 0x90, 0x81,
+0xC3, 0xEE, 0xF0, 0x80, 0x05, 0x0E, 0xEE, 0xB4,
+0x2D, 0xDD, 0x90, 0x81, 0xC2, 0xE0, 0x90, 0x81,
+0x66, 0xF0, 0x90, 0x81, 0xC3, 0xE0, 0x90, 0x81,
+0x67, 0x31, 0x53, 0x94, 0x0A, 0x40, 0x0A, 0xEF,
+0x24, 0xF6, 0x90, 0x81, 0x5E, 0xF0, 0xE4, 0x80,
+0x09, 0xE4, 0x90, 0x81, 0x5E, 0x31, 0x53, 0x74,
+0x0A, 0x9F, 0x90, 0x81, 0x5D, 0xF0, 0x90, 0x81,
+0x66, 0xE0, 0xFF, 0xA3, 0xE0, 0xC3, 0x9F, 0x90,
+0x81, 0x64, 0xF0, 0x90, 0x81, 0x46, 0xE0, 0x30,
+0xE0, 0x05, 0x90, 0x81, 0xA2, 0x80, 0x03, 0x90,
+0x81, 0xA3, 0xE0, 0x04, 0xFF, 0x90, 0x81, 0x64,
+0xE0, 0x2F, 0xF0, 0x90, 0x81, 0x64, 0xE0, 0xC3,
+0x94, 0x10, 0x50, 0x03, 0x74, 0x10, 0xF0, 0x90,
+0x81, 0x64, 0xE0, 0x24, 0x02, 0x12, 0x67, 0xAF,
+0x74, 0x03, 0xF0, 0x12, 0x6C, 0xF1, 0xE4, 0xFF,
+0x31, 0x8B, 0x22, 0xF0, 0x90, 0x81, 0x66, 0xE0,
+0xFF, 0xC3, 0x22, 0x74, 0x69, 0x2E, 0xF5, 0x82,
+0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, 0x2F, 0xFF,
+0x90, 0x81, 0xA6, 0xE0, 0xFD, 0x22, 0x12, 0x45,
+0x06, 0x90, 0x81, 0x9A, 0x12, 0x44, 0xEE, 0x12,
+0x44, 0xB5, 0x78, 0x0A, 0x12, 0x20, 0xA8, 0x90,
+0x81, 0x63, 0xE0, 0xFE, 0xC3, 0x74, 0x0A, 0x9E,
+0x2F, 0xFF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x82, 0xAF, 0xEF, 0xF0, 0x7E,
+0x00, 0x7F, 0x2D, 0x7D, 0x00, 0x7B, 0x01, 0x7A,
+0x81, 0x79, 0x69, 0x12, 0x45, 0x6F, 0xE4, 0x90,
+0x81, 0x62, 0xF0, 0x90, 0x81, 0x61, 0xF0, 0x90,
+0x81, 0x65, 0xF0, 0x90, 0x82, 0xAF, 0xE0, 0xB4,
+0x01, 0x09, 0x90, 0x81, 0x66, 0x74, 0x2D, 0xF0,
+0xE4, 0xA3, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x90, 0x81, 0xAF, 0xE0, 0x54, 0xFE, 0xF0, 0x54,
+0xFD, 0xF0, 0x54, 0xEF, 0xF0, 0x44, 0x08, 0xF0,
+0x22, 0x90, 0x81, 0xAF, 0xE0, 0x30, 0xE0, 0x0D,
+0xE4, 0xF5, 0x1D, 0x90, 0x81, 0xB1, 0x12, 0x49,
+0x02, 0x12, 0x67, 0xC2, 0xF0, 0x90, 0x80, 0x42,
+0xE0, 0xB4, 0x01, 0x12, 0x51, 0x07, 0x13, 0x54,
+0x1F, 0x20, 0xE0, 0x0A, 0xEF, 0xC4, 0x13, 0x54,
+0x07, 0x30, 0xE0, 0x02, 0x51, 0x0F, 0x22, 0x90,
+0x81, 0xAF, 0xE0, 0xFF, 0x13, 0x13, 0x22, 0x90,
+0x81, 0xAF, 0xE0, 0x30, 0xE0, 0x34, 0xC4, 0x13,
+0x54, 0x07, 0x30, 0xE0, 0x2D, 0x90, 0x82, 0xB0,
+0xE0, 0x04, 0xF0, 0xE0, 0xD3, 0x94, 0xC8, 0x40,
+0x21, 0x90, 0x81, 0xAF, 0xE0, 0x54, 0xDF, 0xF0,
+0xE4, 0x90, 0x82, 0xB0, 0xF0, 0x90, 0x81, 0xAF,
+0xE0, 0x13, 0x30, 0xE0, 0x0D, 0x90, 0x81, 0x46,
+0xE0, 0x44, 0x01, 0xF0, 0x90, 0x81, 0x56, 0x74,
+0xD0, 0xF0, 0x22, 0x90, 0x81, 0x44, 0xE0, 0x64,
+0x02, 0x7F, 0x01, 0x60, 0x02, 0x7F, 0x00, 0x22,
+0x90, 0x80, 0x46, 0xE0, 0xFF, 0x90, 0x82, 0x8A,
+0xE0, 0xFB, 0x90, 0x82, 0x95, 0x74, 0x0A, 0xF0,
+0x7D, 0x01, 0x12, 0x5E, 0xE7, 0x90, 0x82, 0x8B,
+0xEE, 0xF0, 0xFC, 0xA3, 0xEF, 0xF0, 0xFD, 0x90,
+0x82, 0x89, 0xE0, 0xFF, 0x12, 0x5E, 0xBD, 0x90,
+0x82, 0x8B, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90,
+0x04, 0x80, 0xE0, 0x54, 0x0F, 0xFD, 0xAC, 0x07,
+0x51, 0xF3, 0x44, 0x01, 0xF0, 0x51, 0xF3, 0x54,
+0xFB, 0xF0, 0xAC, 0x07, 0x74, 0x16, 0x2C, 0x12,
+0x5F, 0xA1, 0xE0, 0x44, 0xFA, 0xF0, 0x74, 0x15,
+0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0xE0, 0x44, 0x1F, 0xF0, 0xAC, 0x07, 0x74, 0x06,
+0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0xE0, 0x44, 0x0F, 0xF0, 0x90, 0x04, 0x53, 0xE4,
+0xF0, 0x90, 0x04, 0x52, 0xF0, 0x90, 0x04, 0x51,
+0x74, 0xFF, 0xF0, 0x90, 0x04, 0x50, 0x74, 0xFD,
+0xF0, 0x74, 0x14, 0x2C, 0x51, 0xEB, 0xE0, 0x54,
+0xC0, 0x4D, 0xFD, 0x74, 0x14, 0x2F, 0x51, 0xEB,
+0xED, 0xF0, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC,
+0xF5, 0x83, 0x22, 0x74, 0x11, 0x2C, 0xF5, 0x82,
+0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xE4,
+0xFE, 0xEF, 0xC3, 0x13, 0xFD, 0xEF, 0x30, 0xE0,
+0x02, 0x7E, 0x80, 0x90, 0xFD, 0x10, 0xED, 0xF0,
+0xAF, 0x06, 0x22, 0x7E, 0x00, 0x7F, 0x04, 0x7D,
+0x00, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0xB7, 0x22,
+0xE0, 0x90, 0x01, 0xBA, 0xF0, 0x90, 0x81, 0x4D,
+0xE0, 0x90, 0x01, 0xBB, 0x22, 0xEF, 0x13, 0x13,
+0x13, 0x54, 0x1F, 0xFE, 0xEF, 0x54, 0x07, 0xFF,
+0x22, 0x90, 0x81, 0x41, 0xE0, 0xC4, 0x13, 0x13,
+0x54, 0x03, 0x22, 0x90, 0x81, 0x46, 0xE0, 0x13,
+0x13, 0x13, 0x54, 0x1F, 0x22, 0x90, 0x06, 0x04,
+0xE0, 0x54, 0x7F, 0xF0, 0x22, 0x7D, 0x6F, 0x7F,
+0xFF, 0x02, 0x4D, 0x1C, 0x90, 0x05, 0x27, 0xE0,
+0x54, 0xBF, 0xF0, 0x22, 0x90, 0x06, 0x04, 0xE0,
+0x44, 0x40, 0xF0, 0x22, 0x90, 0x81, 0x46, 0xE0,
+0x54, 0xBF, 0xF0, 0x22, 0x90, 0x81, 0x51, 0xE0,
+0x90, 0x05, 0x73, 0x22, 0x69, 0xCF
+};
+
+u32 array_length_mp_8188e_t_fw_nic = 15262;
+
+u8 array_mp_8188e_t_fw_nic_89em[] = {
+0xE1, 0x88, 0x40, 0x00, 0x1C, 0x00, 0x00, 0x00,
+0x05, 0x05, 0x14, 0x28, 0xFC, 0x37, 0x00, 0x00,
+0xA5, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x45, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xC1, 0xA4, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xC1, 0x1B, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xE1, 0xFA, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xC2, 0xAF, 0x80, 0xFE, 0x32, 0x12, 0x41, 0x04,
+0x85, 0xD0, 0x0B, 0x75, 0xD0, 0x08, 0xAA, 0xE0,
+0xC2, 0x8C, 0xE5, 0x8A, 0x24, 0x67, 0xF5, 0x8A,
+0xE5, 0x8C, 0x34, 0x79, 0xF5, 0x8C, 0xD2, 0x8C,
+0xEC, 0x24, 0x87, 0xF8, 0xE6, 0xBC, 0x02, 0x02,
+0x74, 0xFF, 0xC3, 0x95, 0x81, 0xB4, 0x40, 0x00,
+0x40, 0xCE, 0x79, 0x03, 0x78, 0x80, 0x16, 0xE6,
+0x08, 0x70, 0x0B, 0xC2, 0xAF, 0xE6, 0x30, 0xE1,
+0x03, 0x44, 0x18, 0xF6, 0xD2, 0xAF, 0x08, 0xD9,
+0xED, 0xEA, 0x8B, 0xD0, 0x22, 0xE5, 0x0C, 0xFF,
+0x23, 0x24, 0x81, 0xF8, 0x0F, 0x08, 0x08, 0xBF,
+0x03, 0x04, 0x7F, 0x00, 0x78, 0x81, 0xE6, 0x30,
+0xE4, 0xF2, 0x00, 0xE5, 0x0C, 0xC3, 0x9F, 0x50,
+0x20, 0x05, 0x0C, 0x74, 0x86, 0x25, 0x0C, 0xF8,
+0xE6, 0xFD, 0xA6, 0x81, 0x08, 0xE6, 0xAE, 0x0C,
+0xBE, 0x02, 0x02, 0x74, 0xFF, 0xCD, 0xF8, 0xE8,
+0x6D, 0x60, 0xE0, 0x08, 0xE6, 0xC0, 0xE0, 0x80,
+0xF6, 0xE5, 0x0C, 0xD3, 0x9F, 0x40, 0x27, 0xE5,
+0x0C, 0x24, 0x87, 0xF8, 0xE6, 0xAE, 0x0C, 0xBE,
+0x02, 0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xCD,
+0xF8, 0xE5, 0x81, 0x6D, 0x60, 0x06, 0xD0, 0xE0,
+0xF6, 0x18, 0x80, 0xF5, 0xE5, 0x0C, 0x24, 0x86,
+0xC8, 0xF6, 0x15, 0x0C, 0x80, 0xD3, 0xE5, 0x0C,
+0x23, 0x24, 0x81, 0xF8, 0x7F, 0x04, 0xC2, 0xAF,
+0xE6, 0x30, 0xE0, 0x03, 0x10, 0xE2, 0x0C, 0x7F,
+0x00, 0x30, 0xE1, 0x07, 0x30, 0xE3, 0x04, 0x7F,
+0x08, 0x54, 0xF4, 0x54, 0x7C, 0xC6, 0xD2, 0xAF,
+0x54, 0x80, 0x42, 0x07, 0x22, 0x78, 0x86, 0xA6,
+0x81, 0x74, 0x02, 0x60, 0x06, 0xFF, 0x08, 0x76,
+0xFF, 0xDF, 0xFB, 0x7F, 0x03, 0xE4, 0x78, 0x80,
+0xF6, 0x08, 0xF6, 0x08, 0xDF, 0xFA, 0x78, 0x81,
+0x76, 0x30, 0x90, 0x46, 0x15, 0x74, 0x01, 0x93,
+0xC0, 0xE0, 0xE4, 0x93, 0xC0, 0xE0, 0x43, 0x89,
+0x01, 0x75, 0x8A, 0x60, 0x75, 0x8C, 0x79, 0xD2,
+0x8C, 0xD2, 0xAF, 0x22, 0x02, 0xEF, 0xD3, 0x94,
+0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0x74, 0x81,
+0x2F, 0x2F, 0xF8, 0xE6, 0x20, 0xE5, 0xF4, 0xC2,
+0xAF, 0xE6, 0x44, 0x30, 0xF6, 0xD2, 0xAF, 0xAE,
+0x0C, 0xEE, 0xC3, 0x9F, 0x50, 0x21, 0x0E, 0x74,
+0x86, 0x2E, 0xF8, 0xE6, 0xF9, 0x08, 0xE6, 0x18,
+0xBE, 0x02, 0x02, 0x74, 0xFF, 0xFD, 0xED, 0x69,
+0x60, 0x09, 0x09, 0xE7, 0x19, 0x19, 0xF7, 0x09,
+0x09, 0x80, 0xF3, 0x16, 0x16, 0x80, 0xDA, 0xEE,
+0xD3, 0x9F, 0x40, 0x04, 0x05, 0x81, 0x05, 0x81,
+0xEE, 0xD3, 0x9F, 0x40, 0x22, 0x74, 0x86, 0x2E,
+0xF8, 0x08, 0xE6, 0xF9, 0xEE, 0xB5, 0x0C, 0x02,
+0xA9, 0x81, 0x18, 0x06, 0x06, 0xE6, 0xFD, 0xED,
+0x69, 0x60, 0x09, 0x19, 0x19, 0xE7, 0x09, 0x09,
+0xF7, 0x19, 0x80, 0xF3, 0x1E, 0x80, 0xD9, 0xEF,
+0x24, 0x86, 0xF8, 0xE6, 0x04, 0xF8, 0xEF, 0x2F,
+0x04, 0x90, 0x46, 0x15, 0x93, 0xF6, 0x08, 0xEF,
+0x2F, 0x93, 0xF6, 0x7F, 0x00, 0x22, 0xEF, 0xD3,
+0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0xEF,
+0x23, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE5, 0xF4,
+0xC2, 0xAF, 0xE6, 0x54, 0x8C, 0xF6, 0xD2, 0xAF,
+0xE5, 0x0C, 0xB5, 0x07, 0x0A, 0x74, 0x86, 0x2F,
+0xF8, 0xE6, 0xF5, 0x81, 0x02, 0x41, 0x4D, 0x50,
+0x2E, 0x74, 0x87, 0x2F, 0xF8, 0xE6, 0xBF, 0x02,
+0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xF9, 0x74,
+0x86, 0x2F, 0xF8, 0xFB, 0xE6, 0xFC, 0xE9, 0x6C,
+0x60, 0x08, 0xA8, 0x05, 0xE7, 0xF6, 0x1D, 0x19,
+0x80, 0xF4, 0xA8, 0x03, 0xA6, 0x05, 0x1F, 0xE5,
+0x0C, 0xB5, 0x07, 0xE3, 0x7F, 0x00, 0x22, 0x74,
+0x87, 0x2F, 0xF8, 0xE6, 0xFD, 0x18, 0x86, 0x01,
+0x0F, 0x74, 0x86, 0x2F, 0xF8, 0xA6, 0x01, 0x08,
+0x86, 0x04, 0xE5, 0x0C, 0xB5, 0x07, 0x02, 0xAC,
+0x81, 0xED, 0x6C, 0x60, 0x08, 0x0D, 0x09, 0xA8,
+0x05, 0xE6, 0xF7, 0x80, 0xF4, 0xE5, 0x0C, 0xB5,
+0x07, 0xDE, 0x89, 0x81, 0x7F, 0x00, 0x22, 0xEF,
+0xD3, 0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22,
+0xEF, 0x23, 0x24, 0x81, 0xF8, 0xC2, 0xAF, 0xE6,
+0x30, 0xE5, 0x05, 0x30, 0xE0, 0x02, 0xD2, 0xE4,
+0xD2, 0xE2, 0xC6, 0xD2, 0xAF, 0x7F, 0x00, 0x30,
+0xE2, 0x01, 0x0F, 0x02, 0x41, 0x4C, 0x8F, 0xF0,
+0xE4, 0xFF, 0xFE, 0xE5, 0x0C, 0x23, 0x24, 0x80,
+0xF8, 0xC2, 0xA9, 0x30, 0xF7, 0x0D, 0x7F, 0x08,
+0xE6, 0x60, 0x0B, 0x2D, 0xF6, 0x60, 0x30, 0x50,
+0x2E, 0x80, 0x07, 0x30, 0xF1, 0x06, 0xED, 0xF6,
+0x60, 0x25, 0x7E, 0x02, 0x08, 0x30, 0xF0, 0x10,
+0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x23, 0x0E, 0x30,
+0xE2, 0x0C, 0xD2, 0xAF, 0x7F, 0x04, 0x80, 0x12,
+0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x13, 0x54, 0xEC,
+0x4E, 0xF6, 0xD2, 0xAF, 0x02, 0x41, 0x4D, 0x7F,
+0x08, 0x08, 0xEF, 0x44, 0x83, 0xF4, 0xC2, 0xAF,
+0x56, 0xC6, 0xD2, 0xAF, 0x54, 0x80, 0x4F, 0xFF,
+0x22, 0xE7, 0x09, 0xF6, 0x08, 0xDF, 0xFA, 0x80,
+0x46, 0xE7, 0x09, 0xF2, 0x08, 0xDF, 0xFA, 0x80,
+0x3E, 0x88, 0x82, 0x8C, 0x83, 0xE7, 0x09, 0xF0,
+0xA3, 0xDF, 0xFA, 0x80, 0x32, 0xE3, 0x09, 0xF6,
+0x08, 0xDF, 0xFA, 0x80, 0x78, 0xE3, 0x09, 0xF2,
+0x08, 0xDF, 0xFA, 0x80, 0x70, 0x88, 0x82, 0x8C,
+0x83, 0xE3, 0x09, 0xF0, 0xA3, 0xDF, 0xFA, 0x80,
+0x64, 0x89, 0x82, 0x8A, 0x83, 0xE0, 0xA3, 0xF6,
+0x08, 0xDF, 0xFA, 0x80, 0x58, 0x89, 0x82, 0x8A,
+0x83, 0xE0, 0xA3, 0xF2, 0x08, 0xDF, 0xFA, 0x80,
+0x4C, 0x80, 0xD2, 0x80, 0xFA, 0x80, 0xC6, 0x80,
+0xD4, 0x80, 0x69, 0x80, 0xF2, 0x80, 0x33, 0x80,
+0x10, 0x80, 0xA6, 0x80, 0xEA, 0x80, 0x9A, 0x80,
+0xA8, 0x80, 0xDA, 0x80, 0xE2, 0x80, 0xCA, 0x80,
+0x33, 0x89, 0x82, 0x8A, 0x83, 0xEC, 0xFA, 0xE4,
+0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC, 0xC5,
+0x83, 0xCC, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8,
+0xCC, 0xC5, 0x83, 0xCC, 0xDF, 0xE9, 0xDE, 0xE7,
+0x80, 0x0D, 0x89, 0x82, 0x8A, 0x83, 0xE4, 0x93,
+0xA3, 0xF6, 0x08, 0xDF, 0xF9, 0xEC, 0xFA, 0xA9,
+0xF0, 0xED, 0xFB, 0x22, 0x89, 0x82, 0x8A, 0x83,
+0xEC, 0xFA, 0xE0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8,
+0xCC, 0xC5, 0x83, 0xCC, 0xF0, 0xA3, 0xC8, 0xC5,
+0x82, 0xC8, 0xCC, 0xC5, 0x83, 0xCC, 0xDF, 0xEA,
+0xDE, 0xE8, 0x80, 0xDB, 0x89, 0x82, 0x8A, 0x83,
+0xE4, 0x93, 0xA3, 0xF2, 0x08, 0xDF, 0xF9, 0x80,
+0xCC, 0x88, 0xF0, 0xEF, 0x60, 0x01, 0x0E, 0x4E,
+0x60, 0xC3, 0x88, 0xF0, 0xED, 0x24, 0x02, 0xB4,
+0x04, 0x00, 0x50, 0xB9, 0xF5, 0x82, 0xEB, 0x24,
+0x02, 0xB4, 0x04, 0x00, 0x50, 0xAF, 0x23, 0x23,
+0x45, 0x82, 0x23, 0x90, 0x43, 0xF9, 0x73, 0xC5,
+0xF0, 0xF8, 0xA3, 0xE0, 0x28, 0xF0, 0xC5, 0xF0,
+0xF8, 0xE5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15,
+0x83, 0xE0, 0x38, 0xF0, 0x22, 0xEF, 0x5B, 0xFF,
+0xEE, 0x5A, 0xFE, 0xED, 0x59, 0xFD, 0xEC, 0x58,
+0xFC, 0x22, 0xEF, 0x4B, 0xFF, 0xEE, 0x4A, 0xFE,
+0xED, 0x49, 0xFD, 0xEC, 0x48, 0xFC, 0x22, 0xEB,
+0x9F, 0xF5, 0xF0, 0xEA, 0x9E, 0x42, 0xF0, 0xE9,
+0x9D, 0x42, 0xF0, 0xE8, 0x9C, 0x45, 0xF0, 0x22,
+0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0x22, 0xE2, 0xFC, 0x08, 0xE2,
+0xFD, 0x08, 0xE2, 0xFE, 0x08, 0xE2, 0xFF, 0x22,
+0xE2, 0xFB, 0x08, 0xE2, 0xF9, 0x08, 0xE2, 0xFA,
+0x08, 0xE2, 0xCB, 0xF8, 0x22, 0xEC, 0xF2, 0x08,
+0xED, 0xF2, 0x08, 0xEE, 0xF2, 0x08, 0xEF, 0xF2,
+0x22, 0xA4, 0x25, 0x82, 0xF5, 0x82, 0xE5, 0xF0,
+0x35, 0x83, 0xF5, 0x83, 0x22, 0xE0, 0xFB, 0xA3,
+0xE0, 0xFA, 0xA3, 0xE0, 0xF9, 0x22, 0xEB, 0xF0,
+0xA3, 0xEA, 0xF0, 0xA3, 0xE9, 0xF0, 0x22, 0xD0,
+0x83, 0xD0, 0x82, 0xF8, 0xE4, 0x93, 0x70, 0x12,
+0x74, 0x01, 0x93, 0x70, 0x0D, 0xA3, 0xA3, 0x93,
+0xF8, 0x74, 0x01, 0x93, 0xF5, 0x82, 0x88, 0x83,
+0xE4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xEF,
+0xA3, 0xA3, 0xA3, 0x80, 0xDF, 0xEF, 0x4E, 0x60,
+0x12, 0xEF, 0x60, 0x01, 0x0E, 0xED, 0xBB, 0x01,
+0x0B, 0x89, 0x82, 0x8A, 0x83, 0xF0, 0xA3, 0xDF,
+0xFC, 0xDE, 0xFA, 0x22, 0x89, 0xF0, 0x50, 0x07,
+0xF7, 0x09, 0xDF, 0xFC, 0xA9, 0xF0, 0x22, 0xBB,
+0xFE, 0xFC, 0xF3, 0x09, 0xDF, 0xFC, 0xA9, 0xF0,
+0x22, 0x02, 0x45, 0xBF, 0x02, 0x41, 0xDD, 0xE4,
+0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0x40, 0x03,
+0xF6, 0x80, 0x01, 0xF2, 0x08, 0xDF, 0xF4, 0x80,
+0x29, 0xE4, 0x93, 0xA3, 0xF8, 0x54, 0x07, 0x24,
+0x0C, 0xC8, 0xC3, 0x33, 0xC4, 0x54, 0x0F, 0x44,
+0x20, 0xC8, 0x83, 0x40, 0x04, 0xF4, 0x56, 0x80,
+0x01, 0x46, 0xF6, 0xDF, 0xE4, 0x80, 0x0B, 0x01,
+0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90,
+0x46, 0x04, 0xE4, 0x7E, 0x01, 0x93, 0x60, 0xBC,
+0xA3, 0xFF, 0x54, 0x3F, 0x30, 0xE5, 0x09, 0x54,
+0x1F, 0xFE, 0xE4, 0x93, 0xA3, 0x60, 0x01, 0x0E,
+0xCF, 0x54, 0xC0, 0x25, 0xE0, 0x60, 0xA8, 0x40,
+0xB8, 0xE4, 0x93, 0xA3, 0xFA, 0xE4, 0x93, 0xA3,
+0xF8, 0xE4, 0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8,
+0xCA, 0xC5, 0x83, 0xCA, 0xF0, 0xA3, 0xC8, 0xC5,
+0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xDF, 0xE9,
+0xDE, 0xE7, 0x80, 0xBE, 0x41, 0x82, 0xA5, 0x00,
+0x41, 0x82, 0xA6, 0x00, 0x41, 0x82, 0xAF, 0x00,
+0x41, 0x82, 0xB1, 0x00, 0x00, 0x50, 0xF5, 0x59,
+0x36, 0x5F, 0xD5, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0,
+0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00,
+0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03,
+0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07,
+0x90, 0x01, 0xC4, 0x74, 0x1B, 0xF0, 0x74, 0x46,
+0xA3, 0xF0, 0xD1, 0x6A, 0x74, 0x1B, 0x04, 0x90,
+0x01, 0xC4, 0xF0, 0x74, 0x46, 0xA3, 0xF0, 0xD0,
+0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0,
+0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0,
+0xE0, 0x32, 0x90, 0x00, 0x54, 0xE0, 0x55, 0x35,
+0xF5, 0x39, 0xA3, 0xE0, 0x55, 0x36, 0xF5, 0x3A,
+0xA3, 0xE0, 0x55, 0x37, 0xF5, 0x3B, 0xA3, 0xE0,
+0x55, 0x38, 0xF5, 0x3C, 0xAD, 0x39, 0x7F, 0x54,
+0x12, 0x32, 0x1E, 0xAD, 0x3A, 0x7F, 0x55, 0x12,
+0x32, 0x1E, 0xAD, 0x3B, 0x7F, 0x56, 0x12, 0x32,
+0x1E, 0xAD, 0x3C, 0x7F, 0x57, 0x12, 0x32, 0x1E,
+0x53, 0x91, 0xEF, 0x22, 0xC0, 0xE0, 0xC0, 0xF0,
+0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0,
+0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0,
+0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0,
+0x07, 0x90, 0x01, 0xC4, 0x74, 0xA4, 0xF0, 0x74,
+0x46, 0xA3, 0xF0, 0x12, 0x6E, 0x5D, 0xE5, 0x41,
+0x30, 0xE4, 0x02, 0xF1, 0x40, 0xE5, 0x41, 0x30,
+0xE6, 0x03, 0x12, 0x6E, 0xBA, 0xE5, 0x43, 0x30,
+0xE0, 0x03, 0x12, 0x6E, 0xC7, 0xE5, 0x43, 0x30,
+0xE1, 0x03, 0x12, 0x55, 0xCB, 0xE5, 0x43, 0x30,
+0xE2, 0x03, 0x12, 0x70, 0x12, 0xE5, 0x43, 0x30,
+0xE3, 0x02, 0xF1, 0x53, 0xE5, 0x43, 0x30, 0xE4,
+0x02, 0xF1, 0x95, 0xE5, 0x43, 0x30, 0xE5, 0x03,
+0x12, 0x67, 0x75, 0xE5, 0x43, 0x30, 0xE6, 0x02,
+0xF1, 0xCD, 0xE5, 0x44, 0x30, 0xE1, 0x03, 0x12,
+0x67, 0xB2, 0x74, 0xA4, 0x04, 0x90, 0x01, 0xC4,
+0xF0, 0x74, 0x46, 0xA3, 0xF0, 0xD0, 0x07, 0xD0,
+0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03, 0xD0,
+0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0,
+0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0x32,
+0x12, 0x60, 0x74, 0x7F, 0x02, 0x8F, 0x0F, 0x7F,
+0x02, 0x71, 0x27, 0x90, 0x80, 0x3C, 0xE0, 0x45,
+0x0F, 0xF0, 0x22, 0xF1, 0x6A, 0x70, 0x12, 0x90,
+0x81, 0x4B, 0xE0, 0x60, 0x0C, 0x90, 0x81, 0x4F,
+0xE0, 0x20, 0xE4, 0x05, 0xF1, 0xB7, 0x12, 0x49,
+0x00, 0x22, 0xE4, 0xFF, 0xF1, 0x72, 0xEF, 0x64,
+0x01, 0x22, 0x12, 0x77, 0xB6, 0xF1, 0xC2, 0xE0,
+0xFD, 0x7C, 0x00, 0x12, 0x6D, 0x55, 0x80, 0x05,
+0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF,
+0xEE, 0x5C, 0xFE, 0xEF, 0x5D, 0x4E, 0x7F, 0x00,
+0x60, 0x02, 0x7F, 0x01, 0x22, 0xF1, 0x6A, 0x70,
+0x1D, 0x90, 0x81, 0x4B, 0xE0, 0x60, 0x17, 0x90,
+0x81, 0x4F, 0xE0, 0x20, 0xE4, 0x10, 0xF1, 0xB7,
+0xF0, 0x90, 0x81, 0x46, 0xE0, 0x12, 0x6F, 0x97,
+0x54, 0x07, 0x70, 0x02, 0xF1, 0xE4, 0x22, 0x90,
+0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74,
+0x02, 0x22, 0x74, 0x38, 0x2E, 0xF5, 0x82, 0xE4,
+0x34, 0x81, 0xF5, 0x83, 0x22, 0xE4, 0xFF, 0xF1,
+0x72, 0xBF, 0x01, 0x0F, 0x90, 0x81, 0x4B, 0xE0,
+0x60, 0x09, 0x12, 0x65, 0xA2, 0x54, 0x07, 0x70,
+0x02, 0xF1, 0xE4, 0x22, 0x90, 0x81, 0x41, 0xE0,
+0x90, 0x81, 0x4D, 0x30, 0xE0, 0x05, 0xE0, 0xFF,
+0x02, 0x76, 0xBD, 0xE0, 0xFF, 0x7D, 0x01, 0x02,
+0x4B, 0x1C, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83,
+0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0,
+0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03, 0xC0,
+0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90,
+0x01, 0xC4, 0x74, 0xFA, 0xF0, 0x74, 0x47, 0xA3,
+0xF0, 0x12, 0x6E, 0x8A, 0xE5, 0x49, 0x30, 0xE1,
+0x02, 0x11, 0xA3, 0xE5, 0x49, 0x30, 0xE2, 0x03,
+0x12, 0x70, 0x35, 0xE5, 0x4A, 0x30, 0xE0, 0x03,
+0x12, 0x70, 0x91, 0xE5, 0x4A, 0x30, 0xE4, 0x03,
+0x12, 0x72, 0x0B, 0xE5, 0x4B, 0x30, 0xE1, 0x03,
+0x12, 0x6F, 0x19, 0xE5, 0x4B, 0x30, 0xE0, 0x03,
+0x12, 0x72, 0x21, 0xE5, 0x4B, 0x30, 0xE4, 0x03,
+0x12, 0x72, 0x69, 0xE5, 0x4C, 0x30, 0xE1, 0x05,
+0x7F, 0x04, 0x12, 0x47, 0x45, 0xE5, 0x4C, 0x30,
+0xE4, 0x03, 0x12, 0x72, 0x6A, 0xE5, 0x4C, 0x30,
+0xE5, 0x03, 0x12, 0x73, 0x24, 0xE5, 0x4C, 0x30,
+0xE6, 0x03, 0x12, 0x73, 0x58, 0x74, 0xFA, 0x04,
+0x90, 0x01, 0xC4, 0xF0, 0x74, 0x47, 0xA3, 0xF0,
+0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04,
+0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00,
+0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0,
+0xD0, 0xE0, 0x32, 0x90, 0x81, 0x4B, 0xE0, 0x60,
+0x03, 0x12, 0x6F, 0xBA, 0x90, 0x81, 0xAF, 0xE0,
+0x30, 0xE0, 0x49, 0xC4, 0x54, 0x0F, 0x20, 0xE0,
+0x17, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0xB1, 0x31,
+0x07, 0xB1, 0x0E, 0x12, 0x77, 0xC2, 0x30, 0xE0,
+0x02, 0x31, 0xCD, 0x12, 0x57, 0x7A, 0xF0, 0x22,
+0x90, 0x81, 0xAF, 0xE0, 0xC4, 0x54, 0x0F, 0x30,
+0xE0, 0x22, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0xB2,
+0x31, 0x07, 0x90, 0x81, 0xAF, 0xE0, 0x54, 0xEF,
+0xF0, 0xE0, 0xC3, 0x13, 0x30, 0xE0, 0x06, 0x7D,
+0x04, 0x7F, 0x01, 0x21, 0xD1, 0x7B, 0x31, 0xF1,
+0x95, 0x12, 0x73, 0x88, 0x22, 0xE0, 0x44, 0x02,
+0xF0, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0xA9, 0xE0,
+0xF5, 0x1E, 0xE4, 0xFB, 0xFD, 0x7F, 0x54, 0x7E,
+0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x8E, 0x19, 0x8F, 0x1A, 0xE5, 0x1E, 0x31, 0x66,
+0x85, 0x19, 0x83, 0x85, 0x1A, 0x82, 0xF0, 0xE5,
+0x1D, 0x31, 0x66, 0xFF, 0xE5, 0x1E, 0x13, 0x13,
+0x13, 0x54, 0x1F, 0x4F, 0xA3, 0xF0, 0xEB, 0x31,
+0x66, 0xFF, 0xE5, 0x1D, 0x13, 0x13, 0x13, 0x54,
+0x1F, 0x4F, 0x31, 0x6D, 0xF0, 0xBD, 0x01, 0x0D,
+0x85, 0x1A, 0x82, 0x8E, 0x83, 0xA3, 0xA3, 0xA3,
+0x74, 0x03, 0xF0, 0x80, 0x06, 0x31, 0x6D, 0xA3,
+0x74, 0x01, 0xF0, 0x31, 0x6D, 0xA3, 0x74, 0x05,
+0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x54, 0x07,
+0xC4, 0x33, 0x54, 0xE0, 0x22, 0x85, 0x1A, 0x82,
+0x85, 0x19, 0x83, 0xA3, 0xA3, 0x22, 0x90, 0x81,
+0x4F, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x81, 0x54,
+0xE0, 0x60, 0x04, 0x64, 0x01, 0x70, 0x11, 0xE4,
+0xF5, 0x1D, 0x90, 0x81, 0x54, 0xE0, 0x31, 0xBA,
+0x31, 0x08, 0x90, 0x81, 0x54, 0xE0, 0x80, 0x11,
+0xE4, 0xF5, 0x1D, 0x31, 0xC1, 0xA4, 0x24, 0xFE,
+0x31, 0xBA, 0x31, 0x08, 0x31, 0xC1, 0xA4, 0x24,
+0xFE, 0x31, 0xBA, 0x90, 0x81, 0x64, 0xF0, 0x90,
+0x81, 0x4E, 0xE0, 0x20, 0xE2, 0x03, 0x12, 0x77,
+0xF3, 0x22, 0xFF, 0x90, 0x81, 0x53, 0xE0, 0x2F,
+0x22, 0x90, 0x81, 0x54, 0xE0, 0x75, 0xF0, 0x03,
+0x22, 0xE0, 0x54, 0x7F, 0xF0, 0x7D, 0x0C, 0x7F,
+0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0xAC, 0x07, 0xEF, 0x14, 0x60, 0x15, 0x14, 0x60,
+0x19, 0x24, 0x02, 0x70, 0x1A, 0xED, 0x54, 0x01,
+0xFE, 0x90, 0x81, 0x46, 0xE0, 0x54, 0xFE, 0x4E,
+0xF0, 0x80, 0x0C, 0x90, 0x81, 0x4E, 0xED, 0xF0,
+0x80, 0x05, 0x90, 0x81, 0x4D, 0xED, 0xF0, 0x90,
+0x00, 0x8F, 0xE0, 0x30, 0xE4, 0x2E, 0xEC, 0x14,
+0x60, 0x07, 0x14, 0x60, 0x1D, 0x24, 0x02, 0x70,
+0x23, 0x90, 0x81, 0x46, 0xE0, 0x54, 0x01, 0xC4,
+0x33, 0x33, 0x33, 0x54, 0x80, 0xFF, 0x90, 0x81,
+0x4E, 0xE0, 0x54, 0x7F, 0x4F, 0xFD, 0x7F, 0x88,
+0x80, 0x07, 0x90, 0x81, 0x4D, 0xE0, 0xFD, 0x7F,
+0x89, 0x12, 0x32, 0x1E, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x7E, 0x00, 0x7F, 0x62, 0x7D, 0x00, 0x7B,
+0x01, 0x7A, 0x81, 0x79, 0x46, 0x12, 0x45, 0x55,
+0x12, 0x77, 0x9C, 0x12, 0x45, 0x55, 0x90, 0x81,
+0x4A, 0x74, 0x02, 0xF0, 0x90, 0x81, 0x51, 0x14,
+0xF0, 0xA3, 0xF0, 0xA3, 0x74, 0x10, 0xF0, 0x90,
+0x81, 0x57, 0xE4, 0xF0, 0xA3, 0x74, 0x02, 0x51,
+0xF3, 0xF0, 0xE4, 0xFD, 0xFF, 0x31, 0xD1, 0x7D,
+0x0C, 0x7F, 0x02, 0x31, 0xD1, 0x31, 0xCD, 0x90,
+0x80, 0x42, 0xE0, 0xFF, 0xB4, 0x01, 0x08, 0x90,
+0x81, 0x56, 0x74, 0x99, 0xF0, 0x80, 0x29, 0xEF,
+0xB4, 0x03, 0x08, 0x90, 0x81, 0x56, 0x74, 0x90,
+0xF0, 0x80, 0x1D, 0x90, 0x81, 0x56, 0x74, 0x40,
+0xF0, 0x90, 0x00, 0x2C, 0xE0, 0x54, 0x0F, 0xFF,
+0xBF, 0x05, 0x08, 0x90, 0x81, 0x68, 0x74, 0x02,
+0xF0, 0x80, 0x05, 0xE4, 0x90, 0x81, 0x68, 0xF0,
+0x90, 0x81, 0xA8, 0x74, 0x02, 0xF0, 0xA3, 0x74,
+0x0F, 0xF0, 0xA3, 0xE0, 0x54, 0x01, 0x44, 0x28,
+0xF0, 0xA3, 0x74, 0x07, 0x51, 0xF3, 0xF0, 0x90,
+0x05, 0x58, 0x74, 0x02, 0xF0, 0x7E, 0x00, 0xFF,
+0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0xAC,
+0x12, 0x45, 0x55, 0x12, 0x77, 0xDB, 0x90, 0x06,
+0x0A, 0xE0, 0x54, 0xF8, 0xF0, 0x7B, 0x56, 0xE4,
+0xFD, 0x7F, 0xFF, 0xB1, 0x15, 0xE4, 0x90, 0x81,
+0xAE, 0xF0, 0x22, 0xF0, 0x90, 0x81, 0x68, 0xE0,
+0x24, 0x04, 0x90, 0x81, 0x63, 0xF0, 0xA3, 0x74,
+0x10, 0x22, 0x90, 0x82, 0xAD, 0xEF, 0xF0, 0xB1,
+0x70, 0x90, 0x82, 0xAD, 0xE0, 0x60, 0x02, 0xB1,
+0x10, 0x7D, 0x04, 0xD1, 0x28, 0x74, 0x04, 0xF0,
+0x22, 0xFD, 0x7F, 0x0C, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x82, 0xAE, 0xED, 0xF0,
+0x90, 0x81, 0x46, 0xE0, 0xFE, 0xC4, 0x13, 0x13,
+0x54, 0x03, 0x30, 0xE0, 0x02, 0x81, 0x62, 0xEE,
+0x12, 0x67, 0xD3, 0x30, 0xE0, 0x02, 0x81, 0x62,
+0x90, 0x81, 0x4E, 0xE0, 0xFE, 0x6F, 0x70, 0x02,
+0x81, 0x62, 0xEF, 0x70, 0x02, 0x61, 0xD8, 0x24,
+0xFE, 0x70, 0x02, 0x81, 0x11, 0x24, 0xFE, 0x60,
+0x47, 0x24, 0xFC, 0x70, 0x02, 0x81, 0x4C, 0x24,
+0xFC, 0x60, 0x02, 0x81, 0x5B, 0xEE, 0xB4, 0x0E,
+0x02, 0x91, 0xE5, 0x90, 0x81, 0x4E, 0xE0, 0x70,
+0x04, 0x7F, 0x01, 0x71, 0x02, 0x90, 0x81, 0x4E,
+0xE0, 0xB4, 0x06, 0x02, 0x91, 0xBE, 0x90, 0x81,
+0x4E, 0xE0, 0xB4, 0x04, 0x0D, 0x90, 0x82, 0xAE,
+0xE0, 0xFF, 0x60, 0x04, 0xB1, 0xEF, 0x80, 0x02,
+0xB1, 0x5A, 0x90, 0x81, 0x4E, 0xE0, 0x64, 0x08,
+0x60, 0x02, 0x81, 0x5B, 0xB1, 0x65, 0x81, 0x5B,
+0x90, 0x81, 0x4E, 0xE0, 0x70, 0x04, 0x7F, 0x01,
+0x71, 0x02, 0x90, 0x81, 0x4E, 0xE0, 0xB4, 0x06,
+0x02, 0x91, 0xBE, 0x90, 0x81, 0x4E, 0xE0, 0xB4,
+0x0E, 0x07, 0x91, 0x67, 0xBF, 0x01, 0x02, 0x91,
+0xE5, 0x90, 0x81, 0x4E, 0xE0, 0x64, 0x0C, 0x60,
+0x02, 0x81, 0x5B, 0x91, 0x67, 0xEF, 0x64, 0x01,
+0x60, 0x02, 0x81, 0x5B, 0xB1, 0x2B, 0x81, 0x5B,
+0x90, 0x81, 0x4E, 0xE0, 0xB4, 0x0E, 0x07, 0x91,
+0x67, 0xBF, 0x01, 0x02, 0x91, 0xE5, 0x90, 0x81,
+0x4E, 0xE0, 0xB4, 0x06, 0x02, 0x91, 0xBE, 0x90,
+0x81, 0x4E, 0xE0, 0xB4, 0x0C, 0x07, 0x91, 0x67,
+0xBF, 0x01, 0x02, 0xB1, 0x2B, 0x90, 0x81, 0x4E,
+0xE0, 0x64, 0x04, 0x70, 0x56, 0x12, 0x75, 0x3F,
+0xEF, 0x64, 0x01, 0x70, 0x4E, 0xF1, 0xC9, 0x80,
+0x4A, 0x90, 0x81, 0x4E, 0xE0, 0xB4, 0x0E, 0x07,
+0x91, 0x67, 0xBF, 0x01, 0x02, 0x91, 0xE5, 0x90,
+0x81, 0x4E, 0xE0, 0xB4, 0x06, 0x02, 0x91, 0xBE,
+0x90, 0x81, 0x4E, 0xE0, 0xB4, 0x0C, 0x07, 0x91,
+0x67, 0xBF, 0x01, 0x02, 0xB1, 0x2B, 0x90, 0x81,
+0x4E, 0xE0, 0x70, 0x04, 0x7F, 0x01, 0x71, 0x02,
+0x90, 0x81, 0x4E, 0xE0, 0xB4, 0x04, 0x14, 0x12,
+0x75, 0xFB, 0x80, 0x0F, 0x90, 0x81, 0x4E, 0xE0,
+0xB4, 0x0C, 0x08, 0x12, 0x6F, 0x8C, 0x30, 0xE0,
+0x02, 0xD1, 0x30, 0x90, 0x81, 0x4E, 0x12, 0x77,
+0xA9, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x75,
+0x26, 0xEF, 0x64, 0x01, 0x60, 0x05, 0x75, 0x1F,
+0x01, 0x80, 0x30, 0x12, 0x70, 0x87, 0x30, 0xE0,
+0x05, 0x75, 0x1F, 0x02, 0x80, 0x25, 0x90, 0x81,
+0x4D, 0xE0, 0xD3, 0x94, 0x04, 0x40, 0x05, 0x75,
+0x1F, 0x08, 0x80, 0x17, 0x90, 0x81, 0xAF, 0xE0,
+0x30, 0xE0, 0x0B, 0xC4, 0x54, 0x0F, 0x30, 0xE0,
+0x05, 0x75, 0x1F, 0x11, 0x80, 0x05, 0x12, 0x5F,
+0xC0, 0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74, 0x02,
+0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x1F, 0xF0, 0x7F,
+0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x81,
+0x47, 0xE0, 0x90, 0x06, 0x04, 0x20, 0xE0, 0x07,
+0xE0, 0x44, 0x40, 0xF1, 0x9B, 0x80, 0x0F, 0x31,
+0xC9, 0x90, 0x05, 0x27, 0xE0, 0x54, 0x7F, 0xF0,
+0x90, 0x81, 0x45, 0x74, 0x0C, 0xF0, 0xE4, 0xFB,
+0xFD, 0x7F, 0xFF, 0x80, 0x30, 0x90, 0x81, 0x47,
+0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x04, 0x31, 0xCD,
+0x80, 0x15, 0x12, 0x77, 0xE3, 0xE0, 0x44, 0x80,
+0xF1, 0x9B, 0x90, 0x05, 0x27, 0xE0, 0x44, 0x80,
+0xF0, 0x90, 0x81, 0x45, 0x74, 0x04, 0xF0, 0xE4,
+0xFB, 0xFD, 0x7F, 0xFF, 0x80, 0x07, 0xB1, 0x70,
+0xE4, 0xFB, 0xFD, 0x7F, 0xFF, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x05, 0x22, 0xED,
+0xF0, 0x90, 0x80, 0x40, 0xEB, 0xF0, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0x12, 0x47, 0x6A, 0x70, 0x29,
+0x90, 0x81, 0x47, 0xE0, 0x54, 0xFD, 0xF0, 0x7B,
+0x2C, 0x12, 0x76, 0x0F, 0x7D, 0x08, 0x7F, 0x01,
+0xD1, 0xC0, 0xBF, 0x01, 0x0F, 0x90, 0x81, 0x46,
+0xE0, 0x44, 0x80, 0xF0, 0x7D, 0x0E, 0xD1, 0x28,
+0x74, 0x0E, 0xF0, 0x22, 0x12, 0x73, 0x4E, 0x04,
+0xF0, 0x22, 0x12, 0x77, 0xDB, 0xB1, 0x10, 0x7D,
+0x0C, 0x7F, 0x01, 0x21, 0xD1, 0xB1, 0x0E, 0x31,
+0xCD, 0x90, 0x81, 0x45, 0x74, 0x0C, 0xF0, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
+0x01, 0x01, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x01,
+0x00, 0x74, 0xFF, 0xF0, 0x90, 0x06, 0xB7, 0x74,
+0x09, 0xF0, 0x90, 0x06, 0xB4, 0x74, 0x86, 0xF0,
+0x12, 0x74, 0xB4, 0xEC, 0x54, 0x7F, 0xFC, 0x90,
+0x82, 0x96, 0x12, 0x20, 0xCE, 0x90, 0x82, 0x96,
+0x12, 0x44, 0xE0, 0x12, 0x5E, 0xAB, 0x7F, 0x7C,
+0xF1, 0xA9, 0x12, 0x20, 0xDA, 0xCC, 0xC0, 0x00,
+0xC0, 0x7F, 0x8C, 0xF1, 0xA9, 0x12, 0x20, 0xDA,
+0x00, 0xC0, 0x00, 0x14, 0x12, 0x74, 0xBB, 0x90,
+0x82, 0x7F, 0x12, 0x20, 0xDA, 0x00, 0x03, 0x3E,
+0x60, 0xE4, 0xFD, 0xFF, 0x12, 0x5F, 0x36, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x90, 0x81, 0xAF, 0xE0,
+0x30, 0xE0, 0x13, 0x90, 0x01, 0x57, 0xE4, 0xF0,
+0xB1, 0x0E, 0x12, 0x77, 0xC2, 0x30, 0xE0, 0x02,
+0x31, 0xCD, 0x12, 0x57, 0x7A, 0xF0, 0x22, 0xEF,
+0x60, 0x35, 0x12, 0x47, 0x6A, 0x70, 0x30, 0x90,
+0x81, 0x47, 0xE0, 0x54, 0xFE, 0xF0, 0x7B, 0x2B,
+0x7D, 0x0F, 0x7F, 0xFF, 0xB1, 0x15, 0x90, 0x06,
+0x04, 0xE0, 0x54, 0xBF, 0xF0, 0xD1, 0xBC, 0xBF,
+0x01, 0x0F, 0x90, 0x81, 0x46, 0xE0, 0x44, 0x40,
+0xF0, 0x7D, 0x06, 0xD1, 0x28, 0x74, 0x06, 0xF0,
+0x22, 0x12, 0x73, 0x4E, 0x74, 0x08, 0xF0, 0x22,
+0x7F, 0x01, 0x31, 0xD1, 0x90, 0x81, 0x45, 0x22,
+0x7B, 0x2F, 0xF1, 0x95, 0x12, 0x73, 0x88, 0x7D,
+0x08, 0xD1, 0x28, 0x74, 0x08, 0xF0, 0x22, 0xEF,
+0x70, 0x3E, 0x7D, 0x78, 0x7F, 0x02, 0x12, 0x54,
+0x7F, 0x7D, 0x02, 0x7F, 0x03, 0x12, 0x54, 0x7F,
+0x7D, 0xC8, 0x7F, 0x02, 0x12, 0x54, 0xD4, 0x12,
+0x47, 0xB7, 0xF0, 0xE4, 0xFF, 0x12, 0x47, 0x72,
+0xEF, 0x70, 0x0C, 0xB1, 0x70, 0xB1, 0x5A, 0x12,
+0x77, 0xEB, 0x54, 0x7F, 0xF0, 0x80, 0x06, 0x7D,
+0x01, 0x7F, 0x0C, 0x71, 0x1C, 0x12, 0x70, 0x7F,
+0x90, 0x06, 0x0A, 0xE0, 0x54, 0xF8, 0xF0, 0x22,
+0x90, 0x01, 0x36, 0x74, 0x78, 0xF0, 0xA3, 0x74,
+0x02, 0xF0, 0x7D, 0x78, 0xFF, 0xF1, 0xBC, 0x7D,
+0x02, 0x7F, 0x03, 0xF1, 0xBC, 0x90, 0x06, 0x0A,
+0xE0, 0x44, 0x07, 0x12, 0x71, 0xAE, 0xE4, 0xFF,
+0x12, 0x47, 0x72, 0xBF, 0x01, 0x11, 0x12, 0x6F,
+0x85, 0xF0, 0x90, 0x81, 0x4E, 0xE0, 0x20, 0xE2,
+0x0A, 0x7D, 0x01, 0x7F, 0x04, 0x61, 0x1C, 0x12,
+0x56, 0x16, 0xF0, 0x22, 0x7D, 0x08, 0xE4, 0xFF,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
+0x82, 0x89, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x90,
+0x80, 0x3E, 0xE0, 0x04, 0xF0, 0x90, 0x04, 0x1D,
+0xE0, 0x60, 0x2C, 0x90, 0x05, 0x22, 0xE0, 0x90,
+0x82, 0x8D, 0xF0, 0x7B, 0x26, 0x12, 0x67, 0xDA,
+0x12, 0x74, 0x49, 0xEF, 0x64, 0x01, 0x70, 0x03,
+0x12, 0x76, 0xE1, 0x90, 0x82, 0x8D, 0xE0, 0xFD,
+0x7B, 0x27, 0xE4, 0xFF, 0xB1, 0x15, 0x90, 0x82,
+0x89, 0xE0, 0xFF, 0xF1, 0x1B, 0x80, 0x0A, 0x90,
+0x82, 0x89, 0xE0, 0xFF, 0xF1, 0x1B, 0x12, 0x76,
+0xE1, 0x12, 0x67, 0x50, 0x7F, 0x01, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x82, 0xB0, 0xEF, 0xF0, 0xC3,
+0x94, 0x02, 0x50, 0x48, 0x90, 0x80, 0x46, 0xE0,
+0xFF, 0x90, 0x04, 0x1C, 0xE0, 0x6F, 0x70, 0x3C,
+0x90, 0x81, 0x4E, 0xE0, 0x64, 0x0E, 0x70, 0x14,
+0x90, 0x82, 0xB0, 0xE0, 0x70, 0x2E, 0x90, 0x81,
+0x46, 0xE0, 0x54, 0x7F, 0xF0, 0x90, 0x06, 0x04,
+0x31, 0xC9, 0x80, 0x1E, 0x90, 0x81, 0x4E, 0xE0,
+0x64, 0x06, 0x70, 0x18, 0x90, 0x82, 0xB0, 0xE0,
+0x60, 0x12, 0x12, 0x77, 0xEB, 0x12, 0x77, 0xE3,
+0xE0, 0x44, 0x80, 0xF0, 0x90, 0x81, 0x4E, 0x74,
+0x04, 0xF0, 0xB1, 0x10, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x12, 0x70, 0x4A, 0x90, 0x81, 0x4E, 0xE0,
+0x64, 0x0C, 0x60, 0x07, 0xE4, 0x71, 0x19, 0xB1,
+0x10, 0xD1, 0xBC, 0x22, 0xB1, 0x0E, 0x90, 0x81,
+0x44, 0x74, 0x01, 0xF0, 0x22, 0x7D, 0xFF, 0x7F,
+0xFF, 0xA1, 0x15, 0xF0, 0x7D, 0x04, 0x7F, 0x01,
+0x21, 0xD1, 0xB1, 0x10, 0x12, 0x74, 0xC2, 0x80,
+0xE5, 0x7E, 0x08, 0x12, 0x2E, 0xA2, 0x90, 0x85,
+0xBB, 0x22, 0x7D, 0x01, 0x7F, 0x02, 0xF1, 0xBC,
+0x7D, 0x02, 0x7F, 0x02, 0x74, 0x3D, 0x2F, 0xF8,
+0xE6, 0x4D, 0xFE, 0xF6, 0x74, 0x30, 0x02, 0x54,
+0x6A, 0x7B, 0x2D, 0xF1, 0x95, 0x12, 0x74, 0x49,
+0x90, 0x01, 0x37, 0x74, 0x02, 0xF0, 0xFD, 0x7F,
+0x03, 0xF1, 0xBC, 0x12, 0x73, 0x88, 0xE4, 0xFD,
+0x7F, 0x01, 0x31, 0xD1, 0xE4, 0x90, 0x81, 0x45,
+0xF0, 0x22, 0x7B, 0x1F, 0x7D, 0x6F, 0x7F, 0xFF,
+0xB1, 0x15, 0x90, 0x05, 0x27, 0xE0, 0x54, 0xBF,
+0xF0, 0x90, 0x81, 0x44, 0x74, 0x04, 0xF0, 0x22,
+0x90, 0x01, 0xC8, 0xE4, 0xF0, 0xA3, 0xF0, 0xA3,
+0xF0, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0xC8, 0x7F,
+0xFF, 0xFE, 0x12, 0x2B, 0x27, 0xBF, 0x01, 0x0A,
+0x90, 0x81, 0xC8, 0xE0, 0x64, 0x03, 0x60, 0x04,
+0x01, 0xB1, 0x01, 0xB9, 0xE4, 0x90, 0x81, 0xCD,
+0xF0, 0x90, 0x81, 0xCD, 0xE0, 0xFF, 0xC3, 0x94,
+0x02, 0x40, 0x02, 0x01, 0xF4, 0xC3, 0x74, 0xFE,
+0x9F, 0xFF, 0xE4, 0x94, 0x00, 0xFE, 0x7B, 0x01,
+0x7A, 0x81, 0x79, 0xC9, 0x12, 0x2B, 0x27, 0xEF,
+0x64, 0x01, 0x70, 0x6D, 0x90, 0x81, 0xC9, 0xE0,
+0xFF, 0x54, 0xC0, 0xFE, 0x60, 0x05, 0xEF, 0x54,
+0x0C, 0x70, 0x16, 0x90, 0x81, 0xC9, 0xE0, 0xFF,
+0x54, 0x30, 0x60, 0x5D, 0xEF, 0x54, 0x03, 0x60,
+0x58, 0x90, 0x81, 0xCA, 0x74, 0x01, 0xF0, 0x80,
+0x05, 0xE4, 0x90, 0x81, 0xCA, 0xF0, 0x90, 0x81,
+0xCA, 0xE0, 0x90, 0x81, 0xC9, 0x70, 0x16, 0xE0,
+0xFF, 0xEE, 0x13, 0x13, 0x54, 0x3F, 0x90, 0x81,
+0xCB, 0xF0, 0xEF, 0x54, 0x0C, 0x13, 0x13, 0x54,
+0x3F, 0xA3, 0xF0, 0x80, 0x0D, 0xE0, 0xFE, 0x54,
+0x30, 0x90, 0x81, 0xCB, 0xF0, 0xEE, 0x54, 0x03,
+0xA3, 0xF0, 0x90, 0x81, 0xCC, 0xE0, 0xB4, 0x01,
+0x08, 0x90, 0x81, 0xCB, 0xE0, 0x64, 0x30, 0x60,
+0x43, 0x90, 0x81, 0xCF, 0x74, 0x02, 0xF0, 0x80,
+0x10, 0x90, 0x81, 0xCF, 0x74, 0x01, 0xF0, 0x80,
+0x08, 0x90, 0x81, 0xCD, 0xE0, 0x04, 0xF0, 0x01,
+0x29, 0x90, 0x01, 0xC4, 0x74, 0x00, 0xF0, 0x74,
+0x50, 0xA3, 0xF0, 0x90, 0x81, 0xCF, 0xE0, 0x90,
+0x01, 0xC8, 0xF0, 0x90, 0x81, 0xC9, 0xE0, 0x90,
+0x01, 0xC9, 0xF0, 0x90, 0x81, 0xCA, 0xE0, 0x90,
+0x01, 0xCA, 0xF0, 0xE4, 0xFD, 0x7F, 0x1F, 0x12,
+0x32, 0x1E, 0x80, 0xD5, 0x22, 0x90, 0x00, 0x80,
+0xE0, 0x44, 0x80, 0xFD, 0x7F, 0x80, 0x12, 0x32,
+0x1E, 0x90, 0xFD, 0x00, 0xE0, 0x54, 0xBF, 0xF0,
+0x11, 0x00, 0x12, 0x6D, 0xEF, 0x12, 0x32, 0x77,
+0x12, 0x6D, 0xFC, 0x31, 0x52, 0x7F, 0x01, 0x12,
+0x42, 0x15, 0x90, 0x81, 0xBB, 0x74, 0x02, 0xF0,
+0xFF, 0x12, 0x42, 0x15, 0x90, 0x81, 0xBB, 0xE0,
+0x04, 0xF0, 0x12, 0x58, 0x0A, 0x31, 0x63, 0x90,
+0x01, 0xCC, 0x74, 0x0F, 0xF0, 0x90, 0x00, 0x80,
+0xE0, 0x44, 0x40, 0xFD, 0x7F, 0x80, 0x12, 0x32,
+0x1E, 0x75, 0x20, 0xFF, 0x12, 0x59, 0x2F, 0x12,
+0x5F, 0x67, 0x12, 0x6E, 0x53, 0xE4, 0xFF, 0x02,
+0x42, 0x9E, 0xE4, 0x90, 0x80, 0x3C, 0x31, 0x5B,
+0xA3, 0xF0, 0x22, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0,
+0xA3, 0xF0, 0x22, 0x31, 0x76, 0x12, 0x6C, 0x9C,
+0x31, 0xB8, 0x12, 0x4A, 0x39, 0x12, 0x76, 0x63,
+0x12, 0x77, 0x9C, 0x02, 0x45, 0x55, 0xE4, 0xFD,
+0xFF, 0x12, 0x77, 0xB6, 0xED, 0x70, 0x13, 0x12,
+0x47, 0xC2, 0xC0, 0x83, 0xC0, 0x82, 0x31, 0xB0,
+0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5E,
+0x80, 0x10, 0x12, 0x47, 0xC2, 0xC0, 0x83, 0xC0,
+0x82, 0x31, 0xB0, 0x80, 0x02, 0xC3, 0x33, 0xD8,
+0xFC, 0x4E, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0x12,
+0x6C, 0xFC, 0x90, 0x81, 0x40, 0xEF, 0xF0, 0x22,
+0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x22,
+0x7E, 0x00, 0x7F, 0x01, 0x7D, 0x00, 0x7B, 0x01,
+0x7A, 0x81, 0x79, 0x41, 0x12, 0x45, 0x55, 0x90,
+0x81, 0x41, 0xE0, 0x54, 0xFD, 0xF0, 0xE4, 0x31,
+0x5C, 0xA3, 0x74, 0x0C, 0xF0, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8B, 0x54, 0x8A,
+0x55, 0x89, 0x56, 0x90, 0x05, 0x27, 0xE0, 0xF5,
+0x57, 0x8B, 0x13, 0x8A, 0x14, 0x89, 0x15, 0x75,
+0x16, 0x01, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0x41,
+0x12, 0x2B, 0xED, 0x12, 0x77, 0xD2, 0xFF, 0xC3,
+0x13, 0x20, 0xE0, 0x02, 0x41, 0x94, 0x90, 0x81,
+0x41, 0xE0, 0x30, 0xE0, 0x73, 0x91, 0x5C, 0x75,
+0x57, 0x21, 0x90, 0x81, 0x41, 0xE0, 0x13, 0x13,
+0x54, 0x3F, 0x30, 0xE0, 0x07, 0x91, 0x50, 0x43,
+0x57, 0x08, 0x80, 0x0C, 0xE4, 0x90, 0x81, 0x42,
+0xF0, 0xA3, 0xF0, 0x7D, 0x40, 0xFF, 0x91, 0x7F,
+0x90, 0x81, 0x41, 0x91, 0x31, 0x30, 0xE0, 0x03,
+0x43, 0x57, 0x12, 0xEF, 0xC4, 0x54, 0x0F, 0x30,
+0xE0, 0x03, 0x43, 0x57, 0x14, 0x90, 0x81, 0x41,
+0xE0, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0, 0x03,
+0x43, 0x57, 0x80, 0x12, 0x76, 0xD7, 0x20, 0xE0,
+0x03, 0x43, 0x57, 0x40, 0x71, 0x41, 0x90, 0x81,
+0x44, 0xE0, 0x70, 0x04, 0x7F, 0x01, 0x71, 0x48,
+0x91, 0x39, 0x30, 0xE0, 0x04, 0x7F, 0x04, 0x80,
+0x0B, 0x91, 0x44, 0xEF, 0x60, 0x04, 0x7F, 0x01,
+0x80, 0x02, 0x7F, 0x02, 0x71, 0x48, 0x61, 0x09,
+0x75, 0x57, 0x01, 0x71, 0x41, 0x90, 0x81, 0x44,
+0xE0, 0x64, 0x04, 0x60, 0x02, 0x61, 0x3C, 0xFF,
+0x71, 0x48, 0x61, 0x3C, 0x90, 0x81, 0x41, 0xE0,
+0x30, 0xE0, 0x76, 0x91, 0x5C, 0x43, 0x57, 0x31,
+0x90, 0x81, 0x41, 0xE0, 0x13, 0x13, 0x54, 0x3F,
+0x30, 0xE0, 0x07, 0x91, 0x50, 0x43, 0x57, 0x08,
+0x80, 0x06, 0x7D, 0x40, 0xE4, 0xFF, 0x91, 0x7F,
+0x90, 0x81, 0x41, 0x91, 0x31, 0x30, 0xE0, 0x03,
+0x43, 0x57, 0x02, 0xEF, 0xC4, 0x54, 0x0F, 0x30,
+0xE0, 0x03, 0x43, 0x57, 0x04, 0x71, 0x41, 0x91,
+0x39, 0x30, 0xE0, 0x0A, 0xF1, 0x5B, 0x60, 0x31,
+0xE4, 0xFD, 0x7F, 0x02, 0x80, 0x1E, 0x12, 0x74,
+0xC2, 0x90, 0x81, 0x45, 0xE0, 0xB4, 0x02, 0x19,
+0x12, 0x74, 0xD4, 0x91, 0x44, 0xBF, 0x01, 0x09,
+0x90, 0x81, 0x4D, 0xE0, 0xFF, 0x7D, 0x01, 0x80,
+0x03, 0xE4, 0xFD, 0xFF, 0x12, 0x4B, 0x1C, 0x80,
+0x08, 0x90, 0x81, 0x4E, 0xE0, 0x90, 0x81, 0x45,
+0xF0, 0x90, 0x05, 0x40, 0x74, 0x22, 0xF0, 0x80,
+0x2B, 0x75, 0x57, 0x01, 0x71, 0x41, 0x90, 0x81,
+0x45, 0xE0, 0xB4, 0x02, 0x06, 0x7D, 0x01, 0x7F,
+0x04, 0x80, 0x0B, 0x90, 0x81, 0x45, 0xE0, 0xB4,
+0x08, 0x07, 0x7D, 0x01, 0x7F, 0x0C, 0x12, 0x4B,
+0x1C, 0x12, 0x75, 0xA7, 0x90, 0x81, 0x4D, 0x12,
+0x47, 0xF3, 0x31, 0xB8, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x90, 0x05, 0x27, 0xE5, 0x57, 0xF0, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
+0x81, 0x44, 0xE0, 0xF5, 0x5A, 0xE5, 0x5A, 0x6F,
+0x70, 0x02, 0x81, 0x29, 0xEF, 0x14, 0x60, 0x38,
+0x14, 0x60, 0x5A, 0x14, 0x60, 0x7B, 0x14, 0x70,
+0x02, 0x81, 0x05, 0x24, 0x04, 0x60, 0x02, 0x81,
+0x29, 0xE5, 0x5A, 0xB4, 0x04, 0x04, 0xF1, 0xC0,
+0x81, 0x29, 0xE5, 0x5A, 0xB4, 0x02, 0x04, 0xF1,
+0xC5, 0x81, 0x29, 0xE5, 0x5A, 0xB4, 0x03, 0x04,
+0xF1, 0xCA, 0x81, 0x29, 0xE5, 0x5A, 0x64, 0x01,
+0x60, 0x02, 0x81, 0x29, 0xF1, 0xB7, 0x81, 0x29,
+0xE5, 0x5A, 0xB4, 0x04, 0x05, 0x12, 0x4F, 0xA2,
+0x81, 0x29, 0xE5, 0x5A, 0xB4, 0x02, 0x05, 0x12,
+0x4F, 0x8C, 0x80, 0x7D, 0xE5, 0x5A, 0xB4, 0x03,
+0x04, 0xF1, 0xCE, 0x80, 0x74, 0xE5, 0x5A, 0x70,
+0x70, 0xF1, 0x97, 0x80, 0x6C, 0xE5, 0x5A, 0xB4,
+0x04, 0x05, 0x12, 0x74, 0x3D, 0x80, 0x62, 0xE5,
+0x5A, 0xB4, 0x01, 0x04, 0xF1, 0xA1, 0x80, 0x59,
+0xE5, 0x5A, 0xB4, 0x03, 0x04, 0xF1, 0xDD, 0x80,
+0x50, 0xE5, 0x5A, 0x70, 0x4C, 0xF1, 0x9F, 0x80,
+0x48, 0xE5, 0x5A, 0xB4, 0x04, 0x05, 0x12, 0x74,
+0xCA, 0x80, 0x3E, 0xE5, 0x5A, 0xB4, 0x01, 0x04,
+0xF1, 0x87, 0x80, 0x35, 0xE5, 0x5A, 0xB4, 0x02,
+0x04, 0xF1, 0xAA, 0x80, 0x2C, 0xE5, 0x5A, 0x70,
+0x28, 0xF1, 0x93, 0x80, 0x24, 0xE5, 0x5A, 0xB4,
+0x03, 0x05, 0x12, 0x76, 0xB8, 0x80, 0x1A, 0xE5,
+0x5A, 0xB4, 0x01, 0x05, 0x12, 0x4F, 0xEA, 0x80,
+0x10, 0xE5, 0x5A, 0xB4, 0x02, 0x05, 0x12, 0x76,
+0xB0, 0x80, 0x06, 0xE5, 0x5A, 0x70, 0x02, 0xF1,
+0x9A, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x81,
+0x47, 0xE0, 0xFF, 0x13, 0x13, 0x13, 0x54, 0x1F,
+0x22, 0x90, 0x81, 0x41, 0xE0, 0xFF, 0xC4, 0x13,
+0x13, 0x54, 0x03, 0x22, 0x90, 0x05, 0x43, 0xE0,
+0x7F, 0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01, 0x22,
+0x90, 0x01, 0x34, 0x74, 0x40, 0xF0, 0xFD, 0xE4,
+0xFF, 0x02, 0x4F, 0xBC, 0x7D, 0x03, 0x7F, 0x02,
+0x74, 0x45, 0x2F, 0xF8, 0xE6, 0x4D, 0xFE, 0xF6,
+0x74, 0x38, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x01,
+0xF5, 0x83, 0xEE, 0xF0, 0x22, 0x7D, 0x02, 0x7F,
+0x02, 0x91, 0x7F, 0x7D, 0x01, 0x7F, 0x02, 0x74,
+0x3D, 0xF1, 0xAF, 0xFE, 0xF6, 0x74, 0x30, 0x80,
+0xE1, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0xB1, 0xC4, 0xEF, 0x64, 0x01, 0x70, 0x1B, 0x90,
+0x81, 0xB9, 0xE0, 0x7D, 0x10, 0x7F, 0x03, 0x60,
+0x08, 0x91, 0x60, 0x12, 0x72, 0xD5, 0xF0, 0x80,
+0x04, 0x91, 0xD4, 0x91, 0x75, 0x12, 0x4E, 0x30,
+0x80, 0x1D, 0x90, 0x81, 0xB9, 0xE0, 0x7D, 0x10,
+0x7F, 0x03, 0x60, 0x04, 0x91, 0x60, 0x80, 0x02,
+0x91, 0xD4, 0x12, 0x4F, 0xB8, 0x7D, 0x01, 0x7F,
+0x02, 0x12, 0x4F, 0xBC, 0x12, 0x4D, 0x65, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x74, 0x45, 0xF1, 0xAF,
+0x80, 0x8C, 0x90, 0x05, 0x62, 0xE0, 0xFE, 0x90,
+0x05, 0x61, 0xE0, 0xFD, 0xED, 0x78, 0x02, 0xCE,
+0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90,
+0x81, 0xBF, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x12,
+0x47, 0x6A, 0x60, 0x02, 0xA1, 0xB7, 0x90, 0x81,
+0x4B, 0xE0, 0x70, 0x02, 0xA1, 0xB7, 0x90, 0x81,
+0x49, 0xE0, 0xFF, 0xC4, 0x54, 0x0F, 0x64, 0x01,
+0x70, 0x22, 0x90, 0x06, 0xAB, 0xE0, 0x90, 0x81,
+0x52, 0xF0, 0x90, 0x06, 0xAA, 0xE0, 0x90, 0x81,
+0x51, 0xF0, 0xA3, 0xE0, 0xFF, 0x70, 0x08, 0x90,
+0x81, 0x51, 0xE0, 0xFE, 0xFF, 0x80, 0x00, 0x90,
+0x81, 0x52, 0xEF, 0xF0, 0xE4, 0x90, 0x81, 0x54,
+0xF0, 0xA3, 0x12, 0x71, 0xAE, 0x12, 0x47, 0xB7,
+0x12, 0x6F, 0x99, 0x54, 0xEF, 0xF0, 0x90, 0x81,
+0x41, 0xE0, 0x30, 0xE0, 0x05, 0x12, 0x65, 0x39,
+0x80, 0x03, 0x12, 0x65, 0xAA, 0x91, 0x2E, 0x30,
+0xE0, 0x5A, 0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03,
+0x20, 0xE0, 0x23, 0xD1, 0x1D, 0x6F, 0x70, 0x4C,
+0x90, 0x81, 0x47, 0xE0, 0x44, 0x40, 0xF0, 0x12,
+0x72, 0xDD, 0xF0, 0xB1, 0xC4, 0xFD, 0x7F, 0x03,
+0x91, 0x60, 0x91, 0x7B, 0xF1, 0x81, 0x90, 0x81,
+0x52, 0xE0, 0x14, 0xF0, 0x80, 0x2E, 0x90, 0x81,
+0x49, 0xE0, 0xC4, 0x54, 0x0F, 0x64, 0x01, 0x70,
+0x23, 0xD1, 0x1D, 0xFE, 0x6F, 0x60, 0x1D, 0x90,
+0x05, 0x73, 0xE0, 0xFF, 0xEE, 0x6F, 0x60, 0x14,
+0x12, 0x6F, 0x8C, 0x30, 0xE0, 0x0E, 0xEF, 0x54,
+0xBF, 0xF0, 0xB1, 0xC4, 0xFD, 0x7F, 0x03, 0x91,
+0xD4, 0x12, 0x4F, 0xB2, 0xD1, 0x16, 0xF0, 0x90,
+0x81, 0x41, 0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x03,
+0xD1, 0x16, 0xF0, 0x22, 0x90, 0x01, 0x3F, 0x74,
+0x10, 0xF0, 0x22, 0x90, 0x81, 0x41, 0xE0, 0x30,
+0xE0, 0x06, 0x90, 0x81, 0x43, 0x74, 0x01, 0xF0,
+0x90, 0x81, 0x4B, 0xE0, 0x60, 0x25, 0x91, 0x2E,
+0x30, 0xE0, 0x09, 0x90, 0x01, 0x3B, 0xE0, 0x30,
+0xE4, 0x02, 0x91, 0x75, 0x90, 0x82, 0xAB, 0xE0,
+0x04, 0xF0, 0xE0, 0xC3, 0x94, 0x80, 0x40, 0x0B,
+0x90, 0x01, 0x98, 0xE0, 0x54, 0xFE, 0xF0, 0xE0,
+0x44, 0x01, 0xF0, 0xD1, 0x25, 0x90, 0x81, 0xB7,
+0xE0, 0x30, 0xE0, 0x09, 0x90, 0x01, 0x3B, 0xE0,
+0x30, 0xE4, 0x02, 0x91, 0x75, 0x22, 0x90, 0x81,
+0x47, 0xE0, 0x44, 0x04, 0x22, 0x90, 0x81, 0x51,
+0xE0, 0xFF, 0xA3, 0xE0, 0x22, 0x90, 0x81, 0xAF,
+0xE0, 0x30, 0xE0, 0x0C, 0xE4, 0xF5, 0x1D, 0x90,
+0x81, 0xB1, 0x12, 0x49, 0x07, 0xF1, 0x7A, 0xF0,
+0x90, 0x80, 0x42, 0xE0, 0xB4, 0x01, 0x13, 0x90,
+0x81, 0xAF, 0x91, 0x31, 0x20, 0xE0, 0x0B, 0xEF,
+0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0, 0x03, 0x12,
+0x76, 0x74, 0x22, 0x12, 0x77, 0xC9, 0xFF, 0x54,
+0x01, 0xFE, 0x90, 0x81, 0xAF, 0xF1, 0xE1, 0xFF,
+0xF0, 0x12, 0x1F, 0xA4, 0xFE, 0x54, 0x04, 0xFD,
+0xEF, 0x54, 0xFB, 0x4D, 0xFF, 0x90, 0x81, 0xAF,
+0xF0, 0xEE, 0x54, 0x08, 0xFE, 0xEF, 0x54, 0xF7,
+0x4E, 0xFF, 0xF0, 0x12, 0x1F, 0xA4, 0x54, 0x10,
+0x25, 0xE0, 0x25, 0xE0, 0xFE, 0xEF, 0x54, 0xBF,
+0x4E, 0x90, 0x81, 0xAF, 0xF0, 0x90, 0x05, 0x52,
+0xE0, 0x54, 0x07, 0xFF, 0x90, 0x82, 0x3B, 0x60,
+0x15, 0x12, 0x45, 0x1D, 0xF1, 0x31, 0xFD, 0x90,
+0x05, 0x56, 0xE0, 0xC3, 0x9D, 0x90, 0x81, 0xB1,
+0xF0, 0xA3, 0xED, 0xF0, 0x80, 0x25, 0x12, 0x45,
+0x1D, 0xF1, 0x31, 0xFB, 0xFF, 0x90, 0x05, 0x54,
+0xE0, 0xC3, 0x9F, 0xFF, 0xE4, 0x94, 0x00, 0xFE,
+0x7C, 0x00, 0x7D, 0x05, 0x12, 0x20, 0x30, 0x90,
+0x81, 0xB1, 0xEF, 0xF0, 0xEB, 0x75, 0xF0, 0x05,
+0x84, 0xA3, 0xF0, 0x90, 0x82, 0x3B, 0x12, 0x45,
+0x1D, 0x12, 0x1F, 0xA4, 0x20, 0xE0, 0x0A, 0x12,
+0x4D, 0x0E, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x80,
+0x06, 0x12, 0x49, 0xCD, 0xF1, 0x7A, 0xF0, 0x90,
+0x81, 0xAF, 0x91, 0x31, 0x20, 0xE0, 0x04, 0xEF,
+0x44, 0x20, 0xF0, 0x12, 0x77, 0xC2, 0x30, 0xE0,
+0x17, 0x90, 0x81, 0x4B, 0x74, 0x01, 0xF0, 0xE4,
+0x90, 0x81, 0x4D, 0xF0, 0xD1, 0x16, 0xF0, 0x12,
+0x71, 0xB9, 0x74, 0x06, 0xF0, 0x02, 0x70, 0xD7,
+0xE4, 0x90, 0x81, 0x4B, 0xF0, 0x90, 0x81, 0x4D,
+0x74, 0x0C, 0xF0, 0x90, 0x81, 0x46, 0xE0, 0x54,
+0xFE, 0xF0, 0xA3, 0xE0, 0x54, 0xFB, 0xF0, 0x22,
+0xF0, 0x90, 0x00, 0x01, 0x02, 0x1F, 0xBD, 0x12,
+0x1F, 0xA4, 0xFF, 0x54, 0x01, 0xFE, 0x90, 0x81,
+0xB7, 0xF1, 0xE1, 0xF1, 0x30, 0x90, 0x81, 0xB8,
+0x12, 0x64, 0x74, 0x90, 0x81, 0xB9, 0xF0, 0x12,
+0x72, 0xE5, 0x90, 0x81, 0xB7, 0xE0, 0x54, 0x01,
+0xFF, 0x81, 0x89, 0x90, 0x81, 0x45, 0xE0, 0x64,
+0x02, 0x22, 0x91, 0x39, 0x30, 0xE0, 0x0B, 0xF1,
+0x5B, 0x60, 0x07, 0x7D, 0x01, 0x7F, 0x02, 0x12,
+0x4B, 0x1C, 0xF1, 0x5B, 0x60, 0x03, 0x12, 0x67,
+0x5F, 0x22, 0x90, 0x81, 0xAF, 0xE0, 0x44, 0x10,
+0x22, 0x7D, 0x02, 0x7F, 0x02, 0x81, 0x7F, 0x7B,
+0x21, 0x12, 0x4F, 0x95, 0x90, 0x81, 0x44, 0x74,
+0x03, 0xF0, 0x22, 0xF1, 0x97, 0x80, 0xF0, 0x02,
+0x4F, 0x8E, 0xF1, 0x97, 0x02, 0x4F, 0xEA, 0xF1,
+0x97, 0x7B, 0x20, 0x12, 0x4F, 0x95, 0xF1, 0xD4,
+0xF0, 0x22, 0x12, 0x4D, 0x70, 0x80, 0xDD, 0x2F,
+0xF8, 0xE6, 0xFE, 0xED, 0xF4, 0x5E, 0x22, 0x12,
+0x76, 0x16, 0xE4, 0x90, 0x81, 0x44, 0xF0, 0x22,
+0x12, 0x4F, 0xA2, 0x80, 0xF2, 0x12, 0x4F, 0x8C,
+0x80, 0xED, 0xF1, 0xCE, 0x80, 0xE9, 0x12, 0x4D,
+0x10, 0x02, 0x4F, 0x8E, 0x12, 0x73, 0x88, 0x90,
+0x81, 0x44, 0x74, 0x02, 0x22, 0xF1, 0xD4, 0xF0,
+0x22, 0xE0, 0x54, 0xFE, 0x4E, 0xFE, 0xF0, 0xEF,
+0x54, 0x02, 0xFF, 0xEE, 0x54, 0xFD, 0x4F, 0x22,
+0x90, 0x00, 0xF7, 0xE0, 0x20, 0xE7, 0x09, 0xE0,
+0x7F, 0x01, 0x20, 0xE6, 0x0C, 0x7F, 0x02, 0x22,
+0x90, 0x00, 0xF7, 0xE0, 0x30, 0xE6, 0x02, 0x7F,
+0x03, 0x22, 0x12, 0x57, 0xF0, 0x90, 0x80, 0x42,
+0xEF, 0xF0, 0x11, 0x2B, 0x90, 0x01, 0x64, 0x74,
+0x01, 0xF0, 0x90, 0x00, 0x12, 0xE0, 0x54, 0xC7,
+0x44, 0x20, 0xFD, 0x7F, 0x12, 0x12, 0x32, 0x1E,
+0x02, 0x2D, 0xA7, 0x90, 0x00, 0x08, 0xE0, 0x54,
+0xEF, 0xF0, 0x11, 0xA3, 0x11, 0xCB, 0x11, 0x62,
+0x11, 0x81, 0xE4, 0xF5, 0x35, 0xF5, 0x37, 0xF5,
+0x36, 0xF5, 0x37, 0x75, 0x38, 0x80, 0xAD, 0x35,
+0x7F, 0x50, 0x12, 0x32, 0x1E, 0xAD, 0x36, 0x7F,
+0x51, 0x12, 0x32, 0x1E, 0xAD, 0x37, 0x7F, 0x52,
+0x12, 0x32, 0x1E, 0xAD, 0x38, 0x7F, 0x53, 0x02,
+0x32, 0x1E, 0x75, 0x3D, 0x10, 0xE4, 0xF5, 0x3E,
+0x75, 0x3F, 0x07, 0x75, 0x40, 0x02, 0x90, 0x01,
+0x30, 0xE5, 0x3D, 0xF0, 0xA3, 0xE5, 0x3E, 0xF0,
+0xA3, 0xE5, 0x3F, 0xF0, 0xA3, 0xE5, 0x40, 0xF0,
+0x22, 0x75, 0x45, 0x07, 0x75, 0x46, 0x01, 0x43,
+0x46, 0x10, 0x75, 0x47, 0x03, 0x75, 0x48, 0x62,
+0x90, 0x01, 0x38, 0xE5, 0x45, 0xF0, 0xA3, 0xE5,
+0x46, 0xF0, 0xA3, 0xE5, 0x47, 0xF0, 0xA3, 0xE5,
+0x48, 0xF0, 0x22, 0x90, 0x01, 0x30, 0xE4, 0x12,
+0x51, 0x5B, 0x90, 0x01, 0x38, 0x12, 0x51, 0x5B,
+0xFD, 0x7F, 0x50, 0x12, 0x32, 0x1E, 0xE4, 0xFD,
+0x7F, 0x51, 0x12, 0x32, 0x1E, 0xE4, 0xFD, 0x7F,
+0x52, 0x12, 0x32, 0x1E, 0xE4, 0xFD, 0x7F, 0x53,
+0x02, 0x32, 0x1E, 0x90, 0x01, 0x34, 0x74, 0xFF,
+0x12, 0x51, 0x5B, 0x90, 0x01, 0x3C, 0x12, 0x51,
+0x5B, 0xFD, 0x7F, 0x54, 0x12, 0x32, 0x1E, 0x7D,
+0xFF, 0x7F, 0x55, 0x12, 0x32, 0x1E, 0x7D, 0xFF,
+0x7F, 0x56, 0x12, 0x32, 0x1E, 0x7D, 0xFF, 0x7F,
+0x57, 0x02, 0x32, 0x1E, 0x90, 0x01, 0xCF, 0xE0,
+0x90, 0x82, 0xAC, 0xF0, 0xE0, 0xFF, 0x30, 0xE0,
+0x07, 0x90, 0x01, 0xCF, 0xE0, 0x54, 0xFE, 0xF0,
+0xEF, 0x30, 0xE5, 0x22, 0x90, 0x01, 0xCF, 0xE0,
+0x54, 0xDF, 0xF0, 0x90, 0x01, 0x34, 0x74, 0x20,
+0xF0, 0xE4, 0xF5, 0xA8, 0xF5, 0xE8, 0x11, 0xA3,
+0x90, 0x00, 0x03, 0xE0, 0x54, 0xFB, 0xFD, 0x7F,
+0x03, 0x12, 0x32, 0x1E, 0x80, 0xFE, 0x22, 0x75,
+0xE8, 0x03, 0x75, 0xA8, 0x84, 0x22, 0xE4, 0x90,
+0x81, 0xD0, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90,
+0x81, 0xD0, 0xE0, 0x64, 0x01, 0xF0, 0x24, 0x36,
+0x90, 0x01, 0xC4, 0xF0, 0x74, 0x59, 0xA3, 0xF0,
+0x90, 0x81, 0x4B, 0xE0, 0x60, 0x0F, 0x90, 0x81,
+0x4E, 0xE0, 0xFF, 0x90, 0x81, 0x4D, 0xE0, 0x6F,
+0x60, 0x03, 0x12, 0x47, 0xE4, 0xC2, 0xAF, 0x12,
+0x6E, 0x2C, 0xBF, 0x01, 0x02, 0x31, 0x80, 0xD2,
+0xAF, 0xF1, 0x58, 0x12, 0x32, 0x9E, 0xBF, 0x01,
+0x02, 0x51, 0xE4, 0x12, 0x41, 0x4D, 0x80, 0xBF,
+0x90, 0x81, 0x46, 0xE0, 0x30, 0xE0, 0x18, 0x90,
+0x81, 0x41, 0xE0, 0xFF, 0x30, 0xE0, 0x0E, 0xC3,
+0x13, 0x30, 0xE0, 0x07, 0xF1, 0xC8, 0xBF, 0x01,
+0x06, 0x80, 0x02, 0x80, 0x00, 0x31, 0xA0, 0x22,
+0x90, 0x81, 0x4E, 0xE0, 0xFF, 0x60, 0x03, 0xB4,
+0x08, 0x0D, 0x51, 0x3D, 0xBF, 0x01, 0x08, 0x31,
+0xB8, 0x90, 0x01, 0xE5, 0xE0, 0x04, 0xF0, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x51,
+0x8C, 0x31, 0xC8, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x12, 0x74, 0xE3, 0x90, 0x81, 0x56, 0xE0, 0x20,
+0xE0, 0x0C, 0x90, 0x00, 0x26, 0xE0, 0x54, 0x7F,
+0xFD, 0x7F, 0x26, 0x12, 0x32, 0x1E, 0x90, 0x00,
+0x08, 0xE0, 0x54, 0xEF, 0xFD, 0x7F, 0x08, 0x12,
+0x32, 0x1E, 0xE4, 0xFF, 0x90, 0x81, 0xD3, 0xEF,
+0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x01,
+0x09, 0xE0, 0x7F, 0x00, 0x30, 0xE7, 0x02, 0x7F,
+0x01, 0x90, 0x81, 0xD3, 0xE0, 0x6F, 0x60, 0x34,
+0xC3, 0x90, 0x81, 0xD5, 0xE0, 0x94, 0x88, 0x90,
+0x81, 0xD4, 0xE0, 0x94, 0x13, 0x40, 0x08, 0x90,
+0x01, 0xC0, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0x90,
+0x81, 0xD4, 0xF1, 0x59, 0xF1, 0x60, 0xD3, 0x90,
+0x81, 0xD5, 0xE0, 0x94, 0x32, 0x90, 0x81, 0xD4,
+0xE0, 0x94, 0x00, 0x40, 0xC1, 0x90, 0x01, 0xC6,
+0xE0, 0x30, 0xE0, 0xBA, 0x22, 0x90, 0x81, 0xB7,
+0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x35, 0x90, 0x02,
+0x87, 0xE0, 0x60, 0x02, 0x80, 0x08, 0x90, 0x01,
+0x00, 0xE0, 0x64, 0x3F, 0x60, 0x05, 0x75, 0x51,
+0x01, 0x80, 0x22, 0x90, 0x02, 0x96, 0xE0, 0x60,
+0x05, 0x75, 0x51, 0x10, 0x80, 0x17, 0x90, 0x02,
+0x86, 0xE0, 0x20, 0xE1, 0x02, 0x80, 0x07, 0x90,
+0x02, 0x86, 0xE0, 0x30, 0xE3, 0x05, 0x75, 0x51,
+0x04, 0x80, 0x02, 0xE1, 0xC0, 0x90, 0x01, 0xB9,
+0x74, 0x08, 0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x51,
+0xF0, 0x7F, 0x00, 0x22, 0x90, 0x81, 0x56, 0xE0,
+0xFD, 0x7F, 0x93, 0x12, 0x32, 0x1E, 0x90, 0x81,
+0x4C, 0xE0, 0x60, 0x12, 0x90, 0x01, 0x2F, 0xE0,
+0x30, 0xE7, 0x05, 0x74, 0x10, 0xF0, 0x80, 0x06,
+0x90, 0x01, 0x2F, 0x74, 0x90, 0xF0, 0x90, 0x00,
+0x08, 0xE0, 0x44, 0x10, 0xFD, 0x7F, 0x08, 0x12,
+0x32, 0x1E, 0x7F, 0x01, 0x31, 0xEC, 0x90, 0x81,
+0x56, 0xE0, 0x20, 0xE0, 0x0C, 0x90, 0x00, 0x26,
+0xE0, 0x44, 0x80, 0xFD, 0x7F, 0x26, 0x12, 0x32,
+0x1E, 0x90, 0x00, 0x90, 0xE0, 0x44, 0x01, 0xFD,
+0x7F, 0x90, 0x12, 0x32, 0x1E, 0x7F, 0x14, 0x7E,
+0x00, 0x02, 0x32, 0xAA, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x12, 0x2D, 0xA7, 0xE4, 0xF5,
+0x53, 0x12, 0x32, 0x9E, 0xEF, 0x60, 0x72, 0x63,
+0x53, 0x01, 0xE5, 0x53, 0x24, 0xE4, 0x90, 0x01,
+0xC4, 0xF0, 0x74, 0x5A, 0xA3, 0xF0, 0x90, 0x00,
+0x88, 0xE0, 0xF5, 0x51, 0xF5, 0x52, 0x54, 0x0F,
+0x60, 0xDF, 0xE5, 0x51, 0x30, 0xE0, 0x0B, 0x20,
+0xE4, 0x03, 0x12, 0x29, 0xC5, 0x53, 0x52, 0xEE,
+0x80, 0x3E, 0xE5, 0x51, 0x30, 0xE1, 0x16, 0x20,
+0xE5, 0x0E, 0x12, 0x11, 0xBD, 0xEF, 0x70, 0x03,
+0x43, 0x52, 0x20, 0x90, 0x01, 0x06, 0xE4, 0xF0,
+0x53, 0x52, 0xFD, 0x80, 0x23, 0xE5, 0x51, 0x30,
+0xE2, 0x0B, 0x20, 0xE6, 0x03, 0x12, 0x69, 0x4A,
+0x53, 0x52, 0xFB, 0x80, 0x13, 0xE5, 0x51, 0x30,
+0xE3, 0x0E, 0x20, 0xE7, 0x08, 0x71, 0x6E, 0xEF,
+0x70, 0x03, 0x43, 0x52, 0x80, 0x53, 0x52, 0xF7,
+0xAD, 0x52, 0x7F, 0x88, 0x12, 0x32, 0x1E, 0x80,
+0x88, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x78, 0x10,
+0x74, 0x01, 0xF2, 0x90, 0x02, 0x09, 0xE0, 0x78,
+0x00, 0xF2, 0x08, 0x74, 0x20, 0xF2, 0x18, 0xE2,
+0xFF, 0x30, 0xE0, 0x05, 0x08, 0xE2, 0x24, 0x80,
+0xF2, 0xEF, 0xC3, 0x13, 0x90, 0xFD, 0x10, 0xF0,
+0x78, 0x01, 0xE2, 0xB1, 0x99, 0xE0, 0x78, 0x03,
+0xF2, 0x64, 0x04, 0x60, 0x0D, 0xE2, 0xFF, 0x64,
+0x08, 0x60, 0x07, 0xEF, 0x64, 0x0C, 0x60, 0x02,
+0xA1, 0x8F, 0xE4, 0x78, 0x02, 0xF2, 0x78, 0x03,
+0xE2, 0xFF, 0x18, 0xE2, 0xC3, 0x9F, 0x50, 0x26,
+0xE2, 0xFD, 0x18, 0xE2, 0x2D, 0x90, 0x81, 0xD3,
+0xF0, 0xE0, 0xFF, 0xB1, 0x99, 0xE0, 0xFE, 0x74,
+0x04, 0x2D, 0xF8, 0xEE, 0xF2, 0xEF, 0xB4, 0xFF,
+0x06, 0x90, 0xFD, 0x10, 0xE0, 0x04, 0xF0, 0x78,
+0x02, 0xE2, 0x04, 0xF2, 0x80, 0xD0, 0x78, 0x04,
+0xE2, 0x78, 0x12, 0xF2, 0xFF, 0x78, 0x05, 0xE2,
+0x78, 0x11, 0xF2, 0x78, 0x06, 0xE2, 0x78, 0x13,
+0xF2, 0x78, 0x07, 0xE2, 0x78, 0x14, 0xF2, 0x78,
+0x08, 0xE2, 0x78, 0x33, 0xF2, 0x78, 0x09, 0xE2,
+0x78, 0x34, 0xF2, 0x78, 0x0A, 0xE2, 0x78, 0x35,
+0xF2, 0x78, 0x0B, 0xE2, 0x78, 0x36, 0xF2, 0x78,
+0x0C, 0xE2, 0x78, 0x37, 0xF2, 0x78, 0x0D, 0xE2,
+0x78, 0x38, 0xF2, 0x78, 0x0E, 0xE2, 0x78, 0x39,
+0xF2, 0x78, 0x0F, 0xE2, 0x78, 0x3A, 0xF2, 0xE4,
+0x78, 0x15, 0xF2, 0xEF, 0x24, 0xF8, 0x60, 0x56,
+0x24, 0xFC, 0x60, 0x4D, 0x24, 0x08, 0x60, 0x02,
+0xA1, 0x71, 0x78, 0x11, 0xE2, 0xB4, 0x01, 0x05,
+0x12, 0x29, 0xC5, 0xA1, 0x76, 0x78, 0x11, 0xE2,
+0xB4, 0x02, 0x05, 0x12, 0x11, 0xBD, 0xA1, 0x76,
+0x78, 0x11, 0xE2, 0xB4, 0x03, 0x05, 0x12, 0x69,
+0x4A, 0xA1, 0x76, 0x78, 0x11, 0xE2, 0xB4, 0x10,
+0x07, 0xB1, 0xAF, 0x12, 0x32, 0xAA, 0xA1, 0x76,
+0x78, 0x11, 0xE2, 0xB4, 0x11, 0x07, 0xB1, 0xAF,
+0x12, 0x32, 0x06, 0xA1, 0x76, 0x78, 0x11, 0xE2,
+0xF4, 0x60, 0x02, 0xA1, 0x76, 0x18, 0xF2, 0xA1,
+0x76, 0x78, 0x15, 0x74, 0x01, 0xF2, 0x78, 0x11,
+0xE2, 0x64, 0x07, 0x60, 0x02, 0xA1, 0x5A, 0x78,
+0x34, 0xB1, 0x92, 0x78, 0x08, 0x12, 0x20, 0xBB,
+0xC0, 0x04, 0xB1, 0xA8, 0x78, 0x33, 0xB1, 0x92,
+0xD0, 0x00, 0x12, 0x44, 0xC2, 0xC0, 0x04, 0xC0,
+0x05, 0xC0, 0x06, 0xC0, 0x07, 0x78, 0x35, 0xB1,
+0x92, 0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0, 0x03,
+0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x44,
+0xC2, 0x78, 0x18, 0x12, 0x45, 0x05, 0x78, 0x15,
+0xE2, 0x60, 0x79, 0x18, 0xE2, 0xFF, 0x18, 0xE2,
+0xFD, 0xF1, 0x28, 0x78, 0x1C, 0x12, 0x45, 0x05,
+0x78, 0x38, 0xB1, 0x92, 0x78, 0x08, 0x12, 0x20,
+0xBB, 0xC0, 0x04, 0xB1, 0xA8, 0x78, 0x37, 0xB1,
+0x92, 0xD0, 0x00, 0x12, 0x44, 0xC2, 0xC0, 0x04,
+0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x78, 0x39,
+0xB1, 0x92, 0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12,
+0x44, 0xC2, 0x78, 0x20, 0x12, 0x45, 0x05, 0x78,
+0x20, 0x12, 0x44, 0xEC, 0x12, 0x20, 0x9B, 0x78,
+0x1C, 0x12, 0x44, 0xF8, 0x12, 0x44, 0xB5, 0xC0,
+0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x78,
+0x18, 0x12, 0x44, 0xEC, 0x78, 0x20, 0x12, 0x44,
+0xF8, 0x12, 0x44, 0xB5, 0xD0, 0x03, 0xD0, 0x02,
+0xD0, 0x01, 0xD0, 0x00, 0x12, 0x44, 0xC2, 0x78,
+0x18, 0x12, 0x45, 0x05, 0x78, 0x18, 0x12, 0x44,
+0xEC, 0x90, 0x82, 0x7F, 0x12, 0x20, 0xCE, 0x78,
+0x13, 0xE2, 0xFD, 0x08, 0xE2, 0xFF, 0xF1, 0x36,
+0x80, 0x1C, 0x78, 0x13, 0xE2, 0xFF, 0x08, 0xE2,
+0xFD, 0x78, 0x11, 0xE2, 0xFB, 0x78, 0x15, 0xE2,
+0x90, 0x82, 0x35, 0xF0, 0x12, 0x67, 0xE1, 0x80,
+0x05, 0x78, 0x10, 0x74, 0x02, 0xF2, 0x78, 0x10,
+0xE2, 0xFF, 0xC3, 0x94, 0x02, 0x50, 0x10, 0xEF,
+0x60, 0x0A, 0x78, 0x02, 0xE2, 0xFF, 0x18, 0xE2,
+0x2F, 0xF2, 0x61, 0x90, 0x7F, 0x01, 0x22, 0x7F,
+0x00, 0x22, 0xE2, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE,
+0x22, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0xFC,
+0xF5, 0x83, 0x22, 0x12, 0x20, 0xBB, 0xA8, 0x04,
+0xA9, 0x05, 0xAA, 0x06, 0xAB, 0x07, 0x22, 0x78,
+0x14, 0xE2, 0xFE, 0x18, 0xE2, 0xFD, 0xED, 0xFF,
+0x78, 0x16, 0xEE, 0xF2, 0xFE, 0x08, 0xEF, 0xF2,
+0xFF, 0x22, 0x90, 0x82, 0x55, 0xEF, 0xF0, 0xA3,
+0xED, 0xF0, 0xA3, 0x12, 0x20, 0xDA, 0x00, 0x00,
+0x00, 0x00, 0xE4, 0x90, 0x82, 0x63, 0xF0, 0x7F,
+0x24, 0x7E, 0x08, 0x12, 0x2D, 0x5C, 0x90, 0x82,
+0x5B, 0x12, 0x20, 0xCE, 0x90, 0x82, 0x55, 0xE0,
+0xFB, 0x70, 0x04, 0xD1, 0xA4, 0x80, 0x06, 0xEB,
+0xD1, 0xB1, 0x12, 0x2D, 0x5C, 0x90, 0x82, 0x5F,
+0x12, 0x20, 0xCE, 0x90, 0x82, 0x56, 0x12, 0x6C,
+0x21, 0x78, 0x17, 0xB1, 0xA3, 0x90, 0x82, 0x5F,
+0x12, 0x44, 0xE0, 0xED, 0x54, 0x7F, 0xFD, 0xEC,
+0x54, 0x80, 0xFC, 0x12, 0x44, 0xC2, 0xEC, 0x44,
+0x80, 0xFC, 0x90, 0x82, 0x5F, 0x12, 0x20, 0xCE,
+0xD1, 0xA4, 0xEC, 0x54, 0x7F, 0xD1, 0xAA, 0xD1,
+0xC4, 0xD1, 0xB1, 0xC0, 0x06, 0xC0, 0x07, 0x90,
+0x82, 0x5F, 0x12, 0x44, 0xE0, 0xD1, 0xAB, 0xD0,
+0x07, 0xD0, 0x06, 0x12, 0x2E, 0xA2, 0xD1, 0xA4,
+0xEC, 0x44, 0x80, 0xD1, 0xAA, 0xD1, 0xC4, 0x70,
+0x04, 0x7F, 0x20, 0x80, 0x09, 0x90, 0x82, 0x55,
+0xE0, 0xB4, 0x01, 0x16, 0x7F, 0x28, 0x7E, 0x08,
+0x12, 0x2D, 0x5C, 0x78, 0x08, 0x12, 0x20, 0xA8,
+0xEF, 0x54, 0x01, 0xFF, 0xE4, 0x90, 0x82, 0x63,
+0xEF, 0xF0, 0x90, 0x82, 0x63, 0xE0, 0x90, 0x82,
+0x55, 0x60, 0x0E, 0xE0, 0x75, 0xF0, 0x08, 0xA4,
+0x24, 0x66, 0xF5, 0x82, 0xE4, 0x34, 0x87, 0x80,
+0x0C, 0xE0, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x64,
+0xF5, 0x82, 0xE4, 0x34, 0x87, 0xD1, 0xBC, 0x12,
+0x2D, 0x5C, 0xED, 0x54, 0x0F, 0xFD, 0xE4, 0xFC,
+0x90, 0x82, 0x57, 0x12, 0x20, 0xCE, 0x90, 0x82,
+0x57, 0x02, 0x44, 0xE0, 0x90, 0x82, 0x5B, 0x02,
+0x44, 0xE0, 0xFC, 0x90, 0x85, 0xBB, 0x02, 0x20,
+0xCE, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x62, 0xF5,
+0x82, 0xE4, 0x34, 0x87, 0xF5, 0x83, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0x22, 0x7F, 0x24, 0x7E, 0x08,
+0x12, 0x2E, 0xA2, 0x90, 0x82, 0x55, 0xE0, 0x22,
+0x90, 0x82, 0x73, 0xEF, 0xF0, 0xAB, 0x05, 0x90,
+0x82, 0x79, 0x12, 0x20, 0xDA, 0x00, 0x00, 0x00,
+0x00, 0xAF, 0x03, 0xE4, 0xFC, 0xFD, 0xFE, 0x78,
+0x14, 0xB1, 0xA3, 0x90, 0x82, 0x75, 0x12, 0x44,
+0xE0, 0xED, 0x54, 0x0F, 0xFD, 0xE4, 0xFC, 0x12,
+0x44, 0xC2, 0xEC, 0x54, 0x0F, 0xFC, 0x90, 0x82,
+0x79, 0x12, 0x20, 0xCE, 0x90, 0x82, 0x73, 0xE0,
+0x75, 0xF0, 0x08, 0xA4, 0x24, 0x60, 0xF5, 0x82,
+0xE4, 0x34, 0x87, 0xD1, 0xBC, 0xC0, 0x06, 0xC0,
+0x07, 0x90, 0x82, 0x79, 0x12, 0x44, 0xE0, 0xD1,
+0xAB, 0xD0, 0x07, 0xD0, 0x06, 0x02, 0x2E, 0xA2,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xB1,
+0xC2, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xC0, 0x07, 0xC0,
+0x05, 0x90, 0x82, 0x7F, 0x12, 0x44, 0xE0, 0x90,
+0x82, 0x75, 0x12, 0x20, 0xCE, 0xD0, 0x05, 0xD0,
+0x07, 0xD1, 0xD0, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x22, 0xE4, 0x75, 0xF0, 0x01, 0x02, 0x44, 0x9F,
+0x7F, 0x14, 0x7E, 0x00, 0x02, 0x32, 0xAA, 0xE4,
+0x90, 0x81, 0xC8, 0xF0, 0xA3, 0xF0, 0x90, 0x01,
+0x98, 0xE0, 0x7F, 0x00, 0x30, 0xE4, 0x02, 0x7F,
+0x01, 0xEF, 0x64, 0x01, 0x60, 0x3B, 0xC3, 0x90,
+0x81, 0xC9, 0xE0, 0x94, 0x88, 0x90, 0x81, 0xC8,
+0xE0, 0x94, 0x13, 0x40, 0x0F, 0x90, 0x01, 0xC1,
+0xE0, 0x44, 0x10, 0xF0, 0x90, 0x01, 0xC7, 0x74,
+0xFD, 0xF0, 0x80, 0x1D, 0x90, 0x81, 0xC8, 0xF1,
+0x59, 0xF1, 0x60, 0xD3, 0x90, 0x81, 0xC9, 0xE0,
+0x94, 0x32, 0x90, 0x81, 0xC8, 0xE0, 0x94, 0x00,
+0x40, 0xBC, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE3,
+0xB5, 0x90, 0x01, 0xC7, 0x74, 0xFE, 0xF0, 0x22,
+0x90, 0x01, 0xB8, 0xE4, 0xF0, 0x7F, 0x01, 0x22,
+0x90, 0x81, 0x44, 0xE0, 0x64, 0x02, 0x7F, 0x01,
+0x60, 0x02, 0x7F, 0x00, 0x22, 0xE4, 0xFB, 0xFA,
+0xFD, 0x7F, 0x01, 0x12, 0x43, 0x4E, 0x90, 0x82,
+0x36, 0xEF, 0xF0, 0x60, 0xF0, 0x90, 0x80, 0x3C,
+0xE0, 0xFF, 0x70, 0x04, 0xA3, 0xE0, 0x60, 0xE5,
+0xC2, 0xAF, 0xEF, 0x30, 0xE1, 0x0A, 0x90, 0x80,
+0x3C, 0xE0, 0x54, 0xFD, 0xF0, 0x12, 0x60, 0x15,
+0xD2, 0xAF, 0xC2, 0xAF, 0x90, 0x80, 0x3C, 0xE0,
+0xFF, 0x30, 0xE2, 0x05, 0x54, 0xFB, 0xF0, 0x31,
+0xA4, 0xD2, 0xAF, 0x80, 0xD0, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x80, 0x9C, 0xE0,
+0xFF, 0x90, 0x80, 0x9B, 0xE0, 0xB5, 0x07, 0x04,
+0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70,
+0x3E, 0x90, 0x80, 0x9B, 0xE0, 0xFE, 0x75, 0xF0,
+0x08, 0x90, 0x80, 0x4B, 0x12, 0x45, 0x11, 0xE0,
+0xFD, 0xEE, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x4C,
+0xF9, 0x74, 0x80, 0x35, 0xF0, 0xFA, 0x7B, 0x01,
+0xAF, 0x05, 0x71, 0x24, 0x90, 0x80, 0x9B, 0x31,
+0x9D, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60,
+0x05, 0xE4, 0x90, 0x80, 0x9B, 0xF0, 0x11, 0x74,
+0x90, 0x80, 0x3C, 0xE0, 0x44, 0x02, 0xF0, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x90, 0x01, 0xCC, 0xE0,
+0x54, 0x0F, 0x90, 0x82, 0xA7, 0xF0, 0x90, 0x82,
+0xA7, 0xE0, 0xFD, 0x70, 0x02, 0x21, 0x72, 0x90,
+0x80, 0x9B, 0xE0, 0xFF, 0x70, 0x06, 0xA3, 0xE0,
+0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90,
+0x80, 0x9C, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01,
+0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x08, 0x90,
+0x01, 0xC1, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90,
+0x82, 0xA5, 0x12, 0x6D, 0x53, 0x80, 0x05, 0xC3,
+0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF,
+0x5D, 0x70, 0x02, 0x21, 0x55, 0xE4, 0x90, 0x82,
+0xA8, 0xF0, 0x90, 0x82, 0xA8, 0xE0, 0xF9, 0xC3,
+0x94, 0x04, 0x50, 0x32, 0x31, 0x74, 0xA4, 0xFF,
+0xE9, 0xFD, 0x7C, 0x00, 0x2F, 0xFF, 0xEC, 0x35,
+0xF0, 0xFE, 0x74, 0xD0, 0x31, 0x8B, 0x90, 0x80,
+0x4B, 0x31, 0x7C, 0x31, 0x73, 0xA4, 0x2D, 0xFF,
+0xEC, 0x35, 0xF0, 0xFE, 0x74, 0xF0, 0x31, 0x8B,
+0x90, 0x80, 0x4F, 0x31, 0x7C, 0xF0, 0x90, 0x82,
+0xA8, 0xE0, 0x04, 0xF0, 0x80, 0xC4, 0x90, 0x82,
+0xA7, 0xE0, 0xFF, 0x90, 0x82, 0xA5, 0xE0, 0xFE,
+0x74, 0x01, 0xA8, 0x06, 0x08, 0x80, 0x02, 0xC3,
+0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0x90, 0x82, 0xA7,
+0xF0, 0x90, 0x82, 0xA5, 0xE0, 0xFF, 0x74, 0x01,
+0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8,
+0xFC, 0x90, 0x01, 0xCC, 0xF0, 0x90, 0x82, 0xA5,
+0xE0, 0x04, 0xF0, 0xE0, 0x54, 0x03, 0xF0, 0x90,
+0x80, 0x9C, 0x31, 0x9D, 0xB4, 0x0A, 0x02, 0x7F,
+0x01, 0xEF, 0x70, 0x02, 0x01, 0x7E, 0xE4, 0x90,
+0x80, 0x9C, 0xF0, 0x01, 0x7E, 0x90, 0x01, 0xC0,
+0xE0, 0x44, 0x02, 0xF0, 0x90, 0x82, 0xA5, 0xE0,
+0x44, 0x80, 0x90, 0x00, 0x8A, 0x31, 0x73, 0x90,
+0x01, 0xD0, 0x12, 0x45, 0x11, 0xE0, 0x90, 0x01,
+0xC3, 0xF0, 0x22, 0xF0, 0x90, 0x82, 0xA5, 0xE0,
+0x75, 0xF0, 0x04, 0x22, 0x12, 0x45, 0x11, 0xE5,
+0x82, 0x29, 0xF5, 0x82, 0xE4, 0x35, 0x83, 0xF5,
+0x83, 0xEF, 0x22, 0x2F, 0xF5, 0x82, 0x74, 0x01,
+0x3E, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x80, 0x9C,
+0xE0, 0x75, 0xF0, 0x08, 0x22, 0xE0, 0x04, 0xF0,
+0xE0, 0x7F, 0x00, 0x22, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0xE4, 0xFF, 0x90, 0x81, 0x34,
+0xE0, 0xFE, 0x90, 0x81, 0x33, 0xE0, 0xFD, 0xB5,
+0x06, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00,
+0xEE, 0x64, 0x01, 0x60, 0x41, 0x90, 0x01, 0xAF,
+0xE0, 0x70, 0x0A, 0xED, 0x51, 0x68, 0xFA, 0x7B,
+0x01, 0x51, 0xC0, 0x7F, 0x01, 0xEF, 0x60, 0x2E,
+0x90, 0x81, 0x33, 0x31, 0x9D, 0xB4, 0x0A, 0x02,
+0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x81,
+0x33, 0xF0, 0x90, 0x81, 0x34, 0xE0, 0xFF, 0x90,
+0x81, 0x33, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01,
+0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70, 0x07, 0x90,
+0x80, 0x3C, 0xE0, 0x44, 0x04, 0xF0, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x81, 0x33, 0xE0, 0xFF, 0x70,
+0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF,
+0x14, 0xFF, 0x90, 0x81, 0x34, 0xE0, 0xB5, 0x07,
+0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF,
+0x60, 0x09, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x02,
+0xF0, 0x80, 0x28, 0xC0, 0x01, 0x90, 0x81, 0x34,
+0xE0, 0x51, 0x68, 0xA8, 0x01, 0xFC, 0x7D, 0x01,
+0xD0, 0x01, 0x7E, 0x00, 0x7F, 0x0F, 0x12, 0x44,
+0x79, 0x90, 0x81, 0x34, 0x31, 0x9D, 0xB4, 0x0A,
+0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90,
+0x81, 0x34, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x75, 0xF0, 0x0F, 0xA4, 0x24, 0x9D, 0xF9, 0x74,
+0x80, 0x35, 0xF0, 0x22, 0x90, 0x82, 0x46, 0x74,
+0x12, 0xF0, 0x90, 0x82, 0x54, 0x74, 0x05, 0xF0,
+0x90, 0x82, 0x48, 0xEF, 0xF0, 0xA3, 0xED, 0xF0,
+0xA3, 0xEB, 0xF0, 0x90, 0x82, 0x44, 0xE0, 0x90,
+0x82, 0x4B, 0xF0, 0x90, 0x82, 0x45, 0xE0, 0x90,
+0x82, 0x4C, 0xF0, 0x7B, 0x01, 0x7A, 0x82, 0x79,
+0x46, 0x51, 0x0B, 0x7F, 0x04, 0x90, 0x82, 0xA9,
+0xEF, 0xF0, 0x7F, 0x02, 0x12, 0x43, 0x27, 0x90,
+0x80, 0x3C, 0xE0, 0xFF, 0x90, 0x82, 0xA9, 0xE0,
+0xFE, 0xEF, 0x4E, 0x90, 0x80, 0x3C, 0xF0, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
+0x82, 0x37, 0x12, 0x45, 0x26, 0x90, 0x82, 0xA6,
+0xE0, 0xFF, 0x04, 0xF0, 0x90, 0x00, 0x01, 0xEF,
+0x12, 0x1F, 0xFC, 0x7F, 0xAF, 0x7E, 0x01, 0x12,
+0x6C, 0xAA, 0xEF, 0x60, 0x3A, 0x90, 0x82, 0x37,
+0x12, 0x45, 0x1D, 0x8B, 0x13, 0x8A, 0x14, 0x89,
+0x15, 0x90, 0x00, 0x0E, 0x12, 0x1F, 0xBD, 0x24,
+0x02, 0xF5, 0x16, 0x7B, 0x01, 0x7A, 0x01, 0x79,
+0xA0, 0x12, 0x2B, 0xED, 0x90, 0x82, 0x37, 0x12,
+0x45, 0x1D, 0x90, 0x00, 0x0E, 0x12, 0x1F, 0xBD,
+0x90, 0x01, 0xAE, 0xF0, 0xA3, 0x74, 0xFF, 0xF0,
+0x90, 0x01, 0xCB, 0xE0, 0x64, 0x80, 0xF0, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x90, 0x82, 0x38, 0x12,
+0x45, 0x26, 0x90, 0x82, 0x37, 0xEF, 0xF0, 0x12,
+0x45, 0x2F, 0x63, 0x54, 0x00, 0x63, 0x5C, 0x01,
+0x63, 0x64, 0x12, 0x63, 0x6C, 0x14, 0x63, 0x75,
+0x20, 0x63, 0x7D, 0x24, 0x63, 0x86, 0x25, 0x63,
+0x8F, 0x26, 0x63, 0x98, 0x27, 0x63, 0xA1, 0xC0,
+0x00, 0x00, 0x63, 0xAA, 0x90, 0x82, 0x38, 0x12,
+0x45, 0x1D, 0x80, 0x72, 0x90, 0x82, 0x38, 0x12,
+0x45, 0x1D, 0x81, 0x13, 0x90, 0x82, 0x38, 0x12,
+0x45, 0x1D, 0x80, 0x4E, 0x90, 0x82, 0x38, 0x12,
+0x45, 0x1D, 0x02, 0x6C, 0x77, 0x90, 0x82, 0x38,
+0x12, 0x45, 0x1D, 0x81, 0x7B, 0x90, 0x82, 0x38,
+0x12, 0x45, 0x1D, 0x02, 0x51, 0xD6, 0x90, 0x82,
+0x38, 0x12, 0x45, 0x1D, 0x02, 0x6C, 0x86, 0x90,
+0x82, 0x38, 0x12, 0x45, 0x1D, 0x02, 0x56, 0x53,
+0x90, 0x82, 0x38, 0x12, 0x45, 0x1D, 0x02, 0x57,
+0x37, 0x90, 0x82, 0x38, 0x12, 0x45, 0x1D, 0x02,
+0x6C, 0x8E, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x01,
+0xF0, 0x90, 0x82, 0x37, 0xE0, 0x90, 0x01, 0xC2,
+0xF0, 0x22, 0x12, 0x1F, 0xA4, 0xFF, 0x90, 0x81,
+0x37, 0xF0, 0xBF, 0x01, 0x08, 0x12, 0x6D, 0x5D,
+0xE4, 0x90, 0x81, 0x37, 0xF0, 0x22, 0x90, 0x02,
+0x09, 0xE0, 0xF5, 0x54, 0x12, 0x1F, 0xA4, 0x25,
+0x54, 0x90, 0x80, 0x44, 0x12, 0x57, 0x30, 0x25,
+0x54, 0x90, 0x80, 0x45, 0x91, 0x74, 0x25, 0x54,
+0x90, 0x80, 0x46, 0xB1, 0x24, 0x25, 0x54, 0x90,
+0x80, 0x47, 0xB1, 0x1D, 0x25, 0x54, 0x90, 0x80,
+0x48, 0xF0, 0x90, 0x00, 0x05, 0x12, 0x1F, 0xBD,
+0x25, 0x54, 0x90, 0x80, 0x49, 0xF0, 0x90, 0x00,
+0x06, 0x12, 0x1F, 0xBD, 0x25, 0x54, 0x90, 0x80,
+0x4A, 0xF0, 0x22, 0x8B, 0x54, 0x8A, 0x55, 0x89,
+0x56, 0x12, 0x57, 0x31, 0xFF, 0xF5, 0x58, 0x12,
+0x1F, 0xA4, 0xFE, 0xC3, 0x13, 0x30, 0xE0, 0x06,
+0x91, 0x75, 0xF5, 0x59, 0x80, 0x02, 0x8F, 0x59,
+0x85, 0x58, 0x57, 0xE5, 0x57, 0xD3, 0x95, 0x59,
+0x50, 0x1F, 0x12, 0x77, 0xD2, 0x54, 0x01, 0xFD,
+0xAF, 0x57, 0x12, 0x51, 0x79, 0xAF, 0x57, 0x12,
+0x47, 0x72, 0xEF, 0xAF, 0x57, 0x70, 0x04, 0xF1,
+0xD2, 0x80, 0x02, 0xF1, 0xD1, 0x05, 0x57, 0x80,
+0xDA, 0xE5, 0x58, 0x70, 0x16, 0xFF, 0x12, 0x47,
+0x72, 0xEF, 0x70, 0x0F, 0x12, 0x4D, 0x70, 0x12,
+0x4D, 0x5A, 0x12, 0x70, 0x7F, 0x54, 0xBF, 0xF0,
+0x54, 0x7F, 0xF0, 0x22, 0xF0, 0x90, 0x00, 0x02,
+0x02, 0x1F, 0xBD, 0x12, 0x77, 0xC9, 0xFF, 0x54,
+0x7F, 0x90, 0x81, 0x4B, 0xF0, 0xEF, 0xF1, 0xD3,
+0xA3, 0x12, 0x57, 0x30, 0xFD, 0x54, 0xF0, 0xC4,
+0x54, 0x0F, 0xFF, 0x90, 0x81, 0x49, 0xE0, 0x54,
+0xF0, 0x4F, 0xB1, 0x24, 0xFC, 0x54, 0x01, 0x25,
+0xE0, 0xFF, 0x90, 0x81, 0x46, 0xE0, 0x54, 0xFD,
+0x4F, 0xF0, 0xEC, 0x54, 0x04, 0xC3, 0x13, 0xFF,
+0x90, 0x81, 0x48, 0xE0, 0x54, 0xFD, 0x4F, 0xF0,
+0xED, 0x54, 0x0F, 0xC4, 0x54, 0xF0, 0xFF, 0xA3,
+0xE0, 0x54, 0x0F, 0x4F, 0x91, 0x74, 0x90, 0x81,
+0x4A, 0xB1, 0x1D, 0xFD, 0x7F, 0x02, 0x12, 0x49,
+0xD1, 0x90, 0x82, 0x3B, 0x12, 0x45, 0x1D, 0x91,
+0xEA, 0x12, 0x73, 0x4E, 0xF0, 0x90, 0x81, 0x4B,
+0x12, 0x77, 0xA9, 0xB1, 0x31, 0x90, 0x01, 0xBE,
+0xF0, 0x22, 0x90, 0x82, 0x3E, 0x12, 0x45, 0x26,
+0x12, 0x75, 0x00, 0x90, 0x81, 0x4B, 0xE0, 0xFF,
+0x12, 0x4E, 0x3F, 0x90, 0x81, 0x4B, 0xE0, 0x60,
+0x1B, 0x90, 0x82, 0x3E, 0x12, 0x45, 0x1D, 0x12,
+0x57, 0x31, 0x54, 0x0F, 0xFF, 0x91, 0x75, 0xFD,
+0x12, 0x75, 0xCE, 0x12, 0x71, 0xB9, 0x74, 0x01,
+0xF0, 0x12, 0x70, 0xD7, 0x22, 0xF0, 0x90, 0x00,
+0x04, 0x02, 0x1F, 0xBD, 0xF0, 0x90, 0x00, 0x03,
+0x02, 0x1F, 0xBD, 0x90, 0x81, 0x4F, 0xE0, 0x44,
+0x01, 0xF0, 0x90, 0x81, 0x49, 0xE0, 0x54, 0x0F,
+0x22, 0x90, 0x06, 0xA9, 0xE0, 0x90, 0x81, 0xC1,
+0xF0, 0xE0, 0xFD, 0x54, 0xC0, 0x70, 0x04, 0xB1,
+0xA2, 0x80, 0x53, 0xED, 0x30, 0xE6, 0x3D, 0x90,
+0x81, 0x4B, 0xE0, 0x64, 0x02, 0x70, 0x26, 0x90,
+0x81, 0x46, 0xE0, 0xFF, 0xC3, 0x13, 0x20, 0xE0,
+0x09, 0x90, 0x81, 0x4F, 0xE0, 0x44, 0x01, 0xF0,
+0x80, 0x19, 0xB1, 0x32, 0x64, 0x01, 0x70, 0x1E,
+0x90, 0x81, 0x4F, 0xE0, 0x44, 0x04, 0xF0, 0x7F,
+0x01, 0xD1, 0xA5, 0x80, 0x11, 0xB1, 0x2B, 0x64,
+0x02, 0x60, 0x04, 0xB1, 0xEC, 0x80, 0x07, 0x12,
+0x4F, 0x79, 0x80, 0x02, 0xB1, 0xA2, 0x90, 0x81,
+0xC1, 0xE0, 0x90, 0x81, 0x4F, 0x30, 0xE7, 0x05,
+0x12, 0x48, 0xFD, 0xE1, 0x57, 0xE0, 0x54, 0xFD,
+0xF0, 0x22, 0x90, 0x81, 0x4F, 0xE0, 0x54, 0xFE,
+0xF0, 0x22, 0x90, 0x06, 0xA9, 0xE0, 0xF5, 0x4E,
+0x54, 0xC0, 0x70, 0x08, 0xB1, 0xA2, 0x54, 0xFD,
+0xF0, 0x02, 0x47, 0xE4, 0xE5, 0x4E, 0x30, 0xE6,
+0x17, 0x90, 0x81, 0x4B, 0xE0, 0x64, 0x01, 0x70,
+0x11, 0xB1, 0x2B, 0x64, 0x02, 0x60, 0x04, 0xB1,
+0xEC, 0x80, 0x07, 0x12, 0x4F, 0x79, 0x80, 0x02,
+0xB1, 0xA2, 0xE5, 0x4E, 0x90, 0x81, 0x4F, 0x30,
+0xE7, 0x05, 0x12, 0x48, 0xFD, 0xE1, 0x57, 0xE0,
+0x54, 0xFD, 0xF0, 0x22, 0x90, 0x04, 0x1D, 0xE0,
+0x70, 0x1B, 0x90, 0x80, 0x45, 0xE0, 0xFF, 0x90,
+0x82, 0x95, 0x74, 0x09, 0xF0, 0x7B, 0x18, 0xE4,
+0xFD, 0xD1, 0x0E, 0x90, 0x81, 0xC2, 0xEE, 0xF0,
+0xA3, 0xEF, 0xF0, 0xF1, 0x50, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x82, 0x93,
+0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x82, 0x92,
+0xEF, 0xF0, 0xE4, 0xFD, 0xFC, 0x12, 0x77, 0x88,
+0x7C, 0x00, 0xAD, 0x07, 0x90, 0x82, 0x92, 0xE0,
+0x90, 0x04, 0x25, 0xF0, 0x90, 0x82, 0x93, 0xE0,
+0x60, 0x0E, 0x74, 0x0F, 0x2F, 0xF5, 0x82, 0xE4,
+0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x80, 0xF0,
+0xAF, 0x05, 0x74, 0x08, 0x2F, 0xF5, 0x82, 0xE4,
+0x34, 0xFC, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x09,
+0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0xE0, 0x54, 0xF0, 0xF0, 0xAF, 0x05, 0xF1, 0x45,
+0xE0, 0x20, 0xE1, 0x15, 0x54, 0x01, 0xFE, 0x90,
+0x82, 0x94, 0xE0, 0x25, 0xE0, 0x25, 0xE0, 0xFB,
+0xEE, 0x44, 0x02, 0x4B, 0xFE, 0xF1, 0x45, 0xEE,
+0xF0, 0x90, 0x82, 0x95, 0xE0, 0xFF, 0xAE, 0x05,
+0x74, 0x1E, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC,
+0xF5, 0x83, 0xEF, 0xF0, 0x74, 0x21, 0x2E, 0xF1,
+0x2F, 0x54, 0xF7, 0xF0, 0xAE, 0x04, 0xAF, 0x05,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x82, 0x9E, 0xEF,
+0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x22, 0x90,
+0x05, 0x22, 0xE0, 0x90, 0x82, 0xA1, 0xF0, 0x7B,
+0x29, 0xF1, 0xDA, 0x12, 0x74, 0x49, 0xBF, 0x01,
+0x02, 0xD1, 0xE2, 0x90, 0x82, 0xA1, 0xE0, 0xFD,
+0x7B, 0x2A, 0xE4, 0xFF, 0x12, 0x4D, 0x15, 0x80,
+0x02, 0xD1, 0xE2, 0xF1, 0x50, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0x90, 0x80, 0x47, 0xE0, 0xFF, 0x90,
+0x82, 0x95, 0x74, 0x0B, 0xF0, 0x7B, 0x08, 0x7D,
+0x01, 0xD1, 0x0E, 0x90, 0x82, 0x9F, 0xEE, 0xF0,
+0xFC, 0xA3, 0xEF, 0xF0, 0xFD, 0x90, 0x82, 0x9E,
+0xE0, 0xFF, 0xF1, 0x39, 0x54, 0x3F, 0xF0, 0xBF,
+0x01, 0x02, 0x80, 0x16, 0xEF, 0x70, 0x02, 0x80,
+0x07, 0x90, 0x81, 0x4E, 0xE0, 0x30, 0xE3, 0x0A,
+0xF1, 0x2C, 0x54, 0xEF, 0xF1, 0x38, 0x44, 0x40,
+0xF0, 0x22, 0xF1, 0x2C, 0x44, 0x10, 0xF1, 0x38,
+0x44, 0x80, 0xF0, 0x22, 0x74, 0x21, 0x2D, 0xF5,
+0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22,
+0xF0, 0x74, 0x1F, 0x2D, 0xF5, 0x82, 0xE4, 0x34,
+0xFC, 0xF5, 0x83, 0xE0, 0x22, 0x74, 0x16, 0x2F,
+0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22,
+0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0, 0x22, 0x90,
+0x81, 0x46, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0x90,
+0x81, 0x4B, 0xE0, 0x64, 0x02, 0x60, 0x0D, 0xB1,
+0x32, 0x60, 0x09, 0x12, 0x75, 0x26, 0xEF, 0x70,
+0x03, 0x12, 0x4B, 0x19, 0x22, 0xE4, 0xFF, 0x12,
+0x47, 0x72, 0xBF, 0x01, 0x11, 0x90, 0x81, 0x4B,
+0xE0, 0x60, 0x0B, 0xB1, 0x32, 0x64, 0x02, 0x60,
+0x02, 0xA1, 0xEC, 0x12, 0x4F, 0x79, 0x22, 0x90,
+0x81, 0x4B, 0xE0, 0x64, 0x01, 0x70, 0x1A, 0xB1,
+0x32, 0x60, 0x0D, 0xE4, 0xFD, 0x7F, 0x0C, 0x12,
+0x4B, 0x1C, 0x12, 0x4D, 0x10, 0x02, 0x70, 0x4A,
+0x90, 0x81, 0x4E, 0xE0, 0x70, 0x03, 0x12, 0x77,
+0xF3, 0x22, 0x90, 0x81, 0x4B, 0xE0, 0x70, 0x07,
+0x90, 0x81, 0x41, 0xE0, 0x30, 0xE0, 0x11, 0x90,
+0x81, 0x41, 0xE0, 0x30, 0xE0, 0x08, 0x12, 0x54,
+0x44, 0xBF, 0x01, 0x04, 0x80, 0x91, 0xF1, 0x8F,
+0x22, 0x22, 0x22, 0xC4, 0x13, 0x13, 0x13, 0x54,
+0x01, 0x22, 0x7D, 0xFF, 0xE4, 0xFF, 0x02, 0x4D,
+0x15, 0xAC, 0x07, 0xED, 0xAD, 0x04, 0x78, 0x24,
+0xF2, 0xED, 0x08, 0xF2, 0xEB, 0xB4, 0x04, 0x07,
+0x78, 0x27, 0x74, 0x01, 0xF2, 0x80, 0x0E, 0xEB,
+0x78, 0x27, 0xB4, 0x05, 0x05, 0x74, 0x02, 0xF2,
+0x80, 0x03, 0x74, 0x04, 0xF2, 0x31, 0x23, 0xE2,
+0x94, 0x00, 0x50, 0x45, 0xE4, 0x78, 0x26, 0xF2,
+0x11, 0xFD, 0x9F, 0x40, 0x02, 0x01, 0xFC, 0x31,
+0x06, 0x60, 0x1F, 0x74, 0x37, 0x2E, 0xF8, 0xE2,
+0x78, 0x32, 0xF2, 0xEE, 0xFF, 0x78, 0x25, 0xE2,
+0x2F, 0xFF, 0x18, 0xE2, 0x34, 0x00, 0x8F, 0x82,
+0xF5, 0x83, 0xE0, 0x78, 0x29, 0xF2, 0x78, 0x32,
+0x31, 0x39, 0x78, 0x24, 0x08, 0xE2, 0xFF, 0x08,
+0xE2, 0x2F, 0xFF, 0x78, 0x28, 0xE2, 0xFD, 0x12,
+0x32, 0x1E, 0x78, 0x26, 0xE2, 0x04, 0xF2, 0x80,
+0xBF, 0x31, 0x23, 0xE2, 0x94, 0x07, 0x50, 0x30,
+0xE4, 0x78, 0x26, 0xF2, 0x11, 0xFD, 0x9F, 0x40,
+0x02, 0x01, 0xFC, 0x31, 0x06, 0x60, 0x14, 0x78,
+0x26, 0xE2, 0xFF, 0x31, 0x2B, 0xE0, 0x78, 0x29,
+0xF2, 0x74, 0x37, 0x2F, 0xF8, 0xE2, 0x78, 0x32,
+0xF2, 0x31, 0x39, 0x31, 0x1B, 0x31, 0x2B, 0xEF,
+0xF0, 0x78, 0x26, 0xE2, 0x04, 0xF2, 0x80, 0xD4,
+0x90, 0x82, 0x35, 0xE0, 0x60, 0x0A, 0x31, 0x13,
+0x12, 0x2D, 0x5C, 0x78, 0x2E, 0x12, 0x45, 0x05,
+0xE4, 0x78, 0x26, 0xF2, 0x11, 0xFD, 0x9F, 0x50,
+0x4E, 0x31, 0x06, 0x60, 0x2B, 0x78, 0x2E, 0x12,
+0x44, 0xEC, 0x78, 0x26, 0xE2, 0xFB, 0x75, 0xF0,
+0x08, 0xA4, 0xF9, 0xF8, 0x12, 0x20, 0xA8, 0x78,
+0x29, 0xEF, 0xF2, 0x74, 0x37, 0x2B, 0xF8, 0xE2,
+0x78, 0x32, 0xF2, 0xE2, 0xFE, 0xF4, 0x5F, 0xFF,
+0x78, 0x28, 0xE2, 0xFD, 0xEE, 0x5D, 0x4F, 0xF2,
+0x31, 0x1B, 0xFD, 0xC3, 0x74, 0x03, 0x9D, 0xFD,
+0xE4, 0x94, 0x00, 0xFC, 0x7B, 0xFE, 0x74, 0x2A,
+0x2D, 0xF9, 0x74, 0x80, 0x3C, 0xFA, 0xEF, 0x12,
+0x1F, 0xEA, 0xE2, 0x04, 0xF2, 0x80, 0xAD, 0x78,
+0x2A, 0x12, 0x44, 0xEC, 0x12, 0x5E, 0xAB, 0x31,
+0x13, 0x12, 0x2E, 0xA2, 0x22, 0x78, 0x27, 0xE2,
+0xFF, 0x18, 0xE2, 0xFE, 0xC3, 0x22, 0x74, 0x33,
+0x2E, 0xF8, 0xE2, 0x78, 0x28, 0xF2, 0x90, 0x82,
+0x35, 0xE0, 0x22, 0x78, 0x24, 0xE2, 0xFE, 0x08,
+0xE2, 0xFF, 0x22, 0x78, 0x28, 0xE2, 0xFF, 0x78,
+0x26, 0xE2, 0x22, 0xD3, 0x78, 0x25, 0xE2, 0x94,
+0xFF, 0x18, 0x22, 0xFD, 0x18, 0xE2, 0x2D, 0xFD,
+0x18, 0xE2, 0x34, 0x00, 0x8D, 0x82, 0xF5, 0x83,
+0x22, 0xE2, 0xFF, 0xF4, 0xFE, 0x78, 0x29, 0xE2,
+0x5E, 0xFE, 0x18, 0xE2, 0xFD, 0xEF, 0x5D, 0x4E,
+0xF2, 0x22, 0xE4, 0x90, 0x81, 0xE3, 0xF0, 0x90,
+0x87, 0x5F, 0xE0, 0x90, 0x81, 0xE2, 0xF0, 0xE4,
+0x90, 0x81, 0xEF, 0xF0, 0x90, 0x81, 0xDF, 0xF0,
+0x90, 0x81, 0xDF, 0xE0, 0xFF, 0xC3, 0x94, 0x40,
+0x50, 0x10, 0x74, 0xF2, 0x2F, 0x91, 0x4E, 0x74,
+0xFF, 0xF0, 0x90, 0x81, 0xDF, 0xE0, 0x04, 0xF0,
+0x80, 0xE6, 0xE4, 0x90, 0x81, 0xDF, 0xF0, 0x90,
+0x81, 0xE2, 0xE0, 0xFF, 0x90, 0x81, 0xDF, 0xE0,
+0xFE, 0xC3, 0x9F, 0x40, 0x02, 0x41, 0x4A, 0x74,
+0xDF, 0x2E, 0xF9, 0xE4, 0x34, 0x86, 0x91, 0x46,
+0x75, 0x16, 0x0A, 0x7B, 0x01, 0x7A, 0x81, 0x79,
+0xD4, 0x12, 0x2B, 0xED, 0x90, 0x81, 0xD5, 0xE0,
+0xFF, 0x12, 0x2F, 0x27, 0xEF, 0x04, 0x90, 0x81,
+0xEF, 0xF0, 0x90, 0x81, 0xD4, 0xE0, 0xFF, 0xA3,
+0xE0, 0xFD, 0x12, 0x31, 0xEA, 0xEF, 0x24, 0xC8,
+0x90, 0x81, 0xF1, 0xF0, 0x75, 0xF0, 0x08, 0xA4,
+0xF0, 0x90, 0x81, 0xD5, 0xE0, 0x54, 0x0F, 0x90,
+0x81, 0xF0, 0xF0, 0xE4, 0x90, 0x81, 0xDE, 0xF0,
+0x90, 0x81, 0xE0, 0xF0, 0x90, 0x81, 0xE0, 0xE0,
+0xFF, 0xC3, 0x94, 0x04, 0x50, 0x57, 0x90, 0x81,
+0xF0, 0xE0, 0xFE, 0xA8, 0x07, 0x08, 0x80, 0x02,
+0xC3, 0x13, 0xD8, 0xFC, 0x20, 0xE0, 0x3E, 0x90,
+0x81, 0xE0, 0xE0, 0x25, 0xE0, 0xFF, 0x90, 0x81,
+0xF1, 0xE0, 0x2F, 0x24, 0xF2, 0xF9, 0xE4, 0x34,
+0x81, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x01,
+0x90, 0x81, 0xDE, 0xE0, 0x75, 0xF0, 0x02, 0xA4,
+0x24, 0xD6, 0xF9, 0x74, 0x81, 0x35, 0xF0, 0x8B,
+0x13, 0xF5, 0x14, 0x89, 0x15, 0x75, 0x16, 0x02,
+0xD0, 0x01, 0xD0, 0x03, 0x12, 0x2B, 0xED, 0x90,
+0x81, 0xDE, 0xE0, 0x04, 0xF0, 0x90, 0x81, 0xE0,
+0xE0, 0x04, 0xF0, 0x80, 0x9F, 0x90, 0x81, 0xEF,
+0xE0, 0xFF, 0x90, 0x81, 0xDF, 0xE0, 0x2F, 0xF0,
+0x21, 0x7F, 0xE4, 0x90, 0x81, 0xE3, 0xF0, 0x90,
+0x81, 0xE3, 0xE0, 0xC3, 0x94, 0x40, 0x40, 0x02,
+0x61, 0xF3, 0xE0, 0xFF, 0x24, 0xF2, 0x91, 0x4E,
+0xE0, 0x90, 0x81, 0xE5, 0xF0, 0xE0, 0xFE, 0x54,
+0xF0, 0xC4, 0x54, 0x0F, 0xFD, 0x90, 0x81, 0xE4,
+0xF0, 0xEE, 0x54, 0x0F, 0xFE, 0xA3, 0xF0, 0x74,
+0xF3, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5,
+0x83, 0xE0, 0x90, 0x81, 0xE6, 0xF0, 0xFC, 0xEE,
+0xFE, 0xEC, 0xFB, 0xEB, 0xFF, 0x90, 0x81, 0xEB,
+0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xED, 0x12, 0x45,
+0x2F, 0x6A, 0xBE, 0x00, 0x6A, 0xF0, 0x01, 0x6B,
+0x5D, 0x02, 0x6B, 0xE4, 0x03, 0x6B, 0x68, 0x04,
+0x6B, 0x79, 0x05, 0x6B, 0x79, 0x06, 0x6B, 0x79,
+0x07, 0x6B, 0x79, 0x08, 0x6B, 0xC1, 0x09, 0x6B,
+0xD2, 0x0A, 0x00, 0x00, 0x6B, 0xF3, 0x90, 0x81,
+0xE3, 0xE0, 0xFD, 0x24, 0xF5, 0xF5, 0x82, 0xE4,
+0x34, 0x81, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0xF4,
+0x2D, 0x91, 0x33, 0xE0, 0xFD, 0xED, 0xFF, 0x90,
+0x81, 0xED, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF, 0xF0,
+0x90, 0x81, 0xE6, 0xE0, 0xFF, 0x12, 0x2F, 0x96,
+0x90, 0x81, 0xE1, 0x74, 0x02, 0xF0, 0x61, 0xE4,
+0x71, 0xF4, 0x12, 0x44, 0xC2, 0xC0, 0x04, 0xC0,
+0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x81, 0xE3,
+0xE0, 0x24, 0xF6, 0xF5, 0x82, 0xE4, 0x34, 0x81,
+0x91, 0x1F, 0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12,
+0x44, 0xC2, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06,
+0xC0, 0x07, 0x90, 0x81, 0xE3, 0xE0, 0x24, 0xF7,
+0xF5, 0x82, 0xE4, 0x34, 0x81, 0x91, 0x1F, 0x78,
+0x18, 0x12, 0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02,
+0xD0, 0x01, 0xD0, 0x00, 0x91, 0x56, 0x90, 0x81,
+0xE7, 0x12, 0x44, 0xE0, 0x90, 0x85, 0x96, 0x12,
+0x20, 0xCE, 0x90, 0x81, 0xEB, 0xE0, 0xFE, 0xA3,
+0xE0, 0xFF, 0x12, 0x2E, 0xE4, 0x90, 0x81, 0xE1,
+0x74, 0x04, 0xF0, 0x61, 0xE4, 0x91, 0x28, 0xE0,
+0xFB, 0xE4, 0xFF, 0x12, 0x30, 0xC7, 0x80, 0x09,
+0x91, 0x28, 0xE0, 0xFB, 0xE4, 0xFF, 0x12, 0x30,
+0x6A, 0x90, 0x81, 0xE1, 0x74, 0x01, 0xF0, 0x80,
+0x6B, 0x90, 0x81, 0xE1, 0x74, 0x02, 0xF0, 0x71,
+0xF4, 0x12, 0x44, 0xC2, 0xC0, 0x04, 0xC0, 0x05,
+0xC0, 0x06, 0xC0, 0x07, 0x90, 0x81, 0xE5, 0x91,
+0x21, 0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0, 0x03,
+0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x91, 0x56,
+0x90, 0x81, 0xE4, 0xE0, 0x24, 0xFB, 0xFF, 0xC0,
+0x07, 0x90, 0x81, 0xE7, 0x12, 0x44, 0xE0, 0x90,
+0x82, 0x7F, 0x12, 0x20, 0xCE, 0x90, 0x81, 0xE6,
+0xE0, 0xFD, 0xD0, 0x07, 0x12, 0x5F, 0x36, 0x80,
+0x23, 0x90, 0x81, 0xE1, 0x74, 0x01, 0x91, 0x3B,
+0x75, 0x16, 0x01, 0x91, 0x5F, 0xF0, 0x7B, 0x04,
+0x80, 0x0F, 0x90, 0x81, 0xE1, 0x74, 0x04, 0x91,
+0x3B, 0x75, 0x16, 0x04, 0x91, 0x5F, 0xF0, 0x7B,
+0x06, 0x12, 0x67, 0xE1, 0x90, 0x81, 0xE1, 0xE0,
+0x24, 0x02, 0xFF, 0x90, 0x81, 0xE3, 0xE0, 0x2F,
+0xF0, 0x41, 0x4F, 0x22, 0x90, 0x81, 0xE3, 0xE0,
+0x24, 0xF5, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5,
+0x83, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78,
+0x08, 0x12, 0x20, 0xBB, 0xA8, 0x04, 0xA9, 0x05,
+0xAA, 0x06, 0xAB, 0x07, 0x90, 0x81, 0xE3, 0xE0,
+0x24, 0xF4, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5,
+0x83, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x22,
+0x90, 0x81, 0xE6, 0xE0, 0xFD, 0x90, 0x81, 0xE3,
+0xE0, 0x24, 0xF4, 0xF5, 0x82, 0xE4, 0x34, 0x81,
+0xF5, 0x83, 0x22, 0xF0, 0x90, 0x81, 0xE3, 0xE0,
+0x24, 0xF4, 0xF9, 0xE4, 0x34, 0x81, 0x75, 0x13,
+0x01, 0xF5, 0x14, 0x89, 0x15, 0x22, 0xF5, 0x82,
+0xE4, 0x34, 0x81, 0xF5, 0x83, 0x22, 0x12, 0x44,
+0xC2, 0x90, 0x81, 0xE7, 0x02, 0x20, 0xCE, 0x7B,
+0xFE, 0x7A, 0x80, 0x79, 0x33, 0x12, 0x2B, 0xED,
+0x90, 0x81, 0xE6, 0xE0, 0xFF, 0x90, 0x81, 0xE5,
+0xE0, 0xFD, 0xE4, 0x90, 0x82, 0x35, 0x22, 0x12,
+0x1F, 0xA4, 0x54, 0x01, 0xFF, 0x90, 0x81, 0xBE,
+0xE0, 0x54, 0xFE, 0x4F, 0xF0, 0x22, 0x12, 0x1F,
+0xA4, 0x90, 0x81, 0xAE, 0xF0, 0x22, 0x12, 0x1F,
+0xA4, 0x90, 0x81, 0xBC, 0x12, 0x57, 0x30, 0x90,
+0x81, 0xBD, 0xF0, 0x22, 0xE4, 0x90, 0x81, 0x33,
+0xF0, 0xA3, 0xF0, 0x90, 0x80, 0x9B, 0xF0, 0xA3,
+0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x90, 0x82, 0x8E, 0xEE, 0xF0, 0xA3, 0xEF,
+0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x82,
+0x8E, 0xE0, 0xFE, 0xA3, 0xE0, 0xF5, 0x82, 0x8E,
+0x83, 0xE0, 0x60, 0x29, 0xC3, 0x90, 0x82, 0x91,
+0xE0, 0x94, 0xE8, 0x90, 0x82, 0x90, 0xE0, 0x94,
+0x03, 0x40, 0x0B, 0x90, 0x01, 0xC0, 0xE0, 0x44,
+0x80, 0xF0, 0x7F, 0x00, 0x80, 0x11, 0x90, 0x82,
+0x90, 0x12, 0x5F, 0x59, 0x7F, 0x0A, 0x7E, 0x00,
+0x12, 0x32, 0xAA, 0x80, 0xC9, 0x7F, 0x01, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x7D, 0x08, 0xED, 0x14, 0xF9,
+0x24, 0x38, 0x12, 0x47, 0xC5, 0xE0, 0x60, 0x3A,
+0x7C, 0x08, 0xEC, 0x14, 0x90, 0x82, 0xAA, 0xF0,
+0x74, 0x38, 0x29, 0x12, 0x47, 0xC5, 0xE0, 0xFB,
+0x7A, 0x00, 0x90, 0x82, 0xAA, 0xB1, 0x53, 0x80,
+0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9,
+0xFF, 0xEE, 0x5A, 0xFE, 0xEF, 0x5B, 0x4E, 0x60,
+0x0F, 0xE9, 0x75, 0xF0, 0x08, 0xA4, 0xFF, 0x90,
+0x82, 0xAA, 0xE0, 0x2F, 0x04, 0xFF, 0x80, 0x06,
+0xDC, 0xC8, 0xDD, 0xB9, 0x7F, 0x00, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0xE0, 0xFF, 0x74, 0x01, 0x7E,
+0x00, 0xA8, 0x07, 0x08, 0x22, 0x7B, 0x01, 0x7A,
+0x82, 0x79, 0x3B, 0x7F, 0xF5, 0x7E, 0x00, 0x12,
+0x2B, 0x27, 0xBF, 0x01, 0x06, 0x90, 0x82, 0x3B,
+0xE0, 0xA3, 0xF0, 0x7B, 0x01, 0x7A, 0x82, 0x79,
+0x3B, 0x7F, 0xF6, 0x7E, 0x00, 0x12, 0x2B, 0x27,
+0xBF, 0x01, 0x08, 0x90, 0x82, 0x3B, 0xE0, 0x90,
+0x82, 0x3D, 0xF0, 0x7B, 0x01, 0x7A, 0x82, 0x79,
+0x3B, 0x7F, 0xF4, 0x7E, 0x00, 0x12, 0x2B, 0x27,
+0xBF, 0x01, 0x08, 0x90, 0x82, 0x3B, 0xE0, 0x90,
+0x82, 0x3E, 0xF0, 0x7B, 0x01, 0x7A, 0x82, 0x79,
+0x3B, 0x7F, 0xF3, 0x7E, 0x00, 0x12, 0x2B, 0x27,
+0xBF, 0x01, 0x08, 0x90, 0x82, 0x3B, 0xE0, 0x90,
+0x82, 0x3F, 0xF0, 0x7B, 0x01, 0x7A, 0x82, 0x79,
+0x3B, 0x7F, 0xF2, 0x7E, 0x00, 0x12, 0x2B, 0x27,
+0xBF, 0x01, 0x08, 0x90, 0x82, 0x3B, 0xE0, 0x90,
+0x82, 0x40, 0xF0, 0x90, 0x82, 0x3C, 0xE0, 0xFF,
+0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFB, 0xA3, 0xE0,
+0x90, 0x82, 0x44, 0xF0, 0x90, 0x82, 0x40, 0xE0,
+0x90, 0x82, 0x45, 0xF0, 0x02, 0x62, 0x74, 0x90,
+0x01, 0x94, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x01,
+0xC7, 0xE4, 0xF0, 0x22, 0x90, 0x01, 0x01, 0xE0,
+0x44, 0x04, 0xF0, 0x90, 0x01, 0x9C, 0x74, 0x7E,
+0xF0, 0xA3, 0x74, 0x92, 0xF0, 0xA3, 0x74, 0xA0,
+0xF0, 0xA3, 0x74, 0x24, 0xF0, 0x90, 0x01, 0x9B,
+0x74, 0x49, 0xF0, 0x90, 0x01, 0x9A, 0x74, 0xE0,
+0xF0, 0x90, 0x01, 0x99, 0xE4, 0xF0, 0x90, 0x01,
+0x98, 0x04, 0xF0, 0x22, 0x7F, 0x02, 0x90, 0x81,
+0xBB, 0xE0, 0xFE, 0xEF, 0xC3, 0x9E, 0x50, 0x18,
+0xEF, 0x25, 0xE0, 0x24, 0x81, 0xF8, 0xE6, 0x30,
+0xE4, 0x0B, 0x90, 0x01, 0xB8, 0x74, 0x08, 0xF0,
+0xA3, 0xF0, 0x7F, 0x00, 0x22, 0x0F, 0x80, 0xDE,
+0x7F, 0x01, 0x22, 0x90, 0x01, 0xE4, 0x74, 0x1C,
+0xF0, 0xA3, 0xE4, 0xF0, 0x22, 0x90, 0x01, 0x34,
+0xE0, 0x55, 0x3D, 0xF5, 0x41, 0xA3, 0xE0, 0x55,
+0x3E, 0xF5, 0x42, 0xA3, 0xE0, 0x55, 0x3F, 0xF5,
+0x43, 0xA3, 0xE0, 0x55, 0x40, 0xF5, 0x44, 0x90,
+0x01, 0x34, 0xE5, 0x41, 0xF0, 0xA3, 0xE5, 0x42,
+0xF0, 0xA3, 0xE5, 0x43, 0xF0, 0xA3, 0xE5, 0x44,
+0xF0, 0x22, 0x90, 0x01, 0x3C, 0xE0, 0x55, 0x45,
+0xF5, 0x49, 0xA3, 0xE0, 0x55, 0x46, 0xF5, 0x4A,
+0xA3, 0xE0, 0x55, 0x47, 0xF5, 0x4B, 0xA3, 0xE0,
+0x55, 0x48, 0xF5, 0x4C, 0x90, 0x01, 0x3C, 0xE5,
+0x49, 0xF0, 0xA3, 0xE5, 0x4A, 0xF0, 0xA3, 0xE5,
+0x4B, 0xF0, 0xA3, 0xE5, 0x4C, 0xF0, 0x53, 0x91,
+0xDF, 0x22, 0x90, 0x81, 0x41, 0xE0, 0x30, 0xE0,
+0x05, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0x90,
+0x81, 0xBD, 0xE0, 0x60, 0x0F, 0xE4, 0xF0, 0x90,
+0x05, 0x53, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x05,
+0xFC, 0xE0, 0x04, 0xF0, 0x90, 0x81, 0x41, 0xE0,
+0x30, 0xE0, 0x10, 0xA3, 0x74, 0x01, 0xF0, 0x90,
+0x81, 0x41, 0xE0, 0xFF, 0xC3, 0x13, 0x30, 0xE0,
+0x02, 0xD1, 0xFE, 0x12, 0x76, 0x1E, 0xE4, 0xFF,
+0x12, 0x72, 0xEF, 0x02, 0x4D, 0xD4, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x54, 0x44,
+0xBF, 0x01, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F,
+0x02, 0x12, 0x53, 0x48, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x90, 0x81, 0x41, 0xE0, 0xFF, 0x30, 0xE0,
+0x3E, 0x90, 0x81, 0x45, 0xE0, 0x7E, 0x00, 0xB4,
+0x02, 0x02, 0x7E, 0x01, 0x90, 0x81, 0x44, 0xE0,
+0x7D, 0x00, 0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED,
+0x4E, 0x70, 0x24, 0xEF, 0xC3, 0x13, 0x30, 0xE0,
+0x02, 0x80, 0xBB, 0xF1, 0x60, 0x90, 0x81, 0x45,
+0xE0, 0xB4, 0x0C, 0x06, 0xE4, 0xFD, 0x7F, 0x08,
+0x80, 0x0A, 0x90, 0x81, 0x45, 0xE0, 0xB4, 0x04,
+0x06, 0xE4, 0xFD, 0xFF, 0x12, 0x4B, 0x1C, 0x22,
+0x90, 0x01, 0x57, 0xE0, 0x60, 0x1E, 0x12, 0x47,
+0xBA, 0xF0, 0x90, 0x81, 0x46, 0xF1, 0x8F, 0x30,
+0xE0, 0x02, 0x80, 0x22, 0xF1, 0xA2, 0x9F, 0x40,
+0x0B, 0xE4, 0xFF, 0x12, 0x47, 0x72, 0xBF, 0x01,
+0x03, 0xF1, 0x85, 0xF0, 0x22, 0x90, 0x81, 0x47,
+0xE0, 0x54, 0xFB, 0x22, 0x90, 0x81, 0x47, 0xE0,
+0xFF, 0x13, 0x13, 0x54, 0x3F, 0x22, 0xEF, 0x54,
+0xFB, 0xF0, 0x90, 0x81, 0x4F, 0xE0, 0x54, 0xFD,
+0xF0, 0x22, 0x90, 0x81, 0x54, 0xE0, 0x04, 0xF0,
+0x90, 0x81, 0x4F, 0xE0, 0x54, 0xEF, 0xF0, 0x90,
+0x81, 0xA8, 0xE0, 0xFF, 0x90, 0x81, 0x54, 0xE0,
+0xD3, 0x22, 0x12, 0x54, 0x2E, 0x30, 0xE0, 0x0C,
+0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, 0xE0,
+0x03, 0x12, 0x57, 0x81, 0x90, 0x81, 0x46, 0xF1,
+0x8F, 0x30, 0xE0, 0x08, 0xF1, 0x96, 0x54, 0x07,
+0x70, 0x37, 0x80, 0x32, 0xF1, 0xA2, 0x9F, 0x40,
+0x2D, 0x12, 0x47, 0x6A, 0x70, 0x2B, 0x12, 0x65,
+0x32, 0x70, 0x04, 0xF1, 0x85, 0xF0, 0x22, 0x90,
+0x81, 0x55, 0xE0, 0x04, 0xF0, 0xE0, 0xD3, 0x94,
+0x02, 0x40, 0x0A, 0xF1, 0x85, 0xF0, 0xE4, 0x90,
+0x81, 0x55, 0xF0, 0x80, 0x03, 0x12, 0x4F, 0x79,
+0xE4, 0x90, 0x81, 0x54, 0xF0, 0x22, 0x12, 0x47,
+0xE4, 0x22, 0x90, 0x81, 0x41, 0xE0, 0xFF, 0x30,
+0xE0, 0x05, 0x12, 0x57, 0x5B, 0x60, 0x15, 0x90,
+0x81, 0x4B, 0xE0, 0x70, 0x04, 0xEF, 0x30, 0xE0,
+0x0B, 0x90, 0x81, 0x4E, 0xE0, 0x64, 0x02, 0x60,
+0x03, 0x12, 0x54, 0xDA, 0x22, 0x90, 0x81, 0x4B,
+0xE0, 0x60, 0x0E, 0x90, 0x06, 0x92, 0xE0, 0x30,
+0xE1, 0x02, 0x80, 0x06, 0x11, 0x7F, 0x12, 0x47,
+0xE4, 0x22, 0x11, 0x87, 0x30, 0xE0, 0x05, 0x90,
+0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x06, 0x92, 0x74,
+0x02, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x04, 0xF0,
+0xE4, 0xF5, 0x1D, 0x90, 0x81, 0xAA, 0xE0, 0xC3,
+0x13, 0x54, 0x7F, 0xF5, 0x1E, 0xE4, 0xFB, 0xFD,
+0x7F, 0x58, 0x7E, 0x01, 0x12, 0x49, 0x11, 0x90,
+0x81, 0x46, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90,
+0x81, 0x46, 0xE0, 0x54, 0xF7, 0xF0, 0x22, 0x90,
+0x81, 0x46, 0xE0, 0x13, 0x13, 0x13, 0x54, 0x1F,
+0x22, 0x31, 0xCA, 0x90, 0x81, 0xC4, 0xEF, 0xF0,
+0x30, 0xE0, 0x05, 0x7D, 0x01, 0xE4, 0x80, 0x02,
+0xE4, 0xFD, 0xFF, 0x12, 0x49, 0xD1, 0x90, 0x81,
+0xC4, 0xE0, 0x30, 0xE6, 0x11, 0x90, 0x01, 0x2F,
+0xE0, 0x30, 0xE7, 0x04, 0xE4, 0xF0, 0x80, 0x06,
+0x90, 0x01, 0x2F, 0x74, 0x80, 0xF0, 0x90, 0x81,
+0x46, 0xE0, 0x90, 0x04, 0xEC, 0x30, 0xE0, 0x06,
+0xE0, 0x54, 0xDD, 0xF0, 0x80, 0x04, 0xE0, 0x44,
+0x22, 0xF0, 0x31, 0xB9, 0x74, 0x02, 0xF0, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xAC, 0x07,
+0x90, 0x81, 0x47, 0xE0, 0x12, 0x67, 0xD3, 0x30,
+0xE0, 0x02, 0x21, 0x98, 0x90, 0x81, 0x46, 0xE0,
+0x30, 0xE0, 0x16, 0x90, 0x81, 0x68, 0xE0, 0x24,
+0x04, 0x90, 0x81, 0x60, 0xF0, 0x90, 0x81, 0x68,
+0xE0, 0x24, 0x03, 0x90, 0x81, 0x5F, 0xF0, 0x80,
+0x0D, 0x90, 0x81, 0x60, 0x74, 0x02, 0xF0, 0x90,
+0x81, 0x5F, 0x14, 0xF0, 0x0B, 0x0B, 0x90, 0x81,
+0x5F, 0xE0, 0xFA, 0x90, 0x81, 0x5E, 0xE0, 0xD3,
+0x9A, 0x50, 0x0E, 0x90, 0x81, 0x53, 0xEB, 0xF0,
+0x90, 0x81, 0x60, 0xE0, 0xC3, 0x9D, 0x2C, 0x80,
+0x11, 0xC3, 0xED, 0x9A, 0x2B, 0x90, 0x81, 0x53,
+0xF0, 0x90, 0x81, 0x5F, 0xE0, 0xFF, 0xA3, 0xE0,
+0xC3, 0x9F, 0x90, 0x81, 0x63, 0xF0, 0x90, 0x81,
+0x60, 0xE0, 0xFF, 0x24, 0x0A, 0xFD, 0xE4, 0x33,
+0xFC, 0x90, 0x81, 0x63, 0x31, 0xA4, 0x98, 0x40,
+0x04, 0xEF, 0x24, 0x0A, 0xF0, 0x90, 0x81, 0x63,
+0xE0, 0xFF, 0x24, 0x23, 0xFD, 0xE4, 0x33, 0xFC,
+0x90, 0x81, 0x53, 0x31, 0xA4, 0x98, 0x40, 0x04,
+0xEF, 0x24, 0x23, 0xF0, 0x90, 0x81, 0x63, 0xE0,
+0xFF, 0x7E, 0x00, 0x90, 0x81, 0x57, 0xEE, 0xF0,
+0xA3, 0xEF, 0xF0, 0x90, 0x05, 0x58, 0xE0, 0x6F,
+0x70, 0x01, 0xE4, 0x60, 0x02, 0x31, 0xAF, 0x90,
+0x81, 0x48, 0xE0, 0x54, 0xFE, 0xF0, 0x80, 0x07,
+0x90, 0x81, 0x48, 0xE0, 0x44, 0x01, 0xF0, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0xE0, 0xD3, 0x9D, 0xEC,
+0x64, 0x80, 0xF8, 0x74, 0x80, 0x22, 0xF0, 0x90,
+0x81, 0x57, 0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0,
+0x22, 0x90, 0x81, 0x5D, 0xE0, 0xFF, 0xA3, 0xE0,
+0xFD, 0x90, 0x81, 0x64, 0xE0, 0xFB, 0x90, 0x82,
+0x9D, 0x22, 0xE4, 0x90, 0x81, 0xC6, 0xF0, 0xA3,
+0xF0, 0x90, 0x00, 0x83, 0xE0, 0x90, 0x81, 0xC5,
+0xF0, 0x90, 0x00, 0x83, 0xE0, 0xFE, 0x90, 0x81,
+0xC5, 0xE0, 0xFF, 0xB5, 0x06, 0x01, 0x22, 0xC3,
+0x90, 0x81, 0xC7, 0xE0, 0x94, 0x64, 0x90, 0x81,
+0xC6, 0xE0, 0x94, 0x00, 0x40, 0x0D, 0x90, 0x01,
+0xC0, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0x81, 0xC5,
+0xE0, 0xFF, 0x22, 0x90, 0x81, 0xC6, 0x12, 0x5F,
+0x59, 0x80, 0xC6, 0x90, 0x81, 0xBC, 0xE0, 0x60,
+0x0F, 0xE4, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44,
+0x01, 0xF0, 0x90, 0x05, 0xFD, 0xE0, 0x04, 0xF0,
+0x22, 0x90, 0x81, 0x41, 0xE0, 0xFF, 0x30, 0xE0,
+0x3F, 0x90, 0x81, 0x45, 0xE0, 0x7E, 0x00, 0xB4,
+0x02, 0x02, 0x7E, 0x01, 0x90, 0x81, 0x44, 0xE0,
+0x7D, 0x00, 0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED,
+0x4E, 0x70, 0x25, 0xEF, 0xC3, 0x13, 0x30, 0xE0,
+0x03, 0x02, 0x6E, 0xFE, 0x12, 0x57, 0x62, 0x90,
+0x81, 0x45, 0xE0, 0xB4, 0x08, 0x06, 0xE4, 0xFD,
+0x7F, 0x0C, 0x80, 0x09, 0x90, 0x81, 0x45, 0xE0,
+0x70, 0x06, 0xFD, 0x7F, 0x04, 0x12, 0x4B, 0x1C,
+0x22, 0x22, 0x51, 0x90, 0x12, 0x4F, 0xB8, 0x7F,
+0x01, 0x51, 0xEF, 0x90, 0x81, 0xB7, 0xE0, 0x30,
+0xE0, 0x15, 0x51, 0xD5, 0xF0, 0x90, 0x81, 0xBA,
+0xE0, 0x60, 0x05, 0x14, 0xF0, 0x02, 0x4E, 0x30,
+0x51, 0xE5, 0xE4, 0xFF, 0x12, 0x54, 0x89, 0x22,
+0xE4, 0x90, 0x81, 0xC4, 0xF0, 0x90, 0x81, 0x4B,
+0xE0, 0x60, 0x39, 0x12, 0x47, 0x6A, 0x70, 0x34,
+0x51, 0xDD, 0xF0, 0x90, 0x81, 0xC4, 0x74, 0x01,
+0xF0, 0xE4, 0x90, 0x81, 0x52, 0xF0, 0x90, 0x81,
+0x41, 0xE0, 0x30, 0xE0, 0x16, 0x90, 0x81, 0x45,
+0xE0, 0xB4, 0x02, 0x05, 0xE4, 0x90, 0x81, 0xC4,
+0xF0, 0x12, 0x54, 0x44, 0xEF, 0x70, 0x04, 0x90,
+0x81, 0xC4, 0xF0, 0x90, 0x81, 0xC4, 0xE0, 0x60,
+0x03, 0x12, 0x49, 0x76, 0x22, 0x90, 0x81, 0xB9,
+0xE0, 0x90, 0x05, 0x73, 0x22, 0x90, 0x81, 0x51,
+0xE0, 0x90, 0x05, 0x73, 0x22, 0x90, 0x81, 0xB8,
+0xE0, 0x14, 0x90, 0x81, 0xBA, 0xF0, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x81,
+0x48, 0xE0, 0xFE, 0xC3, 0x13, 0x30, 0xE0, 0x1F,
+0x90, 0x82, 0x64, 0x74, 0x1E, 0xF0, 0x90, 0x82,
+0x72, 0x74, 0x01, 0xF0, 0x90, 0x82, 0x66, 0xEF,
+0xF0, 0x7B, 0x01, 0x7A, 0x82, 0x79, 0x64, 0x12,
+0x62, 0x0B, 0x7F, 0x04, 0x12, 0x47, 0x45, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x90, 0x81, 0x46, 0x12,
+0x54, 0x3C, 0x30, 0xE0, 0x1F, 0xEF, 0x54, 0xBF,
+0xF0, 0x90, 0x04, 0xE0, 0xE0, 0x90, 0x81, 0x47,
+0x30, 0xE0, 0x06, 0xE0, 0x44, 0x01, 0xF0, 0x80,
+0x08, 0xE0, 0x54, 0xFE, 0x71, 0x4D, 0x74, 0x04,
+0xF0, 0x12, 0x47, 0xE4, 0x22, 0xF0, 0x90, 0x01,
+0xB9, 0x74, 0x01, 0xF0, 0x90, 0x01, 0xB8, 0x22,
+0x90, 0x81, 0x46, 0xE0, 0xFF, 0x12, 0x67, 0xD3,
+0x30, 0xE0, 0x24, 0xEF, 0x54, 0x7F, 0xF0, 0x90,
+0x04, 0xE0, 0xE0, 0x90, 0x81, 0x47, 0x30, 0xE1,
+0x06, 0xE0, 0x44, 0x02, 0xF0, 0x80, 0x07, 0xE0,
+0x54, 0xFD, 0x71, 0x4D, 0x04, 0xF0, 0x90, 0x81,
+0x4B, 0xE0, 0x60, 0x03, 0x12, 0x47, 0xE4, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4,
+0x90, 0x82, 0x83, 0xF0, 0xA3, 0xF0, 0x91, 0x49,
+0x90, 0x85, 0xBB, 0x12, 0x20, 0xDA, 0xCC, 0xF0,
+0x00, 0xC0, 0x7F, 0x8C, 0x12, 0x4F, 0xA9, 0x12,
+0x20, 0xDA, 0x00, 0x00, 0x00, 0x14, 0x91, 0xBB,
+0x90, 0x82, 0x7F, 0x12, 0x20, 0xDA, 0x00, 0x00,
+0x00, 0x00, 0xE4, 0xFD, 0xFF, 0x12, 0x5F, 0x36,
+0x7F, 0xE8, 0x7E, 0x08, 0x12, 0x2D, 0x5C, 0xEF,
+0x54, 0x0E, 0xFF, 0xE4, 0xFE, 0xED, 0x54, 0xF4,
+0xFD, 0xEC, 0x54, 0x03, 0xFC, 0xE4, 0xFB, 0xFA,
+0xF9, 0xF8, 0xC3, 0x12, 0x44, 0xCF, 0x60, 0x18,
+0xD3, 0x91, 0x30, 0x40, 0x09, 0x90, 0x01, 0xC3,
+0xE0, 0x44, 0x02, 0xF0, 0x80, 0x0A, 0x91, 0xAD,
+0x90, 0x82, 0x83, 0x12, 0x5F, 0x59, 0x80, 0xC8,
+0xC3, 0x91, 0x30, 0x50, 0x1C, 0x91, 0xB4, 0xEC,
+0x44, 0x80, 0xFC, 0x90, 0x82, 0x85, 0x12, 0x20,
+0xCE, 0x90, 0x82, 0x85, 0x12, 0x44, 0xE0, 0x12,
+0x5E, 0xAB, 0x7F, 0x7C, 0x7E, 0x08, 0x12, 0x2E,
+0xA2, 0x90, 0x01, 0x00, 0x74, 0x3F, 0xF0, 0xA3,
+0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x05, 0x53, 0xE0,
+0x44, 0x20, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x90, 0x82, 0x84, 0xE0, 0x94, 0xE8, 0x90, 0x82,
+0x83, 0xE0, 0x94, 0x03, 0x22, 0x91, 0xC2, 0x7B,
+0x23, 0x12, 0x4F, 0x95, 0x12, 0x57, 0xD4, 0xF0,
+0x22, 0xE4, 0x90, 0x82, 0xA2, 0xF0, 0xA3, 0xF0,
+0x90, 0x05, 0x22, 0xE0, 0x90, 0x82, 0xA4, 0xF0,
+0x7B, 0x47, 0x12, 0x67, 0xDA, 0x90, 0x05, 0xF8,
+0xE0, 0x70, 0x1B, 0xA3, 0xE0, 0x70, 0x17, 0xA3,
+0xE0, 0x70, 0x13, 0xA3, 0xE0, 0x70, 0x0F, 0x90,
+0x82, 0xA4, 0xE0, 0xFD, 0x7B, 0x48, 0xE4, 0xFF,
+0x12, 0x4D, 0x15, 0x7F, 0x01, 0x22, 0xD3, 0x90,
+0x82, 0xA3, 0xE0, 0x94, 0xE8, 0x90, 0x82, 0xA2,
+0xE0, 0x94, 0x03, 0x40, 0x16, 0x90, 0x01, 0xC0,
+0xE0, 0x44, 0x20, 0xF0, 0x90, 0x82, 0xA4, 0xE0,
+0xFD, 0x7B, 0x5B, 0xE4, 0xFF, 0x12, 0x4D, 0x15,
+0x7F, 0x00, 0x22, 0x91, 0xAD, 0x90, 0x82, 0xA2,
+0x12, 0x5F, 0x59, 0x80, 0xB0, 0x7F, 0x32, 0x7E,
+0x00, 0x02, 0x32, 0xAA, 0x7F, 0x7C, 0x7E, 0x08,
+0x02, 0x2D, 0x5C, 0x7F, 0x70, 0x7E, 0x0E, 0x02,
+0x2E, 0xA2, 0x90, 0x05, 0x27, 0xE0, 0x44, 0x40,
+0xF0, 0x22, 0x7B, 0x22, 0x12, 0x4F, 0x95, 0x91,
+0xC2, 0x02, 0x57, 0x8C, 0x12, 0x4D, 0x10, 0x12,
+0x4F, 0x9C, 0x91, 0xC2, 0x90, 0x81, 0x45, 0x74,
+0x04, 0xF0, 0x22, 0x90, 0x01, 0xC4, 0x74, 0xE3,
+0xF0, 0x74, 0x74, 0xA3, 0xF0, 0x90, 0x00, 0x90,
+0xE0, 0x20, 0xE0, 0xF9, 0x74, 0xE3, 0x04, 0x90,
+0x01, 0xC4, 0xF0, 0x74, 0x74, 0xA3, 0xF0, 0x22,
+0x90, 0x81, 0x46, 0xE0, 0x54, 0xFB, 0xF0, 0xE4,
+0x90, 0x81, 0x54, 0xF0, 0xA3, 0xF0, 0x90, 0x81,
+0x4F, 0xF0, 0x90, 0x81, 0x47, 0xE0, 0x54, 0xF7,
+0xF0, 0x54, 0xBF, 0xF0, 0x12, 0x4F, 0xB2, 0x7D,
+0x10, 0x7F, 0x03, 0x02, 0x54, 0xD4, 0x90, 0x04,
+0x1A, 0xE0, 0xF4, 0x60, 0x03, 0x7F, 0x00, 0x22,
+0x90, 0x04, 0x1B, 0xE0, 0x54, 0x07, 0x64, 0x07,
+0x7F, 0x01, 0x60, 0x02, 0x7F, 0x00, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xB1, 0x26,
+0xEF, 0x64, 0x01, 0x60, 0x05, 0x75, 0x0D, 0x01,
+0x80, 0x42, 0x90, 0x81, 0x4F, 0xE0, 0xFF, 0x54,
+0x03, 0x60, 0x05, 0x75, 0x0D, 0x02, 0x80, 0x34,
+0xEF, 0x30, 0xE2, 0x05, 0x75, 0x0D, 0x08, 0x80,
+0x2B, 0x90, 0x81, 0x4F, 0xE0, 0x30, 0xE4, 0x05,
+0x75, 0x0D, 0x10, 0x80, 0x1F, 0x12, 0x6F, 0x8C,
+0x20, 0xE0, 0x05, 0x75, 0x0D, 0x20, 0x80, 0x14,
+0xB1, 0xB0, 0x8F, 0x0E, 0xE5, 0x0E, 0x64, 0x01,
+0x60, 0x05, 0x85, 0x0E, 0x0D, 0x80, 0x05, 0x12,
+0x5F, 0xC0, 0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74,
+0x04, 0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x0D, 0xF0,
+0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xB1,
+0x26, 0xEF, 0x70, 0x03, 0x12, 0x67, 0x8F, 0x22,
+0x90, 0x81, 0x4D, 0xE0, 0xD3, 0x94, 0x00, 0x40,
+0x06, 0x75, 0x58, 0x04, 0x7F, 0xFF, 0x22, 0x90,
+0x81, 0xAE, 0xE0, 0x60, 0x06, 0x75, 0x58, 0x80,
+0x7F, 0xFF, 0x22, 0x7F, 0x01, 0x22, 0xEF, 0x24,
+0xFE, 0x60, 0x0B, 0x04, 0x70, 0x24, 0x90, 0x81,
+0x51, 0x74, 0x02, 0xF0, 0x80, 0x13, 0xED, 0x70,
+0x06, 0x90, 0x81, 0xAB, 0xE0, 0x80, 0x02, 0xED,
+0x14, 0x90, 0x81, 0x51, 0xF0, 0x90, 0x81, 0x51,
+0xE0, 0xA3, 0xF0, 0x90, 0x81, 0x47, 0xE0, 0x44,
+0x08, 0xF0, 0x22, 0x7B, 0x2E, 0xD1, 0x0F, 0x7D,
+0x02, 0x7F, 0x01, 0x12, 0x49, 0xD1, 0xD1, 0x16,
+0x90, 0x81, 0x45, 0x74, 0x02, 0xF0, 0x22, 0x7D,
+0x6F, 0x7F, 0xFF, 0x02, 0x4D, 0x15, 0x90, 0x05,
+0x27, 0xE0, 0x54, 0xBF, 0xF0, 0x22, 0xE4, 0xF5,
+0x4E, 0x90, 0x81, 0x4B, 0xE0, 0x60, 0x3B, 0x12,
+0x47, 0x6A, 0x70, 0x36, 0x90, 0x81, 0x49, 0xE0,
+0xFF, 0xC4, 0x54, 0x0F, 0x60, 0x09, 0x90, 0x81,
+0x47, 0x12, 0x54, 0x3C, 0x20, 0xE0, 0x03, 0x75,
+0x4E, 0x01, 0x90, 0x81, 0x41, 0xE0, 0x30, 0xE0,
+0x12, 0x90, 0x81, 0x45, 0xE0, 0xB4, 0x02, 0x03,
+0xE4, 0xF5, 0x4E, 0x12, 0x54, 0x44, 0xEF, 0x70,
+0x02, 0xF5, 0x4E, 0xE5, 0x4E, 0x60, 0x03, 0x12,
+0x49, 0x76, 0x22, 0x90, 0x81, 0xAF, 0xE0, 0x54,
+0xFE, 0xF0, 0x54, 0xFD, 0xF0, 0x54, 0xEF, 0xF0,
+0x44, 0x08, 0xF0, 0x22, 0x90, 0x81, 0xAF, 0xE0,
+0x30, 0xE0, 0x34, 0xC4, 0x13, 0x54, 0x07, 0x30,
+0xE0, 0x2D, 0x90, 0x82, 0xAF, 0xE0, 0x04, 0xF0,
+0xE0, 0xD3, 0x94, 0xC8, 0x40, 0x21, 0x90, 0x81,
+0xAF, 0xE0, 0x54, 0xDF, 0xF0, 0xE4, 0x90, 0x82,
+0xAF, 0xF0, 0x90, 0x81, 0xAF, 0xE0, 0x13, 0x30,
+0xE0, 0x0D, 0x90, 0x81, 0x46, 0xE0, 0x44, 0x01,
+0xF0, 0x90, 0x81, 0x56, 0x74, 0xD0, 0xF0, 0x22,
+0x12, 0x4D, 0x70, 0x7B, 0x24, 0x02, 0x4F, 0xEC,
+0x7B, 0x25, 0x02, 0x4F, 0xEC, 0xAE, 0x07, 0x12,
+0x54, 0x44, 0xBF, 0x01, 0x0F, 0xD1, 0xD7, 0x20,
+0xE0, 0x0A, 0xAF, 0x06, 0x7D, 0x01, 0x12, 0x4B,
+0x1C, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0x90,
+0x81, 0x41, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x03,
+0x22, 0x90, 0x80, 0x46, 0xE0, 0xFF, 0x90, 0x82,
+0x8A, 0xE0, 0xFB, 0x90, 0x82, 0x95, 0x74, 0x0A,
+0xF0, 0x7D, 0x01, 0x12, 0x66, 0x0E, 0x90, 0x82,
+0x8B, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF, 0xF0, 0xFD,
+0x90, 0x82, 0x89, 0xE0, 0xFF, 0x12, 0x67, 0x02,
+0x90, 0x82, 0x8B, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
+0x90, 0x04, 0x80, 0xE0, 0x54, 0x0F, 0xFD, 0xAC,
+0x07, 0xF1, 0x7C, 0x44, 0x01, 0xF0, 0xF1, 0x7C,
+0x54, 0xFB, 0xF0, 0xAC, 0x07, 0x74, 0x16, 0x2C,
+0x12, 0x67, 0x48, 0xE0, 0x44, 0xFA, 0xF0, 0x74,
+0x15, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5,
+0x83, 0xE0, 0x44, 0x1F, 0xF0, 0xAC, 0x07, 0x74,
+0x06, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5,
+0x83, 0xE0, 0x44, 0x0F, 0xF0, 0x90, 0x04, 0x53,
+0xE4, 0xF0, 0x90, 0x04, 0x52, 0xF0, 0x90, 0x04,
+0x51, 0x74, 0xFF, 0xF0, 0x90, 0x04, 0x50, 0x74,
+0xFD, 0xF0, 0x74, 0x14, 0x2C, 0xF1, 0x74, 0xE0,
+0x54, 0xC0, 0x4D, 0xFD, 0x74, 0x14, 0x2F, 0xF1,
+0x74, 0xED, 0xF0, 0x22, 0xF5, 0x82, 0xE4, 0x34,
+0xFC, 0xF5, 0x83, 0x22, 0x74, 0x11, 0x2C, 0xF5,
+0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22,
+0xE4, 0xFE, 0xEF, 0xC3, 0x13, 0xFD, 0xEF, 0x30,
+0xE0, 0x02, 0x7E, 0x80, 0x90, 0xFD, 0x10, 0xED,
+0xF0, 0xAF, 0x06, 0x22, 0x7E, 0x00, 0x7F, 0x04,
+0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0xB7,
+0x22, 0xE0, 0x90, 0x01, 0xBA, 0xF0, 0x90, 0x81,
+0x4D, 0xE0, 0x90, 0x01, 0xBB, 0x22, 0xEF, 0x13,
+0x13, 0x13, 0x54, 0x1F, 0xFE, 0xEF, 0x54, 0x07,
+0xFF, 0x22, 0x90, 0x81, 0xAF, 0xE0, 0xC3, 0x13,
+0x22, 0x90, 0x82, 0x3B, 0x12, 0x45, 0x26, 0x02,
+0x1F, 0xA4, 0xAB, 0x54, 0xAA, 0x55, 0xA9, 0x56,
+0x02, 0x1F, 0xA4, 0x90, 0x06, 0x04, 0xE0, 0x54,
+0x7F, 0xF0, 0x22, 0x90, 0x06, 0x04, 0xE0, 0x44,
+0x40, 0xF0, 0x22, 0x90, 0x81, 0x46, 0xE0, 0x54,
+0xBF, 0xF0, 0x22, 0x7D, 0x01, 0x7F, 0x04, 0x02,
+0x4B, 0x1C, 0x0D, 0xBC
+};
+
+u32 array_length_mp_8188e_t_fw_nic_89em = 14364;
+
+#ifdef CONFIG_WOWLAN
+
+u8 array_mp_8188e_t_fw_wowlan[] = {
+0xE1, 0x88, 0x30, 0x00, 0x1C, 0x00, 0x00, 0x00,
+0x05, 0x05, 0x14, 0x27, 0xE4, 0x3F, 0x00, 0x00,
+0xA5, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x47, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xE1, 0xFD, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xE1, 0xAD, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x50, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xE7, 0x09, 0xF6, 0x08, 0xDF, 0xFA, 0x80, 0x46,
+0xE7, 0x09, 0xF2, 0x08, 0xDF, 0xFA, 0x80, 0x3E,
+0x88, 0x82, 0x8C, 0x83, 0xE7, 0x09, 0xF0, 0xA3,
+0xDF, 0xFA, 0x80, 0x32, 0xE3, 0x09, 0xF6, 0x08,
+0xDF, 0xFA, 0x80, 0x78, 0xE3, 0x09, 0xF2, 0x08,
+0xDF, 0xFA, 0x80, 0x70, 0x88, 0x82, 0x8C, 0x83,
+0xE3, 0x09, 0xF0, 0xA3, 0xDF, 0xFA, 0x80, 0x64,
+0x89, 0x82, 0x8A, 0x83, 0xE0, 0xA3, 0xF6, 0x08,
+0xDF, 0xFA, 0x80, 0x58, 0x89, 0x82, 0x8A, 0x83,
+0xE0, 0xA3, 0xF2, 0x08, 0xDF, 0xFA, 0x80, 0x4C,
+0x80, 0xD2, 0x80, 0xFA, 0x80, 0xC6, 0x80, 0xD4,
+0x80, 0x69, 0x80, 0xF2, 0x80, 0x33, 0x80, 0x10,
+0x80, 0xA6, 0x80, 0xEA, 0x80, 0x9A, 0x80, 0xA8,
+0x80, 0xDA, 0x80, 0xE2, 0x80, 0xCA, 0x80, 0x33,
+0x89, 0x82, 0x8A, 0x83, 0xEC, 0xFA, 0xE4, 0x93,
+0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC, 0xC5, 0x83,
+0xCC, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC,
+0xC5, 0x83, 0xCC, 0xDF, 0xE9, 0xDE, 0xE7, 0x80,
+0x0D, 0x89, 0x82, 0x8A, 0x83, 0xE4, 0x93, 0xA3,
+0xF6, 0x08, 0xDF, 0xF9, 0xEC, 0xFA, 0xA9, 0xF0,
+0xED, 0xFB, 0x22, 0x89, 0x82, 0x8A, 0x83, 0xEC,
+0xFA, 0xE0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC,
+0xC5, 0x83, 0xCC, 0xF0, 0xA3, 0xC8, 0xC5, 0x82,
+0xC8, 0xCC, 0xC5, 0x83, 0xCC, 0xDF, 0xEA, 0xDE,
+0xE8, 0x80, 0xDB, 0x89, 0x82, 0x8A, 0x83, 0xE4,
+0x93, 0xA3, 0xF2, 0x08, 0xDF, 0xF9, 0x80, 0xCC,
+0x88, 0xF0, 0xEF, 0x60, 0x01, 0x0E, 0x4E, 0x60,
+0xC3, 0x88, 0xF0, 0xED, 0x24, 0x02, 0xB4, 0x04,
+0x00, 0x50, 0xB9, 0xF5, 0x82, 0xEB, 0x24, 0x02,
+0xB4, 0x04, 0x00, 0x50, 0xAF, 0x23, 0x23, 0x45,
+0x82, 0x23, 0x90, 0x41, 0x50, 0x73, 0xC5, 0xF0,
+0xF8, 0xA3, 0xE0, 0x28, 0xF0, 0xC5, 0xF0, 0xF8,
+0xE5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83,
+0xE0, 0x38, 0xF0, 0x22, 0xC3, 0xEF, 0x9B, 0xFF,
+0xEE, 0x9A, 0xFE, 0xED, 0x99, 0xFD, 0xEC, 0x98,
+0xFC, 0x22, 0xEF, 0x4B, 0xFF, 0xEE, 0x4A, 0xFE,
+0xED, 0x49, 0xFD, 0xEC, 0x48, 0xFC, 0x22, 0xEB,
+0x9F, 0xF5, 0xF0, 0xEA, 0x9E, 0x42, 0xF0, 0xE9,
+0x9D, 0x42, 0xF0, 0xE8, 0x9C, 0x45, 0xF0, 0x22,
+0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0x22, 0xE0, 0xF8, 0xA3, 0xE0,
+0xF9, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0x22,
+0xA4, 0x25, 0x82, 0xF5, 0x82, 0xE5, 0xF0, 0x35,
+0x83, 0xF5, 0x83, 0x22, 0xE0, 0xFB, 0xA3, 0xE0,
+0xFA, 0xA3, 0xE0, 0xF9, 0x22, 0xEB, 0xF0, 0xA3,
+0xEA, 0xF0, 0xA3, 0xE9, 0xF0, 0x22, 0xD0, 0x83,
+0xD0, 0x82, 0xF8, 0xE4, 0x93, 0x70, 0x12, 0x74,
+0x01, 0x93, 0x70, 0x0D, 0xA3, 0xA3, 0x93, 0xF8,
+0x74, 0x01, 0x93, 0xF5, 0x82, 0x88, 0x83, 0xE4,
+0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xEF, 0xA3,
+0xA3, 0xA3, 0x80, 0xDF, 0xE3, 0xF5, 0xF0, 0x09,
+0xE2, 0x08, 0xB5, 0xF0, 0x6B, 0xDF, 0xF5, 0x80,
+0x67, 0xE3, 0xF5, 0xF0, 0x09, 0xE6, 0x08, 0xB5,
+0xF0, 0x5E, 0xDF, 0xF5, 0x80, 0x5A, 0x87, 0xF0,
+0x09, 0xE6, 0x08, 0xB5, 0xF0, 0x52, 0xDF, 0xF6,
+0x80, 0x4E, 0x87, 0xF0, 0x09, 0xE2, 0x08, 0xB5,
+0xF0, 0x46, 0xDF, 0xF6, 0x80, 0x42, 0x88, 0x82,
+0x8C, 0x83, 0x87, 0xF0, 0x09, 0xE0, 0xA3, 0xB5,
+0xF0, 0x36, 0xDF, 0xF6, 0x80, 0x32, 0x88, 0x82,
+0x8C, 0x83, 0x87, 0xF0, 0x09, 0xE4, 0x93, 0xA3,
+0xB5, 0xF0, 0x25, 0xDF, 0xF5, 0x80, 0x21, 0x88,
+0x82, 0x8C, 0x83, 0xE3, 0xF5, 0xF0, 0x09, 0xE0,
+0xA3, 0xB5, 0xF0, 0x14, 0xDF, 0xF5, 0x80, 0x10,
+0x88, 0x82, 0x8C, 0x83, 0xE3, 0xF5, 0xF0, 0x09,
+0xE4, 0x93, 0xA3, 0xB5, 0xF0, 0x02, 0xDF, 0xF4,
+0x02, 0x43, 0xC3, 0x80, 0x87, 0x80, 0xE9, 0x80,
+0x90, 0x80, 0xD4, 0x80, 0x3E, 0x80, 0x15, 0x80,
+0x6E, 0x80, 0x7E, 0x80, 0x9D, 0x80, 0xB7, 0x80,
+0x8D, 0x80, 0xA3, 0x80, 0x51, 0x80, 0x74, 0x80,
+0x3C, 0x02, 0x43, 0xCF, 0x89, 0x82, 0x8A, 0x83,
+0xEC, 0xFA, 0xE4, 0x93, 0xF5, 0xF0, 0xA3, 0xC8,
+0xC5, 0x82, 0xC8, 0xCC, 0xC5, 0x83, 0xCC, 0xE4,
+0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC, 0xC5,
+0x83, 0xCC, 0xB5, 0xF0, 0x76, 0xDF, 0xE3, 0xDE,
+0xE1, 0x80, 0x70, 0x89, 0x82, 0x8A, 0x83, 0xE4,
+0x93, 0xF5, 0xF0, 0xA3, 0xE2, 0x08, 0xB5, 0xF0,
+0x62, 0xDF, 0xF4, 0x80, 0x5E, 0x89, 0x82, 0x8A,
+0x83, 0xE0, 0xF5, 0xF0, 0xA3, 0xE6, 0x08, 0xB5,
+0xF0, 0x51, 0xDF, 0xF5, 0x80, 0x4D, 0x89, 0x82,
+0x8A, 0x83, 0xE0, 0xF5, 0xF0, 0xA3, 0xE2, 0x08,
+0xB5, 0xF0, 0x40, 0xDF, 0xF5, 0x80, 0x3C, 0x89,
+0x82, 0x8A, 0x83, 0xE4, 0x93, 0xF5, 0xF0, 0xA3,
+0xE6, 0x08, 0xB5, 0xF0, 0x2E, 0xDF, 0xF4, 0x80,
+0x2A, 0x80, 0x02, 0x80, 0x57, 0x89, 0x82, 0x8A,
+0x83, 0xEC, 0xFA, 0xE4, 0x93, 0xF5, 0xF0, 0xA3,
+0xC8, 0xC5, 0x82, 0xC8, 0xCC, 0xC5, 0x83, 0xCC,
+0xE0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC, 0xC5,
+0x83, 0xCC, 0xB5, 0xF0, 0x06, 0xDF, 0xE4, 0xDE,
+0xE2, 0x80, 0x00, 0x7F, 0xFF, 0xB5, 0xF0, 0x02,
+0x0F, 0x22, 0x40, 0x02, 0x7F, 0x01, 0x22, 0x89,
+0x82, 0x8A, 0x83, 0xEC, 0xFA, 0xE0, 0xF5, 0xF0,
+0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC, 0xC5, 0x83,
+0xCC, 0xE0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC,
+0xC5, 0x83, 0xCC, 0xB5, 0xF0, 0xD5, 0xDF, 0xE5,
+0xDE, 0xE3, 0x80, 0xCF, 0x89, 0x82, 0x8A, 0x83,
+0xEC, 0xFA, 0xE0, 0xF5, 0xF0, 0xA3, 0xC8, 0xC5,
+0x82, 0xC8, 0xCC, 0xC5, 0x83, 0xCC, 0xE4, 0x93,
+0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCC, 0xC5, 0x83,
+0xCC, 0xB5, 0xF0, 0xAF, 0xDF, 0xE4, 0xDE, 0xE2,
+0x80, 0xA9, 0x88, 0xF0, 0xEF, 0x60, 0x01, 0x0E,
+0x4E, 0x60, 0xAB, 0xED, 0x24, 0x02, 0xB4, 0x04,
+0x00, 0x50, 0x98, 0xF5, 0x82, 0xEB, 0x24, 0x02,
+0xB4, 0x04, 0x00, 0x50, 0x8E, 0x23, 0x23, 0x45,
+0x82, 0x23, 0x90, 0x43, 0x0B, 0x73, 0xEF, 0x4E,
+0x60, 0x12, 0xEF, 0x60, 0x01, 0x0E, 0xED, 0xBB,
+0x01, 0x0B, 0x89, 0x82, 0x8A, 0x83, 0xF0, 0xA3,
+0xDF, 0xFC, 0xDE, 0xFA, 0x22, 0x89, 0xF0, 0x50,
+0x07, 0xF7, 0x09, 0xDF, 0xFC, 0xA9, 0xF0, 0x22,
+0xBB, 0xFE, 0xFC, 0xF3, 0x09, 0xDF, 0xFC, 0xA9,
+0xF0, 0x22, 0xC2, 0xAF, 0x80, 0xFE, 0x32, 0x12,
+0x44, 0x6E, 0x85, 0xD0, 0x0B, 0x75, 0xD0, 0x08,
+0xAA, 0xE0, 0xC2, 0x8C, 0xE5, 0x8A, 0x24, 0x67,
+0xF5, 0x8A, 0xE5, 0x8C, 0x34, 0x79, 0xF5, 0x8C,
+0xD2, 0x8C, 0xEC, 0x24, 0x87, 0xF8, 0xE6, 0xBC,
+0x02, 0x02, 0x74, 0xFF, 0xC3, 0x95, 0x81, 0xB4,
+0x40, 0x00, 0x40, 0xCE, 0x79, 0x03, 0x78, 0x80,
+0x16, 0xE6, 0x08, 0x70, 0x0B, 0xC2, 0xAF, 0xE6,
+0x30, 0xE1, 0x03, 0x44, 0x18, 0xF6, 0xD2, 0xAF,
+0x08, 0xD9, 0xED, 0xEA, 0x8B, 0xD0, 0x22, 0xE5,
+0x0C, 0xFF, 0x23, 0x24, 0x81, 0xF8, 0x0F, 0x08,
+0x08, 0xBF, 0x03, 0x04, 0x7F, 0x00, 0x78, 0x81,
+0xE6, 0x30, 0xE4, 0xF2, 0x00, 0xE5, 0x0C, 0xC3,
+0x9F, 0x50, 0x20, 0x05, 0x0C, 0x74, 0x86, 0x25,
+0x0C, 0xF8, 0xE6, 0xFD, 0xA6, 0x81, 0x08, 0xE6,
+0xAE, 0x0C, 0xBE, 0x02, 0x02, 0x74, 0xFF, 0xCD,
+0xF8, 0xE8, 0x6D, 0x60, 0xE0, 0x08, 0xE6, 0xC0,
+0xE0, 0x80, 0xF6, 0xE5, 0x0C, 0xD3, 0x9F, 0x40,
+0x27, 0xE5, 0x0C, 0x24, 0x87, 0xF8, 0xE6, 0xAE,
+0x0C, 0xBE, 0x02, 0x02, 0x74, 0xFF, 0xFD, 0x18,
+0xE6, 0xCD, 0xF8, 0xE5, 0x81, 0x6D, 0x60, 0x06,
+0xD0, 0xE0, 0xF6, 0x18, 0x80, 0xF5, 0xE5, 0x0C,
+0x24, 0x86, 0xC8, 0xF6, 0x15, 0x0C, 0x80, 0xD3,
+0xE5, 0x0C, 0x23, 0x24, 0x81, 0xF8, 0x7F, 0x04,
+0xC2, 0xAF, 0xE6, 0x30, 0xE0, 0x03, 0x10, 0xE2,
+0x0C, 0x7F, 0x00, 0x30, 0xE1, 0x07, 0x30, 0xE3,
+0x04, 0x7F, 0x08, 0x54, 0xF4, 0x54, 0x7C, 0xC6,
+0xD2, 0xAF, 0x54, 0x80, 0x42, 0x07, 0x22, 0x78,
+0x86, 0xA6, 0x81, 0x74, 0x02, 0x60, 0x06, 0xFF,
+0x08, 0x76, 0xFF, 0xDF, 0xFB, 0x7F, 0x03, 0xE4,
+0x78, 0x80, 0xF6, 0x08, 0xF6, 0x08, 0xDF, 0xFA,
+0x78, 0x81, 0x76, 0x30, 0x90, 0x47, 0xA7, 0x74,
+0x01, 0x93, 0xC0, 0xE0, 0xE4, 0x93, 0xC0, 0xE0,
+0x43, 0x89, 0x01, 0x75, 0x8A, 0x60, 0x75, 0x8C,
+0x79, 0xD2, 0x8C, 0xD2, 0xAF, 0x22, 0x02, 0xEF,
+0xD3, 0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22,
+0x74, 0x81, 0x2F, 0x2F, 0xF8, 0xE6, 0x20, 0xE5,
+0xF4, 0xC2, 0xAF, 0xE6, 0x44, 0x30, 0xF6, 0xD2,
+0xAF, 0xAE, 0x0C, 0xEE, 0xC3, 0x9F, 0x50, 0x21,
+0x0E, 0x74, 0x86, 0x2E, 0xF8, 0xE6, 0xF9, 0x08,
+0xE6, 0x18, 0xBE, 0x02, 0x02, 0x74, 0xFF, 0xFD,
+0xED, 0x69, 0x60, 0x09, 0x09, 0xE7, 0x19, 0x19,
+0xF7, 0x09, 0x09, 0x80, 0xF3, 0x16, 0x16, 0x80,
+0xDA, 0xEE, 0xD3, 0x9F, 0x40, 0x04, 0x05, 0x81,
+0x05, 0x81, 0xEE, 0xD3, 0x9F, 0x40, 0x22, 0x74,
+0x86, 0x2E, 0xF8, 0x08, 0xE6, 0xF9, 0xEE, 0xB5,
+0x0C, 0x02, 0xA9, 0x81, 0x18, 0x06, 0x06, 0xE6,
+0xFD, 0xED, 0x69, 0x60, 0x09, 0x19, 0x19, 0xE7,
+0x09, 0x09, 0xF7, 0x19, 0x80, 0xF3, 0x1E, 0x80,
+0xD9, 0xEF, 0x24, 0x86, 0xF8, 0xE6, 0x04, 0xF8,
+0xEF, 0x2F, 0x04, 0x90, 0x47, 0xA7, 0x93, 0xF6,
+0x08, 0xEF, 0x2F, 0x93, 0xF6, 0x7F, 0x00, 0x22,
+0xEF, 0xD3, 0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF,
+0x22, 0xEF, 0x23, 0x24, 0x81, 0xF8, 0xE6, 0x30,
+0xE5, 0xF4, 0xC2, 0xAF, 0xE6, 0x54, 0x8C, 0xF6,
+0xD2, 0xAF, 0xE5, 0x0C, 0xB5, 0x07, 0x0A, 0x74,
+0x86, 0x2F, 0xF8, 0xE6, 0xF5, 0x81, 0x02, 0x44,
+0xB7, 0x50, 0x2E, 0x74, 0x87, 0x2F, 0xF8, 0xE6,
+0xBF, 0x02, 0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6,
+0xF9, 0x74, 0x86, 0x2F, 0xF8, 0xFB, 0xE6, 0xFC,
+0xE9, 0x6C, 0x60, 0x08, 0xA8, 0x05, 0xE7, 0xF6,
+0x1D, 0x19, 0x80, 0xF4, 0xA8, 0x03, 0xA6, 0x05,
+0x1F, 0xE5, 0x0C, 0xB5, 0x07, 0xE3, 0x7F, 0x00,
+0x22, 0x74, 0x87, 0x2F, 0xF8, 0xE6, 0xFD, 0x18,
+0x86, 0x01, 0x0F, 0x74, 0x86, 0x2F, 0xF8, 0xA6,
+0x01, 0x08, 0x86, 0x04, 0xE5, 0x0C, 0xB5, 0x07,
+0x02, 0xAC, 0x81, 0xED, 0x6C, 0x60, 0x08, 0x0D,
+0x09, 0xA8, 0x05, 0xE6, 0xF7, 0x80, 0xF4, 0xE5,
+0x0C, 0xB5, 0x07, 0xDE, 0x89, 0x81, 0x7F, 0x00,
+0x22, 0xEF, 0xD3, 0x94, 0x02, 0x40, 0x03, 0x7F,
+0xFF, 0x22, 0xEF, 0x23, 0x24, 0x81, 0xF8, 0xC2,
+0xAF, 0xE6, 0x30, 0xE5, 0x05, 0x30, 0xE0, 0x02,
+0xD2, 0xE4, 0xD2, 0xE2, 0xC6, 0xD2, 0xAF, 0x7F,
+0x00, 0x30, 0xE2, 0x01, 0x0F, 0x02, 0x44, 0xB6,
+0x8F, 0xF0, 0xE4, 0xFF, 0xFE, 0xE5, 0x0C, 0x23,
+0x24, 0x80, 0xF8, 0xC2, 0xA9, 0x30, 0xF7, 0x0D,
+0x7F, 0x08, 0xE6, 0x60, 0x0B, 0x2D, 0xF6, 0x60,
+0x30, 0x50, 0x2E, 0x80, 0x07, 0x30, 0xF1, 0x06,
+0xED, 0xF6, 0x60, 0x25, 0x7E, 0x02, 0x08, 0x30,
+0xF0, 0x10, 0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x23,
+0x0E, 0x30, 0xE2, 0x0C, 0xD2, 0xAF, 0x7F, 0x04,
+0x80, 0x12, 0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x13,
+0x54, 0xEC, 0x4E, 0xF6, 0xD2, 0xAF, 0x02, 0x44,
+0xB7, 0x7F, 0x08, 0x08, 0xEF, 0x44, 0x83, 0xF4,
+0xC2, 0xAF, 0x56, 0xC6, 0xD2, 0xAF, 0x54, 0x80,
+0x4F, 0xFF, 0x22, 0x02, 0x47, 0x51, 0x02, 0x45,
+0x47, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3,
+0x40, 0x03, 0xF6, 0x80, 0x01, 0xF2, 0x08, 0xDF,
+0xF4, 0x80, 0x29, 0xE4, 0x93, 0xA3, 0xF8, 0x54,
+0x07, 0x24, 0x0C, 0xC8, 0xC3, 0x33, 0xC4, 0x54,
+0x0F, 0x44, 0x20, 0xC8, 0x83, 0x40, 0x04, 0xF4,
+0x56, 0x80, 0x01, 0x46, 0xF6, 0xDF, 0xE4, 0x80,
+0x0B, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
+0x80, 0x90, 0x47, 0x96, 0xE4, 0x7E, 0x01, 0x93,
+0x60, 0xBC, 0xA3, 0xFF, 0x54, 0x3F, 0x30, 0xE5,
+0x09, 0x54, 0x1F, 0xFE, 0xE4, 0x93, 0xA3, 0x60,
+0x01, 0x0E, 0xCF, 0x54, 0xC0, 0x25, 0xE0, 0x60,
+0xA8, 0x40, 0xB8, 0xE4, 0x93, 0xA3, 0xFA, 0xE4,
+0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0xC8, 0xC5,
+0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xF0, 0xA3,
+0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA,
+0xDF, 0xE9, 0xDE, 0xE7, 0x80, 0xBE, 0x41, 0x84,
+0x92, 0x00, 0x41, 0x84, 0x93, 0x00, 0x41, 0x84,
+0xA3, 0x00, 0x41, 0x84, 0xA4, 0x00, 0x00, 0x60,
+0x16, 0x67, 0xFC, 0x6A, 0x33, 0xC0, 0xE0, 0xC0,
+0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75,
+0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02,
+0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06,
+0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0xAD, 0xF0,
+0x74, 0x47, 0xA3, 0xF0, 0x12, 0x78, 0x9A, 0x74,
+0xAD, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x47,
+0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05,
+0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01,
+0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83,
+0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0xC0, 0xE0, 0xC0,
+0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75,
+0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, 0x02,
+0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06,
+0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0xFD, 0xF0,
+0x74, 0x47, 0xA3, 0xF0, 0x12, 0x78, 0xD4, 0xE5,
+0x41, 0x30, 0xE3, 0x03, 0x12, 0x79, 0x31, 0xE5,
+0x41, 0x30, 0xE4, 0x03, 0x12, 0x50, 0xDE, 0xE5,
+0x43, 0x30, 0xE0, 0x03, 0x12, 0x79, 0x7A, 0xE5,
+0x43, 0x30, 0xE1, 0x02, 0x11, 0x9B, 0xE5, 0x43,
+0x30, 0xE2, 0x03, 0x12, 0x77, 0x6F, 0xE5, 0x43,
+0x30, 0xE3, 0x02, 0xF1, 0xE1, 0xE5, 0x43, 0x30,
+0xE4, 0x03, 0x12, 0x72, 0x73, 0xE5, 0x43, 0x30,
+0xE5, 0x03, 0x12, 0x71, 0x2B, 0xE5, 0x43, 0x30,
+0xE6, 0x03, 0x12, 0x72, 0x38, 0xE5, 0x44, 0x30,
+0xE1, 0x03, 0x12, 0x77, 0x43, 0x74, 0xFD, 0x04,
+0x90, 0x01, 0xC4, 0xF0, 0x74, 0x47, 0xA3, 0xF0,
+0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04,
+0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00,
+0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0,
+0xD0, 0xE0, 0x32, 0x90, 0x81, 0x0A, 0xE0, 0x70,
+0x02, 0x21, 0x2B, 0x90, 0x81, 0x21, 0xE0, 0x04,
+0x31, 0x37, 0x12, 0x42, 0x1A, 0xC0, 0x04, 0xC0,
+0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x05, 0x62,
+0x31, 0x51, 0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12,
+0x42, 0x1A, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06,
+0xC0, 0x07, 0xA3, 0x31, 0x51, 0x78, 0x18, 0x12,
+0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01,
+0xD0, 0x00, 0x12, 0x42, 0x1A, 0x90, 0x81, 0x55,
+0x12, 0x7F, 0x4E, 0x54, 0x7F, 0xF0, 0xA3, 0xE0,
+0x30, 0xE0, 0x0C, 0x12, 0x76, 0xFA, 0x74, 0x05,
+0xF0, 0x12, 0x75, 0xBF, 0x12, 0x77, 0x12, 0x12,
+0x73, 0x7C, 0x54, 0x1F, 0x30, 0xE0, 0x0D, 0x90,
+0x01, 0x3B, 0xE0, 0x30, 0xE4, 0x06, 0x12, 0x6F,
+0xB5, 0x12, 0x6F, 0xDB, 0x90, 0x84, 0x9C, 0xE0,
+0x04, 0xF0, 0xE0, 0xC3, 0x94, 0x80, 0x40, 0x0B,
+0x90, 0x01, 0x98, 0xE0, 0x54, 0xFE, 0xF0, 0xE0,
+0x44, 0x01, 0xF0, 0x12, 0x74, 0x45, 0x12, 0x7B,
+0xD6, 0xE4, 0x90, 0x83, 0xC7, 0xF0, 0x22, 0xF0,
+0x90, 0x05, 0x61, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD,
+0xFE, 0x78, 0x08, 0x12, 0x20, 0xBB, 0xA8, 0x04,
+0xA9, 0x05, 0xAA, 0x06, 0xAB, 0x07, 0x90, 0x05,
+0x60, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x22,
+0xE4, 0x90, 0x83, 0xDD, 0xF0, 0x90, 0x81, 0x0A,
+0xE0, 0x60, 0x59, 0xF1, 0xA8, 0x64, 0x01, 0x70,
+0x53, 0x12, 0x77, 0x22, 0x31, 0x37, 0x12, 0x42,
+0x1A, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0,
+0x07, 0x90, 0x05, 0x62, 0x31, 0x51, 0x78, 0x10,
+0x12, 0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0,
+0x01, 0xD0, 0x00, 0x12, 0x42, 0x1A, 0xC0, 0x04,
+0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xA3, 0x31,
+0x51, 0x78, 0x18, 0x12, 0x20, 0xBB, 0xD0, 0x03,
+0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x7F,
+0x48, 0x44, 0x80, 0xF0, 0x90, 0x83, 0xDD, 0x74,
+0x01, 0xF0, 0xE4, 0x90, 0x81, 0x11, 0xF0, 0x04,
+0x60, 0x02, 0x51, 0x24, 0x22, 0xE4, 0xF5, 0x4E,
+0x90, 0x81, 0x0A, 0xE0, 0x60, 0x5D, 0xF1, 0xA8,
+0x64, 0x01, 0x70, 0x57, 0x31, 0x38, 0x12, 0x42,
+0x1A, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0,
+0x07, 0x90, 0x05, 0x62, 0x31, 0x51, 0x78, 0x10,
+0x12, 0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0,
+0x01, 0xD0, 0x00, 0x12, 0x42, 0x1A, 0xC0, 0x04,
+0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xA3, 0x31,
+0x51, 0x78, 0x18, 0x12, 0x20, 0xBB, 0xD0, 0x03,
+0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x7F,
+0x48, 0x44, 0x80, 0xF0, 0x12, 0x77, 0x3A, 0x60,
+0x09, 0x90, 0x81, 0x06, 0x12, 0x77, 0x2A, 0x20,
+0xE0, 0x03, 0x75, 0x4E, 0x01, 0xE5, 0x4E, 0x60,
+0x02, 0x51, 0x24, 0x22, 0x90, 0x81, 0x0E, 0xE0,
+0x44, 0x10, 0xF0, 0x90, 0x81, 0x13, 0xE0, 0x60,
+0x04, 0x64, 0x01, 0x70, 0x11, 0xE4, 0xF5, 0x1D,
+0x90, 0x81, 0x13, 0xE0, 0x51, 0x63, 0x51, 0x72,
+0x90, 0x81, 0x13, 0xE0, 0x80, 0x0D, 0xE4, 0xF5,
+0x1D, 0x12, 0x76, 0x8F, 0x51, 0x63, 0x51, 0x72,
+0x12, 0x76, 0x8F, 0x51, 0x63, 0x90, 0x81, 0x23,
+0xF0, 0x90, 0x81, 0x0D, 0xE0, 0x20, 0xE2, 0x02,
+0x91, 0x45, 0x22, 0xFF, 0x90, 0x81, 0x12, 0xE0,
+0x2F, 0x22, 0xF0, 0xE4, 0xF5, 0x1D, 0x90, 0x81,
+0x68, 0xE0, 0xF5, 0x1E, 0xE4, 0xFB, 0xFD, 0x7F,
+0x54, 0x7E, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x8E, 0x19, 0x8F, 0x1A, 0xE5, 0x1E,
+0x51, 0xD0, 0x85, 0x19, 0x83, 0x85, 0x1A, 0x82,
+0xF0, 0xE5, 0x1D, 0x51, 0xD0, 0xFF, 0xE5, 0x1E,
+0x13, 0x13, 0x13, 0x54, 0x1F, 0x4F, 0xA3, 0xF0,
+0xEB, 0x51, 0xD0, 0xFF, 0xE5, 0x1D, 0x13, 0x13,
+0x13, 0x54, 0x1F, 0x4F, 0x51, 0xD7, 0xF0, 0xBD,
+0x01, 0x0D, 0x85, 0x1A, 0x82, 0x8E, 0x83, 0xA3,
+0xA3, 0xA3, 0x74, 0x03, 0xF0, 0x80, 0x06, 0x51,
+0xD7, 0xA3, 0x74, 0x01, 0xF0, 0x51, 0xD7, 0xA3,
+0x74, 0x05, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x54, 0x07, 0xC4, 0x33, 0x54, 0xE0, 0x22, 0x85,
+0x1A, 0x82, 0x85, 0x19, 0x83, 0xA3, 0xA3, 0x22,
+0x31, 0x38, 0x12, 0x42, 0x1A, 0xC0, 0x04, 0xC0,
+0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x05, 0x62,
+0x31, 0x51, 0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0,
+0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12,
+0x42, 0x1A, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06,
+0xC0, 0x07, 0xA3, 0x31, 0x51, 0x78, 0x18, 0x12,
+0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01,
+0xD0, 0x00, 0x12, 0x42, 0x1A, 0x90, 0x81, 0x59,
+0x12, 0x20, 0xCE, 0x90, 0x81, 0x5D, 0x12, 0x42,
+0x38, 0x90, 0x81, 0x59, 0x12, 0x42, 0x44, 0xC3,
+0x12, 0x42, 0x27, 0x40, 0x48, 0x90, 0x81, 0x05,
+0xE0, 0x90, 0x81, 0x5D, 0x30, 0xE0, 0x11, 0x12,
+0x7F, 0x19, 0xFF, 0x90, 0x81, 0x27, 0xE0, 0x24,
+0x04, 0x2F, 0xFF, 0x90, 0x81, 0x61, 0x80, 0x07,
+0x12, 0x7F, 0x19, 0xFF, 0x90, 0x81, 0x62, 0xE0,
+0xFE, 0xC3, 0xEF, 0x9E, 0x90, 0x83, 0xD8, 0xF0,
+0x90, 0x83, 0xD8, 0xE0, 0xFF, 0xC3, 0x94, 0x2D,
+0x50, 0x13, 0x74, 0x28, 0x2F, 0xF5, 0x82, 0xE4,
+0x34, 0x81, 0xF5, 0x83, 0xE0, 0x04, 0xF0, 0x90,
+0x81, 0x20, 0xE0, 0x04, 0xF0, 0x90, 0x81, 0x20,
+0xE0, 0xFF, 0xD3, 0x90, 0x81, 0x64, 0xE0, 0x9F,
+0x90, 0x81, 0x63, 0xE0, 0x94, 0x00, 0x40, 0x02,
+0x81, 0x44, 0xE4, 0xFF, 0xFE, 0x12, 0x7F, 0x35,
+0xEF, 0xD3, 0x9D, 0x40, 0x07, 0x90, 0x83, 0xD9,
+0xEE, 0xF0, 0x80, 0x05, 0x0E, 0xEE, 0xB4, 0x2D,
+0xEC, 0xE4, 0xFF, 0xFE, 0x12, 0x7F, 0x35, 0xC3,
+0x90, 0x81, 0x64, 0xE0, 0x9D, 0xFD, 0x90, 0x81,
+0x63, 0xE0, 0x94, 0x00, 0xFC, 0xEF, 0xD3, 0x9D,
+0xE4, 0x9C, 0x40, 0x07, 0x90, 0x83, 0xDA, 0xEE,
+0xF0, 0x80, 0x05, 0x0E, 0xEE, 0xB4, 0x2D, 0xDC,
+0x90, 0x83, 0xD9, 0xE0, 0x90, 0x81, 0x25, 0xF0,
+0x90, 0x83, 0xDA, 0xE0, 0x90, 0x81, 0x26, 0x12,
+0x7F, 0xD1, 0x94, 0x0A, 0x40, 0x0A, 0xEF, 0x24,
+0xF6, 0x90, 0x81, 0x1D, 0xF0, 0xE4, 0x80, 0x0A,
+0xE4, 0x90, 0x81, 0x1D, 0x12, 0x7F, 0xD1, 0x74,
+0x0A, 0x9F, 0x90, 0x81, 0x1C, 0xF0, 0x90, 0x81,
+0x25, 0xE0, 0xFF, 0xA3, 0xE0, 0xC3, 0x9F, 0x90,
+0x81, 0x23, 0xF0, 0x90, 0x81, 0x05, 0xE0, 0x30,
+0xE0, 0x05, 0x90, 0x81, 0x61, 0x80, 0x03, 0x90,
+0x81, 0x62, 0xE0, 0x04, 0xFF, 0x90, 0x81, 0x23,
+0xE0, 0x2F, 0xF0, 0x90, 0x81, 0x23, 0xE0, 0xC3,
+0x94, 0x10, 0x50, 0x03, 0x74, 0x10, 0xF0, 0x90,
+0x81, 0x23, 0xE0, 0x24, 0x02, 0xF0, 0x12, 0x76,
+0xFA, 0x74, 0x03, 0xF0, 0x12, 0x75, 0xBF, 0xE4,
+0xFF, 0x12, 0x7B, 0x1C, 0x22, 0x7D, 0x01, 0x7F,
+0x04, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x90, 0x84, 0x9F, 0xED, 0xF0, 0x90, 0x81, 0x05,
+0xE0, 0xFE, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30,
+0xE0, 0x02, 0xA1, 0x93, 0xEE, 0x12, 0x5F, 0x49,
+0x30, 0xE0, 0x02, 0xA1, 0x93, 0x90, 0x81, 0x0D,
+0xE0, 0xFE, 0x6F, 0x70, 0x02, 0xA1, 0x93, 0xEF,
+0x70, 0x02, 0xA1, 0x07, 0x24, 0xFE, 0x70, 0x02,
+0xA1, 0x41, 0x24, 0xFE, 0x60, 0x49, 0x24, 0xFC,
+0x70, 0x02, 0xA1, 0x7C, 0x24, 0xFC, 0x60, 0x02,
+0xA1, 0x8C, 0xEE, 0xB4, 0x0E, 0x02, 0xB1, 0xDF,
+0x90, 0x81, 0x0D, 0xE0, 0x70, 0x04, 0x7F, 0x01,
+0xD1, 0x1F, 0x90, 0x81, 0x0D, 0xE0, 0xB4, 0x06,
+0x02, 0xB1, 0xFC, 0x90, 0x81, 0x0D, 0xE0, 0xB4,
+0x04, 0x0E, 0x90, 0x84, 0x9F, 0xE0, 0xFF, 0x60,
+0x05, 0x12, 0x77, 0xAD, 0x80, 0x02, 0xF1, 0xAE,
+0x90, 0x81, 0x0D, 0xE0, 0x64, 0x08, 0x60, 0x02,
+0xA1, 0x8C, 0x12, 0x7B, 0x59, 0xA1, 0x8C, 0x90,
+0x81, 0x0D, 0xE0, 0x70, 0x04, 0x7F, 0x01, 0xD1,
+0x1F, 0x90, 0x81, 0x0D, 0xE0, 0xB4, 0x06, 0x02,
+0xB1, 0xFC, 0x90, 0x81, 0x0D, 0xE0, 0xB4, 0x0E,
+0x07, 0xB1, 0x98, 0xBF, 0x01, 0x02, 0xB1, 0xDF,
+0x90, 0x81, 0x0D, 0xE0, 0x64, 0x0C, 0x60, 0x02,
+0xA1, 0x8C, 0xB1, 0x98, 0xEF, 0x64, 0x01, 0x60,
+0x02, 0xA1, 0x8C, 0xD1, 0x53, 0xA1, 0x8C, 0x90,
+0x81, 0x0D, 0xE0, 0xB4, 0x0E, 0x07, 0xB1, 0x98,
+0xBF, 0x01, 0x02, 0xB1, 0xDF, 0x90, 0x81, 0x0D,
+0xE0, 0xB4, 0x06, 0x02, 0xB1, 0xFC, 0x90, 0x81,
+0x0D, 0xE0, 0xB4, 0x0C, 0x07, 0xB1, 0x98, 0xBF,
+0x01, 0x02, 0xD1, 0x53, 0x90, 0x81, 0x0D, 0xE0,
+0x64, 0x04, 0x70, 0x58, 0x12, 0x7A, 0x66, 0xEF,
+0x64, 0x01, 0x70, 0x50, 0x12, 0x6E, 0xDC, 0x80,
+0x4B, 0x90, 0x81, 0x0D, 0xE0, 0xB4, 0x0E, 0x07,
+0xB1, 0x98, 0xBF, 0x01, 0x02, 0xB1, 0xDF, 0x90,
+0x81, 0x0D, 0xE0, 0xB4, 0x06, 0x02, 0xB1, 0xFC,
+0x90, 0x81, 0x0D, 0xE0, 0xB4, 0x0C, 0x07, 0xB1,
+0x98, 0xBF, 0x01, 0x02, 0xD1, 0x53, 0x90, 0x81,
+0x0D, 0xE0, 0x70, 0x04, 0x7F, 0x01, 0xD1, 0x1F,
+0x90, 0x81, 0x0D, 0xE0, 0xB4, 0x04, 0x15, 0x12,
+0x7A, 0xF3, 0x80, 0x10, 0x90, 0x81, 0x0D, 0xE0,
+0xB4, 0x0C, 0x09, 0x12, 0x73, 0x85, 0x30, 0xE0,
+0x03, 0x12, 0x6E, 0xCF, 0x90, 0x81, 0x0D, 0x12,
+0x77, 0x62, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12,
+0x7A, 0x4D, 0xEF, 0x64, 0x01, 0x60, 0x05, 0x75,
+0x1F, 0x01, 0x80, 0x20, 0x12, 0x77, 0x32, 0x54,
+0x1F, 0x30, 0xE0, 0x05, 0x75, 0x1F, 0x02, 0x80,
+0x13, 0x90, 0x81, 0x0C, 0xE0, 0xD3, 0x94, 0x04,
+0x40, 0x05, 0x75, 0x1F, 0x08, 0x80, 0x05, 0x12,
+0x7A, 0xCD, 0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74,
+0x02, 0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x1F, 0xF0,
+0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90,
+0x81, 0x06, 0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x04,
+0x7D, 0x0C, 0x80, 0x05, 0x12, 0x7B, 0xCA, 0x7D,
+0x04, 0x7F, 0x01, 0xD1, 0x86, 0xE4, 0xFB, 0xFD,
+0x7F, 0xFF, 0x80, 0x41, 0x90, 0x81, 0x06, 0xE0,
+0x90, 0x06, 0x04, 0x20, 0xE0, 0x08, 0xE0, 0x44,
+0x40, 0xF0, 0x7D, 0x04, 0x80, 0x06, 0xE0, 0x54,
+0x7F, 0xF0, 0x7D, 0x0C, 0x7F, 0x01, 0xD1, 0x86,
+0xE4, 0xFB, 0xFD, 0x7F, 0xFF, 0x80, 0x1E, 0x90,
+0x84, 0x9E, 0xEF, 0xF0, 0x12, 0x6E, 0x36, 0x90,
+0x84, 0x9E, 0xE0, 0x60, 0x02, 0xD1, 0x38, 0x7D,
+0x04, 0x7F, 0x01, 0x80, 0x51, 0x12, 0x6E, 0x36,
+0xE4, 0xFB, 0xFD, 0x7F, 0xFF, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x05, 0x22, 0xED,
+0xF0, 0x90, 0x80, 0x05, 0xEB, 0xF0, 0xD0, 0xD0,
+0x92, 0xAF, 0x22, 0xF1, 0xA8, 0x64, 0x01, 0x70,
+0x28, 0x90, 0x81, 0x06, 0xE0, 0x54, 0xFD, 0xF0,
+0x7B, 0x2C, 0x12, 0x7A, 0xFE, 0x7D, 0x08, 0x7F,
+0x01, 0x12, 0x66, 0x6B, 0xBF, 0x01, 0x0D, 0x90,
+0x81, 0x05, 0xE0, 0x44, 0x80, 0xF0, 0x7D, 0x0E,
+0x7F, 0x01, 0x80, 0x0A, 0x12, 0x74, 0xCB, 0x04,
+0xF0, 0x22, 0x7D, 0x0C, 0x7F, 0x01, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xAC, 0x07, 0xEF,
+0x14, 0x60, 0x15, 0x14, 0x60, 0x19, 0x24, 0x02,
+0x70, 0x1A, 0xED, 0x54, 0x01, 0xFE, 0x90, 0x81,
+0x05, 0xE0, 0x54, 0xFE, 0x4E, 0xF0, 0x80, 0x0C,
+0x90, 0x81, 0x0D, 0xED, 0xF0, 0x80, 0x05, 0x90,
+0x81, 0x0C, 0xED, 0xF0, 0x90, 0x00, 0x8F, 0xE0,
+0x30, 0xE4, 0x2E, 0xEC, 0x14, 0x60, 0x07, 0x14,
+0x60, 0x1D, 0x24, 0x02, 0x70, 0x23, 0x90, 0x81,
+0x05, 0xE0, 0x54, 0x01, 0xC4, 0x33, 0x33, 0x33,
+0x54, 0x80, 0xFF, 0x90, 0x81, 0x0D, 0xE0, 0x54,
+0x7F, 0x4F, 0xFD, 0x7F, 0x88, 0x80, 0x07, 0x90,
+0x81, 0x0C, 0xE0, 0xFD, 0x7F, 0x89, 0x12, 0x32,
+0x1E, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7E, 0x00,
+0x7F, 0x62, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x81,
+0x79, 0x05, 0x12, 0x44, 0x3E, 0x90, 0x81, 0x09,
+0x74, 0x02, 0xF0, 0x90, 0x81, 0x10, 0x14, 0xF0,
+0xA3, 0xF0, 0xA3, 0x74, 0x10, 0xF0, 0x90, 0x81,
+0x16, 0xE4, 0xF0, 0xA3, 0x74, 0x02, 0x12, 0x7F,
+0x68, 0xF0, 0x12, 0x7B, 0x05, 0xE4, 0xFD, 0xFF,
+0xD1, 0x86, 0x7D, 0x0C, 0x7F, 0x02, 0xD1, 0x86,
+0xD1, 0x82, 0x90, 0x80, 0x07, 0xE0, 0xFF, 0xB4,
+0x01, 0x08, 0x90, 0x81, 0x15, 0x74, 0x99, 0xF0,
+0x80, 0x29, 0xEF, 0xB4, 0x03, 0x08, 0x90, 0x81,
+0x15, 0x74, 0x90, 0xF0, 0x80, 0x1D, 0x90, 0x81,
+0x15, 0x74, 0x40, 0xF0, 0x90, 0x00, 0x2C, 0xE0,
+0x54, 0x0F, 0xFF, 0xBF, 0x05, 0x08, 0x90, 0x81,
+0x27, 0x74, 0x02, 0xF0, 0x80, 0x05, 0xE4, 0x90,
+0x81, 0x27, 0xF0, 0x90, 0x81, 0x67, 0x74, 0x03,
+0xF0, 0xA3, 0x74, 0x0F, 0xF0, 0xA3, 0xE0, 0x54,
+0x01, 0x44, 0x28, 0xF0, 0xA3, 0x74, 0x07, 0x12,
+0x7F, 0x68, 0xF0, 0x7F, 0x01, 0x12, 0x7B, 0x1C,
+0x90, 0x05, 0x58, 0x74, 0x02, 0xF0, 0x7E, 0x00,
+0xFF, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x81, 0x79,
+0x6B, 0x12, 0x44, 0x3E, 0xF1, 0xFA, 0x12, 0x7F,
+0xC1, 0x7B, 0x56, 0xE4, 0xFD, 0x7F, 0xFF, 0xD1,
+0x3D, 0xE4, 0x90, 0x81, 0x6D, 0xF0, 0x22, 0xF0,
+0xE4, 0xFF, 0xF1, 0xB8, 0xEF, 0x22, 0xF1, 0xFA,
+0xD1, 0x38, 0x7D, 0x0C, 0x7F, 0x01, 0xC1, 0x86,
+0x12, 0x77, 0x0B, 0xFE, 0xEF, 0x54, 0x07, 0xFF,
+0x12, 0x60, 0xDF, 0xE0, 0xFD, 0x7C, 0x00, 0x12,
+0x77, 0x4E, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33,
+0xCE, 0xD8, 0xF9, 0xFF, 0xEE, 0x5C, 0xFE, 0xEF,
+0x5D, 0x4E, 0x7F, 0x00, 0x60, 0x02, 0x7F, 0x01,
+0x22, 0xF1, 0xA8, 0x64, 0x01, 0x70, 0x12, 0x90,
+0x81, 0x0A, 0xE0, 0x60, 0x0C, 0x90, 0x81, 0x0E,
+0xE0, 0x20, 0xE4, 0x05, 0x12, 0x73, 0x8F, 0x51,
+0x6A, 0x22, 0x90, 0x06, 0x04, 0xE0, 0x54, 0x7F,
+0xF0, 0x22, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83,
+0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0,
+0x00, 0xC0, 0x01, 0xC0, 0x02, 0xC0, 0x03, 0xC0,
+0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90,
+0x01, 0xC4, 0x74, 0x02, 0xF0, 0x74, 0x50, 0xA3,
+0xF0, 0x12, 0x79, 0x01, 0xE5, 0x49, 0x30, 0xE1,
+0x02, 0x11, 0x89, 0xE5, 0x49, 0x30, 0xE2, 0x03,
+0x12, 0x70, 0xCD, 0xE5, 0x4A, 0x30, 0xE0, 0x03,
+0x12, 0x76, 0xB1, 0xE5, 0x4C, 0x30, 0xE1, 0x04,
+0x7F, 0x04, 0x11, 0xCF, 0xE5, 0x4C, 0x30, 0xE4,
+0x02, 0x11, 0x93, 0xE5, 0x4C, 0x30, 0xE5, 0x03,
+0x12, 0x73, 0x9A, 0xE5, 0x4C, 0x30, 0xE6, 0x03,
+0x12, 0x74, 0x0F, 0x74, 0x02, 0x04, 0x90, 0x01,
+0xC4, 0xF0, 0x74, 0x50, 0xA3, 0xF0, 0xD0, 0x07,
+0xD0, 0x06, 0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03,
+0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0,
+0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0,
+0x32, 0x90, 0x81, 0x0A, 0xE0, 0x60, 0x03, 0x12,
+0x71, 0xC7, 0x22, 0x12, 0x49, 0x58, 0x12, 0x6F,
+0x04, 0x7F, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x81, 0x07, 0xE0, 0xFE, 0xC3,
+0x13, 0x30, 0xE0, 0x1E, 0x90, 0x84, 0x37, 0x74,
+0x1E, 0xF0, 0x90, 0x84, 0x45, 0x74, 0x01, 0xF0,
+0x90, 0x84, 0x39, 0xEF, 0xF0, 0x7B, 0x01, 0x7A,
+0x84, 0x79, 0x37, 0x12, 0x6B, 0xB1, 0x7F, 0x04,
+0x11, 0xCF, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x8F,
+0x0F, 0x7F, 0x02, 0x12, 0x46, 0x91, 0x90, 0x80,
+0x01, 0xE0, 0x45, 0x0F, 0xF0, 0x22, 0x11, 0xE4,
+0x7F, 0x02, 0x80, 0xEB, 0x90, 0x01, 0xCC, 0xE0,
+0x54, 0x0F, 0x90, 0x84, 0x94, 0xF0, 0x90, 0x84,
+0x94, 0xE0, 0xFD, 0x70, 0x02, 0x21, 0xE2, 0x90,
+0x80, 0x60, 0xE0, 0xFF, 0x70, 0x06, 0xA3, 0xE0,
+0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90,
+0x80, 0x61, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01,
+0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x08, 0x90,
+0x01, 0xC1, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90,
+0x84, 0x92, 0x12, 0x77, 0x4C, 0x80, 0x05, 0xC3,
+0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF,
+0x5D, 0x70, 0x02, 0x21, 0xC5, 0xE4, 0x90, 0x84,
+0x95, 0xF0, 0x90, 0x84, 0x95, 0xE0, 0xF9, 0xC3,
+0x94, 0x04, 0x50, 0x36, 0xF1, 0xC9, 0xA4, 0xFF,
+0xE9, 0xFD, 0x7C, 0x00, 0x2F, 0xFF, 0xEC, 0x35,
+0xF0, 0xFE, 0x74, 0xD0, 0x12, 0x7F, 0x56, 0x90,
+0x80, 0x10, 0x12, 0x7F, 0x77, 0xF1, 0xC8, 0xA4,
+0x2D, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74, 0xF0,
+0x12, 0x7F, 0x56, 0x90, 0x80, 0x14, 0x12, 0x7F,
+0x77, 0xF0, 0x90, 0x84, 0x95, 0xE0, 0x04, 0xF0,
+0x80, 0xC0, 0x90, 0x84, 0x94, 0xE0, 0xFF, 0x90,
+0x84, 0x92, 0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x06,
+0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4,
+0x5F, 0x90, 0x84, 0x94, 0xF0, 0x90, 0x84, 0x92,
+0x31, 0xE9, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC,
+0x90, 0x01, 0xCC, 0xF0, 0x90, 0x84, 0x92, 0xE0,
+0x04, 0xF0, 0xE0, 0x54, 0x03, 0xF0, 0x90, 0x80,
+0x61, 0x12, 0x6B, 0x4D, 0xB4, 0x0A, 0x02, 0x7F,
+0x01, 0xEF, 0x70, 0x02, 0x01, 0xEE, 0xE4, 0x90,
+0x80, 0x61, 0xF0, 0x01, 0xEE, 0x90, 0x01, 0xC0,
+0xE0, 0x44, 0x02, 0xF0, 0x90, 0x84, 0x92, 0xE0,
+0x44, 0x80, 0x90, 0x00, 0x8A, 0xF1, 0xC8, 0x90,
+0x01, 0xD0, 0x12, 0x42, 0x50, 0xE0, 0x90, 0x01,
+0xC3, 0xF0, 0x22, 0x12, 0x32, 0x1E, 0x90, 0x84,
+0x96, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08,
+0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x90, 0x84, 0x97, 0xED, 0xF0, 0x90, 0x84, 0x96,
+0xEF, 0xF0, 0xD3, 0x94, 0x07, 0x50, 0x4C, 0x31,
+0xE9, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4,
+0xFF, 0x90, 0x00, 0x47, 0xE0, 0x5F, 0xFD, 0x7F,
+0x47, 0x31, 0xE3, 0x80, 0x02, 0xC3, 0x33, 0xD8,
+0xFC, 0xFF, 0x90, 0x00, 0x46, 0xE0, 0x4F, 0xFD,
+0x7F, 0x46, 0x12, 0x7F, 0xD9, 0x60, 0x10, 0x31,
+0xE6, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xFF,
+0x90, 0x00, 0x45, 0xE0, 0x4F, 0x80, 0x0F, 0x31,
+0xE6, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4,
+0xFF, 0x90, 0x00, 0x45, 0xE0, 0x5F, 0xFD, 0x7F,
+0x45, 0x80, 0x63, 0x90, 0x84, 0x96, 0xE0, 0x24,
+0xF8, 0xF0, 0xE0, 0x24, 0x04, 0x31, 0xEA, 0x80,
+0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90,
+0x00, 0x43, 0xE0, 0x5F, 0xFD, 0x7F, 0x43, 0x31,
+0xE3, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xFF,
+0x90, 0x00, 0x43, 0xE0, 0x4F, 0xFD, 0x7F, 0x43,
+0x12, 0x7F, 0xD9, 0x60, 0x19, 0x90, 0x84, 0x96,
+0xE0, 0x24, 0x04, 0x31, 0xEA, 0x80, 0x02, 0xC3,
+0x33, 0xD8, 0xFC, 0xFF, 0x90, 0x00, 0x42, 0xE0,
+0x4F, 0xFD, 0x7F, 0x42, 0x80, 0x18, 0x90, 0x84,
+0x96, 0xE0, 0x24, 0x04, 0x31, 0xEA, 0x80, 0x02,
+0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00,
+0x42, 0xE0, 0x5F, 0xFD, 0x7F, 0x42, 0x12, 0x32,
+0x1E, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x5E,
+0xAB, 0x90, 0x84, 0x00, 0xEB, 0xF0, 0x90, 0x83,
+0xFF, 0xED, 0xF0, 0x60, 0x13, 0xF1, 0x7B, 0x78,
+0x03, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9,
+0xF0, 0xEE, 0x90, 0x83, 0xFD, 0xF0, 0x80, 0x19,
+0xF1, 0x7B, 0x78, 0x06, 0xC3, 0x33, 0xCE, 0x33,
+0xCE, 0xD8, 0xF9, 0xF0, 0xEE, 0x90, 0x83, 0xFD,
+0xF0, 0x74, 0xFF, 0x75, 0xF0, 0xD0, 0x12, 0x41,
+0xF6, 0x71, 0x98, 0x54, 0x07, 0x7D, 0x00, 0x20,
+0xE0, 0x02, 0x7D, 0x01, 0x31, 0xF1, 0x71, 0x98,
+0x54, 0x01, 0xFD, 0x31, 0xF1, 0x90, 0x84, 0x01,
+0xE0, 0x60, 0x57, 0x71, 0x8B, 0x54, 0x07, 0x7D,
+0x00, 0x20, 0xE0, 0x02, 0x7D, 0x01, 0x31, 0xF1,
+0x90, 0x84, 0x02, 0xE0, 0x60, 0x1D, 0x90, 0x81,
+0x71, 0xE0, 0x30, 0xE0, 0x3D, 0x90, 0x01, 0xC6,
+0xE0, 0x20, 0xE4, 0x36, 0x71, 0x6B, 0x54, 0x07,
+0x7D, 0x00, 0x20, 0xE0, 0x02, 0x7D, 0x01, 0x31,
+0xF1, 0x80, 0xE3, 0xE4, 0x90, 0x84, 0x03, 0xF0,
+0x90, 0x84, 0x00, 0xE0, 0xFF, 0x90, 0x84, 0x03,
+0xE0, 0xC3, 0x9F, 0x50, 0x15, 0x71, 0x6B, 0x54,
+0x07, 0x7D, 0x00, 0x20, 0xE0, 0x02, 0x7D, 0x01,
+0x31, 0xF1, 0x90, 0x84, 0x03, 0xE0, 0x04, 0xF0,
+0x80, 0xDE, 0x22, 0x90, 0x83, 0xFD, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0x71, 0xA7,
+0x90, 0x81, 0x72, 0xE0, 0x54, 0x7F, 0xFF, 0x90,
+0x81, 0x71, 0xE0, 0xFE, 0xC4, 0x13, 0x54, 0x01,
+0xFD, 0x31, 0xF1, 0x90, 0x83, 0xFD, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0x71, 0xA7,
+0x90, 0x81, 0x72, 0xE0, 0x54, 0x7F, 0xFF, 0x90,
+0x81, 0x71, 0xE0, 0xFE, 0xC4, 0x13, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8E, 0x0D,
+0x8F, 0x0E, 0xBD, 0x01, 0x05, 0x12, 0x32, 0x06,
+0x80, 0x07, 0xAF, 0x0E, 0xAE, 0x0D, 0x12, 0x32,
+0xAA, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x67, 0xEA,
+0x12, 0x1F, 0xA4, 0x20, 0xE0, 0x1E, 0x54, 0x01,
+0xFF, 0x90, 0x81, 0x71, 0xE0, 0x54, 0xFE, 0x4F,
+0xF0, 0xA3, 0x71, 0x9B, 0x54, 0x07, 0x7D, 0x00,
+0x20, 0xE0, 0x02, 0x7D, 0x01, 0x31, 0xF1, 0x12,
+0x61, 0x91, 0x81, 0xEF, 0x12, 0x7C, 0x3A, 0xFE,
+0x90, 0x81, 0x71, 0xF1, 0x5E, 0xF1, 0xE6, 0xFF,
+0x90, 0x81, 0x71, 0x12, 0x7F, 0x93, 0xF1, 0x6C,
+0x12, 0x7F, 0x9D, 0x90, 0x81, 0x71, 0xF1, 0xD1,
+0xF1, 0x6C, 0x12, 0x7F, 0xA6, 0x90, 0x81, 0x71,
+0x12, 0x7F, 0xB8, 0xD1, 0x79, 0x54, 0x80, 0xFF,
+0x90, 0x81, 0x72, 0xE0, 0x54, 0x7F, 0x4F, 0xB1,
+0x81, 0xFF, 0x54, 0x02, 0xFE, 0x90, 0x81, 0x75,
+0xE0, 0x54, 0xFD, 0x4E, 0xFE, 0xF0, 0xEF, 0x54,
+0x08, 0xFF, 0xEE, 0x54, 0xF7, 0x4F, 0xF1, 0xB9,
+0x90, 0x81, 0x76, 0xB1, 0x81, 0x54, 0x10, 0xFF,
+0x90, 0x81, 0x75, 0xE0, 0x54, 0xEF, 0x4F, 0xF0,
+0x12, 0x1F, 0xA4, 0xFF, 0x13, 0x13, 0x54, 0x3F,
+0x30, 0xE0, 0x07, 0x90, 0x06, 0x90, 0xE0, 0x44,
+0x04, 0xF0, 0x12, 0x77, 0x0B, 0x30, 0xE0, 0x07,
+0x90, 0x06, 0x90, 0xE0, 0x44, 0x08, 0xF0, 0x90,
+0x80, 0x07, 0xE0, 0xB4, 0x02, 0x06, 0x12, 0x5F,
+0x45, 0x20, 0xE0, 0x55, 0x90, 0x83, 0xEF, 0x12,
+0x42, 0x5C, 0xD1, 0x7B, 0x54, 0x7F, 0xFF, 0x90,
+0x81, 0x72, 0xE0, 0x54, 0x80, 0xF1, 0x73, 0xFF,
+0x54, 0x7F, 0xFE, 0x90, 0x81, 0x73, 0xE0, 0x54,
+0x80, 0xF1, 0xC0, 0xFE, 0x54, 0x01, 0xFD, 0x90,
+0x81, 0x74, 0xF1, 0xF6, 0x54, 0xFE, 0xFE, 0xED,
+0x54, 0x01, 0x4E, 0xB1, 0x81, 0x54, 0x04, 0xFE,
+0x90, 0x81, 0x75, 0xE0, 0x54, 0xFB, 0x4E, 0xF0,
+0xEF, 0x54, 0x80, 0xFF, 0x90, 0x81, 0x73, 0xE0,
+0x54, 0x7F, 0x4F, 0xF0, 0x71, 0x98, 0x54, 0x07,
+0x7D, 0x00, 0x20, 0xE0, 0x02, 0x7D, 0x01, 0x31,
+0xF1, 0x90, 0x80, 0x07, 0xE0, 0xB4, 0x01, 0x07,
+0x90, 0xFE, 0x10, 0xE0, 0x44, 0x04, 0xF0, 0x90,
+0x83, 0xAD, 0x74, 0x05, 0xF0, 0x12, 0x7F, 0xAF,
+0x7A, 0x82, 0x79, 0x8C, 0x12, 0x44, 0x3E, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x90, 0x83, 0xEC, 0x12,
+0x42, 0x65, 0x90, 0x83, 0xEB, 0xEF, 0xF0, 0x12,
+0x42, 0x6E, 0x55, 0x2D, 0x00, 0x55, 0x32, 0x01,
+0x55, 0x37, 0x03, 0x55, 0x3C, 0x04, 0x55, 0x41,
+0x14, 0x55, 0x46, 0x20, 0x55, 0x4B, 0x25, 0x55,
+0x54, 0x80, 0x55, 0x50, 0x81, 0x55, 0x58, 0x82,
+0x55, 0x5D, 0x83, 0x55, 0x61, 0x84, 0x55, 0x66,
+0x88, 0x00, 0x00, 0x55, 0x6B, 0xB1, 0x7B, 0x02,
+0x70, 0x19, 0xB1, 0x7B, 0x02, 0x70, 0x5D, 0xB1,
+0x7B, 0x02, 0x7C, 0x15, 0xB1, 0x7B, 0x02, 0x7C,
+0x47, 0xB1, 0x7B, 0x02, 0x77, 0xE8, 0xB1, 0x7B,
+0x02, 0x74, 0xD5, 0xB1, 0x7B, 0x02, 0x77, 0xF7,
+0xB1, 0x7B, 0xC1, 0x81, 0xB1, 0x7B, 0x61, 0xC6,
+0xB1, 0x7B, 0x02, 0x7E, 0x66, 0xB1, 0x7B, 0xE1,
+0x83, 0xB1, 0x7B, 0x02, 0x7E, 0x74, 0xB1, 0x7B,
+0x02, 0x7E, 0xC8, 0x90, 0x01, 0xC0, 0xE0, 0x44,
+0x01, 0xF0, 0x90, 0x83, 0xEB, 0xE0, 0x90, 0x01,
+0xC2, 0xF0, 0x22, 0x90, 0x83, 0xEC, 0x02, 0x42,
+0x5C, 0xF0, 0x90, 0x00, 0x04, 0x02, 0x1F, 0xBD,
+0x90, 0x84, 0x46, 0x12, 0x42, 0x65, 0x90, 0x84,
+0x4A, 0xE0, 0xFE, 0x64, 0x04, 0x70, 0x0C, 0xD1,
+0x73, 0x12, 0x1F, 0xA4, 0x90, 0x84, 0x4B, 0xD1,
+0x7A, 0x80, 0x10, 0xEE, 0x64, 0x02, 0x70, 0x2F,
+0xD1, 0x73, 0xF1, 0x75, 0x90, 0x84, 0x4B, 0xF0,
+0x12, 0x1F, 0xA4, 0x90, 0x84, 0x4C, 0xB1, 0x81,
+0x90, 0x84, 0x4D, 0xF1, 0xB9, 0x90, 0x84, 0x4E,
+0xF0, 0x90, 0x00, 0x06, 0x12, 0x1F, 0xBD, 0x90,
+0x84, 0x4F, 0xF0, 0x90, 0x00, 0x07, 0x12, 0x1F,
+0xBD, 0x90, 0x84, 0x50, 0xF1, 0xC1, 0xFF, 0xED,
+0x70, 0x19, 0xFE, 0xF1, 0xDB, 0xE0, 0xB4, 0xFF,
+0x06, 0xF1, 0xDB, 0xE4, 0xF0, 0x80, 0x07, 0xF1,
+0xDB, 0xE0, 0x04, 0xF0, 0x80, 0x05, 0x0E, 0xEE,
+0xB4, 0x06, 0xE8, 0x90, 0x84, 0x4A, 0xE0, 0xFE,
+0xB4, 0x04, 0x18, 0xA3, 0xE0, 0xFD, 0xD1, 0x73,
+0xED, 0xF1, 0xEE, 0xFD, 0xD1, 0x73, 0x90, 0x00,
+0x01, 0xED, 0x12, 0x1F, 0xFC, 0x90, 0x00, 0x02,
+0xE4, 0x80, 0x20, 0xEE, 0xB4, 0x02, 0x1F, 0x90,
+0x84, 0x4C, 0xD1, 0x71, 0xEE, 0xF1, 0xEE, 0x44,
+0x20, 0x54, 0x7F, 0xD1, 0x72, 0x90, 0x00, 0x01,
+0xEE, 0x12, 0x1F, 0xFC, 0x90, 0x84, 0x4B, 0xE0,
+0x90, 0x00, 0x02, 0x12, 0x1F, 0xFC, 0xD1, 0x73,
+0xE9, 0x24, 0x03, 0xF9, 0xE4, 0x3A, 0xFA, 0x12,
+0x1F, 0xA4, 0x44, 0x20, 0x12, 0x1F, 0xEA, 0x90,
+0x84, 0x4D, 0xD1, 0x71, 0x90, 0x00, 0x04, 0xEE,
+0x12, 0x1F, 0xFC, 0x90, 0x84, 0x4E, 0xE0, 0x90,
+0x00, 0x05, 0x12, 0x1F, 0xFC, 0x90, 0x84, 0x4F,
+0xE0, 0x90, 0x00, 0x06, 0x12, 0x1F, 0xFC, 0x90,
+0x84, 0x50, 0xE0, 0x90, 0x00, 0x07, 0x02, 0x1F,
+0xFC, 0xE0, 0xFE, 0x90, 0x84, 0x46, 0x02, 0x42,
+0x5C, 0x4E, 0xF0, 0x90, 0x00, 0x01, 0x02, 0x1F,
+0xBD, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x12, 0x7C, 0x40, 0xFE, 0x90, 0x81, 0x6E, 0xF1,
+0x5E, 0xF1, 0xE6, 0xFF, 0x90, 0x81, 0x6E, 0x12,
+0x7F, 0x93, 0xF1, 0x6C, 0x12, 0x7F, 0x9D, 0x90,
+0x81, 0x6E, 0xF1, 0xD1, 0xF1, 0x6C, 0x12, 0x7F,
+0xA6, 0x90, 0x81, 0x6E, 0x12, 0x7F, 0xB8, 0x4E,
+0xF1, 0x74, 0xFF, 0x54, 0x01, 0xFE, 0x90, 0x81,
+0x70, 0xE0, 0x54, 0xFE, 0xD1, 0x79, 0xFE, 0x54,
+0x01, 0xFD, 0x90, 0x81, 0x6F, 0xF1, 0xF6, 0x54,
+0x04, 0xFE, 0xED, 0x54, 0xFB, 0x4E, 0xFE, 0xD1,
+0x7A, 0xFD, 0x54, 0x08, 0xFC, 0xEE, 0x54, 0xF7,
+0x4C, 0xFE, 0x90, 0x81, 0x6F, 0xF0, 0xED, 0x54,
+0x10, 0xFD, 0xEE, 0x54, 0xEF, 0x4D, 0xF0, 0xEF,
+0x54, 0x10, 0xFF, 0xA3, 0xE0, 0x54, 0xEF, 0x4F,
+0xFF, 0xF1, 0x74, 0xF1, 0xD3, 0x90, 0x81, 0x70,
+0xD1, 0x7A, 0x54, 0x02, 0xFF, 0x90, 0x81, 0x6F,
+0xE0, 0x54, 0xFD, 0x4F, 0x12, 0x7D, 0x4B, 0x12,
+0x7F, 0xC9, 0x90, 0x81, 0x6E, 0xE0, 0xC3, 0x13,
+0x54, 0x01, 0xFF, 0x12, 0x7F, 0x0D, 0x12, 0x5F,
+0x9B, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x23, 0x90,
+0x81, 0x6E, 0xE0, 0xFF, 0x13, 0x13, 0x13, 0x54,
+0x1F, 0x20, 0xE0, 0x0E, 0xEF, 0xC3, 0x13, 0x20,
+0xE0, 0x08, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30,
+0xE0, 0x04, 0x7F, 0x01, 0x80, 0x0E, 0x7F, 0x00,
+0x80, 0x0A, 0x90, 0x81, 0x6E, 0xE0, 0x13, 0x13,
+0x13, 0x54, 0x01, 0xFF, 0x12, 0x67, 0xC1, 0x90,
+0x81, 0x6E, 0xE0, 0x54, 0x01, 0xFF, 0x12, 0x61,
+0xBC, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE0, 0x54,
+0xFE, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x02, 0xFF,
+0xEE, 0x54, 0xFD, 0x4F, 0xFF, 0xF0, 0x12, 0x1F,
+0xA4, 0xFE, 0x22, 0x4F, 0xF0, 0x90, 0x00, 0x02,
+0x02, 0x1F, 0xBD, 0x90, 0x83, 0xFD, 0xE0, 0xFE,
+0xA3, 0xE0, 0x22, 0x12, 0x7E, 0xBA, 0x90, 0x83,
+0xB3, 0xD1, 0x7A, 0xFF, 0xED, 0x2F, 0x90, 0x83,
+0xB4, 0xF1, 0x74, 0xFF, 0xED, 0x2F, 0x90, 0x83,
+0xB5, 0xF1, 0xC1, 0xFF, 0xED, 0x2F, 0x90, 0x83,
+0xB6, 0xB1, 0x81, 0xFF, 0xED, 0x2F, 0x90, 0x83,
+0xB7, 0xF1, 0xB9, 0xFF, 0xED, 0x2F, 0x90, 0x83,
+0xB8, 0x12, 0x7E, 0xAD, 0x90, 0x83, 0xB9, 0xF0,
+0x22, 0xF0, 0x90, 0x00, 0x05, 0x02, 0x1F, 0xBD,
+0x4E, 0xF0, 0x90, 0x00, 0x03, 0x02, 0x1F, 0xBD,
+0xF0, 0x90, 0x84, 0x92, 0xE0, 0x75, 0xF0, 0x04,
+0x22, 0xF0, 0xEE, 0x54, 0x20, 0xFE, 0xEF, 0x54,
+0xDF, 0x4E, 0x22, 0x74, 0x4B, 0x2E, 0xF5, 0x82,
+0xE4, 0x34, 0x84, 0xF5, 0x83, 0x22, 0x54, 0x04,
+0xFD, 0xEF, 0x54, 0xFB, 0x4D, 0x22, 0x12, 0x1F,
+0xEA, 0x90, 0x84, 0x4C, 0xE0, 0x22, 0xE0, 0x54,
+0xFE, 0x4D, 0xFD, 0xF0, 0xEE, 0x22, 0x90, 0x00,
+0xF7, 0xE0, 0x20, 0xE7, 0x09, 0xE0, 0x7F, 0x01,
+0x20, 0xE6, 0x0C, 0x7F, 0x02, 0x22, 0x90, 0x00,
+0xF7, 0xE0, 0x30, 0xE6, 0x02, 0x7F, 0x03, 0x22,
+0x12, 0x57, 0xFE, 0x90, 0x80, 0x07, 0xEF, 0xF0,
+0x11, 0x39, 0x90, 0x01, 0x64, 0x74, 0x01, 0xF0,
+0x90, 0x00, 0x12, 0xE0, 0x54, 0xC7, 0x44, 0x20,
+0xFD, 0x7F, 0x12, 0x12, 0x32, 0x1E, 0x02, 0x2D,
+0xA7, 0x90, 0x00, 0x08, 0xE0, 0x54, 0xEF, 0xF0,
+0x11, 0x72, 0xD1, 0xC8, 0x12, 0x78, 0x0D, 0x12,
+0x78, 0x2C, 0xE4, 0xF5, 0x35, 0xF5, 0x37, 0xF5,
+0x36, 0xF5, 0x37, 0x75, 0x38, 0x80, 0xAD, 0x35,
+0x7F, 0x50, 0x12, 0x32, 0x1E, 0xAD, 0x36, 0x7F,
+0x51, 0x12, 0x32, 0x1E, 0xAD, 0x37, 0x7F, 0x52,
+0x12, 0x32, 0x1E, 0xAD, 0x38, 0x7F, 0x53, 0x02,
+0x32, 0x1E, 0x90, 0x01, 0x30, 0xE4, 0x11, 0x98,
+0x90, 0x01, 0x38, 0x11, 0x98, 0xFD, 0x7F, 0x50,
+0x12, 0x32, 0x1E, 0xE4, 0xFD, 0x7F, 0x51, 0x12,
+0x32, 0x1E, 0xE4, 0xFD, 0x7F, 0x52, 0x12, 0x32,
+0x1E, 0xE4, 0xFD, 0x7F, 0x53, 0x02, 0x32, 0x1E,
+0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
+0x83, 0xF3, 0x74, 0x08, 0xF0, 0xE4, 0xA3, 0x11,
+0x98, 0x90, 0x83, 0xFA, 0xF0, 0xA3, 0xF0, 0xA3,
+0xF0, 0x12, 0x7D, 0x88, 0x12, 0x7D, 0x54, 0x90,
+0x83, 0xEB, 0x12, 0x7D, 0x7F, 0x90, 0x83, 0xF2,
+0xF0, 0x90, 0x81, 0x6E, 0xE0, 0x20, 0xE0, 0x02,
+0x41, 0xC9, 0xE4, 0x90, 0x83, 0xF1, 0xF0, 0x90,
+0x83, 0xF2, 0xE0, 0xFF, 0x90, 0x83, 0xF1, 0xE0,
+0xC3, 0x9F, 0x40, 0x02, 0x41, 0xC9, 0xD1, 0xB4,
+0xFD, 0xEC, 0xFF, 0x90, 0xFD, 0x11, 0xF0, 0xAE,
+0x05, 0xAA, 0x06, 0x90, 0x83, 0xF5, 0xEF, 0xF0,
+0x74, 0x02, 0x2A, 0x12, 0x7D, 0xA9, 0x54, 0xF8,
+0xFF, 0x74, 0x03, 0x2A, 0x12, 0x7D, 0x91, 0xFE,
+0xEF, 0x24, 0x18, 0x2E, 0x90, 0x83, 0xFA, 0xF0,
+0xE0, 0xFF, 0x2A, 0x90, 0x83, 0xED, 0xF0, 0x7E,
+0x00, 0xD1, 0xB4, 0x2F, 0xFF, 0xEE, 0x3C, 0x90,
+0x83, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x83,
+0xED, 0xE0, 0xFD, 0x24, 0x00, 0xF1, 0xAA, 0xFE,
+0x54, 0xFC, 0x90, 0x83, 0xF0, 0xF0, 0xAF, 0x06,
+0xF1, 0xBC, 0xFD, 0x90, 0x83, 0xED, 0xE0, 0xF1,
+0xA2, 0x12, 0x64, 0x17, 0x90, 0x83, 0xF4, 0xEF,
+0xF0, 0x74, 0x01, 0x2A, 0xF1, 0xBF, 0xFE, 0x74,
+0x00, 0x2A, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5,
+0x83, 0x12, 0x7D, 0x54, 0x54, 0x3F, 0xFE, 0x90,
+0x83, 0xF6, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x83,
+0xFA, 0xE0, 0x2F, 0xFF, 0xEC, 0x3E, 0xFE, 0x12,
+0x7D, 0x5D, 0x74, 0x0F, 0x2A, 0xF5, 0x82, 0xE4,
+0x34, 0xFB, 0xF5, 0x83, 0xE0, 0xFD, 0x90, 0x83,
+0xEB, 0x12, 0x7D, 0xB7, 0x90, 0x83, 0xEB, 0xE0,
+0xFA, 0xA3, 0xE0, 0xD3, 0x9F, 0xEA, 0x9E, 0x40,
+0x22, 0x90, 0x83, 0xEB, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0x90, 0x80, 0xFA, 0xE0, 0xFA, 0xA3, 0xE0,
+0x24, 0x01, 0xFB, 0xE4, 0x3A, 0xFA, 0xC3, 0xEF,
+0x9B, 0xFF, 0xEE, 0x9A, 0x90, 0x83, 0xEB, 0xF0,
+0xA3, 0xEF, 0xF0, 0xED, 0x30, 0xE7, 0x08, 0x51,
+0xCF, 0x90, 0x01, 0xC7, 0x74, 0x21, 0xF0, 0xED,
+0x30, 0xE6, 0x08, 0x51, 0xCF, 0x90, 0x01, 0xC7,
+0x74, 0x22, 0xF0, 0xED, 0x30, 0xE5, 0x08, 0x51,
+0xCF, 0x90, 0x01, 0xC7, 0x74, 0x23, 0xF0, 0x90,
+0x83, 0xF0, 0xE0, 0x24, 0xF8, 0x60, 0x23, 0x24,
+0x80, 0x60, 0x1F, 0x24, 0xC8, 0x60, 0x04, 0x24,
+0x20, 0x70, 0x7B, 0x90, 0x81, 0x71, 0xE0, 0xFF,
+0xF1, 0x49, 0x30, 0xE0, 0x71, 0xD1, 0x8B, 0x60,
+0x6D, 0x90, 0x83, 0xF0, 0xE0, 0xFF, 0xF1, 0xD9,
+0x80, 0x64, 0xD1, 0x8B, 0x60, 0x1A, 0x51, 0xD7,
+0x90, 0x83, 0xF3, 0xE0, 0xFB, 0x90, 0x83, 0xF5,
+0xE0, 0x90, 0x84, 0x01, 0xF0, 0x51, 0xE5, 0xEF,
+0x60, 0x06, 0x90, 0x83, 0xFC, 0x74, 0x01, 0xF0,
+0x90, 0x81, 0x6E, 0xE0, 0xC3, 0x13, 0x30, 0xE0,
+0x0D, 0x51, 0xD7, 0x91, 0x30, 0xEF, 0x60, 0x06,
+0x90, 0x83, 0xFC, 0x74, 0x01, 0xF0, 0x90, 0x81,
+0x6E, 0xF1, 0x48, 0x30, 0xE0, 0x15, 0x90, 0x83,
+0xFC, 0xE0, 0x70, 0x0F, 0x51, 0xD7, 0xD1, 0x94,
+0xEF, 0x60, 0x08, 0x51, 0xCF, 0x90, 0x01, 0xC7,
+0x74, 0x22, 0xF0, 0x51, 0xD7, 0x71, 0x92, 0xEF,
+0x60, 0x0C, 0x90, 0x81, 0x79, 0xE0, 0x54, 0xFE,
+0xF0, 0x90, 0x01, 0xC7, 0xE4, 0xF0, 0x90, 0x81,
+0x79, 0xE0, 0x30, 0xE0, 0x19, 0x90, 0x80, 0x07,
+0xE0, 0xB4, 0x01, 0x0E, 0x90, 0xFD, 0x01, 0xE0,
+0x20, 0xE6, 0x07, 0x90, 0xFD, 0x00, 0xE0, 0x44,
+0x10, 0xF0, 0x7F, 0x01, 0xD1, 0xF7, 0x12, 0x7D,
+0xC6, 0xEF, 0x64, 0x01, 0x70, 0x3B, 0xF1, 0xF9,
+0x90, 0x83, 0xFB, 0xEF, 0xF0, 0x64, 0x01, 0x60,
+0x22, 0x51, 0xCF, 0x90, 0x83, 0xFB, 0xE0, 0xFF,
+0xB4, 0x02, 0x08, 0x90, 0x01, 0xC7, 0x74, 0x42,
+0xF0, 0x80, 0x0A, 0xEF, 0xB4, 0x04, 0x06, 0x90,
+0x01, 0xC7, 0x74, 0x43, 0xF0, 0x7F, 0x01, 0xD1,
+0xF7, 0x80, 0x0E, 0x90, 0x83, 0xEB, 0x12, 0x7C,
+0x8C, 0x90, 0x83, 0xF1, 0xE0, 0x04, 0xF0, 0x01,
+0xD7, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF0, 0x90,
+0x81, 0x79, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90,
+0x83, 0xEE, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90,
+0x83, 0xF4, 0xE0, 0xFD, 0x22, 0x90, 0x83, 0xFF,
+0xED, 0xF0, 0xA3, 0xEB, 0xD1, 0xAA, 0xE4, 0x90,
+0x84, 0x02, 0xF0, 0x90, 0x84, 0x01, 0xF0, 0xFD,
+0x71, 0x68, 0xEF, 0x54, 0x0C, 0x64, 0x08, 0x70,
+0x53, 0x12, 0x57, 0x7B, 0xFF, 0xA3, 0xE0, 0xD1,
+0x48, 0x64, 0x88, 0x70, 0x47, 0x12, 0x57, 0x7B,
+0xFF, 0xA3, 0xE0, 0x24, 0x07, 0xFD, 0x71, 0x68,
+0xEF, 0x64, 0x8E, 0x70, 0x37, 0x90, 0x84, 0x02,
+0x04, 0xF0, 0x12, 0x57, 0x7B, 0xD1, 0xBC, 0x04,
+0xFD, 0x71, 0x68, 0xEF, 0x64, 0x03, 0x70, 0x24,
+0x12, 0x57, 0x7B, 0xD1, 0xBC, 0xD1, 0x48, 0x30,
+0xE3, 0x07, 0x90, 0x01, 0xC7, 0x74, 0x01, 0x80,
+0x11, 0x90, 0x81, 0x71, 0xE0, 0xC4, 0x13, 0x13,
+0x54, 0x03, 0x30, 0xE0, 0x07, 0x90, 0x01, 0xC7,
+0x74, 0x02, 0x51, 0xCE, 0x90, 0x84, 0x02, 0xE0,
+0xFF, 0x22, 0xCD, 0x34, 0x00, 0xFC, 0x7E, 0x00,
+0xED, 0x2F, 0xFF, 0xEE, 0x3C, 0xFE, 0xE4, 0xFD,
+0xAB, 0x07, 0xAA, 0x06, 0xED, 0x2B, 0xFB, 0xE4,
+0x3A, 0xFA, 0xC3, 0x90, 0x80, 0xFB, 0xE0, 0x9B,
+0x90, 0x80, 0xFA, 0xE0, 0x9A, 0x50, 0x0A, 0xA3,
+0x12, 0x7D, 0x9C, 0xEB, 0x9F, 0xFB, 0xEA, 0x9E,
+0xFA, 0xF1, 0xF1, 0x74, 0x00, 0x2F, 0xF1, 0xAA,
+0xFF, 0x22, 0xD1, 0xA6, 0xD1, 0x5B, 0xEF, 0x70,
+0x02, 0x81, 0x2D, 0x12, 0x57, 0x7B, 0xB1, 0xA9,
+0xEF, 0x70, 0x02, 0x81, 0x2D, 0xB1, 0x7C, 0xCF,
+0x24, 0x08, 0xCF, 0x34, 0x00, 0x90, 0x84, 0x02,
+0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x81, 0x6F, 0xE0,
+0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x2F, 0xB1, 0x8E,
+0x7D, 0x09, 0x71, 0x68, 0xEF, 0x64, 0x06, 0x70,
+0x24, 0xB1, 0x8E, 0x7D, 0x14, 0x71, 0x68, 0xEF,
+0x70, 0x1B, 0xB1, 0x8E, 0x7D, 0x15, 0x71, 0x68,
+0xEF, 0x64, 0x50, 0x70, 0x10, 0xB1, 0x8E, 0x7D,
+0x21, 0x71, 0x68, 0xEF, 0x20, 0xE0, 0x03, 0x30,
+0xE2, 0x03, 0x7F, 0x01, 0x22, 0xF1, 0x9B, 0x54,
+0x3F, 0x30, 0xE0, 0x39, 0xB1, 0x8E, 0x7D, 0x09,
+0x71, 0x68, 0xEF, 0x64, 0x11, 0x70, 0x2E, 0x90,
+0x84, 0x03, 0xE0, 0x24, 0x14, 0xFF, 0x90, 0x84,
+0x02, 0xE0, 0x34, 0x00, 0xFE, 0x90, 0x84, 0x00,
+0xF0, 0xA3, 0xEF, 0xF0, 0x7D, 0x02, 0x71, 0x68,
+0xEF, 0x70, 0x12, 0x90, 0x84, 0x00, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0x7D, 0x03, 0x71, 0x68, 0xBF,
+0x89, 0x03, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22,
+0xD1, 0xAB, 0xA3, 0xED, 0xF0, 0x78, 0x06, 0x7C,
+0x84, 0x7D, 0x01, 0x7B, 0xFF, 0x7A, 0x40, 0x79,
+0xC0, 0xF1, 0xEA, 0x78, 0x0C, 0x7C, 0x84, 0x7D,
+0x01, 0x7B, 0xFF, 0x7A, 0x40, 0x79, 0xC6, 0xD1,
+0x41, 0x78, 0x10, 0x7C, 0x84, 0x7D, 0x01, 0x7B,
+0xFF, 0x7A, 0x40, 0x79, 0xCA, 0xD1, 0x41, 0xE4,
+0x90, 0x84, 0x15, 0xF0, 0xB1, 0x7C, 0xCF, 0x24,
+0x06, 0xCF, 0xD1, 0x38, 0x64, 0x08, 0x60, 0x02,
+0xA1, 0x76, 0xB1, 0x7C, 0xCF, 0x24, 0x07, 0xCF,
+0xD1, 0x38, 0x64, 0x06, 0x60, 0x02, 0xA1, 0x76,
+0x90, 0x84, 0x15, 0x04, 0xF0, 0xE4, 0x90, 0x84,
+0x14, 0xF0, 0xB1, 0x97, 0x94, 0x06, 0x50, 0x1C,
+0x90, 0x83, 0xFE, 0xE0, 0x24, 0x0A, 0xFD, 0x90,
+0x83, 0xFD, 0xE0, 0x71, 0x5B, 0x90, 0x84, 0x14,
+0xE0, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x84,
+0xB1, 0x9E, 0x80, 0xDE, 0x78, 0x00, 0x7C, 0x84,
+0x7D, 0x01, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0x80,
+0xF1, 0xB3, 0x60, 0x02, 0xA1, 0x76, 0x90, 0x84,
+0x14, 0xF0, 0xB1, 0x97, 0x94, 0x04, 0x50, 0x18,
+0xD1, 0x4F, 0xB1, 0x87, 0xCD, 0x24, 0x20, 0x71,
+0x5A, 0x90, 0x84, 0x14, 0xE0, 0x24, 0x10, 0xF5,
+0x82, 0xE4, 0x34, 0x84, 0xB1, 0x9E, 0x80, 0xE2,
+0x78, 0x10, 0x7C, 0x84, 0xF1, 0xC8, 0x60, 0x02,
+0xA1, 0x6D, 0x90, 0x06, 0x30, 0xE0, 0x44, 0x01,
+0x54, 0xDF, 0xF0, 0x90, 0x81, 0x70, 0xE0, 0x30,
+0xE0, 0x02, 0x80, 0x0F, 0x90, 0x83, 0xB1, 0xE0,
+0xB4, 0x02, 0x11, 0xF1, 0x9B, 0x13, 0x54, 0x1F,
+0x20, 0xE0, 0x09, 0x90, 0x01, 0xC7, 0x74, 0x09,
+0x51, 0xCE, 0x80, 0x62, 0xE4, 0x90, 0x84, 0x14,
+0xF0, 0xB1, 0x97, 0x94, 0x06, 0x50, 0x18, 0xD1,
+0x4F, 0xB1, 0x87, 0xCD, 0x24, 0x10, 0x71, 0x5A,
+0x90, 0x84, 0x14, 0xE0, 0x24, 0x06, 0xF5, 0x82,
+0xE4, 0x34, 0x84, 0xB1, 0x9E, 0x80, 0xE2, 0xE4,
+0x90, 0x84, 0x14, 0xF0, 0xB1, 0x97, 0x94, 0x04,
+0x50, 0x18, 0xD1, 0x4F, 0xB1, 0x87, 0xCD, 0x24,
+0x16, 0x71, 0x5A, 0x90, 0x84, 0x14, 0xE0, 0x24,
+0x0C, 0xF5, 0x82, 0xE4, 0x34, 0x84, 0xB1, 0x9E,
+0x80, 0xE2, 0x7B, 0x01, 0x7A, 0x84, 0x79, 0x06,
+0x12, 0x7F, 0x86, 0xF0, 0x7A, 0x84, 0x79, 0x0C,
+0x12, 0x62, 0xAB, 0x80, 0x09, 0x90, 0x06, 0x30,
+0xE0, 0x44, 0x21, 0x54, 0xEF, 0xF0, 0x90, 0x84,
+0x15, 0xE0, 0xFF, 0x22, 0x90, 0x83, 0xFF, 0xE0,
+0xFF, 0x90, 0x83, 0xFE, 0xE0, 0x2F, 0xFF, 0x90,
+0x83, 0xFD, 0xE0, 0x34, 0x00, 0x22, 0x90, 0x84,
+0x02, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0x90,
+0x84, 0x14, 0xE0, 0xFF, 0xC3, 0x22, 0xF5, 0x83,
+0xEF, 0xF0, 0x90, 0x84, 0x14, 0xE0, 0x04, 0xF0,
+0x22, 0xFF, 0xA3, 0xE0, 0xFD, 0x90, 0x84, 0x04,
+0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xED, 0xF0,
+0x78, 0x08, 0x7C, 0x84, 0x7D, 0x01, 0x7B, 0xFF,
+0x7A, 0x40, 0x79, 0xD4, 0xD1, 0x41, 0x90, 0x84,
+0x06, 0xE0, 0xFF, 0x90, 0x84, 0x05, 0xE0, 0x2F,
+0xFF, 0x90, 0x84, 0x04, 0xE0, 0x34, 0x00, 0xFE,
+0x90, 0x84, 0x0C, 0xF0, 0xA3, 0xEF, 0xF0, 0x24,
+0x06, 0xFF, 0xE4, 0x3E, 0xD1, 0x3A, 0x64, 0x08,
+0x70, 0x4D, 0x90, 0x84, 0x0D, 0xE0, 0x24, 0x07,
+0xFF, 0x90, 0x84, 0x0C, 0xE0, 0xD1, 0x38, 0x70,
+0x3E, 0x90, 0x84, 0x07, 0xF0, 0x90, 0x84, 0x07,
+0xE0, 0xFF, 0xC3, 0x94, 0x04, 0x50, 0x24, 0x90,
+0x84, 0x0D, 0xE0, 0x24, 0x18, 0xFD, 0x90, 0x84,
+0x0C, 0xE0, 0x71, 0x5B, 0x90, 0x84, 0x07, 0xE0,
+0x24, 0x08, 0xF5, 0x82, 0xE4, 0x34, 0x84, 0xF5,
+0x83, 0xEF, 0xF0, 0x90, 0x84, 0x07, 0xE0, 0x04,
+0xF0, 0x80, 0xD2, 0x78, 0x08, 0x7C, 0x84, 0xF1,
+0xC8, 0x7F, 0x00, 0x70, 0x02, 0x7F, 0x01, 0x22,
+0x34, 0x00, 0xFE, 0xE4, 0xFD, 0x71, 0x68, 0xEF,
+0x22, 0x7E, 0x00, 0x7F, 0x04, 0x02, 0x41, 0xD0,
+0x24, 0x06, 0xFD, 0x71, 0x68, 0xEF, 0x22, 0x90,
+0x83, 0xFF, 0xE0, 0xFD, 0x90, 0x83, 0xFE, 0xE0,
+0x2D, 0xFD, 0x22, 0xE4, 0xFE, 0xEF, 0x2E, 0xF1,
+0xA2, 0xF5, 0x83, 0xE0, 0xFD, 0x74, 0x04, 0x2E,
+0xF5, 0x82, 0xE4, 0x34, 0x84, 0xF5, 0x83, 0xED,
+0xF0, 0x0E, 0xEE, 0xB4, 0x06, 0xE7, 0x78, 0x7A,
+0x7C, 0x81, 0x7D, 0x01, 0x7B, 0x01, 0x7A, 0x84,
+0x79, 0x04, 0xF1, 0xB3, 0x7F, 0x00, 0x70, 0x02,
+0x7F, 0x01, 0x22, 0x90, 0x83, 0xED, 0xE0, 0xFF,
+0xD1, 0x5B, 0xEF, 0x22, 0xD1, 0xA6, 0xD1, 0x5B,
+0xEF, 0x60, 0x0A, 0x12, 0x57, 0x7B, 0xB1, 0xA9,
+0xEF, 0x60, 0x02, 0x7F, 0x01, 0x22, 0x90, 0x83,
+0xFF, 0xED, 0xF0, 0x90, 0x83, 0xFD, 0xEE, 0xF0,
+0xA3, 0xEF, 0xF0, 0x22, 0x90, 0x83, 0xEB, 0xE0,
+0xFC, 0xA3, 0xE0, 0x22, 0xFF, 0x90, 0x84, 0x00,
+0xE0, 0xFD, 0x90, 0x83, 0xFF, 0xE0, 0x2D, 0x22,
+0x90, 0x01, 0x34, 0x74, 0xFF, 0x11, 0x98, 0x90,
+0x01, 0x3C, 0x11, 0x98, 0xFD, 0x7F, 0x54, 0x12,
+0x32, 0x1E, 0x7D, 0xFF, 0x7F, 0x55, 0x12, 0x32,
+0x1E, 0x7D, 0xFF, 0x7F, 0x56, 0x12, 0x32, 0x1E,
+0x7D, 0xFF, 0x7F, 0x57, 0x02, 0x32, 0x1E, 0x90,
+0x01, 0xC7, 0x74, 0x10, 0xF0, 0x7F, 0x01, 0x90,
+0x84, 0xA2, 0xEF, 0xF0, 0x90, 0x80, 0x07, 0xE0,
+0x64, 0x02, 0x70, 0x1D, 0x90, 0x84, 0xA2, 0xE0,
+0xFD, 0x64, 0x01, 0x70, 0x30, 0x51, 0xCF, 0xF1,
+0x45, 0x30, 0xE0, 0x09, 0x90, 0x01, 0x4D, 0xE0,
+0x64, 0x80, 0xF0, 0x80, 0x20, 0xAF, 0x05, 0x80,
+0x19, 0x90, 0x01, 0x00, 0x74, 0xFF, 0xF0, 0x7F,
+0x64, 0x7E, 0x00, 0x12, 0x32, 0xAA, 0x90, 0x06,
+0x90, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x84, 0xA2,
+0xE0, 0xFF, 0x12, 0x7A, 0x16, 0x90, 0x83, 0xC8,
+0xE0, 0x54, 0xFE, 0xF0, 0x22, 0x90, 0x81, 0x72,
+0xE0, 0xC4, 0x13, 0x13, 0x13, 0x54, 0x01, 0x22,
+0xF1, 0xF9, 0xAD, 0x07, 0x90, 0x01, 0xC4, 0x74,
+0x50, 0xF0, 0x74, 0x5F, 0xA3, 0xF0, 0xED, 0x64,
+0x01, 0x60, 0x1C, 0x51, 0xCF, 0xED, 0xB4, 0x02,
+0x08, 0x90, 0x01, 0xC7, 0x74, 0x40, 0xF0, 0x80,
+0x0A, 0xED, 0xB4, 0x04, 0x06, 0x90, 0x01, 0xC7,
+0x74, 0x41, 0xF0, 0x7F, 0x01, 0xC1, 0xF7, 0x12,
+0x7C, 0x9F, 0x90, 0x02, 0x87, 0xE0, 0x70, 0xF7,
+0x90, 0x06, 0x90, 0xE0, 0x44, 0x02, 0xF0, 0x74,
+0x50, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x5F,
+0xA3, 0xF0, 0x22, 0x90, 0x81, 0x6F, 0xE0, 0x13,
+0x13, 0x22, 0x24, 0x04, 0xF5, 0x82, 0xE4, 0x34,
+0xFB, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5,
+0x83, 0xE0, 0x22, 0x7E, 0x00, 0x7F, 0x06, 0x12,
+0x44, 0x1A, 0xEF, 0x22, 0x74, 0x01, 0x2D, 0xF5,
+0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x22,
+0x7D, 0x01, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0x9B,
+0x7E, 0x00, 0x7F, 0x04, 0x12, 0x44, 0x1A, 0xEF,
+0x22, 0xEF, 0x90, 0x01, 0xC7, 0xB4, 0xA0, 0x05,
+0x74, 0x04, 0xF0, 0x80, 0x03, 0x74, 0x08, 0xF0,
+0x41, 0xCF, 0x7E, 0x00, 0x7F, 0x06, 0x02, 0x41,
+0xD0, 0xEA, 0x90, 0xFD, 0x11, 0xF0, 0xAF, 0x03,
+0x22, 0x90, 0x02, 0x86, 0xE0, 0x20, 0xE2, 0x03,
+0x7F, 0x04, 0x22, 0x90, 0x02, 0x86, 0xE0, 0x7F,
+0x01, 0x20, 0xE1, 0x02, 0x7F, 0x02, 0x22, 0x75,
+0xE8, 0x03, 0x75, 0xA8, 0x84, 0x22, 0x90, 0x00,
+0x80, 0xE0, 0x44, 0x80, 0xFD, 0x7F, 0x80, 0x12,
+0x32, 0x1E, 0x90, 0xFD, 0x00, 0xE0, 0x54, 0xBF,
+0xF0, 0x12, 0x78, 0x4B, 0x12, 0x32, 0x77, 0xF1,
+0xE7, 0x12, 0x78, 0x86, 0x7F, 0x01, 0x12, 0x45,
+0x7F, 0x90, 0x83, 0xC3, 0x74, 0x02, 0xF0, 0xFF,
+0x12, 0x45, 0x7F, 0x90, 0x83, 0xC3, 0xE0, 0x04,
+0xF0, 0x12, 0x58, 0x18, 0x11, 0x70, 0x90, 0x01,
+0xCC, 0x74, 0x0F, 0xF0, 0x90, 0x00, 0x80, 0xE0,
+0x44, 0x40, 0xFD, 0x7F, 0x80, 0x12, 0x32, 0x1E,
+0x75, 0x20, 0xFF, 0x11, 0x0F, 0x12, 0x78, 0x58,
+0x12, 0x78, 0x90, 0xE4, 0xFF, 0x02, 0x46, 0x08,
+0x11, 0x9B, 0x12, 0x77, 0xFF, 0x12, 0x4E, 0xEE,
+0x31, 0x68, 0x31, 0x40, 0x31, 0x53, 0x90, 0x83,
+0xD0, 0xE0, 0x54, 0x7F, 0xF0, 0x54, 0xBF, 0xF0,
+0x54, 0xDF, 0xF0, 0x54, 0xF0, 0xF0, 0xE4, 0x90,
+0x83, 0xD2, 0xF0, 0x90, 0x83, 0xD0, 0xE0, 0x54,
+0xEF, 0xF0, 0x22, 0xE4, 0xFD, 0xFF, 0x12, 0x77,
+0x0B, 0xFE, 0xEF, 0x54, 0x07, 0xFF, 0xED, 0x70,
+0x12, 0x11, 0xDF, 0xC0, 0x83, 0xC0, 0x82, 0x11,
+0xD7, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4,
+0x5E, 0x80, 0x0F, 0x11, 0xDF, 0xC0, 0x83, 0xC0,
+0x82, 0x11, 0xD7, 0x80, 0x02, 0xC3, 0x33, 0xD8,
+0xFC, 0x4E, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0x11,
+0xEA, 0x90, 0x81, 0x04, 0xEF, 0xF0, 0x22, 0xE0,
+0xFE, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x22, 0x74,
+0xFC, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5,
+0x83, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x7D, 0x08, 0xED, 0x14, 0xF9, 0x24, 0xFC,
+0x11, 0xE2, 0xE0, 0x60, 0x3A, 0x7C, 0x08, 0xEC,
+0x14, 0x90, 0x84, 0x9B, 0xF0, 0x74, 0xFC, 0x29,
+0x11, 0xE2, 0xE0, 0xFB, 0x7A, 0x00, 0x90, 0x84,
+0x9B, 0x12, 0x77, 0x4C, 0x80, 0x05, 0xC3, 0x33,
+0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEE, 0x5A,
+0xFE, 0xEF, 0x5B, 0x4E, 0x60, 0x0F, 0xE9, 0x75,
+0xF0, 0x08, 0xA4, 0xFF, 0x90, 0x84, 0x9B, 0xE0,
+0x2F, 0x04, 0xFF, 0x80, 0x06, 0xDC, 0xC8, 0xDD,
+0xBA, 0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x90, 0x83, 0xC4, 0xE0, 0x54, 0xFE, 0xF0, 0x54,
+0x7F, 0xF0, 0x54, 0xFB, 0xF0, 0xA3, 0x74, 0x0A,
+0x02, 0x6A, 0x2C, 0x12, 0x7F, 0xAF, 0x7A, 0x83,
+0x79, 0xC8, 0x12, 0x44, 0x3E, 0x90, 0x83, 0xC9,
+0x74, 0x08, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0x22,
+0x7E, 0x00, 0x7F, 0x27, 0x7D, 0x00, 0x7B, 0x01,
+0x7A, 0x81, 0x79, 0x6E, 0x12, 0x44, 0x3E, 0x90,
+0x06, 0x90, 0xE0, 0x44, 0x20, 0xF0, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFD, 0x7F,
+0x8F, 0x12, 0x32, 0x1E, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x31, 0x7E, 0x90, 0x83, 0xC2, 0xE0, 0xFF,
+0x12, 0x7E, 0x1C, 0x90, 0x01, 0x3F, 0x74, 0x04,
+0xF0, 0x90, 0x80, 0x07, 0xE0, 0xFF, 0xB4, 0x01,
+0x07, 0x90, 0xFD, 0x00, 0xE0, 0x54, 0xEF, 0xF0,
+0xEF, 0xB4, 0x01, 0x07, 0x90, 0xFE, 0x10, 0xE0,
+0x54, 0xFB, 0xF0, 0x22, 0xEF, 0x60, 0x47, 0x90,
+0x04, 0xEC, 0xE0, 0x54, 0xDD, 0xF0, 0x90, 0x83,
+0xB3, 0xE0, 0xFF, 0x60, 0x02, 0x51, 0x28, 0x90,
+0x01, 0xC7, 0xE4, 0x12, 0x7D, 0x4B, 0x12, 0x7F,
+0xC9, 0x90, 0x06, 0x09, 0xE0, 0x54, 0xFE, 0xF0,
+0x7B, 0x35, 0x12, 0x6E, 0xF7, 0x12, 0x6C, 0x1A,
+0x90, 0x02, 0x86, 0xE0, 0x44, 0x04, 0xF0, 0x12,
+0x5F, 0x50, 0xF1, 0xE8, 0x12, 0x4E, 0x35, 0x12,
+0x7E, 0xDA, 0x90, 0x01, 0x34, 0x74, 0x08, 0xF0,
+0xFD, 0xE4, 0xFF, 0x02, 0x6F, 0x08, 0x90, 0x04,
+0xEC, 0xE0, 0x44, 0x22, 0xF0, 0x7D, 0x08, 0xE4,
+0xFF, 0x12, 0x6F, 0xB9, 0x90, 0x06, 0x90, 0xE0,
+0x54, 0xF0, 0xF0, 0x90, 0x02, 0x86, 0xE0, 0x54,
+0xFB, 0xF0, 0x31, 0x91, 0xF1, 0xE9, 0x21, 0x68,
+0xF1, 0xF0, 0x51, 0x38, 0x75, 0x16, 0x08, 0x7B,
+0x01, 0x7A, 0x83, 0x79, 0x7D, 0x02, 0x2B, 0xED,
+0x75, 0x13, 0x01, 0xF5, 0x14, 0x89, 0x15, 0x22,
+0xF1, 0x83, 0x90, 0x84, 0x8F, 0xE4, 0xF0, 0xA3,
+0xEF, 0xF0, 0x90, 0x84, 0x8F, 0x71, 0xF5, 0x90,
+0x84, 0x91, 0xEF, 0xF0, 0x90, 0x84, 0x8F, 0x71,
+0xDF, 0x51, 0x38, 0x75, 0x16, 0x06, 0x7B, 0x01,
+0x7A, 0x81, 0x79, 0x95, 0x71, 0xD7, 0x51, 0xA4,
+0x24, 0x36, 0xF9, 0xE4, 0x34, 0xFC, 0x51, 0x38,
+0x75, 0x16, 0x04, 0x7B, 0x01, 0x7A, 0x81, 0x79,
+0x9B, 0x71, 0xD7, 0x51, 0xA4, 0x71, 0xC9, 0x51,
+0x38, 0x75, 0x16, 0x06, 0x7B, 0x01, 0x7A, 0x81,
+0x79, 0x9F, 0x71, 0xD7, 0x51, 0xA4, 0x71, 0xD0,
+0x51, 0x38, 0x75, 0x16, 0x04, 0x7B, 0x01, 0x7A,
+0x81, 0x79, 0xA5, 0x02, 0x2B, 0xED, 0x12, 0x2B,
+0xED, 0x90, 0x84, 0x1E, 0xA3, 0xE0, 0xFF, 0xA3,
+0xE0, 0x2F, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x84, 0x16, 0x12, 0x42, 0x65,
+0x78, 0x22, 0x7C, 0x84, 0x7D, 0x01, 0x7B, 0xFF,
+0x7A, 0x40, 0x79, 0xCE, 0x12, 0x5F, 0xEA, 0x90,
+0x05, 0x22, 0xE0, 0x90, 0x84, 0x21, 0xF0, 0x90,
+0x04, 0x1D, 0xE0, 0x60, 0x08, 0x7B, 0x33, 0xF1,
+0x0D, 0x70, 0x1B, 0x80, 0x00, 0x90, 0x83, 0xB4,
+0xE0, 0xFF, 0x90, 0x84, 0x83, 0x74, 0x10, 0xF0,
+0x7B, 0x18, 0x7D, 0x01, 0xB1, 0x3A, 0x90, 0x84,
+0x1E, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x84,
+0x1E, 0x71, 0xF5, 0x90, 0x84, 0x20, 0xEF, 0xF0,
+0x90, 0x84, 0x1E, 0xA3, 0xE0, 0x24, 0x20, 0xF9,
+0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0x90, 0x84,
+0x1C, 0xE0, 0xFD, 0x91, 0x9F, 0x90, 0x84, 0x1D,
+0xE0, 0x70, 0x49, 0x71, 0xDE, 0xFA, 0x7B, 0x01,
+0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x71, 0xE8,
+0x75, 0x16, 0x06, 0xD0, 0x01, 0xD0, 0x02, 0xD0,
+0x03, 0x51, 0x9E, 0x71, 0xC9, 0xFA, 0x7B, 0x01,
+0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x71, 0xE8,
+0x75, 0x16, 0x06, 0xD0, 0x01, 0xD0, 0x02, 0xD0,
+0x03, 0x51, 0x9E, 0x71, 0xD0, 0xFA, 0x7B, 0x01,
+0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x84,
+0x16, 0x71, 0xEB, 0x75, 0x16, 0x04, 0xD0, 0x01,
+0xD0, 0x02, 0x80, 0x46, 0x90, 0x84, 0x1D, 0xE0,
+0x64, 0x01, 0x70, 0x43, 0x71, 0xDE, 0xFA, 0x7B,
+0x01, 0xC0, 0x03, 0x8B, 0x13, 0x75, 0x14, 0x81,
+0x75, 0x15, 0x95, 0x75, 0x16, 0x06, 0xD0, 0x03,
+0x51, 0x9E, 0x71, 0xC9, 0xFA, 0x7B, 0x01, 0xC0,
+0x03, 0x8B, 0x13, 0x75, 0x14, 0x81, 0x75, 0x15,
+0x9F, 0x75, 0x16, 0x06, 0xD0, 0x03, 0x51, 0x9E,
+0x71, 0xD0, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0x8B,
+0x13, 0x75, 0x14, 0x81, 0x75, 0x15, 0xA5, 0x75,
+0x16, 0x04, 0xD0, 0x03, 0x12, 0x2B, 0xED, 0x90,
+0x06, 0x30, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x84,
+0x21, 0xE0, 0xFD, 0x7B, 0x34, 0xE4, 0xFF, 0x12,
+0x4E, 0x3D, 0xF1, 0xB3, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x24, 0x3A, 0xF9, 0xE4, 0x34, 0xFC, 0x22,
+0x24, 0x40, 0xF9, 0xE4, 0x34, 0xFC, 0x22, 0x12,
+0x2B, 0xED, 0x90, 0x84, 0x8F, 0x22, 0xA3, 0xA3,
+0xE0, 0x24, 0x30, 0xF9, 0xE4, 0x34, 0xFC, 0x22,
+0x90, 0x84, 0x19, 0x12, 0x42, 0x5C, 0x8B, 0x13,
+0x8A, 0x14, 0x89, 0x15, 0x22, 0xA3, 0xE0, 0xFE,
+0x24, 0x20, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5,
+0x83, 0xE0, 0xFF, 0x74, 0x21, 0x2E, 0xF5, 0x82,
+0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFD, 0x74,
+0x24, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5,
+0x83, 0xE0, 0xFB, 0xE4, 0xFE, 0xEF, 0x30, 0xE7,
+0x04, 0x7C, 0x02, 0x80, 0x02, 0xE4, 0xFC, 0xED,
+0x30, 0xE6, 0x09, 0xAF, 0x03, 0x12, 0x7D, 0xDD,
+0xAE, 0x07, 0x80, 0x02, 0xE4, 0xFE, 0xEC, 0x24,
+0x18, 0x2E, 0xFF, 0x22, 0x90, 0x84, 0x60, 0xED,
+0xF0, 0x90, 0x84, 0x5D, 0x12, 0x42, 0x65, 0x12,
+0x57, 0xC2, 0x90, 0x84, 0x64, 0xF0, 0x90, 0x84,
+0x5D, 0x71, 0xEB, 0x75, 0x16, 0x03, 0x7B, 0x01,
+0x7A, 0x84, 0x79, 0x61, 0x12, 0x2B, 0xED, 0x90,
+0x84, 0x60, 0xE0, 0x70, 0x2E, 0xFF, 0x91, 0x94,
+0xE0, 0xB4, 0xFF, 0x06, 0x91, 0x94, 0xE4, 0xF0,
+0x80, 0x07, 0x91, 0x94, 0xE0, 0x04, 0xF0, 0x80,
+0x05, 0x0F, 0xEF, 0xB4, 0x03, 0xE8, 0x75, 0x13,
+0x01, 0x75, 0x14, 0x84, 0x75, 0x15, 0x61, 0x75,
+0x16, 0x03, 0x90, 0x84, 0x5D, 0x12, 0x42, 0x5C,
+0x12, 0x2B, 0xED, 0x22, 0x74, 0x61, 0x2F, 0xF5,
+0x82, 0xE4, 0x34, 0x84, 0xF5, 0x83, 0x22, 0x90,
+0x84, 0x74, 0xED, 0xF0, 0x90, 0x84, 0x71, 0x12,
+0x42, 0x65, 0xE4, 0x90, 0x84, 0x75, 0xF0, 0xA3,
+0xF0, 0x12, 0x1F, 0xA4, 0xFF, 0x12, 0x56, 0x7B,
+0xFD, 0x12, 0x55, 0x82, 0xFB, 0x91, 0x1B, 0x90,
+0x84, 0x75, 0xEF, 0xF0, 0x90, 0x84, 0x71, 0x12,
+0x42, 0x5C, 0x12, 0x55, 0x82, 0xFF, 0x12, 0x7D,
+0xDD, 0x90, 0x84, 0x76, 0xEF, 0xF0, 0x90, 0x83,
+0xAE, 0xE0, 0x24, 0xFE, 0x60, 0x14, 0x24, 0xFE,
+0x60, 0x10, 0x14, 0x60, 0x07, 0x14, 0x60, 0x04,
+0x24, 0x05, 0x70, 0x41, 0xB1, 0x2E, 0x91, 0x3C,
+0x80, 0x0D, 0xB1, 0x2E, 0x90, 0x83, 0xAE, 0xE0,
+0x90, 0x84, 0x4A, 0xF0, 0x12, 0x55, 0x88, 0x90,
+0x84, 0x76, 0xE0, 0xFF, 0x90, 0x84, 0x71, 0x12,
+0x42, 0x5C, 0x90, 0x84, 0x75, 0xE0, 0x7C, 0x00,
+0x29, 0xF9, 0xEC, 0x3A, 0xFA, 0xC3, 0xE9, 0x9F,
+0xF9, 0xEA, 0x94, 0x00, 0xFA, 0x75, 0x13, 0x01,
+0x75, 0x14, 0x83, 0x75, 0x15, 0x7D, 0xA3, 0xE0,
+0xF5, 0x16, 0x12, 0x2B, 0xED, 0x22, 0x7B, 0x01,
+0x7A, 0x83, 0x79, 0x7D, 0x90, 0x84, 0x74, 0xE0,
+0xFD, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0x90, 0x84, 0x81, 0xED, 0xF0, 0xA3, 0xEB,
+0xF0, 0x90, 0x84, 0x80, 0xEF, 0xF0, 0xE4, 0xFD,
+0xFC, 0xF1, 0xBA, 0x90, 0x84, 0x80, 0xE0, 0x90,
+0x04, 0x25, 0xF0, 0x90, 0x84, 0x81, 0xE0, 0x60,
+0x0E, 0x74, 0x0F, 0x2F, 0xF5, 0x82, 0xE4, 0x34,
+0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0xAF,
+0x05, 0x74, 0x08, 0x2F, 0xF5, 0x82, 0xE4, 0x34,
+0xFC, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x09, 0x2F,
+0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0,
+0x54, 0xF0, 0xF0, 0xAF, 0x05, 0xB1, 0xCC, 0xE0,
+0x20, 0xE1, 0x15, 0x54, 0x01, 0xFE, 0x90, 0x84,
+0x82, 0xE0, 0x25, 0xE0, 0x25, 0xE0, 0xFB, 0xEE,
+0x44, 0x02, 0x4B, 0xFE, 0xB1, 0xCC, 0xEE, 0xF0,
+0x90, 0x84, 0x83, 0xE0, 0xFF, 0xAE, 0x05, 0x74,
+0x1E, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5,
+0x83, 0xEF, 0xF0, 0x74, 0x21, 0x2E, 0xD1, 0xF0,
+0x54, 0xF7, 0xF0, 0xAE, 0x04, 0xAF, 0x05, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x74, 0x16, 0x2F, 0xF5,
+0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x90,
+0x80, 0x0B, 0xE0, 0xFF, 0x90, 0x84, 0x78, 0xE0,
+0xFB, 0x90, 0x84, 0x83, 0x74, 0x0A, 0xF0, 0x7D,
+0x01, 0xB1, 0x3A, 0x90, 0x84, 0x79, 0xEE, 0xF0,
+0xFC, 0xA3, 0xEF, 0xF0, 0xFD, 0x90, 0x84, 0x77,
+0xE0, 0xFF, 0xD1, 0xB5, 0x90, 0x84, 0x79, 0xE0,
+0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x04, 0x80, 0xE0,
+0x54, 0x0F, 0xFD, 0xAC, 0x07, 0xF1, 0x01, 0x44,
+0x01, 0xF0, 0xF1, 0x01, 0x54, 0xFB, 0xF0, 0xAC,
+0x07, 0x74, 0x16, 0x2C, 0xB1, 0xCF, 0xE0, 0x44,
+0xFA, 0xF0, 0x74, 0x15, 0x2C, 0xF5, 0x82, 0xE4,
+0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x1F, 0xF0,
+0xAC, 0x07, 0x74, 0x06, 0x2C, 0xF5, 0x82, 0xE4,
+0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x0F, 0xF0,
+0x90, 0x04, 0x53, 0xE4, 0xF0, 0x90, 0x04, 0x52,
+0xF0, 0x90, 0x04, 0x51, 0x74, 0xFF, 0xF0, 0x90,
+0x04, 0x50, 0x74, 0xFD, 0xF0, 0x74, 0x14, 0x2C,
+0xD1, 0xF9, 0xE0, 0x54, 0xC0, 0x4D, 0xFD, 0x74,
+0x14, 0x2F, 0xD1, 0xF9, 0xED, 0xF0, 0x22, 0x7D,
+0x08, 0xE4, 0xFF, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
+0xC0, 0xD0, 0x90, 0x84, 0x77, 0xEF, 0xF0, 0xA3,
+0xED, 0xF0, 0x90, 0x80, 0x03, 0xE0, 0x04, 0xF0,
+0x90, 0x04, 0x1D, 0xE0, 0x60, 0x21, 0x90, 0x05,
+0x22, 0xE0, 0x90, 0x84, 0x7B, 0xF0, 0x7B, 0x26,
+0xF1, 0x0D, 0x70, 0x02, 0xB1, 0xD7, 0x90, 0x84,
+0x7B, 0xE0, 0xFD, 0x7B, 0x27, 0xE4, 0xFF, 0x12,
+0x4E, 0x3D, 0x12, 0x7B, 0x63, 0x80, 0x05, 0x12,
+0x7B, 0x63, 0xB1, 0xD7, 0xF1, 0xB3, 0x7F, 0x01,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD1, 0xE1, 0x54,
+0x3F, 0xF0, 0xBF, 0x01, 0x02, 0x80, 0x17, 0xEF,
+0x70, 0x02, 0x80, 0x07, 0x90, 0x81, 0x0D, 0xE0,
+0x30, 0xE3, 0x0B, 0xD1, 0xED, 0x54, 0xEF, 0xF0,
+0xD1, 0xE1, 0x44, 0x40, 0xF0, 0x22, 0xD1, 0xED,
+0x44, 0x10, 0xF0, 0xD1, 0xE1, 0x44, 0x80, 0xF0,
+0x22, 0x74, 0x1F, 0x2D, 0xF5, 0x82, 0xE4, 0x34,
+0xFC, 0xF5, 0x83, 0xE0, 0x22, 0x74, 0x21, 0x2D,
+0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0,
+0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
+0x22, 0x74, 0x11, 0x2C, 0xF5, 0x82, 0xE4, 0x34,
+0xFC, 0xF5, 0x83, 0xE0, 0x22, 0x7D, 0xFF, 0xE4,
+0xFF, 0x12, 0x4E, 0x3D, 0xF1, 0x1A, 0xEF, 0x64,
+0x01, 0x22, 0xE4, 0x90, 0x84, 0x8C, 0xF0, 0xA3,
+0xF0, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x84, 0x8E,
+0xF0, 0x7B, 0x47, 0x7D, 0xFF, 0xE4, 0xFF, 0x12,
+0x4E, 0x3D, 0x90, 0x05, 0xF8, 0xE0, 0x70, 0x1B,
+0xA3, 0xE0, 0x70, 0x17, 0xA3, 0xE0, 0x70, 0x13,
+0xA3, 0xE0, 0x70, 0x0F, 0x90, 0x84, 0x8E, 0xE0,
+0xFD, 0x7B, 0x48, 0xE4, 0xFF, 0x12, 0x4E, 0x3D,
+0x7F, 0x01, 0x22, 0xD3, 0x90, 0x84, 0x8D, 0xE0,
+0x94, 0xE8, 0x90, 0x84, 0x8C, 0xE0, 0x94, 0x03,
+0x40, 0x16, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x20,
+0xF0, 0x90, 0x84, 0x8E, 0xE0, 0xFD, 0x7B, 0x5B,
+0xE4, 0xFF, 0x12, 0x4E, 0x3D, 0x7F, 0x00, 0x22,
+0x12, 0x6F, 0xE1, 0x90, 0x84, 0x8C, 0x12, 0x69,
+0xA3, 0x80, 0xAF, 0xE4, 0xFE, 0xEF, 0xC3, 0x13,
+0xFD, 0xEF, 0x30, 0xE0, 0x02, 0x7E, 0x80, 0x90,
+0xFD, 0x10, 0xED, 0xF0, 0xAF, 0x06, 0x22, 0x90,
+0x83, 0xC4, 0x12, 0x73, 0x88, 0x30, 0xE0, 0x0D,
+0x7B, 0x00, 0x7A, 0x00, 0x79, 0x00, 0x12, 0x7F,
+0x86, 0x04, 0xF0, 0x41, 0xAB, 0x7D, 0x08, 0x7F,
+0x02, 0xC1, 0x6B, 0x90, 0x04, 0x1F, 0x74, 0x20,
+0xF0, 0x22, 0xF1, 0x83, 0x7C, 0x00, 0xAD, 0x07,
+0x22, 0xE4, 0xFD, 0xFC, 0xEF, 0x60, 0x1F, 0x90,
+0x83, 0xB7, 0xE0, 0xFF, 0xF1, 0xBA, 0xF1, 0xF4,
+0xFA, 0x7B, 0x01, 0xF1, 0xEA, 0x90, 0x83, 0xEF,
+0x71, 0xEB, 0x75, 0x16, 0x42, 0x7B, 0x01, 0x7A,
+0x82, 0x79, 0x41, 0x12, 0x2B, 0xED, 0x22, 0x22,
+0x22, 0x22, 0x90, 0x83, 0xEF, 0x02, 0x42, 0x65,
+0xF1, 0x83, 0x7E, 0x00, 0x74, 0x00, 0x2F, 0xF9,
+0xE4, 0x34, 0xFC, 0x22, 0xE4, 0x90, 0x83, 0xE4,
+0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x83, 0xE4,
+0xE0, 0x64, 0x01, 0xF0, 0x24, 0xFC, 0x90, 0x01,
+0xC4, 0xF0, 0x74, 0x67, 0xA3, 0xF0, 0x90, 0x81,
+0x0A, 0xE0, 0x60, 0x0F, 0x90, 0x81, 0x0D, 0xE0,
+0xFF, 0x90, 0x81, 0x0C, 0xE0, 0x6F, 0x60, 0x03,
+0x12, 0x72, 0x2E, 0xC2, 0xAF, 0x12, 0x78, 0x5F,
+0xBF, 0x01, 0x02, 0x11, 0x3E, 0xD2, 0xAF, 0x31,
+0xA2, 0x12, 0x44, 0xB7, 0x80, 0xC7, 0x90, 0x81,
+0x05, 0xE0, 0x30, 0xE0, 0x02, 0x11, 0x48, 0x22,
+0x90, 0x81, 0x0D, 0xE0, 0xFF, 0x60, 0x03, 0xB4,
+0x08, 0x0D, 0x31, 0x3D, 0xBF, 0x01, 0x08, 0x11,
+0x60, 0x90, 0x01, 0xE5, 0xE0, 0x04, 0xF0, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x11,
+0xE5, 0x11, 0x70, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x12, 0x79, 0xF9, 0x90, 0x81, 0x15, 0xE0, 0x20,
+0xE0, 0x0C, 0x90, 0x00, 0x26, 0xE0, 0x54, 0x7F,
+0xFD, 0x7F, 0x26, 0x12, 0x32, 0x1E, 0x90, 0x00,
+0x08, 0xE0, 0x54, 0xEF, 0xFD, 0x7F, 0x08, 0x12,
+0x32, 0x1E, 0xE4, 0xFF, 0x90, 0x83, 0xE7, 0x51,
+0x2B, 0x90, 0x01, 0x09, 0xE0, 0x7F, 0x00, 0x30,
+0xE7, 0x02, 0x7F, 0x01, 0x90, 0x83, 0xE7, 0xE0,
+0x6F, 0x60, 0x39, 0xC3, 0x90, 0x83, 0xE9, 0xE0,
+0x94, 0x88, 0x90, 0x83, 0xE8, 0xE0, 0x94, 0x13,
+0x40, 0x08, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x10,
+0xF0, 0x22, 0x90, 0x83, 0xE8, 0x31, 0xA3, 0x7F,
+0x14, 0x7E, 0x00, 0x12, 0x32, 0xAA, 0xD3, 0x90,
+0x83, 0xE9, 0xE0, 0x94, 0x32, 0x90, 0x83, 0xE8,
+0xE0, 0x94, 0x00, 0x40, 0xBC, 0x90, 0x01, 0xC6,
+0xE0, 0x30, 0xE0, 0xB5, 0x22, 0x90, 0x81, 0x15,
+0xE0, 0xFD, 0x7F, 0x93, 0x12, 0x32, 0x1E, 0x90,
+0x81, 0x0B, 0xE0, 0x60, 0x12, 0x90, 0x01, 0x2F,
+0xE0, 0x30, 0xE7, 0x05, 0x74, 0x10, 0xF0, 0x80,
+0x06, 0x90, 0x01, 0x2F, 0x74, 0x90, 0xF0, 0x90,
+0x00, 0x08, 0xE0, 0x44, 0x10, 0xFD, 0x7F, 0x08,
+0x12, 0x32, 0x1E, 0x7F, 0x01, 0x11, 0x94, 0x90,
+0x81, 0x15, 0xE0, 0x20, 0xE0, 0x0C, 0x90, 0x00,
+0x26, 0xE0, 0x44, 0x80, 0xFD, 0x7F, 0x26, 0x12,
+0x32, 0x1E, 0x90, 0x00, 0x90, 0xE0, 0x44, 0x01,
+0xFD, 0x7F, 0x90, 0x12, 0x32, 0x1E, 0x7F, 0x14,
+0x7E, 0x00, 0x02, 0x32, 0xAA, 0x90, 0x02, 0x87,
+0xE0, 0x60, 0x02, 0x80, 0x08, 0x90, 0x01, 0x00,
+0xE0, 0x64, 0x3F, 0x60, 0x05, 0x75, 0x51, 0x01,
+0x80, 0x41, 0x90, 0x81, 0x6E, 0xE0, 0x30, 0xE0,
+0x0B, 0x90, 0x02, 0x82, 0xE0, 0x60, 0x05, 0x75,
+0x51, 0x02, 0x80, 0x2F, 0x90, 0x81, 0x79, 0xE0,
+0x30, 0xE0, 0x05, 0x75, 0x51, 0x08, 0x80, 0x23,
+0x90, 0x02, 0x86, 0xE0, 0x20, 0xE1, 0x02, 0x80,
+0x07, 0x90, 0x02, 0x86, 0xE0, 0x30, 0xE3, 0x05,
+0x75, 0x51, 0x04, 0x80, 0x0E, 0x90, 0x04, 0x1D,
+0xE0, 0x60, 0x05, 0x75, 0x51, 0x40, 0x80, 0x03,
+0x02, 0x7A, 0xCD, 0x90, 0x01, 0xB9, 0x74, 0x08,
+0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x51, 0xF0, 0x7F,
+0x00, 0x22, 0x22, 0xE4, 0x75, 0xF0, 0x01, 0x02,
+0x41, 0xF6, 0xE4, 0x90, 0x84, 0x98, 0xF0, 0xA3,
+0xF0, 0x90, 0x02, 0x86, 0xE0, 0x20, 0xE1, 0x22,
+0xC3, 0x90, 0x84, 0x99, 0xE0, 0x94, 0xD0, 0x90,
+0x84, 0x98, 0xE0, 0x94, 0x07, 0x40, 0x0A, 0x90,
+0x01, 0xC1, 0xE0, 0x44, 0x04, 0xF0, 0x7F, 0x00,
+0x22, 0x90, 0x84, 0x98, 0x31, 0xA3, 0x51, 0x24,
+0x80, 0xD7, 0x7F, 0x01, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x84, 0x7C, 0xEE,
+0xF0, 0xA3, 0x51, 0x2B, 0x90, 0x84, 0x7C, 0xE0,
+0xFE, 0xA3, 0xE0, 0xF5, 0x82, 0x8E, 0x83, 0xE0,
+0x60, 0x23, 0xC3, 0x90, 0x84, 0x7F, 0xE0, 0x94,
+0xE8, 0x90, 0x84, 0x7E, 0xE0, 0x94, 0x03, 0x40,
+0x0B, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x80, 0xF0,
+0x7F, 0x00, 0x80, 0x0B, 0x90, 0x84, 0x7E, 0x31,
+0xA3, 0x51, 0x24, 0x80, 0xCF, 0x7F, 0x01, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0x7F, 0x0A, 0x7E, 0x00,
+0x02, 0x32, 0xAA, 0xEF, 0xF0, 0xE4, 0xA3, 0xF0,
+0xA3, 0xF0, 0x22, 0xE4, 0xFB, 0xFA, 0xFD, 0x7F,
+0x01, 0x12, 0x46, 0xB8, 0x90, 0x83, 0xEA, 0xEF,
+0xF0, 0x60, 0xF0, 0x90, 0x80, 0x01, 0xE0, 0xFF,
+0x70, 0x04, 0xA3, 0xE0, 0x60, 0xE5, 0xC2, 0xAF,
+0xEF, 0x30, 0xE1, 0x09, 0x90, 0x80, 0x01, 0xE0,
+0x54, 0xFD, 0xF0, 0x51, 0x85, 0x51, 0x7B, 0x30,
+0xE2, 0x05, 0x54, 0xFB, 0xF0, 0x51, 0xE6, 0x51,
+0x7B, 0x30, 0xE4, 0x0B, 0x54, 0xEF, 0xF0, 0x31,
+0xAA, 0xBF, 0x01, 0x03, 0x12, 0x58, 0xA0, 0xD2,
+0xAF, 0x80, 0xC8, 0xD2, 0xAF, 0xC2, 0xAF, 0x90,
+0x80, 0x01, 0xE0, 0xFF, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x80, 0x61, 0xE0,
+0xFF, 0x90, 0x80, 0x60, 0xE0, 0xB5, 0x07, 0x04,
+0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70,
+0x40, 0x90, 0x80, 0x60, 0xE0, 0xFE, 0x75, 0xF0,
+0x08, 0x90, 0x80, 0x10, 0x12, 0x42, 0x50, 0xE0,
+0xFD, 0xEE, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x11,
+0xF9, 0x74, 0x80, 0x35, 0xF0, 0xFA, 0x7B, 0x01,
+0xAF, 0x05, 0x12, 0x54, 0xF4, 0x90, 0x80, 0x60,
+0x71, 0x4D, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF,
+0x60, 0x05, 0xE4, 0x90, 0x80, 0x60, 0xF0, 0x12,
+0x50, 0xE4, 0x90, 0x80, 0x01, 0xE0, 0x44, 0x02,
+0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFF, 0x90,
+0x80, 0xF9, 0xE0, 0xFE, 0x90, 0x80, 0xF8, 0xE0,
+0xFD, 0xB5, 0x06, 0x04, 0x7E, 0x01, 0x80, 0x02,
+0x7E, 0x00, 0xEE, 0x64, 0x01, 0x60, 0x41, 0x90,
+0x01, 0xAF, 0xE0, 0x70, 0x0A, 0xED, 0x91, 0x0E,
+0xFA, 0x7B, 0x01, 0x71, 0x54, 0x7F, 0x01, 0xEF,
+0x60, 0x2E, 0x90, 0x80, 0xF8, 0x71, 0x4D, 0xB4,
+0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4,
+0x90, 0x80, 0xF8, 0xF0, 0x90, 0x80, 0xF9, 0xE0,
+0xFF, 0x90, 0x80, 0xF8, 0xE0, 0xB5, 0x07, 0x04,
+0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70,
+0x07, 0x90, 0x80, 0x01, 0xE0, 0x44, 0x04, 0xF0,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE0, 0x04, 0xF0,
+0xE0, 0x7F, 0x00, 0x22, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x83, 0xEB, 0x12, 0x42,
+0x65, 0x90, 0x84, 0x93, 0xE0, 0xFF, 0x04, 0xF0,
+0x90, 0x00, 0x01, 0xEF, 0x12, 0x1F, 0xFC, 0x7F,
+0xAF, 0x7E, 0x01, 0x31, 0xDD, 0xEF, 0x60, 0x34,
+0x90, 0x83, 0xEB, 0x12, 0x63, 0xEB, 0x90, 0x00,
+0x0E, 0x12, 0x1F, 0xBD, 0x24, 0x02, 0xF5, 0x16,
+0x7B, 0x01, 0x7A, 0x01, 0x79, 0xA0, 0x12, 0x2B,
+0xED, 0x90, 0x83, 0xEB, 0x12, 0x42, 0x5C, 0x90,
+0x00, 0x0E, 0x12, 0x1F, 0xBD, 0x90, 0x01, 0xAE,
+0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0x90, 0x01, 0xCB,
+0xE0, 0x64, 0x80, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
+0x90, 0x80, 0xF8, 0xE0, 0xFF, 0x70, 0x06, 0xA3,
+0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF,
+0x90, 0x80, 0xF9, 0xE0, 0xB5, 0x07, 0x04, 0x7F,
+0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x09,
+0x90, 0x01, 0xC1, 0xE0, 0x44, 0x02, 0xF0, 0x80,
+0x28, 0xC0, 0x01, 0x90, 0x80, 0xF9, 0xE0, 0x91,
+0x0E, 0xA8, 0x01, 0xFC, 0x7D, 0x01, 0xD0, 0x01,
+0x7E, 0x00, 0x7F, 0x0F, 0x12, 0x41, 0xD0, 0x90,
+0x80, 0xF9, 0x71, 0x4D, 0xB4, 0x0A, 0x02, 0x7F,
+0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x80, 0xF9,
+0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x75, 0xF0,
+0x0F, 0xA4, 0x24, 0x62, 0xF9, 0x74, 0x80, 0x35,
+0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0,
+0xD0, 0xE4, 0x90, 0x84, 0x6B, 0xF0, 0xA3, 0xF0,
+0x12, 0x67, 0x1A, 0x90, 0x85, 0xBB, 0x12, 0x20,
+0xDA, 0xCC, 0xF0, 0x00, 0xC0, 0x7F, 0x8C, 0xD1,
+0x2D, 0x12, 0x20, 0xDA, 0x00, 0x00, 0x00, 0x14,
+0xD1, 0xC4, 0x12, 0x20, 0xDA, 0x00, 0x00, 0x00,
+0x00, 0xE4, 0xFD, 0xFF, 0xD1, 0x8F, 0x7F, 0xE8,
+0x7E, 0x08, 0x12, 0x2D, 0x5C, 0xEF, 0x54, 0x0E,
+0xFF, 0xE4, 0xFE, 0xED, 0x54, 0xF4, 0xFD, 0xEC,
+0x54, 0x03, 0xFC, 0xE4, 0xFB, 0xFA, 0xF9, 0xF8,
+0xC3, 0x12, 0x42, 0x27, 0x60, 0x17, 0xD3, 0x91,
+0xB8, 0x40, 0x09, 0x90, 0x01, 0xC3, 0xE0, 0x44,
+0x02, 0xF0, 0x80, 0x09, 0xF1, 0xE1, 0x90, 0x84,
+0x6B, 0x31, 0xA3, 0x80, 0xC9, 0xC3, 0x91, 0xB8,
+0x50, 0x17, 0xD1, 0xB1, 0x44, 0x80, 0xFC, 0x90,
+0x84, 0x6D, 0x12, 0x20, 0xCE, 0x90, 0x84, 0x6D,
+0x91, 0xC5, 0x7F, 0x7C, 0x7E, 0x08, 0x12, 0x2E,
+0xA2, 0x90, 0x01, 0x00, 0x74, 0x3F, 0xF0, 0xA3,
+0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x05, 0x53, 0xE0,
+0x44, 0x20, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22,
+0x90, 0x84, 0x6C, 0xE0, 0x94, 0xE8, 0x90, 0x84,
+0x6B, 0xE0, 0x94, 0x03, 0x22, 0x12, 0x42, 0x38,
+0x90, 0x85, 0xBB, 0x02, 0x20, 0xCE, 0x90, 0x84,
+0x28, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xA3, 0x12,
+0x20, 0xDA, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x90,
+0x84, 0x36, 0xF0, 0x7F, 0x24, 0x7E, 0x08, 0x12,
+0x2D, 0x5C, 0x90, 0x84, 0x2E, 0x12, 0x20, 0xCE,
+0x90, 0x84, 0x28, 0xE0, 0xFB, 0x70, 0x04, 0xB1,
+0xB1, 0x80, 0x06, 0xEB, 0xB1, 0xB7, 0x12, 0x2D,
+0x5C, 0x90, 0x84, 0x32, 0x12, 0x20, 0xCE, 0x90,
+0x84, 0x29, 0x12, 0x49, 0x51, 0x78, 0x17, 0xD1,
+0xBA, 0xAB, 0x07, 0x90, 0x84, 0x32, 0x12, 0x42,
+0x38, 0xED, 0x54, 0x7F, 0xFD, 0xEC, 0x54, 0x80,
+0xFC, 0x12, 0x42, 0x1A, 0xEC, 0x44, 0x80, 0xFC,
+0x90, 0x84, 0x32, 0x12, 0x20, 0xCE, 0xB1, 0xB1,
+0xEC, 0x54, 0x7F, 0xFC, 0x91, 0xC8, 0xB1, 0xCA,
+0xB1, 0xB7, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x84,
+0x32, 0x91, 0xC5, 0xD0, 0x07, 0xD0, 0x06, 0x12,
+0x2E, 0xA2, 0xB1, 0xB1, 0xEC, 0x44, 0x80, 0xFC,
+0x91, 0xC8, 0xB1, 0xCA, 0x70, 0x04, 0x7F, 0x20,
+0x80, 0x09, 0x90, 0x84, 0x28, 0xE0, 0xB4, 0x01,
+0x16, 0x7F, 0x28, 0x7E, 0x08, 0x12, 0x2D, 0x5C,
+0x78, 0x08, 0x12, 0x20, 0xA8, 0xEF, 0x54, 0x01,
+0xFF, 0xE4, 0x90, 0x84, 0x36, 0xEF, 0xF0, 0x90,
+0x84, 0x36, 0xE0, 0x90, 0x84, 0x28, 0x60, 0x0E,
+0xE0, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x66, 0xF5,
+0x82, 0xE4, 0x34, 0x87, 0x80, 0x0C, 0xE0, 0x75,
+0xF0, 0x08, 0xA4, 0x24, 0x64, 0xF5, 0x82, 0xE4,
+0x34, 0x87, 0xB1, 0xC2, 0x12, 0x2D, 0x5C, 0xED,
+0x54, 0x0F, 0xFD, 0xE4, 0xFC, 0x90, 0x84, 0x2A,
+0x12, 0x20, 0xCE, 0x90, 0x84, 0x2A, 0x02, 0x42,
+0x38, 0x90, 0x84, 0x2E, 0x02, 0x42, 0x38, 0x75,
+0xF0, 0x08, 0xA4, 0x24, 0x62, 0xF5, 0x82, 0xE4,
+0x34, 0x87, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0x22, 0x7F, 0x24, 0x7E, 0x08, 0x12, 0x2E,
+0xA2, 0x90, 0x84, 0x28, 0xE0, 0x22, 0x90, 0x84,
+0x53, 0xEF, 0xF0, 0xAB, 0x05, 0x90, 0x84, 0x59,
+0x12, 0x20, 0xDA, 0x00, 0x00, 0x00, 0x00, 0xAF,
+0x03, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x14, 0xD1,
+0xBA, 0xAB, 0x07, 0x90, 0x84, 0x55, 0x12, 0x42,
+0x38, 0xED, 0x54, 0x0F, 0xFD, 0xE4, 0xFC, 0x12,
+0x42, 0x1A, 0xEC, 0x54, 0x0F, 0xFC, 0x90, 0x84,
+0x59, 0x12, 0x20, 0xCE, 0x90, 0x84, 0x53, 0xE0,
+0x75, 0xF0, 0x08, 0xA4, 0x24, 0x60, 0xF5, 0x82,
+0xE4, 0x34, 0x87, 0xB1, 0xC2, 0xC0, 0x06, 0xC0,
+0x07, 0x90, 0x84, 0x59, 0x91, 0xC5, 0xD0, 0x07,
+0xD0, 0x06, 0x02, 0x2E, 0xA2, 0x7E, 0x08, 0x12,
+0x2E, 0xA2, 0x90, 0x85, 0xBB, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x01, 0x01,
+0xE0, 0x44, 0x02, 0xF0, 0x90, 0x01, 0x00, 0x74,
+0xFF, 0xF0, 0x90, 0x06, 0xB7, 0x74, 0x09, 0xF0,
+0x90, 0x06, 0xB4, 0x74, 0x86, 0xF0, 0xD1, 0xB1,
+0x54, 0x7F, 0xFC, 0x90, 0x84, 0x84, 0x12, 0x20,
+0xCE, 0x90, 0x84, 0x84, 0x91, 0xC5, 0x7F, 0x7C,
+0xD1, 0x2D, 0x12, 0x20, 0xDA, 0xCC, 0xC0, 0x00,
+0xC0, 0x7F, 0x8C, 0xD1, 0x2D, 0x12, 0x20, 0xDA,
+0x00, 0xC0, 0x00, 0x14, 0xD1, 0xC4, 0x12, 0x20,
+0xDA, 0x00, 0x03, 0x3E, 0x60, 0xE4, 0xFD, 0xFF,
+0xD1, 0x8F, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xC0, 0x07,
+0xC0, 0x05, 0x90, 0x84, 0x67, 0x12, 0x42, 0x38,
+0x90, 0x84, 0x55, 0x12, 0x20, 0xCE, 0xD0, 0x05,
+0xD0, 0x07, 0xB1, 0xD6, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x7F, 0x7C, 0x7E, 0x08, 0x12, 0x2D, 0x5C,
+0xEC, 0x22, 0x12, 0x20, 0xBB, 0xA8, 0x04, 0xA9,
+0x05, 0xAA, 0x06, 0x22, 0x7F, 0x70, 0x7E, 0x0E,
+0x12, 0x2E, 0xA2, 0x90, 0x84, 0x67, 0x22, 0x7B,
+0x2F, 0xD1, 0xF7, 0x91, 0x1A, 0x7D, 0x08, 0x7F,
+0x01, 0x02, 0x4E, 0x86, 0x7B, 0x2D, 0xD1, 0xF7,
+0x12, 0x67, 0x1A, 0x90, 0x01, 0x37, 0x74, 0x02,
+0xF0, 0xFD, 0x7F, 0x03, 0xF1, 0x08, 0x91, 0x1A,
+0xE4, 0xFD, 0x7F, 0x01, 0x02, 0x4E, 0x86, 0x7D,
+0xFF, 0x7F, 0xFF, 0x02, 0x4E, 0x3D, 0x7D, 0x01,
+0x7F, 0x02, 0xF1, 0x08, 0x7D, 0x02, 0x7F, 0x02,
+0x74, 0x3D, 0x2F, 0xF8, 0xE6, 0x4D, 0xFE, 0xF6,
+0x74, 0x30, 0xF1, 0xCA, 0xEE, 0xF0, 0x22, 0x90,
+0x81, 0x05, 0xE0, 0x54, 0xFB, 0xF0, 0xE4, 0x90,
+0x81, 0x13, 0xF0, 0xA3, 0xF0, 0x90, 0x81, 0x0E,
+0xF0, 0x90, 0x81, 0x06, 0xE0, 0x54, 0xF7, 0xF0,
+0x54, 0xBF, 0xF0, 0xD1, 0xFE, 0x7D, 0x10, 0x7F,
+0x03, 0x74, 0x45, 0xF1, 0xD3, 0xF1, 0xC6, 0xEE,
+0xF0, 0x22, 0x90, 0x01, 0x36, 0x74, 0x78, 0xF0,
+0xA3, 0x74, 0x02, 0xF0, 0x7D, 0x78, 0xFF, 0xF1,
+0x08, 0x7D, 0x02, 0x7F, 0x03, 0xF1, 0x08, 0x90,
+0x06, 0x0A, 0xE0, 0x44, 0x07, 0x12, 0x76, 0x9A,
+0xE4, 0xFF, 0x12, 0x4F, 0xB8, 0xBF, 0x01, 0x10,
+0xF1, 0xE8, 0x90, 0x81, 0x0D, 0xE0, 0x20, 0xE2,
+0x0A, 0x7D, 0x01, 0x7F, 0x04, 0x02, 0x4C, 0x49,
+0x12, 0x77, 0x1A, 0x22, 0xEF, 0x70, 0x34, 0x7D,
+0x78, 0x7F, 0x02, 0xF1, 0xB9, 0x7D, 0x02, 0x7F,
+0x03, 0xF1, 0xB9, 0x7D, 0xC8, 0x7F, 0x02, 0xF1,
+0x39, 0x12, 0x73, 0x8F, 0x12, 0x4F, 0xA7, 0x70,
+0x0D, 0xD1, 0x36, 0x12, 0x4F, 0xAE, 0x12, 0x7B,
+0xC2, 0x54, 0x7F, 0xF0, 0x80, 0x07, 0x7D, 0x01,
+0x7F, 0x0C, 0x12, 0x4C, 0x49, 0x12, 0x70, 0xC5,
+0x02, 0x7F, 0xC1, 0x80, 0x8D, 0x7D, 0x02, 0x7F,
+0x02, 0x74, 0x3D, 0xF1, 0xD3, 0xFE, 0xF6, 0x74,
+0x30, 0xF1, 0xCA, 0xEE, 0xF0, 0x22, 0xFE, 0xF6,
+0x74, 0x38, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x01,
+0xF5, 0x83, 0x22, 0x2F, 0xF8, 0xE6, 0xFE, 0xED,
+0xF4, 0x5E, 0x22, 0x7D, 0x01, 0x7F, 0x02, 0x80,
+0xD8, 0x7F, 0x32, 0x7E, 0x00, 0x02, 0x32, 0xAA,
+0x90, 0x81, 0x06, 0xE0, 0x54, 0xFB, 0xF0, 0x22,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x91,
+0xCE, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x84,
+0x9A, 0xEF, 0xF0, 0x7F, 0x02, 0x12, 0x46, 0x91,
+0x90, 0x80, 0x01, 0xE0, 0xFF, 0x90, 0x84, 0x9A,
+0xE0, 0xFE, 0xEF, 0x4E, 0x90, 0x80, 0x01, 0xF0,
+0x22, 0x90, 0x02, 0x09, 0xE0, 0xF5, 0x52, 0x12,
+0x1F, 0xA4, 0x25, 0x52, 0x90, 0x80, 0x09, 0x12,
+0x56, 0x7A, 0x25, 0x52, 0x90, 0x80, 0x0A, 0x12,
+0x57, 0x74, 0x25, 0x52, 0x90, 0x80, 0x0B, 0x12,
+0x57, 0xC1, 0x25, 0x52, 0x90, 0x80, 0x0C, 0x12,
+0x55, 0x81, 0x25, 0x52, 0x90, 0x80, 0x0D, 0x12,
+0x57, 0xB9, 0x25, 0x52, 0x90, 0x80, 0x0E, 0xF0,
+0x90, 0x00, 0x06, 0x12, 0x1F, 0xBD, 0x25, 0x52,
+0x90, 0x80, 0x0F, 0xF0, 0x22, 0x8B, 0x52, 0x8A,
+0x53, 0x89, 0x54, 0x12, 0x56, 0x7B, 0xFF, 0xF5,
+0x56, 0x12, 0x1F, 0xA4, 0xFE, 0xC3, 0x13, 0x30,
+0xE0, 0x07, 0x12, 0x57, 0x75, 0xF5, 0x57, 0x80,
+0x02, 0x8F, 0x57, 0x85, 0x56, 0x55, 0xE5, 0x55,
+0xD3, 0x95, 0x57, 0x50, 0x25, 0xAB, 0x52, 0xAA,
+0x53, 0xA9, 0x54, 0x12, 0x1F, 0xA4, 0x54, 0x01,
+0xFD, 0xAF, 0x55, 0x12, 0x60, 0x9E, 0xAF, 0x55,
+0x12, 0x4F, 0xB8, 0xEF, 0xAF, 0x55, 0x70, 0x04,
+0x91, 0x44, 0x80, 0x02, 0x11, 0xC4, 0x05, 0x55,
+0x80, 0xD4, 0xE5, 0x56, 0x70, 0x15, 0xFF, 0x12,
+0x4F, 0xB8, 0xEF, 0x70, 0x0E, 0x12, 0x6E, 0x36,
+0x12, 0x4F, 0xAE, 0x11, 0xC5, 0x54, 0xBF, 0xF0,
+0x54, 0x7F, 0xF0, 0x22, 0x22, 0x90, 0x81, 0x05,
+0xE0, 0x54, 0xF7, 0xF0, 0x22, 0x90, 0x81, 0x0A,
+0xE0, 0x60, 0x0D, 0x90, 0x06, 0x92, 0xE0, 0x30,
+0xE1, 0x02, 0x80, 0x05, 0x11, 0xC5, 0x51, 0x2E,
+0x22, 0xF1, 0x32, 0x54, 0x1F, 0x30, 0xE0, 0x05,
+0x90, 0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x06, 0x92,
+0x74, 0x02, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x04,
+0xF0, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0x69, 0xE0,
+0xC3, 0x13, 0x54, 0x7F, 0xF5, 0x1E, 0xE4, 0xFB,
+0xFD, 0x7F, 0x58, 0x7E, 0x01, 0x12, 0x4A, 0x7B,
+0x90, 0x81, 0x05, 0xE0, 0x44, 0x08, 0xF0, 0x22,
+0x11, 0xE1, 0x90, 0x81, 0x0D, 0xE0, 0x64, 0x0C,
+0x60, 0x08, 0x31, 0x61, 0x12, 0x4E, 0x38, 0x12,
+0x66, 0x67, 0x22, 0xE4, 0xFF, 0x12, 0x4F, 0xB8,
+0xBF, 0x01, 0x10, 0x90, 0x81, 0x0A, 0xE0, 0x60,
+0x0A, 0x31, 0x69, 0x64, 0x02, 0x60, 0x02, 0x41,
+0x4F, 0x31, 0x18, 0x22, 0x90, 0x81, 0x0A, 0xE0,
+0x64, 0x01, 0x70, 0x14, 0x31, 0x69, 0x60, 0x07,
+0x31, 0x61, 0x12, 0x4E, 0x38, 0x80, 0x8A, 0x90,
+0x81, 0x0D, 0xE0, 0x70, 0x03, 0x12, 0x4C, 0x45,
+0x22, 0xE4, 0xFD, 0x7F, 0x0C, 0x02, 0x4C, 0x49,
+0xF0, 0x90, 0x81, 0x08, 0xE0, 0x54, 0x0F, 0x22,
+0x90, 0x06, 0xA9, 0xE0, 0xF5, 0x4E, 0x54, 0xC0,
+0x70, 0x07, 0x31, 0xBF, 0x54, 0xFD, 0xF0, 0x41,
+0x2E, 0xE5, 0x4E, 0x30, 0xE6, 0x1C, 0x90, 0x81,
+0x0A, 0xE0, 0x64, 0x01, 0x70, 0x16, 0x90, 0x81,
+0x0E, 0xE0, 0x44, 0x01, 0x31, 0x68, 0x64, 0x02,
+0x60, 0x04, 0x51, 0x4F, 0x80, 0x06, 0x31, 0x18,
+0x80, 0x02, 0x31, 0xBF, 0xE5, 0x4E, 0x90, 0x81,
+0x0E, 0x30, 0xE7, 0x0E, 0xE0, 0x44, 0x02, 0x12,
+0x4A, 0x6A, 0x90, 0x81, 0x05, 0xE0, 0x44, 0x04,
+0xF0, 0x22, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90,
+0x81, 0x0E, 0xE0, 0x54, 0xFE, 0xF0, 0x22, 0x71,
+0x7C, 0x54, 0x1F, 0x30, 0xE0, 0x0C, 0xEF, 0xC4,
+0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, 0x03, 0x12,
+0x6F, 0xB5, 0x90, 0x81, 0x05, 0x71, 0x88, 0x30,
+0xE0, 0x0A, 0xEF, 0x51, 0x98, 0xF0, 0x54, 0x07,
+0x70, 0x43, 0x80, 0x3F, 0x90, 0x81, 0x13, 0xE0,
+0x04, 0xF0, 0x90, 0x81, 0x0E, 0xE0, 0x54, 0xEF,
+0xF0, 0xD1, 0xA5, 0x40, 0x2E, 0x12, 0x4F, 0xA8,
+0x64, 0x01, 0x70, 0x29, 0xB1, 0x87, 0x31, 0x69,
+0x70, 0x03, 0x02, 0x6F, 0xE8, 0x90, 0x81, 0x14,
+0xE0, 0x04, 0xF0, 0xE0, 0xD3, 0x94, 0x02, 0x40,
+0x0A, 0x12, 0x6F, 0xE8, 0xE4, 0x90, 0x81, 0x14,
+0xF0, 0x80, 0x02, 0x31, 0x18, 0xE4, 0x90, 0x81,
+0x13, 0xF0, 0x22, 0x51, 0x2E, 0x22, 0x90, 0x81,
+0x0C, 0xE0, 0xFF, 0x7D, 0x01, 0x02, 0x4C, 0x49,
+0xE4, 0xFF, 0x12, 0x4F, 0xB8, 0xBF, 0x01, 0x0E,
+0x90, 0x81, 0x0A, 0xE0, 0x60, 0x08, 0x31, 0xBF,
+0x54, 0x07, 0x70, 0x02, 0x51, 0x2E, 0x22, 0x90,
+0x04, 0x1D, 0xE0, 0x70, 0x1D, 0x90, 0x80, 0x0A,
+0xE0, 0xFF, 0x90, 0x84, 0x83, 0x74, 0x09, 0xF0,
+0x7B, 0x18, 0xE4, 0xFD, 0x12, 0x65, 0x3A, 0x90,
+0x83, 0xD8, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x12,
+0x67, 0xB3, 0x22, 0x12, 0x4F, 0xA8, 0x64, 0x01,
+0x70, 0x1D, 0x90, 0x81, 0x0A, 0xE0, 0x60, 0x17,
+0x90, 0x81, 0x0E, 0xE0, 0x20, 0xE4, 0x10, 0x71,
+0x8F, 0xF0, 0x90, 0x81, 0x05, 0xE0, 0x51, 0x98,
+0xF0, 0x54, 0x07, 0x70, 0x02, 0x51, 0x2E, 0x22,
+0x54, 0xFB, 0xF0, 0x90, 0x81, 0x0E, 0xE0, 0x54,
+0xFD, 0x22, 0x90, 0x05, 0x62, 0xE0, 0xFE, 0x90,
+0x05, 0x61, 0xE0, 0xFD, 0xED, 0x78, 0x02, 0xCE,
+0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x90,
+0x83, 0xD6, 0xEE, 0xF0, 0xA3, 0xEF, 0x12, 0x4F,
+0xA7, 0x64, 0x01, 0x60, 0x02, 0x61, 0x68, 0x90,
+0x81, 0x0A, 0xE0, 0x70, 0x02, 0x61, 0x68, 0xF1,
+0x3A, 0x64, 0x01, 0x70, 0x22, 0x90, 0x06, 0xAB,
+0xE0, 0x90, 0x81, 0x11, 0xF0, 0x90, 0x06, 0xAA,
+0xE0, 0x90, 0x81, 0x10, 0xF0, 0xA3, 0xE0, 0xFF,
+0x70, 0x08, 0x90, 0x81, 0x10, 0xE0, 0xFE, 0xFF,
+0x80, 0x00, 0x90, 0x81, 0x11, 0xEF, 0xF0, 0x12,
+0x4A, 0xE0, 0xE4, 0x90, 0x81, 0x13, 0xF0, 0xA3,
+0xD1, 0x9A, 0x71, 0x8F, 0x51, 0x9A, 0xF0, 0x54,
+0xEF, 0xF0, 0x31, 0x70, 0x71, 0x7C, 0x54, 0x1F,
+0x30, 0xE0, 0x53, 0xEF, 0xC4, 0x13, 0x13, 0x54,
+0x03, 0x20, 0xE0, 0x20, 0x71, 0x69, 0x6F, 0x70,
+0x45, 0x90, 0x81, 0x06, 0xE0, 0x44, 0x40, 0xF0,
+0xF1, 0x22, 0x71, 0x71, 0xF1, 0x56, 0x12, 0x6F,
+0xDB, 0x12, 0x6F, 0xB5, 0x90, 0x81, 0x11, 0xE0,
+0x14, 0xF0, 0x80, 0x2A, 0x90, 0x81, 0x08, 0xE0,
+0xC4, 0x54, 0x0F, 0x64, 0x01, 0x70, 0x1F, 0x71,
+0x69, 0xFE, 0x6F, 0x60, 0x19, 0x90, 0x05, 0x73,
+0xE0, 0xFF, 0xEE, 0x6F, 0x60, 0x10, 0x71, 0x85,
+0x30, 0xE0, 0x0B, 0xEF, 0x54, 0xBF, 0x71, 0x71,
+0x12, 0x6F, 0x39, 0x12, 0x6E, 0xFE, 0xF1, 0x1A,
+0x22, 0x90, 0x81, 0x10, 0xE0, 0xFF, 0xA3, 0xE0,
+0x22, 0xF0, 0x90, 0x01, 0x3F, 0x74, 0x10, 0xF0,
+0xFD, 0x7F, 0x03, 0x22, 0x90, 0x81, 0x06, 0xE0,
+0xFF, 0x13, 0x13, 0x13, 0x22, 0x90, 0x81, 0x06,
+0xE0, 0xFF, 0x13, 0x13, 0x54, 0x3F, 0x22, 0x90,
+0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74,
+0x02, 0x22, 0x90, 0x81, 0x05, 0xF1, 0x2A, 0x30,
+0xE0, 0x19, 0xEF, 0x54, 0xBF, 0x91, 0xC2, 0x30,
+0xE0, 0x06, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x09,
+0xE0, 0x54, 0xFE, 0xF0, 0x91, 0xCB, 0x74, 0x04,
+0xF0, 0x51, 0x2E, 0xE4, 0xFF, 0x90, 0x83, 0xC8,
+0xE0, 0xFD, 0x30, 0xE0, 0x49, 0x90, 0x83, 0xCD,
+0xE0, 0xFC, 0x60, 0x42, 0xF1, 0x4E, 0x80, 0x05,
+0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF,
+0x90, 0x04, 0xE0, 0xE0, 0xFB, 0xEF, 0x5B, 0x60,
+0x0B, 0xE4, 0x90, 0x83, 0xCD, 0xF0, 0x90, 0x83,
+0xCF, 0x04, 0xF0, 0x22, 0x90, 0x83, 0xCA, 0xE0,
+0xD3, 0x9C, 0x50, 0x18, 0xED, 0x13, 0x13, 0x13,
+0x54, 0x1F, 0x30, 0xE0, 0x04, 0x91, 0x3C, 0x80,
+0x03, 0x12, 0x5E, 0xEF, 0x90, 0x83, 0xC8, 0xE0,
+0x54, 0xFE, 0xF0, 0x22, 0xB1, 0x48, 0x22, 0x90,
+0x81, 0x05, 0xE0, 0xFF, 0x12, 0x5F, 0x49, 0x30,
+0xE0, 0x1E, 0xEF, 0x54, 0x7F, 0x91, 0xC2, 0x30,
+0xE1, 0x06, 0xE0, 0x44, 0x02, 0xF0, 0x80, 0x08,
+0xE0, 0x54, 0xFD, 0xF0, 0x91, 0xCB, 0x04, 0xF0,
+0x90, 0x81, 0x0A, 0xE0, 0x60, 0x02, 0x51, 0x2E,
+0x7F, 0x01, 0x80, 0x81, 0xE4, 0xFD, 0xFF, 0x12,
+0x60, 0x9E, 0xE4, 0xFF, 0x22, 0x90, 0x83, 0xC8,
+0xE0, 0x30, 0xE0, 0x75, 0x90, 0x83, 0xCC, 0xE0,
+0x04, 0xF0, 0x90, 0x83, 0xCF, 0xE0, 0x64, 0x01,
+0x70, 0x34, 0x90, 0x83, 0xC8, 0x71, 0x88, 0x30,
+0xE0, 0x2C, 0x90, 0x83, 0xCE, 0xE0, 0x70, 0x26,
+0x90, 0x83, 0xCB, 0xE0, 0xFE, 0xA3, 0xE0, 0xC3,
+0x9E, 0x40, 0x1B, 0xF1, 0x0B, 0x30, 0xE0, 0x0B,
+0x91, 0x3C, 0x90, 0x83, 0xC8, 0xE0, 0x54, 0xFE,
+0xF0, 0x80, 0x0B, 0x12, 0x5E, 0xEF, 0x90, 0x83,
+0xC8, 0xE0, 0x54, 0xFE, 0xF0, 0x22, 0x90, 0x83,
+0xCC, 0xE0, 0xFF, 0x90, 0x83, 0xC9, 0xE0, 0xD3,
+0x9F, 0x50, 0x26, 0x90, 0x06, 0x92, 0xE0, 0x20,
+0xE2, 0x10, 0x90, 0x83, 0xCE, 0xE0, 0x70, 0x0A,
+0xB1, 0x48, 0x90, 0x83, 0xC7, 0xE0, 0x04, 0xF0,
+0x80, 0x06, 0x90, 0x06, 0x92, 0x74, 0x04, 0xF0,
+0xE4, 0x90, 0x83, 0xCC, 0xF0, 0x90, 0x83, 0xCE,
+0xF0, 0x22, 0xF0, 0x90, 0x04, 0xE0, 0xE0, 0x90,
+0x81, 0x06, 0x22, 0x90, 0x01, 0xB9, 0x74, 0x01,
+0xF0, 0x90, 0x01, 0xB8, 0x22, 0x12, 0x67, 0xEA,
+0x12, 0x1F, 0xA4, 0xFF, 0x54, 0x7F, 0x90, 0x81,
+0x0A, 0xF0, 0xEF, 0x12, 0x5F, 0x49, 0xA3, 0x12,
+0x56, 0x7A, 0xFD, 0x54, 0xF0, 0xC4, 0x54, 0x0F,
+0xFF, 0x90, 0x81, 0x08, 0xE0, 0x54, 0xF0, 0x4F,
+0x12, 0x57, 0xC1, 0xFC, 0x54, 0x01, 0x25, 0xE0,
+0xFF, 0x90, 0x81, 0x05, 0xE0, 0x54, 0xFD, 0x4F,
+0xF0, 0xEC, 0x54, 0x04, 0xC3, 0x13, 0xFF, 0x90,
+0x81, 0x07, 0xE0, 0x54, 0xFD, 0x4F, 0xF0, 0xED,
+0x54, 0x0F, 0xC4, 0x54, 0xF0, 0xFF, 0xA3, 0xE0,
+0x54, 0x0F, 0x12, 0x57, 0x73, 0x90, 0x81, 0x09,
+0x12, 0x55, 0x81, 0xFD, 0x7F, 0x02, 0x12, 0x4E,
+0x86, 0x90, 0x83, 0xEF, 0x12, 0x42, 0x5C, 0xB1,
+0x56, 0x91, 0xCB, 0xF0, 0x90, 0x81, 0x0A, 0xF1,
+0x62, 0x31, 0x68, 0x90, 0x01, 0xBE, 0xF0, 0x22,
+0x7D, 0x08, 0x7F, 0x02, 0x12, 0x66, 0x6B, 0x90,
+0x83, 0xCD, 0xE0, 0x04, 0xF0, 0x22, 0x90, 0x83,
+0xF2, 0x12, 0x42, 0x65, 0x12, 0x6F, 0x17, 0x90,
+0x81, 0x0A, 0xE0, 0xFF, 0x12, 0x6F, 0x7C, 0x90,
+0x81, 0x0A, 0xE0, 0x60, 0x19, 0x90, 0x83, 0xF2,
+0x12, 0x42, 0x5C, 0x12, 0x56, 0x7B, 0x54, 0x0F,
+0xFF, 0x12, 0x57, 0x75, 0xFD, 0xF1, 0x80, 0xD1,
+0xFA, 0x74, 0x01, 0xF0, 0xB1, 0xBF, 0x22, 0xD1,
+0xA5, 0x40, 0x33, 0x90, 0x81, 0x24, 0xE0, 0x04,
+0xF0, 0x90, 0x81, 0x66, 0xE0, 0xFF, 0x90, 0x81,
+0x24, 0xE0, 0xD3, 0x9F, 0x50, 0x20, 0x90, 0x81,
+0x1C, 0xE0, 0x04, 0xF0, 0xD1, 0x8F, 0x12, 0x4A,
+0x63, 0x90, 0x81, 0x23, 0xF0, 0xFB, 0x90, 0x81,
+0x1C, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0x90, 0x84,
+0x8B, 0x74, 0x04, 0xF0, 0xB1, 0xBF, 0x22, 0xD3,
+0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xAC, 0x07,
+0x90, 0x81, 0x06, 0x12, 0x5F, 0x48, 0x30, 0xE0,
+0x02, 0xC1, 0x78, 0x90, 0x81, 0x05, 0xE0, 0x30,
+0xE0, 0x16, 0x90, 0x81, 0x27, 0xE0, 0x24, 0x04,
+0x90, 0x81, 0x1F, 0xF0, 0x90, 0x81, 0x27, 0xE0,
+0x24, 0x03, 0x90, 0x81, 0x1E, 0xF0, 0x80, 0x0D,
+0x90, 0x81, 0x1F, 0x74, 0x02, 0xF0, 0x90, 0x81,
+0x1E, 0x14, 0xF0, 0x0B, 0x0B, 0x90, 0x81, 0x1E,
+0xE0, 0xFA, 0x90, 0x81, 0x1D, 0xE0, 0xD3, 0x9A,
+0x50, 0x0E, 0x90, 0x81, 0x12, 0xEB, 0xF0, 0x90,
+0x81, 0x1F, 0xE0, 0xC3, 0x9D, 0x2C, 0x80, 0x11,
+0xC3, 0xED, 0x9A, 0x2B, 0x90, 0x81, 0x12, 0xF0,
+0x90, 0x81, 0x1E, 0xE0, 0xFF, 0xA3, 0xE0, 0xC3,
+0x9F, 0x90, 0x81, 0x22, 0xF0, 0x90, 0x81, 0x1F,
+0xE0, 0xFF, 0x24, 0x0A, 0xFD, 0xE4, 0x33, 0xFC,
+0x90, 0x81, 0x22, 0xD1, 0x84, 0x40, 0x04, 0xEF,
+0x24, 0x0A, 0xF0, 0x90, 0x81, 0x22, 0xE0, 0xFF,
+0x24, 0x23, 0xFD, 0xE4, 0x33, 0xFC, 0x90, 0x81,
+0x12, 0xD1, 0x84, 0x40, 0x04, 0xEF, 0x24, 0x23,
+0xF0, 0x90, 0x81, 0x22, 0xE0, 0xFF, 0x7E, 0x00,
+0x90, 0x81, 0x16, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0,
+0x90, 0x05, 0x58, 0xE0, 0x6F, 0x70, 0x01, 0xE4,
+0x60, 0x02, 0xD1, 0x9B, 0xF1, 0x12, 0x80, 0x07,
+0x90, 0x81, 0x07, 0xE0, 0x44, 0x01, 0xF0, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0xE0, 0xD3, 0x9D, 0xEC,
+0x64, 0x80, 0xF8, 0x74, 0x80, 0x98, 0x22, 0x90,
+0x81, 0x13, 0xE0, 0x75, 0xF0, 0x03, 0xA4, 0x24,
+0xFE, 0x22, 0xF0, 0x90, 0x81, 0x16, 0xA3, 0xE0,
+0x90, 0x05, 0x58, 0xF0, 0x22, 0x90, 0x81, 0x67,
+0xE0, 0xFF, 0x90, 0x81, 0x13, 0xE0, 0xD3, 0x9F,
+0x22, 0x12, 0x79, 0xB8, 0x90, 0x83, 0xDD, 0xEF,
+0xF0, 0x30, 0xE0, 0x05, 0x7D, 0x01, 0xE4, 0x80,
+0x02, 0xE4, 0xFD, 0xFF, 0x12, 0x4E, 0x86, 0x90,
+0x83, 0xDD, 0xE0, 0x30, 0xE6, 0x11, 0x90, 0x01,
+0x2F, 0xE0, 0x30, 0xE7, 0x04, 0xE4, 0xF0, 0x80,
+0x06, 0x90, 0x01, 0x2F, 0x74, 0x80, 0xF0, 0x90,
+0x81, 0x05, 0xE0, 0x90, 0x04, 0xEC, 0x30, 0xE0,
+0x06, 0xE0, 0x54, 0xDD, 0xF0, 0x80, 0x04, 0xE0,
+0x44, 0x22, 0xF0, 0xD1, 0xFA, 0x74, 0x02, 0xF0,
+0xA1, 0xBF, 0x90, 0x81, 0x1C, 0xE0, 0xFF, 0xA3,
+0xE0, 0xFD, 0x90, 0x81, 0x23, 0xE0, 0xFB, 0x90,
+0x84, 0x8B, 0x22, 0xEF, 0x13, 0x13, 0x13, 0x54,
+0x1F, 0x22, 0x90, 0x81, 0x07, 0xE0, 0x54, 0xFE,
+0xF0, 0x22, 0x90, 0x81, 0x06, 0xE0, 0x44, 0x04,
+0xF0, 0x22, 0x90, 0x81, 0x10, 0xE0, 0x90, 0x05,
+0x73, 0x22, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x54,
+0x03, 0x22, 0x90, 0x81, 0x05, 0xE0, 0x13, 0x13,
+0x13, 0x22, 0x90, 0x81, 0x08, 0xE0, 0xFF, 0xC4,
+0x54, 0x0F, 0x22, 0x90, 0x81, 0x0A, 0xE0, 0x60,
+0x02, 0x31, 0x44, 0x22, 0xE0, 0xFF, 0x74, 0x01,
+0x7E, 0x00, 0xA8, 0x07, 0x08, 0x22, 0x74, 0x45,
+0x2F, 0xF8, 0xE6, 0x4D, 0x12, 0x6F, 0xC6, 0xEE,
+0xF0, 0x22, 0xE0, 0x90, 0x01, 0xBA, 0xF0, 0x90,
+0x81, 0x0C, 0xE0, 0x90, 0x01, 0xBB, 0x22, 0x90,
+0x83, 0xCE, 0xE0, 0x04, 0xF0, 0x90, 0x81, 0x0D,
+0xE0, 0x64, 0x02, 0x60, 0x02, 0x51, 0xA2, 0x22,
+0xEF, 0x24, 0xFE, 0x60, 0x0B, 0x04, 0x70, 0x24,
+0x90, 0x81, 0x10, 0x74, 0x02, 0xF0, 0x80, 0x13,
+0xED, 0x70, 0x06, 0x90, 0x81, 0x6A, 0xE0, 0x80,
+0x02, 0xED, 0x14, 0x90, 0x81, 0x10, 0xF0, 0x90,
+0x81, 0x10, 0xE0, 0xA3, 0xF0, 0x90, 0x81, 0x06,
+0xE0, 0x44, 0x08, 0xF0, 0x22, 0xEF, 0x60, 0x37,
+0x12, 0x4F, 0xA8, 0x64, 0x01, 0x70, 0x30, 0x90,
+0x81, 0x06, 0xE0, 0x54, 0xFE, 0xF0, 0x7B, 0x2B,
+0x7D, 0x0F, 0x7F, 0xFF, 0x12, 0x4E, 0x3D, 0x90,
+0x06, 0x04, 0xE0, 0x54, 0xBF, 0xF0, 0x12, 0x66,
+0x67, 0xBF, 0x01, 0x0E, 0x90, 0x81, 0x05, 0xE0,
+0x44, 0x40, 0xF0, 0x7D, 0x06, 0x7F, 0x01, 0x02,
+0x4E, 0x86, 0x91, 0xCB, 0x74, 0x08, 0xF0, 0x22,
+0x12, 0x1F, 0xA4, 0x54, 0x01, 0xFF, 0x90, 0x83,
+0xD5, 0xE0, 0x54, 0xFE, 0x4F, 0xF0, 0x22, 0x12,
+0x1F, 0xA4, 0x90, 0x81, 0x6D, 0xF0, 0x22, 0xE4,
+0x90, 0x80, 0xF8, 0xF0, 0xA3, 0xF0, 0x90, 0x80,
+0x60, 0xF0, 0xA3, 0xF0, 0x22, 0x75, 0x3D, 0x10,
+0xE4, 0xF5, 0x3E, 0x75, 0x3F, 0x07, 0x75, 0x40,
+0x02, 0x90, 0x01, 0x30, 0xE5, 0x3D, 0xF0, 0xA3,
+0xE5, 0x3E, 0xF0, 0xA3, 0xE5, 0x3F, 0xF0, 0xA3,
+0xE5, 0x40, 0xF0, 0x22, 0x75, 0x45, 0x07, 0x75,
+0x46, 0x01, 0x75, 0x47, 0x03, 0x75, 0x48, 0x62,
+0x90, 0x01, 0x38, 0xE5, 0x45, 0xF0, 0xA3, 0xE5,
+0x46, 0xF0, 0xA3, 0xE5, 0x47, 0xF0, 0xA3, 0xE5,
+0x48, 0xF0, 0x22, 0x90, 0x01, 0x94, 0xE0, 0x44,
+0x01, 0xF0, 0x90, 0x01, 0xC7, 0xE4, 0xF0, 0x22,
+0x90, 0x01, 0xC7, 0x74, 0xFE, 0xF0, 0x22, 0x7F,
+0x02, 0x90, 0x83, 0xC3, 0xE0, 0xFE, 0xEF, 0xC3,
+0x9E, 0x50, 0x18, 0xEF, 0x25, 0xE0, 0x24, 0x81,
+0xF8, 0xE6, 0x30, 0xE4, 0x0B, 0x90, 0x01, 0xB8,
+0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x7F, 0x00, 0x22,
+0x0F, 0x80, 0xDE, 0x7F, 0x01, 0x22, 0xE4, 0x90,
+0x80, 0x01, 0x12, 0x58, 0x98, 0xA3, 0xF0, 0x22,
+0x90, 0x01, 0xE4, 0x74, 0x1C, 0xF0, 0xA3, 0xE4,
+0xF0, 0x22, 0x90, 0x00, 0x54, 0xE0, 0x55, 0x35,
+0xF5, 0x39, 0xA3, 0xE0, 0x55, 0x36, 0xF5, 0x3A,
+0xA3, 0xE0, 0x55, 0x37, 0xF5, 0x3B, 0xA3, 0xE0,
+0x55, 0x38, 0xF5, 0x3C, 0xAD, 0x39, 0x7F, 0x54,
+0x12, 0x32, 0x1E, 0xAD, 0x3A, 0x7F, 0x55, 0x12,
+0x32, 0x1E, 0xAD, 0x3B, 0x7F, 0x56, 0x12, 0x32,
+0x1E, 0xAD, 0x3C, 0x7F, 0x57, 0x12, 0x32, 0x1E,
+0x53, 0x91, 0xEF, 0x22, 0x90, 0x01, 0x34, 0xE0,
+0x55, 0x3D, 0xF5, 0x41, 0xA3, 0xE0, 0x55, 0x3E,
+0xF5, 0x42, 0xA3, 0xE0, 0x55, 0x3F, 0xF5, 0x43,
+0xA3, 0xE0, 0x55, 0x40, 0xF5, 0x44, 0x90, 0x01,
+0x34, 0xE5, 0x41, 0xF0, 0xA3, 0xE5, 0x42, 0xF0,
+0xA3, 0xE5, 0x43, 0xF0, 0xA3, 0xE5, 0x44, 0xF0,
+0x22, 0x90, 0x01, 0x3C, 0xE0, 0x55, 0x45, 0xF5,
+0x49, 0xA3, 0xE0, 0x55, 0x46, 0xF5, 0x4A, 0xA3,
+0xE0, 0x55, 0x47, 0xF5, 0x4B, 0xA3, 0xE0, 0x55,
+0x48, 0xF5, 0x4C, 0x90, 0x01, 0x3C, 0xE5, 0x49,
+0xF0, 0xA3, 0xE5, 0x4A, 0xF0, 0xA3, 0xE5, 0x4B,
+0xF0, 0xA3, 0xE5, 0x4C, 0xF0, 0x53, 0x91, 0xDF,
+0x22, 0x90, 0x81, 0x6E, 0xE0, 0x30, 0xE0, 0x05,
+0x7F, 0x10, 0x12, 0x50, 0xCF, 0x22, 0x90, 0x01,
+0xCF, 0xE0, 0x90, 0x84, 0x9D, 0xF0, 0xE0, 0xFF,
+0x30, 0xE0, 0x07, 0x90, 0x01, 0xCF, 0xE0, 0x54,
+0xFE, 0xF0, 0xEF, 0x30, 0xE5, 0x23, 0x90, 0x01,
+0xCF, 0xE0, 0x54, 0xDF, 0xF0, 0x90, 0x01, 0x34,
+0x74, 0x20, 0xF0, 0xE4, 0xF5, 0xA8, 0xF5, 0xE8,
+0x12, 0x58, 0x72, 0x90, 0x00, 0x03, 0xE0, 0x54,
+0xFB, 0xFD, 0x7F, 0x03, 0x12, 0x32, 0x1E, 0x80,
+0xFE, 0x22, 0x12, 0x49, 0xBD, 0xE4, 0xFF, 0x02,
+0x50, 0x9B, 0xC3, 0xEE, 0x94, 0x01, 0x40, 0x0A,
+0x0D, 0xED, 0x13, 0x90, 0xFD, 0x10, 0xF0, 0xE4,
+0x2F, 0xFF, 0x22, 0xC3, 0xEE, 0x94, 0x01, 0x40,
+0x1E, 0x90, 0xFD, 0x11, 0xE0, 0xB5, 0x05, 0x14,
+0x90, 0x01, 0x17, 0xE0, 0xB5, 0x05, 0x07, 0x90,
+0xFD, 0x11, 0xE4, 0xF0, 0x80, 0x06, 0xED, 0x04,
+0x90, 0xFD, 0x11, 0xF0, 0xE4, 0x2F, 0xFF, 0x22,
+0xE4, 0x90, 0x83, 0xDF, 0xF0, 0xA3, 0xF0, 0x90,
+0x00, 0x83, 0xE0, 0x90, 0x83, 0xDE, 0xF0, 0x90,
+0x00, 0x83, 0xE0, 0xFE, 0x90, 0x83, 0xDE, 0xE0,
+0xFF, 0xB5, 0x06, 0x01, 0x22, 0xC3, 0x90, 0x83,
+0xE0, 0xE0, 0x94, 0x64, 0x90, 0x83, 0xDF, 0xE0,
+0x94, 0x00, 0x40, 0x0D, 0x90, 0x01, 0xC0, 0xE0,
+0x44, 0x40, 0xF0, 0x90, 0x83, 0xDE, 0xE0, 0xFF,
+0x22, 0x90, 0x83, 0xDF, 0x12, 0x69, 0xA3, 0x80,
+0xC6, 0x90, 0x01, 0xC4, 0x74, 0xF9, 0xF0, 0x74,
+0x79, 0xA3, 0xF0, 0x90, 0x00, 0x90, 0xE0, 0x20,
+0xE0, 0xF9, 0x74, 0xF9, 0x04, 0x90, 0x01, 0xC4,
+0xF0, 0x74, 0x79, 0xA3, 0xF0, 0x22, 0xEF, 0x64,
+0x01, 0x70, 0x31, 0x90, 0x81, 0x73, 0xE0, 0xFA,
+0x54, 0x7F, 0xFF, 0x7E, 0x00, 0xC0, 0x07, 0x90,
+0x81, 0x75, 0xE0, 0x13, 0x13, 0x54, 0x01, 0xFD,
+0x90, 0x81, 0x74, 0xE0, 0xF9, 0xC3, 0x13, 0x54,
+0x7F, 0xFB, 0xE9, 0x54, 0x01, 0x90, 0x84, 0x01,
+0xF0, 0xEA, 0x12, 0x5F, 0x49, 0xA3, 0xF0, 0xD0,
+0x07, 0x12, 0x52, 0xBE, 0x22, 0x90, 0x04, 0x1A,
+0xE0, 0xF4, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90,
+0x04, 0x1B, 0xE0, 0x54, 0x07, 0x64, 0x07, 0x7F,
+0x01, 0x60, 0x02, 0x7F, 0x00, 0x22, 0xD3, 0x10,
+0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x51, 0x4D, 0xEF,
+0x64, 0x01, 0x60, 0x05, 0x75, 0x58, 0x01, 0x80,
+0x41, 0x90, 0x81, 0x0E, 0xE0, 0xFF, 0x54, 0x03,
+0x60, 0x05, 0x75, 0x58, 0x02, 0x80, 0x33, 0xEF,
+0x30, 0xE2, 0x05, 0x75, 0x58, 0x08, 0x80, 0x2A,
+0x90, 0x81, 0x0E, 0xE0, 0x30, 0xE4, 0x05, 0x75,
+0x58, 0x10, 0x80, 0x1E, 0x12, 0x73, 0x85, 0x20,
+0xE0, 0x05, 0x75, 0x58, 0x20, 0x80, 0x13, 0x51,
+0xD5, 0x8F, 0x59, 0xE5, 0x59, 0x64, 0x01, 0x60,
+0x05, 0x85, 0x59, 0x58, 0x80, 0x04, 0x51, 0xCD,
+0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74, 0x04, 0xF0,
+0x90, 0x01, 0xB8, 0xE5, 0x58, 0xF0, 0x7F, 0x00,
+0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x01, 0xB8,
+0xE4, 0xF0, 0x7F, 0x01, 0x22, 0x90, 0x81, 0x0C,
+0xE0, 0xD3, 0x94, 0x00, 0x40, 0x06, 0x75, 0x52,
+0x04, 0x7F, 0xFF, 0x22, 0x90, 0x81, 0x6D, 0xE0,
+0x60, 0x06, 0x75, 0x52, 0x80, 0x7F, 0xFF, 0x22,
+0x7F, 0x01, 0x22, 0x7B, 0x2E, 0x51, 0xFE, 0x7D,
+0x02, 0x7F, 0x01, 0x02, 0x4E, 0x86, 0x7D, 0x6F,
+0x7F, 0xFF, 0x02, 0x4E, 0x3D, 0x90, 0x81, 0x61,
+0x74, 0x04, 0xF0, 0xA3, 0x14, 0xF0, 0xA3, 0xE4,
+0xF0, 0xA3, 0x74, 0x64, 0xF0, 0xA3, 0x74, 0x05,
+0xF0, 0xA3, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01,
+0xC3, 0xC0, 0xD0, 0x90, 0x84, 0xA0, 0xEF, 0xF0,
+0x7E, 0x00, 0x7F, 0x2D, 0x7D, 0x00, 0x7B, 0x01,
+0x7A, 0x81, 0x79, 0x28, 0x12, 0x44, 0x3E, 0xE4,
+0x90, 0x81, 0x21, 0xF0, 0x90, 0x81, 0x20, 0xF0,
+0x90, 0x81, 0x24, 0xF0, 0x90, 0x84, 0xA0, 0xE0,
+0xB4, 0x01, 0x09, 0x90, 0x81, 0x25, 0x74, 0x2D,
+0xF0, 0xE4, 0xA3, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
+0x22, 0x12, 0x4E, 0x35, 0x7D, 0x0C, 0x7F, 0x01,
+0x02, 0x4E, 0x86, 0x90, 0x84, 0x77, 0xE0, 0xFF,
+0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
+0x84, 0xA1, 0xEF, 0xF0, 0xC3, 0x94, 0x02, 0x50,
+0x44, 0x90, 0x80, 0x0B, 0xE0, 0xFF, 0x90, 0x04,
+0x1C, 0xE0, 0x6F, 0x70, 0x38, 0x90, 0x81, 0x0D,
+0xE0, 0x64, 0x0E, 0x70, 0x15, 0x90, 0x84, 0xA1,
+0xE0, 0x70, 0x2A, 0x90, 0x81, 0x05, 0xE0, 0x54,
+0x7F, 0xF0, 0x12, 0x4F, 0xFA, 0x12, 0x4E, 0x82,
+0x80, 0x18, 0x90, 0x81, 0x0D, 0xE0, 0x64, 0x06,
+0x70, 0x13, 0x90, 0x84, 0xA1, 0xE0, 0x60, 0x0D,
+0x71, 0xC2, 0x71, 0xCA, 0x90, 0x81, 0x0D, 0x74,
+0x04, 0xF0, 0x12, 0x4E, 0x38, 0xD0, 0xD0, 0x92,
+0xAF, 0x22, 0x90, 0x81, 0x05, 0xE0, 0x54, 0xBF,
+0xF0, 0x22, 0x90, 0x06, 0x04, 0xE0, 0x44, 0x40,
+0xF0, 0xE0, 0x44, 0x80, 0xF0, 0x22, 0x90, 0x83,
+0xC4, 0xE0, 0x30, 0xE0, 0x37, 0x12, 0x4F, 0xA8,
+0x64, 0x01, 0x70, 0x30, 0x90, 0x84, 0xA3, 0xE0,
+0x04, 0xF0, 0xE0, 0xB4, 0x0A, 0x0B, 0x90, 0x83,
+0xC6, 0xE0, 0x04, 0xF0, 0xE4, 0x90, 0x84, 0xA3,
+0xF0, 0x90, 0x83, 0xC6, 0xE0, 0xFF, 0x90, 0x83,
+0xC5, 0xE0, 0xD3, 0x9F, 0x50, 0x0E, 0x90, 0x83,
+0xC7, 0xE0, 0x70, 0x08, 0xE4, 0x90, 0x83, 0xC6,
+0xF0, 0x12, 0x67, 0x97, 0x22, 0x91, 0x40, 0xFE,
+0x90, 0x83, 0xC4, 0xE0, 0x54, 0xFE, 0x4E, 0xFE,
+0xF0, 0xEF, 0x54, 0x04, 0xFF, 0xEE, 0x54, 0xFB,
+0x4F, 0xF0, 0x12, 0x1F, 0xA4, 0xC3, 0x13, 0x30,
+0xE0, 0x07, 0x12, 0x56, 0x7B, 0x90, 0x83, 0xC5,
+0xF0, 0x22, 0x90, 0x83, 0xEF, 0x12, 0x42, 0x5C,
+0x12, 0x1F, 0xA4, 0xFF, 0x54, 0x01, 0x22, 0x12,
+0x67, 0xEA, 0x12, 0x61, 0x53, 0x91, 0x3A, 0xFE,
+0x90, 0x83, 0xC8, 0xE0, 0x54, 0xFE, 0x4E, 0xF0,
+0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x2D, 0x12, 0x56,
+0x7B, 0x90, 0x83, 0xC9, 0x12, 0x57, 0x74, 0x90,
+0x83, 0xCA, 0xF0, 0x12, 0x1F, 0xA4, 0xFF, 0x54,
+0x04, 0xFE, 0x90, 0x83, 0xC8, 0xE0, 0x54, 0xFB,
+0x12, 0x57, 0xC0, 0x90, 0x83, 0xCB, 0xF0, 0xEF,
+0x54, 0x08, 0xFF, 0x90, 0x83, 0xC8, 0xE0, 0x54,
+0xF7, 0x4F, 0xF0, 0x22, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0x90, 0x02, 0x84, 0xEF, 0xF0, 0xEE, 0xA3,
+0xF0, 0xA3, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0xB1,
+0x88, 0xB1, 0x54, 0x90, 0x83, 0xEF, 0xB1, 0x7F,
+0x90, 0x83, 0xF3, 0xF0, 0x90, 0x81, 0x6E, 0xE0,
+0x20, 0xE0, 0x02, 0xA1, 0x4A, 0x90, 0x83, 0xF3,
+0xE0, 0xFF, 0xEC, 0xC3, 0x9F, 0x40, 0x02, 0xA1,
+0x4A, 0x90, 0x83, 0xEF, 0xE0, 0xFA, 0xA3, 0xE0,
+0xFB, 0x12, 0x5F, 0xF1, 0xAD, 0x07, 0x74, 0x02,
+0x2D, 0xB1, 0xA9, 0x54, 0xF8, 0xF9, 0x12, 0x5F,
+0xBC, 0xFE, 0x74, 0x00, 0x2D, 0x12, 0x5F, 0xAA,
+0x7A, 0x00, 0x24, 0x00, 0xFF, 0xEA, 0x3E, 0x54,
+0x3F, 0x90, 0x83, 0xF1, 0xF0, 0xA3, 0xEF, 0xF0,
+0x74, 0x03, 0x2D, 0xB1, 0x91, 0xFF, 0x7E, 0x00,
+0xAD, 0x01, 0xED, 0x24, 0x18, 0xFB, 0xEA, 0x33,
+0xCB, 0x2F, 0xFF, 0xEE, 0x3B, 0x90, 0x83, 0xF1,
+0x8F, 0xF0, 0x12, 0x41, 0xF6, 0x90, 0x83, 0xF1,
+0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xB1, 0x5D, 0x90,
+0x83, 0xF1, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90,
+0x83, 0xEF, 0xB1, 0xB7, 0xD3, 0x90, 0x83, 0xF0,
+0xE0, 0x9F, 0x90, 0x83, 0xEF, 0xE0, 0x9E, 0x40,
+0x11, 0x90, 0x80, 0xFB, 0xB1, 0x9C, 0x90, 0x83,
+0xF0, 0xE0, 0x9F, 0xF0, 0x90, 0x83, 0xEF, 0xE0,
+0x9E, 0xF0, 0x90, 0x83, 0xEF, 0x91, 0x8C, 0x0C,
+0x81, 0xB5, 0x22, 0xF0, 0x90, 0x01, 0x17, 0xE0,
+0xFE, 0x90, 0x01, 0x16, 0xE0, 0x7C, 0x00, 0x24,
+0x00, 0xFF, 0xEC, 0x3E, 0x22, 0x7D, 0x7F, 0xEF,
+0x5D, 0xC3, 0x60, 0x0A, 0xB1, 0x72, 0x24, 0x80,
+0xFF, 0xE4, 0x3E, 0xFE, 0x80, 0x03, 0xB1, 0x72,
+0xFF, 0x22, 0x74, 0xFF, 0x9D, 0xFD, 0x74, 0xFF,
+0x94, 0x00, 0x5E, 0xFE, 0xED, 0x5F, 0x22, 0xF0,
+0xA3, 0xEF, 0xF0, 0x90, 0x02, 0x87, 0xE0, 0x22,
+0x90, 0x01, 0x1F, 0xE0, 0xFE, 0x90, 0x01, 0x1E,
+0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83,
+0xE0, 0x54, 0x03, 0x22, 0xE0, 0x24, 0x01, 0xFF,
+0x90, 0x80, 0xFA, 0xE0, 0x34, 0x00, 0xFE, 0xC3,
+0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83,
+0xE0, 0x54, 0x0F, 0x33, 0x33, 0x33, 0x22, 0xEE,
+0x8F, 0xF0, 0x12, 0x41, 0xF6, 0x90, 0x80, 0xFA,
+0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0x90, 0x81,
+0x79, 0xE0, 0x30, 0xE0, 0x0D, 0x90, 0x81, 0x71,
+0xE0, 0xC4, 0x54, 0x0F, 0x20, 0xE0, 0x03, 0x7F,
+0x00, 0x22, 0x7F, 0x01, 0x22, 0xD3, 0x10, 0xAF,
+0x01, 0xC3, 0xC0, 0xD0, 0xEF, 0x20, 0xE0, 0x05,
+0x90, 0x83, 0xB1, 0x80, 0x03, 0x90, 0x83, 0xB2,
+0xE0, 0x90, 0x83, 0xAE, 0xF0, 0x90, 0x83, 0xAE,
+0xE0, 0x14, 0x60, 0x13, 0x14, 0x60, 0x14, 0x24,
+0xFE, 0x60, 0x10, 0x14, 0x60, 0x09, 0x14, 0x60,
+0x06, 0x24, 0x06, 0xE4, 0xFE, 0x80, 0x06, 0x7E,
+0x04, 0x80, 0x02, 0x7E, 0x08, 0xAF, 0x06, 0xD0,
+0xD0, 0x92, 0xAF, 0x22, 0xE4, 0xFE, 0x74, 0x7D,
+0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x83, 0xF5, 0x83,
+0xE0, 0xFD, 0x74, 0xA4, 0x2E, 0x12, 0x6F, 0xCB,
+0xED, 0xF0, 0x0E, 0xEE, 0xB4, 0x08, 0xE7, 0x90,
+0x83, 0xAD, 0xE0, 0x90, 0x04, 0x4C, 0xF0, 0x90,
+0x83, 0xAF, 0xE0, 0x90, 0x04, 0x4D, 0xF0, 0x90,
+0x83, 0xC2, 0xE0, 0x60, 0x18, 0x12, 0x67, 0xF0,
+0xFA, 0x7B, 0x01, 0xC0, 0x03, 0x8B, 0x13, 0x75,
+0x14, 0x83, 0x75, 0x15, 0x7D, 0x75, 0x16, 0x34,
+0xD0, 0x03, 0x12, 0x2B, 0xED, 0x22, 0x12, 0x1F,
+0xA4, 0x90, 0x83, 0xB1, 0x12, 0x56, 0x7A, 0x90,
+0x83, 0xB2, 0xF0, 0x22, 0xD1, 0xBA, 0x90, 0x83,
+0xBA, 0x12, 0x56, 0x7A, 0xFF, 0xED, 0x2F, 0x90,
+0x83, 0xBB, 0x12, 0x57, 0x74, 0xFF, 0xED, 0x2F,
+0x90, 0x83, 0xBC, 0x12, 0x57, 0xC1, 0xFF, 0xED,
+0x2F, 0x90, 0x83, 0xBD, 0x12, 0x55, 0x81, 0xFF,
+0xED, 0x2F, 0x90, 0x83, 0xBE, 0x12, 0x57, 0xB9,
+0xFF, 0xED, 0x2F, 0x90, 0x83, 0xBF, 0xD1, 0xAD,
+0x90, 0x83, 0xC0, 0xF0, 0x22, 0xF0, 0x90, 0x00,
+0x06, 0x12, 0x1F, 0xBD, 0xFF, 0xAE, 0x05, 0xED,
+0x2F, 0x22, 0x90, 0x02, 0x09, 0xE0, 0xFD, 0x12,
+0x1F, 0xA4, 0xFE, 0xAF, 0x05, 0xED, 0x2E, 0x22,
+0xD1, 0xBA, 0x90, 0x83, 0xC1, 0x12, 0x56, 0x7A,
+0xFF, 0xAE, 0x05, 0xED, 0x2F, 0x90, 0x83, 0xC2,
+0xF0, 0x22, 0xE4, 0xFF, 0x74, 0x18, 0xF1, 0x02,
+0x74, 0x80, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x81,
+0xF5, 0x83, 0xEE, 0xF0, 0x74, 0x10, 0xF1, 0x02,
+0x74, 0x7A, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x81,
+0xF5, 0x83, 0xEE, 0xF0, 0x0F, 0xEF, 0xB4, 0x06,
+0xDB, 0x22, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x06,
+0xF5, 0x83, 0xE0, 0xFE, 0x22, 0xEF, 0x60, 0x08,
+0x90, 0x83, 0xB4, 0xE0, 0xFF, 0x12, 0x62, 0x40,
+0x22, 0x12, 0x42, 0x44, 0x90, 0x81, 0x59, 0x12,
+0x42, 0x38, 0x12, 0x42, 0x0C, 0x78, 0x0A, 0x12,
+0x20, 0xA8, 0x90, 0x81, 0x22, 0xE0, 0xFE, 0xC3,
+0x74, 0x0A, 0x9E, 0x2F, 0x22, 0x74, 0x28, 0x2E,
+0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0,
+0x2F, 0xFF, 0x90, 0x81, 0x65, 0xE0, 0xFD, 0x22,
+0x12, 0x42, 0x1A, 0x90, 0x81, 0x5D, 0x12, 0x20,
+0xCE, 0x90, 0x81, 0x06, 0xE0, 0x22, 0x2F, 0xF5,
+0x82, 0x74, 0x01, 0x3E, 0xF5, 0x83, 0xE0, 0xFF,
+0x90, 0x80, 0x61, 0xE0, 0x75, 0xF0, 0x08, 0x22,
+0xF0, 0x90, 0x81, 0x27, 0xE0, 0x24, 0x04, 0x90,
+0x81, 0x22, 0xF0, 0xA3, 0x74, 0x10, 0x22, 0x12,
+0x42, 0x50, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE4,
+0x35, 0x83, 0xF5, 0x83, 0xEF, 0x22, 0x90, 0x84,
+0x19, 0x12, 0x42, 0x65, 0xE4, 0x90, 0x84, 0x1C,
+0xF0, 0xA3, 0x22, 0xF0, 0xEE, 0x54, 0x08, 0xFE,
+0xEF, 0x54, 0xF7, 0x4E, 0x22, 0x54, 0x10, 0xFD,
+0xEF, 0x54, 0xEF, 0x4D, 0xFF, 0x22, 0x54, 0x40,
+0xFD, 0xEF, 0x54, 0xBF, 0x4D, 0xFF, 0x22, 0x7E,
+0x00, 0x7F, 0x08, 0x7D, 0x00, 0x7B, 0x01, 0x22,
+0xF0, 0xEE, 0x54, 0x80, 0xFE, 0xEF, 0x54, 0x7F,
+0x22, 0x90, 0x06, 0x0A, 0xE0, 0x54, 0xF8, 0xF0,
+0x22, 0x90, 0x80, 0xFA, 0xF0, 0xA3, 0xEF, 0xF0,
+0x22, 0xF0, 0x90, 0x81, 0x25, 0xE0, 0xFF, 0xC3,
+0x22, 0x12, 0x32, 0x1E, 0x90, 0x84, 0x97, 0xE0,
+0x22, 0x00, 0xE0, 0x5B
+};
+
+u32 array_length_mp_8188e_t_fw_wowlan = 16388;
+
+#endif /*CONFIG_WOWLAN*/
+
+#endif /* end of LOAD_FW_HEADER_FROM_DRIVER */
+
diff --git a/drivers/staging/rtl8188eu/hal/hal8188e_t_fw.h b/drivers/staging/rtl8188eu/hal/hal8188e_t_fw.h
new file mode 100644
index 000000000000..c64221332ab1
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal8188e_t_fw.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef _FW_HEADER_8188E_T_H
+#define _FW_HEADER_8188E_T_H
+
+#ifdef LOAD_FW_HEADER_FROM_DRIVER
+#if (defined(CONFIG_AP_WOWLAN))
+extern u8 array_mp_8188e_t_fw_ap[15502];
+extern u32 array_length_mp_8188e_t_fw_ap;
+#endif
+
+extern u8 array_mp_8188e_t_fw_nic[15262];
+extern u32 array_length_mp_8188e_t_fw_nic;
+extern u8 array_mp_8188e_t_fw_nic_89em[14364];
+extern u32 array_length_mp_8188e_t_fw_nic_89em;
+#ifdef CONFIG_WOWLAN
+extern u8 array_mp_8188e_t_fw_wowlan[16388];
+extern u32 array_length_mp_8188e_t_fw_wowlan;
+#endif /*CONFIG_WOWLAN*/
+#endif /* end of LOAD_FW_HEADER_FROM_DRIVER */
+
+#endif
+
diff --git a/drivers/staging/rtl8188eu/hal/hal8188erateadaptive.c b/drivers/staging/rtl8188eu/hal/hal8188erateadaptive.c
new file mode 100644
index 000000000000..5ab02885ba7b
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal8188erateadaptive.c
@@ -0,0 +1,1022 @@
+/*++
+Copyright (c) Realtek Semiconductor Corp. All rights reserved.
+
+Module Name:
+ rate_adaptive.c
+
+Abstract:
+ Implement rate Adaptive functions for common operations.
+
+Major Change History:
+ When Who What
+ ---------- --------------- -------------------------------
+ 2011-08-12 Page Create.
+ 2015-04-23 Wilson Fine tune (SD9 Family)
+
+--*/
+#include "mp_precomp.h"
+
+#include "phydm_precomp.h"
+
+
+#if (RATE_ADAPTIVE_SUPPORT == 1)
+/* rate adaptive parameters */
+
+
+static u8 RETRY_PENALTY[PERENTRY][RETRYSIZE + 1] = {{5, 4, 3, 2, 0, 3}, /* 92 , idx=0 */
+ {6, 5, 4, 3, 0, 4}, /* 86 , idx=1 */
+ {6, 5, 4, 2, 0, 4}, /* 81 , idx=2 */
+ {8, 7, 6, 4, 0, 6}, /* 75 , idx=3 */
+ {10, 9, 8, 6, 0, 8}, /* 71 , idx=4 */
+ {10, 9, 8, 4, 0, 8}, /* 66 , idx=5 */
+ {10, 9, 8, 2, 0, 8}, /* 62 , idx=6 */
+ {10, 9, 8, 0, 0, 8}, /* 59 , idx=7 */
+ {18, 17, 16, 8, 0, 16}, /* 53 , idx=8 */
+ {26, 25, 24, 16, 0, 24}, /* 50 , idx=9 */
+ {34, 33, 32, 24, 0, 32}, /* 47 , idx=0x0a */
+ {34, 31, 28, 20, 0, 32}, /* 43 , idx=0x0b */
+ {34, 31, 27, 18, 0, 32}, /* 40 , idx=0x0c */
+ {34, 31, 26, 16, 0, 32}, /* 37 , idx=0x0d */
+ {34, 30, 22, 16, 0, 32}, /* 32 , idx=0x0e */
+ {34, 30, 24, 16, 0, 32}, /* 26 , idx=0x0f */
+ {49, 46, 40, 16, 0, 48}, /* 20 , idx=0x10 */
+ {49, 45, 32, 0, 0, 48}, /* 17 , idx=0x11 */
+ {49, 45, 22, 18, 0, 48}, /* 15 , idx=0x12 */
+ {49, 40, 24, 16, 0, 48}, /* 12 , idx=0x13 */
+ {49, 32, 18, 12, 0, 48}, /* 9 , idx=0x14 */
+ {49, 22, 18, 14, 0, 48}, /* 6 , idx=0x15 */
+ {49, 16, 16, 0, 0, 48}
+};/* 3 */ /* 3, idx=0x16 */
+
+static u8 RETRY_PENALTY_UP[RETRYSIZE + 1] = {49, 44, 16, 16, 0, 48}; /* 12% for rate up */
+
+static u8 PT_PENALTY[RETRYSIZE + 1] = {34, 31, 30, 24, 0, 32};
+
+/* wilson modify */
+
+static u8 RETRY_PENALTY_IDX[2][RATESIZE] = {{
+ 4, 4, 4, 5, 4, 4, 5, 7, 7, 7, 8, 0x0a, /* SS>TH */
+ 4, 4, 4, 4, 6, 0x0a, 0x0b, 0x0d,
+ 5, 5, 7, 7, 8, 0x0b, 0x0d, 0x0f
+ }, /* 0329 R01 */
+ {
+ 0x0a, 0x0a, 0x0b, 0x0c, 0x0a, 0x0a, 0x0b, 0x0c, 0x0d, 0x10, 0x13, 0x13, /* SS<TH */
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11, 0x13, 0x13,
+ 9, 9, 9, 9, 0x0c, 0x0e, 0x11, 0x13
+ }
+};
+
+static u8 RETRY_PENALTY_UP_IDX[RATESIZE] = {0x0c, 0x0d, 0x0d, 0x0f, 0x0d, 0x0e, 0x0f, 0x0f, 0x10, 0x12, 0x13, 0x14, /* SS>TH */
+ 0x0f, 0x10, 0x10, 0x12, 0x12, 0x13, 0x14, 0x15,
+ 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, 0x14, 0x15
+ };
+
+static u8 RSSI_THRESHOLD[RATESIZE] = {0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0x24, 0x26, 0x2a,
+ 0x18, 0x1a, 0x1d, 0x1f, 0x21, 0x27, 0x29, 0x2a,
+ 0, 0, 0, 0x1f, 0x23, 0x28, 0x2a, 0x2c
+ };
+
+static u16 N_THRESHOLD_HIGH[RATESIZE] = {4, 4, 8, 16,
+ 24, 36, 48, 72, 96, 144, 192, 216,
+ 60, 80, 100, 160, 240, 400, 600, 800,
+ 300, 320, 480, 720, 1000, 1200, 1600, 2000
+ };
+static u16 N_THRESHOLD_LOW[RATESIZE] = {2, 2, 4, 8,
+ 12, 18, 24, 36, 48, 72, 96, 108,
+ 30, 40, 50, 80, 120, 200, 300, 400,
+ 150, 160, 240, 360, 500, 600, 800, 1000
+ };
+static u8 TRYING_NECESSARY[RATESIZE] = {2, 2, 2, 2,
+ 2, 2, 3, 3, 4, 4, 5, 7,
+ 4, 4, 7, 10, 10, 12, 12, 18,
+ 5, 7, 7, 8, 11, 18, 36, 60
+ }; /* 0329 */ /* 1207 */
+static u8 DROPING_NECESSARY[RATESIZE] = {1, 1, 1, 1,
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 5, 6, 7, 8, 9, 10, 11, 12
+ };
+
+
+static u32 INIT_RATE_FALLBACK_TABLE[16] = {0x0f8ff015, /* 0: 40M BGN mode */
+ 0x0f8ff010, /* 1: 40M GN mode */
+ 0x0f8ff005, /* 2: BN mode/ 40M BGN mode */
+ 0x0f8ff000, /* 3: N mode */
+ 0x00000ff5, /* 4: BG mode */
+ 0x00000ff0, /* 5: G mode */
+ 0x0000000d, /* 6: B mode */
+ 0, /* 7: */
+ 0, /* 8: */
+ 0, /* 9: */
+ 0, /* 10: */
+ 0, /* 11: */
+ 0, /* 12: */
+ 0, /* 13: */
+ 0, /* 14: */
+ 0, /* 15: */
+
+ };
+static u8 pending_for_rate_up_fail[5] = {2, 10, 24, 40, 60};
+static u16 dynamic_tx_rpt_timing[6] = {0x186a, 0x30d4, 0x493e, 0x61a8, 0x7a12, 0x927c}; /*200ms-1200ms*/
+
+/* End rate adaptive parameters */
+
+static void
+odm_set_tx_rpt_timing_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct _odm_ra_info_ *p_ra_info,
+ u8 extend
+)
+{
+ u8 idx = 0;
+
+ for (idx = 0; idx < 5; idx++)
+ if (dynamic_tx_rpt_timing[idx] == p_ra_info->rpt_time)
+ break;
+
+ if (extend == 0) /* back to default timing */
+ idx = 0; /* 200ms */
+ else if (extend == 1) { /* increase the timing */
+ idx += 1;
+ if (idx > 5)
+ idx = 5;
+ } else if (extend == 2) { /* decrease the timing */
+ if (idx != 0)
+ idx -= 1;
+ }
+ p_ra_info->rpt_time = dynamic_tx_rpt_timing[idx];
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("p_ra_info->rpt_time=0x%x\n", p_ra_info->rpt_time));
+}
+
+static int
+odm_rate_down_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct _odm_ra_info_ *p_ra_info
+)
+{
+ u8 rate_id, lowest_rate, highest_rate;
+ s8 i;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("=====>odm_rate_down_8188e()\n"));
+ if (NULL == p_ra_info) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("odm_rate_down_8188e(): p_ra_info is NULL\n"));
+ return -1;
+ }
+ rate_id = p_ra_info->pre_rate;
+ lowest_rate = p_ra_info->lowest_rate;
+ highest_rate = p_ra_info->highest_rate;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
+ (" rate_id=%d lowest_rate=%d highest_rate=%d rate_sgi=%d\n",
+ rate_id, lowest_rate, highest_rate, p_ra_info->rate_sgi));
+ if (rate_id > highest_rate)
+ rate_id = highest_rate;
+ else if (p_ra_info->rate_sgi)
+ p_ra_info->rate_sgi = 0;
+ else if (rate_id > lowest_rate) {
+ if (rate_id > 0) {
+ for (i = rate_id - 1; i >= lowest_rate; i--) {
+ if (p_ra_info->ra_use_rate & BIT(i)) {
+ rate_id = i;
+ goto rate_down_finish;
+
+ }
+ }
+ }
+ } else if (rate_id <= lowest_rate)
+ rate_id = lowest_rate;
+rate_down_finish:
+ if (p_ra_info->ra_waiting_counter == 1) {
+ p_ra_info->ra_waiting_counter += 1;
+ p_ra_info->ra_pending_counter += 1;
+ } else if (p_ra_info->ra_waiting_counter == 0) {
+ } else {
+ p_ra_info->ra_waiting_counter = 0;
+ p_ra_info->ra_pending_counter = 0;
+ }
+ if (p_ra_info->ra_pending_counter >= 4)
+ p_ra_info->ra_pending_counter = 4;
+ p_ra_info->ra_drop_after_down = 1;
+ p_ra_info->decision_rate = rate_id;
+ odm_set_tx_rpt_timing_8188e(p_dm_odm, p_ra_info, 2);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("rate down, Decrease RPT Timing\n"));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("ra_waiting_counter %d, ra_pending_counter %d RADrop %d", p_ra_info->ra_waiting_counter, p_ra_info->ra_pending_counter, p_ra_info->ra_drop_after_down));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("rate down to rate_id %d rate_sgi %d\n", rate_id, p_ra_info->rate_sgi));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("<=====odm_rate_down_8188e()\n"));
+ return 0;
+}
+
+static int
+odm_rate_up_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct _odm_ra_info_ *p_ra_info
+)
+{
+ u8 rate_id, highest_rate;
+ u8 i;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("=====>odm_rate_up_8188e()\n"));
+ if (NULL == p_ra_info) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("odm_rate_up_8188e(): p_ra_info is NULL\n"));
+ return -1;
+ }
+ rate_id = p_ra_info->pre_rate;
+ highest_rate = p_ra_info->highest_rate;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
+ (" rate_id=%d highest_rate=%d\n",
+ rate_id, highest_rate));
+ if (p_ra_info->ra_waiting_counter == 1) {
+ p_ra_info->ra_waiting_counter = 0;
+ p_ra_info->ra_pending_counter = 0;
+ } else if (p_ra_info->ra_waiting_counter > 1) {
+ p_ra_info->pre_rssi_sta_ra = p_ra_info->rssi_sta_ra;
+ goto rate_up_finish;
+ }
+ odm_set_tx_rpt_timing_8188e(p_dm_odm, p_ra_info, 0);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("odm_rate_up_8188e(): default RPT Timing\n"));
+
+ if (rate_id < highest_rate) {
+ for (i = rate_id + 1; i <= highest_rate; i++) {
+ if (p_ra_info->ra_use_rate & BIT(i)) {
+ rate_id = i;
+ goto rate_up_finish;
+ }
+ }
+ } else if (rate_id == highest_rate) {
+ if (p_ra_info->sgi_enable && (p_ra_info->rate_sgi != 1))
+ p_ra_info->rate_sgi = 1;
+ else if ((p_ra_info->sgi_enable) != 1)
+ p_ra_info->rate_sgi = 0;
+ } else /* if((sta_info_ra->Decision_rate) > (sta_info_ra->Highest_rate)) */
+ rate_id = highest_rate;
+
+rate_up_finish:
+ /* if(p_ra_info->ra_waiting_counter==10) */
+ if (p_ra_info->ra_waiting_counter == (4 + pending_for_rate_up_fail[p_ra_info->ra_pending_counter])) {
+ p_ra_info->ra_waiting_counter = 0;
+ } else
+ p_ra_info->ra_waiting_counter++;
+
+ p_ra_info->decision_rate = rate_id;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("rate up to rate_id %d\n", rate_id));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("ra_waiting_counter %d, ra_pending_counter %d", p_ra_info->ra_waiting_counter, p_ra_info->ra_pending_counter));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("<=====odm_rate_up_8188e()\n"));
+ return 0;
+}
+
+static void odm_reset_ra_counter_8188e(struct _odm_ra_info_ *p_ra_info)
+{
+ u8 rate_id;
+ rate_id = p_ra_info->decision_rate;
+ p_ra_info->nsc_up = (N_THRESHOLD_HIGH[rate_id] + N_THRESHOLD_LOW[rate_id]) >> 1;
+ p_ra_info->nsc_down = (N_THRESHOLD_HIGH[rate_id] + N_THRESHOLD_LOW[rate_id]) >> 1;
+}
+
+static void
+odm_rate_decision_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct _odm_ra_info_ *p_ra_info
+)
+{
+ u8 rate_id = 0, rty_pt_id = 0, penalty_id1 = 0, penalty_id2 = 0;
+ /* u32 pool_retry; */
+ static u8 dynamic_tx_rpt_timing_counter = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("=====>odm_rate_decision_8188e()\n"));
+
+ if (p_ra_info->active && (p_ra_info->TOTAL > 0)) { /* STA used and data packet exits */
+ if (p_ra_info->ra_drop_after_down) {
+ p_ra_info->ra_drop_after_down--;
+ odm_reset_ra_counter_8188e(p_ra_info);
+ return;
+ }
+ if ((p_ra_info->rssi_sta_ra < (p_ra_info->pre_rssi_sta_ra - 3)) || (p_ra_info->rssi_sta_ra > (p_ra_info->pre_rssi_sta_ra + 3))) {
+ p_ra_info->pre_rssi_sta_ra = p_ra_info->rssi_sta_ra;
+ p_ra_info->ra_waiting_counter = 0;
+ p_ra_info->ra_pending_counter = 0;
+ }
+
+ /* Start RA decision */
+ if (p_ra_info->pre_rate > p_ra_info->highest_rate)
+ rate_id = p_ra_info->highest_rate;
+ else
+ rate_id = p_ra_info->pre_rate;
+ if (p_ra_info->rssi_sta_ra > RSSI_THRESHOLD[rate_id])
+ rty_pt_id = 0;
+ else
+ rty_pt_id = 1;
+ penalty_id1 = RETRY_PENALTY_IDX[rty_pt_id][rate_id]; /* TODO by page */
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
+ (" nsc_down init is %d\n", p_ra_info->nsc_down));
+ /* pool_retry=p_ra_info->RTY[2]+p_ra_info->RTY[3]+p_ra_info->RTY[4]+p_ra_info->DROP; */
+ p_ra_info->nsc_down += p_ra_info->RTY[0] * RETRY_PENALTY[penalty_id1][0];
+ p_ra_info->nsc_down += p_ra_info->RTY[1] * RETRY_PENALTY[penalty_id1][1];
+ p_ra_info->nsc_down += p_ra_info->RTY[2] * RETRY_PENALTY[penalty_id1][2];
+ p_ra_info->nsc_down += p_ra_info->RTY[3] * RETRY_PENALTY[penalty_id1][3];
+ p_ra_info->nsc_down += p_ra_info->RTY[4] * RETRY_PENALTY[penalty_id1][4];
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
+ (" nsc_down is %d, total*penalty[5] is %d\n",
+ p_ra_info->nsc_down, (p_ra_info->TOTAL * RETRY_PENALTY[penalty_id1][5])));
+ if (p_ra_info->nsc_down > (p_ra_info->TOTAL * RETRY_PENALTY[penalty_id1][5]))
+ p_ra_info->nsc_down -= p_ra_info->TOTAL * RETRY_PENALTY[penalty_id1][5];
+ else
+ p_ra_info->nsc_down = 0;
+
+ /* rate up */
+ penalty_id2 = RETRY_PENALTY_UP_IDX[rate_id];
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
+ (" nsc_up init is %d\n", p_ra_info->nsc_up));
+ p_ra_info->nsc_up += p_ra_info->RTY[0] * RETRY_PENALTY[penalty_id2][0];
+ p_ra_info->nsc_up += p_ra_info->RTY[1] * RETRY_PENALTY[penalty_id2][1];
+ p_ra_info->nsc_up += p_ra_info->RTY[2] * RETRY_PENALTY[penalty_id2][2];
+ p_ra_info->nsc_up += p_ra_info->RTY[3] * RETRY_PENALTY[penalty_id2][3];
+ p_ra_info->nsc_up += p_ra_info->RTY[4] * RETRY_PENALTY[penalty_id2][4];
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
+ ("nsc_up is %d, total*up[5] is %d\n",
+ p_ra_info->nsc_up, (p_ra_info->TOTAL * RETRY_PENALTY[penalty_id2][5])));
+ if (p_ra_info->nsc_up > (p_ra_info->TOTAL * RETRY_PENALTY[penalty_id2][5]))
+ p_ra_info->nsc_up -= p_ra_info->TOTAL * RETRY_PENALTY[penalty_id2][5];
+ else
+ p_ra_info->nsc_up = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE | ODM_COMP_INIT, ODM_DBG_LOUD,
+ (" RssiStaRa= %d rty_pt_id=%d penalty_id1=0x%x penalty_id2=0x%x rate_id=%d nsc_down=%d nsc_up=%d SGI=%d\n",
+ p_ra_info->rssi_sta_ra, rty_pt_id, penalty_id1, penalty_id2, rate_id, p_ra_info->nsc_down, p_ra_info->nsc_up, p_ra_info->rate_sgi));
+ if ((p_ra_info->nsc_down < N_THRESHOLD_LOW[rate_id]) || (p_ra_info->DROP > DROPING_NECESSARY[rate_id]))
+ odm_rate_down_8188e(p_dm_odm, p_ra_info);
+ /* else if ((p_ra_info->nsc_up > N_THRESHOLD_HIGH[rate_id])&&(pool_retry<POOL_RETRY_TH[rate_id])) */
+ else if (p_ra_info->nsc_up > N_THRESHOLD_HIGH[rate_id])
+ odm_rate_up_8188e(p_dm_odm, p_ra_info);
+
+ if ((p_ra_info->decision_rate) == (p_ra_info->pre_rate))
+ dynamic_tx_rpt_timing_counter += 1;
+ else
+ dynamic_tx_rpt_timing_counter = 0;
+
+ if (dynamic_tx_rpt_timing_counter >= 4) {
+ odm_set_tx_rpt_timing_8188e(p_dm_odm, p_ra_info, 1);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("<=====rate don't change 4 times, Extend RPT Timing\n"));
+ dynamic_tx_rpt_timing_counter = 0;
+ }
+
+ p_ra_info->pre_rate = p_ra_info->decision_rate; /* YJ,add,120120 */
+
+ odm_reset_ra_counter_8188e(p_ra_info);
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("<=====odm_rate_decision_8188e()\n"));
+}
+
+static int
+odm_arfb_refresh_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct _odm_ra_info_ *p_ra_info
+)
+{
+ /* Wilson 2011/10/26 */
+ u32 mask_from_reg;
+ u8 i;
+
+ switch (p_ra_info->rate_id) {
+ case RATR_INX_WIRELESS_NGB:
+ p_ra_info->ra_use_rate = (p_ra_info->rate_mask) & 0x0f8fe00f;
+ break;
+ case RATR_INX_WIRELESS_NG:
+ p_ra_info->ra_use_rate = (p_ra_info->rate_mask) & 0x0f8ff010;
+ break;
+ case RATR_INX_WIRELESS_NB:
+ p_ra_info->ra_use_rate = (p_ra_info->rate_mask) & 0x0f8fe00f;
+ break;
+ case RATR_INX_WIRELESS_N:
+ p_ra_info->ra_use_rate = (p_ra_info->rate_mask) & 0x0f8ff000;
+ break;
+ case RATR_INX_WIRELESS_GB:
+ p_ra_info->ra_use_rate = (p_ra_info->rate_mask) & 0x00000fef;
+ break;
+ case RATR_INX_WIRELESS_G:
+ p_ra_info->ra_use_rate = (p_ra_info->rate_mask) & 0x00000ff0;
+ break;
+ case RATR_INX_WIRELESS_B:
+ p_ra_info->ra_use_rate = (p_ra_info->rate_mask) & 0x0000000d;
+ break;
+ case 12:
+ mask_from_reg = odm_read_4byte(p_dm_odm, REG_ARFR0);
+ p_ra_info->ra_use_rate = (p_ra_info->rate_mask) & mask_from_reg;
+ break;
+ case 13:
+ mask_from_reg = odm_read_4byte(p_dm_odm, REG_ARFR1);
+ p_ra_info->ra_use_rate = (p_ra_info->rate_mask) & mask_from_reg;
+ break;
+ case 14:
+ mask_from_reg = odm_read_4byte(p_dm_odm, REG_ARFR2);
+ p_ra_info->ra_use_rate = (p_ra_info->rate_mask) & mask_from_reg;
+ break;
+ case 15:
+ mask_from_reg = odm_read_4byte(p_dm_odm, REG_ARFR3);
+ p_ra_info->ra_use_rate = (p_ra_info->rate_mask) & mask_from_reg;
+ break;
+
+ default:
+ p_ra_info->ra_use_rate = (p_ra_info->rate_mask);
+ break;
+ }
+ /* Highest rate */
+ if (p_ra_info->ra_use_rate)
+ for (i = RATESIZE ; i >= 0 ; i--) {
+ if ((p_ra_info->ra_use_rate) & BIT(i)) {
+ p_ra_info->highest_rate = i;
+ break;
+ }
+ }
+ else
+ p_ra_info->highest_rate = 0;
+ /* Lowest rate */
+ if (p_ra_info->ra_use_rate)
+ for (i = 0; i < RATESIZE; i++) {
+ if ((p_ra_info->ra_use_rate) & BIT(i)) {
+ p_ra_info->lowest_rate = i;
+ break;
+ }
+ }
+ else
+ p_ra_info->lowest_rate = 0;
+
+#if POWER_TRAINING_ACTIVE == 1
+ if (p_ra_info->highest_rate > 0x13)
+ p_ra_info->pt_mode_ss = 3;
+ else if (p_ra_info->highest_rate > 0x0b)
+ p_ra_info->pt_mode_ss = 2;
+ else if (p_ra_info->highest_rate > 0x0b)
+ p_ra_info->pt_mode_ss = 1;
+ else
+ p_ra_info->pt_mode_ss = 0;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
+ ("ODM_ARFBRefresh_8188E(): pt_mode_ss=%d\n", p_ra_info->pt_mode_ss));
+
+#endif
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
+ ("ODM_ARFBRefresh_8188E(): rate_id=%d rate_mask=%8.8x ra_use_rate=%8.8x highest_rate=%d\n",
+ p_ra_info->rate_id, p_ra_info->rate_mask, p_ra_info->ra_use_rate, p_ra_info->highest_rate));
+ return 0;
+}
+
+#if POWER_TRAINING_ACTIVE == 1
+static void
+odm_pt_try_state_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct _odm_ra_info_ *p_ra_info
+)
+{
+ p_ra_info->pt_try_state = 0;
+ switch (p_ra_info->pt_mode_ss) {
+ case 3:
+ if (p_ra_info->decision_rate >= 0x19)
+ p_ra_info->pt_try_state = 1;
+ break;
+ case 2:
+ if (p_ra_info->decision_rate >= 0x11)
+ p_ra_info->pt_try_state = 1;
+ break;
+ case 1:
+ if (p_ra_info->decision_rate >= 0x0a)
+ p_ra_info->pt_try_state = 1;
+ break;
+ case 0:
+ if (p_ra_info->decision_rate >= 0x03)
+ p_ra_info->pt_try_state = 1;
+ break;
+ default:
+ p_ra_info->pt_try_state = 0;
+ }
+
+ if (p_ra_info->rssi_sta_ra < 48)
+ p_ra_info->pt_stage = 0;
+ else if (p_ra_info->pt_try_state == 1) {
+ if ((p_ra_info->pt_stop_count >= 10) || (p_ra_info->pt_pre_rssi > p_ra_info->rssi_sta_ra + 5)
+ || (p_ra_info->pt_pre_rssi < p_ra_info->rssi_sta_ra - 5) || (p_ra_info->decision_rate != p_ra_info->pt_pre_rate)) {
+ if (p_ra_info->pt_stage == 0)
+ p_ra_info->pt_stage = 1;
+ else if (p_ra_info->pt_stage == 1)
+ p_ra_info->pt_stage = 3;
+ else
+ p_ra_info->pt_stage = 5;
+
+ p_ra_info->pt_pre_rssi = p_ra_info->rssi_sta_ra;
+ p_ra_info->pt_stop_count = 0;
+
+ } else {
+ p_ra_info->ra_stage = 0;
+ p_ra_info->pt_stop_count++;
+ }
+ } else {
+ p_ra_info->pt_stage = 0;
+ p_ra_info->ra_stage = 0;
+ }
+ p_ra_info->pt_pre_rate = p_ra_info->decision_rate;
+
+ /* Disable power training when noisy environment */
+ if (p_dm_odm->is_disable_power_training) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("odm_pt_try_state_8188e(): Disable power training when noisy environment\n"));
+ p_ra_info->pt_stage = 0;
+ p_ra_info->ra_stage = 0;
+ p_ra_info->pt_stop_count = 0;
+ }
+}
+
+static void
+odm_pt_decision_8188e(
+ struct _odm_ra_info_ *p_ra_info
+)
+{
+ u8 stage_BUF;
+ u8 j;
+ u8 temp_stage;
+ u32 numsc;
+ u32 num_total;
+ u8 stage_id;
+
+ stage_BUF = p_ra_info->pt_stage;
+ numsc = 0;
+ num_total = p_ra_info->TOTAL * PT_PENALTY[5];
+ for (j = 0; j <= 4; j++) {
+ numsc += p_ra_info->RTY[j] * PT_PENALTY[j];
+ if (numsc > num_total)
+ break;
+ }
+
+ j = j >> 1;
+ temp_stage = (p_ra_info->pt_stage + 1) >> 1;
+ if (temp_stage > j)
+ stage_id = temp_stage - j;
+ else
+ stage_id = 0;
+
+ p_ra_info->pt_smooth_factor = (p_ra_info->pt_smooth_factor >> 1) + (p_ra_info->pt_smooth_factor >> 2) + stage_id * 16 + 2;
+ if (p_ra_info->pt_smooth_factor > 192)
+ p_ra_info->pt_smooth_factor = 192;
+ stage_id = p_ra_info->pt_smooth_factor >> 6;
+ temp_stage = stage_id * 2;
+ if (temp_stage != 0)
+ temp_stage -= 1;
+ if (p_ra_info->DROP > 3)
+ temp_stage = 0;
+ p_ra_info->pt_stage = temp_stage;
+
+}
+#endif
+
+static void
+odm_ra_tx_rpt_timer_setting(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u16 min_rpt_time
+)
+{
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, (" =====>odm_ra_tx_rpt_timer_setting()\n"));
+
+
+ if (p_dm_odm->currmin_rpt_time != min_rpt_time) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
+ (" currmin_rpt_time =0x%04x min_rpt_time=0x%04x\n", p_dm_odm->currmin_rpt_time, min_rpt_time));
+ rtw_rpt_timer_cfg_cmd(p_dm_odm->adapter, min_rpt_time);
+ p_dm_odm->currmin_rpt_time = min_rpt_time;
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, (" <=====odm_ra_tx_rpt_timer_setting()\n"));
+}
+
+
+void
+odm_ra_support_init(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("=====>odm_ra_support_init()\n"));
+
+ /* 2012/02/14 MH Be noticed, the init must be after IC type is recognized!!!!! */
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E)
+ p_dm_odm->ra_support88e = true;
+
+}
+
+
+
+int
+odm_ra_info_init(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 mac_id
+)
+{
+ struct _odm_ra_info_ *p_ra_info = &p_dm_odm->ra_info[mac_id];
+ p_ra_info->decision_rate = 0x13;
+ p_ra_info->pre_rate = 0x13;
+ p_ra_info->highest_rate = 0x13;
+ p_ra_info->lowest_rate = 0;
+ p_ra_info->rate_id = 0;
+ p_ra_info->rate_mask = 0xffffffff;
+ p_ra_info->rssi_sta_ra = 0;
+ p_ra_info->pre_rssi_sta_ra = 0;
+ p_ra_info->sgi_enable = 0;
+ p_ra_info->ra_use_rate = 0xffffffff;
+ p_ra_info->nsc_down = (N_THRESHOLD_HIGH[0x13] + N_THRESHOLD_LOW[0x13]) / 2;
+ p_ra_info->nsc_up = (N_THRESHOLD_HIGH[0x13] + N_THRESHOLD_LOW[0x13]) / 2;
+ p_ra_info->rate_sgi = 0;
+ p_ra_info->active = 1; /* active is not used at present. by page, 110819 */
+ p_ra_info->rpt_time = 0x927c;
+ p_ra_info->DROP = 0;
+ p_ra_info->RTY[0] = 0;
+ p_ra_info->RTY[1] = 0;
+ p_ra_info->RTY[2] = 0;
+ p_ra_info->RTY[3] = 0;
+ p_ra_info->RTY[4] = 0;
+ p_ra_info->TOTAL = 0;
+ p_ra_info->ra_waiting_counter = 0;
+ p_ra_info->ra_pending_counter = 0;
+ p_ra_info->ra_drop_after_down = 0;
+#if POWER_TRAINING_ACTIVE == 1
+ p_ra_info->pt_active = 1; /* active when this STA is use */
+ p_ra_info->pt_try_state = 0;
+ p_ra_info->pt_stage = 5; /* Need to fill into HW_PWR_STATUS */
+ p_ra_info->pt_smooth_factor = 192;
+ p_ra_info->pt_stop_count = 0;
+ p_ra_info->pt_pre_rate = 0;
+ p_ra_info->pt_pre_rssi = 0;
+ p_ra_info->pt_mode_ss = 0;
+ p_ra_info->ra_stage = 0;
+#endif
+ return 0;
+}
+
+int
+odm_ra_info_init_all(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 mac_id = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("=====>\n"));
+ p_dm_odm->currmin_rpt_time = 0;
+
+ for (mac_id = 0; mac_id < ODM_ASSOCIATE_ENTRY_NUM; mac_id++)
+ odm_ra_info_init(p_dm_odm, mac_id);
+
+ /* Redifine arrays for I-cut NIC */
+ if (p_dm_odm->cut_version == ODM_CUT_I) {
+ u8 i;
+ u8 RETRY_PENALTY_IDX_S[2][RATESIZE] = {{
+ 4, 4, 4, 5,
+ 4, 4, 5, 7, 7, 7, 8, 0x0a, /* SS>TH */
+ 4, 4, 4, 4, 6, 0x0a, 0x0b, 0x0d,
+ 5, 5, 7, 7, 8, 0x0b, 0x0d, 0x0f
+ }, /* 0329 R01 */
+ {
+ 0x0a, 0x0a, 0x0b, 0x0c,
+ 0x0a, 0x0a, 0x0b, 0x0c, 0x0d, 0x10, 0x13, 0x13, /* SS<TH */
+ 0x06, 0x07, 0x08, 0x0d, 0x0e, 0x11, 0x11, 0x11,
+ 9, 9, 9, 9, 0x0c, 0x0e, 0x11, 0x13
+ }
+ };
+
+ u8 RETRY_PENALTY_UP_IDX_S[RATESIZE] = {0x0c, 0x0d, 0x0d, 0x0f,
+ 0x0d, 0x0e, 0x0f, 0x0f, 0x10, 0x12, 0x13, 0x14, /* SS>TH */
+ 0x0b, 0x0b, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12,
+ 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, 0x14, 0x15
+ };
+
+ for (i = 0; i < RATESIZE; i++) {
+ RETRY_PENALTY_IDX[0][i] = RETRY_PENALTY_IDX_S[0][i];
+ RETRY_PENALTY_IDX[1][i] = RETRY_PENALTY_IDX_S[1][i];
+
+ RETRY_PENALTY_UP_IDX[i] = RETRY_PENALTY_UP_IDX_S[i];
+ }
+ return 0;
+ }
+ return 0;
+}
+
+u8
+odm_ra_get_sgi_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 mac_id
+)
+{
+ if ((NULL == p_dm_odm) || (mac_id >= ASSOCIATE_ENTRY_NUM))
+ return 0;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
+ ("mac_id=%d SGI=%d\n", mac_id, p_dm_odm->ra_info[mac_id].rate_sgi));
+ return p_dm_odm->ra_info[mac_id].rate_sgi;
+}
+
+u8
+odm_ra_get_decision_rate_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 mac_id
+)
+{
+ u8 decision_rate = 0;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ u8 cmd_buf[3];
+
+ if ((NULL == p_dm_odm) || (mac_id >= ASSOCIATE_ENTRY_NUM))
+ return 0;
+ decision_rate = (p_dm_odm->ra_info[mac_id].decision_rate);
+
+ if (decision_rate != p_ra_table->link_tx_rate[mac_id]) {
+
+ cmd_buf[1] = mac_id;
+ cmd_buf[0] = decision_rate;
+ phydm_c2h_ra_report_handler(p_dm_odm, &(cmd_buf[0]), 3);
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
+ (" mac_id=%d decision_rate=0x%x\n", mac_id, decision_rate));
+ return decision_rate;
+}
+
+u8
+odm_ra_get_hw_pwr_status_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 mac_id
+)
+{
+ u8 pt_stage = 5;
+ if ((NULL == p_dm_odm) || (mac_id >= ASSOCIATE_ENTRY_NUM))
+ return 0;
+ pt_stage = (p_dm_odm->ra_info[mac_id].pt_stage);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
+ ("mac_id=%d pt_stage=0x%x\n", mac_id, pt_stage));
+ return pt_stage;
+}
+
+void
+odm_ra_update_rate_info_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 mac_id,
+ u8 rate_id,
+ u32 rate_mask,
+ u8 sgi_enable
+)
+{
+ struct _odm_ra_info_ *p_ra_info = NULL;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
+ ("mac_id=%d rate_id=0x%x rate_mask=0x%x sgi_enable=%d\n",
+ mac_id, rate_id, rate_mask, sgi_enable));
+ if ((NULL == p_dm_odm) || (mac_id >= ASSOCIATE_ENTRY_NUM))
+ return;
+
+ p_ra_info = &(p_dm_odm->ra_info[mac_id]);
+ p_ra_info->rate_id = rate_id;
+ p_ra_info->rate_mask = rate_mask;
+ p_ra_info->sgi_enable = sgi_enable;
+ odm_arfb_refresh_8188e(p_dm_odm, p_ra_info);
+}
+
+void
+odm_ra_set_rssi_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 mac_id,
+ u8 rssi
+)
+{
+ struct _odm_ra_info_ *p_ra_info = NULL;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
+ (" mac_id=%d rssi=%d\n", mac_id, rssi));
+ if ((NULL == p_dm_odm) || (mac_id >= ASSOCIATE_ENTRY_NUM))
+ return;
+
+ p_ra_info = &(p_dm_odm->ra_info[mac_id]);
+ p_ra_info->rssi_sta_ra = rssi;
+}
+
+void
+odm_ra_set_tx_rpt_time(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u16 min_rpt_time
+)
+{
+ odm_write_2byte(p_dm_odm, REG_TX_RPT_TIME, min_rpt_time);
+}
+
+void odm_ra_tx_rpt2_handle_8188e(struct PHY_DM_STRUCT *p_dm_odm,
+ u8 *tx_rpt_buf, __le16 tx_rpt_len,
+ u32 mac_id_valid_entry0,
+ u32 mac_id_valid_entry1)
+{
+ struct _odm_ra_info_ *p_ra_info = NULL;
+ u8 mac_id = 0;
+ u8 *p_buffer = NULL;
+ u32 valid = 0, item_num = 0;
+ u16 min_rpt_time = 0x927c;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("=====>odm_ra_tx_rpt2_handle_8188e(): valid0=%d valid1=%d BufferLength=%d\n",
+ mac_id_valid_entry0, mac_id_valid_entry1, tx_rpt_len));
+
+ item_num = le16_to_cpu(tx_rpt_len) >> 3;
+ p_buffer = tx_rpt_buf;
+
+ do {
+ valid = 0;
+ if (mac_id < 32)
+ valid = (1 << mac_id) & mac_id_valid_entry0;
+ else if (mac_id < 64)
+ valid = (1 << (mac_id - 32)) & mac_id_valid_entry1;
+
+ p_ra_info = &(p_dm_odm->ra_info[mac_id]);
+ if (valid) {
+ p_ra_info->RTY[0] = (u16)GET_TX_REPORT_TYPE1_RERTY_0(p_buffer);
+ p_ra_info->RTY[1] = (u16)GET_TX_REPORT_TYPE1_RERTY_1(p_buffer);
+ p_ra_info->RTY[2] = (u16)GET_TX_REPORT_TYPE1_RERTY_2(p_buffer);
+ p_ra_info->RTY[3] = (u16)GET_TX_REPORT_TYPE1_RERTY_3(p_buffer);
+ p_ra_info->RTY[4] = (u16)GET_TX_REPORT_TYPE1_RERTY_4(p_buffer);
+ p_ra_info->DROP = (u16)GET_TX_REPORT_TYPE1_DROP_0(p_buffer);
+
+ p_ra_info->TOTAL = p_ra_info->RTY[0] + \
+ p_ra_info->RTY[1] + \
+ p_ra_info->RTY[2] + \
+ p_ra_info->RTY[3] + \
+ p_ra_info->RTY[4] + \
+ p_ra_info->DROP;
+#if defined(TXRETRY_CNT)
+ extern struct stat_info *get_macidinfo(struct rtl8192cd_priv *priv, unsigned int aid);
+
+ {
+ struct stat_info *pstat = get_macidinfo(p_dm_odm->priv, mac_id);
+ if (pstat) {
+ pstat->cur_tx_ok += p_ra_info->RTY[0];
+ pstat->cur_tx_retry_pkts += p_ra_info->RTY[1] + p_ra_info->RTY[2] + p_ra_info->RTY[3] + p_ra_info->RTY[4];
+ pstat->cur_tx_retry_cnt += p_ra_info->RTY[1] + p_ra_info->RTY[2] * 2 + p_ra_info->RTY[3] * 3 + p_ra_info->RTY[4] * 4;
+ pstat->total_tx_retry_cnt += pstat->cur_tx_retry_cnt;
+ pstat->total_tx_retry_pkts += pstat->cur_tx_retry_pkts;
+ pstat->cur_tx_fail += p_ra_info->DROP;
+ }
+ }
+#endif
+ if (p_ra_info->TOTAL != 0) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
+ ("macid=%d Total=%d R0=%d R1=%d R2=%d R3=%d R4=%d D0=%d valid0=%x valid1=%x\n",
+ mac_id,
+ p_ra_info->TOTAL,
+ p_ra_info->RTY[0],
+ p_ra_info->RTY[1],
+ p_ra_info->RTY[2],
+ p_ra_info->RTY[3],
+ p_ra_info->RTY[4],
+ p_ra_info->DROP,
+ mac_id_valid_entry0,
+ mac_id_valid_entry1));
+#if POWER_TRAINING_ACTIVE == 1
+ if (p_ra_info->pt_active) {
+ if (p_ra_info->ra_stage < 5)
+ odm_rate_decision_8188e(p_dm_odm, p_ra_info);
+ else if (p_ra_info->ra_stage == 5) /* Power training try state */
+ odm_pt_try_state_8188e(p_dm_odm, p_ra_info);
+ else /* ra_stage==6 */
+ odm_pt_decision_8188e(p_ra_info);
+
+ /* Stage_RA counter */
+ if (p_ra_info->ra_stage <= 5)
+ p_ra_info->ra_stage++;
+ else
+ p_ra_info->ra_stage = 0;
+ } else
+ odm_rate_decision_8188e(p_dm_odm, p_ra_info);
+#else
+ odm_rate_decision_8188e(p_dm_odm, p_ra_info);
+#endif
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
+ ("macid=%d R0=%d R1=%d R2=%d R3=%d R4=%d drop=%d valid0=%x rate_id=%d SGI=%d\n",
+ mac_id,
+ p_ra_info->RTY[0],
+ p_ra_info->RTY[1],
+ p_ra_info->RTY[2],
+ p_ra_info->RTY[3],
+ p_ra_info->RTY[4],
+ p_ra_info->DROP,
+ mac_id_valid_entry0,
+ p_ra_info->decision_rate,
+ p_ra_info->rate_sgi));
+ } else
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, (" TOTAL=0!!!!\n"));
+ }
+
+ if (min_rpt_time > p_ra_info->rpt_time)
+ min_rpt_time = p_ra_info->rpt_time;
+
+ p_buffer += TX_RPT2_ITEM_SIZE;
+ mac_id++;
+ } while (mac_id < item_num);
+
+ odm_ra_tx_rpt_timer_setting(p_dm_odm, min_rpt_time);
+
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("<===== odm_ra_tx_rpt2_handle_8188e()\n"));
+}
+
+#else
+
+static void
+odm_ra_tx_rpt_timer_setting(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u16 min_rpt_time
+)
+{
+ return;
+}
+
+
+void
+odm_ra_support_init(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ return;
+}
+
+int
+odm_ra_info_init(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 mac_id
+)
+{
+ return 0;
+}
+
+int
+odm_ra_info_init_all(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ return 0;
+}
+
+u8
+odm_ra_get_sgi_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 mac_id
+)
+{
+ return 0;
+}
+
+u8
+odm_ra_get_decision_rate_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 mac_id
+)
+{
+ return 0;
+}
+u8
+odm_ra_get_hw_pwr_status_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 mac_id
+)
+{
+ return 0;
+}
+
+void
+odm_ra_update_rate_info_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 mac_id,
+ u8 rate_id,
+ u32 rate_mask,
+ u8 sgi_enable
+)
+{
+ return;
+}
+
+void
+odm_ra_set_rssi_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 mac_id,
+ u8 rssi
+)
+{
+ return;
+}
+
+void
+odm_ra_set_tx_rpt_time(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u16 min_rpt_time
+)
+{
+ return;
+}
+
+void
+odm_ra_tx_rpt2_handle_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 *tx_rpt_buf,
+ __le16 tx_rpt_len,
+ u32 mac_id_valid_entry0,
+ u32 mac_id_valid_entry1
+)
+{
+}
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/hal8188erateadaptive.h b/drivers/staging/rtl8188eu/hal/hal8188erateadaptive.h
new file mode 100644
index 000000000000..2aee71ffffba
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal8188erateadaptive.h
@@ -0,0 +1,65 @@
+#ifndef __INC_RA_H
+#define __INC_RA_H
+/*++
+Copyright (c) Realtek Semiconductor Corp. All rights reserved.
+
+Module Name:
+ rate_adaptive.h
+
+Abstract:
+ Prototype of RA and related data structure.
+
+Major Change History:
+ When Who What
+ ---------- --------------- -------------------------------
+ 2011-08-12 Page Create.
+--*/
+
+/* rate adaptive define */
+#define PERENTRY 23
+#define RETRYSIZE 5
+#define RATESIZE 28
+#define TX_RPT2_ITEM_SIZE 8
+
+#define DM_RA_RATE_UP 1
+#define DM_RA_RATE_DOWN 2
+
+/* TX report 2 format in Rx desc */
+#define GET_TX_RPT2_DESC_PKT_LEN_88E(__prx_status_desc) \
+ LE_BITS_TO_4BYTE(__prx_status_desc, 0, 9)
+#define GET_TX_RPT2_DESC_MACID_VALID_1_88E(__prx_status_desc) \
+ LE_BITS_TO_4BYTE(__prx_status_desc+16, 0, 32)
+#define GET_TX_RPT2_DESC_MACID_VALID_2_88E(__prx_status_desc) \
+ LE_BITS_TO_4BYTE(__prx_status_desc+20, 0, 32)
+
+#define GET_TX_REPORT_TYPE1_RERTY_0(__paddr) \
+ LE_BITS_TO_4BYTE(__paddr, 0, 16)
+#define GET_TX_REPORT_TYPE1_RERTY_1(__paddr) \
+ LE_BITS_TO_1BYTE(__paddr+2, 0, 8)
+#define GET_TX_REPORT_TYPE1_RERTY_2(__paddr) \
+ LE_BITS_TO_1BYTE(__paddr+3, 0, 8)
+#define GET_TX_REPORT_TYPE1_RERTY_3(__paddr) \
+ LE_BITS_TO_1BYTE(__paddr+4, 0, 8)
+#define GET_TX_REPORT_TYPE1_RERTY_4(__paddr) \
+ LE_BITS_TO_1BYTE(__paddr+4+1, 0, 8)
+#define GET_TX_REPORT_TYPE1_DROP_0(__paddr) \
+ LE_BITS_TO_1BYTE(__paddr+4+2, 0, 8)
+#define GET_TX_REPORT_TYPE1_DROP_1(__paddr) \
+ LE_BITS_TO_1BYTE(__paddr+4+3, 0, 8)
+
+/* End rate adaptive define */
+
+void odm_ra_support_init(struct PHY_DM_STRUCT *p_dm_odm);
+int odm_ra_info_init_all(struct PHY_DM_STRUCT *p_dm_odm);
+int odm_ra_info_init(struct PHY_DM_STRUCT *p_dm_odm, u32 mac_id);
+u8 odm_ra_get_sgi_8188e(struct PHY_DM_STRUCT *p_dm_odm, u8 mac_id);
+u8 odm_ra_get_decision_rate_8188e(struct PHY_DM_STRUCT *p_dm_odm, u8 mac_id);
+u8 odm_ra_get_hw_pwr_status_8188e(struct PHY_DM_STRUCT *p_dm_odm, u8 mac_id);
+void odm_ra_update_rate_info_8188e(struct PHY_DM_STRUCT *p_dm_odm, u8 mac_id,
+ u8 rate_id, u32 rate_mask, u8 sgi_enable);
+void odm_ra_set_rssi_8188e(struct PHY_DM_STRUCT *p_dm_odm, u8 mac_id, u8 rssi);
+void odm_ra_tx_rpt2_handle_8188e(struct PHY_DM_STRUCT *p_dm_odm, u8 *tx_rpt_buf,
+ __le16 tx_rpt_len, u32 mac_id_valid_entry0, u32 mac_id_valid_entry1);
+void odm_ra_set_tx_rpt_time(struct PHY_DM_STRUCT *p_dm_odm, u16 min_rpt_time);
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/hal8188ereg.h b/drivers/staging/rtl8188eu/hal/hal8188ereg.h
new file mode 100644
index 000000000000..f609da8b08b6
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal8188ereg.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+/* ************************************************************
+ * File Name: hal8188ereg.h
+ *
+ * Description:
+ *
+ * This file is for RTL8188E register definition.
+ *
+ *
+ * ************************************************************ */
+#ifndef __HAL_8188E_REG_H__
+#define __HAL_8188E_REG_H__
+
+/*
+ * Register Definition
+ * */
+#define TRX_ANTDIV_PATH 0x860
+#define RX_ANTDIV_PATH 0xb2c
+#define ODM_R_A_AGC_CORE1_8188E 0xc50
+
+#define REG_GPIO_EXT_CTRL 0x0060
+
+#define REG_MCUFWDL_8188E 0x0080
+#define REG_FW_DBG_STATUS_8188E 0x0088
+#define REG_FW_DBG_CTRL_8188E 0x008F
+
+#define REG_CR_8188E 0x0100
+
+
+/*
+ * Bitmap Definition
+ * */
+#define BIT_FA_RESET_8188E BIT(0)
+#define REG_ADAPTIVE_DATA_RATE_0 0x2B0
+#define REG_DBI_WDATA_8188 0x0348 /* DBI Write data */
+#define REG_DBI_RDATA_8188 0x034C /* DBI Read data */
+#define REG_DBI_ADDR_8188 0x0350 /* DBI Address */
+#define REG_DBI_FLAG_8188 0x0352 /* DBI Read/Write Flag */
+#define REG_MDIO_WDATA_8188E 0x0354 /* MDIO for Write PCIE PHY */
+#define REG_MDIO_RDATA_8188E 0x0356 /* MDIO for Reads PCIE PHY */
+#define REG_MDIO_CTL_8188E 0x0358 /* MDIO for Control */
+
+/* [0-63] */
+#define REG_MACID_NO_LINK 0x484 /* No Link register (bit[x] enabled means dropping packets for MACID in HW queue) */
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/hal_btcoex.c b/drivers/staging/rtl8188eu/hal/hal_btcoex.c
new file mode 100644
index 000000000000..ff28b63ecded
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal_btcoex.c
@@ -0,0 +1,3786 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define __HAL_BTCOEX_C__
+
+#ifdef CONFIG_BT_COEXIST
+
+#include <hal_data.h>
+#include <hal_btcoex.h>
+#include "btc/mp_precomp.h"
+
+/* ************************************
+ * Global variables
+ * ************************************ */
+const char *const BtProfileString[] = {
+ "NONE",
+ "A2DP",
+ "PAN",
+ "HID",
+ "SCO",
+};
+
+const char *const BtSpecString[] = {
+ "1.0b",
+ "1.1",
+ "1.2",
+ "2.0+EDR",
+ "2.1+EDR",
+ "3.0+HS",
+ "4.0",
+};
+
+const char *const BtLinkRoleString[] = {
+ "Master",
+ "Slave",
+};
+
+const char *const h2cStaString[] = {
+ "successful",
+ "h2c busy",
+ "rf off",
+ "fw not read",
+};
+
+const char *const ioStaString[] = {
+ "success",
+ "can not IO",
+ "rf off",
+ "fw not read",
+ "wait io timeout",
+ "invalid len",
+ "idle Q empty",
+ "insert waitQ fail",
+ "unknown fail",
+ "wrong level",
+ "h2c stopped",
+};
+
+const char *const GLBtcWifiBwString[] = {
+ "11bg",
+ "HT20",
+ "HT40",
+ "HT80",
+ "HT160"
+};
+
+const char *const GLBtcWifiFreqString[] = {
+ "2.4G",
+ "5G"
+};
+
+const char *const GLBtcIotPeerString[] = {
+ "UNKNOWN",
+ "REALTEK",
+ "REALTEK_92SE",
+ "BROADCOM",
+ "RALINK",
+ "ATHEROS",
+ "CISCO",
+ "MERU",
+ "MARVELL",
+ "REALTEK_SOFTAP", /* peer is RealTek SOFT_AP, by Bohn, 2009.12.17 */
+ "SELF_SOFTAP", /* Self is SoftAP */
+ "AIRGO",
+ "INTEL",
+ "RTK_APCLIENT",
+ "REALTEK_81XX",
+ "REALTEK_WOW",
+ "REALTEK_JAGUAR_BCUTAP",
+ "REALTEK_JAGUAR_CCUTAP"
+};
+
+const char *const coexOpcodeString[] = {
+ "Wifi status notify",
+ "Wifi progress",
+ "Wifi info",
+ "Power state",
+ "Set Control",
+ "Get Control"
+};
+
+const char *const coexIndTypeString[] = {
+ "bt info",
+ "pstdma",
+ "limited tx/rx",
+ "coex table",
+ "request"
+};
+
+const char *const coexH2cResultString[] = {
+ "ok",
+ "unknown",
+ "un opcode",
+ "opVer MM",
+ "par Err",
+ "par OoR",
+ "reqNum MM",
+ "halMac Fail",
+ "h2c TimeOut",
+ "Invalid c2h Len",
+ "data overflow"
+};
+
+#define HALBTCOUTSRC_AGG_CHK_WINDOW_IN_MS 8000
+
+struct btc_coexist GLBtCoexist;
+BTC_OFFLOAD gl_coex_offload;
+u8 GLBtcWiFiInScanState;
+u8 GLBtcWiFiInIQKState;
+u8 GLBtcWiFiInIPS;
+u8 GLBtcWiFiInLPS;
+u8 GLBtcBtCoexAliveRegistered;
+
+/*
+ * BT control H2C/C2H
+ */
+/* EXT_EID */
+typedef enum _bt_ext_eid {
+ C2H_WIFI_FW_ACTIVE_RSP = 0,
+ C2H_TRIG_BY_BT_FW
+} BT_EXT_EID;
+
+/* C2H_STATUS */
+typedef enum _bt_c2h_status {
+ BT_STATUS_OK = 0,
+ BT_STATUS_VERSION_MISMATCH,
+ BT_STATUS_UNKNOWN_OPCODE,
+ BT_STATUS_ERROR_PARAMETER
+} BT_C2H_STATUS;
+
+/* C2H BT OP CODES */
+typedef enum _bt_op_code {
+ BT_OP_GET_BT_VERSION = 0x00,
+ BT_OP_WRITE_REG_ADDR = 0x0c,
+ BT_OP_WRITE_REG_VALUE = 0x0d,
+
+ BT_OP_READ_REG = 0x11,
+
+ BT_LO_OP_GET_AFH_MAP_L = 0x1e,
+ BT_LO_OP_GET_AFH_MAP_M = 0x1f,
+ BT_LO_OP_GET_AFH_MAP_H = 0x20,
+
+ BT_OP_GET_BT_COEX_SUPPORTED_FEATURE = 0x2a,
+ BT_OP_GET_BT_COEX_SUPPORTED_VERSION = 0x2b,
+ BT_OP_GET_BT_ANT_DET_VAL = 0x2c,
+ BT_OP_GET_BT_BLE_SCAN_PARA = 0x2d,
+ BT_OP_GET_BT_BLE_SCAN_TYPE = 0x2e,
+ BT_OP_MAX
+} BT_OP_CODE;
+
+#define BTC_MPOPER_TIMEOUT 50 /* unit: ms */
+
+#define C2H_MAX_SIZE 16
+u8 GLBtcBtMpOperSeq;
+_mutex GLBtcBtMpOperLock;
+_timer GLBtcBtMpOperTimer;
+_sema GLBtcBtMpRptSema;
+u8 GLBtcBtMpRptSeq;
+u8 GLBtcBtMpRptStatus;
+u8 GLBtcBtMpRptRsp[C2H_MAX_SIZE];
+u8 GLBtcBtMpRptRspSize;
+u8 GLBtcBtMpRptWait;
+u8 GLBtcBtMpRptWiFiOK;
+u8 GLBtcBtMpRptBTOK;
+
+/*
+ * Debug
+ */
+u32 GLBtcDbgType[COMP_MAX];
+u8 GLBtcDbgBuf[BT_TMP_BUF_SIZE];
+u8 gl_btc_trace_buf[BT_TMP_BUF_SIZE];
+
+typedef struct _btcoexdbginfo {
+ u8 *info;
+ u32 size; /* buffer total size */
+ u32 len; /* now used length */
+} BTCDBGINFO, *PBTCDBGINFO;
+
+BTCDBGINFO GLBtcDbgInfo;
+
+#define BT_Operation(Adapter) false
+
+static void DBG_BT_INFO_INIT(PBTCDBGINFO pinfo, u8 *pbuf, u32 size)
+{
+ if (NULL == pinfo)
+ return;
+
+ memset(pinfo, 0, sizeof(BTCDBGINFO));
+
+ if (pbuf && size) {
+ pinfo->info = pbuf;
+ pinfo->size = size;
+ }
+}
+
+void DBG_BT_INFO(u8 *dbgmsg)
+{
+ PBTCDBGINFO pinfo;
+ u32 msglen, buflen;
+ u8 *pbuf;
+
+
+ pinfo = &GLBtcDbgInfo;
+
+ if (NULL == pinfo->info)
+ return;
+
+ msglen = strlen(dbgmsg);
+ if (pinfo->len + msglen > pinfo->size)
+ return;
+
+ pbuf = pinfo->info + pinfo->len;
+ memcpy(pbuf, dbgmsg, msglen);
+ pinfo->len += msglen;
+}
+
+/* ************************************
+ * Debug related function
+ * ************************************ */
+static u8 halbtcoutsrc_IsBtCoexistAvailable(PBTC_COEXIST pBtCoexist)
+{
+ if (!pBtCoexist->bBinded ||
+ NULL == pBtCoexist->Adapter)
+ return false;
+ return true;
+}
+
+static void halbtcoutsrc_DbgInit(void)
+{
+ u8 i;
+
+ for (i = 0; i < COMP_MAX; i++)
+ GLBtcDbgType[i] = 0;
+}
+
+static u8 halbtcoutsrc_IsCsrBtCoex(PBTC_COEXIST pBtCoexist)
+{
+ if (pBtCoexist->board_info.bt_chip_type == BTC_CHIP_CSR_BC4
+ || pBtCoexist->board_info.bt_chip_type == BTC_CHIP_CSR_BC8
+ )
+ return true;
+ return false;
+}
+
+static u8 halbtcoutsrc_IsHwMailboxExist(PBTC_COEXIST pBtCoexist)
+{
+ if (pBtCoexist->board_info.bt_chip_type == BTC_CHIP_CSR_BC4
+ || pBtCoexist->board_info.bt_chip_type == BTC_CHIP_CSR_BC8
+ )
+ return false;
+ else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter))
+ return false;
+ else
+ return true;
+}
+
+static void halbtcoutsrc_LeaveLps(PBTC_COEXIST pBtCoexist)
+{
+ PADAPTER padapter;
+
+
+ padapter = pBtCoexist->Adapter;
+
+ pBtCoexist->bt_info.bt_ctrl_lps = true;
+ pBtCoexist->bt_info.bt_lps_on = false;
+
+ rtw_btcoex_LPS_Leave(padapter);
+}
+
+void halbtcoutsrc_EnterLps(PBTC_COEXIST pBtCoexist)
+{
+ PADAPTER padapter;
+
+
+ padapter = pBtCoexist->Adapter;
+
+ if (pBtCoexist->bdontenterLPS == false) {
+ pBtCoexist->bt_info.bt_ctrl_lps = true;
+ pBtCoexist->bt_info.bt_lps_on = true;
+
+ rtw_btcoex_LPS_Enter(padapter);
+ }
+}
+
+void halbtcoutsrc_NormalLps(PBTC_COEXIST pBtCoexist)
+{
+ PADAPTER padapter;
+
+
+
+ padapter = pBtCoexist->Adapter;
+
+ if (pBtCoexist->bt_info.bt_ctrl_lps) {
+ pBtCoexist->bt_info.bt_lps_on = false;
+ rtw_btcoex_LPS_Leave(padapter);
+ pBtCoexist->bt_info.bt_ctrl_lps = false;
+ }
+}
+
+/*
+ * Constraint:
+ * 1. this function will request pwrctrl->lock
+ */
+void halbtcoutsrc_LeaveLowPower(PBTC_COEXIST pBtCoexist)
+{
+#ifdef CONFIG_LPS_LCLK
+ PADAPTER padapter;
+ PHAL_DATA_TYPE pHalData;
+ struct pwrctrl_priv *pwrctrl;
+ s32 ready;
+ u32 stime;
+ s32 utime;
+ u32 timeout; /* unit: ms */
+
+
+ padapter = pBtCoexist->Adapter;
+ pHalData = GET_HAL_DATA(padapter);
+ pwrctrl = adapter_to_pwrctl(padapter);
+ ready = _FAIL;
+#ifdef LPS_RPWM_WAIT_MS
+ timeout = LPS_RPWM_WAIT_MS;
+#else /* !LPS_RPWM_WAIT_MS */
+ timeout = 30;
+#endif /* !LPS_RPWM_WAIT_MS */
+
+ if (GLBtcBtCoexAliveRegistered == true)
+ return;
+
+ stime = jiffies;
+ do {
+ ready = rtw_register_task_alive(padapter, BTCOEX_ALIVE);
+ if (_SUCCESS == ready)
+ break;
+
+ utime = rtw_get_passing_time_ms(stime);
+ if (utime > timeout)
+ break;
+
+ rtw_msleep_os(1);
+ } while (1);
+
+ GLBtcBtCoexAliveRegistered = true;
+#endif /* CONFIG_LPS_LCLK */
+}
+
+/*
+ * Constraint:
+ * 1. this function will request pwrctrl->lock
+ */
+void halbtcoutsrc_NormalLowPower(PBTC_COEXIST pBtCoexist)
+{
+#ifdef CONFIG_LPS_LCLK
+ PADAPTER padapter;
+
+ if (GLBtcBtCoexAliveRegistered == false)
+ return;
+
+ padapter = pBtCoexist->Adapter;
+ rtw_unregister_task_alive(padapter, BTCOEX_ALIVE);
+
+ GLBtcBtCoexAliveRegistered = false;
+#endif /* CONFIG_LPS_LCLK */
+}
+
+void halbtcoutsrc_DisableLowPower(PBTC_COEXIST pBtCoexist, u8 bLowPwrDisable)
+{
+ pBtCoexist->bt_info.bt_disable_low_pwr = bLowPwrDisable;
+ if (bLowPwrDisable)
+ halbtcoutsrc_LeaveLowPower(pBtCoexist); /* leave 32k low power. */
+ else
+ halbtcoutsrc_NormalLowPower(pBtCoexist); /* original 32k low power behavior. */
+}
+
+void halbtcoutsrc_AggregationCheck(PBTC_COEXIST pBtCoexist)
+{
+ PADAPTER padapter;
+ bool bNeedToAct = false;
+ static u32 preTime = 0;
+ u32 curTime = 0;
+
+ padapter = pBtCoexist->Adapter;
+
+ /* ===================================== */
+ /* To void continuous deleteBA=>addBA=>deleteBA=>addBA */
+ /* This function is not allowed to continuous called. */
+ /* It can only be called after 8 seconds. */
+ /* ===================================== */
+
+ curTime = rtw_systime_to_ms(jiffies);
+ if ((curTime - preTime) < HALBTCOUTSRC_AGG_CHK_WINDOW_IN_MS) /* over 8 seconds you can execute this function again. */
+ return;
+ else
+ preTime = curTime;
+
+ if (pBtCoexist->bt_info.reject_agg_pkt) {
+ bNeedToAct = true;
+ pBtCoexist->bt_info.pre_reject_agg_pkt = pBtCoexist->bt_info.reject_agg_pkt;
+ } else {
+ if (pBtCoexist->bt_info.pre_reject_agg_pkt) {
+ bNeedToAct = true;
+ pBtCoexist->bt_info.pre_reject_agg_pkt = pBtCoexist->bt_info.reject_agg_pkt;
+ }
+
+ if (pBtCoexist->bt_info.pre_bt_ctrl_agg_buf_size !=
+ pBtCoexist->bt_info.bt_ctrl_agg_buf_size) {
+ bNeedToAct = true;
+ pBtCoexist->bt_info.pre_bt_ctrl_agg_buf_size = pBtCoexist->bt_info.bt_ctrl_agg_buf_size;
+ }
+
+ if (pBtCoexist->bt_info.bt_ctrl_agg_buf_size) {
+ if (pBtCoexist->bt_info.pre_agg_buf_size !=
+ pBtCoexist->bt_info.agg_buf_size)
+ bNeedToAct = true;
+ pBtCoexist->bt_info.pre_agg_buf_size = pBtCoexist->bt_info.agg_buf_size;
+ }
+ }
+
+ if (bNeedToAct)
+ rtw_btcoex_rx_ampdu_apply(padapter);
+}
+
+u8 halbtcoutsrc_is_autoload_fail(PBTC_COEXIST pBtCoexist)
+{
+ PADAPTER padapter;
+ PHAL_DATA_TYPE pHalData;
+
+ padapter = pBtCoexist->Adapter;
+ pHalData = GET_HAL_DATA(padapter);
+
+ return pHalData->bautoload_fail_flag;
+}
+
+u8 halbtcoutsrc_is_fw_ready(PBTC_COEXIST pBtCoexist)
+{
+ PADAPTER padapter;
+
+ padapter = pBtCoexist->Adapter;
+
+ return padapter->bFWReady;
+}
+
+u8 halbtcoutsrc_IsWifiBusy(PADAPTER padapter)
+{
+ if (rtw_mi_check_status(padapter, MI_AP_MODE))
+ return true;
+ if (rtw_mi_busy_traffic_check(padapter, false))
+ return true;
+
+ return false;
+}
+
+static u32 _halbtcoutsrc_GetWifiLinkStatus(PADAPTER padapter)
+{
+ struct mlme_priv *pmlmepriv;
+ u8 bp2p;
+ u32 portConnectedStatus;
+
+
+ pmlmepriv = &padapter->mlmepriv;
+ bp2p = false;
+ portConnectedStatus = 0;
+
+#ifdef CONFIG_P2P
+ if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
+ bp2p = true;
+#endif /* CONFIG_P2P */
+
+ if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == true) {
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
+ if (bp2p)
+ portConnectedStatus |= WIFI_P2P_GO_CONNECTED;
+ else
+ portConnectedStatus |= WIFI_AP_CONNECTED;
+ } else {
+ if (bp2p)
+ portConnectedStatus |= WIFI_P2P_GC_CONNECTED;
+ else
+ portConnectedStatus |= WIFI_STA_CONNECTED;
+ }
+ }
+
+ return portConnectedStatus;
+}
+
+u32 halbtcoutsrc_GetWifiLinkStatus(PBTC_COEXIST pBtCoexist)
+{
+ /* ================================= */
+ /* return value: */
+ /* [31:16]=> connected port number */
+ /* [15:0]=> port connected bit define */
+ /* ================================ */
+
+ PADAPTER padapter;
+ u32 retVal;
+ u32 portConnectedStatus, numOfConnectedPort;
+ struct dvobj_priv *dvobj;
+ _adapter *iface;
+ int i;
+
+ padapter = pBtCoexist->Adapter;
+ retVal = 0;
+ portConnectedStatus = 0;
+ numOfConnectedPort = 0;
+ dvobj = adapter_to_dvobj(padapter);
+
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if ((iface) && rtw_is_adapter_up(iface)) {
+ retVal = _halbtcoutsrc_GetWifiLinkStatus(iface);
+ if (retVal) {
+ portConnectedStatus |= retVal;
+ numOfConnectedPort++;
+ }
+ }
+ }
+ retVal = (numOfConnectedPort << 16) | portConnectedStatus;
+
+ return retVal;
+}
+
+static void _btmpoper_timer_hdl(void *p)
+{
+ if (GLBtcBtMpRptWait) {
+ GLBtcBtMpRptWait = 0;
+ up(&GLBtcBtMpRptSema);
+ }
+}
+
+/*
+ * !IMPORTANT!
+ * Before call this function, caller should acquire "GLBtcBtMpOperLock"!
+ * Othrewise there will be racing problem and something may go wrong.
+ */
+static u8 _btmpoper_cmd(PBTC_COEXIST pBtCoexist, u8 opcode, u8 opcodever, u8 *cmd, u8 size)
+{
+ PADAPTER padapter;
+ u8 buf[H2C_BTMP_OPER_LEN] = {0};
+ u8 buflen;
+ u8 seq;
+ u8 timer_cancelled;
+ s32 ret;
+
+
+ if (!cmd && size)
+ size = 0;
+ if ((size + 2) > H2C_BTMP_OPER_LEN)
+ return BT_STATUS_H2C_LENGTH_EXCEEDED;
+ buflen = size + 2;
+
+ seq = GLBtcBtMpOperSeq & 0xF;
+ GLBtcBtMpOperSeq++;
+
+ buf[0] = (opcodever & 0xF) | (seq << 4);
+ buf[1] = opcode;
+ if (cmd && size)
+ memcpy(buf + 2, cmd, size);
+
+ GLBtcBtMpRptWait = 1;
+ GLBtcBtMpRptWiFiOK = 0;
+ GLBtcBtMpRptBTOK = 0;
+ GLBtcBtMpRptStatus = 0;
+ padapter = pBtCoexist->Adapter;
+ _set_timer(&GLBtcBtMpOperTimer, BTC_MPOPER_TIMEOUT);
+ if (rtw_hal_fill_h2c_cmd(padapter, H2C_BT_MP_OPER, buflen, buf) == _FAIL) {
+ _cancel_timer(&GLBtcBtMpOperTimer, &timer_cancelled);
+ ret = BT_STATUS_H2C_FAIL;
+ goto exit;
+ }
+
+ _rtw_down_sema(&GLBtcBtMpRptSema);
+ /* GLBtcBtMpRptWait should be 0 here*/
+
+ if (!GLBtcBtMpRptWiFiOK) {
+ RTW_ERR("%s: Didn't get H2C Rsp Event!\n", __func__);
+ ret = BT_STATUS_H2C_TIMTOUT;
+ goto exit;
+ }
+ if (!GLBtcBtMpRptBTOK) {
+ RTW_ERR("%s: Didn't get BT response!\n", __func__);
+ ret = BT_STATUS_H2C_BT_NO_RSP;
+ goto exit;
+ }
+ if (seq != GLBtcBtMpRptSeq) {
+ RTW_ERR("%s: Sequence number not match!(%d!=%d)!\n",
+ __func__, seq, GLBtcBtMpRptSeq);
+ ret = BT_STATUS_C2H_REQNUM_MISMATCH;
+ goto exit;
+ }
+
+ switch (GLBtcBtMpRptStatus) {
+ /* Examine the status reported from C2H */
+ case BT_STATUS_OK:
+ ret = BT_STATUS_BT_OP_SUCCESS;
+ RTW_DBG("%s: C2H status = BT_STATUS_BT_OP_SUCCESS\n", __func__);
+ break;
+ case BT_STATUS_VERSION_MISMATCH:
+ ret = BT_STATUS_OPCODE_L_VERSION_MISMATCH;
+ RTW_DBG("%s: C2H status = BT_STATUS_OPCODE_L_VERSION_MISMATCH\n", __func__);
+ break;
+ case BT_STATUS_UNKNOWN_OPCODE:
+ ret = BT_STATUS_UNKNOWN_OPCODE_L;
+ RTW_DBG("%s: C2H status = MP_BT_STATUS_UNKNOWN_OPCODE_L\n", __func__);
+ break;
+ case BT_STATUS_ERROR_PARAMETER:
+ ret = BT_STATUS_PARAMETER_FORMAT_ERROR_L;
+ RTW_DBG("%s: C2H status = MP_BT_STATUS_PARAMETER_FORMAT_ERROR_L\n", __func__);
+ break;
+ default:
+ ret = BT_STATUS_UNKNOWN_STATUS_L;
+ RTW_DBG("%s: C2H status = MP_BT_STATUS_UNKNOWN_STATUS_L\n", __func__);
+ break;
+ }
+
+exit:
+ return ret;
+}
+
+u32 halbtcoutsrc_GetBtPatchVer(PBTC_COEXIST pBtCoexist)
+{
+ if (pBtCoexist->bt_info.get_bt_fw_ver_cnt <= 5) {
+ if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == true) {
+ unsigned long irqL;
+ u8 ret;
+
+ _enter_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+ ret = _btmpoper_cmd(pBtCoexist, BT_OP_GET_BT_VERSION, 0, NULL, 0);
+ if (BT_STATUS_BT_OP_SUCCESS == ret) {
+ pBtCoexist->bt_info.bt_real_fw_ver = le16_to_cpu(*(u16 *)GLBtcBtMpRptRsp);
+ pBtCoexist->bt_info.bt_fw_ver = *(GLBtcBtMpRptRsp + 2);
+ pBtCoexist->bt_info.get_bt_fw_ver_cnt++;
+ }
+
+ _exit_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+ } else {
+#ifdef CONFIG_BT_COEXIST_SOCKET_TRX
+ u8 dataLen = 2;
+ u8 buf[4] = {0};
+
+ buf[0] = 0x0; /* OP_Code */
+ buf[1] = 0x0; /* OP_Code_Length */
+ BT_SendEventExtBtCoexControl(pBtCoexist->Adapter, false, dataLen, &buf[0]);
+#endif /* !CONFIG_BT_COEXIST_SOCKET_TRX */
+ }
+ }
+
+exit:
+ return pBtCoexist->bt_info.bt_real_fw_ver;
+}
+
+s32 halbtcoutsrc_GetWifiRssi(PADAPTER padapter)
+{
+ PHAL_DATA_TYPE pHalData;
+ s32 undecorated_smoothed_pwdb = 0;
+
+ pHalData = GET_HAL_DATA(padapter);
+
+ undecorated_smoothed_pwdb = pHalData->entry_min_undecorated_smoothed_pwdb;
+
+ return undecorated_smoothed_pwdb;
+}
+
+u32 halbtcoutsrc_GetBtCoexSupportedFeature(void *pBtcContext)
+{
+ PBTC_COEXIST pBtCoexist;
+ u32 ret = BT_STATUS_BT_OP_SUCCESS;
+ u32 data = 0;
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+
+ if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == true) {
+ u8 buf[3] = {0};
+ unsigned long irqL;
+ u8 op_code;
+ u8 status;
+
+ _enter_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+ op_code = BT_OP_GET_BT_COEX_SUPPORTED_FEATURE;
+ status = _btmpoper_cmd(pBtCoexist, op_code, 0, buf, 0);
+ if (status == BT_STATUS_BT_OP_SUCCESS)
+ data = le16_to_cpu(*(u16 *)GLBtcBtMpRptRsp);
+ else
+ ret = SET_BT_MP_OPER_RET(op_code, status);
+
+ _exit_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+ } else
+ ret = BT_STATUS_NOT_IMPLEMENT;
+
+ return data;
+}
+
+u32 halbtcoutsrc_GetBtCoexSupportedVersion(void *pBtcContext)
+{
+ PBTC_COEXIST pBtCoexist;
+ u32 ret = BT_STATUS_BT_OP_SUCCESS;
+ u32 data = 0xFFFF;
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+
+ if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == true) {
+ u8 buf[3] = {0};
+ unsigned long irqL;
+ u8 op_code;
+ u8 status;
+
+ _enter_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+ op_code = BT_OP_GET_BT_COEX_SUPPORTED_VERSION;
+ status = _btmpoper_cmd(pBtCoexist, op_code, 0, buf, 0);
+ if (status == BT_STATUS_BT_OP_SUCCESS)
+ data = le16_to_cpu(*(u16 *)GLBtcBtMpRptRsp);
+ else
+ ret = SET_BT_MP_OPER_RET(op_code, status);
+
+ _exit_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+ } else
+ ret = BT_STATUS_NOT_IMPLEMENT;
+
+ return data;
+}
+
+static u8 halbtcoutsrc_GetWifiScanAPNum(PADAPTER padapter)
+{
+ struct mlme_priv *pmlmepriv;
+ struct mlme_ext_priv *pmlmeext;
+ static u8 scan_AP_num = 0;
+
+
+ pmlmepriv = &padapter->mlmepriv;
+ pmlmeext = &padapter->mlmeextpriv;
+
+ if (GLBtcWiFiInScanState == false) {
+ if (pmlmepriv->num_of_scanned > 0xFF)
+ scan_AP_num = 0xFF;
+ else
+ scan_AP_num = (u8)pmlmepriv->num_of_scanned;
+ }
+
+ return scan_AP_num;
+}
+
+u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf)
+{
+ PBTC_COEXIST pBtCoexist;
+ PADAPTER padapter;
+ PHAL_DATA_TYPE pHalData;
+ struct mlme_ext_priv *mlmeext;
+ u8 bSoftApExist, bVwifiExist;
+ u8 *pu8;
+ s32 *pS4Tmp;
+ u32 *pU4Tmp;
+ u8 *pU1Tmp;
+ u8 ret;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return false;
+
+ padapter = pBtCoexist->Adapter;
+ pHalData = GET_HAL_DATA(padapter);
+ mlmeext = &padapter->mlmeextpriv;
+ bSoftApExist = false;
+ bVwifiExist = false;
+ pu8 = (u8 *)pOutBuf;
+ pS4Tmp = (s32 *)pOutBuf;
+ pU4Tmp = (u32 *)pOutBuf;
+ pU1Tmp = (u8 *)pOutBuf;
+ ret = true;
+
+ switch (getType) {
+ case BTC_GET_BL_HS_OPERATION:
+ *pu8 = false;
+ ret = false;
+ break;
+
+ case BTC_GET_BL_HS_CONNECTING:
+ *pu8 = false;
+ ret = false;
+ break;
+
+ case BTC_GET_BL_WIFI_FW_READY:
+ *pu8 = halbtcoutsrc_is_fw_ready(pBtCoexist);
+ break;
+
+ case BTC_GET_BL_WIFI_CONNECTED:
+ *pu8 = (rtw_mi_check_status(padapter, MI_LINKED)) ? true : false;
+ break;
+
+ case BTC_GET_BL_WIFI_BUSY:
+ *pu8 = halbtcoutsrc_IsWifiBusy(padapter);
+ break;
+
+ case BTC_GET_BL_WIFI_SCAN:
+ /* Use the value of the new variable GLBtcWiFiInScanState to judge whether WiFi is in scan state or not, since the originally used flag
+ WIFI_SITE_MONITOR in fwstate may not be cleared in time */
+ *pu8 = GLBtcWiFiInScanState;
+ break;
+
+ case BTC_GET_BL_WIFI_LINK:
+ *pu8 = (rtw_mi_check_status(padapter, MI_STA_LINKING)) ? true : false;
+ break;
+
+ case BTC_GET_BL_WIFI_ROAM:
+ *pu8 = (rtw_mi_check_status(padapter, MI_STA_LINKING)) ? true : false;
+ break;
+
+ case BTC_GET_BL_WIFI_4_WAY_PROGRESS:
+ *pu8 = false;
+ break;
+
+ case BTC_GET_BL_WIFI_UNDER_5G:
+ *pu8 = (pHalData->current_band_type == 1) ? true : false;
+ break;
+
+ case BTC_GET_BL_WIFI_AP_MODE_ENABLE:
+ *pu8 = (rtw_mi_check_status(padapter, MI_AP_MODE)) ? true : false;
+ break;
+
+ case BTC_GET_BL_WIFI_ENABLE_ENCRYPTION:
+ *pu8 = padapter->securitypriv.dot11PrivacyAlgrthm == 0 ? false : true;
+ break;
+
+ case BTC_GET_BL_WIFI_UNDER_B_MODE:
+ if (mlmeext->cur_wireless_mode == WIRELESS_11B)
+ *pu8 = true;
+ else
+ *pu8 = false;
+ break;
+
+ case BTC_GET_BL_WIFI_IS_IN_MP_MODE:
+ if (padapter->registrypriv.mp_mode == 0)
+ *pu8 = false;
+ else
+ *pu8 = true;
+ break;
+
+ case BTC_GET_BL_EXT_SWITCH:
+ *pu8 = false;
+ break;
+ case BTC_GET_BL_IS_ASUS_8723B:
+ /* Always return false in linux driver since this case is added only for windows driver */
+ *pu8 = false;
+ break;
+
+ case BTC_GET_S4_WIFI_RSSI:
+ *pS4Tmp = halbtcoutsrc_GetWifiRssi(padapter);
+ break;
+
+ case BTC_GET_S4_HS_RSSI:
+ *pS4Tmp = 0;
+ ret = false;
+ break;
+
+ case BTC_GET_U4_WIFI_BW:
+ if (IsLegacyOnly(mlmeext->cur_wireless_mode))
+ *pU4Tmp = BTC_WIFI_BW_LEGACY;
+ else {
+ switch (pHalData->current_channel_bw) {
+ case CHANNEL_WIDTH_20:
+ *pU4Tmp = BTC_WIFI_BW_HT20;
+ break;
+ case CHANNEL_WIDTH_40:
+ *pU4Tmp = BTC_WIFI_BW_HT40;
+ break;
+ case CHANNEL_WIDTH_80:
+ *pU4Tmp = BTC_WIFI_BW_HT80;
+ break;
+ case CHANNEL_WIDTH_160:
+ *pU4Tmp = BTC_WIFI_BW_HT160;
+ break;
+ default:
+ RTW_INFO("[BTCOEX] unknown bandwidth(%d)\n", pHalData->current_channel_bw);
+ *pU4Tmp = BTC_WIFI_BW_HT40;
+ break;
+ }
+
+ }
+ break;
+
+ case BTC_GET_U4_WIFI_TRAFFIC_DIRECTION: {
+ PRT_LINK_DETECT_T plinkinfo;
+ plinkinfo = &padapter->mlmepriv.LinkDetectInfo;
+
+ if (plinkinfo->NumTxOkInPeriod > plinkinfo->NumRxOkInPeriod)
+ *pU4Tmp = BTC_WIFI_TRAFFIC_TX;
+ else
+ *pU4Tmp = BTC_WIFI_TRAFFIC_RX;
+ }
+ break;
+
+ case BTC_GET_U4_WIFI_FW_VER:
+ *pU4Tmp = pHalData->firmware_version << 16;
+ *pU4Tmp |= pHalData->firmware_sub_version;
+ break;
+
+ case BTC_GET_U4_WIFI_LINK_STATUS:
+ *pU4Tmp = halbtcoutsrc_GetWifiLinkStatus(pBtCoexist);
+ break;
+
+ case BTC_GET_U4_BT_PATCH_VER:
+ *pU4Tmp = halbtcoutsrc_GetBtPatchVer(pBtCoexist);
+ break;
+
+ case BTC_GET_U4_VENDOR:
+ *pU4Tmp = BTC_VENDOR_OTHER;
+ break;
+
+ case BTC_GET_U4_SUPPORTED_VERSION:
+ *pU4Tmp = halbtcoutsrc_GetBtCoexSupportedVersion(pBtCoexist);
+ break;
+ case BTC_GET_U4_SUPPORTED_FEATURE:
+ *pU4Tmp = halbtcoutsrc_GetBtCoexSupportedFeature(pBtCoexist);
+ break;
+
+ case BTC_GET_U4_WIFI_IQK_TOTAL:
+ *pU4Tmp = pHalData->odmpriv.n_iqk_cnt;
+ break;
+
+ case BTC_GET_U4_WIFI_IQK_OK:
+ *pU4Tmp = pHalData->odmpriv.n_iqk_ok_cnt;
+ break;
+
+ case BTC_GET_U4_WIFI_IQK_FAIL:
+ *pU4Tmp = pHalData->odmpriv.n_iqk_fail_cnt;
+ break;
+
+ case BTC_GET_U1_WIFI_DOT11_CHNL:
+ *pU1Tmp = padapter->mlmeextpriv.cur_channel;
+ break;
+
+ case BTC_GET_U1_WIFI_CENTRAL_CHNL:
+ *pU1Tmp = pHalData->current_channel;
+ break;
+
+ case BTC_GET_U1_WIFI_HS_CHNL:
+ *pU1Tmp = 0;
+ ret = false;
+ break;
+
+ case BTC_GET_U1_WIFI_P2P_CHNL:
+#ifdef CONFIG_P2P
+ {
+ struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
+
+ *pU1Tmp = pwdinfo->operating_channel;
+ }
+#else
+ *pU1Tmp = 0;
+#endif
+ break;
+
+ case BTC_GET_U1_MAC_PHY_MODE:
+ /* *pU1Tmp = BTC_SMSP;
+ * *pU1Tmp = BTC_DMSP;
+ * *pU1Tmp = BTC_DMDP;
+ * *pU1Tmp = BTC_MP_UNKNOWN; */
+ break;
+
+ case BTC_GET_U1_AP_NUM:
+ *pU1Tmp = halbtcoutsrc_GetWifiScanAPNum(padapter);
+ break;
+ case BTC_GET_U1_ANT_TYPE:
+ switch (pHalData->bt_coexist.btAntisolation) {
+ case 0:
+ *pU1Tmp = (u8)BTC_ANT_TYPE_0;
+ pBtCoexist->board_info.ant_type = (u8)BTC_ANT_TYPE_0;
+ break;
+ case 1:
+ *pU1Tmp = (u8)BTC_ANT_TYPE_1;
+ pBtCoexist->board_info.ant_type = (u8)BTC_ANT_TYPE_1;
+ break;
+ case 2:
+ *pU1Tmp = (u8)BTC_ANT_TYPE_2;
+ pBtCoexist->board_info.ant_type = (u8)BTC_ANT_TYPE_2;
+ break;
+ case 3:
+ *pU1Tmp = (u8)BTC_ANT_TYPE_3;
+ pBtCoexist->board_info.ant_type = (u8)BTC_ANT_TYPE_3;
+ break;
+ case 4:
+ *pU1Tmp = (u8)BTC_ANT_TYPE_4;
+ pBtCoexist->board_info.ant_type = (u8)BTC_ANT_TYPE_4;
+ break;
+ }
+ break;
+ case BTC_GET_U1_IOT_PEER:
+ *pU1Tmp = mlmeext->mlmext_info.assoc_AP_vendor;
+ break;
+
+ /* =======1Ant=========== */
+ case BTC_GET_U1_LPS_MODE:
+ *pU1Tmp = padapter->dvobj->pwrctl_priv.pwr_mode;
+ break;
+
+ default:
+ ret = false;
+ break;
+ }
+
+ return ret;
+}
+
+u8 halbtcoutsrc_Set(void *pBtcContext, u8 setType, void *pInBuf)
+{
+ PBTC_COEXIST pBtCoexist;
+ PADAPTER padapter;
+ PHAL_DATA_TYPE pHalData;
+ u8 *pu8;
+ u8 *pU1Tmp;
+ u32 *pU4Tmp;
+ u8 ret;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ padapter = pBtCoexist->Adapter;
+ pHalData = GET_HAL_DATA(padapter);
+ pu8 = (u8 *)pInBuf;
+ pU1Tmp = (u8 *)pInBuf;
+ pU4Tmp = (u32 *)pInBuf;
+ ret = true;
+
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return false;
+
+ switch (setType) {
+ /* set some u8 type variables. */
+ case BTC_SET_BL_BT_DISABLE:
+ pBtCoexist->bt_info.bt_disabled = *pu8;
+ break;
+
+ case BTC_SET_BL_BT_ENABLE_DISABLE_CHANGE:
+ pBtCoexist->bt_info.bt_enable_disable_change = *pu8;
+ break;
+
+ case BTC_SET_BL_BT_TRAFFIC_BUSY:
+ pBtCoexist->bt_info.bt_busy = *pu8;
+ break;
+
+ case BTC_SET_BL_BT_LIMITED_DIG:
+ pBtCoexist->bt_info.limited_dig = *pu8;
+ break;
+
+ case BTC_SET_BL_FORCE_TO_ROAM:
+ pBtCoexist->bt_info.force_to_roam = *pu8;
+ break;
+
+ case BTC_SET_BL_TO_REJ_AP_AGG_PKT:
+ pBtCoexist->bt_info.reject_agg_pkt = *pu8;
+ break;
+
+ case BTC_SET_BL_BT_CTRL_AGG_SIZE:
+ pBtCoexist->bt_info.bt_ctrl_agg_buf_size = *pu8;
+ break;
+
+ case BTC_SET_BL_INC_SCAN_DEV_NUM:
+ pBtCoexist->bt_info.increase_scan_dev_num = *pu8;
+ break;
+
+ case BTC_SET_BL_BT_TX_RX_MASK:
+ pBtCoexist->bt_info.bt_tx_rx_mask = *pu8;
+ break;
+
+ case BTC_SET_BL_MIRACAST_PLUS_BT:
+ pBtCoexist->bt_info.miracast_plus_bt = *pu8;
+ break;
+
+ /* set some u8 type variables. */
+ case BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON:
+ pBtCoexist->bt_info.rssi_adjust_for_agc_table_on = *pU1Tmp;
+ break;
+
+ case BTC_SET_U1_AGG_BUF_SIZE:
+ pBtCoexist->bt_info.agg_buf_size = *pU1Tmp;
+ break;
+
+ /* the following are some action which will be triggered */
+ case BTC_SET_ACT_GET_BT_RSSI:
+ ret = false;
+ break;
+
+ case BTC_SET_ACT_AGGREGATE_CTRL:
+ halbtcoutsrc_AggregationCheck(pBtCoexist);
+ break;
+
+ /* =======1Ant=========== */
+ /* set some u8 type variables. */
+ case BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE:
+ pBtCoexist->bt_info.rssi_adjust_for_1ant_coex_type = *pU1Tmp;
+ break;
+
+ case BTC_SET_U1_LPS_VAL:
+ pBtCoexist->bt_info.lps_val = *pU1Tmp;
+ break;
+
+ case BTC_SET_U1_RPWM_VAL:
+ pBtCoexist->bt_info.rpwm_val = *pU1Tmp;
+ break;
+
+ /* the following are some action which will be triggered */
+ case BTC_SET_ACT_LEAVE_LPS:
+ halbtcoutsrc_LeaveLps(pBtCoexist);
+ break;
+
+ case BTC_SET_ACT_ENTER_LPS:
+ halbtcoutsrc_EnterLps(pBtCoexist);
+ break;
+
+ case BTC_SET_ACT_NORMAL_LPS:
+ halbtcoutsrc_NormalLps(pBtCoexist);
+ break;
+
+ case BTC_SET_ACT_DISABLE_LOW_POWER:
+ halbtcoutsrc_DisableLowPower(pBtCoexist, *pu8);
+ break;
+
+ case BTC_SET_ACT_UPDATE_RAMASK:
+ pBtCoexist->bt_info.ra_mask = *pU4Tmp;
+
+ if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == true) {
+ struct sta_info *psta;
+ PWLAN_BSSID_EX cur_network;
+
+ cur_network = &padapter->mlmeextpriv.mlmext_info.network;
+ psta = rtw_get_stainfo(&padapter->stapriv, cur_network->MacAddress);
+ rtw_hal_update_ra_mask(psta, psta->rssi_level, false);
+ }
+ break;
+
+ case BTC_SET_ACT_SEND_MIMO_PS: {
+ u8 newMimoPsMode = 3;
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ /* *pU1Tmp = 0 use SM_PS static type */
+ /* *pU1Tmp = 1 disable SM_PS */
+ if (*pU1Tmp == 0)
+ newMimoPsMode = WLAN_HT_CAP_SM_PS_STATIC;
+ else if (*pU1Tmp == 1)
+ newMimoPsMode = WLAN_HT_CAP_SM_PS_DISABLED;
+
+ if (check_fwstate(&padapter->mlmepriv , WIFI_ASOC_STATE) == true) {
+ /* issue_action_SM_PS(padapter, get_my_bssid(&(pmlmeinfo->network)), newMimoPsMode); */
+ issue_action_SM_PS_wait_ack(padapter , get_my_bssid(&(pmlmeinfo->network)) , newMimoPsMode, 3 , 1);
+ }
+ }
+ break;
+
+ case BTC_SET_ACT_CTRL_BT_INFO:
+#ifdef CONFIG_BT_COEXIST_SOCKET_TRX
+ {
+ u8 dataLen = *pU1Tmp;
+ u8 tmpBuf[BTC_TMP_BUF_SHORT];
+ if (dataLen)
+ memcpy(tmpBuf, pU1Tmp + 1, dataLen);
+ BT_SendEventExtBtInfoControl(padapter, dataLen, &tmpBuf[0]);
+ }
+#else /* !CONFIG_BT_COEXIST_SOCKET_TRX */
+ ret = false;
+#endif /* CONFIG_BT_COEXIST_SOCKET_TRX */
+ break;
+
+ case BTC_SET_ACT_CTRL_BT_COEX:
+#ifdef CONFIG_BT_COEXIST_SOCKET_TRX
+ {
+ u8 dataLen = *pU1Tmp;
+ u8 tmpBuf[BTC_TMP_BUF_SHORT];
+ if (dataLen)
+ memcpy(tmpBuf, pU1Tmp + 1, dataLen);
+ BT_SendEventExtBtCoexControl(padapter, false, dataLen, &tmpBuf[0]);
+ }
+#else /* !CONFIG_BT_COEXIST_SOCKET_TRX */
+ ret = false;
+#endif /* CONFIG_BT_COEXIST_SOCKET_TRX */
+ break;
+ case BTC_SET_ACT_CTRL_8723B_ANT:
+ ret = false;
+ break;
+ /* ===================== */
+ default:
+ ret = false;
+ break;
+ }
+
+ return ret;
+}
+
+u8 halbtcoutsrc_UnderIps(PBTC_COEXIST pBtCoexist)
+{
+ PADAPTER padapter;
+ struct pwrctrl_priv *pwrpriv;
+ u8 bMacPwrCtrlOn;
+
+ padapter = pBtCoexist->Adapter;
+ pwrpriv = &padapter->dvobj->pwrctl_priv;
+ bMacPwrCtrlOn = false;
+
+ if ((pwrpriv->bips_processing)
+ && (IPS_NONE != pwrpriv->ips_mode_req)
+ )
+ return true;
+
+ if (rf_off == pwrpriv->rf_pwrstate)
+ return true;
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if (false == bMacPwrCtrlOn)
+ return true;
+
+ return false;
+}
+
+u8 halbtcoutsrc_UnderLps(PBTC_COEXIST pBtCoexist)
+{
+ return GLBtcWiFiInLPS;
+}
+
+u8 halbtcoutsrc_Under32K(PBTC_COEXIST pBtCoexist)
+{
+ /* todo: the method to check whether wifi is under 32K or not */
+ return false;
+}
+
+void halbtcoutsrc_DisplayCoexStatistics(PBTC_COEXIST pBtCoexist)
+{
+ PADAPTER padapter = pBtCoexist->Adapter;
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+ u8 *cliBuf = pBtCoexist->cli_buf;
+
+ if (pHalData->EEPROMBluetoothCoexist == 1) {
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Coex Status]============");
+ CL_PRINTF(cliBuf);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "IsBtDisabled", rtw_btcoex_IsBtDisabled(padapter));
+ CL_PRINTF(cliBuf);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "IsBtControlLps", rtw_btcoex_IsBtControlLps(padapter));
+ CL_PRINTF(cliBuf);
+ }
+}
+
+void halbtcoutsrc_DisplayBtLinkInfo(PBTC_COEXIST pBtCoexist)
+{
+}
+
+void halbtcoutsrc_DisplayWifiStatus(PBTC_COEXIST pBtCoexist)
+{
+ PADAPTER padapter = pBtCoexist->Adapter;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+ u8 *cliBuf = pBtCoexist->cli_buf;
+ s32 wifiRssi = 0, btHsRssi = 0;
+ bool bScan = false, bLink = false, bRoam = false, bWifiBusy = false, bWifiUnderBMode = false;
+ u32 wifiBw = BTC_WIFI_BW_HT20, wifiTrafficDir = BTC_WIFI_TRAFFIC_TX, wifiFreq = BTC_FREQ_2_4G;
+ u32 wifiLinkStatus = 0x0;
+ bool bBtHsOn = false, bLowPower = false;
+ u8 wifiChnl = 0, wifiP2PChnl = 0, nScanAPNum = 0, FwPSState;
+ u32 iqk_cnt_total = 0, iqk_cnt_ok = 0, iqk_cnt_fail = 0;
+
+ wifiLinkStatus = halbtcoutsrc_GetWifiLinkStatus(pBtCoexist);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d/ %d", "STA/vWifi/HS/p2pGo/p2pGc", \
+ ((wifiLinkStatus & WIFI_STA_CONNECTED) ? 1 : 0), ((wifiLinkStatus & WIFI_AP_CONNECTED) ? 1 : 0),
+ ((wifiLinkStatus & WIFI_HS_CONNECTED) ? 1 : 0), ((wifiLinkStatus & WIFI_P2P_GO_CONNECTED) ? 1 : 0),
+ ((wifiLinkStatus & WIFI_P2P_GC_CONNECTED) ? 1 : 0));
+ CL_PRINTF(cliBuf);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink);
+ 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);
+
+ 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);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_IQK_FAIL, &iqk_cnt_fail);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d %s %s",
+ "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_PRINTF(cliBuf);
+ }
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiChnl);
+ if ((wifiLinkStatus & WIFI_P2P_GO_CONNECTED) || (wifiLinkStatus & WIFI_P2P_GC_CONNECTED))
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U1_WIFI_P2P_CHNL, &wifiP2PChnl);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d dBm/ %d/ %d", "RSSI/ STA_Chnl/ P2P_Chnl", \
+ wifiRssi -100, wifiChnl, wifiP2PChnl);
+ CL_PRINTF(cliBuf);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifiFreq);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U1_AP_NUM, &nScanAPNum);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s/ %d ", "Band/ BW/ Traffic/ APCnt", \
+ GLBtcWifiFreqString[wifiFreq], ((bWifiUnderBMode) ? "11b" : GLBtcWifiBwString[wifiBw]),
+ ((!bWifiBusy) ? "idle" : ((BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) ? "uplink" : "downlink")),
+ nScanAPNum);
+ CL_PRINTF(cliBuf);
+
+ /* power status */
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s%s%s", "Power Status", \
+ ((halbtcoutsrc_UnderIps(pBtCoexist) == true) ? "IPS ON" : "IPS OFF"),
+ ((halbtcoutsrc_UnderLps(pBtCoexist) == true) ? ", LPS ON" : ", LPS OFF"),
+ ((halbtcoutsrc_Under32K(pBtCoexist) == true) ? ", 32k" : ""));
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x (0x%x/0x%x)", "Power mode cmd(lps/rpwm)", \
+ pBtCoexist->pwrModeVal[0], pBtCoexist->pwrModeVal[1],
+ pBtCoexist->pwrModeVal[2], pBtCoexist->pwrModeVal[3],
+ pBtCoexist->pwrModeVal[4], pBtCoexist->pwrModeVal[5],
+ pBtCoexist->bt_info.lps_val,
+ pBtCoexist->bt_info.rpwm_val);
+ CL_PRINTF(cliBuf);
+}
+
+void halbtcoutsrc_DisplayDbgMsg(void *pBtcContext, u8 dispType)
+{
+ PBTC_COEXIST pBtCoexist;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ switch (dispType) {
+ case BTC_DBG_DISP_COEX_STATISTICS:
+ halbtcoutsrc_DisplayCoexStatistics(pBtCoexist);
+ break;
+ case BTC_DBG_DISP_BT_LINK_INFO:
+ halbtcoutsrc_DisplayBtLinkInfo(pBtCoexist);
+ break;
+ case BTC_DBG_DISP_WIFI_STATUS:
+ halbtcoutsrc_DisplayWifiStatus(pBtCoexist);
+ break;
+ default:
+ break;
+ }
+}
+
+/* ************************************
+ * IO related function
+ * ************************************ */
+u8 halbtcoutsrc_Read1Byte(void *pBtcContext, u32 RegAddr)
+{
+ PBTC_COEXIST pBtCoexist;
+ PADAPTER padapter;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ padapter = pBtCoexist->Adapter;
+
+ return rtw_read8(padapter, RegAddr);
+}
+
+u16 halbtcoutsrc_Read2Byte(void *pBtcContext, u32 RegAddr)
+{
+ PBTC_COEXIST pBtCoexist;
+ PADAPTER padapter;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ padapter = pBtCoexist->Adapter;
+
+ return rtw_read16(padapter, RegAddr);
+}
+
+u32 halbtcoutsrc_Read4Byte(void *pBtcContext, u32 RegAddr)
+{
+ PBTC_COEXIST pBtCoexist;
+ PADAPTER padapter;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ padapter = pBtCoexist->Adapter;
+
+ return rtw_read32(padapter, RegAddr);
+}
+
+void halbtcoutsrc_Write1Byte(void *pBtcContext, u32 RegAddr, u8 Data)
+{
+ PBTC_COEXIST pBtCoexist;
+ PADAPTER padapter;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ padapter = pBtCoexist->Adapter;
+
+ rtw_write8(padapter, RegAddr, Data);
+}
+
+void halbtcoutsrc_BitMaskWrite1Byte(void *pBtcContext, u32 regAddr, u8 bitMask, u8 data1b)
+{
+ PBTC_COEXIST pBtCoexist;
+ PADAPTER padapter;
+ u8 originalValue, bitShift;
+ u8 i;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ padapter = pBtCoexist->Adapter;
+ originalValue = 0;
+ bitShift = 0;
+
+ if (bitMask != 0xff) {
+ originalValue = rtw_read8(padapter, regAddr);
+
+ for (i = 0; i <= 7; i++) {
+ if ((bitMask >> i) & 0x1)
+ break;
+ }
+ bitShift = i;
+
+ data1b = (originalValue & ~bitMask) | ((data1b << bitShift) & bitMask);
+ }
+
+ rtw_write8(padapter, regAddr, data1b);
+}
+
+void halbtcoutsrc_Write2Byte(void *pBtcContext, u32 RegAddr, u16 Data)
+{
+ PBTC_COEXIST pBtCoexist;
+ PADAPTER padapter;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ padapter = pBtCoexist->Adapter;
+
+ rtw_write16(padapter, RegAddr, Data);
+}
+
+void halbtcoutsrc_Write4Byte(void *pBtcContext, u32 RegAddr, u32 Data)
+{
+ PBTC_COEXIST pBtCoexist;
+ PADAPTER padapter;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ padapter = pBtCoexist->Adapter;
+
+ rtw_write32(padapter, RegAddr, Data);
+}
+
+void halbtcoutsrc_WriteLocalReg1Byte(void *pBtcContext, u32 RegAddr, u8 Data)
+{
+ PBTC_COEXIST pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ PADAPTER Adapter = pBtCoexist->Adapter;
+
+ if (BTC_INTF_SDIO == pBtCoexist->chip_interface)
+ rtw_write8(Adapter, SDIO_LOCAL_BASE | RegAddr, Data);
+ else
+ rtw_write8(Adapter, RegAddr, Data);
+}
+
+void halbtcoutsrc_SetBbReg(void *pBtcContext, u32 RegAddr, u32 BitMask, u32 Data)
+{
+ PBTC_COEXIST pBtCoexist;
+ PADAPTER padapter;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ padapter = pBtCoexist->Adapter;
+
+ phy_set_bb_reg(padapter, RegAddr, BitMask, Data);
+}
+
+
+u32 halbtcoutsrc_GetBbReg(void *pBtcContext, u32 RegAddr, u32 BitMask)
+{
+ PBTC_COEXIST pBtCoexist;
+ PADAPTER padapter;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ padapter = pBtCoexist->Adapter;
+
+ return phy_query_bb_reg(padapter, RegAddr, BitMask);
+}
+
+void halbtcoutsrc_SetRfReg(void *pBtcContext, u8 eRFPath, u32 RegAddr, u32 BitMask, u32 Data)
+{
+ PBTC_COEXIST pBtCoexist;
+ PADAPTER padapter;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ padapter = pBtCoexist->Adapter;
+
+ phy_set_rf_reg(padapter, eRFPath, RegAddr, BitMask, Data);
+}
+
+u32 halbtcoutsrc_GetRfReg(void *pBtcContext, u8 eRFPath, u32 RegAddr, u32 BitMask)
+{
+ PBTC_COEXIST pBtCoexist;
+ PADAPTER padapter;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ padapter = pBtCoexist->Adapter;
+
+ return phy_query_rf_reg(padapter, eRFPath, RegAddr, BitMask);
+}
+
+u16 halbtcoutsrc_SetBtReg(void *pBtcContext, u8 RegType, u32 RegAddr, u32 Data)
+{
+ PBTC_COEXIST pBtCoexist;
+ u16 ret = BT_STATUS_BT_OP_SUCCESS;
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+
+ if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == true) {
+ u8 buf[3] = {0};
+ unsigned long irqL;
+ u8 op_code;
+ u8 status;
+
+ _enter_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+ Data = cpu_to_le32(Data);
+ op_code = BT_OP_WRITE_REG_VALUE;
+ status = _btmpoper_cmd(pBtCoexist, op_code, 0, (u8 *)&Data, 3);
+ if (status != BT_STATUS_BT_OP_SUCCESS)
+ ret = SET_BT_MP_OPER_RET(op_code, status);
+ else {
+ buf[0] = RegType;
+ *(u16 *)(buf + 1) = cpu_to_le16((u16)RegAddr);
+ op_code = BT_OP_WRITE_REG_ADDR;
+ status = _btmpoper_cmd(pBtCoexist, op_code, 0, buf, 3);
+ if (status != BT_STATUS_BT_OP_SUCCESS)
+ ret = SET_BT_MP_OPER_RET(op_code, status);
+ }
+
+ _exit_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+ } else
+ ret = BT_STATUS_NOT_IMPLEMENT;
+
+ return ret;
+}
+
+u8 halbtcoutsrc_SetBtAntDetection(void *pBtcContext, u8 txTime, u8 btChnl)
+{
+ /* Always return false since we don't implement this yet */
+ return false;
+}
+
+bool
+halbtcoutsrc_SetBtTRXMASK(
+ IN void * pBtcContext,
+ IN u8 bt_trx_mask
+ )
+{
+ /* Always return false since we don't implement this yet */
+ return false;
+}
+
+u16 halbtcoutsrc_GetBtReg_with_status(void *pBtcContext, u8 RegType, u32 RegAddr, u32 *data)
+{
+ PBTC_COEXIST pBtCoexist;
+ u16 ret = BT_STATUS_BT_OP_SUCCESS;
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+
+ if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == true) {
+ u8 buf[3] = {0};
+ unsigned long irqL;
+ u8 op_code;
+ u8 status;
+
+ buf[0] = RegType;
+ *(u16 *)(buf + 1) = cpu_to_le16((u16)RegAddr);
+
+ _enter_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+ op_code = BT_OP_READ_REG;
+ status = _btmpoper_cmd(pBtCoexist, op_code, 0, buf, 3);
+ if (status == BT_STATUS_BT_OP_SUCCESS)
+ *data = le16_to_cpu(*(u16 *)GLBtcBtMpRptRsp);
+ else
+ ret = SET_BT_MP_OPER_RET(op_code, status);
+
+ _exit_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+ } else
+ ret = BT_STATUS_NOT_IMPLEMENT;
+
+ return ret;
+}
+
+u32 halbtcoutsrc_GetBtReg(void *pBtcContext, u8 RegType, u32 RegAddr)
+{
+ u32 regVal;
+
+ return (BT_STATUS_BT_OP_SUCCESS == halbtcoutsrc_GetBtReg_with_status(pBtcContext, RegType, RegAddr, &regVal)) ? regVal : 0xffffffff;
+}
+
+void halbtcoutsrc_FillH2cCmd(void *pBtcContext, u8 elementId, u32 cmdLen, u8 *pCmdBuffer)
+{
+ PBTC_COEXIST pBtCoexist;
+ PADAPTER padapter;
+
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+ padapter = pBtCoexist->Adapter;
+
+ rtw_hal_fill_h2c_cmd(padapter, elementId, cmdLen, pCmdBuffer);
+}
+
+static void halbtcoutsrc_coex_offload_init(void)
+{
+ u8 i;
+
+ gl_coex_offload.h2c_req_num = 0;
+ gl_coex_offload.cnt_h2c_sent = 0;
+ gl_coex_offload.cnt_c2h_ack = 0;
+ gl_coex_offload.cnt_c2h_ind = 0;
+
+ for (i = 0; i < COL_MAX_H2C_REQ_NUM; i++)
+ init_completion(&gl_coex_offload.c2h_event[i]);
+}
+
+static COL_H2C_STATUS halbtcoutsrc_send_h2c(PADAPTER Adapter, PCOL_H2C pcol_h2c, u16 h2c_cmd_len)
+{
+ COL_H2C_STATUS h2c_status = COL_STATUS_C2H_OK;
+ u8 i;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
+ reinit_completion(&gl_coex_offload.c2h_event[pcol_h2c->req_num]); /* set event to un signaled state */
+#else
+ INIT_COMPLETION(gl_coex_offload.c2h_event[pcol_h2c->req_num]);
+#endif
+
+ return h2c_status;
+}
+
+static COL_H2C_STATUS halbtcoutsrc_check_c2h_ack(PADAPTER Adapter, PCOL_SINGLE_H2C_RECORD pH2cRecord)
+{
+ COL_H2C_STATUS c2h_status = COL_STATUS_C2H_OK;
+ PCOL_H2C p_h2c_cmd = (PCOL_H2C)&pH2cRecord->h2c_buf[0];
+ u8 req_num = p_h2c_cmd->req_num;
+ PCOL_C2H_ACK p_c2h_ack = (PCOL_C2H_ACK)&gl_coex_offload.c2h_ack_buf[req_num];
+
+
+ if ((COL_C2H_ACK_HDR_LEN + p_c2h_ack->ret_len) > gl_coex_offload.c2h_ack_len[req_num]) {
+ c2h_status = COL_STATUS_COEX_DATA_OVERFLOW;
+ return c2h_status;
+ }
+ /* else */
+ {
+ memmove(&pH2cRecord->c2h_ack_buf[0], &gl_coex_offload.c2h_ack_buf[req_num], gl_coex_offload.c2h_ack_len[req_num]);
+ pH2cRecord->c2h_ack_len = gl_coex_offload.c2h_ack_len[req_num];
+ }
+
+
+ if (p_c2h_ack->req_num != p_h2c_cmd->req_num) {
+ c2h_status = COL_STATUS_C2H_REQ_NUM_MISMATCH;
+ } else if (p_c2h_ack->opcode_ver != p_h2c_cmd->opcode_ver) {
+ c2h_status = COL_STATUS_C2H_OPCODE_VER_MISMATCH;
+ } else {
+ c2h_status = p_c2h_ack->status;
+ }
+
+ return c2h_status;
+}
+
+COL_H2C_STATUS halbtcoutsrc_CoexH2cProcess(void *pBtCoexist,
+ u8 opcode, u8 opcode_ver, u8 *ph2c_par, u8 h2c_par_len)
+{
+ PADAPTER Adapter = ((struct btc_coexist *)pBtCoexist)->Adapter;
+ u8 H2C_Parameter[BTC_TMP_BUF_SHORT] = {0};
+ PCOL_H2C pcol_h2c = (PCOL_H2C)&H2C_Parameter[0];
+ u16 paraLen = 0;
+ COL_H2C_STATUS h2c_status = COL_STATUS_C2H_OK, c2h_status = COL_STATUS_C2H_OK;
+ COL_H2C_STATUS ret_status = COL_STATUS_C2H_OK;
+ u16 i, col_h2c_len = 0;
+
+ pcol_h2c->opcode = opcode;
+ pcol_h2c->opcode_ver = opcode_ver;
+ pcol_h2c->req_num = gl_coex_offload.h2c_req_num;
+ gl_coex_offload.h2c_req_num++;
+ gl_coex_offload.h2c_req_num %= 16;
+
+ memmove(&pcol_h2c->buf[0], ph2c_par, h2c_par_len);
+
+
+ col_h2c_len = h2c_par_len + 2; /* 2=sizeof(OPCode, OPCode_version and Request number) */
+ BT_PrintData(Adapter, "[COL], H2C cmd: ", col_h2c_len, H2C_Parameter);
+
+ gl_coex_offload.cnt_h2c_sent++;
+
+ gl_coex_offload.h2c_record[opcode].count++;
+ gl_coex_offload.h2c_record[opcode].h2c_len = col_h2c_len;
+ memmove((void *)&gl_coex_offload.h2c_record[opcode].h2c_buf[0], (void *)pcol_h2c, col_h2c_len);
+
+ h2c_status = halbtcoutsrc_send_h2c(Adapter, pcol_h2c, col_h2c_len);
+
+ gl_coex_offload.h2c_record[opcode].c2h_ack_len = 0;
+
+ if (COL_STATUS_C2H_OK == h2c_status) {
+ /* if reach here, it means H2C get the correct c2h response, */
+ c2h_status = halbtcoutsrc_check_c2h_ack(Adapter, &gl_coex_offload.h2c_record[opcode]);
+ ret_status = c2h_status;
+ } else {
+ /* check h2c status error, return error status code to upper layer. */
+ ret_status = h2c_status;
+ }
+ gl_coex_offload.h2c_record[opcode].status[ret_status]++;
+ gl_coex_offload.status[ret_status]++;
+
+ return ret_status;
+}
+
+u8 halbtcoutsrc_GetAntDetValFromBt(void *pBtcContext)
+{
+ /* Always return 0 since we don't implement this yet */
+ return 0;
+}
+
+u8 halbtcoutsrc_GetBleScanTypeFromBt(void *pBtcContext)
+{
+ PBTC_COEXIST pBtCoexist;
+ u32 ret = BT_STATUS_BT_OP_SUCCESS;
+ u8 data = 0;
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+
+ if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == true) {
+ u8 buf[3] = {0};
+ unsigned long irqL;
+ u8 op_code;
+ u8 status;
+
+
+ _enter_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+ op_code = BT_OP_GET_BT_BLE_SCAN_TYPE;
+ status = _btmpoper_cmd(pBtCoexist, op_code, 0, buf, 0);
+ if (status == BT_STATUS_BT_OP_SUCCESS)
+ data = *(u8 *)GLBtcBtMpRptRsp;
+ else
+ ret = SET_BT_MP_OPER_RET(op_code, status);
+
+ _exit_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+ } else
+ ret = BT_STATUS_NOT_IMPLEMENT;
+
+ return data;
+}
+
+u32 halbtcoutsrc_GetBleScanParaFromBt(void *pBtcContext, u8 scanType)
+{
+ PBTC_COEXIST pBtCoexist;
+ u32 ret = BT_STATUS_BT_OP_SUCCESS;
+ u32 data = 0;
+
+ pBtCoexist = (PBTC_COEXIST)pBtcContext;
+
+ if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == true) {
+ u8 buf[3] = {0};
+ unsigned long irqL;
+ u8 op_code;
+ u8 status;
+
+
+ _enter_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+ op_code = BT_OP_GET_BT_BLE_SCAN_PARA;
+ status = _btmpoper_cmd(pBtCoexist, op_code, 0, buf, 0);
+ if (status == BT_STATUS_BT_OP_SUCCESS)
+ data = le32_to_cpu(*(u32 *)GLBtcBtMpRptRsp);
+ else
+ ret = SET_BT_MP_OPER_RET(op_code, status);
+
+ _exit_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+ } else
+ ret = BT_STATUS_NOT_IMPLEMENT;
+
+ return data;
+}
+
+u8 halbtcoutsrc_GetBtAFHMapFromBt(void *pBtcContext, u8 mapType, u8 *afhMap)
+{
+ struct btc_coexist *pBtCoexist = (struct btc_coexist *)pBtcContext;
+ u8 buf[2] = {0};
+ unsigned long irqL;
+ u8 op_code;
+ u32 *AfhMapL = (u32 *)&(afhMap[0]);
+ u32 *AfhMapM = (u32 *)&(afhMap[4]);
+ u16 *AfhMapH = (u16 *)&(afhMap[8]);
+ u8 status;
+ u32 ret = BT_STATUS_BT_OP_SUCCESS;
+
+ if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == false)
+ return false;
+
+ buf[0] = 0;
+ buf[1] = mapType;
+
+ _enter_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+ op_code = BT_LO_OP_GET_AFH_MAP_L;
+ status = _btmpoper_cmd(pBtCoexist, op_code, 0, buf, 0);
+ if (status == BT_STATUS_BT_OP_SUCCESS)
+ *AfhMapL = le32_to_cpu(*(u32 *)GLBtcBtMpRptRsp);
+ else {
+ ret = SET_BT_MP_OPER_RET(op_code, status);
+ goto exit;
+ }
+
+ op_code = BT_LO_OP_GET_AFH_MAP_M;
+ status = _btmpoper_cmd(pBtCoexist, op_code, 0, buf, 0);
+ if (status == BT_STATUS_BT_OP_SUCCESS)
+ *AfhMapM = le32_to_cpu(*(u32 *)GLBtcBtMpRptRsp);
+ else {
+ ret = SET_BT_MP_OPER_RET(op_code, status);
+ goto exit;
+ }
+
+ op_code = BT_LO_OP_GET_AFH_MAP_H;
+ status = _btmpoper_cmd(pBtCoexist, op_code, 0, buf, 0);
+ if (status == BT_STATUS_BT_OP_SUCCESS)
+ *AfhMapH = le16_to_cpu(*(u16 *)GLBtcBtMpRptRsp);
+ else {
+ ret = SET_BT_MP_OPER_RET(op_code, status);
+ goto exit;
+ }
+
+exit:
+
+ _exit_critical_mutex(&GLBtcBtMpOperLock, &irqL);
+
+ return (ret == BT_STATUS_BT_OP_SUCCESS) ? true : false;
+}
+
+u32 halbtcoutsrc_GetPhydmVersion(void *pBtcContext)
+{
+ struct btc_coexist *pBtCoexist = (struct btc_coexist *)pBtcContext;
+ PADAPTER Adapter = pBtCoexist->Adapter;
+}
+
+void halbtcoutsrc_phydm_modify_RA_PCR_threshold(void *pBtcContext, u8 RA_offset_direction, u8 RA_threshold_offset)
+{
+ struct btc_coexist *pBtCoexist = (struct btc_coexist *)pBtcContext;
+
+/* switch to #if 0 in case the phydm version does not provide the function */
+ phydm_modify_RA_PCR_threshold(pBtCoexist->odm_priv, RA_offset_direction, RA_threshold_offset);
+}
+
+u32 halbtcoutsrc_phydm_query_PHY_counter(void *pBtcContext, u8 info_type)
+{
+ struct btc_coexist *pBtCoexist = (struct btc_coexist *)pBtcContext;
+
+/* switch to #if 0 in case the phydm version does not provide the function */
+ return phydm_cmn_info_query((struct PHY_DM_STRUCT *)pBtCoexist->odm_priv, (enum phydm_info_query_e)info_type);
+}
+
+/* ************************************
+ * Extern functions called by other module
+ * ************************************ */
+u8 EXhalbtcoutsrc_BindBtCoexWithAdapter(void *padapter)
+{
+ PBTC_COEXIST pBtCoexist = &GLBtCoexist;
+ u8 antNum = 1, chipType = 0, singleAntPath = 0;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA((PADAPTER)padapter);
+
+ if (pBtCoexist->bBinded)
+ return false;
+ else
+ pBtCoexist->bBinded = true;
+
+ pBtCoexist->statistics.cnt_bind++;
+
+ pBtCoexist->Adapter = padapter;
+ pBtCoexist->odm_priv = (void *)&(pHalData->odmpriv);
+
+ pBtCoexist->stack_info.profile_notified = false;
+
+ pBtCoexist->bt_info.bt_ctrl_agg_buf_size = false;
+ pBtCoexist->bt_info.agg_buf_size = 5;
+
+ pBtCoexist->bt_info.increase_scan_dev_num = false;
+ pBtCoexist->bt_info.miracast_plus_bt = false;
+
+ antNum = rtw_btcoex_get_pg_ant_num((PADAPTER)padapter);
+ EXhalbtcoutsrc_SetAntNum(BT_COEX_ANT_TYPE_PG, antNum);
+
+ if (antNum == 1) {
+ singleAntPath = rtw_btcoex_get_pg_single_ant_path((PADAPTER)padapter);
+ EXhalbtcoutsrc_SetSingleAntPath(singleAntPath);
+ }
+
+ /* set default antenna position to main port */
+ pBtCoexist->board_info.btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT;
+
+ pBtCoexist->board_info.btdm_ant_det_finish = false;
+ pBtCoexist->board_info.btdm_ant_num_by_ant_det = 1;
+
+ pBtCoexist->board_info.tfbga_package = rtw_btcoex_is_tfbga_package_type((PADAPTER)padapter);
+
+ pBtCoexist->board_info.rfe_type = rtw_btcoex_get_pg_rfe_type((PADAPTER)padapter);
+
+ pBtCoexist->board_info.ant_div_cfg = rtw_btcoex_get_ant_div_cfg((PADAPTER)padapter);
+
+ return true;
+}
+
+u8 EXhalbtcoutsrc_InitlizeVariables(void *padapter)
+{
+ PBTC_COEXIST pBtCoexist = &GLBtCoexist;
+
+ /* pBtCoexist->statistics.cntBind++; */
+
+ halbtcoutsrc_DbgInit();
+
+ halbtcoutsrc_coex_offload_init();
+
+ pBtCoexist->chip_interface = BTC_INTF_USB;
+
+ EXhalbtcoutsrc_BindBtCoexWithAdapter(padapter);
+
+ pBtCoexist->btc_read_1byte = halbtcoutsrc_Read1Byte;
+ pBtCoexist->btc_write_1byte = halbtcoutsrc_Write1Byte;
+ pBtCoexist->btc_write_1byte_bitmask = halbtcoutsrc_BitMaskWrite1Byte;
+ pBtCoexist->btc_read_2byte = halbtcoutsrc_Read2Byte;
+ pBtCoexist->btc_write_2byte = halbtcoutsrc_Write2Byte;
+ pBtCoexist->btc_read_4byte = halbtcoutsrc_Read4Byte;
+ pBtCoexist->btc_write_4byte = halbtcoutsrc_Write4Byte;
+ pBtCoexist->btc_write_local_reg_1byte = halbtcoutsrc_WriteLocalReg1Byte;
+
+ pBtCoexist->btc_set_bb_reg = halbtcoutsrc_SetBbReg;
+ pBtCoexist->btc_get_bb_reg = halbtcoutsrc_GetBbReg;
+
+ pBtCoexist->btc_set_rf_reg = halbtcoutsrc_SetRfReg;
+ pBtCoexist->btc_get_rf_reg = halbtcoutsrc_GetRfReg;
+
+ pBtCoexist->btc_fill_h2c = halbtcoutsrc_FillH2cCmd;
+ pBtCoexist->btc_disp_dbg_msg = halbtcoutsrc_DisplayDbgMsg;
+
+ pBtCoexist->btc_get = halbtcoutsrc_Get;
+ pBtCoexist->btc_set = halbtcoutsrc_Set;
+ pBtCoexist->btc_get_bt_reg = halbtcoutsrc_GetBtReg;
+ pBtCoexist->btc_set_bt_reg = halbtcoutsrc_SetBtReg;
+ pBtCoexist->btc_set_bt_ant_detection = halbtcoutsrc_SetBtAntDetection;
+ pBtCoexist->btc_set_bt_trx_mask = halbtcoutsrc_SetBtTRXMASK;
+ pBtCoexist->btc_coex_h2c_process = halbtcoutsrc_CoexH2cProcess;
+ pBtCoexist->btc_get_bt_coex_supported_feature = halbtcoutsrc_GetBtCoexSupportedFeature;
+ pBtCoexist->btc_get_bt_coex_supported_version= halbtcoutsrc_GetBtCoexSupportedVersion;
+ pBtCoexist->btc_get_ant_det_val_from_bt = halbtcoutsrc_GetAntDetValFromBt;
+ pBtCoexist->btc_get_ble_scan_type_from_bt = halbtcoutsrc_GetBleScanTypeFromBt;
+ pBtCoexist->btc_get_ble_scan_para_from_bt = halbtcoutsrc_GetBleScanParaFromBt;
+ pBtCoexist->btc_get_bt_afh_map_from_bt = halbtcoutsrc_GetBtAFHMapFromBt;
+ pBtCoexist->btc_get_bt_phydm_version = halbtcoutsrc_GetPhydmVersion;
+ pBtCoexist->btc_phydm_modify_RA_PCR_threshold = halbtcoutsrc_phydm_modify_RA_PCR_threshold;
+ pBtCoexist->btc_phydm_query_PHY_counter = halbtcoutsrc_phydm_query_PHY_counter;
+
+ pBtCoexist->cli_buf = &GLBtcDbgBuf[0];
+
+ GLBtcWiFiInScanState = false;
+
+ GLBtcWiFiInIQKState = false;
+
+ GLBtcWiFiInIPS = false;
+
+ GLBtcWiFiInLPS = false;
+
+ GLBtcBtCoexAliveRegistered = false;
+
+ /* BT Control H2C/C2H*/
+ GLBtcBtMpOperSeq = 0;
+ _rtw_mutex_init(&GLBtcBtMpOperLock);
+ _init_timer(&GLBtcBtMpOperTimer, ((PADAPTER)padapter)->pnetdev, _btmpoper_timer_hdl, pBtCoexist);
+ sema_init(&GLBtcBtMpRptSema, 0);
+ GLBtcBtMpRptSeq = 0;
+ GLBtcBtMpRptStatus = 0;
+ memset(GLBtcBtMpRptRsp, 0, C2H_MAX_SIZE);
+ GLBtcBtMpRptRspSize = 0;
+ GLBtcBtMpRptWait = 0;
+ GLBtcBtMpRptWiFiOK = 0;
+ GLBtcBtMpRptBTOK = 0;
+
+ return true;
+}
+
+void EXhalbtcoutsrc_PowerOnSetting(PBTC_COEXIST pBtCoexist)
+{
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ /* Power on setting function is only added in 8723B currently */
+ if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_power_on_setting(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_power_on_setting(pBtCoexist);
+ }
+
+ if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_power_on_setting(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_power_on_setting(pBtCoexist);
+ }
+
+ if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_power_on_setting(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_power_on_setting(pBtCoexist);
+ }
+
+ if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_power_on_setting(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_power_on_setting(pBtCoexist);
+ }
+}
+
+void EXhalbtcoutsrc_PreLoadFirmware(PBTC_COEXIST pBtCoexist)
+{
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ pBtCoexist->statistics.cnt_pre_load_firmware++;
+
+ if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_pre_load_firmware(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_pre_load_firmware(pBtCoexist);
+ }
+
+ if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_pre_load_firmware(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_pre_load_firmware(pBtCoexist);
+ }
+
+ if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_pre_load_firmware(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_pre_load_firmware(pBtCoexist);
+ }
+}
+
+void EXhalbtcoutsrc_init_hw_config(PBTC_COEXIST pBtCoexist, u8 bWifiOnly)
+{
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ pBtCoexist->statistics.cnt_init_hw_config++;
+
+ if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821a2ant_init_hw_config(pBtCoexist, bWifiOnly);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821a1ant_init_hw_config(pBtCoexist, bWifiOnly);
+ } else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_init_hw_config(pBtCoexist, bWifiOnly);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_init_hw_config(pBtCoexist, bWifiOnly);
+ } else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8703b1ant_init_hw_config(pBtCoexist, bWifiOnly);
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_init_hw_config(pBtCoexist, bWifiOnly);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_init_hw_config(pBtCoexist, bWifiOnly);
+ } else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8192e2ant_init_hw_config(pBtCoexist, bWifiOnly);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8192e1ant_init_hw_config(pBtCoexist, bWifiOnly);
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8812a2ant_init_hw_config(pBtCoexist, bWifiOnly);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8812a1ant_init_hw_config(pBtCoexist, bWifiOnly);
+ } else if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_init_hw_config(pBtCoexist, bWifiOnly);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_init_hw_config(pBtCoexist, bWifiOnly);
+ #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
+ rtw_hal_set_default_port_id_cmd(pBtCoexist->Adapter, 0);
+ rtw_hal_set_wifi_port_id_cmd(pBtCoexist->Adapter);
+ #endif
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_init_hw_config(pBtCoexist, bWifiOnly);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_init_hw_config(pBtCoexist, bWifiOnly);
+ #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
+ rtw_hal_set_default_port_id_cmd(pBtCoexist->Adapter, 0);
+ rtw_hal_set_wifi_port_id_cmd(pBtCoexist->Adapter);
+ #endif
+ }
+}
+
+void EXhalbtcoutsrc_init_coex_dm(PBTC_COEXIST pBtCoexist)
+{
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ pBtCoexist->statistics.cnt_init_coex_dm++;
+
+ if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821a2ant_init_coex_dm(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821a1ant_init_coex_dm(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_init_coex_dm(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_init_coex_dm(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8703b1ant_init_coex_dm(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_init_coex_dm(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_init_coex_dm(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8192e2ant_init_coex_dm(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8192e1ant_init_coex_dm(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8812a2ant_init_coex_dm(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8812a1ant_init_coex_dm(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_init_coex_dm(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_init_coex_dm(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_init_coex_dm(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_init_coex_dm(pBtCoexist);
+ }
+
+ pBtCoexist->initilized = true;
+}
+
+void EXhalbtcoutsrc_ips_notify(PBTC_COEXIST pBtCoexist, u8 type)
+{
+ u8 ipsType;
+
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ pBtCoexist->statistics.cnt_ips_notify++;
+ if (pBtCoexist->manual_control)
+ return;
+
+ if (IPS_NONE == type) {
+ ipsType = BTC_IPS_LEAVE;
+ GLBtcWiFiInIPS = false;
+ } else {
+ ipsType = BTC_IPS_ENTER;
+ GLBtcWiFiInIPS = true;
+ }
+
+ /* All notify is called in cmd thread, don't need to leave low power again
+ * halbtcoutsrc_LeaveLowPower(pBtCoexist); */
+
+ if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821a2ant_ips_notify(pBtCoexist, ipsType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821a1ant_ips_notify(pBtCoexist, ipsType);
+ } else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_ips_notify(pBtCoexist, ipsType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_ips_notify(pBtCoexist, ipsType);
+ } else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8703b1ant_ips_notify(pBtCoexist, ipsType);
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_ips_notify(pBtCoexist, ipsType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_ips_notify(pBtCoexist, ipsType);
+ } else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8192e2ant_ips_notify(pBtCoexist, ipsType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8192e1ant_ips_notify(pBtCoexist, ipsType);
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8812a2ant_ips_notify(pBtCoexist, ipsType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8812a1ant_ips_notify(pBtCoexist, ipsType);
+ } else if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_ips_notify(pBtCoexist, ipsType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_ips_notify(pBtCoexist, ipsType);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_ips_notify(pBtCoexist, ipsType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_ips_notify(pBtCoexist, ipsType);
+ }
+
+ /* halbtcoutsrc_NormalLowPower(pBtCoexist); */
+}
+
+void EXhalbtcoutsrc_lps_notify(PBTC_COEXIST pBtCoexist, u8 type)
+{
+ u8 lpsType;
+
+
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ pBtCoexist->statistics.cnt_lps_notify++;
+ if (pBtCoexist->manual_control)
+ return;
+
+ if (PS_MODE_ACTIVE == type) {
+ lpsType = BTC_LPS_DISABLE;
+ GLBtcWiFiInLPS = false;
+ } else {
+ lpsType = BTC_LPS_ENABLE;
+ GLBtcWiFiInLPS = true;
+ }
+
+ if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821a2ant_lps_notify(pBtCoexist, lpsType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821a1ant_lps_notify(pBtCoexist, lpsType);
+ } else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_lps_notify(pBtCoexist, lpsType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_lps_notify(pBtCoexist, lpsType);
+ } else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8703b1ant_lps_notify(pBtCoexist, lpsType);
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_lps_notify(pBtCoexist, lpsType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_lps_notify(pBtCoexist, lpsType);
+ } else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8192e2ant_lps_notify(pBtCoexist, lpsType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8192e1ant_lps_notify(pBtCoexist, lpsType);
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8812a2ant_lps_notify(pBtCoexist, lpsType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8812a1ant_lps_notify(pBtCoexist, lpsType);
+ } else if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_lps_notify(pBtCoexist, lpsType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_lps_notify(pBtCoexist, lpsType);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_lps_notify(pBtCoexist, lpsType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_lps_notify(pBtCoexist, lpsType);
+ }
+}
+
+void EXhalbtcoutsrc_scan_notify(PBTC_COEXIST pBtCoexist, u8 type)
+{
+ u8 scanType;
+
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+ pBtCoexist->statistics.cnt_scan_notify++;
+ if (pBtCoexist->manual_control)
+ return;
+
+ if (type) {
+ scanType = BTC_SCAN_START;
+ GLBtcWiFiInScanState = true;
+ } else {
+ scanType = BTC_SCAN_FINISH;
+ GLBtcWiFiInScanState = false;
+ }
+
+ /* All notify is called in cmd thread, don't need to leave low power again
+ * halbtcoutsrc_LeaveLowPower(pBtCoexist); */
+
+ if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821a2ant_scan_notify(pBtCoexist, scanType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821a1ant_scan_notify(pBtCoexist, scanType);
+ } else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_scan_notify(pBtCoexist, scanType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_scan_notify(pBtCoexist, scanType);
+ } else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8703b1ant_scan_notify(pBtCoexist, scanType);
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_scan_notify(pBtCoexist, scanType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_scan_notify(pBtCoexist, scanType);
+ } else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8192e2ant_scan_notify(pBtCoexist, scanType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8192e1ant_scan_notify(pBtCoexist, scanType);
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8812a2ant_scan_notify(pBtCoexist, scanType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8812a1ant_scan_notify(pBtCoexist, scanType);
+ } else if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_scan_notify(pBtCoexist, scanType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_scan_notify(pBtCoexist, scanType);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_scan_notify(pBtCoexist, scanType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_scan_notify(pBtCoexist, scanType);
+ }
+
+ /* halbtcoutsrc_NormalLowPower(pBtCoexist); */
+}
+
+void EXhalbtcoutsrc_SetAntennaPathNotify(PBTC_COEXIST pBtCoexist, u8 type)
+{
+}
+
+void EXhalbtcoutsrc_connect_notify(PBTC_COEXIST pBtCoexist, u8 action)
+{
+ u8 assoType;
+
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+ pBtCoexist->statistics.cnt_connect_notify++;
+ if (pBtCoexist->manual_control)
+ return;
+
+ if (action)
+ assoType = BTC_ASSOCIATE_START;
+ else
+ assoType = BTC_ASSOCIATE_FINISH;
+
+ /* All notify is called in cmd thread, don't need to leave low power again
+ * halbtcoutsrc_LeaveLowPower(pBtCoexist); */
+
+ if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821a2ant_connect_notify(pBtCoexist, assoType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821a1ant_connect_notify(pBtCoexist, assoType);
+ } else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_connect_notify(pBtCoexist, assoType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_connect_notify(pBtCoexist, assoType);
+ } else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8703b1ant_connect_notify(pBtCoexist, assoType);
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_connect_notify(pBtCoexist, assoType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_connect_notify(pBtCoexist, assoType);
+ } else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8192e2ant_connect_notify(pBtCoexist, assoType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8192e1ant_connect_notify(pBtCoexist, assoType);
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8812a2ant_connect_notify(pBtCoexist, assoType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8812a1ant_connect_notify(pBtCoexist, assoType);
+ } else if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_connect_notify(pBtCoexist, assoType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_connect_notify(pBtCoexist, assoType);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_connect_notify(pBtCoexist, assoType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_connect_notify(pBtCoexist, assoType);
+ }
+
+ /* halbtcoutsrc_NormalLowPower(pBtCoexist); */
+}
+
+void EXhalbtcoutsrc_media_status_notify(PBTC_COEXIST pBtCoexist, RT_MEDIA_STATUS mediaStatus)
+{
+ u8 mStatus;
+
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ pBtCoexist->statistics.cnt_media_status_notify++;
+ if (pBtCoexist->manual_control)
+ return;
+
+ if (RT_MEDIA_CONNECT == mediaStatus)
+ mStatus = BTC_MEDIA_CONNECT;
+ else
+ mStatus = BTC_MEDIA_DISCONNECT;
+
+ /* All notify is called in cmd thread, don't need to leave low power again
+ * halbtcoutsrc_LeaveLowPower(pBtCoexist); */
+
+ if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821a2ant_media_status_notify(pBtCoexist, mStatus);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821a1ant_media_status_notify(pBtCoexist, mStatus);
+ } else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_media_status_notify(pBtCoexist, mStatus);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_media_status_notify(pBtCoexist, mStatus);
+ } else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8703b1ant_media_status_notify(pBtCoexist, mStatus);
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_media_status_notify(pBtCoexist, mStatus);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_media_status_notify(pBtCoexist, mStatus);
+ } else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8192e2ant_media_status_notify(pBtCoexist, mStatus);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8192e1ant_media_status_notify(pBtCoexist, mStatus);
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8812a2ant_media_status_notify(pBtCoexist, mStatus);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8812a1ant_media_status_notify(pBtCoexist, mStatus);
+ } else if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_media_status_notify(pBtCoexist, mStatus);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_media_status_notify(pBtCoexist, mStatus);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_media_status_notify(pBtCoexist, mStatus);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_media_status_notify(pBtCoexist, mStatus);
+ }
+
+ /* halbtcoutsrc_NormalLowPower(pBtCoexist); */
+}
+
+void EXhalbtcoutsrc_specific_packet_notify(PBTC_COEXIST pBtCoexist, u8 pktType)
+{
+ u8 packetType;
+
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+ pBtCoexist->statistics.cnt_specific_packet_notify++;
+ if (pBtCoexist->manual_control)
+ return;
+
+ if (PACKET_DHCP == pktType)
+ packetType = BTC_PACKET_DHCP;
+ else if (PACKET_EAPOL == pktType)
+ packetType = BTC_PACKET_EAPOL;
+ else if (PACKET_ARP == pktType)
+ packetType = BTC_PACKET_ARP;
+ else {
+ packetType = BTC_PACKET_UNKNOWN;
+ return;
+ }
+
+ /* All notify is called in cmd thread, don't need to leave low power again
+ * halbtcoutsrc_LeaveLowPower(pBtCoexist); */
+
+ if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821a2ant_specific_packet_notify(pBtCoexist, packetType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821a1ant_specific_packet_notify(pBtCoexist, packetType);
+ } else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_specific_packet_notify(pBtCoexist, packetType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_specific_packet_notify(pBtCoexist, packetType);
+ } else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8703b1ant_specific_packet_notify(pBtCoexist, packetType);
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_specific_packet_notify(pBtCoexist, packetType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_specific_packet_notify(pBtCoexist, packetType);
+ } else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8192e2ant_specific_packet_notify(pBtCoexist, packetType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8192e1ant_specific_packet_notify(pBtCoexist, packetType);
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8812a2ant_specific_packet_notify(pBtCoexist, packetType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8812a1ant_specific_packet_notify(pBtCoexist, packetType);
+ } else if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_specific_packet_notify(pBtCoexist, packetType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_specific_packet_notify(pBtCoexist, packetType);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_specific_packet_notify(pBtCoexist, packetType);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_specific_packet_notify(pBtCoexist, packetType);
+ }
+
+ /* halbtcoutsrc_NormalLowPower(pBtCoexist); */
+}
+
+void EXhalbtcoutsrc_bt_info_notify(PBTC_COEXIST pBtCoexist, u8 *tmpBuf, u8 length)
+{
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ pBtCoexist->statistics.cnt_bt_info_notify++;
+
+ /* All notify is called in cmd thread, don't need to leave low power again
+ * halbtcoutsrc_LeaveLowPower(pBtCoexist); */
+
+ if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821a2ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821a1ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ } else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ } else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8703b1ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ } else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8192e2ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8192e1ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8812a2ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8812a1ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ } else if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_bt_info_notify(pBtCoexist, tmpBuf, length);
+ }
+
+ /* halbtcoutsrc_NormalLowPower(pBtCoexist); */
+}
+
+void
+EXhalbtcoutsrc_RfStatusNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u8 type
+)
+{
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+ pBtCoexist->statistics.cnt_rf_status_notify++;
+
+ if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) {
+ } else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_rf_status_notify(pBtCoexist, type);
+ } else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8703b1ant_rf_status_notify(pBtCoexist, type);
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_rf_status_notify(pBtCoexist, type);
+ } else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ } else if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_rf_status_notify(pBtCoexist, type);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_rf_status_notify(pBtCoexist, type);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_rf_status_notify(pBtCoexist, type);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_rf_status_notify(pBtCoexist, type);
+ }
+}
+
+void EXhalbtcoutsrc_StackOperationNotify(PBTC_COEXIST pBtCoexist, u8 type)
+{
+}
+
+void EXhalbtcoutsrc_halt_notify(PBTC_COEXIST pBtCoexist)
+{
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821a2ant_halt_notify(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821a1ant_halt_notify(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_halt_notify(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_halt_notify(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8703b1ant_halt_notify(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_halt_notify(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_halt_notify(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8192e2ant_halt_notify(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8192e1ant_halt_notify(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8812a2ant_halt_notify(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8812a1ant_halt_notify(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_halt_notify(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_halt_notify(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_halt_notify(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_halt_notify(pBtCoexist);
+ }
+}
+
+void EXhalbtcoutsrc_SwitchBtTRxMask(PBTC_COEXIST pBtCoexist)
+{
+ if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2) {
+ halbtcoutsrc_SetBtReg(pBtCoexist, 0, 0x3c, 0x01); /* BT goto standby while GNT_BT 1-->0 */
+ } else if (pBtCoexist->board_info.btdm_ant_num == 1) {
+ halbtcoutsrc_SetBtReg(pBtCoexist, 0, 0x3c, 0x15); /* BT goto standby while GNT_BT 1-->0 */
+ }
+ }
+}
+
+void EXhalbtcoutsrc_pnp_notify(PBTC_COEXIST pBtCoexist, u8 pnpState)
+{
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ /* */
+ /* currently only 1ant we have to do the notification, */
+ /* once pnp is notified to sleep state, we have to leave LPS that we can sleep normally. */
+ /* */
+
+ if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_pnp_notify(pBtCoexist, pnpState);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_pnp_notify(pBtCoexist, pnpState);
+ } else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8703b1ant_pnp_notify(pBtCoexist, pnpState);
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_pnp_notify(pBtCoexist, pnpState);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_pnp_notify(pBtCoexist, pnpState);
+ } else if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821a1ant_pnp_notify(pBtCoexist, pnpState);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821a2ant_pnp_notify(pBtCoexist, pnpState);
+ } else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8192e1ant_pnp_notify(pBtCoexist, pnpState);
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8812a1ant_pnp_notify(pBtCoexist, pnpState);
+ } else if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_pnp_notify(pBtCoexist, pnpState);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_pnp_notify(pBtCoexist, pnpState);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_pnp_notify(pBtCoexist, pnpState);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_pnp_notify(pBtCoexist, pnpState);
+ }
+}
+
+void EXhalbtcoutsrc_CoexDmSwitch(PBTC_COEXIST pBtCoexist)
+{
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+ pBtCoexist->statistics.cnt_coex_dm_switch++;
+
+ halbtcoutsrc_LeaveLowPower(pBtCoexist);
+
+ if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1) {
+ pBtCoexist->stop_coex_dm = true;
+ ex_halbtc8723b1ant_coex_dm_reset(pBtCoexist);
+ EXhalbtcoutsrc_SetAntNum(BT_COEX_ANT_TYPE_DETECTED, 2);
+ ex_halbtc8723b2ant_init_hw_config(pBtCoexist, false);
+ ex_halbtc8723b2ant_init_coex_dm(pBtCoexist);
+ pBtCoexist->stop_coex_dm = false;
+ }
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1) {
+ pBtCoexist->stop_coex_dm = true;
+ ex_halbtc8723d1ant_coex_dm_reset(pBtCoexist);
+ EXhalbtcoutsrc_SetAntNum(BT_COEX_ANT_TYPE_DETECTED, 2);
+ ex_halbtc8723d2ant_init_hw_config(pBtCoexist, false);
+ ex_halbtc8723d2ant_init_coex_dm(pBtCoexist);
+ pBtCoexist->stop_coex_dm = false;
+ }
+ }
+
+ halbtcoutsrc_NormalLowPower(pBtCoexist);
+}
+
+void EXhalbtcoutsrc_periodical(PBTC_COEXIST pBtCoexist)
+{
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+ pBtCoexist->statistics.cnt_periodical++;
+
+ /* Periodical should be called in cmd thread, */
+ /* don't need to leave low power again
+ * halbtcoutsrc_LeaveLowPower(pBtCoexist); */
+
+ if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821a2ant_periodical(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1) {
+ if (!halbtcoutsrc_UnderIps(pBtCoexist))
+ ex_halbtc8821a1ant_periodical(pBtCoexist);
+ }
+ } else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_periodical(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_periodical(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_periodical(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_periodical(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8703b1ant_periodical(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8192e2ant_periodical(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8192e1ant_periodical(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8812a2ant_periodical(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8812a1ant_periodical(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_periodical(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_periodical(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_periodical(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_periodical(pBtCoexist);
+ }
+
+ /* halbtcoutsrc_NormalLowPower(pBtCoexist); */
+}
+
+void EXhalbtcoutsrc_dbg_control(PBTC_COEXIST pBtCoexist, u8 opCode, u8 opLen, u8 *pData)
+{
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ pBtCoexist->statistics.cnt_dbg_ctrl++;
+
+ /* This function doesn't be called yet, */
+ /* default no need to leave low power to avoid deadlock
+ * halbtcoutsrc_LeaveLowPower(pBtCoexist); */
+
+ if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8192e1ant_dbg_control(pBtCoexist, opCode, opLen, pData);
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8812a2ant_dbg_control(pBtCoexist, opCode, opLen, pData);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8812a1ant_dbg_control(pBtCoexist, opCode, opLen, pData);
+ } else if(IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter))
+ if(pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_dbg_control(pBtCoexist, opCode, opLen, pData);
+
+ /* halbtcoutsrc_NormalLowPower(pBtCoexist); */
+}
+
+void EXhalbtcoutsrc_StackUpdateProfileInfo(void)
+{
+#ifdef CONFIG_BT_COEXIST_SOCKET_TRX
+ PBTC_COEXIST pBtCoexist = &GLBtCoexist;
+ PADAPTER padapter = (PADAPTER)GLBtCoexist.Adapter;
+ PBT_MGNT pBtMgnt = &padapter->coex_info.BtMgnt;
+ u8 i;
+
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ pBtCoexist->stack_info.profile_notified = true;
+
+ pBtCoexist->stack_info.num_of_link =
+ pBtMgnt->ExtConfig.NumberOfACL + pBtMgnt->ExtConfig.NumberOfSCO;
+
+ /* reset first */
+ pBtCoexist->stack_info.bt_link_exist = false;
+ pBtCoexist->stack_info.sco_exist = false;
+ pBtCoexist->stack_info.acl_exist = false;
+ pBtCoexist->stack_info.a2dp_exist = false;
+ pBtCoexist->stack_info.hid_exist = false;
+ pBtCoexist->stack_info.num_of_hid = 0;
+ pBtCoexist->stack_info.pan_exist = false;
+
+ if (!pBtMgnt->ExtConfig.NumberOfACL)
+ pBtCoexist->stack_info.min_bt_rssi = 0;
+
+ if (pBtCoexist->stack_info.num_of_link) {
+ pBtCoexist->stack_info.bt_link_exist = true;
+ if (pBtMgnt->ExtConfig.NumberOfSCO)
+ pBtCoexist->stack_info.sco_exist = true;
+ if (pBtMgnt->ExtConfig.NumberOfACL)
+ pBtCoexist->stack_info.acl_exist = true;
+ }
+
+ for (i = 0; i < pBtMgnt->ExtConfig.NumberOfACL; i++) {
+ if (BT_PROFILE_A2DP == pBtMgnt->ExtConfig.aclLink[i].BTProfile)
+ pBtCoexist->stack_info.a2dp_exist = true;
+ else if (BT_PROFILE_PAN == pBtMgnt->ExtConfig.aclLink[i].BTProfile)
+ pBtCoexist->stack_info.pan_exist = true;
+ else if (BT_PROFILE_HID == pBtMgnt->ExtConfig.aclLink[i].BTProfile) {
+ pBtCoexist->stack_info.hid_exist = true;
+ pBtCoexist->stack_info.num_of_hid++;
+ } else
+ pBtCoexist->stack_info.unknown_acl_exist = true;
+ }
+#endif /* CONFIG_BT_COEXIST_SOCKET_TRX */
+}
+
+void EXhalbtcoutsrc_UpdateMinBtRssi(s8 btRssi)
+{
+ PBTC_COEXIST pBtCoexist = &GLBtCoexist;
+
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ pBtCoexist->stack_info.min_bt_rssi = btRssi;
+}
+
+void EXhalbtcoutsrc_SetHciVersion(u16 hciVersion)
+{
+ PBTC_COEXIST pBtCoexist = &GLBtCoexist;
+
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ pBtCoexist->stack_info.hci_version = hciVersion;
+}
+
+void EXhalbtcoutsrc_SetBtPatchVersion(u16 btHciVersion, u16 btPatchVersion)
+{
+ PBTC_COEXIST pBtCoexist = &GLBtCoexist;
+
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ pBtCoexist->bt_info.bt_real_fw_ver = btPatchVersion;
+ pBtCoexist->bt_info.bt_hci_ver = btHciVersion;
+}
+
+void EXhalbtcoutsrc_SetChipType(u8 chipType)
+{
+ switch (chipType) {
+ default:
+ case BT_2WIRE:
+ case BT_ISSC_3WIRE:
+ case BT_ACCEL:
+ case BT_RTL8756:
+ GLBtCoexist.board_info.bt_chip_type = BTC_CHIP_UNDEF;
+ break;
+ case BT_CSR_BC4:
+ GLBtCoexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC4;
+ break;
+ case BT_CSR_BC8:
+ GLBtCoexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC8;
+ break;
+ case BT_RTL8723A:
+ GLBtCoexist.board_info.bt_chip_type = BTC_CHIP_RTL8723A;
+ break;
+ case BT_RTL8821:
+ GLBtCoexist.board_info.bt_chip_type = BTC_CHIP_RTL8821;
+ break;
+ case BT_RTL8723B:
+ GLBtCoexist.board_info.bt_chip_type = BTC_CHIP_RTL8723B;
+ break;
+ }
+}
+
+void EXhalbtcoutsrc_SetAntNum(u8 type, u8 antNum)
+{
+ if (BT_COEX_ANT_TYPE_PG == type) {
+ GLBtCoexist.board_info.pg_ant_num = antNum;
+ GLBtCoexist.board_info.btdm_ant_num = antNum;
+ } else if (BT_COEX_ANT_TYPE_ANTDIV == type) {
+ GLBtCoexist.board_info.btdm_ant_num = antNum;
+ } else if (BT_COEX_ANT_TYPE_DETECTED == type) {
+ GLBtCoexist.board_info.btdm_ant_num = antNum;
+ }
+}
+
+/*
+ * Currently used by 8723b only, S0 or S1
+ * */
+void EXhalbtcoutsrc_SetSingleAntPath(u8 singleAntPath)
+{
+ GLBtCoexist.board_info.single_ant_path = singleAntPath;
+}
+
+void EXhalbtcoutsrc_DisplayBtCoexInfo(PBTC_COEXIST pBtCoexist)
+{
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ halbtcoutsrc_LeaveLowPower(pBtCoexist);
+
+ if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821a2ant_display_coex_info(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821a1ant_display_coex_info(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723b2ant_display_coex_info(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_display_coex_info(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8703b1ant_display_coex_info(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8723D(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8723d2ant_display_coex_info(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723d1ant_display_coex_info(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8192e2ant_display_coex_info(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8192e1ant_display_coex_info(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8812a2ant_display_coex_info(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8812a1ant_display_coex_info(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_display_coex_info(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_display_coex_info(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_display_coex_info(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_display_coex_info(pBtCoexist);
+ }
+
+ halbtcoutsrc_NormalLowPower(pBtCoexist);
+}
+
+void EXhalbtcoutsrc_DisplayAntDetection(PBTC_COEXIST pBtCoexist)
+{
+ if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ halbtcoutsrc_LeaveLowPower(pBtCoexist);
+
+ if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8723b1ant_display_ant_detection(pBtCoexist);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_display_ant_detection(pBtCoexist);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_display_ant_detection(pBtCoexist);
+ }
+
+ halbtcoutsrc_NormalLowPower(pBtCoexist);
+}
+
+void ex_halbtcoutsrc_pta_off_on_notify(PBTC_COEXIST pBtCoexist, u8 bBTON)
+{
+ if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8812a2ant_pta_off_on_notify(pBtCoexist, (bBTON == true) ? BTC_BT_ON : BTC_BT_OFF);
+ }
+}
+
+void EXhalbtcoutsrc_set_rfe_type(u8 type)
+{
+ GLBtCoexist.board_info.rfe_type= type;
+}
+
+void EXhalbtcoutsrc_switchband_notify(struct btc_coexist *pBtCoexist, u8 type)
+{
+ if(!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist))
+ return;
+
+ if(pBtCoexist->manual_control)
+ return;
+
+ /* Driver should guarantee that the HW status isn't in low power mode */
+ /* halbtcoutsrc_LeaveLowPower(pBtCoexist); */
+
+ if(IS_HARDWARE_TYPE_8822B(pBtCoexist->Adapter)) {
+ if(pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8822b1ant_switchband_notify(pBtCoexist, type);
+ else if(pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8822b2ant_switchband_notify(pBtCoexist, type);
+ } else if (IS_HARDWARE_TYPE_8821C(pBtCoexist->Adapter)) {
+ if (pBtCoexist->board_info.btdm_ant_num == 2)
+ ex_halbtc8821c2ant_switchband_notify(pBtCoexist, type);
+ else if (pBtCoexist->board_info.btdm_ant_num == 1)
+ ex_halbtc8821c1ant_switchband_notify(pBtCoexist, type);
+ }
+
+ /* halbtcoutsrc_NormalLowPower(pBtCoexist); */
+}
+
+static void halbt_init_hw_config92C(PADAPTER padapter)
+{
+ PHAL_DATA_TYPE pHalData;
+ u8 u1Tmp;
+
+
+ pHalData = GET_HAL_DATA(padapter);
+ if ((pHalData->bt_coexist.btChipType == BT_CSR_BC4) ||
+ (pHalData->bt_coexist.btChipType == BT_CSR_BC8)) {
+ if (pHalData->rf_type == RF_1T1R) {
+ /* Config to 1T1R */
+ u1Tmp = rtw_read8(padapter, rOFDM0_TRxPathEnable);
+ u1Tmp &= ~BIT(1);
+ rtw_write8(padapter, rOFDM0_TRxPathEnable, u1Tmp);
+ RT_DISP(FBT, BT_TRACE, ("[BTCoex], BT write 0xC04 = 0x%x\n", u1Tmp));
+
+ u1Tmp = rtw_read8(padapter, rOFDM1_TRxPathEnable);
+ u1Tmp &= ~BIT(1);
+ rtw_write8(padapter, rOFDM1_TRxPathEnable, u1Tmp);
+ RT_DISP(FBT, BT_TRACE, ("[BTCoex], BT write 0xD04 = 0x%x\n", u1Tmp));
+ }
+ }
+}
+
+static void halbt_init_hw_config92D(PADAPTER padapter)
+{
+ PHAL_DATA_TYPE pHalData;
+ u8 u1Tmp;
+
+ pHalData = GET_HAL_DATA(padapter);
+ if ((pHalData->bt_coexist.btChipType == BT_CSR_BC4) ||
+ (pHalData->bt_coexist.btChipType == BT_CSR_BC8)) {
+ if (pHalData->rf_type == RF_1T1R) {
+ /* Config to 1T1R */
+ u1Tmp = rtw_read8(padapter, rOFDM0_TRxPathEnable);
+ u1Tmp &= ~BIT(1);
+ rtw_write8(padapter, rOFDM0_TRxPathEnable, u1Tmp);
+ RT_DISP(FBT, BT_TRACE, ("[BTCoex], BT write 0xC04 = 0x%x\n", u1Tmp));
+
+ u1Tmp = rtw_read8(padapter, rOFDM1_TRxPathEnable);
+ u1Tmp &= ~BIT(1);
+ rtw_write8(padapter, rOFDM1_TRxPathEnable, u1Tmp);
+ RT_DISP(FBT, BT_TRACE, ("[BTCoex], BT write 0xD04 = 0x%x\n", u1Tmp));
+ }
+ }
+}
+
+/*
+ * Description:
+ * Run BT-Coexist mechansim or not
+ *
+ */
+void hal_btcoex_SetBTCoexist(PADAPTER padapter, u8 bBtExist)
+{
+ PHAL_DATA_TYPE pHalData;
+
+
+ pHalData = GET_HAL_DATA(padapter);
+ pHalData->bt_coexist.bBtExist = bBtExist;
+}
+
+/*
+ * Dewcription:
+ * Check is co-exist mechanism enabled or not
+ *
+ * Return:
+ * true Enable BT co-exist mechanism
+ * false Disable BT co-exist mechanism
+ */
+u8 hal_btcoex_IsBtExist(PADAPTER padapter)
+{
+ PHAL_DATA_TYPE pHalData;
+
+
+ pHalData = GET_HAL_DATA(padapter);
+ return pHalData->bt_coexist.bBtExist;
+}
+
+u8 hal_btcoex_IsBtDisabled(PADAPTER padapter)
+{
+ if (!hal_btcoex_IsBtExist(padapter))
+ return true;
+
+ if (GLBtCoexist.bt_info.bt_disabled)
+ return true;
+ else
+ return false;
+}
+
+void hal_btcoex_SetChipType(PADAPTER padapter, u8 chipType)
+{
+ PHAL_DATA_TYPE pHalData;
+
+ pHalData = GET_HAL_DATA(padapter);
+ pHalData->bt_coexist.btChipType = chipType;
+}
+
+void hal_btcoex_SetPgAntNum(PADAPTER padapter, u8 antNum)
+{
+ PHAL_DATA_TYPE pHalData;
+
+ pHalData = GET_HAL_DATA(padapter);
+
+ pHalData->bt_coexist.btTotalAntNum = antNum;
+}
+
+u8 hal_btcoex_Initialize(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ u8 ret;
+
+ memset(&GLBtCoexist, 0, sizeof(GLBtCoexist));
+
+ hal_btcoex_SetBTCoexist(padapter, rtw_btcoex_get_bt_coexist(padapter));
+ hal_btcoex_SetChipType(padapter, rtw_btcoex_get_chip_type(padapter));
+ hal_btcoex_SetPgAntNum(padapter, rtw_btcoex_get_pg_ant_num(padapter));
+
+ ret = EXhalbtcoutsrc_InitlizeVariables((void *)padapter);
+
+ return ret;
+}
+
+void hal_btcoex_PowerOnSetting(PADAPTER padapter)
+{
+ EXhalbtcoutsrc_PowerOnSetting(&GLBtCoexist);
+}
+
+void hal_btcoex_PreLoadFirmware(PADAPTER padapter)
+{
+ EXhalbtcoutsrc_PreLoadFirmware(&GLBtCoexist);
+}
+
+void hal_btcoex_InitHwConfig(PADAPTER padapter, u8 bWifiOnly)
+{
+ if (!hal_btcoex_IsBtExist(padapter))
+ return;
+
+ EXhalbtcoutsrc_init_hw_config(&GLBtCoexist, bWifiOnly);
+ EXhalbtcoutsrc_init_coex_dm(&GLBtCoexist);
+}
+
+void hal_btcoex_IpsNotify(PADAPTER padapter, u8 type)
+{
+ EXhalbtcoutsrc_ips_notify(&GLBtCoexist, type);
+}
+
+void hal_btcoex_LpsNotify(PADAPTER padapter, u8 type)
+{
+ EXhalbtcoutsrc_lps_notify(&GLBtCoexist, type);
+}
+
+void hal_btcoex_ScanNotify(PADAPTER padapter, u8 type)
+{
+ EXhalbtcoutsrc_scan_notify(&GLBtCoexist, type);
+}
+
+void hal_btcoex_ConnectNotify(PADAPTER padapter, u8 action)
+{
+ EXhalbtcoutsrc_connect_notify(&GLBtCoexist, action);
+}
+
+void hal_btcoex_MediaStatusNotify(PADAPTER padapter, u8 mediaStatus)
+{
+ EXhalbtcoutsrc_media_status_notify(&GLBtCoexist, mediaStatus);
+}
+
+void hal_btcoex_SpecialPacketNotify(PADAPTER padapter, u8 pktType)
+{
+ EXhalbtcoutsrc_specific_packet_notify(&GLBtCoexist, pktType);
+}
+
+void hal_btcoex_IQKNotify(PADAPTER padapter, u8 state)
+{
+ GLBtcWiFiInIQKState = state;
+}
+
+void hal_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)
+{
+ if (GLBtcWiFiInIQKState == true)
+ return;
+
+ EXhalbtcoutsrc_bt_info_notify(&GLBtCoexist, tmpBuf, length);
+}
+
+void hal_btcoex_BtMpRptNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)
+{
+ u8 extid, status, len, seq;
+
+
+ if (!GLBtcBtMpRptWait)
+ return;
+
+ if ((length < 3) || (!tmpBuf))
+ return;
+
+ extid = tmpBuf[0];
+ /* not response from BT FW then exit*/
+ switch (extid) {
+ case C2H_WIFI_FW_ACTIVE_RSP:
+ GLBtcBtMpRptWiFiOK = 1;
+ return;
+
+ case C2H_TRIG_BY_BT_FW:
+ _cancel_timer_ex(&GLBtcBtMpOperTimer);
+ GLBtcBtMpRptWait = 0;
+ GLBtcBtMpRptBTOK = 1;
+ break;
+
+ default:
+ return;
+ }
+
+ status = tmpBuf[1] & 0xF;
+ len = length - 3;
+ seq = tmpBuf[2] >> 4;
+
+ GLBtcBtMpRptSeq = seq;
+ GLBtcBtMpRptStatus = status;
+ memcpy(GLBtcBtMpRptRsp, tmpBuf + 3, len);
+ GLBtcBtMpRptRspSize = len;
+ up(&GLBtcBtMpRptSema);
+}
+
+void hal_btcoex_SuspendNotify(PADAPTER padapter, u8 state)
+{
+ switch (state) {
+ case BTCOEX_SUSPEND_STATE_SUSPEND:
+ EXhalbtcoutsrc_pnp_notify(&GLBtCoexist, BTC_WIFI_PNP_SLEEP);
+ break;
+ case BTCOEX_SUSPEND_STATE_SUSPEND_KEEP_ANT:
+ /* should switch to "#if 1" once all ICs' coex. revision are upgraded to support the KEEP_ANT case */
+ EXhalbtcoutsrc_pnp_notify(&GLBtCoexist, BTC_WIFI_PNP_SLEEP);
+ EXhalbtcoutsrc_pnp_notify(&GLBtCoexist, BTC_WIFI_PNP_SLEEP_KEEP_ANT);
+ break;
+ case BTCOEX_SUSPEND_STATE_RESUME:
+ EXhalbtcoutsrc_pnp_notify(&GLBtCoexist, BTC_WIFI_PNP_WAKE_UP);
+ break;
+ }
+}
+
+void hal_btcoex_HaltNotify(PADAPTER padapter, u8 do_halt)
+{
+ if (do_halt == 1)
+ EXhalbtcoutsrc_halt_notify(&GLBtCoexist);
+
+ GLBtCoexist.bBinded = false;
+ GLBtCoexist.Adapter = NULL;
+}
+
+void hal_btcoex_SwitchBtTRxMask(PADAPTER padapter)
+{
+ EXhalbtcoutsrc_SwitchBtTRxMask(&GLBtCoexist);
+}
+
+void hal_btcoex_Hanlder(PADAPTER padapter)
+{
+ u32 bt_patch_ver;
+
+ EXhalbtcoutsrc_periodical(&GLBtCoexist);
+
+ if (GLBtCoexist.bt_info.bt_get_fw_ver == 0) {
+ GLBtCoexist.btc_get(&GLBtCoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver);
+ GLBtCoexist.bt_info.bt_get_fw_ver = bt_patch_ver;
+ }
+}
+
+s32 hal_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter)
+{
+ return (s32)GLBtCoexist.bt_info.reject_agg_pkt;
+}
+
+s32 hal_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER padapter)
+{
+ return (s32)GLBtCoexist.bt_info.bt_ctrl_agg_buf_size;
+}
+
+u32 hal_btcoex_GetAMPDUSize(PADAPTER padapter)
+{
+ return (u32)GLBtCoexist.bt_info.agg_buf_size;
+}
+
+void hal_btcoex_SetManualControl(PADAPTER padapter, u8 bmanual)
+{
+ GLBtCoexist.manual_control = bmanual;
+}
+
+u8 hal_btcoex_1Ant(PADAPTER padapter)
+{
+ if (hal_btcoex_IsBtExist(padapter) == false)
+ return false;
+
+ if (GLBtCoexist.board_info.btdm_ant_num == 1)
+ return true;
+
+ return false;
+}
+
+u8 hal_btcoex_IsBtControlLps(PADAPTER padapter)
+{
+ if (GLBtCoexist.bdontenterLPS == true)
+ return true;
+
+ if (hal_btcoex_IsBtExist(padapter) == false)
+ return false;
+
+ if (GLBtCoexist.bt_info.bt_disabled)
+ return false;
+
+ if (GLBtCoexist.bt_info.bt_ctrl_lps)
+ return true;
+
+ return false;
+}
+
+u8 hal_btcoex_IsLpsOn(PADAPTER padapter)
+{
+ if (GLBtCoexist.bdontenterLPS == true)
+ return false;
+
+ if (hal_btcoex_IsBtExist(padapter) == false)
+ return false;
+
+ if (GLBtCoexist.bt_info.bt_disabled)
+ return false;
+
+ if (GLBtCoexist.bt_info.bt_lps_on)
+ return true;
+
+ return false;
+}
+
+u8 hal_btcoex_RpwmVal(PADAPTER padapter)
+{
+ return GLBtCoexist.bt_info.rpwm_val;
+}
+
+u8 hal_btcoex_LpsVal(PADAPTER padapter)
+{
+ return GLBtCoexist.bt_info.lps_val;
+}
+
+u32 hal_btcoex_GetRaMask(PADAPTER padapter)
+{
+ if (!hal_btcoex_IsBtExist(padapter))
+ return 0;
+
+ if (GLBtCoexist.bt_info.bt_disabled)
+ return 0;
+
+ /* Modify by YiWei , suggest by Cosa and Jenyu
+ * Remove the limit antenna number , because 2 antenna case (ex: 8192eu)also want to get BT coex report rate mask.
+ */
+ /*if (GLBtCoexist.board_info.btdm_ant_num != 1)
+ return 0;*/
+
+ return GLBtCoexist.bt_info.ra_mask;
+}
+
+void hal_btcoex_RecordPwrMode(PADAPTER padapter, u8 *pCmdBuf, u8 cmdLen)
+{
+
+ memcpy(GLBtCoexist.pwrModeVal, pCmdBuf, cmdLen);
+}
+
+void hal_btcoex_DisplayBtCoexInfo(PADAPTER padapter, u8 *pbuf, u32 bufsize)
+{
+ PBTCDBGINFO pinfo;
+
+
+ pinfo = &GLBtcDbgInfo;
+ DBG_BT_INFO_INIT(pinfo, pbuf, bufsize);
+ EXhalbtcoutsrc_DisplayBtCoexInfo(&GLBtCoexist);
+ DBG_BT_INFO_INIT(pinfo, NULL, 0);
+}
+
+void hal_btcoex_SetDBG(PADAPTER padapter, u32 *pDbgModule)
+{
+ u32 i;
+
+
+ if (NULL == pDbgModule)
+ return;
+
+ for (i = 0; i < COMP_MAX; i++)
+ GLBtcDbgType[i] = pDbgModule[i];
+}
+
+u32 hal_btcoex_GetDBG(PADAPTER padapter, u8 *pStrBuf, u32 bufSize)
+{
+ s32 count;
+ u8 *pstr;
+ u32 leftSize;
+
+
+ if ((NULL == pStrBuf) || (0 == bufSize))
+ return 0;
+
+ count = 0;
+ pstr = pStrBuf;
+ leftSize = bufSize;
+ /* RTW_INFO(FUNC_ADPT_FMT ": bufsize=%d\n", FUNC_ADPT_ARG(padapter), bufSize); */
+
+ count = rtw_sprintf(pstr, leftSize, "#define DBG\t%d\n", DBG);
+ if ((count < 0) || (count >= leftSize))
+ goto exit;
+ pstr += count;
+ leftSize -= count;
+
+ count = rtw_sprintf(pstr, leftSize, "BTCOEX Debug Setting:\n");
+ if ((count < 0) || (count >= leftSize))
+ goto exit;
+ pstr += count;
+ leftSize -= count;
+
+ count = rtw_sprintf(pstr, leftSize,
+ "COMP_COEX: 0x%08X\n\n",
+ GLBtcDbgType[COMP_COEX]);
+ if ((count < 0) || (count >= leftSize))
+ goto exit;
+ pstr += count;
+ leftSize -= count;
+
+exit:
+ count = pstr - pStrBuf;
+ return count;
+}
+
+u8 hal_btcoex_IncreaseScanDeviceNum(PADAPTER padapter)
+{
+ if (!hal_btcoex_IsBtExist(padapter))
+ return false;
+
+ if (GLBtCoexist.bt_info.increase_scan_dev_num)
+ return true;
+
+ return false;
+}
+
+u8 hal_btcoex_IsBtLinkExist(PADAPTER padapter)
+{
+ if (GLBtCoexist.bt_link_info.bt_link_exist)
+ return true;
+
+ return false;
+}
+
+void hal_btcoex_SetBtPatchVersion(PADAPTER padapter, u16 btHciVer, u16 btPatchVer)
+{
+ EXhalbtcoutsrc_SetBtPatchVersion(btHciVer, btPatchVer);
+}
+
+void hal_btcoex_SetHciVersion(PADAPTER padapter, u16 hciVersion)
+{
+ EXhalbtcoutsrc_SetHciVersion(hciVersion);
+}
+
+void hal_btcoex_StackUpdateProfileInfo(void)
+{
+ EXhalbtcoutsrc_StackUpdateProfileInfo();
+}
+
+void hal_btcoex_pta_off_on_notify(PADAPTER padapter, u8 bBTON)
+{
+ ex_halbtcoutsrc_pta_off_on_notify(&GLBtCoexist, bBTON);
+}
+
+/*
+ * Description:
+ * Setting BT coex antenna isolation type .
+ * coex mechanisn/ spital stream/ best throughput
+ * anttype = 0 , PSTDMA / 2SS / 0.5T , bad isolation , WiFi/BT ANT Distance<15cm , (<20dB) for 2,3 antenna
+ * anttype = 1 , PSTDMA / 1SS / 0.5T , normal isolaiton , 50cm>WiFi/BT ANT Distance>15cm , (>20dB) for 2 antenna
+ * anttype = 2 , TDMA / 2SS / T , normal isolaiton , 50cm>WiFi/BT ANT Distance>15cm , (>20dB) for 3 antenna
+ * anttype = 3 , no TDMA / 1SS / 0.5T , good isolation , WiFi/BT ANT Distance >50cm , (>40dB) for 2 antenna
+ * anttype = 4 , no TDMA / 2SS / T , good isolation , WiFi/BT ANT Distance >50cm , (>40dB) for 3 antenna
+ * wifi only throughput ~ T
+ * wifi/BT share one antenna with SPDT
+ */
+void hal_btcoex_SetAntIsolationType(PADAPTER padapter, u8 anttype)
+{
+ PHAL_DATA_TYPE pHalData;
+ PBTC_COEXIST pBtCoexist = &GLBtCoexist;
+
+ /*RTW_INFO("####%s , anttype = %d , %d\n" , __func__ , anttype , __LINE__); */
+ pHalData = GET_HAL_DATA(padapter);
+
+
+ pHalData->bt_coexist.btAntisolation = anttype;
+
+ switch (pHalData->bt_coexist.btAntisolation) {
+ case 0:
+ pBtCoexist->board_info.ant_type = (u8)BTC_ANT_TYPE_0;
+ break;
+ case 1:
+ pBtCoexist->board_info.ant_type = (u8)BTC_ANT_TYPE_1;
+ break;
+ case 2:
+ pBtCoexist->board_info.ant_type = (u8)BTC_ANT_TYPE_2;
+ break;
+ case 3:
+ pBtCoexist->board_info.ant_type = (u8)BTC_ANT_TYPE_3;
+ break;
+ case 4:
+ pBtCoexist->board_info.ant_type = (u8)BTC_ANT_TYPE_4;
+ break;
+ }
+
+}
+
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+int
+hal_btcoex_ParseAntIsolationConfigFile(
+ PADAPTER Adapter,
+ char *buffer
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u32 i = 0 , j = 0;
+ char *szLine , *ptmp;
+ int rtStatus = _SUCCESS;
+ char param_value_string[10];
+ u8 param_value;
+ u8 anttype = 4;
+
+ u8 ant_num = 3 , ant_distance = 50 , rfe_type = 1;
+
+ typedef struct ant_isolation {
+ char *param_name; /* antenna isolation config parameter name */
+ u8 *value; /* antenna isolation config parameter value */
+ } ANT_ISOLATION;
+
+ ANT_ISOLATION ant_isolation_param[] = {
+ {"ANT_NUMBER" , &ant_num},
+ {"ANT_DISTANCE" , &ant_distance},
+ {"RFE_TYPE" , &rfe_type},
+ {NULL , 0}
+ };
+
+
+
+ /* RTW_INFO("===>Hal_ParseAntIsolationConfigFile()\n" ); */
+
+ ptmp = buffer;
+ for (szLine = GetLineFromBuffer(ptmp) ; szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
+ /* skip comment */
+ if (IsCommentString(szLine))
+ continue;
+
+ /* RTW_INFO("%s : szLine = %s , strlen(szLine) = %d\n" , __func__ , szLine , strlen(szLine));*/
+ for (j = 0 ; ant_isolation_param[j].param_name != NULL ; j++) {
+ if (strstr(szLine , ant_isolation_param[j].param_name) != NULL) {
+ i = 0;
+ while (i < strlen(szLine)) {
+ if (szLine[i] != '"')
+ ++i;
+ else {
+ /* skip only has one " */
+ if (strpbrk(szLine , "\"") == strrchr(szLine , '"')) {
+ RTW_INFO("Fail to parse parameters , format error!\n");
+ break;
+ }
+ memset((void *)param_value_string , 0 , 10);
+ if (!ParseQualifiedString(szLine , &i , param_value_string , '"' , '"')) {
+ RTW_INFO("Fail to parse parameters\n");
+ return _FAIL;
+ } else if (!GetU1ByteIntegerFromStringInDecimal(param_value_string , ant_isolation_param[j].value))
+ RTW_INFO("Fail to GetU1ByteIntegerFromStringInDecimal\n");
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* YiWei 20140716 , for BT coex antenna isolation control */
+ /* rfe_type = 0 was SPDT , rfe_type = 1 was coupler */
+ if (ant_num == 3 && ant_distance >= 50)
+ anttype = 3;
+ else if (ant_num == 2 && ant_distance >= 50 && rfe_type == 1)
+ anttype = 2;
+ else if (ant_num == 3 && ant_distance >= 15 && ant_distance < 50)
+ anttype = 2;
+ else if (ant_num == 2 && ant_distance >= 15 && ant_distance < 50 && rfe_type == 1)
+ anttype = 2;
+ else if ((ant_num == 2 && ant_distance < 15 && rfe_type == 1) || (ant_num == 3 && ant_distance < 15))
+ anttype = 1;
+ else if (ant_num == 2 && rfe_type == 0)
+ anttype = 0;
+ else
+ anttype = 0;
+
+ hal_btcoex_SetAntIsolationType(Adapter, anttype);
+
+ RTW_INFO("%s : ant_num = %d\n" , __func__ , ant_num);
+ RTW_INFO("%s : ant_distance = %d\n" , __func__ , ant_distance);
+ RTW_INFO("%s : rfe_type = %d\n" , __func__ , rfe_type);
+ /* RTW_INFO("<===Hal_ParseAntIsolationConfigFile()\n"); */
+ return rtStatus;
+}
+
+
+int
+hal_btcoex_AntIsolationConfig_ParaFile(
+ IN PADAPTER Adapter,
+ IN char *pFileName
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ int rlen = 0 , rtStatus = _FAIL;
+
+ memset(pHalData->para_file_buf , 0 , MAX_PARA_FILE_BUF_LEN);
+
+ rtw_get_phy_file_path(Adapter, pFileName);
+ if (rtw_is_file_readable(rtw_phy_para_file_path) == true) {
+ rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+ if (rlen > 0)
+ rtStatus = _SUCCESS;
+ }
+
+
+ if (rtStatus == _SUCCESS) {
+ /*RTW_INFO("%s(): read %s ok\n", __func__ , pFileName);*/
+ rtStatus = hal_btcoex_ParseAntIsolationConfigFile(Adapter , pHalData->para_file_buf);
+ } else
+ RTW_INFO("%s(): No File %s, Load from *** Array!\n" , __func__ , pFileName);
+
+ return rtStatus;
+}
+#endif /* CONFIG_LOAD_PHY_PARA_FROM_FILE */
+
+u16 hal_btcoex_btreg_read(PADAPTER padapter, u8 type, u16 addr, u32 *data)
+{
+ u16 ret = 0;
+
+ halbtcoutsrc_LeaveLowPower(&GLBtCoexist);
+
+ ret = halbtcoutsrc_GetBtReg_with_status(&GLBtCoexist, type, addr, data);
+
+ halbtcoutsrc_NormalLowPower(&GLBtCoexist);
+
+ return ret;
+}
+
+u16 hal_btcoex_btreg_write(PADAPTER padapter, u8 type, u16 addr, u16 val)
+{
+ u16 ret = 0;
+
+ halbtcoutsrc_LeaveLowPower(&GLBtCoexist);
+
+ ret = halbtcoutsrc_SetBtReg(&GLBtCoexist, type, addr, val);
+
+ halbtcoutsrc_NormalLowPower(&GLBtCoexist);
+
+ return ret;
+}
+
+void hal_btcoex_set_rfe_type(u8 type)
+{
+ EXhalbtcoutsrc_set_rfe_type(type);
+}
+void hal_btcoex_switchband_notify(u8 under_scan, u8 band_type)
+{
+ switch (band_type) {
+ case BAND_ON_2_4G:
+ if (under_scan)
+ EXhalbtcoutsrc_switchband_notify(&GLBtCoexist, BTC_SWITCH_TO_24G);
+ else
+ EXhalbtcoutsrc_switchband_notify(&GLBtCoexist, BTC_SWITCH_TO_24G_NOFORSCAN);
+ break;
+ case BAND_ON_5G:
+ EXhalbtcoutsrc_switchband_notify(&GLBtCoexist, BTC_SWITCH_TO_5G);
+ break;
+ default:
+ RTW_INFO("[BTCOEX] unkown switch band type\n");
+ break;
+ }
+}
+#endif /* CONFIG_BT_COEXIST */
diff --git a/drivers/staging/rtl8188eu/hal/hal_btcoex_wifionly.c b/drivers/staging/rtl8188eu/hal/hal_btcoex_wifionly.c
new file mode 100644
index 000000000000..856ebd55bfb8
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal_btcoex_wifionly.c
@@ -0,0 +1,131 @@
+#include "btc/mp_precomp.h"
+#include <hal_btcoex_wifionly.h>
+
+static struct wifi_only_cfg GLBtCoexistWifiOnly;
+
+void halwifionly_write1byte(void * pwifionlyContext, u32 RegAddr, u8 Data)
+{
+ struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
+ PADAPTER Adapter = pwifionlycfg->Adapter;
+
+ rtw_write8(Adapter, RegAddr, Data);
+}
+
+void halwifionly_write2byte(void * pwifionlyContext, u32 RegAddr, u16 Data)
+{
+ struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
+ PADAPTER Adapter = pwifionlycfg->Adapter;
+
+ rtw_write16(Adapter, RegAddr, Data);
+}
+
+void halwifionly_write4byte(void * pwifionlyContext, u32 RegAddr, u32 Data)
+{
+ struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
+ PADAPTER Adapter = pwifionlycfg->Adapter;
+
+ rtw_write32(Adapter, RegAddr, Data);
+}
+
+u8 halwifionly_read1byte(void * pwifionlyContext, u32 RegAddr)
+{
+ struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
+ PADAPTER Adapter = pwifionlycfg->Adapter;
+
+ return rtw_read8(Adapter, RegAddr);
+}
+
+u16 halwifionly_read2byte(void * pwifionlyContext, u32 RegAddr)
+{
+ struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
+ PADAPTER Adapter = pwifionlycfg->Adapter;
+
+ return rtw_read16(Adapter, RegAddr);
+}
+
+u32 halwifionly_read4byte(void * pwifionlyContext, u32 RegAddr)
+{
+ struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
+ PADAPTER Adapter = pwifionlycfg->Adapter;
+
+ return rtw_read32(Adapter, RegAddr);
+}
+
+void halwifionly_bitmaskwrite1byte(void * pwifionlyContext, u32 regAddr, u8 bitMask, u8 data)
+{
+ u8 originalValue, bitShift = 0;
+ u8 i;
+
+ struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
+ PADAPTER Adapter = pwifionlycfg->Adapter;
+
+ if (bitMask != 0xff) {
+ originalValue = rtw_read8(Adapter, regAddr);
+ for (i = 0; i <= 7; i++) {
+ if ((bitMask >> i) & 0x1)
+ break;
+ }
+ bitShift = i;
+ data = ((originalValue) & (~bitMask)) | (((data << bitShift)) & bitMask);
+ }
+ rtw_write8(Adapter, regAddr, data);
+}
+
+void halwifionly_phy_set_rf_reg(void * pwifionlyContext, u8 eRFPath, u32 RegAddr, u32 BitMask, u32 Data)
+{
+ struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
+ PADAPTER Adapter = pwifionlycfg->Adapter;
+
+ phy_set_rf_reg(Adapter, eRFPath, RegAddr, BitMask, Data);
+}
+
+void halwifionly_phy_set_bb_reg(void * pwifionlyContext, u32 RegAddr, u32 BitMask, u32 Data)
+{
+ struct wifi_only_cfg *pwifionlycfg = (struct wifi_only_cfg *)pwifionlyContext;
+ PADAPTER Adapter = pwifionlycfg->Adapter;
+
+ phy_set_bb_reg(Adapter, RegAddr, BitMask, Data);
+}
+
+void hal_btcoex_wifionly_switchband_notify(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ u8 is_5g = false;
+
+ if (pHalData->current_band_type == BAND_ON_5G)
+ is_5g = true;
+}
+
+void hal_btcoex_wifionly_scan_notify(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ u8 is_5g = false;
+
+ if (pHalData->current_band_type == BAND_ON_5G)
+ is_5g = true;
+}
+
+void hal_btcoex_wifionly_hw_config(PADAPTER padapter)
+{
+ struct wifi_only_cfg *pwifionlycfg = &GLBtCoexistWifiOnly;
+}
+
+void hal_btcoex_wifionly_initlizevariables(PADAPTER padapter)
+{
+ struct wifi_only_cfg *pwifionlycfg = &GLBtCoexistWifiOnly;
+ struct wifi_only_haldata *pwifionly_haldata = &pwifionlycfg->haldata_info;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ memset(&GLBtCoexistWifiOnly, 0, sizeof(GLBtCoexistWifiOnly));
+
+ pwifionlycfg->Adapter = padapter;
+
+ pwifionlycfg->chip_interface = WIFIONLY_INTF_USB;
+
+ pwifionly_haldata->customer_id = CUSTOMER_NORMAL;
+ pwifionly_haldata->efuse_pg_antnum = pHalData->EEPROMBluetoothAntNum;
+ pwifionly_haldata->efuse_pg_antpath = pHalData->ant_path;
+ pwifionly_haldata->rfe_type = pHalData->rfe_type;
+ pwifionly_haldata->ant_div_cfg = pHalData->AntDivCfg;
+}
+
diff --git a/drivers/staging/rtl8188eu/hal/hal_com.c b/drivers/staging/rtl8188eu/hal/hal_com.c
new file mode 100644
index 000000000000..4e632edd211f
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal_com.c
@@ -0,0 +1,10540 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _HAL_COM_C_
+
+#include <drv_types.h>
+#include "hal_com_h2c.h"
+
+#include "hal_data.h"
+
+#ifdef RTW_HALMAC
+#include "../../hal/hal_halmac.h"
+#endif
+
+void rtw_dump_fw_info(void *sel, _adapter *adapter)
+{
+ HAL_DATA_TYPE *hal_data = NULL;
+
+ if (!adapter)
+ return;
+
+ hal_data = GET_HAL_DATA(adapter);
+ if (adapter->bFWReady)
+ RTW_PRINT_SEL(sel, "FW VER -%d.%d\n", hal_data->firmware_version, hal_data->firmware_sub_version);
+ else
+ RTW_PRINT_SEL(sel, "FW not ready\n");
+}
+
+/* #define CONFIG_GTK_OL_DBG */
+
+/*#define DBG_SEC_CAM_MOVE*/
+#ifdef DBG_SEC_CAM_MOVE
+void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
+{
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ int cam_id, index = 0;
+ u8 *addr = NULL;
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
+ return;
+
+ addr = get_bssid(pmlmepriv);
+
+ if (addr == NULL) {
+ RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
+ return;
+ }
+
+ rtw_clean_dk_section(adapter);
+
+ do {
+ cam_id = rtw_camid_search(adapter, addr, index, 1);
+
+ if (cam_id == -1)
+ RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
+ else
+ rtw_sec_cam_swap(adapter, cam_id, index);
+
+ index++;
+ } while (index < 4);
+
+}
+
+void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
+{
+ struct security_priv *psecuritypriv = &adapter->securitypriv;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
+ unsigned long irqL;
+ u8 get_key[16];
+
+ memset(get_key, 0, sizeof(get_key));
+
+ if (key_id > 4) {
+ RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
+ rtw_warn_on(1);
+ return;
+ }
+ rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
+
+ /*update key into related sw variable*/
+ _enter_critical_bh(&cam_ctl->lock, &irqL);
+ if (_rtw_camid_is_gk(adapter, key_id)) {
+ RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
+ RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
+ }
+ _exit_critical_bh(&cam_ctl->lock, &irqL);
+
+}
+#endif
+
+
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+ char rtw_phy_para_file_path[PATH_LENGTH_MAX];
+#endif
+
+void dump_chip_info(HAL_VERSION ChipVersion)
+{
+ int cnt = 0;
+ u8 buf[128] = {0};
+
+ if (IS_8188E(ChipVersion))
+ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
+ else if (IS_8188F(ChipVersion))
+ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
+ else if (IS_8812_SERIES(ChipVersion))
+ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
+ else if (IS_8192E(ChipVersion))
+ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
+ else if (IS_8821_SERIES(ChipVersion))
+ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
+ else if (IS_8723B_SERIES(ChipVersion))
+ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
+ else if (IS_8703B_SERIES(ChipVersion))
+ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
+ else if (IS_8723D_SERIES(ChipVersion))
+ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
+ else if (IS_8814A_SERIES(ChipVersion))
+ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
+ else if (IS_8822B_SERIES(ChipVersion))
+ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
+ else if (IS_8821C_SERIES(ChipVersion))
+ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
+ else
+ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
+
+ cnt += sprintf((buf + cnt), "%s_", IS_NORMAL_CHIP(ChipVersion) ? "Normal_Chip" : "Test_Chip");
+ if (IS_CHIP_VENDOR_TSMC(ChipVersion))
+ cnt += sprintf((buf + cnt), "%s_", "TSMC");
+ else if (IS_CHIP_VENDOR_UMC(ChipVersion))
+ cnt += sprintf((buf + cnt), "%s_", "UMC");
+ else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
+ cnt += sprintf((buf + cnt), "%s_", "SMIC");
+
+ if (IS_A_CUT(ChipVersion))
+ cnt += sprintf((buf + cnt), "A_CUT_");
+ else if (IS_B_CUT(ChipVersion))
+ cnt += sprintf((buf + cnt), "B_CUT_");
+ else if (IS_C_CUT(ChipVersion))
+ cnt += sprintf((buf + cnt), "C_CUT_");
+ else if (IS_D_CUT(ChipVersion))
+ cnt += sprintf((buf + cnt), "D_CUT_");
+ else if (IS_E_CUT(ChipVersion))
+ cnt += sprintf((buf + cnt), "E_CUT_");
+ else if (IS_F_CUT(ChipVersion))
+ cnt += sprintf((buf + cnt), "F_CUT_");
+ else if (IS_I_CUT(ChipVersion))
+ cnt += sprintf((buf + cnt), "I_CUT_");
+ else if (IS_J_CUT(ChipVersion))
+ cnt += sprintf((buf + cnt), "J_CUT_");
+ else if (IS_K_CUT(ChipVersion))
+ cnt += sprintf((buf + cnt), "K_CUT_");
+ else
+ cnt += sprintf((buf + cnt), "UNKNOWN_CUT(%d)_", ChipVersion.CUTVersion);
+
+ if (IS_1T1R(ChipVersion))
+ cnt += sprintf((buf + cnt), "1T1R_");
+ else if (IS_1T2R(ChipVersion))
+ cnt += sprintf((buf + cnt), "1T2R_");
+ else if (IS_2T2R(ChipVersion))
+ cnt += sprintf((buf + cnt), "2T2R_");
+ else if (IS_3T3R(ChipVersion))
+ cnt += sprintf((buf + cnt), "3T3R_");
+ else if (IS_3T4R(ChipVersion))
+ cnt += sprintf((buf + cnt), "3T4R_");
+ else if (IS_4T4R(ChipVersion))
+ cnt += sprintf((buf + cnt), "4T4R_");
+ else
+ cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
+
+ cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
+
+ RTW_INFO("%s", buf);
+}
+void rtw_hal_config_rftype(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ if (IS_1T1R(pHalData->version_id)) {
+ pHalData->rf_type = RF_1T1R;
+ pHalData->NumTotalRFPath = 1;
+ } else if (IS_2T2R(pHalData->version_id)) {
+ pHalData->rf_type = RF_2T2R;
+ pHalData->NumTotalRFPath = 2;
+ } else if (IS_1T2R(pHalData->version_id)) {
+ pHalData->rf_type = RF_1T2R;
+ pHalData->NumTotalRFPath = 2;
+ } else if (IS_3T3R(pHalData->version_id)) {
+ pHalData->rf_type = RF_3T3R;
+ pHalData->NumTotalRFPath = 3;
+ } else if (IS_4T4R(pHalData->version_id)) {
+ pHalData->rf_type = RF_4T4R;
+ pHalData->NumTotalRFPath = 4;
+ } else {
+ pHalData->rf_type = RF_1T1R;
+ pHalData->NumTotalRFPath = 1;
+ }
+
+ RTW_INFO("%s RF_Type is %d TotalTxPath is %d\n", __func__, pHalData->rf_type, pHalData->NumTotalRFPath);
+}
+
+#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
+
+/*
+ * Description:
+ * Use hardware(efuse), driver parameter(registry) and default channel plan
+ * to decide which one should be used.
+ *
+ * Parameters:
+ * padapter pointer of adapter
+ * hw_alpha2 country code from HW (efuse/eeprom/mapfile)
+ * hw_chplan channel plan from HW (efuse/eeprom/mapfile)
+ * BIT[7] software configure mode; 0:Enable, 1:disable
+ * 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
+ *
+ * Return:
+ * Final channel plan decision
+ *
+ */
+u8 hal_com_config_channel_plan(
+ PADAPTER padapter,
+ char *hw_alpha2,
+ u8 hw_chplan,
+ char *sw_alpha2,
+ u8 sw_chplan,
+ u8 def_chplan,
+ bool AutoLoadFail
+)
+{
+ PHAL_DATA_TYPE pHalData;
+ u8 force_hw_chplan = false;
+ int chplan = -1;
+ const struct country_chplan *country_ent = NULL, *ent;
+
+ pHalData = GET_HAL_DATA(padapter);
+
+ /* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
+ if (hw_chplan == 0xFF)
+ goto chk_hw_country_code;
+
+ if (AutoLoadFail == true)
+ goto chk_sw_config;
+
+#ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
+ if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
+ force_hw_chplan = true;
+#endif
+
+ hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
+
+chk_hw_country_code:
+ if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
+ ent = rtw_get_chplan_from_country(hw_alpha2);
+ if (ent) {
+ /* get chplan from hw country code, by pass hw chplan setting */
+ country_ent = ent;
+ chplan = ent->chplan;
+ goto chk_sw_config;
+ } else
+ RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
+ }
+
+ if (rtw_is_channel_plan_valid(hw_chplan))
+ chplan = hw_chplan;
+ else if (force_hw_chplan == true) {
+ RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
+ /* hw infomaton invalid, refer to sw information */
+ force_hw_chplan = false;
+ }
+
+chk_sw_config:
+ if (force_hw_chplan == true)
+ goto done;
+
+ if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
+ ent = rtw_get_chplan_from_country(sw_alpha2);
+ if (ent) {
+ /* get chplan from sw country code, by pass sw chplan setting */
+ country_ent = ent;
+ chplan = ent->chplan;
+ goto done;
+ } else
+ RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
+ }
+
+ if (rtw_is_channel_plan_valid(sw_chplan)) {
+ /* cancel hw_alpha2 because chplan is specified by sw_chplan*/
+ country_ent = NULL;
+ chplan = sw_chplan;
+ } else if (sw_chplan != RTW_CHPLAN_MAX)
+ RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
+
+done:
+ if (chplan == -1) {
+ RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
+ chplan = def_chplan;
+ } else if (country_ent) {
+ RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
+ , country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
+ } else
+ RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
+
+ padapter->mlmepriv.country_ent = country_ent;
+ pHalData->bDisableSWChannelPlan = force_hw_chplan;
+
+ return chplan;
+}
+
+bool
+HAL_IsLegalChannel(
+ PADAPTER Adapter,
+ u32 Channel
+)
+{
+ bool bLegalChannel = true;
+
+ if (Channel > 14) {
+ if (is_supported_5g(Adapter->registrypriv.wireless_mode) == false) {
+ bLegalChannel = false;
+ RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
+ }
+ } else if ((Channel <= 14) && (Channel >= 1)) {
+ if (IsSupported24G(Adapter->registrypriv.wireless_mode) == false) {
+ bLegalChannel = false;
+ RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
+ }
+ } else {
+ bLegalChannel = false;
+ RTW_INFO("Channel is Invalid !!!\n");
+ }
+
+ return bLegalChannel;
+}
+
+u8 MRateToHwRate(u8 rate)
+{
+ u8 ret = DESC_RATE1M;
+
+ 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;
+
+ 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;
+
+ 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;
+}
+
+u8 hw_rate_to_m_rate(u8 rate)
+{
+ u8 ret_rate = MGN_1M;
+
+ switch (rate) {
+
+ 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;
+}
+
+void HalSetBrateCfg(
+ PADAPTER Adapter,
+ u8 *mBratesOS,
+ u16 *pBrateCfg)
+{
+ u8 i, is_brate, brate;
+
+ for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
+ is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
+ brate = mBratesOS[i] & 0x7f;
+
+ if (is_brate) {
+ switch (brate) {
+ case IEEE80211_CCK_RATE_1MB:
+ *pBrateCfg |= RATE_1M;
+ break;
+ case IEEE80211_CCK_RATE_2MB:
+ *pBrateCfg |= RATE_2M;
+ break;
+ case IEEE80211_CCK_RATE_5MB:
+ *pBrateCfg |= RATE_5_5M;
+ break;
+ case IEEE80211_CCK_RATE_11MB:
+ *pBrateCfg |= RATE_11M;
+ break;
+ case IEEE80211_OFDM_RATE_6MB:
+ *pBrateCfg |= RATE_6M;
+ break;
+ case IEEE80211_OFDM_RATE_9MB:
+ *pBrateCfg |= RATE_9M;
+ break;
+ case IEEE80211_OFDM_RATE_12MB:
+ *pBrateCfg |= RATE_12M;
+ break;
+ case IEEE80211_OFDM_RATE_18MB:
+ *pBrateCfg |= RATE_18M;
+ break;
+ case IEEE80211_OFDM_RATE_24MB:
+ *pBrateCfg |= RATE_24M;
+ break;
+ case IEEE80211_OFDM_RATE_36MB:
+ *pBrateCfg |= RATE_36M;
+ break;
+ case IEEE80211_OFDM_RATE_48MB:
+ *pBrateCfg |= RATE_48M;
+ break;
+ case IEEE80211_OFDM_RATE_54MB:
+ *pBrateCfg |= RATE_54M;
+ break;
+ }
+ }
+ }
+}
+
+static void
+_OneOutPipeMapping(
+ PADAPTER pAdapter
+)
+{
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
+
+ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
+ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
+ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
+ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
+
+ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
+ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
+ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
+ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
+}
+
+static void
+_TwoOutPipeMapping(
+ PADAPTER pAdapter,
+ bool bWIFICfg
+)
+{
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
+
+ if (bWIFICfg) { /* WMM */
+
+ /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
+ /* { 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */
+ /* 0:ep_0 num, 1:ep_1 num */
+
+ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
+ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
+ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
+ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
+
+ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
+ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
+ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
+ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
+
+ } else { /* typical setting */
+
+
+ /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
+ /* { 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */
+ /* 0:ep_0 num, 1:ep_1 num */
+
+ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
+ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
+ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
+ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
+
+ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
+ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
+ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
+ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
+
+ }
+
+}
+
+static void _ThreeOutPipeMapping(
+ PADAPTER pAdapter,
+ bool bWIFICfg
+)
+{
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
+
+ if (bWIFICfg) { /* for WMM */
+
+ /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
+ /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
+ /* 0:H, 1:N, 2:L */
+
+ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
+ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
+ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
+ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
+
+ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
+ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
+ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
+ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
+
+ } else { /* typical setting */
+
+
+ /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
+ /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
+ /* 0:H, 1:N, 2:L */
+
+ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
+ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
+ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
+ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
+
+ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
+ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
+ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
+ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
+ }
+
+}
+static void _FourOutPipeMapping(
+ PADAPTER pAdapter,
+ bool bWIFICfg
+)
+{
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
+
+ if (bWIFICfg) { /* for WMM */
+
+ /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
+ /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
+ /* 0:H, 1:N, 2:L ,3:E */
+
+ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
+ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
+ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
+ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
+
+ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
+ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
+ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
+ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
+
+ } else { /* typical setting */
+
+
+ /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
+ /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
+ /* 0:H, 1:N, 2:L */
+
+ pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
+ pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
+ pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
+ pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
+
+ pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
+ pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
+ pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
+ pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
+ }
+
+}
+bool
+Hal_MappingOutPipe(
+ PADAPTER pAdapter,
+ u8 NumOutPipe
+)
+{
+ struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
+
+ bool bWIFICfg = (pregistrypriv->wifi_spec) ? true : false;
+
+ bool result = true;
+
+ switch (NumOutPipe) {
+ case 2:
+ _TwoOutPipeMapping(pAdapter, bWIFICfg);
+ break;
+ case 3:
+ case 4:
+ _ThreeOutPipeMapping(pAdapter, bWIFICfg);
+ break;
+ case 1:
+ _OneOutPipeMapping(pAdapter);
+ break;
+ default:
+ result = false;
+ break;
+ }
+
+ return result;
+
+}
+
+void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
+{
+ if (padapter->hal_func.reqtxrpt)
+ padapter->hal_func.reqtxrpt(padapter, macid);
+}
+
+void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
+{
+ int i;
+ _adapter *iface;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ u8 mac_addr[ETH_ALEN];
+
+#ifdef CONFIG_MI_WITH_MBSSID_CAM
+ rtw_mbid_cam_dump(sel, __func__, adapter);
+#else
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if (iface) {
+ rtw_hal_get_macaddr_port(iface, mac_addr);
+ RTW_INFO(ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",
+ ADPT_ARG(iface), iface->hw_port, MAC_ARG(mac_addr));
+ }
+ }
+#endif
+}
+
+void rtw_restore_mac_addr(_adapter *adapter)
+{
+#ifdef CONFIG_MI_WITH_MBSSID_CAM
+ _adapter *iface;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+
+ rtw_mbid_cam_restore(adapter);
+#else
+ int i;
+ _adapter *iface;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if (iface)
+ rtw_hal_set_macaddr_port(iface, adapter_mac_addr(iface));
+ }
+#endif
+ if (1)
+ rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
+}
+
+void rtw_init_hal_com_default_value(PADAPTER Adapter)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
+ struct registry_priv *regsty = adapter_to_regsty(Adapter);
+
+ pHalData->AntDetection = 1;
+ pHalData->antenna_test = false;
+ pHalData->u1ForcedIgiLb = regsty->force_igi_lb;
+}
+
+#ifdef CONFIG_FW_C2H_REG
+void c2h_evt_clear(_adapter *adapter)
+{
+ rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
+}
+
+s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
+{
+ s32 ret = _FAIL;
+ int i;
+ u8 trigger;
+
+ if (buf == NULL)
+ goto exit;
+
+ trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
+
+ if (trigger == C2H_EVT_HOST_CLOSE) {
+ goto exit; /* Not ready */
+ } else if (trigger != C2H_EVT_FW_CLOSE) {
+ goto clear_evt; /* Not a valid value */
+ }
+
+ memset(buf, 0, C2H_REG_LEN);
+
+ /* Read ID, LEN, SEQ */
+ SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
+ SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
+ SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
+
+ if (0) {
+ RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
+ , C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
+ }
+
+ /* Read the content */
+ for (i = 0; i < C2H_PLEN_88XX(buf); i++)
+ *(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
+
+ RTW_DBG_DUMP("payload:\n", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
+
+ ret = _SUCCESS;
+
+clear_evt:
+ /*
+ * Clear event to notify FW we have read the command.
+ * If this field isn't clear, the FW won't update the next command message.
+ */
+ c2h_evt_clear(adapter);
+
+exit:
+ return ret;
+}
+#endif /* CONFIG_FW_C2H_REG */
+
+#ifdef CONFIG_FW_C2H_PKT
+#ifndef DBG_C2H_PKT_PRE_HDL
+#define DBG_C2H_PKT_PRE_HDL 0
+#endif
+#ifndef DBG_C2H_PKT_HDL
+#define DBG_C2H_PKT_HDL 0
+#endif
+void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
+{
+#ifdef RTW_HALMAC
+ /* TODO: extract hal_mac IC's code here*/
+#else
+ u8 parse_fail = 0;
+ u8 hdl_here = 0;
+ s32 ret = _FAIL;
+ u8 id, seq, plen;
+ u8 *payload;
+
+ if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
+ parse_fail = 1;
+ goto exit;
+ }
+
+ hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == true ? 1 : 0;
+ if (hdl_here)
+ ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
+ else
+ ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
+
+exit:
+ if (parse_fail)
+ RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
+ else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
+ RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
+ , hdl_here ? "handle" : "enqueue"
+ , ret == _SUCCESS ? "ok" : "fail"
+ );
+ if (DBG_C2H_PKT_PRE_HDL >= 2)
+ RTW_PRINT_DUMP("dump: ", buf, len);
+ }
+#endif
+}
+
+void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
+{
+#ifdef RTW_HALMAC
+ adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
+#else
+ u8 parse_fail = 0;
+ u8 bypass = 0;
+ s32 ret = _FAIL;
+ u8 id, seq, plen;
+ u8 *payload;
+
+ if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
+ parse_fail = 1;
+ goto exit;
+ }
+
+#ifdef CONFIG_WOWLAN
+ if (adapter_to_pwrctl(adapter)->wowlan_mode == true) {
+ bypass = 1;
+ ret = _SUCCESS;
+ goto exit;
+ }
+#endif
+
+ ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
+
+exit:
+ if (parse_fail)
+ RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
+ else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
+ RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
+ , !bypass ? "handle" : "bypass"
+ , ret == _SUCCESS ? "ok" : "fail"
+ );
+ if (DBG_C2H_PKT_HDL >= 2)
+ RTW_PRINT_DUMP("dump: ", buf, len);
+ }
+#endif
+}
+#endif /* CONFIG_FW_C2H_PKT */
+
+void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
+
+ RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
+ if (0)
+ RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
+
+ rtw_sctx_done(&iqk_sctx);
+}
+
+int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
+
+ iqk_sctx->submit_time = jiffies;
+ iqk_sctx->timeout_ms = timeout_ms;
+ iqk_sctx->status = RTW_SCTX_SUBMITTED;
+
+ return rtw_sctx_wait(iqk_sctx, __func__);
+}
+
+#define GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
+#define GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
+#define GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
+#define GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
+#define GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
+#define GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
+#define GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
+#define GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
+#define GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
+#define GET_C2H_MAC_HIDDEN_RPT_BW(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
+#define GET_C2H_MAC_HIDDEN_RPT_FAB(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 3, 2)
+#define GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
+#define GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
+#define GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
+
+#ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
+#define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
+#endif
+
+#ifdef CONFIG_RTW_MAC_HIDDEN_RPT
+int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ int ret = _FAIL;
+
+ u32 uuid;
+ u8 uuid_x;
+ u8 uuid_y;
+ u8 uuid_z;
+ u16 uuid_crc;
+
+ u8 hci_type;
+ u8 package_type;
+ u8 tr_switch;
+ u8 wl_func;
+ u8 hw_stype;
+ u8 bw;
+ u8 fab;
+ u8 ant_num;
+ u8 protocol;
+ u8 nic;
+
+ int i;
+
+ if (len < MAC_HIDDEN_RPT_LEN) {
+ RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
+ goto exit;
+ }
+
+ uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
+ uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
+ uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
+ uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
+
+ hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
+ package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
+
+ tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
+
+ wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
+ hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
+
+ bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
+ fab = GET_C2H_MAC_HIDDEN_RPT_FAB(data);
+ ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
+
+ protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
+ nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
+
+ if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
+ for (i = 0; i < len; i++)
+ RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
+
+ RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
+ RTW_PRINT("hci_type:0x%x\n", hci_type);
+ RTW_PRINT("package_type:0x%x\n", package_type);
+ RTW_PRINT("tr_switch:0x%x\n", tr_switch);
+ RTW_PRINT("wl_func:0x%x\n", wl_func);
+ RTW_PRINT("hw_stype:0x%x\n", hw_stype);
+ RTW_PRINT("bw:0x%x\n", bw);
+ RTW_PRINT("fab:0x%x\n", fab);
+ RTW_PRINT("ant_num:0x%x\n", ant_num);
+ RTW_PRINT("protocol:0x%x\n", protocol);
+ RTW_PRINT("nic:0x%x\n", nic);
+ }
+
+ /*
+ * NOTICE:
+ * for now, the following is common info/format
+ * if there is any hal difference need to export
+ * some IC dependent code will need to be implement
+ */
+ hal_data->PackageType = package_type;
+ hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
+ hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
+ hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ant_num);
+ hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ant_num);
+ hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
+ hal_spec->hci_type = hci_type;
+
+ /* TODO: tr_switch */
+ /* TODO: fab */
+
+ ret = _SUCCESS;
+
+exit:
+ return ret;
+}
+
+int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ int ret = _FAIL;
+
+ int i;
+
+ if (len < MAC_HIDDEN_RPT_2_LEN) {
+ RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
+ goto exit;
+ }
+
+ if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
+ for (i = 0; i < len; i++)
+ RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
+ }
+
+ ret = _SUCCESS;
+
+exit:
+ return ret;
+}
+
+int hal_read_mac_hidden_rpt(_adapter *adapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
+ int ret = _FAIL;
+ int ret_fwdl;
+ u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
+ u32 start = jiffies;
+ u32 cnt = 0;
+ u32 timeout_ms = 800;
+ u32 min_cnt = 10;
+ u8 id = C2H_DEFEATURE_RSVD;
+ int i;
+
+ u8 hci_type = rtw_get_intf_type(adapter);
+
+ if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
+ && !rtw_is_hw_init_completed(adapter))
+ rtw_hal_power_on(adapter);
+
+ /* inform FW mac hidden rpt from reg is needed */
+ rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
+
+ /* download FW */
+ pHalData->not_xmitframe_fw_dl = 1;
+ ret_fwdl = rtw_hal_fw_dl(adapter, false);
+ pHalData->not_xmitframe_fw_dl = 0;
+ if (ret_fwdl != _SUCCESS)
+ goto mac_hidden_rpt_hdl;
+
+ /* polling for data ready */
+ start = jiffies;
+ do {
+ cnt++;
+ id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
+ if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
+ break;
+ rtw_msleep_os(10);
+ } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
+
+ if (id == C2H_MAC_HIDDEN_RPT) {
+ /* read data */
+ for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
+ mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
+ }
+
+ /* inform FW mac hidden rpt has read */
+ rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
+
+mac_hidden_rpt_hdl:
+ c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
+ c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
+
+ if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
+ ret = _SUCCESS;
+
+exit:
+
+ if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
+ && !rtw_is_hw_init_completed(adapter))
+ rtw_hal_power_off(adapter);
+
+ RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
+ , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
+
+ return ret;
+}
+#endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
+
+int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ int ret = _FAIL;
+
+ int i;
+
+ if (len < DEFEATURE_DBG_LEN) {
+ RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
+ goto exit;
+ }
+
+ for (i = 0; i < len; i++)
+ RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
+
+ ret = _SUCCESS;
+
+exit:
+ return ret;
+}
+
+#ifndef DBG_CUSTOMER_STR_RPT_HANDLE
+#define DBG_CUSTOMER_STR_RPT_HANDLE 0
+#endif
+
+#ifdef CONFIG_RTW_CUSTOMER_STR
+s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
+{
+ u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
+
+ SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
+ return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
+}
+
+#define C2H_CUSTOMER_STR_RPT_BYTE0(_data) ((u8 *)(_data))
+#define C2H_CUSTOMER_STR_RPT_2_BYTE8(_data) ((u8 *)(_data))
+
+int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ int ret = _FAIL;
+ int i;
+
+ if (len < CUSTOMER_STR_RPT_LEN) {
+ RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
+ goto exit;
+ }
+
+ if (DBG_CUSTOMER_STR_RPT_HANDLE)
+ RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
+
+ _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
+
+ if (dvobj->customer_str_sctx != NULL) {
+ if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
+ RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
+ memcpy(dvobj->customer_str, C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
+ dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
+ } else
+ RTW_WARN("%s sctx not set\n", __func__);
+
+ _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
+
+ ret = _SUCCESS;
+
+exit:
+ return ret;
+}
+
+int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ int ret = _FAIL;
+ int i;
+
+ if (len < CUSTOMER_STR_RPT_2_LEN) {
+ RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
+ goto exit;
+ }
+
+ if (DBG_CUSTOMER_STR_RPT_HANDLE)
+ RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
+
+ _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
+
+ if (dvobj->customer_str_sctx != NULL) {
+ if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
+ RTW_WARN("%s rpt not ready\n", __func__);
+ memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN, C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
+ rtw_sctx_done(&dvobj->customer_str_sctx);
+ } else
+ RTW_WARN("%s sctx not set\n", __func__);
+
+ _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
+
+ ret = _SUCCESS;
+
+exit:
+ return ret;
+}
+
+/* read customer str */
+s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct submit_ctx sctx;
+ s32 ret = _SUCCESS;
+
+ _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
+ if (dvobj->customer_str_sctx != NULL)
+ ret = _FAIL;
+ else {
+ rtw_sctx_init(&sctx, 2 * 1000);
+ dvobj->customer_str_sctx = &sctx;
+ }
+ _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
+
+ if (ret == _FAIL) {
+ RTW_WARN("%s another handle ongoing\n", __func__);
+ goto exit;
+ }
+
+ ret = rtw_customer_str_req_cmd(adapter);
+ if (ret != _SUCCESS) {
+ RTW_WARN("%s read cmd fail\n", __func__);
+ _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
+ dvobj->customer_str_sctx = NULL;
+ _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
+ goto exit;
+ }
+
+ /* wait till rpt done or timeout */
+ rtw_sctx_wait(&sctx, __func__);
+
+ _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
+ dvobj->customer_str_sctx = NULL;
+ if (sctx.status == RTW_SCTX_DONE_SUCCESS)
+ memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
+ else
+ ret = _FAIL;
+ _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
+
+exit:
+ return ret;
+}
+
+s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
+{
+ u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
+ u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
+ u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
+ s32 ret;
+
+ SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
+ memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
+
+ SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
+ memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
+
+ SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
+ memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
+
+ ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
+ if (ret != _SUCCESS) {
+ RTW_WARN("%s w1 fail\n", __func__);
+ goto exit;
+ }
+
+ ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
+ if (ret != _SUCCESS) {
+ RTW_WARN("%s w2 fail\n", __func__);
+ goto exit;
+ }
+
+ ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
+ if (ret != _SUCCESS) {
+ RTW_WARN("%s w3 fail\n", __func__);
+ goto exit;
+ }
+
+exit:
+ return ret;
+}
+
+/* write customer str and check if value reported is the same as requested */
+s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct submit_ctx sctx;
+ s32 ret = _SUCCESS;
+
+ _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
+ if (dvobj->customer_str_sctx != NULL)
+ ret = _FAIL;
+ else {
+ rtw_sctx_init(&sctx, 2 * 1000);
+ dvobj->customer_str_sctx = &sctx;
+ }
+ _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
+
+ if (ret == _FAIL) {
+ RTW_WARN("%s another handle ongoing\n", __func__);
+ goto exit;
+ }
+
+ ret = rtw_customer_str_write_cmd(adapter, cs);
+ if (ret != _SUCCESS) {
+ RTW_WARN("%s write cmd fail\n", __func__);
+ _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
+ dvobj->customer_str_sctx = NULL;
+ _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
+ goto exit;
+ }
+
+ ret = rtw_customer_str_req_cmd(adapter);
+ if (ret != _SUCCESS) {
+ RTW_WARN("%s read cmd fail\n", __func__);
+ _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
+ dvobj->customer_str_sctx = NULL;
+ _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
+ goto exit;
+ }
+
+ /* wait till rpt done or timeout */
+ rtw_sctx_wait(&sctx, __func__);
+
+ _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
+ dvobj->customer_str_sctx = NULL;
+ if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
+ if (memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN)) {
+ RTW_WARN("%s read back check fail\n", __func__);
+ RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
+ RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
+ ret = _FAIL;
+ }
+ } else
+ ret = _FAIL;
+ _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
+
+exit:
+ return ret;
+}
+#endif /* CONFIG_RTW_CUSTOMER_STR */
+
+u8 rtw_hal_networktype_to_raid(_adapter *adapter, struct sta_info *psta)
+{
+#ifdef CONFIG_GET_RAID_BY_DRV /*Just for 8188E now*/
+ if (IS_NEW_GENERATION_IC(adapter))
+ return networktype_to_raid_ex(adapter, psta);
+ else
+ return networktype_to_raid(adapter, psta);
+#else
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
+ u8 bw;
+
+ bw = rtw_get_tx_bw_mode(adapter, psta);
+
+ return phydm_rate_id_mapping(&pHalData->odmpriv, psta->wireless_mode, pHalData->rf_type, bw);
+#endif
+}
+u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
+{
+
+ u8 raid;
+ if (IS_NEW_GENERATION_IC(adapter)) {
+
+ raid = (network_type & WIRELESS_11B) ? RATEID_IDX_B
+ : RATEID_IDX_G;
+ } else {
+ raid = (network_type & WIRELESS_11B) ? RATR_INX_WIRELESS_B
+ : RATR_INX_WIRELESS_G;
+ }
+ return raid;
+}
+
+void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
+{
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
+ u8 i, rf_type, tx_nss;
+ u64 tx_ra_bitmap;
+
+ if (psta == NULL)
+ return;
+
+ tx_ra_bitmap = 0;
+
+ /* b/g mode ra_bitmap */
+ for (i = 0; i < sizeof(psta->bssrateset); i++) {
+ if (psta->bssrateset[i])
+ tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
+ }
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
+ tx_nss = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->tx_nss_num);
+ if (psta->htpriv.ht_option) {
+ /* n mode ra_bitmap */
+
+ /* Handling SMPS mode for AP MODE only*/
+ if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true) {
+ /*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
+ if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
+ /*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
+ tx_nss = rtw_min(tx_nss, 1);
+ }
+ }
+
+ tx_ra_bitmap |= (rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss) << 12);
+ }
+ psta->ra_mask = tx_ra_bitmap;
+ psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
+}
+
+#ifndef SEC_CAM_ACCESS_TIMEOUT_MS
+ #define SEC_CAM_ACCESS_TIMEOUT_MS 200
+#endif
+
+#ifndef DBG_SEC_CAM_ACCESS
+ #define DBG_SEC_CAM_ACCESS 0
+#endif
+
+u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
+{
+ _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
+ u32 rdata;
+ u32 cnt = 0;
+ u32 start = 0, end = 0;
+ u8 timeout = 0;
+ u8 sr = 0;
+
+ _enter_critical_mutex(mutex, NULL);
+
+ rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
+
+ start = jiffies;
+ while (1) {
+ if (rtw_is_surprise_removed(adapter)) {
+ sr = 1;
+ break;
+ }
+
+ cnt++;
+ if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
+ break;
+
+ if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
+ timeout = 1;
+ break;
+ }
+ }
+ end = jiffies;
+
+ rdata = rtw_read32(adapter, REG_CAMREAD);
+
+ _exit_critical_mutex(mutex, NULL);
+
+ if (DBG_SEC_CAM_ACCESS || timeout) {
+ RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
+ , FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
+ }
+
+ return rdata;
+}
+
+void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
+{
+ _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
+ u32 cnt = 0;
+ u32 start = 0, end = 0;
+ u8 timeout = 0;
+ u8 sr = 0;
+
+ _enter_critical_mutex(mutex, NULL);
+
+ rtw_write32(adapter, REG_CAMWRITE, wdata);
+ rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
+
+ start = jiffies;
+ while (1) {
+ if (rtw_is_surprise_removed(adapter)) {
+ sr = 1;
+ break;
+ }
+
+ cnt++;
+ if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
+ break;
+
+ if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
+ timeout = 1;
+ break;
+ }
+ }
+ end = jiffies;
+
+ _exit_critical_mutex(mutex, NULL);
+
+ if (DBG_SEC_CAM_ACCESS || timeout) {
+ RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
+ , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
+ }
+}
+
+void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
+{
+ unsigned int val, addr;
+ u8 i;
+ u32 rdata;
+ u8 begin = 0;
+ u8 end = 5; /* TODO: consider other key length accordingly */
+
+ if (!ctrl && !mac && !key) {
+ rtw_warn_on(1);
+ goto exit;
+ }
+
+ /* TODO: check id range */
+
+ if (!ctrl && !mac)
+ begin = 2; /* read from key */
+
+ if (!key && !mac)
+ end = 0; /* read to ctrl */
+ else if (!key)
+ end = 2; /* read to mac */
+
+ for (i = begin; i <= end; i++) {
+ rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
+
+ switch (i) {
+ case 0:
+ if (ctrl)
+ memcpy(ctrl, (u8 *)(&rdata), 2);
+ if (mac)
+ memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
+ break;
+ case 1:
+ if (mac)
+ memcpy(mac + 2, (u8 *)(&rdata), 4);
+ break;
+ default:
+ if (key)
+ memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
+ break;
+ }
+ }
+
+exit:
+ return;
+}
+
+
+void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
+{
+ unsigned int i;
+ int j;
+ u8 addr;
+ u32 wdata;
+
+ /* TODO: consider other key length accordingly */
+ j = 7;
+
+ for (; j >= 0; j--) {
+ switch (j) {
+ case 0:
+ wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
+ break;
+ case 1:
+ wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
+ break;
+ case 6:
+ case 7:
+ wdata = 0;
+ break;
+ default:
+ i = (j - 2) << 2;
+ wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
+ break;
+ }
+
+ addr = (id << 3) + j;
+
+ rtw_sec_write_cam(adapter, addr, wdata);
+ }
+}
+
+void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
+{
+ u8 addr;
+
+ addr = (id << 3);
+ rtw_sec_write_cam(adapter, addr, 0);
+}
+
+bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
+{
+ bool res;
+ u16 ctrl;
+
+ rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
+
+ res = (ctrl & BIT6) ? true : false;
+ return res;
+}
+#ifdef CONFIG_MBSSID_CAM
+void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
+{
+ struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
+
+ spin_lock_init(&mbid_cam_ctl->lock);
+ mbid_cam_ctl->bitmap = 0;
+ ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
+ memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
+}
+
+void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
+{
+}
+
+void rtw_mbid_cam_reset(_adapter *adapter)
+{
+ unsigned long irqL;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
+
+ _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
+ mbid_cam_ctl->bitmap = 0;
+ memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
+ _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
+
+ ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
+}
+static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
+{
+ u8 i;
+ u8 cam_id = INVALID_CAM_ID;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+
+ for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
+ if (mac_addr && !memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == true) {
+ cam_id = i;
+ break;
+ }
+ }
+
+ RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
+ return cam_id;
+}
+
+u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
+{
+ unsigned long irqL;
+
+ u8 cam_id = INVALID_CAM_ID;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
+
+ _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
+ cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
+ _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
+
+ return cam_id;
+}
+static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
+{
+ u8 i;
+ u8 cam_id = INVALID_CAM_ID;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+
+ for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
+ if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
+ cam_id = i;
+ break;
+ }
+ }
+ if (cam_id != INVALID_CAM_ID)
+ RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
+ __func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
+
+ return cam_id;
+}
+
+u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
+{
+ unsigned long irqL;
+ u8 cam_id = INVALID_CAM_ID;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
+
+ _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
+ cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
+ _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
+
+ return cam_id;
+}
+u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
+{
+ unsigned long irqL;
+ s8 i;
+ u8 cam_id = INVALID_CAM_ID;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
+
+ _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
+ for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
+ if (mbid_cam_ctl->bitmap & BIT(i)) {
+ cam_id = i;
+ break;
+ }
+ }
+ _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
+ /*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
+ return cam_id;
+}
+
+inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
+
+ return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
+}
+
+static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
+{
+ if (adapter && pmbid_cam && mac_addr) {
+ memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
+ pmbid_cam->iface_id = adapter->iface_id;
+ }
+}
+static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
+{
+ if (pmbid_cam) {
+ memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
+ pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
+ }
+}
+
+u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
+{
+ unsigned long irqL;
+ u8 cam_id = INVALID_CAM_ID, i;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
+ u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
+
+ if (entry_num >= TOTAL_MBID_CAM_NUM) {
+ RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
+ rtw_warn_on(1);
+ }
+
+ if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
+ goto exit;
+
+ _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
+ for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
+ if (!(mbid_cam_ctl->bitmap & BIT(i))) {
+ mbid_cam_ctl->bitmap |= BIT(i);
+ cam_id = i;
+ break;
+ }
+ }
+ if ((cam_id != INVALID_CAM_ID) && (mac_addr))
+ mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
+ _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
+
+ if (cam_id != INVALID_CAM_ID) {
+ ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
+ RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
+#ifdef DBG_MBID_CAM_DUMP
+ rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
+#endif
+ } else
+ RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
+exit:
+ return cam_id;
+}
+
+u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
+{
+ unsigned long irqL;
+ u8 entry_id = INVALID_CAM_ID;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
+
+ _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
+ entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
+ if (entry_id != INVALID_CAM_ID)
+ mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
+
+ _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
+
+ return entry_id;
+}
+
+u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
+{
+ unsigned long irqL;
+ u8 ret = false;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
+
+ if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
+ RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
+ rtw_warn_on(1);
+ }
+ if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
+ goto exit;
+
+ _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
+ if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
+ if (mac_addr) {
+ mbid_cam_ctl->bitmap |= BIT(camid);
+ mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
+ ret = true;
+ }
+ }
+ _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
+
+ if (ret == true) {
+ ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
+ RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
+#ifdef DBG_MBID_CAM_DUMP
+ rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
+#endif
+ } else
+ RTW_INFO("%s [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
+
+exit:
+ return ret;
+}
+
+void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
+{
+ unsigned long irqL;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
+
+ if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
+ RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
+ rtw_warn_on(1);
+ }
+ _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
+ mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
+ mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
+ _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
+ ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
+ RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
+}
+int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
+{
+ unsigned long irqL;
+ u8 i;
+ _adapter *iface;
+ u8 iface_id;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
+ u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
+ u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
+
+ RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
+
+ _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
+ RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
+ for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
+ RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
+
+ if (mbid_cam_ctl->bitmap & BIT(i)) {
+ iface_id = dvobj->mbid_cam_cache[i].iface_id;
+ RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
+ RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
+
+ iface = dvobj->padapters[iface_id];
+ if (iface) {
+ if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == true)
+ RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
+ else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == true)
+ RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
+ else
+ RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
+ }
+
+ } else
+ RTW_PRINT_SEL(sel, "N/A\n");
+ }
+ _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
+ return 0;
+}
+
+static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
+{
+ u8 poll = 1;
+ u8 cam_ready = false;
+ u32 cam_data1 = 0;
+ u16 cam_data2 = 0;
+
+ if (RTW_CANNOT_RUN(padapter))
+ return;
+
+ rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
+
+ do {
+ if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
+ cam_ready = true;
+ break;
+ }
+ poll++;
+ } while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
+
+ if (cam_ready) {
+ cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
+ mac[0] = cam_data1 & 0xFF;
+ mac[1] = (cam_data1 >> 8) & 0xFF;
+ mac[2] = (cam_data1 >> 16) & 0xFF;
+ mac[3] = (cam_data1 >> 24) & 0xFF;
+
+ cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
+ mac[4] = cam_data2 & 0xFF;
+ mac[5] = (cam_data2 >> 8) & 0xFF;
+ }
+
+}
+int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
+{
+ /*unsigned long irqL;*/
+ u8 i;
+ u8 mac_addr[ETH_ALEN];
+
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
+
+ RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
+
+ /*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
+ for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
+ RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
+ memset(mac_addr, 0, ETH_ALEN);
+ read_mbssid_cam(adapter, i, mac_addr);
+ RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
+ }
+ /*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
+ return 0;
+}
+
+static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
+{
+ u32 cam_val[2] = {0};
+
+ cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
+ cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT) | (mac[5] << 8) | mac[4];
+
+ rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
+}
+
+static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
+{
+ rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
+}
+static void enable_mbssid_cam(_adapter *adapter)
+{
+ u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
+ /*enable MBSSID*/
+ rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR) | RCR_ENMBID);
+ if (max_cam_id != INVALID_CAM_ID) {
+ rtw_write8(adapter, REG_MBID_NUM,
+ ((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | (max_cam_id & 0x07)));
+ }
+}
+void rtw_mbid_cam_restore(_adapter *adapter)
+{
+ u8 i;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
+
+#ifdef DBG_MBID_CAM_DUMP
+ rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
+#endif
+
+ for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
+ if (mbid_cam_ctl->bitmap & BIT(i)) {
+ write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
+ RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
+ }
+ }
+ enable_mbssid_cam(adapter);
+}
+#endif /*CONFIG_MBSSID_CAM*/
+
+#ifdef CONFIG_MI_WITH_MBSSID_CAM
+void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
+{
+
+ /*
+ MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
+ */
+ u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
+
+
+ if (entry_id != INVALID_CAM_ID) {
+ write_mbssid_cam(adapter, entry_id, mac_addr);
+ enable_mbssid_cam(adapter);
+ }
+}
+
+void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
+{
+ u8 idx = 0;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ u8 entry_id;
+
+ if (!mac_addr) {
+ rtw_warn_on(1);
+ return;
+ }
+
+
+ entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
+
+ if (entry_id != INVALID_CAM_ID)
+ write_mbssid_cam(adapter, entry_id, mac_addr);
+}
+
+
+#endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
+
+void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *val)
+{
+ u8 idx = 0;
+ u32 reg_macid = 0;
+
+ if (val == NULL)
+ return;
+
+ RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
+ ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(val));
+
+ switch (adapter->hw_port) {
+ case HW_PORT0:
+ default:
+ reg_macid = REG_MACID;
+ break;
+ case HW_PORT1:
+ reg_macid = REG_MACID1;
+ break;
+ }
+
+ for (idx = 0; idx < 6; idx++)
+ rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macid + idx), val[idx]);
+}
+
+void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
+{
+ u8 idx = 0;
+ u32 reg_macid = 0;
+
+ if (mac_addr == NULL)
+ return;
+
+ memset(mac_addr, 0, ETH_ALEN);
+ switch (adapter->hw_port) {
+ case HW_PORT0:
+ default:
+ reg_macid = REG_MACID;
+ break;
+ case HW_PORT1:
+ reg_macid = REG_MACID1;
+ break;
+ }
+
+ for (idx = 0; idx < 6; idx++)
+ mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macid + idx));
+
+ RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
+ ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(mac_addr));
+}
+
+void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
+{
+ u8 idx = 0;
+ u32 reg_bssid = 0;
+
+ switch (adapter->hw_port) {
+ case HW_PORT0:
+ default:
+ reg_bssid = REG_BSSID;
+ break;
+ case HW_PORT1:
+ reg_bssid = REG_BSSID1;
+ break;
+ }
+
+ for (idx = 0 ; idx < 6; idx++)
+ rtw_write8(adapter, (reg_bssid + idx), val[idx]);
+
+ RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n", __func__, ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(val));
+}
+
+static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
+{
+ switch (adapter->hw_port) {
+ case HW_PORT0:
+ /*REG_CR - BIT[17:16]-Network Type for port 1*/
+ *net_type = rtw_read8(adapter, MSR) & 0x03;
+ break;
+ case HW_PORT1:
+ /*REG_CR - BIT[19:18]-Network Type for port 1*/
+ *net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
+ break;
+ default:
+ RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
+ ADPT_ARG(adapter), adapter->hw_port);
+ rtw_warn_on(1);
+ break;
+ }
+}
+
+void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
+{
+ u8 val8 = 0;
+
+ switch (adapter->hw_port) {
+ case HW_PORT0:
+#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM) /*For 2 hw ports - 88E/92E/8812/8821/8723B*/
+ if (rtw_get_mbid_cam_entry_num(adapter)) {
+ if (net_type != _HW_STATE_NOLINK_)
+ net_type = _HW_STATE_AP_;
+ }
+#endif
+ /*REG_CR - BIT[17:16]-Network Type for port 0*/
+ val8 = rtw_read8(adapter, MSR) & 0x0C;
+ val8 |= net_type;
+ rtw_write8(adapter, MSR, val8);
+ break;
+ case HW_PORT1:
+ /*REG_CR - BIT[19:18]-Network Type for port 1*/
+ val8 = rtw_read8(adapter, MSR) & 0x03;
+ val8 |= net_type << 2;
+ rtw_write8(adapter, MSR, val8);
+ break;
+ default:
+ RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
+ ADPT_ARG(adapter), adapter->hw_port);
+ rtw_warn_on(1);
+ break;
+ }
+}
+
+void hw_var_port_switch(_adapter *adapter)
+{
+#ifdef CONFIG_CONCURRENT_MODE
+#ifdef CONFIG_RUNTIME_PORT_SWITCH
+ /*
+ 0x102: MSR
+ 0x550: REG_BCN_CTRL
+ 0x551: REG_BCN_CTRL_1
+ 0x55A: REG_ATIMWND
+ 0x560: REG_TSFTR
+ 0x568: REG_TSFTR1
+ 0x570: REG_ATIMWND_1
+ 0x610: REG_MACID
+ 0x618: REG_BSSID
+ 0x700: REG_MACID1
+ 0x708: REG_BSSID1
+ */
+
+ int i;
+ u8 msr;
+ u8 bcn_ctrl;
+ u8 bcn_ctrl_1;
+ u8 atimwnd[2];
+ u8 atimwnd_1[2];
+ u8 tsftr[8];
+ u8 tsftr_1[8];
+ u8 macid[6];
+ u8 bssid[6];
+ u8 macid_1[6];
+ u8 bssid_1[6];
+
+ u8 hw_port;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ _adapter *iface = NULL;
+
+ msr = rtw_read8(adapter, MSR);
+ bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
+ bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
+
+ for (i = 0; i < 2; i++)
+ atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
+ for (i = 0; i < 2; i++)
+ atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
+
+ for (i = 0; i < 8; i++)
+ tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
+ for (i = 0; i < 8; i++)
+ tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
+
+ for (i = 0; i < 6; i++)
+ macid[i] = rtw_read8(adapter, REG_MACID + i);
+
+ for (i = 0; i < 6; i++)
+ bssid[i] = rtw_read8(adapter, REG_BSSID + i);
+
+ for (i = 0; i < 6; i++)
+ macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
+
+ for (i = 0; i < 6; i++)
+ bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
+
+#ifdef DBG_RUNTIME_PORT_SWITCH
+ RTW_INFO(FUNC_ADPT_FMT" before switch\n"
+ "msr:0x%02x\n"
+ "bcn_ctrl:0x%02x\n"
+ "bcn_ctrl_1:0x%02x\n"
+ "atimwnd:0x%04x\n"
+ "atimwnd_1:0x%04x\n"
+ "tsftr:%llu\n"
+ "tsftr1:%llu\n"
+ "macid:"MAC_FMT"\n"
+ "bssid:"MAC_FMT"\n"
+ "macid_1:"MAC_FMT"\n"
+ "bssid_1:"MAC_FMT"\n"
+ , FUNC_ADPT_ARG(adapter)
+ , msr
+ , bcn_ctrl
+ , bcn_ctrl_1
+ , *((u16 *)atimwnd)
+ , *((u16 *)atimwnd_1)
+ , *((u64 *)tsftr)
+ , *((u64 *)tsftr_1)
+ , MAC_ARG(macid)
+ , MAC_ARG(bssid)
+ , MAC_ARG(macid_1)
+ , MAC_ARG(bssid_1)
+ );
+#endif /* DBG_RUNTIME_PORT_SWITCH */
+
+ /* disable bcn function, disable update TSF */
+ rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
+ rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
+
+ /* switch msr */
+ msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
+ rtw_write8(adapter, MSR, msr);
+
+ /* write port0 */
+ rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
+ for (i = 0; i < 2; i++)
+ rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
+ for (i = 0; i < 8; i++)
+ rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
+ for (i = 0; i < 6; i++)
+ rtw_write8(adapter, REG_MACID + i, macid_1[i]);
+ for (i = 0; i < 6; i++)
+ rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
+
+ /* write port1 */
+ rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
+ for (i = 0; i < 2; i++)
+ rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
+ for (i = 0; i < 8; i++)
+ rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
+ for (i = 0; i < 6; i++)
+ rtw_write8(adapter, REG_MACID1 + i, macid[i]);
+ for (i = 0; i < 6; i++)
+ rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
+
+ /* write bcn ctl */
+ rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
+ rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
+
+ if (adapter->iface_id == IFACE_ID0)
+ iface = dvobj->padapters[IFACE_ID1];
+ else if (adapter->iface_id == IFACE_ID1)
+ iface = dvobj->padapters[IFACE_ID0];
+
+
+ if (adapter->hw_port == HW_PORT0) {
+ adapter->hw_port = HW_PORT1;
+ iface->hw_port = HW_PORT0;
+ RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
+ ADPT_ARG(iface), ADPT_ARG(adapter));
+ } else {
+ adapter->hw_port = HW_PORT0;
+ iface->hw_port = HW_PORT1;
+ RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
+ ADPT_ARG(adapter), ADPT_ARG(iface));
+ }
+
+#ifdef DBG_RUNTIME_PORT_SWITCH
+ msr = rtw_read8(adapter, MSR);
+ bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
+ bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
+
+ for (i = 0; i < 2; i++)
+ atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
+ for (i = 0; i < 2; i++)
+ atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
+
+ for (i = 0; i < 8; i++)
+ tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
+ for (i = 0; i < 8; i++)
+ tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
+
+ for (i = 0; i < 6; i++)
+ macid[i] = rtw_read8(adapter, REG_MACID + i);
+
+ for (i = 0; i < 6; i++)
+ bssid[i] = rtw_read8(adapter, REG_BSSID + i);
+
+ for (i = 0; i < 6; i++)
+ macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
+
+ for (i = 0; i < 6; i++)
+ bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
+
+ RTW_INFO(FUNC_ADPT_FMT" after switch\n"
+ "msr:0x%02x\n"
+ "bcn_ctrl:0x%02x\n"
+ "bcn_ctrl_1:0x%02x\n"
+ "atimwnd:%u\n"
+ "atimwnd_1:%u\n"
+ "tsftr:%llu\n"
+ "tsftr1:%llu\n"
+ "macid:"MAC_FMT"\n"
+ "bssid:"MAC_FMT"\n"
+ "macid_1:"MAC_FMT"\n"
+ "bssid_1:"MAC_FMT"\n"
+ , FUNC_ADPT_ARG(adapter)
+ , msr
+ , bcn_ctrl
+ , bcn_ctrl_1
+ , *((u16 *)atimwnd)
+ , *((u16 *)atimwnd_1)
+ , *((u64 *)tsftr)
+ , *((u64 *)tsftr_1)
+ , MAC_ARG(macid)
+ , MAC_ARG(bssid)
+ , MAC_ARG(macid_1)
+ , MAC_ARG(bssid_1)
+ );
+#endif /* DBG_RUNTIME_PORT_SWITCH */
+
+#endif /* CONFIG_RUNTIME_PORT_SWITCH */
+#endif /* CONFIG_CONCURRENT_MODE */
+}
+
+const char *const _h2c_msr_role_str[] = {
+ "RSVD",
+ "STA",
+ "AP",
+ "GC",
+ "GO",
+ "TDLS",
+ "ADHOC",
+ "INVALID",
+};
+
+#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
+s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
+{
+ s32 ret = _SUCCESS;
+ u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+
+ SET_H2CCMD_DFTPID_PORT_ID(parm, adapter->hw_port);
+ SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
+
+ RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
+ RTW_INFO("%s port_id :%d, mad_id:%d\n", __func__, adapter->hw_port, mac_id);
+
+ ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
+ dvobj->default_port_id = adapter->hw_port;
+
+ return ret;
+}
+s32 rtw_set_default_port_id(_adapter *adapter)
+{
+ s32 ret = _SUCCESS;
+ struct sta_info *psta;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+
+ if (adapter->hw_port == dvobj->default_port_id)
+ return ret;
+
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
+ psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
+ if (psta)
+ ret = rtw_hal_set_default_port_id_cmd(adapter, psta->mac_id);
+ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
+
+ } else {
+ }
+
+ return ret;
+}
+s32 rtw_set_ps_rsvd_page(_adapter *adapter)
+{
+ s32 ret = _SUCCESS;
+ u16 media_status_rpt = RT_MEDIA_CONNECT;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+
+ if (adapter->hw_port == dvobj->default_port_id)
+ return ret;
+
+ rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
+ (u8 *)&media_status_rpt);
+
+ return ret;
+}
+
+#endif
+/*
+* rtw_hal_set_FwMediaStatusRpt_cmd -
+*
+* @adapter:
+* @opmode: 0:disconnect, 1:connect
+* @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
+* @miracast_sink: 0:source. 1:sink
+* @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
+* @macid:
+* @macid_ind: 0:update Media Status to macid. 1:update Media Status from macid to macid_end
+* @macid_end:
+*/
+s32 rtw_hal_set_FwMediaStatusRpt_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, bool macid_ind, u8 macid_end)
+{
+ struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
+ u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
+ int i;
+ s32 ret;
+
+ SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
+ SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
+ SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
+ SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
+ SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
+ SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
+ SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
+#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
+ SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, adapter->hw_port);
+#endif
+ RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
+
+#ifdef CONFIG_DFS_MASTER
+ /* workaround for TXPAUSE cleared issue by FW's MediaStatusRpt handling */
+ if (macid_ind == 0 && macid == 1
+ && !rtw_odm_dfs_domain_unknown(adapter)
+ ) {
+ u8 parm0_bak = parm[0];
+
+ SET_H2CCMD_MSRRPT_PARM_MACID_IND(&parm0_bak, 0);
+ if (macid_ctl->h2c_msr[macid] == parm0_bak) {
+ ret = _SUCCESS;
+ goto post_action;
+ }
+ }
+#endif
+
+ ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
+ if (ret != _SUCCESS)
+ goto exit;
+
+#ifdef CONFIG_DFS_MASTER
+post_action:
+#endif
+ if (rtw_get_chip_type(adapter) == RTL8188E) {
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+
+ /* 8188E FW doesn't set macid no link, driver does it by self */
+ if (opmode)
+ rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
+ else
+ rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
+
+ /* for 8188E RA */
+#if (RATE_ADAPTIVE_SUPPORT == 1)
+ if (hal_data->fw_ractrl == false) {
+ u8 max_macid;
+
+ max_macid = rtw_search_max_mac_id(adapter);
+ rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
+ }
+#endif
+ }
+
+ SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
+ if (macid_ind == 0)
+ macid_end = macid;
+
+ for (i = macid; macid <= macid_end; macid++) {
+ rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
+ if (!opmode) {
+ rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
+ rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
+ rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
+ rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
+ }
+ }
+ if (!opmode)
+ rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
+
+exit:
+ return ret;
+}
+
+inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
+{
+ return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
+}
+
+inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
+{
+ return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
+}
+
+static void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
+{
+ struct hal_ops *pHalFunc = &padapter->hal_func;
+ u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
+ u8 ret = 0;
+
+ RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
+ rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
+ rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
+ rsvdpageloc->LocBTQosNull);
+
+ SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
+ SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
+ SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
+ SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
+ SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
+
+ ret = rtw_hal_fill_h2c_cmd(padapter,
+ H2C_RSVD_PAGE,
+ H2C_RSVDPAGE_LOC_LEN,
+ u1H2CRsvdPageParm);
+
+}
+
+#ifdef CONFIG_GPIO_WAKEUP
+void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+
+ if (IS_8723D_SERIES(pHalData->version_id) || IS_8822B_SERIES(pHalData->version_id))
+ rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
+ /*
+ * Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
+ * It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
+ * and implement HAL function.
+ * TODO: GPIO_8 multi function?
+ */
+
+ if (index == 13 || index == 14)
+ rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
+}
+
+void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
+{
+ if (index <= 7) {
+ /* config GPIO mode */
+ rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
+ rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
+
+ /* config GPIO Sel */
+ /* 0: input */
+ /* 1: output */
+ rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
+ rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
+
+ /* set output value */
+ if (outputval) {
+ rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
+ rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
+ } else {
+ rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
+ rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
+ }
+ } else if (index <= 15) {
+ /* 88C Series: */
+ /* index: 11~8 transform to 3~0 */
+ /* 8723 Series: */
+ /* index: 12~8 transform to 4~0 */
+
+ index -= 8;
+
+ /* config GPIO mode */
+ rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
+ rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
+
+ /* config GPIO Sel */
+ /* 0: input */
+ /* 1: output */
+ rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
+ rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
+
+ /* set output value */
+ if (outputval) {
+ rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
+ rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
+ } else {
+ rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
+ rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
+ }
+ } else {
+ RTW_INFO("%s: invalid GPIO%d=%d\n",
+ __func__, index, outputval);
+ }
+}
+#endif
+
+static void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
+{
+ struct hal_ops *pHalFunc = &padapter->hal_func;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ u8 res = 0, count = 0, ret = 0;
+#ifdef CONFIG_WOWLAN
+ u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
+
+ RTW_INFO("AOACRsvdPageLoc: RWC=%d ArpRsp=%d NbrAdv=%d GtkRsp=%d GtkInfo=%d ProbeReq=%d NetworkList=%d\n",
+ rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp,
+ rsvdpageloc->LocNbrAdv, rsvdpageloc->LocGTKRsp,
+ rsvdpageloc->LocGTKInfo, rsvdpageloc->LocProbeReq,
+ rsvdpageloc->LocNetList);
+
+ if (check_fwstate(pmlmepriv, _FW_LINKED)) {
+ SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
+ SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
+ /* SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm, rsvdpageloc->LocNbrAdv); */
+#ifdef CONFIG_GTK_OL
+ SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
+ SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
+ SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
+#endif /* CONFIG_GTK_OL */
+ ret = rtw_hal_fill_h2c_cmd(padapter,
+ H2C_AOAC_RSVD_PAGE,
+ H2C_AOAC_RSVDPAGE_LOC_LEN,
+ u1H2CAoacRsvdPageParm);
+
+ RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
+ memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
+ SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
+ rsvdpageloc->LocAOACReport);
+ ret = rtw_hal_fill_h2c_cmd(padapter,
+ H2C_AOAC_RSVDPAGE3,
+ H2C_AOAC_RSVDPAGE_LOC_LEN,
+ u1H2CAoacRsvdPageParm);
+ pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
+ }
+#ifdef CONFIG_PNO_SUPPORT
+ else {
+
+ if (!pwrpriv->wowlan_in_resume) {
+ RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
+ memset(&u1H2CAoacRsvdPageParm, 0,
+ sizeof(u1H2CAoacRsvdPageParm));
+ SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
+ rsvdpageloc->LocPNOInfo);
+ ret = rtw_hal_fill_h2c_cmd(padapter,
+ H2C_AOAC_RSVDPAGE3,
+ H2C_AOAC_RSVDPAGE_LOC_LEN,
+ u1H2CAoacRsvdPageParm);
+ }
+ }
+#endif /* CONFIG_PNO_SUPPORT */
+#endif /* CONFIG_WOWLAN */
+}
+
+/*#define DBG_GET_RSVD_PAGE*/
+int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
+ u32 page_num, u8 *buffer, u32 buffer_size)
+{
+ u32 addr = 0, size = 0, count = 0;
+ u32 page_size = 0, data_low = 0, data_high = 0;
+ u16 txbndy = 0, offset = 0;
+ u8 i = 0;
+ bool rst = false;
+
+ rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
+
+ addr = page_offset * page_size;
+ size = page_num * page_size;
+
+ if (buffer_size < size) {
+ RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
+ __func__, buffer_size, size);
+ return rst;
+ }
+#ifdef RTW_HALMAC
+ if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
+ rst = false;
+ else
+ rst = true;
+#else
+ txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
+
+ offset = (txbndy + page_offset) << 4;
+ count = (buffer_size / 8) + 1;
+
+ rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
+
+ for (i = 0 ; i < count ; i++) {
+ rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
+ data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
+ data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
+ memcpy(buffer + (i * 8),
+ &data_low, sizeof(data_low));
+ memcpy(buffer + ((i * 8) + 4),
+ &data_high, sizeof(data_high));
+ }
+ rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
+ rst = true;
+#endif /*RTW_HALMAC*/
+
+#ifdef DBG_GET_RSVD_PAGE
+ RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
+ __func__, page_offset, page_num, addr, size);
+ RTW_INFO_DUMP("\n", buffer, size);
+ RTW_INFO(" ==================================================\n");
+#endif
+ return rst;
+}
+
+void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
+{
+ u32 page_size = 0;
+ u8 *buffer = NULL;
+ u32 buf_size = 0;
+
+ if (page_num == 0)
+ return;
+
+ RTW_PRINT_SEL(sel, "======= RSVG PAGE DUMP =======\n");
+ RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
+
+ rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
+ if (page_size) {
+ buf_size = page_size * page_num;
+ buffer = rtw_zvmalloc(buf_size);
+
+ if (buffer) {
+ rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
+ _RTW_DUMP_SEL(sel, buffer, buf_size);
+ rtw_vmfree(buffer, buf_size);
+ } else
+ RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
+ } else
+ RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
+
+ RTW_PRINT_SEL(sel, "==========================\n");
+}
+
+#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
+static void rtw_hal_force_enable_rxdma(_adapter *adapter)
+{
+ RTW_INFO("%s: Set 0x690=0x00\n", __func__);
+ rtw_write8(adapter, REG_WOW_CTRL,
+ (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
+ RTW_PRINT("%s: Release RXDMA\n", __func__);
+ rtw_write32(adapter, REG_RXPKT_NUM,
+ (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
+}
+static void rtw_hal_disable_tx_report(_adapter *adapter)
+{
+ rtw_write8(adapter, REG_TX_RPT_CTRL,
+ ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
+ RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
+}
+
+static void rtw_hal_enable_tx_report(_adapter *adapter)
+{
+ rtw_write8(adapter, REG_TX_RPT_CTRL,
+ ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
+ RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
+}
+
+static void rtw_hal_release_rx_dma(_adapter *adapter)
+{
+ u32 val32 = 0;
+
+ val32 = rtw_read32(adapter, REG_RXPKT_NUM);
+
+ rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
+
+ RTW_INFO("%s, [0x%04x]: 0x%08x\n",
+ __func__, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
+}
+
+static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
+{
+ PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
+ u8 ret = 0;
+ s8 trycnt = 100;
+ u32 tmp = 0;
+ int res = 0;
+ /* RX DMA stop */
+ RTW_PRINT("Pause DMA\n");
+ rtw_write32(adapter, REG_RXPKT_NUM,
+ (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
+ do {
+ if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
+ /* stop interface before leave */
+ if (hal->usb_intf_start) {
+ rtw_intf_stop(adapter);
+ RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
+ RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
+ }
+
+ RTW_PRINT("RX_DMA_IDLE is true\n");
+ ret = _SUCCESS;
+ break;
+ }
+ else {
+ /* to avoid interface start repeatedly */
+ if (false == hal->usb_intf_start)
+ rtw_intf_start(adapter);
+ }
+ } while (trycnt--);
+
+ if (trycnt < 0) {
+ tmp = rtw_read16(adapter, REG_RXPKT_NUM + 3);
+
+ RTW_PRINT("Stop RX DMA failed......\n");
+ RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
+ __func__, tmp);
+ tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
+ if (tmp & BIT(3))
+ RTW_PRINT("%s, RX DMA has req\n",
+ __func__);
+ else
+ RTW_PRINT("%s, RX DMA no req\n",
+ __func__);
+ ret = _FAIL;
+ }
+
+ return ret;
+}
+
+#endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
+
+#ifdef CONFIG_WOWLAN
+/*
+ * rtw_hal_check_wow_ctrl
+ * chk_type: true means to check enable, if 0x690 & bit1, WOW enable successful
+ * false means to check disable, if 0x690 & bit1, WOW disable fail
+ */
+static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
+{
+ u8 mstatus = 0;
+ u8 trycnt = 25;
+ u8 res = false;
+
+ mstatus = rtw_read8(adapter, REG_WOW_CTRL);
+ RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
+
+ if (chk_type) {
+ while (!(mstatus & BIT1) && trycnt > 1) {
+ mstatus = rtw_read8(adapter, REG_WOW_CTRL);
+ RTW_PRINT("Loop index: %d :0x%02x\n",
+ trycnt, mstatus);
+ trycnt--;
+ rtw_msleep_os(20);
+ }
+ if (mstatus & BIT1)
+ res = true;
+ else
+ res = false;
+ } else {
+ while (mstatus & BIT1 && trycnt > 1) {
+ mstatus = rtw_read8(adapter, REG_WOW_CTRL);
+ RTW_PRINT("Loop index: %d :0x%02x\n",
+ trycnt, mstatus);
+ trycnt--;
+ rtw_msleep_os(20);
+ }
+
+ if (mstatus & BIT1)
+ res = false;
+ else
+ res = true;
+ }
+ RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
+ __func__, chk_type, res, (25 - trycnt));
+ return res;
+}
+
+#ifdef CONFIG_PNO_SUPPORT
+static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
+{
+ struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
+ u8 res = 0, count = 0;
+ u8 ret = false;
+
+ if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == false) {
+ res = rtw_read8(adapter, REG_PNO_STATUS);
+ while (!(res & BIT(7)) && count < 25) {
+ RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
+ count, res);
+ res = rtw_read8(adapter, REG_PNO_STATUS);
+ count++;
+ rtw_msleep_os(2);
+ }
+ if (res & BIT(7))
+ ret = true;
+ else
+ ret = false;
+ RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
+ }
+ return ret;
+}
+#endif
+
+static void rtw_hal_backup_rate(_adapter *adapter)
+{
+ RTW_INFO("%s\n", __func__);
+ /* backup data rate to register 0x8b for wowlan FW */
+ rtw_write8(adapter, 0x8d, 1);
+ rtw_write8(adapter, 0x8c, 0);
+ rtw_write8(adapter, 0x8f, 0x40);
+ rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
+}
+
+#ifdef CONFIG_GTK_OL
+static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
+{
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ int cam_id, index = 0;
+ u8 *addr = NULL;
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
+ return;
+
+ addr = get_bssid(pmlmepriv);
+
+ if (addr == NULL) {
+ RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
+ return;
+ }
+
+ rtw_clean_dk_section(adapter);
+
+ do {
+ cam_id = rtw_camid_search(adapter, addr, index, 1);
+
+ if (cam_id == -1)
+ RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
+ else
+ rtw_sec_cam_swap(adapter, cam_id, index);
+
+ index++;
+ } while (index < 4);
+
+ rtw_write8(adapter, REG_SECCFG, 0xcc);
+}
+
+static void rtw_dump_aoac_rpt(_adapter *adapter)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+ struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
+
+ RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
+ RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
+ paoac_rpt->replay_counter_eapol_key, 8);
+ RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
+ RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
+ RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
+}
+
+static void rtw_hal_get_aoac_rpt(_adapter *adapter)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+ struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
+ u32 page_offset = 0, page_number = 0;
+ u32 page_size = 0, buf_size = 0;
+ u8 *buffer = NULL;
+ u8 i = 0, tmp = 0;
+ int ret = -1;
+
+ /* read aoac report from rsvd page */
+ page_offset = pwrctl->wowlan_aoac_rpt_loc;
+ page_number = 1;
+
+ rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
+ buf_size = page_size * page_number;
+
+ buffer = rtw_zvmalloc(buf_size);
+
+ if (NULL == buffer) {
+ RTW_ERR("%s buffer allocate failed size(%d)\n",
+ __func__, buf_size);
+ return;
+ }
+
+ RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
+
+ ret = rtw_hal_get_rsvd_page(adapter, page_offset,
+ page_number, buffer, buf_size);
+
+ if (ret == false) {
+ RTW_ERR("%s get aoac report failed\n", __func__);
+ rtw_warn_on(1);
+ goto _exit;
+ }
+
+ memset(paoac_rpt, 0, sizeof(struct aoac_report));
+ memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
+
+ for (i = 0 ; i < 4 ; i++) {
+ tmp = paoac_rpt->replay_counter_eapol_key[i];
+ paoac_rpt->replay_counter_eapol_key[i] =
+ paoac_rpt->replay_counter_eapol_key[7 - i];
+ paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
+ }
+
+ /* rtw_dump_aoac_rpt(adapter); */
+
+_exit:
+ if (buffer)
+ rtw_vmfree(buffer, buf_size);
+}
+
+static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+ struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct security_priv *psecuritypriv = &adapter->securitypriv;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
+ unsigned long irqL;
+ u8 get_key[16];
+ u8 gtk_id = 0, offset = 0, i = 0, sz = 0;
+ u64 replay_count = 0;
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
+ return;
+
+ memset(get_key, 0, sizeof(get_key));
+ memcpy(&replay_count,
+ paoac_rpt->replay_counter_eapol_key, 8);
+
+ /*read gtk key index*/
+ gtk_id = paoac_rpt->key_index;
+
+ if (gtk_id == 5 || gtk_id == 0) {
+ RTW_INFO("%s no rekey event happened.\n", __func__);
+ } else if (gtk_id > 0 && gtk_id < 4) {
+ RTW_INFO("%s update security key.\n", __func__);
+ /*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
+ rtw_sec_read_cam_ent(adapter, gtk_id,
+ NULL, NULL, get_key);
+ rtw_clean_hw_dk_cam(adapter);
+
+ if (_rtw_camid_is_gk(adapter, gtk_id)) {
+ _enter_critical_bh(&cam_ctl->lock, &irqL);
+ memcpy(&dvobj->cam_cache[gtk_id].key,
+ get_key, 16);
+ _exit_critical_bh(&cam_ctl->lock, &irqL);
+ } else {
+ struct setkey_parm parm_gtk;
+
+ parm_gtk.algorithm = paoac_rpt->security_type;
+ parm_gtk.keyid = gtk_id;
+ memcpy(parm_gtk.key, get_key, 16);
+ setkey_hdl(adapter, (u8 *)&parm_gtk);
+ }
+
+ /*update key into related sw variable and sec-cam cache*/
+ psecuritypriv->dot118021XGrpKeyid = gtk_id;
+ memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
+ get_key, 16);
+ /* update SW TKIP TX/RX MIC value */
+ if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
+ offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
+ memcpy(
+ &psecuritypriv->dot118021XGrptxmickey[gtk_id],
+ &(paoac_rpt->group_key[offset]),
+ RTW_TKIP_MIC_LEN);
+
+ offset = RTW_KEK_LEN;
+ memcpy(
+ &psecuritypriv->dot118021XGrprxmickey[gtk_id],
+ &(paoac_rpt->group_key[offset]),
+ RTW_TKIP_MIC_LEN);
+ }
+ /* Update broadcast RX IV */
+ if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
+ sz = sizeof(psecuritypriv->iv_seq[0]);
+ for (i = 0 ; i < 4 ; i++)
+ memset(psecuritypriv->iv_seq[i], 0, sz);
+ }
+
+ RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
+ KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
+ }
+
+ rtw_clean_dk_section(adapter);
+
+ rtw_write8(adapter, REG_SECCFG, 0x0c);
+
+ #ifdef CONFIG_GTK_OL_DBG
+ /* if (gtk_keyindex != 5) */
+ dump_sec_cam(RTW_DBGDUMP, adapter);
+ dump_sec_cam_cache(RTW_DBGDUMP, adapter);
+ #endif
+}
+
+static void rtw_hal_update_tx_iv(_adapter *adapter)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+ struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
+ struct sta_info *psta;
+ struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct security_priv *psecpriv = &adapter->securitypriv;
+
+ u16 val16 = 0;
+ u32 val32 = 0;
+ u64 txiv = 0;
+ u8 *pval = NULL;
+
+ psta = rtw_get_stainfo(&adapter->stapriv,
+ get_my_bssid(&pmlmeinfo->network));
+
+ /* Update TX iv data. */
+ pval = (u8 *)&paoac_rpt->iv;
+
+ if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
+ val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
+ ((u16)(paoac_rpt->iv[0]) << 8);
+ val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
+ ((u32)(paoac_rpt->iv[5]) << 8) +
+ ((u32)(paoac_rpt->iv[6]) << 16) +
+ ((u32)(paoac_rpt->iv[7]) << 24);
+ } else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
+ val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
+ ((u16)(paoac_rpt->iv[1]) << 8);
+ val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
+ ((u32)(paoac_rpt->iv[5]) << 8) +
+ ((u32)(paoac_rpt->iv[6]) << 16) +
+ ((u32)(paoac_rpt->iv[7]) << 24);
+ }
+
+ if (psta) {
+ txiv = val16 + ((u64)val32 << 16);
+ if (txiv != 0)
+ psta->dot11txpn.val = txiv;
+ }
+}
+
+static void rtw_hal_update_sw_security_info(_adapter *adapter)
+{
+ rtw_hal_update_tx_iv(adapter);
+ rtw_hal_update_gtk_offload_info(adapter);
+}
+#endif /*CONFIG_GTK_OL*/
+
+static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
+{
+ struct hal_ops *pHalFunc = &adapter->hal_func;
+
+ u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
+ u8 adopt = 1, check_period = 5;
+ u8 ret = _FAIL;
+
+ SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
+ SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
+ SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
+ SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
+#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
+ SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, adapter->hw_port);
+ RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, adapter->hw_port);
+#else
+ RTW_INFO("%s(): enable = %d\n", __func__, enable);
+#endif
+ ret = rtw_hal_fill_h2c_cmd(adapter,
+ H2C_KEEP_ALIVE,
+ H2C_KEEP_ALIVE_CTRL_LEN,
+ u1H2CKeepAliveParm);
+
+ return ret;
+}
+
+static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
+{
+ struct hal_ops *pHalFunc = &adapter->hal_func;
+ u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
+ u8 adopt = 1, check_period = 10, trypkt_num = 0;
+ u8 ret = _FAIL;
+
+ SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
+ SET_H2CCMD_DISCONDECISION_PARM_ADOPT(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
+ SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, adapter->hw_port);
+ RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, adapter->hw_port);
+#else
+ RTW_INFO("%s(): enable = %d\n", __func__, enable);
+#endif
+
+ ret = rtw_hal_fill_h2c_cmd(adapter,
+ H2C_DISCON_DECISION,
+ H2C_DISCON_DECISION_LEN,
+ u1H2CDisconDecisionParm);
+ return ret;
+}
+
+static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
+{
+ struct security_priv *psecpriv = &adapter->securitypriv;
+ struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
+ struct hal_ops *pHalFunc = &adapter->hal_func;
+
+ u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
+ u8 discont_wake = 1, gpionum = 0, gpio_dur = 0;
+ u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
+ u8 sdio_wakeup_enable = 1;
+ u8 gpio_high_active = 0;
+ u8 magic_pkt = 0;
+ u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
+ u8 ret = _FAIL;
+
+#ifdef CONFIG_GPIO_WAKEUP
+ gpio_high_active = ppwrpriv->is_high_active;
+ gpionum = WAKEUP_GPIO_IDX;
+ sdio_wakeup_enable = 0;
+#endif /* CONFIG_GPIO_WAKEUP */
+
+ if (!ppwrpriv->wowlan_pno_enable)
+ magic_pkt = enable;
+
+ if (psecpriv->dot11PrivacyAlgrthm == _WEP40_ || psecpriv->dot11PrivacyAlgrthm == _WEP104_)
+ hw_unicast = 1;
+ else
+ hw_unicast = 0;
+
+ RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
+ enable, change_unit);
+
+ /* time = (gpio_dur/2) * gpio_unit, default:256 ms */
+ if (enable && change_unit) {
+ gpio_dur = 0x40;
+ gpio_unit = 1;
+ gpio_pulse_en = 1;
+ }
+
+#ifdef CONFIG_PLATFORM_ARM_RK3188
+ if (enable) {
+ gpio_pulse_en = 1;
+ gpio_pulse_cnt = 0x04;
+ }
+#endif
+
+ SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
+ SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
+ SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
+ SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
+ SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
+ SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
+
+#ifdef CONFIG_GTK_OL
+ /* GTK rekey only for AES, if GTK rekey is TKIP, then wake up*/
+ if (psecpriv->binstallKCK_KEK == true)
+ SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
+ else
+ SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
+#else
+ SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
+#endif
+ SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
+ SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
+ SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
+
+ SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
+ SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
+
+ SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
+ SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
+
+ ret = rtw_hal_fill_h2c_cmd(adapter,
+ H2C_WOWLAN,
+ H2C_WOWLAN_LEN,
+ u1H2CWoWlanCtrlParm);
+ return ret;
+}
+
+static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
+{
+ struct hal_ops *pHalFunc = &adapter->hal_func;
+ struct security_priv *psecuritypriv = &(adapter->securitypriv);
+ struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
+ struct registry_priv *pregistrypriv = &adapter->registrypriv;
+ u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
+ u8 ret = _FAIL, count = 0;
+
+ RTW_INFO("%s(): enable=%d\n", __func__, enable);
+
+ if (!ppwrpriv->wowlan_pno_enable) {
+ SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
+ u1H2CRemoteWakeCtrlParm, enable);
+ SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
+ u1H2CRemoteWakeCtrlParm, 1);
+#ifdef CONFIG_GTK_OL
+ if (psecuritypriv->binstallKCK_KEK == true) {
+ SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
+ u1H2CRemoteWakeCtrlParm, 1);
+ } else {
+ RTW_INFO("no kck kek\n");
+ SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
+ u1H2CRemoteWakeCtrlParm, 0);
+ }
+#endif /* CONFIG_GTK_OL */
+
+ if (pregistrypriv->default_patterns_en == false) {
+ SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
+ u1H2CRemoteWakeCtrlParm, enable);
+ /*
+ * filter NetBios name service pkt to avoid being waked-up
+ * by this kind of unicast pkt this exceptional modification
+ * is used for match competitor's behavior
+ */
+ SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
+ u1H2CRemoteWakeCtrlParm, enable);
+ }
+
+ if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
+ (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
+ (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
+ SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
+ u1H2CRemoteWakeCtrlParm, 0);
+ } else {
+ SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
+ u1H2CRemoteWakeCtrlParm, 1);
+ }
+
+ if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
+ SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
+ u1H2CRemoteWakeCtrlParm, enable);
+
+ if (IS_HARDWARE_TYPE_8188E(adapter)) {
+ SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
+ u1H2CRemoteWakeCtrlParm, 0);
+ SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
+ u1H2CRemoteWakeCtrlParm, 1);
+ }
+ }
+
+ SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
+ u1H2CRemoteWakeCtrlParm, 1);
+ }
+#ifdef CONFIG_PNO_SUPPORT
+ else {
+ SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
+ u1H2CRemoteWakeCtrlParm, enable);
+ SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
+ u1H2CRemoteWakeCtrlParm, enable);
+ }
+#endif
+
+#ifdef CONFIG_P2P_WOWLAN
+ if (ppwrpriv->wowlan_p2p_mode) {
+ RTW_INFO("P2P OFFLOAD ENABLE\n");
+ SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
+ } else {
+ RTW_INFO("P2P OFFLOAD DISABLE\n");
+ SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
+ }
+#endif /* CONFIG_P2P_WOWLAN */
+
+
+ ret = rtw_hal_fill_h2c_cmd(adapter,
+ H2C_REMOTE_WAKE_CTRL,
+ H2C_REMOTE_WAKE_CTRL_LEN,
+ u1H2CRemoteWakeCtrlParm);
+ return ret;
+}
+
+static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
+{
+ struct hal_ops *pHalFunc = &adapter->hal_func;
+ u8 ret = _FAIL;
+ u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
+
+ RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
+ __func__, group_alg, pairwise_alg);
+ SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
+ pairwise_alg);
+ SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
+ group_alg);
+
+ ret = rtw_hal_fill_h2c_cmd(adapter,
+ H2C_AOAC_GLOBAL_INFO,
+ H2C_AOAC_GLOBAL_INFO_LEN,
+ u1H2CAOACGlobalInfoParm);
+
+ return ret;
+}
+
+#ifdef CONFIG_PNO_SUPPORT
+static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
+ PRSVDPAGE_LOC rsvdpageloc, u8 enable)
+{
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+ struct hal_ops *pHalFunc = &adapter->hal_func;
+
+ u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
+ u8 res = 0, count = 0, ret = _FAIL;
+
+ RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
+ __func__, rsvdpageloc->LocProbePacket,
+ rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
+
+ SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
+ SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
+ SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
+ rsvdpageloc->LocScanInfo);
+ SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
+ rsvdpageloc->LocProbePacket);
+ /*
+ SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
+ rsvdpageloc->LocSSIDInfo);
+ */
+ ret = rtw_hal_fill_h2c_cmd(adapter,
+ H2C_D0_SCAN_OFFLOAD_INFO,
+ H2C_SCAN_OFFLOAD_CTRL_LEN,
+ u1H2CScanOffloadInfoParm);
+ return ret;
+}
+#endif /* CONFIG_PNO_SUPPORT */
+
+void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
+{
+ struct security_priv *psecpriv = &padapter->securitypriv;
+ struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct sta_info *psta = NULL;
+ u16 media_status_rpt;
+ u8 pkt_type = 0;
+ u8 ret = _SUCCESS;
+
+ RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
+
+ rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, false);
+
+ if (enable) {
+ rtw_hal_set_global_info_cmd(padapter,
+ psecpriv->dot118021XGrpPrivacy,
+ psecpriv->dot11PrivacyAlgrthm);
+
+ if (!(ppwrpriv->wowlan_pno_enable)) {
+ rtw_hal_set_disconnect_decision_cmd(padapter, enable);
+#ifdef CONFIG_ARP_KEEP_ALIVE
+ if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
+ (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
+ pkt_type = 0;
+ else
+ pkt_type = 1;
+#else
+ pkt_type = 0;
+#endif /* CONFIG_ARP_KEEP_ALIVE */
+ 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 */
+ } else {
+ rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
+ }
+ RTW_PRINT("-%s()-\n", __func__);
+}
+#endif /* CONFIG_WOWLAN */
+
+#ifdef CONFIG_AP_WOWLAN
+static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
+{
+ struct security_priv *psecpriv = &adapter->securitypriv;
+ struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
+ struct hal_ops *pHalFunc = &adapter->hal_func;
+
+ u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
+ u8 gpionum = 0, gpio_dur = 0;
+ u8 gpio_pulse = enable;
+ u8 sdio_wakeup_enable = 1;
+ u8 gpio_high_active = 0;
+ u8 ret = _FAIL;
+
+#ifdef CONFIG_GPIO_WAKEUP
+ gpio_high_active = ppwrpriv->is_high_active;
+ gpionum = WAKEUP_GPIO_IDX;
+ sdio_wakeup_enable = 0;
+#endif /*CONFIG_GPIO_WAKEUP*/
+
+ RTW_INFO("%s(): enable=%d\n", __func__, enable);
+
+ SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
+ gpionum);
+ SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
+ gpio_pulse);
+ SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
+ gpio_high_active);
+ SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
+ enable);
+ SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
+ gpio_dur);
+
+ ret = rtw_hal_fill_h2c_cmd(adapter,
+ H2C_AP_WOW_GPIO_CTRL,
+ H2C_AP_WOW_GPIO_CTRL_LEN,
+ u1H2CAPWoWlanCtrlParm);
+
+ return ret;
+}
+
+static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
+{
+ struct hal_ops *pHalFunc = &adapter->hal_func;
+ u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
+ u8 ret = _FAIL;
+
+ RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
+
+ SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
+
+ ret = rtw_hal_fill_h2c_cmd(adapter,
+ H2C_AP_OFFLOAD,
+ H2C_AP_OFFLOAD_LEN,
+ u1H2CAPOffloadCtrlParm);
+
+ return ret;
+}
+
+static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
+{
+ struct hal_ops *pHalFunc = &adapter->hal_func;
+ u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
+ u8 ret = _FAIL;
+
+ RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
+
+ SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
+ SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
+ SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
+
+ if (enable)
+ SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
+ else
+ SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
+
+ ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
+ H2C_AP_PS_LEN, ap_ps_parm);
+
+ return ret;
+}
+
+static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
+ PRSVDPAGE_LOC rsvdpageloc)
+{
+ struct hal_ops *pHalFunc = &padapter->hal_func;
+ u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
+ u8 ret = _FAIL, header = 0;
+
+ if (pHalFunc->fill_h2c_cmd == NULL) {
+ RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
+ return;
+ }
+
+ header = rtw_read8(padapter, REG_BCNQ_BDNY);
+
+ RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
+ rsvdpageloc->LocApOffloadBCN,
+ rsvdpageloc->LocProbeRsp,
+ header);
+
+ SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
+ rsvdpageloc->LocApOffloadBCN + header);
+
+ ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
+ H2C_BCN_RSVDPAGE_LEN, rsvdparm);
+
+ if (ret == _FAIL)
+ RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
+
+ rtw_msleep_os(10);
+
+ memset(&rsvdparm, 0, sizeof(rsvdparm));
+
+ SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
+ rsvdpageloc->LocProbeRsp + header);
+
+ ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
+ H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
+
+ if (ret == _FAIL)
+ RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
+
+ rtw_msleep_os(10);
+}
+
+static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
+{
+ rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
+ rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
+ rtw_hal_set_ap_ps_cmd(padapter, enable);
+}
+
+static void rtw_hal_ap_wow_enable(_adapter *padapter)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct hal_ops *pHalFunc = &padapter->hal_func;
+ struct sta_info *psta = NULL;
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+#ifdef DBG_CHECK_FW_PS_STATE
+ struct dvobj_priv *psdpriv = padapter->dvobj;
+ struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
+#endif /*DBG_CHECK_FW_PS_STATE*/
+ int res;
+ u16 media_status_rpt;
+
+ RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
+#ifdef DBG_CHECK_FW_PS_STATE
+ if (rtw_fw_ps_state(padapter) == _FAIL) {
+ pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
+ RTW_PRINT("wowlan enable no leave 32k\n");
+ }
+#endif /*DBG_CHECK_FW_PS_STATE*/
+
+ /* 1. Download WOWLAN FW*/
+ rtw_hal_fw_dl(padapter, true);
+
+ media_status_rpt = RT_MEDIA_CONNECT;
+ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
+ (u8 *)&media_status_rpt);
+
+ issue_beacon(padapter, 0);
+
+ rtw_msleep_os(2);
+ if (IS_HARDWARE_TYPE_8188E(padapter))
+ rtw_hal_disable_tx_report(padapter);
+ /* RX DMA stop */
+ res = rtw_hal_pause_rx_dma(padapter);
+ if (res == _FAIL)
+ RTW_PRINT("[WARNING] pause RX DMA fail\n");
+
+ /* 5. Set Enable WOWLAN H2C command. */
+ RTW_PRINT("Set Enable AP WOWLan cmd\n");
+ rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
+
+ rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
+ rtw_mi_intf_stop(padapter);
+ /* Invoid SE0 reset signal during suspending*/
+ rtw_write8(padapter, REG_RSV_CTRL, 0x20);
+ if (IS_8188F(pHalData->version_id) == false)
+ rtw_write8(padapter, REG_RSV_CTRL, 0x60);
+}
+
+static void rtw_hal_ap_wow_disable(_adapter *padapter)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+ struct hal_ops *pHalFunc = &padapter->hal_func;
+#ifdef DBG_CHECK_FW_PS_STATE
+ struct dvobj_priv *psdpriv = padapter->dvobj;
+ 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*/
+ pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
+
+ RTW_PRINT("wakeup_reason: 0x%02x\n",
+ pwrctl->wowlan_wake_reason);
+
+ rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
+
+ rtw_msleep_os(2);
+#ifdef DBG_CHECK_FW_PS_STATE
+ if (rtw_fw_ps_state(padapter) == _FAIL) {
+ pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
+ RTW_PRINT("wowlan enable no leave 32k\n");
+ }
+#endif /*DBG_CHECK_FW_PS_STATE*/
+
+ if (IS_HARDWARE_TYPE_8188E(padapter))
+ rtw_hal_enable_tx_report(padapter);
+
+ rtw_hal_force_enable_rxdma(padapter);
+
+ rtw_hal_fw_dl(padapter, false);
+
+#ifdef CONFIG_GPIO_WAKEUP
+ 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
+ media_status_rpt = RT_MEDIA_CONNECT;
+
+ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
+ (u8 *)&media_status_rpt);
+
+ issue_beacon(padapter, 0);
+}
+#endif /*CONFIG_AP_WOWLAN*/
+
+#ifdef CONFIG_P2P_WOWLAN
+static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
+{
+ u8 *ssid_ie;
+ sint ssid_len_ori;
+ int len_diff = 0;
+
+ ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
+
+ /* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
+
+ if (ssid_ie && ssid_len_ori > 0) {
+ switch (hidden_ssid_mode) {
+ case 1: {
+ u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
+ u32 remain_len = 0;
+
+ remain_len = ies_len - (next_ie - ies);
+
+ ssid_ie[1] = 0;
+ memcpy(ssid_ie + 2, next_ie, remain_len);
+ len_diff -= ssid_len_ori;
+
+ break;
+ }
+ case 2:
+ memset(&ssid_ie[2], 0, ssid_len_ori);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return len_diff;
+}
+
+static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
+{
+ /* struct xmit_frame *pmgntframe; */
+ /* struct pkt_attrib *pattrib; */
+ /* unsigned char *pframe; */
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *fctrl;
+ unsigned int rate_len;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ u32 pktlen;
+ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
+ /* unsigned long irqL;
+ * struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
+ u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+#ifdef CONFIG_P2P
+ struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
+#endif /* CONFIG_P2P */
+
+ /* for debug */
+ u8 *dbgbuf = pframe;
+ u8 dbgbufLen = 0, index = 0;
+
+ RTW_INFO("%s\n", __func__);
+ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
+ /* _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
+ * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
+
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+
+ fctrl = &(pwlanhdr->frame_ctl);
+ *(fctrl) = 0;
+
+ memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+ memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
+
+ SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
+ /* pmlmeext->mgnt_seq++; */
+ set_frame_sub_type(pframe, WIFI_BEACON);
+
+ pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
+ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+
+ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
+ /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
+#ifdef CONFIG_P2P
+ /* for P2P : Primary Device Type & Device Name */
+ u32 wpsielen = 0, insert_len = 0;
+ u8 *wpsie = NULL;
+ wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
+
+ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
+ uint wps_offset, remainder_ielen;
+ u8 *premainder_ie, *pframe_wscie;
+
+ wps_offset = (uint)(wpsie - cur_network->IEs);
+
+ premainder_ie = wpsie + wpsielen;
+
+ remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
+
+#ifdef CONFIG_IOCTL_CFG80211
+ if (pwdinfo->driver_interface == DRIVER_CFG80211) {
+ if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
+ memcpy(pframe, cur_network->IEs, wps_offset);
+ pframe += wps_offset;
+ pktlen += wps_offset;
+
+ memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
+ pframe += pmlmepriv->wps_beacon_ie_len;
+ pktlen += pmlmepriv->wps_beacon_ie_len;
+
+ /* copy remainder_ie to pframe */
+ memcpy(pframe, premainder_ie, remainder_ielen);
+ pframe += remainder_ielen;
+ pktlen += remainder_ielen;
+ } else {
+ memcpy(pframe, cur_network->IEs, cur_network->IELength);
+ pframe += cur_network->IELength;
+ pktlen += cur_network->IELength;
+ }
+ } else
+#endif /* CONFIG_IOCTL_CFG80211 */
+ {
+ pframe_wscie = pframe + wps_offset;
+ memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
+ pframe += (wps_offset + wpsielen);
+ pktlen += (wps_offset + wpsielen);
+
+ /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
+ /* Primary Device Type */
+ /* Type: */
+ *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
+ insert_len += 2;
+
+ /* Length: */
+ *(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
+ insert_len += 2;
+
+ /* Value: */
+ /* Category ID */
+ *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
+ insert_len += 2;
+
+ /* OUI */
+ *(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
+ insert_len += 4;
+
+ /* Sub Category ID */
+ *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
+ insert_len += 2;
+
+
+ /* Device Name */
+ /* Type: */
+ *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
+ insert_len += 2;
+
+ /* Length: */
+ *(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
+ insert_len += 2;
+
+ /* Value: */
+ memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
+ insert_len += pwdinfo->device_name_len;
+
+
+ /* update wsc ie length */
+ *(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
+
+ /* pframe move to end */
+ pframe += insert_len;
+ pktlen += insert_len;
+
+ /* copy remainder_ie to pframe */
+ memcpy(pframe, premainder_ie, remainder_ielen);
+ pframe += remainder_ielen;
+ pktlen += remainder_ielen;
+ }
+ } else
+#endif /* CONFIG_P2P */
+ {
+ int len_diff;
+ memcpy(pframe, cur_network->IEs, cur_network->IELength);
+ len_diff = update_hidden_ssid(
+ pframe + _BEACON_IE_OFFSET_
+ , cur_network->IELength - _BEACON_IE_OFFSET_
+ , pmlmeinfo->hidden_ssid_mode
+ );
+ pframe += (cur_network->IELength + len_diff);
+ pktlen += (cur_network->IELength + len_diff);
+ }
+#ifdef CONFIG_P2P
+ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
+ u32 len;
+#ifdef CONFIG_IOCTL_CFG80211
+ if (pwdinfo->driver_interface == DRIVER_CFG80211) {
+ len = pmlmepriv->p2p_beacon_ie_len;
+ if (pmlmepriv->p2p_beacon_ie && len > 0)
+ memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
+ } else
+#endif /* CONFIG_IOCTL_CFG80211 */
+ {
+ len = build_beacon_p2p_ie(pwdinfo, pframe);
+ }
+
+ pframe += len;
+ pktlen += len;
+
+ #ifdef CONFIG_WFD
+ len = rtw_append_beacon_wfd_ie(padapter, pframe);
+ pframe += len;
+ pktlen += len;
+ #endif
+
+ }
+#endif /* CONFIG_P2P */
+
+ goto _issue_bcn;
+
+ }
+
+ /* below for ad-hoc mode */
+
+ /* timestamp will be inserted by hardware */
+ pframe += 8;
+ pktlen += 8;
+
+ /* beacon interval: 2 bytes */
+
+ memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
+
+ pframe += 2;
+ pktlen += 2;
+
+ /* capability info: 2 bytes */
+
+ memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
+
+ pframe += 2;
+ pktlen += 2;
+
+ /* SSID */
+ pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
+
+ /* supported rates... */
+ rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
+ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
+
+ /* DS parameter set */
+ pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
+
+ /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
+ {
+ u8 erpinfo = 0;
+ u32 ATIMWindow;
+ /* IBSS Parameter Set... */
+ /* ATIMWindow = cur->Configuration.ATIMWindow; */
+ ATIMWindow = 0;
+ pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
+
+ /* ERP IE */
+ pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
+ }
+
+
+ /* EXTERNDED SUPPORTED RATE */
+ if (rate_len > 8)
+ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
+
+
+ /* todo:HT for adhoc */
+
+_issue_bcn:
+
+ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
+ /* pmlmepriv->update_bcn = false;
+ *
+ * _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
+ * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
+
+ *pLength = pktlen;
+}
+
+static int get_reg_classes_full_count(struct p2p_channels channel_list)
+{
+ int cnt = 0;
+ int i;
+
+ for (i = 0; i < channel_list.reg_classes; i++)
+ cnt += channel_list.reg_class[i].channels;
+
+ return cnt;
+}
+
+static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
+{
+ /* struct xmit_frame *pmgntframe; */
+ /* struct pkt_attrib *pattrib; */
+ /* unsigned char *pframe; */
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *fctrl;
+ unsigned char *mac;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
+ u16 beacon_interval = 100;
+ u16 capInfo = 0;
+ struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
+ u8 wpsie[255] = { 0x00 };
+ u32 wpsielen = 0, p2pielen = 0;
+ u32 pktlen;
+#ifdef CONFIG_WFD
+ u32 wfdielen = 0;
+#endif
+#ifdef CONFIG_INTEL_WIDI
+ u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
+#endif /* CONFIG_INTEL_WIDI */
+
+ /* for debug */
+ u8 *dbgbuf = pframe;
+ u8 dbgbufLen = 0, index = 0;
+
+ RTW_INFO("%s\n", __func__);
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ mac = adapter_mac_addr(padapter);
+
+ fctrl = &(pwlanhdr->frame_ctl);
+ *(fctrl) = 0;
+
+ /* DA filled by FW */
+ memset(pwlanhdr->addr1, 0, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
+
+ /* Use the device address for BSSID field. */
+ memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
+
+ SetSeqNum(pwlanhdr, 0);
+ set_frame_sub_type(fctrl, WIFI_PROBERSP);
+
+ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pframe += pktlen;
+
+
+ /* timestamp will be inserted by hardware */
+ pframe += 8;
+ pktlen += 8;
+
+ /* beacon interval: 2 bytes */
+ memcpy(pframe, (unsigned char *) &beacon_interval, 2);
+ pframe += 2;
+ pktlen += 2;
+
+ /* capability info: 2 bytes */
+ /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
+ capInfo |= cap_ShortPremble;
+ capInfo |= cap_ShortSlot;
+
+ memcpy(pframe, (unsigned char *) &capInfo, 2);
+ pframe += 2;
+ pktlen += 2;
+
+
+ /* SSID */
+ pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
+
+ /* supported rates... */
+ /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
+ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
+
+ /* DS parameter set */
+ pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
+
+#ifdef CONFIG_IOCTL_CFG80211
+ if (pwdinfo->driver_interface == DRIVER_CFG80211) {
+ if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
+ /* WPS IE */
+ memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
+ pktlen += pmlmepriv->wps_probe_resp_ie_len;
+ pframe += pmlmepriv->wps_probe_resp_ie_len;
+
+ /* P2P IE */
+ memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
+ pktlen += pmlmepriv->p2p_probe_resp_ie_len;
+ pframe += pmlmepriv->p2p_probe_resp_ie_len;
+ }
+ } else
+#endif /* CONFIG_IOCTL_CFG80211 */
+ {
+
+ /* Todo: WPS IE */
+ /* Noted by Albert 20100907 */
+ /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
+
+ wpsielen = 0;
+ /* WPS OUI */
+ *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
+ wpsielen += 4;
+
+ /* WPS version */
+ /* Type: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
+ wpsielen += 2;
+
+ /* Length: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
+ wpsielen += 2;
+
+ /* Value: */
+ wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
+
+#ifdef CONFIG_INTEL_WIDI
+ /* Commented by Kurt */
+ /* Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext. */
+ if (!memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == false
+ || pmlmepriv->num_p2p_sdt != 0) {
+ /* Sec dev type */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SEC_DEV_TYPE_LIST);
+ wpsielen += 2;
+
+ /* Length: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
+ wpsielen += 2;
+
+ /* Value: */
+ /* Category ID */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_DISPLAYS);
+ wpsielen += 2;
+
+ /* OUI */
+ *(u32 *)(wpsie + wpsielen) = cpu_to_be32(INTEL_DEV_TYPE_OUI);
+ wpsielen += 4;
+
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_WIDI_CONSUMER_SINK);
+ wpsielen += 2;
+
+ if (!memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == false) {
+ /* Vendor Extension */
+ memcpy(wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN);
+ wpsielen += L2SDTA_SERVICE_VE_LEN;
+ }
+ }
+#endif /* CONFIG_INTEL_WIDI */
+
+ /* WiFi Simple Config State */
+ /* Type: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
+ wpsielen += 2;
+
+ /* Length: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
+ wpsielen += 2;
+
+ /* Value: */
+ wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
+
+ /* Response Type */
+ /* Type: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
+ wpsielen += 2;
+
+ /* Length: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
+ wpsielen += 2;
+
+ /* Value: */
+ wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
+
+ /* UUID-E */
+ /* Type: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
+ wpsielen += 2;
+
+ /* Length: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
+ wpsielen += 2;
+
+ /* Value: */
+ if (pwdinfo->external_uuid == 0) {
+ memset(wpsie + wpsielen, 0x0, 16);
+ memcpy(wpsie + wpsielen, mac, ETH_ALEN);
+ } else
+ memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
+ wpsielen += 0x10;
+
+ /* Manufacturer */
+ /* Type: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
+ wpsielen += 2;
+
+ /* Length: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
+ wpsielen += 2;
+
+ /* Value: */
+ memcpy(wpsie + wpsielen, "Realtek", 7);
+ wpsielen += 7;
+
+ /* Model Name */
+ /* Type: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
+ wpsielen += 2;
+
+ /* Length: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
+ wpsielen += 2;
+
+ /* Value: */
+ memcpy(wpsie + wpsielen, "8192CU", 6);
+ wpsielen += 6;
+
+ /* Model Number */
+ /* Type: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
+ wpsielen += 2;
+
+ /* Length: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
+ wpsielen += 2;
+
+ /* Value: */
+ wpsie[wpsielen++] = 0x31; /* character 1 */
+
+ /* Serial Number */
+ /* Type: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
+ wpsielen += 2;
+
+ /* Length: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
+ wpsielen += 2;
+
+ /* Value: */
+ memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
+ wpsielen += ETH_ALEN;
+
+ /* Primary Device Type */
+ /* Type: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
+ wpsielen += 2;
+
+ /* Length: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
+ wpsielen += 2;
+
+ /* Value: */
+ /* Category ID */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
+ wpsielen += 2;
+
+ /* OUI */
+ *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
+ wpsielen += 4;
+
+ /* Sub Category ID */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
+ wpsielen += 2;
+
+ /* Device Name */
+ /* Type: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
+ wpsielen += 2;
+
+ /* Length: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
+ wpsielen += 2;
+
+ /* Value: */
+ memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
+ wpsielen += pwdinfo->device_name_len;
+
+ /* Config Method */
+ /* Type: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
+ wpsielen += 2;
+
+ /* Length: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
+ wpsielen += 2;
+
+ /* Value: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
+ wpsielen += 2;
+
+
+ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
+
+
+ p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
+ pframe += p2pielen;
+ pktlen += p2pielen;
+ }
+
+#ifdef CONFIG_WFD
+ wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
+ pframe += wfdielen;
+ pktlen += wfdielen;
+#endif
+
+ *pLength = pktlen;
+}
+
+static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
+{
+ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
+ u8 action = P2P_PUB_ACTION_ACTION;
+ u32 p2poui = cpu_to_be32(P2POUI);
+ u8 oui_subtype = P2P_GO_NEGO_RESP;
+ u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
+ u8 p2pielen = 0, i;
+ uint wpsielen = 0;
+ u16 wps_devicepassword_id = 0x0000;
+ uint wps_devicepassword_id_len = 0;
+ u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
+ u16 len_channellist_attr = 0;
+ u32 pktlen;
+ u8 dialogToken = 0;
+
+ /* struct xmit_frame *pmgntframe; */
+ /* struct pkt_attrib *pattrib; */
+ /* unsigned char *pframe; */
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *fctrl;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
+ /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
+
+#ifdef CONFIG_WFD
+ u32 wfdielen = 0;
+#endif
+
+ /* for debug */
+ u8 *dbgbuf = pframe;
+ u8 dbgbufLen = 0, index = 0;
+
+ RTW_INFO("%s\n", __func__);
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ fctrl = &(pwlanhdr->frame_ctl);
+ *(fctrl) = 0;
+
+ /* RA, filled by FW */
+ memset(pwlanhdr->addr1, 0, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+ memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
+
+ SetSeqNum(pwlanhdr, 0);
+ set_frame_sub_type(pframe, WIFI_ACTION);
+
+ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pframe += pktlen;
+
+ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
+
+ /* dialog token, filled by FW */
+ pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
+
+ memset(wpsie, 0x00, 255);
+ wpsielen = 0;
+
+ /* WPS Section */
+ wpsielen = 0;
+ /* WPS OUI */
+ *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
+ wpsielen += 4;
+
+ /* WPS version */
+ /* Type: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
+ wpsielen += 2;
+
+ /* Length: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
+ wpsielen += 2;
+
+ /* Value: */
+ wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
+
+ /* Device Password ID */
+ /* Type: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
+ wpsielen += 2;
+
+ /* Length: */
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
+ wpsielen += 2;
+
+ /* Value: */
+ if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
+ else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
+ else
+ *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
+ wpsielen += 2;
+
+ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
+
+
+ /* P2P IE Section. */
+
+ /* P2P OUI */
+ p2pielen = 0;
+ p2pie[p2pielen++] = 0x50;
+ p2pie[p2pielen++] = 0x6F;
+ p2pie[p2pielen++] = 0x9A;
+ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
+
+ /* Commented by Albert 20100908 */
+ /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
+ /* 1. Status */
+ /* 2. P2P Capability */
+ /* 3. Group Owner Intent */
+ /* 4. Configuration Timeout */
+ /* 5. Operating Channel */
+ /* 6. Intended P2P Interface Address */
+ /* 7. Channel List */
+ /* 8. Device Info */
+ /* 9. Group ID ( Only GO ) */
+
+
+ /* ToDo: */
+
+ /* P2P Status */
+ /* Type: */
+ p2pie[p2pielen++] = P2P_ATTR_STATUS;
+
+ /* Length: */
+ *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
+ p2pielen += 2;
+
+ /* Value, filled by FW */
+ p2pie[p2pielen++] = 1;
+
+ /* P2P Capability */
+ /* Type: */
+ p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
+
+ /* Length: */
+ *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
+ p2pielen += 2;
+
+ /* Value: */
+ /* Device Capability Bitmap, 1 byte */
+
+ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
+ /* Commented by Albert 2011/03/08 */
+ /* According to the P2P specification */
+ /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
+ p2pie[p2pielen++] = 0;
+ } else {
+ /* Be group owner or meet the error case */
+ p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
+ }
+
+ /* Group Capability Bitmap, 1 byte */
+ if (pwdinfo->persistent_supported)
+ p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
+ else
+ p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
+
+ /* Group Owner Intent */
+ /* Type: */
+ p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
+
+ /* Length: */
+ *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
+ p2pielen += 2;
+
+ /* Value: */
+ if (pwdinfo->peer_intent & 0x01) {
+ /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
+ p2pie[p2pielen++] = (pwdinfo->intent << 1);
+ } else {
+ /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
+ p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
+ }
+
+
+ /* Configuration Timeout */
+ /* Type: */
+ p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
+
+ /* Length: */
+ *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
+ p2pielen += 2;
+
+ /* Value: */
+ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
+ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
+
+ /* Operating Channel */
+ /* Type: */
+ p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
+
+ /* Length: */
+ *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
+ p2pielen += 2;
+
+ /* Value: */
+ /* Country String */
+ p2pie[p2pielen++] = 'X';
+ p2pie[p2pielen++] = 'X';
+
+ /* The third byte should be set to 0x04. */
+ /* Described in the "Operating Channel Attribute" section. */
+ p2pie[p2pielen++] = 0x04;
+
+ /* Operating Class */
+ if (pwdinfo->operating_channel <= 14) {
+ /* Operating Class */
+ p2pie[p2pielen++] = 0x51;
+ } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
+ /* Operating Class */
+ p2pie[p2pielen++] = 0x73;
+ } else {
+ /* Operating Class */
+ p2pie[p2pielen++] = 0x7c;
+ }
+
+ /* Channel Number */
+ p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
+
+ /* Intended P2P Interface Address */
+ /* Type: */
+ p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
+
+ /* Length: */
+ *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
+ p2pielen += 2;
+
+ /* Value: */
+ memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
+ p2pielen += ETH_ALEN;
+
+ /* Channel List */
+ /* Type: */
+ p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
+
+ /* Country String(3) */
+ /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
+ /* + number of channels in all classes */
+ len_channellist_attr = 3
+ + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
+ + get_reg_classes_full_count(pmlmeext->channel_list);
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if (rtw_mi_buddy_check_fwstate(padapter, _FW_LINKED))
+ *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
+ else
+ *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
+
+#else
+
+ *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
+
+#endif
+ p2pielen += 2;
+
+ /* Value: */
+ /* Country String */
+ p2pie[p2pielen++] = 'X';
+ p2pie[p2pielen++] = 'X';
+
+ /* The third byte should be set to 0x04. */
+ /* Described in the "Operating Channel Attribute" section. */
+ p2pie[p2pielen++] = 0x04;
+
+ /* Channel Entry List */
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if (rtw_mi_check_status(padapter, MI_LINKED)) {
+ u8 union_ch = rtw_mi_get_union_chan(padapter);
+
+ /* Operating Class */
+ if (union_ch > 14) {
+ if (union_ch >= 149)
+ p2pie[p2pielen++] = 0x7c;
+ else
+ p2pie[p2pielen++] = 0x73;
+ } else
+ p2pie[p2pielen++] = 0x51;
+
+
+ /* Number of Channels */
+ /* Just support 1 channel and this channel is AP's channel */
+ p2pie[p2pielen++] = 1;
+
+ /* Channel List */
+ p2pie[p2pielen++] = union_ch;
+ } else {
+ int i, j;
+ for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
+ /* Operating Class */
+ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
+
+ /* Number of Channels */
+ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
+
+ /* Channel List */
+ for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
+ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
+ }
+ }
+#else /* CONFIG_CONCURRENT_MODE */
+ {
+ int i, j;
+ for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
+ /* Operating Class */
+ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
+
+ /* Number of Channels */
+ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
+
+ /* Channel List */
+ for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
+ p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
+ }
+ }
+#endif /* CONFIG_CONCURRENT_MODE */
+
+
+ /* Device Info */
+ /* Type: */
+ p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
+
+ /* Length: */
+ /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
+ /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
+ *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
+ p2pielen += 2;
+
+ /* Value: */
+ /* P2P Device Address */
+ memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
+ p2pielen += ETH_ALEN;
+
+ /* Config Method */
+ /* This field should be big endian. Noted by P2P specification. */
+
+ *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
+
+ p2pielen += 2;
+
+ /* Primary Device Type */
+ /* Category ID */
+ *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
+ p2pielen += 2;
+
+ /* OUI */
+ *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
+ p2pielen += 4;
+
+ /* Sub Category ID */
+ *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
+ p2pielen += 2;
+
+ /* Number of Secondary Device Types */
+ p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
+
+ /* Device Name */
+ /* Type: */
+ *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
+ p2pielen += 2;
+
+ /* Length: */
+ *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
+ p2pielen += 2;
+
+ /* Value: */
+ memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
+ p2pielen += pwdinfo->device_name_len;
+
+ if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
+ /* Group ID Attribute */
+ /* Type: */
+ p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
+
+ /* Length: */
+ *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
+ p2pielen += 2;
+
+ /* Value: */
+ /* p2P Device Address */
+ memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
+ p2pielen += ETH_ALEN;
+
+ /* SSID */
+ memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
+ p2pielen += pwdinfo->nego_ssidlen;
+
+ }
+
+ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
+
+#ifdef CONFIG_WFD
+ wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
+ pframe += wfdielen;
+ pktlen += wfdielen;
+#endif
+ *pLength = pktlen;
+}
+
+static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
+{
+ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
+ u8 action = P2P_PUB_ACTION_ACTION;
+ u32 p2poui = cpu_to_be32(P2POUI);
+ u8 oui_subtype = P2P_INVIT_RESP;
+ u8 p2pie[255] = { 0x00 };
+ u8 p2pielen = 0, i;
+ u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
+ u16 len_channellist_attr = 0;
+ u32 pktlen;
+ u8 dialogToken = 0;
+#ifdef CONFIG_WFD
+ u32 wfdielen = 0;
+#endif
+
+ /* struct xmit_frame *pmgntframe; */
+ /* struct pkt_attrib *pattrib; */
+ /* unsigned char *pframe; */
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *fctrl;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
+
+ /* for debug */
+ u8 *dbgbuf = pframe;
+ u8 dbgbufLen = 0, index = 0;
+
+
+ RTW_INFO("%s\n", __func__);
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ fctrl = &(pwlanhdr->frame_ctl);
+ *(fctrl) = 0;
+
+ /* RA fill by FW */
+ memset(pwlanhdr->addr1, 0, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+
+ /* BSSID fill by FW */
+ memset(pwlanhdr->addr3, 0, ETH_ALEN);
+
+ SetSeqNum(pwlanhdr, 0);
+ set_frame_sub_type(pframe, WIFI_ACTION);
+
+ pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
+ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+
+ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
+
+ /* dialog token, filled by FW */
+ pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
+
+ /* P2P IE Section. */
+
+ /* P2P OUI */
+ p2pielen = 0;
+ p2pie[p2pielen++] = 0x50;
+ p2pie[p2pielen++] = 0x6F;
+ p2pie[p2pielen++] = 0x9A;
+ p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
+
+ /* Commented by Albert 20101005 */
+ /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
+ /* 1. Status */
+ /* 2. Configuration Timeout */
+ /* 3. Operating Channel ( Only GO ) */
+ /* 4. P2P Group BSSID ( Only GO ) */
+ /* 5. Channel List */
+
+ /* P2P Status */
+ /* Type: */
+ p2pie[p2pielen++] = P2P_ATTR_STATUS;
+
+ /* Length: */
+ *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
+ p2pielen += 2;
+
+ /* Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
+ p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
+
+ /* Configuration Timeout */
+ /* Type: */
+ p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
+
+ /* Length: */
+ *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
+ p2pielen += 2;
+
+ /* Value: */
+ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
+ p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
+
+ /* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
+ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
+
+#ifdef CONFIG_WFD
+ wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
+ pframe += wfdielen;
+ pktlen += wfdielen;
+#endif
+
+ *pLength = pktlen;
+}
+
+static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
+{
+ unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
+ u8 action = P2P_PUB_ACTION_ACTION;
+ u8 dialogToken = 0;
+ u32 p2poui = cpu_to_be32(P2POUI);
+ u8 oui_subtype = P2P_PROVISION_DISC_RESP;
+ u8 wpsie[100] = { 0x00 };
+ u8 wpsielen = 0;
+ u32 pktlen;
+#ifdef CONFIG_WFD
+ u32 wfdielen = 0;
+#endif
+
+ /* struct xmit_frame *pmgntframe; */
+ /* struct pkt_attrib *pattrib; */
+ /* unsigned char *pframe; */
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *fctrl;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
+
+ /* for debug */
+ u8 *dbgbuf = pframe;
+ u8 dbgbufLen = 0, index = 0;
+
+ RTW_INFO("%s\n", __func__);
+
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ fctrl = &(pwlanhdr->frame_ctl);
+ *(fctrl) = 0;
+
+ /* RA filled by FW */
+ memset(pwlanhdr->addr1, 0, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+ memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
+
+ SetSeqNum(pwlanhdr, 0);
+ set_frame_sub_type(pframe, WIFI_ACTION);
+
+ pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
+ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+
+ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
+ /* dialog token, filled by FW */
+ pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
+
+ wpsielen = 0;
+ /* WPS OUI */
+ /* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
+ RTW_PUT_BE32(wpsie, WPSOUI);
+ wpsielen += 4;
+
+ /* Config Method */
+ /* Type: */
+ /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
+ RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
+ wpsielen += 2;
+
+ /* Length: */
+ /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
+ RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
+ wpsielen += 2;
+
+ /* Value: filled by FW, default value is PBC */
+ /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
+ RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
+ wpsielen += 2;
+
+ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
+
+#ifdef CONFIG_WFD
+ wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
+ pframe += wfdielen;
+ pktlen += wfdielen;
+#endif
+
+ *pLength = pktlen;
+}
+
+u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
+{
+ u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
+ struct hal_ops *pHalFunc = &adapter->hal_func;
+ u8 ret = _FAIL;
+
+ RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
+ rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
+ rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
+ rsvdpageloc->LocPDRsp);
+
+ SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
+ SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
+ SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
+ SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
+ SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
+
+ /* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
+ ret = rtw_hal_fill_h2c_cmd(adapter,
+ H2C_P2P_OFFLOAD_RSVD_PAGE,
+ H2C_P2PRSVDPAGE_LOC_LEN,
+ u1H2CP2PRsvdPageParm);
+
+ return ret;
+}
+
+u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
+{
+
+ u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
+ struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
+ struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
+ struct hal_ops *pHalFunc = &adapter->hal_func;
+ u8 ret = _FAIL;
+
+ memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
+ RTW_INFO("%s\n", __func__);
+ switch (pwdinfo->role) {
+ case P2P_ROLE_DEVICE:
+ RTW_INFO("P2P_ROLE_DEVICE\n");
+ p2p_wowlan_offload->role = 0;
+ break;
+ case P2P_ROLE_CLIENT:
+ RTW_INFO("P2P_ROLE_CLIENT\n");
+ p2p_wowlan_offload->role = 1;
+ break;
+ case P2P_ROLE_GO:
+ RTW_INFO("P2P_ROLE_GO\n");
+ p2p_wowlan_offload->role = 2;
+ break;
+ default:
+ RTW_INFO("P2P_ROLE_DISABLE\n");
+ break;
+ }
+ p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
+ p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
+ offload_cmd = (u8 *)p2p_wowlan_offload;
+ RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
+
+ ret = rtw_hal_fill_h2c_cmd(adapter,
+ H2C_P2P_OFFLOAD,
+ H2C_P2P_OFFLOAD_LEN,
+ offload_cmd);
+ return ret;
+
+ /* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
+}
+#endif /* CONFIG_P2P_WOWLAN */
+
+static void rtw_hal_construct_beacon(_adapter *padapter,
+ u8 *pframe, u32 *pLength)
+{
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *fctrl;
+ u32 rate_len, pktlen;
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
+ u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+
+ /* RTW_INFO("%s\n", __func__); */
+
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ fctrl = &(pwlanhdr->frame_ctl);
+ *(fctrl) = 0;
+
+ memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+ memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
+
+ SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
+ /* pmlmeext->mgnt_seq++; */
+ set_frame_sub_type(pframe, WIFI_BEACON);
+
+ pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
+ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+
+ /* timestamp will be inserted by hardware */
+ pframe += 8;
+ pktlen += 8;
+
+ /* beacon interval: 2 bytes */
+ memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
+
+ pframe += 2;
+ pktlen += 2;
+
+ /* capability info: 2 bytes */
+ memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
+
+ pframe += 2;
+ pktlen += 2;
+
+ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
+ /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
+ pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
+ memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
+
+ goto _ConstructBeacon;
+ }
+
+ /* below for ad-hoc mode */
+
+ /* SSID */
+ pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
+
+ /* supported rates... */
+ rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
+ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
+
+ /* DS parameter set */
+ pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
+
+ if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
+ u32 ATIMWindow;
+ /* IBSS Parameter Set... */
+ /* ATIMWindow = cur->Configuration.ATIMWindow; */
+ ATIMWindow = 0;
+ pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
+ }
+
+
+ /* todo: ERP IE */
+
+
+ /* EXTERNDED SUPPORTED RATE */
+ if (rate_len > 8)
+ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
+
+
+ /* todo:HT for adhoc */
+
+_ConstructBeacon:
+
+ if ((pktlen + TXDESC_SIZE) > 512) {
+ RTW_INFO("beacon frame too large\n");
+ return;
+ }
+
+ *pLength = pktlen;
+
+ /* RTW_INFO("%s bcn_sz=%d\n", __func__, pktlen); */
+
+}
+
+static void rtw_hal_construct_PSPoll(_adapter *padapter,
+ u8 *pframe, u32 *pLength)
+{
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *fctrl;
+ u32 pktlen;
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ /* RTW_INFO("%s\n", __func__); */
+
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ /* Frame control. */
+ fctrl = &(pwlanhdr->frame_ctl);
+ *(fctrl) = 0;
+ SetPwrMgt(fctrl);
+ set_frame_sub_type(pframe, WIFI_PSPOLL);
+
+ /* AID. */
+ set_duration(pframe, (pmlmeinfo->aid | 0xc000));
+
+ /* BSSID. */
+ memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+
+ /* TA. */
+ memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+
+ *pLength = 16;
+}
+
+void rtw_hal_construct_NullFunctionData(
+ PADAPTER padapter,
+ u8 *pframe,
+ u32 *pLength,
+ u8 *StaAddr,
+ u8 bQoS,
+ u8 AC,
+ u8 bEosp,
+ u8 bForcePowerSave)
+{
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *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);
+
+
+ /* RTW_INFO("%s:%d\n", __func__, bForcePowerSave); */
+
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ fctrl = &pwlanhdr->frame_ctl;
+ *(fctrl) = 0;
+ if (bForcePowerSave)
+ SetPwrMgt(fctrl);
+
+ switch (cur_network->network.InfrastructureMode) {
+ case Ndis802_11Infrastructure:
+ SetToDs(fctrl);
+ memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+ memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+ memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
+ break;
+ case Ndis802_11APMode:
+ SetFrDs(fctrl);
+ memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+ memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
+ break;
+ case Ndis802_11IBSS:
+ default:
+ memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+ memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+ break;
+ }
+
+ SetSeqNum(pwlanhdr, 0);
+
+ if (bQoS == true) {
+ struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
+
+ set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
+
+ pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
+ SetPriority(&pwlanqoshdr->qc, AC);
+ SetEOSP(&pwlanqoshdr->qc, bEosp);
+
+ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
+ } else {
+ set_frame_sub_type(pframe, WIFI_DATA_NULL);
+
+ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ }
+
+ *pLength = pktlen;
+}
+
+static void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
+ u8 *StaAddr, bool bHideSSID)
+{
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *fctrl;
+ u8 *mac, *bssid;
+ u32 pktlen;
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
+
+ /*RTW_INFO("%s\n", __func__);*/
+
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ mac = adapter_mac_addr(padapter);
+ bssid = cur_network->MacAddress;
+
+ fctrl = &(pwlanhdr->frame_ctl);
+ *(fctrl) = 0;
+ memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
+ memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
+
+ SetSeqNum(pwlanhdr, 0);
+ set_frame_sub_type(fctrl, WIFI_PROBERSP);
+
+ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pframe += pktlen;
+
+ if (cur_network->IELength > MAX_IE_SZ)
+ return;
+
+ memcpy(pframe, cur_network->IEs, cur_network->IELength);
+ pframe += cur_network->IELength;
+ pktlen += cur_network->IELength;
+
+ *pLength = pktlen;
+}
+
+#ifdef CONFIG_WOWLAN
+static void rtw_hal_append_tkip_mic(PADAPTER padapter,
+ u8 *pframe, u32 offset)
+{
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ struct mic_data micdata;
+ struct sta_info *psta = NULL;
+ int res = 0;
+
+ u8 *payload = (u8 *)(pframe + offset);
+
+ u8 mic[8];
+ u8 priority[4] = {0x0};
+ u8 null_key[16] = {0x0};
+
+ RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
+
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ psta = rtw_get_stainfo(&padapter->stapriv,
+ get_my_bssid(&(pmlmeinfo->network)));
+ if (psta != NULL) {
+ res = !memcmp(&psta->dot11tkiptxmickey.skey[0],
+ null_key, 16);
+ if (res)
+ RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
+ rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
+ }
+
+ rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); /* DA */
+
+ rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
+
+ priority[0] = 0;
+
+ rtw_secmicappend(&micdata, &priority[0], 4);
+
+ rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
+
+ rtw_secgetmic(&micdata, &(mic[0]));
+
+ payload += 36;
+
+ memcpy(payload, &(mic[0]), 8);
+}
+/*
+ * Description:
+ * Construct the ARP response packet to support ARP offload.
+ * */
+static void rtw_hal_construct_ARPRsp(
+ PADAPTER padapter,
+ u8 *pframe,
+ u32 *pLength,
+ u8 *pIPAddress
+)
+{
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *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 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
+ u8 *pARPRspPkt = pframe;
+ /* for TKIP Cal MIC */
+ u8 *payload = pframe;
+ u8 EncryptionHeadOverhead = 0, arp_offset = 0;
+ /* RTW_INFO("%s:%d\n", __func__, bForcePowerSave); */
+
+ 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);
+ memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+ memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+ memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+
+ SetSeqNum(pwlanhdr, 0);
+ set_duration(pwlanhdr, 0);
+ /* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
+ /* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
+ /* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
+ /* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
+ /* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
+ /* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
+
+ /* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
+ /* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 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) {
+ memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
+ *pLength += EncryptionHeadOverhead;
+ /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
+ SetPrivacy(fctrl);
+ }
+
+ /* ------------------------------------------------------------------------- */
+ /* Frame Body. */
+ /* ------------------------------------------------------------------------- */
+ arp_offset = *pLength;
+ pARPRspPkt = (u8 *)(pframe + arp_offset);
+ payload = pARPRspPkt; /* Get Payload pointer */
+ /* LLC header */
+ memcpy(pARPRspPkt, ARPLLCHeader, 8);
+ *pLength += 8;
+
+ /* ARP element */
+ pARPRspPkt += 8;
+ SET_ARP_PKT_HW(pARPRspPkt, 0x0100);
+ SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008); /* IP protocol */
+ SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6);
+ SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4);
+ SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200); /* ARP response */
+ SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
+ SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
+#ifdef CONFIG_ARP_KEEP_ALIVE
+ if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
+ SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
+ SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
+ } else
+#endif
+ {
+ SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt,
+ get_my_bssid(&(pmlmeinfo->network)));
+ SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt,
+ pIPAddress);
+ RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __func__,
+ MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
+ RTW_INFO("%s Target IP Addr" IP_FMT "\n", __func__,
+ IP_ARG(pIPAddress));
+ }
+
+ *pLength += 28;
+
+ if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
+ if (IS_HARDWARE_TYPE_8188E(padapter))
+ rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
+ *pLength += 8;
+ }
+}
+
+#ifdef CONFIG_PNO_SUPPORT
+static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
+ u32 *pLength, pno_ssid_t *ssid)
+{
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *fctrl;
+ u32 pktlen;
+ unsigned char *mac;
+ unsigned char bssrate[NumRates];
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ int bssrate_len = 0;
+ u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ mac = adapter_mac_addr(padapter);
+
+ fctrl = &(pwlanhdr->frame_ctl);
+ *(fctrl) = 0;
+
+ memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
+ memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
+
+ memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
+
+ SetSeqNum(pwlanhdr, 0);
+ set_frame_sub_type(pframe, WIFI_PROBEREQ);
+
+ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pframe += pktlen;
+
+ if (ssid == NULL)
+ pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
+ else {
+ /* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
+ pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
+ }
+
+ get_rate_set(padapter, bssrate, &bssrate_len);
+
+ if (bssrate_len > 8) {
+ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
+ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
+ } else
+ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
+
+ *pLength = pktlen;
+}
+
+static void rtw_hal_construct_PNO_info(_adapter *padapter,
+ u8 *pframe, u32 *pLength)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+ int i;
+
+ u8 *pPnoInfoPkt = pframe;
+ pPnoInfoPkt = (u8 *)(pframe + *pLength);
+ memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
+
+ pPnoInfoPkt += 1;
+ memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
+
+ pPnoInfoPkt += 3;
+ memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
+
+ pPnoInfoPkt += 4;
+ memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
+
+ pPnoInfoPkt += 4;
+ memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
+
+ pPnoInfoPkt += 4;
+ memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
+
+ pPnoInfoPkt += MAX_PNO_LIST_COUNT;
+ memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
+
+ pPnoInfoPkt += MAX_PNO_LIST_COUNT;
+ memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
+
+ pPnoInfoPkt += MAX_PNO_LIST_COUNT;
+ memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
+
+ pPnoInfoPkt += MAX_HIDDEN_AP;
+
+ /*
+ SSID is located at 128th Byte in NLO info Page
+ */
+
+ *pLength += 128;
+ pPnoInfoPkt = pframe + 128;
+
+ for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
+ memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
+ pwrctl->pnlo_info->ssid_length[i]);
+ *pLength += WLAN_SSID_MAXLEN;
+ pPnoInfoPkt += WLAN_SSID_MAXLEN;
+ }
+}
+
+static void rtw_hal_construct_ssid_list(_adapter *padapter,
+ u8 *pframe, u32 *pLength)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+ u8 *pSSIDListPkt = pframe;
+ int i;
+
+ pSSIDListPkt = (u8 *)(pframe + *pLength);
+
+ for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
+ memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
+ pwrctl->pnlo_info->ssid_length[i]);
+
+ *pLength += WLAN_SSID_MAXLEN;
+ pSSIDListPkt += WLAN_SSID_MAXLEN;
+ }
+}
+
+static void rtw_hal_construct_scan_info(_adapter *padapter,
+ u8 *pframe, u32 *pLength)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+ u8 *pScanInfoPkt = pframe;
+ int i;
+
+ pScanInfoPkt = (u8 *)(pframe + *pLength);
+
+ memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
+
+ *pLength += 1;
+ pScanInfoPkt += 1;
+ memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
+
+
+ *pLength += 1;
+ pScanInfoPkt += 1;
+ memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
+
+
+ *pLength += 1;
+ pScanInfoPkt += 1;
+ memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
+
+ *pLength += 1;
+ pScanInfoPkt += 1;
+ memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
+
+ *pLength += 1;
+ pScanInfoPkt += 1;
+ memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
+
+ *pLength += 1;
+ pScanInfoPkt += 1;
+ memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
+
+ *pLength += 1;
+ pScanInfoPkt += 1;
+ memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
+
+ *pLength += 1;
+ pScanInfoPkt += 1;
+ memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
+
+ *pLength += 8;
+ pScanInfoPkt += 8;
+
+ for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
+ memcpy(pScanInfoPkt,
+ &pwrctl->pscan_info->ssid_channel_info[i], 4);
+ *pLength += 4;
+ pScanInfoPkt += 4;
+ }
+}
+#endif /* CONFIG_PNO_SUPPORT */
+
+#ifdef CONFIG_GTK_OL
+static void rtw_hal_construct_GTKRsp(
+ PADAPTER padapter,
+ u8 *pframe,
+ u32 *pLength
+)
+{
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *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 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
+ static u8 GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
+ u8 *pGTKRspPkt = pframe;
+ u8 EncryptionHeadOverhead = 0;
+ /* RTW_INFO("%s:%d\n", __func__, bForcePowerSave); */
+
+ 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);
+
+ memcpy(pwlanhdr->addr1,
+ get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+
+ memcpy(pwlanhdr->addr2,
+ adapter_mac_addr(padapter), ETH_ALEN);
+
+ memcpy(pwlanhdr->addr3,
+ get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+
+ SetSeqNum(pwlanhdr, 0);
+ set_duration(pwlanhdr, 0);
+
+#ifdef CONFIG_WAPI_SUPPORT
+ *pLength = sMacHdrLng;
+#else
+ *pLength = 24;
+#endif /* CONFIG_WAPI_SUPPORT */
+
+ /* ------------------------------------------------------------------------- */
+ /* Security Header: leave space for it if necessary. */
+ /* ------------------------------------------------------------------------- */
+ 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 /* CONFIG_WAPI_SUPPORT */
+ default:
+ EncryptionHeadOverhead = 0;
+ }
+
+ if (EncryptionHeadOverhead > 0) {
+ memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
+ *pLength += EncryptionHeadOverhead;
+ /* SET_80211_HDR_WEP(pGTKRspPkt, 1); */ /* Suggested by CCW. */
+ /* GTK's privacy bit is done by FW */
+ /* SetPrivacy(fctrl); */
+ }
+ /* ------------------------------------------------------------------------- */
+ /* Frame Body. */
+ /* ------------------------------------------------------------------------- */
+ pGTKRspPkt = (u8 *)(pframe + *pLength);
+ /* LLC header */
+ memcpy(pGTKRspPkt, LLCHeader, 8);
+ *pLength += 8;
+
+ /* GTK element */
+ pGTKRspPkt += 8;
+
+ /* GTK frame body after LLC, part 1 */
+ /* TKIP key_length = 32, AES key_length = 16 */
+ if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
+ GTKbody_a[8] = 0x20;
+
+ /* GTK frame body after LLC, part 1 */
+ memcpy(pGTKRspPkt, GTKbody_a, 11);
+ *pLength += 11;
+ pGTKRspPkt += 11;
+ /* GTK frame body after LLC, part 2 */
+ memset(&(pframe[*pLength]), 0, 88);
+ *pLength += 88;
+ pGTKRspPkt += 88;
+
+ if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
+ *pLength += 8;
+}
+#endif /* CONFIG_GTK_OL */
+
+void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
+ u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
+ RSVDPAGE_LOC *rsvd_page_loc)
+{
+ struct security_priv *psecuritypriv = &adapter->securitypriv;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+ struct mlme_ext_priv *pmlmeext;
+ struct mlme_ext_info *pmlmeinfo;
+ u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
+ u32 SSIDLegnth = 0, ProbeReqLength = 0;
+ u8 CurtPktPageNum = 0;
+ u8 currentip[4];
+ u8 cur_dot11txpn[8];
+
+#ifdef CONFIG_GTK_OL
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ struct sta_info *psta;
+ struct security_priv *psecpriv = &adapter->securitypriv;
+ u8 kek[RTW_KEK_LEN];
+ u8 kck[RTW_KCK_LEN];
+#endif /* CONFIG_GTK_OL */
+#ifdef CONFIG_PNO_SUPPORT
+ int pno_index;
+ u8 ssid_num;
+#endif /* CONFIG_PNO_SUPPORT */
+
+ pmlmeext = &adapter->mlmeextpriv;
+ pmlmeinfo = &pmlmeext->mlmext_info;
+
+ if (pwrctl->wowlan_pno_enable == false) {
+ /* ARP RSP * 1 page */
+ rtw_get_current_ip_address(adapter, currentip);
+
+ rsvd_page_loc->LocArpRsp = *page_num;
+
+ RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
+
+ rtw_hal_construct_ARPRsp(adapter, &pframe[index],
+ &ARPLength, currentip);
+
+ rtw_hal_fill_fake_txdesc(adapter,
+ &pframe[index - tx_desc],
+ ARPLength, false, false, true);
+
+ CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
+
+ *page_num += CurtPktPageNum;
+
+ index += (CurtPktPageNum * page_size);
+
+ /* 3 SEC IV * 1 page */
+ rtw_get_sec_iv(adapter, cur_dot11txpn,
+ get_my_bssid(&pmlmeinfo->network));
+
+ rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
+
+ RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
+
+ memcpy(pframe + index - tx_desc, cur_dot11txpn, _AES_IV_LEN_);
+
+ CurtPktPageNum = (u8)PageNum(_AES_IV_LEN_, page_size);
+
+ *page_num += CurtPktPageNum;
+
+ *total_pkt_len = index + _AES_IV_LEN_;
+#ifdef CONFIG_GTK_OL
+ index += (CurtPktPageNum * page_size);
+
+ /* if the ap staion info. exists, get the kek, kck from staion info. */
+ psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
+ if (psta == NULL) {
+ memset(kek, 0, RTW_KEK_LEN);
+ memset(kck, 0, RTW_KCK_LEN);
+ RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
+ __func__);
+ } else {
+ memcpy(kek, psta->kek, RTW_KEK_LEN);
+ memcpy(kck, psta->kck, RTW_KCK_LEN);
+ }
+
+ /* 3 KEK, KCK */
+ rsvd_page_loc->LocGTKInfo = *page_num;
+ RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
+
+ if (IS_HARDWARE_TYPE_8188E(adapter)) {
+ struct security_priv *psecpriv = NULL;
+
+ psecpriv = &adapter->securitypriv;
+ memcpy(pframe + index - tx_desc,
+ &psecpriv->dot11PrivacyAlgrthm, 1);
+ memcpy(pframe + index - tx_desc + 1,
+ &psecpriv->dot118021XGrpPrivacy, 1);
+ memcpy(pframe + index - tx_desc + 2,
+ kck, RTW_KCK_LEN);
+ memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
+ kek, RTW_KEK_LEN);
+ CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
+ } else {
+
+ memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
+ memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
+ kek, RTW_KEK_LEN);
+ GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
+
+ if (psta != NULL &&
+ psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
+ memcpy(pframe + index - tx_desc + 56,
+ &psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
+ GTKLength += RTW_TKIP_MIC_LEN;
+ }
+ CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
+ }
+ *page_num += CurtPktPageNum;
+
+ index += (CurtPktPageNum * page_size);
+
+ /* 3 GTK Response */
+ rsvd_page_loc->LocGTKRsp = *page_num;
+ RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
+ rtw_hal_construct_GTKRsp(adapter, &pframe[index], &GTKLength);
+
+ rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
+ GTKLength, false, false, true);
+
+ CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
+
+ *page_num += CurtPktPageNum;
+
+ index += (CurtPktPageNum * page_size);
+
+ /* below page is empty for GTK extension memory */
+ /* 3(11) GTK EXT MEM */
+ rsvd_page_loc->LocGTKEXTMEM = *page_num;
+ RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
+ CurtPktPageNum = 2;
+
+ if (page_size >= 256)
+ CurtPktPageNum = 1;
+
+ *page_num += CurtPktPageNum;
+ /* extension memory for FW */
+ *total_pkt_len = index + (page_size * CurtPktPageNum);
+#endif /* CONFIG_GTK_OL */
+
+ index += (CurtPktPageNum * page_size);
+
+ /*Reserve 1 page for AOAC report*/
+ rsvd_page_loc->LocAOACReport = *page_num;
+ RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
+ *page_num += 1;
+ *total_pkt_len = index + (page_size * 1);
+ } else {
+#ifdef CONFIG_PNO_SUPPORT
+ if (pwrctl->wowlan_in_resume == false &&
+ pwrctl->pno_inited == true) {
+
+ /* Broadcast Probe Request */
+ rsvd_page_loc->LocProbePacket = *page_num;
+
+ RTW_INFO("loc_probe_req: %d\n",
+ rsvd_page_loc->LocProbePacket);
+
+ rtw_hal_construct_ProbeReq(
+ adapter,
+ &pframe[index],
+ &ProbeReqLength,
+ NULL);
+
+ rtw_hal_fill_fake_txdesc(adapter,
+ &pframe[index - tx_desc],
+ ProbeReqLength, false, false, false);
+
+ CurtPktPageNum =
+ (u8)PageNum(tx_desc + ProbeReqLength, page_size);
+
+ *page_num += CurtPktPageNum;
+
+ index += (CurtPktPageNum * page_size);
+
+ /* Hidden SSID Probe Request */
+ ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
+
+ for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
+ pwrctl->pnlo_info->loc_probe_req[pno_index] =
+ *page_num;
+
+ rtw_hal_construct_ProbeReq(
+ adapter,
+ &pframe[index],
+ &ProbeReqLength,
+ &pwrctl->pno_ssid_list->node[pno_index]);
+
+ rtw_hal_fill_fake_txdesc(adapter,
+ &pframe[index - tx_desc],
+ ProbeReqLength, false, false, false);
+
+ CurtPktPageNum =
+ (u8)PageNum(tx_desc + ProbeReqLength, page_size);
+
+ *page_num += CurtPktPageNum;
+
+ index += (CurtPktPageNum * page_size);
+ }
+
+ /* PNO INFO Page */
+ rsvd_page_loc->LocPNOInfo = *page_num;
+ RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
+ rtw_hal_construct_PNO_info(adapter,
+ &pframe[index - tx_desc],
+ &PNOLength);
+
+ CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
+ *page_num += CurtPktPageNum;
+ index += (CurtPktPageNum * page_size);
+
+ /* Scan Info Page */
+ rsvd_page_loc->LocScanInfo = *page_num;
+ RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
+ rtw_hal_construct_scan_info(adapter,
+ &pframe[index - tx_desc],
+ &ScanInfoLength);
+
+ CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
+ *page_num += CurtPktPageNum;
+ *total_pkt_len = index + ScanInfoLength;
+ index += (CurtPktPageNum * page_size);
+ }
+#endif /* CONFIG_PNO_SUPPORT */
+ }
+}
+
+static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
+{
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+ u8 val8 = 0;
+ u16 val16 = 0;
+
+ if (stop) {
+ /* Pause TX*/
+ pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
+ rtw_write8(adapter, REG_TXPAUSE, 0xff);
+ val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
+ val8 &= ~BIT(0);
+ rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
+ RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
+ __func__,
+ rtw_read8(adapter, REG_SYS_FUNC_EN),
+ pwrpriv->wowlan_txpause_status);
+ } else {
+ val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
+ val8 |= BIT(0);
+ rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
+ RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
+ __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
+ pwrpriv->wowlan_txpause_status);
+ /* release TX*/
+ rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
+ }
+}
+
+static void rtw_hal_reset_mac_rx(_adapter *adapter)
+{
+ u8 val8 = 0;
+ /* Set REG_CR bit1, bit3, bit7 to 0*/
+ val8 = rtw_read8(adapter, REG_CR);
+ val8 &= 0x75;
+ rtw_write8(adapter, REG_CR, val8);
+ val8 = rtw_read8(adapter, REG_CR);
+ /* Set REG_CR bit1, bit3, bit7 to 1*/
+ val8 |= 0x8a;
+ rtw_write8(adapter, REG_CR, val8);
+ RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
+}
+
+static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+ u8 *pattern;
+ u8 len = 0;
+ u8 *mask;
+
+ u8 mask_hw[MAX_WKFM_SIZE] = {0};
+ u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
+ u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ u8 multicast_addr1[2] = {0x33, 0x33};
+ u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
+ u8 mask_len = 0;
+ u8 mac_addr[ETH_ALEN] = {0};
+ u16 count = 0;
+ int i, j;
+
+ if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
+ RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
+ __func__, MAX_WKFM_CAM_NUM);
+ return _FAIL;
+ }
+
+ pattern = pwrctl->patterns[idx].content;
+ len = pwrctl->patterns[idx].len;
+ mask = pwrctl->patterns[idx].mask;
+
+ memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
+ memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
+
+ mask_len = DIV_ROUND_UP(len, 8);
+
+ /* 1. setup A1 table */
+ if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
+ pwow_pattern->type = PATTERN_BROADCAST;
+ else if (memcmp(pattern, multicast_addr1, 2) == 0)
+ pwow_pattern->type = PATTERN_MULTICAST;
+ else if (memcmp(pattern, multicast_addr2, 3) == 0)
+ pwow_pattern->type = PATTERN_MULTICAST;
+ else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
+ pwow_pattern->type = PATTERN_UNICAST;
+ else
+ pwow_pattern->type = PATTERN_INVALID;
+
+ /* translate mask from os to mask for hw */
+
+ /******************************************************************************
+ * pattern from OS uses 'ethenet frame', like this:
+
+ | 6 | 6 | 2 | 20 | Variable | 4 |
+ |--------+--------+------+-----------+------------+-----|
+ | 802.3 Mac Header | IP Header | TCP Packet | FCS |
+ | DA | SA | Type |
+
+ * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
+
+ | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
+ |-------------------+--------+------+-----------+------------+-----|
+ | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
+ | Others | Tpye |
+
+ * Therefore, we need translate mask_from_OS to mask_to_hw.
+ * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
+ * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
+ * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
+ ******************************************************************************/
+ /* Shift 6 bits */
+ for (i = 0; i < mask_len - 1; i++) {
+ mask_hw[i] = mask[i] >> 6;
+ mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
+ }
+
+ mask_hw[i] = (mask[i] >> 6) & 0x3F;
+ /* Set bit 0-5 to zero */
+ mask_hw[0] &= 0xC0;
+
+ for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
+ pwow_pattern->mask[i] = mask_hw[i * 4];
+ pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
+ pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
+ pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
+ }
+
+ /* To get the wake up pattern from the mask.
+ * We do not count first 12 bits which means
+ * DA[6] and SA[6] in the pattern to match HW design. */
+ count = 0;
+ for (i = 12; i < len; i++) {
+ if ((mask[i / 8] >> (i % 8)) & 0x01) {
+ content[count] = pattern[i];
+ count++;
+ }
+ }
+
+ pwow_pattern->crc = rtw_calc_crc(content, count);
+
+ if (pwow_pattern->crc != 0) {
+ if (pwow_pattern->type == PATTERN_INVALID)
+ pwow_pattern->type = PATTERN_VALID;
+ }
+
+ return _SUCCESS;
+}
+
+#ifndef CONFIG_WOW_PATTERN_HW_CAM
+static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
+{
+ u8 val8 = 0;
+ u16 rxff_bndy = 0;
+ u32 rx_dma_buff_sz = 0;
+
+ val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
+ if (val8 != 0)
+ RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
+ __func__, (REG_FIFOPAGE + 3));
+
+ rtw_hal_reset_mac_rx(adapter);
+
+ if (wow_mode) {
+ rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
+ (u8 *)&rx_dma_buff_sz);
+ rxff_bndy = rx_dma_buff_sz - 1;
+
+ rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
+ RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
+ REG_TRXFF_BNDY + 2,
+ rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
+ } else {
+ rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
+ (u8 *)&rx_dma_buff_sz);
+ rxff_bndy = rx_dma_buff_sz - 1;
+ rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
+ RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
+ REG_TRXFF_BNDY + 2,
+ rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
+ }
+}
+
+bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
+{
+ u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
+ u16 offset, rx_buf_ptr = 0;
+ u16 cam_start_offset = 0;
+ u16 ctrl_l = 0, ctrl_h = 0;
+ u8 count = 0, tmp = 0;
+ int i = 0;
+ bool res = true;
+
+ if (idx > MAX_WKFM_CAM_NUM) {
+ RTW_INFO("[Error]: %s, pattern index is out of range\n",
+ __func__);
+ return false;
+ }
+
+ rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
+ (u8 *)&rx_dma_buff_sz);
+
+ if (rx_dma_buff_sz == 0) {
+ RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
+ return false;
+ }
+
+ rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
+
+ if (page_sz == 0) {
+ RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
+ return false;
+ }
+
+ offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
+ cam_start_offset = offset * page_sz;
+
+ ctrl_l = 0x0;
+ ctrl_h = 0x0;
+
+ /* Enable RX packet buffer access */
+ rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
+
+ /* Read the WKFM CAM */
+ for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
+ /*
+ * Set Rx packet buffer offset.
+ * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
+ * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
+ * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
+ * * Index: The index of the wake up frame mask
+ * * WKFMCAM_SIZE: the total size of one WKFM CAM
+ * * per entry offset of a WKFM CAM: Addr i * 4 bytes
+ */
+ rx_buf_ptr =
+ (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
+ rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
+
+ rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
+ data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
+ data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
+
+ RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
+
+ count = 0;
+
+ do {
+ tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
+ rtw_udelay_os(2);
+ count++;
+ } while (!tmp && count < 100);
+
+ if (count >= 100) {
+ RTW_INFO("%s count:%d\n", __func__, count);
+ res = false;
+ }
+ }
+
+ /* Disable RX packet buffer access */
+ rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
+ DISABLE_TRXPKT_BUF_ACCESS);
+ return res;
+}
+
+bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
+ struct rtl_wow_pattern *context)
+{
+ u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
+ u16 offset, rx_buf_ptr = 0;
+ u16 cam_start_offset = 0;
+ u16 ctrl_l = 0, ctrl_h = 0;
+ u8 count = 0, tmp = 0;
+ int res = 0, i = 0;
+
+ if (idx > MAX_WKFM_CAM_NUM) {
+ RTW_INFO("[Error]: %s, pattern index is out of range\n",
+ __func__);
+ return false;
+ }
+
+ rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
+ (u8 *)&rx_dma_buff_sz);
+
+ if (rx_dma_buff_sz == 0) {
+ RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
+ return false;
+ }
+
+ rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
+
+ if (page_sz == 0) {
+ RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
+ return false;
+ }
+
+ offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
+
+ cam_start_offset = offset * page_sz;
+
+ if (IS_HARDWARE_TYPE_8188E(adapter)) {
+ ctrl_l = 0x0001;
+ ctrl_h = 0x0001;
+ } else {
+ ctrl_l = 0x0f01;
+ ctrl_h = 0xf001;
+ }
+
+ /* Enable RX packet buffer access */
+ rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
+
+ /* Write the WKFM CAM */
+ for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
+ /*
+ * Set Rx packet buffer offset.
+ * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
+ * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
+ * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
+ * * Index: The index of the wake up frame mask
+ * * WKFMCAM_SIZE: the total size of one WKFM CAM
+ * * per entry offset of a WKFM CAM: Addr i * 4 bytes
+ */
+ rx_buf_ptr =
+ (cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
+ rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
+
+ if (i == 0) {
+ if (context->type == PATTERN_VALID)
+ data = BIT(31);
+ else if (context->type == PATTERN_BROADCAST)
+ data = BIT(31) | BIT(26);
+ else if (context->type == PATTERN_MULTICAST)
+ data = BIT(31) | BIT(25);
+ else if (context->type == PATTERN_UNICAST)
+ data = BIT(31) | BIT(24);
+
+ if (context->crc != 0)
+ data |= context->crc;
+
+ rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
+ rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
+ } else if (i == 1) {
+ data = 0;
+ rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
+ rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
+ } else if (i == 2 || i == 4) {
+ data = context->mask[i - 2];
+ rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
+ /* write to RX packet buffer*/
+ rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
+ } else if (i == 3 || i == 5) {
+ data = context->mask[i - 2];
+ rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
+ /* write to RX packet buffer*/
+ rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
+ }
+
+ count = 0;
+ do {
+ tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
+ rtw_udelay_os(2);
+ count++;
+ } while (tmp && count < 100);
+
+ if (count >= 100)
+ res = false;
+ else
+ res = true;
+ }
+
+ /* Disable RX packet buffer access */
+ rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
+ DISABLE_TRXPKT_BUF_ACCESS);
+
+ return res;
+}
+void rtw_clean_pattern(_adapter *adapter)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+ struct rtl_wow_pattern zero_pattern;
+ int i = 0;
+
+ memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
+
+ zero_pattern.type = PATTERN_INVALID;
+
+ for (i = 0; i < MAX_WKFM_CAM_NUM; i++)
+ rtw_write_to_frame_mask(adapter, i, &zero_pattern);
+
+ rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
+}
+static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
+ u8 len, u8 *mask, u8 idx)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+ struct mlme_ext_priv *pmlmeext = NULL;
+ struct mlme_ext_info *pmlmeinfo = NULL;
+ struct rtl_wow_pattern wow_pattern;
+ u8 mask_hw[MAX_WKFM_SIZE] = {0};
+ u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
+ u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ u8 multicast_addr1[2] = {0x33, 0x33};
+ u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
+ u8 res = false, index = 0, mask_len = 0;
+ u8 mac_addr[ETH_ALEN] = {0};
+ u16 count = 0;
+ int i, j;
+
+ if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
+ RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
+ __func__, MAX_WKFM_CAM_NUM);
+ return false;
+ }
+
+ pmlmeext = &adapter->mlmeextpriv;
+ pmlmeinfo = &pmlmeext->mlmext_info;
+ memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
+ memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
+
+ mask_len = DIV_ROUND_UP(len, 8);
+
+ /* 1. setup A1 table */
+ if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
+ wow_pattern.type = PATTERN_BROADCAST;
+ else if (memcmp(pattern, multicast_addr1, 2) == 0)
+ wow_pattern.type = PATTERN_MULTICAST;
+ else if (memcmp(pattern, multicast_addr2, 3) == 0)
+ wow_pattern.type = PATTERN_MULTICAST;
+ else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
+ wow_pattern.type = PATTERN_UNICAST;
+ else
+ wow_pattern.type = PATTERN_INVALID;
+
+ /* translate mask from os to mask for hw */
+
+/******************************************************************************
+ * pattern from OS uses 'ethenet frame', like this:
+
+ | 6 | 6 | 2 | 20 | Variable | 4 |
+ |--------+--------+------+-----------+------------+-----|
+ | 802.3 Mac Header | IP Header | TCP Packet | FCS |
+ | DA | SA | Type |
+
+ * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
+
+ | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
+ |-------------------+--------+------+-----------+------------+-----|
+ | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
+ | Others | Tpye |
+
+ * Therefore, we need translate mask_from_OS to mask_to_hw.
+ * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
+ * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
+ * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
+ ******************************************************************************/
+ /* Shift 6 bits */
+ for (i = 0; i < mask_len - 1; i++) {
+ mask_hw[i] = mask[i] >> 6;
+ mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
+ }
+
+ mask_hw[i] = (mask[i] >> 6) & 0x3F;
+ /* Set bit 0-5 to zero */
+ mask_hw[0] &= 0xC0;
+
+ for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
+ wow_pattern.mask[i] = mask_hw[i * 4];
+ wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
+ wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
+ wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
+ }
+
+ /* To get the wake up pattern from the mask.
+ * We do not count first 12 bits which means
+ * DA[6] and SA[6] in the pattern to match HW design. */
+ count = 0;
+ for (i = 12; i < len; i++) {
+ if ((mask[i / 8] >> (i % 8)) & 0x01) {
+ content[count] = pattern[i];
+ count++;
+ }
+ }
+
+ wow_pattern.crc = rtw_calc_crc(content, count);
+
+ if (wow_pattern.crc != 0) {
+ if (wow_pattern.type == PATTERN_INVALID)
+ wow_pattern.type = PATTERN_VALID;
+ }
+
+ index = idx;
+
+ if (!pwrctl->bInSuspend)
+ index += 2;
+
+ /* write pattern */
+ res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
+
+ if (res == false)
+ RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
+ __func__, idx);
+
+ return res;
+}
+void rtw_fill_pattern(_adapter *adapter)
+{
+ int i = 0, total = 0, index;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+ struct rtl_wow_pattern wow_pattern;
+
+ total = pwrpriv->wowlan_pattern_idx;
+
+ if (total > MAX_WKFM_CAM_NUM)
+ total = MAX_WKFM_CAM_NUM;
+
+ for (i = 0 ; i < total ; i++) {
+ if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
+
+ index = i;
+ if (!pwrpriv->bInSuspend)
+ index += 2;
+
+ 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);
+ }
+
+ }
+ rtw_write8(adapter, REG_WKFMCAM_NUM, total);
+
+}
+
+#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);
+ _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
+
+ u32 rdata = 0;
+ u32 cnt = 0;
+ u32 start = 0;
+ u8 timeout = 0;
+ u8 rst = false;
+
+ _enter_critical_mutex(mutex, NULL);
+
+ rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
+
+ start = jiffies;
+ while (1) {
+ if (rtw_is_surprise_removed(adapter))
+ break;
+
+ cnt++;
+ if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
+ rst = _SUCCESS;
+ break;
+ }
+ if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
+ timeout = 1;
+ break;
+ }
+ }
+
+ rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
+
+ _exit_critical_mutex(mutex, NULL);
+
+ /*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
+
+ if (timeout)
+ RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
+
+ return rdata;
+}
+void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
+{
+ int i;
+ u32 rdata;
+
+ memset(context, 0, sizeof(struct rtl_wow_pattern));
+
+ for (i = 4; i >= 0; i--) {
+ rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
+
+ switch (i) {
+ case 4:
+ if (rdata & WOW_BC_BIT)
+ context->type = PATTERN_BROADCAST;
+ else if (rdata & WOW_MC_BIT)
+ context->type = PATTERN_MULTICAST;
+ else if (rdata & WOW_UC_BIT)
+ context->type = PATTERN_UNICAST;
+ else
+ context->type = PATTERN_INVALID;
+
+ context->crc = rdata & 0xFFFF;
+ break;
+ default:
+ memcpy(&context->mask[i], (u8 *)(&rdata), 4);
+ break;
+ }
+ }
+}
+
+static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
+{
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+ _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
+ u32 cnt = 0;
+ u32 start = 0, end = 0;
+ u8 timeout = 0;
+
+ /*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
+ _enter_critical_mutex(mutex, NULL);
+
+ rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
+ rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
+
+ start = jiffies;
+ while (1) {
+ if (rtw_is_surprise_removed(adapter))
+ break;
+
+ cnt++;
+ if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
+ break;
+
+ if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
+ timeout = 1;
+ break;
+ }
+ }
+ end = jiffies;
+
+ _exit_critical_mutex(mutex, NULL);
+
+ if (timeout) {
+ RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
+ , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
+ }
+}
+
+void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
+{
+ int j;
+ u8 addr;
+ u32 wdata = 0;
+
+ for (j = 4; j >= 0; j--) {
+ switch (j) {
+ case 4:
+ wdata = context->crc;
+
+ if (PATTERN_BROADCAST == context->type)
+ wdata |= WOW_BC_BIT;
+ if (PATTERN_MULTICAST == context->type)
+ wdata |= WOW_MC_BIT;
+ if (PATTERN_UNICAST == context->type)
+ wdata |= WOW_UC_BIT;
+ if (PATTERN_INVALID != context->type)
+ wdata |= WOW_VALID_BIT;
+ break;
+ default:
+ wdata = context->mask[j];
+ break;
+ }
+
+ addr = (id << 3) + j;
+
+ _rtw_wow_pattern_write_cam(adapter, addr, wdata);
+ }
+}
+
+static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
+{
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+ _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
+ u32 cnt = 0;
+ u32 start = 0;
+ u8 timeout = 0;
+ u8 rst = _FAIL;
+
+ _enter_critical_mutex(mutex, NULL);
+ rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
+
+ start = jiffies;
+ while (1) {
+ if (rtw_is_surprise_removed(adapter))
+ break;
+
+ cnt++;
+ if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
+ rst = _SUCCESS;
+ break;
+ }
+ if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
+ timeout = 1;
+ break;
+ }
+ }
+ _exit_critical_mutex(mutex, NULL);
+
+ if (timeout)
+ RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
+
+ return rst;
+}
+
+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;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+ struct rtl_wow_pattern wow_pattern;
+
+ total = pwrpriv->wowlan_pattern_idx;
+
+ if (total > MAX_WKFM_CAM_NUM)
+ total = MAX_WKFM_CAM_NUM;
+
+ for (i = 0 ; i < total ; i++) {
+ if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
+ rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
+ rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
+ }
+ }
+}
+
+#endif
+void rtw_wow_pattern_cam_dump(_adapter *adapter)
+{
+
+#ifndef CONFIG_WOW_PATTERN_HW_CAM
+ int i;
+
+ for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
+ RTW_INFO("=======[%d]=======\n", i);
+ rtw_read_from_frame_mask(adapter, i);
+ }
+#else
+ struct rtl_wow_pattern context;
+ int i;
+
+ for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
+ rtw_wow_pattern_read_cam_ent(adapter, i, &context);
+ rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
+ }
+
+#endif
+}
+
+
+static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
+{
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+
+ switch (mode) {
+ case 0:
+ rtw_clean_pattern(adapter);
+ RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
+ break;
+ case 1:
+ rtw_set_default_pattern(adapter);
+ rtw_fill_pattern(adapter);
+ RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
+ break;
+ case 2:
+ rtw_clean_pattern(adapter);
+ rtw_wow_pattern_sw_reset(adapter);
+ RTW_INFO("%s: clean patterns\n", __func__);
+ break;
+ default:
+ RTW_INFO("%s: unknown mode\n", __func__);
+ break;
+ }
+}
+
+static void rtw_hal_wow_enable(_adapter *adapter)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+ struct security_priv *psecuritypriv = &adapter->securitypriv;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct hal_ops *pHalFunc = &adapter->hal_func;
+ struct sta_info *psta = NULL;
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
+ int res;
+ u16 media_status_rpt;
+
+
+ RTW_PRINT("%s, WOWLAN_ENABLE\n", __func__);
+ rtw_hal_gate_bb(adapter, true);
+#ifdef CONFIG_GTK_OL
+ if (psecuritypriv->binstallKCK_KEK == true)
+ rtw_hal_fw_sync_cam_id(adapter);
+#endif
+ /* RX DMA stop */
+ if (IS_HARDWARE_TYPE_8188E(adapter))
+ rtw_hal_disable_tx_report(adapter);
+
+ res = rtw_hal_pause_rx_dma(adapter);
+ if (res == _FAIL)
+ RTW_PRINT("[WARNING] pause RX DMA fail\n");
+
+ #ifndef CONFIG_WOW_PATTERN_HW_CAM
+ /* Reconfig RX_FF Boundary */
+ rtw_hal_set_wow_rxff_boundary(adapter, true);
+ #endif
+
+ /* redownload wow pattern */
+ rtw_hal_dl_pattern(adapter, 1);
+
+ rtw_hal_fw_dl(adapter, true);
+ media_status_rpt = RT_MEDIA_CONNECT;
+ rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
+ (u8 *)&media_status_rpt);
+
+ if (!pwrctl->wowlan_pno_enable) {
+ psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
+
+ if (psta != NULL) {
+ #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
+ rtw_hal_set_default_port_id_cmd(adapter, psta->mac_id);
+ #endif
+
+ rtw_sta_media_status_rpt(adapter, psta, 1);
+ }
+ }
+
+ /* Set WOWLAN H2C command. */
+ RTW_PRINT("Set WOWLan cmd\n");
+ rtw_hal_set_fw_wow_related_cmd(adapter, 1);
+
+ res = rtw_hal_check_wow_ctrl(adapter, true);
+
+ if (res == false)
+ RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
+
+ pwrctl->wowlan_wake_reason =
+ rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
+
+ RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
+ pwrctl->wowlan_wake_reason);
+#ifdef CONFIG_GTK_OL_DBG
+ dump_sec_cam(RTW_DBGDUMP, adapter);
+ dump_sec_cam_cache(RTW_DBGDUMP, adapter);
+#endif
+ /* free adapter's resource */
+ rtw_mi_intf_stop(adapter);
+
+ /* Invoid SE0 reset signal during suspending*/
+ rtw_write8(adapter, REG_RSV_CTRL, 0x20);
+ if (IS_8188F(pHalData->version_id) == false)
+ rtw_write8(adapter, REG_RSV_CTRL, 0x60);
+
+ rtw_hal_gate_bb(adapter, false);
+}
+
+#define DBG_WAKEUP_REASON
+#ifdef DBG_WAKEUP_REASON
+void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
+{
+ RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
+}
+void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
+{
+ if (RX_PAIRWISEKEY == reason)
+ _dbg_wake_up_reason_string(adapter, "Rx pairwise key");
+ else if (RX_GTK == reason)
+ _dbg_wake_up_reason_string(adapter, "Rx GTK");
+ else if (RX_FOURWAY_HANDSHAKE == reason)
+ _dbg_wake_up_reason_string(adapter, "Rx four way handshake");
+ else if (RX_DISASSOC == reason)
+ _dbg_wake_up_reason_string(adapter, "Rx disassoc");
+ else if (RX_DEAUTH == reason)
+ _dbg_wake_up_reason_string(adapter, "Rx deauth");
+ else if (RX_ARP_REQUEST == reason)
+ _dbg_wake_up_reason_string(adapter, "Rx ARP request");
+ else if (FW_DECISION_DISCONNECT == reason)
+ _dbg_wake_up_reason_string(adapter, "FW detect disconnect");
+ else if (RX_MAGIC_PKT == reason)
+ _dbg_wake_up_reason_string(adapter, "Rx magic packet");
+ else if (RX_UNICAST_PKT == reason)
+ _dbg_wake_up_reason_string(adapter, "Rx unicast packet");
+ else if (RX_PATTERN_PKT == reason)
+ _dbg_wake_up_reason_string(adapter, "Rx pattern packet");
+ else if (RTD3_SSID_MATCH == reason)
+ _dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
+ else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
+ _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
+ else if (RX_REALWOW_V2_ACK_LOST == reason)
+ _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
+ else if (ENABLE_FAIL_DMA_IDLE == reason)
+ _dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
+ else if (ENABLE_FAIL_DMA_PAUSE == reason)
+ _dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
+ else if (AP_OFFLOAD_WAKEUP == reason)
+ _dbg_wake_up_reason_string(adapter, "AP offload wakeup");
+ else if (CLK_32K_UNLOCK == reason)
+ _dbg_wake_up_reason_string(adapter, "clk 32k unlock");
+ else if (RTIME_FAIL_DMA_IDLE == 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");
+ else
+ _dbg_wake_up_reason_string(adapter, "unknown reasoen");
+}
+#endif
+
+static void rtw_hal_wow_disable(_adapter *adapter)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+ struct security_priv *psecuritypriv = &adapter->securitypriv;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct hal_ops *pHalFunc = &adapter->hal_func;
+ struct sta_info *psta = NULL;
+ int res;
+ u16 media_status_rpt;
+ u8 val8;
+
+ RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
+
+ if (!pwrctl->wowlan_pno_enable) {
+ psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
+ if (psta != NULL)
+ rtw_sta_media_status_rpt(adapter, psta, 0);
+ else
+ RTW_INFO("%s: psta is null\n", __func__);
+ }
+
+ if (0) {
+ RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
+ RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
+ RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
+ RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
+ }
+
+ pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
+
+ RTW_PRINT("wakeup_reason: 0x%02x\n",
+ pwrctl->wowlan_wake_reason);
+ #ifdef DBG_WAKEUP_REASON
+ _dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
+ #endif
+
+ rtw_hal_set_fw_wow_related_cmd(adapter, 0);
+
+ res = rtw_hal_check_wow_ctrl(adapter, false);
+
+ if (res == false) {
+ RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
+ rtw_hal_force_enable_rxdma(adapter);
+ }
+
+ rtw_hal_gate_bb(adapter, true);
+
+ res = rtw_hal_pause_rx_dma(adapter);
+ if (res == _FAIL)
+ RTW_PRINT("[WARNING] pause RX DMA fail\n");
+
+ /* clean HW pattern match */
+ rtw_hal_dl_pattern(adapter, 0);
+
+ #ifndef CONFIG_WOW_PATTERN_HW_CAM
+ /* config RXFF boundary to original */
+ rtw_hal_set_wow_rxff_boundary(adapter, false);
+ #endif
+ rtw_hal_release_rx_dma(adapter);
+
+ if (IS_HARDWARE_TYPE_8188E(adapter))
+ rtw_hal_enable_tx_report(adapter);
+
+#ifdef CONFIG_GTK_OL
+ if (((pwrctl->wowlan_wake_reason != RX_DISASSOC) ||
+ (pwrctl->wowlan_wake_reason != RX_DEAUTH) ||
+ (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) &&
+ psecuritypriv->binstallKCK_KEK == true) {
+ rtw_hal_get_aoac_rpt(adapter);
+ rtw_hal_update_sw_security_info(adapter);
+ }
+#endif /*CONFIG_GTK_OL*/
+
+ rtw_hal_fw_dl(adapter, false);
+
+#ifdef CONFIG_GPIO_WAKEUP
+ 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
+
+ if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
+ (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
+ (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
+ (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
+
+ media_status_rpt = RT_MEDIA_CONNECT;
+ rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
+ (u8 *)&media_status_rpt);
+
+ if (psta != NULL) {
+ #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
+ rtw_hal_set_default_port_id_cmd(adapter, psta->mac_id);
+ #endif
+ rtw_sta_media_status_rpt(adapter, psta, 1);
+ }
+ }
+ rtw_hal_gate_bb(adapter, false);
+}
+#endif /*CONFIG_WOWLAN*/
+
+#ifdef CONFIG_P2P_WOWLAN
+void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
+ u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
+ RSVDPAGE_LOC *rsvd_page_loc)
+{
+ u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
+ u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
+ u8 CurtPktPageNum = 0;
+
+ /* P2P Beacon */
+ rsvd_page_loc->LocP2PBeacon = *page_num;
+ rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
+ rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
+ P2PBCNLength, false, false, false);
+
+ CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
+
+ *page_num += CurtPktPageNum;
+
+ index += (CurtPktPageNum * page_size);
+
+ /* P2P Probe rsp */
+ rsvd_page_loc->LocP2PProbeRsp = *page_num;
+ rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
+ &P2PProbeRspLength);
+ rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
+ P2PProbeRspLength, false, false, false);
+
+ CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
+
+ *page_num += CurtPktPageNum;
+
+ index += (CurtPktPageNum * page_size);
+
+ /* P2P nego rsp */
+ rsvd_page_loc->LocNegoRsp = *page_num;
+ rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
+ &P2PNegoRspLength);
+ rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
+ P2PNegoRspLength, false, false, false);
+
+ /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
+ /* __func__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
+
+ CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
+
+ *page_num += CurtPktPageNum;
+
+ index += (CurtPktPageNum * page_size);
+
+ /* P2P invite rsp */
+ rsvd_page_loc->LocInviteRsp = *page_num;
+ rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
+ &P2PInviteRspLength);
+ rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
+ P2PInviteRspLength, false, false, false);
+
+ /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
+ /* __func__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
+
+ CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
+
+ *page_num += CurtPktPageNum;
+
+ index += (CurtPktPageNum * page_size);
+
+ /* P2P provision discovery rsp */
+ rsvd_page_loc->LocPDRsp = *page_num;
+ rtw_hal_construct_P2PProvisionDisRsp(adapter,
+ &pframe[index], &P2PPDRspLength);
+
+ rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
+ P2PPDRspLength, false, false, false);
+
+ /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
+ /* __func__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
+
+ CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
+
+ *page_num += CurtPktPageNum;
+
+ *total_pkt_len = index + P2PPDRspLength;
+
+ index += (CurtPktPageNum * page_size);
+
+
+}
+#endif /* CONFIG_P2P_WOWLAN */
+
+#ifdef CONFIG_LPS_PG
+#include "hal_halmac.h"
+
+#define DBG_LPSPG_SEC_DUMP
+#define LPS_PG_INFO_RSVD_LEN 16
+#define LPS_PG_INFO_RSVD_PAGE_NUM 1
+
+#define DBG_LPSPG_INFO_DUMP
+static void rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
+{
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+ struct sta_info *psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ PHAL_DATA_TYPE phal_data = GET_HAL_DATA(adapter);
+ u8 lps_pg_info[LPS_PG_INFO_RSVD_LEN] = {0};
+#ifdef CONFIG_MBSSID_CAM
+ u8 cam_id = INVALID_CAM_ID;
+#endif
+ u8 *psec_cam_id = lps_pg_info + 8;
+ u8 sec_cam_num = 0;
+
+ if (!psta) {
+ RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
+ rtw_warn_on(1);
+ return;
+ }
+
+ /*Byte 0 - used macid*/
+ LPSPG_RSVD_PAGE_SET_MACID(lps_pg_info, psta->mac_id);
+ RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->mac_id);
+
+#ifdef CONFIG_MBSSID_CAM
+ /*Byte 1 - used BSSID CAM entry*/
+ cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
+ if (cam_id != INVALID_CAM_ID)
+ LPSPG_RSVD_PAGE_SET_MBSSCAMID(lps_pg_info, cam_id);
+ RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
+#endif
+
+#ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
+ /*Btye 2 - Max used Pattern Match CAM entry*/
+ if (pwrpriv->wowlan_mode == true &&
+ check_fwstate(&adapter->mlmepriv, _FW_LINKED) == true) {
+ LPSPG_RSVD_PAGE_SET_PMC_NUM(lps_pg_info, pwrpriv->wowlan_pattern_idx);
+ RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
+ }
+#endif
+#ifdef CONFIG_BEAMFORMING /*&& MU BF*/
+ /*Btye 3 - Max MU rate table Group ID*/
+ LPSPG_RSVD_PAGE_SET_MU_RAID_GID(lps_pg_info, _value);
+ RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", _value);
+#endif
+
+ /*Btye 8 ~15 - used Security CAM entry */
+ sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
+
+ /*Btye 4 - used Security CAM entry number*/
+ if (sec_cam_num < 8)
+ LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(lps_pg_info, sec_cam_num);
+ RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
+
+ /*Btye 5 - Txbuf used page number for fw offload*/
+ LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(lps_pg_info, phal_data->drv_rsvd_page_number);
+ RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", phal_data->drv_rsvd_page_number);
+
+#ifdef DBG_LPSPG_SEC_DUMP
+ {
+ int i;
+
+ for (i = 0; i < sec_cam_num; i++)
+ RTW_INFO("%d = sec_cam_id:%d\n", i, psec_cam_id[i]);
+ }
+#endif
+
+#ifdef DBG_LPSPG_INFO_DUMP
+ RTW_INFO("==== DBG_LPSPG_INFO_RSVD_PAGE_DUMP====\n");
+ RTW_INFO(" %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+ *(lps_pg_info), *(lps_pg_info + 1), *(lps_pg_info + 2), *(lps_pg_info + 3),
+ *(lps_pg_info + 4), *(lps_pg_info + 5), *(lps_pg_info + 6), *(lps_pg_info + 7));
+ RTW_INFO(" %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+ *(lps_pg_info + 8), *(lps_pg_info + 9), *(lps_pg_info + 10), *(lps_pg_info + 11),
+ *(lps_pg_info + 12), *(lps_pg_info + 13), *(lps_pg_info + 14), *(lps_pg_info + 15));
+ RTW_INFO("==== DBG_LPSPG_INFO_RSVD_PAGE_DUMP====\n");
+#endif
+
+ rtw_halmac_download_rsvd_page(dvobj, pwrpriv->lpspg_rsvd_page_locate, lps_pg_info, LPS_PG_INFO_RSVD_LEN);
+
+#ifdef DBG_LPSPG_INFO_DUMP
+ RTW_INFO("Get LPS-PG INFO from rsvd page_offset:%d\n", pwrpriv->lpspg_rsvd_page_locate);
+ rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, pwrpriv->lpspg_rsvd_page_locate, 1);
+#endif
+}
+
+
+static u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
+{
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+
+ u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
+ u8 ret = _FAIL;
+
+ RTW_INFO("%s: loc_lpspg_info:%d\n", __func__, pwrpriv->lpspg_rsvd_page_locate);
+
+ if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
+ SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1); /*SecurityCAM_En*/
+#ifdef CONFIG_MBSSID_CAM
+ SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1); /*BSSIDCAM_En*/
+#endif
+
+#if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
+ if (pwrpriv->wowlan_mode == true &&
+ check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+
+ SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1); /*PatternMatchCAM_En*/
+ }
+#endif
+
+#ifdef CONFIG_MACID_SEARCH
+ SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1); /*MACIDSearch_En*/
+#endif
+
+#ifdef CONFIG_TX_SC
+ SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1); /*TXSC_En*/
+#endif
+
+#ifdef CONFIG_BEAMFORMING /*&& MU BF*/
+ SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1); /*MURateTable_En*/
+#endif
+
+ SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_rsvd_page_locate);
+
+#ifdef DBG_LPSPG_INFO_DUMP
+ RTW_INFO("==== DBG_LPSPG_INFO_CMD_DUMP====\n");
+ RTW_INFO(" H2C_CMD: 0x%02x, H2C_LEN: %d\n", H2C_LPS_PG_INFO, H2C_LPS_PG_INFO_LEN);
+ RTW_INFO(" %02X:%02X\n", *(lpspg_info), *(lpspg_info + 1));
+ RTW_INFO("==== DBG_LPSPG_INFO_CMD_DUMP====\n");
+#endif
+
+ ret = rtw_hal_fill_h2c_cmd(adapter,
+ H2C_LPS_PG_INFO,
+ H2C_LPS_PG_INFO_LEN,
+ lpspg_info);
+ return ret;
+}
+u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
+{
+ u8 ret = _FAIL;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+
+ if (pwrpriv->lpspg_rsvd_page_locate == 0) {
+ RTW_ERR("%s [ERROR] lpspg_rsvd_page_locate = 0\n", __func__);
+ rtw_warn_on(1);
+ return ret;
+ }
+
+ rtw_hal_set_lps_pg_info_rsvd_page(adapter);
+ ret = rtw_hal_set_lps_pg_info_cmd(adapter);
+ if (_SUCCESS == ret)
+ pwrpriv->blpspg_info_up = false;
+
+ return ret;
+}
+
+void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
+{
+ switch (hdl_id) {
+ case LPS_PG_INFO_CFG:
+ rtw_hal_set_lps_pg_info(adapter);
+ break;
+ case LPS_PG_REDLEMEM:
+ /*rtw_halmac_redl_fw();*/
+ break;
+
+ case LPS_PG_RESEND_H2C:
+ {
+ struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
+ struct sta_info *sta;
+ PHAL_DATA_TYPE hal_data = GET_HAL_DATA(adapter);
+ int i;
+
+ for (i = 0; i < MACID_NUM_SW_LIMIT; i++) {
+ sta = macid_ctl->sta[i];
+ if (sta && !is_broadcast_mac_addr(sta->hwaddr)) {
+ /*rtw_dm_ra_mask_hdl(adapter, sta);*/
+ /*phydm_rssi_report(hal_data->odmpriv, sta->mac_id);*/
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+#endif /*CONFIG_LPS_PG*/
+
+/*
+ * Description: Fill the reserved packets that FW will use to RSVD page.
+ * Now we just send 4 types packet to rsvd page.
+ * (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
+ * Input:
+ * finished - false:At the first time we will send all the packets as a large packet to Hw,
+ * so we need to set the packet length to total lengh.
+ * true: At the second time, we should send the first packet (default:beacon)
+ * to Hw again and set the lengh in descriptor to the real beacon lengh.
+ * 2009.10.15 by tynli.
+ *
+ * Page Size = 128: 8188e, 8723a/b, 8192c/d,
+ * Page Size = 256: 8192e, 8821a
+ * Page Size = 512: 8812a
+ */
+
+/*#define DBG_DUMP_SET_RSVD_PAGE*/
+void rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished)
+{
+ PHAL_DATA_TYPE pHalData;
+ struct xmit_frame *pcmdframe;
+ struct pkt_attrib *pattrib;
+ struct xmit_priv *pxmitpriv;
+ struct mlme_ext_priv *pmlmeext;
+ struct mlme_ext_info *pmlmeinfo;
+ struct pwrctrl_priv *pwrctl;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct hal_ops *pHalFunc = &adapter->hal_func;
+ u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
+ u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
+ u32 ProbeReqLength = 0, NullFunctionDataLength = 0;
+ u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
+ u8 TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
+ u8 *ReservedPagePacket;
+ u16 BufIndex = 0;
+ u32 TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
+ RSVDPAGE_LOC RsvdPageLoc;
+
+#ifdef DBG_CONFIG_ERROR_DETECT
+ struct sreset_priv *psrtpriv;
+#endif /* DBG_CONFIG_ERROR_DETECT */
+
+#ifdef CONFIG_MCC_MODE
+ u8 dl_mcc_page = _FAIL;
+#endif /* CONFIG_MCC_MODE */
+
+ pHalData = GET_HAL_DATA(adapter);
+#ifdef DBG_CONFIG_ERROR_DETECT
+ psrtpriv = &pHalData->srestpriv;
+#endif
+ pxmitpriv = &adapter->xmitpriv;
+ pmlmeext = &adapter->mlmeextpriv;
+ pmlmeinfo = &pmlmeext->mlmext_info;
+ pwrctl = adapter_to_pwrctl(adapter);
+
+ rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
+
+ if (PageSize == 0) {
+ RTW_INFO("[Error]: %s, PageSize is zero!!\n", __func__);
+ return;
+ }
+
+ if (pwrctl->wowlan_mode == true || pwrctl->wowlan_ap_mode == true)
+ RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, true);
+ else
+ RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, false);
+
+ RTW_INFO("%s PageSize: %d, RsvdPageNUm: %d\n", __func__, PageSize, RsvdPageNum);
+
+ MaxRsvdPageBufSize = RsvdPageNum * PageSize;
+
+ if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
+ RTW_INFO("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
+ __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
+ rtw_warn_on(1);
+ return;
+ }
+
+ pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
+
+ if (pcmdframe == NULL) {
+ RTW_INFO("%s: alloc ReservedPagePacket fail!\n", __func__);
+ return;
+ }
+
+ ReservedPagePacket = pcmdframe->buf_addr;
+ memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
+
+ /* beacon * 2 pages */
+ BufIndex = TxDescOffset;
+ rtw_hal_construct_beacon(adapter,
+ &ReservedPagePacket[BufIndex], &BeaconLength);
+
+ /*
+ * When we count the first page size, we need to reserve description size for the RSVD
+ * packet, it will be filled in front of the packet in TXPKTBUF.
+ */
+ CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
+ /* If we don't add 1 more page, ARP offload function will fail at 8723bs.*/
+ if (CurtPktPageNum == 1)
+ CurtPktPageNum += 1;
+
+ TotalPageNum += CurtPktPageNum;
+
+ BufIndex += (CurtPktPageNum * PageSize);
+
+ if (pwrctl->wowlan_ap_mode == true) {
+ /* (4) probe response*/
+ RsvdPageLoc.LocProbeRsp = TotalPageNum;
+ rtw_hal_construct_ProbeRsp(
+ adapter, &ReservedPagePacket[BufIndex],
+ &ProbeRspLength,
+ get_my_bssid(&pmlmeinfo->network), false);
+ rtw_hal_fill_fake_txdesc(adapter,
+ &ReservedPagePacket[BufIndex - TxDescLen],
+ ProbeRspLength, false, false, false);
+
+ CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
+ TotalPageNum += CurtPktPageNum;
+ TotalPacketLen = BufIndex + ProbeRspLength;
+ BufIndex += (CurtPktPageNum * PageSize);
+ goto download_page;
+ }
+
+ /* ps-poll * 1 page */
+ RsvdPageLoc.LocPsPoll = TotalPageNum;
+ RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
+ rtw_hal_construct_PSPoll(adapter,
+ &ReservedPagePacket[BufIndex], &PSPollLength);
+ rtw_hal_fill_fake_txdesc(adapter,
+ &ReservedPagePacket[BufIndex - TxDescLen],
+ PSPollLength, true, false, false);
+
+ CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
+
+ TotalPageNum += CurtPktPageNum;
+
+ BufIndex += (CurtPktPageNum * PageSize);
+
+#ifdef CONFIG_BT_COEXIST
+ /* BT Qos null data * 1 page */
+ RsvdPageLoc.LocBTQosNull = TotalPageNum;
+ RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
+ rtw_hal_construct_NullFunctionData(
+ adapter,
+ &ReservedPagePacket[BufIndex],
+ &BTQosNullLength,
+ get_my_bssid(&pmlmeinfo->network),
+ true, 0, 0, false);
+ rtw_hal_fill_fake_txdesc(adapter,
+ &ReservedPagePacket[BufIndex - TxDescLen],
+ BTQosNullLength, false, true, false);
+
+ CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength, PageSize);
+
+ TotalPageNum += CurtPktPageNum;
+
+ BufIndex += (CurtPktPageNum * PageSize);
+#endif /* CONFIG_BT_COEXIT */
+
+#ifdef CONFIG_MCC_MODE
+ if (MCC_EN(adapter)) {
+ dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
+ &BufIndex, TxDescLen, PageSize,
+ &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
+ } else
+ dl_mcc_page = _FAIL;
+
+ if (dl_mcc_page == _FAIL) {
+#endif /* CONFIG_MCC_MODE */
+
+ /* null data * 1 page */
+ RsvdPageLoc.LocNullData = TotalPageNum;
+ RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
+ rtw_hal_construct_NullFunctionData(
+ adapter,
+ &ReservedPagePacket[BufIndex],
+ &NullDataLength,
+ get_my_bssid(&pmlmeinfo->network),
+ false, 0, 0, false);
+ rtw_hal_fill_fake_txdesc(adapter,
+ &ReservedPagePacket[BufIndex - TxDescLen],
+ NullDataLength, false, false, false);
+
+ CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
+
+ TotalPageNum += CurtPktPageNum;
+
+ BufIndex += (CurtPktPageNum * PageSize);
+#ifdef CONFIG_MCC_MODE
+ }
+#endif /* CONFIG_MCC_MODE */
+
+ /* Qos null data * 1 page */
+ RsvdPageLoc.LocQosNull = TotalPageNum;
+ RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
+ rtw_hal_construct_NullFunctionData(
+ adapter,
+ &ReservedPagePacket[BufIndex],
+ &QosNullLength,
+ get_my_bssid(&pmlmeinfo->network),
+ true, 0, 0, false);
+ rtw_hal_fill_fake_txdesc(adapter,
+ &ReservedPagePacket[BufIndex - TxDescLen],
+ QosNullLength, false, false, false);
+
+ CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength, PageSize);
+
+ TotalPageNum += CurtPktPageNum;
+
+ TotalPacketLen = BufIndex + QosNullLength;
+
+ BufIndex += (CurtPktPageNum * PageSize);
+
+#ifdef CONFIG_WOWLAN
+ if (pwrctl->wowlan_mode == true &&
+ pwrctl->wowlan_in_resume == false) {
+ rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
+ BufIndex, TxDescLen, PageSize,
+ &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
+ }
+#endif /* CONFIG_WOWLAN */
+
+#ifdef CONFIG_P2P_WOWLAN
+ if (pwrctl->wowlan_p2p_mode) {
+ rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
+ BufIndex, TxDescLen, PageSize,
+ &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
+ }
+#endif /* CONFIG_P2P_WOWLAN */
+
+#ifdef CONFIG_LPS_PG
+ /* must reserved last 1 x page for LPS PG Info*/
+ pwrctl->lpspg_rsvd_page_locate = TotalPageNum;
+ pwrctl->blpspg_info_up = true;
+#endif
+
+download_page:
+ /* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
+ RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
+ __func__, TotalPageNum, TotalPacketLen);
+
+#ifdef CONFIG_LPS_PG
+ if ((TotalPacketLen + (LPS_PG_INFO_RSVD_PAGE_NUM * PageSize)) > MaxRsvdPageBufSize) {
+ pwrctl->lpspg_rsvd_page_locate = 0;
+ pwrctl->blpspg_info_up = false;
+
+ RTW_ERR("%s rsvd page size is not enough!!TotalPacketLen+LPS_PG_INFO_LEN %d, MaxRsvdPageBufSize %d\n",
+ __func__, (TotalPacketLen + (LPS_PG_INFO_RSVD_PAGE_NUM * PageSize)), MaxRsvdPageBufSize);
+ rtw_warn_on(1);
+ }
+#endif
+
+ if (TotalPacketLen > MaxRsvdPageBufSize) {
+ RTW_ERR("%s(ERROR): rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
+ __func__, TotalPacketLen, MaxRsvdPageBufSize);
+ rtw_warn_on(1);
+ goto error;
+ } else {
+ /* update attribute */
+ pattrib = &pcmdframe->attrib;
+ update_mgntframe_attrib(adapter, pattrib);
+ pattrib->qsel = QSLT_BEACON;
+ pattrib->pktlen = TotalPacketLen - TxDescOffset;
+ pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
+ dump_mgntframe_and_wait(adapter, pcmdframe, 100);
+ }
+
+ RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
+ __func__, TotalPacketLen, TotalPageNum);
+#ifdef DBG_DUMP_SET_RSVD_PAGE
+ RTW_INFO(" ==================================================\n");
+ RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
+ RTW_INFO(" ==================================================\n");
+#endif
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
+#ifdef CONFIG_WOWLAN
+ if (pwrctl->wowlan_mode == true &&
+ pwrctl->wowlan_in_resume == false)
+ rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
+#endif /* CONFIG_WOWLAN */
+#ifdef CONFIG_AP_WOWLAN
+ if (pwrctl->wowlan_ap_mode == true)
+ rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
+#endif /* CONFIG_AP_WOWLAN */
+ } else if (pwrctl->wowlan_pno_enable) {
+#ifdef CONFIG_PNO_SUPPORT
+ rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
+ if (pwrctl->wowlan_in_resume)
+ rtw_hal_set_scan_offload_info_cmd(adapter,
+ &RsvdPageLoc, 0);
+ else
+ rtw_hal_set_scan_offload_info_cmd(adapter,
+ &RsvdPageLoc, 1);
+#endif /* CONFIG_PNO_SUPPORT */
+ }
+#ifdef CONFIG_P2P_WOWLAN
+ if (pwrctl->wowlan_p2p_mode)
+ rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
+#endif /* CONFIG_P2P_WOWLAN */
+ return;
+error:
+ rtw_free_xmitframe(pxmitpriv, pcmdframe);
+}
+static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
+{
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+#if defined(CONFIG_MI_WITH_MBSSID_CAM)
+ RTW_INFO("[Warn] %s "ADPT_FMT" enter func\n", __func__, ADPT_ARG(padapter));
+ rtw_warn_on(1);
+ return;
+#endif
+
+ if (!pmlmeext->en_hw_update_tsf)
+ return;
+
+ /* check REG_RCR bit is set */
+ if (!(rtw_read32(padapter, REG_RCR) & RCR_CBSSID_BCN))
+ return;
+
+ /* enable hw update tsf function for non-AP */
+ if (rtw_linked_check(padapter) &&
+ check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) {
+#ifdef CONFIG_CONCURRENT_MODE
+ if (padapter->hw_port == HW_PORT1)
+ rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~DIS_TSF_UDT));
+ else
+#endif
+ rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~DIS_TSF_UDT));
+ }
+ pmlmeext->en_hw_update_tsf = false;
+}
+
+#ifdef CONFIG_TDLS
+#ifdef CONFIG_TDLS_CH_SW
+s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+ u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
+
+
+ SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
+ SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
+ switch (bwmode) {
+ case CHANNEL_WIDTH_40:
+ SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
+ break;
+ case CHANNEL_WIDTH_80:
+ SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
+ break;
+ case CHANNEL_WIDTH_20:
+ default:
+ break;
+ }
+ SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
+
+ return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
+}
+#endif
+#endif
+
+#ifdef CONFIG_WMMPS
+void rtw_hal_update_uapsd_tid(_adapter *adapter)
+{
+ rtw_write8(adapter, REG_WMMPS_UAPSD_TID, 0xFF);
+}
+#endif
+
+#if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
+/* For multi-port support, driver needs to inform the port ID to FW for btc operations */
+s32 rtw_hal_set_wifi_port_id_cmd(_adapter *adapter)
+{
+ u8 port_id = 0;
+ u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
+
+ SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, adapter->hw_port);
+ return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
+}
+#endif
+
+void SetHwReg(_adapter *adapter, u8 variable, u8 *val)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+
+ switch (variable) {
+ case HW_VAR_MEDIA_STATUS: {
+ u8 net_type = *((u8 *)val);
+
+ rtw_hal_set_msr(adapter, net_type);
+ }
+ break;
+ case HW_VAR_MAC_ADDR:
+#ifdef CONFIG_MI_WITH_MBSSID_CAM
+ rtw_hal_set_macaddr_mbid(adapter, val);
+#else
+ rtw_hal_set_macaddr_port(adapter, val);
+#endif
+ break;
+ case HW_VAR_BSSID:
+ rtw_hal_set_bssid(adapter, val);
+ break;
+#ifdef CONFIG_MBSSID_CAM
+ case HW_VAR_MBSSID_CAM_WRITE: {
+ u32 cmd = 0;
+ u32 *cam_val = (u32 *)val;
+
+ rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
+ cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
+ rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
+ }
+ break;
+ case HW_VAR_MBSSID_CAM_CLEAR: {
+ u32 cmd;
+ u8 entry_id = *(u8 *)val;
+
+ rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
+
+ cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
+ rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
+ }
+ break;
+ case HW_VAR_RCR_MBSSID_EN:
+ if (*((u8 *)val))
+ rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR) | RCR_ENMBID);
+ else {
+ u32 val32;
+
+ val32 = rtw_read32(adapter, REG_RCR);
+ val32 &= ~(RCR_ENMBID);
+ rtw_write32(adapter, REG_RCR, val32);
+ }
+ break;
+#endif
+ case HW_VAR_PORT_SWITCH:
+ hw_var_port_switch(adapter);
+ break;
+ case HW_VAR_INIT_RTS_RATE: {
+ u16 brate_cfg = *((u16 *)val);
+ u8 rate_index = 0;
+ HAL_VERSION *hal_ver = &hal_data->version_id;
+
+ if (IS_8188E(*hal_ver)) {
+
+ while (brate_cfg > 0x1) {
+ brate_cfg = (brate_cfg >> 1);
+ rate_index++;
+ }
+ rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
+ } else
+ rtw_warn_on(1);
+ }
+ break;
+ case HW_VAR_SEC_CFG: {
+ u16 reg_scr_ori;
+ u16 reg_scr;
+
+ reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
+ reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
+
+ if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
+ reg_scr |= SCR_CHK_BMC;
+
+ if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
+ reg_scr |= SCR_NoSKMC;
+
+ if (reg_scr != reg_scr_ori)
+ rtw_write16(adapter, REG_SECCFG, reg_scr);
+ }
+ break;
+ case HW_VAR_SEC_DK_CFG: {
+ struct security_priv *sec = &adapter->securitypriv;
+ u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
+
+ if (val) { /* Enable default key related setting */
+ reg_scr |= SCR_TXBCUSEDK;
+ if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
+ reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
+ } else /* Disable default key related setting */
+ reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
+
+ rtw_write8(adapter, REG_SECCFG, reg_scr);
+ }
+ break;
+
+ case HW_VAR_ASIX_IOT:
+ /* enable ASIX IOT function */
+ if (*((u8 *)val) == true) {
+ /* 0xa2e[0]=0 (disable rake receiver) */
+ rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
+ rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
+ /* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
+ rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
+ } else {
+ /* restore reg:0xa2e, reg:0xa1c */
+ rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
+ rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
+ rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
+ }
+ break;
+#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
+ case HW_VAR_WOWLAN: {
+ struct wowlan_ioctl_param *poidparam;
+
+ poidparam = (struct wowlan_ioctl_param *)val;
+ switch (poidparam->subcode) {
+#ifdef CONFIG_WOWLAN
+ case WOWLAN_PATTERN_CLEAN:
+ rtw_hal_dl_pattern(adapter, 2);
+ break;
+ case WOWLAN_ENABLE:
+ rtw_hal_wow_enable(adapter);
+ break;
+ case WOWLAN_DISABLE:
+ rtw_hal_wow_disable(adapter);
+ break;
+#endif /*CONFIG_WOWLAN*/
+#ifdef CONFIG_AP_WOWLAN
+ case WOWLAN_AP_ENABLE:
+ rtw_hal_ap_wow_enable(adapter);
+ break;
+ case WOWLAN_AP_DISABLE:
+ rtw_hal_ap_wow_disable(adapter);
+ break;
+#endif /*CONFIG_AP_WOWLAN*/
+ default:
+ break;
+ }
+ }
+ break;
+#endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
+
+ case HW_VAR_EN_HW_UPDATE_TSF:
+ rtw_hal_set_hw_update_tsf(adapter);
+ break;
+
+ case HW_VAR_APFM_ON_MAC:
+ hal_data->bMacPwrCtrlOn = *val;
+ RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
+ break;
+#ifdef CONFIG_WMMPS
+ case HW_VAR_UAPSD_TID:
+ rtw_hal_update_uapsd_tid(adapter);
+ break;
+#endif
+#ifdef CONFIG_LPS_PG
+ case HW_VAR_LPS_PG_HANDLE:
+ rtw_hal_lps_pg_handler(adapter, *val);
+ break;
+#endif
+
+ default:
+ if (0)
+ RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
+ FUNC_ADPT_ARG(adapter), variable);
+ break;
+ }
+
+}
+
+void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+
+
+ switch (variable) {
+ case HW_VAR_BASIC_RATE:
+ *((u16 *)val) = hal_data->BasicRateSet;
+ break;
+ case HW_VAR_RF_TYPE:
+ *((u8 *)val) = hal_data->rf_type;
+ break;
+ case HW_VAR_MEDIA_STATUS:
+ rtw_hal_get_msr(adapter, val);
+ break;
+ case HW_VAR_DO_IQK:
+ *val = hal_data->bNeedIQK;
+ break;
+ case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
+ if (hal_is_band_support(adapter, BAND_ON_5G))
+ *val = true;
+ else
+ *val = false;
+ break;
+ case HW_VAR_APFM_ON_MAC:
+ *val = hal_data->bMacPwrCtrlOn;
+ break;
+ default:
+ if (0)
+ RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
+ FUNC_ADPT_ARG(adapter), variable);
+ break;
+ }
+
+}
+
+u8
+SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ u8 bResult = _SUCCESS;
+
+ switch (variable) {
+
+ case HAL_DEF_DBG_DUMP_RXPKT:
+ hal_data->bDumpRxPkt = *((u8 *)value);
+ break;
+ case HAL_DEF_DBG_DUMP_TXPKT:
+ hal_data->bDumpTxPkt = *((u8 *)value);
+ break;
+ case HAL_DEF_ANT_DETECT:
+ hal_data->AntDetection = *((u8 *)value);
+ break;
+ case HAL_DEF_DBG_DIS_PWT:
+ hal_data->bDisableTXPowerTraining = *((u8 *)value);
+ break;
+ default:
+ RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __func__, variable);
+ bResult = _FAIL;
+ break;
+ }
+
+ return bResult;
+}
+
+#ifdef CONFIG_BEAMFORMING
+u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
+{
+ struct registry_priv *pregistrypriv = &adapter->registrypriv;
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+
+ return 1;
+
+}
+u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
+{
+ struct registry_priv *pregistrypriv = &adapter->registrypriv;
+ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+
+ return 1;
+}
+#endif
+
+u8
+GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ u8 bResult = _SUCCESS;
+
+ switch (variable) {
+ case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
+ struct mlme_priv *pmlmepriv;
+ struct sta_priv *pstapriv;
+ struct sta_info *psta;
+
+ pmlmepriv = &adapter->mlmepriv;
+ pstapriv = &adapter->stapriv;
+ psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
+ if (psta)
+ *((int *)value) = psta->rssi_stat.undecorated_smoothed_pwdb;
+ }
+ break;
+ case HAL_DEF_DBG_DUMP_RXPKT:
+ *((u8 *)value) = hal_data->bDumpRxPkt;
+ break;
+ case HAL_DEF_DBG_DUMP_TXPKT:
+ *((u8 *)value) = hal_data->bDumpTxPkt;
+ break;
+ case HAL_DEF_ANT_DETECT:
+ *((u8 *)value) = hal_data->AntDetection;
+ break;
+ case HAL_DEF_MACID_SLEEP:
+ *(u8 *)value = false;
+ break;
+ case HAL_DEF_TX_PAGE_SIZE:
+ *((u32 *)value) = PAGE_SIZE_128;
+ break;
+ case HAL_DEF_DBG_DIS_PWT:
+ *(u8 *)value = hal_data->bDisableTXPowerTraining;
+ break;
+ case HAL_DEF_EXPLICIT_BEAMFORMER:
+ case HAL_DEF_EXPLICIT_BEAMFORMEE:
+ case HAL_DEF_VHT_MU_BEAMFORMER:
+ case HAL_DEF_VHT_MU_BEAMFORMEE:
+ *(u8 *)value = false;
+ break;
+#ifdef CONFIG_BEAMFORMING
+ case HAL_DEF_BEAMFORMER_CAP:
+ *(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
+ break;
+ case HAL_DEF_BEAMFORMEE_CAP:
+ *(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
+ break;
+#endif
+ default:
+ RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __func__, variable);
+ bResult = _FAIL;
+ break;
+ }
+
+ return bResult;
+}
+
+void SetHalODMVar(
+ PADAPTER Adapter,
+ HAL_ODM_VARIABLE eVariable,
+ void * pValue1,
+ bool bSet)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct PHY_DM_STRUCT *podmpriv = &pHalData->odmpriv;
+ /* unsigned long irqL; */
+ switch (eVariable) {
+ case HAL_ODM_STA_INFO: {
+ struct sta_info *psta = (struct sta_info *)pValue1;
+ if (bSet) {
+ RTW_INFO("### Set STA_(%d) info ###\n", psta->mac_id);
+ odm_cmn_info_ptr_array_hook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta);
+ } else {
+ RTW_INFO("### Clean STA_(%d) info ###\n", psta->mac_id);
+ /* _enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL); */
+ psta->rssi_level = 0;
+ odm_cmn_info_ptr_array_hook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, NULL);
+
+ /* _exit_critical_bh(&pHalData->odm_stainfo_lock, &irqL); */
+ }
+ }
+ break;
+ case HAL_ODM_P2P_STATE:
+ odm_cmn_info_update(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet);
+ break;
+ case HAL_ODM_WIFI_DISPLAY_STATE:
+ odm_cmn_info_update(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet);
+ break;
+ case HAL_ODM_REGULATION:
+ odm_cmn_info_init(podmpriv, ODM_CMNINFO_DOMAIN_CODE_2G, pHalData->Regulation2_4G);
+ odm_cmn_info_init(podmpriv, ODM_CMNINFO_DOMAIN_CODE_5G, pHalData->Regulation5G);
+ break;
+#if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
+ case HAL_ODM_NOISE_MONITOR: {
+ struct noise_info *pinfo = (struct noise_info *)pValue1;
+
+#ifdef DBG_NOISE_MONITOR
+ RTW_INFO("### Noise monitor chan(%d)-bPauseDIG:%d,IGIValue:0x%02x,max_time:%d (ms) ###\n",
+ pinfo->chan, pinfo->bPauseDIG, pinfo->IGIValue, pinfo->max_time);
+#endif
+
+ pHalData->noise[pinfo->chan] = odm_inband_noise_monitor(podmpriv, pinfo->is_pause_dig, pinfo->igi_value, pinfo->max_time);
+ RTW_INFO("chan_%d, noise = %d (dBm)\n", pinfo->chan, pHalData->noise[pinfo->chan]);
+#ifdef DBG_NOISE_MONITOR
+ RTW_INFO("noise_a = %d, noise_b = %d noise_all:%d\n",
+ podmpriv->noise_level.noise[ODM_RF_PATH_A],
+ podmpriv->noise_level.noise[ODM_RF_PATH_B],
+ podmpriv->noise_level.noise_all);
+#endif
+ }
+ break;
+#endif/*#ifdef CONFIG_BACKGROUND_NOISE_MONITOR*/
+
+ case HAL_ODM_INITIAL_GAIN: {
+ u8 rx_gain = *((u8 *)(pValue1));
+ /*printk("rx_gain:%x\n",rx_gain);*/
+ if (rx_gain == 0xff) {/*restore rx gain*/
+ /*odm_write_dig(podmpriv,pDigTable->backup_ig_value);*/
+ odm_pause_dig(podmpriv, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_0, rx_gain);
+ } else {
+ /*pDigTable->backup_ig_value = pDigTable->cur_ig_value;*/
+ /*odm_write_dig(podmpriv,rx_gain);*/
+ odm_pause_dig(podmpriv, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_0, rx_gain);
+ }
+ }
+ break;
+ case HAL_ODM_FA_CNT_DUMP:
+ if (*((u8 *)pValue1))
+ podmpriv->debug_components |= (ODM_COMP_DIG | ODM_COMP_FA_CNT);
+ else
+ podmpriv->debug_components &= ~(ODM_COMP_DIG | ODM_COMP_FA_CNT);
+ break;
+ case HAL_ODM_DBG_FLAG:
+ odm_cmn_info_update(podmpriv, ODM_CMNINFO_DBG_COMP, *((u64 *)pValue1));
+ break;
+ case HAL_ODM_DBG_LEVEL:
+ odm_cmn_info_update(podmpriv, ODM_CMNINFO_DBG_LEVEL, *((u32 *)pValue1));
+ break;
+ case HAL_ODM_RX_INFO_DUMP: {
+ struct false_ALARM_STATISTICS *false_alm_cnt = (struct false_ALARM_STATISTICS *)phydm_get_structure(podmpriv , PHYDMfalseALMCNT);
+ struct _dynamic_initial_gain_threshold_ *pDM_DigTable = &podmpriv->dm_dig_table;
+ void *sel;
+
+ sel = pValue1;
+
+ _RTW_PRINT_SEL(sel , "============ Rx Info dump ===================\n");
+ _RTW_PRINT_SEL(sel , "is_linked = %d, rssi_min = %d(%%), current_igi = 0x%x\n", podmpriv->is_linked, podmpriv->rssi_min, pDM_DigTable->cur_ig_value);
+ _RTW_PRINT_SEL(sel , "cnt_cck_fail = %d, cnt_ofdm_fail = %d, Total False Alarm = %d\n", false_alm_cnt->cnt_cck_fail, false_alm_cnt->cnt_ofdm_fail, false_alm_cnt->cnt_all);
+
+ if (podmpriv->is_linked) {
+ _RTW_PRINT_SEL(sel , "rx_rate = %s", HDATA_RATE(podmpriv->rx_rate));
+ _RTW_PRINT_SEL(sel , " RSSI_A = %d(%%), RSSI_B = %d(%%)\n", podmpriv->RSSI_A, podmpriv->RSSI_B);
+#ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
+ rtw_dump_raw_rssi_info(Adapter, sel);
+#endif
+ }
+ }
+ break;
+ case HAL_ODM_RX_Dframe_INFO: {
+ void *sel;
+
+ sel = pValue1;
+
+ /*_RTW_PRINT_SEL(sel , "HAL_ODM_RX_Dframe_INFO\n");*/
+#ifdef DBG_RX_DFRAME_RAW_DATA
+ rtw_dump_rx_dframe_info(Adapter, sel);
+#endif
+ }
+ break;
+
+#ifdef CONFIG_AUTO_CHNL_SEL_NHM
+ case HAL_ODM_AUTO_CHNL_SEL: {
+ ACS_OP acs_op = *(ACS_OP *)pValue1;
+
+ rtw_phydm_func_set(Adapter, ODM_BB_NHM_CNT);
+
+ if (ACS_INIT == acs_op) {
+#ifdef DBG_AUTO_CHNL_SEL_NHM
+ RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_INIT\n", ADPT_ARG(Adapter));
+#endif
+ odm_AutoChannelSelectInit(podmpriv);
+ } else if (ACS_RESET == acs_op) {
+ /* Reset statistics for auto channel selection mechanism.*/
+#ifdef DBG_AUTO_CHNL_SEL_NHM
+ RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_RESET\n", ADPT_ARG(Adapter));
+#endif
+ odm_auto_channel_select_reset(podmpriv);
+
+ } else if (ACS_SELECT == acs_op) {
+ /* Collect NHM measurement result after current channel */
+#ifdef DBG_AUTO_CHNL_SEL_NHM
+ RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_SELECT, CH(%d)\n", ADPT_ARG(Adapter), rtw_get_acs_channel(Adapter));
+#endif
+ odm_AutoChannelSelect(podmpriv, rtw_get_acs_channel(Adapter));
+ } else
+ RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: Unexpected OP\n", ADPT_ARG(Adapter));
+
+ }
+ break;
+#endif
+#ifdef CONFIG_ANTENNA_DIVERSITY
+ case HAL_ODM_ANTDIV_SELECT: {
+ u8 antenna = (*(u8 *)pValue1);
+
+ /*switch antenna*/
+ odm_update_rx_idle_ant(&pHalData->odmpriv, antenna);
+ /*RTW_INFO("==> HAL_ODM_ANTDIV_SELECT, Ant_(%s)\n", (antenna == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT");*/
+
+ }
+ break;
+#endif
+
+ default:
+ break;
+ }
+}
+
+void GetHalODMVar(
+ PADAPTER Adapter,
+ HAL_ODM_VARIABLE eVariable,
+ void * pValue1,
+ void * pValue2)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct PHY_DM_STRUCT *podmpriv = &pHalData->odmpriv;
+
+ switch (eVariable) {
+#if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
+ case HAL_ODM_NOISE_MONITOR: {
+ u8 chan = *(u8 *)pValue1;
+ *(s16 *)pValue2 = pHalData->noise[chan];
+#ifdef DBG_NOISE_MONITOR
+ RTW_INFO("### Noise monitor chan(%d)-noise:%d (dBm) ###\n",
+ chan, pHalData->noise[chan]);
+#endif
+ }
+ break;
+#endif/*#ifdef CONFIG_BACKGROUND_NOISE_MONITOR*/
+ case HAL_ODM_DBG_FLAG:
+ *((u64 *)pValue1) = podmpriv->debug_components;
+ break;
+ case HAL_ODM_DBG_LEVEL:
+ *((u32 *)pValue1) = podmpriv->debug_level;
+ break;
+
+#ifdef CONFIG_AUTO_CHNL_SEL_NHM
+ case HAL_ODM_AUTO_CHNL_SEL: {
+#ifdef DBG_AUTO_CHNL_SEL_NHM
+ RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: GET_BEST_CHAN\n", ADPT_ARG(Adapter));
+#endif
+ /* Retrieve better channel from NHM mechanism */
+ if (IsSupported24G(Adapter->registrypriv.wireless_mode))
+ *((u8 *)(pValue1)) = odm_get_auto_channel_select_result(podmpriv, BAND_ON_2_4G);
+ if (is_supported_5g(Adapter->registrypriv.wireless_mode))
+ *((u8 *)(pValue2)) = odm_get_auto_channel_select_result(podmpriv, BAND_ON_5G);
+ }
+ break;
+#endif
+#ifdef CONFIG_ANTENNA_DIVERSITY
+ case HAL_ODM_ANTDIV_SELECT: {
+ struct _FAST_ANTENNA_TRAINNING_ *pDM_FatTable = &podmpriv->dm_fat_table;
+ *((u8 *)pValue1) = pDM_FatTable->rx_idle_ant;
+ }
+ break;
+#endif
+ case HAL_ODM_INITIAL_GAIN: {
+ struct _dynamic_initial_gain_threshold_ *pDM_DigTable = &podmpriv->dm_dig_table;
+ *((u8 *)pValue1) = pDM_DigTable->cur_ig_value;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+
+u32 rtw_phydm_ability_ops(_adapter *adapter, HAL_PHYDM_OPS ops, u32 ability)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
+ struct PHY_DM_STRUCT *podmpriv = &pHalData->odmpriv;
+ u32 result = 0;
+
+ switch (ops) {
+ case HAL_PHYDM_DIS_ALL_FUNC:
+ podmpriv->support_ability = DYNAMIC_FUNC_DISABLE;
+ break;
+ case HAL_PHYDM_FUNC_SET:
+ podmpriv->support_ability |= ability;
+ break;
+ case HAL_PHYDM_FUNC_CLR:
+ podmpriv->support_ability &= ~(ability);
+ break;
+ case HAL_PHYDM_ABILITY_BK:
+ /* dm flag backup*/
+ podmpriv->bk_support_ability = podmpriv->support_ability;
+ break;
+ case HAL_PHYDM_ABILITY_RESTORE:
+ /* restore dm flag */
+ podmpriv->support_ability = podmpriv->bk_support_ability;
+ break;
+ case HAL_PHYDM_ABILITY_SET:
+ podmpriv->support_ability = ability;
+ break;
+ case HAL_PHYDM_ABILITY_GET:
+ result = podmpriv->support_ability;
+ break;
+ }
+ return result;
+}
+
+
+bool
+eqNByte(
+ u8 *str1,
+ u8 *str2,
+ u32 num
+)
+{
+ if (num == 0)
+ return false;
+ while (num > 0) {
+ num--;
+ if (str1[num] != str2[num])
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Description:
+ * Translate a character to hex digit.
+ * */
+u32
+MapCharToHexDigit(
+ char chTmp
+)
+{
+ if (chTmp >= '0' && chTmp <= '9')
+ return chTmp - '0';
+ else if (chTmp >= 'a' && chTmp <= 'f')
+ return 10 + (chTmp - 'a');
+ else if (chTmp >= 'A' && chTmp <= 'F')
+ return 10 + (chTmp - 'A');
+ else
+ return 0;
+}
+
+
+
+/*
+ * Description:
+ * Parse hex number from the string pucStr.
+ * */
+bool
+GetHexValueFromString(
+ char *szStr,
+ u32 *pu4bVal,
+ u32 *pu4bMove
+)
+{
+ char *szScan = szStr;
+
+ /* Check input parameter. */
+ if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
+ RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
+ return false;
+ }
+
+ /* Initialize output. */
+ *pu4bMove = 0;
+ *pu4bVal = 0;
+
+ /* Skip leading space. */
+ while (*szScan != '\0' &&
+ (*szScan == ' ' || *szScan == '\t')) {
+ szScan++;
+ (*pu4bMove)++;
+ }
+
+ /* Skip leading '0x' or '0X'. */
+ if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
+ szScan += 2;
+ (*pu4bMove) += 2;
+ }
+
+ /* Check if szScan is now pointer to a character for hex digit, */
+ /* if not, it means this is not a valid hex number. */
+ if (!IsHexDigit(*szScan))
+ return false;
+
+ /* Parse each digit. */
+ do {
+ (*pu4bVal) <<= 4;
+ *pu4bVal += MapCharToHexDigit(*szScan);
+
+ szScan++;
+ (*pu4bMove)++;
+ } while (IsHexDigit(*szScan));
+
+ return true;
+}
+
+bool
+GetFractionValueFromString(
+ char *szStr,
+ u8 *pInteger,
+ u8 *pFraction,
+ u32 *pu4bMove
+)
+{
+ char *szScan = szStr;
+
+ /* Initialize output. */
+ *pu4bMove = 0;
+ *pInteger = 0;
+ *pFraction = 0;
+
+ /* Skip leading space. */
+ while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) {
+ ++szScan;
+ ++(*pu4bMove);
+ }
+
+ /* Parse each digit. */
+ do {
+ (*pInteger) *= 10;
+ *pInteger += (*szScan - '0');
+
+ ++szScan;
+ ++(*pu4bMove);
+
+ if (*szScan == '.') {
+ ++szScan;
+ ++(*pu4bMove);
+
+ if (*szScan < '0' || *szScan > '9')
+ return false;
+ else {
+ *pFraction = *szScan - '0';
+ ++szScan;
+ ++(*pu4bMove);
+ return true;
+ }
+ }
+ } while (*szScan >= '0' && *szScan <= '9');
+
+ return true;
+}
+
+/*
+ * Description:
+ * Return true if szStr is comment out with leading " */ /* ".
+ * */
+bool
+IsCommentString(
+ char *szStr
+)
+{
+ if (*szStr == '/' && *(szStr + 1) == '/')
+ return true;
+ else
+ return false;
+}
+
+bool
+GetU1ByteIntegerFromStringInDecimal(
+ char *Str,
+ u8 *pInt
+)
+{
+ u16 i = 0;
+ *pInt = 0;
+
+ while (Str[i] != '\0') {
+ if (Str[i] >= '0' && Str[i] <= '9') {
+ *pInt *= 10;
+ *pInt += (Str[i] - '0');
+ } else
+ return false;
+ ++i;
+ }
+
+ return true;
+}
+
+/* <20121004, Kordan> For example,
+ * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
+ * If RightQualifier does not exist, it will hang on in the while loop */
+bool
+ParseQualifiedString(
+ char *In,
+ u32 *Start,
+ char *Out,
+ char LeftQualifier,
+ char RightQualifier
+)
+{
+ u32 i = 0, j = 0;
+ char c = In[(*Start)++];
+
+ if (c != LeftQualifier)
+ return false;
+
+ i = (*Start);
+ while ((c = In[(*Start)++]) != RightQualifier)
+ ; /* find ']' */
+ j = (*Start) - 2;
+ strncpy((char *)Out, (const char *)(In + i), j - i + 1);
+
+ return true;
+}
+
+bool
+isAllSpaceOrTab(
+ u8 *data,
+ u8 size
+)
+{
+ u8 cnt = 0, NumOfSpaceAndTab = 0;
+
+ while (size > cnt) {
+ if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
+ ++NumOfSpaceAndTab;
+
+ ++cnt;
+ }
+
+ return size == NumOfSpaceAndTab;
+}
+
+
+void rtw_hal_check_rxfifo_full(_adapter *adapter)
+{
+ struct dvobj_priv *psdpriv = adapter->dvobj;
+ struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
+ struct registry_priv *regsty = &adapter->registrypriv;
+ int save_cnt = false;
+
+ if (regsty->check_hw_status == 1) {
+ /* switch counter to RX fifo */
+ if (IS_8188E(pHalData->version_id) ||
+ IS_8188F(pHalData->version_id) ||
+ IS_8812_SERIES(pHalData->version_id) ||
+ IS_8821_SERIES(pHalData->version_id) ||
+ IS_8723B_SERIES(pHalData->version_id) ||
+ IS_8192E(pHalData->version_id) ||
+ IS_8703B_SERIES(pHalData->version_id) ||
+ IS_8723D_SERIES(pHalData->version_id)) {
+ rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
+ save_cnt = true;
+ } else {
+ /* todo: other chips */
+ }
+
+
+ if (save_cnt) {
+ pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
+ pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
+ pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
+ } else {
+ /* special value to indicate no implementation */
+ pdbgpriv->dbg_rx_fifo_last_overflow = 1;
+ pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
+ pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
+ }
+ }
+}
+
+void linked_info_dump(_adapter *padapter, u8 benable)
+{
+ struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
+
+ if (padapter->bLinkInfoDump == benable)
+ return;
+
+ RTW_INFO("%s %s\n", __func__, (benable) ? "enable" : "disable");
+
+ if (benable) {
+#ifdef CONFIG_LPS
+ pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
+ rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
+#endif
+
+#ifdef CONFIG_IPS
+ pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
+ rtw_pm_set_ips(padapter, IPS_NONE);
+#endif
+ } else {
+#ifdef CONFIG_IPS
+ rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
+#endif /* CONFIG_IPS */
+
+#ifdef CONFIG_LPS
+ rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
+#endif /* CONFIG_LPS */
+ }
+ padapter->bLinkInfoDump = benable ;
+}
+
+#ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
+void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
+{
+ u8 isCCKrate, rf_path;
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+ struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
+ RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
+ HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
+ isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? true : false;
+
+ if (isCCKrate)
+ psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
+
+ for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
+ RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
+ , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
+
+ if (!isCCKrate) {
+ RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
+ psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
+ }
+ }
+}
+
+void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
+{
+ u8 isCCKrate, rf_path;
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+ struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
+ _RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
+ _RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
+
+ isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? true : false;
+
+ if (isCCKrate)
+ psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
+
+ for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
+ _RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
+ , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
+
+ if (!isCCKrate)
+ _RTW_PRINT_SEL(sel , ",rx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n", psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
+ else
+ _RTW_PRINT_SEL(sel , "\n");
+
+ }
+}
+#endif
+
+#ifdef DBG_RX_DFRAME_RAW_DATA
+void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
+{
+ unsigned long irqL;
+ u8 isCCKrate, rf_path;
+ struct recv_priv *precvpriv = &(padapter->recvpriv);
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct sta_info *psta;
+ struct sta_recv_dframe_info *psta_dframe_info;
+ int i;
+ _list *plist, *phead;
+ char *BW;
+ u8 bc_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ u8 null_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ if (precvpriv->store_law_data_flag) {
+
+ _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
+
+ for (i = 0; i < NUM_STA; i++) {
+ phead = &(pstapriv->sta_hash[i]);
+ plist = get_next(phead);
+
+ while ((rtw_end_of_queue_search(phead, plist)) == false) {
+
+ psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
+ plist = get_next(plist);
+
+ if (psta) {
+ psta_dframe_info = &psta->sta_dframe_info;
+ if ((memcmp(psta->hwaddr, bc_addr, 6))
+ && (memcmp(psta->hwaddr, null_addr, 6))
+ && (memcmp(psta->hwaddr, adapter_mac_addr(padapter), 6))) {
+
+
+ isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? true : false;
+
+ switch (psta_dframe_info->sta_bw_mode) {
+
+ case CHANNEL_WIDTH_20:
+ BW = "20M";
+ break;
+
+ case CHANNEL_WIDTH_40:
+ BW = "40M";
+ break;
+
+ case CHANNEL_WIDTH_80:
+ BW = "80M";
+ break;
+
+ case CHANNEL_WIDTH_160:
+ BW = "160M";
+ break;
+
+ default:
+ BW = "";
+ break;
+ }
+
+ RTW_PRINT_SEL(sel, "==============================\n");
+ _RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
+ _RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", BW, psta_dframe_info->sta_sgi);
+ _RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
+
+ for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
+
+ if (!isCCKrate) {
+
+ _RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
+ _RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
+
+ } else
+
+ _RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
+ }
+ }
+ }
+ }
+ }
+ _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
+ }
+}
+#endif
+void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
+{
+ u8 isCCKrate, rf_path , dframe_type;
+ u8 *ptr;
+ u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+#ifdef DBG_RX_DFRAME_RAW_DATA
+ struct sta_recv_dframe_info *psta_dframe_info;
+#endif
+ struct recv_priv *precvpriv = &(padapter->recvpriv);
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+ struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
+ struct sta_info *psta = prframe->u.hdr.psta;
+ struct _odm_phy_status_info_ *p_phy_info = (struct _odm_phy_status_info_ *)(&pattrib->phy_info);
+ struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
+ psample_pkt_rssi->data_rate = pattrib->data_rate;
+ ptr = prframe->u.hdr.rx_data;
+ dframe_type = GetFrameType(ptr);
+ /*RTW_INFO("=>%s\n", __func__);*/
+
+
+ if (precvpriv->store_law_data_flag) {
+ isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? true : false;
+
+ psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
+ psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
+
+ for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
+ psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
+ psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
+ if (!isCCKrate) {
+ psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
+ psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
+ }
+ }
+#ifdef DBG_RX_DFRAME_RAW_DATA
+ if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
+
+ /*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __func__);*/
+ if (psta) {
+ psta_dframe_info = &psta->sta_dframe_info;
+ /*RTW_INFO("=>%s psta->hwaddr="MAC_FMT" !\n", __func__, MAC_ARG(psta->hwaddr));*/
+ if ((memcmp(psta->hwaddr, bc_addr, ETH_ALEN)) || (padapter->registrypriv.mp_mode == 1)) {
+ psta_dframe_info->sta_data_rate = pattrib->data_rate;
+ psta_dframe_info->sta_sgi = pattrib->sgi;
+ psta_dframe_info->sta_bw_mode = pattrib->bw;
+ for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
+
+ psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
+
+ if (!isCCKrate) {
+ psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
+ psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
+ }
+ }
+ }
+ }
+ }
+#endif
+ }
+
+}
+
+
+int check_phy_efuse_tx_power_info_valid(PADAPTER padapter)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+ u8 *pContent = pHalData->efuse_eeprom_data;
+ int index = 0;
+ u16 tx_index_offset = 0x0000;
+
+ switch (rtw_get_chip_type(padapter)) {
+ case RTL8723B:
+ tx_index_offset = EEPROM_TX_PWR_INX_8723B;
+ break;
+ case RTL8703B:
+ tx_index_offset = EEPROM_TX_PWR_INX_8703B;
+ break;
+ case RTL8723D:
+ tx_index_offset = EEPROM_TX_PWR_INX_8723D;
+ break;
+ case RTL8188E:
+ tx_index_offset = EEPROM_TX_PWR_INX_88E;
+ break;
+ case RTL8188F:
+ tx_index_offset = EEPROM_TX_PWR_INX_8188F;
+ break;
+ case RTL8192E:
+ tx_index_offset = EEPROM_TX_PWR_INX_8192E;
+ break;
+ case RTL8821:
+ tx_index_offset = EEPROM_TX_PWR_INX_8821;
+ break;
+ case RTL8812:
+ tx_index_offset = EEPROM_TX_PWR_INX_8812;
+ break;
+ case RTL8814A:
+ tx_index_offset = EEPROM_TX_PWR_INX_8814;
+ break;
+ case RTL8822B:
+ tx_index_offset = EEPROM_TX_PWR_INX_8822B;
+ break;
+ case RTL8821C:
+ tx_index_offset = EEPROM_TX_PWR_INX_8821C;
+ break;
+ default:
+ tx_index_offset = 0x0010;
+ break;
+ }
+
+ /* TODO: chacking length by ICs */
+ for (index = 0 ; index < 11 ; index++) {
+ if (pContent[tx_index_offset + index] == 0xFF)
+ return false;
+ }
+ return true;
+}
+
+int hal_efuse_macaddr_offset(_adapter *adapter)
+{
+ u8 interface_type = 0;
+ int addr_offset = -1;
+
+ interface_type = rtw_get_intf_type(adapter);
+
+ switch (rtw_get_chip_type(adapter)) {
+ case RTL8188E:
+ if (interface_type == RTW_USB)
+ addr_offset = EEPROM_MAC_ADDR_88EU;
+ else if (interface_type == RTW_SDIO)
+ addr_offset = EEPROM_MAC_ADDR_88ES;
+ else if (interface_type == RTW_PCIE)
+ addr_offset = EEPROM_MAC_ADDR_88EE;
+ break;
+ }
+
+ if (addr_offset == -1) {
+ RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
+ , __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
+ }
+
+ return addr_offset;
+}
+
+int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
+{
+ int ret = _FAIL;
+ int addr_offset;
+
+ addr_offset = hal_efuse_macaddr_offset(padapter);
+ if (addr_offset == -1)
+ goto exit;
+
+ ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
+
+exit:
+ return ret;
+}
+
+void rtw_dump_cur_efuse(PADAPTER padapter)
+{
+ int i =0;
+ u16 mapsize =0;
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
+
+ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, false);
+
+ if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
+ RTW_ERR("wrong map size %d\n", mapsize);
+ return;
+ }
+
+ if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
+ RTW_INFO("EFUSE FILE\n");
+ else
+ RTW_INFO("HW EFUSE\n");
+}
+
+#ifdef CONFIG_EFUSE_CONFIG_FILE
+u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
+ u32 ret = false;
+ u16 maplen = 0;
+
+ EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, false);
+
+ if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
+ RTW_ERR("eFuse length error :%d\n", maplen);
+ return false;
+ }
+
+ 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)
+ rtw_dump_cur_efuse(padapter);
+
+ return ret;
+}
+
+u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
+ u32 ret = _FAIL;
+
+ if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
+ && rtw_check_invalid_mac_address(mac_addr, true) == false
+ ) {
+ hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
+ ret = _SUCCESS;
+ } else
+ hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
+
+ return ret;
+}
+#endif /* CONFIG_EFUSE_CONFIG_FILE */
+
+int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ u8 addr[ETH_ALEN];
+ int addr_offset = hal_efuse_macaddr_offset(adapter);
+ u8 *hw_addr = NULL;
+ int ret = _SUCCESS;
+
+ if (autoload_fail)
+ goto bypass_hw_pg;
+
+ if (addr_offset != -1)
+ hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
+
+#ifdef CONFIG_EFUSE_CONFIG_FILE
+ /* if the hw_addr is written by efuse file, set to NULL */
+ if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
+ hw_addr = NULL;
+#endif
+
+ if (!hw_addr) {
+ /* try getting hw pg data */
+ if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
+ hw_addr = addr;
+ }
+
+ /* check hw pg data */
+ if (hw_addr && rtw_check_invalid_mac_address(hw_addr, true) == false) {
+ memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
+ goto exit;
+ }
+
+bypass_hw_pg:
+
+#ifdef CONFIG_EFUSE_CONFIG_FILE
+ /* check wifi mac file */
+ if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
+ memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
+ goto exit;
+ }
+#endif
+
+ memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
+ ret = _FAIL;
+
+exit:
+ return ret;
+}
+
+#ifdef CONFIG_RF_POWER_TRIM
+u32 Array_kfreemap[] = {
+ 0x08, 0xe,
+ 0x06, 0xc,
+ 0x04, 0xa,
+ 0x02, 0x8,
+ 0x00, 0x6,
+ 0x03, 0x4,
+ 0x05, 0x2,
+ 0x07, 0x0,
+ 0x09, 0x0,
+ 0x0c, 0x0,
+};
+
+void rtw_bb_rf_gain_offset(_adapter *padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct registry_priv *registry_par = &padapter->registrypriv;
+ struct kfree_data_t *kfree_data = &pHalData->kfree_data;
+ u8 value = pHalData->EEPROMRFGainOffset;
+ u8 tmp = 0x3e;
+ u32 res, i = 0;
+ u32 ArrayLen = sizeof(Array_kfreemap) / sizeof(u32);
+ u32 * Array = Array_kfreemap;
+ u32 v1 = 0, v2 = 0, GainValue = 0, target = 0;
+
+ if (registry_par->RegPwrTrimEnable == 2) {
+ RTW_INFO("Registry kfree default force disable.\n");
+ return;
+ }
+
+ if (value & BIT4 || (registry_par->RegPwrTrimEnable == 1)) {
+ RTW_INFO("8188ES Offset RF Gain.\n");
+ RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
+ pHalData->EEPROMRFGainVal);
+
+ if (pHalData->EEPROMRFGainVal != 0xff) {
+ res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
+ REG_RF_BB_GAIN_OFFSET, 0xffffffff);
+
+ RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
+ res &= 0xfff87fff;
+
+ res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
+ RTW_INFO("Offset RF Gain. res=0x%x\n", res);
+
+ rtw_hal_write_rfreg(padapter, RF_PATH_A,
+ REG_RF_BB_GAIN_OFFSET,
+ RF_GAIN_OFFSET_MASK, res);
+ } else {
+ RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
+ pHalData->EEPROMRFGainVal);
+ }
+ } else
+ RTW_INFO("Using the default RF gain.\n");
+}
+#endif /*CONFIG_RF_POWER_TRIM */
+
+bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
+{
+#ifdef CONFIG_RF_POWER_TRIM
+ int i, j;
+
+ for (i = 0; i < BB_GAIN_NUM; i++)
+ for (j = 0; j < RF_PATH_MAX; j++)
+ if (data->bb_gain[i][j] != 0)
+ return 0;
+#endif
+ return 1;
+}
+
+#ifdef CONFIG_USB_RX_AGGREGATION
+static void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ if (cur_wireless_mode < WIRELESS_11_24N
+ && cur_wireless_mode > 0) { /* ABG mode */
+#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
+ u32 remainder = 0;
+ u8 quotient = 0;
+
+ remainder = MAX_RECVBUF_SZ % (4 * 1024);
+ quotient = (u8)(MAX_RECVBUF_SZ >> 12);
+
+ if (quotient > 5) {
+ pHalData->rxagg_usb_size = 0x6;
+ pHalData->rxagg_usb_timeout = 0x10;
+ } else {
+ if (remainder >= 2048) {
+ pHalData->rxagg_usb_size = quotient;
+ pHalData->rxagg_usb_timeout = 0x10;
+ } else {
+ pHalData->rxagg_usb_size = (quotient - 1);
+ pHalData->rxagg_usb_timeout = 0x10;
+ }
+ }
+#else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
+ if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
+ pHalData->rxagg_usb_size = 0x6;
+ pHalData->rxagg_usb_timeout = 0x10;
+ rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
+ pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
+ }
+#endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
+
+ } else if (cur_wireless_mode >= WIRELESS_11_24N
+ && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
+#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
+ u32 remainder = 0;
+ u8 quotient = 0;
+
+ remainder = MAX_RECVBUF_SZ % (4 * 1024);
+ quotient = (u8)(MAX_RECVBUF_SZ >> 12);
+
+ if (quotient > 5) {
+ pHalData->rxagg_usb_size = 0x5;
+ pHalData->rxagg_usb_timeout = 0x20;
+ } else {
+ if (remainder >= 2048) {
+ pHalData->rxagg_usb_size = quotient;
+ pHalData->rxagg_usb_timeout = 0x10;
+ } else {
+ pHalData->rxagg_usb_size = (quotient - 1);
+ pHalData->rxagg_usb_timeout = 0x10;
+ }
+ }
+#else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
+ if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
+ pHalData->rxagg_usb_size = 0x5;
+ pHalData->rxagg_usb_timeout = 0x20;
+ rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
+ pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
+ }
+#endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
+
+ } else {
+ /* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
+ }
+}
+
+static void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ if (cur_wireless_mode < WIRELESS_11_24N
+ && cur_wireless_mode > 0) { /* ABG mode */
+ if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
+ || 0x10 != pHalData->rxagg_usb_timeout) {
+ pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
+ pHalData->rxagg_usb_timeout = 0x10;
+ rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
+ pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
+ }
+ } else if (cur_wireless_mode >= WIRELESS_11_24N
+ && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
+ if (UsbDmaSize != pHalData->rxagg_usb_size
+ || 0x20 != pHalData->rxagg_usb_timeout) {
+ pHalData->rxagg_usb_size = UsbDmaSize;
+ pHalData->rxagg_usb_timeout = 0x20;
+ rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
+ pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
+ }
+ } else {
+ /* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
+ }
+}
+
+static void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
+{
+#ifdef CONFIG_PLATFORM_NOVATEK_NT72668
+ rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
+ return;
+#endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
+
+ rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
+}
+#endif /* CONFIG_USB_RX_AGGREGATION */
+
+/* To avoid RX affect TX throughput */
+void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
+{
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ u8 cur_wireless_mode = WIRELESS_INVALID;
+
+#ifdef CONFIG_USB_RX_AGGREGATION
+#ifdef CONFIG_PLATFORM_NOVATEK_NT72668
+ rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
+#endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
+#endif
+}
+
+/* bus-agg check for SoftAP mode */
+inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
+{
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u8 chk_rst = _SUCCESS;
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
+ return chk_rst;
+
+ /* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
+ /* return chk_rst; */
+
+ if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
+ && (pre_qsel != next_qsel)) {
+ /* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
+ /* pre_qsel,next_qsel); */
+ chk_rst = _FAIL;
+ }
+ return chk_rst;
+}
+
+/*
+ * Description:
+ * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
+ * contant.
+ *
+ * Input:
+ * adapter: adapter pointer.
+ * page_num: The max. page number that user want to dump.
+ * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
+ */
+void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
+{
+
+ int i;
+ u8 val = 0;
+ u8 base = 0;
+ u32 addr = 0;
+ u32 count = (page_size / 8);
+
+ if (page_num <= 0) {
+ RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
+ return;
+ }
+
+ if (page_size < 128 || page_size > 512) {
+ RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
+ return;
+ }
+
+ RTW_INFO("+%s+\n", __func__);
+ val = rtw_read8(padapter, 0x106);
+ rtw_write8(padapter, 0x106, 0x69);
+ RTW_INFO("0x106: 0x%02x\n", val);
+ base = rtw_read8(padapter, 0x209);
+ RTW_INFO("0x209: 0x%02x\n", base);
+
+ addr = ((base)*page_size) / 8;
+ for (i = 0 ; i < page_num * count ; i += 2) {
+ rtw_write32(padapter, 0x140, addr + i);
+ printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
+ rtw_write32(padapter, 0x140, addr + i + 1);
+ printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
+ }
+}
+
+#ifdef CONFIG_GPIO_API
+u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
+{
+ u8 value = 0;
+ u8 direction = 0;
+ u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
+ u8 gpio_num_to_set = gpio_num;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+
+ if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
+ return value;
+
+ rtw_ps_deny(adapter, PS_DENY_IOCTL);
+
+ RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
+ LeaveAllPowerSaveModeDirect(adapter);
+
+ if (gpio_num > 7) {
+ gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
+ gpio_num_to_set = gpio_num - 8;
+ }
+
+ /* Read GPIO Direction */
+ direction = (rtw_read8(adapter, gpio_ctrl_reg_to_set) & BIT(gpio_num_to_set)) >> gpio_num;
+
+ /* According the direction to read register value */
+ if (direction)
+ value = (rtw_read8(adapter, gpio_ctrl_reg_to_set) & BIT(gpio_num_to_set)) >> gpio_num;
+ else
+ value = (rtw_read8(adapter, gpio_ctrl_reg_to_set) & BIT(gpio_num_to_set)) >> gpio_num;
+
+ rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
+ RTW_INFO("%s direction=%d value=%d\n", __func__, direction, value);
+
+ return value;
+}
+
+int rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
+{
+ u8 direction = 0;
+ u8 res = -1;
+ u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
+ u8 gpio_num_to_set = gpio_num;
+
+ if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
+ return -1;
+
+ rtw_ps_deny(adapter, PS_DENY_IOCTL);
+
+ LeaveAllPowerSaveModeDirect(adapter);
+
+ if (gpio_num > 7) {
+ gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
+ gpio_num_to_set = gpio_num - 8;
+ }
+
+ /* Read GPIO direction */
+ direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
+
+ /* If GPIO is output direction, setting value. */
+ if (direction) {
+ if (isHigh)
+ rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
+ else
+ rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
+
+ RTW_INFO("%s Set gpio %x[%d]=%d\n", __func__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
+ res = 0;
+ } else {
+ RTW_INFO("%s The gpio is input,not be set!\n", __func__);
+ res = -1;
+ }
+
+ rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
+ return res;
+}
+
+int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
+{
+ u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
+ u8 gpio_num_to_set = gpio_num;
+
+ if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
+ return -1;
+
+ RTW_INFO("%s gpio_num =%d direction=%d\n", __func__, gpio_num, isOutput);
+
+ rtw_ps_deny(adapter, PS_DENY_IOCTL);
+
+ LeaveAllPowerSaveModeDirect(adapter);
+
+ rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
+
+ if (gpio_num > 7) {
+ gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
+ gpio_num_to_set = gpio_num - 8;
+ }
+
+ if (isOutput)
+ rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
+ else
+ rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
+
+ rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
+
+ return 0;
+}
+int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
+{
+ u8 value;
+ u8 direction;
+ PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
+
+ if (IS_HARDWARE_TYPE_8188E(adapter)) {
+ if (gpio_num > 7 || gpio_num < 4) {
+ RTW_PRINT("%s The gpio number does not included 4~7.\n", __func__);
+ return -1;
+ }
+ }
+
+ rtw_ps_deny(adapter, PS_DENY_IOCTL);
+
+ LeaveAllPowerSaveModeDirect(adapter);
+
+ /* Read GPIO direction */
+ direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
+ if (direction) {
+ RTW_PRINT("%s Can't register output gpio as interrupt.\n", __func__);
+ return -1;
+ }
+
+ /* Config GPIO Mode */
+ rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
+
+ /* Register GPIO interrupt handler*/
+ adapter->gpiointpriv.callback[gpio_num] = callback;
+
+ /* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
+ value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
+ adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
+ rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
+
+ /* Enable GPIO interrupt */
+ adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
+ rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
+
+ rtw_hal_update_hisr_hsisr_ind(adapter, 1);
+
+ rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
+
+ return 0;
+}
+int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
+{
+ u8 value;
+ u8 direction;
+ PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
+
+ if (IS_HARDWARE_TYPE_8188E(adapter)) {
+ if (gpio_num > 7 || gpio_num < 4) {
+ RTW_INFO("%s The gpio number does not included 4~7.\n", __func__);
+ return -1;
+ }
+ }
+
+ rtw_ps_deny(adapter, PS_DENY_IOCTL);
+
+ LeaveAllPowerSaveModeDirect(adapter);
+
+ /* Config GPIO Mode */
+ rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
+
+ /* Unregister GPIO interrupt handler*/
+ adapter->gpiointpriv.callback[gpio_num] = NULL;
+
+ /* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
+ adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
+ rtw_write8(adapter, REG_GPIO_INTM, 0x00);
+
+ /* Disable GPIO interrupt */
+ adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
+ rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
+
+ if (!adapter->gpiointpriv.interrupt_enable_mask)
+ rtw_hal_update_hisr_hsisr_ind(adapter, 0);
+
+ rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
+
+ return 0;
+}
+#endif
+
+s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ u8 i;
+
+ for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
+ if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
+ if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
+ && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ s8 res;
+ u8 i;
+
+ /* If it's an existed record, overwrite it */
+ res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
+ if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
+ rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
+ return;
+ }
+
+ /* Search for the empty record to use */
+ for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
+ if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
+ rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
+ return;
+ }
+ }
+
+ /* Else, overwrite the oldest record */
+ for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
+ memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
+
+ rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
+}
+
+void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
+{
+ rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
+}
+
+void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
+{
+ u32 mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
+ u32 mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
+ u32 mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
+ u32 DropPacket = 0;
+
+ if (!rx_counter) {
+ rtw_warn_on(1);
+ return;
+ }
+ phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
+ mac_cck_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
+ phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
+ mac_ofdm_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
+ phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
+ mac_ht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
+ mac_vht_ok = 0;
+
+ phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
+ mac_cck_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
+ phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
+ mac_ofdm_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
+ phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
+ mac_ht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
+ mac_vht_err = 0;
+
+ phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
+ mac_cck_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
+ phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
+ mac_ofdm_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
+ phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
+ mac_ht_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
+
+ /* Mac_DropPacket */
+ rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
+ DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
+
+ rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
+ rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
+ rx_counter->rx_cck_fa = mac_cck_fa;
+ rx_counter->rx_ofdm_fa = mac_ofdm_fa;
+ rx_counter->rx_ht_fa = mac_ht_fa;
+ rx_counter->rx_pkt_drop = DropPacket;
+}
+void rtw_reset_mac_rx_counters(_adapter *padapter)
+{
+ /* reset mac counter */
+ phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
+ phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
+}
+
+void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
+{
+ u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0, vht_ok = 0, vht_err = 0;
+ if (!rx_counter) {
+ rtw_warn_on(1);
+ return;
+ }
+ cckok = phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
+ ofdmok = phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
+ htok = phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
+ vht_ok = 0;
+ cckcrc = phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
+ ofdmcrc = phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
+ htcrc = phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
+ vht_err = 0;
+ OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +
+ phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
+ phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
+
+ CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
+
+ rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
+ rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
+ rx_counter->rx_ofdm_fa = OFDM_FA;
+ rx_counter->rx_cck_fa = CCK_FA;
+
+}
+
+void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
+{
+}
+
+void rtw_reset_phy_rx_counters(_adapter *padapter)
+{
+ /* reset phy counter */
+ phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
+ rtw_msleep_os(10);
+ phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
+
+ phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset OFDA FA counter */
+ phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset OFDA FA counter */
+ phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
+ phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
+
+ phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
+ phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
+}
+
+#ifdef DBG_RX_COUNTER_DUMP
+void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
+{
+ struct recv_priv *precvpriv = &padapter->recvpriv;
+ if (!rx_counter) {
+ rtw_warn_on(1);
+ return;
+ }
+ rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
+ rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
+ rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
+}
+void rtw_reset_drv_rx_counters(_adapter *padapter)
+{
+ struct recv_priv *precvpriv = &padapter->recvpriv;
+ padapter->drv_rx_cnt_ok = 0;
+ padapter->drv_rx_cnt_crcerror = 0;
+ padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
+}
+void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
+{
+ u8 initialgain;
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
+
+ if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
+ rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
+ RTW_INFO("%s CurIGValue:0x%02x\n", __func__, initialgain);
+ rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, false);
+ /*disable dynamic functions, such as high power, DIG*/
+ rtw_phydm_ability_backup(padapter);
+ rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
+ } else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
+ /* turn on phy-dynamic functions */
+ rtw_phydm_ability_restore(padapter);
+ initialgain = 0xff; /* restore RX GAIN */
+ rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, false);
+
+ }
+}
+
+void rtw_dump_rx_counters(_adapter *padapter)
+{
+ struct dbg_rx_counter rx_counter;
+
+ if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
+ memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
+ rtw_dump_drv_rx_counters(padapter, &rx_counter);
+ RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
+ rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
+ rtw_reset_drv_rx_counters(padapter);
+ }
+
+ if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
+ memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
+ rtw_dump_mac_rx_counters(padapter, &rx_counter);
+ RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
+ rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
+ rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
+ rx_counter.rx_pkt_drop);
+ rtw_reset_mac_rx_counters(padapter);
+ }
+
+ if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
+ memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
+ rtw_dump_phy_rx_counters(padapter, &rx_counter);
+ /* RTW_INFO("%s: OFDM_FA =%d\n", __func__, rx_counter.rx_ofdm_fa); */
+ /* RTW_INFO("%s: CCK_FA =%d\n", __func__, rx_counter.rx_cck_fa); */
+ RTW_INFO("Phy Received packet OK:%d CRC error:%d FA Counter: %d\n", rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
+ rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
+ rtw_reset_phy_rx_counters(padapter);
+ }
+}
+#endif
+void rtw_get_noise(_adapter *padapter)
+{
+#if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct noise_info info;
+ if (rtw_linked_check(padapter)) {
+ info.bPauseDIG = true;
+ info.IGIValue = 0x1e;
+ info.max_time = 100;/* ms */
+ info.chan = pmlmeext->cur_channel ;/* rtw_get_oper_ch(padapter); */
+ rtw_ps_deny(padapter, PS_DENY_IOCTL);
+ LeaveAllPowerSaveModeDirect(padapter);
+
+ rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, false);
+ /* odm_inband_noise_monitor(podmpriv,true,0x20,100); */
+ rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
+ rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &(info.chan), &(padapter->recvpriv.noise));
+#ifdef DBG_NOISE_MONITOR
+ RTW_INFO("chan:%d,noise_level:%d\n", info.chan, padapter->recvpriv.noise);
+#endif
+ }
+#endif
+
+}
+u8 rtw_get_current_tx_sgi(_adapter *padapter, u8 macid)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
+ struct _rate_adaptive_table_ *pRA_Table = &pDM_Odm->dm_ra_table;
+ u8 curr_tx_sgi = 0;
+
+ curr_tx_sgi = odm_ra_get_decision_rate_8188e(pDM_Odm, macid);
+
+ return curr_tx_sgi;
+}
+
+u8 rtw_get_current_tx_rate(_adapter *padapter, u8 macid)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
+ struct _rate_adaptive_table_ *pRA_Table = &pDM_Odm->dm_ra_table;
+ u8 rate_id = 0;
+
+#if (RATE_ADAPTIVE_SUPPORT == 1)
+ rate_id = odm_ra_get_decision_rate_8188e(pDM_Odm, macid);
+#else
+ rate_id = (pRA_Table->link_tx_rate[macid]) & 0x7f;
+#endif
+
+ return rate_id;
+
+}
+
+void update_IOT_info(_adapter *padapter)
+{
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ switch (pmlmeinfo->assoc_AP_vendor) {
+ case HT_IOT_PEER_MARVELL:
+ pmlmeinfo->turboMode_cts2self = 1;
+ pmlmeinfo->turboMode_rtsen = 0;
+ break;
+
+ case HT_IOT_PEER_RALINK:
+ pmlmeinfo->turboMode_cts2self = 0;
+ pmlmeinfo->turboMode_rtsen = 1;
+ /* disable high power */
+ rtw_phydm_func_clr(padapter, ODM_BB_DYNAMIC_TXPWR);
+ break;
+ case HT_IOT_PEER_REALTEK:
+ /* rtw_write16(padapter, 0x4cc, 0xffff); */
+ /* rtw_write16(padapter, 0x546, 0x01c0); */
+ /* disable high power */
+ rtw_phydm_func_clr(padapter, ODM_BB_DYNAMIC_TXPWR);
+ break;
+ default:
+ pmlmeinfo->turboMode_cts2self = 0;
+ pmlmeinfo->turboMode_rtsen = 1;
+ break;
+ }
+
+}
+#ifdef CONFIG_AUTO_CHNL_SEL_NHM
+void rtw_acs_start(_adapter *padapter, bool bStart)
+{
+ if (bStart) {
+ ACS_OP acs_op = ACS_INIT;
+
+ rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, true);
+ rtw_set_acs_channel(padapter, 0);
+ SET_ACS_STATE(padapter, ACS_ENABLE);
+ } else {
+ SET_ACS_STATE(padapter, ACS_DISABLE);
+#ifdef DBG_AUTO_CHNL_SEL_NHM
+ if (1) {
+ u8 best_24g_ch = 0;
+ u8 best_5g_ch = 0;
+
+ rtw_hal_get_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &(best_24g_ch), &(best_5g_ch));
+ RTW_INFO("[ACS-"ADPT_FMT"] Best 2.4G CH:%u\n", ADPT_ARG(padapter), best_24g_ch);
+ RTW_INFO("[ACS-"ADPT_FMT"] Best 5G CH:%u\n", ADPT_ARG(padapter), best_5g_ch);
+ }
+#endif
+ }
+}
+#endif
+
+/* TODO: merge with phydm, see odm_SetCrystalCap() */
+void hal_set_crystal_cap(_adapter *adapter, u8 crystal_cap)
+{
+ crystal_cap = crystal_cap & 0x3F;
+
+ switch (rtw_get_chip_type(adapter)) {
+ case RTL8188E:
+ case RTL8188F:
+ /* write 0x24[16:11] = 0x24[22:17] = CrystalCap */
+ phy_set_bb_reg(adapter, REG_AFE_XTAL_CTRL, 0x007FF800, (crystal_cap | (crystal_cap << 6)));
+ break;
+ default:
+ rtw_warn_on(1);
+ }
+}
+
+int hal_spec_init(_adapter *adapter)
+{
+ u8 interface_type = 0;
+ int ret = _SUCCESS;
+
+ interface_type = rtw_get_intf_type(adapter);
+
+ switch (rtw_get_chip_type(adapter)) {
+ case RTL8188E:
+ init_hal_spec_8188e(adapter);
+ break;
+ default:
+ RTW_ERR("%s: unknown chip_type:%u\n"
+ , __func__, rtw_get_chip_type(adapter));
+ ret = _FAIL;
+ break;
+ }
+ return ret;
+}
+
+static const char *const _band_cap_str[] = {
+ /* BIT0 */"2G",
+ /* BIT1 */"5G",
+};
+
+static const char *const _bw_cap_str[] = {
+ /* BIT0 */"5M",
+ /* BIT1 */"10M",
+ /* BIT2 */"20M",
+ /* BIT3 */"40M",
+ /* BIT4 */"80M",
+ /* BIT5 */"160M",
+ /* BIT6 */"80_80M",
+};
+
+static const char *const _proto_cap_str[] = {
+ /* BIT0 */"b",
+ /* BIT1 */"g",
+ /* BIT2 */"n",
+ /* BIT3 */"ac",
+};
+
+static const char *const _wl_func_str[] = {
+ /* BIT0 */"P2P",
+ /* BIT1 */"MIRACAST",
+ /* BIT2 */"TDLS",
+ /* BIT3 */"FTM",
+};
+
+void dump_hal_spec(void *sel, _adapter *adapter)
+{
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ int i;
+
+ RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
+ RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
+ RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
+ RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
+ RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
+ RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
+ RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
+ RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
+
+ RTW_PRINT_SEL(sel, "band_cap:");
+ for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
+ if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
+ _RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
+ }
+ _RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "bw_cap:");
+ for (i = 0; i < BW_CAP_BIT_NUM; i++) {
+ if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
+ _RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
+ }
+ _RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "proto_cap:");
+ for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
+ if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
+ _RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
+ }
+ _RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "wl_func:");
+ for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
+ if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
+ _RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
+ }
+ _RTW_PRINT_SEL(sel, "\n");
+}
+
+inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
+{
+ return GET_HAL_SPEC(adapter)->band_cap & cap;
+}
+
+inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
+{
+ return GET_HAL_SPEC(adapter)->bw_cap & cap;
+}
+
+inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
+{
+ return GET_HAL_SPEC(adapter)->proto_cap & cap;
+}
+
+inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
+{
+ return GET_HAL_SPEC(adapter)->wl_func & func;
+}
+
+inline bool hal_is_band_support(_adapter *adapter, u8 band)
+{
+ return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
+}
+
+inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
+{
+ return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
+}
+
+inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
+{
+ u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
+
+ if (mode == WIRELESS_11B)
+ if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
+ return 1;
+
+ if (mode == WIRELESS_11G)
+ if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
+ return 1;
+
+ if (mode == WIRELESS_11A)
+ if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
+ return 1;
+
+ if (mode == WIRELESS_11_24N)
+ if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
+ return 1;
+
+ if (mode == WIRELESS_11_5N)
+ if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
+ return 1;
+
+ if (mode == WIRELESS_11AC)
+ if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
+ return 1;
+
+ return 0;
+}
+
+/*
+* hal_largest_bw - starting from in_bw, get largest bw supported by HAL
+* @adapter:
+* @in_bw: starting bw, value of CHANNEL_WIDTH
+*
+* Returns: value of CHANNEL_WIDTH
+*/
+u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
+{
+ for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
+ if (hal_is_bw_support(adapter, in_bw))
+ break;
+ }
+
+ if (!hal_is_bw_support(adapter, in_bw))
+ rtw_warn_on(1);
+
+ return in_bw;
+}
+
+void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
+{
+ if (hw_port == HW_PORT0) {
+ /*disable related TSF function*/
+ rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
+
+ rtw_write32(padapter, REG_TSFTR, tsf);
+ rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
+
+ /*enable related TSF function*/
+ rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
+ } else if (hw_port == HW_PORT1) {
+ /*disable related TSF function*/
+ rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
+
+ rtw_write32(padapter, REG_TSFTR1, tsf);
+ rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
+
+ /*enable related TSF function*/
+ rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
+ } else
+ RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
+}
+
+void ResumeTxBeacon(_adapter *padapter)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+
+
+ /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
+ /* which should be read from register to a global variable. */
+
+
+ pHalData->RegFwHwTxQCtrl |= BIT(6);
+ rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl);
+ /*TBTT hold time :4ms 0x540[19:8]*/
+ rtw_write8(padapter, REG_TBTT_PROHIBIT + 1,
+ TBTT_PROBIHIT_HOLD_TIME & 0xFF);
+ rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
+ (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROBIHIT_HOLD_TIME >> 8));
+}
+
+void StopTxBeacon(_adapter *padapter)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+
+
+ /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
+ /* which should be read from register to a global variable. */
+
+
+ pHalData->RegFwHwTxQCtrl &= ~BIT(6);
+ rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl);
+ rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0x64);
+ rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
+ (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0));
+
+ /*CheckFwRsvdPageContent(padapter);*/ /* 2010.06.23. Added by tynli. */
+}
+
+#ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
+void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
+{
+ RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
+
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) & (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)));
+
+ /* disable Port0 TSF update*/
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | DIS_TSF_UDT);
+
+ /* set net_type */
+ Set_MSR(Adapter, mode);
+
+ if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
+ if (!rtw_mi_check_status(Adapter, MI_AP_MODE))
+ StopTxBeacon(Adapter);
+
+ rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM);/*disable atim wnd*/
+ } else if (mode == _HW_STATE_ADHOC_) {
+ ResumeTxBeacon(Adapter);
+ rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
+
+ } else if (mode == _HW_STATE_AP_) {
+ ResumeTxBeacon(Adapter);
+
+ rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
+
+ /*enable to rx data frame*/
+ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
+
+ /*Beacon Control related register for first time*/
+ rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */
+
+ /*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
+ rtw_write8(Adapter, REG_ATIMWND, 0x0a); /* 10ms */
+ rtw_write16(Adapter, REG_BCNTCFG, 0x00);
+ rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04);
+ rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
+
+ /*reset TSF*/
+ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
+
+ /*enable BCN0 Function for if1*/
+ /*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
+ rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
+ }
+}
+#endif
+
+#ifdef CONFIG_ANTENNA_DIVERSITY
+u8 rtw_hal_antdiv_before_linked(_adapter *padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ u8 cur_ant, change_ant;
+
+ if (!pHalData->AntDivCfg)
+ return false;
+
+ if (pHalData->sw_antdiv_bl_state == 0) {
+ pHalData->sw_antdiv_bl_state = 1;
+
+ rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
+ change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
+
+ return rtw_antenna_select_cmd(padapter, change_ant, false);
+ }
+
+ pHalData->sw_antdiv_bl_state = 0;
+ return false;
+}
+
+void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ if (pHalData->AntDivCfg) {
+ /*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
+ /*select optimum_antenna for before linked =>For antenna diversity*/
+ if (dst->Rssi >= src->Rssi) {/*keep org parameter*/
+ src->Rssi = dst->Rssi;
+ src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
+ }
+ }
+}
+#endif
+
+#ifdef CONFIG_PHY_CAPABILITY_QUERY
+static void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
+ struct phy_spec_t *phy_spec = &pHalData->phy_spec;
+
+ RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
+ RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index [15:8]*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index [7:0]*/
+
+ RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
+ RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Tx : %s\n", ((phy_spec->stbc_cap >> 24) & 0xFF) ? "Supported" : "N/A"); /*VHT STBC Tx [31:24]*/
+ /*VHT STBC Rx [23:16]
+ 0 = not support
+ 1 = support for 1 spatial stream
+ 2 = support for 1 or 2 spatial streams
+ 3 = support for 1 or 2 or 3 spatial streams
+ 4 = support for 1 or 2 or 3 or 4 spatial streams*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
+ RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Tx : %s\n", ((phy_spec->stbc_cap >> 8) & 0xFF) ? "Supported" : "N/A"); /*HT STBC Tx [15:8]*/
+ /*HT STBC Rx [7:0]
+ 0 = not support
+ 1 = support for 1 spatial stream
+ 2 = support for 1 or 2 spatial streams
+ 3 = support for 1 or 2 or 3 spatial streams*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
+
+ RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
+ RTW_PRINT_SEL(sel, "[PHY SPEC] VHT LDPC Tx : %s\n", ((phy_spec->ldpc_cap >> 24) & 0xFF) ? "Supported" : "N/A"); /*VHT LDPC Tx [31:24]*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] VHT LDPC Rx : %s\n", ((phy_spec->ldpc_cap >> 16) & 0xFF) ? "Supported" : "N/A"); /*VHT LDPC Rx [23:16]*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Tx : %s\n", ((phy_spec->ldpc_cap >> 8) & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Tx [15:8]*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Rx : %s\n\n", (phy_spec->ldpc_cap & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Rx [7:0]*/
+ #ifdef CONFIG_BEAMFORMING
+ RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
+ RTW_PRINT_SEL(sel, "[PHY SPEC] VHT MU Bfer : %s\n", ((phy_spec->txbf_cap >> 28) & 0xF) ? "Supported" : "N/A"); /*VHT MU Bfer [31:28]*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] VHT MU Bfee : %s\n", ((phy_spec->txbf_cap >> 24) & 0xF) ? "Supported" : "N/A"); /*VHT MU Bfee [27:24]*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] VHT SU Bfer : %s\n", ((phy_spec->txbf_cap >> 20) & 0xF) ? "Supported" : "N/A"); /*VHT SU Bfer [23:20]*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] VHT SU Bfee : %s\n", ((phy_spec->txbf_cap >> 16) & 0xF) ? "Supported" : "N/A"); /*VHT SU Bfee [19:16]*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF) ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
+
+ RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
+ RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
+ RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
+ #endif
+}
+#else
+static void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
+{
+ u8 phy_cap = false;
+
+ /* STBC */
+ rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
+ RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (phy_cap) ? "Supported" : "N/A");
+
+ phy_cap = false;
+ rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
+ RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (phy_cap) ? "Supported" : "N/A");
+
+ /* LDPC support */
+ phy_cap = false;
+ rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
+ RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (phy_cap) ? "Supported" : "N/A");
+
+ phy_cap = false;
+ rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
+ RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (phy_cap) ? "Supported" : "N/A");
+
+ #ifdef CONFIG_BEAMFORMING
+ phy_cap = false;
+ rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
+ RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (phy_cap) ? "Supported" : "N/A");
+
+ phy_cap = false;
+ rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
+ RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (phy_cap) ? "Supported" : "N/A");
+
+ phy_cap = false;
+ rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
+ RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (phy_cap) ? "Supported" : "N/A");
+
+ phy_cap = false;
+ rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
+ RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (phy_cap) ? "Supported" : "N/A");
+ #endif
+}
+#endif
+void rtw_dump_phy_cap(void *sel, _adapter *adapter)
+{
+ RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
+#ifdef CONFIG_PHY_CAPABILITY_QUERY
+ rtw_dump_phy_cap_by_phydmapi(sel, adapter);
+#else
+ rtw_dump_phy_cap_by_hal(sel, adapter);
+#endif
+}
+
diff --git a/drivers/staging/rtl8188eu/hal/hal_com_c2h.h b/drivers/staging/rtl8188eu/hal/hal_com_c2h.h
new file mode 100644
index 000000000000..172c15258e13
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal_com_c2h.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#ifndef __COMMON_C2H_H__
+#define __COMMON_C2H_H__
+
+#define C2H_TYPE_REG 0
+#define C2H_TYPE_PKT 1
+
+/*
+* C2H event format:
+* Fields TRIGGER PAYLOAD SEQ PLEN ID
+* BITS [127:120] [119:16] [15:8] [7:4] [3:0]
+*/
+#define C2H_ID(_c2h) LE_BITS_TO_1BYTE(((u8*)(_c2h)), 0, 4)
+#define C2H_PLEN(_c2h) LE_BITS_TO_1BYTE(((u8*)(_c2h)), 4, 4)
+#define C2H_SEQ(_c2h) LE_BITS_TO_1BYTE(((u8*)(_c2h)) + 1, 0, 8)
+#define C2H_PAYLOAD(_c2h) (((u8*)(_c2h)) + 2)
+
+#define SET_C2H_ID(_c2h, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_c2h)), 0, 4, _val)
+#define SET_C2H_PLEN(_c2h, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_c2h)), 4, 4, _val)
+#define SET_C2H_SEQ(_c2h, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_c2h)) + 1 , 0, 8, _val)
+
+/*
+* C2H event format:
+* Fields TRIGGER PLEN PAYLOAD SEQ ID
+* BITS [127:120] [119:112] [111:16] [15:8] [7:0]
+*/
+#define C2H_ID_88XX(_c2h) LE_BITS_TO_1BYTE(((u8*)(_c2h)), 0, 8)
+#define C2H_SEQ_88XX(_c2h) LE_BITS_TO_1BYTE(((u8*)(_c2h)) + 1, 0, 8)
+#define C2H_PAYLOAD_88XX(_c2h) (((u8*)(_c2h)) + 2)
+#define C2H_PLEN_88XX(_c2h) LE_BITS_TO_1BYTE(((u8*)(_c2h)) + 14, 0, 8)
+#define C2H_TRIGGER_88XX(_c2h) LE_BITS_TO_1BYTE(((u8*)(_c2h)) + 15, 0, 8)
+
+#define SET_C2H_ID_88XX(_c2h, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_c2h)), 0, 8, _val)
+#define SET_C2H_SEQ_88XX(_c2h, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_c2h)) + 1, 0, 8, _val)
+#define SET_C2H_PLEN_88XX(_c2h, _val) SET_BITS_TO_LE_1BYTE(((u8*)(_c2h)) + 14, 0, 8, _val)
+
+typedef enum _C2H_EVT {
+ C2H_DBG = 0x00,
+ C2H_LB = 0x01,
+ C2H_TXBF = 0x02,
+ C2H_CCX_TX_RPT = 0x03,
+ C2H_AP_REQ_TXRPT = 0x04,
+ C2H_FW_SCAN_COMPLETE = 0x7,
+ C2H_BT_INFO = 0x09,
+ C2H_BT_MP_INFO = 0x0B,
+ C2H_RA_RPT = 0x0C,
+ C2H_SPC_STAT = 0x0D,
+ C2H_RA_PARA_RPT = 0x0E,
+ C2H_FW_CHNL_SWITCH_COMPLETE = 0x10,
+ C2H_IQK_FINISH = 0x11,
+ C2H_MAILBOX_STATUS = 0x15,
+ C2H_P2P_RPORT = 0x16,
+ C2H_MCC = 0x17,
+ C2H_MAC_HIDDEN_RPT = 0x19,
+ C2H_MAC_HIDDEN_RPT_2 = 0x1A,
+ C2H_BCN_EARLY_RPT = 0x1E,
+ C2H_DEFEATURE_DBG = 0x22,
+ C2H_CUSTOMER_STR_RPT = 0x24,
+ C2H_CUSTOMER_STR_RPT_2 = 0x25,
+ C2H_DEFEATURE_RSVD = 0xFD,
+ C2H_EXTEND = 0xff,
+} C2H_EVT;
+
+typedef enum _EXTEND_C2H_EVT {
+ EXTEND_C2H_DBG_PRINT = 0
+} EXTEND_C2H_EVT;
+
+#define C2H_REG_LEN 16
+
+/* C2H_IQK_FINISH, 0x11 */
+#define IQK_OFFLOAD_LEN 1
+void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len);
+int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms);
+#define rtl8812_iqk_wait c2h_iqk_offload_wait /* TODO: remove this after phydm call c2h_iqk_offload_wait instead */
+
+#ifdef CONFIG_RTW_MAC_HIDDEN_RPT
+/* C2H_MAC_HIDDEN_RPT, 0x19 */
+#define MAC_HIDDEN_RPT_LEN 8
+int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len);
+
+/* C2H_MAC_HIDDEN_RPT_2, 0x1A */
+#define MAC_HIDDEN_RPT_2_LEN 5
+int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len);
+int hal_read_mac_hidden_rpt(_adapter *adapter);
+#endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
+
+/* C2H_DEFEATURE_DBG, 0x22 */
+#define DEFEATURE_DBG_LEN 1
+int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len);
+
+#ifdef CONFIG_RTW_CUSTOMER_STR
+/* C2H_CUSTOMER_STR_RPT, 0x24 */
+#define CUSTOMER_STR_RPT_LEN 8
+int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len);
+
+/* C2H_CUSTOMER_STR_RPT_2, 0x25 */
+#define CUSTOMER_STR_RPT_2_LEN 8
+int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len);
+#endif /* CONFIG_RTW_CUSTOMER_STR */
+
+#endif /* __COMMON_C2H_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/hal_com_phycfg.c b/drivers/staging/rtl8188eu/hal/hal_com_phycfg.c
new file mode 100644
index 000000000000..5ad88c012c73
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal_com_phycfg.c
@@ -0,0 +1,5150 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _HAL_COM_PHYCFG_C_
+
+#include <drv_types.h>
+#include <hal_data.h>
+
+#define PG_TXPWR_MSB_DIFF_S4BIT(_pg_v) (((_pg_v) & 0xf0) >> 4)
+#define PG_TXPWR_LSB_DIFF_S4BIT(_pg_v) ((_pg_v) & 0x0f)
+#define PG_TXPWR_MSB_DIFF_TO_S8BIT(_pg_v) ((PG_TXPWR_MSB_DIFF_S4BIT(_pg_v) & BIT3) ? (PG_TXPWR_MSB_DIFF_S4BIT(_pg_v) | 0xF0) : PG_TXPWR_MSB_DIFF_S4BIT(_pg_v))
+#define PG_TXPWR_LSB_DIFF_TO_S8BIT(_pg_v) ((PG_TXPWR_LSB_DIFF_S4BIT(_pg_v) & BIT3) ? (PG_TXPWR_LSB_DIFF_S4BIT(_pg_v) | 0xF0) : PG_TXPWR_LSB_DIFF_S4BIT(_pg_v))
+#define IS_PG_TXPWR_BASE_INVALID(_base) ((_base) > 63)
+#define IS_PG_TXPWR_DIFF_INVALID(_diff) ((_diff) > 7 || (_diff) < -8)
+#define PG_TXPWR_INVALID_BASE 255
+#define PG_TXPWR_INVALID_DIFF 8
+
+#if !IS_PG_TXPWR_BASE_INVALID(PG_TXPWR_INVALID_BASE)
+#error "PG_TXPWR_BASE definition has problem"
+#endif
+
+#if !IS_PG_TXPWR_DIFF_INVALID(PG_TXPWR_INVALID_DIFF)
+#error "PG_TXPWR_DIFF definition has problem"
+#endif
+
+#define PG_TXPWR_SRC_PG_DATA 0
+#define PG_TXPWR_SRC_IC_DEF 1
+#define PG_TXPWR_SRC_DEF 2
+#define PG_TXPWR_SRC_NUM 3
+
+static const char *const _pg_txpwr_src_str[] = {
+ "PG_DATA",
+ "IC_DEF",
+ "DEF",
+ "UNKNOWN"
+};
+
+#define pg_txpwr_src_str(src) (((src) >= PG_TXPWR_SRC_NUM) ? _pg_txpwr_src_str[PG_TXPWR_SRC_NUM] : _pg_txpwr_src_str[(src)])
+
+#ifndef DBG_PG_TXPWR_READ
+#define DBG_PG_TXPWR_READ 0
+#endif
+
+void dump_pg_txpwr_info_2g(void *sel, TxPowerInfo24G *txpwr_info, u8 rfpath_num, u8 max_tx_cnt)
+{
+ int path, group, tx_idx;
+
+ RTW_PRINT_SEL(sel, "2.4G\n");
+ RTW_PRINT_SEL(sel, "CCK-1T base:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (group = 0; group < MAX_CHNL_GROUP_24G; group++)
+ _RTW_PRINT_SEL(sel, "G%02d ", group);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (group = 0; group < MAX_CHNL_GROUP_24G; group++)
+ _RTW_PRINT_SEL(sel, "%3u ", txpwr_info->IndexCCK_Base[path][group]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "CCK diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
+ _RTW_PRINT_SEL(sel, "%dT ", path + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->CCK_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "BW40-1S base:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++)
+ _RTW_PRINT_SEL(sel, "G%02d ", group);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++)
+ _RTW_PRINT_SEL(sel, "%3u ", txpwr_info->IndexBW40_Base[path][group]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "OFDM diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
+ _RTW_PRINT_SEL(sel, "%dT ", path + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->OFDM_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "BW20 diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
+ _RTW_PRINT_SEL(sel, "%dS ", path + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW20_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "BW40 diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
+ _RTW_PRINT_SEL(sel, "%dS ", path + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW40_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+}
+
+void dump_pg_txpwr_info_5g(void *sel, TxPowerInfo5G *txpwr_info, u8 rfpath_num, u8 max_tx_cnt)
+{
+ int path, group, tx_idx;
+
+ RTW_PRINT_SEL(sel, "5G\n");
+ RTW_PRINT_SEL(sel, "BW40-1S base:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (group = 0; group < MAX_CHNL_GROUP_5G; group++)
+ _RTW_PRINT_SEL(sel, "G%02d ", group);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (group = 0; group < MAX_CHNL_GROUP_5G; group++)
+ _RTW_PRINT_SEL(sel, "%3u ", txpwr_info->IndexBW40_Base[path][group]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "OFDM diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
+ _RTW_PRINT_SEL(sel, "%dT ", path + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->OFDM_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "BW20 diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
+ _RTW_PRINT_SEL(sel, "%dS ", path + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW20_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "BW40 diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
+ _RTW_PRINT_SEL(sel, "%dS ", path + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW40_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "BW80 diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
+ _RTW_PRINT_SEL(sel, "%dS ", path + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW80_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "BW160 diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++)
+ _RTW_PRINT_SEL(sel, "%dS ", path + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", txpwr_info->BW160_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+}
+
+static const struct map_t pg_txpwr_def_info =
+ MAP_ENT(0xB8, 1, 0xFF
+ , MAPSEG_ARRAY_ENT(0x10, 168,
+ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
+ 0x04, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
+ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A,
+ 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x04, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
+ 0x2A, 0x2A, 0x2A, 0x2A, 0x04, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D,
+ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x04, 0xEE,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE)
+ );
+
+static const struct map_t rtl8188e_pg_txpwr_def_info =
+ MAP_ENT(0xB8, 1, 0xFF
+ , MAPSEG_ARRAY_ENT(0x10, 12,
+ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24)
+ );
+
+const struct map_t *hal_pg_txpwr_def_info(_adapter *adapter)
+{
+ u8 interface_type = 0;
+ const struct map_t *map = NULL;
+
+ interface_type = rtw_get_intf_type(adapter);
+
+ switch (rtw_get_chip_type(adapter)) {
+ case RTL8188E:
+ map = &rtl8188e_pg_txpwr_def_info;
+ break;
+ }
+
+ if (map == NULL) {
+ RTW_ERR("%s: unknown chip_type:%u\n"
+ , __func__, rtw_get_chip_type(adapter));
+ rtw_warn_on(1);
+ }
+
+ return map;
+}
+
+static u8 hal_chk_pg_txpwr_info_2g(_adapter *adapter, TxPowerInfo24G *pwr_info)
+{
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ u8 path, group, tx_idx;
+
+ if (pwr_info == NULL || !hal_chk_band_cap(adapter, BAND_CAP_2G))
+ return _SUCCESS;
+
+ for (path = 0; path < MAX_RF_PATH; path++) {
+ if (!HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path))
+ continue;
+ for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
+ if (IS_PG_TXPWR_BASE_INVALID(pwr_info->IndexCCK_Base[path][group])
+ || IS_PG_TXPWR_BASE_INVALID(pwr_info->IndexBW40_Base[path][group]))
+ return _FAIL;
+ }
+ for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
+ if (!HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx))
+ continue;
+ if (IS_PG_TXPWR_DIFF_INVALID(pwr_info->CCK_Diff[path][tx_idx])
+ || IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
+ || IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
+ || IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW40_Diff[path][tx_idx]))
+ return _FAIL;
+ }
+ }
+
+ return _SUCCESS;
+}
+
+static u8 hal_chk_pg_txpwr_info_5g(_adapter *adapter, TxPowerInfo5G *pwr_info)
+{
+#ifdef CONFIG_IEEE80211_BAND_5GHZ
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ u8 path, group, tx_idx;
+
+ if (pwr_info == NULL || !hal_chk_band_cap(adapter, BAND_CAP_5G))
+ return _SUCCESS;
+
+ for (path = 0; path < MAX_RF_PATH; path++) {
+ if (!HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path))
+ continue;
+ for (group = 0; group < MAX_CHNL_GROUP_5G; group++)
+ if (IS_PG_TXPWR_BASE_INVALID(pwr_info->IndexBW40_Base[path][group]))
+ return _FAIL;
+ for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
+ if (!HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx))
+ continue;
+ if (IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
+ || IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
+ || IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW40_Diff[path][tx_idx])
+ || IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW80_Diff[path][tx_idx])
+ || IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW160_Diff[path][tx_idx]))
+ return _FAIL;
+ }
+ }
+#endif /* CONFIG_IEEE80211_BAND_5GHZ */
+ return _SUCCESS;
+}
+
+static inline void hal_init_pg_txpwr_info_2g(_adapter *adapter, TxPowerInfo24G *pwr_info)
+{
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ u8 path, group, tx_idx;
+
+ if (pwr_info == NULL)
+ return;
+
+ memset(pwr_info, 0, sizeof(TxPowerInfo24G));
+
+ /* init with invalid value */
+ for (path = 0; path < MAX_RF_PATH; path++) {
+ for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
+ pwr_info->IndexCCK_Base[path][group] = PG_TXPWR_INVALID_BASE;
+ pwr_info->IndexBW40_Base[path][group] = PG_TXPWR_INVALID_BASE;
+ }
+ for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
+ pwr_info->CCK_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
+ pwr_info->OFDM_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
+ pwr_info->BW20_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
+ pwr_info->BW40_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
+ }
+ }
+
+ /* init for dummy base and diff */
+ for (path = 0; path < MAX_RF_PATH; path++) {
+ if (!HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path))
+ break;
+ /* 2.4G BW40 base has 1 less group than CCK base*/
+ pwr_info->IndexBW40_Base[path][MAX_CHNL_GROUP_24G - 1] = 0;
+
+ /* dummy diff */
+ pwr_info->CCK_Diff[path][0] = 0; /* 2.4G CCK-1TX */
+ pwr_info->BW40_Diff[path][0] = 0; /* 2.4G BW40-1S */
+ }
+}
+
+static inline void hal_init_pg_txpwr_info_5g(_adapter *adapter, TxPowerInfo5G *pwr_info)
+{
+#ifdef CONFIG_IEEE80211_BAND_5GHZ
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ u8 path, group, tx_idx;
+
+ if (pwr_info == NULL)
+ return;
+
+ memset(pwr_info, 0, sizeof(TxPowerInfo5G));
+
+ /* init with invalid value */
+ for (path = 0; path < MAX_RF_PATH; path++) {
+ for (group = 0; group < MAX_CHNL_GROUP_5G; group++)
+ pwr_info->IndexBW40_Base[path][group] = PG_TXPWR_INVALID_BASE;
+ for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
+ pwr_info->OFDM_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
+ pwr_info->BW20_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
+ pwr_info->BW40_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
+ pwr_info->BW80_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
+ pwr_info->BW160_Diff[path][tx_idx] = PG_TXPWR_INVALID_DIFF;
+ }
+ }
+
+ for (path = 0; path < MAX_RF_PATH; path++) {
+ if (!HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path))
+ break;
+ /* dummy diff */
+ pwr_info->BW40_Diff[path][0] = 0; /* 5G BW40-1S */
+ }
+#endif /* CONFIG_IEEE80211_BAND_5GHZ */
+}
+
+#if DBG_PG_TXPWR_READ
+#define LOAD_PG_TXPWR_WARN_COND(_txpwr_src) 1
+#else
+#define LOAD_PG_TXPWR_WARN_COND(_txpwr_src) (_txpwr_src > PG_TXPWR_SRC_PG_DATA)
+#endif
+
+static u16 hal_load_pg_txpwr_info_path_2g(
+ _adapter *adapter,
+ TxPowerInfo24G *pwr_info,
+ u32 path,
+ u8 txpwr_src,
+ const struct map_t *txpwr_map,
+ u16 pg_offset)
+{
+#define PG_TXPWR_1PATH_BYTE_NUM_2G 18
+
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ u16 offset = pg_offset;
+ u8 group, tx_idx;
+ u8 val;
+ u8 tmp_base;
+ s8 tmp_diff;
+
+ if (pwr_info == NULL || !hal_chk_band_cap(adapter, BAND_CAP_2G)) {
+ offset += PG_TXPWR_1PATH_BYTE_NUM_2G;
+ goto exit;
+ }
+
+ if (DBG_PG_TXPWR_READ)
+ RTW_INFO("%s [%c] offset:0x%03x\n", __func__, rf_path_char(path), offset);
+
+ for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
+ if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path)) {
+ tmp_base = map_read8(txpwr_map, offset);
+ if (!IS_PG_TXPWR_BASE_INVALID(tmp_base)
+ && IS_PG_TXPWR_BASE_INVALID(pwr_info->IndexCCK_Base[path][group])
+ ) {
+ pwr_info->IndexCCK_Base[path][group] = tmp_base;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 2G G%02d CCK-1T base:%u from %s\n", rf_path_char(path), group, tmp_base, pg_txpwr_src_str(txpwr_src));
+ }
+ }
+ offset++;
+ }
+
+ for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
+ if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path)) {
+ tmp_base = map_read8(txpwr_map, offset);
+ if (!IS_PG_TXPWR_BASE_INVALID(tmp_base)
+ && IS_PG_TXPWR_BASE_INVALID(pwr_info->IndexBW40_Base[path][group])
+ ) {
+ pwr_info->IndexBW40_Base[path][group] = tmp_base;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 2G G%02d BW40-1S base:%u from %s\n", rf_path_char(path), group, tmp_base, pg_txpwr_src_str(txpwr_src));
+ }
+ }
+ offset++;
+ }
+
+ for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
+ if (tx_idx == 0) {
+ if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx)) {
+ val = map_read8(txpwr_map, offset);
+ tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
+ ) {
+ pwr_info->BW20_Diff[path][tx_idx] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 2G BW20-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
+ }
+ tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
+ ) {
+ pwr_info->OFDM_Diff[path][tx_idx] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 2G OFDM-%dT diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
+ }
+ }
+ offset++;
+ } else {
+ if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx)) {
+ val = map_read8(txpwr_map, offset);
+ tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW40_Diff[path][tx_idx])
+ ) {
+ pwr_info->BW40_Diff[path][tx_idx] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 2G BW40-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
+
+ }
+ tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
+ ) {
+ pwr_info->BW20_Diff[path][tx_idx] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 2G BW20-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
+ }
+ }
+ offset++;
+
+ if (HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx)) {
+ val = map_read8(txpwr_map, offset);
+ tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
+ ) {
+ pwr_info->OFDM_Diff[path][tx_idx] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 2G OFDM-%dT diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
+ }
+ tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->CCK_Diff[path][tx_idx])
+ ) {
+ pwr_info->CCK_Diff[path][tx_idx] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 2G CCK-%dT diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
+ }
+ }
+ offset++;
+ }
+ }
+
+ if (offset != pg_offset + PG_TXPWR_1PATH_BYTE_NUM_2G) {
+ RTW_ERR("%s parse %d bytes != %d\n", __func__, offset - pg_offset, PG_TXPWR_1PATH_BYTE_NUM_2G);
+ rtw_warn_on(1);
+ }
+
+exit:
+ return offset;
+}
+
+static u16 hal_load_pg_txpwr_info_path_5g(
+ _adapter *adapter,
+ TxPowerInfo5G *pwr_info,
+ u32 path,
+ u8 txpwr_src,
+ const struct map_t *txpwr_map,
+ u16 pg_offset)
+{
+#define PG_TXPWR_1PATH_BYTE_NUM_5G 24
+
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ u16 offset = pg_offset;
+ u8 group, tx_idx;
+ u8 val;
+ u8 tmp_base;
+ s8 tmp_diff;
+
+#ifdef CONFIG_IEEE80211_BAND_5GHZ
+ if (pwr_info == NULL || !hal_chk_band_cap(adapter, BAND_CAP_5G))
+#endif
+ {
+ offset += PG_TXPWR_1PATH_BYTE_NUM_5G;
+ goto exit;
+ }
+
+#ifdef CONFIG_IEEE80211_BAND_5GHZ
+ if (DBG_PG_TXPWR_READ)
+ RTW_INFO("%s[%c] eaddr:0x%03x\n", __func__, rf_path_char(path), offset);
+
+ for (group = 0; group < MAX_CHNL_GROUP_5G; group++) {
+ if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path)) {
+ tmp_base = map_read8(txpwr_map, offset);
+ if (!IS_PG_TXPWR_BASE_INVALID(tmp_base)
+ && IS_PG_TXPWR_BASE_INVALID(pwr_info->IndexBW40_Base[path][group])
+ ) {
+ pwr_info->IndexBW40_Base[path][group] = tmp_base;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 5G G%02d BW40-1S base:%u from %s\n", rf_path_char(path), group, tmp_base, pg_txpwr_src_str(txpwr_src));
+ }
+ }
+ offset++;
+ }
+
+ for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
+ if (tx_idx == 0) {
+ if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx)) {
+ val = map_read8(txpwr_map, offset);
+ tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
+ ) {
+ pwr_info->BW20_Diff[path][tx_idx] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 5G BW20-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
+ }
+ tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][tx_idx])
+ ) {
+ pwr_info->OFDM_Diff[path][tx_idx] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 5G OFDM-%dT diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
+ }
+ }
+ offset++;
+ } else {
+ if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx)) {
+ val = map_read8(txpwr_map, offset);
+ tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW40_Diff[path][tx_idx])
+ ) {
+ pwr_info->BW40_Diff[path][tx_idx] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 5G BW40-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
+ }
+ tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW20_Diff[path][tx_idx])
+ ) {
+ pwr_info->BW20_Diff[path][tx_idx] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 5G BW20-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
+ }
+ }
+ offset++;
+ }
+ }
+
+ /* OFDM diff 2T ~ 3T */
+ if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, 1)) {
+ val = map_read8(txpwr_map, offset);
+ tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][1])
+ ) {
+ pwr_info->OFDM_Diff[path][1] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 5G OFDM-%dT diff:%d from %s\n", rf_path_char(path), 2, tmp_diff, pg_txpwr_src_str(txpwr_src));
+ }
+ if (HAL_SPEC_CHK_TX_CNT(hal_spec, 2)) {
+ tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][2])
+ ) {
+ pwr_info->OFDM_Diff[path][2] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 5G OFDM-%dT diff:%d from %s\n", rf_path_char(path), 3, tmp_diff, pg_txpwr_src_str(txpwr_src));
+ }
+ }
+ }
+ offset++;
+
+ /* OFDM diff 4T */
+ if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, 3)) {
+ val = map_read8(txpwr_map, offset);
+ tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->OFDM_Diff[path][3])
+ ) {
+ pwr_info->OFDM_Diff[path][3] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 5G OFDM-%dT diff:%d from %s\n", rf_path_char(path), 4, tmp_diff, pg_txpwr_src_str(txpwr_src));
+ }
+ }
+ offset++;
+
+ for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
+ if (HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path) && HAL_SPEC_CHK_TX_CNT(hal_spec, tx_idx)) {
+ val = map_read8(txpwr_map, offset);
+ tmp_diff = PG_TXPWR_MSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW80_Diff[path][tx_idx])
+ ) {
+ pwr_info->BW80_Diff[path][tx_idx] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 5G BW80-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
+ }
+ tmp_diff = PG_TXPWR_LSB_DIFF_TO_S8BIT(val);
+ if (!IS_PG_TXPWR_DIFF_INVALID(tmp_diff)
+ && IS_PG_TXPWR_DIFF_INVALID(pwr_info->BW160_Diff[path][tx_idx])
+ ) {
+ pwr_info->BW160_Diff[path][tx_idx] = tmp_diff;
+ if (LOAD_PG_TXPWR_WARN_COND(txpwr_src))
+ RTW_INFO("[%c] 5G BW160-%dS diff:%d from %s\n", rf_path_char(path), tx_idx + 1, tmp_diff, pg_txpwr_src_str(txpwr_src));
+ }
+ }
+ offset++;
+ }
+
+ if (offset != pg_offset + PG_TXPWR_1PATH_BYTE_NUM_5G) {
+ RTW_ERR("%s parse %d bytes != %d\n", __func__, offset - pg_offset, PG_TXPWR_1PATH_BYTE_NUM_5G);
+ rtw_warn_on(1);
+ }
+
+#endif /* #ifdef CONFIG_IEEE80211_BAND_5GHZ */
+
+exit:
+ return offset;
+}
+
+static void hal_load_pg_txpwr_info(
+ _adapter *adapter,
+ TxPowerInfo24G *pwr_info_2g,
+ TxPowerInfo5G *pwr_info_5g,
+ u8 *pg_data,
+ bool AutoLoadFail
+)
+{
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ u8 path;
+ u16 pg_offset;
+ u8 txpwr_src = PG_TXPWR_SRC_PG_DATA;
+ struct map_t pg_data_map = MAP_ENT(184, 1, 0xFF, MAPSEG_PTR_ENT(0x00, 184, pg_data));
+ const struct map_t *txpwr_map = NULL;
+
+ /* init with invalid value and some dummy base and diff */
+ hal_init_pg_txpwr_info_2g(adapter, pwr_info_2g);
+ hal_init_pg_txpwr_info_5g(adapter, pwr_info_5g);
+
+select_src:
+ pg_offset = 0x10;
+
+ switch (txpwr_src) {
+ case PG_TXPWR_SRC_PG_DATA:
+ txpwr_map = &pg_data_map;
+ break;
+ case PG_TXPWR_SRC_IC_DEF:
+ txpwr_map = hal_pg_txpwr_def_info(adapter);
+ break;
+ case PG_TXPWR_SRC_DEF:
+ default:
+ txpwr_map = &pg_txpwr_def_info;
+ break;
+ };
+
+ if (txpwr_map == NULL)
+ goto end_parse;
+
+ for (path = 0; path < MAX_RF_PATH ; path++) {
+ if (!HAL_SPEC_CHK_RF_PATH_2G(hal_spec, path) && !HAL_SPEC_CHK_RF_PATH_5G(hal_spec, path))
+ break;
+ pg_offset = hal_load_pg_txpwr_info_path_2g(adapter, pwr_info_2g, path, txpwr_src, txpwr_map, pg_offset);
+ pg_offset = hal_load_pg_txpwr_info_path_5g(adapter, pwr_info_5g, path, txpwr_src, txpwr_map, pg_offset);
+ }
+
+ if (hal_chk_pg_txpwr_info_2g(adapter, pwr_info_2g) == _SUCCESS
+ && hal_chk_pg_txpwr_info_5g(adapter, pwr_info_5g) == _SUCCESS)
+ goto exit;
+
+end_parse:
+ txpwr_src++;
+ if (txpwr_src < PG_TXPWR_SRC_NUM)
+ goto select_src;
+
+ if (hal_chk_pg_txpwr_info_2g(adapter, pwr_info_2g) != _SUCCESS
+ || hal_chk_pg_txpwr_info_5g(adapter, pwr_info_5g) != _SUCCESS)
+ rtw_warn_on(1);
+
+exit:
+ if (DBG_PG_TXPWR_READ) {
+ if (pwr_info_2g)
+ dump_pg_txpwr_info_2g(RTW_DBGDUMP, pwr_info_2g, 4, 4);
+ if (pwr_info_5g)
+ dump_pg_txpwr_info_5g(RTW_DBGDUMP, pwr_info_5g, 4, 4);
+ }
+
+ return;
+}
+
+void hal_load_txpwr_info(
+ _adapter *adapter,
+ TxPowerInfo24G *pwr_info_2g,
+ TxPowerInfo5G *pwr_info_5g,
+ u8 *pg_data
+)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ u8 max_tx_cnt = hal_spec->max_tx_cnt;
+ u8 rfpath, ch_idx, group, tx_idx;
+
+ /* load from pg data (or default value) */
+ hal_load_pg_txpwr_info(adapter, pwr_info_2g, pwr_info_5g, pg_data, false);
+
+ /* transform to hal_data */
+ for (rfpath = 0; rfpath < MAX_RF_PATH; rfpath++) {
+
+ if (!pwr_info_2g || !HAL_SPEC_CHK_RF_PATH_2G(hal_spec, rfpath))
+ goto bypass_2g;
+
+ /* 2.4G base */
+ for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++) {
+ u8 cck_group;
+
+ if (rtw_get_ch_group(ch_idx + 1, &group, &cck_group) != BAND_ON_2_4G)
+ continue;
+
+ hal_data->Index24G_CCK_Base[rfpath][ch_idx] = pwr_info_2g->IndexCCK_Base[rfpath][cck_group];
+ hal_data->Index24G_BW40_Base[rfpath][ch_idx] = pwr_info_2g->IndexBW40_Base[rfpath][group];
+ }
+
+ /* 2.4G diff */
+ for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
+ if (tx_idx >= max_tx_cnt)
+ break;
+
+ hal_data->CCK_24G_Diff[rfpath][tx_idx] = pwr_info_2g->CCK_Diff[rfpath][tx_idx];
+ hal_data->OFDM_24G_Diff[rfpath][tx_idx] = pwr_info_2g->OFDM_Diff[rfpath][tx_idx];
+ hal_data->BW20_24G_Diff[rfpath][tx_idx] = pwr_info_2g->BW20_Diff[rfpath][tx_idx];
+ hal_data->BW40_24G_Diff[rfpath][tx_idx] = pwr_info_2g->BW40_Diff[rfpath][tx_idx];
+ }
+bypass_2g:
+ ;
+
+#ifdef CONFIG_IEEE80211_BAND_5GHZ
+ if (!pwr_info_5g || !HAL_SPEC_CHK_RF_PATH_5G(hal_spec, rfpath))
+ goto bypass_5g;
+
+ /* 5G base */
+ for (ch_idx = 0; ch_idx < CENTER_CH_5G_ALL_NUM; ch_idx++) {
+ if (rtw_get_ch_group(center_ch_5g_all[ch_idx], &group, NULL) != BAND_ON_5G)
+ continue;
+ hal_data->Index5G_BW40_Base[rfpath][ch_idx] = pwr_info_5g->IndexBW40_Base[rfpath][group];
+ }
+
+ for (ch_idx = 0 ; ch_idx < CENTER_CH_5G_80M_NUM; ch_idx++) {
+ u8 upper, lower;
+
+ if (rtw_get_ch_group(center_ch_5g_80m[ch_idx], &group, NULL) != BAND_ON_5G)
+ continue;
+
+ upper = pwr_info_5g->IndexBW40_Base[rfpath][group];
+ lower = pwr_info_5g->IndexBW40_Base[rfpath][group + 1];
+ hal_data->Index5G_BW80_Base[rfpath][ch_idx] = (upper + lower) / 2;
+ }
+
+ /* 5G diff */
+ for (tx_idx = 0; tx_idx < MAX_TX_COUNT; tx_idx++) {
+ if (tx_idx >= max_tx_cnt)
+ break;
+
+ hal_data->OFDM_5G_Diff[rfpath][tx_idx] = pwr_info_5g->OFDM_Diff[rfpath][tx_idx];
+ hal_data->BW20_5G_Diff[rfpath][tx_idx] = pwr_info_5g->BW20_Diff[rfpath][tx_idx];
+ hal_data->BW40_5G_Diff[rfpath][tx_idx] = pwr_info_5g->BW40_Diff[rfpath][tx_idx];
+ hal_data->BW80_5G_Diff[rfpath][tx_idx] = pwr_info_5g->BW80_Diff[rfpath][tx_idx];
+ }
+bypass_5g:
+ ;
+#endif /* CONFIG_IEEE80211_BAND_5GHZ */
+ }
+}
+
+void dump_hal_txpwr_info_2g(void *sel, _adapter *adapter, u8 rfpath_num, u8 max_tx_cnt)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ int path, ch_idx, tx_idx;
+
+ RTW_PRINT_SEL(sel, "2.4G\n");
+ RTW_PRINT_SEL(sel, "CCK-1T base:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", center_ch_2g[ch_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++)
+ _RTW_PRINT_SEL(sel, "%2u ", hal_data->Index24G_CCK_Base[path][ch_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "CCK diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%dT ", tx_idx + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", hal_data->CCK_24G_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "BW40-1S base:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", center_ch_2g[ch_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (ch_idx = 0; ch_idx < CENTER_CH_2G_NUM; ch_idx++)
+ _RTW_PRINT_SEL(sel, "%2u ", hal_data->Index24G_BW40_Base[path][ch_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "OFDM diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%dT ", tx_idx + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", hal_data->OFDM_24G_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "BW20 diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", hal_data->BW20_24G_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "BW40 diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", hal_data->BW40_24G_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+}
+
+void dump_hal_txpwr_info_5g(void *sel, _adapter *adapter, u8 rfpath_num, u8 max_tx_cnt)
+{
+#ifdef CONFIG_IEEE80211_BAND_5GHZ
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ int path, ch_idx, tx_idx;
+ u8 dump_section = 0;
+ u8 ch_idx_s = 0;
+
+ RTW_PRINT_SEL(sel, "5G\n");
+ RTW_PRINT_SEL(sel, "BW40-1S base:\n");
+ do {
+ #define DUMP_5G_BW40_BASE_SECTION_NUM 3
+ u8 end[DUMP_5G_BW40_BASE_SECTION_NUM] = {64, 144, 177};
+
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (ch_idx = ch_idx_s; ch_idx < CENTER_CH_5G_ALL_NUM; ch_idx++) {
+ _RTW_PRINT_SEL(sel, "%3d ", center_ch_5g_all[ch_idx]);
+ if (end[dump_section] == center_ch_5g_all[ch_idx])
+ break;
+ }
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (ch_idx = ch_idx_s; ch_idx < CENTER_CH_5G_ALL_NUM; ch_idx++) {
+ _RTW_PRINT_SEL(sel, "%3u ", hal_data->Index5G_BW40_Base[path][ch_idx]);
+ if (end[dump_section] == center_ch_5g_all[ch_idx])
+ break;
+ }
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ ch_idx_s = ch_idx + 1;
+ dump_section++;
+ if (dump_section >= DUMP_5G_BW40_BASE_SECTION_NUM)
+ break;
+ } while (1);
+
+ RTW_PRINT_SEL(sel, "BW80-1S base:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (ch_idx = 0; ch_idx < CENTER_CH_5G_80M_NUM; ch_idx++)
+ _RTW_PRINT_SEL(sel, "%3d ", center_ch_5g_80m[ch_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (ch_idx = 0; ch_idx < CENTER_CH_5G_80M_NUM; ch_idx++)
+ _RTW_PRINT_SEL(sel, "%3u ", hal_data->Index5G_BW80_Base[path][ch_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "OFDM diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%dT ", tx_idx + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", hal_data->OFDM_5G_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "BW20 diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", hal_data->BW20_5G_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "BW40 diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", hal_data->BW40_5G_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ RTW_PRINT_SEL(sel, "BW80 diff:\n");
+ RTW_PRINT_SEL(sel, "%4s ", "");
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%dS ", tx_idx + 1);
+ _RTW_PRINT_SEL(sel, "\n");
+ for (path = 0; path < MAX_RF_PATH && path < rfpath_num; path++) {
+ RTW_PRINT_SEL(sel, "[%c]: ", rf_path_char(path));
+ for (tx_idx = RF_1TX; tx_idx < MAX_TX_COUNT && tx_idx < max_tx_cnt; tx_idx++)
+ _RTW_PRINT_SEL(sel, "%2d ", hal_data->BW80_5G_Diff[path][tx_idx]);
+ _RTW_PRINT_SEL(sel, "\n");
+ }
+ RTW_PRINT_SEL(sel, "\n");
+#endif /* CONFIG_IEEE80211_BAND_5GHZ */
+}
+
+/*
+* rtw_regsty_get_target_tx_power -
+*
+* Return dBm or -1 for undefined
+*/
+static s8 rtw_regsty_get_target_tx_power(
+ PADAPTER Adapter,
+ u8 Band,
+ u8 RfPath,
+ RATE_SECTION RateSection
+)
+{
+ struct registry_priv *regsty = adapter_to_regsty(Adapter);
+ s8 value = 0;
+
+ if (RfPath > RF_PATH_D) {
+ RTW_PRINT("%s invalid RfPath:%d\n", __func__, RfPath);
+ return -1;
+ }
+
+ if (Band != BAND_ON_2_4G
+ #ifdef CONFIG_IEEE80211_BAND_5GHZ
+ && Band != BAND_ON_5G
+ #endif
+ ) {
+ RTW_PRINT("%s invalid Band:%d\n", __func__, Band);
+ return -1;
+ }
+
+ if (RateSection >= RATE_SECTION_NUM
+ #ifdef CONFIG_IEEE80211_BAND_5GHZ
+ || (Band == BAND_ON_5G && RateSection == CCK)
+ #endif
+ ) {
+ RTW_PRINT("%s invalid RateSection:%d in Band:%d, RfPath:%d\n", __func__
+ , RateSection, Band, RfPath);
+ return -1;
+ }
+
+ if (Band == BAND_ON_2_4G)
+ value = regsty->target_tx_pwr_2g[RfPath][RateSection];
+#ifdef CONFIG_IEEE80211_BAND_5GHZ
+ else /* BAND_ON_5G */
+ value = regsty->target_tx_pwr_5g[RfPath][RateSection - 1];
+#endif
+
+ return value;
+}
+
+static bool rtw_regsty_chk_target_tx_power_valid(_adapter *adapter)
+{
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ int path, tx_num, band, rs;
+ s8 target;
+
+ for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
+ if (!hal_is_band_support(adapter, band))
+ continue;
+
+ for (path = 0; path < RF_PATH_MAX; path++) {
+ if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
+ break;
+
+ for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
+ tx_num = rate_section_to_tx_num(rs);
+ if (tx_num >= hal_spec->tx_nss_num)
+ continue;
+
+ if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
+ continue;
+
+ if (IS_VHT_RATE_SECTION(rs))
+ continue;
+
+ target = rtw_regsty_get_target_tx_power(adapter, band, path, rs);
+ if (target == -1) {
+ RTW_PRINT("%s return false for band:%d, path:%d, rs:%d, t:%d\n", __func__, band, path, rs, target);
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+/*
+* PHY_GetTxPowerByRateBase -
+*
+* Return 2 times of dBm
+*/
+u8
+PHY_GetTxPowerByRateBase(
+ PADAPTER Adapter,
+ u8 Band,
+ u8 RfPath,
+ u8 TxNum,
+ RATE_SECTION RateSection
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 value = 0;
+
+ if (RfPath > RF_PATH_D) {
+ RTW_PRINT("%s invalid RfPath:%d\n", __func__, RfPath);
+ return 0;
+ }
+
+ if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
+ RTW_PRINT("%s invalid Band:%d\n", __func__, Band);
+ return 0;
+ }
+
+ if (RateSection >= RATE_SECTION_NUM
+ || (Band == BAND_ON_5G && RateSection == CCK)
+ ) {
+ RTW_PRINT("%s invalid RateSection:%d in Band:%d, RfPath:%d, TxNum:%d\n", __func__
+ , RateSection, Band, RfPath, TxNum);
+ return 0;
+ }
+
+ if (Band == BAND_ON_2_4G)
+ value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][RateSection];
+ else /* BAND_ON_5G */
+ value = pHalData->TxPwrByRateBase5G[RfPath][TxNum][RateSection - 1];
+
+ return value;
+}
+
+static void
+phy_SetTxPowerByRateBase(
+ PADAPTER Adapter,
+ u8 Band,
+ u8 RfPath,
+ RATE_SECTION RateSection,
+ u8 TxNum,
+ u8 Value
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ if (RfPath > RF_PATH_D) {
+ RTW_PRINT("%s invalid RfPath:%d\n", __func__, RfPath);
+ return;
+ }
+
+ if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
+ RTW_PRINT("%s invalid Band:%d\n", __func__, Band);
+ return;
+ }
+
+ if (RateSection >= RATE_SECTION_NUM
+ || (Band == BAND_ON_5G && RateSection == CCK)
+ ) {
+ RTW_PRINT("%s invalid RateSection:%d in %sG, RfPath:%d, TxNum:%d\n", __func__
+ , RateSection, (Band == BAND_ON_2_4G) ? "2.4" : "5", RfPath, TxNum);
+ return;
+ }
+
+ if (Band == BAND_ON_2_4G)
+ pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][RateSection] = Value;
+ else /* BAND_ON_5G */
+ pHalData->TxPwrByRateBase5G[RfPath][TxNum][RateSection - 1] = Value;
+}
+
+static inline bool phy_is_txpwr_by_rate_undefined_of_band_path(_adapter *adapter, u8 band, u8 path)
+{
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ u8 tx_num = 0, rate_idx = 0;
+
+ for (tx_num = 0; tx_num < TX_PWR_BY_RATE_NUM_RF; tx_num++) {
+ if (tx_num >= hal_spec->max_tx_cnt || tx_num >= hal_spec->tx_nss_num)
+ goto exit;
+ for (rate_idx = 0; rate_idx < TX_PWR_BY_RATE_NUM_RATE; rate_idx++) {
+ if (hal_data->TxPwrByRateOffset[band][path][tx_num][rate_idx] != 0)
+ goto exit;
+ }
+ }
+
+exit:
+ return (tx_num >= hal_spec->max_tx_cnt || tx_num >= hal_spec->tx_nss_num) ? true : false;
+}
+
+static inline void phy_txpwr_by_rate_duplicate_band_path(_adapter *adapter, u8 band, u8 s_path, u8 t_path)
+{
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ u8 tx_num = 0, rate_idx = 0;
+
+ for (tx_num = 0; tx_num < TX_PWR_BY_RATE_NUM_RF; tx_num++)
+ for (rate_idx = 0; rate_idx < TX_PWR_BY_RATE_NUM_RATE; rate_idx++)
+ hal_data->TxPwrByRateOffset[band][t_path][tx_num][rate_idx] = hal_data->TxPwrByRateOffset[band][s_path][tx_num][rate_idx];
+}
+
+static void phy_txpwr_by_rate_chk_for_path_dup(_adapter *adapter)
+{
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ u8 band, path;
+ s8 src_path;
+
+ for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++)
+ for (path = RF_PATH_A; path < RF_PATH_MAX; path++)
+ hal_data->txpwr_by_rate_undefined_band_path[band][path] = 0;
+
+ for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
+ if (!hal_is_band_support(adapter, band))
+ continue;
+
+ for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
+ if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
+ continue;
+
+ if (phy_is_txpwr_by_rate_undefined_of_band_path(adapter, band, path))
+ hal_data->txpwr_by_rate_undefined_band_path[band][path] = 1;
+ }
+ }
+
+ for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
+ if (!hal_is_band_support(adapter, band))
+ continue;
+
+ src_path = -1;
+ for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
+ if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
+ continue;
+
+ /* find src */
+ if (src_path == -1 && hal_data->txpwr_by_rate_undefined_band_path[band][path] == 0)
+ src_path = path;
+ }
+
+ if (src_path == -1) {
+ RTW_ERR("%s all power by rate undefined\n", __func__);
+ continue;
+ }
+
+ for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
+ if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
+ continue;
+
+ /* duplicate src to undefined one */
+ if (hal_data->txpwr_by_rate_undefined_band_path[band][path] == 1) {
+ RTW_INFO("%s duplicate %s [%c] to [%c]\n", __func__
+ , band_str(band), rf_path_char(src_path), rf_path_char(path));
+ phy_txpwr_by_rate_duplicate_band_path(adapter, band, src_path, path);
+ }
+ }
+ }
+}
+
+static void
+phy_StoreTxPowerByRateBase(
+ PADAPTER pAdapter
+)
+{
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(pAdapter);
+ struct registry_priv *regsty = adapter_to_regsty(pAdapter);
+
+ u8 rate_sec_base[RATE_SECTION_NUM] = {
+ MGN_11M,
+ MGN_54M,
+ MGN_MCS7,
+ MGN_MCS15,
+ MGN_MCS23,
+ MGN_MCS31,
+ MGN_VHT1SS_MCS7,
+ MGN_VHT2SS_MCS7,
+ MGN_VHT3SS_MCS7,
+ MGN_VHT4SS_MCS7,
+ };
+
+ u8 band, path, rs, tx_num, base, index;
+
+ for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
+ if (!hal_is_band_support(pAdapter, band))
+ continue;
+
+ for (path = RF_PATH_A; path < RF_PATH_MAX; path++) {
+ if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
+ break;
+
+ for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
+ tx_num = rate_section_to_tx_num(rs);
+ if (tx_num >= hal_spec->tx_nss_num)
+ continue;
+
+ if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
+ continue;
+
+ if (IS_VHT_RATE_SECTION(rs))
+ continue;
+
+ if (regsty->target_tx_pwr_valid == true)
+ base = 2 * rtw_regsty_get_target_tx_power(pAdapter, band, path, rs);
+ else
+ base = _PHY_GetTxPowerByRate(pAdapter, band, path, tx_num, rate_sec_base[rs]);
+ phy_SetTxPowerByRateBase(pAdapter, band, path, rs, tx_num, base);
+ }
+ }
+ }
+}
+
+void
+PHY_GetRateValuesOfTxPowerByRate(
+ PADAPTER pAdapter,
+ u32 RegAddr,
+ u32 BitMask,
+ u32 Value,
+ u8 *Rate,
+ s8 *PwrByRateVal,
+ u8 *RateNum
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
+ u8 index = 0, i = 0;
+
+ switch (RegAddr) {
+ case rTxAGC_A_Rate18_06:
+ case rTxAGC_B_Rate18_06:
+ Rate[0] = MGN_6M;
+ Rate[1] = MGN_9M;
+ Rate[2] = MGN_12M;
+ Rate[3] = MGN_18M;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case rTxAGC_A_Rate54_24:
+ case rTxAGC_B_Rate54_24:
+ Rate[0] = MGN_24M;
+ Rate[1] = MGN_36M;
+ Rate[2] = MGN_48M;
+ Rate[3] = MGN_54M;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case rTxAGC_A_CCK1_Mcs32:
+ Rate[0] = MGN_1M;
+ PwrByRateVal[0] = (s8)((((Value >> (8 + 4)) & 0xF)) * 10 +
+ ((Value >> 8) & 0xF));
+ *RateNum = 1;
+ break;
+
+ case rTxAGC_B_CCK11_A_CCK2_11:
+ if (BitMask == 0xffffff00) {
+ Rate[0] = MGN_2M;
+ Rate[1] = MGN_5_5M;
+ Rate[2] = MGN_11M;
+ for (i = 1; i < 4; ++i) {
+ PwrByRateVal[i - 1] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 3;
+ } else if (BitMask == 0x000000ff) {
+ Rate[0] = MGN_11M;
+ PwrByRateVal[0] = (s8)((((Value >> 4) & 0xF)) * 10 +
+ (Value & 0xF));
+ *RateNum = 1;
+ }
+ break;
+
+ case rTxAGC_A_Mcs03_Mcs00:
+ case rTxAGC_B_Mcs03_Mcs00:
+ Rate[0] = MGN_MCS0;
+ Rate[1] = MGN_MCS1;
+ Rate[2] = MGN_MCS2;
+ Rate[3] = MGN_MCS3;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case rTxAGC_A_Mcs07_Mcs04:
+ case rTxAGC_B_Mcs07_Mcs04:
+ Rate[0] = MGN_MCS4;
+ Rate[1] = MGN_MCS5;
+ Rate[2] = MGN_MCS6;
+ Rate[3] = MGN_MCS7;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case rTxAGC_A_Mcs11_Mcs08:
+ case rTxAGC_B_Mcs11_Mcs08:
+ Rate[0] = MGN_MCS8;
+ Rate[1] = MGN_MCS9;
+ Rate[2] = MGN_MCS10;
+ Rate[3] = MGN_MCS11;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case rTxAGC_A_Mcs15_Mcs12:
+ case rTxAGC_B_Mcs15_Mcs12:
+ Rate[0] = MGN_MCS12;
+ Rate[1] = MGN_MCS13;
+ Rate[2] = MGN_MCS14;
+ Rate[3] = MGN_MCS15;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+
+ break;
+
+ case rTxAGC_B_CCK1_55_Mcs32:
+ Rate[0] = MGN_1M;
+ Rate[1] = MGN_2M;
+ Rate[2] = MGN_5_5M;
+ for (i = 1; i < 4; ++i) {
+ PwrByRateVal[i - 1] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 3;
+ break;
+
+ case 0xC20:
+ case 0xE20:
+ case 0x1820:
+ case 0x1a20:
+ Rate[0] = MGN_1M;
+ Rate[1] = MGN_2M;
+ Rate[2] = MGN_5_5M;
+ Rate[3] = MGN_11M;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xC24:
+ case 0xE24:
+ case 0x1824:
+ case 0x1a24:
+ Rate[0] = MGN_6M;
+ Rate[1] = MGN_9M;
+ Rate[2] = MGN_12M;
+ Rate[3] = MGN_18M;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xC28:
+ case 0xE28:
+ case 0x1828:
+ case 0x1a28:
+ Rate[0] = MGN_24M;
+ Rate[1] = MGN_36M;
+ Rate[2] = MGN_48M;
+ Rate[3] = MGN_54M;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xC2C:
+ case 0xE2C:
+ case 0x182C:
+ case 0x1a2C:
+ Rate[0] = MGN_MCS0;
+ Rate[1] = MGN_MCS1;
+ Rate[2] = MGN_MCS2;
+ Rate[3] = MGN_MCS3;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xC30:
+ case 0xE30:
+ case 0x1830:
+ case 0x1a30:
+ Rate[0] = MGN_MCS4;
+ Rate[1] = MGN_MCS5;
+ Rate[2] = MGN_MCS6;
+ Rate[3] = MGN_MCS7;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xC34:
+ case 0xE34:
+ case 0x1834:
+ case 0x1a34:
+ Rate[0] = MGN_MCS8;
+ Rate[1] = MGN_MCS9;
+ Rate[2] = MGN_MCS10;
+ Rate[3] = MGN_MCS11;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xC38:
+ case 0xE38:
+ case 0x1838:
+ case 0x1a38:
+ Rate[0] = MGN_MCS12;
+ Rate[1] = MGN_MCS13;
+ Rate[2] = MGN_MCS14;
+ Rate[3] = MGN_MCS15;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xC3C:
+ case 0xE3C:
+ case 0x183C:
+ case 0x1a3C:
+ Rate[0] = MGN_VHT1SS_MCS0;
+ Rate[1] = MGN_VHT1SS_MCS1;
+ Rate[2] = MGN_VHT1SS_MCS2;
+ Rate[3] = MGN_VHT1SS_MCS3;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xC40:
+ case 0xE40:
+ case 0x1840:
+ case 0x1a40:
+ Rate[0] = MGN_VHT1SS_MCS4;
+ Rate[1] = MGN_VHT1SS_MCS5;
+ Rate[2] = MGN_VHT1SS_MCS6;
+ Rate[3] = MGN_VHT1SS_MCS7;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xC44:
+ case 0xE44:
+ case 0x1844:
+ case 0x1a44:
+ Rate[0] = MGN_VHT1SS_MCS8;
+ Rate[1] = MGN_VHT1SS_MCS9;
+ Rate[2] = MGN_VHT2SS_MCS0;
+ Rate[3] = MGN_VHT2SS_MCS1;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xC48:
+ case 0xE48:
+ case 0x1848:
+ case 0x1a48:
+ Rate[0] = MGN_VHT2SS_MCS2;
+ Rate[1] = MGN_VHT2SS_MCS3;
+ Rate[2] = MGN_VHT2SS_MCS4;
+ Rate[3] = MGN_VHT2SS_MCS5;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xC4C:
+ case 0xE4C:
+ case 0x184C:
+ case 0x1a4C:
+ Rate[0] = MGN_VHT2SS_MCS6;
+ Rate[1] = MGN_VHT2SS_MCS7;
+ Rate[2] = MGN_VHT2SS_MCS8;
+ Rate[3] = MGN_VHT2SS_MCS9;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xCD8:
+ case 0xED8:
+ case 0x18D8:
+ case 0x1aD8:
+ Rate[0] = MGN_MCS16;
+ Rate[1] = MGN_MCS17;
+ Rate[2] = MGN_MCS18;
+ Rate[3] = MGN_MCS19;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xCDC:
+ case 0xEDC:
+ case 0x18DC:
+ case 0x1aDC:
+ Rate[0] = MGN_MCS20;
+ Rate[1] = MGN_MCS21;
+ Rate[2] = MGN_MCS22;
+ Rate[3] = MGN_MCS23;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xCE0:
+ case 0xEE0:
+ case 0x18E0:
+ case 0x1aE0:
+ Rate[0] = MGN_VHT3SS_MCS0;
+ Rate[1] = MGN_VHT3SS_MCS1;
+ Rate[2] = MGN_VHT3SS_MCS2;
+ Rate[3] = MGN_VHT3SS_MCS3;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xCE4:
+ case 0xEE4:
+ case 0x18E4:
+ case 0x1aE4:
+ Rate[0] = MGN_VHT3SS_MCS4;
+ Rate[1] = MGN_VHT3SS_MCS5;
+ Rate[2] = MGN_VHT3SS_MCS6;
+ Rate[3] = MGN_VHT3SS_MCS7;
+ for (i = 0; i < 4; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 4;
+ break;
+
+ case 0xCE8:
+ case 0xEE8:
+ case 0x18E8:
+ case 0x1aE8:
+ Rate[0] = MGN_VHT3SS_MCS8;
+ Rate[1] = MGN_VHT3SS_MCS9;
+ for (i = 0; i < 2; ++i) {
+ PwrByRateVal[i] = (s8)((((Value >> (i * 8 + 4)) & 0xF)) * 10 +
+ ((Value >> (i * 8)) & 0xF));
+ }
+ *RateNum = 2;
+ break;
+
+ default:
+ RTW_PRINT("Invalid RegAddr 0x%x in %s()\n", RegAddr, __func__);
+ break;
+ };
+}
+
+static void
+PHY_StoreTxPowerByRateNew(
+ PADAPTER pAdapter,
+ u32 Band,
+ u32 RfPath,
+ u32 TxNum,
+ u32 RegAddr,
+ u32 BitMask,
+ u32 Data
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ u8 i = 0, rates[4] = {0}, rateNum = 0;
+ s8 PwrByRateVal[4] = {0};
+
+ PHY_GetRateValuesOfTxPowerByRate(pAdapter, RegAddr, BitMask, Data, rates, PwrByRateVal, &rateNum);
+
+ if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
+ RTW_PRINT("Invalid Band %d\n", Band);
+ return;
+ }
+
+ if (RfPath > ODM_RF_PATH_D) {
+ RTW_PRINT("Invalid RfPath %d\n", RfPath);
+ return;
+ }
+
+ if (TxNum > ODM_RF_PATH_D) {
+ RTW_PRINT("Invalid TxNum %d\n", TxNum);
+ return;
+ }
+
+ for (i = 0; i < rateNum; ++i) {
+ u8 rate_idx = PHY_GetRateIndexOfTxPowerByRate(rates[i]);
+
+ if (IS_1T_RATE(rates[i]))
+ pHalData->TxPwrByRateOffset[Band][RfPath][RF_1TX][rate_idx] = PwrByRateVal[i];
+ else if (IS_2T_RATE(rates[i]))
+ pHalData->TxPwrByRateOffset[Band][RfPath][RF_2TX][rate_idx] = PwrByRateVal[i];
+ else if (IS_3T_RATE(rates[i]))
+ pHalData->TxPwrByRateOffset[Band][RfPath][RF_3TX][rate_idx] = PwrByRateVal[i];
+ else if (IS_4T_RATE(rates[i]))
+ pHalData->TxPwrByRateOffset[Band][RfPath][RF_4TX][rate_idx] = PwrByRateVal[i];
+ else
+ rtw_warn_on(1);
+ }
+}
+
+void
+PHY_InitTxPowerByRate(
+ PADAPTER pAdapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ u8 band = 0, rfPath = 0, TxNum = 0, rate = 0, i = 0, j = 0;
+
+ for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
+ for (rfPath = 0; rfPath < TX_PWR_BY_RATE_NUM_RF; ++rfPath)
+ for (TxNum = 0; TxNum < TX_PWR_BY_RATE_NUM_RF; ++TxNum)
+ for (rate = 0; rate < TX_PWR_BY_RATE_NUM_RATE; ++rate)
+ pHalData->TxPwrByRateOffset[band][rfPath][TxNum][rate] = 0;
+}
+
+void
+phy_store_tx_power_by_rate(
+ PADAPTER pAdapter,
+ u32 Band,
+ u32 RfPath,
+ u32 TxNum,
+ u32 RegAddr,
+ u32 BitMask,
+ u32 Data
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
+
+ if (pDM_Odm->phy_reg_pg_version > 0)
+ PHY_StoreTxPowerByRateNew(pAdapter, Band, RfPath, TxNum, RegAddr, BitMask, Data);
+ else
+ RTW_INFO("Invalid PHY_REG_PG.txt version %d\n", pDM_Odm->phy_reg_pg_version);
+
+}
+
+static void
+phy_ConvertTxPowerByRateInDbmToRelativeValues(
+ PADAPTER pAdapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ u8 base = 0, i = 0, value = 0,
+ band = 0, path = 0, txNum = 0, index = 0,
+ startIndex = 0, endIndex = 0;
+ u8 cckRates[4] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M},
+ ofdmRates[8] = {MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M},
+ mcs0_7Rates[8] = {MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7},
+ mcs8_15Rates[8] = {MGN_MCS8, MGN_MCS9, MGN_MCS10, MGN_MCS11, MGN_MCS12, MGN_MCS13, MGN_MCS14, MGN_MCS15},
+ mcs16_23Rates[8] = {MGN_MCS16, MGN_MCS17, MGN_MCS18, MGN_MCS19, MGN_MCS20, MGN_MCS21, MGN_MCS22, MGN_MCS23},
+ vht1ssRates[10] = {MGN_VHT1SS_MCS0, MGN_VHT1SS_MCS1, MGN_VHT1SS_MCS2, MGN_VHT1SS_MCS3, MGN_VHT1SS_MCS4,
+ MGN_VHT1SS_MCS5, MGN_VHT1SS_MCS6, MGN_VHT1SS_MCS7, MGN_VHT1SS_MCS8, MGN_VHT1SS_MCS9},
+ vht2ssRates[10] = {MGN_VHT2SS_MCS0, MGN_VHT2SS_MCS1, MGN_VHT2SS_MCS2, MGN_VHT2SS_MCS3, MGN_VHT2SS_MCS4,
+ MGN_VHT2SS_MCS5, MGN_VHT2SS_MCS6, MGN_VHT2SS_MCS7, MGN_VHT2SS_MCS8, MGN_VHT2SS_MCS9},
+ vht3ssRates[10] = {MGN_VHT3SS_MCS0, MGN_VHT3SS_MCS1, MGN_VHT3SS_MCS2, MGN_VHT3SS_MCS3, MGN_VHT3SS_MCS4,
+ MGN_VHT3SS_MCS5, MGN_VHT3SS_MCS6, MGN_VHT3SS_MCS7, MGN_VHT3SS_MCS8, MGN_VHT3SS_MCS9};
+
+ /* RTW_INFO("===>PHY_ConvertTxPowerByRateInDbmToRelativeValues()\n" ); */
+
+ for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) {
+ for (path = ODM_RF_PATH_A; path <= ODM_RF_PATH_D; ++path) {
+ for (txNum = RF_1TX; txNum < RF_MAX_TX_NUM; ++txNum) {
+ /* CCK */
+ if (band == BAND_ON_2_4G) {
+ base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, CCK);
+ for (i = 0; i < sizeof(cckRates); ++i) {
+ value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, cckRates[i]);
+ PHY_SetTxPowerByRate(pAdapter, band, path, txNum, cckRates[i], value - base);
+ }
+ }
+
+ /* OFDM */
+ base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, OFDM);
+ for (i = 0; i < sizeof(ofdmRates); ++i) {
+ value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, ofdmRates[i]);
+ PHY_SetTxPowerByRate(pAdapter, band, path, txNum, ofdmRates[i], value - base);
+ }
+
+ /* HT MCS0~7 */
+ base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, HT_1SS);
+ for (i = 0; i < sizeof(mcs0_7Rates); ++i) {
+ value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, mcs0_7Rates[i]);
+ PHY_SetTxPowerByRate(pAdapter, band, path, txNum, mcs0_7Rates[i], value - base);
+ }
+
+ /* HT MCS8~15 */
+ base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, HT_2SS);
+ for (i = 0; i < sizeof(mcs8_15Rates); ++i) {
+ value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, mcs8_15Rates[i]);
+ PHY_SetTxPowerByRate(pAdapter, band, path, txNum, mcs8_15Rates[i], value - base);
+ }
+
+ /* HT MCS16~23 */
+ base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, HT_3SS);
+ for (i = 0; i < sizeof(mcs16_23Rates); ++i) {
+ value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, mcs16_23Rates[i]);
+ PHY_SetTxPowerByRate(pAdapter, band, path, txNum, mcs16_23Rates[i], value - base);
+ }
+
+ /* VHT 1SS */
+ base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, VHT_1SS);
+ for (i = 0; i < sizeof(vht1ssRates); ++i) {
+ value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, vht1ssRates[i]);
+ PHY_SetTxPowerByRate(pAdapter, band, path, txNum, vht1ssRates[i], value - base);
+ }
+
+ /* VHT 2SS */
+ base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, VHT_2SS);
+ for (i = 0; i < sizeof(vht2ssRates); ++i) {
+ value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, vht2ssRates[i]);
+ PHY_SetTxPowerByRate(pAdapter, band, path, txNum, vht2ssRates[i], value - base);
+ }
+
+ /* VHT 3SS */
+ base = PHY_GetTxPowerByRateBase(pAdapter, band, path, txNum, VHT_3SS);
+ for (i = 0; i < sizeof(vht3ssRates); ++i) {
+ value = PHY_GetTxPowerByRate(pAdapter, band, path, txNum, vht3ssRates[i]);
+ PHY_SetTxPowerByRate(pAdapter, band, path, txNum, vht3ssRates[i], value - base);
+ }
+ }
+ }
+ }
+
+ /* RTW_INFO("<===PHY_ConvertTxPowerByRateInDbmToRelativeValues()\n" ); */
+}
+
+/*
+ * This function must be called if the value in the PHY_REG_PG.txt(or header)
+ * is exact dBm values
+ */
+void
+PHY_TxPowerByRateConfiguration(
+ PADAPTER pAdapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+
+ phy_txpwr_by_rate_chk_for_path_dup(pAdapter);
+ phy_StoreTxPowerByRateBase(pAdapter);
+ phy_ConvertTxPowerByRateInDbmToRelativeValues(pAdapter);
+}
+
+void
+phy_set_tx_power_index_by_rate_section(
+ PADAPTER pAdapter,
+ u8 RFPath,
+ u8 Channel,
+ u8 RateSection
+)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
+
+ if (RateSection >= RATE_SECTION_NUM) {
+ RTW_INFO("Invalid RateSection %d in %s", RateSection, __func__);
+ rtw_warn_on(1);
+ goto exit;
+ }
+
+ if (RateSection == CCK && pHalData->current_band_type != BAND_ON_2_4G)
+ goto exit;
+
+ PHY_SetTxPowerIndexByRateArray(pAdapter, RFPath, pHalData->current_channel_bw, Channel,
+ rates_by_sections[RateSection].rates, rates_by_sections[RateSection].rate_num);
+
+exit:
+ return;
+}
+
+static bool phy_GetChnlIndex(u8 Channel, u8 *ChannelIdx)
+{
+ u8 i = 0;
+ bool bIn24G = true;
+
+ if (Channel <= 14) {
+ bIn24G = true;
+ *ChannelIdx = Channel - 1;
+ } else {
+ bIn24G = false;
+
+ for (i = 0; i < CENTER_CH_5G_ALL_NUM; ++i) {
+ if (center_ch_5g_all[i] == Channel) {
+ *ChannelIdx = i;
+ return bIn24G;
+ }
+ }
+ }
+
+ return bIn24G;
+}
+
+u8
+PHY_GetTxPowerIndexBase(
+ PADAPTER pAdapter,
+ u8 RFPath,
+ u8 Rate,
+ CHANNEL_WIDTH BandWidth,
+ u8 Channel,
+ bool * bIn24G
+)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
+ u8 i = 0; /* default set to 1S */
+ u8 txPower = 0;
+ u8 chnlIdx = (Channel - 1);
+
+ if (HAL_IsLegalChannel(pAdapter, Channel) == false) {
+ chnlIdx = 0;
+ RTW_INFO("Illegal channel!!\n");
+ }
+
+ *bIn24G = phy_GetChnlIndex(Channel, &chnlIdx);
+
+ /* RTW_INFO("[%s] Channel Index: %d\n", (*bIn24G?"2.4G":"5G"), chnlIdx); */
+
+ if (*bIn24G) { /* 3 ============================== 2.4 G ============================== */
+ if (IS_CCK_RATE(Rate))
+ txPower = pHalData->Index24G_CCK_Base[RFPath][chnlIdx];
+ else if (MGN_6M <= Rate)
+ txPower = pHalData->Index24G_BW40_Base[RFPath][chnlIdx];
+ else
+ RTW_INFO("PHY_GetTxPowerIndexBase: INVALID Rate(0x%02x).\n", Rate);
+
+ /* RTW_INFO("Base Tx power(RF-%c, Rate #%d, Channel Index %d) = 0x%X\n", */
+ /* ((RFPath==0)?'A':'B'), Rate, chnlIdx, txPower); */
+
+ /* OFDM-1T */
+ if ((MGN_6M <= Rate && Rate <= MGN_54M) && !IS_CCK_RATE(Rate)) {
+ txPower += pHalData->OFDM_24G_Diff[RFPath][TX_1S];
+ /* RTW_INFO("+PowerDiff 2.4G (RF-%c): (OFDM-1T) = (%d)\n", ((RFPath==0)?'A':'B'), pHalData->OFDM_24G_Diff[RFPath][TX_1S]); */
+ }
+ /* BW20-1S, BW20-2S */
+ if (BandWidth == CHANNEL_WIDTH_20) {
+ if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW20_24G_Diff[RFPath][TX_1S];
+ if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW20_24G_Diff[RFPath][TX_2S];
+ if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW20_24G_Diff[RFPath][TX_3S];
+ if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW20_24G_Diff[RFPath][TX_4S];
+
+ /* RTW_INFO("+PowerDiff 2.4G (RF-%c): (BW20-1S, BW20-2S, BW20-3S, BW20-4S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), */
+ /* pHalData->BW20_24G_Diff[RFPath][TX_1S], pHalData->BW20_24G_Diff[RFPath][TX_2S], */
+ /* pHalData->BW20_24G_Diff[RFPath][TX_3S], pHalData->BW20_24G_Diff[RFPath][TX_4S]); */
+ }
+ /* BW40-1S, BW40-2S */
+ else if (BandWidth == CHANNEL_WIDTH_40) {
+ if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW40_24G_Diff[RFPath][TX_1S];
+ if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW40_24G_Diff[RFPath][TX_2S];
+ if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW40_24G_Diff[RFPath][TX_3S];
+ if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW40_24G_Diff[RFPath][TX_4S];
+
+ /* RTW_INFO("+PowerDiff 2.4G (RF-%c): (BW40-1S, BW40-2S, BW40-3S, BW40-4S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), */
+ /* pHalData->BW40_24G_Diff[RFPath][TX_1S], pHalData->BW40_24G_Diff[RFPath][TX_2S], */
+ /* pHalData->BW40_24G_Diff[RFPath][TX_3S], pHalData->BW40_24G_Diff[RFPath][TX_4S]); */
+ }
+ /* Willis suggest adopt BW 40M power index while in BW 80 mode */
+ else if (BandWidth == CHANNEL_WIDTH_80) {
+ if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW40_24G_Diff[RFPath][TX_1S];
+ if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW40_24G_Diff[RFPath][TX_2S];
+ if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW40_24G_Diff[RFPath][TX_3S];
+ if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW40_24G_Diff[RFPath][TX_4S];
+
+ /* RTW_INFO("+PowerDiff 2.4G (RF-%c): (BW40-1S, BW40-2S, BW40-3S, BW40-4T) = (%d, %d, %d, %d) P.S. Current is in BW 80MHz\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), */
+ /* pHalData->BW40_24G_Diff[RFPath][TX_1S], pHalData->BW40_24G_Diff[RFPath][TX_2S], */
+ /* pHalData->BW40_24G_Diff[RFPath][TX_3S], pHalData->BW40_24G_Diff[RFPath][TX_4S]); */
+ }
+ }
+#ifdef CONFIG_IEEE80211_BAND_5GHZ
+ else { /* 3 ============================== 5 G ============================== */
+ if (MGN_6M <= Rate)
+ txPower = pHalData->Index5G_BW40_Base[RFPath][chnlIdx];
+ else
+ RTW_INFO("===>PHY_GetTxPowerIndexBase: INVALID Rate(0x%02x).\n", Rate);
+
+ /* RTW_INFO("Base Tx power(RF-%c, Rate #%d, Channel Index %d) = 0x%X\n", */
+ /* ((RFPath==0)?'A':'B'), Rate, chnlIdx, txPower); */
+
+ /* OFDM-1T */
+ if ((MGN_6M <= Rate && Rate <= MGN_54M) && !IS_CCK_RATE(Rate)) {
+ txPower += pHalData->OFDM_5G_Diff[RFPath][TX_1S];
+ /* RTW_INFO("+PowerDiff 5G (RF-%c): (OFDM-1T) = (%d)\n", ((RFPath==0)?'A':'B'), pHalData->OFDM_5G_Diff[RFPath][TX_1S]); */
+ }
+
+ /* BW20-1S, BW20-2S */
+ if (BandWidth == CHANNEL_WIDTH_20) {
+ if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW20_5G_Diff[RFPath][TX_1S];
+ if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW20_5G_Diff[RFPath][TX_2S];
+ if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW20_5G_Diff[RFPath][TX_3S];
+ if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW20_5G_Diff[RFPath][TX_4S];
+
+ /* RTW_INFO("+PowerDiff 5G (RF-%c): (BW20-1S, BW20-2S, BW20-3S, BW20-4S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), */
+ /* pHalData->BW20_5G_Diff[RFPath][TX_1S], pHalData->BW20_5G_Diff[RFPath][TX_2S], */
+ /* pHalData->BW20_5G_Diff[RFPath][TX_3S], pHalData->BW20_5G_Diff[RFPath][TX_4S]); */
+ }
+ /* BW40-1S, BW40-2S */
+ else if (BandWidth == CHANNEL_WIDTH_40) {
+ if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW40_5G_Diff[RFPath][TX_1S];
+ if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW40_5G_Diff[RFPath][TX_2S];
+ if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW40_5G_Diff[RFPath][TX_3S];
+ if ((MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW40_5G_Diff[RFPath][TX_4S];
+
+ /* RTW_INFO("+PowerDiff 5G(RF-%c): (BW40-1S, BW40-2S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), */
+ /* pHalData->BW40_5G_Diff[RFPath][TX_1S], pHalData->BW40_5G_Diff[RFPath][TX_2S], */
+ /* pHalData->BW40_5G_Diff[RFPath][TX_3S], pHalData->BW40_5G_Diff[RFPath][TX_4S]); */
+ }
+ /* BW80-1S, BW80-2S */
+ else if (BandWidth == CHANNEL_WIDTH_80) {
+ /* <20121220, Kordan> Get the index of array "Index5G_BW80_Base". */
+ for (i = 0; i < CENTER_CH_5G_80M_NUM; ++i)
+ if (center_ch_5g_80m[i] == Channel)
+ chnlIdx = i;
+
+ txPower = pHalData->Index5G_BW80_Base[RFPath][chnlIdx];
+
+ if ((MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += + pHalData->BW80_5G_Diff[RFPath][TX_1S];
+ if ((MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW80_5G_Diff[RFPath][TX_2S];
+ if ((MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW80_5G_Diff[RFPath][TX_3S];
+ if ((MGN_MCS23 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9))
+ txPower += pHalData->BW80_5G_Diff[RFPath][TX_4S];
+
+ /* RTW_INFO("+PowerDiff 5G(RF-%c): (BW80-1S, BW80-2S, BW80-3S, BW80-4S) = (%d, %d, %d, %d)\n",((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), */
+ /* pHalData->BW80_5G_Diff[RFPath][TX_1S], pHalData->BW80_5G_Diff[RFPath][TX_2S], */
+ /* pHalData->BW80_5G_Diff[RFPath][TX_3S], pHalData->BW80_5G_Diff[RFPath][TX_4S]); */
+ }
+ }
+#endif /* CONFIG_IEEE80211_BAND_5GHZ */
+
+ return txPower;
+}
+
+s8
+PHY_GetTxPowerTrackingOffset(
+ PADAPTER pAdapter,
+ u8 RFPath,
+ u8 Rate
+)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
+ s8 offset = 0;
+
+ if (pDM_Odm->rf_calibrate_info.txpowertrack_control == false)
+ return offset;
+
+ if ((Rate == MGN_1M) || (Rate == MGN_2M) || (Rate == MGN_5_5M) || (Rate == MGN_11M)) {
+ offset = pDM_Odm->rf_calibrate_info.remnant_cck_swing_idx;
+ /*RTW_INFO("+Remnant_CCKSwingIdx = 0x%x\n", RFPath, Rate, pRFCalibrateInfo->Remnant_CCKSwingIdx);*/
+ } else {
+ offset = pDM_Odm->rf_calibrate_info.remnant_ofdm_swing_idx[RFPath];
+ /*RTW_INFO("+Remanant_OFDMSwingIdx[RFPath %u][Rate 0x%x] = 0x%x\n", RFPath, Rate, pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath]); */
+
+ }
+
+ return offset;
+}
+
+/*The same as MRateToHwRate in hal_com.c*/
+u8
+PHY_GetRateIndexOfTxPowerByRate(
+ u8 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, __func__);
+ break;
+ };
+
+ return index;
+}
+
+s8
+_PHY_GetTxPowerByRate(
+ PADAPTER pAdapter,
+ u8 Band,
+ u8 RFPath,
+ u8 TxNum,
+ u8 Rate
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ s8 value = 0;
+ u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate);
+
+ if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
+ RTW_INFO("Invalid band %d in %s\n", Band, __func__);
+ goto exit;
+ }
+ if (RFPath > ODM_RF_PATH_D) {
+ RTW_INFO("Invalid RfPath %d in %s\n", RFPath, __func__);
+ goto exit;
+ }
+ if (TxNum >= RF_MAX_TX_NUM) {
+ RTW_INFO("Invalid TxNum %d in %s\n", TxNum, __func__);
+ goto exit;
+ }
+ if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) {
+ RTW_INFO("Invalid RateIndex %d in %s\n", rateIndex, __func__);
+ goto exit;
+ }
+
+ value = pHalData->TxPwrByRateOffset[Band][RFPath][TxNum][rateIndex];
+
+exit:
+ return value;
+}
+
+
+s8
+PHY_GetTxPowerByRate(
+ PADAPTER pAdapter,
+ u8 Band,
+ u8 RFPath,
+ u8 TxNum,
+ u8 Rate
+)
+{
+ if (!phy_is_tx_power_by_rate_needed(pAdapter))
+ return 0;
+
+ return _PHY_GetTxPowerByRate(pAdapter, Band, RFPath, TxNum, Rate);
+}
+
+#ifdef CONFIG_PHYDM_POWERTRACK_BY_TSSI
+s8
+PHY_GetTxPowerByRateOriginal(
+ PADAPTER pAdapter,
+ u8 Band,
+ u8 RFPath,
+ u8 TxNum,
+ u8 Rate
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ s8 value = 0, limit = 0;
+ u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate);
+
+ if ((pAdapter->registrypriv.RegEnableTxPowerByRate == 2 && pHalData->EEPROMRegulatory == 2) ||
+ pAdapter->registrypriv.RegEnableTxPowerByRate == 0)
+ return 0;
+
+ if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
+ DBG_871X("Invalid band %d in %s\n", Band, __func__);
+ return value;
+ }
+ if (RFPath > ODM_RF_PATH_D) {
+ DBG_871X("Invalid RfPath %d in %s\n", RFPath, __func__);
+ return value;
+ }
+ if (TxNum >= RF_MAX_TX_NUM) {
+ DBG_871X("Invalid TxNum %d in %s\n", TxNum, __func__);
+ return value;
+ }
+ if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) {
+ DBG_871X("Invalid RateIndex %d in %s\n", rateIndex, __func__);
+ return value;
+ }
+
+ value = pHalData->TxPwrByRate[Band][RFPath][TxNum][rateIndex];
+
+ return value;
+}
+
+#endif
+
+
+void
+PHY_SetTxPowerByRate(
+ PADAPTER pAdapter,
+ u8 Band,
+ u8 RFPath,
+ u8 TxNum,
+ u8 Rate,
+ s8 Value
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate);
+
+ if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
+ RTW_INFO("Invalid band %d in %s\n", Band, __func__);
+ return;
+ }
+ if (RFPath > ODM_RF_PATH_D) {
+ RTW_INFO("Invalid RfPath %d in %s\n", RFPath, __func__);
+ return;
+ }
+ if (TxNum >= RF_MAX_TX_NUM) {
+ RTW_INFO("Invalid TxNum %d in %s\n", TxNum, __func__);
+ return;
+ }
+ if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) {
+ RTW_INFO("Invalid RateIndex %d in %s\n", rateIndex, __func__);
+ return;
+ }
+
+ pHalData->TxPwrByRateOffset[Band][RFPath][TxNum][rateIndex] = Value;
+}
+
+void
+phy_set_tx_power_level_by_path(
+ PADAPTER Adapter,
+ u8 channel,
+ u8 path
+)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
+ bool bIsIn24G = (pHalData->current_band_type == BAND_ON_2_4G);
+
+ /* if ( pMgntInfo->RegNByteAccess == 0 ) */
+ {
+ if (bIsIn24G)
+ phy_set_tx_power_index_by_rate_section(Adapter, path, channel, CCK);
+
+ phy_set_tx_power_index_by_rate_section(Adapter, path, channel, OFDM);
+ phy_set_tx_power_index_by_rate_section(Adapter, path, channel, HT_MCS0_MCS7);
+
+ if (pHalData->NumTotalRFPath >= 2)
+ phy_set_tx_power_index_by_rate_section(Adapter, path, channel, HT_MCS8_MCS15);
+ }
+}
+
+#ifndef DBG_TX_POWER_IDX
+#define DBG_TX_POWER_IDX 0
+#endif
+
+void
+PHY_SetTxPowerIndexByRateArray(
+ PADAPTER pAdapter,
+ u8 RFPath,
+ CHANNEL_WIDTH BandWidth,
+ u8 Channel,
+ u8 *Rates,
+ u8 RateArraySize
+)
+{
+ u32 powerIndex = 0;
+ int i = 0;
+
+ for (i = 0; i < RateArraySize; ++i) {
+#if DBG_TX_POWER_IDX
+ struct txpwr_idx_comp tic;
+
+ powerIndex = rtw_hal_get_tx_power_index(pAdapter, RFPath, Rates[i], BandWidth, Channel, &tic);
+ RTW_INFO("TXPWR: [%c][%s]ch:%u, %s, pwr_idx:%u = %u + (%d=%d:%d) + (%d) + (%d)\n"
+ , rf_path_char(RFPath), ch_width_str(BandWidth), Channel, MGN_RATE_STR(Rates[i])
+ , powerIndex, tic.base, (tic.by_rate > tic.limit ? tic.limit : tic.by_rate), tic.by_rate, tic.limit, tic.tpt, tic.ebias);
+#else
+ powerIndex = phy_get_tx_power_index(pAdapter, RFPath, Rates[i], BandWidth, Channel);
+#endif
+ PHY_SetTxPowerIndex(pAdapter, powerIndex, RFPath, Rates[i]);
+ }
+}
+
+static s8 phy_GetWorldWideLimit(s8 *LimitTable)
+{
+ s8 min = LimitTable[0];
+ u8 i = 0;
+
+ for (i = 0; i < MAX_REGULATION_NUM; ++i) {
+ if (LimitTable[i] < min)
+ min = LimitTable[i];
+ }
+
+ return min;
+}
+
+static s8 phy_GetChannelIndexOfTxPowerLimit(u8 Band, u8 Channel)
+{
+ s8 channelIndex = -1;
+ u8 i = 0;
+
+ if (Band == BAND_ON_2_4G)
+ channelIndex = Channel - 1;
+ else if (Band == BAND_ON_5G) {
+ for (i = 0; i < CENTER_CH_5G_ALL_NUM; ++i) {
+ if (center_ch_5g_all[i] == Channel)
+ channelIndex = i;
+ }
+ } else
+ RTW_PRINT("Invalid Band %d in %s\n", Band, __func__);
+
+ if (channelIndex == -1)
+ RTW_PRINT("Invalid Channel %d of Band %d in %s\n", Channel, Band, __func__);
+
+ return channelIndex;
+}
+
+static s8 _phy_get_txpwr_lmt(
+ PADAPTER Adapter,
+ u32 RegPwrTblSel,
+ BAND_TYPE Band,
+ CHANNEL_WIDTH Bandwidth,
+ u8 RfPath,
+ u8 DataRate,
+ u8 Channel,
+ bool no_sc
+)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter);
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(Adapter);
+ s8 regulation = -1, bw = -1, rs = -1;
+ u8 cch = 0;
+ u8 bw_bmp = 0;
+ s8 min_lmt = MAX_POWER_INDEX;
+ s8 tmp_lmt;
+ u8 final_bw = Bandwidth, final_cch = Channel;
+
+ if ((Adapter->registrypriv.RegEnableTxPowerLimit == 2 && hal_data->EEPROMRegulatory != 1) ||
+ Adapter->registrypriv.RegEnableTxPowerLimit == 0)
+ goto exit;
+
+ switch (RegPwrTblSel) {
+ case 1:
+ regulation = TXPWR_LMT_ETSI;
+ break;
+ case 2:
+ regulation = TXPWR_LMT_MKK;
+ break;
+ case 3:
+ regulation = TXPWR_LMT_FCC;
+ break;
+ case 4:
+ regulation = TXPWR_LMT_WW;
+ break;
+ default:
+ regulation = (Band == BAND_ON_2_4G) ? hal_data->Regulation2_4G : hal_data->Regulation5G;
+ break;
+ }
+
+ if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) {
+ RTW_ERR("%s invalid band:%u\n", __func__, Band);
+ rtw_warn_on(1);
+ goto exit;
+ }
+
+ if (IS_CCK_RATE(DataRate))
+ rs = CCK;
+ else if (IS_OFDM_RATE(DataRate))
+ rs = OFDM;
+ else if (IS_HT1SS_RATE(DataRate))
+ rs = HT_1SS;
+ else if (IS_HT2SS_RATE(DataRate))
+ rs = HT_2SS;
+ else if (IS_HT3SS_RATE(DataRate))
+ rs = HT_3SS;
+ else if (IS_HT4SS_RATE(DataRate))
+ rs = HT_4SS;
+ else if (IS_VHT1SS_RATE(DataRate))
+ rs = VHT_1SS;
+ else if (IS_VHT2SS_RATE(DataRate))
+ rs = VHT_2SS;
+ else if (IS_VHT3SS_RATE(DataRate))
+ rs = VHT_3SS;
+ else if (IS_VHT4SS_RATE(DataRate))
+ rs = VHT_4SS;
+ else {
+ RTW_ERR("%s invalid rate 0x%x\n", __func__, DataRate);
+ rtw_warn_on(1);
+ goto exit;
+ }
+
+ if (Band == BAND_ON_5G && rs == CCK) {
+ RTW_ERR("Wrong rate No CCK(0x%x) in 5G Band\n", DataRate);
+ goto exit;
+ }
+
+ if (no_sc == true) {
+ /* use the input center channel and bandwidth directly */
+ cch = Channel;
+ bw_bmp = ch_width_to_bw_cap(Bandwidth);
+ } else {
+ /*
+ * 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
+ */
+ if (rs == CCK || rs == OFDM)
+ bw_bmp = BW_CAP_20M; /* CCK, OFDM only BW 20M */
+ else if (IS_HT_RATE_SECTION(rs)) {
+ bw_bmp = rtw_get_tx_bw_bmp_of_ht_rate(dvobj, DataRate, Bandwidth);
+ if (bw_bmp == 0)
+ bw_bmp = ch_width_to_bw_cap(Bandwidth > CHANNEL_WIDTH_40 ? CHANNEL_WIDTH_40 : Bandwidth);
+ } else if (IS_VHT_RATE_SECTION(rs)) {
+ bw_bmp = rtw_get_tx_bw_bmp_of_vht_rate(dvobj, DataRate, Bandwidth);
+ if (bw_bmp == 0)
+ bw_bmp = ch_width_to_bw_cap(Bandwidth > CHANNEL_WIDTH_160 ? CHANNEL_WIDTH_160 : Bandwidth);
+ } else
+ rtw_warn_on(1);
+ }
+
+ if (bw_bmp == 0)
+ goto exit;
+
+ /* loop for each possible tx bandwidth to find minimum limit */
+ for (bw = CHANNEL_WIDTH_20; bw <= Bandwidth; bw++) {
+ s8 ch_idx;
+
+ if (!(ch_width_to_bw_cap(bw) & bw_bmp))
+ continue;
+
+ if (no_sc == false) {
+ if (bw == CHANNEL_WIDTH_20)
+ cch = hal_data->cch_20;
+ else if (bw == CHANNEL_WIDTH_40)
+ cch = hal_data->cch_40;
+ else if (bw == CHANNEL_WIDTH_80)
+ cch = hal_data->cch_80;
+ else {
+ cch = 0;
+ rtw_warn_on(1);
+ }
+ }
+
+ ch_idx = phy_GetChannelIndexOfTxPowerLimit(Band, cch);
+ if (ch_idx == -1)
+ continue;
+
+ if (Band == BAND_ON_2_4G) {
+ s8 limits[MAX_REGULATION_NUM] = {0};
+ u8 i = 0;
+
+ for (i = 0; i < MAX_REGULATION_NUM; ++i)
+ limits[i] = hal_data->TxPwrLimit_2_4G[i][bw][rs][ch_idx][RfPath];
+
+ tmp_lmt = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) :
+ hal_data->TxPwrLimit_2_4G[regulation][bw][rs][ch_idx][RfPath];
+
+ } else if (Band == BAND_ON_5G) {
+ s8 limits[MAX_REGULATION_NUM] = {0};
+ u8 i = 0;
+
+ for (i = 0; i < MAX_REGULATION_NUM; ++i)
+ limits[i] = hal_data->TxPwrLimit_5G[i][bw][rs][ch_idx][RfPath];
+
+ tmp_lmt = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) :
+ hal_data->TxPwrLimit_5G[regulation][bw][rs][ch_idx][RfPath];
+ } else
+ continue;
+
+ if (min_lmt >= tmp_lmt) {
+ min_lmt = tmp_lmt;
+ final_cch = cch;
+ final_bw = bw;
+ }
+ }
+
+exit:
+ return min_lmt;
+}
+
+inline s8
+PHY_GetTxPowerLimit(
+ PADAPTER Adapter,
+ u32 RegPwrTblSel,
+ BAND_TYPE Band,
+ CHANNEL_WIDTH Bandwidth,
+ u8 RfPath,
+ u8 DataRate,
+ u8 Channel
+)
+{
+ bool no_sc = false;
+
+ /* MP mode channel don't use secondary channel */
+ if (rtw_mi_mp_mode_check(Adapter) == true)
+ no_sc = true;
+
+ return _phy_get_txpwr_lmt(Adapter, RegPwrTblSel, Band, Bandwidth, RfPath, DataRate, Channel, no_sc);
+}
+
+inline s8
+PHY_GetTxPowerLimit_no_sc(
+ PADAPTER Adapter,
+ u32 RegPwrTblSel,
+ BAND_TYPE Band,
+ CHANNEL_WIDTH Bandwidth,
+ u8 RfPath,
+ u8 DataRate,
+ u8 Channel
+)
+{
+ return _phy_get_txpwr_lmt(Adapter, RegPwrTblSel, Band, Bandwidth, RfPath, DataRate, Channel, true);
+}
+
+#ifdef CONFIG_PHYDM_POWERTRACK_BY_TSSI
+s8
+PHY_GetTxPowerLimitOriginal(
+ PADAPTER Adapter,
+ u32 RegPwrTblSel,
+ BAND_TYPE Band,
+ CHANNEL_WIDTH Bandwidth,
+ u8 RfPath,
+ u8 DataRate,
+ u8 Channel
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ s16 band = -1, regulation = -1, bandwidth = -1,
+ rateSection = -1, channel = -1;
+ s8 powerLimit = MAX_POWER_INDEX;
+
+ if ((Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory != 1) ||
+ Adapter->registrypriv.RegEnableTxPowerLimit == 0)
+ return MAX_POWER_INDEX;
+
+ switch (Adapter->registrypriv.RegPwrTblSel) {
+ case 1:
+ regulation = TXPWR_LMT_ETSI;
+ break;
+
+ case 2:
+ regulation = TXPWR_LMT_MKK;
+ break;
+
+ case 3:
+ regulation = TXPWR_LMT_FCC;
+ break;
+
+ case 4:
+ regulation = TXPWR_LMT_WW;
+ break;
+
+ default:
+ regulation = (Band == BAND_ON_2_4G) ? pHalData->Regulation2_4G
+ : pHalData->Regulation5G;
+ break;
+ }
+
+ /*DBG_871X("pMgntInfo->RegPwrTblSel %d, final regulation %d\n", Adapter->registrypriv.RegPwrTblSel, regulation );*/
+
+
+ if (Band == BAND_ON_2_4G)
+ band = 0;
+ else if (Band == BAND_ON_5G)
+ band = 1;
+
+ if (Bandwidth == CHANNEL_WIDTH_20)
+ bandwidth = 0;
+ else if (Bandwidth == CHANNEL_WIDTH_40)
+ bandwidth = 1;
+ else if (Bandwidth == CHANNEL_WIDTH_80)
+ bandwidth = 2;
+ else if (Bandwidth == CHANNEL_WIDTH_160)
+ bandwidth = 3;
+
+ switch (DataRate) {
+ case MGN_1M:
+ case MGN_2M:
+ case MGN_5_5M:
+ case MGN_11M:
+ rateSection = 0;
+ break;
+
+ case MGN_6M:
+ case MGN_9M:
+ case MGN_12M:
+ case MGN_18M:
+ case MGN_24M:
+ case MGN_36M:
+ case MGN_48M:
+ case MGN_54M:
+ rateSection = 1;
+ break;
+
+ case MGN_MCS0:
+ case MGN_MCS1:
+ case MGN_MCS2:
+ case MGN_MCS3:
+ case MGN_MCS4:
+ case MGN_MCS5:
+ case MGN_MCS6:
+ case MGN_MCS7:
+ rateSection = 2;
+ break;
+
+ case MGN_MCS8:
+ case MGN_MCS9:
+ case MGN_MCS10:
+ case MGN_MCS11:
+ case MGN_MCS12:
+ case MGN_MCS13:
+ case MGN_MCS14:
+ case MGN_MCS15:
+ rateSection = 3;
+ break;
+
+ case MGN_MCS16:
+ case MGN_MCS17:
+ case MGN_MCS18:
+ case MGN_MCS19:
+ case MGN_MCS20:
+ case MGN_MCS21:
+ case MGN_MCS22:
+ case MGN_MCS23:
+ rateSection = 4;
+ break;
+
+ case MGN_MCS24:
+ case MGN_MCS25:
+ case MGN_MCS26:
+ case MGN_MCS27:
+ case MGN_MCS28:
+ case MGN_MCS29:
+ case MGN_MCS30:
+ case MGN_MCS31:
+ rateSection = 5;
+ break;
+
+ case MGN_VHT1SS_MCS0:
+ case MGN_VHT1SS_MCS1:
+ case MGN_VHT1SS_MCS2:
+ case MGN_VHT1SS_MCS3:
+ case MGN_VHT1SS_MCS4:
+ case MGN_VHT1SS_MCS5:
+ case MGN_VHT1SS_MCS6:
+ case MGN_VHT1SS_MCS7:
+ case MGN_VHT1SS_MCS8:
+ case MGN_VHT1SS_MCS9:
+ rateSection = 6;
+ break;
+
+ case MGN_VHT2SS_MCS0:
+ case MGN_VHT2SS_MCS1:
+ case MGN_VHT2SS_MCS2:
+ case MGN_VHT2SS_MCS3:
+ case MGN_VHT2SS_MCS4:
+ case MGN_VHT2SS_MCS5:
+ case MGN_VHT2SS_MCS6:
+ case MGN_VHT2SS_MCS7:
+ case MGN_VHT2SS_MCS8:
+ case MGN_VHT2SS_MCS9:
+ rateSection = 7;
+ break;
+
+ case MGN_VHT3SS_MCS0:
+ case MGN_VHT3SS_MCS1:
+ case MGN_VHT3SS_MCS2:
+ case MGN_VHT3SS_MCS3:
+ case MGN_VHT3SS_MCS4:
+ case MGN_VHT3SS_MCS5:
+ case MGN_VHT3SS_MCS6:
+ case MGN_VHT3SS_MCS7:
+ case MGN_VHT3SS_MCS8:
+ case MGN_VHT3SS_MCS9:
+ rateSection = 8;
+ break;
+
+ case MGN_VHT4SS_MCS0:
+ case MGN_VHT4SS_MCS1:
+ case MGN_VHT4SS_MCS2:
+ case MGN_VHT4SS_MCS3:
+ case MGN_VHT4SS_MCS4:
+ case MGN_VHT4SS_MCS5:
+ case MGN_VHT4SS_MCS6:
+ case MGN_VHT4SS_MCS7:
+ case MGN_VHT4SS_MCS8:
+ case MGN_VHT4SS_MCS9:
+ rateSection = 9;
+ break;
+
+ default:
+ DBG_871X("Wrong rate 0x%x\n", DataRate);
+ break;
+ }
+
+ if (Band == BAND_ON_5G && rateSection == 0)
+ DBG_871X("Wrong rate 0x%x: No CCK in 5G Band\n", DataRate);
+
+ /*workaround for wrong index combination to obtain tx power limit,*/
+ /*OFDM only exists in BW 20M*/
+ if (rateSection == 1)
+ bandwidth = 0;
+
+ /*workaround for wrong index combination to obtain tx power limit,*/
+ /*CCK table will only be given in BW 20M*/
+ if (rateSection == 0)
+ bandwidth = 0;
+
+ /*workaround for wrong indxe combination to obtain tx power limit,*/
+ /*HT on 80M will reference to HT on 40M*/
+ if ((rateSection == 2 || rateSection == 3) && Band == BAND_ON_5G && bandwidth == 2)
+ bandwidth = 1;
+
+ if (Band == BAND_ON_2_4G)
+ channel = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_2_4G, Channel);
+ else if (Band == BAND_ON_5G)
+ channel = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_5G, Channel);
+ else if (Band == BAND_ON_BOTH)
+ /*BAND_ON_BOTH don't care temporarily*/
+
+ if (band == -1 || regulation == -1 || bandwidth == -1 ||
+ rateSection == -1 || channel == -1) {
+ /*DBG_871X("Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnlGroup %d]\n",*/
+ /* band, regulation, bandwidth, RfPath, rateSection, channelGroup );*/
+
+ return MAX_POWER_INDEX;
+ }
+
+ if (Band == BAND_ON_2_4G) {
+ s8 limits[10] = {0};
+ u8 i = 0;
+
+ if (bandwidth >= MAX_2_4G_BANDWIDTH_NUM)
+ bandwidth = MAX_2_4G_BANDWIDTH_NUM - 1;
+
+ for (i = 0; i < MAX_REGULATION_NUM; ++i)
+ limits[i] = pHalData->TxPwrLimit_2_4G_Original[i][bandwidth][rateSection][channel][RfPath];
+
+ powerLimit = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) :
+ pHalData->TxPwrLimit_2_4G_Original[regulation][bandwidth][rateSection][channel][RfPath];
+
+ } else if (Band == BAND_ON_5G) {
+ s8 limits[10] = {0};
+ u8 i = 0;
+
+ for (i = 0; i < MAX_REGULATION_NUM; ++i)
+ limits[i] = pHalData->TxPwrLimit_5G_Original[i][bandwidth][rateSection][channel][RfPath];
+
+ powerLimit = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) :
+ pHalData->TxPwrLimit_5G_Original[regulation][bandwidth][rateSection][channel][RfPath];
+ } else
+ DBG_871X("No power limit table of the specified band\n");
+
+ /*combine 5G VHT & HT rate*/
+ /*5G 20M and 40M HT and VHT can cross reference*/
+ /*
+ if (Band == BAND_ON_5G && powerLimit == MAX_POWER_INDEX) {
+ if (bandwidth == 0 || bandwidth == 1) {
+ if (rateSection == 2)
+ powerLimit = pHalData->TxPwrLimit_5G_Original[regulation]
+ [bandwidth][4][channelGroup][RfPath];
+ else if (rateSection == 4)
+ powerLimit = pHalData->TxPwrLimit_5G_Original[regulation]
+ [bandwidth][2][channelGroup][RfPath];
+ else if (rateSection == 3)
+ powerLimit = pHalData->TxPwrLimit_5G_Original[regulation]
+ [bandwidth][5][channelGroup][RfPath];
+ else if (rateSection == 5)
+ powerLimit = pHalData->TxPwrLimit_5G_Original[regulation]
+ [bandwidth][3][channelGroup][RfPath];
+ }
+ }
+ */
+ /*DBG_871X("TxPwrLmt[Regulation %d][Band %d][BW %d][RFPath %d][Rate 0x%x][Chnl %d] = %d\n",*/
+ /* regulation, pHalData->current_band_type, Bandwidth, RfPath, DataRate, Channel, powerLimit);*/
+ return powerLimit;
+}
+#endif
+
+static void phy_CrossReferenceHTAndVHTTxPowerLimit(PADAPTER pAdapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ u8 regulation, bw, channel, rs, ref_rs;
+ int ht_ref_vht_5g_20_40 = 0;
+ int vht_ref_ht_5g_20_40 = 0;
+ int ht_has_ref_5g_20_40 = 0;
+ int vht_has_ref_5g_20_40 = 0;
+
+ pHalData->tx_pwr_lmt_5g_20_40_ref = 0;
+
+ for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
+
+ for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
+
+ for (channel = 0; channel < CENTER_CH_5G_ALL_NUM; ++channel) {
+
+ for (rs = 0; rs < MAX_RATE_SECTION_NUM; ++rs) {
+
+ /* 5G 20M 40M VHT and HT can cross reference */
+ if (bw == CHANNEL_WIDTH_20 || bw == CHANNEL_WIDTH_40) {
+ if (rs == HT_1SS)
+ ref_rs = VHT_1SS;
+ else if (rs == HT_2SS)
+ ref_rs = VHT_2SS;
+ else if (rs == HT_3SS)
+ ref_rs = VHT_3SS;
+ else if (rs == HT_4SS)
+ ref_rs = VHT_4SS;
+ else if (rs == VHT_1SS)
+ ref_rs = HT_1SS;
+ else if (rs == VHT_2SS)
+ ref_rs = HT_2SS;
+ else if (rs == VHT_3SS)
+ ref_rs = HT_3SS;
+ else if (rs == VHT_4SS)
+ ref_rs = HT_4SS;
+ else
+ continue;
+
+ if (pHalData->TxPwrLimit_5G[regulation][bw][ref_rs][channel][RF_PATH_A] == MAX_POWER_INDEX)
+ continue;
+
+ if (IS_HT_RATE_SECTION(rs))
+ ht_has_ref_5g_20_40++;
+ else if (IS_VHT_RATE_SECTION(rs))
+ vht_has_ref_5g_20_40++;
+ else
+ continue;
+
+ if (pHalData->TxPwrLimit_5G[regulation][bw][rs][channel][RF_PATH_A] != MAX_POWER_INDEX)
+ continue;
+
+ if (IS_HT_RATE_SECTION(rs) && IS_VHT_RATE_SECTION(ref_rs))
+ ht_ref_vht_5g_20_40++;
+ else if (IS_VHT_RATE_SECTION(rs) && IS_HT_RATE_SECTION(ref_rs))
+ vht_ref_ht_5g_20_40++;
+
+ if (0)
+ RTW_INFO("reg:%u, bw:%u, ch:%u, %s ref %s\n"
+ , regulation, bw, channel
+ , rate_section_str(rs), rate_section_str(ref_rs));
+
+ pHalData->TxPwrLimit_5G[regulation][bw][rs][channel][RF_PATH_A] =
+ pHalData->TxPwrLimit_5G[regulation][bw][ref_rs][channel][RF_PATH_A];
+ }
+
+ }
+ }
+ }
+ }
+
+ if (0) {
+ RTW_INFO("ht_ref_vht_5g_20_40:%d, ht_has_ref_5g_20_40:%d\n", ht_ref_vht_5g_20_40, ht_has_ref_5g_20_40);
+ RTW_INFO("vht_ref_hht_5g_20_40:%d, vht_has_ref_5g_20_40:%d\n", vht_ref_ht_5g_20_40, vht_has_ref_5g_20_40);
+ }
+
+ /* 5G 20M&40M HT all come from VHT*/
+ if (ht_ref_vht_5g_20_40 && ht_has_ref_5g_20_40 == ht_ref_vht_5g_20_40)
+ pHalData->tx_pwr_lmt_5g_20_40_ref |= TX_PWR_LMT_REF_HT_FROM_VHT;
+
+ /* 5G 20M&40M VHT all come from HT*/
+ if (vht_ref_ht_5g_20_40 && vht_has_ref_5g_20_40 == vht_ref_ht_5g_20_40)
+ pHalData->tx_pwr_lmt_5g_20_40_ref |= TX_PWR_LMT_REF_VHT_FROM_HT;
+}
+
+void
+PHY_ConvertTxPowerLimitToPowerIndex(
+ PADAPTER Adapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 base;
+ u8 regulation, bw, channel, rateSection;
+ s8 tempValue = 0, tempPwrLmt = 0;
+ u8 rfPath = 0;
+
+ if (pHalData->odmpriv.phy_reg_pg_value_type != PHY_REG_PG_EXACT_VALUE) {
+ rtw_warn_on(1);
+ return;
+ }
+
+ phy_CrossReferenceHTAndVHTTxPowerLimit(Adapter);
+
+ for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
+
+ for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) {
+
+ for (channel = 0; channel < CENTER_CH_2G_NUM; ++channel) {
+
+ for (rateSection = CCK; rateSection <= HT_4SS; ++rateSection) {
+ tempPwrLmt = pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][RF_PATH_A];
+
+ if (tempPwrLmt != MAX_POWER_INDEX) {
+
+ for (rfPath = RF_PATH_A; rfPath < MAX_RF_PATH; ++rfPath) {
+ base = PHY_GetTxPowerByRateBase(Adapter, BAND_ON_2_4G, rfPath, rate_section_to_tx_num(rateSection), rateSection);
+ tempValue = tempPwrLmt - base;
+ pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][rfPath] = tempValue;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/*
+* PHY_InitTxPowerLimit - Set all hal_data.TxPwrLimit_2_4G, TxPwrLimit_5G array to MAX_POWER_INDEX
+*/
+void
+PHY_InitTxPowerLimit(
+ PADAPTER Adapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 i, j, k, l, m;
+
+ for (i = 0; i < MAX_REGULATION_NUM; ++i)
+ for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j)
+ for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
+ for (m = 0; m < CENTER_CH_2G_NUM; ++m)
+ for (l = 0; l < MAX_RF_PATH; ++l)
+ pHalData->TxPwrLimit_2_4G[i][j][k][m][l] = MAX_POWER_INDEX;
+
+ for (i = 0; i < MAX_REGULATION_NUM; ++i)
+ for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j)
+ for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
+ for (m = 0; m < CENTER_CH_5G_ALL_NUM; ++m)
+ for (l = 0; l < MAX_RF_PATH; ++l)
+ pHalData->TxPwrLimit_5G[i][j][k][m][l] = MAX_POWER_INDEX;
+}
+
+/*
+* phy_set_tx_power_limit - Parsing TX power limit from phydm array, called by odm_ConfigBB_TXPWR_LMT_XXX in phydm
+*/
+void
+phy_set_tx_power_limit(
+ struct PHY_DM_STRUCT *pDM_Odm,
+ u8 *Regulation,
+ u8 *Band,
+ u8 *Bandwidth,
+ u8 *RateSection,
+ u8 *RfPath,
+ u8 *Channel,
+ u8 *PowerLimit
+)
+{
+ PADAPTER Adapter = pDM_Odm->adapter;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 regulation = 0, bandwidth = 0, rateSection = 0, channel;
+ s8 powerLimit = 0, prevPowerLimit, channelIndex;
+
+ if (0)
+ RTW_INFO("Index of power limit table [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s][val %s]\n"
+ , Band, Regulation, Bandwidth, RateSection, RfPath, Channel, PowerLimit);
+
+ if (GetU1ByteIntegerFromStringInDecimal((s8 *)Channel, &channel) == false
+ || GetU1ByteIntegerFromStringInDecimal((s8 *)PowerLimit, &powerLimit) == false
+ ) {
+ RTW_PRINT("Illegal index of power limit table [ch %s][val %s]\n", Channel, PowerLimit);
+ return;
+ }
+
+ powerLimit = powerLimit > MAX_POWER_INDEX ? MAX_POWER_INDEX : powerLimit;
+
+ if (eqNByte(Regulation, (u8 *)("FCC"), 3))
+ regulation = TXPWR_LMT_FCC;
+ else if (eqNByte(Regulation, (u8 *)("MKK"), 3))
+ regulation = TXPWR_LMT_MKK;
+ else if (eqNByte(Regulation, (u8 *)("ETSI"), 4))
+ regulation = TXPWR_LMT_ETSI;
+ else if (eqNByte(Regulation, (u8 *)("WW13"), 4))
+ regulation = TXPWR_LMT_WW;
+ else {
+ RTW_PRINT("unknown regulation:%s", Regulation);
+ return;
+ }
+
+ if (eqNByte(RateSection, (u8 *)("CCK"), 3) && eqNByte(RfPath, (u8 *)("1T"), 2))
+ rateSection = CCK;
+ else if (eqNByte(RateSection, (u8 *)("OFDM"), 4) && eqNByte(RfPath, (u8 *)("1T"), 2))
+ rateSection = OFDM;
+ else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("1T"), 2))
+ rateSection = HT_1SS;
+ else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("2T"), 2))
+ rateSection = HT_2SS;
+ else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("3T"), 2))
+ rateSection = HT_3SS;
+ else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("4T"), 2))
+ rateSection = HT_4SS;
+ else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("1T"), 2))
+ rateSection = VHT_1SS;
+ else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("2T"), 2))
+ rateSection = VHT_2SS;
+ else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("3T"), 2))
+ rateSection = VHT_3SS;
+ else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("4T"), 2))
+ rateSection = VHT_4SS;
+ else {
+ RTW_PRINT("Wrong rate section: (%s,%s)\n", RateSection, RfPath);
+ return;
+ }
+
+ if (eqNByte(Bandwidth, (u8 *)("20M"), 3))
+ bandwidth = CHANNEL_WIDTH_20;
+ else if (eqNByte(Bandwidth, (u8 *)("40M"), 3))
+ bandwidth = CHANNEL_WIDTH_40;
+ else if (eqNByte(Bandwidth, (u8 *)("80M"), 3))
+ bandwidth = CHANNEL_WIDTH_80;
+ else {
+ RTW_PRINT("unknown bandwidth: %s\n", Bandwidth);
+ return;
+ }
+
+ if (eqNByte(Band, (u8 *)("2.4G"), 4)) {
+ 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", Bandwidth);
+ return;
+ }
+
+ prevPowerLimit = pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A];
+
+ if (prevPowerLimit != MAX_POWER_INDEX)
+ RTW_PRINT("duplicate tx power limit combination [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s]\n"
+ , Band, Regulation, Bandwidth, RateSection, RfPath, Channel);
+
+ if (powerLimit < prevPowerLimit)
+ pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A] = powerLimit;
+
+ if (0)
+ RTW_INFO("2.4G Band value : [regulation %d][bw %d][rate_section %d][chnl %d][val %d]\n"
+ , regulation, bandwidth, rateSection, channelIndex, pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][ODM_RF_PATH_A]);
+ } else if (eqNByte(Band, (u8 *)("5G"), 2)) {
+
+ channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_5G, channel);
+
+ if (channelIndex == -1) {
+ RTW_PRINT("unsupported channel: %d at 5G\n", channel);
+ return;
+ }
+
+ prevPowerLimit = pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A];
+
+ if (prevPowerLimit != MAX_POWER_INDEX)
+ RTW_PRINT("duplicate tx power limit combination [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s]\n"
+ , Band, Regulation, Bandwidth, RateSection, RfPath, Channel);
+
+ if (powerLimit < prevPowerLimit)
+ pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A] = powerLimit;
+
+ if (0)
+ RTW_INFO("5G Band value : [regulation %d][bw %d][rate_section %d][chnl %d][val %d]\n"
+ , regulation, bandwidth, rateSection, channel, pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A]);
+ } else {
+ RTW_PRINT("Cannot recognize the band info in %s\n", Band);
+ return;
+ }
+}
+
+u8
+phy_get_tx_power_index(
+ PADAPTER pAdapter,
+ u8 RFPath,
+ u8 Rate,
+ CHANNEL_WIDTH BandWidth,
+ u8 Channel
+)
+{
+ return rtw_hal_get_tx_power_index(pAdapter, RFPath, Rate, BandWidth, Channel, NULL);
+}
+
+void
+PHY_SetTxPowerIndex(
+ PADAPTER pAdapter,
+ u32 PowerIndex,
+ u8 RFPath,
+ u8 Rate
+)
+{
+ if (IS_HARDWARE_TYPE_8188E(pAdapter))
+ PHY_SetTxPowerIndex_8188E(pAdapter, PowerIndex, RFPath, Rate);
+}
+
+void dump_tx_power_idx_title(void *sel, _adapter *adapter)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ u8 bw = hal_data->current_channel_bw;
+
+ RTW_PRINT_SEL(sel, "%s", ch_width_str(bw));
+ if (bw >= CHANNEL_WIDTH_80)
+ _RTW_PRINT_SEL(sel, ", cch80:%u", hal_data->cch_80);
+ if (bw >= CHANNEL_WIDTH_40)
+ _RTW_PRINT_SEL(sel, ", cch40:%u", hal_data->cch_40);
+ _RTW_PRINT_SEL(sel, ", cch20:%u\n", hal_data->cch_20);
+
+ RTW_PRINT_SEL(sel, "%-4s %-9s %-3s %-4s %-3s %-4s %-4s %-3s %-5s\n"
+ , "path", "rate", "pwr", "base", "", "(byr", "lmt)", "tpt", "ebias");
+}
+
+void dump_tx_power_idx_by_path_rs(void *sel, _adapter *adapter, u8 rfpath, u8 rs)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ u8 power_idx;
+ struct txpwr_idx_comp tic;
+ u8 tx_num, i;
+ u8 band = hal_data->current_band_type;
+ u8 cch = hal_data->current_channel;
+ u8 bw = hal_data->current_channel_bw;
+
+ if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, rfpath))
+ return;
+
+ if (rs >= RATE_SECTION_NUM)
+ return;
+
+ tx_num = rate_section_to_tx_num(rs);
+ if (tx_num >= hal_spec->tx_nss_num || tx_num >= hal_spec->max_tx_cnt)
+ return;
+
+ if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
+ return;
+
+ if (IS_VHT_RATE_SECTION(rs))
+ return;
+
+ for (i = 0; i < rates_by_sections[rs].rate_num; i++) {
+ power_idx = rtw_hal_get_tx_power_index(adapter, rfpath, rates_by_sections[rs].rates[i], bw, cch, &tic);
+
+ RTW_PRINT_SEL(sel, "%4c %9s %3u %4u %3d (%3d %3d) %3d %5d\n"
+ , rf_path_char(rfpath), MGN_RATE_STR(rates_by_sections[rs].rates[i])
+ , power_idx, tic.base, (tic.by_rate > tic.limit ? tic.limit : tic.by_rate), tic.by_rate, tic.limit, tic.tpt, tic.ebias);
+ }
+}
+
+void dump_tx_power_idx(void *sel, _adapter *adapter)
+{
+ u8 rfpath, rs;
+
+ dump_tx_power_idx_title(sel, adapter);
+ for (rfpath = RF_PATH_A; rfpath < RF_PATH_MAX; rfpath++)
+ for (rs = CCK; rs < RATE_SECTION_NUM; rs++)
+ dump_tx_power_idx_by_path_rs(sel, adapter, rfpath, rs);
+}
+
+bool phy_is_tx_power_limit_needed(_adapter *adapter)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
+
+ if (regsty->RegEnableTxPowerLimit == 1
+ || (regsty->RegEnableTxPowerLimit == 2 && hal_data->EEPROMRegulatory == 1))
+ return true;
+ return false;
+}
+
+bool phy_is_tx_power_by_rate_needed(_adapter *adapter)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
+
+ if (regsty->RegEnableTxPowerByRate == 1
+ || (regsty->RegEnableTxPowerByRate == 2 && hal_data->EEPROMRegulatory != 2))
+ return true;
+ return false;
+}
+
+int phy_load_tx_power_by_rate(_adapter *adapter, u8 chk_file)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
+ int ret = _FAIL;
+
+ hal_data->txpwr_by_rate_loaded = 0;
+ PHY_InitTxPowerByRate(adapter);
+
+ /* tx power limit is based on tx power by rate */
+ hal_data->txpwr_limit_loaded = 0;
+
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+ if (chk_file
+ && phy_ConfigBBWithPgParaFile(adapter, PHY_FILE_PHY_REG_PG) == _SUCCESS
+ ) {
+ hal_data->txpwr_by_rate_from_file = 1;
+ goto post_hdl;
+ }
+#endif
+
+#ifdef CONFIG_EMBEDDED_FWIMG
+ if (HAL_STATUS_SUCCESS == odm_config_bb_with_header_file(&hal_data->odmpriv, CONFIG_BB_PHY_REG_PG)) {
+ RTW_INFO("default power by rate loaded\n");
+ hal_data->txpwr_by_rate_from_file = 0;
+ goto post_hdl;
+ }
+#endif
+
+ RTW_ERR("%s():Read Tx power by rate fail\n", __func__);
+ goto exit;
+
+post_hdl:
+ if (hal_data->odmpriv.phy_reg_pg_value_type != PHY_REG_PG_EXACT_VALUE) {
+ rtw_warn_on(1);
+ goto exit;
+ }
+
+ PHY_TxPowerByRateConfiguration(adapter);
+ hal_data->txpwr_by_rate_loaded = 1;
+
+ ret = _SUCCESS;
+
+exit:
+ return ret;
+}
+
+int phy_load_tx_power_limit(_adapter *adapter, u8 chk_file)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
+ int ret = _FAIL;
+
+ hal_data->txpwr_limit_loaded = 0;
+ PHY_InitTxPowerLimit(adapter);
+
+ if (!hal_data->txpwr_by_rate_loaded && regsty->target_tx_pwr_valid != true) {
+ RTW_ERR("%s():Read Tx power limit before target tx power is specify\n", __func__);
+ goto exit;
+ }
+
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+ if (chk_file
+ && PHY_ConfigRFWithPowerLimitTableParaFile(adapter, PHY_FILE_TXPWR_LMT) == _SUCCESS
+ ) {
+ hal_data->txpwr_limit_from_file = 1;
+ goto post_hdl;
+ }
+#endif
+
+#ifdef CONFIG_EMBEDDED_FWIMG
+ if (HAL_STATUS_SUCCESS == odm_config_rf_with_header_file(&hal_data->odmpriv, CONFIG_RF_TXPWR_LMT, (enum odm_rf_radio_path_e)0)) {
+ RTW_INFO("default power limit loaded\n");
+ hal_data->txpwr_limit_from_file = 0;
+ goto post_hdl;
+ }
+#endif
+
+ RTW_ERR("%s():Read Tx power limit fail\n", __func__);
+ goto exit;
+
+post_hdl:
+ PHY_ConvertTxPowerLimitToPowerIndex(adapter);
+ hal_data->txpwr_limit_loaded = 1;
+ ret = _SUCCESS;
+
+exit:
+ return ret;
+}
+
+void phy_load_tx_power_ext_info(_adapter *adapter, u8 chk_file)
+{
+ struct registry_priv *regsty = adapter_to_regsty(adapter);
+
+ /* check registy target tx power */
+ regsty->target_tx_pwr_valid = rtw_regsty_chk_target_tx_power_valid(adapter);
+
+ /* power by rate and limit */
+ if (phy_is_tx_power_by_rate_needed(adapter)
+ || (phy_is_tx_power_limit_needed(adapter) && regsty->target_tx_pwr_valid != true)
+ )
+ phy_load_tx_power_by_rate(adapter, chk_file);
+
+ if (phy_is_tx_power_limit_needed(adapter))
+ phy_load_tx_power_limit(adapter, chk_file);
+}
+
+inline void phy_reload_tx_power_ext_info(_adapter *adapter)
+{
+ phy_load_tx_power_ext_info(adapter, 1);
+}
+
+inline void phy_reload_default_tx_power_ext_info(_adapter *adapter)
+{
+ phy_load_tx_power_ext_info(adapter, 0);
+}
+
+void dump_tx_power_ext_info(void *sel, _adapter *adapter)
+{
+ struct registry_priv *regsty = adapter_to_regsty(adapter);
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+
+ if (regsty->target_tx_pwr_valid == true)
+ RTW_PRINT_SEL(sel, "target_tx_power: from registry\n");
+ else if (phy_is_tx_power_by_rate_needed(adapter))
+ RTW_PRINT_SEL(sel, "target_tx_power: from power by rate\n");
+ else
+ RTW_PRINT_SEL(sel, "target_tx_power: unavailable\n");
+
+ RTW_PRINT_SEL(sel, "tx_power_by_rate: %s, %s, %s\n"
+ , phy_is_tx_power_by_rate_needed(adapter) ? "enabled" : "disabled"
+ , hal_data->txpwr_by_rate_loaded ? "loaded" : "unloaded"
+ , hal_data->txpwr_by_rate_from_file ? "file" : "default"
+ );
+
+ RTW_PRINT_SEL(sel, "tx_power_limit: %s, %s, %s\n"
+ , phy_is_tx_power_limit_needed(adapter) ? "enabled" : "disabled"
+ , hal_data->txpwr_limit_loaded ? "loaded" : "unloaded"
+ , hal_data->txpwr_limit_from_file ? "file" : "default"
+ );
+}
+
+void dump_target_tx_power(void *sel, _adapter *adapter)
+{
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ struct registry_priv *regsty = adapter_to_regsty(adapter);
+ int path, tx_num, band, rs;
+ u8 target;
+
+ for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
+ if (!hal_is_band_support(adapter, band))
+ continue;
+
+ for (path = 0; path < RF_PATH_MAX; path++) {
+ if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
+ break;
+
+ RTW_PRINT_SEL(sel, "[%s][%c]%s\n", band_str(band), rf_path_char(path)
+ , (regsty->target_tx_pwr_valid == false && hal_data->txpwr_by_rate_undefined_band_path[band][path]) ? "(dup)" : "");
+
+ for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
+ tx_num = rate_section_to_tx_num(rs);
+ if (tx_num >= hal_spec->tx_nss_num)
+ continue;
+
+ if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
+ continue;
+
+ if (IS_VHT_RATE_SECTION(rs))
+ continue;
+
+ target = PHY_GetTxPowerByRateBase(adapter, band, path, rate_section_to_tx_num(rs), rs);
+
+ if (target % 2)
+ _RTW_PRINT_SEL(sel, "%7s: %2d.5\n", rate_section_str(rs), target / 2);
+ else
+ _RTW_PRINT_SEL(sel, "%7s: %4d\n", rate_section_str(rs), target / 2);
+ }
+ }
+ }
+
+exit:
+ return;
+}
+
+void dump_tx_power_by_rate(void *sel, _adapter *adapter)
+{
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ int path, tx_num, band, n, rs;
+ u8 rate_num, max_rate_num, base;
+ s8 by_rate_offset;
+
+ for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
+ if (!hal_is_band_support(adapter, band))
+ continue;
+
+ for (path = 0; path < RF_PATH_MAX; path++) {
+ if (!HAL_SPEC_CHK_RF_PATH(hal_spec, band, path))
+ break;
+
+ RTW_PRINT_SEL(sel, "[%s][%c]%s\n", band_str(band), rf_path_char(path)
+ , hal_data->txpwr_by_rate_undefined_band_path[band][path] ? "(dup)" : "");
+
+ for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
+ tx_num = rate_section_to_tx_num(rs);
+ if (tx_num >= hal_spec->tx_nss_num)
+ continue;
+
+ if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
+ continue;
+
+ if (IS_VHT_RATE_SECTION(rs))
+ continue;
+
+ max_rate_num = 8;
+ rate_num = rate_section_rate_num(rs);
+ base = PHY_GetTxPowerByRateBase(adapter, band, path, tx_num, rs);
+
+ RTW_PRINT_SEL(sel, "%7s: ", rate_section_str(rs));
+
+ /* dump power by rate in db */
+ for (n = rate_num - 1; n >= 0; n--) {
+ by_rate_offset = PHY_GetTxPowerByRate(adapter, band, path, tx_num, rates_by_sections[rs].rates[n]);
+
+ if ((base + by_rate_offset) % 2)
+ _RTW_PRINT_SEL(sel, "%2d.5 ", (base + by_rate_offset) / 2);
+ else
+ _RTW_PRINT_SEL(sel, "%4d ", (base + by_rate_offset) / 2);
+ }
+ for (n = 0; n < max_rate_num - rate_num; n++)
+ _RTW_PRINT_SEL(sel, "%4s ", "");
+
+ _RTW_PRINT_SEL(sel, "|");
+
+ /* dump power by rate in offset */
+ for (n = rate_num - 1; n >= 0; n--) {
+ by_rate_offset = PHY_GetTxPowerByRate(adapter, band, path, tx_num, rates_by_sections[rs].rates[n]);
+ _RTW_PRINT_SEL(sel, "%3d ", by_rate_offset);
+ }
+ RTW_PRINT_SEL(sel, "\n");
+
+ }
+ }
+ }
+}
+
+void dump_tx_power_limit(void *sel, _adapter *adapter)
+{
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
+
+ int bw, band, ch_num, rs, i, path;
+ u8 ch, n, rd, rfpath_num;
+
+ for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
+ if (!hal_is_band_support(adapter, band))
+ continue;
+
+ rd = (band == BAND_ON_2_4G ? hal_data->Regulation2_4G : hal_data->Regulation5G);
+ rfpath_num = (band == BAND_ON_2_4G ? hal_spec->rfpath_num_2g : hal_spec->rfpath_num_5g);
+
+ for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; bw++) {
+
+ if (bw >= CHANNEL_WIDTH_160)
+ break;
+ if (band == BAND_ON_2_4G && bw >= CHANNEL_WIDTH_80)
+ break;
+
+ if (band == BAND_ON_2_4G)
+ ch_num = CENTER_CH_2G_NUM;
+ else
+ ch_num = center_chs_5g_num(bw);
+
+ if (ch_num == 0) {
+ rtw_warn_on(1);
+ break;
+ }
+
+ for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
+ if (band == BAND_ON_2_4G && IS_VHT_RATE_SECTION(rs))
+ continue;
+ if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs))
+ continue;
+ if (bw > CHANNEL_WIDTH_20 && (IS_CCK_RATE_SECTION(rs) || IS_OFDM_RATE_SECTION(rs)))
+ continue;
+ if (bw > CHANNEL_WIDTH_40 && IS_HT_RATE_SECTION(rs))
+ continue;
+
+ if (rate_section_to_tx_num(rs) >= hal_spec->tx_nss_num)
+ continue;
+
+ if (IS_VHT_RATE_SECTION(rs))
+ continue;
+
+ /* by pass 5G 20M, 40M pure reference */
+ if (band == BAND_ON_5G && (bw == CHANNEL_WIDTH_20 || bw == CHANNEL_WIDTH_40)) {
+ if (hal_data->tx_pwr_lmt_5g_20_40_ref == TX_PWR_LMT_REF_HT_FROM_VHT) {
+ if (IS_HT_RATE_SECTION(rs))
+ continue;
+ } else if (hal_data->tx_pwr_lmt_5g_20_40_ref == TX_PWR_LMT_REF_VHT_FROM_HT) {
+ if (IS_VHT_RATE_SECTION(rs) && bw <= CHANNEL_WIDTH_40)
+ continue;
+ }
+ }
+
+ RTW_PRINT_SEL(sel, "[%s][%s][%s]\n"
+ , band_str(band)
+ , ch_width_str(bw)
+ , rate_section_str(rs)
+ );
+
+ /* header for limit in db */
+ RTW_PRINT_SEL(sel, "%3s %5s %5s %5s %5s "
+ , "ch"
+ , (rd == TXPWR_LMT_FCC ? "*FCC" : "FCC")
+ , (rd == TXPWR_LMT_ETSI ? "*ETSI" : "ETSI")
+ , (rd == TXPWR_LMT_MKK ? "*MKK" : "MKK")
+ , (rd == TXPWR_LMT_WW ? "*WW" : "WW")
+ );
+
+ /* header for limit offset */
+ for (path = 0; path < RF_PATH_MAX; path++) {
+ if (path >= rfpath_num)
+ break;
+ _RTW_PRINT_SEL(sel, "|%3c %3c %3c %3c "
+ , (rd == TXPWR_LMT_FCC ? rf_path_char(path) : ' ')
+ , (rd == TXPWR_LMT_ETSI ? rf_path_char(path) : ' ')
+ , (rd == TXPWR_LMT_MKK ? rf_path_char(path) : ' ')
+ , (rd == TXPWR_LMT_WW ? rf_path_char(path) : ' ')
+ );
+ }
+ _RTW_PRINT_SEL(sel, "\n");
+
+ for (n = 0; n < ch_num; n++) {
+ s8 limit_idx[RF_PATH_MAX][MAX_REGULATION_NUM];
+ s8 limit_offset[MAX_REGULATION_NUM];
+ u8 base;
+
+ if (band == BAND_ON_2_4G)
+ ch = n + 1;
+ else
+ ch = center_chs_5g(bw, n);
+
+ if (ch == 0) {
+ rtw_warn_on(1);
+ break;
+ }
+
+ /* dump limit in db (calculate from path A) */
+ limit_offset[0] = PHY_GetTxPowerLimit_no_sc(adapter, 3, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* FCC */
+ limit_offset[1] = PHY_GetTxPowerLimit_no_sc(adapter, 1, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* ETSI */
+ limit_offset[2] = PHY_GetTxPowerLimit_no_sc(adapter, 2, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* MKK */
+ limit_offset[3] = PHY_GetTxPowerLimit_no_sc(adapter, 4, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* WW */
+
+ base = PHY_GetTxPowerByRateBase(adapter, band, RF_PATH_A, rate_section_to_tx_num(rs), rs);
+
+ RTW_PRINT_SEL(sel, "%3u ", ch);
+ for (i = 0; i < MAX_REGULATION_NUM; i++) {
+ if (limit_offset[i] == MAX_POWER_INDEX) {
+ limit_idx[0][i] = MAX_POWER_INDEX;
+ _RTW_PRINT_SEL(sel, "%5s ", "NA");
+ } else {
+ limit_idx[0][i] = limit_offset[i] + base;
+ if ((limit_offset[i] + base) % 2)
+ _RTW_PRINT_SEL(sel, "%3d.5 ", (limit_offset[i] + base) / 2);
+ else
+ _RTW_PRINT_SEL(sel, "%5d ", (limit_offset[i] + base) / 2);
+ }
+ }
+
+ /* dump limit offset of each path */
+ for (path = 0; path < RF_PATH_MAX; path++) {
+ if (path >= rfpath_num)
+ break;
+ limit_offset[0] = PHY_GetTxPowerLimit_no_sc(adapter, 3, band, bw, path, rates_by_sections[rs].rates[0], ch); /* FCC */
+ limit_offset[1] = PHY_GetTxPowerLimit_no_sc(adapter, 1, band, bw, path, rates_by_sections[rs].rates[0], ch); /* ETSI */
+ limit_offset[2] = PHY_GetTxPowerLimit_no_sc(adapter, 2, band, bw, path, rates_by_sections[rs].rates[0], ch); /* MKK */
+ limit_offset[3] = PHY_GetTxPowerLimit_no_sc(adapter, 4, band, bw, path, rates_by_sections[rs].rates[0], ch); /* WW */
+
+ base = PHY_GetTxPowerByRateBase(adapter, band, path, rate_section_to_tx_num(rs), rs);
+
+ _RTW_PRINT_SEL(sel, "|");
+ for (i = 0; i < MAX_REGULATION_NUM; i++) {
+ if (limit_offset[i] == MAX_POWER_INDEX) {
+ limit_idx[path][i] = MAX_POWER_INDEX;
+ _RTW_PRINT_SEL(sel, "%3s ", "NA");
+ } else {
+ limit_idx[path][i] = limit_offset[i] + base;
+ _RTW_PRINT_SEL(sel, "%3d ", limit_offset[i]);
+ }
+ }
+ }
+
+ /* compare limit_idx of each path, print 'x' when mismatch */
+ if (rfpath_num > 1) {
+ for (i = 0; i < MAX_REGULATION_NUM; i++) {
+ for (path = 0; path < RF_PATH_MAX; path++) {
+ if (path >= rfpath_num)
+ break;
+ if (limit_idx[path][i] != limit_idx[(path + 1) % rfpath_num][i])
+ break;
+ }
+ if (path >= rfpath_num)
+ _RTW_PRINT_SEL(sel, " ");
+ else
+ _RTW_PRINT_SEL(sel, "x");
+ }
+ }
+ _RTW_PRINT_SEL(sel, "\n");
+
+ }
+ RTW_PRINT_SEL(sel, "\n");
+ } /* loop for rate sections */
+ } /* loop for bandwidths */
+ } /* loop for bands */
+}
+
+/*
+ * phy file path is stored in global char array rtw_phy_para_file_path
+ * need to care about racing
+ */
+int rtw_get_phy_file_path(_adapter *adapter, const char *file_name)
+{
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+ int len = 0;
+
+ if (file_name) {
+ len += snprintf(rtw_phy_para_file_path, PATH_LENGTH_MAX, "%s", rtw_phy_file_path);
+ #if defined(CONFIG_MULTIDRV) || defined(REALTEK_CONFIG_PATH_WITH_IC_NAME_FOLDER)
+ len += snprintf(rtw_phy_para_file_path + len, PATH_LENGTH_MAX - len, "%s/", hal_spec->ic_name);
+ #endif
+ len += snprintf(rtw_phy_para_file_path + len, PATH_LENGTH_MAX - len, "%s", file_name);
+
+ return true;
+ }
+#endif
+ return false;
+}
+
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+int
+phy_ConfigMACWithParaFile(
+ PADAPTER Adapter,
+ char *pFileName
+)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
+ int rlen = 0, rtStatus = _FAIL;
+ char *szLine, *ptmp;
+ u32 u4bRegOffset, u4bRegValue, u4bMove;
+
+ if (!(Adapter->registrypriv.load_phy_file & LOAD_MAC_PARA_FILE))
+ return rtStatus;
+
+ memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
+
+ if ((pHalData->mac_reg_len == 0) && (pHalData->mac_reg == NULL)) {
+ rtw_get_phy_file_path(Adapter, pFileName);
+ if (rtw_is_file_readable(rtw_phy_para_file_path) == true) {
+ rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+ if (rlen > 0) {
+ rtStatus = _SUCCESS;
+ pHalData->mac_reg = rtw_zvmalloc(rlen);
+ if (pHalData->mac_reg) {
+ memcpy(pHalData->mac_reg, pHalData->para_file_buf, rlen);
+ pHalData->mac_reg_len = rlen;
+ } else
+ RTW_INFO("%s mac_reg alloc fail !\n", __func__);
+ }
+ }
+ } else {
+ if ((pHalData->mac_reg_len != 0) && (pHalData->mac_reg != NULL)) {
+ memcpy(pHalData->para_file_buf, pHalData->mac_reg, pHalData->mac_reg_len);
+ rtStatus = _SUCCESS;
+ } else
+ RTW_INFO("%s(): Critical Error !!!\n", __func__);
+ }
+
+ if (rtStatus == _SUCCESS) {
+ ptmp = pHalData->para_file_buf;
+ for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
+ if (!IsCommentString(szLine)) {
+ /* Get 1st hex value as register offset */
+ if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
+ if (u4bRegOffset == 0xffff) {
+ /* Ending. */
+ break;
+ }
+
+ /* Get 2nd hex value as register value. */
+ szLine += u4bMove;
+ if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove))
+ rtw_write8(Adapter, u4bRegOffset, (u8)u4bRegValue);
+ }
+ }
+ }
+ } else
+ RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __func__, pFileName);
+
+ return rtStatus;
+}
+
+int
+phy_ConfigBBWithParaFile(
+ PADAPTER Adapter,
+ char *pFileName,
+ u32 ConfigType
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ int rlen = 0, rtStatus = _FAIL;
+ char *szLine, *ptmp;
+ u32 u4bRegOffset, u4bRegValue, u4bMove;
+ char *pBuf = NULL;
+ u32 *pBufLen = NULL;
+
+ if (!(Adapter->registrypriv.load_phy_file & LOAD_BB_PARA_FILE))
+ return rtStatus;
+
+ switch (ConfigType) {
+ case CONFIG_BB_PHY_REG:
+ pBuf = pHalData->bb_phy_reg;
+ pBufLen = &pHalData->bb_phy_reg_len;
+ break;
+ case CONFIG_BB_AGC_TAB:
+ pBuf = pHalData->bb_agc_tab;
+ pBufLen = &pHalData->bb_agc_tab_len;
+ break;
+ default:
+ RTW_INFO("Unknown ConfigType!! %d\r\n", ConfigType);
+ break;
+ }
+
+ memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
+
+ if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) {
+ rtw_get_phy_file_path(Adapter, pFileName);
+ if (rtw_is_file_readable(rtw_phy_para_file_path) == true) {
+ rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+ if (rlen > 0) {
+ rtStatus = _SUCCESS;
+ pBuf = rtw_zvmalloc(rlen);
+ if (pBuf) {
+ memcpy(pBuf, pHalData->para_file_buf, rlen);
+ *pBufLen = rlen;
+
+ switch (ConfigType) {
+ case CONFIG_BB_PHY_REG:
+ pHalData->bb_phy_reg = pBuf;
+ break;
+ case CONFIG_BB_AGC_TAB:
+ pHalData->bb_agc_tab = pBuf;
+ break;
+ }
+ } else
+ RTW_INFO("%s(): ConfigType %d alloc fail !\n", __func__, ConfigType);
+ }
+ }
+ } else {
+ if ((pBufLen != NULL) && (*pBufLen != 0) && (pBuf != NULL)) {
+ memcpy(pHalData->para_file_buf, pBuf, *pBufLen);
+ rtStatus = _SUCCESS;
+ } else
+ RTW_INFO("%s(): Critical Error !!!\n", __func__);
+ }
+
+ if (rtStatus == _SUCCESS) {
+ ptmp = pHalData->para_file_buf;
+ for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
+ if (!IsCommentString(szLine)) {
+ /* Get 1st hex value as register offset. */
+ if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
+ if (u4bRegOffset == 0xffff) {
+ /* Ending. */
+ break;
+ } else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) {
+#ifdef CONFIG_LONG_DELAY_ISSUE
+ rtw_msleep_os(50);
+#else
+ rtw_mdelay_os(50);
+#endif
+ } else if (u4bRegOffset == 0xfd)
+ rtw_mdelay_os(5);
+ else if (u4bRegOffset == 0xfc)
+ rtw_mdelay_os(1);
+ else if (u4bRegOffset == 0xfb)
+ rtw_udelay_os(50);
+ else if (u4bRegOffset == 0xfa)
+ rtw_udelay_os(5);
+ else if (u4bRegOffset == 0xf9)
+ rtw_udelay_os(1);
+
+ /* Get 2nd hex value as register value. */
+ szLine += u4bMove;
+ if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
+ /* RTW_INFO("[BB-ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue); */
+ phy_set_bb_reg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue);
+
+ if (u4bRegOffset == 0xa24)
+ pHalData->odmpriv.rf_calibrate_info.rega24 = u4bRegValue;
+
+ /* Add 1us delay between BB/RF register setting. */
+ rtw_udelay_os(1);
+ }
+ }
+ }
+ }
+ } else
+ RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __func__, pFileName);
+
+ return rtStatus;
+}
+
+static void phy_DecryptBBPgParaFile(PADAPTER Adapter, char *buffer)
+{
+ u32 i = 0, j = 0;
+ u8 map[95] = {0};
+ u8 currentChar;
+ char *BufOfLines, *ptmp;
+
+ /* RTW_INFO("=====>phy_DecryptBBPgParaFile()\n"); */
+ /* 32 the ascii code of the first visable char, 126 the last one */
+ for (i = 0; i < 95; ++i)
+ map[i] = (u8)(94 - i);
+
+ ptmp = buffer;
+ i = 0;
+ for (BufOfLines = GetLineFromBuffer(ptmp); BufOfLines != NULL; BufOfLines = GetLineFromBuffer(ptmp)) {
+ /* RTW_INFO("Encrypted Line: %s\n", BufOfLines); */
+
+ for (j = 0; j < strlen(BufOfLines); ++j) {
+ currentChar = BufOfLines[j];
+
+ if (currentChar == '\0')
+ break;
+
+ currentChar -= (u8)((((i + j) * 3) % 128));
+
+ BufOfLines[j] = map[currentChar - 32] + 32;
+ }
+ /* RTW_INFO("Decrypted Line: %s\n", BufOfLines ); */
+ if (strlen(BufOfLines) != 0)
+ i++;
+ BufOfLines[strlen(BufOfLines)] = '\n';
+ }
+}
+
+static int phy_ParseBBPgParaFile(PADAPTER Adapter, char *buffer)
+{
+ int rtStatus = _SUCCESS;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ char *szLine, *ptmp;
+ u32 u4bRegOffset, u4bRegMask, u4bRegValue;
+ u32 u4bMove;
+ bool firstLine = true;
+ u8 tx_num = 0;
+ u8 band = 0, rf_path = 0;
+
+ /* RTW_INFO("=====>phy_ParseBBPgParaFile()\n"); */
+
+ if (Adapter->registrypriv.RegDecryptCustomFile == 1)
+ phy_DecryptBBPgParaFile(Adapter, buffer);
+
+ ptmp = buffer;
+ for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
+ if (isAllSpaceOrTab(szLine, sizeof(*szLine)))
+ continue;
+
+ if (!IsCommentString(szLine)) {
+ /* Get header info (relative value or exact value) */
+ if (firstLine) {
+ if (eqNByte(szLine, (u8 *)("#[v1]"), 5)) {
+
+ pHalData->odmpriv.phy_reg_pg_version = szLine[3] - '0';
+ /* RTW_INFO("This is a new format PHY_REG_PG.txt\n"); */
+ } else if (eqNByte(szLine, (u8 *)("#[v0]"), 5)) {
+ pHalData->odmpriv.phy_reg_pg_version = szLine[3] - '0';
+ /* RTW_INFO("This is a old format PHY_REG_PG.txt ok\n"); */
+ } else {
+ RTW_INFO("The format in PHY_REG_PG are invalid %s\n", szLine);
+ return _FAIL;
+ }
+
+ if (eqNByte(szLine + 5, (u8 *)("[Exact]#"), 8)) {
+ pHalData->odmpriv.phy_reg_pg_value_type = PHY_REG_PG_EXACT_VALUE;
+ /* RTW_INFO("The values in PHY_REG_PG are exact values ok\n"); */
+ firstLine = false;
+ continue;
+ } else if (eqNByte(szLine + 5, (u8 *)("[Relative]#"), 11)) {
+ pHalData->odmpriv.phy_reg_pg_value_type = PHY_REG_PG_RELATIVE_VALUE;
+ /* RTW_INFO("The values in PHY_REG_PG are relative values ok\n"); */
+ firstLine = false;
+ continue;
+ } else {
+ RTW_INFO("The values in PHY_REG_PG are invalid %s\n", szLine);
+ return _FAIL;
+ }
+ }
+
+ if (pHalData->odmpriv.phy_reg_pg_version == 0) {
+ /* Get 1st hex value as register offset. */
+ if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
+ szLine += u4bMove;
+ if (u4bRegOffset == 0xffff) {
+ /* Ending. */
+ break;
+ }
+
+ /* Get 2nd hex value as register mask. */
+ if (GetHexValueFromString(szLine, &u4bRegMask, &u4bMove))
+ szLine += u4bMove;
+ else
+ return _FAIL;
+
+ if (pHalData->odmpriv.phy_reg_pg_value_type == PHY_REG_PG_RELATIVE_VALUE) {
+ /* Get 3rd hex value as register value. */
+ if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
+ phy_store_tx_power_by_rate(Adapter, 0, 0, 1, u4bRegOffset, u4bRegMask, u4bRegValue);
+ /* RTW_INFO("[ADDR] %03X=%08X Mask=%08x\n", u4bRegOffset, u4bRegValue, u4bRegMask); */
+ } else
+ return _FAIL;
+ } else if (pHalData->odmpriv.phy_reg_pg_value_type == PHY_REG_PG_EXACT_VALUE) {
+ u32 combineValue = 0;
+ u8 integer = 0, fraction = 0;
+
+ if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
+ szLine += u4bMove;
+ else
+ return _FAIL;
+
+ integer *= 2;
+ if (fraction == 5)
+ integer += 1;
+ combineValue |= (((integer / 10) << 4) + (integer % 10));
+ /* RTW_INFO(" %d", integer ); */
+
+ if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
+ szLine += u4bMove;
+ else
+ return _FAIL;
+
+ integer *= 2;
+ if (fraction == 5)
+ integer += 1;
+ combineValue <<= 8;
+ combineValue |= (((integer / 10) << 4) + (integer % 10));
+ /* RTW_INFO(" %d", integer ); */
+
+ if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
+ szLine += u4bMove;
+ else
+ return _FAIL;
+
+ integer *= 2;
+ if (fraction == 5)
+ integer += 1;
+ combineValue <<= 8;
+ combineValue |= (((integer / 10) << 4) + (integer % 10));
+ /* RTW_INFO(" %d", integer ); */
+
+ if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
+ szLine += u4bMove;
+ else
+ return _FAIL;
+
+ integer *= 2;
+ if (fraction == 5)
+ integer += 1;
+ combineValue <<= 8;
+ combineValue |= (((integer / 10) << 4) + (integer % 10));
+ /* RTW_INFO(" %d", integer ); */
+ phy_store_tx_power_by_rate(Adapter, 0, 0, 1, u4bRegOffset, u4bRegMask, combineValue);
+
+ /* RTW_INFO("[ADDR] 0x%3x = 0x%4x\n", u4bRegOffset, combineValue ); */
+ }
+ }
+ } else if (pHalData->odmpriv.phy_reg_pg_version > 0) {
+ u32 index = 0, cnt = 0;
+
+ if (eqNByte(szLine, "0xffff", 6))
+ break;
+
+ if (!eqNByte("#[END]#", szLine, 7)) {
+ /* load the table label info */
+ if (szLine[0] == '#') {
+ index = 0;
+ if (eqNByte(szLine, "#[2.4G]" , 7)) {
+ band = BAND_ON_2_4G;
+ index += 8;
+ } else if (eqNByte(szLine, "#[5G]", 5)) {
+ band = BAND_ON_5G;
+ index += 6;
+ } else {
+ RTW_INFO("Invalid band %s in PHY_REG_PG.txt\n", szLine);
+ return _FAIL;
+ }
+
+ rf_path = szLine[index] - 'A';
+ /* RTW_INFO(" Table label Band %d, RfPath %d\n", band, rf_path ); */
+ } else { /* load rows of tables */
+ if (szLine[1] == '1')
+ tx_num = RF_1TX;
+ else if (szLine[1] == '2')
+ tx_num = RF_2TX;
+ else if (szLine[1] == '3')
+ tx_num = RF_3TX;
+ else if (szLine[1] == '4')
+ tx_num = RF_4TX;
+ else {
+ RTW_INFO("Invalid row in PHY_REG_PG.txt '%c'(%d)\n", szLine[1], szLine[1]);
+ return _FAIL;
+ }
+
+ while (szLine[index] != ']')
+ ++index;
+ ++index;/* skip ] */
+
+ /* Get 2nd hex value as register offset. */
+ szLine += index;
+ if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove))
+ szLine += u4bMove;
+ else
+ return _FAIL;
+
+ /* Get 2nd hex value as register mask. */
+ if (GetHexValueFromString(szLine, &u4bRegMask, &u4bMove))
+ szLine += u4bMove;
+ else
+ return _FAIL;
+
+ if (pHalData->odmpriv.phy_reg_pg_value_type == PHY_REG_PG_RELATIVE_VALUE) {
+ /* Get 3rd hex value as register value. */
+ if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
+ phy_store_tx_power_by_rate(Adapter, band, rf_path, tx_num, u4bRegOffset, u4bRegMask, u4bRegValue);
+ /* RTW_INFO("[ADDR] %03X (tx_num %d) =%08X Mask=%08x\n", u4bRegOffset, tx_num, u4bRegValue, u4bRegMask); */
+ } else
+ return _FAIL;
+ } else if (pHalData->odmpriv.phy_reg_pg_value_type == PHY_REG_PG_EXACT_VALUE) {
+ u32 combineValue = 0;
+ u8 integer = 0, fraction = 0;
+
+ if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
+ szLine += u4bMove;
+ else
+ return _FAIL;
+
+ integer *= 2;
+ if (fraction == 5)
+ integer += 1;
+ combineValue |= (((integer / 10) << 4) + (integer % 10));
+ /* RTW_INFO(" %d", integer ); */
+
+ if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
+ szLine += u4bMove;
+ else
+ return _FAIL;
+
+ integer *= 2;
+ if (fraction == 5)
+ integer += 1;
+ combineValue <<= 8;
+ combineValue |= (((integer / 10) << 4) + (integer % 10));
+ /* RTW_INFO(" %d", integer ); */
+
+ if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
+ szLine += u4bMove;
+ else
+ return _FAIL;
+
+ integer *= 2;
+ if (fraction == 5)
+ integer += 1;
+ combineValue <<= 8;
+ combineValue |= (((integer / 10) << 4) + (integer % 10));
+ /* RTW_INFO(" %d", integer ); */
+
+ if (GetFractionValueFromString(szLine, &integer, &fraction, &u4bMove))
+ szLine += u4bMove;
+ else
+ return _FAIL;
+
+ integer *= 2;
+ if (fraction == 5)
+ integer += 1;
+ combineValue <<= 8;
+ combineValue |= (((integer / 10) << 4) + (integer % 10));
+ /* RTW_INFO(" %d", integer ); */
+ phy_store_tx_power_by_rate(Adapter, band, rf_path, tx_num, u4bRegOffset, u4bRegMask, combineValue);
+
+ /* RTW_INFO("[ADDR] 0x%3x (tx_num %d) = 0x%4x\n", u4bRegOffset, tx_num, combineValue ); */
+ }
+ }
+ }
+ }
+ }
+ }
+ /* RTW_INFO("<=====phy_ParseBBPgParaFile()\n"); */
+ return rtStatus;
+}
+
+int
+phy_ConfigBBWithPgParaFile(
+ PADAPTER Adapter,
+ const char *pFileName)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ int rlen = 0, rtStatus = _FAIL;
+
+ if (!(Adapter->registrypriv.load_phy_file & LOAD_BB_PG_PARA_FILE))
+ return rtStatus;
+
+ memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
+
+ if (pHalData->bb_phy_reg_pg == NULL) {
+ rtw_get_phy_file_path(Adapter, pFileName);
+ if (rtw_is_file_readable(rtw_phy_para_file_path) == true) {
+ rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+ if (rlen > 0) {
+ rtStatus = _SUCCESS;
+ pHalData->bb_phy_reg_pg = rtw_zvmalloc(rlen);
+ if (pHalData->bb_phy_reg_pg) {
+ memcpy(pHalData->bb_phy_reg_pg, pHalData->para_file_buf, rlen);
+ pHalData->bb_phy_reg_pg_len = rlen;
+ } else
+ RTW_INFO("%s bb_phy_reg_pg alloc fail !\n", __func__);
+ }
+ }
+ } else {
+ if ((pHalData->bb_phy_reg_pg_len != 0) && (pHalData->bb_phy_reg_pg != NULL)) {
+ memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len);
+ rtStatus = _SUCCESS;
+ } else
+ RTW_INFO("%s(): Critical Error !!!\n", __func__);
+ }
+
+ if (rtStatus == _SUCCESS) {
+ /* RTW_INFO("phy_ConfigBBWithPgParaFile(): read %s ok\n", pFileName); */
+ phy_ParseBBPgParaFile(Adapter, pHalData->para_file_buf);
+ } else
+ RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __func__, pFileName);
+
+ return rtStatus;
+}
+
+#if (MP_DRIVER == 1)
+
+int
+phy_ConfigBBWithMpParaFile(
+ PADAPTER Adapter,
+ char *pFileName
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ int rlen = 0, rtStatus = _FAIL;
+ char *szLine, *ptmp;
+ u32 u4bRegOffset, u4bRegValue, u4bMove;
+
+ if (!(Adapter->registrypriv.load_phy_file & LOAD_BB_MP_PARA_FILE))
+ return rtStatus;
+
+ memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
+
+ if ((pHalData->bb_phy_reg_mp_len == 0) && (pHalData->bb_phy_reg_mp == NULL)) {
+ rtw_get_phy_file_path(Adapter, pFileName);
+ if (rtw_is_file_readable(rtw_phy_para_file_path) == true) {
+ rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+ if (rlen > 0) {
+ rtStatus = _SUCCESS;
+ pHalData->bb_phy_reg_mp = rtw_zvmalloc(rlen);
+ if (pHalData->bb_phy_reg_mp) {
+ memcpy(pHalData->bb_phy_reg_mp, pHalData->para_file_buf, rlen);
+ pHalData->bb_phy_reg_mp_len = rlen;
+ } else
+ RTW_INFO("%s bb_phy_reg_mp alloc fail !\n", __func__);
+ }
+ }
+ } else {
+ if ((pHalData->bb_phy_reg_mp_len != 0) && (pHalData->bb_phy_reg_mp != NULL)) {
+ memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_mp, pHalData->bb_phy_reg_mp_len);
+ rtStatus = _SUCCESS;
+ } else
+ RTW_INFO("%s(): Critical Error !!!\n", __func__);
+ }
+
+ if (rtStatus == _SUCCESS) {
+ /* RTW_INFO("phy_ConfigBBWithMpParaFile(): read %s ok\n", pFileName); */
+
+ ptmp = pHalData->para_file_buf;
+ for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
+ if (!IsCommentString(szLine)) {
+ /* Get 1st hex value as register offset. */
+ if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
+ if (u4bRegOffset == 0xffff) {
+ /* Ending. */
+ break;
+ } else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) {
+#ifdef CONFIG_LONG_DELAY_ISSUE
+ rtw_msleep_os(50);
+#else
+ rtw_mdelay_os(50);
+#endif
+ } else if (u4bRegOffset == 0xfd)
+ rtw_mdelay_os(5);
+ else if (u4bRegOffset == 0xfc)
+ rtw_mdelay_os(1);
+ else if (u4bRegOffset == 0xfb)
+ rtw_udelay_os(50);
+ else if (u4bRegOffset == 0xfa)
+ rtw_udelay_os(5);
+ else if (u4bRegOffset == 0xf9)
+ rtw_udelay_os(1);
+
+ /* Get 2nd hex value as register value. */
+ szLine += u4bMove;
+ if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
+ /* RTW_INFO("[ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue); */
+ phy_set_bb_reg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue);
+
+ /* Add 1us delay between BB/RF register setting. */
+ rtw_udelay_os(1);
+ }
+ }
+ }
+ }
+ } else
+ RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __func__, pFileName);
+
+ return rtStatus;
+}
+
+#endif
+
+int
+PHY_ConfigRFWithParaFile(
+ PADAPTER Adapter,
+ char *pFileName,
+ u8 eRFPath
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ int rlen = 0, rtStatus = _FAIL;
+ char *szLine, *ptmp;
+ u32 u4bRegOffset, u4bRegValue, u4bMove;
+ u16 i;
+ char *pBuf = NULL;
+ u32 *pBufLen = NULL;
+
+ if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_PARA_FILE))
+ return rtStatus;
+
+ switch (eRFPath) {
+ case ODM_RF_PATH_A:
+ pBuf = pHalData->rf_radio_a;
+ pBufLen = &pHalData->rf_radio_a_len;
+ break;
+ case ODM_RF_PATH_B:
+ pBuf = pHalData->rf_radio_b;
+ pBufLen = &pHalData->rf_radio_b_len;
+ break;
+ default:
+ RTW_INFO("Unknown RF path!! %d\r\n", eRFPath);
+ break;
+ }
+
+ memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
+
+ if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) {
+ rtw_get_phy_file_path(Adapter, pFileName);
+ if (rtw_is_file_readable(rtw_phy_para_file_path) == true) {
+ rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+ if (rlen > 0) {
+ rtStatus = _SUCCESS;
+ pBuf = rtw_zvmalloc(rlen);
+ if (pBuf) {
+ memcpy(pBuf, pHalData->para_file_buf, rlen);
+ *pBufLen = rlen;
+
+ switch (eRFPath) {
+ case ODM_RF_PATH_A:
+ pHalData->rf_radio_a = pBuf;
+ break;
+ case ODM_RF_PATH_B:
+ pHalData->rf_radio_b = pBuf;
+ break;
+ }
+ } else
+ RTW_INFO("%s(): eRFPath=%d alloc fail !\n", __func__, eRFPath);
+ }
+ }
+ } else {
+ if ((pBufLen != NULL) && (*pBufLen != 0) && (pBuf != NULL)) {
+ memcpy(pHalData->para_file_buf, pBuf, *pBufLen);
+ rtStatus = _SUCCESS;
+ } else
+ RTW_INFO("%s(): Critical Error !!!\n", __func__);
+ }
+
+ if (rtStatus == _SUCCESS) {
+ /* RTW_INFO("%s(): read %s successfully\n", __func__, pFileName); */
+
+ ptmp = pHalData->para_file_buf;
+ for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
+ if (!IsCommentString(szLine)) {
+ /* Get 1st hex value as register offset. */
+ if (GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) {
+ if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) {
+ /* Deay specific ms. Only RF configuration require delay. */
+#ifdef CONFIG_LONG_DELAY_ISSUE
+ rtw_msleep_os(50);
+#else
+ rtw_mdelay_os(50);
+#endif
+ } else if (u4bRegOffset == 0xfd) {
+ /* delay_ms(5); */
+ for (i = 0; i < 100; i++)
+ rtw_udelay_os(MAX_STALL_TIME);
+ } else if (u4bRegOffset == 0xfc) {
+ /* delay_ms(1); */
+ for (i = 0; i < 20; i++)
+ rtw_udelay_os(MAX_STALL_TIME);
+ } else if (u4bRegOffset == 0xfb)
+ rtw_udelay_os(50);
+ else if (u4bRegOffset == 0xfa)
+ rtw_udelay_os(5);
+ else if (u4bRegOffset == 0xf9)
+ rtw_udelay_os(1);
+ else if (u4bRegOffset == 0xffff)
+ break;
+
+ /* Get 2nd hex value as register value. */
+ szLine += u4bMove;
+ if (GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) {
+ phy_set_rf_reg(Adapter, eRFPath, u4bRegOffset, bRFRegOffsetMask, u4bRegValue);
+
+ /* Temp add, for frequency lock, if no delay, that may cause */
+ /* frequency shift, ex: 2412MHz => 2417MHz */
+ /* If frequency shift, the following action may works. */
+ /* Fractional-N table in radio_a.txt */
+ /* 0x2a 0x00001 */ /* channel 1 */
+ /* 0x2b 0x00808 frequency divider. */
+ /* 0x2b 0x53333 */
+ /* 0x2c 0x0000c */
+ rtw_udelay_os(1);
+ }
+ }
+ }
+ }
+ } else
+ RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __func__, pFileName);
+
+ return rtStatus;
+}
+
+static void initDeltaSwingIndexTables(
+ PADAPTER Adapter,
+ char *Band,
+ char *Path,
+ char *Sign,
+ char *Channel,
+ char *Rate,
+ char *Data
+)
+{
+#define STR_EQUAL_5G(_band, _path, _sign, _rate, _chnl) \
+ ((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\
+ (strcmp(Rate, _rate) == 0) && (strcmp(Channel, _chnl) == 0)\
+ )
+#define STR_EQUAL_2G(_band, _path, _sign, _rate) \
+ ((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\
+ (strcmp(Rate, _rate) == 0)\
+ )
+
+#define STORE_SWING_TABLE(_array, _iteratedIdx) \
+ do { \
+ for (token = strsep(&Data, delim); token != NULL; token = strsep(&Data, delim)) {\
+ sscanf(token, "%d", &idx);\
+ _array[_iteratedIdx++] = (u8)idx;\
+ } } while (0)\
+
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
+ struct odm_rf_calibration_structure *pRFCalibrateInfo = &(pDM_Odm->rf_calibrate_info);
+ u32 j = 0;
+ char *token;
+ char delim[] = ",";
+ u32 idx = 0;
+
+ /* RTW_INFO("===>initDeltaSwingIndexTables(): Band: %s;\nPath: %s;\nSign: %s;\nChannel: %s;\nRate: %s;\n, Data: %s;\n", */
+ /* Band, Path, Sign, Channel, Rate, Data); */
+
+ if (STR_EQUAL_2G("2G", "A", "+", "CCK"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_p, j);
+ else if (STR_EQUAL_2G("2G", "A", "-", "CCK"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_a_n, j);
+ else if (STR_EQUAL_2G("2G", "B", "+", "CCK"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_p, j);
+ else if (STR_EQUAL_2G("2G", "B", "-", "CCK"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2g_cck_b_n, j);
+ else if (STR_EQUAL_2G("2G", "A", "+", "ALL"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2ga_p, j);
+ else if (STR_EQUAL_2G("2G", "A", "-", "ALL"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2ga_n, j);
+ else if (STR_EQUAL_2G("2G", "B", "+", "ALL"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2gb_p, j);
+ else if (STR_EQUAL_2G("2G", "B", "-", "ALL"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_2gb_n, j);
+ else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "0"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[0], j);
+ else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "0"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[0], j);
+ else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "0"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[0], j);
+ else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "0"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[0], j);
+ else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "1"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[1], j);
+ else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "1"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[1], j);
+ else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "1"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[1], j);
+ else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "1"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[1], j);
+ else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "2"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[2], j);
+ else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "2"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[2], j);
+ else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "2"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[2], j);
+ else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "2"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[2], j);
+ else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "3"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_p[3], j);
+ else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "3"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5ga_n[3], j);
+ else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "3"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_p[3], j);
+ else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "3"))
+ STORE_SWING_TABLE(pRFCalibrateInfo->delta_swing_table_idx_5gb_n[3], j);
+ else
+ RTW_INFO("===>initDeltaSwingIndexTables(): The input is invalid!!\n");
+}
+
+int
+PHY_ConfigRFWithTxPwrTrackParaFile(
+ PADAPTER Adapter,
+ char *pFileName
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
+ struct odm_rf_calibration_structure *pRFCalibrateInfo = &(pDM_Odm->rf_calibrate_info);
+ int rlen = 0, rtStatus = _FAIL;
+ char *szLine, *ptmp;
+ u32 i = 0, j = 0;
+ char c = 0;
+
+ if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_TRACK_PARA_FILE))
+ return rtStatus;
+
+ memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
+
+ if ((pHalData->rf_tx_pwr_track_len == 0) && (pHalData->rf_tx_pwr_track == NULL)) {
+ rtw_get_phy_file_path(Adapter, pFileName);
+ if (rtw_is_file_readable(rtw_phy_para_file_path) == true) {
+ rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+ if (rlen > 0) {
+ rtStatus = _SUCCESS;
+ pHalData->rf_tx_pwr_track = rtw_zvmalloc(rlen);
+ if (pHalData->rf_tx_pwr_track) {
+ memcpy(pHalData->rf_tx_pwr_track, pHalData->para_file_buf, rlen);
+ pHalData->rf_tx_pwr_track_len = rlen;
+ } else
+ RTW_INFO("%s rf_tx_pwr_track alloc fail !\n", __func__);
+ }
+ }
+ } else {
+ if ((pHalData->rf_tx_pwr_track_len != 0) && (pHalData->rf_tx_pwr_track != NULL)) {
+ memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len);
+ rtStatus = _SUCCESS;
+ } else
+ RTW_INFO("%s(): Critical Error !!!\n", __func__);
+ }
+
+ if (rtStatus == _SUCCESS) {
+ /* RTW_INFO("%s(): read %s successfully\n", __func__, pFileName); */
+
+ ptmp = pHalData->para_file_buf;
+ for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
+ if (!IsCommentString(szLine)) {
+ char band[5] = "", path[5] = "", sign[5] = "";
+ char chnl[5] = "", rate[10] = "";
+ char data[300] = ""; /* 100 is too small */
+
+ if (strlen(szLine) < 10 || szLine[0] != '[')
+ continue;
+
+ strncpy(band, szLine + 1, 2);
+ strncpy(path, szLine + 5, 1);
+ strncpy(sign, szLine + 8, 1);
+
+ i = 10; /* szLine+10 */
+ if (!ParseQualifiedString(szLine, &i, rate, '[', ']')) {
+ /* RTW_INFO("Fail to parse rate!\n"); */
+ }
+ if (!ParseQualifiedString(szLine, &i, chnl, '[', ']')) {
+ /* RTW_INFO("Fail to parse channel group!\n"); */
+ }
+ while (szLine[i] != '{' && i < strlen(szLine))
+ i++;
+ if (!ParseQualifiedString(szLine, &i, data, '{', '}')) {
+ /* RTW_INFO("Fail to parse data!\n"); */
+ }
+
+ initDeltaSwingIndexTables(Adapter, band, path, sign, chnl, rate, data);
+ }
+ }
+ } else
+ RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __func__, pFileName);
+ return rtStatus;
+}
+
+static int phy_ParsePowerLimitTableFile(
+ PADAPTER Adapter,
+ char *buffer
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &(pHalData->odmpriv);
+ u32 i = 0, forCnt = 0;
+ u8 loadingStage = 0, limitValue = 0, fraction = 0;
+ char *szLine, *ptmp;
+ int rtStatus = _SUCCESS;
+ char band[10], bandwidth[10], rateSection[10],
+ regulation[TXPWR_LMT_MAX_REGULATION_NUM][10], rfPath[10], colNumBuf[10];
+ u8 colNum = 0;
+
+ RTW_INFO("===>phy_ParsePowerLimitTableFile()\n");
+
+ if (Adapter->registrypriv.RegDecryptCustomFile == 1)
+ phy_DecryptBBPgParaFile(Adapter, buffer);
+
+ ptmp = buffer;
+ for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) {
+ if (isAllSpaceOrTab(szLine, sizeof(*szLine)))
+ continue;
+
+ /* skip comment */
+ if (IsCommentString(szLine))
+ continue;
+
+ if (loadingStage == 0) {
+ for (forCnt = 0; forCnt < TXPWR_LMT_MAX_REGULATION_NUM; ++forCnt)
+ memset((void *) regulation[forCnt], 0, 10);
+ memset((void *) band, 0, 10);
+ memset((void *) bandwidth, 0, 10);
+ memset((void *) rateSection, 0, 10);
+ memset((void *) rfPath, 0, 10);
+ memset((void *) colNumBuf, 0, 10);
+
+ if (szLine[0] != '#' || szLine[1] != '#')
+ continue;
+
+ /* skip the space */
+ i = 2;
+ while (szLine[i] == ' ' || szLine[i] == '\t')
+ ++i;
+
+ szLine[--i] = ' '; /* return the space in front of the regulation info */
+
+ /* Parse the label of the table */
+ if (!ParseQualifiedString(szLine, &i, band, ' ', ',')) {
+ RTW_INFO("Fail to parse band!\n");
+ return _FAIL;
+ }
+ if (!ParseQualifiedString(szLine, &i, bandwidth, ' ', ',')) {
+ RTW_INFO("Fail to parse bandwidth!\n");
+ return _FAIL;
+ }
+ if (!ParseQualifiedString(szLine, &i, rfPath, ' ', ',')) {
+ RTW_INFO("Fail to parse rf path!\n");
+ return _FAIL;
+ }
+ if (!ParseQualifiedString(szLine, &i, rateSection, ' ', ',')) {
+ RTW_INFO("Fail to parse rate!\n");
+ return _FAIL;
+ }
+
+ loadingStage = 1;
+ } else if (loadingStage == 1) {
+ if (szLine[0] != '#' || szLine[1] != '#')
+ continue;
+
+ /* skip the space */
+ i = 2;
+ while (szLine[i] == ' ' || szLine[i] == '\t')
+ ++i;
+
+ if (!eqNByte((u8 *)(szLine + i), (u8 *)("START"), 5)) {
+ RTW_INFO("Lost \"## START\" label\n");
+ return _FAIL;
+ }
+
+ loadingStage = 2;
+ } else if (loadingStage == 2) {
+ if (szLine[0] != '#' || szLine[1] != '#')
+ continue;
+
+ /* skip the space */
+ i = 2;
+ while (szLine[i] == ' ' || szLine[i] == '\t')
+ ++i;
+
+ if (!ParseQualifiedString(szLine, &i, colNumBuf, '#', '#')) {
+ RTW_INFO("Fail to parse column number!\n");
+ return _FAIL;
+ }
+
+ if (!GetU1ByteIntegerFromStringInDecimal(colNumBuf, &colNum))
+ return _FAIL;
+
+ if (colNum > TXPWR_LMT_MAX_REGULATION_NUM) {
+ RTW_INFO("unvalid col number %d (greater than max %d)\n",
+ colNum, TXPWR_LMT_MAX_REGULATION_NUM);
+ return _FAIL;
+ }
+
+ for (forCnt = 0; forCnt < colNum; ++forCnt) {
+ u8 regulation_name_cnt = 0;
+
+ /* skip the space */
+ while (szLine[i] == ' ' || szLine[i] == '\t')
+ ++i;
+
+ while (szLine[i] != ' ' && szLine[i] != '\t' && szLine[i] != '\0')
+ regulation[forCnt][regulation_name_cnt++] = szLine[i++];
+ /* RTW_INFO("regulation %s!\n", regulation[forCnt]); */
+
+ if (regulation_name_cnt == 0) {
+ RTW_INFO("unvalid number of regulation!\n");
+ return _FAIL;
+ }
+ }
+
+ loadingStage = 3;
+ } else if (loadingStage == 3) {
+ char channel[10] = {0}, powerLimit[10] = {0};
+ u8 cnt = 0;
+
+ /* the table ends */
+ if (szLine[0] == '#' && szLine[1] == '#') {
+ i = 2;
+ while (szLine[i] == ' ' || szLine[i] == '\t')
+ ++i;
+
+ if (eqNByte((u8 *)(szLine + i), (u8 *)("END"), 3)) {
+ loadingStage = 0;
+ continue;
+ } else {
+ RTW_INFO("Wrong format\n");
+ RTW_INFO("<===== phy_ParsePowerLimitTableFile()\n");
+ return _FAIL;
+ }
+ }
+
+ if ((szLine[0] != 'c' && szLine[0] != 'C') ||
+ (szLine[1] != 'h' && szLine[1] != 'H')) {
+ RTW_INFO("Meet wrong channel => power limt pair '%c','%c'(%d,%d)\n", szLine[0], szLine[1], szLine[0], szLine[1]);
+ continue;
+ }
+ i = 2;/* move to the location behind 'h' */
+
+ /* load the channel number */
+ cnt = 0;
+ while (szLine[i] >= '0' && szLine[i] <= '9') {
+ channel[cnt] = szLine[i];
+ ++cnt;
+ ++i;
+ }
+ /* RTW_INFO("chnl %s!\n", channel); */
+
+ for (forCnt = 0; forCnt < colNum; ++forCnt) {
+ /* skip the space between channel number and the power limit value */
+ while (szLine[i] == ' ' || szLine[i] == '\t')
+ ++i;
+
+ /* load the power limit value */
+ cnt = 0;
+ fraction = 0;
+ memset((void *) powerLimit, 0, 10);
+ while ((szLine[i] >= '0' && szLine[i] <= '9') || szLine[i] == '.') {
+ if (szLine[i] == '.') {
+ if ((szLine[i + 1] >= '0' && szLine[i + 1] <= '9')) {
+ fraction = szLine[i + 1];
+ i += 2;
+ } else {
+ RTW_INFO("Wrong fraction in TXPWR_LMT.txt\n");
+ return _FAIL;
+ }
+
+ break;
+ }
+
+ powerLimit[cnt] = szLine[i];
+ ++cnt;
+ ++i;
+ }
+
+ if (powerLimit[0] == '\0') {
+ powerLimit[0] = '6';
+ powerLimit[1] = '3';
+ i += 2;
+ } else {
+ if (!GetU1ByteIntegerFromStringInDecimal(powerLimit, &limitValue))
+ return _FAIL;
+
+ limitValue *= 2;
+ cnt = 0;
+ if (fraction == '5')
+ ++limitValue;
+
+ /* the value is greater or equal to 100 */
+ if (limitValue >= 100) {
+ powerLimit[cnt++] = limitValue / 100 + '0';
+ limitValue %= 100;
+
+ if (limitValue >= 10) {
+ powerLimit[cnt++] = limitValue / 10 + '0';
+ limitValue %= 10;
+ } else
+ powerLimit[cnt++] = '0';
+
+ powerLimit[cnt++] = limitValue + '0';
+ }
+ /* the value is greater or equal to 10 */
+ else if (limitValue >= 10) {
+ powerLimit[cnt++] = limitValue / 10 + '0';
+ limitValue %= 10;
+ powerLimit[cnt++] = limitValue + '0';
+ }
+ /* the value is less than 10 */
+ else
+ powerLimit[cnt++] = limitValue + '0';
+
+ powerLimit[cnt] = '\0';
+ }
+
+ /* RTW_INFO("ch%s => %s\n", channel, powerLimit); */
+
+ /* store the power limit value */
+ phy_set_tx_power_limit(pDM_Odm, (u8 *)regulation[forCnt], (u8 *)band,
+ (u8 *)bandwidth, (u8 *)rateSection, (u8 *)rfPath, (u8 *)channel, (u8 *)powerLimit);
+
+ }
+ } else {
+ RTW_INFO("Abnormal loading stage in phy_ParsePowerLimitTableFile()!\n");
+ rtStatus = _FAIL;
+ break;
+ }
+ }
+
+ RTW_INFO("<===phy_ParsePowerLimitTableFile()\n");
+ return rtStatus;
+}
+
+int
+PHY_ConfigRFWithPowerLimitTableParaFile(
+ PADAPTER Adapter,
+ const char *pFileName
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ int rlen = 0, rtStatus = _FAIL;
+
+ if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_LMT_PARA_FILE))
+ return rtStatus;
+
+ memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN);
+
+ if (pHalData->rf_tx_pwr_lmt == NULL) {
+ rtw_get_phy_file_path(Adapter, pFileName);
+ if (rtw_is_file_readable(rtw_phy_para_file_path) == true) {
+ rlen = rtw_retrieve_from_file(rtw_phy_para_file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN);
+ if (rlen > 0) {
+ rtStatus = _SUCCESS;
+ pHalData->rf_tx_pwr_lmt = rtw_zvmalloc(rlen);
+ if (pHalData->rf_tx_pwr_lmt) {
+ memcpy(pHalData->rf_tx_pwr_lmt, pHalData->para_file_buf, rlen);
+ pHalData->rf_tx_pwr_lmt_len = rlen;
+ } else
+ RTW_INFO("%s rf_tx_pwr_lmt alloc fail !\n", __func__);
+ }
+ }
+ } else {
+ if ((pHalData->rf_tx_pwr_lmt_len != 0) && (pHalData->rf_tx_pwr_lmt != NULL)) {
+ memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len);
+ rtStatus = _SUCCESS;
+ } else
+ RTW_INFO("%s(): Critical Error !!!\n", __func__);
+ }
+
+ if (rtStatus == _SUCCESS) {
+ /* RTW_INFO("%s(): read %s ok\n", __func__, pFileName); */
+ rtStatus = phy_ParsePowerLimitTableFile(Adapter, pHalData->para_file_buf);
+ } else
+ RTW_INFO("%s(): No File %s, Load from HWImg Array!\n", __func__, pFileName);
+
+ return rtStatus;
+}
+
+void phy_free_filebuf_mask(_adapter *padapter, u8 mask)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ if (pHalData->mac_reg && (mask & LOAD_MAC_PARA_FILE)) {
+ rtw_vmfree(pHalData->mac_reg, pHalData->mac_reg_len);
+ pHalData->mac_reg = NULL;
+ }
+ if (mask & LOAD_BB_PARA_FILE) {
+ if (pHalData->bb_phy_reg) {
+ rtw_vmfree(pHalData->bb_phy_reg, pHalData->bb_phy_reg_len);
+ pHalData->bb_phy_reg = NULL;
+ }
+ if (pHalData->bb_agc_tab) {
+ rtw_vmfree(pHalData->bb_agc_tab, pHalData->bb_agc_tab_len);
+ pHalData->bb_agc_tab = NULL;
+ }
+ }
+ if (pHalData->bb_phy_reg_pg && (mask & LOAD_BB_PG_PARA_FILE)) {
+ rtw_vmfree(pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len);
+ pHalData->bb_phy_reg_pg = NULL;
+ }
+ if (pHalData->bb_phy_reg_mp && (mask & LOAD_BB_MP_PARA_FILE)) {
+ rtw_vmfree(pHalData->bb_phy_reg_mp, pHalData->bb_phy_reg_mp_len);
+ pHalData->bb_phy_reg_mp = NULL;
+ }
+ if (mask & LOAD_RF_PARA_FILE) {
+ if (pHalData->rf_radio_a) {
+ rtw_vmfree(pHalData->rf_radio_a, pHalData->rf_radio_a_len);
+ pHalData->rf_radio_a = NULL;
+ }
+ if (pHalData->rf_radio_b) {
+ rtw_vmfree(pHalData->rf_radio_b, pHalData->rf_radio_b_len);
+ pHalData->rf_radio_b = NULL;
+ }
+ }
+ if (pHalData->rf_tx_pwr_track && (mask & LOAD_RF_TXPWR_TRACK_PARA_FILE)) {
+ rtw_vmfree(pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len);
+ pHalData->rf_tx_pwr_track = NULL;
+ }
+ if (pHalData->rf_tx_pwr_lmt && (mask & LOAD_RF_TXPWR_LMT_PARA_FILE)) {
+ rtw_vmfree(pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len);
+ pHalData->rf_tx_pwr_lmt = NULL;
+ }
+}
+
+inline void phy_free_filebuf(_adapter *padapter)
+{
+ phy_free_filebuf_mask(padapter, 0xFF);
+}
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/hal_dm.c b/drivers/staging/rtl8188eu/hal/hal_dm.c
new file mode 100644
index 000000000000..b7dfd4fe40bd
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal_dm.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#include <drv_types.h>
+#include <hal_data.h>
+
+/* A mapping from HalData to ODM. */
+static enum odm_board_type_e boardType(u8 InterfaceSel)
+{
+ enum odm_board_type_e board = ODM_BOARD_DEFAULT;
+
+ INTERFACE_SELECT_USB usb = (INTERFACE_SELECT_USB)InterfaceSel;
+ switch (usb) {
+ case INTF_SEL1_USB_High_Power:
+ board |= ODM_BOARD_EXT_LNA;
+ board |= ODM_BOARD_EXT_PA;
+ break;
+ case INTF_SEL2_MINICARD:
+ board |= ODM_BOARD_MINICARD;
+ break;
+ case INTF_SEL4_USB_Combo:
+ board |= ODM_BOARD_BT;
+ break;
+ case INTF_SEL5_USB_Combo_MF:
+ board |= ODM_BOARD_BT;
+ break;
+ case INTF_SEL0_USB:
+ case INTF_SEL3_USB_Solo:
+ default:
+ board = ODM_BOARD_DEFAULT;
+ break;
+ }
+ return board;
+}
+
+void Init_ODM_ComInfo(_adapter *adapter)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &(pHalData->odmpriv);
+ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
+ int i;
+
+ memset(pDM_Odm, 0, sizeof(*pDM_Odm));
+
+ pDM_Odm->adapter = adapter;
+
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_PLATFORM, ODM_CE);
+
+ rtw_odm_init_ic_type(adapter);
+
+ if (rtw_get_intf_type(adapter) == RTW_GSPI)
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_INTERFACE, ODM_ITRF_SDIO);
+ else
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_INTERFACE, rtw_get_intf_type(adapter));
+
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_MP_TEST_CHIP, IS_NORMAL_CHIP(pHalData->version_id));
+
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_PATCH_ID, pHalData->CustomerID);
+
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_BWIFI_TEST, adapter->registrypriv.wifi_spec);
+
+
+ if (pHalData->rf_type == RF_1T1R)
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_1T1R);
+ else if (pHalData->rf_type == RF_1T2R)
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_1T2R);
+ else if (pHalData->rf_type == RF_2T2R)
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T2R);
+ else if (pHalData->rf_type == RF_2T2R_GREEN)
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T2R_GREEN);
+ else if (pHalData->rf_type == RF_2T3R)
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T3R);
+ else if (pHalData->rf_type == RF_2T4R)
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T4R);
+ else if (pHalData->rf_type == RF_3T3R)
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_3T3R);
+ else if (pHalData->rf_type == RF_3T4R)
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_3T4R);
+ else if (pHalData->rf_type == RF_4T4R)
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_4T4R);
+ else
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_XTXR);
+
+
+ {
+ /* 1 ======= BoardType: ODM_CMNINFO_BOARD_TYPE ======= */
+ u8 odm_board_type = ODM_BOARD_DEFAULT;
+
+ if (pHalData->ExternalLNA_2G != 0) {
+ odm_board_type |= ODM_BOARD_EXT_LNA;
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_EXT_LNA, 1);
+ }
+ if (pHalData->external_lna_5g != 0) {
+ odm_board_type |= ODM_BOARD_EXT_LNA_5G;
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_5G_EXT_LNA, 1);
+ }
+ if (pHalData->ExternalPA_2G != 0) {
+ odm_board_type |= ODM_BOARD_EXT_PA;
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_EXT_PA, 1);
+ }
+ if (pHalData->external_pa_5g != 0) {
+ odm_board_type |= ODM_BOARD_EXT_PA_5G;
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_5G_EXT_PA, 1);
+ }
+ if (pHalData->EEPROMBluetoothCoexist)
+ odm_board_type |= ODM_BOARD_BT;
+
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_BOARD_TYPE, odm_board_type);
+ /* 1 ============== End of BoardType ============== */
+ }
+
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_DOMAIN_CODE_2G, pHalData->Regulation2_4G);
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_DOMAIN_CODE_5G, pHalData->Regulation5G);
+
+#ifdef CONFIG_DFS_MASTER
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_DFS_REGION_DOMAIN, adapter->registrypriv.dfs_region_domain);
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_DFS_MASTER_ENABLE, &(adapter_to_rfctl(adapter)->dfs_master_enabled));
+#endif
+
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_GPA, pHalData->TypeGPA);
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_APA, pHalData->TypeAPA);
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_GLNA, pHalData->TypeGLNA);
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_ALNA, pHalData->TypeALNA);
+
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_RFE_TYPE, pHalData->rfe_type);
+
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_EXT_TRSW, 0);
+
+ /*Add by YuChen for kfree init*/
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_REGRFKFREEENABLE, adapter->registrypriv.RegPwrTrimEnable);
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_RFKFREEENABLE, pHalData->RfKFreeEnable);
+
+ /*Antenna diversity relative parameters*/
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_ANT_DIV, &(pHalData->AntDivCfg));
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_RF_ANTENNA_TYPE, pHalData->TRxAntDivType);
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_BE_FIX_TX_ANT, pHalData->b_fix_tx_ant);
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_WITH_EXT_ANTENNA_SWITCH, pHalData->with_extenal_ant_switch);
+
+ /*Add by YuChen for adaptivity init*/
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_ADAPTIVITY, &(adapter->registrypriv.adaptivity_en));
+ phydm_adaptivity_info_init(pDM_Odm, PHYDM_ADAPINFO_CARRIER_SENSE_ENABLE, (adapter->registrypriv.adaptivity_mode != 0) ? true : false);
+ phydm_adaptivity_info_init(pDM_Odm, PHYDM_ADAPINFO_DCBACKOFF, adapter->registrypriv.adaptivity_dc_backoff);
+ phydm_adaptivity_info_init(pDM_Odm, PHYDM_ADAPINFO_DYNAMICLINKADAPTIVITY, (adapter->registrypriv.adaptivity_dml != 0) ? true : false);
+ phydm_adaptivity_info_init(pDM_Odm, PHYDM_ADAPINFO_TH_L2H_INI, adapter->registrypriv.adaptivity_th_l2h_ini);
+ phydm_adaptivity_info_init(pDM_Odm, PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF, adapter->registrypriv.adaptivity_th_edcca_hl_diff);
+
+#ifdef CONFIG_IQK_PA_OFF
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_IQKPAOFF, 1);
+#endif
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_IQKFWOFFLOAD, pHalData->RegIQKFWOffload);
+
+ /* Pointer reference */
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_TX_UNI, &(dvobj->traffic_stat.tx_bytes));
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_RX_UNI, &(dvobj->traffic_stat.rx_bytes));
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_WM_MODE, &(pmlmeext->cur_wireless_mode));
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_BAND, &(pHalData->current_band_type));
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_FORCED_RATE, &(pHalData->ForcedDataRate));
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_FORCED_IGI_LB, &(pHalData->u1ForcedIgiLb));
+
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_SEC_CHNL_OFFSET, &(pHalData->nCur40MhzPrimeSC));
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_SEC_MODE, &(adapter->securitypriv.dot11PrivacyAlgrthm));
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_BW, &(pHalData->current_channel_bw));
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_CHNL, &(pHalData->current_channel));
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_NET_CLOSED, &(adapter->net_closed));
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_FORCED_IGI_LB, &(pHalData->u1ForcedIgiLb));
+
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_SCAN, &(pmlmepriv->bScanInProcess));
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_POWER_SAVING, &(pwrctl->bpower_saving));
+ /*Add by Yuchen for phydm beamforming*/
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_TX_TP, &(dvobj->traffic_stat.cur_tx_tp));
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_RX_TP, &(dvobj->traffic_stat.cur_rx_tp));
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_ANT_TEST, &(pHalData->antenna_test));
+ odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_HUBUSBMODE, &(dvobj->usb_speed));
+ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++)
+ odm_cmn_info_ptr_array_hook(pDM_Odm, ODM_CMNINFO_STA_STATUS, i, NULL);
+
+ phydm_init_debug_setting(pDM_Odm);
+
+ /* TODO */
+ /* odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_BT_OPERATION, false); */
+ /* odm_cmn_info_hook(pDM_Odm, ODM_CMNINFO_BT_DISABLE_EDCA, false); */
+}
diff --git a/drivers/staging/rtl8188eu/hal/hal_dm.h b/drivers/staging/rtl8188eu/hal/hal_dm.h
new file mode 100644
index 000000000000..7f6e9928288e
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal_dm.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#ifndef __HAL_DM_H__
+#define __HAL_DM_H__
+
+void Init_ODM_ComInfo(_adapter *adapter);
+
+#endif /* __HAL_DM_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/hal_intf.c b/drivers/staging/rtl8188eu/hal/hal_intf.c
new file mode 100644
index 000000000000..2ca6e68f4edd
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal_intf.c
@@ -0,0 +1,1279 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#define _HAL_INTF_C_
+
+#include <drv_types.h>
+#include <hal_data.h>
+
+const u32 _chip_type_to_odm_ic_type[] = {
+ 0,
+ ODM_RTL8188E,
+ ODM_RTL8192E,
+ ODM_RTL8812,
+ ODM_RTL8821,
+ ODM_RTL8723B,
+ ODM_RTL8814A,
+ ODM_RTL8703B,
+ ODM_RTL8188F,
+ ODM_RTL8822B,
+ ODM_RTL8723D,
+ ODM_RTL8821C,
+ 0,
+};
+
+void rtw_hal_chip_configure(_adapter *padapter)
+{
+ padapter->hal_func.intf_chip_configure(padapter);
+}
+
+/*
+ * Description:
+ * Read chip internal ROM data
+ *
+ * Return:
+ * _SUCCESS success
+ * _FAIL fail
+ */
+u8 rtw_hal_read_chip_info(_adapter *padapter)
+{
+ u8 rtn = _SUCCESS;
+ u8 hci_type = rtw_get_intf_type(padapter);
+ u32 start = jiffies;
+
+ /* before access eFuse, make sure card enable has been called */
+ if ((hci_type == RTW_SDIO || hci_type == RTW_GSPI)
+ && !rtw_is_hw_init_completed(padapter))
+ rtw_hal_power_on(padapter);
+
+ rtn = padapter->hal_func.read_adapter_info(padapter);
+
+ if ((hci_type == RTW_SDIO || hci_type == RTW_GSPI)
+ && !rtw_is_hw_init_completed(padapter))
+ rtw_hal_power_off(padapter);
+
+ RTW_INFO("%s in %d ms\n", __func__, rtw_get_passing_time_ms(start));
+
+ return rtn;
+}
+
+void rtw_hal_read_chip_version(_adapter *padapter)
+{
+ padapter->hal_func.read_chip_version(padapter);
+ rtw_odm_init_ic_type(padapter);
+}
+
+void rtw_hal_def_value_init(_adapter *padapter)
+{
+ if (is_primary_adapter(padapter)) {
+ padapter->hal_func.init_default_value(padapter);
+
+ rtw_init_hal_com_default_value(padapter);
+
+ {
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
+
+ /* hal_spec is ready here */
+ dvobj->macid_ctl.num = rtw_min(hal_spec->macid_num, MACID_NUM_SW_LIMIT);
+
+ dvobj->cam_ctl.sec_cap = hal_spec->sec_cap;
+ dvobj->cam_ctl.num = rtw_min(hal_spec->sec_cam_ent_num, SEC_CAM_ENT_NUM_SW_LIMIT);
+ }
+ }
+}
+
+u8 rtw_hal_data_init(_adapter *padapter)
+{
+ if (is_primary_adapter(padapter)) {
+ padapter->hal_data_sz = sizeof(HAL_DATA_TYPE);
+ padapter->HalData = rtw_zvmalloc(padapter->hal_data_sz);
+ if (padapter->HalData == NULL) {
+ RTW_INFO("cant not alloc memory for HAL DATA\n");
+ return _FAIL;
+ }
+ }
+ return _SUCCESS;
+}
+
+void rtw_hal_data_deinit(_adapter *padapter)
+{
+ if (is_primary_adapter(padapter)) {
+ if (padapter->HalData) {
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+ phy_free_filebuf(padapter);
+#endif
+ rtw_vmfree(padapter->HalData, padapter->hal_data_sz);
+ padapter->HalData = NULL;
+ padapter->hal_data_sz = 0;
+ }
+ }
+}
+
+void rtw_hal_free_data(_adapter *padapter)
+{
+ /* free HAL Data */
+ rtw_hal_data_deinit(padapter);
+}
+void rtw_hal_dm_init(_adapter *padapter)
+{
+ if (is_primary_adapter(padapter)) {
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+
+ padapter->hal_func.dm_init(padapter);
+
+ spin_lock_init(&pHalData->IQKSpinLock);
+
+ phy_load_tx_power_ext_info(padapter, 1);
+ }
+}
+void rtw_hal_dm_deinit(_adapter *padapter)
+{
+ if (is_primary_adapter(padapter)) {
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+
+ padapter->hal_func.dm_deinit(padapter);
+ }
+}
+
+void rtw_hal_sw_led_init(_adapter *padapter)
+{
+ if (padapter->hal_func.InitSwLeds)
+ padapter->hal_func.InitSwLeds(padapter);
+}
+
+void rtw_hal_sw_led_deinit(_adapter *padapter)
+{
+ if (padapter->hal_func.DeInitSwLeds)
+ padapter->hal_func.DeInitSwLeds(padapter);
+}
+
+u32 rtw_hal_power_on(_adapter *padapter)
+{
+ return padapter->hal_func.hal_power_on(padapter);
+}
+void rtw_hal_power_off(_adapter *padapter)
+{
+ struct macid_ctl_t *macid_ctl = &padapter->dvobj->macid_ctl;
+
+ memset(macid_ctl->h2c_msr, 0, MACID_NUM_SW_LIMIT);
+
+ padapter->hal_func.hal_power_off(padapter);
+}
+
+
+static void rtw_hal_init_opmode(_adapter *padapter)
+{
+ NDIS_802_11_NETWORK_INFRASTRUCTURE networkType = Ndis802_11InfrastructureMax;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ sint fw_state;
+
+ fw_state = get_fwstate(pmlmepriv);
+
+ if (fw_state & WIFI_ADHOC_STATE)
+ networkType = Ndis802_11IBSS;
+ else if (fw_state & WIFI_STATION_STATE)
+ networkType = Ndis802_11Infrastructure;
+ else if (fw_state & WIFI_AP_STATE)
+ networkType = Ndis802_11APMode;
+ else
+ return;
+
+ rtw_setopmode_cmd(padapter, networkType, false);
+}
+
+uint rtw_hal_init(_adapter *padapter)
+{
+ uint status = _SUCCESS;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+ int i;
+
+ status = padapter->hal_func.hal_init(padapter);
+
+ if (status == _SUCCESS) {
+ pHalData->hw_init_completed = true;
+ rtw_restore_mac_addr(padapter);
+
+ if (padapter->registrypriv.notch_filter == 1)
+ rtw_hal_notch_filter(padapter, 1);
+
+ for (i = 0; i < dvobj->iface_nums; i++)
+ rtw_sec_restore_wep_key(dvobj->padapters[i]);
+
+ rtw_led_control(padapter, LED_CTL_POWER_ON);
+
+ init_hw_mlme_ext(padapter);
+
+ rtw_hal_init_opmode(padapter);
+
+#ifdef CONFIG_RF_POWER_TRIM
+ rtw_bb_rf_gain_offset(padapter);
+#endif /*CONFIG_RF_POWER_TRIM*/
+
+ } else {
+ pHalData->hw_init_completed = false;
+ RTW_INFO("rtw_hal_init: hal_init fail\n");
+ }
+
+
+ return status;
+
+}
+
+uint rtw_hal_deinit(_adapter *padapter)
+{
+ uint status = _SUCCESS;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+ int i;
+
+ status = padapter->hal_func.hal_deinit(padapter);
+
+ if (status == _SUCCESS) {
+ rtw_led_control(padapter, LED_CTL_POWER_OFF);
+ pHalData->hw_init_completed = false;
+ } else
+ RTW_INFO("\n rtw_hal_deinit: hal_init fail\n");
+
+
+ return status;
+}
+
+void rtw_hal_set_hwreg(_adapter *padapter, u8 variable, u8 *val)
+{
+ padapter->hal_func.set_hw_reg_handler(padapter, variable, val);
+}
+
+void rtw_hal_get_hwreg(_adapter *padapter, u8 variable, u8 *val)
+{
+ padapter->hal_func.GetHwRegHandler(padapter, variable, val);
+}
+
+u8 rtw_hal_set_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, void * pValue)
+{
+ return padapter->hal_func.SetHalDefVarHandler(padapter, eVariable, pValue);
+}
+u8 rtw_hal_get_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, void * pValue)
+{
+ return padapter->hal_func.get_hal_def_var_handler(padapter, eVariable, pValue);
+}
+
+void rtw_hal_set_odm_var(_adapter *padapter, HAL_ODM_VARIABLE eVariable, void * pValue1, bool bSet)
+{
+ padapter->hal_func.SetHalODMVarHandler(padapter, eVariable, pValue1, bSet);
+}
+void rtw_hal_get_odm_var(_adapter *padapter, HAL_ODM_VARIABLE eVariable, void * pValue1, void * pValue2)
+{
+ padapter->hal_func.GetHalODMVarHandler(padapter, eVariable, pValue1, pValue2);
+}
+
+/* FOR SDIO & PCIE */
+void rtw_hal_enable_interrupt(_adapter *padapter)
+{
+}
+
+/* FOR SDIO & PCIE */
+void rtw_hal_disable_interrupt(_adapter *padapter)
+{
+}
+
+u8 rtw_hal_check_ips_status(_adapter *padapter)
+{
+ u8 val = false;
+ if (padapter->hal_func.check_ips_status)
+ val = padapter->hal_func.check_ips_status(padapter);
+ else
+ RTW_INFO("%s: hal_func.check_ips_status is NULL!\n", __func__);
+
+ return val;
+}
+
+s32 rtw_hal_fw_dl(_adapter *padapter, u8 wowlan)
+{
+ return padapter->hal_func.fw_dl(padapter, wowlan);
+}
+
+#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
+void rtw_hal_clear_interrupt(_adapter *padapter)
+{
+}
+#endif
+
+u32 rtw_hal_inirp_init(_adapter *padapter)
+{
+ if (is_primary_adapter(padapter))
+ return padapter->hal_func.inirp_init(padapter);
+ return _SUCCESS;
+}
+u32 rtw_hal_inirp_deinit(_adapter *padapter)
+{
+
+ if (is_primary_adapter(padapter))
+ return padapter->hal_func.inirp_deinit(padapter);
+
+ return _SUCCESS;
+}
+
+/* for USB Auto-suspend */
+u8 rtw_hal_intf_ps_func(_adapter *padapter, HAL_INTF_PS_FUNC efunc_id, u8 *val)
+{
+ if (padapter->hal_func.interface_ps_func)
+ return padapter->hal_func.interface_ps_func(padapter, efunc_id, val);
+ return _FAIL;
+}
+
+s32 rtw_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
+{
+ return padapter->hal_func.hal_xmitframe_enqueue(padapter, pxmitframe);
+}
+
+s32 rtw_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
+{
+ return padapter->hal_func.hal_xmit(padapter, pxmitframe);
+}
+
+/*
+ * [IMPORTANT] This function would be run in interrupt context.
+ */
+s32 rtw_hal_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
+{
+ s32 ret = _FAIL;
+ u8 *pframe, subtype;
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ struct sta_info *psta;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+
+ update_mgntframe_attrib_addr(padapter, pmgntframe);
+ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
+ subtype = get_frame_sub_type(pframe); /* bit(7)~bit(2) */
+
+ /* pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; */
+ /* memcpy(pmgntframe->attrib.ra, pwlanhdr->addr1, ETH_ALEN); */
+
+#ifdef CONFIG_IEEE80211W
+ if (padapter->securitypriv.binstallBIPkey == true && (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC ||
+ subtype == WIFI_ACTION)) {
+ if (IS_MCAST(pmgntframe->attrib.ra) && pmgntframe->attrib.key_type != IEEE80211W_NO_KEY) {
+ pmgntframe->attrib.encrypt = _BIP_;
+ /* pmgntframe->attrib.bswenc = true; */
+ } else if (pmgntframe->attrib.key_type != IEEE80211W_NO_KEY) {
+ psta = rtw_get_stainfo(pstapriv, pmgntframe->attrib.ra);
+ if (psta && psta->bpairwise_key_installed == true) {
+ pmgntframe->attrib.encrypt = _AES_;
+ pmgntframe->attrib.bswenc = true;
+ } else {
+ RTW_INFO("%s, %d, bpairwise_key_installed is false\n", __func__, __LINE__);
+ goto no_mgmt_coalesce;
+ }
+ }
+ RTW_INFO("encrypt=%d, bswenc=%d\n", pmgntframe->attrib.encrypt, pmgntframe->attrib.bswenc);
+ rtw_mgmt_xmitframe_coalesce(padapter, pmgntframe->pkt, pmgntframe);
+ }
+#endif /* CONFIG_IEEE80211W */
+no_mgmt_coalesce:
+ ret = padapter->hal_func.mgnt_xmit(padapter, pmgntframe);
+ return ret;
+}
+
+s32 rtw_hal_init_xmit_priv(_adapter *padapter)
+{
+ return padapter->hal_func.init_xmit_priv(padapter);
+}
+void rtw_hal_free_xmit_priv(_adapter *padapter)
+{
+ padapter->hal_func.free_xmit_priv(padapter);
+}
+
+s32 rtw_hal_init_recv_priv(_adapter *padapter)
+{
+ return padapter->hal_func.init_recv_priv(padapter);
+}
+void rtw_hal_free_recv_priv(_adapter *padapter)
+{
+ padapter->hal_func.free_recv_priv(padapter);
+}
+
+void rtw_update_ramask(_adapter *padapter, struct sta_info *psta, u32 mac_id, u8 rssi_level, u8 is_update_bw)
+{
+ struct macid_cfg h2c_macid_cfg;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
+ u8 disable_cck_rate = false, MimoPs_enable = false;
+ u32 ratr_bitmap_msb = 0, ratr_bitmap_lsb = 0;
+ u64 mask = 0, rate_bitmap = 0;
+ u8 bw, short_gi;
+
+ if (psta == NULL) {
+ RTW_ERR(FUNC_ADPT_FMT" macid:%u, sta is NULL\n", FUNC_ADPT_ARG(padapter), mac_id);
+ rtw_warn_on(1);
+ return;
+ }
+ memset(&h2c_macid_cfg, 0, sizeof(struct macid_cfg));
+
+ bw = rtw_get_tx_bw_mode(padapter, psta);
+ short_gi = query_ra_short_GI(psta, bw);
+
+ ratr_bitmap_msb = (u32)(psta->ra_mask >> 32);
+ ratr_bitmap_lsb = (u32)(psta->ra_mask);
+
+ phydm_update_hal_ra_mask(&hal_data->odmpriv, psta->wireless_mode, hal_data->rf_type, bw, MimoPs_enable, disable_cck_rate, &ratr_bitmap_msb, &ratr_bitmap_lsb, rssi_level);
+ mask = (((u64)ratr_bitmap_msb) << 32) | ((u64)ratr_bitmap_lsb);
+
+
+#ifdef CONFIG_BT_COEXIST
+ if (hal_data->EEPROMBluetoothCoexist == 1) {
+ rate_bitmap = rtw_btcoex_GetRaMask(padapter);
+ mask &= ~rate_bitmap;
+ }
+#endif /* CONFIG_BT_COEXIST */
+
+#ifdef CONFIG_CMCC_TEST
+#ifdef CONFIG_BT_COEXIST
+ if (pmlmeext->cur_wireless_mode & WIRELESS_11G) {
+ if (mac_id == 0) {
+ RTW_INFO("CMCC_BT update raid entry, mask=0x%x\n", mask);
+ /*mask &=0xffffffc0; //disable CCK & <12M OFDM rate for 11G mode for CMCC */
+ mask &= 0xffffff00; /*disable CCK & <24M OFDM rate for 11G mode for CMCC */
+ RTW_INFO("CMCC_BT update raid entry, mask=0x%x\n", mask);
+ }
+ }
+#endif
+#endif
+
+ /*set correct initial date rate for each mac_id */
+ hal_data->INIDATA_RATE[mac_id] = psta->init_rate;
+
+
+ RTW_INFO("%s => mac_id:%d, networkType:0x%02x, mask:0x%016llx\n\t ==> rssi_level:%d, rate_bitmap:0x%016llx, shortGIrate=%d\n\t ==> bw:%d, ignore_bw:0x%d\n",
+ __func__, mac_id, psta->wireless_mode, mask, rssi_level, rate_bitmap, short_gi, bw, (!is_update_bw));
+
+ rtw_macid_ctl_set_bw(macid_ctl, mac_id, bw);
+ rtw_macid_ctl_set_vht_en(macid_ctl, mac_id, is_supported_vht(psta->wireless_mode));
+ rtw_macid_ctl_set_rate_bmp0(macid_ctl, mac_id, mask);
+ rtw_macid_ctl_set_rate_bmp1(macid_ctl, mac_id, mask >> 32);
+ rtw_update_tx_rate_bmp(adapter_to_dvobj(padapter));
+
+ h2c_macid_cfg.mac_id = mac_id;
+ h2c_macid_cfg.rate_id = psta->raid;
+ h2c_macid_cfg.bandwidth = bw;
+ h2c_macid_cfg.ignore_bw = (!is_update_bw);
+ h2c_macid_cfg.short_gi = short_gi;
+ h2c_macid_cfg.ra_mask = mask;
+
+ padapter->hal_func.update_ra_mask_handler(padapter, psta, &h2c_macid_cfg);
+}
+
+void rtw_hal_update_ra_mask(struct sta_info *psta, u8 rssi_level, u8 is_update_bw)
+{
+ _adapter *padapter;
+ struct mlme_priv *pmlmepriv;
+
+ if (!psta)
+ return;
+
+ padapter = psta->padapter;
+
+ pmlmepriv = &(padapter->mlmepriv);
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
+ add_RATid(padapter, psta, rssi_level, is_update_bw);
+ else {
+ psta->raid = rtw_hal_networktype_to_raid(padapter, psta);
+ rtw_update_ramask(padapter, psta, psta->mac_id, rssi_level, is_update_bw);
+ }
+}
+
+/* Start specifical interface thread */
+void rtw_hal_start_thread(_adapter *padapter)
+{
+}
+/* Start specifical interface thread */
+void rtw_hal_stop_thread(_adapter *padapter)
+{
+}
+
+u32 rtw_hal_read_bbreg(_adapter *padapter, u32 RegAddr, u32 BitMask)
+{
+ u32 data = 0;
+ if (padapter->hal_func.read_bbreg)
+ data = padapter->hal_func.read_bbreg(padapter, RegAddr, BitMask);
+ return data;
+}
+void rtw_hal_write_bbreg(_adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data)
+{
+ if (padapter->hal_func.write_bbreg)
+ padapter->hal_func.write_bbreg(padapter, RegAddr, BitMask, Data);
+}
+
+u32 rtw_hal_read_rfreg(_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask)
+{
+ u32 data = 0;
+
+ if (padapter->hal_func.read_rfreg) {
+ data = padapter->hal_func.read_rfreg(padapter, eRFPath, RegAddr, BitMask);
+
+ if (match_rf_read_sniff_ranges(eRFPath, RegAddr, BitMask)) {
+ RTW_INFO("DBG_IO rtw_hal_read_rfreg(%u, 0x%04x, 0x%08x) read:0x%08x(0x%08x)\n"
+ , eRFPath, RegAddr, BitMask, (data << PHY_CalculateBitShift(BitMask)), data);
+ }
+ }
+
+ return data;
+}
+
+void rtw_hal_write_rfreg(_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask, u32 Data)
+{
+ if (padapter->hal_func.write_rfreg) {
+
+ if (match_rf_write_sniff_ranges(eRFPath, RegAddr, BitMask)) {
+ RTW_INFO("DBG_IO rtw_hal_write_rfreg(%u, 0x%04x, 0x%08x) write:0x%08x(0x%08x)\n"
+ , eRFPath, RegAddr, BitMask, (Data << PHY_CalculateBitShift(BitMask)), Data);
+ }
+
+ padapter->hal_func.write_rfreg(padapter, eRFPath, RegAddr, BitMask, Data);
+
+ }
+}
+
+#if defined(CONFIG_SUPPORT_USB_INT)
+void rtw_hal_interrupt_handler(_adapter *padapter, u16 pkt_len, u8 *pbuf)
+{
+ padapter->hal_func.interrupt_handler(padapter, pkt_len, pbuf);
+}
+#endif
+
+void rtw_hal_set_chnl_bw(_adapter *padapter, u8 channel, CHANNEL_WIDTH Bandwidth, u8 Offset40, u8 Offset80)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &(pHalData->odmpriv);
+ u8 cch_160 = Bandwidth == CHANNEL_WIDTH_160 ? channel : 0;
+ u8 cch_80 = Bandwidth == CHANNEL_WIDTH_80 ? channel : 0;
+ u8 cch_40 = Bandwidth == CHANNEL_WIDTH_40 ? channel : 0;
+ u8 cch_20 = Bandwidth == CHANNEL_WIDTH_20 ? channel : 0;
+
+ odm_acquire_spin_lock(pDM_Odm, RT_IQK_SPINLOCK);
+ if (pDM_Odm->rf_calibrate_info.is_iqk_in_progress == true)
+ RTW_ERR("%s, %d, IQK may race condition\n", __func__, __LINE__);
+ odm_release_spin_lock(pDM_Odm, RT_IQK_SPINLOCK);
+
+ /* MP mode channel don't use secondary channel */
+ if (rtw_mi_mp_mode_check(padapter) == false) {
+ if (cch_80 != 0)
+ cch_40 = rtw_get_scch_by_cch_offset(cch_80, CHANNEL_WIDTH_80, Offset80);
+ if (cch_40 != 0)
+ cch_20 = rtw_get_scch_by_cch_offset(cch_40, CHANNEL_WIDTH_40, Offset40);
+ }
+
+ pHalData->cch_80 = cch_80;
+ pHalData->cch_40 = cch_40;
+ pHalData->cch_20 = cch_20;
+
+ if (0)
+ RTW_INFO("%s cch:%u, %s, offset40:%u, offset80:%u (%u, %u, %u)\n", __func__
+ , channel, ch_width_str(Bandwidth), Offset40, Offset80
+ , pHalData->cch_80, pHalData->cch_40, pHalData->cch_20);
+
+ padapter->hal_func.set_chnl_bw_handler(padapter, channel, Bandwidth, Offset40, Offset80);
+}
+
+void rtw_hal_set_tx_power_level(_adapter *padapter, u8 channel)
+{
+ if (padapter->hal_func.set_tx_power_level_handler)
+ padapter->hal_func.set_tx_power_level_handler(padapter, channel);
+}
+
+void rtw_hal_get_tx_power_level(_adapter *padapter, s32 *powerlevel)
+{
+ if (padapter->hal_func.get_tx_power_level_handler)
+ padapter->hal_func.get_tx_power_level_handler(padapter, powerlevel);
+}
+
+void rtw_hal_dm_watchdog(_adapter *padapter)
+{
+#ifdef CONFIG_MCC_MODE
+ if (MCC_EN(padapter)) {
+ if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC))
+ return;
+ }
+#endif /* CONFIG_MCC_MODE */
+
+ padapter->hal_func.hal_dm_watchdog(padapter);
+
+}
+
+#ifdef CONFIG_LPS_LCLK_WD_TIMER
+void rtw_hal_dm_watchdog_in_lps(_adapter *padapter)
+{
+#if defined(CONFIG_CONCURRENT_MODE)
+#ifndef CONFIG_FW_MULTI_PORT_SUPPORT
+ if (padapter->hw_port != HW_PORT0)
+ return;
+#endif
+#endif
+
+ if (adapter_to_pwrctl(padapter)->bFwCurrentInPSMode == true) {
+ padapter->hal_func.hal_dm_watchdog_in_lps(padapter);/* this function caller is in interrupt context */
+ }
+}
+#endif
+
+void rtw_hal_bcn_related_reg_setting(_adapter *padapter)
+{
+ padapter->hal_func.SetBeaconRelatedRegistersHandler(padapter);
+}
+
+#ifdef CONFIG_HOSTAPD_MLME
+s32 rtw_hal_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
+{
+ if (padapter->hal_func.hostap_mgnt_xmit_entry)
+ return padapter->hal_func.hostap_mgnt_xmit_entry(padapter, pkt);
+ return _FAIL;
+}
+#endif /* CONFIG_HOSTAPD_MLME */
+
+#ifdef DBG_CONFIG_ERROR_DETECT
+void rtw_hal_sreset_init(_adapter *padapter)
+{
+ padapter->hal_func.sreset_init_value(padapter);
+}
+void rtw_hal_sreset_reset(_adapter *padapter)
+{
+ padapter = GET_PRIMARY_ADAPTER(padapter);
+ padapter->hal_func.silentreset(padapter);
+}
+
+void rtw_hal_sreset_reset_value(_adapter *padapter)
+{
+ padapter->hal_func.sreset_reset_value(padapter);
+}
+
+void rtw_hal_sreset_xmit_status_check(_adapter *padapter)
+{
+ padapter->hal_func.sreset_xmit_status_check(padapter);
+}
+void rtw_hal_sreset_linked_status_check(_adapter *padapter)
+{
+ padapter->hal_func.sreset_linked_status_check(padapter);
+}
+u8 rtw_hal_sreset_get_wifi_status(_adapter *padapter)
+{
+ return padapter->hal_func.sreset_get_wifi_status(padapter);
+}
+
+bool rtw_hal_sreset_inprogress(_adapter *padapter)
+{
+ padapter = GET_PRIMARY_ADAPTER(padapter);
+ return padapter->hal_func.sreset_inprogress(padapter);
+}
+#endif /* DBG_CONFIG_ERROR_DETECT */
+
+#ifdef CONFIG_IOL
+int rtw_hal_iol_cmd(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_waiting_ms, u32 bndy_cnt)
+{
+ if (adapter->hal_func.IOL_exec_cmds_sync)
+ return adapter->hal_func.IOL_exec_cmds_sync(adapter, xmit_frame, max_waiting_ms, bndy_cnt);
+ return _FAIL;
+}
+#endif
+
+#ifdef CONFIG_XMIT_THREAD_MODE
+s32 rtw_hal_xmit_thread_handler(_adapter *padapter)
+{
+ return padapter->hal_func.xmit_thread_handler(padapter);
+}
+#endif
+
+#ifdef CONFIG_RECV_THREAD_MODE
+s32 rtw_hal_recv_hdl(_adapter *adapter)
+{
+ return adapter->hal_func.recv_hdl(adapter);
+}
+#endif
+
+void rtw_hal_notch_filter(_adapter *adapter, bool enable)
+{
+ if (adapter->hal_func.hal_notch_filter)
+ adapter->hal_func.hal_notch_filter(adapter, enable);
+}
+
+#ifdef CONFIG_FW_C2H_REG
+inline bool rtw_hal_c2h_valid(_adapter *adapter, u8 *buf)
+{
+ HAL_DATA_TYPE *HalData = GET_HAL_DATA(adapter);
+ HAL_VERSION *hal_ver = &HalData->version_id;
+ bool ret = _FAIL;
+
+ ret = C2H_ID_88XX(buf) || C2H_PLEN_88XX(buf);
+
+ return ret;
+}
+
+inline s32 rtw_hal_c2h_evt_read(_adapter *adapter, u8 *buf)
+{
+ HAL_DATA_TYPE *HalData = GET_HAL_DATA(adapter);
+ HAL_VERSION *hal_ver = &HalData->version_id;
+ s32 ret = _FAIL;
+
+ ret = c2h_evt_read_88xx(adapter, buf);
+
+ return ret;
+}
+
+bool rtw_hal_c2h_reg_hdr_parse(_adapter *adapter, u8 *buf, u8 *id, u8 *seq, u8 *plen, u8 **payload)
+{
+ HAL_DATA_TYPE *HalData = GET_HAL_DATA(adapter);
+ HAL_VERSION *hal_ver = &HalData->version_id;
+ bool ret = _FAIL;
+
+ *id = C2H_ID_88XX(buf);
+ *seq = C2H_SEQ_88XX(buf);
+ *plen = C2H_PLEN_88XX(buf);
+ *payload = C2H_PAYLOAD_88XX(buf);
+ ret = _SUCCESS;
+
+ return ret;
+}
+#endif /* CONFIG_FW_C2H_REG */
+
+#ifdef CONFIG_FW_C2H_PKT
+bool rtw_hal_c2h_pkt_hdr_parse(_adapter *adapter, u8 *buf, u16 len, u8 *id, u8 *seq, u8 *plen, u8 **payload)
+{
+ HAL_DATA_TYPE *HalData = GET_HAL_DATA(adapter);
+ HAL_VERSION *hal_ver = &HalData->version_id;
+ bool ret = _FAIL;
+
+ if (!buf || len > 256 || len < 3)
+ goto exit;
+
+ *id = C2H_ID_88XX(buf);
+ *seq = C2H_SEQ_88XX(buf);
+ *plen = len - 2;
+ *payload = C2H_PAYLOAD_88XX(buf);
+ ret = _SUCCESS;
+
+exit:
+ return ret;
+}
+#endif /* CONFIG_FW_C2H_PKT */
+
+s32 c2h_handler(_adapter *adapter, u8 id, u8 seq, u8 plen, u8 *payload)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+ struct PHY_DM_STRUCT *odm = &hal_data->odmpriv;
+ u8 sub_id = 0;
+ s32 ret = _SUCCESS;
+
+ switch (id) {
+ case C2H_DBG:
+ RTW_INFO_DUMP("C2H_DBG: ", payload, plen);
+ break;
+ case C2H_FW_SCAN_COMPLETE:
+ RTW_INFO("[C2H], FW Scan Complete\n");
+ break;
+#ifdef CONFIG_BT_COEXIST
+ case C2H_BT_INFO:
+ rtw_btcoex_BtInfoNotify(adapter, plen, payload);
+ break;
+ case C2H_BT_MP_INFO:
+ rtw_btcoex_BtMpRptNotify(adapter, plen, payload);
+ break;
+ case C2H_MAILBOX_STATUS:
+ RTW_INFO_DUMP("C2H_MAILBOX_STATUS: ", payload, plen);
+ break;
+#endif /* CONFIG_BT_COEXIST */
+ case C2H_IQK_FINISH:
+ c2h_iqk_offload(adapter, payload, plen);
+ break;
+#if defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW)
+ case C2H_FW_CHNL_SWITCH_COMPLETE:
+ rtw_tdls_chsw_oper_done(adapter);
+ break;
+ case C2H_BCN_EARLY_RPT:
+ rtw_tdls_ch_sw_back_to_base_chnl(adapter);
+ break;
+#endif
+#ifdef CONFIG_MCC_MODE
+ case C2H_MCC:
+ rtw_hal_mcc_c2h_handler(adapter, plen, payload);
+ break;
+#endif
+
+#ifdef CONFIG_RTW_MAC_HIDDEN_RPT
+ case C2H_MAC_HIDDEN_RPT:
+ c2h_mac_hidden_rpt_hdl(adapter, payload, plen);
+ break;
+ case C2H_MAC_HIDDEN_RPT_2:
+ c2h_mac_hidden_rpt_2_hdl(adapter, payload, plen);
+ break;
+#endif
+
+ case C2H_DEFEATURE_DBG:
+ c2h_defeature_dbg_hdl(adapter, payload, plen);
+ break;
+
+#ifdef CONFIG_RTW_CUSTOMER_STR
+ case C2H_CUSTOMER_STR_RPT:
+ c2h_customer_str_rpt_hdl(adapter, payload, plen);
+ break;
+ case C2H_CUSTOMER_STR_RPT_2:
+ c2h_customer_str_rpt_2_hdl(adapter, payload, plen);
+ break;
+#endif
+
+ case C2H_EXTEND:
+ sub_id = payload[0];
+ __attribute__ ((__fallthrough__));/* FALL THRU */
+ default:
+ if (phydm_c2H_content_parsing(odm, id, plen, payload) != true)
+ ret = _FAIL;
+ break;
+ }
+
+exit:
+ if (ret != _SUCCESS) {
+ if (id == C2H_EXTEND)
+ RTW_WARN("%s: unknown C2H(0x%02x, 0x%02x)\n", __func__, id, sub_id);
+ else
+ RTW_WARN("%s: unknown C2H(0x%02x)\n", __func__, id);
+ }
+
+ return ret;
+}
+
+#ifndef RTW_HALMAC
+s32 rtw_hal_c2h_handler(_adapter *adapter, u8 id, u8 seq, u8 plen, u8 *payload)
+{
+ s32 ret = _FAIL;
+
+ ret = adapter->hal_func.c2h_handler(adapter, id, seq, plen, payload);
+ if (ret != _SUCCESS)
+ ret = c2h_handler(adapter, id, seq, plen, payload);
+
+ return ret;
+}
+
+s32 rtw_hal_c2h_id_handle_directly(_adapter *adapter, u8 id, u8 seq, u8 plen, u8 *payload)
+{
+ switch (id) {
+ case C2H_CCX_TX_RPT:
+ case C2H_BT_MP_INFO:
+ case C2H_FW_CHNL_SWITCH_COMPLETE:
+ case C2H_IQK_FINISH:
+ case C2H_MCC:
+ case C2H_BCN_EARLY_RPT:
+ case C2H_AP_REQ_TXRPT:
+ case C2H_SPC_STAT:
+ return true;
+ default:
+ return false;
+ }
+}
+#endif /* !RTW_HALMAC */
+
+s32 rtw_hal_is_disable_sw_channel_plan(PADAPTER padapter)
+{
+ return GET_HAL_DATA(padapter)->bDisableSWChannelPlan;
+}
+
+s32 rtw_hal_macid_sleep(PADAPTER padapter, u8 macid)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
+ u8 support;
+
+ support = false;
+ rtw_hal_get_def_var(padapter, HAL_DEF_MACID_SLEEP, &support);
+ if (false == support)
+ return _FAIL;
+
+ if (macid >= macid_ctl->num) {
+ RTW_ERR(FUNC_ADPT_FMT": Invalid macid(%u)\n",
+ FUNC_ADPT_ARG(padapter), macid);
+ return _FAIL;
+ }
+
+ rtw_hal_set_hwreg(padapter, HW_VAR_MACID_SLEEP, &macid);
+
+ return _SUCCESS;
+}
+
+s32 rtw_hal_macid_wakeup(PADAPTER padapter, u8 macid)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
+ u8 support;
+
+ support = false;
+ rtw_hal_get_def_var(padapter, HAL_DEF_MACID_SLEEP, &support);
+ if (false == support)
+ return _FAIL;
+
+ if (macid >= macid_ctl->num) {
+ RTW_ERR(FUNC_ADPT_FMT": Invalid macid(%u)\n",
+ FUNC_ADPT_ARG(padapter), macid);
+ return _FAIL;
+ }
+
+ rtw_hal_set_hwreg(padapter, HW_VAR_MACID_WAKEUP, &macid);
+
+ return _SUCCESS;
+}
+
+s32 rtw_hal_fill_h2c_cmd(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer)
+{
+ _adapter *pri_adapter = GET_PRIMARY_ADAPTER(padapter);
+
+ if (pri_adapter->bFWReady == true)
+ return padapter->hal_func.fill_h2c_cmd(padapter, ElementID, CmdLen, pCmdBuffer);
+ else if (padapter->registrypriv.mp_mode == 0)
+ RTW_PRINT(FUNC_ADPT_FMT" FW doesn't exit when no MP mode, by pass H2C id:0x%02x\n"
+ , FUNC_ADPT_ARG(padapter), ElementID);
+ return _FAIL;
+}
+
+void rtw_hal_fill_fake_txdesc(_adapter *padapter, u8 *pDesc, u32 BufferLen,
+ u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame)
+{
+ padapter->hal_func.fill_fake_txdesc(padapter, pDesc, BufferLen, IsPsPoll, IsBTQosNull, bDataFrame);
+
+}
+u8 rtw_hal_get_txbuff_rsvd_page_num(_adapter *adapter, bool wowlan)
+{
+ return adapter->hal_func.hal_get_tx_buff_rsvd_page_num(adapter, wowlan);
+}
+
+#ifdef CONFIG_GPIO_API
+void rtw_hal_update_hisr_hsisr_ind(_adapter *padapter, u32 flag)
+{
+ if (padapter->hal_func.update_hisr_hsisr_ind)
+ padapter->hal_func.update_hisr_hsisr_ind(padapter, flag);
+}
+
+int rtw_hal_gpio_func_check(_adapter *padapter, u8 gpio_num)
+{
+ int ret = _SUCCESS;
+
+ if (padapter->hal_func.hal_gpio_func_check)
+ ret = padapter->hal_func.hal_gpio_func_check(padapter, gpio_num);
+
+ return ret;
+}
+
+void rtw_hal_gpio_multi_func_reset(_adapter *padapter, u8 gpio_num)
+{
+ if (padapter->hal_func.hal_gpio_multi_func_reset)
+ padapter->hal_func.hal_gpio_multi_func_reset(padapter, gpio_num);
+}
+#endif
+
+void rtw_hal_fw_correct_bcn(_adapter *padapter)
+{
+ if (padapter->hal_func.fw_correct_bcn)
+ padapter->hal_func.fw_correct_bcn(padapter);
+}
+
+void rtw_hal_set_tx_power_index(PADAPTER padapter, u32 powerindex, u8 rfpath, u8 rate)
+{
+ return padapter->hal_func.set_tx_power_index_handler(padapter, powerindex, rfpath, rate);
+}
+
+u8 rtw_hal_get_tx_power_index(PADAPTER padapter, u8 rfpath, u8 rate, u8 bandwidth, u8 channel, struct txpwr_idx_comp *tic)
+{
+ return padapter->hal_func.get_tx_power_index_handler(padapter, rfpath, rate, bandwidth, channel, tic);
+}
+
+#ifdef RTW_HALMAC
+/*
+ * Description:
+ * Initialize MAC registers
+ *
+ * Return:
+ * true success
+ * false fail
+ */
+u8 rtw_hal_init_mac_register(PADAPTER adapter)
+{
+ return adapter->hal_func.init_mac_register(adapter);
+}
+
+/*
+ * Description:
+ * Initialize PHY(BB/RF) related functions
+ *
+ * Return:
+ * true success
+ * false fail
+ */
+u8 rtw_hal_init_phy(PADAPTER adapter)
+{
+ return adapter->hal_func.init_phy(adapter);
+}
+#endif /* RTW_HALMAC */
+
+#ifdef CONFIG_RFKILL_POLL
+bool rtw_hal_rfkill_poll(_adapter *adapter, u8 *valid)
+{
+ bool ret;
+
+ if (adapter->hal_func.hal_radio_onoff_check)
+ ret = adapter->hal_func.hal_radio_onoff_check(adapter, valid);
+ else {
+ *valid = 0;
+ ret = false;
+ }
+ return ret;
+}
+#endif
+
+#define rtw_hal_error_msg(ops_fun) \
+ RTW_PRINT("### %s - Error : Please hook hal_func.%s ###\n", __func__, ops_fun)
+
+u8 rtw_hal_ops_check(_adapter *padapter)
+{
+ u8 ret = _SUCCESS;
+ /*** initialize section ***/
+ if (NULL == padapter->hal_func.read_chip_version) {
+ rtw_hal_error_msg("read_chip_version");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.init_default_value) {
+ rtw_hal_error_msg("init_default_value");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.intf_chip_configure) {
+ rtw_hal_error_msg("intf_chip_configure");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.read_adapter_info) {
+ rtw_hal_error_msg("read_adapter_info");
+ ret = _FAIL;
+ }
+
+ if (NULL == padapter->hal_func.hal_power_on) {
+ rtw_hal_error_msg("hal_power_on");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.hal_power_off) {
+ rtw_hal_error_msg("hal_power_off");
+ ret = _FAIL;
+ }
+
+ if (NULL == padapter->hal_func.hal_init) {
+ rtw_hal_error_msg("hal_init");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.hal_deinit) {
+ rtw_hal_error_msg("hal_deinit");
+ ret = _FAIL;
+ }
+
+ /*** xmit section ***/
+ if (NULL == padapter->hal_func.init_xmit_priv) {
+ rtw_hal_error_msg("init_xmit_priv");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.free_xmit_priv) {
+ rtw_hal_error_msg("free_xmit_priv");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.hal_xmit) {
+ rtw_hal_error_msg("hal_xmit");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.mgnt_xmit) {
+ rtw_hal_error_msg("mgnt_xmit");
+ ret = _FAIL;
+ }
+#ifdef CONFIG_XMIT_THREAD_MODE
+ if (NULL == padapter->hal_func.xmit_thread_handler) {
+ rtw_hal_error_msg("xmit_thread_handler");
+ ret = _FAIL;
+ }
+#endif
+ if (NULL == padapter->hal_func.hal_xmitframe_enqueue) {
+ rtw_hal_error_msg("hal_xmitframe_enqueue");
+ ret = _FAIL;
+ }
+
+ /*** recv section ***/
+ if (NULL == padapter->hal_func.init_recv_priv) {
+ rtw_hal_error_msg("init_recv_priv");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.free_recv_priv) {
+ rtw_hal_error_msg("free_recv_priv");
+ ret = _FAIL;
+ }
+#ifdef CONFIG_RECV_THREAD_MODE
+ if (NULL == padapter->hal_func.recv_hdl) {
+ rtw_hal_error_msg("recv_hdl");
+ ret = _FAIL;
+ }
+#endif
+ if (NULL == padapter->hal_func.inirp_init) {
+ rtw_hal_error_msg("inirp_init");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.inirp_deinit) {
+ rtw_hal_error_msg("inirp_deinit");
+ ret = _FAIL;
+ }
+
+
+ /*** interrupt hdl section ***/
+#if (defined(CONFIG_SUPPORT_USB_INT))
+ if (NULL == padapter->hal_func.interrupt_handler) {
+ rtw_hal_error_msg("interrupt_handler");
+ ret = _FAIL;
+ }
+#endif /*#if ((CONFIG_SUPPORT_USB_INT))*/
+
+ /*** DM section ***/
+ if (NULL == padapter->hal_func.dm_init) {
+ rtw_hal_error_msg("dm_init");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.dm_deinit) {
+ rtw_hal_error_msg("dm_deinit");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.hal_dm_watchdog) {
+ rtw_hal_error_msg("hal_dm_watchdog");
+ ret = _FAIL;
+ }
+#ifdef CONFIG_LPS_LCLK_WD_TIMER
+ if (NULL == padapter->hal_func.hal_dm_watchdog_in_lps) {
+ rtw_hal_error_msg("hal_dm_watchdog_in_lps");
+ ret = _FAIL;
+ }
+#endif
+
+ /*** xxx section ***/
+ if (NULL == padapter->hal_func.set_chnl_bw_handler) {
+ rtw_hal_error_msg("set_chnl_bw_handler");
+ ret = _FAIL;
+ }
+
+ if (NULL == padapter->hal_func.set_hw_reg_handler) {
+ rtw_hal_error_msg("set_hw_reg_handler");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.GetHwRegHandler) {
+ rtw_hal_error_msg("GetHwRegHandler");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.get_hal_def_var_handler) {
+ rtw_hal_error_msg("get_hal_def_var_handler");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.SetHalDefVarHandler) {
+ rtw_hal_error_msg("SetHalDefVarHandler");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.GetHalODMVarHandler) {
+ rtw_hal_error_msg("GetHalODMVarHandler");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.SetHalODMVarHandler) {
+ rtw_hal_error_msg("SetHalODMVarHandler");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.update_ra_mask_handler) {
+ rtw_hal_error_msg("update_ra_mask_handler");
+ ret = _FAIL;
+ }
+
+ if (NULL == padapter->hal_func.SetBeaconRelatedRegistersHandler) {
+ rtw_hal_error_msg("SetBeaconRelatedRegistersHandler");
+ ret = _FAIL;
+ }
+
+ if (NULL == padapter->hal_func.fill_h2c_cmd) {
+ rtw_hal_error_msg("fill_h2c_cmd");
+ ret = _FAIL;
+ }
+
+#ifdef RTW_HALMAC
+ if (NULL == padapter->hal_func.hal_mac_c2h_handler) {
+ rtw_hal_error_msg("hal_mac_c2h_handler");
+ ret = _FAIL;
+ }
+#endif
+
+#if defined(CONFIG_LPS) || defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
+ if (NULL == padapter->hal_func.fill_fake_txdesc) {
+ rtw_hal_error_msg("fill_fake_txdesc");
+ ret = _FAIL;
+ }
+#endif
+ if (NULL == padapter->hal_func.hal_get_tx_buff_rsvd_page_num) {
+ rtw_hal_error_msg("hal_get_tx_buff_rsvd_page_num");
+ ret = _FAIL;
+ }
+
+ if (NULL == padapter->hal_func.fw_dl) {
+ rtw_hal_error_msg("fw_dl");
+ ret = _FAIL;
+ }
+
+ if (!padapter->hal_func.get_tx_power_index_handler) {
+ rtw_hal_error_msg("get_tx_power_index_handler");
+ ret = _FAIL;
+ }
+
+ /*** SReset section ***/
+#ifdef DBG_CONFIG_ERROR_DETECT
+ if (NULL == padapter->hal_func.sreset_init_value) {
+ rtw_hal_error_msg("sreset_init_value");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.sreset_reset_value) {
+ rtw_hal_error_msg("sreset_reset_value");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.silentreset) {
+ rtw_hal_error_msg("silentreset");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.sreset_xmit_status_check) {
+ rtw_hal_error_msg("sreset_xmit_status_check");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.sreset_linked_status_check) {
+ rtw_hal_error_msg("sreset_linked_status_check");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.sreset_get_wifi_status) {
+ rtw_hal_error_msg("sreset_get_wifi_status");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.sreset_inprogress) {
+ rtw_hal_error_msg("sreset_inprogress");
+ ret = _FAIL;
+ }
+#endif /* #ifdef DBG_CONFIG_ERROR_DETECT */
+
+#ifdef RTW_HALMAC
+ if (NULL == padapter->hal_func.init_mac_register) {
+ rtw_hal_error_msg("init_mac_register");
+ ret = _FAIL;
+ }
+ if (NULL == padapter->hal_func.init_phy) {
+ rtw_hal_error_msg("init_phy");
+ ret = _FAIL;
+ }
+#endif /* RTW_HALMAC */
+
+#ifdef CONFIG_RFKILL_POLL
+ if (padapter->hal_func.hal_radio_onoff_check == NULL) {
+ rtw_hal_error_msg("hal_radio_onoff_check");
+ ret = _FAIL;
+ }
+#endif
+ return ret;
+}
diff --git a/drivers/staging/rtl8188eu/hal/hal_mcc.c b/drivers/staging/rtl8188eu/hal/hal_mcc.c
new file mode 100644
index 000000000000..a564cc6509e7
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal_mcc.c
@@ -0,0 +1,1862 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#ifdef CONFIG_MCC_MODE
+#define _HAL_MCC_C_
+
+#include <drv_types.h> /* PADAPTER */
+#include <rtw_mcc.h> /* mcc structure */
+#include <hal_data.h> /* HAL_DATA */
+#include <rtw_pwrctrl.h> /* power control */
+
+#define MCC_DURATION_IDX 0
+#define MCC_TSF_SYNC_OFFSET_IDX 1
+#define MCC_START_TIME_OFFSET_IDX 2
+#define MCC_INTERVAL_IDX 3
+#define MCC_GUARD_OFFSET0_IDX 4
+#define MCC_GUARD_OFFSET1_IDX 5
+#define TU 1024 /* 1 TU equals 1024 microseconds */
+/* port 1 druration, TSF sync offset, start time offset, interval (unit:TU (1024 microseconds))*/
+u8 mcc_switch_channel_policy_table[][6]={
+ {35, 50, 30, 100, 0, 0},
+ {19, 50, 40, 100, 2, 2},
+ {25, 50, 30, 100, 5, 5},
+};
+
+const int mcc_max_policy_num = sizeof(mcc_switch_channel_policy_table) /sizeof(u8) /6;
+
+static void dump_iqk_val_table(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct hal_iqk_reg_backup *iqk_reg_backup = pHalData->iqk_reg_backup;
+ u8 total_rf_path = pHalData->NumTotalRFPath;
+ u8 rf_path_idx = 0;
+ u8 backup_chan_idx = 0;
+ u8 backup_reg_idx = 0;
+
+ RTW_INFO("=============dump IQK backup table================\n");
+ for (backup_chan_idx = 0; backup_chan_idx < MAX_IQK_INFO_BACKUP_CHNL_NUM; backup_chan_idx++) {
+ for (rf_path_idx = 0; rf_path_idx < total_rf_path; rf_path_idx++) {
+ for(backup_reg_idx = 0; backup_reg_idx < MAX_IQK_INFO_BACKUP_REG_NUM; backup_reg_idx++) {
+ RTW_INFO("ch:%d. bw:%d. rf path:%d. reg[%d] = 0x%02x \n"
+ , iqk_reg_backup[backup_chan_idx].central_chnl
+ , iqk_reg_backup[backup_chan_idx].bw_mode
+ , rf_path_idx
+ , backup_reg_idx
+ , iqk_reg_backup[backup_chan_idx].reg_backup[rf_path_idx][backup_reg_idx]
+ );
+ }
+ }
+ }
+ RTW_INFO("=============================================\n");
+}
+
+static void rtw_hal_mcc_build_p2p_noa_attr(PADAPTER padapter, u8 *ie, u32 *ie_len)
+{
+ struct mcc_adapter_priv *pmccadapriv = &padapter->mcc_adapterpriv;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct mcc_obj_priv *pmccobjpriv = &(dvobj->mcc_objpriv);
+ u8 p2p_noa_attr_ie[MAX_P2P_IE_LEN] = {0x00};
+ u32 p2p_noa_attr_len = 0;
+ u8 noa_desc_num = 1;
+ u8 opp_ps = 0; /* Disable OppPS */
+ u8 noa_count = 255;
+ u32 noa_duration = 0x20;
+ u32 noa_interval = 0x64;
+ u8 noa_index = 0;
+ u8 mcc_policy_idx = 0;
+
+ mcc_policy_idx = pmccobjpriv->policy_index;
+ noa_duration = mcc_switch_channel_policy_table[mcc_policy_idx][MCC_DURATION_IDX];
+ noa_interval = mcc_switch_channel_policy_table[mcc_policy_idx][MCC_INTERVAL_IDX];
+
+ /* P2P OUI(4 bytes) */
+ memcpy(p2p_noa_attr_ie, P2P_OUI, 4);
+ p2p_noa_attr_len = p2p_noa_attr_len + 4;
+
+ /* attrute ID(1 byte) */
+ p2p_noa_attr_ie[p2p_noa_attr_len] = P2P_ATTR_NOA;
+ p2p_noa_attr_len = p2p_noa_attr_len + 1;
+
+ /* attrute length(2 bytes) length = noa_desc_num*13 + 2 */
+ RTW_PUT_LE16(p2p_noa_attr_ie + p2p_noa_attr_len, (noa_desc_num*13 + 2));
+ p2p_noa_attr_len = p2p_noa_attr_len + 2;
+
+ /* Index (1 byte) */
+ p2p_noa_attr_ie[p2p_noa_attr_len] = noa_index;
+ p2p_noa_attr_len = p2p_noa_attr_len + 1;
+
+ /* CTWindow and OppPS Parameters (1 byte) */
+ p2p_noa_attr_ie[p2p_noa_attr_len] = opp_ps;
+ p2p_noa_attr_len = p2p_noa_attr_len+ 1;
+
+ /* NoA Count (1 byte) */
+ p2p_noa_attr_ie[p2p_noa_attr_len] = noa_count;
+ p2p_noa_attr_len = p2p_noa_attr_len + 1;
+
+ /* NoA Duration (4 bytes) unit: microseconds */
+ RTW_PUT_LE32(p2p_noa_attr_ie + p2p_noa_attr_len, (noa_duration * TU));
+ p2p_noa_attr_len = p2p_noa_attr_len + 4;
+
+ /* NoA Interval (4 bytes) unit: microseconds */
+ RTW_PUT_LE32(p2p_noa_attr_ie + p2p_noa_attr_len, (noa_interval * TU));
+ p2p_noa_attr_len = p2p_noa_attr_len + 4;
+
+ /* NoA Start Time (4 bytes) unit: microseconds */
+ RTW_PUT_LE32(p2p_noa_attr_ie + p2p_noa_attr_len, pmccadapriv->noa_start_time);
+ if (0)
+ RTW_INFO("indxe:%d, start_time=0x%02x:0x%02x:0x%02x:0x%02x\n"
+ , noa_index
+ , p2p_noa_attr_ie[p2p_noa_attr_len]
+ , p2p_noa_attr_ie[p2p_noa_attr_len + 1]
+ , p2p_noa_attr_ie[p2p_noa_attr_len + 2]
+ , p2p_noa_attr_ie[p2p_noa_attr_len + 3]);
+
+ p2p_noa_attr_len = p2p_noa_attr_len + 4;
+ rtw_set_ie(ie, _VENDOR_SPECIFIC_IE_, p2p_noa_attr_len, (u8 *)p2p_noa_attr_ie, ie_len);
+}
+
+
+/**
+ * rtw_hal_mcc_update_go_p2p_ie - update go p2p ie(add NoA attribute)
+ * @padapter: the adapter to be update go p2p ie
+ */
+static void rtw_hal_mcc_update_go_p2p_ie(PADAPTER padapter)
+{
+ struct mcc_adapter_priv *pmccadapriv = &padapter->mcc_adapterpriv;
+ u8 *pos = NULL;
+
+
+ /* no noa attribute, build it */
+ if (pmccadapriv->p2p_go_noa_ie_len == 0)
+ rtw_hal_mcc_build_p2p_noa_attr(padapter, pmccadapriv->p2p_go_noa_ie, &pmccadapriv->p2p_go_noa_ie_len);
+ else {
+ /* has noa attribut, modify it */
+ /* update index */
+ pos = pmccadapriv->p2p_go_noa_ie + pmccadapriv->p2p_go_noa_ie_len - 15;
+ /* 0~255 */
+ (*pos) = ((*pos) + 1) % 256;
+ if (1)
+ RTW_INFO("indxe:%d\n", (*pos));
+
+ /* update start time */
+ pos = pmccadapriv->p2p_go_noa_ie + pmccadapriv->p2p_go_noa_ie_len - 4;
+ RTW_PUT_LE32(pos, pmccadapriv->noa_start_time);
+ if (0)
+ RTW_INFO("start_time=0x%02x:0x%02x:0x%02x:0x%02x\n"
+ , ((u8*)(pos))[0]
+ , ((u8*)(pos))[1]
+ , ((u8*)(pos))[2]
+ , ((u8*)(pos))[3]);
+
+ }
+
+ if (0) {
+ u8 i = 0;
+ RTW_INFO("p2p_go_noa_ie_len:%d\n", pmccadapriv->p2p_go_noa_ie_len);
+
+ for (i = 0;i < pmccadapriv->p2p_go_noa_ie_len; i++) {
+ if ((i+1)%8 != 0)
+ printk("0x%02x ", pmccadapriv->p2p_go_noa_ie[i]);
+ else
+ printk("0x%02x\n", pmccadapriv->p2p_go_noa_ie[i]);
+ }
+ printk("\n");
+ }
+ update_beacon(padapter, _VENDOR_SPECIFIC_IE_, P2P_OUI, true);
+}
+
+/**
+ * rtw_hal_mcc_remove_go_p2p_ie - remove go p2p ie(add NoA attribute)
+ * @padapter: the adapter to be update go p2p ie
+ */
+static void rtw_hal_mcc_remove_go_p2p_ie(PADAPTER padapter)
+{
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mcc_adapter_priv *pmccadapriv = &padapter->mcc_adapterpriv;
+
+ /* chech has noa ie or not */
+ if (pmccadapriv->p2p_go_noa_ie_len == 0)
+ return;
+
+ pmccadapriv->p2p_go_noa_ie_len = 0;
+ update_beacon(padapter, _VENDOR_SPECIFIC_IE_, P2P_OUI, true);
+}
+
+/* restore IQK value for all interface */
+void rtw_hal_mcc_restore_iqk_val(PADAPTER padapter)
+{
+ u8 take_care_iqk = false;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ _adapter *iface = NULL;
+ u8 i = 0;
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk);
+ if (take_care_iqk == true && MCC_EN(padapter)) {
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if (iface == NULL)
+ continue;
+
+ rtw_hal_ch_sw_iqk_info_restore(iface, CH_SW_USE_CASE_MCC);
+ }
+ }
+
+ if (0)
+ dump_iqk_val_table(padapter);
+}
+
+u8 rtw_hal_check_mcc_status(PADAPTER padapter, u8 mcc_status)
+{
+ struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv);
+
+ if (pmccobjpriv->mcc_status & (mcc_status))
+ return true;
+ else
+ return false;
+}
+
+void rtw_hal_set_mcc_status(PADAPTER padapter, u8 mcc_status)
+{
+ struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv);
+
+ pmccobjpriv->mcc_status |= (mcc_status);
+}
+
+void rtw_hal_clear_mcc_status(PADAPTER padapter, u8 mcc_status)
+{
+ struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv);
+
+ pmccobjpriv->mcc_status &= (~mcc_status);
+}
+
+void rtw_hal_mcc_update_switch_channel_policy_table(PADAPTER padapter)
+{
+ struct registry_priv *registry_par = &padapter->registrypriv;
+ u8 idx = 0;
+
+ if (registry_par->rtw_mcc_policy_table_idx < 0)
+ return;
+
+ if (registry_par->rtw_mcc_policy_table_idx >= mcc_max_policy_num) {
+ RTW_INFO("[MCC] mcc_policy_table_idx error, do not update policy table\n");
+ return;
+ }
+
+ idx = registry_par->rtw_mcc_policy_table_idx;
+
+ if (registry_par->rtw_mcc_duration > 0)
+ mcc_switch_channel_policy_table[idx][MCC_DURATION_IDX] = registry_par->rtw_mcc_duration;
+
+ if (registry_par->rtw_mcc_tsf_sync_offset > 0)
+ mcc_switch_channel_policy_table[idx][MCC_TSF_SYNC_OFFSET_IDX] = registry_par->rtw_mcc_tsf_sync_offset;
+
+ if (registry_par->rtw_mcc_start_time_offset > 0)
+ mcc_switch_channel_policy_table[idx][MCC_START_TIME_OFFSET_IDX] = registry_par->rtw_mcc_start_time_offset;
+
+ if (registry_par->rtw_mcc_interval > 0)
+ mcc_switch_channel_policy_table[idx][MCC_INTERVAL_IDX] = registry_par->rtw_mcc_interval;
+
+ if (registry_par->rtw_mcc_guard_offset0 >= 0)
+ mcc_switch_channel_policy_table[idx][MCC_GUARD_OFFSET0_IDX] = registry_par->rtw_mcc_guard_offset0;
+
+ if (registry_par->rtw_mcc_guard_offset1 >= 0)
+ mcc_switch_channel_policy_table[idx][MCC_GUARD_OFFSET1_IDX] = registry_par->rtw_mcc_guard_offset1;
+
+}
+
+static void rtw_hal_config_mcc_switch_channel_setting(PADAPTER padapter)
+{
+ struct mcc_adapter_priv *pmccadapriv = &padapter->mcc_adapterpriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct mcc_obj_priv *pmccobjpriv = &(dvobj->mcc_objpriv);
+ struct registry_priv *registry_par = &padapter->registrypriv;
+ u8 interval = pmlmepriv->cur_network.network.Configuration.BeaconPeriod;
+ u8 i = 0;
+ s8 mcc_policy_idx = 0;
+
+ rtw_hal_mcc_update_switch_channel_policy_table(padapter);
+ mcc_policy_idx = registry_par->rtw_mcc_policy_table_idx;
+
+ if (mcc_policy_idx < 0 || mcc_policy_idx >= mcc_max_policy_num) {
+ pmccobjpriv->policy_index = 0;
+ RTW_INFO("[MCC] can't find table(%d,%d,%d), use default policy(%d)\n"
+ , pmccobjpriv->duration, interval, mcc_policy_idx, pmccobjpriv->policy_index);
+ } else
+ pmccobjpriv->policy_index = mcc_policy_idx;
+
+ RTW_INFO("[MCC] policy(%d): %d,%d,%d,%d,%d,%d\n"
+ , pmccobjpriv->policy_index
+ , mcc_switch_channel_policy_table[pmccobjpriv->policy_index][MCC_DURATION_IDX]
+ , mcc_switch_channel_policy_table[pmccobjpriv->policy_index][MCC_TSF_SYNC_OFFSET_IDX]
+ , mcc_switch_channel_policy_table[pmccobjpriv->policy_index][MCC_START_TIME_OFFSET_IDX]
+ , mcc_switch_channel_policy_table[pmccobjpriv->policy_index][MCC_INTERVAL_IDX]
+ , mcc_switch_channel_policy_table[pmccobjpriv->policy_index][MCC_GUARD_OFFSET0_IDX]
+ , mcc_switch_channel_policy_table[pmccobjpriv->policy_index][MCC_GUARD_OFFSET1_IDX]);
+
+}
+
+static void rtw_hal_config_mcc_role_setting(PADAPTER padapter)
+{
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ struct mcc_obj_priv *pmccobjpriv = &(pdvobjpriv->mcc_objpriv);
+ struct mcc_adapter_priv *pmccadapriv = &padapter->mcc_adapterpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct wlan_network *cur_network = &(pmlmepriv->cur_network);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct sta_info *psta = NULL;
+ struct registry_priv *preg = &padapter->registrypriv;
+ u8 policy_index = 0;
+ u8 mcc_duration = 0;
+ u8 mcc_interval = 0;
+
+ policy_index = pmccobjpriv->policy_index;
+ mcc_duration = mcc_switch_channel_policy_table[pmccobjpriv->policy_index][MCC_DURATION_IDX]
+ - mcc_switch_channel_policy_table[pmccobjpriv->policy_index][MCC_GUARD_OFFSET0_IDX]
+ - mcc_switch_channel_policy_table[pmccobjpriv->policy_index][MCC_GUARD_OFFSET1_IDX];
+ mcc_interval = mcc_switch_channel_policy_table[pmccobjpriv->policy_index][MCC_INTERVAL_IDX];
+
+ /* GO/AP is 1nd order GC/STA is 2nd order */
+ switch (pmccadapriv->role) {
+ case MCC_ROLE_STA:
+ case MCC_ROLE_GC:
+ pmccadapriv->order = 1;
+ pmccadapriv->mcc_duration = mcc_duration;
+
+ switch (pmlmeext->cur_bwmode) {
+ case CHANNEL_WIDTH_20:
+ /*
+ * target tx byte(bytes) = target tx tp(Mbits/sec) * 1024 * 1024 / 8 * (duration(ms) / 1024)
+ * = target tx tp(Mbits/sec) * 128 * duration(ms)
+ * note:
+ * target tx tp(Mbits/sec) * 1024 * 1024 / 8 ==> Mbits to bytes
+ * duration(ms) / 1024 ==> msec to sec
+ */
+ pmccadapriv->mcc_target_tx_bytes_to_port = preg->rtw_mcc_sta_bw20_target_tx_tp * 128 * pmccadapriv->mcc_duration;
+ break;
+ case CHANNEL_WIDTH_40:
+ pmccadapriv->mcc_target_tx_bytes_to_port = preg->rtw_mcc_sta_bw40_target_tx_tp * 128 * pmccadapriv->mcc_duration;
+ break;
+ case CHANNEL_WIDTH_80:
+ pmccadapriv->mcc_target_tx_bytes_to_port = preg->rtw_mcc_sta_bw80_target_tx_tp * 128 * pmccadapriv->mcc_duration;
+ break;
+ case CHANNEL_WIDTH_160:
+ case CHANNEL_WIDTH_80_80:
+ RTW_INFO(FUNC_ADPT_FMT": not support bwmode = %d\n"
+ , FUNC_ADPT_ARG(padapter), pmlmeext->cur_bwmode);
+ break;
+ }
+
+ /* assign used mac to avoid affecting RA */
+ pmccadapriv->mgmt_queue_macid = MCC_ROLE_STA_GC_MGMT_QUEUE_MACID;
+
+ psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
+ if (psta) {
+ /* combine AP/GO macid and mgmt queue macid to bitmap */
+ pmccadapriv->mcc_macid_bitmap = BIT(psta->mac_id) | BIT(pmccadapriv->mgmt_queue_macid);
+ } else {
+ RTW_INFO(FUNC_ADPT_FMT":AP/GO station info is NULL\n", FUNC_ADPT_ARG(padapter));
+ rtw_warn_on(1);
+ }
+ break;
+ case MCC_ROLE_AP:
+ case MCC_ROLE_GO:
+ pmccadapriv->order = 0;
+ /* total druation value equals interval */
+ pmccadapriv->mcc_duration = mcc_interval - mcc_duration;
+ pmccadapriv->p2p_go_noa_ie_len = 0; /* not NoA attribute at init time */
+
+ switch (pmlmeext->cur_bwmode) {
+ case CHANNEL_WIDTH_20:
+ pmccadapriv->mcc_target_tx_bytes_to_port = preg->rtw_mcc_ap_bw20_target_tx_tp * 128 * pmccadapriv->mcc_duration;
+ break;
+ case CHANNEL_WIDTH_40:
+ pmccadapriv->mcc_target_tx_bytes_to_port = preg->rtw_mcc_ap_bw40_target_tx_tp * 128 * pmccadapriv->mcc_duration;
+ break;
+ case CHANNEL_WIDTH_80:
+ pmccadapriv->mcc_target_tx_bytes_to_port = preg->rtw_mcc_ap_bw80_target_tx_tp * 128 * pmccadapriv->mcc_duration;
+ break;
+ case CHANNEL_WIDTH_160:
+ case CHANNEL_WIDTH_80_80:
+ RTW_INFO(FUNC_ADPT_FMT": not support bwmode = %d\n"
+ , FUNC_ADPT_ARG(padapter), pmlmeext->cur_bwmode);
+ break;
+ }
+
+
+ psta = rtw_get_bcmc_stainfo(padapter);
+
+ if (psta != NULL)
+ pmccadapriv->mgmt_queue_macid = psta->mac_id;
+ else {
+ pmccadapriv->mgmt_queue_macid = MCC_ROLE_SOFTAP_GO_MGMT_QUEUE_MACID;
+ RTW_INFO(FUNC_ADPT_FMT":bcmc station is NULL, use macid %d\n"
+ , FUNC_ADPT_ARG(padapter), pmccadapriv->mgmt_queue_macid);
+ }
+
+ /* combine client macid and mgmt queue macid to bitmap */
+ pmccadapriv->mcc_macid_bitmap = (0xff << 8) | BIT(pmccadapriv->mgmt_queue_macid);
+ break;
+ default:
+ RTW_INFO("Unknown role\n");
+ rtw_warn_on(1);
+ break;
+ }
+
+ pmccobjpriv->iface[pmccadapriv->order] = padapter;
+ RTW_INFO(FUNC_ADPT_FMT": order:%d, role:%d, mcc duration:%d, target tx bytes:%d, mgmt queue macid:%d, bitmap:0x%02x\n"
+ , FUNC_ADPT_ARG(padapter), pmccadapriv->order, pmccadapriv->role, pmccadapriv->mcc_duration
+ , pmccadapriv->mcc_target_tx_bytes_to_port, pmccadapriv->mgmt_queue_macid, pmccadapriv->mcc_macid_bitmap);
+}
+
+static void rtw_hal_clear_mcc_macid(PADAPTER padapter)
+{
+ u16 media_status_rpt;
+ struct mcc_adapter_priv *pmccadapriv = &padapter->mcc_adapterpriv;
+
+ switch (pmccadapriv->role) {
+ case MCC_ROLE_STA:
+ case MCC_ROLE_GC:
+ break;
+ case MCC_ROLE_AP:
+ case MCC_ROLE_GO:
+ /* nothing to do */
+ break;
+ default:
+ RTW_INFO("Unknown role\n");
+ rtw_warn_on(1);
+ break;
+ }
+}
+static u8 rtw_hal_decide_mcc_role(PADAPTER padapter)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ _adapter *iface = NULL;
+ struct mcc_adapter_priv *pmccadapriv = NULL;
+ struct wifidirect_info *pwdinfo = NULL;
+ struct mlme_priv *pmlmepriv = NULL;
+ u8 ret = _SUCCESS, i = 0;
+
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if (iface == NULL)
+ continue;
+
+ pmccadapriv = &iface->mcc_adapterpriv;
+
+ if (MLME_IS_GO(iface))
+ pmccadapriv->role = MCC_ROLE_GO;
+ else if (MLME_IS_AP(iface))
+ pmccadapriv->role = MCC_ROLE_AP;
+ else if (MLME_IS_GC(iface))
+ pmccadapriv->role = MCC_ROLE_GC;
+ else if (MLME_IS_STA(iface))
+ pmccadapriv->role = MCC_ROLE_STA;
+ else {
+ pwdinfo = &iface->wdinfo;
+ pmlmepriv = &iface->mlmepriv;
+
+ RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(iface));
+ RTW_INFO("Unknown:P2P state:%d, mlme state:0x%2x, mlmext info state:0x%02x\n",
+ pwdinfo->role, pmlmepriv->fw_state, iface->mlmeextpriv.mlmext_info.state);
+ rtw_warn_on(1);
+ ret = _FAIL;
+ goto exit;
+ }
+
+ if (ret == _SUCCESS)
+ rtw_hal_config_mcc_role_setting(iface);
+ }
+
+exit:
+ return ret;
+}
+
+static void rtw_hal_init_mcc_parameter(PADAPTER padapter)
+{
+}
+
+static void rtw_hal_construct_CTS(PADAPTER padapter, u8 *pframe, u32 *pLength)
+{
+ u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+ /* frame type, length = 1*/
+ set_frame_sub_type(pframe, WIFI_RTS);
+
+ /* frame control flag, length = 1 */
+ *(pframe + 1) = 0;
+
+ /* frame duration, length = 2 */
+ *(pframe + 2) = 0x00;
+ *(pframe + 3) = 0x78;
+
+ /* frame recvaddr, length = 6 */
+ memcpy((pframe + 4), broadcast_addr, ETH_ALEN);
+ memcpy((pframe + 4 + ETH_ALEN), adapter_mac_addr(padapter), ETH_ALEN);
+ memcpy((pframe + 4 + ETH_ALEN*2), adapter_mac_addr(padapter), ETH_ALEN);
+ *pLength = 22;
+}
+
+u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index,
+ u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
+ RSVDPAGE_LOC *rsvd_page_loc)
+{
+ u32 len = 0;
+ _adapter *iface = NULL;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ struct mcc_obj_priv *pmccobjpriv = &(dvobj->mcc_objpriv);
+ struct mlme_ext_info *pmlmeinfo = NULL;
+ struct mlme_ext_priv *pmlmeext = NULL;
+ u8 ret = _SUCCESS, i = 0, order = 0, CurtPktPageNum = 0;
+ u8 bssid[ETH_ALEN] = {0};
+
+ /* check proccess mcc start setting */
+ if (!rtw_hal_check_mcc_status(adapter, MCC_STATUS_PROCESS_MCC_START_SETTING)) {
+ ret = _FAIL;
+ goto exit;
+ }
+
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if (iface == NULL)
+ continue;
+
+ order = iface->mcc_adapterpriv.order;
+ dvobj->mcc_objpriv.mcc_loc_rsvd_paga[order] = *page_num;
+
+ switch (iface->mcc_adapterpriv.role) {
+ case MCC_ROLE_STA:
+ case MCC_ROLE_GC:
+ /* Build NULL DATA */
+ RTW_INFO("LocNull(order:%d): %d\n"
+ , order, dvobj->mcc_objpriv.mcc_loc_rsvd_paga[order]);
+ len = 0;
+ pmlmeext = &iface->mlmeextpriv;
+ pmlmeinfo = &pmlmeext->mlmext_info;
+
+ memcpy(bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
+ rtw_hal_construct_NullFunctionData(iface
+ , &pframe[*index], &len, bssid, false, 0, 0, false);
+ rtw_hal_fill_fake_txdesc(iface, &pframe[*index-tx_desc],
+ len, false, false, false);
+
+ CurtPktPageNum = (u8)PageNum(tx_desc + len, page_size);
+ *page_num += CurtPktPageNum;
+ *index += (CurtPktPageNum * page_size);
+ *total_pkt_len = *index + len;
+ break;
+ case MCC_ROLE_AP:
+ /* Bulid CTS */
+ RTW_INFO("LocCTS(order:%d): %d\n"
+ , order, dvobj->mcc_objpriv.mcc_loc_rsvd_paga[order]);
+
+ len = 0;
+ rtw_hal_construct_CTS(iface, &pframe[*index], &len);
+ rtw_hal_fill_fake_txdesc(iface, &pframe[*index-tx_desc],
+ len, false, false, false);
+
+ CurtPktPageNum = (u8)PageNum(tx_desc + len, page_size);
+ *page_num += CurtPktPageNum;
+ *index += (CurtPktPageNum * page_size);
+ *total_pkt_len = *index + len;
+ break;
+ case MCC_ROLE_GO:
+ /* To DO */
+ break;
+ }
+ }
+exit:
+ return ret;
+}
+
+/*
+* 1. Download MCC rsvd page
+* 2. Re-Download beacon after download rsvd page
+*/
+static void rtw_hal_set_fw_mcc_rsvd_page(PADAPTER padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct mcc_adapter_priv *pmccadapriv = &padapter->mcc_adapterpriv;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ PADAPTER port0_iface = dvobj_get_port0_adapter(dvobj);
+ PADAPTER iface = NULL;
+ struct mcc_obj_priv *pmccobjpriv = &(dvobj->mcc_objpriv);
+ u8 mstatus = RT_MEDIA_CONNECT, i = 0;
+
+ RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
+
+ rtw_hal_set_hwreg(port0_iface, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus));
+
+ /* Re-Download beacon */
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = pmccobjpriv->iface[i];
+ pmccadapriv = &iface->mcc_adapterpriv;
+ if (pmccadapriv->role == MCC_ROLE_AP
+ || pmccadapriv->role == MCC_ROLE_GO)
+ tx_beacon_hdl(iface, NULL);
+ }
+}
+
+static void rtw_hal_set_mcc_rsvdpage_cmd(_adapter *padapter)
+{
+ u8 cmd[H2C_MCC_LOCATION_LEN] = {0}, i = 0, order = 0;
+ _adapter *iface = NULL;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct mcc_obj_priv *pmccobjpriv = &(dvobj->mcc_objpriv);
+
+
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if (iface == NULL)
+ continue;
+
+ order = iface->mcc_adapterpriv.order;
+ if (order >= H2C_MCC_LOCATION_LEN) {
+ RTW_INFO(FUNC_ADPT_FMT" only support 3 interface at most(%d)\n"
+ , FUNC_ADPT_ARG(padapter), order);
+ continue;
+ }
+
+ SET_H2CCMD_MCC_RSVDPAGE_LOC((cmd + order), (pmccobjpriv->mcc_loc_rsvd_paga[order]));
+ }
+
+#ifdef CONFIG_MCC_MODE_DEBUG
+ RTW_INFO("=========================\n");
+ RTW_INFO("MCC RSVD PAGE LOC:\n");
+ for (i = 0; i < H2C_MCC_LOCATION_LEN; i++)
+ pr_dbg("0x%x ", cmd[i]);
+ pr_dbg("\n");
+ RTW_INFO("=========================\n");
+#endif /* CONFIG_MCC_MODE_DEBUG */
+
+ rtw_hal_fill_h2c_cmd(padapter, H2C_MCC_LOCATION, H2C_MCC_LOCATION_LEN, cmd);
+}
+
+static void rtw_hal_set_mcc_noa_cmd(PADAPTER padapter)
+{
+ struct mcc_adapter_priv *pmccadapriv = &padapter->mcc_adapterpriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct mcc_obj_priv *pmccobjpriv = &(dvobj->mcc_objpriv);
+ u8 cmd[H2C_MCC_NOA_PARAM_LEN] = {0};
+ u8 policy_idx = pmccobjpriv->policy_index;
+ u8 noa_fw_eable = 1;
+ u8 noa_tsf_sync_offset = mcc_switch_channel_policy_table[policy_idx][MCC_TSF_SYNC_OFFSET_IDX];
+ u8 noa_start_time_offset = mcc_switch_channel_policy_table[policy_idx][MCC_START_TIME_OFFSET_IDX];
+ u8 noa_interval = mcc_switch_channel_policy_table[policy_idx][MCC_INTERVAL_IDX];
+ u8 guard_offset0 = mcc_switch_channel_policy_table[policy_idx][MCC_GUARD_OFFSET0_IDX];
+ u8 guard_offset1 = mcc_switch_channel_policy_table[policy_idx][MCC_GUARD_OFFSET1_IDX];
+ u8 swchannel_early_time = MCC_SWCH_FW_EARLY_TIME;
+ u8 i = 0;
+
+ /* FW set NOA enable */
+ SET_H2CCMD_MCC_NOA_FW_EN(cmd, noa_fw_eable);
+ /* TSF Sync offset */
+ SET_H2CCMD_MCC_NOA_TSF_SYNC_OFFSET(cmd, noa_tsf_sync_offset);
+ /* NoA start time offset */
+ SET_H2CCMD_MCC_NOA_START_TIME(cmd, (noa_start_time_offset + guard_offset0));
+ /* NoA interval */
+ SET_H2CCMD_MCC_NOA_INTERVAL(cmd, noa_interval);
+ /* Early time to inform driver by C2H before switch channel */
+ SET_H2CCMD_MCC_EARLY_TIME(cmd, swchannel_early_time);
+
+#ifdef CONFIG_MCC_MODE_DEBUG
+ RTW_INFO("=========================\n");
+ RTW_INFO("NoA:\n");
+ for (i = 0; i < H2C_MCC_NOA_PARAM_LEN; i++)
+ pr_dbg("0x%x ", cmd[i]);
+ pr_dbg("\n");
+ RTW_INFO("=========================\n");
+#endif /* CONFIG_MCC_MODE_DEBUG */
+
+ rtw_hal_fill_h2c_cmd(padapter, H2C_MCC_NOA_PARAM, H2C_MCC_NOA_PARAM_LEN, cmd);
+}
+
+static void rtw_hal_set_mcc_IQK_offload_cmd(PADAPTER padapter)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct mcc_obj_priv *pmccobjpriv = &(dvobj->mcc_objpriv);
+ struct mcc_adapter_priv *pmccadapriv = NULL;
+ _adapter *iface = NULL;
+ u8 cmd[H2C_MCC_IQK_PARAM_LEN] = {0}, bready = 0, i = 0, order = 0;
+ u16 TX_X = 0, TX_Y = 0, RX_X = 0, RX_Y = 0;
+ u8 total_rf_path = GET_HAL_DATA(padapter)->NumTotalRFPath;
+ u8 rf_path_idx = 0, last_order = MAX_MCC_NUM - 1, last_rf_path_index = total_rf_path - 1;
+
+ /* by order, last order & last_rf_path_index must set ready bit = 1 */
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = pmccobjpriv->iface[i];
+ if (iface == NULL)
+ continue;
+
+ pmccadapriv = &iface->mcc_adapterpriv;
+ order = pmccadapriv->order;
+
+ for (rf_path_idx = 0; rf_path_idx < total_rf_path; rf_path_idx ++) {
+
+ memset(cmd, 0, H2C_MCC_IQK_PARAM_LEN);
+ TX_X = pmccadapriv->mcc_iqk_arr[rf_path_idx].TX_X & 0x7ff;/* [10:0] */
+ TX_Y = pmccadapriv->mcc_iqk_arr[rf_path_idx].TX_Y & 0x7ff;/* [10:0] */
+ RX_X = pmccadapriv->mcc_iqk_arr[rf_path_idx].RX_X & 0x3ff;/* [9:0] */
+ RX_Y = pmccadapriv->mcc_iqk_arr[rf_path_idx].RX_Y & 0x3ff;/* [9:0] */
+
+ /* ready or not */
+ if (order == last_order && rf_path_idx == last_rf_path_index)
+ bready = 1;
+ else
+ bready = 0;
+
+ SET_H2CCMD_MCC_IQK_READY(cmd, bready);
+ SET_H2CCMD_MCC_IQK_ORDER(cmd, order);
+ SET_H2CCMD_MCC_IQK_PATH(cmd, rf_path_idx);
+
+ /* fill RX_X[7:0] to (cmd+1)[7:0] bitlen=8 */
+ SET_H2CCMD_MCC_IQK_RX_L(cmd, (u8)(RX_X & 0xff));
+ /* fill RX_X[9:8] to (cmd+2)[1:0] bitlen=2 */
+ SET_H2CCMD_MCC_IQK_RX_M1(cmd, (u8)((RX_X >> 8) & 0x03));
+ /* fill RX_Y[5:0] to (cmd+2)[7:2] bitlen=6 */
+ SET_H2CCMD_MCC_IQK_RX_M2(cmd, (u8)(RX_Y & 0x3f));
+ /* fill RX_Y[9:6] to (cmd+3)[3:0] bitlen=4 */
+ SET_H2CCMD_MCC_IQK_RX_H(cmd, (u8)((RX_Y >> 6) & 0x0f));
+
+
+ /* fill TX_X[7:0] to (cmd+4)[7:0] bitlen=8 */
+ SET_H2CCMD_MCC_IQK_TX_L(cmd, (u8)(TX_X & 0xff));
+ /* fill TX_X[10:8] to (cmd+5)[2:0] bitlen=3 */
+ SET_H2CCMD_MCC_IQK_TX_M1(cmd, (u8)((TX_X >> 8) & 0x07));
+ /* fill TX_Y[4:0] to (cmd+5)[7:3] bitlen=5 */
+ SET_H2CCMD_MCC_IQK_TX_M2(cmd, (u8)(TX_Y & 0x1f));
+ /* fill TX_Y[10:5] to (cmd+6)[5:0] bitlen=6 */
+ SET_H2CCMD_MCC_IQK_TX_H(cmd, (u8)((TX_Y >> 5) & 0x3f));
+
+#ifdef CONFIG_MCC_MODE_DEBUG
+ RTW_INFO("=========================\n");
+ RTW_INFO(FUNC_ADPT_FMT" IQK:\n", FUNC_ADPT_ARG(iface));
+ RTW_INFO("TX_X: 0x%02x\n", TX_X);
+ RTW_INFO("TX_Y: 0x%02x\n", TX_Y);
+ RTW_INFO("RX_X: 0x%02x\n", RX_X);
+ RTW_INFO("RX_Y: 0x%02x\n", RX_Y);
+ RTW_INFO("cmd[0]:0x%02x\n", cmd[0]);
+ RTW_INFO("cmd[1]:0x%02x\n", cmd[1]);
+ RTW_INFO("cmd[2]:0x%02x\n", cmd[2]);
+ RTW_INFO("cmd[3]:0x%02x\n", cmd[3]);
+ RTW_INFO("cmd[4]:0x%02x\n", cmd[4]);
+ RTW_INFO("cmd[5]:0x%02x\n", cmd[5]);
+ RTW_INFO("cmd[6]:0x%02x\n", cmd[6]);
+ RTW_INFO("=========================\n");
+#endif /* CONFIG_MCC_MODE_DEBUG */
+
+ rtw_hal_fill_h2c_cmd(padapter, H2C_MCC_IQK_PARAM, H2C_MCC_IQK_PARAM_LEN, cmd);
+ }
+ }
+}
+
+
+static void rtw_hal_set_mcc_macid_cmd(PADAPTER padapter)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct mcc_adapter_priv *pmccadapriv = NULL;
+ _adapter *iface = NULL;
+ u8 cmd[H2C_MCC_MACID_BITMAP_LEN] = {0}, i = 0, order = 0;
+ u16 bitmap = 0;
+
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if (iface == NULL)
+ continue;
+
+ pmccadapriv = &iface->mcc_adapterpriv;
+ order = pmccadapriv->order;
+ bitmap = pmccadapriv->mcc_macid_bitmap;
+
+ if (order >= (H2C_MCC_MACID_BITMAP_LEN/2)) {
+ RTW_INFO(FUNC_ADPT_FMT" only support 3 interface at most(%d)\n"
+ , FUNC_ADPT_ARG(padapter), order);
+ continue;
+ }
+ SET_H2CCMD_MCC_MACID_BITMAP_L((cmd + order * 2), (u8)(bitmap & 0xff));
+ SET_H2CCMD_MCC_MACID_BITMAP_H((cmd + order * 2), (u8)((bitmap >> 8) & 0xff));
+ }
+
+#ifdef CONFIG_MCC_MODE_DEBUG
+ RTW_INFO("=========================\n");
+ RTW_INFO("MACID BITMAP: ");
+ for (i = 0; i < H2C_MCC_MACID_BITMAP_LEN; i++)
+ pr_dbg("0x%x ", cmd[i]);
+ pr_dbg("\n");
+ RTW_INFO("=========================\n");
+#endif /* CONFIG_MCC_MODE_DEBUG */
+ rtw_hal_fill_h2c_cmd(padapter, H2C_MCC_MACID_BITMAP, H2C_MCC_MACID_BITMAP_LEN, cmd);
+}
+
+static void rtw_hal_set_mcc_ctrl_cmd(PADAPTER padapter, u8 stop)
+{
+ u8 cmd[H2C_MCC_CTRL_LEN] = {0}, i = 0;
+ u8 order = 0, totalnum = 0, chidx = 0, bw = 0, bw40sc = 0, bw80sc = 0;
+ u8 duration = 0, role = 0, incurch = 0, rfetype = 0, distxnull = 0, c2hrpt = 0, chscan = 0;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct mcc_obj_priv *pmccobjpriv = &(dvobj->mcc_objpriv);
+ struct mlme_ext_priv *pmlmeext = NULL;
+ struct mlme_ext_info *pmlmeinfo = NULL;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ _adapter *iface = NULL;
+
+ RTW_INFO(FUNC_ADPT_FMT": stop=%d\n", FUNC_ADPT_ARG(padapter), stop);
+
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = pmccobjpriv->iface[i];
+ if (iface == NULL)
+ continue;
+
+ if (stop) {
+ if (iface != padapter)
+ continue;
+ }
+
+
+ order = iface->mcc_adapterpriv.order;
+ if (!stop)
+ totalnum = dvobj->iface_nums;
+ else
+ totalnum = 0xff; /* 0xff means stop */
+
+ pmlmeext = &iface->mlmeextpriv;
+ chidx = pmlmeext->cur_channel;
+ bw = pmlmeext->cur_bwmode;
+ bw40sc = pmlmeext->cur_ch_offset;
+
+ /* decide 80 band width offset */
+ if (bw == CHANNEL_WIDTH_80) {
+ u8 center_ch = rtw_get_center_ch(chidx, bw, bw40sc);
+
+ if (center_ch > chidx)
+ bw80sc = HAL_PRIME_CHNL_OFFSET_LOWER;
+ else if (center_ch < chidx)
+ bw80sc = HAL_PRIME_CHNL_OFFSET_UPPER;
+ else
+ bw80sc = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+ } else
+ bw80sc = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+
+ duration = iface->mcc_adapterpriv.mcc_duration;
+ role = iface->mcc_adapterpriv.role;
+
+ incurch = false;
+
+ if (IS_HARDWARE_TYPE_8812(padapter))
+ rfetype = pHalData->rfe_type; /* RFETYPE (only for 8812)*/
+ else
+ rfetype = 0;
+
+ /* STA/GC TX NULL data to inform AP/GC for ps mode */
+ switch (role) {
+ case MCC_ROLE_GO:
+ case MCC_ROLE_AP:
+ distxnull = MCC_DISABLE_TX_NULL;
+ break;
+ case MCC_ROLE_GC:
+ case MCC_ROLE_STA:
+ distxnull = MCC_ENABLE_TX_NULL;
+ break;
+ }
+
+ c2hrpt = MCC_C2H_REPORT_ALL_STATUS;
+ chscan = MCC_CHIDX;
+
+ SET_H2CCMD_MCC_CTRL_ORDER(cmd, order);
+ SET_H2CCMD_MCC_CTRL_TOTALNUM(cmd, totalnum);
+ SET_H2CCMD_MCC_CTRL_CHIDX(cmd, chidx);
+ SET_H2CCMD_MCC_CTRL_BW(cmd, bw);
+ SET_H2CCMD_MCC_CTRL_BW40SC(cmd, bw40sc);
+ SET_H2CCMD_MCC_CTRL_BW80SC(cmd, bw80sc);
+ SET_H2CCMD_MCC_CTRL_DURATION(cmd, duration);
+ SET_H2CCMD_MCC_CTRL_ROLE(cmd, role);
+ SET_H2CCMD_MCC_CTRL_INCURCH(cmd, incurch);
+ SET_H2CCMD_MCC_CTRL_RFETYPE(cmd, rfetype);
+ SET_H2CCMD_MCC_CTRL_DISTXNULL(cmd, distxnull);
+ SET_H2CCMD_MCC_CTRL_C2HRPT(cmd, c2hrpt);
+ SET_H2CCMD_MCC_CTRL_CHSCAN(cmd, chscan);
+
+#ifdef CONFIG_MCC_MODE_DEBUG
+ RTW_INFO("=========================\n");
+ RTW_INFO(FUNC_ADPT_FMT" MCC INFO:\n", FUNC_ADPT_ARG(iface));
+ RTW_INFO("cmd[0]:0x%02x\n", cmd[0]);
+ RTW_INFO("cmd[1]:0x%02x\n", cmd[1]);
+ RTW_INFO("cmd[2]:0x%02x\n", cmd[2]);
+ RTW_INFO("cmd[3]:0x%02x\n", cmd[3]);
+ RTW_INFO("cmd[4]:0x%02x\n", cmd[4]);
+ RTW_INFO("cmd[5]:0x%02x\n", cmd[5]);
+ RTW_INFO("cmd[6]:0x%02x\n", cmd[6]);
+ RTW_INFO("=========================\n");
+#endif /* CONFIG_MCC_MODE_DEBUG */
+
+ rtw_hal_fill_h2c_cmd(padapter, H2C_MCC_CTRL, H2C_MCC_CTRL_LEN, cmd);
+ }
+}
+
+static u8 rtw_hal_set_mcc_start_setting(PADAPTER padapter, u8 status)
+{
+ u8 ret = _SUCCESS;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
+
+ if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
+ rtw_warn_on(1);
+ RTW_INFO("PS mode is not active before start mcc, force exit ps mode\n");
+ LeaveAllPowerSaveModeDirect(padapter);
+ }
+
+ if (dvobj->iface_nums > MAX_MCC_NUM) {
+ RTW_INFO("%s: current iface num(%d) > MAX_MCC_NUM(%d)\n", __func__, dvobj->iface_nums, MAX_MCC_NUM);
+ ret = _FAIL;
+ goto exit;
+ }
+
+ /* configure mcc switch channel setting */
+ rtw_hal_config_mcc_switch_channel_setting(padapter);
+
+ if (rtw_hal_decide_mcc_role(padapter) == _FAIL) {
+ ret = _FAIL;
+ goto exit;
+ }
+
+ /* set mcc status to indicate process mcc start setting */
+ rtw_hal_set_mcc_status(padapter, MCC_STATUS_PROCESS_MCC_START_SETTING);
+
+ /* only download rsvd page for connect */
+ if (status == MCC_SETCMD_STATUS_START_CONNECT) {
+ /* download mcc rsvd page */
+ rtw_hal_set_fw_mcc_rsvd_page(padapter);
+ rtw_hal_set_mcc_rsvdpage_cmd(padapter);
+ }
+
+ /* configure NoA setting */
+ rtw_hal_set_mcc_noa_cmd(padapter);
+
+ /* IQK value offload */
+ rtw_hal_set_mcc_IQK_offload_cmd(padapter);
+
+ /* set mac id to fw */
+ rtw_hal_set_mcc_macid_cmd(padapter);
+
+ /* set mcc parameter */
+ rtw_hal_set_mcc_ctrl_cmd(padapter, false);
+
+exit:
+ return ret;
+}
+
+static void rtw_hal_set_mcc_stop_setting(PADAPTER padapter, u8 status)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ _adapter *iface = NULL;
+ u8 i = 0;
+ /*
+ * when adapter disconnect, stop mcc mod
+ * total=0xf means stop mcc mode
+ */
+
+ switch (status) {
+ default:
+ /* let fw switch to other interface channel */
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if (iface == NULL)
+ continue;
+ /* use other interface to set cmd */
+ if (iface != padapter) {
+ rtw_hal_set_mcc_ctrl_cmd(iface, true);
+ break;
+ }
+ }
+ break;
+ }
+}
+
+static void rtw_hal_mcc_status_hdl(PADAPTER padapter, u8 status)
+{
+ switch (status) {
+ case MCC_SETCMD_STATUS_STOP_DISCONNECT:
+ rtw_hal_clear_mcc_status(padapter, MCC_STATUS_NEED_MCC | MCC_STATUS_DOING_MCC);
+ break;
+ case MCC_SETCMD_STATUS_STOP_SCAN_START:
+ rtw_hal_set_mcc_status(padapter, MCC_STATUS_NEED_MCC);
+ rtw_hal_clear_mcc_status(padapter, MCC_STATUS_DOING_MCC);
+ break;
+
+ case MCC_SETCMD_STATUS_START_CONNECT:
+ case MCC_SETCMD_STATUS_START_SCAN_DONE:
+ rtw_hal_set_mcc_status(padapter, MCC_STATUS_NEED_MCC | MCC_STATUS_DOING_MCC);
+ break;
+ default:
+ RTW_INFO(FUNC_ADPT_FMT" error status(%d)\n", FUNC_ADPT_ARG(padapter), status);
+ break;
+ }
+}
+
+static void rtw_hal_mcc_stop_posthdl(PADAPTER padapter)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ _adapter *iface = NULL;
+ u8 i = 0;
+
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if (iface == NULL)
+ continue;
+ /* release network queue */
+ rtw_netif_wake_queue(iface->pnetdev);
+ iface->mcc_adapterpriv.mcc_tx_bytes_from_kernel = 0;
+ iface->mcc_adapterpriv.mcc_last_tx_bytes_from_kernel = 0;
+ iface->mcc_adapterpriv.mcc_tx_bytes_to_port = 0;
+
+ if (iface->mcc_adapterpriv.role == MCC_ROLE_GO)
+ rtw_hal_mcc_remove_go_p2p_ie(iface);
+ }
+}
+
+static void rtw_hal_mcc_start_posthdl(PADAPTER padapter)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ _adapter *iface = NULL;
+ u8 i = 0;
+
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if (iface == NULL)
+ continue;
+ iface->mcc_adapterpriv.mcc_tx_bytes_from_kernel = 0;
+ iface->mcc_adapterpriv.mcc_last_tx_bytes_from_kernel = 0;
+ iface->mcc_adapterpriv.mcc_tx_bytes_to_port = 0;
+ }
+}
+
+/*
+ * rtw_hal_set_mcc_setting - set mcc setting
+ * @padapter: currnet padapter to stop/start MCC
+ * @stop: stop mcc or not
+ * @return val: 1 for SUCCESS, 0 for fail
+ */
+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 = jiffies;
+
+ RTW_INFO("===> "FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
+
+ rtw_sctx_init(&pmccobjpriv->mcc_sctx, MCC_EXPIRE_TIME);
+ pmccobjpriv->mcc_c2h_status = MCC_RPT_MAX;
+
+ if (stop == false) {
+ /* handle mcc start */
+ if (rtw_hal_set_mcc_start_setting(padapter, status) == _FAIL)
+ goto exit;
+
+ /* wait for C2H */
+ if (!rtw_sctx_wait(&pmccobjpriv->mcc_sctx, __func__))
+ RTW_INFO(FUNC_ADPT_FMT": wait for mcc start C2H time out\n", FUNC_ADPT_ARG(padapter));
+ else
+ ret = _SUCCESS;
+
+ if (ret == _SUCCESS) {
+ RTW_INFO(FUNC_ADPT_FMT": mcc start sucecssfully\n", FUNC_ADPT_ARG(padapter));
+ rtw_hal_mcc_start_posthdl(padapter);
+ }
+ } else {
+
+ /* set mcc status to indicate process mcc start setting */
+ rtw_hal_set_mcc_status(padapter, MCC_STATUS_PROCESS_MCC_STOP_SETTING);
+
+ /* handle mcc stop */
+ rtw_hal_set_mcc_stop_setting(padapter, status);
+
+ /* wait for C2H */
+ if (!rtw_sctx_wait(&pmccobjpriv->mcc_sctx, __func__))
+ RTW_INFO(FUNC_ADPT_FMT": wait for mcc stop C2H time out\n", FUNC_ADPT_ARG(padapter));
+ else {
+ ret = _SUCCESS;
+ rtw_hal_mcc_stop_posthdl(padapter);
+ }
+ }
+
+exit:
+
+ rtw_hal_mcc_status_hdl(padapter, status);
+ /* clear mcc status */
+ rtw_hal_clear_mcc_status(padapter
+ , MCC_STATUS_PROCESS_MCC_START_SETTING | MCC_STATUS_PROCESS_MCC_STOP_SETTING);
+
+ RTW_INFO(FUNC_ADPT_FMT" in %dms <===\n"
+ , FUNC_ADPT_ARG(padapter), rtw_get_passing_time_ms(start_time));
+ return ret;
+}
+
+/**
+ * rtw_hal_mcc_check_case_not_limit_traffic - handler flow ctrl for special case
+ * @cur_iface: fw stay channel setting of this iface
+ * @next_iface: fw will swich channel setting of this iface
+ */
+static void rtw_hal_mcc_check_case_not_limit_traffic(PADAPTER cur_iface, PADAPTER next_iface)
+{
+ u8 cur_bw = cur_iface->mlmeextpriv.cur_bwmode;
+ u8 next_bw = next_iface->mlmeextpriv.cur_bwmode;
+
+ /* for both interface are VHT80, doesn't limit_traffic according to iperf results */
+ if (cur_bw == CHANNEL_WIDTH_80 && next_bw == CHANNEL_WIDTH_80) {
+ cur_iface->mcc_adapterpriv.mcc_tp_limit = false;
+ next_iface->mcc_adapterpriv.mcc_tp_limit = false;
+ }
+}
+
+
+/**
+ * rtw_hal_mcc_sw_ch_fw_notify_hdl - handler flow ctrl
+ */
+static void rtw_hal_mcc_sw_ch_fw_notify_hdl(PADAPTER padapter)
+{
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ struct mcc_obj_priv *pmccobjpriv = &(pdvobjpriv->mcc_objpriv);
+ struct mcc_adapter_priv *cur_mccadapriv = NULL, *next_mccadapriv = NULL;
+ _adapter *iface = NULL, *cur_iface = NULL, *next_iface = NULL;
+ struct registry_priv *preg = &padapter->registrypriv;
+ u8 cur_op_ch = pdvobjpriv->oper_channel;
+ u8 i = 0, iface_num = pdvobjpriv->iface_nums, cur_order = 0, next_order = 0;
+ static u8 cnt = 1;
+ u32 single_tx_cri = preg->rtw_mcc_single_tx_cri;
+
+ for (i = 0; i < iface_num; i++) {
+ iface = pdvobjpriv->padapters[i];
+ if (cur_op_ch == iface->mlmeextpriv.cur_channel) {
+ cur_iface = iface;
+ cur_mccadapriv = &cur_iface->mcc_adapterpriv;
+ cur_order = cur_mccadapriv->order;
+ next_order = (cur_order + 1) % iface_num;
+ next_iface = pmccobjpriv->iface[next_order];
+ next_mccadapriv = &next_iface->mcc_adapterpriv;
+ break;
+ }
+ }
+
+ /* check other interface tx busy traffic or not under every 2 switch channel notify(Mbits/100ms) */
+ if (cnt == 2) {
+ cur_mccadapriv->mcc_tp = (cur_mccadapriv->mcc_tx_bytes_from_kernel
+ - cur_mccadapriv->mcc_last_tx_bytes_from_kernel) * 10 * 8 / 1024 / 1024;
+ cur_mccadapriv->mcc_last_tx_bytes_from_kernel = cur_mccadapriv->mcc_tx_bytes_from_kernel;
+
+ next_mccadapriv->mcc_tp = (next_mccadapriv->mcc_tx_bytes_from_kernel
+ - next_mccadapriv->mcc_last_tx_bytes_from_kernel) * 10 * 8 / 1024 / 1024;
+ next_mccadapriv->mcc_last_tx_bytes_from_kernel = next_mccadapriv->mcc_tx_bytes_from_kernel;
+
+ cnt = 1;
+ } else
+ cnt = 2;
+
+ /* check single TX or cuncurrnet TX */
+ if (next_mccadapriv->mcc_tp < single_tx_cri) {
+ /* single TX, does not stop */
+ cur_mccadapriv->mcc_tx_stop = false;
+ cur_mccadapriv->mcc_tp_limit = false;
+ } else {
+ /* concurrent TX, stop */
+ cur_mccadapriv->mcc_tx_stop = true;
+ cur_mccadapriv->mcc_tp_limit = true;
+ }
+
+ if (cur_mccadapriv->mcc_tp < single_tx_cri) {
+ next_mccadapriv->mcc_tx_stop = false;
+ next_mccadapriv->mcc_tp_limit = false;
+ } else {
+ next_mccadapriv->mcc_tx_stop = false;
+ next_mccadapriv->mcc_tp_limit = true;
+ next_mccadapriv->mcc_tx_bytes_to_port = 0;
+ }
+
+ /* stop current iface kernel queue or not */
+ if (cur_mccadapriv->mcc_tx_stop)
+ rtw_netif_stop_queue(cur_iface->pnetdev);
+ else
+ rtw_netif_wake_queue(cur_iface->pnetdev);
+
+ /* stop next iface kernel queue or not */
+ if (next_mccadapriv->mcc_tx_stop)
+ rtw_netif_stop_queue(next_iface->pnetdev);
+ else
+ rtw_netif_wake_queue(next_iface->pnetdev);
+
+ /* start xmit tasklet */
+ rtw_os_xmit_schedule(next_iface);
+
+ rtw_hal_mcc_check_case_not_limit_traffic(cur_iface, next_iface);
+
+ if (0) {
+ RTW_INFO("order:%d, mcc_tx_stop:%d, mcc_tp:%d\n",
+ cur_mccadapriv->order, cur_mccadapriv->mcc_tx_stop, cur_mccadapriv->mcc_tp);
+ dump_os_queue(0, cur_iface);
+ RTW_INFO("order:%d, mcc_tx_stop:%d, mcc_tp:%d\n",
+ next_mccadapriv->order, next_mccadapriv->mcc_tx_stop, next_mccadapriv->mcc_tp);
+ dump_os_queue(0, next_iface);
+ }
+}
+
+static void rtw_hal_mcc_update_noa_start_time_hdl(PADAPTER padapter, u8 buflen, u8 *tmpBuf)
+{
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ struct mcc_obj_priv *pmccobjpriv = &(pdvobjpriv->mcc_objpriv);
+ struct mcc_adapter_priv *pmccadapriv = NULL;
+ PADAPTER iface = NULL;
+ u8 i = 0;
+ u8 policy_idx = pmccobjpriv->policy_index;
+ u8 noa_tsf_sync_offset = mcc_switch_channel_policy_table[policy_idx][MCC_TSF_SYNC_OFFSET_IDX];
+ u8 noa_start_time_offset = mcc_switch_channel_policy_table[policy_idx][MCC_START_TIME_OFFSET_IDX];
+
+ for (i = 0; i < pdvobjpriv->iface_nums; i++) {
+ iface = pdvobjpriv->padapters[i];
+ if (iface == NULL)
+ continue;
+
+ pmccadapriv = &iface->mcc_adapterpriv;
+ /* GO & channel match */
+ if (pmccadapriv->role == MCC_ROLE_GO) {
+ /* convert GO TBTT from FW to noa_start_time(TU convert to mircosecond) */
+ pmccadapriv->noa_start_time = RTW_GET_LE32(tmpBuf + 2) + noa_start_time_offset * TU;
+
+ if (0) {
+ RTW_INFO("TBTT:0x%02x\n", RTW_GET_LE32(tmpBuf + 2));
+ RTW_INFO("noa_tsf_sync_offset:%d, noa_start_time_offset:%d\n", noa_tsf_sync_offset, noa_start_time_offset);
+ RTW_INFO(FUNC_ADPT_FMT"buf=0x%02x:0x%02x:0x%02x:0x%02x, noa_start_time=0x%02x\n"
+ , FUNC_ADPT_ARG(iface)
+ , tmpBuf[2]
+ , tmpBuf[3]
+ , tmpBuf[4]
+ , tmpBuf[5]
+ ,pmccadapriv->noa_start_time);
+ }
+
+ rtw_hal_mcc_update_go_p2p_ie(iface);
+
+ break;
+ }
+ }
+
+}
+
+/**
+ * rtw_hal_mcc_c2h_handler - mcc c2h handler
+ */
+void rtw_hal_mcc_c2h_handler(PADAPTER padapter, u8 buflen, u8 *tmpBuf)
+{
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv);
+ struct mcc_adapter_priv *pmccadapriv = &padapter->mcc_adapterpriv;
+ struct submit_ctx *mcc_sctx = &pmccobjpriv->mcc_sctx;
+ unsigned long irqL;
+
+ /* RTW_INFO("[length]=%d, [C2H data]="MAC_FMT"\n", buflen, MAC_ARG(tmpBuf)); */
+ /* To avoid reg is set, but driver recive c2h to set wrong oper_channel */
+ if (MCC_RPT_STOPMCC == pmccobjpriv->mcc_c2h_status) {
+ RTW_INFO(FUNC_ADPT_FMT" MCC alread stops return\n", FUNC_ADPT_ARG(padapter));
+ return;
+ }
+
+ pmccobjpriv->mcc_c2h_status = tmpBuf[0];
+ switch (pmccobjpriv->mcc_c2h_status) {
+ case MCC_RPT_SUCCESS:
+ pdvobjpriv->oper_channel = tmpBuf[1];
+ _enter_critical_bh(&pmccobjpriv->mcc_lock, &irqL);
+ pmccobjpriv->cur_mcc_success_cnt++;
+ _exit_critical_bh(&pmccobjpriv->mcc_lock, &irqL);
+ break;
+ case MCC_RPT_TXNULL_FAIL:
+ RTW_INFO("[MCC] TXNULL FAIL\n");
+ break;
+ case MCC_RPT_STOPMCC:
+ RTW_INFO("[MCC] MCC stop (time:%d)\n", jiffies);
+ pmccobjpriv->mcc_c2h_status = MCC_RPT_STOPMCC;
+ rtw_sctx_done(&mcc_sctx);
+ break;
+ case MCC_RPT_READY:
+ _enter_critical_bh(&pmccobjpriv->mcc_lock, &irqL);
+ /* initialize counter & time */
+ pmccobjpriv->mcc_launch_time = jiffies;
+ pmccobjpriv->mcc_c2h_status = MCC_RPT_READY;
+ pmccobjpriv->cur_mcc_success_cnt = 0;
+ pmccobjpriv->prev_mcc_success_cnt = 0;
+ pmccobjpriv->mcc_tolerance_time = MCC_TOLERANCE_TIME;
+ _exit_critical_bh(&pmccobjpriv->mcc_lock, &irqL);
+
+ RTW_INFO("[MCC] MCC ready (time:%d)\n", pmccobjpriv->mcc_launch_time);
+ rtw_sctx_done(&mcc_sctx);
+ break;
+ case MCC_RPT_SWICH_CHANNEL_NOTIFY:
+ pdvobjpriv->oper_channel = tmpBuf[1];
+ rtw_hal_mcc_sw_ch_fw_notify_hdl(padapter);
+ break;
+ case MCC_RPT_UPDATE_NOA_START_TIME:
+ rtw_hal_mcc_update_noa_start_time_hdl(padapter, buflen, tmpBuf);
+ break;
+ default:
+ /* RTW_INFO("[MCC] Other MCC status(%d)\n", pmccobjpriv->mcc_c2h_status); */
+ break;
+ }
+}
+
+
+/**
+ * rtw_hal_mcc_sw_status_check - check mcc swich channel status
+ * @padapter: primary adapter
+ */
+void rtw_hal_mcc_sw_status_check(PADAPTER padapter)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct mcc_obj_priv *pmccobjpriv = &(dvobj->mcc_objpriv);
+ struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
+ u8 cur_cnt = 0, prev_cnt = 0, diff_cnt = 0, check_ret = _FAIL;
+ unsigned long irqL;
+
+/* #define MCC_RESTART 1 */
+
+ if (!MCC_EN(padapter))
+ return;
+
+ _enter_critical_mutex(&pmccobjpriv->mcc_mutex, NULL);
+
+ if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC)) {
+
+ if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
+ rtw_warn_on(1);
+ RTW_INFO("PS mode is not active under mcc, force exit ps mode\n");
+ LeaveAllPowerSaveModeDirect(padapter);
+ }
+
+ if (rtw_get_passing_time_ms(pmccobjpriv->mcc_launch_time) > 2000) {
+ _enter_critical_bh(&pmccobjpriv->mcc_lock, &irqL);
+
+ cur_cnt = pmccobjpriv->cur_mcc_success_cnt;
+ prev_cnt = pmccobjpriv->prev_mcc_success_cnt;
+ if (cur_cnt < prev_cnt)
+ diff_cnt = (cur_cnt + 255) - prev_cnt;
+ else
+ diff_cnt = cur_cnt - prev_cnt;
+
+ if (diff_cnt < 30) {
+ pmccobjpriv->mcc_tolerance_time--;
+ RTW_INFO("%s: diff_cnt:%d, tolerance_time:%d\n",
+ __func__, diff_cnt, pmccobjpriv->mcc_tolerance_time);
+ } else
+ pmccobjpriv->mcc_tolerance_time = MCC_TOLERANCE_TIME;
+
+ pmccobjpriv->prev_mcc_success_cnt = pmccobjpriv->cur_mcc_success_cnt;
+
+ if (pmccobjpriv->mcc_tolerance_time != 0)
+ check_ret = _SUCCESS;
+
+ _exit_critical_bh(&pmccobjpriv->mcc_lock, &irqL);
+
+ if (check_ret != _SUCCESS) {
+ RTW_INFO("============ MCC swich channel check fail (%d)=============\n", diff_cnt);
+ /* restart MCC */
+ #ifdef MCC_RESTART
+ rtw_hal_set_mcc_setting(padapter, MCC_SETCMD_STATUS_STOP_DISCONNECT);
+ rtw_hal_set_mcc_setting(padapter, MCC_SETCMD_STATUS_START_CONNECT);
+ #endif /* MCC_RESTART */
+ }
+ } else {
+ _enter_critical_bh(&pmccobjpriv->mcc_lock, &irqL);
+ pmccobjpriv->prev_mcc_success_cnt = pmccobjpriv->cur_mcc_success_cnt;
+ _exit_critical_bh(&pmccobjpriv->mcc_lock, &irqL);
+ }
+
+ }
+ _exit_critical_mutex(&pmccobjpriv->mcc_mutex, NULL);
+}
+
+/**
+ * rtw_hal_mcc_change_scan_flag - change scan flag under mcc
+ *
+ * MCC mode under sitesurvey goto AP channel to tx bcn & data
+ * MCC mode under sitesurvey doesn't support TX data for station mode (FW not support)
+ *
+ * @padapter: the adapter to be change scan flag
+ * @ch: pointer to rerurn ch
+ * @bw: pointer to rerurn bw
+ * @offset: pointer to rerurn offset
+ */
+u8 rtw_hal_mcc_change_scan_flag(PADAPTER padapter, u8 *ch, u8 *bw, u8 *offset)
+{
+ u8 need_ch_setting_union = true, i = 0, flags = 0, role = 0;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct mcc_adapter_priv *pmccadapriv = NULL;
+ struct mlme_ext_priv *pmlmeext = NULL;
+
+ if (!MCC_EN(padapter))
+ goto exit;
+
+ if (!rtw_hal_check_mcc_status(padapter, MCC_STATUS_NEED_MCC))
+ goto exit;
+
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ if (!dvobj->padapters[i])
+ continue;
+
+ pmlmeext = &dvobj->padapters[i]->mlmeextpriv;
+ pmccadapriv = &dvobj->padapters[i]->mcc_adapterpriv;
+ role = pmccadapriv->role;
+
+ switch (role) {
+ case MCC_ROLE_AP:
+ case MCC_ROLE_GO:
+ *ch = pmlmeext->cur_channel;
+ *bw = pmlmeext->cur_bwmode;
+ *offset = pmlmeext->cur_ch_offset;
+ need_ch_setting_union = false;
+ break;
+ case MCC_ROLE_STA:
+ case MCC_ROLE_GC:
+ break;
+ default:
+ RTW_INFO("unknown role\n");
+ rtw_warn_on(1);
+ break;
+ }
+
+ /* check other scan flag */
+ flags = mlmeext_scan_backop_flags(pmlmeext);
+ if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC))
+ flags &= ~SS_BACKOP_PS_ANNC;
+
+ if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_TX_RESUME))
+ flags &= ~SS_BACKOP_TX_RESUME;
+
+ mlmeext_assign_scan_backop_flags(pmlmeext, flags);
+
+ }
+exit:
+ return need_ch_setting_union;
+}
+
+/**
+ * rtw_hal_mcc_calc_tx_bytes_from_kernel - calculte tx bytes from kernel to check concurrent tx or not
+ * @padapter: the adapter to be record tx bytes
+ * @len: data len
+ */
+inline void rtw_hal_mcc_calc_tx_bytes_from_kernel(PADAPTER padapter, u32 len)
+{
+ struct mcc_adapter_priv *pmccadapriv = &padapter->mcc_adapterpriv;
+
+ if (MCC_EN(padapter)) {
+ if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC)) {
+ pmccadapriv->mcc_tx_bytes_from_kernel += len;
+ if (0)
+ RTW_INFO("%s(order:%d): mcc tx bytes from kernel:%lld\n"
+ , __func__, pmccadapriv->order, pmccadapriv->mcc_tx_bytes_from_kernel);
+ }
+ }
+}
+
+/**
+ * rtw_hal_mcc_calc_tx_bytes_to_port - calculte tx bytes to write port in order to flow crtl
+ * @padapter: the adapter to be record tx bytes
+ * @len: data len
+ */
+inline void rtw_hal_mcc_calc_tx_bytes_to_port(PADAPTER padapter, u32 len)
+{
+ if (MCC_EN(padapter)) {
+ struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv);
+ struct mcc_adapter_priv *pmccadapriv = &padapter->mcc_adapterpriv;
+
+ if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC))
+ pmccadapriv->mcc_tx_bytes_to_port += len;
+ if (0)
+ RTW_INFO("%s(order:%d): mcc tx bytes to port:%d, mcc target tx bytes to port:%d\n"
+ , __func__, pmccadapriv->order, pmccadapriv->mcc_tx_bytes_to_port
+ , pmccadapriv->mcc_target_tx_bytes_to_port);
+ }
+}
+
+/**
+ * rtw_hal_mcc_stop_tx_bytes_to_port - stop write port to hw or not
+ * @padapter: the adapter to be stopped
+ */
+inline u8 rtw_hal_mcc_stop_tx_bytes_to_port(PADAPTER padapter)
+{
+ if (MCC_EN(padapter)) {
+ struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv);
+ struct mcc_adapter_priv *pmccadapriv = &padapter->mcc_adapterpriv;
+
+ if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC)) {
+ if (pmccadapriv->mcc_tp_limit) {
+ if (pmccadapriv->mcc_tx_bytes_to_port >= pmccadapriv->mcc_target_tx_bytes_to_port) {
+ pmccadapriv->mcc_tx_stop = true;
+ rtw_netif_stop_queue(padapter->pnetdev);
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+/**
+ * rtw_hal_set_mcc_setting_scan_start - setting mcc under scan start
+ * @padapter: the adapter to be setted
+ * @ch_setting_changed: softap channel setting to be changed or not
+ */
+u8 rtw_hal_set_mcc_setting_scan_start(PADAPTER padapter)
+{
+ u8 ret = _FAIL;
+
+ if (MCC_EN(padapter)) {
+ struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv);
+
+ _enter_critical_mutex(&pmccobjpriv->mcc_mutex, NULL);
+ if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_NEED_MCC)) {
+ if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC)) {
+ ret = rtw_hal_set_mcc_setting(padapter, MCC_SETCMD_STATUS_STOP_SCAN_START);
+ /* issue null data to all station connected to AP before scan */
+ rtw_hal_mcc_issue_null_data(padapter, 0, 1);
+ }
+ }
+ _exit_critical_mutex(&pmccobjpriv->mcc_mutex, NULL);
+ }
+
+ return ret;
+}
+
+/**
+ * rtw_hal_set_mcc_setting_scan_complete - setting mcc after scan commplete
+ * @padapter: the adapter to be setted
+ * @ch_setting_changed: softap channel setting to be changed or not
+ */
+u8 rtw_hal_set_mcc_setting_scan_complete(PADAPTER padapter)
+{
+ u8 ret = _FAIL;
+
+ if (MCC_EN(padapter)) {
+ struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv);
+
+ _enter_critical_mutex(&pmccobjpriv->mcc_mutex, NULL);
+
+ if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_NEED_MCC))
+ ret = rtw_hal_set_mcc_setting(padapter, MCC_SETCMD_STATUS_START_SCAN_DONE);
+
+ _exit_critical_mutex(&pmccobjpriv->mcc_mutex, NULL);
+ }
+
+ return ret;
+}
+
+
+/**
+ * rtw_hal_set_mcc_setting_start_bss_network - setting mcc under softap start
+ * @padapter: the adapter to be setted
+ * @chbw_grouped: channel bw offset can not be allowed or not
+ */
+u8 rtw_hal_set_mcc_setting_start_bss_network(PADAPTER padapter, u8 chbw_allow)
+{
+ u8 ret = _FAIL;
+
+ 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);
+
+ 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);
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * rtw_hal_set_mcc_setting_disconnect - setting mcc under mlme disconnect(stop softap/disconnect from AP)
+ * @padapter: the adapter to be setted
+ */
+u8 rtw_hal_set_mcc_setting_disconnect(PADAPTER padapter)
+{
+ u8 ret = _FAIL;
+
+ if (MCC_EN(padapter)) {
+ struct mcc_obj_priv *pmccobjpriv = &(adapter_to_dvobj(padapter)->mcc_objpriv);
+
+ _enter_critical_mutex(&pmccobjpriv->mcc_mutex, NULL);
+ if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_NEED_MCC)) {
+ if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC))
+ ret = rtw_hal_set_mcc_setting(padapter, MCC_SETCMD_STATUS_STOP_DISCONNECT);
+ }
+ _exit_critical_mutex(&pmccobjpriv->mcc_mutex, NULL);
+ }
+
+ return ret;
+}
+
+/**
+ * rtw_hal_set_mcc_setting_join_done_chk_ch - setting mcc under join done
+ * @padapter: the adapter to be checked
+ */
+u8 rtw_hal_set_mcc_setting_join_done_chk_ch(PADAPTER padapter)
+{
+ u8 ret = _FAIL;
+
+ if (MCC_EN(padapter)) {
+ struct mi_state mstate;
+
+ rtw_mi_status_no_self(padapter, &mstate);
+
+ if (MSTATE_STA_LD_NUM(&mstate) || MSTATE_STA_LG_NUM(&mstate) || MSTATE_AP_NUM(&mstate)) {
+ bool chbw_allow = true;
+ u8 u_ch, u_offset, u_bw;
+ struct mlme_ext_priv *cur_mlmeext = &padapter->mlmeextpriv;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+
+ if (rtw_mi_get_ch_setting_union_no_self(padapter, &u_ch, &u_bw, &u_offset) <= 0) {
+ dump_adapters_status(RTW_DBGDUMP , dvobj);
+ rtw_warn_on(1);
+ }
+
+ RTW_INFO(FUNC_ADPT_FMT" union no self: %u,%u,%u\n"
+ , FUNC_ADPT_ARG(padapter), u_ch, u_bw, u_offset);
+
+ /* chbw_allow? */
+ chbw_allow = rtw_is_chbw_grouped(cur_mlmeext->cur_channel
+ , cur_mlmeext->cur_bwmode, cur_mlmeext->cur_ch_offset
+ , u_ch, u_bw, u_offset);
+
+ RTW_INFO(FUNC_ADPT_FMT" chbw_allow:%d\n"
+ , FUNC_ADPT_ARG(padapter), chbw_allow);
+
+ /* if chbw_allow = false, start MCC setting */
+ if (chbw_allow == false) {
+ struct mcc_obj_priv *pmccobjpriv = &dvobj->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);
+ }
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * rtw_hal_set_mcc_setting_chk_start_clnt_join - check change channel under start clnt join
+ * @padapter: the adapter to be checked
+ * @ch: pointer to rerurn ch
+ * @bw: pointer to rerurn bw
+ * @offset: pointer to rerurn offset
+ * @chbw_allow: allow to use adapter's channel setting
+ */
+u8 rtw_hal_set_mcc_setting_chk_start_clnt_join(PADAPTER padapter, u8 *ch, u8 *bw, u8 *offset, u8 chbw_allow)
+{
+ u8 ret = _FAIL;
+
+ /* if chbw_allow = false under en_mcc = true, we do not change channel related setting */
+ if (MCC_EN(padapter)) {
+ /* restore union channel related setting to current channel related setting */
+ if (chbw_allow == false) {
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+
+ *ch = pmlmeext->cur_channel;
+ *bw = pmlmeext->cur_bwmode;
+ *offset = pmlmeext->cur_ch_offset;
+
+ RTW_INFO(FUNC_ADPT_FMT" en_mcc:%d(%d,%d,%d,)\n"
+ , FUNC_ADPT_ARG(padapter), padapter->registrypriv.en_mcc
+ , *ch, *bw, *offset);
+ ret = _SUCCESS;
+ }
+ }
+
+ return ret;
+}
+
+static void rtw_hal_mcc_dump_noa_content(void *sel, PADAPTER padapter)
+{
+ struct mcc_adapter_priv *pmccadapriv = NULL;
+ u8 *pos = NULL;
+ pmccadapriv = &padapter->mcc_adapterpriv;
+ /* last position for NoA attribute */
+ pos = pmccadapriv->p2p_go_noa_ie + pmccadapriv->p2p_go_noa_ie_len;
+
+
+ RTW_PRINT_SEL(sel, "\nStart to dump NoA Content\n");
+ RTW_PRINT_SEL(sel, "NoA Counts:%d\n", *(pos - 13));
+ RTW_PRINT_SEL(sel, "NoA Duration(TU):%d\n", (RTW_GET_LE32(pos - 12))/TU);
+ RTW_PRINT_SEL(sel, "NoA Interval(TU):%d\n", (RTW_GET_LE32(pos - 8))/TU);
+ RTW_PRINT_SEL(sel, "NoA Start time(microseconds):0x%02x\n", RTW_GET_LE32(pos - 4));
+ RTW_PRINT_SEL(sel, "End to dump NoA Content\n");
+}
+
+void rtw_hal_dump_mcc_info(void *sel, struct dvobj_priv *dvobj)
+{
+ struct mcc_obj_priv *pmccobjpriv = &(dvobj->mcc_objpriv);
+ struct mcc_adapter_priv *pmccadapriv = NULL;
+ _adapter *iface = NULL, *adapter = NULL;
+ struct registry_priv *regpriv = NULL;
+ u8 i = 0;
+
+ /* regpriv is common for all adapter */
+ adapter = dvobj->padapters[IFACE_ID0];
+
+ RTW_PRINT_SEL(sel, "**********************************************\n");
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if (!iface)
+ continue;
+
+ regpriv = &iface->registrypriv;
+ pmccadapriv = &iface->mcc_adapterpriv;
+ if (pmccadapriv) {
+ RTW_PRINT_SEL(sel, "adapter mcc info:\n");
+ RTW_PRINT_SEL(sel, "ifname:%s\n", ADPT_ARG(iface));
+ RTW_PRINT_SEL(sel, "order:%d\n", pmccadapriv->order);
+ RTW_PRINT_SEL(sel, "duration:%d\n", pmccadapriv->mcc_duration);
+ RTW_PRINT_SEL(sel, "target tx bytes:%d\n", pmccadapriv->mcc_target_tx_bytes_to_port);
+ RTW_PRINT_SEL(sel, "current TP:%d\n", pmccadapriv->mcc_tp);
+ RTW_PRINT_SEL(sel, "mgmt queue macid:%d\n", pmccadapriv->mgmt_queue_macid);
+ RTW_PRINT_SEL(sel, "macid bitmap:0x%02x\n\n", pmccadapriv->mcc_macid_bitmap);
+ RTW_PRINT_SEL(sel, "registry data:\n");
+ RTW_PRINT_SEL(sel, "en_mcc:%d\n", regpriv->en_mcc);
+ RTW_PRINT_SEL(sel, "ap target tx TP(BW:20M):%d Mbps\n", regpriv->rtw_mcc_ap_bw20_target_tx_tp);
+ RTW_PRINT_SEL(sel, "ap target tx TP(BW:40M):%d Mbps\n", regpriv->rtw_mcc_ap_bw40_target_tx_tp);
+ RTW_PRINT_SEL(sel, "ap target tx TP(BW:80M):%d Mbps\n", regpriv->rtw_mcc_ap_bw80_target_tx_tp);
+ RTW_PRINT_SEL(sel, "sta target tx TP(BW:20M):%d Mbps\n", regpriv->rtw_mcc_sta_bw20_target_tx_tp);
+ RTW_PRINT_SEL(sel, "sta target tx TP(BW:40M ):%d Mbps\n", regpriv->rtw_mcc_sta_bw40_target_tx_tp);
+ RTW_PRINT_SEL(sel, "sta target tx TP(BW:80M):%d Mbps\n", regpriv->rtw_mcc_sta_bw80_target_tx_tp);
+ RTW_PRINT_SEL(sel, "single tx criteria:%d Mbps\n", regpriv->rtw_mcc_single_tx_cri);
+ if (MLME_IS_GO(iface))
+ rtw_hal_mcc_dump_noa_content(sel, iface);
+ RTW_PRINT_SEL(sel, "**********************************************\n");
+ }
+ }
+ RTW_PRINT_SEL(sel, "------------------------------------------\n");
+ RTW_PRINT_SEL(sel, "policy index:%d\n", pmccobjpriv->policy_index);
+ RTW_PRINT_SEL(sel, "------------------------------------------\n");
+ RTW_PRINT_SEL(sel, "define data:\n");
+ RTW_PRINT_SEL(sel, "ap target tx TP(BW:20M):%d Mbps\n", MCC_AP_BW20_TARGET_TX_TP);
+ RTW_PRINT_SEL(sel, "ap target tx TP(BW:40M):%d Mbps\n", MCC_AP_BW40_TARGET_TX_TP);
+ RTW_PRINT_SEL(sel, "ap target tx TP(BW:80M):%d Mbps\n", MCC_AP_BW80_TARGET_TX_TP);
+ RTW_PRINT_SEL(sel, "sta target tx TP(BW:20M):%d Mbps\n", MCC_STA_BW20_TARGET_TX_TP);
+ RTW_PRINT_SEL(sel, "sta target tx TP(BW:40M):%d Mbps\n", MCC_STA_BW40_TARGET_TX_TP);
+ RTW_PRINT_SEL(sel, "sta target tx TP(BW:80M):%d Mbps\n", MCC_STA_BW80_TARGET_TX_TP);
+ RTW_PRINT_SEL(sel, "single tx criteria:%d Mbps\n", MCC_SINGLE_TX_CRITERIA);
+ RTW_PRINT_SEL(sel, "------------------------------------------\n");
+}
+
+inline void update_mcc_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
+{
+ if (MCC_EN(padapter)) {
+ if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC)) {
+ /* use QSLT_MGNT to check mgnt queue or bcn queue */
+ if (pattrib->qsel == QSLT_MGNT) {
+ pattrib->mac_id = padapter->mcc_adapterpriv.mgmt_queue_macid;
+ pattrib->qsel = QSLT_VO;
+ }
+ }
+ }
+}
+
+inline u8 rtw_hal_mcc_link_status_chk(_adapter *padapter, const char *msg)
+{
+ u8 ret = true, i = 0;
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ _adapter *iface;
+ struct mlme_ext_priv *mlmeext;
+
+ if (MCC_EN(padapter)) {
+ if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_NEED_MCC)) {
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ mlmeext = &iface->mlmeextpriv;
+ if (mlmeext_scan_state(mlmeext) != SCAN_DISABLE) {
+ #ifdef DBG_EXPIRATION_CHK
+ RTW_INFO(FUNC_ADPT_FMT" don't enter %s under scan for MCC mode\n", FUNC_ADPT_ARG(padapter), msg);
+ #endif
+ ret = false;
+ goto exit;
+ }
+ }
+ }
+ }
+
+exit:
+ return ret;
+}
+
+void rtw_hal_mcc_issue_null_data(_adapter *padapter, u8 chbw_allow, u8 ps_mode)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ _adapter *iface = NULL;
+ u32 start = jiffies;
+ u8 i = 0;
+
+ if (!MCC_EN(padapter))
+ return;
+
+ if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC))
+ return;
+
+ if (chbw_allow == true)
+ return;
+
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ /* issue null data to inform ap station will leave */
+ if (is_client_associated_to_ap(iface)) {
+ struct mlme_ext_priv *mlmeext = &iface->mlmeextpriv;
+ u8 ch = mlmeext->cur_channel;
+ u8 bw = mlmeext->cur_bwmode;
+ u8 offset = mlmeext->cur_ch_offset;
+
+ set_channel_bwmode(iface, ch, bw, offset);
+ issue_nulldata(iface, NULL, ps_mode, 3, 50);
+ }
+ }
+ RTW_INFO("%s(%d ms)\n", __func__, rtw_get_passing_time_ms(start));
+}
+
+u8 *rtw_hal_mcc_append_go_p2p_ie(PADAPTER padapter, u8 *pframe, u32 *len)
+{
+ struct mcc_adapter_priv *pmccadapriv = &padapter->mcc_adapterpriv;
+
+ if (!MCC_EN(padapter))
+ return pframe;
+
+ if (!rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC))
+ return pframe;
+
+ if (pmccadapriv->p2p_go_noa_ie_len == 0)
+ return pframe;
+
+ memcpy(pframe, pmccadapriv->p2p_go_noa_ie, pmccadapriv->p2p_go_noa_ie_len);
+ *len = *len + pmccadapriv->p2p_go_noa_ie_len;
+
+ return pframe + pmccadapriv->p2p_go_noa_ie_len;
+}
+
+void rtw_hal_dump_mcc_policy_table(void *sel)
+{
+ u8 idx = 0;
+ RTW_PRINT_SEL(sel, "duration\t,tsf sync offset\t,start time offset\t,interval\t,guard offset0\t,guard offset1\n");
+
+ for (idx = 0; idx < mcc_max_policy_num; idx ++) {
+ RTW_PRINT_SEL(sel, "%d\t\t,%d\t\t\t,%d\t\t\t,%d\t\t,%d\t\t,%d\n"
+ , mcc_switch_channel_policy_table[idx][MCC_DURATION_IDX]
+ , mcc_switch_channel_policy_table[idx][MCC_TSF_SYNC_OFFSET_IDX]
+ , mcc_switch_channel_policy_table[idx][MCC_START_TIME_OFFSET_IDX]
+ , mcc_switch_channel_policy_table[idx][MCC_INTERVAL_IDX]
+ , mcc_switch_channel_policy_table[idx][MCC_GUARD_OFFSET0_IDX]
+ , mcc_switch_channel_policy_table[idx][MCC_GUARD_OFFSET1_IDX]);
+ }
+}
+
+#endif /* CONFIG_MCC_MODE */
diff --git a/drivers/staging/rtl8188eu/hal/hal_mp.c b/drivers/staging/rtl8188eu/hal/hal_mp.c
new file mode 100644
index 000000000000..58dd2adf05df
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal_mp.c
@@ -0,0 +1,883 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _HAL_MP_C_
+
+#include <drv_types.h>
+
+#ifdef CONFIG_MP_INCLUDED
+
+#ifdef RTW_HALMAC
+ #include <hal_data.h> /* struct HAL_DATA_TYPE, RF register definition and etc. */
+#else /* !RTW_HALMAC */
+ #include <rtl8188e_hal.h>
+#endif /* !RTW_HALMAC */
+
+
+static u8 MgntQuery_NssTxRate(u16 Rate)
+{
+ u8 NssNum = RF_TX_NUM_NONIMPLEMENT;
+
+ if ((Rate >= MGN_MCS8 && Rate <= MGN_MCS15) ||
+ (Rate >= MGN_VHT2SS_MCS0 && Rate <= MGN_VHT2SS_MCS9))
+ NssNum = RF_2TX;
+ else if ((Rate >= MGN_MCS16 && Rate <= MGN_MCS23) ||
+ (Rate >= MGN_VHT3SS_MCS0 && Rate <= MGN_VHT3SS_MCS9))
+ NssNum = RF_3TX;
+ else if ((Rate >= MGN_MCS24 && Rate <= MGN_MCS31) ||
+ (Rate >= MGN_VHT4SS_MCS0 && Rate <= MGN_VHT4SS_MCS9))
+ NssNum = RF_4TX;
+ else
+ NssNum = RF_1TX;
+
+ return NssNum;
+}
+
+void hal_mpt_SwitchRfSetting(PADAPTER pAdapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.mpt_ctx);
+ u8 ChannelToSw = pMptCtx->MptChannelToSw;
+ u32 ulRateIdx = pMptCtx->mpt_rate_index;
+ u32 ulbandwidth = pMptCtx->MptBandWidth;
+
+ /* <20120525, Kordan> Dynamic mechanism for APK, asked by Dennis.*/
+ if (IS_HARDWARE_TYPE_8188E(pAdapter)) {
+ phy_set_rf_reg(pAdapter, ODM_RF_PATH_A, RF_0x52, 0x000F0, pMptCtx->backup0x52_RF_A);
+ phy_set_rf_reg(pAdapter, ODM_RF_PATH_B, RF_0x52, 0x000F0, pMptCtx->backup0x52_RF_B);
+ }
+}
+
+s32 hal_mpt_SetPowerTracking(PADAPTER padapter, u8 enable)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &(pHalData->odmpriv);
+
+
+ if (!netif_running(padapter->pnetdev)) {
+ return _FAIL;
+ }
+
+ if (check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE) == false) {
+ return _FAIL;
+ }
+ if (enable)
+ pDM_Odm->rf_calibrate_info.txpowertrack_control = true;
+ else
+ pDM_Odm->rf_calibrate_info.txpowertrack_control = false;
+
+ return _SUCCESS;
+}
+
+void hal_mpt_GetPowerTracking(PADAPTER padapter, u8 *enable)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &(pHalData->odmpriv);
+
+
+ *enable = pDM_Odm->rf_calibrate_info.txpowertrack_control;
+}
+
+
+void hal_mpt_CCKTxPowerAdjust(PADAPTER Adapter, bool bInCH14)
+{
+ u32 TempVal = 0, TempVal2 = 0, TempVal3 = 0;
+ u32 CurrCCKSwingVal = 0, CCKSwingIndex = 12;
+ u8 i;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ PMPT_CONTEXT pMptCtx = &(Adapter->mppriv.mpt_ctx);
+ u8 u1Channel = pHalData->current_channel;
+ u32 ulRateIdx = pMptCtx->mpt_rate_index;
+ u8 DataRate = 0xFF;
+
+ DataRate = mpt_to_mgnt_rate(ulRateIdx);
+
+ if (u1Channel == 14 && IS_CCK_RATE(DataRate))
+ pHalData->bCCKinCH14 = true;
+ else
+ pHalData->bCCKinCH14 = false;
+
+ /* get current cck swing value and check 0xa22 & 0xa23 later to match the table.*/
+ CurrCCKSwingVal = read_bbreg(Adapter, rCCK0_TxFilter1, bMaskHWord);
+
+ if (!pHalData->bCCKinCH14) {
+ /* Readback the current bb cck swing value and compare with the table to */
+ /* get the current swing index */
+ for (i = 0; i < CCK_TABLE_SIZE; i++) {
+ if (((CurrCCKSwingVal & 0xff) == (u32)cck_swing_table_ch1_ch13[i][0]) &&
+ (((CurrCCKSwingVal & 0xff00) >> 8) == (u32)cck_swing_table_ch1_ch13[i][1])) {
+ CCKSwingIndex = i;
+ break;
+ }
+ }
+
+ /*Write 0xa22 0xa23*/
+ TempVal = cck_swing_table_ch1_ch13[CCKSwingIndex][0] +
+ (cck_swing_table_ch1_ch13[CCKSwingIndex][1] << 8);
+
+
+ /*Write 0xa24 ~ 0xa27*/
+ TempVal2 = 0;
+ TempVal2 = cck_swing_table_ch1_ch13[CCKSwingIndex][2] +
+ (cck_swing_table_ch1_ch13[CCKSwingIndex][3] << 8) +
+ (cck_swing_table_ch1_ch13[CCKSwingIndex][4] << 16) +
+ (cck_swing_table_ch1_ch13[CCKSwingIndex][5] << 24);
+
+ /*Write 0xa28 0xa29*/
+ TempVal3 = 0;
+ TempVal3 = cck_swing_table_ch1_ch13[CCKSwingIndex][6] +
+ (cck_swing_table_ch1_ch13[CCKSwingIndex][7] << 8);
+ } else {
+ for (i = 0; i < CCK_TABLE_SIZE; i++) {
+ if (((CurrCCKSwingVal & 0xff) == (u32)cck_swing_table_ch14[i][0]) &&
+ (((CurrCCKSwingVal & 0xff00) >> 8) == (u32)cck_swing_table_ch14[i][1])) {
+ CCKSwingIndex = i;
+ break;
+ }
+ }
+
+ /*Write 0xa22 0xa23*/
+ TempVal = cck_swing_table_ch14[CCKSwingIndex][0] +
+ (cck_swing_table_ch14[CCKSwingIndex][1] << 8);
+
+ /*Write 0xa24 ~ 0xa27*/
+ TempVal2 = 0;
+ TempVal2 = cck_swing_table_ch14[CCKSwingIndex][2] +
+ (cck_swing_table_ch14[CCKSwingIndex][3] << 8) +
+ (cck_swing_table_ch14[CCKSwingIndex][4] << 16) +
+ (cck_swing_table_ch14[CCKSwingIndex][5] << 24);
+
+ /*Write 0xa28 0xa29*/
+ TempVal3 = 0;
+ TempVal3 = cck_swing_table_ch14[CCKSwingIndex][6] +
+ (cck_swing_table_ch14[CCKSwingIndex][7] << 8);
+ }
+
+ write_bbreg(Adapter, rCCK0_TxFilter1, bMaskHWord, TempVal);
+ write_bbreg(Adapter, rCCK0_TxFilter2, bMaskDWord, TempVal2);
+ write_bbreg(Adapter, rCCK0_DebugPort, bMaskLWord, TempVal3);
+}
+
+void hal_mpt_SetChannel(PADAPTER pAdapter)
+{
+ u8 eRFPath;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &(pHalData->odmpriv);
+ struct mp_priv *pmp = &pAdapter->mppriv;
+ u8 channel = pmp->channel;
+ u8 bandwidth = pmp->bandwidth;
+
+ hal_mpt_SwitchRfSetting(pAdapter);
+
+ pHalData->bSwChnl = true;
+ pHalData->bSetChnlBW = true;
+ rtw_hal_set_chnl_bw(pAdapter, channel, bandwidth, 0, 0);
+
+ hal_mpt_CCKTxPowerAdjust(pAdapter, pHalData->bCCKinCH14);
+
+}
+
+/*
+ * Notice
+ * Switch bandwitdth may change center frequency(channel)
+ */
+void hal_mpt_SetBandwidth(PADAPTER pAdapter)
+{
+ struct mp_priv *pmp = &pAdapter->mppriv;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+
+ u8 channel = pmp->channel;
+ u8 bandwidth = pmp->bandwidth;
+
+ pHalData->bSwChnl = true;
+ pHalData->bSetChnlBW = true;
+ rtw_hal_set_chnl_bw(pAdapter, channel, bandwidth, 0, 0);
+
+ hal_mpt_SwitchRfSetting(pAdapter);
+}
+
+static void mpt_SetTxPower_Old(PADAPTER pAdapter, MPT_TXPWR_DEF Rate, u8 *pTxPower)
+{
+ switch (Rate) {
+ case MPT_CCK: {
+ u32 TxAGC = 0, pwr = 0;
+ u8 rf;
+
+ pwr = pTxPower[ODM_RF_PATH_A];
+ if (pwr < 0x3f) {
+ TxAGC = (pwr << 16) | (pwr << 8) | (pwr);
+ phy_set_bb_reg(pAdapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, pTxPower[ODM_RF_PATH_A]);
+ phy_set_bb_reg(pAdapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, TxAGC);
+ }
+ pwr = pTxPower[ODM_RF_PATH_B];
+ if (pwr < 0x3f) {
+ TxAGC = (pwr << 16) | (pwr << 8) | (pwr);
+ phy_set_bb_reg(pAdapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, pTxPower[ODM_RF_PATH_B]);
+ phy_set_bb_reg(pAdapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, TxAGC);
+ }
+ }
+ break;
+
+ case MPT_OFDM_AND_HT: {
+ u32 TxAGC = 0;
+ u8 pwr = 0, rf;
+
+ pwr = pTxPower[0];
+ if (pwr < 0x3f) {
+ TxAGC |= ((pwr << 24) | (pwr << 16) | (pwr << 8) | pwr);
+ RTW_INFO("HT Tx-rf(A) Power = 0x%x\n", TxAGC);
+ phy_set_bb_reg(pAdapter, rTxAGC_A_Rate18_06, bMaskDWord, TxAGC);
+ phy_set_bb_reg(pAdapter, rTxAGC_A_Rate54_24, bMaskDWord, TxAGC);
+ phy_set_bb_reg(pAdapter, rTxAGC_A_Mcs03_Mcs00, bMaskDWord, TxAGC);
+ phy_set_bb_reg(pAdapter, rTxAGC_A_Mcs07_Mcs04, bMaskDWord, TxAGC);
+ phy_set_bb_reg(pAdapter, rTxAGC_A_Mcs11_Mcs08, bMaskDWord, TxAGC);
+ phy_set_bb_reg(pAdapter, rTxAGC_A_Mcs15_Mcs12, bMaskDWord, TxAGC);
+ }
+ TxAGC = 0;
+ pwr = pTxPower[1];
+ if (pwr < 0x3f) {
+ TxAGC |= ((pwr << 24) | (pwr << 16) | (pwr << 8) | pwr);
+ RTW_INFO("HT Tx-rf(B) Power = 0x%x\n", TxAGC);
+ phy_set_bb_reg(pAdapter, rTxAGC_B_Rate18_06, bMaskDWord, TxAGC);
+ phy_set_bb_reg(pAdapter, rTxAGC_B_Rate54_24, bMaskDWord, TxAGC);
+ phy_set_bb_reg(pAdapter, rTxAGC_B_Mcs03_Mcs00, bMaskDWord, TxAGC);
+ phy_set_bb_reg(pAdapter, rTxAGC_B_Mcs07_Mcs04, bMaskDWord, TxAGC);
+ phy_set_bb_reg(pAdapter, rTxAGC_B_Mcs11_Mcs08, bMaskDWord, TxAGC);
+ phy_set_bb_reg(pAdapter, rTxAGC_B_Mcs15_Mcs12, bMaskDWord, TxAGC);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ RTW_INFO("<===mpt_SetTxPower_Old()\n");
+}
+
+static void
+mpt_SetTxPower(
+ PADAPTER pAdapter,
+ MPT_TXPWR_DEF Rate,
+ u8 * pTxPower
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+
+ u8 path = 0 , i = 0, MaxRate = MGN_6M;
+ u8 StartPath = ODM_RF_PATH_A, EndPath = ODM_RF_PATH_B;
+
+ switch (Rate) {
+ case MPT_CCK: {
+ u8 rate[] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M};
+
+ for (path = StartPath; path <= EndPath; path++)
+ for (i = 0; i < sizeof(rate); ++i)
+ PHY_SetTxPowerIndex(pAdapter, pTxPower[path], path, rate[i]);
+ }
+ break;
+ case MPT_OFDM: {
+ u8 rate[] = {
+ MGN_6M, MGN_9M, MGN_12M, MGN_18M,
+ MGN_24M, MGN_36M, MGN_48M, MGN_54M,
+ };
+
+ for (path = StartPath; path <= EndPath; path++)
+ for (i = 0; i < sizeof(rate); ++i)
+ PHY_SetTxPowerIndex(pAdapter, pTxPower[path], path, rate[i]);
+ }
+ break;
+ case MPT_HT: {
+ u8 rate[] = {
+ MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4,
+ MGN_MCS5, MGN_MCS6, MGN_MCS7, MGN_MCS8, MGN_MCS9,
+ MGN_MCS10, MGN_MCS11, MGN_MCS12, MGN_MCS13, MGN_MCS14,
+ MGN_MCS15, MGN_MCS16, MGN_MCS17, MGN_MCS18, MGN_MCS19,
+ MGN_MCS20, MGN_MCS21, MGN_MCS22, MGN_MCS23, MGN_MCS24,
+ MGN_MCS25, MGN_MCS26, MGN_MCS27, MGN_MCS28, MGN_MCS29,
+ MGN_MCS30, MGN_MCS31,
+ };
+ if (pHalData->rf_type == RF_3T3R)
+ MaxRate = MGN_MCS23;
+ else if (pHalData->rf_type == RF_2T2R)
+ MaxRate = MGN_MCS15;
+ else
+ MaxRate = MGN_MCS7;
+ for (path = StartPath; path <= EndPath; path++) {
+ for (i = 0; i < sizeof(rate); ++i) {
+ if (rate[i] > MaxRate)
+ break;
+ PHY_SetTxPowerIndex(pAdapter, pTxPower[path], path, rate[i]);
+ }
+ }
+ }
+ break;
+ case MPT_VHT: {
+ u8 rate[] = {
+ MGN_VHT1SS_MCS0, MGN_VHT1SS_MCS1, MGN_VHT1SS_MCS2, MGN_VHT1SS_MCS3, MGN_VHT1SS_MCS4,
+ MGN_VHT1SS_MCS5, MGN_VHT1SS_MCS6, MGN_VHT1SS_MCS7, MGN_VHT1SS_MCS8, MGN_VHT1SS_MCS9,
+ MGN_VHT2SS_MCS0, MGN_VHT2SS_MCS1, MGN_VHT2SS_MCS2, MGN_VHT2SS_MCS3, MGN_VHT2SS_MCS4,
+ MGN_VHT2SS_MCS5, MGN_VHT2SS_MCS6, MGN_VHT2SS_MCS7, MGN_VHT2SS_MCS8, MGN_VHT2SS_MCS9,
+ MGN_VHT3SS_MCS0, MGN_VHT3SS_MCS1, MGN_VHT3SS_MCS2, MGN_VHT3SS_MCS3, MGN_VHT3SS_MCS4,
+ MGN_VHT3SS_MCS5, MGN_VHT3SS_MCS6, MGN_VHT3SS_MCS7, MGN_VHT3SS_MCS8, MGN_VHT3SS_MCS9,
+ 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_3T3R)
+ MaxRate = MGN_VHT3SS_MCS9;
+ else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R)
+ MaxRate = MGN_VHT2SS_MCS9;
+ else
+ MaxRate = MGN_VHT1SS_MCS9;
+
+ for (path = StartPath; path <= EndPath; path++) {
+ for (i = 0; i < sizeof(rate); ++i) {
+ if (rate[i] > MaxRate)
+ break;
+ PHY_SetTxPowerIndex(pAdapter, pTxPower[path], path, rate[i]);
+ }
+ }
+ }
+ break;
+ default:
+ RTW_INFO("<===mpt_SetTxPower: Illegal channel!!\n");
+ break;
+ }
+}
+
+void hal_mpt_SetTxPower(PADAPTER pAdapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.mpt_ctx);
+ struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
+
+ if (pHalData->rf_chip < RF_TYPE_MAX) {
+ if (IS_HARDWARE_TYPE_8188E(pAdapter)) {
+ u8 path = (pHalData->antenna_tx_path == ANTENNA_A) ? (ODM_RF_PATH_A) : (ODM_RF_PATH_B);
+
+ RTW_INFO("===> MPT_ProSetTxPower: Old\n");
+
+ mpt_SetTxPower_Old(pAdapter, MPT_CCK, pMptCtx->TxPwrLevel);
+ mpt_SetTxPower_Old(pAdapter, MPT_OFDM_AND_HT, pMptCtx->TxPwrLevel);
+
+ } else {
+ RTW_INFO("===> MPT_ProSetTxPower: Jaguar/Jaguar2\n");
+ mpt_SetTxPower(pAdapter, MPT_CCK, pMptCtx->TxPwrLevel);
+ mpt_SetTxPower(pAdapter, MPT_OFDM, pMptCtx->TxPwrLevel);
+ mpt_SetTxPower(pAdapter, MPT_HT, pMptCtx->TxPwrLevel);
+ mpt_SetTxPower(pAdapter, MPT_VHT, pMptCtx->TxPwrLevel);
+ }
+ } else
+ RTW_INFO("RFChipID < RF_TYPE_MAX, the RF chip is not supported - %d\n", pHalData->rf_chip);
+
+ odm_clear_txpowertracking_state(pDM_Odm);
+}
+
+void hal_mpt_SetDataRate(PADAPTER pAdapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.mpt_ctx);
+ u32 DataRate;
+
+ DataRate = mpt_to_mgnt_rate(pMptCtx->mpt_rate_index);
+
+ hal_mpt_SwitchRfSetting(pAdapter);
+
+ hal_mpt_CCKTxPowerAdjust(pAdapter, pHalData->bCCKinCH14);
+}
+
+#define RF_PATH_AB 22
+
+static void mpt_SetRFPath_819X(PADAPTER pAdapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.mpt_ctx);
+ u32 ulAntennaTx, ulAntennaRx;
+ R_ANTENNA_SELECT_OFDM *p_ofdm_tx; /* OFDM Tx register */
+ R_ANTENNA_SELECT_CCK *p_cck_txrx;
+ u8 r_rx_antenna_ofdm = 0, r_ant_select_cck_val = 0;
+ u8 chgTx = 0, chgRx = 0;
+ u32 r_ant_sel_cck_val = 0, r_ant_select_ofdm_val = 0, r_ofdm_tx_en_val = 0;
+
+ ulAntennaTx = pHalData->antenna_tx_path;
+ ulAntennaRx = pHalData->AntennaRxPath;
+
+ p_ofdm_tx = (R_ANTENNA_SELECT_OFDM *)&r_ant_select_ofdm_val;
+ p_cck_txrx = (R_ANTENNA_SELECT_CCK *)&r_ant_select_cck_val;
+
+ p_ofdm_tx->r_ant_ht1 = 0x1;
+ p_ofdm_tx->r_ant_ht2 = 0x2;/*Second TX RF path is A*/
+ p_ofdm_tx->r_ant_non_ht = 0x3;/*/ 0x1+0x2=0x3 */
+
+ switch (ulAntennaTx) {
+ case ANTENNA_A:
+ p_ofdm_tx->r_tx_antenna = 0x1;
+ r_ofdm_tx_en_val = 0x1;
+ p_ofdm_tx->r_ant_l = 0x1;
+ p_ofdm_tx->r_ant_ht_s1 = 0x1;
+ p_ofdm_tx->r_ant_non_ht_s1 = 0x1;
+ p_cck_txrx->r_ccktx_enable = 0x8;
+ chgTx = 1;
+ /*/ From SD3 Willis suggestion !!! Set RF A=TX and B as standby*/
+ {
+ phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2);
+ phy_set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 1);
+ r_ofdm_tx_en_val = 0x3;
+ /*/ Power save*/
+ /*/cosa r_ant_select_ofdm_val = 0x11111111;*/
+ /*/ We need to close RFB by SW control*/
+ if (pHalData->rf_type == RF_2T2R) {
+ phy_set_bb_reg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0);
+ phy_set_bb_reg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 1);
+ phy_set_bb_reg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0);
+ phy_set_bb_reg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 1);
+ phy_set_bb_reg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 0);
+ }
+ }
+ pMptCtx->mpt_rf_path = ODM_RF_PATH_A;
+ break;
+ case ANTENNA_B:
+ p_ofdm_tx->r_tx_antenna = 0x2;
+ r_ofdm_tx_en_val = 0x2;
+ p_ofdm_tx->r_ant_l = 0x2;
+ p_ofdm_tx->r_ant_ht_s1 = 0x2;
+ p_ofdm_tx->r_ant_non_ht_s1 = 0x2;
+ p_cck_txrx->r_ccktx_enable = 0x4;
+ chgTx = 1;
+ /*/ From SD3 Willis suggestion !!! Set RF A as standby*/
+ {
+ phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 1);
+ phy_set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2);
+
+ /*/ 2008/10/31 MH From SD3 Willi's suggestion. We must read RF 1T table.*/
+ /*/ 2009/01/08 MH From Sd3 Willis. We need to close RFA by SW control*/
+ if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_1T2R) {
+ phy_set_bb_reg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 1);
+ phy_set_bb_reg(pAdapter, rFPGA0_XA_RFInterfaceOE, BIT10, 0);
+ phy_set_bb_reg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0);
+ /*/phy_set_bb_reg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0);*/
+ phy_set_bb_reg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 0);
+ phy_set_bb_reg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 1);
+ }
+ }
+ pMptCtx->mpt_rf_path = ODM_RF_PATH_B;
+ break;
+ case ANTENNA_AB:/*/ For 8192S*/
+ p_ofdm_tx->r_tx_antenna = 0x3;
+ r_ofdm_tx_en_val = 0x3;
+ p_ofdm_tx->r_ant_l = 0x3;
+ p_ofdm_tx->r_ant_ht_s1 = 0x3;
+ p_ofdm_tx->r_ant_non_ht_s1 = 0x3;
+ p_cck_txrx->r_ccktx_enable = 0xC;
+ chgTx = 1;
+ /*/ From SD3Willis suggestion !!! Set RF B as standby*/
+ {
+ phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2);
+ phy_set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2);
+ /* Disable Power save*/
+ /*cosa r_ant_select_ofdm_val = 0x3321333;*/
+ /* 2009/01/08 MH From Sd3 Willis. We need to enable RFA/B by SW control*/
+ if (pHalData->rf_type == RF_2T2R) {
+ phy_set_bb_reg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0);
+
+ phy_set_bb_reg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0);
+ /*/phy_set_bb_reg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0);*/
+ phy_set_bb_reg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 1);
+ phy_set_bb_reg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 1);
+ }
+ }
+ pMptCtx->mpt_rf_path = ODM_RF_PATH_AB;
+ break;
+ default:
+ break;
+ }
+ switch (ulAntennaRx) {
+ case ANTENNA_A:
+ r_rx_antenna_ofdm = 0x1; /* A*/
+ p_cck_txrx->r_cckrx_enable = 0x0; /* default: A*/
+ p_cck_txrx->r_cckrx_enable_2 = 0x0; /* option: A*/
+ chgRx = 1;
+ break;
+ case ANTENNA_B:
+ r_rx_antenna_ofdm = 0x2; /*/ B*/
+ p_cck_txrx->r_cckrx_enable = 0x1; /*/ default: B*/
+ p_cck_txrx->r_cckrx_enable_2 = 0x1; /*/ option: B*/
+ chgRx = 1;
+ break;
+ case ANTENNA_AB:/*/ For 8192S and 8192E/U...*/
+ r_rx_antenna_ofdm = 0x3;/*/ AB*/
+ p_cck_txrx->r_cckrx_enable = 0x0;/*/ default:A*/
+ p_cck_txrx->r_cckrx_enable_2 = 0x1;/*/ option:B*/
+ chgRx = 1;
+ break;
+ default:
+ break;
+ }
+
+
+ if (chgTx && chgRx) {
+ switch (pHalData->rf_chip) {
+ case RF_8225:
+ case RF_8256:
+ case RF_6052:
+ /*/r_ant_sel_cck_val = r_ant_select_cck_val;*/
+ phy_set_bb_reg(pAdapter, rFPGA1_TxInfo, 0x7fffffff, r_ant_select_ofdm_val); /*/OFDM Tx*/
+ phy_set_bb_reg(pAdapter, rFPGA0_TxInfo, 0x0000000f, r_ofdm_tx_en_val); /*/OFDM Tx*/
+ phy_set_bb_reg(pAdapter, rOFDM0_TRxPathEnable, 0x0000000f, r_rx_antenna_ofdm); /*/OFDM Rx*/
+ phy_set_bb_reg(pAdapter, rOFDM1_TRxPathEnable, 0x0000000f, r_rx_antenna_ofdm); /*/OFDM Rx*/
+ phy_set_bb_reg(pAdapter, rCCK0_AFESetting, bMaskByte3, r_ant_select_cck_val);/*/r_ant_sel_cck_val); /CCK TxRx*/
+ break;
+
+ default:
+ RTW_INFO("Unsupported RFChipID for switching antenna.\n");
+ break;
+ }
+ }
+} /* MPT_ProSetRFPath */
+
+
+void hal_mpt_SetAntenna(PADAPTER pAdapter)
+
+{
+ RTW_INFO("Do %s\n", __func__);
+ mpt_SetRFPath_819X(pAdapter);
+ RTW_INFO("mpt_SetRFPath_819X Do %s\n", __func__);
+}
+
+s32 hal_mpt_SetThermalMeter(PADAPTER pAdapter, u8 target_ther)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+
+ if (!netif_running(pAdapter->pnetdev)) {
+ return _FAIL;
+ }
+
+
+ if (check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE) == false) {
+ return _FAIL;
+ }
+
+
+ target_ther &= 0xff;
+ if (target_ther < 0x07)
+ target_ther = 0x07;
+ else if (target_ther > 0x1d)
+ target_ther = 0x1d;
+
+ pHalData->eeprom_thermal_meter = target_ther;
+
+ return _SUCCESS;
+}
+
+
+void hal_mpt_TriggerRFThermalMeter(PADAPTER pAdapter)
+{
+ phy_set_rf_reg(pAdapter, ODM_RF_PATH_A, 0x42, BIT17 | BIT16, 0x03);
+
+}
+
+
+u8 hal_mpt_ReadRFThermalMeter(PADAPTER pAdapter)
+
+{
+ u32 ThermalValue = 0;
+
+ ThermalValue = (u8)phy_query_rf_reg(pAdapter, ODM_RF_PATH_A, 0x42, 0xfc00); /*0x42: RF Reg[15:10]*/
+ return (u8)ThermalValue;
+
+}
+
+void hal_mpt_GetThermalMeter(PADAPTER pAdapter, u8 *value)
+{
+ hal_mpt_TriggerRFThermalMeter(pAdapter);
+ rtw_msleep_os(1000);
+ *value = hal_mpt_ReadRFThermalMeter(pAdapter);
+}
+
+void hal_mpt_SetSingleCarrierTx(PADAPTER pAdapter, u8 bStart)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+
+ pAdapter->mppriv.mpt_ctx.bSingleCarrier = bStart;
+
+ if (bStart) {/*/ Start Single Carrier.*/
+ /*/ Start Single Carrier.*/
+ /*/ 1. if OFDM block on?*/
+ if (!phy_query_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn))
+ phy_set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 1); /*set OFDM block on*/
+
+ /*/ 2. set CCK test mode off, set to CCK normal mode*/
+ phy_set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0);
+
+ /*/ 3. turn on scramble setting*/
+ phy_set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, 1);
+
+ /*/ 4. Turn On Continue Tx and turn off the other test modes.*/
+ phy_set_bb_reg(pAdapter, rOFDM1_LSTF, BIT30 | BIT29 | BIT28, OFDM_SingleCarrier);
+ } else {
+ /*/ Stop Single Carrier.*/
+ /*/ Stop Single Carrier.*/
+ /*/ Turn off all test modes.*/
+ phy_set_bb_reg(pAdapter, rOFDM1_LSTF, BIT30 | BIT29 | BIT28, OFDM_ALL_OFF);
+
+ rtw_msleep_os(10);
+ /*/BB Reset*/
+ phy_set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
+ phy_set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
+ }
+}
+
+
+void hal_mpt_SetSingleToneTx(PADAPTER pAdapter, u8 bStart)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.mpt_ctx);
+ u32 ulAntennaTx = pHalData->antenna_tx_path;
+ static u32 regRF = 0, regBB0 = 0, regBB1 = 0, regBB2 = 0, regBB3 = 0;
+ u8 rfPath;
+
+ switch (ulAntennaTx) {
+ case ANTENNA_B:
+ rfPath = ODM_RF_PATH_B;
+ break;
+ case ANTENNA_C:
+ rfPath = ODM_RF_PATH_C;
+ break;
+ case ANTENNA_D:
+ rfPath = ODM_RF_PATH_D;
+ break;
+ case ANTENNA_A:
+ default:
+ rfPath = ODM_RF_PATH_A;
+ break;
+ }
+
+ pAdapter->mppriv.mpt_ctx.is_single_tone = bStart;
+ if (bStart) {
+ /*/ Start Single Tone.*/
+ /*/ <20120326, Kordan> To amplify the power of tone for Xtal calibration. (asked by Edlu)*/
+ if (IS_HARDWARE_TYPE_8188E(pAdapter)) {
+ regRF = phy_query_rf_reg(pAdapter, rfPath, lna_low_gain_3, bRFRegOffsetMask);
+ phy_set_rf_reg(pAdapter, ODM_RF_PATH_A, lna_low_gain_3, BIT1, 0x1); /*/ RF LO enabled*/
+ phy_set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, 0x0);
+ phy_set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 0x0);
+ } else { /*/ Turn On SingleTone and turn off the other test modes.*/
+ phy_set_bb_reg(pAdapter, rOFDM1_LSTF, BIT30 | BIT29 | BIT28, OFDM_SingleTone);
+ }
+ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500);
+ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500);
+ } else {/*/ Stop Single Ton e.*/
+ if (IS_HARDWARE_TYPE_8188E(pAdapter)) {
+ phy_set_rf_reg(pAdapter, ODM_RF_PATH_A, lna_low_gain_3, bRFRegOffsetMask, regRF);
+ phy_set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, 0x1);
+ phy_set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 0x1);
+ }
+ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100);
+ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100);
+ }
+}
+
+void hal_mpt_SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart)
+{
+ u8 Rate;
+
+ pAdapter->mppriv.mpt_ctx.is_carrier_suppression = bStart;
+
+ Rate = HwRateToMPTRate(pAdapter->mppriv.rateidx);
+ if (bStart) {/* Start Carrier Suppression.*/
+ if (Rate <= MPT_RATE_11M) {
+ /*/ 1. if CCK block on?*/
+ if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn))
+ write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);/*set CCK block on*/
+
+ /*/Turn Off All Test Mode*/
+ phy_set_bb_reg(pAdapter, rOFDM1_LSTF, BIT30 | BIT29 | BIT28, OFDM_ALL_OFF);
+
+ write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); /*/transmit mode*/
+ write_bbreg(pAdapter, rCCK0_System, bCCKScramble, 0x0); /*/turn off scramble setting*/
+
+ /*/Set CCK Tx Test Rate*/
+ write_bbreg(pAdapter, rCCK0_System, bCCKTxRate, 0x0); /*/Set FTxRate to 1Mbps*/
+ }
+
+ /*Set for dynamic set Power index*/
+ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500);
+ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500);
+
+ } else {/* Stop Carrier Suppression.*/
+
+ if (Rate <= MPT_RATE_11M) {
+ write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); /*normal mode*/
+ write_bbreg(pAdapter, rCCK0_System, bCCKScramble, 0x1); /*turn on scramble setting*/
+
+ /*BB Reset*/
+ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
+ write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
+ }
+ /*Stop for dynamic set Power index*/
+ write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100);
+ write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100);
+ }
+ RTW_INFO("\n MPT_ProSetCarrierSupp() is finished.\n");
+}
+
+u32 hal_mpt_query_phytxok(PADAPTER pAdapter)
+{
+ PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.mpt_ctx);
+ RT_PMAC_TX_INFO PMacTxInfo = pMptCtx->PMacTxInfo;
+ u16 count = 0;
+
+ if (IS_MPT_CCK_RATE(PMacTxInfo.TX_RATE))
+ count = phy_query_bb_reg(pAdapter, 0xF50, bMaskLWord); /* [15:0]*/
+ else
+ count = phy_query_bb_reg(pAdapter, 0xF50, bMaskHWord); /* [31:16]*/
+
+ if (count > 50000) {
+ rtw_reset_phy_trx_ok_counters(pAdapter);
+ pAdapter->mppriv.tx.sended += count;
+ count = 0;
+ }
+
+ return pAdapter->mppriv.tx.sended + count;
+
+}
+
+static void mpt_StopCckContTx(
+ PADAPTER pAdapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.mpt_ctx);
+ u8 u1bReg;
+
+ pMptCtx->bCckContTx = false;
+ pMptCtx->bOfdmContTx = false;
+
+ phy_set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); /*normal mode*/
+ phy_set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, 0x1); /*turn on scramble setting*/
+
+ /*BB Reset*/
+ phy_set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
+ phy_set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
+
+ phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100);
+ phy_set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100);
+
+} /* mpt_StopCckContTx */
+
+
+static void mpt_StopOfdmContTx(
+ PADAPTER pAdapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.mpt_ctx);
+ u8 u1bReg;
+ u32 data;
+
+ pMptCtx->bCckContTx = false;
+ pMptCtx->bOfdmContTx = false;
+
+ phy_set_bb_reg(pAdapter, rOFDM1_LSTF, BIT30 | BIT29 | BIT28, OFDM_ALL_OFF);
+
+ rtw_mdelay_os(10);
+
+ /*BB Reset*/
+ phy_set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
+ phy_set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
+
+ phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100);
+ phy_set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100);
+} /* mpt_StopOfdmContTx */
+
+
+static void mpt_StartCckContTx(
+ PADAPTER pAdapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.mpt_ctx);
+ u32 cckrate;
+
+ /* 1. if CCK block on */
+ if (!phy_query_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn))
+ phy_set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, 1);/*set CCK block on*/
+
+ /*Turn Off All Test Mode*/
+ phy_set_bb_reg(pAdapter, rOFDM1_LSTF, BIT30 | BIT29 | BIT28, OFDM_ALL_OFF);
+
+ cckrate = pAdapter->mppriv.rateidx;
+
+ phy_set_bb_reg(pAdapter, rCCK0_System, bCCKTxRate, cckrate);
+
+ phy_set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); /*transmit mode*/
+ phy_set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, 0x1); /*turn on scramble setting*/
+
+ phy_set_bb_reg(pAdapter, 0xa14, 0x300, 0x3); /* 0xa15[1:0] = 11 force cck rxiq = 0*/
+ phy_set_bb_reg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x1); /* 0xc08[16] = 1 force ofdm rxiq = ofdm txiq*/
+ phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, BIT14, 1);
+ phy_set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, BIT14, 1);
+ phy_set_bb_reg(pAdapter, 0x0B34, BIT14, 1);
+
+ phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500);
+ phy_set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500);
+
+ pMptCtx->bCckContTx = true;
+ pMptCtx->bOfdmContTx = false;
+
+} /* mpt_StartCckContTx */
+
+
+static void mpt_StartOfdmContTx(
+ PADAPTER pAdapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.mpt_ctx);
+
+ /* 1. if OFDM block on?*/
+ if (!phy_query_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn))
+ phy_set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 1);/*set OFDM block on*/
+
+ /* 2. set CCK test mode off, set to CCK normal mode*/
+ phy_set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0);
+
+ /* 3. turn on scramble setting*/
+ phy_set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, 1);
+
+ phy_set_bb_reg(pAdapter, 0xa14, 0x300, 0x3); /* 0xa15[1:0] = 2b'11*/
+ phy_set_bb_reg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x1); /* 0xc08[16] = 1*/
+
+ /* 4. Turn On Continue Tx and turn off the other test modes.*/
+ phy_set_bb_reg(pAdapter, rOFDM1_LSTF, BIT30 | BIT29 | BIT28, OFDM_ContinuousTx);
+
+ phy_set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500);
+ phy_set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500);
+
+ pMptCtx->bCckContTx = false;
+ pMptCtx->bOfdmContTx = true;
+} /* mpt_StartOfdmContTx */
+
+void hal_mpt_SetContinuousTx(PADAPTER pAdapter, u8 bStart)
+{
+ u8 Rate;
+
+ RT_TRACE(_module_mp_, _drv_info_,
+ ("SetContinuousTx: rate:%d\n", pAdapter->mppriv.rateidx));
+ Rate = HwRateToMPTRate(pAdapter->mppriv.rateidx);
+ pAdapter->mppriv.mpt_ctx.is_start_cont_tx = bStart;
+
+ if (Rate <= MPT_RATE_11M) {
+ if (bStart)
+ mpt_StartCckContTx(pAdapter);
+ else
+ mpt_StopCckContTx(pAdapter);
+
+ } else if (Rate >= MPT_RATE_6M) {
+ if (bStart)
+ mpt_StartOfdmContTx(pAdapter);
+ else
+ mpt_StopOfdmContTx(pAdapter);
+ }
+}
+
+#endif /* CONFIG_MP_INCLUDE*/
diff --git a/drivers/staging/rtl8188eu/hal/hal_phy.c b/drivers/staging/rtl8188eu/hal/hal_phy.c
new file mode 100644
index 000000000000..1a2385aae25a
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal_phy.c
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _HAL_PHY_C_
+
+#include <drv_types.h>
+
+/* ********************************************************************************
+ * Constant.
+ * ********************************************************************************
+ * 2008/11/20 MH For Debug only, RF */
+static RF_SHADOW_T RF_Shadow[RF6052_MAX_PATH][RF6052_MAX_REG];
+
+/**
+* Function: PHY_CalculateBitShift
+*
+* OverView: Get shifted position of the BitMask
+*
+* Input:
+* u32 BitMask,
+*
+* Output: none
+* Return: u32 Return the shift bit bit position of the mask
+*/
+u32
+PHY_CalculateBitShift(
+ u32 BitMask
+)
+{
+ u32 i;
+
+ for (i = 0; i <= 31; i++) {
+ if (((BitMask >> i) & 0x1) == 1)
+ break;
+ }
+
+ return i;
+}
+
+
+/*
+ * ==> RF shadow Operation API Code Section!!!
+ *
+ *-----------------------------------------------------------------------------
+ * Function: PHY_RFShadowRead
+ * PHY_RFShadowWrite
+ * PHY_RFShadowCompare
+ * PHY_RFShadowRecorver
+ * PHY_RFShadowCompareAll
+ * PHY_RFShadowRecorverAll
+ * PHY_RFShadowCompareFlagSet
+ * PHY_RFShadowRecorverFlagSet
+ *
+ * Overview: When we set RF register, we must write shadow at first.
+ * When we are running, we must compare shadow abd locate error addr.
+ * Decide to recorver or not.
+ *
+ * Input: NONE
+ *
+ * Output: NONE
+ *
+ * Return: NONE
+ *
+ * Revised History:
+ * When Who Remark
+ * 11/20/2008 MHC Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+u32
+PHY_RFShadowRead(
+ PADAPTER Adapter,
+ u8 eRFPath,
+ u32 Offset)
+{
+ return RF_Shadow[eRFPath][Offset].Value;
+
+} /* PHY_RFShadowRead */
+
+
+void
+PHY_RFShadowWrite(
+ PADAPTER Adapter,
+ u8 eRFPath,
+ u32 Offset,
+ u32 Data)
+{
+ RF_Shadow[eRFPath][Offset].Value = (Data & bRFRegOffsetMask);
+ RF_Shadow[eRFPath][Offset].Driver_Write = true;
+
+} /* PHY_RFShadowWrite */
+
+
+bool
+PHY_RFShadowCompare(
+ PADAPTER Adapter,
+ u8 eRFPath,
+ u32 Offset)
+{
+ u32 reg;
+ /* Check if we need to check the register */
+ if (RF_Shadow[eRFPath][Offset].Compare == true) {
+ reg = rtw_hal_read_rfreg(Adapter, eRFPath, Offset, bRFRegOffsetMask);
+ /* Compare shadow and real rf register for 20bits!! */
+ if (RF_Shadow[eRFPath][Offset].Value != reg) {
+ /* Locate error position. */
+ RF_Shadow[eRFPath][Offset].ErrorOrNot = true;
+ }
+ return RF_Shadow[eRFPath][Offset].ErrorOrNot ;
+ }
+ return false;
+} /* PHY_RFShadowCompare */
+
+
+void
+PHY_RFShadowRecorver(
+ PADAPTER Adapter,
+ u8 eRFPath,
+ u32 Offset)
+{
+ /* Check if the address is error */
+ if (RF_Shadow[eRFPath][Offset].ErrorOrNot == true) {
+ /* Check if we need to recorver the register. */
+ if (RF_Shadow[eRFPath][Offset].Recorver == true) {
+ rtw_hal_write_rfreg(Adapter, eRFPath, Offset, bRFRegOffsetMask,
+ RF_Shadow[eRFPath][Offset].Value);
+ }
+ }
+
+} /* PHY_RFShadowRecorver */
+
+
+void
+PHY_RFShadowCompareAll(
+ PADAPTER Adapter)
+{
+ u8 eRFPath = 0 ;
+ u32 Offset = 0, maxReg = GET_RF6052_REAL_MAX_REG(Adapter);
+
+ for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) {
+ for (Offset = 0; Offset < maxReg; Offset++)
+ PHY_RFShadowCompare(Adapter, eRFPath, Offset);
+ }
+
+} /* PHY_RFShadowCompareAll */
+
+
+void
+PHY_RFShadowRecorverAll(
+ PADAPTER Adapter)
+{
+ u8 eRFPath = 0;
+ u32 Offset = 0, maxReg = GET_RF6052_REAL_MAX_REG(Adapter);
+
+ for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) {
+ for (Offset = 0; Offset < maxReg; Offset++)
+ PHY_RFShadowRecorver(Adapter, eRFPath, Offset);
+ }
+
+} /* PHY_RFShadowRecorverAll */
+
+
+void
+PHY_RFShadowCompareFlagSet(
+ PADAPTER Adapter,
+ u8 eRFPath,
+ u32 Offset,
+ u8 Type)
+{
+ /* Set True or False!!! */
+ RF_Shadow[eRFPath][Offset].Compare = Type;
+
+} /* PHY_RFShadowCompareFlagSet */
+
+
+void
+PHY_RFShadowRecorverFlagSet(
+ PADAPTER Adapter,
+ u8 eRFPath,
+ u32 Offset,
+ u8 Type)
+{
+ /* Set True or False!!! */
+ RF_Shadow[eRFPath][Offset].Recorver = Type;
+
+} /* PHY_RFShadowRecorverFlagSet */
+
+
+void
+PHY_RFShadowCompareFlagSetAll(
+ PADAPTER Adapter)
+{
+ u8 eRFPath = 0;
+ u32 Offset = 0, maxReg = GET_RF6052_REAL_MAX_REG(Adapter);
+
+ for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) {
+ for (Offset = 0; Offset < maxReg; Offset++) {
+ /* 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!! */
+ if (Offset != 0x26 && Offset != 0x27)
+ PHY_RFShadowCompareFlagSet(Adapter, eRFPath, Offset, false);
+ else
+ PHY_RFShadowCompareFlagSet(Adapter, eRFPath, Offset, true);
+ }
+ }
+
+} /* PHY_RFShadowCompareFlagSetAll */
+
+
+void
+PHY_RFShadowRecorverFlagSetAll(
+ PADAPTER Adapter)
+{
+ u8 eRFPath = 0;
+ u32 Offset = 0, maxReg = GET_RF6052_REAL_MAX_REG(Adapter);
+
+ for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) {
+ for (Offset = 0; Offset < maxReg; Offset++) {
+ /* 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!! */
+ if (Offset != 0x26 && Offset != 0x27)
+ PHY_RFShadowRecorverFlagSet(Adapter, eRFPath, Offset, false);
+ else
+ PHY_RFShadowRecorverFlagSet(Adapter, eRFPath, Offset, true);
+ }
+ }
+
+} /* PHY_RFShadowCompareFlagSetAll */
+
+void
+PHY_RFShadowRefresh(
+ PADAPTER Adapter)
+{
+ u8 eRFPath = 0;
+ u32 Offset = 0, maxReg = GET_RF6052_REAL_MAX_REG(Adapter);
+
+ for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) {
+ for (Offset = 0; Offset < maxReg; Offset++) {
+ RF_Shadow[eRFPath][Offset].Value = 0;
+ RF_Shadow[eRFPath][Offset].Compare = false;
+ RF_Shadow[eRFPath][Offset].Recorver = false;
+ RF_Shadow[eRFPath][Offset].ErrorOrNot = false;
+ RF_Shadow[eRFPath][Offset].Driver_Write = false;
+ }
+ }
+
+} /* PHY_RFShadowRead */
diff --git a/drivers/staging/rtl8188eu/hal/hal_usb.c b/drivers/staging/rtl8188eu/hal/hal_usb.c
new file mode 100644
index 000000000000..db07579f52db
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal_usb.c
@@ -0,0 +1,452 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _HAL_USB_C_
+
+#include <drv_types.h>
+#include <hal_data.h>
+
+int usb_init_recv_priv(_adapter *padapter, u16 ini_in_buf_sz)
+{
+ struct recv_priv *precvpriv = &padapter->recvpriv;
+ int i, res = _SUCCESS;
+ struct recv_buf *precvbuf;
+
+ tasklet_init(&precvpriv->recv_tasklet,
+ (void(*)(unsigned long))usb_recv_tasklet,
+ (unsigned long)padapter);
+
+#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
+ precvpriv->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (precvpriv->int_in_urb == NULL) {
+ res = _FAIL;
+ RTW_INFO("alloc_urb for interrupt in endpoint fail !!!!\n");
+ goto exit;
+ }
+ precvpriv->int_in_buf = rtw_zmalloc(ini_in_buf_sz);
+ if (precvpriv->int_in_buf == NULL) {
+ res = _FAIL;
+ RTW_INFO("alloc_mem for interrupt in endpoint fail !!!!\n");
+ goto exit;
+ }
+#endif /* CONFIG_USB_INTERRUPT_IN_PIPE */
+
+ /* init recv_buf */
+ _rtw_init_queue(&precvpriv->free_recv_buf_queue);
+ _rtw_init_queue(&precvpriv->recv_buf_pending_queue);
+#ifndef CONFIG_USE_USB_BUFFER_ALLOC_RX
+ /* this is used only when RX_IOBUF is sk_buff */
+ skb_queue_head_init(&precvpriv->free_recv_skb_queue);
+#endif
+
+ RTW_INFO("NR_RECVBUFF: %d\n", NR_RECVBUFF);
+ RTW_INFO("MAX_RECVBUF_SZ: %d\n", MAX_RECVBUF_SZ);
+ precvpriv->pallocated_recv_buf = rtw_zmalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4);
+ if (precvpriv->pallocated_recv_buf == NULL) {
+ res = _FAIL;
+ goto exit;
+ }
+
+ precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_recv_buf), 4);
+
+ precvbuf = (struct recv_buf *)precvpriv->precv_buf;
+
+ for (i = 0; i < NR_RECVBUFF ; i++) {
+ INIT_LIST_HEAD(&precvbuf->list);
+
+ spin_lock_init(&precvbuf->recvbuf_lock);
+
+ precvbuf->alloc_sz = MAX_RECVBUF_SZ;
+
+ res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf);
+ if (res == _FAIL)
+ break;
+
+ precvbuf->ref_cnt = 0;
+ precvbuf->adapter = padapter;
+
+ /* list_add_tail(&precvbuf->list, &(precvpriv->free_recv_buf_queue.queue)); */
+
+ precvbuf++;
+ }
+
+ precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF;
+
+ skb_queue_head_init(&precvpriv->rx_skb_queue);
+
+#ifdef CONFIG_RX_INDICATE_QUEUE
+ memset(&precvpriv->rx_indicate_queue, 0, sizeof(struct ifqueue));
+ mtx_init(&precvpriv->rx_indicate_queue.ifq_mtx, "rx_indicate_queue", NULL, MTX_DEF);
+#endif /* CONFIG_RX_INDICATE_QUEUE */
+
+#ifdef CONFIG_PREALLOC_RECV_SKB
+ {
+ int i;
+ SIZE_PTR tmpaddr = 0;
+ SIZE_PTR alignment = 0;
+ struct sk_buff *pskb = NULL;
+
+ RTW_INFO("NR_PREALLOC_RECV_SKB: %d\n", NR_PREALLOC_RECV_SKB);
+#ifdef CONFIG_FIX_NR_BULKIN_BUFFER
+ RTW_INFO("Enable CONFIG_FIX_NR_BULKIN_BUFFER\n");
+#endif
+
+ for (i = 0; i < NR_PREALLOC_RECV_SKB; i++) {
+#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
+ pskb = rtw_alloc_skb_premem(MAX_RECVBUF_SZ);
+#else
+ pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
+#endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
+
+ if (pskb) {
+ pskb->dev = padapter->pnetdev;
+
+#ifndef CONFIG_PREALLOC_RX_SKB_BUFFER
+ tmpaddr = (SIZE_PTR)pskb->data;
+ alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
+ skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment));
+#endif
+ skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
+ }
+ }
+ }
+#endif /* CONFIG_PREALLOC_RECV_SKB */
+
+exit:
+
+ return res;
+}
+
+void usb_free_recv_priv(_adapter *padapter, u16 ini_in_buf_sz)
+{
+ int i;
+ struct recv_buf *precvbuf;
+ struct recv_priv *precvpriv = &padapter->recvpriv;
+
+ precvbuf = (struct recv_buf *)precvpriv->precv_buf;
+
+ for (i = 0; i < NR_RECVBUFF ; i++) {
+ rtw_os_recvbuf_resource_free(padapter, precvbuf);
+ precvbuf++;
+ }
+
+ if (precvpriv->pallocated_recv_buf)
+ rtw_mfree(precvpriv->pallocated_recv_buf, NR_RECVBUFF * sizeof(struct recv_buf) + 4);
+
+#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
+ if (precvpriv->int_in_urb)
+ usb_free_urb(precvpriv->int_in_urb);
+ if (precvpriv->int_in_buf)
+ rtw_mfree(precvpriv->int_in_buf, ini_in_buf_sz);
+#endif /* CONFIG_USB_INTERRUPT_IN_PIPE */
+
+ if (skb_queue_len(&precvpriv->rx_skb_queue))
+ RTW_WARN("rx_skb_queue not empty\n");
+
+ rtw_skb_queue_purge(&precvpriv->rx_skb_queue);
+
+ if (skb_queue_len(&precvpriv->free_recv_skb_queue))
+ RTW_WARN("free_recv_skb_queue not empty, %d\n", skb_queue_len(&precvpriv->free_recv_skb_queue));
+
+#if !defined(CONFIG_USE_USB_BUFFER_ALLOC_RX)
+#if defined(CONFIG_PREALLOC_RECV_SKB) && defined(CONFIG_PREALLOC_RX_SKB_BUFFER)
+ {
+ struct sk_buff *skb;
+
+ while ((skb = skb_dequeue(&precvpriv->free_recv_skb_queue)) != NULL) {
+ if (rtw_free_skb_premem(skb) != 0)
+ rtw_skb_free(skb);
+ }
+ }
+#else
+ rtw_skb_queue_purge(&precvpriv->free_recv_skb_queue);
+#endif /* defined(CONFIG_PREALLOC_RX_SKB_BUFFER) && defined(CONFIG_PREALLOC_RECV_SKB) */
+#endif /* !defined(CONFIG_USE_USB_BUFFER_ALLOC_RX) */
+}
+
+#ifdef CONFIG_FW_C2H_REG
+void usb_c2h_hisr_hdl(_adapter *adapter, u8 *buf)
+{
+ u8 *c2h_evt = buf;
+ u8 id, seq, plen;
+ u8 *payload;
+
+ if (rtw_hal_c2h_reg_hdr_parse(adapter, buf, &id, &seq, &plen, &payload) != _SUCCESS)
+ return;
+
+ if (0)
+ RTW_PRINT("%s C2H == %d\n", __func__, id);
+
+ if (rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload)) {
+ /* Handle directly */
+ rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
+
+ /* Replace with special pointer to trigger c2h_evt_clear only */
+ if (rtw_cbuf_push(adapter->evtpriv.c2h_queue, (void*)&adapter->evtpriv) != _SUCCESS)
+ RTW_ERR("%s rtw_cbuf_push fail\n", __func__);
+ } else {
+ c2h_evt = rtw_malloc(C2H_REG_LEN);
+ if (c2h_evt != NULL) {
+ memcpy(c2h_evt, buf, C2H_REG_LEN);
+ if (rtw_cbuf_push(adapter->evtpriv.c2h_queue, (void*)c2h_evt) != _SUCCESS)
+ RTW_ERR("%s rtw_cbuf_push fail\n", __func__);
+ } else {
+ /* Error handling for malloc fail */
+ if (rtw_cbuf_push(adapter->evtpriv.c2h_queue, (void*)NULL) != _SUCCESS)
+ RTW_ERR("%s rtw_cbuf_push fail\n", __func__);
+ }
+ }
+ _set_workitem(&adapter->evtpriv.c2h_wk);
+}
+#endif
+
+#ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ
+int usb_write_async(struct usb_device *udev, u32 addr, void *pdata, u16 len)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ int ret;
+
+ requesttype = VENDOR_WRITE;/* write_out */
+ request = REALTEK_USB_VENQT_CMD_REQ;
+ index = REALTEK_USB_VENQT_CMD_IDX;/* n/a */
+
+ wvalue = (u16)(addr & 0x0000ffff);
+
+ ret = _usbctrl_vendorreq_async_write(udev, request, wvalue, index, pdata, len, requesttype);
+
+ return ret;
+}
+
+int usb_async_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
+{
+ u8 data;
+ int ret;
+ struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
+ struct usb_device *udev = pdvobjpriv->pusbdev;
+
+ data = val;
+ ret = usb_write_async(udev, addr, &data, 1);
+
+ return ret;
+}
+
+int usb_async_write16(struct intf_hdl *pintfhdl, u32 addr, __le16 val)
+{
+ __le16 data;
+ int ret;
+ struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
+ struct usb_device *udev = pdvobjpriv->pusbdev;
+
+ data = val;
+ ret = usb_write_async(udev, addr, &data, 2);
+
+ return ret;
+}
+
+int usb_async_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
+{
+ u32 data;
+ int ret;
+ struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
+ struct usb_device *udev = pdvobjpriv->pusbdev;
+
+ data = val;
+ ret = usb_write_async(udev, addr, &data, 4);
+
+ return ret;
+}
+#endif /* CONFIG_USB_SUPPORT_ASYNC_VDN_REQ */
+
+u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ u8 data = 0;
+
+ request = 0x05;
+ requesttype = 0x01;/* read_in */
+ index = 0;/* n/a */
+
+ wvalue = (u16)(addr & 0x0000ffff);
+ len = 1;
+ usbctrl_vendorreq(pintfhdl, request, wvalue, index,
+ &data, len, requesttype);
+
+ return data;
+}
+
+u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ __le16 data = 0;
+
+ request = 0x05;
+ requesttype = 0x01;/* read_in */
+ index = 0;/* n/a */
+
+ wvalue = (u16)(addr & 0x0000ffff);
+ len = 2;
+ usbctrl_vendorreq(pintfhdl, request, wvalue, index,
+ &data, len, requesttype);
+
+ return le16_to_cpu(data);
+}
+
+u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ __le32 data = 0;
+
+ request = 0x05;
+ requesttype = 0x01;/* read_in */
+ index = 0;/* n/a */
+
+ wvalue = (u16)(addr & 0x0000ffff);
+ len = 4;
+ usbctrl_vendorreq(pintfhdl, request, wvalue, index,
+ &data, len, requesttype);
+
+ return le32_to_cpu(data);
+}
+
+int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ u8 data;
+ int ret;
+
+ request = 0x05;
+ requesttype = 0x00;/* write_out */
+ index = 0;/* n/a */
+
+ wvalue = (u16)(addr & 0x0000ffff);
+ len = 1;
+
+ data = val;
+ ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index,
+ &data, len, requesttype);
+
+ return ret;
+}
+
+int usb_write16(struct intf_hdl *pintfhdl, u32 addr, __le16 val)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ __le16 data;
+ int ret;
+
+ request = 0x05;
+ requesttype = 0x00;/* write_out */
+ index = 0;/* n/a */
+
+ wvalue = (u16)(addr & 0x0000ffff);
+ len = 2;
+
+ data = val;
+ ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index,
+ &data, len, requesttype);
+
+ return ret;
+
+}
+
+int usb_write32(struct intf_hdl *pintfhdl, u32 addr, __le32 val)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ __le32 data;
+ int ret;
+
+ request = 0x05;
+ requesttype = 0x00;/* write_out */
+ index = 0;/* n/a */
+
+ wvalue = (u16)(addr & 0x0000ffff);
+ len = 4;
+ data = val;
+ ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index,
+ &data, len, requesttype);
+
+ return ret;
+
+}
+
+int usb_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ u8 buf[VENDOR_CMD_MAX_DATA_LEN] = {0};
+ int ret;
+
+ request = 0x05;
+ requesttype = 0x00;/* write_out */
+ index = 0;/* n/a */
+
+ wvalue = (u16)(addr & 0x0000ffff);
+ len = length;
+ memcpy(buf, pdata, len);
+ ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index,
+ buf, len, requesttype);
+
+ return ret;
+}
+
+void usb_set_intf_ops(_adapter *padapter, struct _io_ops *pops)
+{
+ memset((u8 *)pops, 0, sizeof(struct _io_ops));
+
+ pops->_read8 = &usb_read8;
+ pops->_read16 = &usb_read16;
+ pops->_read32 = &usb_read32;
+ pops->_read_mem = &usb_read_mem;
+ pops->_read_port = &usb_read_port;
+
+ pops->_write8 = &usb_write8;
+ pops->_write16 = &usb_write16;
+ pops->_write32 = &usb_write32;
+ pops->_writeN = &usb_writeN;
+
+#ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ
+ pops->_write8_async = &usb_async_write8;
+ pops->_write16_async = &usb_async_write16;
+ pops->_write32_async = &usb_async_write32;
+#endif
+ pops->_write_mem = &usb_write_mem;
+ pops->_write_port = &usb_write_port;
+
+ pops->_read_port_cancel = &usb_read_port_cancel;
+ pops->_write_port_cancel = &usb_write_port_cancel;
+
+#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
+ pops->_read_interrupt = &usb_read_interrupt;
+#endif
+
+}
diff --git a/drivers/staging/rtl8188eu/hal/hal_usb_led.c b/drivers/staging/rtl8188eu/hal/hal_usb_led.c
new file mode 100644
index 000000000000..d777aa501635
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/hal_usb_led.c
@@ -0,0 +1,4235 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#include <drv_types.h>
+#include <hal_data.h>
+
+/*
+ * Description:
+ * Implementation of LED blinking behavior.
+ * It toggle off LED and schedule corresponding timer if necessary.
+ * */
+static void
+SwLedBlink(
+ PLED_USB pLed
+)
+{
+ _adapter *padapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u8 bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(padapter, pLed);
+ } else {
+ SwLedOff(padapter, pLed);
+ }
+
+ /* Determine if we shall change LED state again. */
+ pLed->BlinkTimes--;
+ switch (pLed->CurrLedState) {
+
+ case LED_BLINK_NORMAL:
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ break;
+
+ case LED_BLINK_StartToBlink:
+ if (check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE))
+ bStopBlinking = true;
+ if (check_fwstate(pmlmepriv, _FW_LINKED) &&
+ (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
+ bStopBlinking = true;
+ else if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ break;
+
+ case LED_BLINK_WPS:
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ break;
+
+
+ default:
+ bStopBlinking = true;
+ break;
+
+ }
+
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) && (pLed->bLedOn == false))
+ SwLedOn(padapter, pLed);
+ else if ((check_fwstate(pmlmepriv, _FW_LINKED) == false) && pLed->bLedOn == true)
+ SwLedOff(padapter, pLed);
+
+ pLed->BlinkTimes = 0;
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ /* Assign LED state to toggle. */
+ if (pLed->BlinkingLedState == RTW_LED_ON)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ /* Schedule a timer to toggle LED state. */
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_NORMAL:
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ break;
+
+ case LED_BLINK_SLOWLY:
+ case LED_BLINK_StartToBlink:
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ break;
+
+ case LED_BLINK_WPS: {
+ if (pLed->BlinkingLedState == RTW_LED_ON)
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
+ else
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
+ }
+ break;
+
+ default:
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ break;
+ }
+ }
+}
+
+static void
+SwLedBlink1(
+ PLED_USB pLed
+)
+{
+ _adapter *padapter = pLed->padapter;
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ PLED_USB pLed1 = &(ledpriv->SwLed1);
+ u8 bStopBlinking = false;
+
+ u32 uLedBlinkNoLinkInterval = LED_BLINK_NO_LINK_INTERVAL_ALPHA; /* add by ylb 20121012 for customer led for alpha */
+ if (pHalData->CustomerID == RT_CID_819x_ALPHA_Dlink)
+ uLedBlinkNoLinkInterval = LED_BLINK_NO_LINK_INTERVAL_ALPHA_500MS;
+
+ if (pHalData->CustomerID == RT_CID_819x_CAMEO)
+ pLed = &(ledpriv->SwLed1);
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(padapter, pLed);
+ } else {
+ SwLedOff(padapter, pLed);
+ }
+
+
+ if (pHalData->CustomerID == RT_CID_DEFAULT) {
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ if (!pLed1->bSWLedCtrl) {
+ SwLedOn(padapter, pLed1);
+ pLed1->bSWLedCtrl = true;
+ } else if (!pLed1->bLedOn)
+ SwLedOn(padapter, pLed1);
+ } else {
+ if (!pLed1->bSWLedCtrl) {
+ SwLedOff(padapter, pLed1);
+ pLed1->bSWLedCtrl = true;
+ } else if (pLed1->bLedOn)
+ SwLedOff(padapter, pLed1);
+ }
+ }
+
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_SLOWLY:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), uLedBlinkNoLinkInterval);/* change by ylb 20121012 for customer led for alpha */
+ break;
+
+ case LED_BLINK_NORMAL:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ break;
+
+ case LED_BLINK_SCAN:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->bLedLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+
+ } else if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), uLedBlinkNoLinkInterval);
+ }
+ pLed->bLedScanBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_TXRX:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->bLedLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ } else if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), uLedBlinkNoLinkInterval);
+ }
+ pLed->BlinkTimes = 0;
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_WPS:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ break;
+
+ case LED_BLINK_WPS_STOP: /* WPS success */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+ bStopBlinking = false;
+ } else
+ bStopBlinking = true;
+
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else {
+ pLed->bLedLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ }
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+static void
+SwLedBlink2(
+ PLED_USB pLed
+)
+{
+ _adapter *padapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u8 bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(padapter, pLed);
+ } else {
+ SwLedOff(padapter, pLed);
+ }
+
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_SCAN:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ SwLedOn(padapter, pLed);
+
+ } else if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ SwLedOff(padapter, pLed);
+ }
+ pLed->bLedScanBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_TXRX:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ SwLedOn(padapter, pLed);
+
+ } else if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ SwLedOff(padapter, pLed);
+ }
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+static void
+SwLedBlink3(
+ PLED_USB pLed
+)
+{
+ _adapter *padapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u8 bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(padapter, pLed);
+ } else {
+ if (pLed->CurrLedState != LED_BLINK_WPS_STOP)
+ SwLedOff(padapter, pLed);
+ }
+
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_SCAN:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if (!pLed->bLedOn)
+ SwLedOn(padapter, pLed);
+
+ } else if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if (pLed->bLedOn)
+ SwLedOff(padapter, pLed);
+
+ }
+ pLed->bLedScanBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_TXRX:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ if (!pLed->bLedOn)
+ SwLedOn(padapter, pLed);
+
+ } else if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+
+ if (pLed->bLedOn)
+ SwLedOff(padapter, pLed);
+
+
+ }
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_WPS:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ break;
+
+ case LED_BLINK_WPS_STOP: /* WPS success */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+ bStopBlinking = false;
+ } else
+ bStopBlinking = true;
+
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ SwLedOff(padapter, pLed);
+ else {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ SwLedOn(padapter, pLed);
+ }
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ break;
+
+
+ default:
+ break;
+ }
+
+}
+
+
+static void
+SwLedBlink4(
+ PLED_USB pLed
+)
+{
+ _adapter *padapter = pLed->padapter;
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ PLED_USB pLed1 = &(ledpriv->SwLed1);
+ u8 bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(padapter, pLed);
+ } else {
+ SwLedOff(padapter, pLed);
+ }
+
+ if (!pLed1->bLedWPSBlinkInProgress && pLed1->BlinkingLedState == LED_UNKNOWN) {
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ pLed1->CurrLedState = RTW_LED_OFF;
+ SwLedOff(padapter, pLed1);
+ }
+
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_SLOWLY:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ break;
+
+ case LED_BLINK_StartToBlink:
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ break;
+
+ case LED_BLINK_SCAN:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = false;
+
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(padapter, pLed);
+ else {
+ pLed->bLedNoLinkBlinkInProgress = false;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ pLed->bLedScanBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(padapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_TXRX:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(padapter, pLed);
+ else {
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(padapter, pLed);
+ else {
+
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_WPS:
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ break;
+
+ case LED_BLINK_WPS_STOP: /* WPS authentication fail */
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ break;
+
+ case LED_BLINK_WPS_STOP_OVERLAP: /* WPS session overlap */
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0) {
+ if (pLed->bLedOn)
+ pLed->BlinkTimes = 1;
+ else
+ bStopBlinking = true;
+ }
+
+ if (bStopBlinking) {
+ pLed->BlinkTimes = 10;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ break;
+
+ case LED_BLINK_ALWAYS_ON:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(padapter, pLed);
+ else {
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS) {
+ SwLedOff(padapter, pLed);
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+
+
+}
+
+static void
+SwLedBlink5(
+ PLED_USB pLed
+)
+{
+ _adapter *padapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u8 bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(padapter, pLed);
+ } else {
+ SwLedOff(padapter, pLed);
+ }
+
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_SCAN:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS) {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if (pLed->bLedOn)
+ SwLedOff(padapter, pLed);
+ } else {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if (!pLed->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+
+ pLed->bLedScanBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(padapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+
+ case LED_BLINK_TXRX:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS) {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if (pLed->bLedOn)
+ SwLedOff(padapter, pLed);
+ } else {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if (!pLed->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(padapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+
+
+}
+
+static void
+SwLedBlink6(
+ PLED_USB pLed
+)
+{
+ _adapter *padapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u8 bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(padapter, pLed);
+ } else {
+ SwLedOff(padapter, pLed);
+ }
+
+}
+
+static void
+SwLedBlink7(
+ PLED_USB pLed
+)
+{
+ PADAPTER Adapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
+ bool bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(Adapter, pLed);
+ } else {
+ if (pLed->CurrLedState != LED_BLINK_WPS_STOP)
+ SwLedOff(Adapter, pLed);
+ }
+
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_SCAN:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on)
+ SwLedOff(Adapter, pLed);
+ else if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if (!pLed->bLedOn)
+ SwLedOn(Adapter, pLed);
+
+ } else if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if (pLed->bLedOn)
+ SwLedOff(Adapter, pLed);
+
+ }
+ pLed->bLedScanBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on)
+ SwLedOff(Adapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_NETGEAR);
+ }
+ }
+ break;
+
+ case LED_BLINK_WPS:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_NETGEAR);
+ break;
+
+ case LED_BLINK_WPS_STOP: /* WPS success */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_NETGEAR);
+ bStopBlinking = false;
+ } else
+ bStopBlinking = true;
+
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on)
+ SwLedOff(Adapter, pLed);
+ else {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ SwLedOn(Adapter, pLed);
+ }
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ break;
+
+
+ default:
+ break;
+ }
+
+
+}
+
+static void
+SwLedBlink8(
+ PLED_USB pLed
+)
+{
+ PADAPTER Adapter = pLed->padapter;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(Adapter, pLed);
+ } else {
+ SwLedOff(Adapter, pLed);
+ }
+
+
+}
+
+/* page added for Belkin AC950. 20120813 */
+static void
+SwLedBlink9(
+ PLED_USB pLed
+)
+{
+ PADAPTER Adapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
+ bool bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(Adapter, pLed);
+ } else {
+ SwLedOff(Adapter, pLed);
+ }
+ /* RTW_INFO("%s, pLed->CurrLedState=%d, pLed->BlinkingLedState=%d\n", __func__, pLed->CurrLedState, pLed->BlinkingLedState); */
+
+
+ switch (pLed->CurrLedState) {
+ case RTW_LED_ON:
+ SwLedOn(Adapter, pLed);
+ break;
+
+ case RTW_LED_OFF:
+ SwLedOff(Adapter, pLed);
+ break;
+
+ case LED_BLINK_SLOWLY:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ break;
+
+ case LED_BLINK_StartToBlink:
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ break;
+
+ case LED_BLINK_SCAN:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on)
+ SwLedOff(Adapter, pLed);
+ else if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->bLedLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ } else if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ pLed->BlinkTimes = 0;
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(Adapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_TXRX:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(Adapter, pLed);
+ else {
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(Adapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_WPS:
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ break;
+
+ case LED_BLINK_WPS_STOP: /* WPS authentication fail */
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ break;
+
+ case LED_BLINK_WPS_STOP_OVERLAP: /* WPS session overlap */
+ pLed->BlinkTimes--;
+ pLed->BlinkCounter--;
+ if (pLed->BlinkCounter == 0) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ pLed->CurrLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ } else {
+ if (pLed->BlinkTimes == 0) {
+ if (pLed->bLedOn)
+ pLed->BlinkTimes = 1;
+ else
+ bStopBlinking = true;
+ }
+
+ if (bStopBlinking) {
+ pLed->BlinkTimes = 10;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ }
+ break;
+
+ case LED_BLINK_ALWAYS_ON:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(Adapter, pLed);
+ else {
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS) {
+ SwLedOff(Adapter, pLed);
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_LINK_IN_PROCESS:
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ON_BELKIN);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_OFF_BELKIN);
+ }
+ break;
+
+ case LED_BLINK_AUTH_ERROR:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking == false) {
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_ERROR_INTERVAL_BELKIN);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_ERROR_INTERVAL_BELKIN);
+ }
+ } else {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_ERROR_INTERVAL_BELKIN);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+/* page added for Netgear A6200V2. 20120827 */
+static void
+SwLedBlink10(
+ PLED_USB pLed
+)
+{
+ PADAPTER Adapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
+ bool bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(Adapter, pLed);
+ } else {
+ SwLedOff(Adapter, pLed);
+ }
+
+
+ switch (pLed->CurrLedState) {
+ case RTW_LED_ON:
+ SwLedOn(Adapter, pLed);
+ break;
+
+ case RTW_LED_OFF:
+ SwLedOff(Adapter, pLed);
+ break;
+
+ case LED_BLINK_SLOWLY:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ break;
+
+ case LED_BLINK_StartToBlink:
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ break;
+
+ case LED_BLINK_SCAN:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on)
+ SwLedOff(Adapter, pLed);
+ else if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->bLedNoLinkBlinkInProgress = false;
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ pLed->BlinkTimes = 0;
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(Adapter, pLed);
+ else {
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_NETGEAR);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_SLOWLY_INTERVAL_NETGEAR + LED_BLINK_LINK_INTERVAL_NETGEAR);
+ }
+ }
+ }
+ break;
+
+ case LED_BLINK_WPS:
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_NETGEAR);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL + LED_BLINK_LINK_INTERVAL_NETGEAR);
+ }
+ break;
+
+ case LED_BLINK_WPS_STOP: /* WPS authentication fail */
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ break;
+
+ case LED_BLINK_WPS_STOP_OVERLAP: /* WPS session overlap */
+ pLed->BlinkTimes--;
+ pLed->BlinkCounter--;
+ if (pLed->BlinkCounter == 0) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ pLed->CurrLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ } else {
+ if (pLed->BlinkTimes == 0) {
+ if (pLed->bLedOn)
+ pLed->BlinkTimes = 1;
+ else
+ bStopBlinking = true;
+ }
+
+ if (bStopBlinking) {
+ pLed->BlinkTimes = 10;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ }
+ break;
+
+ case LED_BLINK_ALWAYS_ON:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(Adapter, pLed);
+ else {
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS) {
+ SwLedOff(Adapter, pLed);
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_LINK_IN_PROCESS:
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ON_BELKIN);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_OFF_BELKIN);
+ }
+ break;
+
+ case LED_BLINK_AUTH_ERROR:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking == false) {
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_ERROR_INTERVAL_BELKIN);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_ERROR_INTERVAL_BELKIN);
+ }
+ } else {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_ERROR_INTERVAL_BELKIN);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+SwLedBlink11(
+ PLED_USB pLed
+)
+{
+ PADAPTER Adapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
+ bool bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(Adapter, pLed);
+ } else {
+ SwLedOff(Adapter, pLed);
+ }
+
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_TXRX:
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(Adapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+
+ break;
+
+ case LED_BLINK_WPS:
+ if (pLed->BlinkTimes == 5) {
+ SwLedOn(Adapter, pLed);
+ _set_timer(&(pLed->BlinkTimer), LED_CM11_LINK_ON_INTERVEL);
+ } else {
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_CM11_BLINK_INTERVAL);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_CM11_BLINK_INTERVAL);
+ }
+ }
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking == true)
+ pLed->BlinkTimes = 5;
+ break;
+
+ case LED_BLINK_WPS_STOP: /* WPS authentication fail */
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ } else {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ SwLedOn(Adapter, pLed);
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+static void
+SwLedBlink12(
+ PLED_USB pLed
+)
+{
+ PADAPTER Adapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
+ bool bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(Adapter, pLed);
+ } else {
+ SwLedOff(Adapter, pLed);
+ }
+
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_SLOWLY:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ break;
+
+ case LED_BLINK_TXRX:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS) {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if (pLed->bLedOn)
+ SwLedOff(Adapter, pLed);
+ } else {
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(Adapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+
+
+}
+
+static void
+SwLedBlink13(
+ PLED_USB pLed
+)
+{
+ PADAPTER Adapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
+ bool bStopBlinking = false;
+ static u8 LinkBlinkCnt = 0;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(Adapter, pLed);
+ } else {
+ if (pLed->CurrLedState != LED_BLINK_WPS_STOP)
+ SwLedOff(Adapter, pLed);
+ }
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_LINK_IN_PROCESS:
+ if (!pLed->bLedWPSBlinkInProgress)
+ LinkBlinkCnt++;
+
+ if (LinkBlinkCnt > 15) {
+ LinkBlinkCnt = 0;
+ pLed->bLedBlinkInProgress = false;
+ break;
+ }
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 500);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 500);
+ }
+
+ break;
+
+ case LED_BLINK_WPS:
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_WPS_BLINK_ON_INTERVAL_NETGEAR);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_WPS_BLINK_OFF_INTERVAL_NETGEAR);
+ }
+
+ break;
+
+ case LED_BLINK_WPS_STOP: /* WPS success */
+ SwLedOff(Adapter, pLed);
+ pLed->bLedWPSBlinkInProgress = false;
+ break;
+
+ default:
+ LinkBlinkCnt = 0;
+ break;
+ }
+
+
+}
+
+static void
+SwLedBlink14(
+ PLED_USB pLed
+)
+{
+ PADAPTER Adapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
+ bool bStopBlinking = false;
+ static u8 LinkBlinkCnt = 0;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(Adapter, pLed);
+ } else {
+ if (pLed->CurrLedState != LED_BLINK_WPS_STOP)
+ SwLedOff(Adapter, pLed);
+ }
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_TXRX:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(Adapter, pLed);
+ else
+ SwLedOn(Adapter, pLed);
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(Adapter, pLed);
+ else {
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ }
+
+ break;
+
+ default:
+ LinkBlinkCnt = 0;
+ break;
+ }
+
+}
+
+static void
+SwLedBlink15(
+ PLED_USB pLed
+)
+{
+ PADAPTER Adapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
+ bool bStopBlinking = false;
+ static u8 LinkBlinkCnt = 0;
+ /* Change LED according to BlinkingLedState specified. */
+
+ if (pLed->BlinkingLedState == RTW_LED_ON) {
+ SwLedOn(Adapter, pLed);
+ } else {
+ if (pLed->CurrLedState != LED_BLINK_WPS_STOP)
+ SwLedOff(Adapter, pLed);
+ }
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_WPS:
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_WPS_BLINK_ON_INTERVAL_DLINK);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_WPS_BLINK_OFF_INTERVAL_DLINK);
+ }
+ break;
+
+ case LED_BLINK_WPS_STOP: /* WPS success */
+
+ if (pLed->BlinkingLedState == RTW_LED_OFF) {
+ pLed->bLedWPSBlinkInProgress = false;
+ return;
+ }
+
+ pLed->CurrLedState = LED_BLINK_WPS_STOP;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+
+ _set_timer(&(pLed->BlinkTimer), LED_WPS_BLINK_LINKED_ON_INTERVAL_DLINK);
+ break;
+
+ case LED_BLINK_NO_LINK: {
+ static bool bLedOn = true;
+ if (bLedOn) {
+ bLedOn = false;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ } else {
+ bLedOn = true;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ }
+ pLed->bLedBlinkInProgress = true;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL);
+ }
+ break;
+
+ case LED_BLINK_LINK_IDEL: {
+ static bool bLedOn = true;
+ if (bLedOn) {
+ bLedOn = false;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ } else {
+ bLedOn = true;
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ }
+ pLed->bLedBlinkInProgress = true;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_IDEL_INTERVAL);
+ }
+ break;
+
+ case LED_BLINK_SCAN: {
+ static u8 BlinkTime = 0;
+ if (BlinkTime % 2 == 0)
+ pLed->BlinkingLedState = RTW_LED_ON;
+ else
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ BlinkTime++;
+
+ if (BlinkTime < 24) {
+ pLed->bLedBlinkInProgress = true;
+
+ if (pLed->BlinkingLedState == RTW_LED_ON)
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_OFF_INTERVAL);
+ else
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_ON_INTERVAL);
+ } else {
+ /* if(pLed->OLDLedState ==LED_NO_LINK_BLINK) */
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
+ pLed->CurrLedState = LED_BLINK_NO_LINK;
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), 100);
+ }
+ BlinkTime = 0;
+ }
+ }
+ break;
+
+ case LED_BLINK_TXRX:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(Adapter, pLed);
+ else
+ SwLedOn(Adapter, pLed);
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (adapter_to_pwrctl(Adapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(Adapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ SwLedOff(Adapter, pLed);
+ else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ default:
+ LinkBlinkCnt = 0;
+ break;
+ }
+
+}
+
+/*
+ * Description:
+ * Handler function of LED Blinking.
+ * We dispatch acture LED blink action according to LedStrategy.
+ * */
+void BlinkHandler(PLED_USB pLed)
+{
+ _adapter *padapter = pLed->padapter;
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+
+ /* RTW_INFO("%s (%s:%d)\n",__func__, current->comm, current->pid); */
+
+ if (RTW_CANNOT_RUN(padapter) || (!rtw_is_hw_init_completed(padapter))) {
+ /*RTW_INFO("%s bDriverStopped:%s, bSurpriseRemoved:%s\n"
+ , __func__
+ , rtw_is_drv_stopped(padapter)?"True":"False"
+ , rtw_is_surprise_removed(padapter)?"True":"False" );*/
+ return;
+ }
+
+ switch (ledpriv->LedStrategy) {
+ case SW_LED_MODE0:
+ SwLedBlink(pLed);
+ break;
+
+ case SW_LED_MODE1:
+ SwLedBlink1(pLed);
+ break;
+
+ case SW_LED_MODE2:
+ SwLedBlink2(pLed);
+ break;
+
+ case SW_LED_MODE3:
+ SwLedBlink3(pLed);
+ break;
+
+ case SW_LED_MODE4:
+ SwLedBlink4(pLed);
+ break;
+
+ case SW_LED_MODE5:
+ SwLedBlink5(pLed);
+ break;
+
+ case SW_LED_MODE6:
+ SwLedBlink6(pLed);
+ break;
+
+ case SW_LED_MODE7:
+ SwLedBlink7(pLed);
+ break;
+
+ case SW_LED_MODE8:
+ SwLedBlink8(pLed);
+ break;
+
+ case SW_LED_MODE9:
+ SwLedBlink9(pLed);
+ break;
+
+ case SW_LED_MODE10:
+ SwLedBlink10(pLed);
+ break;
+
+ case SW_LED_MODE11:
+ SwLedBlink11(pLed);
+ break;
+
+ case SW_LED_MODE12:
+ SwLedBlink12(pLed);
+ break;
+
+ case SW_LED_MODE13:
+ SwLedBlink13(pLed);
+ break;
+
+ case SW_LED_MODE14:
+ SwLedBlink14(pLed);
+ break;
+
+ case SW_LED_MODE15:
+ SwLedBlink15(pLed);
+ break;
+
+ default:
+ /* SwLedBlink(pLed); */
+ break;
+ }
+}
+
+/*
+ * Description:
+ * Callback function of LED BlinkTimer,
+ * it just schedules to corresponding BlinkWorkItem/led_blink_hdl
+ * */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
+void BlinkTimerCallback(void *data)
+#else
+void BlinkTimerCallback(struct timer_list *t)
+#endif
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
+ PLED_USB pLed = (PLED_USB)data;
+#else
+ PLED_USB pLed = from_timer(pLed, t, BlinkTimer);
+#endif
+ _adapter *padapter = pLed->padapter;
+
+ /* RTW_INFO("%s\n", __func__); */
+
+ if (RTW_CANNOT_RUN(padapter) || (!rtw_is_hw_init_completed(padapter))) {
+ /*RTW_INFO("%s bDriverStopped:%s, bSurpriseRemoved:%s\n"
+ , __func__
+ , rtw_is_drv_stopped(padapter)?"True":"False"
+ , rtw_is_surprise_removed(padapter)?"True":"False" );*/
+ return;
+ }
+
+#ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
+ rtw_led_blink_cmd(padapter, (void *)pLed);
+#else
+ _set_workitem(&(pLed->BlinkWorkItem));
+#endif
+}
+
+/*
+ * Description:
+ * Callback function of LED BlinkWorkItem.
+ * We dispatch acture LED blink action according to LedStrategy.
+ * */
+void BlinkWorkItemCallback(_workitem *work)
+{
+ PLED_USB pLed = container_of(work, LED_USB, BlinkWorkItem);
+ BlinkHandler(pLed);
+}
+
+static void
+SwLedControlMode0(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ PLED_USB pLed = &(ledpriv->SwLed1);
+
+ /* Decide led state */
+ switch (LedAction) {
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if (pLed->bLedBlinkInProgress == false) {
+ pLed->bLedBlinkInProgress = true;
+
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ pLed->BlinkTimes = 2;
+
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ break;
+
+ case LED_CTL_START_TO_LINK:
+ if (pLed->bLedBlinkInProgress == false) {
+ pLed->bLedBlinkInProgress = true;
+
+ pLed->CurrLedState = LED_BLINK_StartToBlink;
+ pLed->BlinkTimes = 24;
+
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ } else
+ pLed->CurrLedState = LED_BLINK_StartToBlink;
+ break;
+
+ case LED_CTL_LINK:
+ pLed->CurrLedState = RTW_LED_ON;
+ if (pLed->bLedBlinkInProgress == false) {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_NO_LINK:
+ pLed->CurrLedState = RTW_LED_OFF;
+ if (pLed->bLedBlinkInProgress == false) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ SwLedOff(padapter, pLed);
+ break;
+
+ case LED_CTL_START_WPS:
+ if (pLed->bLedBlinkInProgress == false || pLed->CurrLedState == RTW_LED_ON) {
+ pLed->bLedBlinkInProgress = true;
+
+ pLed->CurrLedState = LED_BLINK_WPS;
+ pLed->BlinkTimes = 20;
+
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
+ }
+ }
+ break;
+
+ case LED_CTL_STOP_WPS:
+ if (pLed->bLedBlinkInProgress) {
+ pLed->CurrLedState = RTW_LED_OFF;
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ break;
+
+
+ default:
+ break;
+ }
+
+
+}
+
+/* ALPHA, added by chiyoko, 20090106 */
+static void
+SwLedControlMode1(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ PLED_USB pLed = &(ledpriv->SwLed0);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+
+ u32 uLedBlinkNoLinkInterval = LED_BLINK_NO_LINK_INTERVAL_ALPHA; /* add by ylb 20121012 for customer led for alpha */
+ if (pHalData->CustomerID == RT_CID_819x_ALPHA_Dlink)
+ uLedBlinkNoLinkInterval = LED_BLINK_NO_LINK_INTERVAL_ALPHA_500MS;
+
+ if (pHalData->CustomerID == RT_CID_819x_CAMEO)
+ pLed = &(ledpriv->SwLed1);
+
+ switch (LedAction) {
+ case LED_CTL_POWER_ON:
+ case LED_CTL_START_TO_LINK:
+ case LED_CTL_NO_LINK:
+ if (pLed->bLedNoLinkBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), uLedBlinkNoLinkInterval);/* change by ylb 20121012 for customer led for alpha */
+ }
+ break;
+
+ case LED_CTL_LINK:
+ if (pLed->bLedLinkBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_SITE_SURVEY:
+ if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED) == true))
+ ;
+ else if (pLed->bLedScanBlinkInProgress == false) {
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedScanBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SCAN;
+ pLed->BlinkTimes = 24;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason == RF_CHANGE_BY_IPS)
+ _set_timer(&(pLed->BlinkTimer), LED_INITIAL_INTERVAL);
+ else
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+
+ }
+ break;
+
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if (pLed->bLedBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_START_WPS: /* wait until xinpin finish */
+ case LED_CTL_START_WPS_BOTTON:
+ if (pLed->bLedWPSBlinkInProgress == false) {
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+
+ case LED_CTL_STOP_WPS:
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress)
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ else
+ pLed->bLedWPSBlinkInProgress = true;
+
+ pLed->CurrLedState = LED_BLINK_WPS_STOP;
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL:
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), uLedBlinkNoLinkInterval);/* change by ylb 20121012 for customer led for alpha */
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if (pLed->bLedNoLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+
+ SwLedOff(padapter, pLed);
+ break;
+
+ default:
+ break;
+
+ }
+
+}
+
+/* Arcadyan/Sitecom , added by chiyoko, 20090216 */
+static void
+SwLedControlMode2(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ PLED_USB pLed = &(ledpriv->SwLed0);
+
+ switch (LedAction) {
+ case LED_CTL_SITE_SURVEY:
+ if (pmlmepriv->LinkDetectInfo.bBusyTraffic)
+ ;
+ else if (pLed->bLedScanBlinkInProgress == false) {
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedScanBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SCAN;
+ pLed->BlinkTimes = 24;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if ((pLed->bLedBlinkInProgress == false) && (check_fwstate(pmlmepriv, _FW_LINKED) == true)) {
+ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_LINK:
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_START_WPS: /* wait until xinpin finish */
+ case LED_CTL_START_WPS_BOTTON:
+ if (pLed->bLedWPSBlinkInProgress == false) {
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_STOP_WPS:
+ pLed->bLedWPSBlinkInProgress = false;
+ if (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on) {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ } else {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL:
+ pLed->bLedWPSBlinkInProgress = false;
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_START_TO_LINK:
+ case LED_CTL_NO_LINK:
+ if (!IS_LED_BLINKING(pLed)) {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+
+ SwLedOff(padapter, pLed);
+ break;
+
+ default:
+ break;
+
+ }
+
+}
+
+/* COREGA, added by chiyoko, 20090316 */
+static void
+SwLedControlMode3(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ PLED_USB pLed = &(ledpriv->SwLed0);
+
+ switch (LedAction) {
+ case LED_CTL_SITE_SURVEY:
+ if (pmlmepriv->LinkDetectInfo.bBusyTraffic)
+ ;
+ else if (pLed->bLedScanBlinkInProgress == false) {
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedScanBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SCAN;
+ pLed->BlinkTimes = 24;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if ((pLed->bLedBlinkInProgress == false) && (check_fwstate(pmlmepriv, _FW_LINKED) == true)) {
+ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_LINK:
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_START_WPS: /* wait until xinpin finish */
+ case LED_CTL_START_WPS_BOTTON:
+ if (pLed->bLedWPSBlinkInProgress == false) {
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_STOP_WPS:
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ } else
+ pLed->bLedWPSBlinkInProgress = true;
+
+ pLed->CurrLedState = LED_BLINK_WPS_STOP;
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL:
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_START_TO_LINK:
+ case LED_CTL_NO_LINK:
+ if (!IS_LED_BLINKING(pLed)) {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+
+ SwLedOff(padapter, pLed);
+ break;
+
+ default:
+ break;
+
+ }
+
+}
+
+
+/* Edimax-Belkin, added by chiyoko, 20090413 */
+static void
+SwLedControlMode4(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ PLED_USB pLed = &(ledpriv->SwLed0);
+ PLED_USB pLed1 = &(ledpriv->SwLed1);
+
+ switch (LedAction) {
+ case LED_CTL_START_TO_LINK:
+ if (pLed1->bLedWPSBlinkInProgress) {
+ pLed1->bLedWPSBlinkInProgress = false;
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ pLed1->CurrLedState = RTW_LED_OFF;
+
+ if (pLed1->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+
+ if (pLed->bLedStartToLinkBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+
+ pLed->bLedStartToLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_StartToBlink;
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ }
+ break;
+
+ case LED_CTL_LINK:
+ case LED_CTL_NO_LINK:
+ /* LED1 settings */
+ if (LedAction == LED_CTL_LINK) {
+ if (pLed1->bLedWPSBlinkInProgress) {
+ pLed1->bLedWPSBlinkInProgress = false;
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ pLed1->CurrLedState = RTW_LED_OFF;
+
+ if (pLed1->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ }
+
+ if (pLed->bLedNoLinkBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_SITE_SURVEY:
+ if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED) == true))
+ ;
+ else if (pLed->bLedScanBlinkInProgress == false) {
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedScanBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SCAN;
+ pLed->BlinkTimes = 24;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if (pLed->bLedBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_START_WPS: /* wait until xinpin finish */
+ case LED_CTL_START_WPS_BOTTON:
+ if (pLed1->bLedWPSBlinkInProgress) {
+ pLed1->bLedWPSBlinkInProgress = false;
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ pLed1->CurrLedState = RTW_LED_OFF;
+
+ if (pLed1->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+
+ if (pLed->bLedWPSBlinkInProgress == false) {
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ }
+ break;
+
+ case LED_CTL_STOP_WPS: /* WPS connect success */
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL: /* WPS authentication fail */
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+
+ /* LED1 settings */
+ if (pLed1->bLedWPSBlinkInProgress)
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ else
+ pLed1->bLedWPSBlinkInProgress = true;
+
+ pLed1->CurrLedState = LED_BLINK_WPS_STOP;
+ if (pLed1->bLedOn)
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed1->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL_OVERLAP: /* WPS session overlap */
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+
+ /* LED1 settings */
+ if (pLed1->bLedWPSBlinkInProgress)
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ else
+ pLed1->bLedWPSBlinkInProgress = true;
+
+ pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP;
+ pLed1->BlinkTimes = 10;
+ if (pLed1->bLedOn)
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed1->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+
+ if (pLed->bLedNoLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ if (pLed->bLedStartToLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedStartToLinkBlinkInProgress = false;
+ }
+
+ if (pLed1->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ pLed1->bLedWPSBlinkInProgress = false;
+ }
+
+ pLed1->BlinkingLedState = LED_UNKNOWN;
+ SwLedOff(padapter, pLed);
+ SwLedOff(padapter, pLed1);
+ break;
+
+ case LED_CTL_CONNECTION_NO_TRANSFER:
+ if (pLed->bLedBlinkInProgress == false) {
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ pLed->bLedBlinkInProgress = true;
+
+ pLed->CurrLedState = LED_BLINK_ALWAYS_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ break;
+
+ default:
+ break;
+
+ }
+
+}
+
+
+
+/* Sercomm-Belkin, added by chiyoko, 20090415 */
+static void
+SwLedControlMode5(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+ PLED_USB pLed = &(ledpriv->SwLed0);
+
+ if (pHalData->CustomerID == RT_CID_819x_CAMEO)
+ pLed = &(ledpriv->SwLed1);
+
+ switch (LedAction) {
+ case LED_CTL_POWER_ON:
+ case LED_CTL_NO_LINK:
+ case LED_CTL_LINK: /* solid blue */
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_SITE_SURVEY:
+ if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED) == true))
+ ;
+ else if (pLed->bLedScanBlinkInProgress == false) {
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedScanBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SCAN;
+ pLed->BlinkTimes = 24;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if (pLed->bLedBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_BLINK_SCAN)
+ return;
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+
+ SwLedOff(padapter, pLed);
+ break;
+
+ default:
+ break;
+
+ }
+
+}
+
+/* WNC-Corega, added by chiyoko, 20090902 */
+static void
+SwLedControlMode6(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ PLED_USB pLed0 = &(ledpriv->SwLed0);
+
+ switch (LedAction) {
+ case LED_CTL_POWER_ON:
+ case LED_CTL_LINK:
+ case LED_CTL_NO_LINK:
+ _cancel_timer_ex(&(pLed0->BlinkTimer));
+ pLed0->CurrLedState = RTW_LED_ON;
+ pLed0->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed0->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_POWER_OFF:
+ SwLedOff(padapter, pLed0);
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+/* Netgear, added by sinda, 2011/11/11 */
+static void
+SwLedControlMode7(
+ PADAPTER Adapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(Adapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+ PLED_USB pLed = &(ledpriv->SwLed0);
+
+ switch (LedAction) {
+ case LED_CTL_SITE_SURVEY:
+ if (pmlmepriv->LinkDetectInfo.bBusyTraffic)
+ ;
+ else if (pLed->bLedScanBlinkInProgress == false) {
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedScanBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SCAN;
+ pLed->BlinkTimes = 6;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_NETGEAR);
+ }
+ break;
+
+ case LED_CTL_LINK:
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_START_WPS: /* wait until xinpin finish */
+ case LED_CTL_START_WPS_BOTTON:
+ if (pLed->bLedWPSBlinkInProgress == false) {
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_NETGEAR);
+ }
+ break;
+
+ case LED_CTL_STOP_WPS:
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ } else
+ pLed->bLedWPSBlinkInProgress = true;
+
+ pLed->CurrLedState = LED_BLINK_WPS_STOP;
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_NETGEAR);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+
+ break;
+
+
+ case LED_CTL_STOP_WPS_FAIL:
+ case LED_CTL_STOP_WPS_FAIL_OVERLAP: /* WPS session overlap */
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_START_TO_LINK:
+ case LED_CTL_NO_LINK:
+ if (!IS_LED_BLINKING(pLed)) {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_POWER_OFF:
+ case LED_CTL_POWER_ON:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ default:
+ break;
+
+ }
+
+}
+
+static void
+SwLedControlMode8(
+ PADAPTER Adapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(Adapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+ PLED_USB pLed0 = &(ledpriv->SwLed0);
+
+ switch (LedAction) {
+ case LED_CTL_LINK:
+ _cancel_timer_ex(&(pLed0->BlinkTimer));
+ pLed0->CurrLedState = RTW_LED_ON;
+ pLed0->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed0->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_NO_LINK:
+ _cancel_timer_ex(&(pLed0->BlinkTimer));
+ pLed0->CurrLedState = RTW_LED_OFF;
+ pLed0->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed0->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_POWER_OFF:
+ SwLedOff(Adapter, pLed0);
+ break;
+
+ default:
+ break;
+ }
+
+
+}
+
+/* page added for Belkin AC950, 20120813 */
+static void
+SwLedControlMode9(
+ PADAPTER Adapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(Adapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+ PLED_USB pLed = &(ledpriv->SwLed0);
+ PLED_USB pLed1 = &(ledpriv->SwLed1);
+ PLED_USB pLed2 = &(ledpriv->SwLed2);
+ bool bWPSOverLap = false;
+ /* RTW_INFO("LedAction=%d\n", LedAction); */
+ switch (LedAction) {
+ case LED_CTL_START_TO_LINK:
+ if (pLed2->bLedBlinkInProgress == false) {
+ pLed2->bLedBlinkInProgress = true;
+ pLed2->BlinkingLedState = RTW_LED_ON;
+ pLed2->CurrLedState = LED_BLINK_LINK_IN_PROCESS;
+
+ _set_timer(&(pLed2->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_LINK:
+ case LED_CTL_NO_LINK:
+ /* LED1 settings */
+ if (LedAction == LED_CTL_NO_LINK) {
+ /* if(pMgntInfo->AuthStatus == AUTH_STATUS_FAILED) */
+ if (0) {
+ pLed1->CurrLedState = LED_BLINK_AUTH_ERROR;
+ if (pLed1->bLedOn)
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed1->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed1->BlinkTimer), 0);
+ } else {
+ pLed1->CurrLedState = RTW_LED_OFF;
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ if (pLed1->bLedOn)
+ _set_timer(&(pLed1->BlinkTimer), 0);
+ }
+ } else {
+ pLed1->CurrLedState = RTW_LED_OFF;
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ if (pLed1->bLedOn)
+ _set_timer(&(pLed1->BlinkTimer), 0);
+ }
+
+ /* LED2 settings */
+ if (LedAction == LED_CTL_LINK) {
+ if (Adapter->securitypriv.dot11PrivacyAlgrthm != _NO_PRIVACY_) {
+ if (pLed2->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed2->BlinkTimer));
+ pLed2->bLedBlinkInProgress = false;
+ }
+ pLed2->CurrLedState = RTW_LED_ON;
+ pLed2->bLedNoLinkBlinkInProgress = true;
+ if (!pLed2->bLedOn)
+ _set_timer(&(pLed2->BlinkTimer), 0);
+ } else {
+ if (pLed2->bLedWPSBlinkInProgress != true) {
+ pLed2->CurrLedState = RTW_LED_OFF;
+ pLed2->BlinkingLedState = RTW_LED_OFF;
+ if (pLed2->bLedOn)
+ _set_timer(&(pLed2->BlinkTimer), 0);
+ }
+ }
+ } else { /* NO_LINK */
+ if (pLed2->bLedWPSBlinkInProgress == false) {
+ pLed2->CurrLedState = RTW_LED_OFF;
+ pLed2->BlinkingLedState = RTW_LED_OFF;
+ if (pLed2->bLedOn)
+ _set_timer(&(pLed2->BlinkTimer), 0);
+ }
+ }
+
+ /* LED0 settings */
+ if (pLed->bLedNoLinkBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+
+ break;
+
+ case LED_CTL_SITE_SURVEY:
+ if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED) == true))
+ ;
+ else { /* if(pLed->bLedScanBlinkInProgress ==false) */
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedScanBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SCAN;
+ pLed->BlinkTimes = 24;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+
+ }
+ break;
+
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if (pLed->bLedBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_START_WPS: /* wait until xinpin finish */
+ case LED_CTL_START_WPS_BOTTON:
+ pLed2->bLedBlinkInProgress = true;
+ pLed2->BlinkingLedState = RTW_LED_ON;
+ pLed2->CurrLedState = LED_BLINK_LINK_IN_PROCESS;
+ pLed2->bLedWPSBlinkInProgress = true;
+
+ _set_timer(&(pLed2->BlinkTimer), 500);
+
+ break;
+
+ case LED_CTL_STOP_WPS: /* WPS connect success */
+ /* LED2 settings */
+ if (pLed2->bLedWPSBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed2->BlinkTimer));
+ pLed2->bLedBlinkInProgress = false;
+ pLed2->bLedWPSBlinkInProgress = false;
+ }
+ pLed2->CurrLedState = RTW_LED_ON;
+ pLed2->bLedNoLinkBlinkInProgress = true;
+ if (!pLed2->bLedOn)
+ _set_timer(&(pLed2->BlinkTimer), 0);
+
+ /* LED1 settings */
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ pLed1->CurrLedState = RTW_LED_OFF;
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ if (pLed1->bLedOn)
+ _set_timer(&(pLed1->BlinkTimer), 0);
+
+
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL: /* WPS authentication fail */
+ /* LED1 settings */
+ /* if(bWPSOverLap == false) */
+ {
+ pLed1->CurrLedState = LED_BLINK_AUTH_ERROR;
+ pLed1->BlinkTimes = 50;
+ if (pLed1->bLedOn)
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed1->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed1->BlinkTimer), 0);
+ }
+ /* else */
+ /* { */
+ /* bWPSOverLap = false; */
+ /* pLed1->CurrLedState = RTW_LED_OFF; */
+ /* pLed1->BlinkingLedState = RTW_LED_OFF; */
+ /* _set_timer(&(pLed1->BlinkTimer), 0); */
+ /* } */
+
+ /* LED2 settings */
+ pLed2->CurrLedState = RTW_LED_OFF;
+ pLed2->BlinkingLedState = RTW_LED_OFF;
+ pLed2->bLedWPSBlinkInProgress = false;
+ if (pLed2->bLedOn)
+ _set_timer(&(pLed2->BlinkTimer), 0);
+
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL_OVERLAP: /* WPS session overlap */
+ /* LED1 settings */
+ bWPSOverLap = true;
+ pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP;
+ pLed1->BlinkTimes = 10;
+ pLed1->BlinkCounter = 50;
+ if (pLed1->bLedOn)
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed1->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed1->BlinkTimer), 0);
+
+ /* LED2 settings */
+ pLed2->CurrLedState = RTW_LED_OFF;
+ pLed2->BlinkingLedState = RTW_LED_OFF;
+ pLed2->bLedWPSBlinkInProgress = false;
+ if (pLed2->bLedOn)
+ _set_timer(&(pLed2->BlinkTimer), 0);
+
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+
+ if (pLed->bLedNoLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ if (pLed->bLedStartToLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedStartToLinkBlinkInProgress = false;
+ }
+
+ if (pLed1->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ pLed1->bLedWPSBlinkInProgress = false;
+ }
+
+
+ pLed1->BlinkingLedState = LED_UNKNOWN;
+ SwLedOff(Adapter, pLed);
+ SwLedOff(Adapter, pLed1);
+ break;
+
+ case LED_CTL_CONNECTION_NO_TRANSFER:
+ if (pLed->bLedBlinkInProgress == false) {
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ pLed->bLedBlinkInProgress = true;
+
+ pLed->CurrLedState = LED_BLINK_ALWAYS_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ break;
+
+ default:
+ break;
+
+ }
+
+}
+
+/* page added for Netgear A6200V2, 20120827 */
+static void
+SwLedControlMode10(
+ PADAPTER Adapter,
+ LED_CTL_MODE LedAction
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct led_priv *ledpriv = &(Adapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+ PLED_USB pLed = &(ledpriv->SwLed0);
+ PLED_USB pLed1 = &(ledpriv->SwLed1);
+
+ switch (LedAction) {
+ case LED_CTL_START_TO_LINK:
+ if (pLed1->bLedBlinkInProgress == false) {
+ pLed1->bLedBlinkInProgress = true;
+ pLed1->BlinkingLedState = RTW_LED_ON;
+ pLed1->CurrLedState = LED_BLINK_LINK_IN_PROCESS;
+
+ _set_timer(&(pLed1->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_LINK:
+ case LED_CTL_NO_LINK:
+ if (LedAction == LED_CTL_LINK) {
+ if (pLed->bLedWPSBlinkInProgress == true || pLed1->bLedWPSBlinkInProgress == true)
+ ;
+ else {
+ if (pHalData->current_band_type == BAND_ON_2_4G)
+ /* LED0 settings */
+ {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ _set_timer(&(pLed->BlinkTimer), 0);
+
+ pLed1->CurrLedState = RTW_LED_OFF;
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed1->BlinkTimer), 0);
+ } else if (pHalData->current_band_type == BAND_ON_5G)
+ /* LED1 settings */
+ {
+ pLed1->CurrLedState = RTW_LED_ON;
+ pLed1->BlinkingLedState = RTW_LED_ON;
+ if (pLed1->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ pLed1->bLedBlinkInProgress = false;
+ }
+ _set_timer(&(pLed1->BlinkTimer), 0);
+
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ }
+ } else if (LedAction == LED_CTL_NO_LINK) { /* TODO by page */
+ if (pLed->bLedWPSBlinkInProgress == true || pLed1->bLedWPSBlinkInProgress == true)
+ ;
+ else {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if (pLed->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), 0);
+
+ pLed1->CurrLedState = RTW_LED_OFF;
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ if (pLed1->bLedOn)
+ _set_timer(&(pLed1->BlinkTimer), 0);
+ }
+ }
+
+ break;
+
+ case LED_CTL_SITE_SURVEY:
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
+ ; /* don't blink when media connect */
+ else { /* if(pLed->bLedScanBlinkInProgress ==false) */
+ if (IS_LED_WPS_BLINKING(pLed) || IS_LED_WPS_BLINKING(pLed1))
+ return;
+
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedScanBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SCAN;
+ pLed->BlinkTimes = 12;
+ pLed->BlinkingLedState = LED_BLINK_SCAN;
+ _set_timer(&(pLed->BlinkTimer), 0);
+
+ if (pLed1->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ pLed1->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed1->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ pLed1->bLedBlinkInProgress = false;
+ }
+ pLed1->bLedScanBlinkInProgress = true;
+ pLed1->CurrLedState = LED_BLINK_SCAN;
+ pLed1->BlinkTimes = 12;
+ pLed1->BlinkingLedState = LED_BLINK_SCAN;
+ _set_timer(&(pLed1->BlinkTimer), LED_BLINK_LINK_SLOWLY_INTERVAL_NETGEAR);
+
+ }
+ break;
+
+ case LED_CTL_START_WPS: /* wait until xinpin finish */
+ case LED_CTL_START_WPS_BOTTON:
+ /* LED0 settings */
+ if (pLed->bLedBlinkInProgress == false) {
+ pLed->bLedBlinkInProgress = true;
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->BlinkingLedState = LED_BLINK_WPS;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+
+ /* LED1 settings */
+ if (pLed1->bLedBlinkInProgress == false) {
+ pLed1->bLedBlinkInProgress = true;
+ pLed1->bLedWPSBlinkInProgress = true;
+ pLed1->BlinkingLedState = LED_BLINK_WPS;
+ pLed1->CurrLedState = LED_BLINK_WPS;
+ _set_timer(&(pLed1->BlinkTimer), LED_BLINK_NORMAL_INTERVAL + LED_BLINK_LINK_INTERVAL_NETGEAR);
+ }
+
+
+ break;
+
+ case LED_CTL_STOP_WPS: /* WPS connect success */
+ if (pHalData->current_band_type == BAND_ON_2_4G)
+ /* LED0 settings */
+ {
+ pLed->bLedWPSBlinkInProgress = false;
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ _set_timer(&(pLed->BlinkTimer), 0);
+
+ pLed1->CurrLedState = RTW_LED_OFF;
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed1->BlinkTimer), 0);
+ } else if (pHalData->current_band_type == BAND_ON_5G)
+ /* LED1 settings */
+ {
+ pLed1->bLedWPSBlinkInProgress = false;
+ pLed1->CurrLedState = RTW_LED_ON;
+ pLed1->BlinkingLedState = RTW_LED_ON;
+ if (pLed1->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ pLed1->bLedBlinkInProgress = false;
+ }
+ _set_timer(&(pLed1->BlinkTimer), 0);
+
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL: /* WPS authentication fail */
+ /* LED1 settings */
+ pLed1->bLedWPSBlinkInProgress = false;
+ pLed1->CurrLedState = RTW_LED_OFF;
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed1->BlinkTimer), 0);
+
+ /* LED0 settings */
+ pLed->bLedWPSBlinkInProgress = false;
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if (pLed->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), 0);
+
+ break;
+
+
+ default:
+ break;
+
+ }
+
+}
+
+/* Edimax-ASUS, added by Page, 20121221 */
+static void
+SwLedControlMode11(
+ PADAPTER Adapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(Adapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+ PLED_USB pLed = &(ledpriv->SwLed0);
+
+ switch (LedAction) {
+ case LED_CTL_POWER_ON:
+ case LED_CTL_START_TO_LINK:
+ case LED_CTL_NO_LINK:
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_LINK:
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ break;
+
+ case LED_CTL_START_WPS: /* wait until xinpin finish */
+ case LED_CTL_START_WPS_BOTTON:
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ pLed->BlinkTimes = 5;
+ _set_timer(&(pLed->BlinkTimer), 0);
+
+ break;
+
+
+ case LED_CTL_STOP_WPS:
+ case LED_CTL_STOP_WPS_FAIL:
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->CurrLedState = LED_BLINK_WPS_STOP;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+
+ if (pLed->bLedNoLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+
+ SwLedOff(Adapter, pLed);
+ break;
+
+ default:
+ break;
+
+ }
+
+}
+
+/* page added for NEC */
+
+static void
+SwLedControlMode12(
+ PADAPTER Adapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(Adapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+ PLED_USB pLed = &(ledpriv->SwLed0);
+
+ switch (LedAction) {
+ case LED_CTL_POWER_ON:
+ case LED_CTL_NO_LINK:
+ case LED_CTL_LINK:
+ case LED_CTL_SITE_SURVEY:
+
+ if (pLed->bLedNoLinkBlinkInProgress == false) {
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if (pLed->bLedBlinkInProgress == false) {
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+
+ SwLedOff(Adapter, pLed);
+ break;
+
+ default:
+ break;
+
+ }
+
+}
+
+/* Maddest add for NETGEAR R6100 */
+
+static void
+SwLedControlMode13(
+ PADAPTER Adapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(Adapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+ PLED_USB pLed = &(ledpriv->SwLed0);
+
+ switch (LedAction) {
+ case LED_CTL_LINK:
+ if (pLed->bLedWPSBlinkInProgress)
+ return;
+
+
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_START_WPS: /* wait until xinpin finish */
+ case LED_CTL_START_WPS_BOTTON:
+ if (pLed->bLedWPSBlinkInProgress == false) {
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_WPS_BLINK_OFF_INTERVAL_NETGEAR);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_WPS_BLINK_ON_INTERVAL_NETGEAR);
+ }
+ }
+ break;
+
+ case LED_CTL_STOP_WPS:
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ } else
+ pLed->bLedWPSBlinkInProgress = true;
+
+ pLed->bLedWPSBlinkInProgress = false;
+ pLed->CurrLedState = LED_BLINK_WPS_STOP;
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+
+ break;
+
+
+ case LED_CTL_STOP_WPS_FAIL:
+ case LED_CTL_STOP_WPS_FAIL_OVERLAP: /* WPS session overlap */
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_START_TO_LINK:
+ if ((pLed->bLedBlinkInProgress == false) && (pLed->bLedWPSBlinkInProgress == false)) {
+ pLed->bLedBlinkInProgress = true;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ pLed->CurrLedState = LED_BLINK_LINK_IN_PROCESS;
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_NO_LINK:
+
+ if (pLed->bLedWPSBlinkInProgress)
+ return;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ /* if(!IS_LED_BLINKING(pLed)) */
+ {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_POWER_OFF:
+ case LED_CTL_POWER_ON:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+
+ if (LedAction == LED_CTL_POWER_ON)
+ _set_timer(&(pLed->BlinkTimer), 0);
+ else
+ SwLedOff(Adapter, pLed);
+ break;
+
+ default:
+ break;
+
+ }
+
+
+}
+
+/* Maddest add for DNI Buffalo */
+
+static void
+SwLedControlMode14(
+ PADAPTER Adapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(Adapter->ledpriv);
+ PLED_USB pLed = &(ledpriv->SwLed0);
+
+ switch (LedAction) {
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ SwLedOff(Adapter, pLed);
+ break;
+
+ case LED_CTL_POWER_ON:
+ SwLedOn(Adapter, pLed);
+ break;
+
+ case LED_CTL_LINK:
+ case LED_CTL_NO_LINK:
+ break;
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if (pLed->bLedBlinkInProgress == false) {
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* Maddest add for Dlink */
+
+static void
+SwLedControlMode15(
+ PADAPTER Adapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(Adapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+ PLED_USB pLed = &(ledpriv->SwLed0);
+
+ switch (LedAction) {
+ case LED_CTL_START_WPS: /* wait until xinpin finish */
+ case LED_CTL_START_WPS_BOTTON:
+ if (pLed->bLedWPSBlinkInProgress == false) {
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_WPS_BLINK_OFF_INTERVAL_NETGEAR);
+ } else {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_WPS_BLINK_ON_INTERVAL_NETGEAR);
+ }
+ }
+ break;
+
+ case LED_CTL_STOP_WPS:
+ if (pLed->bLedWPSBlinkInProgress)
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+
+ pLed->CurrLedState = LED_BLINK_WPS_STOP;
+ /* if(check_fwstate(pmlmepriv, _FW_LINKED)== true) */
+ {
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL:
+ case LED_CTL_STOP_WPS_FAIL_OVERLAP: /* WPS session overlap */
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_NO_LINK:
+ if (pLed->bLedWPSBlinkInProgress)
+ return;
+
+ /*if(Adapter->securitypriv.dot11PrivacyAlgrthm > _NO_PRIVACY_)
+ {
+ if(SecIsTxKeyInstalled(Adapter, pMgntInfo->Bssid))
+ {
+ }
+ else
+ {
+ if(pMgntInfo->LEDAssocState ==LED_ASSOC_SECURITY_BEGIN)
+ return;
+ }
+ }*/
+
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ /* if(!IS_LED_BLINKING(pLed)) */
+ {
+ pLed->CurrLedState = LED_BLINK_NO_LINK;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 30);
+ }
+ break;
+
+ case LED_CTL_LINK:
+
+ if (pLed->bLedWPSBlinkInProgress)
+ return;
+
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+
+ pLed->CurrLedState = LED_BLINK_LINK_IDEL;
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), 30);
+ break;
+
+ case LED_CTL_SITE_SURVEY:
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
+ return;
+
+ if (pLed->bLedWPSBlinkInProgress == true)
+ return;
+
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->CurrLedState = LED_BLINK_SCAN;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if (pLed->bLedWPSBlinkInProgress)
+ return;
+
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void
+LedControlUSB(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+
+#if (MP_DRIVER == 1)
+ if (padapter->registrypriv.mp_mode == 1)
+ return;
+#endif
+
+ if (RTW_CANNOT_RUN(padapter) || (!rtw_is_hw_init_completed(padapter))) {
+ /*RTW_INFO("%s bDriverStopped:%s, bSurpriseRemoved:%s\n"
+ , __func__
+ , rtw_is_drv_stopped(padapter)?"True":"False"
+ , rtw_is_surprise_removed(padapter)?"True":"False" );*/
+ return;
+ }
+
+ if (ledpriv->bRegUseLed == false)
+ return;
+
+ /* if(priv->bInHctTest) */
+ /* return; */
+
+#ifdef CONFIG_CONCURRENT_MODE
+ /* Only do led action for PRIMARY_ADAPTER */
+ if (padapter->adapter_type != PRIMARY_ADAPTER)
+ return;
+#endif
+
+ if ((adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on &&
+ adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS) &&
+ (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX ||
+ LedAction == LED_CTL_SITE_SURVEY ||
+ LedAction == LED_CTL_LINK ||
+ LedAction == LED_CTL_NO_LINK ||
+ LedAction == LED_CTL_POWER_ON))
+ return;
+
+ switch (ledpriv->LedStrategy) {
+ case SW_LED_MODE0:
+ SwLedControlMode0(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE1:
+ SwLedControlMode1(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE2:
+ SwLedControlMode2(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE3:
+ SwLedControlMode3(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE4:
+ SwLedControlMode4(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE5:
+ SwLedControlMode5(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE6:
+ SwLedControlMode6(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE7:
+ SwLedControlMode7(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE8:
+ SwLedControlMode8(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE9:
+ SwLedControlMode9(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE10:
+ SwLedControlMode10(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE11:
+ SwLedControlMode11(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE12:
+ SwLedControlMode12(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE13:
+ SwLedControlMode13(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE14:
+ SwLedControlMode14(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE15:
+ SwLedControlMode15(padapter, LedAction);
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+/*
+ * Description:
+ * Reset status of LED_871x object.
+ * */
+void ResetLedStatus(PLED_USB pLed)
+{
+
+ pLed->CurrLedState = RTW_LED_OFF; /* Current LED state. */
+ pLed->bLedOn = false; /* true if LED is ON, false if LED is OFF. */
+
+ pLed->bLedBlinkInProgress = false; /* true if it is blinking, false o.w.. */
+ pLed->bLedWPSBlinkInProgress = false;
+
+ pLed->BlinkTimes = 0; /* Number of times to toggle led state for blinking. */
+ pLed->BlinkCounter = 0;
+ pLed->BlinkingLedState = LED_UNKNOWN; /* Next state for blinking, either RTW_LED_ON or RTW_LED_OFF are. */
+
+ pLed->bLedNoLinkBlinkInProgress = false;
+ pLed->bLedLinkBlinkInProgress = false;
+ pLed->bLedStartToLinkBlinkInProgress = false;
+ pLed->bLedScanBlinkInProgress = false;
+}
+
+/*
+* Description:
+* Initialize an LED_871x object.
+* */
+void
+InitLed(
+ _adapter *padapter,
+ PLED_USB pLed,
+ LED_PIN LedPin
+)
+{
+ pLed->padapter = padapter;
+ pLed->LedPin = LedPin;
+
+ ResetLedStatus(pLed);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
+ _init_timer(&(pLed->BlinkTimer), padapter->pnetdev, BlinkTimerCallback, pLed);
+#else
+ timer_setup(&pLed->BlinkTimer, BlinkTimerCallback, 0);
+#endif
+ _init_workitem(&(pLed->BlinkWorkItem), BlinkWorkItemCallback, pLed);
+}
+
+
+/*
+ * Description:
+ * DeInitialize an LED_871x object.
+ * */
+void
+DeInitLed(
+ PLED_USB pLed
+)
+{
+ _cancel_workitem_sync(&(pLed->BlinkWorkItem));
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ ResetLedStatus(pLed);
+}
diff --git a/drivers/staging/rtl8188eu/hal/halcomtxbf.h b/drivers/staging/rtl8188eu/hal/halcomtxbf.h
new file mode 100644
index 000000000000..a303e5404569
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/halcomtxbf.h
@@ -0,0 +1,135 @@
+#ifndef __HAL_COM_TXBF_H__
+#define __HAL_COM_TXBF_H__
+
+/*
+typedef bool
+(*TXBF_GET)(
+ void* p_adapter,
+ u8 get_type,
+ void* p_out_buf
+ );
+
+typedef bool
+(*TXBF_SET)(
+ void* p_adapter,
+ u8 set_type,
+ void* p_in_buf
+ );
+*/
+
+enum txbf_set_type {
+ TXBF_SET_SOUNDING_ENTER,
+ TXBF_SET_SOUNDING_LEAVE,
+ TXBF_SET_SOUNDING_RATE,
+ TXBF_SET_SOUNDING_STATUS,
+ TXBF_SET_SOUNDING_FW_NDPA,
+ TXBF_SET_SOUNDING_CLK,
+ TXBF_SET_TX_PATH_RESET,
+ TXBF_SET_GET_TX_RATE
+};
+
+
+enum txbf_get_type {
+ TXBF_GET_EXPLICIT_BEAMFORMEE,
+ TXBF_GET_EXPLICIT_BEAMFORMER,
+ TXBF_GET_MU_MIMO_STA,
+ TXBF_GET_MU_MIMO_AP
+};
+
+
+
+/* 2 HAL TXBF related */
+struct _HAL_TXBF_INFO {
+ u8 txbf_idx;
+ u8 ndpa_idx;
+ u8 BW;
+ u8 rate;
+ struct timer_list txbf_fw_ndpa_timer;
+};
+
+#if (BEAMFORMING_SUPPORT == 1)
+
+void
+hal_com_txbf_beamform_init(
+ void *p_dm_void
+);
+
+void
+hal_com_txbf_config_gtab(
+ void *p_dm_void
+);
+
+void
+hal_com_txbf_enter_work_item_callback(
+ void *p_dm_void
+);
+
+void
+hal_com_txbf_leave_work_item_callback(
+ void *p_dm_void
+);
+
+void
+hal_com_txbf_fw_ndpa_work_item_callback(
+ void *p_dm_void
+);
+
+void
+hal_com_txbf_clk_work_item_callback(
+ void *p_dm_void
+);
+
+void
+hal_com_txbf_reset_tx_path_work_item_callback(
+ void *p_dm_void
+);
+
+void
+hal_com_txbf_get_tx_rate_work_item_callback(
+ void *p_dm_void
+);
+
+void
+hal_com_txbf_rate_work_item_callback(
+ void *p_dm_void
+);
+
+void
+hal_com_txbf_fw_ndpa_timer_callback(
+ struct timer_list *p_timer
+);
+
+void
+hal_com_txbf_status_work_item_callback(
+ void *p_dm_void
+);
+
+bool
+hal_com_txbf_set(
+ void *p_dm_void,
+ u8 set_type,
+ void *p_in_buf
+);
+
+bool
+hal_com_txbf_get(
+ struct _ADAPTER *adapter,
+ u8 get_type,
+ void *p_out_buf
+);
+
+#else
+#define hal_com_txbf_beamform_init(p_dm_void) NULL
+#define hal_com_txbf_config_gtab(p_dm_void) NULL
+#define hal_com_txbf_enter_work_item_callback(_adapter) NULL
+#define hal_com_txbf_leave_work_item_callback(_adapter) NULL
+#define hal_com_txbf_fw_ndpa_work_item_callback(_adapter) NULL
+#define hal_com_txbf_clk_work_item_callback(_adapter) NULL
+#define hal_com_txbf_rate_work_item_callback(_adapter) NULL
+#define hal_com_txbf_fw_ndpa_timer_callback(_adapter) NULL
+#define hal_com_txbf_status_work_item_callback(_adapter) NULL
+#define hal_com_txbf_get(_adapter, _get_type, _pout_buf)
+
+#endif
+
+#endif /* #ifndef __HAL_COM_TXBF_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/halhwimg.h b/drivers/staging/rtl8188eu/hal/halhwimg.h
new file mode 100644
index 000000000000..3bb88565d9e8
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/halhwimg.h
@@ -0,0 +1,78 @@
+#pragma once
+#ifndef __INC_HW_IMG_H
+#define __INC_HW_IMG_H
+
+/*
+ * 2011/03/15 MH Add for different IC HW image file selection. code size consideration.
+ * */
+ #if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
+ /* For 92C */
+ #define RTL8192CE_HWIMG_SUPPORT 1
+ #define RTL8192CE_TEST_HWIMG_SUPPORT 0
+ #define RTL8192CU_HWIMG_SUPPORT 0
+ #define RTL8192CU_TEST_HWIMG_SUPPORT 0
+
+ /* For 92D */
+ #define RTL8192DE_HWIMG_SUPPORT 1
+ #define RTL8192DE_TEST_HWIMG_SUPPORT 0
+ #define RTL8192DU_HWIMG_SUPPORT 0
+ #define RTL8192DU_TEST_HWIMG_SUPPORT 0
+
+ /* For 8723 */
+ #define RTL8723E_HWIMG_SUPPORT 1
+ #define RTL8723U_HWIMG_SUPPORT 0
+ #define RTL8723S_HWIMG_SUPPORT 0
+
+ /* For 88E */
+ #define RTL8188EE_HWIMG_SUPPORT 0
+ #define RTL8188EU_HWIMG_SUPPORT 0
+ #define RTL8188ES_HWIMG_SUPPORT 0
+
+ #elif (DEV_BUS_TYPE == RT_USB_INTERFACE)
+ /* For 92C */
+ #define RTL8192CE_HWIMG_SUPPORT 0
+ #define RTL8192CE_TEST_HWIMG_SUPPORT 0
+ #define RTL8192CU_HWIMG_SUPPORT 1
+ #define RTL8192CU_TEST_HWIMG_SUPPORT 0
+
+ /* For 92D */
+ #define RTL8192DE_HWIMG_SUPPORT 0
+ #define RTL8192DE_TEST_HWIMG_SUPPORT 0
+ #define RTL8192DU_HWIMG_SUPPORT 1
+ #define RTL8192DU_TEST_HWIMG_SUPPORT 0
+
+ /* For 8723 */
+ #define RTL8723E_HWIMG_SUPPORT 0
+ #define RTL8723U_HWIMG_SUPPORT 1
+ #define RTL8723S_HWIMG_SUPPORT 0
+
+ /* For 88E */
+ #define RTL8188EE_HWIMG_SUPPORT 0
+ #define RTL8188EU_HWIMG_SUPPORT 0
+ #define RTL8188ES_HWIMG_SUPPORT 0
+
+ #elif (DEV_BUS_TYPE == RT_SDIO_INTERFACE)
+ /* For 92C */
+ #define RTL8192CE_HWIMG_SUPPORT 0
+ #define RTL8192CE_TEST_HWIMG_SUPPORT 0
+ #define RTL8192CU_HWIMG_SUPPORT 1
+ #define RTL8192CU_TEST_HWIMG_SUPPORT 0
+
+ /* For 92D */
+ #define RTL8192DE_HWIMG_SUPPORT 0
+ #define RTL8192DE_TEST_HWIMG_SUPPORT 0
+ #define RTL8192DU_HWIMG_SUPPORT 1
+ #define RTL8192DU_TEST_HWIMG_SUPPORT 0
+
+ /* For 8723 */
+ #define RTL8723E_HWIMG_SUPPORT 0
+ #define RTL8723U_HWIMG_SUPPORT 0
+ #define RTL8723S_HWIMG_SUPPORT 1
+
+ /* For 88E */
+ #define RTL8188EE_HWIMG_SUPPORT 0
+ #define RTL8188EU_HWIMG_SUPPORT 0
+ #define RTL8188ES_HWIMG_SUPPORT 0
+ #endif
+
+#endif /* __INC_HW_IMG_H */
diff --git a/drivers/staging/rtl8188eu/hal/halhwimg8188e_bb.c b/drivers/staging/rtl8188eu/hal/halhwimg8188e_bb.c
new file mode 100644
index 000000000000..5f7c6add8b51
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/halhwimg8188e_bb.c
@@ -0,0 +1,1730 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/*Image2HeaderVersion: 2.18*/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+static bool
+check_positive(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ const u32 condition1,
+ const u32 condition2,
+ const u32 condition3,
+ const u32 condition4
+)
+{
+ u8 _board_type = ((p_dm_odm->board_type & BIT(4)) >> 4) << 0 | /* _GLNA*/
+ ((p_dm_odm->board_type & BIT(3)) >> 3) << 1 | /* _GPA*/
+ ((p_dm_odm->board_type & BIT(7)) >> 7) << 2 | /* _ALNA*/
+ ((p_dm_odm->board_type & BIT(6)) >> 6) << 3 | /* _APA */
+ ((p_dm_odm->board_type & BIT(2)) >> 2) << 4; /* _BT*/
+
+ u32 cond1 = condition1, cond2 = condition2, cond3 = condition3, cond4 = condition4;
+ u32 driver1 = p_dm_odm->cut_version << 24 |
+ (p_dm_odm->support_interface & 0xF0) << 16 |
+ p_dm_odm->support_platform << 16 |
+ p_dm_odm->package_type << 12 |
+ (p_dm_odm->support_interface & 0x0F) << 8 |
+ _board_type;
+
+ u32 driver2 = (p_dm_odm->type_glna & 0xFF) << 0 |
+ (p_dm_odm->type_gpa & 0xFF) << 8 |
+ (p_dm_odm->type_alna & 0xFF) << 16 |
+ (p_dm_odm->type_apa & 0xFF) << 24;
+
+ u32 driver3 = 0;
+
+ u32 driver4 = (p_dm_odm->type_glna & 0xFF00) >> 8 |
+ (p_dm_odm->type_gpa & 0xFF00) |
+ (p_dm_odm->type_alna & 0xFF00) << 8 |
+ (p_dm_odm->type_apa & 0xFF00) << 16;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE,
+ ("===> check_positive (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n", cond1, cond2, cond3, cond4));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE,
+ ("===> check_positive (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n", driver1, driver2, driver3, driver4));
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE,
+ (" (Platform, Interface) = (0x%X, 0x%X)\n", p_dm_odm->support_platform, p_dm_odm->support_interface));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE,
+ (" (Board, Package) = (0x%X, 0x%X)\n", p_dm_odm->board_type, p_dm_odm->package_type));
+
+
+ /*============== value Defined Check ===============*/
+ /*QFN type [15:12] and cut version [27:24] need to do value check*/
+
+ if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) != (driver1 & 0x0000F000)))
+ return false;
+ if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) != (driver1 & 0x0F000000)))
+ return false;
+
+ /*=============== Bit Defined Check ================*/
+ /* We don't care [31:28] */
+
+ cond1 &= 0x00FF0FFF;
+ driver1 &= 0x00FF0FFF;
+
+ if ((cond1 & driver1) == cond1) {
+ u32 bit_mask = 0;
+
+ if ((cond1 & 0x0F) == 0) /* board_type is DONTCARE*/
+ return true;
+
+ if ((cond1 & BIT(0)) != 0) /*GLNA*/
+ bit_mask |= 0x000000FF;
+ if ((cond1 & BIT(1)) != 0) /*GPA*/
+ bit_mask |= 0x0000FF00;
+ if ((cond1 & BIT(2)) != 0) /*ALNA*/
+ bit_mask |= 0x00FF0000;
+ if ((cond1 & BIT(3)) != 0) /*APA*/
+ bit_mask |= 0xFF000000;
+
+ if (((cond2 & bit_mask) == (driver2 & bit_mask)) && ((cond4 & bit_mask) == (driver4 & bit_mask))) /* board_type of each RF path is matched*/
+ return true;
+ else
+ return false;
+ } else
+ return false;
+}
+static bool
+check_negative(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ const u32 condition1,
+ const u32 condition2
+)
+{
+ return true;
+}
+
+/******************************************************************************
+* AGC_TAB.TXT
+******************************************************************************/
+
+static u32 array_mp_8188e_agc_tab[] = {
+ 0x88000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0xF6000001,
+ 0xC78, 0xF5010001,
+ 0xC78, 0xF4020001,
+ 0xC78, 0xF3030001,
+ 0xC78, 0xF2040001,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0xF7000001,
+ 0xC78, 0xF6010001,
+ 0xC78, 0xF5020001,
+ 0xC78, 0xF4030001,
+ 0xC78, 0xF3040001,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC78, 0xF9000001,
+ 0xC78, 0xF8010001,
+ 0xC78, 0xF7020001,
+ 0xC78, 0xF6030001,
+ 0xC78, 0xF5040001,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0xFB000001,
+ 0xC78, 0xFB010001,
+ 0xC78, 0xFA020001,
+ 0xC78, 0xF9030001,
+ 0xC78, 0xF8040001,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0xFF000001,
+ 0xC78, 0xFF010001,
+ 0xC78, 0xFE020001,
+ 0xC78, 0xFD030001,
+ 0xC78, 0xFC040001,
+ 0xA0000000, 0x00000000,
+ 0xC78, 0xFB000001,
+ 0xC78, 0xFB010001,
+ 0xC78, 0xFB020001,
+ 0xC78, 0xFB030001,
+ 0xC78, 0xFB040001,
+ 0xB0000000, 0x00000000,
+ 0x88000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0xF1050001,
+ 0xC78, 0xF0060001,
+ 0xC78, 0xEF070001,
+ 0xC78, 0xEE080001,
+ 0xC78, 0xED090001,
+ 0xC78, 0xEC0A0001,
+ 0xC78, 0xEB0B0001,
+ 0xC78, 0xEA0C0001,
+ 0xC78, 0xE90D0001,
+ 0xC78, 0xE80E0001,
+ 0xC78, 0xE70F0001,
+ 0xC78, 0xE6100001,
+ 0xC78, 0xE5110001,
+ 0xC78, 0xE4120001,
+ 0xC78, 0xE3130001,
+ 0xC78, 0xE2140001,
+ 0xC78, 0xC5150001,
+ 0xC78, 0xC4160001,
+ 0xC78, 0xC3170001,
+ 0xC78, 0xC2180001,
+ 0xC78, 0x88190001,
+ 0xC78, 0x871A0001,
+ 0xC78, 0x861B0001,
+ 0xC78, 0x851C0001,
+ 0xC78, 0x841D0001,
+ 0xC78, 0x831E0001,
+ 0xC78, 0x821F0001,
+ 0xC78, 0x81200001,
+ 0xC78, 0x80210001,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0xF2050001,
+ 0xC78, 0xF1060001,
+ 0xC78, 0xF0070001,
+ 0xC78, 0xEF080001,
+ 0xC78, 0xEE090001,
+ 0xC78, 0xED0A0001,
+ 0xC78, 0xEC0B0001,
+ 0xC78, 0xEB0C0001,
+ 0xC78, 0xEA0D0001,
+ 0xC78, 0xE90E0001,
+ 0xC78, 0xE80F0001,
+ 0xC78, 0xE7100001,
+ 0xC78, 0xE6110001,
+ 0xC78, 0xE5120001,
+ 0xC78, 0xE4130001,
+ 0xC78, 0xE3140001,
+ 0xC78, 0xE2150001,
+ 0xC78, 0xE1160001,
+ 0xC78, 0x89170001,
+ 0xC78, 0x88180001,
+ 0xC78, 0x87190001,
+ 0xC78, 0x861A0001,
+ 0xC78, 0x851B0001,
+ 0xC78, 0x841C0001,
+ 0xC78, 0x831D0001,
+ 0xC78, 0x821E0001,
+ 0xC78, 0x811F0001,
+ 0xC78, 0x6B200001,
+ 0xC78, 0x6A210001,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC78, 0xF4050001,
+ 0xC78, 0xF3060001,
+ 0xC78, 0xF2070001,
+ 0xC78, 0xF1080001,
+ 0xC78, 0xF0090001,
+ 0xC78, 0xEF0A0001,
+ 0xC78, 0xEE0B0001,
+ 0xC78, 0xED0C0001,
+ 0xC78, 0xEC0D0001,
+ 0xC78, 0xEB0E0001,
+ 0xC78, 0xEA0F0001,
+ 0xC78, 0xE9100001,
+ 0xC78, 0xE8110001,
+ 0xC78, 0xE7120001,
+ 0xC78, 0xE6130001,
+ 0xC78, 0xE5140001,
+ 0xC78, 0xE4150001,
+ 0xC78, 0xE3160001,
+ 0xC78, 0xE2170001,
+ 0xC78, 0xE1180001,
+ 0xC78, 0x8A190001,
+ 0xC78, 0x891A0001,
+ 0xC78, 0x881B0001,
+ 0xC78, 0x871C0001,
+ 0xC78, 0x861D0001,
+ 0xC78, 0x851E0001,
+ 0xC78, 0x841F0001,
+ 0xC78, 0x83200001,
+ 0xC78, 0x82210001,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0xF7050001,
+ 0xC78, 0xF6060001,
+ 0xC78, 0xF5070001,
+ 0xC78, 0xF4080001,
+ 0xC78, 0xF3090001,
+ 0xC78, 0xF20A0001,
+ 0xC78, 0xF10B0001,
+ 0xC78, 0xF00C0001,
+ 0xC78, 0xEF0D0001,
+ 0xC78, 0xEE0E0001,
+ 0xC78, 0xED0F0001,
+ 0xC78, 0xEC100001,
+ 0xC78, 0xEB110001,
+ 0xC78, 0xEA120001,
+ 0xC78, 0xE9130001,
+ 0xC78, 0xE8140001,
+ 0xC78, 0xE7150001,
+ 0xC78, 0xE6160001,
+ 0xC78, 0xE5170001,
+ 0xC78, 0xE4180001,
+ 0xC78, 0xC7190001,
+ 0xC78, 0xC61A0001,
+ 0xC78, 0xC51B0001,
+ 0xC78, 0xC41C0001,
+ 0xC78, 0xC31D0001,
+ 0xC78, 0xC21E0001,
+ 0xC78, 0x871F0001,
+ 0xC78, 0x86200001,
+ 0xC78, 0x85210001,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0xFB050001,
+ 0xC78, 0xFA060001,
+ 0xC78, 0xF9070001,
+ 0xC78, 0xF8080001,
+ 0xC78, 0xF7090001,
+ 0xC78, 0xF60A0001,
+ 0xC78, 0xF50B0001,
+ 0xC78, 0xF40C0001,
+ 0xC78, 0xF30D0001,
+ 0xC78, 0xF20E0001,
+ 0xC78, 0xF10F0001,
+ 0xC78, 0xF0100001,
+ 0xC78, 0xEF110001,
+ 0xC78, 0xEE120001,
+ 0xC78, 0xED130001,
+ 0xC78, 0xEC140001,
+ 0xC78, 0xEB150001,
+ 0xC78, 0xEA160001,
+ 0xC78, 0xE9170001,
+ 0xC78, 0xE8180001,
+ 0xC78, 0xE7190001,
+ 0xC78, 0xE61A0001,
+ 0xC78, 0xC51B0001,
+ 0xC78, 0xC41C0001,
+ 0xC78, 0xC31D0001,
+ 0xC78, 0xC21E0001,
+ 0xC78, 0x881F0001,
+ 0xC78, 0x87200001,
+ 0xC78, 0x86210001,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0xFA050001,
+ 0xC78, 0xF9060001,
+ 0xC78, 0xF8070001,
+ 0xC78, 0xF7080001,
+ 0xC78, 0xF6090001,
+ 0xC78, 0xF50A0001,
+ 0xC78, 0xF40B0001,
+ 0xC78, 0xF30C0001,
+ 0xC78, 0xF20D0001,
+ 0xC78, 0xF10E0001,
+ 0xC78, 0xF00F0001,
+ 0xC78, 0xEF100001,
+ 0xC78, 0xEE110001,
+ 0xC78, 0xED120001,
+ 0xC78, 0xEC130001,
+ 0xC78, 0xEB140001,
+ 0xC78, 0xEA150001,
+ 0xC78, 0xE9160001,
+ 0xC78, 0xE8170001,
+ 0xC78, 0xE7180001,
+ 0xC78, 0xE6190001,
+ 0xC78, 0xE51A0001,
+ 0xC78, 0xE41B0001,
+ 0xC78, 0xC71C0001,
+ 0xC78, 0xC61D0001,
+ 0xC78, 0xC51E0001,
+ 0xC78, 0xC41F0001,
+ 0xC78, 0xC3200001,
+ 0xC78, 0xC2210001,
+ 0xA0000000, 0x00000000,
+ 0xC78, 0xFB050001,
+ 0xC78, 0xFA060001,
+ 0xC78, 0xF9070001,
+ 0xC78, 0xF8080001,
+ 0xC78, 0xF7090001,
+ 0xC78, 0xF60A0001,
+ 0xC78, 0xF50B0001,
+ 0xC78, 0xF40C0001,
+ 0xC78, 0xF30D0001,
+ 0xC78, 0xF20E0001,
+ 0xC78, 0xF10F0001,
+ 0xC78, 0xF0100001,
+ 0xC78, 0xEF110001,
+ 0xC78, 0xEE120001,
+ 0xC78, 0xED130001,
+ 0xC78, 0xEC140001,
+ 0xC78, 0xEB150001,
+ 0xC78, 0xEA160001,
+ 0xC78, 0xE9170001,
+ 0xC78, 0xE8180001,
+ 0xC78, 0xE7190001,
+ 0xC78, 0xE61A0001,
+ 0xC78, 0xE51B0001,
+ 0xC78, 0xE41C0001,
+ 0xC78, 0xE31D0001,
+ 0xC78, 0xE21E0001,
+ 0xC78, 0xE11F0001,
+ 0xC78, 0x8A200001,
+ 0xC78, 0x89210001,
+ 0xB0000000, 0x00000000,
+ 0x88000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0x66220001,
+ 0xC78, 0x65230001,
+ 0xC78, 0x64240001,
+ 0xC78, 0x63250001,
+ 0xC78, 0x62260001,
+ 0xC78, 0x61270001,
+ 0xC78, 0x60280001,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0x69220001,
+ 0xC78, 0x68230001,
+ 0xC78, 0x67240001,
+ 0xC78, 0x66250001,
+ 0xC78, 0x65260001,
+ 0xC78, 0x64270001,
+ 0xC78, 0x63280001,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC78, 0x6B220001,
+ 0xC78, 0x6A230001,
+ 0xC78, 0x69240001,
+ 0xC78, 0x68250001,
+ 0xC78, 0x67260001,
+ 0xC78, 0x66270001,
+ 0xC78, 0x65280001,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0x84220001,
+ 0xC78, 0x83230001,
+ 0xC78, 0x82240001,
+ 0xC78, 0x81250001,
+ 0xC78, 0x67260001,
+ 0xC78, 0x66270001,
+ 0xC78, 0x65280001,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0x85220001,
+ 0xC78, 0x84230001,
+ 0xC78, 0x83240001,
+ 0xC78, 0x82250001,
+ 0xC78, 0x6A260001,
+ 0xC78, 0x69270001,
+ 0xC78, 0x68280001,
+ 0xA0000000, 0x00000000,
+ 0xC78, 0x88220001,
+ 0xC78, 0x87230001,
+ 0xC78, 0x86240001,
+ 0xC78, 0x85250001,
+ 0xC78, 0x84260001,
+ 0xC78, 0x83270001,
+ 0xC78, 0x82280001,
+ 0xB0000000, 0x00000000,
+ 0x88000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0x4A290001,
+ 0xC78, 0x492A0001,
+ 0xC78, 0x482B0001,
+ 0xC78, 0x472C0001,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0x62290001,
+ 0xC78, 0x612A0001,
+ 0xC78, 0x462B0001,
+ 0xC78, 0x452C0001,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC78, 0x64290001,
+ 0xC78, 0x632A0001,
+ 0xC78, 0x622B0001,
+ 0xC78, 0x612C0001,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0x64290001,
+ 0xC78, 0x632A0001,
+ 0xC78, 0x622B0001,
+ 0xC78, 0x612C0001,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0x67290001,
+ 0xC78, 0x662A0001,
+ 0xC78, 0x652B0001,
+ 0xC78, 0x642C0001,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0x81290001,
+ 0xC78, 0x242A0001,
+ 0xC78, 0x232B0001,
+ 0xC78, 0x222C0001,
+ 0xA0000000, 0x00000000,
+ 0xC78, 0x6B290001,
+ 0xC78, 0x6A2A0001,
+ 0xC78, 0x692B0001,
+ 0xC78, 0x682C0001,
+ 0xB0000000, 0x00000000,
+ 0x88000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0x462D0001,
+ 0xC78, 0x452E0001,
+ 0xC78, 0x442F0001,
+ 0xC78, 0x43300001,
+ 0xC78, 0x42310001,
+ 0xC78, 0x41320001,
+ 0xC78, 0x40330001,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0x442D0001,
+ 0xC78, 0x432E0001,
+ 0xC78, 0x422F0001,
+ 0xC78, 0x41300001,
+ 0xC78, 0x40310001,
+ 0xC78, 0x40320001,
+ 0xC78, 0x40330001,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC78, 0x462D0001,
+ 0xC78, 0x452E0001,
+ 0xC78, 0x442F0001,
+ 0xC78, 0x43300001,
+ 0xC78, 0x42310001,
+ 0xC78, 0x41320001,
+ 0xC78, 0x40330001,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0x4B2D0001,
+ 0xC78, 0x4A2E0001,
+ 0xC78, 0x492F0001,
+ 0xC78, 0x48300001,
+ 0xC78, 0x47310001,
+ 0xC78, 0x46320001,
+ 0xC78, 0x45330001,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0x4A2D0001,
+ 0xC78, 0x492E0001,
+ 0xC78, 0x482F0001,
+ 0xC78, 0x47300001,
+ 0xC78, 0x46310001,
+ 0xC78, 0x45320001,
+ 0xC78, 0x44330001,
+ 0xA0000000, 0x00000000,
+ 0xC78, 0x672D0001,
+ 0xC78, 0x662E0001,
+ 0xC78, 0x652F0001,
+ 0xC78, 0x64300001,
+ 0xC78, 0x63310001,
+ 0xC78, 0x62320001,
+ 0xC78, 0x61330001,
+ 0xB0000000, 0x00000000,
+ 0x88000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0x40340001,
+ 0xC78, 0x40350001,
+ 0xC78, 0x40360001,
+ 0xC78, 0x40370001,
+ 0xC78, 0x40380001,
+ 0xC78, 0x40390001,
+ 0xC78, 0x403A0001,
+ 0xC78, 0x403B0001,
+ 0xC78, 0x403C0001,
+ 0xC78, 0x403D0001,
+ 0xC78, 0x403E0001,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0x40340001,
+ 0xC78, 0x40350001,
+ 0xC78, 0x40360001,
+ 0xC78, 0x40370001,
+ 0xC78, 0x40380001,
+ 0xC78, 0x40390001,
+ 0xC78, 0x403A0001,
+ 0xC78, 0x403B0001,
+ 0xC78, 0x403C0001,
+ 0xC78, 0x403D0001,
+ 0xC78, 0x403E0001,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC78, 0x40340001,
+ 0xC78, 0x40350001,
+ 0xC78, 0x40360001,
+ 0xC78, 0x40370001,
+ 0xC78, 0x40380001,
+ 0xC78, 0x40390001,
+ 0xC78, 0x403A0001,
+ 0xC78, 0x403B0001,
+ 0xC78, 0x403C0001,
+ 0xC78, 0x403D0001,
+ 0xC78, 0x403E0001,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0x44340001,
+ 0xC78, 0x43350001,
+ 0xC78, 0x42360001,
+ 0xC78, 0x41370001,
+ 0xC78, 0x40380001,
+ 0xC78, 0x40390001,
+ 0xC78, 0x403A0001,
+ 0xC78, 0x403B0001,
+ 0xC78, 0x403C0001,
+ 0xC78, 0x403D0001,
+ 0xC78, 0x403E0001,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0x43340001,
+ 0xC78, 0x42350001,
+ 0xC78, 0x41360001,
+ 0xC78, 0x40370001,
+ 0xC78, 0x40380001,
+ 0xC78, 0x40390001,
+ 0xC78, 0x403A0001,
+ 0xC78, 0x403B0001,
+ 0xC78, 0x403C0001,
+ 0xC78, 0x403D0001,
+ 0xC78, 0x403E0001,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0x60340001,
+ 0xC78, 0x4A350001,
+ 0xC78, 0x49360001,
+ 0xC78, 0x48370001,
+ 0xC78, 0x47380001,
+ 0xC78, 0x46390001,
+ 0xC78, 0x453A0001,
+ 0xC78, 0x443B0001,
+ 0xC78, 0x433C0001,
+ 0xC78, 0x423D0001,
+ 0xC78, 0x413E0001,
+ 0xA0000000, 0x00000000,
+ 0xC78, 0x46340001,
+ 0xC78, 0x45350001,
+ 0xC78, 0x44360001,
+ 0xC78, 0x43370001,
+ 0xC78, 0x42380001,
+ 0xC78, 0x41390001,
+ 0xC78, 0x403A0001,
+ 0xC78, 0x403B0001,
+ 0xC78, 0x403C0001,
+ 0xC78, 0x403D0001,
+ 0xC78, 0x403E0001,
+ 0xB0000000, 0x00000000,
+ 0x80000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC78, 0x403F0001,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0x403F0001,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0x403F0001,
+ 0xA0000000, 0x00000000,
+ 0xC78, 0x403F0001,
+ 0xB0000000, 0x00000000,
+ 0x88000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0xFB400001,
+ 0xC78, 0xFA410001,
+ 0xC78, 0xF9420001,
+ 0xC78, 0xF8430001,
+ 0xC78, 0xF7440001,
+ 0xC78, 0xF6450001,
+ 0xC78, 0xF5460001,
+ 0xC78, 0xF4470001,
+ 0xC78, 0xF3480001,
+ 0xC78, 0xF2490001,
+ 0xC78, 0xF14A0001,
+ 0xC78, 0xF04B0001,
+ 0xC78, 0xEF4C0001,
+ 0xC78, 0xEE4D0001,
+ 0xC78, 0xED4E0001,
+ 0xC78, 0xEC4F0001,
+ 0xC78, 0xEB500001,
+ 0xC78, 0xEA510001,
+ 0xC78, 0xE9520001,
+ 0xC78, 0xE8530001,
+ 0xC78, 0xE7540001,
+ 0xC78, 0xE6550001,
+ 0xC78, 0xE5560001,
+ 0xC78, 0xC6570001,
+ 0xC78, 0xC5580001,
+ 0xC78, 0xC4590001,
+ 0xC78, 0xC35A0001,
+ 0xC78, 0xC25B0001,
+ 0xC78, 0xC15C0001,
+ 0xC78, 0xC05D0001,
+ 0xC78, 0xA35E0001,
+ 0xC78, 0xA25F0001,
+ 0xC78, 0xA1600001,
+ 0xC78, 0x88610001,
+ 0xC78, 0x87620001,
+ 0xC78, 0x86630001,
+ 0xC78, 0x85640001,
+ 0xC78, 0x84650001,
+ 0xC78, 0x83660001,
+ 0xC78, 0x82670001,
+ 0xC78, 0x66680001,
+ 0xC78, 0x65690001,
+ 0xC78, 0x646A0001,
+ 0xC78, 0x636B0001,
+ 0xC78, 0x626C0001,
+ 0xC78, 0x616D0001,
+ 0xC78, 0x486E0001,
+ 0xC78, 0x476F0001,
+ 0xC78, 0x46700001,
+ 0xC78, 0x45710001,
+ 0xC78, 0x44720001,
+ 0xC78, 0x43730001,
+ 0xC78, 0x42740001,
+ 0xC78, 0x41750001,
+ 0xC78, 0x40760001,
+ 0xC78, 0x40770001,
+ 0xC78, 0x40780001,
+ 0xC78, 0x40790001,
+ 0xC78, 0x407A0001,
+ 0xC78, 0x407B0001,
+ 0xC78, 0x407C0001,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0xFB400001,
+ 0xC78, 0xFA410001,
+ 0xC78, 0xF9420001,
+ 0xC78, 0xF8430001,
+ 0xC78, 0xF7440001,
+ 0xC78, 0xF6450001,
+ 0xC78, 0xF5460001,
+ 0xC78, 0xF4470001,
+ 0xC78, 0xF3480001,
+ 0xC78, 0xF2490001,
+ 0xC78, 0xF14A0001,
+ 0xC78, 0xF04B0001,
+ 0xC78, 0xEF4C0001,
+ 0xC78, 0xEE4D0001,
+ 0xC78, 0xED4E0001,
+ 0xC78, 0xEC4F0001,
+ 0xC78, 0xEB500001,
+ 0xC78, 0xEA510001,
+ 0xC78, 0xE9520001,
+ 0xC78, 0xE8530001,
+ 0xC78, 0xE7540001,
+ 0xC78, 0xE6550001,
+ 0xC78, 0xE5560001,
+ 0xC78, 0xE4570001,
+ 0xC78, 0xE3580001,
+ 0xC78, 0xE2590001,
+ 0xC78, 0xC35A0001,
+ 0xC78, 0xC25B0001,
+ 0xC78, 0xC15C0001,
+ 0xC78, 0x8B5D0001,
+ 0xC78, 0x8A5E0001,
+ 0xC78, 0x895F0001,
+ 0xC78, 0x88600001,
+ 0xC78, 0x87610001,
+ 0xC78, 0x86620001,
+ 0xC78, 0x85630001,
+ 0xC78, 0x84640001,
+ 0xC78, 0x67650001,
+ 0xC78, 0x66660001,
+ 0xC78, 0x65670001,
+ 0xC78, 0x64680001,
+ 0xC78, 0x63690001,
+ 0xC78, 0x626A0001,
+ 0xC78, 0x616B0001,
+ 0xC78, 0x606C0001,
+ 0xC78, 0x466D0001,
+ 0xC78, 0x456E0001,
+ 0xC78, 0x446F0001,
+ 0xC78, 0x43700001,
+ 0xC78, 0x42710001,
+ 0xC78, 0x41720001,
+ 0xC78, 0x40730001,
+ 0xC78, 0x40740001,
+ 0xC78, 0x40750001,
+ 0xC78, 0x40760001,
+ 0xC78, 0x40770001,
+ 0xC78, 0x40780001,
+ 0xC78, 0x40790001,
+ 0xC78, 0x407A0001,
+ 0xC78, 0x407B0001,
+ 0xC78, 0x407C0001,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC78, 0xFB400001,
+ 0xC78, 0xFB410001,
+ 0xC78, 0xFB420001,
+ 0xC78, 0xFB430001,
+ 0xC78, 0xFB440001,
+ 0xC78, 0xFB450001,
+ 0xC78, 0xFA460001,
+ 0xC78, 0xF9470001,
+ 0xC78, 0xF8480001,
+ 0xC78, 0xF7490001,
+ 0xC78, 0xF64A0001,
+ 0xC78, 0xF54B0001,
+ 0xC78, 0xF44C0001,
+ 0xC78, 0xF34D0001,
+ 0xC78, 0xF24E0001,
+ 0xC78, 0xF14F0001,
+ 0xC78, 0xF0500001,
+ 0xC78, 0xEF510001,
+ 0xC78, 0xEE520001,
+ 0xC78, 0xED530001,
+ 0xC78, 0xEC540001,
+ 0xC78, 0xEB550001,
+ 0xC78, 0xEA560001,
+ 0xC78, 0xE9570001,
+ 0xC78, 0xE8580001,
+ 0xC78, 0xE7590001,
+ 0xC78, 0xE65A0001,
+ 0xC78, 0xE55B0001,
+ 0xC78, 0xC65C0001,
+ 0xC78, 0xC55D0001,
+ 0xC78, 0xC45E0001,
+ 0xC78, 0xC35F0001,
+ 0xC78, 0xC2600001,
+ 0xC78, 0xC1610001,
+ 0xC78, 0xC0620001,
+ 0xC78, 0xA3630001,
+ 0xC78, 0xA2640001,
+ 0xC78, 0xA1650001,
+ 0xC78, 0x88660001,
+ 0xC78, 0x87670001,
+ 0xC78, 0x86680001,
+ 0xC78, 0x85690001,
+ 0xC78, 0x846A0001,
+ 0xC78, 0x836B0001,
+ 0xC78, 0x826C0001,
+ 0xC78, 0x666D0001,
+ 0xC78, 0x656E0001,
+ 0xC78, 0x646F0001,
+ 0xC78, 0x63700001,
+ 0xC78, 0x62710001,
+ 0xC78, 0x61720001,
+ 0xC78, 0x48730001,
+ 0xC78, 0x47740001,
+ 0xC78, 0x46750001,
+ 0xC78, 0x45760001,
+ 0xC78, 0x44770001,
+ 0xC78, 0x43780001,
+ 0xC78, 0x42790001,
+ 0xC78, 0x417A0001,
+ 0xC78, 0x407B0001,
+ 0xC78, 0x407C0001,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0xFB400001,
+ 0xC78, 0xFB410001,
+ 0xC78, 0xFB420001,
+ 0xC78, 0xFB430001,
+ 0xC78, 0xFB440001,
+ 0xC78, 0xFB450001,
+ 0xC78, 0xFB460001,
+ 0xC78, 0xFB470001,
+ 0xC78, 0xFB480001,
+ 0xC78, 0xFA490001,
+ 0xC78, 0xF94A0001,
+ 0xC78, 0xF84B0001,
+ 0xC78, 0xF74C0001,
+ 0xC78, 0xF64D0001,
+ 0xC78, 0xF54E0001,
+ 0xC78, 0xF44F0001,
+ 0xC78, 0xF3500001,
+ 0xC78, 0xF2510001,
+ 0xC78, 0xF1520001,
+ 0xC78, 0xF0530001,
+ 0xC78, 0xEF540001,
+ 0xC78, 0xEE550001,
+ 0xC78, 0xED560001,
+ 0xC78, 0xEC570001,
+ 0xC78, 0xEB580001,
+ 0xC78, 0xEA590001,
+ 0xC78, 0xE95A0001,
+ 0xC78, 0xE85B0001,
+ 0xC78, 0xE75C0001,
+ 0xC78, 0xE65D0001,
+ 0xC78, 0xE55E0001,
+ 0xC78, 0xE45F0001,
+ 0xC78, 0xE3600001,
+ 0xC78, 0xE2610001,
+ 0xC78, 0xC3620001,
+ 0xC78, 0xC2630001,
+ 0xC78, 0xC1640001,
+ 0xC78, 0x8B650001,
+ 0xC78, 0x8A660001,
+ 0xC78, 0x89670001,
+ 0xC78, 0x88680001,
+ 0xC78, 0x87690001,
+ 0xC78, 0x866A0001,
+ 0xC78, 0x856B0001,
+ 0xC78, 0x846C0001,
+ 0xC78, 0x676D0001,
+ 0xC78, 0x666E0001,
+ 0xC78, 0x656F0001,
+ 0xC78, 0x64700001,
+ 0xC78, 0x63710001,
+ 0xC78, 0x62720001,
+ 0xC78, 0x61730001,
+ 0xC78, 0x60740001,
+ 0xC78, 0x46750001,
+ 0xC78, 0x45760001,
+ 0xC78, 0x44770001,
+ 0xC78, 0x43780001,
+ 0xC78, 0x42790001,
+ 0xC78, 0x417A0001,
+ 0xC78, 0x407B0001,
+ 0xC78, 0x407C0001,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0xFB400001,
+ 0xC78, 0xFB410001,
+ 0xC78, 0xFB420001,
+ 0xC78, 0xFB430001,
+ 0xC78, 0xFB440001,
+ 0xC78, 0xFB450001,
+ 0xC78, 0xFB460001,
+ 0xC78, 0xFB470001,
+ 0xC78, 0xFB480001,
+ 0xC78, 0xFA490001,
+ 0xC78, 0xF94A0001,
+ 0xC78, 0xF84B0001,
+ 0xC78, 0xF74C0001,
+ 0xC78, 0xF64D0001,
+ 0xC78, 0xF54E0001,
+ 0xC78, 0xF44F0001,
+ 0xC78, 0xF3500001,
+ 0xC78, 0xF2510001,
+ 0xC78, 0xF1520001,
+ 0xC78, 0xF0530001,
+ 0xC78, 0xEF540001,
+ 0xC78, 0xEE550001,
+ 0xC78, 0xED560001,
+ 0xC78, 0xEC570001,
+ 0xC78, 0xEB580001,
+ 0xC78, 0xEA590001,
+ 0xC78, 0xE95A0001,
+ 0xC78, 0xE85B0001,
+ 0xC78, 0xE75C0001,
+ 0xC78, 0xE65D0001,
+ 0xC78, 0xE55E0001,
+ 0xC78, 0xE45F0001,
+ 0xC78, 0xE3600001,
+ 0xC78, 0xE2610001,
+ 0xC78, 0xC3620001,
+ 0xC78, 0xC2630001,
+ 0xC78, 0xC1640001,
+ 0xC78, 0x8B650001,
+ 0xC78, 0x8A660001,
+ 0xC78, 0x89670001,
+ 0xC78, 0x88680001,
+ 0xC78, 0x87690001,
+ 0xC78, 0x866A0001,
+ 0xC78, 0x856B0001,
+ 0xC78, 0x846C0001,
+ 0xC78, 0x676D0001,
+ 0xC78, 0x666E0001,
+ 0xC78, 0x656F0001,
+ 0xC78, 0x64700001,
+ 0xC78, 0x63710001,
+ 0xC78, 0x62720001,
+ 0xC78, 0x61730001,
+ 0xC78, 0x60740001,
+ 0xC78, 0x46750001,
+ 0xC78, 0x45760001,
+ 0xC78, 0x44770001,
+ 0xC78, 0x43780001,
+ 0xC78, 0x42790001,
+ 0xC78, 0x417A0001,
+ 0xC78, 0x407B0001,
+ 0xC78, 0x407C0001,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0xC78, 0xFF400001,
+ 0xC78, 0xFF410001,
+ 0xC78, 0xFE420001,
+ 0xC78, 0xFD430001,
+ 0xC78, 0xFC440001,
+ 0xC78, 0xFB450001,
+ 0xC78, 0xFA460001,
+ 0xC78, 0xF9470001,
+ 0xC78, 0xF8480001,
+ 0xC78, 0xF7490001,
+ 0xC78, 0xF64A0001,
+ 0xC78, 0xF54B0001,
+ 0xC78, 0xF44C0001,
+ 0xC78, 0xF34D0001,
+ 0xC78, 0xF24E0001,
+ 0xC78, 0xF14F0001,
+ 0xC78, 0xF0500001,
+ 0xC78, 0xEF510001,
+ 0xC78, 0xEE520001,
+ 0xC78, 0xED530001,
+ 0xC78, 0xEC540001,
+ 0xC78, 0xEB550001,
+ 0xC78, 0xEA560001,
+ 0xC78, 0xE9570001,
+ 0xC78, 0xE8580001,
+ 0xC78, 0xE7590001,
+ 0xC78, 0xE65A0001,
+ 0xC78, 0xE55B0001,
+ 0xC78, 0xE45C0001,
+ 0xC78, 0xA85D0001,
+ 0xC78, 0xA75E0001,
+ 0xC78, 0xA65F0001,
+ 0xC78, 0xA5600001,
+ 0xC78, 0xA4610001,
+ 0xC78, 0xA3620001,
+ 0xC78, 0xA2630001,
+ 0xC78, 0xA1640001,
+ 0xC78, 0x28650001,
+ 0xC78, 0x27660001,
+ 0xC78, 0x26670001,
+ 0xC78, 0x07680001,
+ 0xC78, 0x06690001,
+ 0xC78, 0x056A0001,
+ 0xC78, 0x046B0001,
+ 0xC78, 0x036C0001,
+ 0xC78, 0x026D0001,
+ 0xC78, 0x016E0001,
+ 0xC78, 0x646F0001,
+ 0xC78, 0x63700001,
+ 0xC78, 0x62710001,
+ 0xC78, 0x61720001,
+ 0xC78, 0x47730001,
+ 0xC78, 0x46740001,
+ 0xC78, 0x45750001,
+ 0xC78, 0x44760001,
+ 0xC78, 0x43770001,
+ 0xC78, 0x42780001,
+ 0xC78, 0x41790001,
+ 0xC78, 0x407A0001,
+ 0xC78, 0x407B0001,
+ 0xC78, 0x407C0001,
+ 0xA0000000, 0x00000000,
+ 0xC78, 0xFB400001,
+ 0xC78, 0xFB410001,
+ 0xC78, 0xFB420001,
+ 0xC78, 0xFB430001,
+ 0xC78, 0xFB440001,
+ 0xC78, 0xFB450001,
+ 0xC78, 0xFB460001,
+ 0xC78, 0xFB470001,
+ 0xC78, 0xFB480001,
+ 0xC78, 0xFA490001,
+ 0xC78, 0xF94A0001,
+ 0xC78, 0xF84B0001,
+ 0xC78, 0xF74C0001,
+ 0xC78, 0xF64D0001,
+ 0xC78, 0xF54E0001,
+ 0xC78, 0xF44F0001,
+ 0xC78, 0xF3500001,
+ 0xC78, 0xF2510001,
+ 0xC78, 0xF1520001,
+ 0xC78, 0xF0530001,
+ 0xC78, 0xEF540001,
+ 0xC78, 0xEE550001,
+ 0xC78, 0xED560001,
+ 0xC78, 0xEC570001,
+ 0xC78, 0xEB580001,
+ 0xC78, 0xEA590001,
+ 0xC78, 0xE95A0001,
+ 0xC78, 0xE85B0001,
+ 0xC78, 0xE75C0001,
+ 0xC78, 0xE65D0001,
+ 0xC78, 0xE55E0001,
+ 0xC78, 0xE45F0001,
+ 0xC78, 0xE3600001,
+ 0xC78, 0xE2610001,
+ 0xC78, 0xC3620001,
+ 0xC78, 0xC2630001,
+ 0xC78, 0xC1640001,
+ 0xC78, 0x8B650001,
+ 0xC78, 0x8A660001,
+ 0xC78, 0x89670001,
+ 0xC78, 0x88680001,
+ 0xC78, 0x87690001,
+ 0xC78, 0x866A0001,
+ 0xC78, 0x856B0001,
+ 0xC78, 0x846C0001,
+ 0xC78, 0x676D0001,
+ 0xC78, 0x666E0001,
+ 0xC78, 0x656F0001,
+ 0xC78, 0x64700001,
+ 0xC78, 0x63710001,
+ 0xC78, 0x62720001,
+ 0xC78, 0x61730001,
+ 0xC78, 0x60740001,
+ 0xC78, 0x46750001,
+ 0xC78, 0x45760001,
+ 0xC78, 0x44770001,
+ 0xC78, 0x43780001,
+ 0xC78, 0x42790001,
+ 0xC78, 0x417A0001,
+ 0xC78, 0x407B0001,
+ 0xC78, 0x407C0001,
+ 0xB0000000, 0x00000000,
+ 0x80000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC78, 0x407D0001,
+ 0xC78, 0x407E0001,
+ 0xC78, 0x407F0001,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0x407D0001,
+ 0xC78, 0x407E0001,
+ 0xC78, 0x407F0001,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC78, 0x407D0001,
+ 0xC78, 0x407E0001,
+ 0xC78, 0x407F0001,
+ 0xA0000000, 0x00000000,
+ 0xC78, 0x407D0001,
+ 0xC78, 0x407E0001,
+ 0xC78, 0x407F0001,
+ 0xB0000000, 0x00000000,
+ 0xC50, 0x69553422,
+ 0xC50, 0x69553420,
+
+};
+
+void
+odm_read_and_config_mp_8188e_agc_tab(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 i = 0;
+ u8 c_cond;
+ bool is_matched = true, is_skipped = false;
+ u32 array_len = sizeof(array_mp_8188e_agc_tab) / sizeof(u32);
+ u32 *array = array_mp_8188e_agc_tab;
+
+ u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> odm_read_and_config_mp_8188e_agc_tab\n"));
+
+ while ((i + 1) < array_len) {
+ v1 = array[i];
+ v2 = array[i + 1];
+
+ if (v1 & (BIT(31) | BIT30)) {/*positive & negative condition*/
+ if (v1 & BIT(31)) {/* positive condition*/
+ c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
+ if (c_cond == COND_ENDIF) {/*end*/
+ is_matched = true;
+ is_skipped = false;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ENDIF\n"));
+ } else if (c_cond == COND_ELSE) { /*else*/
+ is_matched = is_skipped ? false : true;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ELSE\n"));
+ } else {/*if , else if*/
+ pre_v1 = v1;
+ pre_v2 = v2;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("IF or ELSE IF\n"));
+ }
+ } else if (v1 & BIT(30)) { /*negative condition*/
+ if (is_skipped == false) {
+ if (check_positive(p_dm_odm, pre_v1, pre_v2, v1, v2)) {
+ is_matched = true;
+ is_skipped = true;
+ } else {
+ is_matched = false;
+ is_skipped = false;
+ }
+ } else
+ is_matched = false;
+ }
+ } else {
+ if (is_matched)
+ odm_config_bb_agc_8188e(p_dm_odm, v1, MASKDWORD, v2);
+ }
+ i = i + 2;
+ }
+}
+
+u32
+odm_get_version_mp_8188e_agc_tab(void)
+{
+ return 70;
+}
+
+/******************************************************************************
+* PHY_REG.TXT
+******************************************************************************/
+
+static u32 array_mp_8188e_phy_reg[] = {
+ 0x800, 0x80040000,
+ 0x804, 0x00000003,
+ 0x808, 0x0000FC00,
+ 0x80C, 0x0000000A,
+ 0x810, 0x10001331,
+ 0x814, 0x020C3D10,
+ 0x818, 0x02200385,
+ 0x81C, 0x00000000,
+ 0x820, 0x01000100,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0x824, 0x00390204,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0x824, 0x00390204,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x824, 0x00390204,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x824, 0x00390204,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x824, 0x00390204,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x824, 0x00390204,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x824, 0x00390004,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0x824, 0x00390204,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x824, 0x00390204,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x824, 0x00390204,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x824, 0x00390004,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x824, 0x00390204,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0x824, 0x00390004,
+ 0xA0000000, 0x00000000,
+ 0x824, 0x00390204,
+ 0xB0000000, 0x00000000,
+ 0x828, 0x00000000,
+ 0x82C, 0x00000000,
+ 0x830, 0x00000000,
+ 0x834, 0x00000000,
+ 0x838, 0x00000000,
+ 0x83C, 0x00000000,
+ 0x840, 0x00010000,
+ 0x844, 0x00000000,
+ 0x848, 0x00000000,
+ 0x84C, 0x00000000,
+ 0x850, 0x00000000,
+ 0x854, 0x00000000,
+ 0x858, 0x569A11A9,
+ 0x85C, 0x01000014,
+ 0x860, 0x66F60110,
+ 0x864, 0x061F0649,
+ 0x868, 0x00000000,
+ 0x86C, 0x27272700,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0x870, 0x07000300,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0x870, 0x07000300,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x870, 0x07000300,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x870, 0x07000300,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x870, 0x07000300,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x870, 0x07000300,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x870, 0x07000300,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0x870, 0x07000300,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x870, 0x07000300,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x870, 0x07000300,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x870, 0x07000300,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x870, 0x07000760,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0x870, 0x07000760,
+ 0xA0000000, 0x00000000,
+ 0x870, 0x07000760,
+ 0xB0000000, 0x00000000,
+ 0x874, 0x25004000,
+ 0x878, 0x00000808,
+ 0x87C, 0x00000000,
+ 0x880, 0xB0000C1C,
+ 0x884, 0x00000001,
+ 0x888, 0x00000000,
+ 0x88C, 0xCCC000C0,
+ 0x890, 0x00000800,
+ 0x894, 0xFFFFFFFE,
+ 0x898, 0x40302010,
+ 0x89C, 0x00706050,
+ 0x900, 0x00000000,
+ 0x904, 0x00000023,
+ 0x908, 0x00000000,
+ 0x90C, 0x81121111,
+ 0x910, 0x00000002,
+ 0x914, 0x00000201,
+ 0xA00, 0x00D047C8,
+ 0xA04, 0x80FF800C,
+ 0xA08, 0x8C838300,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0xA0C, 0x2E7F120F,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0xA0C, 0x2E7F120F,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xA0C, 0x2E7F120F,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xA0C, 0x2E7F120F,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xA0C, 0x2E7F120F,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xA0C, 0x2E7F120F,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xA0C, 0x2D38120F,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0xA0C, 0x2E7F120F,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xA0C, 0x2E7F120F,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xA0C, 0x2E7F120F,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xA0C, 0x2D38120F,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0xA0C, 0x2E7F120F,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0xA0C, 0x2E34120F,
+ 0xA0000000, 0x00000000,
+ 0xA0C, 0x2E7F120F,
+ 0xB0000000, 0x00000000,
+ 0xA10, 0x9500BB7E,
+ 0xA14, 0x1114D028,
+ 0xA18, 0x00881117,
+ 0xA1C, 0x89140F00,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0xA20, 0x13130000,
+ 0xA24, 0x060A0D10,
+ 0xA28, 0x00000103,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0xA20, 0x13130000,
+ 0xA24, 0x060A0D10,
+ 0xA28, 0x00000103,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xA20, 0x13130000,
+ 0xA24, 0x060A0D10,
+ 0xA28, 0x00000103,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xA20, 0x1A1B0000,
+ 0xA24, 0x090E1317,
+ 0xA28, 0x00000204,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xA20, 0x1A1B0000,
+ 0xA24, 0x090E1317,
+ 0xA28, 0x00000204,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xA20, 0x1A1B0000,
+ 0xA24, 0x090E1317,
+ 0xA28, 0x00000204,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xA20, 0x13130000,
+ 0xA24, 0x060A0D10,
+ 0xA28, 0x00000103,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0xA20, 0x13130000,
+ 0xA24, 0x060A0D10,
+ 0xA28, 0x00000103,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xA20, 0x1A1B0000,
+ 0xA24, 0x090E1317,
+ 0xA28, 0x00000204,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xA20, 0x1A1B0000,
+ 0xA24, 0x090E1317,
+ 0xA28, 0x00000204,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xA20, 0x1A1B0000,
+ 0xA24, 0x090E1317,
+ 0xA28, 0x00000204,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0xA20, 0x1A1B0000,
+ 0xA24, 0x090E1317,
+ 0xA28, 0x00000204,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0xA20, 0x1A1B0000,
+ 0xA24, 0x090E1317,
+ 0xA28, 0x00000204,
+ 0xA0000000, 0x00000000,
+ 0xA20, 0x1A1B0000,
+ 0xA24, 0x090E1317,
+ 0xA28, 0x00000204,
+ 0xB0000000, 0x00000000,
+ 0xA2C, 0x00D30000,
+ 0xA70, 0x101FBF00,
+ 0xA74, 0x00000007,
+ 0xA78, 0x00000900,
+ 0xA7C, 0x225B0606,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0xA80, 0x218075B1,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0xA80, 0x218075B1,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xA80, 0x218075B1,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xA80, 0x218075B1,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xA80, 0x218075B1,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xA80, 0x218075B1,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xA80, 0x21807530,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0xA80, 0x218075B1,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xA80, 0x218075B1,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xA80, 0x218075B1,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xA80, 0x21807530,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0xA80, 0x218075B1,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0xA80, 0x21807531,
+ 0xA0000000, 0x00000000,
+ 0xA80, 0x218075B1,
+ 0xB0000000, 0x00000000,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0xB2C, 0x00000000,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0xB2C, 0x00000000,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xB2C, 0x00000000,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xB2C, 0x00000000,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xB2C, 0x00000000,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xB2C, 0x00000000,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xB2C, 0x00000000,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0xB2C, 0x00000000,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xB2C, 0x00000000,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xB2C, 0x00000000,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xB2C, 0x00000000,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0xB2C, 0x80000000,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0xB2C, 0x80000000,
+ 0xA0000000, 0x00000000,
+ 0xB2C, 0x80000000,
+ 0xB0000000, 0x00000000,
+ 0xC00, 0x48071D40,
+ 0xC04, 0x03A05611,
+ 0xC08, 0x000000E4,
+ 0xC0C, 0x6C6C6C6C,
+ 0xC10, 0x08800000,
+ 0xC14, 0x40000100,
+ 0xC18, 0x08800000,
+ 0xC1C, 0x40000100,
+ 0xC20, 0x00000000,
+ 0xC24, 0x00000000,
+ 0xC28, 0x00000000,
+ 0xC2C, 0x00000000,
+ 0xC30, 0x69E9AC47,
+ 0xC34, 0x469652AF,
+ 0xC38, 0x49795994,
+ 0xC3C, 0x0A97971C,
+ 0xC40, 0x1F7C403F,
+ 0xC44, 0x000100B7,
+ 0xC48, 0xEC020107,
+ 0xC4C, 0x007F037F,
+ 0xC50, 0x69553420,
+ 0xC54, 0x43BC0094,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0xC58, 0x00013159,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0xC58, 0x00013159,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xC58, 0x00013959,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC58, 0x00013159,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC58, 0x00013159,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC58, 0x00013959,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xC58, 0x00013169,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0xC58, 0x00013169,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC58, 0x00013169,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC58, 0x00013169,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC58, 0x00013169,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0xC58, 0x00013159,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0xC58, 0x00013159,
+ 0xA0000000, 0x00000000,
+ 0xC58, 0x00013169,
+ 0xB0000000, 0x00000000,
+ 0xC5C, 0x00250492,
+ 0xC60, 0x00000000,
+ 0xC64, 0x7112848B,
+ 0xC68, 0x47C00BFF,
+ 0xC6C, 0x00000036,
+ 0xC70, 0x2C7F000D,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0xC74, 0x028610DB,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0xC74, 0x028610DB,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xC74, 0x028610DB,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC74, 0x028610DB,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC74, 0x028610DB,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC74, 0x028610DB,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xC74, 0x020610DB,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0xC74, 0x020610DB,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC74, 0x020610DB,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC74, 0x020610DB,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC74, 0x020610DB,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0xC74, 0x028610DB,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0xC74, 0x028610DB,
+ 0xA0000000, 0x00000000,
+ 0xC74, 0x020610DB,
+ 0xB0000000, 0x00000000,
+ 0xC78, 0x0000001F,
+ 0xC7C, 0x00B91612,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0xC80, 0x2D4000B5,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0xC80, 0x2D4000B5,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xC80, 0x2D4000B5,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC80, 0x390000E4,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC80, 0x390000E4,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC80, 0x390000E4,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xC80, 0x2D4000B5,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0xC80, 0x2D4000B5,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xC80, 0x390000E4,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xC80, 0x390000E4,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xC80, 0x390000E4,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0xC80, 0x390000E4,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0xC80, 0x390000E4,
+ 0xA0000000, 0x00000000,
+ 0xC80, 0x390000E4,
+ 0xB0000000, 0x00000000,
+ 0xC84, 0x21F60000,
+ 0xC88, 0x40000100,
+ 0xC8C, 0x20200000,
+ 0xC90, 0x00091521,
+ 0xC94, 0x00000000,
+ 0xC98, 0x00121820,
+ 0xC9C, 0x00007F7F,
+ 0xCA0, 0x00000000,
+ 0xCA4, 0x000300A0,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0xCA8, 0xFFFF0000,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0xCA8, 0xFFFF0000,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xCA8, 0xFFFF0000,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xCA8, 0xFFFF0000,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xCA8, 0xFFFF0000,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xCA8, 0xFFFF0000,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xCA8, 0x00000000,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0xCA8, 0x00000000,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xCA8, 0x00000000,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xCA8, 0x00000000,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xCA8, 0x00000000,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0xCA8, 0xFFFF0000,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0xCA8, 0xFFFF0000,
+ 0xA0000000, 0x00000000,
+ 0xCA8, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0xCAC, 0x00000000,
+ 0xCB0, 0x00000000,
+ 0xCB4, 0x00000000,
+ 0xCB8, 0x00000000,
+ 0xCBC, 0x28000000,
+ 0xCC0, 0x00000000,
+ 0xCC4, 0x00000000,
+ 0xCC8, 0x00000000,
+ 0xCCC, 0x00000000,
+ 0xCD0, 0x00000000,
+ 0xCD4, 0x00000000,
+ 0xCD8, 0x64B22427,
+ 0xCDC, 0x00766932,
+ 0xCE0, 0x00222222,
+ 0xCE4, 0x00000000,
+ 0xCE8, 0x37644302,
+ 0xCEC, 0x2F97D40C,
+ 0xD00, 0x00000740,
+ 0xD04, 0x00020401,
+ 0xD08, 0x0000907F,
+ 0xD0C, 0x20010201,
+ 0xD10, 0xA0633333,
+ 0xD14, 0x3333BC43,
+ 0xD18, 0x7A8F5B6F,
+ 0xD2C, 0xCC979975,
+ 0xD30, 0x00000000,
+ 0xD34, 0x80608000,
+ 0xD38, 0x00000000,
+ 0xD3C, 0x00127353,
+ 0xD40, 0x00000000,
+ 0xD44, 0x00000000,
+ 0xD48, 0x00000000,
+ 0xD4C, 0x00000000,
+ 0xD50, 0x6437140A,
+ 0xD54, 0x00000000,
+ 0xD58, 0x00000282,
+ 0xD5C, 0x30032064,
+ 0xD60, 0x4653DE68,
+ 0xD64, 0x04518A3C,
+ 0xD68, 0x00002101,
+ 0xD6C, 0x2A201C16,
+ 0xD70, 0x1812362E,
+ 0xD74, 0x322C2220,
+ 0xD78, 0x000E3C24,
+ 0xE00, 0x2D2D2D2D,
+ 0xE04, 0x2D2D2D2D,
+ 0xE08, 0x0390272D,
+ 0xE10, 0x2D2D2D2D,
+ 0xE14, 0x2D2D2D2D,
+ 0xE18, 0x2D2D2D2D,
+ 0xE1C, 0x2D2D2D2D,
+ 0xE28, 0x00000000,
+ 0xE30, 0x1000DC1F,
+ 0xE34, 0x10008C1F,
+ 0xE38, 0x02140102,
+ 0xE3C, 0x681604C2,
+ 0xE40, 0x01007C00,
+ 0xE44, 0x01004800,
+ 0xE48, 0xFB000000,
+ 0xE4C, 0x000028D1,
+ 0xE50, 0x1000DC1F,
+ 0xE54, 0x10008C1F,
+ 0xE58, 0x02140102,
+ 0xE5C, 0x28160D05,
+ 0xE60, 0x00000048,
+ 0xE68, 0x001B25A4,
+ 0xE6C, 0x00C00014,
+ 0xE70, 0x00C00014,
+ 0xE74, 0x01000014,
+ 0xE78, 0x01000014,
+ 0xE7C, 0x01000014,
+ 0xE80, 0x01000014,
+ 0xE84, 0x00C00014,
+ 0xE88, 0x01000014,
+ 0xE8C, 0x00C00014,
+ 0xED0, 0x00C00014,
+ 0xED4, 0x00C00014,
+ 0xED8, 0x00C00014,
+ 0xEDC, 0x00000014,
+ 0xEE0, 0x00000014,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0xEE8, 0x32555448,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0xEE8, 0x32555448,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xEE8, 0x32555448,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xEE8, 0x32555448,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xEE8, 0x32555448,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xEE8, 0x32555448,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0xEE8, 0x32555448,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0xEE8, 0x32555448,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0xEE8, 0x32555448,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0xEE8, 0x32555448,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0xEE8, 0x32555448,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0xEE8, 0x21555448,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0xEE8, 0x21555448,
+ 0xA0000000, 0x00000000,
+ 0xEE8, 0x21555448,
+ 0xB0000000, 0x00000000,
+ 0xEEC, 0x01C00014,
+ 0xF14, 0x00000003,
+ 0xF4C, 0x00000000,
+ 0xF00, 0x00000300,
+
+};
+
+void
+odm_read_and_config_mp_8188e_phy_reg(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 i = 0;
+ u8 c_cond;
+ bool is_matched = true, is_skipped = false;
+ u32 array_len = sizeof(array_mp_8188e_phy_reg) / sizeof(u32);
+ u32 *array = array_mp_8188e_phy_reg;
+
+ u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> odm_read_and_config_mp_8188e_phy_reg\n"));
+
+ while ((i + 1) < array_len) {
+ v1 = array[i];
+ v2 = array[i + 1];
+
+ if (v1 & (BIT(31) | BIT30)) {/*positive & negative condition*/
+ if (v1 & BIT(31)) {/* positive condition*/
+ c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
+ if (c_cond == COND_ENDIF) {/*end*/
+ is_matched = true;
+ is_skipped = false;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ENDIF\n"));
+ } else if (c_cond == COND_ELSE) { /*else*/
+ is_matched = is_skipped ? false : true;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ELSE\n"));
+ } else {/*if , else if*/
+ pre_v1 = v1;
+ pre_v2 = v2;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("IF or ELSE IF\n"));
+ }
+ } else if (v1 & BIT(30)) { /*negative condition*/
+ if (is_skipped == false) {
+ if (check_positive(p_dm_odm, pre_v1, pre_v2, v1, v2)) {
+ is_matched = true;
+ is_skipped = true;
+ } else {
+ is_matched = false;
+ is_skipped = false;
+ }
+ } else
+ is_matched = false;
+ }
+ } else {
+ if (is_matched)
+ odm_config_bb_phy_8188e(p_dm_odm, v1, MASKDWORD, v2);
+ }
+ i = i + 2;
+ }
+}
+
+u32
+odm_get_version_mp_8188e_phy_reg(void)
+{
+ return 70;
+}
+
+/******************************************************************************
+* PHY_REG_PG.TXT
+******************************************************************************/
+
+static u32 array_mp_8188e_phy_reg_pg[] = {
+ 0, 0, 0, 0x00000e08, 0x0000ff00, 0x00003800,
+ 0, 0, 0, 0x0000086c, 0xffffff00, 0x32343600,
+ 0, 0, 0, 0x00000e00, 0xffffffff, 0x40424446,
+ 0, 0, 0, 0x00000e04, 0xffffffff, 0x28323638,
+ 0, 0, 0, 0x00000e10, 0xffffffff, 0x38404244,
+ 0, 0, 0, 0x00000e14, 0xffffffff, 0x26303436
+};
+
+void
+odm_read_and_config_mp_8188e_phy_reg_pg(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 i = 0;
+ u32 array_len = sizeof(array_mp_8188e_phy_reg_pg) / sizeof(u32);
+ u32 *array = array_mp_8188e_phy_reg_pg;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> odm_read_and_config_mp_8188e_phy_reg_pg\n"));
+
+ p_dm_odm->phy_reg_pg_version = 1;
+ p_dm_odm->phy_reg_pg_value_type = PHY_REG_PG_EXACT_VALUE;
+
+ for (i = 0; i < array_len; i += 6) {
+ u32 v1 = array[i];
+ u32 v2 = array[i + 1];
+ u32 v3 = array[i + 2];
+ u32 v4 = array[i + 3];
+ u32 v5 = array[i + 4];
+ u32 v6 = array[i + 5];
+
+ odm_config_bb_phy_reg_pg_8188e(p_dm_odm, v1, v2, v3, v4, v5, v6);
+ }
+}
diff --git a/drivers/staging/rtl8188eu/hal/halhwimg8188e_bb.h b/drivers/staging/rtl8188eu/hal/halhwimg8188e_bb.h
new file mode 100644
index 000000000000..a0ad19bb56ed
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/halhwimg8188e_bb.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/*Image2HeaderVersion: 2.18*/
+#if (RTL8188E_SUPPORT == 1)
+#ifndef __INC_MP_BB_HW_IMG_8188E_H
+#define __INC_MP_BB_HW_IMG_8188E_H
+
+
+/******************************************************************************
+* AGC_TAB.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_agc_tab(/* TC: Test Chip, MP: MP Chip*/
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+u32 odm_get_version_mp_8188e_agc_tab(void);
+
+/******************************************************************************
+* PHY_REG.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_phy_reg(/* TC: Test Chip, MP: MP Chip*/
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+u32 odm_get_version_mp_8188e_phy_reg(void);
+
+/******************************************************************************
+* PHY_REG_PG.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_phy_reg_pg(/* TC: Test Chip, MP: MP Chip*/
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+u32 odm_get_version_mp_8188e_phy_reg_pg(void);
+
+#endif
+#endif /* end of HWIMG_SUPPORT*/
diff --git a/drivers/staging/rtl8188eu/hal/halhwimg8188e_mac.c b/drivers/staging/rtl8188eu/hal/halhwimg8188e_mac.c
new file mode 100644
index 000000000000..e9d3837c6233
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/halhwimg8188e_mac.c
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/*Image2HeaderVersion: 2.18*/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+#if (RTL8188E_SUPPORT == 1)
+static bool
+check_positive(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ const u32 condition1,
+ const u32 condition2,
+ const u32 condition3,
+ const u32 condition4
+)
+{
+ u8 _board_type = ((p_dm_odm->board_type & BIT(4)) >> 4) << 0 | /* _GLNA*/
+ ((p_dm_odm->board_type & BIT(3)) >> 3) << 1 | /* _GPA*/
+ ((p_dm_odm->board_type & BIT(7)) >> 7) << 2 | /* _ALNA*/
+ ((p_dm_odm->board_type & BIT(6)) >> 6) << 3 | /* _APA */
+ ((p_dm_odm->board_type & BIT(2)) >> 2) << 4; /* _BT*/
+
+ u32 cond1 = condition1, cond2 = condition2, cond3 = condition3, cond4 = condition4;
+ u32 driver1 = p_dm_odm->cut_version << 24 |
+ (p_dm_odm->support_interface & 0xF0) << 16 |
+ p_dm_odm->support_platform << 16 |
+ p_dm_odm->package_type << 12 |
+ (p_dm_odm->support_interface & 0x0F) << 8 |
+ _board_type;
+
+ u32 driver2 = (p_dm_odm->type_glna & 0xFF) << 0 |
+ (p_dm_odm->type_gpa & 0xFF) << 8 |
+ (p_dm_odm->type_alna & 0xFF) << 16 |
+ (p_dm_odm->type_apa & 0xFF) << 24;
+
+ u32 driver3 = 0;
+
+ u32 driver4 = (p_dm_odm->type_glna & 0xFF00) >> 8 |
+ (p_dm_odm->type_gpa & 0xFF00) |
+ (p_dm_odm->type_alna & 0xFF00) << 8 |
+ (p_dm_odm->type_apa & 0xFF00) << 16;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE,
+ ("===> check_positive (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n", cond1, cond2, cond3, cond4));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE,
+ ("===> check_positive (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n", driver1, driver2, driver3, driver4));
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE,
+ (" (Platform, Interface) = (0x%X, 0x%X)\n", p_dm_odm->support_platform, p_dm_odm->support_interface));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE,
+ (" (Board, Package) = (0x%X, 0x%X)\n", p_dm_odm->board_type, p_dm_odm->package_type));
+
+
+ /*============== value Defined Check ===============*/
+ /*QFN type [15:12] and cut version [27:24] need to do value check*/
+
+ if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) != (driver1 & 0x0000F000)))
+ return false;
+ if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) != (driver1 & 0x0F000000)))
+ return false;
+
+ /*=============== Bit Defined Check ================*/
+ /* We don't care [31:28] */
+
+ cond1 &= 0x00FF0FFF;
+ driver1 &= 0x00FF0FFF;
+
+ if ((cond1 & driver1) == cond1) {
+ u32 bit_mask = 0;
+
+ if ((cond1 & 0x0F) == 0) /* board_type is DONTCARE*/
+ return true;
+
+ if ((cond1 & BIT(0)) != 0) /*GLNA*/
+ bit_mask |= 0x000000FF;
+ if ((cond1 & BIT(1)) != 0) /*GPA*/
+ bit_mask |= 0x0000FF00;
+ if ((cond1 & BIT(2)) != 0) /*ALNA*/
+ bit_mask |= 0x00FF0000;
+ if ((cond1 & BIT(3)) != 0) /*APA*/
+ bit_mask |= 0xFF000000;
+
+ if (((cond2 & bit_mask) == (driver2 & bit_mask)) && ((cond4 & bit_mask) == (driver4 & bit_mask))) /* board_type of each RF path is matched*/
+ return true;
+ else
+ return false;
+ } else
+ return false;
+}
+static bool
+check_negative(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ const u32 condition1,
+ const u32 condition2
+)
+{
+ return true;
+}
+
+/******************************************************************************
+* MAC_REG.TXT
+******************************************************************************/
+
+static u32 array_mp_8188e_mac_reg[] = {
+ 0x026, 0x00000041,
+ 0x027, 0x00000035,
+ 0x80000002, 0x00000000, 0x40000000, 0x00000000,
+ 0x040, 0x0000000C,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x040, 0x0000000C,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x040, 0x0000000C,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x040, 0x0000000C,
+ 0xA0000000, 0x00000000,
+ 0x040, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x421, 0x0000000F,
+ 0x428, 0x0000000A,
+ 0x429, 0x00000010,
+ 0x430, 0x00000000,
+ 0x431, 0x00000001,
+ 0x432, 0x00000002,
+ 0x433, 0x00000004,
+ 0x434, 0x00000005,
+ 0x435, 0x00000006,
+ 0x436, 0x00000007,
+ 0x437, 0x00000008,
+ 0x438, 0x00000000,
+ 0x439, 0x00000000,
+ 0x43A, 0x00000001,
+ 0x43B, 0x00000002,
+ 0x43C, 0x00000004,
+ 0x43D, 0x00000005,
+ 0x43E, 0x00000006,
+ 0x43F, 0x00000007,
+ 0x440, 0x0000005D,
+ 0x441, 0x00000001,
+ 0x442, 0x00000000,
+ 0x444, 0x00000015,
+ 0x445, 0x000000F0,
+ 0x446, 0x0000000F,
+ 0x447, 0x00000000,
+ 0x458, 0x00000041,
+ 0x459, 0x000000A8,
+ 0x45A, 0x00000072,
+ 0x45B, 0x000000B9,
+ 0x460, 0x00000066,
+ 0x461, 0x00000066,
+ 0x480, 0x00000008,
+ 0x4C8, 0x000000FF,
+ 0x4C9, 0x00000008,
+ 0x4CC, 0x000000FF,
+ 0x4CD, 0x000000FF,
+ 0x4CE, 0x00000001,
+ 0x4D3, 0x00000001,
+ 0x500, 0x00000026,
+ 0x501, 0x000000A2,
+ 0x502, 0x0000002F,
+ 0x503, 0x00000000,
+ 0x504, 0x00000028,
+ 0x505, 0x000000A3,
+ 0x506, 0x0000005E,
+ 0x507, 0x00000000,
+ 0x508, 0x0000002B,
+ 0x509, 0x000000A4,
+ 0x50A, 0x0000005E,
+ 0x50B, 0x00000000,
+ 0x50C, 0x0000004F,
+ 0x50D, 0x000000A4,
+ 0x50E, 0x00000000,
+ 0x50F, 0x00000000,
+ 0x512, 0x0000001C,
+ 0x514, 0x0000000A,
+ 0x516, 0x0000000A,
+ 0x525, 0x0000004F,
+ 0x550, 0x00000010,
+ 0x551, 0x00000010,
+ 0x559, 0x00000002,
+ 0x55D, 0x000000FF,
+ 0x605, 0x00000030,
+ 0x608, 0x0000000E,
+ 0x609, 0x0000002A,
+ 0x620, 0x000000FF,
+ 0x621, 0x000000FF,
+ 0x622, 0x000000FF,
+ 0x623, 0x000000FF,
+ 0x624, 0x000000FF,
+ 0x625, 0x000000FF,
+ 0x626, 0x000000FF,
+ 0x627, 0x000000FF,
+ 0x63C, 0x00000008,
+ 0x63D, 0x00000008,
+ 0x63E, 0x0000000C,
+ 0x63F, 0x0000000C,
+ 0x640, 0x00000040,
+ 0x652, 0x00000020,
+ 0x66E, 0x00000005,
+ 0x700, 0x00000021,
+ 0x701, 0x00000043,
+ 0x702, 0x00000065,
+ 0x703, 0x00000087,
+ 0x708, 0x00000021,
+ 0x709, 0x00000043,
+ 0x70A, 0x00000065,
+ 0x70B, 0x00000087,
+
+};
+
+void
+odm_read_and_config_mp_8188e_mac_reg(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 i = 0;
+ u8 c_cond;
+ bool is_matched = true, is_skipped = false;
+ u32 array_len = sizeof(array_mp_8188e_mac_reg) / sizeof(u32);
+ u32 *array = array_mp_8188e_mac_reg;
+
+ u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> odm_read_and_config_mp_8188e_mac_reg\n"));
+
+ while ((i + 1) < array_len) {
+ v1 = array[i];
+ v2 = array[i + 1];
+
+ if (v1 & (BIT(31) | BIT30)) {/*positive & negative condition*/
+ if (v1 & BIT(31)) {/* positive condition*/
+ c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
+ if (c_cond == COND_ENDIF) {/*end*/
+ is_matched = true;
+ is_skipped = false;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ENDIF\n"));
+ } else if (c_cond == COND_ELSE) { /*else*/
+ is_matched = is_skipped ? false : true;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ELSE\n"));
+ } else {/*if , else if*/
+ pre_v1 = v1;
+ pre_v2 = v2;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("IF or ELSE IF\n"));
+ }
+ } else if (v1 & BIT(30)) { /*negative condition*/
+ if (is_skipped == false) {
+ if (check_positive(p_dm_odm, pre_v1, pre_v2, v1, v2)) {
+ is_matched = true;
+ is_skipped = true;
+ } else {
+ is_matched = false;
+ is_skipped = false;
+ }
+ } else
+ is_matched = false;
+ }
+ } else {
+ if (is_matched)
+ odm_config_mac_8188e(p_dm_odm, v1, (u8)v2);
+ }
+ i = i + 2;
+ }
+}
+
+u32
+odm_get_version_mp_8188e_mac_reg(void)
+{
+ return 70;
+}
+
+#endif /* end of HWIMG_SUPPORT*/
diff --git a/drivers/staging/rtl8188eu/hal/halhwimg8188e_mac.h b/drivers/staging/rtl8188eu/hal/halhwimg8188e_mac.h
new file mode 100644
index 000000000000..40f5ab8073bf
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/halhwimg8188e_mac.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/*Image2HeaderVersion: 2.18*/
+#if (RTL8188E_SUPPORT == 1)
+#ifndef __INC_MP_MAC_HW_IMG_8188E_H
+#define __INC_MP_MAC_HW_IMG_8188E_H
+
+
+/******************************************************************************
+* MAC_REG.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_mac_reg(/* TC: Test Chip, MP: MP Chip*/
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+u32 odm_get_version_mp_8188e_mac_reg(void);
+
+#endif
+#endif /* end of HWIMG_SUPPORT*/
diff --git a/drivers/staging/rtl8188eu/hal/halhwimg8188e_rf.c b/drivers/staging/rtl8188eu/hal/halhwimg8188e_rf.c
new file mode 100644
index 000000000000..da5af62eed12
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/halhwimg8188e_rf.c
@@ -0,0 +1,2183 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/*Image2HeaderVersion: 2.18*/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+static bool
+check_positive(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ const u32 condition1,
+ const u32 condition2,
+ const u32 condition3,
+ const u32 condition4
+)
+{
+ u8 _board_type = ((p_dm_odm->board_type & BIT(4)) >> 4) << 0 | /* _GLNA*/
+ ((p_dm_odm->board_type & BIT(3)) >> 3) << 1 | /* _GPA*/
+ ((p_dm_odm->board_type & BIT(7)) >> 7) << 2 | /* _ALNA*/
+ ((p_dm_odm->board_type & BIT(6)) >> 6) << 3 | /* _APA */
+ ((p_dm_odm->board_type & BIT(2)) >> 2) << 4; /* _BT*/
+
+ u32 cond1 = condition1, cond2 = condition2, cond3 = condition3, cond4 = condition4;
+ u32 driver1 = p_dm_odm->cut_version << 24 |
+ (p_dm_odm->support_interface & 0xF0) << 16 |
+ p_dm_odm->support_platform << 16 |
+ p_dm_odm->package_type << 12 |
+ (p_dm_odm->support_interface & 0x0F) << 8 |
+ _board_type;
+
+ u32 driver2 = (p_dm_odm->type_glna & 0xFF) << 0 |
+ (p_dm_odm->type_gpa & 0xFF) << 8 |
+ (p_dm_odm->type_alna & 0xFF) << 16 |
+ (p_dm_odm->type_apa & 0xFF) << 24;
+
+ u32 driver3 = 0;
+
+ u32 driver4 = (p_dm_odm->type_glna & 0xFF00) >> 8 |
+ (p_dm_odm->type_gpa & 0xFF00) |
+ (p_dm_odm->type_alna & 0xFF00) << 8 |
+ (p_dm_odm->type_apa & 0xFF00) << 16;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE,
+ ("===> check_positive (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n", cond1, cond2, cond3, cond4));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE,
+ ("===> check_positive (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n", driver1, driver2, driver3, driver4));
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE,
+ (" (Platform, Interface) = (0x%X, 0x%X)\n", p_dm_odm->support_platform, p_dm_odm->support_interface));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE,
+ (" (Board, Package) = (0x%X, 0x%X)\n", p_dm_odm->board_type, p_dm_odm->package_type));
+
+
+ /*============== value Defined Check ===============*/
+ /*QFN type [15:12] and cut version [27:24] need to do value check*/
+
+ if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) != (driver1 & 0x0000F000)))
+ return false;
+ if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) != (driver1 & 0x0F000000)))
+ return false;
+
+ /*=============== Bit Defined Check ================*/
+ /* We don't care [31:28] */
+
+ cond1 &= 0x00FF0FFF;
+ driver1 &= 0x00FF0FFF;
+
+ if ((cond1 & driver1) == cond1) {
+ u32 bit_mask = 0;
+
+ if ((cond1 & 0x0F) == 0) /* board_type is DONTCARE*/
+ return true;
+
+ if ((cond1 & BIT(0)) != 0) /*GLNA*/
+ bit_mask |= 0x000000FF;
+ if ((cond1 & BIT(1)) != 0) /*GPA*/
+ bit_mask |= 0x0000FF00;
+ if ((cond1 & BIT(2)) != 0) /*ALNA*/
+ bit_mask |= 0x00FF0000;
+ if ((cond1 & BIT(3)) != 0) /*APA*/
+ bit_mask |= 0xFF000000;
+
+ if (((cond2 & bit_mask) == (driver2 & bit_mask)) && ((cond4 & bit_mask) == (driver4 & bit_mask))) /* board_type of each RF path is matched*/
+ return true;
+ else
+ return false;
+ } else
+ return false;
+}
+static bool
+check_negative(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ const u32 condition1,
+ const u32 condition2
+)
+{
+ return true;
+}
+
+/******************************************************************************
+* RadioA.TXT
+******************************************************************************/
+
+static u32 array_mp_8188e_radioa[] = {
+ 0x000, 0x00030000,
+ 0x008, 0x00084000,
+ 0x018, 0x00000407,
+ 0x019, 0x00000012,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0x01B, 0x00000084,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0x01B, 0x00000084,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x01B, 0x00000084,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x01B, 0x00000084,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x01B, 0x00000084,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x01B, 0x00000084,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x01B, 0x00000084,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0x01B, 0x00000084,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x01E, 0x00080009,
+ 0x01F, 0x00000880,
+ 0x02F, 0x0001A060,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C0000,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0x03F, 0x000C0000,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x03F, 0x000C0000,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x03F, 0x00000000,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C0000,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x03F, 0x000C0000,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x03F, 0x000C0000,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C0000,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x00000000,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x00000000,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x03F, 0x00000000,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x03F, 0x00000000,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x000C0000,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x03F, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x03F, 0x00000000,
+ 0xB0000000, 0x00000000,
+ 0x042, 0x000060C0,
+ 0x057, 0x000D0000,
+ 0x058, 0x000BE180,
+ 0x067, 0x00001552,
+ 0x083, 0x00000000,
+ 0x0B0, 0x000FF8FC,
+ 0x0B1, 0x00054400,
+ 0x0B2, 0x000CCC19,
+ 0x0B4, 0x00043003,
+ 0x0B6, 0x0004953E,
+ 0x0B7, 0x0001C718,
+ 0x0B8, 0x000060FF,
+ 0x0B9, 0x00080001,
+ 0x0BA, 0x00040000,
+ 0x0BB, 0x00000400,
+ 0x0BF, 0x000C0000,
+ 0x0C2, 0x00002400,
+ 0x0C3, 0x00000009,
+ 0x0C4, 0x00040C91,
+ 0x0C5, 0x00099999,
+ 0x0C6, 0x000000A3,
+ 0x0C7, 0x00088820,
+ 0x0C8, 0x00076C06,
+ 0x0C9, 0x00000000,
+ 0x0CA, 0x00080000,
+ 0x0DF, 0x00000180,
+ 0x0EF, 0x000001A0,
+ 0x051, 0x0006B27D,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0x052, 0x0007E49D,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0x052, 0x0007E49D,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x052, 0x0007E49D,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x052, 0x0007E49D,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x052, 0x0007E49D,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x052, 0x0007E49D,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x052, 0x0007E49D,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x052, 0x0007E4DD,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0x052, 0x0007E49D,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x052, 0x0007E49D,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x052, 0x0007E49D,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x052, 0x0007E49D,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0x052, 0x0007E49D,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x052, 0x0007E4DD,
+ 0xA0000000, 0x00000000,
+ 0x052, 0x0007E49D,
+ 0xB0000000, 0x00000000,
+ 0x053, 0x00000073,
+ 0x056, 0x00051FF3,
+ 0x035, 0x00000086,
+ 0x035, 0x00000186,
+ 0x035, 0x00000286,
+ 0x036, 0x00001C25,
+ 0x036, 0x00009C25,
+ 0x036, 0x00011C25,
+ 0x036, 0x00019C25,
+ 0x0B6, 0x00048538,
+ 0x018, 0x00000C07,
+ 0x05A, 0x0004BD00,
+ 0x019, 0x000739D0,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0000A095,
+ 0x034, 0x00009092,
+ 0x034, 0x0000808E,
+ 0x034, 0x0000704F,
+ 0x034, 0x0000604C,
+ 0x034, 0x00005049,
+ 0x034, 0x0000400C,
+ 0x034, 0x00003009,
+ 0x034, 0x00002006,
+ 0x034, 0x00001003,
+ 0x034, 0x00000000,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0x034, 0x0000A095,
+ 0x034, 0x00009092,
+ 0x034, 0x0000808E,
+ 0x034, 0x0000704F,
+ 0x034, 0x0000604C,
+ 0x034, 0x00005049,
+ 0x034, 0x0000400C,
+ 0x034, 0x00003009,
+ 0x034, 0x00002006,
+ 0x034, 0x00001003,
+ 0x034, 0x00000000,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x034, 0x0000A095,
+ 0x034, 0x00009092,
+ 0x034, 0x0000808E,
+ 0x034, 0x0000704F,
+ 0x034, 0x0000604C,
+ 0x034, 0x00005049,
+ 0x034, 0x0000400C,
+ 0x034, 0x00003009,
+ 0x034, 0x00002006,
+ 0x034, 0x00001003,
+ 0x034, 0x00000000,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x034, 0x0000A095,
+ 0x034, 0x00009092,
+ 0x034, 0x0000808E,
+ 0x034, 0x0000704F,
+ 0x034, 0x0000604C,
+ 0x034, 0x00005049,
+ 0x034, 0x0000400C,
+ 0x034, 0x00003009,
+ 0x034, 0x00002006,
+ 0x034, 0x00001003,
+ 0x034, 0x00000000,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0x034, 0x0000A095,
+ 0x034, 0x00009092,
+ 0x034, 0x0000808E,
+ 0x034, 0x0000704F,
+ 0x034, 0x0000604C,
+ 0x034, 0x00005049,
+ 0x034, 0x0000400C,
+ 0x034, 0x00003009,
+ 0x034, 0x00002006,
+ 0x034, 0x00001003,
+ 0x034, 0x00000000,
+ 0xA0000000, 0x00000000,
+ 0x034, 0x0000ADF3,
+ 0x034, 0x00009DF0,
+ 0x034, 0x00008DED,
+ 0x034, 0x00007DEA,
+ 0x034, 0x00006DE7,
+ 0x034, 0x000054EE,
+ 0x034, 0x000044EB,
+ 0x034, 0x000034E8,
+ 0x034, 0x0000246B,
+ 0x034, 0x00001468,
+ 0x034, 0x0000006D,
+ 0xB0000000, 0x00000000,
+ 0x000, 0x00030159,
+ 0x084, 0x00068200,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0x086, 0x000000CE,
+ 0x087, 0x00048A00,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0x086, 0x000000CE,
+ 0x087, 0x00048A00,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x086, 0x000000CE,
+ 0x087, 0x00048A00,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x086, 0x000000CE,
+ 0x087, 0x00079F80,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x086, 0x000000CE,
+ 0x087, 0x00048A00,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x086, 0x000000CE,
+ 0x087, 0x00048A00,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x086, 0x000000CE,
+ 0x087, 0x00048A00,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x086, 0x000000CE,
+ 0x087, 0x00048A00,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0x086, 0x000000CE,
+ 0x087, 0x00048A00,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x086, 0x000000CE,
+ 0x087, 0x00048A00,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x086, 0x000000CE,
+ 0x087, 0x00048A00,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x086, 0x000000CE,
+ 0x087, 0x00079F80,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0x086, 0x0008014E,
+ 0x087, 0x0004DF80,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x086, 0x000000CE,
+ 0x087, 0x00048A00,
+ 0xA0000000, 0x00000000,
+ 0x086, 0x000000CE,
+ 0x087, 0x00048A00,
+ 0xB0000000, 0x00000000,
+ 0x08E, 0x00065540,
+ 0x08F, 0x00088000,
+ 0x0EF, 0x000020A0,
+ 0x88000003, 0x00000000, 0x40000000, 0x00000000,
+ 0x03B, 0x000F02B0,
+ 0x03B, 0x000EF7B0,
+ 0x03B, 0x000D4FB0,
+ 0x03B, 0x000CF060,
+ 0x03B, 0x000B0090,
+ 0x03B, 0x000A0080,
+ 0x03B, 0x00090080,
+ 0x03B, 0x0008F780,
+ 0x03B, 0x000722B0,
+ 0x03B, 0x0006F7B0,
+ 0x03B, 0x00054FB0,
+ 0x03B, 0x0004F060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020080,
+ 0x03B, 0x00010080,
+ 0x03B, 0x0000F780,
+ 0x0EF, 0x000000A0,
+ 0x98000003, 0x00000001, 0x40000000, 0x00000000,
+ 0x03B, 0x000F02B0,
+ 0x03B, 0x000EF7B0,
+ 0x03B, 0x000D4FB0,
+ 0x03B, 0x000CF060,
+ 0x03B, 0x000B0090,
+ 0x03B, 0x000A0080,
+ 0x03B, 0x00090080,
+ 0x03B, 0x0008F780,
+ 0x03B, 0x000722B0,
+ 0x03B, 0x0006F7B0,
+ 0x03B, 0x00054FB0,
+ 0x03B, 0x0004F060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020080,
+ 0x03B, 0x00010080,
+ 0x03B, 0x0000F780,
+ 0x0EF, 0x000000A0,
+ 0x98000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x03B, 0x000F02B0,
+ 0x03B, 0x000EF7B0,
+ 0x03B, 0x000D4FB0,
+ 0x03B, 0x000CF060,
+ 0x03B, 0x000B0090,
+ 0x03B, 0x000A0080,
+ 0x03B, 0x00090080,
+ 0x03B, 0x0008F780,
+ 0x03B, 0x000722B0,
+ 0x03B, 0x0006F7B0,
+ 0x03B, 0x00054FB0,
+ 0x03B, 0x0004F060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020080,
+ 0x03B, 0x00010080,
+ 0x03B, 0x0000F780,
+ 0x0EF, 0x000000A0,
+ 0x90000003, 0x00000002, 0x40000000, 0x00000000,
+ 0x03B, 0x000F07B0,
+ 0x03B, 0x000EF7B0,
+ 0x03B, 0x000D0020,
+ 0x03B, 0x000CF060,
+ 0x03B, 0x000B07E0,
+ 0x03B, 0x000A0010,
+ 0x03B, 0x00090000,
+ 0x03B, 0x0008F780,
+ 0x03B, 0x000727B0,
+ 0x03B, 0x0006F7B0,
+ 0x03B, 0x00054FB0,
+ 0x03B, 0x0004F060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020080,
+ 0x03B, 0x00010080,
+ 0x03B, 0x0000F780,
+ 0x0EF, 0x000000A0,
+ 0x98000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x03B, 0x000F02B0,
+ 0x03B, 0x000EF7B0,
+ 0x03B, 0x000D4FB0,
+ 0x03B, 0x000CF060,
+ 0x03B, 0x000B0090,
+ 0x03B, 0x000A0080,
+ 0x03B, 0x00090080,
+ 0x03B, 0x0008F780,
+ 0x03B, 0x000722B0,
+ 0x03B, 0x0006F7B0,
+ 0x03B, 0x00054FB0,
+ 0x03B, 0x0004F060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020080,
+ 0x03B, 0x00010080,
+ 0x03B, 0x0000F780,
+ 0x0EF, 0x000000A0,
+ 0x98000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x03B, 0x000F02B0,
+ 0x03B, 0x000EF7B0,
+ 0x03B, 0x000D4FB0,
+ 0x03B, 0x000CF060,
+ 0x03B, 0x000B0090,
+ 0x03B, 0x000A0080,
+ 0x03B, 0x00090080,
+ 0x03B, 0x0008F780,
+ 0x03B, 0x000722B0,
+ 0x03B, 0x0006F7B0,
+ 0x03B, 0x00054FB0,
+ 0x03B, 0x0004F060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020080,
+ 0x03B, 0x00010080,
+ 0x03B, 0x0000F780,
+ 0x0EF, 0x000000A0,
+ 0x98000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x03B, 0x000F02B0,
+ 0x03B, 0x000EF7B0,
+ 0x03B, 0x000D4FB0,
+ 0x03B, 0x000CF060,
+ 0x03B, 0x000B0090,
+ 0x03B, 0x000A0080,
+ 0x03B, 0x00090080,
+ 0x03B, 0x0008F780,
+ 0x03B, 0x000722B0,
+ 0x03B, 0x0006F7B0,
+ 0x03B, 0x00054FB0,
+ 0x03B, 0x0004F060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020080,
+ 0x03B, 0x00010080,
+ 0x03B, 0x0000F780,
+ 0x0EF, 0x000000A0,
+ 0x98000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x03B, 0x000F02B0,
+ 0x03B, 0x000EF7B0,
+ 0x03B, 0x000D4FB0,
+ 0x03B, 0x000CF060,
+ 0x03B, 0x000B0090,
+ 0x03B, 0x000A0080,
+ 0x03B, 0x00090080,
+ 0x03B, 0x0008F780,
+ 0x03B, 0x000722B0,
+ 0x03B, 0x0006F7B0,
+ 0x03B, 0x00054FB0,
+ 0x03B, 0x0004F060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020080,
+ 0x03B, 0x00010080,
+ 0x03B, 0x0000F780,
+ 0x0EF, 0x000000A0,
+ 0x90000002, 0x00000000, 0x40000000, 0x00000000,
+ 0x03B, 0x000F02B0,
+ 0x03B, 0x000EF7B0,
+ 0x03B, 0x000D4FB0,
+ 0x03B, 0x000CF060,
+ 0x03B, 0x000B0090,
+ 0x03B, 0x000A0080,
+ 0x03B, 0x00090080,
+ 0x03B, 0x0008F780,
+ 0x03B, 0x000722B0,
+ 0x03B, 0x0006F7B0,
+ 0x03B, 0x00054FB0,
+ 0x03B, 0x0004F060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020080,
+ 0x03B, 0x00010080,
+ 0x03B, 0x0000F780,
+ 0x0EF, 0x000000A0,
+ 0x90000001, 0x00000000, 0x40000000, 0x00000000,
+ 0x03B, 0x000F02B0,
+ 0x03B, 0x000EF7B0,
+ 0x03B, 0x000D4FB0,
+ 0x03B, 0x000CF060,
+ 0x03B, 0x000B0090,
+ 0x03B, 0x000A0080,
+ 0x03B, 0x00090080,
+ 0x03B, 0x0008F780,
+ 0x03B, 0x000722B0,
+ 0x03B, 0x0006F7B0,
+ 0x03B, 0x00054FB0,
+ 0x03B, 0x0004F060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020080,
+ 0x03B, 0x00010080,
+ 0x03B, 0x0000F780,
+ 0x0EF, 0x000000A0,
+ 0x90000001, 0x00000001, 0x40000000, 0x00000000,
+ 0x03B, 0x000F02B0,
+ 0x03B, 0x000EF7B0,
+ 0x03B, 0x000D4FB0,
+ 0x03B, 0x000CF060,
+ 0x03B, 0x000B0090,
+ 0x03B, 0x000A0080,
+ 0x03B, 0x00090080,
+ 0x03B, 0x0008F780,
+ 0x03B, 0x000722B0,
+ 0x03B, 0x0006F7B0,
+ 0x03B, 0x00054FB0,
+ 0x03B, 0x0004F060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020080,
+ 0x03B, 0x00010080,
+ 0x03B, 0x0000F780,
+ 0x0EF, 0x000000A0,
+ 0x90000001, 0x00000002, 0x40000000, 0x00000000,
+ 0x03B, 0x000F07B0,
+ 0x03B, 0x000EF7B0,
+ 0x03B, 0x000D0020,
+ 0x03B, 0x000CF060,
+ 0x03B, 0x000B07E0,
+ 0x03B, 0x000A0010,
+ 0x03B, 0x00090000,
+ 0x03B, 0x0008F780,
+ 0x03B, 0x000727B0,
+ 0x03B, 0x0006F7B0,
+ 0x03B, 0x00054FB0,
+ 0x03B, 0x0004F060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020080,
+ 0x03B, 0x00010080,
+ 0x03B, 0x0000F780,
+ 0x0EF, 0x000000A0,
+ 0x98000000, 0x00000000, 0x40000000, 0x00000000,
+ 0x03B, 0x000F6030,
+ 0x03B, 0x000E6030,
+ 0x03B, 0x000D6030,
+ 0x03B, 0x000C6030,
+ 0x03B, 0x000BF030,
+ 0x03B, 0x000A0020,
+ 0x03B, 0x00090090,
+ 0x03B, 0x0008F080,
+ 0x03B, 0x0007A730,
+ 0x03B, 0x000607B0,
+ 0x03B, 0x0005F770,
+ 0x03B, 0x00040060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020780,
+ 0x03B, 0x000107A0,
+ 0x03B, 0x0000F760,
+ 0x0EF, 0x000000A0,
+ 0x90000400, 0x00000000, 0x40000000, 0x00000000,
+ 0x03B, 0x000F02B0,
+ 0x03B, 0x000EF7B0,
+ 0x03B, 0x000D4FB0,
+ 0x03B, 0x000CF060,
+ 0x03B, 0x000B0090,
+ 0x03B, 0x000A0080,
+ 0x03B, 0x00090080,
+ 0x03B, 0x0008F780,
+ 0x03B, 0x000722B0,
+ 0x03B, 0x0006F7B0,
+ 0x03B, 0x00054FB0,
+ 0x03B, 0x0004F060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020080,
+ 0x03B, 0x00010080,
+ 0x03B, 0x0000F780,
+ 0x0EF, 0x000000A0,
+ 0xA0000000, 0x00000000,
+ 0x03B, 0x000F02B0,
+ 0x03B, 0x000EF7B0,
+ 0x03B, 0x000D4FB0,
+ 0x03B, 0x000CF060,
+ 0x03B, 0x000B0090,
+ 0x03B, 0x000A0080,
+ 0x03B, 0x00090080,
+ 0x03B, 0x0008F780,
+ 0x03B, 0x000722B0,
+ 0x03B, 0x0006F7B0,
+ 0x03B, 0x00054FB0,
+ 0x03B, 0x0004F060,
+ 0x03B, 0x00030090,
+ 0x03B, 0x00020080,
+ 0x03B, 0x00010080,
+ 0x03B, 0x0000F780,
+ 0x0EF, 0x000000A0,
+ 0xB0000000, 0x00000000,
+ 0x000, 0x00010159,
+ 0x018, 0x0000F407,
+ 0xFFE, 0x00000000,
+ 0xFFE, 0x00000000,
+ 0x01F, 0x00080003,
+ 0xFFE, 0x00000000,
+ 0xFFE, 0x00000000,
+ 0x01E, 0x00000001,
+ 0x01F, 0x00080000,
+ 0x000, 0x00033E60,
+
+};
+
+void
+odm_read_and_config_mp_8188e_radioa(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 i = 0;
+ u8 c_cond;
+ bool is_matched = true, is_skipped = false;
+ u32 array_len = sizeof(array_mp_8188e_radioa) / sizeof(u32);
+ u32 *array = array_mp_8188e_radioa;
+
+ u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> odm_read_and_config_mp_8188e_radioa\n"));
+
+ while ((i + 1) < array_len) {
+ v1 = array[i];
+ v2 = array[i + 1];
+
+ if (v1 & (BIT(31) | BIT30)) {/*positive & negative condition*/
+ if (v1 & BIT(31)) {/* positive condition*/
+ c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
+ if (c_cond == COND_ENDIF) {/*end*/
+ is_matched = true;
+ is_skipped = false;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ENDIF\n"));
+ } else if (c_cond == COND_ELSE) { /*else*/
+ is_matched = is_skipped ? false : true;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ELSE\n"));
+ } else {/*if , else if*/
+ pre_v1 = v1;
+ pre_v2 = v2;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("IF or ELSE IF\n"));
+ }
+ } else if (v1 & BIT(30)) { /*negative condition*/
+ if (is_skipped == false) {
+ if (check_positive(p_dm_odm, pre_v1, pre_v2, v1, v2)) {
+ is_matched = true;
+ is_skipped = true;
+ } else {
+ is_matched = false;
+ is_skipped = false;
+ }
+ } else
+ is_matched = false;
+ }
+ } else {
+ if (is_matched)
+ odm_config_rf_radio_a_8188e(p_dm_odm, v1, v2);
+ }
+ i = i + 2;
+ }
+}
+
+u32
+odm_get_version_mp_8188e_radioa(void)
+{
+ return 70;
+}
+
+/******************************************************************************
+* TxPowerTrack_AP.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_txpowertrack_ap(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+}
+
+/******************************************************************************
+* TxPowerTrack_PCIE.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_txpowertrack_pcie(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+}
+
+/******************************************************************************
+* TxPowerTrack_PCIE_ICUT.TXT
+******************************************************************************/
+
+static u8 g_delta_swing_table_idx_mp_5gb_n_txpowertrack_pcie_icut_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 17, 17, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+};
+static u8 g_delta_swing_table_idx_mp_5gb_p_txpowertrack_pcie_icut_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+};
+static u8 g_delta_swing_table_idx_mp_5ga_n_txpowertrack_pcie_icut_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 17, 17, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+};
+static u8 g_delta_swing_table_idx_mp_5ga_p_txpowertrack_pcie_icut_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+};
+static u8 g_delta_swing_table_idx_mp_2gb_n_txpowertrack_pcie_icut_8188e[] = {0, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
+static u8 g_delta_swing_table_idx_mp_2gb_p_txpowertrack_pcie_icut_8188e[] = {0, 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 9, 9, 10, 11, 11, 11, 11, 11};
+static u8 g_delta_swing_table_idx_mp_2ga_n_txpowertrack_pcie_icut_8188e[] = {0, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
+static u8 g_delta_swing_table_idx_mp_2ga_p_txpowertrack_pcie_icut_8188e[] = {0, 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 9, 9, 10, 11, 11, 11, 11, 11};
+static u8 g_delta_swing_table_idx_mp_2g_cck_b_n_txpowertrack_pcie_icut_8188e[] = {0, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
+static u8 g_delta_swing_table_idx_mp_2g_cck_b_p_txpowertrack_pcie_icut_8188e[] = {0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 10, 10, 11, 12, 12, 12, 12};
+static u8 g_delta_swing_table_idx_mp_2g_cck_a_n_txpowertrack_pcie_icut_8188e[] = {0, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
+static u8 g_delta_swing_table_idx_mp_2g_cck_a_p_txpowertrack_pcie_icut_8188e[] = {0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 10, 10, 11, 12, 12, 12, 12};
+
+void
+odm_read_and_config_mp_8188e_txpowertrack_pcie_icut(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ struct odm_rf_calibration_structure *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_MP_8188E\n"));
+
+
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2ga_p, g_delta_swing_table_idx_mp_2ga_p_txpowertrack_pcie_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2ga_n, g_delta_swing_table_idx_mp_2ga_n_txpowertrack_pcie_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2gb_p, g_delta_swing_table_idx_mp_2gb_p_txpowertrack_pcie_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2gb_n, g_delta_swing_table_idx_mp_2gb_n_txpowertrack_pcie_icut_8188e, DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_a_p, g_delta_swing_table_idx_mp_2g_cck_a_p_txpowertrack_pcie_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_a_n, g_delta_swing_table_idx_mp_2g_cck_a_n_txpowertrack_pcie_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_b_p, g_delta_swing_table_idx_mp_2g_cck_b_p_txpowertrack_pcie_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_b_n, g_delta_swing_table_idx_mp_2g_cck_b_n_txpowertrack_pcie_icut_8188e, DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5ga_p, g_delta_swing_table_idx_mp_5ga_p_txpowertrack_pcie_icut_8188e, DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5ga_n, g_delta_swing_table_idx_mp_5ga_n_txpowertrack_pcie_icut_8188e, DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5gb_p, g_delta_swing_table_idx_mp_5gb_p_txpowertrack_pcie_icut_8188e, DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5gb_n, g_delta_swing_table_idx_mp_5gb_n_txpowertrack_pcie_icut_8188e, DELTA_SWINGIDX_SIZE * 3);
+}
+
+void
+odm_read_and_config_mp_8188e_txpowertrack_sdio(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+}
+
+/******************************************************************************
+* TxPowerTrack_SDIO_ICUT.TXT
+******************************************************************************/
+
+static u8 g_delta_swing_table_idx_mp_5gb_n_txpowertrack_sdio_icut_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 17, 17, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+};
+static u8 g_delta_swing_table_idx_mp_5gb_p_txpowertrack_sdio_icut_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+};
+static u8 g_delta_swing_table_idx_mp_5ga_n_txpowertrack_sdio_icut_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 17, 17, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+};
+static u8 g_delta_swing_table_idx_mp_5ga_p_txpowertrack_sdio_icut_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+};
+static u8 g_delta_swing_table_idx_mp_2gb_n_txpowertrack_sdio_icut_8188e[] = {0, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
+static u8 g_delta_swing_table_idx_mp_2gb_p_txpowertrack_sdio_icut_8188e[] = {0, 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 9, 9, 10, 11, 11, 11, 11, 11};
+static u8 g_delta_swing_table_idx_mp_2ga_n_txpowertrack_sdio_icut_8188e[] = {0, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
+static u8 g_delta_swing_table_idx_mp_2ga_p_txpowertrack_sdio_icut_8188e[] = {0, 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 9, 9, 10, 11, 11, 11, 11, 11};
+static u8 g_delta_swing_table_idx_mp_2g_cck_b_n_txpowertrack_sdio_icut_8188e[] = {0, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
+static u8 g_delta_swing_table_idx_mp_2g_cck_b_p_txpowertrack_sdio_icut_8188e[] = {0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 10, 10, 11, 12, 12, 12, 12};
+static u8 g_delta_swing_table_idx_mp_2g_cck_a_n_txpowertrack_sdio_icut_8188e[] = {0, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
+static u8 g_delta_swing_table_idx_mp_2g_cck_a_p_txpowertrack_sdio_icut_8188e[] = {0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 10, 10, 11, 12, 12, 12, 12};
+
+void
+odm_read_and_config_mp_8188e_txpowertrack_sdio_icut(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ struct odm_rf_calibration_structure *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_MP_8188E\n"));
+
+
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2ga_p, g_delta_swing_table_idx_mp_2ga_p_txpowertrack_sdio_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2ga_n, g_delta_swing_table_idx_mp_2ga_n_txpowertrack_sdio_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2gb_p, g_delta_swing_table_idx_mp_2gb_p_txpowertrack_sdio_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2gb_n, g_delta_swing_table_idx_mp_2gb_n_txpowertrack_sdio_icut_8188e, DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_a_p, g_delta_swing_table_idx_mp_2g_cck_a_p_txpowertrack_sdio_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_a_n, g_delta_swing_table_idx_mp_2g_cck_a_n_txpowertrack_sdio_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_b_p, g_delta_swing_table_idx_mp_2g_cck_b_p_txpowertrack_sdio_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_b_n, g_delta_swing_table_idx_mp_2g_cck_b_n_txpowertrack_sdio_icut_8188e, DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5ga_p, g_delta_swing_table_idx_mp_5ga_p_txpowertrack_sdio_icut_8188e, DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5ga_n, g_delta_swing_table_idx_mp_5ga_n_txpowertrack_sdio_icut_8188e, DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5gb_p, g_delta_swing_table_idx_mp_5gb_p_txpowertrack_sdio_icut_8188e, DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5gb_n, g_delta_swing_table_idx_mp_5gb_n_txpowertrack_sdio_icut_8188e, DELTA_SWINGIDX_SIZE * 3);
+}
+
+/******************************************************************************
+* TxPowerTrack_USB.TXT
+******************************************************************************/
+
+static u8 g_delta_swing_table_idx_mp_5gb_n_txpowertrack_usb_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 17, 17, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+};
+static u8 g_delta_swing_table_idx_mp_5gb_p_txpowertrack_usb_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+};
+static u8 g_delta_swing_table_idx_mp_5ga_n_txpowertrack_usb_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 17, 17, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+};
+static u8 g_delta_swing_table_idx_mp_5ga_p_txpowertrack_usb_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+};
+static u8 g_delta_swing_table_idx_mp_2gb_n_txpowertrack_usb_8188e[] = {0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9};
+static u8 g_delta_swing_table_idx_mp_2gb_p_txpowertrack_usb_8188e[] = {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 7, 8, 8, 8, 8};
+static u8 g_delta_swing_table_idx_mp_2ga_n_txpowertrack_usb_8188e[] = {0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9};
+static u8 g_delta_swing_table_idx_mp_2ga_p_txpowertrack_usb_8188e[] = {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 7, 8, 8, 8, 8};
+static u8 g_delta_swing_table_idx_mp_2g_cck_b_n_txpowertrack_usb_8188e[] = {0, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9};
+static u8 g_delta_swing_table_idx_mp_2g_cck_b_p_txpowertrack_usb_8188e[] = {0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 6, 6, 6, 6, 7, 7};
+static u8 g_delta_swing_table_idx_mp_2g_cck_a_n_txpowertrack_usb_8188e[] = {0, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9};
+static u8 g_delta_swing_table_idx_mp_2g_cck_a_p_txpowertrack_usb_8188e[] = {0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 6, 6, 6, 6, 7, 7};
+
+void
+odm_read_and_config_mp_8188e_txpowertrack_usb(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ struct odm_rf_calibration_structure *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_MP_8188E\n"));
+
+
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2ga_p, g_delta_swing_table_idx_mp_2ga_p_txpowertrack_usb_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2ga_n, g_delta_swing_table_idx_mp_2ga_n_txpowertrack_usb_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2gb_p, g_delta_swing_table_idx_mp_2gb_p_txpowertrack_usb_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2gb_n, g_delta_swing_table_idx_mp_2gb_n_txpowertrack_usb_8188e, DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_a_p, g_delta_swing_table_idx_mp_2g_cck_a_p_txpowertrack_usb_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_a_n, g_delta_swing_table_idx_mp_2g_cck_a_n_txpowertrack_usb_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_b_p, g_delta_swing_table_idx_mp_2g_cck_b_p_txpowertrack_usb_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_b_n, g_delta_swing_table_idx_mp_2g_cck_b_n_txpowertrack_usb_8188e, DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5ga_p, g_delta_swing_table_idx_mp_5ga_p_txpowertrack_usb_8188e, DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5ga_n, g_delta_swing_table_idx_mp_5ga_n_txpowertrack_usb_8188e, DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5gb_p, g_delta_swing_table_idx_mp_5gb_p_txpowertrack_usb_8188e, DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5gb_n, g_delta_swing_table_idx_mp_5gb_n_txpowertrack_usb_8188e, DELTA_SWINGIDX_SIZE * 3);
+}
+
+/******************************************************************************
+* TxPowerTrack_USB_ICUT.TXT
+******************************************************************************/
+
+static u8 g_delta_swing_table_idx_mp_5gb_n_txpowertrack_usb_icut_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 17, 17, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+};
+static u8 g_delta_swing_table_idx_mp_5gb_p_txpowertrack_usb_icut_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+};
+static u8 g_delta_swing_table_idx_mp_5ga_n_txpowertrack_usb_icut_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 17, 17, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+ {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18},
+};
+static u8 g_delta_swing_table_idx_mp_5ga_p_txpowertrack_usb_icut_8188e[][DELTA_SWINGIDX_SIZE] = {
+ {0, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
+};
+static u8 g_delta_swing_table_idx_mp_2gb_n_txpowertrack_usb_icut_8188e[] = {
+ 0, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9};
+static u8 g_delta_swing_table_idx_mp_2gb_p_txpowertrack_usb_icut_8188e[] = {
+ 0, 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 9,
+ 9, 10, 11, 11, 11, 11, 11};
+static u8 g_delta_swing_table_idx_mp_2ga_n_txpowertrack_usb_icut_8188e[] = {
+ 0, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9};
+static u8 g_delta_swing_table_idx_mp_2ga_p_txpowertrack_usb_icut_8188e[] = {
+ 0, 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 9,
+ 9, 10, 11, 11, 11, 11, 11};
+static u8 g_delta_swing_table_idx_mp_2g_cck_b_n_txpowertrack_usb_icut_8188e[] = {
+ 0, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8};
+static u8 g_delta_swing_table_idx_mp_2g_cck_b_p_txpowertrack_usb_icut_8188e[] = {
+ 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9,
+ 10, 10, 11, 12, 12, 12, 12};
+static u8 g_delta_swing_table_idx_mp_2g_cck_a_n_txpowertrack_usb_icut_8188e[] = {
+ 0, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8};
+static u8 g_delta_swing_table_idx_mp_2g_cck_a_p_txpowertrack_usb_icut_8188e[] = {
+ 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9,
+ 10, 10, 11, 12, 12, 12, 12
+};
+
+void
+odm_read_and_config_mp_8188e_txpowertrack_usb_icut(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ struct odm_rf_calibration_structure *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_MP_8188E\n"));
+
+
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2ga_p, g_delta_swing_table_idx_mp_2ga_p_txpowertrack_usb_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2ga_n, g_delta_swing_table_idx_mp_2ga_n_txpowertrack_usb_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2gb_p, g_delta_swing_table_idx_mp_2gb_p_txpowertrack_usb_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2gb_n, g_delta_swing_table_idx_mp_2gb_n_txpowertrack_usb_icut_8188e, DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_a_p, g_delta_swing_table_idx_mp_2g_cck_a_p_txpowertrack_usb_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_a_n, g_delta_swing_table_idx_mp_2g_cck_a_n_txpowertrack_usb_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_b_p, g_delta_swing_table_idx_mp_2g_cck_b_p_txpowertrack_usb_icut_8188e, DELTA_SWINGIDX_SIZE);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_2g_cck_b_n, g_delta_swing_table_idx_mp_2g_cck_b_n_txpowertrack_usb_icut_8188e, DELTA_SWINGIDX_SIZE);
+
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5ga_p, g_delta_swing_table_idx_mp_5ga_p_txpowertrack_usb_icut_8188e, DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5ga_n, g_delta_swing_table_idx_mp_5ga_n_txpowertrack_usb_icut_8188e, DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5gb_p, g_delta_swing_table_idx_mp_5gb_p_txpowertrack_usb_icut_8188e, DELTA_SWINGIDX_SIZE * 3);
+ odm_move_memory(p_dm_odm, p_rf_calibrate_info->delta_swing_table_idx_5gb_n, g_delta_swing_table_idx_mp_5gb_n_txpowertrack_usb_icut_8188e, DELTA_SWINGIDX_SIZE * 3);
+}
+
+/******************************************************************************
+* TXPWR_LMT.TXT
+******************************************************************************/
+
+static const char *array_mp_8188e_txpwr_lmt[] = {
+ "FCC", "2.4G", "20M", "CCK", "1T", "01", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "01", "26",
+ "MKK", "2.4G", "20M", "CCK", "1T", "01", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "02", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "02", "26",
+ "MKK", "2.4G", "20M", "CCK", "1T", "02", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "03", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "03", "26",
+ "MKK", "2.4G", "20M", "CCK", "1T", "03", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "04", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "04", "26",
+ "MKK", "2.4G", "20M", "CCK", "1T", "04", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "05", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "05", "26",
+ "MKK", "2.4G", "20M", "CCK", "1T", "05", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "06", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "06", "26",
+ "MKK", "2.4G", "20M", "CCK", "1T", "06", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "07", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "07", "26",
+ "MKK", "2.4G", "20M", "CCK", "1T", "07", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "08", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "08", "26",
+ "MKK", "2.4G", "20M", "CCK", "1T", "08", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "09", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "09", "26",
+ "MKK", "2.4G", "20M", "CCK", "1T", "09", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "10", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "10", "26",
+ "MKK", "2.4G", "20M", "CCK", "1T", "10", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "11", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "11", "26",
+ "MKK", "2.4G", "20M", "CCK", "1T", "11", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "12", "63",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "12", "26",
+ "MKK", "2.4G", "20M", "CCK", "1T", "12", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "13", "63",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "13", "26",
+ "MKK", "2.4G", "20M", "CCK", "1T", "13", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "14", "63",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63",
+ "MKK", "2.4G", "20M", "CCK", "1T", "14", "32",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "01", "28",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "01", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "01", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "02", "28",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "02", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "02", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "03", "30",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "03", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "04", "30",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "04", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "04", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "05", "30",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "05", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "05", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "06", "30",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "06", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "07", "30",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "07", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "07", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "08", "30",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "08", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "08", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "09", "28",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "09", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "10", "28",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "10", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "10", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "11", "28",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "11", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "11", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "12", "63",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "12", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "13", "63",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "13", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "13", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "14", "63",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "14", "63",
+ "FCC", "2.4G", "20M", "HT", "1T", "01", "28",
+ "ETSI", "2.4G", "20M", "HT", "1T", "01", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "01", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "02", "28",
+ "ETSI", "2.4G", "20M", "HT", "1T", "02", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "02", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "03", "30",
+ "ETSI", "2.4G", "20M", "HT", "1T", "03", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "03", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "04", "30",
+ "ETSI", "2.4G", "20M", "HT", "1T", "04", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "04", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "05", "30",
+ "ETSI", "2.4G", "20M", "HT", "1T", "05", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "05", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "06", "30",
+ "ETSI", "2.4G", "20M", "HT", "1T", "06", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "06", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "07", "30",
+ "ETSI", "2.4G", "20M", "HT", "1T", "07", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "07", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "08", "30",
+ "ETSI", "2.4G", "20M", "HT", "1T", "08", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "08", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "09", "28",
+ "ETSI", "2.4G", "20M", "HT", "1T", "09", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "09", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "10", "28",
+ "ETSI", "2.4G", "20M", "HT", "1T", "10", "30",
+ "MKK", "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", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "12", "63",
+ "ETSI", "2.4G", "20M", "HT", "1T", "12", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "12", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "13", "63",
+ "ETSI", "2.4G", "20M", "HT", "1T", "13", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "13", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "14", "63",
+ "ETSI", "2.4G", "20M", "HT", "1T", "14", "63",
+ "MKK", "2.4G", "20M", "HT", "1T", "14", "63",
+ "FCC", "2.4G", "20M", "HT", "2T", "01", "28",
+ "ETSI", "2.4G", "20M", "HT", "2T", "01", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "01", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "02", "28",
+ "ETSI", "2.4G", "20M", "HT", "2T", "02", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "02", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "03", "30",
+ "ETSI", "2.4G", "20M", "HT", "2T", "03", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "03", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "04", "30",
+ "ETSI", "2.4G", "20M", "HT", "2T", "04", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "04", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "05", "30",
+ "ETSI", "2.4G", "20M", "HT", "2T", "05", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "05", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "06", "30",
+ "ETSI", "2.4G", "20M", "HT", "2T", "06", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "06", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "07", "30",
+ "ETSI", "2.4G", "20M", "HT", "2T", "07", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "07", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "08", "30",
+ "ETSI", "2.4G", "20M", "HT", "2T", "08", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "08", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "09", "28",
+ "ETSI", "2.4G", "20M", "HT", "2T", "09", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "09", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "10", "28",
+ "ETSI", "2.4G", "20M", "HT", "2T", "10", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "10", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "11", "28",
+ "ETSI", "2.4G", "20M", "HT", "2T", "11", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "11", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "12", "63",
+ "ETSI", "2.4G", "20M", "HT", "2T", "12", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "12", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "13", "63",
+ "ETSI", "2.4G", "20M", "HT", "2T", "13", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "13", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "14", "63",
+ "ETSI", "2.4G", "20M", "HT", "2T", "14", "63",
+ "MKK", "2.4G", "20M", "HT", "2T", "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",
+ "FCC", "2.4G", "40M", "HT", "1T", "02", "63",
+ "ETSI", "2.4G", "40M", "HT", "1T", "02", "63",
+ "MKK", "2.4G", "40M", "HT", "1T", "02", "63",
+ "FCC", "2.4G", "40M", "HT", "1T", "03", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "03", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "03", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "04", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "04", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "04", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "05", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "05", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "05", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "06", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "06", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "06", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "07", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "07", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "07", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "08", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "08", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "08", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "09", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "09", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "09", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "10", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "10", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "10", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "11", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "11", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "11", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "12", "63",
+ "ETSI", "2.4G", "40M", "HT", "1T", "12", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "12", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "13", "63",
+ "ETSI", "2.4G", "40M", "HT", "1T", "13", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "13", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "14", "63",
+ "ETSI", "2.4G", "40M", "HT", "1T", "14", "63",
+ "MKK", "2.4G", "40M", "HT", "1T", "14", "63",
+ "FCC", "2.4G", "40M", "HT", "2T", "01", "63",
+ "ETSI", "2.4G", "40M", "HT", "2T", "01", "63",
+ "MKK", "2.4G", "40M", "HT", "2T", "01", "63",
+ "FCC", "2.4G", "40M", "HT", "2T", "02", "63",
+ "ETSI", "2.4G", "40M", "HT", "2T", "02", "63",
+ "MKK", "2.4G", "40M", "HT", "2T", "02", "63",
+ "FCC", "2.4G", "40M", "HT", "2T", "03", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "03", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "03", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "04", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "04", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "04", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "05", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "05", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "05", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "06", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "06", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "06", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "07", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "07", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "07", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "08", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "08", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "08", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "09", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "09", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "09", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "10", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "10", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "10", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "11", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "11", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "11", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "12", "63",
+ "ETSI", "2.4G", "40M", "HT", "2T", "12", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "12", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "13", "63",
+ "ETSI", "2.4G", "40M", "HT", "2T", "13", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "13", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "14", "63",
+ "ETSI", "2.4G", "40M", "HT", "2T", "14", "63",
+ "MKK", "2.4G", "40M", "HT", "2T", "14", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "36", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "36", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "36", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "40", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "40", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "40", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "44", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "44", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "44", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "48", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "48", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "48", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "52", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "52", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "52", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "56", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "56", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "56", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "60", "32",
+ "ETSI", "5G", "20M", "OFDM", "1T", "60", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "60", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "64", "28",
+ "ETSI", "5G", "20M", "OFDM", "1T", "64", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "64", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "100", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "100", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "100", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "114", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "114", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "114", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "108", "32",
+ "ETSI", "5G", "20M", "OFDM", "1T", "108", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "108", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "112", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "112", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "112", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "116", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "116", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "116", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "120", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "120", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "120", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "124", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "124", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "124", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "128", "32",
+ "ETSI", "5G", "20M", "OFDM", "1T", "128", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "128", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "132", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "132", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "132", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "136", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "136", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "136", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "140", "28",
+ "ETSI", "5G", "20M", "OFDM", "1T", "140", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "140", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "149", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "149", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "149", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "153", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "153", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "153", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "157", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "157", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "157", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "161", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "161", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "161", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "165", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "165", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "165", "63",
+ "FCC", "5G", "20M", "HT", "1T", "36", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "36", "32",
+ "MKK", "5G", "20M", "HT", "1T", "36", "32",
+ "FCC", "5G", "20M", "HT", "1T", "40", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "40", "32",
+ "MKK", "5G", "20M", "HT", "1T", "40", "32",
+ "FCC", "5G", "20M", "HT", "1T", "44", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "44", "32",
+ "MKK", "5G", "20M", "HT", "1T", "44", "32",
+ "FCC", "5G", "20M", "HT", "1T", "48", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "48", "32",
+ "MKK", "5G", "20M", "HT", "1T", "48", "32",
+ "FCC", "5G", "20M", "HT", "1T", "52", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "52", "32",
+ "MKK", "5G", "20M", "HT", "1T", "52", "32",
+ "FCC", "5G", "20M", "HT", "1T", "56", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "56", "32",
+ "MKK", "5G", "20M", "HT", "1T", "56", "32",
+ "FCC", "5G", "20M", "HT", "1T", "60", "32",
+ "ETSI", "5G", "20M", "HT", "1T", "60", "32",
+ "MKK", "5G", "20M", "HT", "1T", "60", "32",
+ "FCC", "5G", "20M", "HT", "1T", "64", "28",
+ "ETSI", "5G", "20M", "HT", "1T", "64", "32",
+ "MKK", "5G", "20M", "HT", "1T", "64", "32",
+ "FCC", "5G", "20M", "HT", "1T", "100", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "100", "32",
+ "MKK", "5G", "20M", "HT", "1T", "100", "32",
+ "FCC", "5G", "20M", "HT", "1T", "114", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "114", "32",
+ "MKK", "5G", "20M", "HT", "1T", "114", "32",
+ "FCC", "5G", "20M", "HT", "1T", "108", "32",
+ "ETSI", "5G", "20M", "HT", "1T", "108", "32",
+ "MKK", "5G", "20M", "HT", "1T", "108", "32",
+ "FCC", "5G", "20M", "HT", "1T", "112", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "112", "32",
+ "MKK", "5G", "20M", "HT", "1T", "112", "32",
+ "FCC", "5G", "20M", "HT", "1T", "116", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "116", "32",
+ "MKK", "5G", "20M", "HT", "1T", "116", "32",
+ "FCC", "5G", "20M", "HT", "1T", "120", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "120", "32",
+ "MKK", "5G", "20M", "HT", "1T", "120", "32",
+ "FCC", "5G", "20M", "HT", "1T", "124", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "124", "32",
+ "MKK", "5G", "20M", "HT", "1T", "124", "32",
+ "FCC", "5G", "20M", "HT", "1T", "128", "32",
+ "ETSI", "5G", "20M", "HT", "1T", "128", "32",
+ "MKK", "5G", "20M", "HT", "1T", "128", "32",
+ "FCC", "5G", "20M", "HT", "1T", "132", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "132", "32",
+ "MKK", "5G", "20M", "HT", "1T", "132", "32",
+ "FCC", "5G", "20M", "HT", "1T", "136", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "136", "32",
+ "MKK", "5G", "20M", "HT", "1T", "136", "32",
+ "FCC", "5G", "20M", "HT", "1T", "140", "28",
+ "ETSI", "5G", "20M", "HT", "1T", "140", "32",
+ "MKK", "5G", "20M", "HT", "1T", "140", "32",
+ "FCC", "5G", "20M", "HT", "1T", "149", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "149", "32",
+ "MKK", "5G", "20M", "HT", "1T", "149", "63",
+ "FCC", "5G", "20M", "HT", "1T", "153", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "153", "32",
+ "MKK", "5G", "20M", "HT", "1T", "153", "63",
+ "FCC", "5G", "20M", "HT", "1T", "157", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "157", "32",
+ "MKK", "5G", "20M", "HT", "1T", "157", "63",
+ "FCC", "5G", "20M", "HT", "1T", "161", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "161", "32",
+ "MKK", "5G", "20M", "HT", "1T", "161", "63",
+ "FCC", "5G", "20M", "HT", "1T", "165", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "165", "32",
+ "MKK", "5G", "20M", "HT", "1T", "165", "63",
+ "FCC", "5G", "20M", "HT", "2T", "36", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "36", "30",
+ "MKK", "5G", "20M", "HT", "2T", "36", "30",
+ "FCC", "5G", "20M", "HT", "2T", "40", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "40", "30",
+ "MKK", "5G", "20M", "HT", "2T", "40", "30",
+ "FCC", "5G", "20M", "HT", "2T", "44", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "44", "30",
+ "MKK", "5G", "20M", "HT", "2T", "44", "30",
+ "FCC", "5G", "20M", "HT", "2T", "48", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "48", "30",
+ "MKK", "5G", "20M", "HT", "2T", "48", "30",
+ "FCC", "5G", "20M", "HT", "2T", "52", "34",
+ "ETSI", "5G", "20M", "HT", "2T", "52", "30",
+ "MKK", "5G", "20M", "HT", "2T", "52", "30",
+ "FCC", "5G", "20M", "HT", "2T", "56", "32",
+ "ETSI", "5G", "20M", "HT", "2T", "56", "30",
+ "MKK", "5G", "20M", "HT", "2T", "56", "30",
+ "FCC", "5G", "20M", "HT", "2T", "60", "30",
+ "ETSI", "5G", "20M", "HT", "2T", "60", "30",
+ "MKK", "5G", "20M", "HT", "2T", "60", "30",
+ "FCC", "5G", "20M", "HT", "2T", "64", "26",
+ "ETSI", "5G", "20M", "HT", "2T", "64", "30",
+ "MKK", "5G", "20M", "HT", "2T", "64", "30",
+ "FCC", "5G", "20M", "HT", "2T", "100", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "100", "30",
+ "MKK", "5G", "20M", "HT", "2T", "100", "30",
+ "FCC", "5G", "20M", "HT", "2T", "114", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "114", "30",
+ "MKK", "5G", "20M", "HT", "2T", "114", "30",
+ "FCC", "5G", "20M", "HT", "2T", "108", "30",
+ "ETSI", "5G", "20M", "HT", "2T", "108", "30",
+ "MKK", "5G", "20M", "HT", "2T", "108", "30",
+ "FCC", "5G", "20M", "HT", "2T", "112", "32",
+ "ETSI", "5G", "20M", "HT", "2T", "112", "30",
+ "MKK", "5G", "20M", "HT", "2T", "112", "30",
+ "FCC", "5G", "20M", "HT", "2T", "116", "32",
+ "ETSI", "5G", "20M", "HT", "2T", "116", "30",
+ "MKK", "5G", "20M", "HT", "2T", "116", "30",
+ "FCC", "5G", "20M", "HT", "2T", "120", "34",
+ "ETSI", "5G", "20M", "HT", "2T", "120", "30",
+ "MKK", "5G", "20M", "HT", "2T", "120", "30",
+ "FCC", "5G", "20M", "HT", "2T", "124", "32",
+ "ETSI", "5G", "20M", "HT", "2T", "124", "30",
+ "MKK", "5G", "20M", "HT", "2T", "124", "30",
+ "FCC", "5G", "20M", "HT", "2T", "128", "30",
+ "ETSI", "5G", "20M", "HT", "2T", "128", "30",
+ "MKK", "5G", "20M", "HT", "2T", "128", "30",
+ "FCC", "5G", "20M", "HT", "2T", "132", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "132", "30",
+ "MKK", "5G", "20M", "HT", "2T", "132", "30",
+ "FCC", "5G", "20M", "HT", "2T", "136", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "136", "30",
+ "MKK", "5G", "20M", "HT", "2T", "136", "30",
+ "FCC", "5G", "20M", "HT", "2T", "140", "26",
+ "ETSI", "5G", "20M", "HT", "2T", "140", "30",
+ "MKK", "5G", "20M", "HT", "2T", "140", "30",
+ "FCC", "5G", "20M", "HT", "2T", "149", "34",
+ "ETSI", "5G", "20M", "HT", "2T", "149", "30",
+ "MKK", "5G", "20M", "HT", "2T", "149", "63",
+ "FCC", "5G", "20M", "HT", "2T", "153", "34",
+ "ETSI", "5G", "20M", "HT", "2T", "153", "30",
+ "MKK", "5G", "20M", "HT", "2T", "153", "63",
+ "FCC", "5G", "20M", "HT", "2T", "157", "34",
+ "ETSI", "5G", "20M", "HT", "2T", "157", "30",
+ "MKK", "5G", "20M", "HT", "2T", "157", "63",
+ "FCC", "5G", "20M", "HT", "2T", "161", "34",
+ "ETSI", "5G", "20M", "HT", "2T", "161", "30",
+ "MKK", "5G", "20M", "HT", "2T", "161", "63",
+ "FCC", "5G", "20M", "HT", "2T", "165", "34",
+ "ETSI", "5G", "20M", "HT", "2T", "165", "30",
+ "MKK", "5G", "20M", "HT", "2T", "165", "63",
+ "FCC", "5G", "40M", "HT", "1T", "38", "30",
+ "ETSI", "5G", "40M", "HT", "1T", "38", "32",
+ "MKK", "5G", "40M", "HT", "1T", "38", "32",
+ "FCC", "5G", "40M", "HT", "1T", "46", "30",
+ "ETSI", "5G", "40M", "HT", "1T", "46", "32",
+ "MKK", "5G", "40M", "HT", "1T", "46", "32",
+ "FCC", "5G", "40M", "HT", "1T", "54", "32",
+ "ETSI", "5G", "40M", "HT", "1T", "54", "32",
+ "MKK", "5G", "40M", "HT", "1T", "54", "32",
+ "FCC", "5G", "40M", "HT", "1T", "62", "32",
+ "ETSI", "5G", "40M", "HT", "1T", "62", "32",
+ "MKK", "5G", "40M", "HT", "1T", "62", "32",
+ "FCC", "5G", "40M", "HT", "1T", "102", "28",
+ "ETSI", "5G", "40M", "HT", "1T", "102", "32",
+ "MKK", "5G", "40M", "HT", "1T", "102", "32",
+ "FCC", "5G", "40M", "HT", "1T", "110", "32",
+ "ETSI", "5G", "40M", "HT", "1T", "110", "32",
+ "MKK", "5G", "40M", "HT", "1T", "110", "32",
+ "FCC", "5G", "40M", "HT", "1T", "118", "34",
+ "ETSI", "5G", "40M", "HT", "1T", "118", "32",
+ "MKK", "5G", "40M", "HT", "1T", "118", "32",
+ "FCC", "5G", "40M", "HT", "1T", "126", "34",
+ "ETSI", "5G", "40M", "HT", "1T", "126", "32",
+ "MKK", "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",
+ "FCC", "5G", "40M", "HT", "1T", "151", "34",
+ "ETSI", "5G", "40M", "HT", "1T", "151", "32",
+ "MKK", "5G", "40M", "HT", "1T", "151", "63",
+ "FCC", "5G", "40M", "HT", "1T", "159", "34",
+ "ETSI", "5G", "40M", "HT", "1T", "159", "32",
+ "MKK", "5G", "40M", "HT", "1T", "159", "63",
+ "FCC", "5G", "40M", "HT", "2T", "38", "28",
+ "ETSI", "5G", "40M", "HT", "2T", "38", "30",
+ "MKK", "5G", "40M", "HT", "2T", "38", "30",
+ "FCC", "5G", "40M", "HT", "2T", "46", "28",
+ "ETSI", "5G", "40M", "HT", "2T", "46", "30",
+ "MKK", "5G", "40M", "HT", "2T", "46", "30",
+ "FCC", "5G", "40M", "HT", "2T", "54", "30",
+ "ETSI", "5G", "40M", "HT", "2T", "54", "30",
+ "MKK", "5G", "40M", "HT", "2T", "54", "30",
+ "FCC", "5G", "40M", "HT", "2T", "62", "30",
+ "ETSI", "5G", "40M", "HT", "2T", "62", "30",
+ "MKK", "5G", "40M", "HT", "2T", "62", "30",
+ "FCC", "5G", "40M", "HT", "2T", "102", "26",
+ "ETSI", "5G", "40M", "HT", "2T", "102", "30",
+ "MKK", "5G", "40M", "HT", "2T", "102", "30",
+ "FCC", "5G", "40M", "HT", "2T", "110", "30",
+ "ETSI", "5G", "40M", "HT", "2T", "110", "30",
+ "MKK", "5G", "40M", "HT", "2T", "110", "30",
+ "FCC", "5G", "40M", "HT", "2T", "118", "34",
+ "ETSI", "5G", "40M", "HT", "2T", "118", "30",
+ "MKK", "5G", "40M", "HT", "2T", "118", "30",
+ "FCC", "5G", "40M", "HT", "2T", "126", "32",
+ "ETSI", "5G", "40M", "HT", "2T", "126", "30",
+ "MKK", "5G", "40M", "HT", "2T", "126", "30",
+ "FCC", "5G", "40M", "HT", "2T", "134", "30",
+ "ETSI", "5G", "40M", "HT", "2T", "134", "30",
+ "MKK", "5G", "40M", "HT", "2T", "134", "30",
+ "FCC", "5G", "40M", "HT", "2T", "151", "34",
+ "ETSI", "5G", "40M", "HT", "2T", "151", "30",
+ "MKK", "5G", "40M", "HT", "2T", "151", "63",
+ "FCC", "5G", "40M", "HT", "2T", "159", "34",
+ "ETSI", "5G", "40M", "HT", "2T", "159", "30",
+ "MKK", "5G", "40M", "HT", "2T", "159", "63",
+ "FCC", "5G", "80M", "VHT", "1T", "42", "30",
+ "ETSI", "5G", "80M", "VHT", "1T", "42", "32",
+ "MKK", "5G", "80M", "VHT", "1T", "42", "32",
+ "FCC", "5G", "80M", "VHT", "1T", "58", "28",
+ "ETSI", "5G", "80M", "VHT", "1T", "58", "32",
+ "MKK", "5G", "80M", "VHT", "1T", "58", "32",
+ "FCC", "5G", "80M", "VHT", "1T", "106", "30",
+ "ETSI", "5G", "80M", "VHT", "1T", "106", "32",
+ "MKK", "5G", "80M", "VHT", "1T", "106", "32",
+ "FCC", "5G", "80M", "VHT", "1T", "122", "34",
+ "ETSI", "5G", "80M", "VHT", "1T", "122", "32",
+ "MKK", "5G", "80M", "VHT", "1T", "122", "32",
+ "FCC", "5G", "80M", "VHT", "1T", "155", "34",
+ "ETSI", "5G", "80M", "VHT", "1T", "155", "32",
+ "MKK", "5G", "80M", "VHT", "1T", "155", "63",
+ "FCC", "5G", "80M", "VHT", "2T", "42", "28",
+ "ETSI", "5G", "80M", "VHT", "2T", "42", "30",
+ "MKK", "5G", "80M", "VHT", "2T", "42", "30",
+ "FCC", "5G", "80M", "VHT", "2T", "58", "26",
+ "ETSI", "5G", "80M", "VHT", "2T", "58", "30",
+ "MKK", "5G", "80M", "VHT", "2T", "58", "30",
+ "FCC", "5G", "80M", "VHT", "2T", "106", "28",
+ "ETSI", "5G", "80M", "VHT", "2T", "106", "30",
+ "MKK", "5G", "80M", "VHT", "2T", "106", "30",
+ "FCC", "5G", "80M", "VHT", "2T", "122", "32",
+ "ETSI", "5G", "80M", "VHT", "2T", "122", "30",
+ "MKK", "5G", "80M", "VHT", "2T", "122", "30",
+ "FCC", "5G", "80M", "VHT", "2T", "155", "34",
+ "ETSI", "5G", "80M", "VHT", "2T", "155", "30",
+ "MKK", "5G", "80M", "VHT", "2T", "155", "63"
+};
+
+void
+odm_read_and_config_mp_8188e_txpwr_lmt(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 i = 0;
+ u32 array_len = sizeof(array_mp_8188e_txpwr_lmt) / sizeof(u8 *);
+ u8 **array = (u8 **)array_mp_8188e_txpwr_lmt;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> odm_read_and_config_mp_8188e_txpwr_lmt\n"));
+
+ for (i = 0; i < array_len; i += 7) {
+ 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];
+
+ odm_config_bb_txpwr_lmt_8188e(p_dm_odm, regulation, band, bandwidth, rate, rf_path, chnl, val);
+ }
+
+}
+
+/******************************************************************************
+* TXPWR_LMT_88EE_M2_for_MSI.TXT
+******************************************************************************/
+
+static const char *array_mp_8188e_txpwr_lmt_88ee_m2_for_msi[] = {
+ "FCC", "2.4G", "20M", "CCK", "1T", "01", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "01", "28",
+ "MKK", "2.4G", "20M", "CCK", "1T", "01", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "02", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "02", "28",
+ "MKK", "2.4G", "20M", "CCK", "1T", "02", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "03", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "03", "28",
+ "MKK", "2.4G", "20M", "CCK", "1T", "03", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "04", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "04", "28",
+ "MKK", "2.4G", "20M", "CCK", "1T", "04", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "05", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "05", "28",
+ "MKK", "2.4G", "20M", "CCK", "1T", "05", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "06", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "06", "28",
+ "MKK", "2.4G", "20M", "CCK", "1T", "06", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "07", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "07", "28",
+ "MKK", "2.4G", "20M", "CCK", "1T", "07", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "08", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "08", "28",
+ "MKK", "2.4G", "20M", "CCK", "1T", "08", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "09", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "09", "28",
+ "MKK", "2.4G", "20M", "CCK", "1T", "09", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "10", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "10", "28",
+ "MKK", "2.4G", "20M", "CCK", "1T", "10", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "11", "32",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "11", "28",
+ "MKK", "2.4G", "20M", "CCK", "1T", "11", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "12", "63",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "12", "28",
+ "MKK", "2.4G", "20M", "CCK", "1T", "12", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "13", "63",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "13", "28",
+ "MKK", "2.4G", "20M", "CCK", "1T", "13", "32",
+ "FCC", "2.4G", "20M", "CCK", "1T", "14", "63",
+ "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63",
+ "MKK", "2.4G", "20M", "CCK", "1T", "14", "32",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "01", "28",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "01", "28",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "01", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "02", "28",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "02", "28",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "02", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "03", "30",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "03", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "04", "30",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "04", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "04", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "05", "30",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "05", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "05", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "06", "30",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "06", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "07", "30",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "07", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "07", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "08", "30",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "08", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "08", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "09", "28",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "09", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "10", "28",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "10", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "10", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "11", "28",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "11", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "11", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "12", "63",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "12", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "13", "63",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "13", "30",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "13", "30",
+ "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63",
+ "ETSI", "2.4G", "20M", "OFDM", "1T", "14", "63",
+ "MKK", "2.4G", "20M", "OFDM", "1T", "14", "63",
+ "FCC", "2.4G", "20M", "HT", "1T", "01", "28",
+ "ETSI", "2.4G", "20M", "HT", "1T", "01", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "01", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "02", "28",
+ "ETSI", "2.4G", "20M", "HT", "1T", "02", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "02", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "03", "30",
+ "ETSI", "2.4G", "20M", "HT", "1T", "03", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "03", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "04", "30",
+ "ETSI", "2.4G", "20M", "HT", "1T", "04", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "04", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "05", "30",
+ "ETSI", "2.4G", "20M", "HT", "1T", "05", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "05", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "06", "30",
+ "ETSI", "2.4G", "20M", "HT", "1T", "06", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "06", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "07", "30",
+ "ETSI", "2.4G", "20M", "HT", "1T", "07", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "07", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "08", "30",
+ "ETSI", "2.4G", "20M", "HT", "1T", "08", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "08", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "09", "28",
+ "ETSI", "2.4G", "20M", "HT", "1T", "09", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "09", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "10", "28",
+ "ETSI", "2.4G", "20M", "HT", "1T", "10", "30",
+ "MKK", "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", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "12", "63",
+ "ETSI", "2.4G", "20M", "HT", "1T", "12", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "12", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "13", "63",
+ "ETSI", "2.4G", "20M", "HT", "1T", "13", "30",
+ "MKK", "2.4G", "20M", "HT", "1T", "13", "30",
+ "FCC", "2.4G", "20M", "HT", "1T", "14", "63",
+ "ETSI", "2.4G", "20M", "HT", "1T", "14", "63",
+ "MKK", "2.4G", "20M", "HT", "1T", "14", "63",
+ "FCC", "2.4G", "20M", "HT", "2T", "01", "28",
+ "ETSI", "2.4G", "20M", "HT", "2T", "01", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "01", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "02", "28",
+ "ETSI", "2.4G", "20M", "HT", "2T", "02", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "02", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "03", "30",
+ "ETSI", "2.4G", "20M", "HT", "2T", "03", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "03", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "04", "30",
+ "ETSI", "2.4G", "20M", "HT", "2T", "04", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "04", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "05", "30",
+ "ETSI", "2.4G", "20M", "HT", "2T", "05", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "05", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "06", "30",
+ "ETSI", "2.4G", "20M", "HT", "2T", "06", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "06", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "07", "30",
+ "ETSI", "2.4G", "20M", "HT", "2T", "07", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "07", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "08", "30",
+ "ETSI", "2.4G", "20M", "HT", "2T", "08", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "08", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "09", "28",
+ "ETSI", "2.4G", "20M", "HT", "2T", "09", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "09", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "10", "28",
+ "ETSI", "2.4G", "20M", "HT", "2T", "10", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "10", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "11", "28",
+ "ETSI", "2.4G", "20M", "HT", "2T", "11", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "11", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "12", "63",
+ "ETSI", "2.4G", "20M", "HT", "2T", "12", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "12", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "13", "63",
+ "ETSI", "2.4G", "20M", "HT", "2T", "13", "30",
+ "MKK", "2.4G", "20M", "HT", "2T", "13", "30",
+ "FCC", "2.4G", "20M", "HT", "2T", "14", "63",
+ "ETSI", "2.4G", "20M", "HT", "2T", "14", "63",
+ "MKK", "2.4G", "20M", "HT", "2T", "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",
+ "FCC", "2.4G", "40M", "HT", "1T", "02", "63",
+ "ETSI", "2.4G", "40M", "HT", "1T", "02", "63",
+ "MKK", "2.4G", "40M", "HT", "1T", "02", "63",
+ "FCC", "2.4G", "40M", "HT", "1T", "03", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "03", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "03", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "04", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "04", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "04", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "05", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "05", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "05", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "06", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "06", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "06", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "07", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "07", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "07", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "08", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "08", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "08", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "09", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "09", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "09", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "10", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "10", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "10", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "11", "26",
+ "ETSI", "2.4G", "40M", "HT", "1T", "11", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "11", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "12", "63",
+ "ETSI", "2.4G", "40M", "HT", "1T", "12", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "12", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "13", "63",
+ "ETSI", "2.4G", "40M", "HT", "1T", "13", "26",
+ "MKK", "2.4G", "40M", "HT", "1T", "13", "26",
+ "FCC", "2.4G", "40M", "HT", "1T", "14", "63",
+ "ETSI", "2.4G", "40M", "HT", "1T", "14", "63",
+ "MKK", "2.4G", "40M", "HT", "1T", "14", "63",
+ "FCC", "2.4G", "40M", "HT", "2T", "01", "63",
+ "ETSI", "2.4G", "40M", "HT", "2T", "01", "63",
+ "MKK", "2.4G", "40M", "HT", "2T", "01", "63",
+ "FCC", "2.4G", "40M", "HT", "2T", "02", "63",
+ "ETSI", "2.4G", "40M", "HT", "2T", "02", "63",
+ "MKK", "2.4G", "40M", "HT", "2T", "02", "63",
+ "FCC", "2.4G", "40M", "HT", "2T", "03", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "03", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "03", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "04", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "04", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "04", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "05", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "05", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "05", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "06", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "06", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "06", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "07", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "07", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "07", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "08", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "08", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "08", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "09", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "09", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "09", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "10", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "10", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "10", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "11", "26",
+ "ETSI", "2.4G", "40M", "HT", "2T", "11", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "11", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "12", "63",
+ "ETSI", "2.4G", "40M", "HT", "2T", "12", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "12", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "13", "63",
+ "ETSI", "2.4G", "40M", "HT", "2T", "13", "26",
+ "MKK", "2.4G", "40M", "HT", "2T", "13", "26",
+ "FCC", "2.4G", "40M", "HT", "2T", "14", "63",
+ "ETSI", "2.4G", "40M", "HT", "2T", "14", "63",
+ "MKK", "2.4G", "40M", "HT", "2T", "14", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "36", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "36", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "36", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "40", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "40", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "40", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "44", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "44", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "44", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "48", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "48", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "48", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "52", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "52", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "52", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "56", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "56", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "56", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "60", "32",
+ "ETSI", "5G", "20M", "OFDM", "1T", "60", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "60", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "64", "28",
+ "ETSI", "5G", "20M", "OFDM", "1T", "64", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "64", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "100", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "100", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "100", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "114", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "114", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "114", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "108", "32",
+ "ETSI", "5G", "20M", "OFDM", "1T", "108", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "108", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "112", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "112", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "112", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "116", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "116", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "116", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "120", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "120", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "120", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "124", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "124", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "124", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "128", "32",
+ "ETSI", "5G", "20M", "OFDM", "1T", "128", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "128", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "132", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "132", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "132", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "136", "30",
+ "ETSI", "5G", "20M", "OFDM", "1T", "136", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "136", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "140", "28",
+ "ETSI", "5G", "20M", "OFDM", "1T", "140", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "140", "32",
+ "FCC", "5G", "20M", "OFDM", "1T", "149", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "149", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "149", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "153", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "153", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "153", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "157", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "157", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "157", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "161", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "161", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "161", "63",
+ "FCC", "5G", "20M", "OFDM", "1T", "165", "34",
+ "ETSI", "5G", "20M", "OFDM", "1T", "165", "32",
+ "MKK", "5G", "20M", "OFDM", "1T", "165", "63",
+ "FCC", "5G", "20M", "HT", "1T", "36", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "36", "32",
+ "MKK", "5G", "20M", "HT", "1T", "36", "32",
+ "FCC", "5G", "20M", "HT", "1T", "40", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "40", "32",
+ "MKK", "5G", "20M", "HT", "1T", "40", "32",
+ "FCC", "5G", "20M", "HT", "1T", "44", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "44", "32",
+ "MKK", "5G", "20M", "HT", "1T", "44", "32",
+ "FCC", "5G", "20M", "HT", "1T", "48", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "48", "32",
+ "MKK", "5G", "20M", "HT", "1T", "48", "32",
+ "FCC", "5G", "20M", "HT", "1T", "52", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "52", "32",
+ "MKK", "5G", "20M", "HT", "1T", "52", "32",
+ "FCC", "5G", "20M", "HT", "1T", "56", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "56", "32",
+ "MKK", "5G", "20M", "HT", "1T", "56", "32",
+ "FCC", "5G", "20M", "HT", "1T", "60", "32",
+ "ETSI", "5G", "20M", "HT", "1T", "60", "32",
+ "MKK", "5G", "20M", "HT", "1T", "60", "32",
+ "FCC", "5G", "20M", "HT", "1T", "64", "28",
+ "ETSI", "5G", "20M", "HT", "1T", "64", "32",
+ "MKK", "5G", "20M", "HT", "1T", "64", "32",
+ "FCC", "5G", "20M", "HT", "1T", "100", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "100", "32",
+ "MKK", "5G", "20M", "HT", "1T", "100", "32",
+ "FCC", "5G", "20M", "HT", "1T", "114", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "114", "32",
+ "MKK", "5G", "20M", "HT", "1T", "114", "32",
+ "FCC", "5G", "20M", "HT", "1T", "108", "32",
+ "ETSI", "5G", "20M", "HT", "1T", "108", "32",
+ "MKK", "5G", "20M", "HT", "1T", "108", "32",
+ "FCC", "5G", "20M", "HT", "1T", "112", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "112", "32",
+ "MKK", "5G", "20M", "HT", "1T", "112", "32",
+ "FCC", "5G", "20M", "HT", "1T", "116", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "116", "32",
+ "MKK", "5G", "20M", "HT", "1T", "116", "32",
+ "FCC", "5G", "20M", "HT", "1T", "120", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "120", "32",
+ "MKK", "5G", "20M", "HT", "1T", "120", "32",
+ "FCC", "5G", "20M", "HT", "1T", "124", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "124", "32",
+ "MKK", "5G", "20M", "HT", "1T", "124", "32",
+ "FCC", "5G", "20M", "HT", "1T", "128", "32",
+ "ETSI", "5G", "20M", "HT", "1T", "128", "32",
+ "MKK", "5G", "20M", "HT", "1T", "128", "32",
+ "FCC", "5G", "20M", "HT", "1T", "132", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "132", "32",
+ "MKK", "5G", "20M", "HT", "1T", "132", "32",
+ "FCC", "5G", "20M", "HT", "1T", "136", "30",
+ "ETSI", "5G", "20M", "HT", "1T", "136", "32",
+ "MKK", "5G", "20M", "HT", "1T", "136", "32",
+ "FCC", "5G", "20M", "HT", "1T", "140", "28",
+ "ETSI", "5G", "20M", "HT", "1T", "140", "32",
+ "MKK", "5G", "20M", "HT", "1T", "140", "32",
+ "FCC", "5G", "20M", "HT", "1T", "149", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "149", "32",
+ "MKK", "5G", "20M", "HT", "1T", "149", "63",
+ "FCC", "5G", "20M", "HT", "1T", "153", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "153", "32",
+ "MKK", "5G", "20M", "HT", "1T", "153", "63",
+ "FCC", "5G", "20M", "HT", "1T", "157", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "157", "32",
+ "MKK", "5G", "20M", "HT", "1T", "157", "63",
+ "FCC", "5G", "20M", "HT", "1T", "161", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "161", "32",
+ "MKK", "5G", "20M", "HT", "1T", "161", "63",
+ "FCC", "5G", "20M", "HT", "1T", "165", "34",
+ "ETSI", "5G", "20M", "HT", "1T", "165", "32",
+ "MKK", "5G", "20M", "HT", "1T", "165", "63",
+ "FCC", "5G", "20M", "HT", "2T", "36", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "36", "30",
+ "MKK", "5G", "20M", "HT", "2T", "36", "30",
+ "FCC", "5G", "20M", "HT", "2T", "40", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "40", "30",
+ "MKK", "5G", "20M", "HT", "2T", "40", "30",
+ "FCC", "5G", "20M", "HT", "2T", "44", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "44", "30",
+ "MKK", "5G", "20M", "HT", "2T", "44", "30",
+ "FCC", "5G", "20M", "HT", "2T", "48", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "48", "30",
+ "MKK", "5G", "20M", "HT", "2T", "48", "30",
+ "FCC", "5G", "20M", "HT", "2T", "52", "34",
+ "ETSI", "5G", "20M", "HT", "2T", "52", "30",
+ "MKK", "5G", "20M", "HT", "2T", "52", "30",
+ "FCC", "5G", "20M", "HT", "2T", "56", "32",
+ "ETSI", "5G", "20M", "HT", "2T", "56", "30",
+ "MKK", "5G", "20M", "HT", "2T", "56", "30",
+ "FCC", "5G", "20M", "HT", "2T", "60", "30",
+ "ETSI", "5G", "20M", "HT", "2T", "60", "30",
+ "MKK", "5G", "20M", "HT", "2T", "60", "30",
+ "FCC", "5G", "20M", "HT", "2T", "64", "26",
+ "ETSI", "5G", "20M", "HT", "2T", "64", "30",
+ "MKK", "5G", "20M", "HT", "2T", "64", "30",
+ "FCC", "5G", "20M", "HT", "2T", "100", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "100", "30",
+ "MKK", "5G", "20M", "HT", "2T", "100", "30",
+ "FCC", "5G", "20M", "HT", "2T", "114", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "114", "30",
+ "MKK", "5G", "20M", "HT", "2T", "114", "30",
+ "FCC", "5G", "20M", "HT", "2T", "108", "30",
+ "ETSI", "5G", "20M", "HT", "2T", "108", "30",
+ "MKK", "5G", "20M", "HT", "2T", "108", "30",
+ "FCC", "5G", "20M", "HT", "2T", "112", "32",
+ "ETSI", "5G", "20M", "HT", "2T", "112", "30",
+ "MKK", "5G", "20M", "HT", "2T", "112", "30",
+ "FCC", "5G", "20M", "HT", "2T", "116", "32",
+ "ETSI", "5G", "20M", "HT", "2T", "116", "30",
+ "MKK", "5G", "20M", "HT", "2T", "116", "30",
+ "FCC", "5G", "20M", "HT", "2T", "120", "34",
+ "ETSI", "5G", "20M", "HT", "2T", "120", "30",
+ "MKK", "5G", "20M", "HT", "2T", "120", "30",
+ "FCC", "5G", "20M", "HT", "2T", "124", "32",
+ "ETSI", "5G", "20M", "HT", "2T", "124", "30",
+ "MKK", "5G", "20M", "HT", "2T", "124", "30",
+ "FCC", "5G", "20M", "HT", "2T", "128", "30",
+ "ETSI", "5G", "20M", "HT", "2T", "128", "30",
+ "MKK", "5G", "20M", "HT", "2T", "128", "30",
+ "FCC", "5G", "20M", "HT", "2T", "132", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "132", "30",
+ "MKK", "5G", "20M", "HT", "2T", "132", "30",
+ "FCC", "5G", "20M", "HT", "2T", "136", "28",
+ "ETSI", "5G", "20M", "HT", "2T", "136", "30",
+ "MKK", "5G", "20M", "HT", "2T", "136", "30",
+ "FCC", "5G", "20M", "HT", "2T", "140", "26",
+ "ETSI", "5G", "20M", "HT", "2T", "140", "30",
+ "MKK", "5G", "20M", "HT", "2T", "140", "30",
+ "FCC", "5G", "20M", "HT", "2T", "149", "34",
+ "ETSI", "5G", "20M", "HT", "2T", "149", "30",
+ "MKK", "5G", "20M", "HT", "2T", "149", "63",
+ "FCC", "5G", "20M", "HT", "2T", "153", "34",
+ "ETSI", "5G", "20M", "HT", "2T", "153", "30",
+ "MKK", "5G", "20M", "HT", "2T", "153", "63",
+ "FCC", "5G", "20M", "HT", "2T", "157", "34",
+ "ETSI", "5G", "20M", "HT", "2T", "157", "30",
+ "MKK", "5G", "20M", "HT", "2T", "157", "63",
+ "FCC", "5G", "20M", "HT", "2T", "161", "34",
+ "ETSI", "5G", "20M", "HT", "2T", "161", "30",
+ "MKK", "5G", "20M", "HT", "2T", "161", "63",
+ "FCC", "5G", "20M", "HT", "2T", "165", "34",
+ "ETSI", "5G", "20M", "HT", "2T", "165", "30",
+ "MKK", "5G", "20M", "HT", "2T", "165", "63",
+ "FCC", "5G", "40M", "HT", "1T", "38", "30",
+ "ETSI", "5G", "40M", "HT", "1T", "38", "32",
+ "MKK", "5G", "40M", "HT", "1T", "38", "32",
+ "FCC", "5G", "40M", "HT", "1T", "46", "30",
+ "ETSI", "5G", "40M", "HT", "1T", "46", "32",
+ "MKK", "5G", "40M", "HT", "1T", "46", "32",
+ "FCC", "5G", "40M", "HT", "1T", "54", "32",
+ "ETSI", "5G", "40M", "HT", "1T", "54", "32",
+ "MKK", "5G", "40M", "HT", "1T", "54", "32",
+ "FCC", "5G", "40M", "HT", "1T", "62", "32",
+ "ETSI", "5G", "40M", "HT", "1T", "62", "32",
+ "MKK", "5G", "40M", "HT", "1T", "62", "32",
+ "FCC", "5G", "40M", "HT", "1T", "102", "28",
+ "ETSI", "5G", "40M", "HT", "1T", "102", "32",
+ "MKK", "5G", "40M", "HT", "1T", "102", "32",
+ "FCC", "5G", "40M", "HT", "1T", "110", "32",
+ "ETSI", "5G", "40M", "HT", "1T", "110", "32",
+ "MKK", "5G", "40M", "HT", "1T", "110", "32",
+ "FCC", "5G", "40M", "HT", "1T", "118", "34",
+ "ETSI", "5G", "40M", "HT", "1T", "118", "32",
+ "MKK", "5G", "40M", "HT", "1T", "118", "32",
+ "FCC", "5G", "40M", "HT", "1T", "126", "34",
+ "ETSI", "5G", "40M", "HT", "1T", "126", "32",
+ "MKK", "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",
+ "FCC", "5G", "40M", "HT", "1T", "151", "34",
+ "ETSI", "5G", "40M", "HT", "1T", "151", "32",
+ "MKK", "5G", "40M", "HT", "1T", "151", "63",
+ "FCC", "5G", "40M", "HT", "1T", "159", "34",
+ "ETSI", "5G", "40M", "HT", "1T", "159", "32",
+ "MKK", "5G", "40M", "HT", "1T", "159", "63",
+ "FCC", "5G", "40M", "HT", "2T", "38", "28",
+ "ETSI", "5G", "40M", "HT", "2T", "38", "30",
+ "MKK", "5G", "40M", "HT", "2T", "38", "30",
+ "FCC", "5G", "40M", "HT", "2T", "46", "28",
+ "ETSI", "5G", "40M", "HT", "2T", "46", "30",
+ "MKK", "5G", "40M", "HT", "2T", "46", "30",
+ "FCC", "5G", "40M", "HT", "2T", "54", "30",
+ "ETSI", "5G", "40M", "HT", "2T", "54", "30",
+ "MKK", "5G", "40M", "HT", "2T", "54", "30",
+ "FCC", "5G", "40M", "HT", "2T", "62", "30",
+ "ETSI", "5G", "40M", "HT", "2T", "62", "30",
+ "MKK", "5G", "40M", "HT", "2T", "62", "30",
+ "FCC", "5G", "40M", "HT", "2T", "102", "26",
+ "ETSI", "5G", "40M", "HT", "2T", "102", "30",
+ "MKK", "5G", "40M", "HT", "2T", "102", "30",
+ "FCC", "5G", "40M", "HT", "2T", "110", "30",
+ "ETSI", "5G", "40M", "HT", "2T", "110", "30",
+ "MKK", "5G", "40M", "HT", "2T", "110", "30",
+ "FCC", "5G", "40M", "HT", "2T", "118", "34",
+ "ETSI", "5G", "40M", "HT", "2T", "118", "30",
+ "MKK", "5G", "40M", "HT", "2T", "118", "30",
+ "FCC", "5G", "40M", "HT", "2T", "126", "32",
+ "ETSI", "5G", "40M", "HT", "2T", "126", "30",
+ "MKK", "5G", "40M", "HT", "2T", "126", "30",
+ "FCC", "5G", "40M", "HT", "2T", "134", "30",
+ "ETSI", "5G", "40M", "HT", "2T", "134", "30",
+ "MKK", "5G", "40M", "HT", "2T", "134", "30",
+ "FCC", "5G", "40M", "HT", "2T", "151", "34",
+ "ETSI", "5G", "40M", "HT", "2T", "151", "30",
+ "MKK", "5G", "40M", "HT", "2T", "151", "63",
+ "FCC", "5G", "40M", "HT", "2T", "159", "34",
+ "ETSI", "5G", "40M", "HT", "2T", "159", "30",
+ "MKK", "5G", "40M", "HT", "2T", "159", "63",
+ "FCC", "5G", "80M", "VHT", "1T", "42", "30",
+ "ETSI", "5G", "80M", "VHT", "1T", "42", "32",
+ "MKK", "5G", "80M", "VHT", "1T", "42", "32",
+ "FCC", "5G", "80M", "VHT", "1T", "58", "28",
+ "ETSI", "5G", "80M", "VHT", "1T", "58", "32",
+ "MKK", "5G", "80M", "VHT", "1T", "58", "32",
+ "FCC", "5G", "80M", "VHT", "1T", "106", "30",
+ "ETSI", "5G", "80M", "VHT", "1T", "106", "32",
+ "MKK", "5G", "80M", "VHT", "1T", "106", "32",
+ "FCC", "5G", "80M", "VHT", "1T", "122", "34",
+ "ETSI", "5G", "80M", "VHT", "1T", "122", "32",
+ "MKK", "5G", "80M", "VHT", "1T", "122", "32",
+ "FCC", "5G", "80M", "VHT", "1T", "155", "34",
+ "ETSI", "5G", "80M", "VHT", "1T", "155", "32",
+ "MKK", "5G", "80M", "VHT", "1T", "155", "63",
+ "FCC", "5G", "80M", "VHT", "2T", "42", "28",
+ "ETSI", "5G", "80M", "VHT", "2T", "42", "30",
+ "MKK", "5G", "80M", "VHT", "2T", "42", "30",
+ "FCC", "5G", "80M", "VHT", "2T", "58", "26",
+ "ETSI", "5G", "80M", "VHT", "2T", "58", "30",
+ "MKK", "5G", "80M", "VHT", "2T", "58", "30",
+ "FCC", "5G", "80M", "VHT", "2T", "106", "28",
+ "ETSI", "5G", "80M", "VHT", "2T", "106", "30",
+ "MKK", "5G", "80M", "VHT", "2T", "106", "30",
+ "FCC", "5G", "80M", "VHT", "2T", "122", "32",
+ "ETSI", "5G", "80M", "VHT", "2T", "122", "30",
+ "MKK", "5G", "80M", "VHT", "2T", "122", "30",
+ "FCC", "5G", "80M", "VHT", "2T", "155", "34",
+ "ETSI", "5G", "80M", "VHT", "2T", "155", "30",
+ "MKK", "5G", "80M", "VHT", "2T", "155", "63"
+};
+
+void
+odm_read_and_config_mp_8188e_txpwr_lmt_88e_e_m2_for_msi(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 i = 0;
+ u32 array_len = sizeof(array_mp_8188e_txpwr_lmt_88ee_m2_for_msi) / sizeof(u8 *);
+ u8 **array = (u8 **)array_mp_8188e_txpwr_lmt_88ee_m2_for_msi;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> odm_read_and_config_mp_8188e_txpwr_lmt_88e_e_m2_for_msi\n"));
+
+ for (i = 0; i < array_len; i += 7) {
+ 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];
+
+ odm_config_bb_txpwr_lmt_8188e(p_dm_odm, regulation, band, bandwidth, rate, rf_path, chnl, val);
+ }
+
+}
diff --git a/drivers/staging/rtl8188eu/hal/halhwimg8188e_rf.h b/drivers/staging/rtl8188eu/hal/halhwimg8188e_rf.h
new file mode 100644
index 000000000000..470d594d6c9e
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/halhwimg8188e_rf.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/*Image2HeaderVersion: 2.18*/
+#if (RTL8188E_SUPPORT == 1)
+#ifndef __INC_MP_RF_HW_IMG_8188E_H
+#define __INC_MP_RF_HW_IMG_8188E_H
+
+
+/******************************************************************************
+* RadioA.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_radioa(/* TC: Test Chip, MP: MP Chip*/
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+u32 odm_get_version_mp_8188e_radioa(void);
+
+/******************************************************************************
+* TxPowerTrack_AP.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_txpowertrack_ap(/* TC: Test Chip, MP: MP Chip*/
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+u32 odm_get_version_mp_8188e_txpowertrack_ap(void);
+
+/******************************************************************************
+* TxPowerTrack_PCIE.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_txpowertrack_pcie(/* TC: Test Chip, MP: MP Chip*/
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+u32 odm_get_version_mp_8188e_txpowertrack_pcie(void);
+
+/******************************************************************************
+* TxPowerTrack_PCIE_ICUT.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_txpowertrack_pcie_icut(/* TC: Test Chip, MP: MP Chip*/
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+u32 odm_get_version_mp_8188e_txpowertrack_pcie_icut(void);
+
+/******************************************************************************
+* TxPowerTrack_SDIO.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_txpowertrack_sdio(/* TC: Test Chip, MP: MP Chip*/
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+u32 odm_get_version_mp_8188e_txpowertrack_sdio(void);
+
+/******************************************************************************
+* TxPowerTrack_SDIO_ICUT.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_txpowertrack_sdio_icut(/* TC: Test Chip, MP: MP Chip*/
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+u32 odm_get_version_mp_8188e_txpowertrack_sdio_icut(void);
+
+/******************************************************************************
+* TxPowerTrack_USB.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_txpowertrack_usb(/* TC: Test Chip, MP: MP Chip*/
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+u32 odm_get_version_mp_8188e_txpowertrack_usb(void);
+
+/******************************************************************************
+* TxPowerTrack_USB_ICUT.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_txpowertrack_usb_icut(/* TC: Test Chip, MP: MP Chip*/
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+u32 odm_get_version_mp_8188e_txpowertrack_usb_icut(void);
+
+/******************************************************************************
+* TXPWR_LMT.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_txpwr_lmt(/* TC: Test Chip, MP: MP Chip*/
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+u32 odm_get_version_mp_8188e_txpwr_lmt(void);
+
+/******************************************************************************
+* TXPWR_LMT_88EE_M2_for_MSI.TXT
+******************************************************************************/
+
+void
+odm_read_and_config_mp_8188e_txpwr_lmt_88e_e_m2_for_msi(/* TC: Test Chip, MP: MP Chip*/
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+u32 odm_get_version_mp_8188e_txpwr_lmt_88ee_m2_for_msi(void);
+
+#endif
+#endif /* end of HWIMG_SUPPORT*/
diff --git a/drivers/staging/rtl8188eu/hal/halphyrf_8188e_ce.c b/drivers/staging/rtl8188eu/hal/halphyrf_8188e_ce.c
new file mode 100644
index 000000000000..326d9762a15e
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/halphyrf_8188e_ce.c
@@ -0,0 +1,1973 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+/*---------------------------Define Local Constant---------------------------*/
+/* 2010/04/25 MH Define the max tx power tracking tx agc power. */
+#define ODM_TXPWRTRACK_MAX_IDX_88E 6
+
+/*---------------------------Define Local Constant---------------------------*/
+
+/* 3============================================================
+ * 3 Tx Power Tracking
+ * 3============================================================ */
+
+static void set_iqk_matrix_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 OFDM_index,
+ u8 rf_path,
+ s32 iqk_result_x,
+ s32 iqk_result_y
+)
+{
+ s32 ele_A = 0, ele_D, ele_C = 0, value32;
+
+ ele_D = (ofdm_swing_table_new[OFDM_index] & 0xFFC00000) >> 22;
+
+ /* new element A = element D x X */
+ if ((iqk_result_x != 0) && (*(p_dm_odm->p_band_type) == ODM_BAND_2_4G)) {
+ if ((iqk_result_x & 0x00000200) != 0) /* consider minus */
+ iqk_result_x = iqk_result_x | 0xFFFFFC00;
+ ele_A = ((iqk_result_x * ele_D) >> 8) & 0x000003FF;
+
+ /* new element C = element D x Y */
+ if ((iqk_result_y & 0x00000200) != 0)
+ iqk_result_y = iqk_result_y | 0xFFFFFC00;
+ ele_C = ((iqk_result_y * ele_D) >> 8) & 0x000003FF;
+
+ /* if (rf_path == ODM_RF_PATH_A) */
+ switch (rf_path) {
+ case ODM_RF_PATH_A:
+ /* wirte new elements A, C, D to regC80 and regC94, element B is always 0 */
+ value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A;
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XA_TX_IQ_IMBALANCE, MASKDWORD, value32);
+
+ value32 = (ele_C & 0x000003C0) >> 6;
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XC_TX_AFE, MASKH4BITS, value32);
+
+ value32 = ((iqk_result_x * ele_D) >> 7) & 0x01;
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_ECCA_THRESHOLD, BIT(24), value32);
+ break;
+ case ODM_RF_PATH_B:
+ /* wirte new elements A, C, D to regC88 and regC9C, element B is always 0 */
+ value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A;
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XB_TX_IQ_IMBALANCE, MASKDWORD, value32);
+
+ value32 = (ele_C & 0x000003C0) >> 6;
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XD_TX_AFE, MASKH4BITS, value32);
+
+ value32 = ((iqk_result_x * ele_D) >> 7) & 0x01;
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_ECCA_THRESHOLD, BIT(28), value32);
+
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (rf_path) {
+ case ODM_RF_PATH_A:
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XA_TX_IQ_IMBALANCE, MASKDWORD, ofdm_swing_table_new[OFDM_index]);
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XC_TX_AFE, MASKH4BITS, 0x00);
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_ECCA_THRESHOLD, BIT(24), 0x00);
+ break;
+
+ case ODM_RF_PATH_B:
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XB_TX_IQ_IMBALANCE, MASKDWORD, ofdm_swing_table_new[OFDM_index]);
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XD_TX_AFE, MASKH4BITS, 0x00);
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_ECCA_THRESHOLD, BIT(28), 0x00);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("TxPwrTracking path B: X = 0x%x, Y = 0x%x ele_A = 0x%x ele_C = 0x%x ele_D = 0x%x 0xeb4 = 0x%x 0xebc = 0x%x\n",
+ (u32)iqk_result_x, (u32)iqk_result_y, (u32)ele_A, (u32)ele_C, (u32)ele_D, (u32)iqk_result_x, (u32)iqk_result_y));
+}
+
+void do_iqk_8188e(
+ void *p_dm_void,
+ u8 delta_thermal_index,
+ u8 thermal_value,
+ u8 threshold
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
+
+ odm_reset_iqk_result(p_dm_odm);
+
+ p_dm_odm->rf_calibrate_info.thermal_value_iqk = thermal_value;
+ phy_iq_calibrate_8188e(adapter, false);
+}
+
+/*-----------------------------------------------------------------------------
+ * Function: odm_TxPwrTrackSetPwr88E()
+ *
+ * Overview: 88E change all channel tx power accordign to flag.
+ * OFDM & CCK are all different.
+ *
+ * Input: NONE
+ *
+ * Output: NONE
+ *
+ * Return: NONE
+ *
+ * Revised History:
+ * When Who Remark
+ * 04/23/2012 MHC Create version 0.
+ *
+ *---------------------------------------------------------------------------*/
+void
+odm_tx_pwr_track_set_pwr88_e(
+ void *p_dm_void,
+ enum pwrtrack_method method,
+ u8 rf_path,
+ u8 channel_mapped_index
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ PHAL_DATA_TYPE p_hal_data = GET_HAL_DATA(adapter);
+ u8 pwr_tracking_limit_ofdm = 30; /* +0dB */
+ u8 pwr_tracking_limit_cck = 28; /* -2dB */
+ u8 tx_rate = 0xFF;
+ u8 final_ofdm_swing_index = 0;
+ u8 final_cck_swing_index = 0;
+ u8 i = 0;
+ struct odm_rf_calibration_structure *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
+
+ if (p_dm_odm->mp_mode == true) {
+ PMPT_CONTEXT p_mpt_ctx = &(adapter->mppriv.mpt_ctx);
+
+ tx_rate = mpt_to_mgnt_rate(p_mpt_ctx->mpt_rate_index);
+ } else {
+ u16 rate = *(p_dm_odm->p_forced_data_rate);
+
+ if (!rate) { /*auto rate*/
+ if (rate != 0xFF) {
+ if (p_dm_odm->number_linked_client != 0)
+ tx_rate = hw_rate_to_m_rate(p_dm_odm->tx_rate);
+ }
+ } else /*force rate*/
+ tx_rate = (u8)rate;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("Power Tracking tx_rate=0x%X\n", tx_rate));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("===>ODM_TxPwrTrackSetPwr8188E\n"));
+
+ if (tx_rate != 0xFF) {
+ /* 2 CCK */
+ if (((tx_rate >= MGN_1M) && (tx_rate <= MGN_5_5M)) || (tx_rate == MGN_11M))
+ pwr_tracking_limit_cck = 28; /* -2dB */
+ /* 2 OFDM */
+ else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M))
+ pwr_tracking_limit_ofdm = 36; /* +3dB */
+ else if (tx_rate == MGN_54M)
+ pwr_tracking_limit_ofdm = 34; /* +2dB */
+
+ /* 2 HT */
+ else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2)) /* QPSK/BPSK */
+ pwr_tracking_limit_ofdm = 38; /* +4dB */
+ else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4)) /* 16QAM */
+ pwr_tracking_limit_ofdm = 36; /* +3dB */
+ else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7)) /* 64QAM */
+ pwr_tracking_limit_ofdm = 34; /* +2dB */
+
+ else
+ pwr_tracking_limit_ofdm = p_rf_calibrate_info->default_ofdm_index; /*Default OFDM index = 30*/
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("tx_rate=0x%x, pwr_tracking_limit=%d\n", tx_rate, pwr_tracking_limit_ofdm));
+
+ if (method == TXAGC) {
+ u32 pwr = 0, tx_agc = 0;
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+
+ p_rf_calibrate_info->remnant_ofdm_swing_idx[rf_path] = p_rf_calibrate_info->absolute_ofdm_swing_idx[rf_path]; /*Remnant index equal to aboslute compensate value.*/
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("odm_TxPwrTrackSetPwr88E CH=%d\n", *(p_dm_odm->p_channel)));
+
+ if (p_dm_odm->mp_mode == true) {
+ pwr = phy_query_bb_reg(adapter, REG_TX_AGC_A_RATE18_06, 0xFF);
+ pwr += p_dm_odm->rf_calibrate_info.power_index_offset[ODM_RF_PATH_A];
+ phy_set_bb_reg(adapter, REG_TX_AGC_A_CCK_1_MCS32, MASKBYTE1, pwr);
+ tx_agc = (pwr << 16) | (pwr << 8) | (pwr);
+ phy_set_bb_reg(adapter, REG_TX_AGC_B_CCK_11_A_CCK_2_11, MASKH3BYTES, tx_agc);
+ /* RT_DISP(FPHY, PHY_TXPWR, ("odm_tx_pwr_track_set_pwr88_e: CCK Tx-rf(A) Power = 0x%x\n", tx_agc)); */
+
+ pwr = phy_query_bb_reg(adapter, REG_TX_AGC_A_RATE18_06, 0xFF);
+ pwr += (p_rf_calibrate_info->bb_swing_idx_ofdm[ODM_RF_PATH_A] - p_rf_calibrate_info->bb_swing_idx_ofdm_base[RF_PATH_A]);
+ tx_agc |= ((pwr << 24) | (pwr << 16) | (pwr << 8) | pwr);
+ phy_set_bb_reg(adapter, REG_TX_AGC_A_RATE18_06, MASKDWORD, tx_agc);
+ phy_set_bb_reg(adapter, REG_TX_AGC_A_RATE54_24, MASKDWORD, tx_agc);
+ phy_set_bb_reg(adapter, REG_TX_AGC_A_MCS03_MCS00, MASKDWORD, tx_agc);
+ phy_set_bb_reg(adapter, REG_TX_AGC_A_MCS07_MCS04, MASKDWORD, tx_agc);
+ phy_set_bb_reg(adapter, REG_TX_AGC_A_MCS11_MCS08, MASKDWORD, tx_agc);
+ phy_set_bb_reg(adapter, REG_TX_AGC_A_MCS15_MCS12, MASKDWORD, tx_agc);
+ /* RT_DISP(FPHY, PHY_TXPWR, ("odm_tx_pwr_track_set_pwr88_e: OFDM Tx-rf(A) Power = 0x%x\n", tx_agc)); */
+ } else {
+ /* phy_set_tx_power_level8188e(p_dm_odm->adapter, *p_dm_odm->p_channel); */
+ p_rf_calibrate_info->modify_tx_agc_flag_path_a = true;
+ p_rf_calibrate_info->modify_tx_agc_flag_path_a_cck = true;
+
+ if (rf_path == ODM_RF_PATH_A) {
+ phy_set_tx_power_index_by_rate_section(adapter, ODM_RF_PATH_A, *p_dm_odm->p_channel, CCK);
+ phy_set_tx_power_index_by_rate_section(adapter, ODM_RF_PATH_A, *p_dm_odm->p_channel, OFDM);
+ phy_set_tx_power_index_by_rate_section(adapter, ODM_RF_PATH_A, *p_dm_odm->p_channel, HT_MCS0_MCS7);
+ }
+ }
+ } else if (method == BBSWING) {
+ final_ofdm_swing_index = p_rf_calibrate_info->default_ofdm_index + p_rf_calibrate_info->absolute_ofdm_swing_idx[rf_path];
+ final_cck_swing_index = p_rf_calibrate_info->default_cck_index + p_rf_calibrate_info->absolute_ofdm_swing_idx[rf_path];
+
+ if (final_ofdm_swing_index >= pwr_tracking_limit_ofdm)
+ final_ofdm_swing_index = pwr_tracking_limit_ofdm;
+ else if (final_ofdm_swing_index <= 0)
+ final_ofdm_swing_index = 0;
+
+ if (final_cck_swing_index >= CCK_TABLE_SIZE)
+ final_cck_swing_index = CCK_TABLE_SIZE - 1;
+ else if (p_rf_calibrate_info->bb_swing_idx_cck <= 0)
+ final_cck_swing_index = 0;
+
+ /* Adjust BB swing by OFDM IQ matrix */
+ if (rf_path == ODM_RF_PATH_A) {
+ set_iqk_matrix_8188e(p_dm_odm, final_ofdm_swing_index, ODM_RF_PATH_A,
+ p_dm_odm->rf_calibrate_info.iqk_matrix_reg_setting[channel_mapped_index].value[0][0],
+ p_dm_odm->rf_calibrate_info.iqk_matrix_reg_setting[channel_mapped_index].value[0][1]);
+ /* Adjust BB swing by CCK filter coefficient */
+ if (!p_dm_odm->rf_calibrate_info.is_cck_in_ch14) {
+ odm_write_1byte(p_dm_odm, 0xa22, cck_swing_table_ch1_ch13_new[final_cck_swing_index][0]);
+ odm_write_1byte(p_dm_odm, 0xa23, cck_swing_table_ch1_ch13_new[final_cck_swing_index][1]);
+ odm_write_1byte(p_dm_odm, 0xa24, cck_swing_table_ch1_ch13_new[final_cck_swing_index][2]);
+ odm_write_1byte(p_dm_odm, 0xa25, cck_swing_table_ch1_ch13_new[final_cck_swing_index][3]);
+ odm_write_1byte(p_dm_odm, 0xa26, cck_swing_table_ch1_ch13_new[final_cck_swing_index][4]);
+ odm_write_1byte(p_dm_odm, 0xa27, cck_swing_table_ch1_ch13_new[final_cck_swing_index][5]);
+ odm_write_1byte(p_dm_odm, 0xa28, cck_swing_table_ch1_ch13_new[final_cck_swing_index][6]);
+ odm_write_1byte(p_dm_odm, 0xa29, cck_swing_table_ch1_ch13_new[final_cck_swing_index][7]);
+ } else {
+ odm_write_1byte(p_dm_odm, 0xa22, cck_swing_table_ch14_new[final_cck_swing_index][0]);
+ odm_write_1byte(p_dm_odm, 0xa23, cck_swing_table_ch14_new[final_cck_swing_index][1]);
+ odm_write_1byte(p_dm_odm, 0xa24, cck_swing_table_ch14_new[final_cck_swing_index][2]);
+ odm_write_1byte(p_dm_odm, 0xa25, cck_swing_table_ch14_new[final_cck_swing_index][3]);
+ odm_write_1byte(p_dm_odm, 0xa26, cck_swing_table_ch14_new[final_cck_swing_index][4]);
+ odm_write_1byte(p_dm_odm, 0xa27, cck_swing_table_ch14_new[final_cck_swing_index][5]);
+ odm_write_1byte(p_dm_odm, 0xa28, cck_swing_table_ch14_new[final_cck_swing_index][6]);
+ odm_write_1byte(p_dm_odm, 0xa29, cck_swing_table_ch14_new[final_cck_swing_index][7]);
+ }
+ }
+ } else if (method == MIX_MODE) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("p_rf_calibrate_info->default_ofdm_index=%d, p_dm_odm->DefaultCCKIndex=%d, p_rf_calibrate_info->absolute_ofdm_swing_idx[rf_path]=%d, rf_path = %d\n",
+ p_rf_calibrate_info->default_ofdm_index, p_rf_calibrate_info->default_cck_index, p_rf_calibrate_info->absolute_ofdm_swing_idx[rf_path], rf_path));
+
+ final_cck_swing_index = p_rf_calibrate_info->default_cck_index + p_rf_calibrate_info->absolute_ofdm_swing_idx[rf_path];
+ final_ofdm_swing_index = p_rf_calibrate_info->default_ofdm_index + p_rf_calibrate_info->absolute_ofdm_swing_idx[rf_path];
+
+ if (final_ofdm_swing_index > pwr_tracking_limit_ofdm) { /* BBSwing higher then Limit */
+ p_rf_calibrate_info->remnant_ofdm_swing_idx[rf_path] = final_ofdm_swing_index - pwr_tracking_limit_ofdm;
+
+ set_iqk_matrix_8188e(p_dm_odm, pwr_tracking_limit_ofdm, ODM_RF_PATH_A,
+ p_dm_odm->rf_calibrate_info.iqk_matrix_reg_setting[channel_mapped_index].value[0][0],
+ p_dm_odm->rf_calibrate_info.iqk_matrix_reg_setting[channel_mapped_index].value[0][1]);
+
+ p_rf_calibrate_info->modify_tx_agc_flag_path_a = true;
+
+ phy_set_tx_power_index_by_rate_section(adapter, ODM_RF_PATH_A, *p_dm_odm->p_channel, OFDM);
+ phy_set_tx_power_index_by_rate_section(adapter, ODM_RF_PATH_A, *p_dm_odm->p_channel, HT_MCS0_MCS7);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("******Path_A Over BBSwing Limit, pwr_tracking_limit = %d, Remnant tx_agc value = %d\n", pwr_tracking_limit_ofdm, p_rf_calibrate_info->remnant_ofdm_swing_idx[rf_path]));
+ } else if (final_ofdm_swing_index <= 0) {
+ p_rf_calibrate_info->remnant_ofdm_swing_idx[rf_path] = final_ofdm_swing_index;
+
+ set_iqk_matrix_8188e(p_dm_odm, 0, ODM_RF_PATH_A,
+ p_dm_odm->rf_calibrate_info.iqk_matrix_reg_setting[channel_mapped_index].value[0][0],
+ p_dm_odm->rf_calibrate_info.iqk_matrix_reg_setting[channel_mapped_index].value[0][1]);
+
+ p_rf_calibrate_info->modify_tx_agc_flag_path_a = true;
+
+ phy_set_tx_power_index_by_rate_section(adapter, ODM_RF_PATH_A, *p_dm_odm->p_channel, OFDM);
+ phy_set_tx_power_index_by_rate_section(adapter, ODM_RF_PATH_A, *p_dm_odm->p_channel, HT_MCS0_MCS7);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("******Path_A Lower then BBSwing lower bound 0, Remnant tx_agc value = %d\n", p_rf_calibrate_info->remnant_ofdm_swing_idx[rf_path]));
+ } else {
+ set_iqk_matrix_8188e(p_dm_odm, final_ofdm_swing_index, ODM_RF_PATH_A,
+ p_dm_odm->rf_calibrate_info.iqk_matrix_reg_setting[channel_mapped_index].value[0][0],
+ p_dm_odm->rf_calibrate_info.iqk_matrix_reg_setting[channel_mapped_index].value[0][1]);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("******Path_A Compensate with BBSwing, final_ofdm_swing_index = %d\n", final_ofdm_swing_index));
+
+ if (p_rf_calibrate_info->modify_tx_agc_flag_path_a) { /*If tx_agc has changed, reset tx_agc again*/
+ p_rf_calibrate_info->remnant_ofdm_swing_idx[rf_path] = 0;
+
+ phy_set_tx_power_index_by_rate_section(adapter, ODM_RF_PATH_A, *p_dm_odm->p_channel, OFDM);
+ phy_set_tx_power_index_by_rate_section(adapter, ODM_RF_PATH_A, *p_dm_odm->p_channel, HT_MCS0_MCS7);
+
+ p_rf_calibrate_info->modify_tx_agc_flag_path_a = false;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("******Path_A p_dm_odm->Modify_TxAGC_Flag = false\n"));
+ }
+ }
+
+ if (final_cck_swing_index > pwr_tracking_limit_cck) {
+ p_rf_calibrate_info->remnant_cck_swing_idx = final_cck_swing_index - pwr_tracking_limit_cck;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("******Path_A CCK Over Limit, pwr_tracking_limit_cck = %d, p_rf_calibrate_info->remnant_cck_swing_idx = %d\n", pwr_tracking_limit_cck, p_rf_calibrate_info->remnant_cck_swing_idx));
+
+ /* Adjust BB swing by CCK filter coefficient */
+
+ if (!p_dm_odm->rf_calibrate_info.is_cck_in_ch14) {
+ odm_write_1byte(p_dm_odm, 0xa22, cck_swing_table_ch1_ch13_new[pwr_tracking_limit_cck][0]);
+ odm_write_1byte(p_dm_odm, 0xa23, cck_swing_table_ch1_ch13_new[pwr_tracking_limit_cck][1]);
+ odm_write_1byte(p_dm_odm, 0xa24, cck_swing_table_ch1_ch13_new[pwr_tracking_limit_cck][2]);
+ odm_write_1byte(p_dm_odm, 0xa25, cck_swing_table_ch1_ch13_new[pwr_tracking_limit_cck][3]);
+ odm_write_1byte(p_dm_odm, 0xa26, cck_swing_table_ch1_ch13_new[pwr_tracking_limit_cck][4]);
+ odm_write_1byte(p_dm_odm, 0xa27, cck_swing_table_ch1_ch13_new[pwr_tracking_limit_cck][5]);
+ odm_write_1byte(p_dm_odm, 0xa28, cck_swing_table_ch1_ch13_new[pwr_tracking_limit_cck][6]);
+ odm_write_1byte(p_dm_odm, 0xa29, cck_swing_table_ch1_ch13_new[pwr_tracking_limit_cck][7]);
+ } else {
+ odm_write_1byte(p_dm_odm, 0xa22, cck_swing_table_ch14_new[pwr_tracking_limit_cck][0]);
+ odm_write_1byte(p_dm_odm, 0xa23, cck_swing_table_ch14_new[pwr_tracking_limit_cck][1]);
+ odm_write_1byte(p_dm_odm, 0xa24, cck_swing_table_ch14_new[pwr_tracking_limit_cck][2]);
+ odm_write_1byte(p_dm_odm, 0xa25, cck_swing_table_ch14_new[pwr_tracking_limit_cck][3]);
+ odm_write_1byte(p_dm_odm, 0xa26, cck_swing_table_ch14_new[pwr_tracking_limit_cck][4]);
+ odm_write_1byte(p_dm_odm, 0xa27, cck_swing_table_ch14_new[pwr_tracking_limit_cck][5]);
+ odm_write_1byte(p_dm_odm, 0xa28, cck_swing_table_ch14_new[pwr_tracking_limit_cck][6]);
+ odm_write_1byte(p_dm_odm, 0xa29, cck_swing_table_ch14_new[pwr_tracking_limit_cck][7]);
+ }
+
+ p_rf_calibrate_info->modify_tx_agc_flag_path_a_cck = true;
+
+ phy_set_tx_power_index_by_rate_section(adapter, ODM_RF_PATH_A, *p_dm_odm->p_channel, CCK);
+
+ } else if (final_cck_swing_index <= 0) { /* Lowest CCK index = 0 */
+ p_rf_calibrate_info->remnant_cck_swing_idx = final_cck_swing_index;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("******Path_A CCK Under Limit, pwr_tracking_limit_cck = %d, p_rf_calibrate_info->remnant_cck_swing_idx = %d\n", 0, p_rf_calibrate_info->remnant_cck_swing_idx));
+
+ if (!p_dm_odm->rf_calibrate_info.is_cck_in_ch14) {
+ odm_write_1byte(p_dm_odm, 0xa22, cck_swing_table_ch1_ch13_new[0][0]);
+ odm_write_1byte(p_dm_odm, 0xa23, cck_swing_table_ch1_ch13_new[0][1]);
+ odm_write_1byte(p_dm_odm, 0xa24, cck_swing_table_ch1_ch13_new[0][2]);
+ odm_write_1byte(p_dm_odm, 0xa25, cck_swing_table_ch1_ch13_new[0][3]);
+ odm_write_1byte(p_dm_odm, 0xa26, cck_swing_table_ch1_ch13_new[0][4]);
+ odm_write_1byte(p_dm_odm, 0xa27, cck_swing_table_ch1_ch13_new[0][5]);
+ odm_write_1byte(p_dm_odm, 0xa28, cck_swing_table_ch1_ch13_new[0][6]);
+ odm_write_1byte(p_dm_odm, 0xa29, cck_swing_table_ch1_ch13_new[0][7]);
+ } else {
+ odm_write_1byte(p_dm_odm, 0xa22, cck_swing_table_ch14_new[0][0]);
+ odm_write_1byte(p_dm_odm, 0xa23, cck_swing_table_ch14_new[0][1]);
+ odm_write_1byte(p_dm_odm, 0xa24, cck_swing_table_ch14_new[0][2]);
+ odm_write_1byte(p_dm_odm, 0xa25, cck_swing_table_ch14_new[0][3]);
+ odm_write_1byte(p_dm_odm, 0xa26, cck_swing_table_ch14_new[0][4]);
+ odm_write_1byte(p_dm_odm, 0xa27, cck_swing_table_ch14_new[0][5]);
+ odm_write_1byte(p_dm_odm, 0xa28, cck_swing_table_ch14_new[0][6]);
+ odm_write_1byte(p_dm_odm, 0xa29, cck_swing_table_ch14_new[0][7]);
+ }
+
+ p_rf_calibrate_info->modify_tx_agc_flag_path_a_cck = true;
+
+ phy_set_tx_power_index_by_rate_section(adapter, ODM_RF_PATH_A, *p_dm_odm->p_channel, CCK);
+
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("******Path_A CCK Compensate with BBSwing, final_cck_swing_index = %d\n", final_cck_swing_index));
+
+ if (!p_dm_odm->rf_calibrate_info.is_cck_in_ch14) {
+ odm_write_1byte(p_dm_odm, 0xa22, cck_swing_table_ch1_ch13_new[final_cck_swing_index][0]);
+ odm_write_1byte(p_dm_odm, 0xa23, cck_swing_table_ch1_ch13_new[final_cck_swing_index][1]);
+ odm_write_1byte(p_dm_odm, 0xa24, cck_swing_table_ch1_ch13_new[final_cck_swing_index][2]);
+ odm_write_1byte(p_dm_odm, 0xa25, cck_swing_table_ch1_ch13_new[final_cck_swing_index][3]);
+ odm_write_1byte(p_dm_odm, 0xa26, cck_swing_table_ch1_ch13_new[final_cck_swing_index][4]);
+ odm_write_1byte(p_dm_odm, 0xa27, cck_swing_table_ch1_ch13_new[final_cck_swing_index][5]);
+ odm_write_1byte(p_dm_odm, 0xa28, cck_swing_table_ch1_ch13_new[final_cck_swing_index][6]);
+ odm_write_1byte(p_dm_odm, 0xa29, cck_swing_table_ch1_ch13_new[final_cck_swing_index][7]);
+ } else {
+ odm_write_1byte(p_dm_odm, 0xa22, cck_swing_table_ch14_new[final_cck_swing_index][0]);
+ odm_write_1byte(p_dm_odm, 0xa23, cck_swing_table_ch14_new[final_cck_swing_index][1]);
+ odm_write_1byte(p_dm_odm, 0xa24, cck_swing_table_ch14_new[final_cck_swing_index][2]);
+ odm_write_1byte(p_dm_odm, 0xa25, cck_swing_table_ch14_new[final_cck_swing_index][3]);
+ odm_write_1byte(p_dm_odm, 0xa26, cck_swing_table_ch14_new[final_cck_swing_index][4]);
+ odm_write_1byte(p_dm_odm, 0xa27, cck_swing_table_ch14_new[final_cck_swing_index][5]);
+ odm_write_1byte(p_dm_odm, 0xa28, cck_swing_table_ch14_new[final_cck_swing_index][6]);
+ odm_write_1byte(p_dm_odm, 0xa29, cck_swing_table_ch14_new[final_cck_swing_index][7]);
+ }
+
+ if (p_rf_calibrate_info->modify_tx_agc_flag_path_a_cck) { /*If tx_agc has changed, reset tx_agc again*/
+ p_rf_calibrate_info->remnant_cck_swing_idx = 0;
+ phy_set_tx_power_index_by_rate_section(adapter, ODM_RF_PATH_A, *p_dm_odm->p_channel, CCK);
+ p_rf_calibrate_info->modify_tx_agc_flag_path_a_cck = false;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("******Path_A p_dm_odm->Modify_TxAGC_Flag_CCK = false\n"));
+ }
+ }
+ } else
+ return;
+} /* odm_TxPwrTrackSetPwr88E */
+
+void
+get_delta_swing_table_8188e(
+ void *p_dm_void,
+ u8 **temperature_up_a,
+ u8 **temperature_down_a,
+ u8 **temperature_up_b,
+ u8 **temperature_down_b
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ PHAL_DATA_TYPE p_hal_data = GET_HAL_DATA(adapter);
+ struct odm_rf_calibration_structure *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
+
+ u8 tx_rate = 0xFF;
+ u8 channel = *p_dm_odm->p_channel;
+
+ if (p_dm_odm->mp_mode == true) {
+ PMPT_CONTEXT p_mpt_ctx = &(adapter->mppriv.mpt_ctx);
+
+ tx_rate = mpt_to_mgnt_rate(p_mpt_ctx->mpt_rate_index);
+ } else {
+ u16 rate = *(p_dm_odm->p_forced_data_rate);
+
+ if (!rate) { /*auto rate*/
+ if (rate != 0xFF) {
+ if (p_dm_odm->number_linked_client != 0)
+ tx_rate = hw_rate_to_m_rate(p_dm_odm->tx_rate);
+ }
+ } else /*force rate*/
+ tx_rate = (u8)rate;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("Power Tracking tx_rate=0x%X\n", tx_rate));
+
+ if (1 <= channel && channel <= 14) {
+ if (IS_CCK_RATE(tx_rate)) {
+ *temperature_up_a = p_rf_calibrate_info->delta_swing_table_idx_2g_cck_a_p;
+ *temperature_down_a = p_rf_calibrate_info->delta_swing_table_idx_2g_cck_a_n;
+ } else {
+ *temperature_up_a = p_rf_calibrate_info->delta_swing_table_idx_2ga_p;
+ *temperature_down_a = p_rf_calibrate_info->delta_swing_table_idx_2ga_n;
+ }
+ } else {
+ *temperature_up_a = (u8 *)delta_swing_table_idx_2ga_p_8188e;
+ *temperature_down_a = (u8 *)delta_swing_table_idx_2ga_n_8188e;
+ }
+
+}
+
+void configure_txpower_track_8188e(
+ struct _TXPWRTRACK_CFG *p_config
+)
+{
+ p_config->swing_table_size_cck = CCK_TABLE_SIZE;
+ p_config->swing_table_size_ofdm = OFDM_TABLE_SIZE;
+ p_config->threshold_iqk = IQK_THRESHOLD;
+ p_config->average_thermal_num = AVG_THERMAL_NUM_88E;
+ p_config->rf_path_count = MAX_PATH_NUM_8188E;
+ p_config->thermal_reg_addr = RF_T_METER_88E;
+
+ p_config->odm_tx_pwr_track_set_pwr = odm_tx_pwr_track_set_pwr88_e;
+ p_config->do_iqk = do_iqk_8188e;
+ p_config->phy_lc_calibrate = phy_lc_calibrate_8188e;
+ p_config->get_delta_swing_table = get_delta_swing_table_8188e;
+}
+
+/* 1 7. IQK */
+#define MAX_TOLERANCE 5
+#define IQK_DELAY_TIME 1 /* ms */
+
+static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
+phy_path_a_iqk_8188e(
+ struct _ADAPTER *p_adapter,
+ bool config_path_b
+)
+{
+ u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
+ u8 result = 0x00;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path A IQK!\n"));
+
+ /* 1 Tx IQK */
+ /* path-A IQK setting */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path-A IQK setting!\n"));
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK_TONE_A, MASKDWORD, 0x10008c1c);
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK_TONE_A, MASKDWORD, 0x30008c1c);
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK_PI_A, MASKDWORD, 0x8214032a);
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK_PI_A, MASKDWORD, 0x28160000);
+
+ /* LO calibration setting */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LO calibration setting!\n"));
+ odm_set_bb_reg(p_dm_odm, REG_IQK_AGC_RSP, MASKDWORD, 0x00462911);
+
+ /* One shot, path A LOK & IQK */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("One shot, path A LOK & IQK!\n"));
+ odm_set_bb_reg(p_dm_odm, REG_IQK_AGC_PTS, MASKDWORD, 0xf9000000);
+ odm_set_bb_reg(p_dm_odm, REG_IQK_AGC_PTS, MASKDWORD, 0xf8000000);
+
+ /* delay x ms */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME_88E));
+ /* platform_stall_execution(IQK_DELAY_TIME_88E*1000); */
+ ODM_delay_ms(IQK_DELAY_TIME_88E);
+
+ /* Check failed */
+ reg_eac = odm_get_bb_reg(p_dm_odm, REG_RX_POWER_AFTER_IQK_A_2, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeac = 0x%x\n", reg_eac));
+ reg_e94 = odm_get_bb_reg(p_dm_odm, REG_TX_POWER_BEFORE_IQK_A, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe94 = 0x%x\n", reg_e94));
+ reg_e9c = odm_get_bb_reg(p_dm_odm, REG_TX_POWER_AFTER_IQK_A, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe9c = 0x%x\n", reg_e9c));
+ reg_ea4 = odm_get_bb_reg(p_dm_odm, REG_RX_POWER_BEFORE_IQK_A_2, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xea4 = 0x%x\n", reg_ea4));
+
+ if (!(reg_eac & BIT(28)) &&
+ (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
+ (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
+ result |= 0x01;
+ else /* if Tx not OK, ignore Rx */
+ return result;
+ return result;
+}
+
+static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
+phy_path_a_rx_iqk(
+ struct _ADAPTER *p_adapter,
+ bool config_path_b
+)
+{
+ u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u4tmp;
+ u8 result = 0x00;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path A Rx IQK!\n"));
+
+ /* 1 Get TXIMR setting */
+ /* modify RXIQK mode table */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path-A Rx IQK modify RXIQK mode table!\n"));
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, MASKH3BYTES, 0x000000);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_WE_LUT, RFREGOFFSETMASK, 0x800a0);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_RCK_OS, RFREGOFFSETMASK, 0x30000);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_TXPA_G1, RFREGOFFSETMASK, 0x0000f);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_TXPA_G2, RFREGOFFSETMASK, 0xf117B);
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, MASKH3BYTES, 0x808000);
+
+ /* IQK setting */
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK, MASKDWORD, 0x01007c00);
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK, MASKDWORD, 0x81004800);
+
+ /* path-A IQK setting */
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK_TONE_A, MASKDWORD, 0x10008c1c);
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK_TONE_A, MASKDWORD, 0x30008c1c);
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK_PI_A, MASKDWORD, 0x82160804);
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK_PI_A, MASKDWORD, 0x28160000);
+
+ /* LO calibration setting */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LO calibration setting!\n"));
+ odm_set_bb_reg(p_dm_odm, REG_IQK_AGC_RSP, MASKDWORD, 0x0046a911);
+
+ /* One shot, path A LOK & IQK */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("One shot, path A LOK & IQK!\n"));
+ odm_set_bb_reg(p_dm_odm, REG_IQK_AGC_PTS, MASKDWORD, 0xf9000000);
+ odm_set_bb_reg(p_dm_odm, REG_IQK_AGC_PTS, MASKDWORD, 0xf8000000);
+
+ /* delay x ms */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME_88E));
+ /* platform_stall_execution(IQK_DELAY_TIME_88E*1000); */
+ ODM_delay_ms(IQK_DELAY_TIME_88E);
+
+ /* Check failed */
+ reg_eac = odm_get_bb_reg(p_dm_odm, REG_RX_POWER_AFTER_IQK_A_2, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeac = 0x%x\n", reg_eac));
+ reg_e94 = odm_get_bb_reg(p_dm_odm, REG_TX_POWER_BEFORE_IQK_A, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe94 = 0x%x\n", reg_e94));
+ reg_e9c = odm_get_bb_reg(p_dm_odm, REG_TX_POWER_AFTER_IQK_A, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe9c = 0x%x\n", reg_e9c));
+
+ if (!(reg_eac & BIT(28)) &&
+ (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
+ (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
+ result |= 0x01;
+ else /* if Tx not OK, ignore Rx */
+ return result;
+
+ u4tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) | ((reg_e9c & 0x3FF0000) >> 16);
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK, MASKDWORD, u4tmp);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe40 = 0x%x u4tmp = 0x%x\n", odm_get_bb_reg(p_dm_odm, REG_TX_IQK, MASKDWORD), u4tmp));
+
+ /* 1 RX IQK */
+ /* modify RXIQK mode table */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path-A Rx IQK modify RXIQK mode table 2!\n"));
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, MASKH3BYTES, 0x000000);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_WE_LUT, RFREGOFFSETMASK, 0x800a0);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_RCK_OS, RFREGOFFSETMASK, 0x30000);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_TXPA_G1, RFREGOFFSETMASK, 0x0000f);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_TXPA_G2, RFREGOFFSETMASK, 0xf7ffa);
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, MASKH3BYTES, 0x808000);
+
+ /* IQK setting */
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK, MASKDWORD, 0x01004800);
+
+ /* path-A IQK setting */
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK_TONE_A, MASKDWORD, 0x30008c1c);
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK_TONE_A, MASKDWORD, 0x10008c1c);
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK_PI_A, MASKDWORD, 0x82160c05);
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK_PI_A, MASKDWORD, 0x28160c05);
+
+ /* LO calibration setting */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LO calibration setting!\n"));
+ odm_set_bb_reg(p_dm_odm, REG_IQK_AGC_RSP, MASKDWORD, 0x0046a911);
+
+ /* One shot, path A LOK & IQK */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("One shot, path A LOK & IQK!\n"));
+ odm_set_bb_reg(p_dm_odm, REG_IQK_AGC_PTS, MASKDWORD, 0xf9000000);
+ odm_set_bb_reg(p_dm_odm, REG_IQK_AGC_PTS, MASKDWORD, 0xf8000000);
+
+ /* delay x ms */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME_88E));
+ /* platform_stall_execution(IQK_DELAY_TIME_88E*1000); */
+ ODM_delay_ms(IQK_DELAY_TIME_88E);
+
+ /* Check failed */
+ reg_eac = odm_get_bb_reg(p_dm_odm, REG_RX_POWER_AFTER_IQK_A_2, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeac = 0x%x\n", reg_eac));
+ reg_e94 = odm_get_bb_reg(p_dm_odm, REG_TX_POWER_BEFORE_IQK_A, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe94 = 0x%x\n", reg_e94));
+ reg_e9c = odm_get_bb_reg(p_dm_odm, REG_TX_POWER_AFTER_IQK_A, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe9c = 0x%x\n", reg_e9c));
+ reg_ea4 = odm_get_bb_reg(p_dm_odm, REG_RX_POWER_BEFORE_IQK_A_2, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xea4 = 0x%x\n", reg_ea4));
+
+ if (!(reg_eac & BIT(27)) && /* if Tx is OK, check whether Rx is OK */
+ (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
+ (((reg_eac & 0x03FF0000) >> 16) != 0x36))
+ result |= 0x02;
+ else
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path A Rx IQK fail!!\n"));
+
+ return result;
+}
+
+static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
+phy_path_b_iqk_8188e(
+ struct _ADAPTER *p_adapter
+)
+{
+ u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
+ u8 result = 0x00;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path B IQK!\n"));
+
+ /* One shot, path B LOK & IQK */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("One shot, path A LOK & IQK!\n"));
+ odm_set_bb_reg(p_dm_odm, REG_IQK_AGC_CONT, MASKDWORD, 0x00000002);
+ odm_set_bb_reg(p_dm_odm, REG_IQK_AGC_CONT, MASKDWORD, 0x00000000);
+
+ /* delay x ms */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("delay %d ms for One shot, path B LOK & IQK.\n", IQK_DELAY_TIME_88E));
+ /* platform_stall_execution(IQK_DELAY_TIME_88E*1000); */
+ ODM_delay_ms(IQK_DELAY_TIME_88E);
+
+ /* Check failed */
+ reg_eac = odm_get_bb_reg(p_dm_odm, REG_RX_POWER_AFTER_IQK_A_2, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeac = 0x%x\n", reg_eac));
+ reg_eb4 = odm_get_bb_reg(p_dm_odm, REG_TX_POWER_BEFORE_IQK_B, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeb4 = 0x%x\n", reg_eb4));
+ reg_ebc = odm_get_bb_reg(p_dm_odm, REG_TX_POWER_AFTER_IQK_B, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xebc = 0x%x\n", reg_ebc));
+ reg_ec4 = odm_get_bb_reg(p_dm_odm, REG_RX_POWER_BEFORE_IQK_B_2, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xec4 = 0x%x\n", reg_ec4));
+ reg_ecc = odm_get_bb_reg(p_dm_odm, REG_RX_POWER_AFTER_IQK_B_2, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xecc = 0x%x\n", reg_ecc));
+
+ if (!(reg_eac & BIT(31)) &&
+ (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
+ (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
+ result |= 0x01;
+ else
+ return result;
+
+ if (!(reg_eac & BIT(30)) &&
+ (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
+ (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
+ result |= 0x02;
+ else
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path B Rx IQK fail!!\n"));
+
+ return result;
+
+}
+
+static void _phy_path_a_fill_iqk_matrix(
+ struct _ADAPTER *p_adapter,
+ bool is_iqk_ok,
+ s32 result[][8],
+ u8 final_candidate,
+ bool is_tx_only
+)
+{
+ u32 oldval_0, X, TX0_A, reg;
+ s32 Y, TX0_C;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path A IQ Calibration %s !\n", (is_iqk_ok) ? "Success" : "Failed"));
+
+ if (final_candidate == 0xFF)
+ return;
+
+ else if (is_iqk_ok) {
+ oldval_0 = (odm_get_bb_reg(p_dm_odm, REG_OFDM_0_XA_TX_IQ_IMBALANCE, MASKDWORD) >> 22) & 0x3FF;
+
+ X = result[final_candidate][0];
+ if ((X & 0x00000200) != 0)
+ X = X | 0xFFFFFC00;
+ TX0_A = (X * oldval_0) >> 8;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("X = 0x%x, TX0_A = 0x%x, oldval_0 0x%x\n", X, TX0_A, oldval_0));
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XA_TX_IQ_IMBALANCE, 0x3FF, TX0_A);
+
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_ECCA_THRESHOLD, BIT(31), ((X * oldval_0 >> 7) & 0x1));
+
+ Y = result[final_candidate][1];
+ if ((Y & 0x00000200) != 0)
+ Y = Y | 0xFFFFFC00;
+
+ TX0_C = (Y * oldval_0) >> 8;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Y = 0x%x, TX = 0x%x\n", Y, TX0_C));
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XC_TX_AFE, 0xF0000000, ((TX0_C & 0x3C0) >> 6));
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XA_TX_IQ_IMBALANCE, 0x003F0000, (TX0_C & 0x3F));
+
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_ECCA_THRESHOLD, BIT(29), ((Y * oldval_0 >> 7) & 0x1));
+
+ if (is_tx_only) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_path_a_fill_iqk_matrix only Tx OK\n"));
+ return;
+ }
+
+ reg = result[final_candidate][2];
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XA_RX_IQ_IMBALANCE, 0x3FF, reg);
+
+ reg = result[final_candidate][3] & 0x3F;
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XA_RX_IQ_IMBALANCE, 0xFC00, reg);
+
+ reg = (result[final_candidate][3] >> 6) & 0xF;
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_RX_IQ_EXT_ANTA, 0xF0000000, reg);
+ }
+}
+
+static void _phy_path_b_fill_iqk_matrix(
+ struct _ADAPTER *p_adapter,
+ bool is_iqk_ok,
+ s32 result[][8],
+ u8 final_candidate,
+ bool is_tx_only /* do Tx only */
+)
+{
+ u32 oldval_1, X, TX1_A, reg;
+ s32 Y, TX1_C;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path B IQ Calibration %s !\n", (is_iqk_ok) ? "Success" : "Failed"));
+
+ if (final_candidate == 0xFF)
+ return;
+
+ else if (is_iqk_ok) {
+ oldval_1 = (odm_get_bb_reg(p_dm_odm, REG_OFDM_0_XB_TX_IQ_IMBALANCE, MASKDWORD) >> 22) & 0x3FF;
+
+ X = result[final_candidate][4];
+ if ((X & 0x00000200) != 0)
+ X = X | 0xFFFFFC00;
+ TX1_A = (X * oldval_1) >> 8;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("X = 0x%x, TX1_A = 0x%x\n", X, TX1_A));
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XB_TX_IQ_IMBALANCE, 0x3FF, TX1_A);
+
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_ECCA_THRESHOLD, BIT(27), ((X * oldval_1 >> 7) & 0x1));
+
+ Y = result[final_candidate][5];
+ if ((Y & 0x00000200) != 0)
+ Y = Y | 0xFFFFFC00;
+
+ TX1_C = (Y * oldval_1) >> 8;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Y = 0x%x, TX1_C = 0x%x\n", Y, TX1_C));
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XD_TX_AFE, 0xF0000000, ((TX1_C & 0x3C0) >> 6));
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XB_TX_IQ_IMBALANCE, 0x003F0000, (TX1_C & 0x3F));
+
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_ECCA_THRESHOLD, BIT(25), ((Y * oldval_1 >> 7) & 0x1));
+
+ if (is_tx_only)
+ return;
+
+ reg = result[final_candidate][6];
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XB_RX_IQ_IMBALANCE, 0x3FF, reg);
+
+ reg = result[final_candidate][7] & 0x3F;
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XB_RX_IQ_IMBALANCE, 0xFC00, reg);
+
+ reg = (result[final_candidate][7] >> 6) & 0xF;
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_AGC_RSSI_TABLE, 0x0000F000, reg);
+ }
+}
+
+/*
+ * 2011/07/26 MH Add an API for testing IQK fail case.
+ *
+ * MP Already declare in odm.c */
+static bool odm_check_power_status(
+ struct _ADAPTER *adapter)
+{
+ return true;
+}
+
+void
+_phy_save_adda_registers(
+ struct _ADAPTER *p_adapter,
+ u32 *adda_reg,
+ u32 *adda_backup,
+ u32 register_num
+)
+{
+ u32 i;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+
+ if (odm_check_power_status(p_adapter) == false)
+ return;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Save ADDA parameters.\n"));
+ for (i = 0 ; i < register_num ; i++)
+ adda_backup[i] = odm_get_bb_reg(p_dm_odm, adda_reg[i], MASKDWORD);
+}
+
+static void _phy_save_mac_registers(
+ struct _ADAPTER *p_adapter,
+ u32 *mac_reg,
+ u32 *mac_backup
+)
+{
+ u32 i;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Save MAC parameters.\n"));
+ for (i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++)
+ mac_backup[i] = odm_read_1byte(p_dm_odm, mac_reg[i]);
+ mac_backup[i] = odm_read_4byte(p_dm_odm, mac_reg[i]);
+
+}
+
+static void _phy_reload_adda_registers(
+ struct _ADAPTER *p_adapter,
+ u32 *adda_reg,
+ u32 *adda_backup,
+ u32 regiester_num
+)
+{
+ u32 i;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Reload ADDA power saving parameters !\n"));
+ for (i = 0 ; i < regiester_num; i++)
+ odm_set_bb_reg(p_dm_odm, adda_reg[i], MASKDWORD, adda_backup[i]);
+}
+
+static void _phy_reload_mac_registers(
+ struct _ADAPTER *p_adapter,
+ u32 *mac_reg,
+ u32 *mac_backup
+)
+{
+ u32 i;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Reload MAC parameters !\n"));
+ for (i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++)
+ odm_write_1byte(p_dm_odm, mac_reg[i], (u8)mac_backup[i]);
+ odm_write_4byte(p_dm_odm, mac_reg[i], mac_backup[i]);
+}
+
+void
+_phy_path_adda_on(
+ struct _ADAPTER *p_adapter,
+ u32 *adda_reg,
+ bool is_path_a_on,
+ bool is2T
+)
+{
+ u32 path_on;
+ u32 i;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("ADDA ON.\n"));
+
+ path_on = is_path_a_on ? 0x04db25a4 : 0x0b1b25a4;
+ if (false == is2T) {
+ path_on = 0x0bdb25a0;
+ odm_set_bb_reg(p_dm_odm, adda_reg[0], MASKDWORD, 0x0b1b25a0);
+ } else
+ odm_set_bb_reg(p_dm_odm, adda_reg[0], MASKDWORD, path_on);
+
+ for (i = 1 ; i < IQK_ADDA_REG_NUM ; i++)
+ odm_set_bb_reg(p_dm_odm, adda_reg[i], MASKDWORD, path_on);
+
+}
+
+void
+_phy_mac_setting_calibration(
+ struct _ADAPTER *p_adapter,
+ u32 *mac_reg,
+ u32 *mac_backup
+)
+{
+ u32 i = 0;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("MAC settings for Calibration.\n"));
+
+ odm_write_1byte(p_dm_odm, mac_reg[i], 0x3F);
+
+ for (i = 1 ; i < (IQK_MAC_REG_NUM - 1); i++)
+ odm_write_1byte(p_dm_odm, mac_reg[i], (u8)(mac_backup[i] & (~BIT(3))));
+ odm_write_1byte(p_dm_odm, mac_reg[i], (u8)(mac_backup[i] & (~BIT(5))));
+
+}
+
+void _phy_path_a_stand_by(struct _ADAPTER *p_adapter)
+{
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path-A standby mode!\n"));
+
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, MASKH3BYTES, 0x0);
+ odm_set_bb_reg(p_dm_odm, 0x840, MASKDWORD, 0x00010000);
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, MASKH3BYTES, 0x808000);
+}
+
+static void _phy_pi_mode_switch(
+ struct _ADAPTER *p_adapter,
+ bool pi_mode
+)
+{
+ u32 mode;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("BB Switch to %s mode!\n", (pi_mode ? "PI" : "SI")));
+
+ mode = pi_mode ? 0x01000100 : 0x01000000;
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XA_HSSI_PARAMETER1, MASKDWORD, mode);
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XB_HSSI_PARAMETER1, MASKDWORD, mode);
+}
+
+static bool phy_simularity_compare_8188e(
+ struct _ADAPTER *p_adapter,
+ s32 result[][8],
+ u8 c1,
+ u8 c2
+)
+{
+ u32 i, j, diff, simularity_bit_map, bound;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+ u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
+ bool is_result = true;
+ bool is2T = IS_2T2R(p_hal_data->version_id);
+
+ if (is2T)
+ bound = 8;
+ else
+ bound = 4;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("===> IQK:phy_simularity_compare_8188e c1 %d c2 %d!!!\n", c1, c2));
+
+ simularity_bit_map = 0;
+
+ for (i = 0; i < bound; i++) {
+ diff = (result[c1][i] > result[c2][i]) ? (result[c1][i] - result[c2][i]) : (result[c2][i] - result[c1][i]);
+ if (diff > MAX_TOLERANCE) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK:phy_simularity_compare_8188e differnece overflow index %d compare1 0x%x compare2 0x%x!!!\n", i, result[c1][i], result[c2][i]));
+
+ if ((i == 2 || i == 6) && !simularity_bit_map) {
+ if (result[c1][i] + result[c1][i + 1] == 0)
+ final_candidate[(i / 4)] = c2;
+ else if (result[c2][i] + result[c2][i + 1] == 0)
+ final_candidate[(i / 4)] = c1;
+ else
+ simularity_bit_map = simularity_bit_map | (1 << i);
+ } else
+ simularity_bit_map = simularity_bit_map | (1 << i);
+ }
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK:phy_simularity_compare_8188e simularity_bit_map %d !!!\n", simularity_bit_map));
+
+ if (simularity_bit_map == 0) {
+ for (i = 0; i < (bound / 4); i++) {
+ if (final_candidate[i] != 0xFF) {
+ for (j = i * 4; j < (i + 1) * 4 - 2; j++)
+ result[3][j] = result[final_candidate[i]][j];
+ is_result = false;
+ }
+ }
+ return is_result;
+ } else if (!(simularity_bit_map & 0x0F)) { /* path A OK */
+ for (i = 0; i < 4; i++)
+ result[3][i] = result[c1][i];
+ return false;
+ } else if (!(simularity_bit_map & 0xF0) && is2T) { /* path B OK */
+ for (i = 4; i < 8; i++)
+ result[3][i] = result[c1][i];
+ return false;
+ } else
+ return false;
+
+}
+
+static void _phy_iq_calibrate_8188e(
+ struct _ADAPTER *p_adapter,
+ s32 result[][8],
+ u8 t,
+ bool is2T
+)
+{
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+ u32 i;
+ u8 path_aok = 0, path_bok = 0;
+ u32 ADDA_REG[IQK_ADDA_REG_NUM] = {
+ REG_FPGA0_XCD_SWITCH_CONTROL, REG_BLUE_TOOTH,
+ REG_RX_WAIT_CCA, REG_TX_CCK_RFON,
+ REG_TX_CCK_BBON, REG_TX_OFDM_RFON,
+ REG_TX_OFDM_BBON, REG_TX_TO_RX,
+ REG_TX_TO_TX, REG_RX_CCK,
+ REG_RX_OFDM, REG_RX_WAIT_RIFS,
+ REG_RX_TO_RX, REG_STANDBY,
+ REG_SLEEP, REG_PMPD_ANAEN
+ };
+ u32 IQK_MAC_REG[IQK_MAC_REG_NUM] = {
+ REG_TXPAUSE, REG_BCN_CTRL,
+ REG_BCN_CTRL_1, REG_GPIO_MUXCFG
+ };
+
+ /* since 92C & 92D have the different define in IQK_BB_REG */
+ u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
+ REG_OFDM_0_TRX_PATH_ENABLE, REG_OFDM_0_TR_MUX_PAR,
+ REG_FPGA0_XCD_RF_INTERFACE_SW, REG_CONFIG_ANT_A, REG_CONFIG_ANT_B,
+ REG_FPGA0_XAB_RF_INTERFACE_SW, REG_FPGA0_XA_RF_INTERFACE_OE,
+ REG_FPGA0_XB_RF_INTERFACE_OE, REG_CCK_0_AFE_SETTING
+ };
+
+ u32 retry_count = 2;
+
+ if (p_dm_odm->mp_mode == true)
+ retry_count = 9;
+
+ /* Note: IQ calibration must be performed after loading */
+ /* PHY_REG.txt , and radio_a, radio_b.txt */
+
+ /* u32 bbvalue; */
+
+ if (t == 0) {
+ /* bbvalue = odm_get_bb_reg(p_dm_odm, REG_FPGA0_RFMOD, MASKDWORD);
+ * RT_DISP(FINIT, INIT_IQK, ("_phy_iq_calibrate_8188e()==>0x%08x\n",bbvalue)); */
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQ Calibration for %s for %d times\n", (is2T ? "2T2R" : "1T1R"), t));
+
+ /* Save ADDA parameters, turn path A ADDA on */
+ _phy_save_adda_registers(p_adapter, ADDA_REG, p_dm_odm->rf_calibrate_info.ADDA_backup, IQK_ADDA_REG_NUM);
+ _phy_save_mac_registers(p_adapter, IQK_MAC_REG, p_dm_odm->rf_calibrate_info.IQK_MAC_backup);
+ _phy_save_adda_registers(p_adapter, IQK_BB_REG_92C, p_dm_odm->rf_calibrate_info.IQK_BB_backup, IQK_BB_REG_NUM);
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQ Calibration for %s for %d times\n", (is2T ? "2T2R" : "1T1R"), t));
+
+ _phy_path_adda_on(p_adapter, ADDA_REG, true, is2T);
+
+ if (t == 0)
+ p_dm_odm->rf_calibrate_info.is_rf_pi_enable = (u8)odm_get_bb_reg(p_dm_odm, REG_FPGA0_XA_HSSI_PARAMETER1, BIT(8));
+
+ if (!p_dm_odm->rf_calibrate_info.is_rf_pi_enable) {
+ /* Switch BB to PI mode to do IQ Calibration. */
+ _phy_pi_mode_switch(p_adapter, true);
+ }
+
+ /* MAC settings */
+ _phy_mac_setting_calibration(p_adapter, IQK_MAC_REG, p_dm_odm->rf_calibrate_info.IQK_MAC_backup);
+
+ /* BB setting */
+ /* odm_set_bb_reg(p_dm_odm, REG_FPGA0_RFMOD, BIT24, 0x00); */
+ odm_set_bb_reg(p_dm_odm, REG_CCK_0_AFE_SETTING, 0x0f000000, 0xf);
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_TRX_PATH_ENABLE, MASKDWORD, 0x03a05600);
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_TR_MUX_PAR, MASKDWORD, 0x000800e4);
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XCD_RF_INTERFACE_SW, MASKDWORD, 0x22204000);
+
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XAB_RF_INTERFACE_SW, BIT(10), 0x01);
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XAB_RF_INTERFACE_SW, BIT(26), 0x01);
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XA_RF_INTERFACE_OE, BIT(10), 0x00);
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XB_RF_INTERFACE_OE, BIT(10), 0x00);
+
+ if (is2T) {
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XA_LSSI_PARAMETER, MASKDWORD, 0x00010000);
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XB_LSSI_PARAMETER, MASKDWORD, 0x00010000);
+ }
+
+ /* Page B init */
+ /* AP or IQK */
+ odm_set_bb_reg(p_dm_odm, REG_CONFIG_ANT_A, MASKDWORD, 0x0f600000);
+
+ if (is2T)
+ odm_set_bb_reg(p_dm_odm, REG_CONFIG_ANT_B, MASKDWORD, 0x0f600000);
+
+ /* IQ calibration setting */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK setting!\n"));
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, MASKH3BYTES, 0x808000);
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK, MASKDWORD, 0x01007c00);
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK, MASKDWORD, 0x81004800);
+
+ for (i = 0 ; i < retry_count ; i++) {
+ path_aok = phy_path_a_iqk_8188e(p_adapter, is2T);
+ /* if(path_aok == 0x03){ */
+ if (path_aok == 0x01) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path A Tx IQK Success!!\n"));
+ result[t][0] = (odm_get_bb_reg(p_dm_odm, REG_TX_POWER_BEFORE_IQK_A, MASKDWORD) & 0x3FF0000) >> 16;
+ result[t][1] = (odm_get_bb_reg(p_dm_odm, REG_TX_POWER_AFTER_IQK_A, MASKDWORD) & 0x3FF0000) >> 16;
+ break;
+ }
+ }
+
+ for (i = 0 ; i < retry_count ; i++) {
+ path_aok = phy_path_a_rx_iqk(p_adapter, is2T);
+ if (path_aok == 0x03) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path A Rx IQK Success!!\n"));
+ /* result[t][0] = (odm_get_bb_reg(p_dm_odm, REG_TX_POWER_BEFORE_IQK_A, MASKDWORD)&0x3FF0000)>>16;
+ * result[t][1] = (odm_get_bb_reg(p_dm_odm, REG_TX_POWER_AFTER_IQK_A, MASKDWORD)&0x3FF0000)>>16; */
+ result[t][2] = (odm_get_bb_reg(p_dm_odm, REG_RX_POWER_BEFORE_IQK_A_2, MASKDWORD) & 0x3FF0000) >> 16;
+ result[t][3] = (odm_get_bb_reg(p_dm_odm, REG_RX_POWER_AFTER_IQK_A_2, MASKDWORD) & 0x3FF0000) >> 16;
+ break;
+ } else
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path A Rx IQK Fail!!\n"));
+ }
+
+ if (0x00 == path_aok)
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path A IQK failed!!\n"));
+
+ if (is2T) {
+ _phy_path_a_stand_by(p_adapter);
+
+ /* Turn path B ADDA on */
+ _phy_path_adda_on(p_adapter, ADDA_REG, false, is2T);
+
+ for (i = 0 ; i < retry_count ; i++) {
+ path_bok = phy_path_b_iqk_8188e(p_adapter);
+ if (path_bok == 0x03) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path B IQK Success!!\n"));
+ result[t][4] = (odm_get_bb_reg(p_dm_odm, REG_TX_POWER_BEFORE_IQK_B, MASKDWORD) & 0x3FF0000) >> 16;
+ result[t][5] = (odm_get_bb_reg(p_dm_odm, REG_TX_POWER_AFTER_IQK_B, MASKDWORD) & 0x3FF0000) >> 16;
+ result[t][6] = (odm_get_bb_reg(p_dm_odm, REG_RX_POWER_BEFORE_IQK_B_2, MASKDWORD) & 0x3FF0000) >> 16;
+ result[t][7] = (odm_get_bb_reg(p_dm_odm, REG_RX_POWER_AFTER_IQK_B_2, MASKDWORD) & 0x3FF0000) >> 16;
+ break;
+ } else if (i == (retry_count - 1) && path_bok == 0x01) { /* Tx IQK OK */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path B Only Tx IQK Success!!\n"));
+ result[t][4] = (odm_get_bb_reg(p_dm_odm, REG_TX_POWER_BEFORE_IQK_B, MASKDWORD) & 0x3FF0000) >> 16;
+ result[t][5] = (odm_get_bb_reg(p_dm_odm, REG_TX_POWER_AFTER_IQK_B, MASKDWORD) & 0x3FF0000) >> 16;
+ }
+ }
+
+ if (0x00 == path_bok)
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path B IQK failed!!\n"));
+ }
+
+ /* Back to BB mode, load original value */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK:Back to BB mode, load original value!\n"));
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, MASKH3BYTES, 0);
+
+ if (t != 0) {
+ if (!p_dm_odm->rf_calibrate_info.is_rf_pi_enable) {
+ /* Switch back BB to SI mode after finish IQ Calibration. */
+ _phy_pi_mode_switch(p_adapter, false);
+ }
+
+ /* Reload ADDA power saving parameters */
+ _phy_reload_adda_registers(p_adapter, ADDA_REG, p_dm_odm->rf_calibrate_info.ADDA_backup, IQK_ADDA_REG_NUM);
+
+ /* Reload MAC parameters */
+ _phy_reload_mac_registers(p_adapter, IQK_MAC_REG, p_dm_odm->rf_calibrate_info.IQK_MAC_backup);
+
+ _phy_reload_adda_registers(p_adapter, IQK_BB_REG_92C, p_dm_odm->rf_calibrate_info.IQK_BB_backup, IQK_BB_REG_NUM);
+
+ /* Restore RX initial gain */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XA_LSSI_PARAMETER, MASKDWORD, 0x00032ed3);
+ if (is2T)
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XB_LSSI_PARAMETER, MASKDWORD, 0x00032ed3);
+
+ /* load 0xe30 IQC default value */
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK_TONE_A, MASKDWORD, 0x01008c00);
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK_TONE_A, MASKDWORD, 0x01008c00);
+
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_iq_calibrate_8188e() <==\n"));
+
+}
+
+static void _phy_lc_calibrate_8188e(struct PHY_DM_STRUCT *p_dm_odm, bool is2T)
+{
+ u8 tmp_reg;
+ u32 rf_amode = 0, rf_bmode = 0, lc_cal;
+ struct _ADAPTER *p_adapter = p_dm_odm->adapter;
+ /* Check continuous TX and Packet TX */
+ tmp_reg = odm_read_1byte(p_dm_odm, 0xd03);
+
+ if ((tmp_reg & 0x70) != 0) /* Deal with contisuous TX case */
+ odm_write_1byte(p_dm_odm, 0xd03, tmp_reg & 0x8F); /* disable all continuous TX */
+ else /* Deal with Packet TX case */
+ odm_write_1byte(p_dm_odm, REG_TXPAUSE, 0xFF); /* block all queues */
+
+ if ((tmp_reg & 0x70) != 0) {
+ /* 1. Read original RF mode */
+ /* path-A */
+ rf_amode = phy_query_rf_reg(p_adapter, ODM_RF_PATH_A, RF_AC, MASK12BITS);
+
+ /* path-B */
+ if (is2T)
+ rf_bmode = phy_query_rf_reg(p_adapter, ODM_RF_PATH_B, RF_AC, MASK12BITS);
+
+ /* 2. Set RF mode = standby mode */
+ /* path-A */
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_AC, MASK12BITS, (rf_amode & 0x8FFFF) | 0x10000);
+
+ /* path-B */
+ if (is2T)
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, RF_AC, MASK12BITS, (rf_bmode & 0x8FFFF) | 0x10000);
+ }
+
+ /* 3. Read RF reg18 */
+ lc_cal = phy_query_rf_reg(p_adapter, ODM_RF_PATH_A, RF_CHNLBW, MASK12BITS);
+
+ /* 4. Set LC calibration begin bit15 */
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_CHNLBW, MASK12BITS, lc_cal | 0x08000);
+
+ ODM_delay_ms(100);
+
+ /* Restore original situation */
+ if ((tmp_reg & 0x70) != 0) { /* Deal with contisuous TX case */
+ /* path-A */
+ odm_write_1byte(p_dm_odm, 0xd03, tmp_reg);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_AC, MASK12BITS, rf_amode);
+
+ /* path-B */
+ if (is2T)
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, RF_AC, MASK12BITS, rf_bmode);
+ } else /* Deal with Packet TX case */
+ odm_write_1byte(p_dm_odm, REG_TXPAUSE, 0x00);
+}
+
+/* Analog Pre-distortion calibration */
+#define APK_BB_REG_NUM 8
+#define APK_CURVE_REG_NUM 4
+#define PATH_NUM 2
+
+static void _phy_ap_calibrate_8188e(
+ struct _ADAPTER *p_adapter,
+ s8 delta,
+ bool is2T
+)
+{
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+ u32 reg_d[PATH_NUM];
+ u32 tmp_reg, index, offset, apkbound;
+ u8 path, i, pathbound = PATH_NUM;
+ u32 BB_backup[APK_BB_REG_NUM];
+ u32 BB_REG[APK_BB_REG_NUM] = {
+ REG_FPGA1_TX_BLOCK, REG_OFDM_0_TRX_PATH_ENABLE,
+ REG_FPGA0_RFMOD, REG_OFDM_0_TR_MUX_PAR,
+ REG_FPGA0_XCD_RF_INTERFACE_SW, REG_FPGA0_XAB_RF_INTERFACE_SW,
+ REG_FPGA0_XA_RF_INTERFACE_OE, REG_FPGA0_XB_RF_INTERFACE_OE
+ };
+ u32 BB_AP_MODE[APK_BB_REG_NUM] = {
+ 0x00000020, 0x00a05430, 0x02040000,
+ 0x000800e4, 0x00204000
+ };
+ u32 BB_normal_AP_MODE[APK_BB_REG_NUM] = {
+ 0x00000020, 0x00a05430, 0x02040000,
+ 0x000800e4, 0x22204000
+ };
+
+ u32 AFE_backup[IQK_ADDA_REG_NUM];
+ u32 AFE_REG[IQK_ADDA_REG_NUM] = {
+ REG_FPGA0_XCD_SWITCH_CONTROL, REG_BLUE_TOOTH,
+ REG_RX_WAIT_CCA, REG_TX_CCK_RFON,
+ REG_TX_CCK_BBON, REG_TX_OFDM_RFON,
+ REG_TX_OFDM_BBON, REG_TX_TO_RX,
+ REG_TX_TO_TX, REG_RX_CCK,
+ REG_RX_OFDM, REG_RX_WAIT_RIFS,
+ REG_RX_TO_RX, REG_STANDBY,
+ REG_SLEEP, REG_PMPD_ANAEN
+ };
+
+ u32 MAC_backup[IQK_MAC_REG_NUM];
+ u32 MAC_REG[IQK_MAC_REG_NUM] = {
+ REG_TXPAUSE, REG_BCN_CTRL,
+ REG_BCN_CTRL_1, REG_GPIO_MUXCFG
+ };
+
+ u32 APK_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = {
+ {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c},
+ {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e}
+ };
+
+ u32 APK_normal_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = {
+ {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, /* path settings equal to path b settings */
+ {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c}
+ };
+
+ u32 APK_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = {
+ {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d},
+ {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050}
+ };
+
+ u32 APK_normal_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = {
+ {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, /* path settings equal to path b settings */
+ {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}
+ };
+
+ u32 AFE_on_off[PATH_NUM] = {
+ 0x04db25a4, 0x0b1b25a4
+ }; /* path A on path B off / path A off path B on */
+
+ u32 APK_offset[PATH_NUM] = {
+ REG_CONFIG_ANT_A, REG_CONFIG_ANT_B
+ };
+
+ u32 APK_normal_offset[PATH_NUM] = {
+ REG_CONFIG_PMPD_ANT_A, REG_CONFIG_PMPD_ANT_B
+ };
+
+ u32 APK_value[PATH_NUM] = {
+ 0x92fc0000, 0x12fc0000
+ };
+
+ u32 APK_normal_value[PATH_NUM] = {
+ 0x92680000, 0x12680000
+ };
+
+ s8 APK_delta_mapping[APK_BB_REG_NUM][13] = {
+ {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
+ {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
+ {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
+ {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6},
+ {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0}
+ };
+
+ u32 APK_normal_setting_value_1[13] = {
+ 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28,
+ 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3,
+ 0x12680000, 0x00880000, 0x00880000
+ };
+
+ u32 APK_normal_setting_value_2[16] = {
+ 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3,
+ 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025,
+ 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008,
+ 0x00050006
+ };
+
+ u32 APK_result[PATH_NUM][APK_BB_REG_NUM]; /* val_1_1a, val_1_2a, val_2a, val_3a, val_4a
+ * u32 AP_curve[PATH_NUM][APK_CURVE_REG_NUM]; */
+
+ s32 BB_offset, delta_V, delta_offset;
+
+#if MP_DRIVER == 1
+ PMPT_CONTEXT p_mpt_ctx = &(p_adapter->mppriv.mpt_ctx);
+
+ if (p_dm_odm->mp_mode == true) {
+ p_mpt_ctx->APK_bound[0] = 45;
+ p_mpt_ctx->APK_bound[1] = 52;
+ }
+#endif
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("==>_phy_ap_calibrate_8188e() delta %d\n", delta));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("AP Calibration for %s\n", (is2T ? "2T2R" : "1T1R")));
+ if (!is2T)
+ pathbound = 1;
+
+ /* 2 FOR NORMAL CHIP SETTINGS */
+
+ /* Temporarily do not allow normal driver to do the following settings because these offset
+ * and value will cause RF internal PA to be unpredictably disabled by HW, such that RF Tx signal
+ * will disappear after disable/enable card many times on 88CU. RF SD and DD have not find the
+ * root cause, so we remove these actions temporarily. Added by tynli and SD3 Allen. 2010.05.31.
+ * #if MP_DRIVER != 1 */
+ if (p_dm_odm->mp_mode == false)
+ return;
+ /* #endif */
+ /* settings adjust for normal chip */
+ for (index = 0; index < PATH_NUM; index++) {
+ APK_offset[index] = APK_normal_offset[index];
+ APK_value[index] = APK_normal_value[index];
+ AFE_on_off[index] = 0x6fdb25a4;
+ }
+
+ for (index = 0; index < APK_BB_REG_NUM; index++) {
+ for (path = 0; path < pathbound; path++) {
+ APK_RF_init_value[path][index] = APK_normal_RF_init_value[path][index];
+ APK_RF_value_0[path][index] = APK_normal_RF_value_0[path][index];
+ }
+ BB_AP_MODE[index] = BB_normal_AP_MODE[index];
+ }
+
+ apkbound = 6;
+
+ /* save BB default value */
+ for (index = 0; index < APK_BB_REG_NUM ; index++) {
+ if (index == 0) /* skip */
+ continue;
+ BB_backup[index] = odm_get_bb_reg(p_dm_odm, BB_REG[index], MASKDWORD);
+ }
+
+ /* save MAC default value */
+ _phy_save_mac_registers(p_adapter, MAC_REG, MAC_backup);
+
+ /* save AFE default value */
+ _phy_save_adda_registers(p_adapter, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM);
+
+ for (path = 0; path < pathbound; path++) {
+ if (path == ODM_RF_PATH_A) {
+ /* path A APK */
+ /* load APK setting */
+ /* path-A */
+ offset = REG_PDP_ANT_A;
+ for (index = 0; index < 11; index++) {
+ odm_set_bb_reg(p_dm_odm, offset, MASKDWORD, APK_normal_setting_value_1[index]);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() offset 0x%x value 0x%x\n", offset, odm_get_bb_reg(p_dm_odm, offset, MASKDWORD)));
+
+ offset += 0x04;
+ }
+
+ odm_set_bb_reg(p_dm_odm, REG_CONFIG_PMPD_ANT_B, MASKDWORD, 0x12680000);
+
+ offset = REG_CONFIG_ANT_A;
+ for (; index < 13; index++) {
+ odm_set_bb_reg(p_dm_odm, offset, MASKDWORD, APK_normal_setting_value_1[index]);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() offset 0x%x value 0x%x\n", offset, odm_get_bb_reg(p_dm_odm, offset, MASKDWORD)));
+
+ offset += 0x04;
+ }
+
+ /* page-B1 */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, MASKH3BYTES, 0x400000);
+
+ /* path A */
+ offset = REG_PDP_ANT_A;
+ for (index = 0; index < 16; index++) {
+ odm_set_bb_reg(p_dm_odm, offset, MASKDWORD, APK_normal_setting_value_2[index]);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() offset 0x%x value 0x%x\n", offset, odm_get_bb_reg(p_dm_odm, offset, MASKDWORD)));
+
+ offset += 0x04;
+ }
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, MASKH3BYTES, 0x000000);
+ } else if (path == ODM_RF_PATH_B) {
+ /* path B APK */
+ /* load APK setting */
+ /* path-B */
+ offset = REG_PDP_ANT_B;
+ for (index = 0; index < 10; index++) {
+ odm_set_bb_reg(p_dm_odm, offset, MASKDWORD, APK_normal_setting_value_1[index]);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() offset 0x%x value 0x%x\n", offset, odm_get_bb_reg(p_dm_odm, offset, MASKDWORD)));
+
+ offset += 0x04;
+ }
+ odm_set_bb_reg(p_dm_odm, REG_CONFIG_PMPD_ANT_A, MASKDWORD, 0x12680000);
+ phy_set_bb_reg(p_adapter, REG_CONFIG_PMPD_ANT_B, MASKDWORD, 0x12680000);
+
+ offset = REG_CONFIG_ANT_A;
+ index = 11;
+ for (; index < 13; index++) { /* offset 0xb68, 0xb6c */
+ odm_set_bb_reg(p_dm_odm, offset, MASKDWORD, APK_normal_setting_value_1[index]);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() offset 0x%x value 0x%x\n", offset, odm_get_bb_reg(p_dm_odm, offset, MASKDWORD)));
+
+ offset += 0x04;
+ }
+
+ /* page-B1 */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, MASKH3BYTES, 0x400000);
+
+ /* path B */
+ offset = 0xb60;
+ for (index = 0; index < 16; index++) {
+ odm_set_bb_reg(p_dm_odm, offset, MASKDWORD, APK_normal_setting_value_2[index]);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() offset 0x%x value 0x%x\n", offset, odm_get_bb_reg(p_dm_odm, offset, MASKDWORD)));
+
+ offset += 0x04;
+ }
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, MASKH3BYTES, 0);
+ }
+
+ /* save RF default value */
+ reg_d[path] = phy_query_rf_reg(p_adapter, path, RF_TXBIAS_A, MASKDWORD);
+
+ /* path A AFE all on, path B AFE All off or vise versa */
+ for (index = 0; index < IQK_ADDA_REG_NUM ; index++)
+ odm_set_bb_reg(p_dm_odm, AFE_REG[index], MASKDWORD, AFE_on_off[path]);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() offset 0xe70 %x\n", odm_get_bb_reg(p_dm_odm, REG_RX_WAIT_CCA, MASKDWORD)));
+
+ /* BB to AP mode */
+ if (path == 0) {
+ for (index = 0; index < APK_BB_REG_NUM ; index++) {
+
+ if (index == 0) /* skip */
+ continue;
+ else if (index < 5)
+ odm_set_bb_reg(p_dm_odm, BB_REG[index], MASKDWORD, BB_AP_MODE[index]);
+ else if (BB_REG[index] == 0x870)
+ odm_set_bb_reg(p_dm_odm, BB_REG[index], MASKDWORD, BB_backup[index] | BIT(10) | BIT(26));
+ else
+ odm_set_bb_reg(p_dm_odm, BB_REG[index], BIT(10), 0x0);
+ }
+
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK_TONE_A, MASKDWORD, 0x01008c00);
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK_TONE_A, MASKDWORD, 0x01008c00);
+ } else { /* path B */
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK_TONE_B, MASKDWORD, 0x01008c00);
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK_TONE_B, MASKDWORD, 0x01008c00);
+
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() offset 0x800 %x\n", odm_get_bb_reg(p_dm_odm, 0x800, MASKDWORD)));
+
+ /* MAC settings */
+ _phy_mac_setting_calibration(p_adapter, MAC_REG, MAC_backup);
+
+ if (path == ODM_RF_PATH_A) /* path B to standby mode */
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, RF_AC, MASKDWORD, 0x10000);
+ else { /* path A to standby mode */
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_AC, MASKDWORD, 0x10000);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_MODE1, MASKDWORD, 0x1000f);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_MODE2, MASKDWORD, 0x20103);
+ }
+
+ delta_offset = ((delta + 14) / 2);
+ if (delta_offset < 0)
+ delta_offset = 0;
+ else if (delta_offset > 12)
+ delta_offset = 12;
+
+ /* AP calibration */
+ for (index = 0; index < APK_BB_REG_NUM; index++) {
+ if (index != 1) /* only DO PA11+PAD01001, AP RF setting */
+ continue;
+
+ tmp_reg = APK_RF_init_value[path][index];
+ if (!p_dm_odm->rf_calibrate_info.is_apk_thermal_meter_ignore) {
+ BB_offset = (tmp_reg & 0xF0000) >> 16;
+
+ if (!(tmp_reg & BIT(15))) /* sign bit 0 */
+ BB_offset = -BB_offset;
+
+ delta_V = APK_delta_mapping[index][delta_offset];
+
+ BB_offset += delta_V;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() APK index %d tmp_reg 0x%x delta_V %d delta_offset %d\n", index, tmp_reg, delta_V, delta_offset));
+
+ if (BB_offset < 0) {
+ tmp_reg = tmp_reg & (~BIT(15));
+ BB_offset = -BB_offset;
+ } else
+ tmp_reg = tmp_reg | BIT(15);
+ tmp_reg = (tmp_reg & 0xFFF0FFFF) | (BB_offset << 16);
+ }
+ odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)path, RF_IPA_A, MASKDWORD, 0x8992e);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() offset 0xc %x\n", phy_query_rf_reg(p_adapter, path, RF_IPA_A, MASKDWORD)));
+ odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)path, RF_AC, MASKDWORD, APK_RF_value_0[path][index]);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() offset 0x0 %x\n", phy_query_rf_reg(p_adapter, path, RF_AC, MASKDWORD)));
+ odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)path, RF_TXBIAS_A, MASKDWORD, tmp_reg);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() offset 0xd %x\n", phy_query_rf_reg(p_adapter, path, RF_TXBIAS_A, MASKDWORD)));
+
+ /* PA11+PAD01111, one shot */
+ i = 0;
+ do {
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, MASKH3BYTES, 0x800000);
+ {
+ odm_set_bb_reg(p_dm_odm, APK_offset[path], MASKDWORD, APK_value[0]);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() offset 0x%x value 0x%x\n", APK_offset[path], odm_get_bb_reg(p_dm_odm, APK_offset[path], MASKDWORD)));
+ ODM_delay_ms(3);
+ odm_set_bb_reg(p_dm_odm, APK_offset[path], MASKDWORD, APK_value[1]);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() offset 0x%x value 0x%x\n", APK_offset[path], odm_get_bb_reg(p_dm_odm, APK_offset[path], MASKDWORD)));
+
+ ODM_delay_ms(20);
+ }
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, MASKH3BYTES, 0x000000);
+
+ if (path == ODM_RF_PATH_A)
+ tmp_reg = odm_get_bb_reg(p_dm_odm, REG_APK, 0x03E00000);
+ else
+ tmp_reg = odm_get_bb_reg(p_dm_odm, REG_APK, 0xF8000000);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_phy_ap_calibrate_8188e() offset 0xbd8[25:21] %x\n", tmp_reg));
+
+ i++;
+ } while (tmp_reg > apkbound && i < 4);
+
+ APK_result[path][index] = tmp_reg;
+ }
+ }
+
+ /* reload MAC default value */
+ _phy_reload_mac_registers(p_adapter, MAC_REG, MAC_backup);
+
+ /* reload BB default value */
+ for (index = 0; index < APK_BB_REG_NUM ; index++) {
+
+ if (index == 0) /* skip */
+ continue;
+ odm_set_bb_reg(p_dm_odm, BB_REG[index], MASKDWORD, BB_backup[index]);
+ }
+
+ /* reload AFE default value */
+ _phy_reload_adda_registers(p_adapter, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM);
+
+ /* reload RF path default value */
+ for (path = 0; path < pathbound; path++) {
+ odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)path, 0xd, MASKDWORD, reg_d[path]);
+ if (path == ODM_RF_PATH_B) {
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_MODE1, MASKDWORD, 0x1000f);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_MODE2, MASKDWORD, 0x20101);
+ }
+
+ /* note no index == 0 */
+ if (APK_result[path][1] > 6)
+ APK_result[path][1] = 6;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("apk path %d result %d 0x%x \t", path, 1, APK_result[path][1]));
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("\n"));
+
+ for (path = 0; path < pathbound; path++) {
+ odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)path, 0x3, MASKDWORD,
+ ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (APK_result[path][1] << 5) | APK_result[path][1]));
+ if (path == ODM_RF_PATH_A)
+ odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)path, 0x4, MASKDWORD,
+ ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x00 << 5) | 0x05));
+ else
+ odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)path, 0x4, MASKDWORD,
+ ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x02 << 5) | 0x05));
+ odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)path, RF_BS_PA_APSET_G9_G11, MASKDWORD,
+ ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | 0x08));
+ }
+
+ p_dm_odm->rf_calibrate_info.is_ap_kdone = true;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("<==_phy_ap_calibrate_8188e()\n"));
+}
+
+#define DP_BB_REG_NUM 7
+#define DP_RF_REG_NUM 1
+#define DP_RETRY_LIMIT 10
+#define DP_PATH_NUM 2
+#define DP_DPK_NUM 3
+#define DP_DPK_VALUE_NUM 2
+
+void
+phy_iq_calibrate_8188e(
+ struct _ADAPTER *p_adapter,
+ bool is_recovery
+)
+{
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+
+#if (MP_DRIVER == 1)
+ PMPT_CONTEXT p_mpt_ctx = &(p_adapter->mppriv.mpt_ctx);
+#endif/* (MP_DRIVER == 1) */
+
+ s32 result[4][8]; /* last is final result */
+ u8 i, final_candidate, indexforchannel;
+ u8 channel_to_iqk = 7;
+ bool is_patha_ok, is_pathb_ok;
+ s32 rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, regecc, reg_tmp = 0;
+ bool is12simular, is13simular, is23simular;
+ bool is_start_cont_tx = false, is_single_tone = false, is_carrier_suppression = false;
+ u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
+ REG_OFDM_0_XA_RX_IQ_IMBALANCE, REG_OFDM_0_XB_RX_IQ_IMBALANCE,
+ REG_OFDM_0_ECCA_THRESHOLD, REG_OFDM_0_AGC_RSSI_TABLE,
+ REG_OFDM_0_XA_TX_IQ_IMBALANCE, REG_OFDM_0_XB_TX_IQ_IMBALANCE,
+ REG_OFDM_0_XC_TX_AFE, REG_OFDM_0_XD_TX_AFE,
+ REG_OFDM_0_RX_IQ_EXT_ANTA
+ };
+ u32 start_time;
+ s32 progressing_time;
+
+ if (odm_check_power_status(p_adapter) == false)
+ return;
+
+ if (!(p_dm_odm->support_ability & ODM_RF_CALIBRATION))
+ return;
+
+#if MP_DRIVER == 1
+ if (p_dm_odm->mp_mode == true) {
+ is_start_cont_tx = p_mpt_ctx->is_start_cont_tx;
+ is_single_tone = p_mpt_ctx->is_single_tone;
+ is_carrier_suppression = p_mpt_ctx->is_carrier_suppression;
+ }
+#endif
+
+ /* 20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
+ if (is_single_tone || is_carrier_suppression)
+ return;
+
+#if DISABLE_BB_RF
+ return;
+#endif
+
+ if (p_dm_odm->rf_calibrate_info.is_iqk_in_progress)
+ return;
+
+ if (is_recovery) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("phy_iq_calibrate_8188e: Return due to is_recovery!\n"));
+ _phy_reload_adda_registers(p_adapter, IQK_BB_REG_92C, p_dm_odm->rf_calibrate_info.IQK_BB_backup_recover, 9);
+ return;
+ }
+
+ odm_acquire_spin_lock(p_dm_odm, RT_IQK_SPINLOCK);
+ p_dm_odm->rf_calibrate_info.is_iqk_in_progress = true;
+ odm_release_spin_lock(p_dm_odm, RT_IQK_SPINLOCK);
+
+ start_time = odm_get_current_time(p_dm_odm);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK:Start!!!\n"));
+
+ for (i = 0; i < 8; i++) {
+ result[0][i] = 0;
+ result[1][i] = 0;
+ result[2][i] = 0;
+ result[3][i] = 0;
+ }
+ final_candidate = 0xff;
+ is_patha_ok = false;
+ is_pathb_ok = false;
+ is12simular = false;
+ is23simular = false;
+ is13simular = false;
+
+ for (i = 0; i < 3; i++) {
+ /* For 88C 1T1R */
+ _phy_iq_calibrate_8188e(p_adapter, result, i, false);
+
+ if (i == 1) {
+ is12simular = phy_simularity_compare_8188e(p_adapter, result, 0, 1);
+ if (is12simular) {
+ final_candidate = 0;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: is12simular final_candidate is %x\n", final_candidate));
+ break;
+ }
+ }
+
+ if (i == 2) {
+ is13simular = phy_simularity_compare_8188e(p_adapter, result, 0, 2);
+ if (is13simular) {
+ final_candidate = 0;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: is13simular final_candidate is %x\n", final_candidate));
+
+ break;
+ }
+ is23simular = phy_simularity_compare_8188e(p_adapter, result, 1, 2);
+ if (is23simular) {
+ final_candidate = 1;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: is23simular final_candidate is %x\n", final_candidate));
+ } else {
+ for (i = 0; i < 8; i++)
+ reg_tmp += result[3][i];
+
+ if (reg_tmp != 0)
+ final_candidate = 3;
+ else
+ final_candidate = 0xFF;
+ }
+ }
+ }
+ /* RT_TRACE(COMP_INIT,DBG_LOUD,("Release Mutex in IQCalibrate\n")); */
+
+ for (i = 0; i < 4; i++) {
+ rege94 = result[i][0];
+ rege9c = result[i][1];
+ regea4 = result[i][2];
+ regeac = result[i][3];
+ regeb4 = result[i][4];
+ regebc = result[i][5];
+ regec4 = result[i][6];
+ regecc = result[i][7];
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: rege94=%x rege9c=%x regea4=%x regeac=%x regeb4=%x regebc=%x regec4=%x regecc=%x\n ", rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, regecc));
+ }
+
+ if (final_candidate != 0xff) {
+ p_dm_odm->rf_calibrate_info.rege94 = rege94 = result[final_candidate][0];
+ p_dm_odm->rf_calibrate_info.rege9c = rege9c = result[final_candidate][1];
+ regea4 = result[final_candidate][2];
+ regeac = result[final_candidate][3];
+ p_dm_odm->rf_calibrate_info.regeb4 = regeb4 = result[final_candidate][4];
+ p_dm_odm->rf_calibrate_info.regebc = regebc = result[final_candidate][5];
+ regec4 = result[final_candidate][6];
+ regecc = result[final_candidate][7];
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: final_candidate is %x\n", final_candidate));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: rege94=%x rege9c=%x regea4=%x regeac=%x regeb4=%x regebc=%x regec4=%x regecc=%x\n ", rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, regecc));
+ is_patha_ok = is_pathb_ok = true;
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: FAIL use default value\n"));
+
+ p_dm_odm->rf_calibrate_info.rege94 = p_dm_odm->rf_calibrate_info.regeb4 = 0x100; /* X default value */
+ p_dm_odm->rf_calibrate_info.rege9c = p_dm_odm->rf_calibrate_info.regebc = 0x0; /* Y default value */
+ }
+
+ if ((rege94 != 0)/*&&(regea4 != 0)*/) {
+ _phy_path_a_fill_iqk_matrix(p_adapter, is_patha_ok, result, final_candidate, (regea4 == 0));
+ }
+
+ indexforchannel = odm_get_right_chnl_place_for_iqk(*p_dm_odm->p_channel);
+
+ /* To Fix BSOD when final_candidate is 0xff
+ * by sherry 20120321 */
+ if (final_candidate < 4) {
+ for (i = 0; i < iqk_matrix_reg_num; i++)
+ p_dm_odm->rf_calibrate_info.iqk_matrix_reg_setting[indexforchannel].value[0][i] = result[final_candidate][i];
+ p_dm_odm->rf_calibrate_info.iqk_matrix_reg_setting[indexforchannel].is_iqk_done = true;
+ }
+ /* RT_DISP(FINIT, INIT_IQK, ("\nIQK OK indexforchannel %d.\n", indexforchannel)); */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("\nIQK OK indexforchannel %d.\n", indexforchannel));
+
+ _phy_save_adda_registers(p_adapter, IQK_BB_REG_92C, p_dm_odm->rf_calibrate_info.IQK_BB_backup_recover, 9);
+
+ odm_acquire_spin_lock(p_dm_odm, RT_IQK_SPINLOCK);
+ p_dm_odm->rf_calibrate_info.is_iqk_in_progress = false;
+ odm_release_spin_lock(p_dm_odm, RT_IQK_SPINLOCK);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK finished\n"));
+ progressing_time = odm_get_progressing_time(p_dm_odm, start_time);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK progressing_time = %d\n", progressing_time));
+
+}
+
+void
+phy_lc_calibrate_8188e(
+ void *p_dm_void
+)
+{
+ bool is_start_cont_tx = false, is_single_tone = false, is_carrier_suppression = false;
+ u32 timeout = 2000, timecount = 0;
+ u32 start_time;
+ s32 progressing_time;
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ struct _ADAPTER *p_adapter = p_dm_odm->adapter;
+ /* HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter); */
+
+#if (MP_DRIVER == 1)
+ PMPT_CONTEXT p_mpt_ctx = &(p_adapter->mppriv.mpt_ctx);
+
+ if (p_dm_odm->mp_mode == true) {
+ is_start_cont_tx = p_mpt_ctx->is_start_cont_tx;
+ is_single_tone = p_mpt_ctx->is_single_tone;
+ is_carrier_suppression = p_mpt_ctx->is_carrier_suppression;
+ }
+#endif
+
+#if DISABLE_BB_RF
+ return;
+#endif
+
+ if (!(p_dm_odm->support_ability & ODM_RF_CALIBRATION))
+ return;
+ /* 20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
+ if (is_single_tone || is_carrier_suppression)
+ return;
+
+ start_time = odm_get_current_time(p_dm_odm);
+ while (*(p_dm_odm->p_is_scan_in_process) && timecount < timeout) {
+ ODM_delay_ms(50);
+ timecount += 50;
+ }
+
+ p_dm_odm->rf_calibrate_info.is_lck_in_progress = true;
+
+ /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LCK:Start!!!interface %d currentband %x delay %d ms\n", p_dm_odm->interface_index, p_hal_data->CurrentBandType92D, timecount)); */
+ _phy_lc_calibrate_8188e(p_dm_odm, false);
+
+ p_dm_odm->rf_calibrate_info.is_lck_in_progress = false;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LCK:Finish!!!interface %d\n", p_dm_odm->interface_index));
+ progressing_time = odm_get_progressing_time(p_dm_odm, start_time);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LCK progressing_time = %d\n", progressing_time));
+}
+
+static void _phy_set_rf_path_switch_8188e(
+ struct _ADAPTER *p_adapter,
+ bool is_main,
+ bool is2T
+)
+{
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+
+ if (!rtw_is_hw_init_completed(p_adapter)) {
+ u8 u1b_tmp;
+ u1b_tmp = odm_read_1byte(p_dm_odm, REG_LEDCFG2) | BIT(7);
+ odm_write_1byte(p_dm_odm, REG_LEDCFG2, u1b_tmp);
+ /* odm_set_bb_reg(p_dm_odm, REG_LEDCFG0, BIT23, 0x01); */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XAB_RF_PARAMETER, BIT(13), 0x01);
+ }
+
+ if (is2T) { /* 92C */
+ if (is_main)
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XB_RF_INTERFACE_OE, BIT(5) | BIT6, 0x1); /* 92C_Path_A */
+ else
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XB_RF_INTERFACE_OE, BIT(5) | BIT6, 0x2); /* BT */
+ } else { /* 88C */
+
+ /* <20120504, Kordan> [8188E] We should make AntDiversity controlled by HW (0x870[9:8] = 0), */
+ /* otherwise the following action has no effect. (0x860[9:8] has the effect only if AntDiversity controlled by SW) */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XAB_RF_INTERFACE_SW, BIT(8) | BIT(9), 0x0);
+ odm_set_bb_reg(p_dm_odm, 0x914, MASKLWORD, 0x0201); /* Set up the ant mapping table */
+
+ if (is_main) {
+ /* odm_set_bb_reg(p_dm_odm, REG_FPGA0_XA_RF_INTERFACE_OE, BIT(8)|BIT9, 0x2); */ /* Tx Main (SW control)(The right antenna) */
+ /* 4 [ Tx ] */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XA_RF_INTERFACE_OE, BIT(14) | BIT13 | BIT12, 0x1); /* Tx Main (HW control)(The right antenna) */
+
+ /* 4 [ Rx ] */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XB_RF_INTERFACE_OE, BIT(5) | BIT4 | BIT3, 0x1); /* ant_div_type = TRDiv, right antenna */
+ if (p_dm_odm->ant_div_type == CGCS_RX_HW_ANTDIV)
+ odm_set_bb_reg(p_dm_odm, REG_CONFIG_RAM64X16, BIT(31), 0x1); /* RxCG, Default is RxCG. ant_div_type = 2RDiv, left antenna */
+
+ } else {
+ /* odm_set_bb_reg(p_dm_odm, REG_FPGA0_XA_RF_INTERFACE_OE, BIT(8)|BIT9, 0x1); */ /* Tx Aux (SW control)(The left antenna) */
+ /* 4 [ Tx ] */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XA_RF_INTERFACE_OE, BIT(14) | BIT13 | BIT12, 0x0); /* Tx Aux (HW control)(The left antenna) */
+
+ /* 4 [ Rx ] */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XB_RF_INTERFACE_OE, BIT(5) | BIT4 | BIT3, 0x0); /* ant_div_type = TRDiv, left antenna */
+ if (p_dm_odm->ant_div_type == CGCS_RX_HW_ANTDIV)
+ odm_set_bb_reg(p_dm_odm, REG_CONFIG_RAM64X16, BIT(31), 0x0); /* RxCS, ant_div_type = 2RDiv, right antenna */
+ }
+
+ }
+}
+void phy_set_rf_path_switch_8188e(
+ struct _ADAPTER *p_adapter,
+ bool is_main
+)
+{
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+
+#if DISABLE_BB_RF
+ return;
+#endif
+
+ {
+ /* For 88C 1T1R */
+ _phy_set_rf_path_switch_8188e(p_adapter, is_main, false);
+ }
+}
+
+
diff --git a/drivers/staging/rtl8188eu/hal/halphyrf_8188e_ce.h b/drivers/staging/rtl8188eu/hal/halphyrf_8188e_ce.h
new file mode 100644
index 000000000000..bd40705904c4
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/halphyrf_8188e_ce.h
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __HAL_PHY_RF_8188E_H__
+#define __HAL_PHY_RF_8188E_H__
+
+/*--------------------------Define Parameters-------------------------------*/
+#define IQK_DELAY_TIME_88E 10 /* ms */
+#define index_mapping_NUM_88E 15
+#define AVG_THERMAL_NUM_88E 4
+
+#include "halphyrf_ce.h"
+
+void configure_txpower_track_8188e(
+ struct _TXPWRTRACK_CFG *p_config
+);
+
+void
+get_delta_swing_table_8188e(
+ void *p_dm_void,
+ u8 **temperature_up_a,
+ u8 **temperature_down_a,
+ u8 **temperature_up_b,
+ u8 **temperature_down_b
+);
+
+void do_iqk_8188e(
+ void *p_dm_void,
+ u8 delta_thermal_index,
+ u8 thermal_value,
+ u8 threshold
+);
+
+void
+odm_tx_pwr_track_set_pwr88_e(
+ void *p_dm_void,
+ enum pwrtrack_method method,
+ u8 rf_path,
+ u8 channel_mapped_index
+);
+
+/* 1 7. IQK */
+
+void
+phy_iq_calibrate_8188e(
+ struct _ADAPTER *adapter,
+ bool is_recovery);
+
+/*
+ * LC calibrate
+ * */
+void
+phy_lc_calibrate_8188e(
+ void *p_dm_void
+);
+
+void
+phy_digital_predistortion_8188e(struct _ADAPTER *p_adapter);
+
+
+void
+_phy_save_adda_registers(
+ struct _ADAPTER *p_adapter,
+ u32 *adda_reg,
+ u32 *adda_backup,
+ u32 register_num
+);
+
+void
+_phy_path_adda_on(
+ struct _ADAPTER *p_adapter,
+ u32 *adda_reg,
+ bool is_path_a_on,
+ bool is2T
+);
+
+void
+_phy_mac_setting_calibration(
+ struct _ADAPTER *p_adapter,
+ u32 *mac_reg,
+ u32 *mac_backup
+);
+
+
+void
+_phy_path_a_stand_by(
+ struct _ADAPTER *p_adapter
+);
+
+
+#endif /* #ifndef __HAL_PHY_RF_8188E_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/halphyrf_ap.h b/drivers/staging/rtl8188eu/hal/halphyrf_ap.h
new file mode 100644
index 000000000000..065fe30dadf5
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/halphyrf_ap.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __HAL_PHY_RF_H__
+#define __HAL_PHY_RF_H__
+
+#include "phydm_powertracking_ap.h"
+
+enum pwrtrack_method {
+ BBSWING,
+ TXAGC,
+ MIX_MODE,
+ TSSI_MODE
+};
+
+typedef void (*func_set_pwr)(void *, enum pwrtrack_method, u8, u8);
+typedef void(*func_iqk)(void *, u8, u8, u8);
+typedef void (*func_lck)(void *);
+/* refine by YuChen for 8814A */
+typedef void (*func_swing)(void *, u8 **, u8 **, u8 **, u8 **);
+typedef void (*func_swing8814only)(void *, u8 **, u8 **, u8 **, u8 **);
+typedef void (*func_all_swing)(void *, u8 **, u8 **, u8 **, u8 **, u8 **, u8 **, u8 **, u8 **);
+
+
+struct _TXPWRTRACK_CFG {
+ u8 swing_table_size_cck;
+ u8 swing_table_size_ofdm;
+ u8 threshold_iqk;
+ u8 threshold_dpk;
+ u8 average_thermal_num;
+ u8 rf_path_count;
+ u32 thermal_reg_addr;
+ func_set_pwr odm_tx_pwr_track_set_pwr;
+ func_iqk do_iqk;
+ func_lck phy_lc_calibrate;
+ func_swing get_delta_swing_table;
+ func_swing8814only get_delta_swing_table8814only;
+ func_all_swing get_delta_all_swing_table;
+};
+
+void
+configure_txpower_track(
+ void *p_dm_void,
+ struct _TXPWRTRACK_CFG *p_config
+);
+
+void
+odm_txpowertracking_callback_thermal_meter(
+ struct _ADAPTER *adapter
+);
+
+#if ODM_IC_11AC_SERIES_SUPPORT
+void
+odm_txpowertracking_callback_thermal_meter_jaguar_series(
+ struct _ADAPTER *adapter
+);
+
+#define IS_CCK_RATE(_rate) (ODM_MGN_1M == _rate || _rate == ODM_MGN_2M || _rate == ODM_MGN_5_5M || _rate == ODM_MGN_11M)
+
+
+#define ODM_TARGET_CHNL_NUM_2G_5G 59
+
+void
+odm_reset_iqk_result(
+ void *p_dm_void
+);
+u8
+odm_get_right_chnl_place_for_iqk(
+ u8 chnl
+);
+
+void phydm_rf_init(void *p_dm_void);
+void phydm_rf_watchdog(void *p_dm_void);
+
+#endif /* #ifndef __HAL_PHY_RF_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/halphyrf_ce.c b/drivers/staging/rtl8188eu/hal/halphyrf_ce.c
new file mode 100644
index 000000000000..d5737272dee9
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/halphyrf_ce.c
@@ -0,0 +1,635 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+#define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _delta_thermal) \
+ do {\
+ for (_offset = 0; _offset < _size; _offset++) { \
+ \
+ if (_delta_thermal < thermal_threshold[_direction][_offset]) { \
+ \
+ if (_offset != 0)\
+ _offset--;\
+ break;\
+ } \
+ } \
+ if (_offset >= _size)\
+ _offset = _size-1;\
+ } while (0)
+
+void configure_txpower_track(
+ void *p_dm_void,
+ struct _TXPWRTRACK_CFG *p_config
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E)
+ configure_txpower_track_8188e(p_config);
+}
+
+/* **********************************************************************
+ * <20121113, Kordan> This function should be called when tx_agc changed.
+ * Otherwise the previous compensation is gone, because we record the
+ * delta of temperature between two TxPowerTracking watch dogs.
+ *
+ * NOTE: If Tx BB swing or Tx scaling is varified during run-time, still
+ * need to call this function.
+ * ********************************************************************** */
+void
+odm_clear_txpowertracking_state(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ PHAL_DATA_TYPE p_hal_data = GET_HAL_DATA(p_dm_odm->adapter);
+ u8 p = 0;
+ struct odm_rf_calibration_structure *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
+
+ p_rf_calibrate_info->bb_swing_idx_cck_base = p_rf_calibrate_info->default_cck_index;
+ p_rf_calibrate_info->bb_swing_idx_cck = p_rf_calibrate_info->default_cck_index;
+ p_dm_odm->rf_calibrate_info.CCK_index = 0;
+
+ for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) {
+ p_rf_calibrate_info->bb_swing_idx_ofdm_base[p] = p_rf_calibrate_info->default_ofdm_index;
+ p_rf_calibrate_info->bb_swing_idx_ofdm[p] = p_rf_calibrate_info->default_ofdm_index;
+ p_rf_calibrate_info->OFDM_index[p] = p_rf_calibrate_info->default_ofdm_index;
+
+ p_rf_calibrate_info->power_index_offset[p] = 0;
+ p_rf_calibrate_info->delta_power_index[p] = 0;
+ p_rf_calibrate_info->delta_power_index_last[p] = 0;
+
+ p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = 0; /* Initial Mix mode power tracking*/
+ p_rf_calibrate_info->remnant_ofdm_swing_idx[p] = 0;
+ p_rf_calibrate_info->kfree_offset[p] = 0;
+ }
+
+ p_rf_calibrate_info->modify_tx_agc_flag_path_a = false; /*Initial at Modify Tx Scaling mode*/
+ p_rf_calibrate_info->modify_tx_agc_flag_path_b = false; /*Initial at Modify Tx Scaling mode*/
+ p_rf_calibrate_info->modify_tx_agc_flag_path_c = false; /*Initial at Modify Tx Scaling mode*/
+ p_rf_calibrate_info->modify_tx_agc_flag_path_d = false; /*Initial at Modify Tx Scaling mode*/
+ p_rf_calibrate_info->remnant_cck_swing_idx = 0;
+ p_rf_calibrate_info->thermal_value = p_hal_data->eeprom_thermal_meter;
+
+ p_rf_calibrate_info->modify_tx_agc_value_cck = 0; /* modify by Mingzhi.Guo */
+ p_rf_calibrate_info->modify_tx_agc_value_ofdm = 0; /* modify by Mingzhi.Guo */
+
+}
+
+void
+odm_txpowertracking_callback_thermal_meter(
+ struct _ADAPTER *adapter
+)
+{
+
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->odmpriv;
+ struct odm_rf_calibration_structure *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
+ u8 thermal_value = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0;
+ s8 diff_DPK[4] = {0};
+ u8 thermal_value_avg_count = 0;
+ u32 thermal_value_avg = 0, regc80, regcd0, regcd4, regab4;
+ u8 OFDM_min_index = 0; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */
+ u8 indexforchannel = 0; /* get_right_chnl_place_for_iqk(p_hal_data->current_channel) */
+ u8 power_tracking_type = p_hal_data->rf_power_tracking_type;
+ u8 xtal_offset_eanble = 0;
+ struct _TXPWRTRACK_CFG c;
+ /* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */
+ u8 *delta_swing_table_idx_tup_a = NULL;
+ u8 *delta_swing_table_idx_tdown_a = NULL;
+ u8 *delta_swing_table_idx_tup_b = NULL;
+ u8 *delta_swing_table_idx_tdown_b = NULL;
+ /*for 8814 add by Yu Chen*/
+ u8 *delta_swing_table_idx_tup_c = NULL;
+ u8 *delta_swing_table_idx_tdown_c = NULL;
+ u8 *delta_swing_table_idx_tup_d = NULL;
+ u8 *delta_swing_table_idx_tdown_d = NULL;
+ /*for Xtal Offset by James.Tung*/
+ s8 *delta_swing_table_xtal_up = NULL;
+ s8 *delta_swing_table_xtal_down = NULL;
+
+ /* 4 2. Initilization ( 7 steps in total ) */
+
+ configure_txpower_track(p_dm_odm, &c);
+
+ (*c.get_delta_swing_table)(p_dm_odm, (u8 **)&delta_swing_table_idx_tup_a, (u8 **)&delta_swing_table_idx_tdown_a,
+ (u8 **)&delta_swing_table_idx_tup_b, (u8 **)&delta_swing_table_idx_tdown_b);
+
+ if (p_dm_odm->support_ic_type & ODM_RTL8814A) /*for 8814 path C & D*/
+ (*c.get_delta_swing_table8814only)(p_dm_odm, (u8 **)&delta_swing_table_idx_tup_c, (u8 **)&delta_swing_table_idx_tdown_c,
+ (u8 **)&delta_swing_table_idx_tup_d, (u8 **)&delta_swing_table_idx_tdown_d);
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D)) /*for Xtal Offset*/
+ (*c.get_delta_swing_xtal_table)(p_dm_odm, (s8 **)&delta_swing_table_xtal_up, (s8 **)&delta_swing_table_xtal_down);
+
+ p_rf_calibrate_info->txpowertracking_callback_cnt++; /*cosa add for debug*/
+ p_rf_calibrate_info->is_txpowertracking_init = true;
+
+ /*p_rf_calibrate_info->txpowertrack_control = p_hal_data->txpowertrack_control;
+ <Kordan> We should keep updating the control variable according to HalData.
+ <Kordan> rf_calibrate_info.rega24 will be initialized when ODM HW configuring, but MP configures with para files. */
+ if (p_dm_odm->mp_mode == true)
+ p_rf_calibrate_info->rega24 = 0x090e1317;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("===>odm_txpowertracking_callback_thermal_meter\n p_rf_calibrate_info->bb_swing_idx_cck_base: %d, p_rf_calibrate_info->bb_swing_idx_ofdm_base[A]: %d, p_rf_calibrate_info->default_ofdm_index: %d\n",
+ p_rf_calibrate_info->bb_swing_idx_cck_base, p_rf_calibrate_info->bb_swing_idx_ofdm_base[ODM_RF_PATH_A], p_rf_calibrate_info->default_ofdm_index));
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("p_rf_calibrate_info->txpowertrack_control=%d, p_hal_data->eeprom_thermal_meter %d\n", p_rf_calibrate_info->txpowertrack_control, p_hal_data->eeprom_thermal_meter));
+ thermal_value = (u8)odm_get_rf_reg(p_dm_odm, ODM_RF_PATH_A, c.thermal_reg_addr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */
+
+ /*add log by zhao he, check c80/c94/c14/ca0 value*/
+ if (p_dm_odm->support_ic_type == ODM_RTL8723D) {
+ regc80 = odm_get_bb_reg(p_dm_odm, 0xc80, MASKDWORD);
+ regcd0 = odm_get_bb_reg(p_dm_odm, 0xcd0, MASKDWORD);
+ regcd4 = odm_get_bb_reg(p_dm_odm, 0xcd4, MASKDWORD);
+ regab4 = odm_get_bb_reg(p_dm_odm, 0xab4, 0x000007FF);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", regc80, regcd0, regcd4, regab4));
+ }
+
+ if (!p_rf_calibrate_info->txpowertrack_control)
+ return;
+
+
+ /*4 3. Initialize ThermalValues of rf_calibrate_info*/
+
+ if (p_rf_calibrate_info->is_reloadtxpowerindex)
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("reload ofdm index for band switch\n"));
+
+ /*4 4. Calculate average thermal meter*/
+
+ p_rf_calibrate_info->thermal_value_avg[p_rf_calibrate_info->thermal_value_avg_index] = thermal_value;
+ p_rf_calibrate_info->thermal_value_avg_index++;
+ if (p_rf_calibrate_info->thermal_value_avg_index == c.average_thermal_num) /*Average times = c.average_thermal_num*/
+ p_rf_calibrate_info->thermal_value_avg_index = 0;
+
+ for (i = 0; i < c.average_thermal_num; i++) {
+ if (p_rf_calibrate_info->thermal_value_avg[i]) {
+ thermal_value_avg += p_rf_calibrate_info->thermal_value_avg[i];
+ thermal_value_avg_count++;
+ }
+ }
+
+ if (thermal_value_avg_count) { /* Calculate Average thermal_value after average enough times */
+ thermal_value = (u8)(thermal_value_avg / thermal_value_avg_count);
+ p_rf_calibrate_info->thermal_value_delta = thermal_value - p_hal_data->eeprom_thermal_meter;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("AVG Thermal Meter = 0x%X, EFUSE Thermal base = 0x%X\n", thermal_value, p_hal_data->eeprom_thermal_meter));
+ }
+
+ /* 4 5. Calculate delta, delta_LCK, delta_IQK. */
+
+ /* "delta" here is used to determine whether thermal value changes or not. */
+ delta = (thermal_value > p_rf_calibrate_info->thermal_value) ? (thermal_value - p_rf_calibrate_info->thermal_value) : (p_rf_calibrate_info->thermal_value - thermal_value);
+ delta_LCK = (thermal_value > p_rf_calibrate_info->thermal_value_lck) ? (thermal_value - p_rf_calibrate_info->thermal_value_lck) : (p_rf_calibrate_info->thermal_value_lck - thermal_value);
+ delta_IQK = (thermal_value > p_rf_calibrate_info->thermal_value_iqk) ? (thermal_value - p_rf_calibrate_info->thermal_value_iqk) : (p_rf_calibrate_info->thermal_value_iqk - thermal_value);
+
+ if (p_rf_calibrate_info->thermal_value_iqk == 0xff) { /*no PG, use thermal value for IQK*/
+ p_rf_calibrate_info->thermal_value_iqk = thermal_value;
+ delta_IQK = (thermal_value > p_rf_calibrate_info->thermal_value_iqk) ? (thermal_value - p_rf_calibrate_info->thermal_value_iqk) : (p_rf_calibrate_info->thermal_value_iqk - thermal_value);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("no PG, use thermal_value for IQK\n"));
+ }
+
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ diff_DPK[p] = (s8)thermal_value - (s8)p_rf_calibrate_info->dpk_thermal[p];
+
+ /*4 6. If necessary, do LCK.*/
+
+ if (!(p_dm_odm->support_ic_type & ODM_RTL8821)) { /*no PG, do LCK at initial status*/
+ if (p_rf_calibrate_info->thermal_value_lck == 0xff) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("no PG, do LCK\n"));
+ p_rf_calibrate_info->thermal_value_lck = thermal_value;
+
+ /*Use RTLCK, so close power tracking driver LCK*/
+ if (!(p_dm_odm->support_ic_type & ODM_RTL8814A)) {
+ if (c.phy_lc_calibrate)
+ (*c.phy_lc_calibrate)(p_dm_odm);
+ }
+
+ delta_LCK = (thermal_value > p_rf_calibrate_info->thermal_value_lck) ? (thermal_value - p_rf_calibrate_info->thermal_value_lck) : (p_rf_calibrate_info->thermal_value_lck - thermal_value);
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", delta, delta_LCK, delta_IQK));
+
+ /* Delta temperature is equal to or larger than 20 centigrade.*/
+ if (delta_LCK >= c.threshold_iqk) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("delta_LCK(%d) >= threshold_iqk(%d)\n", delta_LCK, c.threshold_iqk));
+ p_rf_calibrate_info->thermal_value_lck = thermal_value;
+
+ /*Use RTLCK, so close power tracking driver LCK*/
+ if (!(p_dm_odm->support_ic_type & ODM_RTL8814A)) {
+ if (c.phy_lc_calibrate)
+ (*c.phy_lc_calibrate)(p_dm_odm);
+ }
+ }
+ }
+
+ /*3 7. If necessary, move the index of swing table to adjust Tx power.*/
+
+ if (delta > 0 && p_rf_calibrate_info->txpowertrack_control) {
+ /* "delta" here is used to record the absolute value of differrence. */
+ delta = thermal_value > p_hal_data->eeprom_thermal_meter ? (thermal_value - p_hal_data->eeprom_thermal_meter) : (p_hal_data->eeprom_thermal_meter - thermal_value);
+ if (delta >= TXPWR_TRACK_TABLE_SIZE)
+ delta = TXPWR_TRACK_TABLE_SIZE - 1;
+
+ /*4 7.1 The Final Power index = BaseIndex + power_index_offset*/
+
+ if (thermal_value > p_hal_data->eeprom_thermal_meter) {
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
+ p_rf_calibrate_info->delta_power_index_last[p] = p_rf_calibrate_info->delta_power_index[p]; /*recording poer index offset*/
+ switch (p) {
+ case ODM_RF_PATH_B:
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("delta_swing_table_idx_tup_b[%d] = %d\n", delta, delta_swing_table_idx_tup_b[delta]));
+
+ p_rf_calibrate_info->delta_power_index[p] = delta_swing_table_idx_tup_b[delta];
+ p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_b[delta]; /*Record delta swing for mix mode power tracking*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("******Temp is higher and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
+ break;
+
+ case ODM_RF_PATH_C:
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("delta_swing_table_idx_tup_c[%d] = %d\n", delta, delta_swing_table_idx_tup_c[delta]));
+
+ p_rf_calibrate_info->delta_power_index[p] = delta_swing_table_idx_tup_c[delta];
+ p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_c[delta]; /*Record delta swing for mix mode power tracking*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("******Temp is higher and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
+ break;
+
+ case ODM_RF_PATH_D:
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("delta_swing_table_idx_tup_d[%d] = %d\n", delta, delta_swing_table_idx_tup_d[delta]));
+
+ p_rf_calibrate_info->delta_power_index[p] = delta_swing_table_idx_tup_d[delta];
+ p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_d[delta]; /*Record delta swing for mix mode power tracking*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("******Temp is higher and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
+ break;
+
+ default:
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("delta_swing_table_idx_tup_a[%d] = %d\n", delta, delta_swing_table_idx_tup_a[delta]));
+
+ p_rf_calibrate_info->delta_power_index[p] = delta_swing_table_idx_tup_a[delta];
+ p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = delta_swing_table_idx_tup_a[delta]; /*Record delta swing for mix mode power tracking*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("******Temp is higher and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
+ break;
+ }
+ }
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D)) {
+ /*Save xtal_offset from Xtal table*/
+ p_rf_calibrate_info->xtal_offset_last = p_rf_calibrate_info->xtal_offset; /*recording last Xtal offset*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("[Xtal] delta_swing_table_xtal_up[%d] = %d\n", delta, delta_swing_table_xtal_up[delta]));
+ p_rf_calibrate_info->xtal_offset = delta_swing_table_xtal_up[delta];
+
+ if (p_rf_calibrate_info->xtal_offset_last == p_rf_calibrate_info->xtal_offset)
+ xtal_offset_eanble = 0;
+ else
+ xtal_offset_eanble = 1;
+ }
+
+ } else {
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
+ p_rf_calibrate_info->delta_power_index_last[p] = p_rf_calibrate_info->delta_power_index[p]; /*recording poer index offset*/
+
+ switch (p) {
+ case ODM_RF_PATH_B:
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("delta_swing_table_idx_tdown_b[%d] = %d\n", delta, delta_swing_table_idx_tdown_b[delta]));
+ p_rf_calibrate_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_b[delta];
+ p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_b[delta]; /*Record delta swing for mix mode power tracking*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("******Temp is lower and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
+ break;
+
+ case ODM_RF_PATH_C:
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("delta_swing_table_idx_tdown_c[%d] = %d\n", delta, delta_swing_table_idx_tdown_c[delta]));
+ p_rf_calibrate_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_c[delta];
+ p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_c[delta]; /*Record delta swing for mix mode power tracking*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("******Temp is lower and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
+ break;
+
+ case ODM_RF_PATH_D:
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("delta_swing_table_idx_tdown_d[%d] = %d\n", delta, delta_swing_table_idx_tdown_d[delta]));
+ p_rf_calibrate_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_d[delta];
+ p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_d[delta]; /*Record delta swing for mix mode power tracking*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("******Temp is lower and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
+ break;
+
+ default:
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("delta_swing_table_idx_tdown_a[%d] = %d\n", delta, delta_swing_table_idx_tdown_a[delta]));
+ p_rf_calibrate_info->delta_power_index[p] = -1 * delta_swing_table_idx_tdown_a[delta];
+ p_rf_calibrate_info->absolute_ofdm_swing_idx[p] = -1 * delta_swing_table_idx_tdown_a[delta]; /*Record delta swing for mix mode power tracking*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("******Temp is lower and p_rf_calibrate_info->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n", p_rf_calibrate_info->absolute_ofdm_swing_idx[p]));
+ break;
+ }
+ }
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723D)) {
+ /*Save xtal_offset from Xtal table*/
+ p_rf_calibrate_info->xtal_offset_last = p_rf_calibrate_info->xtal_offset; /*recording last Xtal offset*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("[Xtal] delta_swing_table_xtal_down[%d] = %d\n", delta, delta_swing_table_xtal_down[delta]));
+ p_rf_calibrate_info->xtal_offset = delta_swing_table_xtal_down[delta];
+
+ if (p_rf_calibrate_info->xtal_offset_last == p_rf_calibrate_info->xtal_offset)
+ xtal_offset_eanble = 0;
+ else
+ xtal_offset_eanble = 1;
+ }
+
+ }
+
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("\n\n=========================== [path-%d] Calculating power_index_offset===========================\n", p));
+
+ if (p_rf_calibrate_info->delta_power_index[p] == p_rf_calibrate_info->delta_power_index_last[p]) /*If Thermal value changes but lookup table value still the same*/
+ p_rf_calibrate_info->power_index_offset[p] = 0;
+ else
+ p_rf_calibrate_info->power_index_offset[p] = p_rf_calibrate_info->delta_power_index[p] - p_rf_calibrate_info->delta_power_index_last[p]; /*Power index diff between 2 times Power Tracking*/
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("[path-%d] power_index_offset(%d) = delta_power_index(%d) - delta_power_index_last(%d)\n", p, p_rf_calibrate_info->power_index_offset[p], p_rf_calibrate_info->delta_power_index[p], p_rf_calibrate_info->delta_power_index_last[p]));
+
+ p_rf_calibrate_info->OFDM_index[p] = p_rf_calibrate_info->bb_swing_idx_ofdm_base[p] + p_rf_calibrate_info->power_index_offset[p];
+ p_rf_calibrate_info->CCK_index = p_rf_calibrate_info->bb_swing_idx_cck_base + p_rf_calibrate_info->power_index_offset[p];
+
+ p_rf_calibrate_info->bb_swing_idx_cck = p_rf_calibrate_info->CCK_index;
+ p_rf_calibrate_info->bb_swing_idx_ofdm[p] = p_rf_calibrate_info->OFDM_index[p];
+
+ /*************Print BB Swing base and index Offset*************/
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("The 'CCK' final index(%d) = BaseIndex(%d) + power_index_offset(%d)\n", p_rf_calibrate_info->bb_swing_idx_cck, p_rf_calibrate_info->bb_swing_idx_cck_base, p_rf_calibrate_info->power_index_offset[p]));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("The 'OFDM' final index(%d) = BaseIndex[%d](%d) + power_index_offset(%d)\n", p_rf_calibrate_info->bb_swing_idx_ofdm[p], p, p_rf_calibrate_info->bb_swing_idx_ofdm_base[p], p_rf_calibrate_info->power_index_offset[p]));
+
+ /*4 7.1 Handle boundary conditions of index.*/
+
+ if (p_rf_calibrate_info->OFDM_index[p] > c.swing_table_size_ofdm - 1)
+ p_rf_calibrate_info->OFDM_index[p] = c.swing_table_size_ofdm - 1;
+ else if (p_rf_calibrate_info->OFDM_index[p] <= OFDM_min_index)
+ p_rf_calibrate_info->OFDM_index[p] = OFDM_min_index;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("\n\n========================================================================================================\n"));
+
+ if (p_rf_calibrate_info->CCK_index > c.swing_table_size_cck - 1)
+ p_rf_calibrate_info->CCK_index = c.swing_table_size_cck - 1;
+ else if (p_rf_calibrate_info->CCK_index <= 0)
+ p_rf_calibrate_info->CCK_index = 0;
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("The thermal meter is unchanged or TxPowerTracking OFF(%d): thermal_value: %d, p_rf_calibrate_info->thermal_value: %d\n",
+ p_rf_calibrate_info->txpowertrack_control, thermal_value, p_rf_calibrate_info->thermal_value));
+
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ p_rf_calibrate_info->power_index_offset[p] = 0;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n",
+ p_rf_calibrate_info->CCK_index, p_rf_calibrate_info->bb_swing_idx_cck_base)); /*Print Swing base & current*/
+
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index[%d]: %d\n",
+ p_rf_calibrate_info->OFDM_index[p], p, p_rf_calibrate_info->bb_swing_idx_ofdm_base[p]));
+ }
+
+ if ((p_dm_odm->support_ic_type & ODM_RTL8814A)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("power_tracking_type=%d\n", power_tracking_type));
+
+ if (power_tracking_type == 0) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX_MODE**********\n"));
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_MODE, p, 0);
+ } else if (power_tracking_type == 1) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX(2G) TSSI(5G) MODE**********\n"));
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_2G_TSSI_5G_MODE, p, 0);
+ } else if (power_tracking_type == 2) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX(5G) TSSI(2G)MODE**********\n"));
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_5G_TSSI_2G_MODE, p, 0);
+ } else if (power_tracking_type == 3) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking TSSI MODE**********\n"));
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, TSSI_MODE, p, 0);
+ }
+ p_rf_calibrate_info->thermal_value = thermal_value; /*Record last Power Tracking Thermal value*/
+
+ } else if ((p_rf_calibrate_info->power_index_offset[ODM_RF_PATH_A] != 0 ||
+ p_rf_calibrate_info->power_index_offset[ODM_RF_PATH_B] != 0 ||
+ p_rf_calibrate_info->power_index_offset[ODM_RF_PATH_C] != 0 ||
+ p_rf_calibrate_info->power_index_offset[ODM_RF_PATH_D] != 0) &&
+ p_rf_calibrate_info->txpowertrack_control && (p_hal_data->eeprom_thermal_meter != 0xff)) {
+ /* 4 7.2 Configure the Swing Table to adjust Tx Power. */
+
+ p_rf_calibrate_info->is_tx_power_changed = true; /*Always true after Tx Power is adjusted by power tracking.*/
+ /* */
+ /* 2012/04/23 MH According to Luke's suggestion, we can not write BB digital */
+ /* to increase TX power. Otherwise, EVM will be bad. */
+ /* */
+ /* 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */
+ if (thermal_value > p_rf_calibrate_info->thermal_value) {
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("Temperature Increasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
+ p, p_rf_calibrate_info->power_index_offset[p], delta, thermal_value, p_hal_data->eeprom_thermal_meter, p_rf_calibrate_info->thermal_value));
+ }
+ } else if (thermal_value < p_rf_calibrate_info->thermal_value) { /*Low temperature*/
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("Temperature Decreasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
+ p, p_rf_calibrate_info->power_index_offset[p], delta, thermal_value, p_hal_data->eeprom_thermal_meter, p_rf_calibrate_info->thermal_value));
+ }
+ }
+
+ if (thermal_value > p_hal_data->eeprom_thermal_meter) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("Temperature(%d) higher than PG value(%d)\n", thermal_value, p_hal_data->eeprom_thermal_meter));
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E || p_dm_odm->support_ic_type == ODM_RTL8192E || p_dm_odm->support_ic_type == ODM_RTL8821 ||
+ p_dm_odm->support_ic_type == ODM_RTL8812 || p_dm_odm->support_ic_type == ODM_RTL8723B || p_dm_odm->support_ic_type == ODM_RTL8814A ||
+ p_dm_odm->support_ic_type == ODM_RTL8703B || p_dm_odm->support_ic_type == ODM_RTL8188F || p_dm_odm->support_ic_type == ODM_RTL8822B ||
+ p_dm_odm->support_ic_type == ODM_RTL8723D || p_dm_odm->support_ic_type == ODM_RTL8821C) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX_MODE**********\n"));
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_MODE, p, 0);
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking BBSWING_MODE**********\n"));
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, BBSWING, p, indexforchannel);
+ }
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("Temperature(%d) lower than PG value(%d)\n", thermal_value, p_hal_data->eeprom_thermal_meter));
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E || p_dm_odm->support_ic_type == ODM_RTL8192E || p_dm_odm->support_ic_type == ODM_RTL8821 ||
+ p_dm_odm->support_ic_type == ODM_RTL8812 || p_dm_odm->support_ic_type == ODM_RTL8723B || p_dm_odm->support_ic_type == ODM_RTL8814A ||
+ p_dm_odm->support_ic_type == ODM_RTL8703B || p_dm_odm->support_ic_type == ODM_RTL8188F || p_dm_odm->support_ic_type == ODM_RTL8822B ||
+ p_dm_odm->support_ic_type == ODM_RTL8723D || p_dm_odm->support_ic_type == ODM_RTL8821C) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX_MODE**********\n"));
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, MIX_MODE, p, indexforchannel);
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking BBSWING_MODE**********\n"));
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ (*c.odm_tx_pwr_track_set_pwr)(p_dm_odm, BBSWING, p, indexforchannel);
+ }
+
+ }
+
+ p_rf_calibrate_info->bb_swing_idx_cck_base = p_rf_calibrate_info->bb_swing_idx_cck; /*Record last time Power Tracking result as base.*/
+ for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++)
+ p_rf_calibrate_info->bb_swing_idx_ofdm_base[p] = p_rf_calibrate_info->bb_swing_idx_ofdm[p];
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("p_rf_calibrate_info->thermal_value = %d thermal_value= %d\n", p_rf_calibrate_info->thermal_value, thermal_value));
+
+ p_rf_calibrate_info->thermal_value = thermal_value; /*Record last Power Tracking Thermal value*/
+
+ }
+
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8703B || p_dm_odm->support_ic_type == ODM_RTL8723D) {
+
+ if (xtal_offset_eanble != 0 && p_rf_calibrate_info->txpowertrack_control && (p_hal_data->eeprom_thermal_meter != 0xff)) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter Xtal Tracking**********\n"));
+
+ if (thermal_value > p_hal_data->eeprom_thermal_meter) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("Temperature(%d) higher than PG value(%d)\n", thermal_value, p_hal_data->eeprom_thermal_meter));
+ (*c.odm_txxtaltrack_set_xtal)(p_dm_odm);
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
+ ("Temperature(%d) lower than PG value(%d)\n", thermal_value, p_hal_data->eeprom_thermal_meter));
+ (*c.odm_txxtaltrack_set_xtal)(p_dm_odm);
+ }
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********End Xtal Tracking**********\n"));
+ }
+ if (p_rf_calibrate_info->dpk_thermal[ODM_RF_PATH_A] != 0) {
+ if (diff_DPK[ODM_RF_PATH_A] >= c.threshold_dpk) {
+ odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
+ odm_set_bb_reg(p_dm_odm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), (diff_DPK[ODM_RF_PATH_A] / c.threshold_dpk));
+ odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
+ } else if ((diff_DPK[ODM_RF_PATH_A] <= -1 * c.threshold_dpk)) {
+ s32 value = 0x20 + (diff_DPK[ODM_RF_PATH_A] / c.threshold_dpk);
+
+ odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
+ odm_set_bb_reg(p_dm_odm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), value);
+ odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
+ } else {
+ odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
+ odm_set_bb_reg(p_dm_odm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), 0);
+ odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
+ }
+ }
+ if (p_rf_calibrate_info->dpk_thermal[ODM_RF_PATH_B] != 0) {
+ if (diff_DPK[ODM_RF_PATH_B] >= c.threshold_dpk) {
+ odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
+ odm_set_bb_reg(p_dm_odm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), (diff_DPK[ODM_RF_PATH_B] / c.threshold_dpk));
+ odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
+ } else if ((diff_DPK[ODM_RF_PATH_B] <= -1 * c.threshold_dpk)) {
+ s32 value = 0x20 + (diff_DPK[ODM_RF_PATH_B] / c.threshold_dpk);
+
+ odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
+ odm_set_bb_reg(p_dm_odm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), value);
+ odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
+ } else {
+ odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x1);
+ odm_set_bb_reg(p_dm_odm, 0xec4, BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), 0);
+ odm_set_bb_reg(p_dm_odm, 0x82c, BIT(31), 0x0);
+ }
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("<===odm_txpowertracking_callback_thermal_meter\n"));
+
+ p_rf_calibrate_info->tx_powercount = 0;
+}
+
+
+
+/* 3============================================================
+ * 3 IQ Calibration
+ * 3============================================================ */
+
+void
+odm_reset_iqk_result(
+ void *p_dm_void
+)
+{
+ return;
+}
+u8 odm_get_right_chnl_place_for_iqk(u8 chnl)
+{
+ u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159, 161, 163, 165
+ };
+ u8 place = chnl;
+
+
+ if (chnl > 14) {
+ for (place = 14; place < sizeof(channel_all); place++) {
+ if (channel_all[place] == chnl)
+ return place - 13;
+ }
+ }
+ return 0;
+
+}
+
+static void odm_iq_calibrate(struct PHY_DM_STRUCT *p_dm_odm)
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+
+ if (p_dm_odm->is_linked) {
+ if ((*p_dm_odm->p_channel != p_dm_odm->pre_channel) && (!*p_dm_odm->p_is_scan_in_process)) {
+ p_dm_odm->pre_channel = *p_dm_odm->p_channel;
+ p_dm_odm->linked_interval = 0;
+ }
+
+ if (p_dm_odm->linked_interval < 3)
+ p_dm_odm->linked_interval++;
+ } else
+ p_dm_odm->linked_interval = 0;
+}
+
+void phydm_rf_init(void *p_dm_void)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ odm_txpowertracking_init(p_dm_odm);
+
+ odm_clear_txpowertracking_state(p_dm_odm);
+}
+
+void phydm_rf_watchdog(void *p_dm_void)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ odm_txpowertracking_check(p_dm_odm);
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
+ odm_iq_calibrate(p_dm_odm);
+}
diff --git a/drivers/staging/rtl8188eu/hal/halphyrf_ce.h b/drivers/staging/rtl8188eu/hal/halphyrf_ce.h
new file mode 100644
index 000000000000..12870601c09c
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/halphyrf_ce.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __HAL_PHY_RF_H__
+#define __HAL_PHY_RF_H__
+
+#include "phydm_kfree.h"
+#include "phydm_powertracking_ce.h"
+
+enum spur_cal_method {
+ PLL_RESET,
+ AFE_PHASE_SEL
+};
+
+enum pwrtrack_method {
+ BBSWING,
+ TXAGC,
+ MIX_MODE,
+ TSSI_MODE,
+ MIX_2G_TSSI_5G_MODE,
+ MIX_5G_TSSI_2G_MODE
+};
+
+typedef void (*func_set_pwr)(void *, enum pwrtrack_method, u8, u8);
+typedef void(*func_iqk)(void *, u8, u8, u8);
+typedef void (*func_lck)(void *);
+typedef void (*func_swing)(void *, u8 **, u8 **, u8 **, u8 **);
+typedef void (*func_swing8814only)(void *, u8 **, u8 **, u8 **, u8 **);
+typedef void(*func_swing_xtal)(void *, s8 **, s8 **);
+typedef void(*func_set_xtal)(void *);
+
+struct _TXPWRTRACK_CFG {
+ u8 swing_table_size_cck;
+ u8 swing_table_size_ofdm;
+ u8 threshold_iqk;
+ u8 threshold_dpk;
+ u8 average_thermal_num;
+ u8 rf_path_count;
+ u32 thermal_reg_addr;
+ func_set_pwr odm_tx_pwr_track_set_pwr;
+ func_iqk do_iqk;
+ func_lck phy_lc_calibrate;
+ func_swing get_delta_swing_table;
+ func_swing8814only get_delta_swing_table8814only;
+ func_swing_xtal get_delta_swing_xtal_table;
+ func_set_xtal odm_txxtaltrack_set_xtal;
+};
+
+void
+configure_txpower_track(
+ void *p_dm_void,
+ struct _TXPWRTRACK_CFG *p_config
+);
+
+
+void
+odm_clear_txpowertracking_state(
+ void *p_dm_void
+);
+
+void
+odm_txpowertracking_callback_thermal_meter(
+ struct _ADAPTER *adapter
+);
+
+#define ODM_TARGET_CHNL_NUM_2G_5G 59
+
+void
+odm_reset_iqk_result(
+ void *p_dm_void
+);
+u8
+odm_get_right_chnl_place_for_iqk(
+ u8 chnl
+);
+
+void phydm_rf_init(void *p_dm_void);
+void phydm_rf_watchdog(void *p_dm_void);
+
+#endif /* #ifndef __HAL_PHY_RF_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/haltxbfinterface.h b/drivers/staging/rtl8188eu/hal/haltxbfinterface.h
new file mode 100644
index 000000000000..4bf9502d4355
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/haltxbfinterface.h
@@ -0,0 +1,14 @@
+#ifndef __HAL_TXBF_INTERFACE_H__
+#define __HAL_TXBF_INTERFACE_H__
+
+#define beamforming_get_ndpa_frame(p_dm_odm, _pdu_os)
+#define beamforming_get_report_frame(adapter, precv_frame) RT_STATUS_FAILURE
+#define send_fw_ht_ndpa_packet(p_dm_void, RA, BW)
+#define send_sw_ht_ndpa_packet(p_dm_void, RA, BW)
+#define send_fw_vht_ndpa_packet(p_dm_void, RA, AID, BW)
+#define send_sw_vht_ndpa_packet(p_dm_void, RA, AID, BW)
+#define send_sw_vht_gid_mgnt_frame(p_dm_void, RA, idx)
+#define send_sw_vht_bf_report_poll(p_dm_void, RA, is_final_poll)
+#define send_sw_vht_mu_ndpa_packet(p_dm_void, BW)
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/haltxbfjaguar.h b/drivers/staging/rtl8188eu/hal/haltxbfjaguar.h
new file mode 100644
index 000000000000..7c7f73ed391a
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/haltxbfjaguar.h
@@ -0,0 +1,74 @@
+#ifndef __HAL_TXBF_JAGUAR_H__
+#define __HAL_TXBF_JAGUAR_H__
+#if ((RTL8812A_SUPPORT == 1) || (RTL8821A_SUPPORT == 1))
+#if (BEAMFORMING_SUPPORT == 1)
+
+void
+hal_txbf_8812a_set_ndpa_rate(
+ void *p_dm_void,
+ u8 BW,
+ u8 rate
+);
+
+
+void
+hal_txbf_jaguar_enter(
+ void *p_dm_void,
+ u8 idx
+);
+
+
+void
+hal_txbf_jaguar_leave(
+ void *p_dm_void,
+ u8 idx
+);
+
+
+void
+hal_txbf_jaguar_status(
+ void *p_dm_void,
+ u8 idx
+);
+
+
+void
+hal_txbf_jaguar_fw_txbf(
+ void *p_dm_void,
+ u8 idx
+);
+
+
+void
+hal_txbf_jaguar_patch(
+ void *p_dm_void,
+ u8 operation
+);
+
+
+void
+hal_txbf_jaguar_clk_8812a(
+ void *p_dm_void
+);
+#else
+
+#define hal_txbf_8812a_set_ndpa_rate(p_dm_void, BW, rate)
+#define hal_txbf_jaguar_enter(p_dm_void, idx)
+#define hal_txbf_jaguar_leave(p_dm_void, idx)
+#define hal_txbf_jaguar_status(p_dm_void, idx)
+#define hal_txbf_jaguar_fw_txbf(p_dm_void, idx)
+#define hal_txbf_jaguar_patch(p_dm_void, operation)
+#define hal_txbf_jaguar_clk_8812a(p_dm_void)
+#endif
+#else
+
+#define hal_txbf_8812a_set_ndpa_rate(p_dm_void, BW, rate)
+#define hal_txbf_jaguar_enter(p_dm_void, idx)
+#define hal_txbf_jaguar_leave(p_dm_void, idx)
+#define hal_txbf_jaguar_status(p_dm_void, idx)
+#define hal_txbf_jaguar_fw_txbf(p_dm_void, idx)
+#define hal_txbf_jaguar_patch(p_dm_void, operation)
+#define hal_txbf_jaguar_clk_8812a(p_dm_void)
+#endif
+
+#endif /* #ifndef __HAL_TXBF_JAGUAR_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/mp_precomp.h b/drivers/staging/rtl8188eu/hal/mp_precomp.h
new file mode 100644
index 000000000000..0b2a7707a499
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/mp_precomp.h
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
diff --git a/drivers/staging/rtl8188eu/hal/phydm.c b/drivers/staging/rtl8188eu/hal/phydm.c
new file mode 100644
index 000000000000..beab57636586
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm.c
@@ -0,0 +1,2341 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+static const u16 db_invert_table[12][8] = {
+ { 1, 1, 1, 2, 2, 2, 2, 3},
+ { 3, 3, 4, 4, 4, 5, 6, 6},
+ { 7, 8, 9, 10, 11, 13, 14, 16},
+ { 18, 20, 22, 25, 28, 32, 35, 40},
+ { 45, 50, 56, 63, 71, 79, 89, 100},
+ { 112, 126, 141, 158, 178, 200, 224, 251},
+ { 282, 316, 355, 398, 447, 501, 562, 631},
+ { 708, 794, 891, 1000, 1122, 1259, 1413, 1585},
+ { 1778, 1995, 2239, 2512, 2818, 3162, 3548, 3981},
+ { 4467, 5012, 5623, 6310, 7079, 7943, 8913, 10000},
+ { 11220, 12589, 14125, 15849, 17783, 19953, 22387, 25119},
+ { 28184, 31623, 35481, 39811, 44668, 50119, 56234, 65535}
+};
+
+
+/* ************************************************************
+ * Local Function predefine.
+ * ************************************************************ */
+
+/* START------------COMMON INFO RELATED--------------- */
+
+void
+odm_global_adapter_check(
+ void
+);
+
+/* move to odm_PowerTacking.h by YuChen */
+
+
+
+void
+odm_update_power_training_state(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+/* ************************************************************
+ * 3 Export Interface
+ * ************************************************************ */
+
+/*Y = 10*log(X)*/
+s32
+odm_pwdb_conversion(
+ s32 X,
+ u32 total_bit,
+ u32 decimal_bit
+)
+{
+ s32 Y, integer = 0, decimal = 0;
+ u32 i;
+
+ if (X == 0)
+ X = 1; /* log2(x), x can't be 0 */
+
+ for (i = (total_bit - 1); i > 0; i--) {
+ if (X & BIT(i)) {
+ integer = i;
+ if (i > 0)
+ decimal = (X & BIT(i - 1)) ? 2 : 0; /* decimal is 0.5dB*3=1.5dB~=2dB */
+ break;
+ }
+ }
+
+ Y = 3 * (integer - decimal_bit) + decimal; /* 10*log(x)=3*log2(x), */
+
+ return Y;
+}
+
+s32
+odm_sign_conversion(
+ s32 value,
+ u32 total_bit
+)
+{
+ if (value & BIT(total_bit - 1))
+ value -= BIT(total_bit);
+ return value;
+}
+
+void
+phydm_seq_sorting(
+ void *p_dm_void,
+ u32 *p_value,
+ u32 *rank_idx,
+ u32 *p_idx_out,
+ u8 seq_length
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 i = 0, j = 0;
+ u32 tmp_a, tmp_b;
+ u32 tmp_idx_a, tmp_idx_b;
+
+ for (i = 0; i < seq_length; i++) {
+ rank_idx[i] = i;
+ /**/
+ }
+
+ for (i = 0; i < (seq_length - 1); i++) {
+
+ for (j = 0; j < (seq_length - 1 - i); j++) {
+
+ tmp_a = p_value[j];
+ tmp_b = p_value[j + 1];
+
+ tmp_idx_a = rank_idx[j];
+ tmp_idx_b = rank_idx[j + 1];
+
+ if (tmp_a < tmp_b) {
+ p_value[j] = tmp_b;
+ p_value[j + 1] = tmp_a;
+
+ rank_idx[j] = tmp_idx_b;
+ rank_idx[j + 1] = tmp_idx_a;
+ }
+ }
+ }
+
+ for (i = 0; i < seq_length; i++) {
+ p_idx_out[rank_idx[i]] = i + 1;
+ /**/
+ }
+
+
+
+}
+
+void
+odm_init_mp_driver_status(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+
+ /* Update information every period */
+ p_dm_odm->mp_mode = (bool)adapter->registrypriv.mp_mode;
+
+}
+
+static void
+odm_update_mp_driver_status(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+
+ /* Update information erery period */
+ p_dm_odm->mp_mode = (bool)adapter->registrypriv.mp_mode;
+}
+
+static void
+phydm_init_trx_antenna_setting(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ if (p_dm_odm->support_ic_type & (ODM_RTL8814A)) {
+ u8 rx_ant = 0, tx_ant = 0;
+
+ rx_ant = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG(BB_RX_PATH, p_dm_odm), ODM_BIT(BB_RX_PATH, p_dm_odm));
+ tx_ant = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG(BB_TX_PATH, p_dm_odm), ODM_BIT(BB_TX_PATH, p_dm_odm));
+ p_dm_odm->tx_ant_status = (tx_ant & 0xf);
+ p_dm_odm->rx_ant_status = (rx_ant & 0xf);
+ } else if (p_dm_odm->support_ic_type & (ODM_RTL8723D | ODM_RTL8821C)) {
+ p_dm_odm->tx_ant_status = 0x1;
+ p_dm_odm->rx_ant_status = 0x1;
+
+ }
+}
+
+static void
+phydm_traffic_load_decision(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _sw_antenna_switch_ *p_dm_swat_table = &p_dm_odm->dm_swat_table;
+
+ /*---TP & Trafic-load calculation---*/
+
+ if (p_dm_odm->last_tx_ok_cnt > (*(p_dm_odm->p_num_tx_bytes_unicast)))
+ p_dm_odm->last_tx_ok_cnt = (*(p_dm_odm->p_num_tx_bytes_unicast));
+
+ if (p_dm_odm->last_rx_ok_cnt > (*(p_dm_odm->p_num_rx_bytes_unicast)))
+ p_dm_odm->last_rx_ok_cnt = (*(p_dm_odm->p_num_rx_bytes_unicast));
+
+ p_dm_odm->cur_tx_ok_cnt = *(p_dm_odm->p_num_tx_bytes_unicast) - p_dm_odm->last_tx_ok_cnt;
+ p_dm_odm->cur_rx_ok_cnt = *(p_dm_odm->p_num_rx_bytes_unicast) - p_dm_odm->last_rx_ok_cnt;
+ p_dm_odm->last_tx_ok_cnt = *(p_dm_odm->p_num_tx_bytes_unicast);
+ p_dm_odm->last_rx_ok_cnt = *(p_dm_odm->p_num_rx_bytes_unicast);
+
+ p_dm_odm->tx_tp = ((p_dm_odm->tx_tp) >> 1) + (u32)(((p_dm_odm->cur_tx_ok_cnt) >> 18) >> 1); /* <<3(8bit), >>20(10^6,M), >>1(2sec)*/
+ p_dm_odm->rx_tp = ((p_dm_odm->rx_tp) >> 1) + (u32)(((p_dm_odm->cur_rx_ok_cnt) >> 18) >> 1); /* <<3(8bit), >>20(10^6,M), >>1(2sec)*/
+ p_dm_odm->total_tp = p_dm_odm->tx_tp + p_dm_odm->rx_tp;
+
+ if (p_dm_odm->total_tp == 0)
+ p_dm_odm->consecutive_idlel_time += PHYDM_WATCH_DOG_PERIOD;
+ else
+ p_dm_odm->consecutive_idlel_time = 0;
+
+ p_dm_odm->pre_traffic_load = p_dm_odm->traffic_load;
+
+ if (p_dm_odm->cur_tx_ok_cnt > 1875000 || p_dm_odm->cur_rx_ok_cnt > 1875000) { /* ( 1.875M * 8bit ) / 2sec= 7.5M bits /sec )*/
+
+ p_dm_odm->traffic_load = TRAFFIC_HIGH;
+ /**/
+ } else if (p_dm_odm->cur_tx_ok_cnt > 500000 || p_dm_odm->cur_rx_ok_cnt > 500000) { /*( 0.5M * 8bit ) / 2sec = 2M bits /sec )*/
+
+ p_dm_odm->traffic_load = TRAFFIC_MID;
+ /**/
+ } else if (p_dm_odm->cur_tx_ok_cnt > 100000 || p_dm_odm->cur_rx_ok_cnt > 100000) { /*( 0.1M * 8bit ) / 2sec = 0.4M bits /sec )*/
+
+ p_dm_odm->traffic_load = TRAFFIC_LOW;
+ /**/
+ } else {
+
+ p_dm_odm->traffic_load = TRAFFIC_ULTRA_LOW;
+ /**/
+ }
+}
+
+static void
+phydm_config_ofdm_tx_path(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 path
+)
+{
+ u8 ofdm_tx_path = 0x33;
+}
+
+void
+phydm_config_ofdm_rx_path(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 path
+)
+{
+ u8 ofdm_rx_path = 0;
+
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8192E)) {
+ }
+}
+
+static void
+phydm_config_cck_rx_antenna_init(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+}
+
+static void
+phydm_config_cck_rx_path(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 path,
+ u8 path_div_en
+)
+{
+ u8 path_div_select = 0;
+ u8 cck_1_path = 0, cck_2_path = 0;
+}
+
+void
+phydm_config_trx_path(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 pre_support_ability;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ /* CCK */
+ if (dm_value[0] == 0) {
+
+ if (dm_value[1] == 1) { /*TX*/
+ if (dm_value[2] == 1)
+ odm_set_bb_reg(p_dm_odm, 0xa04, 0xf0000000, 0x8);
+ else if (dm_value[2] == 2)
+ odm_set_bb_reg(p_dm_odm, 0xa04, 0xf0000000, 0x4);
+ else if (dm_value[2] == 3)
+ odm_set_bb_reg(p_dm_odm, 0xa04, 0xf0000000, 0xc);
+ } else if (dm_value[1] == 2) { /*RX*/
+
+ phydm_config_cck_rx_antenna_init(p_dm_odm);
+
+ if (dm_value[2] == 1)
+ phydm_config_cck_rx_path(p_dm_odm, PHYDM_A, CCA_PATHDIV_DISABLE);
+ else if (dm_value[2] == 2)
+ phydm_config_cck_rx_path(p_dm_odm, PHYDM_B, CCA_PATHDIV_DISABLE);
+ else if (dm_value[2] == 3) {
+ if (dm_value[3] == 1) /*enable path diversity*/
+ phydm_config_cck_rx_path(p_dm_odm, PHYDM_AB, CCA_PATHDIV_ENABLE);
+ else
+ phydm_config_cck_rx_path(p_dm_odm, PHYDM_B, CCA_PATHDIV_DISABLE);
+ }
+ }
+ }
+ /* OFDM */
+ else if (dm_value[0] == 1) {
+
+ if (dm_value[1] == 1) { /*TX*/
+ phydm_config_ofdm_tx_path(p_dm_odm, dm_value[2]);
+ /**/
+ } else if (dm_value[1] == 2) { /*RX*/
+ phydm_config_ofdm_rx_path(p_dm_odm, dm_value[2]);
+ /**/
+ }
+ }
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "PHYDM Set path [%s] [%s] = [%s%s%s%s]\n",
+ (dm_value[0] == 1) ? "OFDM" : "CCK",
+ (dm_value[1] == 1) ? "TX" : "RX",
+ (dm_value[2] & 0x1) ? "A" : "",
+ (dm_value[2] & 0x2) ? "B" : "",
+ (dm_value[2] & 0x4) ? "C" : "",
+ (dm_value[2] & 0x8) ? "D" : ""
+ ));
+
+}
+
+static void
+phydm_init_cck_setting(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 value_824, value_82c;
+
+ p_dm_odm->is_cck_high_power = (bool) odm_get_bb_reg(p_dm_odm, ODM_REG(CCK_RPT_FORMAT, p_dm_odm), ODM_BIT(CCK_RPT_FORMAT, p_dm_odm));
+
+ p_dm_odm->cck_new_agc = false;
+}
+
+static void
+phydm_init_soft_ml_setting(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+}
+
+static void
+phydm_init_hw_info_by_rfe(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+}
+
+static void
+odm_common_info_self_init(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ phydm_init_cck_setting(p_dm_odm);
+ p_dm_odm->rf_path_rx_enable = (u8) odm_get_bb_reg(p_dm_odm, ODM_REG(BB_RX_PATH, p_dm_odm), ODM_BIT(BB_RX_PATH, p_dm_odm));
+ odm_init_mp_driver_status(p_dm_odm);
+ phydm_init_trx_antenna_setting(p_dm_odm);
+ phydm_init_soft_ml_setting(p_dm_odm);
+
+ p_dm_odm->phydm_period = PHYDM_WATCH_DOG_PERIOD;
+ p_dm_odm->phydm_sys_up_time = 0;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_1SS)
+ p_dm_odm->num_rf_path = 1;
+ else if (p_dm_odm->support_ic_type & ODM_IC_2SS)
+ p_dm_odm->num_rf_path = 2;
+ else if (p_dm_odm->support_ic_type & ODM_IC_3SS)
+ p_dm_odm->num_rf_path = 3;
+ else if (p_dm_odm->support_ic_type & ODM_IC_4SS)
+ p_dm_odm->num_rf_path = 4;
+
+ p_dm_odm->tx_rate = 0xFF;
+
+ p_dm_odm->number_linked_client = 0;
+ p_dm_odm->pre_number_linked_client = 0;
+ p_dm_odm->number_active_client = 0;
+ p_dm_odm->pre_number_active_client = 0;
+
+ p_dm_odm->last_tx_ok_cnt = 0;
+ p_dm_odm->last_rx_ok_cnt = 0;
+ p_dm_odm->tx_tp = 0;
+ p_dm_odm->rx_tp = 0;
+ p_dm_odm->total_tp = 0;
+ p_dm_odm->traffic_load = TRAFFIC_LOW;
+
+ p_dm_odm->nbi_set_result = 0;
+ p_dm_odm->is_init_hw_info_by_rfe = false;
+
+}
+
+static void
+odm_common_info_self_update(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u8 entry_cnt = 0, num_active_client = 0;
+ u32 i, one_entry_macid = 0, ma_rx_tp = 0;
+ struct sta_info *p_entry;
+
+ if (*(p_dm_odm->p_band_width) == ODM_BW40M) {
+ if (*(p_dm_odm->p_sec_ch_offset) == 1)
+ p_dm_odm->control_channel = *(p_dm_odm->p_channel) - 2;
+ else if (*(p_dm_odm->p_sec_ch_offset) == 2)
+ p_dm_odm->control_channel = *(p_dm_odm->p_channel) + 2;
+ } else
+ p_dm_odm->control_channel = *(p_dm_odm->p_channel);
+
+ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
+ p_entry = p_dm_odm->p_odm_sta_info[i];
+ if (IS_STA_VALID(p_entry)) {
+ entry_cnt++;
+ if (entry_cnt == 1)
+ one_entry_macid = i;
+ }
+ }
+
+ if (entry_cnt == 1) {
+ p_dm_odm->is_one_entry_only = true;
+ p_dm_odm->one_entry_macid = one_entry_macid;
+ } else
+ p_dm_odm->is_one_entry_only = false;
+
+ p_dm_odm->pre_number_linked_client = p_dm_odm->number_linked_client;
+ p_dm_odm->pre_number_active_client = p_dm_odm->number_active_client;
+
+ p_dm_odm->number_linked_client = entry_cnt;
+ p_dm_odm->number_active_client = num_active_client;
+
+ /* Update MP driver status*/
+ odm_update_mp_driver_status(p_dm_odm);
+
+ /*Traffic load information update*/
+ phydm_traffic_load_decision(p_dm_odm);
+
+ p_dm_odm->phydm_sys_up_time += p_dm_odm->phydm_period;
+}
+
+static void
+odm_common_info_self_reset(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ p_dm_odm->phy_dbg_info.num_qry_beacon_pkt = 0;
+}
+
+void *
+phydm_get_structure(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 structure_type
+)
+
+{
+ void *p_struct = NULL;
+
+ switch (structure_type) {
+ case PHYDMfalseALMCNT:
+ p_struct = &(p_dm_odm->false_alm_cnt);
+ break;
+ case PHYDM_CFOTRACK:
+ p_struct = &(p_dm_odm->dm_cfo_track);
+ break;
+ case PHYDM_ADAPTIVITY:
+ p_struct = &(p_dm_odm->adaptivity);
+ break;
+ default:
+ break;
+ }
+
+ return p_struct;
+}
+
+static void
+odm_hw_setting(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+}
+#if SUPPORTABLITY_PHYDMLIZE
+static void
+phydm_supportability_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 support_ability = 0;
+
+ if (p_dm_odm->support_ic_type != ODM_RTL8821C)
+ return;
+
+ switch (p_dm_odm->support_ic_type) {
+
+ /*---------------N Series--------------------*/
+ case ODM_RTL8188E:
+ 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_RF_TX_PWR_TRACK |
+ ODM_RF_RX_GAIN_TRACK |
+ ODM_RF_CALIBRATION |
+ ODM_BB_CFO_TRACKING |
+ ODM_BB_NHM_CNT |
+ ODM_BB_PRIMARY_CCA;
+ break;
+
+ case ODM_RTL8192E:
+ support_ability |=
+ ODM_BB_DIG |
+ ODM_RF_TX_PWR_TRACK |
+ ODM_BB_RA_MASK |
+ ODM_BB_FA_CNT |
+ ODM_BB_RSSI_MONITOR |
+ ODM_BB_CFO_TRACKING |
+ /* ODM_BB_PWR_TRAIN |*/
+ ODM_BB_NHM_CNT |
+ ODM_BB_PRIMARY_CCA;
+ break;
+
+ case ODM_RTL8723B:
+ support_ability |=
+ ODM_BB_DIG |
+ ODM_BB_RA_MASK |
+ ODM_BB_FA_CNT |
+ ODM_BB_RSSI_MONITOR |
+ ODM_BB_CCK_PD |
+ ODM_RF_TX_PWR_TRACK |
+ ODM_RF_RX_GAIN_TRACK |
+ ODM_RF_CALIBRATION |
+ ODM_BB_CFO_TRACKING |
+ /* ODM_BB_PWR_TRAIN |*/
+ ODM_BB_NHM_CNT;
+ break;
+
+ case ODM_RTL8703B:
+ support_ability |=
+ ODM_BB_DIG |
+ ODM_BB_RA_MASK |
+ ODM_BB_FA_CNT |
+ ODM_BB_RSSI_MONITOR |
+ ODM_BB_CCK_PD |
+ ODM_BB_CFO_TRACKING |
+ /* ODM_BB_PWR_TRAIN | */
+ ODM_BB_NHM_CNT |
+ ODM_RF_TX_PWR_TRACK |
+ /* ODM_RF_RX_GAIN_TRACK | */
+ ODM_RF_CALIBRATION;
+ break;
+
+ case ODM_RTL8723D:
+ support_ability |=
+ ODM_BB_DIG |
+ ODM_BB_RA_MASK |
+ ODM_BB_FA_CNT |
+ ODM_BB_RSSI_MONITOR |
+ ODM_BB_CCK_PD |
+ ODM_BB_CFO_TRACKING |
+ /* ODM_BB_PWR_TRAIN | */
+ ODM_BB_NHM_CNT |
+ ODM_RF_TX_PWR_TRACK;
+ /* ODM_RF_RX_GAIN_TRACK | */
+ /* ODM_RF_CALIBRATION | */
+ break;
+
+ case ODM_RTL8188F:
+ support_ability |=
+ ODM_BB_DIG |
+ ODM_BB_RA_MASK |
+ ODM_BB_FA_CNT |
+ ODM_BB_RSSI_MONITOR |
+ ODM_BB_CCK_PD |
+ ODM_BB_CFO_TRACKING |
+ ODM_BB_NHM_CNT |
+ ODM_RF_TX_PWR_TRACK |
+ ODM_RF_CALIBRATION;
+ break;
+ /*---------------AC Series-------------------*/
+
+ case ODM_RTL8812:
+ case ODM_RTL8821:
+ support_ability |=
+ ODM_BB_DIG |
+ ODM_BB_FA_CNT |
+ ODM_BB_RSSI_MONITOR |
+ ODM_BB_RA_MASK |
+ ODM_RF_TX_PWR_TRACK |
+ ODM_BB_CFO_TRACKING |
+ /* ODM_BB_PWR_TRAIN |*/
+ ODM_BB_DYNAMIC_TXPWR |
+ ODM_BB_NHM_CNT;
+ break;
+
+ case ODM_RTL8814A:
+ support_ability |=
+ ODM_BB_DIG |
+ ODM_BB_FA_CNT |
+ ODM_BB_RSSI_MONITOR |
+ ODM_BB_RA_MASK |
+ ODM_RF_TX_PWR_TRACK |
+ ODM_BB_CCK_PD |
+ ODM_BB_CFO_TRACKING |
+ ODM_BB_DYNAMIC_TXPWR |
+ ODM_BB_NHM_CNT;
+ break;
+
+ case ODM_RTL8822B:
+ support_ability |=
+ ODM_BB_DIG |
+ ODM_BB_FA_CNT |
+ ODM_BB_CCK_PD |
+ ODM_BB_CFO_TRACKING |
+ ODM_BB_RATE_ADAPTIVE |
+ ODM_BB_RSSI_MONITOR |
+ ODM_BB_RA_MASK |
+ ODM_RF_TX_PWR_TRACK;
+ break;
+
+ case ODM_RTL8821C:
+ support_ability |=
+ ODM_BB_DIG |
+ ODM_BB_RA_MASK |
+ ODM_BB_CCK_PD |
+ ODM_BB_FA_CNT |
+ ODM_BB_RSSI_MONITOR |
+ ODM_BB_RATE_ADAPTIVE |
+ ODM_RF_TX_PWR_TRACK |
+ ODM_MAC_EDCA_TURBO |
+ ODM_BB_CFO_TRACKING;
+ break;
+ default:
+ dbg_print("[Warning] Supportability Init error !!!\n");
+ break;
+
+ }
+
+ if (*(p_dm_odm->p_enable_antdiv))
+ support_ability |= ODM_BB_ANT_DIV;
+
+ if (*(p_dm_odm->p_enable_adaptivity)) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ODM adaptivity is set to Enabled!!!\n"));
+
+ support_ability |= ODM_BB_ADAPTIVITY;
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ODM adaptivity is set to disnabled!!!\n"));
+ /**/
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("PHYDM support_ability = ((0x%x))\n", support_ability));
+ odm_cmn_info_init(p_dm_odm, ODM_CMNINFO_ABILITY, support_ability);
+}
+#endif
+
+/*
+ * 2011/09/21 MH Add to describe different team necessary resource allocate??
+ * */
+void
+odm_dm_init(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+#if SUPPORTABLITY_PHYDMLIZE
+ phydm_supportability_init(p_dm_odm);
+#endif
+ odm_common_info_self_init(p_dm_odm);
+ odm_dig_init(p_dm_odm);
+ phydm_nhm_counter_statistics_init(p_dm_odm);
+ phydm_adaptivity_init(p_dm_odm);
+ phydm_ra_info_init(p_dm_odm);
+ odm_rate_adaptive_mask_init(p_dm_odm);
+ odm_cfo_tracking_init(p_dm_odm);
+#if PHYDM_SUPPORT_EDCA
+ odm_edca_turbo_init(p_dm_odm);
+#endif
+ odm_rssi_monitor_init(p_dm_odm);
+ phydm_rf_init(p_dm_odm);
+ odm_txpowertracking_init(p_dm_odm);
+
+ odm_antenna_diversity_init(p_dm_odm);
+#if (CONFIG_DYNAMIC_RX_PATH == 1)
+ phydm_dynamic_rx_path_init(p_dm_odm);
+#endif
+ odm_auto_channel_select_init(p_dm_odm);
+ odm_path_diversity_init(p_dm_odm);
+ odm_dynamic_tx_power_init(p_dm_odm);
+ phydm_init_ra_info(p_dm_odm);
+#if (PHYDM_LA_MODE_SUPPORT == 1)
+ adc_smp_init(p_dm_odm);
+#endif
+
+
+#ifdef BEAMFORMING_VERSION_1
+ if (p_hal_data->beamforming_version == BEAMFORMING_VERSION_1)
+#endif
+ {
+ phydm_beamforming_init(p_dm_odm);
+ }
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+#if (defined(CONFIG_BB_POWER_SAVING))
+ odm_dynamic_bb_power_saving_init(p_dm_odm);
+#endif
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E) {
+ odm_primary_cca_init(p_dm_odm);
+ odm_ra_info_init_all(p_dm_odm);
+ }
+ }
+}
+
+void
+odm_dm_reset(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+
+ odm_ant_div_reset(p_dm_odm);
+ phydm_set_edcca_threshold_api(p_dm_odm, p_dm_dig_table->cur_ig_value);
+}
+
+
+void
+phydm_support_ability_debug(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 pre_support_ability;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ pre_support_ability = p_dm_odm->support_ability ;
+ PHYDM_SNPRINTF((output + used, out_len - used, "\n%s\n", "================================"));
+ if (dm_value[0] == 100) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "[Supportability] PhyDM Selection\n"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "================================"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "00. (( %s ))DIG\n", ((p_dm_odm->support_ability & ODM_BB_DIG) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "01. (( %s ))RA_MASK\n", ((p_dm_odm->support_ability & ODM_BB_RA_MASK) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "02. (( %s ))DYNAMIC_TXPWR\n", ((p_dm_odm->support_ability & ODM_BB_DYNAMIC_TXPWR) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "03. (( %s ))FA_CNT\n", ((p_dm_odm->support_ability & ODM_BB_FA_CNT) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "04. (( %s ))RSSI_MONITOR\n", ((p_dm_odm->support_ability & ODM_BB_RSSI_MONITOR) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "05. (( %s ))CCK_PD\n", ((p_dm_odm->support_ability & ODM_BB_CCK_PD) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "06. (( %s ))ANT_DIV\n", ((p_dm_odm->support_ability & ODM_BB_ANT_DIV) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "08. (( %s ))PWR_TRAIN\n", ((p_dm_odm->support_ability & ODM_BB_PWR_TRAIN) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "09. (( %s ))RATE_ADAPTIVE\n", ((p_dm_odm->support_ability & ODM_BB_RATE_ADAPTIVE) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "10. (( %s ))PATH_DIV\n", ((p_dm_odm->support_ability & ODM_BB_PATH_DIV) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "13. (( %s ))ADAPTIVITY\n", ((p_dm_odm->support_ability & ODM_BB_ADAPTIVITY) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "14. (( %s ))struct _CFO_TRACKING_\n", ((p_dm_odm->support_ability & ODM_BB_CFO_TRACKING) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "15. (( %s ))NHM_CNT\n", ((p_dm_odm->support_ability & ODM_BB_NHM_CNT) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "16. (( %s ))PRIMARY_CCA\n", ((p_dm_odm->support_ability & ODM_BB_PRIMARY_CCA) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "17. (( %s ))TXBF\n", ((p_dm_odm->support_ability & ODM_BB_TXBF) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "18. (( %s ))DYNAMIC_ARFR\n", ((p_dm_odm->support_ability & ODM_BB_DYNAMIC_ARFR) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "20. (( %s ))EDCA_TURBO\n", ((p_dm_odm->support_ability & ODM_MAC_EDCA_TURBO) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "21. (( %s ))DYNAMIC_RX_PATH\n", ((p_dm_odm->support_ability & ODM_BB_DYNAMIC_RX_PATH) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "24. (( %s ))TX_PWR_TRACK\n", ((p_dm_odm->support_ability & ODM_RF_TX_PWR_TRACK) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "25. (( %s ))RX_GAIN_TRACK\n", ((p_dm_odm->support_ability & ODM_RF_RX_GAIN_TRACK) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "26. (( %s ))RF_CALIBRATION\n", ((p_dm_odm->support_ability & ODM_RF_CALIBRATION) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "================================"));
+ }
+ /*
+ else if(dm_value[0] == 101)
+ {
+ p_dm_odm->support_ability = 0 ;
+ dbg_print("Disable all support_ability components\n");
+ PHYDM_SNPRINTF((output+used, out_len-used,"%s\n", "Disable all support_ability components"));
+ }
+ */
+ else {
+
+ if (dm_value[1] == 1) { /* enable */
+ p_dm_odm->support_ability |= BIT(dm_value[0]) ;
+ if (BIT(dm_value[0]) & ODM_BB_PATH_DIV)
+ odm_path_diversity_init(p_dm_odm);
+ } else if (dm_value[1] == 2) /* disable */
+ p_dm_odm->support_ability &= ~(BIT(dm_value[0])) ;
+ else {
+ /* dbg_print("\n[Warning!!!] 1:enable, 2:disable \n\n"); */
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "[Warning!!!] 1:enable, 2:disable"));
+ }
+ }
+ PHYDM_SNPRINTF((output + used, out_len - used, "pre-support_ability = 0x%x\n", pre_support_ability));
+ PHYDM_SNPRINTF((output + used, out_len - used, "Curr-support_ability = 0x%x\n", p_dm_odm->support_ability));
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "================================"));
+}
+
+void
+phydm_watchdog_mp(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+#if (CONFIG_DYNAMIC_RX_PATH == 1)
+ phydm_dynamic_rx_path_caller(p_dm_odm);
+#endif
+}
+/*
+ * 2011/09/20 MH This is the entry pointer for all team to execute HW out source DM.
+ * You can not add any dummy function here, be care, you can only use DM structure
+ * to perform any new ODM_DM.
+ * */
+void
+odm_dm_watchdog(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ odm_common_info_self_update(p_dm_odm);
+ phydm_basic_dbg_message(p_dm_odm);
+ phydm_receiver_blocking(p_dm_odm);
+ odm_hw_setting(p_dm_odm);
+
+ odm_false_alarm_counter_statistics(p_dm_odm);
+ phydm_noisy_detection(p_dm_odm);
+
+ odm_rssi_monitor_check(p_dm_odm);
+
+ if (*(p_dm_odm->p_is_power_saving) == true) {
+ odm_dig_by_rssi_lps(p_dm_odm);
+ phydm_adaptivity(p_dm_odm);
+ odm_antenna_diversity(p_dm_odm); /*enable AntDiv in PS mode, request from SD4 Jeff*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("DMWatchdog in power saving mode\n"));
+ return;
+ }
+
+ phydm_check_adaptivity(p_dm_odm);
+ odm_update_power_training_state(p_dm_odm);
+ odm_DIG(p_dm_odm);
+ phydm_adaptivity(p_dm_odm);
+ odm_cck_packet_detection_thresh(p_dm_odm);
+
+ phydm_ra_info_watchdog(p_dm_odm);
+#if PHYDM_SUPPORT_EDCA
+ odm_edca_turbo_check(p_dm_odm);
+#endif
+ odm_path_diversity(p_dm_odm);
+ odm_cfo_tracking(p_dm_odm);
+ odm_dynamic_tx_power(p_dm_odm);
+ odm_antenna_diversity(p_dm_odm);
+#if (CONFIG_DYNAMIC_RX_PATH == 1)
+ phydm_dynamic_rx_path(p_dm_odm);
+#endif
+
+ phydm_beamforming_watchdog(p_dm_odm);
+
+ phydm_rf_watchdog(p_dm_odm);
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E)
+ odm_dynamic_primary_cca(p_dm_odm);
+ }
+ odm_dtc(p_dm_odm);
+
+ odm_common_info_self_reset(p_dm_odm);
+}
+
+/*
+ * Init /.. Fixed HW value. Only init time.
+ * */
+void
+odm_cmn_info_init(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_cmninfo_e cmn_info,
+ u32 value
+)
+{
+ /* */
+ /* This section is used for init value */
+ /* */
+ switch (cmn_info) {
+ /* */
+ /* Fixed ODM value. */
+ /* */
+ case ODM_CMNINFO_ABILITY:
+ p_dm_odm->support_ability = (u32)value;
+ break;
+
+ case ODM_CMNINFO_RF_TYPE:
+ p_dm_odm->rf_type = (u8)value;
+ break;
+
+ case ODM_CMNINFO_PLATFORM:
+ p_dm_odm->support_platform = (u8)value;
+ break;
+
+ case ODM_CMNINFO_INTERFACE:
+ p_dm_odm->support_interface = (u8)value;
+ break;
+
+ case ODM_CMNINFO_MP_TEST_CHIP:
+ p_dm_odm->is_mp_chip = (u8)value;
+ break;
+
+ case ODM_CMNINFO_IC_TYPE:
+ p_dm_odm->support_ic_type = value;
+ break;
+
+ case ODM_CMNINFO_CUT_VER:
+ p_dm_odm->cut_version = (u8)value;
+ break;
+
+ case ODM_CMNINFO_FAB_VER:
+ p_dm_odm->fab_version = (u8)value;
+ break;
+
+ case ODM_CMNINFO_RFE_TYPE:
+ p_dm_odm->rfe_type = (u8)value;
+ phydm_init_hw_info_by_rfe(p_dm_odm);
+ break;
+
+ case ODM_CMNINFO_RF_ANTENNA_TYPE:
+ p_dm_odm->ant_div_type = (u8)value;
+ break;
+
+ case ODM_CMNINFO_WITH_EXT_ANTENNA_SWITCH:
+ p_dm_odm->with_extenal_ant_switch = (u8)value;
+ break;
+
+ case ODM_CMNINFO_BE_FIX_TX_ANT:
+ p_dm_odm->dm_fat_table.b_fix_tx_ant = (u8)value;
+ break;
+
+ case ODM_CMNINFO_BOARD_TYPE:
+ if (!p_dm_odm->is_init_hw_info_by_rfe)
+ p_dm_odm->board_type = (u8)value;
+ break;
+
+ case ODM_CMNINFO_PACKAGE_TYPE:
+ if (!p_dm_odm->is_init_hw_info_by_rfe)
+ p_dm_odm->package_type = (u8)value;
+ break;
+
+ case ODM_CMNINFO_EXT_LNA:
+ if (!p_dm_odm->is_init_hw_info_by_rfe)
+ p_dm_odm->ext_lna = (u8)value;
+ break;
+
+ case ODM_CMNINFO_5G_EXT_LNA:
+ if (!p_dm_odm->is_init_hw_info_by_rfe)
+ p_dm_odm->ext_lna_5g = (u8)value;
+ break;
+
+ case ODM_CMNINFO_EXT_PA:
+ if (!p_dm_odm->is_init_hw_info_by_rfe)
+ p_dm_odm->ext_pa = (u8)value;
+ break;
+
+ case ODM_CMNINFO_5G_EXT_PA:
+ if (!p_dm_odm->is_init_hw_info_by_rfe)
+ p_dm_odm->ext_pa_5g = (u8)value;
+ break;
+
+ case ODM_CMNINFO_GPA:
+ if (!p_dm_odm->is_init_hw_info_by_rfe)
+ p_dm_odm->type_gpa = (u16)value;
+ break;
+
+ case ODM_CMNINFO_APA:
+ if (!p_dm_odm->is_init_hw_info_by_rfe)
+ p_dm_odm->type_apa = (u16)value;
+ break;
+
+ case ODM_CMNINFO_GLNA:
+ if (!p_dm_odm->is_init_hw_info_by_rfe)
+ p_dm_odm->type_glna = (u16)value;
+ break;
+
+ case ODM_CMNINFO_ALNA:
+ if (!p_dm_odm->is_init_hw_info_by_rfe)
+ p_dm_odm->type_alna = (u16)value;
+ break;
+
+ case ODM_CMNINFO_EXT_TRSW:
+ if (!p_dm_odm->is_init_hw_info_by_rfe)
+ p_dm_odm->ext_trsw = (u8)value;
+ break;
+ case ODM_CMNINFO_EXT_LNA_GAIN:
+ p_dm_odm->ext_lna_gain = (u8)value;
+ break;
+ case ODM_CMNINFO_PATCH_ID:
+ p_dm_odm->patch_id = (u8)value;
+ break;
+ case ODM_CMNINFO_BINHCT_TEST:
+ p_dm_odm->is_in_hct_test = (bool)value;
+ break;
+ case ODM_CMNINFO_BWIFI_TEST:
+ p_dm_odm->wifi_test = (u8)value;
+ break;
+ case ODM_CMNINFO_SMART_CONCURRENT:
+ p_dm_odm->is_dual_mac_smart_concurrent = (bool)value;
+ break;
+ case ODM_CMNINFO_DOMAIN_CODE_2G:
+ p_dm_odm->odm_regulation_2_4g = (u8)value;
+ break;
+ case ODM_CMNINFO_DOMAIN_CODE_5G:
+ p_dm_odm->odm_regulation_5g = (u8)value;
+ break;
+ case ODM_CMNINFO_CONFIG_BB_RF:
+ p_dm_odm->config_bbrf = (bool)value;
+ break;
+ case ODM_CMNINFO_IQKFWOFFLOAD:
+ p_dm_odm->iqk_fw_offload = (u8)value;
+ break;
+ case ODM_CMNINFO_IQKPAOFF:
+ p_dm_odm->rf_calibrate_info.is_iqk_pa_off = (bool)value;
+ break;
+ case ODM_CMNINFO_REGRFKFREEENABLE:
+ p_dm_odm->rf_calibrate_info.reg_rf_kfree_enable = (u8)value;
+ break;
+ case ODM_CMNINFO_RFKFREEENABLE:
+ p_dm_odm->rf_calibrate_info.rf_kfree_enable = (u8)value;
+ break;
+ case ODM_CMNINFO_NORMAL_RX_PATH_CHANGE:
+ p_dm_odm->normal_rx_path = (u8)value;
+ break;
+ case ODM_CMNINFO_EFUSE0X3D8:
+ p_dm_odm->efuse0x3d8 = (u8)value;
+ break;
+ case ODM_CMNINFO_EFUSE0X3D7:
+ p_dm_odm->efuse0x3d7 = (u8)value;
+ break;
+#ifdef CONFIG_PHYDM_DFS_MASTER
+ case ODM_CMNINFO_DFS_REGION_DOMAIN:
+ p_dm_odm->dfs_region_domain = (u8)value;
+ break;
+#endif
+ /* To remove the compiler warning, must add an empty default statement to handle the other values. */
+ default:
+ /* do nothing */
+ break;
+
+ }
+
+}
+
+
+void
+odm_cmn_info_hook(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_cmninfo_e cmn_info,
+ void *p_value
+)
+{
+ /* */
+ /* Hook call by reference pointer. */
+ /* */
+ switch (cmn_info) {
+ /* */
+ /* Dynamic call by reference pointer. */
+ /* */
+ case ODM_CMNINFO_MAC_PHY_MODE:
+ p_dm_odm->p_mac_phy_mode = (u8 *)p_value;
+ break;
+
+ case ODM_CMNINFO_TX_UNI:
+ p_dm_odm->p_num_tx_bytes_unicast = (u64 *)p_value;
+ break;
+
+ case ODM_CMNINFO_RX_UNI:
+ p_dm_odm->p_num_rx_bytes_unicast = (u64 *)p_value;
+ break;
+
+ case ODM_CMNINFO_WM_MODE:
+ p_dm_odm->p_wireless_mode = (u8 *)p_value;
+ break;
+
+ case ODM_CMNINFO_BAND:
+ p_dm_odm->p_band_type = (u8 *)p_value;
+ break;
+
+ case ODM_CMNINFO_SEC_CHNL_OFFSET:
+ p_dm_odm->p_sec_ch_offset = (u8 *)p_value;
+ break;
+
+ case ODM_CMNINFO_SEC_MODE:
+ p_dm_odm->p_security = (u8 *)p_value;
+ break;
+
+ case ODM_CMNINFO_BW:
+ p_dm_odm->p_band_width = (u8 *)p_value;
+ break;
+
+ case ODM_CMNINFO_CHNL:
+ p_dm_odm->p_channel = (u8 *)p_value;
+ break;
+
+ case ODM_CMNINFO_DMSP_GET_VALUE:
+ p_dm_odm->p_is_get_value_from_other_mac = (bool *)p_value;
+ break;
+
+ case ODM_CMNINFO_BUDDY_ADAPTOR:
+ p_dm_odm->p_buddy_adapter = (struct _ADAPTER **)p_value;
+ break;
+
+ case ODM_CMNINFO_DMSP_IS_MASTER:
+ p_dm_odm->p_is_master_of_dmsp = (bool *)p_value;
+ break;
+
+ case ODM_CMNINFO_SCAN:
+ p_dm_odm->p_is_scan_in_process = (bool *)p_value;
+ break;
+
+ case ODM_CMNINFO_POWER_SAVING:
+ p_dm_odm->p_is_power_saving = (bool *)p_value;
+ break;
+
+ case ODM_CMNINFO_ONE_PATH_CCA:
+ p_dm_odm->p_one_path_cca = (u8 *)p_value;
+ break;
+
+ case ODM_CMNINFO_DRV_STOP:
+ p_dm_odm->p_is_driver_stopped = (bool *)p_value;
+ break;
+
+ case ODM_CMNINFO_PNP_IN:
+ p_dm_odm->p_is_driver_is_going_to_pnp_set_power_sleep = (bool *)p_value;
+ break;
+
+ case ODM_CMNINFO_INIT_ON:
+ p_dm_odm->pinit_adpt_in_progress = (bool *)p_value;
+ break;
+
+ case ODM_CMNINFO_ANT_TEST:
+ p_dm_odm->p_antenna_test = (u8 *)p_value;
+ break;
+
+ case ODM_CMNINFO_NET_CLOSED:
+ p_dm_odm->p_is_net_closed = (bool *)p_value;
+ break;
+
+ case ODM_CMNINFO_FORCED_RATE:
+ p_dm_odm->p_forced_data_rate = (u16 *)p_value;
+ break;
+ case ODM_CMNINFO_ANT_DIV:
+ p_dm_odm->p_enable_antdiv = (u8 *)p_value;
+ break;
+ case ODM_CMNINFO_ADAPTIVITY:
+ p_dm_odm->p_enable_adaptivity = (u8 *)p_value;
+ break;
+ case ODM_CMNINFO_FORCED_IGI_LB:
+ p_dm_odm->pu1_forced_igi_lb = (u8 *)p_value;
+ break;
+
+ case ODM_CMNINFO_P2P_LINK:
+ p_dm_odm->dm_dig_table.is_p2p_in_process = (u8 *)p_value;
+ break;
+
+ case ODM_CMNINFO_IS1ANTENNA:
+ p_dm_odm->p_is_1_antenna = (bool *)p_value;
+ break;
+
+ case ODM_CMNINFO_RFDEFAULTPATH:
+ p_dm_odm->p_rf_default_path = (u8 *)p_value;
+ break;
+
+ case ODM_CMNINFO_FCS_MODE:
+ p_dm_odm->p_is_fcs_mode_enable = (bool *)p_value;
+ break;
+ /*add by YuChen for beamforming PhyDM*/
+ case ODM_CMNINFO_HUBUSBMODE:
+ p_dm_odm->hub_usb_mode = (u8 *)p_value;
+ break;
+ case ODM_CMNINFO_FWDWRSVDPAGEINPROGRESS:
+ p_dm_odm->p_is_fw_dw_rsvd_page_in_progress = (bool *)p_value;
+ break;
+ case ODM_CMNINFO_TX_TP:
+ p_dm_odm->p_current_tx_tp = (u32 *)p_value;
+ break;
+ case ODM_CMNINFO_RX_TP:
+ p_dm_odm->p_current_rx_tp = (u32 *)p_value;
+ break;
+ case ODM_CMNINFO_SOUNDING_SEQ:
+ p_dm_odm->p_sounding_seq = (u8 *)p_value;
+ break;
+#ifdef CONFIG_PHYDM_DFS_MASTER
+ case ODM_CMNINFO_DFS_MASTER_ENABLE:
+ p_dm_odm->dfs_master_enabled = (u8 *)p_value;
+ break;
+#endif
+ case ODM_CMNINFO_FORCE_TX_ANT_BY_TXDESC:
+ p_dm_odm->dm_fat_table.p_force_tx_ant_by_desc = (u8 *)p_value;
+ break;
+ case ODM_CMNINFO_SET_S0S1_DEFAULT_ANTENNA:
+ p_dm_odm->dm_fat_table.p_default_s0_s1 = (u8 *)p_value;
+ break;
+
+ default:
+ /*do nothing*/
+ break;
+
+ }
+
+}
+
+
+void
+odm_cmn_info_ptr_array_hook(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_cmninfo_e cmn_info,
+ u16 index,
+ void *p_value
+)
+{
+ /*Hook call by reference pointer.*/
+ switch (cmn_info) {
+ /*Dynamic call by reference pointer. */
+ case ODM_CMNINFO_STA_STATUS:
+ p_dm_odm->p_odm_sta_info[index] = (struct sta_info *)p_value;
+
+ if (IS_STA_VALID(p_dm_odm->p_odm_sta_info[index]))
+ p_dm_odm->platform2phydm_macid_table[((struct sta_info *)p_value)->mac_id] = index;
+
+ break;
+ /* To remove the compiler warning, must add an empty default statement to handle the other values. */
+ default:
+ /* do nothing */
+ break;
+ }
+
+}
+
+
+/*
+ * Update band/CHannel/.. The values are dynamic but non-per-packet.
+ * */
+void
+odm_cmn_info_update(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 cmn_info,
+ u64 value
+)
+{
+ /* */
+ /* This init variable may be changed in run time. */
+ /* */
+ switch (cmn_info) {
+ case ODM_CMNINFO_LINK_IN_PROGRESS:
+ p_dm_odm->is_link_in_process = (bool)value;
+ break;
+
+ case ODM_CMNINFO_ABILITY:
+ p_dm_odm->support_ability = (u32)value;
+ break;
+
+ case ODM_CMNINFO_RF_TYPE:
+ p_dm_odm->rf_type = (u8)value;
+ break;
+
+ case ODM_CMNINFO_WIFI_DIRECT:
+ p_dm_odm->is_wifi_direct = (bool)value;
+ break;
+
+ case ODM_CMNINFO_WIFI_DISPLAY:
+ p_dm_odm->is_wifi_display = (bool)value;
+ break;
+
+ case ODM_CMNINFO_LINK:
+ p_dm_odm->is_linked = (bool)value;
+ break;
+
+ case ODM_CMNINFO_STATION_STATE:
+ p_dm_odm->bsta_state = (bool)value;
+ break;
+
+ case ODM_CMNINFO_RSSI_MIN:
+ p_dm_odm->rssi_min = (u8)value;
+ break;
+
+ case ODM_CMNINFO_DBG_COMP:
+ p_dm_odm->debug_components = (u32)value;
+ break;
+
+ case ODM_CMNINFO_DBG_LEVEL:
+ p_dm_odm->debug_level = (u32)value;
+ break;
+ case ODM_CMNINFO_RA_THRESHOLD_HIGH:
+ p_dm_odm->rate_adaptive.high_rssi_thresh = (u8)value;
+ break;
+
+ case ODM_CMNINFO_RA_THRESHOLD_LOW:
+ p_dm_odm->rate_adaptive.low_rssi_thresh = (u8)value;
+ break;
+#if defined(BT_SUPPORT) && (BT_SUPPORT == 1)
+ /* The following is for BT HS mode and BT coexist mechanism. */
+ case ODM_CMNINFO_BT_ENABLED:
+ p_dm_odm->is_bt_enabled = (bool)value;
+ break;
+
+ case ODM_CMNINFO_BT_HS_CONNECT_PROCESS:
+ p_dm_odm->is_bt_connect_process = (bool)value;
+ break;
+
+ case ODM_CMNINFO_BT_HS_RSSI:
+ p_dm_odm->bt_hs_rssi = (u8)value;
+ break;
+
+ case ODM_CMNINFO_BT_OPERATION:
+ p_dm_odm->is_bt_hs_operation = (bool)value;
+ break;
+
+ case ODM_CMNINFO_BT_LIMITED_DIG:
+ p_dm_odm->is_bt_limited_dig = (bool)value;
+ break;
+
+ case ODM_CMNINFO_BT_DIG:
+ p_dm_odm->bt_hs_dig_val = (u8)value;
+ break;
+
+ case ODM_CMNINFO_BT_BUSY:
+ p_dm_odm->is_bt_busy = (bool)value;
+ break;
+
+ case ODM_CMNINFO_BT_DISABLE_EDCA:
+ p_dm_odm->is_bt_disable_edca_turbo = (bool)value;
+ break;
+#endif
+ case ODM_CMNINFO_AP_TOTAL_NUM:
+ p_dm_odm->ap_total_num = (u8)value;
+ break;
+
+ case ODM_CMNINFO_POWER_TRAINING:
+ p_dm_odm->is_disable_power_training = (bool)value;
+ break;
+
+#ifdef CONFIG_PHYDM_DFS_MASTER
+ case ODM_CMNINFO_DFS_REGION_DOMAIN:
+ p_dm_odm->dfs_region_domain = (u8)value;
+ break;
+#endif
+ default:
+ /* do nothing */
+ break;
+ }
+}
+
+u32
+phydm_cmn_info_query(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum phydm_info_query_e info_type
+)
+{
+ struct false_ALARM_STATISTICS *false_alm_cnt = (struct false_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDMfalseALMCNT);
+
+ switch (info_type) {
+ case PHYDM_INFO_FA_OFDM:
+ return false_alm_cnt->cnt_ofdm_fail;
+
+ case PHYDM_INFO_FA_CCK:
+ return false_alm_cnt->cnt_cck_fail;
+
+ case PHYDM_INFO_FA_TOTAL:
+ return false_alm_cnt->cnt_all;
+
+ case PHYDM_INFO_CCA_OFDM:
+ return false_alm_cnt->cnt_ofdm_cca;
+
+ case PHYDM_INFO_CCA_CCK:
+ return false_alm_cnt->cnt_cck_cca;
+
+ case PHYDM_INFO_CCA_ALL:
+ return false_alm_cnt->cnt_cca_all;
+
+ case PHYDM_INFO_CRC32_OK_VHT:
+ return false_alm_cnt->cnt_vht_crc32_ok;
+
+ case PHYDM_INFO_CRC32_OK_HT:
+ return false_alm_cnt->cnt_ht_crc32_ok;
+
+ case PHYDM_INFO_CRC32_OK_LEGACY:
+ return false_alm_cnt->cnt_ofdm_crc32_ok;
+
+ case PHYDM_INFO_CRC32_OK_CCK:
+ return false_alm_cnt->cnt_cck_crc32_ok;
+
+ case PHYDM_INFO_CRC32_ERROR_VHT:
+ return false_alm_cnt->cnt_vht_crc32_error;
+
+ case PHYDM_INFO_CRC32_ERROR_HT:
+ return false_alm_cnt->cnt_ht_crc32_error;
+
+ case PHYDM_INFO_CRC32_ERROR_LEGACY:
+ return false_alm_cnt->cnt_ofdm_crc32_error;
+
+ case PHYDM_INFO_CRC32_ERROR_CCK:
+ return false_alm_cnt->cnt_cck_crc32_error;
+
+ case PHYDM_INFO_EDCCA_FLAG:
+ return false_alm_cnt->edcca_flag;
+
+ case PHYDM_INFO_OFDM_ENABLE:
+ return false_alm_cnt->ofdm_block_enable;
+
+ case PHYDM_INFO_CCK_ENABLE:
+ return false_alm_cnt->cck_block_enable;
+
+ case PHYDM_INFO_DBG_PORT_0:
+ return false_alm_cnt->dbg_port0;
+
+ default:
+ return 0xffffffff;
+
+ }
+}
+
+void
+odm_init_all_timers(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))
+ odm_ant_div_timers(p_dm_odm, INIT_ANTDIV_TIMMER);
+#endif
+
+#if (CONFIG_DYNAMIC_RX_PATH == 1)
+ phydm_dynamic_rx_path_timers(p_dm_odm, INIT_DRP_TIMMER);
+#endif
+
+#if (BEAMFORMING_SUPPORT == 1)
+ odm_initialize_timer(p_dm_odm, &p_dm_odm->beamforming_info.beamforming_timer,
+ (void *)beamforming_sw_timer_callback, NULL, "beamforming_timer");
+#endif
+}
+
+void
+odm_cancel_all_timers(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))
+ odm_ant_div_timers(p_dm_odm, CANCEL_ANTDIV_TIMMER);
+#endif
+
+#if (CONFIG_DYNAMIC_RX_PATH == 1)
+ phydm_dynamic_rx_path_timers(p_dm_odm, CANCEL_DRP_TIMMER);
+#endif
+
+#if (BEAMFORMING_SUPPORT == 1)
+ odm_cancel_timer(p_dm_odm, &p_dm_odm->beamforming_info.beamforming_timer);
+#endif
+}
+
+
+void
+odm_release_all_timers(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))
+ odm_ant_div_timers(p_dm_odm, RELEASE_ANTDIV_TIMMER);
+#endif
+
+#if (CONFIG_DYNAMIC_RX_PATH == 1)
+ phydm_dynamic_rx_path_timers(p_dm_odm, RELEASE_DRP_TIMMER);
+#endif
+
+#if (BEAMFORMING_SUPPORT == 1)
+ odm_release_timer(p_dm_odm, &p_dm_odm->beamforming_info.beamforming_timer);
+#endif
+}
+
+
+/* 3============================================================
+ * 3 Tx Power Tracking
+ * 3============================================================ */
+
+/* need to ODM CE Platform
+ * move to here for ANT detection mechanism using */
+
+u32
+get_psd_data(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ unsigned int point,
+ u8 initial_gain_psd)
+{
+ /* unsigned int val, rfval; */
+ /* int psd_report; */
+ u32 psd_report;
+
+ /* HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter); */
+ /* Debug Message */
+ /* val = phy_query_bb_reg(adapter,0x908, MASKDWORD); */
+ /* dbg_print("reg908 = 0x%x\n",val); */
+ /* val = phy_query_bb_reg(adapter,0xDF4, MASKDWORD); */
+ /* rfval = phy_query_rf_reg(adapter, ODM_RF_PATH_A, 0x00, RFREGOFFSETMASK); */
+ /* dbg_print("RegDF4 = 0x%x, RFReg00 = 0x%x\n",val, rfval); */
+ /* dbg_print("PHYTXON = %x, OFDMCCA_PP = %x, CCKCCA_PP = %x, RFReg00 = %x\n", */
+ /* (val&BIT25)>>25, (val&BIT14)>>14, (val&BIT15)>>15, rfval); */
+
+ /* Set DCO frequency index, offset=(40MHz/SamplePts)*point */
+ odm_set_bb_reg(p_dm_odm, 0x808, 0x3FF, point);
+
+ /* Start PSD calculation, Reg808[22]=0->1 */
+ odm_set_bb_reg(p_dm_odm, 0x808, BIT(22), 1);
+ /* Need to wait for HW PSD report */
+ odm_stall_execution(1000);
+ odm_set_bb_reg(p_dm_odm, 0x808, BIT(22), 0);
+ /* Read PSD report, Reg8B4[15:0] */
+ psd_report = odm_get_bb_reg(p_dm_odm, 0x8B4, MASKDWORD) & 0x0000FFFF;
+
+ psd_report = (u32)(odm_convert_to_db(psd_report)) + (u32)(initial_gain_psd - 0x1c);
+
+ return psd_report;
+}
+
+u32
+odm_convert_to_db(
+ u32 value)
+{
+ u8 i;
+ u8 j;
+ u32 dB;
+
+ value = value & 0xFFFF;
+
+ for (i = 0; i < 12; i++) {
+ if (value <= db_invert_table[i][7])
+ break;
+ }
+
+ if (i >= 12) {
+ return 96; /* maximum 96 dB */
+ }
+
+ for (j = 0; j < 8; j++) {
+ if (value <= db_invert_table[i][j])
+ break;
+ }
+
+ dB = (i << 3) + j + 1;
+
+ return dB;
+}
+
+u32
+odm_convert_to_linear(
+ u32 value)
+{
+ u8 i;
+ u8 j;
+ u32 linear;
+
+ /* 1dB~96dB */
+
+ value = value & 0xFF;
+
+ i = (u8)((value - 1) >> 3);
+ j = (u8)(value - 1) - (i << 3);
+
+ linear = db_invert_table[i][j];
+
+ return linear;
+}
+
+/*
+ * ODM multi-port consideration, added by Roger, 2013.10.01.
+ * */
+void
+odm_asoc_entry_init(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+}
+
+/* Justin: According to the current RRSI to adjust Response Frame TX power, 2012/11/05 */
+void odm_dtc(struct PHY_DM_STRUCT *p_dm_odm)
+{
+#ifdef CONFIG_DM_RESP_TXAGC
+#define DTC_BASE 35 /* RSSI higher than this value, start to decade TX power */
+#define DTC_DWN_BASE (DTC_BASE-5) /* RSSI lower than this value, start to increase TX power */
+
+ /* RSSI vs TX power step mapping: decade TX power */
+ static const u8 dtc_table_down[] = {
+ DTC_BASE,
+ (DTC_BASE + 5),
+ (DTC_BASE + 10),
+ (DTC_BASE + 15),
+ (DTC_BASE + 20),
+ (DTC_BASE + 25)
+ };
+
+ /* RSSI vs TX power step mapping: increase TX power */
+ static const u8 dtc_table_up[] = {
+ DTC_DWN_BASE,
+ (DTC_DWN_BASE - 5),
+ (DTC_DWN_BASE - 10),
+ (DTC_DWN_BASE - 15),
+ (DTC_DWN_BASE - 15),
+ (DTC_DWN_BASE - 20),
+ (DTC_DWN_BASE - 20),
+ (DTC_DWN_BASE - 25),
+ (DTC_DWN_BASE - 25),
+ (DTC_DWN_BASE - 30),
+ (DTC_DWN_BASE - 35)
+ };
+
+ u8 i;
+ u8 dtc_steps = 0;
+ u8 sign;
+ u8 resp_txagc = 0;
+
+ if (DTC_BASE < p_dm_odm->rssi_min) {
+ /* need to decade the CTS TX power */
+ sign = 1;
+ for (i = 0; i < ARRAY_SIZE(dtc_table_down); i++) {
+ if ((dtc_table_down[i] >= p_dm_odm->rssi_min) || (dtc_steps >= 6))
+ break;
+ else
+ dtc_steps++;
+ }
+ } else {
+ sign = 0;
+ dtc_steps = 0;
+ }
+
+ resp_txagc = dtc_steps | (sign << 4);
+ resp_txagc = resp_txagc | (resp_txagc << 5);
+ odm_write_1byte(p_dm_odm, 0x06d9, resp_txagc);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_PWR_TRAIN, ODM_DBG_LOUD, ("%s rssi_min:%u, set RESP_TXAGC to %s %u\n",
+ __func__, p_dm_odm->rssi_min, sign ? "minus" : "plus", dtc_steps));
+#endif /* CONFIG_RESP_TXAGC_ADJUST */
+}
+
+void
+odm_update_power_training_state(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ struct false_ALARM_STATISTICS *false_alm_cnt = (struct false_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDMfalseALMCNT);
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+ u32 score = 0;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_PWR_TRAIN))
+ return;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("odm_update_power_training_state()============>\n"));
+ p_dm_odm->is_change_state = false;
+
+ /* Debug command */
+ if (p_dm_odm->force_power_training_state) {
+ if (p_dm_odm->force_power_training_state == 1 && !p_dm_odm->is_disable_power_training) {
+ p_dm_odm->is_change_state = true;
+ p_dm_odm->is_disable_power_training = true;
+ } else if (p_dm_odm->force_power_training_state == 2 && p_dm_odm->is_disable_power_training) {
+ p_dm_odm->is_change_state = true;
+ p_dm_odm->is_disable_power_training = false;
+ }
+
+ p_dm_odm->PT_score = 0;
+ p_dm_odm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
+ p_dm_odm->phy_dbg_info.num_qry_phy_status_cck = 0;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("odm_update_power_training_state(): force_power_training_state = %d\n",
+ p_dm_odm->force_power_training_state));
+ return;
+ }
+
+ if (!p_dm_odm->is_linked)
+ return;
+
+ /* First connect */
+ if ((p_dm_odm->is_linked) && (p_dm_dig_table->is_media_connect_0 == false)) {
+ p_dm_odm->PT_score = 0;
+ p_dm_odm->is_change_state = true;
+ p_dm_odm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
+ p_dm_odm->phy_dbg_info.num_qry_phy_status_cck = 0;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("odm_update_power_training_state(): First Connect\n"));
+ return;
+ }
+
+ /* Compute score */
+ if (p_dm_odm->nhm_cnt_0 >= 215)
+ score = 2;
+ else if (p_dm_odm->nhm_cnt_0 >= 190)
+ score = 1; /* unknow state */
+ else {
+ u32 rx_pkt_cnt;
+
+ rx_pkt_cnt = (u32)(p_dm_odm->phy_dbg_info.num_qry_phy_status_ofdm) + (u32)(p_dm_odm->phy_dbg_info.num_qry_phy_status_cck);
+
+ if ((false_alm_cnt->cnt_cca_all > 31 && rx_pkt_cnt > 31) && (false_alm_cnt->cnt_cca_all >= rx_pkt_cnt)) {
+ if ((rx_pkt_cnt + (rx_pkt_cnt >> 1)) <= false_alm_cnt->cnt_cca_all)
+ score = 0;
+ else if ((rx_pkt_cnt + (rx_pkt_cnt >> 2)) <= false_alm_cnt->cnt_cca_all)
+ score = 1;
+ else
+ score = 2;
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("odm_update_power_training_state(): rx_pkt_cnt = %d, cnt_cca_all = %d\n",
+ rx_pkt_cnt, false_alm_cnt->cnt_cca_all));
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("odm_update_power_training_state(): num_qry_phy_status_ofdm = %d, num_qry_phy_status_cck = %d\n",
+ (u32)(p_dm_odm->phy_dbg_info.num_qry_phy_status_ofdm), (u32)(p_dm_odm->phy_dbg_info.num_qry_phy_status_cck)));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("odm_update_power_training_state(): nhm_cnt_0 = %d, score = %d\n",
+ p_dm_odm->nhm_cnt_0, score));
+
+ /* smoothing */
+ p_dm_odm->PT_score = (score << 4) + (p_dm_odm->PT_score >> 1) + (p_dm_odm->PT_score >> 2);
+ score = (p_dm_odm->PT_score + 32) >> 6;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("odm_update_power_training_state(): PT_score = %d, score after smoothing = %d\n",
+ p_dm_odm->PT_score, score));
+
+ /* mode decision */
+ if (score == 2) {
+ if (p_dm_odm->is_disable_power_training) {
+ p_dm_odm->is_change_state = true;
+ p_dm_odm->is_disable_power_training = false;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("odm_update_power_training_state(): Change state\n"));
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("odm_update_power_training_state(): Enable Power Training\n"));
+ } else if (score == 0) {
+ if (!p_dm_odm->is_disable_power_training) {
+ p_dm_odm->is_change_state = true;
+ p_dm_odm->is_disable_power_training = true;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("odm_update_power_training_state(): Change state\n"));
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("odm_update_power_training_state(): Disable Power Training\n"));
+ }
+
+ p_dm_odm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
+ p_dm_odm->phy_dbg_info.num_qry_phy_status_cck = 0;
+}
+
+
+
+/*===========================================================*/
+/* The following is for compile only*/
+/*===========================================================*/
+/*#define TARGET_CHNL_NUM_2G_5G 59*/
+/*===========================================================*/
+
+void
+phydm_noisy_detection(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 total_fa_cnt, total_cca_cnt;
+ u32 score = 0, i, score_smooth;
+
+ total_cca_cnt = p_dm_odm->false_alm_cnt.cnt_cca_all;
+ total_fa_cnt = p_dm_odm->false_alm_cnt.cnt_all;
+
+ for (i = 0; i <= 16; i++) {
+ if (total_fa_cnt * 16 >= total_cca_cnt * (16 - i)) {
+ score = 16 - i;
+ break;
+ }
+ }
+
+ /* noisy_decision_smooth = noisy_decision_smooth>>1 + (score<<3)>>1; */
+ p_dm_odm->noisy_decision_smooth = (p_dm_odm->noisy_decision_smooth >> 1) + (score << 2);
+
+ /* Round the noisy_decision_smooth: +"3" comes from (2^3)/2-1 */
+ score_smooth = (total_cca_cnt >= 300) ? ((p_dm_odm->noisy_decision_smooth + 3) >> 3) : 0;
+
+ p_dm_odm->noisy_decision = (score_smooth >= 3) ? 1 : 0;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_NOISY_DETECT, ODM_DBG_LOUD,
+ ("[NoisyDetection] total_cca_cnt=%d, total_fa_cnt=%d, noisy_decision_smooth=%d, score=%d, score_smooth=%d, p_dm_odm->noisy_decision=%d\n",
+ total_cca_cnt, total_fa_cnt, p_dm_odm->noisy_decision_smooth, score, score_smooth, p_dm_odm->noisy_decision));
+
+}
+
+void
+phydm_set_ext_switch(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+ u32 ext_ant_switch = dm_value[0];
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
+
+ /*Output Pin Settings*/
+ odm_set_mac_reg(p_dm_odm, 0x4C, BIT(23), 0); /*select DPDT_P and DPDT_N as output pin*/
+ odm_set_mac_reg(p_dm_odm, 0x4C, BIT(24), 1); /*by WLAN control*/
+
+ odm_set_bb_reg(p_dm_odm, 0xCB4, 0xF, 7); /*DPDT_P = 1b'0*/
+ odm_set_bb_reg(p_dm_odm, 0xCB4, 0xF0, 7); /*DPDT_N = 1b'0*/
+
+ if (ext_ant_switch == MAIN_ANT) {
+ odm_set_bb_reg(p_dm_odm, 0xCB4, (BIT(29) | BIT(28)), 1);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("***8821A set ant switch = 2b'01 (Main)\n"));
+ } else if (ext_ant_switch == AUX_ANT) {
+ odm_set_bb_reg(p_dm_odm, 0xCB4, BIT(29) | BIT(28), 2);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("***8821A set ant switch = 2b'10 (Aux)\n"));
+ }
+ }
+}
+
+static void
+phydm_csi_mask_enable(
+ void *p_dm_void,
+ u32 enable
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 reg_value = 0;
+
+ reg_value = (enable == CSI_MASK_ENABLE) ? 1 : 0;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+
+ odm_set_bb_reg(p_dm_odm, 0xD2C, BIT(28), reg_value);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("Enable CSI Mask: Reg 0xD2C[28] = ((0x%x))\n", reg_value));
+
+ } else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+
+ odm_set_bb_reg(p_dm_odm, 0x874, BIT(0), reg_value);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("Enable CSI Mask: Reg 0x874[0] = ((0x%x))\n", reg_value));
+ }
+
+}
+
+static void
+phydm_clean_all_csi_mask(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+
+ odm_set_bb_reg(p_dm_odm, 0xD40, MASKDWORD, 0);
+ odm_set_bb_reg(p_dm_odm, 0xD44, MASKDWORD, 0);
+ odm_set_bb_reg(p_dm_odm, 0xD48, MASKDWORD, 0);
+ odm_set_bb_reg(p_dm_odm, 0xD4c, MASKDWORD, 0);
+
+ } else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+
+ odm_set_bb_reg(p_dm_odm, 0x880, MASKDWORD, 0);
+ odm_set_bb_reg(p_dm_odm, 0x884, MASKDWORD, 0);
+ odm_set_bb_reg(p_dm_odm, 0x888, MASKDWORD, 0);
+ odm_set_bb_reg(p_dm_odm, 0x88c, MASKDWORD, 0);
+ odm_set_bb_reg(p_dm_odm, 0x890, MASKDWORD, 0);
+ odm_set_bb_reg(p_dm_odm, 0x894, MASKDWORD, 0);
+ odm_set_bb_reg(p_dm_odm, 0x898, MASKDWORD, 0);
+ odm_set_bb_reg(p_dm_odm, 0x89c, MASKDWORD, 0);
+ }
+}
+
+static void
+phydm_set_csi_mask_reg(
+ void *p_dm_void,
+ u32 tone_idx_tmp,
+ u8 tone_direction
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 byte_offset, bit_offset;
+ u32 target_reg;
+ u8 reg_tmp_value;
+ u32 tone_num = 64;
+ u32 tone_num_shift = 0;
+ u32 csi_mask_reg_p = 0, csi_mask_reg_n = 0;
+
+ /* calculate real tone idx*/
+ if ((tone_idx_tmp % 10) >= 5)
+ tone_idx_tmp += 10;
+
+ tone_idx_tmp = (tone_idx_tmp / 10);
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+
+ tone_num = 64;
+ csi_mask_reg_p = 0xD40;
+ csi_mask_reg_n = 0xD48;
+
+ } else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+
+ tone_num = 128;
+ csi_mask_reg_p = 0x880;
+ csi_mask_reg_n = 0x890;
+ }
+
+ if (tone_direction == FREQ_POSITIVE) {
+
+ if (tone_idx_tmp >= (tone_num - 1))
+ tone_idx_tmp = (tone_num - 1);
+
+ byte_offset = (u8)(tone_idx_tmp >> 3);
+ bit_offset = (u8)(tone_idx_tmp & 0x7);
+ target_reg = csi_mask_reg_p + byte_offset;
+
+ } else {
+ tone_num_shift = tone_num;
+
+ if (tone_idx_tmp >= tone_num)
+ tone_idx_tmp = tone_num;
+
+ tone_idx_tmp = tone_num - tone_idx_tmp;
+
+ byte_offset = (u8)(tone_idx_tmp >> 3);
+ bit_offset = (u8)(tone_idx_tmp & 0x7);
+ target_reg = csi_mask_reg_n + byte_offset;
+ }
+
+ reg_tmp_value = odm_read_1byte(p_dm_odm, target_reg);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("Pre Mask tone idx[%d]: Reg0x%x = ((0x%x))\n", (tone_idx_tmp + tone_num_shift), target_reg, reg_tmp_value));
+ reg_tmp_value |= BIT(bit_offset);
+ odm_write_1byte(p_dm_odm, target_reg, reg_tmp_value);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("New Mask tone idx[%d]: Reg0x%x = ((0x%x))\n", (tone_idx_tmp + tone_num_shift), target_reg, reg_tmp_value));
+}
+
+static void
+phydm_set_nbi_reg(
+ void *p_dm_void,
+ u32 tone_idx_tmp,
+ u32 bw
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 nbi_table_128[NBI_TABLE_SIZE_128] = {25, 55, 85, 115, 135, 155, 185, 205, 225, 245, /*1~10*/ /*tone_idx X 10*/
+ 265, 285, 305, 335, 355, 375, 395, 415, 435, 455, /*11~20*/
+ 485, 505, 525, 555, 585, 615, 635
+ }; /*21~27*/
+
+ u32 nbi_table_256[NBI_TABLE_SIZE_256] = { 25, 55, 85, 115, 135, 155, 175, 195, 225, 245, /*1~10*/
+ 265, 285, 305, 325, 345, 365, 385, 405, 425, 445, /*11~20*/
+ 465, 485, 505, 525, 545, 565, 585, 605, 625, 645, /*21~30*/
+ 665, 695, 715, 735, 755, 775, 795, 815, 835, 855, /*31~40*/
+ 875, 895, 915, 935, 955, 975, 995, 1015, 1035, 1055, /*41~50*/
+ 1085, 1105, 1125, 1145, 1175, 1195, 1225, 1255, 1275
+ }; /*51~59*/
+
+ u32 reg_idx = 0;
+ u32 i;
+ u8 nbi_table_idx = FFT_128_TYPE;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
+
+ nbi_table_idx = FFT_128_TYPE;
+ else if (p_dm_odm->support_ic_type & ODM_IC_11AC_1_SERIES)
+
+ nbi_table_idx = FFT_256_TYPE;
+ else if (p_dm_odm->support_ic_type & ODM_IC_11AC_2_SERIES) {
+
+ if (bw == 80)
+ nbi_table_idx = FFT_256_TYPE;
+ else /*20M, 40M*/
+ nbi_table_idx = FFT_128_TYPE;
+ }
+
+ if (nbi_table_idx == FFT_128_TYPE) {
+
+ for (i = 0; i < NBI_TABLE_SIZE_128; i++) {
+ if (tone_idx_tmp < nbi_table_128[i]) {
+ reg_idx = i + 1;
+ break;
+ }
+ }
+
+ } else if (nbi_table_idx == FFT_256_TYPE) {
+
+ for (i = 0; i < NBI_TABLE_SIZE_256; i++) {
+ if (tone_idx_tmp < nbi_table_256[i]) {
+ reg_idx = i + 1;
+ break;
+ }
+ }
+ }
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(p_dm_odm, 0xc40, 0x1f000000, reg_idx);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("Set tone idx: Reg0xC40[28:24] = ((0x%x))\n", reg_idx));
+ /**/
+ } else {
+ odm_set_bb_reg(p_dm_odm, 0x87c, 0xfc000, reg_idx);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("Set tone idx: Reg0x87C[19:14] = ((0x%x))\n", reg_idx));
+ /**/
+ }
+}
+
+
+static void
+phydm_nbi_enable(
+ void *p_dm_void,
+ u32 enable
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 reg_value = 0;
+
+ reg_value = (enable == NBI_ENABLE) ? 1 : 0;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+
+ odm_set_bb_reg(p_dm_odm, 0xc40, BIT(9), reg_value);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("Enable NBI Reg0xC40[9] = ((0x%x))\n", reg_value));
+
+ } else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+
+ odm_set_bb_reg(p_dm_odm, 0x87c, BIT(13), reg_value);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("Enable NBI Reg0x87C[13] = ((0x%x))\n", reg_value));
+ }
+}
+
+static u8
+phydm_calculate_fc(
+ void *p_dm_void,
+ u32 channel,
+ u32 bw,
+ u32 second_ch,
+ u32 *fc_in
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 fc = *fc_in;
+ u32 start_ch_per_40m[NUM_START_CH_40M] = {36, 44, 52, 60, 100, 108, 116, 124, 132, 140, 149, 157, 165, 173};
+ u32 start_ch_per_80m[NUM_START_CH_80M] = {36, 52, 100, 116, 132, 149, 165};
+ u32 *p_start_ch = &(start_ch_per_40m[0]);
+ u32 num_start_channel = NUM_START_CH_40M;
+ u32 channel_offset = 0;
+ u32 i;
+
+ /*2.4G*/
+ if (channel <= 14 && channel > 0) {
+
+ if (bw == 80)
+ return SET_ERROR;
+
+ fc = 2412 + (channel - 1) * 5;
+
+ if (bw == 40 && (second_ch == PHYDM_ABOVE)) {
+
+ if (channel >= 10) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("CH = ((%d)), Scnd_CH = ((%d)) Error setting\n", channel, second_ch));
+ return SET_ERROR;
+ }
+ fc += 10;
+ } else if (bw == 40 && (second_ch == PHYDM_BELOW)) {
+
+ if (channel <= 2) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("CH = ((%d)), Scnd_CH = ((%d)) Error setting\n", channel, second_ch));
+ return SET_ERROR;
+ }
+ fc -= 10;
+ }
+ }
+ /*5G*/
+ else if (channel >= 36 && channel <= 177) {
+
+ if (bw != 20) {
+
+ if (bw == 40) {
+ num_start_channel = NUM_START_CH_40M;
+ p_start_ch = &(start_ch_per_40m[0]);
+ channel_offset = CH_OFFSET_40M;
+ } else if (bw == 80) {
+ num_start_channel = NUM_START_CH_80M;
+ p_start_ch = &(start_ch_per_80m[0]);
+ channel_offset = CH_OFFSET_80M;
+ }
+
+ for (i = 0; i < num_start_channel; i++) {
+
+ if (channel < p_start_ch[i + 1]) {
+ channel = p_start_ch[i] + channel_offset;
+ break;
+ }
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("Mod_CH = ((%d))\n", channel));
+ }
+
+ fc = 5180 + (channel - 36) * 5;
+
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("CH = ((%d)) Error setting\n", channel));
+ return SET_ERROR;
+ }
+
+ *fc_in = fc;
+
+ return SET_SUCCESS;
+}
+
+
+static u8
+phydm_calculate_intf_distance(
+ void *p_dm_void,
+ u32 bw,
+ u32 fc,
+ u32 f_interference,
+ u32 *p_tone_idx_tmp_in
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 bw_up, bw_low;
+ u32 int_distance;
+ u32 tone_idx_tmp;
+ u8 set_result = SET_NO_NEED;
+
+ bw_up = fc + bw / 2;
+ bw_low = fc - bw / 2;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("[f_l, fc, fh] = [ %d, %d, %d ], f_int = ((%d))\n", bw_low, fc, bw_up, f_interference));
+
+ if ((f_interference >= bw_low) && (f_interference <= bw_up)) {
+
+ int_distance = (fc >= f_interference) ? (fc - f_interference) : (f_interference - fc);
+ tone_idx_tmp = (int_distance << 5); /* =10*(int_distance /0.3125) */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("int_distance = ((%d MHz)) Mhz, tone_idx_tmp = ((%d.%d))\n", int_distance, (tone_idx_tmp / 10), (tone_idx_tmp % 10)));
+ *p_tone_idx_tmp_in = tone_idx_tmp;
+ set_result = SET_SUCCESS;
+ }
+
+ return set_result;
+
+}
+
+
+static u8
+phydm_csi_mask_setting(
+ void *p_dm_void,
+ u32 enable,
+ u32 channel,
+ u32 bw,
+ u32 f_interference,
+ u32 second_ch
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 fc;
+ u32 int_distance;
+ u8 tone_direction;
+ u32 tone_idx_tmp;
+ u8 set_result = SET_SUCCESS;
+
+ if (enable == CSI_MASK_DISABLE) {
+ set_result = SET_SUCCESS;
+ phydm_clean_all_csi_mask(p_dm_odm);
+
+ } else {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("[Set CSI MASK_] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
+ channel, bw, f_interference, (((bw == 20) || (channel > 14)) ? "Don't care" : (second_ch == PHYDM_ABOVE) ? "H" : "L")));
+
+ /*calculate fc*/
+ if (phydm_calculate_fc(p_dm_odm, channel, bw, second_ch, &fc) == SET_ERROR)
+ set_result = SET_ERROR;
+
+ else {
+ /*calculate interference distance*/
+ if (phydm_calculate_intf_distance(p_dm_odm, bw, fc, f_interference, &tone_idx_tmp) == SET_SUCCESS) {
+
+ tone_direction = (f_interference >= fc) ? FREQ_POSITIVE : FREQ_NEGATIVE;
+ phydm_set_csi_mask_reg(p_dm_odm, tone_idx_tmp, tone_direction);
+ set_result = SET_SUCCESS;
+ } else
+ set_result = SET_NO_NEED;
+ }
+ }
+
+ if (set_result == SET_SUCCESS)
+ phydm_csi_mask_enable(p_dm_odm, enable);
+ else
+ phydm_csi_mask_enable(p_dm_odm, CSI_MASK_DISABLE);
+
+ return set_result;
+}
+
+u8
+phydm_nbi_setting(
+ void *p_dm_void,
+ u32 enable,
+ u32 channel,
+ u32 bw,
+ u32 f_interference,
+ u32 second_ch
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 fc;
+ u32 int_distance;
+ u32 tone_idx_tmp;
+ u8 set_result = SET_SUCCESS;
+ u32 bw_max = 40;
+
+ if (enable == NBI_DISABLE)
+ set_result = SET_SUCCESS;
+
+ else {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_API, ODM_DBG_LOUD, ("[Set NBI] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
+ channel, bw, f_interference, (((second_ch == PHYDM_DONT_CARE) || (bw == 20) || (channel > 14)) ? "Don't care" : (second_ch == PHYDM_ABOVE) ? "H" : "L")));
+
+ /*calculate fc*/
+ if (phydm_calculate_fc(p_dm_odm, channel, bw, second_ch, &fc) == SET_ERROR)
+ set_result = SET_ERROR;
+
+ else {
+ /*calculate interference distance*/
+ if (phydm_calculate_intf_distance(p_dm_odm, bw, fc, f_interference, &tone_idx_tmp) == SET_SUCCESS) {
+
+ phydm_set_nbi_reg(p_dm_odm, tone_idx_tmp, bw);
+ set_result = SET_SUCCESS;
+ } else
+ set_result = SET_NO_NEED;
+ }
+ }
+
+ if (set_result == SET_SUCCESS)
+ phydm_nbi_enable(p_dm_odm, enable);
+ else
+ phydm_nbi_enable(p_dm_odm, NBI_DISABLE);
+
+ return set_result;
+}
+
+void
+phydm_api_debug(
+ void *p_dm_void,
+ u32 function_map,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+ u32 channel = dm_value[1];
+ u32 bw = dm_value[2];
+ u32 f_interference = dm_value[3];
+ u32 second_ch = dm_value[4];
+ u8 set_result = 0;
+
+ /*PHYDM_API_NBI*/
+ /*-------------------------------------------------------------------------------------------------------------------------------*/
+ if (function_map == PHYDM_API_NBI) {
+
+ if (dm_value[0] == 100) {
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "[HELP-NBI] EN(on=1, off=2) CH BW(20/40/80) f_intf(Mhz) Scnd_CH(L=1, H=2)\n"));
+ return;
+
+ } else if (dm_value[0] == NBI_ENABLE) {
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "[Enable NBI] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
+ channel, bw, f_interference, ((second_ch == PHYDM_DONT_CARE) || (bw == 20) || (channel > 14)) ? "Don't care" : ((second_ch == PHYDM_ABOVE) ? "H" : "L")));
+ set_result = phydm_nbi_setting(p_dm_odm, NBI_ENABLE, channel, bw, f_interference, second_ch);
+
+ } else if (dm_value[0] == NBI_DISABLE) {
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "[Disable NBI]\n"));
+ set_result = phydm_nbi_setting(p_dm_odm, NBI_DISABLE, channel, bw, f_interference, second_ch);
+
+ } else
+
+ set_result = SET_ERROR;
+ PHYDM_SNPRINTF((output + used, out_len - used, "[NBI set result: %s]\n", (set_result == SET_SUCCESS) ? "Success" : ((set_result == SET_NO_NEED) ? "No need" : "Error")));
+
+ }
+
+ /*PHYDM_CSI_MASK*/
+ /*-------------------------------------------------------------------------------------------------------------------------------*/
+ else if (function_map == PHYDM_API_CSI_MASK) {
+
+ if (dm_value[0] == 100) {
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "[HELP-CSI MASK] EN(on=1, off=2) CH BW(20/40/80) f_intf(Mhz) Scnd_CH(L=1, H=2)\n"));
+ return;
+
+ } else if (dm_value[0] == CSI_MASK_ENABLE) {
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "[Enable CSI MASK] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
+ channel, bw, f_interference, (channel > 14) ? "Don't care" : (((second_ch == PHYDM_DONT_CARE) || (bw == 20) || (channel > 14)) ? "H" : "L")));
+ set_result = phydm_csi_mask_setting(p_dm_odm, CSI_MASK_ENABLE, channel, bw, f_interference, second_ch);
+
+ } else if (dm_value[0] == CSI_MASK_DISABLE) {
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "[Disable CSI MASK]\n"));
+ set_result = phydm_csi_mask_setting(p_dm_odm, CSI_MASK_DISABLE, channel, bw, f_interference, second_ch);
+
+ } else
+
+ set_result = SET_ERROR;
+ PHYDM_SNPRINTF((output + used, out_len - used, "[CSI MASK set result: %s]\n", (set_result == SET_SUCCESS) ? "Success" : ((set_result == SET_NO_NEED) ? "No need" : "Error")));
+ }
+}
+
+void
+phydm_receiver_blocking(
+ void *p_dm_void
+)
+{
+#ifdef CONFIG_RECEIVER_BLOCKING
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 channel = *p_dm_odm->p_channel;
+ u8 bw = *p_dm_odm->p_band_width;
+ u8 set_result = 0;
+
+ if (!(p_dm_odm->support_ic_type & ODM_RECEIVER_BLOCKING_SUPPORT))
+ return;
+
+ if (p_dm_odm->consecutive_idlel_time > 10 && p_dm_odm->mp_mode == false && p_dm_odm->adaptivity_enable == true) {
+ if ((bw == ODM_BW20M) && (channel == 1)) {
+ set_result = phydm_nbi_setting(p_dm_odm, NBI_ENABLE, channel, 20, 2410, PHYDM_DONT_CARE);
+ p_dm_odm->is_receiver_blocking_en = true;
+ } else if ((bw == ODM_BW20M) && (channel == 13)) {
+ set_result = phydm_nbi_setting(p_dm_odm, NBI_ENABLE, channel, 20, 2473, PHYDM_DONT_CARE);
+ p_dm_odm->is_receiver_blocking_en = true;
+ } else if (*(p_dm_odm->p_is_scan_in_process) == false) {
+ if (p_dm_odm->is_receiver_blocking_en && channel != 1 && channel != 13) {
+ phydm_nbi_enable(p_dm_odm, NBI_DISABLE);
+ odm_set_bb_reg(p_dm_odm, 0xc40, 0x1f000000, 0x1f);
+ p_dm_odm->is_receiver_blocking_en = false;
+ }
+ }
+ } else {
+ if (p_dm_odm->is_receiver_blocking_en) {
+ phydm_nbi_enable(p_dm_odm, NBI_DISABLE);
+ odm_set_bb_reg(p_dm_odm, 0xc40, 0x1f000000, 0x1f);
+ p_dm_odm->is_receiver_blocking_en = false;
+ }
+ }
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD,
+ ("[NBI set result: %s]\n", (set_result == SET_SUCCESS ? "Success" : (set_result == SET_NO_NEED ? "No need" : "Error"))));
+#endif
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm.h b/drivers/staging/rtl8188eu/hal/phydm.h
new file mode 100644
index 000000000000..004354ceb84f
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm.h
@@ -0,0 +1,1069 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __HALDMOUTSRC_H__
+#define __HALDMOUTSRC_H__
+
+/*============================================================*/
+/*include files*/
+/*============================================================*/
+#include "phydm_pre_define.h"
+#include "phydm_dig.h"
+#if PHYDM_SUPPORT_EDCA
+#include "phydm_edcaturbocheck.h"
+#endif
+#include "phydm_pathdiv.h"
+#include "phydm_antdiv.h"
+#include "phydm_antdect.h"
+#include "phydm_dynamicbbpowersaving.h"
+#include "phydm_rainfo.h"
+#include "phydm_dynamictxpower.h"
+#include "phydm_cfotracking.h"
+#include "phydm_acs.h"
+#include "phydm_adaptivity.h"
+#include "phydm_iqk.h"
+#include "phydm_dfs.h"
+#include "phydm_ccx.h"
+#include "phydm_hal_txbf_api.h"
+
+#include "phydm_adc_sampling.h"
+#include "phydm_dynamic_rx_path.h"
+
+#include "phydm_beamforming.h"
+
+#include "phydm_noisemonitor.h"
+#include "halphyrf_ce.h"
+
+/*============================================================*/
+/*Definition */
+/*============================================================*/
+
+/* Traffic load decision */
+#define TRAFFIC_ULTRA_LOW 1
+#define TRAFFIC_LOW 2
+#define TRAFFIC_MID 3
+#define TRAFFIC_HIGH 4
+
+#define NONE 0
+
+/*NBI API------------------------------------*/
+#define NBI_ENABLE 1
+#define NBI_DISABLE 2
+
+#define NBI_TABLE_SIZE_128 27
+#define NBI_TABLE_SIZE_256 59
+
+#define NUM_START_CH_80M 7
+#define NUM_START_CH_40M 14
+
+#define CH_OFFSET_40M 2
+#define CH_OFFSET_80M 6
+
+/*CSI MASK API------------------------------------*/
+#define CSI_MASK_ENABLE 1
+#define CSI_MASK_DISABLE 2
+
+/*------------------------------------------------*/
+
+#define FFT_128_TYPE 1
+#define FFT_256_TYPE 2
+
+#define SET_SUCCESS 1
+#define SET_ERROR 2
+#define SET_NO_NEED 3
+
+#define FREQ_POSITIVE 1
+#define FREQ_NEGATIVE 2
+
+#define PHYDM_WATCH_DOG_PERIOD 2
+
+/*============================================================*/
+/*structure and define*/
+/*============================================================*/
+
+/*2011/09/20 MH Add for AP/ADSLpseudo DM structuer requirement.*/
+/*We need to remove to other position???*/
+
+struct rtl8192cd_priv {
+ u8 temp;
+};
+
+struct _dynamic_primary_cca {
+ u8 pri_cca_flag;
+ u8 intf_flag;
+ u8 intf_type;
+ u8 dup_rts_flag;
+ u8 monitor_flag;
+ u8 CH_offset;
+ u8 MF_state;
+};
+
+#define dm_type_by_fw 0
+#define dm_type_by_driver 1
+
+/*Declare for common info*/
+
+#define IQK_THRESHOLD 8
+#define DPK_THRESHOLD 4
+
+struct _odm_phy_status_info_ {
+ /* */
+ /* Be care, if you want to add any element please insert between */
+ /* rx_pwdb_all & signal_strength. */
+ /* */
+ u8 rx_pwdb_all;
+ u8 signal_quality; /* in 0-100 index. */
+ s8 rx_mimo_signal_quality[4]; /* per-path's EVM translate to 0~100% */
+ u8 rx_mimo_evm_dbm[4]; /* per-path's original EVM (dbm) */
+ u8 rx_mimo_signal_strength[4]; /* in 0~100 index */
+ s16 cfo_short[4]; /* per-path's cfo_short */
+ s16 cfo_tail[4]; /* per-path's cfo_tail */
+ s8 rx_power; /* in dBm Translate from PWdB */
+ s8 recv_signal_power; /* Real power in dBm for this packet, no beautification and aggregation. Keep this raw info to be used for the other procedures. */
+ u8 bt_rx_rssi_percentage;
+ u8 signal_strength; /* in 0-100 index. */
+ s8 rx_pwr[4]; /* per-path's pwdb */
+ s8 rx_snr[4]; /* per-path's SNR */
+ /* s8 BB_Backup[13]; backup reg. */
+#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1)
+ u8 rx_count:2; /* RX path counter---*/
+ u8 band_width:2;
+ u8 rxsc:4; /* sub-channel---*/
+#else
+ u8 band_width;
+#endif
+ u8 bt_coex_pwr_adjust;
+#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1)
+ u8 channel; /* channel number---*/
+ bool is_mu_packet; /* is MU packet or not---*/
+ bool is_beamformed; /* BF packet---*/
+#endif
+};
+
+struct _odm_per_pkt_info_ {
+ u8 data_rate;
+ u8 station_id;
+ bool is_packet_match_bssid;
+ bool is_packet_to_self;
+ bool is_packet_beacon;
+ bool is_to_self;
+ u8 ppdu_cnt;
+};
+
+struct _odm_phy_dbg_info_ {
+ /*ODM Write,debug info*/
+ s8 rx_snr_db[4];
+ u32 num_qry_phy_status;
+ u32 num_qry_phy_status_cck;
+ u32 num_qry_phy_status_ofdm;
+#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1)
+ u32 num_qry_mu_pkt;
+ u32 num_qry_bf_pkt;
+ u32 num_qry_mu_vht_pkt[40];
+ u32 num_qry_vht_pkt[40];
+ bool is_ldpc_pkt;
+ bool is_stbc_pkt;
+ u8 num_of_ppdu[4];
+ u8 gid_num[4];
+#endif
+ u8 num_qry_beacon_pkt;
+ /* Others */
+ s32 rx_evm[4];
+
+};
+
+/*2011/20/20 MH For MP driver RT_WLAN_STA = struct sta_info*/
+/*Please declare below ODM relative info in your STA info structure.*/
+
+struct _ODM_STA_INFO {
+ /*Driver Write*/
+ bool is_used; /*record the sta status link or not?*/
+ u8 iot_peer; /*Enum value. HT_IOT_PEER_E*/
+
+ /*ODM Write*/
+ /*PHY_STATUS_INFO*/
+ u8 rssi_path[4];
+ u8 rssi_ave;
+ u8 RXEVM[4];
+ u8 RXSNR[4];
+
+};
+
+enum odm_cmninfo_e {
+ /*Fixed value*/
+ /*-----------HOOK BEFORE REG INIT-----------*/
+ ODM_CMNINFO_PLATFORM = 0,
+ ODM_CMNINFO_ABILITY,
+ ODM_CMNINFO_INTERFACE,
+ ODM_CMNINFO_MP_TEST_CHIP,
+ ODM_CMNINFO_IC_TYPE,
+ ODM_CMNINFO_CUT_VER,
+ ODM_CMNINFO_FAB_VER,
+ ODM_CMNINFO_RF_TYPE,
+ ODM_CMNINFO_RFE_TYPE,
+ ODM_CMNINFO_BOARD_TYPE,
+ ODM_CMNINFO_PACKAGE_TYPE,
+ ODM_CMNINFO_EXT_LNA,
+ ODM_CMNINFO_5G_EXT_LNA,
+ ODM_CMNINFO_EXT_PA,
+ ODM_CMNINFO_5G_EXT_PA,
+ ODM_CMNINFO_GPA,
+ ODM_CMNINFO_APA,
+ ODM_CMNINFO_GLNA,
+ ODM_CMNINFO_ALNA,
+ ODM_CMNINFO_EXT_TRSW,
+ ODM_CMNINFO_EXT_LNA_GAIN,
+ ODM_CMNINFO_PATCH_ID,
+ ODM_CMNINFO_BINHCT_TEST,
+ ODM_CMNINFO_BWIFI_TEST,
+ ODM_CMNINFO_SMART_CONCURRENT,
+ ODM_CMNINFO_CONFIG_BB_RF,
+ ODM_CMNINFO_DOMAIN_CODE_2G,
+ ODM_CMNINFO_DOMAIN_CODE_5G,
+ ODM_CMNINFO_IQKFWOFFLOAD,
+ ODM_CMNINFO_IQKPAOFF,
+ ODM_CMNINFO_HUBUSBMODE,
+ ODM_CMNINFO_FWDWRSVDPAGEINPROGRESS,
+ ODM_CMNINFO_TX_TP,
+ ODM_CMNINFO_RX_TP,
+ ODM_CMNINFO_SOUNDING_SEQ,
+ ODM_CMNINFO_REGRFKFREEENABLE,
+ ODM_CMNINFO_RFKFREEENABLE,
+ ODM_CMNINFO_NORMAL_RX_PATH_CHANGE,
+ ODM_CMNINFO_EFUSE0X3D8,
+ ODM_CMNINFO_EFUSE0X3D7,
+ /*-----------HOOK BEFORE REG INIT-----------*/
+
+ /*Dynamic value:*/
+
+ /*--------- POINTER REFERENCE-----------*/
+ ODM_CMNINFO_MAC_PHY_MODE,
+ ODM_CMNINFO_TX_UNI,
+ ODM_CMNINFO_RX_UNI,
+ ODM_CMNINFO_WM_MODE,
+ ODM_CMNINFO_BAND,
+ ODM_CMNINFO_SEC_CHNL_OFFSET,
+ ODM_CMNINFO_SEC_MODE,
+ ODM_CMNINFO_BW,
+ ODM_CMNINFO_CHNL,
+ ODM_CMNINFO_FORCED_RATE,
+ ODM_CMNINFO_ANT_DIV,
+ ODM_CMNINFO_ADAPTIVITY,
+ ODM_CMNINFO_DMSP_GET_VALUE,
+ ODM_CMNINFO_BUDDY_ADAPTOR,
+ ODM_CMNINFO_DMSP_IS_MASTER,
+ ODM_CMNINFO_SCAN,
+ ODM_CMNINFO_POWER_SAVING,
+ ODM_CMNINFO_ONE_PATH_CCA,
+ ODM_CMNINFO_DRV_STOP,
+ ODM_CMNINFO_PNP_IN,
+ ODM_CMNINFO_INIT_ON,
+ ODM_CMNINFO_ANT_TEST,
+ ODM_CMNINFO_NET_CLOSED,
+ ODM_CMNINFO_FORCED_IGI_LB,
+ ODM_CMNINFO_P2P_LINK,
+ ODM_CMNINFO_FCS_MODE,
+ ODM_CMNINFO_IS1ANTENNA,
+ ODM_CMNINFO_RFDEFAULTPATH,
+ ODM_CMNINFO_DFS_MASTER_ENABLE,
+ ODM_CMNINFO_FORCE_TX_ANT_BY_TXDESC,
+ ODM_CMNINFO_SET_S0S1_DEFAULT_ANTENNA,
+ /*--------- POINTER REFERENCE-----------*/
+
+ /*------------CALL BY VALUE-------------*/
+ ODM_CMNINFO_WIFI_DIRECT,
+ ODM_CMNINFO_WIFI_DISPLAY,
+ ODM_CMNINFO_LINK_IN_PROGRESS,
+ ODM_CMNINFO_LINK,
+ ODM_CMNINFO_STATION_STATE,
+ ODM_CMNINFO_RSSI_MIN,
+ ODM_CMNINFO_DBG_COMP,
+ ODM_CMNINFO_DBG_LEVEL,
+ ODM_CMNINFO_RA_THRESHOLD_HIGH,
+ ODM_CMNINFO_RA_THRESHOLD_LOW,
+ ODM_CMNINFO_RF_ANTENNA_TYPE,
+ ODM_CMNINFO_WITH_EXT_ANTENNA_SWITCH,
+ ODM_CMNINFO_BE_FIX_TX_ANT,
+ ODM_CMNINFO_BT_ENABLED,
+ ODM_CMNINFO_BT_HS_CONNECT_PROCESS,
+ ODM_CMNINFO_BT_HS_RSSI,
+ ODM_CMNINFO_BT_OPERATION,
+ ODM_CMNINFO_BT_LIMITED_DIG,
+ ODM_CMNINFO_BT_DIG,
+ ODM_CMNINFO_BT_BUSY,
+ ODM_CMNINFO_BT_DISABLE_EDCA,
+ ODM_CMNINFO_AP_TOTAL_NUM,
+ ODM_CMNINFO_POWER_TRAINING,
+ ODM_CMNINFO_DFS_REGION_DOMAIN,
+ /*------------CALL BY VALUE-------------*/
+
+ /*Dynamic ptr array hook itms.*/
+ ODM_CMNINFO_STA_STATUS,
+ ODM_CMNINFO_MAX,
+
+};
+
+enum phydm_info_query_e {
+ PHYDM_INFO_FA_OFDM,
+ PHYDM_INFO_FA_CCK,
+ PHYDM_INFO_FA_TOTAL,
+ PHYDM_INFO_CCA_OFDM,
+ PHYDM_INFO_CCA_CCK,
+ PHYDM_INFO_CCA_ALL,
+ PHYDM_INFO_CRC32_OK_VHT,
+ PHYDM_INFO_CRC32_OK_HT,
+ PHYDM_INFO_CRC32_OK_LEGACY,
+ PHYDM_INFO_CRC32_OK_CCK,
+ PHYDM_INFO_CRC32_ERROR_VHT,
+ PHYDM_INFO_CRC32_ERROR_HT,
+ PHYDM_INFO_CRC32_ERROR_LEGACY,
+ PHYDM_INFO_CRC32_ERROR_CCK,
+ PHYDM_INFO_EDCCA_FLAG,
+ PHYDM_INFO_OFDM_ENABLE,
+ PHYDM_INFO_CCK_ENABLE,
+ PHYDM_INFO_DBG_PORT_0
+};
+
+enum phydm_api_e {
+
+ PHYDM_API_NBI = 1,
+ PHYDM_API_CSI_MASK,
+
+};
+
+/*2011/10/20 MH Define ODM support ability. ODM_CMNINFO_ABILITY*/
+enum odm_ability_e {
+
+ /*BB ODM section BIT 0-19*/
+ ODM_BB_DIG = BIT(0),
+ ODM_BB_RA_MASK = BIT(1),
+ ODM_BB_DYNAMIC_TXPWR = BIT(2),
+ ODM_BB_FA_CNT = BIT(3),
+ ODM_BB_RSSI_MONITOR = BIT(4),
+ ODM_BB_CCK_PD = BIT(5),
+ ODM_BB_ANT_DIV = BIT(6),
+ ODM_BB_PWR_TRAIN = BIT(8),
+ ODM_BB_RATE_ADAPTIVE = BIT(9),
+ ODM_BB_PATH_DIV = BIT(10),
+ ODM_BB_ADAPTIVITY = BIT(13),
+ ODM_BB_CFO_TRACKING = BIT(14),
+ ODM_BB_NHM_CNT = BIT(15),
+ ODM_BB_PRIMARY_CCA = BIT(16),
+ ODM_BB_TXBF = BIT(17),
+ ODM_BB_DYNAMIC_ARFR = BIT(18),
+
+ ODM_MAC_EDCA_TURBO = BIT(20),
+ ODM_BB_DYNAMIC_RX_PATH = BIT(21),
+
+ /*RF ODM section BIT 24-31*/
+ ODM_RF_TX_PWR_TRACK = BIT(24),
+ ODM_RF_RX_GAIN_TRACK = BIT(25),
+ ODM_RF_CALIBRATION = BIT(26),
+
+};
+
+/*ODM_CMNINFO_ONE_PATH_CCA*/
+enum odm_cca_path_e {
+ ODM_CCA_2R = 0,
+ ODM_CCA_1R_A = 1,
+ ODM_CCA_1R_B = 2,
+};
+
+enum cca_pathdiv_en_e {
+ CCA_PATHDIV_DISABLE = 0,
+ CCA_PATHDIV_ENABLE = 1,
+
+};
+
+enum phy_reg_pg_type {
+ PHY_REG_PG_RELATIVE_VALUE = 0,
+ PHY_REG_PG_EXACT_VALUE = 1
+};
+
+/*2011/09/22 MH Copy from SD4 defined structure. We use to support PHY DM integration.*/
+
+struct PHY_DM_STRUCT {
+ /*Add for different team use temporarily*/
+ struct _ADAPTER *adapter; /*For CE/NIC team*/
+ struct rtl8192cd_priv *priv; /*For AP/ADSL team*/
+ /*WHen you use adapter or priv pointer, you must make sure the pointer is ready.*/
+ bool odm_ready;
+
+ struct rtl8192cd_priv fake_priv;
+ enum phy_reg_pg_type phy_reg_pg_value_type;
+ u8 phy_reg_pg_version;
+
+ u32 debug_components;
+ u32 fw_debug_components;
+ u32 debug_level;
+
+ u32 num_qry_phy_status_all; /*CCK + OFDM*/
+ u32 last_num_qry_phy_status_all;
+ u32 rx_pwdb_ave;
+ bool MPDIG_2G; /*off MPDIG*/
+ u8 times_2g;
+ bool is_init_hw_info_by_rfe;
+
+ /*------ ODM HANDLE, DRIVER NEEDS NOT TO HOOK------*/
+ bool is_cck_high_power;
+ u8 rf_path_rx_enable;
+ u8 control_channel;
+ /*------ ODM HANDLE, DRIVER NEEDS NOT TO HOOK------*/
+
+ /* 1 COMMON INFORMATION */
+
+ /*Init value*/
+ /*-----------HOOK BEFORE REG INIT-----------*/
+ /*ODM Platform info AP/ADSL/CE/MP = 1/2/3/4*/
+ u8 support_platform;
+ /* ODM Platform info WIN/AP/CE = 1/2/3 */
+ u8 normal_rx_path;
+ /*ODM Support Ability DIG/RATR/TX_PWR_TRACK/ �K�K = 1/2/3/�K*/
+ u32 support_ability;
+ /*ODM PCIE/USB/SDIO = 1/2/3*/
+ u8 support_interface;
+ /*ODM composite or independent. Bit oriented/ 92C+92D+ .... or any other type = 1/2/3/...*/
+ u32 support_ic_type;
+ /*cut version TestChip/A-cut/B-cut... = 0/1/2/3/...*/
+ u8 cut_version;
+ /*Fab version TSMC/UMC = 0/1*/
+ u8 fab_version;
+ /*RF type 4T4R/3T3R/2T2R/1T2R/1T1R/...*/
+ u8 rf_type;
+ u8 rfe_type;
+ /*Board type Normal/HighPower/MiniCard/SLIM/Combo/... = 0/1/2/3/4/...*/
+ u8 board_type;
+ u8 package_type;
+ u16 type_glna;
+ u16 type_gpa;
+ u16 type_alna;
+ u16 type_apa;
+ /*with external LNA NO/Yes = 0/1*/
+ u8 ext_lna; /*2G*/
+ u8 ext_lna_5g; /*5G*/
+ /*with external PA NO/Yes = 0/1*/
+ u8 ext_pa; /*2G*/
+ u8 ext_pa_5g; /*5G*/
+ /*with Efuse number*/
+ u8 efuse0x3d7;
+ u8 efuse0x3d8;
+ /*with external TRSW NO/Yes = 0/1*/
+ u8 ext_trsw;
+ u8 ext_lna_gain; /*2G*/
+ u8 patch_id; /*Customer ID*/
+ bool is_in_hct_test;
+ u8 wifi_test;
+
+ bool is_dual_mac_smart_concurrent;
+ u32 bk_support_ability;
+ u8 ant_div_type;
+ u8 with_extenal_ant_switch;
+ bool config_bbrf;
+ u8 odm_regulation_2_4g;
+ u8 odm_regulation_5g;
+ u8 iqk_fw_offload;
+ bool cck_new_agc;
+ u8 phydm_period;
+ u32 phydm_sys_up_time;
+ u8 num_rf_path;
+ u8 is_receiver_blocking_en;
+ /*-----------HOOK BEFORE REG INIT-----------*/
+
+ /*Dynamic value*/
+
+ /*--------- POINTER REFERENCE-----------*/
+
+ u8 u1_byte_temp;
+ bool BOOLEAN_temp;
+ struct _ADAPTER *PADAPTER_temp;
+
+ /*MAC PHY mode SMSP/DMSP/DMDP = 0/1/2*/
+ u8 *p_mac_phy_mode;
+ /*TX Unicast byte count*/
+ u64 *p_num_tx_bytes_unicast;
+ /*RX Unicast byte count*/
+ u64 *p_num_rx_bytes_unicast;
+ /*Wireless mode B/G/A/N = BIT0/BIT1/BIT2/BIT3*/
+ u8 *p_wireless_mode;
+ /*Frequence band 2.4G/5G = 0/1*/
+ u8 *p_band_type;
+ /*Secondary channel offset don't_care/below/above = 0/1/2*/
+ u8 *p_sec_ch_offset;
+ /*security mode Open/WEP/AES/TKIP = 0/1/2/3*/
+ u8 *p_security;
+ /*BW info 20M/40M/80M = 0/1/2*/
+ u8 *p_band_width;
+ /*Central channel location Ch1/Ch2/....*/
+ u8 *p_channel; /*central channel number*/
+ bool dpk_done;
+ /*Common info for 92D DMSP*/
+
+ bool *p_is_get_value_from_other_mac;
+ struct _ADAPTER **p_buddy_adapter;
+ bool *p_is_master_of_dmsp; /* MAC0: master, MAC1: slave */
+ /*Common info for status*/
+ bool *p_is_scan_in_process;
+ bool *p_is_power_saving;
+ /*CCA path 2-path/path-A/path-B = 0/1/2; using enum odm_cca_path_e.*/
+ u8 *p_one_path_cca;
+ u8 *p_antenna_test;
+ bool *p_is_net_closed;
+ u8 *pu1_forced_igi_lb;
+ bool *p_is_fcs_mode_enable;
+ /*--------- For 8723B IQK-----------*/
+ bool *p_is_1_antenna;
+ u8 *p_rf_default_path;
+ /* 0:S1, 1:S0 */
+
+ /*--------- POINTER REFERENCE-----------*/
+ u16 *p_forced_data_rate;
+ u8 *p_enable_antdiv;
+ u8 *p_enable_adaptivity;
+ u8 *hub_usb_mode;
+ bool *p_is_fw_dw_rsvd_page_in_progress;
+ u32 *p_current_tx_tp;
+ u32 *p_current_rx_tp;
+ u8 *p_sounding_seq;
+ /*------------CALL BY VALUE-------------*/
+ bool is_link_in_process;
+ bool is_wifi_direct;
+ bool is_wifi_display;
+ bool is_linked;
+ bool bsta_state;
+ u8 rssi_min;
+ u8 interface_index; /*Add for 92D dual MAC: 0--Mac0 1--Mac1*/
+ bool is_mp_chip;
+ bool is_one_entry_only;
+ bool mp_mode;
+ u32 one_entry_macid;
+ u8 pre_number_linked_client;
+ u8 number_linked_client;
+ u8 pre_number_active_client;
+ u8 number_active_client;
+ /*Common info for BTDM*/
+ bool is_bt_enabled; /*BT is enabled*/
+ bool is_bt_connect_process; /*BT HS is under connection progress.*/
+ u8 bt_hs_rssi; /*BT HS mode wifi rssi value.*/
+ bool is_bt_hs_operation; /*BT HS mode is under progress*/
+ u8 bt_hs_dig_val; /*use BT rssi to decide the DIG value*/
+ bool is_bt_disable_edca_turbo; /*Under some condition, don't enable the EDCA Turbo*/
+ bool is_bt_busy; /*BT is busy.*/
+ bool is_bt_limited_dig; /*BT is busy.*/
+ bool is_disable_phy_api;
+ /*------------CALL BY VALUE-------------*/
+ u8 RSSI_A;
+ u8 RSSI_B;
+ u8 RSSI_C;
+ u8 RSSI_D;
+ u64 RSSI_TRSW;
+ u64 RSSI_TRSW_H;
+ u64 RSSI_TRSW_L;
+ u64 RSSI_TRSW_iso;
+ u8 tx_ant_status;
+ u8 rx_ant_status;
+ u8 cck_lna_idx;
+ u8 cck_vga_idx;
+ u8 curr_station_id;
+ u8 ofdm_agc_idx[4];
+
+ u8 rx_rate;
+ bool is_noisy_state;
+ u8 tx_rate;
+ u8 linked_interval;
+ u8 pre_channel;
+ u32 txagc_offset_value_a;
+ bool is_txagc_offset_positive_a;
+ u32 txagc_offset_value_b;
+ bool is_txagc_offset_positive_b;
+ u32 tx_tp;
+ u32 rx_tp;
+ u32 total_tp;
+ u64 cur_tx_ok_cnt;
+ u64 cur_rx_ok_cnt;
+ u64 last_tx_ok_cnt;
+ u64 last_rx_ok_cnt;
+ u16 consecutive_idlel_time; /*unit: second*/
+ u32 bb_swing_offset_a;
+ bool is_bb_swing_offset_positive_a;
+ u32 bb_swing_offset_b;
+ bool is_bb_swing_offset_positive_b;
+ u8 igi_lower_bound;
+ u8 igi_upper_bound;
+ u8 antdiv_rssi;
+ u8 fat_comb_a;
+ u8 fat_comb_b;
+ u8 antdiv_intvl;
+ u8 ant_type;
+ u8 pre_ant_type;
+ u8 antdiv_period;
+ u8 evm_antdiv_period;
+ u8 antdiv_select;
+ u8 path_select;
+ u8 antdiv_evm_en;
+ u8 bdc_holdstate;
+ u8 ndpa_period;
+ bool h2c_rarpt_connect;
+ bool cck_agc_report_type;
+
+ u8 dm_dig_max_TH;
+ u8 dm_dig_min_TH;
+ u8 print_agc;
+ u8 traffic_load;
+ u8 pre_traffic_load;
+ /*8821C Antenna BTG/WLG/WLA Select*/
+ u8 current_rf_set_8821c;
+ u8 default_rf_set_8821c;
+ /*For Adaptivtiy*/
+ u16 nhm_cnt_0;
+ u16 nhm_cnt_1;
+ s8 TH_L2H_default;
+ s8 th_edcca_hl_diff_default;
+ s8 th_l2h_ini;
+ s8 th_edcca_hl_diff;
+ s8 th_l2h_ini_mode2;
+ s8 th_edcca_hl_diff_mode2;
+ bool carrier_sense_enable;
+ u8 adaptivity_igi_upper;
+ bool adaptivity_flag;
+ u8 dc_backoff;
+ bool adaptivity_enable;
+ u8 ap_total_num;
+ bool edcca_enable;
+ struct _ADAPTIVITY_STATISTICS adaptivity;
+ /*For Adaptivtiy*/
+ u8 last_usb_hub;
+ u8 tx_bf_data_rate;
+
+ u8 nbi_set_result;
+
+ u8 c2h_cmd_start;
+ u8 fw_debug_trace[60];
+ u8 pre_c2h_seq;
+ bool fw_buff_is_enpty;
+ u32 data_frame_num;
+
+ /*for noise detection*/
+ bool noisy_decision; /*b_noisy*/
+ bool pre_b_noisy;
+ u32 noisy_decision_smooth;
+ bool is_disable_dym_ecs;
+ struct _ODM_NOISE_MONITOR_ noise_level;
+ /*Define STA info.*/
+ /*_ODM_STA_INFO*/
+ /*2012/01/12 MH For MP, we need to reduce one array pointer for default port.??*/
+ struct sta_info *p_odm_sta_info[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 platform2phydm_macid_table[ODM_ASSOCIATE_ENTRY_NUM];
+ /* platform_macid_table[platform_macid] = phydm_macid */
+#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1)
+ s32 accumulate_pwdb[ODM_ASSOCIATE_ENTRY_NUM];
+#endif
+
+#if (RATE_ADAPTIVE_SUPPORT == 1)
+ u16 currmin_rpt_time;
+ struct _odm_ra_info_ ra_info[ODM_ASSOCIATE_ENTRY_NUM];
+ /*Use mac_id as array index. STA mac_id=0, VWiFi Client mac_id={1, ODM_ASSOCIATE_ENTRY_NUM-1} //YJ,add,120119*/
+#endif
+
+ /*2012/02/14 MH Add to share 88E ra with other SW team.*/
+ /*We need to colelct all support abilit to a proper area.*/
+
+ bool ra_support88e;
+
+ struct _odm_phy_dbg_info_ phy_dbg_info;
+
+ /*ODM Structure*/
+#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))
+
+#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1
+ struct _SMART_ANTENNA_TRAINNING_ dm_sat_table;
+#endif
+
+#endif
+ struct _FAST_ANTENNA_TRAINNING_ dm_fat_table;
+ struct _dynamic_initial_gain_threshold_ dm_dig_table;
+#if (defined(CONFIG_BB_POWER_SAVING))
+ struct _dynamic_power_saving dm_ps_table;
+#endif
+ struct _dynamic_primary_cca dm_pri_cca;
+ struct _rate_adaptive_table_ dm_ra_table;
+ struct false_ALARM_STATISTICS false_alm_cnt;
+ struct false_ALARM_STATISTICS flase_alm_cnt_buddy_adapter;
+ struct _sw_antenna_switch_ dm_swat_table;
+ struct _CFO_TRACKING_ dm_cfo_track;
+ struct _ACS_ dm_acs;
+ struct _CCX_INFO dm_ccx_info;
+#if (PHYDM_LA_MODE_SUPPORT == 1)
+ struct _RT_ADCSMP adcsmp;
+#endif
+#if (CONFIG_DYNAMIC_RX_PATH == 1)
+ struct _DYNAMIC_RX_PATH_ dm_drp_table;
+#endif
+
+#if (defined(CONFIG_PATH_DIVERSITY))
+ struct _ODM_PATH_DIVERSITY_ dm_path_div;
+#endif
+
+#if PHYDM_SUPPORT_EDCA
+ struct _EDCA_TURBO_ dm_edca_table;
+ u32 WMMEDCA_BE;
+#endif
+
+ bool *p_is_driver_stopped;
+ bool *p_is_driver_is_going_to_pnp_set_power_sleep;
+ bool *pinit_adpt_in_progress;
+
+ /*PSD*/
+ bool is_user_assign_level;
+ u8 RSSI_BT; /*come from BT*/
+ bool is_psd_in_process;
+ bool is_psd_active;
+ bool is_dm_initial_gain_enable;
+
+ /*MPT DIG*/
+ struct timer_list mpt_dig_timer;
+
+ /*for rate adaptive, in fact, 88c/92c fw will handle this*/
+ u8 is_use_ra_mask;
+
+ struct _ODM_RATE_ADAPTIVE rate_adaptive;
+#if (defined(CONFIG_ANT_DETECTION))
+ struct _ANT_DETECTED_INFO ant_detected_info; /* Antenna detected information for RSSI tool*/
+#endif
+ struct odm_rf_calibration_structure rf_calibrate_info;
+ u32 n_iqk_cnt;
+ u32 n_iqk_ok_cnt;
+ u32 n_iqk_fail_cnt;
+
+ /*Power Training*/
+ u8 force_power_training_state;
+ bool is_change_state;
+ u32 PT_score;
+ u64 ofdm_rx_cnt;
+ u64 cck_rx_cnt;
+ bool is_disable_power_training;
+ u8 dynamic_tx_high_power_lvl;
+ u8 last_dtp_lvl;
+ u32 tx_agc_ofdm_18_6;
+ u8 rx_pkt_type;
+
+ /*ODM relative time.*/
+ struct timer_list path_div_switch_timer;
+ /*2011.09.27 add for path Diversity*/
+ struct timer_list cck_path_diversity_timer;
+ struct timer_list fast_ant_training_timer;
+#ifdef ODM_EVM_ENHANCE_ANTDIV
+ struct timer_list evm_fast_ant_training_timer;
+#endif
+ struct timer_list sbdcnt_timer;
+
+ /*ODM relative workitem.*/
+#if (BEAMFORMING_SUPPORT == 1)
+ struct _RT_BEAMFORMING_INFO beamforming_info;
+#endif
+
+#ifdef CONFIG_PHYDM_DFS_MASTER
+ u8 dfs_region_domain;
+ u8 *dfs_master_enabled;
+
+ /*====== phydm_radar_detect_with_dbg_parm start ======*/
+ u8 radar_detect_dbg_parm_en;
+ u32 radar_detect_reg_918;
+ u32 radar_detect_reg_91c;
+ u32 radar_detect_reg_920;
+ u32 radar_detect_reg_924;
+ /*====== phydm_radar_detect_with_dbg_parm end ======*/
+#endif
+};
+
+enum phydm_structure_type {
+ PHYDMfalseALMCNT,
+ PHYDM_CFOTRACK,
+ PHYDM_ADAPTIVITY,
+ PHYDM_ROMINFO,
+
+};
+
+enum odm_rf_content {
+ odm_radioa_txt = 0x1000,
+ odm_radiob_txt = 0x1001,
+ odm_radioc_txt = 0x1002,
+ odm_radiod_txt = 0x1003
+};
+
+enum odm_bb_config_type {
+ CONFIG_BB_PHY_REG,
+ CONFIG_BB_AGC_TAB,
+ CONFIG_BB_AGC_TAB_2G,
+ CONFIG_BB_AGC_TAB_5G,
+ CONFIG_BB_PHY_REG_PG,
+ CONFIG_BB_PHY_REG_MP,
+ CONFIG_BB_AGC_TAB_DIFF,
+};
+
+enum odm_rf_config_type {
+ CONFIG_RF_RADIO,
+ CONFIG_RF_TXPWR_LMT,
+};
+
+enum odm_fw_config_type {
+ CONFIG_FW_NIC,
+ CONFIG_FW_NIC_2,
+ CONFIG_FW_AP,
+ CONFIG_FW_AP_2,
+ CONFIG_FW_MP,
+ CONFIG_FW_WOWLAN,
+ CONFIG_FW_WOWLAN_2,
+ CONFIG_FW_AP_WOWLAN,
+ CONFIG_FW_BT,
+};
+
+/*status code*/
+enum rt_status {
+ RT_STATUS_SUCCESS,
+ RT_STATUS_FAILURE,
+ RT_STATUS_PENDING,
+ RT_STATUS_RESOURCE,
+ RT_STATUS_INVALID_CONTEXT,
+ RT_STATUS_INVALID_PARAMETER,
+ RT_STATUS_NOT_SUPPORT,
+ RT_STATUS_OS_API_FAILED,
+};
+
+#ifdef REMOVE_PACK
+ #pragma pack()
+#endif
+
+/*===========================================================*/
+/*AGC RX High Power mode*/
+/*===========================================================*/
+#define lna_low_gain_1 0x64
+#define lna_low_gain_2 0x5A
+#define lna_low_gain_3 0x58
+
+#define FA_RXHP_TH1 5000
+#define FA_RXHP_TH2 1500
+#define FA_RXHP_TH3 800
+#define FA_RXHP_TH4 600
+#define FA_RXHP_TH5 500
+
+enum dm_1r_cca_e {
+ CCA_1R = 0,
+ CCA_2R = 1,
+ CCA_MAX = 2,
+};
+
+enum dm_rf_e {
+ rf_save = 0,
+ rf_normal = 1,
+ RF_MAX = 2,
+};
+
+/*check Sta pointer valid or not*/
+
+#define IS_STA_VALID(p_sta) (p_sta)
+
+u32 odm_convert_to_db(u32 value);
+
+u32 odm_convert_to_linear(u32 value);
+
+u32
+get_psd_data(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ unsigned int point,
+ u8 initial_gain_psd);
+
+s32
+odm_pwdb_conversion(
+ s32 X,
+ u32 total_bit,
+ u32 decimal_bit
+);
+
+s32
+odm_sign_conversion(
+ s32 value,
+ u32 total_bit
+);
+
+void
+odm_init_mp_driver_status(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+void
+phydm_txcurrentcalibration(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+void
+phydm_seq_sorting(
+ void *p_dm_void,
+ u32 *p_value,
+ u32 *rank_idx,
+ u32 *p_idx_out,
+ u8 seq_length
+);
+
+void
+odm_dm_init(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+void
+odm_dm_reset(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+void
+phydm_support_ability_debug(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+);
+
+void
+phydm_config_ofdm_rx_path(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 path
+);
+
+void
+phydm_config_trx_path(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+);
+
+void
+odm_dm_watchdog(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+void
+phydm_watchdog_mp(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+void
+odm_cmn_info_init(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_cmninfo_e cmn_info,
+ u32 value
+);
+
+void
+odm_cmn_info_hook(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_cmninfo_e cmn_info,
+ void *p_value
+);
+
+void
+odm_cmn_info_ptr_array_hook(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_cmninfo_e cmn_info,
+ u16 index,
+ void *p_value
+);
+
+void
+odm_cmn_info_update(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 cmn_info,
+ u64 value
+);
+
+u32
+phydm_cmn_info_query(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum phydm_info_query_e info_type
+);
+
+void
+odm_init_all_timers(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+void
+odm_cancel_all_timers(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+void
+odm_release_all_timers(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+void
+odm_asoc_entry_init(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+void *
+phydm_get_structure(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 structure_type
+);
+
+ /*===========================================================*/
+ /* The following is for compile only*/
+ /*===========================================================*/
+
+ #define IS_HARDWARE_TYPE_8723A(_adapter) false
+ #define IS_HARDWARE_TYPE_8723AE(_adapter) false
+ #define IS_HARDWARE_TYPE_8192C(_adapter) false
+ #define IS_HARDWARE_TYPE_8192D(_adapter) false
+ #define RF_T_METER_92D 0x42
+
+ #define GET_RX_STATUS_DESC_RX_MCS(__prx_status_desc) LE_BITS_TO_1BYTE(__prx_status_desc+12, 0, 6)
+
+ #define REG_CONFIG_RAM64X16 0xb2c
+
+ #define TARGET_CHNL_NUM_2G_5G 59
+
+ /* *********************************************************** */
+
+ void odm_dtc(struct PHY_DM_STRUCT *p_dm_odm);
+
+void phydm_noisy_detection(struct PHY_DM_STRUCT *p_dm_odm);
+
+#endif
+
+void
+phydm_set_ext_switch(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+);
+
+void
+phydm_api_debug(
+ void *p_dm_void,
+ u32 function_map,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+);
+
+u8
+phydm_nbi_setting(
+ void *p_dm_void,
+ u32 enable,
+ u32 channel,
+ u32 bw,
+ u32 f_interference,
+ u32 second_ch
+);
+
+void
+phydm_receiver_blocking(
+ void *p_dm_void
+);
diff --git a/drivers/staging/rtl8188eu/hal/phydm_acs.c b/drivers/staging/rtl8188eu/hal/phydm_acs.c
new file mode 100644
index 000000000000..b3ae46f5cd95
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_acs.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+
+u8
+odm_get_auto_channel_select_result(
+ void *p_dm_void,
+ u8 band
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ACS_ *p_acs = &p_dm_odm->dm_acs;
+
+ if (band == ODM_BAND_2_4G) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("[struct _ACS_] odm_get_auto_channel_select_result(): clean_channel_2g(%d)\n", p_acs->clean_channel_2g));
+ return (u8)p_acs->clean_channel_2g;
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("[struct _ACS_] odm_get_auto_channel_select_result(): clean_channel_5g(%d)\n", p_acs->clean_channel_5g));
+ return (u8)p_acs->clean_channel_5g;
+ }
+}
+
+static void
+odm_auto_channel_select_setting(
+ void *p_dm_void,
+ bool is_enable
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u16 period = 0x2710;/* 40ms in default */
+ u16 nhm_type = 0x7;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_auto_channel_select_setting()=========>\n"));
+
+ if (is_enable) {
+ /* 20 ms */
+ period = 0x1388;
+ nhm_type = 0x1;
+ }
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+ /* PHY parameters initialize for ac series */
+ odm_write_2byte(p_dm_odm, ODM_REG_CCX_PERIOD_11AC + 2, period); /* 0x990[31:16]=0x2710 Time duration for NHM unit: 4us, 0x2710=40ms */
+ /* odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(8)|BIT9|BIT10, nhm_type); */ /* 0x994[9:8]=3 enable CCX */
+ } else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+ /* PHY parameters initialize for n series */
+ odm_write_2byte(p_dm_odm, ODM_REG_CCX_PERIOD_11N + 2, period); /* 0x894[31:16]=0x2710 Time duration for NHM unit: 4us, 0x2710=40ms */
+ /* odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(10)|BIT9|BIT8, nhm_type); */ /* 0x890[9:8]=3 enable CCX */
+ }
+}
+
+void
+odm_auto_channel_select_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ACS_ *p_acs = &p_dm_odm->dm_acs;
+ u8 i;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_NHM_CNT))
+ return;
+
+ if (p_acs->is_force_acs_result)
+ return;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_auto_channel_select_init()=========>\n"));
+
+ p_acs->clean_channel_2g = 1;
+ p_acs->clean_channel_5g = 36;
+
+ for (i = 0; i < ODM_MAX_CHANNEL_2G; ++i) {
+ p_acs->channel_info_2g[0][i] = 0;
+ p_acs->channel_info_2g[1][i] = 0;
+ }
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+ for (i = 0; i < ODM_MAX_CHANNEL_5G; ++i) {
+ p_acs->channel_info_5g[0][i] = 0;
+ p_acs->channel_info_5g[1][i] = 0;
+ }
+ }
+}
+
+void
+odm_auto_channel_select_reset(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ACS_ *p_acs = &p_dm_odm->dm_acs;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_NHM_CNT))
+ return;
+
+ if (p_acs->is_force_acs_result)
+ return;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_auto_channel_select_reset()=========>\n"));
+
+ odm_auto_channel_select_setting(p_dm_odm, true); /* for 20ms measurement */
+ phydm_nhm_counter_statistics_reset(p_dm_odm);
+}
+
+void
+odm_auto_channel_select(
+ void *p_dm_void,
+ u8 channel
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ACS_ *p_acs = &p_dm_odm->dm_acs;
+ u8 channel_idx = 0, search_idx = 0;
+ u16 max_score = 0;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_NHM_CNT)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_auto_channel_select(): Return: support_ability ODM_BB_NHM_CNT is disabled\n"));
+ return;
+ }
+
+ if (p_acs->is_force_acs_result) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_auto_channel_select(): Force 2G clean channel = %d, 5G clean channel = %d\n",
+ p_acs->clean_channel_2g, p_acs->clean_channel_5g));
+ return;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_auto_channel_select(): channel = %d=========>\n", channel));
+
+ phydm_get_nhm_counter_statistics(p_dm_odm);
+ odm_auto_channel_select_setting(p_dm_odm, false);
+
+ if (channel >= 1 && channel <= 14) {
+ channel_idx = channel - 1;
+ p_acs->channel_info_2g[1][channel_idx]++;
+
+ if (p_acs->channel_info_2g[1][channel_idx] >= 2)
+ p_acs->channel_info_2g[0][channel_idx] = (p_acs->channel_info_2g[0][channel_idx] >> 1) +
+ (p_acs->channel_info_2g[0][channel_idx] >> 2) + (p_dm_odm->nhm_cnt_0 >> 2);
+ else
+ p_acs->channel_info_2g[0][channel_idx] = p_dm_odm->nhm_cnt_0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_auto_channel_select(): nhm_cnt_0 = %d\n", p_dm_odm->nhm_cnt_0));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_auto_channel_select(): Channel_Info[0][%d] = %d, Channel_Info[1][%d] = %d\n", channel_idx, p_acs->channel_info_2g[0][channel_idx], channel_idx, p_acs->channel_info_2g[1][channel_idx]));
+
+ for (search_idx = 0; search_idx < ODM_MAX_CHANNEL_2G; search_idx++) {
+ if (p_acs->channel_info_2g[1][search_idx] != 0) {
+ if (p_acs->channel_info_2g[0][search_idx] >= max_score) {
+ max_score = p_acs->channel_info_2g[0][search_idx];
+ p_acs->clean_channel_2g = search_idx + 1;
+ }
+ }
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("(1)odm_auto_channel_select(): 2G: clean_channel_2g = %d, max_score = %d\n",
+ p_acs->clean_channel_2g, max_score));
+
+ } else if (channel >= 36) {
+ /* Need to do */
+ p_acs->clean_channel_5g = channel;
+ }
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_acs.h b/drivers/staging/rtl8188eu/hal/phydm_acs.h
new file mode 100644
index 000000000000..29f0f792975b
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_acs.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMACS_H__
+#define __PHYDMACS_H__
+
+#define ACS_VERSION "1.1" /*20150729 by YuChen*/
+#define CLM_VERSION "1.0"
+
+#define ODM_MAX_CHANNEL_2G 14
+#define ODM_MAX_CHANNEL_5G 24
+
+/* For phydm_auto_channel_select_setting_ap() */
+#define STORE_DEFAULT_NHM_SETTING 0
+#define RESTORE_DEFAULT_NHM_SETTING 1
+#define ACS_NHM_SETTING 2
+
+struct _ACS_ {
+ bool is_force_acs_result;
+ u8 clean_channel_2g;
+ u8 clean_channel_5g;
+ u16 channel_info_2g[2][ODM_MAX_CHANNEL_2G]; /* Channel_Info[1]: channel score, Channel_Info[2]:Channel_Scan_Times */
+ u16 channel_info_5g[2][ODM_MAX_CHANNEL_5G];
+};
+
+
+void
+odm_auto_channel_select_init(
+ void *p_dm_void
+);
+
+void
+odm_auto_channel_select_reset(
+ void *p_dm_void
+);
+
+void
+odm_auto_channel_select(
+ void *p_dm_void,
+ u8 channel
+);
+
+u8
+odm_get_auto_channel_select_result(
+ void *p_dm_void,
+ u8 band
+);
+
+#endif /* #ifndef __PHYDMACS_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/phydm_adaptivity.c b/drivers/staging/rtl8188eu/hal/phydm_adaptivity.c
new file mode 100644
index 000000000000..adfab691ca1b
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_adaptivity.c
@@ -0,0 +1,823 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+void
+phydm_check_adaptivity(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTIVITY_STATISTICS *adaptivity = (struct _ADAPTIVITY_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_ADAPTIVITY);
+
+ if (p_dm_odm->support_ability & ODM_BB_ADAPTIVITY) {
+ {
+ if (adaptivity->dynamic_link_adaptivity || adaptivity->acs_for_adaptivity) {
+ if (p_dm_odm->is_linked && adaptivity->is_check == false) {
+ phydm_nhm_counter_statistics(p_dm_odm);
+ phydm_check_environment(p_dm_odm);
+ } else if (!p_dm_odm->is_linked)
+ adaptivity->is_check = false;
+ } else {
+ p_dm_odm->adaptivity_enable = true;
+
+ if (p_dm_odm->support_ic_type & (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA))
+ p_dm_odm->adaptivity_flag = false;
+ else
+ p_dm_odm->adaptivity_flag = true;
+ }
+ }
+ } else {
+ p_dm_odm->adaptivity_enable = false;
+ p_dm_odm->adaptivity_flag = false;
+ }
+}
+
+void
+phydm_nhm_counter_statistics_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+ /*PHY parameters initialize for n series*/
+ odm_write_2byte(p_dm_odm, ODM_REG_CCX_PERIOD_11N + 2, 0xC350); /*0x894[31:16]=0x0xC350 Time duration for NHM unit: us, 0xc350=200ms*/
+ odm_write_2byte(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N + 2, 0xffff); /*0x890[31:16]=0xffff th_9, th_10*/
+ odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff50); /*0x898=0xffffff52 th_3, th_2, th_1, th_0*/
+ odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffffff); /*0x89c=0xffffffff th_7, th_6, th_5, th_4*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_FPGA0_IQK_11N, MASKBYTE0, 0xff); /*0xe28[7:0]=0xff th_8*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(10) | BIT9 | BIT8, 0x1); /*0x890[10:8]=1 ignoreCCA ignore PHYTXON enable CCX*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RSTC_11N, BIT(7), 0x1); /*0xc0c[7]=1 max power among all RX ants*/
+ }
+ else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+ /*PHY parameters initialize for ac series*/
+ odm_write_2byte(p_dm_odm, ODM_REG_CCX_PERIOD_11AC + 2, 0xC350); /*0x990[31:16]=0xC350 Time duration for NHM unit: us, 0xc350=200ms*/
+ odm_write_2byte(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC + 2, 0xffff); /*0x994[31:16]=0xffff th_9, th_10*/
+ odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0xffffff50); /*0x998=0xffffff52 th_3, th_2, th_1, th_0*/
+ odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffffff); /*0x99c=0xffffffff th_7, th_6, th_5, th_4*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH8_11AC, MASKBYTE0, 0xff); /*0x9a0[7:0]=0xff th_8*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(8) | BIT9 | BIT10, 0x1); /*0x994[10:8]=1 ignoreCCA ignore PHYTXON enable CCX*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_9E8_11AC, BIT(0), 0x1); /*0x9e8[7]=1 max power among all RX ants*/
+
+ }
+}
+
+void
+phydm_nhm_counter_statistics(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_NHM_CNT))
+ return;
+
+ /*Get NHM report*/
+ phydm_get_nhm_counter_statistics(p_dm_odm);
+
+ /*Reset NHM counter*/
+ phydm_nhm_counter_statistics_reset(p_dm_odm);
+}
+
+void
+phydm_get_nhm_counter_statistics(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 value32 = 0;
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_CNT_11AC, MASKDWORD);
+ else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_CNT_11N, MASKDWORD);
+
+ p_dm_odm->nhm_cnt_0 = (u8)(value32 & MASKBYTE0);
+ p_dm_odm->nhm_cnt_1 = (u8)((value32 & MASKBYTE1) >> 8);
+
+}
+
+void
+phydm_nhm_counter_statistics_reset(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 0);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 1);
+ } else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 0);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 1);
+ }
+}
+
+void
+phydm_set_edcca_threshold(
+ void *p_dm_void,
+ s8 H2L,
+ s8 L2H
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_ECCA_THRESHOLD, MASKBYTE2 | MASKBYTE0, (u32)((u8)L2H | (u8)H2L << 16));
+ else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XB_LSSI_READ_BACK, MASKLWORD, (u16)((u8)L2H | (u8)H2L << 8));
+}
+
+static void
+phydm_set_lna(
+ void *p_dm_void,
+ enum phydm_set_lna type
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8188E | ODM_RTL8192E)) {
+ if (type == phydm_disable_lna) {
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x0000f);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0x37f82); /*disable LNA*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ if (p_dm_odm->rf_type > ODM_1T1R) {
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x30, 0xfffff, 0x18000);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x31, 0xfffff, 0x0000f);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x32, 0xfffff, 0x37f82);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x0);
+ }
+ } else if (type == phydm_enable_lna) {
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x0000f);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0x77f82); /*back to normal*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ if (p_dm_odm->rf_type > ODM_1T1R) {
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x30, 0xfffff, 0x18000);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x31, 0xfffff, 0x0000f);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x32, 0xfffff, 0x77f82);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x0);
+ }
+ }
+ } else if (p_dm_odm->support_ic_type & ODM_RTL8723B) {
+ if (type == phydm_disable_lna) {
+ /*S0*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x0001f);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xe6137); /*disable LNA*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ /*S1*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xed, 0x00020, 0x1);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x43, 0xfffff, 0x3008d); /*select Rx mode and disable LNA*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xed, 0x00020, 0x0);
+ } else if (type == phydm_enable_lna) {
+ /*S0*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x0001f);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xe6177); /*disable LNA*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ /*S1*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xed, 0x00020, 0x1);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x43, 0xfffff, 0x300bd); /*select Rx mode and disable LNA*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xed, 0x00020, 0x0);
+ }
+
+ } else if (p_dm_odm->support_ic_type & ODM_RTL8812) {
+ if (type == phydm_disable_lna) {
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x3f7ff);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xc22bf); /*disable LNA*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ if (p_dm_odm->rf_type > ODM_1T1R) {
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x30, 0xfffff, 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x31, 0xfffff, 0x3f7ff);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x32, 0xfffff, 0xc22bf); /*disable LNA*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x0);
+ }
+ } else if (type == phydm_enable_lna) {
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x3f7ff);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xc26bf); /*disable LNA*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ if (p_dm_odm->rf_type > ODM_1T1R) {
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x30, 0xfffff, 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x31, 0xfffff, 0x3f7ff);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x32, 0xfffff, 0xc26bf); /*disable LNA*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x0);
+ }
+ }
+ } else if (p_dm_odm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
+ if (type == phydm_disable_lna) {
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x0002f);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xfb09b); /*disable LNA*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ } else if (type == phydm_enable_lna) {
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x0002f);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xfb0bb); /*disable LNA*/
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
+ }
+ }
+}
+
+
+
+void
+phydm_set_trx_mux(
+ void *p_dm_void,
+ enum phydm_trx_mux_type tx_mode,
+ enum phydm_trx_mux_type rx_mode
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_RPT_FORMAT_11N, BIT(3) | BIT2 | BIT1, tx_mode); /*set TXmod to standby mode to remove outside noise affect*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_RPT_FORMAT_11N, BIT(22) | BIT21 | BIT20, rx_mode); /*set RXmod to standby mode to remove outside noise affect*/
+ if (p_dm_odm->rf_type > ODM_1T1R) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_RPT_FORMAT_11N_B, BIT(3) | BIT2 | BIT1, tx_mode); /*set TXmod to standby mode to remove outside noise affect*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_RPT_FORMAT_11N_B, BIT(22) | BIT21 | BIT20, rx_mode); /*set RXmod to standby mode to remove outside noise affect*/
+ }
+ } else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_TRMUX_11AC, BIT(11) | BIT10 | BIT9 | BIT8, tx_mode); /*set TXmod to standby mode to remove outside noise affect*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_TRMUX_11AC, BIT(7) | BIT6 | BIT5 | BIT4, rx_mode); /*set RXmod to standby mode to remove outside noise affect*/
+ if (p_dm_odm->rf_type > ODM_1T1R) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_TRMUX_11AC_B, BIT(11) | BIT10 | BIT9 | BIT8, tx_mode); /*set TXmod to standby mode to remove outside noise affect*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_TRMUX_11AC_B, BIT(7) | BIT6 | BIT5 | BIT4, rx_mode); /*set RXmod to standby mode to remove outside noise affect*/
+ }
+ }
+}
+
+void
+phydm_mac_edcca_state(
+ void *p_dm_void,
+ enum phydm_mac_edcca_type state
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ if (state == phydm_ignore_edcca) {
+ odm_set_mac_reg(p_dm_odm, REG_TX_PTCL_CTRL, BIT(15), 1); /*ignore EDCCA reg520[15]=1*/
+ /* odm_set_mac_reg(p_dm_odm, REG_RD_CTRL, BIT(11), 0); */ /*reg524[11]=0*/
+ } else { /*don't set MAC ignore EDCCA signal*/
+ odm_set_mac_reg(p_dm_odm, REG_TX_PTCL_CTRL, BIT(15), 0); /*don't ignore EDCCA reg520[15]=0*/
+ /* odm_set_mac_reg(p_dm_odm, REG_RD_CTRL, BIT(11), 1); */ /*reg524[11]=1 */
+ }
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("EDCCA enable state = %d\n", state));
+
+}
+
+bool
+phydm_cal_nhm_cnt(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u16 base = 0;
+
+ base = p_dm_odm->nhm_cnt_0 + p_dm_odm->nhm_cnt_1;
+
+ if (base != 0) {
+ p_dm_odm->nhm_cnt_0 = ((p_dm_odm->nhm_cnt_0) << 8) / base;
+ p_dm_odm->nhm_cnt_1 = ((p_dm_odm->nhm_cnt_1) << 8) / base;
+ }
+ if ((p_dm_odm->nhm_cnt_0 - p_dm_odm->nhm_cnt_1) >= 100)
+ return true; /*clean environment*/
+ else
+ return false; /*noisy environment*/
+
+}
+
+
+void
+phydm_check_environment(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTIVITY_STATISTICS *adaptivity = (struct _ADAPTIVITY_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_ADAPTIVITY);
+ bool is_clean_environment = false;
+
+ if (adaptivity->is_first_link == true) {
+ if (p_dm_odm->support_ic_type & (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA))
+ p_dm_odm->adaptivity_flag = false;
+ else
+ p_dm_odm->adaptivity_flag = true;
+
+ adaptivity->is_first_link = false;
+ return;
+ } else {
+ if (adaptivity->nhm_wait < 3) { /*Start enter NHM after 4 nhm_wait*/
+ adaptivity->nhm_wait++;
+ phydm_nhm_counter_statistics(p_dm_odm);
+ return;
+ } else {
+ phydm_nhm_counter_statistics(p_dm_odm);
+ is_clean_environment = phydm_cal_nhm_cnt(p_dm_odm);
+ if (is_clean_environment == true) {
+ p_dm_odm->th_l2h_ini = adaptivity->th_l2h_ini_backup; /*adaptivity mode*/
+ p_dm_odm->th_edcca_hl_diff = adaptivity->th_edcca_hl_diff_backup;
+
+ p_dm_odm->adaptivity_enable = true;
+
+ if (p_dm_odm->support_ic_type & (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA))
+ p_dm_odm->adaptivity_flag = false;
+ else
+ p_dm_odm->adaptivity_flag = true;
+ } else {
+ if (!adaptivity->acs_for_adaptivity) {
+ p_dm_odm->th_l2h_ini = p_dm_odm->th_l2h_ini_mode2; /*mode2*/
+ p_dm_odm->th_edcca_hl_diff = p_dm_odm->th_edcca_hl_diff_mode2;
+
+ p_dm_odm->adaptivity_flag = false;
+ p_dm_odm->adaptivity_enable = false;
+ }
+ }
+ adaptivity->nhm_wait = 0;
+ adaptivity->is_first_link = true;
+ adaptivity->is_check = true;
+ }
+
+ }
+
+
+}
+
+void
+phydm_search_pwdb_lower_bound(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTIVITY_STATISTICS *adaptivity = (struct _ADAPTIVITY_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_ADAPTIVITY);
+ u32 value32 = 0, reg_value32 = 0;
+ u8 cnt, try_count = 0;
+ u8 tx_edcca1 = 0, tx_edcca0 = 0;
+ bool is_adjust = true;
+ s8 th_l2h_dmc, th_h2l_dmc, igi_target = 0x32;
+ s8 diff;
+ u8 IGI = adaptivity->igi_base + 30 + (u8)p_dm_odm->th_l2h_ini - (u8)p_dm_odm->th_edcca_hl_diff;
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8723B | ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A))
+ phydm_set_lna(p_dm_odm, phydm_disable_lna);
+ else {
+ phydm_set_trx_mux(p_dm_odm, phydm_standby_mode, phydm_standby_mode);
+ odm_pause_dig(p_dm_odm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_0, 0x7e);
+ }
+
+ diff = igi_target - (s8)IGI;
+ th_l2h_dmc = p_dm_odm->th_l2h_ini + diff;
+ if (th_l2h_dmc > 10)
+ th_l2h_dmc = 10;
+ th_h2l_dmc = th_l2h_dmc - p_dm_odm->th_edcca_hl_diff;
+
+ phydm_set_edcca_threshold(p_dm_odm, th_h2l_dmc, th_l2h_dmc);
+ ODM_delay_ms(30);
+
+ while (is_adjust) {
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x0);
+ reg_value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11N, MASKDWORD);
+ } else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x0);
+ reg_value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ }
+ while (reg_value32 & BIT(3) && try_count < 3) {
+ try_count = try_count + 1;
+ ODM_delay_ms(3);
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
+ reg_value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11N, MASKDWORD);
+ else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
+ reg_value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ }
+ try_count = 0;
+
+ for (cnt = 0; cnt < 20; cnt++) {
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x208);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11N, MASKDWORD);
+ } else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x209);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ }
+ if (value32 & BIT(30) && (p_dm_odm->support_ic_type & (ODM_RTL8723B | ODM_RTL8188E)))
+ tx_edcca1 = tx_edcca1 + 1;
+ else if (value32 & BIT(29))
+ tx_edcca1 = tx_edcca1 + 1;
+ else
+ tx_edcca0 = tx_edcca0 + 1;
+ }
+
+ if (tx_edcca1 > 1) {
+ IGI = IGI - 1;
+ th_l2h_dmc = th_l2h_dmc + 1;
+ if (th_l2h_dmc > 10)
+ th_l2h_dmc = 10;
+ th_h2l_dmc = th_l2h_dmc - p_dm_odm->th_edcca_hl_diff;
+
+ phydm_set_edcca_threshold(p_dm_odm, th_h2l_dmc, th_l2h_dmc);
+ if (th_l2h_dmc == 10) {
+ is_adjust = false;
+ adaptivity->h2l_lb = th_h2l_dmc;
+ adaptivity->l2h_lb = th_l2h_dmc;
+ p_dm_odm->adaptivity_igi_upper = IGI;
+ }
+
+ tx_edcca1 = 0;
+ tx_edcca0 = 0;
+
+ } else {
+ is_adjust = false;
+ adaptivity->h2l_lb = th_h2l_dmc;
+ adaptivity->l2h_lb = th_l2h_dmc;
+ p_dm_odm->adaptivity_igi_upper = IGI;
+ tx_edcca1 = 0;
+ tx_edcca0 = 0;
+ }
+ }
+
+ p_dm_odm->adaptivity_igi_upper = p_dm_odm->adaptivity_igi_upper - p_dm_odm->dc_backoff;
+ adaptivity->h2l_lb = adaptivity->h2l_lb + p_dm_odm->dc_backoff;
+ adaptivity->l2h_lb = adaptivity->l2h_lb + p_dm_odm->dc_backoff;
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8723B | ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A))
+ phydm_set_lna(p_dm_odm, phydm_enable_lna);
+ else {
+ phydm_set_trx_mux(p_dm_odm, phydm_tx_mode, phydm_rx_mode);
+ odm_pause_dig(p_dm_odm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_0, NONE);
+ }
+
+ phydm_set_edcca_threshold(p_dm_odm, 0x7f, 0x7f); /*resume to no link state*/
+}
+
+static bool
+phydm_re_search_condition(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ /*struct _ADAPTIVITY_STATISTICS* adaptivity = (struct _ADAPTIVITY_STATISTICS*)phydm_get_structure(p_dm_odm, PHYDM_ADAPTIVITY);*/
+ u8 adaptivity_igi_upper;
+ u8 count = 0;
+ /*s8 TH_L2H_dmc, IGI_target = 0x32;*/
+ /*s8 diff;*/
+
+ adaptivity_igi_upper = p_dm_odm->adaptivity_igi_upper + p_dm_odm->dc_backoff;
+
+ /*TH_L2H_dmc = 10;*/
+
+ /*diff = TH_L2H_dmc - p_dm_odm->TH_L2H_ini;*/
+ /*lowest_IGI_upper = IGI_target - diff;*/
+
+ /*if ((adaptivity_igi_upper - lowest_IGI_upper) <= 5)*/
+ if (adaptivity_igi_upper <= 0x26 && count < 3) {
+ count = count + 1;
+ return true;
+ }
+ else
+ return false;
+
+}
+
+void
+phydm_adaptivity_info_init(
+ void *p_dm_void,
+ enum phydm_adapinfo_e cmn_info,
+ u32 value
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTIVITY_STATISTICS *adaptivity = (struct _ADAPTIVITY_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_ADAPTIVITY);
+
+ switch (cmn_info) {
+ case PHYDM_ADAPINFO_CARRIER_SENSE_ENABLE:
+ p_dm_odm->carrier_sense_enable = (bool)value;
+ break;
+
+ case PHYDM_ADAPINFO_DCBACKOFF:
+ p_dm_odm->dc_backoff = (u8)value;
+ break;
+
+ case PHYDM_ADAPINFO_DYNAMICLINKADAPTIVITY:
+ adaptivity->dynamic_link_adaptivity = (bool)value;
+ break;
+
+ case PHYDM_ADAPINFO_TH_L2H_INI:
+ p_dm_odm->th_l2h_ini = (s8)value;
+ break;
+
+ case PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF:
+ p_dm_odm->th_edcca_hl_diff = (s8)value;
+ break;
+
+ case PHYDM_ADAPINFO_AP_NUM_TH:
+ adaptivity->ap_num_th = (u8)value;
+ break;
+
+ default:
+ break;
+
+ }
+
+}
+
+
+
+void
+phydm_adaptivity_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTIVITY_STATISTICS *adaptivity = (struct _ADAPTIVITY_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_ADAPTIVITY);
+ s8 igi_target = 0x32;
+
+ if (p_dm_odm->carrier_sense_enable == false) {
+ if (p_dm_odm->th_l2h_ini == 0)
+ p_dm_odm->th_l2h_ini = 0xf5;
+ } else
+ p_dm_odm->th_l2h_ini = 0xa;
+
+ if (p_dm_odm->th_edcca_hl_diff == 0)
+ p_dm_odm->th_edcca_hl_diff = 7;
+ if (p_dm_odm->wifi_test == true || p_dm_odm->mp_mode == true)
+ p_dm_odm->edcca_enable = false; /*even no adaptivity, we still enable EDCCA, AP side use mib control*/
+ else
+ p_dm_odm->edcca_enable = true;
+
+ p_dm_odm->adaptivity_igi_upper = 0;
+ p_dm_odm->adaptivity_enable = false; /*use this flag to decide enable or disable*/
+
+ p_dm_odm->th_l2h_ini_mode2 = 20;
+ p_dm_odm->th_edcca_hl_diff_mode2 = 8;
+ adaptivity->th_l2h_ini_backup = p_dm_odm->th_l2h_ini;
+ adaptivity->th_edcca_hl_diff_backup = p_dm_odm->th_edcca_hl_diff;
+
+ adaptivity->igi_base = 0x32;
+ adaptivity->igi_target = 0x1c;
+ adaptivity->h2l_lb = 0;
+ adaptivity->l2h_lb = 0;
+ adaptivity->nhm_wait = 0;
+ adaptivity->is_check = false;
+ adaptivity->is_first_link = true;
+ adaptivity->adajust_igi_level = 0;
+ adaptivity->is_stop_edcca = false;
+ adaptivity->backup_h2l = 0;
+ adaptivity->backup_l2h = 0;
+
+ phydm_mac_edcca_state(p_dm_odm, phydm_dont_ignore_edcca);
+
+ /*Search pwdB lower bound*/
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x208);
+ else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x209);
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_GAIN_IDX_EDCCA) {
+ /*odm_set_bb_reg(p_dm_odm, ODM_REG_EDCCA_DOWN_OPT_11N, BIT(12) | BIT11 | BIT10, 0x7);*/ /*interfernce need > 2^x us, and then EDCCA will be 1*/
+ if (p_dm_odm->support_ic_type & ODM_RTL8197F) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_PAGE_B1_97F, BIT(30), 0x1); /*set to page B1*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_EDCCA_DCNF_97F, BIT(27) | BIT26, 0x1); /*0:rx_dfir, 1: dcnf_out, 2 :rx_iq, 3: rx_nbi_nf_out*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_PAGE_B1_97F, BIT(30), 0x0);
+ } else
+ odm_set_bb_reg(p_dm_odm, ODM_REG_EDCCA_DCNF_11N, BIT(21) | BIT20, 0x1); /*0:rx_dfir, 1: dcnf_out, 2 :rx_iq, 3: rx_nbi_nf_out*/
+ }
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_GAIN_IDX_EDCCA) { /*8814a no need to find pwdB lower bound, maybe*/
+ /*odm_set_bb_reg(p_dm_odm, ODM_REG_EDCCA_DOWN_OPT, BIT(30) | BIT29 | BIT28, 0x7);*/ /*interfernce need > 2^x us, and then EDCCA will be 1*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_ACBB_EDCCA_ENHANCE, BIT(29) | BIT28, 0x1); /*0:rx_dfir, 1: dcnf_out, 2 :rx_iq, 3: rx_nbi_nf_out*/
+ }
+
+ if (!(p_dm_odm->support_ic_type & (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA))) {
+ phydm_search_pwdb_lower_bound(p_dm_odm);
+ if (phydm_re_search_condition(p_dm_odm))
+ phydm_search_pwdb_lower_bound(p_dm_odm);
+ }
+
+ /*we need to consider PwdB upper bound for 8814 later IC*/
+ adaptivity->adajust_igi_level = (u8)((p_dm_odm->th_l2h_ini + igi_target) - pwdb_upper_bound + dfir_loss); /*IGI = L2H - PwdB - dfir_loss*/
+
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("th_l2h_ini = 0x%x, th_edcca_hl_diff = 0x%x, adaptivity->adajust_igi_level = 0x%x\n", p_dm_odm->th_l2h_ini, p_dm_odm->th_edcca_hl_diff, adaptivity->adajust_igi_level));
+
+ /*Check this later on Windows*/
+ /*phydm_set_edcca_threshold_api(p_dm_odm, p_dm_dig_table->cur_ig_value);*/
+
+}
+
+
+void
+phydm_adaptivity(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+ u8 IGI = p_dm_dig_table->cur_ig_value;
+ s8 th_l2h_dmc, th_h2l_dmc;
+ s8 diff = 0, igi_target;
+ struct _ADAPTIVITY_STATISTICS *adaptivity = (struct _ADAPTIVITY_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_ADAPTIVITY);
+
+ if ((p_dm_odm->edcca_enable == false) || (adaptivity->is_stop_edcca == true)) {
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("Disable EDCCA!!!\n"));
+ return;
+ }
+
+ if (!(p_dm_odm->support_ability & ODM_BB_ADAPTIVITY)) {
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("adaptivity disable, enable EDCCA mode!!!\n"));
+ p_dm_odm->th_l2h_ini = p_dm_odm->th_l2h_ini_mode2;
+ p_dm_odm->th_edcca_hl_diff = p_dm_odm->th_edcca_hl_diff_mode2;
+ }
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("odm_Adaptivity() =====>\n"));
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("igi_base=0x%x, th_l2h_ini = %d, th_edcca_hl_diff = %d\n",
+ adaptivity->igi_base, p_dm_odm->th_l2h_ini, p_dm_odm->th_edcca_hl_diff));
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+ /*fix AC series when enable EDCCA hang issue*/
+ odm_set_bb_reg(p_dm_odm, 0x800, BIT(10), 1); /*ADC_mask disable*/
+ odm_set_bb_reg(p_dm_odm, 0x800, BIT(10), 0); /*ADC_mask enable*/
+ }
+ if (*p_dm_odm->p_band_width == ODM_BW20M) /*CHANNEL_WIDTH_20*/
+ igi_target = adaptivity->igi_base;
+ else if (*p_dm_odm->p_band_width == ODM_BW40M)
+ igi_target = adaptivity->igi_base + 2;
+ else if (*p_dm_odm->p_band_width == ODM_BW80M)
+ igi_target = adaptivity->igi_base + 2;
+ else
+ igi_target = adaptivity->igi_base;
+ adaptivity->igi_target = (u8) igi_target;
+
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("band_width=%s, igi_target=0x%x, dynamic_link_adaptivity = %d, acs_for_adaptivity = %d\n",
+ (*p_dm_odm->p_band_width == ODM_BW80M) ? "80M" : ((*p_dm_odm->p_band_width == ODM_BW40M) ? "40M" : "20M"), igi_target, adaptivity->dynamic_link_adaptivity, adaptivity->acs_for_adaptivity));
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("RSSI_min = %d, adaptivity->adajust_igi_level= 0x%x, adaptivity_flag = %d, adaptivity_enable = %d\n",
+ p_dm_odm->rssi_min, adaptivity->adajust_igi_level, p_dm_odm->adaptivity_flag, p_dm_odm->adaptivity_enable));
+
+ if ((adaptivity->dynamic_link_adaptivity == true) && (!p_dm_odm->is_linked) && (p_dm_odm->adaptivity_enable == false)) {
+ phydm_set_edcca_threshold(p_dm_odm, 0x7f, 0x7f);
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("In DynamicLink mode(noisy) and No link, Turn off EDCCA!!\n"));
+ return;
+ }
+
+ if (p_dm_odm->support_ic_type & (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) {
+ if ((adaptivity->adajust_igi_level > IGI) && (p_dm_odm->adaptivity_enable == true))
+ diff = adaptivity->adajust_igi_level - IGI;
+
+ th_l2h_dmc = p_dm_odm->th_l2h_ini - diff + igi_target;
+ th_h2l_dmc = th_l2h_dmc - p_dm_odm->th_edcca_hl_diff;
+ } else {
+ diff = igi_target - (s8)IGI;
+ th_l2h_dmc = p_dm_odm->th_l2h_ini + diff;
+ if (th_l2h_dmc > 10 && (p_dm_odm->adaptivity_enable == true))
+ th_l2h_dmc = 10;
+
+ th_h2l_dmc = th_l2h_dmc - p_dm_odm->th_edcca_hl_diff;
+
+ /*replace lower bound to prevent EDCCA always equal 1*/
+ if (th_h2l_dmc < adaptivity->h2l_lb)
+ th_h2l_dmc = adaptivity->h2l_lb;
+ if (th_l2h_dmc < adaptivity->l2h_lb)
+ th_l2h_dmc = adaptivity->l2h_lb;
+ }
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("IGI=0x%x, th_l2h_dmc = %d, th_h2l_dmc = %d\n", IGI, th_l2h_dmc, th_h2l_dmc));
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("adaptivity_igi_upper=0x%x, h2l_lb = 0x%x, l2h_lb = 0x%x\n", p_dm_odm->adaptivity_igi_upper, adaptivity->h2l_lb, adaptivity->l2h_lb));
+
+ phydm_set_edcca_threshold(p_dm_odm, th_h2l_dmc, th_l2h_dmc);
+
+ if (p_dm_odm->adaptivity_enable == true)
+ odm_set_mac_reg(p_dm_odm, REG_RD_CTRL, BIT(11), 1);
+
+ return;
+}
+
+/*This API is for solving USB can't Tx problem due to USB3.0 interference in 2.4G*/
+void
+phydm_pause_edcca(
+ void *p_dm_void,
+ bool is_pasue_edcca
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTIVITY_STATISTICS *adaptivity = (struct _ADAPTIVITY_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_ADAPTIVITY);
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+ u8 IGI = p_dm_dig_table->cur_ig_value;
+ s8 diff = 0;
+
+ if (is_pasue_edcca) {
+ adaptivity->is_stop_edcca = true;
+ if (p_dm_odm->support_ic_type & (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) {
+ if (adaptivity->adajust_igi_level > IGI)
+ diff = adaptivity->adajust_igi_level - IGI;
+
+ adaptivity->backup_l2h = p_dm_odm->th_l2h_ini - diff + adaptivity->igi_target;
+ adaptivity->backup_h2l = adaptivity->backup_l2h - p_dm_odm->th_edcca_hl_diff;
+ } else {
+ diff = adaptivity->igi_target - (s8)IGI;
+ adaptivity->backup_l2h = p_dm_odm->th_l2h_ini + diff;
+ if (adaptivity->backup_l2h > 10)
+ adaptivity->backup_l2h = 10;
+
+ adaptivity->backup_h2l = adaptivity->backup_l2h - p_dm_odm->th_edcca_hl_diff;
+
+ /*replace lower bound to prevent EDCCA always equal 1*/
+ if (adaptivity->backup_h2l < adaptivity->h2l_lb)
+ adaptivity->backup_h2l = adaptivity->h2l_lb;
+ if (adaptivity->backup_l2h < adaptivity->l2h_lb)
+ adaptivity->backup_l2h = adaptivity->l2h_lb;
+ }
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("pauseEDCCA : L2Hbak = 0x%x, H2Lbak = 0x%x, IGI = 0x%x\n", adaptivity->backup_l2h, adaptivity->backup_h2l, IGI));
+
+ /*Disable EDCCA*/
+ phydm_pause_edcca_work_item_callback(p_dm_odm);
+ } else {
+
+ adaptivity->is_stop_edcca = false;
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("resumeEDCCA : L2Hbak = 0x%x, H2Lbak = 0x%x, IGI = 0x%x\n", adaptivity->backup_l2h, adaptivity->backup_h2l, IGI));
+ /*Resume EDCCA*/
+ phydm_resume_edcca_work_item_callback(p_dm_odm);
+ }
+}
+
+
+void
+phydm_pause_edcca_work_item_callback(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_ECCA_THRESHOLD, MASKBYTE2 | MASKBYTE0, (u32)(0x7f | 0x7f << 16));
+ else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XB_LSSI_READ_BACK, MASKLWORD, (u16)(0x7f | 0x7f << 8));
+}
+
+void
+phydm_resume_edcca_work_item_callback(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTIVITY_STATISTICS *adaptivity = (struct _ADAPTIVITY_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_ADAPTIVITY);
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_ECCA_THRESHOLD, MASKBYTE2 | MASKBYTE0, (u32)((u8)adaptivity->backup_l2h | (u8)adaptivity->backup_h2l << 16));
+ else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XB_LSSI_READ_BACK, MASKLWORD, (u16)((u8)adaptivity->backup_l2h | (u8)adaptivity->backup_h2l << 8));
+}
+
+
+void
+phydm_set_edcca_threshold_api(
+ void *p_dm_void,
+ u8 IGI
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTIVITY_STATISTICS *adaptivity = (struct _ADAPTIVITY_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_ADAPTIVITY);
+ s8 th_l2h_dmc, th_h2l_dmc;
+ s8 diff = 0, igi_target = 0x32;
+
+ if (p_dm_odm->support_ability & ODM_BB_ADAPTIVITY) {
+ if (p_dm_odm->support_ic_type & (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) {
+ if (adaptivity->adajust_igi_level > IGI)
+ diff = adaptivity->adajust_igi_level - IGI;
+
+ th_l2h_dmc = p_dm_odm->th_l2h_ini - diff + igi_target;
+ th_h2l_dmc = th_l2h_dmc - p_dm_odm->th_edcca_hl_diff;
+ } else {
+ diff = igi_target - (s8)IGI;
+ th_l2h_dmc = p_dm_odm->th_l2h_ini + diff;
+ if (th_l2h_dmc > 10)
+ th_l2h_dmc = 10;
+
+ th_h2l_dmc = th_l2h_dmc - p_dm_odm->th_edcca_hl_diff;
+
+ /*replace lower bound to prevent EDCCA always equal 1*/
+ if (th_h2l_dmc < adaptivity->h2l_lb)
+ th_h2l_dmc = adaptivity->h2l_lb;
+ if (th_l2h_dmc < adaptivity->l2h_lb)
+ th_l2h_dmc = adaptivity->l2h_lb;
+ }
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("API :IGI=0x%x, th_l2h_dmc = %d, th_h2l_dmc = %d\n", IGI, th_l2h_dmc, th_h2l_dmc));
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("API :adaptivity_igi_upper=0x%x, h2l_lb = 0x%x, l2h_lb = 0x%x\n", p_dm_odm->adaptivity_igi_upper, adaptivity->h2l_lb, adaptivity->l2h_lb));
+
+ phydm_set_edcca_threshold(p_dm_odm, th_h2l_dmc, th_l2h_dmc);
+ }
+
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_adaptivity.h b/drivers/staging/rtl8188eu/hal/phydm_adaptivity.h
new file mode 100644
index 000000000000..2a4a208be479
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_adaptivity.h
@@ -0,0 +1,159 @@
+
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMADAPTIVITY_H__
+#define __PHYDMADAPTIVITY_H__
+
+#define ADAPTIVITY_VERSION "9.3.5" /*20160902 changed by Kevin, refine method for searching pwdb lower bound*/
+
+#define pwdb_upper_bound 7
+#define dfir_loss 5
+
+enum phydm_adapinfo_e {
+ PHYDM_ADAPINFO_CARRIER_SENSE_ENABLE = 0,
+ PHYDM_ADAPINFO_DCBACKOFF,
+ PHYDM_ADAPINFO_DYNAMICLINKADAPTIVITY,
+ PHYDM_ADAPINFO_TH_L2H_INI,
+ PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF,
+ PHYDM_ADAPINFO_AP_NUM_TH
+};
+
+enum phydm_set_lna {
+ phydm_disable_lna = 0,
+ phydm_enable_lna = 1,
+};
+
+
+enum phydm_trx_mux_type {
+ phydm_shutdown = 0,
+ phydm_standby_mode = 1,
+ phydm_tx_mode = 2,
+ phydm_rx_mode = 3
+};
+
+enum phydm_mac_edcca_type {
+ phydm_ignore_edcca = 0,
+ phydm_dont_ignore_edcca = 1
+};
+
+struct _ADAPTIVITY_STATISTICS {
+ s8 th_l2h_ini_backup;
+ s8 th_edcca_hl_diff_backup;
+ s8 igi_base;
+ u8 igi_target;
+ u8 nhm_wait;
+ s8 h2l_lb;
+ s8 l2h_lb;
+ bool is_first_link;
+ bool is_check;
+ bool dynamic_link_adaptivity;
+ u8 ap_num_th;
+ u8 adajust_igi_level;
+ bool acs_for_adaptivity;
+ s8 backup_l2h;
+ s8 backup_h2l;
+ bool is_stop_edcca;
+};
+
+void
+phydm_pause_edcca(
+ void *p_dm_void,
+ bool is_pasue_edcca
+);
+
+void
+phydm_check_adaptivity(
+ void *p_dm_void
+);
+
+void
+phydm_check_environment(
+ void *p_dm_void
+);
+
+void
+phydm_nhm_counter_statistics_init(
+ void *p_dm_void
+);
+
+void
+phydm_nhm_counter_statistics(
+ void *p_dm_void
+);
+
+void
+phydm_nhm_counter_statistics_reset(
+ void *p_dm_void
+);
+
+void
+phydm_get_nhm_counter_statistics(
+ void *p_dm_void
+);
+
+void
+phydm_mac_edcca_state(
+ void *p_dm_void,
+ enum phydm_mac_edcca_type state
+);
+
+void
+phydm_set_edcca_threshold(
+ void *p_dm_void,
+ s8 H2L,
+ s8 L2H
+);
+
+void
+phydm_set_trx_mux(
+ void *p_dm_void,
+ enum phydm_trx_mux_type tx_mode,
+ enum phydm_trx_mux_type rx_mode
+);
+
+bool
+phydm_cal_nhm_cnt(
+ void *p_dm_void
+);
+
+void
+phydm_search_pwdb_lower_bound(
+ void *p_dm_void
+);
+
+void
+phydm_adaptivity_info_init(
+ void *p_dm_void,
+ enum phydm_adapinfo_e cmn_info,
+ u32 value
+);
+
+void
+phydm_adaptivity_init(
+ void *p_dm_void
+);
+
+void
+phydm_adaptivity(
+ void *p_dm_void
+);
+
+void
+phydm_set_edcca_threshold_api(
+ void *p_dm_void,
+ u8 IGI
+);
+
+void
+phydm_pause_edcca_work_item_callback(
+ void *p_dm_void
+);
+
+void
+phydm_resume_edcca_work_item_callback(
+ void *p_dm_void
+);
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_adc_sampling.c b/drivers/staging/rtl8188eu/hal/phydm_adc_sampling.c
new file mode 100644
index 000000000000..89739a27bc97
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_adc_sampling.c
@@ -0,0 +1,594 @@
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+
+#if (PHYDM_LA_MODE_SUPPORT == 1)
+
+bool
+phydm_la_buffer_allocate(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _RT_ADCSMP *adc_smp = &(p_dm_odm->adcsmp);
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ struct _RT_ADCSMP_STRING *adc_smp_buf = &(adc_smp->adc_smp_buf);
+ bool ret = false;
+
+ dbg_print("[LA mode BufferAllocate]\n");
+
+ if (adc_smp_buf->length == 0) {
+
+ odm_allocate_memory(p_dm_odm, (void **)&adc_smp_buf->octet, adc_smp_buf->buffer_size);
+ if (!adc_smp_buf->octet) {
+ ret = false;
+ } else
+ adc_smp_buf->length = adc_smp_buf->buffer_size;
+ ret = true;
+ }
+
+ return ret;
+}
+
+void
+phydm_la_get_tx_pkt_buf(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _RT_ADCSMP *adc_smp = &(p_dm_odm->adcsmp);
+ struct _RT_ADCSMP_STRING *adc_smp_buf = &(adc_smp->adc_smp_buf);
+ u32 i = 0, value32, data_l = 0, data_h = 0;
+ u32 addr, finish_addr;
+ u32 end_addr = (adc_smp_buf->start_pos + adc_smp_buf->buffer_size) - 1; /*end_addr = 0x3ffff;*/
+ bool is_round_up;
+ static u32 page = 0xFF;
+ u32 smp_cnt = 0, smp_number = 0, addr_8byte = 0;
+
+ odm_memory_set(p_dm_odm, adc_smp_buf->octet, 0, adc_smp_buf->length);
+ odm_write_1byte(p_dm_odm, 0x0106, 0x69);
+
+ dbg_print("GetTxPktBuf\n");
+
+ value32 = odm_read_4byte(p_dm_odm, 0x7c0);
+ is_round_up = (bool)((value32 & BIT(31)) >> 31);
+ finish_addr = (value32 & 0x7FFF0000) >> 16; /*Reg7C0[30:16]: finish addr (unit: 8byte)*/
+
+ if (is_round_up) {
+ addr = (finish_addr + 1) << 3;
+ dbg_print("is_round_up = ((%d)), finish_addr=((0x%x)), 0x7c0=((0x%x))\n", is_round_up, finish_addr, value32);
+ smp_number = ((adc_smp_buf->buffer_size) >> 3); /*Byte to 64Byte*/
+ } else {
+ addr = adc_smp_buf->start_pos;
+
+ addr_8byte = addr >> 3;
+ if (addr_8byte > finish_addr)
+ smp_number = addr_8byte - finish_addr;
+ else
+ smp_number = finish_addr - addr_8byte;
+
+ dbg_print("is_round_up = ((%d)), finish_addr=((0x%x * 8Byte)), Start_Addr = ((0x%x * 8Byte)), smp_number = ((%d))\n", is_round_up, finish_addr, addr_8byte, smp_number);
+
+ }
+ if (p_dm_odm->support_ic_type & ODM_RTL8197F) {
+ for (addr = 0x0, i = 0; addr < end_addr; addr += 8, i += 2) { /*64K byte*/
+ if ((addr & 0xfff) == 0)
+ odm_set_bb_reg(p_dm_odm, 0x0140, MASKLWORD, 0x780 + (addr >> 12));
+ data_l = odm_get_bb_reg(p_dm_odm, 0x8000 + (addr & 0xfff), MASKDWORD);
+ data_h = odm_get_bb_reg(p_dm_odm, 0x8000 + (addr & 0xfff) + 4, MASKDWORD);
+
+ dbg_print("%08x%08x\n", data_h, data_l);
+ }
+ } else {
+ while (addr != (finish_addr << 3)) {
+ if (page != (addr >> 12)) {
+ /*Reg140=0x780+(addr>>12), addr=0x30~0x3F, total 16 pages*/
+ page = (addr >> 12);
+ }
+ odm_set_bb_reg(p_dm_odm, 0x0140, MASKLWORD, 0x780 + page);
+
+ /*pDataL = 0x8000+(addr&0xfff);*/
+ data_l = odm_get_bb_reg(p_dm_odm, 0x8000 + (addr & 0xfff), MASKDWORD);
+ data_h = odm_get_bb_reg(p_dm_odm, 0x8000 + (addr & 0xfff) + 4, MASKDWORD);
+
+ adc_smp_buf->octet[i] = data_h;
+ adc_smp_buf->octet[i + 1] = data_l;
+
+#if DBG
+ dbg_print("%08x%08x\n", data_h, data_l);
+#endif
+ i = i + 2;
+
+ if ((addr + 8) >= end_addr)
+ addr = adc_smp_buf->start_pos;
+ else
+ addr = addr + 8;
+
+ smp_cnt++;
+ if (smp_cnt >= (smp_number - 1))
+ break;
+ }
+ dbg_print("smp_cnt = ((%d))\n", smp_cnt);
+ }
+}
+
+void
+phydm_la_mode_set_mac_iq_dump(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _RT_ADCSMP *adc_smp = &(p_dm_odm->adcsmp);
+ u32 reg_value;
+
+ odm_write_1byte(p_dm_odm, 0x7c0, 0); /*clear all 0x7c0*/
+ odm_set_mac_reg(p_dm_odm, 0x7c0, BIT(0), 1); /*Enable LA mode HW block*/
+
+ if (adc_smp->la_trig_mode == PHYDM_MAC_TRIG) {
+
+ adc_smp->is_bb_trigger = 0;
+ odm_set_mac_reg(p_dm_odm, 0x7c0, BIT(2), 1); /*polling bit for MAC mode*/
+ odm_set_mac_reg(p_dm_odm, 0x7c0, BIT(4) | BIT3, adc_smp->la_trigger_edge); /*trigger mode for MAC*/
+
+ dbg_print("[MAC_trig] ref_mask = ((0x%x)), ref_value = ((0x%x)), dbg_port = ((0x%x))\n", adc_smp->la_mac_ref_mask, adc_smp->la_trig_sig_sel, adc_smp->la_dbg_port);
+ /*[Set MAC Debug Port]*/
+ odm_set_mac_reg(p_dm_odm, 0xF4, BIT(16), 1);
+ odm_set_mac_reg(p_dm_odm, 0x38, 0xff0000, adc_smp->la_dbg_port);
+ odm_set_mac_reg(p_dm_odm, 0x7c4, MASKDWORD, adc_smp->la_mac_ref_mask);
+ odm_set_mac_reg(p_dm_odm, 0x7c8, MASKDWORD, adc_smp->la_trig_sig_sel);
+
+ } else {
+
+ adc_smp->is_bb_trigger = 1;
+ odm_set_mac_reg(p_dm_odm, 0x7c0, BIT(1), 1); /*polling bit for BB ADC mode*/
+
+ if (adc_smp->la_trig_mode == PHYDM_ADC_MAC_TRIG) {
+
+ odm_set_mac_reg(p_dm_odm, 0x7c0, BIT(3), 1); /*polling bit for MAC trigger event*/
+ odm_set_mac_reg(p_dm_odm, 0x7c0, BIT(7) | BIT(6), adc_smp->la_trig_sig_sel);
+
+ if (adc_smp->la_trig_sig_sel == ADCSMP_TRIG_REG)
+ odm_set_mac_reg(p_dm_odm, 0x7c0, BIT(5), 1); /* manual trigger 0x7C0[5] = 0->1*/
+ }
+ }
+
+ reg_value = odm_get_bb_reg(p_dm_odm, 0x7c0, 0xff);
+ dbg_print("4. [Set MAC IQ dump] 0x7c0[7:0] = ((0x%x))\n", reg_value);
+}
+
+void
+phydm_la_mode_set_dma_type(
+ void *p_dm_void,
+ u8 la_dma_type
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ dbg_print("2. [LA mode DMA setting] Dma_type = ((%d))\n", la_dma_type);
+ if (p_dm_odm->support_ic_type & ODM_N_ANTDIV_SUPPORT)
+ odm_set_bb_reg(p_dm_odm, 0x9a0, 0xf00, la_dma_type); /*0x9A0[11:8]*/
+ else
+ odm_set_bb_reg(p_dm_odm, odm_adc_trigger_jaguar2, 0xf00, la_dma_type); /*0x95C[11:8]*/
+}
+
+void
+phydm_adc_smp_start(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _RT_ADCSMP *adc_smp = &(p_dm_odm->adcsmp);
+ u8 tmp_u1b;
+ u8 backup_DMA, while_cnt = 0;
+ u8 polling_ok = false, target_polling_bit;
+
+ phydm_la_mode_bb_setting(p_dm_odm);
+ phydm_la_mode_set_dma_type(p_dm_odm, adc_smp->la_dma_type);
+ phydm_la_mode_set_trigger_time(p_dm_odm, adc_smp->la_trigger_time);
+
+ if (p_dm_odm->support_ic_type & ODM_RTL8197F)
+ odm_set_bb_reg(p_dm_odm, 0xd00, BIT(26), 0x1);
+ else { /*for 8814A and 8822B?*/
+ odm_write_1byte(p_dm_odm, 0x198c, 0x7);
+ odm_write_1byte(p_dm_odm, 0x8b4, 0x80);
+ /* odm_set_bb_reg(p_dm_odm, 0x8b4, BIT7, 1); */
+ }
+
+ phydm_la_mode_set_mac_iq_dump(p_dm_odm);
+ /* return; */
+
+ target_polling_bit = (adc_smp->is_bb_trigger) ? BIT(1) : BIT(2);
+ do { /*Polling time always use 100ms, when it exceed 2s, break while loop*/
+ tmp_u1b = odm_read_1byte(p_dm_odm, 0x7c0);
+
+ if (adc_smp->adc_smp_state != ADCSMP_STATE_SET) {
+ dbg_print("[state Error] adc_smp_state != ADCSMP_STATE_SET\n");
+ break;
+
+ } else if (tmp_u1b & target_polling_bit) {
+ ODM_delay_ms(100);
+ while_cnt = while_cnt + 1;
+ continue;
+ } else {
+ dbg_print("[LA Query OK] polling_bit=((0x%x))\n", target_polling_bit);
+ polling_ok = true;
+ if (p_dm_odm->support_ic_type & ODM_RTL8197F)
+ odm_set_bb_reg(p_dm_odm, 0x7c0, BIT(0), 0x0);
+ break;
+ }
+ } while (while_cnt < 20);
+
+ if (adc_smp->adc_smp_state == ADCSMP_STATE_SET) {
+
+ if (polling_ok)
+ phydm_la_get_tx_pkt_buf(p_dm_odm);
+ else
+ dbg_print("[Polling timeout]\n");
+ }
+
+ if (adc_smp->adc_smp_state == ADCSMP_STATE_SET)
+ adc_smp->adc_smp_state = ADCSMP_STATE_QUERY;
+
+ dbg_print("[LA mode] LA_pattern_count = ((%d))\n", adc_smp->la_count);
+
+ adc_smp_stop(p_dm_odm);
+
+ if (adc_smp->la_count == 0) {
+ dbg_print("LA Dump finished ---------->\n\n\n");
+ /**/
+ } else {
+ adc_smp->la_count--;
+ dbg_print("LA Dump more ---------->\n\n\n");
+ adc_smp_set(p_dm_odm, adc_smp->la_trig_mode, adc_smp->la_trig_sig_sel, adc_smp->la_dma_type, adc_smp->la_trigger_time, 0);
+ }
+
+}
+
+void
+adc_smp_set(
+ void *p_dm_void,
+ u8 trig_mode,
+ u32 trig_sig_sel,
+ u8 dma_data_sig_sel,
+ u32 trigger_time,
+ u16 polling_time
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ bool is_set_success = true;
+ struct _RT_ADCSMP *adc_smp = &(p_dm_odm->adcsmp);
+
+ adc_smp->la_trig_mode = trig_mode;
+ adc_smp->la_trig_sig_sel = trig_sig_sel;
+ adc_smp->la_dma_type = dma_data_sig_sel;
+ adc_smp->la_trigger_time = trigger_time;
+
+ if (adc_smp->adc_smp_state != ADCSMP_STATE_IDLE)
+ is_set_success = false;
+ else if (adc_smp->adc_smp_buf.length == 0)
+ is_set_success = phydm_la_buffer_allocate(p_dm_odm);
+
+ if (is_set_success) {
+ adc_smp->adc_smp_state = ADCSMP_STATE_SET;
+
+ dbg_print("[LA Set Success] LA_State=((%d))\n", adc_smp->adc_smp_state);
+
+ phydm_adc_smp_start(p_dm_odm);
+ } else
+ dbg_print("[LA Set Fail] LA_State=((%d))\n", adc_smp->adc_smp_state);
+
+
+}
+
+void
+adc_smp_query(
+ void *p_dm_void,
+ void *output,
+ u32 out_len,
+ u32 *pused
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _RT_ADCSMP *adc_smp = &(p_dm_odm->adcsmp);
+ struct _RT_ADCSMP_STRING *adc_smp_buf = &(adc_smp->adc_smp_buf);
+ u32 used = *pused;
+ u32 i;
+ /* struct timespec t; */
+ /* rtw_get_current_timespec(&t); */
+
+ dbg_print("%s adc_smp_state %d", __func__, adc_smp->adc_smp_state);
+
+ for (i = 0; i < (adc_smp_buf->length >> 2) - 2; i += 2) {
+ PHYDM_SNPRINTF((output + used, out_len - used,
+ "%08x%08x\n", adc_smp_buf->octet[i], adc_smp_buf->octet[i + 1]));
+ }
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\n"));
+ /* PHYDM_SNPRINTF((output+used, out_len-used, "\n[%lu.%06lu]\n", t.tv_sec, t.tv_nsec)); */
+ *pused = used;
+}
+
+s32
+adc_smp_get_sample_counts(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _RT_ADCSMP *adc_smp = &(p_dm_odm->adcsmp);
+ struct _RT_ADCSMP_STRING *adc_smp_buf = &(adc_smp->adc_smp_buf);
+
+ return (adc_smp_buf->length >> 2) - 2;
+}
+
+s32
+adc_smp_query_single_data(
+ void *p_dm_void,
+ void *output,
+ u32 out_len,
+ u32 index
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _RT_ADCSMP *adc_smp = &(p_dm_odm->adcsmp);
+ struct _RT_ADCSMP_STRING *adc_smp_buf = &(adc_smp->adc_smp_buf);
+ u32 used = 0;
+
+ /* dbg_print("%s adc_smp_state %d\n", __func__, adc_smp->adc_smp_state); */
+ if (adc_smp->adc_smp_state != ADCSMP_STATE_QUERY) {
+ PHYDM_SNPRINTF((output + used, out_len - used,
+ "Error: la data is not ready yet ...\n"));
+ return -1;
+ }
+
+ if (index < ((adc_smp_buf->length >> 2) - 2)) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "%08x%08x\n",
+ adc_smp_buf->octet[index], adc_smp_buf->octet[index + 1]));
+ }
+ return 0;
+}
+
+void
+adc_smp_stop(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _RT_ADCSMP *adc_smp = &(p_dm_odm->adcsmp);
+
+ adc_smp->adc_smp_state = ADCSMP_STATE_IDLE;
+ dbg_print("[LA_Stop] LA_state = ((%d))\n", adc_smp->adc_smp_state);
+}
+
+void
+adc_smp_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _RT_ADCSMP *adc_smp = &(p_dm_odm->adcsmp);
+ struct _RT_ADCSMP_STRING *adc_smp_buf = &(adc_smp->adc_smp_buf);
+
+ adc_smp->adc_smp_state = ADCSMP_STATE_IDLE;
+
+ if (p_dm_odm->support_ic_type & ODM_RTL8814A) {
+ adc_smp_buf->start_pos = 0x30000;
+ adc_smp_buf->buffer_size = 0x10000;
+ } else if (p_dm_odm->support_ic_type & ODM_RTL8822B) {
+ adc_smp_buf->start_pos = 0x20000;
+ adc_smp_buf->buffer_size = 0x20000;
+ } else if (p_dm_odm->support_ic_type & ODM_RTL8197F) {
+ adc_smp_buf->start_pos = 0x00000;
+ adc_smp_buf->buffer_size = 0x10000;
+ } else if (p_dm_odm->support_ic_type & ODM_RTL8821C) {
+ adc_smp_buf->start_pos = 0x8000;
+ adc_smp_buf->buffer_size = 0x8000;
+ }
+
+}
+
+void
+adc_smp_de_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _RT_ADCSMP *adc_smp = &(p_dm_odm->adcsmp);
+ struct _RT_ADCSMP_STRING *adc_smp_buf = &(adc_smp->adc_smp_buf);
+
+ adc_smp_stop(p_dm_odm);
+
+ if (adc_smp_buf->length != 0x0) {
+ odm_free_memory(p_dm_odm, adc_smp_buf->octet, adc_smp_buf->length);
+ adc_smp_buf->length = 0x0;
+ }
+}
+
+void
+phydm_la_mode_bb_setting(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _RT_ADCSMP *adc_smp = &(p_dm_odm->adcsmp);
+
+ u8 trig_mode = adc_smp->la_trig_mode;
+ u32 trig_sig_sel = adc_smp->la_trig_sig_sel;
+ u32 dbg_port = adc_smp->la_dbg_port;
+ u8 is_trigger_edge = adc_smp->la_trigger_edge;
+ u8 sampling_rate = adc_smp->la_smp_rate;
+
+ dbg_print("1. [LA mode bb_setting] trig_mode = ((%d)), dbg_port = ((0x%x)), Trig_Edge = ((%d)), smp_rate = ((%d)), Trig_Sel = ((0x%x))\n",
+ trig_mode, dbg_port, is_trigger_edge, sampling_rate, trig_sig_sel);
+
+ if (trig_mode == PHYDM_MAC_TRIG)
+ trig_sig_sel = 0; /*ignore this setting*/
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+
+ if (trig_mode == PHYDM_ADC_RF0_TRIG) {
+ odm_set_bb_reg(p_dm_odm, 0x8f8, BIT(25) | BIT24 | BIT23 | BIT22, 9); /*DBGOUT_RFC_a[31:0]*/
+ } else if (trig_mode == PHYDM_ADC_RF1_TRIG) {
+ odm_set_bb_reg(p_dm_odm, 0x8f8, BIT(25) | BIT24 | BIT23 | BIT22, 8); /*DBGOUT_RFC_b[31:0]*/
+ } else
+ odm_set_bb_reg(p_dm_odm, 0x8f8, BIT(25) | BIT(24) | BIT(23) | BIT(22), 0);
+ /*
+ (0:) '{ofdm_dbg[31:0]}'
+ (1:) '{cca,crc32_fail,dbg_ofdm[29:0]}'
+ (2:) '{vbon,crc32_fail,dbg_ofdm[29:0]}'
+ (3:) '{cca,crc32_ok,dbg_ofdm[29:0]}'
+ (4:) '{vbon,crc32_ok,dbg_ofdm[29:0]}'
+ (5:) '{dbg_iqk_anta}'
+ (6:) '{cca,ofdm_crc_ok,dbg_dp_anta[29:0]}'
+ (7:) '{dbg_iqk_antb}'
+ (8:) '{DBGOUT_RFC_b[31:0]}'
+ (9:) '{DBGOUT_RFC_a[31:0]}'
+ (a:) '{dbg_ofdm}'
+ (b:) '{dbg_cck}'
+ */
+
+ odm_set_bb_reg(p_dm_odm, 0x198C, BIT(2) | BIT1 | BIT0, 7); /*disable dbg clk gating*/
+
+ /*dword= odm_get_bb_reg(p_dm_odm, 0x8FC, MASKDWORD);*/
+ /*dbg_print("dbg_port = ((0x%x))\n", dword);*/
+ odm_set_bb_reg(p_dm_odm, 0x95C, 0x1f, trig_sig_sel); /*0x95C[4:0], BB debug port bit*/
+ odm_set_bb_reg(p_dm_odm, 0x8FC, MASKDWORD, dbg_port);
+ odm_set_bb_reg(p_dm_odm, 0x95C, BIT(31), is_trigger_edge); /*0: posedge, 1: negedge*/
+ odm_set_bb_reg(p_dm_odm, 0x95c, 0xe0, sampling_rate);
+ /* (0:) '80MHz'
+ (1:) '40MHz'
+ (2:) '20MHz'
+ (3:) '10MHz'
+ (4:) '5MHz'
+ (5:) '2.5MHz'
+ (6:) '1.25MHz'
+ (7:) '160MHz (for BW160 ic)'
+ */
+ } else {
+ odm_set_bb_reg(p_dm_odm, 0x9a0, 0x1f, trig_sig_sel); /*0x9A0[4:0], BB debug port bit*/
+ odm_set_bb_reg(p_dm_odm, 0x908, MASKDWORD, dbg_port);
+ odm_set_bb_reg(p_dm_odm, 0x9A0, BIT(31), is_trigger_edge); /*0: posedge, 1: negedge*/
+ odm_set_bb_reg(p_dm_odm, 0x9A0, 0xe0, sampling_rate);
+ /* (0:) '80MHz'
+ (1:) '40MHz'
+ (2:) '20MHz'
+ (3:) '10MHz'
+ (4:) '5MHz'
+ (5:) '2.5MHz'
+ (6:) '1.25MHz'
+ (7:) '160MHz (for BW160 ic)'
+ */
+ }
+}
+
+void
+phydm_la_mode_set_trigger_time(
+ void *p_dm_void,
+ u32 trigger_time_mu_sec
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 trigger_time_unit_num;
+ u32 time_unit = 0;
+
+ if (trigger_time_mu_sec < 128) {
+ time_unit = 0; /*unit: 1mu sec*/
+ } else if (trigger_time_mu_sec < 256) {
+ time_unit = 1; /*unit: 2mu sec*/
+ } else if (trigger_time_mu_sec < 512) {
+ time_unit = 2; /*unit: 4mu sec*/
+ } else if (trigger_time_mu_sec < 1024) {
+ time_unit = 3; /*unit: 8mu sec*/
+ } else if (trigger_time_mu_sec < 2048) {
+ time_unit = 4; /*unit: 16mu sec*/
+ } else if (trigger_time_mu_sec < 4096) {
+ time_unit = 5; /*unit: 32mu sec*/
+ } else if (trigger_time_mu_sec < 8192) {
+ time_unit = 6; /*unit: 64mu sec*/
+ }
+
+ trigger_time_unit_num = (u8)(trigger_time_mu_sec >> time_unit);
+
+ dbg_print("3. [Set Trigger Time] Trig_Time = ((%d)) * unit = ((2^%d us))\n", trigger_time_unit_num, time_unit);
+
+ odm_set_mac_reg(p_dm_odm, 0x7cc, BIT(20) | BIT(19) | BIT(18), time_unit);
+ odm_set_mac_reg(p_dm_odm, 0x7c0, 0x7f00, (trigger_time_unit_num & 0x7f));
+
+}
+
+void
+phydm_lamode_trigger_setting(
+ void *p_dm_void,
+ char input[][16],
+ u32 *_used,
+ char *output,
+ u32 *_out_len,
+ u32 input_num
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _RT_ADCSMP *adc_smp = &(p_dm_odm->adcsmp);
+ u8 trig_mode, dma_data_sig_sel;
+ u32 trig_sig_sel;
+ bool is_enable_la_mode, is_trigger_edge;
+ u32 dbg_port, trigger_time_mu_sec;
+ u32 mac_ref_signal_mask;
+ u8 sampling_rate = 0, i;
+ char help[] = "-h";
+ u32 var1[10] = {0};
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ if (p_dm_odm->support_ic_type & PHYDM_IC_SUPPORT_LA_MODE) {
+
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+ is_enable_la_mode = (bool)var1[0];
+ /*dbg_print("echo cmd input_num = %d\n", input_num);*/
+
+ if ((strcmp(input[1], help) == 0)) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "{En} {0:BB,1:BB_MAC,2:RF0,3:RF1,4:MAC} \n {BB:dbg_port[bit],BB_MAC:0-ok/1-fail/2-cca,MAC:ref} {DMA type} {TrigTime} \n {polling_time/ref_mask} {dbg_port} {0:P_Edge, 1:N_Edge} {SpRate:0-80M,1-40M,2-20M} {Capture num}\n"));
+ /**/
+ } else if ((is_enable_la_mode == 1)) {
+
+ PHYDM_SSCANF(input[2], DCMD_DECIMAL, &var1[1]);
+
+ trig_mode = (u8)var1[1];
+
+ if (trig_mode == PHYDM_MAC_TRIG)
+ PHYDM_SSCANF(input[3], DCMD_HEX, &var1[2]);
+ else
+ PHYDM_SSCANF(input[3], DCMD_DECIMAL, &var1[2]);
+ trig_sig_sel = var1[2];
+
+ PHYDM_SSCANF(input[4], DCMD_DECIMAL, &var1[3]);
+ PHYDM_SSCANF(input[5], DCMD_DECIMAL, &var1[4]);
+ PHYDM_SSCANF(input[6], DCMD_HEX, &var1[5]);
+ PHYDM_SSCANF(input[7], DCMD_HEX, &var1[6]);
+ PHYDM_SSCANF(input[8], DCMD_DECIMAL, &var1[7]);
+ PHYDM_SSCANF(input[9], DCMD_DECIMAL, &var1[8]);
+ PHYDM_SSCANF(input[10], DCMD_DECIMAL, &var1[9]);
+
+ dma_data_sig_sel = (u8)var1[3];
+ trigger_time_mu_sec = var1[4]; /*unit: us*/
+
+ adc_smp->la_mac_ref_mask = var1[5];
+ adc_smp->la_dbg_port = var1[6];
+ adc_smp->la_trigger_edge = (u8) var1[7];
+ adc_smp->la_smp_rate = (u8)(var1[8] & 0x7);
+ adc_smp->la_count = var1[9];
+
+
+ dbg_print("echo lamode %d %d %d %d %d %d %x %d %d %d\n", var1[0], var1[1], var1[2], var1[3], var1[4], var1[5], var1[6], var1[7], var1[8], var1[9]);
+ PHYDM_SNPRINTF((output + used, out_len - used, "a.En= ((1)), b.mode = ((%d)), c.Trig_Sel = ((0x%x)), d.Dma_type = ((%d))\n", trig_mode, trig_sig_sel, dma_data_sig_sel));
+ PHYDM_SNPRINTF((output + used, out_len - used, "e.Trig_Time = ((%dus)), f.mac_ref_mask = ((0x%x)), g.dbg_port = ((0x%x))\n", trigger_time_mu_sec, adc_smp->la_mac_ref_mask, adc_smp->la_dbg_port));
+ PHYDM_SNPRINTF((output + used, out_len - used, "h.Trig_edge = ((%d)), i.smp rate = ((%d MHz)), j.Cap_num = ((%d))\n", adc_smp->la_trigger_edge, (80 >> adc_smp->la_smp_rate), adc_smp->la_count));
+
+ adc_smp_set(p_dm_odm, trig_mode, trig_sig_sel, dma_data_sig_sel, trigger_time_mu_sec, 0);
+
+ } else {
+ adc_smp_stop(p_dm_odm);
+ PHYDM_SNPRINTF((output + used, out_len - used, "Disable LA mode\n"));
+ }
+ }
+}
+
+#endif /*endif PHYDM_LA_MODE_SUPPORT == 1*/
diff --git a/drivers/staging/rtl8188eu/hal/phydm_adc_sampling.h b/drivers/staging/rtl8188eu/hal/phydm_adc_sampling.h
new file mode 100644
index 000000000000..1aec84345dea
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_adc_sampling.h
@@ -0,0 +1,123 @@
+#ifndef __INC_ADCSMP_H
+#define __INC_ADCSMP_H
+
+#define DYNAMIC_LA_MODE "1.0" /*2016.07.15 Dino */
+
+#if (PHYDM_LA_MODE_SUPPORT == 1)
+
+struct _RT_ADCSMP_STRING {
+ u32 *octet;
+ u32 length;
+ u32 buffer_size;
+ u32 start_pos;
+};
+
+
+enum rt_adcsmp_trig_sel {
+ PHYDM_ADC_BB_TRIG = 0,
+ PHYDM_ADC_MAC_TRIG = 1,
+ PHYDM_ADC_RF0_TRIG = 2,
+ PHYDM_ADC_RF1_TRIG = 3,
+ PHYDM_MAC_TRIG = 4
+};
+
+
+enum rt_adcsmp_trig_sig_sel {
+ ADCSMP_TRIG_CRCOK = 0,
+ ADCSMP_TRIG_CRCFAIL = 1,
+ ADCSMP_TRIG_CCA = 2,
+ ADCSMP_TRIG_REG = 3
+};
+
+
+enum rt_adcsmp_state {
+ ADCSMP_STATE_IDLE = 0,
+ ADCSMP_STATE_SET = 1,
+ ADCSMP_STATE_QUERY = 2
+};
+
+
+struct _RT_ADCSMP {
+ struct _RT_ADCSMP_STRING adc_smp_buf;
+ enum rt_adcsmp_state adc_smp_state;
+ u8 la_trig_mode;
+ u32 la_trig_sig_sel;
+ u8 la_dma_type;
+ u32 la_trigger_time;
+ u32 la_mac_ref_mask;
+ u32 la_dbg_port;
+ u8 la_trigger_edge;
+ u8 la_smp_rate;
+ u32 la_count;
+ u8 is_bb_trigger;
+ u8 la_work_item_index;
+};
+
+void
+adc_smp_set(
+ void *p_dm_void,
+ u8 trig_mode,
+ u32 trig_sig_sel,
+ u8 dma_data_sig_sel,
+ u32 trigger_time,
+ u16 polling_time
+);
+
+void
+adc_smp_query(
+ void *p_dm_void,
+ void *output,
+ u32 out_len,
+ u32 *pused
+);
+
+s32
+adc_smp_get_sample_counts(
+ void *p_dm_void
+);
+
+s32
+adc_smp_query_single_data(
+ void *p_dm_void,
+ void *output,
+ u32 out_len,
+ u32 index
+);
+
+void
+adc_smp_stop(
+ void *p_dm_void
+);
+
+void
+adc_smp_init(
+ void *p_dm_void
+);
+
+void
+adc_smp_de_init(
+ void *p_dm_void
+);
+
+void
+phydm_la_mode_bb_setting(
+ void *p_dm_void
+);
+
+void
+phydm_la_mode_set_trigger_time(
+ void *p_dm_void,
+ u32 trigger_time_mu_sec
+);
+
+void
+phydm_lamode_trigger_setting(
+ void *p_dm_void,
+ char input[][16],
+ u32 *_used,
+ char *output,
+ u32 *_out_len,
+ u32 input_num
+);
+#endif
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_antdect.c b/drivers/staging/rtl8188eu/hal/phydm_antdect.c
new file mode 100644
index 000000000000..0ffd7109a24c
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_antdect.c
@@ -0,0 +1,847 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+#if (defined(CONFIG_ANT_DETECTION))
+
+/* IS_ANT_DETECT_SUPPORT_SINGLE_TONE(adapter)
+ * IS_ANT_DETECT_SUPPORT_RSSI(adapter)
+ * IS_ANT_DETECT_SUPPORT_PSD(adapter) */
+
+/* 1 [1. Single Tone method] =================================================== */
+
+/*
+ * Description:
+ * Set Single/Dual Antenna default setting for products that do not do detection in advance.
+ *
+ * Added by Joseph, 2012.03.22
+ * */
+void
+odm_single_dual_antenna_default_setting(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _sw_antenna_switch_ *p_dm_swat_table = &p_dm_odm->dm_swat_table;
+ struct _ADAPTER *p_adapter = p_dm_odm->adapter;
+
+ u8 bt_ant_num = BT_GetPgAntNum(p_adapter);
+ /* Set default antenna A and B status */
+ if (bt_ant_num == 2) {
+ p_dm_swat_table->ANTA_ON = true;
+ p_dm_swat_table->ANTB_ON = true;
+
+ } else if (bt_ant_num == 1) {
+ /* Set antenna A as default */
+ p_dm_swat_table->ANTA_ON = true;
+ p_dm_swat_table->ANTB_ON = false;
+
+ } else
+ RT_ASSERT(false, ("Incorrect antenna number!!\n"));
+}
+
+
+/* 2 8723A ANT DETECT
+ *
+ * Description:
+ * Implement IQK single tone for RF DPK loopback and BB PSD scanning.
+ * This function is cooperated with BB team Neil.
+ *
+ * Added by Roger, 2011.12.15
+ * */
+bool
+odm_single_dual_antenna_detection(
+ void *p_dm_void,
+ u8 mode
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTER *p_adapter = p_dm_odm->adapter;
+ struct _sw_antenna_switch_ *p_dm_swat_table = &p_dm_odm->dm_swat_table;
+ u32 current_channel, rf_loop_reg;
+ u8 n;
+ u32 reg88c, regc08, reg874, regc50, reg948, regb2c, reg92c, reg930, reg064, afe_rrx_wait_cca;
+ u8 initial_gain = 0x5a;
+ u32 PSD_report_tmp;
+ u32 ant_a_report = 0x0, ant_b_report = 0x0, ant_0_report = 0x0;
+ bool is_result = true;
+ u32 afe_backup[16];
+ u32 AFE_REG_8723A[16] = {
+ REG_RX_WAIT_CCA, REG_TX_CCK_RFON,
+ REG_TX_CCK_BBON, REG_TX_OFDM_RFON,
+ REG_TX_OFDM_BBON, REG_TX_TO_RX,
+ REG_TX_TO_TX, REG_RX_CCK,
+ REG_RX_OFDM, REG_RX_WAIT_RIFS,
+ REG_RX_TO_RX, REG_STANDBY,
+ REG_SLEEP, REG_PMPD_ANAEN,
+ REG_FPGA0_XCD_SWITCH_CONTROL, REG_BLUE_TOOTH
+ };
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_single_dual_antenna_detection()============>\n"));
+
+
+ if (!(p_dm_odm->support_ic_type & ODM_RTL8723B))
+ return is_result;
+
+ /* Retrieve antenna detection registry info, added by Roger, 2012.11.27. */
+ if (!IS_ANT_DETECT_SUPPORT_SINGLE_TONE(p_adapter))
+ return is_result;
+
+ /* 1 Backup Current RF/BB Settings */
+
+ current_channel = odm_get_rf_reg(p_dm_odm, ODM_RF_PATH_A, ODM_CHANNEL, RFREGOFFSETMASK);
+ rf_loop_reg = odm_get_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x00, RFREGOFFSETMASK);
+ if (p_dm_odm->support_ic_type & ODM_RTL8723B) {
+ reg92c = odm_get_bb_reg(p_dm_odm, REG_DPDT_CONTROL, MASKDWORD);
+ reg930 = odm_get_bb_reg(p_dm_odm, rfe_ctrl_anta_src, MASKDWORD);
+ reg948 = odm_get_bb_reg(p_dm_odm, REG_S0_S1_PATH_SWITCH, MASKDWORD);
+ regb2c = odm_get_bb_reg(p_dm_odm, REG_AGC_TABLE_SELECT, MASKDWORD);
+ reg064 = odm_get_mac_reg(p_dm_odm, REG_SYM_WLBT_PAPE_SEL, BIT(29));
+ odm_set_bb_reg(p_dm_odm, REG_DPDT_CONTROL, 0x3, 0x1);
+ odm_set_bb_reg(p_dm_odm, rfe_ctrl_anta_src, 0xff, 0x77);
+ odm_set_mac_reg(p_dm_odm, REG_SYM_WLBT_PAPE_SEL, BIT(29), 0x1); /* dbg 7 */
+ odm_set_bb_reg(p_dm_odm, REG_S0_S1_PATH_SWITCH, 0x3c0, 0x0);/* dbg 8 */
+ odm_set_bb_reg(p_dm_odm, REG_AGC_TABLE_SELECT, BIT(31), 0x0);
+ }
+
+ odm_stall_execution(10);
+
+ /* Store A path Register 88c, c08, 874, c50 */
+ reg88c = odm_get_bb_reg(p_dm_odm, REG_FPGA0_ANALOG_PARAMETER4, MASKDWORD);
+ regc08 = odm_get_bb_reg(p_dm_odm, REG_OFDM_0_TR_MUX_PAR, MASKDWORD);
+ reg874 = odm_get_bb_reg(p_dm_odm, REG_FPGA0_XCD_RF_INTERFACE_SW, MASKDWORD);
+ regc50 = odm_get_bb_reg(p_dm_odm, REG_OFDM_0_XA_AGC_CORE1, MASKDWORD);
+
+ /* Store AFE Registers */
+ if (p_dm_odm->support_ic_type & ODM_RTL8723B)
+ afe_rrx_wait_cca = odm_get_bb_reg(p_dm_odm, REG_RX_WAIT_CCA, MASKDWORD);
+
+ /* Set PSD 128 pts */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_PSD_FUNCTION, BIT(14) | BIT15, 0x0); /* 128 pts */
+
+ /* To SET CH1 to do */
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, ODM_CHANNEL, RFREGOFFSETMASK, 0x7401); /* channel 1 */
+
+ /* AFE all on step */
+ if (p_dm_odm->support_ic_type & ODM_RTL8723B)
+ odm_set_bb_reg(p_dm_odm, REG_RX_WAIT_CCA, MASKDWORD, 0x01c00016);
+
+ /* 3 wire Disable */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_ANALOG_PARAMETER4, MASKDWORD, 0xCCF000C0);
+
+ /* BB IQK setting */
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_TR_MUX_PAR, MASKDWORD, 0x000800E4);
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XCD_RF_INTERFACE_SW, MASKDWORD, 0x22208000);
+
+ /* IQK setting tone@ 4.34Mhz */
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK_TONE_A, MASKDWORD, 0x10008C1C);
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK, MASKDWORD, 0x01007c00);
+
+ /* Page B init */
+ odm_set_bb_reg(p_dm_odm, REG_CONFIG_ANT_A, MASKDWORD, 0x00080000);
+ odm_set_bb_reg(p_dm_odm, REG_CONFIG_ANT_A, MASKDWORD, 0x0f600000);
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK, MASKDWORD, 0x01004800);
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK_TONE_A, MASKDWORD, 0x10008c1f);
+ if (p_dm_odm->support_ic_type & ODM_RTL8723B) {
+ odm_set_bb_reg(p_dm_odm, REG_TX_IQK_PI_A, MASKDWORD, 0x82150016);
+ odm_set_bb_reg(p_dm_odm, REG_RX_IQK_PI_A, MASKDWORD, 0x28150016);
+ }
+ odm_set_bb_reg(p_dm_odm, REG_IQK_AGC_RSP, MASKDWORD, 0x001028d0);
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XA_AGC_CORE1, 0x7f, initial_gain);
+
+ /* IQK Single tone start */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, 0xffffff00, 0x808000);
+ odm_set_bb_reg(p_dm_odm, REG_IQK_AGC_PTS, MASKDWORD, 0xf9000000);
+ odm_set_bb_reg(p_dm_odm, REG_IQK_AGC_PTS, MASKDWORD, 0xf8000000);
+
+ odm_stall_execution(10000);
+
+ /* PSD report of antenna A */
+ PSD_report_tmp = 0x0;
+ for (n = 0; n < 2; n++) {
+ PSD_report_tmp = get_psd_data(p_dm_odm, 14, initial_gain);
+ if (PSD_report_tmp > ant_a_report)
+ ant_a_report = PSD_report_tmp;
+ }
+
+ /* change to Antenna B */
+ if (p_dm_odm->support_ic_type & ODM_RTL8723B) {
+ /* odm_set_bb_reg(p_dm_odm, REG_DPDT_CONTROL, 0x3, 0x2); */
+ odm_set_bb_reg(p_dm_odm, REG_S0_S1_PATH_SWITCH, 0xfff, 0x280);
+ odm_set_bb_reg(p_dm_odm, REG_AGC_TABLE_SELECT, BIT(31), 0x1);
+ }
+
+ odm_stall_execution(10);
+
+ /* PSD report of antenna B */
+ PSD_report_tmp = 0x0;
+ for (n = 0; n < 2; n++) {
+ PSD_report_tmp = get_psd_data(p_dm_odm, 14, initial_gain);
+ if (PSD_report_tmp > ant_b_report)
+ ant_b_report = PSD_report_tmp;
+ }
+
+ /* Close IQK Single Tone function */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_IQK, 0xffffff00, 0x000000);
+
+ /* 1 Return to antanna A */
+ if (p_dm_odm->support_ic_type & ODM_RTL8723B) {
+ /* external DPDT */
+ odm_set_bb_reg(p_dm_odm, REG_DPDT_CONTROL, MASKDWORD, reg92c);
+
+ /* internal S0/S1 */
+ odm_set_bb_reg(p_dm_odm, REG_S0_S1_PATH_SWITCH, MASKDWORD, reg948);
+ odm_set_bb_reg(p_dm_odm, REG_AGC_TABLE_SELECT, MASKDWORD, regb2c);
+ odm_set_bb_reg(p_dm_odm, rfe_ctrl_anta_src, MASKDWORD, reg930);
+ odm_set_mac_reg(p_dm_odm, REG_SYM_WLBT_PAPE_SEL, BIT(29), reg064);
+ }
+
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_ANALOG_PARAMETER4, MASKDWORD, reg88c);
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_TR_MUX_PAR, MASKDWORD, regc08);
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_XCD_RF_INTERFACE_SW, MASKDWORD, reg874);
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XA_AGC_CORE1, 0x7F, 0x40);
+ odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XA_AGC_CORE1, MASKDWORD, regc50);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, current_channel);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x00, RFREGOFFSETMASK, rf_loop_reg);
+
+ /* Reload AFE Registers */
+ if (p_dm_odm->support_ic_type & ODM_RTL8723B)
+ odm_set_bb_reg(p_dm_odm, REG_RX_WAIT_CCA, MASKDWORD, afe_rrx_wait_cca);
+
+ if (p_dm_odm->support_ic_type & ODM_RTL8723B) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_A[%d]= %d\n", 2416, ant_a_report));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_B[%d]= %d\n", 2416, ant_b_report));
+
+ /* 2 Test ant B based on ant A is ON */
+ if ((ant_a_report >= 100) && (ant_b_report >= 100) && (ant_a_report <= 135) && (ant_b_report <= 135)) {
+ u8 TH1 = 2, TH2 = 6;
+
+ if ((ant_a_report - ant_b_report < TH1) || (ant_b_report - ant_a_report < TH1)) {
+ p_dm_swat_table->ANTA_ON = true;
+ p_dm_swat_table->ANTB_ON = true;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_single_dual_antenna_detection(): Dual Antenna\n"));
+ } else if (((ant_a_report - ant_b_report >= TH1) && (ant_a_report - ant_b_report <= TH2)) ||
+ ((ant_b_report - ant_a_report >= TH1) && (ant_b_report - ant_a_report <= TH2))) {
+ p_dm_swat_table->ANTA_ON = false;
+ p_dm_swat_table->ANTB_ON = false;
+ is_result = false;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_single_dual_antenna_detection(): Need to check again\n"));
+ } else {
+ p_dm_swat_table->ANTA_ON = true;
+ p_dm_swat_table->ANTB_ON = false;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_single_dual_antenna_detection(): Single Antenna\n"));
+ }
+ p_dm_odm->ant_detected_info.is_ant_detected = true;
+ p_dm_odm->ant_detected_info.db_for_ant_a = ant_a_report;
+ p_dm_odm->ant_detected_info.db_for_ant_b = ant_b_report;
+ p_dm_odm->ant_detected_info.db_for_ant_o = ant_0_report;
+
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("return false!!\n"));
+ is_result = false;
+ }
+ }
+ return is_result;
+
+}
+
+
+
+/* 1 [2. Scan AP RSSI method] ================================================== */
+
+
+
+
+bool
+odm_sw_ant_div_check_before_link(
+ void *p_dm_void
+)
+{
+
+#if (RT_MEM_SIZE_LEVEL != RT_MEM_SIZE_MINIMUM)
+
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
+ PMGNT_INFO p_mgnt_info = &adapter->MgntInfo;
+ struct _sw_antenna_switch_ *p_dm_swat_table = &p_dm_odm->dm_swat_table;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+ s8 score = 0;
+ PRT_WLAN_BSS p_tmp_bss_desc, p_test_bss_desc;
+ u8 power_target_L = 9, power_target_H = 16;
+ u8 tmp_power_diff = 0, power_diff = 0, avg_power_diff = 0, max_power_diff = 0, min_power_diff = 0xff;
+ u16 index, counter = 0;
+ static u8 scan_channel;
+ u32 tmp_swas_no_link_bk_reg948;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ANTA_ON = (( %d )) , ANTB_ON = (( %d ))\n", p_dm_odm->dm_swat_table.ANTA_ON, p_dm_odm->dm_swat_table.ANTB_ON));
+
+ /* if(HP id) */
+ {
+ if (p_dm_odm->dm_swat_table.rssi_ant_dect_result == true && p_dm_odm->support_ic_type == ODM_RTL8723B) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("8723B RSSI-based Antenna Detection is done\n"));
+ return false;
+ }
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8723B) {
+ if (p_dm_swat_table->swas_no_link_bk_reg948 == 0xff)
+ p_dm_swat_table->swas_no_link_bk_reg948 = odm_read_4byte(p_dm_odm, REG_S0_S1_PATH_SWITCH);
+ }
+ }
+
+ if (p_dm_odm->adapter == NULL) { /* For BSOD when plug/unplug fast. //By YJ,120413 */
+ /* The ODM structure is not initialized. */
+ return false;
+ }
+
+ /* Retrieve antenna detection registry info, added by Roger, 2012.11.27. */
+ if (!IS_ANT_DETECT_SUPPORT_RSSI(adapter))
+ return false;
+ else
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Antenna Detection: RSSI method\n"));
+
+ /* Since driver is going to set BB register, it shall check if there is another thread controlling BB/RF. */
+ odm_acquire_spin_lock(p_dm_odm, RT_RF_STATE_SPINLOCK);
+ if (p_hal_data->eRFPowerState != eRfOn || p_mgnt_info->RFChangeInProgress || p_mgnt_info->bMediaConnect) {
+ odm_release_spin_lock(p_dm_odm, RT_RF_STATE_SPINLOCK);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
+ ("odm_sw_ant_div_check_before_link(): rf_change_in_progress(%x), e_rf_power_state(%x)\n",
+ p_mgnt_info->RFChangeInProgress, p_hal_data->eRFPowerState));
+
+ p_dm_swat_table->swas_no_link_state = 0;
+
+ return false;
+ } else
+ odm_release_spin_lock(p_dm_odm, RT_RF_STATE_SPINLOCK);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("p_dm_swat_table->swas_no_link_state = %d\n", p_dm_swat_table->swas_no_link_state));
+ /* 1 Run AntDiv mechanism "Before Link" part. */
+ if (p_dm_swat_table->swas_no_link_state == 0) {
+ /* 1 Prepare to do Scan again to check current antenna state. */
+
+ /* Set check state to next step. */
+ p_dm_swat_table->swas_no_link_state = 1;
+
+ /* Copy Current Scan list. */
+ p_mgnt_info->tmpNumBssDesc = p_mgnt_info->NumBssDesc;
+ PlatformMoveMemory((void *)adapter->MgntInfo.tmpbssDesc, (void *)p_mgnt_info->bssDesc, sizeof(RT_WLAN_BSS) * MAX_BSS_DESC);
+
+ /* Go back to scan function again. */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_sw_ant_div_check_before_link: Scan one more time\n"));
+ p_mgnt_info->ScanStep = 0;
+ p_mgnt_info->bScanAntDetect = true;
+ scan_channel = odm_sw_ant_div_select_scan_chnl(adapter);
+
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8188E | ODM_RTL8821)) {
+ if (p_dm_fat_table->rx_idle_ant == MAIN_ANT)
+ odm_update_rx_idle_ant(p_dm_odm, AUX_ANT);
+ else
+ odm_update_rx_idle_ant(p_dm_odm, MAIN_ANT);
+ if (scan_channel == 0) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
+ ("odm_sw_ant_div_check_before_link(): No AP List Avaiable, Using ant(%s)\n", (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? "AUX_ANT" : "MAIN_ANT"));
+
+ if (IS_5G_WIRELESS_MODE(p_mgnt_info->dot11CurrentWirelessMode)) {
+ p_dm_swat_table->ant_5g = p_dm_fat_table->rx_idle_ant;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("p_dm_swat_table->ant_5g=%s\n", (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"));
+ } else {
+ p_dm_swat_table->ant_2g = p_dm_fat_table->rx_idle_ant;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("p_dm_swat_table->ant_2g=%s\n", (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"));
+ }
+ return false;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
+ ("odm_sw_ant_div_check_before_link: Change to %s for testing.\n", ((p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT")));
+ } else if (p_dm_odm->support_ic_type & (ODM_RTL8723B)) {
+ /*Switch Antenna to another one.*/
+
+ tmp_swas_no_link_bk_reg948 = odm_read_4byte(p_dm_odm, REG_S0_S1_PATH_SWITCH);
+
+ if ((p_dm_swat_table->cur_antenna == MAIN_ANT) && (tmp_swas_no_link_bk_reg948 == 0x200)) {
+ odm_set_bb_reg(p_dm_odm, REG_S0_S1_PATH_SWITCH, 0xfff, 0x280);
+ odm_set_bb_reg(p_dm_odm, REG_AGC_TABLE_SELECT, BIT(31), 0x1);
+ p_dm_swat_table->cur_antenna = AUX_ANT;
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Reg[948]= (( %x )) was in wrong state\n", tmp_swas_no_link_bk_reg948));
+ return false;
+ }
+ odm_stall_execution(10);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_sw_ant_div_check_before_link: Change to (( %s-ant)) for testing.\n", (p_dm_swat_table->cur_antenna == MAIN_ANT) ? "MAIN" : "AUX"));
+ }
+
+ odm_sw_ant_div_construct_scan_chnl(adapter, scan_channel);
+ PlatformSetTimer(adapter, &p_mgnt_info->ScanTimer, 5);
+
+ return true;
+ } else { /* p_dm_swat_table->swas_no_link_state == 1 */
+ /* 1 ScanComple() is called after antenna swiched. */
+ /* 1 Check scan result and determine which antenna is going */
+ /* 1 to be used. */
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" tmp_num_bss_desc= (( %d ))\n", p_mgnt_info->tmpNumBssDesc)); /* debug for Dino */
+
+ for (index = 0; index < p_mgnt_info->tmpNumBssDesc; index++) {
+ p_tmp_bss_desc = &(p_mgnt_info->tmpbssDesc[index]); /* Antenna 1 */
+ p_test_bss_desc = &(p_mgnt_info->bssDesc[index]); /* Antenna 2 */
+
+ if (PlatformCompareMemory(p_test_bss_desc->bdBssIdBuf, p_tmp_bss_desc->bdBssIdBuf, 6) != 0) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_sw_ant_div_check_before_link(): ERROR!! This shall not happen.\n"));
+ continue;
+ }
+
+ if (p_dm_odm->support_ic_type != ODM_RTL8723B) {
+ if (p_tmp_bss_desc->ChannelNumber == scan_channel) {
+ if (p_tmp_bss_desc->RecvSignalPower > p_test_bss_desc->RecvSignalPower) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_sw_ant_div_check_before_link: Compare scan entry: score++\n"));
+ RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", p_tmp_bss_desc->bdSsIdBuf, p_tmp_bss_desc->bdSsIdLen);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("at ch %d, Original: %d, Test: %d\n\n", p_tmp_bss_desc->ChannelNumber, p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower));
+
+ score++;
+ PlatformMoveMemory(p_test_bss_desc, p_tmp_bss_desc, sizeof(RT_WLAN_BSS));
+ } else if (p_tmp_bss_desc->RecvSignalPower < p_test_bss_desc->RecvSignalPower) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_sw_ant_div_check_before_link: Compare scan entry: score--\n"));
+ RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", p_tmp_bss_desc->bdSsIdBuf, p_tmp_bss_desc->bdSsIdLen);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("at ch %d, Original: %d, Test: %d\n\n", p_tmp_bss_desc->ChannelNumber, p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower));
+ score--;
+ } else {
+ if (p_test_bss_desc->bdTstamp - p_tmp_bss_desc->bdTstamp < 5000) {
+ RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", p_tmp_bss_desc->bdSsIdBuf, p_tmp_bss_desc->bdSsIdLen);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("at ch %d, Original: %d, Test: %d\n", p_tmp_bss_desc->ChannelNumber, p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("The 2nd Antenna didn't get this AP\n\n"));
+ }
+ }
+ }
+ } else { /* 8723B */
+ if (p_tmp_bss_desc->ChannelNumber == scan_channel) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("channel_number == scan_channel->(( %d ))\n", p_tmp_bss_desc->ChannelNumber));
+
+ if (p_tmp_bss_desc->RecvSignalPower > p_test_bss_desc->RecvSignalPower) { /* Pow(Ant1) > Pow(Ant2) */
+ counter++;
+ tmp_power_diff = (u8)(p_tmp_bss_desc->RecvSignalPower - p_test_bss_desc->RecvSignalPower);
+ power_diff = power_diff + tmp_power_diff;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Original: %d, Test: %d\n", p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower));
+ ODM_PRINT_ADDR(p_dm_odm, ODM_COMP_ANT_DIV, DBG_LOUD, ("SSID:"), p_tmp_bss_desc->bdSsIdBuf);
+ ODM_PRINT_ADDR(p_dm_odm, ODM_COMP_ANT_DIV, DBG_LOUD, ("BSSID:"), p_tmp_bss_desc->bdSsIdBuf);
+
+ /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("tmp_power_diff: (( %d)),max_power_diff: (( %d)),min_power_diff: (( %d))\n", tmp_power_diff,max_power_diff,min_power_diff)); */
+ if (tmp_power_diff > max_power_diff)
+ max_power_diff = tmp_power_diff;
+ if (tmp_power_diff < min_power_diff)
+ min_power_diff = tmp_power_diff;
+ /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("max_power_diff: (( %d)),min_power_diff: (( %d))\n",max_power_diff,min_power_diff)); */
+
+ PlatformMoveMemory(p_test_bss_desc, p_tmp_bss_desc, sizeof(RT_WLAN_BSS));
+ } else if (p_test_bss_desc->RecvSignalPower > p_tmp_bss_desc->RecvSignalPower) { /* Pow(Ant1) < Pow(Ant2) */
+ counter++;
+ tmp_power_diff = (u8)(p_test_bss_desc->RecvSignalPower - p_tmp_bss_desc->RecvSignalPower);
+ power_diff = power_diff + tmp_power_diff;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Original: %d, Test: %d\n", p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower));
+ ODM_PRINT_ADDR(p_dm_odm, ODM_COMP_ANT_DIV, DBG_LOUD, ("SSID:"), p_tmp_bss_desc->bdSsIdBuf);
+ ODM_PRINT_ADDR(p_dm_odm, ODM_COMP_ANT_DIV, DBG_LOUD, ("BSSID:"), p_tmp_bss_desc->bdSsIdBuf);
+ if (tmp_power_diff > max_power_diff)
+ max_power_diff = tmp_power_diff;
+ if (tmp_power_diff < min_power_diff)
+ min_power_diff = tmp_power_diff;
+ } else { /* Pow(Ant1) = Pow(Ant2) */
+ if (p_test_bss_desc->bdTstamp > p_tmp_bss_desc->bdTstamp) { /* Stamp(Ant1) < Stamp(Ant2) */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("time_diff: %lld\n", (p_test_bss_desc->bdTstamp - p_tmp_bss_desc->bdTstamp) / 1000));
+ if (p_test_bss_desc->bdTstamp - p_tmp_bss_desc->bdTstamp > 5000) {
+ counter++;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Original: %d, Test: %d\n", p_tmp_bss_desc->RecvSignalPower, p_test_bss_desc->RecvSignalPower));
+ ODM_PRINT_ADDR(p_dm_odm, ODM_COMP_ANT_DIV, DBG_LOUD, ("SSID:"), p_tmp_bss_desc->bdSsIdBuf);
+ ODM_PRINT_ADDR(p_dm_odm, ODM_COMP_ANT_DIV, DBG_LOUD, ("BSSID:"), p_tmp_bss_desc->bdSsIdBuf);
+ min_power_diff = 0;
+ }
+ } else
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Error !!!]: Time_diff: %lld\n", (p_test_bss_desc->bdTstamp - p_tmp_bss_desc->bdTstamp) / 1000));
+ }
+ }
+ }
+ }
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8188E | ODM_RTL8821)) {
+ if (p_mgnt_info->NumBssDesc != 0 && score < 0) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
+ ("odm_sw_ant_div_check_before_link(): Using ant(%s)\n", (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"));
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
+ ("odm_sw_ant_div_check_before_link(): Remain ant(%s)\n", (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? "AUX_ANT" : "MAIN_ANT"));
+
+ if (p_dm_fat_table->rx_idle_ant == MAIN_ANT)
+ odm_update_rx_idle_ant(p_dm_odm, AUX_ANT);
+ else
+ odm_update_rx_idle_ant(p_dm_odm, MAIN_ANT);
+ }
+
+ if (IS_5G_WIRELESS_MODE(p_mgnt_info->dot11CurrentWirelessMode)) {
+ p_dm_swat_table->ant_5g = p_dm_fat_table->rx_idle_ant;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("p_dm_swat_table->ant_5g=%s\n", (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"));
+ } else {
+ p_dm_swat_table->ant_2g = p_dm_fat_table->rx_idle_ant;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("p_dm_swat_table->ant_2g=%s\n", (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"));
+ }
+ } else if (p_dm_odm->support_ic_type == ODM_RTL8723B) {
+ if (counter == 0) {
+ if (p_dm_odm->dm_swat_table.pre_aux_fail_detec == false) {
+ p_dm_odm->dm_swat_table.pre_aux_fail_detec = true;
+ p_dm_odm->dm_swat_table.rssi_ant_dect_result = false;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("counter=(( 0 )) , [[ Cannot find any AP with Aux-ant ]] -> Scan Target-channel again\n"));
+
+ /* 3 [ Scan again ] */
+ odm_sw_ant_div_construct_scan_chnl(adapter, scan_channel);
+ PlatformSetTimer(adapter, &p_mgnt_info->ScanTimer, 5);
+ return true;
+ } else { /* pre_aux_fail_detec == true */
+ /* 2 [ Single Antenna ] */
+ p_dm_odm->dm_swat_table.pre_aux_fail_detec = false;
+ p_dm_odm->dm_swat_table.rssi_ant_dect_result = true;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("counter=(( 0 )) , [[ Still cannot find any AP ]]\n"));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_sw_ant_div_check_before_link(): Single antenna\n"));
+ }
+ p_dm_odm->dm_swat_table.aux_fail_detec_counter++;
+ } else {
+ p_dm_odm->dm_swat_table.pre_aux_fail_detec = false;
+
+ if (counter == 3) {
+ avg_power_diff = ((power_diff - max_power_diff - min_power_diff) >> 1) + ((max_power_diff + min_power_diff) >> 2);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("counter: (( %d )) , power_diff: (( %d ))\n", counter, power_diff));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ counter==3 ] Modified avg_power_diff: (( %d )) , max_power_diff: (( %d )) , min_power_diff: (( %d ))\n", avg_power_diff, max_power_diff, min_power_diff));
+ } else if (counter >= 4) {
+ avg_power_diff = (power_diff - max_power_diff - min_power_diff) / (counter - 2);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("counter: (( %d )) , power_diff: (( %d ))\n", counter, power_diff));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ counter>=4 ] Modified avg_power_diff: (( %d )) , max_power_diff: (( %d )) , min_power_diff: (( %d ))\n", avg_power_diff, max_power_diff, min_power_diff));
+
+ } else { /* counter==1,2 */
+ avg_power_diff = power_diff / counter;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("avg_power_diff: (( %d )) , counter: (( %d )) , power_diff: (( %d ))\n", avg_power_diff, counter, power_diff));
+ }
+
+ /* 2 [ Retry ] */
+ if ((avg_power_diff >= power_target_L) && (avg_power_diff <= power_target_H)) {
+ p_dm_odm->dm_swat_table.retry_counter++;
+
+ if (p_dm_odm->dm_swat_table.retry_counter <= 3) {
+ p_dm_odm->dm_swat_table.rssi_ant_dect_result = false;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[[ Low confidence result ]] avg_power_diff= (( %d )) -> Scan Target-channel again ]]\n", avg_power_diff));
+
+ /* 3 [ Scan again ] */
+ odm_sw_ant_div_construct_scan_chnl(adapter, scan_channel);
+ PlatformSetTimer(adapter, &p_mgnt_info->ScanTimer, 5);
+ return true;
+ } else {
+ p_dm_odm->dm_swat_table.rssi_ant_dect_result = true;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[[ Still Low confidence result ]] (( retry_counter > 3 ))\n"));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_sw_ant_div_check_before_link(): Single antenna\n"));
+ }
+
+ }
+ /* 2 [ Dual Antenna ] */
+ else if ((p_mgnt_info->NumBssDesc != 0) && (avg_power_diff < power_target_L)) {
+ p_dm_odm->dm_swat_table.rssi_ant_dect_result = true;
+ if (p_dm_odm->dm_swat_table.ANTB_ON == false) {
+ p_dm_odm->dm_swat_table.ANTA_ON = true;
+ p_dm_odm->dm_swat_table.ANTB_ON = true;
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_sw_ant_div_check_before_link(): Dual antenna\n"));
+ p_dm_odm->dm_swat_table.dual_ant_counter++;
+
+ /* set bt coexDM from 1ant coexDM to 2ant coexDM */
+ BT_SetBtCoexAntNum(adapter, BT_COEX_ANT_TYPE_DETECTED, 2);
+
+ /* 3 [ Init antenna diversity ] */
+ p_dm_odm->support_ability |= ODM_BB_ANT_DIV;
+ odm_ant_div_init(p_dm_odm);
+ }
+ /* 2 [ Single Antenna ] */
+ else if (avg_power_diff > power_target_H) {
+ p_dm_odm->dm_swat_table.rssi_ant_dect_result = true;
+ if (p_dm_odm->dm_swat_table.ANTB_ON == true) {
+ p_dm_odm->dm_swat_table.ANTA_ON = true;
+ p_dm_odm->dm_swat_table.ANTB_ON = false;
+ /* bt_set_bt_coex_ant_num(adapter, BT_COEX_ANT_TYPE_DETECTED, 1); */
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_sw_ant_div_check_before_link(): Single antenna\n"));
+ p_dm_odm->dm_swat_table.single_ant_counter++;
+ }
+ }
+ /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("is_result=(( %d ))\n",p_dm_odm->dm_swat_table.rssi_ant_dect_result)); */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("dual_ant_counter = (( %d )), single_ant_counter = (( %d )) , retry_counter = (( %d )) , aux_fail_detec_counter = (( %d ))\n\n\n",
+ p_dm_odm->dm_swat_table.dual_ant_counter, p_dm_odm->dm_swat_table.single_ant_counter, p_dm_odm->dm_swat_table.retry_counter, p_dm_odm->dm_swat_table.aux_fail_detec_counter));
+
+ /* 2 recover the antenna setting */
+
+ if (p_dm_odm->dm_swat_table.ANTB_ON == false)
+ odm_set_bb_reg(p_dm_odm, REG_S0_S1_PATH_SWITCH, 0xfff, (p_dm_swat_table->swas_no_link_bk_reg948));
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("is_result=(( %d )), Recover Reg[948]= (( %x )) \n\n", p_dm_odm->dm_swat_table.rssi_ant_dect_result, p_dm_swat_table->swas_no_link_bk_reg948));
+
+
+ }
+
+ /* Check state reset to default and wait for next time. */
+ p_dm_swat_table->swas_no_link_state = 0;
+ p_mgnt_info->bScanAntDetect = false;
+
+ return false;
+ }
+
+#else
+ return false;
+#endif
+
+ return false;
+}
+
+
+
+
+
+
+/* 1 [3. PSD method] ========================================================== */
+
+
+
+
+u32
+odm_get_psd_data(
+ void *p_dm_void,
+ u16 point,
+ u8 initial_gain)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 psd_report;
+
+ odm_set_bb_reg(p_dm_odm, 0x808, 0x3FF, point);
+ odm_set_bb_reg(p_dm_odm, 0x808, BIT(22), 1); /* Start PSD calculation, Reg808[22]=0->1 */
+ odm_stall_execution(150);/* Wait for HW PSD report */
+ odm_set_bb_reg(p_dm_odm, 0x808, BIT(22), 0);/* Stop PSD calculation, Reg808[22]=1->0 */
+ psd_report = odm_get_bb_reg(p_dm_odm, 0x8B4, MASKDWORD) & 0x0000FFFF; /* Read PSD report, Reg8B4[15:0] */
+
+ psd_report = (u32)(odm_convert_to_db(psd_report)); /* +(u32)(initial_gain); */
+ return psd_report;
+}
+
+
+
+void
+odm_single_dual_antenna_detection_psd(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 channel_ori;
+ u8 initial_gain = 0x36;
+ u8 tone_idx;
+ u8 tone_lenth_1 = 7, tone_lenth_2 = 4;
+ u16 tone_idx_1[7] = {88, 104, 120, 8, 24, 40, 56};
+ u16 tone_idx_2[4] = {8, 24, 40, 56};
+ u32 psd_report_main[11] = {0}, psd_report_aux[11] = {0};
+ /* u8 tone_lenth_1=4, tone_lenth_2=2; */
+ /* u16 tone_idx_1[4]={88, 120, 24, 56}; */
+ /* u16 tone_idx_2[2]={ 24, 56}; */
+ /* u32 psd_report_main[6]={0}, psd_report_aux[6]={0}; */
+
+ u32 PSD_report_temp, max_psd_report_main = 0, max_psd_report_aux = 0;
+ u32 PSD_power_threshold;
+ u32 main_psd_result = 0, aux_psd_result = 0;
+ u32 regc50, reg948, regb2c, regc14, reg908;
+ u32 i = 0, test_num = 8;
+
+
+ if (p_dm_odm->support_ic_type != ODM_RTL8723B)
+ return;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_single_dual_antenna_detection_psd()============>\n"));
+
+ /* 2 [ Backup Current RF/BB Settings ] */
+
+ channel_ori = odm_get_rf_reg(p_dm_odm, ODM_RF_PATH_A, ODM_CHANNEL, RFREGOFFSETMASK);
+ reg948 = odm_get_bb_reg(p_dm_odm, REG_S0_S1_PATH_SWITCH, MASKDWORD);
+ regb2c = odm_get_bb_reg(p_dm_odm, REG_AGC_TABLE_SELECT, MASKDWORD);
+ regc50 = odm_get_bb_reg(p_dm_odm, REG_OFDM_0_XA_AGC_CORE1, MASKDWORD);
+ regc14 = odm_get_bb_reg(p_dm_odm, 0xc14, MASKDWORD);
+ reg908 = odm_get_bb_reg(p_dm_odm, 0x908, MASKDWORD);
+
+ /* 2 [ setting for doing PSD function (CH4)] */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_RFMOD, BIT(24), 0); /* disable whole CCK block */
+ odm_write_1byte(p_dm_odm, REG_TXPAUSE, 0xFF); /* Turn off TX -> Pause TX Queue */
+ odm_set_bb_reg(p_dm_odm, 0xC14, MASKDWORD, 0x0); /* [ Set IQK Matrix = 0 ] equivalent to [ Turn off CCA] */
+
+ /* PHYTXON while loop */
+ odm_set_bb_reg(p_dm_odm, 0x908, MASKDWORD, 0x803);
+ while (odm_get_bb_reg(p_dm_odm, 0xdf4, BIT(6))) {
+ i++;
+ if (i > 1000000) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Wait in %s() more than %d times!\n", __func__, i));
+ break;
+ }
+ }
+
+ odm_set_bb_reg(p_dm_odm, 0xc50, 0x7f, initial_gain);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, ODM_CHANNEL, 0x7ff, 0x04); /* Set RF to CH4 & 40M */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_ANALOG_PARAMETER4, 0xf00000, 0xf); /* 3 wire Disable 88c[23:20]=0xf */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_PSD_FUNCTION, BIT(14) | BIT15, 0x0); /* 128 pt */ /* Set PSD 128 ptss */
+ odm_stall_execution(3000);
+
+
+ /* 2 [ Doing PSD Function in (CH4)] */
+
+ /* Antenna A */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Switch to Main-ant (CH4)\n"));
+ odm_set_bb_reg(p_dm_odm, 0x948, 0xfff, 0x200);
+ odm_stall_execution(10);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("dbg\n"));
+ for (i = 0; i < test_num; i++) {
+ for (tone_idx = 0; tone_idx < tone_lenth_1; tone_idx++) {
+ PSD_report_temp = odm_get_psd_data(p_dm_odm, tone_idx_1[tone_idx], initial_gain);
+ /* if( PSD_report_temp>psd_report_main[tone_idx] ) */
+ psd_report_main[tone_idx] += PSD_report_temp;
+ }
+ }
+ /* Antenna B */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Switch to Aux-ant (CH4)\n"));
+ odm_set_bb_reg(p_dm_odm, 0x948, 0xfff, 0x280);
+ odm_stall_execution(10);
+ for (i = 0; i < test_num; i++) {
+ for (tone_idx = 0; tone_idx < tone_lenth_1; tone_idx++) {
+ PSD_report_temp = odm_get_psd_data(p_dm_odm, tone_idx_1[tone_idx], initial_gain);
+ /* if( PSD_report_temp>psd_report_aux[tone_idx] ) */
+ psd_report_aux[tone_idx] += PSD_report_temp;
+ }
+ }
+ /* 2 [ Doing PSD Function in (CH8)] */
+
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_ANALOG_PARAMETER4, 0xf00000, 0x0); /* 3 wire enable 88c[23:20]=0x0 */
+ odm_stall_execution(3000);
+
+ odm_set_bb_reg(p_dm_odm, 0xc50, 0x7f, initial_gain);
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, ODM_CHANNEL, 0x7ff, 0x04); /* Set RF to CH8 & 40M */
+
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_ANALOG_PARAMETER4, 0xf00000, 0xf); /* 3 wire Disable 88c[23:20]=0xf */
+ odm_stall_execution(3000);
+
+ /* Antenna A */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Switch to Main-ant (CH8)\n"));
+ odm_set_bb_reg(p_dm_odm, 0x948, 0xfff, 0x200);
+ odm_stall_execution(10);
+
+ for (i = 0; i < test_num; i++) {
+ for (tone_idx = 0; tone_idx < tone_lenth_2; tone_idx++) {
+ PSD_report_temp = odm_get_psd_data(p_dm_odm, tone_idx_2[tone_idx], initial_gain);
+ /* if( PSD_report_temp>psd_report_main[tone_idx] ) */
+ psd_report_main[tone_lenth_1 + tone_idx] += PSD_report_temp;
+ }
+ }
+
+ /* Antenna B */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Switch to Aux-ant (CH8)\n"));
+ odm_set_bb_reg(p_dm_odm, 0x948, 0xfff, 0x280);
+ odm_stall_execution(10);
+
+ for (i = 0; i < test_num; i++) {
+ for (tone_idx = 0; tone_idx < tone_lenth_2; tone_idx++) {
+ PSD_report_temp = odm_get_psd_data(p_dm_odm, tone_idx_2[tone_idx], initial_gain);
+ /* if( PSD_report_temp>psd_report_aux[tone_idx] ) */
+ psd_report_aux[tone_lenth_1 + tone_idx] += PSD_report_temp;
+ }
+ }
+
+ /* 2 [ Calculate Result ] */
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("\nMain PSD Result: (ALL)\n"));
+ for (tone_idx = 0; tone_idx < (tone_lenth_1 + tone_lenth_2); tone_idx++) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Tone-%d]: %d,\n", (tone_idx + 1), psd_report_main[tone_idx]));
+ main_psd_result += psd_report_main[tone_idx];
+ if (psd_report_main[tone_idx] > max_psd_report_main)
+ max_psd_report_main = psd_report_main[tone_idx];
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("--------------------------- \nTotal_Main= (( %d ))\n", main_psd_result));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("MAX_Main = (( %d ))\n", max_psd_report_main));
+
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("\nAux PSD Result: (ALL)\n"));
+ for (tone_idx = 0; tone_idx < (tone_lenth_1 + tone_lenth_2); tone_idx++) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Tone-%d]: %d,\n", (tone_idx + 1), psd_report_aux[tone_idx]));
+ aux_psd_result += psd_report_aux[tone_idx];
+ if (psd_report_aux[tone_idx] > max_psd_report_aux)
+ max_psd_report_aux = psd_report_aux[tone_idx];
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("--------------------------- \nTotal_Aux= (( %d ))\n", aux_psd_result));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("MAX_Aux = (( %d ))\n\n", max_psd_report_aux));
+
+ /* main_psd_result=main_psd_result-max_psd_report_main; */
+ /* aux_psd_result=aux_psd_result-max_psd_report_aux; */
+ PSD_power_threshold = (main_psd_result * 7) >> 3;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Main_result, Aux_result ] = [ %d , %d ], PSD_power_threshold=(( %d ))\n", main_psd_result, aux_psd_result, PSD_power_threshold));
+
+ /* 3 [ Dual Antenna ] */
+ if (aux_psd_result >= PSD_power_threshold) {
+ if (p_dm_odm->dm_swat_table.ANTB_ON == false) {
+ p_dm_odm->dm_swat_table.ANTA_ON = true;
+ p_dm_odm->dm_swat_table.ANTB_ON = true;
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_sw_ant_div_check_before_link(): Dual antenna\n"));
+
+ /* set bt coexDM from 1ant coexDM to 2ant coexDM */
+ /* bt_set_bt_coex_ant_num(p_adapter, BT_COEX_ANT_TYPE_DETECTED, 2); */
+
+ /* Init antenna diversity */
+ p_dm_odm->support_ability |= ODM_BB_ANT_DIV;
+ odm_ant_div_init(p_dm_odm);
+ }
+ /* 3 [ Single Antenna ] */
+ else {
+ if (p_dm_odm->dm_swat_table.ANTB_ON == true) {
+ p_dm_odm->dm_swat_table.ANTA_ON = true;
+ p_dm_odm->dm_swat_table.ANTB_ON = false;
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_sw_ant_div_check_before_link(): Single antenna\n"));
+ }
+
+ /* 2 [ Recover all parameters ] */
+
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, channel_ori);
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_ANALOG_PARAMETER4, 0xf00000, 0x0); /* 3 wire enable 88c[23:20]=0x0 */
+ odm_set_bb_reg(p_dm_odm, 0xc50, 0x7f, regc50);
+
+ odm_set_bb_reg(p_dm_odm, REG_S0_S1_PATH_SWITCH, MASKDWORD, reg948);
+ odm_set_bb_reg(p_dm_odm, REG_AGC_TABLE_SELECT, MASKDWORD, regb2c);
+
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_RFMOD, BIT(24), 1); /* enable whole CCK block */
+ odm_write_1byte(p_dm_odm, REG_TXPAUSE, 0x0); /* Turn on TX */ /* Resume TX Queue */
+ odm_set_bb_reg(p_dm_odm, 0xC14, MASKDWORD, regc14); /* [ Set IQK Matrix = 0 ] equivalent to [ Turn on CCA] */
+ odm_set_bb_reg(p_dm_odm, 0x908, MASKDWORD, reg908);
+
+ return;
+
+}
+
+#endif
+void
+odm_sw_ant_detect_init(
+ void *p_dm_void
+)
+{
+#if (defined(CONFIG_ANT_DETECTION))
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _sw_antenna_switch_ *p_dm_swat_table = &p_dm_odm->dm_swat_table;
+
+ /* p_dm_swat_table->pre_antenna = MAIN_ANT; */
+ /* p_dm_swat_table->cur_antenna = MAIN_ANT; */
+ p_dm_swat_table->swas_no_link_state = 0;
+ p_dm_swat_table->pre_aux_fail_detec = false;
+ p_dm_swat_table->swas_no_link_bk_reg948 = 0xff;
+#endif
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_antdect.h b/drivers/staging/rtl8188eu/hal/phydm_antdect.h
new file mode 100644
index 000000000000..fcfab48cf1d6
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_antdect.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMANTDECT_H__
+#define __PHYDMANTDECT_H__
+
+#define ANTDECT_VERSION "2.1" /*2015.07.29 by YuChen*/
+
+#if (defined(CONFIG_ANT_DETECTION))
+/* ANT Test */
+#define ANTTESTALL 0x00 /*ant A or B will be Testing*/
+#define ANTTESTA 0x01 /*ant A will be Testing*/
+#define ANTTESTB 0x02 /*ant B will be testing*/
+
+#define MAX_ANTENNA_DETECTION_CNT 10
+
+
+struct _ANT_DETECTED_INFO {
+ bool is_ant_detected;
+ u32 db_for_ant_a;
+ u32 db_for_ant_b;
+ u32 db_for_ant_o;
+};
+
+
+enum dm_swas_e {
+ antenna_a = 1,
+ antenna_b = 2,
+ antenna_max = 3,
+};
+
+
+
+/* 1 [1. Single Tone method] =================================================== */
+
+
+
+void
+odm_single_dual_antenna_default_setting(
+ void *p_dm_void
+);
+
+bool
+odm_single_dual_antenna_detection(
+ void *p_dm_void,
+ u8 mode
+);
+
+/* 1 [2. Scan AP RSSI method] ================================================== */
+
+#define sw_ant_div_check_before_link odm_sw_ant_div_check_before_link
+
+bool
+odm_sw_ant_div_check_before_link(
+ void *p_dm_void
+);
+
+
+
+
+/* 1 [3. PSD method] ========================================================== */
+
+
+void
+odm_single_dual_antenna_detection_psd(
+ void *p_dm_void
+);
+
+#endif
+
+void
+odm_sw_ant_detect_init(
+ void *p_dm_void
+);
+
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_antdiv.c b/drivers/staging/rtl8188eu/hal/phydm_antdiv.c
new file mode 100644
index 000000000000..92d213b84482
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_antdiv.c
@@ -0,0 +1,3194 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+/* ******************************************************
+ * when antenna test utility is on or some testing need to disable antenna diversity
+ * call this function to disable all ODM related mechanisms which will switch antenna.
+ * ****************************************************** */
+void
+odm_stop_antenna_switch_dm(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ /* disable ODM antenna diversity */
+ p_dm_odm->support_ability &= ~ODM_BB_ANT_DIV;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("STOP Antenna Diversity\n"));
+}
+
+void
+phydm_enable_antenna_diversity(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ p_dm_odm->support_ability |= ODM_BB_ANT_DIV;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("AntDiv is enabled & Re-Init AntDiv\n"));
+ odm_antenna_diversity_init(p_dm_odm);
+}
+
+void
+odm_set_ant_config(
+ void *p_dm_void,
+ u8 ant_setting /* 0=A, 1=B, 2=C, .... */
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ if (p_dm_odm->support_ic_type == ODM_RTL8723B) {
+ if (ant_setting == 0) /* ant A*/
+ odm_set_bb_reg(p_dm_odm, 0x948, MASKDWORD, 0x00000000);
+ else if (ant_setting == 1)
+ odm_set_bb_reg(p_dm_odm, 0x948, MASKDWORD, 0x00000280);
+ } else if (p_dm_odm->support_ic_type == ODM_RTL8723D) {
+ if (ant_setting == 0) /* ant A*/
+ odm_set_bb_reg(p_dm_odm, 0x948, MASKLWORD, 0x0000);
+ else if (ant_setting == 1)
+ odm_set_bb_reg(p_dm_odm, 0x948, MASKLWORD, 0x0280);
+ }
+}
+
+/* ****************************************************** */
+
+
+void
+odm_sw_ant_div_rest_after_link(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _sw_antenna_switch_ *p_dm_swat_table = &p_dm_odm->dm_swat_table;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+ u32 i;
+
+ if (p_dm_odm->ant_div_type == S0S1_SW_ANTDIV) {
+
+ p_dm_swat_table->try_flag = SWAW_STEP_INIT;
+ p_dm_swat_table->rssi_trying = 0;
+ p_dm_swat_table->double_chk_flag = 0;
+
+ p_dm_fat_table->rx_idle_ant = MAIN_ANT;
+
+#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))
+ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++)
+ phydm_antdiv_reset_statistic(p_dm_odm, i);
+#endif
+
+
+ }
+}
+
+
+#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))
+void
+phydm_antdiv_reset_statistic(
+ void *p_dm_void,
+ u32 macid
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+
+ p_dm_fat_table->main_ant_sum[macid] = 0;
+ p_dm_fat_table->aux_ant_sum[macid] = 0;
+ p_dm_fat_table->main_ant_cnt[macid] = 0;
+ p_dm_fat_table->aux_ant_cnt[macid] = 0;
+ p_dm_fat_table->main_ant_sum_cck[macid] = 0;
+ p_dm_fat_table->aux_ant_sum_cck[macid] = 0;
+ p_dm_fat_table->main_ant_cnt_cck[macid] = 0;
+ p_dm_fat_table->aux_ant_cnt_cck[macid] = 0;
+}
+
+void
+odm_ant_div_on_off(
+ void *p_dm_void,
+ u8 swch
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+
+ if (p_dm_fat_table->ant_div_on_off != swch) {
+ if (p_dm_odm->ant_div_type == S0S1_SW_ANTDIV)
+ return;
+
+ if (p_dm_odm->support_ic_type & ODM_N_ANTDIV_SUPPORT) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("(( Turn %s )) N-Series HW-AntDiv block\n", (swch == ANTDIV_ON) ? "ON" : "OFF"));
+ odm_set_bb_reg(p_dm_odm, 0xc50, BIT(7), swch);
+ odm_set_bb_reg(p_dm_odm, 0xa00, BIT(15), swch);
+
+ } else if (p_dm_odm->support_ic_type & ODM_AC_ANTDIV_SUPPORT) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("(( Turn %s )) AC-Series HW-AntDiv block\n", (swch == ANTDIV_ON) ? "ON" : "OFF"));
+ if (p_dm_odm->support_ic_type & (ODM_RTL8812 | ODM_RTL8822B)) {
+ odm_set_bb_reg(p_dm_odm, 0xc50, BIT(7), swch); /* OFDM AntDiv function block enable */
+ odm_set_bb_reg(p_dm_odm, 0xa00, BIT(15), swch); /* CCK AntDiv function block enable */
+ } else {
+ odm_set_bb_reg(p_dm_odm, 0x8D4, BIT(24), swch); /* OFDM AntDiv function block enable */
+
+ if ((p_dm_odm->cut_version >= ODM_CUT_C) && (p_dm_odm->support_ic_type == ODM_RTL8821) && (p_dm_odm->ant_div_type != S0S1_SW_ANTDIV)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("(( Turn %s )) CCK HW-AntDiv block\n", (swch == ANTDIV_ON) ? "ON" : "OFF"));
+ odm_set_bb_reg(p_dm_odm, 0x800, BIT(25), swch);
+ odm_set_bb_reg(p_dm_odm, 0xA00, BIT(15), swch); /* CCK AntDiv function block enable */
+ } else if (p_dm_odm->support_ic_type == ODM_RTL8821C) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("(( Turn %s )) CCK HW-AntDiv block\n", (swch == ANTDIV_ON) ? "ON" : "OFF"));
+ odm_set_bb_reg(p_dm_odm, 0x800, BIT(25), swch);
+ odm_set_bb_reg(p_dm_odm, 0xA00, BIT(15), swch); /* CCK AntDiv function block enable */
+ }
+ }
+ }
+ }
+ p_dm_fat_table->ant_div_on_off = swch;
+
+}
+
+void
+phydm_fast_training_enable(
+ void *p_dm_void,
+ u8 swch
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 enable;
+
+ if (swch == FAT_ON)
+ enable = 1;
+ else
+ enable = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Fast ant Training_en = ((%d))\n", enable));
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E) {
+ odm_set_bb_reg(p_dm_odm, 0xe08, BIT(16), enable); /*enable fast training*/
+ /**/
+ } else if (p_dm_odm->support_ic_type == ODM_RTL8192E) {
+ odm_set_bb_reg(p_dm_odm, 0xB34, BIT(28), enable); /*enable fast training (path-A)*/
+ /*odm_set_bb_reg(p_dm_odm, 0xB34, BIT(29), enable);*/ /*enable fast training (path-B)*/
+ } else if (p_dm_odm->support_ic_type & (ODM_RTL8821 | ODM_RTL8822B)) {
+ odm_set_bb_reg(p_dm_odm, 0x900, BIT(19), enable); /*enable fast training */
+ /**/
+ }
+}
+
+void
+phydm_keep_rx_ack_ant_by_tx_ant_time(
+ void *p_dm_void,
+ u32 time
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ /* Timming issue: keep Rx ant after tx for ACK ( time x 3.2 mu sec)*/
+ if (p_dm_odm->support_ic_type & ODM_N_ANTDIV_SUPPORT) {
+
+ odm_set_bb_reg(p_dm_odm, 0xE20, BIT(23) | BIT(22) | BIT(21) | BIT(20), time);
+ /**/
+ } else if (p_dm_odm->support_ic_type & ODM_AC_ANTDIV_SUPPORT) {
+
+ odm_set_bb_reg(p_dm_odm, 0x818, BIT(23) | BIT(22) | BIT(21) | BIT(20), time);
+ /**/
+ }
+}
+
+void
+odm_tx_by_tx_desc_or_reg(
+ void *p_dm_void,
+ u8 swch
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+ u8 enable;
+
+ if (p_dm_fat_table->b_fix_tx_ant == NO_FIX_TX_ANT)
+ enable = (swch == TX_BY_DESC) ? 1 : 0;
+ else
+ enable = 0;/*Force TX by Reg*/
+
+ if (p_dm_odm->ant_div_type != CGCS_RX_HW_ANTDIV) {
+ if (p_dm_odm->support_ic_type & ODM_N_ANTDIV_SUPPORT)
+ odm_set_bb_reg(p_dm_odm, 0x80c, BIT(21), enable);
+ else if (p_dm_odm->support_ic_type & ODM_AC_ANTDIV_SUPPORT)
+ odm_set_bb_reg(p_dm_odm, 0x900, BIT(18), enable);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[AntDiv] TX_Ant_BY (( %s ))\n", (enable == TX_BY_DESC) ? "DESC" : "REG"));
+ }
+}
+
+void
+odm_update_rx_idle_ant(
+ void *p_dm_void,
+ u8 ant
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+ u32 default_ant, optional_ant, value32, default_tx_ant;
+
+ if (p_dm_fat_table->rx_idle_ant != ant) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Update Rx-Idle-ant ] rx_idle_ant =%s\n", (ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"));
+
+ if (!(p_dm_odm->support_ic_type & ODM_RTL8723B))
+ p_dm_fat_table->rx_idle_ant = ant;
+
+ if (ant == MAIN_ANT) {
+ default_ant = ANT1_2G;
+ optional_ant = ANT2_2G;
+ } else {
+ default_ant = ANT2_2G;
+ optional_ant = ANT1_2G;
+ }
+
+ if (p_dm_fat_table->b_fix_tx_ant != NO_FIX_TX_ANT)
+ default_tx_ant = (p_dm_fat_table->b_fix_tx_ant == FIX_TX_AT_MAIN) ? 0 : 1;
+ else
+ default_tx_ant = default_ant;
+
+ if (p_dm_odm->support_ic_type & ODM_N_ANTDIV_SUPPORT) {
+ if (p_dm_odm->support_ic_type == ODM_RTL8192E) {
+ odm_set_bb_reg(p_dm_odm, 0xB38, BIT(5) | BIT4 | BIT3, default_ant); /* Default RX */
+ odm_set_bb_reg(p_dm_odm, 0xB38, BIT(8) | BIT7 | BIT6, optional_ant); /* Optional RX */
+ odm_set_bb_reg(p_dm_odm, 0x860, BIT(14) | BIT13 | BIT12, default_ant); /* Default TX */
+ }
+#if (RTL8723B_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8723B) {
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0x948, 0xFFF);
+
+ if (value32 != 0x280)
+ odm_update_rx_idle_ant_8723b(p_dm_odm, ant, default_ant, optional_ant);
+ else
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Update Rx-Idle-ant ] 8723B: Fail to set RX antenna due to 0x948 = 0x280\n"));
+ }
+#endif
+ else { /*8188E & 8188F*/
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8723D) {
+#if (RTL8723D_SUPPORT == 1)
+ phydm_set_tx_ant_pwr_8723d(p_dm_odm, ant);
+#endif
+ }
+#if (RTL8188F_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8188F) {
+ phydm_update_rx_idle_antenna_8188F(p_dm_odm, default_ant);
+ /**/
+ }
+#endif
+
+ odm_set_bb_reg(p_dm_odm, 0x864, BIT(5) | BIT4 | BIT3, default_ant); /*Default RX*/
+ odm_set_bb_reg(p_dm_odm, 0x864, BIT(8) | BIT7 | BIT6, optional_ant); /*Optional RX*/
+ odm_set_bb_reg(p_dm_odm, 0x860, BIT(14) | BIT13 | BIT12, default_tx_ant); /*Default TX*/
+ }
+ } else if (p_dm_odm->support_ic_type & ODM_AC_ANTDIV_SUPPORT) {
+ u16 value16 = odm_read_2byte(p_dm_odm, ODM_REG_TRMUX_11AC + 2);
+ /* */
+ /* 2014/01/14 MH/Luke.Lee Add direct write for register 0xc0a to prevnt */
+ /* incorrect 0xc08 bit0-15 .We still not know why it is changed. */
+ /* */
+ value16 &= ~(BIT(11) | BIT(10) | BIT(9) | BIT(8) | BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3));
+ value16 |= ((u16)default_ant << 3);
+ value16 |= ((u16)optional_ant << 6);
+ value16 |= ((u16)default_ant << 9);
+ odm_write_2byte(p_dm_odm, ODM_REG_TRMUX_11AC + 2, value16);
+ }
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E) {
+ odm_set_mac_reg(p_dm_odm, 0x6D8, BIT(7) | BIT6, default_tx_ant); /*PathA Resp Tx*/
+ /**/
+ } else {
+ odm_set_mac_reg(p_dm_odm, 0x6D8, BIT(10) | BIT9 | BIT8, default_tx_ant); /*PathA Resp Tx*/
+ /**/
+ }
+
+ } else { /* p_dm_fat_table->rx_idle_ant == ant */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Stay in Ori-ant ] rx_idle_ant =%s\n", (ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"));
+ p_dm_fat_table->rx_idle_ant = ant;
+ }
+}
+
+void
+odm_update_tx_ant(
+ void *p_dm_void,
+ u8 ant,
+ u32 mac_id
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+ u8 tx_ant;
+
+ if (p_dm_fat_table->b_fix_tx_ant != NO_FIX_TX_ANT)
+ ant = (p_dm_fat_table->b_fix_tx_ant == FIX_TX_AT_MAIN) ? MAIN_ANT : AUX_ANT;
+
+ if (p_dm_odm->ant_div_type == CG_TRX_SMART_ANTDIV)
+ tx_ant = ant;
+ else {
+ if (ant == MAIN_ANT)
+ tx_ant = ANT1_2G;
+ else
+ tx_ant = ANT2_2G;
+ }
+
+ p_dm_fat_table->antsel_a[mac_id] = tx_ant & BIT(0);
+ p_dm_fat_table->antsel_b[mac_id] = (tx_ant & BIT(1)) >> 1;
+ p_dm_fat_table->antsel_c[mac_id] = (tx_ant & BIT(2)) >> 2;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Set TX-DESC value]: mac_id:(( %d )), tx_ant = (( %s ))\n", mac_id, (ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"));
+ /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("antsel_tr_mux=(( 3'b%d%d%d ))\n",p_dm_fat_table->antsel_c[mac_id] , p_dm_fat_table->antsel_b[mac_id] , p_dm_fat_table->antsel_a[mac_id] )); */
+
+}
+
+#ifdef BEAMFORMING_SUPPORT
+
+void
+odm_rx_hw_ant_div_init_88e(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 value32;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8188E AntDiv_Init => ant_div_type=[CGCS_RX_HW_ANTDIV]\n"));
+
+ /* MAC setting */
+ value32 = odm_get_mac_reg(p_dm_odm, ODM_REG_ANTSEL_PIN_11N, MASKDWORD);
+ odm_set_mac_reg(p_dm_odm, ODM_REG_ANTSEL_PIN_11N, MASKDWORD, value32 | (BIT(23) | BIT25)); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */
+ /* Pin Settings */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_PIN_CTRL_11N, BIT(9) | BIT8, 0);/* reg870[8]=1'b0, reg870[9]=1'b0 */ /* antsel antselb by HW */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(10), 0); /* reg864[10]=1'b0 */ /* antsel2 by HW */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_LNA_SWITCH_11N, BIT(22), 1); /* regb2c[22]=1'b0 */ /* disable CS/CG switch */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_LNA_SWITCH_11N, BIT(31), 1); /* regb2c[31]=1'b1 */ /* output at CG only */
+ /* OFDM Settings */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
+ /* CCK Settings */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_BB_PWR_SAV4_11N, BIT(7), 1); /* Fix CCK PHY status report issue */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1); /* CCK complete HW AntDiv within 64 samples */
+
+ odm_set_bb_reg(p_dm_odm, ODM_REG_ANT_MAPPING1_11N, 0xFFFF, 0x0001); /* antenna mapping table */
+
+ p_dm_fat_table->enable_ctrl_frame_antdiv = 1;
+}
+
+void
+odm_trx_hw_ant_div_init_88e(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 value32;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8188E AntDiv_Init => ant_div_type=[CG_TRX_HW_ANTDIV (SPDT)]\n"));
+
+ /* MAC setting */
+ value32 = odm_get_mac_reg(p_dm_odm, ODM_REG_ANTSEL_PIN_11N, MASKDWORD);
+ odm_set_mac_reg(p_dm_odm, ODM_REG_ANTSEL_PIN_11N, MASKDWORD, value32 | (BIT(23) | BIT25)); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */
+ /* Pin Settings */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_PIN_CTRL_11N, BIT(9) | BIT8, 0);/* reg870[8]=1'b0, reg870[9]=1'b0 */ /* antsel antselb by HW */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_RX_ANT_CTRL_11N, BIT(10), 0); /* reg864[10]=1'b0 */ /* antsel2 by HW */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_LNA_SWITCH_11N, BIT(22), 0); /* regb2c[22]=1'b0 */ /* disable CS/CG switch */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_LNA_SWITCH_11N, BIT(31), 1); /* regb2c[31]=1'b1 */ /* output at CG only */
+ /* OFDM Settings */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
+ /* CCK Settings */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_BB_PWR_SAV4_11N, BIT(7), 1); /* Fix CCK PHY status report issue */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1); /* CCK complete HW AntDiv within 64 samples */
+
+ /* antenna mapping table */
+ if (!p_dm_odm->is_mp_chip) { /* testchip */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_RX_DEFUALT_A_11N, BIT(10) | BIT9 | BIT8, 1); /* Reg858[10:8]=3'b001 */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_RX_DEFUALT_A_11N, BIT(13) | BIT12 | BIT11, 2); /* Reg858[13:11]=3'b010 */
+ } else /* MPchip */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_ANT_MAPPING1_11N, MASKDWORD, 0x0201); /*Reg914=3'b010, Reg915=3'b001*/
+
+ p_dm_fat_table->enable_ctrl_frame_antdiv = 1;
+}
+
+
+#if (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) || (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY))
+void odm_smart_hw_ant_div_init_88e(void *p_dm_void)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 value32, i;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8188E AntDiv_Init => ant_div_type=[CG_TRX_SMART_ANTDIV]\n"));
+
+ p_dm_fat_table->train_idx = 0;
+ p_dm_fat_table->fat_state = FAT_PREPARE_STATE;
+
+ p_dm_odm->fat_comb_a = 5;
+ p_dm_odm->antdiv_intvl = 0x64; /* 100ms */
+
+ for (i = 0; i < 6; i++)
+ p_dm_fat_table->bssid[i] = 0;
+ for (i = 0; i < (p_dm_odm->fat_comb_a) ; i++) {
+ p_dm_fat_table->ant_sum_rssi[i] = 0;
+ p_dm_fat_table->ant_rssi_cnt[i] = 0;
+ p_dm_fat_table->ant_ave_rssi[i] = 0;
+ }
+
+ /* MAC setting */
+ value32 = odm_get_mac_reg(p_dm_odm, 0x4c, MASKDWORD);
+ odm_set_mac_reg(p_dm_odm, 0x4c, MASKDWORD, value32 | (BIT(23) | BIT25)); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */
+ value32 = odm_get_mac_reg(p_dm_odm, 0x7B4, MASKDWORD);
+ odm_set_mac_reg(p_dm_odm, 0x7b4, MASKDWORD, value32 | (BIT(16) | BIT17)); /* Reg7B4[16]=1 enable antenna training, Reg7B4[17]=1 enable A2 match */
+ /* value32 = platform_efio_read_4byte(adapter, 0x7B4); */
+ /* platform_efio_write_4byte(adapter, 0x7b4, value32|BIT(18)); */ /* append MACID in reponse packet */
+
+ /* Match MAC ADDR */
+ odm_set_mac_reg(p_dm_odm, 0x7b4, 0xFFFF, 0);
+ odm_set_mac_reg(p_dm_odm, 0x7b0, MASKDWORD, 0);
+
+ odm_set_bb_reg(p_dm_odm, 0x870, BIT(9) | BIT8, 0);/* reg870[8]=1'b0, reg870[9]=1'b0 */ /* antsel antselb by HW */
+ odm_set_bb_reg(p_dm_odm, 0x864, BIT(10), 0); /* reg864[10]=1'b0 */ /* antsel2 by HW */
+ odm_set_bb_reg(p_dm_odm, 0xb2c, BIT(22), 0); /* regb2c[22]=1'b0 */ /* disable CS/CG switch */
+ odm_set_bb_reg(p_dm_odm, 0xb2c, BIT(31), 0); /* regb2c[31]=1'b1 */ /* output at CS only */
+ odm_set_bb_reg(p_dm_odm, 0xca4, MASKDWORD, 0x000000a0);
+
+ /* antenna mapping table */
+ if (p_dm_odm->fat_comb_a == 2) {
+ if (!p_dm_odm->is_mp_chip) { /* testchip */
+ odm_set_bb_reg(p_dm_odm, 0x858, BIT(10) | BIT9 | BIT8, 1); /* Reg858[10:8]=3'b001 */
+ odm_set_bb_reg(p_dm_odm, 0x858, BIT(13) | BIT12 | BIT11, 2); /* Reg858[13:11]=3'b010 */
+ } else { /* MPchip */
+ odm_set_bb_reg(p_dm_odm, 0x914, MASKBYTE0, 1);
+ odm_set_bb_reg(p_dm_odm, 0x914, MASKBYTE1, 2);
+ }
+ } else {
+ if (!p_dm_odm->is_mp_chip) { /* testchip */
+ odm_set_bb_reg(p_dm_odm, 0x858, BIT(10) | BIT9 | BIT8, 0); /* Reg858[10:8]=3'b000 */
+ odm_set_bb_reg(p_dm_odm, 0x858, BIT(13) | BIT12 | BIT11, 1); /* Reg858[13:11]=3'b001 */
+ odm_set_bb_reg(p_dm_odm, 0x878, BIT(16), 0);
+ odm_set_bb_reg(p_dm_odm, 0x858, BIT(15) | BIT14, 2); /* (Reg878[0],Reg858[14:15])=3'b010 */
+ odm_set_bb_reg(p_dm_odm, 0x878, BIT(19) | BIT18 | BIT17, 3); /* Reg878[3:1]=3b'011 */
+ odm_set_bb_reg(p_dm_odm, 0x878, BIT(22) | BIT21 | BIT20, 4); /* Reg878[6:4]=3b'100 */
+ odm_set_bb_reg(p_dm_odm, 0x878, BIT(25) | BIT24 | BIT23, 5); /* Reg878[9:7]=3b'101 */
+ odm_set_bb_reg(p_dm_odm, 0x878, BIT(28) | BIT27 | BIT26, 6); /* Reg878[12:10]=3b'110 */
+ odm_set_bb_reg(p_dm_odm, 0x878, BIT(31) | BIT30 | BIT29, 7); /* Reg878[15:13]=3b'111 */
+ } else { /* MPchip */
+ odm_set_bb_reg(p_dm_odm, 0x914, MASKBYTE0, 4); /* 0: 3b'000 */
+ odm_set_bb_reg(p_dm_odm, 0x914, MASKBYTE1, 2); /* 1: 3b'001 */
+ odm_set_bb_reg(p_dm_odm, 0x914, MASKBYTE2, 0); /* 2: 3b'010 */
+ odm_set_bb_reg(p_dm_odm, 0x914, MASKBYTE3, 1); /* 3: 3b'011 */
+ odm_set_bb_reg(p_dm_odm, 0x918, MASKBYTE0, 3); /* 4: 3b'100 */
+ odm_set_bb_reg(p_dm_odm, 0x918, MASKBYTE1, 5); /* 5: 3b'101 */
+ odm_set_bb_reg(p_dm_odm, 0x918, MASKBYTE2, 6); /* 6: 3b'110 */
+ odm_set_bb_reg(p_dm_odm, 0x918, MASKBYTE3, 255); /* 7: 3b'111 */
+ }
+ }
+
+ /* Default ant setting when no fast training */
+ odm_set_bb_reg(p_dm_odm, 0x864, BIT(5) | BIT4 | BIT3, 0); /* Default RX */
+ odm_set_bb_reg(p_dm_odm, 0x864, BIT(8) | BIT7 | BIT6, 1); /* Optional RX */
+ odm_set_bb_reg(p_dm_odm, 0x860, BIT(14) | BIT13 | BIT12, 0); /* Default TX */
+
+ /* Enter Traing state */
+ odm_set_bb_reg(p_dm_odm, 0x864, BIT(2) | BIT1 | BIT0, (p_dm_odm->fat_comb_a - 1)); /* reg864[2:0]=3'd6 */ /* ant combination=reg864[2:0]+1 */
+
+ /* SW Control */
+ /* phy_set_bb_reg(adapter, 0x864, BIT10, 1); */
+ /* phy_set_bb_reg(adapter, 0x870, BIT9, 1); */
+ /* phy_set_bb_reg(adapter, 0x870, BIT8, 1); */
+ /* phy_set_bb_reg(adapter, 0x864, BIT11, 1); */
+ /* phy_set_bb_reg(adapter, 0x860, BIT9, 0); */
+ /* phy_set_bb_reg(adapter, 0x860, BIT8, 0); */
+}
+#endif
+
+#ifdef ODM_EVM_ENHANCE_ANTDIV
+
+void
+odm_evm_fast_ant_reset(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+
+ p_dm_fat_table->EVM_method_enable = 0;
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_ON);
+ p_dm_fat_table->fat_state = NORMAL_STATE_MIAN;
+ p_dm_odm->antdiv_period = 0;
+ odm_set_mac_reg(p_dm_odm, 0x608, BIT(8), 0);
+}
+
+
+void
+odm_evm_enhance_ant_div(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 main_rssi, aux_rssi ;
+ u32 main_crc_utility = 0, aux_crc_utility = 0, utility_ratio = 1;
+ u32 main_evm, aux_evm, diff_rssi = 0, diff_EVM = 0;
+ u8 score_EVM = 0, score_CRC = 0;
+ u8 rssi_larger_ant = 0;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+ u32 value32, i;
+ bool main_above1 = false, aux_above1 = false;
+ bool force_antenna = false;
+ struct sta_info *p_entry;
+ p_dm_fat_table->target_ant_enhance = 0xFF;
+
+
+ if ((p_dm_odm->support_ic_type & ODM_EVM_ENHANCE_ANTDIV_SUPPORT_IC)) {
+ if (p_dm_odm->is_one_entry_only) {
+ /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[One Client only]\n")); */
+ i = p_dm_odm->one_entry_macid;
+
+ main_rssi = (p_dm_fat_table->main_ant_cnt[i] != 0) ? (p_dm_fat_table->main_ant_sum[i] / p_dm_fat_table->main_ant_cnt[i]) : 0;
+ aux_rssi = (p_dm_fat_table->aux_ant_cnt[i] != 0) ? (p_dm_fat_table->aux_ant_sum[i] / p_dm_fat_table->aux_ant_cnt[i]) : 0;
+
+ if ((main_rssi == 0 && aux_rssi != 0 && aux_rssi >= FORCE_RSSI_DIFF) || (main_rssi != 0 && aux_rssi == 0 && main_rssi >= FORCE_RSSI_DIFF))
+ diff_rssi = FORCE_RSSI_DIFF;
+ else if (main_rssi != 0 && aux_rssi != 0)
+ diff_rssi = (main_rssi >= aux_rssi) ? (main_rssi - aux_rssi) : (aux_rssi - main_rssi);
+
+ if (main_rssi >= aux_rssi)
+ rssi_larger_ant = MAIN_ANT;
+ else
+ rssi_larger_ant = AUX_ANT;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" Main_Cnt = (( %d )) , main_rssi= (( %d ))\n", p_dm_fat_table->main_ant_cnt[i], main_rssi));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" Aux_Cnt = (( %d )) , aux_rssi = (( %d ))\n", p_dm_fat_table->aux_ant_cnt[i], aux_rssi));
+
+ if (((main_rssi >= evm_rssi_th_high || aux_rssi >= evm_rssi_th_high) || (p_dm_fat_table->EVM_method_enable == 1))
+ /* && (diff_rssi <= FORCE_RSSI_DIFF + 1) */
+ ) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[> TH_H || EVM_method_enable==1] && "));
+
+ if (((main_rssi >= evm_rssi_th_low) || (aux_rssi >= evm_rssi_th_low))) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[> TH_L ]\n"));
+
+ /* 2 [ Normal state Main] */
+ if (p_dm_fat_table->fat_state == NORMAL_STATE_MIAN) {
+
+ p_dm_fat_table->EVM_method_enable = 1;
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_OFF);
+ p_dm_odm->antdiv_period = p_dm_odm->evm_antdiv_period;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ start training: MIAN]\n"));
+ p_dm_fat_table->main_ant_evm_sum[i] = 0;
+ p_dm_fat_table->aux_ant_evm_sum[i] = 0;
+ p_dm_fat_table->main_ant_evm_cnt[i] = 0;
+ p_dm_fat_table->aux_ant_evm_cnt[i] = 0;
+
+ p_dm_fat_table->fat_state = NORMAL_STATE_AUX;
+ odm_set_mac_reg(p_dm_odm, 0x608, BIT(8), 1); /* Accept CRC32 Error packets. */
+ odm_update_rx_idle_ant(p_dm_odm, MAIN_ANT);
+
+ p_dm_fat_table->crc32_ok_cnt = 0;
+ p_dm_fat_table->crc32_fail_cnt = 0;
+ odm_set_timer(p_dm_odm, &p_dm_odm->evm_fast_ant_training_timer, p_dm_odm->antdiv_intvl); /* m */
+ }
+ /* 2 [ Normal state Aux ] */
+ else if (p_dm_fat_table->fat_state == NORMAL_STATE_AUX) {
+ p_dm_fat_table->main_crc32_ok_cnt = p_dm_fat_table->crc32_ok_cnt;
+ p_dm_fat_table->main_crc32_fail_cnt = p_dm_fat_table->crc32_fail_cnt;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ start training: AUX]\n"));
+ p_dm_fat_table->fat_state = TRAINING_STATE;
+ odm_update_rx_idle_ant(p_dm_odm, AUX_ANT);
+
+ p_dm_fat_table->crc32_ok_cnt = 0;
+ p_dm_fat_table->crc32_fail_cnt = 0;
+ odm_set_timer(p_dm_odm, &p_dm_odm->evm_fast_ant_training_timer, p_dm_odm->antdiv_intvl); /* ms */
+ } else if (p_dm_fat_table->fat_state == TRAINING_STATE) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Training state ]\n"));
+ p_dm_fat_table->fat_state = NORMAL_STATE_MIAN;
+
+ /* 3 [CRC32 statistic] */
+ p_dm_fat_table->aux_crc32_ok_cnt = p_dm_fat_table->crc32_ok_cnt;
+ p_dm_fat_table->aux_crc32_fail_cnt = p_dm_fat_table->crc32_fail_cnt;
+
+ if ((p_dm_fat_table->main_crc32_ok_cnt > ((p_dm_fat_table->aux_crc32_ok_cnt) << 1)) || ((diff_rssi >= 20) && (rssi_larger_ant == MAIN_ANT))) {
+ p_dm_fat_table->target_ant_crc32 = MAIN_ANT;
+ force_antenna = true;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("CRC32 Force Main\n"));
+ } else if ((p_dm_fat_table->aux_crc32_ok_cnt > ((p_dm_fat_table->main_crc32_ok_cnt) << 1)) || ((diff_rssi >= 20) && (rssi_larger_ant == AUX_ANT))) {
+ p_dm_fat_table->target_ant_crc32 = AUX_ANT;
+ force_antenna = true;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("CRC32 Force Aux\n"));
+ } else {
+ if (p_dm_fat_table->main_crc32_fail_cnt <= 5)
+ p_dm_fat_table->main_crc32_fail_cnt = 5;
+
+ if (p_dm_fat_table->aux_crc32_fail_cnt <= 5)
+ p_dm_fat_table->aux_crc32_fail_cnt = 5;
+
+ if (p_dm_fat_table->main_crc32_ok_cnt > p_dm_fat_table->main_crc32_fail_cnt)
+ main_above1 = true;
+
+ if (p_dm_fat_table->aux_crc32_ok_cnt > p_dm_fat_table->aux_crc32_fail_cnt)
+ aux_above1 = true;
+
+ if (main_above1 == true && aux_above1 == false) {
+ force_antenna = true;
+ p_dm_fat_table->target_ant_crc32 = MAIN_ANT;
+ } else if (main_above1 == false && aux_above1 == true) {
+ force_antenna = true;
+ p_dm_fat_table->target_ant_crc32 = AUX_ANT;
+ } else if (main_above1 == true && aux_above1 == true) {
+ main_crc_utility = ((p_dm_fat_table->main_crc32_ok_cnt) << 7) / p_dm_fat_table->main_crc32_fail_cnt;
+ aux_crc_utility = ((p_dm_fat_table->aux_crc32_ok_cnt) << 7) / p_dm_fat_table->aux_crc32_fail_cnt;
+ p_dm_fat_table->target_ant_crc32 = (main_crc_utility == aux_crc_utility) ? (p_dm_fat_table->pre_target_ant_enhance) : ((main_crc_utility >= aux_crc_utility) ? MAIN_ANT : AUX_ANT);
+
+ if (main_crc_utility != 0 && aux_crc_utility != 0) {
+ if (main_crc_utility >= aux_crc_utility)
+ utility_ratio = (main_crc_utility << 1) / aux_crc_utility;
+ else
+ utility_ratio = (aux_crc_utility << 1) / main_crc_utility;
+ }
+ } else if (main_above1 == false && aux_above1 == false) {
+ if (p_dm_fat_table->main_crc32_ok_cnt == 0)
+ p_dm_fat_table->main_crc32_ok_cnt = 1;
+ if (p_dm_fat_table->aux_crc32_ok_cnt == 0)
+ p_dm_fat_table->aux_crc32_ok_cnt = 1;
+
+ main_crc_utility = ((p_dm_fat_table->main_crc32_fail_cnt) << 7) / p_dm_fat_table->main_crc32_ok_cnt;
+ aux_crc_utility = ((p_dm_fat_table->aux_crc32_fail_cnt) << 7) / p_dm_fat_table->aux_crc32_ok_cnt;
+ p_dm_fat_table->target_ant_crc32 = (main_crc_utility == aux_crc_utility) ? (p_dm_fat_table->pre_target_ant_enhance) : ((main_crc_utility <= aux_crc_utility) ? MAIN_ANT : AUX_ANT);
+
+ if (main_crc_utility != 0 && aux_crc_utility != 0) {
+ if (main_crc_utility >= aux_crc_utility)
+ utility_ratio = (main_crc_utility << 1) / (aux_crc_utility);
+ else
+ utility_ratio = (aux_crc_utility << 1) / (main_crc_utility);
+ }
+ }
+ }
+ odm_set_mac_reg(p_dm_odm, 0x608, BIT(8), 0);/* NOT Accept CRC32 Error packets. */
+
+ /* 3 [EVM statistic] */
+ main_evm = (p_dm_fat_table->main_ant_evm_cnt[i] != 0) ? (p_dm_fat_table->main_ant_evm_sum[i] / p_dm_fat_table->main_ant_evm_cnt[i]) : 0;
+ aux_evm = (p_dm_fat_table->aux_ant_evm_cnt[i] != 0) ? (p_dm_fat_table->aux_ant_evm_sum[i] / p_dm_fat_table->aux_ant_evm_cnt[i]) : 0;
+ p_dm_fat_table->target_ant_evm = (main_evm == aux_evm) ? (p_dm_fat_table->pre_target_ant_enhance) : ((main_evm >= aux_evm) ? MAIN_ANT : AUX_ANT);
+
+ if ((main_evm == 0 || aux_evm == 0))
+ diff_EVM = 0;
+ else if (main_evm >= aux_evm)
+ diff_EVM = main_evm - aux_evm;
+ else
+ diff_EVM = aux_evm - main_evm;
+
+ /* 2 [ Decision state ] */
+ if (p_dm_fat_table->target_ant_evm == p_dm_fat_table->target_ant_crc32) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Decision type 1, CRC_utility = ((%d)), EVM_diff = ((%d))\n", utility_ratio, diff_EVM));
+
+ if ((utility_ratio < 2 && force_antenna == false) && diff_EVM <= 30)
+ p_dm_fat_table->target_ant_enhance = p_dm_fat_table->pre_target_ant_enhance;
+ else
+ p_dm_fat_table->target_ant_enhance = p_dm_fat_table->target_ant_evm;
+ } else if ((diff_EVM <= 50 && (utility_ratio > 4 && force_antenna == false)) || (force_antenna == true)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Decision type 2, CRC_utility = ((%d)), EVM_diff = ((%d))\n", utility_ratio, diff_EVM));
+ p_dm_fat_table->target_ant_enhance = p_dm_fat_table->target_ant_crc32;
+ } else if (diff_EVM >= 100) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Decision type 3, CRC_utility = ((%d)), EVM_diff = ((%d))\n", utility_ratio, diff_EVM));
+ p_dm_fat_table->target_ant_enhance = p_dm_fat_table->target_ant_evm;
+ } else if (utility_ratio >= 6 && force_antenna == false) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Decision type 4, CRC_utility = ((%d)), EVM_diff = ((%d))\n", utility_ratio, diff_EVM));
+ p_dm_fat_table->target_ant_enhance = p_dm_fat_table->target_ant_crc32;
+ } else {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Decision type 5, CRC_utility = ((%d)), EVM_diff = ((%d))\n", utility_ratio, diff_EVM));
+
+ if (force_antenna == true)
+ score_CRC = 3;
+ else if (utility_ratio >= 3) /*>0.5*/
+ score_CRC = 2;
+ else if (utility_ratio >= 2) /*>1*/
+ score_CRC = 1;
+ else
+ score_CRC = 0;
+
+ if (diff_EVM >= 100)
+ score_EVM = 2;
+ else if (diff_EVM >= 50)
+ score_EVM = 1;
+ else
+ score_EVM = 0;
+
+ if (score_CRC > score_EVM)
+ p_dm_fat_table->target_ant_enhance = p_dm_fat_table->target_ant_crc32;
+ else if (score_CRC < score_EVM)
+ p_dm_fat_table->target_ant_enhance = p_dm_fat_table->target_ant_evm;
+ else
+ p_dm_fat_table->target_ant_enhance = p_dm_fat_table->pre_target_ant_enhance;
+ }
+ p_dm_fat_table->pre_target_ant_enhance = p_dm_fat_table->target_ant_enhance;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Client[ %d ] : MainEVM_Cnt = (( %d )) , main_evm= (( %d ))\n", i, p_dm_fat_table->main_ant_evm_cnt[i], main_evm));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Client[ %d ] : AuxEVM_Cnt = (( %d )) , aux_evm = (( %d ))\n", i, p_dm_fat_table->aux_ant_evm_cnt[i], aux_evm));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** target_ant_evm = (( %s ))\n", (p_dm_fat_table->target_ant_evm == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("M_CRC_Ok = (( %d )) , M_CRC_Fail = (( %d )), main_crc_utility = (( %d ))\n", p_dm_fat_table->main_crc32_ok_cnt, p_dm_fat_table->main_crc32_fail_cnt, main_crc_utility));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("A_CRC_Ok = (( %d )) , A_CRC_Fail = (( %d )), aux_crc_utility = (( %d ))\n", p_dm_fat_table->aux_crc32_ok_cnt, p_dm_fat_table->aux_crc32_fail_cnt, aux_crc_utility));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** target_ant_crc32 = (( %s ))\n", (p_dm_fat_table->target_ant_crc32 == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("****** target_ant_enhance = (( %s ))******\n", (p_dm_fat_table->target_ant_enhance == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"));
+
+
+ }
+ } else { /* RSSI< = evm_rssi_th_low */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ <TH_L: escape from > TH_L ]\n"));
+ odm_evm_fast_ant_reset(p_dm_odm);
+ }
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[escape from> TH_H || EVM_method_enable==1]\n"));
+ odm_evm_fast_ant_reset(p_dm_odm);
+ }
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[multi-Client]\n"));
+ odm_evm_fast_ant_reset(p_dm_odm);
+ }
+ }
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
+void odm_evm_fast_ant_training_callback(void *p_dm_void)
+#else
+void odm_evm_fast_ant_training_callback(struct timer_list *t)
+#endif
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+#else
+ struct PHY_DM_STRUCT *p_dm_odm = from_timer(p_dm_odm, t, evm_fast_ant_training_timer);
+#endif
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("******odm_evm_fast_ant_training_callback******\n"));
+ odm_hw_ant_div(p_dm_odm);
+}
+#endif
+
+void
+odm_hw_ant_div(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 i, min_max_rssi = 0xFF, ant_div_max_rssi = 0, max_rssi = 0, local_max_rssi;
+ u32 main_rssi, aux_rssi, mian_cnt, aux_cnt;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+ u8 rx_idle_ant = p_dm_fat_table->rx_idle_ant, target_ant = 7;
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+ struct sta_info *p_entry;
+
+ if (!p_dm_odm->is_linked) { /* is_linked==False */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[No Link!!!]\n"));
+
+ if (p_dm_fat_table->is_become_linked == true) {
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_OFF);
+ odm_update_rx_idle_ant(p_dm_odm, MAIN_ANT);
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_REG);
+ p_dm_odm->antdiv_period = 0;
+
+ p_dm_fat_table->is_become_linked = p_dm_odm->is_linked;
+ }
+ return;
+ } else {
+ if (p_dm_fat_table->is_become_linked == false) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Linked !!!]\n"));
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_ON);
+ p_dm_fat_table->is_become_linked = p_dm_odm->is_linked;
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8723B && p_dm_odm->ant_div_type == CG_TRX_HW_ANTDIV) {
+ odm_set_bb_reg(p_dm_odm, 0x930, 0xF0, 8); /* DPDT_P = ANTSEL[0] */ /* for 8723B AntDiv function patch. BB Dino 130412 */
+ odm_set_bb_reg(p_dm_odm, 0x930, 0xF, 8); /* DPDT_N = ANTSEL[0] */
+ }
+
+ /* 2 BDC Init */
+
+#ifdef ODM_EVM_ENHANCE_ANTDIV
+ odm_evm_fast_ant_reset(p_dm_odm);
+#endif
+ }
+ }
+
+ if (*(p_dm_fat_table->p_force_tx_ant_by_desc) == false) {
+ if (p_dm_odm->is_one_entry_only == true)
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_REG);
+ else
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_DESC);
+ }
+
+#ifdef ODM_EVM_ENHANCE_ANTDIV
+ if (p_dm_odm->antdiv_evm_en == 1) {
+ odm_evm_enhance_ant_div(p_dm_odm);
+ if (p_dm_fat_table->fat_state != NORMAL_STATE_MIAN)
+ return;
+ } else
+ odm_evm_fast_ant_reset(p_dm_odm);
+#endif
+
+ /* 2 BDC mode Arbitration */
+
+ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
+ p_entry = p_dm_odm->p_odm_sta_info[i];
+ if (IS_STA_VALID(p_entry)) {
+ /* 2 Caculate RSSI per Antenna */
+ if ((p_dm_fat_table->main_ant_cnt[i] != 0) || (p_dm_fat_table->aux_ant_cnt[i] != 0)) {
+ mian_cnt = p_dm_fat_table->main_ant_cnt[i];
+ aux_cnt = p_dm_fat_table->aux_ant_cnt[i];
+ main_rssi = (mian_cnt != 0) ? (p_dm_fat_table->main_ant_sum[i] / mian_cnt) : 0;
+ aux_rssi = (aux_cnt != 0) ? (p_dm_fat_table->aux_ant_sum[i] / aux_cnt) : 0;
+ target_ant = (mian_cnt == aux_cnt) ? p_dm_fat_table->rx_idle_ant : ((mian_cnt >= aux_cnt) ? MAIN_ANT : AUX_ANT); /*Use counter number for OFDM*/
+
+ } else { /*CCK only case*/
+ mian_cnt = p_dm_fat_table->main_ant_cnt_cck[i];
+ aux_cnt = p_dm_fat_table->aux_ant_cnt_cck[i];
+ main_rssi = (mian_cnt != 0) ? (p_dm_fat_table->main_ant_sum_cck[i] / mian_cnt) : 0;
+ aux_rssi = (aux_cnt != 0) ? (p_dm_fat_table->aux_ant_sum_cck[i] / aux_cnt) : 0;
+ target_ant = (main_rssi == aux_rssi) ? p_dm_fat_table->rx_idle_ant : ((main_rssi >= aux_rssi) ? MAIN_ANT : AUX_ANT); /*Use RSSI for CCK only case*/
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Client[ %d ] : Main_Cnt = (( %d )) , CCK_Main_Cnt = (( %d )) , main_rssi= (( %d ))\n", i, p_dm_fat_table->main_ant_cnt[i], p_dm_fat_table->main_ant_cnt_cck[i], main_rssi));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Client[ %d ] : Aux_Cnt = (( %d )) , CCK_Aux_Cnt = (( %d )) , aux_rssi = (( %d ))\n", i, p_dm_fat_table->aux_ant_cnt[i], p_dm_fat_table->aux_ant_cnt_cck[i], aux_rssi));
+ /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** MAC ID:[ %d ] , target_ant = (( %s ))\n", i ,( target_ant ==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); */
+
+ local_max_rssi = (main_rssi > aux_rssi) ? main_rssi : aux_rssi;
+ /* 2 Select max_rssi for DIG */
+ if ((local_max_rssi > ant_div_max_rssi) && (local_max_rssi < 40))
+ ant_div_max_rssi = local_max_rssi;
+ if (local_max_rssi > max_rssi)
+ max_rssi = local_max_rssi;
+
+ /* 2 Select RX Idle Antenna */
+ if ((local_max_rssi != 0) && (local_max_rssi < min_max_rssi)) {
+ rx_idle_ant = target_ant;
+ min_max_rssi = local_max_rssi;
+ }
+
+#ifdef ODM_EVM_ENHANCE_ANTDIV
+ if (p_dm_odm->antdiv_evm_en == 1) {
+ if (p_dm_fat_table->target_ant_enhance != 0xFF) {
+ target_ant = p_dm_fat_table->target_ant_enhance;
+ rx_idle_ant = p_dm_fat_table->target_ant_enhance;
+ }
+ }
+#endif
+
+ /* 2 Select TX Antenna */
+ if (p_dm_odm->ant_div_type != CGCS_RX_HW_ANTDIV) {
+ odm_update_tx_ant(p_dm_odm, target_ant, i);
+ }
+
+ /* ------------------------------------------------------------ */
+
+ }
+ phydm_antdiv_reset_statistic(p_dm_odm, i);
+ }
+
+
+
+ /* 2 Set RX Idle Antenna & TX Antenna(Because of HW Bug ) */
+
+ odm_update_rx_idle_ant(p_dm_odm, rx_idle_ant);
+
+ /* 2 BDC Main Algorithm */
+ if (ant_div_max_rssi == 0)
+ p_dm_dig_table->ant_div_rssi_max = p_dm_odm->rssi_min;
+ else
+ p_dm_dig_table->ant_div_rssi_max = ant_div_max_rssi;
+
+ p_dm_dig_table->RSSI_max = max_rssi;
+}
+
+
+
+#ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY
+
+void
+odm_s0s1_sw_ant_div_reset(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _sw_antenna_switch_ *p_dm_swat_table = &p_dm_odm->dm_swat_table;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+
+ p_dm_fat_table->is_become_linked = false;
+ p_dm_swat_table->try_flag = SWAW_STEP_INIT;
+ p_dm_swat_table->double_chk_flag = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_s0s1_sw_ant_div_reset(): p_dm_fat_table->is_become_linked = %d\n", p_dm_fat_table->is_become_linked));
+}
+
+void
+odm_s0s1_sw_ant_div(
+ void *p_dm_void,
+ u8 step
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _sw_antenna_switch_ *p_dm_swat_table = &p_dm_odm->dm_swat_table;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+ u32 i, min_max_rssi = 0xFF, local_max_rssi, local_min_rssi;
+ u32 main_rssi, aux_rssi;
+ u8 high_traffic_train_time_u = 0x32, high_traffic_train_time_l = 0, train_time_temp;
+ u8 low_traffic_train_time_u = 200, low_traffic_train_time_l = 0;
+ u8 rx_idle_ant = p_dm_swat_table->pre_antenna, target_ant, next_ant = 0;
+ struct sta_info *p_entry = NULL;
+ u32 value32;
+ u32 main_ant_sum;
+ u32 aux_ant_sum;
+ u32 main_ant_cnt;
+ u32 aux_ant_cnt;
+
+
+ if (!p_dm_odm->is_linked) { /* is_linked==False */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[No Link!!!]\n"));
+ if (p_dm_fat_table->is_become_linked == true) {
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_REG);
+ if (p_dm_odm->support_ic_type == ODM_RTL8723B) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Set REG 948[9:6]=0x0\n"));
+ odm_set_bb_reg(p_dm_odm, 0x948, (BIT(9) | BIT(8) | BIT(7) | BIT(6)), 0x0);
+ }
+ p_dm_fat_table->is_become_linked = p_dm_odm->is_linked;
+ }
+ return;
+ } else {
+ if (p_dm_fat_table->is_become_linked == false) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Linked !!!]\n"));
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8723B) {
+ value32 = odm_get_bb_reg(p_dm_odm, 0x864, BIT(5) | BIT(4) | BIT(3));
+
+#if (RTL8723B_SUPPORT == 1)
+ if (value32 == 0x0)
+ odm_update_rx_idle_ant_8723b(p_dm_odm, MAIN_ANT, ANT1_2G, ANT2_2G);
+ else if (value32 == 0x1)
+ odm_update_rx_idle_ant_8723b(p_dm_odm, AUX_ANT, ANT2_2G, ANT1_2G);
+#endif
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("8723B: First link! Force antenna to %s\n", (value32 == 0x0 ? "MAIN" : "AUX")));
+ }
+ p_dm_fat_table->is_become_linked = p_dm_odm->is_linked;
+ }
+ }
+
+ if (*(p_dm_fat_table->p_force_tx_ant_by_desc) == false) {
+ if (p_dm_odm->is_one_entry_only == true)
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_REG);
+ else
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_DESC);
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[%d] { try_flag=(( %d )), step=(( %d )), double_chk_flag = (( %d )) }\n",
+ __LINE__, p_dm_swat_table->try_flag, step, p_dm_swat_table->double_chk_flag));
+
+ /* Handling step mismatch condition. */
+ /* Peak step is not finished at last time. Recover the variable and check again. */
+ if (step != p_dm_swat_table->try_flag) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[step != try_flag] Need to Reset After Link\n"));
+ odm_sw_ant_div_rest_after_link(p_dm_odm);
+ }
+
+ if (p_dm_swat_table->try_flag == SWAW_STEP_INIT) {
+
+ p_dm_swat_table->try_flag = SWAW_STEP_PEEK;
+ p_dm_swat_table->train_time_flag = 0;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[set try_flag = 0] Prepare for peek!\n\n"));
+ return;
+
+ } else {
+
+ /* 1 Normal state (Begin Trying) */
+ if (p_dm_swat_table->try_flag == SWAW_STEP_PEEK) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("TxOkCnt=(( %llu )), RxOkCnt=(( %llu )), traffic_load = (%d))\n", p_dm_odm->cur_tx_ok_cnt, p_dm_odm->cur_rx_ok_cnt, p_dm_odm->traffic_load));
+
+ if (p_dm_odm->traffic_load == TRAFFIC_HIGH) {
+ train_time_temp = p_dm_swat_table->train_time ;
+
+ if (p_dm_swat_table->train_time_flag == 3) {
+ high_traffic_train_time_l = 0xa;
+
+ if (train_time_temp <= 16)
+ train_time_temp = high_traffic_train_time_l;
+ else
+ train_time_temp -= 16;
+
+ } else if (p_dm_swat_table->train_time_flag == 2) {
+ train_time_temp -= 8;
+ high_traffic_train_time_l = 0xf;
+ } else if (p_dm_swat_table->train_time_flag == 1) {
+ train_time_temp -= 4;
+ high_traffic_train_time_l = 0x1e;
+ } else if (p_dm_swat_table->train_time_flag == 0) {
+ train_time_temp += 8;
+ high_traffic_train_time_l = 0x28;
+ }
+
+
+ /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** train_time_temp = ((%d))\n",train_time_temp)); */
+
+ /* -- */
+ if (train_time_temp > high_traffic_train_time_u)
+ train_time_temp = high_traffic_train_time_u;
+
+ else if (train_time_temp < high_traffic_train_time_l)
+ train_time_temp = high_traffic_train_time_l;
+
+ p_dm_swat_table->train_time = train_time_temp; /*10ms~200ms*/
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("train_time_flag=((%d)), train_time=((%d))\n", p_dm_swat_table->train_time_flag, p_dm_swat_table->train_time));
+
+ } else if ((p_dm_odm->traffic_load == TRAFFIC_MID) || (p_dm_odm->traffic_load == TRAFFIC_LOW)) {
+
+ train_time_temp = p_dm_swat_table->train_time ;
+
+ if (p_dm_swat_table->train_time_flag == 3) {
+ low_traffic_train_time_l = 10;
+ if (train_time_temp < 50)
+ train_time_temp = low_traffic_train_time_l;
+ else
+ train_time_temp -= 50;
+ } else if (p_dm_swat_table->train_time_flag == 2) {
+ train_time_temp -= 30;
+ low_traffic_train_time_l = 36;
+ } else if (p_dm_swat_table->train_time_flag == 1) {
+ train_time_temp -= 10;
+ low_traffic_train_time_l = 40;
+ } else {
+
+ train_time_temp += 10;
+ low_traffic_train_time_l = 50;
+ }
+
+ /* -- */
+ if (train_time_temp >= low_traffic_train_time_u)
+ train_time_temp = low_traffic_train_time_u;
+
+ else if (train_time_temp <= low_traffic_train_time_l)
+ train_time_temp = low_traffic_train_time_l;
+
+ p_dm_swat_table->train_time = train_time_temp; /*10ms~200ms*/
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("train_time_flag=((%d)) , train_time=((%d))\n", p_dm_swat_table->train_time_flag, p_dm_swat_table->train_time));
+
+ } else {
+ p_dm_swat_table->train_time = 0xc8; /*200ms*/
+
+ }
+
+ /* ----------------- */
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Current min_max_rssi is ((%d))\n", p_dm_fat_table->min_max_rssi));
+
+ /* ---reset index--- */
+ if (p_dm_swat_table->reset_idx >= RSSI_CHECK_RESET_PERIOD) {
+
+ p_dm_fat_table->min_max_rssi = 0;
+ p_dm_swat_table->reset_idx = 0;
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("reset_idx = (( %d ))\n", p_dm_swat_table->reset_idx));
+
+ p_dm_swat_table->reset_idx++;
+
+ /* ---double check flag--- */
+ if ((p_dm_fat_table->min_max_rssi > RSSI_CHECK_THRESHOLD) && (p_dm_swat_table->double_chk_flag == 0)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" min_max_rssi is ((%d)), and > %d\n",
+ p_dm_fat_table->min_max_rssi, RSSI_CHECK_THRESHOLD));
+
+ p_dm_swat_table->double_chk_flag = 1;
+ p_dm_swat_table->try_flag = SWAW_STEP_DETERMINE;
+ p_dm_swat_table->rssi_trying = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Test the current ant for (( %d )) ms again\n", p_dm_swat_table->train_time));
+ odm_update_rx_idle_ant(p_dm_odm, p_dm_fat_table->rx_idle_ant);
+ odm_set_timer(p_dm_odm, &(p_dm_swat_table->phydm_sw_antenna_switch_timer), p_dm_swat_table->train_time); /*ms*/
+ return;
+ }
+
+ next_ant = (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
+
+ p_dm_swat_table->try_flag = SWAW_STEP_DETERMINE;
+
+ if (p_dm_swat_table->reset_idx <= 1)
+ p_dm_swat_table->rssi_trying = 2;
+ else
+ p_dm_swat_table->rssi_trying = 1;
+
+ odm_s0s1_sw_ant_div_by_ctrl_frame(p_dm_odm, SWAW_STEP_PEEK);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[set try_flag=1] Normal state: Begin Trying!!\n"));
+
+ } else if ((p_dm_swat_table->try_flag == SWAW_STEP_DETERMINE) && (p_dm_swat_table->double_chk_flag == 0)) {
+
+ next_ant = (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
+ p_dm_swat_table->rssi_trying--;
+ }
+
+ /* 1 Decision state */
+ if ((p_dm_swat_table->try_flag == SWAW_STEP_DETERMINE) && (p_dm_swat_table->rssi_trying == 0)) {
+
+ bool is_by_ctrl_frame = false;
+ u64 pkt_cnt_total = 0;
+
+ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
+ p_entry = p_dm_odm->p_odm_sta_info[i];
+ if (IS_STA_VALID(p_entry)) {
+ /* 2 Caculate RSSI per Antenna */
+
+ main_ant_sum = (u32)p_dm_fat_table->main_ant_sum[i] + (u32)p_dm_fat_table->main_ant_sum_cck[i];
+ aux_ant_sum = (u32)p_dm_fat_table->aux_ant_sum[i] + (u32)p_dm_fat_table->aux_ant_sum_cck[i];
+ main_ant_cnt = (u32)p_dm_fat_table->main_ant_cnt[i] + (u32)p_dm_fat_table->main_ant_cnt_cck[i];
+ aux_ant_cnt = (u32)p_dm_fat_table->aux_ant_cnt[i] + (u32)p_dm_fat_table->aux_ant_cnt_cck[i];
+
+ main_rssi = (main_ant_cnt != 0) ? (main_ant_sum / main_ant_cnt) : 0;
+ aux_rssi = (aux_ant_cnt != 0) ? (aux_ant_sum / aux_ant_cnt) : 0;
+
+ if (p_dm_fat_table->main_ant_cnt[i] <= 1 && p_dm_fat_table->main_ant_cnt_cck[i] >= 1)
+ main_rssi = 0;
+
+ if (p_dm_fat_table->aux_ant_cnt[i] <= 1 && p_dm_fat_table->aux_ant_cnt_cck[i] >= 1)
+ aux_rssi = 0;
+
+ target_ant = (main_rssi == aux_rssi) ? p_dm_swat_table->pre_antenna : ((main_rssi >= aux_rssi) ? MAIN_ANT : AUX_ANT);
+ local_max_rssi = (main_rssi >= aux_rssi) ? main_rssi : aux_rssi;
+ local_min_rssi = (main_rssi >= aux_rssi) ? aux_rssi : main_rssi;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** CCK_counter_main = (( %d )) , CCK_counter_aux= (( %d ))\n", p_dm_fat_table->main_ant_cnt_cck[i], p_dm_fat_table->aux_ant_cnt_cck[i]));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** OFDM_counter_main = (( %d )) , OFDM_counter_aux= (( %d ))\n", p_dm_fat_table->main_ant_cnt[i], p_dm_fat_table->aux_ant_cnt[i]));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Main_Cnt = (( %d )) , main_rssi= (( %d ))\n", main_ant_cnt, main_rssi));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Aux_Cnt = (( %d )) , aux_rssi = (( %d ))\n", aux_ant_cnt, aux_rssi));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** MAC ID:[ %d ] , target_ant = (( %s ))\n", i, (target_ant == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT"));
+
+ /* 2 Select RX Idle Antenna */
+
+ if (local_max_rssi != 0 && local_max_rssi < min_max_rssi) {
+ rx_idle_ant = target_ant;
+ min_max_rssi = local_max_rssi;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** local_max_rssi-local_min_rssi = ((%d))\n", (local_max_rssi - local_min_rssi)));
+
+ if ((local_max_rssi - local_min_rssi) > 8) {
+ if (local_min_rssi != 0)
+ p_dm_swat_table->train_time_flag = 3;
+ else {
+ if (min_max_rssi > RSSI_CHECK_THRESHOLD)
+ p_dm_swat_table->train_time_flag = 0;
+ else
+ p_dm_swat_table->train_time_flag = 3;
+ }
+ } else if ((local_max_rssi - local_min_rssi) > 5)
+ p_dm_swat_table->train_time_flag = 2;
+ else if ((local_max_rssi - local_min_rssi) > 2)
+ p_dm_swat_table->train_time_flag = 1;
+ else
+ p_dm_swat_table->train_time_flag = 0;
+
+ }
+
+ /* 2 Select TX Antenna */
+ if (target_ant == MAIN_ANT)
+ p_dm_fat_table->antsel_a[i] = ANT1_2G;
+ else
+ p_dm_fat_table->antsel_a[i] = ANT2_2G;
+
+ }
+ phydm_antdiv_reset_statistic(p_dm_odm, i);
+ pkt_cnt_total += (main_ant_cnt + aux_ant_cnt);
+ }
+
+ if (p_dm_swat_table->is_sw_ant_div_by_ctrl_frame) {
+ odm_s0s1_sw_ant_div_by_ctrl_frame(p_dm_odm, SWAW_STEP_DETERMINE);
+ is_by_ctrl_frame = true;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Control frame packet counter = %d, data frame packet counter = %llu\n",
+ p_dm_swat_table->pkt_cnt_sw_ant_div_by_ctrl_frame, pkt_cnt_total));
+
+ if (min_max_rssi == 0xff || ((pkt_cnt_total < (p_dm_swat_table->pkt_cnt_sw_ant_div_by_ctrl_frame >> 1)) && p_dm_odm->phy_dbg_info.num_qry_beacon_pkt < 2)) {
+ min_max_rssi = 0;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Check RSSI of control frame because min_max_rssi == 0xff\n"));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("is_by_ctrl_frame = %d\n", is_by_ctrl_frame));
+
+ if (is_by_ctrl_frame) {
+ main_rssi = (p_dm_fat_table->main_ant_ctrl_frame_cnt != 0) ? (p_dm_fat_table->main_ant_ctrl_frame_sum / p_dm_fat_table->main_ant_ctrl_frame_cnt) : 0;
+ aux_rssi = (p_dm_fat_table->aux_ant_ctrl_frame_cnt != 0) ? (p_dm_fat_table->aux_ant_ctrl_frame_sum / p_dm_fat_table->aux_ant_ctrl_frame_cnt) : 0;
+
+ if (p_dm_fat_table->main_ant_ctrl_frame_cnt <= 1 && p_dm_fat_table->cck_ctrl_frame_cnt_main >= 1)
+ main_rssi = 0;
+
+ if (p_dm_fat_table->aux_ant_ctrl_frame_cnt <= 1 && p_dm_fat_table->cck_ctrl_frame_cnt_aux >= 1)
+ aux_rssi = 0;
+
+ if (main_rssi != 0 || aux_rssi != 0) {
+ rx_idle_ant = (main_rssi == aux_rssi) ? p_dm_swat_table->pre_antenna : ((main_rssi >= aux_rssi) ? MAIN_ANT : AUX_ANT);
+ local_max_rssi = (main_rssi >= aux_rssi) ? main_rssi : aux_rssi;
+ local_min_rssi = (main_rssi >= aux_rssi) ? aux_rssi : main_rssi;
+
+ if ((local_max_rssi - local_min_rssi) > 8)
+ p_dm_swat_table->train_time_flag = 3;
+ else if ((local_max_rssi - local_min_rssi) > 5)
+ p_dm_swat_table->train_time_flag = 2;
+ else if ((local_max_rssi - local_min_rssi) > 2)
+ p_dm_swat_table->train_time_flag = 1;
+ else
+ p_dm_swat_table->train_time_flag = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Control frame: main_rssi = %d, aux_rssi = %d\n", main_rssi, aux_rssi));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("rx_idle_ant decided by control frame = %s\n", (rx_idle_ant == MAIN_ANT ? "MAIN" : "AUX")));
+ }
+ }
+ }
+
+ p_dm_fat_table->min_max_rssi = min_max_rssi;
+ p_dm_swat_table->try_flag = SWAW_STEP_PEEK;
+
+ if (p_dm_swat_table->double_chk_flag == 1) {
+ p_dm_swat_table->double_chk_flag = 0;
+
+ if (p_dm_fat_table->min_max_rssi > RSSI_CHECK_THRESHOLD) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" [Double check] min_max_rssi ((%d)) > %d again!!\n",
+ p_dm_fat_table->min_max_rssi, RSSI_CHECK_THRESHOLD));
+
+ odm_update_rx_idle_ant(p_dm_odm, rx_idle_ant);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[reset try_flag = 0] Training accomplished !!!]\n\n\n"));
+ return;
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" [Double check] min_max_rssi ((%d)) <= %d !!\n",
+ p_dm_fat_table->min_max_rssi, RSSI_CHECK_THRESHOLD));
+
+ next_ant = (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
+ p_dm_swat_table->try_flag = SWAW_STEP_PEEK;
+ p_dm_swat_table->reset_idx = RSSI_CHECK_RESET_PERIOD;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[set try_flag=0] Normal state: Need to tryg again!!\n\n\n"));
+ return;
+ }
+ } else {
+ if (p_dm_fat_table->min_max_rssi < RSSI_CHECK_THRESHOLD)
+ p_dm_swat_table->reset_idx = RSSI_CHECK_RESET_PERIOD;
+
+ p_dm_swat_table->pre_antenna = rx_idle_ant;
+ odm_update_rx_idle_ant(p_dm_odm, rx_idle_ant);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[reset try_flag = 0] Training accomplished !!!] \n\n\n"));
+ return;
+ }
+
+ }
+
+ }
+
+ /* 1 4.Change TRX antenna */
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("rssi_trying = (( %d )), ant: (( %s )) >>> (( %s ))\n",
+ p_dm_swat_table->rssi_trying, (p_dm_fat_table->rx_idle_ant == MAIN_ANT ? "MAIN" : "AUX"), (next_ant == MAIN_ANT ? "MAIN" : "AUX")));
+
+ odm_update_rx_idle_ant(p_dm_odm, next_ant);
+
+ /* 1 5.Reset Statistics */
+
+ p_dm_fat_table->rx_idle_ant = next_ant;
+
+ /* 1 6.Set next timer (Trying state) */
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" Test ((%s)) ant for (( %d )) ms\n", (next_ant == MAIN_ANT ? "MAIN" : "AUX"), p_dm_swat_table->train_time));
+ odm_set_timer(p_dm_odm, &(p_dm_swat_table->phydm_sw_antenna_switch_timer), p_dm_swat_table->train_time); /*ms*/
+}
+
+void odm_sw_antdiv_workitem_callback(void *p_context)
+{
+ struct _ADAPTER * p_adapter = (struct _ADAPTER *)p_context;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+
+ /*dbg_print("SW_antdiv_Workitem_Callback");*/
+ odm_s0s1_sw_ant_div(&p_hal_data->odmpriv, SWAW_STEP_DETERMINE);
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
+void odm_sw_antdiv_callback(void *function_context)
+#else
+void odm_sw_antdiv_callback(istruct timer_list *t)
+#endif
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)function_context;
+#else
+ struct PHY_DM_STRUCT *p_dm_odm = timer_list(p_dm_odm, t, dm_swat_table.phydm_sw_antenna_switch_timer);
+#endif
+ struct _ADAPTER *padapter = p_dm_odm->adapter;
+ if (padapter->net_closed == true)
+ return;
+
+ rtw_run_in_thread_cmd(padapter, odm_sw_antdiv_workitem_callback, padapter);
+}
+
+
+#endif
+
+void
+odm_s0s1_sw_ant_div_by_ctrl_frame(
+ void *p_dm_void,
+ u8 step
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _sw_antenna_switch_ *p_dm_swat_table = &p_dm_odm->dm_swat_table;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+
+ switch (step) {
+ case SWAW_STEP_PEEK:
+ p_dm_swat_table->pkt_cnt_sw_ant_div_by_ctrl_frame = 0;
+ p_dm_swat_table->is_sw_ant_div_by_ctrl_frame = true;
+ p_dm_fat_table->main_ant_ctrl_frame_cnt = 0;
+ p_dm_fat_table->aux_ant_ctrl_frame_cnt = 0;
+ p_dm_fat_table->main_ant_ctrl_frame_sum = 0;
+ p_dm_fat_table->aux_ant_ctrl_frame_sum = 0;
+ p_dm_fat_table->cck_ctrl_frame_cnt_main = 0;
+ p_dm_fat_table->cck_ctrl_frame_cnt_aux = 0;
+ p_dm_fat_table->ofdm_ctrl_frame_cnt_main = 0;
+ p_dm_fat_table->ofdm_ctrl_frame_cnt_aux = 0;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_S0S1_SwAntDivForAPMode(): Start peek and reset counter\n"));
+ break;
+ case SWAW_STEP_DETERMINE:
+ p_dm_swat_table->is_sw_ant_div_by_ctrl_frame = false;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_S0S1_SwAntDivForAPMode(): Stop peek\n"));
+ break;
+ default:
+ p_dm_swat_table->is_sw_ant_div_by_ctrl_frame = false;
+ break;
+ }
+}
+
+void
+odm_antsel_statistics_of_ctrl_frame(
+ void *p_dm_void,
+ u8 antsel_tr_mux,
+ u32 rx_pwdb_all
+
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+
+ if (antsel_tr_mux == ANT1_2G) {
+ p_dm_fat_table->main_ant_ctrl_frame_sum += rx_pwdb_all;
+ p_dm_fat_table->main_ant_ctrl_frame_cnt++;
+ } else {
+ p_dm_fat_table->aux_ant_ctrl_frame_sum += rx_pwdb_all;
+ p_dm_fat_table->aux_ant_ctrl_frame_cnt++;
+ }
+}
+
+void
+odm_s0s1_sw_ant_div_by_ctrl_frame_process_rssi(
+ void *p_dm_void,
+ void *p_phy_info_void,
+ void *p_pkt_info_void
+ /* struct _odm_phy_status_info_* p_phy_info, */
+ /* struct _odm_per_pkt_info_* p_pktinfo */
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _odm_phy_status_info_ *p_phy_info = (struct _odm_phy_status_info_ *)p_phy_info_void;
+ struct _odm_per_pkt_info_ *p_pktinfo = (struct _odm_per_pkt_info_ *)p_pkt_info_void;
+ struct _sw_antenna_switch_ *p_dm_swat_table = &p_dm_odm->dm_swat_table;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+ bool is_cck_rate;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_ANT_DIV))
+ return;
+
+ if (p_dm_odm->ant_div_type != S0S1_SW_ANTDIV)
+ return;
+
+ /* In try state */
+ if (!p_dm_swat_table->is_sw_ant_div_by_ctrl_frame)
+ return;
+
+ /* No HW error and match receiver address */
+ if (!p_pktinfo->is_to_self)
+ return;
+
+ p_dm_swat_table->pkt_cnt_sw_ant_div_by_ctrl_frame++;
+ is_cck_rate = ((p_pktinfo->data_rate >= DESC_RATE1M) && (p_pktinfo->data_rate <= DESC_RATE11M)) ? true : false;
+
+ if (is_cck_rate) {
+ p_dm_fat_table->antsel_rx_keep_0 = (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? ANT1_2G : ANT2_2G;
+
+ if (p_dm_fat_table->antsel_rx_keep_0 == ANT1_2G)
+ p_dm_fat_table->cck_ctrl_frame_cnt_main++;
+ else
+ p_dm_fat_table->cck_ctrl_frame_cnt_aux++;
+
+ odm_antsel_statistics_of_ctrl_frame(p_dm_odm, p_dm_fat_table->antsel_rx_keep_0, p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A]);
+ } else {
+ if (p_dm_fat_table->antsel_rx_keep_0 == ANT1_2G)
+ p_dm_fat_table->ofdm_ctrl_frame_cnt_main++;
+ else
+ p_dm_fat_table->ofdm_ctrl_frame_cnt_aux++;
+
+ odm_antsel_statistics_of_ctrl_frame(p_dm_odm, p_dm_fat_table->antsel_rx_keep_0, p_phy_info->rx_pwdb_all);
+ }
+}
+
+#endif /* #if (RTL8723B_SUPPORT == 1) || (RTL8821A_SUPPORT == 1) */
+
+
+
+
+void
+odm_set_next_mac_addr_target(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+ struct sta_info *p_entry;
+ u32 value32, i;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_set_next_mac_addr_target() ==>\n"));
+
+ if (p_dm_odm->is_linked) {
+ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
+
+ if ((p_dm_fat_table->train_idx + 1) == ODM_ASSOCIATE_ENTRY_NUM)
+ p_dm_fat_table->train_idx = 0;
+ else
+ p_dm_fat_table->train_idx++;
+
+ p_entry = p_dm_odm->p_odm_sta_info[p_dm_fat_table->train_idx];
+
+ if (IS_STA_VALID(p_entry)) {
+
+ /*Match MAC ADDR*/
+ value32 = (p_entry->hwaddr[5] << 8) | p_entry->hwaddr[4];
+
+ odm_set_mac_reg(p_dm_odm, 0x7b4, 0xFFFF, value32);/*0x7b4~0x7b5*/
+
+ value32 = (p_entry->hwaddr[3] << 24) | (p_entry->hwaddr[2] << 16) | (p_entry->hwaddr[1] << 8) | p_entry->hwaddr[0];
+ odm_set_mac_reg(p_dm_odm, 0x7b0, MASKDWORD, value32);/*0x7b0~0x7b3*/
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("p_dm_fat_table->train_idx=%d\n", p_dm_fat_table->train_idx));
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Training MAC addr = %x:%x:%x:%x:%x:%x\n",
+ p_entry->hwaddr[5], p_entry->hwaddr[4], p_entry->hwaddr[3], p_entry->hwaddr[2], p_entry->hwaddr[1], p_entry->hwaddr[0]));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Training MAC addr = %x:%x:%x:%x:%x:%x\n",
+ p_entry->MacAddr[5], p_entry->MacAddr[4], p_entry->MacAddr[3], p_entry->MacAddr[2], p_entry->MacAddr[1], p_entry->MacAddr[0]));
+ break;
+ }
+ }
+ }
+}
+
+#if (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) || (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY))
+
+void
+odm_fast_ant_training(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+
+ u32 max_rssi_path_a = 0, pckcnt_path_a = 0;
+ u8 i, target_ant_path_a = 0;
+ bool is_pkt_filter_macth_path_a = false;
+#if (RTL8192E_SUPPORT == 1)
+ u32 max_rssi_path_b = 0, pckcnt_path_b = 0;
+ u8 target_ant_path_b = 0;
+ bool is_pkt_filter_macth_path_b = false;
+#endif
+
+
+ if (!p_dm_odm->is_linked) { /* is_linked==False */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[No Link!!!]\n"));
+
+ if (p_dm_fat_table->is_become_linked == true) {
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_OFF);
+ phydm_fast_training_enable(p_dm_odm, FAT_OFF);
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_REG);
+ p_dm_fat_table->is_become_linked = p_dm_odm->is_linked;
+ }
+ return;
+ } else {
+ if (p_dm_fat_table->is_become_linked == false) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Linked!!!]\n"));
+ p_dm_fat_table->is_become_linked = p_dm_odm->is_linked;
+ }
+ }
+
+ if (*(p_dm_fat_table->p_force_tx_ant_by_desc) == false) {
+ if (p_dm_odm->is_one_entry_only == true)
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_REG);
+ else
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_DESC);
+ }
+
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E)
+ odm_set_bb_reg(p_dm_odm, 0x864, BIT(2) | BIT(1) | BIT(0), ((p_dm_odm->fat_comb_a) - 1));
+#if (RTL8192E_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8192E) {
+ odm_set_bb_reg(p_dm_odm, 0xB38, BIT(2) | BIT1 | BIT0, ((p_dm_odm->fat_comb_a) - 1)); /* path-A */ /* ant combination=regB38[2:0]+1 */
+ odm_set_bb_reg(p_dm_odm, 0xB38, BIT(18) | BIT17 | BIT16, ((p_dm_odm->fat_comb_b) - 1)); /* path-B */ /* ant combination=regB38[18:16]+1 */
+ }
+#endif
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("==>odm_fast_ant_training()\n"));
+
+ /* 1 TRAINING STATE */
+ if (p_dm_fat_table->fat_state == FAT_TRAINING_STATE) {
+ /* 2 Caculate RSSI per Antenna */
+
+ /* 3 [path-A]--------------------------- */
+ for (i = 0; i < (p_dm_odm->fat_comb_a); i++) { /* i : antenna index */
+ if (p_dm_fat_table->ant_rssi_cnt[i] == 0)
+ p_dm_fat_table->ant_ave_rssi[i] = 0;
+ else {
+ p_dm_fat_table->ant_ave_rssi[i] = p_dm_fat_table->ant_sum_rssi[i] / p_dm_fat_table->ant_rssi_cnt[i];
+ is_pkt_filter_macth_path_a = true;
+ }
+
+ if (p_dm_fat_table->ant_ave_rssi[i] > max_rssi_path_a) {
+ max_rssi_path_a = p_dm_fat_table->ant_ave_rssi[i];
+ pckcnt_path_a = p_dm_fat_table->ant_rssi_cnt[i];
+ target_ant_path_a = i ;
+ } else if (p_dm_fat_table->ant_ave_rssi[i] == max_rssi_path_a) {
+ if ((p_dm_fat_table->ant_rssi_cnt[i]) > pckcnt_path_a) {
+ max_rssi_path_a = p_dm_fat_table->ant_ave_rssi[i];
+ pckcnt_path_a = p_dm_fat_table->ant_rssi_cnt[i];
+ target_ant_path_a = i ;
+ }
+ }
+
+ ODM_RT_TRACE("*** ant-index : [ %d ], counter = (( %d )), Avg RSSI = (( %d ))\n", i, p_dm_fat_table->ant_rssi_cnt[i], p_dm_fat_table->ant_ave_rssi[i]);
+ }
+
+ /* 1 DECISION STATE */
+
+ /* 2 Select TRX Antenna */
+
+ phydm_fast_training_enable(p_dm_odm, FAT_OFF);
+
+ /* 3 [path-A]--------------------------- */
+ if (is_pkt_filter_macth_path_a == false) {
+ /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("{path-A}: None Packet is matched\n")); */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("{path-A}: None Packet is matched\n"));
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_OFF);
+ } else {
+ ODM_RT_TRACE("target_ant_path_a = (( %d )) , max_rssi_path_a = (( %d ))\n", target_ant_path_a, max_rssi_path_a);
+
+ /* 3 [ update RX-optional ant ] Default RX is Omni, Optional RX is the best decision by FAT */
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E)
+ odm_set_bb_reg(p_dm_odm, 0x864, BIT(8) | BIT(7) | BIT(6), target_ant_path_a);
+ else if (p_dm_odm->support_ic_type == ODM_RTL8192E) {
+ odm_set_bb_reg(p_dm_odm, 0xB38, BIT(8) | BIT7 | BIT6, target_ant_path_a); /* Optional RX [pth-A] */
+ }
+ /* 3 [ update TX ant ] */
+ odm_update_tx_ant(p_dm_odm, target_ant_path_a, (p_dm_fat_table->train_idx));
+
+ if (target_ant_path_a == 0)
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_OFF);
+ }
+
+ /* 2 Reset counter */
+ for (i = 0; i < (p_dm_odm->fat_comb_a); i++) {
+ p_dm_fat_table->ant_sum_rssi[i] = 0;
+ p_dm_fat_table->ant_rssi_cnt[i] = 0;
+ }
+
+ p_dm_fat_table->fat_state = FAT_PREPARE_STATE;
+ return;
+ }
+
+ /* 1 NORMAL STATE */
+ if (p_dm_fat_table->fat_state == FAT_PREPARE_STATE) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Start Prepare state ]\n"));
+
+ odm_set_next_mac_addr_target(p_dm_odm);
+
+ /* 2 Prepare Training */
+ p_dm_fat_table->fat_state = FAT_TRAINING_STATE;
+ phydm_fast_training_enable(p_dm_odm, FAT_ON);
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_ON); /* enable HW AntDiv */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Start Training state]\n"));
+
+ odm_set_timer(p_dm_odm, &p_dm_odm->fast_ant_training_timer, p_dm_odm->antdiv_intvl); /* ms */
+ }
+
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
+void odm_fast_ant_training_callback(void *p_dm_void)
+#else
+void odm_fast_ant_training_callback(struct timer_list *t)
+#endif
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+#else
+ struct PHY_DM_STRUCT *p_dm_odm = from_timer(p_dm_odm, t, fast_ant_training_timer);
+#endif
+ struct _ADAPTER *padapter = p_dm_odm->adapter;
+
+ if (padapter->net_closed == true)
+ return;
+ /* if(*p_dm_odm->p_is_net_closed == true) */
+ /* return; */
+
+#if USE_WORKITEM
+ odm_schedule_work_item(&p_dm_odm->fast_ant_training_workitem);
+#else
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("******odm_fast_ant_training_callback******\n"));
+ odm_fast_ant_training(p_dm_odm);
+#endif
+}
+
+void
+odm_fast_ant_training_work_item_callback(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("******odm_fast_ant_training_work_item_callback******\n"));
+ odm_fast_ant_training(p_dm_odm);
+}
+
+#endif
+
+#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1
+
+u32
+phydm_construct_hl_beam_codeword(
+ void *p_dm_void,
+ u32 *beam_pattern_idx,
+ u32 ant_num
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _SMART_ANTENNA_TRAINNING_ *pdm_sat_table = &(p_dm_odm->dm_sat_table);
+ u32 codeword = 0;
+ u32 data_tmp;
+ u32 i;
+ u32 break_counter = 0;
+
+ if (ant_num < 8) {
+ for (i = 0; i < (pdm_sat_table->ant_num_total); i++) {
+ /*ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("beam_pattern_num[%x] = %x\n",i,beam_pattern_num[i] ));*/
+ if ((i < (pdm_sat_table->first_train_ant - 1)) /*|| (break_counter >= (pdm_sat_table->ant_num))*/) {
+ data_tmp = 0;
+ /**/
+ } else {
+
+ break_counter++;
+
+ if (beam_pattern_idx[i] == 0) {
+
+ if (*p_dm_odm->p_band_type == ODM_BAND_5G)
+ data_tmp = pdm_sat_table->rfu_codeword_table_5g[0];
+ else
+ data_tmp = pdm_sat_table->rfu_codeword_table[0];
+
+ } else if (beam_pattern_idx[i] == 1) {
+
+
+ if (*p_dm_odm->p_band_type == ODM_BAND_5G)
+ data_tmp = pdm_sat_table->rfu_codeword_table_5g[1];
+ else
+ data_tmp = pdm_sat_table->rfu_codeword_table[1];
+
+ } else if (beam_pattern_idx[i] == 2) {
+
+ if (*p_dm_odm->p_band_type == ODM_BAND_5G)
+ data_tmp = pdm_sat_table->rfu_codeword_table_5g[2];
+ else
+ data_tmp = pdm_sat_table->rfu_codeword_table[2];
+
+ } else if (beam_pattern_idx[i] == 3) {
+
+ if (*p_dm_odm->p_band_type == ODM_BAND_5G)
+ data_tmp = pdm_sat_table->rfu_codeword_table_5g[3];
+ else
+ data_tmp = pdm_sat_table->rfu_codeword_table[3];
+ }
+ }
+
+
+ codeword |= (data_tmp << (i * 4));
+
+ }
+ }
+
+ return codeword;
+}
+
+void
+phydm_update_beam_pattern(
+ void *p_dm_void,
+ u32 codeword,
+ u32 codeword_length
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _SMART_ANTENNA_TRAINNING_ *pdm_sat_table = &(p_dm_odm->dm_sat_table);
+ u8 i;
+ bool beam_ctrl_signal;
+ u32 one = 0x1;
+ u32 reg44_tmp_p, reg44_tmp_n, reg44_ori;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] Set Beam Pattern =0x%x\n", codeword));
+
+ reg44_ori = odm_get_mac_reg(p_dm_odm, 0x44, MASKDWORD);
+ /*ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("reg44_ori =0x%x\n", reg44_ori));*/
+
+ for (i = 0; i <= (codeword_length - 1); i++) {
+ beam_ctrl_signal = (bool)((codeword & BIT(i)) >> i);
+
+ if (p_dm_odm->debug_components & ODM_COMP_ANT_DIV) {
+
+ if (i == (codeword_length - 1)) {
+ dbg_print("%d ]\n", beam_ctrl_signal);
+ /**/
+ } else if (i == 0) {
+ dbg_print("Send codeword[1:24] ---> [ %d ", beam_ctrl_signal);
+ /**/
+ } else if ((i % 4) == 3) {
+ dbg_print("%d | ", beam_ctrl_signal);
+ /**/
+ } else {
+ dbg_print("%d ", beam_ctrl_signal);
+ /**/
+ }
+ }
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8821) {
+ }
+ }
+}
+
+void
+phydm_update_rx_idle_beam(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+ struct _SMART_ANTENNA_TRAINNING_ *pdm_sat_table = &(p_dm_odm->dm_sat_table);
+ u32 i;
+
+ pdm_sat_table->update_beam_codeword = phydm_construct_hl_beam_codeword(p_dm_odm, &(pdm_sat_table->rx_idle_beam[0]), pdm_sat_table->ant_num);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Set target beam_pattern codeword = (( 0x%x ))\n", pdm_sat_table->update_beam_codeword));
+
+ for (i = 0; i < (pdm_sat_table->ant_num); i++) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Update Rx-Idle-Beam ] RxIdleBeam[%d] =%d\n", i, pdm_sat_table->rx_idle_beam[i]));
+ /**/
+ }
+
+#if DEV_BUS_TYPE == RT_PCI_INTERFACE
+ phydm_update_beam_pattern(p_dm_odm, pdm_sat_table->update_beam_codeword, pdm_sat_table->data_codeword_bit_num);
+#else
+ odm_schedule_work_item(&pdm_sat_table->hl_smart_antenna_workitem);
+ /*odm_stall_execution(1);*/
+#endif
+
+ pdm_sat_table->pre_codeword = pdm_sat_table->update_beam_codeword;
+}
+
+void
+phydm_hl_smart_ant_debug(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _SMART_ANTENNA_TRAINNING_ *pdm_sat_table = &(p_dm_odm->dm_sat_table);
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+ u32 one = 0x1;
+ u32 codeword_length = pdm_sat_table->data_codeword_bit_num;
+ u32 beam_ctrl_signal, i;
+
+ if (dm_value[0] == 1) { /*fix beam pattern*/
+
+ pdm_sat_table->fix_beam_pattern_en = dm_value[1];
+
+ if (pdm_sat_table->fix_beam_pattern_en == 1) {
+
+ pdm_sat_table->fix_beam_pattern_codeword = dm_value[2];
+
+ if (pdm_sat_table->fix_beam_pattern_codeword > (one << codeword_length)) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] Codeword overflow, Current codeword is ((0x%x)), and should be less than ((%d))bit\n",
+ pdm_sat_table->fix_beam_pattern_codeword, codeword_length));
+ (pdm_sat_table->fix_beam_pattern_codeword) &= 0xffffff;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] Auto modify to (0x%x)\n", pdm_sat_table->fix_beam_pattern_codeword));
+ }
+
+ pdm_sat_table->update_beam_codeword = pdm_sat_table->fix_beam_pattern_codeword;
+
+ /*---------------------------------------------------------*/
+ PHYDM_SNPRINTF((output + used, out_len - used, "Fix Beam Pattern\n"));
+ for (i = 0; i <= (codeword_length - 1); i++) {
+ beam_ctrl_signal = (bool)((pdm_sat_table->update_beam_codeword & BIT(i)) >> i);
+
+ if (i == (codeword_length - 1)) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "%d]\n", beam_ctrl_signal));
+ /**/
+ } else if (i == 0) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "Send Codeword[1:24] to RFU -> [%d", beam_ctrl_signal));
+ /**/
+ } else if ((i % 4) == 3) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "%d|", beam_ctrl_signal));
+ /**/
+ } else {
+ PHYDM_SNPRINTF((output + used, out_len - used, "%d", beam_ctrl_signal));
+ /**/
+ }
+ }
+ /*---------------------------------------------------------*/
+
+
+#if DEV_BUS_TYPE == RT_PCI_INTERFACE
+ phydm_update_beam_pattern(p_dm_odm, pdm_sat_table->update_beam_codeword, pdm_sat_table->data_codeword_bit_num);
+#else
+ odm_schedule_work_item(&pdm_sat_table->hl_smart_antenna_workitem);
+ /*odm_stall_execution(1);*/
+#endif
+ } else if (pdm_sat_table->fix_beam_pattern_en == 0)
+ PHYDM_SNPRINTF((output + used, out_len - used, "[ SmartAnt ] Smart Antenna: Enable\n"));
+
+ } else if (dm_value[0] == 2) { /*set latch time*/
+
+ pdm_sat_table->latch_time = dm_value[1];
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] latch_time =0x%x\n", pdm_sat_table->latch_time));
+ } else if (dm_value[0] == 3) {
+
+ pdm_sat_table->fix_training_num_en = dm_value[1];
+
+ if (pdm_sat_table->fix_training_num_en == 1) {
+ pdm_sat_table->per_beam_training_pkt_num = (u8)dm_value[2];
+ pdm_sat_table->decision_holding_period = (u8)dm_value[3];
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "[SmartAnt][Dbg] Fix_train_en = (( %d )), train_pkt_num = (( %d )), holding_period = (( %d )),\n",
+ pdm_sat_table->fix_training_num_en, pdm_sat_table->per_beam_training_pkt_num, pdm_sat_table->decision_holding_period));
+
+ } else if (pdm_sat_table->fix_training_num_en == 0) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "[ SmartAnt ] AUTO per_beam_training_pkt_num\n"));
+ /**/
+ }
+ } else if (dm_value[0] == 4) {
+
+ if (dm_value[1] == 1) {
+ pdm_sat_table->ant_num = 1;
+ pdm_sat_table->first_train_ant = MAIN_ANT;
+
+ } else if (dm_value[1] == 2) {
+ pdm_sat_table->ant_num = 1;
+ pdm_sat_table->first_train_ant = AUX_ANT;
+
+ } else if (dm_value[1] == 3) {
+ pdm_sat_table->ant_num = 2;
+ pdm_sat_table->first_train_ant = MAIN_ANT;
+ }
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "[ SmartAnt ] Set ant Num = (( %d )), first_train_ant = (( %d ))\n",
+ pdm_sat_table->ant_num, (pdm_sat_table->first_train_ant - 1)));
+ } else if (dm_value[0] == 5) {
+
+ if (dm_value[1] <= 3) {
+ pdm_sat_table->rfu_codeword_table[dm_value[1]] = dm_value[2];
+ PHYDM_SNPRINTF((output + used, out_len - used, "[ SmartAnt ] Set Beam_2G: (( %d )), RFU codeword table = (( 0x%x ))\n",
+ dm_value[1], dm_value[2]));
+ } else {
+ for (i = 0; i < 4; i++) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "[ SmartAnt ] Show Beam_2G: (( %d )), RFU codeword table = (( 0x%x ))\n",
+ i, pdm_sat_table->rfu_codeword_table[i]));
+ }
+ }
+ } else if (dm_value[0] == 6) {
+
+ if (dm_value[1] <= 3) {
+ pdm_sat_table->rfu_codeword_table_5g[dm_value[1]] = dm_value[2];
+ PHYDM_SNPRINTF((output + used, out_len - used, "[ SmartAnt ] Set Beam_5G: (( %d )), RFU codeword table = (( 0x%x ))\n",
+ dm_value[1], dm_value[2]));
+ } else {
+ for (i = 0; i < 4; i++) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "[ SmartAnt ] Show Beam_5G: (( %d )), RFU codeword table = (( 0x%x ))\n",
+ i, pdm_sat_table->rfu_codeword_table_5g[i]));
+ }
+ }
+ } else if (dm_value[0] == 7) {
+
+ if (dm_value[1] <= 4) {
+
+ pdm_sat_table->beam_patten_num_each_ant = dm_value[1];
+ PHYDM_SNPRINTF((output + used, out_len - used, "[ SmartAnt ] Set Beam number = (( %d ))\n",
+ pdm_sat_table->beam_patten_num_each_ant));
+ } else {
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "[ SmartAnt ] Show Beam number = (( %d ))\n",
+ pdm_sat_table->beam_patten_num_each_ant));
+ }
+ }
+
+}
+
+
+void
+phydm_set_all_ant_same_beam_num(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _SMART_ANTENNA_TRAINNING_ *pdm_sat_table = &(p_dm_odm->dm_sat_table);
+
+ if (p_dm_odm->ant_div_type == HL_SW_SMART_ANT_TYPE1) { /*2ant for 8821A*/
+
+ pdm_sat_table->rx_idle_beam[0] = pdm_sat_table->fast_training_beam_num;
+ pdm_sat_table->rx_idle_beam[1] = pdm_sat_table->fast_training_beam_num;
+ }
+
+ pdm_sat_table->update_beam_codeword = phydm_construct_hl_beam_codeword(p_dm_odm, &(pdm_sat_table->rx_idle_beam[0]), pdm_sat_table->ant_num);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] Set all ant beam_pattern: codeword = (( 0x%x ))\n", pdm_sat_table->update_beam_codeword));
+
+#if DEV_BUS_TYPE == RT_PCI_INTERFACE
+ phydm_update_beam_pattern(p_dm_odm, pdm_sat_table->update_beam_codeword, pdm_sat_table->data_codeword_bit_num);
+#else
+ odm_schedule_work_item(&pdm_sat_table->hl_smart_antenna_workitem);
+ /*odm_stall_execution(1);*/
+#endif
+}
+
+void
+odm_fast_ant_training_hl_smart_antenna_type1(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _SMART_ANTENNA_TRAINNING_ *pdm_sat_table = &(p_dm_odm->dm_sat_table);
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &(p_dm_odm->dm_fat_table);
+ struct _sw_antenna_switch_ *p_dm_swat_table = &p_dm_odm->dm_swat_table;
+ u32 codeword = 0, i, j;
+ u32 target_ant;
+ u32 avg_rssi_tmp, avg_rssi_tmp_ma;
+ u32 target_ant_beam_max_rssi[SUPPORT_RF_PATH_NUM] = {0};
+ u32 max_beam_ant_rssi = 0;
+ u32 target_ant_beam[SUPPORT_RF_PATH_NUM] = {0};
+ u32 beam_tmp;
+ u8 next_ant;
+ u32 rssi_sorting_seq[SUPPORT_BEAM_PATTERN_NUM] = {0};
+ u32 rank_idx_seq[SUPPORT_BEAM_PATTERN_NUM] = {0};
+ u32 rank_idx_out[SUPPORT_BEAM_PATTERN_NUM] = {0};
+ u8 per_beam_rssi_diff_tmp = 0, training_pkt_num_offset;
+ u32 break_counter = 0;
+ u32 used_ant;
+
+
+ if (!p_dm_odm->is_linked) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[No Link!!!]\n"));
+
+ if (p_dm_fat_table->is_become_linked == true) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Link->no Link\n"));
+ p_dm_fat_table->fat_state = FAT_BEFORE_LINK_STATE;
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_OFF);
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_REG);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("change to (( %d )) FAT_state\n", p_dm_fat_table->fat_state));
+
+ p_dm_fat_table->is_become_linked = p_dm_odm->is_linked;
+ }
+ return;
+
+ } else {
+ if (p_dm_fat_table->is_become_linked == false) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Linked !!!]\n"));
+
+ p_dm_fat_table->fat_state = FAT_PREPARE_STATE;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("change to (( %d )) FAT_state\n", p_dm_fat_table->fat_state));
+
+ /*pdm_sat_table->fast_training_beam_num = 0;*/
+ /*phydm_set_all_ant_same_beam_num(p_dm_odm);*/
+
+ p_dm_fat_table->is_become_linked = p_dm_odm->is_linked;
+ }
+ }
+
+ if (*(p_dm_fat_table->p_force_tx_ant_by_desc) == false) {
+ if (p_dm_odm->is_one_entry_only == true)
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_REG);
+ else
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_DESC);
+ }
+
+ /*ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("HL Smart ant Training: state (( %d ))\n", p_dm_fat_table->fat_state));*/
+
+ /* [DECISION STATE] */
+ /*=======================================================================================*/
+ if (p_dm_fat_table->fat_state == FAT_DECISION_STATE) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 3. In Decision state]\n"));
+ phydm_fast_training_enable(p_dm_odm, FAT_OFF);
+
+ break_counter = 0;
+ /*compute target beam in each antenna*/
+ for (i = (pdm_sat_table->first_train_ant - 1); i < pdm_sat_table->ant_num_total; i++) {
+ for (j = 0; j < (pdm_sat_table->beam_patten_num_each_ant); j++) {
+
+ if (pdm_sat_table->pkt_rssi_cnt[i][j] == 0) {
+ avg_rssi_tmp = pdm_sat_table->pkt_rssi_pre[i][j];
+ avg_rssi_tmp = (avg_rssi_tmp >= 2) ? (avg_rssi_tmp - 2) : avg_rssi_tmp;
+ avg_rssi_tmp_ma = avg_rssi_tmp;
+ } else {
+ avg_rssi_tmp = (pdm_sat_table->pkt_rssi_sum[i][j]) / (pdm_sat_table->pkt_rssi_cnt[i][j]);
+ avg_rssi_tmp_ma = (avg_rssi_tmp + pdm_sat_table->pkt_rssi_pre[i][j]) >> 1;
+ }
+
+ rssi_sorting_seq[j] = avg_rssi_tmp;
+ pdm_sat_table->pkt_rssi_pre[i][j] = avg_rssi_tmp;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ant[%d], Beam[%d]: pkt_cnt=(( %d )), avg_rssi_MA=(( %d )), avg_rssi=(( %d ))\n",
+ i, j, pdm_sat_table->pkt_rssi_cnt[i][j], avg_rssi_tmp_ma, avg_rssi_tmp));
+
+ if (avg_rssi_tmp > target_ant_beam_max_rssi[i]) {
+ target_ant_beam[i] = j;
+ target_ant_beam_max_rssi[i] = avg_rssi_tmp;
+ }
+
+ /*reset counter value*/
+ pdm_sat_table->pkt_rssi_sum[i][j] = 0;
+ pdm_sat_table->pkt_rssi_cnt[i][j] = 0;
+
+ }
+ pdm_sat_table->rx_idle_beam[i] = target_ant_beam[i];
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("---------> Target of ant[%d]: Beam_num-(( %d )) RSSI= ((%d))\n",
+ i, target_ant_beam[i], target_ant_beam_max_rssi[i]));
+
+ /*sorting*/
+ /*
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Pre]rssi_sorting_seq = [%d, %d, %d, %d]\n", rssi_sorting_seq[0], rssi_sorting_seq[1], rssi_sorting_seq[2], rssi_sorting_seq[3]));
+ */
+
+ /*phydm_seq_sorting(p_dm_odm, &rssi_sorting_seq[0], &rank_idx_seq[0], &rank_idx_out[0], SUPPORT_BEAM_PATTERN_NUM);*/
+
+ /*
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Post]rssi_sorting_seq = [%d, %d, %d, %d]\n", rssi_sorting_seq[0], rssi_sorting_seq[1], rssi_sorting_seq[2], rssi_sorting_seq[3]));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Post]rank_idx_seq = [%d, %d, %d, %d]\n", rank_idx_seq[0], rank_idx_seq[1], rank_idx_seq[2], rank_idx_seq[3]));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Post]rank_idx_out = [%d, %d, %d, %d]\n", rank_idx_out[0], rank_idx_out[1], rank_idx_out[2], rank_idx_out[3]));
+ */
+
+ if (target_ant_beam_max_rssi[i] > max_beam_ant_rssi) {
+ target_ant = i;
+ max_beam_ant_rssi = target_ant_beam_max_rssi[i];
+ /*ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Target of ant = (( %d )) max_beam_ant_rssi = (( %d ))\n",
+ target_ant, max_beam_ant_rssi));*/
+ }
+ break_counter++;
+ if (break_counter >= (pdm_sat_table->ant_num))
+ break;
+ }
+
+#ifdef CONFIG_FAT_PATCH
+ break_counter = 0;
+ for (i = (pdm_sat_table->first_train_ant - 1); i < pdm_sat_table->ant_num_total; i++) {
+ for (j = 0; j < (pdm_sat_table->beam_patten_num_each_ant); j++) {
+
+ per_beam_rssi_diff_tmp = (u8)(max_beam_ant_rssi - pdm_sat_table->pkt_rssi_pre[i][j]);
+ pdm_sat_table->beam_train_rssi_diff[i][j] = per_beam_rssi_diff_tmp;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ant[%d], Beam[%d]: RSSI_diff= ((%d))\n",
+ i, j, per_beam_rssi_diff_tmp));
+ }
+ break_counter++;
+ if (break_counter >= (pdm_sat_table->ant_num))
+ break;
+ }
+#endif
+
+ if (target_ant == 0)
+ target_ant = MAIN_ANT;
+ else if (target_ant == 1)
+ target_ant = AUX_ANT;
+
+ if (pdm_sat_table->ant_num > 1) {
+ /* [ update RX ant ]*/
+ odm_update_rx_idle_ant(p_dm_odm, (u8)target_ant);
+
+ /* [ update TX ant ]*/
+ odm_update_tx_ant(p_dm_odm, (u8)target_ant, (p_dm_fat_table->train_idx));
+ }
+
+ /*set beam in each antenna*/
+ phydm_update_rx_idle_beam(p_dm_odm);
+
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_ON);
+ p_dm_fat_table->fat_state = FAT_PREPARE_STATE;
+ return;
+
+ }
+ /* [TRAINING STATE] */
+ else if (p_dm_fat_table->fat_state == FAT_TRAINING_STATE) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 2. In Training state]\n"));
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("fat_beam_n = (( %d )), pre_fat_beam_n = (( %d ))\n",
+ pdm_sat_table->fast_training_beam_num, pdm_sat_table->pre_fast_training_beam_num));
+
+ if (pdm_sat_table->fast_training_beam_num > pdm_sat_table->pre_fast_training_beam_num)
+
+ pdm_sat_table->force_update_beam_en = 0;
+
+ else {
+
+ pdm_sat_table->force_update_beam_en = 1;
+
+ pdm_sat_table->pkt_counter = 0;
+ beam_tmp = pdm_sat_table->fast_training_beam_num;
+ if (pdm_sat_table->fast_training_beam_num >= (pdm_sat_table->beam_patten_num_each_ant - 1)) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Timeout Update] Beam_num (( %d )) -> (( decision ))\n", pdm_sat_table->fast_training_beam_num));
+ p_dm_fat_table->fat_state = FAT_DECISION_STATE;
+ odm_fast_ant_training_hl_smart_antenna_type1(p_dm_odm);
+
+ } else {
+ pdm_sat_table->fast_training_beam_num++;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Timeout Update] Beam_num (( %d )) -> (( %d ))\n", beam_tmp, pdm_sat_table->fast_training_beam_num));
+ phydm_set_all_ant_same_beam_num(p_dm_odm);
+ p_dm_fat_table->fat_state = FAT_TRAINING_STATE;
+
+ }
+ }
+ pdm_sat_table->pre_fast_training_beam_num = pdm_sat_table->fast_training_beam_num;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[prepare state] Update Pre_Beam =(( %d ))\n", pdm_sat_table->pre_fast_training_beam_num));
+ }
+ /* [Prepare state] */
+ /*=======================================================================================*/
+ else if (p_dm_fat_table->fat_state == FAT_PREPARE_STATE) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("\n\n[ 1. In Prepare state]\n"));
+
+ if (p_dm_odm->pre_traffic_load == (p_dm_odm->traffic_load)) {
+ if (pdm_sat_table->decision_holding_period != 0) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Holding_period = (( %d )), return!!!\n", pdm_sat_table->decision_holding_period));
+ pdm_sat_table->decision_holding_period--;
+ return;
+ }
+ }
+
+
+ /* Set training packet number*/
+ if (pdm_sat_table->fix_training_num_en == 0) {
+
+ switch (p_dm_odm->traffic_load) {
+
+ case TRAFFIC_HIGH:
+ pdm_sat_table->per_beam_training_pkt_num = 8;
+ pdm_sat_table->decision_holding_period = 2;
+ break;
+ case TRAFFIC_MID:
+ pdm_sat_table->per_beam_training_pkt_num = 6;
+ pdm_sat_table->decision_holding_period = 3;
+ break;
+ case TRAFFIC_LOW:
+ pdm_sat_table->per_beam_training_pkt_num = 3; /*ping 60000*/
+ pdm_sat_table->decision_holding_period = 4;
+ break;
+ case TRAFFIC_ULTRA_LOW:
+ pdm_sat_table->per_beam_training_pkt_num = 1;
+ pdm_sat_table->decision_holding_period = 6;
+ break;
+ default:
+ break;
+ }
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Fix_training_en = (( %d )), training_pkt_num_base = (( %d )), holding_period = ((%d))\n",
+ pdm_sat_table->fix_training_num_en, pdm_sat_table->per_beam_training_pkt_num, pdm_sat_table->decision_holding_period));
+
+
+#ifdef CONFIG_FAT_PATCH
+ break_counter = 0;
+ for (i = (pdm_sat_table->first_train_ant - 1); i < pdm_sat_table->ant_num_total; i++) {
+ for (j = 0; j < (pdm_sat_table->beam_patten_num_each_ant); j++) {
+
+ per_beam_rssi_diff_tmp = pdm_sat_table->beam_train_rssi_diff[i][j];
+ training_pkt_num_offset = per_beam_rssi_diff_tmp;
+
+ if ((pdm_sat_table->per_beam_training_pkt_num) > training_pkt_num_offset)
+ pdm_sat_table->beam_train_cnt[i][j] = pdm_sat_table->per_beam_training_pkt_num - training_pkt_num_offset;
+ else
+ pdm_sat_table->beam_train_cnt[i][j] = 1;
+
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ant[%d]: Beam_num-(( %d )) training_pkt_num = ((%d))\n",
+ i, j, pdm_sat_table->beam_train_cnt[i][j]));
+ }
+ break_counter++;
+ if (break_counter >= (pdm_sat_table->ant_num))
+ break;
+ }
+
+
+ phydm_fast_training_enable(p_dm_odm, FAT_OFF);
+ pdm_sat_table->pre_beacon_counter = pdm_sat_table->beacon_counter;
+ pdm_sat_table->update_beam_idx = 0;
+
+ if (*p_dm_odm->p_band_type == ODM_BAND_5G) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Set 5G ant\n"));
+ /*used_ant = (pdm_sat_table->first_train_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;*/
+ used_ant = pdm_sat_table->first_train_ant;
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Set 2.4G ant\n"));
+ used_ant = pdm_sat_table->first_train_ant;
+ }
+
+ odm_update_rx_idle_ant(p_dm_odm, (u8)used_ant);
+
+#else
+ /* Set training MAC addr. of target */
+ odm_set_next_mac_addr_target(p_dm_odm);
+ phydm_fast_training_enable(p_dm_odm, FAT_ON);
+#endif
+
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_OFF);
+ pdm_sat_table->pkt_counter = 0;
+ pdm_sat_table->fast_training_beam_num = 0;
+ phydm_set_all_ant_same_beam_num(p_dm_odm);
+ pdm_sat_table->pre_fast_training_beam_num = pdm_sat_table->fast_training_beam_num;
+ p_dm_fat_table->fat_state = FAT_TRAINING_STATE;
+ }
+
+}
+
+#endif /*#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1*/
+
+void
+odm_ant_div_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+ struct _sw_antenna_switch_ *p_dm_swat_table = &p_dm_odm->dm_swat_table;
+
+
+ if (!(p_dm_odm->support_ability & ODM_BB_ANT_DIV)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Return!!!] Not Support Antenna Diversity Function\n"));
+ return;
+ }
+ /* --- */
+
+ /* 2 [--General---] */
+ p_dm_odm->antdiv_period = 0;
+
+ p_dm_fat_table->is_become_linked = false;
+ p_dm_fat_table->ant_div_on_off = 0xff;
+
+ /* 3 - AP - */
+
+ /* 2 [---Set MAIN_ANT as default antenna if Auto-ant enable---] */
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_OFF);
+
+ p_dm_odm->ant_type = ODM_AUTO_ANT;
+
+ p_dm_fat_table->rx_idle_ant = 0xff; /*to make RX-idle-antenna will be updated absolutly*/
+ odm_update_rx_idle_ant(p_dm_odm, MAIN_ANT);
+ phydm_keep_rx_ack_ant_by_tx_ant_time(p_dm_odm, 0); /* Timming issue: keep Rx ant after tx for ACK ( 5 x 3.2 mu = 16mu sec)*/
+
+ /* 2 [---Set TX Antenna---] */
+ if (p_dm_fat_table->p_force_tx_ant_by_desc == NULL) {
+ p_dm_fat_table->force_tx_ant_by_desc = 0;
+ p_dm_fat_table->p_force_tx_ant_by_desc = &(p_dm_fat_table->force_tx_ant_by_desc);
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("p_force_tx_ant_by_desc = %d\n", *p_dm_fat_table->p_force_tx_ant_by_desc));
+
+ if (*(p_dm_fat_table->p_force_tx_ant_by_desc) == true)
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_DESC);
+ else
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_REG);
+
+
+ /* 2 [--88E---] */
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E) {
+#if (RTL8188E_SUPPORT == 1)
+ /* p_dm_odm->ant_div_type = CGCS_RX_HW_ANTDIV; */
+ /* p_dm_odm->ant_div_type = CG_TRX_HW_ANTDIV; */
+ /* p_dm_odm->ant_div_type = CG_TRX_SMART_ANTDIV; */
+
+ if ((p_dm_odm->ant_div_type != CGCS_RX_HW_ANTDIV) && (p_dm_odm->ant_div_type != CG_TRX_HW_ANTDIV) && (p_dm_odm->ant_div_type != CG_TRX_SMART_ANTDIV)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Return!!!] 88E Not Supprrt This AntDiv type\n"));
+ p_dm_odm->support_ability &= ~(ODM_BB_ANT_DIV);
+ return;
+ }
+
+ if (p_dm_odm->ant_div_type == CGCS_RX_HW_ANTDIV)
+ odm_rx_hw_ant_div_init_88e(p_dm_odm);
+ else if (p_dm_odm->ant_div_type == CG_TRX_HW_ANTDIV)
+ odm_trx_hw_ant_div_init_88e(p_dm_odm);
+#if (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) || (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY))
+ else if (p_dm_odm->ant_div_type == CG_TRX_SMART_ANTDIV)
+ odm_smart_hw_ant_div_init_88e(p_dm_odm);
+#endif
+#endif
+ }
+
+ /* 2 [--92E---] */
+#if (RTL8192E_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8192E) {
+ /* p_dm_odm->ant_div_type = CGCS_RX_HW_ANTDIV; */
+ /* p_dm_odm->ant_div_type = CG_TRX_HW_ANTDIV; */
+ /* p_dm_odm->ant_div_type = CG_TRX_SMART_ANTDIV; */
+
+ if ((p_dm_odm->ant_div_type != CGCS_RX_HW_ANTDIV) && (p_dm_odm->ant_div_type != CG_TRX_HW_ANTDIV) && (p_dm_odm->ant_div_type != CG_TRX_SMART_ANTDIV)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Return!!!] 8192E Not Supprrt This AntDiv type\n"));
+ p_dm_odm->support_ability &= ~(ODM_BB_ANT_DIV);
+ return;
+ }
+
+ if (p_dm_odm->ant_div_type == CGCS_RX_HW_ANTDIV)
+ odm_rx_hw_ant_div_init_92e(p_dm_odm);
+ else if (p_dm_odm->ant_div_type == CG_TRX_HW_ANTDIV)
+ odm_trx_hw_ant_div_init_92e(p_dm_odm);
+#if (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) || (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY))
+ else if (p_dm_odm->ant_div_type == CG_TRX_SMART_ANTDIV)
+ odm_smart_hw_ant_div_init_92e(p_dm_odm);
+#endif
+
+ }
+#endif
+
+ /* 2 [--8723B---] */
+#if (RTL8723B_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8723B) {
+ p_dm_odm->ant_div_type = S0S1_SW_ANTDIV;
+ /* p_dm_odm->ant_div_type = CG_TRX_HW_ANTDIV; */
+
+ if (p_dm_odm->ant_div_type != S0S1_SW_ANTDIV && p_dm_odm->ant_div_type != CG_TRX_HW_ANTDIV) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Return!!!] 8723B Not Supprrt This AntDiv type\n"));
+ p_dm_odm->support_ability &= ~(ODM_BB_ANT_DIV);
+ return;
+ }
+
+ if (p_dm_odm->ant_div_type == S0S1_SW_ANTDIV)
+ odm_s0s1_sw_ant_div_init_8723b(p_dm_odm);
+ else if (p_dm_odm->ant_div_type == CG_TRX_HW_ANTDIV)
+ odm_trx_hw_ant_div_init_8723b(p_dm_odm);
+ }
+#endif
+ /*2 [--8723D---]*/
+#if (RTL8723D_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8723D) {
+ if (p_dm_fat_table->p_default_s0_s1 == NULL) {
+ p_dm_fat_table->default_s0_s1 = 1;
+ p_dm_fat_table->p_default_s0_s1 = &(p_dm_fat_table->default_s0_s1);
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("default_s0_s1 = %d\n", *p_dm_fat_table->p_default_s0_s1));
+
+ if (*(p_dm_fat_table->p_default_s0_s1) == true)
+ odm_update_rx_idle_ant(p_dm_odm, MAIN_ANT);
+ else
+ odm_update_rx_idle_ant(p_dm_odm, AUX_ANT);
+
+ if (p_dm_odm->ant_div_type == S0S1_TRX_HW_ANTDIV)
+ odm_trx_hw_ant_div_init_8723d(p_dm_odm);
+ else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Return!!!] 8723D Not Supprrt This AntDiv type\n"));
+ p_dm_odm->support_ability &= ~(ODM_BB_ANT_DIV);
+ return;
+ }
+
+ }
+#endif
+ /* 2 [--8811A 8821A---] */
+#if (RTL8821A_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8821) {
+#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1
+ p_dm_odm->ant_div_type = HL_SW_SMART_ANT_TYPE1;
+
+ if (p_dm_odm->ant_div_type == HL_SW_SMART_ANT_TYPE1) {
+
+ odm_trx_hw_ant_div_init_8821a(p_dm_odm);
+ phydm_hl_smart_ant_type1_init_8821a(p_dm_odm);
+ } else
+#endif
+ {
+ /*p_dm_odm->ant_div_type = CG_TRX_HW_ANTDIV;*/
+ p_dm_odm->ant_div_type = S0S1_SW_ANTDIV;
+
+ if (p_dm_odm->ant_div_type != CG_TRX_HW_ANTDIV && p_dm_odm->ant_div_type != S0S1_SW_ANTDIV) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Return!!!] 8821A & 8811A Not Supprrt This AntDiv type\n"));
+ p_dm_odm->support_ability &= ~(ODM_BB_ANT_DIV);
+ return;
+ }
+ if (p_dm_odm->ant_div_type == CG_TRX_HW_ANTDIV)
+ odm_trx_hw_ant_div_init_8821a(p_dm_odm);
+ else if (p_dm_odm->ant_div_type == S0S1_SW_ANTDIV)
+ odm_s0s1_sw_ant_div_init_8821a(p_dm_odm);
+ }
+ }
+#endif
+
+ /* 2 [--8821C---] */
+#if (RTL8821C_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8821C) {
+ p_dm_odm->ant_div_type = CG_TRX_HW_ANTDIV;
+ if (p_dm_odm->ant_div_type != CG_TRX_HW_ANTDIV) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Return!!!] 8821C Not Supprrt This AntDiv type\n"));
+ p_dm_odm->support_ability &= ~(ODM_BB_ANT_DIV);
+ return;
+ }
+ odm_trx_hw_ant_div_init_8821c(p_dm_odm);
+ }
+#endif
+
+ /* 2 [--8881A---] */
+#if (RTL8881A_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8881A) {
+ /* p_dm_odm->ant_div_type = CGCS_RX_HW_ANTDIV; */
+ /* p_dm_odm->ant_div_type = CG_TRX_HW_ANTDIV; */
+
+ if (p_dm_odm->ant_div_type == CG_TRX_HW_ANTDIV) {
+
+ odm_trx_hw_ant_div_init_8881a(p_dm_odm);
+ /**/
+ } else {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Return!!!] 8881A Not Supprrt This AntDiv type\n"));
+ p_dm_odm->support_ability &= ~(ODM_BB_ANT_DIV);
+ return;
+ }
+
+ odm_trx_hw_ant_div_init_8881a(p_dm_odm);
+ }
+#endif
+
+ /* 2 [--8812---] */
+#if (RTL8812A_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8812) {
+ /* p_dm_odm->ant_div_type = CG_TRX_HW_ANTDIV; */
+
+ if (p_dm_odm->ant_div_type != CG_TRX_HW_ANTDIV) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Return!!!] 8812A Not Supprrt This AntDiv type\n"));
+ p_dm_odm->support_ability &= ~(ODM_BB_ANT_DIV);
+ return;
+ }
+ odm_trx_hw_ant_div_init_8812a(p_dm_odm);
+ }
+#endif
+
+ /*[--8188F---]*/
+#if (RTL8188F_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8188F) {
+
+ p_dm_odm->ant_div_type = S0S1_SW_ANTDIV;
+ odm_s0s1_sw_ant_div_init_8188f(p_dm_odm);
+ }
+#endif
+
+}
+
+void
+odm_ant_div(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTER *p_adapter = p_dm_odm->adapter;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1
+ struct _SMART_ANTENNA_TRAINNING_ *pdm_sat_table = &(p_dm_odm->dm_sat_table);
+#endif
+
+ if (*p_dm_odm->p_band_type == ODM_BAND_5G) {
+ if (p_dm_fat_table->idx_ant_div_counter_5g < p_dm_odm->antdiv_period) {
+ p_dm_fat_table->idx_ant_div_counter_5g++;
+ return;
+ } else
+ p_dm_fat_table->idx_ant_div_counter_5g = 0;
+ } else if (*p_dm_odm->p_band_type == ODM_BAND_2_4G) {
+ if (p_dm_fat_table->idx_ant_div_counter_2g < p_dm_odm->antdiv_period) {
+ p_dm_fat_table->idx_ant_div_counter_2g++;
+ return;
+ } else
+ p_dm_fat_table->idx_ant_div_counter_2g = 0;
+ }
+
+ /* ---------- */
+ if (!(p_dm_odm->support_ability & ODM_BB_ANT_DIV)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Return!!!] Not Support Antenna Diversity Function\n"));
+ return;
+ }
+
+ /* ---------- */
+
+ if (p_dm_odm->antdiv_select == 1)
+ p_dm_odm->ant_type = ODM_FIX_MAIN_ANT;
+ else if (p_dm_odm->antdiv_select == 2)
+ p_dm_odm->ant_type = ODM_FIX_AUX_ANT;
+ else /* if (p_dm_odm->antdiv_select==0) */
+ p_dm_odm->ant_type = ODM_AUTO_ANT;
+
+ if (p_dm_odm->ant_type != ODM_AUTO_ANT) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Fix Antenna at (( %s ))\n", (p_dm_odm->ant_type == ODM_FIX_MAIN_ANT) ? "MAIN" : "AUX"));
+
+ if (p_dm_odm->ant_type != p_dm_odm->pre_ant_type) {
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_OFF);
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_REG);
+
+ if (p_dm_odm->ant_type == ODM_FIX_MAIN_ANT)
+ odm_update_rx_idle_ant(p_dm_odm, MAIN_ANT);
+ else if (p_dm_odm->ant_type == ODM_FIX_AUX_ANT)
+ odm_update_rx_idle_ant(p_dm_odm, AUX_ANT);
+ }
+ p_dm_odm->pre_ant_type = p_dm_odm->ant_type;
+ return;
+ } else {
+ if (p_dm_odm->ant_type != p_dm_odm->pre_ant_type) {
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_ON);
+ odm_tx_by_tx_desc_or_reg(p_dm_odm, TX_BY_DESC);
+ }
+ p_dm_odm->pre_ant_type = p_dm_odm->ant_type;
+ }
+
+
+ /* 3 ----------------------------------------------------------------------------------------------------------- */
+ /* 2 [--88E---] */
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E) {
+#if (RTL8188E_SUPPORT == 1)
+ if (p_dm_odm->ant_div_type == CG_TRX_HW_ANTDIV || p_dm_odm->ant_div_type == CGCS_RX_HW_ANTDIV)
+ odm_hw_ant_div(p_dm_odm);
+
+#if (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) || (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY))
+ else if (p_dm_odm->ant_div_type == CG_TRX_SMART_ANTDIV)
+ odm_fast_ant_training(p_dm_odm);
+#endif
+
+#endif
+
+ }
+ /* 2 [--92E---] */
+#if (RTL8192E_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8192E) {
+ if (p_dm_odm->ant_div_type == CGCS_RX_HW_ANTDIV || p_dm_odm->ant_div_type == CG_TRX_HW_ANTDIV)
+ odm_hw_ant_div(p_dm_odm);
+
+#if (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) || (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY))
+ else if (p_dm_odm->ant_div_type == CG_TRX_SMART_ANTDIV)
+ odm_fast_ant_training(p_dm_odm);
+#endif
+
+ }
+#endif
+
+#if (RTL8723B_SUPPORT == 1)
+ /* 2 [--8723B---] */
+ else if (p_dm_odm->support_ic_type == ODM_RTL8723B) {
+ if (phydm_is_bt_enable_8723b(p_dm_odm)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[BT is enable!!!]\n"));
+ if (p_dm_fat_table->is_become_linked == true) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Set REG 948[9:6]=0x0\n"));
+ if (p_dm_odm->support_ic_type == ODM_RTL8723B)
+ odm_set_bb_reg(p_dm_odm, 0x948, BIT(9) | BIT(8) | BIT(7) | BIT(6), 0x0);
+
+ p_dm_fat_table->is_become_linked = false;
+ }
+ } else {
+ if (p_dm_odm->ant_div_type == S0S1_SW_ANTDIV) {
+
+#ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY
+ odm_s0s1_sw_ant_div(p_dm_odm, SWAW_STEP_PEEK);
+#endif
+ } else if (p_dm_odm->ant_div_type == CG_TRX_HW_ANTDIV)
+ odm_hw_ant_div(p_dm_odm);
+ }
+ }
+#endif
+ /*8723D*/
+#if (RTL8723D_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8723D) {
+
+ odm_hw_ant_div(p_dm_odm);
+ /**/
+ }
+#endif
+
+ /* 2 [--8821A---] */
+#if (RTL8821A_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8821) {
+#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1
+ if (p_dm_odm->ant_div_type == HL_SW_SMART_ANT_TYPE1) {
+
+ if (pdm_sat_table->fix_beam_pattern_en != 0) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" [ SmartAnt ] Fix SmartAnt Pattern = 0x%x\n", pdm_sat_table->fix_beam_pattern_codeword));
+ /*return;*/
+ } else {
+ /*ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] ant_div_type = HL_SW_SMART_ANT_TYPE1\n"));*/
+ odm_fast_ant_training_hl_smart_antenna_type1(p_dm_odm);
+ }
+
+ } else
+#endif
+ {
+
+ if (!p_dm_odm->is_bt_enabled) { /*BT disabled*/
+ if (p_dm_odm->ant_div_type == S0S1_SW_ANTDIV) {
+ p_dm_odm->ant_div_type = CG_TRX_HW_ANTDIV;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" [S0S1_SW_ANTDIV] -> [CG_TRX_HW_ANTDIV]\n"));
+ /*odm_set_bb_reg(p_dm_odm, 0x8D4, BIT24, 1); */
+ if (p_dm_fat_table->is_become_linked == true)
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_ON);
+ }
+
+ } else { /*BT enabled*/
+
+ if (p_dm_odm->ant_div_type == CG_TRX_HW_ANTDIV) {
+ p_dm_odm->ant_div_type = S0S1_SW_ANTDIV;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" [CG_TRX_HW_ANTDIV] -> [S0S1_SW_ANTDIV]\n"));
+ /*odm_set_bb_reg(p_dm_odm, 0x8D4, BIT24, 0);*/
+ odm_ant_div_on_off(p_dm_odm, ANTDIV_OFF);
+ }
+ }
+
+ if (p_dm_odm->ant_div_type == S0S1_SW_ANTDIV) {
+
+#ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY
+ odm_s0s1_sw_ant_div(p_dm_odm, SWAW_STEP_PEEK);
+#endif
+ } else if (p_dm_odm->ant_div_type == CG_TRX_HW_ANTDIV)
+ odm_hw_ant_div(p_dm_odm);
+ }
+ }
+#endif
+
+ /* 2 [--8821C---] */
+#if (RTL8821C_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8821C)
+ odm_hw_ant_div(p_dm_odm);
+#endif
+
+ /* 2 [--8881A---] */
+#if (RTL8881A_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8881A)
+ odm_hw_ant_div(p_dm_odm);
+#endif
+
+ /* 2 [--8812A---] */
+#if (RTL8812A_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8812)
+ odm_hw_ant_div(p_dm_odm);
+#endif
+
+#if (RTL8188F_SUPPORT == 1)
+ /* [--8188F---]*/
+ else if (p_dm_odm->support_ic_type == ODM_RTL8188F) {
+
+#ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY
+ odm_s0s1_sw_ant_div(p_dm_odm, SWAW_STEP_PEEK);
+#endif
+ }
+#endif
+
+ /* [--8822B---]*/
+#if (RTL8821A_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type == ODM_RTL8822B) {
+#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1
+ if (p_dm_odm->ant_div_type == HL_SW_SMART_ANT_TYPE1) {
+
+ if (pdm_sat_table->fix_beam_pattern_en != 0)
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" [ SmartAnt ] Fix SmartAnt Pattern = 0x%x\n", pdm_sat_table->fix_beam_pattern_codeword));
+ else
+ odm_fast_ant_training_hl_smart_antenna_type1(p_dm_odm);
+ }
+#endif
+ }
+#endif
+
+
+}
+
+
+void
+odm_antsel_statistics(
+ void *p_dm_void,
+ u8 antsel_tr_mux,
+ u32 mac_id,
+ u32 utility,
+ u8 method,
+ u8 is_cck_rate
+
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+
+ if (method == RSSI_METHOD) {
+
+ if (is_cck_rate) {
+ if (antsel_tr_mux == ANT1_2G) {
+ if (p_dm_fat_table->main_ant_sum_cck[mac_id] > 65435) /*to prevent u16 overflow, max(RSSI)=100, 65435+100 = 65535 (u16)*/
+ return;
+
+ p_dm_fat_table->main_ant_sum_cck[mac_id] += (u16)utility;
+ p_dm_fat_table->main_ant_cnt_cck[mac_id]++;
+ } else {
+ if (p_dm_fat_table->aux_ant_sum_cck[mac_id] > 65435)
+ return;
+
+ p_dm_fat_table->aux_ant_sum_cck[mac_id] += (u16)utility;
+ p_dm_fat_table->aux_ant_cnt_cck[mac_id]++;
+ }
+
+ } else { /*ofdm rate*/
+
+ if (antsel_tr_mux == ANT1_2G) {
+ if (p_dm_fat_table->main_ant_sum[mac_id] > 65435)
+ return;
+
+ p_dm_fat_table->main_ant_sum[mac_id] += (u16)utility;
+ p_dm_fat_table->main_ant_cnt[mac_id]++;
+ } else {
+ if (p_dm_fat_table->aux_ant_sum[mac_id] > 65435)
+ return;
+
+ p_dm_fat_table->aux_ant_sum[mac_id] += (u16)utility;
+ p_dm_fat_table->aux_ant_cnt[mac_id]++;
+ }
+ }
+ }
+#ifdef ODM_EVM_ENHANCE_ANTDIV
+ else if (method == EVM_METHOD) {
+ if (antsel_tr_mux == ANT1_2G) {
+ p_dm_fat_table->main_ant_evm_sum[mac_id] += (utility << 5);
+ p_dm_fat_table->main_ant_evm_cnt[mac_id]++;
+ } else {
+ p_dm_fat_table->aux_ant_evm_sum[mac_id] += (utility << 5);
+ p_dm_fat_table->aux_ant_evm_cnt[mac_id]++;
+ }
+ } else if (method == CRC32_METHOD) {
+ if (utility == 0)
+ p_dm_fat_table->crc32_fail_cnt++;
+ else
+ p_dm_fat_table->crc32_ok_cnt += utility;
+ }
+#endif
+}
+
+
+void
+odm_process_rssi_for_ant_div(
+ void *p_dm_void,
+ void *p_phy_info_void,
+ void *p_pkt_info_void
+ /* struct _odm_phy_status_info_* p_phy_info, */
+ /* struct _odm_per_pkt_info_* p_pktinfo */
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _odm_phy_status_info_ *p_phy_info = (struct _odm_phy_status_info_ *)p_phy_info_void;
+ struct _odm_per_pkt_info_ *p_pktinfo = (struct _odm_per_pkt_info_ *)p_pkt_info_void;
+ u8 is_cck_rate = 0, cck_max_rate = ODM_RATE11M;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1
+ struct _SMART_ANTENNA_TRAINNING_ *pdm_sat_table = &(p_dm_odm->dm_sat_table);
+ u32 beam_tmp;
+ u8 next_ant;
+ u8 train_pkt_number;
+#endif
+
+ u8 rx_power_ant0, rx_power_ant1;
+ u8 rx_evm_ant0, rx_evm_ant1;
+
+ cck_max_rate = ODM_RATE11M;
+ is_cck_rate = (p_pktinfo->data_rate <= cck_max_rate) ? true : false;
+
+ if ((p_dm_odm->support_ic_type & ODM_IC_2SS) && (p_pktinfo->data_rate > cck_max_rate)) {
+ rx_power_ant0 = p_phy_info->rx_mimo_signal_strength[0];
+ rx_power_ant1 = p_phy_info->rx_mimo_signal_strength[1];
+
+ rx_evm_ant0 = p_phy_info->rx_mimo_signal_quality[0];
+ rx_evm_ant1 = p_phy_info->rx_mimo_signal_quality[1];
+ } else
+ rx_power_ant0 = p_phy_info->rx_pwdb_all;
+
+#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1
+#ifdef CONFIG_FAT_PATCH
+ if ((p_dm_odm->ant_div_type == HL_SW_SMART_ANT_TYPE1) && (p_dm_fat_table->fat_state == FAT_TRAINING_STATE)) {
+
+ /*[Beacon]*/
+ if (p_pktinfo->is_packet_beacon) {
+
+ pdm_sat_table->beacon_counter++;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("MatchBSSID_beacon_counter = ((%d))\n", pdm_sat_table->beacon_counter));
+
+ if (pdm_sat_table->beacon_counter >= pdm_sat_table->pre_beacon_counter + 2) {
+
+ if (pdm_sat_table->ant_num > 1) {
+ next_ant = (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
+ odm_update_rx_idle_ant(p_dm_odm, next_ant);
+ }
+
+ pdm_sat_table->update_beam_idx++;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("pre_beacon_counter = ((%d)), pkt_counter = ((%d)), update_beam_idx = ((%d))\n",
+ pdm_sat_table->pre_beacon_counter, pdm_sat_table->pkt_counter, pdm_sat_table->update_beam_idx));
+
+ pdm_sat_table->pre_beacon_counter = pdm_sat_table->beacon_counter;
+ pdm_sat_table->pkt_counter = 0;
+ }
+ }
+ /*[data]*/
+ else if (p_pktinfo->is_packet_to_self) {
+
+ if (pdm_sat_table->pkt_skip_statistic_en == 0) {
+ /*
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("StaID[%d]: antsel_pathA = ((%d)), hw_antsw_occur = ((%d)), Beam_num = ((%d)), RSSI = ((%d))\n",
+ p_pktinfo->station_id, p_dm_fat_table->antsel_rx_keep_0, p_dm_fat_table->hw_antsw_occur, pdm_sat_table->fast_training_beam_num, rx_power_ant0));
+ */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ID[%d][pkt_cnt = %d]: {ANT, Beam} = {%d, %d}, RSSI = ((%d))\n",
+ p_pktinfo->station_id, pdm_sat_table->pkt_counter, p_dm_fat_table->antsel_rx_keep_0, pdm_sat_table->fast_training_beam_num, rx_power_ant0));
+
+ pdm_sat_table->pkt_rssi_sum[p_dm_fat_table->antsel_rx_keep_0][pdm_sat_table->fast_training_beam_num] += rx_power_ant0;
+ pdm_sat_table->pkt_rssi_cnt[p_dm_fat_table->antsel_rx_keep_0][pdm_sat_table->fast_training_beam_num]++;
+ pdm_sat_table->pkt_counter++;
+
+ train_pkt_number = pdm_sat_table->beam_train_cnt[p_dm_fat_table->rx_idle_ant - 1][pdm_sat_table->fast_training_beam_num];
+
+ /*Swich Antenna erery N pkts*/
+ if (pdm_sat_table->pkt_counter == train_pkt_number) {
+
+ if (pdm_sat_table->ant_num > 1) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("packet enugh ((%d ))pkts ---> Switch antenna\n", train_pkt_number));
+ next_ant = (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
+ odm_update_rx_idle_ant(p_dm_odm, next_ant);
+ }
+
+ pdm_sat_table->update_beam_idx++;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("pre_beacon_counter = ((%d)), update_beam_idx_counter = ((%d))\n",
+ pdm_sat_table->pre_beacon_counter, pdm_sat_table->update_beam_idx));
+
+ pdm_sat_table->pre_beacon_counter = pdm_sat_table->beacon_counter;
+ pdm_sat_table->pkt_counter = 0;
+ }
+ }
+ }
+
+ /*Swich Beam after switch "pdm_sat_table->ant_num" antennas*/
+ if (pdm_sat_table->update_beam_idx == pdm_sat_table->ant_num) {
+
+ pdm_sat_table->update_beam_idx = 0;
+ pdm_sat_table->pkt_counter = 0;
+ beam_tmp = pdm_sat_table->fast_training_beam_num;
+
+ if (pdm_sat_table->fast_training_beam_num >= (pdm_sat_table->beam_patten_num_each_ant - 1)) {
+
+ p_dm_fat_table->fat_state = FAT_DECISION_STATE;
+
+#if DEV_BUS_TYPE == RT_PCI_INTERFACE
+ odm_fast_ant_training_hl_smart_antenna_type1(p_dm_odm);
+#else
+ odm_schedule_work_item(&pdm_sat_table->hl_smart_antenna_decision_workitem);
+#endif
+
+
+ } else {
+ pdm_sat_table->fast_training_beam_num++;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Update Beam_num (( %d )) -> (( %d ))\n", beam_tmp, pdm_sat_table->fast_training_beam_num));
+ phydm_set_all_ant_same_beam_num(p_dm_odm);
+
+ p_dm_fat_table->fat_state = FAT_TRAINING_STATE;
+ }
+ }
+
+ }
+#else
+
+ if (p_dm_odm->ant_div_type == HL_SW_SMART_ANT_TYPE1) {
+ if ((p_dm_odm->support_ic_type & ODM_HL_SMART_ANT_TYPE1_SUPPORT) &&
+ (p_pktinfo->is_packet_to_self) &&
+ (p_dm_fat_table->fat_state == FAT_TRAINING_STATE)
+ ) {
+
+ if (pdm_sat_table->pkt_skip_statistic_en == 0) {
+ /*
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("StaID[%d]: antsel_pathA = ((%d)), hw_antsw_occur = ((%d)), Beam_num = ((%d)), RSSI = ((%d))\n",
+ p_pktinfo->station_id, p_dm_fat_table->antsel_rx_keep_0, p_dm_fat_table->hw_antsw_occur, pdm_sat_table->fast_training_beam_num, rx_power_ant0));
+ */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("StaID[%d]: antsel_pathA = ((%d)), is_packet_to_self = ((%d)), Beam_num = ((%d)), RSSI = ((%d))\n",
+ p_pktinfo->station_id, p_dm_fat_table->antsel_rx_keep_0, p_pktinfo->is_packet_to_self, pdm_sat_table->fast_training_beam_num, rx_power_ant0));
+
+
+ pdm_sat_table->pkt_rssi_sum[p_dm_fat_table->antsel_rx_keep_0][pdm_sat_table->fast_training_beam_num] += rx_power_ant0;
+ pdm_sat_table->pkt_rssi_cnt[p_dm_fat_table->antsel_rx_keep_0][pdm_sat_table->fast_training_beam_num]++;
+ pdm_sat_table->pkt_counter++;
+
+ /*swich beam every N pkt*/
+ if ((pdm_sat_table->pkt_counter) >= (pdm_sat_table->per_beam_training_pkt_num)) {
+
+ pdm_sat_table->pkt_counter = 0;
+ beam_tmp = pdm_sat_table->fast_training_beam_num;
+
+ if (pdm_sat_table->fast_training_beam_num >= (pdm_sat_table->beam_patten_num_each_ant - 1)) {
+
+ p_dm_fat_table->fat_state = FAT_DECISION_STATE;
+
+#if DEV_BUS_TYPE == RT_PCI_INTERFACE
+ odm_fast_ant_training_hl_smart_antenna_type1(p_dm_odm);
+#else
+ odm_schedule_work_item(&pdm_sat_table->hl_smart_antenna_decision_workitem);
+#endif
+
+
+ } else {
+ pdm_sat_table->fast_training_beam_num++;
+ phydm_set_all_ant_same_beam_num(p_dm_odm);
+
+ p_dm_fat_table->fat_state = FAT_TRAINING_STATE;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Update Beam_num (( %d )) -> (( %d ))\n", beam_tmp, pdm_sat_table->fast_training_beam_num));
+ }
+ }
+ }
+ }
+ }
+#endif
+ else
+#endif
+ if (p_dm_odm->ant_div_type == CG_TRX_SMART_ANTDIV) {
+ if ((p_dm_odm->support_ic_type & ODM_SMART_ANT_SUPPORT) && (p_pktinfo->is_packet_to_self) && (p_dm_fat_table->fat_state == FAT_TRAINING_STATE)) { /* (p_pktinfo->is_packet_match_bssid && (!p_pktinfo->is_packet_beacon)) */
+ u8 antsel_tr_mux;
+ antsel_tr_mux = (p_dm_fat_table->antsel_rx_keep_2 << 2) | (p_dm_fat_table->antsel_rx_keep_1 << 1) | p_dm_fat_table->antsel_rx_keep_0;
+ p_dm_fat_table->ant_sum_rssi[antsel_tr_mux] += rx_power_ant0;
+ p_dm_fat_table->ant_rssi_cnt[antsel_tr_mux]++;
+ }
+ } else { /* ant_div_type != CG_TRX_SMART_ANTDIV */
+ if ((p_dm_odm->support_ic_type & ODM_ANTDIV_SUPPORT) && (p_pktinfo->is_packet_to_self || p_dm_fat_table->use_ctrl_frame_antdiv)) {
+
+ if (p_dm_odm->ant_div_type == S0S1_SW_ANTDIV) {
+
+ if (is_cck_rate)
+ p_dm_fat_table->antsel_rx_keep_0 = (p_dm_fat_table->rx_idle_ant == MAIN_ANT) ? ANT1_2G : ANT2_2G;
+
+ odm_antsel_statistics(p_dm_odm, p_dm_fat_table->antsel_rx_keep_0, p_pktinfo->station_id, rx_power_ant0, RSSI_METHOD, is_cck_rate);
+
+ } else {
+
+ odm_antsel_statistics(p_dm_odm, p_dm_fat_table->antsel_rx_keep_0, p_pktinfo->station_id, rx_power_ant0, RSSI_METHOD, is_cck_rate);
+
+#ifdef ODM_EVM_ENHANCE_ANTDIV
+ if (p_dm_odm->support_ic_type == ODM_RTL8192E) {
+ if (!is_cck_rate)
+ odm_antsel_statistics(p_dm_odm, p_dm_fat_table->antsel_rx_keep_0, p_pktinfo->station_id, rx_evm_ant0, EVM_METHOD, is_cck_rate);
+
+ }
+#endif
+ }
+ }
+ }
+ /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("is_cck_rate=%d, PWDB_ALL=%d\n",is_cck_rate, p_phy_info->rx_pwdb_all)); */
+ /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("antsel_tr_mux=3'b%d%d%d\n",p_dm_fat_table->antsel_rx_keep_2, p_dm_fat_table->antsel_rx_keep_1, p_dm_fat_table->antsel_rx_keep_0)); */
+}
+
+void
+odm_set_tx_ant_by_tx_info(
+ void *p_dm_void,
+ u8 *p_desc,
+ u8 mac_id
+
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_ANT_DIV))
+ return;
+
+ if (p_dm_odm->ant_div_type == CGCS_RX_HW_ANTDIV)
+ return;
+
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8723B) {
+#if (RTL8723B_SUPPORT == 1)
+ SET_TX_DESC_ANTSEL_A_8723B(p_desc, p_dm_fat_table->antsel_a[mac_id]);
+ /*ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[8723B] SetTxAntByTxInfo_WIN: mac_id=%d, antsel_tr_mux=3'b%d%d%d\n",
+ mac_id, p_dm_fat_table->antsel_c[mac_id], p_dm_fat_table->antsel_b[mac_id], p_dm_fat_table->antsel_a[mac_id]));*/
+#endif
+ } else if (p_dm_odm->support_ic_type == ODM_RTL8821) {
+#if (RTL8821A_SUPPORT == 1)
+ SET_TX_DESC_ANTSEL_A_8812(p_desc, p_dm_fat_table->antsel_a[mac_id]);
+ /*ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[8821A] SetTxAntByTxInfo_WIN: mac_id=%d, antsel_tr_mux=3'b%d%d%d\n",
+ mac_id, p_dm_fat_table->antsel_c[mac_id], p_dm_fat_table->antsel_b[mac_id], p_dm_fat_table->antsel_a[mac_id]));*/
+#endif
+ } else if (p_dm_odm->support_ic_type == ODM_RTL8188E) {
+#if (RTL8188E_SUPPORT == 1)
+ SET_TX_DESC_ANTSEL_A_88E(p_desc, p_dm_fat_table->antsel_a[mac_id]);
+ SET_TX_DESC_ANTSEL_B_88E(p_desc, p_dm_fat_table->antsel_b[mac_id]);
+ SET_TX_DESC_ANTSEL_C_88E(p_desc, p_dm_fat_table->antsel_c[mac_id]);
+ /*ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[8188E] SetTxAntByTxInfo_WIN: mac_id=%d, antsel_tr_mux=3'b%d%d%d\n",
+ mac_id, p_dm_fat_table->antsel_c[mac_id], p_dm_fat_table->antsel_b[mac_id], p_dm_fat_table->antsel_a[mac_id]));*/
+#endif
+ } else if (p_dm_odm->support_ic_type == ODM_RTL8821C) {
+#if (RTL8821C_SUPPORT == 1)
+ SET_TX_DESC_ANTSEL_A_8821C(p_desc, p_dm_fat_table->antsel_a[mac_id]);
+ /*ODM_RT_TRACE(p_dm_odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[8821C] SetTxAntByTxInfo_WIN: mac_id=%d, antsel_tr_mux=3'b%d%d%d\n",
+ mac_id, p_dm_fat_table->antsel_c[mac_id], p_dm_fat_table->antsel_b[mac_id], p_dm_fat_table->antsel_a[mac_id]));*/
+#endif
+ }
+}
+
+void
+odm_ant_div_config(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("CE Config Antenna Diversity\n"));
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8723B)
+ p_dm_odm->ant_div_type = S0S1_SW_ANTDIV;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[AntDiv Config Info] AntDiv_SupportAbility = (( %x ))\n", ((p_dm_odm->support_ability & ODM_BB_ANT_DIV) ? 1 : 0)));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[AntDiv Config Info] be_fix_tx_ant = ((%d))\n", p_dm_odm->dm_fat_table.b_fix_tx_ant));
+
+}
+
+
+void
+odm_ant_div_timers(
+ void *p_dm_void,
+ u8 state
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ if (state == INIT_ANTDIV_TIMMER) {
+#ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
+ odm_initialize_timer(p_dm_odm, &(p_dm_odm->dm_swat_table.phydm_sw_antenna_switch_timer),
+ (void *)odm_sw_antdiv_callback, NULL, "phydm_sw_antenna_switch_timer");
+#else
+ timer_setup(&p_dm_odm->dm_swat_table.phydm_sw_antenna_switch_timer, odm_sw_antdiv_callback, 0);
+#endif
+#elif (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) || (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY))
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
+ odm_initialize_timer(p_dm_odm, &p_dm_odm->fast_ant_training_timer,
+ (void *)odm_fast_ant_training_callback, NULL, "fast_ant_training_timer");
+#else
+ timer_setup(&p_dm_odm->fast_ant_training_timer, odm_fast_ant_training_callback, 0);
+#endif
+#endif
+
+#ifdef ODM_EVM_ENHANCE_ANTDIV
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
+ odm_initialize_timer(p_dm_odm, &p_dm_odm->evm_fast_ant_training_timer,
+ (void *)odm_evm_fast_ant_training_callback, NULL, "evm_fast_ant_training_timer");
+#else
+ timer_setup(&p_dm_odm->evm_fast_ant_training_timer, odm_evm_fast_ant_training_callback, 0);
+#endif
+#endif
+ } else if (state == CANCEL_ANTDIV_TIMMER) {
+#ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY
+ odm_cancel_timer(p_dm_odm, &(p_dm_odm->dm_swat_table.phydm_sw_antenna_switch_timer));
+#elif (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) || (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY))
+ odm_cancel_timer(p_dm_odm, &p_dm_odm->fast_ant_training_timer);
+#endif
+
+#ifdef ODM_EVM_ENHANCE_ANTDIV
+ odm_cancel_timer(p_dm_odm, &p_dm_odm->evm_fast_ant_training_timer);
+#endif
+ } else if (state == RELEASE_ANTDIV_TIMMER) {
+#ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY
+ odm_release_timer(p_dm_odm, &(p_dm_odm->dm_swat_table.phydm_sw_antenna_switch_timer));
+#elif (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) || (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY))
+ odm_release_timer(p_dm_odm, &p_dm_odm->fast_ant_training_timer);
+#endif
+
+#ifdef ODM_EVM_ENHANCE_ANTDIV
+ odm_release_timer(p_dm_odm, &p_dm_odm->evm_fast_ant_training_timer);
+#endif
+ }
+
+}
+
+void
+phydm_antdiv_debug(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ /*struct _FAST_ANTENNA_TRAINNING_* p_dm_fat_table = &p_dm_odm->dm_fat_table;*/
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ if (dm_value[0] == 1) { /*fixed or auto antenna*/
+
+ if (dm_value[1] == 0) {
+ p_dm_odm->antdiv_select = 0;
+ PHYDM_SNPRINTF((output + used, out_len - used, "AntDiv: Auto\n"));
+ } else if (dm_value[1] == 1) {
+ p_dm_odm->antdiv_select = 1;
+ PHYDM_SNPRINTF((output + used, out_len - used, "AntDiv: Fix MAin\n"));
+ } else if (dm_value[1] == 2) {
+ p_dm_odm->antdiv_select = 2;
+ PHYDM_SNPRINTF((output + used, out_len - used, "AntDiv: Fix Aux\n"));
+ }
+ } else if (dm_value[0] == 2) { /*dynamic period for AntDiv*/
+
+ p_dm_odm->antdiv_period = (u8)dm_value[1];
+ PHYDM_SNPRINTF((output + used, out_len - used, "AntDiv_period = ((%d))\n", p_dm_odm->antdiv_period));
+ }
+}
+
+#endif /*#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))*/
+
+void
+odm_ant_div_reset(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (p_dm_odm->ant_div_type == S0S1_SW_ANTDIV) {
+#ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY
+ odm_s0s1_sw_ant_div_reset(p_dm_odm);
+#endif
+ }
+
+}
+
+void
+odm_antenna_diversity_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))
+ odm_ant_div_config(p_dm_odm);
+ odm_ant_div_init(p_dm_odm);
+#endif
+}
+
+void
+odm_antenna_diversity(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ if (p_dm_odm->mp_mode == true)
+ return;
+
+#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))
+ odm_ant_div(p_dm_odm);
+#endif
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_antdiv.h b/drivers/staging/rtl8188eu/hal/phydm_antdiv.h
new file mode 100644
index 000000000000..14fc9c1df824
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_antdiv.h
@@ -0,0 +1,516 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMANTDIV_H__
+#define __PHYDMANTDIV_H__
+
+/*#define ANTDIV_VERSION "2.0" //2014.11.04*/
+/*#define ANTDIV_VERSION "2.1" //2015.01.13 Dino*/
+/*#define ANTDIV_VERSION "2.2" 2015.01.16 Dino*/
+/*#define ANTDIV_VERSION "3.1" 2015.07.29 YuChen, remove 92c 92d 8723a*/
+/*#define ANTDIV_VERSION "3.2" 2015.08.11 Stanley, disable antenna diversity when BT is enable for 8723B*/
+/*#define ANTDIV_VERSION "3.3" 2015.08.12 Stanley. 8723B does not need to check the antenna is control by BT,
+ because antenna diversity only works when BT is disable or radio off*/
+/*#define ANTDIV_VERSION "3.4" 2015.08.28 Dino 1.Add 8821A Smart Antenna 2. Add 8188F SW S0S1 Antenna Diversity*/
+/*#define ANTDIV_VERSION "3.5" 2015.10.07 Stanley Always check antenna detection result from BT-coex. for 8723B, not from PHYDM*/
+/*#define ANTDIV_VERSION "3.6"*/ /*2015.11.16 Stanley */
+/*#define ANTDIV_VERSION "3.7"*/ /*2015.11.20 Dino Add SmartAnt FAT Patch */
+/*#define ANTDIV_VERSION "3.8" 2015.12.21 Dino, Add SmartAnt dynamic training packet num */
+#define ANTDIV_VERSION "3.9" /*2016.01.05 Dino, Add SmartAnt cmd for converting single & two smtant, and add cmd for adjust truth table */
+
+/* 1 ============================================================
+ * 1 Definition
+ * 1 ============================================================ */
+
+#define ANTDIV_INIT 0xff
+#define MAIN_ANT 1 /*ant A or ant Main or S1*/
+#define AUX_ANT 2 /*AntB or ant Aux or S0*/
+#define MAX_ANT 3 /* 3 for AP using*/
+
+#define ANT1_2G 0 /* = ANT2_5G for 8723D BTG S1 RX S0S1 diversity for 8723D, TX fixed at S1 */
+#define ANT2_2G 1 /* = ANT1_5G for 8723D BTG S0 RX S0S1 diversity for 8723D, TX fixed at S1 */
+/*smart antenna*/
+#define SUPPORT_RF_PATH_NUM 4
+#define SUPPORT_BEAM_PATTERN_NUM 4
+#define NUM_ANTENNA_8821A 2
+
+#define NO_FIX_TX_ANT 0
+#define FIX_TX_AT_MAIN 1
+#define FIX_AUX_AT_MAIN 2
+
+/* Antenna Diversty Control type */
+#define ODM_AUTO_ANT 0
+#define ODM_FIX_MAIN_ANT 1
+#define ODM_FIX_AUX_ANT 2
+
+#define ODM_N_ANTDIV_SUPPORT (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8188F | ODM_RTL8723D | ODM_RTL8195A)
+#define ODM_AC_ANTDIV_SUPPORT (ODM_RTL8821 | ODM_RTL8881A | ODM_RTL8812 | ODM_RTL8821C | ODM_RTL8822B | ODM_RTL8814B)
+#define ODM_ANTDIV_SUPPORT (ODM_N_ANTDIV_SUPPORT | ODM_AC_ANTDIV_SUPPORT)
+#define ODM_SMART_ANT_SUPPORT (ODM_RTL8188E | ODM_RTL8192E)
+#define ODM_HL_SMART_ANT_TYPE1_SUPPORT (ODM_RTL8821 | ODM_RTL8822B)
+
+#define ODM_ANTDIV_2G_SUPPORT_IC (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8881A | ODM_RTL8188F | ODM_RTL8723D)
+#define ODM_ANTDIV_5G_SUPPORT_IC (ODM_RTL8821 | ODM_RTL8881A | ODM_RTL8812 | ODM_RTL8821C)
+
+#define ODM_EVM_ENHANCE_ANTDIV_SUPPORT_IC (ODM_RTL8192E)
+
+#define ODM_ANTDIV_2G BIT(0)
+#define ODM_ANTDIV_5G BIT(1)
+
+#define ANTDIV_ON 1
+#define ANTDIV_OFF 0
+
+#define FAT_ON 1
+#define FAT_OFF 0
+
+#define TX_BY_DESC 1
+#define TX_BY_REG 0
+
+#define RSSI_METHOD 0
+#define EVM_METHOD 1
+#define CRC32_METHOD 2
+
+#define INIT_ANTDIV_TIMMER 0
+#define CANCEL_ANTDIV_TIMMER 1
+#define RELEASE_ANTDIV_TIMMER 2
+
+#define CRC32_FAIL 1
+#define CRC32_OK 0
+
+#define evm_rssi_th_high 25
+#define evm_rssi_th_low 20
+
+#define NORMAL_STATE_MIAN 1
+#define NORMAL_STATE_AUX 2
+#define TRAINING_STATE 3
+
+#define FORCE_RSSI_DIFF 10
+
+#define CSI_ON 1
+#define CSI_OFF 0
+
+#define DIVON_CSIOFF 1
+#define DIVOFF_CSION 2
+
+#define BDC_DIV_TRAIN_STATE 0
+#define bdc_bfer_train_state 1
+#define BDC_DECISION_STATE 2
+#define BDC_BF_HOLD_STATE 3
+#define BDC_DIV_HOLD_STATE 4
+
+#define BDC_MODE_1 1
+#define BDC_MODE_2 2
+#define BDC_MODE_3 3
+#define BDC_MODE_4 4
+#define BDC_MODE_NULL 0xff
+
+/*SW S0S1 antenna diversity*/
+#define SWAW_STEP_INIT 0xff
+#define SWAW_STEP_PEEK 0
+#define SWAW_STEP_DETERMINE 1
+
+#define RSSI_CHECK_RESET_PERIOD 10
+#define RSSI_CHECK_THRESHOLD 50
+
+/*Hong Lin Smart antenna*/
+#define HL_SMTANT_2WIRE_DATA_LEN 24
+
+/* 1 ============================================================
+ * 1 structure
+ * 1 ============================================================ */
+
+
+struct _sw_antenna_switch_ {
+ u8 double_chk_flag; /*If current antenna RSSI > "RSSI_CHECK_THRESHOLD", than check this antenna again*/
+ u8 try_flag;
+ s32 pre_rssi;
+ u8 cur_antenna;
+ u8 pre_antenna;
+ u8 rssi_trying;
+ u8 reset_idx;
+ u8 train_time;
+ u8 train_time_flag; /*base on RSSI difference between two antennas*/
+ struct timer_list phydm_sw_antenna_switch_timer;
+ u32 pkt_cnt_sw_ant_div_by_ctrl_frame;
+ bool is_sw_ant_div_by_ctrl_frame;
+
+ /* AntDect (Before link Antenna Switch check) need to be moved*/
+ u16 single_ant_counter;
+ u16 dual_ant_counter;
+ u16 aux_fail_detec_counter;
+ u16 retry_counter;
+ u8 swas_no_link_state;
+ u32 swas_no_link_bk_reg948;
+ bool ANTA_ON; /*To indicate ant A is or not*/
+ bool ANTB_ON; /*To indicate ant B is on or not*/
+ bool pre_aux_fail_detec;
+ bool rssi_ant_dect_result;
+ u8 ant_5g;
+ u8 ant_2g;
+};
+
+#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1
+struct _SMART_ANTENNA_TRAINNING_ {
+ u32 latch_time;
+ bool pkt_skip_statistic_en;
+ u32 fix_beam_pattern_en;
+ u32 fix_training_num_en;
+ u32 fix_beam_pattern_codeword;
+ u32 update_beam_codeword;
+ u32 ant_num; /*number of used smart beam antenna*/
+ u32 ant_num_total;/*number of total smart beam antenna*/
+ u32 first_train_ant; /*decide witch antenna to train first*/
+ u32 rfu_codeword_table[4]; /*2G beam truth table*/
+ u32 rfu_codeword_table_5g[4]; /*5G beam truth table*/
+ u32 beam_patten_num_each_ant;/*number of beam can be switched in each antenna*/
+ u32 data_codeword_bit_num;
+ u8 per_beam_training_pkt_num;
+ u8 decision_holding_period;
+ u8 pkt_counter;
+ u32 fast_training_beam_num;
+ u32 pre_fast_training_beam_num;
+ u32 pkt_rssi_pre[SUPPORT_RF_PATH_NUM][SUPPORT_BEAM_PATTERN_NUM];
+ u8 beam_train_cnt[SUPPORT_RF_PATH_NUM][SUPPORT_BEAM_PATTERN_NUM];
+ u8 beam_train_rssi_diff[SUPPORT_RF_PATH_NUM][SUPPORT_BEAM_PATTERN_NUM];
+ u32 pkt_rssi_sum[8][SUPPORT_BEAM_PATTERN_NUM];
+ u32 pkt_rssi_cnt[8][SUPPORT_BEAM_PATTERN_NUM];
+ u32 rx_idle_beam[SUPPORT_RF_PATH_NUM];
+ u32 pre_codeword;
+ bool force_update_beam_en;
+ u32 beacon_counter;
+ u32 pre_beacon_counter;
+ u8 update_beam_idx;
+};
+#endif
+
+struct _FAST_ANTENNA_TRAINNING_ {
+ u8 bssid[6];
+ u8 antsel_rx_keep_0;
+ u8 antsel_rx_keep_1;
+ u8 antsel_rx_keep_2;
+ u8 antsel_rx_keep_3;
+ u32 ant_sum_rssi[7];
+ u32 ant_rssi_cnt[7];
+ u32 ant_ave_rssi[7];
+ u8 fat_state;
+ u32 train_idx;
+ u8 antsel_a[ODM_ASSOCIATE_ENTRY_NUM];
+ u8 antsel_b[ODM_ASSOCIATE_ENTRY_NUM];
+ u8 antsel_c[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 main_ant_sum[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 aux_ant_sum[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 main_ant_cnt[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 aux_ant_cnt[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 main_ant_sum_cck[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 aux_ant_sum_cck[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 main_ant_cnt_cck[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 aux_ant_cnt_cck[ODM_ASSOCIATE_ENTRY_NUM];
+ u8 rx_idle_ant;
+ u8 ant_div_on_off;
+ bool is_become_linked;
+ u32 min_max_rssi;
+ u8 idx_ant_div_counter_2g;
+ u8 idx_ant_div_counter_5g;
+ u8 ant_div_2g_5g;
+
+#ifdef ODM_EVM_ENHANCE_ANTDIV
+ u32 main_ant_evm_sum[ODM_ASSOCIATE_ENTRY_NUM];
+ u32 aux_ant_evm_sum[ODM_ASSOCIATE_ENTRY_NUM];
+ u32 main_ant_evm_cnt[ODM_ASSOCIATE_ENTRY_NUM];
+ u32 aux_ant_evm_cnt[ODM_ASSOCIATE_ENTRY_NUM];
+ bool EVM_method_enable;
+ u8 target_ant_evm;
+ u8 target_ant_crc32;
+ u8 target_ant_enhance;
+ u8 pre_target_ant_enhance;
+ u16 main_mpdu_ok_cnt;
+ u16 aux_mpdu_ok_cnt;
+
+ u32 crc32_ok_cnt;
+ u32 crc32_fail_cnt;
+ u32 main_crc32_ok_cnt;
+ u32 aux_crc32_ok_cnt;
+ u32 main_crc32_fail_cnt;
+ u32 aux_crc32_fail_cnt;
+#endif
+ u32 cck_ctrl_frame_cnt_main;
+ u32 cck_ctrl_frame_cnt_aux;
+ u32 ofdm_ctrl_frame_cnt_main;
+ u32 ofdm_ctrl_frame_cnt_aux;
+ u32 main_ant_ctrl_frame_sum;
+ u32 aux_ant_ctrl_frame_sum;
+ u32 main_ant_ctrl_frame_cnt;
+ u32 aux_ant_ctrl_frame_cnt;
+ u8 b_fix_tx_ant;
+ bool fix_ant_bfee;
+ bool enable_ctrl_frame_antdiv;
+ bool use_ctrl_frame_antdiv;
+ u8 hw_antsw_occur;
+ u8 *p_force_tx_ant_by_desc;
+ u8 force_tx_ant_by_desc; /*A temp value, will hook to driver team's outer parameter later*/
+ u8 *p_default_s0_s1;
+ u8 default_s0_s1;
+};
+
+
+/* 1 ============================================================
+ * 1 enumeration
+ * 1 ============================================================ */
+
+
+
+enum fat_state_e /*Fast antenna training*/
+{
+ FAT_BEFORE_LINK_STATE = 0,
+ FAT_PREPARE_STATE = 1,
+ FAT_TRAINING_STATE = 2,
+ FAT_DECISION_STATE = 3
+};
+
+enum ant_div_type_e {
+ NO_ANTDIV = 0xFF,
+ CG_TRX_HW_ANTDIV = 0x01,
+ CGCS_RX_HW_ANTDIV = 0x02,
+ FIXED_HW_ANTDIV = 0x03,
+ CG_TRX_SMART_ANTDIV = 0x04,
+ CGCS_RX_SW_ANTDIV = 0x05,
+ S0S1_SW_ANTDIV = 0x06, /*8723B intrnal switch S0 S1*/
+ S0S1_TRX_HW_ANTDIV = 0x07, /*TRX S0S1 diversity for 8723D*/
+ HL_SW_SMART_ANT_TYPE1 = 0x10 /*Hong-Lin Smart antenna use for 8821AE which is a 2 ant. entitys, and each ant. is equipped with 4 antenna patterns*/
+};
+
+
+/* 1 ============================================================
+ * 1 function prototype
+ * 1 ============================================================ */
+
+
+void
+odm_stop_antenna_switch_dm(
+ void *p_dm_void
+);
+
+void
+phydm_enable_antenna_diversity(
+ void *p_dm_void
+);
+
+void
+odm_set_ant_config(
+ void *p_dm_void,
+ u8 ant_setting /* 0=A, 1=B, 2=C, .... */
+);
+
+
+#define sw_ant_div_rest_after_link odm_sw_ant_div_rest_after_link
+
+void odm_sw_ant_div_rest_after_link(
+ void *p_dm_void
+);
+
+#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))
+
+void
+phydm_antdiv_reset_statistic(
+ void *p_dm_void,
+ u32 macid
+);
+
+void
+odm_update_rx_idle_ant(
+ void *p_dm_void,
+ u8 ant
+);
+
+#if (RTL8723B_SUPPORT == 1)
+void
+odm_update_rx_idle_ant_8723b(
+ void *p_dm_void,
+ u8 ant,
+ u32 default_ant,
+ u32 optional_ant
+);
+#endif
+
+#if (RTL8188F_SUPPORT == 1)
+void
+phydm_update_rx_idle_antenna_8188F(
+ void *p_dm_void,
+ u32 default_ant
+);
+#endif
+
+#if (RTL8723D_SUPPORT == 1)
+
+void
+phydm_set_tx_ant_pwr_8723d(
+ void *p_dm_void,
+ u8 ant
+);
+
+#endif
+
+#ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY
+
+void
+odm_sw_antdiv_workitem_callback(
+ void *p_context
+);
+
+void
+odm_sw_antdiv_callback(
+ void *function_context
+);
+
+void
+odm_s0s1_sw_ant_div_by_ctrl_frame(
+ void *p_dm_void,
+ u8 step
+);
+
+void
+odm_antsel_statistics_of_ctrl_frame(
+ void *p_dm_void,
+ u8 antsel_tr_mux,
+ u32 rx_pwdb_all
+);
+
+void
+odm_s0s1_sw_ant_div_by_ctrl_frame_process_rssi(
+ void *p_dm_void,
+ void *p_phy_info_void,
+ void *p_pkt_info_void
+);
+
+#endif
+
+#ifdef ODM_EVM_ENHANCE_ANTDIV
+void
+odm_evm_fast_ant_training_callback(
+ void *p_dm_void
+);
+#endif
+
+void
+odm_hw_ant_div(
+ void *p_dm_void
+);
+
+#if (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) || (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY))
+void
+odm_fast_ant_training(
+ void *p_dm_void
+);
+
+void
+odm_fast_ant_training_callback(
+ void *p_dm_void
+);
+
+void
+odm_fast_ant_training_work_item_callback(
+ void *p_dm_void
+);
+#endif
+
+
+#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1
+
+void
+phydm_update_beam_pattern(
+ void *p_dm_void,
+ u32 codeword,
+ u32 codeword_length
+);
+
+void
+phydm_set_all_ant_same_beam_num(
+ void *p_dm_void
+);
+
+void
+phydm_hl_smart_ant_debug(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+);
+
+#endif/*#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1*/
+
+void
+odm_ant_div_init(
+ void *p_dm_void
+);
+
+void
+odm_ant_div(
+ void *p_dm_void
+);
+
+void
+odm_antsel_statistics(
+ void *p_dm_void,
+ u8 antsel_tr_mux,
+ u32 mac_id,
+ u32 utility,
+ u8 method,
+ u8 is_cck_rate
+);
+
+void
+odm_process_rssi_for_ant_div(
+ void *p_dm_void,
+ void *p_phy_info_void,
+ void *p_pkt_info_void
+);
+
+
+
+void
+odm_set_tx_ant_by_tx_info(
+ void *p_dm_void,
+ u8 *p_desc,
+ u8 mac_id
+);
+
+void
+odm_ant_div_config(
+ void *p_dm_void
+);
+
+void
+odm_ant_div_timers(
+ void *p_dm_void,
+ u8 state
+);
+
+void
+phydm_antdiv_debug(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+);
+
+#endif /*#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))*/
+
+void
+odm_ant_div_reset(
+ void *p_dm_void
+);
+
+void
+odm_antenna_diversity_init(
+ void *p_dm_void
+);
+
+void
+odm_antenna_diversity(
+ void *p_dm_void
+);
+
+#endif /*#ifndef __ODMANTDIV_H__*/
diff --git a/drivers/staging/rtl8188eu/hal/phydm_beamforming.h b/drivers/staging/rtl8188eu/hal/phydm_beamforming.h
new file mode 100644
index 000000000000..e3413f682948
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_beamforming.h
@@ -0,0 +1,27 @@
+#ifndef __INC_PHYDM_BEAMFORMING_H
+#define __INC_PHYDM_BEAMFORMING_H
+
+#ifndef BEAMFORMING_SUPPORT
+ #define BEAMFORMING_SUPPORT 0
+#endif
+
+/*Beamforming Related*/
+#include "halcomtxbf.h"
+#include "haltxbfjaguar.h"
+#include "haltxbfinterface.h"
+
+#define beamforming_gid_paid(adapter, p_tcb)
+#define phydm_acting_determine(p_dm_odm, type) false
+#define beamforming_enter(p_dm_odm, sta_idx)
+#define beamforming_leave(p_dm_odm, RA)
+#define beamforming_end_fw(p_dm_odm)
+#define beamforming_control_v1(p_dm_odm, RA, AID, mode, BW, rate) true
+#define beamforming_control_v2(p_dm_odm, idx, mode, BW, period) true
+#define phydm_beamforming_end_sw(p_dm_odm, _status)
+#define beamforming_timer_callback(p_dm_odm)
+#define phydm_beamforming_init(p_dm_odm)
+#define phydm_beamforming_control_v2(p_dm_odm, _idx, _mode, _BW, _period) false
+#define beamforming_watchdog(p_dm_odm)
+#define phydm_beamforming_watchdog(p_dm_odm)
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_ccx.c b/drivers/staging/rtl8188eu/hal/phydm_ccx.c
new file mode 100644
index 000000000000..e8417490e7e2
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_ccx.c
@@ -0,0 +1,389 @@
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+/*Set NHM period, threshold, disable ignore cca or not, disable ignore txon or not*/
+void
+phydm_nhm_setting(
+ void *p_dm_void,
+ u8 nhm_setting
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _CCX_INFO *ccx_info = &p_dm_odm->dm_ccx_info;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+
+ if (nhm_setting == SET_NHM_SETTING) {
+
+ /*Set inexclude_cca, inexclude_txon*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(9), ccx_info->nhm_inexclude_cca);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(10), ccx_info->nhm_inexclude_txon);
+
+ /*Set NHM period*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCX_PERIOD_11AC, MASKHWORD, ccx_info->NHM_period);
+
+ /*Set NHM threshold*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE0, ccx_info->NHM_th[0]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE1, ccx_info->NHM_th[1]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE2, ccx_info->NHM_th[2]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE3, ccx_info->NHM_th[3]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE0, ccx_info->NHM_th[4]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE1, ccx_info->NHM_th[5]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE2, ccx_info->NHM_th[6]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE3, ccx_info->NHM_th[7]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH8_11AC, MASKBYTE0, ccx_info->NHM_th[8]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE2, ccx_info->NHM_th[9]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE3, ccx_info->NHM_th[10]);
+
+ /*CCX EN*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(8), CCX_EN);
+
+ } else if (nhm_setting == STORE_NHM_SETTING) {
+
+ /*Store pervious disable_ignore_cca, disable_ignore_txon*/
+ ccx_info->NHM_inexclude_cca_restore = (enum nhm_inexclude_cca)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(9));
+ ccx_info->NHM_inexclude_txon_restore = (enum nhm_inexclude_txon)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(10));
+
+ /*Store pervious NHM period*/
+ ccx_info->NHM_period_restore = (u16)odm_get_bb_reg(p_dm_odm, ODM_REG_CCX_PERIOD_11AC, MASKHWORD);
+
+ /*Store NHM threshold*/
+ ccx_info->NHM_th_restore[0] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE0);
+ ccx_info->NHM_th_restore[1] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE1);
+ ccx_info->NHM_th_restore[2] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE2);
+ ccx_info->NHM_th_restore[3] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE3);
+ ccx_info->NHM_th_restore[4] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE0);
+ ccx_info->NHM_th_restore[5] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE1);
+ ccx_info->NHM_th_restore[6] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE2);
+ ccx_info->NHM_th_restore[7] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE3);
+ ccx_info->NHM_th_restore[8] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH8_11AC, MASKBYTE0);
+ ccx_info->NHM_th_restore[9] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE2);
+ ccx_info->NHM_th_restore[10] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE3);
+ } else if (nhm_setting == RESTORE_NHM_SETTING) {
+
+ /*Set disable_ignore_cca, disable_ignore_txon*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(9), ccx_info->NHM_inexclude_cca_restore);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(10), ccx_info->NHM_inexclude_txon_restore);
+
+ /*Set NHM period*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCX_PERIOD_11AC, MASKHWORD, ccx_info->NHM_period);
+
+ /*Set NHM threshold*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE0, ccx_info->NHM_th_restore[0]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE1, ccx_info->NHM_th_restore[1]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE2, ccx_info->NHM_th_restore[2]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, MASKBYTE3, ccx_info->NHM_th_restore[3]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE0, ccx_info->NHM_th_restore[4]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE1, ccx_info->NHM_th_restore[5]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE2, ccx_info->NHM_th_restore[6]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, MASKBYTE3, ccx_info->NHM_th_restore[7]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH8_11AC, MASKBYTE0, ccx_info->NHM_th_restore[8]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE2, ccx_info->NHM_th_restore[9]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, MASKBYTE3, ccx_info->NHM_th_restore[10]);
+ } else
+ return;
+ }
+
+ else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+
+ if (nhm_setting == SET_NHM_SETTING) {
+
+ /*Set disable_ignore_cca, disable_ignore_txon*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(9), ccx_info->nhm_inexclude_cca);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(10), ccx_info->nhm_inexclude_txon);
+
+ /*Set NHM period*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCX_PERIOD_11N, MASKHWORD, ccx_info->NHM_period);
+
+ /*Set NHM threshold*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE0, ccx_info->NHM_th[0]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE1, ccx_info->NHM_th[1]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE2, ccx_info->NHM_th[2]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE3, ccx_info->NHM_th[3]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE0, ccx_info->NHM_th[4]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE1, ccx_info->NHM_th[5]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE2, ccx_info->NHM_th[6]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE3, ccx_info->NHM_th[7]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH8_11N, MASKBYTE0, ccx_info->NHM_th[8]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE2, ccx_info->NHM_th[9]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE3, ccx_info->NHM_th[10]);
+
+ /*CCX EN*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(8), CCX_EN);
+ } else if (nhm_setting == STORE_NHM_SETTING) {
+
+ /*Store pervious disable_ignore_cca, disable_ignore_txon*/
+ ccx_info->NHM_inexclude_cca_restore = (enum nhm_inexclude_cca)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(9));
+ ccx_info->NHM_inexclude_txon_restore = (enum nhm_inexclude_txon)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(10));
+
+ /*Store pervious NHM period*/
+ ccx_info->NHM_period_restore = (u16)odm_get_bb_reg(p_dm_odm, ODM_REG_CCX_PERIOD_11N, MASKHWORD);
+
+ /*Store NHM threshold*/
+ ccx_info->NHM_th_restore[0] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE0);
+ ccx_info->NHM_th_restore[1] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE1);
+ ccx_info->NHM_th_restore[2] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE2);
+ ccx_info->NHM_th_restore[3] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE3);
+ ccx_info->NHM_th_restore[4] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE0);
+ ccx_info->NHM_th_restore[5] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE1);
+ ccx_info->NHM_th_restore[6] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE2);
+ ccx_info->NHM_th_restore[7] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE3);
+ ccx_info->NHM_th_restore[8] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH8_11N, MASKBYTE0);
+ ccx_info->NHM_th_restore[9] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE2);
+ ccx_info->NHM_th_restore[10] = (u8)odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE3);
+
+ } else if (nhm_setting == RESTORE_NHM_SETTING) {
+
+ /*Set disable_ignore_cca, disable_ignore_txon*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(9), ccx_info->NHM_inexclude_cca_restore);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(10), ccx_info->NHM_inexclude_txon_restore);
+
+ /*Set NHM period*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCX_PERIOD_11N, MASKHWORD, ccx_info->NHM_period_restore);
+
+ /*Set NHM threshold*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE0, ccx_info->NHM_th_restore[0]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE1, ccx_info->NHM_th_restore[1]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE2, ccx_info->NHM_th_restore[2]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, MASKBYTE3, ccx_info->NHM_th_restore[3]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE0, ccx_info->NHM_th_restore[4]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE1, ccx_info->NHM_th_restore[5]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE2, ccx_info->NHM_th_restore[6]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, MASKBYTE3, ccx_info->NHM_th_restore[7]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH8_11N, MASKBYTE0, ccx_info->NHM_th_restore[8]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE2, ccx_info->NHM_th_restore[9]);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, MASKBYTE3, ccx_info->NHM_th_restore[10]);
+ } else
+ return;
+
+ }
+}
+
+void
+phydm_nhm_trigger(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _CCX_INFO *ccx_info = &p_dm_odm->dm_ccx_info;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+
+ /*Trigger NHM*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 0);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 1);
+ } else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+
+ /*Trigger NHM*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 0);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 1);
+ }
+}
+
+void
+phydm_get_nhm_result(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 value32;
+ struct _CCX_INFO *ccx_info = &p_dm_odm->dm_ccx_info;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+
+ value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_CNT_11AC);
+ ccx_info->NHM_result[0] = (u8)(value32 & MASKBYTE0);
+ ccx_info->NHM_result[1] = (u8)((value32 & MASKBYTE1) >> 8);
+ ccx_info->NHM_result[2] = (u8)((value32 & MASKBYTE2) >> 16);
+ ccx_info->NHM_result[3] = (u8)((value32 & MASKBYTE3) >> 24);
+
+ value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_CNT7_TO_CNT4_11AC);
+ ccx_info->NHM_result[4] = (u8)(value32 & MASKBYTE0);
+ ccx_info->NHM_result[5] = (u8)((value32 & MASKBYTE1) >> 8);
+ ccx_info->NHM_result[6] = (u8)((value32 & MASKBYTE2) >> 16);
+ ccx_info->NHM_result[7] = (u8)((value32 & MASKBYTE3) >> 24);
+
+ value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_CNT11_TO_CNT8_11AC);
+ ccx_info->NHM_result[8] = (u8)(value32 & MASKBYTE0);
+ ccx_info->NHM_result[9] = (u8)((value32 & MASKBYTE1) >> 8);
+ ccx_info->NHM_result[10] = (u8)((value32 & MASKBYTE2) >> 16);
+ ccx_info->NHM_result[11] = (u8)((value32 & MASKBYTE3) >> 24);
+
+ /*Get NHM duration*/
+ value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_DUR_READY_11AC);
+ ccx_info->NHM_duration = (u16)(value32 & MASKLWORD);
+
+ }
+
+ else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+
+ value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_CNT_11N);
+ ccx_info->NHM_result[0] = (u8)(value32 & MASKBYTE0);
+ ccx_info->NHM_result[1] = (u8)((value32 & MASKBYTE1) >> 8);
+ ccx_info->NHM_result[2] = (u8)((value32 & MASKBYTE2) >> 16);
+ ccx_info->NHM_result[3] = (u8)((value32 & MASKBYTE3) >> 24);
+
+ value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_CNT7_TO_CNT4_11N);
+ ccx_info->NHM_result[4] = (u8)(value32 & MASKBYTE0);
+ ccx_info->NHM_result[5] = (u8)((value32 & MASKBYTE1) >> 8);
+ ccx_info->NHM_result[6] = (u8)((value32 & MASKBYTE2) >> 16);
+ ccx_info->NHM_result[7] = (u8)((value32 & MASKBYTE3) >> 24);
+
+ value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_CNT9_TO_CNT8_11N);
+ ccx_info->NHM_result[8] = (u8)((value32 & MASKBYTE2) >> 16);
+ ccx_info->NHM_result[9] = (u8)((value32 & MASKBYTE3) >> 24);
+
+ value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_CNT10_TO_CNT11_11N);
+ ccx_info->NHM_result[10] = (u8)((value32 & MASKBYTE2) >> 16);
+ ccx_info->NHM_result[11] = (u8)((value32 & MASKBYTE3) >> 24);
+
+ /*Get NHM duration*/
+ value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_CNT10_TO_CNT11_11N);
+ ccx_info->NHM_duration = (u16)(value32 & MASKLWORD);
+
+ }
+
+}
+
+bool
+phydm_check_nhm_ready(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 value32 = 0;
+ u8 i;
+ bool ret = false;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_CLM_RESULT_11AC, MASKDWORD);
+
+ for (i = 0; i < 200; i++) {
+
+ ODM_delay_ms(1);
+ if (odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_DUR_READY_11AC, BIT(17))) {
+ ret = 1;
+ break;
+ }
+ }
+ }
+
+ else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_CLM_READY_11N, MASKDWORD);
+
+ for (i = 0; i < 200; i++) {
+
+ ODM_delay_ms(1);
+ if (odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_DUR_READY_11AC, BIT(17))) {
+ ret = 1;
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+static void phydm_store_nhm_setting(void *p_dm_void)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _CCX_INFO *ccx_info = &p_dm_odm->dm_ccx_info;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+
+
+ } else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+
+
+
+ }
+}
+
+void
+phydm_clm_setting(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _CCX_INFO *ccx_info = &p_dm_odm->dm_ccx_info;
+
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCX_PERIOD_11AC, MASKLWORD, ccx_info->CLM_period); /*4us sample 1 time*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CLM_11AC, BIT(8), 0x1); /*Enable CCX for CLM*/
+
+ } else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCX_PERIOD_11N, MASKLWORD, ccx_info->CLM_period); /*4us sample 1 time*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CLM_11N, BIT(8), 0x1); /*Enable CCX for CLM*/
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CCX, ODM_DBG_LOUD, ("[%s] : CLM period = %dus\n", __func__, ccx_info->CLM_period * 4));
+
+}
+
+void
+phydm_clm_trigger(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CLM_11AC, BIT(0), 0x0); /*Trigger CLM*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CLM_11AC, BIT(0), 0x1);
+ } else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CLM_11N, BIT(0), 0x0); /*Trigger CLM*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CLM_11N, BIT(0), 0x1);
+ }
+}
+
+bool
+phydm_check_cl_mready(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 value32 = 0;
+ bool ret = false;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_CLM_RESULT_11AC, MASKDWORD); /*make sure CLM calc is ready*/
+ else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_CLM_READY_11N, MASKDWORD); /*make sure CLM calc is ready*/
+
+ if ((p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) && (value32 & BIT(16)))
+ ret = true;
+ else if ((p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) && (value32 & BIT(16)))
+ ret = true;
+ else
+ ret = false;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CCX, ODM_DBG_LOUD, ("[%s] : CLM ready = %d\n", __func__, ret));
+
+ return ret;
+}
+
+void
+phydm_get_cl_mresult(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _CCX_INFO *ccx_info = &p_dm_odm->dm_ccx_info;
+
+ u32 value32 = 0;
+ u16 results = 0;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_CLM_RESULT_11AC, MASKDWORD); /*read CLM calc result*/
+ else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_CLM_RESULT_11N, MASKDWORD); /*read CLM calc result*/
+
+ ccx_info->CLM_result = (u16)(value32 & MASKLWORD);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CCX, ODM_DBG_LOUD, ("[%s] : CLM result = %dus\n", __func__, ccx_info->CLM_result * 4));
+
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_ccx.h b/drivers/staging/rtl8188eu/hal/phydm_ccx.h
new file mode 100644
index 000000000000..d9adf6332e30
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_ccx.h
@@ -0,0 +1,102 @@
+#ifndef __PHYDMCCX_H__
+#define __PHYDMCCX_H__
+
+#define CCX_EN 1
+
+#define SET_NHM_SETTING 0
+#define STORE_NHM_SETTING 1
+#define RESTORE_NHM_SETTING 2
+
+/*
+#define NHM_EXCLUDE_CCA 0
+#define NHM_INCLUDE_CCA 1
+#define NHM_EXCLUDE_TXON 0
+#define NHM_INCLUDE_TXON 1
+*/
+
+enum nhm_inexclude_cca {
+ NHM_EXCLUDE_CCA,
+ NHM_INCLUDE_CCA
+};
+
+enum nhm_inexclude_txon {
+ NHM_EXCLUDE_TXON,
+ NHM_INCLUDE_TXON
+};
+
+
+struct _CCX_INFO {
+
+ /*Settings*/
+ u8 NHM_th[11];
+ u16 NHM_period; /* 4us per unit */
+ u16 CLM_period; /* 4us per unit */
+ enum nhm_inexclude_txon nhm_inexclude_txon;
+ enum nhm_inexclude_cca nhm_inexclude_cca;
+
+ /*Previous Settings*/
+ u8 NHM_th_restore[11];
+ u16 NHM_period_restore; /* 4us per unit */
+ u16 CLM_period_restore; /* 4us per unit */
+ enum nhm_inexclude_txon NHM_inexclude_txon_restore;
+ enum nhm_inexclude_cca NHM_inexclude_cca_restore;
+
+ /*Report*/
+ u8 NHM_result[12];
+ u16 NHM_duration;
+ u16 CLM_result;
+
+
+ bool echo_NHM_en;
+ bool echo_CLM_en;
+ u8 echo_IGI;
+
+};
+
+/*NHM*/
+
+void
+phydm_nhm_setting(
+ void *p_dm_void,
+ u8 nhm_setting
+);
+
+void
+phydm_nhm_trigger(
+ void *p_dm_void
+);
+
+void
+phydm_get_nhm_result(
+ void *p_dm_void
+);
+
+bool
+phydm_check_nhm_ready(
+ void *p_dm_void
+);
+
+/*CLM*/
+
+void
+phydm_clm_setting(
+ void *p_dm_void
+);
+
+void
+phydm_clm_trigger(
+ void *p_dm_void
+);
+
+bool
+phydm_check_cl_mready(
+ void *p_dm_void
+);
+
+void
+phydm_get_cl_mresult(
+ void *p_dm_void
+);
+
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_cfotracking.c b/drivers/staging/rtl8188eu/hal/phydm_cfotracking.c
new file mode 100644
index 000000000000..b8782d1ac6db
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_cfotracking.c
@@ -0,0 +1,297 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+static void
+odm_set_crystal_cap(
+ void *p_dm_void,
+ u8 crystal_cap
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _CFO_TRACKING_ *p_cfo_track = (struct _CFO_TRACKING_ *)phydm_get_structure(p_dm_odm, PHYDM_CFOTRACK);
+
+ if (p_cfo_track->crystal_cap == crystal_cap)
+ return;
+
+ p_cfo_track->crystal_cap = crystal_cap;
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8188E | ODM_RTL8188F)) {
+ /* write 0x24[22:17] = 0x24[16:11] = crystal_cap */
+ crystal_cap = crystal_cap & 0x3F;
+ odm_set_bb_reg(p_dm_odm, REG_AFE_XTAL_CTRL, 0x007ff800, (crystal_cap | (crystal_cap << 6)));
+ } else if (p_dm_odm->support_ic_type & ODM_RTL8812) {
+ /* write 0x2C[30:25] = 0x2C[24:19] = crystal_cap */
+ crystal_cap = crystal_cap & 0x3F;
+ odm_set_bb_reg(p_dm_odm, REG_MAC_PHY_CTRL, 0x7FF80000, (crystal_cap | (crystal_cap << 6)));
+ } else if ((p_dm_odm->support_ic_type & (ODM_RTL8703B | ODM_RTL8723B | ODM_RTL8192E | ODM_RTL8821))) {
+ /* 0x2C[23:18] = 0x2C[17:12] = crystal_cap */
+ crystal_cap = crystal_cap & 0x3F;
+ odm_set_bb_reg(p_dm_odm, REG_MAC_PHY_CTRL, 0x00FFF000, (crystal_cap | (crystal_cap << 6)));
+ } else if (p_dm_odm->support_ic_type & ODM_RTL8814A) {
+ /* write 0x2C[26:21] = 0x2C[20:15] = crystal_cap */
+ crystal_cap = crystal_cap & 0x3F;
+ odm_set_bb_reg(p_dm_odm, REG_MAC_PHY_CTRL, 0x07FF8000, (crystal_cap | (crystal_cap << 6)));
+ } else if (p_dm_odm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C)) {
+ /* write 0x24[30:25] = 0x28[6:1] = crystal_cap */
+ crystal_cap = crystal_cap & 0x3F;
+ odm_set_bb_reg(p_dm_odm, REG_AFE_XTAL_CTRL, 0x7e000000, crystal_cap);
+ odm_set_bb_reg(p_dm_odm, REG_AFE_PLL_CTRL, 0x7e, crystal_cap);
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_set_crystal_cap(): Use default setting.\n"));
+ odm_set_bb_reg(p_dm_odm, REG_MAC_PHY_CTRL, 0xFFF000, (crystal_cap | (crystal_cap << 6)));
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_set_crystal_cap(): crystal_cap = 0x%x\n", crystal_cap));
+}
+
+static u8
+odm_get_default_crytaltal_cap(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 crystal_cap = 0x20;
+
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
+
+ crystal_cap = p_hal_data->crystal_cap;
+
+ crystal_cap = crystal_cap & 0x3f;
+
+ return crystal_cap;
+}
+
+static void
+odm_set_atc_status(
+ void *p_dm_void,
+ bool atc_status
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _CFO_TRACKING_ *p_cfo_track = (struct _CFO_TRACKING_ *)phydm_get_structure(p_dm_odm, PHYDM_CFOTRACK);
+
+ if (p_cfo_track->is_atc_status == atc_status)
+ return;
+
+ odm_set_bb_reg(p_dm_odm, ODM_REG(BB_ATC, p_dm_odm), ODM_BIT(BB_ATC, p_dm_odm), atc_status);
+ p_cfo_track->is_atc_status = atc_status;
+}
+
+static bool
+odm_get_atc_status(
+ void *p_dm_void
+)
+{
+ bool atc_status;
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ atc_status = (bool)odm_get_bb_reg(p_dm_odm, ODM_REG(BB_ATC, p_dm_odm), ODM_BIT(BB_ATC, p_dm_odm));
+ return atc_status;
+}
+
+void
+odm_cfo_tracking_reset(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _CFO_TRACKING_ *p_cfo_track = (struct _CFO_TRACKING_ *)phydm_get_structure(p_dm_odm, PHYDM_CFOTRACK);
+
+ p_cfo_track->def_x_cap = odm_get_default_crytaltal_cap(p_dm_odm);
+ p_cfo_track->is_adjust = true;
+
+ if (p_cfo_track->crystal_cap > p_cfo_track->def_x_cap) {
+ odm_set_crystal_cap(p_dm_odm, p_cfo_track->crystal_cap - 1);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD,
+ ("odm_cfo_tracking_reset(): approch default value (0x%x)\n", p_cfo_track->crystal_cap));
+ } else if (p_cfo_track->crystal_cap < p_cfo_track->def_x_cap) {
+ odm_set_crystal_cap(p_dm_odm, p_cfo_track->crystal_cap + 1);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD,
+ ("odm_cfo_tracking_reset(): approch default value (0x%x)\n", p_cfo_track->crystal_cap));
+ }
+ odm_set_atc_status(p_dm_odm, true);
+}
+
+void
+odm_cfo_tracking_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _CFO_TRACKING_ *p_cfo_track = (struct _CFO_TRACKING_ *)phydm_get_structure(p_dm_odm, PHYDM_CFOTRACK);
+
+ p_cfo_track->def_x_cap = p_cfo_track->crystal_cap = odm_get_default_crytaltal_cap(p_dm_odm);
+ p_cfo_track->is_atc_status = odm_get_atc_status(p_dm_odm);
+ p_cfo_track->is_adjust = true;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking_init()=========>\n"));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("ODM_CfoTracking_init(): is_atc_status = %d, crystal_cap = 0x%x\n", p_cfo_track->is_atc_status, p_cfo_track->def_x_cap));
+}
+
+void
+odm_cfo_tracking(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _CFO_TRACKING_ *p_cfo_track = (struct _CFO_TRACKING_ *)phydm_get_structure(p_dm_odm, PHYDM_CFOTRACK);
+ s32 CFO_ave = 0;
+ u32 CFO_rpt_sum, cfo_khz_avg[4] = {0};
+ s32 CFO_ave_diff;
+ s8 crystal_cap = p_cfo_track->crystal_cap;
+ u8 adjust_xtal = 1, i, valid_path_cnt = 0;
+
+ /* 4 Support ability */
+ if (!(p_dm_odm->support_ability & ODM_BB_CFO_TRACKING)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_cfo_tracking(): Return: support_ability ODM_BB_CFO_TRACKING is disabled\n"));
+ return;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_cfo_tracking()=========>\n"));
+
+ if (!p_dm_odm->is_linked || !p_dm_odm->is_one_entry_only) {
+ /* 4 No link or more than one entry */
+ odm_cfo_tracking_reset(p_dm_odm);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_cfo_tracking(): Reset: is_linked = %d, is_one_entry_only = %d\n",
+ p_dm_odm->is_linked, p_dm_odm->is_one_entry_only));
+ } else {
+ /* 3 1. CFO Tracking */
+ /* 4 1.1 No new packet */
+ if (p_cfo_track->packet_count == p_cfo_track->packet_count_pre) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_cfo_tracking(): packet counter doesn't change\n"));
+ return;
+ }
+ p_cfo_track->packet_count_pre = p_cfo_track->packet_count;
+
+ /* 4 1.2 Calculate CFO */
+ for (i = 0; i < p_dm_odm->num_rf_path; i++) {
+
+ if (p_cfo_track->CFO_cnt[i] == 0)
+ continue;
+
+ valid_path_cnt++;
+ CFO_rpt_sum = (u32)((p_cfo_track->CFO_tail[i] < 0) ? (0 - p_cfo_track->CFO_tail[i]) : p_cfo_track->CFO_tail[i]);
+ cfo_khz_avg[i] = CFO_HW_RPT_2_MHZ(CFO_rpt_sum) / p_cfo_track->CFO_cnt[i];
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("[path %d] CFO_rpt_sum = (( %d )), CFO_cnt = (( %d )) , CFO_avg= (( %s%d )) kHz\n",
+ i, CFO_rpt_sum, p_cfo_track->CFO_cnt[i], ((p_cfo_track->CFO_tail[i] < 0) ? "-" : " "), cfo_khz_avg[i]));
+ }
+
+ for (i = 0; i < valid_path_cnt; i++) {
+
+ /* ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("path [%d], p_cfo_track->CFO_tail = %d\n", i, p_cfo_track->CFO_tail[i])); */
+ if (p_cfo_track->CFO_tail[i] < 0) {
+ CFO_ave += (0 - (s32)cfo_khz_avg[i]);
+ /* ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("CFO_ave = %d\n", CFO_ave)); */
+ } else
+ CFO_ave += (s32)cfo_khz_avg[i];
+ }
+
+ if (valid_path_cnt >= 2)
+ CFO_ave = CFO_ave / valid_path_cnt;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("valid_path_cnt = ((%d)), CFO_ave = ((%d kHz))\n", valid_path_cnt, CFO_ave));
+
+ /*reset counter*/
+ for (i = 0; i < p_dm_odm->num_rf_path; i++) {
+ p_cfo_track->CFO_tail[i] = 0;
+ p_cfo_track->CFO_cnt[i] = 0;
+ }
+
+ /* 4 1.3 Avoid abnormal large CFO */
+ CFO_ave_diff = (p_cfo_track->CFO_ave_pre >= CFO_ave) ? (p_cfo_track->CFO_ave_pre - CFO_ave) : (CFO_ave - p_cfo_track->CFO_ave_pre);
+ if (CFO_ave_diff > 20 && p_cfo_track->large_cfo_hit == 0 && !p_cfo_track->is_adjust) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_cfo_tracking(): first large CFO hit\n"));
+ p_cfo_track->large_cfo_hit = 1;
+ return;
+ } else
+ p_cfo_track->large_cfo_hit = 0;
+ p_cfo_track->CFO_ave_pre = CFO_ave;
+
+ /* 4 1.4 Dynamic Xtal threshold */
+ if (p_cfo_track->is_adjust == false) {
+ if (CFO_ave > CFO_TH_XTAL_HIGH || CFO_ave < (-CFO_TH_XTAL_HIGH))
+ p_cfo_track->is_adjust = true;
+ } else {
+ if (CFO_ave < CFO_TH_XTAL_LOW && CFO_ave > (-CFO_TH_XTAL_LOW))
+ p_cfo_track->is_adjust = false;
+ }
+
+ /* 4 1.5 BT case: Disable CFO tracking */
+ if (p_dm_odm->is_bt_enabled) {
+ p_cfo_track->is_adjust = false;
+ odm_set_crystal_cap(p_dm_odm, p_cfo_track->def_x_cap);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_cfo_tracking(): Disable CFO tracking for BT!!\n"));
+ }
+
+ /* 4 1.7 Adjust Crystal Cap. */
+ if (p_cfo_track->is_adjust) {
+ if (CFO_ave > CFO_TH_XTAL_LOW)
+ crystal_cap = crystal_cap + adjust_xtal;
+ else if (CFO_ave < (-CFO_TH_XTAL_LOW))
+ crystal_cap = crystal_cap - adjust_xtal;
+
+ if (crystal_cap > 0x3f)
+ crystal_cap = 0x3f;
+ else if (crystal_cap < 0)
+ crystal_cap = 0;
+
+ odm_set_crystal_cap(p_dm_odm, (u8)crystal_cap);
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_cfo_tracking(): Crystal cap = 0x%x, Default Crystal cap = 0x%x\n",
+ p_cfo_track->crystal_cap, p_cfo_track->def_x_cap));
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
+ return;
+
+ /* 3 2. Dynamic ATC switch */
+ if (CFO_ave < CFO_TH_ATC && CFO_ave > -CFO_TH_ATC) {
+ odm_set_atc_status(p_dm_odm, false);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_cfo_tracking(): Disable ATC!!\n"));
+ } else {
+ odm_set_atc_status(p_dm_odm, true);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("odm_cfo_tracking(): Enable ATC!!\n"));
+ }
+ }
+}
+
+void
+odm_parsing_cfo(
+ void *p_dm_void,
+ void *p_pktinfo_void,
+ s8 *pcfotail,
+ u8 num_ss
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _odm_per_pkt_info_ *p_pktinfo = (struct _odm_per_pkt_info_ *)p_pktinfo_void;
+ struct _CFO_TRACKING_ *p_cfo_track = (struct _CFO_TRACKING_ *)phydm_get_structure(p_dm_odm, PHYDM_CFOTRACK);
+ u8 i;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_CFO_TRACKING))
+ return;
+
+ if (p_pktinfo->is_packet_match_bssid) {
+ if (num_ss > p_dm_odm->num_rf_path) /*For fool proof*/
+ num_ss = p_dm_odm->num_rf_path;
+
+ /* 3 Update CFO report for path-A & path-B */
+ /* Only paht-A and path-B have CFO tail and short CFO */
+ for (i = 0; i < num_ss; i++) {
+ p_cfo_track->CFO_tail[i] += pcfotail[i];
+ p_cfo_track->CFO_cnt[i]++;
+ /*ODM_RT_TRACE(p_dm_odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, ("[ID %d][path %d][rate 0x%x] CFO_tail = ((%d)), CFO_tail_sum = ((%d)), CFO_cnt = ((%d))\n",
+ p_pktinfo->station_id, i, p_pktinfo->data_rate, pcfotail[i], p_cfo_track->CFO_tail[i], p_cfo_track->CFO_cnt[i]));
+ */
+ }
+
+ /* 3 Update packet counter */
+ if (p_cfo_track->packet_count == 0xffffffff)
+ p_cfo_track->packet_count = 0;
+ else
+ p_cfo_track->packet_count++;
+ }
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_cfotracking.h b/drivers/staging/rtl8188eu/hal/phydm_cfotracking.h
new file mode 100644
index 000000000000..f59da576653f
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_cfotracking.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMCFOTRACK_H__
+#define __PHYDMCFOTRACK_H__
+
+#define CFO_TRACKING_VERSION "1.4" /*2015.10.01 Stanley, Modify for 8822B*/
+
+#define CFO_TH_XTAL_HIGH 20 /* kHz */
+#define CFO_TH_XTAL_LOW 10 /* kHz */
+#define CFO_TH_ATC 80 /* kHz */
+
+struct _CFO_TRACKING_ {
+ bool is_atc_status;
+ bool large_cfo_hit;
+ bool is_adjust;
+ u8 crystal_cap;
+ u8 def_x_cap;
+ s32 CFO_tail[4];
+ u32 CFO_cnt[4];
+ s32 CFO_ave_pre;
+ u32 packet_count;
+ u32 packet_count_pre;
+
+ bool is_force_xtal_cap;
+ bool is_reset;
+};
+
+void
+odm_cfo_tracking_reset(
+ void *p_dm_void
+);
+
+void
+odm_cfo_tracking_init(
+ void *p_dm_void
+);
+
+void
+odm_cfo_tracking(
+ void *p_dm_void
+);
+
+void
+odm_parsing_cfo(
+ void *p_dm_void,
+ void *p_pktinfo_void,
+ s8 *pcfotail,
+ u8 num_ss
+);
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_debug.c b/drivers/staging/rtl8188eu/hal/phydm_debug.c
new file mode 100644
index 000000000000..81361eeafb49
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_debug.c
@@ -0,0 +1,2357 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+void
+phydm_init_debug_setting(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ p_dm_odm->debug_level = ODM_DBG_TRACE;
+
+ p_dm_odm->fw_debug_components = 0;
+ p_dm_odm->debug_components =
+ \
+#if DBG
+ /*BB Functions*/
+ /* ODM_COMP_DIG |*/
+ /* ODM_COMP_RA_MASK |*/
+ /* ODM_COMP_DYNAMIC_TXPWR |*/
+ /* ODM_COMP_FA_CNT |*/
+ /* ODM_COMP_RSSI_MONITOR |*/
+ /* ODM_COMP_SNIFFER |*/
+ /* ODM_COMP_ANT_DIV |*/
+ /* ODM_COMP_NOISY_DETECT |*/
+ /* ODM_COMP_RATE_ADAPTIVE |*/
+ /* ODM_COMP_PATH_DIV |*/
+ /* ODM_COMP_DYNAMIC_PRICCA |*/
+ /* ODM_COMP_MP |*/
+ /* ODM_COMP_CFO_TRACKING |*/
+ /* ODM_COMP_ACS |*/
+ /* PHYDM_COMP_ADAPTIVITY |*/
+ /* PHYDM_COMP_RA_DBG |*/
+ /* PHYDM_COMP_TXBF |*/
+
+ /*MAC Functions*/
+ /* ODM_COMP_EDCA_TURBO |*/
+ /* ODM_COMP_DYNAMIC_RX_PATH |*/
+ /* ODM_FW_DEBUG_TRACE |*/
+
+ /*RF Functions*/
+ /* ODM_COMP_TX_PWR_TRACK |*/
+ /* ODM_COMP_CALIBRATION |*/
+
+ /*Common*/
+ /* ODM_PHY_CONFIG |*/
+ /* ODM_COMP_INIT |*/
+ /* ODM_COMP_COMMON |*/
+ /* ODM_COMP_API |*/
+
+
+#endif
+ 0;
+
+ p_dm_odm->fw_buff_is_enpty = true;
+ p_dm_odm->pre_c2h_seq = 0;
+}
+
+#if CONFIG_PHYDM_DEBUG_FUNCTION
+static void
+phydm_bb_rx_hang_info(
+ void *p_dm_void,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ u32 value32 = 0;
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
+ return;
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xF80, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "rptreg of sc/bw/ht/...", value32));
+
+ if (p_dm_odm->support_ic_type & ODM_RTL8822B)
+ odm_set_bb_reg(p_dm_odm, 0x198c, BIT(2) | BIT(1) | BIT(0), 7);
+
+ /* dbg_port = basic state machine */
+ {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x000);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "basic state machine", value32));
+ }
+
+ /* dbg_port = state machine */
+ {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x007);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "state machine", value32));
+ }
+
+ /* dbg_port = CCA-related*/
+ {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x204);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "CCA-related", value32));
+ }
+
+
+ /* dbg_port = edcca/rxd*/
+ {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x278);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "edcca/rxd", value32));
+ }
+
+ /* dbg_port = rx_state/mux_state/ADC_MASK_OFDM*/
+ {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x290);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "rx_state/mux_state/ADC_MASK_OFDM", value32));
+ }
+
+ /* dbg_port = bf-related*/
+ {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x2B2);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "bf-related", value32));
+ }
+
+ /* dbg_port = bf-related*/
+ {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x2B8);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "bf-related", value32));
+ }
+
+ /* dbg_port = txon/rxd*/
+ {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xA03);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "txon/rxd", value32));
+ }
+
+ /* dbg_port = l_rate/l_length*/
+ {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xA0B);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "l_rate/l_length", value32));
+ }
+
+ /* dbg_port = rxd/rxd_hit*/
+ {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xA0D);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "rxd/rxd_hit", value32));
+ }
+
+ /* dbg_port = dis_cca*/
+ {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xAA0);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "dis_cca", value32));
+ }
+
+
+ /* dbg_port = tx*/
+ {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xAB0);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "tx", value32));
+ }
+
+ /* dbg_port = rx plcp*/
+ {
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xAD0);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "rx plcp", value32));
+
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xAD1);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "rx plcp", value32));
+
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xAD2);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "rx plcp", value32));
+
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0xAD3);
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "0x8fc", value32));
+
+ value32 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = 0x%x", "rx plcp", value32));
+ }
+
+}
+
+static void
+phydm_bb_debug_info_n_series(
+ void *p_dm_void,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ u32 value32 = 0, value32_1 = 0, value32_2 = 0, value32_3 = 0;
+ u8 rf_gain_a = 0, rf_gain_b = 0, rf_gain_c = 0, rf_gain_d = 0;
+ u8 rx_snr_a = 0, rx_snr_b = 0, rx_snr_c = 0, rx_snr_d = 0;
+
+ s8 rxevm_0 = 0, rxevm_1 = 0;
+ s32 short_cfo_a = 0, short_cfo_b = 0, long_cfo_a = 0, long_cfo_b = 0;
+ s32 scfo_a = 0, scfo_b = 0, avg_cfo_a = 0, avg_cfo_b = 0;
+ s32 cfo_end_a = 0, cfo_end_b = 0, acq_cfo_a = 0, acq_cfo_b = 0;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s\n", "BB Report Info"));
+
+ /*AGC result*/
+ value32 = odm_get_bb_reg(p_dm_odm, 0xdd0, MASKDWORD);
+ rf_gain_a = (u8)(value32 & 0x3f);
+ rf_gain_a = rf_gain_a << 1;
+
+ rf_gain_b = (u8)((value32 >> 8) & 0x3f);
+ rf_gain_b = rf_gain_b << 1;
+
+ rf_gain_c = (u8)((value32 >> 16) & 0x3f);
+ rf_gain_c = rf_gain_c << 1;
+
+ rf_gain_d = (u8)((value32 >> 24) & 0x3f);
+ rf_gain_d = rf_gain_d << 1;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d / %d / %d", "OFDM RX RF Gain(A/B/C/D)", rf_gain_a, rf_gain_b, rf_gain_c, rf_gain_d));
+
+ /*SNR report*/
+ value32 = odm_get_bb_reg(p_dm_odm, 0xdd4, MASKDWORD);
+ rx_snr_a = (u8)(value32 & 0xff);
+ rx_snr_a = rx_snr_a >> 1;
+
+ rx_snr_b = (u8)((value32 >> 8) & 0xff);
+ rx_snr_b = rx_snr_b >> 1;
+
+ rx_snr_c = (u8)((value32 >> 16) & 0xff);
+ rx_snr_c = rx_snr_c >> 1;
+
+ rx_snr_d = (u8)((value32 >> 24) & 0xff);
+ rx_snr_d = rx_snr_d >> 1;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d / %d / %d", "RXSNR(A/B/C/D, dB)", rx_snr_a, rx_snr_b, rx_snr_c, rx_snr_d));
+
+ /* PostFFT related info*/
+ value32 = odm_get_bb_reg(p_dm_odm, 0xdd8, MASKDWORD);
+
+ rxevm_0 = (s8)((value32 & MASKBYTE2) >> 16);
+ rxevm_0 /= 2;
+ if (rxevm_0 < -63)
+ rxevm_0 = 0;
+
+ rxevm_1 = (s8)((value32 & MASKBYTE3) >> 24);
+ rxevm_1 /= 2;
+ if (rxevm_1 < -63)
+ rxevm_1 = 0;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d", "RXEVM (1ss/2ss)", rxevm_0, rxevm_1));
+
+ /*CFO Report Info*/
+ odm_set_bb_reg(p_dm_odm, 0xd00, BIT(26), 1);
+
+ /*Short CFO*/
+ value32 = odm_get_bb_reg(p_dm_odm, 0xdac, MASKDWORD);
+ value32_1 = odm_get_bb_reg(p_dm_odm, 0xdb0, MASKDWORD);
+
+ short_cfo_b = (s32)(value32 & 0xfff); /*S(12,11)*/
+ short_cfo_a = (s32)((value32 & 0x0fff0000) >> 16);
+
+ long_cfo_b = (s32)(value32_1 & 0x1fff); /*S(13,12)*/
+ long_cfo_a = (s32)((value32_1 & 0x1fff0000) >> 16);
+
+ /*SFO 2's to dec*/
+ if (short_cfo_a > 2047)
+ short_cfo_a = short_cfo_a - 4096;
+ if (short_cfo_b > 2047)
+ short_cfo_b = short_cfo_b - 4096;
+
+ short_cfo_a = (short_cfo_a * 312500) / 2048;
+ short_cfo_b = (short_cfo_b * 312500) / 2048;
+
+ /*LFO 2's to dec*/
+
+ if (long_cfo_a > 4095)
+ long_cfo_a = long_cfo_a - 8192;
+
+ if (long_cfo_b > 4095)
+ long_cfo_b = long_cfo_b - 8192;
+
+ long_cfo_a = long_cfo_a * 312500 / 4096;
+ long_cfo_b = long_cfo_b * 312500 / 4096;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s", "CFO Report Info"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d", "Short CFO(Hz) <A/B>", short_cfo_a, short_cfo_b));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d", "Long CFO(Hz) <A/B>", long_cfo_a, long_cfo_b));
+
+ /*SCFO*/
+ value32 = odm_get_bb_reg(p_dm_odm, 0xdb8, MASKDWORD);
+ value32_1 = odm_get_bb_reg(p_dm_odm, 0xdb4, MASKDWORD);
+
+ scfo_b = (s32)(value32 & 0x7ff); /*S(11,10)*/
+ scfo_a = (s32)((value32 & 0x07ff0000) >> 16);
+
+ if (scfo_a > 1023)
+ scfo_a = scfo_a - 2048;
+
+ if (scfo_b > 1023)
+ scfo_b = scfo_b - 2048;
+
+ scfo_a = scfo_a * 312500 / 1024;
+ scfo_b = scfo_b * 312500 / 1024;
+
+ avg_cfo_b = (s32)(value32_1 & 0x1fff); /*S(13,12)*/
+ avg_cfo_a = (s32)((value32_1 & 0x1fff0000) >> 16);
+
+ if (avg_cfo_a > 4095)
+ avg_cfo_a = avg_cfo_a - 8192;
+
+ if (avg_cfo_b > 4095)
+ avg_cfo_b = avg_cfo_b - 8192;
+
+ avg_cfo_a = avg_cfo_a * 312500 / 4096;
+ avg_cfo_b = avg_cfo_b * 312500 / 4096;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d", "value SCFO(Hz) <A/B>", scfo_a, scfo_b));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d", "Avg CFO(Hz) <A/B>", avg_cfo_a, avg_cfo_b));
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xdbc, MASKDWORD);
+ value32_1 = odm_get_bb_reg(p_dm_odm, 0xde0, MASKDWORD);
+
+ cfo_end_b = (s32)(value32 & 0x1fff); /*S(13,12)*/
+ cfo_end_a = (s32)((value32 & 0x1fff0000) >> 16);
+
+ if (cfo_end_a > 4095)
+ cfo_end_a = cfo_end_a - 8192;
+
+ if (cfo_end_b > 4095)
+ cfo_end_b = cfo_end_b - 8192;
+
+ cfo_end_a = cfo_end_a * 312500 / 4096;
+ cfo_end_b = cfo_end_b * 312500 / 4096;
+
+ acq_cfo_b = (s32)(value32_1 & 0x1fff); /*S(13,12)*/
+ acq_cfo_a = (s32)((value32_1 & 0x1fff0000) >> 16);
+
+ if (acq_cfo_a > 4095)
+ acq_cfo_a = acq_cfo_a - 8192;
+
+ if (acq_cfo_b > 4095)
+ acq_cfo_b = acq_cfo_b - 8192;
+
+ acq_cfo_a = acq_cfo_a * 312500 / 4096;
+ acq_cfo_b = acq_cfo_b * 312500 / 4096;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d", "End CFO(Hz) <A/B>", cfo_end_a, cfo_end_b));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d", "ACQ CFO(Hz) <A/B>", acq_cfo_a, acq_cfo_b));
+
+}
+
+
+static void
+phydm_bb_debug_info(
+ void *p_dm_void,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ char *tmp_string = NULL;
+
+ u8 RX_HT_BW, RX_VHT_BW, RXSC, RX_HT, RX_BW;
+ static u8 v_rx_bw ;
+ u32 value32, value32_1, value32_2, value32_3;
+ s32 SFO_A, SFO_B, SFO_C, SFO_D;
+ s32 LFO_A, LFO_B, LFO_C, LFO_D;
+ static u8 MCSS, tail, parity, rsv, vrsv, idx, smooth, htsound, agg, stbc, vstbc, fec, fecext, sgi, sgiext, htltf, vgid, v_nsts, vtxops, vrsv2, vbrsv, bf, vbcrc;
+ static u16 h_length, htcrc8, length;
+ static u16 vpaid;
+ static u16 v_length, vhtcrc8, v_mcss, v_tail, vb_tail;
+ static u8 HMCSS, HRX_BW;
+
+ u8 pwdb;
+ s8 RXEVM_0, RXEVM_1, RXEVM_2 ;
+ u8 rf_gain_path_a, rf_gain_path_b, rf_gain_path_c, rf_gain_path_d;
+ u8 rx_snr_path_a, rx_snr_path_b, rx_snr_path_c, rx_snr_path_d;
+ s32 sig_power;
+ const char *L_rate[8] = {"6M", "9M", "12M", "18M", "24M", "36M", "48M", "54M"};
+
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+ phydm_bb_debug_info_n_series(p_dm_odm, &used, output, &out_len);
+ return;
+ }
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s\n", "BB Report Info"));
+
+ /*BW & mode Detection*/
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xf80, MASKDWORD);
+ value32_2 = value32;
+ RX_HT_BW = (u8)(value32 & 0x1);
+ RX_VHT_BW = (u8)((value32 >> 1) & 0x3);
+ RXSC = (u8)(value32 & 0x78);
+ value32_1 = (value32 & 0x180) >> 7;
+ RX_HT = (u8)(value32_1);
+
+ RX_BW = 0;
+
+ if (RX_HT == 2) {
+ if (RX_VHT_BW == 0)
+ tmp_string = "20M";
+ else if (RX_VHT_BW == 1)
+ tmp_string = "40M";
+ else
+ tmp_string = "80M";
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s %s %s", "mode", "VHT", tmp_string));
+ RX_BW = RX_VHT_BW;
+ } else if (RX_HT == 1) {
+ if (RX_HT_BW == 0)
+ tmp_string = "20M";
+ else if (RX_HT_BW == 1)
+ tmp_string = "40M";
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s %s %s", "mode", "HT", tmp_string));
+ RX_BW = RX_HT_BW;
+ } else
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s %s", "mode", "Legacy"));
+
+ if (RX_HT != 0) {
+ if (RXSC == 0)
+ tmp_string = "duplicate/full bw";
+ else if (RXSC == 1)
+ tmp_string = "usc20-1";
+ else if (RXSC == 2)
+ tmp_string = "lsc20-1";
+ else if (RXSC == 3)
+ tmp_string = "usc20-2";
+ else if (RXSC == 4)
+ tmp_string = "lsc20-2";
+ else if (RXSC == 9)
+ tmp_string = "usc40";
+ else if (RXSC == 10)
+ tmp_string = "lsc40";
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s", tmp_string));
+ }
+
+ /* RX signal power and AGC related info*/
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xF90, MASKDWORD);
+ pwdb = (u8)((value32 & MASKBYTE1) >> 8);
+ pwdb = pwdb >> 1;
+ sig_power = -110 + pwdb;
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d", "OFDM RX Signal Power(dB)", sig_power));
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xd14, MASKDWORD);
+ rx_snr_path_a = (u8)(value32 & 0xFF) >> 1;
+ rf_gain_path_a = (s8)((value32 & MASKBYTE1) >> 8);
+ rf_gain_path_a *= 2;
+ value32 = odm_get_bb_reg(p_dm_odm, 0xd54, MASKDWORD);
+ rx_snr_path_b = (u8)(value32 & 0xFF) >> 1;
+ rf_gain_path_b = (s8)((value32 & MASKBYTE1) >> 8);
+ rf_gain_path_b *= 2;
+ value32 = odm_get_bb_reg(p_dm_odm, 0xd94, MASKDWORD);
+ rx_snr_path_c = (u8)(value32 & 0xFF) >> 1;
+ rf_gain_path_c = (s8)((value32 & MASKBYTE1) >> 8);
+ rf_gain_path_c *= 2;
+ value32 = odm_get_bb_reg(p_dm_odm, 0xdd4, MASKDWORD);
+ rx_snr_path_d = (u8)(value32 & 0xFF) >> 1;
+ rf_gain_path_d = (s8)((value32 & MASKBYTE1) >> 8);
+ rf_gain_path_d *= 2;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d / %d / %d", "OFDM RX RF Gain(A/B/C/D)", rf_gain_path_a, rf_gain_path_b, rf_gain_path_c, rf_gain_path_d));
+
+
+ /* RX counter related info*/
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xF08, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d", "OFDM CCA counter", ((value32 & 0xFFFF0000) >> 16)));
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xFD0, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d", "OFDM SBD Fail counter", value32 & 0xFFFF));
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xFC4, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d", "VHT SIGA/SIGB CRC8 Fail counter", value32 & 0xFFFF, ((value32 & 0xFFFF0000) >> 16)));
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xFCC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d", "CCK CCA counter", value32 & 0xFFFF));
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xFBC, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d", "LSIG (parity Fail/rate Illegal) counter", value32 & 0xFFFF, ((value32 & 0xFFFF0000) >> 16)));
+
+ value32_1 = odm_get_bb_reg(p_dm_odm, 0xFC8, MASKDWORD);
+ value32_2 = odm_get_bb_reg(p_dm_odm, 0xFC0, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d", "HT/VHT MCS NOT SUPPORT counter", ((value32_2 & 0xFFFF0000) >> 16), value32_1 & 0xFFFF));
+
+ /* PostFFT related info*/
+ value32 = odm_get_bb_reg(p_dm_odm, 0xF8c, MASKDWORD);
+ RXEVM_0 = (s8)((value32 & MASKBYTE2) >> 16);
+ RXEVM_0 /= 2;
+ if (RXEVM_0 < -63)
+ RXEVM_0 = 0;
+
+ RXEVM_1 = (s8)((value32 & MASKBYTE3) >> 24);
+ RXEVM_1 /= 2;
+ value32 = odm_get_bb_reg(p_dm_odm, 0xF88, MASKDWORD);
+ RXEVM_2 = (s8)((value32 & MASKBYTE2) >> 16);
+ RXEVM_2 /= 2;
+
+ if (RXEVM_1 < -63)
+ RXEVM_1 = 0;
+ if (RXEVM_2 < -63)
+ RXEVM_2 = 0;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d / %d", "RXEVM (1ss/2ss/3ss)", RXEVM_0, RXEVM_1, RXEVM_2));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d / %d / %d", "RXSNR(A/B/C/D, dB)", rx_snr_path_a, rx_snr_path_b, rx_snr_path_c, rx_snr_path_d));
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xF8C, MASKDWORD);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d", "CSI_1st /CSI_2nd", value32 & 0xFFFF, ((value32 & 0xFFFF0000) >> 16)));
+
+ /*BW & mode Detection*/
+
+ /*Reset Page F counter*/
+ odm_set_bb_reg(p_dm_odm, 0xB58, BIT(0), 1);
+ odm_set_bb_reg(p_dm_odm, 0xB58, BIT(0), 0);
+
+ /*CFO Report Info*/
+ /*Short CFO*/
+ value32 = odm_get_bb_reg(p_dm_odm, 0xd0c, MASKDWORD);
+ value32_1 = odm_get_bb_reg(p_dm_odm, 0xd4c, MASKDWORD);
+ value32_2 = odm_get_bb_reg(p_dm_odm, 0xd8c, MASKDWORD);
+ value32_3 = odm_get_bb_reg(p_dm_odm, 0xdcc, MASKDWORD);
+
+ SFO_A = (s32)(value32 & 0xfff);
+ SFO_B = (s32)(value32_1 & 0xfff);
+ SFO_C = (s32)(value32_2 & 0xfff);
+ SFO_D = (s32)(value32_3 & 0xfff);
+
+ LFO_A = (s32)(value32 >> 16);
+ LFO_B = (s32)(value32_1 >> 16);
+ LFO_C = (s32)(value32_2 >> 16);
+ LFO_D = (s32)(value32_3 >> 16);
+
+ /*SFO 2's to dec*/
+ if (SFO_A > 2047)
+ SFO_A = SFO_A - 4096;
+ SFO_A = (SFO_A * 312500) / 2048;
+ if (SFO_B > 2047)
+ SFO_B = SFO_B - 4096;
+ SFO_B = (SFO_B * 312500) / 2048;
+ if (SFO_C > 2047)
+ SFO_C = SFO_C - 4096;
+ SFO_C = (SFO_C * 312500) / 2048;
+ if (SFO_D > 2047)
+ SFO_D = SFO_D - 4096;
+ SFO_D = (SFO_D * 312500) / 2048;
+
+ /*LFO 2's to dec*/
+
+ if (LFO_A > 4095)
+ LFO_A = LFO_A - 8192;
+
+ if (LFO_B > 4095)
+ LFO_B = LFO_B - 8192;
+
+ if (LFO_C > 4095)
+ LFO_C = LFO_C - 8192;
+
+ if (LFO_D > 4095)
+ LFO_D = LFO_D - 8192;
+ LFO_A = LFO_A * 312500 / 4096;
+ LFO_B = LFO_B * 312500 / 4096;
+ LFO_C = LFO_C * 312500 / 4096;
+ LFO_D = LFO_D * 312500 / 4096;
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s", "CFO Report Info"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d / %d /%d", "Short CFO(Hz) <A/B/C/D>", SFO_A, SFO_B, SFO_C, SFO_D));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d / %d /%d", "Long CFO(Hz) <A/B/C/D>", LFO_A, LFO_B, LFO_C, LFO_D));
+
+ /*SCFO*/
+ value32 = odm_get_bb_reg(p_dm_odm, 0xd10, MASKDWORD);
+ value32_1 = odm_get_bb_reg(p_dm_odm, 0xd50, MASKDWORD);
+ value32_2 = odm_get_bb_reg(p_dm_odm, 0xd90, MASKDWORD);
+ value32_3 = odm_get_bb_reg(p_dm_odm, 0xdd0, MASKDWORD);
+
+ SFO_A = (s32)(value32 & 0x7ff);
+ SFO_B = (s32)(value32_1 & 0x7ff);
+ SFO_C = (s32)(value32_2 & 0x7ff);
+ SFO_D = (s32)(value32_3 & 0x7ff);
+
+ if (SFO_A > 1023)
+ SFO_A = SFO_A - 2048;
+
+ if (SFO_B > 2047)
+ SFO_B = SFO_B - 4096;
+
+ if (SFO_C > 2047)
+ SFO_C = SFO_C - 4096;
+
+ if (SFO_D > 2047)
+ SFO_D = SFO_D - 4096;
+
+ SFO_A = SFO_A * 312500 / 1024;
+ SFO_B = SFO_B * 312500 / 1024;
+ SFO_C = SFO_C * 312500 / 1024;
+ SFO_D = SFO_D * 312500 / 1024;
+
+ LFO_A = (s32)(value32 >> 16);
+ LFO_B = (s32)(value32_1 >> 16);
+ LFO_C = (s32)(value32_2 >> 16);
+ LFO_D = (s32)(value32_3 >> 16);
+
+ if (LFO_A > 4095)
+ LFO_A = LFO_A - 8192;
+
+ if (LFO_B > 4095)
+ LFO_B = LFO_B - 8192;
+
+ if (LFO_C > 4095)
+ LFO_C = LFO_C - 8192;
+
+ if (LFO_D > 4095)
+ LFO_D = LFO_D - 8192;
+ LFO_A = LFO_A * 312500 / 4096;
+ LFO_B = LFO_B * 312500 / 4096;
+ LFO_C = LFO_C * 312500 / 4096;
+ LFO_D = LFO_D * 312500 / 4096;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d / %d /%d", "value SCFO(Hz) <A/B/C/D>", SFO_A, SFO_B, SFO_C, SFO_D));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d / %d /%d", "ACQ CFO(Hz) <A/B/C/D>", LFO_A, LFO_B, LFO_C, LFO_D));
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xd14, MASKDWORD);
+ value32_1 = odm_get_bb_reg(p_dm_odm, 0xd54, MASKDWORD);
+ value32_2 = odm_get_bb_reg(p_dm_odm, 0xd94, MASKDWORD);
+ value32_3 = odm_get_bb_reg(p_dm_odm, 0xdd4, MASKDWORD);
+
+ LFO_A = (s32)(value32 >> 16);
+ LFO_B = (s32)(value32_1 >> 16);
+ LFO_C = (s32)(value32_2 >> 16);
+ LFO_D = (s32)(value32_3 >> 16);
+
+ if (LFO_A > 4095)
+ LFO_A = LFO_A - 8192;
+
+ if (LFO_B > 4095)
+ LFO_B = LFO_B - 8192;
+
+ if (LFO_C > 4095)
+ LFO_C = LFO_C - 8192;
+
+ if (LFO_D > 4095)
+ LFO_D = LFO_D - 8192;
+
+ LFO_A = LFO_A * 312500 / 4096;
+ LFO_B = LFO_B * 312500 / 4096;
+ LFO_C = LFO_C * 312500 / 4096;
+ LFO_D = LFO_D * 312500 / 4096;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d / %d / %d /%d", "End CFO(Hz) <A/B/C/D>", LFO_A, LFO_B, LFO_C, LFO_D));
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xf20, MASKDWORD); /*L SIG*/
+
+ tail = (u8)((value32 & 0xfc0000) >> 16);
+ parity = (u8)((value32 & 0x20000) >> 16);
+ length = (u16)((value32 & 0x1ffe00) >> 8);
+ rsv = (u8)(value32 & 0x10);
+ MCSS = (u8)(value32 & 0x0f);
+
+ switch (MCSS) {
+ case 0x0b:
+ idx = 0;
+ break;
+ case 0x0f:
+ idx = 1;
+ break;
+ case 0x0a:
+ idx = 2;
+ break;
+ case 0x0e:
+ idx = 3;
+ break;
+ case 0x09:
+ idx = 4;
+ break;
+ case 0x08:
+ idx = 5;
+ break;
+ case 0x0c:
+ idx = 6;
+ break;
+ default:
+ idx = 6;
+ break;
+
+ }
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s", "L-SIG"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s : %s", "rate", L_rate[idx]));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %x / %x / %x", "Rsv/length/parity", rsv, RX_BW, length));
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xf2c, MASKDWORD); /*HT SIG*/
+ if (RX_HT == 1) {
+
+ HMCSS = (u8)(value32 & 0x7F);
+ HRX_BW = (u8)(value32 & 0x80);
+ h_length = (u16)((value32 >> 8) & 0xffff);
+ }
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s", "HT-SIG1"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %x / %x / %x", "MCS/BW/length", HMCSS, HRX_BW, h_length));
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xf30, MASKDWORD); /*HT SIG*/
+
+ if (RX_HT == 1) {
+ smooth = (u8)(value32 & 0x01);
+ htsound = (u8)(value32 & 0x02);
+ rsv = (u8)(value32 & 0x04);
+ agg = (u8)(value32 & 0x08);
+ stbc = (u8)(value32 & 0x30);
+ fec = (u8)(value32 & 0x40);
+ sgi = (u8)(value32 & 0x80);
+ htltf = (u8)((value32 & 0x300) >> 8);
+ htcrc8 = (u16)((value32 & 0x3fc00) >> 8);
+ tail = (u8)((value32 & 0xfc0000) >> 16);
+ }
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s", "HT-SIG2"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %x / %x / %x / %x / %x / %x", "Smooth/NoSound/Rsv/Aggregate/STBC/LDPC", smooth, htsound, rsv, agg, stbc, fec));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %x / %x / %x / %x", "SGI/E-HT-LTFs/CRC/tail", sgi, htltf, htcrc8, tail));
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xf2c, MASKDWORD); /*VHT SIG A1*/
+ if (RX_HT == 2) {
+ /* value32 = odm_get_bb_reg(p_dm_odm, 0xf2c,MASKDWORD);*/
+ v_rx_bw = (u8)(value32 & 0x03);
+ vrsv = (u8)(value32 & 0x04);
+ vstbc = (u8)(value32 & 0x08);
+ vgid = (u8)((value32 & 0x3f0) >> 4);
+ v_nsts = (u8)(((value32 & 0x1c00) >> 8) + 1);
+ vpaid = (u16)(value32 & 0x3fe);
+ vtxops = (u8)((value32 & 0x400000) >> 20);
+ vrsv2 = (u8)((value32 & 0x800000) >> 20);
+ }
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s", "VHT-SIG-A1"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %x / %x / %x / %x / %x / %x / %x / %x", "BW/Rsv1/STBC/GID/Nsts/PAID/TXOPPS/Rsv2", v_rx_bw, vrsv, vstbc, vgid, v_nsts, vpaid, vtxops, vrsv2));
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xf30, MASKDWORD); /*VHT SIG*/
+
+ if (RX_HT == 2) {
+ /*value32 = odm_get_bb_reg(p_dm_odm, 0xf30,MASKDWORD); */ /*VHT SIG*/
+
+ /* sgi=(u8)(value32&0x01); */
+ sgiext = (u8)(value32 & 0x03);
+ /* fec = (u8)(value32&0x04); */
+ fecext = (u8)(value32 & 0x0C);
+
+ v_mcss = (u8)(value32 & 0xf0);
+ bf = (u8)((value32 & 0x100) >> 8);
+ vrsv = (u8)((value32 & 0x200) >> 8);
+ vhtcrc8 = (u16)((value32 & 0x3fc00) >> 8);
+ v_tail = (u8)((value32 & 0xfc0000) >> 16);
+ }
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s", "VHT-SIG-A2"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %x / %x / %x / %x / %x / %x / %x", "SGI/FEC/MCS/BF/Rsv/CRC/tail", sgiext, fecext, v_mcss, bf, vrsv, vhtcrc8, v_tail));
+
+ value32 = odm_get_bb_reg(p_dm_odm, 0xf34, MASKDWORD); /*VHT SIG*/
+ {
+ v_length = (u16)(value32 & 0x1fffff);
+ vbrsv = (u8)((value32 & 0x600000) >> 20);
+ vb_tail = (u16)((value32 & 0x1f800000) >> 20);
+ vbcrc = (u8)((value32 & 0x80000000) >> 28);
+
+ }
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s", "VHT-SIG-B"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %x / %x / %x / %x", "length/Rsv/tail/CRC", v_length, vbrsv, vb_tail, vbcrc));
+
+ /*for Condition number*/
+ if (p_dm_odm->support_ic_type & ODM_RTL8822B) {
+ s32 condition_num = 0;
+ char *factor = NULL;
+
+ odm_set_bb_reg(p_dm_odm, 0x1988, BIT(22), 0x1); /*enable report condition number*/
+
+ condition_num = odm_get_bb_reg(p_dm_odm, 0xf84, MASKDWORD);
+ condition_num = (condition_num & 0x3ffff) >> 4;
+
+ if (*p_dm_odm->p_band_width == ODM_BW80M)
+ factor = "256/234";
+ else if (*p_dm_odm->p_band_width == ODM_BW40M)
+ factor = "128/108";
+ else if (*p_dm_odm->p_band_width == ODM_BW20M) {
+ if (RX_HT != 2 || RX_HT != 1)
+ factor = "64/52"; /*HT or VHT*/
+ else
+ factor = "64/48"; /*legacy*/
+ }
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = %d (factor = %s)", "Condition number", condition_num, factor));
+
+ }
+
+}
+#endif /*#if CONFIG_PHYDM_DEBUG_FUNCTION*/
+
+void
+phydm_basic_dbg_message
+(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct false_ALARM_STATISTICS *false_alm_cnt = (struct false_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDMfalseALMCNT);
+ struct _CFO_TRACKING_ *p_cfo_track = (struct _CFO_TRACKING_ *)phydm_get_structure(p_dm_odm, PHYDM_CFOTRACK);
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ u16 macid, phydm_macid, client_cnt = 0;
+ struct sta_info *p_entry;
+ s32 tmp_val = 0;
+ u8 tmp_val_u1 = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("[PHYDM Common MSG] System up time: ((%d sec))----->\n", p_dm_odm->phydm_sys_up_time));
+
+ if (p_dm_odm->is_linked) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("Curr_STA_ID = 0x%x\n", p_dm_odm->curr_station_id));
+
+ /*Print RX rate*/
+ if (p_dm_odm->rx_rate <= ODM_RATE11M) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("[CCK AGC Report] LNA_idx = 0x%x, VGA_idx = 0x%x\n",
+ p_dm_odm->cck_lna_idx, p_dm_odm->cck_vga_idx));
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("[OFDM AGC Report] { 0x%x, 0x%x, 0x%x, 0x%x }\n",
+ p_dm_odm->ofdm_agc_idx[0], p_dm_odm->ofdm_agc_idx[1], p_dm_odm->ofdm_agc_idx[2], p_dm_odm->ofdm_agc_idx[3]));
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("RSSI: { %d, %d, %d, %d }, rx_rate:",
+ (p_dm_odm->RSSI_A == 0xff) ? 0 : p_dm_odm->RSSI_A,
+ (p_dm_odm->RSSI_B == 0xff) ? 0 : p_dm_odm->RSSI_B,
+ (p_dm_odm->RSSI_C == 0xff) ? 0 : p_dm_odm->RSSI_C,
+ (p_dm_odm->RSSI_D == 0xff) ? 0 : p_dm_odm->RSSI_D));
+
+ phydm_print_rate(p_dm_odm, p_dm_odm->rx_rate, ODM_COMP_COMMON);
+
+ /*Print TX rate*/
+ for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++) {
+
+ p_entry = p_dm_odm->p_odm_sta_info[macid];
+ if (IS_STA_VALID(p_entry)) {
+
+ phydm_macid = (p_dm_odm->platform2phydm_macid_table[macid]);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("TXRate [%d]:", macid));
+ phydm_print_rate(p_dm_odm, p_ra_table->link_tx_rate[macid], ODM_COMP_COMMON);
+
+ client_cnt++;
+
+ if (client_cnt == p_dm_odm->number_linked_client)
+ break;
+ }
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("TP { TX, RX, total} = {%d, %d, %d }Mbps, traffic_load = (%d))\n",
+ p_dm_odm->tx_tp, p_dm_odm->rx_tp, p_dm_odm->total_tp, p_dm_odm->traffic_load));
+
+ tmp_val_u1 = (p_cfo_track->crystal_cap > p_cfo_track->def_x_cap) ? (p_cfo_track->crystal_cap - p_cfo_track->def_x_cap) : (p_cfo_track->def_x_cap - p_cfo_track->crystal_cap);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("CFO_avg = ((%d kHz)) , CrystalCap_tracking = ((%s%d))\n",
+ p_cfo_track->CFO_ave_pre, ((p_cfo_track->crystal_cap > p_cfo_track->def_x_cap) ? "+" : "-"), tmp_val_u1));
+
+#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1)
+ /*STBC or LDPC pkt*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("LDPC = %s, STBC = %s\n", (p_dm_odm->phy_dbg_info.is_ldpc_pkt) ? "Y" : "N", (p_dm_odm->phy_dbg_info.is_stbc_pkt) ? "Y" : "N"));
+#endif
+ } else
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("No Link !!!\n"));
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n",
+ false_alm_cnt->cnt_cck_cca, false_alm_cnt->cnt_ofdm_cca, false_alm_cnt->cnt_cca_all));
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("[FA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n",
+ false_alm_cnt->cnt_cck_fail, false_alm_cnt->cnt_ofdm_fail, false_alm_cnt->cnt_all));
+
+#if (ODM_IC_11N_SERIES_SUPPORT == 1)
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("[OFDM FA Detail] Parity_Fail = (( %d )), Rate_Illegal = (( %d )), CRC8_fail = (( %d )), Mcs_fail = (( %d )), Fast_Fsync = (( %d )), SB_Search_fail = (( %d ))\n",
+ false_alm_cnt->cnt_parity_fail, false_alm_cnt->cnt_rate_illegal, false_alm_cnt->cnt_crc8_fail, false_alm_cnt->cnt_mcs_fail, false_alm_cnt->cnt_fast_fsync, false_alm_cnt->cnt_sb_search_fail));
+ }
+#endif
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("is_linked = %d, Num_client = %d, rssi_min = %d, current_igi = 0x%x, bNoisy=%d\n\n",
+ p_dm_odm->is_linked, p_dm_odm->number_linked_client, p_dm_odm->rssi_min, p_dm_dig_table->cur_ig_value, p_dm_odm->noisy_decision));
+}
+
+void phydm_basic_profile(
+ void *p_dm_void,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+#if CONFIG_PHYDM_DEBUG_FUNCTION
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ char *cut = NULL;
+ char *ic_type = NULL;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+ u32 commit_ver = 0;
+ u32 date = 0;
+ char *commit_by = NULL;
+ u32 release_ver = 0;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "%-35s\n", "% Basic Profile %"));
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E) {
+ ic_type = "RTL8188E";
+ date = RELEASE_DATE_8188E;
+ commit_by = COMMIT_BY_8188E;
+ release_ver = RELEASE_VERSION_8188E;
+ }
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s (MP Chip: %s)\n", "IC type", ic_type, p_dm_odm->is_mp_chip ? "Yes" : "No"));
+
+ if (p_dm_odm->cut_version == ODM_CUT_A)
+ cut = "A";
+ else if (p_dm_odm->cut_version == ODM_CUT_B)
+ cut = "B";
+ else if (p_dm_odm->cut_version == ODM_CUT_C)
+ cut = "C";
+ else if (p_dm_odm->cut_version == ODM_CUT_D)
+ cut = "D";
+ else if (p_dm_odm->cut_version == ODM_CUT_E)
+ cut = "E";
+ else if (p_dm_odm->cut_version == ODM_CUT_F)
+ cut = "F";
+ else if (p_dm_odm->cut_version == ODM_CUT_I)
+ cut = "I";
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "cut version", cut));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %d\n", "PHY Parameter version", odm_get_hw_img_version(p_dm_odm)));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %d\n", "PHY Parameter Commit date", date));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "PHY Parameter Commit by", commit_by));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %d\n", "PHY Parameter Release version", release_ver));
+
+ {
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %d (Subversion: %d)\n", "FW version", p_hal_data->firmware_version, p_hal_data->firmware_sub_version));
+ }
+ /* 1 PHY DM version List */
+ PHYDM_SNPRINTF((output + used, out_len - used, "%-35s\n", "% PHYDM version %"));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Code base", PHYDM_CODE_BASE));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Release Date", PHYDM_RELEASE_DATE));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "adaptivity", ADAPTIVITY_VERSION));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "DIG", DIG_VERSION));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Dynamic BB PowerSaving", DYNAMIC_BBPWRSAV_VERSION));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "CFO Tracking", CFO_TRACKING_VERSION));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Antenna Diversity", ANTDIV_VERSION));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Power Tracking", POWRTRACKING_VERSION));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Dynamic TxPower", DYNAMIC_TXPWR_VERSION));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "RA Info", RAINFO_VERSION));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Auto channel Selection", ACS_VERSION));
+#if PHYDM_SUPPORT_EDCA
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "EDCA Turbo", EDCATURBO_VERSION));
+#endif
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "path Diversity", PATHDIV_VERSION));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "LA mode", DYNAMIC_LA_MODE));
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Dynamic RX path", DYNAMIC_RX_PATH_VERSION));
+
+ *_used = used;
+ *_out_len = out_len;
+#endif /*#if CONFIG_PHYDM_DEBUG_FUNCTION*/
+}
+
+#if CONFIG_PHYDM_DEBUG_FUNCTION
+void
+phydm_fw_trace_en_h2c(
+ void *p_dm_void,
+ bool enable,
+ u32 fw_debug_component,
+ u32 monitor_mode,
+ u32 macid
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 h2c_parameter[7] = {0};
+ u8 cmd_length;
+
+ if (p_dm_odm->support_ic_type & PHYDM_IC_3081_SERIES) {
+
+ h2c_parameter[0] = enable;
+ h2c_parameter[1] = (u8)(fw_debug_component & MASKBYTE0);
+ h2c_parameter[2] = (u8)((fw_debug_component & MASKBYTE1) >> 8);
+ h2c_parameter[3] = (u8)((fw_debug_component & MASKBYTE2) >> 16);
+ h2c_parameter[4] = (u8)((fw_debug_component & MASKBYTE3) >> 24);
+ h2c_parameter[5] = (u8)monitor_mode;
+ h2c_parameter[6] = (u8)macid;
+ cmd_length = 7;
+
+ } else {
+
+ h2c_parameter[0] = enable;
+ h2c_parameter[1] = (u8)monitor_mode;
+ h2c_parameter[2] = (u8)macid;
+ cmd_length = 3;
+ }
+
+
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("---->\n"));
+ if (monitor_mode == 0)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[H2C] FW_debug_en: (( %d ))\n", enable));
+ else
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[H2C] FW_debug_en: (( %d )), mode: (( %d )), macid: (( %d ))\n", enable, monitor_mode, macid));
+ odm_fill_h2c_cmd(p_dm_odm, PHYDM_H2C_FW_TRACE_EN, cmd_length, h2c_parameter);
+}
+
+static void
+phydm_get_per_path_txagc(
+ void *p_dm_void,
+ u8 path,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 rate_idx;
+ u8 txagc;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+}
+
+static void
+phydm_get_txagc(
+ void *p_dm_void,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ /* path-A */
+ PHYDM_SNPRINTF((output + used, out_len - used, "%-35s\n", "path-A===================="));
+ phydm_get_per_path_txagc(p_dm_odm, ODM_RF_PATH_A, _used, output, _out_len);
+
+ /* path-B */
+ PHYDM_SNPRINTF((output + used, out_len - used, "\n%-35s\n", "path-B===================="));
+ phydm_get_per_path_txagc(p_dm_odm, ODM_RF_PATH_B, _used, output, _out_len);
+
+ /* path-C */
+ PHYDM_SNPRINTF((output + used, out_len - used, "\n%-35s\n", "path-C===================="));
+ phydm_get_per_path_txagc(p_dm_odm, ODM_RF_PATH_C, _used, output, _out_len);
+
+ /* path-D */
+ PHYDM_SNPRINTF((output + used, out_len - used, "\n%-35s\n", "path-D===================="));
+ phydm_get_per_path_txagc(p_dm_odm, ODM_RF_PATH_D, _used, output, _out_len);
+
+}
+
+static void
+phydm_set_txagc(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ /*dm_value[1] = path*/
+ /*dm_value[2] = hw_rate*/
+ /*dm_value[3] = power_index*/
+}
+
+static void
+phydm_debug_trace(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 pre_debug_components, one = 1;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ pre_debug_components = p_dm_odm->debug_components;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\n%s\n", "================================"));
+ if (dm_value[0] == 100) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "[Debug Message] PhyDM Selection"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "================================"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "00. (( %s ))DIG\n", ((p_dm_odm->debug_components & ODM_COMP_DIG) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "01. (( %s ))RA_MASK\n", ((p_dm_odm->debug_components & ODM_COMP_RA_MASK) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "02. (( %s ))DYNAMIC_TXPWR\n", ((p_dm_odm->debug_components & ODM_COMP_DYNAMIC_TXPWR) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "03. (( %s ))FA_CNT\n", ((p_dm_odm->debug_components & ODM_COMP_FA_CNT) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "04. (( %s ))RSSI_MONITOR\n", ((p_dm_odm->debug_components & ODM_COMP_RSSI_MONITOR) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "05. (( %s ))SNIFFER\n", ((p_dm_odm->debug_components & ODM_COMP_SNIFFER) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "06. (( %s ))ANT_DIV\n", ((p_dm_odm->debug_components & ODM_COMP_ANT_DIV) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "07. (( %s ))DFS\n", ((p_dm_odm->debug_components & ODM_COMP_DFS) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "08. (( %s ))NOISY_DETECT\n", ((p_dm_odm->debug_components & ODM_COMP_NOISY_DETECT) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "09. (( %s ))RATE_ADAPTIVE\n", ((p_dm_odm->debug_components & ODM_COMP_RATE_ADAPTIVE) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "10. (( %s ))PATH_DIV\n", ((p_dm_odm->debug_components & ODM_COMP_PATH_DIV) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "12. (( %s ))DYNAMIC_PRICCA\n", ((p_dm_odm->debug_components & ODM_COMP_DYNAMIC_PRICCA) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "14. (( %s ))MP\n", ((p_dm_odm->debug_components & ODM_COMP_MP) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "15. (( %s ))struct _CFO_TRACKING_\n", ((p_dm_odm->debug_components & ODM_COMP_CFO_TRACKING) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "16. (( %s ))struct _ACS_\n", ((p_dm_odm->debug_components & ODM_COMP_ACS) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "17. (( %s ))ADAPTIVITY\n", ((p_dm_odm->debug_components & PHYDM_COMP_ADAPTIVITY) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "18. (( %s ))RA_DBG\n", ((p_dm_odm->debug_components & PHYDM_COMP_RA_DBG) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "19. (( %s ))TXBF\n", ((p_dm_odm->debug_components & PHYDM_COMP_TXBF) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "20. (( %s ))EDCA_TURBO\n", ((p_dm_odm->debug_components & ODM_COMP_EDCA_TURBO) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "22. (( %s ))FW_DEBUG_TRACE\n", ((p_dm_odm->debug_components & ODM_FW_DEBUG_TRACE) ? ("V") : ("."))));
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "24. (( %s ))TX_PWR_TRACK\n", ((p_dm_odm->debug_components & ODM_COMP_TX_PWR_TRACK) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "26. (( %s ))CALIBRATION\n", ((p_dm_odm->debug_components & ODM_COMP_CALIBRATION) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "28. (( %s ))PHY_CONFIG\n", ((p_dm_odm->debug_components & ODM_PHY_CONFIG) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "29. (( %s ))INIT\n", ((p_dm_odm->debug_components & ODM_COMP_INIT) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "30. (( %s ))COMMON\n", ((p_dm_odm->debug_components & ODM_COMP_COMMON) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "31. (( %s ))API\n", ((p_dm_odm->debug_components & ODM_COMP_API) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "================================"));
+
+ } else if (dm_value[0] == 101) {
+ p_dm_odm->debug_components = 0;
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "Disable all debug components"));
+ } else {
+ if (dm_value[1] == 1) /*enable*/
+ p_dm_odm->debug_components |= (one << dm_value[0]);
+ else if (dm_value[1] == 2) /*disable*/
+ p_dm_odm->debug_components &= ~(one << dm_value[0]);
+ else
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "[Warning!!!] 1:enable, 2:disable"));
+ }
+ PHYDM_SNPRINTF((output + used, out_len - used, "pre-DbgComponents = 0x%x\n", pre_debug_components));
+ PHYDM_SNPRINTF((output + used, out_len - used, "Curr-DbgComponents = 0x%x\n", p_dm_odm->debug_components));
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "================================"));
+}
+
+static void
+phydm_fw_debug_trace(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 pre_fw_debug_components, one = 1;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ pre_fw_debug_components = p_dm_odm->fw_debug_components;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\n%s\n", "================================"));
+ if (dm_value[0] == 100) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "[FW Debug Component]"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "================================"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "00. (( %s ))RA\n", ((p_dm_odm->fw_debug_components & PHYDM_FW_COMP_RA) ? ("V") : ("."))));
+
+ if (p_dm_odm->support_ic_type & PHYDM_IC_3081_SERIES) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "01. (( %s ))MU\n", ((p_dm_odm->fw_debug_components & PHYDM_FW_COMP_MU) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "02. (( %s ))path Div\n", ((p_dm_odm->fw_debug_components & PHYDM_FW_COMP_PHY_CONFIG) ? ("V") : ("."))));
+ PHYDM_SNPRINTF((output + used, out_len - used, "03. (( %s ))Phy Config\n", ((p_dm_odm->fw_debug_components & PHYDM_FW_COMP_PHY_CONFIG) ? ("V") : ("."))));
+ }
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "================================"));
+
+ } else {
+ if (dm_value[0] == 101) {
+ p_dm_odm->fw_debug_components = 0;
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "Clear all fw debug components"));
+ } else {
+ if (dm_value[1] == 1) /*enable*/
+ p_dm_odm->fw_debug_components |= (one << dm_value[0]);
+ else if (dm_value[1] == 2) /*disable*/
+ p_dm_odm->fw_debug_components &= ~(one << dm_value[0]);
+ else
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "[Warning!!!] 1:enable, 2:disable"));
+ }
+
+ if (p_dm_odm->fw_debug_components == 0) {
+ p_dm_odm->debug_components &= ~ODM_FW_DEBUG_TRACE;
+ phydm_fw_trace_en_h2c(p_dm_odm, false, p_dm_odm->fw_debug_components, dm_value[2], dm_value[3]); /*H2C to enable C2H Msg*/
+ } else {
+ p_dm_odm->debug_components |= ODM_FW_DEBUG_TRACE;
+ phydm_fw_trace_en_h2c(p_dm_odm, true, p_dm_odm->fw_debug_components, dm_value[2], dm_value[3]); /*H2C to enable C2H Msg*/
+ }
+ }
+}
+
+static void
+phydm_dump_bb_reg(
+ void *p_dm_void,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 addr = 0;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+
+ /* BB Reg, For Nseries IC we only need to dump page8 to pageF using 3 digits*/
+ for (addr = 0x800; addr < 0xfff; addr += 4) {
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "0x%03x 0x%08x\n", addr, odm_get_bb_reg(p_dm_odm, addr, MASKDWORD)));
+ else
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "0x%04x 0x%08x\n", addr, odm_get_bb_reg(p_dm_odm, addr, MASKDWORD)));
+ }
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8822B | ODM_RTL8814A | ODM_RTL8821C)) {
+
+ if (p_dm_odm->rf_type > ODM_2T2R) {
+ for (addr = 0x1800; addr < 0x18ff; addr += 4)
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "0x%04x 0x%08x\n", addr, odm_get_bb_reg(p_dm_odm, addr, MASKDWORD)));
+ }
+
+ if (p_dm_odm->rf_type > ODM_3T3R) {
+ for (addr = 0x1a00; addr < 0x1aff; addr += 4)
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "0x%04x 0x%08x\n", addr, odm_get_bb_reg(p_dm_odm, addr, MASKDWORD)));
+ }
+
+ for (addr = 0x1900; addr < 0x19ff; addr += 4)
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "0x%04x 0x%08x\n", addr, odm_get_bb_reg(p_dm_odm, addr, MASKDWORD)));
+
+ for (addr = 0x1c00; addr < 0x1cff; addr += 4)
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "0x%04x 0x%08x\n", addr, odm_get_bb_reg(p_dm_odm, addr, MASKDWORD)));
+
+ for (addr = 0x1f00; addr < 0x1fff; addr += 4)
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "0x%04x 0x%08x\n", addr, odm_get_bb_reg(p_dm_odm, addr, MASKDWORD)));
+ }
+}
+
+static void
+phydm_dump_all_reg(
+ void *p_dm_void,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 addr = 0;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ /* dump MAC register */
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "MAC==========\n"));
+ for (addr = 0; addr < 0x7ff; addr += 4)
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "0x%04x 0x%08x\n", addr, odm_get_bb_reg(p_dm_odm, addr, MASKDWORD)));
+
+ for (addr = 0x1000; addr < 0x17ff; addr += 4)
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "0x%04x 0x%08x\n", addr, odm_get_bb_reg(p_dm_odm, addr, MASKDWORD)));
+
+ /* dump BB register */
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "BB==========\n"));
+ phydm_dump_bb_reg(p_dm_odm, &used, output, &out_len);
+
+ /* dump RF register */
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "RF-A==========\n"));
+ for (addr = 0; addr < 0xFF; addr++)
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "0x%02x 0x%05x\n", addr, odm_get_rf_reg(p_dm_odm, ODM_RF_PATH_A, addr, RFREGOFFSETMASK)));
+
+ if (p_dm_odm->rf_type > ODM_1T1R) {
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "RF-B==========\n"));
+ for (addr = 0; addr < 0xFF; addr++)
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "0x%02x 0x%05x\n", addr, odm_get_rf_reg(p_dm_odm, ODM_RF_PATH_B, addr, RFREGOFFSETMASK)));
+ }
+
+ if (p_dm_odm->rf_type > ODM_2T2R) {
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "RF-C==========\n"));
+ for (addr = 0; addr < 0xFF; addr++)
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "0x%02x 0x%05x\n", addr, odm_get_rf_reg(p_dm_odm, ODM_RF_PATH_C, addr, RFREGOFFSETMASK)));
+ }
+
+ if (p_dm_odm->rf_type > ODM_3T3R) {
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "RF-D==========\n"));
+ for (addr = 0; addr < 0xFF; addr++)
+ PHYDM_VAST_INFO_SNPRINTF((output + used, out_len - used, "0x%02x 0x%05x\n", addr, odm_get_rf_reg(p_dm_odm, ODM_RF_PATH_D, addr, RFREGOFFSETMASK)));
+ }
+}
+
+static void
+phydm_enable_big_jump(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ bool state
+)
+{
+}
+
+struct _PHYDM_COMMAND {
+ char name[16];
+ u8 id;
+};
+
+enum PHYDM_CMD_ID {
+ PHYDM_HELP,
+ PHYDM_DEMO,
+ PHYDM_RA,
+ PHYDM_PROFILE,
+ PHYDM_ANTDIV,
+ PHYDM_PATHDIV,
+ PHYDM_DEBUG,
+ PHYDM_FW_DEBUG,
+ PHYDM_SUPPORT_ABILITY,
+ PHYDM_GET_TXAGC,
+ PHYDM_SET_TXAGC,
+ PHYDM_SMART_ANT,
+ PHYDM_API,
+ PHYDM_TRX_PATH,
+ PHYDM_LA_MODE,
+ PHYDM_DUMP_REG,
+ PHYDM_MU_MIMO,
+ PHYDM_HANG,
+ PHYDM_BIG_JUMP,
+ PHYDM_SHOW_RXRATE,
+ PHYDM_NBI_EN,
+ PHYDM_CSI_MASK_EN,
+ PHYDM_DFS,
+ PHYDM_IQK,
+ PHYDM_NHM,
+ PHYDM_CLM,
+ PHYDM_BB_INFO,
+ PHYDM_TXBF,
+ PHYDM_PAUSE_DIG_EN,
+ PHYDM_H2C,
+ PHYDM_ANT_SWITCH,
+ PHYDM_DYNAMIC_RA_PATH
+};
+
+static struct _PHYDM_COMMAND phy_dm_ary[] = {
+ {"-h", PHYDM_HELP}, /*do not move this element to other position*/
+ {"demo", PHYDM_DEMO}, /*do not move this element to other position*/
+ {"ra", PHYDM_RA},
+ {"profile", PHYDM_PROFILE},
+ {"antdiv", PHYDM_ANTDIV},
+ {"pathdiv", PHYDM_PATHDIV},
+ {"dbg", PHYDM_DEBUG},
+ {"fw_dbg", PHYDM_FW_DEBUG},
+ {"ability", PHYDM_SUPPORT_ABILITY},
+ {"get_txagc", PHYDM_GET_TXAGC},
+ {"set_txagc", PHYDM_SET_TXAGC},
+ {"smtant", PHYDM_SMART_ANT},
+ {"api", PHYDM_API},
+ {"trxpath", PHYDM_TRX_PATH},
+ {"lamode", PHYDM_LA_MODE},
+ {"dumpreg", PHYDM_DUMP_REG},
+ {"mu", PHYDM_MU_MIMO},
+ {"hang", PHYDM_HANG},
+ {"bigjump", PHYDM_BIG_JUMP},
+ {"rxrate", PHYDM_SHOW_RXRATE},
+ {"nbi", PHYDM_NBI_EN},
+ {"csi_mask", PHYDM_CSI_MASK_EN},
+ {"dfs", PHYDM_DFS},
+ {"iqk", PHYDM_IQK},
+ {"nhm", PHYDM_NHM},
+ {"clm", PHYDM_CLM},
+ {"bbinfo", PHYDM_BB_INFO},
+ {"txbf", PHYDM_TXBF},
+ {"pause_dig", PHYDM_PAUSE_DIG_EN},
+ {"h2c", PHYDM_H2C},
+ {"ant_switch", PHYDM_ANT_SWITCH},
+ {"drp", PHYDM_DYNAMIC_RA_PATH}
+};
+
+#endif /*#if CONFIG_PHYDM_DEBUG_FUNCTION*/
+
+void
+phydm_cmd_parser(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ char input[][MAX_ARGV],
+ u32 input_num,
+ u8 flag,
+ char *output,
+ u32 out_len
+)
+{
+#if CONFIG_PHYDM_DEBUG_FUNCTION
+ u32 used = 0;
+ u8 id = 0;
+ int var1[10] = {0};
+ int i, input_idx = 0, phydm_ary_size;
+ char help[] = "-h";
+
+ if (flag == 0) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "GET, nothing to print\n"));
+ return;
+ }
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\n"));
+
+ /* Parsing Cmd ID */
+ if (input_num) {
+
+ phydm_ary_size = sizeof(phy_dm_ary) / sizeof(struct _PHYDM_COMMAND);
+ for (i = 0; i < phydm_ary_size; i++) {
+ if (strcmp(phy_dm_ary[i].name, input[0]) == 0) {
+ id = phy_dm_ary[i].id;
+ break;
+ }
+ }
+ if (i == phydm_ary_size) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "SET, command not found!\n"));
+ return;
+ }
+ }
+
+ switch (id) {
+
+ case PHYDM_HELP:
+ {
+ PHYDM_SNPRINTF((output + used, out_len - used, "BB cmd ==>\n"));
+ for (i = 0; i < phydm_ary_size - 2; i++) {
+
+ PHYDM_SNPRINTF((output + used, out_len - used, " %-5d: %s\n", i, phy_dm_ary[i + 2].name));
+ /**/
+ }
+ }
+ break;
+
+ case PHYDM_DEMO: { /*echo demo 10 0x3a z abcde >cmd*/
+ u32 directory = 0;
+ char char_temp;
+
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &directory);
+ PHYDM_SNPRINTF((output + used, out_len - used, "Decimal value = %d\n", directory));
+ PHYDM_SSCANF(input[2], DCMD_HEX, &directory);
+ PHYDM_SNPRINTF((output + used, out_len - used, "Hex value = 0x%x\n", directory));
+ PHYDM_SSCANF(input[3], DCMD_CHAR, &char_temp);
+ PHYDM_SNPRINTF((output + used, out_len - used, "Char = %c\n", char_temp));
+ PHYDM_SNPRINTF((output + used, out_len - used, "String = %s\n", input[4]));
+ }
+ break;
+
+ case PHYDM_RA:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);
+
+ /*PHYDM_SNPRINTF((output + used, out_len - used, "new SET, RA_var[%d]= (( %d ))\n", i, var1[i]));*/
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+ /*PHYDM_SNPRINTF((output+used, out_len-used, "odm_RA_debug\n"));*/
+#if (defined(CONFIG_RA_DBG_CMD))
+ odm_RA_debug((void *)p_dm_odm, (u32 *) var1);
+#else
+ phydm_RA_debug_PCR(p_dm_odm, (u32 *)var1, &used, output, &out_len);
+#endif
+ }
+
+
+ break;
+
+ case PHYDM_ANTDIV:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]);
+
+ /*PHYDM_SNPRINTF((output+used, out_len-used, "new SET, PATHDIV_var[%d]= (( %d ))\n", i, var1[i]));*/
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+ /*PHYDM_SNPRINTF((output+used, out_len-used, "odm_PATHDIV_debug\n"));*/
+#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))
+ phydm_antdiv_debug(p_dm_odm, (u32 *)var1, &used, output, &out_len);
+#endif
+ }
+
+ break;
+
+ case PHYDM_PATHDIV:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]);
+
+ /*PHYDM_SNPRINTF((output+used, out_len-used, "new SET, PATHDIV_var[%d]= (( %d ))\n", i, var1[i]));*/
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+ /*PHYDM_SNPRINTF((output+used, out_len-used, "odm_PATHDIV_debug\n"));*/
+#if (defined(CONFIG_PATH_DIVERSITY))
+ odm_pathdiv_debug(p_dm_odm, (u32 *)var1, &used, output, &out_len);
+#endif
+ }
+
+ break;
+
+ case PHYDM_DEBUG:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);
+
+ /*PHYDM_SNPRINTF((output+used, out_len-used, "new SET, Debug_var[%d]= (( %d ))\n", i, var1[i]));*/
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+ /*PHYDM_SNPRINTF((output+used, out_len-used, "odm_debug_comp\n"));*/
+ phydm_debug_trace(p_dm_odm, (u32 *)var1, &used, output, &out_len);
+ }
+
+
+ break;
+
+ case PHYDM_FW_DEBUG:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1)
+ phydm_fw_debug_trace(p_dm_odm, (u32 *)var1, &used, output, &out_len);
+
+ break;
+
+ case PHYDM_SUPPORT_ABILITY:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);
+
+ /*PHYDM_SNPRINTF((output+used, out_len-used, "new SET, support ablity_var[%d]= (( %d ))\n", i, var1[i]));*/
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+ /*PHYDM_SNPRINTF((output+used, out_len-used, "support ablity\n"));*/
+ phydm_support_ability_debug(p_dm_odm, (u32 *)var1, &used, output, &out_len);
+ }
+
+ break;
+
+ case PHYDM_SMART_ANT:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))
+#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1
+ phydm_hl_smart_ant_debug(p_dm_odm, (u32 *)var1, &used, output, &out_len);
+#endif
+#endif
+ }
+
+ break;
+
+ case PHYDM_API:
+ PHYDM_SNPRINTF((output + used, out_len - used, "This IC doesn't support PHYDM API function\n"));
+ break;
+ case PHYDM_PROFILE: /*echo profile, >cmd*/
+ phydm_basic_profile(p_dm_odm, &used, output, &out_len);
+ break;
+ case PHYDM_GET_TXAGC:
+ phydm_get_txagc(p_dm_odm, &used, output, &out_len);
+ break;
+ case PHYDM_SET_TXAGC:
+ {
+ bool is_enable_dbg_mode;
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if ((strcmp(input[1], help) == 0)) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "{En} {pathA~D(0~3)} {rate_idx(Hex), All_rate:0xff} {txagc_idx (Hex)}\n"));
+ /**/
+
+ } else {
+
+ is_enable_dbg_mode = (bool)var1[0];
+ if (is_enable_dbg_mode) {
+ p_dm_odm->is_disable_phy_api = false;
+ phydm_set_txagc(p_dm_odm, (u32 *)var1, &used, output, &out_len);
+ p_dm_odm->is_disable_phy_api = true;
+ } else {
+ p_dm_odm->is_disable_phy_api = false;
+ PHYDM_SNPRINTF((output + used, out_len - used, "Disable API debug mode\n"));
+ }
+ }
+ }
+ break;
+
+ case PHYDM_TRX_PATH:
+
+ for (i = 0; i < 4; i++) {
+ if (input[i + 1])
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);
+ }
+ phydm_config_trx_path(p_dm_odm, (u32 *)var1, &used, output, &out_len);
+ break;
+
+ case PHYDM_LA_MODE:
+
+#if (PHYDM_LA_MODE_SUPPORT == 1)
+ p_dm_odm->support_ability &= ~(ODM_BB_FA_CNT);
+ phydm_lamode_trigger_setting(p_dm_odm, &input[0], &used, output, &out_len, input_num);
+ p_dm_odm->support_ability |= ODM_BB_FA_CNT;
+#else
+ PHYDM_SNPRINTF((output + used, out_len - used, "This IC doesn't support LA mode\n"));
+#endif
+
+ break;
+
+ case PHYDM_DUMP_REG:
+ {
+ u8 type = 0;
+
+ if (input[1]) {
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+ type = (u8)var1[0];
+ }
+
+ if (type == 0)
+ phydm_dump_bb_reg(p_dm_odm, &used, output, &out_len);
+ else if (type == 1)
+ phydm_dump_all_reg(p_dm_odm, &used, output, &out_len);
+ }
+ break;
+
+ case PHYDM_MU_MIMO:
+ break;
+ case PHYDM_BIG_JUMP:
+ PHYDM_SNPRINTF((output + used, out_len - used, "The command is only for 8822B!\n"));
+ break;
+ case PHYDM_HANG:
+ phydm_bb_rx_hang_info(p_dm_odm, &used, output, &out_len);
+ break;
+ case PHYDM_SHOW_RXRATE:
+ break;
+ case PHYDM_NBI_EN:
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+
+ phydm_api_debug(p_dm_odm, PHYDM_API_NBI, (u32 *)var1, &used, output, &out_len);
+ /**/
+ }
+
+
+ break;
+
+ case PHYDM_CSI_MASK_EN:
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+
+ phydm_api_debug(p_dm_odm, PHYDM_API_CSI_MASK, (u32 *)var1, &used, output, &out_len);
+ /**/
+ }
+
+
+ break;
+
+ case PHYDM_DFS:
+ {
+ u32 var[6] = {0};
+
+ for (i = 0; i < 6; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1)
+ phydm_dfs_debug(p_dm_odm, var, &used, output, &out_len);
+ }
+ break;
+ case PHYDM_IQK:
+ break;
+ case PHYDM_NHM:
+ {
+ u8 target_rssi;
+ u32 value32;
+ u16 nhm_period = 0xC350; /* 200ms */
+ u8 IGI;
+ struct _CCX_INFO *ccx_info = &p_dm_odm->dm_ccx_info;
+
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+
+ if (input_num == 1) {
+
+ ccx_info->echo_NHM_en = false;
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n Trigger NHM: echo nhm 1\n"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r (Exclude CCA)\n"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r Trigger NHM: echo nhm 2\n"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r (Include CCA)\n"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r Get NHM results: echo nhm 3\n"));
+
+ return;
+ }
+
+ /* NMH trigger */
+ if ((var1[0] <= 2) && (var1[0] != 0)) {
+
+ ccx_info->echo_NHM_en = true;
+ ccx_info->echo_IGI = (u8)odm_get_bb_reg(p_dm_odm, 0xC50, MASKBYTE0);
+
+ target_rssi = ccx_info->echo_IGI - 10;
+
+ ccx_info->NHM_th[0] = (target_rssi - 15 + 10) * 2;
+
+ for (i = 1; i <= 10; i++)
+ ccx_info->NHM_th[i] = ccx_info->NHM_th[0] + 6 * i;
+
+ /* 4 1. store previous NHM setting */
+ phydm_nhm_setting(p_dm_odm, STORE_NHM_SETTING);
+
+ /* 4 2. Set NHM period, 0x990[31:16]=0xC350, Time duration for NHM unit: 4us, 0xC350=200ms */
+ ccx_info->NHM_period = nhm_period;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n Monitor NHM for %d us", nhm_period * 4));
+
+ /* 4 3. Set NHM inexclude_txon, inexclude_cca, ccx_en */
+
+
+ ccx_info->nhm_inexclude_cca = (var1[0] == 1) ? NHM_EXCLUDE_CCA : NHM_INCLUDE_CCA;
+ ccx_info->nhm_inexclude_txon = NHM_EXCLUDE_TXON;
+
+ phydm_nhm_setting(p_dm_odm, SET_NHM_SETTING);
+
+ for (i = 0; i <= 10; i++) {
+
+ if (i == 5)
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n NHM_th[%d] = 0x%x, echo_IGI = 0x%x", i, ccx_info->NHM_th[i], ccx_info->echo_IGI));
+ else if (i == 10)
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n NHM_th[%d] = 0x%x\n", i, ccx_info->NHM_th[i]));
+ else
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n NHM_th[%d] = 0x%x", i, ccx_info->NHM_th[i]));
+ }
+
+ /* 4 4. Trigger NHM */
+ phydm_nhm_trigger(p_dm_odm);
+
+ }
+
+ /*Get NHM results*/
+ else if (var1[0] == 3) {
+
+ IGI = (u8)odm_get_bb_reg(p_dm_odm, 0xC50, MASKBYTE0);
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n Cur_IGI = 0x%x", IGI));
+
+ phydm_get_nhm_result(p_dm_odm);
+
+ /* 4 Resotre NHM setting */
+ phydm_nhm_setting(p_dm_odm, RESTORE_NHM_SETTING);
+
+ for (i = 0; i <= 11; i++) {
+
+ if (i == 5)
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n nhm_result[%d] = %d, echo_IGI = 0x%x", i, ccx_info->NHM_result[i], ccx_info->echo_IGI));
+ else if (i == 11)
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n nhm_result[%d] = %d\n", i, ccx_info->NHM_result[i]));
+ else
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n nhm_result[%d] = %d", i, ccx_info->NHM_result[i]));
+ }
+
+ ccx_info->echo_NHM_en = false;
+ } else {
+
+ ccx_info->echo_NHM_en = false;
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n Trigger NHM: echo nhm 1\n"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r (Exclude CCA)\n"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r Trigger NHM: echo nhm 2\n"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r (Include CCA)\n"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r Get NHM results: echo nhm 3\n"));
+
+ return;
+ }
+ }
+ break;
+
+ case PHYDM_CLM:
+ {
+ struct _CCX_INFO *ccx_info = &p_dm_odm->dm_ccx_info;
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+
+ /* PHYDM_SNPRINTF((output + used, out_len - used, "\r\n input_num = %d\n", input_num)); */
+
+ if (input_num == 1) {
+
+ ccx_info->echo_CLM_en = false;
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n Trigger CLM: echo clm 1\n"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r Get CLM results: echo clm 2\n"));
+ return;
+ }
+
+ /* Set & trigger CLM */
+ if (var1[0] == 1) {
+
+ ccx_info->echo_CLM_en = true;
+ ccx_info->CLM_period = 0xC350; /*100ms*/
+ phydm_clm_setting(p_dm_odm);
+ phydm_clm_trigger(p_dm_odm);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n Monitor CLM for 200ms\n"));
+ }
+
+ /* Get CLM results */
+ else if (var1[0] == 2) {
+
+ ccx_info->echo_CLM_en = false;
+ phydm_get_cl_mresult(p_dm_odm);
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n CLM_result = %d us\n", ccx_info->CLM_result * 4));
+
+ } else {
+
+ ccx_info->echo_CLM_en = false;
+ PHYDM_SNPRINTF((output + used, out_len - used, "\n\r Error command !\n"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r Trigger CLM: echo clm 1\n"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r Get CLM results: echo clm 2\n"));
+ }
+ }
+ break;
+
+ case PHYDM_BB_INFO:
+ {
+ s32 value32 = 0;
+
+ phydm_bb_debug_info(p_dm_odm, &used, output, &out_len);
+
+ if (p_dm_odm->support_ic_type & ODM_RTL8822B && input[1]) {
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+ odm_set_bb_reg(p_dm_odm, 0x1988, 0x003fff00, var1[0]);
+ value32 = odm_get_bb_reg(p_dm_odm, 0xf84, MASKDWORD);
+ value32 = (value32 & 0xff000000) >> 24;
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n %-35s = condition num = %d, subcarriers = %d\n", "Over condition num subcarrier", var1[0], value32));
+ odm_set_bb_reg(p_dm_odm, 0x1988, BIT(22), 0x0); /*disable report condition number*/
+ }
+ }
+ break;
+
+ case PHYDM_TXBF:
+ {
+#if (BEAMFORMING_SUPPORT == 1)
+ struct _RT_BEAMFORMING_INFO *p_beamforming_info = &p_dm_odm->beamforming_info;
+
+ PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
+ if (var1[0] == 1) {
+ p_beamforming_info->apply_v_matrix = true;
+ p_beamforming_info->snding3ss = false;
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n apply V matrix and 3SS 789 dont snding\n"));
+ } else if (var1[0] == 0) {
+ p_beamforming_info->apply_v_matrix = false;
+ p_beamforming_info->snding3ss = true;
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n dont apply V matrix and 3SS 789 snding\n"));
+ } else
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n unknown cmd!!\n"));
+#else
+ PHYDM_SNPRINTF((output + used, out_len - used, "\r\n no TxBF !!\n"));
+#endif
+ }
+ break;
+
+ case PHYDM_PAUSE_DIG_EN:
+
+
+ for (i = 0; i < 5; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+ if (var1[0] == 0) {
+ odm_pause_dig(p_dm_odm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_7, (u8)var1[1]);
+ PHYDM_SNPRINTF((output + used, out_len - used, "Set IGI_value = ((%x))\n", var1[1]));
+ } else if (var1[0] == 1) {
+ odm_pause_dig(p_dm_odm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_7, (u8)var1[1]);
+ PHYDM_SNPRINTF((output + used, out_len - used, "Resume IGI_value\n"));
+ } else
+ PHYDM_SNPRINTF((output + used, out_len - used, "echo (1:pause, 2resume) (IGI_value)\n"));
+ }
+
+ break;
+
+ case PHYDM_H2C:
+
+ for (i = 0; i < 8; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1)
+ phydm_h2C_debug(p_dm_odm, (u32 *)var1, &used, output, &out_len);
+
+
+ break;
+
+ case PHYDM_ANT_SWITCH:
+
+ for (i = 0; i < 8; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1) {
+
+#if (RTL8821A_SUPPORT == 1)
+ phydm_set_ext_switch(p_dm_odm, (u32 *)var1, &used, output, &out_len);
+#else
+ PHYDM_SNPRINTF((output + used, out_len - used, "Not Support IC"));
+#endif
+ }
+
+
+ break;
+
+ case PHYDM_DYNAMIC_RA_PATH:
+
+#if (CONFIG_DYNAMIC_RX_PATH == 1)
+ for (i = 0; i < 8; i++) {
+ if (input[i + 1]) {
+ PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]);
+ input_idx++;
+ }
+ }
+
+ if (input_idx >= 1)
+ phydm_drp_debug(p_dm_odm, (u32 *)var1, &used, output, &out_len);
+
+#else
+ PHYDM_SNPRINTF((output + used, out_len - used, "Not Support IC"));
+#endif
+
+ break;
+
+ default:
+ PHYDM_SNPRINTF((output + used, out_len - used, "SET, unknown command!\n"));
+ break;
+
+ }
+#endif /*#if CONFIG_PHYDM_DEBUG_FUNCTION*/
+}
+
+#ifdef __ECOS
+char *strsep(char **s, const char *ct)
+{
+ char *sbegin = *s;
+ char *end;
+
+ if (sbegin == NULL)
+ return NULL;
+
+ end = strpbrk(sbegin, ct);
+ if (end)
+ *end++ = '\0';
+ *s = end;
+ return sbegin;
+}
+#endif
+
+s32
+phydm_cmd(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ char *input,
+ u32 in_len,
+ u8 flag,
+ char *output,
+ u32 out_len
+)
+{
+ char *token;
+ u32 argc = 0;
+ char argv[MAX_ARGC][MAX_ARGV];
+
+ do {
+ token = strsep(&input, ", ");
+ if (token) {
+ strcpy(argv[argc], token);
+ argc++;
+ } else
+ break;
+ } while (argc < MAX_ARGC);
+
+ if (argc == 1)
+ argv[0][strlen(argv[0]) - 1] = '\0';
+
+ phydm_cmd_parser(p_dm_odm, argv, argc, flag, output, out_len);
+
+ return 0;
+}
+
+void
+phydm_fw_trace_handler(
+ void *p_dm_void,
+ u8 *cmd_buf,
+ u8 cmd_len
+)
+{
+#if CONFIG_PHYDM_DEBUG_FUNCTION
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ /*u8 debug_trace_11byte[60];*/
+ u8 freg_num, c2h_seq, buf_0 = 0;
+
+ if (!(p_dm_odm->support_ic_type & PHYDM_IC_3081_SERIES))
+ return;
+
+ if (cmd_len > 12)
+ return;
+
+ buf_0 = cmd_buf[0];
+ freg_num = (buf_0 & 0xf);
+ c2h_seq = (buf_0 & 0xf0) >> 4;
+ /*ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW debug message] freg_num = (( %d )), c2h_seq = (( %d ))\n", freg_num,c2h_seq ));*/
+
+ /*strncpy(debug_trace_11byte,&cmd_buf[1],(cmd_len-1));*/
+ /*debug_trace_11byte[cmd_len-1] = '\0';*/
+ /*ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW debug message] %s\n", debug_trace_11byte));*/
+ /*ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW debug message] cmd_len = (( %d ))\n", cmd_len));*/
+ /*ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW debug message] c2h_cmd_start = (( %d ))\n", p_dm_odm->c2h_cmd_start));*/
+
+
+
+ /*ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("pre_seq = (( %d )), current_seq = (( %d ))\n", p_dm_odm->pre_c2h_seq, c2h_seq));*/
+ /*ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("fw_buff_is_enpty = (( %d ))\n", p_dm_odm->fw_buff_is_enpty));*/
+
+ if ((c2h_seq != p_dm_odm->pre_c2h_seq) && p_dm_odm->fw_buff_is_enpty == false) {
+ p_dm_odm->fw_debug_trace[p_dm_odm->c2h_cmd_start] = '\0';
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW Dbg Queue Overflow] %s\n", p_dm_odm->fw_debug_trace));
+ p_dm_odm->c2h_cmd_start = 0;
+ }
+
+ if ((cmd_len - 1) > (60 - p_dm_odm->c2h_cmd_start)) {
+ p_dm_odm->fw_debug_trace[p_dm_odm->c2h_cmd_start] = '\0';
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW Dbg Queue error: wrong C2H length] %s\n", p_dm_odm->fw_debug_trace));
+ p_dm_odm->c2h_cmd_start = 0;
+ return;
+ }
+
+ strncpy((char *)&(p_dm_odm->fw_debug_trace[p_dm_odm->c2h_cmd_start]), (char *)&cmd_buf[1], (cmd_len - 1));
+ p_dm_odm->c2h_cmd_start += (cmd_len - 1);
+ p_dm_odm->fw_buff_is_enpty = false;
+
+ if (freg_num == 0 || p_dm_odm->c2h_cmd_start >= 60) {
+ if (p_dm_odm->c2h_cmd_start < 60)
+ p_dm_odm->fw_debug_trace[p_dm_odm->c2h_cmd_start] = '\0';
+ else
+ p_dm_odm->fw_debug_trace[59] = '\0';
+
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW DBG Msg] %s\n", p_dm_odm->fw_debug_trace));
+ /*dbg_print("[FW DBG Msg] %s\n", p_dm_odm->fw_debug_trace);*/
+ p_dm_odm->c2h_cmd_start = 0;
+ p_dm_odm->fw_buff_is_enpty = true;
+ }
+
+ p_dm_odm->pre_c2h_seq = c2h_seq;
+#endif /*#if CONFIG_PHYDM_DEBUG_FUNCTION*/
+}
+
+void
+phydm_fw_trace_handler_code(
+ void *p_dm_void,
+ u8 *buffer,
+ u8 cmd_len
+)
+{
+#if CONFIG_PHYDM_DEBUG_FUNCTION
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 function = buffer[0];
+ u8 dbg_num = buffer[1];
+ u16 content_0 = (((u16)buffer[3]) << 8) | ((u16)buffer[2]);
+ u16 content_1 = (((u16)buffer[5]) << 8) | ((u16)buffer[4]);
+ u16 content_2 = (((u16)buffer[7]) << 8) | ((u16)buffer[6]);
+ u16 content_3 = (((u16)buffer[9]) << 8) | ((u16)buffer[8]);
+ u16 content_4 = (((u16)buffer[11]) << 8) | ((u16)buffer[10]);
+
+ if (cmd_len > 12)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW Msg] Invalid cmd length (( %d )) >12\n", cmd_len));
+
+ /* ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW Msg] Func=((%d)), num=((%d)), ct_0=((%d)), ct_1=((%d)), ct_2=((%d)), ct_3=((%d)), ct_4=((%d))\n", */
+ /* function, dbg_num, content_0, content_1, content_2, content_3, content_4)); */
+
+ /*--------------------------------------------*/
+#if (CONFIG_RA_FW_DBG_CODE)
+ if (function == RATE_DECISION) {
+ if (dbg_num == 0) {
+ if (content_0 == 1)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] RA_CNT=((%d)) Max_device=((%d))--------------------------->\n", content_1, content_2));
+ else if (content_0 == 2)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] Check RA macid= ((%d)), MediaStatus=((%d)), Dis_RA=((%d)), try_bit=((0x%x))\n", content_1, content_2, content_3, content_4));
+ else if (content_0 == 3)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] Check RA total=((%d)), drop=((0x%x)), TXRPT_TRY_bit=((%x)), bNoisy=((%x))\n", content_1, content_2, content_3, content_4));
+ } else if (dbg_num == 1) {
+ if (content_0 == 1)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] RTY[0,1,2,3]=[ %d , %d , %d , %d ]\n", content_1, content_2, content_3, content_4));
+ else if (content_0 == 2) {
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] RTY[4]=[ %d ], drop=(( %d )), total=(( %d )), current_rate=((0x %x ))", content_1, content_2, content_3, content_4));
+ phydm_print_rate(p_dm_odm, (u8)content_4, ODM_FW_DEBUG_TRACE);
+ } else if (content_0 == 3)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] penality_idx=(( %d ))\n", content_1));
+ else if (content_0 == 4)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] RSSI=(( %d )), ra_stage = (( %d ))\n", content_1, content_2));
+ }
+
+ else if (dbg_num == 3) {
+ if (content_0 == 1)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] Fast_RA (( DOWN )) total=((%d)), total>>1=((%d)), R4+R3+R2 = ((%d)), RateDownHold = ((%d))\n", content_1, content_2, content_3, content_4));
+ else if (content_0 == 2)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] Fast_RA (( UP )) total_acc=((%d)), total_acc>>1=((%d)), R4+R3+R2 = ((%d)), RateDownHold = ((%d))\n", content_1, content_2, content_3, content_4));
+ else if (content_0 == 3)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] Fast_RA (( UP )) ((rate Down Hold)) RA_CNT=((%d))\n", content_1));
+ else if (content_0 == 4)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] Fast_RA (( UP )) ((tota_accl<5 skip)) RA_CNT=((%d))\n", content_1));
+ else if (content_0 == 8)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] Fast_RA (( Reset Tx Rpt )) RA_CNT=((%d))\n", content_1));
+ }
+
+ else if (dbg_num == 4) {
+ if (content_0 == 3) {
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] RER_CNT PCR_ori =(( %d )), ratio_ori =(( %d )), pcr_updown_bitmap =(( 0x%x )), pcr_var_diff =(( %d ))\n", content_1, content_2, content_3, content_4));
+ /**/
+ } else if (content_0 == 4) {
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] pcr_shift_value =(( %s%d )), rate_down_threshold =(( %d )), rate_up_threshold =(( %d ))\n", ((content_1) ? "+" : "-"), content_2, content_3, content_4));
+ /**/
+ } else if (content_0 == 5) {
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] pcr_mean =(( %d )), PCR_VAR =(( %d )), offset =(( %d )), decision_offset_p =(( %d ))\n", content_1, content_2, content_3, content_4));
+ /**/
+ }
+ }
+
+ else if (dbg_num == 5) {
+ if (content_0 == 1)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] (( UP)) Nsc=(( %d )), N_High=(( %d )), RateUp_Waiting=(( %d )), RateUp_Fail=(( %d ))\n", content_1, content_2, content_3, content_4));
+ else if (content_0 == 2)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] ((DOWN)) Nsc=(( %d )), N_Low=(( %d ))\n", content_1, content_2));
+ else if (content_0 == 3)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] ((HOLD)) Nsc=((%d)), N_High=((%d)), N_Low=((%d)), Reset_CNT=((%d))\n", content_1, content_2, content_3, content_4));
+ } else if (dbg_num == 0x60) {
+ if (content_0 == 1)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] ((AP RPT)) macid=((%d)), BUPDATE[macid]=((%d))\n", content_1, content_2));
+ else if (content_0 == 4)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] ((AP RPT)) pass=((%d)), rty_num=((%d)), drop=((%d)), total=((%d))\n", content_1, content_2, content_3, content_4));
+ else if (content_0 == 5)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW] ((AP RPT)) PASS=((%d)), RTY_NUM=((%d)), DROP=((%d)), TOTAL=((%d))\n", content_1, content_2, content_3, content_4));
+ }
+ }
+ /*--------------------------------------------*/
+ else if (function == INIT_RA_TABLE) {
+ if (dbg_num == 3)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][INIT_RA_INFO] Ra_init, RA_SKIP_CNT = (( %d ))\n", content_0));
+
+ }
+ /*--------------------------------------------*/
+ else if (function == RATE_UP) {
+ if (dbg_num == 2) {
+ if (content_0 == 1)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][RateUp] ((Highest rate->return)), macid=((%d)) Nsc=((%d))\n", content_1, content_2));
+ } else if (dbg_num == 5) {
+ if (content_0 == 0)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][RateUp] ((rate UP)), up_rate_tmp=((0x%x)), rate_idx=((0x%x)), SGI_en=((%d)), SGI=((%d))\n", content_1, content_2, content_3, content_4));
+ else if (content_0 == 1)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][RateUp] ((rate UP)), rate_1=((0x%x)), rate_2=((0x%x)), BW=((%d)), Try_Bit=((%d))\n", content_1, content_2, content_3, content_4));
+ }
+
+ }
+ /*--------------------------------------------*/
+ else if (function == RATE_DOWN) {
+ if (dbg_num == 5) {
+ if (content_0 == 1)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][RateDownStep] ((rate Down)), macid=((%d)), rate1=((0x%x)), rate2=((0x%x)), BW=((%d))\n", content_1, content_2, content_3, content_4));
+ }
+ } else if (function == TRY_DONE) {
+ if (dbg_num == 1) {
+ if (content_0 == 1) {
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][Try Done] ((try succsess )) macid=((%d)), Try_Done_cnt=((%d))\n", content_1, content_2));
+ /**/
+ }
+ } else if (dbg_num == 2) {
+ if (content_0 == 1) {
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][Try Done] ((try)) macid=((%d)), Try_Done_cnt=((%d)), rate_2=((%d)), try_succes=((%d))\n", content_1, content_2, content_3, content_4));
+ /**/
+ }
+ }
+ }
+ /*--------------------------------------------*/
+ else if (function == RA_H2C) {
+ if (dbg_num == 1) {
+ if (content_0 == 0) {
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][H2C=0x49] fw_trace_en=((%d)), mode =((%d)), macid=((%d))\n", content_1, content_2, content_3));
+ /**/
+ /*C2H_RA_Dbg_code(F_RA_H2C,1,0, SysMib.ODM.DEBUG.fw_trace_en, mode, macid, 0); //RA MASK*/
+ }
+ }
+ }
+ /*--------------------------------------------*/
+ else if (function == F_RATE_AP_RPT) {
+ if (dbg_num == 1) {
+ if (content_0 == 1)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][AP RPT] ((1)), SPE_STATIS=((0x%x))---------->\n", content_3));
+ } else if (dbg_num == 2) {
+ if (content_0 == 1)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][AP RPT] RTY_all=((%d))\n", content_1));
+ } else if (dbg_num == 3) {
+ if (content_0 == 1)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][AP RPT] MACID1[%d], TOTAL=((%d)), RTY=((%d))\n", content_3, content_1, content_2));
+ } else if (dbg_num == 4) {
+ if (content_0 == 1)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][AP RPT] MACID2[%d], TOTAL=((%d)), RTY=((%d))\n", content_3, content_1, content_2));
+ } else if (dbg_num == 5) {
+ if (content_0 == 1)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][AP RPT] MACID1[%d], PASS=((%d)), DROP=((%d))\n", content_3, content_1, content_2));
+ } else if (dbg_num == 6) {
+ if (content_0 == 1)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][AP RPT] MACID2[%d],, PASS=((%d)), DROP=((%d))\n", content_3, content_1, content_2));
+ }
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][general][%d, %d, %d] = {%d, %d, %d, %d}\n", function, dbg_num, content_0, content_1, content_2, content_3, content_4));
+ /**/
+ }
+#else
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][general][%d, %d, %d] = {%d, %d, %d, %d}\n", function, dbg_num, content_0, content_1, content_2, content_3, content_4));
+#endif
+ /*--------------------------------------------*/
+
+#endif /*#if CONFIG_PHYDM_DEBUG_FUNCTION*/
+}
+
+void
+phydm_fw_trace_handler_8051(
+ void *p_dm_void,
+ u8 *buffer,
+ u8 cmd_len
+)
+{
+#if CONFIG_PHYDM_DEBUG_FUNCTION
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ int i = 0;
+ u8 extend_c2h_sub_id = 0, extend_c2h_dbg_len = 0, extend_c2h_dbg_seq = 0;
+ u8 fw_debug_trace[128];
+ u8 *extend_c2h_dbg_content = NULL;
+
+ if (cmd_len > 127)
+ return;
+
+ extend_c2h_sub_id = buffer[0];
+ extend_c2h_dbg_len = buffer[1];
+ extend_c2h_dbg_content = buffer + 2; /*DbgSeq+DbgContent for show HEX*/
+
+go_backfor_aggre_dbg_pkt:
+ i = 0;
+ extend_c2h_dbg_seq = buffer[2];
+ extend_c2h_dbg_content = buffer + 3;
+
+ for (; ; i++) {
+ fw_debug_trace[i] = extend_c2h_dbg_content[i];
+ if (extend_c2h_dbg_content[i + 1] == '\0') {
+ fw_debug_trace[i + 1] = '\0';
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW DBG Msg] %s", &(fw_debug_trace[0])));
+ break;
+ } else if (extend_c2h_dbg_content[i] == '\n') {
+ fw_debug_trace[i + 1] = '\0';
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW DBG Msg] %s", &(fw_debug_trace[0])));
+ buffer = extend_c2h_dbg_content + i + 3;
+ goto go_backfor_aggre_dbg_pkt;
+ }
+ }
+
+
+#endif /*#if CONFIG_PHYDM_DEBUG_FUNCTION*/
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_debug.h b/drivers/staging/rtl8188eu/hal/phydm_debug.h
new file mode 100644
index 000000000000..661139551cf0
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_debug.h
@@ -0,0 +1,294 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+
+#ifndef __ODM_DBG_H__
+#define __ODM_DBG_H__
+
+/*#define DEBUG_VERSION "1.1"*/ /*2015.07.29 YuChen*/
+/*#define DEBUG_VERSION "1.2"*/ /*2015.08.28 Dino*/
+#define DEBUG_VERSION "1.3" /*2016.04.28 YuChen*/
+/* -----------------------------------------------------------------------------
+ * Define the debug levels
+ *
+ * 1. DBG_TRACE and DBG_LOUD are used for normal cases.
+ * So that, they can help SW engineer to develope or trace states changed
+ * and also help HW enginner to trace every operation to and from HW,
+ * e.g IO, Tx, Rx.
+ *
+ * 2. DBG_WARNNING and DBG_SERIOUS are used for unusual or error cases,
+ * which help us to debug SW or HW.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Never used in a call to ODM_RT_TRACE()!
+ * */
+#define ODM_DBG_OFF 1
+
+/*
+ * Fatal bug.
+ * For example, Tx/Rx/IO locked up, OS hangs, memory access violation,
+ * resource allocation failed, unexpected HW behavior, HW BUG and so on.
+ * */
+#define ODM_DBG_SERIOUS 2
+
+/*
+ * Abnormal, rare, or unexpeted cases.
+ * For example, IRP/Packet/OID canceled, device suprisely unremoved and so on.
+ * */
+#define ODM_DBG_WARNING 3
+
+/*
+ * Normal case with useful information about current SW or HW state.
+ * For example, Tx/Rx descriptor to fill, Tx/Rx descriptor completed status,
+ * SW protocol state change, dynamic mechanism state change and so on.
+ * */
+#define ODM_DBG_LOUD 4
+
+/*
+ * Normal case with detail execution flow or information.
+ * */
+#define ODM_DBG_TRACE 5
+
+/*FW DBG MSG*/
+#define RATE_DECISION BIT(0)
+#define INIT_RA_TABLE BIT(1)
+#define RATE_UP BIT(2)
+#define RATE_DOWN BIT(3)
+#define TRY_DONE BIT(4)
+#define RA_H2C BIT(5)
+#define F_RATE_AP_RPT BIT(7)
+
+/* -----------------------------------------------------------------------------
+ * Define the tracing components
+ *
+ * -----------------------------------------------------------------------------
+ *BB FW Functions*/
+#define PHYDM_FW_COMP_RA BIT(0)
+#define PHYDM_FW_COMP_MU BIT(1)
+#define PHYDM_FW_COMP_PATH_DIV BIT(2)
+#define PHYDM_FW_COMP_PHY_CONFIG BIT(3)
+
+
+/*BB Driver Functions*/
+#define ODM_COMP_DIG BIT(0)
+#define ODM_COMP_RA_MASK BIT(1)
+#define ODM_COMP_DYNAMIC_TXPWR BIT(2)
+#define ODM_COMP_FA_CNT BIT(3)
+#define ODM_COMP_RSSI_MONITOR BIT(4)
+#define ODM_COMP_SNIFFER BIT(5)
+#define ODM_COMP_ANT_DIV BIT(6)
+#define ODM_COMP_DFS BIT(7)
+#define ODM_COMP_NOISY_DETECT BIT(8)
+#define ODM_COMP_RATE_ADAPTIVE BIT(9)
+#define ODM_COMP_PATH_DIV BIT(10)
+#define ODM_COMP_CCX BIT(11)
+
+#define ODM_COMP_DYNAMIC_PRICCA BIT(12)
+/*BIT13 TBD*/
+#define ODM_COMP_MP BIT(14)
+#define ODM_COMP_CFO_TRACKING BIT(15)
+#define ODM_COMP_ACS BIT(16)
+#define PHYDM_COMP_ADAPTIVITY BIT(17)
+#define PHYDM_COMP_RA_DBG BIT(18)
+#define PHYDM_COMP_TXBF BIT(19)
+/* MAC Functions */
+#define ODM_COMP_EDCA_TURBO BIT(20)
+#define ODM_COMP_DYNAMIC_RX_PATH BIT(21)
+#define ODM_FW_DEBUG_TRACE BIT(22)
+/* RF Functions */
+/*BIT23 TBD*/
+#define ODM_COMP_TX_PWR_TRACK BIT(24)
+/*BIT25 TBD*/
+#define ODM_COMP_CALIBRATION BIT(26)
+/* Common Functions */
+/*BIT27 TBD*/
+#define ODM_PHY_CONFIG BIT(28)
+#define ODM_COMP_INIT BIT(29)
+#define ODM_COMP_COMMON BIT(30)
+#define ODM_COMP_API BIT(31)
+
+
+/*------------------------Export Marco Definition---------------------------*/
+
+#define config_phydm_read_txagc_check(data) (data != INVALID_TXAGC_DATA)
+
+#define dbg_print printk
+#define RT_PRINTK(fmt, args...) dbg_print("%s(): " fmt, __func__, ## args);
+#define RT_DISP(dbgtype, dbgflag, printstr)
+
+#ifndef ASSERT
+ #define ASSERT(expr)
+#endif
+
+#if DBG
+#define ODM_RT_TRACE(p_dm_odm, comp, level, fmt) \
+ do { \
+ if (((comp) & p_dm_odm->debug_components) && (level <= p_dm_odm->debug_level || level == ODM_DBG_SERIOUS)) { \
+ \
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E) \
+ dbg_print("[PhyDM-8188E] "); \
+ else if (p_dm_odm->support_ic_type == ODM_RTL8192E) \
+ dbg_print("[PhyDM-8192E] "); \
+ else if (p_dm_odm->support_ic_type == ODM_RTL8812) \
+ dbg_print("[PhyDM-8812A] "); \
+ else if (p_dm_odm->support_ic_type == ODM_RTL8821) \
+ dbg_print("[PhyDM-8821A] "); \
+ else if (p_dm_odm->support_ic_type == ODM_RTL8814A) \
+ dbg_print("[PhyDM-8814A] "); \
+ else if (p_dm_odm->support_ic_type == ODM_RTL8703B) \
+ dbg_print("[PhyDM-8703B] "); \
+ else if (p_dm_odm->support_ic_type == ODM_RTL8822B) \
+ dbg_print("[PhyDM-8822B] "); \
+ else if (p_dm_odm->support_ic_type == ODM_RTL8188F) \
+ dbg_print("[PhyDM-8188F] "); \
+ RT_PRINTK fmt; \
+ } \
+ } while (0)
+
+#define ODM_RT_TRACE_F(p_dm_odm, comp, level, fmt) do {\
+ if (((comp) & p_dm_odm->debug_components) && (level <= p_dm_odm->debug_level)) { \
+ \
+ RT_PRINTK fmt; \
+ } \
+ } while (0)
+
+
+#define ODM_RT_ASSERT(p_dm_odm, expr, fmt) do {\
+ if (!(expr)) { \
+ dbg_print("Assertion failed! %s at ......\n", #expr); \
+ dbg_print(" ......%s,%s, line=%d\n", __FILE__, __func__, __LINE__); \
+ RT_PRINTK fmt; \
+ ASSERT(false); \
+ } \
+ } while (0)
+
+#define ODM_dbg_enter() { dbg_print(" == > %s\n", __func__); }
+#define ODM_dbg_exit() { dbg_print("< == %s\n", __func__); }
+#define ODM_dbg_trace(str) { dbg_print("%s:%s\n", __func__, str); }
+
+#define ODM_PRINT_ADDR(p_dm_odm, comp, level, title_str, ptr) do {\
+ if (((comp) & p_dm_odm->debug_components) && (level <= p_dm_odm->debug_level)) { \
+ \
+ int __i; \
+ u8 *__ptr = (u8 *)ptr; \
+ dbg_print("[ODM] "); \
+ dbg_print(title_str); \
+ dbg_print(" "); \
+ for (__i = 0; __i < 6; __i++) \
+ dbg_print("%02X%s", __ptr[__i], (__i == 5) ? "" : "-"); \
+ dbg_print("\n"); \
+ } \
+ } while (0)
+
+#else
+#define ODM_RT_TRACE(p_dm_odm, comp, level, fmt)
+#define ODM_RT_TRACE_F(p_dm_odm, comp, level, fmt)
+#define ODM_RT_ASSERT(p_dm_odm, expr, fmt)
+#define ODM_dbg_enter()
+#define ODM_dbg_exit()
+#define ODM_dbg_trace(str)
+#define ODM_PRINT_ADDR(p_dm_odm, comp, level, title_str, ptr)
+#endif
+
+
+void
+phydm_init_debug_setting(struct PHY_DM_STRUCT *p_dm_odm);
+
+void phydm_basic_dbg_message(void *p_dm_void);
+
+#define PHYDM_DBGPRINT 0
+#define MAX_ARGC 20
+#define MAX_ARGV 16
+#define DCMD_DECIMAL "%d"
+#define DCMD_CHAR "%c"
+#define DCMD_HEX "%x"
+
+#define PHYDM_SSCANF(x, y, z) sscanf(x, y, z)
+
+#define PHYDM_VAST_INFO_SNPRINTF(msg)\
+ do {\
+ snprintf msg;\
+ dbg_print(output);\
+ } while (0)
+
+#if (PHYDM_DBGPRINT == 1)
+#define PHYDM_SNPRINTF(msg)\
+ do {\
+ snprintf msg;\
+ dbg_print(output);\
+ } while (0)
+#else
+#define PHYDM_SNPRINTF(msg)\
+ do {\
+ if (out_len > used)\
+ used += snprintf msg;\
+ } while (0)
+#endif
+
+void phydm_basic_profile(
+ void *p_dm_void,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+);
+s32
+phydm_cmd(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ char *input,
+ u32 in_len,
+ u8 flag,
+ char *output,
+ u32 out_len
+);
+
+void
+phydm_cmd_parser(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ char input[][16],
+ u32 input_num,
+ u8 flag,
+ char *output,
+ u32 out_len
+);
+
+bool
+phydm_api_trx_mode(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_rf_path_e tx_path,
+ enum odm_rf_path_e rx_path,
+ bool is_tx2_path
+);
+
+void
+phydm_fw_trace_en_h2c(
+ void *p_dm_void,
+ bool enable,
+ u32 fw_debug_component,
+ u32 monitor_mode,
+ u32 macid
+);
+
+void
+phydm_fw_trace_handler(
+ void *p_dm_void,
+ u8 *cmd_buf,
+ u8 cmd_len
+);
+
+void
+phydm_fw_trace_handler_code(
+ void *p_dm_void,
+ u8 *buffer,
+ u8 cmd_len
+);
+
+void
+phydm_fw_trace_handler_8051(
+ void *p_dm_void,
+ u8 *cmd_buf,
+ u8 cmd_len
+);
+
+#endif /* __ODM_DBG_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/phydm_dfs.c b/drivers/staging/rtl8188eu/hal/phydm_dfs.c
new file mode 100644
index 000000000000..5b1f6f45d3cd
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_dfs.c
@@ -0,0 +1,241 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/*
+============================================================
+ include files
+============================================================
+*/
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+#if defined(CONFIG_PHYDM_DFS_MASTER)
+void phydm_radar_detect_reset(void *p_dm_void)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ odm_set_bb_reg(p_dm_odm, 0x924, BIT(15), 0);
+ odm_set_bb_reg(p_dm_odm, 0x924, BIT(15), 1);
+}
+
+void phydm_radar_detect_disable(void *p_dm_void)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ odm_set_bb_reg(p_dm_odm, 0x924, BIT(15), 0);
+}
+
+static void phydm_radar_detect_with_dbg_parm(void *p_dm_void)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, p_dm_odm->radar_detect_reg_918);
+ odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, p_dm_odm->radar_detect_reg_91c);
+ odm_set_bb_reg(p_dm_odm, 0x920, MASKDWORD, p_dm_odm->radar_detect_reg_920);
+ odm_set_bb_reg(p_dm_odm, 0x924, MASKDWORD, p_dm_odm->radar_detect_reg_924);
+}
+
+/* Init radar detection parameters, called after ch, bw is set */
+void phydm_radar_detect_enable(void *p_dm_void)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 region_domain = p_dm_odm->dfs_region_domain;
+ u8 c_channel = *(p_dm_odm->p_channel);
+
+ if (region_domain == PHYDM_DFS_DOMAIN_UNKNOWN) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DFS, ODM_DBG_LOUD, ("PHYDM_DFS_DOMAIN_UNKNOWN\n"));
+ return;
+ }
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8821 | ODM_RTL8812 | ODM_RTL8881A)) {
+
+ odm_set_bb_reg(p_dm_odm, 0x814, 0x3fffffff, 0x04cc4d10);
+ odm_set_bb_reg(p_dm_odm, 0x834, MASKBYTE0, 0x06);
+
+ if (p_dm_odm->radar_detect_dbg_parm_en) {
+ phydm_radar_detect_with_dbg_parm(p_dm_odm);
+ goto exit;
+ }
+
+ if (region_domain == PHYDM_DFS_DOMAIN_ETSI) {
+ odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c17ecdf);
+ odm_set_bb_reg(p_dm_odm, 0x924, MASKDWORD, 0x01528500);
+ odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x0fa21a20);
+ odm_set_bb_reg(p_dm_odm, 0x920, MASKDWORD, 0xe0f69204);
+
+ } else if (region_domain == PHYDM_DFS_DOMAIN_MKK) {
+ odm_set_bb_reg(p_dm_odm, 0x924, MASKDWORD, 0x01528500);
+ odm_set_bb_reg(p_dm_odm, 0x920, MASKDWORD, 0xe0d67234);
+
+ if (c_channel >= 52 && c_channel <= 64) {
+ odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c16ecdf);
+ odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x0f141a20);
+ } else {
+ odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c16acdf);
+ if (p_dm_odm->p_band_width == ODM_BW20M)
+ odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x64721a20);
+ else
+ odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x68721a20);
+ }
+
+ } else if (region_domain == PHYDM_DFS_DOMAIN_FCC) {
+ odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c16acdf);
+ odm_set_bb_reg(p_dm_odm, 0x924, MASKDWORD, 0x01528500);
+ odm_set_bb_reg(p_dm_odm, 0x920, MASKDWORD, 0xe0d67231);
+ if (p_dm_odm->p_band_width == ODM_BW20M)
+ odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x64741a20);
+ else
+ odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x68741a20);
+ } else {
+ /* not supported */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DFS, ODM_DBG_LOUD, ("Unsupported dfs_region_domain:%d\n", region_domain));
+ }
+
+ } else if (p_dm_odm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B)) {
+
+ odm_set_bb_reg(p_dm_odm, 0x814, 0x3fffffff, 0x04cc4d10);
+ odm_set_bb_reg(p_dm_odm, 0x834, MASKBYTE0, 0x06);
+
+ /* 8822B only, when BW = 20M, DFIR output is 40Mhz, but DFS input is 80MMHz, so it need to upgrade to 80MHz */
+ if (p_dm_odm->support_ic_type & ODM_RTL8822B) {
+ if (p_dm_odm->p_band_width == ODM_BW20M)
+ odm_set_bb_reg(p_dm_odm, 0x1984, BIT(26), 1);
+ else
+ odm_set_bb_reg(p_dm_odm, 0x1984, BIT(26), 0);
+ }
+
+ if (p_dm_odm->radar_detect_dbg_parm_en) {
+ phydm_radar_detect_with_dbg_parm(p_dm_odm);
+ goto exit;
+ }
+
+ if (region_domain == PHYDM_DFS_DOMAIN_ETSI) {
+ odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c16acdf);
+ odm_set_bb_reg(p_dm_odm, 0x924, MASKDWORD, 0x095a8500);
+ odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x0fa21a20);
+ odm_set_bb_reg(p_dm_odm, 0x920, MASKDWORD, 0xe0f57204);
+
+ } else if (region_domain == PHYDM_DFS_DOMAIN_MKK) {
+ odm_set_bb_reg(p_dm_odm, 0x924, MASKDWORD, 0x095a8500);
+ odm_set_bb_reg(p_dm_odm, 0x920, MASKDWORD, 0xe0d67234);
+
+ if (c_channel >= 52 && c_channel <= 64) {
+ odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c16ecdf);
+ odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x0f141a20);
+ } else {
+ odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c166cdf);
+ if (p_dm_odm->p_band_width == ODM_BW20M)
+ odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x64721a20);
+ else
+ odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x68721a20);
+ }
+ } else if (region_domain == PHYDM_DFS_DOMAIN_FCC) {
+ odm_set_bb_reg(p_dm_odm, 0x918, MASKDWORD, 0x1c166cdf);
+ odm_set_bb_reg(p_dm_odm, 0x924, MASKDWORD, 0x095a8500);
+ odm_set_bb_reg(p_dm_odm, 0x920, MASKDWORD, 0xe0d67231);
+ if (p_dm_odm->p_band_width == ODM_BW20M)
+ odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x64741a20);
+ else
+ odm_set_bb_reg(p_dm_odm, 0x91c, MASKDWORD, 0x68741a20);
+ } else {
+ /* not supported */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DFS, ODM_DBG_LOUD, ("Unsupported dfs_region_domain:%d\n", region_domain));
+ }
+ } else {
+ /* not supported IC type*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DFS, ODM_DBG_LOUD, ("Unsupported IC type:%d\n", p_dm_odm->support_ic_type));
+ }
+
+exit:
+ phydm_radar_detect_reset(p_dm_odm);
+}
+
+bool phydm_radar_detect(void *p_dm_void)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ bool enable_DFS = false;
+ bool radar_detected = false;
+ u8 region_domain = p_dm_odm->dfs_region_domain;
+
+ if (region_domain == PHYDM_DFS_DOMAIN_UNKNOWN) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DFS, ODM_DBG_LOUD, ("PHYDM_DFS_DOMAIN_UNKNOWN\n"));
+ return false;
+ }
+
+ if (odm_get_bb_reg(p_dm_odm, 0x924, BIT(15)))
+ enable_DFS = true;
+
+ if ((odm_get_bb_reg(p_dm_odm, 0xf98, BIT(17)))
+ || (!(region_domain == PHYDM_DFS_DOMAIN_ETSI) && (odm_get_bb_reg(p_dm_odm, 0xf98, BIT(19)))))
+ radar_detected = true;
+
+ if (enable_DFS && radar_detected) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DFS, ODM_DBG_LOUD
+ , ("Radar detect: enable_DFS:%d, radar_detected:%d\n"
+ , enable_DFS, radar_detected));
+
+ phydm_radar_detect_reset(p_dm_odm);
+ }
+
+exit:
+ return enable_DFS && radar_detected;
+}
+#endif /* defined(CONFIG_PHYDM_DFS_MASTER) */
+
+bool
+phydm_dfs_master_enabled(
+ void *p_dm_void
+)
+{
+#ifdef CONFIG_PHYDM_DFS_MASTER
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ return *p_dm_odm->dfs_master_enabled ? true : false;
+#else
+ return false;
+#endif
+}
+
+void
+phydm_dfs_debug(
+ void *p_dm_void,
+ u32 *const argv,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ switch (argv[0]) {
+ case 1:
+#if defined(CONFIG_PHYDM_DFS_MASTER)
+ /* set dbg parameters for radar detection instead of the default value */
+ if (argv[1] == 1) {
+ p_dm_odm->radar_detect_reg_918 = argv[2];
+ p_dm_odm->radar_detect_reg_91c = argv[3];
+ p_dm_odm->radar_detect_reg_920 = argv[4];
+ p_dm_odm->radar_detect_reg_924 = argv[5];
+ p_dm_odm->radar_detect_dbg_parm_en = 1;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "Radar detection with dbg parameter\n"));
+ PHYDM_SNPRINTF((output + used, out_len - used, "reg918:0x%08X\n", p_dm_odm->radar_detect_reg_918));
+ PHYDM_SNPRINTF((output + used, out_len - used, "reg91c:0x%08X\n", p_dm_odm->radar_detect_reg_91c));
+ PHYDM_SNPRINTF((output + used, out_len - used, "reg920:0x%08X\n", p_dm_odm->radar_detect_reg_920));
+ PHYDM_SNPRINTF((output + used, out_len - used, "reg924:0x%08X\n", p_dm_odm->radar_detect_reg_924));
+ } else {
+ p_dm_odm->radar_detect_dbg_parm_en = 0;
+ PHYDM_SNPRINTF((output + used, out_len - used, "Radar detection with default parameter\n"));
+ }
+ phydm_radar_detect_enable(p_dm_odm);
+#endif /* defined(CONFIG_PHYDM_DFS_MASTER) */
+
+ break;
+ default:
+ break;
+ }
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_dfs.h b/drivers/staging/rtl8188eu/hal/phydm_dfs.h
new file mode 100644
index 000000000000..b89ccea0d6f5
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_dfs.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDM_DFS_H__
+#define __PHYDM_DFS_H__
+
+#define DFS_VERSION "0.0"
+
+/* ============================================================
+ Definition
+ ============================================================
+*/
+
+/*
+============================================================
+1 structure
+ ============================================================
+*/
+
+/* ============================================================
+ enumeration
+ ============================================================
+*/
+
+enum phydm_dfs_region_domain {
+ PHYDM_DFS_DOMAIN_UNKNOWN = 0,
+ PHYDM_DFS_DOMAIN_FCC = 1,
+ PHYDM_DFS_DOMAIN_MKK = 2,
+ PHYDM_DFS_DOMAIN_ETSI = 3,
+};
+
+/*
+============================================================
+ function prototype
+============================================================
+*/
+#if defined(CONFIG_PHYDM_DFS_MASTER)
+ void phydm_radar_detect_reset(void *p_dm_void);
+ void phydm_radar_detect_disable(void *p_dm_void);
+ void phydm_radar_detect_enable(void *p_dm_void);
+ bool phydm_radar_detect(void *p_dm_void);
+#endif /* defined(CONFIG_PHYDM_DFS_MASTER) */
+
+bool
+phydm_dfs_master_enabled(
+ void *p_dm_void
+);
+
+void
+phydm_dfs_debug(
+ void *p_dm_void,
+ u32 *const argv,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+);
+
+#endif /*#ifndef __PHYDM_DFS_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/phydm_dig.c b/drivers/staging/rtl8188eu/hal/phydm_dig.c
new file mode 100644
index 000000000000..f13f77c05ef0
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_dig.c
@@ -0,0 +1,1305 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+
+void
+odm_change_dynamic_init_gain_thresh(
+ void *p_dm_void,
+ u32 dm_type,
+ u32 dm_value
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+
+ if (dm_type == DIG_TYPE_THRESH_HIGH)
+ p_dm_dig_table->rssi_high_thresh = dm_value;
+ else if (dm_type == DIG_TYPE_THRESH_LOW)
+ p_dm_dig_table->rssi_low_thresh = dm_value;
+ else if (dm_type == DIG_TYPE_ENABLE)
+ p_dm_dig_table->dig_enable_flag = true;
+ else if (dm_type == DIG_TYPE_DISABLE)
+ p_dm_dig_table->dig_enable_flag = false;
+ else if (dm_type == DIG_TYPE_BACKOFF) {
+ if (dm_value > 30)
+ dm_value = 30;
+ p_dm_dig_table->backoff_val = (u8)dm_value;
+ } else if (dm_type == DIG_TYPE_RX_GAIN_MIN) {
+ if (dm_value == 0)
+ dm_value = 0x1;
+ p_dm_dig_table->rx_gain_range_min = (u8)dm_value;
+ } else if (dm_type == DIG_TYPE_RX_GAIN_MAX) {
+ if (dm_value > 0x50)
+ dm_value = 0x50;
+ p_dm_dig_table->rx_gain_range_max = (u8)dm_value;
+ }
+} /* dm_change_dynamic_init_gain_thresh */
+
+static int
+get_igi_for_diff(int value_IGI)
+{
+#define ONERCCA_LOW_TH 0x30
+#define ONERCCA_LOW_DIFF 8
+
+ if (value_IGI < ONERCCA_LOW_TH) {
+ if ((ONERCCA_LOW_TH - value_IGI) < ONERCCA_LOW_DIFF)
+ return ONERCCA_LOW_TH;
+ else
+ return value_IGI + ONERCCA_LOW_DIFF;
+ } else
+ return value_IGI;
+}
+
+static void
+odm_fa_threshold_check(
+ void *p_dm_void,
+ bool is_dfs_band,
+ bool is_performance,
+ u32 rx_tp,
+ u32 tx_tp,
+ u32 *dm_FA_thres
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (p_dm_odm->is_linked && (is_performance || is_dfs_band)) {
+ /*For NIC*/
+ dm_FA_thres[0] = DM_DIG_FA_TH0;
+ dm_FA_thres[1] = DM_DIG_FA_TH1;
+ dm_FA_thres[2] = DM_DIG_FA_TH2;
+ } else {
+ if (is_dfs_band) {
+ /* For DFS band and no link */
+ dm_FA_thres[0] = 250;
+ dm_FA_thres[1] = 1000;
+ dm_FA_thres[2] = 2000;
+ } else {
+ dm_FA_thres[0] = 2000;
+ dm_FA_thres[1] = 4000;
+ dm_FA_thres[2] = 5000;
+ }
+ }
+ return;
+}
+
+static u8
+odm_forbidden_igi_check(
+ void *p_dm_void,
+ u8 dig_dynamic_min,
+ u8 current_igi
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+ struct false_ALARM_STATISTICS *p_false_alm_cnt = (struct false_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDMfalseALMCNT);
+ u8 rx_gain_range_min = p_dm_dig_table->rx_gain_range_min;
+
+ if (p_dm_dig_table->large_fa_timeout) {
+ if (--p_dm_dig_table->large_fa_timeout == 0)
+ p_dm_dig_table->large_fa_hit = 0;
+ }
+
+ if (p_false_alm_cnt->cnt_all > 10000) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnormally false alarm case.\n"));
+
+ if (p_dm_dig_table->large_fa_hit != 3)
+ p_dm_dig_table->large_fa_hit++;
+
+ if (p_dm_dig_table->forbidden_igi < current_igi) { /* if(p_dm_dig_table->forbidden_igi < p_dm_dig_table->cur_ig_value) */
+ p_dm_dig_table->forbidden_igi = current_igi;/* p_dm_dig_table->forbidden_igi = p_dm_dig_table->cur_ig_value; */
+ p_dm_dig_table->large_fa_hit = 1;
+ p_dm_dig_table->large_fa_timeout = LARGE_FA_TIMEOUT;
+ }
+
+ if (p_dm_dig_table->large_fa_hit >= 3) {
+ if ((p_dm_dig_table->forbidden_igi + 2) > p_dm_dig_table->rx_gain_range_max)
+ rx_gain_range_min = p_dm_dig_table->rx_gain_range_max;
+ else
+ rx_gain_range_min = (p_dm_dig_table->forbidden_igi + 2);
+ p_dm_dig_table->recover_cnt = 1800;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnormally false alarm case: recover_cnt = %d\n", p_dm_dig_table->recover_cnt));
+ }
+ }
+
+ else if (p_false_alm_cnt->cnt_all > 2000) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Abnormally false alarm case.\n"));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("cnt_all=%d, cnt_all_pre=%d, current_igi=0x%x, pre_ig_value=0x%x\n",
+ p_false_alm_cnt->cnt_all, p_false_alm_cnt->cnt_all_pre, current_igi, p_dm_dig_table->pre_ig_value));
+
+ /* p_false_alm_cnt->cnt_all = 1.1875*p_false_alm_cnt->cnt_all_pre */
+ if ((p_false_alm_cnt->cnt_all > (p_false_alm_cnt->cnt_all_pre + (p_false_alm_cnt->cnt_all_pre >> 3) + (p_false_alm_cnt->cnt_all_pre >> 4))) && (current_igi < p_dm_dig_table->pre_ig_value)) {
+ if (p_dm_dig_table->large_fa_hit != 3)
+ p_dm_dig_table->large_fa_hit++;
+
+ if (p_dm_dig_table->forbidden_igi < current_igi) { /*if(p_dm_dig_table->forbidden_igi < p_dm_dig_table->cur_ig_value)*/
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Updating forbidden_igi by current_igi, forbidden_igi=0x%x, current_igi=0x%x\n",
+ p_dm_dig_table->forbidden_igi, current_igi));
+
+ p_dm_dig_table->forbidden_igi = current_igi; /*p_dm_dig_table->forbidden_igi = p_dm_dig_table->cur_ig_value;*/
+ p_dm_dig_table->large_fa_hit = 1;
+ p_dm_dig_table->large_fa_timeout = LARGE_FA_TIMEOUT;
+ }
+
+ }
+
+ if (p_dm_dig_table->large_fa_hit >= 3) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("FaHit is greater than 3, rx_gain_range_max=0x%x, rx_gain_range_min=0x%x, forbidden_igi=0x%x\n",
+ p_dm_dig_table->rx_gain_range_max, rx_gain_range_min, p_dm_dig_table->forbidden_igi));
+
+ if ((p_dm_dig_table->forbidden_igi + 1) > p_dm_dig_table->rx_gain_range_max)
+ rx_gain_range_min = p_dm_dig_table->rx_gain_range_max;
+ else
+ rx_gain_range_min = (p_dm_dig_table->forbidden_igi + 1);
+
+ p_dm_dig_table->recover_cnt = 1200;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Abnormally false alarm case: recover_cnt = %d, rx_gain_range_min = 0x%x\n", p_dm_dig_table->recover_cnt, rx_gain_range_min));
+ }
+ }
+
+ else {
+ if (p_dm_dig_table->recover_cnt != 0) {
+
+ p_dm_dig_table->recover_cnt--;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: recover_cnt = %d\n", p_dm_dig_table->recover_cnt));
+ } else {
+ if (p_dm_dig_table->large_fa_hit < 3) {
+ if ((p_dm_dig_table->forbidden_igi - 2) < dig_dynamic_min) { /* DM_DIG_MIN) */
+ p_dm_dig_table->forbidden_igi = dig_dynamic_min; /* DM_DIG_MIN; */
+ rx_gain_range_min = dig_dynamic_min; /* DM_DIG_MIN; */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: At Lower Bound\n"));
+ } else {
+ if (p_dm_dig_table->large_fa_hit == 0) {
+ p_dm_dig_table->forbidden_igi -= 2;
+ rx_gain_range_min = (p_dm_dig_table->forbidden_igi + 2);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: Approach Lower Bound\n"));
+ }
+ }
+ } else
+ p_dm_dig_table->large_fa_hit = 0;
+ }
+ }
+
+ return rx_gain_range_min;
+
+}
+
+static void
+odm_inband_noise_calculate(
+ void *p_dm_void
+)
+{
+}
+
+static void
+odm_dig_for_bt_hs_mode(
+ void *p_dm_void
+)
+{
+}
+
+static void
+phydm_set_big_jump_step(
+ void *p_dm_void,
+ u8 current_igi
+)
+{
+}
+
+void
+odm_write_dig(
+ void *p_dm_void,
+ u8 current_igi
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+
+ if (p_dm_dig_table->is_stop_dig) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_write_dig(): Stop Writing IGI\n"));
+ return;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_TRACE, ("odm_write_dig(): ODM_REG(IGI_A,p_dm_odm)=0x%x, ODM_BIT(IGI,p_dm_odm)=0x%x\n",
+ ODM_REG(IGI_A, p_dm_odm), ODM_BIT(IGI, p_dm_odm)));
+
+ /* 1 Check initial gain by upper bound */
+ if ((!p_dm_dig_table->is_psd_in_progress) && p_dm_odm->is_linked) {
+ if (current_igi > p_dm_dig_table->rx_gain_range_max) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_TRACE, ("odm_write_dig(): current_igi(0x%02x) is larger than upper bound !!\n", current_igi));
+ current_igi = p_dm_dig_table->rx_gain_range_max;
+ }
+ if (p_dm_odm->support_ability & ODM_BB_ADAPTIVITY && p_dm_odm->adaptivity_flag == true) {
+ if (current_igi > p_dm_odm->adaptivity_igi_upper)
+ current_igi = p_dm_odm->adaptivity_igi_upper;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_write_dig(): adaptivity case: Force upper bound to 0x%x !!!!!!\n", current_igi));
+ }
+ }
+
+ if (p_dm_dig_table->cur_ig_value != current_igi) {
+
+#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1)
+ /* Set IGI value of CCK for new CCK AGC */
+ if (p_dm_odm->cck_new_agc) {
+ if (p_dm_odm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE)
+ odm_set_bb_reg(p_dm_odm, 0xa0c, 0x00003f00, (current_igi >> 1));
+ }
+#endif
+
+ /*Add by YuChen for USB IO too slow issue*/
+ if ((p_dm_odm->support_ability & ODM_BB_ADAPTIVITY) && (current_igi > p_dm_dig_table->cur_ig_value)) {
+ p_dm_dig_table->cur_ig_value = current_igi;
+ phydm_adaptivity(p_dm_odm);
+ }
+
+ /* 1 Set IGI value */
+ if (p_dm_odm->support_platform & (ODM_WIN | ODM_CE)) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_A, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
+
+ if (p_dm_odm->rf_type > ODM_1T1R)
+ odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_B, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
+
+#if (RTL8814A_SUPPORT == 1)
+ if (p_dm_odm->support_ic_type & ODM_RTL8814A) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_C, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
+ odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_D, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
+ }
+#endif
+ } else if (p_dm_odm->support_platform & (ODM_AP)) {
+ switch (*(p_dm_odm->p_one_path_cca)) {
+ case ODM_CCA_2R:
+ odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_A, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
+
+ if (p_dm_odm->rf_type > ODM_1T1R)
+ odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_B, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
+#if (RTL8814A_SUPPORT == 1)
+ if (p_dm_odm->support_ic_type & ODM_RTL8814A) {
+ odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_C, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
+ odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_D, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
+ }
+#endif
+ break;
+ case ODM_CCA_1R_A:
+ odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_A, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
+ if (p_dm_odm->rf_type != ODM_1T1R)
+ odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_B, p_dm_odm), ODM_BIT(IGI, p_dm_odm), get_igi_for_diff(current_igi));
+ break;
+ case ODM_CCA_1R_B:
+ odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_B, p_dm_odm), ODM_BIT(IGI, p_dm_odm), get_igi_for_diff(current_igi));
+ if (p_dm_odm->rf_type != ODM_1T1R)
+ odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_A, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
+ break;
+ }
+ }
+
+ p_dm_dig_table->cur_ig_value = current_igi;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_TRACE, ("odm_write_dig(): current_igi(0x%02x).\n", current_igi));
+
+}
+
+void
+odm_pause_dig(
+ void *p_dm_void,
+ enum phydm_pause_type pause_type,
+ enum phydm_pause_level pause_level,
+ u8 igi_value
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig()=========> level = %d\n", pause_level));
+
+ if ((p_dm_dig_table->pause_dig_level == 0) && (!(p_dm_odm->support_ability & ODM_BB_DIG) || !(p_dm_odm->support_ability & ODM_BB_FA_CNT))) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD,
+ ("odm_pause_dig(): Return: support_ability DIG or FA is disabled !!\n"));
+ return;
+ }
+
+ if (pause_level > DM_DIG_MAX_PAUSE_TYPE) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD,
+ ("odm_pause_dig(): Return: Wrong pause level !!\n"));
+ return;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): pause level = 0x%x, Current value = 0x%x\n", p_dm_dig_table->pause_dig_level, igi_value));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ p_dm_dig_table->pause_dig_value[7], p_dm_dig_table->pause_dig_value[6], p_dm_dig_table->pause_dig_value[5], p_dm_dig_table->pause_dig_value[4],
+ p_dm_dig_table->pause_dig_value[3], p_dm_dig_table->pause_dig_value[2], p_dm_dig_table->pause_dig_value[1], p_dm_dig_table->pause_dig_value[0]));
+
+ switch (pause_type) {
+ /* Pause DIG */
+ case PHYDM_PAUSE:
+ {
+ /* Disable DIG */
+ odm_cmn_info_update(p_dm_odm, ODM_CMNINFO_ABILITY, p_dm_odm->support_ability & (~ODM_BB_DIG));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): Pause DIG !!\n"));
+
+ /* Backup IGI value */
+ if (p_dm_dig_table->pause_dig_level == 0) {
+ p_dm_dig_table->igi_backup = p_dm_dig_table->cur_ig_value;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): Backup IGI = 0x%x, new IGI = 0x%x\n", p_dm_dig_table->igi_backup, igi_value));
+ }
+
+ /* Record IGI value */
+ p_dm_dig_table->pause_dig_value[pause_level] = igi_value;
+
+ /* Update pause level */
+ p_dm_dig_table->pause_dig_level = (p_dm_dig_table->pause_dig_level | BIT(pause_level));
+
+ /* Write new IGI value */
+ if (BIT(pause_level + 1) > p_dm_dig_table->pause_dig_level) {
+ odm_write_dig(p_dm_odm, igi_value);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): IGI of higher level = 0x%x\n", igi_value));
+ }
+ break;
+ }
+ /* Resume DIG */
+ case PHYDM_RESUME:
+ {
+ /* check if the level is illegal or not */
+ if ((p_dm_dig_table->pause_dig_level & (BIT(pause_level))) != 0) {
+ p_dm_dig_table->pause_dig_level = p_dm_dig_table->pause_dig_level & (~(BIT(pause_level)));
+ p_dm_dig_table->pause_dig_value[pause_level] = 0;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): Resume DIG !!\n"));
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): Wrong resume level !!\n"));
+ break;
+ }
+
+ /* Resume DIG */
+ if (p_dm_dig_table->pause_dig_level == 0) {
+ /* Write backup IGI value */
+ odm_write_dig(p_dm_odm, p_dm_dig_table->igi_backup);
+ p_dm_dig_table->is_ignore_dig = true;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): Write original IGI = 0x%x\n", p_dm_dig_table->igi_backup));
+
+ /* Enable DIG */
+ odm_cmn_info_update(p_dm_odm, ODM_CMNINFO_ABILITY, p_dm_odm->support_ability | ODM_BB_DIG);
+ break;
+ }
+
+ if (BIT(pause_level) > p_dm_dig_table->pause_dig_level) {
+ s8 max_level;
+
+ /* Calculate the maximum level now */
+ for (max_level = (pause_level - 1); max_level >= 0; max_level--) {
+ if ((p_dm_dig_table->pause_dig_level & BIT(max_level)) > 0)
+ break;
+ }
+
+ /* write IGI of lower level */
+ odm_write_dig(p_dm_odm, p_dm_dig_table->pause_dig_value[max_level]);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): Write IGI (0x%x) of level (%d)\n",
+ p_dm_dig_table->pause_dig_value[max_level], max_level));
+ break;
+ }
+ break;
+ }
+ default:
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): Wrong type !!\n"));
+ break;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): pause level = 0x%x, Current value = 0x%x\n", p_dm_dig_table->pause_dig_level, igi_value));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ p_dm_dig_table->pause_dig_value[7], p_dm_dig_table->pause_dig_value[6], p_dm_dig_table->pause_dig_value[5], p_dm_dig_table->pause_dig_value[4],
+ p_dm_dig_table->pause_dig_value[3], p_dm_dig_table->pause_dig_value[2], p_dm_dig_table->pause_dig_value[1], p_dm_dig_table->pause_dig_value[0]));
+
+}
+
+static bool
+odm_dig_abort(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+
+ /* support_ability */
+ if (!(p_dm_odm->support_ability & ODM_BB_FA_CNT)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: support_ability ODM_BB_FA_CNT is disabled\n"));
+ return true;
+ }
+
+ /* support_ability */
+ if (!(p_dm_odm->support_ability & ODM_BB_DIG)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: support_ability ODM_BB_DIG is disabled\n"));
+ return true;
+ }
+
+ /* ScanInProcess */
+ if (*(p_dm_odm->p_is_scan_in_process)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: In Scan Progress\n"));
+ return true;
+ }
+
+ if (p_dm_dig_table->is_ignore_dig) {
+ p_dm_dig_table->is_ignore_dig = false;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: Ignore DIG\n"));
+ return true;
+ }
+
+ /* add by Neil Chen to avoid PSD is processing */
+ if (p_dm_odm->is_dm_initial_gain_enable == false) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: PSD is Processing\n"));
+ return true;
+ }
+
+#ifdef CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV
+ if ((p_dm_odm->is_linked) && (p_dm_odm->adapter->registrypriv.force_igi != 0)) {
+ printk("p_dm_odm->rssi_min=%d\n", p_dm_odm->rssi_min);
+ odm_write_dig(p_dm_odm, p_dm_odm->adapter->registrypriv.force_igi);
+ return true;
+ }
+#endif
+ return false;
+}
+
+void
+odm_dig_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+ u32 ret_value;
+ u8 i;
+
+ p_dm_dig_table->is_stop_dig = false;
+ p_dm_dig_table->is_ignore_dig = false;
+ p_dm_dig_table->is_psd_in_progress = false;
+ p_dm_dig_table->cur_ig_value = (u8) odm_get_bb_reg(p_dm_odm, ODM_REG(IGI_A, p_dm_odm), ODM_BIT(IGI, p_dm_odm));
+ p_dm_dig_table->pre_ig_value = 0;
+ p_dm_dig_table->rssi_low_thresh = DM_DIG_THRESH_LOW;
+ p_dm_dig_table->rssi_high_thresh = DM_DIG_THRESH_HIGH;
+ p_dm_dig_table->fa_low_thresh = DMfalseALARM_THRESH_LOW;
+ p_dm_dig_table->fa_high_thresh = DMfalseALARM_THRESH_HIGH;
+ p_dm_dig_table->backoff_val = DM_DIG_BACKOFF_DEFAULT;
+ p_dm_dig_table->backoff_val_range_max = DM_DIG_BACKOFF_MAX;
+ p_dm_dig_table->backoff_val_range_min = DM_DIG_BACKOFF_MIN;
+ p_dm_dig_table->pre_cck_cca_thres = 0xFF;
+ p_dm_dig_table->cur_cck_cca_thres = 0x83;
+ p_dm_dig_table->forbidden_igi = DM_DIG_MIN_NIC;
+ p_dm_dig_table->large_fa_hit = 0;
+ p_dm_dig_table->large_fa_timeout = 0;
+ p_dm_dig_table->recover_cnt = 0;
+ p_dm_dig_table->is_media_connect_0 = false;
+ p_dm_dig_table->is_media_connect_1 = false;
+
+ /* To Initialize p_dm_odm->is_dm_initial_gain_enable == false to avoid DIG error */
+ p_dm_odm->is_dm_initial_gain_enable = true;
+
+ p_dm_dig_table->dig_dynamic_min_0 = DM_DIG_MIN_NIC;
+ p_dm_dig_table->dig_dynamic_min_1 = DM_DIG_MIN_NIC;
+
+ /* To Initi BT30 IGI */
+ p_dm_dig_table->bt30_cur_igi = 0x32;
+
+ odm_memory_set(p_dm_odm, p_dm_dig_table->pause_dig_value, 0, (DM_DIG_MAX_PAUSE_TYPE + 1));
+ p_dm_dig_table->pause_dig_level = 0;
+ odm_memory_set(p_dm_odm, p_dm_dig_table->pause_cckpd_value, 0, (DM_DIG_MAX_PAUSE_TYPE + 1));
+ p_dm_dig_table->pause_cckpd_level = 0;
+
+ if (p_dm_odm->board_type & (ODM_BOARD_EXT_PA | ODM_BOARD_EXT_LNA)) {
+ p_dm_dig_table->rx_gain_range_max = DM_DIG_MAX_NIC;
+ p_dm_dig_table->rx_gain_range_min = DM_DIG_MIN_NIC;
+ } else {
+ p_dm_dig_table->rx_gain_range_max = DM_DIG_MAX_NIC;
+ p_dm_dig_table->rx_gain_range_min = DM_DIG_MIN_NIC;
+ }
+}
+
+
+void
+odm_DIG(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ /* Common parameters */
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+ struct false_ALARM_STATISTICS *p_false_alm_cnt = (struct false_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDMfalseALMCNT);
+ bool first_connect, first_dis_connect;
+ u8 dig_max_of_min, dig_dynamic_min;
+ u8 dm_dig_max, dm_dig_min;
+ u8 current_igi = p_dm_dig_table->cur_ig_value;
+ u8 offset;
+ u32 dm_FA_thres[3];
+ u32 tx_tp = 0, rx_tp = 0;
+ bool dig_go_up_check = true;
+ bool is_dfs_band = false;
+ bool is_performance = true, is_first_tp_target = false, is_first_coverage = false;
+
+ if (odm_dig_abort(p_dm_odm) == true)
+ return;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG()===========================>\n\n"));
+
+
+ /* 1 Update status */
+ {
+ dig_dynamic_min = p_dm_dig_table->dig_dynamic_min_0;
+ first_connect = (p_dm_odm->is_linked) && (p_dm_dig_table->is_media_connect_0 == false);
+ first_dis_connect = (!p_dm_odm->is_linked) && (p_dm_dig_table->is_media_connect_0 == true);
+ }
+
+
+ /* 1 Boundary Decision */
+ {
+ /* 2 For WIN\CE */
+ if (p_dm_odm->support_ic_type >= ODM_RTL8188E)
+ dm_dig_max = 0x5A;
+ else
+ dm_dig_max = DM_DIG_MAX_NIC;
+
+ if (p_dm_odm->support_ic_type != ODM_RTL8821)
+ dm_dig_min = DM_DIG_MIN_NIC;
+ else
+ dm_dig_min = 0x1C;
+
+ dig_max_of_min = DM_DIG_MAX_AP;
+
+ /* Modify lower bound for DFS band */
+ if ((((*p_dm_odm->p_channel >= 52) && (*p_dm_odm->p_channel <= 64)) ||
+ ((*p_dm_odm->p_channel >= 100) && (*p_dm_odm->p_channel <= 140)))
+ && phydm_dfs_master_enabled(p_dm_odm) == true
+ ) {
+ is_dfs_band = true;
+ if (*p_dm_odm->p_band_width == ODM_BW20M)
+ dm_dig_min = DM_DIG_MIN_AP_DFS + 2;
+ else
+ dm_dig_min = DM_DIG_MIN_AP_DFS;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): ====== In DFS band ======\n"));
+ }
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Absolutly upper bound = 0x%x, lower bound = 0x%x\n", dm_dig_max, dm_dig_min));
+
+ if (p_dm_odm->pu1_forced_igi_lb && (0 < *p_dm_odm->pu1_forced_igi_lb)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Force IGI lb to: 0x%02x !!!!!!\n", *p_dm_odm->pu1_forced_igi_lb));
+ dm_dig_min = *p_dm_odm->pu1_forced_igi_lb;
+ dm_dig_max = (dm_dig_min <= dm_dig_max) ? (dm_dig_max) : (dm_dig_min + 1);
+ }
+
+ /* 1 Adjust boundary by RSSI */
+ if (p_dm_odm->is_linked && is_performance) {
+ /* 2 Modify DIG upper bound */
+ /* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */
+ if ((p_dm_odm->support_ic_type & (ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8812 | ODM_RTL8821)) && (p_dm_odm->is_bt_limited_dig == 1)) {
+ offset = 10;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Coex. case: Force upper bound to RSSI + %d !!!!!!\n", offset));
+ } else
+ offset = 15;
+
+ if ((p_dm_odm->rssi_min + offset) > dm_dig_max)
+ p_dm_dig_table->rx_gain_range_max = dm_dig_max;
+ else if ((p_dm_odm->rssi_min + offset) < dm_dig_min)
+ p_dm_dig_table->rx_gain_range_max = dm_dig_min;
+ else
+ p_dm_dig_table->rx_gain_range_max = p_dm_odm->rssi_min + offset;
+
+ /* 2 Modify DIG lower bound */
+ /* if(p_dm_odm->is_one_entry_only) */
+ {
+ if (p_dm_odm->rssi_min < dm_dig_min)
+ dig_dynamic_min = dm_dig_min;
+ else if (p_dm_odm->rssi_min > dig_max_of_min)
+ dig_dynamic_min = dig_max_of_min;
+ else
+ dig_dynamic_min = p_dm_odm->rssi_min;
+
+ if (is_dfs_band) {
+ dig_dynamic_min = dm_dig_min;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): DFS band: Force lower bound to 0x%x after link !!!!!!\n", dm_dig_min));
+ }
+ }
+ } else {
+ if (is_performance && is_dfs_band) {
+ p_dm_dig_table->rx_gain_range_max = 0x28;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): DFS band: Force upper bound to 0x%x before link !!!!!!\n", p_dm_dig_table->rx_gain_range_max));
+ } else {
+ if (is_performance)
+ p_dm_dig_table->rx_gain_range_max = DM_DIG_MAX_OF_MIN;
+ else
+ p_dm_dig_table->rx_gain_range_max = dm_dig_max;
+ }
+ dig_dynamic_min = dm_dig_min;
+ }
+
+ /* 1 Force Lower Bound for AntDiv */
+ if (p_dm_odm->is_linked && !p_dm_odm->is_one_entry_only) {
+ if ((p_dm_odm->support_ic_type & ODM_ANTDIV_SUPPORT) && (p_dm_odm->support_ability & ODM_BB_ANT_DIV)) {
+ if (p_dm_odm->ant_div_type == CG_TRX_HW_ANTDIV || p_dm_odm->ant_div_type == CG_TRX_SMART_ANTDIV) {
+ if (p_dm_dig_table->ant_div_rssi_max > dig_max_of_min)
+ dig_dynamic_min = dig_max_of_min;
+ else
+ dig_dynamic_min = (u8) p_dm_dig_table->ant_div_rssi_max;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Antenna diversity case: Force lower bound to 0x%x !!!!!!\n", dig_dynamic_min));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Antenna diversity case: RSSI_max = 0x%x !!!!!!\n", p_dm_dig_table->ant_div_rssi_max));
+ }
+ }
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Adjust boundary by RSSI Upper bound = 0x%x, Lower bound = 0x%x\n",
+ p_dm_dig_table->rx_gain_range_max, dig_dynamic_min));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Link status: is_linked = %d, RSSI = %d, bFirstConnect = %d, bFirsrDisConnect = %d\n\n",
+ p_dm_odm->is_linked, p_dm_odm->rssi_min, first_connect, first_dis_connect));
+
+ /* 1 Modify DIG lower bound, deal with abnormal case */
+ /* 2 Abnormal false alarm case */
+ if (is_dfs_band)
+ p_dm_dig_table->rx_gain_range_min = dig_dynamic_min;
+ else
+ {
+ if (!p_dm_odm->is_linked) {
+ p_dm_dig_table->rx_gain_range_min = dig_dynamic_min;
+
+ if (first_dis_connect)
+ p_dm_dig_table->forbidden_igi = dig_dynamic_min;
+ } else
+ p_dm_dig_table->rx_gain_range_min = odm_forbidden_igi_check(p_dm_odm, dig_dynamic_min, current_igi);
+ }
+
+ /* 2 Abnormal # beacon case */
+ if (p_dm_odm->is_linked && !first_connect) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Beacon Num (%d)\n", p_dm_odm->phy_dbg_info.num_qry_beacon_pkt));
+ if ((p_dm_odm->phy_dbg_info.num_qry_beacon_pkt < 5) && (p_dm_odm->bsta_state)) {
+ p_dm_dig_table->rx_gain_range_min = 0x1c;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnrormal #beacon (%d) case in STA mode: Force lower bound to 0x%x !!!!!!\n\n",
+ p_dm_odm->phy_dbg_info.num_qry_beacon_pkt, p_dm_dig_table->rx_gain_range_min));
+ }
+ }
+
+ /* 2 Abnormal lower bound case */
+ if (p_dm_dig_table->rx_gain_range_min > p_dm_dig_table->rx_gain_range_max) {
+ p_dm_dig_table->rx_gain_range_min = p_dm_dig_table->rx_gain_range_max;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnrormal lower bound case: Force lower bound to 0x%x !!!!!!\n\n", p_dm_dig_table->rx_gain_range_min));
+ }
+
+
+ /* 1 False alarm threshold decision */
+ odm_fa_threshold_check(p_dm_odm, is_dfs_band, is_performance, rx_tp, tx_tp, dm_FA_thres);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): False alarm threshold = %d, %d, %d \n\n", dm_FA_thres[0], dm_FA_thres[1], dm_FA_thres[2]));
+
+ /* 1 Adjust initial gain by false alarm */
+ if (p_dm_odm->is_linked && is_performance) {
+ /* 2 After link */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Adjust IGI after link\n"));
+
+ if (is_first_tp_target || (first_connect && is_performance)) {
+ p_dm_dig_table->large_fa_hit = 0;
+
+ if (is_dfs_band) {
+ if (p_dm_odm->rssi_min > 0x28)
+ current_igi = 0x28;
+ else
+ current_igi = p_dm_odm->rssi_min;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): DFS band: One-shot to 0x28 upmost!!!!!!\n"));
+ } else {
+ if (p_dm_odm->rssi_min < dig_max_of_min) {
+ if (current_igi < p_dm_odm->rssi_min)
+ current_igi = p_dm_odm->rssi_min;
+ } else {
+ if (current_igi < dig_max_of_min)
+ current_igi = dig_max_of_min;
+ }
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): First connect case: IGI does on-shot to 0x%x\n", current_igi));
+
+ } else {
+ if ((p_false_alm_cnt->cnt_all > dm_FA_thres[2]) && dig_go_up_check)
+ current_igi = current_igi + 4;
+ else if ((p_false_alm_cnt->cnt_all > dm_FA_thres[1]) && dig_go_up_check)
+ current_igi = current_igi + 2;
+ else if (p_false_alm_cnt->cnt_all < dm_FA_thres[0])
+ current_igi = current_igi - 2;
+
+ /* 4 Abnormal # beacon case */
+ if ((p_dm_odm->phy_dbg_info.num_qry_beacon_pkt < 5) && (p_false_alm_cnt->cnt_all < DM_DIG_FA_TH1) && (p_dm_odm->bsta_state)) {
+ current_igi = p_dm_dig_table->rx_gain_range_min;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnormal #beacon (%d) case: IGI does one-shot to 0x%x\n",
+ p_dm_odm->phy_dbg_info.num_qry_beacon_pkt, current_igi));
+ }
+ }
+ } else {
+ /* 2 Before link */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Adjust IGI before link\n"));
+
+ if (first_dis_connect || is_first_coverage) {
+ current_igi = dm_dig_min;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): First disconnect case: IGI does on-shot to lower bound\n"));
+ } else {
+ if ((p_false_alm_cnt->cnt_all > dm_FA_thres[2]) && dig_go_up_check)
+ current_igi = current_igi + 4;
+ else if ((p_false_alm_cnt->cnt_all > dm_FA_thres[1]) && dig_go_up_check)
+ current_igi = current_igi + 2;
+ else if (p_false_alm_cnt->cnt_all < dm_FA_thres[0])
+ current_igi = current_igi - 2;
+ }
+ }
+
+ /* 1 Check initial gain by upper/lower bound */
+ if (current_igi < p_dm_dig_table->rx_gain_range_min)
+ current_igi = p_dm_dig_table->rx_gain_range_min;
+
+ if (current_igi > p_dm_dig_table->rx_gain_range_max)
+ current_igi = p_dm_dig_table->rx_gain_range_max;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): cur_ig_value=0x%x, TotalFA = %d\n\n", current_igi, p_false_alm_cnt->cnt_all));
+
+ /* 1 Update status */
+ {
+#if (((ODM_CONFIG_BT_COEXIST == 1)))
+ if (p_dm_odm->is_bt_hs_operation) {
+ if (p_dm_odm->is_linked) {
+ if (p_dm_dig_table->bt30_cur_igi > (current_igi))
+ odm_write_dig(p_dm_odm, current_igi);
+ else
+ odm_write_dig(p_dm_odm, p_dm_dig_table->bt30_cur_igi);
+
+ p_dm_dig_table->is_media_connect_0 = p_dm_odm->is_linked;
+ p_dm_dig_table->dig_dynamic_min_0 = dig_dynamic_min;
+ } else {
+ if (p_dm_odm->is_link_in_process)
+ odm_write_dig(p_dm_odm, 0x1c);
+ else if (p_dm_odm->is_bt_connect_process)
+ odm_write_dig(p_dm_odm, 0x28);
+ else
+ odm_write_dig(p_dm_odm, p_dm_dig_table->bt30_cur_igi);/* odm_write_dig(p_dm_odm, p_dm_dig_table->cur_ig_value); */
+ }
+ } else /* BT is not using */
+#endif
+ {
+ odm_write_dig(p_dm_odm, current_igi);/* odm_write_dig(p_dm_odm, p_dm_dig_table->cur_ig_value); */
+ p_dm_dig_table->is_media_connect_0 = p_dm_odm->is_linked;
+ p_dm_dig_table->dig_dynamic_min_0 = dig_dynamic_min;
+ }
+ }
+}
+
+void
+odm_dig_by_rssi_lps(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct false_ALARM_STATISTICS *p_false_alm_cnt = (struct false_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDMfalseALMCNT);
+
+ u8 rssi_lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */
+ u8 current_igi = p_dm_odm->rssi_min;
+
+ if (odm_dig_abort(p_dm_odm) == true)
+ return;
+
+ current_igi = current_igi + RSSI_OFFSET_DIG;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_dig_by_rssi_lps()==>\n"));
+
+ /* Using FW PS mode to make IGI */
+ /* Adjust by FA in LPS MODE */
+ if (p_false_alm_cnt->cnt_all > DM_DIG_FA_TH2_LPS)
+ current_igi = current_igi + 4;
+ else if (p_false_alm_cnt->cnt_all > DM_DIG_FA_TH1_LPS)
+ current_igi = current_igi + 2;
+ else if (p_false_alm_cnt->cnt_all < DM_DIG_FA_TH0_LPS)
+ current_igi = current_igi - 2;
+
+
+ /* Lower bound checking */
+
+ /* RSSI Lower bound check */
+ if ((p_dm_odm->rssi_min - 10) > DM_DIG_MIN_NIC)
+ rssi_lower = (p_dm_odm->rssi_min - 10);
+ else
+ rssi_lower = DM_DIG_MIN_NIC;
+
+ /* Upper and Lower Bound checking */
+ if (current_igi > DM_DIG_MAX_NIC)
+ current_igi = DM_DIG_MAX_NIC;
+ else if (current_igi < rssi_lower)
+ current_igi = rssi_lower;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_dig_by_rssi_lps(): p_false_alm_cnt->cnt_all = %d\n", p_false_alm_cnt->cnt_all));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_dig_by_rssi_lps(): p_dm_odm->rssi_min = %d\n", p_dm_odm->rssi_min));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_dig_by_rssi_lps(): current_igi = 0x%x\n", current_igi));
+
+ odm_write_dig(p_dm_odm, current_igi);/* odm_write_dig(p_dm_odm, p_dm_dig_table->cur_ig_value); */
+}
+
+/* 3============================================================
+ * 3 FASLE ALARM CHECK
+ * 3============================================================ */
+
+void
+odm_false_alarm_counter_statistics(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct false_ALARM_STATISTICS *false_alm_cnt = (struct false_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDMfalseALMCNT);
+#if (PHYDM_LA_MODE_SUPPORT == 1)
+ struct _RT_ADCSMP *adc_smp = &(p_dm_odm->adcsmp);
+#endif
+ u32 ret_value;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_FA_CNT))
+ return;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics()======>\n"));
+
+#if (ODM_IC_11N_SERIES_SUPPORT == 1)
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
+
+ /* hold ofdm counter */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1); /* hold page C counter */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 1); /* hold page D counter */
+
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_TYPE1_11N, MASKDWORD);
+ false_alm_cnt->cnt_fast_fsync = (ret_value & 0xffff);
+ false_alm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16);
+
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_TYPE2_11N, MASKDWORD);
+ false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff);
+ false_alm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
+
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_TYPE3_11N, MASKDWORD);
+ false_alm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
+ false_alm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
+
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_TYPE4_11N, MASKDWORD);
+ false_alm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
+
+ false_alm_cnt->cnt_ofdm_fail = false_alm_cnt->cnt_parity_fail + false_alm_cnt->cnt_rate_illegal +
+ false_alm_cnt->cnt_crc8_fail + false_alm_cnt->cnt_mcs_fail +
+ false_alm_cnt->cnt_fast_fsync + false_alm_cnt->cnt_sb_search_fail;
+
+ /* read CCK CRC32 counter */
+ false_alm_cnt->cnt_cck_crc32_error = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_CRC32_ERROR_CNT_11N, MASKDWORD);
+ false_alm_cnt->cnt_cck_crc32_ok = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_CRC32_OK_CNT_11N, MASKDWORD);
+
+ /* read OFDM CRC32 counter */
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_OFDM_CRC32_CNT_11N, MASKDWORD);
+ false_alm_cnt->cnt_ofdm_crc32_error = (ret_value & 0xffff0000) >> 16;
+ false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff;
+
+ /* read HT CRC32 counter */
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_HT_CRC32_CNT_11N, MASKDWORD);
+ false_alm_cnt->cnt_ht_crc32_error = (ret_value & 0xffff0000) >> 16;
+ false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff;
+
+ /* read VHT CRC32 counter */
+ false_alm_cnt->cnt_vht_crc32_error = 0;
+ false_alm_cnt->cnt_vht_crc32_ok = 0;
+
+#if (RTL8188E_SUPPORT == 1)
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E) {
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_SC_CNT_11N, MASKDWORD);
+ false_alm_cnt->cnt_bw_lsc = (ret_value & 0xffff);
+ false_alm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16);
+ }
+#endif
+
+ {
+ /* hold cck counter */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11N, BIT(12), 1);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11N, BIT(14), 1);
+
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_FA_LSB_11N, MASKBYTE0);
+ false_alm_cnt->cnt_cck_fail = ret_value;
+
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_FA_MSB_11N, MASKBYTE3);
+ false_alm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
+
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_CCA_CNT_11N, MASKDWORD);
+ false_alm_cnt->cnt_cck_cca = ((ret_value & 0xFF) << 8) | ((ret_value & 0xFF00) >> 8);
+ }
+
+ false_alm_cnt->cnt_all_pre = false_alm_cnt->cnt_all;
+
+ false_alm_cnt->cnt_all = (false_alm_cnt->cnt_fast_fsync +
+ false_alm_cnt->cnt_sb_search_fail +
+ false_alm_cnt->cnt_parity_fail +
+ false_alm_cnt->cnt_rate_illegal +
+ false_alm_cnt->cnt_crc8_fail +
+ false_alm_cnt->cnt_mcs_fail +
+ false_alm_cnt->cnt_cck_fail);
+
+ false_alm_cnt->cnt_cca_all = false_alm_cnt->cnt_ofdm_cca + false_alm_cnt->cnt_cck_cca;
+
+ if (p_dm_odm->support_ic_type >= ODM_RTL8188E) {
+ /*reset false alarm counter registers*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31), 1);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31), 0);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), 1);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), 0);
+
+ /*update ofdm counter*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0); /*update page C counter*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 0); /*update page D counter*/
+
+ /*reset CCK CCA counter*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2);
+
+ /*reset CCK FA counter*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2);
+
+ /*reset CRC32 counter*/
+ odm_set_bb_reg(p_dm_odm, ODM_REG_PAGE_F_RST_11N, BIT(16), 1);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_PAGE_F_RST_11N, BIT(16), 0);
+ }
+
+ /* Get debug port 0 */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x0);
+ false_alm_cnt->dbg_port0 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11N, MASKDWORD);
+
+ /* Get EDCCA flag */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x208);
+ false_alm_cnt->edcca_flag = (bool)odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11N, BIT(30));
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): cnt_fast_fsync=%d, cnt_sb_search_fail=%d\n",
+ false_alm_cnt->cnt_fast_fsync, false_alm_cnt->cnt_sb_search_fail));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): cnt_parity_fail=%d, cnt_rate_illegal=%d\n",
+ false_alm_cnt->cnt_parity_fail, false_alm_cnt->cnt_rate_illegal));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): cnt_crc8_fail=%d, cnt_mcs_fail=%d\n",
+ false_alm_cnt->cnt_crc8_fail, false_alm_cnt->cnt_mcs_fail));
+ }
+#endif
+
+#if (ODM_IC_11AC_SERIES_SUPPORT == 1)
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
+ u32 cck_enable;
+
+ /* read OFDM FA counter */
+ false_alm_cnt->cnt_ofdm_fail = odm_get_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_11AC, MASKLWORD);
+
+ /* Read CCK FA counter */
+ false_alm_cnt->cnt_cck_fail = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_FA_11AC, MASKLWORD);
+
+ /* read CCK/OFDM CCA counter */
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_CCA_CNT_11AC, MASKDWORD);
+ false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff0000) >> 16;
+ false_alm_cnt->cnt_cck_cca = ret_value & 0xffff;
+
+ /* read CCK CRC32 counter */
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_CRC32_CNT_11AC, MASKDWORD);
+ false_alm_cnt->cnt_cck_crc32_error = (ret_value & 0xffff0000) >> 16;
+ false_alm_cnt->cnt_cck_crc32_ok = ret_value & 0xffff;
+
+ /* read OFDM CRC32 counter */
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_OFDM_CRC32_CNT_11AC, MASKDWORD);
+ false_alm_cnt->cnt_ofdm_crc32_error = (ret_value & 0xffff0000) >> 16;
+ false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff;
+
+ /* read HT CRC32 counter */
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_HT_CRC32_CNT_11AC, MASKDWORD);
+ false_alm_cnt->cnt_ht_crc32_error = (ret_value & 0xffff0000) >> 16;
+ false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff;
+
+ /* read VHT CRC32 counter */
+ ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_VHT_CRC32_CNT_11AC, MASKDWORD);
+ false_alm_cnt->cnt_vht_crc32_error = (ret_value & 0xffff0000) >> 16;
+ false_alm_cnt->cnt_vht_crc32_ok = ret_value & 0xffff;
+
+#if (RTL8881A_SUPPORT == 1)
+ /* For 8881A */
+ if (p_dm_odm->support_ic_type == ODM_RTL8881A) {
+ u32 cnt_ofdm_fail_temp = 0;
+
+ if (false_alm_cnt->cnt_ofdm_fail >= false_alm_cnt->cnt_ofdm_fail_pre) {
+ cnt_ofdm_fail_temp = false_alm_cnt->cnt_ofdm_fail_pre;
+ false_alm_cnt->cnt_ofdm_fail_pre = false_alm_cnt->cnt_ofdm_fail;
+ false_alm_cnt->cnt_ofdm_fail = false_alm_cnt->cnt_ofdm_fail - cnt_ofdm_fail_temp;
+ } else
+ false_alm_cnt->cnt_ofdm_fail_pre = false_alm_cnt->cnt_ofdm_fail;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): cnt_ofdm_fail=%d\n", false_alm_cnt->cnt_ofdm_fail_pre));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): cnt_ofdm_fail_pre=%d\n", cnt_ofdm_fail_temp));
+
+ /* Reset FA counter by enable/disable OFDM */
+ if (false_alm_cnt->cnt_ofdm_fail_pre >= 0x7fff) {
+ /* reset OFDM */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_BB_RX_PATH_11AC, BIT(29), 0);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_BB_RX_PATH_11AC, BIT(29), 1);
+ false_alm_cnt->cnt_ofdm_fail_pre = 0;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): Reset false alarm counter\n"));
+ }
+ }
+#endif
+
+ /* reset OFDM FA coutner */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0);
+
+ /* reset CCK FA counter */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1);
+
+ /* reset CCA counter */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_RST_RPT_11AC, BIT(0), 1);
+ odm_set_bb_reg(p_dm_odm, ODM_REG_RST_RPT_11AC, BIT(0), 0);
+
+ cck_enable = odm_get_bb_reg(p_dm_odm, ODM_REG_BB_RX_PATH_11AC, BIT(28));
+ if (cck_enable) { /* if(*p_dm_odm->p_band_type == ODM_BAND_2_4G) */
+ false_alm_cnt->cnt_all = false_alm_cnt->cnt_ofdm_fail + false_alm_cnt->cnt_cck_fail;
+ false_alm_cnt->cnt_cca_all = false_alm_cnt->cnt_cck_cca + false_alm_cnt->cnt_ofdm_cca;
+ } else {
+ false_alm_cnt->cnt_all = false_alm_cnt->cnt_ofdm_fail;
+ false_alm_cnt->cnt_cca_all = false_alm_cnt->cnt_ofdm_cca;
+ }
+
+#if (PHYDM_LA_MODE_SUPPORT == 1)
+ if (adc_smp->adc_smp_state == ADCSMP_STATE_IDLE)
+#endif
+ {
+ /* Get debug port 0 */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x0);
+ false_alm_cnt->dbg_port0 = odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, MASKDWORD);
+
+ /* Get EDCCA flag */
+ odm_set_bb_reg(p_dm_odm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x209);
+ false_alm_cnt->edcca_flag = (bool)odm_get_bb_reg(p_dm_odm, ODM_REG_RPT_11AC, BIT(30));
+ }
+
+ }
+#endif
+
+
+ false_alm_cnt->cnt_crc32_error_all = false_alm_cnt->cnt_vht_crc32_error + false_alm_cnt->cnt_ht_crc32_error + false_alm_cnt->cnt_ofdm_crc32_error + false_alm_cnt->cnt_cck_crc32_error;
+ false_alm_cnt->cnt_crc32_ok_all = false_alm_cnt->cnt_vht_crc32_ok + false_alm_cnt->cnt_ht_crc32_ok + false_alm_cnt->cnt_ofdm_crc32_ok + false_alm_cnt->cnt_cck_crc32_ok;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): cnt_ofdm_cca=%d\n", false_alm_cnt->cnt_ofdm_cca));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): cnt_cck_cca=%d\n", false_alm_cnt->cnt_cck_cca));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): cnt_cca_all=%d\n", false_alm_cnt->cnt_cca_all));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): cnt_ofdm_fail=%d\n", false_alm_cnt->cnt_ofdm_fail));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): cnt_cck_fail=%d\n", false_alm_cnt->cnt_cck_fail));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): cnt_ofdm_fail=%d\n", false_alm_cnt->cnt_ofdm_fail));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): Total False Alarm=%d\n", false_alm_cnt->cnt_all));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): CCK CRC32 fail: %d, ok: %d\n", false_alm_cnt->cnt_cck_crc32_error, false_alm_cnt->cnt_cck_crc32_ok));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): OFDM CRC32 fail: %d, ok: %d\n", false_alm_cnt->cnt_ofdm_crc32_error, false_alm_cnt->cnt_ofdm_crc32_ok));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): HT CRC32 fail: %d, ok: %d\n", false_alm_cnt->cnt_ht_crc32_error, false_alm_cnt->cnt_ht_crc32_ok));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): VHT CRC32 fail: %d, ok: %d\n", false_alm_cnt->cnt_vht_crc32_error, false_alm_cnt->cnt_vht_crc32_ok));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): Total CRC32 fail: %d, ok: %d\n", false_alm_cnt->cnt_crc32_error_all, false_alm_cnt->cnt_crc32_ok_all));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): dbg port 0x0 = 0x%x, EDCCA = %d\n\n", false_alm_cnt->dbg_port0, false_alm_cnt->edcca_flag));
+}
+
+/* 3============================================================
+ * 3 CCK Packet Detect threshold
+ * 3============================================================ */
+
+void
+odm_pause_cck_packet_detection(
+ void *p_dm_void,
+ enum phydm_pause_type pause_type,
+ enum phydm_pause_level pause_level,
+ u8 cck_pd_threshold
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection()=========> level = %d\n", pause_level));
+
+ if ((p_dm_dig_table->pause_cckpd_level == 0) && (!(p_dm_odm->support_ability & ODM_BB_CCK_PD) || !(p_dm_odm->support_ability & ODM_BB_FA_CNT))) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Return: support_ability ODM_BB_CCK_PD or ODM_BB_FA_CNT is disabled\n"));
+ return;
+ }
+
+ if (pause_level > DM_DIG_MAX_PAUSE_TYPE) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD,
+ ("odm_pause_cck_packet_detection(): Return: Wrong pause level !!\n"));
+ return;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): pause level = 0x%x, Current value = 0x%x\n", p_dm_dig_table->pause_cckpd_level, cck_pd_threshold));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ p_dm_dig_table->pause_cckpd_value[7], p_dm_dig_table->pause_cckpd_value[6], p_dm_dig_table->pause_cckpd_value[5], p_dm_dig_table->pause_cckpd_value[4],
+ p_dm_dig_table->pause_cckpd_value[3], p_dm_dig_table->pause_cckpd_value[2], p_dm_dig_table->pause_cckpd_value[1], p_dm_dig_table->pause_cckpd_value[0]));
+
+ switch (pause_type) {
+ /* Pause CCK Packet Detection threshold */
+ case PHYDM_PAUSE:
+ {
+ /* Disable CCK PD */
+ odm_cmn_info_update(p_dm_odm, ODM_CMNINFO_ABILITY, p_dm_odm->support_ability & (~ODM_BB_CCK_PD));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): Pause CCK packet detection threshold !!\n"));
+
+ /* Backup original CCK PD threshold decided by CCK PD mechanism */
+ if (p_dm_dig_table->pause_cckpd_level == 0) {
+ p_dm_dig_table->cck_pd_backup = p_dm_dig_table->cur_cck_cca_thres;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD,
+ ("odm_pause_cck_packet_detection(): Backup CCKPD = 0x%x, new CCKPD = 0x%x\n", p_dm_dig_table->cck_pd_backup, cck_pd_threshold));
+ }
+
+ /* Update pause level */
+ p_dm_dig_table->pause_cckpd_level = (p_dm_dig_table->pause_cckpd_level | BIT(pause_level));
+
+ /* Record CCK PD threshold */
+ p_dm_dig_table->pause_cckpd_value[pause_level] = cck_pd_threshold;
+
+ /* Write new CCK PD threshold */
+ if (BIT(pause_level + 1) > p_dm_dig_table->pause_cckpd_level) {
+ odm_write_cck_cca_thres(p_dm_odm, cck_pd_threshold);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): CCKPD of higher level = 0x%x\n", cck_pd_threshold));
+ }
+ break;
+ }
+ /* Resume CCK Packet Detection threshold */
+ case PHYDM_RESUME:
+ {
+ /* check if the level is illegal or not */
+ if ((p_dm_dig_table->pause_cckpd_level & (BIT(pause_level))) != 0) {
+ p_dm_dig_table->pause_cckpd_level = p_dm_dig_table->pause_cckpd_level & (~(BIT(pause_level)));
+ p_dm_dig_table->pause_cckpd_value[pause_level] = 0;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): Resume CCK PD !!\n"));
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): Wrong resume level !!\n"));
+ break;
+ }
+
+ /* Resume DIG */
+ if (p_dm_dig_table->pause_cckpd_level == 0) {
+ /* Write backup IGI value */
+ odm_write_cck_cca_thres(p_dm_odm, p_dm_dig_table->cck_pd_backup);
+ /* p_dm_dig_table->is_ignore_dig = true; */
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): Write original CCKPD = 0x%x\n", p_dm_dig_table->cck_pd_backup));
+
+ /* Enable DIG */
+ odm_cmn_info_update(p_dm_odm, ODM_CMNINFO_ABILITY, p_dm_odm->support_ability | ODM_BB_CCK_PD);
+ break;
+ }
+
+ if (BIT(pause_level) > p_dm_dig_table->pause_cckpd_level) {
+ s8 max_level;
+
+ /* Calculate the maximum level now */
+ for (max_level = (pause_level - 1); max_level >= 0; max_level--) {
+ if ((p_dm_dig_table->pause_cckpd_level & BIT(max_level)) > 0)
+ break;
+ }
+
+ /* write CCKPD of lower level */
+ odm_write_cck_cca_thres(p_dm_odm, p_dm_dig_table->pause_cckpd_value[max_level]);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): Write CCKPD (0x%x) of level (%d)\n",
+ p_dm_dig_table->pause_cckpd_value[max_level], max_level));
+ break;
+ }
+ break;
+ }
+ default:
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): Wrong type !!\n"));
+ break;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): pause level = 0x%x, Current value = 0x%x\n", p_dm_dig_table->pause_cckpd_level, cck_pd_threshold));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ p_dm_dig_table->pause_cckpd_value[7], p_dm_dig_table->pause_cckpd_value[6], p_dm_dig_table->pause_cckpd_value[5], p_dm_dig_table->pause_cckpd_value[4],
+ p_dm_dig_table->pause_cckpd_value[3], p_dm_dig_table->pause_cckpd_value[2], p_dm_dig_table->pause_cckpd_value[1], p_dm_dig_table->pause_cckpd_value[0]));
+}
+
+
+void
+odm_cck_packet_detection_thresh(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+ struct false_ALARM_STATISTICS *false_alm_cnt = (struct false_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDMfalseALMCNT);
+ u8 cur_cck_cca_thres = p_dm_dig_table->cur_cck_cca_thres, RSSI_thd = 35;
+
+ if ((!(p_dm_odm->support_ability & ODM_BB_CCK_PD)) || (!(p_dm_odm->support_ability & ODM_BB_FA_CNT))) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_cck_packet_detection_thresh() return==========\n"));
+#ifdef MCR_WIRELESS_EXTEND
+ odm_write_cck_cca_thres(p_dm_odm, 0x43);
+#endif
+ return;
+ }
+
+ if (p_dm_odm->ext_lna)
+ return;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_cck_packet_detection_thresh() ==========>\n"));
+
+ if (p_dm_dig_table->cck_fa_ma == 0xffffffff)
+ p_dm_dig_table->cck_fa_ma = false_alm_cnt->cnt_cck_fail;
+ else
+ p_dm_dig_table->cck_fa_ma = ((p_dm_dig_table->cck_fa_ma << 1) + p_dm_dig_table->cck_fa_ma + false_alm_cnt->cnt_cck_fail) >> 2;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_cck_packet_detection_thresh(): CCK FA moving average = %d\n", p_dm_dig_table->cck_fa_ma));
+
+ if (p_dm_odm->is_linked) {
+ if (p_dm_odm->rssi_min > RSSI_thd)
+ cur_cck_cca_thres = 0xcd;
+ else if (p_dm_odm->rssi_min > 20) {
+ if (p_dm_dig_table->cck_fa_ma > ((DM_DIG_FA_TH1 >> 1) + (DM_DIG_FA_TH1 >> 3)))
+ cur_cck_cca_thres = 0xcd;
+ else if (p_dm_dig_table->cck_fa_ma < (DM_DIG_FA_TH0 >> 1))
+ cur_cck_cca_thres = 0x83;
+ } else if (p_dm_odm->rssi_min > 7)
+ cur_cck_cca_thres = 0x83;
+ else
+ cur_cck_cca_thres = 0x40;
+ } else {
+ if (p_dm_dig_table->cck_fa_ma > 0x400)
+ cur_cck_cca_thres = 0x83;
+ else if (p_dm_dig_table->cck_fa_ma < 0x200)
+ cur_cck_cca_thres = 0x40;
+ }
+
+ odm_write_cck_cca_thres(p_dm_odm, cur_cck_cca_thres);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_cck_packet_detection_thresh() cur_cck_cca_thres = 0x%x\n", cur_cck_cca_thres));
+}
+
+void
+odm_write_cck_cca_thres(
+ void *p_dm_void,
+ u8 cur_cck_cca_thres
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+
+ if (p_dm_dig_table->cur_cck_cca_thres != cur_cck_cca_thres) { /* modify by Guo.Mingzhi 2012-01-03 */
+ odm_write_1byte(p_dm_odm, ODM_REG(CCK_CCA, p_dm_odm), cur_cck_cca_thres);
+ p_dm_dig_table->cck_fa_ma = 0xffffffff;
+ }
+ p_dm_dig_table->pre_cck_cca_thres = p_dm_dig_table->cur_cck_cca_thres;
+ p_dm_dig_table->cur_cck_cca_thres = cur_cck_cca_thres;
+}
+
+bool
+phydm_dig_go_up_check(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _CCX_INFO *ccx_info = &p_dm_odm->dm_ccx_info;
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
+ u8 cur_ig_value = p_dm_dig_table->cur_ig_value;
+ u8 max_DIG_cover_bond;
+ u8 current_igi_max_up_resolution;
+ u8 rx_gain_range_max;
+ u8 i = 0;
+
+ u32 total_NHM_cnt;
+ u32 DIG_cover_cnt;
+ u32 over_DIG_cover_cnt;
+ bool ret = true;
+
+ return ret;
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_dig.h b/drivers/staging/rtl8188eu/hal/phydm_dig.h
new file mode 100644
index 000000000000..bf7659530bdd
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_dig.h
@@ -0,0 +1,292 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMDIG_H__
+#define __PHYDMDIG_H__
+
+#define DIG_VERSION "1.3" /* 2016.08.16 YuChen. Modify IGI lower bound to 0x1e for 8197F asked by RF Arthur*/
+
+/* Pause DIG & CCKPD */
+#define DM_DIG_MAX_PAUSE_TYPE 0x7
+
+enum dig_goupcheck_level {
+
+ DIG_GOUPCHECK_LEVEL_0,
+ DIG_GOUPCHECK_LEVEL_1,
+ DIG_GOUPCHECK_LEVEL_2
+
+};
+
+struct _dynamic_initial_gain_threshold_ {
+ bool is_stop_dig; /* for debug */
+ bool is_ignore_dig;
+ bool is_psd_in_progress;
+
+ u8 dig_enable_flag;
+ u8 dig_ext_port_stage;
+
+ int rssi_low_thresh;
+ int rssi_high_thresh;
+
+ u32 fa_low_thresh;
+ u32 fa_high_thresh;
+
+ u8 cur_sta_connect_state;
+ u8 pre_sta_connect_state;
+ u8 cur_multi_sta_connect_state;
+
+ u8 pre_ig_value;
+ u8 cur_ig_value;
+ u8 backup_ig_value; /* MP DIG */
+ u8 bt30_cur_igi;
+ u8 igi_backup;
+
+ s8 backoff_val;
+ s8 backoff_val_range_max;
+ s8 backoff_val_range_min;
+ u8 rx_gain_range_max;
+ u8 rx_gain_range_min;
+ u8 rssi_val_min;
+
+ u8 pre_cck_cca_thres;
+ u8 cur_cck_cca_thres;
+ u8 pre_cck_pd_state;
+ u8 cur_cck_pd_state;
+ u8 cck_pd_backup;
+ u8 pause_cckpd_level;
+ u8 pause_cckpd_value[DM_DIG_MAX_PAUSE_TYPE + 1];
+
+ u8 large_fa_hit;
+ u8 large_fa_timeout; /*if (large_fa_hit), monitor "large_fa_timeout" sec, if timeout, large_fa_hit=0*/
+ u8 forbidden_igi;
+ u32 recover_cnt;
+
+ u8 dig_dynamic_min_0;
+ u8 dig_dynamic_min_1;
+ bool is_media_connect_0;
+ bool is_media_connect_1;
+
+ u32 ant_div_rssi_max;
+ u32 RSSI_max;
+
+ u8 *is_p2p_in_process;
+
+ u8 pause_dig_level;
+ u8 pause_dig_value[DM_DIG_MAX_PAUSE_TYPE + 1];
+
+ u32 cck_fa_ma;
+ enum dig_goupcheck_level dig_go_up_check_level;
+};
+
+struct false_ALARM_STATISTICS {
+ u32 cnt_parity_fail;
+ u32 cnt_rate_illegal;
+ u32 cnt_crc8_fail;
+ u32 cnt_mcs_fail;
+ u32 cnt_ofdm_fail;
+ u32 cnt_ofdm_fail_pre; /* For RTL8881A */
+ u32 cnt_cck_fail;
+ u32 cnt_all;
+ u32 cnt_all_pre;
+ u32 cnt_fast_fsync;
+ u32 cnt_sb_search_fail;
+ u32 cnt_ofdm_cca;
+ u32 cnt_cck_cca;
+ u32 cnt_cca_all;
+ u32 cnt_bw_usc; /* Gary */
+ u32 cnt_bw_lsc; /* Gary */
+ u32 cnt_cck_crc32_error;
+ u32 cnt_cck_crc32_ok;
+ u32 cnt_ofdm_crc32_error;
+ u32 cnt_ofdm_crc32_ok;
+ u32 cnt_ht_crc32_error;
+ u32 cnt_ht_crc32_ok;
+ u32 cnt_vht_crc32_error;
+ u32 cnt_vht_crc32_ok;
+ u32 cnt_crc32_error_all;
+ u32 cnt_crc32_ok_all;
+ bool cck_block_enable;
+ bool ofdm_block_enable;
+ u32 dbg_port0;
+ bool edcca_flag;
+};
+
+enum dm_dig_op_e {
+ DIG_TYPE_THRESH_HIGH = 0,
+ DIG_TYPE_THRESH_LOW = 1,
+ DIG_TYPE_BACKOFF = 2,
+ DIG_TYPE_RX_GAIN_MIN = 3,
+ DIG_TYPE_RX_GAIN_MAX = 4,
+ DIG_TYPE_ENABLE = 5,
+ DIG_TYPE_DISABLE = 6,
+ DIG_OP_TYPE_MAX
+};
+
+/*
+enum dm_cck_pdth_e
+{
+ CCK_PD_STAGE_LowRssi = 0,
+ CCK_PD_STAGE_HighRssi = 1,
+ CCK_PD_STAGE_MAX = 3,
+};
+
+enum dm_dig_ext_port_alg_e
+{
+ DIG_EXT_PORT_STAGE_0 = 0,
+ DIG_EXT_PORT_STAGE_1 = 1,
+ DIG_EXT_PORT_STAGE_2 = 2,
+ DIG_EXT_PORT_STAGE_3 = 3,
+ DIG_EXT_PORT_STAGE_MAX = 4,
+};
+
+enum dm_dig_connect_e
+{
+ DIG_STA_DISCONNECT = 0,
+ DIG_STA_CONNECT = 1,
+ DIG_STA_BEFORE_CONNECT = 2,
+ dig_multi_sta_disconnect = 3,
+ dig_multi_sta_connect = 4,
+ DIG_CONNECT_MAX
+};
+
+
+#define DM_MultiSTA_InitGainChangeNotify(Event) {dm_dig_table.cur_multi_sta_connect_state = Event;}
+
+#define DM_MultiSTA_InitGainChangeNotify_CONNECT(_ADAPTER) \
+ DM_MultiSTA_InitGainChangeNotify(dig_multi_sta_connect)
+
+#define DM_MultiSTA_InitGainChangeNotify_DISCONNECT(_ADAPTER) \
+ DM_MultiSTA_InitGainChangeNotify(dig_multi_sta_disconnect)
+*/
+
+enum phydm_pause_type {
+ PHYDM_PAUSE = BIT(0),
+ PHYDM_RESUME = BIT(1)
+};
+
+enum phydm_pause_level {
+ /* number of pause level can't exceed DM_DIG_MAX_PAUSE_TYPE */
+ PHYDM_PAUSE_LEVEL_0 = 0,
+ PHYDM_PAUSE_LEVEL_1 = 1,
+ PHYDM_PAUSE_LEVEL_2 = 2,
+ PHYDM_PAUSE_LEVEL_3 = 3,
+ PHYDM_PAUSE_LEVEL_4 = 4,
+ PHYDM_PAUSE_LEVEL_5 = 5,
+ PHYDM_PAUSE_LEVEL_6 = 6,
+ PHYDM_PAUSE_LEVEL_7 = DM_DIG_MAX_PAUSE_TYPE /* maximum level */
+};
+
+#define DM_DIG_THRESH_HIGH 40
+#define DM_DIG_THRESH_LOW 35
+
+#define DMfalseALARM_THRESH_LOW 400
+#define DMfalseALARM_THRESH_HIGH 1000
+
+#define DM_DIG_MAX_NIC 0x3e
+#define DM_DIG_MIN_NIC 0x20
+#define DM_DIG_MAX_OF_MIN_NIC 0x3e
+
+#define DM_DIG_MAX_AP 0x3e
+#define DM_DIG_MIN_AP 0x20
+#define DM_DIG_MAX_OF_MIN 0x2A /* 0x32 */
+#define DM_DIG_MIN_AP_DFS 0x20
+
+#define DM_DIG_MAX_NIC_HP 0x46
+#define DM_DIG_MIN_NIC_HP 0x2e
+
+#define DM_DIG_MAX_AP_HP 0x42
+#define DM_DIG_MIN_AP_HP 0x30
+
+/* vivi 92c&92d has different definition, 20110504
+ * this is for 92c */
+#ifdef CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV
+ #define DM_DIG_FA_TH0 0x80/* 0x20 */
+#else
+ #define DM_DIG_FA_TH0 0x200/* 0x20 */
+#endif
+
+#define DM_DIG_FA_TH1 0x300
+#define DM_DIG_FA_TH2 0x400
+/* this is for 92d */
+#define DM_DIG_FA_TH0_92D 0x100
+#define DM_DIG_FA_TH1_92D 0x400
+#define DM_DIG_FA_TH2_92D 0x600
+
+#define DM_DIG_BACKOFF_MAX 12
+#define DM_DIG_BACKOFF_MIN -4
+#define DM_DIG_BACKOFF_DEFAULT 10
+
+#define DM_DIG_FA_TH0_LPS 4 /* -> 4 in lps */
+#define DM_DIG_FA_TH1_LPS 15 /* -> 15 lps */
+#define DM_DIG_FA_TH2_LPS 30 /* -> 30 lps */
+#define RSSI_OFFSET_DIG 0x05
+#define LARGE_FA_TIMEOUT 60
+
+
+void
+odm_change_dynamic_init_gain_thresh(
+ void *p_dm_void,
+ u32 dm_type,
+ u32 dm_value
+);
+
+void
+odm_write_dig(
+ void *p_dm_void,
+ u8 current_igi
+);
+
+void
+odm_pause_dig(
+ void *p_dm_void,
+ enum phydm_pause_type pause_type,
+ enum phydm_pause_level pause_level,
+ u8 igi_value
+);
+
+void
+odm_dig_init(
+ void *p_dm_void
+);
+
+void
+odm_DIG(
+ void *p_dm_void
+);
+
+void
+odm_dig_by_rssi_lps(
+ void *p_dm_void
+);
+
+void
+odm_false_alarm_counter_statistics(
+ void *p_dm_void
+);
+
+void
+odm_pause_cck_packet_detection(
+ void *p_dm_void,
+ enum phydm_pause_type pause_type,
+ enum phydm_pause_level pause_level,
+ u8 cck_pd_threshold
+);
+
+void
+odm_cck_packet_detection_thresh(
+ void *p_dm_void
+);
+
+void
+odm_write_cck_cca_thres(
+ void *p_dm_void,
+ u8 cur_cck_cca_thres
+);
+
+bool
+phydm_dig_go_up_check(
+ void *p_dm_void
+);
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_dynamic_rx_path.c b/drivers/staging/rtl8188eu/hal/phydm_dynamic_rx_path.c
new file mode 100644
index 000000000000..f68783fe4b72
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_dynamic_rx_path.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+#if (CONFIG_DYNAMIC_RX_PATH == 1)
+
+void
+phydm_process_phy_status_for_dynamic_rx_path(
+ void *p_dm_void,
+ void *p_phy_info_void,
+ void *p_pkt_info_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _odm_phy_status_info_ *p_phy_info = (struct _odm_phy_status_info_ *)p_phy_info_void;
+ struct _odm_per_pkt_info_ *p_pktinfo = (struct _odm_per_pkt_info_ *)p_pkt_info_void;
+ struct _DYNAMIC_RX_PATH_ *p_dm_drp_table = &(p_dm_odm->dm_drp_table);
+ /*u8 is_cck_rate=0;*/
+
+
+
+}
+
+void
+phydm_drp_get_statistic(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _DYNAMIC_RX_PATH_ *p_dm_drp_table = &(p_dm_odm->dm_drp_table);
+ struct false_ALARM_STATISTICS *false_alm_cnt = (struct false_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDMfalseALMCNT);
+
+ odm_false_alarm_counter_statistics(p_dm_odm);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n",
+ false_alm_cnt->cnt_cck_cca, false_alm_cnt->cnt_ofdm_cca, false_alm_cnt->cnt_cca_all));
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("[FA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n",
+ false_alm_cnt->cnt_cck_fail, false_alm_cnt->cnt_ofdm_fail, false_alm_cnt->cnt_all));
+}
+
+void
+phydm_dynamic_rx_path(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _DYNAMIC_RX_PATH_ *p_dm_drp_table = &(p_dm_odm->dm_drp_table);
+ u8 training_set_timmer_en;
+ u8 curr_drp_state;
+ u32 rx_ok_cal;
+ u32 RSSI = 0;
+ struct false_ALARM_STATISTICS *false_alm_cnt = (struct false_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDMfalseALMCNT);
+
+ if (!(p_dm_odm->support_ability & ODM_BB_DYNAMIC_RX_PATH)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("[Return Init] Not Support Dynamic RX PAth\n"));
+ return;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("Current drp_state = ((%d))\n", p_dm_drp_table->drp_state));
+
+ curr_drp_state = p_dm_drp_table->drp_state;
+
+ if (p_dm_drp_table->drp_state == DRP_INIT_STATE) {
+
+ phydm_drp_get_statistic(p_dm_odm);
+
+ if (false_alm_cnt->cnt_crc32_ok_all > 20) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("[Stop DRP Training] cnt_crc32_ok_all = ((%d))\n", false_alm_cnt->cnt_crc32_ok_all));
+ p_dm_drp_table->drp_state = DRP_INIT_STATE;
+ training_set_timmer_en = false;
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("[Start DRP Training] cnt_crc32_ok_all = ((%d))\n", false_alm_cnt->cnt_crc32_ok_all));
+ p_dm_drp_table->drp_state = DRP_TRAINING_STATE_0;
+ p_dm_drp_table->curr_rx_path = PHYDM_AB;
+ training_set_timmer_en = true;
+ }
+
+ } else if (p_dm_drp_table->drp_state == DRP_TRAINING_STATE_0) {
+
+ phydm_drp_get_statistic(p_dm_odm);
+
+ p_dm_drp_table->curr_cca_all_cnt_0 = false_alm_cnt->cnt_cca_all;
+ p_dm_drp_table->curr_fa_all_cnt_0 = false_alm_cnt->cnt_all;
+
+ p_dm_drp_table->drp_state = DRP_TRAINING_STATE_1;
+ p_dm_drp_table->curr_rx_path = PHYDM_B;
+ training_set_timmer_en = true;
+
+ } else if (p_dm_drp_table->drp_state == DRP_TRAINING_STATE_1) {
+ phydm_drp_get_statistic(p_dm_odm);
+ p_dm_drp_table->curr_cca_all_cnt_1 = false_alm_cnt->cnt_cca_all;
+ p_dm_drp_table->curr_fa_all_cnt_1 = false_alm_cnt->cnt_all;
+ p_dm_drp_table->drp_state = DRP_DECISION_STATE;
+ } else if (p_dm_drp_table->drp_state == DRP_TRAINING_STATE_2) {
+
+ phydm_drp_get_statistic(p_dm_odm);
+
+ p_dm_drp_table->curr_cca_all_cnt_2 = false_alm_cnt->cnt_cca_all;
+ p_dm_drp_table->curr_fa_all_cnt_2 = false_alm_cnt->cnt_all;
+ p_dm_drp_table->drp_state = DRP_DECISION_STATE;
+ }
+
+ if (p_dm_drp_table->drp_state == DRP_DECISION_STATE) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("Current drp_state = ((%d))\n", p_dm_drp_table->drp_state));
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("[0] {CCA, FA} = {%d, %d}\n", p_dm_drp_table->curr_cca_all_cnt_0, p_dm_drp_table->curr_fa_all_cnt_0));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("[1] {CCA, FA} = {%d, %d}\n", p_dm_drp_table->curr_cca_all_cnt_1, p_dm_drp_table->curr_fa_all_cnt_1));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("[2] {CCA, FA} = {%d, %d}\n", p_dm_drp_table->curr_cca_all_cnt_2, p_dm_drp_table->curr_fa_all_cnt_2));
+
+ if (p_dm_drp_table->curr_fa_all_cnt_1 < p_dm_drp_table->curr_fa_all_cnt_0) {
+
+ if ((p_dm_drp_table->curr_fa_all_cnt_0 - p_dm_drp_table->curr_fa_all_cnt_1) > p_dm_drp_table->fa_diff_threshold)
+ p_dm_drp_table->curr_rx_path = PHYDM_B;
+ else
+ p_dm_drp_table->curr_rx_path = PHYDM_AB;
+ } else
+ p_dm_drp_table->curr_rx_path = PHYDM_AB;
+
+ phydm_config_ofdm_rx_path(p_dm_odm, p_dm_drp_table->curr_rx_path);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("[Training Result] curr_rx_path = ((%s%s)),\n",
+ ((p_dm_drp_table->curr_rx_path & PHYDM_A) ? "A" : " "), ((p_dm_drp_table->curr_rx_path & PHYDM_B) ? "B" : " ")));
+
+ p_dm_drp_table->drp_state = DRP_INIT_STATE;
+ training_set_timmer_en = false;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("DRP_state: ((%d)) -> ((%d))\n", curr_drp_state, p_dm_drp_table->drp_state));
+
+ if (training_set_timmer_en) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("[Training en] curr_rx_path = ((%s%s)), training_time = ((%d ms))\n",
+ ((p_dm_drp_table->curr_rx_path & PHYDM_A) ? "A" : " "), ((p_dm_drp_table->curr_rx_path & PHYDM_B) ? "B" : " "), p_dm_drp_table->training_time));
+
+ phydm_config_ofdm_rx_path(p_dm_odm, p_dm_drp_table->curr_rx_path);
+ odm_set_timer(p_dm_odm, &(p_dm_drp_table->phydm_dynamic_rx_path_timer), p_dm_drp_table->training_time); /*ms*/
+ } else
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("DRP period end\n\n", curr_drp_state, p_dm_drp_table->drp_state));
+
+}
+
+void
+phydm_dynamic_rx_path_callback(
+ void *function_context
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)function_context;
+ struct _ADAPTER *padapter = p_dm_odm->adapter;
+
+ if (padapter->net_closed == true)
+ return;
+}
+
+void
+phydm_dynamic_rx_path_timers(
+ void *p_dm_void,
+ u8 state
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _DYNAMIC_RX_PATH_ *p_dm_drp_table = &(p_dm_odm->dm_drp_table);
+
+ if (state == INIT_DRP_TIMMER) {
+
+ odm_initialize_timer(p_dm_odm, &(p_dm_drp_table->phydm_dynamic_rx_path_timer),
+ (void *)phydm_dynamic_rx_path_callback, NULL, "phydm_sw_antenna_switch_timer");
+ } else if (state == CANCEL_DRP_TIMMER)
+
+ odm_cancel_timer(p_dm_odm, &(p_dm_drp_table->phydm_dynamic_rx_path_timer));
+
+ else if (state == RELEASE_DRP_TIMMER)
+
+ odm_release_timer(p_dm_odm, &(p_dm_drp_table->phydm_dynamic_rx_path_timer));
+
+}
+
+void
+phydm_dynamic_rx_path_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _DYNAMIC_RX_PATH_ *p_dm_drp_table = &(p_dm_odm->dm_drp_table);
+ bool ret_value;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_DYNAMIC_RX_PATH)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("[Return] Not Support Dynamic RX PAth\n"));
+ return;
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_DYNAMIC_RX_PATH, ODM_DBG_LOUD, ("phydm_dynamic_rx_path_init\n"));
+
+ p_dm_drp_table->drp_state = DRP_INIT_STATE;
+ p_dm_drp_table->rssi_threshold = DRP_RSSI_TH;
+ p_dm_drp_table->fa_count_thresold = 50;
+ p_dm_drp_table->fa_diff_threshold = 50;
+ p_dm_drp_table->training_time = 100; /*ms*/
+ p_dm_drp_table->drp_skip_counter = 0;
+ p_dm_drp_table->drp_period = 0;
+ p_dm_drp_table->drp_init_finished = true;
+
+ ret_value = phydm_api_trx_mode(p_dm_odm, (enum odm_rf_path_e)(ODM_RF_A | ODM_RF_B), (enum odm_rf_path_e)(ODM_RF_A | ODM_RF_B), true);
+
+}
+
+void
+phydm_drp_debug(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+ struct _DYNAMIC_RX_PATH_ *p_dm_drp_table = &(p_dm_odm->dm_drp_table);
+
+ switch (dm_value[0]) {
+
+ case DRP_TRAINING_TIME:
+ p_dm_drp_table->training_time = (u16)dm_value[1];
+ break;
+ case DRP_TRAINING_PERIOD:
+ p_dm_drp_table->drp_period = (u8)dm_value[1];
+ break;
+ case DRP_RSSI_THRESHOLD:
+ p_dm_drp_table->rssi_threshold = (u8)dm_value[1];
+ break;
+ case DRP_FA_THRESHOLD:
+ p_dm_drp_table->fa_count_thresold = dm_value[1];
+ break;
+ case DRP_FA_DIFF_THRESHOLD:
+ p_dm_drp_table->fa_diff_threshold = dm_value[1];
+ break;
+ default:
+ PHYDM_SNPRINTF((output + used, out_len - used, "[DRP] unknown command\n"));
+ break;
+}
+}
+
+void
+phydm_dynamic_rx_path_caller(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _DYNAMIC_RX_PATH_ *p_dm_drp_table = &(p_dm_odm->dm_drp_table);
+
+ if (p_dm_drp_table->drp_skip_counter < p_dm_drp_table->drp_period)
+ p_dm_drp_table->drp_skip_counter++;
+ else
+ p_dm_drp_table->drp_skip_counter = 0;
+
+ if (p_dm_drp_table->drp_skip_counter != 0)
+ return;
+
+ if (p_dm_drp_table->drp_init_finished != true)
+ return;
+
+ phydm_dynamic_rx_path(p_dm_odm);
+
+}
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_dynamic_rx_path.h b/drivers/staging/rtl8188eu/hal/phydm_dynamic_rx_path.h
new file mode 100644
index 000000000000..0502cf96d770
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_dynamic_rx_path.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMDYMICRXPATH_H__
+#define __PHYDMDYMICRXPATH_H__
+
+#define DYNAMIC_RX_PATH_VERSION "1.0" /*2016.07.15 Dino */
+
+
+#define DRP_RSSI_TH 35
+
+#define INIT_DRP_TIMMER 0
+#define CANCEL_DRP_TIMMER 1
+#define RELEASE_DRP_TIMMER 2
+
+#if (CONFIG_DYNAMIC_RX_PATH == 1)
+
+enum drp_state_e {
+ DRP_INIT_STATE = 0,
+ DRP_TRAINING_STATE_0 = 1,
+ DRP_TRAINING_STATE_1 = 2,
+ DRP_TRAINING_STATE_2 = 3,
+ DRP_DECISION_STATE = 4
+};
+
+enum adjustable_value_e {
+ DRP_TRAINING_TIME = 0,
+ DRP_TRAINING_PERIOD = 1,
+ DRP_RSSI_THRESHOLD = 2,
+ DRP_FA_THRESHOLD = 3,
+ DRP_FA_DIFF_THRESHOLD = 4
+};
+
+struct _DYNAMIC_RX_PATH_ {
+ u8 curr_rx_path;
+ u8 drp_state;
+ u16 training_time;
+ u8 rssi_threshold;
+ u32 fa_count_thresold;
+ u32 fa_diff_threshold;
+ u32 curr_cca_all_cnt_0;
+ u32 curr_fa_all_cnt_0;
+ u32 curr_cca_all_cnt_1;
+ u32 curr_fa_all_cnt_1;
+ u32 curr_cca_all_cnt_2;
+ u32 curr_fa_all_cnt_2;
+ u8 drp_skip_counter;
+ u8 drp_period;
+ u8 drp_init_finished;
+ struct timer_list phydm_dynamic_rx_path_timer;
+};
+
+
+
+void
+phydm_process_phy_status_for_dynamic_rx_path(
+ void *p_dm_void,
+ void *p_phy_info_void,
+ void *p_pkt_info_void
+);
+
+void phydm_dynamic_rx_path(void *p_dm_void);
+
+void phydm_dynamic_rx_path_callback(void *function_context);
+
+void
+phydm_dynamic_rx_path_timers(
+ void *p_dm_void,
+ u8 state
+);
+
+void
+phydm_dynamic_rx_path_init(
+ void *p_dm_void
+);
+
+void
+phydm_drp_debug(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+);
+
+void
+phydm_dynamic_rx_path_caller(
+ void *p_dm_void
+);
+
+#endif
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_dynamicbbpowersaving.c b/drivers/staging/rtl8188eu/hal/phydm_dynamicbbpowersaving.c
new file mode 100644
index 000000000000..7544d20741dd
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_dynamicbbpowersaving.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+#if (defined(CONFIG_BB_POWER_SAVING))
+
+void
+odm_dynamic_bb_power_saving_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _dynamic_power_saving *p_dm_ps_table = &p_dm_odm->dm_ps_table;
+
+ p_dm_ps_table->pre_cca_state = CCA_MAX;
+ p_dm_ps_table->cur_cca_state = CCA_MAX;
+ p_dm_ps_table->pre_rf_state = RF_MAX;
+ p_dm_ps_table->cur_rf_state = RF_MAX;
+ p_dm_ps_table->rssi_val_min = 0;
+ p_dm_ps_table->initialize = 0;
+}
+
+void
+odm_rf_saving(
+ void *p_dm_void,
+ u8 is_force_in_normal
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _dynamic_power_saving *p_dm_ps_table = &p_dm_odm->dm_ps_table;
+ u8 rssi_up_bound = 30 ;
+ u8 rssi_low_bound = 25;
+ if (p_dm_odm->patch_id == 40) { /* RT_CID_819x_FUNAI_TV */
+ rssi_up_bound = 50 ;
+ rssi_low_bound = 45;
+ }
+ if (p_dm_ps_table->initialize == 0) {
+ p_dm_ps_table->reg874 = (odm_get_bb_reg(p_dm_odm, 0x874, MASKDWORD) & 0x1CC000) >> 14;
+ p_dm_ps_table->regc70 = (odm_get_bb_reg(p_dm_odm, 0xc70, MASKDWORD) & BIT(3)) >> 3;
+ p_dm_ps_table->reg85c = (odm_get_bb_reg(p_dm_odm, 0x85c, MASKDWORD) & 0xFF000000) >> 24;
+ p_dm_ps_table->rega74 = (odm_get_bb_reg(p_dm_odm, 0xa74, MASKDWORD) & 0xF000) >> 12;
+ /* Reg818 = phy_query_bb_reg(p_adapter, 0x818, MASKDWORD); */
+ p_dm_ps_table->initialize = 1;
+ }
+
+ if (!is_force_in_normal) {
+ if (p_dm_odm->rssi_min != 0xFF) {
+ if (p_dm_ps_table->pre_rf_state == rf_normal) {
+ if (p_dm_odm->rssi_min >= rssi_up_bound)
+ p_dm_ps_table->cur_rf_state = rf_save;
+ else
+ p_dm_ps_table->cur_rf_state = rf_normal;
+ } else {
+ if (p_dm_odm->rssi_min <= rssi_low_bound)
+ p_dm_ps_table->cur_rf_state = rf_normal;
+ else
+ p_dm_ps_table->cur_rf_state = rf_save;
+ }
+ } else
+ p_dm_ps_table->cur_rf_state = RF_MAX;
+ } else
+ p_dm_ps_table->cur_rf_state = rf_normal;
+
+ if (p_dm_ps_table->pre_rf_state != p_dm_ps_table->cur_rf_state) {
+ if (p_dm_ps_table->cur_rf_state == rf_save) {
+ odm_set_bb_reg(p_dm_odm, 0x874, 0x1C0000, 0x2); /* reg874[20:18]=3'b010 */
+ odm_set_bb_reg(p_dm_odm, 0xc70, BIT(3), 0); /* regc70[3]=1'b0 */
+ odm_set_bb_reg(p_dm_odm, 0x85c, 0xFF000000, 0x63); /* reg85c[31:24]=0x63 */
+ odm_set_bb_reg(p_dm_odm, 0x874, 0xC000, 0x2); /* reg874[15:14]=2'b10 */
+ odm_set_bb_reg(p_dm_odm, 0xa74, 0xF000, 0x3); /* RegA75[7:4]=0x3 */
+ odm_set_bb_reg(p_dm_odm, 0x818, BIT(28), 0x0); /* Reg818[28]=1'b0 */
+ odm_set_bb_reg(p_dm_odm, 0x818, BIT(28), 0x1); /* Reg818[28]=1'b1 */
+ } else {
+ odm_set_bb_reg(p_dm_odm, 0x874, 0x1CC000, p_dm_ps_table->reg874);
+ odm_set_bb_reg(p_dm_odm, 0xc70, BIT(3), p_dm_ps_table->regc70);
+ odm_set_bb_reg(p_dm_odm, 0x85c, 0xFF000000, p_dm_ps_table->reg85c);
+ odm_set_bb_reg(p_dm_odm, 0xa74, 0xF000, p_dm_ps_table->rega74);
+ odm_set_bb_reg(p_dm_odm, 0x818, BIT(28), 0x0);
+ }
+ p_dm_ps_table->pre_rf_state = p_dm_ps_table->cur_rf_state;
+ }
+}
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_dynamicbbpowersaving.h b/drivers/staging/rtl8188eu/hal/phydm_dynamicbbpowersaving.h
new file mode 100644
index 000000000000..fe5f1564b6fe
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_dynamicbbpowersaving.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMDYNAMICBBPOWERSAVING_H__
+#define __PHYDMDYNAMICBBPOWERSAVING_H__
+
+#define DYNAMIC_BBPWRSAV_VERSION "1.1"
+
+#if (defined(CONFIG_BB_POWER_SAVING))
+
+struct _dynamic_power_saving {
+ u8 pre_cca_state;
+ u8 cur_cca_state;
+
+ u8 pre_rf_state;
+ u8 cur_rf_state;
+
+ int rssi_val_min;
+
+ u8 initialize;
+ u32 reg874, regc70, reg85c, rega74;
+
+};
+
+#define dm_rf_saving odm_rf_saving
+
+void odm_rf_saving(
+ void *p_dm_void,
+ u8 is_force_in_normal
+);
+
+void
+odm_dynamic_bb_power_saving_init(
+ void *p_dm_void
+);
+#else
+#define dm_rf_saving(p_dm_void, is_force_in_normal)
+#endif
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_dynamictxpower.c b/drivers/staging/rtl8188eu/hal/phydm_dynamictxpower.c
new file mode 100644
index 000000000000..6829d1b3e6f8
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_dynamictxpower.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+void
+odm_dynamic_tx_power_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ p_dm_odm->last_dtp_lvl = tx_high_pwr_level_normal;
+ p_dm_odm->dynamic_tx_high_power_lvl = tx_high_pwr_level_normal;
+ p_dm_odm->tx_agc_ofdm_18_6 = odm_get_bb_reg(p_dm_odm, 0xC24, MASKDWORD); /*TXAGC {18M 12M 9M 6M}*/
+}
+
+void
+odm_dynamic_tx_power_save_power_index(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 index;
+ u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a};
+
+}
+
+void
+odm_dynamic_tx_power_restore_power_index(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 index;
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
+ u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a};
+}
+
+void
+odm_dynamic_tx_power_write_power_index(
+ void *p_dm_void,
+ u8 value)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 index;
+ u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a};
+
+ for (index = 0; index < 6; index++)
+ /* platform_efio_write_1byte(adapter, power_index_reg[index], value); */
+ odm_write_1byte(p_dm_odm, power_index_reg[index], value);
+
+}
+
+static void
+odm_dynamic_tx_power_nic_ce(
+ void *p_dm_void
+)
+{
+}
+
+void
+odm_dynamic_tx_power(
+ void *p_dm_void
+)
+{
+ /* */
+ /* For AP/ADSL use struct rtl8192cd_priv* */
+ /* For CE/NIC use struct _ADAPTER* */
+ /* */
+ /* struct _ADAPTER* p_adapter = p_dm_odm->adapter;
+ * struct rtl8192cd_priv* priv = p_dm_odm->priv; */
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ if (!(p_dm_odm->support_ability & ODM_BB_DYNAMIC_TXPWR))
+ return;
+ /* */
+ /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */
+ /* at the same time. In the stage2/3, we need to prive universal interface and merge all */
+ /* HW dynamic mechanism. */
+ /* */
+ switch (p_dm_odm->support_platform) {
+ case ODM_WIN:
+ odm_dynamic_tx_power_nic(p_dm_odm);
+ break;
+ case ODM_CE:
+ odm_dynamic_tx_power_nic_ce(p_dm_odm);
+ break;
+ case ODM_AP:
+ odm_dynamic_tx_power_ap(p_dm_odm);
+ break;
+ default:
+ break;
+ }
+
+
+}
+
+
+void
+odm_dynamic_tx_power_nic(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_DYNAMIC_TXPWR))
+ return;
+}
+
+void
+odm_dynamic_tx_power_ap(
+ void *p_dm_void
+
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+}
+
+void
+odm_dynamic_tx_power_8821(
+ void *p_dm_void,
+ u8 *p_desc,
+ u8 mac_id
+)
+{
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_dynamictxpower.h b/drivers/staging/rtl8188eu/hal/phydm_dynamictxpower.h
new file mode 100644
index 000000000000..b8a82c54be5c
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_dynamictxpower.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMDYNAMICTXPOWER_H__
+#define __PHYDMDYNAMICTXPOWER_H__
+
+/*#define DYNAMIC_TXPWR_VERSION "1.0"*/
+/*#define DYNAMIC_TXPWR_VERSION "1.3" */ /*2015.08.26, Add 8814 Dynamic TX power*/
+#define DYNAMIC_TXPWR_VERSION "1.4" /*2015.11.06, Add CE 8821A Dynamic TX power*/
+
+#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
+#define TX_POWER_NEAR_FIELD_THRESH_LVL1 60
+
+#define tx_high_pwr_level_normal 0
+#define tx_high_pwr_level_level1 1
+#define tx_high_pwr_level_level2 2
+
+#define tx_high_pwr_level_bt1 3
+#define tx_high_pwr_level_bt2 4
+#define tx_high_pwr_level_15 5
+#define tx_high_pwr_level_35 6
+#define tx_high_pwr_level_50 7
+#define tx_high_pwr_level_70 8
+#define tx_high_pwr_level_100 9
+
+void
+odm_dynamic_tx_power_init(
+ void *p_dm_void
+);
+
+void
+odm_dynamic_tx_power_restore_power_index(
+ void *p_dm_void
+);
+
+void
+odm_dynamic_tx_power_nic(
+ void *p_dm_void
+);
+
+void
+odm_dynamic_tx_power_save_power_index(
+ void *p_dm_void
+);
+
+void
+odm_dynamic_tx_power_write_power_index(
+ void *p_dm_void,
+ u8 value);
+
+void
+odm_dynamic_tx_power_8821(
+ void *p_dm_void,
+ u8 *p_desc,
+ u8 mac_id
+);
+
+void
+odm_dynamic_tx_power(
+ void *p_dm_void
+);
+
+void
+odm_dynamic_tx_power_ap(
+ void *p_dm_void
+);
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_edcaturbocheck.c b/drivers/staging/rtl8188eu/hal/phydm_edcaturbocheck.c
new file mode 100644
index 000000000000..2da41a0ebc91
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_edcaturbocheck.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+#if PHYDM_SUPPORT_EDCA
+
+void
+odm_edca_turbo_init(
+ void *p_dm_void)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ p_dm_odm->dm_edca_table.is_current_turbo_edca = false;
+ p_dm_odm->dm_edca_table.is_cur_rdl_state = false;
+ adapter->recvpriv.is_any_non_be_pkts = false;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial VO PARAM: 0x%x\n", odm_read_4byte(p_dm_odm, ODM_EDCA_VO_PARAM)));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial VI PARAM: 0x%x\n", odm_read_4byte(p_dm_odm, ODM_EDCA_VI_PARAM)));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial BE PARAM: 0x%x\n", odm_read_4byte(p_dm_odm, ODM_EDCA_BE_PARAM)));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial BK PARAM: 0x%x\n", odm_read_4byte(p_dm_odm, ODM_EDCA_BK_PARAM)));
+} /* ODM_InitEdcaTurbo */
+
+void
+odm_edca_turbo_check(
+ void *p_dm_void
+)
+{
+ /* */
+ /* For AP/ADSL use struct rtl8192cd_priv* */
+ /* For CE/NIC use struct _ADAPTER* */
+ /* */
+
+ /* */
+ /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */
+ /* at the same time. In the stage2/3, we need to prive universal interface and merge all */
+ /* HW dynamic mechanism. */
+ /* */
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("odm_edca_turbo_check========================>\n"));
+
+ if (!(p_dm_odm->support_ability & ODM_MAC_EDCA_TURBO))
+ return;
+
+ switch (p_dm_odm->support_platform) {
+ case ODM_WIN:
+ break;
+ case ODM_CE:
+ odm_edca_turbo_check_ce(p_dm_odm);
+ break;
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("<========================odm_edca_turbo_check\n"));
+
+} /* odm_CheckEdcaTurbo */
+
+void
+odm_edca_turbo_check_ce(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ u32 EDCA_BE_UL = 0x5ea42b;/* Parameter suggested by Scott */ /* edca_setting_UL[p_mgnt_info->iot_peer]; */
+ u32 EDCA_BE_DL = 0x00a42b;/* Parameter suggested by Scott */ /* edca_setting_DL[p_mgnt_info->iot_peer]; */
+ u32 ic_type = p_dm_odm->support_ic_type;
+ u32 iot_peer = 0;
+ u8 wireless_mode = 0xFF; /* invalid value */
+ u32 traffic_index;
+ u32 edca_param;
+ u64 cur_tx_bytes = 0;
+ u64 cur_rx_bytes = 0;
+ u8 bbtchange = true;
+ u8 is_bias_on_rx = false;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapter);
+ struct xmit_priv *pxmitpriv = &(adapter->xmitpriv);
+ struct recv_priv *precvpriv = &(adapter->recvpriv);
+ struct registry_priv *pregpriv = &adapter->registrypriv;
+ struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ if (p_dm_odm->is_linked != true) {
+ precvpriv->is_any_non_be_pkts = false;
+ return;
+ }
+
+ if ((pregpriv->wifi_spec == 1)) { /* || (pmlmeinfo->HT_enable == 0)) */
+ precvpriv->is_any_non_be_pkts = false;
+ return;
+ }
+
+ if (p_dm_odm->p_wireless_mode != NULL)
+ wireless_mode = *(p_dm_odm->p_wireless_mode);
+
+ iot_peer = pmlmeinfo->assoc_AP_vendor;
+
+ if (iot_peer >= HT_IOT_PEER_MAX) {
+ precvpriv->is_any_non_be_pkts = false;
+ return;
+ }
+
+ if (p_dm_odm->support_ic_type & ODM_RTL8188E) {
+ if ((iot_peer == HT_IOT_PEER_RALINK) || (iot_peer == HT_IOT_PEER_ATHEROS))
+ is_bias_on_rx = true;
+ }
+
+ /* Check if the status needs to be changed. */
+ if ((bbtchange) || (!precvpriv->is_any_non_be_pkts)) {
+ cur_tx_bytes = pdvobjpriv->traffic_stat.cur_tx_bytes;
+ cur_rx_bytes = pdvobjpriv->traffic_stat.cur_rx_bytes;
+
+ /* traffic, TX or RX */
+ if (is_bias_on_rx) {
+ if (cur_tx_bytes > (cur_rx_bytes << 2)) {
+ /* Uplink TP is present. */
+ traffic_index = UP_LINK;
+ } else {
+ /* Balance TP is present. */
+ traffic_index = DOWN_LINK;
+ }
+ } else {
+ if (cur_rx_bytes > (cur_tx_bytes << 2)) {
+ /* Downlink TP is present. */
+ traffic_index = DOWN_LINK;
+ } else {
+ /* Balance TP is present. */
+ traffic_index = UP_LINK;
+ }
+ }
+
+ /* if ((p_dm_odm->dm_edca_table.prv_traffic_idx != traffic_index) || (!p_dm_odm->dm_edca_table.is_current_turbo_edca)) */
+ {
+ if (p_dm_odm->support_interface == ODM_ITRF_PCIE) {
+ EDCA_BE_UL = 0x6ea42b;
+ EDCA_BE_DL = 0x6ea42b;
+ }
+
+ /* 92D txop can't be set to 0x3e for cisco1250 */
+ if ((iot_peer == HT_IOT_PEER_CISCO) && (wireless_mode == ODM_WM_N24G)) {
+ EDCA_BE_DL = edca_setting_DL[iot_peer];
+ EDCA_BE_UL = edca_setting_UL[iot_peer];
+ }
+ /* merge from 92s_92c_merge temp brunch v2445 20120215 */
+ else if ((iot_peer == HT_IOT_PEER_CISCO) && ((wireless_mode == ODM_WM_G) || (wireless_mode == (ODM_WM_B | ODM_WM_G)) || (wireless_mode == ODM_WM_A) || (wireless_mode == ODM_WM_B)))
+ EDCA_BE_DL = edca_setting_dl_g_mode[iot_peer];
+ else if ((iot_peer == HT_IOT_PEER_AIRGO) && ((wireless_mode == ODM_WM_G) || (wireless_mode == ODM_WM_A)))
+ EDCA_BE_DL = 0xa630;
+ else if (iot_peer == HT_IOT_PEER_MARVELL) {
+ EDCA_BE_DL = edca_setting_DL[iot_peer];
+ EDCA_BE_UL = edca_setting_UL[iot_peer];
+ } else if (iot_peer == HT_IOT_PEER_ATHEROS) {
+ /* Set DL EDCA for Atheros peer to 0x3ea42b. Suggested by SD3 Wilson for ASUS TP issue. */
+ EDCA_BE_DL = edca_setting_DL[iot_peer];
+ }
+
+ if ((ic_type == ODM_RTL8812) || (ic_type == ODM_RTL8821) || (ic_type == ODM_RTL8192E)) { /* add 8812AU/8812AE */
+ EDCA_BE_UL = 0x5ea42b;
+ EDCA_BE_DL = 0x5ea42b;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("8812A: EDCA_BE_UL=0x%x EDCA_BE_DL =0x%x", EDCA_BE_UL, EDCA_BE_DL));
+ }
+
+ if (traffic_index == DOWN_LINK)
+ edca_param = EDCA_BE_DL;
+ else
+ edca_param = EDCA_BE_UL;
+
+ rtw_write32(adapter, REG_EDCA_BE_PARAM, edca_param);
+
+ p_dm_odm->dm_edca_table.prv_traffic_idx = traffic_index;
+ }
+
+ p_dm_odm->dm_edca_table.is_current_turbo_edca = true;
+ } else {
+ /* */
+ /* Turn Off EDCA turbo here. */
+ /* Restore original EDCA according to the declaration of AP. */
+ /* */
+ if (p_dm_odm->dm_edca_table.is_current_turbo_edca) {
+ rtw_write32(adapter, REG_EDCA_BE_PARAM, p_hal_data->ac_param_be);
+ p_dm_odm->dm_edca_table.is_current_turbo_edca = false;
+ }
+ }
+}
+
+#endif /*PHYDM_SUPPORT_EDCA*/
diff --git a/drivers/staging/rtl8188eu/hal/phydm_edcaturbocheck.h b/drivers/staging/rtl8188eu/hal/phydm_edcaturbocheck.h
new file mode 100644
index 000000000000..82ccd733e2db
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_edcaturbocheck.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMEDCATURBOCHECK_H__
+#define __PHYDMEDCATURBOCHECK_H__
+
+#if PHYDM_SUPPORT_EDCA
+/*#define EDCATURBO_VERSION "2.1"*/
+#define EDCATURBO_VERSION "2.3" /*2015.07.29 by YuChen*/
+
+struct _EDCA_TURBO_ {
+ bool is_current_turbo_edca;
+ bool is_cur_rdl_state;
+
+ u32 prv_traffic_idx; /* edca turbo */
+
+};
+
+static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
+ /* UNKNOWN REALTEK_90 REALTEK_92SE BROADCOM RALINK ATHEROS CISCO MERU MARVELL 92U_AP SELF_AP(DownLink/Tx) */
+{ 0x5e4322, 0xa44f, 0x5e4322, 0x5ea32b, 0x5ea422, 0x5ea322, 0x3ea430, 0x5ea42b, 0x5ea44f, 0x5e4322, 0x5e4322};
+
+
+static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
+ /* UNKNOWN REALTEK_90 REALTEK_92SE BROADCOM RALINK ATHEROS CISCO MERU, MARVELL 92U_AP SELF_AP(UpLink/Rx) */
+{ 0xa44f, 0x5ea44f, 0x5e4322, 0x5ea42b, 0xa44f, 0xa630, 0x5ea630, 0x5ea42b, 0xa44f, 0xa42b, 0xa42b};
+
+static u32 edca_setting_dl_g_mode[HT_IOT_PEER_MAX] =
+ /* UNKNOWN REALTEK_90 REALTEK_92SE BROADCOM RALINK ATHEROS CISCO MERU, MARVELL 92U_AP SELF_AP */
+{ 0x4322, 0xa44f, 0x5e4322, 0xa42b, 0x5e4322, 0x4322, 0xa42b, 0x5ea42b, 0xa44f, 0x5e4322, 0x5ea42b};
+
+void
+odm_edca_turbo_check(
+ void *p_dm_void
+);
+void
+odm_edca_turbo_init(
+ void *p_dm_void
+);
+
+void
+odm_edca_turbo_check_ce(
+ void *p_dm_void
+);
+
+#endif /*PHYDM_SUPPORT_EDCA*/
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_features.h b/drivers/staging/rtl8188eu/hal/phydm_features.h
new file mode 100644
index 000000000000..6339c4b25839
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_features.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDM_FEATURES_H__
+#define __PHYDM_FEATURES
+
+#define ODM_RECEIVER_BLOCKING_SUPPORT (ODM_RTL8188E | ODM_RTL8192E)
+#define PHYDM_LA_MODE_SUPPORT 0
+
+/*phydm debyg report & tools*/
+#define CONFIG_PHYDM_DEBUG_FUNCTION 1
+
+#define CONFIG_DYNAMIC_RX_PATH 0
+
+#define PHYDM_SUPPORT_EDCA 1
+#define SUPPORTABLITY_PHYDMLIZE 1
+#define RA_MASK_PHYDMLIZE_CE 1
+
+/*Antenna Diversity*/
+#ifdef CONFIG_ANTENNA_DIVERSITY
+ #define CONFIG_PHYDM_ANTENNA_DIVERSITY
+#endif
+
+#ifdef CONFIG_DFS_MASTER
+ #define CONFIG_PHYDM_DFS_MASTER
+#endif
+
+#define CONFIG_RECEIVER_BLOCKING
+#define CONFIG_RA_FW_DBG_CODE 0
+#define CONFIG_BB_POWER_SAVING
+#define CONFIG_BB_TXBF_API
+
+#ifdef CONFIG_BT_COEXIST
+ #define BT_SUPPORT 1
+#endif
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_hal_txbf_api.c b/drivers/staging/rtl8188eu/hal/phydm_hal_txbf_api.c
new file mode 100644
index 000000000000..36ccbde9feb0
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_hal_txbf_api.c
@@ -0,0 +1,72 @@
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+#if (defined(CONFIG_BB_TXBF_API))
+u8 beamforming_get_htndp_tx_rate(
+ void *p_dm_void,
+ u8 comp_steering_num_of_bfer
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 nr_index = 0;
+ u8 ndp_tx_rate;
+ /*Find nr*/
+ nr_index = tx_bf_nr(1, comp_steering_num_of_bfer);
+
+ switch (nr_index) {
+ case 1:
+ ndp_tx_rate = ODM_MGN_MCS8;
+ break;
+
+ case 2:
+ ndp_tx_rate = ODM_MGN_MCS16;
+ break;
+
+ case 3:
+ ndp_tx_rate = ODM_MGN_MCS24;
+ break;
+
+ default:
+ ndp_tx_rate = ODM_MGN_MCS8;
+ break;
+ }
+
+ return ndp_tx_rate;
+
+}
+
+u8
+beamforming_get_vht_ndp_tx_rate(
+ void *p_dm_void,
+ u8 comp_steering_num_of_bfer
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 nr_index = 0;
+ u8 ndp_tx_rate;
+ /*Find nr*/
+ nr_index = tx_bf_nr(1, comp_steering_num_of_bfer);
+
+ switch (nr_index) {
+ case 1:
+ ndp_tx_rate = ODM_MGN_VHT2SS_MCS0;
+ break;
+
+ case 2:
+ ndp_tx_rate = ODM_MGN_VHT3SS_MCS0;
+ break;
+
+ case 3:
+ ndp_tx_rate = ODM_MGN_VHT4SS_MCS0;
+ break;
+
+ default:
+ ndp_tx_rate = ODM_MGN_VHT2SS_MCS0;
+ break;
+ }
+
+ return ndp_tx_rate;
+
+}
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_hal_txbf_api.h b/drivers/staging/rtl8188eu/hal/phydm_hal_txbf_api.h
new file mode 100644
index 000000000000..b91a6deaff0d
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_hal_txbf_api.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#ifndef __PHYDM_HAL_TXBF_API_H__
+#define __PHYDM_HAL_TXBF_API_H__
+
+#if (defined(CONFIG_BB_TXBF_API))
+
+#define tx_bf_nr(a, b) ((a > b) ? (b) : (a))
+
+u8
+beamforming_get_htndp_tx_rate(
+ void *p_dm_void,
+ u8 comp_steering_num_of_bfer
+);
+
+u8
+beamforming_get_vht_ndp_tx_rate(
+ void *p_dm_void,
+ u8 comp_steering_num_of_bfer
+);
+
+#define phydm_get_beamforming_sounding_info(p_dm_void, troughput, total_bfee_num, tx_rate)
+#define phydm_get_ndpa_rate(p_dm_void)
+#define phydm_get_mu_bfee_snding_decision(p_dm_void, troughput)
+
+#endif
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_hwconfig.c b/drivers/staging/rtl8188eu/hal/phydm_hwconfig.c
new file mode 100644
index 000000000000..321743dfb50e
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_hwconfig.c
@@ -0,0 +1,2102 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+#define READ_AND_CONFIG_MP(ic, txt) (odm_read_and_config_mp_##ic##txt(p_dm_odm))
+#define READ_AND_CONFIG_TC(ic, txt) (odm_read_and_config_tc_##ic##txt(p_dm_odm))
+
+#if (PHYDM_TESTCHIP_SUPPORT == 1)
+#define READ_AND_CONFIG(ic, txt) do {\
+ if (p_dm_odm->is_mp_chip)\
+ READ_AND_CONFIG_MP(ic, txt);\
+ else\
+ READ_AND_CONFIG_TC(ic, txt);\
+ } while (0)
+#else
+#define READ_AND_CONFIG READ_AND_CONFIG_MP
+#endif
+
+#define READ_FIRMWARE_MP(ic, txt) (odm_read_firmware_mp_##ic##txt(p_dm_odm, p_firmware, p_size))
+#define READ_FIRMWARE_TC(ic, txt) (odm_read_firmware_tc_##ic##txt(p_dm_odm, p_firmware, p_size))
+
+#if (PHYDM_TESTCHIP_SUPPORT == 1)
+#define READ_FIRMWARE(ic, txt) do {\
+ if (p_dm_odm->is_mp_chip)\
+ READ_FIRMWARE_MP(ic, txt);\
+ else\
+ READ_FIRMWARE_TC(ic, txt);\
+ } while (0)
+#else
+#define READ_FIRMWARE READ_FIRMWARE_MP
+#endif
+
+#define GET_VERSION_MP(ic, txt) (odm_get_version_mp_##ic##txt())
+#define GET_VERSION_TC(ic, txt) (odm_get_version_tc_##ic##txt())
+
+#if (PHYDM_TESTCHIP_SUPPORT == 1)
+ #define GET_VERSION(ic, txt) (p_dm_odm->is_mp_chip ? GET_VERSION_MP(ic, txt) : GET_VERSION_TC(ic, txt))
+#else
+ #define GET_VERSION(ic, txt) GET_VERSION_MP(ic, txt)
+#endif
+
+static u8
+odm_query_rx_pwr_percentage(
+ s8 ant_power
+)
+{
+ if ((ant_power <= -100) || (ant_power >= 20))
+ return 0;
+ else if (ant_power >= 0)
+ return 100;
+ else
+ return 100 + ant_power;
+}
+
+/*
+ * 2012/01/12 MH MOve some signal strength smooth method to MP HAL layer.
+ * IF other SW team do not support the feature, remove this section.??
+ * */
+static s32
+odm_signal_scale_mapping_92c_series_patch_rt_cid_819x_lenovo(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ s32 curr_sig
+)
+{
+ s32 ret_sig = 0;
+ return ret_sig;
+}
+
+static s32
+odm_signal_scale_mapping_92c_series_patch_rt_cid_819x_netcore(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ s32 curr_sig
+)
+{
+ s32 ret_sig = 0;
+ return ret_sig;
+}
+
+static s32
+odm_signal_scale_mapping_92c_series(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ s32 curr_sig
+)
+{
+ s32 ret_sig = 0;
+
+ if ((p_dm_odm->support_interface == ODM_ITRF_USB) || (p_dm_odm->support_interface == ODM_ITRF_SDIO)) {
+ if (curr_sig >= 51 && curr_sig <= 100)
+ ret_sig = 100;
+ else if (curr_sig >= 41 && curr_sig <= 50)
+ ret_sig = 80 + ((curr_sig - 40) * 2);
+ else if (curr_sig >= 31 && curr_sig <= 40)
+ ret_sig = 66 + (curr_sig - 30);
+ else if (curr_sig >= 21 && curr_sig <= 30)
+ ret_sig = 54 + (curr_sig - 20);
+ else if (curr_sig >= 10 && curr_sig <= 20)
+ ret_sig = 42 + (((curr_sig - 10) * 2) / 3);
+ else if (curr_sig >= 5 && curr_sig <= 9)
+ ret_sig = 22 + (((curr_sig - 5) * 3) / 2);
+ else if (curr_sig >= 1 && curr_sig <= 4)
+ ret_sig = 6 + (((curr_sig - 1) * 3) / 2);
+ else
+ ret_sig = curr_sig;
+ }
+
+ return ret_sig;
+}
+s32
+odm_signal_scale_mapping(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ s32 curr_sig
+)
+{
+ {
+#ifdef CONFIG_SIGNAL_SCALE_MAPPING
+ return odm_signal_scale_mapping_92c_series(p_dm_odm, curr_sig);
+#else
+ return curr_sig;
+#endif
+ }
+
+}
+
+static u8 odm_sq_process_patch_rt_cid_819x_lenovo(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 is_cck_rate,
+ u8 PWDB_ALL,
+ u8 path,
+ u8 RSSI
+)
+{
+ u8 SQ = 0;
+ return SQ;
+}
+
+static u8 odm_sq_process_patch_rt_cid_819x_acer(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 is_cck_rate,
+ u8 PWDB_ALL,
+ u8 path,
+ u8 RSSI
+)
+{
+ u8 SQ = 0;
+
+ return SQ;
+}
+
+static u8
+odm_evm_db_to_percentage(
+ s8 value
+)
+{
+ /* */
+ /* -33dB~0dB to 0%~99% */
+ /* */
+ s8 ret_val;
+
+ ret_val = value;
+ ret_val /= 2;
+
+ /*dbg_print("value=%d\n", value);*/
+ /*ODM_RT_DISP(FRX, RX_PHY_SQ, ("EVMdbToPercentage92C value=%d / %x\n", ret_val, ret_val));*/
+#ifdef ODM_EVM_ENHANCE_ANTDIV
+ if (ret_val >= 0)
+ ret_val = 0;
+
+ if (ret_val <= -40)
+ ret_val = -40;
+
+ ret_val = 0 - ret_val;
+ ret_val *= 3;
+#else
+ if (ret_val >= 0)
+ ret_val = 0;
+
+ if (ret_val <= -33)
+ ret_val = -33;
+
+ ret_val = 0 - ret_val;
+ ret_val *= 3;
+
+ if (ret_val == 99)
+ ret_val = 100;
+#endif
+
+ return (u8)ret_val;
+}
+
+static u8
+odm_evm_dbm_jaguar_series(
+ s8 value
+)
+{
+ s8 ret_val = value;
+
+ /* -33dB~0dB to 33dB ~ 0dB */
+ if (ret_val == -128)
+ ret_val = 127;
+ else if (ret_val < 0)
+ ret_val = 0 - ret_val;
+
+ ret_val = ret_val >> 1;
+ return (u8)ret_val;
+}
+
+static s16
+odm_cfo(
+ s8 value
+)
+{
+ s16 ret_val;
+
+ if (value < 0) {
+ ret_val = 0 - value;
+ ret_val = (ret_val << 1) + (ret_val >> 1) ; /* *2.5~=312.5/2^7 */
+ ret_val = ret_val | BIT(12); /* set bit12 as 1 for negative cfo */
+ } else {
+ ret_val = value;
+ ret_val = (ret_val << 1) + (ret_val >> 1) ; /* *2.5~=312.5/2^7 */
+ }
+ return ret_val;
+}
+
+static u8
+phydm_rate_to_num_ss(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 data_rate
+)
+{
+ u8 num_ss = 1;
+
+ if (data_rate <= ODM_RATE54M)
+ num_ss = 1;
+ else if (data_rate <= ODM_RATEMCS31)
+ num_ss = ((data_rate - ODM_RATEMCS0) >> 3) + 1;
+ else if (data_rate <= ODM_RATEVHTSS1MCS9)
+ num_ss = 1;
+ else if (data_rate <= ODM_RATEVHTSS2MCS9)
+ num_ss = 2;
+ else if (data_rate <= ODM_RATEVHTSS3MCS9)
+ num_ss = 3;
+ else if (data_rate <= ODM_RATEVHTSS4MCS9)
+ num_ss = 4;
+
+ return num_ss;
+}
+
+#if (ODM_IC_11N_SERIES_SUPPORT == 1)
+
+#if (RTL8703B_SUPPORT == 1)
+s8
+odm_CCKRSSI_8703B(
+ u16 LNA_idx,
+ u8 VGA_idx
+)
+{
+ s8 rx_pwr_all = 0x00;
+
+ switch (LNA_idx) {
+ case 0xf:
+ rx_pwr_all = -48 - (2 * VGA_idx);
+ break;
+ case 0xb:
+ rx_pwr_all = -42 - (2 * VGA_idx); /*TBD*/
+ break;
+ case 0xa:
+ rx_pwr_all = -36 - (2 * VGA_idx);
+ break;
+ case 8:
+ rx_pwr_all = -32 - (2 * VGA_idx);
+ break;
+ case 7:
+ rx_pwr_all = -19 - (2 * VGA_idx);
+ break;
+ case 4:
+ rx_pwr_all = -6 - (2 * VGA_idx);
+ break;
+ case 0:
+ rx_pwr_all = -2 - (2 * VGA_idx);
+ break;
+ default:
+ /*rx_pwr_all = -53+(2*(31-VGA_idx));*/
+ /*dbg_print("wrong LNA index\n");*/
+ break;
+
+ }
+ return rx_pwr_all;
+}
+#endif
+
+#if (RTL8195A_SUPPORT == 1)
+s8
+odm_CCKRSSI_8195A(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u16 LNA_idx,
+ u8 VGA_idx
+)
+{
+ s8 rx_pwr_all = 0;
+ s8 lna_gain = 0;
+ s8 lna_gain_table_0[8] = {0, -8, -15, -22, -29, -36, -45, -54};
+ s8 lna_gain_table_1[8] = {0, -8, -15, -22, -29, -36, -45, -54};/*use 8195A to calibrate this table. 2016.06.24, Dino*/
+
+ if (p_dm_odm->cck_agc_report_type == 0)
+ lna_gain = lna_gain_table_0[LNA_idx];
+ else
+ lna_gain = lna_gain_table_1[LNA_idx];
+
+ rx_pwr_all = lna_gain - (2 * VGA_idx);
+
+ return rx_pwr_all;
+}
+#endif
+
+#if (RTL8192E_SUPPORT == 1)
+s8
+odm_CCKRSSI_8192E(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u16 LNA_idx,
+ u8 VGA_idx
+)
+{
+ s8 rx_pwr_all = 0;
+ s8 lna_gain = 0;
+ s8 lna_gain_table_0[8] = {15, 9, -10, -21, -23, -27, -43, -44};
+ s8 lna_gain_table_1[8] = {24, 18, 13, -4, -11, -18, -31, -36};/*use 8192EU to calibrate this table. 2015.12.15, Dino*/
+
+ if (p_dm_odm->cck_agc_report_type == 0)
+ lna_gain = lna_gain_table_0[LNA_idx];
+ else
+ lna_gain = lna_gain_table_1[LNA_idx];
+
+ rx_pwr_all = lna_gain - (2 * VGA_idx);
+
+ return rx_pwr_all;
+}
+#endif
+
+#if (RTL8188E_SUPPORT == 1)
+static s8
+odm_CCKRSSI_8188E(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u16 LNA_idx,
+ u8 VGA_idx
+)
+{
+ s8 rx_pwr_all = 0;
+ s8 lna_gain = 0;
+ s8 lna_gain_table_0[8] = {17, -1, -13, -29, -32, -35, -38, -41};/*only use lna0/1/2/3/7*/
+ s8 lna_gain_table_1[8] = {29, 20, 12, 3, -6, -15, -24, -33}; /*only use lna3 /7*/
+
+ if (p_dm_odm->cut_version >= ODM_CUT_I) /*SMIC*/
+ lna_gain = lna_gain_table_0[LNA_idx];
+ else /*TSMC*/
+ lna_gain = lna_gain_table_1[LNA_idx];
+
+ rx_pwr_all = lna_gain - (2 * VGA_idx);
+
+ return rx_pwr_all;
+}
+#endif
+
+static void
+odm_rx_phy_status92c_series_parsing(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct _odm_phy_status_info_ *p_phy_info,
+ u8 *p_phy_status,
+ struct _odm_per_pkt_info_ *p_pktinfo
+)
+{
+ struct _sw_antenna_switch_ *p_dm_swat_table = &p_dm_odm->dm_swat_table;
+ u8 i, max_spatial_stream;
+ s8 rx_pwr[4], rx_pwr_all = 0;
+ u8 EVM, PWDB_ALL = 0, PWDB_ALL_BT;
+ u8 RSSI, total_rssi = 0;
+ bool is_cck_rate = false;
+ u8 rf_rx_num = 0;
+ u8 cck_highpwr = 0;
+ u8 LNA_idx = 0;
+ u8 VGA_idx = 0;
+ u8 cck_agc_rpt;
+ u8 num_ss;
+ struct _phy_status_rpt_8192cd *p_phy_sta_rpt = (struct _phy_status_rpt_8192cd *)p_phy_status;
+
+ is_cck_rate = (p_pktinfo->data_rate <= ODM_RATE11M) ? true : false;
+
+ if (p_pktinfo->is_to_self)
+ p_dm_odm->curr_station_id = p_pktinfo->station_id;
+
+ p_phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1;
+ p_phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
+
+ if (is_cck_rate) {
+ p_dm_odm->phy_dbg_info.num_qry_phy_status_cck++;
+ cck_agc_rpt = p_phy_sta_rpt->cck_agc_rpt_ofdm_cfosho_a ;
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8703B)) {
+
+#if (RTL8703B_SUPPORT == 1)
+ if (p_dm_odm->cck_agc_report_type == 1) { /*4 bit LNA*/
+
+ u8 cck_agc_rpt_b = (p_phy_sta_rpt->cck_rpt_b_ofdm_cfosho_b & BIT(7)) ? 1 : 0;
+
+ LNA_idx = (cck_agc_rpt_b << 3) | ((cck_agc_rpt & 0xE0) >> 5);
+ VGA_idx = (cck_agc_rpt & 0x1F);
+
+ rx_pwr_all = odm_CCKRSSI_8703B(LNA_idx, VGA_idx);
+ }
+#endif
+ } else { /*3 bit LNA*/
+
+ LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
+ VGA_idx = (cck_agc_rpt & 0x1F);
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8188E)) {
+
+#if (RTL8188E_SUPPORT == 1)
+ rx_pwr_all = odm_CCKRSSI_8188E(p_dm_odm, LNA_idx, VGA_idx);
+ /**/
+#endif
+ }
+#if (RTL8192E_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type & (ODM_RTL8192E)) {
+
+ rx_pwr_all = odm_CCKRSSI_8192E(p_dm_odm, LNA_idx, VGA_idx);
+ /**/
+ }
+#endif
+#if (RTL8723B_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type & (ODM_RTL8723B)) {
+
+ rx_pwr_all = odm_CCKRSSI_8723B(LNA_idx, VGA_idx);
+ /**/
+ }
+#endif
+#if (RTL8188F_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type & (ODM_RTL8188F)) {
+
+ rx_pwr_all = odm_CCKRSSI_8188E(p_dm_odm, LNA_idx, VGA_idx);
+ /**/
+ }
+#endif
+#if (RTL8195A_SUPPORT == 1)
+ else if (p_dm_odm->support_ic_type & (ODM_RTL8195A)) {
+
+ rx_pwr_all = odm_CCKRSSI_8195A(LNA_idx, VGA_idx);
+ /**/
+ }
+#endif
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("ext_lna_gain (( %d )), LNA_idx: (( 0x%x )), VGA_idx: (( 0x%x )), rx_pwr_all: (( %d ))\n",
+ p_dm_odm->ext_lna_gain, LNA_idx, VGA_idx, rx_pwr_all));
+
+ if (p_dm_odm->board_type & ODM_BOARD_EXT_LNA)
+ rx_pwr_all -= p_dm_odm->ext_lna_gain;
+
+ PWDB_ALL = odm_query_rx_pwr_percentage(rx_pwr_all);
+
+ if (p_pktinfo->is_to_self) {
+ p_dm_odm->cck_lna_idx = LNA_idx;
+ p_dm_odm->cck_vga_idx = VGA_idx;
+ }
+ p_phy_info->rx_pwdb_all = PWDB_ALL;
+
+ p_phy_info->bt_rx_rssi_percentage = PWDB_ALL;
+ p_phy_info->recv_signal_power = rx_pwr_all;
+ /* */
+ /* (3) Get Signal Quality (EVM) */
+ /* */
+ /* if(p_pktinfo->is_packet_match_bssid) */
+ {
+ u8 SQ, SQ_rpt;
+
+ if (p_phy_info->rx_pwdb_all > 40 && !p_dm_odm->is_in_hct_test)
+ SQ = 100;
+ else {
+ SQ_rpt = p_phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all;
+
+ if (SQ_rpt > 64)
+ SQ = 0;
+ else if (SQ_rpt < 20)
+ SQ = 100;
+ else
+ SQ = ((64 - SQ_rpt) * 100) / 44;
+
+ }
+
+ /* dbg_print("cck SQ = %d\n", SQ); */
+ p_phy_info->signal_quality = SQ;
+ p_phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = SQ;
+ p_phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
+ }
+
+ for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) {
+ if (i == 0)
+ p_phy_info->rx_mimo_signal_strength[0] = PWDB_ALL;
+ else
+ p_phy_info->rx_mimo_signal_strength[1] = 0;
+ }
+ } else { /* 2 is OFDM rate */
+ p_dm_odm->phy_dbg_info.num_qry_phy_status_ofdm++;
+
+ /* */
+ /* (1)Get RSSI for HT rate */
+ /* */
+
+ for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) {
+ /* 2008/01/30 MH we will judge RF RX path now. */
+ if (p_dm_odm->rf_path_rx_enable & BIT(i))
+ rf_rx_num++;
+ /* else */
+ /* continue; */
+
+ rx_pwr[i] = ((p_phy_sta_rpt->path_agc[i].gain & 0x3F) * 2) - 110;
+
+ if (p_pktinfo->is_to_self) {
+ p_dm_odm->ofdm_agc_idx[i] = (p_phy_sta_rpt->path_agc[i].gain & 0x3F);
+ /**/
+ }
+
+ p_phy_info->rx_pwr[i] = rx_pwr[i];
+
+ /* Translate DBM to percentage. */
+ RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]);
+ total_rssi += RSSI;
+ /* RT_DISP(FRX, RX_PHY_SS, ("RF-%d RXPWR=%x RSSI=%d\n", i, rx_pwr[i], RSSI)); */
+
+ p_phy_info->rx_mimo_signal_strength[i] = (u8) RSSI;
+
+ /* Get Rx snr value in DB */
+ p_phy_info->rx_snr[i] = p_dm_odm->phy_dbg_info.rx_snr_db[i] = (s32)(p_phy_sta_rpt->path_rxsnr[i] / 2);
+
+ }
+
+ /* */
+ /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */
+ /* */
+ rx_pwr_all = (((p_phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all) >> 1) & 0x7f) - 110;
+
+ PWDB_ALL_BT = PWDB_ALL = odm_query_rx_pwr_percentage(rx_pwr_all);
+
+ p_phy_info->rx_pwdb_all = PWDB_ALL;
+ /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("ODM OFDM RSSI=%d\n",p_phy_info->rx_pwdb_all)); */
+ p_phy_info->bt_rx_rssi_percentage = PWDB_ALL_BT;
+ p_phy_info->rx_power = rx_pwr_all;
+ p_phy_info->recv_signal_power = rx_pwr_all;
+
+ if ((p_dm_odm->support_platform == ODM_WIN) && (p_dm_odm->patch_id == 19)) {
+ /* do nothing */
+ } else if ((p_dm_odm->support_platform == ODM_WIN) && (p_dm_odm->patch_id == 25)) {
+ /* do nothing */
+ } else { /* p_mgnt_info->customer_id != RT_CID_819X_LENOVO */
+ /* */
+ /* (3)EVM of HT rate */
+ /* */
+ if (p_pktinfo->data_rate >= ODM_RATEMCS8 && p_pktinfo->data_rate <= ODM_RATEMCS15)
+ max_spatial_stream = 2; /* both spatial stream make sense */
+ else
+ max_spatial_stream = 1; /* only spatial stream 1 makes sense */
+
+ for (i = 0; i < max_spatial_stream; i++) {
+ /* Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment */
+ /* fill most significant bit to "zero" when doing shifting operation which may change a negative */
+ /* value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. */
+ EVM = odm_evm_db_to_percentage((p_phy_sta_rpt->stream_rxevm[i])); /* dbm */
+
+ /* GET_RX_STATUS_DESC_RX_MCS(p_desc), p_drv_info->rxevm[i], "%", EVM)); */
+
+ /* if(p_pktinfo->is_packet_match_bssid) */
+ {
+ if (i == ODM_RF_PATH_A) /* Fill value in RFD, Get the first spatial stream only */
+ p_phy_info->signal_quality = (u8)(EVM & 0xff);
+ p_phy_info->rx_mimo_signal_quality[i] = (u8)(EVM & 0xff);
+ }
+ }
+ }
+
+ num_ss = phydm_rate_to_num_ss(p_dm_odm, p_pktinfo->data_rate);
+ odm_parsing_cfo(p_dm_odm, p_pktinfo, p_phy_sta_rpt->path_cfotail, num_ss);
+
+ }
+ /* UI BSS List signal strength(in percentage), make it good looking, from 0~100. */
+ /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */
+ if (is_cck_rate) {
+ p_phy_info->signal_strength = (u8)(odm_signal_scale_mapping(p_dm_odm, PWDB_ALL));/*PWDB_ALL;*/
+ } else {
+ if (rf_rx_num != 0)
+ p_phy_info->signal_strength = (u8)(odm_signal_scale_mapping(p_dm_odm, total_rssi /= rf_rx_num));
+ }
+
+ /* For 92C/92D HW (Hybrid) Antenna Diversity */
+#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))
+ /* For 88E HW Antenna Diversity */
+ p_dm_odm->dm_fat_table.antsel_rx_keep_0 = p_phy_sta_rpt->ant_sel;
+ p_dm_odm->dm_fat_table.antsel_rx_keep_1 = p_phy_sta_rpt->ant_sel_b;
+ p_dm_odm->dm_fat_table.antsel_rx_keep_2 = p_phy_sta_rpt->antsel_rx_keep_2;
+#endif
+}
+#endif
+
+#if ODM_IC_11AC_SERIES_SUPPORT
+
+void
+odm_rx_phy_bw_jaguar_series_parsing(
+ struct _odm_phy_status_info_ *p_phy_info,
+ struct _odm_per_pkt_info_ *p_pktinfo,
+ struct _phy_status_rpt_8812 *p_phy_sta_rpt
+)
+{
+
+ if (p_pktinfo->data_rate <= ODM_RATE54M) {
+ switch (p_phy_sta_rpt->r_RFMOD) {
+ case 1:
+ if (p_phy_sta_rpt->sub_chnl == 0)
+ p_phy_info->band_width = 1;
+ else
+ p_phy_info->band_width = 0;
+ break;
+
+ case 2:
+ if (p_phy_sta_rpt->sub_chnl == 0)
+ p_phy_info->band_width = 2;
+ else if (p_phy_sta_rpt->sub_chnl == 9 || p_phy_sta_rpt->sub_chnl == 10)
+ p_phy_info->band_width = 1;
+ else
+ p_phy_info->band_width = 0;
+ break;
+
+ default:
+ case 0:
+ p_phy_info->band_width = 0;
+ break;
+ }
+ }
+
+}
+
+void
+odm_rx_phy_status_jaguar_series_parsing(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct _odm_phy_status_info_ *p_phy_info,
+ u8 *p_phy_status,
+ struct _odm_per_pkt_info_ *p_pktinfo
+)
+{
+ u8 i, max_spatial_stream;
+ s8 rx_pwr[4], rx_pwr_all = 0;
+ u8 EVM, evm_dbm, PWDB_ALL = 0, PWDB_ALL_BT;
+ u8 RSSI, avg_rssi = 0, best_rssi = 0, second_rssi = 0;
+ u8 is_cck_rate = 0;
+ u8 rf_rx_num = 0;
+ u8 cck_highpwr = 0;
+ u8 LNA_idx, VGA_idx;
+ struct _phy_status_rpt_8812 *p_phy_sta_rpt = (struct _phy_status_rpt_8812 *)p_phy_status;
+ struct _FAST_ANTENNA_TRAINNING_ *p_dm_fat_table = &p_dm_odm->dm_fat_table;
+ u8 num_ss;
+
+ odm_rx_phy_bw_jaguar_series_parsing(p_phy_info, p_pktinfo, p_phy_sta_rpt);
+
+ if (p_pktinfo->data_rate <= ODM_RATE11M)
+ is_cck_rate = true;
+ else
+ is_cck_rate = false;
+
+ if (p_pktinfo->is_to_self)
+ p_dm_odm->curr_station_id = p_pktinfo->station_id;
+ else
+ p_dm_odm->curr_station_id = 0xff;
+
+ p_phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1;
+ p_phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1;
+ p_phy_info->rx_mimo_signal_quality[ODM_RF_PATH_C] = -1;
+ p_phy_info->rx_mimo_signal_quality[ODM_RF_PATH_D] = -1;
+
+ if (is_cck_rate) {
+ u8 cck_agc_rpt;
+ p_dm_odm->phy_dbg_info.num_qry_phy_status_cck++;
+
+ /*(1)Hardware does not provide RSSI for CCK*/
+ /*(2)PWDB, Average PWDB calculated by hardware (for rate adaptive)*/
+
+ /*if(p_hal_data->e_rf_power_state == e_rf_on)*/
+ cck_highpwr = p_dm_odm->is_cck_high_power;
+ /*else*/
+ /*cck_highpwr = false;*/
+
+ cck_agc_rpt = p_phy_sta_rpt->cfosho[0] ;
+ LNA_idx = ((cck_agc_rpt & 0xE0) >> 5);
+ VGA_idx = (cck_agc_rpt & 0x1F);
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8812) {
+ switch (LNA_idx) {
+ case 7:
+ if (VGA_idx <= 27)
+ rx_pwr_all = -100 + 2 * (27 - VGA_idx); /*VGA_idx = 27~2*/
+ else
+ rx_pwr_all = -100;
+ break;
+ case 6:
+ rx_pwr_all = -48 + 2 * (2 - VGA_idx); /*VGA_idx = 2~0*/
+ break;
+ case 5:
+ rx_pwr_all = -42 + 2 * (7 - VGA_idx); /*VGA_idx = 7~5*/
+ break;
+ case 4:
+ rx_pwr_all = -36 + 2 * (7 - VGA_idx); /*VGA_idx = 7~4*/
+ break;
+ case 3:
+ /*rx_pwr_all = -28 + 2*(7-VGA_idx); VGA_idx = 7~0*/
+ rx_pwr_all = -24 + 2 * (7 - VGA_idx); /*VGA_idx = 7~0*/
+ break;
+ case 2:
+ if (cck_highpwr)
+ rx_pwr_all = -12 + 2 * (5 - VGA_idx); /*VGA_idx = 5~0*/
+ else
+ rx_pwr_all = -6 + 2 * (5 - VGA_idx);
+ break;
+ case 1:
+ rx_pwr_all = 8 - 2 * VGA_idx;
+ break;
+ case 0:
+ rx_pwr_all = 14 - 2 * VGA_idx;
+ break;
+ default:
+ /*dbg_print("CCK Exception default\n");*/
+ break;
+ }
+ rx_pwr_all += 6;
+ PWDB_ALL = odm_query_rx_pwr_percentage(rx_pwr_all);
+
+ if (cck_highpwr == false) {
+ if (PWDB_ALL >= 80)
+ PWDB_ALL = ((PWDB_ALL - 80) << 1) + ((PWDB_ALL - 80) >> 1) + 80;
+ else if ((PWDB_ALL <= 78) && (PWDB_ALL >= 20))
+ PWDB_ALL += 3;
+ if (PWDB_ALL > 100)
+ PWDB_ALL = 100;
+ }
+ } else if (p_dm_odm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
+ s8 pout = -6;
+
+ switch (LNA_idx) {
+ case 5:
+ rx_pwr_all = pout - 32 - (2 * VGA_idx);
+ break;
+ case 4:
+ rx_pwr_all = pout - 24 - (2 * VGA_idx);
+ break;
+ case 2:
+ rx_pwr_all = pout - 11 - (2 * VGA_idx);
+ break;
+ case 1:
+ rx_pwr_all = pout + 5 - (2 * VGA_idx);
+ break;
+ case 0:
+ rx_pwr_all = pout + 21 - (2 * VGA_idx);
+ break;
+ }
+ PWDB_ALL = odm_query_rx_pwr_percentage(rx_pwr_all);
+ } else if (p_dm_odm->support_ic_type == ODM_RTL8814A || p_dm_odm->support_ic_type == ODM_RTL8822B) {
+ s8 pout = -6;
+
+ switch (LNA_idx) {
+ /*CCK only use LNA: 2, 3, 5, 7*/
+ case 7:
+ rx_pwr_all = pout - 32 - (2 * VGA_idx);
+ break;
+ case 5:
+ rx_pwr_all = pout - 22 - (2 * VGA_idx);
+ break;
+ case 3:
+ rx_pwr_all = pout - 2 - (2 * VGA_idx);
+ break;
+ case 2:
+ rx_pwr_all = pout + 5 - (2 * VGA_idx);
+ break;
+ /*case 6:*/
+ /*rx_pwr_all = pout -26 - (2*VGA_idx);*/
+ /*break;*/
+ /*case 4:*/
+ /*rx_pwr_all = pout - 8 - (2*VGA_idx);*/
+ /*break;*/
+ /*case 1:*/
+ /*rx_pwr_all = pout + 21 - (2*VGA_idx);*/
+ /*break;*/
+ /*case 0:*/
+ /*rx_pwr_all = pout + 10 - (2*VGA_idx);*/
+ /* break; */
+ default:
+ /* dbg_print("CCK Exception default\n"); */
+ break;
+ }
+ PWDB_ALL = odm_query_rx_pwr_percentage(rx_pwr_all);
+ }
+
+ p_dm_odm->cck_lna_idx = LNA_idx;
+ p_dm_odm->cck_vga_idx = VGA_idx;
+ p_phy_info->rx_pwdb_all = PWDB_ALL;
+ /* if(p_pktinfo->station_id == 0) */
+ /* { */
+ /* dbg_print("CCK: LNA_idx = %d, VGA_idx = %d, p_phy_info->rx_pwdb_all = %d\n", */
+ /* LNA_idx, VGA_idx, p_phy_info->rx_pwdb_all); */
+ /* } */
+ p_phy_info->bt_rx_rssi_percentage = PWDB_ALL;
+ p_phy_info->recv_signal_power = rx_pwr_all;
+ /*(3) Get Signal Quality (EVM)*/
+ /*if (p_pktinfo->is_packet_match_bssid)*/
+ {
+ u8 SQ, SQ_rpt;
+
+ if ((p_dm_odm->support_platform == ODM_WIN) &&
+ (p_dm_odm->patch_id == RT_CID_819X_LENOVO))
+ SQ = odm_sq_process_patch_rt_cid_819x_lenovo(p_dm_odm, is_cck_rate, PWDB_ALL, 0, 0);
+ else if (p_phy_info->rx_pwdb_all > 40 && !p_dm_odm->is_in_hct_test)
+ SQ = 100;
+ else {
+ SQ_rpt = p_phy_sta_rpt->pwdb_all;
+
+ if (SQ_rpt > 64)
+ SQ = 0;
+ else if (SQ_rpt < 20)
+ SQ = 100;
+ else
+ SQ = ((64 - SQ_rpt) * 100) / 44;
+ }
+
+ /* dbg_print("cck SQ = %d\n", SQ); */
+ p_phy_info->signal_quality = SQ;
+ p_phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = SQ;
+ }
+
+ for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
+ if (i == 0)
+ p_phy_info->rx_mimo_signal_strength[0] = PWDB_ALL;
+ else
+ p_phy_info->rx_mimo_signal_strength[i] = 0;
+ }
+ } else {
+ /*is OFDM rate*/
+ p_dm_fat_table->hw_antsw_occur = p_phy_sta_rpt->hw_antsw_occur;
+
+ p_dm_odm->phy_dbg_info.num_qry_phy_status_ofdm++;
+
+ /*(1)Get RSSI for OFDM rate*/
+
+ for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
+ /*2008/01/30 MH we will judge RF RX path now.*/
+ /* dbg_print("p_dm_odm->rf_path_rx_enable = %x\n", p_dm_odm->rf_path_rx_enable); */
+ if (p_dm_odm->rf_path_rx_enable & BIT(i))
+ rf_rx_num++;
+ /* else */
+ /* continue; */
+ /*2012.05.25 LukeLee: Testchip AGC report is wrong, it should be restored back to old formula in MP chip*/
+ /* if((p_dm_odm->support_ic_type & (ODM_RTL8812|ODM_RTL8821)) && (!p_dm_odm->is_mp_chip)) */
+ if (i < ODM_RF_PATH_C)
+ rx_pwr[i] = (p_phy_sta_rpt->gain_trsw[i] & 0x7F) - 110;
+ else
+ rx_pwr[i] = (p_phy_sta_rpt->gain_trsw_cd[i - 2] & 0x7F) - 110;
+ /* else */
+ /*rx_pwr[i] = ((p_phy_sta_rpt->gain_trsw[i]& 0x3F)*2) - 110; OLD FORMULA*/
+
+ p_phy_info->rx_pwr[i] = rx_pwr[i];
+
+ /* Translate DBM to percentage. */
+ RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]);
+
+ /*total_rssi += RSSI;*/
+ /*Get the best two RSSI*/
+ if (RSSI > best_rssi && RSSI > second_rssi) {
+ second_rssi = best_rssi;
+ best_rssi = RSSI;
+ } else if (RSSI > second_rssi && RSSI <= best_rssi)
+ second_rssi = RSSI;
+
+ /*RT_DISP(FRX, RX_PHY_SS, ("RF-%d RXPWR=%x RSSI=%d\n", i, rx_pwr[i], RSSI));*/
+
+ p_phy_info->rx_mimo_signal_strength[i] = (u8) RSSI;
+
+ /*Get Rx snr value in DB*/
+ if (i < ODM_RF_PATH_C)
+ p_phy_info->rx_snr[i] = p_dm_odm->phy_dbg_info.rx_snr_db[i] = p_phy_sta_rpt->rxsnr[i] / 2;
+ else if (p_dm_odm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B))
+ p_phy_info->rx_snr[i] = p_dm_odm->phy_dbg_info.rx_snr_db[i] = p_phy_sta_rpt->csi_current[i - 2] / 2;
+
+ /*(2) CFO_short & CFO_tail*/
+ if (i < ODM_RF_PATH_C) {
+ p_phy_info->cfo_short[i] = odm_cfo((p_phy_sta_rpt->cfosho[i]));
+ p_phy_info->cfo_tail[i] = odm_cfo((p_phy_sta_rpt->cfotail[i]));
+ }
+ }
+
+ /*(3)PWDB, Average PWDB calculated by hardware (for rate adaptive)*/
+
+ /*2012.05.25 LukeLee: Testchip AGC report is wrong, it should be restored back to old formula in MP chip*/
+ if ((p_dm_odm->support_ic_type & (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) && (!p_dm_odm->is_mp_chip))
+ rx_pwr_all = (p_phy_sta_rpt->pwdb_all & 0x7f) - 110;
+ else
+ rx_pwr_all = (((p_phy_sta_rpt->pwdb_all) >> 1) & 0x7f) - 110; /*OLD FORMULA*/
+
+ PWDB_ALL_BT = PWDB_ALL = odm_query_rx_pwr_percentage(rx_pwr_all);
+
+ p_phy_info->rx_pwdb_all = PWDB_ALL;
+ /*ODM_RT_TRACE(p_dm_odm,ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("ODM OFDM RSSI=%d\n",p_phy_info->rx_pwdb_all));*/
+ p_phy_info->bt_rx_rssi_percentage = PWDB_ALL_BT;
+ p_phy_info->rx_power = rx_pwr_all;
+ p_phy_info->recv_signal_power = rx_pwr_all;
+
+ if ((p_dm_odm->support_platform == ODM_WIN) && (p_dm_odm->patch_id == 19)) {
+ /*do nothing*/
+ } else {
+ /*p_mgnt_info->customer_id != RT_CID_819X_LENOVO*/
+
+ /*(4)EVM of OFDM rate*/
+
+ if ((p_pktinfo->data_rate >= ODM_RATEMCS8) &&
+ (p_pktinfo->data_rate <= ODM_RATEMCS15))
+ max_spatial_stream = 2;
+ else if ((p_pktinfo->data_rate >= ODM_RATEVHTSS2MCS0) &&
+ (p_pktinfo->data_rate <= ODM_RATEVHTSS2MCS9))
+ max_spatial_stream = 2;
+ else if ((p_pktinfo->data_rate >= ODM_RATEMCS16) &&
+ (p_pktinfo->data_rate <= ODM_RATEMCS23))
+ max_spatial_stream = 3;
+ else if ((p_pktinfo->data_rate >= ODM_RATEVHTSS3MCS0) &&
+ (p_pktinfo->data_rate <= ODM_RATEVHTSS3MCS9))
+ max_spatial_stream = 3;
+ else
+ max_spatial_stream = 1;
+
+ /*if (p_pktinfo->is_packet_match_bssid) */
+ {
+ /*dbg_print("p_pktinfo->data_rate = %d\n", p_pktinfo->data_rate);*/
+
+ for (i = 0; i < max_spatial_stream; i++) {
+ /*Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment*/
+ /*fill most significant bit to "zero" when doing shifting operation which may change a negative*/
+ /*value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.*/
+
+ if (p_pktinfo->data_rate >= ODM_RATE6M && p_pktinfo->data_rate <= ODM_RATE54M) {
+ if (i == ODM_RF_PATH_A) {
+ EVM = odm_evm_db_to_percentage((p_phy_sta_rpt->sigevm)); /*dbm*/
+ EVM += 20;
+ if (EVM > 100)
+ EVM = 100;
+ }
+ } else {
+ if (i < ODM_RF_PATH_C) {
+ if (p_phy_sta_rpt->rxevm[i] == -128)
+ p_phy_sta_rpt->rxevm[i] = -25;
+ EVM = odm_evm_db_to_percentage((p_phy_sta_rpt->rxevm[i])); /*dbm*/
+ } else {
+ if (p_phy_sta_rpt->rxevm_cd[i - 2] == -128)
+ p_phy_sta_rpt->rxevm_cd[i - 2] = -25;
+ EVM = odm_evm_db_to_percentage((p_phy_sta_rpt->rxevm_cd[i - 2])); /*dbm*/
+ }
+ }
+
+ if (i < ODM_RF_PATH_C)
+ evm_dbm = odm_evm_dbm_jaguar_series(p_phy_sta_rpt->rxevm[i]);
+ else
+ evm_dbm = odm_evm_dbm_jaguar_series(p_phy_sta_rpt->rxevm_cd[i - 2]);
+ /*RT_DISP(FRX, RX_PHY_SQ, ("RXRATE=%x RXEVM=%x EVM=%s%d\n",*/
+ /*p_pktinfo->data_rate, p_phy_sta_rpt->rxevm[i], "%", EVM));*/
+
+ {
+ if (i == ODM_RF_PATH_A) {
+ /*Fill value in RFD, Get the first spatial stream only*/
+ p_phy_info->signal_quality = EVM;
+ }
+ p_phy_info->rx_mimo_signal_quality[i] = EVM;
+ p_phy_info->rx_mimo_evm_dbm[i] = evm_dbm;
+ }
+ }
+ }
+ }
+
+ num_ss = phydm_rate_to_num_ss(p_dm_odm, p_pktinfo->data_rate);
+ odm_parsing_cfo(p_dm_odm, p_pktinfo, p_phy_sta_rpt->cfotail, num_ss);
+
+ }
+ /* dbg_print("is_cck_rate= %d, p_phy_info->signal_strength=%d % PWDB_AL=%d rf_rx_num=%d\n", is_cck_rate, p_phy_info->signal_strength, PWDB_ALL, rf_rx_num); */
+
+ /*UI BSS List signal strength(in percentage), make it good looking, from 0~100.*/
+ /*It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().*/
+ if (is_cck_rate) {
+ p_phy_info->signal_strength = (u8)(odm_signal_scale_mapping(p_dm_odm, PWDB_ALL));/*PWDB_ALL;*/
+ } else {
+ if (rf_rx_num != 0) {
+ /* 2015/01 Sean, use the best two RSSI only, suggested by Ynlin and ChenYu.*/
+ if (rf_rx_num == 1)
+ avg_rssi = best_rssi;
+ else
+ avg_rssi = (best_rssi + second_rssi) / 2;
+ p_phy_info->signal_strength = (u8)(odm_signal_scale_mapping(p_dm_odm, avg_rssi));
+ }
+ }
+ p_dm_odm->rx_pwdb_ave = p_dm_odm->rx_pwdb_ave + p_phy_info->rx_pwdb_all;
+
+ p_dm_odm->dm_fat_table.antsel_rx_keep_0 = p_phy_sta_rpt->antidx_anta;
+ p_dm_odm->dm_fat_table.antsel_rx_keep_1 = p_phy_sta_rpt->antidx_antb;
+ p_dm_odm->dm_fat_table.antsel_rx_keep_2 = p_phy_sta_rpt->antidx_antc;
+ p_dm_odm->dm_fat_table.antsel_rx_keep_3 = p_phy_sta_rpt->antidx_antd;
+ /*ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("StaID[%d]: antidx_anta = ((%d)), MatchBSSID = ((%d))\n", p_pktinfo->station_id, p_phy_sta_rpt->antidx_anta, p_pktinfo->is_packet_match_bssid));*/
+
+ /* dbg_print("p_phy_sta_rpt->antidx_anta = %d, p_phy_sta_rpt->antidx_antb = %d\n",*/
+ /* p_phy_sta_rpt->antidx_anta, p_phy_sta_rpt->antidx_antb);*/
+ /* dbg_print("----------------------------\n");*/
+ /* dbg_print("p_pktinfo->station_id=%d, p_pktinfo->data_rate=0x%x\n",p_pktinfo->station_id, p_pktinfo->data_rate);*/
+ /* dbg_print("p_phy_sta_rpt->r_RFMOD = %d\n", p_phy_sta_rpt->r_RFMOD);*/
+ /* dbg_print("p_phy_sta_rpt->gain_trsw[0]=0x%x, p_phy_sta_rpt->gain_trsw[1]=0x%x\n",*/
+ /* p_phy_sta_rpt->gain_trsw[0],p_phy_sta_rpt->gain_trsw[1]);*/
+ /* dbg_print("p_phy_sta_rpt->gain_trsw[2]=0x%x, p_phy_sta_rpt->gain_trsw[3]=0x%x\n",*/
+ /* p_phy_sta_rpt->gain_trsw_cd[0],p_phy_sta_rpt->gain_trsw_cd[1]);*/
+ /* dbg_print("p_phy_sta_rpt->pwdb_all = 0x%x, p_phy_info->rx_pwdb_all = %d\n", p_phy_sta_rpt->pwdb_all, p_phy_info->rx_pwdb_all);*/
+ /* dbg_print("p_phy_sta_rpt->cfotail[i] = 0x%x, p_phy_sta_rpt->CFO_tail[i] = 0x%x\n", p_phy_sta_rpt->cfotail[0], p_phy_sta_rpt->cfotail[1]);*/
+ /* dbg_print("p_phy_sta_rpt->rxevm[0] = %d, p_phy_sta_rpt->rxevm[1] = %d\n", p_phy_sta_rpt->rxevm[0], p_phy_sta_rpt->rxevm[1]);*/
+ /* dbg_print("p_phy_sta_rpt->rxevm[2] = %d, p_phy_sta_rpt->rxevm[3] = %d\n", p_phy_sta_rpt->rxevm_cd[0], p_phy_sta_rpt->rxevm_cd[1]);*/
+ /* dbg_print("p_phy_info->rx_mimo_signal_strength[0]=%d, p_phy_info->rx_mimo_signal_strength[1]=%d, rx_pwdb_all=%d\n",*/
+ /* p_phy_info->rx_mimo_signal_strength[0], p_phy_info->rx_mimo_signal_strength[1], p_phy_info->rx_pwdb_all);*/
+ /* dbg_print("p_phy_info->rx_mimo_signal_strength[2]=%d, p_phy_info->rx_mimo_signal_strength[3]=%d\n",*/
+ /* p_phy_info->rx_mimo_signal_strength[2], p_phy_info->rx_mimo_signal_strength[3]);*/
+ /* dbg_print("ppPhyInfo->rx_mimo_signal_quality[0]=%d, p_phy_info->rx_mimo_signal_quality[1]=%d\n",*/
+ /* p_phy_info->rx_mimo_signal_quality[0], p_phy_info->rx_mimo_signal_quality[1]);*/
+ /* dbg_print("ppPhyInfo->rx_mimo_signal_quality[2]=%d, p_phy_info->rx_mimo_signal_quality[3]=%d\n",*/
+ /* p_phy_info->rx_mimo_signal_quality[2], p_phy_info->rx_mimo_signal_quality[3]);*/
+
+}
+
+#endif
+
+void
+phydm_reset_rssi_for_dm(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 station_id
+)
+{
+ struct sta_info *p_entry;
+
+ p_entry = p_dm_odm->p_odm_sta_info[station_id];
+
+ if (!IS_STA_VALID(p_entry)) {
+ /**/
+ return;
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("Reset RSSI for macid = (( %d ))\n", station_id));
+
+ p_entry->rssi_stat.undecorated_smoothed_cck = -1;
+ p_entry->rssi_stat.undecorated_smoothed_ofdm = -1;
+ p_entry->rssi_stat.undecorated_smoothed_pwdb = -1;
+ p_entry->rssi_stat.ofdm_pkt = 0;
+ p_entry->rssi_stat.cck_pkt = 0;
+ p_entry->rssi_stat.cck_sum_power = 0;
+ p_entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_INIT;
+ p_entry->rssi_stat.packet_map = 0;
+ p_entry->rssi_stat.valid_bit = 0;
+}
+
+void
+odm_init_rssi_for_dm(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+
+}
+
+static void
+odm_process_rssi_for_dm(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct _odm_phy_status_info_ *p_phy_info,
+ struct _odm_per_pkt_info_ *p_pktinfo
+)
+{
+
+ s32 undecorated_smoothed_pwdb, undecorated_smoothed_cck, undecorated_smoothed_ofdm, rssi_ave, cck_pkt;
+ u8 i, is_cck_rate = 0;
+ u8 RSSI_max, RSSI_min;
+ u32 weighting = 0;
+ u8 send_rssi_2_fw = 0;
+ struct sta_info *p_entry;
+
+ if (p_pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM)
+ return;
+
+#ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY
+ odm_s0s1_sw_ant_div_by_ctrl_frame_process_rssi(p_dm_odm, p_phy_info, p_pktinfo);
+#endif
+
+ /* */
+ /* 2012/05/30 MH/Luke.Lee Add some description */
+ /* In windows driver: AP/IBSS mode STA */
+ /* */
+ /* if (p_dm_odm->support_platform == ODM_WIN) */
+ /* { */
+ /* p_entry = p_dm_odm->p_odm_sta_info[p_dm_odm->pAidMap[p_pktinfo->station_id-1]]; */
+ /* } */
+ /* else */
+ p_entry = p_dm_odm->p_odm_sta_info[p_pktinfo->station_id];
+
+ if (!IS_STA_VALID(p_entry)) {
+ return;
+ /**/
+ }
+
+ if ((!p_pktinfo->is_packet_match_bssid))/*data frame only*/
+ return;
+
+ if (p_pktinfo->is_packet_beacon)
+ p_dm_odm->phy_dbg_info.num_qry_beacon_pkt++;
+
+ is_cck_rate = (p_pktinfo->data_rate <= ODM_RATE11M) ? true : false;
+ p_dm_odm->rx_rate = p_pktinfo->data_rate;
+
+ /* --------------Statistic for antenna/path diversity------------------ */
+ if (p_dm_odm->support_ability & ODM_BB_ANT_DIV) {
+#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))
+ odm_process_rssi_for_ant_div(p_dm_odm, p_phy_info, p_pktinfo);
+#endif
+ }
+#if (defined(CONFIG_PATH_DIVERSITY))
+ else if (p_dm_odm->support_ability & ODM_BB_PATH_DIV)
+ phydm_process_rssi_for_path_div(p_dm_odm, p_phy_info, p_pktinfo);
+#endif
+ /* -----------------Smart Antenna Debug Message------------------ */
+
+ undecorated_smoothed_cck = p_entry->rssi_stat.undecorated_smoothed_cck;
+ undecorated_smoothed_ofdm = p_entry->rssi_stat.undecorated_smoothed_ofdm;
+ undecorated_smoothed_pwdb = p_entry->rssi_stat.undecorated_smoothed_pwdb;
+
+ if (p_pktinfo->is_packet_to_self || p_pktinfo->is_packet_beacon) {
+
+ if (!is_cck_rate) { /* ofdm rate */
+ {
+ if (p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B] == 0) {
+ rssi_ave = p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
+ p_dm_odm->RSSI_A = p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
+ p_dm_odm->RSSI_B = 0;
+ } else {
+ /*dbg_print("p_rfd->status.rx_mimo_signal_strength[0] = %d, p_rfd->status.rx_mimo_signal_strength[1] = %d\n",*/
+ /*p_rfd->status.rx_mimo_signal_strength[0], p_rfd->status.rx_mimo_signal_strength[1]);*/
+ p_dm_odm->RSSI_A = p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
+ p_dm_odm->RSSI_B = p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
+
+ if (p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] > p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) {
+ RSSI_max = p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
+ RSSI_min = p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
+ } else {
+ RSSI_max = p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
+ RSSI_min = p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
+ }
+ if ((RSSI_max - RSSI_min) < 3)
+ rssi_ave = RSSI_max;
+ else if ((RSSI_max - RSSI_min) < 6)
+ rssi_ave = RSSI_max - 1;
+ else if ((RSSI_max - RSSI_min) < 10)
+ rssi_ave = RSSI_max - 2;
+ else
+ rssi_ave = RSSI_max - 3;
+ }
+ }
+
+ /* 1 Process OFDM RSSI */
+ if (undecorated_smoothed_ofdm <= 0) { /* initialize */
+ undecorated_smoothed_ofdm = p_phy_info->rx_pwdb_all;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("OFDM_INIT: (( %d ))\n", undecorated_smoothed_ofdm));
+ } else {
+ if (p_phy_info->rx_pwdb_all > (u32)undecorated_smoothed_ofdm) {
+ undecorated_smoothed_ofdm =
+ (((undecorated_smoothed_ofdm)*(RX_SMOOTH_FACTOR - 1)) +
+ (rssi_ave)) / (RX_SMOOTH_FACTOR);
+ undecorated_smoothed_ofdm = undecorated_smoothed_ofdm + 1;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("OFDM_1: (( %d ))\n", undecorated_smoothed_ofdm));
+ } else {
+ undecorated_smoothed_ofdm =
+ (((undecorated_smoothed_ofdm)*(RX_SMOOTH_FACTOR - 1)) +
+ (rssi_ave)) / (RX_SMOOTH_FACTOR);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("OFDM_2: (( %d ))\n", undecorated_smoothed_ofdm));
+ }
+ }
+ if (p_entry->rssi_stat.ofdm_pkt != 64) {
+ i = 63;
+ p_entry->rssi_stat.ofdm_pkt -= (u8)(((p_entry->rssi_stat.packet_map >> i) & BIT(0)) - 1);
+ }
+ p_entry->rssi_stat.packet_map = (p_entry->rssi_stat.packet_map << 1) | BIT(0);
+
+ } else {
+ rssi_ave = p_phy_info->rx_pwdb_all;
+ p_dm_odm->RSSI_A = (u8) p_phy_info->rx_pwdb_all;
+ p_dm_odm->RSSI_B = 0xFF;
+ p_dm_odm->RSSI_C = 0xFF;
+ p_dm_odm->RSSI_D = 0xFF;
+
+ if (p_entry->rssi_stat.cck_pkt <= 63)
+ p_entry->rssi_stat.cck_pkt++;
+
+ /* 1 Process CCK RSSI */
+ if (undecorated_smoothed_cck <= 0) { /* initialize */
+ undecorated_smoothed_cck = p_phy_info->rx_pwdb_all;
+ p_entry->rssi_stat.cck_sum_power = (u16)p_phy_info->rx_pwdb_all ; /*reset*/
+ p_entry->rssi_stat.cck_pkt = 1; /*reset*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("CCK_INIT: (( %d ))\n", undecorated_smoothed_cck));
+ } else if (p_entry->rssi_stat.cck_pkt <= CCK_RSSI_INIT_COUNT) {
+
+ p_entry->rssi_stat.cck_sum_power = p_entry->rssi_stat.cck_sum_power + (u16)p_phy_info->rx_pwdb_all;
+ undecorated_smoothed_cck = p_entry->rssi_stat.cck_sum_power / p_entry->rssi_stat.cck_pkt;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("CCK_0: (( %d )), SumPow = (( %d )), cck_pkt = (( %d ))\n",
+ undecorated_smoothed_cck, p_entry->rssi_stat.cck_sum_power, p_entry->rssi_stat.cck_pkt));
+ } else {
+ if (p_phy_info->rx_pwdb_all > (u32)undecorated_smoothed_cck) {
+ undecorated_smoothed_cck =
+ (((undecorated_smoothed_cck)*(RX_SMOOTH_FACTOR - 1)) +
+ (p_phy_info->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
+ undecorated_smoothed_cck = undecorated_smoothed_cck + 1;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("CCK_1: (( %d ))\n", undecorated_smoothed_cck));
+ } else {
+ undecorated_smoothed_cck =
+ (((undecorated_smoothed_cck)*(RX_SMOOTH_FACTOR - 1)) +
+ (p_phy_info->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("CCK_2: (( %d ))\n", undecorated_smoothed_cck));
+ }
+ }
+ i = 63;
+ p_entry->rssi_stat.ofdm_pkt -= (u8)((p_entry->rssi_stat.packet_map >> i) & BIT(0));
+ p_entry->rssi_stat.packet_map = p_entry->rssi_stat.packet_map << 1;
+ }
+
+ /* if(p_entry) */
+ {
+ /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */
+ if (p_entry->rssi_stat.ofdm_pkt == 64) { /* speed up when all packets are OFDM*/
+ undecorated_smoothed_pwdb = undecorated_smoothed_ofdm;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("PWDB_0[%d] = (( %d ))\n", p_pktinfo->station_id, undecorated_smoothed_cck));
+ } else {
+ if (p_entry->rssi_stat.valid_bit < 64)
+ p_entry->rssi_stat.valid_bit++;
+
+ if (p_entry->rssi_stat.valid_bit == 64) {
+ weighting = ((p_entry->rssi_stat.ofdm_pkt) > 4) ? 64 : (p_entry->rssi_stat.ofdm_pkt << 4);
+ undecorated_smoothed_pwdb = (weighting * undecorated_smoothed_ofdm + (64 - weighting) * undecorated_smoothed_cck) >> 6;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("PWDB_1[%d] = (( %d )), W = (( %d ))\n", p_pktinfo->station_id, undecorated_smoothed_cck, weighting));
+ } else {
+ if (p_entry->rssi_stat.valid_bit != 0)
+ undecorated_smoothed_pwdb = (p_entry->rssi_stat.ofdm_pkt * undecorated_smoothed_ofdm + (p_entry->rssi_stat.valid_bit - p_entry->rssi_stat.ofdm_pkt) * undecorated_smoothed_cck) / p_entry->rssi_stat.valid_bit;
+ else
+ undecorated_smoothed_pwdb = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("PWDB_2[%d] = (( %d )), ofdm_pkt = (( %d )), Valid_Bit = (( %d ))\n", p_pktinfo->station_id, undecorated_smoothed_cck, p_entry->rssi_stat.ofdm_pkt, p_entry->rssi_stat.valid_bit));
+ }
+ }
+
+ if ((p_entry->rssi_stat.ofdm_pkt >= 1 || p_entry->rssi_stat.cck_pkt >= 5) && (p_entry->rssi_stat.is_send_rssi == RA_RSSI_STATE_INIT)) {
+
+ send_rssi_2_fw = 1;
+ p_entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_SEND;
+ }
+
+ p_entry->rssi_stat.undecorated_smoothed_cck = undecorated_smoothed_cck;
+ p_entry->rssi_stat.undecorated_smoothed_ofdm = undecorated_smoothed_ofdm;
+ p_entry->rssi_stat.undecorated_smoothed_pwdb = undecorated_smoothed_pwdb;
+
+ if (send_rssi_2_fw) { /* Trigger init rate by RSSI */
+
+ if (p_entry->rssi_stat.ofdm_pkt != 0)
+ p_entry->rssi_stat.undecorated_smoothed_pwdb = undecorated_smoothed_ofdm;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RSSI_MONITOR, ODM_DBG_LOUD, ("[Send to FW] PWDB = (( %d )), ofdm_pkt = (( %d )), cck_pkt = (( %d ))\n",
+ undecorated_smoothed_pwdb, p_entry->rssi_stat.ofdm_pkt, p_entry->rssi_stat.cck_pkt));
+
+ phydm_ra_rssi_rpt_wk(p_dm_odm);
+ }
+ }
+
+ }
+}
+
+#if (ODM_IC_11N_SERIES_SUPPORT == 1)
+/*
+ * Endianness before calling this API
+ * */
+static void
+odm_phy_status_query_92c_series(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct _odm_phy_status_info_ *p_phy_info,
+ u8 *p_phy_status,
+ struct _odm_per_pkt_info_ *p_pktinfo
+)
+{
+ odm_rx_phy_status92c_series_parsing(p_dm_odm, p_phy_info, p_phy_status, p_pktinfo);
+ odm_process_rssi_for_dm(p_dm_odm, p_phy_info, p_pktinfo);
+}
+#endif
+
+/*
+ * Endianness before calling this API
+ * */
+#if ODM_IC_11AC_SERIES_SUPPORT
+
+void
+odm_phy_status_query_jaguar_series(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct _odm_phy_status_info_ *p_phy_info,
+ u8 *p_phy_status,
+ struct _odm_per_pkt_info_ *p_pktinfo
+)
+{
+ odm_rx_phy_status_jaguar_series_parsing(p_dm_odm, p_phy_info, p_phy_status, p_pktinfo);
+ odm_process_rssi_for_dm(p_dm_odm, p_phy_info, p_pktinfo);
+
+}
+#endif
+
+void
+odm_phy_status_query(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct _odm_phy_status_info_ *p_phy_info,
+ u8 *p_phy_status,
+ struct _odm_per_pkt_info_ *p_pktinfo
+)
+{
+#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1)
+ if (p_dm_odm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE) {
+ phydm_rx_phy_status_new_type(p_dm_odm, p_phy_status, p_pktinfo, p_phy_info);
+ return;
+ }
+#endif
+
+#if ODM_IC_11AC_SERIES_SUPPORT
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
+ odm_phy_status_query_jaguar_series(p_dm_odm, p_phy_info, p_phy_status, p_pktinfo);
+#endif
+
+#if ODM_IC_11N_SERIES_SUPPORT
+ if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
+ odm_phy_status_query_92c_series(p_dm_odm, p_phy_info, p_phy_status, p_pktinfo);
+#endif
+}
+
+/* For future use. */
+void
+odm_mac_status_query(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 *p_mac_status,
+ u8 mac_id,
+ bool is_packet_match_bssid,
+ bool is_packet_to_self,
+ bool is_packet_beacon
+)
+{
+ /* 2011/10/19 Driver team will handle in the future. */
+
+}
+
+/*
+ * If you want to add a new IC, Please follow below template and generate a new one.
+ *
+ * */
+
+enum hal_status
+odm_config_rf_with_header_file(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_rf_config_type config_type,
+ enum odm_rf_radio_path_e e_rf_path
+)
+{
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
+ ("===>odm_config_rf_with_header_file (%s)\n", (p_dm_odm->is_mp_chip) ? "MPChip" : "TestChip"));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
+ ("p_dm_odm->support_platform: 0x%X, p_dm_odm->support_interface: 0x%X, p_dm_odm->board_type: 0x%X\n",
+ p_dm_odm->support_platform, p_dm_odm->support_interface, p_dm_odm->board_type));
+
+ /* 1 AP doesn't use PHYDM power tracking table in these ICs */
+
+ /* 1 All platforms support */
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E) {
+ if (config_type == CONFIG_RF_RADIO) {
+ if (e_rf_path == ODM_RF_PATH_A)
+ READ_AND_CONFIG_MP(8188e, _radioa);
+ } else if (config_type == CONFIG_RF_TXPWR_LMT)
+ READ_AND_CONFIG_MP(8188e, _txpwr_lmt);
+ }
+ return HAL_STATUS_SUCCESS;
+}
+
+enum hal_status
+odm_config_rf_with_tx_pwr_track_header_file(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
+ ("===>odm_config_rf_with_tx_pwr_track_header_file (%s)\n", (p_dm_odm->is_mp_chip) ? "MPChip" : "TestChip"));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
+ ("p_dm_odm->support_platform: 0x%X, p_dm_odm->support_interface: 0x%X, p_dm_odm->board_type: 0x%X\n",
+ p_dm_odm->support_platform, p_dm_odm->support_interface, p_dm_odm->board_type));
+
+ /* 1 AP doesn't use PHYDM power tracking table in these ICs */
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E) {
+ if (odm_get_mac_reg(p_dm_odm, 0xF0, 0xF000) >= 8) { /*if 0xF0[15:12] >= 8, SMIC*/
+ if (p_dm_odm->support_interface == ODM_ITRF_PCIE)
+ READ_AND_CONFIG_MP(8188e, _txpowertrack_pcie_icut);
+ else if (p_dm_odm->support_interface == ODM_ITRF_USB)
+ READ_AND_CONFIG_MP(8188e, _txpowertrack_usb_icut);
+ else if (p_dm_odm->support_interface == ODM_ITRF_SDIO)
+ READ_AND_CONFIG_MP(8188e, _txpowertrack_sdio_icut);
+ } else { /*else 0xF0[15:12] < 8, TSMC*/
+ if (p_dm_odm->support_interface == ODM_ITRF_PCIE)
+ READ_AND_CONFIG_MP(8188e, _txpowertrack_pcie);
+ else if (p_dm_odm->support_interface == ODM_ITRF_USB)
+ READ_AND_CONFIG_MP(8188e, _txpowertrack_usb);
+ else if (p_dm_odm->support_interface == ODM_ITRF_SDIO)
+ READ_AND_CONFIG_MP(8188e, _txpowertrack_sdio);
+ }
+
+ }
+
+ /* 1 All platforms support */
+ return HAL_STATUS_SUCCESS;
+}
+
+enum hal_status
+odm_config_bb_with_header_file(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_bb_config_type config_type
+)
+{
+ /* 1 All platforms support */
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E) {
+ if (config_type == CONFIG_BB_PHY_REG)
+ READ_AND_CONFIG_MP(8188e, _phy_reg);
+ else if (config_type == CONFIG_BB_AGC_TAB)
+ READ_AND_CONFIG_MP(8188e, _agc_tab);
+ else if (config_type == CONFIG_BB_PHY_REG_PG)
+ READ_AND_CONFIG_MP(8188e, _phy_reg_pg);
+ }
+ return HAL_STATUS_SUCCESS;
+}
+
+enum hal_status
+odm_config_mac_with_header_file(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
+ ("===>odm_config_mac_with_header_file (%s)\n", (p_dm_odm->is_mp_chip) ? "MPChip" : "TestChip"));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
+ ("p_dm_odm->support_platform: 0x%X, p_dm_odm->support_interface: 0x%X, p_dm_odm->board_type: 0x%X\n",
+ p_dm_odm->support_platform, p_dm_odm->support_interface, p_dm_odm->board_type));
+
+ /* 1 All platforms support */
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E)
+ READ_AND_CONFIG_MP(8188e, _mac_reg);
+ return HAL_STATUS_SUCCESS;
+}
+
+enum hal_status
+odm_config_fw_with_header_file(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_fw_config_type config_type,
+ u8 *p_firmware,
+ u32 *p_size
+)
+{
+ return HAL_STATUS_SUCCESS;
+}
+
+u32
+odm_get_hw_img_version(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 version = 0;
+
+ /*1 All platforms support*/
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E)
+ version = GET_VERSION_MP(8188e, _mac_reg);
+ return version;
+}
+
+#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1)
+/* For 8822B only!! need to move to FW finally */
+/*==============================================*/
+
+bool
+phydm_query_is_mu_api(
+ struct PHY_DM_STRUCT *p_phydm,
+ u8 ppdu_idx,
+ u8 *p_data_rate,
+ u8 *p_gid
+)
+{
+ u8 data_rate = 0, gid = 0;
+ bool is_mu = FALSE;
+
+ data_rate = p_phydm->phy_dbg_info.num_of_ppdu[ppdu_idx];
+ gid = p_phydm->phy_dbg_info.gid_num[ppdu_idx];
+
+ if (data_rate & BIT(7)) {
+ is_mu = TRUE;
+ data_rate = data_rate & ~(BIT(7));
+ } else
+ is_mu = FALSE;
+
+ *p_data_rate = data_rate;
+ *p_gid = gid;
+
+ return is_mu;
+
+}
+
+void
+phydm_rx_statistic_cal(
+ struct PHY_DM_STRUCT *p_phydm,
+ u8 *p_phy_status,
+ struct _odm_per_pkt_info_ *p_pktinfo
+)
+{
+ struct _phy_status_rpt_jaguar2_type1 *p_phy_sta_rpt = (struct _phy_status_rpt_jaguar2_type1 *)p_phy_status;
+ u8 date_rate = p_pktinfo->data_rate & ~(BIT(7));
+
+ if ((p_phy_sta_rpt->gid != 0) && (p_phy_sta_rpt->gid != 63)) {
+ if (date_rate >= ODM_RATEVHTSS1MCS0) {
+ p_phydm->phy_dbg_info.num_qry_mu_vht_pkt[date_rate - 0x2C]++;
+ p_phydm->phy_dbg_info.num_of_ppdu[p_pktinfo->ppdu_cnt] = date_rate | BIT(7);
+ p_phydm->phy_dbg_info.gid_num[p_pktinfo->ppdu_cnt] = p_phy_sta_rpt->gid;
+ }
+
+ } else {
+ if (date_rate >= ODM_RATEVHTSS1MCS0) {
+ p_phydm->phy_dbg_info.num_qry_vht_pkt[date_rate - 0x2C]++;
+ p_phydm->phy_dbg_info.num_of_ppdu[p_pktinfo->ppdu_cnt] = date_rate;
+ p_phydm->phy_dbg_info.gid_num[p_pktinfo->ppdu_cnt] = p_phy_sta_rpt->gid;
+ }
+ }
+
+}
+
+void
+phydm_reset_phy_info(
+ struct PHY_DM_STRUCT *p_phydm,
+ struct _odm_phy_status_info_ *p_phy_info
+)
+{
+ p_phy_info->rx_pwdb_all = 0;
+ p_phy_info->signal_quality = 0;
+ p_phy_info->band_width = 0;
+ p_phy_info->rx_count = 0;
+ odm_memory_set(p_phydm, p_phy_info->rx_mimo_signal_quality, 0, 4);
+ odm_memory_set(p_phydm, p_phy_info->rx_mimo_signal_strength, 0, 4);
+ odm_memory_set(p_phydm, p_phy_info->rx_snr, 0, 4);
+
+ p_phy_info->rx_power = -110;
+ p_phy_info->recv_signal_power = -110;
+ p_phy_info->bt_rx_rssi_percentage = 0;
+ p_phy_info->signal_strength = 0;
+ p_phy_info->bt_coex_pwr_adjust = 0;
+ p_phy_info->channel = 0;
+ p_phy_info->is_mu_packet = 0;
+ p_phy_info->is_beamformed = 0;
+ p_phy_info->rxsc = 0;
+ odm_memory_set(p_phydm, p_phy_info->rx_pwr, -110, 4);
+ odm_memory_set(p_phydm, p_phy_info->rx_mimo_evm_dbm, 0, 4);
+ odm_memory_set(p_phydm, p_phy_info->cfo_short, 0, 8);
+ odm_memory_set(p_phydm, p_phy_info->cfo_tail, 0, 8);
+}
+
+void
+phydm_set_per_path_phy_info(
+ u8 rx_path,
+ s8 rx_pwr,
+ s8 rx_evm,
+ s8 cfo_tail,
+ s8 rx_snr,
+ struct _odm_phy_status_info_ *p_phy_info
+)
+{
+ u8 evm_dbm = 0;
+ u8 evm_percentage = 0;
+
+ /* SNR is S(8,1), EVM is S(8,1), CFO is S(8,7) */
+
+ if (rx_evm < 0) {
+ /* Calculate EVM in dBm */
+ evm_dbm = ((u8)(0 - rx_evm) >> 1);
+
+ /* Calculate EVM in percentage */
+ if (evm_dbm >= 33)
+ evm_percentage = 100;
+ else
+ evm_percentage = (evm_dbm << 1) + (evm_dbm);
+ }
+
+ p_phy_info->rx_pwr[rx_path] = rx_pwr;
+ p_phy_info->rx_mimo_evm_dbm[rx_path] = evm_dbm;
+
+ /* CFO = CFO_tail * 312.5 / 2^7 ~= CFO tail * 39/512 (kHz)*/
+ p_phy_info->cfo_tail[rx_path] = cfo_tail;
+ p_phy_info->cfo_tail[rx_path] = ((p_phy_info->cfo_tail[rx_path] << 5) + (p_phy_info->cfo_tail[rx_path] << 2) +
+ (p_phy_info->cfo_tail[rx_path] << 1) + (p_phy_info->cfo_tail[rx_path])) >> 9;
+
+ p_phy_info->rx_mimo_signal_strength[rx_path] = odm_query_rx_pwr_percentage(rx_pwr);
+ p_phy_info->rx_mimo_signal_quality[rx_path] = evm_percentage;
+ p_phy_info->rx_snr[rx_path] = rx_snr >> 1;
+}
+
+void
+phydm_set_common_phy_info(
+ s8 rx_power,
+ u8 channel,
+ bool is_beamformed,
+ bool is_mu_packet,
+ u8 bandwidth,
+ u8 signal_quality,
+ u8 rxsc,
+ struct _odm_phy_status_info_ *p_phy_info
+)
+{
+ p_phy_info->rx_power = rx_power; /* RSSI in dB */
+ p_phy_info->recv_signal_power = rx_power; /* RSSI in dB */
+ p_phy_info->channel = channel; /* channel number */
+ p_phy_info->is_beamformed = is_beamformed; /* apply BF */
+ p_phy_info->is_mu_packet = is_mu_packet; /* MU packet */
+ p_phy_info->rxsc = rxsc;
+ p_phy_info->rx_pwdb_all = odm_query_rx_pwr_percentage(rx_power); /* RSSI in percentage */
+ p_phy_info->signal_quality = signal_quality; /* signal quality */
+ p_phy_info->band_width = bandwidth; /* bandwidth */
+}
+
+void
+phydm_get_rx_phy_status_type0(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 *p_phy_status,
+ struct _odm_per_pkt_info_ *p_pktinfo,
+ struct _odm_phy_status_info_ *p_phy_info
+)
+{
+ /* type 0 is used for cck packet */
+
+ struct _phy_status_rpt_jaguar2_type0 *p_phy_sta_rpt = (struct _phy_status_rpt_jaguar2_type0 *)p_phy_status;
+ u8 i, SQ = 0;
+ s8 rx_power = p_phy_sta_rpt->pwdb - 110;
+
+#if (RTL8723D_SUPPORT == 1)
+ if (p_dm_odm->support_ic_type & ODM_RTL8723D)
+ rx_power = p_phy_sta_rpt->pwdb - 97;
+#endif
+#if (RTL8197F_SUPPORT == 1)
+ if (p_dm_odm->support_ic_type & ODM_RTL8197F)
+ rx_power = p_phy_sta_rpt->pwdb - 97;
+#endif
+
+ /* Calculate Signal Quality*/
+ if (p_pktinfo->is_packet_match_bssid) {
+ if (p_phy_sta_rpt->signal_quality >= 64)
+ SQ = 0;
+ else if (p_phy_sta_rpt->signal_quality <= 20)
+ SQ = 100;
+ else {
+ /* mapping to 2~99% */
+ SQ = 64 - p_phy_sta_rpt->signal_quality;
+ SQ = ((SQ << 3) + SQ) >> 2;
+ }
+ }
+
+ /* Modify CCK PWDB if old AGC */
+ if (p_dm_odm->cck_new_agc == false) {
+ u8 lna_idx, vga_idx;
+
+ lna_idx = ((p_phy_sta_rpt->lna_h << 3) | p_phy_sta_rpt->lna_l);
+ vga_idx = p_phy_sta_rpt->vga;
+ }
+
+ /* Update CCK packet counter */
+ p_dm_odm->phy_dbg_info.num_qry_phy_status_cck++;
+
+ /*CCK no STBC and LDPC*/
+ p_dm_odm->phy_dbg_info.is_ldpc_pkt = false;
+ p_dm_odm->phy_dbg_info.is_stbc_pkt = false;
+
+ /* Update Common information */
+ phydm_set_common_phy_info(rx_power, p_phy_sta_rpt->channel, false,
+ false, ODM_BW20M, SQ, p_phy_sta_rpt->rxsc, p_phy_info);
+
+ /* Update CCK pwdb */
+ phydm_set_per_path_phy_info(ODM_RF_PATH_A, rx_power, 0, 0, 0, p_phy_info); /* Update per-path information */
+
+ p_dm_odm->dm_fat_table.antsel_rx_keep_0 = p_phy_sta_rpt->antidx_a;
+ p_dm_odm->dm_fat_table.antsel_rx_keep_1 = p_phy_sta_rpt->antidx_b;
+ p_dm_odm->dm_fat_table.antsel_rx_keep_2 = p_phy_sta_rpt->antidx_c;
+ p_dm_odm->dm_fat_table.antsel_rx_keep_3 = p_phy_sta_rpt->antidx_d;
+}
+
+void
+phydm_get_rx_phy_status_type1(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 *p_phy_status,
+ struct _odm_per_pkt_info_ *p_pktinfo,
+ struct _odm_phy_status_info_ *p_phy_info
+)
+{
+ /* type 1 is used for ofdm packet */
+
+ struct _phy_status_rpt_jaguar2_type1 *p_phy_sta_rpt = (struct _phy_status_rpt_jaguar2_type1 *)p_phy_status;
+ s8 rx_pwr_db = -120;
+ u8 i, rxsc, bw = ODM_BW20M, rx_count = 0;
+ bool is_mu;
+ u8 num_ss;
+
+ /* Update OFDM packet counter */
+ p_dm_odm->phy_dbg_info.num_qry_phy_status_ofdm++;
+
+ /* Update per-path information */
+ for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
+ if (p_dm_odm->rx_ant_status & BIT(i)) {
+ s8 rx_path_pwr_db;
+
+ /* RX path counter */
+ rx_count++;
+
+ /* Update per-path information (RSSI_dB RSSI_percentage EVM SNR CFO SQ) */
+ /* EVM report is reported by stream, not path */
+ rx_path_pwr_db = p_phy_sta_rpt->pwdb[i] - 110; /* per-path pwdb in dB domain */
+ phydm_set_per_path_phy_info(i, rx_path_pwr_db, p_phy_sta_rpt->rxevm[rx_count - 1],
+ p_phy_sta_rpt->cfo_tail[i], p_phy_sta_rpt->rxsnr[i], p_phy_info);
+
+ /* search maximum pwdb */
+ if (rx_path_pwr_db > rx_pwr_db)
+ rx_pwr_db = rx_path_pwr_db;
+ }
+ }
+
+ /* mapping RX counter from 1~4 to 0~3 */
+ if (rx_count > 0)
+ p_phy_info->rx_count = rx_count - 1;
+
+ /* Check if MU packet or not */
+ if ((p_phy_sta_rpt->gid != 0) && (p_phy_sta_rpt->gid != 63)) {
+ is_mu = true;
+ p_dm_odm->phy_dbg_info.num_qry_mu_pkt++;
+ } else
+ is_mu = false;
+
+ /* count BF packet */
+ p_dm_odm->phy_dbg_info.num_qry_bf_pkt = p_dm_odm->phy_dbg_info.num_qry_bf_pkt + p_phy_sta_rpt->beamformed;
+
+ /*STBC or LDPC pkt*/
+ p_dm_odm->phy_dbg_info.is_ldpc_pkt = p_phy_sta_rpt->ldpc;
+ p_dm_odm->phy_dbg_info.is_stbc_pkt = p_phy_sta_rpt->stbc;
+
+ /* Check sub-channel */
+ if ((p_pktinfo->data_rate > ODM_RATE11M) && (p_pktinfo->data_rate < ODM_RATEMCS0))
+ rxsc = p_phy_sta_rpt->l_rxsc;
+ else
+ rxsc = p_phy_sta_rpt->ht_rxsc;
+
+ /* Check RX bandwidth */
+ if (p_dm_odm->support_ic_type & ODM_RTL8822B) {
+ if ((rxsc >= 1) && (rxsc <= 8))
+ bw = ODM_BW20M;
+ else if ((rxsc >= 9) && (rxsc <= 12))
+ bw = ODM_BW40M;
+ else if (rxsc >= 13)
+ bw = ODM_BW80M;
+ else
+ bw = p_phy_sta_rpt->rf_mode;
+ } else if (p_dm_odm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D)) {
+ if (p_phy_sta_rpt->rf_mode == 0)
+ bw = ODM_BW20M;
+ else if ((rxsc == 1) || (rxsc == 2))
+ bw = ODM_BW20M;
+ else
+ bw = ODM_BW40M;
+ }
+
+ /* Update packet information */
+ phydm_set_common_phy_info(rx_pwr_db, p_phy_sta_rpt->channel, (bool)p_phy_sta_rpt->beamformed,
+ is_mu, bw, odm_evm_db_to_percentage(p_phy_sta_rpt->rxevm[0]), rxsc, p_phy_info);
+
+ num_ss = phydm_rate_to_num_ss(p_dm_odm, p_pktinfo->data_rate);
+
+ odm_parsing_cfo(p_dm_odm, p_pktinfo, p_phy_sta_rpt->cfo_tail, num_ss);
+ p_dm_odm->dm_fat_table.antsel_rx_keep_0 = p_phy_sta_rpt->antidx_a;
+ p_dm_odm->dm_fat_table.antsel_rx_keep_1 = p_phy_sta_rpt->antidx_b;
+ p_dm_odm->dm_fat_table.antsel_rx_keep_2 = p_phy_sta_rpt->antidx_c;
+ p_dm_odm->dm_fat_table.antsel_rx_keep_3 = p_phy_sta_rpt->antidx_d;
+
+ if (p_pktinfo->is_packet_match_bssid) {
+ /*
+ dbg_print("channel = %d, band = %d, l_rxsc = %d, ht_rxsc = %d, rf_mode = %d\n", p_phy_sta_rpt->channel, p_phy_sta_rpt->band, p_phy_sta_rpt->l_rxsc, p_phy_sta_rpt->ht_rxsc, p_phy_sta_rpt->rf_mode);
+ dbg_print("Antidx A = %d, B = %d, C = %d, D = %d\n", p_phy_sta_rpt->antidx_a, p_phy_sta_rpt->antidx_b, p_phy_sta_rpt->antidx_c, p_phy_sta_rpt->antidx_d);
+ dbg_print("pwdb A: 0x%x, B: 0x%x, C: 0x%x, D: 0x%x\n", p_phy_sta_rpt->pwdb[0], p_phy_sta_rpt->pwdb[1], p_phy_sta_rpt->pwdb[2], p_phy_sta_rpt->pwdb[3]);
+ dbg_print("EVM A: %d, B: %d, C: %d, D: %d\n", p_phy_sta_rpt->rxevm[0], p_phy_sta_rpt->rxevm[1], p_phy_sta_rpt->rxevm[2], p_phy_sta_rpt->rxevm[3]);
+ dbg_print("SNR A: %d, B: %d, C: %d, D: %d\n", p_phy_sta_rpt->rxsnr[0], p_phy_sta_rpt->rxsnr[1], p_phy_sta_rpt->rxsnr[2], p_phy_sta_rpt->rxsnr[3]);
+ dbg_print("CFO A: %d, B: %d, C: %d, D: %d\n", p_phy_sta_rpt->cfo_tail[0], p_phy_sta_rpt->cfo_tail[1], p_phy_sta_rpt->cfo_tail[2], p_phy_sta_rpt->cfo_tail[3]);
+ dbg_print("paid = %d, gid = %d, length = %d\n", (p_phy_sta_rpt->paid + (p_phy_sta_rpt->paid_msb<<8)), p_phy_sta_rpt->gid, p_phy_sta_rpt->lsig_length);
+ dbg_print("ldpc: %d, stbc: %d, bf: %d, gnt_bt: %d, antsw: %d\n", p_phy_sta_rpt->ldpc, p_phy_sta_rpt->stbc, p_phy_sta_rpt->beamformed, p_phy_sta_rpt->gnt_bt, p_phy_sta_rpt->hw_antsw_occu);
+ dbg_print("NBI: %d, pos: %d\n", p_phy_sta_rpt->nb_intf_flag, (p_phy_sta_rpt->intf_pos + (p_phy_sta_rpt->intf_pos_msb<<8)));
+ dbg_print("rsvd_0 = %d, rsvd_1 = %d, rsvd_2 = %d, rsvd_3 = %d, rsvd_4 = %d, rsvd_5 = %d\n", p_phy_sta_rpt->rsvd_0, p_phy_sta_rpt->rsvd_1, p_phy_sta_rpt->rsvd_2, p_phy_sta_rpt->rsvd_3, p_phy_sta_rpt->rsvd_4, p_phy_sta_rpt->rsvd_5);
+ */
+ phydm_rx_statistic_cal(p_dm_odm, p_phy_status, p_pktinfo);
+ }
+ /*
+ dbg_print("phydm_get_rx_phy_status_type1 p_pktinfo->is_packet_match_bssid = %d\n", p_pktinfo->is_packet_match_bssid);
+ dbg_print("p_pktinfo->data_rate = 0x%x\n", p_pktinfo->data_rate);
+ */
+}
+
+void
+phydm_get_rx_phy_status_type2(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 *p_phy_status,
+ struct _odm_per_pkt_info_ *p_pktinfo,
+ struct _odm_phy_status_info_ *p_phy_info
+)
+{
+ struct _phy_status_rpt_jaguar2_type2 *p_phy_sta_rpt = (struct _phy_status_rpt_jaguar2_type2 *)p_phy_status;
+ s8 rx_pwr_db = -120;
+ u8 i, rxsc, bw = ODM_BW20M, rx_count = 0;
+
+ /* Update OFDM packet counter */
+ p_dm_odm->phy_dbg_info.num_qry_phy_status_ofdm++;
+
+ /* Update per-path information */
+ for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
+ if (p_dm_odm->rx_ant_status & BIT(i)) {
+ s8 rx_path_pwr_db;
+
+ /* RX path counter */
+ rx_count++;
+
+ /* Update per-path information (RSSI_dB RSSI_percentage EVM SNR CFO SQ) */
+#if (RTL8197F_SUPPORT == 1)
+ if ((p_dm_odm->support_ic_type & ODM_RTL8197F) && (p_phy_sta_rpt->pwdb[i] == 0x7f)) { /*for 97f workaround*/
+
+ if (i == ODM_RF_PATH_A) {
+ rx_path_pwr_db = (p_phy_sta_rpt->gain_a) << 1;
+ rx_path_pwr_db = rx_path_pwr_db - 110;
+ } else if (i == ODM_RF_PATH_B) {
+ rx_path_pwr_db = (p_phy_sta_rpt->gain_b) << 1;
+ rx_path_pwr_db = rx_path_pwr_db - 110;
+ } else
+ rx_path_pwr_db = 0;
+ } else
+#endif
+ rx_path_pwr_db = p_phy_sta_rpt->pwdb[i] - 110; /* per-path pwdb in dB domain */
+
+ phydm_set_per_path_phy_info(i, rx_path_pwr_db, 0, 0, 0, p_phy_info);
+
+ /* search maximum pwdb */
+ if (rx_path_pwr_db > rx_pwr_db)
+ rx_pwr_db = rx_path_pwr_db;
+ }
+ }
+
+ /* mapping RX counter from 1~4 to 0~3 */
+ if (rx_count > 0)
+ p_phy_info->rx_count = rx_count - 1;
+
+ /* Check RX sub-channel */
+ if ((p_pktinfo->data_rate > ODM_RATE11M) && (p_pktinfo->data_rate < ODM_RATEMCS0))
+ rxsc = p_phy_sta_rpt->l_rxsc;
+ else
+ rxsc = p_phy_sta_rpt->ht_rxsc;
+
+ /*STBC or LDPC pkt*/
+ p_dm_odm->phy_dbg_info.is_ldpc_pkt = p_phy_sta_rpt->ldpc;
+ p_dm_odm->phy_dbg_info.is_stbc_pkt = p_phy_sta_rpt->stbc;
+
+ /* Check RX bandwidth */
+ /* the BW information of sc=0 is useless, because there is no information of RF mode*/
+
+ if (p_dm_odm->support_ic_type & ODM_RTL8822B) {
+ if ((rxsc >= 1) && (rxsc <= 8))
+ bw = ODM_BW20M;
+ else if ((rxsc >= 9) && (rxsc <= 12))
+ bw = ODM_BW40M;
+ else if (rxsc >= 13)
+ bw = ODM_BW80M;
+ else
+ bw = ODM_BW20M;
+ } else if (p_dm_odm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D)) {
+ if (rxsc == 3)
+ bw = ODM_BW40M;
+ else if ((rxsc == 1) || (rxsc == 2))
+ bw = ODM_BW20M;
+ else
+ bw = ODM_BW20M;
+ }
+
+ /* Update packet information */
+ phydm_set_common_phy_info(rx_pwr_db, p_phy_sta_rpt->channel, (bool)p_phy_sta_rpt->beamformed,
+ false, bw, 0, rxsc, p_phy_info);
+
+}
+
+void
+phydm_get_rx_phy_status_type5(
+ u8 *p_phy_status
+)
+{
+}
+
+void
+phydm_process_rssi_for_dm_new_type(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct _odm_phy_status_info_ *p_phy_info,
+ struct _odm_per_pkt_info_ *p_pktinfo
+)
+{
+ s32 undecorated_smoothed_pwdb, accumulate_pwdb;
+ u32 rssi_ave;
+ u8 i;
+ struct sta_info *p_entry;
+ u8 scaling_factor = 4;
+
+ if (p_pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM)
+ return;
+
+ p_entry = p_dm_odm->p_odm_sta_info[p_pktinfo->station_id];
+
+ if (!IS_STA_VALID(p_entry))
+ return;
+
+ if ((!p_pktinfo->is_packet_match_bssid))/*data frame only*/
+ return;
+
+ if (p_pktinfo->is_packet_beacon)
+ p_dm_odm->phy_dbg_info.num_qry_beacon_pkt++;
+
+#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))
+ if (p_dm_odm->support_ability & ODM_BB_ANT_DIV)
+ odm_process_rssi_for_ant_div(p_dm_odm, p_phy_info, p_pktinfo);
+#endif
+
+#if (CONFIG_DYNAMIC_RX_PATH == 1)
+ phydm_process_phy_status_for_dynamic_rx_path(p_dm_odm, p_phy_info, p_pktinfo);
+ dbg_print("====>\n");
+#endif
+
+ if (p_pktinfo->is_packet_to_self || p_pktinfo->is_packet_beacon) {
+ u32 RSSI_linear = 0;
+
+ p_dm_odm->rx_rate = p_pktinfo->data_rate;
+ undecorated_smoothed_pwdb = p_entry->rssi_stat.undecorated_smoothed_pwdb;
+ accumulate_pwdb = p_dm_odm->accumulate_pwdb[p_pktinfo->station_id];
+ p_dm_odm->RSSI_A = p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A];
+ p_dm_odm->RSSI_B = p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B];
+ p_dm_odm->RSSI_C = p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_C];
+ p_dm_odm->RSSI_D = p_phy_info->rx_mimo_signal_strength[ODM_RF_PATH_D];
+
+ for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) {
+ if (p_phy_info->rx_mimo_signal_strength[i] != 0)
+ RSSI_linear += odm_convert_to_linear(p_phy_info->rx_mimo_signal_strength[i]);
+ }
+
+ switch (p_phy_info->rx_count + 1) {
+ case 2:
+ RSSI_linear = (RSSI_linear >> 1);
+ break;
+ case 3:
+ RSSI_linear = ((RSSI_linear) + (RSSI_linear << 1) + (RSSI_linear << 3)) >> 5; /* RSSI_linear/3 ~ RSSI_linear*11/32 */
+ break;
+ case 4:
+ RSSI_linear = (RSSI_linear >> 2);
+ break;
+ }
+ rssi_ave = odm_convert_to_db(RSSI_linear);
+
+ if (undecorated_smoothed_pwdb <= 0) {
+ accumulate_pwdb = (p_phy_info->rx_pwdb_all << scaling_factor);
+ undecorated_smoothed_pwdb = p_phy_info->rx_pwdb_all;
+ } else {
+ accumulate_pwdb = accumulate_pwdb - (accumulate_pwdb >> scaling_factor) + rssi_ave;
+ undecorated_smoothed_pwdb = (accumulate_pwdb + (1 << (scaling_factor - 1))) >> scaling_factor;
+ }
+
+ if (p_entry->rssi_stat.undecorated_smoothed_pwdb == -1)
+ phydm_ra_rssi_rpt_wk(p_dm_odm);
+ p_entry->rssi_stat.undecorated_smoothed_pwdb = undecorated_smoothed_pwdb;
+ p_dm_odm->accumulate_pwdb[p_pktinfo->station_id] = accumulate_pwdb;
+ }
+}
+
+void
+phydm_rx_phy_status_new_type(
+ struct PHY_DM_STRUCT *p_phydm,
+ u8 *p_phy_status,
+ struct _odm_per_pkt_info_ *p_pktinfo,
+ struct _odm_phy_status_info_ *p_phy_info
+)
+{
+ u8 phy_status_type = (*p_phy_status & 0xf);
+
+ /* Memory reset */
+ phydm_reset_phy_info(p_phydm, p_phy_info);
+
+ /* Phy status parsing */
+ switch (phy_status_type) {
+ case 0:
+ phydm_get_rx_phy_status_type0(p_phydm, p_phy_status, p_pktinfo, p_phy_info);
+ break;
+ case 1:
+ phydm_get_rx_phy_status_type1(p_phydm, p_phy_status, p_pktinfo, p_phy_info);
+ break;
+ case 2:
+ phydm_get_rx_phy_status_type2(p_phydm, p_phy_status, p_pktinfo, p_phy_info);
+ break;
+ default:
+ return;
+ }
+
+ /* Update signal strength to UI, and p_phy_info->rx_pwdb_all is the maximum RSSI of all path */
+ p_phy_info->signal_strength = (u8)(odm_signal_scale_mapping(p_phydm, p_phy_info->rx_pwdb_all));
+
+ /* Calculate average RSSI and smoothed RSSI */
+ phydm_process_rssi_for_dm_new_type(p_phydm, p_phy_info, p_pktinfo);
+
+}
+/*==============================================*/
+#endif
+
+u32
+query_phydm_trx_capability(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 value32 = 0xFFFFFFFF;
+
+#if (RTL8821C_SUPPORT == 1)
+ if (p_dm_odm->support_ic_type == ODM_RTL8821C)
+ value32 = query_phydm_trx_capability_8821c(p_dm_odm);
+#endif
+
+ return value32;
+}
+
+u32
+query_phydm_stbc_capability(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 value32 = 0xFFFFFFFF;
+
+#if (RTL8821C_SUPPORT == 1)
+ if (p_dm_odm->support_ic_type == ODM_RTL8821C)
+ value32 = query_phydm_stbc_capability_8821c(p_dm_odm);
+#endif
+
+ return value32;
+}
+
+u32
+query_phydm_ldpc_capability(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 value32 = 0xFFFFFFFF;
+
+#if (RTL8821C_SUPPORT == 1)
+ if (p_dm_odm->support_ic_type == ODM_RTL8821C)
+ value32 = query_phydm_ldpc_capability_8821c(p_dm_odm);
+#endif
+
+ return value32;
+}
+
+u32
+query_phydm_txbf_parameters(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 value32 = 0xFFFFFFFF;
+
+#if (RTL8821C_SUPPORT == 1)
+ if (p_dm_odm->support_ic_type == ODM_RTL8821C)
+ value32 = query_phydm_txbf_parameters_8821c(p_dm_odm);
+#endif
+
+ return value32;
+}
+
+u32
+query_phydm_txbf_capability(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ u32 value32 = 0xFFFFFFFF;
+
+#if (RTL8821C_SUPPORT == 1)
+ if (p_dm_odm->support_ic_type == ODM_RTL8821C)
+ value32 = query_phydm_txbf_capability_8821c(p_dm_odm);
+#endif
+
+ return value32;
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_hwconfig.h b/drivers/staging/rtl8188eu/hal/phydm_hwconfig.h
new file mode 100644
index 000000000000..b1964a125e16
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_hwconfig.h
@@ -0,0 +1,547 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+
+#ifndef __HALHWOUTSRC_H__
+#define __HALHWOUTSRC_H__
+
+
+/*--------------------------Define -------------------------------------------*/
+#define CCK_RSSI_INIT_COUNT 5
+
+#define RA_RSSI_STATE_INIT 0
+#define RA_RSSI_STATE_SEND 1
+#define RA_RSSI_STATE_HOLD 2
+
+#define CFO_HW_RPT_2_MHZ(val) ((val<<1) + (val>>1))
+/* ((X* 3125) / 10)>>7 = (X*10)>>2 = X*2.5 = X<<1 + X>>1 */
+
+#define AGC_DIFF_CONFIG_MP(ic, band) (odm_read_and_config_mp_##ic##_agc_tab_diff(p_dm_odm, array_mp_##ic##_agc_tab_diff_##band, \
+ sizeof(array_mp_##ic##_agc_tab_diff_##band)/sizeof(u32)))
+#define AGC_DIFF_CONFIG_TC(ic, band) (odm_read_and_config_tc_##ic##_agc_tab_diff(p_dm_odm, array_tc_##ic##_agc_tab_diff_##band, \
+ sizeof(array_tc_##ic##_agc_tab_diff_##band)/sizeof(u32)))
+
+#define AGC_DIFF_CONFIG(ic, band) do {\
+ if (p_dm_odm->is_mp_chip)\
+ AGC_DIFF_CONFIG_MP(ic, band);\
+ else\
+ AGC_DIFF_CONFIG_TC(ic, band);\
+ } while (0)
+
+
+/* ************************************************************
+ * structure and define
+ * ************************************************************ */
+
+__PACK struct _phy_rx_agc_info {
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 gain: 7, trsw: 1;
+#else
+ u8 trsw: 1, gain: 7;
+#endif
+};
+
+__PACK struct _phy_status_rpt_8192cd {
+ struct _phy_rx_agc_info path_agc[2];
+ u8 ch_corr[2];
+ u8 cck_sig_qual_ofdm_pwdb_all;
+ u8 cck_agc_rpt_ofdm_cfosho_a;
+ u8 cck_rpt_b_ofdm_cfosho_b;
+ u8 rsvd_1;/*ch_corr_msb;*/
+ u8 noise_power_db_msb;
+ s8 path_cfotail[2];
+ u8 pcts_mask[2];
+ s8 stream_rxevm[2];
+ u8 path_rxsnr[2];
+ u8 noise_power_db_lsb;
+ u8 rsvd_2[3];
+ u8 stream_csi[2];
+ u8 stream_target_csi[2];
+ s8 sig_evm;
+ u8 rsvd_3;
+
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 antsel_rx_keep_2: 1; /*ex_intf_flg:1;*/
+ u8 sgi_en: 1;
+ u8 rxsc: 2;
+ u8 idle_long: 1;
+ u8 r_ant_train_en: 1;
+ u8 ant_sel_b: 1;
+ u8 ant_sel: 1;
+#else /*_BIG_ENDIAN_ */
+ u8 ant_sel: 1;
+ u8 ant_sel_b: 1;
+ u8 r_ant_train_en: 1;
+ u8 idle_long: 1;
+ u8 rxsc: 2;
+ u8 sgi_en: 1;
+ u8 antsel_rx_keep_2: 1;/*ex_intf_flg:1;*/
+#endif
+};
+
+
+struct _phy_status_rpt_8812 {
+ /* DWORD 0*/
+ u8 gain_trsw[2]; /*path-A and path-B {TRSW, gain[6:0] }*/
+ u8 chl_num_LSB; /*channel number[7:0]*/
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 chl_num_MSB: 2; /*channel number[9:8]*/
+ u8 sub_chnl: 4; /*sub-channel location[3:0]*/
+ u8 r_RFMOD: 2; /*RF mode[1:0]*/
+#else /*_BIG_ENDIAN_ */
+ u8 r_RFMOD: 2;
+ u8 sub_chnl: 4;
+ u8 chl_num_MSB: 2;
+#endif
+
+ /* DWORD 1*/
+ u8 pwdb_all; /*CCK signal quality / OFDM pwdb all*/
+ s8 cfosho[2]; /*DW1 byte 1 DW1 byte2 CCK AGC report and CCK_BB_Power / OFDM path-A and path-B short CFO*/
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ /*this should be checked again because the definition of 8812 and 8814 is different*/
+ /* u8 r_cck_rx_enable_pathc:2; cck rx enable pathc[1:0]*/
+ /* u8 cck_rx_path:4; cck rx path[3:0]*/
+ u8 resvd_0: 6;
+ u8 bt_RF_ch_MSB: 2; /*8812A:2'b0 8814A: bt rf channel keep[7:6]*/
+#else /*_BIG_ENDIAN_*/
+ u8 bt_RF_ch_MSB: 2;
+ u8 resvd_0: 6;
+#endif
+
+ /* DWORD 2*/
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 ant_div_sw_a: 1; /*8812A: ant_div_sw_a 8814A: 1'b0*/
+ u8 ant_div_sw_b: 1; /*8812A: ant_div_sw_b 8814A: 1'b0*/
+ u8 bt_RF_ch_LSB: 6; /*8812A: 6'b0 8814A: bt rf channel keep[5:0]*/
+#else /*_BIG_ENDIAN_ */
+ u8 bt_RF_ch_LSB: 6;
+ u8 ant_div_sw_b: 1;
+ u8 ant_div_sw_a: 1;
+#endif
+ s8 cfotail[2]; /*DW2 byte 1 DW2 byte 2 path-A and path-B CFO tail*/
+ u8 PCTS_MSK_RPT_0; /*PCTS mask report[7:0]*/
+ u8 PCTS_MSK_RPT_1; /*PCTS mask report[15:8]*/
+
+ /* DWORD 3*/
+ s8 rxevm[2]; /*DW3 byte 1 DW3 byte 2 stream 1 and stream 2 RX EVM*/
+ s8 rxsnr[2]; /*DW3 byte 3 DW4 byte 0 path-A and path-B RX SNR*/
+
+ /* DWORD 4*/
+ u8 PCTS_MSK_RPT_2; /*PCTS mask report[23:16]*/
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 PCTS_MSK_RPT_3: 6; /*PCTS mask report[29:24]*/
+ u8 pcts_rpt_valid: 1; /*pcts_rpt_valid*/
+ u8 resvd_1: 1; /*1'b0*/
+#else /*_BIG_ENDIAN_*/
+ u8 resvd_1: 1;
+ u8 pcts_rpt_valid: 1;
+ u8 PCTS_MSK_RPT_3: 6;
+#endif
+ s8 rxevm_cd[2]; /*DW 4 byte 3 DW5 byte 0 8812A: 16'b0 8814A: stream 3 and stream 4 RX EVM*/
+
+ /* DWORD 5*/
+ u8 csi_current[2]; /*DW5 byte 1 DW5 byte 2 8812A: stream 1 and 2 CSI 8814A: path-C and path-D RX SNR*/
+ u8 gain_trsw_cd[2]; /*DW5 byte 3 DW6 byte 0 path-C and path-D {TRSW, gain[6:0] }*/
+
+ /* DWORD 6*/
+ s8 sigevm; /*signal field EVM*/
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 antidx_antc: 3; /*8812A: 3'b0 8814A: antidx_antc[2:0]*/
+ u8 antidx_antd: 3; /*8812A: 3'b0 8814A: antidx_antd[2:0]*/
+ u8 dpdt_ctrl_keep: 1; /*8812A: 1'b0 8814A: dpdt_ctrl_keep*/
+ u8 GNT_BT_keep: 1; /*8812A: 1'b0 8814A: GNT_BT_keep*/
+#else /*_BIG_ENDIAN_*/
+ u8 GNT_BT_keep: 1;
+ u8 dpdt_ctrl_keep: 1;
+ u8 antidx_antd: 3;
+ u8 antidx_antc: 3;
+#endif
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 antidx_anta: 3; /*antidx_anta[2:0]*/
+ u8 antidx_antb: 3; /*antidx_antb[2:0]*/
+ u8 hw_antsw_occur: 2; /*1'b0*/
+#else /*_BIG_ENDIAN_*/
+ u8 hw_antsw_occur: 2;
+ u8 antidx_antb: 3;
+ u8 antidx_anta: 3;
+#endif
+};
+
+void
+phydm_reset_rssi_for_dm(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 station_id
+);
+
+void
+odm_init_rssi_for_dm(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+void
+odm_phy_status_query(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct _odm_phy_status_info_ *p_phy_info,
+ u8 *p_phy_status,
+ struct _odm_per_pkt_info_ *p_pktinfo
+);
+
+void
+odm_mac_status_query(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 *p_mac_status,
+ u8 mac_id,
+ bool is_packet_match_bssid,
+ bool is_packet_to_self,
+ bool is_packet_beacon
+);
+
+enum hal_status
+odm_config_rf_with_tx_pwr_track_header_file(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+enum hal_status
+odm_config_rf_with_header_file(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_rf_config_type config_type,
+ enum odm_rf_radio_path_e e_rf_path
+);
+
+enum hal_status
+odm_config_bb_with_header_file(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_bb_config_type config_type
+);
+
+enum hal_status
+odm_config_mac_with_header_file(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+enum hal_status
+odm_config_fw_with_header_file(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_fw_config_type config_type,
+ u8 *p_firmware,
+ u32 *p_size
+);
+
+u32
+odm_get_hw_img_version(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+s32
+odm_signal_scale_mapping(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ s32 curr_sig
+);
+
+#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1)
+/*For 8822B only!! need to move to FW finally */
+/*==============================================*/
+void
+phydm_rx_phy_status_new_type(
+ struct PHY_DM_STRUCT *p_phydm,
+ u8 *p_phy_status,
+ struct _odm_per_pkt_info_ *p_pktinfo,
+ struct _odm_phy_status_info_ *p_phy_info
+);
+
+bool
+phydm_query_is_mu_api(
+ struct PHY_DM_STRUCT *p_phydm,
+ u8 ppdu_idx,
+ u8 *p_data_rate,
+ u8 *p_gid
+);
+
+struct _phy_status_rpt_jaguar2_type0 {
+ /* DW0 */
+ u8 page_num;
+ u8 pwdb;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 gain: 6;
+ u8 rsvd_0: 1;
+ u8 trsw: 1;
+#else
+ u8 trsw: 1;
+ u8 rsvd_0: 1;
+ u8 gain: 6;
+#endif
+ u8 rsvd_1;
+
+ /* DW1 */
+ u8 rsvd_2;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 rxsc: 4;
+ u8 agc_table: 4;
+#else
+ u8 agc_table: 4;
+ u8 rxsc: 4;
+#endif
+ u8 channel;
+ u8 band;
+
+ /* DW2 */
+ u16 length;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 antidx_a: 3;
+ u8 antidx_b: 3;
+ u8 rsvd_3: 2;
+ u8 antidx_c: 3;
+ u8 antidx_d: 3;
+ u8 rsvd_4:2;
+#else
+ u8 rsvd_3: 2;
+ u8 antidx_b: 3;
+ u8 antidx_a: 3;
+ u8 rsvd_4:2;
+ u8 antidx_d: 3;
+ u8 antidx_c: 3;
+#endif
+
+ /* DW3 */
+ u8 signal_quality;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 vga:5;
+ u8 lna_l:3;
+ u8 bb_power:6;
+ u8 rsvd_9:1;
+ u8 lna_h:1;
+#else
+ u8 lna_l:3;
+ u8 vga:5;
+ u8 lna_h:1;
+ u8 rsvd_9:1;
+ u8 bb_power:6;
+#endif
+ u8 rsvd_5;
+
+ /* DW4 */
+ u32 rsvd_6;
+
+ /* DW5 */
+ u32 rsvd_7;
+
+ /* DW6 */
+ u32 rsvd_8;
+};
+
+struct _phy_status_rpt_jaguar2_type1 {
+ /* DW0 and DW1 */
+ u8 page_num;
+ u8 pwdb[4];
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 l_rxsc: 4;
+ u8 ht_rxsc: 4;
+#else
+ u8 ht_rxsc: 4;
+ u8 l_rxsc: 4;
+#endif
+ u8 channel;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 band: 2;
+ u8 rsvd_0: 1;
+ u8 hw_antsw_occu: 1;
+ u8 gnt_bt: 1;
+ u8 ldpc: 1;
+ u8 stbc: 1;
+ u8 beamformed: 1;
+#else
+ u8 beamformed: 1;
+ u8 stbc: 1;
+ u8 ldpc: 1;
+ u8 gnt_bt: 1;
+ u8 hw_antsw_occu: 1;
+ u8 rsvd_0: 1;
+ u8 band: 2;
+#endif
+
+ /* DW2 */
+ u16 lsig_length;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 antidx_a: 3;
+ u8 antidx_b: 3;
+ u8 rsvd_1: 2;
+ u8 antidx_c: 3;
+ u8 antidx_d: 3;
+ u8 rsvd_2: 2;
+#else
+ u8 rsvd_1: 2;
+ u8 antidx_b: 3;
+ u8 antidx_a: 3;
+ u8 rsvd_2: 2;
+ u8 antidx_d: 3;
+ u8 antidx_c: 3;
+#endif
+
+ /* DW3 */
+ u8 paid;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 paid_msb: 1;
+ u8 gid: 6;
+ u8 rsvd_3: 1;
+#else
+ u8 rsvd_3: 1;
+ u8 gid: 6;
+ u8 paid_msb: 1;
+#endif
+ u8 intf_pos;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 intf_pos_msb: 1;
+ u8 rsvd_4: 2;
+ u8 nb_intf_flag: 1;
+ u8 rf_mode: 2;
+ u8 rsvd_5: 2;
+#else
+ u8 rsvd_5: 2;
+ u8 rf_mode: 2;
+ u8 nb_intf_flag: 1;
+ u8 rsvd_4: 2;
+ u8 intf_pos_msb: 1;
+#endif
+
+ /* DW4 */
+ s8 rxevm[4]; /* s(8,1) */
+
+ /* DW5 */
+ s8 cfo_tail[4]; /* s(8,7) */
+
+ /* DW6 */
+ s8 rxsnr[4]; /* s(8,1) */
+};
+
+struct _phy_status_rpt_jaguar2_type2 {
+ /* DW0 ane DW1 */
+ u8 page_num;
+ u8 pwdb[4];
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 l_rxsc: 4;
+ u8 ht_rxsc: 4;
+#else
+ u8 ht_rxsc: 4;
+ u8 l_rxsc: 4;
+#endif
+ u8 channel;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 band: 2;
+ u8 rsvd_0: 1;
+ u8 hw_antsw_occu: 1;
+ u8 gnt_bt: 1;
+ u8 ldpc: 1;
+ u8 stbc: 1;
+ u8 beamformed: 1;
+#else
+ u8 beamformed: 1;
+ u8 stbc: 1;
+ u8 ldpc: 1;
+ u8 gnt_bt: 1;
+ u8 hw_antsw_occu: 1;
+ u8 rsvd_0: 1;
+ u8 band: 2;
+#endif
+
+ /* DW2 */
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 shift_l_map: 6;
+ u8 rsvd_1: 2;
+#else
+ u8 rsvd_1: 2;
+ u8 shift_l_map: 6;
+#endif
+ u8 cnt_pw2cca;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 agc_table_a: 4;
+ u8 agc_table_b: 4;
+ u8 agc_table_c: 4;
+ u8 agc_table_d: 4;
+#else
+ u8 agc_table_b: 4;
+ u8 agc_table_a: 4;
+ u8 agc_table_d: 4;
+ u8 agc_table_c: 4;
+#endif
+
+ /* DW3 ~ DW6*/
+ u8 cnt_cca2agc_rdy;
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 gain_a: 6;
+ u8 rsvd_2: 1;
+ u8 trsw_a: 1;
+ u8 gain_b: 6;
+ u8 rsvd_3: 1;
+ u8 trsw_b: 1;
+ u8 gain_c: 6;
+ u8 rsvd_4: 1;
+ u8 trsw_c: 1;
+ u8 gain_d: 6;
+ u8 rsvd_5: 1;
+ u8 trsw_d: 1;
+ u8 aagc_step_a: 2;
+ u8 aagc_step_b: 2;
+ u8 aagc_step_c: 2;
+ u8 aagc_step_d: 2;
+#else
+ u8 trsw_a: 1;
+ u8 rsvd_2: 1;
+ u8 gain_a: 6;
+ u8 trsw_b: 1;
+ u8 rsvd_3: 1;
+ u8 gain_b: 6;
+ u8 trsw_c: 1;
+ u8 rsvd_4: 1;
+ u8 gain_c: 6;
+ u8 trsw_d: 1;
+ u8 rsvd_5: 1;
+ u8 gain_d: 6;
+ u8 aagc_step_d: 2;
+ u8 aagc_step_c: 2;
+ u8 aagc_step_b: 2;
+ u8 aagc_step_a: 2;
+#endif
+ u8 ht_aagc_gain[4];
+ u8 dagc_gain[4];
+#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE)
+ u8 counter: 6;
+ u8 rsvd_6: 2;
+ u8 syn_count: 5;
+ u8 rsvd_7:3;
+#else
+ u8 rsvd_6: 2;
+ u8 counter: 6;
+ u8 rsvd_7:3;
+ u8 syn_count: 5;
+#endif
+};
+/*==============================================*/
+#endif /*#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1)*/
+
+u32
+query_phydm_trx_capability(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+u32
+query_phydm_stbc_capability(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+u32
+query_phydm_ldpc_capability(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+u32
+query_phydm_txbf_parameters(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+u32
+query_phydm_txbf_capability(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+#endif /*#ifndef __HALHWOUTSRC_H__*/
diff --git a/drivers/staging/rtl8188eu/hal/phydm_interface.c b/drivers/staging/rtl8188eu/hal/phydm_interface.c
new file mode 100644
index 000000000000..e4a18e55d350
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_interface.c
@@ -0,0 +1,451 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+/*
+ * ODM IO Relative API.
+ * */
+
+u8
+odm_read_1byte(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr
+)
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+
+ return rtw_read8(adapter, reg_addr);
+}
+
+u16
+odm_read_2byte(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr
+)
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+
+ return rtw_read16(adapter, reg_addr);
+}
+
+u32
+odm_read_4byte(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr
+)
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+
+ return rtw_read32(adapter, reg_addr);
+}
+
+void
+odm_write_1byte(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr,
+ u8 data
+)
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+
+ rtw_write8(adapter, reg_addr, data);
+}
+
+
+void
+odm_write_2byte(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr,
+ u16 data
+)
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+
+ rtw_write16(adapter, reg_addr, data);
+}
+
+void
+odm_write_4byte(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr,
+ u32 data
+)
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+
+ rtw_write32(adapter, reg_addr, data);
+}
+
+void
+odm_set_mac_reg(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr,
+ u32 bit_mask,
+ u32 data
+)
+{
+ phy_set_bb_reg(p_dm_odm->adapter, reg_addr, bit_mask, data);
+}
+
+u32
+odm_get_mac_reg(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr,
+ u32 bit_mask
+)
+{
+ return phy_query_mac_reg(p_dm_odm->adapter, reg_addr, bit_mask);
+}
+
+void
+odm_set_bb_reg(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr,
+ u32 bit_mask,
+ u32 data
+)
+{
+ phy_set_bb_reg(p_dm_odm->adapter, reg_addr, bit_mask, data);
+}
+
+u32
+odm_get_bb_reg(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr,
+ u32 bit_mask
+)
+{
+ return phy_query_bb_reg(p_dm_odm->adapter, reg_addr, bit_mask);
+}
+
+void
+odm_set_rf_reg(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_rf_radio_path_e e_rf_path,
+ u32 reg_addr,
+ u32 bit_mask,
+ u32 data
+)
+{
+ phy_set_rf_reg(p_dm_odm->adapter, e_rf_path, reg_addr, bit_mask, data);
+}
+
+u32
+odm_get_rf_reg(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_rf_radio_path_e e_rf_path,
+ u32 reg_addr,
+ u32 bit_mask
+)
+{
+ return phy_query_rf_reg(p_dm_odm->adapter, e_rf_path, reg_addr, bit_mask);
+}
+
+/*
+ * ODM Memory relative API.
+ * */
+void
+odm_allocate_memory(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ void **p_ptr,
+ u32 length
+)
+{
+ *p_ptr = rtw_zvmalloc(length);
+}
+
+/* length could be ignored, used to detect memory leakage. */
+void
+odm_free_memory(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ void *p_ptr,
+ u32 length
+)
+{
+ rtw_vmfree(p_ptr, length);
+}
+
+void
+odm_move_memory(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ void *p_dest,
+ void *p_src,
+ u32 length
+)
+{
+ memcpy(p_dest, p_src, length);
+}
+
+void odm_memory_set(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ void *pbuf,
+ s8 value,
+ u32 length
+)
+{
+ memset(pbuf, value, length);
+}
+
+s32 odm_compare_memory(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ void *p_buf1,
+ void *p_buf2,
+ u32 length
+)
+{
+ return !memcmp(p_buf1, p_buf2, length);
+}
+
+/*
+ * ODM MISC relative API.
+ * */
+void
+odm_acquire_spin_lock(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum rt_spinlock_type type
+)
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+
+ rtw_odm_acquirespinlock(adapter, type);
+}
+
+void
+odm_release_spin_lock(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum rt_spinlock_type type
+)
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ rtw_odm_releasespinlock(adapter, type);
+}
+
+/*
+ * ODM Timer relative API.
+ * */
+void
+odm_stall_execution(
+ u32 us_delay
+)
+{
+ rtw_udelay_os(us_delay);
+}
+
+void
+ODM_delay_ms(u32 ms)
+{
+ rtw_mdelay_os(ms);
+}
+
+void
+ODM_delay_us(u32 us)
+{
+ rtw_udelay_os(us);
+}
+
+void
+ODM_sleep_ms(u32 ms)
+{
+ rtw_msleep_os(ms);
+}
+
+void
+ODM_sleep_us(u32 us)
+{
+ rtw_usleep_os(us);
+}
+
+void
+odm_set_timer(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct timer_list *p_timer,
+ u32 ms_delay
+)
+{
+ _set_timer(p_timer, ms_delay); /* ms */
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
+void
+odm_initialize_timer(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct timer_list *p_timer,
+ void *call_back_func,
+ void *p_context,
+ const char *sz_id
+)
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ _init_timer(p_timer, adapter->pnetdev, call_back_func, p_dm_odm);
+}
+#endif
+
+void
+odm_cancel_timer(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct timer_list *p_timer
+)
+{
+ _cancel_timer_ex(p_timer);
+}
+
+void
+odm_release_timer(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct timer_list *p_timer
+)
+{
+}
+
+static u8
+phydm_trans_h2c_id(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 phydm_h2c_id
+)
+{
+ u8 platform_h2c_id = phydm_h2c_id;
+
+ switch (phydm_h2c_id) {
+ /* 1 [0] */
+ case ODM_H2C_RSSI_REPORT:
+ platform_h2c_id = H2C_RSSI_SETTING;
+ break;
+ /* 1 [3] */
+ case ODM_H2C_WIFI_CALIBRATION:
+ break;
+ /* 1 [4] */
+ case ODM_H2C_IQ_CALIBRATION:
+ break;
+ /* 1 [5] */
+ case ODM_H2C_RA_PARA_ADJUST:
+ break;
+ /* 1 [6] */
+ case PHYDM_H2C_DYNAMIC_TX_PATH:
+ break;
+ /* [7]*/
+ case PHYDM_H2C_FW_TRACE_EN:
+ platform_h2c_id = 0x49;
+ break;
+ case PHYDM_H2C_TXBF:
+ break;
+ case PHYDM_H2C_MU:
+ break;
+ default:
+ platform_h2c_id = phydm_h2c_id;
+ break;
+ }
+ return platform_h2c_id;
+}
+
+/*ODM FW relative API.*/
+
+void
+odm_fill_h2c_cmd(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 phydm_h2c_id,
+ u32 cmd_len,
+ u8 *p_cmd_buffer
+)
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ u8 platform_h2c_id;
+
+ platform_h2c_id = phydm_trans_h2c_id(p_dm_odm, phydm_h2c_id);
+
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("[H2C] platform_h2c_id = ((0x%x))\n", platform_h2c_id));
+
+ rtw_hal_fill_h2c_cmd(adapter, platform_h2c_id, cmd_len, p_cmd_buffer);
+}
+
+u8
+phydm_c2H_content_parsing(
+ void *p_dm_void,
+ u8 c2h_cmd_id,
+ u8 c2h_cmd_len,
+ u8 *tmp_buf
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 extend_c2h_sub_id = 0;
+ u8 find_c2h_cmd = true;
+
+ switch (c2h_cmd_id) {
+ case PHYDM_C2H_DBG:
+ phydm_fw_trace_handler(p_dm_odm, tmp_buf, c2h_cmd_len);
+ break;
+ case PHYDM_C2H_RA_RPT:
+ phydm_c2h_ra_report_handler(p_dm_odm, tmp_buf, c2h_cmd_len);
+ break;
+ case PHYDM_C2H_RA_PARA_RPT:
+ odm_c2h_ra_para_report_handler(p_dm_odm, tmp_buf, c2h_cmd_len);
+ break;
+ case PHYDM_C2H_DYNAMIC_TX_PATH_RPT:
+ if (p_dm_odm->support_ic_type & (ODM_RTL8814A))
+ phydm_c2h_dtp_handler(p_dm_odm, tmp_buf, c2h_cmd_len);
+ break;
+ case PHYDM_C2H_IQK_FINISH:
+ break;
+ case PHYDM_C2H_DBG_CODE:
+ phydm_fw_trace_handler_code(p_dm_odm, tmp_buf, c2h_cmd_len);
+ break;
+
+ case PHYDM_C2H_EXTEND:
+ extend_c2h_sub_id = tmp_buf[0];
+ if (extend_c2h_sub_id == PHYDM_EXTEND_C2H_DBG_PRINT)
+ phydm_fw_trace_handler_8051(p_dm_odm, tmp_buf, c2h_cmd_len);
+
+ break;
+ default:
+ find_c2h_cmd = false;
+ break;
+ }
+ return find_c2h_cmd;
+}
+
+u64
+odm_get_current_time(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+ return (u64)jiffies;
+}
+
+u64
+odm_get_progressing_time(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u64 start_time
+)
+{
+ return rtw_get_passing_time_ms((u32)start_time);
+}
+
+void
+phydm_set_hw_reg_handler_interface (
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 RegName,
+ u8 *val
+ )
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+
+ adapter->hal_func.set_hw_reg_handler(adapter, RegName, val);
+}
+
+void
+phydm_get_hal_def_var_handler_interface (
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum _HAL_DEF_VARIABLE e_variable,
+ void *p_value
+ )
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+
+ adapter->hal_func.get_hal_def_var_handler(adapter, e_variable, p_value);
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_interface.h b/drivers/staging/rtl8188eu/hal/phydm_interface.h
new file mode 100644
index 000000000000..232da6f9d606
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_interface.h
@@ -0,0 +1,351 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+
+#ifndef __ODM_INTERFACE_H__
+#define __ODM_INTERFACE_H__
+
+#define INTERFACE_VERSION "1.1" /*2015.07.29 YuChen*/
+
+/*
+ * =========== Constant/Structure/Enum/... Define
+ * */
+
+
+
+/*
+ * =========== Macro Define
+ * */
+
+#define _reg_all(_name) ODM_##_name
+#define _reg_ic(_name, _ic) ODM_##_name##_ic
+#define _bit_all(_name) BIT_##_name
+#define _bit_ic(_name, _ic) BIT_##_name##_ic
+
+/* _cat: implemented by Token-Passing Operator. */
+
+/*===================================
+
+#define ODM_REG_DIG_11N 0xC50
+#define ODM_REG_DIG_11AC 0xDDD
+
+ODM_REG(DIG, _pdm_odm)
+=====================================*/
+
+#define _reg_11N(_name) ODM_REG_##_name##_11N
+#define _reg_11AC(_name) ODM_REG_##_name##_11AC
+#define _bit_11N(_name) ODM_BIT_##_name##_11N
+#define _bit_11AC(_name) ODM_BIT_##_name##_11AC
+
+#ifdef __ECOS
+#define _rtk_cat(_name, _ic_type, _func) \
+ (\
+ ((_ic_type) & ODM_IC_11N_SERIES) ? _func##_11N(_name) : \
+ _func##_11AC(_name) \
+ )
+#else
+
+#define _cat(_name, _ic_type, _func) \
+ (\
+ ((_ic_type) & ODM_IC_11N_SERIES) ? _func##_11N(_name) : \
+ _func##_11AC(_name) \
+ )
+#endif
+/*
+ * only sample code
+ *#define _cat(_name, _ic_type, _func) \
+ * ( \
+ * ((_ic_type) & ODM_RTL8188E) ? _func##_ic(_name, _8188E) : \
+ * _func##_ic(_name, _8195) \
+ * )
+ */
+
+/* _name: name of register or bit.
+ * Example: "ODM_REG(R_A_AGC_CORE1, p_dm_odm)"
+ * gets "ODM_R_A_AGC_CORE1" or "ODM_R_A_AGC_CORE1_8192C", depends on support_ic_type. */
+#ifdef __ECOS
+ #define ODM_REG(_name, _pdm_odm) _rtk_cat(_name, _pdm_odm->support_ic_type, _reg)
+ #define ODM_BIT(_name, _pdm_odm) _rtk_cat(_name, _pdm_odm->support_ic_type, _bit)
+#else
+ #define ODM_REG(_name, _pdm_odm) _cat(_name, _pdm_odm->support_ic_type, _reg)
+ #define ODM_BIT(_name, _pdm_odm) _cat(_name, _pdm_odm->support_ic_type, _bit)
+#endif
+enum phydm_h2c_cmd {
+ PHYDM_H2C_TXBF = 0x41,
+ ODM_H2C_RSSI_REPORT = 0x42,
+ ODM_H2C_IQ_CALIBRATION = 0x45,
+ ODM_H2C_RA_PARA_ADJUST = 0x47,
+ PHYDM_H2C_DYNAMIC_TX_PATH = 0x48,
+ PHYDM_H2C_FW_TRACE_EN = 0x49,
+ ODM_H2C_WIFI_CALIBRATION = 0x6d,
+ PHYDM_H2C_MU = 0x4a,
+ ODM_MAX_H2CCMD
+};
+
+enum phydm_c2h_evt {
+ PHYDM_C2H_DBG = 0,
+ PHYDM_C2H_LB = 1,
+ PHYDM_C2H_XBF = 2,
+ PHYDM_C2H_TX_REPORT = 3,
+ PHYDM_C2H_INFO = 9,
+ PHYDM_C2H_BT_MP = 11,
+ PHYDM_C2H_RA_RPT = 12,
+ PHYDM_C2H_RA_PARA_RPT = 14,
+ PHYDM_C2H_DYNAMIC_TX_PATH_RPT = 15,
+ PHYDM_C2H_IQK_FINISH = 17, /*0x11*/
+ PHYDM_C2H_DBG_CODE = 0xFE,
+ PHYDM_C2H_EXTEND = 0xFF,
+};
+
+enum phydm_extend_c2h_evt {
+ PHYDM_EXTEND_C2H_DBG_PRINT = 0
+
+};
+
+
+/*
+ * =========== Extern Variable ??? It should be forbidden.
+ * */
+
+
+/*
+ * =========== EXtern Function Prototype
+ * */
+
+
+u8
+odm_read_1byte(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr
+);
+
+u16
+odm_read_2byte(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr
+);
+
+u32
+odm_read_4byte(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr
+);
+
+void
+odm_write_1byte(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr,
+ u8 data
+);
+
+void
+odm_write_2byte(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr,
+ u16 data
+);
+
+void
+odm_write_4byte(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr,
+ u32 data
+);
+
+void
+odm_set_mac_reg(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr,
+ u32 bit_mask,
+ u32 data
+);
+
+u32
+odm_get_mac_reg(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr,
+ u32 bit_mask
+);
+
+void
+odm_set_bb_reg(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr,
+ u32 bit_mask,
+ u32 data
+);
+
+u32
+odm_get_bb_reg(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 reg_addr,
+ u32 bit_mask
+);
+
+void
+odm_set_rf_reg(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_rf_radio_path_e e_rf_path,
+ u32 reg_addr,
+ u32 bit_mask,
+ u32 data
+);
+
+u32
+odm_get_rf_reg(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum odm_rf_radio_path_e e_rf_path,
+ u32 reg_addr,
+ u32 bit_mask
+);
+
+
+/*
+ * Memory Relative Function.
+ * */
+void
+odm_allocate_memory(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ void **p_ptr,
+ u32 length
+);
+void
+odm_free_memory(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ void *p_ptr,
+ u32 length
+);
+
+void
+odm_move_memory(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ void *p_dest,
+ void *p_src,
+ u32 length
+);
+
+s32 odm_compare_memory(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ void *p_buf1,
+ void *p_buf2,
+ u32 length
+);
+
+void odm_memory_set
+(struct PHY_DM_STRUCT *p_dm_odm,
+ void *pbuf,
+ s8 value,
+ u32 length);
+
+/*
+ * ODM MISC-spin lock relative API.
+ * */
+void
+odm_acquire_spin_lock(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum rt_spinlock_type type
+);
+
+void
+odm_release_spin_lock(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum rt_spinlock_type type
+);
+
+/*
+ * ODM Timer relative API.
+ * */
+void
+odm_stall_execution(
+ u32 us_delay
+);
+
+void
+ODM_delay_ms(u32 ms);
+
+
+
+void
+ODM_delay_us(u32 us);
+
+void
+ODM_sleep_ms(u32 ms);
+
+void
+ODM_sleep_us(u32 us);
+
+void
+odm_set_timer(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct timer_list *p_timer,
+ u32 ms_delay
+);
+
+void
+odm_initialize_timer(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct timer_list *p_timer,
+ void *call_back_func,
+ void *p_context,
+ const char *sz_id
+);
+
+void
+odm_cancel_timer(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct timer_list *p_timer
+);
+
+void
+odm_release_timer(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ struct timer_list *p_timer
+);
+
+/*
+ * ODM FW relative API.
+ * */
+void
+odm_fill_h2c_cmd(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 element_id,
+ u32 cmd_len,
+ u8 *p_cmd_buffer
+);
+
+u8
+phydm_c2H_content_parsing(
+ void *p_dm_void,
+ u8 c2h_cmd_id,
+ u8 c2h_cmd_len,
+ u8 *tmp_buf
+);
+
+u64
+odm_get_current_time(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+u64
+odm_get_progressing_time(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u64 start_time
+);
+
+void
+phydm_set_hw_reg_handler_interface (
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 reg_Name,
+ u8 *val
+ );
+
+void
+phydm_get_hal_def_var_handler_interface (
+ struct PHY_DM_STRUCT *p_dm_odm,
+ enum _HAL_DEF_VARIABLE e_variable,
+ void *p_value
+);
+
+#endif /* __ODM_INTERFACE_H__ */
+
diff --git a/drivers/staging/rtl8188eu/hal/phydm_iqk.h b/drivers/staging/rtl8188eu/hal/phydm_iqk.h
new file mode 100644
index 000000000000..2c6338124746
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_iqk.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMIQK_H__
+#define __PHYDMIQK_H__
+
+/*--------------------------Define Parameters-------------------------------*/
+#define LOK_delay 1
+#define WBIQK_delay 10
+#define TX_IQK 0
+#define RX_IQK 1
+#define TXIQK 0
+#define RXIQK1 1
+#define RXIQK2 2
+#define kcount_limit_80m 2
+#define kcount_limit_others 4
+#define rxiqk_gs_limit 4
+
+#define NUM 4
+/*---------------------------End Define Parameters-------------------------------*/
+
+struct _IQK_INFORMATION {
+ bool LOK_fail[NUM];
+ bool IQK_fail[2][NUM];
+ u32 iqc_matrix[2][NUM];
+ u8 iqk_times;
+ u32 rf_reg18;
+ u32 lna_idx;
+ u8 rxiqk_step;
+ u8 tmp1bcc;
+ u8 kcount;
+
+ u32 iqk_channel[2];
+ bool IQK_fail_report[2][4][2]; /*channel/path/TRX(TX:0, RX:1) */
+ u32 IQK_CFIR_real[2][4][2][8]; /*channel / path / TRX(TX:0, RX:1) / CFIR_real*/
+ u32 IQK_CFIR_imag[2][4][2][8]; /*channel / path / TRX(TX:0, RX:1) / CFIR_imag*/
+ u8 retry_count[2][4][3]; /* channel / path / (TXK:0, RXK1:1, RXK2:2) */
+ u8 gs_retry_count[2][4][2]; /* channel / path / (GSRXK1:0, GSRXK2:1) */
+ u8 RXIQK_fail_code[2][4]; /* channel / path 0:SRXK1 fail, 1:RXK1 fail 2:RXK2 fail */
+ u32 LOK_IDAC[2][4]; /*channel / path*/
+ u16 RXIQK_AGC[2][4]; /*channel / path*/
+ u32 bypass_iqk[2][4]; /*channel / 0xc94/0xe94*/
+ u32 tmp_GNTWL;
+ bool is_BTG;
+ bool isbnd;
+};
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_kfree.c b/drivers/staging/rtl8188eu/hal/phydm_kfree.c
new file mode 100644
index 000000000000..31d33110e785
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_kfree.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/*============================================================*/
+/*include files*/
+/*============================================================*/
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+
+/*<YuChen, 150720> Add for KFree Feature Requested by RF David.*/
+/*This is a phydm API*/
+
+static void phydm_set_kfree_to_rf_8814a(void *p_dm_void, u8 e_rf_path, u8 data)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct odm_rf_calibration_structure *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
+ bool is_odd;
+
+ if ((data % 2) != 0) { /*odd->positive*/
+ data = data - 1;
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(19), 1);
+ is_odd = true;
+ } else { /*even->negative*/
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(19), 0);
+ is_odd = false;
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_MP, ODM_DBG_LOUD, ("phy_ConfigKFree8814A(): RF_0x55[19]= %d\n", is_odd));
+ switch (data) {
+ case 0:
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 0);
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 0);
+ p_rf_calibrate_info->kfree_offset[e_rf_path] = 0;
+ break;
+ case 2:
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 1);
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 0);
+ p_rf_calibrate_info->kfree_offset[e_rf_path] = 0;
+ break;
+ case 4:
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 0);
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 1);
+ p_rf_calibrate_info->kfree_offset[e_rf_path] = 1;
+ break;
+ case 6:
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 1);
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 1);
+ p_rf_calibrate_info->kfree_offset[e_rf_path] = 1;
+ break;
+ case 8:
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 0);
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 2);
+ p_rf_calibrate_info->kfree_offset[e_rf_path] = 2;
+ break;
+ case 10:
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 1);
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 2);
+ p_rf_calibrate_info->kfree_offset[e_rf_path] = 2;
+ break;
+ case 12:
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 0);
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 3);
+ p_rf_calibrate_info->kfree_offset[e_rf_path] = 3;
+ break;
+ case 14:
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 1);
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 3);
+ p_rf_calibrate_info->kfree_offset[e_rf_path] = 3;
+ break;
+ case 16:
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 0);
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 4);
+ p_rf_calibrate_info->kfree_offset[e_rf_path] = 4;
+ break;
+ case 18:
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 1);
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 4);
+ p_rf_calibrate_info->kfree_offset[e_rf_path] = 4;
+ break;
+ case 20:
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), 0);
+ odm_set_rf_reg(p_dm_odm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(17) | BIT(16) | BIT(15), 5);
+ p_rf_calibrate_info->kfree_offset[e_rf_path] = 5;
+ break;
+
+ default:
+ break;
+ }
+
+ if (is_odd == false) {
+ /*that means Kfree offset is negative, we need to record it.*/
+ p_rf_calibrate_info->kfree_offset[e_rf_path] = (-1) * p_rf_calibrate_info->kfree_offset[e_rf_path];
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_MP, ODM_DBG_LOUD, ("phy_ConfigKFree8814A(): kfree_offset = %d\n", p_rf_calibrate_info->kfree_offset[e_rf_path]));
+ } else
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_MP, ODM_DBG_LOUD, ("phy_ConfigKFree8814A(): kfree_offset = %d\n", p_rf_calibrate_info->kfree_offset[e_rf_path]));
+
+}
+
+
+static void phydm_set_kfree_to_rf(void *p_dm_void, u8 e_rf_path, u8 data)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (p_dm_odm->support_ic_type & ODM_RTL8814A)
+ phydm_set_kfree_to_rf_8814a(p_dm_odm, e_rf_path, data);
+}
+
+void
+phydm_config_kfree(
+ void *p_dm_void,
+ u8 channel_to_sw,
+ u8 *kfree_table
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct odm_rf_calibration_structure *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
+ u8 rfpath = 0, max_rf_path = 0;
+ u8 channel_idx = 0;
+
+ if (p_dm_odm->support_ic_type & ODM_RTL8814A)
+ max_rf_path = 4; /*0~3*/
+ else if (p_dm_odm->support_ic_type & (ODM_RTL8812 | ODM_RTL8192E | ODM_RTL8822B))
+ max_rf_path = 2; /*0~1*/
+ else
+ max_rf_path = 1;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_MP, ODM_DBG_LOUD, ("===>phy_ConfigKFree8814A()\n"));
+
+ if (p_rf_calibrate_info->reg_rf_kfree_enable == 2) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_MP, ODM_DBG_LOUD, ("phy_ConfigKFree8814A(): reg_rf_kfree_enable == 2, Disable\n"));
+ return;
+ } else if (p_rf_calibrate_info->reg_rf_kfree_enable == 1 || p_rf_calibrate_info->reg_rf_kfree_enable == 0) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_MP, ODM_DBG_LOUD, ("phy_ConfigKFree8814A(): reg_rf_kfree_enable == true\n"));
+ /*Make sure the targetval is defined*/
+ if (((p_rf_calibrate_info->reg_rf_kfree_enable == 1) && (kfree_table[0] != 0xFF)) || (p_rf_calibrate_info->rf_kfree_enable == true)) {
+ /*if kfree_table[0] == 0xff, means no Kfree*/
+ if (*p_dm_odm->p_band_type == ODM_BAND_2_4G) {
+ if (channel_to_sw <= 14 && channel_to_sw >= 1)
+ channel_idx = PHYDM_2G;
+ } else if (*p_dm_odm->p_band_type == ODM_BAND_5G) {
+ if (channel_to_sw >= 36 && channel_to_sw <= 48)
+ channel_idx = PHYDM_5GLB1;
+ if (channel_to_sw >= 52 && channel_to_sw <= 64)
+ channel_idx = PHYDM_5GLB2;
+ if (channel_to_sw >= 100 && channel_to_sw <= 120)
+ channel_idx = PHYDM_5GMB1;
+ if (channel_to_sw >= 124 && channel_to_sw <= 144)
+ channel_idx = PHYDM_5GMB2;
+ if (channel_to_sw >= 149 && channel_to_sw <= 177)
+ channel_idx = PHYDM_5GHB;
+ }
+
+ for (rfpath = ODM_RF_PATH_A; rfpath < max_rf_path; rfpath++) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_MP, ODM_DBG_LOUD, ("phydm_kfree(): PATH_%d: %#x\n", rfpath, kfree_table[channel_idx * max_rf_path + rfpath]));
+ phydm_set_kfree_to_rf(p_dm_odm, rfpath, kfree_table[channel_idx * max_rf_path + rfpath]);
+ }
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_MP, ODM_DBG_LOUD, ("phy_ConfigKFree8814A(): targetval not defined, Don't execute KFree Process.\n"));
+ return;
+ }
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_MP, ODM_DBG_LOUD, ("<===phy_ConfigKFree8814A()\n"));
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_kfree.h b/drivers/staging/rtl8188eu/hal/phydm_kfree.h
new file mode 100644
index 000000000000..6de330dabdb9
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_kfree.h
@@ -0,0 +1,29 @@
+
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMKFREE_H__
+#define __PHYDKFREE_H__
+
+#define KFREE_VERSION "1.0"
+
+enum phydm_kfree_channeltosw {
+ PHYDM_2G = 0,
+ PHYDM_5GLB1 = 1,
+ PHYDM_5GLB2 = 2,
+ PHYDM_5GMB1 = 3,
+ PHYDM_5GMB2 = 4,
+ PHYDM_5GHB = 5,
+};
+
+
+void
+phydm_config_kfree(
+ void *p_dm_void,
+ u8 channel_to_sw,
+ u8 *kfree_table
+);
+
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_noisemonitor.c b/drivers/staging/rtl8188eu/hal/phydm_noisemonitor.c
new file mode 100644
index 000000000000..f9cd06f2cba7
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_noisemonitor.c
@@ -0,0 +1,270 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+#include "phydm_noisemonitor.h"
+
+/* *************************************************
+ * This function is for inband noise test utility only
+ * To obtain the inband noise level(dbm), do the following.
+ * 1. disable DIG and Power Saving
+ * 2. Set initial gain = 0x1a
+ * 3. Stop updating idle time pwer report (for driver read)
+ * - 0x80c[25]
+ *
+ * ************************************************* */
+
+#define VALID_MIN -35
+#define VALID_MAX 10
+#define VALID_CNT 5
+
+static s16 odm_inband_noise_monitor_n_series(struct PHY_DM_STRUCT *p_dm_odm, u8 is_pause_dig, u8 igi_value, u32 max_time)
+{
+ u32 tmp4b;
+ u8 max_rf_path = 0, rf_path;
+ u8 reg_c50, reg_c58, valid_done = 0;
+ struct noise_level noise_data;
+ u64 start = 0, func_start = 0, func_end = 0;
+
+ func_start = odm_get_current_time(p_dm_odm);
+ p_dm_odm->noise_level.noise_all = 0;
+
+ if ((p_dm_odm->rf_type == ODM_1T2R) || (p_dm_odm->rf_type == ODM_2T2R))
+ max_rf_path = 2;
+ else
+ max_rf_path = 1;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_DebugControlInbandNoise_Nseries() ==>\n"));
+
+ odm_memory_set(p_dm_odm, &noise_data, 0, sizeof(struct noise_level));
+
+ /* */
+ /* step 1. Disable DIG && Set initial gain. */
+ /* */
+
+ if (is_pause_dig)
+ odm_pause_dig(p_dm_odm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_1, igi_value);
+ /* */
+ /* step 2. Disable all power save for read registers */
+ /* */
+ /* dcmd_DebugControlPowerSave(p_adapter, PSDisable); */
+
+ /* */
+ /* step 3. Get noise power level */
+ /* */
+ start = odm_get_current_time(p_dm_odm);
+ while (1) {
+
+ /* Stop updating idle time pwer report (for driver read) */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_TX_GAIN_STAGE, BIT(25), 1);
+
+ /* Read Noise Floor Report */
+ tmp4b = odm_get_bb_reg(p_dm_odm, 0x8f8, MASKDWORD);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("Noise Floor Report (0x8f8) = 0x%08x\n", tmp4b));
+
+ /* odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XA_AGC_CORE1, MASKBYTE0, TestInitialGain); */
+ /* if(max_rf_path == 2) */
+ /* odm_set_bb_reg(p_dm_odm, REG_OFDM_0_XB_AGC_CORE1, MASKBYTE0, TestInitialGain); */
+
+ /* update idle time pwer report per 5us */
+ odm_set_bb_reg(p_dm_odm, REG_FPGA0_TX_GAIN_STAGE, BIT(25), 0);
+
+ noise_data.value[ODM_RF_PATH_A] = (u8)(tmp4b & 0xff);
+ noise_data.value[ODM_RF_PATH_B] = (u8)((tmp4b & 0xff00) >> 8);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("value_a = 0x%x(%d), value_b = 0x%x(%d)\n",
+ noise_data.value[ODM_RF_PATH_A], noise_data.value[ODM_RF_PATH_A], noise_data.value[ODM_RF_PATH_B], noise_data.value[ODM_RF_PATH_B]));
+
+ for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) {
+ noise_data.sval[rf_path] = (s8)noise_data.value[rf_path];
+ noise_data.sval[rf_path] /= 2;
+ }
+
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("sval_a = %d, sval_b = %d\n",
+ noise_data.sval[ODM_RF_PATH_A], noise_data.sval[ODM_RF_PATH_B]));
+ /* ODM_delay_ms(10); */
+ /* ODM_sleep_ms(10); */
+
+ for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) {
+ if ((noise_data.valid_cnt[rf_path] < VALID_CNT) && (noise_data.sval[rf_path] < VALID_MAX && noise_data.sval[rf_path] >= VALID_MIN)) {
+ noise_data.valid_cnt[rf_path]++;
+ noise_data.sum[rf_path] += noise_data.sval[rf_path];
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("rf_path:%d Valid sval = %d\n", rf_path, noise_data.sval[rf_path]));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("Sum of sval = %d,\n", noise_data.sum[rf_path]));
+ if (noise_data.valid_cnt[rf_path] == VALID_CNT) {
+ valid_done++;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("After divided, rf_path:%d,sum = %d\n", rf_path, noise_data.sum[rf_path]));
+ }
+
+ }
+
+ }
+
+ /* printk("####### valid_done:%d #############\n",valid_done); */
+ if ((valid_done == max_rf_path) || (odm_get_progressing_time(p_dm_odm, start) > max_time)) {
+ for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) {
+ /* printk("%s PATH_%d - sum = %d, VALID_CNT = %d\n",__func__,rf_path,noise_data.sum[rf_path], noise_data.valid_cnt[rf_path]); */
+ if (noise_data.valid_cnt[rf_path])
+ noise_data.sum[rf_path] /= noise_data.valid_cnt[rf_path];
+ else
+ noise_data.sum[rf_path] = 0;
+ }
+ break;
+ }
+ }
+ reg_c50 = (u8)odm_get_bb_reg(p_dm_odm, REG_OFDM_0_XA_AGC_CORE1, MASKBYTE0);
+ reg_c50 &= ~BIT(7);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("0x%x = 0x%02x(%d)\n", REG_OFDM_0_XA_AGC_CORE1, reg_c50, reg_c50));
+ p_dm_odm->noise_level.noise[ODM_RF_PATH_A] = (u8)(-110 + reg_c50 + noise_data.sum[ODM_RF_PATH_A]);
+ p_dm_odm->noise_level.noise_all += p_dm_odm->noise_level.noise[ODM_RF_PATH_A];
+
+ if (max_rf_path == 2) {
+ reg_c58 = (u8)odm_get_bb_reg(p_dm_odm, REG_OFDM_0_XB_AGC_CORE1, MASKBYTE0);
+ reg_c58 &= ~BIT(7);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("0x%x = 0x%02x(%d)\n", REG_OFDM_0_XB_AGC_CORE1, reg_c58, reg_c58));
+ p_dm_odm->noise_level.noise[ODM_RF_PATH_B] = (u8)(-110 + reg_c58 + noise_data.sum[ODM_RF_PATH_B]);
+ p_dm_odm->noise_level.noise_all += p_dm_odm->noise_level.noise[ODM_RF_PATH_B];
+ }
+ p_dm_odm->noise_level.noise_all /= max_rf_path;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("noise_a = %d, noise_b = %d\n",
+ p_dm_odm->noise_level.noise[ODM_RF_PATH_A],
+ p_dm_odm->noise_level.noise[ODM_RF_PATH_B]));
+
+ /* */
+ /* step 4. Recover the Dig */
+ /* */
+ if (is_pause_dig)
+ odm_pause_dig(p_dm_odm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_1, igi_value);
+ func_end = odm_get_progressing_time(p_dm_odm, func_start) ;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_DebugControlInbandNoise_Nseries() <==\n"));
+ return p_dm_odm->noise_level.noise_all;
+
+}
+
+static s16
+odm_inband_noise_monitor_ac_series(struct PHY_DM_STRUCT *p_dm_odm, u8 is_pause_dig, u8 igi_value, u32 max_time
+ )
+{
+ s32 rxi_buf_anta, rxq_buf_anta; /*rxi_buf_antb, rxq_buf_antb;*/
+ s32 value32, pwdb_A = 0, sval, noise, sum;
+ bool pd_flag;
+ u8 i, valid_cnt;
+ u64 start = 0, func_start = 0, func_end = 0;
+
+
+ if (!(p_dm_odm->support_ic_type & (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A)))
+ return 0;
+
+ func_start = odm_get_current_time(p_dm_odm);
+ p_dm_odm->noise_level.noise_all = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_inband_noise_monitor_ac_series() ==>\n"));
+
+ /* step 1. Disable DIG && Set initial gain. */
+ if (is_pause_dig)
+ odm_pause_dig(p_dm_odm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_1, igi_value);
+
+ /* step 2. Disable all power save for read registers */
+ /*dcmd_DebugControlPowerSave(p_adapter, PSDisable); */
+
+ /* step 3. Get noise power level */
+ start = odm_get_current_time(p_dm_odm);
+
+ /* reset counters */
+ sum = 0;
+ valid_cnt = 0;
+
+ /* step 3. Get noise power level */
+ while (1) {
+ /*Set IGI=0x1C */
+ odm_write_dig(p_dm_odm, 0x1C);
+ /*stop CK320&CK88 */
+ odm_set_bb_reg(p_dm_odm, 0x8B4, BIT(6), 1);
+ /*Read path-A */
+ odm_set_bb_reg(p_dm_odm, 0x8FC, MASKDWORD, 0x200); /*set debug port*/
+ value32 = odm_get_bb_reg(p_dm_odm, 0xFA0, MASKDWORD); /*read debug port*/
+
+ rxi_buf_anta = (value32 & 0xFFC00) >> 10; /*rxi_buf_anta=RegFA0[19:10]*/
+ rxq_buf_anta = value32 & 0x3FF; /*rxq_buf_anta=RegFA0[19:10]*/
+
+ pd_flag = (bool)((value32 & BIT(31)) >> 31);
+
+ /*Not in packet detection period or Tx state */
+ if ((!pd_flag) || (rxi_buf_anta != 0x200)) {
+ /*sign conversion*/
+ rxi_buf_anta = odm_sign_conversion(rxi_buf_anta, 10);
+ rxq_buf_anta = odm_sign_conversion(rxq_buf_anta, 10);
+
+ pwdb_A = odm_pwdb_conversion(rxi_buf_anta * rxi_buf_anta + rxq_buf_anta * rxq_buf_anta, 20, 18); /*S(10,9)*S(10,9)=S(20,18)*/
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pwdb_A= %d dB, rxi_buf_anta= 0x%x, rxq_buf_anta= 0x%x\n", pwdb_A, rxi_buf_anta & 0x3FF, rxq_buf_anta & 0x3FF));
+ }
+ /*Start CK320&CK88*/
+ odm_set_bb_reg(p_dm_odm, 0x8B4, BIT(6), 0);
+ /*BB Reset*/
+ odm_write_1byte(p_dm_odm, 0x02, odm_read_1byte(p_dm_odm, 0x02) & (~BIT(0)));
+ odm_write_1byte(p_dm_odm, 0x02, odm_read_1byte(p_dm_odm, 0x02) | BIT(0));
+ /*PMAC Reset*/
+ odm_write_1byte(p_dm_odm, 0xB03, odm_read_1byte(p_dm_odm, 0xB03) & (~BIT(0)));
+ odm_write_1byte(p_dm_odm, 0xB03, odm_read_1byte(p_dm_odm, 0xB03) | BIT(0));
+ /*CCK Reset*/
+ if (odm_read_1byte(p_dm_odm, 0x80B) & BIT(4)) {
+ odm_write_1byte(p_dm_odm, 0x80B, odm_read_1byte(p_dm_odm, 0x80B) & (~BIT(4)));
+ odm_write_1byte(p_dm_odm, 0x80B, odm_read_1byte(p_dm_odm, 0x80B) | BIT(4));
+ }
+
+ sval = pwdb_A;
+
+ if (sval < 0 && sval >= -27) {
+ if (valid_cnt < VALID_CNT) {
+ valid_cnt++;
+ sum += sval;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("Valid sval = %d\n", sval));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("Sum of sval = %d,\n", sum));
+ if ((valid_cnt >= VALID_CNT) || (odm_get_progressing_time(p_dm_odm, start) > max_time)) {
+ sum /= VALID_CNT;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("After divided, sum = %d\n", sum));
+ break;
+ }
+ }
+ }
+ }
+
+ /*ADC backoff is 12dB,*/
+ /*Ptarget=0x1C-110=-82dBm*/
+ noise = sum + 12 + 0x1C - 110;
+
+ /*Offset*/
+ noise = noise - 3;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("noise = %d\n", noise));
+ p_dm_odm->noise_level.noise_all = (s16)noise;
+
+ /* step 4. Recover the Dig*/
+ if (is_pause_dig)
+ odm_pause_dig(p_dm_odm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_1, igi_value);
+
+ func_end = odm_get_progressing_time(p_dm_odm, func_start);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_inband_noise_monitor_ac_series() <==\n"));
+
+ return p_dm_odm->noise_level.noise_all;
+}
+
+s16
+odm_inband_noise_monitor(void *p_dm_void, u8 is_pause_dig, u8 igi_value, u32 max_time)
+{
+
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
+ return odm_inband_noise_monitor_ac_series(p_dm_odm, is_pause_dig, igi_value, max_time);
+ else
+ return odm_inband_noise_monitor_n_series(p_dm_odm, is_pause_dig, igi_value, max_time);
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_noisemonitor.h b/drivers/staging/rtl8188eu/hal/phydm_noisemonitor.h
new file mode 100644
index 000000000000..bab7cae20177
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_noisemonitor.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#ifndef __ODMNOISEMONITOR_H__
+#define __ODMNOISEMONITOR_H__
+
+#define ODM_MAX_CHANNEL_NUM 38/* 14+24 */
+struct noise_level {
+ /* u8 value_a, value_b; */
+ u8 value[MAX_RF_PATH];
+ /* s8 sval_a, sval_b; */
+ s8 sval[MAX_RF_PATH];
+
+ /* s32 noise_a=0, noise_b=0,sum_a=0, sum_b=0; */
+ /* s32 noise[ODM_RF_PATH_MAX]; */
+ s32 sum[MAX_RF_PATH];
+ /* u8 valid_cnt_a=0, valid_cnt_b=0, */
+ u8 valid[MAX_RF_PATH];
+ u8 valid_cnt[MAX_RF_PATH];
+
+};
+
+
+struct _ODM_NOISE_MONITOR_ {
+ s8 noise[MAX_RF_PATH];
+ s16 noise_all;
+};
+
+s16 odm_inband_noise_monitor(void *p_dm_void, u8 is_pause_dig, u8 igi_value, u32 max_time);
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_pathdiv.c b/drivers/staging/rtl8188eu/hal/phydm_pathdiv.c
new file mode 100644
index 000000000000..81a4901e878d
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_pathdiv.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+#if (defined(CONFIG_PATH_DIVERSITY))
+void odm_pathdiv_debug(void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &(p_dm_odm->dm_path_div);
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ p_dm_odm->path_select = (dm_value[0] & 0xf);
+ PHYDM_SNPRINTF((output + used, out_len - used, "Path_select = (( 0x%x ))\n", p_dm_odm->path_select));
+
+ /* 2 [Fix path] */
+ if (p_dm_odm->path_select != PHYDM_AUTO_PATH) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "Trun on path [%s%s%s%s]\n",
+ ((p_dm_odm->path_select) & 0x1) ? "A" : "",
+ ((p_dm_odm->path_select) & 0x2) ? "B" : "",
+ ((p_dm_odm->path_select) & 0x4) ? "C" : "",
+ ((p_dm_odm->path_select) & 0x8) ? "D" : ""));
+
+ phydm_dtp_fix_tx_path(p_dm_odm, p_dm_odm->path_select);
+ } else
+ PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "Auto path"));
+}
+
+#endif /* #if(defined(CONFIG_PATH_DIVERSITY)) */
+
+void
+phydm_c2h_dtp_handler(
+ void *p_dm_void,
+ u8 *cmd_buf,
+ u8 cmd_len
+)
+{
+#if (defined(CONFIG_PATH_DIVERSITY))
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &(p_dm_odm->dm_path_div);
+
+ u8 macid = cmd_buf[0];
+ u8 target = cmd_buf[1];
+ u8 nsc_1 = cmd_buf[2];
+ u8 nsc_2 = cmd_buf[3];
+ u8 nsc_3 = cmd_buf[4];
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("Target_candidate = (( %d ))\n", target));
+#endif
+}
+
+void
+odm_path_diversity(
+ void *p_dm_void
+)
+{
+#if (defined(CONFIG_PATH_DIVERSITY))
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ if (!(p_dm_odm->support_ability & ODM_BB_PATH_DIV)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("Return: Not Support PathDiv\n"));
+ return;
+ }
+#endif
+}
+
+void
+odm_path_diversity_init(
+ void *p_dm_void
+)
+{
+#if (defined(CONFIG_PATH_DIVERSITY))
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ /*p_dm_odm->support_ability |= ODM_BB_PATH_DIV;*/
+
+ if (p_dm_odm->mp_mode == true)
+ return;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_PATH_DIV)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("Return: Not Support PathDiv\n"));
+ return;
+ }
+#endif
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_pathdiv.h b/drivers/staging/rtl8188eu/hal/phydm_pathdiv.h
new file mode 100644
index 000000000000..97a160d46be6
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_pathdiv.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMPATHDIV_H__
+#define __PHYDMPATHDIV_H__
+/*#define PATHDIV_VERSION "2.0" //2014.11.04*/
+#define PATHDIV_VERSION "3.1" /*2015.07.29 by YuChen*/
+
+#if (defined(CONFIG_PATH_DIVERSITY))
+#define USE_PATH_A_AS_DEFAULT_ANT /* for 8814 dynamic TX path selection */
+
+#define NUM_RESET_DTP_PERIOD 5
+#define ANT_DECT_RSSI_TH 3
+
+#define PATH_A 1
+#define PATH_B 2
+#define PATH_C 3
+#define PATH_D 4
+
+#define PHYDM_AUTO_PATH 0
+#define PHYDM_FIX_PATH 1
+
+#define NUM_CHOOSE2_FROM4 6
+#define NUM_CHOOSE3_FROM4 4
+
+
+#define PHYDM_A BIT(0)
+#define PHYDM_B BIT(1)
+#define PHYDM_C BIT(2)
+#define PHYDM_D BIT(3)
+#define PHYDM_AB (BIT(0) | BIT1) /* 0 */
+#define PHYDM_AC (BIT(0) | BIT2) /* 1 */
+#define PHYDM_AD (BIT(0) | BIT3) /* 2 */
+#define PHYDM_BC (BIT(1) | BIT2) /* 3 */
+#define PHYDM_BD (BIT(1) | BIT3) /* 4 */
+#define PHYDM_CD (BIT(2) | BIT3) /* 5 */
+
+#define PHYDM_ABC (BIT(0) | BIT1 | BIT2) /* 0*/
+#define PHYDM_ABD (BIT(0) | BIT1 | BIT3) /* 1*/
+#define PHYDM_ACD (BIT(0) | BIT2 | BIT3) /* 2*/
+#define PHYDM_BCD (BIT(1) | BIT2 | BIT3) /* 3*/
+
+#define PHYDM_ABCD (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+
+
+enum phydm_dtp_state {
+ PHYDM_DTP_INIT = 1,
+ PHYDM_DTP_RUNNING_1
+
+};
+
+enum phydm_path_div_type {
+ PHYDM_2R_PATH_DIV = 1,
+ PHYDM_4R_PATH_DIV = 2
+};
+
+void
+phydm_process_rssi_for_path_div(
+ void *p_dm_void,
+ void *p_phy_info_void,
+ void *p_pkt_info_void
+);
+
+struct _ODM_PATH_DIVERSITY_ {
+ u8 resp_tx_path;
+ u8 path_sel[ODM_ASSOCIATE_ENTRY_NUM];
+ u32 path_a_sum[ODM_ASSOCIATE_ENTRY_NUM];
+ u32 path_b_sum[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 path_a_cnt[ODM_ASSOCIATE_ENTRY_NUM];
+ u16 path_b_cnt[ODM_ASSOCIATE_ENTRY_NUM];
+ u8 phydm_path_div_type;
+#if RTL8814A_SUPPORT
+
+ u32 path_a_sum_all;
+ u32 path_b_sum_all;
+ u32 path_c_sum_all;
+ u32 path_d_sum_all;
+
+ u32 path_a_cnt_all;
+ u32 path_b_cnt_all;
+ u32 path_c_cnt_all;
+ u32 path_d_cnt_all;
+
+ u8 dtp_period;
+ bool is_become_linked;
+ bool is_u3_mode;
+ u8 num_tx_path;
+ u8 default_path;
+ u8 num_candidate;
+ u8 ant_candidate_1;
+ u8 ant_candidate_2;
+ u8 ant_candidate_3;
+ u8 phydm_dtp_state;
+ u8 dtp_check_patha_counter;
+ bool fix_path_bfer;
+ u8 search_space_2[NUM_CHOOSE2_FROM4];
+ u8 search_space_3[NUM_CHOOSE3_FROM4];
+
+ u8 pre_tx_path;
+ u8 use_path_a_as_default_ant;
+ bool is_path_a_exist;
+
+#endif
+};
+
+
+#endif /* #if(defined(CONFIG_PATH_DIVERSITY)) */
+
+void
+phydm_c2h_dtp_handler(
+ void *p_dm_void,
+ u8 *cmd_buf,
+ u8 cmd_len
+);
+
+void
+odm_path_diversity_init(
+ void *p_dm_void
+);
+
+void
+odm_path_diversity(
+ void *p_dm_void
+);
+
+void
+odm_pathdiv_debug(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+);
+
+#endif /* #ifndef __ODMPATHDIV_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/phydm_powertracking_ce.c b/drivers/staging/rtl8188eu/hal/phydm_powertracking_ce.c
new file mode 100644
index 000000000000..3f0ae1142526
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_powertracking_ce.c
@@ -0,0 +1,646 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/*============================================================ */
+/* include files */
+/*============================================================ */
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+/* ************************************************************
+ * Global var
+ * ************************************************************ */
+
+u32 ofdm_swing_table[OFDM_TABLE_SIZE] = {
+ 0x7f8001fe, /* 0, +6.0dB */
+ 0x788001e2, /* 1, +5.5dB */
+ 0x71c001c7, /* 2, +5.0dB*/
+ 0x6b8001ae, /* 3, +4.5dB*/
+ 0x65400195, /* 4, +4.0dB*/
+ 0x5fc0017f, /* 5, +3.5dB*/
+ 0x5a400169, /* 6, +3.0dB*/
+ 0x55400155, /* 7, +2.5dB*/
+ 0x50800142, /* 8, +2.0dB*/
+ 0x4c000130, /* 9, +1.5dB*/
+ 0x47c0011f, /* 10, +1.0dB*/
+ 0x43c0010f, /* 11, +0.5dB*/
+ 0x40000100, /* 12, +0dB*/
+ 0x3c8000f2, /* 13, -0.5dB*/
+ 0x390000e4, /* 14, -1.0dB*/
+ 0x35c000d7, /* 15, -1.5dB*/
+ 0x32c000cb, /* 16, -2.0dB*/
+ 0x300000c0, /* 17, -2.5dB*/
+ 0x2d4000b5, /* 18, -3.0dB*/
+ 0x2ac000ab, /* 19, -3.5dB*/
+ 0x288000a2, /* 20, -4.0dB*/
+ 0x26000098, /* 21, -4.5dB*/
+ 0x24000090, /* 22, -5.0dB*/
+ 0x22000088, /* 23, -5.5dB*/
+ 0x20000080, /* 24, -6.0dB*/
+ 0x1e400079, /* 25, -6.5dB*/
+ 0x1c800072, /* 26, -7.0dB*/
+ 0x1b00006c, /* 27. -7.5dB*/
+ 0x19800066, /* 28, -8.0dB*/
+ 0x18000060, /* 29, -8.5dB*/
+ 0x16c0005b, /* 30, -9.0dB*/
+ 0x15800056, /* 31, -9.5dB*/
+ 0x14400051, /* 32, -10.0dB*/
+ 0x1300004c, /* 33, -10.5dB*/
+ 0x12000048, /* 34, -11.0dB*/
+ 0x11000044, /* 35, -11.5dB*/
+ 0x10000040, /* 36, -12.0dB*/
+};
+
+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*/
+ {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB*/
+ {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */
+ {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB*/
+ {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB*/
+ {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB*/
+ {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */
+ {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB*/
+ {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */
+ {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB*/
+ {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB <== default */
+ {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB*/
+ {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */
+ {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB*/
+ {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
+ {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB*/
+ {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */
+ {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB*/
+ {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB*/
+ {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB*/
+ {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB*/
+ {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB*/
+ {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB*/
+ {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB*/
+ {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB*/
+ {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB*/
+ {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB*/
+ {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB*/
+ {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB*/
+ {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB*/
+ {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB*/
+};
+
+
+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 */
+ {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB*/
+ {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */
+ {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB*/
+ {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */
+ {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */
+ {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */
+ {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB*/
+ {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */
+ {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB*/
+ {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB <== default*/
+ {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */
+ {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */
+ {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB*/
+ {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
+ {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB*/
+ {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */
+ {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB*/
+ {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB*/
+ {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB*/
+ {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB*/
+ {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB*/
+ {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB*/
+ {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB*/
+ {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB*/
+ {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB*/
+ {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB*/
+ {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB*/
+ {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB*/
+ {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB*/
+ {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB*/
+};
+
+
+u32 ofdm_swing_table_new[OFDM_TABLE_SIZE] = {
+ 0x0b40002d, /* 0, -15.0dB */
+ 0x0c000030, /* 1, -14.5dB*/
+ 0x0cc00033, /* 2, -14.0dB*/
+ 0x0d800036, /* 3, -13.5dB*/
+ 0x0e400039, /* 4, -13.0dB */
+ 0x0f00003c, /* 5, -12.5dB*/
+ 0x10000040, /* 6, -12.0dB*/
+ 0x11000044, /* 7, -11.5dB*/
+ 0x12000048, /* 8, -11.0dB*/
+ 0x1300004c, /* 9, -10.5dB*/
+ 0x14400051, /* 10, -10.0dB*/
+ 0x15800056, /* 11, -9.5dB*/
+ 0x16c0005b, /* 12, -9.0dB*/
+ 0x18000060, /* 13, -8.5dB*/
+ 0x19800066, /* 14, -8.0dB*/
+ 0x1b00006c, /* 15, -7.5dB*/
+ 0x1c800072, /* 16, -7.0dB*/
+ 0x1e400079, /* 17, -6.5dB*/
+ 0x20000080, /* 18, -6.0dB*/
+ 0x22000088, /* 19, -5.5dB*/
+ 0x24000090, /* 20, -5.0dB*/
+ 0x26000098, /* 21, -4.5dB*/
+ 0x288000a2, /* 22, -4.0dB*/
+ 0x2ac000ab, /* 23, -3.5dB*/
+ 0x2d4000b5, /* 24, -3.0dB*/
+ 0x300000c0, /* 25, -2.5dB*/
+ 0x32c000cb, /* 26, -2.0dB*/
+ 0x35c000d7, /* 27, -1.5dB*/
+ 0x390000e4, /* 28, -1.0dB*/
+ 0x3c8000f2, /* 29, -0.5dB*/
+ 0x40000100, /* 30, +0dB*/
+ 0x43c0010f, /* 31, +0.5dB*/
+ 0x47c0011f, /* 32, +1.0dB*/
+ 0x4c000130, /* 33, +1.5dB*/
+ 0x50800142, /* 34, +2.0dB*/
+ 0x55400155, /* 35, +2.5dB*/
+ 0x5a400169, /* 36, +3.0dB*/
+ 0x5fc0017f, /* 37, +3.5dB*/
+ 0x65400195, /* 38, +4.0dB*/
+ 0x6b8001ae, /* 39, +4.5dB*/
+ 0x71c001c7, /* 40, +5.0dB*/
+ 0x788001e2, /* 41, +5.5dB*/
+ 0x7f8001fe /* 42, +6.0dB*/
+};
+
+
+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*/
+ {0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/
+ {0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/
+ {0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/
+ {0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/
+ {0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/
+ {0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/
+ {0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/
+ {0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/
+ {0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/
+ {0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/
+ {0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/
+ {0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/
+ {0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/
+ {0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/
+ {0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/
+ {0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/
+ {0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/
+ {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] = {
+ {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*/
+ {0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/
+ {0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/
+ {0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/
+ {0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/
+ {0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/
+ {0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/
+ {0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/
+ {0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/
+ {0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/
+ {0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/
+ {0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/
+ {0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/
+ {0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/
+ {0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/
+ {0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/
+ {0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/
+ {0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/
+ {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] = {
+ {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*/
+ {0x51, 0x4F, 0x47, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/
+ {0x56, 0x53, 0x4B, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/
+ {0x5B, 0x58, 0x50, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/
+ {0x60, 0x5D, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/
+ {0x66, 0x63, 0x59, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/
+ {0x6C, 0x69, 0x5F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/
+ {0x73, 0x6F, 0x64, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/
+ {0x79, 0x76, 0x6A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/
+ {0x81, 0x7C, 0x71, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/
+ {0x88, 0x84, 0x77, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/
+ {0x90, 0x8C, 0x7E, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/
+ {0x99, 0x94, 0x86, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/
+ {0xA2, 0x9D, 0x8E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/
+ {0xAC, 0xA6, 0x96, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/
+ {0xB6, 0xB0, 0x9F, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/
+ {0xC1, 0xBA, 0xA8, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/
+ {0xCC, 0xC5, 0xB2, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/
+ {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] = {
+ {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*/
+ {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 3, -14.5dB*/
+ {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 4, -14.0dB*/
+ {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 5, -13.5dB*/
+ {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 6, -13.0dB*/
+ {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 7, -12.5dB*/
+ {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 8, -12.0dB*/
+ {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 9, -11.5dB*/
+ {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 10, -11.0dB*/
+ {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 11, -10.5dB*/
+ {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 12, -10.0dB*/
+ {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 13, -9.5dB*/
+ {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 14, -9.0dB */
+ {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 15, -8.5dB*/
+ {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
+ {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 17, -7.5dB*/
+ {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 18, -7.0dB */
+ {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 19, -6.5dB*/
+ {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /*20, -6.0dB */
+ {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 21, -5.5dB*/
+ {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 22, -5.0dB */
+ {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 23, -4.5dB*/
+ {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 24, -4.0dB */
+ {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 25, -3.5dB*/
+ {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 26, -3.0dB*/
+ {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 27, -2.5dB*/
+ {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 28, -2.0dB */
+ {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 29, -1.5dB*/
+ {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 30, -1.0dB*/
+ {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 31, -0.5dB*/
+ {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} /* 32, +0dB*/
+};
+
+
+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*/
+ {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 3, -14.5dB*/
+ {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 4, -14.0dB*/
+ {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /*5, -13.5dB*/
+ {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 6, -13.0dB*/
+ {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 7, -12.5dB*/
+ {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 8, -12.0dB*/
+ {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 9, -11.5dB*/
+ {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 10, -11.0dB*/
+ {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /*11, -10.5dB*/
+ {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 12, -10.0dB*/
+ {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 13, -9.5dB*/
+ {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /*14, -9.0dB */
+ {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 15, -8.5dB*/
+ {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
+ {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 17, -7.5dB*/
+ {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 18, -7.0dB */
+ {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 19, -6.5dB */
+ {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 20, -6.0dB */
+ {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 21, -5.5dB*/
+ {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 22, -5.0dB */
+ {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /*23, -4.5dB*/
+ {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 24, -4.0dB */
+ {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 25, -3.5dB */
+ {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 26, -3.0dB */
+ {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /*27, -2.5dB*/
+ {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 28, -2.0dB */
+ {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /*29, -1.5dB*/
+ {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 30, -1.0dB */
+ {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 31, -0.5dB */
+ {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} /* 32, +0dB */
+};
+u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D] = {
+ 0x0CD, /*0 , -20dB*/
+ 0x0D9,
+ 0x0E6,
+ 0x0F3,
+ 0x102,
+ 0x111,
+ 0x121,
+ 0x132,
+ 0x144,
+ 0x158,
+ 0x16C,
+ 0x182,
+ 0x198,
+ 0x1B1,
+ 0x1CA,
+ 0x1E5,
+ 0x202,
+ 0x221,
+ 0x241,
+ 0x263,
+ 0x287,
+ 0x2AE,
+ 0x2D6,
+ 0x301,
+ 0x32F,
+ 0x35F,
+ 0x392,
+ 0x3C9,
+ 0x402,
+ 0x43F,
+ 0x47F,
+ 0x4C3,
+ 0x50C,
+ 0x558,
+ 0x5A9,
+ 0x5FF,
+ 0x65A,
+ 0x6BA,
+ 0x720,
+ 0x78C,
+ 0x7FF,
+};
+
+
+u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE] = {
+ 0x081, /* 0, -12.0dB*/
+ 0x088, /* 1, -11.5dB*/
+ 0x090, /* 2, -11.0dB*/
+ 0x099, /* 3, -10.5dB*/
+ 0x0A2, /* 4, -10.0dB*/
+ 0x0AC, /* 5, -9.5dB*/
+ 0x0B6, /* 6, -9.0dB*/
+ 0x0C0, /*7, -8.5dB*/
+ 0x0CC, /* 8, -8.0dB*/
+ 0x0D8, /* 9, -7.5dB*/
+ 0x0E5, /* 10, -7.0dB*/
+ 0x0F2, /* 11, -6.5dB*/
+ 0x101, /* 12, -6.0dB*/
+ 0x110, /* 13, -5.5dB*/
+ 0x120, /* 14, -5.0dB*/
+ 0x131, /* 15, -4.5dB*/
+ 0x143, /* 16, -4.0dB*/
+ 0x156, /* 17, -3.5dB*/
+ 0x16A, /* 18, -3.0dB*/
+ 0x180, /* 19, -2.5dB*/
+ 0x197, /* 20, -2.0dB*/
+ 0x1AF, /* 21, -1.5dB*/
+ 0x1C8, /* 22, -1.0dB*/
+ 0x1E3, /* 23, -0.5dB*/
+ 0x200, /* 24, +0 dB*/
+ 0x21E, /* 25, +0.5dB*/
+ 0x23E, /* 26, +1.0dB*/
+ 0x261, /* 27, +1.5dB*/
+ 0x285,/* 28, +2.0dB*/
+ 0x2AB, /* 29, +2.5dB*/
+ 0x2D3, /*30, +3.0dB*/
+ 0x2FE, /* 31, +3.5dB*/
+ 0x32B, /* 32, +4.0dB*/
+ 0x35C, /* 33, +4.5dB*/
+ 0x38E, /* 34, +5.0dB*/
+ 0x3C4, /* 35, +5.5dB*/
+ 0x3FE /* 36, +6.0dB */
+};
+
+#ifdef AP_BUILD_WORKAROUND
+
+unsigned int tx_pwr_trk_ofdm_swing_tbl[tx_pwr_trk_ofdm_swing_tbl_len] = {
+ /* +6.0dB */ 0x7f8001fe,
+ /* +5.5dB */ 0x788001e2,
+ /* +5.0dB */ 0x71c001c7,
+ /* +4.5dB */ 0x6b8001ae,
+ /* +4.0dB */ 0x65400195,
+ /* +3.5dB */ 0x5fc0017f,
+ /* +3.0dB */ 0x5a400169,
+ /* +2.5dB */ 0x55400155,
+ /* +2.0dB */ 0x50800142,
+ /* +1.5dB */ 0x4c000130,
+ /* +1.0dB */ 0x47c0011f,
+ /* +0.5dB */ 0x43c0010f,
+ /* 0.0dB */ 0x40000100,
+ /* -0.5dB */ 0x3c8000f2,
+ /* -1.0dB */ 0x390000e4,
+ /* -1.5dB */ 0x35c000d7,
+ /* -2.0dB */ 0x32c000cb,
+ /* -2.5dB */ 0x300000c0,
+ /* -3.0dB */ 0x2d4000b5,
+ /* -3.5dB */ 0x2ac000ab,
+ /* -4.0dB */ 0x288000a2,
+ /* -4.5dB */ 0x26000098,
+ /* -5.0dB */ 0x24000090,
+ /* -5.5dB */ 0x22000088,
+ /* -6.0dB */ 0x20000080,
+ /* -6.5dB */ 0x1a00006c,
+ /* -7.0dB */ 0x1c800072,
+ /* -7.5dB */ 0x18000060,
+ /* -8.0dB */ 0x19800066,
+ /* -8.5dB */ 0x15800056,
+ /* -9.0dB */ 0x26c0005b,
+ /* -9.5dB */ 0x14400051,
+ /* -10.0dB */ 0x24400051,
+ /* -10.5dB */ 0x1300004c,
+ /* -11.0dB */ 0x12000048,
+ /* -11.5dB */ 0x11000044,
+ /* -12.0dB */ 0x10000040
+};
+#endif
+
+
+
+void
+odm_txpowertracking_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ odm_txpowertracking_thermal_meter_init(p_dm_odm);
+}
+
+static u8
+get_swing_index(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
+ u8 i = 0;
+ u32 bb_swing;
+ u32 swing_table_size;
+ u32 *p_swing_table;
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E || p_dm_odm->support_ic_type == ODM_RTL8723B
+ || p_dm_odm->support_ic_type == ODM_RTL8192E || p_dm_odm->support_ic_type == ODM_RTL8188F || p_dm_odm->support_ic_type == ODM_RTL8703B
+ ) {
+ bb_swing = odm_get_bb_reg(p_dm_odm, REG_OFDM_0_XA_TX_IQ_IMBALANCE, 0xFFC00000);
+
+ p_swing_table = ofdm_swing_table_new;
+ swing_table_size = OFDM_TABLE_SIZE;
+ } else {
+#if ((RTL8812A_SUPPORT == 1) || (RTL8821A_SUPPORT == 1))
+ if (p_dm_odm->support_ic_type == ODM_RTL8812 || p_dm_odm->support_ic_type == ODM_RTL8821) {
+ bb_swing = phy_get_tx_bb_swing_8812a(adapter, p_hal_data->current_band_type, ODM_RF_PATH_A);
+ p_swing_table = tx_scaling_table_jaguar;
+ swing_table_size = TXSCALE_TABLE_SIZE;
+ } else
+#endif
+ {
+ bb_swing = 0;
+ p_swing_table = ofdm_swing_table;
+ swing_table_size = OFDM_TABLE_SIZE;
+ }
+ }
+
+ for (i = 0; i < swing_table_size; ++i) {
+ u32 table_value = p_swing_table[i];
+
+ if (table_value >= 0x100000)
+ table_value >>= 22;
+ if (bb_swing == table_value)
+ break;
+ }
+ return i;
+}
+
+void
+odm_txpowertracking_thermal_meter_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 default_swing_index = get_swing_index(p_dm_odm);
+ u8 p = 0;
+ struct odm_rf_calibration_structure *p_rf_calibrate_info = &(p_dm_odm->rf_calibrate_info);
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
+
+ p_rf_calibrate_info->is_txpowertracking = true;
+ p_rf_calibrate_info->tx_powercount = 0;
+ p_rf_calibrate_info->is_txpowertracking_init = false;
+
+ if (p_dm_odm->mp_mode == false)
+ p_rf_calibrate_info->txpowertrack_control = true;
+ else
+ p_rf_calibrate_info->txpowertrack_control = false;
+
+ if (p_dm_odm->mp_mode == false)
+ p_rf_calibrate_info->txpowertrack_control = true;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("p_dm_odm txpowertrack_control = %d\n", p_rf_calibrate_info->txpowertrack_control));
+
+ /* p_dm_odm->rf_calibrate_info.txpowertrack_control = true; */
+ p_rf_calibrate_info->thermal_value = p_hal_data->eeprom_thermal_meter;
+ p_rf_calibrate_info->thermal_value_iqk = p_hal_data->eeprom_thermal_meter;
+ p_rf_calibrate_info->thermal_value_lck = p_hal_data->eeprom_thermal_meter;
+
+ if (p_rf_calibrate_info->default_bb_swing_index_flag != true) {
+ /*The index of "0 dB" in SwingTable.*/
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E || p_dm_odm->support_ic_type == ODM_RTL8723B ||
+ p_dm_odm->support_ic_type == ODM_RTL8192E || p_dm_odm->support_ic_type == ODM_RTL8703B) {
+ p_rf_calibrate_info->default_ofdm_index = (default_swing_index >= OFDM_TABLE_SIZE) ? 30 : default_swing_index;
+ p_rf_calibrate_info->default_cck_index = 20;
+ } else if (p_dm_odm->support_ic_type == ODM_RTL8188F) { /*add by Mingzhi.Guo 2015-03-23*/
+ p_rf_calibrate_info->default_ofdm_index = 28; /*OFDM: -1dB*/
+ p_rf_calibrate_info->default_cck_index = 20; /*CCK:-6dB*/
+ } else if (p_dm_odm->support_ic_type == ODM_RTL8723D) { /*add by zhaohe 2015-10-27*/
+ p_rf_calibrate_info->default_ofdm_index = 28; /*OFDM: -1dB*/
+ p_rf_calibrate_info->default_cck_index = 28; /*CCK: -6dB*/
+ } else {
+ p_rf_calibrate_info->default_ofdm_index = (default_swing_index >= TXSCALE_TABLE_SIZE) ? 24 : default_swing_index;
+ p_rf_calibrate_info->default_cck_index = 24;
+ }
+ p_rf_calibrate_info->default_bb_swing_index_flag = true;
+ }
+
+ p_rf_calibrate_info->bb_swing_idx_cck_base = p_rf_calibrate_info->default_cck_index;
+ p_rf_calibrate_info->CCK_index = p_rf_calibrate_info->default_cck_index;
+
+ for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) {
+ p_rf_calibrate_info->bb_swing_idx_ofdm_base[p] = p_rf_calibrate_info->default_ofdm_index;
+ p_rf_calibrate_info->OFDM_index[p] = p_rf_calibrate_info->default_ofdm_index;
+ p_rf_calibrate_info->delta_power_index[p] = 0;
+ p_rf_calibrate_info->delta_power_index_last[p] = 0;
+ p_rf_calibrate_info->power_index_offset[p] = 0;
+ }
+ p_rf_calibrate_info->modify_tx_agc_value_ofdm = 0;
+ p_rf_calibrate_info->modify_tx_agc_value_cck = 0;
+
+}
+
+
+void
+odm_txpowertracking_check(
+ void *p_dm_void
+)
+{
+ /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate
+ at the same time. In the stage2/3, we need to prive universal interface and merge all
+ HW dynamic mechanism. */
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ switch (p_dm_odm->support_platform) {
+ case ODM_WIN:
+ odm_txpowertracking_check_mp(p_dm_odm);
+ break;
+
+ case ODM_CE:
+ odm_txpowertracking_check_ce(p_dm_odm);
+ break;
+
+ case ODM_AP:
+ odm_txpowertracking_check_ap(p_dm_odm);
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+void
+odm_txpowertracking_check_ce(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+
+ if (!(p_dm_odm->support_ability & ODM_RF_TX_PWR_TRACK))
+ return;
+
+ if (!p_dm_odm->rf_calibrate_info.tm_trigger) {
+
+ if (IS_HARDWARE_TYPE_8188E(adapter))
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_T_METER_NEW, (BIT(17) | BIT(16)), 0x03);
+ else
+ odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, RF_T_METER_OLD, RFREGOFFSETMASK, 0x60);
+
+
+
+ p_dm_odm->rf_calibrate_info.tm_trigger = 1;
+ return;
+ } else {
+
+ odm_txpowertracking_callback_thermal_meter(adapter);
+ p_dm_odm->rf_calibrate_info.tm_trigger = 0;
+ }
+}
+
+void
+odm_txpowertracking_check_mp(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+}
+
+void
+odm_txpowertracking_check_ap(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_powertracking_ce.h b/drivers/staging/rtl8188eu/hal/phydm_powertracking_ce.h
new file mode 100644
index 000000000000..ca45b6b8712f
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_powertracking_ce.h
@@ -0,0 +1,285 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMPOWERTRACKING_H__
+#define __PHYDMPOWERTRACKING_H__
+
+#define POWRTRACKING_VERSION "1.1"
+
+#define DPK_DELTA_MAPPING_NUM 13
+#define index_mapping_HP_NUM 15
+#define OFDM_TABLE_SIZE 43
+#define CCK_TABLE_SIZE 33
+#define CCK_TABLE_SIZE_88F 21
+#define TXSCALE_TABLE_SIZE 37
+#define CCK_TABLE_SIZE_8723D 41
+
+#define TXPWR_TRACK_TABLE_SIZE 30
+#define DELTA_SWINGIDX_SIZE 30
+#define DELTA_SWINTSSI_SIZE 61
+#define BAND_NUM 4
+
+#define AVG_THERMAL_NUM 8
+#define HP_THERMAL_NUM 8
+#define IQK_MAC_REG_NUM 4
+#define IQK_ADDA_REG_NUM 16
+#define IQK_BB_REG_NUM_MAX 10
+
+#define IQK_BB_REG_NUM 9
+
+
+
+#define iqk_matrix_reg_num 8
+#define IQK_MATRIX_SETTINGS_NUM (14+24+21) /* Channels_2_4G_NUM + Channels_5G_20M_NUM + Channels_5G */
+
+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 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 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. */
+static u8 delta_swing_table_idx_2ga_p_8188e[] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9};
+static u8 delta_swing_table_idx_2ga_n_8188e[] = {0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11};
+
+#define dm_check_txpowertracking odm_txpowertracking_check
+
+struct _IQK_MATRIX_REGS_SETTING {
+ bool is_iqk_done;
+ s32 value[3][iqk_matrix_reg_num];
+ bool is_bw_iqk_result_saved[3];
+};
+
+struct odm_rf_calibration_structure {
+ /* for tx power tracking */
+
+ u32 rega24; /* for TempCCK */
+ s32 rege94;
+ s32 rege9c;
+ s32 regeb4;
+ s32 regebc;
+
+ u8 tx_powercount;
+ bool is_txpowertracking_init;
+ bool is_txpowertracking;
+ u8 txpowertrack_control; /* for mp mode, turn off txpwrtracking as default */
+ u8 tm_trigger;
+ u8 internal_pa_5g[2]; /* pathA / pathB */
+
+ u8 thermal_meter[2]; /* thermal_meter, index 0 for RFIC0, and 1 for RFIC1 */
+ u8 thermal_value;
+ u8 thermal_value_lck;
+ u8 thermal_value_iqk;
+ s8 thermal_value_delta; /* delta of thermal_value and efuse thermal */
+ u8 thermal_value_dpk;
+ u8 thermal_value_avg[AVG_THERMAL_NUM];
+ u8 thermal_value_avg_index;
+ u8 thermal_value_rx_gain;
+ u8 thermal_value_crystal;
+ u8 thermal_value_dpk_store;
+ u8 thermal_value_dpk_track;
+ bool txpowertracking_in_progress;
+
+ bool is_reloadtxpowerindex;
+ u8 is_rf_pi_enable;
+ u32 txpowertracking_callback_cnt; /* cosa add for debug */
+
+
+ /* ------------------------- Tx power Tracking ------------------------- */
+ u8 is_cck_in_ch14;
+ u8 CCK_index;
+ u8 OFDM_index[MAX_RF_PATH];
+ s8 power_index_offset[MAX_RF_PATH];
+ s8 delta_power_index[MAX_RF_PATH];
+ s8 delta_power_index_last[MAX_RF_PATH];
+ bool is_tx_power_changed;
+ s8 xtal_offset;
+ s8 xtal_offset_last;
+
+ u8 thermal_value_hp[HP_THERMAL_NUM];
+ u8 thermal_value_hp_index;
+ struct _IQK_MATRIX_REGS_SETTING iqk_matrix_reg_setting[IQK_MATRIX_SETTINGS_NUM];
+ u8 delta_lck;
+ s8 bb_swing_diff_2g, bb_swing_diff_5g; /* Unit: dB */
+ u8 delta_swing_table_idx_2g_cck_a_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2g_cck_a_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2g_cck_b_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2g_cck_b_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2g_cck_c_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2g_cck_c_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2g_cck_d_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2g_cck_d_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2ga_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2ga_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2gb_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2gb_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2gc_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2gc_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2gd_p[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2gd_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5ga_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5ga_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5gb_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5gb_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5gc_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5gc_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5gd_p[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_5gd_n[BAND_NUM][DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_tssi_table_2g_cck_a[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_2g_cck_b[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_2g_cck_c[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_2g_cck_d[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_2ga[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_2gb[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_2gc[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_2gd[DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_5ga[BAND_NUM][DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_5gb[BAND_NUM][DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_5gc[BAND_NUM][DELTA_SWINTSSI_SIZE];
+ u8 delta_swing_tssi_table_5gd[BAND_NUM][DELTA_SWINTSSI_SIZE];
+ s8 delta_swing_table_xtal_p[DELTA_SWINGIDX_SIZE];
+ s8 delta_swing_table_xtal_n[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2ga_p_8188e[DELTA_SWINGIDX_SIZE];
+ u8 delta_swing_table_idx_2ga_n_8188e[DELTA_SWINGIDX_SIZE];
+
+ u8 bb_swing_idx_ofdm[MAX_RF_PATH];
+ u8 bb_swing_idx_ofdm_current;
+ u8 bb_swing_idx_ofdm_base[MAX_RF_PATH];
+ bool default_bb_swing_index_flag;
+ bool bb_swing_flag_ofdm;
+ u8 bb_swing_idx_cck;
+ u8 bb_swing_idx_cck_current;
+ u8 bb_swing_idx_cck_base;
+ u8 default_ofdm_index;
+ u8 default_cck_index;
+ bool bb_swing_flag_cck;
+
+ s8 absolute_ofdm_swing_idx[MAX_RF_PATH];
+ s8 remnant_ofdm_swing_idx[MAX_RF_PATH];
+ s8 absolute_cck_swing_idx[MAX_RF_PATH];
+ s8 remnant_cck_swing_idx;
+ s8 modify_tx_agc_value; /*Remnat compensate value at tx_agc */
+ bool modify_tx_agc_flag_path_a;
+ bool modify_tx_agc_flag_path_b;
+ bool modify_tx_agc_flag_path_c;
+ bool modify_tx_agc_flag_path_d;
+ bool modify_tx_agc_flag_path_a_cck;
+
+ s8 kfree_offset[MAX_RF_PATH];
+
+ /* -------------------------------------------------------------------- */
+
+ /* for IQK */
+ u32 regc04;
+ u32 reg874;
+ u32 regc08;
+ u32 regb68;
+ u32 regb6c;
+ u32 reg870;
+ u32 reg860;
+ u32 reg864;
+
+ bool is_iqk_initialized;
+ bool is_lck_in_progress;
+ bool is_antenna_detected;
+ bool is_need_iqk;
+ bool is_iqk_in_progress;
+ bool is_iqk_pa_off;
+ u8 delta_iqk;
+ u32 ADDA_backup[IQK_ADDA_REG_NUM];
+ u32 IQK_MAC_backup[IQK_MAC_REG_NUM];
+ u32 IQK_BB_backup_recover[9];
+ u32 IQK_BB_backup[IQK_BB_REG_NUM];
+ u32 tx_iqc_8723b[2][3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}} */
+ u32 rx_iqc_8723b[2][2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}} */
+ u32 tx_iqc_8703b[3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/
+ u32 rx_iqc_8703b[2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/
+ u32 tx_iqc_8723d[2][3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/
+ u32 rx_iqc_8723d[2][2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/
+
+ u8 iqk_step;
+ u8 kcount;
+ u8 retry_count[4][2]; /* [4]: path ABCD, [2] TXK, RXK */
+ bool is_mp_mode;
+
+
+
+ /* <James> IQK time measurement */
+ u64 iqk_start_time;
+ u64 iqk_progressing_time;
+ u64 iqk_total_progressing_time;
+
+ u32 lok_result;
+
+ /* for APK */
+ u32 ap_koutput[2][2]; /* path A/B; output1_1a/output1_2a */
+ u8 is_ap_kdone;
+ u8 is_apk_thermal_meter_ignore;
+
+ /* DPK */
+ bool is_dpk_fail;
+ u8 is_dp_done;
+ u8 is_dp_path_aok;
+ u8 is_dp_path_bok;
+
+ u32 tx_lok[2];
+ u32 dpk_tx_agc;
+ s32 dpk_gain;
+ u32 dpk_thermal[4];
+ s8 modify_tx_agc_value_ofdm;
+ s8 modify_tx_agc_value_cck;
+
+ /*Add by Yuchen for Kfree Phydm*/
+ u8 reg_rf_kfree_enable; /*for registry*/
+ u8 rf_kfree_enable; /*for efuse enable check*/
+
+};
+
+
+void
+odm_txpowertracking_check(
+ void *p_dm_void
+);
+
+
+void
+odm_txpowertracking_init(
+ void *p_dm_void
+);
+
+void
+odm_txpowertracking_check_ap(
+ void *p_dm_void
+);
+
+void
+odm_txpowertracking_thermal_meter_init(
+ void *p_dm_void
+);
+
+void
+odm_txpowertracking_init(
+ void *p_dm_void
+);
+
+void
+odm_txpowertracking_check_mp(
+ void *p_dm_void
+);
+
+
+void
+odm_txpowertracking_check_ce(
+ void *p_dm_void
+);
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_pre_define.h b/drivers/staging/rtl8188eu/hal/phydm_pre_define.h
new file mode 100644
index 000000000000..de83ea4a3d5c
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_pre_define.h
@@ -0,0 +1,578 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+
+#ifndef __PHYDMPREDEFINE_H__
+#define __PHYDMPREDEFINE_H__
+
+/* 1 ============================================================
+ * 1 Definition
+ * 1 ============================================================ */
+
+#define PHYDM_CODE_BASE "PHYDM_012"
+#define PHYDM_RELEASE_DATE "20160900"
+
+/* Max path of IC */
+#define MAX_PATH_NUM_8188E 1
+#define MAX_PATH_NUM_8192E 2
+#define MAX_PATH_NUM_8723B 1
+#define MAX_PATH_NUM_8812A 2
+#define MAX_PATH_NUM_8821A 1
+#define MAX_PATH_NUM_8814A 4
+#define MAX_PATH_NUM_8822B 2
+#define MAX_PATH_NUM_8821B 2
+#define MAX_PATH_NUM_8703B 1
+#define MAX_PATH_NUM_8188F 1
+#define MAX_PATH_NUM_8723D 1
+#define MAX_PATH_NUM_8197F 2
+#define MAX_PATH_NUM_8821C 1
+
+/* Max RF path */
+#define ODM_RF_PATH_MAX 2
+#define ODM_RF_PATH_MAX_JAGUAR 4
+
+/*Bit define path*/
+#define PHYDM_A BIT(0)
+#define PHYDM_B BIT(1)
+#define PHYDM_C BIT(2)
+#define PHYDM_D BIT(3)
+#define PHYDM_AB (BIT(0) | BIT(1))
+#define PHYDM_AC (BIT(0) | BIT(2))
+#define PHYDM_AD (BIT(0) | BIT(3))
+#define PHYDM_BC (BIT(1) | BIT(2))
+#define PHYDM_BD (BIT(1) | BIT(3))
+#define PHYDM_CD (BIT(2) | BIT(3))
+#define PHYDM_ABC (BIT(0) | BIT(1) | BIT(2))
+#define PHYDM_ABD (BIT(0) | BIT(1) | BIT(3))
+#define PHYDM_ACD (BIT(0) | BIT(2) | BIT(3))
+#define PHYDM_BCD (BIT(1) | BIT(2) | BIT(3))
+#define PHYDM_ABCD (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+
+/* number of entry */
+#define ASSOCIATE_ENTRY_NUM MACID_NUM_SW_LIMIT /* Max size of asoc_entry[].*/
+#define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM
+
+/* -----MGN rate--------------------------------- */
+
+enum ODM_MGN_RATE {
+ ODM_MGN_1M = 0x02,
+ ODM_MGN_2M = 0x04,
+ ODM_MGN_5_5M = 0x0B,
+ ODM_MGN_6M = 0x0C,
+ ODM_MGN_9M = 0x12,
+ ODM_MGN_11M = 0x16,
+ ODM_MGN_12M = 0x18,
+ ODM_MGN_18M = 0x24,
+ ODM_MGN_24M = 0x30,
+ ODM_MGN_36M = 0x48,
+ ODM_MGN_48M = 0x60,
+ ODM_MGN_54M = 0x6C,
+ ODM_MGN_MCS32 = 0x7F,
+ ODM_MGN_MCS0,
+ ODM_MGN_MCS1,
+ ODM_MGN_MCS2,
+ ODM_MGN_MCS3,
+ ODM_MGN_MCS4,
+ ODM_MGN_MCS5,
+ ODM_MGN_MCS6,
+ ODM_MGN_MCS7,
+ ODM_MGN_MCS8,
+ ODM_MGN_MCS9,
+ ODM_MGN_MCS10,
+ ODM_MGN_MCS11,
+ ODM_MGN_MCS12,
+ ODM_MGN_MCS13,
+ ODM_MGN_MCS14,
+ ODM_MGN_MCS15,
+ ODM_MGN_MCS16,
+ ODM_MGN_MCS17,
+ ODM_MGN_MCS18,
+ ODM_MGN_MCS19,
+ ODM_MGN_MCS20,
+ ODM_MGN_MCS21,
+ ODM_MGN_MCS22,
+ ODM_MGN_MCS23,
+ ODM_MGN_MCS24,
+ ODM_MGN_MCS25,
+ ODM_MGN_MCS26,
+ ODM_MGN_MCS27,
+ ODM_MGN_MCS28,
+ ODM_MGN_MCS29,
+ ODM_MGN_MCS30,
+ ODM_MGN_MCS31,
+ ODM_MGN_VHT1SS_MCS0,
+ ODM_MGN_VHT1SS_MCS1,
+ ODM_MGN_VHT1SS_MCS2,
+ ODM_MGN_VHT1SS_MCS3,
+ ODM_MGN_VHT1SS_MCS4,
+ ODM_MGN_VHT1SS_MCS5,
+ ODM_MGN_VHT1SS_MCS6,
+ ODM_MGN_VHT1SS_MCS7,
+ ODM_MGN_VHT1SS_MCS8,
+ ODM_MGN_VHT1SS_MCS9,
+ ODM_MGN_VHT2SS_MCS0,
+ ODM_MGN_VHT2SS_MCS1,
+ ODM_MGN_VHT2SS_MCS2,
+ ODM_MGN_VHT2SS_MCS3,
+ ODM_MGN_VHT2SS_MCS4,
+ ODM_MGN_VHT2SS_MCS5,
+ ODM_MGN_VHT2SS_MCS6,
+ ODM_MGN_VHT2SS_MCS7,
+ ODM_MGN_VHT2SS_MCS8,
+ ODM_MGN_VHT2SS_MCS9,
+ ODM_MGN_VHT3SS_MCS0,
+ ODM_MGN_VHT3SS_MCS1,
+ ODM_MGN_VHT3SS_MCS2,
+ ODM_MGN_VHT3SS_MCS3,
+ ODM_MGN_VHT3SS_MCS4,
+ ODM_MGN_VHT3SS_MCS5,
+ ODM_MGN_VHT3SS_MCS6,
+ ODM_MGN_VHT3SS_MCS7,
+ ODM_MGN_VHT3SS_MCS8,
+ ODM_MGN_VHT3SS_MCS9,
+ ODM_MGN_VHT4SS_MCS0,
+ ODM_MGN_VHT4SS_MCS1,
+ ODM_MGN_VHT4SS_MCS2,
+ ODM_MGN_VHT4SS_MCS3,
+ ODM_MGN_VHT4SS_MCS4,
+ ODM_MGN_VHT4SS_MCS5,
+ ODM_MGN_VHT4SS_MCS6,
+ ODM_MGN_VHT4SS_MCS7,
+ ODM_MGN_VHT4SS_MCS8,
+ ODM_MGN_VHT4SS_MCS9,
+ ODM_MGN_UNKNOWN
+};
+
+#define ODM_MGN_MCS0_SG 0xc0
+#define ODM_MGN_MCS1_SG 0xc1
+#define ODM_MGN_MCS2_SG 0xc2
+#define ODM_MGN_MCS3_SG 0xc3
+#define ODM_MGN_MCS4_SG 0xc4
+#define ODM_MGN_MCS5_SG 0xc5
+#define ODM_MGN_MCS6_SG 0xc6
+#define ODM_MGN_MCS7_SG 0xc7
+#define ODM_MGN_MCS8_SG 0xc8
+#define ODM_MGN_MCS9_SG 0xc9
+#define ODM_MGN_MCS10_SG 0xca
+#define ODM_MGN_MCS11_SG 0xcb
+#define ODM_MGN_MCS12_SG 0xcc
+#define ODM_MGN_MCS13_SG 0xcd
+#define ODM_MGN_MCS14_SG 0xce
+#define ODM_MGN_MCS15_SG 0xcf
+
+/* -----DESC rate--------------------------------- */
+
+#define ODM_RATEMCS15_SG 0x1c
+#define ODM_RATEMCS32 0x20
+
+
+/* CCK Rates, TxHT = 0 */
+#define ODM_RATE1M 0x00
+#define ODM_RATE2M 0x01
+#define ODM_RATE5_5M 0x02
+#define ODM_RATE11M 0x03
+/* OFDM Rates, TxHT = 0 */
+#define ODM_RATE6M 0x04
+#define ODM_RATE9M 0x05
+#define ODM_RATE12M 0x06
+#define ODM_RATE18M 0x07
+#define ODM_RATE24M 0x08
+#define ODM_RATE36M 0x09
+#define ODM_RATE48M 0x0A
+#define ODM_RATE54M 0x0B
+/* MCS Rates, TxHT = 1 */
+#define ODM_RATEMCS0 0x0C
+#define ODM_RATEMCS1 0x0D
+#define ODM_RATEMCS2 0x0E
+#define ODM_RATEMCS3 0x0F
+#define ODM_RATEMCS4 0x10
+#define ODM_RATEMCS5 0x11
+#define ODM_RATEMCS6 0x12
+#define ODM_RATEMCS7 0x13
+#define ODM_RATEMCS8 0x14
+#define ODM_RATEMCS9 0x15
+#define ODM_RATEMCS10 0x16
+#define ODM_RATEMCS11 0x17
+#define ODM_RATEMCS12 0x18
+#define ODM_RATEMCS13 0x19
+#define ODM_RATEMCS14 0x1A
+#define ODM_RATEMCS15 0x1B
+#define ODM_RATEMCS16 0x1C
+#define ODM_RATEMCS17 0x1D
+#define ODM_RATEMCS18 0x1E
+#define ODM_RATEMCS19 0x1F
+#define ODM_RATEMCS20 0x20
+#define ODM_RATEMCS21 0x21
+#define ODM_RATEMCS22 0x22
+#define ODM_RATEMCS23 0x23
+#define ODM_RATEMCS24 0x24
+#define ODM_RATEMCS25 0x25
+#define ODM_RATEMCS26 0x26
+#define ODM_RATEMCS27 0x27
+#define ODM_RATEMCS28 0x28
+#define ODM_RATEMCS29 0x29
+#define ODM_RATEMCS30 0x2A
+#define ODM_RATEMCS31 0x2B
+#define ODM_RATEVHTSS1MCS0 0x2C
+#define ODM_RATEVHTSS1MCS1 0x2D
+#define ODM_RATEVHTSS1MCS2 0x2E
+#define ODM_RATEVHTSS1MCS3 0x2F
+#define ODM_RATEVHTSS1MCS4 0x30
+#define ODM_RATEVHTSS1MCS5 0x31
+#define ODM_RATEVHTSS1MCS6 0x32
+#define ODM_RATEVHTSS1MCS7 0x33
+#define ODM_RATEVHTSS1MCS8 0x34
+#define ODM_RATEVHTSS1MCS9 0x35
+#define ODM_RATEVHTSS2MCS0 0x36
+#define ODM_RATEVHTSS2MCS1 0x37
+#define ODM_RATEVHTSS2MCS2 0x38
+#define ODM_RATEVHTSS2MCS3 0x39
+#define ODM_RATEVHTSS2MCS4 0x3A
+#define ODM_RATEVHTSS2MCS5 0x3B
+#define ODM_RATEVHTSS2MCS6 0x3C
+#define ODM_RATEVHTSS2MCS7 0x3D
+#define ODM_RATEVHTSS2MCS8 0x3E
+#define ODM_RATEVHTSS2MCS9 0x3F
+#define ODM_RATEVHTSS3MCS0 0x40
+#define ODM_RATEVHTSS3MCS1 0x41
+#define ODM_RATEVHTSS3MCS2 0x42
+#define ODM_RATEVHTSS3MCS3 0x43
+#define ODM_RATEVHTSS3MCS4 0x44
+#define ODM_RATEVHTSS3MCS5 0x45
+#define ODM_RATEVHTSS3MCS6 0x46
+#define ODM_RATEVHTSS3MCS7 0x47
+#define ODM_RATEVHTSS3MCS8 0x48
+#define ODM_RATEVHTSS3MCS9 0x49
+#define ODM_RATEVHTSS4MCS0 0x4A
+#define ODM_RATEVHTSS4MCS1 0x4B
+#define ODM_RATEVHTSS4MCS2 0x4C
+#define ODM_RATEVHTSS4MCS3 0x4D
+#define ODM_RATEVHTSS4MCS4 0x4E
+#define ODM_RATEVHTSS4MCS5 0x4F
+#define ODM_RATEVHTSS4MCS6 0x50
+#define ODM_RATEVHTSS4MCS7 0x51
+#define ODM_RATEVHTSS4MCS8 0x52
+#define ODM_RATEVHTSS4MCS9 0x53
+
+#define ODM_NUM_RATE_IDX (ODM_RATEVHTSS4MCS9+1)
+
+/* 1 ============================================================
+ * 1 enumeration
+ * 1 ============================================================ */
+
+
+/* ODM_CMNINFO_INTERFACE */
+enum odm_interface_e {
+ ODM_ITRF_PCIE = 0x1,
+ ODM_ITRF_USB = 0x2,
+ ODM_ITRF_SDIO = 0x4,
+ ODM_ITRF_ALL = 0x7,
+};
+
+/* ODM_CMNINFO_IC_TYPE */
+enum odm_ic_type_e {
+ ODM_RTL8188E = BIT(0),
+ ODM_RTL8812 = BIT(1),
+ ODM_RTL8821 = BIT(2),
+ ODM_RTL8192E = BIT(3),
+ ODM_RTL8723B = BIT(4),
+ ODM_RTL8814A = BIT(5),
+ ODM_RTL8881A = BIT(6),
+ ODM_RTL8822B = BIT(7),
+ ODM_RTL8703B = BIT(8),
+ ODM_RTL8195A = BIT(9),
+ ODM_RTL8188F = BIT(10),
+ ODM_RTL8723D = BIT(11),
+ ODM_RTL8197F = BIT(12),
+ ODM_RTL8821C = BIT(13),
+ ODM_RTL8814B = BIT(14),
+ ODM_RTL8198F = BIT(15)
+};
+
+
+#define ODM_IC_1SS (ODM_RTL8188E | ODM_RTL8188F | ODM_RTL8723B | ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8881A | ODM_RTL8821 | ODM_RTL8821C | ODM_RTL8195A)
+#define ODM_IC_2SS (ODM_RTL8192E | ODM_RTL8197F | ODM_RTL8812 | ODM_RTL8822B)
+#define ODM_IC_3SS (ODM_RTL8814A)
+#define ODM_IC_4SS (ODM_RTL8814B | ODM_RTL8198F)
+
+
+#define ODM_IC_11N_SERIES (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8703B | ODM_RTL8188F | ODM_RTL8723D | ODM_RTL8197F)
+#define ODM_IC_11AC_SERIES (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A | ODM_RTL8881A | ODM_RTL8822B | ODM_RTL8821C)
+#define ODM_IC_11AC_1_SERIES (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)
+#define ODM_IC_11AC_2_SERIES (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C)
+#define ODM_IC_TXBF_SUPPORT (ODM_RTL8192E | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A | ODM_RTL8881A | ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C)
+#define ODM_IC_11N_GAIN_IDX_EDCCA (ODM_RTL8195A | ODM_RTL8703B | ODM_RTL8188F | ODM_RTL8723D | ODM_RTL8197F)
+#define ODM_IC_11AC_GAIN_IDX_EDCCA (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C)
+#define ODM_IC_PHY_STATUE_NEW_TYPE (ODM_RTL8197F | ODM_RTL8822B | ODM_RTL8723D | ODM_RTL8821C)
+
+#define PHYDM_IC_8051_SERIES (ODM_RTL8881A | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8703B | ODM_RTL8188F)
+#define PHYDM_IC_3081_SERIES (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C)
+
+#define PHYDM_IC_SUPPORT_LA_MODE (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C)
+
+#define ODM_IC_11N_SERIES_SUPPORT 1
+#define ODM_IC_11AC_SERIES_SUPPORT 0
+
+#ifdef CONFIG_BT_COEXIST
+ #define ODM_CONFIG_BT_COEXIST 1
+#else
+ #define ODM_CONFIG_BT_COEXIST 0
+#endif
+
+#define ODM_PHY_STATUS_NEW_TYPE_SUPPORT 0
+
+/* ODM_CMNINFO_CUT_VER */
+enum odm_cut_version_e {
+ ODM_CUT_A = 0,
+ ODM_CUT_B = 1,
+ ODM_CUT_C = 2,
+ ODM_CUT_D = 3,
+ ODM_CUT_E = 4,
+ ODM_CUT_F = 5,
+
+ ODM_CUT_I = 8,
+ ODM_CUT_J = 9,
+ ODM_CUT_K = 10,
+ ODM_CUT_TEST = 15,
+};
+
+/* ODM_CMNINFO_FAB_VER */
+enum odm_fab_e {
+ ODM_TSMC = 0,
+ ODM_UMC = 1,
+};
+
+/* ODM_CMNINFO_RF_TYPE
+ *
+ * For example 1T2R (A+AB = BIT(0)|BIT(4)|BIT(5))
+ * */
+enum odm_rf_path_e {
+ ODM_RF_A = BIT(0),
+ ODM_RF_B = BIT(1),
+ ODM_RF_C = BIT(2),
+ ODM_RF_D = BIT(3),
+};
+
+enum odm_rf_tx_num_e {
+ ODM_1T = 1,
+ ODM_2T = 2,
+ ODM_3T = 3,
+ ODM_4T = 4,
+};
+
+enum odm_rf_type_e {
+ ODM_1T1R,
+ ODM_1T2R,
+ ODM_2T2R,
+ ODM_2T2R_GREEN,
+ ODM_2T3R,
+ ODM_2T4R,
+ ODM_3T3R,
+ ODM_3T4R,
+ ODM_4T4R,
+ ODM_XTXR
+};
+
+
+enum odm_mac_phy_mode_e {
+ ODM_SMSP = 0,
+ ODM_DMSP = 1,
+ ODM_DMDP = 2,
+};
+
+
+enum odm_bt_coexist_e {
+ ODM_BT_BUSY = 1,
+ ODM_BT_ON = 2,
+ ODM_BT_OFF = 3,
+ ODM_BT_NONE = 4,
+};
+
+/* ODM_CMNINFO_OP_MODE */
+enum odm_operation_mode_e {
+ ODM_NO_LINK = BIT(0),
+ ODM_LINK = BIT(1),
+ ODM_SCAN = BIT(2),
+ ODM_POWERSAVE = BIT(3),
+ ODM_AP_MODE = BIT(4),
+ ODM_CLIENT_MODE = BIT(5),
+ ODM_AD_HOC = BIT(6),
+ ODM_WIFI_DIRECT = BIT(7),
+ ODM_WIFI_DISPLAY = BIT(8),
+};
+
+/* ODM_CMNINFO_WM_MODE */
+enum odm_wireless_mode_e {
+ ODM_WM_UNKNOW = 0x0,
+ ODM_WM_B = BIT(0),
+ ODM_WM_G = BIT(1),
+ ODM_WM_A = BIT(2),
+ ODM_WM_N24G = BIT(3),
+ ODM_WM_N5G = BIT(4),
+ ODM_WM_AUTO = BIT(5),
+ ODM_WM_AC = BIT(6),
+};
+
+/* ODM_CMNINFO_BAND */
+enum odm_band_type_e {
+ ODM_BAND_2_4G = 0,
+ ODM_BAND_5G,
+ ODM_BAND_ON_BOTH,
+ ODM_BANDMAX
+};
+
+/* ODM_CMNINFO_SEC_CHNL_OFFSET */
+enum phydm_sec_chnl_offset_e {
+
+ PHYDM_DONT_CARE = 0,
+ PHYDM_BELOW = 1,
+ PHYDM_ABOVE = 2
+};
+
+/* ODM_CMNINFO_SEC_MODE */
+enum odm_security_e {
+ ODM_SEC_OPEN = 0,
+ ODM_SEC_WEP40 = 1,
+ ODM_SEC_TKIP = 2,
+ ODM_SEC_RESERVE = 3,
+ ODM_SEC_AESCCMP = 4,
+ ODM_SEC_WEP104 = 5,
+ ODM_WEP_WPA_MIXED = 6, /* WEP + WPA */
+ ODM_SEC_SMS4 = 7,
+};
+
+/* ODM_CMNINFO_BW */
+enum odm_bw_e {
+ ODM_BW20M = 0,
+ ODM_BW40M = 1,
+ ODM_BW80M = 2,
+ ODM_BW160M = 3,
+ ODM_BW5M = 4,
+ ODM_BW10M = 5,
+ ODM_BW_MAX = 6
+};
+
+/* ODM_CMNINFO_CHNL */
+
+/* ODM_CMNINFO_BOARD_TYPE */
+enum odm_board_type_e {
+ ODM_BOARD_DEFAULT = 0, /* The DEFAULT case. */
+ ODM_BOARD_MINICARD = BIT(0), /* 0 = non-mini card, 1= mini card. */
+ ODM_BOARD_SLIM = BIT(1), /* 0 = non-slim card, 1 = slim card */
+ ODM_BOARD_BT = BIT(2), /* 0 = without BT card, 1 = with BT */
+ ODM_BOARD_EXT_PA = BIT(3), /* 0 = no 2G ext-PA, 1 = existing 2G ext-PA */
+ ODM_BOARD_EXT_LNA = BIT(4), /* 0 = no 2G ext-LNA, 1 = existing 2G ext-LNA */
+ ODM_BOARD_EXT_TRSW = BIT(5), /* 0 = no ext-TRSW, 1 = existing ext-TRSW */
+ ODM_BOARD_EXT_PA_5G = BIT(6), /* 0 = no 5G ext-PA, 1 = existing 5G ext-PA */
+ ODM_BOARD_EXT_LNA_5G = BIT(7), /* 0 = no 5G ext-LNA, 1 = existing 5G ext-LNA */
+};
+
+enum odm_package_type_e {
+ ODM_PACKAGE_DEFAULT = 0,
+ ODM_PACKAGE_QFN68 = BIT(0),
+ ODM_PACKAGE_TFBGA90 = BIT(1),
+ ODM_PACKAGE_TFBGA79 = BIT(2),
+};
+
+enum odm_type_gpa_e {
+ TYPE_GPA0 = 0x0000,
+ TYPE_GPA1 = 0x0055,
+ TYPE_GPA2 = 0x00AA,
+ TYPE_GPA3 = 0x00FF,
+ TYPE_GPA4 = 0x5500,
+ TYPE_GPA5 = 0x5555,
+ TYPE_GPA6 = 0x55AA,
+ TYPE_GPA7 = 0x55FF,
+ TYPE_GPA8 = 0xAA00,
+ TYPE_GPA9 = 0xAA55,
+ TYPE_GPA10 = 0xAAAA,
+ TYPE_GPA11 = 0xAAFF,
+ TYPE_GPA12 = 0xFF00,
+ TYPE_GPA13 = 0xFF55,
+ TYPE_GPA14 = 0xFFAA,
+ TYPE_GPA15 = 0xFFFF,
+};
+
+enum odm_type_apa_e {
+ TYPE_APA0 = 0x0000,
+ TYPE_APA1 = 0x0055,
+ TYPE_APA2 = 0x00AA,
+ TYPE_APA3 = 0x00FF,
+ TYPE_APA4 = 0x5500,
+ TYPE_APA5 = 0x5555,
+ TYPE_APA6 = 0x55AA,
+ TYPE_APA7 = 0x55FF,
+ TYPE_APA8 = 0xAA00,
+ TYPE_APA9 = 0xAA55,
+ TYPE_APA10 = 0xAAAA,
+ TYPE_APA11 = 0xAAFF,
+ TYPE_APA12 = 0xFF00,
+ TYPE_APA13 = 0xFF55,
+ TYPE_APA14 = 0xFFAA,
+ TYPE_APA15 = 0xFFFF,
+};
+
+enum odm_type_glna_e {
+ TYPE_GLNA0 = 0x0000,
+ TYPE_GLNA1 = 0x0055,
+ TYPE_GLNA2 = 0x00AA,
+ TYPE_GLNA3 = 0x00FF,
+ TYPE_GLNA4 = 0x5500,
+ TYPE_GLNA5 = 0x5555,
+ TYPE_GLNA6 = 0x55AA,
+ TYPE_GLNA7 = 0x55FF,
+ TYPE_GLNA8 = 0xAA00,
+ TYPE_GLNA9 = 0xAA55,
+ TYPE_GLNA10 = 0xAAAA,
+ TYPE_GLNA11 = 0xAAFF,
+ TYPE_GLNA12 = 0xFF00,
+ TYPE_GLNA13 = 0xFF55,
+ TYPE_GLNA14 = 0xFFAA,
+ TYPE_GLNA15 = 0xFFFF,
+};
+
+enum odm_type_alna_e {
+ TYPE_ALNA0 = 0x0000,
+ TYPE_ALNA1 = 0x0055,
+ TYPE_ALNA2 = 0x00AA,
+ TYPE_ALNA3 = 0x00FF,
+ TYPE_ALNA4 = 0x5500,
+ TYPE_ALNA5 = 0x5555,
+ TYPE_ALNA6 = 0x55AA,
+ TYPE_ALNA7 = 0x55FF,
+ TYPE_ALNA8 = 0xAA00,
+ TYPE_ALNA9 = 0xAA55,
+ TYPE_ALNA10 = 0xAAAA,
+ TYPE_ALNA11 = 0xAAFF,
+ TYPE_ALNA12 = 0xFF00,
+ TYPE_ALNA13 = 0xFF55,
+ TYPE_ALNA14 = 0xFFAA,
+ TYPE_ALNA15 = 0xFFFF,
+};
+
+
+enum odm_rf_radio_path_e {
+ ODM_RF_PATH_A = 0, /* Radio path A */
+ ODM_RF_PATH_B = 1, /* Radio path B */
+ ODM_RF_PATH_C = 2, /* Radio path C */
+ ODM_RF_PATH_D = 3, /* Radio path D */
+ ODM_RF_PATH_AB,
+ ODM_RF_PATH_AC,
+ ODM_RF_PATH_AD,
+ ODM_RF_PATH_BC,
+ ODM_RF_PATH_BD,
+ ODM_RF_PATH_CD,
+ ODM_RF_PATH_ABC,
+ ODM_RF_PATH_ACD,
+ ODM_RF_PATH_BCD,
+ ODM_RF_PATH_ABCD,
+ /* ODM_RF_PATH_MAX, */ /* Max RF number 90 support */
+};
+
+enum odm_parameter_init_e {
+ ODM_PRE_SETTING = 0,
+ ODM_POST_SETTING = 1,
+};
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_precomp.h b/drivers/staging/rtl8188eu/hal/phydm_precomp.h
new file mode 100644
index 000000000000..7bd1d4b52e25
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_precomp.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __ODM_PRECOMP_H__
+#define __ODM_PRECOMP_H__
+
+#include "phydm_types.h"
+
+#define TEST_FALG___ 1
+
+/* 2 Config Flags and Structs - defined by each ODM type */
+
+#define __PACK
+#define __WLAN_ATTRIB_PACK__
+
+/* 2 OutSrc Header Files */
+
+#include "phydm.h"
+#include "phydm_hwconfig.h"
+#include "phydm_debug.h"
+#include "phydm_regdefine11ac.h"
+#include "phydm_regdefine11n.h"
+#include "phydm_interface.h"
+#include "phydm_reg.h"
+
+#include "phydm_adc_sampling.h"
+
+
+void
+phy_set_tx_power_limit(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 *regulation,
+ u8 *band,
+ u8 *bandwidth,
+ u8 *rate_section,
+ u8 *rf_path,
+ u8 *channel,
+ u8 *power_limit
+);
+
+#define RTL8188E_T_SUPPORT 1
+#ifdef CONFIG_SFW_SUPPORTED
+ #define RTL8188E_S_SUPPORT 1
+#else
+ #define RTL8188E_S_SUPPORT 0
+#endif
+
+#include "hal8188erateadaptive.h" /* for RA,Power training */
+#include "halhwimg8188e_mac.h"
+#include "halhwimg8188e_rf.h"
+#include "halhwimg8188e_bb.h"
+#include "phydm_regconfig8188e.h"
+#include "phydm_rtl8188e.h"
+#include "hal8188ereg.h"
+#include "version_rtl8188e.h"
+#include "rtl8188e_hal.h"
+#include "halphyrf_8188e_ce.h"
+
+#endif /* __ODM_PRECOMP_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/phydm_rainfo.c b/drivers/staging/rtl8188eu/hal/phydm_rainfo.c
new file mode 100644
index 000000000000..dcfe419329da
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_rainfo.c
@@ -0,0 +1,2198 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+
+void
+phydm_h2C_debug(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 h2c_parameter[H2C_MAX_LENGTH] = {0};
+ u8 phydm_h2c_id = (u8)dm_value[0];
+ u8 i;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ PHYDM_SNPRINTF((output + used, out_len - used, "Phydm Send H2C_ID (( 0x%x))\n", phydm_h2c_id));
+ for (i = 0; i < H2C_MAX_LENGTH; i++) {
+
+ h2c_parameter[i] = (u8)dm_value[i + 1];
+ PHYDM_SNPRINTF((output + used, out_len - used, "H2C: Byte[%d] = ((0x%x))\n", i, h2c_parameter[i]));
+ }
+
+ odm_fill_h2c_cmd(p_dm_odm, phydm_h2c_id, H2C_MAX_LENGTH, h2c_parameter);
+
+}
+
+#if (defined(CONFIG_RA_DBG_CMD))
+void
+odm_ra_para_adjust_send_h2c(
+ void *p_dm_void
+)
+{
+
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ u8 h2c_parameter[6] = {0};
+
+ h2c_parameter[0] = RA_FIRST_MACID;
+
+ if (p_ra_table->ra_para_feedback_req) { /*h2c_parameter[5]=1 ; ask FW for all RA parameters*/
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("[H2C] Ask FW for RA parameter\n"));
+ h2c_parameter[5] |= BIT(1); /*ask FW to report RA parameters*/
+ h2c_parameter[1] = p_ra_table->para_idx; /*p_ra_table->para_idx;*/
+ p_ra_table->ra_para_feedback_req = 0;
+ } else {
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("[H2C] Send H2C to FW for modifying RA parameter\n"));
+
+ h2c_parameter[1] = p_ra_table->para_idx;
+ h2c_parameter[2] = p_ra_table->rate_idx;
+ /* [8 bit]*/
+ if (p_ra_table->para_idx == RADBG_RTY_PENALTY || p_ra_table->para_idx == RADBG_RATE_UP_RTY_RATIO || p_ra_table->para_idx == RADBG_RATE_DOWN_RTY_RATIO) {
+ h2c_parameter[3] = p_ra_table->value;
+ h2c_parameter[4] = 0;
+ }
+ /* [16 bit]*/
+ else {
+ h2c_parameter[3] = (u8)(((p_ra_table->value_16) & 0xf0) >> 4); /*byte1*/
+ h2c_parameter[4] = (u8)((p_ra_table->value_16) & 0x0f); /*byte0*/
+ }
+ }
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" h2c_parameter[1] = 0x%x\n", h2c_parameter[1]));
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" h2c_parameter[2] = 0x%x\n", h2c_parameter[2]));
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" h2c_parameter[3] = 0x%x\n", h2c_parameter[3]));
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" h2c_parameter[4] = 0x%x\n", h2c_parameter[4]));
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" h2c_parameter[5] = 0x%x\n", h2c_parameter[5]));
+
+ odm_fill_h2c_cmd(p_dm_odm, ODM_H2C_RA_PARA_ADJUST, 6, h2c_parameter);
+
+}
+
+
+void
+odm_ra_para_adjust(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ u8 rate_idx = p_ra_table->rate_idx;
+ u8 value = p_ra_table->value;
+ u8 pre_value = 0xff;
+
+ if (p_ra_table->para_idx == RADBG_RTY_PENALTY) {
+ pre_value = p_ra_table->RTY_P[rate_idx];
+ p_ra_table->RTY_P[rate_idx] = value;
+ p_ra_table->RTY_P_modify_note[rate_idx] = 1;
+ } else if (p_ra_table->para_idx == RADBG_N_HIGH) {
+
+ } else if (p_ra_table->para_idx == RADBG_N_LOW) {
+
+ } else if (p_ra_table->para_idx == RADBG_RATE_UP_RTY_RATIO) {
+ pre_value = p_ra_table->RATE_UP_RTY_RATIO[rate_idx];
+ p_ra_table->RATE_UP_RTY_RATIO[rate_idx] = value;
+ p_ra_table->RATE_UP_RTY_RATIO_modify_note[rate_idx] = 1;
+ } else if (p_ra_table->para_idx == RADBG_RATE_DOWN_RTY_RATIO) {
+ pre_value = p_ra_table->RATE_DOWN_RTY_RATIO[rate_idx];
+ p_ra_table->RATE_DOWN_RTY_RATIO[rate_idx] = value;
+ p_ra_table->RATE_DOWN_RTY_RATIO_modify_note[rate_idx] = 1;
+ }
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("Change RA Papa[%d], rate[ %d ], ((%d)) -> ((%d))\n", p_ra_table->para_idx, rate_idx, pre_value, value));
+ odm_ra_para_adjust_send_h2c(p_dm_odm);
+}
+
+void
+phydm_ra_print_msg(
+ void *p_dm_void,
+ u8 *value,
+ u8 *value_default,
+ u8 *modify_note
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ u32 i;
+
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" |rate index| |Current-value| |Default-value| |Modify?|\n"));
+ for (i = 0 ; i <= (p_ra_table->rate_length); i++) {
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" [ %d ] %10d %14d %14s\n", i, value[i], value_default[i], ((modify_note[i] == 1) ? "V" : " . ")));
+ }
+
+}
+
+void
+odm_RA_debug(
+ void *p_dm_void,
+ u32 *const dm_value
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+
+ p_ra_table->is_ra_dbg_init = false;
+
+ if (dm_value[0] == 100) { /*1 Print RA Parameters*/
+ u8 default_pointer_value;
+ u8 *pvalue;
+ u8 *pvalue_default;
+ u8 *pmodify_note;
+
+ pvalue = pvalue_default = pmodify_note = &default_pointer_value;
+
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("\n------------------------------------------------------------------------------------\n"));
+
+ if (dm_value[1] == RADBG_RTY_PENALTY) { /* [1]*/
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" [1] RTY_PENALTY\n"));
+ pvalue = &(p_ra_table->RTY_P[0]);
+ pvalue_default = &(p_ra_table->RTY_P_default[0]);
+ pmodify_note = (u8 *)&(p_ra_table->RTY_P_modify_note[0]);
+ } else if (dm_value[1] == RADBG_N_HIGH) /* [2]*/
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" [2] N_HIGH\n"));
+
+ else if (dm_value[1] == RADBG_N_LOW) /*[3]*/
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" [3] N_LOW\n"));
+
+ else if (dm_value[1] == RADBG_RATE_UP_RTY_RATIO) { /* [8]*/
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" [8] RATE_UP_RTY_RATIO\n"));
+ pvalue = &(p_ra_table->RATE_UP_RTY_RATIO[0]);
+ pvalue_default = &(p_ra_table->RATE_UP_RTY_RATIO_default[0]);
+ pmodify_note = (u8 *)&(p_ra_table->RATE_UP_RTY_RATIO_modify_note[0]);
+ } else if (dm_value[1] == RADBG_RATE_DOWN_RTY_RATIO) { /* [9]*/
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" [9] RATE_DOWN_RTY_RATIO\n"));
+ pvalue = &(p_ra_table->RATE_DOWN_RTY_RATIO[0]);
+ pvalue_default = &(p_ra_table->RATE_DOWN_RTY_RATIO_default[0]);
+ pmodify_note = (u8 *)&(p_ra_table->RATE_DOWN_RTY_RATIO_modify_note[0]);
+ }
+
+ phydm_ra_print_msg(p_dm_odm, pvalue, pvalue_default, pmodify_note);
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("\n------------------------------------------------------------------------------------\n\n"));
+
+ } else if (dm_value[0] == 101) {
+ p_ra_table->para_idx = (u8)dm_value[1];
+
+ p_ra_table->ra_para_feedback_req = 1;
+ odm_ra_para_adjust_send_h2c(p_dm_odm);
+ } else {
+ p_ra_table->para_idx = (u8)dm_value[0];
+ p_ra_table->rate_idx = (u8)dm_value[1];
+ p_ra_table->value = (u8)dm_value[2];
+
+ odm_ra_para_adjust(p_dm_odm);
+ }
+}
+
+void
+odm_ra_para_adjust_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ u8 i;
+ u8 ra_para_pool_u8[3] = { RADBG_RTY_PENALTY, RADBG_RATE_UP_RTY_RATIO, RADBG_RATE_DOWN_RTY_RATIO};
+ u8 rate_size_ht_1ss = 20, rate_size_ht_2ss = 28, rate_size_ht_3ss = 36; /*4+8+8+8+8 =36*/
+ u8 rate_size_vht_1ss = 10, rate_size_vht_2ss = 20, rate_size_vht_3ss = 30; /*10 + 10 +10 =30*/
+
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("odm_ra_para_adjust_init\n"));
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8188F | ODM_RTL8195A | ODM_RTL8703B | ODM_RTL8723B | ODM_RTL8188E | ODM_RTL8723D))
+ p_ra_table->rate_length = rate_size_ht_1ss;
+ else if (p_dm_odm->support_ic_type & (ODM_RTL8192E | ODM_RTL8197F))
+ p_ra_table->rate_length = rate_size_ht_2ss;
+ else if (p_dm_odm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A | ODM_RTL8821C))
+ p_ra_table->rate_length = rate_size_ht_1ss + rate_size_vht_1ss;
+ else if (p_dm_odm->support_ic_type & (ODM_RTL8812 | ODM_RTL8822B))
+ p_ra_table->rate_length = rate_size_ht_2ss + rate_size_vht_2ss;
+ else if (p_dm_odm->support_ic_type == ODM_RTL8814A)
+ p_ra_table->rate_length = rate_size_ht_3ss + rate_size_vht_3ss;
+ else
+ p_ra_table->rate_length = rate_size_ht_1ss;
+
+ p_ra_table->is_ra_dbg_init = true;
+ for (i = 0; i < 3; i++) {
+ p_ra_table->ra_para_feedback_req = 1;
+ p_ra_table->para_idx = ra_para_pool_u8[i];
+ odm_ra_para_adjust_send_h2c(p_dm_odm);
+ }
+}
+
+#else
+
+void
+phydm_RA_debug_PCR(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ u32 used = *_used;
+ u32 out_len = *_out_len;
+
+ if (dm_value[0] == 100) {
+ PHYDM_SNPRINTF((output + used, out_len - used, "[Get] PCR RA_threshold_offset = (( %s%d ))\n", ((p_ra_table->RA_threshold_offset == 0) ? " " : ((p_ra_table->RA_offset_direction) ? "+" : "-")), p_ra_table->RA_threshold_offset));
+ /**/
+ } else if (dm_value[0] == 0) {
+ p_ra_table->RA_offset_direction = 0;
+ p_ra_table->RA_threshold_offset = (u8)dm_value[1];
+ PHYDM_SNPRINTF((output + used, out_len - used, "[Set] PCR RA_threshold_offset = (( -%d ))\n", p_ra_table->RA_threshold_offset));
+ } else if (dm_value[0] == 1) {
+ p_ra_table->RA_offset_direction = 1;
+ p_ra_table->RA_threshold_offset = (u8)dm_value[1];
+ PHYDM_SNPRINTF((output + used, out_len - used, "[Set] PCR RA_threshold_offset = (( +%d ))\n", p_ra_table->RA_threshold_offset));
+ } else {
+ PHYDM_SNPRINTF((output + used, out_len - used, "[Set] Error\n"));
+ /**/
+ }
+
+}
+
+#endif /*#if (defined(CONFIG_RA_DBG_CMD))*/
+
+void
+odm_c2h_ra_para_report_handler(
+ void *p_dm_void,
+ u8 *cmd_buf,
+ u8 cmd_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+
+ u8 para_idx = cmd_buf[0]; /*Retry Penalty, NH, NL*/
+ u8 rate_type_start = cmd_buf[1];
+ u8 rate_type_length = cmd_len - 2;
+ u8 i;
+
+
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("[ From FW C2H RA Para ] cmd_buf[0]= (( %d ))\n", cmd_buf[0]));
+
+#if (defined(CONFIG_RA_DBG_CMD))
+ if (para_idx == RADBG_RTY_PENALTY) {
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" |rate index| |RTY Penality index|\n"));
+
+ for (i = 0 ; i < (rate_type_length) ; i++) {
+ if (p_ra_table->is_ra_dbg_init)
+ p_ra_table->RTY_P_default[rate_type_start + i] = cmd_buf[2 + i];
+
+ p_ra_table->RTY_P[rate_type_start + i] = cmd_buf[2 + i];
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("%8d %15d\n", (rate_type_start + i), p_ra_table->RTY_P[rate_type_start + i]));
+ }
+
+ } else if (para_idx == RADBG_N_HIGH) {
+ /**/
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" |rate index| |N-High|\n"));
+
+
+ } else if (para_idx == RADBG_N_LOW) {
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" |rate index| |N-Low|\n"));
+ /**/
+ } else if (para_idx == RADBG_RATE_UP_RTY_RATIO) {
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" |rate index| |rate Up RTY Ratio|\n"));
+
+ for (i = 0; i < (rate_type_length); i++) {
+ if (p_ra_table->is_ra_dbg_init)
+ p_ra_table->RATE_UP_RTY_RATIO_default[rate_type_start + i] = cmd_buf[2 + i];
+
+ p_ra_table->RATE_UP_RTY_RATIO[rate_type_start + i] = cmd_buf[2 + i];
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("%8d %15d\n", (rate_type_start + i), p_ra_table->RATE_UP_RTY_RATIO[rate_type_start + i]));
+ }
+ } else if (para_idx == RADBG_RATE_DOWN_RTY_RATIO) {
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" |rate index| |rate Down RTY Ratio|\n"));
+
+ for (i = 0; i < (rate_type_length); i++) {
+ if (p_ra_table->is_ra_dbg_init)
+ p_ra_table->RATE_DOWN_RTY_RATIO_default[rate_type_start + i] = cmd_buf[2 + i];
+
+ p_ra_table->RATE_DOWN_RTY_RATIO[rate_type_start + i] = cmd_buf[2 + i];
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("%8d %15d\n", (rate_type_start + i), p_ra_table->RATE_DOWN_RTY_RATIO[rate_type_start + i]));
+ }
+ } else
+#endif
+ if (para_idx == RADBG_DEBUG_MONITOR1) {
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("-------------------------------\n"));
+ if (p_dm_odm->support_ic_type & PHYDM_IC_3081_SERIES) {
+
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "RSSI =", cmd_buf[1]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x\n", "rate =", cmd_buf[2] & 0x7f));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "SGI =", (cmd_buf[2] & 0x80) >> 7));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "BW =", cmd_buf[3]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "BW_max =", cmd_buf[4]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x\n", "multi_rate0 =", cmd_buf[5]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x\n", "multi_rate1 =", cmd_buf[6]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "DISRA =", cmd_buf[7]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "VHT_EN =", cmd_buf[8]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "SGI_support =", cmd_buf[9]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "try_ness =", cmd_buf[10]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x\n", "pre_rate =", cmd_buf[11]));
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "RSSI =", cmd_buf[1]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %x\n", "BW =", cmd_buf[2]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "DISRA =", cmd_buf[3]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "VHT_EN =", cmd_buf[4]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "Hightest rate =", cmd_buf[5]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x\n", "Lowest rate =", cmd_buf[6]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x\n", "SGI_support =", cmd_buf[7]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "Rate_ID =", cmd_buf[8]));;
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("-------------------------------\n"));
+ } else if (para_idx == RADBG_DEBUG_MONITOR2) {
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("-------------------------------\n"));
+ if (p_dm_odm->support_ic_type & PHYDM_IC_3081_SERIES) {
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "rate_id =", cmd_buf[1]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x\n", "highest_rate =", cmd_buf[2]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x\n", "lowest_rate =", cmd_buf[3]));
+
+ for (i = 4; i <= 11; i++)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("RAMASK = 0x%x\n", cmd_buf[i]));
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %x%x %x%x %x%x %x%x\n", "RA Mask:",
+ cmd_buf[8], cmd_buf[7], cmd_buf[6], cmd_buf[5], cmd_buf[4], cmd_buf[3], cmd_buf[2], cmd_buf[1]));
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("-------------------------------\n"));
+ } else if (para_idx == RADBG_DEBUG_MONITOR3) {
+
+ for (i = 0; i < (cmd_len - 1); i++)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("content[%d] = %d\n", i, cmd_buf[1 + i]));
+ } else if (para_idx == RADBG_DEBUG_MONITOR4)
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s {%d.%d}\n", "RA version =", cmd_buf[1], cmd_buf[2]));
+ else if (para_idx == RADBG_DEBUG_MONITOR5) {
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x\n", "Current rate =", cmd_buf[1]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "Retry ratio =", cmd_buf[2]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d\n", "rate down ratio =", cmd_buf[3]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x\n", "highest rate =", cmd_buf[4]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s {0x%x 0x%x}\n", "Muti-try =", cmd_buf[5], cmd_buf[6]));
+ ODM_RT_TRACE(p_dm_odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x%x%x%x%x\n", "RA mask =", cmd_buf[11], cmd_buf[10], cmd_buf[9], cmd_buf[8], cmd_buf[7]));
+ }
+}
+
+void
+phydm_ra_dynamic_retry_count(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ struct sta_info *p_entry;
+ u8 i, retry_offset;
+ u32 ma_rx_tp;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_DYNAMIC_ARFR))
+ return;
+
+ /*ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("p_dm_odm->pre_b_noisy = %d\n", p_dm_odm->pre_b_noisy ));*/
+ if (p_dm_odm->pre_b_noisy != p_dm_odm->noisy_decision) {
+
+ if (p_dm_odm->noisy_decision) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("->Noisy Env. RA fallback value\n"));
+ odm_set_mac_reg(p_dm_odm, 0x430, MASKDWORD, 0x0);
+ odm_set_mac_reg(p_dm_odm, 0x434, MASKDWORD, 0x04030201);
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("->Clean Env. RA fallback value\n"));
+ odm_set_mac_reg(p_dm_odm, 0x430, MASKDWORD, 0x01000000);
+ odm_set_mac_reg(p_dm_odm, 0x434, MASKDWORD, 0x06050402);
+ }
+ p_dm_odm->pre_b_noisy = p_dm_odm->noisy_decision;
+ }
+}
+
+#if (defined(CONFIG_RA_DYNAMIC_RTY_LIMIT))
+
+void
+phydm_retry_limit_table_bound(
+ void *p_dm_void,
+ u8 *retry_limit,
+ u8 offset
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+
+ if (*retry_limit > offset) {
+
+ *retry_limit -= offset;
+
+ if (*retry_limit < p_ra_table->retrylimit_low)
+ *retry_limit = p_ra_table->retrylimit_low;
+ else if (*retry_limit > p_ra_table->retrylimit_high)
+ *retry_limit = p_ra_table->retrylimit_high;
+ } else
+ *retry_limit = p_ra_table->retrylimit_low;
+}
+
+void
+phydm_reset_retry_limit_table(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ u8 i;
+
+#if ((RTL8192E_SUPPORT == 1) || (RTL8723B_SUPPORT == 1) || (RTL8188E_SUPPORT == 1))
+ u8 per_rate_retrylimit_table_20M[ODM_RATEMCS15 + 1] = {
+ 1, 1, 2, 4, /*CCK*/
+ 2, 2, 4, 6, 8, 12, 16, 18, /*OFDM*/
+ 2, 4, 6, 8, 12, 18, 20, 22, /*20M HT-1SS*/
+ 2, 4, 6, 8, 12, 18, 20, 22 /*20M HT-2SS*/
+ };
+ u8 per_rate_retrylimit_table_40M[ODM_RATEMCS15 + 1] = {
+ 1, 1, 2, 4, /*CCK*/
+ 2, 2, 4, 6, 8, 12, 16, 18, /*OFDM*/
+ 4, 8, 12, 16, 24, 32, 32, 32, /*40M HT-1SS*/
+ 4, 8, 12, 16, 24, 32, 32, 32 /*40M HT-2SS*/
+ };
+
+#elif (RTL8821A_SUPPORT == 1) || (RTL8881A_SUPPORT == 1)
+
+#elif (RTL8812A_SUPPORT == 1)
+
+#elif (RTL8814A_SUPPORT == 1)
+
+#else
+
+#endif
+
+ memcpy(&(p_ra_table->per_rate_retrylimit_20M[0]), &(per_rate_retrylimit_table_20M[0]), ODM_NUM_RATE_IDX);
+ memcpy(&(p_ra_table->per_rate_retrylimit_40M[0]), &(per_rate_retrylimit_table_40M[0]), ODM_NUM_RATE_IDX);
+
+ for (i = 0; i < ODM_NUM_RATE_IDX; i++) {
+ phydm_retry_limit_table_bound(p_dm_odm, &(p_ra_table->per_rate_retrylimit_20M[i]), 0);
+ phydm_retry_limit_table_bound(p_dm_odm, &(p_ra_table->per_rate_retrylimit_40M[i]), 0);
+ }
+}
+
+void
+phydm_ra_dynamic_retry_limit_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+
+ p_ra_table->retry_descend_num = RA_RETRY_DESCEND_NUM;
+ p_ra_table->retrylimit_low = RA_RETRY_LIMIT_LOW;
+ p_ra_table->retrylimit_high = RA_RETRY_LIMIT_HIGH;
+
+ phydm_reset_retry_limit_table(p_dm_odm);
+
+}
+
+#endif
+
+void
+phydm_ra_dynamic_retry_limit(
+ void *p_dm_void
+)
+{
+#if (defined(CONFIG_RA_DYNAMIC_RTY_LIMIT))
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ struct sta_info *p_entry;
+ u8 i, retry_offset;
+ u32 ma_rx_tp;
+
+
+ if (p_dm_odm->pre_number_active_client == p_dm_odm->number_active_client) {
+
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" pre_number_active_client == number_active_client\n"));
+ return;
+
+ } else {
+ if (p_dm_odm->number_active_client == 1) {
+ phydm_reset_retry_limit_table(p_dm_odm);
+ ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("one client only->reset to default value\n"));
+ } else {
+
+ retry_offset = p_dm_odm->number_active_client * p_ra_table->retry_descend_num;
+
+ for (i = 0; i < ODM_NUM_RATE_IDX; i++) {
+
+ phydm_retry_limit_table_bound(p_dm_odm, &(p_ra_table->per_rate_retrylimit_20M[i]), retry_offset);
+ phydm_retry_limit_table_bound(p_dm_odm, &(p_ra_table->per_rate_retrylimit_40M[i]), retry_offset);
+ }
+ }
+ }
+#endif
+}
+
+#if (defined(CONFIG_RA_DYNAMIC_RATE_ID))
+void
+phydm_ra_dynamic_rate_id_on_assoc(
+ void *p_dm_void,
+ u8 wireless_mode,
+ u8 init_rate_id
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("[ON ASSOC] rf_mode = ((0x%x)), wireless_mode = ((0x%x)), init_rate_id = ((0x%x))\n", p_dm_odm->rf_type, wireless_mode, init_rate_id));
+
+ if ((p_dm_odm->rf_type == ODM_2T2R) | (p_dm_odm->rf_type == ODM_2T2R_GREEN) | (p_dm_odm->rf_type == ODM_2T3R) | (p_dm_odm->rf_type == ODM_2T4R)) {
+
+ if ((p_dm_odm->support_ic_type & (ODM_RTL8812 | ODM_RTL8192E)) &&
+ (wireless_mode & (ODM_WM_N24G | ODM_WM_N5G))
+ ) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("[ON ASSOC] set N-2SS ARFR5 table\n"));
+ odm_set_mac_reg(p_dm_odm, 0x4a4, MASKDWORD, 0xfc1ffff); /*N-2SS, ARFR5, rate_id = 0xe*/
+ odm_set_mac_reg(p_dm_odm, 0x4a8, MASKDWORD, 0x0); /*N-2SS, ARFR5, rate_id = 0xe*/
+ } else if ((p_dm_odm->support_ic_type & (ODM_RTL8812)) &&
+ (wireless_mode & (ODM_WM_AC_5G | ODM_WM_AC_24G | ODM_WM_AC_ONLY))
+ ) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("[ON ASSOC] set AC-2SS ARFR0 table\n"));
+ odm_set_mac_reg(p_dm_odm, 0x444, MASKDWORD, 0x0fff); /*AC-2SS, ARFR0, rate_id = 0x9*/
+ odm_set_mac_reg(p_dm_odm, 0x448, MASKDWORD, 0xff01f000); /*AC-2SS, ARFR0, rate_id = 0x9*/
+ }
+ }
+
+}
+
+void
+phydm_ra_dynamic_rate_id_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (p_dm_odm->support_ic_type & (ODM_RTL8812 | ODM_RTL8192E)) {
+
+ odm_set_mac_reg(p_dm_odm, 0x4a4, MASKDWORD, 0xfc1ffff); /*N-2SS, ARFR5, rate_id = 0xe*/
+ odm_set_mac_reg(p_dm_odm, 0x4a8, MASKDWORD, 0x0); /*N-2SS, ARFR5, rate_id = 0xe*/
+
+ odm_set_mac_reg(p_dm_odm, 0x444, MASKDWORD, 0x0fff); /*AC-2SS, ARFR0, rate_id = 0x9*/
+ odm_set_mac_reg(p_dm_odm, 0x448, MASKDWORD, 0xff01f000); /*AC-2SS, ARFR0, rate_id = 0x9*/
+ }
+}
+
+void
+phydm_update_rate_id(
+ void *p_dm_void,
+ u8 rate,
+ u8 platform_macid
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ u8 current_tx_ss;
+ u8 rate_idx = rate & 0x7f; /*remove bit7 SGI*/
+ u8 wireless_mode;
+ u8 phydm_macid;
+ struct sta_info *p_entry;
+
+
+#if 0
+ if (rate_idx >= ODM_RATEVHTSS2MCS0) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("rate[%d]: (( VHT2SS-MCS%d ))\n", platform_macid, (rate_idx - ODM_RATEVHTSS2MCS0)));
+ /*dummy for SD4 check patch*/
+ } else if (rate_idx >= ODM_RATEVHTSS1MCS0) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("rate[%d]: (( VHT1SS-MCS%d ))\n", platform_macid, (rate_idx - ODM_RATEVHTSS1MCS0)));
+ /*dummy for SD4 check patch*/
+ } else if (rate_idx >= ODM_RATEMCS0) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("rate[%d]: (( HT-MCS%d ))\n", platform_macid, (rate_idx - ODM_RATEMCS0)));
+ /*dummy for SD4 check patch*/
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("rate[%d]: (( HT-MCS%d ))\n", platform_macid, rate_idx));
+ /*dummy for SD4 check patch*/
+ }
+#endif
+
+ phydm_macid = p_dm_odm->platform2phydm_macid_table[platform_macid];
+ p_entry = p_dm_odm->p_odm_sta_info[phydm_macid];
+
+ if (IS_STA_VALID(p_entry)) {
+ wireless_mode = p_entry->wireless_mode;
+
+ if ((p_dm_odm->rf_type == ODM_2T2R) | (p_dm_odm->rf_type == ODM_2T2R_GREEN) | (p_dm_odm->rf_type == ODM_2T3R) | (p_dm_odm->rf_type == ODM_2T4R)) {
+
+ p_entry->ratr_idx = p_entry->ratr_idx_init;
+ if (wireless_mode & (ODM_WM_N24G | ODM_WM_N5G)) { /*N mode*/
+ if (rate_idx >= ODM_RATEMCS8 && rate_idx <= ODM_RATEMCS15) { /*2SS mode*/
+
+ p_entry->ratr_idx = ARFR_5_RATE_ID;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("ARFR_5\n"));
+ }
+ } else if (wireless_mode & (ODM_WM_AC_5G | ODM_WM_AC_24G | ODM_WM_AC_ONLY)) {/*AC mode*/
+ if (rate_idx >= ODM_RATEVHTSS2MCS0 && rate_idx <= ODM_RATEVHTSS2MCS9) {/*2SS mode*/
+
+ p_entry->ratr_idx = ARFR_0_RATE_ID;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("ARFR_0\n"));
+ }
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("UPdate_RateID[%d]: (( 0x%x ))\n", platform_macid, p_entry->ratr_idx));
+ }
+ }
+
+}
+#endif
+
+void
+phydm_print_rate(
+ void *p_dm_void,
+ u8 rate,
+ u32 dbg_component
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 legacy_table[12] = {1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54};
+ u8 rate_idx = rate & 0x7f; /*remove bit7 SGI*/
+ u8 vht_en = (rate_idx >= ODM_RATEVHTSS1MCS0) ? 1 : 0;
+ u8 b_sgi = (rate & 0x80) >> 7;
+
+ ODM_RT_TRACE_F(p_dm_odm, dbg_component, ODM_DBG_LOUD, ("( %s%s%s%s%d%s%s)\n",
+ ((rate_idx >= ODM_RATEVHTSS1MCS0) && (rate_idx <= ODM_RATEVHTSS1MCS9)) ? "VHT 1ss " : "",
+ ((rate_idx >= ODM_RATEVHTSS2MCS0) && (rate_idx <= ODM_RATEVHTSS2MCS9)) ? "VHT 2ss " : "",
+ ((rate_idx >= ODM_RATEVHTSS3MCS0) && (rate_idx <= ODM_RATEVHTSS3MCS9)) ? "VHT 3ss " : "",
+ (rate_idx >= ODM_RATEMCS0) ? "MCS " : "",
+ (vht_en) ? ((rate_idx - ODM_RATEVHTSS1MCS0) % 10) : ((rate_idx >= ODM_RATEMCS0) ? (rate_idx - ODM_RATEMCS0) : ((rate_idx <= ODM_RATE54M) ? legacy_table[rate_idx] : 0)),
+ (b_sgi) ? "-S" : " ",
+ (rate_idx >= ODM_RATEMCS0) ? "" : "M"));
+}
+
+void
+phydm_c2h_ra_report_handler(
+ void *p_dm_void,
+ u8 *cmd_buf,
+ u8 cmd_len
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ u8 legacy_table[12] = {1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54};
+ u8 macid = cmd_buf[1];
+ u8 rate = cmd_buf[0];
+ u8 rate_idx = rate & 0x7f; /*remove bit7 SGI*/
+ u8 pre_rate = p_ra_table->link_tx_rate[macid];
+ u8 rate_order;
+
+ if (cmd_len >= 4) {
+ if (cmd_buf[3] == 0) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("TX Init-rate Update[%d]:", macid));
+ /**/
+ } else if (cmd_buf[3] == 0xff) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("FW Level: Fix rate[%d]:", macid));
+ /**/
+ } else if (cmd_buf[3] == 1) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("Try Success[%d]:", macid));
+ /**/
+ } else if (cmd_buf[3] == 2) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("Try Fail & Try Again[%d]:", macid));
+ /**/
+ } else if (cmd_buf[3] == 3) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("rate Back[%d]:", macid));
+ /**/
+ } else if (cmd_buf[3] == 4) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("start rate by RSSI[%d]:", macid));
+ /**/
+ } else if (cmd_buf[3] == 5) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("Try rate[%d]:", macid));
+ /**/
+ }
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("Tx rate Update[%d]:", macid));
+ /**/
+ }
+
+ /*phydm_print_rate(p_dm_odm, pre_rate_idx, ODM_COMP_RATE_ADAPTIVE);*/
+ /*ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, (">\n",macid );*/
+ phydm_print_rate(p_dm_odm, rate, ODM_COMP_RATE_ADAPTIVE);
+
+ p_ra_table->link_tx_rate[macid] = rate;
+
+ /*trigger power training*/
+
+ rate_order = phydm_rate_order_compute(p_dm_odm, rate_idx);
+
+ if ((p_dm_odm->is_one_entry_only) ||
+ ((rate_order > p_ra_table->highest_client_tx_order) && (p_ra_table->power_tracking_flag == 1))
+ ) {
+ phydm_update_pwr_track(p_dm_odm, rate_idx);
+ p_ra_table->power_tracking_flag = 0;
+ }
+
+ /*trigger dynamic rate ID*/
+#if (defined(CONFIG_RA_DYNAMIC_RATE_ID))
+ if (p_dm_odm->support_ic_type & (ODM_RTL8812 | ODM_RTL8192E))
+ phydm_update_rate_id(p_dm_odm, rate, macid);
+#endif
+
+}
+
+void
+odm_rssi_monitor_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+
+ p_ra_table->firstconnect = false;
+}
+
+void
+odm_ra_post_action_on_assoc(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ /*
+ p_dm_odm->h2c_rarpt_connect = 1;
+ odm_rssi_monitor_check(p_dm_odm);
+ p_dm_odm->h2c_rarpt_connect = 0;
+ */
+}
+
+void
+phydm_init_ra_info(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+}
+
+void
+phydm_modify_RA_PCR_threshold(
+ void *p_dm_void,
+ u8 RA_offset_direction,
+ u8 RA_threshold_offset
+
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+
+ p_ra_table->RA_offset_direction = RA_offset_direction;
+ p_ra_table->RA_threshold_offset = RA_threshold_offset;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("Set RA_threshold_offset = (( %s%d ))\n", ((RA_threshold_offset == 0) ? " " : ((RA_offset_direction) ? "+" : "-")), RA_threshold_offset));
+}
+
+static void
+odm_rssi_monitor_check_mp(
+ void *p_dm_void
+)
+{
+}
+
+/*H2C_RSSI_REPORT*/
+static s8 phydm_rssi_report(struct PHY_DM_STRUCT *p_dm_odm, u8 mac_id)
+{
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapter);
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
+ u8 h2c_parameter[H2C_0X42_LENGTH] = {0};
+ u8 UL_DL_STATE = 0, STBC_TX = 0, tx_bf_en = 0;
+ u8 cmdlen = H2C_0X42_LENGTH, first_connect = false;
+ u64 cur_tx_ok_cnt = 0, cur_rx_ok_cnt = 0;
+ struct sta_info *p_entry = p_dm_odm->p_odm_sta_info[mac_id];
+
+ if (!IS_STA_VALID(p_entry))
+ return _FAIL;
+
+ if (mac_id != p_entry->mac_id) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("%s mac_id:%u:%u invalid\n", __func__, mac_id, p_entry->mac_id));
+ rtw_warn_on(1);
+ return _FAIL;
+ }
+
+ if (IS_MCAST(p_entry->hwaddr)) /*if(psta->mac_id ==1)*/
+ return _FAIL;
+
+ if (p_entry->rssi_stat.undecorated_smoothed_pwdb == (-1)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("%s mac_id:%u, mac:"MAC_FMT", rssi == -1\n", __func__, p_entry->mac_id, MAC_ARG(p_entry->hwaddr)));
+ return _FAIL;
+ }
+
+ cur_tx_ok_cnt = pdvobjpriv->traffic_stat.cur_tx_bytes;
+ cur_rx_ok_cnt = pdvobjpriv->traffic_stat.cur_rx_bytes;
+ if (cur_rx_ok_cnt > (cur_tx_ok_cnt * 6))
+ UL_DL_STATE = 1;
+ else
+ UL_DL_STATE = 0;
+
+#ifdef CONFIG_BEAMFORMING
+ {
+#if (BEAMFORMING_SUPPORT == 1)
+ enum beamforming_cap beamform_cap = phydm_beamforming_get_entry_beam_cap_by_mac_id(p_dm_odm, p_entry->mac_id);
+#else/*for drv beamforming*/
+ enum beamforming_cap beamform_cap = beamforming_get_entry_beam_cap_by_mac_id(&adapter->mlmepriv, p_entry->mac_id);
+#endif
+
+ if (beamform_cap & (BEAMFORMER_CAP_HT_EXPLICIT | BEAMFORMER_CAP_VHT_SU))
+ tx_bf_en = 1;
+ else
+ tx_bf_en = 0;
+ }
+#endif /*#ifdef CONFIG_BEAMFORMING*/
+
+ if (tx_bf_en)
+ STBC_TX = 0;
+ else
+ STBC_TX = TEST_FLAG(p_entry->htpriv.stbc_cap, STBC_HT_ENABLE_TX);
+
+ h2c_parameter[0] = (u8)(p_entry->mac_id & 0xFF);
+ h2c_parameter[2] = p_entry->rssi_stat.undecorated_smoothed_pwdb & 0x7F;
+
+ if (UL_DL_STATE)
+ h2c_parameter[3] |= RAINFO_BE_RX_STATE;
+
+ if (tx_bf_en)
+ h2c_parameter[3] |= RAINFO_BF_STATE;
+ if (STBC_TX)
+ h2c_parameter[3] |= RAINFO_STBC_STATE;
+ if (p_dm_odm->noisy_decision)
+ h2c_parameter[3] |= RAINFO_NOISY_STATE;
+
+ if ((p_entry->ra_rpt_linked == false) && (p_entry->rssi_stat.is_send_rssi == RA_RSSI_STATE_SEND)) {
+ h2c_parameter[3] |= RAINFO_INIT_RSSI_RATE_STATE;
+ p_entry->ra_rpt_linked = true;
+ p_entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_HOLD;
+ first_connect = true;
+ }
+
+ h2c_parameter[4] = (p_ra_table->RA_threshold_offset & 0x7f) | (p_ra_table->RA_offset_direction << 7);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("RA_threshold_offset = (( %s%d ))\n", ((p_ra_table->RA_threshold_offset == 0) ? " " : ((p_ra_table->RA_offset_direction) ? "+" : "-")), p_ra_table->RA_threshold_offset));
+
+ if (first_connect) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("%s mac_id:%u, mac:"MAC_FMT", rssi:%d\n", __func__,
+ p_entry->mac_id, MAC_ARG(p_entry->hwaddr), p_entry->rssi_stat.undecorated_smoothed_pwdb));
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("%s RAINFO - TP:%s, TxBF:%s, STBC:%s, Noisy:%s, Firstcont:%s\n", __func__,
+ (UL_DL_STATE) ? "DL" : "UL", (tx_bf_en) ? "EN" : "DIS", (STBC_TX) ? "EN" : "DIS",
+ (p_dm_odm->noisy_decision) ? "True" : "False", (first_connect) ? "True" : "False"));
+ }
+
+ if (p_hal_data->fw_ractrl == true) {
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E)
+ cmdlen = 3;
+ odm_fill_h2c_cmd(p_dm_odm, ODM_H2C_RSSI_REPORT, cmdlen, h2c_parameter);
+ } else {
+#if ((RATE_ADAPTIVE_SUPPORT == 1))
+ if (p_dm_odm->support_ic_type == ODM_RTL8188E)
+ odm_ra_set_rssi_8188e(p_dm_odm, (u8)(p_entry->mac_id & 0xFF), p_entry->rssi_stat.undecorated_smoothed_pwdb & 0x7F);
+#endif
+ }
+ return _SUCCESS;
+}
+
+static void phydm_ra_rssi_rpt_wk_hdl(void *p_context)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_context;
+ int i;
+ u8 mac_id = 0xFF;
+ struct sta_info *p_entry = NULL;
+
+ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
+ p_entry = p_dm_odm->p_odm_sta_info[i];
+ if (IS_STA_VALID(p_entry)) {
+ if (IS_MCAST(p_entry->hwaddr)) /*if(psta->mac_id ==1)*/
+ continue;
+ if (p_entry->ra_rpt_linked == false) {
+ mac_id = i;
+ break;
+ }
+ }
+ }
+ if (mac_id != 0xFF)
+ phydm_rssi_report(p_dm_odm, mac_id);
+}
+void phydm_ra_rssi_rpt_wk(void *p_context)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_context;
+
+ rtw_run_in_thread_cmd(p_dm_odm->adapter, phydm_ra_rssi_rpt_wk_hdl, p_dm_odm);
+}
+
+static void
+odm_rssi_monitor_check_ce(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ADAPTER *adapter = p_dm_odm->adapter;
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
+ struct sta_info *p_entry;
+ int i;
+ int tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
+ u8 sta_cnt = 0;
+
+ if (p_dm_odm->is_linked != true)
+ return;
+
+ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
+ p_entry = p_dm_odm->p_odm_sta_info[i];
+ if (IS_STA_VALID(p_entry)) {
+ if (IS_MCAST(p_entry->hwaddr)) /*if(psta->mac_id ==1)*/
+ continue;
+
+ if (p_entry->rssi_stat.undecorated_smoothed_pwdb == (-1))
+ continue;
+
+ if (p_entry->rssi_stat.undecorated_smoothed_pwdb < tmp_entry_min_pwdb)
+ tmp_entry_min_pwdb = p_entry->rssi_stat.undecorated_smoothed_pwdb;
+
+ if (p_entry->rssi_stat.undecorated_smoothed_pwdb > tmp_entry_max_pwdb)
+ tmp_entry_max_pwdb = p_entry->rssi_stat.undecorated_smoothed_pwdb;
+
+ if (phydm_rssi_report(p_dm_odm, i))
+ sta_cnt++;
+ }
+ }
+
+ if (tmp_entry_max_pwdb != 0) /* If associated entry is found */
+ p_hal_data->entry_max_undecorated_smoothed_pwdb = tmp_entry_max_pwdb;
+ else
+ p_hal_data->entry_max_undecorated_smoothed_pwdb = 0;
+
+ if (tmp_entry_min_pwdb != 0xff) /* If associated entry is found */
+ p_hal_data->entry_min_undecorated_smoothed_pwdb = tmp_entry_min_pwdb;
+ else
+ p_hal_data->entry_min_undecorated_smoothed_pwdb = 0;
+
+ find_minimum_rssi(adapter);/* get pdmpriv->min_undecorated_pwdb_for_dm */
+
+ p_dm_odm->rssi_min = p_hal_data->min_undecorated_pwdb_for_dm;
+ /* odm_cmn_info_update(&p_hal_data->odmpriv,ODM_CMNINFO_RSSI_MIN, pdmpriv->min_undecorated_pwdb_for_dm); */
+}
+
+static void
+odm_rssi_monitor_check_ap(
+ void *p_dm_void
+)
+{
+}
+
+void
+odm_rssi_monitor_check(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_RSSI_MONITOR))
+ return;
+
+ switch (p_dm_odm->support_platform) {
+ case ODM_WIN:
+ odm_rssi_monitor_check_mp(p_dm_odm);
+ break;
+
+ case ODM_CE:
+ odm_rssi_monitor_check_ce(p_dm_odm);
+ break;
+
+ case ODM_AP:
+ odm_rssi_monitor_check_ap(p_dm_odm);
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+void
+odm_rate_adaptive_mask_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ODM_RATE_ADAPTIVE *p_odm_ra = &p_dm_odm->rate_adaptive;
+
+ p_odm_ra->type = dm_type_by_driver;
+ if (p_odm_ra->type == dm_type_by_driver)
+ p_dm_odm->is_use_ra_mask = true;
+ else
+ p_dm_odm->is_use_ra_mask = false;
+
+ p_odm_ra->ratr_state = DM_RATR_STA_INIT;
+
+ p_odm_ra->ldpc_thres = 35;
+ p_odm_ra->is_use_ldpc = false;
+
+ p_odm_ra->high_rssi_thresh = 50;
+ p_odm_ra->low_rssi_thresh = 20;
+}
+/*-----------------------------------------------------------------------------
+ * Function: odm_refresh_rate_adaptive_mask()
+ *
+ * Overview: Update rate table mask according to rssi
+ *
+ * Input: NONE
+ *
+ * Output: NONE
+ *
+ * Return: NONE
+ *
+ * Revised History:
+ * When Who Remark
+ * 05/27/2009 hpfan Create version 0.
+ *
+ *---------------------------------------------------------------------------*/
+void
+odm_refresh_rate_adaptive_mask(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+
+ if (!p_dm_odm->is_linked)
+ return;
+
+ if (!(p_dm_odm->support_ability & ODM_BB_RA_MASK)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_TRACE, ("odm_refresh_rate_adaptive_mask(): Return cos not supported\n"));
+ return;
+ }
+
+ p_ra_table->force_update_ra_mask_count++;
+ /* */
+ /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */
+ /* at the same time. In the stage2/3, we need to prive universal interface and merge all */
+ /* HW dynamic mechanism. */
+ /* */
+ switch (p_dm_odm->support_platform) {
+ case ODM_WIN:
+ odm_refresh_rate_adaptive_mask_mp(p_dm_odm);
+ break;
+
+ case ODM_CE:
+ odm_refresh_rate_adaptive_mask_ce(p_dm_odm);
+ break;
+
+ case ODM_AP:
+ odm_refresh_rate_adaptive_mask_apadsl(p_dm_odm);
+ break;
+ }
+
+}
+
+static u8
+phydm_trans_platform_bw(
+ void *p_dm_void,
+ u8 BW
+)
+{
+ if (BW == CHANNEL_WIDTH_20)
+ BW = PHYDM_BW_20;
+
+ else if (BW == CHANNEL_WIDTH_40)
+ BW = PHYDM_BW_40;
+
+ else if (BW == CHANNEL_WIDTH_80)
+ BW = PHYDM_BW_80;
+
+ else if (BW == CHANNEL_WIDTH_160)
+ BW = PHYDM_BW_160;
+
+ else if (BW == CHANNEL_WIDTH_80_80)
+ BW = PHYDM_BW_80_80;
+
+ return BW;
+}
+
+static u8
+phydm_trans_platform_rf_type(
+ void *p_dm_void,
+ u8 rf_type
+)
+{
+ if (rf_type == RF_1T2R)
+ rf_type = PHYDM_RF_1T2R;
+
+ else if (rf_type == RF_2T4R)
+ rf_type = PHYDM_RF_2T4R;
+
+ else if (rf_type == RF_2T2R)
+ rf_type = PHYDM_RF_2T2R;
+
+ else if (rf_type == RF_1T1R)
+ rf_type = PHYDM_RF_1T1R;
+
+ else if (rf_type == RF_2T2R_GREEN)
+ rf_type = PHYDM_RF_2T2R_GREEN;
+
+ else if (rf_type == RF_3T3R)
+ rf_type = PHYDM_RF_3T3R;
+
+ else if (rf_type == RF_4T4R)
+ rf_type = PHYDM_RF_4T4R;
+
+ else if (rf_type == RF_2T3R)
+ rf_type = PHYDM_RF_1T2R;
+
+ else if (rf_type == RF_3T4R)
+ rf_type = PHYDM_RF_3T4R;
+
+ return rf_type;
+}
+
+static u32
+phydm_trans_platform_wireless_mode(
+ void *p_dm_void,
+ u32 wireless_mode
+)
+{
+ if (wireless_mode == WIRELESS_11A)
+ wireless_mode = PHYDM_WIRELESS_MODE_A;
+
+ else if (wireless_mode == WIRELESS_11B)
+ wireless_mode = PHYDM_WIRELESS_MODE_B;
+
+ else if ((wireless_mode == WIRELESS_11G) || (wireless_mode == WIRELESS_11BG))
+ wireless_mode = PHYDM_WIRELESS_MODE_G;
+
+ else if (wireless_mode == WIRELESS_AUTO)
+ wireless_mode = PHYDM_WIRELESS_MODE_AUTO;
+
+ else if ((wireless_mode == WIRELESS_11_24N) ||
+ (wireless_mode == WIRELESS_11G_24N) ||
+ (wireless_mode == WIRELESS_11B_24N) ||
+ (wireless_mode == WIRELESS_11BG_24N) ||
+ (wireless_mode == WIRELESS_MODE_24G) ||
+ (wireless_mode == WIRELESS_11ABGN) ||
+ (wireless_mode == WIRELESS_11AGN))
+ wireless_mode = PHYDM_WIRELESS_MODE_N_24G;
+
+ else if ((wireless_mode == WIRELESS_11_5N) || (wireless_mode == WIRELESS_11A_5N))
+ wireless_mode = PHYDM_WIRELESS_MODE_N_5G;
+
+ else if ((wireless_mode == WIRELESS_11AC) || (wireless_mode == WIRELESS_11_5AC) || (wireless_mode == WIRELESS_MODE_5G))
+ wireless_mode = PHYDM_WIRELESS_MODE_AC_5G;
+
+ else if (wireless_mode == WIRELESS_11_24AC)
+ wireless_mode = PHYDM_WIRELESS_MODE_AC_24G;
+
+ else if (wireless_mode == WIRELESS_11AC)
+ wireless_mode = PHYDM_WIRELESS_MODE_AC_ONLY;
+
+ else if (wireless_mode == WIRELESS_MODE_MAX)
+ wireless_mode = PHYDM_WIRELESS_MODE_MAX;
+ else
+ wireless_mode = PHYDM_WIRELESS_MODE_UNKNOWN;
+
+ return wireless_mode;
+}
+
+u8
+phydm_vht_en_mapping(
+ void *p_dm_void,
+ u32 wireless_mode
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 vht_en_out = 0;
+
+ if ((wireless_mode == PHYDM_WIRELESS_MODE_AC_5G) ||
+ (wireless_mode == PHYDM_WIRELESS_MODE_AC_24G) ||
+ (wireless_mode == PHYDM_WIRELESS_MODE_AC_ONLY)
+ ) {
+ vht_en_out = 1;
+ /**/
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("wireless_mode= (( 0x%x )), VHT_EN= (( %d ))\n", wireless_mode, vht_en_out));
+ return vht_en_out;
+}
+
+u8
+phydm_rate_id_mapping(
+ void *p_dm_void,
+ u32 wireless_mode,
+ u8 rf_type,
+ u8 bw
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 rate_id_idx = 0;
+ u8 phydm_BW;
+ u8 phydm_rf_type;
+
+ phydm_BW = phydm_trans_platform_bw(p_dm_odm, bw);
+ phydm_rf_type = phydm_trans_platform_rf_type(p_dm_odm, rf_type);
+ wireless_mode = phydm_trans_platform_wireless_mode(p_dm_odm, wireless_mode);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("wireless_mode= (( 0x%x )), rf_type = (( 0x%x )), BW = (( 0x%x ))\n",
+ wireless_mode, phydm_rf_type, phydm_BW));
+
+
+ switch (wireless_mode) {
+
+ case PHYDM_WIRELESS_MODE_N_24G:
+ {
+
+ if (phydm_BW == PHYDM_BW_40) {
+
+ if (phydm_rf_type == PHYDM_RF_1T1R)
+ rate_id_idx = PHYDM_BGN_40M_1SS;
+ else if (phydm_rf_type == PHYDM_RF_2T2R)
+ rate_id_idx = PHYDM_BGN_40M_2SS;
+ else
+ rate_id_idx = PHYDM_ARFR5_N_3SS;
+
+ } else {
+
+ if (phydm_rf_type == PHYDM_RF_1T1R)
+ rate_id_idx = PHYDM_BGN_20M_1SS;
+ else if (phydm_rf_type == PHYDM_RF_2T2R)
+ rate_id_idx = PHYDM_BGN_20M_2SS;
+ else
+ rate_id_idx = PHYDM_ARFR5_N_3SS;
+ }
+ }
+ break;
+
+ case PHYDM_WIRELESS_MODE_N_5G:
+ {
+ if (phydm_rf_type == PHYDM_RF_1T1R)
+ rate_id_idx = PHYDM_GN_N1SS;
+ else if (phydm_rf_type == PHYDM_RF_2T2R)
+ rate_id_idx = PHYDM_GN_N2SS;
+ else
+ rate_id_idx = PHYDM_ARFR5_N_3SS;
+ }
+
+ break;
+
+ case PHYDM_WIRELESS_MODE_G:
+ rate_id_idx = PHYDM_BG;
+ break;
+
+ case PHYDM_WIRELESS_MODE_A:
+ rate_id_idx = PHYDM_G;
+ break;
+
+ case PHYDM_WIRELESS_MODE_B:
+ rate_id_idx = PHYDM_B_20M;
+ break;
+
+
+ case PHYDM_WIRELESS_MODE_AC_5G:
+ case PHYDM_WIRELESS_MODE_AC_ONLY:
+ {
+ if (phydm_rf_type == PHYDM_RF_1T1R)
+ rate_id_idx = PHYDM_ARFR1_AC_1SS;
+ else if (phydm_rf_type == PHYDM_RF_2T2R)
+ rate_id_idx = PHYDM_ARFR0_AC_2SS;
+ else
+ rate_id_idx = PHYDM_ARFR4_AC_3SS;
+ }
+ break;
+
+ case PHYDM_WIRELESS_MODE_AC_24G:
+ {
+ /*Becareful to set "Lowest rate" while using PHYDM_ARFR4_AC_3SS in 2.4G/5G*/
+ if (phydm_BW >= PHYDM_BW_80) {
+ if (phydm_rf_type == PHYDM_RF_1T1R)
+ rate_id_idx = PHYDM_ARFR1_AC_1SS;
+ else if (phydm_rf_type == PHYDM_RF_2T2R)
+ rate_id_idx = PHYDM_ARFR0_AC_2SS;
+ else
+ rate_id_idx = PHYDM_ARFR4_AC_3SS;
+ } else {
+
+ if (phydm_rf_type == PHYDM_RF_1T1R)
+ rate_id_idx = PHYDM_ARFR2_AC_2G_1SS;
+ else if (phydm_rf_type == PHYDM_RF_2T2R)
+ rate_id_idx = PHYDM_ARFR3_AC_2G_2SS;
+ else
+ rate_id_idx = PHYDM_ARFR4_AC_3SS;
+ }
+ }
+ break;
+
+ default:
+ rate_id_idx = 0;
+ break;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("RA rate ID = (( 0x%x ))\n", rate_id_idx));
+
+ return rate_id_idx;
+}
+
+void
+phydm_update_hal_ra_mask(
+ void *p_dm_void,
+ u32 wireless_mode,
+ u8 rf_type,
+ u8 BW,
+ u8 mimo_ps_enable,
+ u8 disable_cck_rate,
+ u32 *ratr_bitmap_msb_in,
+ u32 *ratr_bitmap_lsb_in,
+ u8 tx_rate_level
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u32 mask_rate_threshold;
+ u8 phydm_rf_type;
+ u8 phydm_BW;
+ u32 ratr_bitmap = *ratr_bitmap_lsb_in, ratr_bitmap_msb = *ratr_bitmap_msb_in;
+
+ wireless_mode = phydm_trans_platform_wireless_mode(p_dm_odm, wireless_mode);
+
+ phydm_rf_type = phydm_trans_platform_rf_type(p_dm_odm, rf_type);
+ phydm_BW = phydm_trans_platform_bw(p_dm_odm, BW);
+
+ /*ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("phydm_rf_type = (( %x )), rf_type = (( %x ))\n", phydm_rf_type, rf_type));*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("Platfoem original RA Mask = (( 0x %x | %x ))\n", ratr_bitmap_msb, ratr_bitmap));
+
+ switch (wireless_mode) {
+
+ case PHYDM_WIRELESS_MODE_B:
+ {
+ ratr_bitmap &= 0x0000000f;
+ }
+ break;
+
+ case PHYDM_WIRELESS_MODE_G:
+ {
+ ratr_bitmap &= 0x00000ff5;
+ }
+ break;
+
+ case PHYDM_WIRELESS_MODE_A:
+ {
+ ratr_bitmap &= 0x00000ff0;
+ }
+ break;
+
+ case PHYDM_WIRELESS_MODE_N_24G:
+ case PHYDM_WIRELESS_MODE_N_5G:
+ {
+ if (mimo_ps_enable)
+ phydm_rf_type = PHYDM_RF_1T1R;
+
+ if (phydm_rf_type == PHYDM_RF_1T1R) {
+
+ if (phydm_BW == PHYDM_BW_40)
+ ratr_bitmap &= 0x000ff015;
+ else
+ ratr_bitmap &= 0x000ff005;
+ } else if (phydm_rf_type == PHYDM_RF_2T2R || phydm_rf_type == PHYDM_RF_2T4R || phydm_rf_type == PHYDM_RF_2T3R) {
+
+ if (phydm_BW == PHYDM_BW_40)
+ ratr_bitmap &= 0x0ffff015;
+ else
+ ratr_bitmap &= 0x0ffff005;
+ } else { /*3T*/
+
+ ratr_bitmap &= 0xfffff015;
+ ratr_bitmap_msb &= 0xf;
+ }
+ }
+ break;
+
+ case PHYDM_WIRELESS_MODE_AC_24G:
+ {
+ if (phydm_rf_type == PHYDM_RF_1T1R)
+ ratr_bitmap &= 0x003ff015;
+ else if (phydm_rf_type == PHYDM_RF_2T2R || phydm_rf_type == PHYDM_RF_2T4R || phydm_rf_type == PHYDM_RF_2T3R)
+ ratr_bitmap &= 0xfffff015;
+ else {/*3T*/
+
+ ratr_bitmap &= 0xfffff010;
+ ratr_bitmap_msb &= 0x3ff;
+ }
+
+ if (phydm_BW == PHYDM_BW_20) {/* AC 20MHz doesn't support MCS9 */
+ ratr_bitmap &= 0x7fdfffff;
+ ratr_bitmap_msb &= 0x1ff;
+ }
+ }
+ break;
+
+ case PHYDM_WIRELESS_MODE_AC_5G:
+ {
+ if (phydm_rf_type == PHYDM_RF_1T1R)
+ ratr_bitmap &= 0x003ff010;
+ else if (phydm_rf_type == PHYDM_RF_2T2R || phydm_rf_type == PHYDM_RF_2T4R || phydm_rf_type == PHYDM_RF_2T3R)
+ ratr_bitmap &= 0xfffff010;
+ else {/*3T*/
+
+ ratr_bitmap &= 0xfffff010;
+ ratr_bitmap_msb &= 0x3ff;
+ }
+
+ if (phydm_BW == PHYDM_BW_20) {/* AC 20MHz doesn't support MCS9 */
+ ratr_bitmap &= 0x7fdfffff;
+ ratr_bitmap_msb &= 0x1ff;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (wireless_mode != PHYDM_WIRELESS_MODE_B) {
+
+ if (tx_rate_level == 0)
+ ratr_bitmap &= 0xffffffff;
+ else if (tx_rate_level == 1)
+ ratr_bitmap &= 0xfffffff0;
+ else if (tx_rate_level == 2)
+ ratr_bitmap &= 0xffffefe0;
+ else if (tx_rate_level == 3)
+ ratr_bitmap &= 0xffffcfc0;
+ else if (tx_rate_level == 4)
+ ratr_bitmap &= 0xffff8f80;
+ else if (tx_rate_level >= 5)
+ ratr_bitmap &= 0xffff0f00;
+
+ }
+
+ if (disable_cck_rate)
+ ratr_bitmap &= 0xfffffff0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("wireless_mode= (( 0x%x )), rf_type = (( 0x%x )), BW = (( 0x%x )), MimoPs_en = (( %d )), tx_rate_level= (( 0x%x ))\n",
+ wireless_mode, phydm_rf_type, phydm_BW, mimo_ps_enable, tx_rate_level));
+
+ /*ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("111 Phydm modified RA Mask = (( 0x %x | %x ))\n", ratr_bitmap_msb, ratr_bitmap));*/
+
+ *ratr_bitmap_lsb_in = ratr_bitmap;
+ *ratr_bitmap_msb_in = ratr_bitmap_msb;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("Phydm modified RA Mask = (( 0x %x | %x ))\n", *ratr_bitmap_msb_in, *ratr_bitmap_lsb_in));
+
+}
+
+u8
+phydm_RA_level_decision(
+ void *p_dm_void,
+ u32 rssi,
+ u8 ratr_state
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 ra_lowest_rate;
+ u8 ra_rate_floor_table[RA_FLOOR_TABLE_SIZE] = {20, 34, 38, 42, 46, 50, 100}; /*MCS0 ~ MCS4 , VHT1SS MCS0 ~ MCS4 , G 6M~24M*/
+ u8 new_ratr_state = 0;
+ u8 i;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("curr RA level = ((%d)), Rate_floor_table ori [ %d , %d, %d , %d, %d, %d]\n", ratr_state,
+ ra_rate_floor_table[0], ra_rate_floor_table[1], ra_rate_floor_table[2], ra_rate_floor_table[3], ra_rate_floor_table[4], ra_rate_floor_table[5]));
+
+ for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) {
+
+ if (i >= (ratr_state))
+ ra_rate_floor_table[i] += RA_FLOOR_UP_GAP;
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("RSSI = ((%d)), Rate_floor_table_mod [ %d , %d, %d , %d, %d, %d]\n",
+ rssi, ra_rate_floor_table[0], ra_rate_floor_table[1], ra_rate_floor_table[2], ra_rate_floor_table[3], ra_rate_floor_table[4], ra_rate_floor_table[5]));
+
+ for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) {
+
+ if (rssi < ra_rate_floor_table[i]) {
+ new_ratr_state = i;
+ break;
+ }
+ }
+
+
+
+ return new_ratr_state;
+
+}
+
+void
+odm_refresh_rate_adaptive_mask_mp(
+ void *p_dm_void
+)
+{
+}
+
+void
+odm_refresh_rate_adaptive_mask_ce(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ struct _ADAPTER *p_adapter = p_dm_odm->adapter;
+ struct _ODM_RATE_ADAPTIVE *p_ra = &p_dm_odm->rate_adaptive;
+ u32 i;
+ struct sta_info *p_entry;
+ u8 ratr_state_new;
+
+ if (RTW_CANNOT_RUN(p_adapter)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_TRACE, ("<---- odm_refresh_rate_adaptive_mask(): driver is going to unload\n"));
+ return;
+ }
+
+ if (!p_dm_odm->is_use_ra_mask) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("<---- odm_refresh_rate_adaptive_mask(): driver does not control rate adaptive mask\n"));
+ return;
+ }
+
+ for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
+
+ p_entry = p_dm_odm->p_odm_sta_info[i];
+
+ if (IS_STA_VALID(p_entry)) {
+
+ if (IS_MCAST(p_entry->hwaddr))
+ continue;
+
+#if ((RTL8812A_SUPPORT == 1) || (RTL8821A_SUPPORT == 1))
+ if ((p_dm_odm->support_ic_type == ODM_RTL8812) || (p_dm_odm->support_ic_type == ODM_RTL8821)) {
+ if (p_entry->rssi_stat.undecorated_smoothed_pwdb < p_ra->ldpc_thres) {
+ p_ra->is_use_ldpc = true;
+ p_ra->is_lower_rts_rate = true;
+ if ((p_dm_odm->support_ic_type == ODM_RTL8821) && (p_dm_odm->cut_version == ODM_CUT_A))
+ set_ra_ldpc_8812(p_entry, true);
+ /* dbg_print("RSSI=%d, is_use_ldpc = true\n", p_hal_data->undecorated_smoothed_pwdb); */
+ } else if (p_entry->rssi_stat.undecorated_smoothed_pwdb > (p_ra->ldpc_thres - 5)) {
+ p_ra->is_use_ldpc = false;
+ p_ra->is_lower_rts_rate = false;
+ if ((p_dm_odm->support_ic_type == ODM_RTL8821) && (p_dm_odm->cut_version == ODM_CUT_A))
+ set_ra_ldpc_8812(p_entry, false);
+ /* dbg_print("RSSI=%d, is_use_ldpc = false\n", p_hal_data->undecorated_smoothed_pwdb); */
+ }
+ }
+#endif
+
+#if RA_MASK_PHYDMLIZE_CE
+ ratr_state_new = phydm_RA_level_decision(p_dm_odm, p_entry->rssi_stat.undecorated_smoothed_pwdb, p_entry->rssi_level);
+
+ if ((p_entry->rssi_level != ratr_state_new) || (p_ra_table->force_update_ra_mask_count >= FORCED_UPDATE_RAMASK_PERIOD)) {
+
+ p_ra_table->force_update_ra_mask_count = 0;
+ /*ODM_PRINT_ADDR(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("Target AP addr :"), pstat->hwaddr);*/
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("Update Tx RA Level: ((%x)) -> ((%x)), RSSI = ((%d))\n",
+ p_entry->rssi_level, ratr_state_new, p_entry->rssi_stat.undecorated_smoothed_pwdb));
+
+ p_entry->rssi_level = ratr_state_new;
+ rtw_hal_update_ra_mask(p_entry, p_entry->rssi_level, false);
+ } else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("Stay in RA level = (( %d ))\n\n", ratr_state_new));
+ /**/
+ }
+#else
+ if (odm_ra_state_check(p_dm_odm, p_entry->rssi_stat.undecorated_smoothed_pwdb, false, &p_entry->rssi_level)) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("RSSI:%d, RSSI_LEVEL:%d\n", p_entry->rssi_stat.undecorated_smoothed_pwdb, p_entry->rssi_level));
+ /* printk("RSSI:%d, RSSI_LEVEL:%d\n", pstat->rssi_stat.undecorated_smoothed_pwdb, pstat->rssi_level); */
+ rtw_hal_update_ra_mask(p_entry, p_entry->rssi_level, false);
+ } else if (p_dm_odm->is_change_state) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("Change Power Training state, is_disable_power_training = %d\n", p_dm_odm->is_disable_power_training));
+ rtw_hal_update_ra_mask(p_entry, p_entry->rssi_level, false);
+ }
+#endif
+
+ }
+ }
+}
+
+void
+odm_refresh_rate_adaptive_mask_apadsl(
+ void *p_dm_void
+)
+{
+}
+
+void
+odm_refresh_basic_rate_mask(
+ void *p_dm_void
+)
+{
+}
+
+u8
+phydm_rate_order_compute(
+ void *p_dm_void,
+ u8 rate_idx
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 rate_order = 0;
+
+ if (rate_idx >= ODM_RATEVHTSS4MCS0) {
+
+ rate_idx -= ODM_RATEVHTSS4MCS0;
+ /**/
+ } else if (rate_idx >= ODM_RATEVHTSS3MCS0) {
+
+ rate_idx -= ODM_RATEVHTSS3MCS0;
+ /**/
+ } else if (rate_idx >= ODM_RATEVHTSS2MCS0) {
+
+ rate_idx -= ODM_RATEVHTSS2MCS0;
+ /**/
+ } else if (rate_idx >= ODM_RATEVHTSS1MCS0) {
+
+ rate_idx -= ODM_RATEVHTSS1MCS0;
+ /**/
+ } else if (rate_idx >= ODM_RATEMCS24) {
+
+ rate_idx -= ODM_RATEMCS24;
+ /**/
+ } else if (rate_idx >= ODM_RATEMCS16) {
+
+ rate_idx -= ODM_RATEMCS16;
+ /**/
+ } else if (rate_idx >= ODM_RATEMCS8) {
+
+ rate_idx -= ODM_RATEMCS8;
+ /**/
+ }
+ rate_order = rate_idx;
+
+ return rate_order;
+
+}
+
+static void
+phydm_ra_common_info_update(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+ u16 macid;
+ u8 rate_order_tmp;
+ u8 cnt = 0;
+
+ p_ra_table->highest_client_tx_order = 0;
+ p_ra_table->power_tracking_flag = 1;
+
+ if (p_dm_odm->number_linked_client != 0) {
+ for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++) {
+
+ rate_order_tmp = phydm_rate_order_compute(p_dm_odm, ((p_ra_table->link_tx_rate[macid]) & 0x7f));
+
+ if (rate_order_tmp >= (p_ra_table->highest_client_tx_order)) {
+ p_ra_table->highest_client_tx_order = rate_order_tmp;
+ p_ra_table->highest_client_tx_rate_order = macid;
+ }
+
+ cnt++;
+
+ if (cnt == p_dm_odm->number_linked_client)
+ break;
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("MACID[%d], Highest Tx order Update for power traking: %d\n", (p_ra_table->highest_client_tx_rate_order), (p_ra_table->highest_client_tx_order)));
+ }
+}
+
+void
+phydm_ra_info_watchdog(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ phydm_ra_common_info_update(p_dm_odm);
+ phydm_ra_dynamic_retry_limit(p_dm_odm);
+ phydm_ra_dynamic_retry_count(p_dm_odm);
+ odm_refresh_rate_adaptive_mask(p_dm_odm);
+ odm_refresh_basic_rate_mask(p_dm_odm);
+}
+
+void
+phydm_ra_info_init(
+ void *p_dm_void
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _rate_adaptive_table_ *p_ra_table = &p_dm_odm->dm_ra_table;
+
+ p_ra_table->highest_client_tx_rate_order = 0;
+ p_ra_table->highest_client_tx_order = 0;
+ p_ra_table->RA_threshold_offset = 0;
+ p_ra_table->RA_offset_direction = 0;
+
+#if (defined(CONFIG_RA_DYNAMIC_RTY_LIMIT))
+ phydm_ra_dynamic_retry_limit_init(p_dm_odm);
+#endif
+
+#if (defined(CONFIG_RA_DYNAMIC_RATE_ID))
+ phydm_ra_dynamic_rate_id_init(p_dm_odm);
+#endif
+#if (defined(CONFIG_RA_DBG_CMD))
+ odm_ra_para_adjust_init(p_dm_odm);
+#endif
+
+}
+
+u8
+odm_find_rts_rate(
+ void *p_dm_void,
+ u8 tx_rate,
+ bool is_erp_protect
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 rts_ini_rate = ODM_RATE6M;
+
+ if (is_erp_protect) /* use CCK rate as RTS*/
+ rts_ini_rate = ODM_RATE1M;
+ else {
+ switch (tx_rate) {
+ case ODM_RATEVHTSS3MCS9:
+ case ODM_RATEVHTSS3MCS8:
+ case ODM_RATEVHTSS3MCS7:
+ case ODM_RATEVHTSS3MCS6:
+ case ODM_RATEVHTSS3MCS5:
+ case ODM_RATEVHTSS3MCS4:
+ case ODM_RATEVHTSS3MCS3:
+ case ODM_RATEVHTSS2MCS9:
+ case ODM_RATEVHTSS2MCS8:
+ case ODM_RATEVHTSS2MCS7:
+ case ODM_RATEVHTSS2MCS6:
+ case ODM_RATEVHTSS2MCS5:
+ case ODM_RATEVHTSS2MCS4:
+ case ODM_RATEVHTSS2MCS3:
+ case ODM_RATEVHTSS1MCS9:
+ case ODM_RATEVHTSS1MCS8:
+ case ODM_RATEVHTSS1MCS7:
+ case ODM_RATEVHTSS1MCS6:
+ case ODM_RATEVHTSS1MCS5:
+ case ODM_RATEVHTSS1MCS4:
+ case ODM_RATEVHTSS1MCS3:
+ case ODM_RATEMCS15:
+ case ODM_RATEMCS14:
+ case ODM_RATEMCS13:
+ case ODM_RATEMCS12:
+ case ODM_RATEMCS11:
+ case ODM_RATEMCS7:
+ case ODM_RATEMCS6:
+ case ODM_RATEMCS5:
+ case ODM_RATEMCS4:
+ case ODM_RATEMCS3:
+ case ODM_RATE54M:
+ case ODM_RATE48M:
+ case ODM_RATE36M:
+ case ODM_RATE24M:
+ rts_ini_rate = ODM_RATE24M;
+ break;
+ case ODM_RATEVHTSS3MCS2:
+ case ODM_RATEVHTSS3MCS1:
+ case ODM_RATEVHTSS2MCS2:
+ case ODM_RATEVHTSS2MCS1:
+ case ODM_RATEVHTSS1MCS2:
+ case ODM_RATEVHTSS1MCS1:
+ case ODM_RATEMCS10:
+ case ODM_RATEMCS9:
+ case ODM_RATEMCS2:
+ case ODM_RATEMCS1:
+ case ODM_RATE18M:
+ case ODM_RATE12M:
+ rts_ini_rate = ODM_RATE12M;
+ break;
+ case ODM_RATEVHTSS3MCS0:
+ case ODM_RATEVHTSS2MCS0:
+ case ODM_RATEVHTSS1MCS0:
+ case ODM_RATEMCS8:
+ case ODM_RATEMCS0:
+ case ODM_RATE9M:
+ case ODM_RATE6M:
+ rts_ini_rate = ODM_RATE6M;
+ break;
+ case ODM_RATE11M:
+ case ODM_RATE5_5M:
+ case ODM_RATE2M:
+ case ODM_RATE1M:
+ rts_ini_rate = ODM_RATE1M;
+ break;
+ default:
+ rts_ini_rate = ODM_RATE6M;
+ break;
+ }
+ }
+
+ if (*p_dm_odm->p_band_type == 1) {
+ if (rts_ini_rate < ODM_RATE6M)
+ rts_ini_rate = ODM_RATE6M;
+ }
+ return rts_ini_rate;
+
+}
+
+static void
+odm_set_ra_dm_arfb_by_noisy(
+ struct PHY_DM_STRUCT *p_dm_odm
+)
+{
+}
+
+void
+odm_update_noisy_state(
+ void *p_dm_void,
+ bool is_noisy_state_from_c2h
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+
+ if (p_dm_odm->support_ic_type == ODM_RTL8821 || p_dm_odm->support_ic_type == ODM_RTL8812 ||
+ p_dm_odm->support_ic_type == ODM_RTL8723B || p_dm_odm->support_ic_type == ODM_RTL8192E || p_dm_odm->support_ic_type == ODM_RTL8188E || p_dm_odm->support_ic_type == ODM_RTL8723D)
+ p_dm_odm->is_noisy_state = is_noisy_state_from_c2h;
+ odm_set_ra_dm_arfb_by_noisy(p_dm_odm);
+};
+
+void
+phydm_update_pwr_track(
+ void *p_dm_void,
+ u8 rate
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ u8 path_idx = 0;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("Pwr Track Get rate=0x%x\n", rate));
+
+ p_dm_odm->tx_rate = rate;
+}
+
+
+static void
+find_minimum_rssi(
+ struct _ADAPTER *p_adapter
+)
+{
+ HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &(p_hal_data->odmpriv);
+
+ /*Determine the minimum RSSI*/
+
+ if ((p_dm_odm->is_linked != true) &&
+ (p_hal_data->entry_min_undecorated_smoothed_pwdb == 0)) {
+ p_hal_data->min_undecorated_pwdb_for_dm = 0;
+ /*ODM_RT_TRACE(p_dm_odm,COMP_BB_POWERSAVING, DBG_LOUD, ("Not connected to any\n"));*/
+ } else
+ p_hal_data->min_undecorated_pwdb_for_dm = p_hal_data->entry_min_undecorated_smoothed_pwdb;
+
+ /*DBG_8192C("%s=>min_undecorated_pwdb_for_dm(%d)\n",__func__,pdmpriv->min_undecorated_pwdb_for_dm);*/
+ /*ODM_RT_TRACE(p_dm_odm,COMP_DIG, DBG_LOUD, ("min_undecorated_pwdb_for_dm =%d\n",p_hal_data->min_undecorated_pwdb_for_dm));*/
+}
+
+u64
+phydm_get_rate_bitmap_ex(
+ void *p_dm_void,
+ u32 macid,
+ u64 ra_mask,
+ u8 rssi_level,
+ u64 *dm_ra_mask,
+ u8 *dm_rte_id
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct sta_info *p_entry;
+ u64 rate_bitmap = 0;
+ u8 wireless_mode;
+
+ p_entry = p_dm_odm->p_odm_sta_info[macid];
+ if (!IS_STA_VALID(p_entry))
+ return ra_mask;
+ wireless_mode = p_entry->wireless_mode;
+ switch (wireless_mode) {
+ case ODM_WM_B:
+ if (ra_mask & 0x000000000000000c) /* 11M or 5.5M enable */
+ rate_bitmap = 0x000000000000000d;
+ else
+ rate_bitmap = 0x000000000000000f;
+ break;
+
+ case (ODM_WM_G):
+ case (ODM_WM_A):
+ if (rssi_level == DM_RATR_STA_HIGH)
+ rate_bitmap = 0x0000000000000f00;
+ else
+ rate_bitmap = 0x0000000000000ff0;
+ break;
+
+ case (ODM_WM_B|ODM_WM_G):
+ if (rssi_level == DM_RATR_STA_HIGH)
+ rate_bitmap = 0x0000000000000f00;
+ else if (rssi_level == DM_RATR_STA_MIDDLE)
+ rate_bitmap = 0x0000000000000ff0;
+ else
+ rate_bitmap = 0x0000000000000ff5;
+ break;
+
+ case (ODM_WM_B|ODM_WM_G|ODM_WM_N24G):
+ case (ODM_WM_B|ODM_WM_N24G):
+ case (ODM_WM_G|ODM_WM_N24G):
+ case (ODM_WM_A|ODM_WM_N5G):
+ {
+ if (p_dm_odm->rf_type == ODM_1T2R || p_dm_odm->rf_type == ODM_1T1R) {
+ if (rssi_level == DM_RATR_STA_HIGH)
+ rate_bitmap = 0x00000000000f0000;
+ else if (rssi_level == DM_RATR_STA_MIDDLE)
+ rate_bitmap = 0x00000000000ff000;
+ else {
+ if (*(p_dm_odm->p_band_width) == ODM_BW40M)
+ rate_bitmap = 0x00000000000ff015;
+ else
+ rate_bitmap = 0x00000000000ff005;
+ }
+ } else if (p_dm_odm->rf_type == ODM_2T2R || p_dm_odm->rf_type == ODM_2T3R || p_dm_odm->rf_type == ODM_2T4R) {
+ if (rssi_level == DM_RATR_STA_HIGH)
+ rate_bitmap = 0x000000000f8f0000;
+ else if (rssi_level == DM_RATR_STA_MIDDLE)
+ rate_bitmap = 0x000000000f8ff000;
+ else {
+ if (*(p_dm_odm->p_band_width) == ODM_BW40M)
+ rate_bitmap = 0x000000000f8ff015;
+ else
+ rate_bitmap = 0x000000000f8ff005;
+ }
+ } else {
+ if (rssi_level == DM_RATR_STA_HIGH)
+ rate_bitmap = 0x0000000f0f0f0000L;
+ else if (rssi_level == DM_RATR_STA_MIDDLE)
+ rate_bitmap = 0x0000000fcfcfe000L;
+ else {
+ if (*(p_dm_odm->p_band_width) == ODM_BW40M)
+ rate_bitmap = 0x0000000ffffff015L;
+ else
+ rate_bitmap = 0x0000000ffffff005L;
+ }
+ }
+ }
+ break;
+
+ case (ODM_WM_AC|ODM_WM_G):
+ if (rssi_level == 1)
+ rate_bitmap = 0x00000000fc3f0000L;
+ else if (rssi_level == 2)
+ rate_bitmap = 0x00000000fffff000L;
+ else
+ rate_bitmap = 0x00000000ffffffffL;
+ break;
+
+ case (ODM_WM_AC|ODM_WM_A):
+
+ if (p_dm_odm->rf_type == ODM_1T2R || p_dm_odm->rf_type == ODM_1T1R) {
+ if (rssi_level == 1) /* add by Gary for ac-series */
+ rate_bitmap = 0x00000000003f8000L;
+ else if (rssi_level == 2)
+ rate_bitmap = 0x00000000003fe000L;
+ else
+ rate_bitmap = 0x00000000003ff010L;
+ } else if (p_dm_odm->rf_type == ODM_2T2R || p_dm_odm->rf_type == ODM_2T3R || p_dm_odm->rf_type == ODM_2T4R) {
+ if (rssi_level == 1) /* add by Gary for ac-series */
+ rate_bitmap = 0x00000000fe3f8000L; /* VHT 2SS MCS3~9 */
+ else if (rssi_level == 2)
+ rate_bitmap = 0x00000000fffff000L; /* VHT 2SS MCS0~9 */
+ else
+ rate_bitmap = 0x00000000fffff010L; /* All */
+ } else {
+ if (rssi_level == 1) /* add by Gary for ac-series */
+ rate_bitmap = 0x000003f8fe3f8000ULL; /* VHT 3SS MCS3~9 */
+ else if (rssi_level == 2)
+ rate_bitmap = 0x000003fffffff000ULL; /* VHT3SS MCS0~9 */
+ else
+ rate_bitmap = 0x000003fffffff010ULL; /* All */
+ }
+ break;
+
+ default:
+ if (p_dm_odm->rf_type == ODM_1T2R || p_dm_odm->rf_type == ODM_1T1R)
+ rate_bitmap = 0x00000000000fffff;
+ else if (p_dm_odm->rf_type == ODM_2T2R || p_dm_odm->rf_type == ODM_2T3R || p_dm_odm->rf_type == ODM_2T4R)
+ rate_bitmap = 0x000000000fffffff;
+ else
+ rate_bitmap = 0x0000003fffffffffULL;
+ break;
+
+ }
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, (" ==> rssi_level:0x%02x, wireless_mode:0x%02x, rate_bitmap:0x%016llx\n", rssi_level, wireless_mode, rate_bitmap));
+
+ return ra_mask & rate_bitmap;
+}
+
+
+u32
+odm_get_rate_bitmap(
+ void *p_dm_void,
+ u32 macid,
+ u32 ra_mask,
+ u8 rssi_level
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct sta_info *p_entry;
+ u32 rate_bitmap = 0;
+ u8 wireless_mode;
+ /* u8 wireless_mode =*(p_dm_odm->p_wireless_mode); */
+
+
+ p_entry = p_dm_odm->p_odm_sta_info[macid];
+ if (!IS_STA_VALID(p_entry))
+ return ra_mask;
+
+ wireless_mode = p_entry->wireless_mode;
+
+ switch (wireless_mode) {
+ case ODM_WM_B:
+ if (ra_mask & 0x0000000c) /* 11M or 5.5M enable */
+ rate_bitmap = 0x0000000d;
+ else
+ rate_bitmap = 0x0000000f;
+ break;
+
+ case (ODM_WM_G):
+ case (ODM_WM_A):
+ if (rssi_level == DM_RATR_STA_HIGH)
+ rate_bitmap = 0x00000f00;
+ else
+ rate_bitmap = 0x00000ff0;
+ break;
+
+ case (ODM_WM_B|ODM_WM_G):
+ if (rssi_level == DM_RATR_STA_HIGH)
+ rate_bitmap = 0x00000f00;
+ else if (rssi_level == DM_RATR_STA_MIDDLE)
+ rate_bitmap = 0x00000ff0;
+ else
+ rate_bitmap = 0x00000ff5;
+ break;
+
+ case (ODM_WM_B|ODM_WM_G|ODM_WM_N24G):
+ case (ODM_WM_B|ODM_WM_N24G):
+ case (ODM_WM_G|ODM_WM_N24G):
+ case (ODM_WM_A|ODM_WM_N5G):
+ {
+ if (p_dm_odm->rf_type == ODM_1T2R || p_dm_odm->rf_type == ODM_1T1R) {
+ if (rssi_level == DM_RATR_STA_HIGH)
+ rate_bitmap = 0x000f0000;
+ else if (rssi_level == DM_RATR_STA_MIDDLE)
+ rate_bitmap = 0x000ff000;
+ else {
+ if (*(p_dm_odm->p_band_width) == ODM_BW40M)
+ rate_bitmap = 0x000ff015;
+ else
+ rate_bitmap = 0x000ff005;
+ }
+ } else {
+ if (rssi_level == DM_RATR_STA_HIGH)
+ rate_bitmap = 0x0f8f0000;
+ else if (rssi_level == DM_RATR_STA_MIDDLE)
+ rate_bitmap = 0x0f8ff000;
+ else {
+ if (*(p_dm_odm->p_band_width) == ODM_BW40M)
+ rate_bitmap = 0x0f8ff015;
+ else
+ rate_bitmap = 0x0f8ff005;
+ }
+ }
+ }
+ break;
+
+ case (ODM_WM_AC|ODM_WM_G):
+ if (rssi_level == 1)
+ rate_bitmap = 0xfc3f0000;
+ else if (rssi_level == 2)
+ rate_bitmap = 0xfffff000;
+ else
+ rate_bitmap = 0xffffffff;
+ break;
+
+ case (ODM_WM_AC|ODM_WM_A):
+
+ if (p_dm_odm->rf_type == RF_1T1R) {
+ if (rssi_level == 1) /* add by Gary for ac-series */
+ rate_bitmap = 0x003f8000;
+ else if (rssi_level == 2)
+ rate_bitmap = 0x003ff000;
+ else
+ rate_bitmap = 0x003ff010;
+ } else {
+ if (rssi_level == 1) /* add by Gary for ac-series */
+ rate_bitmap = 0xfe3f8000; /* VHT 2SS MCS3~9 */
+ else if (rssi_level == 2)
+ rate_bitmap = 0xfffff000; /* VHT 2SS MCS0~9 */
+ else
+ rate_bitmap = 0xfffff010; /* All */
+ }
+ break;
+
+ default:
+ if (p_dm_odm->rf_type == RF_1T2R)
+ rate_bitmap = 0x000fffff;
+ else
+ rate_bitmap = 0x0fffffff;
+ break;
+
+ }
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("%s ==> rssi_level:0x%02x, wireless_mode:0x%02x, rate_bitmap:0x%08x\n", __func__, rssi_level, wireless_mode, rate_bitmap));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, (" ==> rssi_level:0x%02x, wireless_mode:0x%02x, rate_bitmap:0x%08x\n", rssi_level, wireless_mode, rate_bitmap));
+
+ return ra_mask & rate_bitmap;
+
+}
+
+/* RA_MASK_PHYDMLIZE, will delete it later*/
+
+#if (RA_MASK_PHYDMLIZE_CE || RA_MASK_PHYDMLIZE_AP || RA_MASK_PHYDMLIZE_WIN)
+
+bool
+odm_ra_state_check(
+ void *p_dm_void,
+ s32 RSSI,
+ bool is_force_update,
+ u8 *p_ra_tr_state
+)
+{
+ struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
+ struct _ODM_RATE_ADAPTIVE *p_ra = &p_dm_odm->rate_adaptive;
+ const u8 go_up_gap = 5;
+ u8 high_rssi_thresh_for_ra = p_ra->high_rssi_thresh;
+ u8 low_rssi_thresh_for_ra = p_ra->low_rssi_thresh;
+ u8 ratr_state;
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("RSSI= (( %d )), Current_RSSI_level = (( %d ))\n", RSSI, *p_ra_tr_state));
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("[Ori RA RSSI Thresh] High= (( %d )), Low = (( %d ))\n", high_rssi_thresh_for_ra, low_rssi_thresh_for_ra));
+ /* threshold Adjustment:*/
+ /* when RSSI state trends to go up one or two levels, make sure RSSI is high enough.*/
+ /* Here go_up_gap is added to solve the boundary's level alternation issue.*/
+ switch (*p_ra_tr_state) {
+ case DM_RATR_STA_INIT:
+ case DM_RATR_STA_HIGH:
+ break;
+ case DM_RATR_STA_MIDDLE:
+ high_rssi_thresh_for_ra += go_up_gap;
+ break;
+ case DM_RATR_STA_LOW:
+ high_rssi_thresh_for_ra += go_up_gap;
+ low_rssi_thresh_for_ra += go_up_gap;
+ break;
+ default:
+ ODM_RT_ASSERT(p_dm_odm, false, ("wrong rssi level setting %d !", *p_ra_tr_state));
+ break;
+ }
+
+ /* Decide ratr_state by RSSI.*/
+ if (RSSI > high_rssi_thresh_for_ra)
+ ratr_state = DM_RATR_STA_HIGH;
+ else if (RSSI > low_rssi_thresh_for_ra)
+ ratr_state = DM_RATR_STA_MIDDLE;
+
+ else
+ ratr_state = DM_RATR_STA_LOW;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("[Mod RA RSSI Thresh] High= (( %d )), Low = (( %d ))\n", high_rssi_thresh_for_ra, low_rssi_thresh_for_ra));
+ if (*p_ra_tr_state != ratr_state || is_force_update) {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("[RSSI Level Update] %d->%d\n", *p_ra_tr_state, ratr_state));
+ *p_ra_tr_state = ratr_state;
+ return true;
+ }
+
+ return false;
+}
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_rainfo.h b/drivers/staging/rtl8188eu/hal/phydm_rainfo.h
new file mode 100644
index 000000000000..9eda17d184a1
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_rainfo.h
@@ -0,0 +1,484 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __PHYDMRAINFO_H__
+#define __PHYDMRAINFO_H__
+
+/*#define RAINFO_VERSION "2.0" //2014.11.04*/
+/*#define RAINFO_VERSION "3.0" //2015.01.13 Dino*/
+/*#define RAINFO_VERSION "3.1" //2015.01.14 Dino*/
+/*#define RAINFO_VERSION "3.3" 2015.07.29 YuChen*/
+/*#define RAINFO_VERSION "3.4"*/ /*2015.12.15 Stanley*/
+/*#define RAINFO_VERSION "4.0"*/ /*2016.03.24 Dino, Add more RA mask state and Phydm-lize partial ra mask function */
+/*#define RAINFO_VERSION "4.1"*/ /*2016.04.20 Dino, Add new function to adjust PCR RA threshold */
+/*#define RAINFO_VERSION "4.2"*/ /*2016.05.17 Dino, Add H2C debug cmd */
+#define RAINFO_VERSION "4.3" /*2016.07.11 Dino, Fix RA hang in CCK 1M problem */
+
+#define FORCED_UPDATE_RAMASK_PERIOD 5
+
+#define H2C_0X42_LENGTH 5
+#define H2C_MAX_LENGTH 7
+
+#define RA_FLOOR_UP_GAP 3
+#define RA_FLOOR_TABLE_SIZE 7
+
+#define ACTIVE_TP_THRESHOLD 150
+#define RA_RETRY_DESCEND_NUM 2
+#define RA_RETRY_LIMIT_LOW 4
+#define RA_RETRY_LIMIT_HIGH 32
+
+#define RAINFO_BE_RX_STATE BIT(0) /* 1:RX */ /* ULDL */
+#define RAINFO_STBC_STATE BIT(1)
+/* #define RAINFO_LDPC_STATE BIT2 */
+#define RAINFO_NOISY_STATE BIT(2) /* set by Noisy_Detection */
+#define RAINFO_SHURTCUT_STATE BIT(3)
+#define RAINFO_SHURTCUT_FLAG BIT(4)
+#define RAINFO_INIT_RSSI_RATE_STATE BIT(5)
+#define RAINFO_BF_STATE BIT(6)
+#define RAINFO_BE_TX_STATE BIT(7) /* 1:TX */
+
+#define RA_MASK_CCK 0xf
+#define RA_MASK_OFDM 0xff0
+#define RA_MASK_HT1SS 0xff000
+#define RA_MASK_HT2SS 0xff00000
+/*#define RA_MASK_MCS3SS */
+#define RA_MASK_HT4SS 0xff0
+#define RA_MASK_VHT1SS 0x3ff000
+#define RA_MASK_VHT2SS 0xffc00000
+
+ #define RA_FIRST_MACID 0
+
+#define ap_init_rate_adaptive_state odm_rate_adaptive_state_ap_init
+
+#if (RA_MASK_PHYDMLIZE_CE || RA_MASK_PHYDMLIZE_AP || RA_MASK_PHYDMLIZE_WIN)
+ #define DM_RATR_STA_INIT 0
+ #define DM_RATR_STA_HIGH 1
+ #define DM_RATR_STA_MIDDLE 2
+ #define DM_RATR_STA_LOW 3
+ #define DM_RATR_STA_ULTRA_LOW 4
+#endif
+
+enum phydm_ra_arfr_num_e {
+ ARFR_0_RATE_ID = 0x9,
+ ARFR_1_RATE_ID = 0xa,
+ ARFR_2_RATE_ID = 0xb,
+ ARFR_3_RATE_ID = 0xc,
+ ARFR_4_RATE_ID = 0xd,
+ ARFR_5_RATE_ID = 0xe
+};
+
+enum phydm_ra_dbg_para_e {
+ RADBG_PCR_TH_OFFSET = 0,
+ RADBG_RTY_PENALTY = 1,
+ RADBG_N_HIGH = 2,
+ RADBG_N_LOW = 3,
+ RADBG_TRATE_UP_TABLE = 4,
+ RADBG_TRATE_DOWN_TABLE = 5,
+ RADBG_TRYING_NECESSARY = 6,
+ RADBG_TDROPING_NECESSARY = 7,
+ RADBG_RATE_UP_RTY_RATIO = 8,
+ RADBG_RATE_DOWN_RTY_RATIO = 9, /* u8 */
+
+ RADBG_DEBUG_MONITOR1 = 0xc,
+ RADBG_DEBUG_MONITOR2 = 0xd,
+ RADBG_DEBUG_MONITOR3 = 0xe,
+ RADBG_DEBUG_MONITOR4 = 0xf,
+ RADBG_DEBUG_MONITOR5 = 0x10,
+ NUM_RA_PARA
+};
+
+enum phydm_wireless_mode_e {
+
+ PHYDM_WIRELESS_MODE_UNKNOWN = 0x00,
+ PHYDM_WIRELESS_MODE_A = 0x01,
+ PHYDM_WIRELESS_MODE_B = 0x02,
+ PHYDM_WIRELESS_MODE_G = 0x04,
+ PHYDM_WIRELESS_MODE_AUTO = 0x08,
+ PHYDM_WIRELESS_MODE_N_24G = 0x10,
+ PHYDM_WIRELESS_MODE_N_5G = 0x20,
+ PHYDM_WIRELESS_MODE_AC_5G = 0x40,
+ PHYDM_WIRELESS_MODE_AC_24G = 0x80,
+ PHYDM_WIRELESS_MODE_AC_ONLY = 0x100,
+ PHYDM_WIRELESS_MODE_MAX = 0x800,
+ PHYDM_WIRELESS_MODE_ALL = 0xFFFF
+};
+
+enum phydm_rateid_idx_e {
+
+ PHYDM_BGN_40M_2SS = 0,
+ PHYDM_BGN_40M_1SS = 1,
+ PHYDM_BGN_20M_2SS = 2,
+ PHYDM_BGN_20M_1SS = 3,
+ PHYDM_GN_N2SS = 4,
+ PHYDM_GN_N1SS = 5,
+ PHYDM_BG = 6,
+ PHYDM_G = 7,
+ PHYDM_B_20M = 8,
+ PHYDM_ARFR0_AC_2SS = 9,
+ PHYDM_ARFR1_AC_1SS = 10,
+ PHYDM_ARFR2_AC_2G_1SS = 11,
+ PHYDM_ARFR3_AC_2G_2SS = 12,
+ PHYDM_ARFR4_AC_3SS = 13,
+ PHYDM_ARFR5_N_3SS = 14
+};
+
+enum phydm_rf_type_def_e {
+ PHYDM_RF_1T1R = 0,
+ PHYDM_RF_1T2R,
+ PHYDM_RF_2T2R,
+ PHYDM_RF_2T2R_GREEN,
+ PHYDM_RF_2T3R,
+ PHYDM_RF_2T4R,
+ PHYDM_RF_3T3R,
+ PHYDM_RF_3T4R,
+ PHYDM_RF_4T4R,
+ PHYDM_RF_MAX_TYPE
+};
+
+enum phydm_bw_e {
+ PHYDM_BW_20 = 0,
+ PHYDM_BW_40,
+ PHYDM_BW_80,
+ PHYDM_BW_80_80,
+ PHYDM_BW_160,
+ PHYDM_BW_10,
+ PHYDM_BW_5
+};
+
+
+#if (RATE_ADAPTIVE_SUPPORT == 1)/* 88E RA */
+struct _odm_ra_info_ {
+ u8 rate_id;
+ u32 rate_mask;
+ u32 ra_use_rate;
+ u8 rate_sgi;
+ u8 rssi_sta_ra;
+ u8 pre_rssi_sta_ra;
+ u8 sgi_enable;
+ u8 decision_rate;
+ u8 pre_rate;
+ u8 highest_rate;
+ u8 lowest_rate;
+ u32 nsc_up;
+ u32 nsc_down;
+ u16 RTY[5];
+ u32 TOTAL;
+ u16 DROP;
+ u8 active;
+ u16 rpt_time;
+ u8 ra_waiting_counter;
+ u8 ra_pending_counter;
+ u8 ra_drop_after_down;
+ u8 pt_active; /* on or off */
+ u8 pt_try_state; /* 0 trying state, 1 for decision state */
+ u8 pt_stage; /* 0~6 */
+ u8 pt_stop_count; /* Stop PT counter */
+ u8 pt_pre_rate; /* if rate change do PT */
+ u8 pt_pre_rssi; /* if RSSI change 5% do PT */
+ u8 pt_mode_ss; /* decide whitch rate should do PT */
+ u8 ra_stage; /* StageRA, decide how many times RA will be done between PT */
+ u8 pt_smooth_factor;
+};
+#endif
+
+
+struct _rate_adaptive_table_ {
+ u8 firstconnect;
+#if (defined(CONFIG_RA_DBG_CMD))
+ bool is_ra_dbg_init;
+
+ u8 RTY_P[ODM_NUM_RATE_IDX];
+ u8 RTY_P_default[ODM_NUM_RATE_IDX];
+ bool RTY_P_modify_note[ODM_NUM_RATE_IDX];
+
+ u8 RATE_UP_RTY_RATIO[ODM_NUM_RATE_IDX];
+ u8 RATE_UP_RTY_RATIO_default[ODM_NUM_RATE_IDX];
+ bool RATE_UP_RTY_RATIO_modify_note[ODM_NUM_RATE_IDX];
+
+ u8 RATE_DOWN_RTY_RATIO[ODM_NUM_RATE_IDX];
+ u8 RATE_DOWN_RTY_RATIO_default[ODM_NUM_RATE_IDX];
+ bool RATE_DOWN_RTY_RATIO_modify_note[ODM_NUM_RATE_IDX];
+
+ bool ra_para_feedback_req;
+
+ u8 para_idx;
+ u8 rate_idx;
+ u8 value;
+ u16 value_16;
+ u8 rate_length;
+#endif
+ u8 link_tx_rate[ODM_ASSOCIATE_ENTRY_NUM];
+ u8 highest_client_tx_order;
+ u16 highest_client_tx_rate_order;
+ u8 power_tracking_flag;
+ u8 RA_threshold_offset;
+ u8 RA_offset_direction;
+ u8 force_update_ra_mask_count;
+
+#if (defined(CONFIG_RA_DYNAMIC_RTY_LIMIT))
+ u8 per_rate_retrylimit_20M[ODM_NUM_RATE_IDX];
+ u8 per_rate_retrylimit_40M[ODM_NUM_RATE_IDX];
+ u8 retry_descend_num;
+ u8 retrylimit_low;
+ u8 retrylimit_high;
+#endif
+
+
+};
+
+struct _ODM_RATE_ADAPTIVE {
+ u8 type; /* dm_type_by_fw/dm_type_by_driver */
+ u8 high_rssi_thresh; /* if RSSI > high_rssi_thresh => ratr_state is DM_RATR_STA_HIGH */
+ u8 low_rssi_thresh; /* if RSSI <= low_rssi_thresh => ratr_state is DM_RATR_STA_LOW */
+ u8 ratr_state; /* Current RSSI level, DM_RATR_STA_HIGH/DM_RATR_STA_MIDDLE/DM_RATR_STA_LOW */
+
+ u8 ldpc_thres; /* if RSSI > ldpc_thres => switch from LPDC to BCC */
+ bool is_lower_rts_rate;
+
+ bool is_use_ldpc;
+};
+
+void
+phydm_h2C_debug(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+);
+
+#if (defined(CONFIG_RA_DBG_CMD))
+
+void
+odm_RA_debug(
+ void *p_dm_void,
+ u32 *const dm_value
+);
+
+void
+odm_ra_para_adjust_init(
+ void *p_dm_void
+);
+
+#else
+
+void
+phydm_RA_debug_PCR(
+ void *p_dm_void,
+ u32 *const dm_value,
+ u32 *_used,
+ char *output,
+ u32 *_out_len
+);
+
+#endif
+
+void
+odm_c2h_ra_para_report_handler(
+ void *p_dm_void,
+ u8 *cmd_buf,
+ u8 cmd_len
+);
+
+void
+odm_ra_para_adjust(
+ void *p_dm_void
+);
+
+void
+phydm_ra_dynamic_retry_count(
+ void *p_dm_void
+);
+
+void
+phydm_ra_dynamic_retry_limit(
+ void *p_dm_void
+);
+
+void
+phydm_ra_dynamic_rate_id_on_assoc(
+ void *p_dm_void,
+ u8 wireless_mode,
+ u8 init_rate_id
+);
+
+void
+phydm_print_rate(
+ void *p_dm_void,
+ u8 rate,
+ u32 dbg_component
+);
+
+void
+phydm_c2h_ra_report_handler(
+ void *p_dm_void,
+ u8 *cmd_buf,
+ u8 cmd_len
+);
+
+u8
+phydm_rate_order_compute(
+ void *p_dm_void,
+ u8 rate_idx
+);
+
+void
+phydm_ra_info_watchdog(
+ void *p_dm_void
+);
+
+void
+phydm_ra_info_init(
+ void *p_dm_void
+);
+
+void
+odm_rssi_monitor_init(
+ void *p_dm_void
+);
+
+void
+phydm_modify_RA_PCR_threshold(
+ void *p_dm_void,
+ u8 RA_offset_direction,
+ u8 RA_threshold_offset
+);
+
+void
+odm_rssi_monitor_check(
+ void *p_dm_void
+);
+
+void
+phydm_init_ra_info(
+ void *p_dm_void
+);
+
+u8
+phydm_vht_en_mapping(
+ void *p_dm_void,
+ u32 wireless_mode
+);
+
+u8
+phydm_rate_id_mapping(
+ void *p_dm_void,
+ u32 wireless_mode,
+ u8 rf_type,
+ u8 bw
+);
+
+void
+phydm_update_hal_ra_mask(
+ void *p_dm_void,
+ u32 wireless_mode,
+ u8 rf_type,
+ u8 BW,
+ u8 mimo_ps_enable,
+ u8 disable_cck_rate,
+ u32 *ratr_bitmap_msb_in,
+ u32 *ratr_bitmap_in,
+ u8 tx_rate_level
+);
+
+void
+odm_rate_adaptive_mask_init(
+ void *p_dm_void
+);
+
+void
+odm_refresh_rate_adaptive_mask(
+ void *p_dm_void
+);
+
+void
+odm_refresh_rate_adaptive_mask_mp(
+ void *p_dm_void
+);
+
+void
+odm_refresh_rate_adaptive_mask_ce(
+ void *p_dm_void
+);
+
+void
+odm_refresh_rate_adaptive_mask_apadsl(
+ void *p_dm_void
+);
+
+u8
+phydm_RA_level_decision(
+ void *p_dm_void,
+ u32 rssi,
+ u8 ratr_state
+);
+
+bool
+odm_ra_state_check(
+ void *p_dm_void,
+ s32 RSSI,
+ bool is_force_update,
+ u8 *p_ra_tr_state
+);
+
+void
+odm_refresh_basic_rate_mask(
+ void *p_dm_void
+);
+void
+odm_ra_post_action_on_assoc(
+ void *p_dm_odm
+);
+
+u8
+odm_find_rts_rate(
+ void *p_dm_void,
+ u8 tx_rate,
+ bool is_erp_protect
+);
+
+void
+odm_update_noisy_state(
+ void *p_dm_void,
+ bool is_noisy_state_from_c2h
+);
+
+void
+phydm_update_pwr_track(
+ void *p_dm_void,
+ u8 rate
+);
+
+
+void
+odm_rate_adaptive_state_ap_init(
+ void *PADAPTER_void,
+ struct sta_info *p_entry
+);
+
+static void
+find_minimum_rssi(
+ struct _ADAPTER *p_adapter
+);
+
+u64
+phydm_get_rate_bitmap_ex(
+ void *p_dm_void,
+ u32 macid,
+ u64 ra_mask,
+ u8 rssi_level,
+ u64 *dm_ra_mask,
+ u8 *dm_rte_id
+);
+u32
+odm_get_rate_bitmap(
+ void *p_dm_void,
+ u32 macid,
+ u32 ra_mask,
+ u8 rssi_level
+);
+
+void phydm_ra_rssi_rpt_wk(void *p_context);
+
+#endif /*#ifndef __ODMRAINFO_H__*/
diff --git a/drivers/staging/rtl8188eu/hal/phydm_reg.h b/drivers/staging/rtl8188eu/hal/phydm_reg.h
new file mode 100644
index 000000000000..1e0c230d7112
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_reg.h
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+/* ************************************************************
+ * File Name: odm_reg.h
+ *
+ * Description:
+ *
+ * This file is for general register definition.
+ *
+ *
+ * ************************************************************ */
+#ifndef __HAL_ODM_REG_H__
+#define __HAL_ODM_REG_H__
+
+/*
+ * Register Definition
+ * */
+
+/* MAC REG */
+#define ODM_BB_RESET 0x002
+#define ODM_DUMMY 0x4fe
+#define RF_T_METER_OLD 0x24
+#define RF_T_METER_NEW 0x42
+
+#define ODM_EDCA_VO_PARAM 0x500
+#define ODM_EDCA_VI_PARAM 0x504
+#define ODM_EDCA_BE_PARAM 0x508
+#define ODM_EDCA_BK_PARAM 0x50C
+#define ODM_TXPAUSE 0x522
+
+/* LTE_COEX */
+#define REG_LTECOEX_CTRL 0x07C0
+#define REG_LTECOEX_WRITE_DATA 0x07C4
+#define REG_LTECOEX_READ_DATA 0x07C8
+#define REG_LTECOEX_PATH_CONTROL 0x70
+
+/* BB REG */
+#define ODM_FPGA_PHY0_PAGE8 0x800
+#define ODM_PSD_SETTING 0x808
+#define ODM_AFE_SETTING 0x818
+#define ODM_TXAGC_B_6_18 0x830
+#define ODM_TXAGC_B_24_54 0x834
+#define ODM_TXAGC_B_MCS32_5 0x838
+#define ODM_TXAGC_B_MCS0_MCS3 0x83c
+#define ODM_TXAGC_B_MCS4_MCS7 0x848
+#define ODM_TXAGC_B_MCS8_MCS11 0x84c
+#define ODM_ANALOG_REGISTER 0x85c
+#define ODM_RF_INTERFACE_OUTPUT 0x860
+#define ODM_TXAGC_B_MCS12_MCS15 0x868
+#define ODM_TXAGC_B_11_A_2_11 0x86c
+#define ODM_AD_DA_LSB_MASK 0x874
+#define ODM_ENABLE_3_WIRE 0x88c
+#define ODM_PSD_REPORT 0x8b4
+#define ODM_R_ANT_SELECT 0x90c
+#define ODM_CCK_ANT_SELECT 0xa07
+#define ODM_CCK_PD_THRESH 0xa0a
+#define ODM_CCK_RF_REG1 0xa11
+#define ODM_CCK_MATCH_FILTER 0xa20
+#define ODM_CCK_RAKE_MAC 0xa2e
+#define ODM_CCK_CNT_RESET 0xa2d
+#define ODM_CCK_TX_DIVERSITY 0xa2f
+#define ODM_CCK_FA_CNT_MSB 0xa5b
+#define ODM_CCK_FA_CNT_LSB 0xa5c
+#define ODM_CCK_NEW_FUNCTION 0xa75
+#define ODM_OFDM_PHY0_PAGE_C 0xc00
+#define ODM_OFDM_RX_ANT 0xc04
+#define ODM_R_A_RXIQI 0xc14
+#define ODM_R_A_AGC_CORE1 0xc50
+#define ODM_R_A_AGC_CORE2 0xc54
+#define ODM_R_B_AGC_CORE1 0xc58
+#define ODM_R_AGC_PAR 0xc70
+#define ODM_R_HTSTF_AGC_PAR 0xc7c
+#define ODM_TX_PWR_TRAINING_A 0xc90
+#define ODM_TX_PWR_TRAINING_B 0xc98
+#define ODM_OFDM_FA_CNT1 0xcf0
+#define ODM_OFDM_PHY0_PAGE_D 0xd00
+#define ODM_OFDM_FA_CNT2 0xda0
+#define ODM_OFDM_FA_CNT3 0xda4
+#define ODM_OFDM_FA_CNT4 0xda8
+#define ODM_TXAGC_A_6_18 0xe00
+#define ODM_TXAGC_A_24_54 0xe04
+#define ODM_TXAGC_A_1_MCS32 0xe08
+#define ODM_TXAGC_A_MCS0_MCS3 0xe10
+#define ODM_TXAGC_A_MCS4_MCS7 0xe14
+#define ODM_TXAGC_A_MCS8_MCS11 0xe18
+#define ODM_TXAGC_A_MCS12_MCS15 0xe1c
+
+/* RF REG */
+#define ODM_GAIN_SETTING 0x00
+#define ODM_CHANNEL 0x18
+#define ODM_RF_T_METER 0x24
+#define ODM_RF_T_METER_92D 0x42
+#define ODM_RF_T_METER_88E 0x42
+#define ODM_RF_T_METER_92E 0x42
+#define ODM_RF_T_METER_8812 0x42
+#define REG_RF_TX_GAIN_OFFSET 0x55
+
+/* ant Detect Reg */
+#define ODM_DPDT 0x300
+
+/* PSD Init */
+#define ODM_PSDREG 0x808
+
+/* 92D path Div */
+#define PATHDIV_REG 0xB30
+#define PATHDIV_TRI 0xBA0
+
+
+/*
+ * Bitmap Definition
+ * */
+
+#define BIT_FA_RESET BIT(0)
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_regconfig8188e.c b/drivers/staging/rtl8188eu/hal/phydm_regconfig8188e.c
new file mode 100644
index 000000000000..90d6239f942a
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_regconfig8188e.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#include "mp_precomp.h"
+
+#include "phydm_precomp.h"
+
+#if (RTL8188E_SUPPORT == 1)
+
+void
+odm_config_rf_reg_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 addr,
+ u32 data,
+ enum odm_rf_radio_path_e RF_PATH,
+ u32 reg_addr
+)
+{
+ if (addr == 0xffe) {
+#ifdef CONFIG_LONG_DELAY_ISSUE
+ ODM_sleep_ms(50);
+#else
+ ODM_delay_ms(50);
+#endif
+ } else if (addr == 0xfd)
+ ODM_delay_ms(5);
+ else if (addr == 0xfc)
+ ODM_delay_ms(1);
+ else if (addr == 0xfb)
+ ODM_delay_us(50);
+ else if (addr == 0xfa)
+ ODM_delay_us(5);
+ else if (addr == 0xf9)
+ ODM_delay_us(1);
+ else {
+ odm_set_rf_reg(p_dm_odm, RF_PATH, reg_addr, RFREGOFFSETMASK, data);
+ /* Add 1us delay between BB/RF register setting. */
+ ODM_delay_us(1);
+ }
+}
+
+
+void
+odm_config_rf_radio_a_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 addr,
+ u32 data
+)
+{
+ u32 content = 0x1000; /* RF_Content: radioa_txt */
+ u32 maskfor_phy_set = (u32)(content & 0xE000);
+
+ odm_config_rf_reg_8188e(p_dm_odm, addr, data, ODM_RF_PATH_A, addr | maskfor_phy_set);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE, ("===> odm_config_rf_with_header_file: [RadioA] %08X %08X\n", addr, data));
+}
+
+void
+odm_config_rf_radio_b_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 addr,
+ u32 data
+)
+{
+ u32 content = 0x1001; /* RF_Content: radiob_txt */
+ u32 maskfor_phy_set = (u32)(content & 0xE000);
+
+ odm_config_rf_reg_8188e(p_dm_odm, addr, data, ODM_RF_PATH_B, addr | maskfor_phy_set);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE, ("===> odm_config_rf_with_header_file: [RadioB] %08X %08X\n", addr, data));
+
+}
+
+void
+odm_config_mac_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 addr,
+ u8 data
+)
+{
+ odm_write_1byte(p_dm_odm, addr, data);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE, ("===> odm_config_mac_with_header_file: [MAC_REG] %08X %08X\n", addr, data));
+}
+
+void
+odm_config_bb_agc_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 addr,
+ u32 bitmask,
+ u32 data
+)
+{
+ odm_set_bb_reg(p_dm_odm, addr, bitmask, data);
+ /* Add 1us delay between BB/RF register setting. */
+ ODM_delay_us(1);
+
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE, ("===> odm_config_bb_with_header_file: [AGC_TAB] %08X %08X\n", addr, data));
+}
+
+void
+odm_config_bb_phy_reg_pg_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 band,
+ u32 rf_path,
+ u32 tx_num,
+ u32 addr,
+ u32 bitmask,
+ u32 data
+)
+{
+ if (addr == 0xfe) {
+#ifdef CONFIG_LONG_DELAY_ISSUE
+ ODM_sleep_ms(50);
+#else
+ ODM_delay_ms(50);
+#endif
+ } else if (addr == 0xfd)
+ ODM_delay_ms(5);
+ else if (addr == 0xfc)
+ ODM_delay_ms(1);
+ else if (addr == 0xfb)
+ ODM_delay_us(50);
+ else if (addr == 0xfa)
+ ODM_delay_us(5);
+ else if (addr == 0xf9)
+ ODM_delay_us(1);
+ else {
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> odm_config_bb_with_header_file: [PHY_REG] %08X %08X %08X\n", addr, bitmask, data));
+ phy_store_tx_power_by_rate(p_dm_odm->adapter, band, rf_path, tx_num, addr, bitmask, data);
+ }
+}
+
+void
+odm_config_bb_txpwr_lmt_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 *regulation,
+ u8 *band,
+ u8 *bandwidth,
+ u8 *rate_section,
+ u8 *rf_path,
+ u8 *channel,
+ u8 *power_limit
+)
+{
+ phy_set_tx_power_limit(p_dm_odm, regulation, band,
+ bandwidth, rate_section, rf_path, channel, power_limit);
+}
+
+void
+odm_config_bb_phy_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 addr,
+ u32 bitmask,
+ u32 data
+)
+{
+ if (addr == 0xfe) {
+#ifdef CONFIG_LONG_DELAY_ISSUE
+ ODM_sleep_ms(50);
+#else
+ ODM_delay_ms(50);
+#endif
+ } else if (addr == 0xfd)
+ ODM_delay_ms(5);
+ else if (addr == 0xfc)
+ ODM_delay_ms(1);
+ else if (addr == 0xfb)
+ ODM_delay_us(50);
+ else if (addr == 0xfa)
+ ODM_delay_us(5);
+ else if (addr == 0xf9)
+ ODM_delay_us(1);
+ else {
+ if (addr == 0xa24)
+ p_dm_odm->rf_calibrate_info.rega24 = data;
+ odm_set_bb_reg(p_dm_odm, addr, bitmask, data);
+
+ /* Add 1us delay between BB/RF register setting. */
+ ODM_delay_us(1);
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE, ("===> odm_config_bb_with_header_file: [PHY_REG] %08X %08X\n", addr, data));
+ }
+}
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_regconfig8188e.h b/drivers/staging/rtl8188eu/hal/phydm_regconfig8188e.h
new file mode 100644
index 000000000000..a530c3b58072
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_regconfig8188e.h
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#ifndef __INC_ODM_REGCONFIG_H_8188E
+#define __INC_ODM_REGCONFIG_H_8188E
+
+#if (RTL8188E_SUPPORT == 1)
+
+void
+odm_config_rf_reg_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 addr,
+ u32 data,
+ enum odm_rf_radio_path_e RF_PATH,
+ u32 reg_addr
+);
+
+void
+odm_config_rf_radio_a_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 addr,
+ u32 data
+);
+
+void
+odm_config_rf_radio_b_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 addr,
+ u32 data
+);
+
+void
+odm_config_mac_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 addr,
+ u8 data
+);
+
+void
+odm_config_bb_agc_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 addr,
+ u32 bitmask,
+ u32 data
+);
+
+void
+odm_config_bb_phy_reg_pg_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 band,
+ u32 rf_path,
+ u32 tx_num,
+ u32 addr,
+ u32 bitmask,
+ u32 data
+);
+
+void
+odm_config_bb_phy_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u32 addr,
+ u32 bitmask,
+ u32 data
+);
+
+void
+odm_config_bb_txpwr_lmt_8188e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 *regulation,
+ u8 *band,
+ u8 *bandwidth,
+ u8 *rate_section,
+ u8 *rf_path,
+ u8 *channel,
+ u8 *power_limit
+);
+
+#endif
+#endif /* end of SUPPORT */
diff --git a/drivers/staging/rtl8188eu/hal/phydm_regdefine11ac.h b/drivers/staging/rtl8188eu/hal/phydm_regdefine11ac.h
new file mode 100644
index 000000000000..596b07afc0ca
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_regdefine11ac.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __ODM_REGDEFINE11AC_H__
+#define __ODM_REGDEFINE11AC_H__
+
+/* 2 RF REG LIST */
+
+
+
+/* 2 BB REG LIST
+ * PAGE 8 */
+#define ODM_REG_CCK_RPT_FORMAT_11AC 0x804
+#define ODM_REG_BB_RX_PATH_11AC 0x808
+#define ODM_REG_BB_TX_PATH_11AC 0x80c
+#define ODM_REG_BB_ATC_11AC 0x860
+#define ODM_REG_EDCCA_POWER_CAL 0x8dc
+#define ODM_REG_DBG_RPT_11AC 0x8fc
+/* PAGE 9 */
+#define ODM_REG_EDCCA_DOWN_OPT 0x900
+#define ODM_REG_ACBB_EDCCA_ENHANCE 0x944
+#define odm_adc_trigger_jaguar2 0x95C /*ADC sample mode*/
+#define ODM_REG_OFDM_FA_RST_11AC 0x9A4
+#define ODM_REG_CCX_PERIOD_11AC 0x990
+#define ODM_REG_NHM_TH9_TH10_11AC 0x994
+#define ODM_REG_CLM_11AC 0x994
+#define ODM_REG_NHM_TH3_TO_TH0_11AC 0x998
+#define ODM_REG_NHM_TH7_TO_TH4_11AC 0x99c
+#define ODM_REG_NHM_TH8_11AC 0x9a0
+#define ODM_REG_NHM_9E8_11AC 0x9e8
+#define ODM_REG_CSI_CONTENT_VALUE 0x9b4
+/* PAGE A */
+#define ODM_REG_CCK_CCA_11AC 0xA0A
+#define ODM_REG_CCK_FA_RST_11AC 0xA2C
+#define ODM_REG_CCK_FA_11AC 0xA5C
+/* PAGE B */
+#define ODM_REG_RST_RPT_11AC 0xB58
+/* PAGE C */
+#define ODM_REG_TRMUX_11AC 0xC08
+#define ODM_REG_IGI_A_11AC 0xC50
+/* PAGE E */
+#define ODM_REG_IGI_B_11AC 0xE50
+#define ODM_REG_TRMUX_11AC_B 0xE08
+/* PAGE F */
+#define ODM_REG_CCK_CRC32_CNT_11AC 0xF04
+#define ODM_REG_CCK_CCA_CNT_11AC 0xF08
+#define ODM_REG_VHT_CRC32_CNT_11AC 0xF0c
+#define ODM_REG_HT_CRC32_CNT_11AC 0xF10
+#define ODM_REG_OFDM_CRC32_CNT_11AC 0xF14
+#define ODM_REG_OFDM_FA_11AC 0xF48
+#define ODM_REG_RPT_11AC 0xfa0
+#define ODM_REG_CLM_RESULT_11AC 0xfa4
+#define ODM_REG_NHM_CNT_11AC 0xfa8
+#define ODM_REG_NHM_DUR_READY_11AC 0xfb4
+
+#define ODM_REG_NHM_CNT7_TO_CNT4_11AC 0xfac
+#define ODM_REG_NHM_CNT11_TO_CNT8_11AC 0xfb0
+#define ODM_REG_OFDM_FA_TYPE2_11AC 0xFD0
+/* PAGE 18 */
+#define ODM_REG_IGI_C_11AC 0x1850
+/* PAGE 1A */
+#define ODM_REG_IGI_D_11AC 0x1A50
+
+/* 2 MAC REG LIST */
+#define ODM_REG_RESP_TX_11AC 0x6D8
+
+
+
+/* DIG Related */
+#define ODM_BIT_IGI_11AC 0xFFFFFFFF
+#define ODM_BIT_CCK_RPT_FORMAT_11AC BIT(16)
+#define ODM_BIT_BB_RX_PATH_11AC 0xF
+#define ODM_BIT_BB_TX_PATH_11AC 0xF
+#define ODM_BIT_BB_ATC_11AC BIT(14)
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_regdefine11n.h b/drivers/staging/rtl8188eu/hal/phydm_regdefine11n.h
new file mode 100644
index 000000000000..90d753576f02
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_regdefine11n.h
@@ -0,0 +1,196 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#ifndef __ODM_REGDEFINE11N_H__
+#define __ODM_REGDEFINE11N_H__
+
+
+/* 2 RF REG LIST */
+#define ODM_REG_RF_MODE_11N 0x00
+#define ODM_REG_RF_0B_11N 0x0B
+#define ODM_REG_CHNBW_11N 0x18
+#define ODM_REG_T_METER_11N 0x24
+#define ODM_REG_RF_25_11N 0x25
+#define ODM_REG_RF_26_11N 0x26
+#define ODM_REG_RF_27_11N 0x27
+#define ODM_REG_RF_2B_11N 0x2B
+#define ODM_REG_RF_2C_11N 0x2C
+#define ODM_REG_RXRF_A3_11N 0x3C
+#define ODM_REG_T_METER_92D_11N 0x42
+#define ODM_REG_T_METER_88E_11N 0x42
+
+
+
+/* 2 BB REG LIST
+ * PAGE 8 */
+#define ODM_REG_BB_CTRL_11N 0x800
+#define ODM_REG_RF_PIN_11N 0x804
+#define ODM_REG_PSD_CTRL_11N 0x808
+#define ODM_REG_TX_ANT_CTRL_11N 0x80C
+#define ODM_REG_BB_PWR_SAV5_11N 0x818
+#define ODM_REG_CCK_RPT_FORMAT_11N 0x824
+#define ODM_REG_CCK_RPT_FORMAT_11N_B 0x82C
+#define ODM_REG_RX_DEFUALT_A_11N 0x858
+#define ODM_REG_RX_DEFUALT_B_11N 0x85A
+#define ODM_REG_BB_PWR_SAV3_11N 0x85C
+#define ODM_REG_ANTSEL_CTRL_11N 0x860
+#define ODM_REG_RX_ANT_CTRL_11N 0x864
+#define ODM_REG_PIN_CTRL_11N 0x870
+#define ODM_REG_BB_PWR_SAV1_11N 0x874
+#define ODM_REG_ANTSEL_PATH_11N 0x878
+#define ODM_REG_BB_3WIRE_11N 0x88C
+#define ODM_REG_SC_CNT_11N 0x8C4
+#define ODM_REG_PSD_DATA_11N 0x8B4
+#define ODM_REG_CCX_PERIOD_11N 0x894
+#define ODM_REG_NHM_TH9_TH10_11N 0x890
+#define ODM_REG_CLM_11N 0x890
+#define ODM_REG_NHM_TH3_TO_TH0_11N 0x898
+#define ODM_REG_NHM_TH7_TO_TH4_11N 0x89c
+#define ODM_REG_NHM_TH8_11N 0xe28
+#define ODM_REG_CLM_READY_11N 0x8b4
+#define ODM_REG_CLM_RESULT_11N 0x8d0
+#define ODM_REG_NHM_CNT_11N 0x8d8
+
+/* For struct _ACS_, Jeffery, 2014-12-26 */
+#define ODM_REG_NHM_CNT7_TO_CNT4_11N 0x8dc
+#define ODM_REG_NHM_CNT9_TO_CNT8_11N 0x8d0
+#define ODM_REG_NHM_CNT10_TO_CNT11_11N 0x8d4
+
+/* PAGE 9 */
+#define ODM_REG_BB_CTRL_PAGE9_11N 0x900
+#define ODM_REG_DBG_RPT_11N 0x908
+#define ODM_REG_BB_TX_PATH_11N 0x90c
+#define ODM_REG_ANT_MAPPING1_11N 0x914
+#define ODM_REG_ANT_MAPPING2_11N 0x918
+#define ODM_REG_EDCCA_DOWN_OPT_11N 0x948
+#define ODM_REG_RX_DFIR_MOD_97F 0x948
+
+/* PAGE A */
+#define ODM_REG_CCK_ANTDIV_PARA1_11N 0xA00
+#define ODM_REG_CCK_ANT_SEL_11N 0xA04
+#define ODM_REG_CCK_CCA_11N 0xA0A
+#define ODM_REG_CCK_ANTDIV_PARA2_11N 0xA0C
+#define ODM_REG_CCK_ANTDIV_PARA3_11N 0xA10
+#define ODM_REG_CCK_ANTDIV_PARA4_11N 0xA14
+#define ODM_REG_CCK_FILTER_PARA1_11N 0xA22
+#define ODM_REG_CCK_FILTER_PARA2_11N 0xA23
+#define ODM_REG_CCK_FILTER_PARA3_11N 0xA24
+#define ODM_REG_CCK_FILTER_PARA4_11N 0xA25
+#define ODM_REG_CCK_FILTER_PARA5_11N 0xA26
+#define ODM_REG_CCK_FILTER_PARA6_11N 0xA27
+#define ODM_REG_CCK_FILTER_PARA7_11N 0xA28
+#define ODM_REG_CCK_FILTER_PARA8_11N 0xA29
+#define ODM_REG_CCK_FA_RST_11N 0xA2C
+#define ODM_REG_CCK_FA_MSB_11N 0xA58
+#define ODM_REG_CCK_FA_LSB_11N 0xA5C
+#define ODM_REG_CCK_CCA_CNT_11N 0xA60
+#define ODM_REG_BB_PWR_SAV4_11N 0xA74
+/* PAGE B */
+#define ODM_REG_LNA_SWITCH_11N 0xB2C
+#define ODM_REG_PATH_SWITCH_11N 0xB30
+#define ODM_REG_RSSI_CTRL_11N 0xB38
+#define ODM_REG_CONFIG_ANTA_11N 0xB68
+#define ODM_REG_RSSI_BT_11N 0xB9C
+#define ODM_REG_RXCK_RFMOD 0xBB0
+#define ODM_REG_EDCCA_DCNF_97F 0xBC0
+
+/* PAGE C */
+#define ODM_REG_OFDM_FA_HOLDC_11N 0xC00
+#define ODM_REG_BB_RX_PATH_11N 0xC04
+#define ODM_REG_TRMUX_11N 0xC08
+#define ODM_REG_OFDM_FA_RSTC_11N 0xC0C
+#define ODM_REG_DOWNSAM_FACTOR_11N 0xC10
+#define ODM_REG_RXIQI_MATRIX_11N 0xC14
+#define ODM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C
+#define ODM_REG_IGI_A_11N 0xC50
+#define ODM_REG_ANTDIV_PARA2_11N 0xC54
+#define ODM_REG_IGI_B_11N 0xC58
+#define ODM_REG_ANTDIV_PARA3_11N 0xC5C
+#define ODM_REG_L1SBD_PD_CH_11N 0XC6C
+#define ODM_REG_BB_PWR_SAV2_11N 0xC70
+#define ODM_REG_BB_AGC_SET_2_11N 0xc74
+#define ODM_REG_RX_OFF_11N 0xC7C
+#define ODM_REG_TXIQK_MATRIXA_11N 0xC80
+#define ODM_REG_TXIQK_MATRIXB_11N 0xC88
+#define ODM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94
+#define ODM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C
+#define ODM_REG_RXIQK_MATRIX_LSB_11N 0xCA0
+#define ODM_REG_ANTDIV_PARA1_11N 0xCA4
+#define ODM_REG_SMALL_BANDWIDTH_11N 0xCE4
+#define ODM_REG_OFDM_FA_TYPE1_11N 0xCF0
+/* PAGE D */
+#define ODM_REG_OFDM_FA_RSTD_11N 0xD00
+#define ODM_REG_BB_RX_ANT_11N 0xD04
+#define ODM_REG_BB_ATC_11N 0xD2C
+#define ODM_REG_OFDM_FA_TYPE2_11N 0xDA0
+#define ODM_REG_OFDM_FA_TYPE3_11N 0xDA4
+#define ODM_REG_OFDM_FA_TYPE4_11N 0xDA8
+#define ODM_REG_RPT_11N 0xDF4
+/* PAGE E */
+#define ODM_REG_TXAGC_A_6_18_11N 0xE00
+#define ODM_REG_TXAGC_A_24_54_11N 0xE04
+#define ODM_REG_TXAGC_A_1_MCS32_11N 0xE08
+#define ODM_REG_TXAGC_A_MCS0_3_11N 0xE10
+#define ODM_REG_TXAGC_A_MCS4_7_11N 0xE14
+#define ODM_REG_TXAGC_A_MCS8_11_11N 0xE18
+#define ODM_REG_TXAGC_A_MCS12_15_11N 0xE1C
+#define ODM_REG_EDCCA_DCNF_11N 0xE24
+#define ODM_REG_TAP_UPD_97F 0xE24
+#define ODM_REG_FPGA0_IQK_11N 0xE28
+#define ODM_REG_PAGE_B1_97F 0xE28
+#define ODM_REG_TXIQK_TONE_A_11N 0xE30
+#define ODM_REG_RXIQK_TONE_A_11N 0xE34
+#define ODM_REG_TXIQK_PI_A_11N 0xE38
+#define ODM_REG_RXIQK_PI_A_11N 0xE3C
+#define ODM_REG_TXIQK_11N 0xE40
+#define ODM_REG_RXIQK_11N 0xE44
+#define ODM_REG_IQK_AGC_PTS_11N 0xE48
+#define ODM_REG_IQK_AGC_RSP_11N 0xE4C
+#define ODM_REG_BLUETOOTH_11N 0xE6C
+#define ODM_REG_RX_WAIT_CCA_11N 0xE70
+#define ODM_REG_TX_CCK_RFON_11N 0xE74
+#define ODM_REG_TX_CCK_BBON_11N 0xE78
+#define ODM_REG_OFDM_RFON_11N 0xE7C
+#define ODM_REG_OFDM_BBON_11N 0xE80
+#define ODM_REG_TX2RX_11N 0xE84
+#define ODM_REG_TX2TX_11N 0xE88
+#define ODM_REG_RX_CCK_11N 0xE8C
+#define ODM_REG_RX_OFDM_11N 0xED0
+#define ODM_REG_RX_WAIT_RIFS_11N 0xED4
+#define ODM_REG_RX2RX_11N 0xED8
+#define ODM_REG_STANDBY_11N 0xEDC
+#define ODM_REG_SLEEP_11N 0xEE0
+#define ODM_REG_PMPD_ANAEN_11N 0xEEC
+/* PAGE F */
+#define ODM_REG_PAGE_F_RST_11N 0xF14
+#define ODM_REG_IGI_C_11N 0xF84
+#define ODM_REG_IGI_D_11N 0xF88
+#define ODM_REG_CCK_CRC32_ERROR_CNT_11N 0xF84
+#define ODM_REG_CCK_CRC32_OK_CNT_11N 0xF88
+#define ODM_REG_HT_CRC32_CNT_11N 0xF90
+#define ODM_REG_OFDM_CRC32_CNT_11N 0xF94
+
+/* 2 MAC REG LIST */
+#define ODM_REG_BB_RST_11N 0x02
+#define ODM_REG_ANTSEL_PIN_11N 0x4C
+#define ODM_REG_EARLY_MODE_11N 0x4D0
+#define ODM_REG_RSSI_MONITOR_11N 0x4FE
+#define ODM_REG_EDCA_VO_11N 0x500
+#define ODM_REG_EDCA_VI_11N 0x504
+#define ODM_REG_EDCA_BE_11N 0x508
+#define ODM_REG_EDCA_BK_11N 0x50C
+#define ODM_REG_TXPAUSE_11N 0x522
+#define ODM_REG_RESP_TX_11N 0x6D8
+#define ODM_REG_ANT_TRAIN_PARA1_11N 0x7b0
+#define ODM_REG_ANT_TRAIN_PARA2_11N 0x7b4
+
+
+/* DIG Related */
+#define ODM_BIT_IGI_11N 0x0000007F
+#define ODM_BIT_CCK_RPT_FORMAT_11N BIT(9)
+#define ODM_BIT_BB_RX_PATH_11N 0xF
+#define ODM_BIT_BB_TX_PATH_11N 0xF
+#define ODM_BIT_BB_ATC_11N BIT(11)
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_rtl8188e.c b/drivers/staging/rtl8188eu/hal/phydm_rtl8188e.c
new file mode 100644
index 000000000000..43f5ba125ee0
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_rtl8188e.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#include "mp_precomp.h"
+
+#include "phydm_precomp.h"
+
+void odm_dig_lower_bound_88e(struct PHY_DM_STRUCT *p_dm_odm)
+{
+ struct _dynamic_initial_gain_threshold_ *p_dm_dig_table =
+ &p_dm_odm->dm_dig_table;
+
+ if (p_dm_odm->ant_div_type == CG_TRX_HW_ANTDIV) {
+ p_dm_dig_table->rx_gain_range_min =
+ (u8)p_dm_dig_table->ant_div_rssi_max;
+ ODM_RT_TRACE(p_dm_odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
+ ("odm_dig_lower_bound_88e(): p_dm_dig_table->ant_div_rssi_max=%d\n",
+ p_dm_dig_table->ant_div_rssi_max));
+ }
+}
+
+/*=============================================================
+* AntDiv Before Link
+===============================================================*/
+void odm_sw_ant_div_reset_before_link(struct PHY_DM_STRUCT *p_dm_odm)
+{
+ struct _sw_antenna_switch_ *p_dm_swat_table = &p_dm_odm->dm_swat_table;
+
+ p_dm_swat_table->swas_no_link_state = 0;
+}
+
+/* 3============================================================
+ * 3 Dynamic Primary CCA
+ * 3============================================================ */
+
+void odm_primary_cca_init(struct PHY_DM_STRUCT *p_dm_odm)
+{
+ struct _dynamic_primary_cca *primary_cca = &(p_dm_odm->dm_pri_cca);
+ primary_cca->dup_rts_flag = 0;
+ primary_cca->intf_flag = 0;
+ primary_cca->intf_type = 0;
+ primary_cca->monitor_flag = 0;
+ primary_cca->pri_cca_flag = 0;
+}
+
+bool odm_dynamic_primary_cca_dup_rts(struct PHY_DM_STRUCT *p_dm_odm)
+{
+ struct _dynamic_primary_cca *primary_cca = &(p_dm_odm->dm_pri_cca);
+
+ return primary_cca->dup_rts_flag;
+}
+
+void odm_dynamic_primary_cca(struct PHY_DM_STRUCT *p_dm_odm)
+{
+}
diff --git a/drivers/staging/rtl8188eu/hal/phydm_rtl8188e.h b/drivers/staging/rtl8188eu/hal/phydm_rtl8188e.h
new file mode 100644
index 000000000000..c131632ea092
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_rtl8188e.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#ifndef __ODM_RTL8188E_H__
+#define __ODM_RTL8188E_H__
+
+#if (RTL8188E_SUPPORT == 1)
+
+
+
+#define MAIN_ANT_CG_TRX 1
+#define AUX_ANT_CG_TRX 0
+#define MAIN_ANT_CGCS_RX 0
+#define AUX_ANT_CGCS_RX 1
+
+void
+odm_dig_lower_bound_88e(
+ struct PHY_DM_STRUCT *p_dm_odm
+);
+
+#define sw_ant_div_reset_before_link odm_sw_ant_div_reset_before_link
+
+void odm_sw_ant_div_reset_before_link(struct PHY_DM_STRUCT *p_dm_odm);
+
+void
+odm_set_tx_ant_by_tx_info_88e(
+ struct PHY_DM_STRUCT *p_dm_odm,
+ u8 *p_desc,
+ u8 mac_id
+);
+
+void
+odm_primary_cca_init(
+ struct PHY_DM_STRUCT *p_dm_odm);
+
+bool
+odm_dynamic_primary_cca_dup_rts(
+ struct PHY_DM_STRUCT *p_dm_odm);
+
+void
+odm_dynamic_primary_cca(
+ struct PHY_DM_STRUCT *p_dm_odm);
+
+#else /* (RTL8188E_SUPPORT == 0)*/
+
+#define odm_primary_cca_init(_pdm_odm)
+#define odm_dynamic_primary_cca(_pdm_odm)
+
+#endif /* RTL8188E_SUPPORT */
+
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/phydm_types.h b/drivers/staging/rtl8188eu/hal/phydm_types.h
new file mode 100644
index 000000000000..f5fe63953a9f
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/phydm_types.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#ifndef __ODM_TYPES_H__
+#define __ODM_TYPES_H__
+
+
+/*Define Different SW team support*/
+#define ODM_AP 0x01 /*BIT0*/
+#define ODM_CE 0x04 /*BIT2*/
+#define ODM_WIN 0x08 /*BIT3*/
+#define ODM_ADSL 0x10 /*BIT4*/
+#define ODM_IOT 0x20 /*BIT5*/
+
+/*Deifne HW endian support*/
+#define ODM_ENDIAN_BIG 0
+#define ODM_ENDIAN_LITTLE 1
+
+ #define GET_PDM_ODM(__padapter) ((struct PHY_DM_STRUCT*)(&((GET_HAL_DATA(__padapter))->odmpriv)))
+
+ #define RT_PCI_INTERFACE 1
+ #define RT_USB_INTERFACE 2
+ #define RT_SDIO_INTERFACE 3
+
+enum hal_status {
+ HAL_STATUS_SUCCESS,
+ HAL_STATUS_FAILURE,
+ /*RT_STATUS_PENDING,
+ RT_STATUS_RESOURCE,
+ RT_STATUS_INVALID_CONTEXT,
+ RT_STATUS_INVALID_PARAMETER,
+ RT_STATUS_NOT_SUPPORT,
+ RT_STATUS_OS_API_FAILED,*/
+};
+
+
+#define VISTA_USB_RX_REVISE 0
+
+/*
+ * Declare for ODM spin lock defintion temporarily fro compile pass.
+ * */
+enum rt_spinlock_type {
+ RT_TX_SPINLOCK = 1,
+ RT_RX_SPINLOCK = 2,
+ RT_RM_SPINLOCK = 3,
+ RT_CAM_SPINLOCK = 4,
+ RT_SCAN_SPINLOCK = 5,
+ RT_LOG_SPINLOCK = 7,
+ RT_BW_SPINLOCK = 8,
+ RT_CHNLOP_SPINLOCK = 9,
+ RT_RF_OPERATE_SPINLOCK = 10,
+ RT_INITIAL_SPINLOCK = 11,
+ RT_RF_STATE_SPINLOCK = 12, /* For RF state. Added by Bruce, 2007-10-30. */
+#if VISTA_USB_RX_REVISE
+ RT_USBRX_CONTEXT_SPINLOCK = 13,
+ RT_USBRX_POSTPROC_SPINLOCK = 14, /* protect data of adapter->IndicateW/ IndicateR */
+#endif
+ /* Shall we define Ndis 6.2 SpinLock Here ? */
+ RT_PORT_SPINLOCK = 16,
+ RT_VNIC_SPINLOCK = 17,
+ RT_HVL_SPINLOCK = 18,
+ RT_H2C_SPINLOCK = 20, /* For H2C cmd. Added by tynli. 2009.11.09. */
+
+ rt_bt_data_spinlock = 25,
+
+ RT_WAPI_OPTION_SPINLOCK = 26,
+ RT_WAPI_RX_SPINLOCK = 27,
+
+ /* add for 92D CCK control issue */
+ RT_CCK_PAGEA_SPINLOCK = 28,
+ RT_BUFFER_SPINLOCK = 29,
+ RT_CHANNEL_AND_BANDWIDTH_SPINLOCK = 30,
+ RT_GEN_TEMP_BUF_SPINLOCK = 31,
+ RT_AWB_SPINLOCK = 32,
+ RT_FW_PS_SPINLOCK = 33,
+ RT_HW_TIMER_SPIN_LOCK = 34,
+ RT_MPT_WI_SPINLOCK = 35,
+ RT_P2P_SPIN_LOCK = 36, /* Protect P2P context */
+ RT_DBG_SPIN_LOCK = 37,
+ RT_IQK_SPINLOCK = 38,
+ RT_PENDED_OID_SPINLOCK = 39,
+ RT_CHNLLIST_SPINLOCK = 40,
+ RT_INDIC_SPINLOCK = 41, /* protect indication */
+ RT_RFD_SPINLOCK = 42,
+ RT_SYNC_IO_CNT_SPINLOCK = 43,
+ RT_LAST_SPINLOCK,
+};
+
+ #include <drv_types.h>
+ #define DEV_BUS_TYPE RT_USB_INTERFACE
+
+ #if defined(__LITTLE_ENDIAN)
+ #define ODM_ENDIAN_TYPE ODM_ENDIAN_LITTLE
+ #elif defined (__BIG_ENDIAN)
+ #define ODM_ENDIAN_TYPE ODM_ENDIAN_BIG
+ #endif
+
+ #define SET_TX_DESC_ANTSEL_A_88E(__ptx_desc, __value) SET_BITS_TO_LE_4BYTE(__ptx_desc+8, 24, 1, __value)
+ #define SET_TX_DESC_ANTSEL_B_88E(__ptx_desc, __value) SET_BITS_TO_LE_4BYTE(__ptx_desc+8, 25, 1, __value)
+ #define SET_TX_DESC_ANTSEL_C_88E(__ptx_desc, __value) SET_BITS_TO_LE_4BYTE(__ptx_desc+28, 29, 1, __value)
+
+ /* define useless flag to avoid compile warning */
+ #define USE_WORKITEM 0
+ #define FOR_BRAZIL_PRETEST 0
+ #define FPGA_TWO_MAC_VERIFICATION 0
+ #define RTL8881A_SUPPORT 0
+
+ #if (defined(TESTCHIP_SUPPORT))
+ #define PHYDM_TESTCHIP_SUPPORT 1
+ #else
+ #define PHYDM_TESTCHIP_SUPPORT 0
+ #endif
+
+#define READ_NEXT_PAIR(v1, v2, i) do { if (i+2 >= array_len) break; i += 2; v1 = array[i]; v2 = array[i+1]; } while (0)
+#define COND_ELSE 2
+#define COND_ENDIF 3
+
+#define MASKBYTE0 0xff
+#define MASKBYTE1 0xff00
+#define MASKBYTE2 0xff0000
+#define MASKBYTE3 0xff000000
+#define MASKHWORD 0xffff0000
+#define MASKLWORD 0x0000ffff
+#define MASKDWORD 0xffffffff
+#define MASK7BITS 0x7f
+#define MASK12BITS 0xfff
+#define MASKH4BITS 0xf0000000
+#define MASK20BITS 0xfffff
+#define MASKOFDM_D 0xffc00000
+#define MASKCCK 0x3f3f3f3f
+#define RFREGOFFSETMASK 0xfffff
+#define MASKH3BYTES 0xffffff00
+#define MASKL3BYTES 0x00ffffff
+#define MASKBYTE2HIGHNIBBLE 0x00f00000
+#define MASKBYTE3LOWNIBBLE 0x0f000000
+#define MASKL3BYTES 0x00ffffff
+#define RFREGOFFSETMASK 0xfffff
+
+
+#include "phydm_features.h"
+
+#endif /* __ODM_TYPES_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/rtchnlplan.c b/drivers/staging/rtl8188eu/hal/rtchnlplan.c
new file mode 100644
index 000000000000..20c2a5d4ad18
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/rtchnlplan.c
@@ -0,0 +1,287 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+/******************************************************************************
+
+ History:
+ data Who Remark (Internal History)
+
+ 05/14/2012 MH Collect RTK inernal infromation and generate channel plan draft.
+
+******************************************************************************/
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+#include "mp_precomp.h"
+#include "phydm_precomp.h"
+#include "rtchnlplan.h"
+
+
+
+/*
+ * channel Plan Domain Code
+ * */
+
+/*
+ channel Plan Contents
+ Domain Code EEPROM Countries in Specific Domain
+ 2G RD 5G RD Bit[6:0] 2G 5G
+ Case Old Define 00h~1Fh Old Define Old Define
+ 1 2G_WORLD 5G_NULL 20h Worldwird 13 NA
+ 2 2G_ETSI1 5G_NULL 21h Europe 2G NA
+ 3 2G_FCC1 5G_NULL 22h US 2G NA
+ 4 2G_MKK1 5G_NULL 23h Japan 2G NA
+ 5 2G_ETSI2 5G_NULL 24h France 2G NA
+ 6 2G_FCC1 5G_FCC1 25h US 2G US 5G �K�j��{��
+ 7 2G_WORLD 5G_ETSI1 26h Worldwird 13 Europe �K�j��{��
+ 8 2G_MKK1 5G_MKK1 27h Japan 2G Japan 5G �K�j��{��
+ 9 2G_WORLD 5G_KCC1 28h Worldwird 13 Korea �K�j��{��
+ 10 2G_WORLD 5G_FCC2 29h Worldwird 13 US o/w DFS Channels
+ 11 2G_WORLD 5G_FCC3 30h Worldwird 13 India, Mexico
+ 12 2G_WORLD 5G_FCC4 31h Worldwird 13 Venezuela
+ 13 2G_WORLD 5G_FCC5 32h Worldwird 13 China
+ 14 2G_WORLD 5G_FCC6 33h Worldwird 13 Israel
+ 15 2G_FCC1 5G_FCC7 34h US 2G US/Canada �K�j��{��
+ 16 2G_WORLD 5G_ETSI2 35h Worldwird 13 Australia, New Zealand �K�j��{��
+ 17 2G_WORLD 5G_ETSI3 36h Worldwird 13 Russia
+ 18 2G_MKK1 5G_MKK2 37h Japan 2G Japan (W52, W53)
+ 19 2G_MKK1 5G_MKK3 38h Japan 2G Japan (W56)
+ 20 2G_FCC1 5G_NCC1 39h US 2G Taiwan �K�j��{��
+
+ NA 2G_WORLD 5G_FCC1 7F FCC FCC DFS Channels Realtek Define
+
+
+
+
+
+ 2.4G Regulatory Domains
+ Case 2G RD regulation Channels Frequencyes Note Countries in Specific Domain
+ 1 2G_WORLD ETSI 1~13 2412~2472 Passive scan CH 12, 13 Worldwird 13
+ 2 2G_ETSI1 ETSI 1~13 2412~2472 Europe
+ 3 2G_FCC1 FCC 1~11 2412~2462 US
+ 4 2G_MKK1 MKK 1~13, 14 2412~2472, 2484 Japan
+ 5 2G_ETSI2 ETSI 10~13 2457~2472 France
+
+
+
+
+ 5G Regulatory Domains
+ Case 5G RD regulation Channels Frequencyes Note Countries in Specific Domain
+ 1 5G_NULL NA NA NA Do not support 5GHz
+ 2 5G_ETSI1 ETSI "36~48, 52~64,
+ 100~140" "5180~5240, 5260~5230
+ 5500~5700" Band1, Ban2, Band3 Europe
+ 3 5G_ETSI2 ETSI "36~48, 52~64,
+ 100~140, 149~165" "5180~5240, 5260~5230
+ 5500~5700, 5745~5825" Band1, Ban2, Band3, Band4 Australia, New Zealand
+ 4 5G_ETSI3 ETSI "36~48, 52~64,
+ 100~132, 149~165"
+ "5180~5240, 5260~5230
+ 5500~5660, 5745~5825" Band1, Ban2, Band3(except CH 136, 140), Band4" Russia
+ 5 5G_FCC1 FCC "36~48, 52~64,
+ 100~140, 149~165"
+ "5180~5240, 5260~5230
+ 5500~5700, 5745~5825" Band1(5150~5250MHz),
+ Band2(5250~5350MHz),
+ Band3(5470~5725MHz),
+ Band4(5725~5850MHz)" US
+ 6 5G_FCC2 FCC 36~48, 149~165 5180~5240, 5745~5825 Band1, Band4 FCC o/w DFS Channels
+ 7 5G_FCC3 FCC "36~48, 52~64,
+ 149~165" "5180~5240, 5260~5230
+ 5745~5825" Band1, Ban2, Band4 India, Mexico
+ 8 5G_FCC4 FCC "36~48, 52~64,
+ 149~161" "5180~5240, 5260~5230
+ 5745~5805" Band1, Ban2,
+ Band4(except CH 165)" Venezuela
+ 9 5G_FCC5 FCC 149~165 5745~5825 Band4 China
+ 10 5G_FCC6 FCC 36~48, 52~64 5180~5240, 5260~5230 Band1, Band2 Israel
+ 11 5G_FCC7
+ 5G_IC1 FCC
+ IC" "36~48, 52~64,
+ 100~116, 136, 140,
+ 149~165" "5180~5240, 5260~5230
+ 5500~5580, 5680, 5700,
+ 5745~5825" "Band1, Band2,
+ Band3(except 5600~5650MHz),
+ Band4" "US
+ Canada"
+ 12 5G_KCC1 KCC "36~48, 52~64,
+ 100~124, 149~165" "5180~5240, 5260~5230
+ 5500~5620, 5745~5825" "Band1, Ban2,
+ Band3(5470~5650MHz),
+ Band4" Korea
+ 13 5G_MKK1 MKK "36~48, 52~64,
+ 100~140" "5180~5240, 5260~5230
+ 5500~5700" W52, W53, W56 Japan
+ 14 5G_MKK2 MKK 36~48, 52~64 5180~5240, 5260~5230 W52, W53 Japan (W52, W53)
+ 15 5G_MKK3 MKK 100~140 5500~5700 W56 Japan (W56)
+ 16 5G_NCC1 NCC "56~64,
+ 100~116, 136, 140,
+ 149~165" "5260~5320
+ 5500~5580, 5680, 5700,
+ 5745~5825" "Band2(except CH 52),
+ Band3(except 5600~5650MHz),
+ Band4" Taiwan
+
+
+*/
+
+/*
+ * 2.4G CHannel
+ *
+ *
+
+ 2.4G band Regulatory Domains RTL8192D
+ channel number channel Frequency US Canada Europe Spain France Japan Japan 20M 40M
+ (MHz) (FCC) (IC) (ETSI) (MPHPT)
+ 1 2412 v v v v v
+ 2 2417 v v v v v
+ 3 2422 v v v v v v
+ 4 2427 v v v v v v
+ 5 2432 v v v v v v
+ 6 2437 v v v v v v
+ 7 2442 v v v v v v
+ 8 2447 v v v v v v
+ 9 2452 v v v v v v
+ 10 2457 v v v v v v v v
+ 11 2462 v v v v v v v v
+ 12 2467 v v v v v
+ 13 2472 v v v v
+ 14 2484 v v
+
+
+*/
+
+
+/*
+ * 5G Operating channel
+ *
+ *
+
+ 5G band RTL8192D RTL8195 (Jaguar) Jaguar 2 Regulatory Domains
+ channel number channel Frequency Global Global Global "US
+(FCC 15.407)" "Canada
+(FCC, except 5.6~5.65GHz)" Argentina, Australia, New Zealand, Brazil, S. Africa (FCC/ETSI) "Europe
+(CE 301 893)" China India, Mexico, Singapore Israel, Turkey "Japan
+(MIC Item 19-3, 19-3-2)" Korea Russia, Ukraine "Taiwan
+(NCC)" Venezuela
+ (MHz) (20MHz) (20MHz) (40MHz) (80MHz) (160MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz)
+"band 1
+5.15GHz
+~
+5.25GHz" 36 5180 v v v v v Indoor Indoor v Indoor v Indoor Indoor v v v
+ 40 5200 v v v Indoor Indoor v Indoor v Indoor Indoor v v v
+ 44 5220 v v v v Indoor Indoor v Indoor v Indoor Indoor v v v
+ 48 5240 v v v Indoor Indoor v Indoor v Indoor Indoor v v v
+"band 2
+5.25GHz
+~
+5.35GHz
+(DFS)" 52 5260 v v v v v v v v Indoor v Indoor Indoor v v v
+ 56 5280 v v v v v v Indoor v Indoor Indoor v v Indoor v
+ 60 5300 v v v v v v v Indoor v Indoor Indoor v v Indoor v
+ 64 5320 v v v v v v Indoor v Indoor Indoor v v Indoor v
+
+"band 3
+5.47GHz
+~
+5.725GHz
+(DFS)" 100 5500 v v v v v v v v v v v v v
+ 104 5520 v v v v v v v v v v v
+ 108 5540 v v v v v v v v v v v v
+ 112 5560 v v v v v v v v v v v
+ 116 5580 v v v v v v v v v v v v v
+ 120 5600 v v v Indoor v Indoor v v v
+ 124 5620 v v v v Indoor v Indoor v v v
+ 128 5640 v v v Indoor v Indoor v v
+ 132 5660 v v v E v Indoor v Indoor v v
+ 136 5680 v v v v v v v v v
+ 140 5700 v v E v v v v v v v
+ 144 5720 E E E
+"band 4
+5.725GHz
+~
+5.85GHz
+(~5.9GHz)" 149 5745 v v v v v v v v v v v v v v
+ 153 5765 v v v v v v v v v v v v
+ 157 5785 v v v v v v v v v v v v v
+ 161 5805 v v v v v v v v v v v v
+ 165 5825 v v P P v v v v v v v v v
+ 169 5845 P P P
+ 173 5865 P P P P
+ 177 5885 P P P
+channel count 28 28 14 7 0 28 24 20 24 19 5 13 8 19 20 22 15 12
+ E: FCC accepted the ask for CH144 from Accord. PS: 160MHz �� 80MHz+80MHz��{�H Argentina Belgium (��Q��) India Israel Russia
+ P: Customer's requirement from James. Australia The Netherlands (����) Mexico Turkey Ukraine
+ New Zealand UK (�^��) Singapore
+ Brazil Switzerland (��h)
+
+
+*/
+
+/*---------------------------Define Local Constant---------------------------*/
+
+
+/* define Maximum Power v.s each band for each region
+ * ISRAEL
+ * Format:
+ * RT_CHANNEL_DOMAIN_Region ={{{chnl_start, chnl_end, Pwr_dB_Max}, {Chn2_Start, Chn2_end, Pwr_dB_Max}, {Chn3_Start, Chn3_end, Pwr_dB_Max}, {Chn4_Start, Chn4_end, Pwr_dB_Max}, {Chn5_Start, Chn5_end, Pwr_dB_Max}}, Limit_Num}
+ * RT_CHANNEL_DOMAIN_FCC ={{{01,11,30}, {36,48,17}, {52,64,24}, {100,140,24}, {149,165,30}}, 5}
+ * "NR" is non-release channle.
+ * Issue--- Israel--Russia--New Zealand
+ * DOMAIN_01= (2G_WORLD, 5G_NULL)
+ * DOMAIN_02= (2G_ETSI1, 5G_NULL)
+ * DOMAIN_03= (2G_FCC1, 5G_NULL)
+ * DOMAIN_04= (2G_MKK1, 5G_NULL)
+ * DOMAIN_05= (2G_ETSI2, 5G_NULL)
+ * DOMAIN_06= (2G_FCC1, 5G_FCC1)
+ * DOMAIN_07= (2G_WORLD, 5G_ETSI1)
+ * DOMAIN_08= (2G_MKK1, 5G_MKK1)
+ * DOMAIN_09= (2G_WORLD, 5G_KCC1)
+ * DOMAIN_10= (2G_WORLD, 5G_FCC2)
+ * DOMAIN_11= (2G_WORLD, 5G_FCC3)----india
+ * DOMAIN_12= (2G_WORLD, 5G_FCC4)----Venezuela
+ * DOMAIN_13= (2G_WORLD, 5G_FCC5)----China
+ * DOMAIN_14= (2G_WORLD, 5G_FCC6)----Israel
+ * DOMAIN_15= (2G_FCC1, 5G_FCC7)-----Canada
+ * DOMAIN_16= (2G_WORLD, 5G_ETSI2)---Australia
+ * DOMAIN_17= (2G_WORLD, 5G_ETSI3)---Russia
+ * DOMAIN_18= (2G_MKK1, 5G_MKK2)-----Japan
+ * DOMAIN_19= (2G_MKK1, 5G_MKK3)-----Japan
+ * DOMAIN_20= (2G_FCC1, 5G_NCC1)-----Taiwan
+ * DOMAIN_21= (2G_FCC1, 5G_NCC1)-----Taiwan */
+
+
+static struct _RT_CHANNEL_PLAN_MAXPWR chnl_plan_pwr_max_2g[] = {
+
+ /* 2G_WORLD, */
+ {{1, 13, 20}, 1},
+
+ /* 2G_ETSI1 */
+ {{1, 13, 20}, 1},
+
+ /* RT_CHANNEL_DOMAIN_ETSI */
+ {{{1, 11, 17}, {40, 56, 17}, {60, 128, 17}, {0, 0, 0}, {149, 165, 17}}, 4},
+
+ /* RT_CHANNEL_DOMAIN_MKK */
+ {{{1, 11, 17}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, 1},
+
+ /* Add new channel plan mex power table. */
+ /* ...... */
+};
+
+/*
+ * counter & Realtek channel plan transfer table.
+ * */
+struct _RT_CHANNEL_PLAN_COUNTRY_TRANSFER_TABLE rt_ctry_chnl_tbl[] = {
+
+ {
+ RT_CTRY_AL, /* "Albania�����ڥ���" */
+ "AL",
+ RT_2G_WORLD,
+ RT_5G_WORLD,
+ RT_CHANNEL_DOMAIN_UNDEFINED /* 2G/5G world. */
+ },
+}; /* rt_ctry_chnl_tbl */
diff --git a/drivers/staging/rtl8188eu/hal/rtchnlplan.h b/drivers/staging/rtl8188eu/hal/rtchnlplan.h
new file mode 100644
index 000000000000..5d9d049cd474
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/rtchnlplan.h
@@ -0,0 +1,615 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+
+#ifndef __RT_CHANNELPLAN_H__
+#define __RT_CHANNELPLAN_H__
+
+enum rt_channel_domain_new {
+
+ /* ===== Add new channel plan above this line =============== */
+
+ /* For new architecture we define different 2G/5G CH area for all country. */
+ /* 2.4 G only */
+ RT_CHANNEL_DOMAIN_2G_WORLD_5G_NULL = 0x20,
+ RT_CHANNEL_DOMAIN_2G_ETSI1_5G_NULL = 0x21,
+ RT_CHANNEL_DOMAIN_2G_FCC1_5G_NULL = 0x22,
+ RT_CHANNEL_DOMAIN_2G_MKK1_5G_NULL = 0x23,
+ RT_CHANNEL_DOMAIN_2G_ETSI2_5G_NULL = 0x24,
+ /* 2.4 G + 5G type 1 */
+ RT_CHANNEL_DOMAIN_2G_FCC1_5G_FCC1 = 0x25,
+ RT_CHANNEL_DOMAIN_2G_WORLD_5G_ETSI1 = 0x26,
+ /* RT_CHANNEL_DOMAIN_2G_WORLD_5G_ETSI1 = 0x27, */
+ /* ..... */
+
+ RT_CHANNEL_DOMAIN_MAX_NEW,
+
+};
+
+/*
+ *
+ *
+ *
+
+Countries "Country Abbreviation" Domain Code SKU's Ch# of 20MHz
+ 2G 5G Ch# of 40MHz
+"Albania�����ڥ���" AL Local Test
+
+"Algeria�����ΧQ��" DZ CE TCF
+
+"Antigua & Barbuda�w���ʮq&�ڥ��F" AG 2G_WORLD FCC TCF
+
+"Argentina���ڧ�" AR 2G_WORLD Local Test
+
+"Armenia�Ȭ�����" AM 2G_WORLD ETSI
+
+"Aruba���|�ڮq" AW 2G_WORLD FCC TCF
+
+"Australia�D�w" AU 2G_WORLD 5G_ETSI2
+
+"Austria���a�Q" AT 2G_WORLD 5G_ETSI1 CE
+
+"Azerbaijan�������" AZ 2G_WORLD CE TCF
+
+"Bahamas�ګ���" BS 2G_WORLD
+
+"Barbados�ڤڦh��" BB 2G_WORLD FCC TCF
+
+"Belgium��Q��" BE 2G_WORLD 5G_ETSI1 CE
+
+"Bermuda�ʼ}�F" BM 2G_WORLD FCC TCF
+
+"Brazil�ڦ�" BR 2G_WORLD Local Test
+
+"Bulgaria�O�[�Q��" BG 2G_WORLD 5G_ETSI1 CE
+
+"Canada�[���j" CA 2G_FCC1 5G_FCC7 IC / FCC IC / FCC
+
+"Cayman Islands�}�Ҹs�q" KY 2G_WORLD 5G_ETSI1 CE
+
+"Chile���Q" CL 2G_WORLD FCC TCF
+
+"China����" CN 2G_WORLD 5G_FCC5 �H��?�i2002�j353?
+
+"Columbia���ۤ��" CO 2G_WORLD Voluntary
+
+"Costa Rica�����F���[" CR 2G_WORLD FCC TCF
+
+"Cyprus�������" CY 2G_WORLD 5G_ETSI1 CE
+
+"Czech ���J" CZ 2G_WORLD 5G_ETSI1 CE
+
+"Denmark����" DK 2G_WORLD 5G_ETSI1 CE
+
+"Dominican Republic�h�����[�@�M��" DO 2G_WORLD FCC TCF
+
+"Egypt�J��" EG 2G_WORLD CE T CF
+
+"El Salvador�ĺ��˦h" SV 2G_WORLD Voluntary
+
+"Estonia�R�F����" EE 2G_WORLD 5G_ETSI1 CE
+
+"Finland����" FI 2G_WORLD 5G_ETSI1 CE
+
+"France�k��" FR 5G_E TSI1 CE
+
+"Germany�w��" DE 2G_WORLD 5G_ETSI1 CE
+
+"Greece ��þ" GR 2G_WORLD 5G_ETSI1 CE
+
+"Guam���q" GU 2G_WORLD
+
+"Guatemala�ʦa����" GT 2G_WORLD
+
+"Haiti���a" HT 2G_WORLD FCC TCF
+
+"Honduras�����Դ�" HN 2G_WORLD FCC TCF
+
+"Hungary�I���Q" HU 2G_WORLD 5G_ETSI1 CE
+
+"Iceland�B�q" IS 2G_WORLD 5G_ETSI1 CE
+
+"India�L��" 2G_WORLD 5G_FCC3 FCC/CE TCF
+
+"Ireland�R����" IE 2G_WORLD 5G_ETSI1 CE
+
+"Israel�H��C" IL 5G_F CC6 CE TCF
+
+"Italy�q�j�Q" IT 2G_WORLD 5G_ETSI1 CE
+
+"Japan�饻" JP 2G_MKK1 5G_MKK1 MKK MKK
+
+"Korea����" KR 2G_WORLD 5G_KCC1 KCC KCC
+
+"Latvia�Բ����" LV 2G_WORLD 5G_ETSI1 CE
+
+"Lithuania�߳��{" LT 2G_WORLD 5G_ETSI1 CE
+
+"Luxembourg�c�˳�" LU 2G_WORLD 5G_ETSI1 CE
+
+"Malaysia���Ӧ��" MY 2G_WORLD Local Test
+
+"Malta�����L" MT 2G_WORLD 5G_ETSI1 CE
+
+"Mexico�����" MX 2G_WORLD 5G_FCC3 Local Test
+
+"Morocco������" MA CE TCF
+
+"Netherlands����" NL 2G_WORLD 5G_ETSI1 CE
+
+"New Zealand���" NZ 2G_WORLD 5G_ETSI2
+
+"Norway����" NO 2G_WORLD 5G_ETSI1 CE
+
+"Panama�ڮ��� " PA 2G_FCC1 Voluntary
+
+"Philippines��߻�" PH 2G_WORLD FCC TCF
+
+"Poland�i��" PL 2G_WORLD 5G_ETSI1 CE
+
+"Portugal�����" PT 2G_WORLD 5G_ETSI1 CE
+
+"Romaniaù������" RO 2G_WORLD 5G_ETSI1 CE
+
+"Russia�Xù��" RU 2G_WORLD 5G_ETSI3 CE TCF
+
+"Saudi Arabia�F�a���ԧB" SA 2G_WORLD CE TCF
+
+"Singapore�s�[�Y" SG 2G_WORLD
+
+"Slovakia������J" SK 2G_WORLD 5G_ETSI1 CE
+
+"Slovenia����������" SI 2G_WORLD 5G_ETSI1 CE
+
+"South Africa�n�D" ZA 2G_WORLD CE TCF
+
+"Spain��Z��" ES 5G_ETSI1 CE
+
+"Sweden���" SE 2G_WORLD 5G_ETSI1 CE
+
+"Switzerland��h" CH 2G_WORLD 5G_ETSI1 CE
+
+"Taiwan�O�W" TW 2G_FCC1 5G_NCC1 NCC
+
+"Thailand����" TH 2G_WORLD FCC/CE TCF
+
+"Turkey�g�ը�" TR 2G_WORLD
+
+"Ukraine�Q�J��" UA 2G_WORLD Local Test
+
+"United Kingdom�^��" GB 2G_WORLD 5G_ETSI1 CE ETSI
+
+"United States����" US 2G_FCC1 5G_FCC7 FCC FCC
+
+"Venezuela�e�����" VE 2G_WORLD 5G_FCC4 FCC TCF
+
+"Vietnam�V�n" VN 2G_WORLD FCC/CE TCF
+
+
+
+*/
+
+/* counter abbervation. */
+enum rt_country_name {
+ RT_CTRY_AL, /* "Albania�����ڥ���" */
+ RT_CTRY_DZ, /* "Algeria�����ΧQ��" */
+ RT_CTRY_AG, /* "Antigua & Barbuda�w���ʮq&�ڥ��F" */
+ RT_CTRY_AR, /* "Argentina���ڧ�" */
+ RT_CTRY_AM, /* "Armenia�Ȭ�����" */
+ RT_CTRY_AW, /* "Aruba���|�ڮq" */
+ RT_CTRY_AU, /* "Australia�D�w" */
+ RT_CTRY_AT, /* "Austria���a�Q" */
+ RT_CTRY_AZ, /* "Azerbaijan�������" */
+ RT_CTRY_BS, /* "Bahamas�ګ���" */
+ RT_CTRY_BB, /* "Barbados�ڤڦh��" */
+ RT_CTRY_BE, /* "Belgium��Q��" */
+ RT_CTRY_BM, /* "Bermuda�ʼ}�F" */
+ RT_CTRY_BR, /* "Brazil�ڦ�" */
+ RT_CTRY_BG, /* "Bulgaria�O�[�Q��" */
+ RT_CTRY_CA, /* "Canada�[���j" */
+ RT_CTRY_KY, /* "Cayman Islands�}�Ҹs�q" */
+ RT_CTRY_CL, /* "Chile���Q" */
+ RT_CTRY_CN, /* "China����" */
+ RT_CTRY_CO, /* "Columbia���ۤ��" */
+ RT_CTRY_CR, /* "Costa Rica�����F���[" */
+ RT_CTRY_CY, /* "Cyprus�������" */
+ RT_CTRY_CZ, /* "Czech ���J" */
+ RT_CTRY_DK, /* "Denmark����" */
+ RT_CTRY_DO, /* "Dominican Republic�h�����[�@�M��" */
+ RT_CTRY_CE, /* "Egypt�J��" EG 2G_WORLD */
+ RT_CTRY_SV, /* "El Salvador�ĺ��˦h" */
+ RT_CTRY_EE, /* "Estonia�R�F����" */
+ RT_CTRY_FI, /* "Finland����" */
+ RT_CTRY_FR, /* "France�k��" */
+ RT_CTRY_DE, /* "Germany�w��" */
+ RT_CTRY_GR, /* "Greece ��þ" */
+ RT_CTRY_GU, /* "Guam���q" */
+ RT_CTRY_GT, /* "Guatemala�ʦa����" */
+ RT_CTRY_HT, /* "Haiti���a" */
+ RT_CTRY_HN, /* "Honduras�����Դ�" */
+ RT_CTRY_HU, /* "Hungary�I���Q" */
+ RT_CTRY_IS, /* "Iceland�B�q" */
+ RT_CTRY_IN, /* "India�L��" */
+ RT_CTRY_IE, /* "Ireland�R����" */
+ RT_CTRY_IL, /* "Israel�H��C" */
+ RT_CTRY_IT, /* "Italy�q�j�Q" */
+ RT_CTRY_JP, /* "Japan�饻" */
+ RT_CTRY_KR, /* "Korea����" */
+ RT_CTRY_LV, /* "Latvia�Բ����" */
+ RT_CTRY_LT, /* "Lithuania�߳��{" */
+ RT_CTRY_LU, /* "Luxembourg�c�˳�" */
+ RT_CTRY_MY, /* "Malaysia���Ӧ��" */
+ RT_CTRY_MT, /* "Malta�����L" */
+ RT_CTRY_MX, /* "Mexico�����" */
+ RT_CTRY_MA, /* "Morocco������" */
+ RT_CTRY_NL, /* "Netherlands����" */
+ RT_CTRY_NZ, /* "New Zealand���" */
+ RT_CTRY_NO, /* "Norway����" */
+ RT_CTRY_PA, /* "Panama�ڮ��� " */
+ RT_CTRY_PH, /* "Philippines��߻�" */
+ RT_CTRY_PL, /* "Poland�i��" */
+ RT_CTRY_PT, /* "Portugal�����" */
+ RT_CTRY_RO, /* "Romaniaù������" */
+ RT_CTRY_RU, /* "Russia�Xù��" */
+ RT_CTRY_SA, /* "Saudi Arabia�F�a���ԧB" */
+ RT_CTRY_SG, /* "Singapore�s�[�Y" */
+ RT_CTRY_SK, /* "Slovakia������J" */
+ RT_CTRY_SI, /* "Slovenia����������" */
+ RT_CTRY_ZA, /* "South Africa�n�D" */
+ RT_CTRY_ES, /* "Spain��Z��" */
+ RT_CTRY_SE, /* "Sweden���" */
+ RT_CTRY_CH, /* "Switzerland��h" */
+ RT_CTRY_TW, /* "Taiwan�O�W" */
+ RT_CTRY_TH, /* "Thailand����" */
+ RT_CTRY_TR, /* "Turkey�g�ը�" */
+ RT_CTRY_UA, /* "Ukraine�Q�J��" */
+ RT_CTRY_GB, /* "United Kingdom�^��" */
+ RT_CTRY_US, /* "United States����" */
+ RT_CTRY_VE, /* "Venezuela�e�����" */
+ RT_CTRY_VN, /* "Vietnam�V�n" */
+ RT_CTRY_MAX,
+
+};
+
+/* Scan type including active and passive scan. */
+enum rt_scan_type_new {
+ SCAN_NULL,
+ SCAN_ACT,
+ SCAN_PAS,
+ SCAN_BOTH,
+};
+
+
+/* Power table sample. */
+
+struct _RT_CHNL_PLAN_LIMIT {
+ u16 chnl_start;
+ u16 chnl_end;
+
+ u16 freq_start;
+ u16 freq_end;
+};
+
+
+/*
+ * 2.4G Regulatory Domains
+ * */
+enum rt_regulation_2g {
+ RT_2G_NULL,
+ RT_2G_WORLD,
+ RT_2G_ETSI1,
+ RT_2G_FCC1,
+ RT_2G_MKK1,
+ RT_2G_ETSI2
+
+};
+
+
+/* typedef struct _RT_CHANNEL_BEHAVIOR
+ * {
+ * u8 chnl;
+ * enum rt_scan_type_new
+ *
+ * }RT_CHANNEL_BEHAVIOR, *PRT_CHANNEL_BEHAVIOR; */
+
+/* typedef struct _RT_CHANNEL_PLAN_TYPE
+ * {
+ * RT_CHANNEL_BEHAVIOR
+ * u8 Chnl_num;
+ * }RT_CHNL_PLAN_TYPE, *PRT_CHNL_PLAN_TYPE; */
+
+/*
+ * 2.4G channel number
+ * channel definition & number
+ * */
+#define CHNL_RT_2G_NULL \
+ {0}, 0
+#define CHNL_RT_2G_WORLD \
+ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13
+#define CHNL_RT_2G_WORLD_TEST \
+ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13
+
+#define CHNL_RT_2G_EFSI1 \
+ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13
+#define CHNL_RT_2G_FCC1 \
+ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11
+#define CHNL_RT_2G_MKK1 \
+ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14
+#define CHNL_RT_2G_ETSI2 \
+ {10, 11, 12, 13}, 4
+
+/*
+ * 2.4G channel active or passive scan.
+ * */
+#define CHNL_RT_2G_NULL_SCAN_TYPE \
+ {SCAN_NULL}
+#define CHNL_RT_2G_WORLD_SCAN_TYPE \
+ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}
+#define CHNL_RT_2G_EFSI1_SCAN_TYPE \
+ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+#define CHNL_RT_2G_FCC1_SCAN_TYPE \
+ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+#define CHNL_RT_2G_MKK1_SCAN_TYPE \
+ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+#define CHNL_RT_2G_ETSI2_SCAN_TYPE \
+ {1, 1, 1, 1}
+
+
+/*
+ * 2.4G band & Frequency Section
+ * Freqency start & end / band number
+ * */
+#define FREQ_RT_2G_NULL \
+ {0}, 0
+/* Passive scan CH 12, 13 */
+#define FREQ_RT_2G_WORLD \
+ {2412, 2472}, 1
+#define FREQ_RT_2G_EFSI1 \
+ {2412, 2472}, 1
+#define FREQ_RT_2G_FCC1 \
+ {2412, 2462}, 1
+#define FREQ_RT_2G_MKK1 \
+ {2412, 2484}, 1
+#define FREQ_RT_2G_ETSI2 \
+ {2457, 2472}, 1
+
+
+/*
+ * 5G Regulatory Domains
+ * */
+enum rt_regulation_5g {
+ RT_5G_NULL,
+ RT_5G_WORLD,
+ RT_5G_ETSI1,
+ RT_5G_ETSI2,
+ RT_5G_ETSI3,
+ RT_5G_FCC1,
+ RT_5G_FCC2,
+ RT_5G_FCC3,
+ RT_5G_FCC4,
+ RT_5G_FCC5,
+ RT_5G_FCC6,
+ RT_5G_FCC7,
+ RT_5G_IC1,
+ RT_5G_KCC1,
+ RT_5G_MKK1,
+ RT_5G_MKK2,
+ RT_5G_MKK3,
+ RT_5G_NCC1,
+
+};
+
+/*
+ * 5G channel number
+ * */
+#define CHNL_RT_5G_NULL \
+ {0}, 0
+#define CHNL_RT_5G_WORLD \
+ {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19
+#define CHNL_RT_5G_ETSI1 \
+ {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24
+#define CHNL_RT_5G_ETSI2 \
+ {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22
+#define CHNL_RT_5G_ETSI3 \
+ {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24
+#define CHNL_RT_5G_FCC1 \
+ {36, 40, 44, 48, 149, 153, 157, 161, 165}, 9
+#define CHNL_RT_5G_FCC2 \
+ {36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13
+#define CHNL_RT_5G_FCC3 \
+ {36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12
+#define CHNL_RT_5G_FCC4 \
+ {149, 153, 157, 161, 165}, 5
+#define CHNL_RT_5G_FCC5 \
+ {36, 40, 44, 48, 52, 56, 60, 64}, 8
+#define CHNL_RT_5G_FCC6 \
+ {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20
+#define CHNL_RT_5G_FCC7 \
+ {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20
+#define CHNL_RT_5G_IC1 \
+ {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 20
+#define CHNL_RT_5G_KCC1 \
+ {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19
+#define CHNL_RT_5G_MKK1 \
+ {36, 40, 44, 48, 52, 56, 60, 64}, 8
+#define CHNL_RT_5G_MKK2 \
+ {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11
+#define CHNL_RT_5G_MKK3 \
+ {56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 24
+#define CHNL_RT_5G_NCC1 \
+ {56, 60, 64, 149, 153, 157, 161, 165}, 8
+
+/*
+ * 5G channel active or passive scan.
+ * */
+#define CHNL_RT_5G_NULL_SCAN_TYPE \
+ {SCAN_NULL}
+#define CHNL_RT_5G_WORLD_SCAN_TYPE \
+ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+#define CHNL_RT_5G_ETSI1_SCAN_TYPE \
+ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+#define CHNL_RT_5G_ETSI2_SCAN_TYPE \
+ {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22
+#define CHNL_RT_5G_ETSI3_SCAN_TYPE \
+ {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24
+#define CHNL_RT_5G_FCC1_SCAN_TYPE \
+ {36, 40, 44, 48, 149, 153, 157, 161, 165}, 9
+#define CHNL_RT_5G_FCC2_SCAN_TYPE \
+ {36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13
+#define CHNL_RT_5G_FCC3_SCAN_TYPE \
+ {36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12
+#define CHNL_RT_5G_FCC4_SCAN_TYPE \
+ {149, 153, 157, 161, 165}, 5
+#define CHNL_RT_5G_FCC5_SCAN_TYPE \
+ {36, 40, 44, 48, 52, 56, 60, 64}, 8
+#define CHNL_RT_5G_FCC6_SCAN_TYPE \
+ {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20
+#define CHNL_RT_5G_FCC7_SCAN_TYPE \
+ {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20
+#define CHNL_RT_5G_IC1_SCAN_TYPE \
+ {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 20
+#define CHNL_RT_5G_KCC1_SCAN_TYPE \
+ {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19
+#define CHNL_RT_5G_MKK1_SCAN_TYPE \
+ {36, 40, 44, 48, 52, 56, 60, 64}, 8
+#define CHNL_RT_5G_MKK2_SCAN_TYPE \
+ {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11
+#define CHNL_RT_5G_MKK3_SCAN_TYPE \
+ {56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 24
+#define CHNL_RT_5G_NCC1_SCAN_TYPE \
+ {56, 60, 64, 149, 153, 157, 161, 165}, 8
+
+/*
+ * Global regulation
+ * */
+enum rt_regulation_cmn {
+ RT_WORLD,
+ RT_FCC,
+ RT_MKK,
+ RT_ETSI,
+ RT_IC,
+ RT_CE,
+ RT_NCC,
+
+};
+
+
+
+/*
+ * Special requirement for different regulation domain.
+ * For internal test or customerize special request.
+ * */
+enum rt_chnlplan_sreq {
+ RT_SREQ_NA = 0x0,
+ RT_SREQ_2G_ADHOC_11N = 0x00000001,
+ RT_SREQ_2G_ADHOC_11B = 0x00000002,
+ RT_SREQ_2G_ALL_PASS = 0x00000004,
+ RT_SREQ_2G_ALL_ACT = 0x00000008,
+ RT_SREQ_5G_ADHOC_11N = 0x00000010,
+ RT_SREQ_5G_ADHOC_11AC = 0x00000020,
+ RT_SREQ_5G_ALL_PASS = 0x00000040,
+ RT_SREQ_5G_ALL_ACT = 0x00000080,
+ RT_SREQ_C1_PLAN = 0x00000100,
+ RT_SREQ_C2_PLAN = 0x00000200,
+ RT_SREQ_C3_PLAN = 0x00000400,
+ RT_SREQ_C4_PLAN = 0x00000800,
+ RT_SREQ_NFC_ON = 0x00001000,
+ RT_SREQ_MASK = 0x0000FFFF, /* Requirements bit mask */
+
+};
+
+
+/*
+ * enum rt_country_name & enum rt_regulation_2g & enum rt_regulation_5g transfer table
+ *
+ * */
+struct _RT_CHANNEL_PLAN_COUNTRY_TRANSFER_TABLE {
+ /* */
+ /* Define countery domain and corresponding */
+ /* */
+ enum rt_country_name country_enum;
+ char country_name[3];
+
+ /* char Domain_Name[12]; */
+ enum rt_regulation_2g domain_2g;
+
+ enum rt_regulation_5g domain_5g;
+
+ RT_CHANNEL_DOMAIN rt_ch_domain;
+ /* u8 Country_Area; */
+
+};
+
+
+#define RT_MAX_CHNL_NUM_2G 13
+#define RT_MAX_CHNL_NUM_5G 44
+
+/* Power table sample. */
+
+struct _RT_CHNL_PLAN_PWR_LIMIT {
+ u16 chnl_start;
+ u16 chnl_end;
+ u8 db_max;
+ u16 m_w_max;
+};
+
+
+#define RT_MAX_BAND_NUM 5
+
+struct _RT_CHANNEL_PLAN_MAXPWR {
+ /* STRING_T */
+ struct _RT_CHNL_PLAN_PWR_LIMIT chnl[RT_MAX_BAND_NUM];
+ u8 band_useful_num;
+
+
+};
+
+
+/*
+ * Power By rate Table.
+ * */
+
+
+
+struct _RT_CHANNEL_PLAN_NEW {
+ /* */
+ /* Define countery domain and corresponding */
+ /* */
+ /* char country_name[36]; */
+ /* u8 country_enum; */
+
+ /* char Domain_Name[12]; */
+
+
+ struct _RT_CHANNEL_PLAN_COUNTRY_TRANSFER_TABLE *p_ctry_transfer;
+
+ RT_CHANNEL_DOMAIN rt_ch_domain;
+
+ enum rt_regulation_2g domain_2g;
+
+ enum rt_regulation_5g domain_5g;
+
+ enum rt_regulation_cmn regulator;
+
+ enum rt_chnlplan_sreq chnl_sreq;
+
+ /* struct _RT_CHNL_PLAN_LIMIT RtChnl; */
+
+ u8 chnl_2g[MAX_CHANNEL_NUM]; /* CHNL_RT_2G_WORLD */
+ u8 len_2g;
+ u8 chnl_2g_scan_tp[MAX_CHANNEL_NUM]; /* CHNL_RT_2G_WORLD_SCAN_TYPE */
+ /* u8 Freq2G[2]; */ /* FREQ_RT_2G_WORLD */
+
+ u8 chnl_5g[MAX_CHANNEL_NUM];
+ u8 len_5g;
+ u8 chnl_5g_scan_tp[MAX_CHANNEL_NUM];
+ /* u8 Freq2G[2]; */ /* FREQ_RT_2G_WORLD */
+
+ struct _RT_CHANNEL_PLAN_MAXPWR chnl_max_pwr;
+
+
+};
+
+
+#endif /* __RT_CHANNELPLAN_H__ */
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
new file mode 100644
index 000000000000..51863cde7b1c
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
@@ -0,0 +1,790 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _RTL8188E_CMD_C_
+
+#include <drv_types.h>
+#include <rtl8188e_hal.h>
+#include "hal_com_h2c.h"
+
+#define CONFIG_H2C_EF
+
+#define RTL88E_MAX_H2C_BOX_NUMS 4
+#define RTL88E_MAX_CMD_LEN 7
+#define RTL88E_MESSAGE_BOX_SIZE 4
+#define RTL88E_EX_MESSAGE_BOX_SIZE 4
+
+static u8 _is_fw_read_cmd_down(_adapter *padapter, u8 msgbox_num)
+{
+ u8 read_down = false;
+ int retry_cnts = 100;
+
+ u8 valid;
+
+ /* RTW_INFO(" _is_fw_read_cmd_down ,reg_1cc(%x),msg_box(%d)...\n",rtw_read8(padapter,REG_HMETFR),msgbox_num); */
+
+ do {
+ valid = rtw_read8(padapter, REG_HMETFR) & BIT(msgbox_num);
+ if (0 == valid)
+ read_down = true;
+ else
+ rtw_msleep_os(1);
+ } while ((!read_down) && (retry_cnts--));
+
+ return read_down;
+
+}
+
+
+/*****************************************
+* H2C Msg format :
+* 0x1DF - 0x1D0
+*| 31 - 8 | 7-5 4 - 0 |
+*| h2c_msg |Class_ID CMD_ID |
+*
+* Extend 0x1FF - 0x1F0
+*|31 - 0 |
+*|ext_msg|
+******************************************/
+s32 FillH2CCmd_88E(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ u8 h2c_box_num;
+ u32 msgbox_addr;
+ u32 msgbox_ex_addr = 0;
+ u8 cmd_idx, ext_cmd_len;
+ u32 h2c_cmd = 0;
+ u32 h2c_cmd_ex = 0;
+ s32 ret = _FAIL;
+
+
+ padapter = GET_PRIMARY_ADAPTER(padapter);
+ pHalData = GET_HAL_DATA(padapter);
+
+ if (padapter->bFWReady == false) {
+ RTW_INFO("FillH2CCmd_88E(): return H2C cmd because fw is not ready\n");
+ return ret;
+ }
+
+ _enter_critical_mutex(&(dvobj->h2c_fwcmd_mutex), NULL);
+
+ if (!pCmdBuffer)
+ goto exit;
+ if (CmdLen > RTL88E_MAX_CMD_LEN)
+ goto exit;
+ if (rtw_is_surprise_removed(padapter))
+ goto exit;
+
+ /* pay attention to if race condition happened in H2C cmd setting. */
+ do {
+ h2c_box_num = pHalData->LastHMEBoxNum;
+
+ if (!_is_fw_read_cmd_down(padapter, h2c_box_num)) {
+ RTW_INFO(" fw read cmd failed...\n");
+ goto exit;
+ }
+
+ *(u8 *)(&h2c_cmd) = ElementID;
+
+ if (CmdLen <= 3)
+ memcpy((u8 *)(&h2c_cmd) + 1, pCmdBuffer, CmdLen);
+ else {
+ memcpy((u8 *)(&h2c_cmd) + 1, pCmdBuffer, 3);
+ ext_cmd_len = CmdLen - 3;
+ memcpy((u8 *)(&h2c_cmd_ex), pCmdBuffer + 3, ext_cmd_len);
+
+ /* Write Ext command */
+ msgbox_ex_addr = REG_HMEBOX_EXT_0 + (h2c_box_num * RTL88E_EX_MESSAGE_BOX_SIZE);
+#ifdef CONFIG_H2C_EF
+ for (cmd_idx = 0; cmd_idx < ext_cmd_len; cmd_idx++)
+ rtw_write8(padapter, msgbox_ex_addr + cmd_idx, *((u8 *)(&h2c_cmd_ex) + cmd_idx));
+#else
+ h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex);
+ rtw_write32(padapter, msgbox_ex_addr, h2c_cmd_ex);
+#endif
+ }
+ /* Write command */
+ msgbox_addr = REG_HMEBOX_0 + (h2c_box_num * RTL88E_MESSAGE_BOX_SIZE);
+#ifdef CONFIG_H2C_EF
+ for (cmd_idx = 0; cmd_idx < RTL88E_MESSAGE_BOX_SIZE; cmd_idx++)
+ rtw_write8(padapter, msgbox_addr + cmd_idx, *((u8 *)(&h2c_cmd) + cmd_idx));
+#else
+ h2c_cmd = le32_to_cpu(h2c_cmd);
+ rtw_write32(padapter, msgbox_addr, h2c_cmd);
+#endif
+
+
+ /* RTW_INFO("MSG_BOX:%d,CmdLen(%d), reg:0x%x =>h2c_cmd:0x%x, reg:0x%x =>h2c_cmd_ex:0x%x ..\n" */
+ /* ,pHalData->LastHMEBoxNum ,CmdLen,msgbox_addr,h2c_cmd,msgbox_ex_addr,h2c_cmd_ex); */
+
+ pHalData->LastHMEBoxNum = (h2c_box_num + 1) % RTL88E_MAX_H2C_BOX_NUMS;
+
+ } while (0);
+
+ ret = _SUCCESS;
+
+exit:
+
+ _exit_critical_mutex(&(dvobj->h2c_fwcmd_mutex), NULL);
+
+
+ return ret;
+}
+
+static u8 rtl8192c_h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
+{
+ u8 ElementID, CmdLen;
+ u8 *pCmdBuffer;
+ struct cmd_msg_parm *pcmdmsg;
+
+ if (!pbuf)
+ return H2C_PARAMETERS_ERROR;
+
+ pcmdmsg = (struct cmd_msg_parm *)pbuf;
+ ElementID = pcmdmsg->eid;
+ CmdLen = pcmdmsg->sz;
+ pCmdBuffer = pcmdmsg->buf;
+
+ FillH2CCmd_88E(padapter, ElementID, CmdLen, pCmdBuffer);
+
+ return H2C_SUCCESS;
+}
+
+u8 rtl8188e_set_rssi_cmd(_adapter *padapter, u8 *param)
+{
+ u8 res = _SUCCESS;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ if (pHalData->fw_ractrl == false) {
+ RTW_INFO("==>%s fw dont support RA\n", __func__);
+ return _FAIL;
+ }
+
+ *((__le32 *) param) = cpu_to_le32(*((u32 *) param));
+ FillH2CCmd_88E(padapter, H2C_RSSI_REPORT, 3, param);
+
+ return res;
+}
+
+u8 rtl8188e_set_raid_cmd(_adapter *padapter, u32 bitmap, u8 *arg, u8 bw)
+{
+ u8 res = _SUCCESS;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct sta_info *psta = NULL;
+ struct macid_ctl_t *macid_ctl = &padapter->dvobj->macid_ctl;
+ u8 macid, init_rate, raid, shortGIrate = false;
+ u8 H2CCommand[7] = {0};
+ u8 ignore_bw = false;
+
+ if (pHalData->fw_ractrl == false) {
+ RTW_INFO("==>%s fw dont support RA\n", __func__);
+ return _FAIL;
+ }
+
+ macid = arg[0];
+ raid = arg[1];
+ shortGIrate = arg[2] & 0x0F;
+ ignore_bw = arg[2] >> 4;
+ init_rate = arg[3];
+
+ if (macid < macid_ctl->num)
+ psta = macid_ctl->sta[macid];
+ if (psta == NULL) {
+ RTW_PRINT(FUNC_ADPT_FMT" macid:%u, sta is NULL\n"
+ , FUNC_ADPT_ARG(padapter), macid);
+ return _FAIL;
+ }
+
+ H2CCommand[0] = macid;
+ H2CCommand[1] = raid | (shortGIrate ? 0x80 : 0x00) ;
+ H2CCommand[2] = bw & 0x03; /* BW; */
+ if (ignore_bw)
+ H2CCommand[2] |= BIT(3);
+
+#ifdef CONFIG_INTEL_PROXIM
+ if (padapter->proximity.proxim_on == true)
+ pHalData->bDisableTXPowerTraining = false;
+#endif
+
+ /* DisableTXPowerTraining */
+ if (pHalData->bDisableTXPowerTraining) {
+ H2CCommand[2] |= BIT6;
+ RTW_INFO("%s,Disable PWT by driver\n", __func__);
+ } else {
+ struct PHY_DM_STRUCT *pDM_OutSrc = &pHalData->odmpriv;
+
+ if (pDM_OutSrc->is_disable_power_training) {
+ H2CCommand[2] |= BIT6;
+ RTW_INFO("%s,Disable PWT by DM\n", __func__);
+ }
+ }
+
+ H2CCommand[3] = (u8)(bitmap & 0x000000ff);
+ H2CCommand[4] = (u8)((bitmap & 0x0000ff00) >> 8);
+ H2CCommand[5] = (u8)((bitmap & 0x00ff0000) >> 16);
+ H2CCommand[6] = (u8)((bitmap & 0xff000000) >> 24);
+
+ FillH2CCmd_88E(padapter, H2C_DM_MACID_CFG, 7, H2CCommand);
+
+ /* The firmware Rate Adaption function is triggered by TBTT INT, so to */
+ /* enable the rate adaption, we need to enable the hardware Beacon function Reg 0x550[3] */
+ /* SetBcnCtrlReg(padapter, BIT3, 0); */
+ rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | BIT3);
+
+ return res;
+
+}
+
+void rtl8188e_set_FwPwrMode_cmd(PADAPTER padapter, u8 Mode)
+{
+ SETPWRMODE_PARM H2CSetPwrMode;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+ u8 RLBM = 0; /* 0:Min, 1:Max , 2:User define */
+
+ RTW_INFO("%s: Mode=%d SmartPS=%d UAPSD=%d\n", __func__,
+ Mode, pwrpriv->smart_ps, padapter->registrypriv.uapsd_enable);
+
+ H2CSetPwrMode.AwakeInterval = 2; /* DTIM = 1 */
+
+ switch (Mode) {
+ case PS_MODE_ACTIVE:
+ H2CSetPwrMode.Mode = 0;
+ break;
+ case PS_MODE_MIN:
+ H2CSetPwrMode.Mode = 1;
+ break;
+ case PS_MODE_MAX:
+ RLBM = 1;
+ H2CSetPwrMode.Mode = 1;
+ break;
+ case PS_MODE_DTIM:
+ RLBM = 2;
+ H2CSetPwrMode.AwakeInterval = 3; /* DTIM = 2 */
+ H2CSetPwrMode.Mode = 1;
+ break;
+ case PS_MODE_UAPSD_WMM:
+ H2CSetPwrMode.Mode = 2;
+ break;
+ default:
+ H2CSetPwrMode.Mode = 0;
+ break;
+ }
+
+ /* H2CSetPwrMode.Mode = Mode; */
+
+ H2CSetPwrMode.SmartPS_RLBM = (((pwrpriv->smart_ps << 4) & 0xf0) | (RLBM & 0x0f));
+
+ H2CSetPwrMode.bAllQueueUAPSD = padapter->registrypriv.uapsd_enable;
+
+ if (Mode > 0) {
+ H2CSetPwrMode.PwrState = 0x00;/* AllON(0x0C), RFON(0x04), RFOFF(0x00) */
+#ifdef CONFIG_EXT_CLK
+ H2CSetPwrMode.Mode |= BIT(7);/* supporting 26M XTAL CLK_Request feature. */
+#endif /* CONFIG_EXT_CLK */
+ } else
+ H2CSetPwrMode.PwrState = 0x0C;/* AllON(0x0C), RFON(0x04), RFOFF(0x00) */
+
+ FillH2CCmd_88E(padapter, H2C_PS_PWR_MODE, sizeof(H2CSetPwrMode), (u8 *)&H2CSetPwrMode);
+
+
+}
+
+static void ConstructBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
+{
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *fctrl;
+ u32 rate_len, pktlen;
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
+ u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+
+ /* RTW_INFO("%s\n", __func__); */
+
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ fctrl = &(pwlanhdr->frame_ctl);
+ *(fctrl) = 0;
+
+ memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+ memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
+
+ SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
+ /* pmlmeext->mgnt_seq++; */
+ set_frame_sub_type(pframe, WIFI_BEACON);
+
+ pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
+ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+
+ /* timestamp will be inserted by hardware */
+ pframe += 8;
+ pktlen += 8;
+
+ /* beacon interval: 2 bytes */
+ memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
+
+ pframe += 2;
+ pktlen += 2;
+
+ /* capability info: 2 bytes */
+ memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
+
+ pframe += 2;
+ pktlen += 2;
+
+ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
+ /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
+ pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
+ memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
+
+ goto _ConstructBeacon;
+ }
+
+ /* below for ad-hoc mode */
+
+ /* SSID */
+ pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
+
+ /* supported rates... */
+ rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
+ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
+
+ /* DS parameter set */
+ pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
+
+ if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
+ u32 ATIMWindow;
+ /* IBSS Parameter Set... */
+ /* ATIMWindow = cur->Configuration.ATIMWindow; */
+ ATIMWindow = 0;
+ pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
+ }
+
+
+ /* todo: ERP IE */
+
+
+ /* EXTERNDED SUPPORTED RATE */
+ if (rate_len > 8)
+ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
+
+
+ /* todo:HT for adhoc */
+
+_ConstructBeacon:
+
+ if ((pktlen + TXDESC_SIZE) > 512) {
+ RTW_INFO("beacon frame too large\n");
+ return;
+ }
+
+ *pLength = pktlen;
+
+ /* RTW_INFO("%s bcn_sz=%d\n", __func__, pktlen); */
+
+}
+
+static void ConstructPSPoll(_adapter *padapter, u8 *pframe, u32 *pLength)
+{
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *fctrl;
+ u32 pktlen;
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ /* RTW_INFO("%s\n", __func__); */
+
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ /* Frame control. */
+ fctrl = &(pwlanhdr->frame_ctl);
+ *(fctrl) = 0;
+ SetPwrMgt(fctrl);
+ set_frame_sub_type(pframe, WIFI_PSPOLL);
+
+ /* AID. */
+ set_duration(pframe, (pmlmeinfo->aid | 0xc000));
+
+ /* BSSID. */
+ memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+
+ /* TA. */
+ memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+
+ *pLength = 16;
+}
+
+static void ConstructNullFunctionData(
+ PADAPTER padapter,
+ u8 *pframe,
+ u32 *pLength,
+ u8 *StaAddr,
+ u8 bQoS,
+ u8 AC,
+ u8 bEosp,
+ u8 bForcePowerSave)
+{
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ __le16 *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);
+
+
+ /* RTW_INFO("%s:%d\n", __func__, bForcePowerSave); */
+
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ fctrl = &pwlanhdr->frame_ctl;
+ *(fctrl) = 0;
+ if (bForcePowerSave)
+ SetPwrMgt(fctrl);
+
+ switch (cur_network->network.InfrastructureMode) {
+ case Ndis802_11Infrastructure:
+ SetToDs(fctrl);
+ memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+ memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+ memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
+ break;
+ case Ndis802_11APMode:
+ SetFrDs(fctrl);
+ memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+ memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
+ break;
+ case Ndis802_11IBSS:
+ default:
+ memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
+ memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+ break;
+ }
+
+ SetSeqNum(pwlanhdr, 0);
+
+ if (bQoS == true) {
+ struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
+
+ set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
+
+ pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
+ SetPriority(&pwlanqoshdr->qc, AC);
+ SetEOSP(&pwlanqoshdr->qc, bEosp);
+
+ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
+ } else {
+ set_frame_sub_type(pframe, WIFI_DATA_NULL);
+
+ pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ }
+
+ *pLength = pktlen;
+}
+
+static void rtl8188e_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
+{
+ u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
+ u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
+
+ /* RTW_INFO("8188RsvdPageLoc: PsPoll=%d Null=%d QoSNull=%d\n", */
+ /* rsvdpageloc->LocPsPoll, rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull); */
+
+ SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
+ SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
+ SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
+
+ FillH2CCmd_88E(padapter, H2C_COM_RSVD_PAGE, H2C_RSVDPAGE_LOC_LEN, u1H2CRsvdPageParm);
+
+#ifdef CONFIG_WOWLAN
+ /* RTW_INFO("8188E_AOACRsvdPageLoc: RWC=%d ArpRsp=%d\n", rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp); */
+ SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
+ SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
+
+ FillH2CCmd_88E(padapter, H2C_COM_AOAC_RSVD_PAGE, H2C_AOAC_RSVDPAGE_LOC_LEN, u1H2CAoacRsvdPageParm);
+#endif
+}
+
+/* To check if reserved page content is destroyed by beacon beacuse beacon is too large.
+ * 2010.06.23. Added by tynli. */
+void
+CheckFwRsvdPageContent(
+ PADAPTER Adapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u32 MaxBcnPageNum;
+
+ if (pHalData->FwRsvdPageStartOffset != 0) {
+ /*MaxBcnPageNum = PageNum_128(pMgntInfo->MaxBeaconSize);
+ RT_ASSERT((MaxBcnPageNum <= pHalData->FwRsvdPageStartOffset),
+ ("CheckFwRsvdPageContent(): The reserved page content has been"\
+ "destroyed by beacon!!! MaxBcnPageNum(%d) FwRsvdPageStartOffset(%d)\n!",
+ MaxBcnPageNum, pHalData->FwRsvdPageStartOffset));*/
+ }
+}
+
+/*
+ * Description: Get the reserved page number in Tx packet buffer.
+ * Retrun value: the page number.
+ * 2012.08.09, by tynli.
+ * */
+u8
+GetTxBufferRsvdPageNum8188E(_adapter *padapter, bool wowlan)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ u8 RsvdPageNum = 0;
+ /* default reseved 1 page for the IC type which is undefined. */
+ u8 TxPageBndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8188E(padapter);
+
+ rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_BOUNDARY, (u8 *)&TxPageBndy);
+
+ RsvdPageNum = LAST_ENTRY_OF_TX_PKT_BUFFER_8188E(padapter) - TxPageBndy + 1;
+
+ return RsvdPageNum;
+}
+
+void rtl8188e_set_FwJoinBssReport_cmd(PADAPTER padapter, u8 mstatus)
+{
+ JOINBSSRPT_PARM_88E JoinBssRptParm;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+#ifdef CONFIG_WOWLAN
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct sta_info *psta = NULL;
+#endif
+ bool bSendBeacon = false;
+ bool bcn_valid = false;
+ u8 DLBcnCount = 0;
+ u32 poll = 0;
+
+
+ RTW_INFO("%s mstatus(%x)\n", __func__, mstatus);
+
+ if (mstatus == 1) {
+ /* We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C. */
+ /* Suggested by filen. Added by tynli. */
+ rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000 | pmlmeinfo->aid));
+ /* Do not set TSF again here or vWiFi beacon DMA INT will not work. */
+ /* correct_TSF(padapter, pmlmeext); */
+ /* Hw sequende enable by dedault. 2010.06.23. by tynli. */
+ /* rtw_write16(padapter, REG_NQOS_SEQ, ((pmlmeext->mgnt_seq+100)&0xFFF)); */
+ /* rtw_write8(padapter, REG_HWSEQ_CTRL, 0xFF); */
+
+ /* Set REG_CR bit 8. DMA beacon by SW. */
+ pHalData->RegCR_1 |= BIT0;
+ rtw_write8(padapter, REG_CR + 1, pHalData->RegCR_1);
+
+ /* Disable Hw protection for a time which revserd for Hw sending beacon. */
+ /* Fix download reserved page packet fail that access collision with the protection time. */
+ /* 2010.05.11. Added by tynli. */
+ /* SetBcnCtrlReg(padapter, 0, BIT3); */
+ /* SetBcnCtrlReg(padapter, BIT4, 0); */
+ rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~BIT(3)));
+ rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | BIT(4));
+
+ if (pHalData->RegFwHwTxQCtrl & BIT6) {
+ RTW_INFO("HalDownloadRSVDPage(): There is an Adapter is sending beacon.\n");
+ bSendBeacon = true;
+ }
+
+ /* Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame. */
+ rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, (pHalData->RegFwHwTxQCtrl & (~BIT6)));
+ pHalData->RegFwHwTxQCtrl &= (~BIT6);
+
+ /* Clear beacon valid check bit. */
+ rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
+ DLBcnCount = 0;
+ poll = 0;
+ do {
+ /* download rsvd page.*/
+ rtw_hal_set_fw_rsvd_page(padapter, false);
+ DLBcnCount++;
+ do {
+ rtw_yield_os();
+ /* rtw_mdelay_os(10); */
+ /* check rsvd page download OK. */
+ rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bcn_valid));
+ poll++;
+ } while (!bcn_valid && (poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
+
+ } while (!bcn_valid && DLBcnCount <= 100 && !RTW_CANNOT_RUN(padapter));
+
+ /* RT_ASSERT(bcn_valid, ("HalDownloadRSVDPage88ES(): 1 Download RSVD page failed!\n")); */
+ if (RTW_CANNOT_RUN(padapter))
+ ;
+ else if (!bcn_valid)
+ RTW_INFO(ADPT_FMT": 1 DL RSVD page failed! DLBcnCount:%u, poll:%u\n",
+ ADPT_ARG(padapter) , DLBcnCount, poll);
+ else {
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+ pwrctl->fw_psmode_iface_id = padapter->iface_id;
+ RTW_INFO(ADPT_FMT": 1 DL RSVD page success! DLBcnCount:%u, poll:%u\n",
+ ADPT_ARG(padapter), DLBcnCount, poll);
+ }
+
+ /* Enable Bcn */
+ /* SetBcnCtrlReg(padapter, BIT3, 0); */
+ /* SetBcnCtrlReg(padapter, 0, BIT4); */
+ rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | BIT(3));
+ rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~BIT(4)));
+
+ /* To make sure that if there exists an adapter which would like to send beacon. */
+ /* If exists, the origianl value of 0x422[6] will be 1, we should check this to */
+ /* prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */
+ /* the beacon cannot be sent by HW. */
+ /* 2010.06.23. Added by tynli. */
+ if (bSendBeacon) {
+ rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, (pHalData->RegFwHwTxQCtrl | BIT6));
+ pHalData->RegFwHwTxQCtrl |= BIT6;
+ }
+
+ /* */
+ /* Update RSVD page location H2C to Fw. */
+ /* */
+ if (bcn_valid) {
+ rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
+ RTW_INFO("Set RSVD page location to Fw.\n");
+ /* FillH2CCmd88E(Adapter, H2C_88E_RSVDPAGE, H2C_RSVDPAGE_LOC_LENGTH, pMgntInfo->u1RsvdPageLoc); */
+ }
+
+ /* Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli. */
+ /* if(!padapter->bEnterPnpSleep) */
+ {
+ /* Clear CR[8] or beacon packet will not be send to TxBuf anymore. */
+ pHalData->RegCR_1 &= (~BIT0);
+ rtw_write8(padapter, REG_CR + 1, pHalData->RegCR_1);
+ }
+ }
+}
+
+#ifdef CONFIG_P2P_PS
+void rtl8188e_set_p2p_ps_offload_cmd(_adapter *padapter, u8 p2p_ps_state)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+ struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
+ struct P2P_PS_Offload_t *p2p_ps_offload = (struct P2P_PS_Offload_t *)(&pHalData->p2p_ps_offload);
+ u8 i;
+
+ switch (p2p_ps_state) {
+ case P2P_PS_DISABLE:
+ RTW_INFO("P2P_PS_DISABLE\n");
+ memset(p2p_ps_offload, 0 , 1);
+ break;
+ case P2P_PS_ENABLE:
+ RTW_INFO("P2P_PS_ENABLE\n");
+ /* update CTWindow value. */
+ if (pwdinfo->ctwindow > 0) {
+ p2p_ps_offload->CTWindow_En = 1;
+ rtw_write8(padapter, REG_P2P_CTWIN, pwdinfo->ctwindow);
+ }
+
+ /* hw only support 2 set of NoA */
+ for (i = 0 ; i < pwdinfo->noa_num ; i++) {
+ /* To control the register setting for which NOA */
+ rtw_write8(padapter, REG_NOA_DESC_SEL, (i << 4));
+ if (i == 0)
+ p2p_ps_offload->NoA0_En = 1;
+ else
+ p2p_ps_offload->NoA1_En = 1;
+
+ /* config P2P NoA Descriptor Register */
+ /* RTW_INFO("%s(): noa_duration = %x\n",__func__,pwdinfo->noa_duration[i]); */
+ rtw_write32(padapter, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]);
+
+ /* RTW_INFO("%s(): noa_interval = %x\n",__func__,pwdinfo->noa_interval[i]); */
+ rtw_write32(padapter, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]);
+
+ /* RTW_INFO("%s(): start_time = %x\n",__func__,pwdinfo->noa_start_time[i]); */
+ rtw_write32(padapter, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]);
+
+ /* RTW_INFO("%s(): noa_count = %x\n",__func__,pwdinfo->noa_count[i]); */
+ rtw_write8(padapter, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]);
+ }
+
+ if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
+ /* rst p2p circuit */
+ rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(4));
+
+ p2p_ps_offload->Offload_En = 1;
+
+ if (pwdinfo->role == P2P_ROLE_GO) {
+ p2p_ps_offload->role = 1;
+ p2p_ps_offload->AllStaSleep = 0;
+ } else
+ p2p_ps_offload->role = 0;
+
+ p2p_ps_offload->discovery = 0;
+ }
+ break;
+ case P2P_PS_SCAN:
+ RTW_INFO("P2P_PS_SCAN\n");
+ p2p_ps_offload->discovery = 1;
+ break;
+ case P2P_PS_SCAN_DONE:
+ RTW_INFO("P2P_PS_SCAN_DONE\n");
+ p2p_ps_offload->discovery = 0;
+ pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
+ break;
+ default:
+ break;
+ }
+
+ FillH2CCmd_88E(padapter, H2C_PS_P2P_OFFLOAD, 1, (u8 *)p2p_ps_offload);
+}
+#endif /* CONFIG_P2P_PS */
+
+#ifdef CONFIG_TSF_RESET_OFFLOAD
+/*
+ ask FW to Reset sync register at Beacon early interrupt
+*/
+u8 rtl8188e_reset_tsf(_adapter *padapter, u8 reset_port)
+{
+ u8 buf[2];
+ u8 res = _SUCCESS;
+
+ s32 ret;
+ if (HW_PORT0 == reset_port) {
+ buf[0] = 0x1;
+ buf[1] = 0;
+ } else {
+ buf[0] = 0x0;
+ buf[1] = 0x1;
+ }
+
+ ret = FillH2CCmd_88E(padapter, H2C_RESET_TSF, 2, buf);
+
+
+ return res;
+}
+
+int reset_tsf(PADAPTER Adapter, u8 reset_port)
+{
+ u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
+ u32 reg_reset_tsf_cnt = (HW_PORT0 == reset_port) ?
+ REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
+ u32 reg_bcncrtl = (HW_PORT0 == reset_port) ?
+ REG_BCN_CTRL_1 : REG_BCN_CTRL;
+
+ rtw_mi_buddy_scan_abort(Adapter, false); /* site survey will cause reset_tsf fail */
+ reset_cnt_after = reset_cnt_before = rtw_read8(Adapter, reg_reset_tsf_cnt);
+ rtl8188e_reset_tsf(Adapter, reset_port);
+
+ while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
+ rtw_msleep_os(100);
+ loop_cnt++;
+ reset_cnt_after = rtw_read8(Adapter, reg_reset_tsf_cnt);
+ }
+
+ return (loop_cnt >= 10) ? _FAIL : true;
+}
+
+
+#endif /* CONFIG_TSF_RESET_OFFLOAD */
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c
new file mode 100644
index 000000000000..36a0790908d9
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+/* ************************************************************
+ * Description:
+ *
+ * This file is for 92CE/92CU dynamic mechanism only
+ *
+ *
+ * ************************************************************ */
+#define _RTL8188E_DM_C_
+
+/* ************************************************************
+ * include files
+ * ************************************************************ */
+#include <drv_types.h>
+#include <rtl8188e_hal.h>
+
+/* ************************************************************
+ * Global var
+ * ************************************************************ */
+
+
+static void
+dm_CheckProtection(
+ PADAPTER Adapter
+)
+{
+}
+
+static void
+dm_CheckStatistics(
+ PADAPTER Adapter
+)
+{
+}
+
+#ifdef CONFIG_SUPPORT_HW_WPS_PBC
+static void dm_CheckPbcGPIO(_adapter *padapter)
+{
+ u8 tmp1byte;
+ u8 bPbcPressed = false;
+
+ if (!padapter->registrypriv.hw_wps_pbc)
+ return;
+
+ tmp1byte = rtw_read8(padapter, GPIO_IO_SEL);
+ tmp1byte |= (HAL_8188E_HW_GPIO_WPS_BIT);
+ rtw_write8(padapter, GPIO_IO_SEL, tmp1byte); /* enable GPIO[2] as output mode */
+
+ tmp1byte &= ~(HAL_8188E_HW_GPIO_WPS_BIT);
+ rtw_write8(padapter, GPIO_IN, tmp1byte); /* reset the floating voltage level */
+
+ tmp1byte = rtw_read8(padapter, GPIO_IO_SEL);
+ tmp1byte &= ~(HAL_8188E_HW_GPIO_WPS_BIT);
+ rtw_write8(padapter, GPIO_IO_SEL, tmp1byte); /* enable GPIO[2] as input mode */
+
+ tmp1byte = rtw_read8(padapter, GPIO_IN);
+
+ if (tmp1byte == 0xff)
+ return ;
+
+ if (tmp1byte & HAL_8188E_HW_GPIO_WPS_BIT)
+ bPbcPressed = true;
+
+ if (bPbcPressed) {
+ /* Here we only set bPbcPressed to true */
+ /* After trigger PBC, the variable will be set to false */
+ RTW_INFO("CheckPbcGPIO - PBC is pressed\n");
+ rtw_request_wps_pbc_event(padapter);
+ }
+}
+#endif/* #ifdef CONFIG_SUPPORT_HW_WPS_PBC */
+
+/* Initialize GPIO setting registers */
+static void
+dm_InitGPIOSetting(
+ PADAPTER Adapter
+)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
+
+ u8 tmp1byte;
+
+ tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG);
+ tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
+
+ rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
+
+}
+
+/* ************************************************************
+ * functions
+ * ************************************************************ */
+static void Init_ODM_ComInfo_88E(PADAPTER Adapter)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &(pHalData->odmpriv);
+ u32 SupportAbility = 0;
+ u8 cut_ver, fab_ver;
+
+ Init_ODM_ComInfo(Adapter);
+
+ fab_ver = ODM_TSMC;
+ cut_ver = ODM_CUT_A;
+
+ if (IS_VENDOR_8188E_I_CUT_SERIES(Adapter))
+ cut_ver = ODM_CUT_I;
+
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_FAB_VER, fab_ver);
+ odm_cmn_info_init(pDM_Odm, ODM_CMNINFO_CUT_VER, cut_ver);
+
+#ifdef CONFIG_DISABLE_ODM
+ SupportAbility = 0;
+#else
+ SupportAbility = ODM_RF_CALIBRATION |
+ ODM_RF_TX_PWR_TRACK
+ ;
+#endif
+
+ odm_cmn_info_update(pDM_Odm, ODM_CMNINFO_ABILITY, SupportAbility);
+
+}
+static void Update_ODM_ComInfo_88E(PADAPTER Adapter)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &(pHalData->odmpriv);
+ u32 SupportAbility = 0;
+ int i;
+
+ SupportAbility = 0
+ | 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_SAVE */
+ | ODM_BB_CFO_TRACKING
+ | ODM_RF_CALIBRATION
+ | ODM_RF_TX_PWR_TRACK
+ | ODM_BB_NHM_CNT
+ | ODM_BB_PRIMARY_CCA
+ /* | ODM_BB_PWR_TRAIN */
+ ;
+
+ if (rtw_odm_adaptivity_needed(Adapter) == true) {
+ rtw_odm_adaptivity_config_msg(RTW_DBGDUMP, Adapter);
+ SupportAbility |= ODM_BB_ADAPTIVITY;
+ }
+
+ if (!Adapter->registrypriv.qos_opt_enable)
+ SupportAbility |= ODM_MAC_EDCA_TURBO;
+
+#ifdef CONFIG_ANTENNA_DIVERSITY
+ if (pHalData->AntDivCfg)
+ SupportAbility |= ODM_BB_ANT_DIV;
+#endif
+
+#if (MP_DRIVER == 1)
+ if (Adapter->registrypriv.mp_mode == 1) {
+ SupportAbility = 0
+ | ODM_RF_CALIBRATION
+ | ODM_RF_TX_PWR_TRACK
+ ;
+ }
+#endif/* (MP_DRIVER==1) */
+
+#ifdef CONFIG_DISABLE_ODM
+ SupportAbility = 0;
+#endif/* CONFIG_DISABLE_ODM */
+
+ odm_cmn_info_update(pDM_Odm, ODM_CMNINFO_ABILITY, SupportAbility);
+}
+
+void
+rtl8188e_InitHalDm(
+ PADAPTER Adapter
+)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &(pHalData->odmpriv);
+ u8 i;
+
+ dm_InitGPIOSetting(Adapter);
+
+ pHalData->DM_Type = dm_type_by_driver;
+
+ Update_ODM_ComInfo_88E(Adapter);
+ odm_dm_init(pDM_Odm);
+}
+
+
+void
+rtl8188e_HalDmWatchDog(
+ PADAPTER Adapter
+)
+{
+ bool bFwCurrentInPSMode = false;
+ bool bFwPSAwake = true;
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
+ struct PHY_DM_STRUCT *pDM_Odm = &(pHalData->odmpriv);
+
+
+ if (!rtw_is_hw_init_completed(Adapter))
+ goto skip_dm;
+
+#ifdef CONFIG_LPS
+ bFwCurrentInPSMode = adapter_to_pwrctl(Adapter)->bFwCurrentInPSMode;
+ rtw_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake));
+#endif
+
+#ifdef CONFIG_P2P_PS
+ /* Fw is under p2p powersaving mode, driver should stop dynamic mechanism. */
+ /* modifed by thomas. 2011.06.11. */
+ if (Adapter->wdinfo.p2p_ps_mode)
+ bFwPSAwake = false;
+#endif /* CONFIG_P2P_PS */
+
+ if ((rtw_is_hw_init_completed(Adapter))
+ && ((!bFwCurrentInPSMode) && bFwPSAwake)) {
+ /* Calculate Tx/Rx statistics. */
+ dm_CheckStatistics(Adapter);
+
+ rtw_hal_check_rxfifo_full(Adapter);
+ }
+
+ /* ODM */
+ if (rtw_is_hw_init_completed(Adapter)) {
+ u8 bLinked = false;
+ u8 bsta_state = false;
+#ifdef CONFIG_DISABLE_ODM
+ pHalData->odmpriv.support_ability = 0;
+#endif
+
+ if (rtw_mi_check_status(Adapter, MI_ASSOC)) {
+ bLinked = true;
+ if (rtw_mi_check_status(Adapter, MI_STA_LINKED))
+ bsta_state = true;
+ }
+
+ odm_cmn_info_update(&pHalData->odmpriv , ODM_CMNINFO_LINK, bLinked);
+ odm_cmn_info_update(&pHalData->odmpriv , ODM_CMNINFO_STATION_STATE, bsta_state);
+
+
+ odm_dm_watchdog(&pHalData->odmpriv);
+
+ }
+
+skip_dm:
+
+#ifdef CONFIG_SUPPORT_HW_WPS_PBC
+ /* Check GPIO to determine current Pbc status. */
+ dm_CheckPbcGPIO(Adapter);
+#endif
+ return;
+}
+
+void rtl8188e_init_dm_priv(PADAPTER Adapter)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
+ struct PHY_DM_STRUCT *podmpriv = &pHalData->odmpriv;
+
+ /* spin_lock_init(&(pHalData->odm_stainfo_lock)); */
+ Init_ODM_ComInfo_88E(Adapter);
+ odm_init_all_timers(podmpriv);
+
+}
+
+void rtl8188e_deinit_dm_priv(PADAPTER Adapter)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
+ struct PHY_DM_STRUCT *podmpriv = &pHalData->odmpriv;
+ odm_cancel_all_timers(podmpriv);
+}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
new file mode 100644
index 000000000000..f039dd816e08
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
@@ -0,0 +1,4629 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _HAL_INIT_C_
+
+#include <drv_types.h>
+#include <rtl8188e_hal.h>
+#ifdef CONFIG_SFW_SUPPORTED
+#include "hal8188e_s_fw.h"
+#endif
+#include "hal8188e_t_fw.h"
+
+
+#if defined(CONFIG_IOL)
+static void iol_mode_enable(PADAPTER padapter, u8 enable)
+{
+ u8 reg_0xf0 = 0;
+
+ if (enable) {
+ /* Enable initial offload */
+ reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+ /* RTW_INFO("%s reg_0xf0:0x%02x, write 0x%02x\n", __func__, reg_0xf0, reg_0xf0|SW_OFFLOAD_EN); */
+ rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN);
+
+ if (padapter->bFWReady == false) {
+ RTW_INFO("bFWReady == false call reset 8051...\n");
+ _8051Reset88E(padapter);
+ }
+
+ } else {
+ /* disable initial offload */
+ reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+ /* RTW_INFO("%s reg_0xf0:0x%02x, write 0x%02x\n", __func__, reg_0xf0, reg_0xf0& ~SW_OFFLOAD_EN); */
+ rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
+ }
+}
+
+static s32 iol_execute(PADAPTER padapter, u8 control)
+{
+ s32 status = _FAIL;
+ u8 reg_0x88 = 0, reg_1c7 = 0;
+ u32 start = 0, passing_time = 0;
+
+ u32 t1, t2;
+ control = control & 0x0f;
+ reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+ /* RTW_INFO("%s reg_0x88:0x%02x, write 0x%02x\n", __func__, reg_0x88, reg_0x88|control); */
+ rtw_write8(padapter, REG_HMEBOX_E0, reg_0x88 | control);
+
+ t1 = start = jiffies;
+ while (
+ /* (reg_1c7 = rtw_read8(padapter, 0x1c7) >1) && */
+ (reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0)) & control
+ && (passing_time = rtw_get_passing_time_ms(start)) < 1000
+ ) {
+ /* RTW_INFO("%s polling reg_0x88:0x%02x,reg_0x1c7:0x%02x\n", __func__, reg_0x88,rtw_read8(padapter, 0x1c7) ); */
+ /* rtw_udelay_os(100); */
+ }
+
+ reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+ status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
+ if (reg_0x88 & control << 4)
+ status = _FAIL;
+ t2 = jiffies;
+
+ return status;
+}
+
+static s32 iol_InitLLTTable(
+ PADAPTER padapter,
+ u8 txpktbuf_bndy
+)
+{
+ s32 rst = _SUCCESS;
+ iol_mode_enable(padapter, 1);
+ /* RTW_INFO("%s txpktbuf_bndy:%u\n", __func__, txpktbuf_bndy); */
+ rtw_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy);
+ rst = iol_execute(padapter, CMD_INIT_LLT);
+ iol_mode_enable(padapter, 0);
+ return rst;
+}
+
+static void
+efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf)
+{
+ u8 *efuseTbl = NULL;
+ u8 rtemp8;
+ u16 eFuse_Addr = 0;
+ u8 offset, wren;
+ u16 i, j;
+ u16 **eFuseWord = NULL;
+ u16 efuse_utilized = 0;
+ u8 efuse_usage = 0;
+ u8 u1temp = 0;
+
+
+ efuseTbl = (u8 *)rtw_zmalloc(EFUSE_MAP_LEN_88E);
+ if (efuseTbl == NULL) {
+ RTW_INFO("%s: alloc efuseTbl fail!\n", __func__);
+ goto exit;
+ }
+
+ eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, 2);
+ if (eFuseWord == NULL) {
+ RTW_INFO("%s: alloc eFuseWord fail!\n", __func__);
+ goto exit;
+ }
+
+ /* 0. Refresh efuse init map as all oxFF. */
+ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
+ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
+ eFuseWord[i][j] = 0xFFFF;
+
+ /* */
+ /* 1. Read the first byte to check if efuse is empty!!! */
+ /* */
+ /* */
+ rtemp8 = *(phymap + eFuse_Addr);
+ if (rtemp8 != 0xFF) {
+ efuse_utilized++;
+ eFuse_Addr++;
+ } else {
+ RTW_INFO("EFUSE is empty efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, rtemp8);
+ goto exit;
+ }
+
+
+ /* */
+ /* 2. Read real efuse content. Filter PG header and every section data. */
+ /* */
+ while ((rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("efuse_Addr-%d efuse_data=%x\n", eFuse_Addr-1, *rtemp8)); */
+
+ /* Check PG header for section num. */
+ if ((rtemp8 & 0x1F) == 0x0F) { /* extended header */
+ u1temp = ((rtemp8 & 0xE0) >> 5);
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header u1temp=%x *rtemp&0xE0 0x%x\n", u1temp, *rtemp8 & 0xE0)); */
+
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header u1temp=%x\n", u1temp)); */
+
+ rtemp8 = *(phymap + eFuse_Addr);
+
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8)); */
+
+ if ((rtemp8 & 0x0F) == 0x0F) {
+ eFuse_Addr++;
+ rtemp8 = *(phymap + eFuse_Addr);
+
+ if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
+ eFuse_Addr++;
+ continue;
+ } else {
+ offset = ((rtemp8 & 0xF0) >> 1) | u1temp;
+ wren = (rtemp8 & 0x0F);
+ eFuse_Addr++;
+ }
+ } else {
+ offset = ((rtemp8 >> 4) & 0x0f);
+ wren = (rtemp8 & 0x0f);
+ }
+
+ if (offset < EFUSE_MAX_SECTION_88E) {
+ /* Get word enable value from PG header */
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Offset-%d Worden=%x\n", offset, wren)); */
+
+ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
+ /* Check word enable condition in the section */
+ if (!(wren & 0x01)) {
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d\n", eFuse_Addr)); */
+ rtemp8 = *(phymap + eFuse_Addr);
+ eFuse_Addr++;
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Data=0x%x\n", *rtemp8)); */
+ efuse_utilized++;
+ eFuseWord[offset][i] = (rtemp8 & 0xff);
+
+
+ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
+ break;
+
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d", eFuse_Addr)); */
+ rtemp8 = *(phymap + eFuse_Addr);
+ eFuse_Addr++;
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Data=0x%x\n", *rtemp8)); */
+
+ efuse_utilized++;
+ eFuseWord[offset][i] |= (((u16)rtemp8 << 8) & 0xff00);
+
+ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
+ break;
+ }
+
+ wren >>= 1;
+
+ }
+ }
+
+ /* Read next PG header */
+ rtemp8 = *(phymap + eFuse_Addr);
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d rtemp 0x%x\n", eFuse_Addr, *rtemp8)); */
+
+ if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
+ efuse_utilized++;
+ eFuse_Addr++;
+ }
+ }
+
+ /* */
+ /* 3. Collect 16 sections and 4 word unit into Efuse map. */
+ /* */
+ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
+ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
+ efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff);
+ efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff);
+ }
+ }
+
+
+ /* */
+ /* 4. Copy from Efuse map to output pointer memory!!! */
+ /* */
+ for (i = 0; i < _size_byte; i++)
+ pbuf[i] = efuseTbl[_offset + i];
+
+ /* */
+ /* 5. Calculate Efuse utilization. */
+ /* */
+ efuse_usage = (u8)((efuse_utilized * 100) / EFUSE_REAL_CONTENT_LEN_88E);
+ /* rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_utilized); */
+
+exit:
+ if (efuseTbl)
+ rtw_mfree(efuseTbl, EFUSE_MAP_LEN_88E);
+
+ if (eFuseWord)
+ rtw_mfree2d((void *)eFuseWord, EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
+}
+
+static void efuse_read_phymap_from_txpktbuf(
+ ADAPTER *adapter,
+ int bcnhead, /* beacon head, where FW store len(2-byte) and efuse physical map. */
+ u8 *content, /* buffer to store efuse physical map */
+ u16 *size /* for efuse content: the max byte to read. will update to byte read */
+)
+{
+ u16 dbg_addr = 0;
+ u32 start = 0, passing_time = 0;
+ u8 reg_0x143 = 0;
+ u8 reg_0x106 = 0;
+ u32 lo32 = 0, hi32 = 0;
+ u16 len = 0, count = 0;
+ int i = 0;
+ u16 limit = *size;
+
+ u8 *pos = content;
+
+ if (bcnhead < 0) /* if not valid */
+ bcnhead = rtw_read8(adapter, REG_TDECTRL + 1);
+
+ RTW_INFO("%s bcnhead:%d\n", __func__, bcnhead);
+
+ /* reg_0x106 = rtw_read8(adapter, REG_PKT_BUFF_ACCESS_CTRL); */
+ /* RTW_INFO("%s reg_0x106:0x%02x, write 0x%02x\n", __func__, reg_0x106, 0x69); */
+ rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
+ /* RTW_INFO("%s reg_0x106:0x%02x\n", __func__, rtw_read8(adapter, 0x106)); */
+
+ dbg_addr = bcnhead * 128 / 8; /* 8-bytes addressing */
+
+ while (1) {
+ /* RTW_INFO("%s dbg_addr:0x%x\n", __func__, dbg_addr+i); */
+ rtw_write16(adapter, REG_PKTBUF_DBG_ADDR, dbg_addr + i);
+
+ /* RTW_INFO("%s write reg_0x143:0x00\n", __func__); */
+ rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
+ start = jiffies;
+ while (!(reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG)) /* dbg */
+ /* while(rtw_read8(adapter, REG_TXPKTBUF_DBG) & BIT0 */
+ && (passing_time = rtw_get_passing_time_ms(start)) < 1000
+ ) {
+ RTW_INFO("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, rtw_read8(adapter, 0x106));
+ rtw_usleep_os(100);
+ }
+
+
+ lo32 = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
+ hi32 = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
+
+ if (i == 0) {
+ u8 lenc[2];
+ u16 lenbak, aaabak;
+ u16 aaa;
+ lenc[0] = rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L);
+ lenc[1] = rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L + 1);
+
+ aaabak = le16_to_cpup((__le16 *)lenc);
+ lenbak = le16_to_cpu(*((__le16 *)lenc));
+ aaa = le16_to_cpup((__le16 *)&lo32);
+ len = le16_to_cpu(*((__le16 *)&lo32));
+
+ limit = (len - 2 < limit) ? len - 2 : limit;
+
+ RTW_INFO("%s len:%u, lenbak:%u, aaa:%u, aaabak:%u\n", __func__, len, lenbak, aaa, aaabak);
+
+ memcpy(pos, ((u8 *)&lo32) + 2, (limit >= count + 2) ? 2 : limit - count);
+ count += (limit >= count + 2) ? 2 : limit - count;
+ pos = content + count;
+
+ } else {
+ memcpy(pos, ((u8 *)&lo32), (limit >= count + 4) ? 4 : limit - count);
+ count += (limit >= count + 4) ? 4 : limit - count;
+ pos = content + count;
+
+
+ }
+
+ if (limit > count && len - 2 > count) {
+ memcpy(pos, (u8 *)&hi32, (limit >= count + 4) ? 4 : limit - count);
+ count += (limit >= count + 4) ? 4 : limit - count;
+ pos = content + count;
+ }
+
+ if (limit <= count || len - 2 <= count)
+ break;
+
+ i++;
+ }
+
+ rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
+
+ RTW_INFO("%s read count:%u\n", __func__, count);
+ *size = count;
+
+}
+
+
+static s32 iol_read_efuse(
+ PADAPTER padapter,
+ u8 txpktbuf_bndy,
+ u16 offset,
+ u16 size_byte,
+ u8 *logical_map
+)
+{
+ s32 status = _FAIL;
+ u8 reg_0x106 = 0;
+ u8 physical_map[512];
+ u16 size = 512;
+ int i;
+
+
+ rtw_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy);
+ memset(physical_map, 0xFF, 512);
+
+ rtw_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
+
+ status = iol_execute(padapter, CMD_READ_EFUSE_MAP);
+
+ if (status == _SUCCESS)
+ efuse_read_phymap_from_txpktbuf(padapter, txpktbuf_bndy, physical_map, &size);
+
+ efuse_phymap_to_logical(physical_map, offset, size_byte, logical_map);
+
+ return status;
+}
+
+s32 rtl8188e_iol_efuse_patch(PADAPTER padapter)
+{
+ s32 result = _SUCCESS;
+
+ if (rtw_IOL_applied(padapter)) {
+ iol_mode_enable(padapter, 1);
+ result = iol_execute(padapter, CMD_READ_EFUSE_MAP);
+ if (result == _SUCCESS)
+ result = iol_execute(padapter, CMD_EFUSE_PATCH);
+
+ iol_mode_enable(padapter, 0);
+ }
+ return result;
+}
+
+static s32 iol_ioconfig(
+ PADAPTER padapter,
+ u8 iocfg_bndy
+)
+{
+ s32 rst = _SUCCESS;
+
+ /* RTW_INFO("%s iocfg_bndy:%u\n", __func__, iocfg_bndy); */
+ rtw_write8(padapter, REG_TDECTRL + 1, iocfg_bndy);
+ rst = iol_execute(padapter, CMD_IOCONFIG);
+
+ return rst;
+}
+
+static int rtl8188e_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
+{
+
+ u32 start_time = jiffies;
+ u32 passing_time_ms;
+ u8 polling_ret, i;
+ int ret = _FAIL;
+ u32 t1, t2;
+
+ if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
+ goto exit;
+ {
+ struct pkt_attrib *pattrib = &xmit_frame->attrib;
+ if (rtw_usb_bulk_size_boundary(adapter, TXDESC_SIZE + pattrib->last_txcmdsz)) {
+ if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
+ goto exit;
+ }
+ }
+
+ /* rtw_IOL_cmd_buf_dump(adapter,xmit_frame->attrib.pktlen+TXDESC_OFFSET,xmit_frame->buf_addr); */
+ /* rtw_hal_mgnt_xmit(adapter, xmit_frame); */
+ /* rtw_dump_xframe_sync(adapter, xmit_frame); */
+
+ dump_mgntframe_and_wait(adapter, xmit_frame, max_wating_ms);
+
+ t1 = jiffies;
+ iol_mode_enable(adapter, 1);
+ for (i = 0; i < bndy_cnt; i++) {
+ u8 page_no = 0;
+ page_no = i * 2 ;
+ ret = iol_ioconfig(adapter, page_no);
+ if (ret != _SUCCESS)
+ break;
+ }
+ iol_mode_enable(adapter, 0);
+ t2 = jiffies;
+exit:
+ /* restore BCN_HEAD */
+ rtw_write8(adapter, REG_TDECTRL + 1, 0);
+ return ret;
+}
+
+void rtw_IOL_cmd_tx_pkt_buf_dump(ADAPTER *Adapter, int data_len)
+{
+ u32 fifo_data, reg_140;
+ u32 addr, rstatus, loop = 0;
+
+ u16 data_cnts = (data_len / 8) + 1;
+ u8 *pbuf = rtw_zvmalloc(data_len + 10);
+ RTW_INFO("###### %s ######\n", __func__);
+
+ rtw_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
+ if (pbuf) {
+ for (addr = 0; addr < data_cnts; addr++) {
+ rtw_write32(Adapter, 0x140, addr);
+ rtw_usleep_os(2);
+ loop = 0;
+ do {
+ rstatus = (reg_140 = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL) & BIT24);
+ if (rstatus) {
+ fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L);
+ memcpy(pbuf + (addr * 8), &fifo_data , 4);
+
+ fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H);
+ memcpy(pbuf + (addr * 8 + 4), &fifo_data, 4);
+
+ }
+ rtw_usleep_os(2);
+ } while (!rstatus && (loop++ < 10));
+ }
+ rtw_IOL_cmd_buf_dump(Adapter, data_len, pbuf);
+ rtw_vmfree(pbuf, data_len + 10);
+
+ }
+ RTW_INFO("###### %s ######\n", __func__);
+}
+
+#endif /* defined(CONFIG_IOL) */
+
+
+static void
+_FWDownloadEnable_8188E(
+ PADAPTER padapter,
+ bool enable
+)
+{
+ u8 tmp;
+
+ if (enable) {
+ /* MCU firmware download enable. */
+ tmp = rtw_read8(padapter, REG_MCUFWDL);
+ rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
+
+ /* 8051 reset */
+ tmp = rtw_read8(padapter, REG_MCUFWDL + 2);
+ rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
+ } else {
+
+ /* MCU firmware download disable. */
+ tmp = rtw_read8(padapter, REG_MCUFWDL);
+ rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
+
+ /* Reserved for fw extension. */
+ rtw_write8(padapter, REG_MCUFWDL + 1, 0x00);
+ }
+}
+#define MAX_REG_BOLCK_SIZE 196
+static int
+_BlockWrite(
+ PADAPTER padapter,
+ void * buffer,
+ u32 buffSize
+)
+{
+ int ret = _SUCCESS;
+
+ u32 blockSize_p1 = 4; /* (Default) Phase #1 : PCI muse use 4-byte write to download FW */
+ u32 blockSize_p2 = 8; /* Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */
+ u32 blockSize_p3 = 1; /* Phase #3 : Use 1-byte, the remnant of FW image. */
+ u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
+ u32 remainSize_p1 = 0, remainSize_p2 = 0;
+ u8 *bufferPtr = (u8 *)buffer;
+ u32 i = 0, offset = 0;
+
+ blockSize_p1 = MAX_REG_BOLCK_SIZE;
+
+ /* 3 Phase #1 */
+ blockCount_p1 = buffSize / blockSize_p1;
+ remainSize_p1 = buffSize % blockSize_p1;
+
+
+
+ for (i = 0; i < blockCount_p1; i++) {
+ ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
+
+ if (ret == _FAIL)
+ goto exit;
+ }
+
+ /* 3 Phase #2 */
+ if (remainSize_p1) {
+ offset = blockCount_p1 * blockSize_p1;
+
+ blockCount_p2 = remainSize_p1 / blockSize_p2;
+ remainSize_p2 = remainSize_p1 % blockSize_p2;
+
+
+
+ for (i = 0; i < blockCount_p2; i++) {
+ ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + offset + i * blockSize_p2), blockSize_p2, (bufferPtr + offset + i * blockSize_p2));
+
+ if (ret == _FAIL)
+ goto exit;
+ }
+ }
+
+ /* 3 Phase #3 */
+ if (remainSize_p2) {
+ offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
+
+ blockCount_p3 = remainSize_p2 / blockSize_p3;
+
+
+ for (i = 0 ; i < blockCount_p3 ; i++) {
+ ret = rtw_write8(padapter, (FW_8188E_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
+
+ if (ret == _FAIL)
+ goto exit;
+ }
+ }
+
+exit:
+ return ret;
+}
+
+static int
+_PageWrite(
+ PADAPTER padapter,
+ u32 page,
+ void * buffer,
+ u32 size
+)
+{
+ u8 value8;
+ u8 u8Page = (u8)(page & 0x07) ;
+
+ value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page ;
+ rtw_write8(padapter, REG_MCUFWDL + 2, value8);
+
+ return _BlockWrite(padapter, buffer, size);
+}
+
+static void
+_FillDummy(
+ u8 *pFwBuf,
+ u32 *pFwLen
+)
+{
+ u32 FwLen = *pFwLen;
+ u8 remain = (u8)(FwLen % 4);
+ remain = (remain == 0) ? 0 : (4 - remain);
+
+ while (remain > 0) {
+ pFwBuf[FwLen] = 0;
+ FwLen++;
+ remain--;
+ }
+
+ *pFwLen = FwLen;
+}
+
+static int
+_WriteFW(
+ PADAPTER padapter,
+ void * buffer,
+ u32 size
+)
+{
+ /* Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. */
+ int ret = _SUCCESS;
+ u32 pageNums, remainSize ;
+ u32 page, offset;
+ u8 *bufferPtr = (u8 *)buffer;
+
+ pageNums = size / MAX_DLFW_PAGE_SIZE ;
+ /* RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4\n")); */
+ remainSize = size % MAX_DLFW_PAGE_SIZE;
+
+ for (page = 0; page < pageNums; page++) {
+ offset = page * MAX_DLFW_PAGE_SIZE;
+ ret = _PageWrite(padapter, page, bufferPtr + offset, MAX_DLFW_PAGE_SIZE);
+
+ if (ret == _FAIL)
+ goto exit;
+ }
+ if (remainSize) {
+ offset = pageNums * MAX_DLFW_PAGE_SIZE;
+ page = pageNums;
+ ret = _PageWrite(padapter, page, bufferPtr + offset, remainSize);
+
+ if (ret == _FAIL)
+ goto exit;
+
+ }
+
+exit:
+ return ret;
+}
+
+static void _MCUIO_Reset88E(PADAPTER padapter, u8 bReset)
+{
+ u8 u1bTmp;
+
+ if (bReset == true) {
+ u1bTmp = rtw_read8(padapter, REG_RSV_CTRL);
+ rtw_write8(padapter, REG_RSV_CTRL, (u1bTmp & (~BIT1)));
+ /* Reset MCU IO Wrapper- sugggest by SD1-Gimmy */
+ u1bTmp = rtw_read8(padapter, REG_RSV_CTRL + 1);
+ rtw_write8(padapter, REG_RSV_CTRL + 1, (u1bTmp & (~BIT3)));
+ } else {
+ u1bTmp = rtw_read8(padapter, REG_RSV_CTRL);
+ rtw_write8(padapter, REG_RSV_CTRL, (u1bTmp & (~BIT1)));
+ /* Enable MCU IO Wrapper */
+ u1bTmp = rtw_read8(padapter, REG_RSV_CTRL + 1);
+ rtw_write8(padapter, REG_RSV_CTRL + 1, u1bTmp | BIT3);
+ }
+
+}
+
+void _8051Reset88E(PADAPTER padapter)
+{
+ u8 u1bTmp;
+
+ _MCUIO_Reset88E(padapter, true);
+ u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
+ rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT2));
+ _MCUIO_Reset88E(padapter, false);
+ rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp | (BIT2));
+
+ RTW_INFO("=====> _8051Reset88E(): 8051 reset success .\n");
+}
+
+static s32 polling_fwdl_chksum(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
+{
+ s32 ret = _FAIL;
+ u32 value32;
+ u32 start = jiffies;
+ u32 cnt = 0;
+
+ /* polling CheckSum report */
+ do {
+ cnt++;
+ value32 = rtw_read32(adapter, REG_MCUFWDL);
+ if (value32 & FWDL_ChkSum_rpt || RTW_CANNOT_IO(adapter))
+ break;
+ rtw_yield_os();
+ } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
+
+ if (!(value32 & FWDL_ChkSum_rpt))
+ goto exit;
+
+ if (rtw_fwdl_test_trigger_chksum_fail())
+ goto exit;
+
+ ret = _SUCCESS;
+
+exit:
+ RTW_INFO("%s: Checksum report %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __func__
+ , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), value32);
+
+ return ret;
+}
+
+static s32 _FWFreeToGo(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
+{
+ s32 ret = _FAIL;
+ u32 value32;
+ u32 start = jiffies;
+ u32 cnt = 0;
+
+ value32 = rtw_read32(adapter, REG_MCUFWDL);
+ value32 |= MCUFWDL_RDY;
+ value32 &= ~WINTINI_RDY;
+ rtw_write32(adapter, REG_MCUFWDL, value32);
+
+ _8051Reset88E(adapter);
+
+ /* polling for FW ready */
+ do {
+ cnt++;
+ value32 = rtw_read32(adapter, REG_MCUFWDL);
+ if (value32 & WINTINI_RDY || RTW_CANNOT_IO(adapter))
+ break;
+ rtw_yield_os();
+ } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
+
+ if (!(value32 & WINTINI_RDY))
+ goto exit;
+
+ if (rtw_fwdl_test_trigger_wintint_rdy_fail())
+ goto exit;
+
+ ret = _SUCCESS;
+
+exit:
+ RTW_INFO("%s: Polling FW ready %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __func__
+ , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), value32);
+ return ret;
+}
+
+#define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
+
+
+#ifdef CONFIG_FILE_FWIMG
+ extern char *rtw_fw_file_path;
+ extern char *rtw_fw_wow_file_path;
+ u8 FwBuffer8188E[FW_8188E_SIZE];
+#endif /* CONFIG_FILE_FWIMG */
+
+/*
+ * Description:
+ * Download 8192C firmware code.
+ *
+ * */
+s32 rtl8188e_FirmwareDownload(PADAPTER padapter, bool bUsedWoWLANFw)
+{
+ s32 rtStatus = _SUCCESS;
+ u8 write_fw = 0;
+ u32 fwdl_start_time;
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+
+ PRT_FIRMWARE_8188E pFirmware = NULL;
+ PRT_8188E_FIRMWARE_HDR pFwHdr = NULL;
+
+ u8 *pFirmwareBuf;
+ u32 FirmwareLen, tmp_fw_len = 0;
+#ifdef CONFIG_FILE_FWIMG
+ u8 *fwfilepath;
+#endif /* CONFIG_FILE_FWIMG */
+
+#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+#endif
+
+ pFirmware = (PRT_FIRMWARE_8188E)rtw_zmalloc(sizeof(RT_FIRMWARE_8188E));
+ if (!pFirmware) {
+ rtStatus = _FAIL;
+ goto exit;
+ }
+
+
+
+#ifdef CONFIG_FILE_FWIMG
+#ifdef CONFIG_WOWLAN
+ if (bUsedWoWLANFw)
+ fwfilepath = rtw_fw_wow_file_path;
+ else
+#endif /* CONFIG_WOWLAN */
+ {
+ fwfilepath = rtw_fw_file_path;
+ }
+#endif /* CONFIG_FILE_FWIMG */
+
+#ifdef CONFIG_FILE_FWIMG
+ if (rtw_is_file_readable(fwfilepath) == true) {
+ RTW_INFO("%s accquire FW from file:%s\n", __func__, fwfilepath);
+ pFirmware->eFWSource = FW_SOURCE_IMG_FILE;
+ } else
+#endif /* CONFIG_FILE_FWIMG */
+ {
+ pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;
+ }
+
+ switch (pFirmware->eFWSource) {
+ case FW_SOURCE_IMG_FILE:
+#ifdef CONFIG_FILE_FWIMG
+ rtStatus = rtw_retrieve_from_file(fwfilepath, FwBuffer8188E, FW_8188E_SIZE);
+ pFirmware->ulFwLength = rtStatus >= 0 ? rtStatus : 0;
+ pFirmware->szFwBuffer = FwBuffer8188E;
+#endif /* CONFIG_FILE_FWIMG */
+ break;
+ case FW_SOURCE_HEADER_FILE:
+ if (bUsedWoWLANFw) {
+#ifdef CONFIG_WOWLAN
+ if (pwrpriv->wowlan_mode) {
+ #ifdef CONFIG_SFW_SUPPORTED
+ if (IS_VENDOR_8188E_I_CUT_SERIES(padapter)) {
+ pFirmware->szFwBuffer = array_mp_8188e_s_fw_wowlan;
+ pFirmware->ulFwLength = array_length_mp_8188e_s_fw_wowlan;
+ } else
+ #endif
+ {
+ pFirmware->szFwBuffer = array_mp_8188e_t_fw_wowlan;
+ pFirmware->ulFwLength = array_length_mp_8188e_t_fw_wowlan;
+ }
+ RTW_INFO("%s fw:%s, size: %d\n", __func__,
+ "WoWLAN", pFirmware->ulFwLength);
+ }
+#endif /*CONFIG_WOWLAN*/
+
+#ifdef CONFIG_AP_WOWLAN
+ if (pwrpriv->wowlan_ap_mode) {
+ pFirmware->szFwBuffer = array_mp_8188e_t_fw_ap;
+ pFirmware->ulFwLength = array_length_mp_8188e_t_fw_ap;
+
+ RTW_INFO("%s fw: %s, size: %d\n", __func__,
+ "AP_WoWLAN", pFirmware->ulFwLength);
+ }
+#endif /*CONFIG_AP_WOWLAN*/
+ } else {
+#ifdef CONFIG_SFW_SUPPORTED
+ if (IS_VENDOR_8188E_I_CUT_SERIES(padapter)) {
+ pFirmware->szFwBuffer = array_mp_8188e_s_fw_nic;
+ pFirmware->ulFwLength = array_length_mp_8188e_s_fw_nic;
+ } else
+#endif
+ {
+ pFirmware->szFwBuffer = array_mp_8188e_t_fw_nic;
+ pFirmware->ulFwLength = array_length_mp_8188e_t_fw_nic;
+ }
+ RTW_INFO("%s fw:%s, size: %d\n", __func__, "NIC", pFirmware->ulFwLength);
+ }
+ break;
+ }
+
+ tmp_fw_len = IS_VENDOR_8188E_I_CUT_SERIES(padapter) ? FW_8188E_SIZE_2 : FW_8188E_SIZE;
+
+ if ((pFirmware->ulFwLength - 32) > tmp_fw_len) {
+ rtStatus = _FAIL;
+ RTW_ERR("Firmware size:%u exceed %u\n", pFirmware->ulFwLength, tmp_fw_len);
+ goto exit;
+ }
+
+ pFirmwareBuf = pFirmware->szFwBuffer;
+ FirmwareLen = pFirmware->ulFwLength;
+
+ /* To Check Fw header. Added by tynli. 2009.12.04. */
+ pFwHdr = (PRT_8188E_FIRMWARE_HDR)pFirmwareBuf;
+
+ pHalData->firmware_version = le16_to_cpu(pFwHdr->Version);
+ pHalData->firmware_sub_version = pFwHdr->Subversion;
+ pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
+
+ RTW_INFO("%s: fw_ver=%x fw_subver=%04x sig=0x%x, Month=%02x, Date=%02x, Hour=%02x, Minute=%02x\n",
+ __func__, pHalData->firmware_version,
+ pHalData->firmware_sub_version, pHalData->FirmwareSignature,
+ pFwHdr->Month, pFwHdr->Date, pFwHdr->Hour, pFwHdr->Minute);
+
+ if (IS_FW_HEADER_EXIST_88E(pFwHdr)) {
+ /* Shift 32 bytes for FW header */
+ pFirmwareBuf = pFirmwareBuf + 32;
+ FirmwareLen = FirmwareLen - 32;
+ }
+
+ /* Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
+ /* or it will cause download Fw fail. 2010.02.01. by tynli. */
+ if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */
+ rtw_write8(padapter, REG_MCUFWDL, 0x00);
+ _8051Reset88E(padapter);
+ }
+
+ _FWDownloadEnable_8188E(padapter, true);
+ fwdl_start_time = jiffies;
+ while (!RTW_CANNOT_IO(padapter)
+ && (write_fw++ < 3 || rtw_get_passing_time_ms(fwdl_start_time) < 500)) {
+ /* reset FWDL chksum */
+ rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
+
+ rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
+ if (rtStatus != _SUCCESS)
+ continue;
+
+ rtStatus = polling_fwdl_chksum(padapter, 5, 50);
+ if (rtStatus == _SUCCESS)
+ break;
+ }
+ _FWDownloadEnable_8188E(padapter, false);
+ if (_SUCCESS != rtStatus)
+ goto fwdl_stat;
+
+ rtStatus = _FWFreeToGo(padapter, 10, 200);
+ if (_SUCCESS != rtStatus)
+ goto fwdl_stat;
+
+fwdl_stat:
+ RTW_INFO("FWDL %s. write_fw:%u, %dms\n"
+ , (rtStatus == _SUCCESS) ? "success" : "fail"
+ , write_fw
+ , rtw_get_passing_time_ms(fwdl_start_time)
+ );
+
+exit:
+ if (pFirmware)
+ rtw_mfree((u8 *)pFirmware, sizeof(RT_FIRMWARE_8188E));
+
+ rtl8188e_InitializeFirmwareVars(padapter);
+
+ return rtStatus;
+}
+
+void rtl8188e_InitializeFirmwareVars(PADAPTER padapter)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+
+ /* Init Fw LPS related. */
+ pwrpriv->bFwCurrentInPSMode = false;
+
+ /* Init H2C cmd. */
+ rtw_write8(padapter, REG_HMETFR, 0x0f);
+
+ /* Init H2C counter. by tynli. 2009.12.09. */
+ pHalData->LastHMEBoxNum = 0;
+}
+
+/* ***********************************************************
+ * Efuse related code
+ * *********************************************************** */
+enum {
+ VOLTAGE_V25 = 0x03,
+ LDOE25_SHIFT = 28 ,
+};
+
+static bool
+hal_EfusePgPacketWrite2ByteHeader(
+ PADAPTER pAdapter,
+ u8 efuseType,
+ u16 *pAddr,
+ PPGPKT_STRUCT pTargetPkt,
+ bool bPseudoTest);
+static bool
+hal_EfusePgPacketWrite1ByteHeader(
+ PADAPTER pAdapter,
+ u8 efuseType,
+ u16 *pAddr,
+ PPGPKT_STRUCT pTargetPkt,
+ bool bPseudoTest);
+static bool
+hal_EfusePgPacketWriteData(
+ PADAPTER pAdapter,
+ u8 efuseType,
+ u16 *pAddr,
+ PPGPKT_STRUCT pTargetPkt,
+ bool bPseudoTest);
+
+static void
+hal_EfusePowerSwitch_RTL8188E(
+ PADAPTER pAdapter,
+ u8 bWrite,
+ u8 PwrState)
+{
+ u8 tempval;
+ u16 tmpV16;
+
+ if (PwrState == true) {
+ rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
+ /* Reset: 0x0000h[28], default valid */
+ tmpV16 = rtw_read16(pAdapter, REG_SYS_FUNC_EN);
+ if (!(tmpV16 & FEN_ELDR)) {
+ tmpV16 |= FEN_ELDR ;
+ rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
+ }
+
+ /* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
+ tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR);
+ if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
+ tmpV16 |= (LOADER_CLK_EN | ANA8M) ;
+ rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
+ }
+
+ if (bWrite == true) {
+ /* Enable LDO 2.5V before read/write action */
+ tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
+ if (IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) {
+ tempval &= 0x87;
+ tempval |= 0x38; /* 0x34[30:27] = 0b'0111, Use LDO 2.25V, Suggested by SD1 Pisa */
+ } else {
+ tempval &= 0x0F;
+ tempval |= (VOLTAGE_V25 << 4);
+ }
+ rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval | 0x80));
+ }
+ } else {
+ rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
+
+ if (bWrite == true) {
+ /* Disable LDO 2.5V after read/write action */
+ tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
+ rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval & 0x7F));
+ }
+ }
+}
+
+static void
+rtl8188e_EfusePowerSwitch(
+ PADAPTER pAdapter,
+ u8 bWrite,
+ u8 PwrState)
+{
+ hal_EfusePowerSwitch_RTL8188E(pAdapter, bWrite, PwrState);
+}
+
+
+
+static bool efuse_read_phymap(
+ PADAPTER Adapter,
+ u8 *pbuf, /* buffer to store efuse physical map */
+ u16 *size /* the max byte to read. will update to byte read */
+)
+{
+ u8 *pos = pbuf;
+ u16 limit = *size;
+ u16 addr = 0;
+ bool reach_end = false;
+
+ /* */
+ /* Refresh efuse init map as all 0xFF. */
+ /* */
+ memset(pbuf, 0xFF, limit);
+
+
+ /* */
+ /* Read physical efuse content. */
+ /* */
+ while (addr < limit) {
+ ReadEFuseByte(Adapter, addr, pos, false);
+ if (*pos != 0xFF) {
+ pos++;
+ addr++;
+ } else {
+ reach_end = true;
+ break;
+ }
+ }
+
+ *size = addr;
+
+ return reach_end;
+
+}
+
+static void
+Hal_EfuseReadEFuse88E(
+ PADAPTER Adapter,
+ u16 _offset,
+ u16 _size_byte,
+ u8 *pbuf,
+ bool bPseudoTest
+)
+{
+ /* u8 efuseTbl[EFUSE_MAP_LEN_88E]; */
+ u8 *efuseTbl = NULL;
+ u8 rtemp8[1];
+ u16 eFuse_Addr = 0;
+ u8 offset, wren;
+ u16 i, j;
+ /* u16 eFuseWord[EFUSE_MAX_SECTION_88E][EFUSE_MAX_WORD_UNIT]; */
+ u16 **eFuseWord = NULL;
+ u16 efuse_utilized = 0;
+ u8 efuse_usage = 0;
+ u8 u1temp = 0;
+
+ /* */
+ /* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
+ /* */
+ if ((_offset + _size_byte) > EFUSE_MAP_LEN_88E) {
+ /* total E-Fuse table is 512bytes */
+ RTW_INFO("Hal_EfuseReadEFuse88E(): Invalid offset(%#x) with read bytes(%#x)!!\n", _offset, _size_byte);
+ goto exit;
+ }
+
+ efuseTbl = (u8 *)rtw_zmalloc(EFUSE_MAP_LEN_88E);
+ if (efuseTbl == NULL) {
+ RTW_INFO("%s: alloc efuseTbl fail!\n", __func__);
+ goto exit;
+ }
+
+ eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, 2);
+ if (eFuseWord == NULL) {
+ RTW_INFO("%s: alloc eFuseWord fail!\n", __func__);
+ goto exit;
+ }
+
+ /* 0. Refresh efuse init map as all oxFF. */
+ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
+ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
+ eFuseWord[i][j] = 0xFFFF;
+
+ /* */
+ /* 1. Read the first byte to check if efuse is empty!!! */
+ /* */
+ /* */
+ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ if (*rtemp8 != 0xFF) {
+ efuse_utilized++;
+ /* RTW_INFO("efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8); */
+ eFuse_Addr++;
+ } else {
+ RTW_INFO("EFUSE is empty efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8);
+ goto exit;
+ }
+
+
+ /* */
+ /* 2. Read real efuse content. Filter PG header and every section data. */
+ /* */
+ while ((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("efuse_Addr-%d efuse_data=%x\n", eFuse_Addr-1, *rtemp8)); */
+
+ /* Check PG header for section num. */
+ if ((*rtemp8 & 0x1F) == 0x0F) { /* extended header */
+ u1temp = ((*rtemp8 & 0xE0) >> 5);
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header u1temp=%x *rtemp&0xE0 0x%x\n", u1temp, *rtemp8 & 0xE0)); */
+
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header u1temp=%x\n", u1temp)); */
+
+ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8)); */
+
+ if ((*rtemp8 & 0x0F) == 0x0F) {
+ eFuse_Addr++;
+ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+
+ if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
+ eFuse_Addr++;
+ continue;
+ } else {
+ offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
+ wren = (*rtemp8 & 0x0F);
+ eFuse_Addr++;
+ }
+ } else {
+ offset = ((*rtemp8 >> 4) & 0x0f);
+ wren = (*rtemp8 & 0x0f);
+ }
+
+ if (offset < EFUSE_MAX_SECTION_88E) {
+ /* Get word enable value from PG header */
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Offset-%d Worden=%x\n", offset, wren)); */
+
+ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
+ /* Check word enable condition in the section */
+ if (!(wren & 0x01)) {
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d\n", eFuse_Addr)); */
+ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ eFuse_Addr++;
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Data=0x%x\n", *rtemp8)); */
+ efuse_utilized++;
+ eFuseWord[offset][i] = (*rtemp8 & 0xff);
+
+
+ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
+ break;
+
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d", eFuse_Addr)); */
+ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ eFuse_Addr++;
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Data=0x%x\n", *rtemp8)); */
+
+ efuse_utilized++;
+ eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
+
+ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
+ break;
+ }
+
+ wren >>= 1;
+
+ }
+ } else { /* deal with error offset,skip error data */
+ RTW_PRINT("invalid offset:0x%02x\n", offset);
+ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
+ /* Check word enable condition in the section */
+ if (!(wren & 0x01)) {
+ eFuse_Addr++;
+ efuse_utilized++;
+ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
+ break;
+ eFuse_Addr++;
+ efuse_utilized++;
+ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
+ break;
+ }
+ }
+ }
+ /* Read next PG header */
+ ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d rtemp 0x%x\n", eFuse_Addr, *rtemp8)); */
+
+ if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
+ efuse_utilized++;
+ eFuse_Addr++;
+ }
+ }
+
+ /* */
+ /* 3. Collect 16 sections and 4 word unit into Efuse map. */
+ /* */
+ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
+ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
+ efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff);
+ efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff);
+ }
+ }
+
+
+ /* */
+ /* 4. Copy from Efuse map to output pointer memory!!! */
+ /* */
+ for (i = 0; i < _size_byte; i++)
+ pbuf[i] = efuseTbl[_offset + i];
+
+ /* */
+ /* 5. Calculate Efuse utilization. */
+ /* */
+ efuse_usage = (u8)((eFuse_Addr * 100) / EFUSE_REAL_CONTENT_LEN_88E);
+ rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_BYTES, (u8 *)&eFuse_Addr);
+
+exit:
+ if (efuseTbl)
+ rtw_mfree(efuseTbl, EFUSE_MAP_LEN_88E);
+
+ if (eFuseWord)
+ rtw_mfree2d((void *)eFuseWord, EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
+}
+
+
+static bool
+Hal_EfuseSwitchToBank(
+ PADAPTER pAdapter,
+ u8 bank,
+ bool bPseudoTest
+)
+{
+ bool bRet = false;
+ u32 value32 = 0;
+
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("Efuse switch bank to %d\n", bank)); */
+ if (bPseudoTest) {
+ fakeEfuseBank = bank;
+ bRet = true;
+ } else
+ bRet = true;
+ return bRet;
+}
+
+
+
+static void
+ReadEFuseByIC(
+ PADAPTER Adapter,
+ u8 efuseType,
+ u16 _offset,
+ u16 _size_byte,
+ u8 *pbuf,
+ bool bPseudoTest
+)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
+#ifdef DBG_IOL_READ_EFUSE_MAP
+ u8 logical_map[512];
+#endif
+
+#ifdef CONFIG_IOL_READ_EFUSE_MAP
+ if (!bPseudoTest) { /* && rtw_IOL_applied(Adapter)) */
+ int ret = _FAIL;
+ if (rtw_IOL_applied(Adapter)) {
+ rtw_hal_power_on(Adapter);
+
+ iol_mode_enable(Adapter, 1);
+#ifdef DBG_IOL_READ_EFUSE_MAP
+ iol_read_efuse(Adapter, 0, _offset, _size_byte, logical_map);
+#else
+ ret = iol_read_efuse(Adapter, 0, _offset, _size_byte, pbuf);
+#endif
+ iol_mode_enable(Adapter, 0);
+
+ if (_SUCCESS == ret)
+ goto exit;
+ }
+ }
+#endif
+ Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
+
+exit:
+
+#ifdef DBG_IOL_READ_EFUSE_MAP
+ if (!memcmp(logical_map, pHalData->efuse_eeprom_data, 0x130) == false) {
+ int i;
+ RTW_INFO("%s compare first 0x130 byte fail\n", __func__);
+ for (i = 0; i < 512; i++) {
+ if (i % 16 == 0)
+ RTW_INFO("0x%03x: ", i);
+ RTW_INFO("%02x ", logical_map[i]);
+ if (i % 16 == 15)
+ RTW_INFO("\n");
+ }
+ RTW_INFO("\n");
+ }
+#endif
+
+ return;
+}
+
+static void
+ReadEFuse_Pseudo(
+ PADAPTER Adapter,
+ u8 efuseType,
+ u16 _offset,
+ u16 _size_byte,
+ u8 *pbuf,
+ bool bPseudoTest
+)
+{
+ Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
+}
+
+static void
+rtl8188e_ReadEFuse(
+ PADAPTER Adapter,
+ u8 efuseType,
+ u16 _offset,
+ u16 _size_byte,
+ u8 *pbuf,
+ bool bPseudoTest
+)
+{
+ if (bPseudoTest)
+ ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
+ else
+ ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
+}
+
+/* Do not support BT */
+static void
+Hal_EFUSEGetEfuseDefinition88E(
+ PADAPTER pAdapter,
+ u8 efuseType,
+ u8 type,
+ void * pOut
+)
+{
+ switch (type) {
+ case TYPE_EFUSE_MAX_SECTION: {
+ u8 *pMax_section;
+ pMax_section = (u8 *)pOut;
+ *pMax_section = EFUSE_MAX_SECTION_88E;
+ }
+ break;
+ case TYPE_EFUSE_REAL_CONTENT_LEN: {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
+ }
+ break;
+ case TYPE_EFUSE_CONTENT_LEN_BANK: {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
+ }
+ break;
+ case TYPE_AVAILABLE_EFUSE_BYTES_BANK: {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
+ }
+ break;
+ case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
+ }
+ break;
+ case TYPE_EFUSE_MAP_LEN: {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = (u16)EFUSE_MAP_LEN_88E;
+ }
+ break;
+ case TYPE_EFUSE_PROTECT_BYTES_BANK: {
+ u8 *pu1Tmp;
+ pu1Tmp = (u8 *)pOut;
+ *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E);
+ }
+ break;
+ default: {
+ u8 *pu1Tmp;
+ pu1Tmp = (u8 *)pOut;
+ *pu1Tmp = 0;
+ }
+ break;
+ }
+}
+
+static void
+Hal_EFUSEGetEfuseDefinition_Pseudo88E(
+ PADAPTER pAdapter,
+ u8 efuseType,
+ u8 type,
+ void * pOut
+)
+{
+ switch (type) {
+ case TYPE_EFUSE_MAX_SECTION: {
+ u8 *pMax_section;
+ pMax_section = (u8 *)pOut;
+ *pMax_section = EFUSE_MAX_SECTION_88E;
+ }
+ break;
+ case TYPE_EFUSE_REAL_CONTENT_LEN: {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
+ }
+ break;
+ case TYPE_EFUSE_CONTENT_LEN_BANK: {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
+ }
+ break;
+ case TYPE_AVAILABLE_EFUSE_BYTES_BANK: {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
+ }
+ break;
+ case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
+ }
+ break;
+ case TYPE_EFUSE_MAP_LEN: {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = (u16)EFUSE_MAP_LEN_88E;
+ }
+ break;
+ case TYPE_EFUSE_PROTECT_BYTES_BANK: {
+ u8 *pu1Tmp;
+ pu1Tmp = (u8 *)pOut;
+ *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E);
+ }
+ break;
+ default: {
+ u8 *pu1Tmp;
+ pu1Tmp = (u8 *)pOut;
+ *pu1Tmp = 0;
+ }
+ break;
+ }
+}
+
+
+static void
+rtl8188e_EFUSE_GetEfuseDefinition(
+ PADAPTER pAdapter,
+ u8 efuseType,
+ u8 type,
+ void *pOut,
+ bool bPseudoTest
+)
+{
+ if (bPseudoTest)
+ Hal_EFUSEGetEfuseDefinition_Pseudo88E(pAdapter, efuseType, type, pOut);
+ else
+ Hal_EFUSEGetEfuseDefinition88E(pAdapter, efuseType, type, pOut);
+}
+
+static u8
+Hal_EfuseWordEnableDataWrite(PADAPTER pAdapter,
+ u16 efuse_addr,
+ u8 word_en,
+ u8 *data,
+ bool bPseudoTest)
+{
+ u16 tmpaddr = 0;
+ u16 start_addr = efuse_addr;
+ u8 badworden = 0x0F;
+ u8 tmpdata[8];
+
+ memset((void *)tmpdata, 0xff, PGPKT_DATA_SIZE);
+
+ if (!(word_en & BIT0)) {
+ tmpaddr = start_addr;
+ efuse_OneByteWrite(pAdapter, start_addr++, data[0], bPseudoTest);
+ efuse_OneByteWrite(pAdapter, start_addr++, data[1], bPseudoTest);
+ phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
+
+ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[0], bPseudoTest);
+ efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[1], bPseudoTest);
+ phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
+
+ if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
+ badworden &= (~BIT0);
+ }
+ if (!(word_en & BIT1)) {
+ tmpaddr = start_addr;
+ efuse_OneByteWrite(pAdapter, start_addr++, data[2], bPseudoTest);
+ efuse_OneByteWrite(pAdapter, start_addr++, data[3], bPseudoTest);
+ phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
+
+ efuse_OneByteRead(pAdapter, tmpaddr , &tmpdata[2], bPseudoTest);
+ efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[3], bPseudoTest);
+ phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
+
+ if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
+ badworden &= (~BIT1);
+ }
+ if (!(word_en & BIT2)) {
+ tmpaddr = start_addr;
+ efuse_OneByteWrite(pAdapter, start_addr++, data[4], bPseudoTest);
+ efuse_OneByteWrite(pAdapter, start_addr++, data[5], bPseudoTest);
+ phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
+
+ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[4], bPseudoTest);
+ efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[5], bPseudoTest);
+ phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
+
+ if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
+ badworden &= (~BIT2);
+ }
+ if (!(word_en & BIT3)) {
+ tmpaddr = start_addr;
+ efuse_OneByteWrite(pAdapter, start_addr++, data[6], bPseudoTest);
+ efuse_OneByteWrite(pAdapter, start_addr++, data[7], bPseudoTest);
+ phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
+
+ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[6], bPseudoTest);
+ efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[7], bPseudoTest);
+ phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
+
+ if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
+ badworden &= (~BIT3);
+ }
+ return badworden;
+}
+
+static u8
+Hal_EfuseWordEnableDataWrite_Pseudo(PADAPTER pAdapter,
+ u16 efuse_addr,
+ u8 word_en,
+ u8 *data,
+ bool bPseudoTest)
+{
+ u8 ret = 0;
+
+ ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
+
+ return ret;
+}
+
+static u8
+rtl8188e_Efuse_WordEnableDataWrite(PADAPTER pAdapter,
+ u16 efuse_addr,
+ u8 word_en,
+ u8 *data,
+ bool bPseudoTest)
+{
+ u8 ret = 0;
+
+ if (bPseudoTest)
+ ret = Hal_EfuseWordEnableDataWrite_Pseudo(pAdapter, efuse_addr, word_en, data, bPseudoTest);
+ else
+ ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
+
+ return ret;
+}
+
+
+static u16
+hal_EfuseGetCurrentSize_8188e(PADAPTER pAdapter,
+ bool bPseudoTest)
+{
+ int bContinual = true;
+
+ u16 efuse_addr = 0;
+ u8 hoffset = 0, hworden = 0;
+ u8 efuse_data, word_cnts = 0;
+
+ if (bPseudoTest)
+ efuse_addr = (u16)(fakeEfuseUsedBytes);
+ else
+ rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseGetCurrentSize_8723A(), start_efuse_addr = %d\n", efuse_addr)); */
+
+ while (bContinual &&
+ efuse_OneByteRead(pAdapter, efuse_addr , &efuse_data, bPseudoTest) &&
+ AVAILABLE_EFUSE_ADDR(efuse_addr)) {
+ if (efuse_data != 0xFF) {
+ if ((efuse_data & 0x1F) == 0x0F) { /* extended header */
+ hoffset = efuse_data;
+ efuse_addr++;
+ efuse_OneByteRead(pAdapter, efuse_addr , &efuse_data, bPseudoTest);
+ if ((efuse_data & 0x0F) == 0x0F) {
+ efuse_addr++;
+ continue;
+ } else {
+ hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
+ hworden = efuse_data & 0x0F;
+ }
+ } else {
+ hoffset = (efuse_data >> 4) & 0x0F;
+ hworden = efuse_data & 0x0F;
+ }
+ word_cnts = Efuse_CalculateWordCnts(hworden);
+ /* read next header */
+ efuse_addr = efuse_addr + (word_cnts * 2) + 1;
+ } else
+ bContinual = false ;
+ }
+
+ if (bPseudoTest) {
+ fakeEfuseUsedBytes = efuse_addr;
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseGetCurrentSize_8723A(), return %d\n", fakeEfuseUsedBytes)); */
+ } else {
+ rtw_hal_set_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseGetCurrentSize_8723A(), return %d\n", efuse_addr)); */
+ }
+
+ return efuse_addr;
+}
+
+static u16
+Hal_EfuseGetCurrentSize_Pseudo(PADAPTER pAdapter,
+ bool bPseudoTest)
+{
+ u16 ret = 0;
+
+ ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest);
+
+ return ret;
+}
+
+
+static u16
+rtl8188e_EfuseGetCurrentSize(
+ PADAPTER pAdapter,
+ u8 efuseType,
+ bool bPseudoTest)
+{
+ u16 ret = 0;
+
+ if (bPseudoTest)
+ ret = Hal_EfuseGetCurrentSize_Pseudo(pAdapter, bPseudoTest);
+ else
+ ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest);
+
+
+ return ret;
+}
+
+
+static int
+hal_EfusePgPacketRead_8188e(
+ PADAPTER pAdapter,
+ u8 offset,
+ u8 *data,
+ bool bPseudoTest)
+{
+ u8 ReadState = PG_STATE_HEADER;
+
+ int bContinual = true;
+ int bDataEmpty = true ;
+
+ u8 efuse_data, word_cnts = 0;
+ u16 efuse_addr = 0;
+ u8 hoffset = 0, hworden = 0;
+ u8 tmpidx = 0;
+ u8 tmpdata[8];
+ u8 max_section = 0;
+ u8 tmp_header = 0;
+
+ EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, (void *)&max_section, bPseudoTest);
+
+ if (data == NULL)
+ return false;
+ if (offset > max_section)
+ return false;
+
+ memset((void *)data, 0xff, sizeof(u8) * PGPKT_DATA_SIZE);
+ memset((void *)tmpdata, 0xff, sizeof(u8) * PGPKT_DATA_SIZE);
+
+
+ /* */
+ /* <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */
+ /* Skip dummy parts to prevent unexpected data read from Efuse. */
+ /* By pass right now. 2009.02.19. */
+ /* */
+ while (bContinual && AVAILABLE_EFUSE_ADDR(efuse_addr)) {
+ /* ------- Header Read ------------- */
+ if (ReadState & PG_STATE_HEADER) {
+ if (efuse_OneByteRead(pAdapter, efuse_addr , &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {
+ if (EXT_HEADER(efuse_data)) {
+ tmp_header = efuse_data;
+ efuse_addr++;
+ efuse_OneByteRead(pAdapter, efuse_addr , &efuse_data, bPseudoTest);
+ if (!ALL_WORDS_DISABLED(efuse_data)) {
+ hoffset = ((tmp_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
+ hworden = efuse_data & 0x0F;
+ } else {
+ RTW_INFO("Error, All words disabled\n");
+ efuse_addr++;
+ continue;
+ }
+ } else {
+ hoffset = (efuse_data >> 4) & 0x0F;
+ hworden = efuse_data & 0x0F;
+ }
+ word_cnts = Efuse_CalculateWordCnts(hworden);
+ bDataEmpty = true ;
+
+ if (hoffset == offset) {
+ for (tmpidx = 0; tmpidx < word_cnts * 2 ; tmpidx++) {
+ if (efuse_OneByteRead(pAdapter, efuse_addr + 1 + tmpidx , &efuse_data, bPseudoTest)) {
+ tmpdata[tmpidx] = efuse_data;
+ if (efuse_data != 0xff)
+ bDataEmpty = false;
+ }
+ }
+ if (bDataEmpty == false)
+ ReadState = PG_STATE_DATA;
+ else { /* read next header */
+ efuse_addr = efuse_addr + (word_cnts * 2) + 1;
+ ReadState = PG_STATE_HEADER;
+ }
+ } else { /* read next header */
+ efuse_addr = efuse_addr + (word_cnts * 2) + 1;
+ ReadState = PG_STATE_HEADER;
+ }
+
+ } else
+ bContinual = false ;
+ }
+ /* ------- Data section Read ------------- */
+ else if (ReadState & PG_STATE_DATA) {
+ efuse_WordEnableDataRead(hworden, tmpdata, data);
+ efuse_addr = efuse_addr + (word_cnts * 2) + 1;
+ ReadState = PG_STATE_HEADER;
+ }
+
+ }
+
+ if ((data[0] == 0xff) && (data[1] == 0xff) && (data[2] == 0xff) && (data[3] == 0xff) &&
+ (data[4] == 0xff) && (data[5] == 0xff) && (data[6] == 0xff) && (data[7] == 0xff))
+ return false;
+ else
+ return true;
+
+}
+
+static int
+Hal_EfusePgPacketRead(PADAPTER pAdapter,
+ u8 offset,
+ u8 *data,
+ bool bPseudoTest)
+{
+ int ret = 0;
+
+ ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest);
+
+
+ return ret;
+}
+
+static int
+Hal_EfusePgPacketRead_Pseudo(PADAPTER pAdapter,
+ u8 offset,
+ u8 *data,
+ bool bPseudoTest)
+{
+ int ret = 0;
+
+ ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest);
+
+ return ret;
+}
+
+static int
+rtl8188e_Efuse_PgPacketRead(PADAPTER pAdapter,
+ u8 offset,
+ u8 *data,
+ bool bPseudoTest)
+{
+ int ret = 0;
+
+ if (bPseudoTest)
+ ret = Hal_EfusePgPacketRead_Pseudo(pAdapter, offset, data, bPseudoTest);
+ else
+ ret = Hal_EfusePgPacketRead(pAdapter, offset, data, bPseudoTest);
+
+ return ret;
+}
+
+static bool
+hal_EfuseFixHeaderProcess(
+ PADAPTER pAdapter,
+ u8 efuseType,
+ PPGPKT_STRUCT pFixPkt,
+ u16 *pAddr,
+ bool bPseudoTest
+)
+{
+ u8 originaldata[8], badworden = 0;
+ u16 efuse_addr = *pAddr;
+ u32 PgWriteSuccess = 0;
+
+ memset((void *)originaldata, 0xff, 8);
+
+ if (Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata, bPseudoTest)) {
+ /* check if data exist */
+ badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pFixPkt->word_en, originaldata, bPseudoTest);
+
+ if (badworden != 0xf) { /* write fail */
+ PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata, bPseudoTest);
+
+ if (!PgWriteSuccess)
+ return false;
+ else
+ efuse_addr = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);
+ } else
+ efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1;
+ } else
+ efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1;
+ *pAddr = efuse_addr;
+ return true;
+}
+
+static bool
+hal_EfusePgPacketWrite2ByteHeader(
+ PADAPTER pAdapter,
+ u8 efuseType,
+ u16 *pAddr,
+ PPGPKT_STRUCT pTargetPkt,
+ bool bPseudoTest)
+{
+ bool bRet = false, bContinual = true;
+ u16 efuse_addr = *pAddr, efuse_max_available_len = 0;
+ u8 pg_header = 0, tmp_header = 0, pg_header_temp = 0;
+ u8 repeatcnt = 0;
+
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("Wirte 2byte header\n")); */
+ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len, bPseudoTest);
+
+ while (efuse_addr < efuse_max_available_len) {
+ pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("pg_header = 0x%x\n", pg_header)); */
+ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
+ phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
+ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
+ phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
+ while (tmp_header == 0xFF || pg_header != tmp_header) {
+ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("Repeat over limit for pg_header!!\n")); */
+ return false;
+ }
+
+ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
+ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
+ }
+
+ /* to write ext_header */
+ if (tmp_header == pg_header) {
+ efuse_addr++;
+ pg_header_temp = pg_header;
+ pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
+
+ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
+ phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
+ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
+ phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
+ while (tmp_header == 0xFF || pg_header != tmp_header) {
+ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("Repeat over limit for ext_header!!\n")); */
+ return false;
+ }
+
+ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
+ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
+ }
+
+ if ((tmp_header & 0x0F) == 0x0F) { /* word_en PG fail */
+ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("Repeat over limit for word_en!!\n")); */
+ return false;
+ } else {
+ efuse_addr++;
+ continue;
+ }
+ } else if (pg_header != tmp_header) { /* offset PG fail */
+ PGPKT_STRUCT fixPkt;
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("Error condition for offset PG fail, need to cover the existed data\n")); */
+ fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1);
+ fixPkt.word_en = tmp_header & 0x0F;
+ fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
+ if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
+ return false;
+ } else {
+ bRet = true;
+ break;
+ }
+ } else if ((tmp_header & 0x1F) == 0x0F) { /* wrong extended header */
+ efuse_addr += 2;
+ continue;
+ }
+ }
+
+ *pAddr = efuse_addr;
+ return bRet;
+}
+
+static bool
+hal_EfusePgPacketWrite1ByteHeader(
+ PADAPTER pAdapter,
+ u8 efuseType,
+ u16 *pAddr,
+ PPGPKT_STRUCT pTargetPkt,
+ bool bPseudoTest)
+{
+ bool bRet = false;
+ u8 pg_header = 0, tmp_header = 0;
+ u16 efuse_addr = *pAddr;
+ u8 repeatcnt = 0;
+
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("Wirte 1byte header\n")); */
+ pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
+
+ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
+ phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
+
+ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
+
+ phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
+
+ while (tmp_header == 0xFF || pg_header != tmp_header) {
+ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
+ return false;
+ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
+ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
+ }
+
+ if (pg_header == tmp_header)
+ bRet = true;
+ else {
+ PGPKT_STRUCT fixPkt;
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("Error condition for fixed PG packet, need to cover the existed data\n")); */
+ fixPkt.offset = (tmp_header >> 4) & 0x0F;
+ fixPkt.word_en = tmp_header & 0x0F;
+ fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
+ if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
+ return false;
+ }
+
+ *pAddr = efuse_addr;
+ return bRet;
+}
+
+static bool
+hal_EfusePgPacketWriteData(
+ PADAPTER pAdapter,
+ u8 efuseType,
+ u16 *pAddr,
+ PPGPKT_STRUCT pTargetPkt,
+ bool bPseudoTest)
+{
+ bool bRet = false;
+ u16 efuse_addr = *pAddr;
+ u8 badworden = 0;
+ u32 PgWriteSuccess = 0;
+
+ badworden = 0x0f;
+ badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
+ if (badworden == 0x0F) {
+ /* write ok */
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePgPacketWriteData ok!!\n")); */
+ return true;
+ } else {
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePgPacketWriteData Fail!!\n")); */
+ /* reorganize other pg packet */
+
+ PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
+
+ if (!PgWriteSuccess)
+ return false;
+ else
+ return true;
+ }
+
+ return bRet;
+}
+
+static bool
+hal_EfusePgPacketWriteHeader(
+ PADAPTER pAdapter,
+ u8 efuseType,
+ u16 *pAddr,
+ PPGPKT_STRUCT pTargetPkt,
+ bool bPseudoTest)
+{
+ bool bRet = false;
+
+ if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
+ bRet = hal_EfusePgPacketWrite2ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
+ else
+ bRet = hal_EfusePgPacketWrite1ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
+
+ return bRet;
+}
+
+static bool
+wordEnMatched(
+ PPGPKT_STRUCT pTargetPkt,
+ PPGPKT_STRUCT pCurPkt,
+ u8 *pWden
+)
+{
+ u8 match_word_en = 0x0F; /* default all words are disabled */
+ u8 i;
+
+ /* check if the same words are enabled both target and current PG packet */
+ if (((pTargetPkt->word_en & BIT0) == 0) &&
+ ((pCurPkt->word_en & BIT0) == 0)) {
+ match_word_en &= ~BIT0; /* enable word 0 */
+ }
+ if (((pTargetPkt->word_en & BIT1) == 0) &&
+ ((pCurPkt->word_en & BIT1) == 0)) {
+ match_word_en &= ~BIT1; /* enable word 1 */
+ }
+ if (((pTargetPkt->word_en & BIT2) == 0) &&
+ ((pCurPkt->word_en & BIT2) == 0)) {
+ match_word_en &= ~BIT2; /* enable word 2 */
+ }
+ if (((pTargetPkt->word_en & BIT3) == 0) &&
+ ((pCurPkt->word_en & BIT3) == 0)) {
+ match_word_en &= ~BIT3; /* enable word 3 */
+ }
+
+ *pWden = match_word_en;
+
+ if (match_word_en != 0xf)
+ return true;
+ else
+ return false;
+}
+
+static bool
+hal_EfuseCheckIfDatafollowed(
+ PADAPTER pAdapter,
+ u8 word_cnts,
+ u16 startAddr,
+ bool bPseudoTest
+)
+{
+ bool bRet = false;
+ u8 i, efuse_data;
+
+ for (i = 0; i < (word_cnts * 2) ; i++) {
+ if (efuse_OneByteRead(pAdapter, (startAddr + i) , &efuse_data, bPseudoTest) && (efuse_data != 0xFF))
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+static bool
+hal_EfusePartialWriteCheck(
+ PADAPTER pAdapter,
+ u8 efuseType,
+ u16 *pAddr,
+ PPGPKT_STRUCT pTargetPkt,
+ bool bPseudoTest
+)
+{
+ bool bRet = false;
+ u8 i, efuse_data = 0, cur_header = 0;
+ u8 new_wden = 0, matched_wden = 0, badworden = 0;
+ u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0;
+ PGPKT_STRUCT curPkt;
+
+ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len, bPseudoTest);
+ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&efuse_max, bPseudoTest);
+
+ if (efuseType == EFUSE_WIFI) {
+ if (bPseudoTest)
+ startAddr = (u16)(fakeEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN);
+ else {
+ rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);
+ startAddr %= EFUSE_REAL_CONTENT_LEN;
+ }
+ } else {
+ if (bPseudoTest)
+ startAddr = (u16)(fakeBTEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN);
+ else
+ startAddr = (u16)(BTEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN);
+ }
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePartialWriteCheck(), startAddr=%d\n", startAddr)); */
+
+ while (1) {
+ if (startAddr >= efuse_max_available_len) {
+ bRet = false;
+ break;
+ }
+
+ if (efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {
+ if (EXT_HEADER(efuse_data)) {
+ cur_header = efuse_data;
+ startAddr++;
+ efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest);
+ if (ALL_WORDS_DISABLED(efuse_data)) {
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("Error condition, all words disabled")); */
+ bRet = false;
+ break;
+ } else {
+ curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
+ curPkt.word_en = efuse_data & 0x0F;
+ }
+ } else {
+ cur_header = efuse_data;
+ curPkt.offset = (cur_header >> 4) & 0x0F;
+ curPkt.word_en = cur_header & 0x0F;
+ }
+
+ curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
+ /* if same header is found but no data followed */
+ /* write some part of data followed by the header. */
+ if ((curPkt.offset == pTargetPkt->offset) &&
+ (!hal_EfuseCheckIfDatafollowed(pAdapter, curPkt.word_cnts, startAddr + 1, bPseudoTest)) &&
+ wordEnMatched(pTargetPkt, &curPkt, &matched_wden)) {
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("Need to partial write data by the previous wrote header\n")); */
+ /* Here to write partial data */
+ badworden = Efuse_WordEnableDataWrite(pAdapter, startAddr + 1, matched_wden, pTargetPkt->data, bPseudoTest);
+ if (badworden != 0x0F) {
+ u32 PgWriteSuccess = 0;
+ /* if write fail on some words, write these bad words again */
+
+ PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
+
+ if (!PgWriteSuccess) {
+ bRet = false; /* write fail, return */
+ break;
+ }
+ }
+ /* partial write ok, update the target packet for later use */
+ for (i = 0; i < 4; i++) {
+ if ((matched_wden & (0x1 << i)) == 0) { /* this word has been written */
+ pTargetPkt->word_en |= (0x1 << i); /* disable the word */
+ }
+ }
+ pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
+ }
+ /* read from next header */
+ startAddr = startAddr + (curPkt.word_cnts * 2) + 1;
+ } else {
+ /* not used header, 0xff */
+ *pAddr = startAddr;
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("Started from unused header offset=%d\n", startAddr)); */
+ bRet = true;
+ break;
+ }
+ }
+ return bRet;
+}
+
+static bool
+hal_EfusePgCheckAvailableAddr(
+ PADAPTER pAdapter,
+ u8 efuseType,
+ bool bPseudoTest
+)
+{
+ u16 efuse_max_available_len = 0;
+
+ /* Change to check TYPE_EFUSE_MAP_LEN ,beacuse 8188E raw 256,logic map over 256. */
+ EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&efuse_max_available_len, false);
+
+ /* EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&efuse_max_available_len, bPseudoTest); */
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("efuse_max_available_len = %d\n", efuse_max_available_len)); */
+
+ if (Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest) >= efuse_max_available_len) {
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePgCheckAvailableAddr error!!\n")); */
+ return false;
+ }
+ return true;
+}
+
+static void
+hal_EfuseConstructPGPkt(
+ u8 offset,
+ u8 word_en,
+ u8 *pData,
+ PPGPKT_STRUCT pTargetPkt
+
+)
+{
+ memset((void *)pTargetPkt->data, 0xFF, sizeof(u8) * 8);
+ pTargetPkt->offset = offset;
+ pTargetPkt->word_en = word_en;
+ efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
+ pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
+
+ /* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseConstructPGPkt(), targetPkt, offset=%d, word_en=0x%x, word_cnts=%d\n", pTargetPkt->offset, pTargetPkt->word_en, pTargetPkt->word_cnts)); */
+}
+
+static bool
+hal_EfusePgPacketWrite_BT(
+ PADAPTER pAdapter,
+ u8 offset,
+ u8 word_en,
+ u8 *pData,
+ bool bPseudoTest
+)
+{
+ PGPKT_STRUCT targetPkt;
+ u16 startAddr = 0;
+ u8 efuseType = EFUSE_BT;
+
+ if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
+ return false;
+
+ hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
+
+ if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
+ return false;
+
+ if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
+ return false;
+
+ if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
+ return false;
+
+ return true;
+}
+
+static bool
+hal_EfusePgPacketWrite_8188e(
+ PADAPTER pAdapter,
+ u8 offset,
+ u8 word_en,
+ u8 *pData,
+ bool bPseudoTest
+)
+{
+ PGPKT_STRUCT targetPkt;
+ u16 startAddr = 0;
+ u8 efuseType = EFUSE_WIFI;
+
+ if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
+ return false;
+
+ hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
+
+ if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
+ return false;
+
+ if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
+ return false;
+
+ if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
+ return false;
+
+ return true;
+}
+
+
+static int
+Hal_EfusePgPacketWrite_Pseudo(PADAPTER pAdapter,
+ u8 offset,
+ u8 word_en,
+ u8 *data,
+ bool bPseudoTest)
+{
+ int ret;
+
+ ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest);
+
+ return ret;
+}
+
+static int
+Hal_EfusePgPacketWrite(PADAPTER pAdapter,
+ u8 offset,
+ u8 word_en,
+ u8 *data,
+ bool bPseudoTest)
+{
+ int ret = 0;
+ ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest);
+
+
+ return ret;
+}
+
+static int
+rtl8188e_Efuse_PgPacketWrite(PADAPTER pAdapter,
+ u8 offset,
+ u8 word_en,
+ u8 *data,
+ bool bPseudoTest)
+{
+ int ret;
+
+ if (bPseudoTest)
+ ret = Hal_EfusePgPacketWrite_Pseudo(pAdapter, offset, word_en, data, bPseudoTest);
+ else
+ ret = Hal_EfusePgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest);
+ return ret;
+}
+
+static void read_chip_version_8188e(PADAPTER padapter)
+{
+ u32 value32;
+ HAL_DATA_TYPE *pHalData;
+
+ pHalData = GET_HAL_DATA(padapter);
+
+ value32 = rtw_read32(padapter, REG_SYS_CFG);
+ pHalData->version_id.ICType = CHIP_8188E;
+ pHalData->version_id.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
+
+ pHalData->version_id.RFType = RF_TYPE_1T1R;
+ pHalData->version_id.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
+ pHalData->version_id.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /* IC version (CUT) */
+
+ /* For regulator mode. by tynli. 2011.01.14 */
+ pHalData->RegulatorMode = ((value32 & TRP_BT_EN) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
+
+ pHalData->version_id.ROMVer = 0; /* ROM code version. */
+ pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
+
+ rtw_hal_config_rftype(padapter);
+ dump_chip_info(pHalData->version_id);
+}
+
+void rtl8188e_start_thread(_adapter *padapter)
+{
+}
+
+void rtl8188e_stop_thread(_adapter *padapter)
+{
+}
+
+static void hal_notch_filter_8188e(_adapter *adapter, bool enable)
+{
+ if (enable) {
+ RTW_INFO("Enable notch filter\n");
+ rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT1);
+ } else {
+ RTW_INFO("Disable notch filter\n");
+ rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT1);
+ }
+}
+
+static void update_ra_mask_8188e(_adapter *padapter, struct sta_info *psta, struct macid_cfg *h2c_macid_cfg)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
+
+ if (hal_data->fw_ractrl == true) {
+ u8 arg[4] = {0};
+
+ arg[0] = h2c_macid_cfg->mac_id;/* MACID */
+ arg[1] = h2c_macid_cfg->rate_id;
+ arg[2] = (h2c_macid_cfg->ignore_bw << 4) | h2c_macid_cfg->short_gi;
+ arg[3] = psta->init_rate;
+ rtl8188e_set_raid_cmd(padapter, h2c_macid_cfg->ra_mask, arg, h2c_macid_cfg->bandwidth);
+ } else {
+
+#if (RATE_ADAPTIVE_SUPPORT == 1)
+
+ odm_ra_update_rate_info_8188e(
+ &(hal_data->odmpriv),
+ h2c_macid_cfg->mac_id,
+ h2c_macid_cfg->rate_id,
+ h2c_macid_cfg->ra_mask,
+ h2c_macid_cfg->short_gi
+ );
+
+#endif
+ }
+
+}
+
+void init_hal_spec_8188e(_adapter *adapter)
+{
+ struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
+
+ hal_spec->ic_name = "rtl8188e";
+ hal_spec->macid_num = 64;
+ hal_spec->sec_cam_ent_num = 32;
+ hal_spec->sec_cap = 0;
+ hal_spec->rfpath_num_2g = 1;
+ hal_spec->rfpath_num_5g = 0;
+ hal_spec->max_tx_cnt = 1;
+ hal_spec->tx_nss_num = 1;
+ hal_spec->rx_nss_num = 1;
+ hal_spec->band_cap = BAND_CAP_2G;
+ hal_spec->bw_cap = BW_CAP_20M | BW_CAP_40M;
+ hal_spec->port_num = 2;
+ hal_spec->proto_cap = PROTO_CAP_11B | PROTO_CAP_11G | PROTO_CAP_11N;
+ hal_spec->wl_func = 0
+ | WL_FUNC_P2P
+ | WL_FUNC_MIRACAST
+ | WL_FUNC_TDLS
+ ;
+}
+
+#ifdef CONFIG_RFKILL_POLL
+bool rtl8188e_gpio_radio_on_off_check(_adapter *adapter, u8 *valid)
+{
+ u32 tmp32;
+ bool ret;
+
+ *valid = 0;
+ return false; /* unblock */
+}
+#endif
+
+void rtl8188e_init_default_value(_adapter *adapter)
+{
+ HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
+
+ adapter->registrypriv.wireless_mode = WIRELESS_11BG_24N;
+}
+
+void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
+{
+ pHalFunc->dm_init = &rtl8188e_init_dm_priv;
+ pHalFunc->dm_deinit = &rtl8188e_deinit_dm_priv;
+
+ pHalFunc->read_chip_version = read_chip_version_8188e;
+
+ pHalFunc->update_ra_mask_handler = update_ra_mask_8188e;
+
+ pHalFunc->set_chnl_bw_handler = &PHY_SetSwChnlBWMode8188E;
+
+ pHalFunc->set_tx_power_level_handler = &PHY_SetTxPowerLevel8188E;
+ pHalFunc->get_tx_power_level_handler = &PHY_GetTxPowerLevel8188E;
+
+ pHalFunc->get_tx_power_index_handler = &PHY_GetTxPowerIndex_8188E;
+
+ pHalFunc->hal_dm_watchdog = &rtl8188e_HalDmWatchDog;
+
+ pHalFunc->run_thread = &rtl8188e_start_thread;
+ pHalFunc->cancel_thread = &rtl8188e_stop_thread;
+
+ pHalFunc->read_bbreg = &PHY_QueryBBReg8188E;
+ pHalFunc->write_bbreg = &PHY_SetBBReg8188E;
+ pHalFunc->read_rfreg = &PHY_QueryRFReg8188E;
+ pHalFunc->write_rfreg = &PHY_SetRFReg8188E;
+
+
+ /* Efuse related function */
+ pHalFunc->EfusePowerSwitch = &rtl8188e_EfusePowerSwitch;
+ pHalFunc->ReadEFuse = &rtl8188e_ReadEFuse;
+ pHalFunc->EFUSEGetEfuseDefinition = &rtl8188e_EFUSE_GetEfuseDefinition;
+ pHalFunc->EfuseGetCurrentSize = &rtl8188e_EfuseGetCurrentSize;
+ pHalFunc->Efuse_PgPacketRead = &rtl8188e_Efuse_PgPacketRead;
+ pHalFunc->Efuse_PgPacketWrite = &rtl8188e_Efuse_PgPacketWrite;
+ pHalFunc->Efuse_WordEnableDataWrite = &rtl8188e_Efuse_WordEnableDataWrite;
+
+#ifdef DBG_CONFIG_ERROR_DETECT
+ pHalFunc->sreset_init_value = &sreset_init_value;
+ pHalFunc->sreset_reset_value = &sreset_reset_value;
+ pHalFunc->silentreset = &sreset_reset;
+ pHalFunc->sreset_xmit_status_check = &rtl8188e_sreset_xmit_status_check;
+ pHalFunc->sreset_linked_status_check = &rtl8188e_sreset_linked_status_check;
+ pHalFunc->sreset_get_wifi_status = &sreset_get_wifi_status;
+ pHalFunc->sreset_inprogress = &sreset_inprogress;
+#endif /* DBG_CONFIG_ERROR_DETECT */
+
+ pHalFunc->GetHalODMVarHandler = GetHalODMVar;
+ pHalFunc->SetHalODMVarHandler = SetHalODMVar;
+
+#ifdef CONFIG_IOL
+ pHalFunc->IOL_exec_cmds_sync = &rtl8188e_IOL_exec_cmds_sync;
+#endif
+
+ pHalFunc->hal_notch_filter = &hal_notch_filter_8188e;
+ pHalFunc->fill_h2c_cmd = &FillH2CCmd_88E;
+ pHalFunc->fill_fake_txdesc = &rtl8188e_fill_fake_txdesc;
+ pHalFunc->fw_dl = &rtl8188e_FirmwareDownload;
+ pHalFunc->hal_get_tx_buff_rsvd_page_num = &GetTxBufferRsvdPageNum8188E;
+
+#ifdef CONFIG_GPIO_API
+ pHalFunc->hal_gpio_func_check = &rtl8188e_GpioFuncCheck;
+#endif
+#ifdef CONFIG_RFKILL_POLL
+ pHalFunc->hal_radio_onoff_check = rtl8188e_gpio_radio_on_off_check;
+#endif
+}
+
+u8 GetEEPROMSize8188E(PADAPTER padapter)
+{
+ u8 size = 0;
+ u32 cr;
+
+ cr = rtw_read16(padapter, REG_9346CR);
+ /* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */
+ size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
+
+ RTW_INFO("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46");
+
+ return size;
+}
+
+/* -------------------------------------------------------------------------
+ *
+ * LLT R/W/Init function
+ *
+ * ------------------------------------------------------------------------- */
+static s32 _LLTWrite(PADAPTER padapter, u32 address, u32 data)
+{
+ s32 status = _SUCCESS;
+ s8 count = POLLING_LLT_THRESHOLD;
+ u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
+
+ rtw_write32(padapter, REG_LLT_INIT, value);
+
+ /* polling */
+ do {
+ value = rtw_read32(padapter, REG_LLT_INIT);
+ if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
+ break;
+ } while (--count);
+
+ if (count <= 0) {
+ RTW_INFO("Failed to polling write LLT done at address %d!\n", address);
+ status = _FAIL;
+ }
+
+ return status;
+}
+
+static u8 _LLTRead(PADAPTER padapter, u32 address)
+{
+ s32 count = POLLING_LLT_THRESHOLD;
+ u32 value = _LLT_INIT_ADDR(address) | _LLT_OP(_LLT_READ_ACCESS);
+ u16 LLTReg = REG_LLT_INIT;
+
+
+ rtw_write32(padapter, LLTReg, value);
+
+ /* polling and get value */
+ do {
+ value = rtw_read32(padapter, LLTReg);
+ if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
+ return (u8)value;
+ } while (--count);
+
+
+
+
+ return 0xFF;
+}
+
+s32 InitLLTTable(PADAPTER padapter, u8 txpktbuf_bndy)
+{
+ s32 status = _FAIL;
+ u32 i;
+ u32 Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER_8188E(padapter);/* 176, 22k */
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+#if defined(CONFIG_IOL_LLT)
+ if (rtw_IOL_applied(padapter))
+ status = iol_InitLLTTable(padapter, txpktbuf_bndy);
+ else
+#endif
+ {
+ for (i = 0; i < (txpktbuf_bndy - 1); i++) {
+ status = _LLTWrite(padapter, i, i + 1);
+ if (_SUCCESS != status)
+ return status;
+ }
+
+ /* end of list */
+ status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
+ if (_SUCCESS != status)
+ return status;
+
+ /* Make the other pages as ring buffer */
+ /* This ring buffer is used as beacon buffer if we config this MAC as two MAC transfer. */
+ /* Otherwise used as local loopback buffer. */
+ for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
+ status = _LLTWrite(padapter, i, (i + 1));
+ if (_SUCCESS != status)
+ return status;
+ }
+
+ /* Let last entry point to the start entry of ring buffer */
+ status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
+ if (_SUCCESS != status)
+ return status;
+ }
+
+ return status;
+}
+
+void
+Hal_InitPGData88E(PADAPTER padapter)
+{
+
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ u32 i;
+ u16 value16;
+
+ if (false == pHalData->bautoload_fail_flag) {
+ /* autoload OK. */
+ if (is_boot_from_eeprom(padapter)) {
+ /* Read all Content from EEPROM or EFUSE. */
+ for (i = 0; i < HWSET_MAX_SIZE; i += 2) {
+ /* value16 = EF2Byte(ReadEEprom(pAdapter, (u16) (i>>1)));
+ * *((u16*)(&PROMContent[i])) = value16; */
+ }
+ } else {
+ /* Read EFUSE real map to shadow. */
+ EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+ }
+ } else {
+ /* autoload fail */
+ /* pHalData->AutoloadFailFlag = true; */
+ /* update to default value 0xFF */
+ if (!is_boot_from_eeprom(padapter))
+ EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+ }
+
+#ifdef CONFIG_EFUSE_CONFIG_FILE
+ if (check_phy_efuse_tx_power_info_valid(padapter) == false) {
+ if (Hal_readPGDataFromConfigFile(padapter) != _SUCCESS)
+ RTW_ERR("invalid phy efuse and read from file fail, will use driver default!!\n");
+ }
+#endif
+}
+
+void
+Hal_EfuseParseIDCode88E(
+ PADAPTER padapter,
+ u8 *hwinfo
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ u16 EEPROMId;
+
+
+ /* Checl 0x8129 again for making sure autoload status!! */
+ EEPROMId = le16_to_cpu(*((__le16 *)hwinfo));
+ if (EEPROMId != RTL_EEPROM_ID) {
+ RTW_INFO("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
+ pHalData->bautoload_fail_flag = true;
+ } else
+ pHalData->bautoload_fail_flag = false;
+
+ RTW_INFO("EEPROM ID=0x%04x\n", EEPROMId);
+}
+
+void Hal_ReadPowerSavingMode88E(
+ PADAPTER padapter,
+ u8 *hwinfo,
+ bool AutoLoadFail
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
+ u8 tmpvalue;
+
+ if (AutoLoadFail) {
+ pwrctl->bHWPowerdown = false;
+ pwrctl->bSupportRemoteWakeup = false;
+ } else {
+
+ /* hw power down mode selection , 0:rf-off / 1:power down */
+
+ if (padapter->registrypriv.hwpdn_mode == 2)
+ pwrctl->bHWPowerdown = (hwinfo[EEPROM_RF_FEATURE_OPTION_88E] & BIT4);
+ else
+ pwrctl->bHWPowerdown = padapter->registrypriv.hwpdn_mode;
+
+ /* decide hw if support remote wakeup function */
+ /* if hw supported, 8051 (SIE) will generate WeakUP signal( D+/D- toggle) when autoresume */
+ pwrctl->bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0] & BIT1) ? true : false;
+
+ RTW_INFO("%s...bHWPwrPindetect(%x)-bHWPowerdown(%x) ,bSupportRemoteWakeup(%x)\n", __func__,
+ pwrctl->bHWPwrPindetect, pwrctl->bHWPowerdown, pwrctl->bSupportRemoteWakeup);
+
+ RTW_INFO("### PS params=> power_mgnt(%x),usbss_enable(%x) ###\n", padapter->registrypriv.power_mgnt, padapter->registrypriv.usbss_enable);
+
+ }
+
+}
+
+void
+Hal_ReadTxPowerInfo88E(
+ PADAPTER padapter,
+ u8 *PROMContent,
+ bool AutoLoadFail
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ TxPowerInfo24G pwrInfo24G;
+
+ hal_load_txpwr_info(padapter, &pwrInfo24G, NULL, PROMContent);
+
+ /* 2010/10/19 MH Add Regulator recognize for EU. */
+ if (!AutoLoadFail) {
+ struct registry_priv *registry_par = &padapter->registrypriv;
+
+ if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
+ pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION & 0x7); /* bit0~2 */
+ else
+ pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x7); /* bit0~2 */
+
+ } else
+ pHalData->EEPROMRegulatory = 0;
+ RTW_INFO("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory);
+
+}
+
+
+void
+Hal_EfuseParseXtal_8188E(
+ PADAPTER pAdapter,
+ u8 *hwinfo,
+ bool AutoLoadFail
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+
+ if (!AutoLoadFail) {
+ pHalData->crystal_cap = hwinfo[EEPROM_XTAL_88E];
+ if (pHalData->crystal_cap == 0xFF)
+ pHalData->crystal_cap = EEPROM_Default_CrystalCap_88E;
+ } else
+ pHalData->crystal_cap = EEPROM_Default_CrystalCap_88E;
+ RTW_INFO("crystal_cap: 0x%2x\n", pHalData->crystal_cap);
+}
+
+void
+Hal_ReadPAType_8188E(
+ PADAPTER Adapter,
+ u8 *PROMContent,
+ bool AutoloadFail
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 PA_LNAType_2G = 0;
+
+ if (!AutoloadFail) {
+ if (GetRegAmplifierType2G(Adapter) == 0) { /* AUTO*/
+
+ /* PA & LNA Type */
+ PA_LNAType_2G = LE_BITS_TO_1BYTE(&PROMContent[EEPROM_RFE_OPTION_8188E], 2, 2); /* 0xCA[3:2] */
+ /*
+ ePA/eLNA sel.(ePA+eLNA=0x0, ePA+iLNA enable = 0x1, iPA+eLNA enable =0x2, iPA+iLNA=0x3)
+ */
+ switch (PA_LNAType_2G) {
+ case 0:
+ pHalData->ExternalPA_2G = 1;
+ pHalData->ExternalLNA_2G = 1;
+ break;
+ case 1:
+ pHalData->ExternalPA_2G = 1;
+ pHalData->ExternalLNA_2G = 0;
+ break;
+ case 2:
+ pHalData->ExternalPA_2G = 0;
+ pHalData->ExternalLNA_2G = 1;
+ break;
+ case 3:
+ default:
+ pHalData->ExternalPA_2G = 0;
+ pHalData->ExternalLNA_2G = 0;
+ break;
+ }
+ } else {
+ pHalData->ExternalPA_2G = (GetRegAmplifierType2G(Adapter) & ODM_BOARD_EXT_PA) ? 1 : 0;
+ pHalData->ExternalLNA_2G = (GetRegAmplifierType2G(Adapter) & ODM_BOARD_EXT_LNA) ? 1 : 0;
+ }
+ } else {
+ pHalData->ExternalPA_2G = EEPROM_Default_PAType;
+ pHalData->external_pa_5g = EEPROM_Default_PAType;
+ pHalData->ExternalLNA_2G = EEPROM_Default_LNAType;
+ pHalData->external_lna_5g = EEPROM_Default_LNAType;
+
+ if (GetRegAmplifierType2G(Adapter) == 0) {
+ /* AUTO*/
+ pHalData->ExternalPA_2G = EEPROM_Default_PAType;
+ pHalData->ExternalLNA_2G = EEPROM_Default_LNAType;
+ } else {
+ pHalData->ExternalPA_2G = (GetRegAmplifierType2G(Adapter) & ODM_BOARD_EXT_PA) ? 1 : 0;
+ pHalData->ExternalLNA_2G = (GetRegAmplifierType2G(Adapter) & ODM_BOARD_EXT_LNA) ? 1 : 0;
+ }
+ }
+ RTW_INFO("pHalData->ExternalPA_2G = %d , pHalData->ExternalLNA_2G = %d\n", pHalData->ExternalPA_2G, pHalData->ExternalLNA_2G);
+}
+
+void
+Hal_ReadAmplifierType_8188E(
+ PADAPTER Adapter,
+ u8 * PROMContent,
+ bool AutoloadFail
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 GLNA_type = 0;
+
+ if (!AutoloadFail) {
+ if (GetRegGLNAType(Adapter) == 0) /* AUTO */
+ GLNA_type = LE_BITS_TO_1BYTE(&PROMContent[EEPROM_RFE_OPTION_8188E], 4, 3); /* 0xCA[6:4] */
+ else
+ GLNA_type = GetRegGLNAType(Adapter) & 0x7;
+ } else {
+ if (GetRegGLNAType(Adapter) == 0) /* AUTO */
+ GLNA_type = 0;
+ else
+ GLNA_type = GetRegGLNAType(Adapter) & 0x7;
+ }
+ /*
+ Ext-LNA Gain sel.(form 10dB to 24dB, 1table/2dB,ext: 000=10dB, 001=12dB...)
+ */
+ switch (GLNA_type) {
+ case 0:
+ pHalData->TypeGLNA = 0x1; /* (10dB) */
+ break;
+ case 2:
+ pHalData->TypeGLNA = 0x2; /* (14dB) */
+ break;
+ default:
+ pHalData->TypeGLNA = 0x0; /* (others not support) */
+ break;
+ }
+ RTW_INFO("pHalData->TypeGLNA is 0x%x\n", pHalData->TypeGLNA);
+}
+
+void
+Hal_ReadRFEType_8188E(
+ PADAPTER Adapter,
+ u8 * PROMContent,
+ bool AutoloadFail
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ /* Keep the same flow as 8192EU to be extensible */
+ const u8 RFETypeMaxVal = 1, RFETypeMask = 0x1;
+
+ if (!AutoloadFail) {
+ if (GetRegRFEType(Adapter) != 64) {
+ pHalData->rfe_type = GetRegRFEType(Adapter);
+ /*
+ Above 1, rfe_type is filled the default value.
+ */
+ if (pHalData->rfe_type > RFETypeMaxVal)
+ pHalData->rfe_type = EEPROM_DEFAULT_RFE_OPTION_8188E;
+
+ } else if ((0xFF == PROMContent[EEPROM_RFE_OPTION_8188E]) ||
+ ((pHalData->ExternalPA_2G == 0) && (pHalData->ExternalLNA_2G == 0)))
+ pHalData->rfe_type = EEPROM_DEFAULT_RFE_OPTION_8188E;
+ else {
+ /*
+ type 0:0x00 for 88EE/ER_HP RFE control
+ */
+ pHalData->rfe_type = PROMContent[EEPROM_RFE_OPTION_8188E] & RFETypeMask; /* 0xCA[1:0] */
+ }
+ } else {
+ if (GetRegRFEType(Adapter) != 64) {
+ pHalData->rfe_type = GetRegRFEType(Adapter);
+ /*
+ Above 3, rfe_type is filled the default value.
+ */
+ if (pHalData->rfe_type > RFETypeMaxVal)
+ pHalData->rfe_type = EEPROM_DEFAULT_RFE_OPTION_8188E;
+
+ } else
+ pHalData->rfe_type = EEPROM_DEFAULT_RFE_OPTION_8188E;
+
+ }
+
+ RTW_INFO("pHalData->rfe_type is 0x%x\n", pHalData->rfe_type);
+}
+
+void
+Hal_EfuseParseBoardType88E(
+ PADAPTER pAdapter,
+ u8 *hwinfo,
+ bool AutoLoadFail
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+
+ if (!AutoLoadFail) {
+ pHalData->InterfaceSel = ((hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0xE0) >> 5);
+ if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
+ pHalData->InterfaceSel = (EEPROM_DEFAULT_BOARD_OPTION & 0xE0) >> 5;
+ } else
+ pHalData->InterfaceSel = 0;
+ RTW_INFO("Board Type: 0x%2x\n", pHalData->InterfaceSel);
+}
+
+void
+Hal_EfuseParseEEPROMVer88E(
+ PADAPTER padapter,
+ u8 *hwinfo,
+ bool AutoLoadFail
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ if (!AutoLoadFail) {
+ pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_88E];
+ if (pHalData->EEPROMVersion == 0xFF)
+ pHalData->EEPROMVersion = EEPROM_Default_Version;
+ } else
+ pHalData->EEPROMVersion = 1;
+}
+
+void
+rtl8188e_EfuseParseChnlPlan(
+ PADAPTER padapter,
+ u8 *hwinfo,
+ bool AutoLoadFail
+)
+{
+ padapter->mlmepriv.ChannelPlan = hal_com_config_channel_plan(
+ padapter
+ , hwinfo ? &hwinfo[EEPROM_COUNTRY_CODE_88E] : NULL
+ , hwinfo ? hwinfo[EEPROM_ChannelPlan_88E] : 0xFF
+ , padapter->registrypriv.alpha2
+ , padapter->registrypriv.channel_plan
+ , RTW_CHPLAN_WORLD_NULL
+ , AutoLoadFail
+ );
+}
+
+void
+Hal_EfuseParseCustomerID88E(
+ PADAPTER padapter,
+ u8 *hwinfo,
+ bool AutoLoadFail
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ if (!AutoLoadFail) {
+ pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_88E];
+ /* pHalData->EEPROMSubCustomerID = hwinfo[EEPROM_CustomID_88E]; */
+ } else {
+ pHalData->EEPROMCustomerID = 0;
+ pHalData->EEPROMSubCustomerID = 0;
+ }
+ RTW_INFO("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID);
+ /* RTW_INFO("EEPROM SubCustomer ID: 0x%02x\n", pHalData->EEPROMSubCustomerID); */
+}
+
+
+void
+Hal_ReadAntennaDiversity88E(
+ PADAPTER pAdapter,
+ u8 *PROMContent,
+ bool AutoLoadFail
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ struct registry_priv *registry_par = &pAdapter->registrypriv;
+
+ if (!AutoLoadFail) {
+ /* Antenna Diversity setting. */
+ if (registry_par->antdiv_cfg == 2) { /* 2:By EFUSE */
+ pHalData->AntDivCfg = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x18) >> 3;
+ if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
+ pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION & 0x18) >> 3;
+ } else {
+ pHalData->AntDivCfg = registry_par->antdiv_cfg ; /* 0:OFF , 1:ON, 2:By EFUSE */
+ }
+
+ if (registry_par->antdiv_type == 0) { /* If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead. */
+ pHalData->TRxAntDivType = PROMContent[EEPROM_RF_ANTENNA_OPT_88E];
+ if (pHalData->TRxAntDivType == 0xFF)
+ pHalData->TRxAntDivType = CG_TRX_HW_ANTDIV; /* For 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) */
+ } else
+ pHalData->TRxAntDivType = registry_par->antdiv_type ;
+
+ if (pHalData->TRxAntDivType == CG_TRX_HW_ANTDIV || pHalData->TRxAntDivType == CGCS_RX_HW_ANTDIV)
+ pHalData->AntDivCfg = 1; /* 0xC1[3] is ignored. */
+ } else
+ pHalData->AntDivCfg = 0;
+
+ RTW_INFO("EEPROM : AntDivCfg = %x, TRxAntDivType = %x\n", pHalData->AntDivCfg, pHalData->TRxAntDivType);
+
+
+}
+
+void
+Hal_ReadThermalMeter_88E(
+ PADAPTER Adapter,
+ u8 *PROMContent,
+ bool AutoloadFail
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 tempval;
+
+ /* */
+ /* ThermalMeter from EEPROM */
+ /* */
+ if (!AutoloadFail)
+ pHalData->eeprom_thermal_meter = PROMContent[EEPROM_THERMAL_METER_88E];
+ else
+ pHalData->eeprom_thermal_meter = EEPROM_Default_ThermalMeter_88E;
+ /* pHalData->eeprom_thermal_meter = (tempval&0x1f); */ /* [4:0] */
+
+ if (pHalData->eeprom_thermal_meter == 0xff || AutoloadFail) {
+ pHalData->odmpriv.rf_calibrate_info.is_apk_thermal_meter_ignore = true;
+ pHalData->eeprom_thermal_meter = EEPROM_Default_ThermalMeter_88E;
+ }
+
+ /* pHalData->ThermalMeter[0] = pHalData->eeprom_thermal_meter; */
+ RTW_INFO("ThermalMeter = 0x%x\n", pHalData->eeprom_thermal_meter);
+
+}
+
+#ifdef CONFIG_RF_POWER_TRIM
+void Hal_ReadRFGainOffset(
+ PADAPTER Adapter,
+ u8 *PROMContent,
+ bool AutoloadFail)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 thermal_offset = 0;
+ /* */
+ /* BB_RF Gain Offset from EEPROM */
+ /* */
+
+ if (!AutoloadFail) {
+ pHalData->EEPROMRFGainOffset = PROMContent[EEPROM_RF_GAIN_OFFSET];
+
+ if ((pHalData->EEPROMRFGainOffset != 0xFF) &&
+ (pHalData->EEPROMRFGainOffset & BIT4))
+ efuse_OneByteRead(Adapter, EEPROM_RF_GAIN_VAL, &pHalData->EEPROMRFGainVal, false);
+ else {
+ pHalData->EEPROMRFGainOffset = 0;
+ pHalData->EEPROMRFGainVal = 0;
+ }
+
+ RTW_INFO("pHalData->EEPROMRFGainVal=%x\n", pHalData->EEPROMRFGainVal);
+ } else {
+ efuse_OneByteRead(Adapter, EEPROM_RF_GAIN_VAL, &pHalData->EEPROMRFGainVal, false);
+
+ if (pHalData->EEPROMRFGainVal != 0xFF)
+ pHalData->EEPROMRFGainOffset = BIT4;
+ else
+ pHalData->EEPROMRFGainOffset = 0;
+ RTW_INFO("else AutoloadFail =%x,\n", AutoloadFail);
+ }
+
+ if (Adapter->registrypriv.RegPwrTrimEnable == 1) {
+ efuse_OneByteRead(Adapter, EEPROM_RF_GAIN_VAL, &pHalData->EEPROMRFGainVal, false);
+ RTW_INFO("pHalData->EEPROMRFGainVal=%x\n", pHalData->EEPROMRFGainVal);
+
+ }
+ /* */
+ /* BB_RF Thermal Offset from EEPROM */
+ /* */
+ if (((pHalData->EEPROMRFGainOffset != 0xFF) && (pHalData->EEPROMRFGainOffset & BIT4)) || (Adapter->registrypriv.RegPwrTrimEnable == 1)) {
+
+ efuse_OneByteRead(Adapter, EEPROM_THERMAL_OFFSET, &thermal_offset, false);
+ if (thermal_offset != 0xFF) {
+ if (thermal_offset & BIT0)
+ pHalData->eeprom_thermal_meter += ((thermal_offset >> 1) & 0x0F);
+ else
+ pHalData->eeprom_thermal_meter -= ((thermal_offset >> 1) & 0x0F);
+
+ RTW_INFO("%s =>thermal_offset:0x%02x pHalData->eeprom_thermal_meter=0x%02x\n", __func__ , thermal_offset, pHalData->eeprom_thermal_meter);
+ }
+ }
+
+ RTW_INFO("%s => EEPRORFGainOffset = 0x%02x,EEPROMRFGainVal=0x%02x,thermal_offset:0x%02x\n",
+ __func__, pHalData->EEPROMRFGainOffset, pHalData->EEPROMRFGainVal, thermal_offset);
+
+}
+
+#endif /*CONFIG_RF_POWER_TRIM*/
+
+bool HalDetectPwrDownMode88E(PADAPTER Adapter)
+{
+ u8 tmpvalue = 0;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(Adapter);
+
+ EFUSE_ShadowRead(Adapter, 1, EEPROM_RF_FEATURE_OPTION_88E, (u32 *)&tmpvalue);
+
+ /* 2010/08/25 MH INF priority > PDN Efuse value. */
+ if (tmpvalue & BIT(4) && pwrctrlpriv->reg_pdnmode)
+ pHalData->pwrdown = true;
+ else
+ pHalData->pwrdown = false;
+
+ RTW_INFO("HalDetectPwrDownMode(): PDN=%d\n", pHalData->pwrdown);
+
+ return pHalData->pwrdown;
+} /* HalDetectPwrDownMode */
+
+#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
+void Hal_DetectWoWMode(PADAPTER pAdapter)
+{
+ adapter_to_pwrctl(pAdapter)->bSupportRemoteWakeup = true;
+}
+#endif
+
+/* ************************************************************************************
+ *
+ * 20100209 Joseph:
+ * This function is used only for 92C to set REG_BCN_CTRL(0x550) register.
+ * We just reserve the value of the register in variable pHalData->RegBcnCtrlVal and then operate
+ * the value of the register via atomic operation.
+ * This prevents from race condition when setting this register.
+ * The value of pHalData->RegBcnCtrlVal is initialized in HwConfigureRTL8192CE() function.
+ * */
+void SetBcnCtrlReg(
+ PADAPTER padapter,
+ u8 SetBits,
+ u8 ClearBits)
+{
+ PHAL_DATA_TYPE pHalData;
+
+
+ pHalData = GET_HAL_DATA(padapter);
+
+ pHalData->RegBcnCtrlVal |= SetBits;
+ pHalData->RegBcnCtrlVal &= ~ClearBits;
+
+ rtw_write8(padapter, REG_BCN_CTRL, (u8)pHalData->RegBcnCtrlVal);
+}
+
+void _InitTransferPageSize(PADAPTER padapter)
+{
+ /* Tx page size is always 128. */
+
+ u8 value8;
+ value8 = _PSRX(PBP_128) | _PSTX(PBP_128);
+ rtw_write8(padapter, REG_PBP, value8);
+}
+
+
+static void hw_var_set_monitor(PADAPTER Adapter, u8 variable, u8 *val)
+{
+ u32 value_rcr, rcr_bits;
+ u16 value_rxfltmap2;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
+
+ if (*((u8 *)val) == _HW_STATE_MONITOR_) {
+
+ /* Receive all type */
+ rcr_bits = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_ACF | RCR_AMF | RCR_APP_PHYST_RXFF;
+
+ /* Append FCS */
+ rcr_bits |= RCR_APPFCS;
+
+ /* Receive all data frames */
+ value_rxfltmap2 = 0xFFFF;
+
+ value_rcr = rcr_bits;
+ rtw_write32(Adapter, REG_RCR, value_rcr);
+
+ rtw_write16(Adapter, REG_RXFLTMAP2, value_rxfltmap2);
+ } else {
+ /* do nothing */
+ }
+}
+
+static void hw_var_set_opmode(PADAPTER Adapter, u8 variable, u8 *val)
+{
+ u8 val8;
+ u8 mode = *((u8 *)val);
+ static u8 isMonitor = false;
+
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ if (isMonitor == true) {
+ /* reset RCR */
+ rtw_write32(Adapter, REG_RCR, pHalData->ReceiveConfig);
+ isMonitor = false;
+ }
+
+ RTW_INFO(ADPT_FMT "- Port-%d set opmode = %d\n", ADPT_ARG(Adapter),
+ get_hw_port(Adapter), mode);
+
+ if (mode == _HW_STATE_MONITOR_) {
+ isMonitor = true;
+ /* set net_type */
+ Set_MSR(Adapter, _HW_STATE_NOLINK_);
+
+ hw_var_set_monitor(Adapter, variable, val);
+ return;
+ }
+
+ rtw_hal_set_hwreg(Adapter, HW_VAR_MAC_ADDR, adapter_mac_addr(Adapter)); /* set mac addr to mac register */
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if (Adapter->hw_port == HW_PORT1) {
+ /* disable Port1 TSF update */
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | BIT(4));
+
+ /* set net_type */
+ Set_MSR(Adapter, mode);
+
+ if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
+ if (!rtw_mi_check_status(Adapter, MI_AP_MODE)) {
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+ rtw_write8(Adapter, REG_DRVERLYINT, 0x05);/* restore early int time to 5ms */
+
+ UpdateInterruptMask8188EU(Adapter, true, 0, IMR_BCNDMAINT0_88E);
+
+#endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
+
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+ UpdateInterruptMask8188EU(Adapter, true , 0, (IMR_TBDER_88E | IMR_TBDOK_88E));
+
+#endif/* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
+#endif /* CONFIG_INTERRUPT_BASED_TXBCN */
+
+ StopTxBeacon(Adapter);
+ }
+
+ rtw_write8(Adapter, REG_BCN_CTRL_1, 0x11); /* disable atim wnd and disable beacon function */
+ /* rtw_write8(Adapter,REG_BCN_CTRL_1, 0x18); */
+ } else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/) {
+ /* Beacon is polled to TXBUF */
+ rtw_write32(Adapter, REG_CR, rtw_read32(Adapter, REG_CR) | BIT(8));
+
+ ResumeTxBeacon(Adapter);
+ rtw_write8(Adapter, REG_BCN_CTRL_1, 0x1a);
+ /* BIT4 - If set 0, hw will clr bcnq when tx becon ok/fail or port 1 */
+ rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
+ } else if (mode == _HW_STATE_AP_) {
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+ UpdateInterruptMask8188EU(Adapter, true , IMR_BCNDMAINT0_88E, 0);
+#endif/* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
+
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+ UpdateInterruptMask8188EU(Adapter, true , (IMR_TBDER_88E | IMR_TBDOK_88E), 0);
+#endif/* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
+
+#endif /* CONFIG_INTERRUPT_BASED_TXBCN */
+
+ ResumeTxBeacon(Adapter);
+
+ rtw_write8(Adapter, REG_BCN_CTRL_1, 0x12);
+
+ /* Beacon is polled to TXBUF */
+ rtw_write32(Adapter, REG_CR, rtw_read32(Adapter, REG_CR) | BIT(8));
+
+ /* Set RCR */
+ /* rtw_write32(padapter, REG_RCR, 0x70002a8e); */ /* CBSSID_DATA must set to 0 */
+ if (Adapter->registrypriv.wifi_spec)
+ /* for 11n Logo 4.2.31/4.2.32, disable BSSID BCN check for AP mode */
+ rtw_write32(Adapter, REG_RCR, (0x7000208e & ~(RCR_CBSSID_BCN)));
+ else
+ rtw_write32(Adapter, REG_RCR, 0x7000208e);/* CBSSID_DATA must set to 0,Reject ICV_ERROR packets */
+
+ /* enable to rx data frame */
+ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
+ /* enable to rx ps-poll */
+ rtw_write16(Adapter, REG_RXFLTMAP1, 0x0400);
+
+ /* Beacon Control related register for first time */
+ rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */
+ rtw_write8(Adapter, REG_DRVERLYINT, 0x05);/* 5ms */
+ /* rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF); */
+ rtw_write8(Adapter, REG_ATIMWND_1, 0x0c); /* 13ms for port1 */
+ rtw_write16(Adapter, REG_BCNTCFG, 0x00);
+
+ /* TBTT setup time:128 us */
+ rtw_write8(Adapter, REG_TBTT_PROHIBIT, 0x04);
+
+ /*TBTT hold time :4ms 0x540[19:8]*/
+ rtw_write8(Adapter, REG_TBTT_PROHIBIT + 1,
+ TBTT_PROBIHIT_HOLD_TIME & 0xFF);
+ rtw_write8(Adapter, REG_TBTT_PROHIBIT + 2,
+ (rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROBIHIT_HOLD_TIME >> 8));
+
+ rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
+
+ /* reset TSF2 */
+ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1));
+
+
+ /* BIT4 - If set 0, hw will clr bcnq when tx becon ok/fail or port 1 */
+ rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
+ /* enable BCN1 Function for if2 */
+ /* don't enable update TSF1 for if2 (due to TSF update when beacon/probe rsp are received) */
+ rtw_write8(Adapter, REG_BCN_CTRL_1, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | EN_TXBCN_RPT | BIT(1)));
+
+ if (!rtw_mi_buddy_check_fwstate(Adapter, WIFI_FW_ASSOC_SUCCESS))
+ rtw_write8(Adapter, REG_BCN_CTRL,
+ rtw_read8(Adapter, REG_BCN_CTRL) & ~EN_BCN_FUNCTION);
+
+ /* BCN1 TSF will sync to BCN0 TSF with offset(0x518) if if1_sta linked */
+ /* rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(5)); */
+ /* rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(3)); */
+
+ /* dis BCN0 ATIM WND if if1 is station */
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(0));
+
+#ifdef CONFIG_TSF_RESET_OFFLOAD
+ /* Reset TSF for STA+AP concurrent mode */
+ if (rtw_mi_buddy_check_fwstate(Adapter, (WIFI_STATION_STATE | WIFI_ASOC_STATE))) {
+ if (reset_tsf(Adapter, HW_PORT1) == false)
+ RTW_INFO("ERROR! %s()-%d: Reset port1 TSF fail\n",
+ __func__, __LINE__);
+ }
+#endif /* CONFIG_TSF_RESET_OFFLOAD */
+ }
+ } else /* (Adapter->hw_port == HW_PORT1)*/
+#endif /* CONFIG_CONCURRENT_MODE */
+ {
+#ifdef CONFIG_MI_WITH_MBSSID_CAM /*For Port0 - MBSS CAM*/
+ hw_var_set_opmode_mbid(Adapter, mode);
+#else
+ /* disable Port0 TSF update */
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+
+ /* set net_type */
+ Set_MSR(Adapter, mode);
+
+ if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
+#ifdef CONFIG_CONCURRENT_MODE
+ if (!rtw_mi_check_status(Adapter, MI_AP_MODE))
+#endif /*CONFIG_CONCURRENT_MODE*/
+ {
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+ rtw_write8(Adapter, REG_DRVERLYINT, 0x05);/* restore early int time to 5ms */
+ UpdateInterruptMask8188EU(Adapter, true, 0, IMR_BCNDMAINT0_88E);
+#endif/* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
+
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+ UpdateInterruptMask8188EU(Adapter, true , 0, (IMR_TBDER_88E | IMR_TBDOK_88E));
+#endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
+
+#endif /* CONFIG_INTERRUPT_BASED_TXBCN */
+ StopTxBeacon(Adapter);
+ }
+
+ rtw_write8(Adapter, REG_BCN_CTRL, 0x19); /* disable atim wnd */
+ /* rtw_write8(Adapter,REG_BCN_CTRL, 0x18); */
+ } else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/) {
+ /* Beacon is polled to TXBUF */
+ rtw_write16(Adapter, REG_CR, rtw_read16(Adapter, REG_CR) | BIT(8));
+
+ ResumeTxBeacon(Adapter);
+ rtw_write8(Adapter, REG_BCN_CTRL, 0x1a);
+ /* BIT3 - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
+ rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
+ } else if (mode == _HW_STATE_AP_) {
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+ UpdateInterruptMask8188EU(Adapter, true , IMR_BCNDMAINT0_88E, 0);
+#endif/* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
+
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+ UpdateInterruptMask8188EU(Adapter, true , (IMR_TBDER_88E | IMR_TBDOK_88E), 0);
+#endif/* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
+
+#endif /* CONFIG_INTERRUPT_BASED_TXBCN */
+
+ ResumeTxBeacon(Adapter);
+
+ rtw_write8(Adapter, REG_BCN_CTRL, 0x12);
+
+ /* Beacon is polled to TXBUF */
+ rtw_write32(Adapter, REG_CR, rtw_read32(Adapter, REG_CR) | BIT(8));
+
+ /* Set RCR */
+ /* rtw_write32(padapter, REG_RCR, 0x70002a8e); */ /* CBSSID_DATA must set to 0 */
+ if (Adapter->registrypriv.wifi_spec)
+ /* for 11n Logo 4.2.31/4.2.32, disable BSSID BCN check for AP mode */
+ rtw_write32(Adapter, REG_RCR, (0x7000208e & ~(RCR_CBSSID_BCN)));
+ else
+ rtw_write32(Adapter, REG_RCR, 0x7000208e);/* CBSSID_DATA must set to 0,reject ICV_ERR packet */
+ /* enable to rx data frame */
+ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
+ /* enable to rx ps-poll */
+ rtw_write16(Adapter, REG_RXFLTMAP1, 0x0400);
+
+ /* Beacon Control related register for first time */
+ rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */
+ rtw_write8(Adapter, REG_DRVERLYINT, 0x05);/* 5ms */
+ /* rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF); */
+ rtw_write8(Adapter, REG_ATIMWND, 0x0c); /* 13ms */
+ rtw_write16(Adapter, REG_BCNTCFG, 0x00);
+
+ /* TBTT setup time:128 us */
+ rtw_write8(Adapter, REG_TBTT_PROHIBIT, 0x04);
+
+ /*TBTT hold time :4ms 0x540[19:8]*/
+ rtw_write8(Adapter, REG_TBTT_PROHIBIT + 1,
+ TBTT_PROBIHIT_HOLD_TIME & 0xFF);
+ rtw_write8(Adapter, REG_TBTT_PROHIBIT + 2,
+ (rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROBIHIT_HOLD_TIME >> 8));
+
+ rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
+
+ /* reset TSF */
+ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
+
+ /* BIT3 - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
+ rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
+
+ /* enable BCN0 Function for if1 */
+ /* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
+#if defined(CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR)
+ rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | EN_TXBCN_RPT | BIT(1)));
+#else
+ rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | BIT(1)));
+#endif
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if (!rtw_mi_buddy_check_fwstate(Adapter, WIFI_FW_ASSOC_SUCCESS))
+ rtw_write8(Adapter, REG_BCN_CTRL_1,
+ rtw_read8(Adapter, REG_BCN_CTRL_1) & ~EN_BCN_FUNCTION);
+#endif
+
+ /* dis BCN1 ATIM WND if if2 is station */
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | BIT(0));
+#ifdef CONFIG_TSF_RESET_OFFLOAD
+ /* Reset TSF for STA+AP concurrent mode */
+ if (rtw_mi_buddy_check_fwstate(Adapter, (WIFI_STATION_STATE | WIFI_ASOC_STATE))) {
+ if (reset_tsf(Adapter, HW_PORT0) == false)
+ RTW_INFO("ERROR! %s()-%d: Reset port0 TSF fail\n",
+ __func__, __LINE__);
+ }
+#endif /* CONFIG_TSF_RESET_OFFLOAD */
+ }
+#endif
+ }
+}
+
+static void hw_var_set_bcn_func(PADAPTER Adapter, u8 variable, u8 *val)
+{
+ u32 bcn_ctrl_reg;
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if (Adapter->hw_port == HW_PORT1)
+ bcn_ctrl_reg = REG_BCN_CTRL_1;
+ else
+#endif
+ bcn_ctrl_reg = REG_BCN_CTRL;
+
+
+ if (*((u8 *)val))
+ rtw_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
+ else
+ rtw_write8(Adapter, bcn_ctrl_reg, rtw_read8(Adapter, bcn_ctrl_reg) & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+
+
+}
+
+static void hw_var_set_correct_tsf(PADAPTER Adapter, u8 variable, u8 *val)
+{
+#ifdef CONFIG_MI_WITH_MBSSID_CAM
+ /*do nothing*/
+#else
+ u64 tsf;
+ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
+ /* pHalData->RegTxPause |= STOP_BCNQ;BIT(6) */
+ /* rtw_write8(Adapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)|BIT(6))); */
+ StopTxBeacon(Adapter);
+ }
+
+ /*tsf = pmlmeext->TSFValue - ((u32)pmlmeext->TSFValue % (pmlmeinfo->bcn_interval*1024)) -1024; //us */
+ tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
+
+ rtw_hal_correct_tsf(Adapter, Adapter->hw_port, tsf);
+
+#ifdef CONFIG_CONCURRENT_MODE
+ /* Update buddy port's TSF if it is SoftAP for beacon TX issue!*/
+ if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
+ && rtw_mi_check_status(Adapter, MI_AP_MODE)) {
+
+ struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter);
+ int i;
+ _adapter *iface;
+
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if (!iface)
+ continue;
+ if (iface == Adapter)
+ continue;
+
+ if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == true
+ && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == true
+ ) {
+ rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
+#ifdef CONFIG_TSF_RESET_OFFLOAD
+ if (reset_tsf(iface, iface->hw_port) == false)
+ RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n", __func__, ADPT_ARG(iface), iface->hw_port);
+#endif /* CONFIG_TSF_RESET_OFFLOAD*/
+ }
+ }
+ }
+#endif/*CONFIG_CONCURRENT_MODE*/
+ if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
+ /* pHalData->RegTxPause &= (~STOP_BCNQ); */
+ /* rtw_write8(Adapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)&(~BIT(6)))); */
+ ResumeTxBeacon(Adapter);
+ }
+#endif /*CONFIG_MI_WITH_MBSSID_CAM*/
+}
+
+static void hw_var_set_mlme_disconnect(PADAPTER Adapter, u8 variable, u8 *val)
+{
+ /*Set RCR to not to receive data frame when NO LINK state
+ rtw_write32(Adapter, REG_RCR, rtw_read32(padapter, REG_RCR) & ~RCR_ADF);
+ reject all data frames */
+#ifdef CONFIG_CONCURRENT_MODE
+ if (rtw_mi_check_status(Adapter, MI_LINKED) == false)
+#endif
+ rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if (Adapter->hw_port == HW_PORT1) {
+ /*reset TSF1*/
+ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1));
+
+ /*disable update TSF1*/
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | DIS_TSF_UDT);
+
+ /* disable Port1's beacon function*/
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) & (~BIT(3)));
+ } else
+#endif
+ {
+ /*reset TSF*/
+ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
+
+ /*disable update TSF*/
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | DIS_TSF_UDT);
+ }
+
+}
+
+
+static void hw_var_set_mlme_sitesurvey(PADAPTER Adapter, u8 variable, u8 *val)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter);
+ u32 value_rcr, rcr_clear_bit;
+ u16 value_rxfltmap2;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ int i;
+ _adapter *iface;
+
+#ifdef DBG_IFACE_STATUS
+ DBG_IFACE_STATUS_DUMP(Adapter);
+#endif
+
+
+#ifdef CONFIG_FIND_BEST_CHANNEL
+
+ rcr_clear_bit = (RCR_CBSSID_BCN | RCR_CBSSID_DATA);
+
+ /* Receive all data frames */
+ value_rxfltmap2 = 0xFFFF;
+
+#else /* CONFIG_FIND_BEST_CHANNEL */
+
+ rcr_clear_bit = RCR_CBSSID_BCN;
+
+ /* config RCR to receive different BSSID & not to receive data frame */
+ value_rxfltmap2 = 0;
+
+#endif /* CONFIG_FIND_BEST_CHANNEL */
+
+ if (rtw_mi_check_fwstate(Adapter, WIFI_AP_STATE))
+ rcr_clear_bit = RCR_CBSSID_BCN;
+
+#ifdef CONFIG_TDLS
+ /* TDLS will clear RCR_CBSSID_DATA bit for connection.*/
+ else if (Adapter->tdlsinfo.link_established == true)
+ rcr_clear_bit = RCR_CBSSID_BCN;
+#endif /*CONFIG_TDLS*/
+
+ value_rcr = rtw_read32(Adapter, REG_RCR);
+
+ if (*((u8 *)val)) {/*under sitesurvey*/
+ /*
+ * 1. configure REG_RXFLTMAP2
+ * 2. disable TSF update & buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
+ * 3. config RCR to receive different BSSID BCN or probe rsp
+ */
+
+ rtw_write16(Adapter, REG_RXFLTMAP2, value_rxfltmap2);
+
+#ifdef CONFIG_MI_WITH_MBSSID_CAM
+ /*do nothing~~*/
+#else
+
+ /* disable update TSF */
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if (!iface)
+ continue;
+
+ if (rtw_linked_check(iface) &&
+ check_fwstate(&(iface->mlmepriv), WIFI_AP_STATE) != true) {
+ if (iface->hw_port == HW_PORT1)
+ rtw_write8(iface, REG_BCN_CTRL_1, rtw_read8(iface, REG_BCN_CTRL_1) | DIS_TSF_UDT);
+ else
+ rtw_write8(iface, REG_BCN_CTRL, rtw_read8(iface, REG_BCN_CTRL) | DIS_TSF_UDT);
+
+ iface->mlmeextpriv.en_hw_update_tsf = false;
+ }
+
+ }
+#endif/*CONFIG_MI_WITH_MBSSID_CAM*/
+
+ value_rcr &= ~(rcr_clear_bit);
+ rtw_write32(Adapter, REG_RCR, value_rcr);
+
+ /* Save orignal RRSR setting.*/
+ pHalData->RegRRSR = rtw_read16(Adapter, REG_RRSR);
+
+ if (rtw_mi_check_status(Adapter, MI_AP_MODE))
+ StopTxBeacon(Adapter);
+ } else {/*sitesurvey done*/
+ /*
+ * 1. enable rx data frame
+ * 2. config RCR not to receive different BSSID BCN or probe rsp
+ * 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict
+ * so, we enable TSF update when rx first BCN after sitesurvey done
+ */
+
+ if (rtw_mi_check_fwstate(Adapter, _FW_LINKED | WIFI_AP_STATE))
+ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);/*enable to rx data frame*/
+
+#ifdef CONFIG_MI_WITH_MBSSID_CAM
+ value_rcr &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
+#else
+ value_rcr |= rcr_clear_bit;
+#endif
+ /* for 11n Logo 4.2.31/4.2.32, disable BSSID BCN check for AP mode */
+ if (Adapter->registrypriv.wifi_spec && MLME_IS_AP(Adapter))
+ value_rcr &= ~(RCR_CBSSID_BCN);
+
+ rtw_write32(Adapter, REG_RCR, value_rcr);
+
+#ifdef CONFIG_MI_WITH_MBSSID_CAM
+ /*if ((rtw_mi_get_assoced_sta_num(Adapter) == 1) && (!rtw_mi_check_status(Adapter, MI_AP_MODE)))
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~DIS_TSF_UDT));*/
+#else
+
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if (!iface)
+ continue;
+ if (rtw_linked_check(iface) &&
+ check_fwstate(&(iface->mlmepriv), WIFI_AP_STATE) != true) {
+ /* enable HW TSF update when recive beacon*/
+ /*if (iface->hw_port == HW_PORT1)
+ rtw_write8(iface, REG_BCN_CTRL_1, rtw_read8(iface, REG_BCN_CTRL_1)&(~(DIS_TSF_UDT)));
+ else
+ rtw_write8(iface, REG_BCN_CTRL, rtw_read8(iface, REG_BCN_CTRL)&(~(DIS_TSF_UDT)));
+ */
+ iface->mlmeextpriv.en_hw_update_tsf = true;
+ }
+ }
+#endif
+
+ /* Restore orignal RRSR setting. */
+ rtw_write16(Adapter, REG_RRSR, pHalData->RegRRSR);
+
+ if (rtw_mi_get_ap_num(Adapter)) {
+ ResumeTxBeacon(Adapter);
+ rtw_mi_tx_beacon_hdl(Adapter);
+ }
+ }
+}
+
+static void hw_var_set_mlme_join(PADAPTER Adapter, u8 variable, u8 *val)
+{
+#ifdef CONFIG_CONCURRENT_MODE
+ u8 RetryLimit = 0x30;
+ u8 type = *((u8 *)val);
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+
+ if (type == 0) { /* prepare to join */
+ if (rtw_mi_check_status(Adapter, MI_AP_MODE))
+ StopTxBeacon(Adapter);
+
+ /*enable to rx data frame.Accept all data frame*/
+ /*rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF);*/
+ rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
+#ifdef CONFIG_MI_WITH_MBSSID_CAM
+ /*
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && (rtw_mi_get_assoced_sta_num(Adapter) == 1))
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN);
+ else if ((rtw_mi_get_ap_num(Adapter) == 1) && (rtw_mi_get_assoced_sta_num(Adapter) == 1))
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN);
+ else*/
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) & (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)));
+#else
+ if (rtw_mi_check_status(Adapter, MI_AP_MODE))
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
+ else
+ rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+#endif
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
+ RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
+ else /* Ad-hoc Mode */
+ RetryLimit = 0x7;
+ } else if (type == 1) { /* joinbss_event call back when join res < 0 */
+ if (rtw_mi_check_status(Adapter, MI_LINKED) == false)
+ rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
+
+ if (rtw_mi_check_status(Adapter, MI_AP_MODE)) {
+ ResumeTxBeacon(Adapter);
+
+ /* reset TSF 1/2 after ResumeTxBeacon */
+ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
+
+ }
+ } else if (type == 2) { /* sta add event call back */
+#ifdef CONFIG_MI_WITH_MBSSID_CAM
+ /*if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && (rtw_mi_get_assoced_sta_num(Adapter) == 1))
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~DIS_TSF_UDT));*/
+#else
+ /* enable update TSF */
+ if (Adapter->hw_port == HW_PORT1)
+ rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) & (~DIS_TSF_UDT));
+ else
+ rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~DIS_TSF_UDT));
+
+#endif
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
+ /* fixed beacon issue for 8191su........... */
+ rtw_write8(Adapter, 0x542 , 0x02);
+ RetryLimit = 0x7;
+ }
+
+
+ if (rtw_mi_check_status(Adapter, MI_AP_MODE)) {
+ ResumeTxBeacon(Adapter);
+
+ /* reset TSF 1/2 after ResumeTxBeacon */
+ rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
+ }
+
+ }
+
+ rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
+
+#endif
+}
+
+
+
+void SetHwReg8188E(_adapter *adapter, u8 variable, u8 *val)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
+ struct PHY_DM_STRUCT *podmpriv = &pHalData->odmpriv;
+
+ switch (variable) {
+
+ case HW_VAR_SET_OPMODE:
+ hw_var_set_opmode(adapter, variable, val);
+ break;
+ case HW_VAR_BASIC_RATE: {
+ struct mlme_ext_info *mlmext_info = &adapter->mlmeextpriv.mlmext_info;
+ u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
+ u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
+ u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
+
+ HalSetBrateCfg(adapter, val, &BrateCfg);
+ input_b = BrateCfg;
+
+ /* apply force and allow mask */
+ BrateCfg |= rrsr_2g_force_mask;
+ BrateCfg &= rrsr_2g_allow_mask;
+ masked = BrateCfg;
+
+ /* IOT consideration */
+ if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
+ /* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
+ if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
+ BrateCfg |= RRSR_6M;
+ }
+ ioted = BrateCfg;
+
+ pHalData->BasicRateSet = BrateCfg;
+
+ RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
+
+ /* Set RRSR rate table. */
+ rtw_write16(adapter, REG_RRSR, BrateCfg);
+ rtw_write8(adapter, REG_RRSR + 2, rtw_read8(adapter, REG_RRSR + 2) & 0xf0);
+
+ rtw_hal_set_hwreg(adapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);
+ }
+ break;
+ case HW_VAR_TXPAUSE:
+ rtw_write8(adapter, REG_TXPAUSE, *((u8 *)val));
+ break;
+ case HW_VAR_BCN_FUNC:
+ hw_var_set_bcn_func(adapter, variable, val);
+ break;
+
+ case HW_VAR_CORRECT_TSF:
+ hw_var_set_correct_tsf(adapter, variable, val);
+ break;
+
+ case HW_VAR_CHECK_BSSID:
+ if (*((u8 *)val))
+ rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+ else {
+ u32 val32;
+
+ val32 = rtw_read32(adapter, REG_RCR);
+
+ val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+
+ rtw_write32(adapter, REG_RCR, val32);
+ }
+ break;
+
+ case HW_VAR_MLME_DISCONNECT:
+ hw_var_set_mlme_disconnect(adapter, variable, val);
+ break;
+
+ case HW_VAR_MLME_SITESURVEY:
+ hw_var_set_mlme_sitesurvey(adapter, variable, val);
+ break;
+
+ case HW_VAR_MLME_JOIN:
+#ifdef CONFIG_CONCURRENT_MODE
+ hw_var_set_mlme_join(adapter, variable, val);
+#else
+ {
+ u8 RetryLimit = 0x30;
+ u8 type = *((u8 *)val);
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+
+ if (type == 0) { /* prepare to join */
+ /* enable to rx data frame.Accept all data frame */
+ /* rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF); */
+ rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
+
+ if (adapter->in_cta_test) {
+ u32 v = rtw_read32(adapter, REG_RCR);
+ v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); /* | RCR_ADF */
+ rtw_write32(adapter, REG_RCR, v);
+ } else
+ rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
+ RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
+ else /* Ad-hoc Mode */
+ RetryLimit = 0x7;
+ } else if (type == 1) /* joinbss_event call back when join res < 0 */
+ rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
+ else if (type == 2) { /* sta add event call back */
+ /* enable update TSF */
+ rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & (~BIT(4)));
+
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
+ RetryLimit = 0x7;
+ }
+
+ rtw_write16(adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
+ }
+#endif
+ break;
+
+ case HW_VAR_ON_RCR_AM:
+ rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR) | RCR_AM);
+ RTW_INFO("%s, %d, RCR= %x\n", __func__, __LINE__, rtw_read32(adapter, REG_RCR));
+ break;
+ case HW_VAR_OFF_RCR_AM:
+ rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR) & (~RCR_AM));
+ RTW_INFO("%s, %d, RCR= %x\n", __func__, __LINE__, rtw_read32(adapter, REG_RCR));
+ break;
+ case HW_VAR_BEACON_INTERVAL:
+ rtw_write16(adapter, REG_BCN_INTERVAL, *((u16 *)val));
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+ {
+ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ u16 bcn_interval = *((u16 *)val);
+ if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
+ RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, bcn_interval, bcn_interval >> 1);
+ rtw_write8(adapter, REG_DRVERLYINT, bcn_interval >> 1); /* 50ms for sdio */
+ }
+ }
+#endif/* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
+
+ break;
+ case HW_VAR_SLOT_TIME: {
+ rtw_write8(adapter, REG_SLOT, val[0]);
+ }
+ break;
+ case HW_VAR_ACK_PREAMBLE: {
+ u8 regTmp;
+ u8 bShortPreamble = *((bool *)val);
+ /* Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */
+ regTmp = (pHalData->nCur40MhzPrimeSC) << 5;
+ rtw_write8(adapter, REG_RRSR + 2, regTmp);
+
+ regTmp = rtw_read8(adapter, REG_WMAC_TRXPTCL_CTL + 2);
+ if (bShortPreamble)
+ regTmp |= BIT1;
+ else
+ regTmp &= (~BIT1);
+ rtw_write8(adapter, REG_WMAC_TRXPTCL_CTL + 2, regTmp);
+ }
+ break;
+ case HW_VAR_CAM_EMPTY_ENTRY: {
+ u8 ucIndex = *((u8 *)val);
+ u8 i;
+ u32 ulCommand = 0;
+ u32 ulContent = 0;
+ u32 ulEncAlgo = CAM_AES;
+
+ for (i = 0; i < CAM_CONTENT_COUNT; i++) {
+ /* filled id in CAM config 2 byte */
+ if (i == 0) {
+ ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
+ /* ulContent |= CAM_VALID; */
+ } else
+ ulContent = 0;
+ /* polling bit, and No Write enable, and address */
+ ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
+ ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
+ /* write content 0 is equall to mark invalid */
+ rtw_write32(adapter, WCAMI, ulContent); /* delay_ms(40); */
+ rtw_write32(adapter, RWCAM, ulCommand); /* delay_ms(40); */
+ }
+ }
+ break;
+ case HW_VAR_CAM_INVALID_ALL:
+ rtw_write32(adapter, RWCAM, BIT(31) | BIT(30));
+ break;
+ case HW_VAR_AC_PARAM_VO:
+ rtw_write32(adapter, REG_EDCA_VO_PARAM, ((u32 *)(val))[0]);
+ break;
+ case HW_VAR_AC_PARAM_VI:
+ rtw_write32(adapter, REG_EDCA_VI_PARAM, ((u32 *)(val))[0]);
+ break;
+ case HW_VAR_AC_PARAM_BE:
+ pHalData->ac_param_be = ((u32 *)(val))[0];
+ rtw_write32(adapter, REG_EDCA_BE_PARAM, ((u32 *)(val))[0]);
+ break;
+ case HW_VAR_AC_PARAM_BK:
+ rtw_write32(adapter, REG_EDCA_BK_PARAM, ((u32 *)(val))[0]);
+ break;
+ case HW_VAR_ACM_CTRL: {
+ u8 acm_ctrl = *((u8 *)val);
+ u8 AcmCtrl = rtw_read8(adapter, REG_ACMHWCTRL);
+
+ if (acm_ctrl > 1)
+ AcmCtrl = AcmCtrl | 0x1;
+
+ if (acm_ctrl & BIT(3))
+ AcmCtrl |= AcmHw_VoqEn;
+ else
+ AcmCtrl &= (~AcmHw_VoqEn);
+
+ if (acm_ctrl & BIT(2))
+ AcmCtrl |= AcmHw_ViqEn;
+ else
+ AcmCtrl &= (~AcmHw_ViqEn);
+
+ if (acm_ctrl & BIT(1))
+ AcmCtrl |= AcmHw_BeqEn;
+ else
+ AcmCtrl &= (~AcmHw_BeqEn);
+
+ RTW_INFO("[HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
+ rtw_write8(adapter, REG_ACMHWCTRL, AcmCtrl);
+ }
+ break;
+ case HW_VAR_AMPDU_FACTOR: {
+ u8 RegToSet_Normal[4] = {0x41, 0xa8, 0x72, 0xb9};
+ u8 RegToSet_BT[4] = {0x31, 0x74, 0x42, 0x97};
+ u8 FactorToSet;
+ u8 *pRegToSet;
+ u8 index = 0;
+
+#ifdef CONFIG_BT_COEXIST
+ if ((pHalData->bt_coexist.BT_Coexist) &&
+ (pHalData->bt_coexist.BT_CoexistType == BT_CSR_BC4))
+ pRegToSet = RegToSet_BT; /* 0x97427431; */
+ else
+#endif
+ pRegToSet = RegToSet_Normal; /* 0xb972a841; */
+
+ FactorToSet = *((u8 *)val);
+ if (FactorToSet <= 3) {
+ FactorToSet = (1 << (FactorToSet + 2));
+ if (FactorToSet > 0xf)
+ FactorToSet = 0xf;
+
+ for (index = 0; index < 4; index++) {
+ if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4))
+ pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet << 4);
+
+ if ((pRegToSet[index] & 0x0f) > FactorToSet)
+ pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet);
+
+ rtw_write8(adapter, (REG_AGGLEN_LMT + index), pRegToSet[index]);
+ }
+
+ }
+ }
+ break;
+ case HW_VAR_H2C_FW_PWRMODE: {
+ u8 psmode = (*(u8 *)val);
+
+ /* Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power */
+ /* saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang. */
+ if (psmode != PS_MODE_ACTIVE)
+ odm_rf_saving(podmpriv, true);
+ rtl8188e_set_FwPwrMode_cmd(adapter, psmode);
+ }
+ break;
+ case HW_VAR_H2C_FW_JOINBSSRPT: {
+ u8 mstatus = (*(u8 *)val);
+ rtl8188e_set_FwJoinBssReport_cmd(adapter, mstatus);
+ }
+ break;
+#ifdef CONFIG_P2P_PS
+ case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: {
+ u8 p2p_ps_state = (*(u8 *)val);
+ rtl8188e_set_p2p_ps_offload_cmd(adapter, p2p_ps_state);
+ }
+ break;
+#endif /* CONFIG_P2P_PS */
+#ifdef CONFIG_TDLS
+ case HW_VAR_TDLS_WRCR:
+ rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR) & (~RCR_CBSSID_DATA));
+ break;
+ case HW_VAR_TDLS_RS_RCR:
+ rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR) | (RCR_CBSSID_DATA));
+ break;
+#endif /* CONFIG_TDLS */
+#ifdef CONFIG_BT_COEXIST
+ case HW_VAR_BT_SET_COEXIST: {
+ u8 bStart = (*(u8 *)val);
+ rtl8192c_set_dm_bt_coexist(adapter, bStart);
+ }
+ break;
+ case HW_VAR_BT_ISSUE_DELBA: {
+ u8 dir = (*(u8 *)val);
+ rtl8192c_issue_delete_ba(adapter, dir);
+ }
+ break;
+#endif
+#if (RATE_ADAPTIVE_SUPPORT == 1)
+ case HW_VAR_RPT_TIMER_SETTING: {
+ u16 min_rpt_time = (*(u16 *)val);
+
+ odm_ra_set_tx_rpt_time(podmpriv, min_rpt_time);
+ }
+ break;
+#endif
+
+ case HW_VAR_EFUSE_BYTES: /* To set EFUE total used bytes, added by Roger, 2008.12.22. */
+ pHalData->EfuseUsedBytes = *((u16 *)val);
+ break;
+ case HW_VAR_FIFO_CLEARN_UP: {
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
+ u8 trycnt = 100;
+
+ /* pause tx */
+ rtw_write8(adapter, REG_TXPAUSE, 0xff);
+
+ /* keep sn */
+ adapter->xmitpriv.nqos_ssn = rtw_read16(adapter, REG_NQOS_SEQ);
+
+ if (pwrpriv->bkeepfwalive != true) {
+ /* RX DMA stop */
+ rtw_write32(adapter, REG_RXPKT_NUM, (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
+ do {
+ if (!(rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE))
+ break;
+ } while (trycnt--);
+ if (trycnt == 0)
+ RTW_INFO("Stop RX DMA failed......\n");
+
+ /* RQPN Load 0 */
+ rtw_write16(adapter, REG_RQPN_NPQ, 0x0);
+ rtw_write32(adapter, REG_RQPN, 0x80000000);
+ rtw_mdelay_os(10);
+ }
+ }
+ break;
+
+ case HW_VAR_RESTORE_HW_SEQ:
+ /* restore Sequence No. */
+ rtw_write8(adapter, 0x4dc, adapter->xmitpriv.nqos_ssn);
+ break;
+
+#if (RATE_ADAPTIVE_SUPPORT == 1)
+ case HW_VAR_TX_RPT_MAX_MACID: {
+ u8 maxMacid = *val;
+
+ RTW_INFO("### MacID(%d),Set Max Tx RPT MID(%d)\n", maxMacid, maxMacid + 1);
+ rtw_write8(adapter, REG_TX_RPT_CTRL + 1, maxMacid + 1);
+ }
+ break;
+#endif /* (RATE_ADAPTIVE_SUPPORT == 1) */
+
+ case HW_VAR_BCN_VALID:
+ /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw */
+ rtw_write8(adapter, REG_TDECTRL + 2, rtw_read8(adapter, REG_TDECTRL + 2) | BIT0);
+ break;
+
+
+ case HW_VAR_CHECK_TXBUF: {
+ u8 retry_limit;
+ u16 val16;
+ u32 reg_200 = 0, reg_204 = 0;
+ u32 init_reg_200 = 0, init_reg_204 = 0;
+ u32 start = jiffies;
+ u32 pass_ms;
+ int i = 0;
+
+ retry_limit = 0x01;
+
+ val16 = retry_limit << RETRY_LIMIT_SHORT_SHIFT | retry_limit << RETRY_LIMIT_LONG_SHIFT;
+ rtw_write16(adapter, REG_RL, val16);
+
+ while (rtw_get_passing_time_ms(start) < 2000
+ && !RTW_CANNOT_RUN(adapter)
+ ) {
+ reg_200 = rtw_read32(adapter, 0x200);
+ reg_204 = rtw_read32(adapter, 0x204);
+
+ if (i == 0) {
+ init_reg_200 = reg_200;
+ init_reg_204 = reg_204;
+ }
+
+ i++;
+ if ((reg_200 & 0x00ffffff) != (reg_204 & 0x00ffffff)) {
+ /* RTW_INFO("%s: (HW_VAR_CHECK_TXBUF)TXBUF NOT empty - 0x204=0x%x, 0x200=0x%x (%d)\n", __func__, reg_204, reg_200, i); */
+ rtw_msleep_os(10);
+ } else
+ break;
+ }
+
+ pass_ms = rtw_get_passing_time_ms(start);
+
+ if (RTW_CANNOT_RUN(adapter))
+ ;
+ else if (pass_ms >= 2000 || (reg_200 & 0x00ffffff) != (reg_204 & 0x00ffffff)) {
+ RTW_PRINT("%s:(HW_VAR_CHECK_TXBUF)NOT empty(%d) in %d ms\n", __func__, i, pass_ms);
+ RTW_PRINT("%s:(HW_VAR_CHECK_TXBUF)0x200=0x%08x, 0x204=0x%08x (0x%08x, 0x%08x)\n",
+ __func__, reg_200, reg_204, init_reg_200, init_reg_204);
+ /* rtw_warn_on(1); */
+ } else
+ RTW_INFO("%s:(HW_VAR_CHECK_TXBUF)TXBUF Empty(%d) in %d ms\n", __func__, i, pass_ms);
+
+ retry_limit = 0x30;
+ val16 = retry_limit << RETRY_LIMIT_SHORT_SHIFT | retry_limit << RETRY_LIMIT_LONG_SHIFT;
+ rtw_write16(adapter, REG_RL, val16);
+ }
+ break;
+ case HW_VAR_RESP_SIFS: {
+ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
+
+ if ((pmlmeext->cur_wireless_mode == WIRELESS_11G) ||
+ (pmlmeext->cur_wireless_mode == WIRELESS_11BG)) { /* WIRELESS_MODE_G){ */
+ val[0] = 0x0a;
+ val[1] = 0x0a;
+ } else {
+ val[0] = 0x0e;
+ val[1] = 0x0e;
+ }
+
+ /* SIFS for OFDM Data ACK */
+ rtw_write8(adapter, REG_SIFS_CTX + 1, val[0]);
+ /* SIFS for OFDM consecutive tx like CTS data! */
+ rtw_write8(adapter, REG_SIFS_TRX + 1, val[1]);
+
+ rtw_write8(adapter, REG_SPEC_SIFS + 1, val[0]);
+ rtw_write8(adapter, REG_MAC_SPEC_SIFS + 1, val[0]);
+
+ /* RESP_SIFS for OFDM */
+ rtw_write8(adapter, REG_RESP_SIFS_OFDM, val[0]);
+ rtw_write8(adapter, REG_RESP_SIFS_OFDM + 1, val[0]);
+ }
+ break;
+
+ case HW_VAR_MACID_LINK: {
+ u32 reg_macid_no_link;
+ u8 bit_shift;
+ u8 id = *(u8 *)val;
+ u32 val32;
+
+ if (id < 32) {
+ reg_macid_no_link = REG_MACID_NO_LINK_0;
+ bit_shift = id;
+ } else if (id < 64) {
+ reg_macid_no_link = REG_MACID_NO_LINK_1;
+ bit_shift = id - 32;
+ } else {
+ rtw_warn_on(1);
+ break;
+ }
+
+ val32 = rtw_read32(adapter, reg_macid_no_link);
+ if (!(val32 & BIT(bit_shift)))
+ break;
+
+ val32 &= ~BIT(bit_shift);
+ rtw_write32(adapter, reg_macid_no_link, val32);
+ }
+ break;
+
+ case HW_VAR_MACID_NOLINK: {
+ u32 reg_macid_no_link;
+ u8 bit_shift;
+ u8 id = *(u8 *)val;
+ u32 val32;
+
+ if (id < 32) {
+ reg_macid_no_link = REG_MACID_NO_LINK_0;
+ bit_shift = id;
+ } else if (id < 64) {
+ reg_macid_no_link = REG_MACID_NO_LINK_1;
+ bit_shift = id - 32;
+ } else {
+ rtw_warn_on(1);
+ break;
+ }
+
+ val32 = rtw_read32(adapter, reg_macid_no_link);
+ if (val32 & BIT(bit_shift))
+ break;
+
+ val32 |= BIT(bit_shift);
+ rtw_write32(adapter, reg_macid_no_link, val32);
+ }
+ break;
+
+ case HW_VAR_MACID_SLEEP: {
+ u32 reg_macid_sleep;
+ u8 bit_shift;
+ u8 id = *(u8 *)val;
+ u32 val32;
+
+ if (id < 32) {
+ reg_macid_sleep = REG_MACID_PAUSE_0;
+ bit_shift = id;
+ } else if (id < 64) {
+ reg_macid_sleep = REG_MACID_PAUSE_1;
+ bit_shift = id - 32;
+ } else {
+ rtw_warn_on(1);
+ break;
+ }
+
+ val32 = rtw_read32(adapter, reg_macid_sleep);
+ RTW_INFO(FUNC_ADPT_FMT ": [HW_VAR_MACID_SLEEP] macid=%d, org reg_0x%03x=0x%08X\n",
+ FUNC_ADPT_ARG(adapter), id, reg_macid_sleep, val32);
+
+ if (val32 & BIT(bit_shift))
+ break;
+
+ val32 |= BIT(bit_shift);
+ rtw_write32(adapter, reg_macid_sleep, val32);
+ }
+ break;
+
+ case HW_VAR_MACID_WAKEUP: {
+ u32 reg_macid_sleep;
+ u8 bit_shift;
+ u8 id = *(u8 *)val;
+ u32 val32;
+
+ if (id < 32) {
+ reg_macid_sleep = REG_MACID_PAUSE_0;
+ bit_shift = id;
+ } else if (id < 64) {
+ reg_macid_sleep = REG_MACID_PAUSE_1;
+ bit_shift = id - 32;
+ } else {
+ rtw_warn_on(1);
+ break;
+ }
+
+ val32 = rtw_read32(adapter, reg_macid_sleep);
+ RTW_INFO(FUNC_ADPT_FMT ": [HW_VAR_MACID_WAKEUP] macid=%d, org reg_0x%03x=0x%08X\n",
+ FUNC_ADPT_ARG(adapter), id, reg_macid_sleep, val32);
+
+ if (!(val32 & BIT(bit_shift)))
+ break;
+
+ val32 &= ~BIT(bit_shift);
+ rtw_write32(adapter, reg_macid_sleep, val32);
+ }
+ break;
+
+ default:
+ SetHwReg(adapter, variable, val);
+ break;
+ }
+
+}
+
+struct qinfo_88e {
+ u32 head:8;
+ u32 pkt_num:8;
+ u32 tail:8;
+ u32 ac:2;
+ u32 macid:6;
+};
+
+struct bcn_qinfo_88e {
+ u16 head:8;
+ u16 pkt_num:8;
+};
+
+static void dump_qinfo_88e(void *sel, struct qinfo_88e *info, const char *tag)
+{
+ /* if (info->pkt_num) */
+ RTW_PRINT_SEL(sel, "%shead:0x%02x, tail:0x%02x, pkt_num:%u, macid:%u, ac:%u\n"
+ , tag ? tag : "", info->head, info->tail, info->pkt_num, info->macid, info->ac
+ );
+}
+
+static void dump_bcn_qinfo_88e(void *sel, struct bcn_qinfo_88e *info, const char *tag)
+{
+ /* if (info->pkt_num) */
+ RTW_PRINT_SEL(sel, "%shead:0x%02x, pkt_num:%u\n"
+ , tag ? tag : "", info->head, info->pkt_num
+ );
+}
+
+static void dump_mac_qinfo_88e(void *sel, _adapter *adapter)
+{
+ u32 q0_info;
+ u32 q1_info;
+ u32 q2_info;
+ u32 q3_info;
+ /*
+ u32 q4_info;
+ u32 q5_info;
+ u32 q6_info;
+ u32 q7_info;
+ */
+ u32 mg_q_info;
+ u32 hi_q_info;
+ u16 bcn_q_info;
+
+ q0_info = rtw_read32(adapter, REG_Q0_INFO);
+ q1_info = rtw_read32(adapter, REG_Q1_INFO);
+ q2_info = rtw_read32(adapter, REG_Q2_INFO);
+ q3_info = rtw_read32(adapter, REG_Q3_INFO);
+ /*
+ q4_info = rtw_read32(adapter, REG_Q4_INFO);
+ q5_info = rtw_read32(adapter, REG_Q5_INFO);
+ q6_info = rtw_read32(adapter, REG_Q6_INFO);
+ q7_info = rtw_read32(adapter, REG_Q7_INFO);
+ */
+ mg_q_info = rtw_read32(adapter, REG_MGQ_INFO);
+ hi_q_info = rtw_read32(adapter, REG_HGQ_INFO);
+ bcn_q_info = rtw_read16(adapter, REG_BCNQ_INFO);
+
+ dump_qinfo_88e(sel, (struct qinfo_88e *)&q0_info, "Q0 ");
+ dump_qinfo_88e(sel, (struct qinfo_88e *)&q1_info, "Q1 ");
+ dump_qinfo_88e(sel, (struct qinfo_88e *)&q2_info, "Q2 ");
+ dump_qinfo_88e(sel, (struct qinfo_88e *)&q3_info, "Q3 ");
+ /*
+ dump_qinfo_88e(sel, (struct qinfo_88e *)&q4_info, "Q4 ");
+ dump_qinfo_88e(sel, (struct qinfo_88e *)&q5_info, "Q5 ");
+ dump_qinfo_88e(sel, (struct qinfo_88e *)&q6_info, "Q6 ");
+ dump_qinfo_88e(sel, (struct qinfo_88e *)&q7_info, "Q7 ");
+ */
+ dump_qinfo_88e(sel, (struct qinfo_88e *)&mg_q_info, "MG ");
+ dump_qinfo_88e(sel, (struct qinfo_88e *)&hi_q_info, "HI ");
+ dump_bcn_qinfo_88e(sel, (struct bcn_qinfo_88e *)&bcn_q_info, "BCN ");
+}
+
+void GetHwReg8188E(_adapter *adapter, u8 variable, u8 *val)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
+
+
+ switch (variable) {
+ case HW_VAR_SYS_CLKR:
+ *val = rtw_read8(adapter, REG_SYS_CLKR);
+ break;
+
+ case HW_VAR_TXPAUSE:
+ val[0] = rtw_read8(adapter, REG_TXPAUSE);
+ break;
+ case HW_VAR_BCN_VALID:
+ /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2 */
+ val[0] = (BIT0 & rtw_read8(adapter, REG_TDECTRL + 2)) ? true : false;
+ break;
+ case HW_VAR_FWLPS_RF_ON: {
+ /* When we halt NIC, we should check if FW LPS is leave. */
+ if (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off) {
+ /* If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave, */
+ /* because Fw is unload. */
+ val[0] = true;
+ } else {
+ u32 valRCR;
+ valRCR = rtw_read32(adapter, REG_RCR);
+ valRCR &= 0x00070000;
+ if (valRCR)
+ val[0] = false;
+ else
+ val[0] = true;
+ }
+ }
+ break;
+ case HW_VAR_EFUSE_BYTES: /* To get EFUE total used bytes, added by Roger, 2008.12.22. */
+ *((u16 *)(val)) = pHalData->EfuseUsedBytes;
+ break;
+ case HW_VAR_CHK_HI_QUEUE_EMPTY:
+ *val = ((rtw_read32(adapter, REG_HGQ_INFO) & 0x0000ff00) == 0) ? true : false;
+ break;
+ case HW_VAR_DUMP_MAC_QUEUE_INFO:
+ dump_mac_qinfo_88e(val, adapter);
+ break;
+ default:
+ GetHwReg(adapter, variable, val);
+ break;
+ }
+
+}
+
+static void hal_ra_info_dump(_adapter *padapter , void *sel)
+{
+ int i;
+ u8 mac_id;
+ u8 bLinked = false;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+ struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
+ _adapter *iface;
+
+ for (i = 0; i < dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ if ((iface) && rtw_is_adapter_up(iface)) {
+ if (rtw_linked_check(iface)) {
+ bLinked = true;
+ break;
+ }
+ }
+ }
+
+ for (i = 0; i < macid_ctl->num; i++) {
+
+ if (rtw_macid_is_used(macid_ctl, i) && !rtw_macid_is_bmc(macid_ctl, i)) {
+
+ mac_id = (u8) i;
+
+ if (bLinked) {
+ _RTW_PRINT_SEL(sel , "============ RA status - Mac_id:%d ===================\n", mac_id);
+ if (pHalData->fw_ractrl == false) {
+#if (RATE_ADAPTIVE_SUPPORT == 1)
+ _RTW_PRINT_SEL(sel , "Mac_id:%d ,RSSI:%d(%%)\n", mac_id, pHalData->odmpriv.ra_info[mac_id].rssi_sta_ra);
+
+ _RTW_PRINT_SEL(sel , "rate_sgi = %d, decision_rate = %s\n", pHalData->odmpriv.ra_info[mac_id].rate_sgi,
+ HDATA_RATE(pHalData->odmpriv.ra_info[mac_id].decision_rate));
+
+ _RTW_PRINT_SEL(sel , "pt_stage = %d\n", pHalData->odmpriv.ra_info[mac_id].pt_stage);
+
+ _RTW_PRINT_SEL(sel , "rate_id = %d,ra_use_rate = 0x%08x\n", pHalData->odmpriv.ra_info[mac_id].rate_id, pHalData->odmpriv.ra_info[mac_id].ra_use_rate);
+
+#endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
+ } else {
+ u8 cur_rate = rtw_read8(padapter, REG_ADAPTIVE_DATA_RATE_0 + mac_id);
+ u8 sgi = (cur_rate & BIT7) ? true : false;
+
+ cur_rate &= 0x7f;
+
+ _RTW_PRINT_SEL(sel , "Mac_id:%d ,SGI:%d ,Rate:%s\n", mac_id, sgi, HDATA_RATE(cur_rate));
+ }
+ }
+ }
+ }
+}
+
+u8
+GetHalDefVar8188E(
+ PADAPTER Adapter,
+ HAL_DEF_VARIABLE eVariable,
+ void * pValue
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 bResult = _SUCCESS;
+
+ switch (eVariable) {
+ case HAL_DEF_IS_SUPPORT_ANT_DIV:
+#ifdef CONFIG_ANTENNA_DIVERSITY
+ *((u8 *)pValue) = (pHalData->AntDivCfg == 0) ? false : true;
+#endif
+ break;
+ case HAL_DEF_DRVINFO_SZ:
+ *((u32 *)pValue) = DRVINFO_SZ;
+ break;
+ case HAL_DEF_MAX_RECVBUF_SZ:
+ *((u32 *)pValue) = MAX_RECVBUF_SZ;
+ break;
+ case HAL_DEF_RX_PACKET_OFFSET:
+ *((u32 *)pValue) = RXDESC_SIZE + DRVINFO_SZ * 8;
+ break;
+#if (RATE_ADAPTIVE_SUPPORT == 1)
+ case HAL_DEF_RA_DECISION_RATE: {
+ u8 MacID = *((u8 *)pValue);
+ *((u8 *)pValue) = odm_ra_get_decision_rate_8188e(&(pHalData->odmpriv), MacID);
+ }
+ break;
+
+ case HAL_DEF_RA_SGI: {
+ u8 MacID = *((u8 *)pValue);
+ *((u8 *)pValue) = odm_ra_get_sgi_8188e(&(pHalData->odmpriv), MacID);
+ }
+ break;
+#endif
+
+
+ case HAL_DEF_PT_PWR_STATUS:
+#if (POWER_TRAINING_ACTIVE == 1)
+ {
+ u8 MacID = *((u8 *)pValue);
+ *((u8 *)pValue) = odm_ra_get_hw_pwr_status_8188e(&(pHalData->odmpriv), MacID);
+ }
+#endif /* (POWER_TRAINING_ACTIVE==1) */
+ break;
+ case HAL_DEF_EXPLICIT_BEAMFORMEE:
+ case HAL_DEF_EXPLICIT_BEAMFORMER:
+ *((u8 *)pValue) = false;
+ break;
+
+ case HW_DEF_RA_INFO_DUMP:
+ hal_ra_info_dump(Adapter, pValue);
+ break;
+
+ case HAL_DEF_TX_PAGE_SIZE:
+ *((u32 *)pValue) = PAGE_SIZE_128;
+ break;
+ case HAL_DEF_TX_PAGE_BOUNDARY:
+ if (!Adapter->registrypriv.wifi_spec)
+ *(u8 *)pValue = TX_PAGE_BOUNDARY_88E(Adapter);
+ else
+ *(u8 *)pValue = WMM_NORMAL_TX_PAGE_BOUNDARY_88E(Adapter);
+ break;
+ case HAL_DEF_MACID_SLEEP:
+ *(u8 *)pValue = true; /* support macid sleep */
+ break;
+ case HAL_DEF_RX_DMA_SZ_WOW:
+ *(u32 *)pValue = RX_DMA_SIZE_88E(Adapter) - RESV_FMWF;
+ break;
+ case HAL_DEF_RX_DMA_SZ:
+ *(u32 *)pValue = MAX_RX_DMA_BUFFER_SIZE_88E(Adapter);
+ break;
+ case HAL_DEF_RX_PAGE_SIZE:
+ *(u32 *)pValue = PAGE_SIZE_128;
+ break;
+ case HW_VAR_BEST_AMPDU_DENSITY:
+ *((u32 *)pValue) = AMPDU_DENSITY_VALUE_7;
+ break;
+ default:
+ bResult = GetHalDefVar(Adapter, eVariable, pValue);
+ break;
+ }
+
+ return bResult;
+}
+
+#ifdef CONFIG_GPIO_API
+int rtl8188e_GpioFuncCheck(PADAPTER adapter, u8 gpio_num)
+{
+ int ret = _SUCCESS;
+
+ if (IS_HARDWARE_TYPE_8188E(adapter) == _FAIL) {
+ if ((gpio_num > 7) || (gpio_num < 4)) {
+ RTW_INFO("%s The gpio number does not included 4~7.\n",__func__);
+ ret = _FAIL;
+ }
+ }
+
+ return ret;
+}
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c
new file mode 100644
index 000000000000..907434cb011b
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c
@@ -0,0 +1,1713 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _RTL8188E_PHYCFG_C_
+
+#include <drv_types.h>
+#include <rtl8188e_hal.h>
+
+
+/*---------------------------Define Local Constant---------------------------*/
+/* Channel switch:The size of command tables for switch channel*/
+#define MAX_PRECMD_CNT 16
+#define MAX_RFDEPENDCMD_CNT 16
+#define MAX_POSTCMD_CNT 16
+
+#define MAX_DOZE_WAITING_TIMES_9x 64
+
+/*---------------------------Define Local Constant---------------------------*/
+
+
+/*------------------------Define global variable-----------------------------*/
+
+/*------------------------Define local variable------------------------------*/
+
+
+/*--------------------Define export function prototype-----------------------*/
+/* Please refer to header file
+ *--------------------Define export function prototype-----------------------*/
+
+/*----------------------------Function Body----------------------------------*/
+/*
+ * 1. BB register R/W API
+ * */
+
+#if (SIC_ENABLE == 1)
+static bool
+sic_IsSICReady(
+ PADAPTER Adapter
+)
+{
+ bool bRet = false;
+ u32 retryCnt = 0;
+ u8 sic_cmd = 0xff;
+
+ while (1) {
+ if (retryCnt++ >= SIC_MAX_POLL_CNT) {
+ /* RTPRINT(FPHY, (PHY_SICR|PHY_SICW), ("[SIC], sic_IsSICReady() return false\n")); */
+ return false;
+ }
+
+ /* if(RT_SDIO_CANNOT_IO(Adapter)) */
+ /* return false; */
+
+ sic_cmd = rtw_read8(Adapter, SIC_CMD_REG);
+ /* sic_cmd = PlatformEFIORead1Byte(Adapter, SIC_CMD_REG); */
+#if (SIC_HW_SUPPORT == 1)
+ sic_cmd &= 0xf0; /* [7:4] */
+#endif
+ /* RTPRINT(FPHY, (PHY_SICR|PHY_SICW), ("[SIC], sic_IsSICReady(), readback 0x%x=0x%x\n", SIC_CMD_REG, sic_cmd)); */
+ if (sic_cmd == SIC_CMD_READY)
+ return true;
+ else {
+ rtw_msleep_os(1);
+ /* delay_ms(1); */
+ }
+ }
+
+ return bRet;
+}
+
+/*
+u32
+sic_CalculateBitShift(
+ u32 BitMask
+ )
+{
+ u32 i;
+
+ for(i=0; i<=31; i++)
+ {
+ if ( ((BitMask>>i) & 0x1 ) == 1)
+ break;
+ }
+
+ return i;
+}
+*/
+
+static u32
+sic_Read4Byte(
+ Pvoid Adapter,
+ u32 offset
+)
+{
+ u32 u4ret = 0xffffffff;
+#if RTL8188E_SUPPORT == 1
+ u8 retry = 0;
+#endif
+
+ /* RTPRINT(FPHY, PHY_SICR, ("[SIC], sic_Read4Byte(): read offset(%#x)\n", offset)); */
+
+ if (sic_IsSICReady(Adapter)) {
+#if (SIC_HW_SUPPORT == 1)
+ rtw_write8(Adapter, SIC_CMD_REG, SIC_CMD_PREREAD);
+ /* PlatformEFIOWrite1Byte(Adapter, SIC_CMD_REG, SIC_CMD_PREREAD); */
+ /* RTPRINT(FPHY, PHY_SICR, ("write cmdreg 0x%x = 0x%x\n", SIC_CMD_REG, SIC_CMD_PREREAD)); */
+#endif
+ rtw_write8(Adapter, SIC_ADDR_REG, (u8)(offset & 0xff));
+ /* PlatformEFIOWrite1Byte(Adapter, SIC_ADDR_REG, (u8)(offset&0xff)); */
+ /* RTPRINT(FPHY, PHY_SICR, ("write 0x%x = 0x%x\n", SIC_ADDR_REG, (u8)(offset&0xff))); */
+ rtw_write8(Adapter, SIC_ADDR_REG + 1, (u8)((offset & 0xff00) >> 8));
+ /* PlatformEFIOWrite1Byte(Adapter, SIC_ADDR_REG+1, (u8)((offset&0xff00)>>8)); */
+ /* RTPRINT(FPHY, PHY_SICR, ("write 0x%x = 0x%x\n", SIC_ADDR_REG+1, (u8)((offset&0xff00)>>8))); */
+ rtw_write8(Adapter, SIC_CMD_REG, SIC_CMD_READ);
+ /* PlatformEFIOWrite1Byte(Adapter, SIC_CMD_REG, SIC_CMD_READ); */
+ /* RTPRINT(FPHY, PHY_SICR, ("write cmdreg 0x%x = 0x%x\n", SIC_CMD_REG, SIC_CMD_READ)); */
+
+#if RTL8188E_SUPPORT == 1
+ retry = 4;
+ while (retry--) {
+ rtw_udelay_os(50);
+ /* PlatformStallExecution(50); */
+ }
+#else
+ rtw_udelay_os(200);
+ /* PlatformStallExecution(200); */
+#endif
+
+ if (sic_IsSICReady(Adapter)) {
+ u4ret = rtw_read32(Adapter, SIC_DATA_REG);
+ /* u4ret = PlatformEFIORead4Byte(Adapter, SIC_DATA_REG); */
+ /* RTPRINT(FPHY, PHY_SICR, ("read 0x%x = 0x%x\n", SIC_DATA_REG, u4ret)); */
+ /* DbgPrint("<===Read 0x%x = 0x%x\n", offset, u4ret); */
+ }
+ }
+
+ return u4ret;
+}
+
+static void
+sic_Write4Byte(
+ Pvoid Adapter,
+ u32 offset,
+ u32 data
+)
+{
+#if RTL8188E_SUPPORT == 1
+ u8 retry = 6;
+#endif
+ /* DbgPrint("=>Write 0x%x = 0x%x\n", offset, data); */
+ /* RTPRINT(FPHY, PHY_SICW, ("[SIC], sic_Write4Byte(): write offset(%#x)=0x%x\n", offset, data)); */
+ if (sic_IsSICReady(Adapter)) {
+#if (SIC_HW_SUPPORT == 1)
+ rtw_write8(Adapter, SIC_CMD_REG, SIC_CMD_PREWRITE);
+ /* PlatformEFIOWrite1Byte(Adapter, SIC_CMD_REG, SIC_CMD_PREWRITE); */
+ /* RTPRINT(FPHY, PHY_SICW, ("write data 0x%x = 0x%x\n", SIC_CMD_REG, SIC_CMD_PREWRITE)); */
+#endif
+ rtw_write8(Adapter, SIC_ADDR_REG, (u8)(offset & 0xff));
+ /* PlatformEFIOWrite1Byte(Adapter, SIC_ADDR_REG, (u8)(offset&0xff)); */
+ /* RTPRINT(FPHY, PHY_SICW, ("write 0x%x=0x%x\n", SIC_ADDR_REG, (u8)(offset&0xff))); */
+ rtw_write8(Adapter, SIC_ADDR_REG + 1, (u8)((offset & 0xff00) >> 8));
+ /* PlatformEFIOWrite1Byte(Adapter, SIC_ADDR_REG+1, (u8)((offset&0xff00)>>8)); */
+ /* RTPRINT(FPHY, PHY_SICW, ("write 0x%x=0x%x\n", (SIC_ADDR_REG+1), (u8)((offset&0xff00)>>8))); */
+ rtw_write32(Adapter, SIC_DATA_REG, (u32)data);
+ /* PlatformEFIOWrite4Byte(Adapter, SIC_DATA_REG, (u32)data); */
+ /* RTPRINT(FPHY, PHY_SICW, ("write data 0x%x = 0x%x\n", SIC_DATA_REG, data)); */
+ rtw_write8(Adapter, SIC_CMD_REG, SIC_CMD_WRITE);
+ /* PlatformEFIOWrite1Byte(Adapter, SIC_CMD_REG, SIC_CMD_WRITE); */
+ /* RTPRINT(FPHY, PHY_SICW, ("write data 0x%x = 0x%x\n", SIC_CMD_REG, SIC_CMD_WRITE)); */
+#if RTL8188E_SUPPORT == 1
+ while (retry--) {
+ rtw_udelay_os(50);
+ /* PlatformStallExecution(50); */
+ }
+#else
+ rtw_udelay_os(150);
+ /* PlatformStallExecution(150); */
+#endif
+
+ }
+}
+/* ************************************************************
+ * extern function
+ * ************************************************************ */
+static void
+SIC_SetBBReg(
+ PADAPTER Adapter,
+ u32 RegAddr,
+ u32 BitMask,
+ u32 Data
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u32 OriginalValue, BitShift;
+ u16 BBWaitCounter = 0;
+
+ if (BitMask != bMaskDWord) { /* if not "double word" write */
+ OriginalValue = sic_Read4Byte(Adapter, RegAddr);
+ /* BitShift = sic_CalculateBitShift(BitMask); */
+ BitShift = PHY_CalculateBitShift(BitMask);
+ Data = (((OriginalValue)&(~BitMask)) | (Data << BitShift));
+ }
+
+ sic_Write4Byte(Adapter, RegAddr, Data);
+}
+
+static u32
+SIC_QueryBBReg(
+ PADAPTER Adapter,
+ u32 RegAddr,
+ u32 BitMask
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u32 ReturnValue = 0, OriginalValue, BitShift;
+ u16 BBWaitCounter = 0;
+
+ OriginalValue = sic_Read4Byte(Adapter, RegAddr);
+ BitShift = PHY_CalculateBitShift(BitMask);
+ ReturnValue = (OriginalValue & BitMask) >> BitShift;
+
+ return ReturnValue;
+}
+
+void
+SIC_Init(
+ PADAPTER Adapter
+)
+{
+ /* Here we need to write 0x1b8~0x1bf = 0 after fw is downloaded */
+ /* because for 8723E at beginning 0x1b8=0x1e, that will cause */
+ /* sic always not be ready */
+#if (SIC_HW_SUPPORT == 1)
+ /* RTPRINT(FPHY, PHY_SICR, ("[SIC], SIC_Init(), write 0x%x = 0x%x\n", */
+ /* SIC_INIT_REG, SIC_INIT_VAL)); */
+ rtw_write8(Adapter, SIC_INIT_REG, SIC_INIT_VAL);
+ /* PlatformEFIOWrite1Byte(Adapter, SIC_INIT_REG, SIC_INIT_VAL); */
+ /* RTPRINT(FPHY, PHY_SICR, ("[SIC], SIC_Init(), write 0x%x = 0x%x\n", */
+ /* SIC_CMD_REG, SIC_CMD_INIT)); */
+ rtw_write8(Adapter, SIC_CMD_REG, SIC_CMD_INIT);
+ /* PlatformEFIOWrite1Byte(Adapter, SIC_CMD_REG, SIC_CMD_INIT); */
+#else
+ /* RTPRINT(FPHY, PHY_SICR, ("[SIC], SIC_Init(), write 0x1b8~0x1bf = 0x0\n")); */
+ rtw_write32(Adapter, SIC_CMD_REG, 0);
+ /* PlatformEFIOWrite4Byte(Adapter, SIC_CMD_REG, 0); */
+ rtw_write32(Adapter, SIC_CMD_REG + 4, 0);
+ /* PlatformEFIOWrite4Byte(Adapter, SIC_CMD_REG+4, 0); */
+#endif
+}
+
+static bool
+SIC_LedOff(
+ PADAPTER Adapter
+)
+{
+ /* When SIC is enabled, led pin will be used as debug pin, */
+ /* so don't execute led function when SIC is enabled. */
+ return true;
+}
+#endif
+
+/**
+* Function: PHY_QueryBBReg
+*
+* OverView: Read "sepcific bits" from BB register
+*
+* Input:
+* PADAPTER Adapter,
+* u32 RegAddr, //The target address to be readback
+* u32 BitMask //The target bit position in the target address
+* //to be readback
+* Output: None
+* Return: u32 Data //The readback register value
+* Note: This function is equal to "GetRegSetting" in PHY programming guide
+*/
+u32
+PHY_QueryBBReg8188E(
+ PADAPTER Adapter,
+ u32 RegAddr,
+ u32 BitMask
+)
+{
+ u32 ReturnValue = 0, OriginalValue, BitShift;
+ u16 BBWaitCounter = 0;
+
+#if (DISABLE_BB_RF == 1)
+ return 0;
+#endif
+
+#if (SIC_ENABLE == 1)
+ return SIC_QueryBBReg(Adapter, RegAddr, BitMask);
+#endif
+
+
+ OriginalValue = rtw_read32(Adapter, RegAddr);
+ BitShift = PHY_CalculateBitShift(BitMask);
+ ReturnValue = (OriginalValue & BitMask) >> BitShift;
+
+ /* RTPRINT(FPHY, PHY_BBR, ("BBR MASK=0x%lx Addr[0x%lx]=0x%lx\n", BitMask, RegAddr, OriginalValue)); */
+
+ return ReturnValue;
+
+}
+
+
+/**
+* Function: PHY_SetBBReg
+*
+* OverView: Write "Specific bits" to BB register (page 8~)
+*
+* Input:
+* PADAPTER Adapter,
+* u32 RegAddr, //The target address to be modified
+* u32 BitMask //The target bit position in the target address
+* //to be modified
+* u32 Data //The new register value in the target bit position
+* //of the target address
+*
+* Output: None
+* Return: None
+* Note: This function is equal to "PutRegSetting" in PHY programming guide
+*/
+
+void
+PHY_SetBBReg8188E(
+ PADAPTER Adapter,
+ u32 RegAddr,
+ u32 BitMask,
+ u32 Data
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ /* u16 BBWaitCounter = 0; */
+ u32 OriginalValue, BitShift;
+
+#if (DISABLE_BB_RF == 1)
+ return;
+#endif
+
+#if (SIC_ENABLE == 1)
+ SIC_SetBBReg(Adapter, RegAddr, BitMask, Data);
+ return;
+#endif
+
+
+ if (BitMask != bMaskDWord) { /* if not "double word" write */
+ OriginalValue = rtw_read32(Adapter, RegAddr);
+ BitShift = PHY_CalculateBitShift(BitMask);
+ Data = ((OriginalValue & (~BitMask)) | ((Data << BitShift) & BitMask));
+ }
+
+ rtw_write32(Adapter, RegAddr, Data);
+
+ /* RTPRINT(FPHY, PHY_BBW, ("BBW MASK=0x%lx Addr[0x%lx]=0x%lx\n", BitMask, RegAddr, Data)); */
+
+}
+
+
+/*
+ * 2. RF register R/W API
+ *
+ **
+* Function: phy_RFSerialRead
+*
+* OverView: Read regster from RF chips
+*
+* Input:
+* PADAPTER Adapter,
+* u8 eRFPath, //Radio path of A/B/C/D
+* u32 Offset, //The target address to be read
+*
+* Output: None
+* Return: u32 reback value
+* Note: Threre are three types of serial operations:
+* 1. Software serial write
+* 2. Hardware LSSI-Low Speed Serial Interface
+* 3. Hardware HSSI-High speed
+* serial write. Driver need to implement (1) and (2).
+* This function is equal to the combination of RF_ReadReg() and RFLSSIRead()
+*/
+static u32
+phy_RFSerialRead(
+ PADAPTER Adapter,
+ u8 eRFPath,
+ u32 Offset
+)
+{
+ u32 retValue = 0;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ BB_REGISTER_DEFINITION_T *pPhyReg = &pHalData->PHYRegDef[eRFPath];
+ u32 NewOffset;
+ u32 tmplong, tmplong2;
+ u8 RfPiEnable = 0;
+
+ _enter_critical_mutex(&(adapter_to_dvobj(Adapter)->rf_read_reg_mutex) , NULL);
+ /* Make sure RF register offset is correct */
+ Offset &= 0xff;
+
+ /* Switch page for 8256 RF IC */
+ NewOffset = Offset;
+
+ /* 2009/06/17 MH We can not execute IO for power save or other accident mode. */
+ /* if(RT_CANNOT_IO(Adapter)) */
+ /* { */
+ /* RTPRINT(FPHY, PHY_RFR, ("phy_RFSerialRead return all one\n")); */
+ /* return 0xFFFFFFFF; */
+ /* } */
+
+ /* For 92S LSSI Read RFLSSIRead */
+ /* For RF A/B write 0x824/82c(does not work in the future) */
+ /* We must use 0x824 for RF A and B to execute read trigger */
+ tmplong = phy_query_bb_reg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord);
+ if (eRFPath == RF_PATH_A)
+ tmplong2 = tmplong;
+ else
+ tmplong2 = phy_query_bb_reg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord);
+
+ tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset << 23) | bLSSIReadEdge; /* T65 RF */
+
+ phy_set_bb_reg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord, tmplong & (~bLSSIReadEdge));
+ rtw_udelay_os(10);/* PlatformStallExecution(10); */
+
+ phy_set_bb_reg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord, tmplong2);
+ rtw_udelay_os(100);/* PlatformStallExecution(100); */
+
+ /* phy_set_bb_reg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord, tmplong|bLSSIReadEdge); */
+ rtw_udelay_os(10);/* PlatformStallExecution(10); */
+
+ if (eRFPath == RF_PATH_A)
+ RfPiEnable = (u8)phy_query_bb_reg(Adapter, rFPGA0_XA_HSSIParameter1, BIT8);
+ else if (eRFPath == RF_PATH_B)
+ RfPiEnable = (u8)phy_query_bb_reg(Adapter, rFPGA0_XB_HSSIParameter1, BIT8);
+
+ if (RfPiEnable) {
+ /* Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */
+ retValue = phy_query_bb_reg(Adapter, pPhyReg->rfLSSIReadBackPi, bLSSIReadBackData);
+ /* RTW_INFO("Readback from RF-PI : 0x%x\n", retValue); */
+ } else {
+ /* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */
+ retValue = phy_query_bb_reg(Adapter, pPhyReg->rfLSSIReadBack, bLSSIReadBackData);
+ /* RTW_INFO("Readback from RF-SI : 0x%x\n", retValue); */
+ }
+ /* RTW_INFO("RFR-%d Addr[0x%x]=0x%x\n", eRFPath, pPhyReg->rfLSSIReadBack, retValue); */
+ _exit_critical_mutex(&(adapter_to_dvobj(Adapter)->rf_read_reg_mutex) , NULL);
+ return retValue;
+
+}
+
+
+
+/**
+* Function: phy_RFSerialWrite
+*
+* OverView: Write data to RF register (page 8~)
+*
+* Input:
+* PADAPTER Adapter,
+* u8 eRFPath, //Radio path of A/B/C/D
+* u32 Offset, //The target address to be read
+* u32 Data //The new register Data in the target bit position
+* //of the target to be read
+*
+* Output: None
+* Return: None
+* Note: Threre are three types of serial operations:
+* 1. Software serial write
+* 2. Hardware LSSI-Low Speed Serial Interface
+* 3. Hardware HSSI-High speed
+* serial write. Driver need to implement (1) and (2).
+* This function is equal to the combination of RF_ReadReg() and RFLSSIRead()
+ *
+ * Note: For RF8256 only
+ * The total count of RTL8256(Zebra4) register is around 36 bit it only employs
+ * 4-bit RF address. RTL8256 uses "register mode control bit" (Reg00[12], Reg00[10])
+ * to access register address bigger than 0xf. See "Appendix-4 in PHY Configuration
+ * programming guide" for more details.
+ * Thus, we define a sub-finction for RTL8526 register address conversion
+ * ===========================================================
+ * Register Mode RegCTL[1] RegCTL[0] Note
+ * (Reg00[12]) (Reg00[10])
+ * ===========================================================
+ * Reg_Mode0 0 x Reg 0 ~15(0x0 ~ 0xf)
+ * ------------------------------------------------------------------
+ * Reg_Mode1 1 0 Reg 16 ~30(0x1 ~ 0xf)
+ * ------------------------------------------------------------------
+ * Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf)
+ * ------------------------------------------------------------------
+ *
+ * 2008/09/02 MH Add 92S RF definition
+ *
+ *
+ *
+*/
+static void
+phy_RFSerialWrite(
+ PADAPTER Adapter,
+ u8 eRFPath,
+ u32 Offset,
+ u32 Data
+)
+{
+ u32 DataAndAddr = 0;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ BB_REGISTER_DEFINITION_T *pPhyReg = &pHalData->PHYRegDef[eRFPath];
+ u32 NewOffset;
+
+ Offset &= 0xff;
+
+ /* Switch page for 8256 RF IC */
+ NewOffset = Offset;
+
+ /* Put write addr in [5:0] and write data in [31:16] */
+ DataAndAddr = ((NewOffset << 20) | (Data & 0x000fffff)) & 0x0fffffff; /* T65 RF */
+
+ /* Write Operation */
+ phy_set_bb_reg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
+}
+
+/**
+* Function: PHY_QueryRFReg
+*
+* OverView: Query "Specific bits" to RF register (page 8~)
+*
+* Input:
+* PADAPTER Adapter,
+* u8 eRFPath, //Radio path of A/B/C/D
+* u32 RegAddr, //The target address to be read
+* u32 BitMask //The target bit position in the target address
+* //to be read
+*
+* Output: None
+* Return: u32 Readback value
+* Note: This function is equal to "GetRFRegSetting" in PHY programming guide
+*/
+u32
+PHY_QueryRFReg8188E(
+ PADAPTER Adapter,
+ u8 eRFPath,
+ u32 RegAddr,
+ u32 BitMask
+)
+{
+ u32 Original_Value, Readback_Value, BitShift;
+ /* HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); */
+ /* u8 RFWaitCounter = 0; */
+ /* unsigned long irqL; */
+
+#if (DISABLE_BB_RF == 1)
+ return 0;
+#endif
+
+
+ Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr);
+
+ BitShift = PHY_CalculateBitShift(BitMask);
+ Readback_Value = (Original_Value & BitMask) >> BitShift;
+
+ return Readback_Value;
+}
+
+/**
+* Function: PHY_SetRFReg
+*
+* OverView: Write "Specific bits" to RF register (page 8~)
+*
+* Input:
+* PADAPTER Adapter,
+* u8 eRFPath, //Radio path of A/B/C/D
+* u32 RegAddr, //The target address to be modified
+* u32 BitMask //The target bit position in the target address
+* //to be modified
+* u32 Data //The new register Data in the target bit position
+* //of the target address
+*
+* Output: None
+* Return: None
+* Note: This function is equal to "PutRFRegSetting" in PHY programming guide
+*/
+void
+PHY_SetRFReg8188E(
+ PADAPTER Adapter,
+ u8 eRFPath,
+ u32 RegAddr,
+ u32 BitMask,
+ u32 Data
+)
+{
+
+ /* HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); */
+ /* u8 RFWaitCounter = 0; */
+ u32 Original_Value, BitShift;
+ /* unsigned long irqL; */
+
+#if (DISABLE_BB_RF == 1)
+ return;
+#endif
+
+ /* RF data is 12 bits only */
+ if (BitMask != bRFRegOffsetMask) {
+ Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr);
+ BitShift = PHY_CalculateBitShift(BitMask);
+ Data = ((Original_Value & (~BitMask)) | (Data << BitShift));
+ }
+
+ phy_RFSerialWrite(Adapter, eRFPath, RegAddr, Data);
+}
+
+
+/*
+ * 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt.
+ * */
+
+/*-----------------------------------------------------------------------------
+ * Function: PHY_MACConfig8192C
+ *
+ * Overview: Condig MAC by header file or parameter file.
+ *
+ * Input: NONE
+ *
+ * Output: NONE
+ *
+ * Return: NONE
+ *
+ * Revised History:
+ * When Who Remark
+ * 08/12/2008 MHC Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+s32 PHY_MACConfig8188E(PADAPTER Adapter)
+{
+ int rtStatus = _SUCCESS;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u16 val = 0;
+
+ /* */
+ /* Config MAC */
+ /* */
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+ rtStatus = phy_ConfigMACWithParaFile(Adapter, PHY_FILE_MAC_REG);
+ if (rtStatus == _FAIL)
+#endif
+ {
+#ifdef CONFIG_EMBEDDED_FWIMG
+ if (HAL_STATUS_FAILURE == odm_config_mac_with_header_file(&pHalData->odmpriv))
+ rtStatus = _FAIL;
+ else
+ rtStatus = _SUCCESS;
+#endif/* CONFIG_EMBEDDED_FWIMG */
+ }
+
+ /* 2010.07.13 AMPDU aggregation number B */
+ val |= MAX_AGGR_NUM;
+ val = val << 8;
+ val |= MAX_AGGR_NUM;
+ rtw_write16(Adapter, REG_MAX_AGGR_NUM, val);
+ /* rtw_write8(Adapter, REG_MAX_AGGR_NUM, 0x0B); */
+
+ return rtStatus;
+
+}
+
+/*-----------------------------------------------------------------------------
+* Function: phy_InitBBRFRegisterDefinition
+*
+* OverView: Initialize Register definition offset for Radio Path A/B/C/D
+*
+* Input:
+* PADAPTER Adapter,
+*
+* Output: None
+* Return: None
+* Note: The initialization value is constant and it should never be changes
+-----------------------------------------------------------------------------*/
+static void
+phy_InitBBRFRegisterDefinition(
+ PADAPTER Adapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ /* RF Interface Sowrtware Control */
+ pHalData->PHYRegDef[RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; /* 16 LSBs if read 32-bit from 0x870 */
+ pHalData->PHYRegDef[RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */
+ pHalData->PHYRegDef[RF_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;/* 16 LSBs if read 32-bit from 0x874 */
+ pHalData->PHYRegDef[RF_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;/* 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) */
+
+ /* RF Interface Output (and Enable) */
+ pHalData->PHYRegDef[RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; /* 16 LSBs if read 32-bit from 0x860 */
+ pHalData->PHYRegDef[RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; /* 16 LSBs if read 32-bit from 0x864 */
+
+ /* RF Interface (Output and) Enable */
+ pHalData->PHYRegDef[RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
+ pHalData->PHYRegDef[RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */
+
+ /* Addr of LSSI. Wirte RF register by driver */
+ pHalData->PHYRegDef[RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; /* LSSI Parameter */
+ pHalData->PHYRegDef[RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
+
+ /* Tranceiver A~D HSSI Parameter-2 */
+ pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; /* wire control parameter2 */
+ pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; /* wire control parameter2 */
+
+ /* Tranceiver LSSI Readback SI mode */
+ pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
+ pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
+ pHalData->PHYRegDef[RF_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack;
+ pHalData->PHYRegDef[RF_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack;
+
+ /* Tranceiver LSSI Readback PI mode */
+ pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback;
+ pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBackPi = TransceiverB_HSPI_Readback;
+}
+
+static void
+phy_BB8192C_Config_1T(
+ PADAPTER Adapter
+)
+{
+ /* for path - B */
+ phy_set_bb_reg(Adapter, rFPGA0_TxInfo, 0x3, 0x2);
+ phy_set_bb_reg(Adapter, rFPGA1_TxInfo, 0x300033, 0x200022);
+
+ /* 20100519 Joseph: Add for 1T2R config. Suggested by Kevin, Jenyu and Yunan. */
+ phy_set_bb_reg(Adapter, rCCK0_AFESetting, bMaskByte3, 0x45);
+ phy_set_bb_reg(Adapter, rOFDM0_TRxPathEnable, bMaskByte0, 0x23);
+ phy_set_bb_reg(Adapter, rOFDM0_AGCParameter1, 0x30, 0x1); /* B path first AGC */
+
+ phy_set_bb_reg(Adapter, 0xe74, 0x0c000000, 0x2);
+ phy_set_bb_reg(Adapter, 0xe78, 0x0c000000, 0x2);
+ phy_set_bb_reg(Adapter, 0xe7c, 0x0c000000, 0x2);
+ phy_set_bb_reg(Adapter, 0xe80, 0x0c000000, 0x2);
+ phy_set_bb_reg(Adapter, 0xe88, 0x0c000000, 0x2);
+
+
+}
+
+/* Joseph test: new initialize order!!
+ * Test only!! This part need to be re-organized.
+ * Now it is just for 8256. */
+static int
+phy_BB8190_Config_HardCode(
+ PADAPTER Adapter
+)
+{
+ /* RT_ASSERT(false, ("This function is not implement yet!!\n")); */
+ return _SUCCESS;
+}
+
+static int
+phy_BB8188E_Config_ParaFile(
+ PADAPTER Adapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ int rtStatus = _SUCCESS;
+
+ /* */
+ /* 1. Read PHY_REG.TXT BB INIT!! */
+ /* */
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+ if (phy_ConfigBBWithParaFile(Adapter, PHY_FILE_PHY_REG, CONFIG_BB_PHY_REG) == _FAIL)
+#endif
+ {
+#ifdef CONFIG_EMBEDDED_FWIMG
+ if (HAL_STATUS_FAILURE == odm_config_bb_with_header_file(&pHalData->odmpriv, CONFIG_BB_PHY_REG))
+ rtStatus = _FAIL;
+#endif
+ }
+
+ if (rtStatus != _SUCCESS) {
+ goto phy_BB8190_Config_ParaFile_Fail;
+ }
+
+#if (MP_DRIVER == 1)
+ /* */
+ /* 1.1 Read PHY_REG_MP.TXT BB INIT!! */
+ /* */
+ if (Adapter->registrypriv.mp_mode == 1) {
+ /* 3 Read PHY_REG.TXT BB INIT!! */
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+ if (phy_ConfigBBWithMpParaFile(Adapter, PHY_FILE_PHY_REG_MP) == _FAIL)
+#endif
+ {
+#ifdef CONFIG_EMBEDDED_FWIMG
+ if (HAL_STATUS_SUCCESS != odm_config_bb_with_header_file(&pHalData->odmpriv, CONFIG_BB_PHY_REG_MP))
+ rtStatus = _FAIL;
+#endif
+ }
+
+ if (rtStatus != _SUCCESS) {
+ RTW_INFO("phy_BB8188E_Config_ParaFile():Write BB Reg MP Fail!!");
+ goto phy_BB8190_Config_ParaFile_Fail;
+ }
+ }
+#endif /* #if (MP_DRIVER == 1) */
+
+ /* */
+ /* 3. BB AGC table Initialization */
+ /* */
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+ if (phy_ConfigBBWithParaFile(Adapter, PHY_FILE_AGC_TAB, CONFIG_BB_AGC_TAB) == _FAIL)
+#endif
+ {
+#ifdef CONFIG_EMBEDDED_FWIMG
+ if (HAL_STATUS_FAILURE == odm_config_bb_with_header_file(&pHalData->odmpriv, CONFIG_BB_AGC_TAB))
+ rtStatus = _FAIL;
+#endif
+ }
+
+ if (rtStatus != _SUCCESS) {
+ goto phy_BB8190_Config_ParaFile_Fail;
+ }
+
+
+phy_BB8190_Config_ParaFile_Fail:
+
+ return rtStatus;
+}
+
+
+int
+PHY_BBConfig8188E(
+ PADAPTER Adapter
+)
+{
+ int rtStatus = _SUCCESS;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u32 RegVal;
+ u8 TmpU1B = 0;
+ u8 value8;
+
+ phy_InitBBRFRegisterDefinition(Adapter);
+
+
+ /* Enable BB and RF */
+ RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
+ rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal | BIT13 | BIT0 | BIT1));
+
+ /* 20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */
+ /* rtw_write8(Adapter, REG_AFE_PLL_CTRL, 0x83); */
+ /* rtw_write8(Adapter, REG_AFE_PLL_CTRL+1, 0xdb); */
+
+ rtw_write8(Adapter, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
+
+ rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | FEN_BB_GLB_RSTn | FEN_BBRSTB);
+
+ /* Config BB and AGC */
+ rtStatus = phy_BB8188E_Config_ParaFile(Adapter);
+
+ hal_set_crystal_cap(Adapter, pHalData->crystal_cap);
+
+ return rtStatus;
+}
+
+int
+PHY_RFConfig8188E(
+ PADAPTER Adapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ int rtStatus = _SUCCESS;
+
+ /* RF config */
+ rtStatus = PHY_RF6052_Config8188E(Adapter);
+ return rtStatus;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Function: PHY_ConfigRFWithParaFile()
+ *
+ * Overview: This function read RF parameters from general file format, and do RF 3-wire
+ *
+ * Input: PADAPTER Adapter
+ * ps1Byte pFileName
+ * u8 eRFPath
+ *
+ * Output: NONE
+ *
+ * Return: RT_STATUS_SUCCESS: configuration file exist
+ *
+ * Note: Delay may be required for RF configuration
+ *---------------------------------------------------------------------------*/
+int
+rtl8188e_PHY_ConfigRFWithParaFile(
+ PADAPTER Adapter,
+ u8 *pFileName,
+ u8 eRFPath
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ int rtStatus = _SUCCESS;
+
+
+ return rtStatus;
+
+}
+
+/* ****************************************
+ * The following is for High Power PA
+ * **************************************** */
+#define HighPowerRadioAArrayLen 22
+/* This is for High power PA */
+static u32 Rtl8192S_HighPower_RadioA_Array[HighPowerRadioAArrayLen] = {
+ 0x013, 0x00029ea4,
+ 0x013, 0x00025e74,
+ 0x013, 0x00020ea4,
+ 0x013, 0x0001ced0,
+ 0x013, 0x00019f40,
+ 0x013, 0x00014e70,
+ 0x013, 0x000106a0,
+ 0x013, 0x0000c670,
+ 0x013, 0x000082a0,
+ 0x013, 0x00004270,
+ 0x013, 0x00000240,
+};
+
+/* ****************************************
+ *-----------------------------------------------------------------------------
+ * Function: GetTxPowerLevel8190()
+ *
+ * Overview: This function is export to "common" moudule
+ *
+ * Input: PADAPTER Adapter
+ * psByte Power Level
+ *
+ * Output: NONE
+ *
+ * Return: NONE
+ *
+ *---------------------------------------------------------------------------*/
+void
+PHY_GetTxPowerLevel8188E(
+ PADAPTER Adapter,
+ s32 *powerlevel
+)
+{
+}
+
+/*-----------------------------------------------------------------------------
+ * Function: SetTxPowerLevel8190()
+ *
+ * Overview: This function is export to "HalCommon" moudule
+ * We must consider RF path later!!!!!!!
+ *
+ * Input: PADAPTER Adapter
+ * u8 channel
+ *
+ * Output: NONE
+ *
+ * Return: NONE
+ * 2008/11/04 MHC We remove EEPROM_93C56.
+ * We need to move CCX relative code to independet file.
+ * 2009/01/21 MHC Support new EEPROM format from SD3 requirement.
+ *
+ *---------------------------------------------------------------------------*/
+void
+PHY_SetTxPowerLevel8188E(
+ PADAPTER Adapter,
+ u8 Channel
+)
+{
+ /* RTW_INFO("==>PHY_SetTxPowerLevel8188E()\n"); */
+
+ phy_set_tx_power_level_by_path(Adapter, Channel, ODM_RF_PATH_A);
+
+ /* RTW_INFO("<==PHY_SetTxPowerLevel8188E()\n"); */
+}
+
+void
+PHY_SetTxPowerIndex_8188E(
+ PADAPTER Adapter,
+ u32 PowerIndex,
+ u8 RFPath,
+ u8 Rate
+)
+{
+ if (RFPath == ODM_RF_PATH_A) {
+ switch (Rate) {
+ case MGN_1M:
+ phy_set_bb_reg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, PowerIndex);
+ break;
+ case MGN_2M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte1, PowerIndex);
+ break;
+ case MGN_5_5M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte2, PowerIndex);
+ break;
+ case MGN_11M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte3, PowerIndex);
+ break;
+
+ case MGN_6M:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Rate18_06, bMaskByte0, PowerIndex);
+ break;
+ case MGN_9M:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Rate18_06, bMaskByte1, PowerIndex);
+ break;
+ case MGN_12M:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Rate18_06, bMaskByte2, PowerIndex);
+ break;
+ case MGN_18M:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Rate18_06, bMaskByte3, PowerIndex);
+ break;
+
+ case MGN_24M:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Rate54_24, bMaskByte0, PowerIndex);
+ break;
+ case MGN_36M:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Rate54_24, bMaskByte1, PowerIndex);
+ break;
+ case MGN_48M:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Rate54_24, bMaskByte2, PowerIndex);
+ break;
+ case MGN_54M:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Rate54_24, bMaskByte3, PowerIndex);
+ break;
+
+ case MGN_MCS0:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte0, PowerIndex);
+ break;
+ case MGN_MCS1:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte1, PowerIndex);
+ break;
+ case MGN_MCS2:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte2, PowerIndex);
+ break;
+ case MGN_MCS3:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte3, PowerIndex);
+ break;
+
+ case MGN_MCS4:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte0, PowerIndex);
+ break;
+ case MGN_MCS5:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte1, PowerIndex);
+ break;
+ case MGN_MCS6:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte2, PowerIndex);
+ break;
+ case MGN_MCS7:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte3, PowerIndex);
+ break;
+
+ case MGN_MCS8:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs11_Mcs08, bMaskByte0, PowerIndex);
+ break;
+ case MGN_MCS9:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs11_Mcs08, bMaskByte1, PowerIndex);
+ break;
+ case MGN_MCS10:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs11_Mcs08, bMaskByte2, PowerIndex);
+ break;
+ case MGN_MCS11:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs11_Mcs08, bMaskByte3, PowerIndex);
+ break;
+
+ case MGN_MCS12:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs15_Mcs12, bMaskByte0, PowerIndex);
+ break;
+ case MGN_MCS13:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs15_Mcs12, bMaskByte1, PowerIndex);
+ break;
+ case MGN_MCS14:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs15_Mcs12, bMaskByte2, PowerIndex);
+ break;
+ case MGN_MCS15:
+ phy_set_bb_reg(Adapter, rTxAGC_A_Mcs15_Mcs12, bMaskByte3, PowerIndex);
+ break;
+
+ default:
+ RTW_INFO("Invalid Rate!!\n");
+ break;
+ }
+ } else if (RFPath == ODM_RF_PATH_B) {
+ switch (Rate) {
+ case MGN_1M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_CCK1_55_Mcs32, bMaskByte1, PowerIndex);
+ break;
+ case MGN_2M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_CCK1_55_Mcs32, bMaskByte2, PowerIndex);
+ break;
+ case MGN_5_5M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_CCK1_55_Mcs32, bMaskByte3, PowerIndex);
+ break;
+ case MGN_11M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, PowerIndex);
+ break;
+
+ case MGN_6M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Rate18_06, bMaskByte0, PowerIndex);
+ break;
+ case MGN_9M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Rate18_06, bMaskByte1, PowerIndex);
+ break;
+ case MGN_12M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Rate18_06, bMaskByte2, PowerIndex);
+ break;
+ case MGN_18M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Rate18_06, bMaskByte3, PowerIndex);
+ break;
+
+ case MGN_24M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Rate54_24, bMaskByte0, PowerIndex);
+ break;
+ case MGN_36M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Rate54_24, bMaskByte1, PowerIndex);
+ break;
+ case MGN_48M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Rate54_24, bMaskByte2, PowerIndex);
+ break;
+ case MGN_54M:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Rate54_24, bMaskByte3, PowerIndex);
+ break;
+
+ case MGN_MCS0:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs03_Mcs00, bMaskByte0, PowerIndex);
+ break;
+ case MGN_MCS1:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs03_Mcs00, bMaskByte1, PowerIndex);
+ break;
+ case MGN_MCS2:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs03_Mcs00, bMaskByte2, PowerIndex);
+ break;
+ case MGN_MCS3:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs03_Mcs00, bMaskByte3, PowerIndex);
+ break;
+
+ case MGN_MCS4:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs07_Mcs04, bMaskByte0, PowerIndex);
+ break;
+ case MGN_MCS5:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs07_Mcs04, bMaskByte1, PowerIndex);
+ break;
+ case MGN_MCS6:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs07_Mcs04, bMaskByte2, PowerIndex);
+ break;
+ case MGN_MCS7:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs07_Mcs04, bMaskByte3, PowerIndex);
+ break;
+
+ case MGN_MCS8:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs11_Mcs08, bMaskByte0, PowerIndex);
+ break;
+ case MGN_MCS9:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs11_Mcs08, bMaskByte1, PowerIndex);
+ break;
+ case MGN_MCS10:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs11_Mcs08, bMaskByte2, PowerIndex);
+ break;
+ case MGN_MCS11:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs11_Mcs08, bMaskByte3, PowerIndex);
+ break;
+
+ case MGN_MCS12:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs15_Mcs12, bMaskByte0, PowerIndex);
+ break;
+ case MGN_MCS13:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs15_Mcs12, bMaskByte1, PowerIndex);
+ break;
+ case MGN_MCS14:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs15_Mcs12, bMaskByte2, PowerIndex);
+ break;
+ case MGN_MCS15:
+ phy_set_bb_reg(Adapter, rTxAGC_B_Mcs15_Mcs12, bMaskByte3, PowerIndex);
+ break;
+
+ default:
+ RTW_INFO("Invalid Rate!!\n");
+ break;
+ }
+ } else
+ RTW_INFO("Invalid RFPath!!\n");
+}
+
+static u8
+phy_GetCurrentTxNum_8188E(
+ PADAPTER pAdapter,
+ u8 Rate
+)
+{
+ u8 tmpByte = 0;
+ u32 tmpDWord = 0;
+ u8 TxNum = RF_TX_NUM_NONIMPLEMENT;
+
+ if ((Rate >= MGN_MCS8 && Rate <= MGN_MCS15))
+ TxNum = RF_2TX;
+ else
+ TxNum = RF_1TX;
+
+ return TxNum;
+}
+
+static s8 tx_power_extra_bias(
+ u8 RFPath,
+ u8 Rate,
+ CHANNEL_WIDTH BandWidth,
+ u8 Channel
+)
+{
+ s8 bias = 0;
+
+ if (Rate == MGN_2M)
+ bias = -9;
+
+ return bias;
+}
+
+u8
+PHY_GetTxPowerIndex_8188E(
+ PADAPTER pAdapter,
+ u8 RFPath,
+ u8 Rate,
+ u8 BandWidth,
+ u8 Channel,
+ struct txpwr_idx_comp *tic
+)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
+ u8 base_idx = 0, power_idx = 0;
+ s8 by_rate_diff = 0, limit = 0, tpt_offset = 0, extra_bias = 0;
+ u8 txNum = phy_GetCurrentTxNum_8188E(pAdapter, Rate);
+ bool bIn24G = false;
+
+ base_idx = PHY_GetTxPowerIndexBase(pAdapter, RFPath, Rate, BandWidth, Channel, &bIn24G);
+
+ by_rate_diff = PHY_GetTxPowerByRate(pAdapter, BAND_ON_2_4G, RFPath, txNum, Rate);
+ limit = PHY_GetTxPowerLimit(pAdapter, pAdapter->registrypriv.RegPwrTblSel, (u8)(!bIn24G), pHalData->current_channel_bw, RFPath, Rate, pHalData->current_channel);
+
+ tpt_offset = PHY_GetTxPowerTrackingOffset(pAdapter, RFPath, Rate);
+
+ if (pAdapter->registrypriv.mp_mode != 1)
+ extra_bias = tx_power_extra_bias(RFPath, Rate, BandWidth, Channel);
+
+ if (tic) {
+ tic->base = base_idx;
+ tic->by_rate = by_rate_diff;
+ tic->limit = limit;
+ tic->tpt = tpt_offset;
+ tic->ebias = extra_bias;
+ }
+
+ by_rate_diff = by_rate_diff > limit ? limit : by_rate_diff;
+ power_idx = base_idx + by_rate_diff + tpt_offset + extra_bias;
+
+ if (power_idx > MAX_POWER_INDEX)
+ power_idx = MAX_POWER_INDEX;
+
+ return power_idx;
+}
+
+/*
+ * Description:
+ * Update transmit power level of all channel supported.
+ *
+ * TODO:
+ * A mode.
+ * By Bruce, 2008-02-04.
+ * */
+bool
+PHY_UpdateTxPowerDbm8188E(
+ PADAPTER Adapter,
+ int powerInDbm
+)
+{
+ return true;
+}
+
+static void
+PHY_ScanOperationBackup8188E(
+ PADAPTER Adapter,
+ u8 Operation
+)
+{
+}
+
+static void
+phy_SpurCalibration_8188E(
+ PADAPTER Adapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct PHY_DM_STRUCT *p_dm_odm = &(pHalData->odmpriv);
+
+ if (pHalData->current_channel_bw == CHANNEL_WIDTH_20 && (pHalData->current_channel == 13 || pHalData->current_channel == 14)) {
+ phy_set_bb_reg(Adapter, rOFDM0_RxDSP, BIT(9), 0x1);/* enable notch filter */
+ phy_set_bb_reg(Adapter, rOFDM1_IntfDet, BIT(8) | BIT(7) | BIT(6), 0x2); /* intf_TH */
+ phy_set_bb_reg(Adapter, rOFDM0_RxDSP, BIT(28) | BIT(27) | BIT(26) | BIT(25) | BIT(24), 0x1f);
+ p_dm_odm->is_receiver_blocking_en = false;
+ } else if (pHalData->current_channel_bw == CHANNEL_WIDTH_40 && pHalData->current_channel == 11) {
+ phy_set_bb_reg(Adapter, rOFDM0_RxDSP, BIT(9), 0x1);/* enable notch filter */
+ phy_set_bb_reg(Adapter, rOFDM1_IntfDet, BIT(8) | BIT(7) | BIT(6), 0x2); /* intf_TH */
+ phy_set_bb_reg(Adapter, rOFDM0_RxDSP, BIT(28) | BIT(27) | BIT(26) | BIT(25) | BIT(24), 0x1f);
+ p_dm_odm->is_receiver_blocking_en = false;
+ } else {
+ if (Adapter->registrypriv.notch_filter == 0)
+ phy_set_bb_reg(Adapter, rOFDM0_RxDSP, BIT(9), 0x0);/* disable notch filter */
+ }
+}
+
+/*-----------------------------------------------------------------------------
+ * Function: PHY_SetBWModeCallback8192C()
+ *
+ * Overview: Timer callback function for SetSetBWMode
+ *
+ * Input: PRT_TIMER pTimer
+ *
+ * Output: NONE
+ *
+ * Return: NONE
+ *
+ * Note: (1) We do not take j mode into consideration now
+ * (2) Will two workitem of "switch channel" and "switch channel bandwidth" run
+ * concurrently?
+ *---------------------------------------------------------------------------*/
+static void
+_PHY_SetBWMode88E(
+ PADAPTER Adapter
+)
+{
+ /* PADAPTER Adapter = (PADAPTER)pTimer->Adapter; */
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 regBwOpMode;
+ u8 regRRSR_RSC;
+
+ /* return; */
+
+ /* Added it for 20/40 mhz switch time evaluation by guangan 070531 */
+ /* u32 NowL, NowH; */
+ /* u64 BeginTime, EndTime; */
+
+ if (pHalData->rf_chip == RF_PSEUDO_11N) {
+ /* pHalData->SetBWModeInProgress= false; */
+ return;
+ }
+
+ /* There is no 40MHz mode in RF_8225. */
+ if (pHalData->rf_chip == RF_8225)
+ return;
+
+ if (rtw_is_drv_stopped(Adapter))
+ return;
+
+ /* Added it for 20/40 mhz switch time evaluation by guangan 070531 */
+ /* NowL = PlatformEFIORead4Byte(Adapter, TSFR); */
+ /* NowH = PlatformEFIORead4Byte(Adapter, TSFR+4); */
+ /* BeginTime = ((u64)NowH << 32) + NowL; */
+
+ /* 3 */
+ /* 3 */ /* <1>Set MAC register */
+ /* 3 */
+ /* Adapter->hal_func.SetBWModeHandler(); */
+
+ regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE);
+ regRRSR_RSC = rtw_read8(Adapter, REG_RRSR + 2);
+ /* regBwOpMode = rtw_hal_get_hwreg(Adapter,HW_VAR_BWMODE,(u8 *)&regBwOpMode); */
+
+ switch (pHalData->current_channel_bw) {
+ case CHANNEL_WIDTH_20:
+ regBwOpMode |= BW_OPMODE_20MHZ;
+ /* 2007/02/07 Mark by Emily becasue we have not verify whether this register works */
+ rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode);
+ break;
+
+ case CHANNEL_WIDTH_40:
+ regBwOpMode &= ~BW_OPMODE_20MHZ;
+ /* 2007/02/07 Mark by Emily becasue we have not verify whether this register works */
+ rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode);
+
+ regRRSR_RSC = (regRRSR_RSC & 0x90) | (pHalData->nCur40MhzPrimeSC << 5);
+ rtw_write8(Adapter, REG_RRSR + 2, regRRSR_RSC);
+ break;
+
+ default:
+ break;
+ }
+
+ /* 3 */
+ /* 3 */ /* <2>Set PHY related register */
+ /* 3 */
+ switch (pHalData->current_channel_bw) {
+ /* 20 MHz channel*/
+ case CHANNEL_WIDTH_20:
+ phy_set_bb_reg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
+ phy_set_bb_reg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
+ /* phy_set_bb_reg(Adapter, rFPGA0_AnalogParameter2, BIT10, 1); */
+
+ break;
+
+
+ /* 40 MHz channel*/
+ case CHANNEL_WIDTH_40:
+ phy_set_bb_reg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
+ phy_set_bb_reg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
+
+ /* Set Control channel to upper or lower. These settings are required only for 40MHz */
+ phy_set_bb_reg(Adapter, rCCK0_System, bCCKSideBand, (pHalData->nCur40MhzPrimeSC >> 1));
+ phy_set_bb_reg(Adapter, rOFDM1_LSTF, 0xC00, pHalData->nCur40MhzPrimeSC);
+ /* phy_set_bb_reg(Adapter, rFPGA0_AnalogParameter2, BIT10, 0); */
+
+ phy_set_bb_reg(Adapter, 0x818, (BIT26 | BIT27), (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
+
+ break;
+
+
+
+ default:
+ break;
+
+ }
+ /* Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315 */
+
+ /* Added it for 20/40 mhz switch time evaluation by guangan 070531 */
+ /* NowL = PlatformEFIORead4Byte(Adapter, TSFR); */
+ /* NowH = PlatformEFIORead4Byte(Adapter, TSFR+4); */
+ /* EndTime = ((u64)NowH << 32) + NowL; */
+
+ /* 3<3>Set RF related register */
+ switch (pHalData->rf_chip) {
+ case RF_8225:
+ /* PHY_SetRF8225Bandwidth(Adapter, pHalData->current_channel_bw); */
+ break;
+
+ case RF_8256:
+ /* Please implement this function in Hal8190PciPhy8256.c */
+ /* PHY_SetRF8256Bandwidth(Adapter, pHalData->current_channel_bw); */
+ break;
+
+ case RF_8258:
+ /* Please implement this function in Hal8190PciPhy8258.c */
+ /* PHY_SetRF8258Bandwidth(); */
+ break;
+
+ case RF_PSEUDO_11N:
+ /* Do Nothing */
+ break;
+
+ case RF_6052:
+ rtl8188e_PHY_RF6052SetBandwidth(Adapter, pHalData->current_channel_bw);
+ break;
+
+ default:
+ /* RT_ASSERT(false, ("Unknown RFChipID: %d\n", pHalData->RFChipID)); */
+ break;
+ }
+
+ /* pHalData->SetBWModeInProgress= false; */
+
+}
+
+void
+PHY_SetBWMode8188E(
+ PADAPTER Adapter,
+ CHANNEL_WIDTH Bandwidth, /* 20M or 40M */
+ unsigned char Offset /* Upper, Lower, or Don't care */
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ CHANNEL_WIDTH tmpBW = pHalData->current_channel_bw;
+ /* Modified it for 20/40 mhz switch by guangan 070531 */
+ /* PMGNT_INFO pMgntInfo=&Adapter->MgntInfo; */
+
+ /* return; */
+
+ /* if(pHalData->SwChnlInProgress)
+ * if(pMgntInfo->bScanInProgress)
+ * {
+ * return;
+ * } */
+
+ /* if(pHalData->SetBWModeInProgress)
+ * {
+ * */ /* Modified it for 20/40 mhz switch by guangan 070531
+ * PlatformCancelTimer(Adapter, &pHalData->SetBWModeTimer);
+ * */ /* return;
+ * } */
+
+ /* if(pHalData->SetBWModeInProgress) */
+ /* return; */
+
+ /* pHalData->SetBWModeInProgress= true; */
+
+ pHalData->current_channel_bw = Bandwidth;
+
+ pHalData->nCur40MhzPrimeSC = Offset;
+
+ if (!RTW_CANNOT_RUN(Adapter)) {
+ _PHY_SetBWMode88E(Adapter);
+ if (IS_VENDOR_8188E_I_CUT_SERIES(Adapter))
+ phy_SpurCalibration_8188E(Adapter);
+ } else {
+ /* pHalData->SetBWModeInProgress= false; */
+ pHalData->current_channel_bw = tmpBW;
+ }
+
+}
+
+
+static void _PHY_SwChnl8188E(PADAPTER Adapter, u8 channel)
+{
+ u8 eRFPath;
+ u32 param1, param2;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ if (Adapter->bNotifyChannelChange)
+ RTW_INFO("[%s] ch = %d\n", __func__, channel);
+
+ /* s1. pre common command - CmdID_SetTxPowerLevel */
+ PHY_SetTxPowerLevel8188E(Adapter, channel);
+
+ /* s2. RF dependent command - CmdID_RF_WriteReg, param1=RF_CHNLBW, param2=channel */
+ param1 = RF_CHNLBW;
+ param2 = channel;
+ for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) {
+ pHalData->RfRegChnlVal[eRFPath] = ((pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | param2);
+ phy_set_rf_reg(Adapter, eRFPath, param1, bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]);
+ }
+
+
+ /* s3. post common command - CmdID_End, None */
+
+}
+void
+PHY_SwChnl8188E(/* Call after initialization */
+ PADAPTER Adapter,
+ u8 channel
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 tmpchannel = pHalData->current_channel;
+ bool bResult = true;
+
+ if (pHalData->rf_chip == RF_PSEUDO_11N)
+ return; /* return immediately if it is peudo-phy */
+
+ while (pHalData->odmpriv.rf_calibrate_info.is_lck_in_progress)
+ rtw_msleep_os(50);
+
+ /* -------------------------------------------- */
+ switch (pHalData->CurrentWirelessMode) {
+ case WIRELESS_MODE_A:
+ case WIRELESS_MODE_N_5G:
+ break;
+ case WIRELESS_MODE_B:
+ break;
+ case WIRELESS_MODE_G:
+ case WIRELESS_MODE_N_24G:
+ break;
+ default:
+ break;
+ }
+ /* -------------------------------------------- */
+
+ if (channel == 0)
+ channel = 1;
+
+ pHalData->current_channel = channel;
+
+ if (!RTW_CANNOT_RUN(Adapter)) {
+ _PHY_SwChnl8188E(Adapter, channel);
+
+ if (IS_VENDOR_8188E_I_CUT_SERIES(Adapter))
+ phy_SpurCalibration_8188E(Adapter);
+
+
+
+ if (!bResult)
+ pHalData->current_channel = tmpchannel;
+ } else {
+ pHalData->current_channel = tmpchannel;
+ }
+}
+
+void
+PHY_SetSwChnlBWMode8188E(
+ PADAPTER Adapter,
+ u8 channel,
+ CHANNEL_WIDTH Bandwidth,
+ u8 Offset40,
+ u8 Offset80
+)
+{
+ /* RTW_INFO("%s()===>\n",__func__); */
+
+ PHY_SwChnl8188E(Adapter, channel);
+ PHY_SetBWMode8188E(Adapter, Bandwidth, Offset40);
+
+ /* RTW_INFO("<==%s()\n",__func__); */
+}
+
+static void _PHY_SetRFPathSwitch(
+ PADAPTER pAdapter,
+ bool bMain,
+ bool is2T
+)
+{
+ u8 u1bTmp;
+
+ if (!rtw_is_hw_init_completed(pAdapter)) {
+ u1bTmp = rtw_read8(pAdapter, REG_LEDCFG2) | BIT7;
+ rtw_write8(pAdapter, REG_LEDCFG2, u1bTmp);
+ /* phy_set_bb_reg(pAdapter, REG_LEDCFG0, BIT23, 0x01); */
+ phy_set_bb_reg(pAdapter, rFPGA0_XAB_RFParameter, BIT13, 0x01);
+ }
+
+ if (is2T) {
+ if (bMain)
+ phy_set_bb_reg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT5 | BIT6, 0x1); /* 92C_Path_A */
+ else
+ phy_set_bb_reg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT5 | BIT6, 0x2); /* BT */
+ } else {
+
+ if (bMain)
+ phy_set_bb_reg(pAdapter, rFPGA0_XA_RFInterfaceOE, 0x300, 0x2); /* Main */
+ else
+ phy_set_bb_reg(pAdapter, rFPGA0_XA_RFInterfaceOE, 0x300, 0x1); /* Aux */
+ }
+
+}
+
+/* return value true => Main; false => Aux */
+
+static bool _PHY_QueryRFPathSwitch(
+ PADAPTER pAdapter,
+ bool is2T
+)
+{
+ /* if(is2T)
+ * return true; */
+
+ if (!rtw_is_hw_init_completed(pAdapter)) {
+ phy_set_bb_reg(pAdapter, REG_LEDCFG0, BIT23, 0x01);
+ phy_set_bb_reg(pAdapter, rFPGA0_XAB_RFParameter, BIT13, 0x01);
+ }
+
+ if (is2T) {
+ if (phy_query_bb_reg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT5 | BIT6) == 0x01)
+ return true;
+ else
+ return false;
+ } else {
+ if (phy_query_bb_reg(pAdapter, rFPGA0_XA_RFInterfaceOE, 0x300) == 0x02)
+ return true;
+ else
+ return false;
+ }
+}
+
+
+static void
+_PHY_DumpRFReg(PADAPTER pAdapter)
+{
+ u32 rfRegValue, rfRegOffset;
+
+ /* RTPRINT(FINIT, INIT_RF, ("PHY_DumpRFReg()====>\n")); */
+
+ for (rfRegOffset = 0x00; rfRegOffset <= 0x30; rfRegOffset++) {
+ rfRegValue = phy_query_rf_reg(pAdapter, RF_PATH_A, rfRegOffset, bMaskDWord);
+ /* RTPRINT(FINIT, INIT_RF, (" 0x%02x = 0x%08x\n",rfRegOffset,rfRegValue)); */
+ }
+ /* RTPRINT(FINIT, INIT_RF, ("<===== PHY_DumpRFReg()\n")); */
+}
+
+
+/*
+ * Move from phycfg.c to gen.c to be code independent later
+ *
+ * -------------------------Move to other DIR later---------------------------- */
+
+/*
+ * Description:
+ * To dump all Tx FIFO LLT related link-list table.
+ * Added by Roger, 2009.03.10.
+ * */
+static void DumpBBDbgPort_92CU(PADAPTER Adapter)
+{
+ phy_set_bb_reg(Adapter, 0x0908, 0xffff, 0x0000);
+
+ phy_set_bb_reg(Adapter, 0x0908, 0xffff, 0x0803);
+
+ phy_set_bb_reg(Adapter, 0x0908, 0xffff, 0x0a06);
+
+ phy_set_bb_reg(Adapter, 0x0908, 0xffff, 0x0007);
+
+ phy_set_bb_reg(Adapter, 0x0908, 0xffff, 0x0100);
+ phy_set_bb_reg(Adapter, 0x0a28, 0x00ff0000, 0x000f0000);
+
+ phy_set_bb_reg(Adapter, 0x0908, 0xffff, 0x0100);
+ phy_set_bb_reg(Adapter, 0x0a28, 0x00ff0000, 0x00150000);
+}
+
+void
+PHY_SetRFEReg_8188E(
+ PADAPTER Adapter
+)
+{
+ u8 u1tmp = 0;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ if ((pHalData->ExternalPA_2G == 0) && (pHalData->ExternalLNA_2G == 0))
+ return;
+
+ switch (pHalData->rfe_type) {
+ /* 88EU rfe_type should always be 0 */
+ case 0:
+ default:
+ phy_set_bb_reg(Adapter, 0x40, BIT2|BIT3, 0x3); /*0x3 << 2*/
+ phy_set_bb_reg(Adapter, 0xEE8, BIT28, 0x1);
+ phy_set_bb_reg(Adapter, 0x87C, BIT0, 0x0);
+ break;
+ }
+}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c b/drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c
new file mode 100644
index 000000000000..b69680087422
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+/******************************************************************************
+ *
+ *
+ * Module: rtl8188e_rf6052.c ( Source C File)
+ *
+ * Note: Provide RF 6052 series relative API.
+ *
+ * Function:
+ *
+ * Export:
+ *
+ * Abbrev:
+ *
+ * History:
+ * Data Who Remark
+ *
+ * 09/25/2008 MHC Create initial version.
+ * 11/05/2008 MHC Add API for tw power setting.
+ *
+ *
+******************************************************************************/
+
+#define _RTL8188E_RF6052_C_
+
+#include <drv_types.h>
+#include <rtl8188e_hal.h>
+
+/*---------------------------Define Local Constant---------------------------*/
+
+/*---------------------------Define Local Constant---------------------------*/
+
+
+/*------------------------Define global variable-----------------------------*/
+/*------------------------Define global variable-----------------------------*/
+
+
+/*------------------------Define local variable------------------------------*/
+
+/*------------------------Define local variable------------------------------*/
+
+
+/*-----------------------------------------------------------------------------
+ * Function: RF_ChangeTxPath
+ *
+ * Overview: For RL6052, we must change some RF settign for 1T or 2T.
+ *
+ * Input: u16 DataRate // 0x80-8f, 0x90-9f
+ *
+ * Output: NONE
+ *
+ * Return: NONE
+ *
+ * Revised History:
+ * When Who Remark
+ * 09/25/2008 MHC Create Version 0.
+ * Firmwaer support the utility later.
+ *
+ *---------------------------------------------------------------------------*/
+void rtl8188e_RF_ChangeTxPath(PADAPTER Adapter,
+ u16 DataRate)
+{
+ /* We do not support gain table change inACUT now !!!! Delete later !!! */
+} /* RF_ChangeTxPath */
+
+/*-----------------------------------------------------------------------------
+ * Function: PHY_RF6052SetBandwidth()
+ *
+ * Overview: This function is called by SetBWModeCallback8190Pci() only
+ *
+ * Input: PADAPTER Adapter
+ * WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M
+ *
+ * Output: NONE
+ *
+ * Return: NONE
+ *
+ * Note: For RF type 0222D
+ *---------------------------------------------------------------------------*/
+void
+rtl8188e_PHY_RF6052SetBandwidth(
+ PADAPTER Adapter,
+ CHANNEL_WIDTH Bandwidth) /* 20M or 40M */
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ switch (Bandwidth) {
+ case CHANNEL_WIDTH_20:
+ pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff) | BIT(10) | BIT(11));
+ phy_set_rf_reg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]);
+ break;
+
+ case CHANNEL_WIDTH_40:
+ pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff) | BIT(10));
+ phy_set_rf_reg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]);
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+static int
+phy_RF6052_Config_ParaFile(
+ PADAPTER Adapter
+)
+{
+ u32 u4RegValue = 0;
+ u8 eRFPath;
+ BB_REGISTER_DEFINITION_T *pPhyReg;
+
+ int rtStatus = _SUCCESS;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ /* 3 */ /* ----------------------------------------------------------------- */
+ /* 3 */ /* <2> Initialize RF */
+ /* 3 */ /* ----------------------------------------------------------------- */
+ /* for(eRFPath = RF_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++) */
+ for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) {
+
+ pPhyReg = &pHalData->PHYRegDef[eRFPath];
+
+ /*----Store original RFENV control type----*/
+ switch (eRFPath) {
+ case RF_PATH_A:
+ case RF_PATH_C:
+ u4RegValue = phy_query_bb_reg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV);
+ break;
+ case RF_PATH_B:
+ case RF_PATH_D:
+ u4RegValue = phy_query_bb_reg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV << 16);
+ break;
+ }
+
+ /*----Set RF_ENV enable----*/
+ phy_set_bb_reg(Adapter, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1);
+ rtw_udelay_os(1);/* PlatformStallExecution(1); */
+
+ /*----Set RF_ENV output high----*/
+ phy_set_bb_reg(Adapter, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
+ rtw_udelay_os(1);/* PlatformStallExecution(1); */
+
+ /* Set bit number of Address and Data for RF register */
+ phy_set_bb_reg(Adapter, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); /* Set 1 to 4 bits for 8255 */
+ rtw_udelay_os(1);/* PlatformStallExecution(1); */
+
+ phy_set_bb_reg(Adapter, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); /* Set 0 to 12 bits for 8255 */
+ rtw_udelay_os(1);/* PlatformStallExecution(1); */
+
+ /*----Initialize RF fom connfiguration file----*/
+ switch (eRFPath) {
+ case RF_PATH_A:
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+ if (PHY_ConfigRFWithParaFile(Adapter, PHY_FILE_RADIO_A, eRFPath) == _FAIL)
+#endif
+ {
+#ifdef CONFIG_EMBEDDED_FWIMG
+ if (HAL_STATUS_FAILURE == odm_config_rf_with_header_file(&pHalData->odmpriv, CONFIG_RF_RADIO, (enum odm_rf_radio_path_e)eRFPath))
+ rtStatus = _FAIL;
+#endif
+ }
+ break;
+ case RF_PATH_B:
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+ if (PHY_ConfigRFWithParaFile(Adapter, PHY_FILE_RADIO_B, eRFPath) == _FAIL)
+#endif
+ {
+#ifdef CONFIG_EMBEDDED_FWIMG
+ if (HAL_STATUS_FAILURE == odm_config_rf_with_header_file(&pHalData->odmpriv, CONFIG_RF_RADIO, (enum odm_rf_radio_path_e)eRFPath))
+ rtStatus = _FAIL;
+#endif
+ }
+ break;
+ case RF_PATH_C:
+ break;
+ case RF_PATH_D:
+ break;
+ }
+
+ /*----Restore RFENV control type----*/;
+ switch (eRFPath) {
+ case RF_PATH_A:
+ case RF_PATH_C:
+ phy_set_bb_reg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
+ break;
+ case RF_PATH_B:
+ case RF_PATH_D:
+ phy_set_bb_reg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV << 16, u4RegValue);
+ break;
+ }
+
+ if (rtStatus != _SUCCESS) {
+ goto phy_RF6052_Config_ParaFile_Fail;
+ }
+
+ }
+
+
+ /* 3 ----------------------------------------------------------------- */
+ /* 3 Configuration of Tx Power Tracking */
+ /* 3 ----------------------------------------------------------------- */
+
+#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
+ if (PHY_ConfigRFWithTxPwrTrackParaFile(Adapter, PHY_FILE_TXPWR_TRACK) == _FAIL)
+#endif
+ {
+#ifdef CONFIG_EMBEDDED_FWIMG
+ odm_config_rf_with_tx_pwr_track_header_file(&pHalData->odmpriv);
+#endif
+ }
+
+ return rtStatus;
+
+phy_RF6052_Config_ParaFile_Fail:
+ return rtStatus;
+}
+
+
+int
+PHY_RF6052_Config8188E(
+ PADAPTER Adapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ int rtStatus = _SUCCESS;
+
+ /* */
+ /* Initialize general global value */
+ /* */
+ /* TODO: Extend RF_PATH_C and RF_PATH_D in the future */
+ if (pHalData->rf_type == RF_1T1R)
+ pHalData->NumTotalRFPath = 1;
+ else
+ pHalData->NumTotalRFPath = 2;
+
+ /* */
+ /* Config BB and RF */
+ /* */
+ rtStatus = phy_RF6052_Config_ParaFile(Adapter);
+ return rtStatus;
+}
+
+/* End of HalRf6052.c */
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c
new file mode 100644
index 000000000000..e6b0f77bcdc2
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _RTL8188E_REDESC_C_
+
+#include <drv_types.h>
+#include <rtl8188e_hal.h>
+
+void rtl8188e_query_rx_desc_status(
+ union recv_frame *precvframe,
+ struct recv_stat *prxstat)
+{
+ struct rx_pkt_attrib *pattrib;
+ struct recv_stat report;
+ PRXREPORT prxreport;
+ /* struct recv_frame_hdr *phdr; */
+
+ /* phdr = &precvframe->u.hdr; */
+
+ report.rxdw0 = prxstat->rxdw0;
+ report.rxdw1 = prxstat->rxdw1;
+ report.rxdw2 = prxstat->rxdw2;
+ report.rxdw3 = prxstat->rxdw3;
+ report.rxdw4 = prxstat->rxdw4;
+ report.rxdw5 = prxstat->rxdw5;
+
+ prxreport = (PRXREPORT)&report;
+
+ pattrib = &precvframe->u.hdr.attrib;
+ memset(pattrib, 0, sizeof(struct rx_pkt_attrib));
+
+ pattrib->crc_err = (u8)((le32_to_cpu(report.rxdw0) >> 14) & 0x1);;/* (u8)prxreport->crc32; */
+
+ /* update rx report to recv_frame attribute */
+ pattrib->pkt_rpt_type = (u8)((le32_to_cpu(report.rxdw3) >> 14) & 0x3);/* prxreport->rpt_sel; */
+
+ if (pattrib->pkt_rpt_type == NORMAL_RX) { /* Normal rx packet */
+ pattrib->pkt_len = cpu_to_le16(le32_to_cpu(report.rxdw0) & 0x00003fff); /* (u16)prxreport->pktlen; */
+ pattrib->drvinfo_sz = (u8)((le32_to_cpu(report.rxdw0) >> 16) & 0xf) * 8;/* (u8)(prxreport->drvinfosize << 3); */
+
+ pattrib->physt = (u8)((le32_to_cpu(report.rxdw0) >> 26) & 0x1); /* (u8)prxreport->physt; */
+
+ pattrib->bdecrypted = (le32_to_cpu(report.rxdw0) & BIT(27)) ? 0 : 1; /* (u8)(prxreport->swdec ? 0 : 1); */
+ pattrib->encrypt = (u8)((le32_to_cpu(report.rxdw0) >> 20) & 0x7);/* (u8)prxreport->security; */
+
+ pattrib->qos = (u8)((le32_to_cpu(report.rxdw0) >> 23) & 0x1);/* (u8)prxreport->qos; */
+ pattrib->priority = (u8)((le32_to_cpu(report.rxdw1) >> 8) & 0xf);/* (u8)prxreport->tid; */
+
+ pattrib->amsdu = (u8)((le32_to_cpu(report.rxdw1) >> 13) & 0x1);/* (u8)prxreport->amsdu; */
+
+ pattrib->seq_num = cpu_to_le16(le32_to_cpu(report.rxdw2) & 0x00000fff);/* (u16)prxreport->seq; */
+ pattrib->frag_num = (u8)((le32_to_cpu(report.rxdw2) >> 12) & 0xf);/* (u8)prxreport->frag; */
+ pattrib->mfrag = (u8)((le32_to_cpu(report.rxdw1) >> 27) & 0x1);/* (u8)prxreport->mf; */
+ pattrib->mdata = (u8)((le32_to_cpu(report.rxdw1) >> 26) & 0x1);/* (u8)prxreport->md; */
+
+ pattrib->data_rate = (u8)(le32_to_cpu(report.rxdw3) & 0x3f);/* (u8)prxreport->rxmcs; */
+
+ pattrib->icv_err = (u8)((le32_to_cpu(report.rxdw0) >> 15) & 0x1);/* (u8)prxreport->icverr; */
+ pattrib->shift_sz = (u8)((le32_to_cpu(report.rxdw0) >> 24) & 0x3);
+ } else if (pattrib->pkt_rpt_type == TX_REPORT1) { /* CCX */
+ pattrib->pkt_len = cpu_to_le16(TX_RPT1_PKT_LEN);
+ pattrib->drvinfo_sz = 0;
+ } else if (pattrib->pkt_rpt_type == TX_REPORT2) { /* TX RPT */
+ pattrib->pkt_len = cpu_to_le16(le32_to_cpu(report.rxdw0) & 0x3FF); /* Rx length[9:0] */
+ pattrib->drvinfo_sz = 0;
+
+ /* */
+ /* Get TX report MAC ID valid. */
+ /* */
+ pattrib->MacIDValidEntry[0] = report.rxdw4;
+ pattrib->MacIDValidEntry[1] = report.rxdw5;
+ } else if (pattrib->pkt_rpt_type == HIS_REPORT) { /* USB HISR RPT */
+ pattrib->pkt_len = cpu_to_le16(le32_to_cpu(report.rxdw0) & 0x00003fff); /* (u16)prxreport->pktlen; */
+ }
+
+}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_sreset.c b/drivers/staging/rtl8188eu/hal/rtl8188e_sreset.c
new file mode 100644
index 000000000000..8879174915ae
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_sreset.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _RTL8188E_SRESET_C_
+
+/* #include <rtl8188e_sreset.h> */
+#include <rtl8188e_hal.h>
+
+#ifdef DBG_CONFIG_ERROR_DETECT
+
+void rtl8188e_sreset_xmit_status_check(_adapter *padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct sreset_priv *psrtpriv = &pHalData->srestpriv;
+
+ unsigned long current_time;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ unsigned int diff_time;
+ u32 txdma_status;
+
+ txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS);
+ if (txdma_status != 0x00 && txdma_status != 0xeaeaeaea) {
+ RTW_INFO("%s REG_TXDMA_STATUS:0x%08x\n", __func__, txdma_status);
+ rtw_hal_sreset_reset(padapter);
+ }
+ current_time = jiffies;
+
+ if (0 == pxmitpriv->free_xmitbuf_cnt || 0 == pxmitpriv->free_xmit_extbuf_cnt) {
+
+ diff_time = rtw_get_passing_time_ms(psrtpriv->last_tx_time);
+
+ if (diff_time > 2000) {
+ if (psrtpriv->last_tx_complete_time == 0)
+ psrtpriv->last_tx_complete_time = current_time;
+ else {
+ diff_time = rtw_get_passing_time_ms(psrtpriv->last_tx_complete_time);
+ if (diff_time > 4000) {
+ u32 ability = 0;
+
+ /* padapter->Wifi_Error_Status = WIFI_TX_HANG; */
+ ability = rtw_phydm_ability_get(padapter);
+ RTW_INFO("%s tx hang %s\n", __func__,
+ (ability & ODM_BB_ADAPTIVITY) ? "ODM_BB_ADAPTIVITY" : "");
+
+ if (!(ability & ODM_BB_ADAPTIVITY))
+ rtw_hal_sreset_reset(padapter);
+ }
+ }
+ }
+ }
+
+ if (psrtpriv->dbg_trigger_point == SRESET_TGP_XMIT_STATUS) {
+ psrtpriv->dbg_trigger_point = SRESET_TGP_NULL;
+ rtw_hal_sreset_reset(padapter);
+ return;
+ }
+}
+
+void rtl8188e_sreset_linked_status_check(_adapter *padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct sreset_priv *psrtpriv = &pHalData->srestpriv;
+
+ u32 rx_dma_status = 0;
+ u8 fw_status = 0;
+ rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS);
+ if (rx_dma_status != 0x00) {
+ RTW_INFO("%s REG_RXDMA_STATUS:0x%08x\n", __func__, rx_dma_status);
+ rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status);
+ }
+ fw_status = rtw_read8(padapter, REG_FMETHR);
+ if (fw_status != 0x00) {
+ if (fw_status == 1)
+ RTW_INFO("%s REG_FW_STATUS (0x%02x), Read_Efuse_Fail !!\n", __func__, fw_status);
+ else if (fw_status == 2)
+ RTW_INFO("%s REG_FW_STATUS (0x%02x), Condition_No_Match !!\n", __func__, fw_status);
+ }
+ if (psrtpriv->dbg_trigger_point == SRESET_TGP_LINK_STATUS) {
+ psrtpriv->dbg_trigger_point = SRESET_TGP_NULL;
+ rtw_hal_sreset_reset(padapter);
+ return;
+ }
+}
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c
new file mode 100644
index 000000000000..cad2ac0ce2ee
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _RTL8188E_XMIT_C_
+
+#include <drv_types.h>
+#include <rtl8188e_hal.h>
+
+#ifdef CONFIG_XMIT_ACK
+void dump_txrpt_ccx_88e(void *buf)
+{
+ struct txrpt_ccx_88e *txrpt_ccx = (struct txrpt_ccx_88e *)buf;
+
+ RTW_INFO("%s:\n"
+ "tag1:%u, pkt_num:%u, txdma_underflow:%u, int_bt:%u, int_tri:%u, int_ccx:%u\n"
+ "mac_id:%u, pkt_ok:%u, bmc:%u\n"
+ "retry_cnt:%u, lifetime_over:%u, retry_over:%u\n"
+ "ccx_qtime:%u\n"
+ "final_data_rate:0x%02x\n"
+ "qsel:%u, sw:0x%03x\n"
+ , __func__
+ , txrpt_ccx->tag1, txrpt_ccx->pkt_num, txrpt_ccx->txdma_underflow, txrpt_ccx->int_bt, txrpt_ccx->int_tri, txrpt_ccx->int_ccx
+ , txrpt_ccx->mac_id, txrpt_ccx->pkt_ok, txrpt_ccx->bmc
+ , txrpt_ccx->retry_cnt, txrpt_ccx->lifetime_over, txrpt_ccx->retry_over
+ , txrpt_ccx_qtime_88e(txrpt_ccx)
+ , txrpt_ccx->final_data_rate
+ , txrpt_ccx->qsel, txrpt_ccx_sw_88e(txrpt_ccx)
+ );
+}
+
+void handle_txrpt_ccx_88e(_adapter *adapter, u8 *buf)
+{
+ struct txrpt_ccx_88e *txrpt_ccx = (struct txrpt_ccx_88e *)buf;
+
+#ifdef DBG_CCX
+ dump_txrpt_ccx_88e(buf);
+#endif
+
+ if (txrpt_ccx->int_ccx) {
+ if (txrpt_ccx->pkt_ok)
+ rtw_ack_tx_done(&adapter->xmitpriv, RTW_SCTX_DONE_SUCCESS);
+ else
+ rtw_ack_tx_done(&adapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
+ }
+}
+#endif /* CONFIG_XMIT_ACK */
+
+void _dbg_dump_tx_info(_adapter *padapter, int frame_tag, struct tx_desc *ptxdesc)
+{
+ u8 bDumpTxPkt;
+ u8 bDumpTxDesc = false;
+ rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(bDumpTxPkt));
+
+ if (bDumpTxPkt == 1) { /* dump txdesc for data frame */
+ RTW_INFO("dump tx_desc for data frame\n");
+ if ((frame_tag & 0x0f) == DATA_FRAMETAG)
+ bDumpTxDesc = true;
+ } else if (bDumpTxPkt == 2) { /* dump txdesc for mgnt frame */
+ RTW_INFO("dump tx_desc for mgnt frame\n");
+ if ((frame_tag & 0x0f) == MGNT_FRAMETAG)
+ bDumpTxDesc = true;
+ } else if (bDumpTxPkt == 3) { /* dump early info */
+ }
+
+ if (bDumpTxDesc) {
+ /* ptxdesc->txdw4 = cpu_to_le32(0x00001006); */ /* RTS Rate=24M */
+ /* ptxdesc->txdw6 = 0x6666f800; */
+ RTW_INFO("=====================================\n");
+ RTW_INFO("txdw0(0x%08x)\n", ptxdesc->txdw0);
+ RTW_INFO("txdw1(0x%08x)\n", ptxdesc->txdw1);
+ RTW_INFO("txdw2(0x%08x)\n", ptxdesc->txdw2);
+ RTW_INFO("txdw3(0x%08x)\n", ptxdesc->txdw3);
+ RTW_INFO("txdw4(0x%08x)\n", ptxdesc->txdw4);
+ RTW_INFO("txdw5(0x%08x)\n", ptxdesc->txdw5);
+ RTW_INFO("txdw6(0x%08x)\n", ptxdesc->txdw6);
+ RTW_INFO("txdw7(0x%08x)\n", ptxdesc->txdw7);
+ RTW_INFO("=====================================\n");
+ }
+
+}
+
+/*
+ * Description:
+ * Aggregation packets and send to hardware
+ *
+ * Return:
+ * 0 Success
+ * -1 Hardware resource(TX FIFO) not ready
+ * -2 Software resource(xmitbuf) not ready
+ */
+#ifdef CONFIG_TX_EARLY_MODE
+
+/* #define DBG_EMINFO */
+
+#if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1
+ #define EARLY_MODE_MAX_PKT_NUM 10
+#else
+ #define EARLY_MODE_MAX_PKT_NUM 5
+#endif
+
+
+struct EMInfo {
+ u8 EMPktNum;
+ u16 EMPktLen[EARLY_MODE_MAX_PKT_NUM];
+};
+
+
+void
+InsertEMContent_8188E(
+ struct EMInfo *pEMInfo,
+ IN u8 * VirtualAddress)
+{
+
+#if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1
+ u8 index = 0;
+ u32 dwtmp = 0;
+#endif
+
+ memset(VirtualAddress, 0, EARLY_MODE_INFO_SIZE);
+ if (pEMInfo->EMPktNum == 0)
+ return;
+
+#ifdef DBG_EMINFO
+ {
+ int i;
+ RTW_INFO("\n%s ==> pEMInfo->EMPktNum =%d\n", __func__, pEMInfo->EMPktNum);
+ for (i = 0; i < EARLY_MODE_MAX_PKT_NUM; i++)
+ RTW_INFO("%s ==> pEMInfo->EMPktLen[%d] =%d\n", __func__, i, pEMInfo->EMPktLen[i]);
+
+ }
+#endif
+
+#if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1
+ SET_EARLYMODE_PKTNUM(VirtualAddress, pEMInfo->EMPktNum);
+
+ if (pEMInfo->EMPktNum == 1)
+ dwtmp = pEMInfo->EMPktLen[0];
+ else {
+ dwtmp = pEMInfo->EMPktLen[0];
+ dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
+ dwtmp += pEMInfo->EMPktLen[1];
+ }
+ SET_EARLYMODE_LEN0(VirtualAddress, dwtmp);
+ if (pEMInfo->EMPktNum <= 3)
+ dwtmp = pEMInfo->EMPktLen[2];
+ else {
+ dwtmp = pEMInfo->EMPktLen[2];
+ dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
+ dwtmp += pEMInfo->EMPktLen[3];
+ }
+ SET_EARLYMODE_LEN1(VirtualAddress, dwtmp);
+ if (pEMInfo->EMPktNum <= 5)
+ dwtmp = pEMInfo->EMPktLen[4];
+ else {
+ dwtmp = pEMInfo->EMPktLen[4];
+ dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
+ dwtmp += pEMInfo->EMPktLen[5];
+ }
+ SET_EARLYMODE_LEN2_1(VirtualAddress, dwtmp & 0xF);
+ SET_EARLYMODE_LEN2_2(VirtualAddress, dwtmp >> 4);
+ if (pEMInfo->EMPktNum <= 7)
+ dwtmp = pEMInfo->EMPktLen[6];
+ else {
+ dwtmp = pEMInfo->EMPktLen[6];
+ dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
+ dwtmp += pEMInfo->EMPktLen[7];
+ }
+ SET_EARLYMODE_LEN3(VirtualAddress, dwtmp);
+ if (pEMInfo->EMPktNum <= 9)
+ dwtmp = pEMInfo->EMPktLen[8];
+ else {
+ dwtmp = pEMInfo->EMPktLen[8];
+ dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
+ dwtmp += pEMInfo->EMPktLen[9];
+ }
+ SET_EARLYMODE_LEN4(VirtualAddress, dwtmp);
+#else
+ SET_EARLYMODE_PKTNUM(VirtualAddress, pEMInfo->EMPktNum);
+ SET_EARLYMODE_LEN0(VirtualAddress, pEMInfo->EMPktLen[0]);
+ SET_EARLYMODE_LEN1(VirtualAddress, pEMInfo->EMPktLen[1]);
+ SET_EARLYMODE_LEN2_1(VirtualAddress, pEMInfo->EMPktLen[2] & 0xF);
+ SET_EARLYMODE_LEN2_2(VirtualAddress, pEMInfo->EMPktLen[2] >> 4);
+ SET_EARLYMODE_LEN3(VirtualAddress, pEMInfo->EMPktLen[3]);
+ SET_EARLYMODE_LEN4(VirtualAddress, pEMInfo->EMPktLen[4]);
+#endif
+
+}
+
+
+
+void UpdateEarlyModeInfo8188E(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
+{
+ /* _adapter *padapter, struct xmit_frame *pxmitframe,struct tx_servq *ptxservq */
+ int index, j;
+ u16 offset, pktlen;
+ PTXDESC_8188E ptxdesc;
+
+ u8 *pmem, *pEMInfo_mem;
+ s8 node_num_0 = 0, node_num_1 = 0;
+ struct EMInfo eminfo;
+ struct agg_pkt_info *paggpkt;
+ struct xmit_frame *pframe = (struct xmit_frame *)pxmitbuf->priv_data;
+ pmem = pframe->buf_addr;
+
+#ifdef DBG_EMINFO
+ RTW_INFO("\n%s ==> agg_num:%d\n", __func__, pframe->agg_num);
+ for (index = 0; index < pframe->agg_num; index++) {
+ offset = pxmitpriv->agg_pkt[index].offset;
+ pktlen = pxmitpriv->agg_pkt[index].pkt_len;
+ RTW_INFO("%s ==> agg_pkt[%d].offset=%d\n", __func__, index, offset);
+ RTW_INFO("%s ==> agg_pkt[%d].pkt_len=%d\n", __func__, index, pktlen);
+ }
+#endif
+
+ if (pframe->agg_num > EARLY_MODE_MAX_PKT_NUM) {
+ node_num_0 = pframe->agg_num;
+ node_num_1 = EARLY_MODE_MAX_PKT_NUM - 1;
+ }
+
+ for (index = 0; index < pframe->agg_num; index++) {
+
+ offset = pxmitpriv->agg_pkt[index].offset;
+ pktlen = pxmitpriv->agg_pkt[index].pkt_len;
+
+ memset(&eminfo, 0, sizeof(struct EMInfo));
+ if (pframe->agg_num > EARLY_MODE_MAX_PKT_NUM) {
+ if (node_num_0 > EARLY_MODE_MAX_PKT_NUM) {
+ eminfo.EMPktNum = EARLY_MODE_MAX_PKT_NUM;
+ node_num_0--;
+ } else {
+ eminfo.EMPktNum = node_num_1;
+ node_num_1--;
+ }
+ } else
+ eminfo.EMPktNum = pframe->agg_num - (index + 1);
+ for (j = 0; j < eminfo.EMPktNum ; j++) {
+ eminfo.EMPktLen[j] = pxmitpriv->agg_pkt[index + 1 + j].pkt_len + 4; /* 4 bytes CRC */
+ }
+
+ if (pmem) {
+ if (index == 0) {
+ ptxdesc = (PTXDESC_8188E)(pmem);
+ pEMInfo_mem = ((u8 *)ptxdesc) + TXDESC_SIZE;
+ } else {
+ pmem = pmem + pxmitpriv->agg_pkt[index - 1].offset;
+ ptxdesc = (PTXDESC_8188E)(pmem);
+ pEMInfo_mem = ((u8 *)ptxdesc) + TXDESC_SIZE;
+ }
+
+#ifdef DBG_EMINFO
+ RTW_INFO("%s ==> desc.pkt_len=%d\n", __func__, ptxdesc->pktlen);
+#endif
+ InsertEMContent_8188E(&eminfo, pEMInfo_mem);
+ }
+
+
+ }
+ memset(pxmitpriv->agg_pkt, 0, sizeof(struct agg_pkt_info) * MAX_AGG_PKT_NUM);
+
+}
+#endif
+
+#if defined(CONFIG_CONCURRENT_MODE)
+void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc)
+{
+ if ((pattrib->encrypt > 0) && (!pattrib->bswenc)
+ && (pattrib->bmc_camid != INVALID_SEC_MAC_CAM_ID)) {
+
+ ptxdesc->txdw1 |= cpu_to_le32((0x01 << 21) & 0x00200000);
+ ptxdesc->txdw1 |= cpu_to_le32((pattrib->bmc_camid) & 0x1f);
+ }
+}
+#endif
+
+void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc)
+{
+ __le16 *usPtr = (__le16 *)ptxdesc;
+ u32 count = 16; /* (32 bytes / 2 bytes per XOR) => 16 times */
+ u32 index;
+ u16 checksum = 0;
+
+
+ /* Clear first */
+ ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
+
+ for (index = 0; index < count; index++)
+ checksum ^= le16_to_cpu(*(usPtr + index));
+
+ ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
+}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c
new file mode 100644
index 000000000000..d787787c4e50
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+
+#include <drv_types.h>
+#include <rtl8188e_hal.h>
+
+/* ********************************************************************************
+ * LED object.
+ * ******************************************************************************** */
+
+
+/* ********************************************************************************
+ * Prototype of protected function.
+ * ******************************************************************************** */
+
+
+/* ********************************************************************************
+ * LED_819xUsb routines.
+ * ******************************************************************************** */
+
+/*
+ * Description:
+ * Turn on LED according to LedPin specified.
+ * */
+static void
+SwLedOn_8188EU(
+ _adapter *padapter,
+ PLED_USB pLed
+)
+{
+ u8 LedCfg;
+ /* HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); */
+
+ if (RTW_CANNOT_RUN(padapter))
+ return;
+
+ LedCfg = rtw_read8(padapter, REG_LEDCFG2);
+ switch (pLed->LedPin) {
+ case LED_PIN_LED0:
+ rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0xf0) | BIT5 | BIT6); /* SW control led0 on. */
+ break;
+
+ case LED_PIN_LED1:
+ rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0x0f) | BIT5); /* SW control led1 on. */
+ break;
+
+ default:
+ break;
+ }
+
+ pLed->bLedOn = true;
+}
+
+
+/*
+ * Description:
+ * Turn off LED according to LedPin specified.
+ * */
+static void
+SwLedOff_8188EU(
+ _adapter *padapter,
+ PLED_USB pLed
+)
+{
+ u8 LedCfg;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ if (RTW_CANNOT_RUN(padapter))
+ goto exit;
+
+
+ LedCfg = rtw_read8(padapter, REG_LEDCFG2);/* 0x4E */
+
+ switch (pLed->LedPin) {
+ case LED_PIN_LED0:
+ if (pHalData->bLedOpenDrain == true) { /* Open-drain arrangement for controlling the LED) */
+ LedCfg &= 0x90; /* Set to software control. */
+ rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT3));
+ LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG);
+ LedCfg &= 0xFE;
+ rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg);
+ } else
+ rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT3 | BIT5 | BIT6));
+ break;
+
+ case LED_PIN_LED1:
+ LedCfg &= 0x0f; /* Set to software control. */
+ rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT3));
+ break;
+
+ default:
+ break;
+ }
+exit:
+ pLed->bLedOn = false;
+
+}
+
+/* ********************************************************************************
+ * Interface to manipulate LED objects.
+ * ******************************************************************************** */
+
+
+/* ********************************************************************************
+ * Default LED behavior.
+ * ******************************************************************************** */
+
+/*
+ * Description:
+ * Initialize all LED_871x objects.
+ * */
+void
+rtl8188eu_InitSwLeds(
+ _adapter *padapter
+)
+{
+ struct led_priv *pledpriv = &(padapter->ledpriv);
+
+ pledpriv->LedControlHandler = LedControlUSB;
+
+ pledpriv->SwLedOn = SwLedOn_8188EU;
+ pledpriv->SwLedOff = SwLedOff_8188EU;
+
+ InitLed(padapter, &(pledpriv->SwLed0), LED_PIN_LED0);
+
+ InitLed(padapter, &(pledpriv->SwLed1), LED_PIN_LED1);
+}
+
+
+/*
+ * Description:
+ * DeInitialize all LED_819xUsb objects.
+ * */
+void
+rtl8188eu_DeInitSwLeds(
+ _adapter *padapter
+)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+
+ DeInitLed(&(ledpriv->SwLed0));
+ DeInitLed(&(ledpriv->SwLed1));
+}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c
new file mode 100644
index 000000000000..6c2e04222d88
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _RTL8188EU_RECV_C_
+
+#include <drv_types.h>
+#include <rtl8188e_hal.h>
+
+int rtl8188eu_init_recv_priv(_adapter *padapter)
+{
+ return usb_init_recv_priv(padapter, INTERRUPT_MSG_FORMAT_LEN);
+}
+
+void rtl8188eu_free_recv_priv(_adapter *padapter)
+{
+ usb_free_recv_priv(padapter, INTERRUPT_MSG_FORMAT_LEN);
+}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
new file mode 100644
index 000000000000..ed9a5fa6e76c
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
@@ -0,0 +1,1261 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _RTL8188E_XMIT_C_
+
+#include <drv_types.h>
+#include <rtl8188e_hal.h>
+
+
+s32 rtl8188eu_init_xmit_priv(_adapter *padapter)
+{
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ tasklet_init(&pxmitpriv->xmit_tasklet,
+ (void(*)(unsigned long))rtl8188eu_xmit_tasklet,
+ (unsigned long)padapter);
+#ifdef CONFIG_TX_EARLY_MODE
+ pHalData->bEarlyModeEnable = padapter->registrypriv.early_mode;
+#endif
+
+ return _SUCCESS;
+}
+
+void rtl8188eu_free_xmit_priv(_adapter *padapter)
+{
+}
+
+static u8 urb_zero_packet_chk(_adapter *padapter, int sz)
+{
+ u8 blnSetTxDescOffset;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ blnSetTxDescOffset = (((sz + TXDESC_SIZE) % pHalData->UsbBulkOutSize) == 0) ? 1 : 0;
+
+ return blnSetTxDescOffset;
+}
+
+static void rtl8188eu_cal_txdesc_chksum(struct tx_desc *ptxdesc)
+{
+ __le16 *usPtr = (__le16 *)ptxdesc;
+ u32 count = 16; /* (32 bytes / 2 bytes per XOR) => 16 times */
+ u32 index;
+ u16 checksum = 0;
+
+ /* Clear first */
+ ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
+
+ for (index = 0 ; index < count ; index++)
+ checksum = checksum ^ le16_to_cpu(*(usPtr + index));
+
+ ptxdesc->txdw7 |= cpu_to_le32(0x0000ffff & checksum);
+
+}
+/*
+ * Description: In normal chip, we should send some packet to Hw which will be used by Fw
+ * in FW LPS mode. The function is to fill the Tx descriptor of this packets, then
+ * Fw can tell Hw to send these packet derectly.
+ * */
+void rtl8188e_fill_fake_txdesc(
+ PADAPTER padapter,
+ u8 *pDesc,
+ u32 BufferLen,
+ u8 IsPsPoll,
+ u8 IsBTQosNull,
+ u8 bDataFrame)
+{
+ struct tx_desc *ptxdesc;
+
+
+ /* Clear all status */
+ ptxdesc = (struct tx_desc *)pDesc;
+ memset(pDesc, 0, TXDESC_SIZE);
+
+ /* offset 0 */
+ ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); /* own, bFirstSeg, bLastSeg; */
+
+ ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000); /* 32 bytes for TX Desc */
+
+ ptxdesc->txdw0 |= cpu_to_le32(BufferLen & 0x0000ffff); /* Buffer size + command header */
+
+ /* offset 4 */
+ ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT << QSEL_SHT) & 0x00001f00); /* Fixed queue of Mgnt queue */
+
+ /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw. */
+ if (IsPsPoll)
+ ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR);
+ else {
+ ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); /* Hw set sequence number */
+ ptxdesc->txdw3 |= cpu_to_le32((8 << 28)); /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */
+ }
+
+ if (IsBTQosNull) {
+ ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); /* BT NULL */
+ }
+
+ /* offset 16 */
+ ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */
+
+ /* */
+ /* Encrypt the data frame if under security mode excepct null data. Suggested by CCW. */
+ /* */
+ if (bDataFrame) {
+ u32 EncAlg;
+
+ EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm;
+ switch (EncAlg) {
+ case _NO_PRIVACY_:
+ SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x0);
+ break;
+ case _WEP40_:
+ case _WEP104_:
+ case _TKIP_:
+ SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x1);
+ break;
+ case _SMS4_:
+ SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x2);
+ break;
+ case _AES_:
+ SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x3);
+ break;
+ default:
+ SET_TX_DESC_SEC_TYPE_8188E(pDesc, 0x0);
+ break;
+ }
+ }
+ /* USB interface drop packet if the checksum of descriptor isn't correct. */
+ /* Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.). */
+ rtl8188eu_cal_txdesc_chksum(ptxdesc);
+}
+
+static void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc)
+{
+ if ((pattrib->encrypt > 0) && !pattrib->bswenc) {
+ switch (pattrib->encrypt) {
+ /* SEC_TYPE : 0:NO_ENC,1:WEP40/TKIP,2:WAPI,3:AES */
+ case _WEP40_:
+ case _WEP104_:
+ ptxdesc->txdw1 |= cpu_to_le32((0x01 << SEC_TYPE_SHT) & 0x00c00000);
+ ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT);
+ break;
+ case _TKIP_:
+ case _TKIP_WTMIC_:
+ ptxdesc->txdw1 |= cpu_to_le32((0x01 << SEC_TYPE_SHT) & 0x00c00000);
+ ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT);
+ break;
+#ifdef CONFIG_WAPI_SUPPORT
+ case _SMS4_:
+ ptxdesc->txdw1 |= cpu_to_le32((0x02 << SEC_TYPE_SHT) & 0x00c00000);
+ ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT);
+ break;
+#endif
+ case _AES_:
+ ptxdesc->txdw1 |= cpu_to_le32((0x03 << SEC_TYPE_SHT) & 0x00c00000);
+ ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT);
+ break;
+ case _NO_PRIVACY_:
+ default:
+ break;
+
+ }
+
+ }
+
+}
+
+static void fill_txdesc_vcs(struct pkt_attrib *pattrib, __le32 *pdw)
+{
+ /* RTW_INFO("cvs_mode=%d\n", pattrib->vcs_mode); */
+
+ switch (pattrib->vcs_mode) {
+ case RTS_CTS:
+ *pdw |= cpu_to_le32(RTS_EN);
+ break;
+ case CTS_TO_SELF:
+ *pdw |= cpu_to_le32(CTS_2_SELF);
+ break;
+ case NONE_VCS:
+ default:
+ break;
+ }
+
+ if (pattrib->vcs_mode) {
+ *pdw |= cpu_to_le32(HW_RTS_EN);
+
+ /* Set RTS BW */
+ if (pattrib->ht_en) {
+ *pdw |= (pattrib->bwmode & CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(27)) : 0;
+
+ if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
+ *pdw |= cpu_to_le32((0x01 << 28) & 0x30000000);
+ else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
+ *pdw |= cpu_to_le32((0x02 << 28) & 0x30000000);
+ else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
+ *pdw |= 0;
+ else
+ *pdw |= cpu_to_le32((0x03 << 28) & 0x30000000);
+ }
+ }
+}
+
+static void fill_txdesc_phy(struct pkt_attrib *pattrib, __le32 *pdw)
+{
+ /* RTW_INFO("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset); */
+
+ if (pattrib->ht_en) {
+ *pdw |= (pattrib->bwmode & CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(25)) : 0;
+
+ if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
+ *pdw |= cpu_to_le32((0x01 << DATA_SC_SHT) & 0x003f0000);
+ else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
+ *pdw |= cpu_to_le32((0x02 << DATA_SC_SHT) & 0x003f0000);
+ else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
+ *pdw |= 0;
+ else
+ *pdw |= cpu_to_le32((0x03 << DATA_SC_SHT) & 0x003f0000);
+ }
+}
+
+
+static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz , u8 bagg_pkt)
+{
+ int pull = 0;
+ uint qsel;
+ bool sgi = 0;
+ u8 data_rate = 0, pwr_status, offset;
+ _adapter *padapter = pxmitframe->padapter;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+
+ struct tx_desc *ptxdesc = (struct tx_desc *)pmem;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ sint bmcst = IS_MCAST(pattrib->ra);
+#ifdef CONFIG_P2P
+ struct wifidirect_info *pwdinfo = &padapter->wdinfo;
+#endif /* CONFIG_P2P */
+
+#ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
+ if (padapter->registrypriv.mp_mode == 0) {
+ /* if((!bagg_pkt) &&(urb_zero_packet_chk(padapter, sz)==0)) */ /* (sz %512) != 0 */
+ if ((PACKET_OFFSET_SZ != 0) && (!bagg_pkt) && (rtw_usb_bulk_size_boundary(padapter, TXDESC_SIZE + sz) == false)) {
+ ptxdesc = (struct tx_desc *)(pmem + PACKET_OFFSET_SZ);
+ /* RTW_INFO("==> non-agg-pkt,shift pointer...\n"); */
+ pull = 1;
+ }
+ }
+#endif /* CONFIG_USE_USB_BUFFER_ALLOC_TX */
+
+ memset(ptxdesc, 0, sizeof(struct tx_desc));
+
+ /* 4 offset 0 */
+ ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
+ /* RTW_INFO("%s==> pkt_len=%d,bagg_pkt=%02x\n",__func__,sz,bagg_pkt); */
+ ptxdesc->txdw0 |= cpu_to_le32(sz & 0x0000ffff);/* update TXPKTSIZE */
+
+ offset = TXDESC_SIZE + OFFSET_SZ;
+
+#ifdef CONFIG_TX_EARLY_MODE
+ if (bagg_pkt) {
+ offset += EARLY_MODE_INFO_SIZE ;/* 0x28 */
+ }
+#endif
+ /* RTW_INFO("%s==>offset(0x%02x)\n",__func__,offset); */
+ ptxdesc->txdw0 |= cpu_to_le32(((offset) << OFFSET_SHT) & 0x00ff0000);/* 32 bytes for TX Desc */
+
+ if (bmcst)
+ ptxdesc->txdw0 |= cpu_to_le32(BMC);
+
+#ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
+ if (padapter->registrypriv.mp_mode == 0) {
+ if ((PACKET_OFFSET_SZ != 0) && (!bagg_pkt)) {
+ if ((pull) && (pxmitframe->pkt_offset > 0))
+ pxmitframe->pkt_offset = pxmitframe->pkt_offset - 1;
+ }
+ }
+#endif
+ /* RTW_INFO("%s, pkt_offset=0x%02x\n",__func__,pxmitframe->pkt_offset); */
+
+ /* pkt_offset, unit:8 bytes padding */
+ if (pxmitframe->pkt_offset > 0)
+ ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000);
+
+ if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
+ /* RTW_INFO("pxmitframe->frame_tag == DATA_FRAMETAG\n"); */
+
+ /* offset 4 */
+ ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x3F);
+
+ qsel = (uint)(pattrib->qsel & 0x0000001f);
+ /* RTW_INFO("==> macid(%d) qsel:0x%02x\n",pattrib->mac_id,qsel); */
+ ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
+
+ ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000F0000);
+
+ fill_txdesc_sectype(pattrib, ptxdesc);
+
+#if defined(CONFIG_CONCURRENT_MODE)
+ if (bmcst)
+ fill_txdesc_force_bmc_camid(pattrib, ptxdesc);
+#endif
+
+ if (pattrib->ampdu_en == true) {
+ ptxdesc->txdw2 |= cpu_to_le32(AGG_EN);/* AGG EN */
+ ptxdesc->txdw2 |= cpu_to_le32((pattrib->ampdu_spacing <<
+ AMPDU_DENSITY_SHT) & 0x00700000);
+
+ /* SET_TX_DESC_MAX_AGG_NUM_88E(pDesc, 0x1F); */
+ /* SET_TX_DESC_MCSG1_MAX_LEN_88E(pDesc, 0x6); */
+ /* SET_TX_DESC_MCSG2_MAX_LEN_88E(pDesc, 0x6); */
+ /* SET_TX_DESC_MCSG3_MAX_LEN_88E(pDesc, 0x6); */
+ /* SET_TX_DESC_MCS7_SGI_MAX_LEN_88E(pDesc, 0x6); */
+ ptxdesc->txdw6 = cpu_to_le32(0x6666f800);
+ } else {
+ ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);/* AGG BK */
+ }
+
+ /* offset 8 */
+
+
+ /* offset 12 */
+ ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0FFF0000);
+
+
+ /* offset 16 , offset 20 */
+ if (pattrib->qos_en)
+ ptxdesc->txdw4 |= cpu_to_le32(QOS);/* QoS */
+
+ /* offset 20 */
+#ifdef CONFIG_USB_TX_AGGREGATION
+ if (pxmitframe->agg_num > 1) {
+ /* RTW_INFO("%s agg_num:%d\n",__func__,pxmitframe->agg_num ); */
+ ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << USB_TXAGG_NUM_SHT) & 0xFF000000);
+ }
+#endif
+
+ if ((pattrib->ether_type != 0x888e) &&
+ (pattrib->ether_type != 0x0806) &&
+ (pattrib->ether_type != 0x88b4) &&
+ (pattrib->dhcp_pkt != 1)) {
+ /* Non EAP & ARP & DHCP type data packet */
+
+ fill_txdesc_vcs(pattrib, &ptxdesc->txdw4);
+ fill_txdesc_phy(pattrib, &ptxdesc->txdw4);
+
+ ptxdesc->txdw4 |= cpu_to_le32(0x00000008);/* RTS Rate=24M */
+ ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);/* DATA/RTS Rate FB LMT */
+
+#if (RATE_ADAPTIVE_SUPPORT == 1)
+ if (pHalData->fw_ractrl == false) {
+ /* driver-based RA*/
+ /* driver uses rate */
+ ptxdesc->txdw4 |= cpu_to_le32(USERATE);/* rate control always by driver */
+ if (pattrib->ht_en)
+ sgi = odm_ra_get_sgi_8188e(&pHalData->odmpriv, pattrib->mac_id);
+
+ data_rate = odm_ra_get_decision_rate_8188e(&pHalData->odmpriv, pattrib->mac_id);
+
+#if (POWER_TRAINING_ACTIVE == 1)
+ pwr_status = odm_ra_get_hw_pwr_status_8188e(&pHalData->odmpriv, pattrib->mac_id);
+ ptxdesc->txdw4 |= cpu_to_le32((pwr_status & 0x7) << PWR_STATUS_SHT);
+#endif
+ } else
+#endif/* if (RATE_ADAPTIVE_SUPPORT == 1) */
+ {
+ /* FW-based RA, TODO */
+ if (pattrib->ht_en)
+ sgi = 1;
+
+ data_rate = 0x13; /* default rate: MCS7 */
+ }
+
+ if (padapter->fix_rate != 0xFF) {
+ data_rate = padapter->fix_rate;
+ ptxdesc->txdw4 |= cpu_to_le32(USERATE);
+ if (!padapter->data_fb)
+ ptxdesc->txdw4 |= cpu_to_le32(DISDATAFB);
+ sgi = (padapter->fix_rate & BIT(7)) ? 1 : 0;
+ }
+
+ if (sgi)
+ ptxdesc->txdw5 |= cpu_to_le32(SGI);
+
+ ptxdesc->txdw5 |= cpu_to_le32(data_rate & 0x3F);
+ } else {
+ /* EAP data packet and ARP packet and DHCP. */
+ /* Use the 1M data rate to send the EAP/ARP packet. */
+ /* This will maybe make the handshake smooth. */
+
+ /* driver uses rate */
+ ptxdesc->txdw4 |= cpu_to_le32(USERATE);/* rate control always by driver */
+ ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);/* AGG BK */
+
+ if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
+ ptxdesc->txdw4 |= cpu_to_le32(BIT(24));/* DATA_SHORT */
+
+ ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
+ }
+
+#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
+ /* offset 24 */
+ if (pattrib->hw_tcp_csum == 1) {
+ /* ptxdesc->txdw6 = 0; */ /* clear TCP_CHECKSUM and IP_CHECKSUM. It's zero already!! */
+ u8 ip_hdr_offset = 32 + pattrib->hdrlen + pattrib->iv_len + 8;
+ ptxdesc->txdw7 = (1 << 31) | (ip_hdr_offset << 16);
+ RTW_INFO("ptxdesc->txdw7 = %08x\n", ptxdesc->txdw7);
+ }
+#endif
+
+#ifdef CONFIG_TDLS
+#ifdef CONFIG_XMIT_ACK
+ /* CCX-TXRPT ack for xmit mgmt frames. */
+ if (pxmitframe->ack_report) {
+#ifdef DBG_CCX
+ static u16 ccx_sw = 0x123;
+
+ ptxdesc->txdw7 |= cpu_to_le32(((ccx_sw) << 16) & 0x0fff0000);
+ RTW_INFO("%s set ccx, sw:0x%03x\n", __func__, ccx_sw);
+ ccx_sw = (ccx_sw + 1) % 0xfff;
+#endif
+ ptxdesc->txdw2 |= cpu_to_le32(BIT(19));
+ }
+#endif /* CONFIG_XMIT_ACK */
+#endif
+ } else if ((pxmitframe->frame_tag & 0x0f) == MGNT_FRAMETAG) {
+ /* RTW_INFO("pxmitframe->frame_tag == MGNT_FRAMETAG\n"); */
+ /* driver uses rate */
+ ptxdesc->txdw4 |= cpu_to_le32(USERATE);/* rate control always by driver */
+
+ /* offset 4 */
+ ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x3f);
+
+ qsel = (uint)(pattrib->qsel & 0x0000001f);
+ ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
+
+ ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000f0000);
+
+ /* fill_txdesc_sectype(pattrib, ptxdesc); */
+
+ /* offset 8 */
+#ifdef CONFIG_XMIT_ACK
+ /* CCX-TXRPT ack for xmit mgmt frames. */
+ if (pxmitframe->ack_report) {
+#ifdef DBG_CCX
+ static u16 ccx_sw = 0x123;
+ ptxdesc->txdw7 |= cpu_to_le32(((ccx_sw) << 16) & 0x0fff0000);
+ RTW_INFO("%s set ccx, sw:0x%03x\n", __func__, ccx_sw);
+ ccx_sw = (ccx_sw + 1) % 0xfff;
+#endif
+ ptxdesc->txdw2 |= cpu_to_le32(BIT(19));
+ }
+#endif /* CONFIG_XMIT_ACK */
+
+ /* offset 12 */
+ ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0FFF0000);
+
+ /* offset 20 */
+ ptxdesc->txdw5 |= cpu_to_le32(RTY_LMT_EN);/* retry limit enable */
+ if (pattrib->retry_ctrl == true)
+ ptxdesc->txdw5 |= cpu_to_le32(0x00180000);/* retry limit = 6 */
+ else
+ ptxdesc->txdw5 |= cpu_to_le32(0x00300000);/* retry limit = 12 */
+
+ ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pattrib->rate));
+
+ } else if ((pxmitframe->frame_tag & 0x0f) == TXAGG_FRAMETAG)
+ RTW_INFO("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
+#ifdef CONFIG_MP_INCLUDED
+ else if (((pxmitframe->frame_tag & 0x0f) == MP_FRAMETAG) &&
+ (padapter->registrypriv.mp_mode == 1))
+ fill_txdesc_for_mp(padapter, (u8 *)ptxdesc);
+#endif
+ else {
+ RTW_INFO("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag);
+
+ /* offset 4 */
+ ptxdesc->txdw1 |= cpu_to_le32((4) & 0x3f); /* CAM_ID(MAC_ID) */
+
+ ptxdesc->txdw1 |= cpu_to_le32((6 << RATE_ID_SHT) & 0x000f0000); /* raid */
+
+ /* offset 8 */
+
+ /* offset 12 */
+ ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0fff0000);
+
+ /* offset 20 */
+ ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
+ }
+
+ /* 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */
+ /* (1) The sequence number of each non-Qos frame / broadcast / multicast / */
+ /* mgnt frame should be controled by Hw because Fw will also send null data */
+ /* which we cannot control when Fw LPS enable. */
+ /* --> default enable non-Qos data sequense number. 2010.06.23. by tynli. */
+ /* (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. */
+ /* (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. */
+ /* 2010.06.23. Added by tynli. */
+ if (!pattrib->qos_en) {
+ /* ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); */ /* Hw set sequence number */
+ /* ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); */ /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */
+
+ ptxdesc->txdw3 |= cpu_to_le32(EN_HWSEQ); /* Hw set sequence number */
+ ptxdesc->txdw4 |= cpu_to_le32(HW_SSN); /* Hw set sequence number */
+
+ }
+
+#ifdef CONFIG_ANTENNA_DIVERSITY
+ odm_set_tx_ant_by_tx_info(&pHalData->odmpriv, pmem, pattrib->mac_id);
+#endif
+
+ rtl8188eu_cal_txdesc_chksum(ptxdesc);
+ _dbg_dump_tx_info(padapter, pxmitframe->frame_tag, ptxdesc);
+ return pull;
+
+}
+
+
+#ifdef CONFIG_XMIT_THREAD_MODE
+/*
+ * Description
+ * Transmit xmitbuf to hardware tx fifo
+ *
+ * Return
+ * _SUCCESS ok
+ * _FAIL something error
+ */
+s32 rtl8188eu_xmit_buf_handler(PADAPTER padapter)
+{
+ /* PHAL_DATA_TYPE phal; */
+ struct xmit_priv *pxmitpriv;
+ struct xmit_buf *pxmitbuf;
+ s32 ret;
+
+
+ /* phal = GET_HAL_DATA(padapter); */
+ pxmitpriv = &padapter->xmitpriv;
+
+ ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
+ if (_FAIL == ret) {
+ return _FAIL;
+ }
+ if (RTW_CANNOT_RUN(padapter)) {
+ return _FAIL;
+ }
+
+ if (rtw_mi_check_pending_xmitbuf(padapter) == 0)
+ return _SUCCESS;
+
+#ifdef CONFIG_LPS_LCLK
+ ret = rtw_register_tx_alive(padapter);
+ if (ret != _SUCCESS) {
+ return _SUCCESS;
+ }
+#endif
+
+ do {
+ pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
+ if (pxmitbuf == NULL)
+ break;
+
+ rtw_write_port(padapter, pxmitbuf->ff_hwaddr, pxmitbuf->len, (unsigned char *)pxmitbuf);
+
+ } while (1);
+
+#ifdef CONFIG_LPS_LCLK
+ rtw_unregister_tx_alive(padapter);
+#endif
+
+ return _SUCCESS;
+}
+#endif
+
+#ifdef CONFIG_IOL_IOREG_CFG_DBG
+ #include <rtw_iol.h>
+#endif
+/* for non-agg data frame or management frame */
+static s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
+{
+ s32 ret = _SUCCESS;
+ s32 inner_ret = _SUCCESS;
+ int t, sz, w_sz, pull = 0;
+ u8 *mem_addr;
+ u32 ff_hwaddr;
+ struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
+ (pxmitframe->attrib.ether_type != 0x0806) &&
+ (pxmitframe->attrib.ether_type != 0x888e) &&
+ (pxmitframe->attrib.ether_type != 0x88b4) &&
+ (pxmitframe->attrib.dhcp_pkt != 1))
+ rtw_issue_addbareq_cmd(padapter, pxmitframe);
+ mem_addr = pxmitframe->buf_addr;
+
+
+ for (t = 0; t < pattrib->nr_frags; t++) {
+ if (inner_ret != _SUCCESS && ret == _SUCCESS)
+ ret = _FAIL;
+
+ if (t != (pattrib->nr_frags - 1)) {
+
+ sz = pxmitpriv->frag_len;
+ sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);
+ } else /* no frag */
+ sz = pattrib->last_txcmdsz;
+
+ pull = update_txdesc(pxmitframe, mem_addr, sz, false);
+
+ if (pull) {
+ mem_addr += PACKET_OFFSET_SZ; /* pull txdesc head */
+
+ /* pxmitbuf->pbuf = mem_addr; */
+ pxmitframe->buf_addr = mem_addr;
+
+ w_sz = sz + TXDESC_SIZE;
+ } else
+ w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
+#ifdef CONFIG_IOL_IOREG_CFG_DBG
+ rtw_IOL_cmd_buf_dump(padapter, w_sz, pxmitframe->buf_addr);
+#endif
+ ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
+
+#ifdef CONFIG_XMIT_THREAD_MODE
+ pxmitbuf->len = w_sz;
+ pxmitbuf->ff_hwaddr = ff_hwaddr;
+ enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
+#else
+ /* RTW_INFO("%s: rtw_write_port size =%d\n", __func__,w_sz); */
+ inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char *)pxmitbuf);
+#endif
+
+ rtw_count_tx_stats(padapter, pxmitframe, sz);
+
+ /* RTW_INFO("rtw_write_port, w_sz=%d, sz=%d, txdesc_sz=%d, tid=%d\n", w_sz, sz, w_sz-sz, pattrib->priority); */
+
+ mem_addr += w_sz;
+
+ mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));
+
+ }
+
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+
+ if (ret != _SUCCESS)
+ rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
+
+ return ret;
+}
+
+#ifdef CONFIG_USB_TX_AGGREGATION
+static u32 xmitframe_need_length(struct xmit_frame *pxmitframe)
+{
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+
+ u32 len = 0;
+
+ /* no consider fragement */
+ len = pattrib->hdrlen + pattrib->iv_len +
+ SNAP_SIZE + sizeof(u16) +
+ pattrib->pktlen +
+ ((pattrib->bswenc) ? pattrib->icv_len : 0);
+
+ if (pattrib->encrypt == _TKIP_)
+ len += 8;
+
+ return len;
+}
+
+#define IDEA_CONDITION 1 /* check all packets before enqueue */
+s32 rtl8188eu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct xmit_frame *pxmitframe = NULL;
+ struct xmit_frame *pfirstframe = NULL;
+
+ /* aggregate variable */
+ struct hw_xmit *phwxmit;
+ struct sta_info *psta = NULL;
+ struct tx_servq *ptxservq = NULL;
+
+ unsigned long irqL;
+ _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
+
+ u32 pbuf; /* next pkt address */
+ u32 pbuf_tail; /* last pkt tail */
+ u32 len; /* packet length, except TXDESC_SIZE and PKT_OFFSET */
+
+ u32 bulkSize = pHalData->UsbBulkOutSize;
+ u8 descCount;
+ u32 bulkPtr;
+
+ /* dump frame variable */
+ u32 ff_hwaddr;
+
+ _list *sta_plist, *sta_phead;
+ u8 single_sta_in_queue = false;
+
+#ifndef IDEA_CONDITION
+ int res = _SUCCESS;
+#endif
+
+
+
+ /* check xmitbuffer is ok */
+ if (pxmitbuf == NULL) {
+ pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
+ if (pxmitbuf == NULL) {
+ /* RTW_INFO("%s #1, connot alloc xmitbuf!!!!\n",__func__); */
+ return false;
+ }
+ }
+
+ /* RTW_INFO("%s =====================================\n",__func__); */
+ /* 3 1. pick up first frame */
+ do {
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+
+ pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
+ if (pxmitframe == NULL) {
+ /* no more xmit frame, release xmit buffer */
+ /* RTW_INFO("no more xmit frame ,return\n"); */
+ rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
+ return false;
+ }
+
+#ifndef IDEA_CONDITION
+ if (pxmitframe->frame_tag != DATA_FRAMETAG) {
+ /* rtw_free_xmitframe(pxmitpriv, pxmitframe); */
+ continue;
+ }
+
+ /* TID 0~15 */
+ if ((pxmitframe->attrib.priority < 0) ||
+ (pxmitframe->attrib.priority > 15)) {
+ /* rtw_free_xmitframe(pxmitpriv, pxmitframe); */
+ continue;
+ }
+#endif
+ /* RTW_INFO("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority); */
+ pxmitframe->pxmitbuf = pxmitbuf;
+ pxmitframe->buf_addr = pxmitbuf->pbuf;
+ pxmitbuf->priv_data = pxmitframe;
+
+ pxmitframe->agg_num = 1; /* alloc xmitframe should assign to 1. */
+#ifdef CONFIG_TX_EARLY_MODE
+ pxmitframe->pkt_offset = (PACKET_OFFSET_SZ / 8) + 1; /* 2; */ /* first frame of aggregation, reserve one offset for EM info ,another for usb bulk-out block check */
+#else
+ pxmitframe->pkt_offset = (PACKET_OFFSET_SZ / 8); /* 1; */ /* first frame of aggregation, reserve offset */
+#endif
+
+ if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == false) {
+ RTW_INFO("%s coalesce 1st xmitframe failed\n", __func__);
+ continue;
+ }
+
+ /* always return ndis_packet after rtw_xmitframe_coalesce */
+ rtw_os_xmit_complete(padapter, pxmitframe);
+
+ break;
+ } while (1);
+
+ /* 3 2. aggregate same priority and same DA(AP or STA) frames */
+ pfirstframe = pxmitframe;
+ len = xmitframe_need_length(pfirstframe) + TXDESC_SIZE + (pfirstframe->pkt_offset * PACKET_OFFSET_SZ);
+ pbuf_tail = len;
+ pbuf = _RND8(pbuf_tail);
+
+ /* check pkt amount in one bulk */
+ descCount = 0;
+ bulkPtr = bulkSize;
+ if (pbuf < bulkPtr) {
+ descCount++;
+ if (descCount == pHalData->UsbTxAggDescNum)
+ goto agg_end;
+ } else {
+ descCount = 0;
+ bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; /* round to next bulkSize */
+ }
+
+ /* dequeue same priority packet from station tx queue */
+ /* psta = pfirstframe->attrib.psta; */
+ psta = rtw_get_stainfo(&padapter->stapriv, pfirstframe->attrib.ra);
+ if (pfirstframe->attrib.psta != psta)
+ RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pfirstframe->attrib.psta, psta);
+ if (psta == NULL)
+ RTW_INFO("rtw_xmit_classifier: psta == NULL\n");
+ if (!(psta->state & _FW_LINKED))
+ RTW_INFO("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
+
+ switch (pfirstframe->attrib.priority) {
+ case 1:
+ case 2:
+ ptxservq = &(psta->sta_xmitpriv.bk_q);
+ phwxmit = pxmitpriv->hwxmits + 3;
+ break;
+
+ case 4:
+ case 5:
+ ptxservq = &(psta->sta_xmitpriv.vi_q);
+ phwxmit = pxmitpriv->hwxmits + 1;
+ break;
+
+ case 6:
+ case 7:
+ ptxservq = &(psta->sta_xmitpriv.vo_q);
+ phwxmit = pxmitpriv->hwxmits;
+ break;
+
+ case 0:
+ case 3:
+ default:
+ ptxservq = &(psta->sta_xmitpriv.be_q);
+ phwxmit = pxmitpriv->hwxmits + 2;
+ break;
+ }
+ /* RTW_INFO("==> pkt_no=%d,pkt_len=%d,len=%d,RND8_LEN=%d,pkt_offset=0x%02x\n", */
+ /* pxmitframe->agg_num,pxmitframe->attrib.last_txcmdsz,len,pbuf,pxmitframe->pkt_offset ); */
+
+ _enter_critical_bh(&pxmitpriv->lock, &irqL);
+
+ sta_phead = get_list_head(phwxmit->sta_queue);
+ sta_plist = get_next(sta_phead);
+ single_sta_in_queue = rtw_end_of_queue_search(sta_phead, get_next(sta_plist));
+
+ xmitframe_phead = get_list_head(&ptxservq->sta_pending);
+ 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);
+
+ if (_FAIL == rtw_hal_busagg_qsel_check(padapter, pfirstframe->attrib.qsel, pxmitframe->attrib.qsel))
+ break;
+
+ pxmitframe->agg_num = 0; /* not first frame of aggregation */
+#ifdef CONFIG_TX_EARLY_MODE
+ pxmitframe->pkt_offset = 1;/* not first frame of aggregation,reserve offset for EM Info */
+#else
+ pxmitframe->pkt_offset = 0; /* not first frame of aggregation, no need to reserve offset */
+#endif
+
+ len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
+
+ if (_RND8(pbuf + len) > MAX_XMITBUF_SZ)
+ /* if (_RND8(pbuf + len) > (MAX_XMITBUF_SZ/2))//to do : for TX TP finial tune , Georgia 2012-0323 */
+ {
+ /* RTW_INFO("%s....len> MAX_XMITBUF_SZ\n",__func__); */
+ pxmitframe->agg_num = 1;
+ pxmitframe->pkt_offset = 1;
+ break;
+ }
+ list_del_init(&pxmitframe->list);
+ ptxservq->qcnt--;
+ phwxmit->accnt--;
+
+#ifndef IDEA_CONDITION
+ /* suppose only data frames would be in queue */
+ if (pxmitframe->frame_tag != DATA_FRAMETAG) {
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+ continue;
+ }
+
+ /* TID 0~15 */
+ if ((pxmitframe->attrib.priority < 0) ||
+ (pxmitframe->attrib.priority > 15)) {
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+ continue;
+ }
+#endif
+
+ /* pxmitframe->pxmitbuf = pxmitbuf; */
+ pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
+
+ if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == false) {
+ RTW_INFO("%s coalesce failed\n", __func__);
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+ continue;
+ }
+
+ /* RTW_INFO("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority); */
+ /* always return ndis_packet after rtw_xmitframe_coalesce */
+ rtw_os_xmit_complete(padapter, pxmitframe);
+
+ /* (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz */
+ update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, true);
+
+ /* don't need xmitframe any more */
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+
+ /* handle pointer and stop condition */
+ pbuf_tail = pbuf + len;
+ pbuf = _RND8(pbuf_tail);
+
+
+ pfirstframe->agg_num++;
+#ifdef CONFIG_TX_EARLY_MODE
+ pxmitpriv->agg_pkt[pfirstframe->agg_num - 1].offset = _RND8(len);
+ pxmitpriv->agg_pkt[pfirstframe->agg_num - 1].pkt_len = pxmitframe->attrib.last_txcmdsz;
+#endif
+ if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
+ break;
+
+ if (pbuf < bulkPtr) {
+ descCount++;
+ if (descCount == pHalData->UsbTxAggDescNum)
+ break;
+ } else {
+ descCount = 0;
+ bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize;
+ }
+ } /* end while( aggregate same priority and same DA(AP or STA) frames) */
+ if (_rtw_queue_empty(&ptxservq->sta_pending) == true)
+ list_del_init(&ptxservq->tx_pending);
+ else if (single_sta_in_queue == false) {
+ /* Re-arrange the order of stations in this ac queue to balance the service for these stations */
+ list_del_init(&ptxservq->tx_pending);
+ list_add_tail(&ptxservq->tx_pending, get_list_head(phwxmit->sta_queue));
+ }
+
+ _exit_critical_bh(&pxmitpriv->lock, &irqL);
+
+agg_end:
+
+ if ((pfirstframe->attrib.ether_type != 0x0806) &&
+ (pfirstframe->attrib.ether_type != 0x888e) &&
+ (pfirstframe->attrib.ether_type != 0x88b4) &&
+ (pfirstframe->attrib.dhcp_pkt != 1))
+ rtw_issue_addbareq_cmd(padapter, pfirstframe);
+#ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
+ /* 3 3. update first frame txdesc */
+ if ((PACKET_OFFSET_SZ != 0) && ((pbuf_tail % bulkSize) == 0)) {
+ /* remove pkt_offset */
+ pbuf_tail -= PACKET_OFFSET_SZ;
+ pfirstframe->buf_addr += PACKET_OFFSET_SZ;
+ pfirstframe->pkt_offset--;
+ /* RTW_INFO("$$$$$ buf size equal to USB block size $$$$$$\n"); */
+ }
+#endif /* CONFIG_USE_USB_BUFFER_ALLOC_TX */
+
+ update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, true);
+
+#ifdef CONFIG_TX_EARLY_MODE
+ /* prepare EM info for first frame, agg_num value start from 1 */
+ pxmitpriv->agg_pkt[0].offset = _RND8(pfirstframe->attrib.last_txcmdsz + TXDESC_SIZE + (pfirstframe->pkt_offset * PACKET_OFFSET_SZ));
+ pxmitpriv->agg_pkt[0].pkt_len = pfirstframe->attrib.last_txcmdsz;/* get from rtw_xmitframe_coalesce */
+
+ UpdateEarlyModeInfo8188E(pxmitpriv, pxmitbuf);
+#endif
+
+ /* 3 4. write xmit buffer to USB FIFO */
+ ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
+ /* RTW_INFO("%s ===================================== write port,buf_size(%d)\n",__func__,pbuf_tail); */
+ /* xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr */
+ rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf);
+
+
+ /* 3 5. update statisitc */
+ pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
+ pbuf_tail -= (pfirstframe->pkt_offset * PACKET_OFFSET_SZ);
+
+
+ rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);
+
+ rtw_free_xmitframe(pxmitpriv, pfirstframe);
+
+ return true;
+}
+
+#else
+
+s32 rtl8188eu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
+{
+
+ struct hw_xmit *phwxmits;
+ sint hwentry;
+ struct xmit_frame *pxmitframe = NULL;
+ int res = _SUCCESS, xcnt = 0;
+
+ phwxmits = pxmitpriv->hwxmits;
+ hwentry = pxmitpriv->hwxmit_entry;
+
+
+ if (pxmitbuf == NULL) {
+ pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
+ if (!pxmitbuf)
+ return false;
+ }
+
+
+ do {
+ pxmitframe = rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);
+
+ if (pxmitframe) {
+ pxmitframe->pxmitbuf = pxmitbuf;
+
+ pxmitframe->buf_addr = pxmitbuf->pbuf;
+
+ pxmitbuf->priv_data = pxmitframe;
+
+ if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
+ if (pxmitframe->attrib.priority <= 15) /* TID0~15 */
+ res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
+ /* RTW_INFO("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority); */
+ rtw_os_xmit_complete(padapter, pxmitframe);/* always return ndis_packet after rtw_xmitframe_coalesce */
+ }
+
+
+
+
+ if (res == _SUCCESS)
+ rtw_dump_xframe(padapter, pxmitframe);
+ else {
+ rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+ }
+
+ xcnt++;
+
+ } else {
+ rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
+ return false;
+ }
+
+ break;
+
+ } while (0/*xcnt < (NR_XMITFRAME >> 3)*/);
+
+ return true;
+
+}
+#endif
+
+
+
+static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
+{
+ s32 res = _SUCCESS;
+ /* RTW_INFO("==> %s\n",__func__); */
+
+ res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
+ if (res == _SUCCESS)
+ rtw_dump_xframe(padapter, pxmitframe);
+ else
+ RTW_INFO("==> %s xmitframe_coalsece failed\n", __func__);
+
+ return res;
+}
+
+/*
+ * Return
+ * true dump packet directly
+ * false enqueue packet
+ */
+static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
+{
+ unsigned long irqL;
+ s32 res;
+ struct xmit_buf *pxmitbuf = NULL;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ _enter_critical_bh(&pxmitpriv->lock, &irqL);
+
+ /* RTW_INFO("==> %s\n",__func__); */
+
+ if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0) {
+ /* RTW_INFO("enqueue AC(%d)\n",pattrib->priority); */
+ goto enqueue;
+ }
+
+ if (rtw_xmit_ac_blocked(padapter) == true)
+ goto enqueue;
+
+ if (DEV_STA_LG_NUM(padapter->dvobj))
+ goto enqueue;
+
+ pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
+ if (pxmitbuf == NULL)
+ goto enqueue;
+
+ _exit_critical_bh(&pxmitpriv->lock, &irqL);
+
+ pxmitframe->pxmitbuf = pxmitbuf;
+ pxmitframe->buf_addr = pxmitbuf->pbuf;
+ pxmitbuf->priv_data = pxmitframe;
+
+ if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
+ rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+ }
+
+ return true;
+
+enqueue:
+ res = rtw_xmitframe_enqueue(padapter, pxmitframe);
+ _exit_critical_bh(&pxmitpriv->lock, &irqL);
+
+ if (res != _SUCCESS) {
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+
+ pxmitpriv->tx_drop++;
+ return true;
+ }
+
+ return false;
+}
+
+s32 rtl8188eu_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
+{
+ return rtw_dump_xframe(padapter, pmgntframe);
+}
+
+/*
+ * Return
+ * true dump packet directly ok
+ * false temporary can't transmit packets to hardware
+ */
+s32 rtl8188eu_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
+{
+ return pre_xmitframe(padapter, pxmitframe);
+}
+
+s32 rtl8188eu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
+{
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ s32 err;
+
+ err = rtw_xmitframe_enqueue(padapter, pxmitframe);
+ if (err != _SUCCESS) {
+ rtw_free_xmitframe(pxmitpriv, pxmitframe);
+
+ pxmitpriv->tx_drop++;
+ } else {
+ tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
+ }
+
+ return err;
+
+}
+
+
+#ifdef CONFIG_HOSTAPD_MLME
+
+static void rtl8188eu_hostap_mgnt_xmit_cb(struct urb *urb)
+{
+ struct sk_buff *skb = (struct sk_buff *)urb->context;
+
+ rtw_skb_free(skb);
+}
+
+s32 rtl8188eu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
+{
+ u16 fc;
+ int rc, len, pipe;
+ unsigned int bmcst, tid, qsel;
+ struct sk_buff *skb, *pxmit_skb;
+ struct urb *urb;
+ unsigned char *pxmitbuf;
+ struct tx_desc *ptxdesc;
+ struct rtw_ieee80211_hdr *tx_hdr;
+ struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
+ struct net_device *pnetdev = padapter->pnetdev;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
+
+
+ skb = pkt;
+
+ len = skb->len;
+ tx_hdr = (struct rtw_ieee80211_hdr *)(skb->data);
+ fc = le16_to_cpu(tx_hdr->frame_ctl);
+ bmcst = IS_MCAST(tx_hdr->addr1);
+
+ if ((fc & RTW_IEEE80211_FCTL_FTYPE) != RTW_IEEE80211_FTYPE_MGMT)
+ goto _exit;
+
+ pxmit_skb = rtw_skb_alloc(len + TXDESC_SIZE);
+
+ if (!pxmit_skb)
+ goto _exit;
+
+ pxmitbuf = pxmit_skb->data;
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb)
+ goto _exit;
+
+ /* ----- fill tx desc ----- */
+ ptxdesc = (struct tx_desc *)pxmitbuf;
+ memset(ptxdesc, 0, sizeof(*ptxdesc));
+
+ /* offset 0 */
+ ptxdesc->txdw0 |= cpu_to_le32(len & 0x0000ffff);
+ ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000); /* default = 32 bytes for TX Desc */
+ ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
+
+ if (bmcst)
+ ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
+
+ /* offset 4 */
+ ptxdesc->txdw1 |= cpu_to_le32(0x00);/* MAC_ID */
+
+ ptxdesc->txdw1 |= cpu_to_le32((0x12 << QSEL_SHT) & 0x00001f00);
+
+ ptxdesc->txdw1 |= cpu_to_le32((0x06 << 16) & 0x000f0000); /* b mode */
+
+ /* offset 8 */
+
+ /* offset 12 */
+ ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl) << 16) & 0xffff0000);
+
+ /* offset 16 */
+ ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */
+
+ /* offset 20 */
+
+
+ /* HW append seq */
+ ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); /* Hw set sequence number */
+ ptxdesc->txdw3 |= cpu_to_le32((8 << 28)); /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */
+
+
+ rtl8188eu_cal_txdesc_chksum(ptxdesc);
+ /* ----- end of fill tx desc ----- */
+
+ /* */
+ skb_put(pxmit_skb, len + TXDESC_SIZE);
+ pxmitbuf = pxmitbuf + TXDESC_SIZE;
+ memcpy(pxmitbuf, skb->data, len);
+
+ /* RTW_INFO("mgnt_xmit, len=%x\n", pxmit_skb->len); */
+
+
+ /* ----- prepare urb for submit ----- */
+
+ /* translate DMA FIFO addr to pipehandle */
+ /* pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX); */
+ pipe = usb_sndbulkpipe(pdvobj->pusbdev, pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX] & 0x0f);
+
+ usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
+ pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb);
+
+ urb->transfer_flags |= URB_ZERO_PACKET;
+ usb_anchor_urb(urb, &phostapdpriv->anchored);
+ rc = usb_submit_urb(urb, GFP_ATOMIC);
+ if (rc < 0) {
+ usb_unanchor_urb(urb);
+ kfree_skb(skb);
+ }
+ usb_free_urb(urb);
+
+
+_exit:
+
+ rtw_skb_free(skb);
+
+ return 0;
+}
+#endif
diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c
new file mode 100644
index 000000000000..3e037e53b1a3
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c
@@ -0,0 +1,2135 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _HCI_HAL_INIT_C_
+
+#include <drv_types.h>
+#include <rtl8188e_hal.h>
+#include "hal_com_h2c.h"
+
+static void
+_ConfigNormalChipOutEP_8188E(
+ PADAPTER pAdapter,
+ u8 NumOutPipe
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+
+ switch (NumOutPipe) {
+ case 3:
+ pHalData->OutEpQueueSel = TX_SELE_HQ | TX_SELE_LQ | TX_SELE_NQ;
+ pHalData->OutEpNumber = 3;
+ break;
+ case 2:
+ pHalData->OutEpQueueSel = TX_SELE_HQ | TX_SELE_NQ;
+ pHalData->OutEpNumber = 2;
+ break;
+ case 1:
+ pHalData->OutEpQueueSel = TX_SELE_HQ;
+ pHalData->OutEpNumber = 1;
+ break;
+ default:
+ break;
+
+ }
+ RTW_INFO("%s OutEpQueueSel(0x%02x), OutEpNumber(%d)\n", __func__, pHalData->OutEpQueueSel, pHalData->OutEpNumber);
+
+}
+
+static bool HalUsbSetQueuePipeMapping8188EUsb(
+ PADAPTER pAdapter,
+ u8 NumInPipe,
+ u8 NumOutPipe
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ bool result = false;
+
+ _ConfigNormalChipOutEP_8188E(pAdapter, NumOutPipe);
+
+ /* Normal chip with one IN and one OUT doesn't have interrupt IN EP. */
+ if (1 == pHalData->OutEpNumber) {
+ if (1 != NumInPipe)
+ return result;
+ }
+
+ /* All config other than above support one Bulk IN and one Interrupt IN. */
+ /* if(2 != NumInPipe){ */
+ /* return result; */
+ /* } */
+
+ result = Hal_MappingOutPipe(pAdapter, NumOutPipe);
+
+ return result;
+
+}
+
+static void rtl8188eu_interface_configure(_adapter *padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ struct registry_priv *registry_par = &padapter->registrypriv;
+
+ if (IS_HIGH_SPEED_USB(padapter)) {
+ pHalData->UsbBulkOutSize = USB_HIGH_SPEED_BULK_SIZE;/* 512 bytes */
+ } else {
+ pHalData->UsbBulkOutSize = USB_FULL_SPEED_BULK_SIZE;/* 64 bytes */
+ }
+
+ pHalData->interfaceIndex = pdvobjpriv->InterfaceNumber;
+
+#ifdef CONFIG_USB_TX_AGGREGATION
+ pHalData->UsbTxAggMode = 1;
+ pHalData->UsbTxAggDescNum = 0x1; /* only 4 bits */
+#endif
+
+#ifdef CONFIG_USB_RX_AGGREGATION
+ pHalData->rxagg_mode = registry_par->usb_rxagg_mode;
+
+ if ((pHalData->rxagg_mode != RX_AGG_DMA) && (pHalData->rxagg_mode != RX_AGG_USB))
+ pHalData->rxagg_mode = RX_AGG_DMA;
+
+ if (pHalData->rxagg_mode == RX_AGG_DMA) {
+ pHalData->rxagg_dma_size = 48; /* uint: 128b, 0x0A = 10 = MAX_RX_DMA_BUFFER_SIZE/2/pHalData->UsbBulkOutSize */
+ pHalData->rxagg_dma_timeout = 0x4; /* 6, absolute time = 34ms/(2^6) */
+ } else if (pHalData->rxagg_mode == RX_AGG_USB) {
+ pHalData->rxagg_usb_size = 16; /* unit: 512b */
+ pHalData->rxagg_usb_timeout = 0x6;
+ }
+#endif
+
+ HalUsbSetQueuePipeMapping8188EUsb(padapter,
+ pdvobjpriv->RtNumInPipes, pdvobjpriv->RtNumOutPipes);
+
+}
+
+static u32 _InitPowerOn_8188EU(_adapter *padapter)
+{
+ u16 value16;
+ /* HW Power on sequence */
+ u8 bMacPwrCtrlOn = false;
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if (bMacPwrCtrlOn == true)
+ return _SUCCESS;
+
+ if (!HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_PWR_ON_FLOW)) {
+ RTW_ERR("%s: run power on flow fail\n", __func__);
+ return _FAIL;
+ }
+
+ /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
+ /* Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
+ rtw_write16(padapter, REG_CR, 0x00); /* suggseted by zhouzhou, by page, 20111230 */
+
+ /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
+ value16 = rtw_read16(padapter, REG_CR);
+ value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN
+ | PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN);
+ /* for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
+
+ rtw_write16(padapter, REG_CR, value16);
+
+ bMacPwrCtrlOn = true;
+ rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+
+ return _SUCCESS;
+
+}
+
+static void _dbg_dump_macreg(_adapter *padapter)
+{
+ u32 offset = 0;
+ u32 val32 = 0;
+ u32 index = 0 ;
+ for (index = 0; index < 64; index++) {
+ offset = index * 4;
+ val32 = rtw_read32(padapter, offset);
+ RTW_INFO("offset : 0x%02x ,val:0x%08x\n", offset, val32);
+ }
+}
+
+static void _InitPABias(_adapter *padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ u8 pa_setting;
+
+ /* FIXED PA current issue */
+ /* efuse_one_byte_read(padapter, 0x1FA, &pa_setting); */
+ efuse_OneByteRead(padapter, 0x1FA, &pa_setting, false);
+
+ if (!(pa_setting & BIT0)) {
+ phy_set_rf_reg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x0F406);
+ phy_set_rf_reg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x4F406);
+ phy_set_rf_reg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x8F406);
+ phy_set_rf_reg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0xCF406);
+ }
+
+ if (!(pa_setting & BIT4)) {
+ pa_setting = rtw_read8(padapter, 0x16);
+ pa_setting &= 0x0F;
+ rtw_write8(padapter, 0x16, pa_setting | 0x80);
+ rtw_write8(padapter, 0x16, pa_setting | 0x90);
+ }
+}
+#ifdef CONFIG_BT_COEXIST
+static void _InitBTCoexist(_adapter *padapter)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist);
+ u8 u1Tmp;
+
+ if (pbtpriv->BT_Coexist && pbtpriv->BT_CoexistType == BT_CSR_BC4) {
+
+ /* #if MP_DRIVER != 1 */
+ if (padapter->registrypriv.mp_mode == 0) {
+ if (pbtpriv->BT_Ant_isolation) {
+ rtw_write8(padapter, REG_GPIO_MUXCFG, 0xa0);
+ RTW_INFO("BT write 0x%x = 0x%x\n", REG_GPIO_MUXCFG, 0xa0);
+ }
+ }
+ /* #endif */
+
+ u1Tmp = rtw_read8(padapter, 0x4fd) & BIT0;
+ u1Tmp = u1Tmp |
+ ((pbtpriv->BT_Ant_isolation == 1) ? 0 : BIT1) |
+ ((pbtpriv->BT_Service == BT_SCO) ? 0 : BIT2);
+ rtw_write8(padapter, 0x4fd, u1Tmp);
+ RTW_INFO("BT write 0x%x = 0x%x for non-isolation\n", 0x4fd, u1Tmp);
+
+ rtw_write32(padapter, REG_BT_COEX_TABLE + 4, 0xaaaa9aaa);
+ RTW_INFO("BT write 0x%x = 0x%x\n", REG_BT_COEX_TABLE + 4, 0xaaaa9aaa);
+
+ rtw_write32(padapter, REG_BT_COEX_TABLE + 8, 0xffbd0040);
+ RTW_INFO("BT write 0x%x = 0x%x\n", REG_BT_COEX_TABLE + 8, 0xffbd0040);
+
+ rtw_write32(padapter, REG_BT_COEX_TABLE + 0xc, 0x40000010);
+ RTW_INFO("BT write 0x%x = 0x%x\n", REG_BT_COEX_TABLE + 0xc, 0x40000010);
+
+ /* Config to 1T1R */
+ u1Tmp = rtw_read8(padapter, rOFDM0_TRxPathEnable);
+ u1Tmp &= ~(BIT1);
+ rtw_write8(padapter, rOFDM0_TRxPathEnable, u1Tmp);
+ RTW_INFO("BT write 0xC04 = 0x%x\n", u1Tmp);
+
+ u1Tmp = rtw_read8(padapter, rOFDM1_TRxPathEnable);
+ u1Tmp &= ~(BIT1);
+ rtw_write8(padapter, rOFDM1_TRxPathEnable, u1Tmp);
+ RTW_INFO("BT write 0xD04 = 0x%x\n", u1Tmp);
+
+ }
+}
+#endif
+
+/* ---------------------------------------------------------------
+ *
+ * MAC init functions
+ *
+ * --------------------------------------------------------------- */
+
+/* Shall USB interface init this? */
+static void
+_InitInterrupt(
+ PADAPTER Adapter
+)
+{
+ u32 imr, imr_ex;
+ u8 usb_opt;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
+ struct dvobj_priv *pdev = adapter_to_dvobj(Adapter);
+#endif
+
+ /* HISR write one to clear */
+ rtw_write32(Adapter, REG_HISR_88E, 0xFFFFFFFF);
+ /* HIMR - */
+ imr = IMR_PSTIMEOUT_88E | IMR_TBDER_88E | IMR_CPWM_88E | IMR_CPWM2_88E ;
+ rtw_write32(Adapter, REG_HIMR_88E, imr);
+ pHalData->IntrMask[0] = imr;
+
+ imr_ex = IMR_TXERR_88E | IMR_RXERR_88E | IMR_TXFOVW_88E | IMR_RXFOVW_88E;
+ rtw_write32(Adapter, REG_HIMRE_88E, imr_ex);
+ pHalData->IntrMask[1] = imr_ex;
+
+#ifdef CONFIG_SUPPORT_USB_INT
+ /* REG_USB_SPECIAL_OPTION - BIT(4) */
+ /* 0; Use interrupt endpoint to upload interrupt pkt */
+ /* 1; Use bulk endpoint to upload interrupt pkt, */
+ usb_opt = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+
+ if ((IS_FULL_SPEED_USB(Adapter))
+#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
+ || (pdev->RtInPipe[REALTEK_USB_IN_INT_EP_IDX] == 0x05)
+#endif
+ )
+ usb_opt = usb_opt & (~INT_BULK_SEL);
+ else
+ usb_opt = usb_opt | (INT_BULK_SEL);
+
+ rtw_write8(Adapter, REG_USB_SPECIAL_OPTION, usb_opt);
+
+#endif/* CONFIG_SUPPORT_USB_INT */
+
+}
+
+static void
+_InitQueueReservedPage(
+ PADAPTER Adapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct registry_priv *pregistrypriv = &Adapter->registrypriv;
+ u32 outEPNum = (u32)pHalData->OutEpNumber;
+ u32 numHQ = 0;
+ u32 numLQ = 0;
+ u32 numNQ = 0;
+ u32 numPubQ = 0x00;
+ u32 value32;
+ u8 value8;
+ bool bWiFiConfig = pregistrypriv->wifi_spec;
+
+ if (bWiFiConfig || pregistrypriv->qos_opt_enable) {
+ if (pHalData->OutEpQueueSel & TX_SELE_HQ)
+ numHQ = WMM_NORMAL_PAGE_NUM_HPQ_88E;
+
+ if (pHalData->OutEpQueueSel & TX_SELE_LQ)
+ numLQ = WMM_NORMAL_PAGE_NUM_LPQ_88E;
+
+ /* NOTE: This step shall be proceed before writting REG_RQPN. */
+ if (pHalData->OutEpQueueSel & TX_SELE_NQ)
+ numNQ = WMM_NORMAL_PAGE_NUM_NPQ_88E;
+ } else {
+ if (pHalData->OutEpQueueSel & TX_SELE_HQ)
+ numHQ = NORMAL_PAGE_NUM_HPQ_88E;
+
+ if (pHalData->OutEpQueueSel & TX_SELE_LQ)
+ numLQ = NORMAL_PAGE_NUM_LPQ_88E;
+
+ /* NOTE: This step shall be proceed before writting REG_RQPN. */
+ if (pHalData->OutEpQueueSel & TX_SELE_NQ)
+ numNQ = NORMAL_PAGE_NUM_NPQ_88E;
+ }
+
+ value8 = (u8)_NPQ(numNQ);
+ rtw_write8(Adapter, REG_RQPN_NPQ, value8);
+
+ numPubQ = TX_TOTAL_PAGE_NUMBER_88E(Adapter) - numHQ - numLQ - numNQ;
+
+ /* TX DMA */
+ value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN;
+ rtw_write32(Adapter, REG_RQPN, value32);
+}
+
+static void
+_InitTxBufferBoundary(
+ PADAPTER Adapter,
+ u8 txpktbuf_bndy
+)
+{
+ struct registry_priv *pregistrypriv = &Adapter->registrypriv;
+ /* HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); */
+
+ /* u16 txdmactrl; */
+
+ rtw_write8(Adapter, REG_BCNQ_BDNY, txpktbuf_bndy);
+ rtw_write8(Adapter, REG_MGQ_BDNY, txpktbuf_bndy);
+ rtw_write8(Adapter, REG_WMAC_LBK_BF_HD, txpktbuf_bndy);
+ rtw_write8(Adapter, REG_TRXFF_BNDY, txpktbuf_bndy);
+ rtw_write8(Adapter, REG_TDECTRL + 1, txpktbuf_bndy);
+
+}
+
+static void
+_InitPageBoundary(
+ PADAPTER Adapter
+)
+{
+ /* RX Page Boundary */
+ u16 rxff_bndy = 0;
+
+ rxff_bndy = MAX_RX_DMA_BUFFER_SIZE_88E(Adapter) - 1;
+
+ rtw_write16(Adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
+}
+
+static void
+_InitNormalChipRegPriority(
+ PADAPTER Adapter,
+ u16 beQ,
+ u16 bkQ,
+ u16 viQ,
+ u16 voQ,
+ u16 mgtQ,
+ u16 hiQ
+)
+{
+ u16 value16 = (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7);
+
+ value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) |
+ _TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) |
+ _TXDMA_MGQ_MAP(mgtQ) | _TXDMA_HIQ_MAP(hiQ);
+
+ rtw_write16(Adapter, REG_TRXDMA_CTRL, value16);
+}
+
+static void
+_InitNormalChipOneOutEpPriority(
+ PADAPTER Adapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ u16 value = 0;
+ switch (pHalData->OutEpQueueSel) {
+ case TX_SELE_HQ:
+ value = QUEUE_HIGH;
+ break;
+ case TX_SELE_LQ:
+ value = QUEUE_LOW;
+ break;
+ case TX_SELE_NQ:
+ value = QUEUE_NORMAL;
+ break;
+ default:
+ /* RT_ASSERT(false,("Shall not reach here!\n")); */
+ break;
+ }
+
+ _InitNormalChipRegPriority(Adapter,
+ value,
+ value,
+ value,
+ value,
+ value,
+ value
+ );
+
+}
+
+static void
+_InitNormalChipTwoOutEpPriority(
+ PADAPTER Adapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct registry_priv *pregistrypriv = &Adapter->registrypriv;
+ u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
+
+ u16 valueHi = 0;
+ u16 valueLow = 0;
+
+ switch (pHalData->OutEpQueueSel) {
+ case (TX_SELE_HQ | TX_SELE_LQ):
+ valueHi = QUEUE_HIGH;
+ valueLow = QUEUE_LOW;
+ break;
+ case (TX_SELE_NQ | TX_SELE_LQ):
+ valueHi = QUEUE_NORMAL;
+ valueLow = QUEUE_LOW;
+ break;
+ case (TX_SELE_HQ | TX_SELE_NQ):
+ valueHi = QUEUE_HIGH;
+ valueLow = QUEUE_NORMAL;
+ break;
+ default:
+ /* RT_ASSERT(false,("Shall not reach here!\n")); */
+ break;
+ }
+
+ if (!pregistrypriv->wifi_spec) {
+ beQ = valueLow;
+ bkQ = valueLow;
+ viQ = valueHi;
+ voQ = valueHi;
+ mgtQ = valueHi;
+ hiQ = valueHi;
+ } else { /* for WMM ,CONFIG_OUT_EP_WIFI_MODE */
+ beQ = valueLow;
+ bkQ = valueHi;
+ viQ = valueHi;
+ voQ = valueLow;
+ mgtQ = valueHi;
+ hiQ = valueHi;
+ }
+
+ _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
+
+}
+
+static void
+_InitNormalChipThreeOutEpPriority(
+ PADAPTER Adapter
+)
+{
+ struct registry_priv *pregistrypriv = &Adapter->registrypriv;
+ u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
+
+ if (!pregistrypriv->wifi_spec) { /* typical setting */
+ beQ = QUEUE_LOW;
+ bkQ = QUEUE_LOW;
+ viQ = QUEUE_NORMAL;
+ voQ = QUEUE_HIGH;
+ mgtQ = QUEUE_HIGH;
+ hiQ = QUEUE_HIGH;
+ } else { /* for WMM */
+ beQ = QUEUE_LOW;
+ bkQ = QUEUE_NORMAL;
+ viQ = QUEUE_NORMAL;
+ voQ = QUEUE_HIGH;
+ mgtQ = QUEUE_HIGH;
+ hiQ = QUEUE_HIGH;
+ }
+ _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
+}
+
+static void
+_InitQueuePriority(
+ PADAPTER Adapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ switch (pHalData->OutEpNumber) {
+ case 1:
+ _InitNormalChipOneOutEpPriority(Adapter);
+ break;
+ case 2:
+ _InitNormalChipTwoOutEpPriority(Adapter);
+ break;
+ case 3:
+ _InitNormalChipThreeOutEpPriority(Adapter);
+ break;
+ default:
+ /* RT_ASSERT(false,("Shall not reach here!\n")); */
+ break;
+ }
+
+}
+
+static void
+_InitHardwareDropIncorrectBulkOut(
+ PADAPTER Adapter
+)
+{
+#ifdef ENABLE_USB_DROP_INCORRECT_OUT
+ u32 value32 = rtw_read32(Adapter, REG_TXDMA_OFFSET_CHK);
+ value32 |= DROP_DATA_EN;
+ rtw_write32(Adapter, REG_TXDMA_OFFSET_CHK, value32);
+#endif
+}
+
+static void
+_InitNetworkType(
+ PADAPTER Adapter
+)
+{
+ u32 value32;
+
+ value32 = rtw_read32(Adapter, REG_CR);
+ /* TODO: use the other function to set network type */
+ value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP);
+
+ rtw_write32(Adapter, REG_CR, value32);
+ /* RASSERT(pIoBase->rtw_read8(REG_CR + 2) == 0x2); */
+}
+
+static void
+_InitDriverInfoSize(
+ PADAPTER Adapter,
+ u8 drvInfoSize
+)
+{
+ rtw_write8(Adapter, REG_RX_DRVINFO_SZ, drvInfoSize);
+}
+
+static void
+_InitWMACSetting(
+ PADAPTER Adapter
+)
+{
+ /* u32 value32; */
+ /* u16 value16; */
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ /* pHalData->ReceiveConfig = AAP | APM | AM | AB | APP_ICV | ADF | AMF | APP_FCS | HTC_LOC_CTRL | APP_MIC | APP_PHYSTS; */
+ /* pHalData->ReceiveConfig = */
+ /* RCR_AAP | RCR_APM | RCR_AM | RCR_AB |RCR_CBSSID_DATA| RCR_CBSSID_BCN| RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | RCR_APP_MIC | RCR_APP_PHYSTS; */
+ /* don't turn on AAP, it will allow all packets to driver */
+ pHalData->ReceiveConfig = RCR_APM | RCR_AM | RCR_AB | RCR_CBSSID_DATA | RCR_CBSSID_BCN | RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | RCR_APP_MIC | RCR_APP_PHYST_RXFF;
+
+#if (1 == RTL8188E_RX_PACKET_INCLUDE_CRC)
+ pHalData->ReceiveConfig |= ACRC32;
+#endif
+
+ /* some REG_RCR will be modified later by phy_ConfigMACWithHeaderFile() */
+ rtw_write32(Adapter, REG_RCR, pHalData->ReceiveConfig);
+
+ /* Accept all multicast address */
+ rtw_write32(Adapter, REG_MAR, 0xFFFFFFFF);
+ rtw_write32(Adapter, REG_MAR + 4, 0xFFFFFFFF);
+
+ /* Accept all data frames */
+ /* value16 = 0xFFFF; */
+ /* rtw_write16(Adapter, REG_RXFLTMAP2, value16); */
+
+ /* 2010.09.08 hpfan */
+ /* Since ADF is removed from RCR, ps-poll will not be indicate to driver, */
+ /* RxFilterMap should mask ps-poll to gurantee AP mode can rx ps-poll. */
+ /* value16 = 0x400; */
+ /* rtw_write16(Adapter, REG_RXFLTMAP1, value16); */
+
+ /* Accept all management frames */
+ /* value16 = 0xFFFF; */
+ /* rtw_write16(Adapter, REG_RXFLTMAP0, value16); */
+
+ /* enable RX_SHIFT bits */
+ /* rtw_write8(Adapter, REG_TRXDMA_CTRL, rtw_read8(Adapter, REG_TRXDMA_CTRL)|BIT(1)); */
+
+}
+
+static void
+_InitAdaptiveCtrl(
+ PADAPTER Adapter
+)
+{
+ u16 value16;
+ u32 value32;
+
+ /* Response Rate Set */
+ value32 = rtw_read32(Adapter, REG_RRSR);
+ value32 &= ~RATE_BITMAP_ALL;
+ value32 |= RATE_RRSR_CCK_ONLY_1M;
+ rtw_write32(Adapter, REG_RRSR, value32);
+
+ /* CF-END Threshold */
+ /* m_spIoBase->rtw_write8(REG_CFEND_TH, 0x1); */
+
+ /* SIFS (used in NAV) */
+ value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
+ rtw_write16(Adapter, REG_SPEC_SIFS, value16);
+
+ /* Retry Limit */
+ value16 = _LRL(0x30) | _SRL(0x30);
+ rtw_write16(Adapter, REG_RL, value16);
+
+}
+
+static void
+_InitRateFallback(
+ PADAPTER Adapter
+)
+{
+ /* Set Data Auto Rate Fallback Retry Count register. */
+ rtw_write32(Adapter, REG_DARFRC, 0x00000000);
+ rtw_write32(Adapter, REG_DARFRC + 4, 0x10080404);
+ rtw_write32(Adapter, REG_RARFRC, 0x04030201);
+ rtw_write32(Adapter, REG_RARFRC + 4, 0x08070605);
+
+}
+
+static void
+_InitEDCA(
+ PADAPTER Adapter
+)
+{
+ /* Set Spec SIFS (used in NAV) */
+ rtw_write16(Adapter, REG_SPEC_SIFS, 0x100a);
+ rtw_write16(Adapter, REG_MAC_SPEC_SIFS, 0x100a);
+
+ /* Set SIFS for CCK */
+ rtw_write16(Adapter, REG_SIFS_CTX, 0x100a);
+
+ /* Set SIFS for OFDM */
+ rtw_write16(Adapter, REG_SIFS_TRX, 0x100a);
+
+ /* TXOP */
+ rtw_write32(Adapter, REG_EDCA_BE_PARAM, 0x005EA42B);
+ rtw_write32(Adapter, REG_EDCA_BK_PARAM, 0x0000A44F);
+ rtw_write32(Adapter, REG_EDCA_VI_PARAM, 0x005EA324);
+ rtw_write32(Adapter, REG_EDCA_VO_PARAM, 0x002FA226);
+}
+
+static void
+_InitBeaconMaxError(
+ PADAPTER Adapter,
+ bool InfraMode
+)
+{
+
+}
+
+#ifdef CONFIG_LED
+static void _InitHWLed(PADAPTER Adapter)
+{
+ struct led_priv *pledpriv = &(Adapter->ledpriv);
+
+ if (pledpriv->LedStrategy != HW_LED)
+ return;
+
+ /* HW led control
+ * to do ....
+ * must consider cases of antenna diversity/ commbo card/solo card/mini card */
+
+}
+#endif /* CONFIG_LED */
+
+static void
+_InitRDGSetting(
+ PADAPTER Adapter
+)
+{
+ rtw_write8(Adapter, REG_RD_CTRL, 0xFF);
+ rtw_write16(Adapter, REG_RD_NAV_NXT, 0x200);
+ rtw_write8(Adapter, REG_RD_RESP_PKT_TH, 0x05);
+}
+
+static void
+_InitRetryFunction(
+ PADAPTER Adapter
+)
+{
+ u8 value8;
+
+ value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL);
+ value8 |= EN_AMPDU_RTY_NEW;
+ rtw_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
+
+ /* Set ACK timeout */
+ rtw_write8(Adapter, REG_ACKTO, 0x40);
+}
+
+/*-----------------------------------------------------------------------------
+ * Function: usb_AggSettingTxUpdate()
+ *
+ * Overview: Seperate TX/RX parameters update independent for TP detection and
+ * dynamic TX/RX aggreagtion parameters update.
+ *
+ * Input: PADAPTER
+ *
+ * Output/Return: NONE
+ *
+ * Revised History:
+ * When Who Remark
+ * 12/10/2010 MHC Seperate to smaller function.
+ *
+ *---------------------------------------------------------------------------*/
+static void
+usb_AggSettingTxUpdate(
+ PADAPTER Adapter
+)
+{
+#ifdef CONFIG_USB_TX_AGGREGATION
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ /* PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); */
+ u32 value32;
+
+ if (Adapter->registrypriv.wifi_spec)
+ pHalData->UsbTxAggMode = false;
+
+ if (pHalData->UsbTxAggMode) {
+ value32 = rtw_read32(Adapter, REG_TDECTRL);
+ value32 = value32 & ~(BLK_DESC_NUM_MASK << BLK_DESC_NUM_SHIFT);
+ value32 |= ((pHalData->UsbTxAggDescNum & BLK_DESC_NUM_MASK) << BLK_DESC_NUM_SHIFT);
+
+ rtw_write32(Adapter, REG_TDECTRL, value32);
+ }
+
+#endif
+} /* usb_AggSettingTxUpdate */
+
+/*-----------------------------------------------------------------------------
+ * Function: usb_AggSettingRxUpdate()
+ *
+ * Overview: Seperate TX/RX parameters update independent for TP detection and
+ * dynamic TX/RX aggreagtion parameters update.
+ *
+ * Input: PADAPTER
+ *
+ * Output/Return: NONE
+ *
+ * Revised History:
+ * When Who Remark
+ * 12/10/2010 MHC Seperate to smaller function.
+ *
+ *---------------------------------------------------------------------------*/
+static void
+usb_AggSettingRxUpdate(
+ PADAPTER Adapter
+)
+{
+#ifdef CONFIG_USB_RX_AGGREGATION
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ /* PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); */
+ u8 valueDMA;
+ u8 valueUSB;
+
+ valueDMA = rtw_read8(Adapter, REG_TRXDMA_CTRL);
+ valueUSB = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+
+ switch (pHalData->rxagg_mode) {
+ case RX_AGG_DMA:
+ valueDMA |= RXDMA_AGG_EN;
+ valueUSB &= ~USB_AGG_EN;
+ break;
+ case RX_AGG_USB:
+ valueDMA &= ~RXDMA_AGG_EN;
+ valueUSB |= USB_AGG_EN;
+ break;
+ case RX_AGG_MIX:
+ valueDMA |= RXDMA_AGG_EN;
+ valueUSB |= USB_AGG_EN;
+ break;
+ case RX_AGG_DISABLE:
+ default:
+ valueDMA &= ~RXDMA_AGG_EN;
+ valueUSB &= ~USB_AGG_EN;
+ break;
+ }
+
+ rtw_write8(Adapter, REG_TRXDMA_CTRL, valueDMA);
+ rtw_write8(Adapter, REG_USB_SPECIAL_OPTION, valueUSB);
+
+ switch (pHalData->rxagg_mode) {
+ case RX_AGG_DMA:
+ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, pHalData->rxagg_dma_size);
+ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH + 1, pHalData->rxagg_dma_timeout);
+ break;
+ case RX_AGG_USB:
+ rtw_write8(Adapter, REG_USB_AGG_TH, pHalData->rxagg_usb_size);
+ rtw_write8(Adapter, REG_USB_AGG_TO, pHalData->rxagg_usb_timeout);
+ break;
+ case RX_AGG_MIX:
+ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, pHalData->rxagg_dma_size);
+ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH + 1, pHalData->rxagg_dma_timeout & 0x1F); /* 0x280[12:8] */
+
+ rtw_write8(Adapter, REG_USB_AGG_TH, pHalData->rxagg_usb_size);
+ rtw_write8(Adapter, REG_USB_AGG_TO, pHalData->rxagg_usb_timeout);
+
+ break;
+ case RX_AGG_DISABLE:
+ default:
+ /* TODO: */
+ break;
+ }
+
+ switch (PBP_128) {
+ case PBP_128:
+ pHalData->HwRxPageSize = 128;
+ break;
+ case PBP_64:
+ pHalData->HwRxPageSize = 64;
+ break;
+ case PBP_256:
+ pHalData->HwRxPageSize = 256;
+ break;
+ case PBP_512:
+ pHalData->HwRxPageSize = 512;
+ break;
+ case PBP_1024:
+ pHalData->HwRxPageSize = 1024;
+ break;
+ default:
+ /* RT_ASSERT(false, ("RX_PAGE_SIZE_REG_VALUE definition is incorrect!\n")); */
+ break;
+ }
+#endif
+} /* usb_AggSettingRxUpdate */
+
+static void
+InitUsbAggregationSetting(
+ PADAPTER Adapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ /* Tx aggregation setting */
+ usb_AggSettingTxUpdate(Adapter);
+
+ /* Rx aggregation setting */
+ usb_AggSettingRxUpdate(Adapter);
+
+ /* 201/12/10 MH Add for USB agg mode dynamic switch. */
+ pHalData->UsbRxHighSpeedMode = false;
+}
+
+static void
+HalRxAggr8188EUsb(
+ PADAPTER Adapter,
+ bool Value
+)
+{
+}
+
+/*-----------------------------------------------------------------------------
+ * Function: USB_AggModeSwitch()
+ *
+ * Overview: When RX traffic is more than 40M, we need to adjust some parameters to increase
+ * RX speed by increasing batch indication size. This will decrease TCP ACK speed, we
+ * need to monitor the influence of FTP/network share.
+ * For TX mode, we are still ubder investigation.
+ *
+ * Input: PADAPTER
+ *
+ * Output: NONE
+ *
+ * Return: NONE
+ *
+ * Revised History:
+ * When Who Remark
+ * 12/10/2010 MHC Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+static void
+USB_AggModeSwitch(
+ PADAPTER Adapter
+)
+{
+} /* USB_AggModeSwitch */
+
+static void
+_InitOperationMode(
+ PADAPTER Adapter
+)
+{
+}
+
+static void
+_InitBeaconParameters(
+ PADAPTER Adapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ rtw_write16(Adapter, REG_BCN_CTRL, 0x1010);
+
+ /* TODO: Remove these magic number */
+ /* TBTT setup time:128 us */
+ rtw_write8(Adapter, REG_TBTT_PROHIBIT, 0x04);
+
+ /*TBTT hold time :4ms 0x540[19:8]*/
+ rtw_write8(Adapter, REG_TBTT_PROHIBIT + 1,
+ TBTT_PROBIHIT_HOLD_TIME & 0xFF);
+ rtw_write8(Adapter, REG_TBTT_PROHIBIT + 2,
+ (rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROBIHIT_HOLD_TIME >> 8));
+ rtw_write8(Adapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME_8188E);/* 5ms */
+ rtw_write8(Adapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME_8188E); /* 2ms */
+
+ /* Suggested by designer timchen. Change beacon AIFS to the largest number */
+ /* beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
+ rtw_write16(Adapter, REG_BCNTCFG, 0x660F);
+
+ pHalData->RegBcnCtrlVal = rtw_read8(Adapter, REG_BCN_CTRL);
+ pHalData->RegTxPause = rtw_read8(Adapter, REG_TXPAUSE);
+ pHalData->RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2);
+ pHalData->RegReg542 = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2);
+ pHalData->RegCR_1 = rtw_read8(Adapter, REG_CR + 1);
+}
+
+static void
+_InitRFType(
+ PADAPTER Adapter
+)
+{
+ struct registry_priv *pregpriv = &Adapter->registrypriv;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+#if DISABLE_BB_RF
+ pHalData->rf_chip = RF_PSEUDO_11N;
+ return;
+#endif
+ pHalData->rf_chip = RF_6052;
+
+ /* TODO: Consider that EEPROM set 92CU to 1T1R later. */
+ /* Force to overwrite setting according to chip version. Ignore EEPROM setting. */
+ /* pHalData->RF_Type = is92CU ? RF_2T2R : RF_1T1R; */
+ RTW_INFO("Set RF Chip ID to RF_6052 and RF type to %d.\n", pHalData->rf_type);
+
+}
+
+static void
+_BeaconFunctionEnable(
+ PADAPTER Adapter,
+ bool Enable,
+ bool Linked
+)
+{
+ rtw_write8(Adapter, REG_BCN_CTRL, (BIT4 | BIT3 | BIT1));
+ /* SetBcnCtrlReg(Adapter, (BIT4 | BIT3 | BIT1), 0x00); */
+
+ rtw_write8(Adapter, REG_RD_CTRL + 1, 0x6F);
+}
+
+/* Set CCK and OFDM Block "ON" */
+static void _BBTurnOnBlock(
+ PADAPTER Adapter
+)
+{
+#if (DISABLE_BB_RF)
+ return;
+#endif
+
+ phy_set_bb_reg(Adapter, rFPGA0_RFMOD, bCCKEn, 0x1);
+ phy_set_bb_reg(Adapter, rFPGA0_RFMOD, bOFDMEn, 0x1);
+}
+
+static void _RfPowerSave(
+ PADAPTER Adapter
+)
+{
+}
+
+enum {
+ Antenna_Lfet = 1,
+ Antenna_Right = 2,
+};
+
+static void
+_InitAntenna_Selection(PADAPTER Adapter)
+{
+#ifdef CONFIG_ANTENNA_DIVERSITY
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ if (pHalData->AntDivCfg == 0)
+ return;
+ RTW_INFO("==> %s ....\n", __func__);
+
+ rtw_write32(Adapter, REG_LEDCFG0, rtw_read32(Adapter, REG_LEDCFG0) | BIT23);
+ phy_set_bb_reg(Adapter, rFPGA0_XAB_RFParameter, BIT13, 0x01);
+#endif
+}
+
+/*
+ * 2010/08/26 MH Add for selective suspend mode check.
+ * If Efuse 0x0e bit1 is not enabled, we can not support selective suspend for Minicard and
+ * slim card.
+ * */
+static void
+HalDetectSelectiveSuspendMode(
+ PADAPTER Adapter
+)
+{
+} /* HalDetectSelectiveSuspendMode */
+
+rt_rf_power_state RfOnOffDetect(PADAPTER pAdapter)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(pAdapter);
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+ u8 val8;
+ rt_rf_power_state rfpowerstate = rf_off;
+
+ if (pwrctl->bHWPowerdown) {
+ val8 = rtw_read8(pAdapter, REG_HSISR);
+ RTW_INFO("pwrdown, 0x5c(BIT7)=%02x\n", val8);
+ rfpowerstate = (val8 & BIT7) ? rf_off : rf_on;
+ } else { /* rf on/off */
+ rtw_write8(pAdapter, REG_MAC_PINMUX_CFG, rtw_read8(pAdapter, REG_MAC_PINMUX_CFG) & ~(BIT3));
+ val8 = rtw_read8(pAdapter, REG_GPIO_IO_SEL);
+ RTW_INFO("GPIO_IN=%02x\n", val8);
+ rfpowerstate = (val8 & BIT3) ? rf_on : rf_off;
+ }
+ return rfpowerstate;
+} /* HalDetectPwrDownMode */
+
+void _ps_open_RF(_adapter *padapter);
+
+static u32 rtl8188eu_hal_init(PADAPTER Adapter)
+{
+ u8 value8 = 0;
+ u16 value16;
+ u8 txpktbuf_bndy;
+ u32 status = _SUCCESS;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(Adapter);
+ struct registry_priv *pregistrypriv = &Adapter->registrypriv;
+
+ rt_rf_power_state eRfPowerStateToSet;
+#ifdef CONFIG_BT_COEXIST
+ struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist);
+#endif
+
+ u32 init_start_time = jiffies;
+
+#ifdef DBG_HAL_INIT_PROFILING
+
+ enum HAL_INIT_STAGES {
+ HAL_INIT_STAGES_BEGIN = 0,
+ HAL_INIT_STAGES_INIT_PW_ON,
+ HAL_INIT_STAGES_MISC01,
+ HAL_INIT_STAGES_DOWNLOAD_FW,
+ HAL_INIT_STAGES_MAC,
+ HAL_INIT_STAGES_BB,
+ HAL_INIT_STAGES_RF,
+ HAL_INIT_STAGES_EFUSE_PATCH,
+ HAL_INIT_STAGES_INIT_LLTT,
+
+ HAL_INIT_STAGES_MISC02,
+ HAL_INIT_STAGES_TURN_ON_BLOCK,
+ HAL_INIT_STAGES_INIT_SECURITY,
+ HAL_INIT_STAGES_MISC11,
+ HAL_INIT_STAGES_INIT_HAL_DM,
+ /* HAL_INIT_STAGES_RF_PS, */
+ HAL_INIT_STAGES_IQK,
+ HAL_INIT_STAGES_PW_TRACK,
+ HAL_INIT_STAGES_LCK,
+ /* HAL_INIT_STAGES_MISC21, */
+ /* HAL_INIT_STAGES_INIT_PABIAS, */
+#ifdef CONFIG_BT_COEXIST
+ HAL_INIT_STAGES_BT_COEXIST,
+#endif
+ /* HAL_INIT_STAGES_ANTENNA_SEL, */
+ /* HAL_INIT_STAGES_MISC31, */
+ HAL_INIT_STAGES_END,
+ HAL_INIT_STAGES_NUM
+ };
+
+ char *hal_init_stages_str[] = {
+ "HAL_INIT_STAGES_BEGIN",
+ "HAL_INIT_STAGES_INIT_PW_ON",
+ "HAL_INIT_STAGES_MISC01",
+ "HAL_INIT_STAGES_DOWNLOAD_FW",
+ "HAL_INIT_STAGES_MAC",
+ "HAL_INIT_STAGES_BB",
+ "HAL_INIT_STAGES_RF",
+ "HAL_INIT_STAGES_EFUSE_PATCH",
+ "HAL_INIT_STAGES_INIT_LLTT",
+ "HAL_INIT_STAGES_MISC02",
+ "HAL_INIT_STAGES_TURN_ON_BLOCK",
+ "HAL_INIT_STAGES_INIT_SECURITY",
+ "HAL_INIT_STAGES_MISC11",
+ "HAL_INIT_STAGES_INIT_HAL_DM",
+ /* "HAL_INIT_STAGES_RF_PS", */
+ "HAL_INIT_STAGES_IQK",
+ "HAL_INIT_STAGES_PW_TRACK",
+ "HAL_INIT_STAGES_LCK",
+ /* "HAL_INIT_STAGES_MISC21", */
+#ifdef CONFIG_BT_COEXIST
+ "HAL_INIT_STAGES_BT_COEXIST",
+#endif
+ /* "HAL_INIT_STAGES_ANTENNA_SEL", */
+ /* "HAL_INIT_STAGES_MISC31", */
+ "HAL_INIT_STAGES_END",
+ };
+
+ int hal_init_profiling_i;
+ u32 hal_init_stages_timestamp[HAL_INIT_STAGES_NUM]; /* used to record the time of each stage's starting point */
+
+ for (hal_init_profiling_i = 0; hal_init_profiling_i < HAL_INIT_STAGES_NUM; hal_init_profiling_i++)
+ hal_init_stages_timestamp[hal_init_profiling_i] = 0;
+
+#define HAL_INIT_PROFILE_TAG(stage) do { hal_init_stages_timestamp[(stage)] = jiffies; } while (0)
+#else
+#define HAL_INIT_PROFILE_TAG(stage) do {} while (0)
+#endif /* DBG_HAL_INIT_PROFILING */
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BEGIN);
+
+ if (pwrctrlpriv->bkeepfwalive) {
+ _ps_open_RF(Adapter);
+
+ if (pHalData->bIQKInitialized) {
+ /* PHY_IQCalibrate(padapter, true); */
+ phy_iq_calibrate_8188e(Adapter, true);
+ } else {
+ /* PHY_IQCalibrate(padapter, false); */
+ phy_iq_calibrate_8188e(Adapter, false);
+ pHalData->bIQKInitialized = true;
+ }
+
+ /* dm_check_txpowertracking(padapter);
+ * phy_lc_calibrate(padapter); */
+ odm_txpowertracking_check(&pHalData->odmpriv);
+ phy_lc_calibrate_8188e(&pHalData->odmpriv);
+
+ goto exit;
+ }
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PW_ON);
+ status = rtw_hal_power_on(Adapter);
+ if (status == _FAIL) {
+ goto exit;
+ }
+
+ /* Set RF type for BB/RF configuration */
+ _InitRFType(Adapter);/* ->_ReadRFType() */
+
+ /* Save target channel */
+ /* <Roger_Notes> Current Channel will be updated again later. */
+ pHalData->current_channel = 6;/* default set to 6 */
+ if (pwrctrlpriv->reg_rfoff == true)
+ pwrctrlpriv->rf_pwrstate = rf_off;
+
+ /* 2010/08/09 MH We need to check if we need to turnon or off RF after detecting */
+ /* HW GPIO pin. Before PHY_RFConfig8192C. */
+ /* HalDetectPwrDownMode(Adapter); */
+ /* 2010/08/26 MH If Efuse does not support sective suspend then disable the function. */
+ /*HalDetectSelectiveSuspendMode(Adapter);*/
+
+ if (!pregistrypriv->wifi_spec)
+ txpktbuf_bndy = TX_PAGE_BOUNDARY_88E(Adapter);
+ else {
+ /* for WMM */
+ txpktbuf_bndy = WMM_NORMAL_TX_PAGE_BOUNDARY_88E(Adapter);
+ }
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC01);
+ _InitQueueReservedPage(Adapter);
+ _InitQueuePriority(Adapter);
+ _InitPageBoundary(Adapter);
+ _InitTransferPageSize(Adapter);
+
+#ifdef CONFIG_IOL_IOREG_CFG
+ _InitTxBufferBoundary(Adapter, 0);
+#endif
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_DOWNLOAD_FW);
+ if (Adapter->registrypriv.mp_mode == 0) {
+ status = rtl8188e_FirmwareDownload(Adapter, false);
+ if (status != _SUCCESS) {
+ RTW_INFO("%s: Download Firmware failed!!\n", __func__);
+ Adapter->bFWReady = false;
+ pHalData->fw_ractrl = false;
+ return status;
+ } else {
+ Adapter->bFWReady = true;
+#ifdef CONFIG_SFW_SUPPORTED
+ pHalData->fw_ractrl = IS_VENDOR_8188E_I_CUT_SERIES(Adapter) ? true : false;
+#else
+ pHalData->fw_ractrl = false;
+#endif
+ }
+ }
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MAC);
+#if (HAL_MAC_ENABLE == 1)
+ status = PHY_MACConfig8188E(Adapter);
+ if (status == _FAIL) {
+ RTW_INFO(" ### Failed to init MAC ......\n ");
+ goto exit;
+ }
+#endif
+
+ /* */
+ /* d. Initialize BB related configurations. */
+ /* */
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BB);
+#if (HAL_BB_ENABLE == 1)
+ status = PHY_BBConfig8188E(Adapter);
+ if (status == _FAIL) {
+ RTW_INFO(" ### Failed to init BB ......\n ");
+ goto exit;
+ }
+#endif
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_RF);
+#if (HAL_RF_ENABLE == 1)
+ status = PHY_RFConfig8188E(Adapter);
+ if (status == _FAIL) {
+ RTW_INFO(" ### Failed to init RF ......\n ");
+ goto exit;
+ }
+#endif
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_EFUSE_PATCH);
+#if defined(CONFIG_IOL_EFUSE_PATCH)
+ status = rtl8188e_iol_efuse_patch(Adapter);
+ if (status == _FAIL) {
+ RTW_INFO("%s rtl8188e_iol_efuse_patch failed\n", __func__);
+ goto exit;
+ }
+#endif
+
+ _InitTxBufferBoundary(Adapter, txpktbuf_bndy);
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_LLTT);
+ status = InitLLTTable(Adapter, txpktbuf_bndy);
+ if (status == _FAIL) {
+ goto exit;
+ }
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC02);
+ /* Get Rx PHY status in order to report RSSI and others. */
+ _InitDriverInfoSize(Adapter, DRVINFO_SZ);
+
+ _InitInterrupt(Adapter);
+ _InitNetworkType(Adapter);/* set msr */
+ _InitWMACSetting(Adapter);
+ _InitAdaptiveCtrl(Adapter);
+ _InitEDCA(Adapter);
+ /* _InitRateFallback(Adapter); */ /* just follow MP Team ???Georgia */
+ _InitRetryFunction(Adapter);
+ InitUsbAggregationSetting(Adapter);
+ _InitOperationMode(Adapter);/* todo */
+ _InitBeaconParameters(Adapter);
+ _InitBeaconMaxError(Adapter, true);
+
+ /* */
+ /* Init CR MACTXEN, MACRXEN after setting RxFF boundary REG_TRXFF_BNDY to patch */
+ /* Hw bug which Hw initials RxFF boundry size to a value which is larger than the real Rx buffer size in 88E. */
+ /* */
+ /* Enable MACTXEN/MACRXEN block */
+ value16 = rtw_read16(Adapter, REG_CR);
+ value16 |= (MACTXEN | MACRXEN);
+ rtw_write8(Adapter, REG_CR, value16);
+
+ _InitHardwareDropIncorrectBulkOut(Adapter);
+
+ if (pHalData->bRDGEnable)
+ _InitRDGSetting(Adapter);
+
+ /* Enable TX Report & Tx Report Timer */
+ value8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+ rtw_write8(Adapter, REG_TX_RPT_CTRL, (value8 | BIT1 | BIT0));
+
+#if (RATE_ADAPTIVE_SUPPORT == 1)
+ if (!pHalData->fw_ractrl) {
+ /* Set MAX RPT MACID */
+ rtw_write8(Adapter, REG_TX_RPT_CTRL + 1, 2); /* FOR sta mode ,0: bc/mc ,1:AP */
+ /* Tx RPT Timer. Unit: 32us */
+ rtw_write16(Adapter, REG_TX_RPT_TIME, 0xCdf0);
+ } else
+#endif
+ {
+ /* disable tx rpt */
+ rtw_write8(Adapter, REG_TX_RPT_CTRL + 1, 0); /* FOR sta mode ,0: bc/mc ,1:AP */
+ }
+
+#ifdef CONFIG_TX_EARLY_MODE
+ if (pHalData->bEarlyModeEnable) {
+
+ value8 = rtw_read8(Adapter, REG_EARLY_MODE_CONTROL);
+#if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1
+ value8 = value8 | 0x1f;
+#else
+ value8 = value8 | 0xf;
+#endif
+ rtw_write8(Adapter, REG_EARLY_MODE_CONTROL, value8);
+
+ rtw_write8(Adapter, REG_EARLY_MODE_CONTROL + 3, 0x80);
+
+ value8 = rtw_read8(Adapter, REG_TCR + 1);
+ value8 = value8 | 0x40;
+ rtw_write8(Adapter, REG_TCR + 1, value8);
+ } else
+#endif
+ {
+ rtw_write8(Adapter, REG_EARLY_MODE_CONTROL, 0);
+ }
+
+ rtw_write32(Adapter, REG_MACID_NO_LINK_0, 0xFFFFFFFF);
+ rtw_write32(Adapter, REG_MACID_NO_LINK_1, 0xFFFFFFFF);
+
+#if defined(CONFIG_CONCURRENT_MODE) || defined(CONFIG_TX_MCAST2UNI)
+
+#ifdef CONFIG_CHECK_AC_LIFETIME
+ /* Enable lifetime check for the four ACs */
+ rtw_write8(Adapter, REG_LIFETIME_CTRL, rtw_read8(Adapter, REG_LIFETIME_CTRL) | 0x0f);
+#endif /* CONFIG_CHECK_AC_LIFETIME */
+
+#ifdef CONFIG_TX_MCAST2UNI
+ rtw_write16(Adapter, REG_PKT_VO_VI_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */
+ rtw_write16(Adapter, REG_PKT_BE_BK_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */
+#else /* CONFIG_TX_MCAST2UNI */
+ rtw_write16(Adapter, REG_PKT_VO_VI_LIFE_TIME, 0x3000); /* unit: 256us. 3s */
+ rtw_write16(Adapter, REG_PKT_BE_BK_LIFE_TIME, 0x3000); /* unit: 256us. 3s */
+#endif /* CONFIG_TX_MCAST2UNI */
+#endif /* CONFIG_CONCURRENT_MODE || CONFIG_TX_MCAST2UNI */
+
+#ifdef CONFIG_LED
+ _InitHWLed(Adapter);
+#endif /* CONFIG_LED */
+
+ /* */
+ /* Joseph Note: Keep RfRegChnlVal for later use. */
+ /* */
+ pHalData->RfRegChnlVal[0] = phy_query_rf_reg(Adapter, 0, RF_CHNLBW, bRFRegOffsetMask);
+ pHalData->RfRegChnlVal[1] = phy_query_rf_reg(Adapter, 1, RF_CHNLBW, bRFRegOffsetMask);
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_TURN_ON_BLOCK);
+ _BBTurnOnBlock(Adapter);
+ /* NicIFSetMacAddress(padapter, padapter->PermanentAddress); */
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_SECURITY);
+ invalidate_cam_all(Adapter);
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC11);
+ /* 2010/12/17 MH We need to set TX power according to EFUSE content at first. */
+ PHY_SetTxPowerLevel8188E(Adapter, pHalData->current_channel);
+
+ /* Move by Neo for USB SS to below setp
+ * _RfPowerSave(Adapter); */
+
+ _InitAntenna_Selection(Adapter);
+
+ /* */
+ /* Disable BAR, suggested by Scott */
+ /* 2010.04.09 add by hpfan */
+ /* */
+ rtw_write32(Adapter, REG_BAR_MODE_CTRL, 0x0201ffff);
+
+ /* HW SEQ CTRL */
+ /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */
+ rtw_write8(Adapter, REG_HWSEQ_CTRL, 0xFF);
+
+ PHY_SetRFEReg_8188E(Adapter);
+
+ if (pregistrypriv->wifi_spec) {
+ rtw_write16(Adapter, REG_FAST_EDCA_CTRL , 0);
+ /* Nav limit , suggest by scott */
+ rtw_write8(Adapter, REG_NAV_UPPER, 0x0);
+ }
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_HAL_DM);
+ rtl8188e_InitHalDm(Adapter);
+
+#if (MP_DRIVER == 1)
+ if (Adapter->registrypriv.mp_mode == 1) {
+ Adapter->mppriv.channel = pHalData->current_channel;
+ MPT_InitializeAdapter(Adapter, Adapter->mppriv.channel);
+ } else
+#endif /* #if (MP_DRIVER == 1) */
+ {
+ /* */
+ /* 2010/08/11 MH Merge from 8192SE for Minicard init. We need to confirm current radio status */
+ /* and then decide to enable RF or not.!!!??? For Selective suspend mode. We may not */
+ /* call init_adapter. May cause some problem?? */
+ /* */
+ /* Fix the bug that Hw/Sw radio off before S3/S4, the RF off action will not be executed */
+ /* in MgntActSet_RF_State() after wake up, because the value of pHalData->eRFPowerState */
+ /* is the same as eRfOff, we should change it to eRfOn after we config RF parameters. */
+ /* Added by tynli. 2010.03.30. */
+ pwrctrlpriv->rf_pwrstate = rf_on;
+
+ if (!pHalData->fw_ractrl) {
+ /* enable Tx report. */
+ rtw_write8(Adapter, REG_FWHW_TXQ_CTRL + 1, 0x0F);
+ /* tynli_test_tx_report. */
+ rtw_write16(Adapter, REG_TX_RPT_TIME, 0x3DF0);
+ }
+
+ /* Suggested by SD1 pisa. Added by tynli. 2011.10.21. */
+ rtw_write8(Adapter, REG_EARLY_MODE_CONTROL + 3, 0x01); /* Pretx_en, for WEP/TKIP SEC */
+
+ /* enable tx DMA to drop the redundate data of packet */
+ rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK) | DROP_DATA_EN));
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK);
+ /* 2010/08/26 MH Merge from 8192CE. */
+ if (pwrctrlpriv->rf_pwrstate == rf_on) {
+ if (pHalData->bIQKInitialized)
+ phy_iq_calibrate_8188e(Adapter, true);
+ else {
+ phy_iq_calibrate_8188e(Adapter, false);
+ pHalData->bIQKInitialized = true;
+ }
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_PW_TRACK);
+
+ odm_txpowertracking_check(&pHalData->odmpriv);
+
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_LCK);
+ phy_lc_calibrate_8188e(&pHalData->odmpriv);
+ }
+ }
+
+ /* HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PABIAS);
+ * _InitPABias(Adapter); */
+ rtw_write8(Adapter, REG_USB_HRPWM, 0);
+
+#ifdef CONFIG_XMIT_ACK
+ /* ack for xmit mgmt frames. */
+ rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, rtw_read32(Adapter, REG_FWHW_TXQ_CTRL) | BIT(12));
+#endif /* CONFIG_XMIT_ACK */
+
+exit:
+ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END);
+
+ RTW_INFO("%s in %dms\n", __func__, rtw_get_passing_time_ms(init_start_time));
+
+#ifdef DBG_HAL_INIT_PROFILING
+ hal_init_stages_timestamp[HAL_INIT_STAGES_END] = jiffies;
+
+ for (hal_init_profiling_i = 0; hal_init_profiling_i < HAL_INIT_STAGES_NUM - 1; hal_init_profiling_i++) {
+ RTW_INFO("DBG_HAL_INIT_PROFILING: %35s, %u, %5u, %5u\n"
+ , hal_init_stages_str[hal_init_profiling_i]
+ , hal_init_stages_timestamp[hal_init_profiling_i]
+ , (hal_init_stages_timestamp[hal_init_profiling_i + 1] - hal_init_stages_timestamp[hal_init_profiling_i])
+ , rtw_get_time_interval_ms(hal_init_stages_timestamp[hal_init_profiling_i], hal_init_stages_timestamp[hal_init_profiling_i + 1])
+ );
+ }
+#endif
+
+ return status;
+}
+
+void _ps_open_RF(_adapter *padapter)
+{
+ /* here call with bRegSSPwrLvl 1, bRegSSPwrLvl 2 needs to be verified */
+ /* phy_SsPwrSwitch92CU(padapter, rf_on, 1); */
+}
+
+static void _ps_close_RF(_adapter *padapter)
+{
+ /* here call with bRegSSPwrLvl 1, bRegSSPwrLvl 2 needs to be verified */
+ /* phy_SsPwrSwitch92CU(padapter, rf_off, 1); */
+}
+
+static void
+hal_poweroff_8188eu(
+ PADAPTER Adapter
+)
+{
+
+ u8 val8;
+ u16 val16;
+ u32 val32;
+ u8 bMacPwrCtrlOn = false;
+
+ rtw_hal_get_hwreg(Adapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+ if (bMacPwrCtrlOn == false)
+ return ;
+
+ /* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */
+ val8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+ rtw_write8(Adapter, REG_TX_RPT_CTRL, val8 & (~BIT1));
+
+ /* stop rx */
+ rtw_write8(Adapter, REG_CR, 0x0);
+
+ /* Run LPS WL RFOFF flow */
+ HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_LPS_ENTER_FLOW);
+
+ /* 2. 0x1F[7:0] = 0 */ /* turn off RF */
+ /* rtw_write8(Adapter, REG_RF_CTRL, 0x00); */
+
+ val8 = rtw_read8(Adapter, REG_MCUFWDL);
+ if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */
+ /* _8051Reset88E(padapter); */
+
+ /* Reset MCU 0x2[10]=0. */
+ val8 = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1);
+ val8 &= ~BIT(2); /* 0x2[10], FEN_CPUEN */
+ rtw_write8(Adapter, REG_SYS_FUNC_EN + 1, val8);
+ }
+
+ /* val8 = rtw_read8(Adapter, REG_SYS_FUNC_EN+1); */
+ /* val8 &= ~BIT(2); */ /* 0x2[10], FEN_CPUEN */
+ /* rtw_write8(Adapter, REG_SYS_FUNC_EN+1, val8); */
+
+ /* MCUFWDL 0x80[1:0]=0 */
+ /* reset MCU ready status */
+ rtw_write8(Adapter, REG_MCUFWDL, 0);
+
+ /* YJ,add,111212 */
+ /* Disable 32k */
+ val8 = rtw_read8(Adapter, REG_32K_CTRL);
+ rtw_write8(Adapter, REG_32K_CTRL, val8 & (~BIT0));
+
+ /* Card disable power action flow */
+ HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_DISABLE_FLOW);
+
+ /* Reset MCU IO Wrapper */
+ val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+ rtw_write8(Adapter, REG_RSV_CTRL + 1, (val8 & (~BIT3)));
+ val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+ rtw_write8(Adapter, REG_RSV_CTRL + 1, val8 | BIT3);
+
+ /* YJ,test add, 111207. For Power Consumption. */
+ val8 = rtw_read8(Adapter, GPIO_IN);
+ rtw_write8(Adapter, GPIO_OUT, val8);
+ rtw_write8(Adapter, GPIO_IO_SEL, 0xFF);/* Reg0x46 */
+
+ val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL);
+ /* rtw_write8(Adapter, REG_GPIO_IO_SEL, (val8<<4)|val8); */
+ rtw_write8(Adapter, REG_GPIO_IO_SEL, (val8 << 4));
+ val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1);
+ rtw_write8(Adapter, REG_GPIO_IO_SEL + 1, val8 | 0x0F); /* Reg0x43 */
+ rtw_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */
+
+ Adapter->bFWReady = false;
+
+ bMacPwrCtrlOn = false;
+ rtw_hal_set_hwreg(Adapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
+}
+static void rtl8188eu_hw_power_down(_adapter *padapter)
+{
+ /* 2010/-8/09 MH For power down module, we need to enable register block contrl reg at 0x1c. */
+ /* Then enable power down control bit of register 0x04 BIT4 and BIT15 as 1. */
+
+ /* Enable register area 0x0-0xc. */
+ rtw_write8(padapter, REG_RSV_CTRL, 0x0);
+ rtw_write16(padapter, REG_APS_FSMCO, 0x8812);
+}
+
+static u32 rtl8188eu_hal_deinit(PADAPTER Adapter)
+{
+ struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(Adapter);
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ RTW_INFO("==> %s\n", __func__);
+
+#ifdef CONFIG_SUPPORT_USB_INT
+ rtw_write32(Adapter, REG_HIMR_88E, IMR_DISABLED_88E);
+ rtw_write32(Adapter, REG_HIMRE_88E, IMR_DISABLED_88E);
+#endif
+
+#ifdef SUPPORT_HW_RFOFF_DETECTED
+ RTW_INFO("bkeepfwalive(%x)\n", pwrctl->bkeepfwalive);
+ if (pwrctl->bkeepfwalive) {
+ _ps_close_RF(Adapter);
+ if ((pwrctl->bHWPwrPindetect) && (pwrctl->bHWPowerdown))
+ rtl8188eu_hw_power_down(Adapter);
+ } else
+#endif
+ {
+ if (rtw_is_hw_init_completed(Adapter)) {
+ rtw_hal_power_off(Adapter);
+
+ if ((pwrctl->bHWPwrPindetect) && (pwrctl->bHWPowerdown))
+ rtl8188eu_hw_power_down(Adapter);
+
+ }
+ }
+ return _SUCCESS;
+}
+
+static unsigned int rtl8188eu_inirp_init(PADAPTER Adapter)
+{
+ u8 i;
+ struct recv_buf *precvbuf;
+ uint status;
+ struct dvobj_priv *pdev = adapter_to_dvobj(Adapter);
+ struct intf_hdl *pintfhdl = &Adapter->iopriv.intf;
+ struct recv_priv *precvpriv = &(Adapter->recvpriv);
+ u32(*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
+#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u32(*_read_interrupt)(struct intf_hdl *pintfhdl, u32 addr);
+#endif
+
+ _read_port = pintfhdl->io_ops._read_port;
+
+ status = _SUCCESS;
+
+ precvpriv->ff_hwaddr = RECV_BULK_IN_ADDR;
+
+ /* issue Rx irp to receive data */
+ precvbuf = (struct recv_buf *)precvpriv->precv_buf;
+ for (i = 0; i < NR_RECVBUFF; i++) {
+ if (_read_port(pintfhdl, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf) == false) {
+ status = _FAIL;
+ goto exit;
+ }
+
+ precvbuf++;
+ precvpriv->free_recv_buf_queue_cnt--;
+ }
+
+#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
+ if (pdev->RtInPipe[REALTEK_USB_IN_INT_EP_IDX] != 0x05) {
+ status = _FAIL;
+ RTW_INFO("%s =>Warning !! Have not USB Int-IN pipe, RtIntInPipe(%d)!!!\n", __func__, pdev->RtInPipe[REALTEK_USB_IN_INT_EP_IDX]);
+ goto exit;
+ }
+ _read_interrupt = pintfhdl->io_ops._read_interrupt;
+ if (_read_interrupt(pintfhdl, RECV_INT_IN_ADDR) == false) {
+ status = _FAIL;
+ }
+#endif
+
+exit:
+
+ return status;
+
+}
+
+static unsigned int rtl8188eu_inirp_deinit(PADAPTER Adapter)
+{
+
+ rtw_read_port_cancel(Adapter);
+
+ return _SUCCESS;
+}
+
+/* -------------------------------------------------------------------------
+ *
+ * EEPROM Power index mapping
+ *
+ * ------------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+ *
+ * EEPROM/EFUSE Content Parsing
+ *
+ * ------------------------------------------------------------------- */
+
+static void
+_ReadLEDSetting(
+ PADAPTER Adapter,
+ u8 *PROMContent,
+ bool AutoloadFail
+)
+{
+ struct led_priv *pledpriv = &(Adapter->ledpriv);
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+#ifdef CONFIG_SW_LED
+ pledpriv->bRegUseLed = true;
+
+ switch (pHalData->CustomerID) {
+ default:
+ pledpriv->LedStrategy = SW_LED_MODE1;
+ break;
+ }
+ pHalData->bLedOpenDrain = true;/* Support Open-drain arrangement for controlling the LED. Added by Roger, 2009.10.16. */
+#else /* HW LED */
+ pledpriv->LedStrategy = HW_LED;
+#endif /* CONFIG_SW_LED */
+}
+
+static void
+_ReadRFSetting(
+ PADAPTER Adapter,
+ u8 *PROMContent,
+ bool AutoloadFail
+)
+{
+}
+
+static void
+hal_InitPGData(
+ PADAPTER pAdapter,
+ u8 *PROMContent
+)
+{
+}
+static void
+Hal_EfuseParsePIDVID_8188EU(
+ PADAPTER pAdapter,
+ u8 *hwinfo,
+ bool AutoLoadFail
+)
+{
+
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
+
+ if (!AutoLoadFail) {
+ /* VID, PID */
+ pHalData->EEPROMVID = ReadLE2Byte(&hwinfo[EEPROM_VID_88EU]);
+ pHalData->EEPROMPID = ReadLE2Byte(&hwinfo[EEPROM_PID_88EU]);
+
+ /* Customer ID, 0x00 and 0xff are reserved for Realtek. */
+ pHalData->EEPROMCustomerID = *(u8 *)&hwinfo[EEPROM_CustomID_88E];
+ pHalData->EEPROMSubCustomerID = EEPROM_Default_SubCustomerID;
+
+ } else {
+ pHalData->EEPROMVID = EEPROM_Default_VID;
+ pHalData->EEPROMPID = EEPROM_Default_PID;
+
+ /* Customer ID, 0x00 and 0xff are reserved for Realtek. */
+ pHalData->EEPROMCustomerID = EEPROM_Default_CustomerID;
+ pHalData->EEPROMSubCustomerID = EEPROM_Default_SubCustomerID;
+
+ }
+
+ RTW_INFO("VID = 0x%04X, PID = 0x%04X\n", pHalData->EEPROMVID, pHalData->EEPROMPID);
+ RTW_INFO("Customer ID: 0x%02X, SubCustomer ID: 0x%02X\n", pHalData->EEPROMCustomerID, pHalData->EEPROMSubCustomerID);
+}
+
+static void
+Hal_CustomizeByCustomerID_8188EU(
+ PADAPTER padapter
+)
+{
+}
+
+static void
+readAdapterInfo_8188EU(
+ PADAPTER padapter
+)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
+
+ /* parse the eeprom/efuse content */
+ Hal_EfuseParseIDCode88E(padapter, pHalData->efuse_eeprom_data);
+ Hal_EfuseParsePIDVID_8188EU(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+ hal_config_macaddr(padapter, pHalData->bautoload_fail_flag);
+ Hal_ReadPowerSavingMode88E(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+ Hal_ReadTxPowerInfo88E(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+ Hal_EfuseParseEEPROMVer88E(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+ rtl8188e_EfuseParseChnlPlan(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+ Hal_EfuseParseXtal_8188E(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+ Hal_EfuseParseCustomerID88E(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+ Hal_ReadAntennaDiversity88E(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+ Hal_EfuseParseBoardType88E(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+ Hal_ReadThermalMeter_88E(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+ Hal_ReadPAType_8188E(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+ Hal_ReadAmplifierType_8188E(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+ Hal_ReadRFEType_8188E(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+#ifdef CONFIG_RF_POWER_TRIM
+ Hal_ReadRFGainOffset(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+#endif /*CONFIG_RF_POWER_TRIM*/
+
+ Hal_CustomizeByCustomerID_8188EU(padapter);
+
+ _ReadLEDSetting(padapter, pHalData->efuse_eeprom_data, pHalData->bautoload_fail_flag);
+}
+
+static void _ReadPROMContent(
+ PADAPTER Adapter
+)
+{
+ PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
+ u8 eeValue;
+
+ /* check system boot selection */
+ eeValue = rtw_read8(Adapter, REG_9346CR);
+ pHalData->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false;
+ pHalData->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true;
+
+ RTW_INFO("Boot from %s, Autoload %s !\n", (pHalData->EepromOrEfuse ? "EEPROM" : "EFUSE"),
+ (pHalData->bautoload_fail_flag ? "Fail" : "OK"));
+
+ /* pHalData->EEType = IS_BOOT_FROM_EEPROM(Adapter) ? EEPROM_93C46 : EEPROM_BOOT_EFUSE; */
+
+ Hal_InitPGData88E(Adapter);
+ readAdapterInfo_8188EU(Adapter);
+}
+
+static void
+_ReadRFType(
+ PADAPTER Adapter
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+#if DISABLE_BB_RF
+ pHalData->rf_chip = RF_PSEUDO_11N;
+#else
+ pHalData->rf_chip = RF_6052;
+#endif
+}
+
+static u8 ReadAdapterInfo8188EU(PADAPTER Adapter)
+{
+ /* Read EEPROM size before call any EEPROM function */
+ Adapter->EepromAddressSize = GetEEPROMSize8188E(Adapter);
+
+ /* Efuse_InitSomeVar(Adapter); */
+
+ _ReadRFType(Adapter);/* rf_chip->_InitRFType() */
+ _ReadPROMContent(Adapter);
+
+ return _SUCCESS;
+}
+
+static void UpdateInterruptMask8188EU(PADAPTER padapter, u8 bHIMR0 , u32 AddMSR, u32 RemoveMSR)
+{
+ HAL_DATA_TYPE *pHalData;
+
+ u32 *himr;
+ pHalData = GET_HAL_DATA(padapter);
+
+ if (bHIMR0)
+ himr = &(pHalData->IntrMask[0]);
+ else
+ himr = &(pHalData->IntrMask[1]);
+
+ if (AddMSR)
+ *himr |= AddMSR;
+
+ if (RemoveMSR)
+ *himr &= (~RemoveMSR);
+
+ if (bHIMR0)
+ rtw_write32(padapter, REG_HIMR_88E, *himr);
+ else
+ rtw_write32(padapter, REG_HIMRE_88E, *himr);
+
+}
+
+static void SetHwReg8188EU(PADAPTER Adapter, u8 variable, u8 *val)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ switch (variable) {
+
+ case HW_VAR_RXDMA_AGG_PG_TH:
+#ifdef CONFIG_USB_RX_AGGREGATION
+ {
+ u8 threshold = *((u8 *)val);
+ if (threshold == 0)
+ threshold = pHalData->rxagg_dma_size;
+ rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, threshold);
+ }
+#endif
+ break;
+ case HW_VAR_SET_RPWM:
+#ifdef CONFIG_LPS_LCLK
+ {
+ u8 ps_state = *((u8 *)val);
+ /* rpwm value only use BIT0(clock bit) ,BIT6(Ack bit), and BIT7(Toggle bit) for 88e. */
+ /* BIT0 value - 1: 32k, 0:40MHz. */
+ /* BIT6 value - 1: report cpwm value after success set, 0:do not report. */
+ /* BIT7 value - Toggle bit change. */
+ /* modify by Thomas. 2012/4/2. */
+ ps_state = ps_state & 0xC1;
+ /* RTW_INFO("##### Change RPWM value to = %x for switch clk #####\n",ps_state); */
+ rtw_write8(Adapter, REG_USB_HRPWM, ps_state);
+ }
+#endif
+ break;
+ default:
+ SetHwReg8188E(Adapter, variable, val);
+ break;
+ }
+
+}
+
+static void GetHwReg8188EU(PADAPTER Adapter, u8 variable, u8 *val)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+
+ switch (variable) {
+ default:
+ GetHwReg8188E(Adapter, variable, val);
+ break;
+ }
+
+}
+
+/*
+ * Description:
+ * Query setting of specified variable.
+ * */
+static u8
+GetHalDefVar8188EUsb(
+ PADAPTER Adapter,
+ HAL_DEF_VARIABLE eVariable,
+ void * pValue
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 bResult = _SUCCESS;
+
+ switch (eVariable) {
+ case HW_VAR_MAX_RX_AMPDU_FACTOR:
+ *((u32 *)pValue) = MAX_AMPDU_FACTOR_64K;
+ break;
+
+ case HAL_DEF_TX_LDPC:
+ case HAL_DEF_RX_LDPC:
+ *((u8 *)pValue) = false;
+ break;
+ case HAL_DEF_TX_STBC:
+ *((u8 *)pValue) = 0;
+ break;
+ case HAL_DEF_RX_STBC:
+ *((u8 *)pValue) = 1;
+ break;
+ default:
+ bResult = GetHalDefVar8188E(Adapter, eVariable, pValue);
+ break;
+ }
+
+ return bResult;
+}
+
+/*
+ * Description:
+ * Change default setting of specified variable.
+ * */
+static u8
+SetHalDefVar8188EUsb(
+ PADAPTER Adapter,
+ HAL_DEF_VARIABLE eVariable,
+ void * pValue
+)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ u8 bResult = _SUCCESS;
+
+ switch (eVariable) {
+ default:
+ bResult = SetHalDefVar(Adapter, eVariable, pValue);
+ break;
+ }
+
+ return bResult;
+}
+
+static void _update_response_rate(_adapter *padapter, unsigned int mask)
+{
+ u8 RateIndex = 0;
+ /* Set RRSR rate table. */
+ rtw_write8(padapter, REG_RRSR, mask & 0xff);
+ rtw_write8(padapter, REG_RRSR + 1, (mask >> 8) & 0xff);
+
+ /* Set RTS initial rate */
+ while (mask > 0x1) {
+ mask = (mask >> 1);
+ RateIndex++;
+ }
+ rtw_write8(padapter, REG_INIRTS_RATE_SEL, RateIndex);
+}
+
+static void SetBeaconRelatedRegisters8188EUsb(PADAPTER padapter)
+{
+ u32 value32;
+ /* HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); */
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ u32 bcn_ctrl_reg = REG_BCN_CTRL;
+ /* reset TSF, enable update TSF, correcting TSF On Beacon */
+
+ /* REG_BCN_INTERVAL */
+ /* REG_BCNDMATIM */
+ /* REG_ATIMWND */
+ /* REG_TBTT_PROHIBIT */
+ /* REG_DRVERLYINT */
+ /* REG_BCN_MAX_ERR */
+ /* REG_BCNTCFG */ /* (0x510) */
+ /* REG_DUAL_TSF_RST */
+ /* REG_BCN_CTRL */ /* (0x550) */
+
+ /* BCN interval */
+#ifdef CONFIG_CONCURRENT_MODE
+ if (padapter->hw_port == HW_PORT1)
+ bcn_ctrl_reg = REG_BCN_CTRL_1;
+#endif
+ rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
+ rtw_write8(padapter, REG_ATIMWND, 0x02);/* 2ms */
+
+ _InitBeaconParameters(padapter);
+
+ rtw_write8(padapter, REG_SLOT, 0x09);
+
+ value32 = rtw_read32(padapter, REG_TCR);
+ value32 &= ~TSFRST;
+ rtw_write32(padapter, REG_TCR, value32);
+
+ value32 |= TSFRST;
+ rtw_write32(padapter, REG_TCR, value32);
+
+ /* NOTE: Fix test chip's bug (about contention windows's randomness) */
+ rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
+ rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
+
+ _BeaconFunctionEnable(padapter, true, true);
+
+ ResumeTxBeacon(padapter);
+
+ /* rtw_write8(padapter, 0x422, rtw_read8(padapter, 0x422)|BIT(6)); */
+
+ /* rtw_write8(padapter, 0x541, 0xff); */
+
+ /* rtw_write8(padapter, 0x542, rtw_read8(padapter, 0x541)|BIT(0)); */
+
+ rtw_write8(padapter, bcn_ctrl_reg, rtw_read8(padapter, bcn_ctrl_reg) | BIT(1));
+
+}
+
+static void rtl8188eu_init_default_value(_adapter *padapter)
+{
+ PHAL_DATA_TYPE pHalData;
+ struct pwrctrl_priv *pwrctrlpriv;
+ u8 i;
+
+ pHalData = GET_HAL_DATA(padapter);
+ pwrctrlpriv = adapter_to_pwrctl(padapter);
+
+ rtl8188e_init_default_value(padapter);
+
+ /* init default value */
+ pHalData->fw_ractrl = false;
+ if (!pwrctrlpriv->bkeepfwalive)
+ pHalData->LastHMEBoxNum = 0;
+
+ /* init dm default value */
+ pHalData->bIQKInitialized = false;
+ pHalData->odmpriv.rf_calibrate_info.tm_trigger = 0;/* for IQK */
+ /* pdmpriv->binitialized = false;
+ * pdmpriv->prv_traffic_idx = 3;
+ * pdmpriv->initialize = 0; */
+ pHalData->odmpriv.rf_calibrate_info.thermal_value_hp_index = 0;
+ for (i = 0; i < HP_THERMAL_NUM; i++)
+ pHalData->odmpriv.rf_calibrate_info.thermal_value_hp[i] = 0;
+
+ pHalData->EfuseHal.fakeEfuseBank = 0;
+ pHalData->EfuseHal.fakeEfuseUsedBytes = 0;
+ memset(pHalData->EfuseHal.fakeEfuseContent, 0xFF, EFUSE_MAX_HW_SIZE);
+ memset(pHalData->EfuseHal.fakeEfuseInitMap, 0xFF, EFUSE_MAX_MAP_LEN);
+ memset(pHalData->EfuseHal.fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);
+}
+
+static u8 rtl8188eu_ps_func(PADAPTER Adapter, HAL_INTF_PS_FUNC efunc_id, u8 *val)
+{
+ u8 bResult = true;
+ switch (efunc_id) {
+
+#if defined(CONFIG_AUTOSUSPEND) && defined(SUPPORT_HW_RFOFF_DETECTED)
+ case HAL_USB_SELECT_SUSPEND: {
+ u8 bfwpoll = *((u8 *)val);
+ /* rtl8188e_set_FwSelectSuspend_cmd(Adapter,bfwpoll ,500); */ /* note fw to support hw power down ping detect */
+ }
+ break;
+#endif /* CONFIG_AUTOSUSPEND && SUPPORT_HW_RFOFF_DETECTED */
+
+ default:
+ break;
+ }
+ return bResult;
+}
+
+void rtl8188eu_set_hal_ops(_adapter *padapter)
+{
+ struct hal_ops *pHalFunc = &padapter->hal_func;
+
+ pHalFunc->hal_power_on = _InitPowerOn_8188EU;
+ pHalFunc->hal_power_off = hal_poweroff_8188eu;
+
+ pHalFunc->hal_init = &rtl8188eu_hal_init;
+ pHalFunc->hal_deinit = &rtl8188eu_hal_deinit;
+
+ pHalFunc->inirp_init = &rtl8188eu_inirp_init;
+ pHalFunc->inirp_deinit = &rtl8188eu_inirp_deinit;
+
+ pHalFunc->init_xmit_priv = &rtl8188eu_init_xmit_priv;
+ pHalFunc->free_xmit_priv = &rtl8188eu_free_xmit_priv;
+
+ pHalFunc->init_recv_priv = &rtl8188eu_init_recv_priv;
+ pHalFunc->free_recv_priv = &rtl8188eu_free_recv_priv;
+#ifdef CONFIG_SW_LED
+ pHalFunc->InitSwLeds = &rtl8188eu_InitSwLeds;
+ pHalFunc->DeInitSwLeds = &rtl8188eu_DeInitSwLeds;
+#else /* case of hw led or no led */
+ pHalFunc->InitSwLeds = NULL;
+ pHalFunc->DeInitSwLeds = NULL;
+#endif/* CONFIG_SW_LED */
+
+ pHalFunc->init_default_value = &rtl8188eu_init_default_value;
+ pHalFunc->intf_chip_configure = &rtl8188eu_interface_configure;
+ pHalFunc->read_adapter_info = &ReadAdapterInfo8188EU;
+ pHalFunc->set_hw_reg_handler = &SetHwReg8188EU;
+ pHalFunc->GetHwRegHandler = &GetHwReg8188EU;
+ pHalFunc->get_hal_def_var_handler = &GetHalDefVar8188EUsb;
+ pHalFunc->SetHalDefVarHandler = &SetHalDefVar8188EUsb;
+
+ pHalFunc->SetBeaconRelatedRegistersHandler = &SetBeaconRelatedRegisters8188EUsb;
+
+ pHalFunc->hal_xmit = &rtl8188eu_hal_xmit;
+ pHalFunc->mgnt_xmit = &rtl8188eu_mgnt_xmit;
+ pHalFunc->hal_xmitframe_enqueue = &rtl8188eu_hal_xmitframe_enqueue;
+
+#ifdef CONFIG_HOSTAPD_MLME
+ pHalFunc->hostap_mgnt_xmit_entry = &rtl8188eu_hostap_mgnt_xmit_entry;
+#endif
+ pHalFunc->interface_ps_func = &rtl8188eu_ps_func;
+
+#ifdef CONFIG_XMIT_THREAD_MODE
+ pHalFunc->xmit_thread_handler = &rtl8188eu_xmit_buf_handler;
+#endif
+#ifdef CONFIG_SUPPORT_USB_INT
+ pHalFunc->interrupt_handler = interrupt_handler_8188eu;
+#endif
+ rtl8188e_set_hal_ops(pHalFunc);
+
+}
diff --git a/drivers/staging/rtl8188eu/hal/usb_ops_linux.c b/drivers/staging/rtl8188eu/hal/usb_ops_linux.c
new file mode 100644
index 000000000000..021e73723b6b
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/usb_ops_linux.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. */
+
+#define _HCI_OPS_OS_C_
+
+#include <drv_types.h>
+#include <rtl8188e_hal.h>
+
+
+#ifdef CONFIG_SUPPORT_USB_INT
+void interrupt_handler_8188eu(_adapter *padapter, u16 pkt_len, u8 *pbuf)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct reportpwrstate_parm pwr_rpt;
+
+ if (pkt_len != INTERRUPT_MSG_FORMAT_LEN) {
+ RTW_INFO("%s Invalid interrupt content length (%d)!\n", __func__, pkt_len);
+ return ;
+ }
+
+ /* HISR */
+ memcpy(&(pHalData->IntArray[0]), &(pbuf[USB_INTR_CONTENT_HISR_OFFSET]), 4);
+ memcpy(&(pHalData->IntArray[1]), &(pbuf[USB_INTR_CONTENT_HISRE_OFFSET]), 4);
+
+#ifdef CONFIG_LPS_LCLK
+ if (pHalData->IntArray[0] & IMR_CPWM_88E) {
+ memcpy(&pwr_rpt.state, &(pbuf[USB_INTR_CONTENT_CPWM1_OFFSET]), 1);
+ /* memcpy(&pwr_rpt.state2, &(pbuf[USB_INTR_CONTENT_CPWM2_OFFSET]), 1); */
+
+ /* 88e's cpwm value only change BIT0, so driver need to add PS_STATE_S2 for LPS flow. */
+ pwr_rpt.state |= PS_STATE_S2;
+ _set_workitem(&(adapter_to_pwrctl(padapter)->cpwm_event));
+ }
+#endif/* CONFIG_LPS_LCLK */
+
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN
+
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
+ if (pHalData->IntArray[0] & IMR_BCNDMAINT0_88E) /*only for BCN_0*/
+#endif
+#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
+ if (pHalData->IntArray[0] & (IMR_TBDER_88E | IMR_TBDOK_88E))
+#endif
+ {
+ rtw_mi_set_tx_beacon_cmd(padapter);
+ }
+#endif /* CONFIG_INTERRUPT_BASED_TXBCN */
+
+
+
+
+#ifdef DBG_CONFIG_ERROR_DETECT_INT
+ if (pHalData->IntArray[1] & IMR_TXERR_88E)
+ RTW_INFO("===> %s Tx Error Flag Interrupt Status\n", __func__);
+ if (pHalData->IntArray[1] & IMR_RXERR_88E)
+ RTW_INFO("===> %s Rx Error Flag INT Status\n", __func__);
+ if (pHalData->IntArray[1] & IMR_TXFOVW_88E)
+ RTW_INFO("===> %s Transmit FIFO Overflow\n", __func__);
+ if (pHalData->IntArray[1] & IMR_RXFOVW_88E)
+ RTW_INFO("===> %s Receive FIFO Overflow\n", __func__);
+#endif/* DBG_CONFIG_ERROR_DETECT_INT */
+
+
+#ifdef CONFIG_FW_C2H_REG
+ /* C2H Event */
+ if (pbuf[0] != 0)
+ usb_c2h_hisr_hdl(padapter, pbuf);
+#endif
+}
+#endif
+
+
+int recvbuf2recvframe(PADAPTER padapter, void *ptr)
+{
+ u8 *pbuf;
+ u16 pkt_cnt;
+ u32 pkt_offset;
+ s32 transfer_len;
+ struct recv_stat *prxstat;
+ u8 *pphy_status = NULL;
+ union recv_frame *precvframe = NULL;
+ struct rx_pkt_attrib *pattrib = NULL;
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct recv_priv *precvpriv = &padapter->recvpriv;
+ _queue *pfree_recv_queue = &precvpriv->free_recv_queue;
+ _pkt *pskb;
+
+#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
+ pskb = NULL;
+ transfer_len = (s32)((struct recv_buf *)ptr)->transfer_len;
+ pbuf = ((struct recv_buf *)ptr)->pbuf;
+#else
+ pskb = (_pkt *)ptr;
+ transfer_len = (s32)pskb->len;
+ pbuf = pskb->data;
+#endif
+ prxstat = (struct recv_stat *)pbuf;
+ pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff;
+
+ do {
+ prxstat = (struct recv_stat *)pbuf;
+
+ precvframe = rtw_alloc_recvframe(pfree_recv_queue);
+ if (precvframe == NULL) {
+ RTW_INFO("%s()-%d: rtw_alloc_recvframe() failed! RX Drop!\n", __func__, __LINE__);
+ goto _exit_recvbuf2recvframe;
+ }
+
+ INIT_LIST_HEAD(&precvframe->u.hdr.list);
+ precvframe->u.hdr.precvbuf = NULL; /* can't access the precvbuf for new arch. */
+ precvframe->u.hdr.len = 0;
+
+ rtl8188e_query_rx_desc_status(precvframe, prxstat);
+
+ pattrib = &precvframe->u.hdr.attrib;
+
+ if ((padapter->registrypriv.mp_mode == 0) && ((pattrib->crc_err) || (pattrib->icv_err))) {
+ RTW_INFO("%s: RX Warning! crc_err=%d icv_err=%d, skip!\n", __func__, pattrib->crc_err, pattrib->icv_err);
+ rtw_free_recvframe(precvframe, pfree_recv_queue);
+ goto _exit_recvbuf2recvframe;
+ }
+
+
+ pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz +
+ pattrib->shift_sz + le16_to_cpu(pattrib->pkt_len);
+
+ if ((le16_to_cpu(pattrib->pkt_len) <= 0) || (pkt_offset > transfer_len)) {
+ RTW_INFO("%s()-%d: RX Warning!,pkt_len<=0 or pkt_offset> transfoer_len\n", __func__, __LINE__);
+ rtw_free_recvframe(precvframe, pfree_recv_queue);
+ goto _exit_recvbuf2recvframe;
+ }
+
+#ifdef CONFIG_RX_PACKET_APPEND_FCS
+ if (check_fwstate(&padapter->mlmepriv, WIFI_MONITOR_STATE) == false)
+ if ((pattrib->pkt_rpt_type == NORMAL_RX) && (pHalData->ReceiveConfig & RCR_APPFCS))
+ pattrib->pkt_len -= IEEE80211_FCS_LEN;
+#endif
+
+ if (rtw_os_alloc_recvframe(padapter, precvframe,
+ (pbuf + pattrib->shift_sz + pattrib->drvinfo_sz + RXDESC_SIZE), pskb) == _FAIL) {
+ rtw_free_recvframe(precvframe, pfree_recv_queue);
+
+ goto _exit_recvbuf2recvframe;
+ }
+
+ recvframe_put(precvframe, pattrib->pkt_len);
+ /* recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE); */
+
+ if (pattrib->pkt_rpt_type == NORMAL_RX) { /* Normal rx packet */
+ if (pattrib->physt)
+ pphy_status = pbuf + RXDESC_OFFSET;
+
+#ifdef CONFIG_CONCURRENT_MODE
+ pre_recv_entry(precvframe, pphy_status);
+#endif /*CONFIG_CONCURRENT_MODE*/
+
+
+ if (pattrib->physt && pphy_status)
+ rx_query_phy_status(precvframe, pphy_status);
+
+ rtw_recv_entry(precvframe);
+
+ } else { /* pkt_rpt_type == TX_REPORT1-CCX, TX_REPORT2-TX RTP,HIS_REPORT-USB HISR RTP */
+
+ /* enqueue recvframe to txrtp queue */
+ if (pattrib->pkt_rpt_type == TX_REPORT1) {
+ /* RTW_INFO("rx CCX\n"); */
+ /* CCX-TXRPT ack for xmit mgmt frames. */
+ handle_txrpt_ccx_88e(padapter, precvframe->u.hdr.rx_data);
+ } else if (pattrib->pkt_rpt_type == TX_REPORT2) {
+ /* RTW_INFO("recv TX RPT\n"); */
+ odm_ra_tx_rpt2_handle_8188e(
+ &pHalData->odmpriv,
+ precvframe->u.hdr.rx_data,
+ pattrib->pkt_len,
+ le32_to_cpu(pattrib->MacIDValidEntry[0]),
+ le32_to_cpu(pattrib->MacIDValidEntry[1]));
+ } else if (pattrib->pkt_rpt_type == HIS_REPORT) {
+ /* RTW_INFO("%s , rx USB HISR\n",__func__); */
+#ifdef CONFIG_SUPPORT_USB_INT
+ interrupt_handler_8188eu(padapter, le16_to_cpu(pattrib->pkt_len), precvframe->u.hdr.rx_data);
+#endif
+ }
+ rtw_free_recvframe(precvframe, pfree_recv_queue);
+
+ }
+
+#ifdef CONFIG_USB_RX_AGGREGATION
+ switch (pHalData->rxagg_mode) {
+ case RX_AGG_DMA:
+ case RX_AGG_MIX:
+ pkt_offset = (u16)_RND128(pkt_offset);
+ break;
+ case RX_AGG_USB:
+ pkt_offset = (u16)_RND4(pkt_offset);
+ break;
+ case RX_AGG_DISABLE:
+ default:
+ break;
+ }
+#endif
+ pkt_cnt--;
+ transfer_len -= pkt_offset;
+ pbuf += pkt_offset;
+ precvframe = NULL;
+
+ if (transfer_len > 0 && pkt_cnt == 0)
+ pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff;
+
+ } while ((transfer_len > 0) && (pkt_cnt > 0));
+
+_exit_recvbuf2recvframe:
+
+ return _SUCCESS;
+}
+
+
+
+void rtl8188eu_xmit_tasklet(void *priv)
+{
+ int ret = false;
+ _adapter *padapter = (_adapter *)priv;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+
+ while (1) {
+ if (RTW_CANNOT_TX(padapter)) {
+ RTW_INFO("xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel\n");
+ break;
+ }
+
+ if (rtw_xmit_ac_blocked(padapter) == true)
+ break;
+
+ ret = rtl8188eu_xmitframe_complete(padapter, pxmitpriv, NULL);
+
+ if (ret == false)
+ break;
+ }
+
+}
+
+void rtl8188eu_set_hw_type(struct dvobj_priv *pdvobj)
+{
+ pdvobj->HardwareType = HARDWARE_TYPE_RTL8188EU;
+ RTW_INFO("CHIP TYPE: RTL8188E\n");
+}
diff --git a/drivers/staging/rtl8188eu/hal/version_rtl8188e.h b/drivers/staging/rtl8188eu/hal/version_rtl8188e.h
new file mode 100644
index 000000000000..0facf233a901
--- /dev/null
+++ b/drivers/staging/rtl8188eu/hal/version_rtl8188e.h
@@ -0,0 +1,10 @@
+/*RTL8188E PHY Parameters*/
+/*
+[Caution]
+ Since 01/Aug/2015, the commit rules will be simplified.
+ You do not need to fill up the version.h anymore,
+ only the maintenance supervisor fills it before formal release.
+*/
+#define RELEASE_DATE_8188E 20160517
+#define COMMIT_BY_8188E "RF_Eason"
+#define RELEASE_VERSION_8188E 70
--
2.31.1