diff options
Diffstat (limited to 'drivers/net/wireless')
4 files changed, 219 insertions, 97 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 55e489d2147d..9bb23b3854aa 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h | |||
@@ -658,6 +658,8 @@ extern const struct bcmevent_name bcmevent_names[]; | |||
658 | 658 | ||
659 | extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen, | 659 | extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen, |
660 | char *buf, uint len); | 660 | char *buf, uint len); |
661 | extern uint brcmf_c_mkiovar_bsscfg(char *name, char *data, uint datalen, | ||
662 | char *buf, uint buflen, s32 bssidx); | ||
661 | 663 | ||
662 | extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); | 664 | extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); |
663 | 665 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index fbecde73f904..efcb5056f295 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | |||
@@ -88,6 +88,52 @@ brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) | |||
88 | return len; | 88 | return len; |
89 | } | 89 | } |
90 | 90 | ||
91 | uint | ||
92 | brcmf_c_mkiovar_bsscfg(char *name, char *data, uint datalen, | ||
93 | char *buf, uint buflen, s32 bssidx) | ||
94 | { | ||
95 | const s8 *prefix = "bsscfg:"; | ||
96 | s8 *p; | ||
97 | u32 prefixlen; | ||
98 | u32 namelen; | ||
99 | u32 iolen; | ||
100 | __le32 bssidx_le; | ||
101 | |||
102 | if (bssidx == 0) | ||
103 | return brcmf_c_mkiovar(name, data, datalen, buf, buflen); | ||
104 | |||
105 | prefixlen = (u32) strlen(prefix); /* lengh of bsscfg prefix */ | ||
106 | namelen = (u32) strlen(name) + 1; /* lengh of iovar name + null */ | ||
107 | iolen = prefixlen + namelen + sizeof(bssidx_le) + datalen; | ||
108 | |||
109 | if (buflen < 0 || iolen > (u32)buflen) { | ||
110 | brcmf_dbg(ERROR, "buffer is too short\n"); | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | p = buf; | ||
115 | |||
116 | /* copy prefix, no null */ | ||
117 | memcpy(p, prefix, prefixlen); | ||
118 | p += prefixlen; | ||
119 | |||
120 | /* copy iovar name including null */ | ||
121 | memcpy(p, name, namelen); | ||
122 | p += namelen; | ||
123 | |||
124 | /* bss config index as first data */ | ||
125 | bssidx_le = cpu_to_le32(bssidx); | ||
126 | memcpy(p, &bssidx_le, sizeof(bssidx_le)); | ||
127 | p += sizeof(bssidx_le); | ||
128 | |||
129 | /* parameter buffer follows */ | ||
130 | if (datalen) | ||
131 | memcpy(p, data, datalen); | ||
132 | |||
133 | return iolen; | ||
134 | |||
135 | } | ||
136 | |||
91 | bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, | 137 | bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, |
92 | struct sk_buff *pkt, int prec) | 138 | struct sk_buff *pkt, int prec) |
93 | { | 139 | { |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 24e8f8d708ad..d0a2fa0babbf 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -366,6 +366,44 @@ brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par) | |||
366 | return err; | 366 | return err; |
367 | } | 367 | } |
368 | 368 | ||
369 | static s32 | ||
370 | brcmf_dev_iovar_setbuf_bsscfg(struct net_device *ndev, s8 *name, | ||
371 | void *param, s32 paramlen, | ||
372 | void *buf, s32 buflen, s32 bssidx) | ||
373 | { | ||
374 | s32 err = -ENOMEM; | ||
375 | u32 len; | ||
376 | |||
377 | len = brcmf_c_mkiovar_bsscfg(name, param, paramlen, | ||
378 | buf, buflen, bssidx); | ||
379 | BUG_ON(!len); | ||
380 | if (len > 0) | ||
381 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len); | ||
382 | if (err) | ||
383 | WL_ERR("error (%d)\n", err); | ||
384 | |||
385 | return err; | ||
386 | } | ||
387 | |||
388 | static s32 | ||
389 | brcmf_dev_iovar_getbuf_bsscfg(struct net_device *ndev, s8 *name, | ||
390 | void *param, s32 paramlen, | ||
391 | void *buf, s32 buflen, s32 bssidx) | ||
392 | { | ||
393 | s32 err = -ENOMEM; | ||
394 | u32 len; | ||
395 | |||
396 | len = brcmf_c_mkiovar_bsscfg(name, param, paramlen, | ||
397 | buf, buflen, bssidx); | ||
398 | BUG_ON(!len); | ||
399 | if (len > 0) | ||
400 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, buf, len); | ||
401 | if (err) | ||
402 | WL_ERR("error (%d)\n", err); | ||
403 | |||
404 | return err; | ||
405 | } | ||
406 | |||
369 | static void convert_key_from_CPU(struct brcmf_wsec_key *key, | 407 | static void convert_key_from_CPU(struct brcmf_wsec_key *key, |
370 | struct brcmf_wsec_key_le *key_le) | 408 | struct brcmf_wsec_key_le *key_le) |
371 | { | 409 | { |
@@ -380,16 +418,22 @@ static void convert_key_from_CPU(struct brcmf_wsec_key *key, | |||
380 | memcpy(key_le->ea, key->ea, sizeof(key->ea)); | 418 | memcpy(key_le->ea, key->ea, sizeof(key->ea)); |
381 | } | 419 | } |
382 | 420 | ||
383 | static int send_key_to_dongle(struct net_device *ndev, | 421 | static int |
384 | struct brcmf_wsec_key *key) | 422 | send_key_to_dongle(struct brcmf_cfg80211_priv *cfg_priv, s32 bssidx, |
423 | struct net_device *ndev, struct brcmf_wsec_key *key) | ||
385 | { | 424 | { |
386 | int err; | 425 | int err; |
387 | struct brcmf_wsec_key_le key_le; | 426 | struct brcmf_wsec_key_le key_le; |
388 | 427 | ||
389 | convert_key_from_CPU(key, &key_le); | 428 | convert_key_from_CPU(key, &key_le); |
390 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le)); | 429 | |
430 | err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le, | ||
431 | sizeof(key_le), | ||
432 | cfg_priv->extra_buf, | ||
433 | WL_EXTRA_BUF_MAX, bssidx); | ||
434 | |||
391 | if (err) | 435 | if (err) |
392 | WL_ERR("WLC_SET_KEY error (%d)\n", err); | 436 | WL_ERR("wsec_key error (%d)\n", err); |
393 | return err; | 437 | return err; |
394 | } | 438 | } |
395 | 439 | ||
@@ -487,6 +531,49 @@ brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval) | |||
487 | return err; | 531 | return err; |
488 | } | 532 | } |
489 | 533 | ||
534 | static s32 | ||
535 | brcmf_dev_intvar_set_bsscfg(struct net_device *ndev, s8 *name, u32 val, | ||
536 | s32 bssidx) | ||
537 | { | ||
538 | s8 buf[BRCMF_DCMD_SMLEN]; | ||
539 | __le32 val_le; | ||
540 | |||
541 | val_le = cpu_to_le32(val); | ||
542 | |||
543 | return brcmf_dev_iovar_setbuf_bsscfg(ndev, name, &val_le, | ||
544 | sizeof(val_le), buf, sizeof(buf), | ||
545 | bssidx); | ||
546 | } | ||
547 | |||
548 | static s32 | ||
549 | brcmf_dev_intvar_get_bsscfg(struct net_device *ndev, s8 *name, s32 *val, | ||
550 | s32 bssidx) | ||
551 | { | ||
552 | s8 buf[BRCMF_DCMD_SMLEN]; | ||
553 | s32 err; | ||
554 | __le32 val_le; | ||
555 | |||
556 | memset(buf, 0, sizeof(buf)); | ||
557 | err = brcmf_dev_iovar_getbuf_bsscfg(ndev, name, val, sizeof(*val), buf, | ||
558 | sizeof(buf), bssidx); | ||
559 | if (err == 0) { | ||
560 | memcpy(&val_le, buf, sizeof(val_le)); | ||
561 | *val = le32_to_cpu(val_le); | ||
562 | } | ||
563 | return err; | ||
564 | } | ||
565 | |||
566 | |||
567 | /* | ||
568 | * For now brcmf_find_bssidx will return 0. Once p2p gets implemented this | ||
569 | * should return the ndev matching bssidx. | ||
570 | */ | ||
571 | static s32 | ||
572 | brcmf_find_bssidx(struct brcmf_cfg80211_priv *cfg_priv, struct net_device *ndev) | ||
573 | { | ||
574 | return 0; | ||
575 | } | ||
576 | |||
490 | static void brcmf_set_mpc(struct net_device *ndev, int mpc) | 577 | static void brcmf_set_mpc(struct net_device *ndev, int mpc) |
491 | { | 578 | { |
492 | s32 err = 0; | 579 | s32 err = 0; |
@@ -1600,14 +1687,15 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) | |||
1600 | } | 1687 | } |
1601 | 1688 | ||
1602 | static s32 | 1689 | static s32 |
1603 | brcmf_set_wep_sharedkey(struct net_device *ndev, | 1690 | brcmf_set_sharedkey(struct net_device *ndev, |
1604 | struct cfg80211_connect_params *sme) | 1691 | struct cfg80211_connect_params *sme) |
1605 | { | 1692 | { |
1606 | struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); | 1693 | struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); |
1607 | struct brcmf_cfg80211_security *sec; | 1694 | struct brcmf_cfg80211_security *sec; |
1608 | struct brcmf_wsec_key key; | 1695 | struct brcmf_wsec_key key; |
1609 | s32 val; | 1696 | s32 val; |
1610 | s32 err = 0; | 1697 | s32 err = 0; |
1698 | s32 bssidx; | ||
1611 | 1699 | ||
1612 | WL_CONN("key len (%d)\n", sme->key_len); | 1700 | WL_CONN("key len (%d)\n", sme->key_len); |
1613 | 1701 | ||
@@ -1621,46 +1709,46 @@ brcmf_set_wep_sharedkey(struct net_device *ndev, | |||
1621 | if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) | 1709 | if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) |
1622 | return 0; | 1710 | return 0; |
1623 | 1711 | ||
1624 | if (sec->cipher_pairwise & | 1712 | if (!(sec->cipher_pairwise & |
1625 | (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) { | 1713 | (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104))) |
1626 | memset(&key, 0, sizeof(key)); | 1714 | return 0; |
1627 | key.len = (u32) sme->key_len; | ||
1628 | key.index = (u32) sme->key_idx; | ||
1629 | if (key.len > sizeof(key.data)) { | ||
1630 | WL_ERR("Too long key length (%u)\n", key.len); | ||
1631 | return -EINVAL; | ||
1632 | } | ||
1633 | memcpy(key.data, sme->key, key.len); | ||
1634 | key.flags = BRCMF_PRIMARY_KEY; | ||
1635 | switch (sec->cipher_pairwise) { | ||
1636 | case WLAN_CIPHER_SUITE_WEP40: | ||
1637 | key.algo = CRYPTO_ALGO_WEP1; | ||
1638 | break; | ||
1639 | case WLAN_CIPHER_SUITE_WEP104: | ||
1640 | key.algo = CRYPTO_ALGO_WEP128; | ||
1641 | break; | ||
1642 | default: | ||
1643 | WL_ERR("Invalid algorithm (%d)\n", | ||
1644 | sme->crypto.ciphers_pairwise[0]); | ||
1645 | return -EINVAL; | ||
1646 | } | ||
1647 | /* Set the new key/index */ | ||
1648 | WL_CONN("key length (%d) key index (%d) algo (%d)\n", | ||
1649 | key.len, key.index, key.algo); | ||
1650 | WL_CONN("key \"%s\"\n", key.data); | ||
1651 | err = send_key_to_dongle(ndev, &key); | ||
1652 | if (err) | ||
1653 | return err; | ||
1654 | 1715 | ||
1655 | if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) { | 1716 | memset(&key, 0, sizeof(key)); |
1656 | WL_CONN("set auth_type to shared key\n"); | 1717 | key.len = (u32) sme->key_len; |
1657 | val = 1; /* shared key */ | 1718 | key.index = (u32) sme->key_idx; |
1658 | err = brcmf_dev_intvar_set(ndev, "auth", val); | 1719 | if (key.len > sizeof(key.data)) { |
1659 | if (err) { | 1720 | WL_ERR("Too long key length (%u)\n", key.len); |
1660 | WL_ERR("set auth failed (%d)\n", err); | 1721 | return -EINVAL; |
1661 | return err; | 1722 | } |
1662 | } | 1723 | memcpy(key.data, sme->key, key.len); |
1663 | } | 1724 | key.flags = BRCMF_PRIMARY_KEY; |
1725 | switch (sec->cipher_pairwise) { | ||
1726 | case WLAN_CIPHER_SUITE_WEP40: | ||
1727 | key.algo = CRYPTO_ALGO_WEP1; | ||
1728 | break; | ||
1729 | case WLAN_CIPHER_SUITE_WEP104: | ||
1730 | key.algo = CRYPTO_ALGO_WEP128; | ||
1731 | break; | ||
1732 | default: | ||
1733 | WL_ERR("Invalid algorithm (%d)\n", | ||
1734 | sme->crypto.ciphers_pairwise[0]); | ||
1735 | return -EINVAL; | ||
1736 | } | ||
1737 | /* Set the new key/index */ | ||
1738 | WL_CONN("key length (%d) key index (%d) algo (%d)\n", | ||
1739 | key.len, key.index, key.algo); | ||
1740 | WL_CONN("key \"%s\"\n", key.data); | ||
1741 | bssidx = brcmf_find_bssidx(cfg_priv, ndev); | ||
1742 | err = send_key_to_dongle(cfg_priv, bssidx, ndev, &key); | ||
1743 | if (err) | ||
1744 | return err; | ||
1745 | |||
1746 | if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) { | ||
1747 | WL_CONN("set auth_type to shared key\n"); | ||
1748 | val = WL_AUTH_SHARED_KEY; /* shared key */ | ||
1749 | err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", val, bssidx); | ||
1750 | if (err) | ||
1751 | WL_ERR("set auth failed (%d)\n", err); | ||
1664 | } | 1752 | } |
1665 | return err; | 1753 | return err; |
1666 | } | 1754 | } |
@@ -1722,9 +1810,9 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, | |||
1722 | goto done; | 1810 | goto done; |
1723 | } | 1811 | } |
1724 | 1812 | ||
1725 | err = brcmf_set_wep_sharedkey(ndev, sme); | 1813 | err = brcmf_set_sharedkey(ndev, sme); |
1726 | if (err) { | 1814 | if (err) { |
1727 | WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err); | 1815 | WL_ERR("brcmf_set_sharedkey failed (%d)\n", err); |
1728 | goto done; | 1816 | goto done; |
1729 | } | 1817 | } |
1730 | 1818 | ||
@@ -1863,16 +1951,19 @@ static s32 | |||
1863 | brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev, | 1951 | brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev, |
1864 | u8 key_idx, bool unicast, bool multicast) | 1952 | u8 key_idx, bool unicast, bool multicast) |
1865 | { | 1953 | { |
1954 | struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); | ||
1866 | u32 index; | 1955 | u32 index; |
1867 | u32 wsec; | 1956 | u32 wsec; |
1868 | s32 err = 0; | 1957 | s32 err = 0; |
1958 | s32 bssidx; | ||
1869 | 1959 | ||
1870 | WL_TRACE("Enter\n"); | 1960 | WL_TRACE("Enter\n"); |
1871 | WL_CONN("key index (%d)\n", key_idx); | 1961 | WL_CONN("key index (%d)\n", key_idx); |
1872 | if (!check_sys_up(wiphy)) | 1962 | if (!check_sys_up(wiphy)) |
1873 | return -EIO; | 1963 | return -EIO; |
1874 | 1964 | ||
1875 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec); | 1965 | bssidx = brcmf_find_bssidx(cfg_priv, ndev); |
1966 | err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx); | ||
1876 | if (err) { | 1967 | if (err) { |
1877 | WL_ERR("WLC_GET_WSEC error (%d)\n", err); | 1968 | WL_ERR("WLC_GET_WSEC error (%d)\n", err); |
1878 | goto done; | 1969 | goto done; |
@@ -1895,9 +1986,11 @@ static s32 | |||
1895 | brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, | 1986 | brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, |
1896 | u8 key_idx, const u8 *mac_addr, struct key_params *params) | 1987 | u8 key_idx, const u8 *mac_addr, struct key_params *params) |
1897 | { | 1988 | { |
1989 | struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); | ||
1898 | struct brcmf_wsec_key key; | 1990 | struct brcmf_wsec_key key; |
1899 | struct brcmf_wsec_key_le key_le; | 1991 | struct brcmf_wsec_key_le key_le; |
1900 | s32 err = 0; | 1992 | s32 err = 0; |
1993 | s32 bssidx; | ||
1901 | 1994 | ||
1902 | memset(&key, 0, sizeof(key)); | 1995 | memset(&key, 0, sizeof(key)); |
1903 | key.index = (u32) key_idx; | 1996 | key.index = (u32) key_idx; |
@@ -1906,12 +1999,13 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, | |||
1906 | if (!is_multicast_ether_addr(mac_addr)) | 1999 | if (!is_multicast_ether_addr(mac_addr)) |
1907 | memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN); | 2000 | memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN); |
1908 | key.len = (u32) params->key_len; | 2001 | key.len = (u32) params->key_len; |
2002 | bssidx = brcmf_find_bssidx(cfg_priv, ndev); | ||
1909 | /* check for key index change */ | 2003 | /* check for key index change */ |
1910 | if (key.len == 0) { | 2004 | if (key.len == 0) { |
1911 | /* key delete */ | 2005 | /* key delete */ |
1912 | err = send_key_to_dongle(ndev, &key); | 2006 | err = send_key_to_dongle(cfg_priv, bssidx, ndev, &key); |
1913 | if (err) | 2007 | if (err) |
1914 | return err; | 2008 | WL_ERR("key delete error (%d)\n", err); |
1915 | } else { | 2009 | } else { |
1916 | if (key.len > sizeof(key.data)) { | 2010 | if (key.len > sizeof(key.data)) { |
1917 | WL_ERR("Invalid key length (%d)\n", key.len); | 2011 | WL_ERR("Invalid key length (%d)\n", key.len); |
@@ -1967,12 +2061,12 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, | |||
1967 | convert_key_from_CPU(&key, &key_le); | 2061 | convert_key_from_CPU(&key, &key_le); |
1968 | 2062 | ||
1969 | brcmf_netdev_wait_pend8021x(ndev); | 2063 | brcmf_netdev_wait_pend8021x(ndev); |
1970 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, | 2064 | err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le, |
1971 | sizeof(key_le)); | 2065 | sizeof(key_le), |
1972 | if (err) { | 2066 | cfg_priv->extra_buf, |
1973 | WL_ERR("WLC_SET_KEY error (%d)\n", err); | 2067 | WL_EXTRA_BUF_MAX, bssidx); |
1974 | return err; | 2068 | if (err) |
1975 | } | 2069 | WL_ERR("wsec_key error (%d)\n", err); |
1976 | } | 2070 | } |
1977 | return err; | 2071 | return err; |
1978 | } | 2072 | } |
@@ -1982,11 +2076,13 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
1982 | u8 key_idx, bool pairwise, const u8 *mac_addr, | 2076 | u8 key_idx, bool pairwise, const u8 *mac_addr, |
1983 | struct key_params *params) | 2077 | struct key_params *params) |
1984 | { | 2078 | { |
2079 | struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); | ||
1985 | struct brcmf_wsec_key key; | 2080 | struct brcmf_wsec_key key; |
1986 | s32 val; | 2081 | s32 val; |
1987 | s32 wsec; | 2082 | s32 wsec; |
1988 | s32 err = 0; | 2083 | s32 err = 0; |
1989 | u8 keybuf[8]; | 2084 | u8 keybuf[8]; |
2085 | s32 bssidx; | ||
1990 | 2086 | ||
1991 | WL_TRACE("Enter\n"); | 2087 | WL_TRACE("Enter\n"); |
1992 | WL_CONN("key index (%d)\n", key_idx); | 2088 | WL_CONN("key index (%d)\n", key_idx); |
@@ -2013,10 +2109,12 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
2013 | switch (params->cipher) { | 2109 | switch (params->cipher) { |
2014 | case WLAN_CIPHER_SUITE_WEP40: | 2110 | case WLAN_CIPHER_SUITE_WEP40: |
2015 | key.algo = CRYPTO_ALGO_WEP1; | 2111 | key.algo = CRYPTO_ALGO_WEP1; |
2112 | val = WEP_ENABLED; | ||
2016 | WL_CONN("WLAN_CIPHER_SUITE_WEP40\n"); | 2113 | WL_CONN("WLAN_CIPHER_SUITE_WEP40\n"); |
2017 | break; | 2114 | break; |
2018 | case WLAN_CIPHER_SUITE_WEP104: | 2115 | case WLAN_CIPHER_SUITE_WEP104: |
2019 | key.algo = CRYPTO_ALGO_WEP128; | 2116 | key.algo = CRYPTO_ALGO_WEP128; |
2117 | val = WEP_ENABLED; | ||
2020 | WL_CONN("WLAN_CIPHER_SUITE_WEP104\n"); | 2118 | WL_CONN("WLAN_CIPHER_SUITE_WEP104\n"); |
2021 | break; | 2119 | break; |
2022 | case WLAN_CIPHER_SUITE_TKIP: | 2120 | case WLAN_CIPHER_SUITE_TKIP: |
@@ -2024,14 +2122,17 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
2024 | memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); | 2122 | memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); |
2025 | memcpy(&key.data[16], keybuf, sizeof(keybuf)); | 2123 | memcpy(&key.data[16], keybuf, sizeof(keybuf)); |
2026 | key.algo = CRYPTO_ALGO_TKIP; | 2124 | key.algo = CRYPTO_ALGO_TKIP; |
2125 | val = TKIP_ENABLED; | ||
2027 | WL_CONN("WLAN_CIPHER_SUITE_TKIP\n"); | 2126 | WL_CONN("WLAN_CIPHER_SUITE_TKIP\n"); |
2028 | break; | 2127 | break; |
2029 | case WLAN_CIPHER_SUITE_AES_CMAC: | 2128 | case WLAN_CIPHER_SUITE_AES_CMAC: |
2030 | key.algo = CRYPTO_ALGO_AES_CCM; | 2129 | key.algo = CRYPTO_ALGO_AES_CCM; |
2130 | val = AES_ENABLED; | ||
2031 | WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n"); | 2131 | WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n"); |
2032 | break; | 2132 | break; |
2033 | case WLAN_CIPHER_SUITE_CCMP: | 2133 | case WLAN_CIPHER_SUITE_CCMP: |
2034 | key.algo = CRYPTO_ALGO_AES_CCM; | 2134 | key.algo = CRYPTO_ALGO_AES_CCM; |
2135 | val = AES_ENABLED; | ||
2035 | WL_CONN("WLAN_CIPHER_SUITE_CCMP\n"); | 2136 | WL_CONN("WLAN_CIPHER_SUITE_CCMP\n"); |
2036 | break; | 2137 | break; |
2037 | default: | 2138 | default: |
@@ -2040,28 +2141,23 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
2040 | goto done; | 2141 | goto done; |
2041 | } | 2142 | } |
2042 | 2143 | ||
2043 | err = send_key_to_dongle(ndev, &key); /* Set the new key/index */ | 2144 | bssidx = brcmf_find_bssidx(cfg_priv, ndev); |
2145 | err = send_key_to_dongle(cfg_priv, bssidx, ndev, &key); | ||
2044 | if (err) | 2146 | if (err) |
2045 | goto done; | 2147 | goto done; |
2046 | 2148 | ||
2047 | val = WEP_ENABLED; | 2149 | err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx); |
2048 | err = brcmf_dev_intvar_get(ndev, "wsec", &wsec); | ||
2049 | if (err) { | 2150 | if (err) { |
2050 | WL_ERR("get wsec error (%d)\n", err); | 2151 | WL_ERR("get wsec error (%d)\n", err); |
2051 | goto done; | 2152 | goto done; |
2052 | } | 2153 | } |
2053 | wsec &= ~(WEP_ENABLED); | ||
2054 | wsec |= val; | 2154 | wsec |= val; |
2055 | err = brcmf_dev_intvar_set(ndev, "wsec", wsec); | 2155 | err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx); |
2056 | if (err) { | 2156 | if (err) { |
2057 | WL_ERR("set wsec error (%d)\n", err); | 2157 | WL_ERR("set wsec error (%d)\n", err); |
2058 | goto done; | 2158 | goto done; |
2059 | } | 2159 | } |
2060 | 2160 | ||
2061 | val = 1; /* assume shared key. otherwise 0 */ | ||
2062 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val); | ||
2063 | if (err) | ||
2064 | WL_ERR("WLC_SET_AUTH error (%d)\n", err); | ||
2065 | done: | 2161 | done: |
2066 | WL_TRACE("Exit\n"); | 2162 | WL_TRACE("Exit\n"); |
2067 | return err; | 2163 | return err; |
@@ -2071,10 +2167,10 @@ static s32 | |||
2071 | brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, | 2167 | brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, |
2072 | u8 key_idx, bool pairwise, const u8 *mac_addr) | 2168 | u8 key_idx, bool pairwise, const u8 *mac_addr) |
2073 | { | 2169 | { |
2170 | struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); | ||
2074 | struct brcmf_wsec_key key; | 2171 | struct brcmf_wsec_key key; |
2075 | s32 err = 0; | 2172 | s32 err = 0; |
2076 | s32 val; | 2173 | s32 bssidx; |
2077 | s32 wsec; | ||
2078 | 2174 | ||
2079 | WL_TRACE("Enter\n"); | 2175 | WL_TRACE("Enter\n"); |
2080 | if (!check_sys_up(wiphy)) | 2176 | if (!check_sys_up(wiphy)) |
@@ -2089,7 +2185,8 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, | |||
2089 | WL_CONN("key index (%d)\n", key_idx); | 2185 | WL_CONN("key index (%d)\n", key_idx); |
2090 | 2186 | ||
2091 | /* Set the new key/index */ | 2187 | /* Set the new key/index */ |
2092 | err = send_key_to_dongle(ndev, &key); | 2188 | bssidx = brcmf_find_bssidx(cfg_priv, ndev); |
2189 | err = send_key_to_dongle(cfg_priv, bssidx, ndev, &key); | ||
2093 | if (err) { | 2190 | if (err) { |
2094 | if (err == -EINVAL) { | 2191 | if (err == -EINVAL) { |
2095 | if (key.index >= DOT11_MAX_DEFAULT_KEYS) | 2192 | if (key.index >= DOT11_MAX_DEFAULT_KEYS) |
@@ -2098,35 +2195,8 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, | |||
2098 | } | 2195 | } |
2099 | /* Ignore this error, may happen during DISASSOC */ | 2196 | /* Ignore this error, may happen during DISASSOC */ |
2100 | err = -EAGAIN; | 2197 | err = -EAGAIN; |
2101 | goto done; | ||
2102 | } | 2198 | } |
2103 | 2199 | ||
2104 | val = 0; | ||
2105 | err = brcmf_dev_intvar_get(ndev, "wsec", &wsec); | ||
2106 | if (err) { | ||
2107 | WL_ERR("get wsec error (%d)\n", err); | ||
2108 | /* Ignore this error, may happen during DISASSOC */ | ||
2109 | err = -EAGAIN; | ||
2110 | goto done; | ||
2111 | } | ||
2112 | wsec &= ~(WEP_ENABLED); | ||
2113 | wsec |= val; | ||
2114 | err = brcmf_dev_intvar_set(ndev, "wsec", wsec); | ||
2115 | if (err) { | ||
2116 | WL_ERR("set wsec error (%d)\n", err); | ||
2117 | /* Ignore this error, may happen during DISASSOC */ | ||
2118 | err = -EAGAIN; | ||
2119 | goto done; | ||
2120 | } | ||
2121 | |||
2122 | val = 0; /* assume open key. otherwise 1 */ | ||
2123 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val); | ||
2124 | if (err) { | ||
2125 | WL_ERR("WLC_SET_AUTH error (%d)\n", err); | ||
2126 | /* Ignore this error, may happen during DISASSOC */ | ||
2127 | err = -EAGAIN; | ||
2128 | } | ||
2129 | done: | ||
2130 | WL_TRACE("Exit\n"); | 2200 | WL_TRACE("Exit\n"); |
2131 | return err; | 2201 | return err; |
2132 | } | 2202 | } |
@@ -2141,6 +2211,7 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, | |||
2141 | struct brcmf_cfg80211_security *sec; | 2211 | struct brcmf_cfg80211_security *sec; |
2142 | s32 wsec; | 2212 | s32 wsec; |
2143 | s32 err = 0; | 2213 | s32 err = 0; |
2214 | s32 bssidx; | ||
2144 | 2215 | ||
2145 | WL_TRACE("Enter\n"); | 2216 | WL_TRACE("Enter\n"); |
2146 | WL_CONN("key index (%d)\n", key_idx); | 2217 | WL_CONN("key index (%d)\n", key_idx); |
@@ -2149,14 +2220,15 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, | |||
2149 | 2220 | ||
2150 | memset(¶ms, 0, sizeof(params)); | 2221 | memset(¶ms, 0, sizeof(params)); |
2151 | 2222 | ||
2152 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec); | 2223 | bssidx = brcmf_find_bssidx(cfg_priv, ndev); |
2224 | err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx); | ||
2153 | if (err) { | 2225 | if (err) { |
2154 | WL_ERR("WLC_GET_WSEC error (%d)\n", err); | 2226 | WL_ERR("WLC_GET_WSEC error (%d)\n", err); |
2155 | /* Ignore this error, may happen during DISASSOC */ | 2227 | /* Ignore this error, may happen during DISASSOC */ |
2156 | err = -EAGAIN; | 2228 | err = -EAGAIN; |
2157 | goto done; | 2229 | goto done; |
2158 | } | 2230 | } |
2159 | switch (wsec) { | 2231 | switch (wsec & ~SES_OW_ENABLED) { |
2160 | case WEP_ENABLED: | 2232 | case WEP_ENABLED: |
2161 | sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); | 2233 | sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); |
2162 | if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { | 2234 | if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index 52e408ed6f41..f2069e89137f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | |||
@@ -130,6 +130,8 @@ do { \ | |||
130 | #define WL_ESCAN_ACTION_CONTINUE 2 | 130 | #define WL_ESCAN_ACTION_CONTINUE 2 |
131 | #define WL_ESCAN_ACTION_ABORT 3 | 131 | #define WL_ESCAN_ACTION_ABORT 3 |
132 | 132 | ||
133 | #define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */ | ||
134 | |||
133 | /* dongle status */ | 135 | /* dongle status */ |
134 | enum wl_status { | 136 | enum wl_status { |
135 | WL_STATUS_READY, | 137 | WL_STATUS_READY, |