aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2011-08-30 14:57:52 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2011-08-31 03:13:00 -0400
commit9a5b13182cc10d693c55a5c02d753e54514b9bfc (patch)
tree8f8e42821b908d519bb587181cfe5a889b5dd92e
parent3c774bbab78435e349de2c88fc6e054716f8f2ea (diff)
ath6kl: Delay initial group key setup in AP mode
The target is not ready to accept addkey commands until the connect event has been delivered, so delay these operations for the initial GTK. In addition, properly set interface connected and mark netdev ready when the AP mode setup has been completed. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c31
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h25
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c36
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c4
4 files changed, 60 insertions, 36 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 4752a76e13cd..faefc23750d3 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -888,6 +888,26 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
888 key_usage, key->seq_len); 888 key_usage, key->seq_len);
889 889
890 ar->def_txkey_index = key_index; 890 ar->def_txkey_index = key_index;
891
892 if (ar->nw_type == AP_NETWORK && !pairwise &&
893 (key_type == TKIP_CRYPT || key_type == AES_CRYPT) && params) {
894 ar->ap_mode_bkey.valid = true;
895 ar->ap_mode_bkey.key_index = key_index;
896 ar->ap_mode_bkey.key_type = key_type;
897 ar->ap_mode_bkey.key_len = key->key_len;
898 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
899 if (!test_bit(CONNECTED, &ar->flag)) {
900 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
901 "key configuration until AP mode has been "
902 "started\n");
903 /*
904 * The key will be set in ath6kl_connect_ap_mode() once
905 * the connected event is received from the target.
906 */
907 return 0;
908 }
909 }
910
891 status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index, 911 status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
892 key_type, key_usage, key->key_len, 912 key_type, key_usage, key->key_len,
893 key->seq, key->key, KEY_OP_INIT_VAL, 913 key->seq, key->key, KEY_OP_INIT_VAL,
@@ -997,6 +1017,9 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
997 if (ar->prwise_crypto == WEP_CRYPT) 1017 if (ar->prwise_crypto == WEP_CRYPT)
998 key_usage |= TX_USAGE; 1018 key_usage |= TX_USAGE;
999 1019
1020 if (ar->nw_type == AP_NETWORK && !test_bit(CONNECTED, &ar->flag))
1021 return 0; /* Delay until AP mode has been started */
1022
1000 status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index, 1023 status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
1001 ar->prwise_crypto, key_usage, 1024 ar->prwise_crypto, key_usage,
1002 key->key_len, key->seq, key->key, 1025 key->key_len, key->seq, key->key,
@@ -1495,6 +1518,8 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
1495 if (!add) 1518 if (!add)
1496 return 0; 1519 return 0;
1497 1520
1521 ar->ap_mode_bkey.valid = false;
1522
1498 /* TODO: 1523 /* TODO:
1499 * info->interval 1524 * info->interval
1500 * info->dtim_period 1525 * info->dtim_period
@@ -1580,7 +1605,11 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
1580 p.dot11_auth_mode = ar->dot11_auth_mode; 1605 p.dot11_auth_mode = ar->dot11_auth_mode;
1581 p.ch = cpu_to_le16(ar->next_chan); 1606 p.ch = cpu_to_le16(ar->next_chan);
1582 1607
1583 return ath6kl_wmi_ap_profile_commit(ar->wmi, &p); 1608 res = ath6kl_wmi_ap_profile_commit(ar->wmi, &p);
1609 if (res < 0)
1610 return res;
1611
1612 return 0;
1584} 1613}
1585 1614
1586static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev, 1615static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev,
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 00d0add2ab46..f0b1dff1ce09 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -335,26 +335,13 @@ struct ath6kl_mbox_info {
335#define ATH6KL_KEY_RECV 0x02 335#define ATH6KL_KEY_RECV 0x02
336#define ATH6KL_KEY_DEFAULT 0x80 /* default xmit key */ 336#define ATH6KL_KEY_DEFAULT 0x80 /* default xmit key */
337 337
338/* 338/* Initial group key for AP mode */
339 * WPA/RSN get/set key request. Specify the key/cipher
340 * type and whether the key is to be used for sending and/or
341 * receiving. The key index should be set only when working
342 * with global keys (use IEEE80211_KEYIX_NONE for ``no index'').
343 * Otherwise a unicast/pairwise key is specified by the bssid
344 * (on a station) or mac address (on an ap). They key length
345 * must include any MIC key data; otherwise it should be no
346 * more than ATH6KL_KEYBUF_SIZE.
347 */
348struct ath6kl_req_key { 339struct ath6kl_req_key {
349 u8 ik_type; /* key/cipher type */ 340 bool valid;
350 u8 ik_pad; 341 u8 key_index;
351 u16 ik_keyix; /* key index */ 342 int key_type;
352 u8 ik_keylen; /* key length in bytes */ 343 u8 key[WLAN_MAX_KEY_LEN];
353 u8 ik_flags; 344 u8 key_len;
354 u8 ik_macaddr[ETH_ALEN];
355 u64 ik_keyrsc; /* key receive sequence counter */
356 u64 ik_keytsc; /* key transmit sequence counter */
357 u8 ik_keydata[ATH6KL_KEYBUF_SIZE + ATH6KL_MICBUF_SIZE];
358}; 345};
359 346
360/* Flag info */ 347/* Flag info */
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 89e29ead254f..a19caecdfdeb 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -437,11 +437,15 @@ static void ath6kl_connect_ap_mode(struct ath6kl *ar, u16 channel, u8 *bssid,
437 size_t ies_len = 0; 437 size_t ies_len = 0;
438 struct station_info sinfo; 438 struct station_info sinfo;
439 struct ath6kl_req_key *ik; 439 struct ath6kl_req_key *ik;
440 enum crypto_type keyType = NONE_CRYPT; 440 int res;
441 u8 key_rsc[ATH6KL_KEY_SEQ_LEN];
441 442
442 if (memcmp(dev->dev_addr, bssid, ETH_ALEN) == 0) { 443 if (memcmp(dev->dev_addr, bssid, ETH_ALEN) == 0) {
443 ik = &ar->ap_mode_bkey; 444 ik = &ar->ap_mode_bkey;
444 445
446 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "AP mode started on %u MHz\n",
447 channel);
448
445 switch (ar->auth_mode) { 449 switch (ar->auth_mode) {
446 case NONE_AUTH: 450 case NONE_AUTH:
447 if (ar->prwise_crypto == WEP_CRYPT) 451 if (ar->prwise_crypto == WEP_CRYPT)
@@ -450,26 +454,26 @@ static void ath6kl_connect_ap_mode(struct ath6kl *ar, u16 channel, u8 *bssid,
450 case WPA_PSK_AUTH: 454 case WPA_PSK_AUTH:
451 case WPA2_PSK_AUTH: 455 case WPA2_PSK_AUTH:
452 case (WPA_PSK_AUTH|WPA2_PSK_AUTH): 456 case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
453 switch (ik->ik_type) { 457 if (!ik->valid)
454 case ATH6KL_CIPHER_TKIP:
455 keyType = TKIP_CRYPT;
456 break;
457 case ATH6KL_CIPHER_AES_CCM:
458 keyType = AES_CRYPT;
459 break; 458 break;
460 default: 459
461 goto skip_key; 460 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed addkey for "
461 "the initial group key for AP mode\n");
462 memset(key_rsc, 0, sizeof(key_rsc));
463 res = ath6kl_wmi_addkey_cmd(
464 ar->wmi, ik->key_index, ik->key_type,
465 GROUP_USAGE, ik->key_len, key_rsc, ik->key,
466 KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG);
467 if (res) {
468 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed "
469 "addkey failed: %d\n", res);
462 } 470 }
463 ath6kl_wmi_addkey_cmd(ar->wmi, ik->ik_keyix, keyType,
464 GROUP_USAGE, ik->ik_keylen,
465 (u8 *)&ik->ik_keyrsc,
466 ik->ik_keydata,
467 KEY_OP_INIT_VAL, ik->ik_macaddr,
468 SYNC_BOTH_WMIFLAG);
469 break; 471 break;
470 } 472 }
471skip_key: 473
474 ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
472 set_bit(CONNECTED, &ar->flag); 475 set_bit(CONNECTED, &ar->flag);
476 netif_carrier_on(ar->net_dev);
473 return; 477 return;
474 } 478 }
475 479
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 0114a7136977..d587f84b41cf 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -1764,6 +1764,10 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,
1764 struct wmi_add_cipher_key_cmd *cmd; 1764 struct wmi_add_cipher_key_cmd *cmd;
1765 int ret; 1765 int ret;
1766 1766
1767 ath6kl_dbg(ATH6KL_DBG_WMI, "addkey cmd: key_index=%u key_type=%d "
1768 "key_usage=%d key_len=%d key_op_ctrl=%d\n",
1769 key_index, key_type, key_usage, key_len, key_op_ctrl);
1770
1767 if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) || 1771 if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) ||
1768 (key_material == NULL)) 1772 (key_material == NULL))
1769 return -EINVAL; 1773 return -EINVAL;