From 9ce99b04b5b82fdf11e4c76b60a5f82c1e541297 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 17 Aug 2017 12:46:49 -0500 Subject: staging: r8822be: Add phydm mini driver The RTL8822BE, an 802.11ac wireless network card, is now appearing in new computers. Its driver is being placed in staging to reduce the time that users of this new card will have access to in-kernel drivers. New Realtek wireless devices have a new method for PHY control and dynamic management. The RTL8822BE is the first of these devices, thus there is additional code required. In the final version, this code will be a separate module; however, it is combined with the r8822be driver to minimize the interference with the drivers in the wireless tree. Signed-off-by: Ping-Ke Shih Signed-off-by: Larry Finger Cc: Yan-Hsuan Chuang Cc: Birming Chiu Cc: Shaofu Cc: Steven Ting Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtlwifi/phydm/halphyrf_ce.c | 965 ++++ drivers/staging/rtlwifi/phydm/halphyrf_ce.h | 85 + drivers/staging/rtlwifi/phydm/mp_precomp.h | 24 + drivers/staging/rtlwifi/phydm/phydm.c | 1986 ++++++++ drivers/staging/rtlwifi/phydm/phydm.h | 946 ++++ drivers/staging/rtlwifi/phydm/phydm_acs.c | 200 + drivers/staging/rtlwifi/phydm/phydm_acs.h | 57 + drivers/staging/rtlwifi/phydm/phydm_adaptivity.c | 941 ++++ drivers/staging/rtlwifi/phydm/phydm_adaptivity.h | 119 + drivers/staging/rtlwifi/phydm/phydm_adc_sampling.c | 628 +++ drivers/staging/rtlwifi/phydm/phydm_adc_sampling.h | 96 + drivers/staging/rtlwifi/phydm/phydm_antdiv.c | 83 + drivers/staging/rtlwifi/phydm/phydm_antdiv.h | 301 ++ drivers/staging/rtlwifi/phydm/phydm_beamforming.h | 48 + drivers/staging/rtlwifi/phydm/phydm_ccx.c | 457 ++ drivers/staging/rtlwifi/phydm/phydm_ccx.h | 83 + drivers/staging/rtlwifi/phydm/phydm_cfotracking.c | 343 ++ drivers/staging/rtlwifi/phydm/phydm_cfotracking.h | 60 + drivers/staging/rtlwifi/phydm/phydm_debug.c | 2910 ++++++++++++ drivers/staging/rtlwifi/phydm/phydm_debug.h | 175 + drivers/staging/rtlwifi/phydm/phydm_dfs.h | 59 + drivers/staging/rtlwifi/phydm/phydm_dig.c | 1535 +++++++ drivers/staging/rtlwifi/phydm/phydm_dig.h | 241 + .../staging/rtlwifi/phydm/phydm_dynamic_rx_path.h | 37 + .../rtlwifi/phydm/phydm_dynamicbbpowersaving.c | 129 + .../rtlwifi/phydm/phydm_dynamicbbpowersaving.h | 50 + .../staging/rtlwifi/phydm/phydm_dynamictxpower.c | 102 + .../staging/rtlwifi/phydm/phydm_dynamictxpower.h | 64 + .../staging/rtlwifi/phydm/phydm_edcaturbocheck.c | 139 + .../staging/rtlwifi/phydm/phydm_edcaturbocheck.h | 44 + drivers/staging/rtlwifi/phydm/phydm_features.h | 33 + drivers/staging/rtlwifi/phydm/phydm_hwconfig.c | 1928 ++++++++ drivers/staging/rtlwifi/phydm/phydm_hwconfig.h | 510 +++ drivers/staging/rtlwifi/phydm/phydm_interface.c | 341 ++ drivers/staging/rtlwifi/phydm/phydm_interface.h | 205 + drivers/staging/rtlwifi/phydm/phydm_iqk.h | 76 + drivers/staging/rtlwifi/phydm/phydm_kfree.c | 228 + drivers/staging/rtlwifi/phydm/phydm_kfree.h | 42 + drivers/staging/rtlwifi/phydm/phydm_noisemonitor.c | 330 ++ drivers/staging/rtlwifi/phydm/phydm_noisemonitor.h | 46 + .../staging/rtlwifi/phydm/phydm_powertracking_ce.c | 644 +++ .../staging/rtlwifi/phydm/phydm_powertracking_ce.h | 293 ++ drivers/staging/rtlwifi/phydm/phydm_pre_define.h | 613 +++ drivers/staging/rtlwifi/phydm/phydm_precomp.h | 85 + drivers/staging/rtlwifi/phydm/phydm_psd.c | 422 ++ drivers/staging/rtlwifi/phydm/phydm_psd.h | 67 + drivers/staging/rtlwifi/phydm/phydm_rainfo.c | 1208 +++++ drivers/staging/rtlwifi/phydm/phydm_rainfo.h | 269 ++ drivers/staging/rtlwifi/phydm/phydm_reg.h | 151 + .../staging/rtlwifi/phydm/phydm_regdefine11ac.h | 94 + drivers/staging/rtlwifi/phydm/phydm_regdefine11n.h | 213 + drivers/staging/rtlwifi/phydm/phydm_types.h | 130 + .../rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.c | 1969 ++++++++ .../rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.h | 54 + .../rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.c | 222 + .../rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.h | 38 + .../rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.c | 4744 ++++++++++++++++++++ .../rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.h | 129 + .../rtlwifi/phydm/rtl8822b/halphyrf_8822b.c | 351 ++ .../rtlwifi/phydm/rtl8822b/halphyrf_8822b.h | 45 + .../rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.c | 1815 ++++++++ .../rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.h | 84 + .../rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.c | 1410 ++++++ .../rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.h | 48 + .../rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.c | 168 + .../rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.h | 54 + .../rtlwifi/phydm/rtl8822b/phydm_rtl8822b.c | 225 + .../rtlwifi/phydm/rtl8822b/phydm_rtl8822b.h | 30 + .../rtlwifi/phydm/rtl8822b/version_rtl8822b.h | 34 + drivers/staging/rtlwifi/phydm/rtl_phydm.c | 874 ++++ drivers/staging/rtlwifi/phydm/rtl_phydm.h | 45 + drivers/staging/rtlwifi/phydm/txbf/halcomtxbf.h | 67 + drivers/staging/rtlwifi/phydm/txbf/haltxbf8822b.h | 39 + .../staging/rtlwifi/phydm/txbf/haltxbfinterface.h | 38 + drivers/staging/rtlwifi/phydm/txbf/haltxbfjaguar.h | 36 + .../rtlwifi/phydm/txbf/phydm_hal_txbf_api.h | 41 + 76 files changed, 33395 insertions(+) create mode 100644 drivers/staging/rtlwifi/phydm/halphyrf_ce.c create mode 100644 drivers/staging/rtlwifi/phydm/halphyrf_ce.h create mode 100644 drivers/staging/rtlwifi/phydm/mp_precomp.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_acs.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_acs.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_adaptivity.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_adaptivity.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_adc_sampling.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_adc_sampling.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_antdiv.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_antdiv.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_beamforming.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_ccx.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_ccx.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_cfotracking.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_cfotracking.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_debug.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_debug.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_dfs.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_dig.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_dig.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_dynamic_rx_path.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_features.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_hwconfig.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_hwconfig.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_interface.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_interface.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_iqk.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_kfree.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_kfree.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_noisemonitor.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_noisemonitor.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_pre_define.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_precomp.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_psd.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_psd.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_rainfo.c create mode 100644 drivers/staging/rtlwifi/phydm/phydm_rainfo.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_reg.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_regdefine11ac.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_regdefine11n.h create mode 100644 drivers/staging/rtlwifi/phydm/phydm_types.h create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.c create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.h create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.c create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.h create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.c create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.h create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.c create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.h create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.c create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.h create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.c create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.h create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.c create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.h create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.c create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.h create mode 100644 drivers/staging/rtlwifi/phydm/rtl8822b/version_rtl8822b.h create mode 100644 drivers/staging/rtlwifi/phydm/rtl_phydm.c create mode 100644 drivers/staging/rtlwifi/phydm/rtl_phydm.h create mode 100644 drivers/staging/rtlwifi/phydm/txbf/halcomtxbf.h create mode 100644 drivers/staging/rtlwifi/phydm/txbf/haltxbf8822b.h create mode 100644 drivers/staging/rtlwifi/phydm/txbf/haltxbfinterface.h create mode 100644 drivers/staging/rtlwifi/phydm/txbf/haltxbfjaguar.h create mode 100644 drivers/staging/rtlwifi/phydm/txbf/phydm_hal_txbf_api.h (limited to 'drivers/staging/rtlwifi') diff --git a/drivers/staging/rtlwifi/phydm/halphyrf_ce.c b/drivers/staging/rtlwifi/phydm/halphyrf_ce.c new file mode 100644 index 000000000000..684e383201d6 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/halphyrf_ce.c @@ -0,0 +1,965 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "mp_precomp.h" +#include "phydm_precomp.h" + +#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) + +static inline void phydm_set_calibrate_info_up( + struct phy_dm_struct *dm, struct txpwrtrack_cfg *c, u8 delta, + struct dm_rf_calibration_struct *cali_info, + u8 *delta_swing_table_idx_tup_a, u8 *delta_swing_table_idx_tup_b, + u8 *delta_swing_table_idx_tup_c, u8 *delta_swing_table_idx_tup_d) +{ + u8 p = 0; + + for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++) { + cali_info->delta_power_index_last[p] = + cali_info->delta_power_index + [p]; /*recording poer index offset*/ + switch (p) { + case ODM_RF_PATH_B: + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "delta_swing_table_idx_tup_b[%d] = %d\n", + delta, delta_swing_table_idx_tup_b[delta]); + + cali_info->delta_power_index[p] = + delta_swing_table_idx_tup_b[delta]; + /*Record delta swing for mix mode pwr tracking*/ + cali_info->absolute_ofdm_swing_idx[p] = + delta_swing_table_idx_tup_b[delta]; + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n", + cali_info->absolute_ofdm_swing_idx[p]); + break; + + case ODM_RF_PATH_C: + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "delta_swing_table_idx_tup_c[%d] = %d\n", + delta, delta_swing_table_idx_tup_c[delta]); + + cali_info->delta_power_index[p] = + delta_swing_table_idx_tup_c[delta]; + /*Record delta swing for mix mode pwr tracking*/ + cali_info->absolute_ofdm_swing_idx[p] = + delta_swing_table_idx_tup_c[delta]; + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n", + cali_info->absolute_ofdm_swing_idx[p]); + break; + + case ODM_RF_PATH_D: + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "delta_swing_table_idx_tup_d[%d] = %d\n", + delta, delta_swing_table_idx_tup_d[delta]); + + cali_info->delta_power_index[p] = + delta_swing_table_idx_tup_d[delta]; + /*Record delta swing for mix mode pwr tracking*/ + cali_info->absolute_ofdm_swing_idx[p] = + delta_swing_table_idx_tup_d[delta]; + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n", + cali_info->absolute_ofdm_swing_idx[p]); + break; + + default: + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "delta_swing_table_idx_tup_a[%d] = %d\n", + delta, delta_swing_table_idx_tup_a[delta]); + + cali_info->delta_power_index[p] = + delta_swing_table_idx_tup_a[delta]; + /*Record delta swing for mix mode pwr tracking*/ + cali_info->absolute_ofdm_swing_idx[p] = + delta_swing_table_idx_tup_a[delta]; + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "******Temp is higher and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n", + cali_info->absolute_ofdm_swing_idx[p]); + break; + } + } +} + +static inline void phydm_set_calibrate_info_down( + struct phy_dm_struct *dm, struct txpwrtrack_cfg *c, u8 delta, + struct dm_rf_calibration_struct *cali_info, + u8 *delta_swing_table_idx_tdown_a, u8 *delta_swing_table_idx_tdown_b, + u8 *delta_swing_table_idx_tdown_c, u8 *delta_swing_table_idx_tdown_d) +{ + u8 p = 0; + + for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++) { + cali_info->delta_power_index_last[p] = + cali_info->delta_power_index + [p]; /*recording poer index offset*/ + + switch (p) { + case ODM_RF_PATH_B: + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "delta_swing_table_idx_tdown_b[%d] = %d\n", + delta, + delta_swing_table_idx_tdown_b[delta]); + cali_info->delta_power_index[p] = + -1 * delta_swing_table_idx_tdown_b[delta]; + /*Record delta swing for mix mode pwr tracking*/ + cali_info->absolute_ofdm_swing_idx[p] = + -1 * delta_swing_table_idx_tdown_b[delta]; + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_B] = %d\n", + cali_info->absolute_ofdm_swing_idx[p]); + break; + + case ODM_RF_PATH_C: + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "delta_swing_table_idx_tdown_c[%d] = %d\n", + delta, + delta_swing_table_idx_tdown_c[delta]); + cali_info->delta_power_index[p] = + -1 * delta_swing_table_idx_tdown_c[delta]; + /*Record delta swing for mix mode pwr tracking*/ + cali_info->absolute_ofdm_swing_idx[p] = + -1 * delta_swing_table_idx_tdown_c[delta]; + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_C] = %d\n", + cali_info->absolute_ofdm_swing_idx[p]); + break; + + case ODM_RF_PATH_D: + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "delta_swing_table_idx_tdown_d[%d] = %d\n", + delta, + delta_swing_table_idx_tdown_d[delta]); + cali_info->delta_power_index[p] = + -1 * delta_swing_table_idx_tdown_d[delta]; + /*Record delta swing for mix mode pwr tracking*/ + cali_info->absolute_ofdm_swing_idx[p] = + -1 * delta_swing_table_idx_tdown_d[delta]; + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_D] = %d\n", + cali_info->absolute_ofdm_swing_idx[p]); + break; + + default: + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "delta_swing_table_idx_tdown_a[%d] = %d\n", + delta, + delta_swing_table_idx_tdown_a[delta]); + cali_info->delta_power_index[p] = + -1 * delta_swing_table_idx_tdown_a[delta]; + /*Record delta swing for mix mode pwr tracking*/ + cali_info->absolute_ofdm_swing_idx[p] = + -1 * delta_swing_table_idx_tdown_a[delta]; + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "******Temp is lower and cali_info->absolute_ofdm_swing_idx[ODM_RF_PATH_A] = %d\n", + cali_info->absolute_ofdm_swing_idx[p]); + break; + } + } +} + +static inline void phydm_odm_tx_power_set(struct phy_dm_struct *dm, + struct txpwrtrack_cfg *c, + u8 indexforchannel, u8 flag) +{ + u8 p = 0; + + if (dm->support_ic_type == ODM_RTL8188E || + dm->support_ic_type == ODM_RTL8192E || + dm->support_ic_type == ODM_RTL8821 || + dm->support_ic_type == ODM_RTL8812 || + dm->support_ic_type == ODM_RTL8723B || + dm->support_ic_type == ODM_RTL8814A || + dm->support_ic_type == ODM_RTL8703B || + dm->support_ic_type == ODM_RTL8188F || + dm->support_ic_type == ODM_RTL8822B || + dm->support_ic_type == ODM_RTL8723D || + dm->support_ic_type == ODM_RTL8821C || + dm->support_ic_type == ODM_RTL8710B) { /* JJ ADD 20161014 */ + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "**********Enter POWER Tracking MIX_MODE**********\n"); + for (p = ODM_RF_PATH_A; p < c->rf_path_count; p++) { + if (flag == 0) + (*c->odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, + 0); + else + (*c->odm_tx_pwr_track_set_pwr)(dm, MIX_MODE, p, + indexforchannel); + } + } else { + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "**********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)(dm, BBSWING, p, + indexforchannel); + } +} + +void configure_txpower_track(void *dm_void, struct txpwrtrack_cfg *config) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + /* JJ ADD 20161014 */ + + if (dm->support_ic_type == ODM_RTL8822B) + configure_txpower_track_8822b(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 *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + struct rtl_efuse *rtlefu = rtl_efuse(rtlpriv); + u8 p = 0; + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index; + cali_info->bb_swing_idx_cck = cali_info->default_cck_index; + dm->rf_calibrate_info.CCK_index = 0; + + for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) { + cali_info->bb_swing_idx_ofdm_base[p] = + cali_info->default_ofdm_index; + cali_info->bb_swing_idx_ofdm[p] = cali_info->default_ofdm_index; + cali_info->OFDM_index[p] = cali_info->default_ofdm_index; + + cali_info->power_index_offset[p] = 0; + cali_info->delta_power_index[p] = 0; + cali_info->delta_power_index_last[p] = 0; + + cali_info->absolute_ofdm_swing_idx[p] = + 0; /* Initial Mix mode power tracking*/ + cali_info->remnant_ofdm_swing_idx[p] = 0; + cali_info->kfree_offset[p] = 0; + } + + cali_info->modify_tx_agc_flag_path_a = + false; /*Initial at Modify Tx Scaling mode*/ + cali_info->modify_tx_agc_flag_path_b = + false; /*Initial at Modify Tx Scaling mode*/ + cali_info->modify_tx_agc_flag_path_c = + false; /*Initial at Modify Tx Scaling mode*/ + cali_info->modify_tx_agc_flag_path_d = + false; /*Initial at Modify Tx Scaling mode*/ + cali_info->remnant_cck_swing_idx = 0; + cali_info->thermal_value = rtlefu->eeprom_thermalmeter; + + cali_info->modify_tx_agc_value_cck = 0; /* modify by Mingzhi.Guo */ + cali_info->modify_tx_agc_value_ofdm = 0; /* modify by Mingzhi.Guo */ +} + +void odm_txpowertracking_callback_thermal_meter(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + struct rtl_efuse *rtlefu = rtl_efuse(rtlpriv); + void *adapter = dm->adapter; + + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + u8 thermal_value = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0; + s8 diff_DPK[4]; /* use 'for..loop' to initialize */ + u8 thermal_value_avg_count = 0; + u32 thermal_value_avg = 0, regc80, regcd0, regcd4, regab4; + + /* OFDM BB Swing should be less than +3.0dB (required by Arthur) */ + u8 OFDM_min_index = 0; + /* get_right_chnl_place_for_iqk(hal_data->current_channel) */ + u8 indexforchannel = 0; + u8 power_tracking_type = 0; /* no specify 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. Initialization ( 7 steps in total ) */ + + configure_txpower_track(dm, &c); + + (*c.get_delta_swing_table)(dm, (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 (dm->support_ic_type & ODM_RTL8814A) /*for 8814 path C & D*/ + (*c.get_delta_swing_table8814only)( + dm, (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); + /* JJ ADD 20161014 */ + if (dm->support_ic_type & + (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) /*for Xtal Offset*/ + (*c.get_delta_swing_xtal_table)( + dm, (s8 **)&delta_swing_table_xtal_up, + (s8 **)&delta_swing_table_xtal_down); + + cali_info->txpowertracking_callback_cnt++; /*cosa add for debug*/ + cali_info->is_txpowertracking_init = true; + + /*cali_info->txpowertrack_control = hal_data->txpowertrack_control; + * We should keep updating ctrl variable according to HalData. + * rf_calibrate_info.rega24 will be initialized when + *ODM HW configuring, but MP configures with para files. + */ + if (dm->mp_mode) + cali_info->rega24 = 0x090e1317; + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "===>%s\n cali_info->bb_swing_idx_cck_base: %d, cali_info->bb_swing_idx_ofdm_base[A]: %d, cali_info->default_ofdm_index: %d\n", + __func__, cali_info->bb_swing_idx_cck_base, + cali_info->bb_swing_idx_ofdm_base[ODM_RF_PATH_A], + cali_info->default_ofdm_index); + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "cali_info->txpowertrack_control=%d, rtlefu->eeprom_thermalmeter %d\n", + cali_info->txpowertrack_control, rtlefu->eeprom_thermalmeter); + + thermal_value = + (u8)odm_get_rf_reg(dm, 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 (dm->support_ic_type == ODM_RTL8723D) { + regc80 = odm_get_bb_reg(dm, 0xc80, MASKDWORD); + regcd0 = odm_get_bb_reg(dm, 0xcd0, MASKDWORD); + regcd4 = odm_get_bb_reg(dm, 0xcd4, MASKDWORD); + regab4 = odm_get_bb_reg(dm, 0xab4, 0x000007FF); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", + regc80, regcd0, regcd4, regab4); + } + /* JJ ADD 20161014 */ + if (dm->support_ic_type == ODM_RTL8710B) { + regc80 = odm_get_bb_reg(dm, 0xc80, MASKDWORD); + regcd0 = odm_get_bb_reg(dm, 0xcd0, MASKDWORD); + regcd4 = odm_get_bb_reg(dm, 0xcd4, MASKDWORD); + regab4 = odm_get_bb_reg(dm, 0xab4, 0x000007FF); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "0xc80 = 0x%x 0xcd0 = 0x%x 0xcd4 = 0x%x 0xab4 = 0x%x\n", + regc80, regcd0, regcd4, regab4); + } + + if (!cali_info->txpowertrack_control) + return; + + /*4 3. Initialize ThermalValues of rf_calibrate_info*/ + + if (cali_info->is_reloadtxpowerindex) + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "reload ofdm index for band switch\n"); + + /*4 4. Calculate average thermal meter*/ + + cali_info->thermal_value_avg[cali_info->thermal_value_avg_index] = + thermal_value; + cali_info->thermal_value_avg_index++; + if (cali_info->thermal_value_avg_index == + c.average_thermal_num) /*Average times = c.average_thermal_num*/ + cali_info->thermal_value_avg_index = 0; + + for (i = 0; i < c.average_thermal_num; i++) { + if (cali_info->thermal_value_avg[i]) { + thermal_value_avg += cali_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); + cali_info->thermal_value_delta = + thermal_value - rtlefu->eeprom_thermalmeter; + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "AVG Thermal Meter = 0x%X, EFUSE Thermal base = 0x%X\n", + thermal_value, rtlefu->eeprom_thermalmeter); + } + + /* 4 5. Calculate delta, delta_LCK, delta_IQK. */ + + /* "delta" is used to determine whether thermal value changes or not*/ + delta = (thermal_value > cali_info->thermal_value) ? + (thermal_value - cali_info->thermal_value) : + (cali_info->thermal_value - thermal_value); + delta_LCK = (thermal_value > cali_info->thermal_value_lck) ? + (thermal_value - cali_info->thermal_value_lck) : + (cali_info->thermal_value_lck - thermal_value); + delta_IQK = (thermal_value > cali_info->thermal_value_iqk) ? + (thermal_value - cali_info->thermal_value_iqk) : + (cali_info->thermal_value_iqk - thermal_value); + + if (cali_info->thermal_value_iqk == + 0xff) { /*no PG, use thermal value for IQK*/ + cali_info->thermal_value_iqk = thermal_value; + delta_IQK = + (thermal_value > cali_info->thermal_value_iqk) ? + (thermal_value - cali_info->thermal_value_iqk) : + (cali_info->thermal_value_iqk - thermal_value); + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "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)cali_info->dpk_thermal[p]; + + /*4 6. If necessary, do LCK.*/ + + if (!(dm->support_ic_type & + ODM_RTL8821)) { /*no PG, do LCK at initial status*/ + if (cali_info->thermal_value_lck == 0xff) { + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "no PG, do LCK\n"); + cali_info->thermal_value_lck = thermal_value; + + /*Use RTLCK, so close power tracking driver LCK*/ + if (!(dm->support_ic_type & ODM_RTL8814A) && + c.phy_lc_calibrate) + (*c.phy_lc_calibrate)(dm); + + delta_LCK = + (thermal_value > cali_info->thermal_value_lck) ? + (thermal_value - + cali_info->thermal_value_lck) : + (cali_info->thermal_value_lck - + thermal_value); + } + + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "(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(dm, ODM_COMP_TX_PWR_TRACK, + "delta_LCK(%d) >= threshold_iqk(%d)\n", + delta_LCK, c.threshold_iqk); + cali_info->thermal_value_lck = thermal_value; + + /*Use RTLCK, so close power tracking driver LCK*/ + if (!(dm->support_ic_type & ODM_RTL8814A) && + c.phy_lc_calibrate) + (*c.phy_lc_calibrate)(dm); + } + } + + /*3 7. If necessary, move the index of swing table to adjust Tx power.*/ + + if (delta > 0 && cali_info->txpowertrack_control) { + /* "delta" here is used to record the abs value of difference.*/ + delta = thermal_value > rtlefu->eeprom_thermalmeter ? + (thermal_value - rtlefu->eeprom_thermalmeter) : + (rtlefu->eeprom_thermalmeter - 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 > rtlefu->eeprom_thermalmeter) { + phydm_set_calibrate_info_up( + dm, &c, delta, cali_info, + delta_swing_table_idx_tup_a, + delta_swing_table_idx_tup_b, + delta_swing_table_idx_tup_c, + delta_swing_table_idx_tup_d); + /* JJ ADD 20161014 */ + if (dm->support_ic_type & + (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) { + /*Save xtal_offset from Xtal table*/ + + /*recording last Xtal offset*/ + cali_info->xtal_offset_last = + cali_info->xtal_offset; + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "[Xtal] delta_swing_table_xtal_up[%d] = %d\n", + delta, + delta_swing_table_xtal_up[delta]); + cali_info->xtal_offset = + delta_swing_table_xtal_up[delta]; + xtal_offset_eanble = + (cali_info->xtal_offset_last == + cali_info->xtal_offset) ? + 0 : + 1; + } + + } else { + phydm_set_calibrate_info_down( + dm, &c, delta, cali_info, + delta_swing_table_idx_tdown_a, + delta_swing_table_idx_tdown_b, + delta_swing_table_idx_tdown_c, + delta_swing_table_idx_tdown_d); + /* JJ ADD 20161014 */ + if (dm->support_ic_type & + (ODM_RTL8703B | ODM_RTL8723D | ODM_RTL8710B)) { + /*Save xtal_offset from Xtal table*/ + + /*recording last Xtal offset*/ + cali_info->xtal_offset_last = + cali_info->xtal_offset; + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "[Xtal] delta_swing_table_xtal_down[%d] = %d\n", + delta, + delta_swing_table_xtal_down[delta]); + cali_info->xtal_offset = + delta_swing_table_xtal_down[delta]; + xtal_offset_eanble = + (cali_info->xtal_offset_last == + cali_info->xtal_offset) ? + 0 : + 1; + } + } + + for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) { + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "\n\n=========================== [path-%d] Calculating power_index_offset===========================\n", + p); + + if (cali_info->delta_power_index[p] == + cali_info->delta_power_index_last[p]) { + /* If Thermal value changes but lookup table + * value still the same + */ + cali_info->power_index_offset[p] = 0; + } else { + /*Power idx diff between 2 times Pwr Tracking*/ + cali_info->power_index_offset[p] = + cali_info->delta_power_index[p] - + cali_info->delta_power_index_last[p]; + } + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "[path-%d] power_index_offset(%d) = delta_power_index(%d) - delta_power_index_last(%d)\n", + p, cali_info->power_index_offset[p], + cali_info->delta_power_index[p], + cali_info->delta_power_index_last[p]); + + cali_info->OFDM_index[p] = + cali_info->bb_swing_idx_ofdm_base[p] + + cali_info->power_index_offset[p]; + cali_info->CCK_index = + cali_info->bb_swing_idx_cck_base + + cali_info->power_index_offset[p]; + + cali_info->bb_swing_idx_cck = cali_info->CCK_index; + cali_info->bb_swing_idx_ofdm[p] = + cali_info->OFDM_index[p]; + + /*******Print BB Swing base and index Offset**********/ + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "The 'CCK' final index(%d) = BaseIndex(%d) + power_index_offset(%d)\n", + cali_info->bb_swing_idx_cck, + cali_info->bb_swing_idx_cck_base, + cali_info->power_index_offset[p]); + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "The 'OFDM' final index(%d) = BaseIndex[%d](%d) + power_index_offset(%d)\n", + cali_info->bb_swing_idx_ofdm[p], p, + cali_info->bb_swing_idx_ofdm_base[p], + cali_info->power_index_offset[p]); + + /*4 7.1 Handle boundary conditions of index.*/ + + if (cali_info->OFDM_index[p] > + c.swing_table_size_ofdm - 1) + cali_info->OFDM_index[p] = + c.swing_table_size_ofdm - 1; + else if (cali_info->OFDM_index[p] <= OFDM_min_index) + cali_info->OFDM_index[p] = OFDM_min_index; + } + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "\n\n========================================================================================================\n"); + + if (cali_info->CCK_index > c.swing_table_size_cck - 1) + cali_info->CCK_index = c.swing_table_size_cck - 1; + else if (cali_info->CCK_index <= 0) + cali_info->CCK_index = 0; + } else { + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "The thermal meter is unchanged or TxPowerTracking OFF(%d): thermal_value: %d, cali_info->thermal_value: %d\n", + cali_info->txpowertrack_control, thermal_value, + cali_info->thermal_value); + + for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) + cali_info->power_index_offset[p] = 0; + } + + /*Print Swing base & current*/ + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "TxPowerTracking: [CCK] Swing Current index: %d, Swing base index: %d\n", + cali_info->CCK_index, cali_info->bb_swing_idx_cck_base); + + for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "TxPowerTracking: [OFDM] Swing Current index: %d, Swing base index[%d]: %d\n", + cali_info->OFDM_index[p], p, + cali_info->bb_swing_idx_ofdm_base[p]); + + if ((dm->support_ic_type & ODM_RTL8814A)) { + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "power_tracking_type=%d\n", power_tracking_type); + + if (power_tracking_type == 0) { + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "**********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)(dm, MIX_MODE, p, + 0); + } else if (power_tracking_type == 1) { + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "**********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)( + dm, MIX_2G_TSSI_5G_MODE, p, 0); + } else if (power_tracking_type == 2) { + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "**********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)( + dm, MIX_5G_TSSI_2G_MODE, p, 0); + } else if (power_tracking_type == 3) { + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "**********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)(dm, TSSI_MODE, p, + 0); + } + /*Record last Power Tracking Thermal value*/ + cali_info->thermal_value = thermal_value; + + } else if ((cali_info->power_index_offset[ODM_RF_PATH_A] != 0 || + cali_info->power_index_offset[ODM_RF_PATH_B] != 0 || + cali_info->power_index_offset[ODM_RF_PATH_C] != 0 || + cali_info->power_index_offset[ODM_RF_PATH_D] != 0) && + cali_info->txpowertrack_control && + (rtlefu->eeprom_thermalmeter != 0xff)) { + /* 4 7.2 Configure the Swing Table to adjust Tx Power. */ + + /*Always true after Tx Power is adjusted by power tracking.*/ + cali_info->is_tx_power_changed = true; + /* 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 > cali_info->thermal_value) { + for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) { + /* print temperature increasing */ + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "Temperature Increasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", + p, cali_info->power_index_offset[p], + delta, thermal_value, + rtlefu->eeprom_thermalmeter, + cali_info->thermal_value); + } + } else if (thermal_value < + cali_info->thermal_value) { /*Low temperature*/ + for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) { + /* print temperature decreasing */ + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "Temperature Decreasing(%d): delta_pi: %d, delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", + p, cali_info->power_index_offset[p], + delta, thermal_value, + rtlefu->eeprom_thermalmeter, + cali_info->thermal_value); + } + } + + if (thermal_value > rtlefu->eeprom_thermalmeter) { + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "Temperature(%d) higher than PG value(%d)\n", + thermal_value, rtlefu->eeprom_thermalmeter); + + phydm_odm_tx_power_set(dm, &c, indexforchannel, 0); + } else { + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "Temperature(%d) lower than PG value(%d)\n", + thermal_value, rtlefu->eeprom_thermalmeter); + phydm_odm_tx_power_set(dm, &c, indexforchannel, 1); + } + + /*Record last time Power Tracking result as base.*/ + cali_info->bb_swing_idx_cck_base = cali_info->bb_swing_idx_cck; + + for (p = ODM_RF_PATH_A; p < c.rf_path_count; p++) + cali_info->bb_swing_idx_ofdm_base[p] = + cali_info->bb_swing_idx_ofdm[p]; + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "cali_info->thermal_value = %d thermal_value= %d\n", + cali_info->thermal_value, thermal_value); + + /*Record last Power Tracking Thermal value*/ + cali_info->thermal_value = thermal_value; + } + + if (dm->support_ic_type == ODM_RTL8703B || + dm->support_ic_type == ODM_RTL8723D || + dm->support_ic_type == ODM_RTL8710B) { /* JJ ADD 20161014 */ + + if (xtal_offset_eanble != 0 && + cali_info->txpowertrack_control && + (rtlefu->eeprom_thermalmeter != 0xff)) { + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "**********Enter Xtal Tracking**********\n"); + + if (thermal_value > rtlefu->eeprom_thermalmeter) { + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "Temperature(%d) higher than PG value(%d)\n", + thermal_value, + rtlefu->eeprom_thermalmeter); + (*c.odm_txxtaltrack_set_xtal)(dm); + } else { + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "Temperature(%d) lower than PG value(%d)\n", + thermal_value, + rtlefu->eeprom_thermalmeter); + (*c.odm_txxtaltrack_set_xtal)(dm); + } + } + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "**********End Xtal Tracking**********\n"); + } + + if (!IS_HARDWARE_TYPE_8723B(adapter)) { + /* Delta temperature is equal to or larger than 20 centigrade + * (When threshold is 8). + */ + if (delta_IQK >= c.threshold_iqk) { + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "delta_IQK(%d) >= threshold_iqk(%d)\n", + delta_IQK, c.threshold_iqk); + if (!cali_info->is_iqk_in_progress) + (*c.do_iqk)(dm, delta_IQK, thermal_value, 8); + } + } + if (cali_info->dpk_thermal[ODM_RF_PATH_A] != 0) { + if (diff_DPK[ODM_RF_PATH_A] >= c.threshold_dpk) { + odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1); + odm_set_bb_reg( + dm, 0xcc4, + BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), + (diff_DPK[ODM_RF_PATH_A] / c.threshold_dpk)); + odm_set_bb_reg(dm, 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(dm, 0x82c, BIT(31), 0x1); + odm_set_bb_reg(dm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | + BIT(11) | BIT(10), + value); + odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0); + } else { + odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1); + odm_set_bb_reg(dm, 0xcc4, BIT(14) | BIT(13) | BIT(12) | + BIT(11) | BIT(10), + 0); + odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0); + } + } + if (cali_info->dpk_thermal[ODM_RF_PATH_B] != 0) { + if (diff_DPK[ODM_RF_PATH_B] >= c.threshold_dpk) { + odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1); + odm_set_bb_reg( + dm, 0xec4, + BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10), + (diff_DPK[ODM_RF_PATH_B] / c.threshold_dpk)); + odm_set_bb_reg(dm, 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(dm, 0x82c, BIT(31), 0x1); + odm_set_bb_reg(dm, 0xec4, BIT(14) | BIT(13) | BIT(12) | + BIT(11) | BIT(10), + value); + odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0); + } else { + odm_set_bb_reg(dm, 0x82c, BIT(31), 0x1); + odm_set_bb_reg(dm, 0xec4, BIT(14) | BIT(13) | BIT(12) | + BIT(11) | BIT(10), + 0); + odm_set_bb_reg(dm, 0x82c, BIT(31), 0x0); + } + } + + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, "<===%s\n", __func__); + + cali_info->tx_powercount = 0; +} + +/* 3============================================================ + * 3 IQ Calibration + * 3============================================================ + */ + +void odm_reset_iqk_result(void *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 *dm) +{ + void *adapter = dm->adapter; + + if (IS_HARDWARE_TYPE_8812AU(adapter)) + return; + + if (dm->is_linked) { + if ((*dm->channel != dm->pre_channel) && + (!*dm->is_scan_in_process)) { + dm->pre_channel = *dm->channel; + dm->linked_interval = 0; + } + + if (dm->linked_interval < 3) + dm->linked_interval++; + + if (dm->linked_interval == 2) { + if (IS_HARDWARE_TYPE_8814A(adapter)) + ; + + else if (IS_HARDWARE_TYPE_8822B(adapter)) + phy_iq_calibrate_8822b(dm, false); + } + } else { + dm->linked_interval = 0; + } +} + +void phydm_rf_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + odm_txpowertracking_init(dm); + + odm_clear_txpowertracking_state(dm); +} + +void phydm_rf_watchdog(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + odm_txpowertracking_check(dm); + if (dm->support_ic_type & ODM_IC_11AC_SERIES) + odm_iq_calibrate(dm); +} diff --git a/drivers/staging/rtlwifi/phydm/halphyrf_ce.h b/drivers/staging/rtlwifi/phydm/halphyrf_ce.h new file mode 100644 index 000000000000..e5d6257efb2b --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/halphyrf_ce.h @@ -0,0 +1,85 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __HAL_PHY_RF_H__ +#define __HAL_PHY_RF_H__ + +#include "phydm_kfree.h" + +#include "rtl8822b/phydm_iqk_8822b.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 *dm_void, struct txpwrtrack_cfg *config); + +void odm_clear_txpowertracking_state(void *dm_void); + +void odm_txpowertracking_callback_thermal_meter(void *dm); + +#define ODM_TARGET_CHNL_NUM_2G_5G 59 + +void odm_reset_iqk_result(void *dm_void); +u8 odm_get_right_chnl_place_for_iqk(u8 chnl); + +void phydm_rf_init(void *dm_void); +void phydm_rf_watchdog(void *dm_void); + +#endif /* #ifndef __HAL_PHY_RF_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/mp_precomp.h b/drivers/staging/rtlwifi/phydm/mp_precomp.h new file mode 100644 index 000000000000..b313de511ed6 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/mp_precomp.h @@ -0,0 +1,24 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ diff --git a/drivers/staging/rtlwifi/phydm/phydm.c b/drivers/staging/rtlwifi/phydm/phydm.c new file mode 100644 index 000000000000..37888c3087a4 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm.c @@ -0,0 +1,1986 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include 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--------------- */ + +static void odm_update_power_training_state(struct phy_dm_struct *dm); + +/* ************************************************************ + * 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 is 0.5dB*3=1.5dB~=2dB */ + decimal = (X & BIT(i - 1)) ? 2 : 0; + } + 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 *dm_void, u32 *value, u32 *rank_idx, u32 *idx_out, + u8 seq_length) +{ + 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 = value[j]; + tmp_b = value[j + 1]; + + tmp_idx_a = rank_idx[j]; + tmp_idx_b = rank_idx[j + 1]; + + if (tmp_a < tmp_b) { + value[j] = tmp_b; + 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++) { + idx_out[rank_idx[i]] = i + 1; + /**/ + } +} + +void odm_init_mp_driver_status(struct phy_dm_struct *dm) +{ + dm->mp_mode = false; +} + +static void odm_update_mp_driver_status(struct phy_dm_struct *dm) +{ + /* Do nothing. */ +} + +static void phydm_init_trx_antenna_setting(struct phy_dm_struct *dm) +{ + /*#if (RTL8814A_SUPPORT == 1)*/ + + if (dm->support_ic_type & (ODM_RTL8814A)) { + u8 rx_ant = 0, tx_ant = 0; + + rx_ant = (u8)odm_get_bb_reg(dm, ODM_REG(BB_RX_PATH, dm), + ODM_BIT(BB_RX_PATH, dm)); + tx_ant = (u8)odm_get_bb_reg(dm, ODM_REG(BB_TX_PATH, dm), + ODM_BIT(BB_TX_PATH, dm)); + dm->tx_ant_status = (tx_ant & 0xf); + dm->rx_ant_status = (rx_ant & 0xf); + } else if (dm->support_ic_type & (ODM_RTL8723D | ODM_RTL8821C | + ODM_RTL8710B)) { /* JJ ADD 20161014 */ + dm->tx_ant_status = 0x1; + dm->rx_ant_status = 0x1; + } + /*#endif*/ +} + +static void phydm_traffic_load_decision(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + /*---TP & Trafic-load calculation---*/ + + if (dm->last_tx_ok_cnt > *dm->num_tx_bytes_unicast) + dm->last_tx_ok_cnt = *dm->num_tx_bytes_unicast; + + if (dm->last_rx_ok_cnt > *dm->num_rx_bytes_unicast) + dm->last_rx_ok_cnt = *dm->num_rx_bytes_unicast; + + dm->cur_tx_ok_cnt = *dm->num_tx_bytes_unicast - dm->last_tx_ok_cnt; + dm->cur_rx_ok_cnt = *dm->num_rx_bytes_unicast - dm->last_rx_ok_cnt; + dm->last_tx_ok_cnt = *dm->num_tx_bytes_unicast; + dm->last_rx_ok_cnt = *dm->num_rx_bytes_unicast; + + dm->tx_tp = ((dm->tx_tp) >> 1) + + (u32)(((dm->cur_tx_ok_cnt) >> 18) >> + 1); /* <<3(8bit), >>20(10^6,M), >>1(2sec)*/ + dm->rx_tp = ((dm->rx_tp) >> 1) + + (u32)(((dm->cur_rx_ok_cnt) >> 18) >> + 1); /* <<3(8bit), >>20(10^6,M), >>1(2sec)*/ + dm->total_tp = dm->tx_tp + dm->rx_tp; + + dm->pre_traffic_load = dm->traffic_load; + + if (dm->cur_tx_ok_cnt > 1875000 || + dm->cur_rx_ok_cnt > + 1875000) { /* ( 1.875M * 8bit ) / 2sec= 7.5M bits /sec )*/ + + dm->traffic_load = TRAFFIC_HIGH; + /**/ + } else if ( + dm->cur_tx_ok_cnt > 500000 || + dm->cur_rx_ok_cnt > + 500000) { /*( 0.5M * 8bit ) / 2sec = 2M bits /sec )*/ + + dm->traffic_load = TRAFFIC_MID; + /**/ + } else if ( + dm->cur_tx_ok_cnt > 100000 || + dm->cur_rx_ok_cnt > + 100000) { /*( 0.1M * 8bit ) / 2sec = 0.4M bits /sec )*/ + + dm->traffic_load = TRAFFIC_LOW; + /**/ + } else { + dm->traffic_load = TRAFFIC_ULTRA_LOW; + /**/ + } +} + +static void phydm_config_ofdm_tx_path(struct phy_dm_struct *dm, u32 path) {} + +void phydm_config_ofdm_rx_path(struct phy_dm_struct *dm, u32 path) +{ + u8 ofdm_rx_path = 0; + + if (dm->support_ic_type & (ODM_RTL8192E)) { + } else if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8822B)) { + if (path == PHYDM_A) { + ofdm_rx_path = 1; + /**/ + } else if (path == PHYDM_B) { + ofdm_rx_path = 2; + /**/ + } else if (path == PHYDM_AB) { + ofdm_rx_path = 3; + /**/ + } + + odm_set_bb_reg(dm, 0x808, MASKBYTE0, + ((ofdm_rx_path << 4) | ofdm_rx_path)); + } +} + +static void phydm_config_cck_rx_antenna_init(struct phy_dm_struct *dm) {} + +static void phydm_config_cck_rx_path(struct phy_dm_struct *dm, u8 path, + u8 path_div_en) +{ +} + +void phydm_config_trx_path(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + 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(dm, 0xa04, 0xf0000000, 0x8); + else if (dm_value[2] == 2) + odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x4); + else if (dm_value[2] == 3) + odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0xc); + } else if (dm_value[1] == 2) { /*RX*/ + + phydm_config_cck_rx_antenna_init(dm); + + if (dm_value[2] == 1) + phydm_config_cck_rx_path(dm, PHYDM_A, + CCA_PATHDIV_DISABLE); + else if (dm_value[2] == 2) + phydm_config_cck_rx_path(dm, PHYDM_B, + CCA_PATHDIV_DISABLE); + else if (dm_value[2] == 3 && + dm_value[3] == 1) /*enable path diversity*/ + phydm_config_cck_rx_path(dm, PHYDM_AB, + CCA_PATHDIV_ENABLE); + else if (dm_value[2] == 3 && dm_value[3] != 1) + phydm_config_cck_rx_path(dm, PHYDM_B, + CCA_PATHDIV_DISABLE); + } + } + /* OFDM */ + else if (dm_value[0] == 1) { + if (dm_value[1] == 1) { /*TX*/ + phydm_config_ofdm_tx_path(dm, dm_value[2]); + /**/ + } else if (dm_value[1] == 2) { /*RX*/ + phydm_config_ofdm_rx_path(dm, 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 *dm) +{ + dm->is_cck_high_power = (bool)odm_get_bb_reg( + dm, ODM_REG(CCK_RPT_FORMAT, dm), ODM_BIT(CCK_RPT_FORMAT, dm)); + + /* JJ ADD 20161014 */ + /* JJ ADD 20161014 */ + if (dm->support_ic_type & (ODM_RTL8723D | ODM_RTL8822B | ODM_RTL8197F | + ODM_RTL8821C | ODM_RTL8710B)) + dm->cck_new_agc = odm_get_bb_reg(dm, 0xa9c, BIT(17)) ? + true : + false; /*1: new agc 0: old agc*/ + else + dm->cck_new_agc = false; +} + +static void phydm_init_soft_ml_setting(struct phy_dm_struct *dm) +{ + if (!dm->mp_mode) { + if (dm->support_ic_type & ODM_RTL8822B) + odm_set_bb_reg(dm, 0x19a8, MASKDWORD, 0xc10a0000); + } +} + +static void phydm_init_hw_info_by_rfe(struct phy_dm_struct *dm) +{ + if (dm->support_ic_type & ODM_RTL8822B) + phydm_init_hw_info_by_rfe_type_8822b(dm); +} + +static void odm_common_info_self_init(struct phy_dm_struct *dm) +{ + phydm_init_cck_setting(dm); + dm->rf_path_rx_enable = (u8)odm_get_bb_reg(dm, ODM_REG(BB_RX_PATH, dm), + ODM_BIT(BB_RX_PATH, dm)); + odm_init_mp_driver_status(dm); + phydm_init_trx_antenna_setting(dm); + phydm_init_soft_ml_setting(dm); + + dm->phydm_period = PHYDM_WATCH_DOG_PERIOD; + dm->phydm_sys_up_time = 0; + + if (dm->support_ic_type & ODM_IC_1SS) + dm->num_rf_path = 1; + else if (dm->support_ic_type & ODM_IC_2SS) + dm->num_rf_path = 2; + else if (dm->support_ic_type & ODM_IC_3SS) + dm->num_rf_path = 3; + else if (dm->support_ic_type & ODM_IC_4SS) + dm->num_rf_path = 4; + + dm->tx_rate = 0xFF; + + dm->number_linked_client = 0; + dm->pre_number_linked_client = 0; + dm->number_active_client = 0; + dm->pre_number_active_client = 0; + + dm->last_tx_ok_cnt = 0; + dm->last_rx_ok_cnt = 0; + dm->tx_tp = 0; + dm->rx_tp = 0; + dm->total_tp = 0; + dm->traffic_load = TRAFFIC_LOW; + + dm->nbi_set_result = 0; + dm->is_init_hw_info_by_rfe = false; + dm->pre_dbg_priority = BB_DBGPORT_RELEASE; +} + +static void odm_common_info_self_update(struct phy_dm_struct *dm) +{ + u8 entry_cnt = 0, num_active_client = 0; + u32 i, one_entry_macid = 0; + struct rtl_sta_info *entry; + + /* THis variable cannot be used because it is wrong*/ + if (*dm->band_width == ODM_BW40M) { + if (*dm->sec_ch_offset == 1) + dm->control_channel = *dm->channel - 2; + else if (*dm->sec_ch_offset == 2) + dm->control_channel = *dm->channel + 2; + } else { + dm->control_channel = *dm->channel; + } + + for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { + entry = dm->odm_sta_info[i]; + if (IS_STA_VALID(entry)) { + entry_cnt++; + if (entry_cnt == 1) + one_entry_macid = i; + } + } + + if (entry_cnt == 1) { + dm->is_one_entry_only = true; + dm->one_entry_macid = one_entry_macid; + } else { + dm->is_one_entry_only = false; + } + + dm->pre_number_linked_client = dm->number_linked_client; + dm->pre_number_active_client = dm->number_active_client; + + dm->number_linked_client = entry_cnt; + dm->number_active_client = num_active_client; + + /* Update MP driver status*/ + odm_update_mp_driver_status(dm); + + /*Traffic load information update*/ + phydm_traffic_load_decision(dm); + + dm->phydm_sys_up_time += dm->phydm_period; +} + +static void odm_common_info_self_reset(struct phy_dm_struct *dm) +{ + dm->phy_dbg_info.num_qry_beacon_pkt = 0; +} + +void *phydm_get_structure(struct phy_dm_struct *dm, u8 structure_type) + +{ + void *p_struct = NULL; + + switch (structure_type) { + case PHYDM_FALSEALMCNT: + p_struct = &dm->false_alm_cnt; + break; + + case PHYDM_CFOTRACK: + p_struct = &dm->dm_cfo_track; + break; + + case PHYDM_ADAPTIVITY: + p_struct = &dm->adaptivity; + break; + + default: + break; + } + + return p_struct; +} + +static void odm_hw_setting(struct phy_dm_struct *dm) +{ + if (dm->support_ic_type & ODM_RTL8822B) + phydm_hwsetting_8822b(dm); +} + +static void phydm_supportability_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 support_ability = 0; + + if (dm->support_ic_type != ODM_RTL8821C) + return; + + switch (dm->support_ic_type) { + /*---------------AC Series-------------------*/ + + 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; + + default: + 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; + + ODM_RT_TRACE(dm, ODM_COMP_UNCOND, + "[Warning] Supportability Init Warning !!!\n"); + break; + } + + if (*dm->enable_antdiv) + support_ability |= ODM_BB_ANT_DIV; + + if (*dm->enable_adaptivity) { + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "ODM adaptivity is set to Enabled!!!\n"); + + support_ability |= ODM_BB_ADAPTIVITY; + + } else { + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "ODM adaptivity is set to disnabled!!!\n"); + /**/ + } + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "PHYDM support_ability = ((0x%x))\n", + support_ability); + odm_cmn_info_init(dm, ODM_CMNINFO_ABILITY, support_ability); +} + +/* + * 2011/09/21 MH Add to describe different team necessary resource allocate?? + */ +void odm_dm_init(struct phy_dm_struct *dm) +{ + phydm_supportability_init(dm); + odm_common_info_self_init(dm); + odm_dig_init(dm); + phydm_nhm_counter_statistics_init(dm); + phydm_adaptivity_init(dm); + phydm_ra_info_init(dm); + odm_rate_adaptive_mask_init(dm); + odm_cfo_tracking_init(dm); + odm_edca_turbo_init(dm); + odm_rssi_monitor_init(dm); + phydm_rf_init(dm); + odm_txpowertracking_init(dm); + + if (dm->support_ic_type & ODM_RTL8822B) + phydm_txcurrentcalibration(dm); + + odm_antenna_diversity_init(dm); + odm_auto_channel_select_init(dm); + odm_dynamic_tx_power_init(dm); + phydm_init_ra_info(dm); + adc_smp_init(dm); + + phydm_beamforming_init(dm); + + if (dm->support_ic_type & ODM_IC_11N_SERIES) { + /* 11n series */ + odm_dynamic_bb_power_saving_init(dm); + } + + phydm_psd_init(dm); +} + +void odm_dm_reset(struct phy_dm_struct *dm) +{ + struct dig_thres *dig_tab = &dm->dm_dig_table; + + odm_ant_div_reset(dm); + phydm_set_edcca_threshold_api(dm, dig_tab->cur_ig_value); +} + +void phydm_support_ability_debug(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 pre_support_ability; + u32 used = *_used; + u32 out_len = *_out_len; + + pre_support_ability = dm->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", + ((dm->support_ability & ODM_BB_DIG) ? ("V") : ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "01. ((