aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Goldenshtein <victorg@ti.com>2012-06-21 03:56:46 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-06-21 10:42:17 -0400
commit66572cfc30a4b764150c83ee5d842a3ce17991c9 (patch)
tree3b344b9c986b55f77b4652fd46ce2dad9138ea31
parent0f6b3f597daab2254614e2773e322e73fb1b6f4b (diff)
mac80211: add command to get current rssi
Get current rssi (in dBm) from the driver/FW. Instead of reporting the signal received in the last rx packet, which might be inaccurate if rx traffic is low and beacon filtering is enabled, get the signal from the driver/FW. Signed-off-by: Victor Goldenshtein <victorg@ti.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/mac80211.h5
-rw-r--r--net/mac80211/cfg.c21
-rw-r--r--net/mac80211/driver-ops.h15
-rw-r--r--net/mac80211/driver-trace.h26
4 files changed, 59 insertions, 8 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index d152f54064fd..f11c2f8b00c9 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2249,6 +2249,9 @@ enum ieee80211_rate_control_changed {
2249 * @get_et_strings: Ethtool API to get a set of strings to describe stats 2249 * @get_et_strings: Ethtool API to get a set of strings to describe stats
2250 * and perhaps other supported types of ethtool data-sets. 2250 * and perhaps other supported types of ethtool data-sets.
2251 * 2251 *
2252 * @get_rssi: Get current signal strength in dBm, the function is optional
2253 * and can sleep.
2254 *
2252 */ 2255 */
2253struct ieee80211_ops { 2256struct ieee80211_ops {
2254 void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); 2257 void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -2388,6 +2391,8 @@ struct ieee80211_ops {
2388 void (*get_et_strings)(struct ieee80211_hw *hw, 2391 void (*get_et_strings)(struct ieee80211_hw *hw,
2389 struct ieee80211_vif *vif, 2392 struct ieee80211_vif *vif,
2390 u32 sset, u8 *data); 2393 u32 sset, u8 *data);
2394 int (*get_rssi)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2395 struct ieee80211_sta *sta, s8 *rssi_dbm);
2391}; 2396};
2392 2397
2393/** 2398/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 03aff23c70fd..d0c8f78115cb 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -353,6 +353,7 @@ void sta_set_rate_info_tx(struct sta_info *sta,
353static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 353static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
354{ 354{
355 struct ieee80211_sub_if_data *sdata = sta->sdata; 355 struct ieee80211_sub_if_data *sdata = sta->sdata;
356 struct ieee80211_local *local = sdata->local;
356 struct timespec uptime; 357 struct timespec uptime;
357 358
358 sinfo->generation = sdata->local->sta_generation; 359 sinfo->generation = sdata->local->sta_generation;
@@ -388,7 +389,9 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
388 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || 389 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
389 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { 390 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
390 sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; 391 sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
391 sinfo->signal = (s8)sta->last_signal; 392 if (!local->ops->get_rssi ||
393 drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal))
394 sinfo->signal = (s8)sta->last_signal;
392 sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); 395 sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
393 } 396 }
394 397
@@ -517,7 +520,7 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
517 * network device. 520 * network device.
518 */ 521 */
519 522
520 rcu_read_lock(); 523 mutex_lock(&local->sta_mtx);
521 524
522 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 525 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
523 sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid); 526 sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid);
@@ -546,7 +549,7 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
546 data[i] = (u8)sinfo.signal_avg; 549 data[i] = (u8)sinfo.signal_avg;
547 i++; 550 i++;
548 } else { 551 } else {
549 list_for_each_entry_rcu(sta, &local->sta_list, list) { 552 list_for_each_entry(sta, &local->sta_list, list) {
550 /* Make sure this station belongs to the proper dev */ 553 /* Make sure this station belongs to the proper dev */
551 if (sta->sdata->dev != dev) 554 if (sta->sdata->dev != dev)
552 continue; 555 continue;
@@ -603,7 +606,7 @@ do_survey:
603 else 606 else
604 data[i++] = -1LL; 607 data[i++] = -1LL;
605 608
606 rcu_read_unlock(); 609 mutex_unlock(&local->sta_mtx);
607 610
608 if (WARN_ON(i != STA_STATS_LEN)) 611 if (WARN_ON(i != STA_STATS_LEN))
609 return; 612 return;
@@ -629,10 +632,11 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
629 int idx, u8 *mac, struct station_info *sinfo) 632 int idx, u8 *mac, struct station_info *sinfo)
630{ 633{
631 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 634 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
635 struct ieee80211_local *local = sdata->local;
632 struct sta_info *sta; 636 struct sta_info *sta;
633 int ret = -ENOENT; 637 int ret = -ENOENT;
634 638
635 rcu_read_lock(); 639 mutex_lock(&local->sta_mtx);
636 640
637 sta = sta_info_get_by_idx(sdata, idx); 641 sta = sta_info_get_by_idx(sdata, idx);
638 if (sta) { 642 if (sta) {
@@ -641,7 +645,7 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
641 sta_set_sinfo(sta, sinfo); 645 sta_set_sinfo(sta, sinfo);
642 } 646 }
643 647
644 rcu_read_unlock(); 648 mutex_unlock(&local->sta_mtx);
645 649
646 return ret; 650 return ret;
647} 651}
@@ -658,10 +662,11 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
658 u8 *mac, struct station_info *sinfo) 662 u8 *mac, struct station_info *sinfo)
659{ 663{
660 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 664 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
665 struct ieee80211_local *local = sdata->local;
661 struct sta_info *sta; 666 struct sta_info *sta;
662 int ret = -ENOENT; 667 int ret = -ENOENT;
663 668
664 rcu_read_lock(); 669 mutex_lock(&local->sta_mtx);
665 670
666 sta = sta_info_get_bss(sdata, mac); 671 sta = sta_info_get_bss(sdata, mac);
667 if (sta) { 672 if (sta) {
@@ -669,7 +674,7 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
669 sta_set_sinfo(sta, sinfo); 674 sta_set_sinfo(sta, sinfo);
670 } 675 }
671 676
672 rcu_read_unlock(); 677 mutex_unlock(&local->sta_mtx);
673 678
674 return ret; 679 return ret;
675} 680}
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 6d33a0c743ab..933026949df9 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -845,4 +845,19 @@ drv_allow_buffered_frames(struct ieee80211_local *local,
845 more_data); 845 more_data);
846 trace_drv_return_void(local); 846 trace_drv_return_void(local);
847} 847}
848
849static inline int drv_get_rssi(struct ieee80211_local *local,
850 struct ieee80211_sub_if_data *sdata,
851 struct ieee80211_sta *sta,
852 s8 *rssi_dbm)
853{
854 int ret;
855
856 might_sleep();
857
858 ret = local->ops->get_rssi(&local->hw, &sdata->vif, sta, rssi_dbm);
859 trace_drv_get_rssi(local, sta, *rssi_dbm, ret);
860
861 return ret;
862}
848#endif /* __MAC80211_DRIVER_OPS */ 863#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 6de00b2c268c..a0f7d357884d 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -1218,6 +1218,32 @@ DEFINE_EVENT(release_evt, drv_allow_buffered_frames,
1218 TP_ARGS(local, sta, tids, num_frames, reason, more_data) 1218 TP_ARGS(local, sta, tids, num_frames, reason, more_data)
1219); 1219);
1220 1220
1221TRACE_EVENT(drv_get_rssi,
1222 TP_PROTO(struct ieee80211_local *local, struct ieee80211_sta *sta,
1223 s8 rssi, int ret),
1224
1225 TP_ARGS(local, sta, rssi, ret),
1226
1227 TP_STRUCT__entry(
1228 LOCAL_ENTRY
1229 STA_ENTRY
1230 __field(s8, rssi)
1231 __field(int, ret)
1232 ),
1233
1234 TP_fast_assign(
1235 LOCAL_ASSIGN;
1236 STA_ASSIGN;
1237 __entry->rssi = rssi;
1238 __entry->ret = ret;
1239 ),
1240
1241 TP_printk(
1242 LOCAL_PR_FMT STA_PR_FMT " rssi:%d ret:%d",
1243 LOCAL_PR_ARG, STA_PR_ARG, __entry->rssi, __entry->ret
1244 )
1245);
1246
1221/* 1247/*
1222 * Tracing for API calls that drivers call. 1248 * Tracing for API calls that drivers call.
1223 */ 1249 */