diff options
-rw-r--r-- | include/net/cfg80211.h | 1 | ||||
-rw-r--r-- | net/mac80211/wext.c | 69 | ||||
-rw-r--r-- | net/wireless/wext-compat.c | 59 |
3 files changed, 61 insertions, 68 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 579085564883..fe87819954a5 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -1646,6 +1646,7 @@ int cfg80211_wext_siwtxpower(struct net_device *dev, | |||
1646 | int cfg80211_wext_giwtxpower(struct net_device *dev, | 1646 | int cfg80211_wext_giwtxpower(struct net_device *dev, |
1647 | struct iw_request_info *info, | 1647 | struct iw_request_info *info, |
1648 | union iwreq_data *data, char *keybuf); | 1648 | union iwreq_data *data, char *keybuf); |
1649 | struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev); | ||
1649 | 1650 | ||
1650 | int cfg80211_wext_siwpower(struct net_device *dev, | 1651 | int cfg80211_wext_siwpower(struct net_device *dev, |
1651 | struct iw_request_info *info, | 1652 | struct iw_request_info *info, |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 244d830f5cfb..5acb8140ee58 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -165,73 +165,6 @@ static int ieee80211_ioctl_giwap(struct net_device *dev, | |||
165 | } | 165 | } |
166 | 166 | ||
167 | 167 | ||
168 | /* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ | ||
169 | static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev) | ||
170 | { | ||
171 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
172 | struct iw_statistics *wstats = &local->wstats; | ||
173 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
174 | struct sta_info *sta = NULL; | ||
175 | |||
176 | rcu_read_lock(); | ||
177 | |||
178 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
179 | sta = sta_info_get(local, sdata->u.mgd.bssid); | ||
180 | |||
181 | if (!sta) { | ||
182 | wstats->discard.fragment = 0; | ||
183 | wstats->discard.misc = 0; | ||
184 | wstats->qual.qual = 0; | ||
185 | wstats->qual.level = 0; | ||
186 | wstats->qual.noise = 0; | ||
187 | wstats->qual.updated = IW_QUAL_ALL_INVALID; | ||
188 | } else { | ||
189 | wstats->qual.updated = 0; | ||
190 | /* | ||
191 | * mirror what cfg80211 does for iwrange/scan results, | ||
192 | * otherwise userspace gets confused. | ||
193 | */ | ||
194 | if (local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | | ||
195 | IEEE80211_HW_SIGNAL_DBM)) { | ||
196 | wstats->qual.updated |= IW_QUAL_LEVEL_UPDATED; | ||
197 | wstats->qual.updated |= IW_QUAL_QUAL_UPDATED; | ||
198 | } else { | ||
199 | wstats->qual.updated |= IW_QUAL_LEVEL_INVALID; | ||
200 | wstats->qual.updated |= IW_QUAL_QUAL_INVALID; | ||
201 | } | ||
202 | |||
203 | if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) { | ||
204 | wstats->qual.level = sta->last_signal; | ||
205 | wstats->qual.qual = sta->last_signal; | ||
206 | } else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { | ||
207 | int sig = sta->last_signal; | ||
208 | |||
209 | wstats->qual.updated |= IW_QUAL_DBM; | ||
210 | wstats->qual.level = sig; | ||
211 | if (sig < -110) | ||
212 | sig = -110; | ||
213 | else if (sig > -40) | ||
214 | sig = -40; | ||
215 | wstats->qual.qual = sig + 110; | ||
216 | } | ||
217 | |||
218 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) { | ||
219 | /* | ||
220 | * This assumes that if driver reports noise, it also | ||
221 | * reports signal in dBm. | ||
222 | */ | ||
223 | wstats->qual.noise = sta->last_noise; | ||
224 | wstats->qual.updated |= IW_QUAL_NOISE_UPDATED; | ||
225 | } else { | ||
226 | wstats->qual.updated |= IW_QUAL_NOISE_INVALID; | ||
227 | } | ||
228 | } | ||
229 | |||
230 | rcu_read_unlock(); | ||
231 | |||
232 | return wstats; | ||
233 | } | ||
234 | |||
235 | /* Structures to export the Wireless Handlers */ | 168 | /* Structures to export the Wireless Handlers */ |
236 | 169 | ||
237 | static const iw_handler ieee80211_handler[] = | 170 | static const iw_handler ieee80211_handler[] = |
@@ -298,5 +231,5 @@ const struct iw_handler_def ieee80211_iw_handler_def = | |||
298 | { | 231 | { |
299 | .num_standard = ARRAY_SIZE(ieee80211_handler), | 232 | .num_standard = ARRAY_SIZE(ieee80211_handler), |
300 | .standard = (iw_handler *) ieee80211_handler, | 233 | .standard = (iw_handler *) ieee80211_handler, |
301 | .get_wireless_stats = ieee80211_get_wireless_stats, | 234 | .get_wireless_stats = cfg80211_wireless_stats, |
302 | }; | 235 | }; |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 3a5f999703f1..226cf8609079 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -1156,3 +1156,62 @@ int cfg80211_wext_giwrate(struct net_device *dev, | |||
1156 | return 0; | 1156 | return 0; |
1157 | } | 1157 | } |
1158 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwrate); | 1158 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwrate); |
1159 | |||
1160 | /* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ | ||
1161 | struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) | ||
1162 | { | ||
1163 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
1164 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
1165 | /* we are under RTNL - globally locked - so can use static structs */ | ||
1166 | static struct iw_statistics wstats; | ||
1167 | static struct station_info sinfo; | ||
1168 | u8 *addr; | ||
1169 | |||
1170 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) | ||
1171 | return NULL; | ||
1172 | |||
1173 | if (!rdev->ops->get_station) | ||
1174 | return NULL; | ||
1175 | |||
1176 | addr = wdev->wext.connect.bssid; | ||
1177 | if (!addr) | ||
1178 | return NULL; | ||
1179 | |||
1180 | if (rdev->ops->get_station(&rdev->wiphy, dev, addr, &sinfo)) | ||
1181 | return NULL; | ||
1182 | |||
1183 | memset(&wstats, 0, sizeof(wstats)); | ||
1184 | |||
1185 | switch (rdev->wiphy.signal_type) { | ||
1186 | case CFG80211_SIGNAL_TYPE_MBM: | ||
1187 | if (sinfo.filled & STATION_INFO_SIGNAL) { | ||
1188 | int sig = sinfo.signal; | ||
1189 | wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; | ||
1190 | wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; | ||
1191 | wstats.qual.updated |= IW_QUAL_DBM; | ||
1192 | wstats.qual.level = sig; | ||
1193 | if (sig < -110) | ||
1194 | sig = -110; | ||
1195 | else if (sig > -40) | ||
1196 | sig = -40; | ||
1197 | wstats.qual.qual = sig + 110; | ||
1198 | break; | ||
1199 | } | ||
1200 | case CFG80211_SIGNAL_TYPE_UNSPEC: | ||
1201 | if (sinfo.filled & STATION_INFO_SIGNAL) { | ||
1202 | wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; | ||
1203 | wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; | ||
1204 | wstats.qual.level = sinfo.signal; | ||
1205 | wstats.qual.qual = sinfo.signal; | ||
1206 | break; | ||
1207 | } | ||
1208 | default: | ||
1209 | wstats.qual.updated |= IW_QUAL_LEVEL_INVALID; | ||
1210 | wstats.qual.updated |= IW_QUAL_QUAL_INVALID; | ||
1211 | } | ||
1212 | |||
1213 | wstats.qual.updated |= IW_QUAL_NOISE_INVALID; | ||
1214 | |||
1215 | return &wstats; | ||
1216 | } | ||
1217 | EXPORT_SYMBOL_GPL(cfg80211_wireless_stats); | ||