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
@@ -124,6 +126,13 @@ struct cca_msrmnt_query {
124126 u32 time_req ;
125127};
126128
129+ /* algo bit vector */
130+ #define KEY_ALGO_MASK (_algo ) (1 << (_algo))
131+
132+ /* start enum value for BSS properties */
133+ #define WL_WSEC_INFO_BSS_BASE 0x0100
134+ #define WL_WSEC_INFO_BSS_ALGOS (WL_WSEC_INFO_BSS_BASE + 6)
135+
127136static bool check_vif_up (struct brcmf_cfg80211_vif * vif )
128137{
129138 if (!test_bit (BRCMF_VIF_STATUS_READY , & vif -> sme_state )) {
@@ -236,16 +245,22 @@ static const struct ieee80211_regdomain brcmf_regdom = {
236245/* Note: brcmf_cipher_suites is an array of int defining which cipher suites
237246 * are supported. A pointer to this array and the number of entries is passed
238247 * on to upper layers. AES_CMAC defines whether or not the driver supports MFP.
239- * So the cipher suite AES_CMAC has to be the last one in the array, and when
240- * device does not support MFP then the number of suites will be decreased by 1
248+ * MFP support includes a few other suites, so if MFP is not supported,
249+ * then the number of suites will be decreased by 4
241250 */
242251static const u32 brcmf_cipher_suites [] = {
243252 WLAN_CIPHER_SUITE_WEP40 ,
244253 WLAN_CIPHER_SUITE_WEP104 ,
245254 WLAN_CIPHER_SUITE_TKIP ,
246255 WLAN_CIPHER_SUITE_CCMP ,
247- /* Keep as last entry: */
248- WLAN_CIPHER_SUITE_AES_CMAC
256+ WLAN_CIPHER_SUITE_CCMP_256 ,
257+ WLAN_CIPHER_SUITE_GCMP ,
258+ WLAN_CIPHER_SUITE_GCMP_256 ,
259+ /* Keep as last 4 entries: */
260+ WLAN_CIPHER_SUITE_AES_CMAC ,
261+ WLAN_CIPHER_SUITE_BIP_CMAC_256 ,
262+ WLAN_CIPHER_SUITE_BIP_GMAC_128 ,
263+ WLAN_CIPHER_SUITE_BIP_GMAC_256
249264};
250265
251266/* Vendor specific ie. id = 221, oui and type defines exact ie */
@@ -2018,6 +2033,48 @@ static s32 brcmf_set_auth_type(struct net_device *ndev,
20182033 return err ;
20192034}
20202035
2036+ static s32 brcmf_set_wsec_info_algos (struct brcmf_if * ifp , u32 algos , u32 mask )
2037+ {
2038+ struct brcmf_pub * drvr = ifp -> drvr ;
2039+ s32 err = 0 ;
2040+ struct brcmf_wsec_info * wsec_info ;
2041+ struct brcmf_xtlv * wsec_info_tlv ;
2042+ u16 tlv_data_len ;
2043+ u8 tlv_data [8 ];
2044+ u32 param_len ;
2045+ u8 * buf ;
2046+
2047+ brcmf_dbg (TRACE , "Enter\n" );
2048+
2049+ buf = kzalloc (sizeof (struct brcmf_wsec_info ) + sizeof (tlv_data ),
2050+ GFP_KERNEL );
2051+ if (!buf ) {
2052+ bphy_err (drvr , "unable to allocate.\n" );
2053+ return - ENOMEM ;
2054+ }
2055+ wsec_info = (struct brcmf_wsec_info * )buf ;
2056+ wsec_info -> version = BRCMF_WSEC_INFO_VER ;
2057+ wsec_info_tlv =
2058+ (struct brcmf_xtlv * )(buf +
2059+ offsetof(struct brcmf_wsec_info , tlvs ));
2060+ wsec_info -> num_tlvs ++ ;
2061+ tlv_data_len = sizeof (tlv_data );
2062+ memcpy (tlv_data , & algos , sizeof (algos ));
2063+ memcpy (tlv_data + sizeof (algos ), & mask , sizeof (mask ));
2064+ brcmf_xtlv_pack_header (wsec_info_tlv , WL_WSEC_INFO_BSS_ALGOS ,
2065+ tlv_data_len , tlv_data , 0 );
2066+
2067+ param_len = offsetof(struct brcmf_wsec_info , tlvs ) +
2068+ offsetof(struct brcmf_wsec_info_tlv , data ) + tlv_data_len ;
2069+
2070+ err = brcmf_fil_bsscfg_data_set (ifp , "wsec_info" , buf , param_len );
2071+ if (err )
2072+ brcmf_err ("set wsec_info_error:%d\n" , err );
2073+
2074+ kfree (buf );
2075+ return err ;
2076+ }
2077+
20212078static s32
20222079brcmf_set_wsec_mode (struct net_device * ndev ,
20232080 struct cfg80211_connect_params * sme )
@@ -2030,6 +2087,8 @@ brcmf_set_wsec_mode(struct net_device *ndev,
20302087 s32 gval = 0 ;
20312088 s32 wsec ;
20322089 s32 err = 0 ;
2090+ u32 algos = 0 ;
2091+ u32 mask = 0 ;
20332092
20342093 if (sme -> crypto .n_ciphers_pairwise ) {
20352094 switch (sme -> crypto .ciphers_pairwise [0 ]) {
@@ -2046,6 +2105,15 @@ brcmf_set_wsec_mode(struct net_device *ndev,
20462105 case WLAN_CIPHER_SUITE_AES_CMAC :
20472106 pval = AES_ENABLED ;
20482107 break ;
2108+ case WLAN_CIPHER_SUITE_GCMP_256 :
2109+ if (!brcmf_feat_is_enabled (ifp , BRCMF_FEAT_GCMP )) {
2110+ brcmf_err ("This chip does not support GCMP\n" );
2111+ return - EOPNOTSUPP ;
2112+ }
2113+ pval = AES_ENABLED ;
2114+ algos = KEY_ALGO_MASK (CRYPTO_ALGO_AES_GCM256 );
2115+ mask = algos | KEY_ALGO_MASK (CRYPTO_ALGO_AES_CCM );
2116+ break ;
20492117 default :
20502118 bphy_err (drvr , "invalid cipher pairwise (%d)\n" ,
20512119 sme -> crypto .ciphers_pairwise [0 ]);
@@ -2067,6 +2135,15 @@ brcmf_set_wsec_mode(struct net_device *ndev,
20672135 case WLAN_CIPHER_SUITE_AES_CMAC :
20682136 gval = AES_ENABLED ;
20692137 break ;
2138+ case WLAN_CIPHER_SUITE_GCMP_256 :
2139+ if (!brcmf_feat_is_enabled (ifp , BRCMF_FEAT_GCMP )) {
2140+ brcmf_err ("This chip does not support GCMP\n" );
2141+ return - EOPNOTSUPP ;
2142+ }
2143+ gval = AES_ENABLED ;
2144+ algos = KEY_ALGO_MASK (CRYPTO_ALGO_AES_GCM256 );
2145+ mask = algos | KEY_ALGO_MASK (CRYPTO_ALGO_AES_CCM );
2146+ break ;
20702147 default :
20712148 bphy_err (drvr , "invalid cipher group (%d)\n" ,
20722149 sme -> crypto .cipher_group );
@@ -2075,6 +2152,7 @@ brcmf_set_wsec_mode(struct net_device *ndev,
20752152 }
20762153
20772154 brcmf_dbg (CONN , "pval (%d) gval (%d)\n" , pval , gval );
2155+ brcmf_dbg (CONN , "algos (0x%x) mask (0x%x)\n" , algos , mask );
20782156 /* In case of privacy, but no security and WPS then simulate */
20792157 /* setting AES. WPS-2.0 allows no security */
20802158 if (brcmf_find_wpsie (sme -> ie , sme -> ie_len ) && !pval && !gval &&
@@ -2087,6 +2165,15 @@ brcmf_set_wsec_mode(struct net_device *ndev,
20872165 bphy_err (drvr , "error (%d)\n" , err );
20882166 return err ;
20892167 }
2168+ if (brcmf_feat_is_enabled (ifp , BRCMF_FEAT_GCMP )) {
2169+ brcmf_dbg (CONN , "set_wsec_info algos (0x%x) mask (0x%x)\n" ,
2170+ algos , mask );
2171+ err = brcmf_set_wsec_info_algos (ifp , algos , mask );
2172+ if (err ) {
2173+ brcmf_err ("set wsec_info error (%d)\n" , err );
2174+ return err ;
2175+ }
2176+ }
20902177
20912178 sec = & profile -> sec ;
20922179 sec -> cipher_pairwise = sme -> crypto .ciphers_pairwise [0 ];
@@ -2798,6 +2885,8 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
27982885 s32 val ;
27992886 s32 wsec ;
28002887 s32 err ;
2888+ u32 algos = 0 ;
2889+ u32 mask = 0 ;
28012890 u8 keybuf [8 ];
28022891 bool ext_key ;
28032892
@@ -2881,6 +2970,30 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
28812970 val = AES_ENABLED ;
28822971 brcmf_dbg (CONN , "WLAN_CIPHER_SUITE_CCMP\n" );
28832972 break ;
2973+ case WLAN_CIPHER_SUITE_GCMP_256 :
2974+ if (!brcmf_feat_is_enabled (ifp , BRCMF_FEAT_GCMP )) {
2975+ brcmf_err ("the low layer not support GCMP\n" );
2976+ err = - EOPNOTSUPP ;
2977+ goto done ;
2978+ }
2979+ key -> algo = CRYPTO_ALGO_AES_GCM256 ;
2980+ val = AES_ENABLED ;
2981+ brcmf_dbg (CONN , "WLAN_CIPHER_SUITE_GCMP_256\n" );
2982+ algos = KEY_ALGO_MASK (CRYPTO_ALGO_AES_GCM256 );
2983+ mask = algos | KEY_ALGO_MASK (CRYPTO_ALGO_AES_CCM );
2984+ break ;
2985+ case WLAN_CIPHER_SUITE_BIP_GMAC_256 :
2986+ if (!brcmf_feat_is_enabled (ifp , BRCMF_FEAT_GCMP )) {
2987+ brcmf_err ("the low layer not support GCMP\n" );
2988+ err = - EOPNOTSUPP ;
2989+ goto done ;
2990+ }
2991+ key -> algo = CRYPTO_ALGO_BIP_GMAC256 ;
2992+ val = AES_ENABLED ;
2993+ algos = KEY_ALGO_MASK (CRYPTO_ALGO_BIP_GMAC256 );
2994+ mask = algos | KEY_ALGO_MASK (CRYPTO_ALGO_AES_CCM );
2995+ brcmf_dbg (CONN , "WLAN_CIPHER_SUITE_BIP_GMAC_256\n" );
2996+ break ;
28842997 default :
28852998 bphy_err (drvr , "Invalid cipher (0x%x)\n" , params -> cipher );
28862999 err = - EINVAL ;
@@ -2902,6 +3015,17 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
29023015 bphy_err (drvr , "set wsec error (%d)\n" , err );
29033016 goto done ;
29043017 }
3018+ if (brcmf_feat_is_enabled (ifp , BRCMF_FEAT_GCMP )) {
3019+ brcmf_dbg (CONN ,
3020+ "set_wsdec_info algos (0x%x) mask (0x%x)\n" ,
3021+ algos , mask );
3022+ err = brcmf_set_wsec_info_algos (ifp , algos , mask );
3023+ if (err ) {
3024+ brcmf_err ("set wsec_info error (%d)\n" , err );
3025+ return err ;
3026+ }
3027+ }
3028+
29053029
29063030done :
29073031 brcmf_dbg (TRACE , "Exit\n" );
0 commit comments