Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.16-rc1 281 lines 8.7 kB view raw
1/****************************************************************************** 2 * 3 * Copyright(c) 2009-2010 Realtek Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 17 * 18 * The full GNU General Public License is included in this distribution in the 19 * file called LICENSE. 20 * 21 * Contact Information: 22 * wlanfae <wlanfae@realtek.com> 23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, 24 * Hsinchu 300, Taiwan. 25 * 26 * Larry Finger <Larry.Finger@lwfinger.net> 27 * 28 *****************************************************************************/ 29#include "wifi.h" 30#include "stats.h" 31#include <linux/export.h> 32 33u8 rtl_query_rxpwrpercentage(char antpower) 34{ 35 if ((antpower <= -100) || (antpower >= 20)) 36 return 0; 37 else if (antpower >= 0) 38 return 100; 39 else 40 return (100 + antpower); 41} 42//EXPORT_SYMBOL(rtl_query_rxpwrpercentage); 43 44u8 rtl_evm_db_to_percentage(char value) 45{ 46 char ret_val; 47 ret_val = value; 48 49 if (ret_val >= 0) 50 ret_val = 0; 51 if (ret_val <= -33) 52 ret_val = -33; 53 ret_val = 0 - ret_val; 54 ret_val *= 3; 55 if (ret_val == 99) 56 ret_val = 100; 57 58 return ret_val; 59} 60//EXPORT_SYMBOL(rtl_evm_db_to_percentage); 61 62long rtl_translate_todbm(struct ieee80211_hw *hw, 63 u8 signal_strength_index) 64{ 65 long signal_power; 66 67 signal_power = (long)((signal_strength_index + 1) >> 1); 68 signal_power -= 95; 69 return signal_power; 70} 71 72long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig) 73{ 74 long retsig; 75 76 if (currsig >= 61 && currsig <= 100) 77 retsig = 90 + ((currsig - 60) / 4); 78 else if (currsig >= 41 && currsig <= 60) 79 retsig = 78 + ((currsig - 40) / 2); 80 else if (currsig >= 31 && currsig <= 40) 81 retsig = 66 + (currsig - 30); 82 else if (currsig >= 21 && currsig <= 30) 83 retsig = 54 + (currsig - 20); 84 else if (currsig >= 5 && currsig <= 20) 85 retsig = 42 + (((currsig - 5) * 2) / 3); 86 else if (currsig == 4) 87 retsig = 36; 88 else if (currsig == 3) 89 retsig = 27; 90 else if (currsig == 2) 91 retsig = 18; 92 else if (currsig == 1) 93 retsig = 9; 94 else 95 retsig = currsig; 96 97 return retsig; 98} 99//EXPORT_SYMBOL(rtl_signal_scale_mapping); 100 101void rtl_process_ui_rssi(struct ieee80211_hw *hw, struct rtl_stats *pstatus) 102{ 103 struct rtl_priv *rtlpriv = rtl_priv(hw); 104 struct rtl_phy *rtlphy = &(rtlpriv->phy); 105 u8 rfpath; 106 u32 last_rssi, tmpval; 107 108 if (!pstatus->b_packet_toself && !pstatus->b_packet_beacon) 109 return; 110 111 rtlpriv->stats.pwdb_all_cnt += pstatus->rx_pwdb_all; 112 rtlpriv->stats.rssi_calculate_cnt++; 113 114 if (rtlpriv->stats.ui_rssi.total_num++ >= PHY_RSSI_SLID_WIN_MAX) { 115 rtlpriv->stats.ui_rssi.total_num = PHY_RSSI_SLID_WIN_MAX; 116 last_rssi = rtlpriv->stats.ui_rssi.elements[ 117 rtlpriv->stats.ui_rssi.index]; 118 rtlpriv->stats.ui_rssi.total_val -= last_rssi; 119 } 120 rtlpriv->stats.ui_rssi.total_val += pstatus->signalstrength; 121 rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++] = 122 pstatus->signalstrength; 123 if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) 124 rtlpriv->stats.ui_rssi.index = 0; 125 tmpval = rtlpriv->stats.ui_rssi.total_val / 126 rtlpriv->stats.ui_rssi.total_num; 127 rtlpriv->stats.signal_strength = rtl_translate_todbm(hw, 128 (u8) tmpval); 129 pstatus->rssi = rtlpriv->stats.signal_strength; 130 131 if (pstatus->b_is_cck) 132 return; 133 134 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; 135 rfpath++) { 136 if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { 137 rtlpriv->stats.rx_rssi_percentage[rfpath] = 138 pstatus->rx_mimo_signalstrength[rfpath]; 139 140 } 141 if (pstatus->rx_mimo_signalstrength[rfpath] > 142 rtlpriv->stats.rx_rssi_percentage[rfpath]) { 143 rtlpriv->stats.rx_rssi_percentage[rfpath] = 144 ((rtlpriv->stats.rx_rssi_percentage[rfpath] * 145 (RX_SMOOTH_FACTOR - 1)) + 146 (pstatus->rx_mimo_signalstrength[rfpath])) / 147 (RX_SMOOTH_FACTOR); 148 rtlpriv->stats.rx_rssi_percentage[rfpath] = 149 rtlpriv->stats.rx_rssi_percentage[rfpath] + 1; 150 } else { 151 rtlpriv->stats.rx_rssi_percentage[rfpath] = 152 ((rtlpriv->stats.rx_rssi_percentage[rfpath] * 153 (RX_SMOOTH_FACTOR - 1)) + 154 (pstatus->rx_mimo_signalstrength[rfpath])) / 155 (RX_SMOOTH_FACTOR); 156 } 157 rtlpriv->stats.rx_snr_db[rfpath] = pstatus->rx_snr[rfpath]; 158 rtlpriv->stats.rx_evm_dbm[rfpath] = 159 pstatus->rx_mimo_evm_dbm[rfpath]; 160 rtlpriv->stats.rx_cfo_short[rfpath] = 161 pstatus->cfo_short[rfpath]; 162 rtlpriv->stats.rx_cfo_tail[rfpath] = pstatus->cfo_tail[rfpath]; 163 } 164} 165 166static void rtl_update_rxsignalstatistics(struct ieee80211_hw *hw, 167 struct rtl_stats *pstatus) 168{ 169 struct rtl_priv *rtlpriv = rtl_priv(hw); 170 int weighting = 0; 171 172 if (rtlpriv->stats.recv_signal_power == 0) 173 rtlpriv->stats.recv_signal_power = pstatus->recvsignalpower; 174 if (pstatus->recvsignalpower > rtlpriv->stats.recv_signal_power) 175 weighting = 5; 176 else if (pstatus->recvsignalpower < rtlpriv->stats.recv_signal_power) 177 weighting = (-5); 178 rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * 179 5 + pstatus->recvsignalpower + weighting) / 6; 180} 181 182static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus) 183{ 184 struct rtl_priv *rtlpriv = rtl_priv(hw); 185 struct rtl_sta_info *drv_priv = NULL; 186 struct ieee80211_sta *sta = NULL; 187 long undecorated_smoothed_pwdb; 188 189 rcu_read_lock(); 190 if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) 191 sta = rtl_find_sta(hw, pstatus->psaddr); 192 193 /* adhoc or ap mode */ 194 if (sta) { 195 drv_priv = (struct rtl_sta_info *) sta->drv_priv; 196 undecorated_smoothed_pwdb = 197 drv_priv->rssi_stat.undecorated_smoothed_pwdb; 198 } else { 199 undecorated_smoothed_pwdb = 200 rtlpriv->dm.undecorated_smoothed_pwdb; 201 } 202 203 if (undecorated_smoothed_pwdb < 0) 204 undecorated_smoothed_pwdb = pstatus->rx_pwdb_all; 205 if (pstatus->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { 206 undecorated_smoothed_pwdb = (((undecorated_smoothed_pwdb) * 207 (RX_SMOOTH_FACTOR - 1)) + 208 (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); 209 undecorated_smoothed_pwdb = undecorated_smoothed_pwdb + 1; 210 } else { 211 undecorated_smoothed_pwdb = (((undecorated_smoothed_pwdb) * 212 (RX_SMOOTH_FACTOR - 1)) + 213 (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); 214 } 215 216 if(sta) { 217 drv_priv->rssi_stat.undecorated_smoothed_pwdb = 218 undecorated_smoothed_pwdb; 219 } else { 220 rtlpriv->dm.undecorated_smoothed_pwdb = undecorated_smoothed_pwdb; 221 } 222 rcu_read_unlock(); 223 224 rtl_update_rxsignalstatistics(hw, pstatus); 225} 226 227static void rtl_process_ui_link_quality(struct ieee80211_hw *hw, 228 struct rtl_stats *pstatus) 229{ 230 struct rtl_priv *rtlpriv = rtl_priv(hw); 231 u32 last_evm, n_stream, tmpval; 232 233 if (pstatus->signalquality == 0) 234 return; 235 236 if (rtlpriv->stats.ui_link_quality.total_num++ >= 237 PHY_LINKQUALITY_SLID_WIN_MAX) { 238 rtlpriv->stats.ui_link_quality.total_num = 239 PHY_LINKQUALITY_SLID_WIN_MAX; 240 last_evm = rtlpriv->stats.ui_link_quality.elements[ 241 rtlpriv->stats.ui_link_quality.index]; 242 rtlpriv->stats.ui_link_quality.total_val -= last_evm; 243 } 244 rtlpriv->stats.ui_link_quality.total_val += pstatus->signalquality; 245 rtlpriv->stats.ui_link_quality.elements[ 246 rtlpriv->stats.ui_link_quality.index++] = 247 pstatus->signalquality; 248 if (rtlpriv->stats.ui_link_quality.index >= 249 PHY_LINKQUALITY_SLID_WIN_MAX) 250 rtlpriv->stats.ui_link_quality.index = 0; 251 tmpval = rtlpriv->stats.ui_link_quality.total_val / 252 rtlpriv->stats.ui_link_quality.total_num; 253 rtlpriv->stats.signal_quality = tmpval; 254 rtlpriv->stats.last_sigstrength_inpercent = tmpval; 255 for (n_stream = 0; n_stream < 2; n_stream++) { 256 if (pstatus->rx_mimo_signalquality[n_stream] != -1) { 257 if (rtlpriv->stats.rx_evm_percentage[n_stream] == 0) { 258 rtlpriv->stats.rx_evm_percentage[n_stream] = 259 pstatus->rx_mimo_signalquality[n_stream]; 260 } 261 rtlpriv->stats.rx_evm_percentage[n_stream] = 262 ((rtlpriv->stats.rx_evm_percentage[n_stream] 263 * (RX_SMOOTH_FACTOR - 1)) + 264 (pstatus->rx_mimo_signalquality[n_stream] * 1)) / 265 (RX_SMOOTH_FACTOR); 266 } 267 } 268} 269 270void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer, 271 struct rtl_stats *pstatus) 272{ 273 274 if (!pstatus->b_packet_matchbssid) 275 return; 276 277 rtl_process_ui_rssi(hw, pstatus); 278 rtl_process_pwdb(hw, pstatus); 279 rtl_process_ui_link_quality(hw, pstatus); 280} 281//EXPORT_SYMBOL(rtl_process_phyinfo);