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)
@@ -1840,15 +1842,20 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
18401842 struct brcmf_cfg80211_security * sec ;
18411843 s32 val = 0 ;
18421844 s32 err = 0 ;
1843-
1844- if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_1 )
1845+ if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_1 ) {
18451846 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED ;
1846- else if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_2 )
1847- val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED ;
1848- else if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_3 )
1847+ } else if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_2 ) {
1848+ if (sme -> crypto .akm_suites [0 ] == WLAN_AKM_SUITE_SAE )
1849+ val = WPA3_AUTH_SAE_PSK ;
1850+ else if (sme -> crypto .akm_suites [0 ] == WLAN_AKM_SUITE_OWE )
1851+ val = WPA3_AUTH_OWE ;
1852+ else
1853+ val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED ;
1854+ } else if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_3 ) {
18491855 val = WPA3_AUTH_SAE_PSK ;
1850- else
1856+ } else {
18511857 val = WPA_AUTH_DISABLED ;
1858+ }
18521859 brcmf_dbg (CONN , "setting wpa_auth to 0x%0x\n" , val );
18531860 err = brcmf_fil_bsscfg_int_set (ifp , "wpa_auth" , val );
18541861 if (err ) {
@@ -2063,9 +2070,13 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
20632070 u16 rsn_cap ;
20642071 u32 mfp ;
20652072 u16 count ;
2073+ s32 okc_enable ;
2074+ u16 pmkid_count ;
2075+ const u8 * group_mgmt_cs = NULL ;
20662076
20672077 profile -> use_fwsup = BRCMF_PROFILE_FWSUP_NONE ;
20682078 profile -> is_ft = false;
2079+ profile -> is_okc = false;
20692080
20702081 if (!sme -> crypto .n_akm_suites )
20712082 return 0 ;
@@ -2082,13 +2093,15 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
20822093 val = WPA_AUTH_UNSPECIFIED ;
20832094 if (sme -> want_1x )
20842095 profile -> use_fwsup = BRCMF_PROFILE_FWSUP_1X ;
2096+ else
2097+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_ROAM ;
20852098 break ;
20862099 case WLAN_AKM_SUITE_PSK :
20872100 val = WPA_AUTH_PSK ;
20882101 break ;
20892102 default :
2090- bphy_err (drvr , "invalid akm suite (%d)\n" ,
2091- sme -> crypto .akm_suites [ 0 ] );
2103+ bphy_err (drvr , "invalid cipher group (%d)\n" ,
2104+ sme -> crypto .cipher_group );
20922105 return - EINVAL ;
20932106 }
20942107 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED )) {
@@ -2097,11 +2110,15 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
20972110 val = WPA2_AUTH_UNSPECIFIED ;
20982111 if (sme -> want_1x )
20992112 profile -> use_fwsup = BRCMF_PROFILE_FWSUP_1X ;
2113+ else
2114+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_ROAM ;
21002115 break ;
21012116 case WLAN_AKM_SUITE_8021X_SHA256 :
21022117 val = WPA2_AUTH_1X_SHA256 ;
21032118 if (sme -> want_1x )
21042119 profile -> use_fwsup = BRCMF_PROFILE_FWSUP_1X ;
2120+ else
2121+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_ROAM ;
21052122 break ;
21062123 case WLAN_AKM_SUITE_PSK_SHA256 :
21072124 val = WPA2_AUTH_PSK_SHA256 ;
@@ -2114,14 +2131,35 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
21142131 profile -> is_ft = true;
21152132 if (sme -> want_1x )
21162133 profile -> use_fwsup = BRCMF_PROFILE_FWSUP_1X ;
2134+ else
2135+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_ROAM ;
21172136 break ;
21182137 case WLAN_AKM_SUITE_FT_PSK :
21192138 val = WPA2_AUTH_PSK | WPA2_AUTH_FT ;
21202139 profile -> is_ft = true;
2140+ if (brcmf_feat_is_enabled (ifp , BRCMF_FEAT_FWSUP ))
2141+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_PSK ;
2142+ else
2143+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_ROAM ;
2144+ break ;
2145+ case WLAN_AKM_SUITE_DPP :
2146+ val = WFA_AUTH_DPP ;
2147+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_NONE ;
2148+ break ;
2149+ case WLAN_AKM_SUITE_OWE :
2150+ val = WPA3_AUTH_OWE ;
2151+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_ROAM ;
2152+ break ;
2153+ case WLAN_AKM_SUITE_8021X_SUITE_B_192 :
2154+ val = WPA3_AUTH_1X_SUITE_B_SHA384 ;
2155+ if (sme -> want_1x )
2156+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_1X ;
2157+ else
2158+ profile -> use_fwsup = BRCMF_PROFILE_FWSUP_ROAM ;
21212159 break ;
21222160 default :
2123- bphy_err (drvr , "invalid akm suite (%d)\n" ,
2124- sme -> crypto .akm_suites [ 0 ] );
2161+ bphy_err (drvr , "invalid cipher group (%d)\n" ,
2162+ sme -> crypto .cipher_group );
21252163 return - EINVAL ;
21262164 }
21272165 } else if (val & WPA3_AUTH_SAE_PSK ) {
@@ -2142,15 +2180,34 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
21422180 }
21432181 break ;
21442182 default :
2145- bphy_err (drvr , "invalid akm suite (%d)\n" ,
2146- sme -> crypto .akm_suites [ 0 ] );
2183+ bphy_err (drvr , "invalid cipher group (%d)\n" ,
2184+ sme -> crypto .cipher_group );
21472185 return - EINVAL ;
21482186 }
21492187 }
2150-
2151- if (profile -> use_fwsup == BRCMF_PROFILE_FWSUP_1X )
2188+ if (( profile -> use_fwsup == BRCMF_PROFILE_FWSUP_1X ) ||
2189+ (profile -> use_fwsup == BRCMF_PROFILE_FWSUP_ROAM )) {
21522190 brcmf_dbg (INFO , "using 1X offload\n" );
2153-
2191+ err = brcmf_fil_bsscfg_int_get (netdev_priv (ndev ), "okc_enable" ,
2192+ & okc_enable );
2193+ if (err ) {
2194+ bphy_err (drvr , "get okc_enable failed (%d)\n" , err );
2195+ } else {
2196+ brcmf_dbg (INFO , "get okc_enable (%d)\n" , okc_enable );
2197+ profile -> is_okc = okc_enable ;
2198+ }
2199+ } else if (profile -> use_fwsup != BRCMF_PROFILE_FWSUP_SAE &&
2200+ (val == WPA3_AUTH_SAE_PSK )) {
2201+ brcmf_dbg (INFO , "not using SAE offload\n" );
2202+ err = brcmf_fil_bsscfg_int_get (netdev_priv (ndev ), "okc_enable" ,
2203+ & okc_enable );
2204+ if (err ) {
2205+ bphy_err (drvr , "get okc_enable failed (%d)\n" , err );
2206+ } else {
2207+ brcmf_dbg (INFO , "get okc_enable (%d)\n" , okc_enable );
2208+ profile -> is_okc = okc_enable ;
2209+ }
2210+ }
21542211 if (!brcmf_feat_is_enabled (ifp , BRCMF_FEAT_MFP ))
21552212 goto skip_mfp_config ;
21562213 /* The MFP mode (1 or 2) needs to be determined, parse IEs. The
@@ -2183,14 +2240,47 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
21832240 mfp = BRCMF_MFP_REQUIRED ;
21842241 else if (rsn_cap & RSN_CAP_MFPC_MASK )
21852242 mfp = BRCMF_MFP_CAPABLE ;
2243+ /* In case of dpp, very low tput is observed if MFPC is set in
2244+ * firmmare. Firmware needs to ensure that MFPC is not set when
2245+ * MFPR was requested from fmac. However since this change being
2246+ * specific to DPP, fmac needs to set wpa_auth prior to mfp, so
2247+ * that firmware can use this info to prevent MFPC being set in
2248+ * case of dpp.
2249+ */
2250+ if (val == WFA_AUTH_DPP ) {
2251+ brcmf_dbg (CONN , "setting wpa_auth to 0x%0x\n" , val );
2252+ err = brcmf_fil_bsscfg_int_set (netdev_priv (ndev ), "wpa_auth" ,
2253+ val );
2254+ if (err ) {
2255+ bphy_err (drvr , "could not set wpa_auth (%d)\n" , err );
2256+ return err ;
2257+ }
2258+ }
2259+
21862260 brcmf_fil_bsscfg_int_set (netdev_priv (ndev ), "mfp" , mfp );
2261+ offset += RSN_CAP_LEN ;
2262+ if (mfp && (ie_len - offset >= RSN_PMKID_COUNT_LEN )) {
2263+ pmkid_count = ie [offset ] + (ie [offset + 1 ] << 8 );
2264+ offset += RSN_PMKID_COUNT_LEN + (pmkid_count * WLAN_PMKID_LEN );
2265+ if (ie_len - offset >= WPA_IE_MIN_OUI_LEN ) {
2266+ group_mgmt_cs = & ie [offset ];
2267+ if (memcmp (group_mgmt_cs , RSN_OUI , TLV_OUI_LEN ) == 0 ) {
2268+ brcmf_fil_bsscfg_data_set (ifp , "bip" ,
2269+ (void * )group_mgmt_cs ,
2270+ WPA_IE_MIN_OUI_LEN );
2271+ }
2272+ }
2273+ }
21872274
21882275skip_mfp_config :
2189- brcmf_dbg (CONN , "setting wpa_auth to %d\n" , val );
2190- err = brcmf_fil_bsscfg_int_set (netdev_priv (ndev ), "wpa_auth" , val );
2191- if (err ) {
2192- bphy_err (drvr , "could not set wpa_auth (%d)\n" , err );
2193- return err ;
2276+ if (val != WFA_AUTH_DPP ) {
2277+ brcmf_dbg (CONN , "setting wpa_auth to 0x%0x\n" , val );
2278+ err = brcmf_fil_bsscfg_int_set (netdev_priv (ndev ), "wpa_auth" ,
2279+ val );
2280+ if (err ) {
2281+ bphy_err (drvr , "could not set wpa_auth (%d)\n" , err );
2282+ return err ;
2283+ }
21942284 }
21952285
21962286 return err ;
@@ -2441,6 +2531,18 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
24412531 }
24422532 }
24432533
2534+ if (profile -> use_fwsup != BRCMF_PROFILE_FWSUP_NONE ) {
2535+ /* enable firmware supplicant for this interface */
2536+ err = brcmf_fil_iovar_int_set (ifp , "sup_wpa" , 1 );
2537+ if (err < 0 ) {
2538+ bphy_err (drvr ,
2539+ "failed to enable fw supplicant\n" );
2540+ goto done ;
2541+ }
2542+ } else {
2543+ err = brcmf_fil_iovar_int_set (ifp , "sup_wpa" , 0 );
2544+ }
2545+
24442546 if ((profile -> use_fwsup == BRCMF_PROFILE_FWSUP_PSK ) &&
24452547 params -> crypto .psk )
24462548 err = brcmf_set_pmk (ifp , params -> crypto .psk ,
@@ -5886,17 +5988,29 @@ static int brcmf_cfg80211_set_pmk(struct wiphy *wiphy, struct net_device *dev,
58865988 const struct cfg80211_pmk_conf * conf )
58875989{
58885990 struct brcmf_if * ifp ;
5889-
5991+ struct brcmf_pub * drvr ;
5992+ int ret ;
58905993 brcmf_dbg (TRACE , "enter\n" );
58915994
58925995 /* expect using firmware supplicant for 1X */
58935996 ifp = netdev_priv (dev );
5894- if (WARN_ON (ifp -> vif -> profile .use_fwsup != BRCMF_PROFILE_FWSUP_1X ))
5997+ drvr = ifp -> drvr ;
5998+ if (WARN_ON ((ifp -> vif -> profile .use_fwsup != BRCMF_PROFILE_FWSUP_1X ) &&
5999+ (ifp -> vif -> profile .use_fwsup != BRCMF_PROFILE_FWSUP_ROAM ) &&
6000+ (ifp -> vif -> profile .is_ft != true) &&
6001+ (ifp -> vif -> profile .is_okc != true)))
58956002 return - EINVAL ;
58966003
58976004 if (conf -> pmk_len > BRCMF_WSEC_MAX_PSK_LEN )
58986005 return - ERANGE ;
58996006
6007+ if (ifp -> vif -> profile .is_okc ) {
6008+ ret = brcmf_fil_iovar_data_set (ifp , "okc_info_pmk" , conf -> pmk ,
6009+ conf -> pmk_len );
6010+ if (ret < 0 )
6011+ bphy_err (drvr , "okc_info_pmk iovar failed: ret=%d\n" ,
6012+ ret );
6013+ }
59006014 return brcmf_set_pmk (ifp , conf -> pmk , conf -> pmk_len );
59016015}
59026016
@@ -6333,6 +6447,46 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
63336447 return err ;
63346448}
63356449
6450+ static bool brcmf_has_pmkid (const u8 * parse , u32 len )
6451+ {
6452+ const struct brcmf_tlv * rsn_ie ;
6453+ const u8 * ie ;
6454+ u32 ie_len ;
6455+ u32 offset ;
6456+ u16 count ;
6457+
6458+ rsn_ie = brcmf_parse_tlvs (parse , len , WLAN_EID_RSN );
6459+ if (!rsn_ie )
6460+ goto done ;
6461+ ie = (const u8 * )rsn_ie ;
6462+ ie_len = rsn_ie -> len + TLV_HDR_LEN ;
6463+ /* Skip group data cipher suite */
6464+ offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN ;
6465+ if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len )
6466+ goto done ;
6467+ /* Skip pairwise cipher suite(s) */
6468+ count = ie [offset ] + (ie [offset + 1 ] << 8 );
6469+ offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN );
6470+ if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len )
6471+ goto done ;
6472+ /* Skip auth key management suite(s) */
6473+ count = ie [offset ] + (ie [offset + 1 ] << 8 );
6474+ offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN );
6475+ if (offset + RSN_CAP_LEN >= ie_len )
6476+ goto done ;
6477+ /* Skip rsn capabilities */
6478+ offset += RSN_CAP_LEN ;
6479+ if (offset + RSN_PMKID_COUNT_LEN > ie_len )
6480+ goto done ;
6481+ /* Extract PMKID count */
6482+ count = ie [offset ] + (ie [offset + 1 ] << 8 );
6483+ if (count )
6484+ return true;
6485+
6486+ done :
6487+ return false;
6488+ }
6489+
63366490static s32
63376491brcmf_bss_roaming_done (struct brcmf_cfg80211_info * cfg ,
63386492 struct net_device * ndev ,
@@ -6403,11 +6557,16 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
64036557 cfg80211_roamed (ndev , & roam_info , GFP_KERNEL );
64046558 brcmf_dbg (CONN , "Report roaming result\n" );
64056559
6406- if (profile -> use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile -> is_ft ) {
6407- cfg80211_port_authorized (ndev , profile -> bssid , NULL , 0 , GFP_KERNEL );
6560+ if (((profile -> use_fwsup == BRCMF_PROFILE_FWSUP_1X ||
6561+ profile -> use_fwsup == BRCMF_PROFILE_FWSUP_ROAM ) &&
6562+ (brcmf_has_pmkid (roam_info .req_ie , roam_info .req_ie_len ) ||
6563+ profile -> is_ft || profile -> is_okc ))) {
6564+ cfg80211_port_authorized (ndev , profile -> bssid , NULL , 0 ,
6565+ GFP_KERNEL );
64086566 brcmf_dbg (CONN , "Report port authorized\n" );
64096567 }
64106568
6569+ clear_bit (BRCMF_VIF_STATUS_CONNECTING , & ifp -> vif -> sme_state );
64116570 set_bit (BRCMF_VIF_STATUS_CONNECTED , & ifp -> vif -> sme_state );
64126571 brcmf_dbg (TRACE , "Exit\n" );
64136572 return err ;
0 commit comments