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 ,
@@ -5877,17 +5979,29 @@ static int brcmf_cfg80211_set_pmk(struct wiphy *wiphy, struct net_device *dev,
58775979 const struct cfg80211_pmk_conf * conf )
58785980{
58795981 struct brcmf_if * ifp ;
5880-
5982+ struct brcmf_pub * drvr ;
5983+ int ret ;
58815984 brcmf_dbg (TRACE , "enter\n" );
58825985
58835986 /* expect using firmware supplicant for 1X */
58845987 ifp = netdev_priv (dev );
5885- if (WARN_ON (ifp -> vif -> profile .use_fwsup != BRCMF_PROFILE_FWSUP_1X ))
5988+ drvr = ifp -> drvr ;
5989+ if (WARN_ON ((ifp -> vif -> profile .use_fwsup != BRCMF_PROFILE_FWSUP_1X ) &&
5990+ (ifp -> vif -> profile .use_fwsup != BRCMF_PROFILE_FWSUP_ROAM ) &&
5991+ (ifp -> vif -> profile .is_ft != true) &&
5992+ (ifp -> vif -> profile .is_okc != true)))
58865993 return - EINVAL ;
58875994
58885995 if (conf -> pmk_len > BRCMF_WSEC_MAX_PSK_LEN )
58895996 return - ERANGE ;
58905997
5998+ if (ifp -> vif -> profile .is_okc ) {
5999+ ret = brcmf_fil_iovar_data_set (ifp , "okc_info_pmk" , conf -> pmk ,
6000+ conf -> pmk_len );
6001+ if (ret < 0 )
6002+ bphy_err (drvr , "okc_info_pmk iovar failed: ret=%d\n" ,
6003+ ret );
6004+ }
58916005 return brcmf_set_pmk (ifp , conf -> pmk , conf -> pmk_len );
58926006}
58936007
@@ -6324,6 +6438,46 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
63246438 return err ;
63256439}
63266440
6441+ static bool brcmf_has_pmkid (const u8 * parse , u32 len )
6442+ {
6443+ const struct brcmf_tlv * rsn_ie ;
6444+ const u8 * ie ;
6445+ u32 ie_len ;
6446+ u32 offset ;
6447+ u16 count ;
6448+
6449+ rsn_ie = brcmf_parse_tlvs (parse , len , WLAN_EID_RSN );
6450+ if (!rsn_ie )
6451+ goto done ;
6452+ ie = (const u8 * )rsn_ie ;
6453+ ie_len = rsn_ie -> len + TLV_HDR_LEN ;
6454+ /* Skip group data cipher suite */
6455+ offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN ;
6456+ if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len )
6457+ goto done ;
6458+ /* Skip pairwise cipher suite(s) */
6459+ count = ie [offset ] + (ie [offset + 1 ] << 8 );
6460+ offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN );
6461+ if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len )
6462+ goto done ;
6463+ /* Skip auth key management suite(s) */
6464+ count = ie [offset ] + (ie [offset + 1 ] << 8 );
6465+ offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN );
6466+ if (offset + RSN_CAP_LEN >= ie_len )
6467+ goto done ;
6468+ /* Skip rsn capabilities */
6469+ offset += RSN_CAP_LEN ;
6470+ if (offset + RSN_PMKID_COUNT_LEN > ie_len )
6471+ goto done ;
6472+ /* Extract PMKID count */
6473+ count = ie [offset ] + (ie [offset + 1 ] << 8 );
6474+ if (count )
6475+ return true;
6476+
6477+ done :
6478+ return false;
6479+ }
6480+
63276481static s32
63286482brcmf_bss_roaming_done (struct brcmf_cfg80211_info * cfg ,
63296483 struct net_device * ndev ,
@@ -6394,11 +6548,16 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
63946548 cfg80211_roamed (ndev , & roam_info , GFP_KERNEL );
63956549 brcmf_dbg (CONN , "Report roaming result\n" );
63966550
6397- if (profile -> use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile -> is_ft ) {
6398- cfg80211_port_authorized (ndev , profile -> bssid , NULL , 0 , GFP_KERNEL );
6551+ if (((profile -> use_fwsup == BRCMF_PROFILE_FWSUP_1X ||
6552+ profile -> use_fwsup == BRCMF_PROFILE_FWSUP_ROAM ) &&
6553+ (brcmf_has_pmkid (roam_info .req_ie , roam_info .req_ie_len ) ||
6554+ profile -> is_ft || profile -> is_okc ))) {
6555+ cfg80211_port_authorized (ndev , profile -> bssid , NULL , 0 ,
6556+ GFP_KERNEL );
63996557 brcmf_dbg (CONN , "Report port authorized\n" );
64006558 }
64016559
6560+ clear_bit (BRCMF_VIF_STATUS_CONNECTING , & ifp -> vif -> sme_state );
64026561 set_bit (BRCMF_VIF_STATUS_CONNECTED , & ifp -> vif -> sme_state );
64036562 brcmf_dbg (TRACE , "Exit\n" );
64046563 return err ;
0 commit comments