aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2010-03-23 03:02:34 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-03-24 16:04:33 -0400
commita97c13c34509be460dea23c86f31c02daa2428b5 (patch)
treeeb5d2860af9d6f3121254f2ef262e197b10bed34
parentd6dc1a386358979e12366d1f35eeb68fc181e101 (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.h30
-rw-r--r--net/mac80211/cfg.c27
-rw-r--r--net/mac80211/mlme.c15
3 files changed, 72 insertions, 0 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index d14226f29ff..1a8f50af49a 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 */
148enum ieee80211_bss_change { 149enum 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 */
189struct ieee80211_bss_conf { 194struct 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 */
963enum ieee80211_hw_flags { 976enum 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 */
2391void ieee80211_connection_loss(struct ieee80211_vif *vif); 2405void 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 */
2419void 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 b7116ef84a3..c8f520529ee 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
1405static 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
1405static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, 1431static 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 865ea1cfb7b..65eafda5738 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
2191void 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}
2199EXPORT_SYMBOL(ieee80211_cqm_rssi_notify);