diff options
author | Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 2010-12-21 15:44:42 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-12-22 15:43:31 -0500 |
commit | 49b35bd3f5bbc6997b24b04e9d4896f00cee3528 (patch) | |
tree | 586a27da60ef7f235d3cb7db14c491098d01ae87 | |
parent | a3463a1fdc9aa0881760e54efbd62742275601a5 (diff) |
rndis_wlan: add support for set_cqm_rssi_config
Device poller already reads current RSSI, so add support for
set_cqm_rssi_config there.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/rndis_wlan.c | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index aa21d867f0ee..0cd971a4dd94 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -478,6 +478,9 @@ struct rndis_wlan_private { | |||
478 | struct mutex command_lock; | 478 | struct mutex command_lock; |
479 | unsigned long work_pending; | 479 | unsigned long work_pending; |
480 | int last_qual; | 480 | int last_qual; |
481 | s32 cqm_rssi_thold; | ||
482 | u32 cqm_rssi_hyst; | ||
483 | int last_cqm_event_rssi; | ||
481 | 484 | ||
482 | struct ieee80211_supported_band band; | 485 | struct ieee80211_supported_band band; |
483 | struct ieee80211_channel channels[ARRAY_SIZE(rndis_channels)]; | 486 | struct ieee80211_channel channels[ARRAY_SIZE(rndis_channels)]; |
@@ -569,6 +572,10 @@ static int rndis_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, | |||
569 | 572 | ||
570 | static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev); | 573 | static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev); |
571 | 574 | ||
575 | static int rndis_set_cqm_rssi_config(struct wiphy *wiphy, | ||
576 | struct net_device *dev, | ||
577 | s32 rssi_thold, u32 rssi_hyst); | ||
578 | |||
572 | static const struct cfg80211_ops rndis_config_ops = { | 579 | static const struct cfg80211_ops rndis_config_ops = { |
573 | .change_virtual_intf = rndis_change_virtual_intf, | 580 | .change_virtual_intf = rndis_change_virtual_intf, |
574 | .scan = rndis_scan, | 581 | .scan = rndis_scan, |
@@ -588,6 +595,7 @@ static const struct cfg80211_ops rndis_config_ops = { | |||
588 | .set_pmksa = rndis_set_pmksa, | 595 | .set_pmksa = rndis_set_pmksa, |
589 | .del_pmksa = rndis_del_pmksa, | 596 | .del_pmksa = rndis_del_pmksa, |
590 | .flush_pmksa = rndis_flush_pmksa, | 597 | .flush_pmksa = rndis_flush_pmksa, |
598 | .set_cqm_rssi_config = rndis_set_cqm_rssi_config, | ||
591 | }; | 599 | }; |
592 | 600 | ||
593 | static void *rndis_wiphy_privid = &rndis_wiphy_privid; | 601 | static void *rndis_wiphy_privid = &rndis_wiphy_privid; |
@@ -2566,6 +2574,19 @@ static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) | |||
2566 | return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid)); | 2574 | return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid)); |
2567 | } | 2575 | } |
2568 | 2576 | ||
2577 | static int rndis_set_cqm_rssi_config(struct wiphy *wiphy, | ||
2578 | struct net_device *dev, | ||
2579 | s32 rssi_thold, u32 rssi_hyst) | ||
2580 | { | ||
2581 | struct rndis_wlan_private *priv = wiphy_priv(wiphy); | ||
2582 | |||
2583 | priv->cqm_rssi_thold = rssi_thold; | ||
2584 | priv->cqm_rssi_hyst = rssi_hyst; | ||
2585 | priv->last_cqm_event_rssi = 0; | ||
2586 | |||
2587 | return 0; | ||
2588 | } | ||
2589 | |||
2569 | static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, | 2590 | static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, |
2570 | struct ndis_80211_assoc_info *info) | 2591 | struct ndis_80211_assoc_info *info) |
2571 | { | 2592 | { |
@@ -3095,6 +3116,32 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev, struct wiphy *wiphy) | |||
3095 | return retval; | 3116 | return retval; |
3096 | } | 3117 | } |
3097 | 3118 | ||
3119 | static void rndis_do_cqm(struct usbnet *usbdev, s32 rssi) | ||
3120 | { | ||
3121 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | ||
3122 | enum nl80211_cqm_rssi_threshold_event event; | ||
3123 | int thold, hyst, last_event; | ||
3124 | |||
3125 | if (priv->cqm_rssi_thold >= 0 || rssi >= 0) | ||
3126 | return; | ||
3127 | if (priv->infra_mode != NDIS_80211_INFRA_INFRA) | ||
3128 | return; | ||
3129 | |||
3130 | last_event = priv->last_cqm_event_rssi; | ||
3131 | thold = priv->cqm_rssi_thold; | ||
3132 | hyst = priv->cqm_rssi_hyst; | ||
3133 | |||
3134 | if (rssi < thold && (last_event == 0 || rssi < last_event - hyst)) | ||
3135 | event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW; | ||
3136 | else if (rssi > thold && (last_event == 0 || rssi > last_event + hyst)) | ||
3137 | event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; | ||
3138 | else | ||
3139 | return; | ||
3140 | |||
3141 | priv->last_cqm_event_rssi = rssi; | ||
3142 | cfg80211_cqm_rssi_notify(usbdev->net, event, GFP_KERNEL); | ||
3143 | } | ||
3144 | |||
3098 | #define DEVICE_POLLER_JIFFIES (HZ) | 3145 | #define DEVICE_POLLER_JIFFIES (HZ) |
3099 | static void rndis_device_poller(struct work_struct *work) | 3146 | static void rndis_device_poller(struct work_struct *work) |
3100 | { | 3147 | { |
@@ -3129,8 +3176,10 @@ static void rndis_device_poller(struct work_struct *work) | |||
3129 | 3176 | ||
3130 | len = sizeof(rssi); | 3177 | len = sizeof(rssi); |
3131 | ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len); | 3178 | ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len); |
3132 | if (ret == 0) | 3179 | if (ret == 0) { |
3133 | priv->last_qual = level_to_qual(le32_to_cpu(rssi)); | 3180 | priv->last_qual = level_to_qual(le32_to_cpu(rssi)); |
3181 | rndis_do_cqm(usbdev, le32_to_cpu(rssi)); | ||
3182 | } | ||
3134 | 3183 | ||
3135 | netdev_dbg(usbdev->net, "dev-poller: OID_802_11_RSSI -> %d, rssi:%d, qual: %d\n", | 3184 | netdev_dbg(usbdev->net, "dev-poller: OID_802_11_RSSI -> %d, rssi:%d, qual: %d\n", |
3136 | ret, le32_to_cpu(rssi), level_to_qual(le32_to_cpu(rssi))); | 3185 | ret, le32_to_cpu(rssi), level_to_qual(le32_to_cpu(rssi))); |