3232#include "vendor.h"
3333#include "bus.h"
3434#include "common.h"
35+ #include "feature.h"
3536#include "fwvid.h"
37+ #include "xtlv.h"
3638
3739#define BRCMF_SCAN_IE_LEN_MAX 2048
3840
@@ -125,6 +127,13 @@ struct cca_msrmnt_query {
125127 u32 time_req ;
126128};
127129
130+ /* algo bit vector */
131+ #define KEY_ALGO_MASK (_algo ) (1 << (_algo))
132+
133+ /* start enum value for BSS properties */
134+ #define WL_WSEC_INFO_BSS_BASE 0x0100
135+ #define WL_WSEC_INFO_BSS_ALGOS (WL_WSEC_INFO_BSS_BASE + 6)
136+
128137static bool check_vif_up (struct brcmf_cfg80211_vif * vif )
129138{
130139 if (!test_bit (BRCMF_VIF_STATUS_READY , & vif -> sme_state )) {
@@ -237,16 +246,22 @@ static const struct ieee80211_regdomain brcmf_regdom = {
237246/* Note: brcmf_cipher_suites is an array of int defining which cipher suites
238247 * are supported. A pointer to this array and the number of entries is passed
239248 * on to upper layers. AES_CMAC defines whether or not the driver supports MFP.
240- * So the cipher suite AES_CMAC has to be the last one in the array, and when
241- * device does not support MFP then the number of suites will be decreased by 1
249+ * MFP support includes a few other suites, so if MFP is not supported,
250+ * then the number of suites will be decreased by 4
242251 */
243252static const u32 brcmf_cipher_suites [] = {
244253 WLAN_CIPHER_SUITE_WEP40 ,
245254 WLAN_CIPHER_SUITE_WEP104 ,
246255 WLAN_CIPHER_SUITE_TKIP ,
247256 WLAN_CIPHER_SUITE_CCMP ,
248- /* Keep as last entry: */
249- WLAN_CIPHER_SUITE_AES_CMAC
257+ WLAN_CIPHER_SUITE_CCMP_256 ,
258+ WLAN_CIPHER_SUITE_GCMP ,
259+ WLAN_CIPHER_SUITE_GCMP_256 ,
260+ /* Keep as last 4 entries: */
261+ WLAN_CIPHER_SUITE_AES_CMAC ,
262+ WLAN_CIPHER_SUITE_BIP_CMAC_256 ,
263+ WLAN_CIPHER_SUITE_BIP_GMAC_128 ,
264+ WLAN_CIPHER_SUITE_BIP_GMAC_256
250265};
251266
252267/* Vendor specific ie. id = 221, oui and type defines exact ie */
@@ -2014,6 +2029,48 @@ static s32 brcmf_set_auth_type(struct net_device *ndev,
20142029 return err ;
20152030}
20162031
2032+ static s32 brcmf_set_wsec_info_algos (struct brcmf_if * ifp , u32 algos , u32 mask )
2033+ {
2034+ struct brcmf_pub * drvr = ifp -> drvr ;
2035+ s32 err = 0 ;
2036+ struct brcmf_wsec_info * wsec_info ;
2037+ struct brcmf_xtlv * wsec_info_tlv ;
2038+ u16 tlv_data_len ;
2039+ u8 tlv_data [8 ];
2040+ u32 param_len ;
2041+ u8 * buf ;
2042+
2043+ brcmf_dbg (TRACE , "Enter\n" );
2044+
2045+ buf = kzalloc (sizeof (struct brcmf_wsec_info ) + sizeof (tlv_data ),
2046+ GFP_KERNEL );
2047+ if (!buf ) {
2048+ bphy_err (drvr , "unable to allocate.\n" );
2049+ return - ENOMEM ;
2050+ }
2051+ wsec_info = (struct brcmf_wsec_info * )buf ;
2052+ wsec_info -> version = BRCMF_WSEC_INFO_VER ;
2053+ wsec_info_tlv =
2054+ (struct brcmf_xtlv * )(buf +
2055+ offsetof(struct brcmf_wsec_info , tlvs ));
2056+ wsec_info -> num_tlvs ++ ;
2057+ tlv_data_len = sizeof (tlv_data );
2058+ memcpy (tlv_data , & algos , sizeof (algos ));
2059+ memcpy (tlv_data + sizeof (algos ), & mask , sizeof (mask ));
2060+ brcmf_xtlv_pack_header (wsec_info_tlv , WL_WSEC_INFO_BSS_ALGOS ,
2061+ tlv_data_len , tlv_data , 0 );
2062+
2063+ param_len = offsetof(struct brcmf_wsec_info , tlvs ) +
2064+ offsetof(struct brcmf_wsec_info_tlv , data ) + tlv_data_len ;
2065+
2066+ err = brcmf_fil_bsscfg_data_set (ifp , "wsec_info" , buf , param_len );
2067+ if (err )
2068+ brcmf_err ("set wsec_info_error:%d\n" , err );
2069+
2070+ kfree (buf );
2071+ return err ;
2072+ }
2073+
20172074static s32
20182075brcmf_set_wsec_mode (struct net_device * ndev ,
20192076 struct cfg80211_connect_params * sme )
@@ -2026,6 +2083,8 @@ brcmf_set_wsec_mode(struct net_device *ndev,
20262083 s32 gval = 0 ;
20272084 s32 wsec ;
20282085 s32 err = 0 ;
2086+ u32 algos = 0 ;
2087+ u32 mask = 0 ;
20292088
20302089 if (sme -> crypto .n_ciphers_pairwise ) {
20312090 switch (sme -> crypto .ciphers_pairwise [0 ]) {
@@ -2042,6 +2101,15 @@ brcmf_set_wsec_mode(struct net_device *ndev,
20422101 case WLAN_CIPHER_SUITE_AES_CMAC :
20432102 pval = AES_ENABLED ;
20442103 break ;
2104+ case WLAN_CIPHER_SUITE_GCMP_256 :
2105+ if (!brcmf_feat_is_enabled (ifp , BRCMF_FEAT_GCMP )) {
2106+ brcmf_err ("This chip does not support GCMP\n" );
2107+ return - EOPNOTSUPP ;
2108+ }
2109+ pval = AES_ENABLED ;
2110+ algos = KEY_ALGO_MASK (CRYPTO_ALGO_AES_GCM256 );
2111+ mask = algos | KEY_ALGO_MASK (CRYPTO_ALGO_AES_CCM );
2112+ break ;
20452113 default :
20462114 bphy_err (drvr , "invalid cipher pairwise (%d)\n" ,
20472115 sme -> crypto .ciphers_pairwise [0 ]);
@@ -2063,6 +2131,15 @@ brcmf_set_wsec_mode(struct net_device *ndev,
20632131 case WLAN_CIPHER_SUITE_AES_CMAC :
20642132 gval = AES_ENABLED ;
20652133 break ;
2134+ case WLAN_CIPHER_SUITE_GCMP_256 :
2135+ if (!brcmf_feat_is_enabled (ifp , BRCMF_FEAT_GCMP )) {
2136+ brcmf_err ("This chip does not support GCMP\n" );
2137+ return - EOPNOTSUPP ;
2138+ }
2139+ gval = AES_ENABLED ;
2140+ algos = KEY_ALGO_MASK (CRYPTO_ALGO_AES_GCM256 );
2141+ mask = algos | KEY_ALGO_MASK (CRYPTO_ALGO_AES_CCM );
2142+ break ;
20662143 default :
20672144 bphy_err (drvr , "invalid cipher group (%d)\n" ,
20682145 sme -> crypto .cipher_group );
@@ -2071,6 +2148,7 @@ brcmf_set_wsec_mode(struct net_device *ndev,
20712148 }
20722149
20732150 brcmf_dbg (CONN , "pval (%d) gval (%d)\n" , pval , gval );
2151+ brcmf_dbg (CONN , "algos (0x%x) mask (0x%x)\n" , algos , mask );
20742152 /* In case of privacy, but no security and WPS then simulate */
20752153 /* setting AES. WPS-2.0 allows no security */
20762154 if (brcmf_find_wpsie (sme -> ie , sme -> ie_len ) && !pval && !gval &&
@@ -2083,6 +2161,15 @@ brcmf_set_wsec_mode(struct net_device *ndev,
20832161 bphy_err (drvr , "error (%d)\n" , err );
20842162 return err ;
20852163 }
2164+ if (brcmf_feat_is_enabled (ifp , BRCMF_FEAT_GCMP )) {
2165+ brcmf_dbg (CONN , "set_wsec_info algos (0x%x) mask (0x%x)\n" ,
2166+ algos , mask );
2167+ err = brcmf_set_wsec_info_algos (ifp , algos , mask );
2168+ if (err ) {
2169+ brcmf_err ("set wsec_info error (%d)\n" , err );
2170+ return err ;
2171+ }
2172+ }
20862173
20872174 sec = & profile -> sec ;
20882175 sec -> cipher_pairwise = sme -> crypto .ciphers_pairwise [0 ];
@@ -2797,6 +2884,8 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
27972884 s32 val ;
27982885 s32 wsec ;
27992886 s32 err ;
2887+ u32 algos = 0 ;
2888+ u32 mask = 0 ;
28002889 u8 keybuf [8 ];
28012890 bool ext_key ;
28022891
@@ -2880,6 +2969,30 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
28802969 val = AES_ENABLED ;
28812970 brcmf_dbg (CONN , "WLAN_CIPHER_SUITE_CCMP\n" );
28822971 break ;
2972+ case WLAN_CIPHER_SUITE_GCMP_256 :
2973+ if (!brcmf_feat_is_enabled (ifp , BRCMF_FEAT_GCMP )) {
2974+ brcmf_err ("the low layer not support GCMP\n" );
2975+ err = - EOPNOTSUPP ;
2976+ goto done ;
2977+ }
2978+ key -> algo = CRYPTO_ALGO_AES_GCM256 ;
2979+ val = AES_ENABLED ;
2980+ brcmf_dbg (CONN , "WLAN_CIPHER_SUITE_GCMP_256\n" );
2981+ algos = KEY_ALGO_MASK (CRYPTO_ALGO_AES_GCM256 );
2982+ mask = algos | KEY_ALGO_MASK (CRYPTO_ALGO_AES_CCM );
2983+ break ;
2984+ case WLAN_CIPHER_SUITE_BIP_GMAC_256 :
2985+ if (!brcmf_feat_is_enabled (ifp , BRCMF_FEAT_GCMP )) {
2986+ brcmf_err ("the low layer not support GCMP\n" );
2987+ err = - EOPNOTSUPP ;
2988+ goto done ;
2989+ }
2990+ key -> algo = CRYPTO_ALGO_BIP_GMAC256 ;
2991+ val = AES_ENABLED ;
2992+ algos = KEY_ALGO_MASK (CRYPTO_ALGO_BIP_GMAC256 );
2993+ mask = algos | KEY_ALGO_MASK (CRYPTO_ALGO_AES_CCM );
2994+ brcmf_dbg (CONN , "WLAN_CIPHER_SUITE_BIP_GMAC_256\n" );
2995+ break ;
28832996 default :
28842997 bphy_err (drvr , "Invalid cipher (0x%x)\n" , params -> cipher );
28852998 err = - EINVAL ;
@@ -2901,6 +3014,17 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
29013014 bphy_err (drvr , "set wsec error (%d)\n" , err );
29023015 goto done ;
29033016 }
3017+ if (brcmf_feat_is_enabled (ifp , BRCMF_FEAT_GCMP )) {
3018+ brcmf_dbg (CONN ,
3019+ "set_wsdec_info algos (0x%x) mask (0x%x)\n" ,
3020+ algos , mask );
3021+ err = brcmf_set_wsec_info_algos (ifp , algos , mask );
3022+ if (err ) {
3023+ brcmf_err ("set wsec_info error (%d)\n" , err );
3024+ return err ;
3025+ }
3026+ }
3027+
29043028
29053029done :
29063030 brcmf_dbg (TRACE , "Exit\n" );
0 commit comments