1 /******************************************************************************
3 * Copyright(c) 2009-2010 Realtek Corporation.
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.
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
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
28 u8
stg_rtl_query_rxpwrpercentage(char antpower
)
30 if ((antpower
<= -100) || (antpower
>= 20))
32 else if (antpower
>= 0)
35 return 100 + antpower
;
37 EXPORT_SYMBOL(stg_rtl_query_rxpwrpercentage
);
39 u8
stg_rtl_evm_db_to_percentage(char value
)
48 ret_val
= 0 - ret_val
;
55 EXPORT_SYMBOL(stg_rtl_evm_db_to_percentage
);
57 u8
rtl_evm_dbm_jaguar(char value
)
62 /* -33dB~0dB to 33dB ~ 0dB*/
66 ret_val
= 0 - ret_val
;
68 ret_val
= ret_val
>> 1;
71 EXPORT_SYMBOL(rtl_evm_dbm_jaguar
);
73 static long rtl_translate_todbm(struct ieee80211_hw
*hw
,
74 u8 signal_strength_index
)
78 signal_power
= (long)((signal_strength_index
+ 1) >> 1);
83 long stg_rtl_signal_scale_mapping(struct ieee80211_hw
*hw
, long currsig
)
87 if (currsig
>= 61 && currsig
<= 100)
88 retsig
= 90 + ((currsig
- 60) / 4);
89 else if (currsig
>= 41 && currsig
<= 60)
90 retsig
= 78 + ((currsig
- 40) / 2);
91 else if (currsig
>= 31 && currsig
<= 40)
92 retsig
= 66 + (currsig
- 30);
93 else if (currsig
>= 21 && currsig
<= 30)
94 retsig
= 54 + (currsig
- 20);
95 else if (currsig
>= 5 && currsig
<= 20)
96 retsig
= 42 + (((currsig
- 5) * 2) / 3);
97 else if (currsig
== 4)
99 else if (currsig
== 3)
101 else if (currsig
== 2)
103 else if (currsig
== 1)
110 EXPORT_SYMBOL(stg_rtl_signal_scale_mapping
);
112 static void rtl_process_ui_rssi(struct ieee80211_hw
*hw
, struct rtl_stats
*pstatus
)
114 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
115 struct rtl_phy
*rtlphy
= &(rtlpriv
->phy
);
117 u32 last_rssi
, tmpval
;
119 if (!pstatus
->b_packet_toself
&& !pstatus
->b_packet_beacon
)
122 rtlpriv
->stats
.pwdb_all_cnt
+= pstatus
->rx_pwdb_all
;
123 rtlpriv
->stats
.rssi_calculate_cnt
++;
125 if (rtlpriv
->stats
.ui_rssi
.total_num
++ >= PHY_RSSI_SLID_WIN_MAX
) {
126 rtlpriv
->stats
.ui_rssi
.total_num
= PHY_RSSI_SLID_WIN_MAX
;
127 last_rssi
= rtlpriv
->stats
.ui_rssi
.elements
[
128 rtlpriv
->stats
.ui_rssi
.index
];
129 rtlpriv
->stats
.ui_rssi
.total_val
-= last_rssi
;
131 rtlpriv
->stats
.ui_rssi
.total_val
+= pstatus
->signalstrength
;
132 rtlpriv
->stats
.ui_rssi
.elements
[rtlpriv
->stats
.ui_rssi
.index
++] =
133 pstatus
->signalstrength
;
134 if (rtlpriv
->stats
.ui_rssi
.index
>= PHY_RSSI_SLID_WIN_MAX
)
135 rtlpriv
->stats
.ui_rssi
.index
= 0;
136 tmpval
= rtlpriv
->stats
.ui_rssi
.total_val
/
137 rtlpriv
->stats
.ui_rssi
.total_num
;
138 rtlpriv
->stats
.signal_strength
= rtl_translate_todbm(hw
,
140 pstatus
->rssi
= rtlpriv
->stats
.signal_strength
;
142 if (pstatus
->b_is_cck
)
145 for (rfpath
= RF90_PATH_A
; rfpath
< rtlphy
->num_total_rfpath
;
147 if (rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] == 0) {
148 rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] =
149 pstatus
->rx_mimo_signalstrength
[rfpath
];
151 if (pstatus
->rx_mimo_signalstrength
[rfpath
] >
152 rtlpriv
->stats
.rx_rssi_percentage
[rfpath
]) {
153 rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] =
154 ((rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] *
155 (RX_SMOOTH_FACTOR
- 1)) +
156 (pstatus
->rx_mimo_signalstrength
[rfpath
])) /
158 rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] =
159 rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] + 1;
161 rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] =
162 ((rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] *
163 (RX_SMOOTH_FACTOR
- 1)) +
164 (pstatus
->rx_mimo_signalstrength
[rfpath
])) /
167 rtlpriv
->stats
.rx_snr_db
[rfpath
] = pstatus
->rx_snr
[rfpath
];
168 rtlpriv
->stats
.rx_evm_dbm
[rfpath
] =
169 pstatus
->rx_mimo_evm_dbm
[rfpath
];
170 rtlpriv
->stats
.rx_cfo_short
[rfpath
] =
171 pstatus
->cfo_short
[rfpath
];
172 rtlpriv
->stats
.rx_cfo_tail
[rfpath
] = pstatus
->cfo_tail
[rfpath
];
176 static void rtl_update_rxsignalstatistics(struct ieee80211_hw
*hw
,
177 struct rtl_stats
*pstatus
)
179 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
182 if (rtlpriv
->stats
.recv_signal_power
== 0)
183 rtlpriv
->stats
.recv_signal_power
= pstatus
->recvsignalpower
;
184 if (pstatus
->recvsignalpower
> rtlpriv
->stats
.recv_signal_power
)
186 else if (pstatus
->recvsignalpower
< rtlpriv
->stats
.recv_signal_power
)
188 rtlpriv
->stats
.recv_signal_power
= (rtlpriv
->stats
.recv_signal_power
*
189 5 + pstatus
->recvsignalpower
+ weighting
) / 6;
192 static void rtl_process_pwdb(struct ieee80211_hw
*hw
, struct rtl_stats
*pstatus
)
194 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
195 struct rtl_sta_info
*drv_priv
= NULL
;
196 struct ieee80211_sta
*sta
= NULL
;
197 long undecorated_smoothed_pwdb
;
200 if (rtlpriv
->mac80211
.opmode
!= NL80211_IFTYPE_STATION
)
201 sta
= rtl_find_sta(hw
, pstatus
->psaddr
);
203 /* adhoc or ap mode */
205 drv_priv
= (struct rtl_sta_info
*)sta
->drv_priv
;
206 undecorated_smoothed_pwdb
=
207 drv_priv
->rssi_stat
.undecorated_smoothed_pwdb
;
209 undecorated_smoothed_pwdb
=
210 rtlpriv
->dm
.undecorated_smoothed_pwdb
;
213 if (undecorated_smoothed_pwdb
< 0)
214 undecorated_smoothed_pwdb
= pstatus
->rx_pwdb_all
;
215 if (pstatus
->rx_pwdb_all
> (u32
) undecorated_smoothed_pwdb
) {
216 undecorated_smoothed_pwdb
= (((undecorated_smoothed_pwdb
) *
217 (RX_SMOOTH_FACTOR
- 1)) +
218 (pstatus
->rx_pwdb_all
)) / (RX_SMOOTH_FACTOR
);
219 undecorated_smoothed_pwdb
= undecorated_smoothed_pwdb
+ 1;
221 undecorated_smoothed_pwdb
= (((undecorated_smoothed_pwdb
) *
222 (RX_SMOOTH_FACTOR
- 1)) +
223 (pstatus
->rx_pwdb_all
)) / (RX_SMOOTH_FACTOR
);
227 drv_priv
->rssi_stat
.undecorated_smoothed_pwdb
=
228 undecorated_smoothed_pwdb
;
230 rtlpriv
->dm
.undecorated_smoothed_pwdb
= undecorated_smoothed_pwdb
;
234 rtl_update_rxsignalstatistics(hw
, pstatus
);
237 static void rtl_process_ui_link_quality(struct ieee80211_hw
*hw
,
238 struct rtl_stats
*pstatus
)
240 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
241 u32 last_evm
, n_stream
, tmpval
;
243 if (pstatus
->signalquality
== 0)
246 if (rtlpriv
->stats
.ui_link_quality
.total_num
++ >=
247 PHY_LINKQUALITY_SLID_WIN_MAX
) {
248 rtlpriv
->stats
.ui_link_quality
.total_num
=
249 PHY_LINKQUALITY_SLID_WIN_MAX
;
250 last_evm
= rtlpriv
->stats
.ui_link_quality
.elements
[
251 rtlpriv
->stats
.ui_link_quality
.index
];
252 rtlpriv
->stats
.ui_link_quality
.total_val
-= last_evm
;
254 rtlpriv
->stats
.ui_link_quality
.total_val
+= pstatus
->signalquality
;
255 rtlpriv
->stats
.ui_link_quality
.elements
[
256 rtlpriv
->stats
.ui_link_quality
.index
++] =
257 pstatus
->signalquality
;
258 if (rtlpriv
->stats
.ui_link_quality
.index
>=
259 PHY_LINKQUALITY_SLID_WIN_MAX
)
260 rtlpriv
->stats
.ui_link_quality
.index
= 0;
261 tmpval
= rtlpriv
->stats
.ui_link_quality
.total_val
/
262 rtlpriv
->stats
.ui_link_quality
.total_num
;
263 rtlpriv
->stats
.signal_quality
= tmpval
;
264 rtlpriv
->stats
.last_sigstrength_inpercent
= tmpval
;
265 for (n_stream
= 0; n_stream
< 2; n_stream
++) {
266 if (pstatus
->rx_mimo_signalquality
[n_stream
] != -1) {
267 if (rtlpriv
->stats
.rx_evm_percentage
[n_stream
] == 0) {
268 rtlpriv
->stats
.rx_evm_percentage
[n_stream
] =
269 pstatus
->rx_mimo_signalquality
[n_stream
];
271 rtlpriv
->stats
.rx_evm_percentage
[n_stream
] =
272 ((rtlpriv
->stats
.rx_evm_percentage
[n_stream
]
273 * (RX_SMOOTH_FACTOR
- 1)) +
274 (pstatus
->rx_mimo_signalquality
[n_stream
] * 1)) /
280 void stg_rtl_process_phyinfo(struct ieee80211_hw
*hw
, u8
*buffer
,
281 struct rtl_stats
*pstatus
)
283 if (!pstatus
->b_packet_matchbssid
)
286 rtl_process_ui_rssi(hw
, pstatus
);
287 rtl_process_pwdb(hw
, pstatus
);
288 rtl_process_ui_link_quality(hw
, pstatus
);
290 EXPORT_SYMBOL(stg_rtl_process_phyinfo
);