aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-11-14 10:43:50 -0500
committerJohannes Berg <johannes.berg@intel.com>2015-01-08 09:27:54 -0500
commit11f78ac32b06648c1dde9371b70323168b51a83e (patch)
tree2cea75cf1a053308f980dc69ebc9e7e7cd7a59e6 /net/wireless
parent4ed20bebf51578229a1986efcf46344075ec8447 (diff)
cfg80211: allow survey data to return global data
Not all devices are able to report survey data (particularly time spent for various operations) per channel. As all these statistics already exist in survey data, allow such devices to report them (if userspace requested it) Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/nl80211.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 94ab2014fefe..9555ef9fd99e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6613,12 +6613,17 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
6613} 6613}
6614 6614
6615static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, 6615static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
6616 int flags, struct net_device *dev, 6616 int flags, struct net_device *dev,
6617 struct survey_info *survey) 6617 bool allow_radio_stats,
6618 struct survey_info *survey)
6618{ 6619{
6619 void *hdr; 6620 void *hdr;
6620 struct nlattr *infoattr; 6621 struct nlattr *infoattr;
6621 6622
6623 /* skip radio stats if userspace didn't request them */
6624 if (!survey->channel && !allow_radio_stats)
6625 return 0;
6626
6622 hdr = nl80211hdr_put(msg, portid, seq, flags, 6627 hdr = nl80211hdr_put(msg, portid, seq, flags,
6623 NL80211_CMD_NEW_SURVEY_RESULTS); 6628 NL80211_CMD_NEW_SURVEY_RESULTS);
6624 if (!hdr) 6629 if (!hdr)
@@ -6631,7 +6636,8 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
6631 if (!infoattr) 6636 if (!infoattr)
6632 goto nla_put_failure; 6637 goto nla_put_failure;
6633 6638
6634 if (nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY, 6639 if (survey->channel &&
6640 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
6635 survey->channel->center_freq)) 6641 survey->channel->center_freq))
6636 goto nla_put_failure; 6642 goto nla_put_failure;
6637 6643
@@ -6671,19 +6677,22 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
6671 return -EMSGSIZE; 6677 return -EMSGSIZE;
6672} 6678}
6673 6679
6674static int nl80211_dump_survey(struct sk_buff *skb, 6680static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
6675 struct netlink_callback *cb)
6676{ 6681{
6677 struct survey_info survey; 6682 struct survey_info survey;
6678 struct cfg80211_registered_device *rdev; 6683 struct cfg80211_registered_device *rdev;
6679 struct wireless_dev *wdev; 6684 struct wireless_dev *wdev;
6680 int survey_idx = cb->args[2]; 6685 int survey_idx = cb->args[2];
6681 int res; 6686 int res;
6687 bool radio_stats;
6682 6688
6683 res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); 6689 res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
6684 if (res) 6690 if (res)
6685 return res; 6691 return res;
6686 6692
6693 /* prepare_wdev_dump parsed the attributes */
6694 radio_stats = nl80211_fam.attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
6695
6687 if (!wdev->netdev) { 6696 if (!wdev->netdev) {
6688 res = -EINVAL; 6697 res = -EINVAL;
6689 goto out_err; 6698 goto out_err;
@@ -6701,13 +6710,9 @@ static int nl80211_dump_survey(struct sk_buff *skb,
6701 if (res) 6710 if (res)
6702 goto out_err; 6711 goto out_err;
6703 6712
6704 /* Survey without a channel doesn't make sense */ 6713 /* don't send disabled channels, but do send non-channel data */
6705 if (!survey.channel) { 6714 if (survey.channel &&
6706 res = -EINVAL; 6715 survey.channel->flags & IEEE80211_CHAN_DISABLED) {
6707 goto out;
6708 }
6709
6710 if (survey.channel->flags & IEEE80211_CHAN_DISABLED) {
6711 survey_idx++; 6716 survey_idx++;
6712 continue; 6717 continue;
6713 } 6718 }
@@ -6715,7 +6720,7 @@ static int nl80211_dump_survey(struct sk_buff *skb,
6715 if (nl80211_send_survey(skb, 6720 if (nl80211_send_survey(skb,
6716 NETLINK_CB(cb->skb).portid, 6721 NETLINK_CB(cb->skb).portid,
6717 cb->nlh->nlmsg_seq, NLM_F_MULTI, 6722 cb->nlh->nlmsg_seq, NLM_F_MULTI,
6718 wdev->netdev, &survey) < 0) 6723 wdev->netdev, radio_stats, &survey) < 0)
6719 goto out; 6724 goto out;
6720 survey_idx++; 6725 survey_idx++;
6721 } 6726 }