aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas')
-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 4bc128fa5848..3f2dfaf879c5 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,
22 22
23 lbs_deb_enter(LBS_DEB_ASSOC); 23 lbs_deb_enter(LBS_DEB_ASSOC);
24 24
25 /* FIXME: take channel into account when picking SSIDs if a channel
26 * is set.
27 */
28
25 lbs_deb_assoc("New SSID requested: %s\n", assoc_req->ssid.ssid); 29 lbs_deb_assoc("New SSID requested: %s\n", assoc_req->ssid.ssid);
26 if (assoc_req->mode == IW_MODE_INFRA) { 30 if (assoc_req->mode == IW_MODE_INFRA) {
27 if (adapter->prescan) { 31 if (adapter->prescan) {
@@ -158,6 +162,69 @@ done:
158} 162}
159 163
160 164
165static int update_channel(wlan_private * priv)
166{
167 /* the channel in f/w could be out of sync, get the current channel */
168 return libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
169 cmd_opt_802_11_rf_channel_get,
170 cmd_option_waitforrsp, 0, NULL);
171}
172
173static int assoc_helper_channel(wlan_private *priv,
174 struct assoc_request * assoc_req)
175{
176 wlan_adapter *adapter = priv->adapter;
177 int ret = 0;
178
179 lbs_deb_enter(LBS_DEB_ASSOC);
180
181 ret = update_channel(priv);
182 if (ret < 0) {
183 lbs_deb_assoc("ASSOC: channel: error getting channel.");
184 }
185
186 if (assoc_req->channel == adapter->curbssparams.channel)
187 goto done;
188
189 lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
190 adapter->curbssparams.channel, assoc_req->channel);
191
192 ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
193 cmd_opt_802_11_rf_channel_set,
194 cmd_option_waitforrsp, 0, &assoc_req->channel);
195 if (ret < 0) {
196 lbs_deb_assoc("ASSOC: channel: error setting channel.");
197 }
198
199 ret = update_channel(priv);
200 if (ret < 0) {
201 lbs_deb_assoc("ASSOC: channel: error getting channel.");
202 }
203
204 if (assoc_req->channel != adapter->curbssparams.channel) {
205 lbs_deb_assoc("ASSOC: channel: failed to update channel to %d",
206 assoc_req->channel);
207 goto done;
208 }
209
210 if ( assoc_req->secinfo.wep_enabled
211 && (assoc_req->wep_keys[0].len
212 || assoc_req->wep_keys[1].len
213 || assoc_req->wep_keys[2].len
214 || assoc_req->wep_keys[3].len)) {
215 /* Make sure WEP keys are re-sent to firmware */
216 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
217 }
218
219 /* Must restart/rejoin adhoc networks after channel change */
220 set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
221
222done:
223 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
224 return ret;
225}
226
227
161static int assoc_helper_wep_keys(wlan_private *priv, 228static int assoc_helper_wep_keys(wlan_private *priv,
162 struct assoc_request * assoc_req) 229 struct assoc_request * assoc_req)
163{ 230{
@@ -334,6 +401,11 @@ static int should_stop_adhoc(wlan_adapter *adapter,
334 return 1; 401 return 1;
335 } 402 }
336 403
404 if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
405 if (assoc_req->channel != adapter->curbssparams.channel)
406 return 1;
407 }
408
337 return 0; 409 return 0;
338} 410}
339 411
@@ -423,6 +495,15 @@ lbs_deb_assoc("ASSOC(:%d) mode: ret = %d\n", __LINE__, ret);
423 } 495 }
424 } 496 }
425 497
498 if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
499 ret = assoc_helper_channel(priv, assoc_req);
500 if (ret) {
501 lbs_deb_assoc("ASSOC(:%d) channel: ret = %d\n",
502 __LINE__, ret);
503 goto out;
504 }
505 }
506
426 if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) 507 if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)
427 || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { 508 || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
428 ret = assoc_helper_wep_keys(priv, assoc_req); 509 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 41d8a4cdd43b..4ca60d9323b4 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -287,7 +287,6 @@ struct _wlan_adapter {
287 u32 txantenna; 287 u32 txantenna;
288 u32 rxantenna; 288 u32 rxantenna;
289 289
290 u8 adhocchannel;
291 u32 fragthsd; 290 u32 fragthsd;
292 u32 rtsthsd; 291 u32 rtsthsd;
293 292
diff --git a/drivers/net/wireless/libertas/fw.c b/drivers/net/wireless/libertas/fw.c
index 56b272d62a86..2e535ef7e803 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)
220 memset(&adapter->capinfo, 0, sizeof(adapter->capinfo)); 220 memset(&adapter->capinfo, 0, sizeof(adapter->capinfo));
221 adapter->capinfo.shortpreamble = SHORT_PREAMBLE_ALLOWED; 221 adapter->capinfo.shortpreamble = SHORT_PREAMBLE_ALLOWED;
222 222
223 adapter->adhocchannel = DEFAULT_AD_HOC_CHANNEL;
224
225 adapter->psmode = wlan802_11powermodecam; 223 adapter->psmode = wlan802_11powermodecam;
226 adapter->multipledtim = MRVDRV_DEFAULT_MULTIPLE_DTIM; 224 adapter->multipledtim = MRVDRV_DEFAULT_MULTIPLE_DTIM;
227 225
diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c
index c9111b877067..a11ce3a6f611 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
158 158
159 libertas_set_radio_control(priv); 159 libertas_set_radio_control(priv);
160 160
161 lbs_deb_join("Adhoc channel = %d\n", adapter->adhocchannel);
162 lbs_deb_join("curbssparams.channel = %d\n", 161 lbs_deb_join("curbssparams.channel = %d\n",
163 adapter->curbssparams.channel); 162 adapter->curbssparams.channel);
164 lbs_deb_join("curbssparams.band = %d\n", adapter->curbssparams.band); 163 lbs_deb_join("curbssparams.band = %d\n", adapter->curbssparams.band);
@@ -513,15 +512,13 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
513 adhs->phyparamset.dsparamset.elementid = DS_PARA_IE_ID; 512 adhs->phyparamset.dsparamset.elementid = DS_PARA_IE_ID;
514 adhs->phyparamset.dsparamset.len = DS_PARA_IE_LEN; 513 adhs->phyparamset.dsparamset.len = DS_PARA_IE_LEN;
515 514
516 WARN_ON(!adapter->adhocchannel); 515 WARN_ON(!adapter->curbssparams.channel);
517 516
518 lbs_deb_join("ADHOC_S_CMD: Creating ADHOC on channel %d\n", 517 lbs_deb_join("ADHOC_S_CMD: Creating ADHOC on channel %d\n",
519 adapter->adhocchannel); 518 adapter->curbssparams.channel);
520
521 adapter->curbssparams.channel = adapter->adhocchannel;
522 519
523 pbssdesc->channel = adapter->adhocchannel; 520 pbssdesc->channel = adapter->curbssparams.channel;
524 adhs->phyparamset.dsparamset.currentchan = adapter->adhocchannel; 521 adhs->phyparamset.dsparamset.currentchan = adapter->curbssparams.channel;
525 522
526 memcpy(&pbssdesc->phyparamset, 523 memcpy(&pbssdesc->phyparamset,
527 &adhs->phyparamset, sizeof(union ieeetypes_phyparamset)); 524 &adhs->phyparamset, sizeof(union ieeetypes_phyparamset));
@@ -909,7 +906,7 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
909 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); 906 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
910 907
911 lbs_deb_join("ADHOC_RESP: - Joined/Started Ad Hoc\n"); 908 lbs_deb_join("ADHOC_RESP: - Joined/Started Ad Hoc\n");
912 lbs_deb_join("ADHOC_RESP: channel = %d\n", adapter->adhocchannel); 909 lbs_deb_join("ADHOC_RESP: channel = %d\n", adapter->curbssparams.channel);
913 lbs_deb_join("ADHOC_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n", 910 lbs_deb_join("ADHOC_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
914 padhocresult->BSSID[0], padhocresult->BSSID[1], 911 padhocresult->BSSID[0], padhocresult->BSSID[1],
915 padhocresult->BSSID[2], padhocresult->BSSID[3], 912 padhocresult->BSSID[2], padhocresult->BSSID[3],
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 518371a76c36..40dd08018b49 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,
157 return cfp; 157 return cfp;
158} 158}
159 159
160static int updatecurrentchannel(wlan_private * priv)
161{
162 int ret;
163
164 /*
165 ** the channel in f/w could be out of sync, get the current channel
166 */
167 ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
168 cmd_opt_802_11_rf_channel_get,
169 cmd_option_waitforrsp, 0, NULL);
170
171 lbs_deb_wext("current channel %d\n",
172 priv->adapter->curbssparams.channel);
173
174 return ret;
175}
176
177static int setcurrentchannel(wlan_private * priv, int channel)
178{
179 lbs_deb_wext("set channel %d\n", channel);
180
181 /*
182 ** Current channel is not set to adhocchannel requested, set channel
183 */
184 return (libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
185 cmd_opt_802_11_rf_channel_set,
186 cmd_option_waitforrsp, 0, &channel));
187}
188
189static int changeadhocchannel(wlan_private * priv, int channel)
190{
191 int ret = 0;
192 struct WLAN_802_11_SSID curadhocssid;
193 struct bss_descriptor * join_bss = NULL;
194 wlan_adapter *adapter = priv->adapter;
195
196 adapter->adhocchannel = channel;
197
198 updatecurrentchannel(priv);
199
200 if (adapter->curbssparams.channel == adapter->adhocchannel) {
201 /* adhocchannel is set to the current channel already */
202 goto out;
203 }
204
205 lbs_deb_wext("updating channel from %d to %d\n",
206 adapter->curbssparams.channel, adapter->adhocchannel);
207
208 setcurrentchannel(priv, adapter->adhocchannel);
209
210 updatecurrentchannel(priv);
211
212 if (adapter->curbssparams.channel != adapter->adhocchannel) {
213 lbs_deb_wext("failed to updated channel to %d, channel = %d\n",
214 adapter->adhocchannel, adapter->curbssparams.channel);
215 ret = -1;
216 goto out;
217 }
218
219 if (adapter->connect_status != libertas_connected)
220 goto out;
221
222 lbs_deb_wext("channel changed while in IBSS\n");
223
224 /* Copy the current ssid */
225 memcpy(&curadhocssid, &adapter->curbssparams.ssid,
226 sizeof(struct WLAN_802_11_SSID));
227
228 /* Exit Adhoc mode */
229 lbs_deb_wext("in changeadhocchannel(): sending Adhoc stop\n");
230 ret = libertas_stop_adhoc_network(priv);
231 if (ret)
232 goto out;
233
234 /* Scan for the network, do not save previous results. Stale
235 * scan data will cause us to join a non-existant adhoc network
236 */
237 libertas_send_specific_SSID_scan(priv, &curadhocssid, 1);
238
239 /* find out the BSSID that matches the current SSID */
240 join_bss = libertas_find_SSID_in_list(adapter, &curadhocssid, NULL,
241 IW_MODE_ADHOC);
242
243 if (join_bss) {
244 lbs_deb_wext("SSID found in list, so join\n");
245 libertas_join_adhoc_network(priv, join_bss);
246 } else {
247 lbs_deb_wext("SSID not found in list, "
248 "creating AdHoc with SSID '%s'\n",
249 curadhocssid.ssid);
250 libertas_start_adhoc_network(priv, &curadhocssid);
251 }
252
253out:
254 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
255 return ret;
256}
257 160
258/** 161/**
259 * @brief Set Radio On/OFF 162 * @brief Set Radio On/OFF
@@ -1228,82 +1131,59 @@ out:
1228static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info, 1131static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
1229 struct iw_freq *fwrq, char *extra) 1132 struct iw_freq *fwrq, char *extra)
1230{ 1133{
1231 int ret = 0; 1134 int ret = -EINVAL;
1232 wlan_private *priv = dev->priv; 1135 wlan_private *priv = dev->priv;
1233 wlan_adapter *adapter = priv->adapter; 1136 wlan_adapter *adapter = priv->adapter;
1234 int rc = -EINPROGRESS; /* Call commit handler */
1235 struct chan_freq_power *cfp; 1137 struct chan_freq_power *cfp;
1138 struct assoc_request * assoc_req;
1236 1139
1237 lbs_deb_enter(LBS_DEB_WEXT); 1140 lbs_deb_enter(LBS_DEB_WEXT);
1238 1141
1239 /* 1142 mutex_lock(&adapter->lock);
1240 * If setting by frequency, convert to a channel 1143 assoc_req = wlan_get_association_request(adapter);
1241 */ 1144 if (!assoc_req) {
1242 if (fwrq->e == 1) { 1145 ret = -ENOMEM;
1146 goto out;
1147 }
1243 1148
1149 /* If setting by frequency, convert to a channel */
1150 if (fwrq->e == 1) {
1244 long f = fwrq->m / 100000; 1151 long f = fwrq->m / 100000;
1245 int c = 0;
1246 1152
1247 cfp = find_cfp_by_band_and_freq(adapter, 0, f); 1153 cfp = find_cfp_by_band_and_freq(adapter, 0, f);
1248 if (!cfp) { 1154 if (!cfp) {
1249 lbs_deb_wext("invalid freq %ld\n", f); 1155 lbs_deb_wext("invalid freq %ld\n", f);
1250 return -EINVAL; 1156 goto out;
1251 } 1157 }
1252 1158
1253 c = (int)cfp->channel;
1254
1255 if (c < 0)
1256 return -EINVAL;
1257
1258 fwrq->e = 0; 1159 fwrq->e = 0;
1259 fwrq->m = c; 1160 fwrq->m = (int) cfp->channel;
1260 } 1161 }
1261 1162
1262 /* 1163 /* Setting by channel number */
1263 * Setting by channel number
1264 */
1265 if (fwrq->m > 1000 || fwrq->e > 0) { 1164 if (fwrq->m > 1000 || fwrq->e > 0) {
1266 rc = -EOPNOTSUPP; 1165 goto out;
1267 } else { 1166 }
1268 int channel = fwrq->m;
1269 1167
1270 cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, channel); 1168 cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, fwrq->m);
1271 if (!cfp) { 1169 if (!cfp) {
1272 rc = -EINVAL; 1170 goto out;
1273 } else {
1274 if (adapter->mode == IW_MODE_ADHOC) {
1275 rc = changeadhocchannel(priv, channel);
1276 /* If station is WEP enabled, send the
1277 * command to set WEP in firmware
1278 */
1279 if (adapter->secinfo.wep_enabled) {
1280 lbs_deb_wext("set_freq: WEP enabled\n");
1281 ret = libertas_prepare_and_send_command(priv,
1282 cmd_802_11_set_wep,
1283 cmd_act_add,
1284 cmd_option_waitforrsp,
1285 0,
1286 NULL);
1287
1288 if (ret) {
1289 rc = ret;
1290 goto out;
1291 }
1292
1293 adapter->currentpacketfilter |=
1294 cmd_act_mac_wep_enable;
1295
1296 libertas_set_mac_packet_filter(priv);
1297 }
1298 } else {
1299 rc = -EOPNOTSUPP;
1300 }
1301 }
1302 } 1171 }
1303 1172
1173 assoc_req->channel = fwrq->m;
1174 ret = 0;
1175
1304out: 1176out:
1305 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", rc); 1177 if (ret == 0) {
1306 return rc; 1178 set_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags);
1179 wlan_postpone_association_work(priv);
1180 } else {
1181 wlan_cancel_association_work(priv);
1182 }
1183 mutex_unlock(&adapter->lock);
1184
1185 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1186 return ret;
1307} 1187}
1308 1188
1309/** 1189/**