summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/wext.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-12-11 19:56:28 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 15:06:56 -0800
commit823eaa2cc261e3723772aa4aaa4d76c5815b117f (patch)
tree678d61c898704a66408df65206759f0e5e59472a /drivers/net/wireless/libertas/wext.c
parentf5956bf1e4575175135d636db1b7f3ab950e0dc3 (diff)
libertas: allow setting channel on mshX device
Signed-off-by: David Woodhouse <dwmw2@infradead.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/wext.c')
-rw-r--r--drivers/net/wireless/libertas/wext.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 0a060726cf3..262d4cc5804 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -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 */