6565#define RSN_CAP_MFPR_MASK BIT(6)
6666#define RSN_CAP_MFPC_MASK BIT(7)
6767#define RSN_PMKID_COUNT_LEN 2
68+ #define DPP_AKM_SUITE_TYPE 2
69+ #define WLAN_AKM_SUITE_DPP SUITE(WLAN_OUI_WFA, DPP_AKM_SUITE_TYPE)
6870
6971#define VNDR_IE_CMD_LEN 4 /* length of the set command
7072 * string :"add", "del" (+ NUL)
@@ -1841,15 +1843,20 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
18411843 struct brcmf_cfg80211_security * sec ;
18421844 s32 val = 0 ;
18431845 s32 err = 0 ;
1844-
1845- if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_1 )
1846+ if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_1 ) {
18461847 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED ;
1847- else if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_2 )
1848- val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED ;
1849- else if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_3 )
1848+ } else if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_2 ) {
1849+ if (sme -> crypto .akm_suites [0 ] == WLAN_AKM_SUITE_SAE )
1850+ val = WPA3_AUTH_SAE_PSK ;
1851+ else if (sme -> crypto .akm_suites [0 ] == WLAN_AKM_SUITE_OWE )
1852+ val = WPA3_AUTH_OWE ;
1853+ else
1854+ val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED ;
1855+ } else if (sme -> crypto .wpa_versions & NL80211_WPA_VERSION_3 ) {
18501856 val = WPA3_AUTH_SAE_PSK ;
1851- else
1857+ } else {
18521858 val = WPA_AUTH_DISABLED ;
1859+ }
18531860 brcmf_dbg (CONN , "setting wpa_auth to 0x%0x\n" , val );
18541861 err = brcmf_fil_bsscfg_int_set (ifp , "wpa_auth" , val );
18551862 if (err ) {
@@ -2064,9 +2071,13 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
20642071 u16 rsn_cap ;
20652072 u32 mfp ;
20662073 u16 count ;
2074+ s32 okc_enable ;
2075+ u16 pmkid_count ;
2076+ const u8 * group_mgmt_cs = NULL ;
20672077
20682078 profile -> use_fwsup = BRCMF_PROFILE_FWSUP_NONE ;
20692079 profile -> is_ft = false;
2080+ profile -> is_okc = false;
20702081
20712082 if (!sme -> crypto .n_akm_suites )
20722083 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 ) {
@@ -2141,16 +2179,35 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
21412179 profile -> use_fwsup = BRCMF_PROFILE_FWSUP_SAE ;
21422180 }
21432181 break ;
2144- default :
2145- bphy_err (drvr , "invalid akm suite (%d)\n" ,
2146- sme -> crypto .akm_suites [ 0 ] );
2182+ default :
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 ,
@@ -2454,7 +2556,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
24542556 goto done ;
24552557 }
24562558 err = brcmf_set_sae_password (ifp , params -> crypto .sae_pwd ,
2457- params -> crypto .sae_pwd_len );
2559+ params -> crypto .sae_pwd_len );
24582560 if (!err && params -> crypto .psk )
24592561 err = brcmf_set_pmk (ifp , params -> crypto .psk ,
24602562 BRCMF_WSEC_MAX_PSK_LEN );
@@ -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