[PATCH] ipw2200: wireless extension sensitivity threshold support

The patch allows the user to set the handover threshold, i.e. the number
of consecutively missed beacons that will trigger a roaming attempt. The
disassociation threshold is set to 3 times the handover threshold.

Signed-off-by: Olivier Hochreutiner <olivier.hochreutiner@epfl.ch>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 954a095..078f33b 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -8608,6 +8608,52 @@
 	return 0;
 }
 
+static int ipw_wx_set_sens(struct net_device *dev,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *extra)
+{
+	struct ipw_priv *priv = ieee80211_priv(dev);
+	int err = 0;
+
+	IPW_DEBUG_WX("Setting roaming threshold to %d\n", wrqu->sens.value);
+	IPW_DEBUG_WX("Setting disassociate threshold to %d\n", 3*wrqu->sens.value);
+	mutex_lock(&priv->mutex);
+
+	if (wrqu->sens.fixed == 0)
+	{
+		priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
+		priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
+		goto out;
+	}
+	if ((wrqu->sens.value > IPW_MB_ROAMING_THRESHOLD_MAX) ||
+	    (wrqu->sens.value < IPW_MB_ROAMING_THRESHOLD_MIN)) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	priv->roaming_threshold = wrqu->sens.value;
+	priv->disassociate_threshold = 3*wrqu->sens.value;
+      out:
+	mutex_unlock(&priv->mutex);
+	return err;
+}
+
+static int ipw_wx_get_sens(struct net_device *dev,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *extra)
+{
+	struct ipw_priv *priv = ieee80211_priv(dev);
+	mutex_lock(&priv->mutex);
+	wrqu->sens.fixed = 1;
+	wrqu->sens.value = priv->roaming_threshold;
+	mutex_unlock(&priv->mutex);
+
+	IPW_DEBUG_WX("GET roaming threshold -> %s %d \n",
+		     wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
+
+	return 0;
+}
+
 static int ipw_wx_set_rate(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
@@ -9429,6 +9475,8 @@
 	IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
 	IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
 	IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
+	IW_IOCTL(SIOCSIWSENS) = ipw_wx_set_sens,
+	IW_IOCTL(SIOCGIWSENS) = ipw_wx_get_sens,
 	IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
 	IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
 	IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,