aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2009-05-22 20:07:14 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-06-03 14:05:09 -0400
commit822ac03a07cc9e714727a6d49ea050b92483f82a (patch)
treeef8f5c187a29980c7737605996212d4220d988e7 /drivers/net/wireless
parentbe0d76e48f6cc1f8b01eeb5efbeea41f2efdab49 (diff)
libertas: convert CMD_802_11_ASSOCIATE to a direct command
Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/libertas/assoc.c627
-rw-r--r--drivers/net/wireless/libertas/assoc.h13
-rw-r--r--drivers/net/wireless/libertas/cmd.c5
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c6
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h22
-rw-r--r--drivers/net/wireless/libertas/types.h7
6 files changed, 331 insertions, 349 deletions
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index d004170ec417..cb737207d208 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -12,8 +12,6 @@
12#include "scan.h" 12#include "scan.h"
13#include "cmd.h" 13#include "cmd.h"
14 14
15static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp);
16
17static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) = 15static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) =
18 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 16 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
19static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) = 17static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) =
@@ -149,6 +147,249 @@ static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth
149 return ret; 147 return ret;
150} 148}
151 149
150
151static int lbs_assoc_post(struct lbs_private *priv,
152 struct cmd_ds_802_11_associate_response *resp)
153{
154 int ret = 0;
155 union iwreq_data wrqu;
156 struct bss_descriptor *bss;
157 u16 status_code;
158
159 lbs_deb_enter(LBS_DEB_ASSOC);
160
161 if (!priv->in_progress_assoc_req) {
162 lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
163 ret = -1;
164 goto done;
165 }
166 bss = &priv->in_progress_assoc_req->bss;
167
168 /*
169 * Older FW versions map the IEEE 802.11 Status Code in the association
170 * response to the following values returned in resp->statuscode:
171 *
172 * IEEE Status Code Marvell Status Code
173 * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
174 * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
175 * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
176 * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
177 * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
178 * others -> 0x0003 ASSOC_RESULT_REFUSED
179 *
180 * Other response codes:
181 * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
182 * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
183 * association response from the AP)
184 */
185
186 status_code = le16_to_cpu(resp->statuscode);
187 if (priv->fwrelease < 0x09000000) {
188 switch (status_code) {
189 case 0x00:
190 break;
191 case 0x01:
192 lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
193 break;
194 case 0x02:
195 lbs_deb_assoc("ASSOC_RESP: internal timer "
196 "expired while waiting for the AP\n");
197 break;
198 case 0x03:
199 lbs_deb_assoc("ASSOC_RESP: association "
200 "refused by AP\n");
201 break;
202 case 0x04:
203 lbs_deb_assoc("ASSOC_RESP: authentication "
204 "refused by AP\n");
205 break;
206 default:
207 lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
208 " unknown\n", status_code);
209 break;
210 }
211 } else {
212 /* v9+ returns the AP's association response */
213 lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x\n", status_code);
214 }
215
216 if (status_code) {
217 lbs_mac_event_disconnected(priv);
218 ret = -1;
219 goto done;
220 }
221
222 lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP",
223 (void *) (resp + sizeof (resp->hdr)),
224 le16_to_cpu(resp->hdr.size) - sizeof (resp->hdr));
225
226 /* Send a Media Connected event, according to the Spec */
227 priv->connect_status = LBS_CONNECTED;
228
229 /* Update current SSID and BSSID */
230 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
231 priv->curbssparams.ssid_len = bss->ssid_len;
232 memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
233
234 priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
235 priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
236
237 memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
238 memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
239 priv->nextSNRNF = 0;
240 priv->numSNRNF = 0;
241
242 netif_carrier_on(priv->dev);
243 if (!priv->tx_pending_len)
244 netif_wake_queue(priv->dev);
245
246 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
247 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
248 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
249
250done:
251 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
252 return ret;
253}
254
255/**
256 * @brief This function prepares an association-class command.
257 *
258 * @param priv A pointer to struct lbs_private structure
259 * @param assoc_req The association request describing the BSS to associate
260 * or reassociate with
261 * @param command The actual command, either CMD_802_11_ASSOCIATE or
262 * CMD_802_11_REASSOCIATE
263 *
264 * @return 0 or -1
265 */
266static int lbs_associate(struct lbs_private *priv,
267 struct assoc_request *assoc_req,
268 u16 command)
269{
270 struct cmd_ds_802_11_associate cmd;
271 int ret = 0;
272 struct bss_descriptor *bss = &assoc_req->bss;
273 u8 *pos = &(cmd.iebuf[0]);
274 u16 tmpcap, tmplen, tmpauth;
275 struct mrvl_ie_ssid_param_set *ssid;
276 struct mrvl_ie_ds_param_set *ds;
277 struct mrvl_ie_cf_param_set *cf;
278 struct mrvl_ie_rates_param_set *rates;
279 struct mrvl_ie_rsn_param_set *rsn;
280 struct mrvl_ie_auth_type *auth;
281
282 lbs_deb_enter(LBS_DEB_ASSOC);
283
284 BUG_ON((command != CMD_802_11_ASSOCIATE) &&
285 (command != CMD_802_11_REASSOCIATE));
286
287 memset(&cmd, 0, sizeof(cmd));
288 cmd.hdr.command = cpu_to_le16(command);
289
290 /* Fill in static fields */
291 memcpy(cmd.bssid, bss->bssid, ETH_ALEN);
292 cmd.listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
293
294 /* Capability info */
295 tmpcap = (bss->capability & CAPINFO_MASK);
296 if (bss->mode == IW_MODE_INFRA)
297 tmpcap |= WLAN_CAPABILITY_ESS;
298 cmd.capability = cpu_to_le16(tmpcap);
299 lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
300
301 /* SSID */
302 ssid = (struct mrvl_ie_ssid_param_set *) pos;
303 ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
304 tmplen = bss->ssid_len;
305 ssid->header.len = cpu_to_le16(tmplen);
306 memcpy(ssid->ssid, bss->ssid, tmplen);
307 pos += sizeof(ssid->header) + tmplen;
308
309 ds = (struct mrvl_ie_ds_param_set *) pos;
310 ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
311 ds->header.len = cpu_to_le16(1);
312 ds->channel = bss->phy.ds.channel;
313 pos += sizeof(ds->header) + 1;
314
315 cf = (struct mrvl_ie_cf_param_set *) pos;
316 cf->header.type = cpu_to_le16(TLV_TYPE_CF);
317 tmplen = sizeof(*cf) - sizeof (cf->header);
318 cf->header.len = cpu_to_le16(tmplen);
319 /* IE payload should be zeroed, firmware fills it in for us */
320 pos += sizeof(*cf);
321
322 rates = (struct mrvl_ie_rates_param_set *) pos;
323 rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
324 memcpy(&rates->rates, &bss->rates, MAX_RATES);
325 tmplen = MAX_RATES;
326 if (get_common_rates(priv, rates->rates, &tmplen)) {
327 ret = -1;
328 goto done;
329 }
330 pos += sizeof(rates->header) + tmplen;
331 rates->header.len = cpu_to_le16(tmplen);
332 lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
333
334 /* Copy the infra. association rates into Current BSS state structure */
335 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
336 memcpy(&priv->curbssparams.rates, &rates->rates, tmplen);
337
338 /* Set MSB on basic rates as the firmware requires, but _after_
339 * copying to current bss rates.
340 */
341 lbs_set_basic_rate_flags(rates->rates, tmplen);
342
343 /* Firmware v9+ indicate authentication suites as a TLV */
344 if (priv->fwrelease >= 0x09000000) {
345 DECLARE_MAC_BUF(mac);
346
347 auth = (struct mrvl_ie_auth_type *) pos;
348 auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
349 auth->header.len = cpu_to_le16(2);
350 tmpauth = iw_auth_to_ieee_auth(priv->secinfo.auth_mode);
351 auth->auth = cpu_to_le16(tmpauth);
352 pos += sizeof(auth->header) + 2;
353
354 lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
355 print_mac(mac, bss->bssid), priv->secinfo.auth_mode);
356 }
357
358 /* WPA/WPA2 IEs */
359 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
360 rsn = (struct mrvl_ie_rsn_param_set *) pos;
361 /* WPA_IE or WPA2_IE */
362 rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
363 tmplen = (u16) assoc_req->wpa_ie[1];
364 rsn->header.len = cpu_to_le16(tmplen);
365 memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
366 lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: WPA/RSN IE", (u8 *) rsn,
367 sizeof(rsn->header) + tmplen);
368 pos += sizeof(rsn->header) + tmplen;
369 }
370
371 cmd.hdr.size = cpu_to_le16((sizeof(cmd) - sizeof(cmd.iebuf)) +
372 (u16)(pos - (u8 *) &cmd.iebuf));
373
374 /* update curbssparams */
375 priv->curbssparams.channel = bss->phy.ds.channel;
376
377 if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
378 ret = -1;
379 goto done;
380 }
381
382 ret = lbs_cmd_with_response(priv, command, &cmd);
383 if (ret == 0) {
384 ret = lbs_assoc_post(priv,
385 (struct cmd_ds_802_11_associate_response *) &cmd);
386 }
387
388done:
389 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
390 return ret;
391}
392
152/** 393/**
153 * @brief Associate to a specific BSS discovered in a scan 394 * @brief Associate to a specific BSS discovered in a scan
154 * 395 *
@@ -157,7 +398,7 @@ static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth
157 * 398 *
158 * @return 0-success, otherwise fail 399 * @return 0-success, otherwise fail
159 */ 400 */
160static int lbs_associate(struct lbs_private *priv, 401static int lbs_try_associate(struct lbs_private *priv,
161 struct assoc_request *assoc_req) 402 struct assoc_request *assoc_req)
162{ 403{
163 int ret; 404 int ret;
@@ -184,14 +425,78 @@ static int lbs_associate(struct lbs_private *priv,
184 if (ret) 425 if (ret)
185 goto out; 426 goto out;
186 427
187 ret = lbs_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE, 428 ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE);
188 0, CMD_OPTION_WAITFORRSP, 0, assoc_req);
189 429
190out: 430out:
191 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 431 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
192 return ret; 432 return ret;
193} 433}
194 434
435static int lbs_adhoc_post(struct lbs_private *priv,
436 struct cmd_ds_802_11_ad_hoc_result *resp)
437{
438 int ret = 0;
439 u16 command = le16_to_cpu(resp->hdr.command);
440 u16 result = le16_to_cpu(resp->hdr.result);
441 union iwreq_data wrqu;
442 struct bss_descriptor *bss;
443 DECLARE_SSID_BUF(ssid);
444
445 lbs_deb_enter(LBS_DEB_JOIN);
446
447 if (!priv->in_progress_assoc_req) {
448 lbs_deb_join("ADHOC_RESP: no in-progress association "
449 "request\n");
450 ret = -1;
451 goto done;
452 }
453 bss = &priv->in_progress_assoc_req->bss;
454
455 /*
456 * Join result code 0 --> SUCCESS
457 */
458 if (result) {
459 lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result);
460 if (priv->connect_status == LBS_CONNECTED)
461 lbs_mac_event_disconnected(priv);
462 ret = -1;
463 goto done;
464 }
465
466 /* Send a Media Connected event, according to the Spec */
467 priv->connect_status = LBS_CONNECTED;
468
469 if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
470 /* Update the created network descriptor with the new BSSID */
471 memcpy(bss->bssid, resp->bssid, ETH_ALEN);
472 }
473
474 /* Set the BSSID from the joined/started descriptor */
475 memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
476
477 /* Set the new SSID to current SSID */
478 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
479 priv->curbssparams.ssid_len = bss->ssid_len;
480
481 netif_carrier_on(priv->dev);
482 if (!priv->tx_pending_len)
483 netif_wake_queue(priv->dev);
484
485 memset(&wrqu, 0, sizeof(wrqu));
486 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
487 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
488 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
489
490 lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n",
491 print_ssid(ssid, bss->ssid, bss->ssid_len),
492 priv->curbssparams.bssid,
493 priv->curbssparams.channel);
494
495done:
496 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
497 return ret;
498}
499
195/** 500/**
196 * @brief Join an adhoc network found in a previous scan 501 * @brief Join an adhoc network found in a previous scan
197 * 502 *
@@ -337,8 +642,10 @@ static int lbs_adhoc_join(struct lbs_private *priv,
337 } 642 }
338 643
339 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd); 644 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd);
340 if (ret == 0) 645 if (ret == 0) {
341 ret = lbs_adhoc_post(priv, (struct cmd_header *) &cmd); 646 ret = lbs_adhoc_post(priv,
647 (struct cmd_ds_802_11_ad_hoc_result *)&cmd);
648 }
342 649
343out: 650out:
344 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 651 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -445,7 +752,8 @@ static int lbs_adhoc_start(struct lbs_private *priv,
445 752
446 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd); 753 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd);
447 if (ret == 0) 754 if (ret == 0)
448 ret = lbs_adhoc_post(priv, (struct cmd_header *) &cmd); 755 ret = lbs_adhoc_post(priv,
756 (struct cmd_ds_802_11_ad_hoc_result *)&cmd);
449 757
450out: 758out:
451 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 759 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -770,7 +1078,7 @@ static int assoc_helper_essid(struct lbs_private *priv,
770 assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel); 1078 assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel);
771 if (bss != NULL) { 1079 if (bss != NULL) {
772 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); 1080 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
773 ret = lbs_associate(priv, assoc_req); 1081 ret = lbs_try_associate(priv, assoc_req);
774 } else { 1082 } else {
775 lbs_deb_assoc("SSID not found; cannot associate\n"); 1083 lbs_deb_assoc("SSID not found; cannot associate\n");
776 } 1084 }
@@ -822,8 +1130,9 @@ static int assoc_helper_bssid(struct lbs_private *priv,
822 1130
823 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); 1131 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
824 if (assoc_req->mode == IW_MODE_INFRA) { 1132 if (assoc_req->mode == IW_MODE_INFRA) {
825 ret = lbs_associate(priv, assoc_req); 1133 ret = lbs_try_associate(priv, assoc_req);
826 lbs_deb_assoc("ASSOC: lbs_associate(bssid) returned %d\n", ret); 1134 lbs_deb_assoc("ASSOC: lbs_try_associate(bssid) returned %d\n",
1135 ret);
827 } else if (assoc_req->mode == IW_MODE_ADHOC) { 1136 } else if (assoc_req->mode == IW_MODE_ADHOC) {
828 lbs_adhoc_join(priv, assoc_req); 1137 lbs_adhoc_join(priv, assoc_req);
829 } 1138 }
@@ -1549,299 +1858,3 @@ int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, u8 bssid[ETH_ALEN],
1549 return ret; 1858 return ret;
1550} 1859}
1551 1860
1552int lbs_cmd_80211_associate(struct lbs_private *priv,
1553 struct cmd_ds_command *cmd, void *pdata_buf)
1554{
1555 struct cmd_ds_802_11_associate *passo = &cmd->params.associate;
1556 int ret = 0;
1557 struct assoc_request *assoc_req = pdata_buf;
1558 struct bss_descriptor *bss = &assoc_req->bss;
1559 u8 *pos;
1560 u16 tmpcap, tmplen, tmpauth;
1561 struct mrvl_ie_ssid_param_set *ssid;
1562 struct mrvl_ie_ds_param_set *ds;
1563 struct mrvl_ie_cf_param_set *cf;
1564 struct mrvl_ie_rates_param_set *rates;
1565 struct mrvl_ie_rsn_param_set *rsn;
1566 struct mrvl_ie_auth_type *auth;
1567
1568 lbs_deb_enter(LBS_DEB_ASSOC);
1569
1570 pos = (u8 *) passo;
1571
1572 if (!priv) {
1573 ret = -1;
1574 goto done;
1575 }
1576
1577 cmd->command = cpu_to_le16(CMD_802_11_ASSOCIATE);
1578
1579 memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr));
1580 pos += sizeof(passo->peerstaaddr);
1581
1582 /* set the listen interval */
1583 passo->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
1584
1585 pos += sizeof(passo->capability);
1586 pos += sizeof(passo->listeninterval);
1587 pos += sizeof(passo->bcnperiod);
1588 pos += sizeof(passo->dtimperiod);
1589
1590 ssid = (struct mrvl_ie_ssid_param_set *) pos;
1591 ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
1592 tmplen = bss->ssid_len;
1593 ssid->header.len = cpu_to_le16(tmplen);
1594 memcpy(ssid->ssid, bss->ssid, tmplen);
1595 pos += sizeof(ssid->header) + tmplen;
1596
1597 ds = (struct mrvl_ie_ds_param_set *) pos;
1598 ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
1599 ds->header.len = cpu_to_le16(1);
1600 ds->channel = bss->phy.ds.channel;
1601 pos += sizeof(ds->header) + 1;
1602
1603 cf = (struct mrvl_ie_cf_param_set *) pos;
1604 cf->header.type = cpu_to_le16(TLV_TYPE_CF);
1605 tmplen = sizeof(*cf) - sizeof (cf->header);
1606 cf->header.len = cpu_to_le16(tmplen);
1607 /* IE payload should be zeroed, firmware fills it in for us */
1608 pos += sizeof(*cf);
1609
1610 rates = (struct mrvl_ie_rates_param_set *) pos;
1611 rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
1612 memcpy(&rates->rates, &bss->rates, MAX_RATES);
1613 tmplen = MAX_RATES;
1614 if (get_common_rates(priv, rates->rates, &tmplen)) {
1615 ret = -1;
1616 goto done;
1617 }
1618 pos += sizeof(rates->header) + tmplen;
1619 rates->header.len = cpu_to_le16(tmplen);
1620 lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
1621
1622 /* Copy the infra. association rates into Current BSS state structure */
1623 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
1624 memcpy(&priv->curbssparams.rates, &rates->rates, tmplen);
1625
1626 /* Set MSB on basic rates as the firmware requires, but _after_
1627 * copying to current bss rates.
1628 */
1629 lbs_set_basic_rate_flags(rates->rates, tmplen);
1630
1631 /* Firmware v9+ indicate authentication suites as a TLV */
1632 if (priv->fwrelease >= 0x09000000) {
1633 DECLARE_MAC_BUF(mac);
1634
1635 auth = (struct mrvl_ie_auth_type *) pos;
1636 auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
1637 auth->header.len = cpu_to_le16(2);
1638 tmpauth = iw_auth_to_ieee_auth(priv->secinfo.auth_mode);
1639 auth->auth = cpu_to_le16(tmpauth);
1640 pos += sizeof(auth->header) + 2;
1641
1642 lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
1643 print_mac(mac, bss->bssid), priv->secinfo.auth_mode);
1644 }
1645
1646 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
1647 rsn = (struct mrvl_ie_rsn_param_set *) pos;
1648 /* WPA_IE or WPA2_IE */
1649 rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
1650 tmplen = (u16) assoc_req->wpa_ie[1];
1651 rsn->header.len = cpu_to_le16(tmplen);
1652 memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
1653 lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: RSN IE", (u8 *) rsn,
1654 sizeof(rsn->header) + tmplen);
1655 pos += sizeof(rsn->header) + tmplen;
1656 }
1657
1658 /* update curbssparams */
1659 priv->curbssparams.channel = bss->phy.ds.channel;
1660
1661 if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
1662 ret = -1;
1663 goto done;
1664 }
1665
1666 cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN);
1667
1668 /* set the capability info */
1669 tmpcap = (bss->capability & CAPINFO_MASK);
1670 if (bss->mode == IW_MODE_INFRA)
1671 tmpcap |= WLAN_CAPABILITY_ESS;
1672 passo->capability = cpu_to_le16(tmpcap);
1673 lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
1674
1675done:
1676 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1677 return ret;
1678}
1679
1680int lbs_ret_80211_associate(struct lbs_private *priv,
1681 struct cmd_ds_command *resp)
1682{
1683 int ret = 0;
1684 union iwreq_data wrqu;
1685 struct ieee_assoc_response *passocrsp;
1686 struct bss_descriptor *bss;
1687 u16 status_code;
1688
1689 lbs_deb_enter(LBS_DEB_ASSOC);
1690
1691 if (!priv->in_progress_assoc_req) {
1692 lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
1693 ret = -1;
1694 goto done;
1695 }
1696 bss = &priv->in_progress_assoc_req->bss;
1697
1698 passocrsp = (struct ieee_assoc_response *) &resp->params;
1699
1700 /*
1701 * Older FW versions map the IEEE 802.11 Status Code in the association
1702 * response to the following values returned in passocrsp->statuscode:
1703 *
1704 * IEEE Status Code Marvell Status Code
1705 * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
1706 * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1707 * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1708 * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1709 * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1710 * others -> 0x0003 ASSOC_RESULT_REFUSED
1711 *
1712 * Other response codes:
1713 * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
1714 * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
1715 * association response from the AP)
1716 */
1717
1718 status_code = le16_to_cpu(passocrsp->statuscode);
1719 switch (status_code) {
1720 case 0x00:
1721 break;
1722 case 0x01:
1723 lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
1724 break;
1725 case 0x02:
1726 lbs_deb_assoc("ASSOC_RESP: internal timer "
1727 "expired while waiting for the AP\n");
1728 break;
1729 case 0x03:
1730 lbs_deb_assoc("ASSOC_RESP: association "
1731 "refused by AP\n");
1732 break;
1733 case 0x04:
1734 lbs_deb_assoc("ASSOC_RESP: authentication "
1735 "refused by AP\n");
1736 break;
1737 default:
1738 lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
1739 " unknown\n", status_code);
1740 break;
1741 }
1742
1743 if (status_code) {
1744 lbs_mac_event_disconnected(priv);
1745 ret = -1;
1746 goto done;
1747 }
1748
1749 lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP", (void *)&resp->params,
1750 le16_to_cpu(resp->size) - S_DS_GEN);
1751
1752 /* Send a Media Connected event, according to the Spec */
1753 priv->connect_status = LBS_CONNECTED;
1754
1755 /* Update current SSID and BSSID */
1756 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
1757 priv->curbssparams.ssid_len = bss->ssid_len;
1758 memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
1759
1760 priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
1761 priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
1762
1763 memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
1764 memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
1765 priv->nextSNRNF = 0;
1766 priv->numSNRNF = 0;
1767
1768 netif_carrier_on(priv->dev);
1769 if (!priv->tx_pending_len)
1770 netif_wake_queue(priv->dev);
1771
1772 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
1773 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1774 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1775
1776done:
1777 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1778 return ret;
1779}
1780
1781static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp)
1782{
1783 int ret = 0;
1784 u16 command = le16_to_cpu(resp->command);
1785 u16 result = le16_to_cpu(resp->result);
1786 struct cmd_ds_802_11_ad_hoc_result *adhoc_resp;
1787 union iwreq_data wrqu;
1788 struct bss_descriptor *bss;
1789 DECLARE_SSID_BUF(ssid);
1790
1791 lbs_deb_enter(LBS_DEB_JOIN);
1792
1793 adhoc_resp = (struct cmd_ds_802_11_ad_hoc_result *) resp;
1794
1795 if (!priv->in_progress_assoc_req) {
1796 lbs_deb_join("ADHOC_RESP: no in-progress association "
1797 "request\n");
1798 ret = -1;
1799 goto done;
1800 }
1801 bss = &priv->in_progress_assoc_req->bss;
1802
1803 /*
1804 * Join result code 0 --> SUCCESS
1805 */
1806 if (result) {
1807 lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result);
1808 if (priv->connect_status == LBS_CONNECTED)
1809 lbs_mac_event_disconnected(priv);
1810 ret = -1;
1811 goto done;
1812 }
1813
1814 /* Send a Media Connected event, according to the Spec */
1815 priv->connect_status = LBS_CONNECTED;
1816
1817 if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
1818 /* Update the created network descriptor with the new BSSID */
1819 memcpy(bss->bssid, adhoc_resp->bssid, ETH_ALEN);
1820 }
1821
1822 /* Set the BSSID from the joined/started descriptor */
1823 memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
1824
1825 /* Set the new SSID to current SSID */
1826 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
1827 priv->curbssparams.ssid_len = bss->ssid_len;
1828
1829 netif_carrier_on(priv->dev);
1830 if (!priv->tx_pending_len)
1831 netif_wake_queue(priv->dev);
1832
1833 memset(&wrqu, 0, sizeof(wrqu));
1834 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
1835 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1836 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1837
1838 lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n",
1839 print_ssid(ssid, bss->ssid, bss->ssid_len),
1840 priv->curbssparams.bssid,
1841 priv->curbssparams.channel);
1842
1843done:
1844 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
1845 return ret;
1846}
1847
diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h
index 8b7336dd02a3..6e765e9f91a3 100644
--- a/drivers/net/wireless/libertas/assoc.h
+++ b/drivers/net/wireless/libertas/assoc.h
@@ -8,22 +8,9 @@
8void lbs_association_worker(struct work_struct *work); 8void lbs_association_worker(struct work_struct *work);
9struct assoc_request *lbs_get_association_request(struct lbs_private *priv); 9struct assoc_request *lbs_get_association_request(struct lbs_private *priv);
10 10
11struct cmd_ds_command;
12int lbs_cmd_80211_authenticate(struct lbs_private *priv,
13 struct cmd_ds_command *cmd,
14 void *pdata_buf);
15
16int lbs_adhoc_stop(struct lbs_private *priv); 11int lbs_adhoc_stop(struct lbs_private *priv);
17 12
18int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, 13int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
19 u8 bssid[ETH_ALEN], u16 reason); 14 u8 bssid[ETH_ALEN], u16 reason);
20int lbs_cmd_80211_associate(struct lbs_private *priv,
21 struct cmd_ds_command *cmd,
22 void *pdata_buf);
23
24int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
25 struct cmd_ds_command *resp);
26int lbs_ret_80211_associate(struct lbs_private *priv,
27 struct cmd_ds_command *resp);
28 15
29#endif /* _LBS_ASSOC_H */ 16#endif /* _LBS_ASSOC_H */
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index bd740fc00f94..01db705a38ec 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1414,11 +1414,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1414 ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action); 1414 ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action);
1415 break; 1415 break;
1416 1416
1417 case CMD_802_11_ASSOCIATE:
1418 case CMD_802_11_REASSOCIATE:
1419 ret = lbs_cmd_80211_associate(priv, cmdptr, pdata_buf);
1420 break;
1421
1422 case CMD_MAC_REG_ACCESS: 1417 case CMD_MAC_REG_ACCESS:
1423 case CMD_BBP_REG_ACCESS: 1418 case CMD_BBP_REG_ACCESS:
1424 case CMD_RF_REG_ACCESS: 1419 case CMD_RF_REG_ACCESS:
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index a830ecaf98de..14b3d562db09 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -210,12 +210,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
210 ret = lbs_ret_reg_access(priv, respcmd, resp); 210 ret = lbs_ret_reg_access(priv, respcmd, resp);
211 break; 211 break;
212 212
213 case CMD_RET_802_11_ASSOCIATE:
214 case CMD_RET(CMD_802_11_ASSOCIATE):
215 case CMD_RET(CMD_802_11_REASSOCIATE):
216 ret = lbs_ret_80211_associate(priv, resp);
217 break;
218
219 case CMD_RET(CMD_802_11_SET_AFC): 213 case CMD_RET(CMD_802_11_SET_AFC):
220 case CMD_RET(CMD_802_11_GET_AFC): 214 case CMD_RET(CMD_802_11_GET_AFC):
221 spin_lock_irqsave(&priv->driver_lock, flags); 215 spin_lock_irqsave(&priv->driver_lock, flags);
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index 4c930bd1b292..0a2e29140add 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -265,22 +265,23 @@ struct cmd_ds_802_11_deauthenticate {
265} __attribute__ ((packed)); 265} __attribute__ ((packed));
266 266
267struct cmd_ds_802_11_associate { 267struct cmd_ds_802_11_associate {
268 u8 peerstaaddr[6]; 268 struct cmd_header hdr;
269
270 u8 bssid[6];
269 __le16 capability; 271 __le16 capability;
270 __le16 listeninterval; 272 __le16 listeninterval;
271 __le16 bcnperiod; 273 __le16 bcnperiod;
272 u8 dtimperiod; 274 u8 dtimperiod;
273 275 u8 iebuf[512]; /* Enough for required and most optional IEs */
274#if 0
275 mrvlietypes_ssidparamset_t ssidParamSet;
276 mrvlietypes_phyparamset_t phyparamset;
277 mrvlietypes_ssparamset_t ssparamset;
278 mrvlietypes_ratesparamset_t ratesParamSet;
279#endif
280} __attribute__ ((packed)); 276} __attribute__ ((packed));
281 277
282struct cmd_ds_802_11_associate_rsp { 278struct cmd_ds_802_11_associate_response {
283 struct ieee_assoc_response response; 279 struct cmd_header hdr;
280
281 __le16 capability;
282 __le16 statuscode;
283 __le16 aid;
284 u8 iebuf[512];
284} __attribute__ ((packed)); 285} __attribute__ ((packed));
285 286
286struct cmd_ds_802_11_set_wep { 287struct cmd_ds_802_11_set_wep {
@@ -771,7 +772,6 @@ struct cmd_ds_command {
771 /* command Body */ 772 /* command Body */
772 union { 773 union {
773 struct cmd_ds_802_11_ps_mode psmode; 774 struct cmd_ds_802_11_ps_mode psmode;
774 struct cmd_ds_802_11_associate associate;
775 struct cmd_ds_802_11_get_stat gstat; 775 struct cmd_ds_802_11_get_stat gstat;
776 struct cmd_ds_802_3_get_stat gstat_8023; 776 struct cmd_ds_802_3_get_stat gstat_8023;
777 struct cmd_ds_802_11_rf_antenna rant; 777 struct cmd_ds_802_11_rf_antenna rant;
diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h
index 4ad3bb6bc2c1..99905df65b25 100644
--- a/drivers/net/wireless/libertas/types.h
+++ b/drivers/net/wireless/libertas/types.h
@@ -54,13 +54,6 @@ union ieee_phy_param_set {
54 struct ieee_ie_ds_param_set ds; 54 struct ieee_ie_ds_param_set ds;
55} __attribute__ ((packed)); 55} __attribute__ ((packed));
56 56
57struct ieee_assoc_response {
58 __le16 capability;
59 __le16 statuscode;
60 __le16 aid;
61 u8 iebuffer[1];
62} __attribute__ ((packed));
63
64/** TLV type ID definition */ 57/** TLV type ID definition */
65#define PROPRIETARY_TLV_BASE_ID 0x0100 58#define PROPRIETARY_TLV_BASE_ID 0x0100
66 59