This patch adds a new wext event that notifies the user space about a low signal quality. The currently used indicator is as follows: If three successive beacons are received with a signal quality lower then 40% user space gets informed. Any ideas about which indicators should be used? Comments? Signed-off-by: Helmut Schaa <hschaa@xxxxxxx> --- diff --git a/include/linux/wireless.h b/include/linux/wireless.h index d7958f9..6229aa2 100644 --- a/include/linux/wireless.h +++ b/include/linux/wireless.h @@ -294,6 +294,7 @@ #define SIOCSIWPOWER 0x8B2C /* set Power Management settings */ #define SIOCGIWPOWER 0x8B2D /* get Power Management settings */ + /* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM). * This ioctl uses struct iw_point and data buffer that includes IE id and len * fields. More than one IE may be included in the request. Setting the generic @@ -389,6 +390,8 @@ * pre-authentication * (struct iw_pmkid_cand) */ +#define IWEVROAM 0x8C0A /* roaming threshold exceeded */ + #define IWEVFIRST 0x8C00 #define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3912fba..c05f70c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -351,6 +351,7 @@ struct ieee80211_if_sta { u32 supp_rates_bits[IEEE80211_NUM_BANDS]; int wmm_last_param_set; + unsigned int roam_threshold_count; }; struct ieee80211_if_mesh { diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2e55208..e67fe56 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -45,6 +45,7 @@ #define IEEE80211_IBSS_MAX_STA_ENTRIES 128 +#define IEEE80211_ROAMING_QUALITY_THRESHOLD 40 /* utils */ static int ecw2cw(int ecw) @@ -1659,6 +1660,27 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, } } +static void ieee80211_rx_check_threshold(struct ieee80211_sub_if_data *sdata, + int freq) +{ + union iwreq_data wrqu; + struct ieee80211_bss *bss; + struct ieee80211_if_sta *ifsta = &sdata->u.sta; + bss = ieee80211_rx_bss_get(sdata->local, ifsta->bssid, freq, + ifsta->ssid, ifsta->ssid_len); + + if (bss->qual < IEEE80211_ROAMING_QUALITY_THRESHOLD) { + if (++(ifsta->roam_threshold_count) > 3) { + printk(KERN_DEBUG "%s roaming theshold exceeded\n", + sdata->dev->name); + memset(&wrqu, 0, sizeof(wrqu)); + wireless_send_event(sdata->dev, IWEVROAM, &wrqu, NULL); + } + } else + ifsta->roam_threshold_count = 0; + + ieee80211_rx_bss_put(sdata->local, bss); +} static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, @@ -1711,6 +1733,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, &bss_info); } + ieee80211_rx_check_threshold(sdata, rx_status->freq); ieee80211_bss_info_change_notify(sdata, changed); } diff --git a/net/wireless/wext.c b/net/wireless/wext.c index d98ffb7..c2feebb 100644 --- a/net/wireless/wext.c +++ b/net/wireless/wext.c @@ -387,6 +387,9 @@ static const struct iw_ioctl_description standard_event[] = { .token_size = 1, .max_tokens = sizeof(struct iw_pmkid_cand), }, + [IWEVROAM - IWEVFIRST] = { + .header_type = IW_HEADER_TYPE_ADDR, + }, }; static const unsigned standard_event_num = ARRAY_SIZE(standard_event); -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html