aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-11-24 02:10:05 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-11-24 16:19:36 -0500
commitc063dbf52b998b852122dff07a8b8dd430b38437 (patch)
treeb27cc73fa8a1d9ed8fb5b0a1306e8194e18662a9
parent79b1c460a0b55e55981c25c56597c4d5d2872de3 (diff)
cfg80211: allow using CQM event to notify packet loss
This adds the ability for drivers to use CQM events to notify about packet loss for specific stations (which could be the AP for the managed mode case). Since the threshold might be determined by the driver (it isn't passed in right now) it will be passed out of the driver to userspace in the event. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/linux/nl80211.h3
-rw-r--r--include/net/cfg80211.h12
-rw-r--r--net/wireless/mlme.c12
-rw-r--r--net/wireless/nl80211.c45
-rw-r--r--net/wireless/nl80211.h4
5 files changed, 76 insertions, 0 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 037b4e498890..d706bf3badc8 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1819,6 +1819,8 @@ enum nl80211_ps_state {
1819 * the minimum amount the RSSI level must change after an event before a 1819 * the minimum amount the RSSI level must change after an event before a
1820 * new event may be issued (to reduce effects of RSSI oscillation). 1820 * new event may be issued (to reduce effects of RSSI oscillation).
1821 * @NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT: RSSI threshold event 1821 * @NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT: RSSI threshold event
1822 * @NL80211_ATTR_CQM_PKT_LOSS_EVENT: a u32 value indicating that this many
1823 * consecutive packets were not acknowledged by the peer
1822 * @__NL80211_ATTR_CQM_AFTER_LAST: internal 1824 * @__NL80211_ATTR_CQM_AFTER_LAST: internal
1823 * @NL80211_ATTR_CQM_MAX: highest key attribute 1825 * @NL80211_ATTR_CQM_MAX: highest key attribute
1824 */ 1826 */
@@ -1827,6 +1829,7 @@ enum nl80211_attr_cqm {
1827 NL80211_ATTR_CQM_RSSI_THOLD, 1829 NL80211_ATTR_CQM_RSSI_THOLD,
1828 NL80211_ATTR_CQM_RSSI_HYST, 1830 NL80211_ATTR_CQM_RSSI_HYST,
1829 NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, 1831 NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
1832 NL80211_ATTR_CQM_PKT_LOSS_EVENT,
1830 1833
1831 /* keep last */ 1834 /* keep last */
1832 __NL80211_ATTR_CQM_AFTER_LAST, 1835 __NL80211_ATTR_CQM_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index dd4c43f512e2..0663945cfa48 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2601,6 +2601,18 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
2601 enum nl80211_cqm_rssi_threshold_event rssi_event, 2601 enum nl80211_cqm_rssi_threshold_event rssi_event,
2602 gfp_t gfp); 2602 gfp_t gfp);
2603 2603
2604/**
2605 * cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer
2606 * @dev: network device
2607 * @peer: peer's MAC address
2608 * @num_packets: how many packets were lost -- should be a fixed threshold
2609 * but probably no less than maybe 50, or maybe a throughput dependent
2610 * threshold (to account for temporary interference)
2611 * @gfp: context flags
2612 */
2613void cfg80211_cqm_pktloss_notify(struct net_device *dev,
2614 const u8 *peer, u32 num_packets, gfp_t gfp);
2615
2604/* Logging, debugging and troubleshooting/diagnostic helpers. */ 2616/* Logging, debugging and troubleshooting/diagnostic helpers. */
2605 2617
2606/* wiphy_printk helpers, similar to dev_printk */ 2618/* wiphy_printk helpers, similar to dev_printk */
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 26838d903b9a..6980a0c315b2 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -1028,3 +1028,15 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
1028 nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp); 1028 nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp);
1029} 1029}
1030EXPORT_SYMBOL(cfg80211_cqm_rssi_notify); 1030EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
1031
1032void cfg80211_cqm_pktloss_notify(struct net_device *dev,
1033 const u8 *peer, u32 num_packets, gfp_t gfp)
1034{
1035 struct wireless_dev *wdev = dev->ieee80211_ptr;
1036 struct wiphy *wiphy = wdev->wiphy;
1037 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
1038
1039 /* Indicate roaming trigger event to user space */
1040 nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp);
1041}
1042EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8734efa663d1..67ff7e92cb99 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5715,6 +5715,51 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
5715 nlmsg_free(msg); 5715 nlmsg_free(msg);
5716} 5716}
5717 5717
5718void
5719nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
5720 struct net_device *netdev, const u8 *peer,
5721 u32 num_packets, gfp_t gfp)
5722{
5723 struct sk_buff *msg;
5724 struct nlattr *pinfoattr;
5725 void *hdr;
5726
5727 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
5728 if (!msg)
5729 return;
5730
5731 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
5732 if (!hdr) {
5733 nlmsg_free(msg);
5734 return;
5735 }
5736
5737 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5738 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5739 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, peer);
5740
5741 pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM);
5742 if (!pinfoattr)
5743 goto nla_put_failure;
5744
5745 NLA_PUT_U32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets);
5746
5747 nla_nest_end(msg, pinfoattr);
5748
5749 if (genlmsg_end(msg, hdr) < 0) {
5750 nlmsg_free(msg);
5751 return;
5752 }
5753
5754 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5755 nl80211_mlme_mcgrp.id, gfp);
5756 return;
5757
5758 nla_put_failure:
5759 genlmsg_cancel(msg, hdr);
5760 nlmsg_free(msg);
5761}
5762
5718static int nl80211_netlink_notify(struct notifier_block * nb, 5763static int nl80211_netlink_notify(struct notifier_block * nb,
5719 unsigned long state, 5764 unsigned long state,
5720 void *_notify) 5765 void *_notify)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 30d2f939150d..16c2f7190768 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -87,5 +87,9 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
87 struct net_device *netdev, 87 struct net_device *netdev,
88 enum nl80211_cqm_rssi_threshold_event rssi_event, 88 enum nl80211_cqm_rssi_threshold_event rssi_event,
89 gfp_t gfp); 89 gfp_t gfp);
90void
91nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
92 struct net_device *netdev, const u8 *peer,
93 u32 num_packets, gfp_t gfp);
90 94
91#endif /* __NET_WIRELESS_NL80211_H */ 95#endif /* __NET_WIRELESS_NL80211_H */