| /****************************************************************************** |
| * |
| * 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 <wlanfae@realtek.com> |
| * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, |
| * Hsinchu 300, Taiwan. |
| * |
| * Larry Finger <Larry.Finger@lwfinger.net> |
| * |
| *****************************************************************************/ |
| |
| /* ************************************************************ |
| * include files |
| * *************************************************************/ |
| |
| #include "mp_precomp.h" |
| #include "phydm_precomp.h" |
| |
| #define READ_AND_CONFIG_MP(ic, txt) (odm_read_and_config_mp_##ic##txt(dm)) |
| #define READ_AND_CONFIG_TC(ic, txt) (odm_read_and_config_tc_##ic##txt(dm)) |
| |
| #define READ_AND_CONFIG READ_AND_CONFIG_MP |
| |
| #define READ_FIRMWARE_MP(ic, txt) \ |
| (odm_read_firmware_mp_##ic##txt(dm, p_firmware, size)) |
| #define READ_FIRMWARE_TC(ic, txt) \ |
| (odm_read_firmware_tc_##ic##txt(dm, p_firmware, size)) |
| |
| #define READ_FIRMWARE READ_FIRMWARE_MP |
| |
| #define GET_VERSION_MP(ic, txt) (odm_get_version_mp_##ic##txt()) |
| #define GET_VERSION_TC(ic, txt) (odm_get_version_tc_##ic##txt()) |
| |
| #define GET_VERSION(ic, txt) GET_VERSION_MP(ic, txt) |
| |
| static u32 phydm_process_rssi_pwdb(struct phy_dm_struct *dm, |
| struct rtl_sta_info *entry, |
| struct dm_per_pkt_info *pktinfo, |
| u32 undecorated_smoothed_ofdm, |
| u32 undecorated_smoothed_cck) |
| { |
| u32 weighting = 0, undecorated_smoothed_pwdb; |
| /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */ |
| |
| if (entry->rssi_stat.ofdm_pkt == |
| 64) { /* speed up when all packets are OFDM*/ |
| undecorated_smoothed_pwdb = undecorated_smoothed_ofdm; |
| ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, |
| "PWDB_0[%d] = (( %d ))\n", pktinfo->station_id, |
| undecorated_smoothed_cck); |
| } else { |
| if (entry->rssi_stat.valid_bit < 64) |
| entry->rssi_stat.valid_bit++; |
| |
| if (entry->rssi_stat.valid_bit == 64) { |
| weighting = ((entry->rssi_stat.ofdm_pkt) > 4) ? |
| 64 : |
| (entry->rssi_stat.ofdm_pkt << 4); |
| undecorated_smoothed_pwdb = |
| (weighting * undecorated_smoothed_ofdm + |
| (64 - weighting) * undecorated_smoothed_cck) >> |
| 6; |
| ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, |
| "PWDB_1[%d] = (( %d )), W = (( %d ))\n", |
| pktinfo->station_id, |
| undecorated_smoothed_cck, weighting); |
| } else { |
| if (entry->rssi_stat.valid_bit != 0) |
| undecorated_smoothed_pwdb = |
| (entry->rssi_stat.ofdm_pkt * |
| undecorated_smoothed_ofdm + |
| (entry->rssi_stat.valid_bit - |
| entry->rssi_stat.ofdm_pkt) * |
| undecorated_smoothed_cck) / |
| entry->rssi_stat.valid_bit; |
| else |
| undecorated_smoothed_pwdb = 0; |
| |
| ODM_RT_TRACE( |
| dm, ODM_COMP_RSSI_MONITOR, |
| "PWDB_2[%d] = (( %d )), ofdm_pkt = (( %d )), Valid_Bit = (( %d ))\n", |
| pktinfo->station_id, undecorated_smoothed_cck, |
| entry->rssi_stat.ofdm_pkt, |
| entry->rssi_stat.valid_bit); |
| } |
| } |
| |
| return undecorated_smoothed_pwdb; |
| } |
| |
| static u32 phydm_process_rssi_cck(struct phy_dm_struct *dm, |
| struct dm_phy_status_info *phy_info, |
| struct rtl_sta_info *entry, |
| u32 undecorated_smoothed_cck) |
| { |
| u32 rssi_ave; |
| u8 i; |
| |
| rssi_ave = phy_info->rx_pwdb_all; |
| dm->rssi_a = (u8)phy_info->rx_pwdb_all; |
| dm->rssi_b = 0xFF; |
| dm->rssi_c = 0xFF; |
| dm->rssi_d = 0xFF; |
| |
| if (entry->rssi_stat.cck_pkt <= 63) |
| entry->rssi_stat.cck_pkt++; |
| |
| /* 1 Process CCK RSSI */ |
| if (undecorated_smoothed_cck <= 0) { /* initialize */ |
| undecorated_smoothed_cck = phy_info->rx_pwdb_all; |
| entry->rssi_stat.cck_sum_power = |
| (u16)phy_info->rx_pwdb_all; /*reset*/ |
| entry->rssi_stat.cck_pkt = 1; /*reset*/ |
| ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, "CCK_INIT: (( %d ))\n", |
| undecorated_smoothed_cck); |
| } else if (entry->rssi_stat.cck_pkt <= CCK_RSSI_INIT_COUNT) { |
| entry->rssi_stat.cck_sum_power = |
| entry->rssi_stat.cck_sum_power + |
| (u16)phy_info->rx_pwdb_all; |
| undecorated_smoothed_cck = entry->rssi_stat.cck_sum_power / |
| entry->rssi_stat.cck_pkt; |
| |
| ODM_RT_TRACE( |
| dm, ODM_COMP_RSSI_MONITOR, |
| "CCK_0: (( %d )), SumPow = (( %d )), cck_pkt = (( %d ))\n", |
| undecorated_smoothed_cck, |
| entry->rssi_stat.cck_sum_power, |
| entry->rssi_stat.cck_pkt); |
| } else { |
| if (phy_info->rx_pwdb_all > (u32)undecorated_smoothed_cck) { |
| undecorated_smoothed_cck = |
| (((undecorated_smoothed_cck) * |
| (RX_SMOOTH_FACTOR - 1)) + |
| (phy_info->rx_pwdb_all)) / |
| (RX_SMOOTH_FACTOR); |
| undecorated_smoothed_cck = undecorated_smoothed_cck + 1; |
| ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, |
| "CCK_1: (( %d ))\n", |
| undecorated_smoothed_cck); |
| } else { |
| undecorated_smoothed_cck = |
| (((undecorated_smoothed_cck) * |
| (RX_SMOOTH_FACTOR - 1)) + |
| (phy_info->rx_pwdb_all)) / |
| (RX_SMOOTH_FACTOR); |
| ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, |
| "CCK_2: (( %d ))\n", |
| undecorated_smoothed_cck); |
| } |
| } |
| |
| i = 63; |
| entry->rssi_stat.ofdm_pkt -= |
| (u8)((entry->rssi_stat.packet_map >> i) & BIT(0)); |
| entry->rssi_stat.packet_map = entry->rssi_stat.packet_map << 1; |
| return undecorated_smoothed_cck; |
| } |
| |
| static u32 phydm_process_rssi_ofdm(struct phy_dm_struct *dm, |
| struct dm_phy_status_info *phy_info, |
| struct rtl_sta_info *entry, |
| u32 undecorated_smoothed_ofdm) |
| { |
| u32 rssi_ave; |
| u8 rssi_max, rssi_min, i; |
| |
| if (dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B)) { |
| u8 rx_count = 0; |
| u32 rssi_linear = 0; |
| |
| if (dm->rx_ant_status & ODM_RF_A) { |
| dm->rssi_a = phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_A]; |
| rx_count++; |
| rssi_linear += odm_convert_to_linear( |
| phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_A]); |
| } else { |
| dm->rssi_a = 0; |
| } |
| |
| if (dm->rx_ant_status & ODM_RF_B) { |
| dm->rssi_b = phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_B]; |
| rx_count++; |
| rssi_linear += odm_convert_to_linear( |
| phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_B]); |
| } else { |
| dm->rssi_b = 0; |
| } |
| |
| if (dm->rx_ant_status & ODM_RF_C) { |
| dm->rssi_c = phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_C]; |
| rx_count++; |
| rssi_linear += odm_convert_to_linear( |
| phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_C]); |
| } else { |
| dm->rssi_c = 0; |
| } |
| |
| if (dm->rx_ant_status & ODM_RF_D) { |
| dm->rssi_d = phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_D]; |
| rx_count++; |
| rssi_linear += odm_convert_to_linear( |
| phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_D]); |
| } else { |
| dm->rssi_d = 0; |
| } |
| |
| /* Calculate average RSSI */ |
| switch (rx_count) { |
| case 2: |
| rssi_linear = (rssi_linear >> 1); |
| break; |
| case 3: |
| /* rssi_linear/3 ~ rssi_linear*11/32 */ |
| rssi_linear = ((rssi_linear) + (rssi_linear << 1) + |
| (rssi_linear << 3)) >> |
| 5; |
| break; |
| case 4: |
| rssi_linear = (rssi_linear >> 2); |
| break; |
| } |
| |
| rssi_ave = odm_convert_to_db(rssi_linear); |
| } else { |
| if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B] == 0) { |
| rssi_ave = phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_A]; |
| dm->rssi_a = phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_A]; |
| dm->rssi_b = 0; |
| } else { |
| dm->rssi_a = phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_A]; |
| dm->rssi_b = phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_B]; |
| |
| if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] > |
| phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) { |
| rssi_max = phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_A]; |
| rssi_min = phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_B]; |
| } else { |
| rssi_max = phy_info->rx_mimo_signal_strength |
| [ODM_RF_PATH_B]; |
| rssi_min = 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 = phy_info->rx_pwdb_all; |
| ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, "OFDM_INIT: (( %d ))\n", |
| undecorated_smoothed_ofdm); |
| } else { |
| if (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(dm, ODM_COMP_RSSI_MONITOR, |
| "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(dm, ODM_COMP_RSSI_MONITOR, |
| "OFDM_2: (( %d ))\n", |
| undecorated_smoothed_ofdm); |
| } |
| } |
| |
| if (entry->rssi_stat.ofdm_pkt != 64) { |
| i = 63; |
| entry->rssi_stat.ofdm_pkt -= |
| (u8)(((entry->rssi_stat.packet_map >> i) & BIT(0)) - 1); |
| } |
| |
| entry->rssi_stat.packet_map = |
| (entry->rssi_stat.packet_map << 1) | BIT(0); |
| return undecorated_smoothed_ofdm; |
| } |
| |
| static u8 odm_evm_db_to_percentage(s8); |
| static u8 odm_evm_dbm_jaguar_series(s8); |
| |
| static inline u32 phydm_get_rssi_average(struct phy_dm_struct *dm, |
| struct dm_phy_status_info *phy_info) |
| { |
| u8 rssi_max = 0, rssi_min = 0; |
| |
| dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A]; |
| dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]; |
| |
| if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] > |
| phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) { |
| rssi_max = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A]; |
| rssi_min = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]; |
| } else { |
| rssi_max = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]; |
| rssi_min = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A]; |
| } |
| if ((rssi_max - rssi_min) < 3) |
| return rssi_max; |
| else if ((rssi_max - rssi_min) < 6) |
| return rssi_max - 1; |
| else if ((rssi_max - rssi_min) < 10) |
| return rssi_max - 2; |
| else |
| return rssi_max - 3; |
| } |
| |
| static inline u8 phydm_get_evm_dbm(u8 i, u8 EVM, |
| struct phy_status_rpt_8812 *phy_sta_rpt, |
| struct dm_phy_status_info *phy_info) |
| { |
| if (i < ODM_RF_PATH_C) |
| return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm[i]); |
| else |
| return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm_cd[i - 2]); |
| /*RT_DISP(FRX, RX_PHY_SQ, ("RXRATE=%x RXEVM=%x EVM=%s%d\n",*/ |
| /*pktinfo->data_rate, phy_sta_rpt->rxevm[i], "%", EVM));*/ |
| } |
| |
| static inline u8 phydm_get_odm_evm(u8 i, struct dm_per_pkt_info *pktinfo, |
| struct phy_status_rpt_8812 *phy_sta_rpt) |
| { |
| u8 evm = 0; |
| |
| if (pktinfo->data_rate >= ODM_RATE6M && |
| pktinfo->data_rate <= ODM_RATE54M) { |
| if (i == ODM_RF_PATH_A) { |
| evm = odm_evm_db_to_percentage( |
| (phy_sta_rpt->sigevm)); /*dbm*/ |
| evm += 20; |
| if (evm > 100) |
| evm = 100; |
| } |
| } else { |
| if (i < ODM_RF_PATH_C) { |
| if (phy_sta_rpt->rxevm[i] == -128) |
| phy_sta_rpt->rxevm[i] = -25; |
| evm = odm_evm_db_to_percentage( |
| (phy_sta_rpt->rxevm[i])); /*dbm*/ |
| } else { |
| if (phy_sta_rpt->rxevm_cd[i - 2] == -128) |
| phy_sta_rpt->rxevm_cd[i - 2] = -25; |
| evm = odm_evm_db_to_percentage( |
| (phy_sta_rpt->rxevm_cd[i - 2])); /*dbm*/ |
| } |
| } |
| |
| return evm; |
| } |
| |
| static inline s8 phydm_get_rx_pwr(u8 LNA_idx, u8 VGA_idx, u8 cck_highpwr) |
| { |
| switch (LNA_idx) { |
| case 7: |
| if (VGA_idx <= 27) |
| return -100 + 2 * (27 - VGA_idx); /*VGA_idx = 27~2*/ |
| else |
| return -100; |
| break; |
| case 6: |
| return -48 + 2 * (2 - VGA_idx); /*VGA_idx = 2~0*/ |
| case 5: |
| return -42 + 2 * (7 - VGA_idx); /*VGA_idx = 7~5*/ |
| case 4: |
| return -36 + 2 * (7 - VGA_idx); /*VGA_idx = 7~4*/ |
| case 3: |
| return -24 + 2 * (7 - VGA_idx); /*VGA_idx = 7~0*/ |
| case 2: |
| if (cck_highpwr) |
| return -12 + 2 * (5 - VGA_idx); /*VGA_idx = 5~0*/ |
| else |
| return -6 + 2 * (5 - VGA_idx); |
| break; |
| case 1: |
| return 8 - 2 * VGA_idx; |
| case 0: |
| return 14 - 2 * VGA_idx; |
| default: |
| break; |
| } |
| return 0; |
| } |
| |
| static inline u8 phydm_adjust_pwdb(u8 cck_highpwr, u8 pwdb_all) |
| { |
| if (!cck_highpwr) { |
| if (pwdb_all >= 80) |
| return ((pwdb_all - 80) << 1) + ((pwdb_all - 80) >> 1) + |
| 80; |
| else if ((pwdb_all <= 78) && (pwdb_all >= 20)) |
| return pwdb_all + 3; |
| if (pwdb_all > 100) |
| return 100; |
| } |
| return pwdb_all; |
| } |
| |
| static inline u8 |
| phydm_get_signal_quality_8812(struct dm_phy_status_info *phy_info, |
| struct phy_dm_struct *dm, |
| struct phy_status_rpt_8812 *phy_sta_rpt) |
| { |
| u8 sq_rpt; |
| |
| if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test) |
| return 100; |
| |
| sq_rpt = phy_sta_rpt->pwdb_all; |
| |
| if (sq_rpt > 64) |
| return 0; |
| else if (sq_rpt < 20) |
| return 100; |
| else |
| return ((64 - sq_rpt) * 100) / 44; |
| } |
| |
| static inline u8 |
| phydm_get_signal_quality_8192(struct dm_phy_status_info *phy_info, |
| struct phy_dm_struct *dm, |
| struct phy_status_rpt_8192cd *phy_sta_rpt) |
| { |
| u8 sq_rpt; |
| |
| if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test) |
| return 100; |
| |
| sq_rpt = phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all; |
| |
| if (sq_rpt > 64) |
| return 0; |
| else if (sq_rpt < 20) |
| return 100; |
| else |
| return ((64 - sq_rpt) * 100) / 44; |
| } |
| |
| 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.?? |
| */ |
| |
| s32 odm_signal_scale_mapping(struct phy_dm_struct *dm, s32 curr_sig) |
| { |
| { |
| return curr_sig; |
| } |
| } |
| |
| static u8 odm_sq_process_patch_rt_cid_819x_lenovo(struct phy_dm_struct *dm, |
| 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; |
| |
| 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; |
| |
| 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 *dm, 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; |
| } |
| |
| static void odm_rx_phy_status92c_series_parsing( |
| struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info, |
| u8 *phy_status, struct dm_per_pkt_info *pktinfo) |
| { |
| 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 LNA_idx = 0; |
| u8 VGA_idx = 0; |
| u8 cck_agc_rpt; |
| u8 num_ss; |
| struct phy_status_rpt_8192cd *phy_sta_rpt = |
| (struct phy_status_rpt_8192cd *)phy_status; |
| |
| is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false; |
| |
| if (pktinfo->is_to_self) |
| dm->curr_station_id = pktinfo->station_id; |
| |
| phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1; |
| phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1; |
| |
| if (is_cck_rate) { |
| dm->phy_dbg_info.num_qry_phy_status_cck++; |
| cck_agc_rpt = phy_sta_rpt->cck_agc_rpt_ofdm_cfosho_a; |
| |
| if (dm->support_ic_type & (ODM_RTL8703B)) { |
| } else { /*3 bit LNA*/ |
| |
| LNA_idx = ((cck_agc_rpt & 0xE0) >> 5); |
| VGA_idx = (cck_agc_rpt & 0x1F); |
| } |
| |
| ODM_RT_TRACE( |
| dm, ODM_COMP_RSSI_MONITOR, |
| "ext_lna_gain (( %d )), LNA_idx: (( 0x%x )), VGA_idx: (( 0x%x )), rx_pwr_all: (( %d ))\n", |
| dm->ext_lna_gain, LNA_idx, VGA_idx, rx_pwr_all); |
| |
| if (dm->board_type & ODM_BOARD_EXT_LNA) |
| rx_pwr_all -= dm->ext_lna_gain; |
| |
| pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); |
| |
| if (pktinfo->is_to_self) { |
| dm->cck_lna_idx = LNA_idx; |
| dm->cck_vga_idx = VGA_idx; |
| } |
| phy_info->rx_pwdb_all = pwdb_all; |
| |
| phy_info->bt_rx_rssi_percentage = pwdb_all; |
| phy_info->recv_signal_power = rx_pwr_all; |
| /* (3) Get Signal Quality (EVM) */ |
| { |
| u8 sq; |
| |
| sq = phydm_get_signal_quality_8192(phy_info, dm, |
| phy_sta_rpt); |
| phy_info->signal_quality = sq; |
| phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq; |
| 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) |
| phy_info->rx_mimo_signal_strength[0] = pwdb_all; |
| else |
| phy_info->rx_mimo_signal_strength[1] = 0; |
| } |
| } else { /* 2 is OFDM rate */ |
| dm->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 (dm->rf_path_rx_enable & BIT(i)) |
| rf_rx_num++; |
| /* else */ |
| /* continue; */ |
| |
| rx_pwr[i] = |
| ((phy_sta_rpt->path_agc[i].gain & 0x3F) * 2) - |
| 110; |
| |
| if (pktinfo->is_to_self) { |
| dm->ofdm_agc_idx[i] = |
| (phy_sta_rpt->path_agc[i].gain & 0x3F); |
| /**/ |
| } |
| |
| phy_info->rx_pwr[i] = rx_pwr[i]; |
| |
| /* Translate DBM to percentage. */ |
| RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]); |
| total_rssi += RSSI; |
| |
| phy_info->rx_mimo_signal_strength[i] = (u8)RSSI; |
| |
| /* Get Rx snr value in DB */ |
| dm->phy_dbg_info.rx_snr_db[i] = |
| (s32)(phy_sta_rpt->path_rxsnr[i] / 2); |
| phy_info->rx_snr[i] = dm->phy_dbg_info.rx_snr_db[i]; |
| |
| /* Record Signal Strength for next packet */ |
| /* if(pktinfo->is_packet_match_bssid) */ |
| { |
| } |
| } |
| |
| /* */ |
| /* (2)PWDB, Average PWDB calcuated by hardware (for RA) */ |
| /* */ |
| rx_pwr_all = (((phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all) >> 1) & |
| 0x7f) - |
| 110; |
| |
| pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); |
| pwdb_all_bt = pwdb_all; |
| |
| phy_info->rx_pwdb_all = pwdb_all; |
| phy_info->bt_rx_rssi_percentage = pwdb_all_bt; |
| phy_info->rx_power = rx_pwr_all; |
| phy_info->recv_signal_power = rx_pwr_all; |
| |
| if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) { |
| /* do nothing */ |
| } else if ((dm->support_platform == ODM_WIN) && |
| (dm->patch_id == 25)) { |
| /* do nothing */ |
| } else { /* mgnt_info->customer_id != RT_CID_819X_LENOVO */ |
| /* */ |
| /* (3)EVM of HT rate */ |
| /* */ |
| if (pktinfo->data_rate >= ODM_RATEMCS8 && |
| pktinfo->data_rate <= ODM_RATEMCS15) { |
| /* both spatial stream make sense */ |
| max_spatial_stream = 2; |
| } else { |
| /* only spatial stream 1 makes sense */ |
| max_spatial_stream = 1; |
| } |
| |
| for (i = 0; i < max_spatial_stream; i++) { |
| /*Don't 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( |
| (phy_sta_rpt |
| ->stream_rxevm[i])); /* dbm */ |
| |
| /* Fill value in RFD, Get the first spatial |
| * stream only |
| */ |
| if (i == ODM_RF_PATH_A) |
| phy_info->signal_quality = |
| (u8)(EVM & 0xff); |
| phy_info->rx_mimo_signal_quality[i] = |
| (u8)(EVM & 0xff); |
| } |
| } |
| |
| num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate); |
| odm_parsing_cfo(dm, pktinfo, 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) { |
| phy_info->signal_strength = (u8)( |
| odm_signal_scale_mapping(dm, pwdb_all)); /*pwdb_all;*/ |
| } else { |
| if (rf_rx_num != 0) { |
| phy_info->signal_strength = |
| (u8)(odm_signal_scale_mapping(dm, total_rssi /= |
| rf_rx_num)); |
| } |
| } |
| |
| /* For 92C/92D HW (Hybrid) Antenna Diversity */ |
| } |
| |
| static void |
| odm_rx_phy_bw_jaguar_series_parsing(struct dm_phy_status_info *phy_info, |
| struct dm_per_pkt_info *pktinfo, |
| struct phy_status_rpt_8812 *phy_sta_rpt) |
| { |
| if (pktinfo->data_rate <= ODM_RATE54M) { |
| switch (phy_sta_rpt->r_RFMOD) { |
| case 1: |
| if (phy_sta_rpt->sub_chnl == 0) |
| phy_info->band_width = 1; |
| else |
| phy_info->band_width = 0; |
| break; |
| |
| case 2: |
| if (phy_sta_rpt->sub_chnl == 0) |
| phy_info->band_width = 2; |
| else if (phy_sta_rpt->sub_chnl == 9 || |
| phy_sta_rpt->sub_chnl == 10) |
| phy_info->band_width = 1; |
| else |
| phy_info->band_width = 0; |
| break; |
| |
| default: |
| case 0: |
| phy_info->band_width = 0; |
| break; |
| } |
| } |
| } |
| |
| static void odm_rx_phy_status_jaguar_series_parsing( |
| struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info, |
| u8 *phy_status, struct dm_per_pkt_info *pktinfo) |
| { |
| u8 i, max_spatial_stream; |
| s8 rx_pwr[4], rx_pwr_all = 0; |
| u8 EVM = 0, 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 *phy_sta_rpt = |
| (struct phy_status_rpt_8812 *)phy_status; |
| struct fast_antenna_training *fat_tab = &dm->dm_fat_table; |
| u8 num_ss; |
| |
| odm_rx_phy_bw_jaguar_series_parsing(phy_info, pktinfo, phy_sta_rpt); |
| |
| if (pktinfo->data_rate <= ODM_RATE11M) |
| is_cck_rate = true; |
| else |
| is_cck_rate = false; |
| |
| if (pktinfo->is_to_self) |
| dm->curr_station_id = pktinfo->station_id; |
| else |
| dm->curr_station_id = 0xff; |
| |
| phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1; |
| phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1; |
| phy_info->rx_mimo_signal_quality[ODM_RF_PATH_C] = -1; |
| phy_info->rx_mimo_signal_quality[ODM_RF_PATH_D] = -1; |
| |
| if (is_cck_rate) { |
| u8 cck_agc_rpt; |
| |
| dm->phy_dbg_info.num_qry_phy_status_cck++; |
| |
| /*(1)Hardware does not provide RSSI for CCK*/ |
| /*(2)PWDB, Average PWDB calculated by hardware (for RA)*/ |
| |
| cck_highpwr = dm->is_cck_high_power; |
| |
| cck_agc_rpt = phy_sta_rpt->cfosho[0]; |
| LNA_idx = ((cck_agc_rpt & 0xE0) >> 5); |
| VGA_idx = (cck_agc_rpt & 0x1F); |
| |
| if (dm->support_ic_type == ODM_RTL8812) { |
| rx_pwr_all = |
| phydm_get_rx_pwr(LNA_idx, VGA_idx, cck_highpwr); |
| rx_pwr_all += 6; |
| pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); |
| pwdb_all = phydm_adjust_pwdb(cck_highpwr, pwdb_all); |
| |
| } else if (dm->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 (dm->support_ic_type == ODM_RTL8814A || |
| dm->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; |
| default: |
| break; |
| } |
| pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); |
| } |
| |
| dm->cck_lna_idx = LNA_idx; |
| dm->cck_vga_idx = VGA_idx; |
| phy_info->rx_pwdb_all = pwdb_all; |
| phy_info->bt_rx_rssi_percentage = pwdb_all; |
| phy_info->recv_signal_power = rx_pwr_all; |
| /*(3) Get Signal Quality (EVM)*/ |
| { |
| u8 sq; |
| |
| if ((dm->support_platform == ODM_WIN) && |
| (dm->patch_id == RT_CID_819X_LENOVO)) |
| sq = odm_sq_process_patch_rt_cid_819x_lenovo( |
| dm, is_cck_rate, pwdb_all, 0, 0); |
| else |
| sq = phydm_get_signal_quality_8812(phy_info, dm, |
| phy_sta_rpt); |
| |
| phy_info->signal_quality = sq; |
| 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) |
| phy_info->rx_mimo_signal_strength[0] = pwdb_all; |
| else |
| phy_info->rx_mimo_signal_strength[i] = 0; |
| } |
| } else { |
| /*is OFDM rate*/ |
| fat_tab->hw_antsw_occur = phy_sta_rpt->hw_antsw_occur; |
| |
| dm->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.*/ |
| if (dm->rf_path_rx_enable & BIT(i)) |
| rf_rx_num++; |
| /*2012.05.25 LukeLee: Testchip AGC report is wrong, |
| *it should be restored back to old formula in MP chip |
| */ |
| if (i < ODM_RF_PATH_C) |
| rx_pwr[i] = (phy_sta_rpt->gain_trsw[i] & 0x7F) - |
| 110; |
| else |
| rx_pwr[i] = (phy_sta_rpt->gain_trsw_cd[i - 2] & |
| 0x7F) - |
| 110; |
| |
| 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; |
| } |
| |
| phy_info->rx_mimo_signal_strength[i] = (u8)RSSI; |
| |
| /*Get Rx snr value in DB*/ |
| if (i < ODM_RF_PATH_C) |
| phy_info->rx_snr[i] = |
| dm->phy_dbg_info.rx_snr_db[i] = |
| phy_sta_rpt->rxsnr[i] / 2; |
| else if (dm->support_ic_type & |
| (ODM_RTL8814A | ODM_RTL8822B)) |
| phy_info->rx_snr[i] = dm->phy_dbg_info |
| .rx_snr_db[i] = |
| phy_sta_rpt->csi_current[i - 2] / 2; |
| |
| /*(2) CFO_short & CFO_tail*/ |
| if (i < ODM_RF_PATH_C) { |
| phy_info->cfo_short[i] = |
| odm_cfo((phy_sta_rpt->cfosho[i])); |
| phy_info->cfo_tail[i] = |
| odm_cfo((phy_sta_rpt->cfotail[i])); |
| } |
| } |
| |
| /*(3)PWDB, Average PWDB calculated by hardware (for RA)*/ |
| |
| /*2012.05.25 LukeLee: Testchip AGC report is wrong, it should be |
| *restored back to old formula in MP chip |
| */ |
| if ((dm->support_ic_type & |
| (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) && |
| (!dm->is_mp_chip)) |
| rx_pwr_all = (phy_sta_rpt->pwdb_all & 0x7f) - 110; |
| else |
| rx_pwr_all = (((phy_sta_rpt->pwdb_all) >> 1) & 0x7f) - |
| 110; /*OLD FORMULA*/ |
| |
| pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); |
| pwdb_all_bt = pwdb_all; |
| |
| phy_info->rx_pwdb_all = pwdb_all; |
| phy_info->bt_rx_rssi_percentage = pwdb_all_bt; |
| phy_info->rx_power = rx_pwr_all; |
| phy_info->recv_signal_power = rx_pwr_all; |
| |
| if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) { |
| /*do nothing*/ |
| } else { |
| /*mgnt_info->customer_id != RT_CID_819X_LENOVO*/ |
| |
| /*(4)EVM of OFDM rate*/ |
| |
| if ((pktinfo->data_rate >= ODM_RATEMCS8) && |
| (pktinfo->data_rate <= ODM_RATEMCS15)) |
| max_spatial_stream = 2; |
| else if ((pktinfo->data_rate >= ODM_RATEVHTSS2MCS0) && |
| (pktinfo->data_rate <= ODM_RATEVHTSS2MCS9)) |
| max_spatial_stream = 2; |
| else if ((pktinfo->data_rate >= ODM_RATEMCS16) && |
| (pktinfo->data_rate <= ODM_RATEMCS23)) |
| max_spatial_stream = 3; |
| else if ((pktinfo->data_rate >= ODM_RATEVHTSS3MCS0) && |
| (pktinfo->data_rate <= ODM_RATEVHTSS3MCS9)) |
| max_spatial_stream = 3; |
| else |
| max_spatial_stream = 1; |
| |
| for (i = 0; i < max_spatial_stream; i++) { |
| /*Don't 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 = phydm_get_odm_evm(i, pktinfo, |
| phy_sta_rpt); |
| evm_dbm = phydm_get_evm_dbm(i, EVM, phy_sta_rpt, |
| phy_info); |
| phy_info->rx_mimo_signal_quality[i] = EVM; |
| phy_info->rx_mimo_evm_dbm[i] = evm_dbm; |
| } |
| } |
| |
| num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate); |
| odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->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) { |
| phy_info->signal_strength = (u8)( |
| odm_signal_scale_mapping(dm, 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; |
| phy_info->signal_strength = |
| (u8)(odm_signal_scale_mapping(dm, avg_rssi)); |
| } |
| } |
| dm->rx_pwdb_ave = dm->rx_pwdb_ave + phy_info->rx_pwdb_all; |
| |
| dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_anta; |
| dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_antb; |
| dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_antc; |
| dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_antd; |
| } |
| |
| void phydm_reset_rssi_for_dm(struct phy_dm_struct *dm, u8 station_id) |
| { |
| struct rtl_sta_info *entry; |
| |
| entry = dm->odm_sta_info[station_id]; |
| |
| if (!IS_STA_VALID(entry)) |
| return; |
| |
| ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, |
| "Reset RSSI for macid = (( %d ))\n", station_id); |
| |
| entry->rssi_stat.undecorated_smoothed_cck = -1; |
| entry->rssi_stat.undecorated_smoothed_ofdm = -1; |
| entry->rssi_stat.undecorated_smoothed_pwdb = -1; |
| entry->rssi_stat.ofdm_pkt = 0; |
| entry->rssi_stat.cck_pkt = 0; |
| entry->rssi_stat.cck_sum_power = 0; |
| entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_INIT; |
| entry->rssi_stat.packet_map = 0; |
| entry->rssi_stat.valid_bit = 0; |
| } |
| |
| void odm_init_rssi_for_dm(struct phy_dm_struct *dm) {} |
| |
| static void odm_process_rssi_for_dm(struct phy_dm_struct *dm, |
| struct dm_phy_status_info *phy_info, |
| struct dm_per_pkt_info *pktinfo) |
| { |
| s32 undecorated_smoothed_pwdb, undecorated_smoothed_cck, |
| undecorated_smoothed_ofdm; |
| u8 is_cck_rate = 0; |
| u8 send_rssi_2_fw = 0; |
| struct rtl_sta_info *entry; |
| |
| if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM) |
| return; |
| |
| /* 2012/05/30 MH/Luke.Lee Add some description */ |
| /* In windows driver: AP/IBSS mode STA */ |
| entry = dm->odm_sta_info[pktinfo->station_id]; |
| |
| if (!IS_STA_VALID(entry)) |
| return; |
| |
| { |
| if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/ |
| return; |
| } |
| |
| if (pktinfo->is_packet_beacon) |
| dm->phy_dbg_info.num_qry_beacon_pkt++; |
| |
| is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false; |
| dm->rx_rate = pktinfo->data_rate; |
| |
| /* --------------Statistic for antenna/path diversity---------------- */ |
| |
| /* -----------------Smart Antenna Debug Message------------------ */ |
| |
| undecorated_smoothed_cck = entry->rssi_stat.undecorated_smoothed_cck; |
| undecorated_smoothed_ofdm = entry->rssi_stat.undecorated_smoothed_ofdm; |
| undecorated_smoothed_pwdb = entry->rssi_stat.undecorated_smoothed_pwdb; |
| |
| if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) { |
| if (!is_cck_rate) /* ofdm rate */ |
| undecorated_smoothed_ofdm = phydm_process_rssi_ofdm( |
| dm, phy_info, entry, undecorated_smoothed_ofdm); |
| else |
| undecorated_smoothed_cck = phydm_process_rssi_cck( |
| dm, phy_info, entry, undecorated_smoothed_cck); |
| |
| undecorated_smoothed_pwdb = phydm_process_rssi_pwdb( |
| dm, entry, pktinfo, undecorated_smoothed_ofdm, |
| undecorated_smoothed_cck); |
| |
| if ((entry->rssi_stat.ofdm_pkt >= 1 || |
| entry->rssi_stat.cck_pkt >= 5) && |
| (entry->rssi_stat.is_send_rssi == RA_RSSI_STATE_INIT)) { |
| send_rssi_2_fw = 1; |
| entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_SEND; |
| } |
| |
| entry->rssi_stat.undecorated_smoothed_cck = |
| undecorated_smoothed_cck; |
| entry->rssi_stat.undecorated_smoothed_ofdm = |
| undecorated_smoothed_ofdm; |
| entry->rssi_stat.undecorated_smoothed_pwdb = |
| undecorated_smoothed_pwdb; |
| |
| if (send_rssi_2_fw) { /* Trigger init rate by RSSI */ |
| |
| if (entry->rssi_stat.ofdm_pkt != 0) |
| entry->rssi_stat.undecorated_smoothed_pwdb = |
| undecorated_smoothed_ofdm; |
| |
| ODM_RT_TRACE( |
| dm, ODM_COMP_RSSI_MONITOR, |
| "[Send to FW] PWDB = (( %d )), ofdm_pkt = (( %d )), cck_pkt = (( %d ))\n", |
| undecorated_smoothed_pwdb, |
| entry->rssi_stat.ofdm_pkt, |
| entry->rssi_stat.cck_pkt); |
| } |
| } |
| } |
| |
| /* |
| * Endianness before calling this API |
| */ |
| static void odm_phy_status_query_92c_series(struct phy_dm_struct *dm, |
| struct dm_phy_status_info *phy_info, |
| u8 *phy_status, |
| struct dm_per_pkt_info *pktinfo) |
| { |
| odm_rx_phy_status92c_series_parsing(dm, phy_info, phy_status, pktinfo); |
| odm_process_rssi_for_dm(dm, phy_info, pktinfo); |
| } |
| |
| /* |
| * Endianness before calling this API |
| */ |
| |
| static void odm_phy_status_query_jaguar_series( |
| struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info, |
| u8 *phy_status, struct dm_per_pkt_info *pktinfo) |
| { |
| odm_rx_phy_status_jaguar_series_parsing(dm, phy_info, phy_status, |
| pktinfo); |
| odm_process_rssi_for_dm(dm, phy_info, pktinfo); |
| } |
| |
| void odm_phy_status_query(struct phy_dm_struct *dm, |
| struct dm_phy_status_info *phy_info, u8 *phy_status, |
| struct dm_per_pkt_info *pktinfo) |
| { |
| if (dm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE) { |
| phydm_rx_phy_status_new_type(dm, phy_status, pktinfo, phy_info); |
| return; |
| } |
| |
| if (dm->support_ic_type & ODM_IC_11AC_SERIES) |
| odm_phy_status_query_jaguar_series(dm, phy_info, phy_status, |
| pktinfo); |
| |
| if (dm->support_ic_type & ODM_IC_11N_SERIES) |
| odm_phy_status_query_92c_series(dm, phy_info, phy_status, |
| pktinfo); |
| } |
| |
| /* For future use. */ |
| void odm_mac_status_query(struct phy_dm_struct *dm, u8 *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 *dm, |
| enum odm_rf_config_type config_type, |
| enum odm_rf_radio_path e_rf_path) |
| { |
| ODM_RT_TRACE(dm, ODM_COMP_INIT, |
| "===>%s (%s)\n", __func__, |
| (dm->is_mp_chip) ? "MPChip" : "TestChip"); |
| ODM_RT_TRACE( |
| dm, ODM_COMP_INIT, |
| "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n", |
| dm->support_platform, dm->support_interface, dm->board_type); |
| |
| /* 1 AP doesn't use PHYDM power tracking table in these ICs */ |
| /* JJ ADD 20161014 */ |
| |
| /* 1 All platforms support */ |
| if (dm->support_ic_type == ODM_RTL8822B) { |
| if (config_type == CONFIG_RF_RADIO) { |
| if (e_rf_path == ODM_RF_PATH_A) |
| READ_AND_CONFIG_MP(8822b, _radioa); |
| else if (e_rf_path == ODM_RF_PATH_B) |
| READ_AND_CONFIG_MP(8822b, _radiob); |
| } else if (config_type == CONFIG_RF_TXPWR_LMT) { |
| if (dm->rfe_type == 5) |
| READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type5); |
| else |
| READ_AND_CONFIG_MP(8822b, _txpwr_lmt); |
| } |
| } |
| |
| return HAL_STATUS_SUCCESS; |
| } |
| |
| enum hal_status |
| odm_config_rf_with_tx_pwr_track_header_file(struct phy_dm_struct *dm) |
| { |
| ODM_RT_TRACE(dm, ODM_COMP_INIT, |
| "===>%s (%s)\n", __func__, |
| (dm->is_mp_chip) ? "MPChip" : "TestChip"); |
| ODM_RT_TRACE( |
| dm, ODM_COMP_INIT, |
| "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n", |
| dm->support_platform, dm->support_interface, dm->board_type); |
| |
| /* 1 AP doesn't use PHYDM power tracking table in these ICs */ |
| /* JJ ADD 20161014 */ |
| |
| /* 1 All platforms support */ |
| |
| if (dm->support_ic_type == ODM_RTL8822B) { |
| if (dm->rfe_type == 0) |
| READ_AND_CONFIG_MP(8822b, _txpowertrack_type0); |
| else if (dm->rfe_type == 1) |
| READ_AND_CONFIG_MP(8822b, _txpowertrack_type1); |
| else if (dm->rfe_type == 2) |
| READ_AND_CONFIG_MP(8822b, _txpowertrack_type2); |
| else if ((dm->rfe_type == 3) || (dm->rfe_type == 5)) |
| READ_AND_CONFIG_MP(8822b, _txpowertrack_type3_type5); |
| else if (dm->rfe_type == 4) |
| READ_AND_CONFIG_MP(8822b, _txpowertrack_type4); |
| else if (dm->rfe_type == 6) |
| READ_AND_CONFIG_MP(8822b, _txpowertrack_type6); |
| else if (dm->rfe_type == 7) |
| READ_AND_CONFIG_MP(8822b, _txpowertrack_type7); |
| else if (dm->rfe_type == 8) |
| READ_AND_CONFIG_MP(8822b, _txpowertrack_type8); |
| else if (dm->rfe_type == 9) |
| READ_AND_CONFIG_MP(8822b, _txpowertrack_type9); |
| else |
| READ_AND_CONFIG_MP(8822b, _txpowertrack); |
| } |
| |
| return HAL_STATUS_SUCCESS; |
| } |
| |
| enum hal_status |
| odm_config_bb_with_header_file(struct phy_dm_struct *dm, |
| enum odm_bb_config_type config_type) |
| { |
| /* 1 AP doesn't use PHYDM initialization in these ICs */ |
| /* JJ ADD 20161014 */ |
| |
| /* 1 All platforms support */ |
| if (dm->support_ic_type == ODM_RTL8822B) { |
| if (config_type == CONFIG_BB_PHY_REG) |
| READ_AND_CONFIG_MP(8822b, _phy_reg); |
| else if (config_type == CONFIG_BB_AGC_TAB) |
| READ_AND_CONFIG_MP(8822b, _agc_tab); |
| else if (config_type == CONFIG_BB_PHY_REG_PG) |
| READ_AND_CONFIG_MP(8822b, _phy_reg_pg); |
| /*else if (config_type == CONFIG_BB_PHY_REG_MP)*/ |
| /*READ_AND_CONFIG_MP(8822b, _phy_reg_mp);*/ |
| } |
| |
| return HAL_STATUS_SUCCESS; |
| } |
| |
| enum hal_status odm_config_mac_with_header_file(struct phy_dm_struct *dm) |
| { |
| ODM_RT_TRACE(dm, ODM_COMP_INIT, |
| "===>%s (%s)\n", __func__, |
| (dm->is_mp_chip) ? "MPChip" : "TestChip"); |
| ODM_RT_TRACE( |
| dm, ODM_COMP_INIT, |
| "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n", |
| dm->support_platform, dm->support_interface, dm->board_type); |
| |
| /* 1 AP doesn't use PHYDM initialization in these ICs */ |
| /* JJ ADD 20161014 */ |
| |
| /* 1 All platforms support */ |
| if (dm->support_ic_type == ODM_RTL8822B) |
| READ_AND_CONFIG_MP(8822b, _mac_reg); |
| |
| return HAL_STATUS_SUCCESS; |
| } |
| |
| enum hal_status |
| odm_config_fw_with_header_file(struct phy_dm_struct *dm, |
| enum odm_fw_config_type config_type, |
| u8 *p_firmware, u32 *size) |
| { |
| return HAL_STATUS_SUCCESS; |
| } |
| |
| u32 odm_get_hw_img_version(struct phy_dm_struct *dm) |
| { |
| u32 version = 0; |
| |
| /* 1 AP doesn't use PHYDM initialization in these ICs */ |
| /* JJ ADD 20161014 */ |
| |
| /*1 All platforms support*/ |
| if (dm->support_ic_type == ODM_RTL8822B) |
| version = GET_VERSION_MP(8822b, _mac_reg); |
| |
| return version; |
| } |
| |
| /* For 8822B only!! need to move to FW finally */ |
| /*==============================================*/ |
| |
| bool phydm_query_is_mu_api(struct phy_dm_struct *phydm, u8 ppdu_idx, |
| u8 *p_data_rate, u8 *p_gid) |
| { |
| u8 data_rate = 0, gid = 0; |
| bool is_mu = false; |
| |
| data_rate = phydm->phy_dbg_info.num_of_ppdu[ppdu_idx]; |
| gid = 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; |
| } |
| |
| static void phydm_rx_statistic_cal(struct phy_dm_struct *phydm, u8 *phy_status, |
| struct dm_per_pkt_info *pktinfo) |
| { |
| struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt = |
| (struct phy_status_rpt_jaguar2_type1 *)phy_status; |
| u8 date_rate = pktinfo->data_rate & ~(BIT(7)); |
| |
| if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) { |
| if (date_rate >= ODM_RATEVHTSS1MCS0) { |
| phydm->phy_dbg_info |
| .num_qry_mu_vht_pkt[date_rate - 0x2C]++; |
| phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] = |
| date_rate | BIT(7); |
| phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] = |
| phy_sta_rpt->gid; |
| } |
| |
| } else { |
| if (date_rate >= ODM_RATEVHTSS1MCS0) { |
| phydm->phy_dbg_info.num_qry_vht_pkt[date_rate - 0x2C]++; |
| phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] = |
| date_rate; |
| phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] = |
| phy_sta_rpt->gid; |
| } |
| } |
| } |
| |
| static void phydm_reset_phy_info(struct phy_dm_struct *phydm, |
| struct dm_phy_status_info *phy_info) |
| { |
| phy_info->rx_pwdb_all = 0; |
| phy_info->signal_quality = 0; |
| phy_info->band_width = 0; |
| phy_info->rx_count = 0; |
| odm_memory_set(phydm, phy_info->rx_mimo_signal_quality, 0, 4); |
| odm_memory_set(phydm, phy_info->rx_mimo_signal_strength, 0, 4); |
| odm_memory_set(phydm, phy_info->rx_snr, 0, 4); |
| |
| phy_info->rx_power = -110; |
| phy_info->recv_signal_power = -110; |
| phy_info->bt_rx_rssi_percentage = 0; |
| phy_info->signal_strength = 0; |
| phy_info->bt_coex_pwr_adjust = 0; |
| phy_info->channel = 0; |
| phy_info->is_mu_packet = 0; |
| phy_info->is_beamformed = 0; |
| phy_info->rxsc = 0; |
| odm_memory_set(phydm, phy_info->rx_pwr, -110, 4); |
| odm_memory_set(phydm, phy_info->rx_mimo_evm_dbm, 0, 4); |
| odm_memory_set(phydm, phy_info->cfo_short, 0, 8); |
| odm_memory_set(phydm, phy_info->cfo_tail, 0, 8); |
| } |
| |
| static void phydm_set_per_path_phy_info(u8 rx_path, s8 rx_pwr, s8 rx_evm, |
| s8 cfo_tail, s8 rx_snr, |
| struct dm_phy_status_info *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); |
| } |
| |
| phy_info->rx_pwr[rx_path] = rx_pwr; |
| phy_info->rx_mimo_evm_dbm[rx_path] = evm_dbm; |
| |
| /* CFO = CFO_tail * 312.5 / 2^7 ~= CFO tail * 39/512 (kHz)*/ |
| phy_info->cfo_tail[rx_path] = cfo_tail; |
| phy_info->cfo_tail[rx_path] = ((phy_info->cfo_tail[rx_path] << 5) + |
| (phy_info->cfo_tail[rx_path] << 2) + |
| (phy_info->cfo_tail[rx_path] << 1) + |
| (phy_info->cfo_tail[rx_path])) >> |
| 9; |
| |
| phy_info->rx_mimo_signal_strength[rx_path] = |
| odm_query_rx_pwr_percentage(rx_pwr); |
| phy_info->rx_mimo_signal_quality[rx_path] = evm_percentage; |
| phy_info->rx_snr[rx_path] = rx_snr >> 1; |
| } |
| |
| static 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 dm_phy_status_info *phy_info) |
| { |
| phy_info->rx_power = rx_power; /* RSSI in dB */ |
| phy_info->recv_signal_power = rx_power; /* RSSI in dB */ |
| phy_info->channel = channel; /* channel number */ |
| phy_info->is_beamformed = is_beamformed; /* apply BF */ |
| phy_info->is_mu_packet = is_mu_packet; /* MU packet */ |
| phy_info->rxsc = rxsc; |
| phy_info->rx_pwdb_all = |
| odm_query_rx_pwr_percentage(rx_power); /* RSSI in percentage */ |
| phy_info->signal_quality = signal_quality; /* signal quality */ |
| phy_info->band_width = bandwidth; /* bandwidth */ |
| } |
| |
| static void phydm_get_rx_phy_status_type0(struct phy_dm_struct *dm, |
| u8 *phy_status, |
| struct dm_per_pkt_info *pktinfo, |
| struct dm_phy_status_info *phy_info) |
| { |
| /* type 0 is used for cck packet */ |
| |
| struct phy_status_rpt_jaguar2_type0 *phy_sta_rpt = |
| (struct phy_status_rpt_jaguar2_type0 *)phy_status; |
| u8 sq = 0; |
| s8 rx_power = phy_sta_rpt->pwdb - 110; |
| |
| /* JJ ADD 20161014 */ |
| |
| /* Calculate Signal Quality*/ |
| if (pktinfo->is_packet_match_bssid) { |
| if (phy_sta_rpt->signal_quality >= 64) { |
| sq = 0; |
| } else if (phy_sta_rpt->signal_quality <= 20) { |
| sq = 100; |
| } else { |
| /* mapping to 2~99% */ |
| sq = 64 - phy_sta_rpt->signal_quality; |
| sq = ((sq << 3) + sq) >> 2; |
| } |
| } |
| |
| /* Modify CCK PWDB if old AGC */ |
| if (!dm->cck_new_agc) { |
| u8 lna_idx, vga_idx; |
| |
| lna_idx = ((phy_sta_rpt->lna_h << 3) | phy_sta_rpt->lna_l); |
| vga_idx = phy_sta_rpt->vga; |
| |
| /* JJ ADD 20161014 */ |
| |
| /* Need to do !! */ |
| /*if (dm->support_ic_type & ODM_RTL8822B) */ |
| /*rx_power = odm_CCKRSSI_8822B(LNA_idx, VGA_idx);*/ |
| } |
| |
| /* Update CCK packet counter */ |
| dm->phy_dbg_info.num_qry_phy_status_cck++; |
| |
| /*CCK no STBC and LDPC*/ |
| dm->phy_dbg_info.is_ldpc_pkt = false; |
| dm->phy_dbg_info.is_stbc_pkt = false; |
| |
| /* Update Common information */ |
| phydm_set_common_phy_info(rx_power, phy_sta_rpt->channel, false, false, |
| ODM_BW20M, sq, phy_sta_rpt->rxsc, phy_info); |
| |
| /* Update CCK pwdb */ |
| /* Update per-path information */ |
| phydm_set_per_path_phy_info(ODM_RF_PATH_A, rx_power, 0, 0, 0, phy_info); |
| |
| dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a; |
| dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b; |
| dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c; |
| dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d; |
| } |
| |
| static void phydm_get_rx_phy_status_type1(struct phy_dm_struct *dm, |
| u8 *phy_status, |
| struct dm_per_pkt_info *pktinfo, |
| struct dm_phy_status_info *phy_info) |
| { |
| /* type 1 is used for ofdm packet */ |
| |
| struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt = |
| (struct phy_status_rpt_jaguar2_type1 *)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 */ |
| dm->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 (dm->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 = phy_sta_rpt->pwdb[i] - |
| 110; /* per-path pwdb in dB domain */ |
| phydm_set_per_path_phy_info( |
| i, rx_path_pwr_db, |
| phy_sta_rpt->rxevm[rx_count - 1], |
| phy_sta_rpt->cfo_tail[i], phy_sta_rpt->rxsnr[i], |
| 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) |
| phy_info->rx_count = rx_count - 1; |
| |
| /* Check if MU packet or not */ |
| if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) { |
| is_mu = true; |
| dm->phy_dbg_info.num_qry_mu_pkt++; |
| } else { |
| is_mu = false; |
| } |
| |
| /* count BF packet */ |
| dm->phy_dbg_info.num_qry_bf_pkt = |
| dm->phy_dbg_info.num_qry_bf_pkt + phy_sta_rpt->beamformed; |
| |
| /*STBC or LDPC pkt*/ |
| dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc; |
| dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc; |
| |
| /* Check sub-channel */ |
| if ((pktinfo->data_rate > ODM_RATE11M) && |
| (pktinfo->data_rate < ODM_RATEMCS0)) |
| rxsc = phy_sta_rpt->l_rxsc; |
| else |
| rxsc = phy_sta_rpt->ht_rxsc; |
| |
| /* Check RX bandwidth */ |
| if (dm->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 = phy_sta_rpt->rf_mode; |
| } else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D | |
| ODM_RTL8710B)) { /* JJ ADD 20161014 */ |
| if (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, phy_sta_rpt->channel, (bool)phy_sta_rpt->beamformed, |
| is_mu, bw, odm_evm_db_to_percentage(phy_sta_rpt->rxevm[0]), |
| rxsc, phy_info); |
| |
| num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate); |
| |
| odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfo_tail, num_ss); |
| dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a; |
| dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b; |
| dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c; |
| dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d; |
| |
| if (pktinfo->is_packet_match_bssid) { |
| /* */ |
| phydm_rx_statistic_cal(dm, phy_status, pktinfo); |
| } |
| } |
| |
| static void phydm_get_rx_phy_status_type2(struct phy_dm_struct *dm, |
| u8 *phy_status, |
| struct dm_per_pkt_info *pktinfo, |
| struct dm_phy_status_info *phy_info) |
| { |
| struct phy_status_rpt_jaguar2_type2 *phy_sta_rpt = |
| (struct phy_status_rpt_jaguar2_type2 *)phy_status; |
| s8 rx_pwr_db = -120; |
| u8 i, rxsc, bw = ODM_BW20M, rx_count = 0; |
| |
| /* Update OFDM packet counter */ |
| dm->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 (dm->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) |
| */ |
| rx_path_pwr_db = 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, |
| 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) |
| phy_info->rx_count = rx_count - 1; |
| |
| /* Check RX sub-channel */ |
| if ((pktinfo->data_rate > ODM_RATE11M) && |
| (pktinfo->data_rate < ODM_RATEMCS0)) |
| rxsc = phy_sta_rpt->l_rxsc; |
| else |
| rxsc = phy_sta_rpt->ht_rxsc; |
| |
| /*STBC or LDPC pkt*/ |
| dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc; |
| dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc; |
| |
| /* Check RX bandwidth */ |
| /* the BW information of sc=0 is useless, because there is |
| * no information of RF mode |
| */ |
| |
| if (dm->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 (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D | |
| ODM_RTL8710B)) { /* JJ ADD 20161014 */ |
| 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, phy_sta_rpt->channel, |
| (bool)phy_sta_rpt->beamformed, false, bw, 0, |
| rxsc, phy_info); |
| } |
| |
| static void |
| phydm_process_rssi_for_dm_new_type(struct phy_dm_struct *dm, |
| struct dm_phy_status_info *phy_info, |
| struct dm_per_pkt_info *pktinfo) |
| { |
| s32 undecorated_smoothed_pwdb, accumulate_pwdb; |
| u32 rssi_ave; |
| u8 i; |
| struct rtl_sta_info *entry; |
| u8 scaling_factor = 4; |
| |
| if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM) |
| return; |
| |
| entry = dm->odm_sta_info[pktinfo->station_id]; |
| |
| if (!IS_STA_VALID(entry)) |
| return; |
| |
| if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/ |
| return; |
| |
| if (pktinfo->is_packet_beacon) |
| dm->phy_dbg_info.num_qry_beacon_pkt++; |
| |
| if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) { |
| u32 rssi_linear = 0; |
| |
| dm->rx_rate = pktinfo->data_rate; |
| undecorated_smoothed_pwdb = |
| entry->rssi_stat.undecorated_smoothed_pwdb; |
| accumulate_pwdb = dm->accumulate_pwdb[pktinfo->station_id]; |
| dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A]; |
| dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]; |
| dm->rssi_c = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_C]; |
| dm->rssi_d = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_D]; |
| |
| for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { |
| if (phy_info->rx_mimo_signal_strength[i] != 0) |
| rssi_linear += odm_convert_to_linear( |
| phy_info->rx_mimo_signal_strength[i]); |
| } |
| |
| switch (phy_info->rx_count + 1) { |
| case 2: |
| rssi_linear = (rssi_linear >> 1); |
| break; |
| case 3: |
| /* rssi_linear/3 ~ rssi_linear*11/32 */ |
| rssi_linear = ((rssi_linear) + (rssi_linear << 1) + |
| (rssi_linear << 3)) >> |
| 5; |
| break; |
| case 4: |
| rssi_linear = (rssi_linear >> 2); |
| break; |
| } |
| rssi_ave = odm_convert_to_db(rssi_linear); |
| |
| if (undecorated_smoothed_pwdb <= 0) { |
| accumulate_pwdb = |
| (phy_info->rx_pwdb_all << scaling_factor); |
| undecorated_smoothed_pwdb = 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; |
| } |
| |
| entry->rssi_stat.undecorated_smoothed_pwdb = |
| undecorated_smoothed_pwdb; |
| dm->accumulate_pwdb[pktinfo->station_id] = accumulate_pwdb; |
| } |
| } |
| |
| void phydm_rx_phy_status_new_type(struct phy_dm_struct *phydm, u8 *phy_status, |
| struct dm_per_pkt_info *pktinfo, |
| struct dm_phy_status_info *phy_info) |
| { |
| u8 phy_status_type = (*phy_status & 0xf); |
| |
| /* Memory reset */ |
| phydm_reset_phy_info(phydm, phy_info); |
| |
| /* Phy status parsing */ |
| switch (phy_status_type) { |
| case 0: { |
| phydm_get_rx_phy_status_type0(phydm, phy_status, pktinfo, |
| phy_info); |
| break; |
| } |
| case 1: { |
| phydm_get_rx_phy_status_type1(phydm, phy_status, pktinfo, |
| phy_info); |
| break; |
| } |
| case 2: { |
| phydm_get_rx_phy_status_type2(phydm, phy_status, pktinfo, |
| phy_info); |
| break; |
| } |
| default: |
| return; |
| } |
| |
| /* Update signal strength to UI, and phy_info->rx_pwdb_all is the |
| * maximum RSSI of all path |
| */ |
| phy_info->signal_strength = |
| (u8)(odm_signal_scale_mapping(phydm, phy_info->rx_pwdb_all)); |
| |
| /* Calculate average RSSI and smoothed RSSI */ |
| phydm_process_rssi_for_dm_new_type(phydm, phy_info, pktinfo); |
| } |
| |
| u32 query_phydm_trx_capability(struct phy_dm_struct *dm) |
| { |
| u32 value32 = 0xFFFFFFFF; |
| |
| return value32; |
| } |
| |
| u32 query_phydm_stbc_capability(struct phy_dm_struct *dm) |
| { |
| u32 value32 = 0xFFFFFFFF; |
| |
| return value32; |
| } |
| |
| u32 query_phydm_ldpc_capability(struct phy_dm_struct *dm) |
| { |
| u32 value32 = 0xFFFFFFFF; |
| |
| return value32; |
| } |
| |
| u32 query_phydm_txbf_parameters(struct phy_dm_struct *dm) |
| { |
| u32 value32 = 0xFFFFFFFF; |
| |
| return value32; |
| } |
| |
| u32 query_phydm_txbf_capability(struct phy_dm_struct *dm) |
| { |
| u32 value32 = 0xFFFFFFFF; |
| |
| return value32; |
| } |