diff options
Diffstat (limited to 'drivers/net/wireless/libertas/assoc.c')
-rw-r--r-- | drivers/net/wireless/libertas/assoc.c | 134 |
1 files changed, 75 insertions, 59 deletions
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index 75c67c9d1178..d004170ec417 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c | |||
@@ -19,8 +19,9 @@ static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) = | |||
19 | static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) = | 19 | static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) = |
20 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | 20 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
21 | 21 | ||
22 | /* The firmware needs certain bits masked out of the beacon-derviced capability | 22 | /* The firmware needs the following bits masked out of the beacon-derived |
23 | * field when associating/joining to BSSs. | 23 | * capability field when associating/joining to a BSS: |
24 | * 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused) | ||
24 | */ | 25 | */ |
25 | #define CAPINFO_MASK (~(0xda00)) | 26 | #define CAPINFO_MASK (~(0xda00)) |
26 | 27 | ||
@@ -102,6 +103,52 @@ static void lbs_set_basic_rate_flags(u8 *rates, size_t len) | |||
102 | } | 103 | } |
103 | 104 | ||
104 | 105 | ||
106 | static u8 iw_auth_to_ieee_auth(u8 auth) | ||
107 | { | ||
108 | if (auth == IW_AUTH_ALG_OPEN_SYSTEM) | ||
109 | return 0x00; | ||
110 | else if (auth == IW_AUTH_ALG_SHARED_KEY) | ||
111 | return 0x01; | ||
112 | else if (auth == IW_AUTH_ALG_LEAP) | ||
113 | return 0x80; | ||
114 | |||
115 | lbs_deb_join("%s: invalid auth alg 0x%X\n", __func__, auth); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * @brief This function prepares the authenticate command. AUTHENTICATE only | ||
121 | * sets the authentication suite for future associations, as the firmware | ||
122 | * handles authentication internally during the ASSOCIATE command. | ||
123 | * | ||
124 | * @param priv A pointer to struct lbs_private structure | ||
125 | * @param bssid The peer BSSID with which to authenticate | ||
126 | * @param auth The authentication mode to use (from wireless.h) | ||
127 | * | ||
128 | * @return 0 or -1 | ||
129 | */ | ||
130 | static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth) | ||
131 | { | ||
132 | struct cmd_ds_802_11_authenticate cmd; | ||
133 | int ret = -1; | ||
134 | DECLARE_MAC_BUF(mac); | ||
135 | |||
136 | lbs_deb_enter(LBS_DEB_JOIN); | ||
137 | |||
138 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||
139 | memcpy(cmd.bssid, bssid, ETH_ALEN); | ||
140 | |||
141 | cmd.authtype = iw_auth_to_ieee_auth(auth); | ||
142 | |||
143 | lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n", | ||
144 | print_mac(mac, bssid), cmd.authtype); | ||
145 | |||
146 | ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd); | ||
147 | |||
148 | lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); | ||
149 | return ret; | ||
150 | } | ||
151 | |||
105 | /** | 152 | /** |
106 | * @brief Associate to a specific BSS discovered in a scan | 153 | * @brief Associate to a specific BSS discovered in a scan |
107 | * | 154 | * |
@@ -118,11 +165,15 @@ static int lbs_associate(struct lbs_private *priv, | |||
118 | 165 | ||
119 | lbs_deb_enter(LBS_DEB_ASSOC); | 166 | lbs_deb_enter(LBS_DEB_ASSOC); |
120 | 167 | ||
121 | ret = lbs_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE, | 168 | /* FW v9 and higher indicate authentication suites as a TLV in the |
122 | 0, CMD_OPTION_WAITFORRSP, | 169 | * association command, not as a separate authentication command. |
123 | 0, assoc_req->bss.bssid); | 170 | */ |
124 | if (ret) | 171 | if (priv->fwrelease < 0x09000000) { |
125 | goto out; | 172 | ret = lbs_set_authentication(priv, assoc_req->bss.bssid, |
173 | priv->secinfo.auth_mode); | ||
174 | if (ret) | ||
175 | goto out; | ||
176 | } | ||
126 | 177 | ||
127 | /* Use short preamble only when both the BSS and firmware support it */ | 178 | /* Use short preamble only when both the BSS and firmware support it */ |
128 | if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && | 179 | if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && |
@@ -1466,57 +1517,6 @@ struct assoc_request *lbs_get_association_request(struct lbs_private *priv) | |||
1466 | 1517 | ||
1467 | 1518 | ||
1468 | /** | 1519 | /** |
1469 | * @brief This function prepares command of authenticate. | ||
1470 | * | ||
1471 | * @param priv A pointer to struct lbs_private structure | ||
1472 | * @param cmd A pointer to cmd_ds_command structure | ||
1473 | * @param pdata_buf Void cast of pointer to a BSSID to authenticate with | ||
1474 | * | ||
1475 | * @return 0 or -1 | ||
1476 | */ | ||
1477 | int lbs_cmd_80211_authenticate(struct lbs_private *priv, | ||
1478 | struct cmd_ds_command *cmd, | ||
1479 | void *pdata_buf) | ||
1480 | { | ||
1481 | struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth; | ||
1482 | int ret = -1; | ||
1483 | u8 *bssid = pdata_buf; | ||
1484 | |||
1485 | lbs_deb_enter(LBS_DEB_JOIN); | ||
1486 | |||
1487 | cmd->command = cpu_to_le16(CMD_802_11_AUTHENTICATE); | ||
1488 | cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate) | ||
1489 | + S_DS_GEN); | ||
1490 | |||
1491 | /* translate auth mode to 802.11 defined wire value */ | ||
1492 | switch (priv->secinfo.auth_mode) { | ||
1493 | case IW_AUTH_ALG_OPEN_SYSTEM: | ||
1494 | pauthenticate->authtype = 0x00; | ||
1495 | break; | ||
1496 | case IW_AUTH_ALG_SHARED_KEY: | ||
1497 | pauthenticate->authtype = 0x01; | ||
1498 | break; | ||
1499 | case IW_AUTH_ALG_LEAP: | ||
1500 | pauthenticate->authtype = 0x80; | ||
1501 | break; | ||
1502 | default: | ||
1503 | lbs_deb_join("AUTH_CMD: invalid auth alg 0x%X\n", | ||
1504 | priv->secinfo.auth_mode); | ||
1505 | goto out; | ||
1506 | } | ||
1507 | |||
1508 | memcpy(pauthenticate->macaddr, bssid, ETH_ALEN); | ||
1509 | |||
1510 | lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n", | ||
1511 | bssid, pauthenticate->authtype); | ||
1512 | ret = 0; | ||
1513 | |||
1514 | out: | ||
1515 | lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); | ||
1516 | return ret; | ||
1517 | } | ||
1518 | |||
1519 | /** | ||
1520 | * @brief Deauthenticate from a specific BSS | 1520 | * @brief Deauthenticate from a specific BSS |
1521 | * | 1521 | * |
1522 | * @param priv A pointer to struct lbs_private structure | 1522 | * @param priv A pointer to struct lbs_private structure |
@@ -1557,12 +1557,13 @@ int lbs_cmd_80211_associate(struct lbs_private *priv, | |||
1557 | struct assoc_request *assoc_req = pdata_buf; | 1557 | struct assoc_request *assoc_req = pdata_buf; |
1558 | struct bss_descriptor *bss = &assoc_req->bss; | 1558 | struct bss_descriptor *bss = &assoc_req->bss; |
1559 | u8 *pos; | 1559 | u8 *pos; |
1560 | u16 tmpcap, tmplen; | 1560 | u16 tmpcap, tmplen, tmpauth; |
1561 | struct mrvl_ie_ssid_param_set *ssid; | 1561 | struct mrvl_ie_ssid_param_set *ssid; |
1562 | struct mrvl_ie_ds_param_set *ds; | 1562 | struct mrvl_ie_ds_param_set *ds; |
1563 | struct mrvl_ie_cf_param_set *cf; | 1563 | struct mrvl_ie_cf_param_set *cf; |
1564 | struct mrvl_ie_rates_param_set *rates; | 1564 | struct mrvl_ie_rates_param_set *rates; |
1565 | struct mrvl_ie_rsn_param_set *rsn; | 1565 | struct mrvl_ie_rsn_param_set *rsn; |
1566 | struct mrvl_ie_auth_type *auth; | ||
1566 | 1567 | ||
1567 | lbs_deb_enter(LBS_DEB_ASSOC); | 1568 | lbs_deb_enter(LBS_DEB_ASSOC); |
1568 | 1569 | ||
@@ -1627,6 +1628,21 @@ int lbs_cmd_80211_associate(struct lbs_private *priv, | |||
1627 | */ | 1628 | */ |
1628 | lbs_set_basic_rate_flags(rates->rates, tmplen); | 1629 | lbs_set_basic_rate_flags(rates->rates, tmplen); |
1629 | 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 | |||
1630 | if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { | 1646 | if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { |
1631 | rsn = (struct mrvl_ie_rsn_param_set *) pos; | 1647 | rsn = (struct mrvl_ie_rsn_param_set *) pos; |
1632 | /* WPA_IE or WPA2_IE */ | 1648 | /* WPA_IE or WPA2_IE */ |