aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/libertas/assoc.c81
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/fw.c2
-rw-r--r--drivers/net/wireless/libertas/join.c13
-rw-r--r--drivers/net/wireless/libertas/wext.c182
5 files changed, 117 insertions, 162 deletions
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index 4bc128fa584..3f2dfaf879c 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -22,6 +22,10 @@ static int assoc_helper_essid(wlan_private *priv,
lbs_deb_enter(LBS_DEB_ASSOC);
+ /* FIXME: take channel into account when picking SSIDs if a channel
+ * is set.
+ */
+
lbs_deb_assoc("New SSID requested: %s\n", assoc_req->ssid.ssid);
if (assoc_req->mode == IW_MODE_INFRA) {
if (adapter->prescan) {
@@ -158,6 +162,69 @@ done:
}
+static int update_channel(wlan_private * priv)
+{
+ /* the channel in f/w could be out of sync, get the current channel */
+ return libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
+ cmd_opt_802_11_rf_channel_get,
+ cmd_option_waitforrsp, 0, NULL);
+}
+
+static int assoc_helper_channel(wlan_private *priv,
+ struct assoc_request * assoc_req)
+{
+ wlan_adapter *adapter = priv->adapter;
+ int ret = 0;
+
+ lbs_deb_enter(LBS_DEB_ASSOC);
+
+ ret = update_channel(priv);
+ if (ret < 0) {
+ lbs_deb_assoc("ASSOC: channel: error getting channel.");
+ }
+
+ if (assoc_req->channel == adapter->curbssparams.channel)
+ goto done;
+
+ lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
+ adapter->curbssparams.channel, assoc_req->channel);
+
+ ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
+ cmd_opt_802_11_rf_channel_set,
+ cmd_option_waitforrsp, 0, &assoc_req->channel);
+ if (ret < 0) {
+ lbs_deb_assoc("ASSOC: channel: error setting channel.");
+ }
+
+ ret = update_channel(priv);
+ if (ret < 0) {
+ lbs_deb_assoc("ASSOC: channel: error getting channel.");
+ }
+
+ if (assoc_req->channel != adapter->curbssparams.channel) {
+ lbs_deb_assoc("ASSOC: channel: failed to update channel to %d",
+ assoc_req->channel);
+ goto done;
+ }
+
+ if ( assoc_req->secinfo.wep_enabled
+ && (assoc_req->wep_keys[0].len
+ || assoc_req->wep_keys[1].len
+ || assoc_req->wep_keys[2].len
+ || assoc_req->wep_keys[3].len)) {
+ /* Make sure WEP keys are re-sent to firmware */
+ set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
+ }
+
+ /* Must restart/rejoin adhoc networks after channel change */
+ set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
+
+done:
+ lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
+ return ret;
+}
+
+
static int assoc_helper_wep_keys(wlan_private *priv,
struct assoc_request * assoc_req)
{
@@ -334,6 +401,11 @@ static int should_stop_adhoc(wlan_adapter *adapter,
return 1;
}
+ if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
+ if (assoc_req->channel != adapter->curbssparams.channel)
+ return 1;
+ }
+
return 0;
}
@@ -423,6 +495,15 @@ lbs_deb_assoc("ASSOC(:%d) mode: ret = %d\n", __LINE__, ret);
}
}
+ if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
+ ret = assoc_helper_channel(priv, assoc_req);
+ if (ret) {
+ lbs_deb_assoc("ASSOC(:%d) channel: ret = %d\n",
+ __LINE__, ret);
+ goto out;
+ }
+ }
+
if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)
|| test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
ret = assoc_helper_wep_keys(priv, assoc_req);
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 41d8a4cdd43..4ca60d9323b 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -287,7 +287,6 @@ struct _wlan_adapter {
u32 txantenna;
u32 rxantenna;
- u8 adhocchannel;
u32 fragthsd;
u32 rtsthsd;
diff --git a/drivers/net/wireless/libertas/fw.c b/drivers/net/wireless/libertas/fw.c
index 56b272d62a8..2e535ef7e80 100644
--- a/drivers/net/wireless/libertas/fw.c
+++ b/drivers/net/wireless/libertas/fw.c
@@ -220,8 +220,6 @@ static void wlan_init_adapter(wlan_private * priv)
memset(&adapter->capinfo, 0, sizeof(adapter->capinfo));
adapter->capinfo.shortpreamble = SHORT_PREAMBLE_ALLOWED;
- adapter->adhocchannel = DEFAULT_AD_HOC_CHANNEL;
-
adapter->psmode = wlan802_11powermodecam;
adapter->multipledtim = MRVDRV_DEFAULT_MULTIPLE_DTIM;
diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c
index c9111b87706..a11ce3a6f61 100644
--- a/drivers/net/wireless/libertas/join.c
+++ b/drivers/net/wireless/libertas/join.c
@@ -158,7 +158,6 @@ int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *a
libertas_set_radio_control(priv);
- lbs_deb_join("Adhoc channel = %d\n", adapter->adhocchannel);
lbs_deb_join("curbssparams.channel = %d\n",
adapter->curbssparams.channel);
lbs_deb_join("curbssparams.band = %d\n", adapter->curbssparams.band);
@@ -513,15 +512,13 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
adhs->phyparamset.dsparamset.elementid = DS_PARA_IE_ID;
adhs->phyparamset.dsparamset.len = DS_PARA_IE_LEN;
- WARN_ON(!adapter->adhocchannel);
+ WARN_ON(!adapter->curbssparams.channel);
lbs_deb_join("ADHOC_S_CMD: Creating ADHOC on channel %d\n",
- adapter->adhocchannel);
-
- adapter->curbssparams.channel = adapter->adhocchannel;
+ adapter->curbssparams.channel);
- pbssdesc->channel = adapter->adhocchannel;
- adhs->phyparamset.dsparamset.currentchan = adapter->adhocchannel;
+ pbssdesc->channel = adapter->curbssparams.channel;
+ adhs->phyparamset.dsparamset.currentchan = adapter->curbssparams.channel;
memcpy(&pbssdesc->phyparamset,
&adhs->phyparamset, sizeof(union ieeetypes_phyparamset));
@@ -909,7 +906,7 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
lbs_deb_join("ADHOC_RESP: - Joined/Started Ad Hoc\n");
- lbs_deb_join("ADHOC_RESP: channel = %d\n", adapter->adhocchannel);
+ lbs_deb_join("ADHOC_RESP: channel = %d\n", adapter->curbssparams.channel);
lbs_deb_join("ADHOC_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
padhocresult->BSSID[0], padhocresult->BSSID[1],
padhocresult->BSSID[2], padhocresult->BSSID[3],
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 518371a76c3..40dd08018b4 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -157,103 +157,6 @@ static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * adapter,
return cfp;
}
-static int updatecurrentchannel(wlan_private * priv)
-{
- int ret;
-
- /*
- ** the channel in f/w could be out of sync, get the current channel
- */
- ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
- cmd_opt_802_11_rf_channel_get,
- cmd_option_waitforrsp, 0, NULL);
-
- lbs_deb_wext("current channel %d\n",
- priv->adapter->curbssparams.channel);
-
- return ret;
-}
-
-static int setcurrentchannel(wlan_private * priv, int channel)
-{
- lbs_deb_wext("set channel %d\n", channel);
-
- /*
- ** Current channel is not set to adhocchannel requested, set channel
- */
- return (libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
- cmd_opt_802_11_rf_channel_set,
- cmd_option_waitforrsp, 0, &channel));
-}
-
-static int changeadhocchannel(wlan_private * priv, int channel)
-{
- int ret = 0;
- struct WLAN_802_11_SSID curadhocssid;
- struct bss_descriptor * join_bss = NULL;
- wlan_adapter *adapter = priv->adapter;
-
- adapter->adhocchannel = channel;
-
- updatecurrentchannel(priv);
-
- if (adapter->curbssparams.channel == adapter->adhocchannel) {
- /* adhocchannel is set to the current channel already */
- goto out;
- }
-
- lbs_deb_wext("updating channel from %d to %d\n",
- adapter->curbssparams.channel, adapter->adhocchannel);
-
- setcurrentchannel(priv, adapter->adhocchannel);
-
- updatecurrentchannel(priv);
-
- if (adapter->curbssparams.channel != adapter->adhocchannel) {
- lbs_deb_wext("failed to updated channel to %d, channel = %d\n",
- adapter->adhocchannel, adapter->curbssparams.channel);
- ret = -1;
- goto out;
- }
-
- if (adapter->connect_status != libertas_connected)
- goto out;
-
- lbs_deb_wext("channel changed while in IBSS\n");
-
- /* Copy the current ssid */
- memcpy(&curadhocssid, &adapter->curbssparams.ssid,
- sizeof(struct WLAN_802_11_SSID));
-
- /* Exit Adhoc mode */
- lbs_deb_wext("in changeadhocchannel(): sending Adhoc stop\n");
- ret = libertas_stop_adhoc_network(priv);
- if (ret)
- goto out;
-
- /* Scan for the network, do not save previous results. Stale
- * scan data will cause us to join a non-existant adhoc network
- */
- libertas_send_specific_SSID_scan(priv, &curadhocssid, 1);
-
- /* find out the BSSID that matches the current SSID */
- join_bss = libertas_find_SSID_in_list(adapter, &curadhocssid, NULL,
- IW_MODE_ADHOC);
-
- if (join_bss) {
- lbs_deb_wext("SSID found in list, so join\n");
- libertas_join_adhoc_network(priv, join_bss);
- } else {
- lbs_deb_wext("SSID not found in list, "
- "creating AdHoc with SSID '%s'\n",
- curadhocssid.ssid);
- libertas_start_adhoc_network(priv, &curadhocssid);
- }
-
-out:
- lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
- return ret;
-}
/**
* @brief Set Radio On/OFF
@@ -1228,82 +1131,59 @@ out:
static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
struct iw_freq *fwrq, char *extra)
{
- int ret = 0;
+ int ret = -EINVAL;
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- int rc = -EINPROGRESS; /* Call commit handler */
struct chan_freq_power *cfp;
+ struct assoc_request * assoc_req;
lbs_deb_enter(LBS_DEB_WEXT);
- /*
- * If setting by frequency, convert to a channel
- */
- if (fwrq->e == 1) {
+ mutex_lock(&adapter->lock);
+ assoc_req = wlan_get_association_request(adapter);
+ if (!assoc_req) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ /* If setting by frequency, convert to a channel */
+ if (fwrq->e == 1) {
long f = fwrq->m / 100000;
- int c = 0;
cfp = find_cfp_by_band_and_freq(adapter, 0, f);
if (!cfp) {
lbs_deb_wext("invalid freq %ld\n", f);
- return -EINVAL;
+ goto out;
}
- c = (int)cfp->channel;
-
- if (c < 0)
- return -EINVAL;
-
fwrq->e = 0;
- fwrq->m = c;
+ fwrq->m = (int) cfp->channel;
}
- /*
- * Setting by channel number
- */
+ /* Setting by channel number */
if (fwrq->m > 1000 || fwrq->e > 0) {
- rc = -EOPNOTSUPP;
- } else {
- int channel = fwrq->m;
+ goto out;
+ }
- cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, channel);
- if (!cfp) {
- rc = -EINVAL;
- } else {
- if (adapter->mode == IW_MODE_ADHOC) {
- rc = changeadhocchannel(priv, channel);
- /* If station is WEP enabled, send the
- * command to set WEP in firmware
- */
- if (adapter->secinfo.wep_enabled) {
- lbs_deb_wext("set_freq: WEP enabled\n");
- ret = libertas_prepare_and_send_command(priv,
- cmd_802_11_set_wep,
- cmd_act_add,
- cmd_option_waitforrsp,
- 0,
- NULL);
-
- if (ret) {
- rc = ret;
- goto out;
- }
-
- adapter->currentpacketfilter |=
- cmd_act_mac_wep_enable;
-
- libertas_set_mac_packet_filter(priv);
- }
- } else {
- rc = -EOPNOTSUPP;
- }
- }
+ cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, fwrq->m);
+ if (!cfp) {
+ goto out;
}
+ assoc_req->channel = fwrq->m;
+ ret = 0;
+
out:
- lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", rc);
- return rc;
+ if (ret == 0) {
+ set_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags);
+ wlan_postpone_association_work(priv);
+ } else {
+ wlan_cancel_association_work(priv);
+ }
+ mutex_unlock(&adapter->lock);
+
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
}
/**