libertas: allow setting channel on mshX device
authorDavid Woodhouse <dwmw2@infradead.org>
Wed, 12 Dec 2007 00:56:28 +0000 (19:56 -0500)
committerDavid S. Miller <davem@davemloft.net>
Mon, 28 Jan 2008 23:06:56 +0000 (15:06 -0800)
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/libertas/wext.c

index 0a060726cf32c4a4f870911c384c36e171c0e866..262d4cc580460ddf224ecddecafe0fa88cb49056 100644 (file)
@@ -959,6 +959,57 @@ out:
        return ret;
 }
 
+static int lbs_mesh_set_freq(struct net_device *dev,
+                            struct iw_request_info *info,
+                            struct iw_freq *fwrq, char *extra)
+{
+       struct lbs_private *priv = dev->priv;
+       struct chan_freq_power *cfp;
+       int ret = -EINVAL;
+
+       lbs_deb_enter(LBS_DEB_WEXT);
+
+       /* If setting by frequency, convert to a channel */
+       if (fwrq->e == 1) {
+               long f = fwrq->m / 100000;
+
+               cfp = find_cfp_by_band_and_freq(priv, 0, f);
+               if (!cfp) {
+                       lbs_deb_wext("invalid freq %ld\n", f);
+                       goto out;
+               }
+
+               fwrq->e = 0;
+               fwrq->m = (int) cfp->channel;
+       }
+
+       /* Setting by channel number */
+       if (fwrq->m > 1000 || fwrq->e > 0) {
+               goto out;
+       }
+
+       cfp = lbs_find_cfp_by_band_and_channel(priv, 0, fwrq->m);
+       if (!cfp) {
+               goto out;
+       }
+
+       if (fwrq->m != priv->curbssparams.channel) {
+               lbs_deb_wext("mesh channel change forces eth disconnect\n");
+               if (priv->mode == IW_MODE_INFRA)
+                       lbs_send_deauthentication(priv);
+               else if (priv->mode == IW_MODE_ADHOC)
+                       lbs_stop_adhoc_network(priv);
+       }
+       priv->curbssparams.channel = fwrq->m;
+       lbs_mesh_config(priv, 0);
+       lbs_mesh_config(priv, 1);
+       ret = 0;
+
+out:
+       lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+       return ret;
+}
+
 static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
                  struct iw_param *vwrq, char *extra)
 {
@@ -2097,7 +2148,7 @@ static const iw_handler mesh_wlan_handler[] = {
        (iw_handler) lbs_get_name,      /* SIOCGIWNAME */
        (iw_handler) NULL,      /* SIOCSIWNWID */
        (iw_handler) NULL,      /* SIOCGIWNWID */
-       (iw_handler) lbs_set_freq,      /* SIOCSIWFREQ */
+       (iw_handler) lbs_mesh_set_freq, /* SIOCSIWFREQ */
        (iw_handler) lbs_get_freq,      /* SIOCGIWFREQ */
        (iw_handler) NULL,              /* SIOCSIWMODE */
        (iw_handler) mesh_wlan_get_mode,        /* SIOCGIWMODE */