diff options
author | Juuso Oikarinen <juuso.oikarinen@nokia.com> | 2010-03-23 03:02:34 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-03-24 16:04:33 -0400 |
commit | a97c13c34509be460dea23c86f31c02daa2428b5 (patch) | |
tree | eb5d2860af9d6f3121254f2ef262e197b10bed34 | |
parent | d6dc1a386358979e12366d1f35eeb68fc181e101 (diff) |
mac80211: Add support for connection quality monitoring
Add support for the set_cqm_config op. This op function configures the
requested connection quality monitor rssi threshold and rssi hysteresis
values to the hardware if the hardware supports
IEEE80211_HW_SUPPORTS_CQM.
For unsupported hardware, currently -EOPNOTSUPP is returned, so the mac80211
is currently not doing connection quality monitoring on the host. This could be
added later, if needed.
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | include/net/mac80211.h | 30 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 27 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 15 |
3 files changed, 72 insertions, 0 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d14226f29ffc..1a8f50af49a0 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -144,6 +144,7 @@ struct ieee80211_low_level_stats { | |||
144 | * new beacon (beaconing modes) | 144 | * new beacon (beaconing modes) |
145 | * @BSS_CHANGED_BEACON_ENABLED: Beaconing should be | 145 | * @BSS_CHANGED_BEACON_ENABLED: Beaconing should be |
146 | * enabled/disabled (beaconing modes) | 146 | * enabled/disabled (beaconing modes) |
147 | * @BSS_CHANGED_CQM: Connection quality monitor config changed | ||
147 | */ | 148 | */ |
148 | enum ieee80211_bss_change { | 149 | enum ieee80211_bss_change { |
149 | BSS_CHANGED_ASSOC = 1<<0, | 150 | BSS_CHANGED_ASSOC = 1<<0, |
@@ -156,6 +157,7 @@ enum ieee80211_bss_change { | |||
156 | BSS_CHANGED_BSSID = 1<<7, | 157 | BSS_CHANGED_BSSID = 1<<7, |
157 | BSS_CHANGED_BEACON = 1<<8, | 158 | BSS_CHANGED_BEACON = 1<<8, |
158 | BSS_CHANGED_BEACON_ENABLED = 1<<9, | 159 | BSS_CHANGED_BEACON_ENABLED = 1<<9, |
160 | BSS_CHANGED_CQM = 1<<10, | ||
159 | }; | 161 | }; |
160 | 162 | ||
161 | /** | 163 | /** |
@@ -185,6 +187,9 @@ enum ieee80211_bss_change { | |||
185 | * @enable_beacon: whether beaconing should be enabled or not | 187 | * @enable_beacon: whether beaconing should be enabled or not |
186 | * @ht_operation_mode: HT operation mode (like in &struct ieee80211_ht_info). | 188 | * @ht_operation_mode: HT operation mode (like in &struct ieee80211_ht_info). |
187 | * This field is only valid when the channel type is one of the HT types. | 189 | * This field is only valid when the channel type is one of the HT types. |
190 | * @cqm_rssi_thold: Connection quality monitor RSSI threshold, a zero value | ||
191 | * implies disabled | ||
192 | * @cqm_rssi_hyst: Connection quality monitor RSSI hysteresis | ||
188 | */ | 193 | */ |
189 | struct ieee80211_bss_conf { | 194 | struct ieee80211_bss_conf { |
190 | const u8 *bssid; | 195 | const u8 *bssid; |
@@ -202,6 +207,8 @@ struct ieee80211_bss_conf { | |||
202 | u64 timestamp; | 207 | u64 timestamp; |
203 | u32 basic_rates; | 208 | u32 basic_rates; |
204 | u16 ht_operation_mode; | 209 | u16 ht_operation_mode; |
210 | s32 cqm_rssi_thold; | ||
211 | u32 cqm_rssi_hyst; | ||
205 | }; | 212 | }; |
206 | 213 | ||
207 | /** | 214 | /** |
@@ -959,6 +966,12 @@ enum ieee80211_tkip_key_type { | |||
959 | * periodic keep-alives to the AP and probing the AP on beacon loss. | 966 | * periodic keep-alives to the AP and probing the AP on beacon loss. |
960 | * When this flag is set, signaling beacon-loss will cause an immediate | 967 | * When this flag is set, signaling beacon-loss will cause an immediate |
961 | * change to disassociated state. | 968 | * change to disassociated state. |
969 | * | ||
970 | * @IEEE80211_HW_SUPPORTS_CQM_RSSI: | ||
971 | * Hardware can do connection quality monitoring - i.e. it can monitor | ||
972 | * connection quality related parameters, such as the RSSI level and | ||
973 | * provide notifications if configured trigger levels are reached. | ||
974 | * | ||
962 | */ | 975 | */ |
963 | enum ieee80211_hw_flags { | 976 | enum ieee80211_hw_flags { |
964 | IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, | 977 | IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, |
@@ -981,6 +994,7 @@ enum ieee80211_hw_flags { | |||
981 | IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, | 994 | IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, |
982 | IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, | 995 | IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, |
983 | IEEE80211_HW_CONNECTION_MONITOR = 1<<19, | 996 | IEEE80211_HW_CONNECTION_MONITOR = 1<<19, |
997 | IEEE80211_HW_SUPPORTS_CQM_RSSI = 1<<20, | ||
984 | }; | 998 | }; |
985 | 999 | ||
986 | /** | 1000 | /** |
@@ -2390,6 +2404,22 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif); | |||
2390 | */ | 2404 | */ |
2391 | void ieee80211_connection_loss(struct ieee80211_vif *vif); | 2405 | void ieee80211_connection_loss(struct ieee80211_vif *vif); |
2392 | 2406 | ||
2407 | /** | ||
2408 | * ieee80211_cqm_rssi_notify - inform a configured connection quality monitoring | ||
2409 | * rssi threshold triggered | ||
2410 | * | ||
2411 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. | ||
2412 | * @rssi_event: the RSSI trigger event type | ||
2413 | * @gfp: context flags | ||
2414 | * | ||
2415 | * When the %IEEE80211_HW_SUPPORTS_CQM_RSSI is set, and a connection quality | ||
2416 | * monitoring is configured with an rssi threshold, the driver will inform | ||
2417 | * whenever the rssi level reaches the threshold. | ||
2418 | */ | ||
2419 | void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, | ||
2420 | enum nl80211_cqm_rssi_threshold_event rssi_event, | ||
2421 | gfp_t gfp); | ||
2422 | |||
2393 | /* Rate control API */ | 2423 | /* Rate control API */ |
2394 | 2424 | ||
2395 | /** | 2425 | /** |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index b7116ef84a3b..c8f520529eec 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1402,6 +1402,32 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
1402 | return 0; | 1402 | return 0; |
1403 | } | 1403 | } |
1404 | 1404 | ||
1405 | static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy, | ||
1406 | struct net_device *dev, | ||
1407 | s32 rssi_thold, u32 rssi_hyst) | ||
1408 | { | ||
1409 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1410 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
1411 | struct ieee80211_vif *vif = &sdata->vif; | ||
1412 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | ||
1413 | |||
1414 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) | ||
1415 | return -EOPNOTSUPP; | ||
1416 | |||
1417 | if (rssi_thold == bss_conf->cqm_rssi_thold && | ||
1418 | rssi_hyst == bss_conf->cqm_rssi_hyst) | ||
1419 | return 0; | ||
1420 | |||
1421 | bss_conf->cqm_rssi_thold = rssi_thold; | ||
1422 | bss_conf->cqm_rssi_hyst = rssi_hyst; | ||
1423 | |||
1424 | /* tell the driver upon association, unless already associated */ | ||
1425 | if (sdata->u.mgd.associated) | ||
1426 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM); | ||
1427 | |||
1428 | return 0; | ||
1429 | } | ||
1430 | |||
1405 | static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, | 1431 | static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, |
1406 | struct net_device *dev, | 1432 | struct net_device *dev, |
1407 | const u8 *addr, | 1433 | const u8 *addr, |
@@ -1506,4 +1532,5 @@ struct cfg80211_ops mac80211_config_ops = { | |||
1506 | .remain_on_channel = ieee80211_remain_on_channel, | 1532 | .remain_on_channel = ieee80211_remain_on_channel, |
1507 | .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, | 1533 | .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, |
1508 | .action = ieee80211_action, | 1534 | .action = ieee80211_action, |
1535 | .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, | ||
1509 | }; | 1536 | }; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 865ea1cfb7bb..65eafda5738a 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -750,6 +750,11 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
750 | /* And the BSSID changed - we're associated now */ | 750 | /* And the BSSID changed - we're associated now */ |
751 | bss_info_changed |= BSS_CHANGED_BSSID; | 751 | bss_info_changed |= BSS_CHANGED_BSSID; |
752 | 752 | ||
753 | /* Tell the driver to monitor connection quality (if supported) */ | ||
754 | if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) && | ||
755 | sdata->vif.bss_conf.cqm_rssi_thold) | ||
756 | bss_info_changed |= BSS_CHANGED_CQM; | ||
757 | |||
753 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); | 758 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); |
754 | 759 | ||
755 | mutex_lock(&local->iflist_mtx); | 760 | mutex_lock(&local->iflist_mtx); |
@@ -2182,3 +2187,13 @@ int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata, | |||
2182 | *cookie = (unsigned long) skb; | 2187 | *cookie = (unsigned long) skb; |
2183 | return 0; | 2188 | return 0; |
2184 | } | 2189 | } |
2190 | |||
2191 | void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, | ||
2192 | enum nl80211_cqm_rssi_threshold_event rssi_event, | ||
2193 | gfp_t gfp) | ||
2194 | { | ||
2195 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
2196 | |||
2197 | cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); | ||
2198 | } | ||
2199 | EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); | ||