diff options
-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 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 | ||
165 | static 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 | |||
173 | static 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 | |||
222 | done: | ||
223 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | ||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | |||
161 | static int assoc_helper_wep_keys(wlan_private *priv, | 228 | static 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 | ||
160 | static 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 | |||
177 | static 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 | |||
189 | static 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 | |||
253 | out: | ||
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: | |||
1228 | static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info, | 1131 | static 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 | |||
1304 | out: | 1176 | out: |
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 | /** |