diff options
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r-- | drivers/net/wireless/libertas/assoc.c | 81 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/dev.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/fw.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/join.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/wext.c | 182 |
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; } /** |