6666#define RSN_CAP_MFPR_MASK BIT(6)
6767#define RSN_CAP_MFPC_MASK BIT(7)
6868#define RSN_PMKID_COUNT_LEN 2
69+ #define DPP_AKM_SUITE_TYPE 2
70+ #define WLAN_AKM_SUITE_DPP SUITE(WLAN_OUI_WFA, DPP_AKM_SUITE_TYPE)
6971
7072#define VNDR_IE_CMD_LEN 4 /* length of the set command
7173 * string :"add", "del" (+ NUL)
@@ -1836,15 +1838,20 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
18361838 struct brcmf_cfg80211_security * sec ;
18371839 s32 val = 0 ;
18381840 s32 err = 0 ;
1839-
1840- if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_1 )
1841+ if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_1 ) {
18411842 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED ;
1842- else if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_2 )
1843- val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED ;
1844- else if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_3 )
1843+ } else if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_2 ) {
1844+ if (sme -> crypto .akm_suites [0 ] == WLAN_AKM_SUITE_SAE )
1845+ val = WPA3_AUTH_SAE_PSK ;
1846+ else if (sme -> crypto .akm_suites [0 ] == WLAN_AKM_SUITE_OWE )
1847+ val = WPA3_AUTH_OWE ;
1848+ else
1849+ val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED ;
1850+ } else if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_3 ) {
18451851 val = WPA3_AUTH_SAE_PSK ;
1846- else
1852+ } else {
18471853 val = WPA_AUTH_DISABLED ;
1854+ }
18481855 brcmf_dbg (CONN , "setting wpa_auth to 0x%0x\n" , val );
18491856 err = brcmf_fil_bsscfg_int_set (ifp , "wpa_auth" , val );
18501857 if (err ) {
@@ -2059,9 +2066,13 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
20592066 u16 rsn_cap ;
20602067 u32 mfp ;
20612068 u16 count ;
2069+ s32 okc_enable ;
2070+ u16 pmkid_count ;
2071+ const u8 * group_mgmt_cs = NULL ;
20622072
20632073 profile -> use_fwsup = BRCMF_PROFILE_FWSUP_NONE ;
20642074 profile -> is_ft = false;
2075+ profile -> is_okc = false;
20652076
20662077 if (!sme -> crypto .n_akm_suites )
20672078 return 0 ;
@@ -2077,13 +2088,15 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
20772088 val = WPA_AUTH_UNSPECIFIED ;
20782089 if (sme -> want_1x )
20792090 profile -> use_fwsup = BRCMF_PROFILE_FWSUP_1X ;
2091+ else
2092+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_ROAM ;
20802093 break ;
20812094 case WLAN_AKM_SUITE_PSK :
20822095 val = WPA_AUTH_PSK ;
20832096 break ;
20842097 default :
2085- bphy_err (drvr , "invalid akm suite (%d)\n" ,
2086- sme -> crypto .akm_suites [ 0 ] );
2098+ bphy_err (drvr , "invalid cipher group (%d)\n" ,
2099+ sme -> crypto .cipher_group );
20872100 return - EINVAL ;
20882101 }
20892102 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED )) {
@@ -2092,11 +2105,15 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
20922105 val = WPA2_AUTH_UNSPECIFIED ;
20932106 if (sme -> want_1x )
20942107 profile -> use_fwsup = BRCMF_PROFILE_FWSUP_1X ;
2108+ else
2109+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_ROAM ;
20952110 break ;
20962111 case WLAN_AKM_SUITE_8021X_SHA256 :
20972112 val = WPA2_AUTH_1X_SHA256 ;
20982113 if (sme -> want_1x )
20992114 profile -> use_fwsup = BRCMF_PROFILE_FWSUP_1X ;
2115+ else
2116+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_ROAM ;
21002117 break ;
21012118 case WLAN_AKM_SUITE_PSK_SHA256 :
21022119 val = WPA2_AUTH_PSK_SHA256 ;
@@ -2109,14 +2126,35 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
21092126 profile -> is_ft = true;
21102127 if (sme -> want_1x )
21112128 profile -> use_fwsup = BRCMF_PROFILE_FWSUP_1X ;
2129+ else
2130+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_ROAM ;
21122131 break ;
21132132 case WLAN_AKM_SUITE_FT_PSK :
21142133 val = WPA2_AUTH_PSK | WPA2_AUTH_FT ;
21152134 profile -> is_ft = true;
2135+ if (brcmf_feat_is_enabled (ifp , BRCMF_FEAT_FWSUP ))
2136+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_PSK ;
2137+ else
2138+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_ROAM ;
2139+ break ;
2140+ case WLAN_AKM_SUITE_DPP :
2141+ val = WFA_AUTH_DPP ;
2142+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_NONE ;
2143+ break ;
2144+ case WLAN_AKM_SUITE_OWE :
2145+ val = WPA3_AUTH_OWE ;
2146+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_ROAM ;
2147+ break ;
2148+ case WLAN_AKM_SUITE_8021X_SUITE_B_192 :
2149+ val = WPA3_AUTH_1X_SUITE_B_SHA384 ;
2150+ if (sme -> want_1x )
2151+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_1X ;
2152+ else
2153+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_ROAM ;
21162154 break ;
21172155 default :
2118- bphy_err (drvr , "invalid akm suite (%d)\n" ,
2119- sme -> crypto .akm_suites [ 0 ] );
2156+ bphy_err (drvr , "invalid cipher group (%d)\n" ,
2157+ sme -> crypto .cipher_group );
21202158 return - EINVAL ;
21212159 }
21222160 } else if (val & WPA3_AUTH_SAE_PSK ) {
@@ -2137,15 +2175,34 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
21372175 }
21382176 break ;
21392177 default :
2140- bphy_err (drvr , "invalid akm suite (%d)\n" ,
2141- sme -> crypto .akm_suites [ 0 ] );
2178+ bphy_err (drvr , "invalid cipher group (%d)\n" ,
2179+ sme -> crypto .cipher_group );
21422180 return - EINVAL ;
21432181 }
21442182 }
2145-
2146- if (profile -> use_fwsup == BRCMF_PROFILE_FWSUP_1X )
2183+ if (( profile -> use_fwsup == BRCMF_PROFILE_FWSUP_1X ) ||
2184+ (profile -> use_fwsup == BRCMF_PROFILE_FWSUP_ROAM )) {
21472185 brcmf_dbg (INFO , "using 1X offload\n" );
2148-
2186+ err = brcmf_fil_bsscfg_int_get (netdev_priv (ndev ), "okc_enable" ,
2187+ & okc_enable );
2188+ if (err ) {
2189+ bphy_err (drvr , "get okc_enable failed (%d)\n" , err );
2190+ } else {
2191+ brcmf_dbg (INFO , "get okc_enable (%d)\n" , okc_enable );
2192+ profile -> is_okc = okc_enable ;
2193+ }
2194+ } else if (profile -> use_fwsup != BRCMF_PROFILE_FWSUP_SAE &&
2195+ (val == WPA3_AUTH_SAE_PSK )) {
2196+ brcmf_dbg (INFO , "not using SAE offload\n" );
2197+ err = brcmf_fil_bsscfg_int_get (netdev_priv (ndev ), "okc_enable" ,
2198+ & okc_enable );
2199+ if (err ) {
2200+ bphy_err (drvr , "get okc_enable failed (%d)\n" , err );
2201+ } else {
2202+ brcmf_dbg (INFO , "get okc_enable (%d)\n" , okc_enable );
2203+ profile -> is_okc = okc_enable ;
2204+ }
2205+ }
21492206 if (!brcmf_feat_is_enabled (ifp , BRCMF_FEAT_MFP ))
21502207 goto skip_mfp_config ;
21512208 /* The MFP mode (1 or 2) needs to be determined, parse IEs. The
@@ -2178,14 +2235,47 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
21782235 mfp = BRCMF_MFP_REQUIRED ;
21792236 else if (rsn_cap & RSN_CAP_MFPC_MASK )
21802237 mfp = BRCMF_MFP_CAPABLE ;
2238+ /* In case of dpp, very low tput is observed if MFPC is set in
2239+ * firmmare. Firmware needs to ensure that MFPC is not set when
2240+ * MFPR was requested from fmac. However since this change being
2241+ * specific to DPP, fmac needs to set wpa_auth prior to mfp, so
2242+ * that firmware can use this info to prevent MFPC being set in
2243+ * case of dpp.
2244+ */
2245+ if (val == WFA_AUTH_DPP ) {
2246+ brcmf_dbg (CONN , "setting wpa_auth to 0x%0x\n" , val );
2247+ err = brcmf_fil_bsscfg_int_set (netdev_priv (ndev ), "wpa_auth" ,
2248+ val );
2249+ if (err ) {
2250+ bphy_err (drvr , "could not set wpa_auth (%d)\n" , err );
2251+ return err ;
2252+ }
2253+ }
2254+
21812255 brcmf_fil_bsscfg_int_set (netdev_priv (ndev ), "mfp" , mfp );
2256+ offset += RSN_CAP_LEN ;
2257+ if (mfp && (ie_len - offset >= RSN_PMKID_COUNT_LEN )) {
2258+ pmkid_count = ie [offset ] + (ie [offset + 1 ] << 8 );
2259+ offset += RSN_PMKID_COUNT_LEN + (pmkid_count * WLAN_PMKID_LEN );
2260+ if (ie_len - offset >= WPA_IE_MIN_OUI_LEN ) {
2261+ group_mgmt_cs = & ie [offset ];
2262+ if (memcmp (group_mgmt_cs , RSN_OUI , TLV_OUI_LEN ) == 0 ) {
2263+ brcmf_fil_bsscfg_data_set (ifp , "bip" ,
2264+ (void * )group_mgmt_cs ,
2265+ WPA_IE_MIN_OUI_LEN );
2266+ }
2267+ }
2268+ }
21822269
21832270skip_mfp_config :
2184- brcmf_dbg (CONN , "setting wpa_auth to %d\n" , val );
2185- err = brcmf_fil_bsscfg_int_set (netdev_priv (ndev ), "wpa_auth" , val );
2186- if (err ) {
2187- bphy_err (drvr , "could not set wpa_auth (%d)\n" , err );
2188- return err ;
2271+ if (val != WFA_AUTH_DPP ) {
2272+ brcmf_dbg (CONN , "setting wpa_auth to 0x%0x\n" , val );
2273+ err = brcmf_fil_bsscfg_int_set (netdev_priv (ndev ), "wpa_auth" ,
2274+ val );
2275+ if (err ) {
2276+ bphy_err (drvr , "could not set wpa_auth (%d)\n" , err );
2277+ return err ;
2278+ }
21892279 }
21902280
21912281 return err ;
@@ -2436,6 +2526,18 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
24362526 }
24372527 }
24382528
2529+ if (profile -> use_fwsup != BRCMF_PROFILE_FWSUP_NONE ) {
2530+ /* enable firmware supplicant for this interface */
2531+ err = brcmf_fil_iovar_int_set (ifp , "sup_wpa" , 1 );
2532+ if (err < 0 ) {
2533+ bphy_err (drvr ,
2534+ "failed to enable fw supplicant\n" );
2535+ goto done ;
2536+ }
2537+ } else {
2538+ err = brcmf_fil_iovar_int_set (ifp , "sup_wpa" , 0 );
2539+ }
2540+
24392541 if ((profile -> use_fwsup == BRCMF_PROFILE_FWSUP_PSK ) &&
24402542 params -> crypto .psk )
24412543 err = brcmf_set_pmk (ifp , params -> crypto .psk ,
@@ -5870,17 +5972,29 @@ static int brcmf_cfg80211_set_pmk(struct wiphy *wiphy, struct net_device *dev,
58705972 const struct cfg80211_pmk_conf * conf )
58715973{
58725974 struct brcmf_if * ifp ;
5873-
5975+ struct brcmf_pub * drvr ;
5976+ int ret ;
58745977 brcmf_dbg (TRACE , "enter\n" );
58755978
58765979 /* expect using firmware supplicant for 1X */
58775980 ifp = netdev_priv (dev );
5878- if (WARN_ON (ifp -> vif -> profile .use_fwsup != BRCMF_PROFILE_FWSUP_1X ))
5981+ drvr = ifp -> drvr ;
5982+ if (WARN_ON ((ifp -> vif -> profile .use_fwsup != BRCMF_PROFILE_FWSUP_1X ) &&
5983+ (ifp -> vif -> profile .use_fwsup != BRCMF_PROFILE_FWSUP_ROAM ) &&
5984+ (ifp -> vif -> profile .is_ft != true) &&
5985+ (ifp -> vif -> profile .is_okc != true)))
58795986 return - EINVAL ;
58805987
58815988 if (conf -> pmk_len > BRCMF_WSEC_MAX_PSK_LEN )
58825989 return - ERANGE ;
58835990
5991+ if (ifp -> vif -> profile .is_okc ) {
5992+ ret = brcmf_fil_iovar_data_set (ifp , "okc_info_pmk" , conf -> pmk ,
5993+ conf -> pmk_len );
5994+ if (ret < 0 )
5995+ bphy_err (drvr , "okc_info_pmk iovar failed: ret=%d\n" ,
5996+ ret );
5997+ }
58845998 return brcmf_set_pmk (ifp , conf -> pmk , conf -> pmk_len );
58855999}
58866000
@@ -6317,6 +6431,46 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
63176431 return err ;
63186432}
63196433
6434+ static bool brcmf_has_pmkid (const u8 * parse , u32 len )
6435+ {
6436+ const struct brcmf_tlv * rsn_ie ;
6437+ const u8 * ie ;
6438+ u32 ie_len ;
6439+ u32 offset ;
6440+ u16 count ;
6441+
6442+ rsn_ie = brcmf_parse_tlvs (parse , len , WLAN_EID_RSN );
6443+ if (!rsn_ie )
6444+ goto done ;
6445+ ie = (const u8 * )rsn_ie ;
6446+ ie_len = rsn_ie -> len + TLV_HDR_LEN ;
6447+ /* Skip group data cipher suite */
6448+ offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN ;
6449+ if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len )
6450+ goto done ;
6451+ /* Skip pairwise cipher suite(s) */
6452+ count = ie [offset ] + (ie [offset + 1 ] << 8 );
6453+ offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN );
6454+ if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len )
6455+ goto done ;
6456+ /* Skip auth key management suite(s) */
6457+ count = ie [offset ] + (ie [offset + 1 ] << 8 );
6458+ offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN );
6459+ if (offset + RSN_CAP_LEN >= ie_len )
6460+ goto done ;
6461+ /* Skip rsn capabilities */
6462+ offset += RSN_CAP_LEN ;
6463+ if (offset + RSN_PMKID_COUNT_LEN > ie_len )
6464+ goto done ;
6465+ /* Extract PMKID count */
6466+ count = ie [offset ] + (ie [offset + 1 ] << 8 );
6467+ if (count )
6468+ return true;
6469+
6470+ done :
6471+ return false;
6472+ }
6473+
63206474static s32
63216475brcmf_bss_roaming_done (struct brcmf_cfg80211_info * cfg ,
63226476 struct net_device * ndev ,
@@ -6387,11 +6541,16 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
63876541 cfg80211_roamed (ndev , & roam_info , GFP_KERNEL );
63886542 brcmf_dbg (CONN , "Report roaming result\n" );
63896543
6390- if (profile -> use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile -> is_ft ) {
6391- cfg80211_port_authorized (ndev , profile -> bssid , NULL , 0 , GFP_KERNEL );
6544+ if (((profile -> use_fwsup == BRCMF_PROFILE_FWSUP_1X ||
6545+ profile -> use_fwsup == BRCMF_PROFILE_FWSUP_ROAM ) &&
6546+ (brcmf_has_pmkid (roam_info .req_ie , roam_info .req_ie_len ) ||
6547+ profile -> is_ft || profile -> is_okc ))) {
6548+ cfg80211_port_authorized (ndev , profile -> bssid , NULL , 0 ,
6549+ GFP_KERNEL );
63926550 brcmf_dbg (CONN , "Report port authorized\n" );
63936551 }
63946552
6553+ clear_bit (BRCMF_VIF_STATUS_CONNECTING , & ifp -> vif -> sme_state );
63956554 set_bit (BRCMF_VIF_STATUS_CONNECTED , & ifp -> vif -> sme_state );
63966555 brcmf_dbg (TRACE , "Exit\n" );
63976556 return err ;
0 commit comments