diff options
author | Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> | 2023-06-13 15:47:24 +0000 |
---|---|---|
committer | Android Partner Code Review <android-gerrit-partner@google.com> | 2023-06-13 15:47:24 +0000 |
commit | 3bb77cf9674d4ea45ecb773602ea90c98f91a1b4 (patch) | |
tree | 7c6a65f12cb602b174458e426c7504fd84d71a22 | |
parent | c8e0e92c75730b4dcced2d916d816ae7396f81f1 (diff) | |
parent | 697d630720e6fe4fa5c34501da4f89018616f38b (diff) | |
download | bcm4398-3bb77cf9674d4ea45ecb773602ea90c98f91a1b4.tar.gz |
Merge "bcmdhd: Fix connection failure reported with tplink wifi 7 AP" into android14-gs-pixel-5.15-udc-d1
-rw-r--r-- | wl_cfg80211.c | 75 | ||||
-rw-r--r-- | wl_cfg80211.h | 11 | ||||
-rw-r--r-- | wl_cfgvif.c | 70 | ||||
-rw-r--r-- | wl_cfgvif.h | 2 |
4 files changed, 127 insertions, 31 deletions
diff --git a/wl_cfg80211.c b/wl_cfg80211.c index 75a2b19..2f6c819 100644 --- a/wl_cfg80211.c +++ b/wl_cfg80211.c @@ -16106,17 +16106,20 @@ static s32 wl_update_bss_info(struct bcm_cfg80211 *cfg, struct net_device *ndev, return BCME_NOMEM; } + if (!target_bssid) { #ifdef WL_MLO - WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags); - mld_netinfo = _wl_get_netinfo_by_wdev(cfg, ndev->ieee80211_ptr); - if (mld_netinfo && mld_netinfo->mlinfo.num_links) { - /* copy for local use */ - (void)memcpy_s(&mlinfo, sizeof(mlinfo), &mld_netinfo->mlinfo, sizeof(mlinfo)); - ml_conn = TRUE; - num_links = mld_netinfo->mlinfo.num_links; - } - WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags); + WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags); + mld_netinfo = _wl_get_netinfo_by_wdev(cfg, ndev->ieee80211_ptr); + if (mld_netinfo && mld_netinfo->mlinfo.num_links) { + /* copy for local use */ + (void)memcpy_s(&mlinfo, sizeof(mlinfo), + &mld_netinfo->mlinfo, sizeof(mlinfo)); + ml_conn = TRUE; + num_links = mld_netinfo->mlinfo.num_links; + } + WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags); #endif /* WL_MLO */ + } mutex_lock(&cfg->usr_sync); for (index = 0; index < num_links; index++) { @@ -16127,8 +16130,9 @@ static s32 wl_update_bss_info(struct bcm_cfg80211 *cfg, struct net_device *ndev, * instance as even FW does not have peer link addr populated. */ if (target_bssid) { - WL_INFORM_MEM(("Update bssinfo for target bssid\n")); curbssid = target_bssid; + WL_INFORM_MEM(("Update bssinfo for target bssid " MACDBG "\n", + MAC2STRDBG(curbssid))); } else if (ml_conn) { #ifdef WL_MLO linkinfo = &mlinfo.links[index]; @@ -16158,7 +16162,8 @@ static s32 wl_update_bss_info(struct bcm_cfg80211 *cfg, struct net_device *ndev, } bi = (wl_bss_info_v109_t *)(buf + 4); chspec = wl_chspec_driver_to_host(bi->chanspec); - WL_INFORM_MEM(("link_idx %d chanspec %x\n", link_idx, chspec)); + WL_INFORM_MEM(("chanspec:0x%x\n band:%d chan:%d", chspec, CHSPEC_BAND(chspec), + wf_chspec_ctlchan(wl_chspec_driver_to_host(chspec)))); /* chanspec queried for ASSOCIATED BSSID needs to be valid */ if (!(target_bssid) && !wf_chspec_valid(chspec)) { WL_ERR(("Invalid chanspec from get bss info %x\n", chspec)); @@ -26583,24 +26588,9 @@ wl_notify_start_auth(struct bcm_cfg80211 *cfg, goto fail; } -#ifdef WL_MLO - if (cfg->mlo.supported && !ETHER_ISNULLADDR(e->addr.octet) && - memcmp(evt_data->bssid.octet, e->addr.octet, ETH_ALEN)) { - /* For MLO cases, e->addr would carry MLD address and incase - * MLD is different from link address, a bss entry needs to - * be created so that the host accepts the SAE AUTH indication. - * Without this WAR, host will ignore the event since MLD is not - * known to host yet. This WAR to be removed once user space and - * kernel is ML aware. - */ - WL_INFORM_MEM(("[MLO] Create MLD bss entry\n")); - wl_update_bss_info(cfg, ndev, false, evt_data->bssid.octet); - } else -#endif /* WL_MLO */ - if (wl_get_drv_status(cfg, CONNECTED, ndev)) { - /* Make sure bss_info is updated in roam case */ - wl_update_bss_info(cfg, ndev, false, evt_data->bssid.octet); - } + WL_INFORM(("evt_data->addr: " MACDBG " e->addr: " MACDBG "\n", + MAC2STRDBG(evt_data->bssid.octet), MAC2STRDBG(e->addr.octet))); + wl_update_bss_info(cfg, ndev, false, evt_data->bssid.octet); ext_auth_param.ssid.ssid_len = MIN(evt_data->ssid.SSID_len, DOT11_MAX_SSID_LEN); if (ext_auth_param.ssid.ssid_len) { @@ -26608,12 +26598,35 @@ wl_notify_start_auth(struct bcm_cfg80211 *cfg, evt_data->ssid.SSID, ext_auth_param.ssid.ssid_len); } - (void)memcpy_s(&ext_auth_param.bssid, ETHER_ADDR_LEN, &e->addr, ETHER_ADDR_LEN); + /* + * For MLO cases, e->addr would carry MLD address and in case + * MLD is different from link address, a bss entry needs to + * be created for non-ml aware kernels so that the host accepts + * the SAE AUTH indication. Without this WAR, host will ignore + * the event since MLD is unknown to host yet. + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)) || defined(WL_EXT_AUTH_BKPORT) + (void)memcpy_s(&ext_auth_param.mld_addr, ETHER_ADDR_LEN, e->addr.octet, ETHER_ADDR_LEN); + (void)memcpy_s(&ext_auth_param.bssid, + ETHER_ADDR_LEN, evt_data->bssid.octet, ETHER_ADDR_LEN); +#else + /* In non-ml aware kernels, use MLD address for auth ind for SAE PMK calc. */ + (void)memcpy_s(&ext_auth_param.bssid, ETHER_ADDR_LEN, e->addr.octet, ETHER_ADDR_LEN); + if (cfg->mlo.supported && !ETHER_ISNULLADDR(e->addr.octet) && + memcmp(evt_data->bssid.octet, e->addr.octet, ETH_ALEN)) { + /* report MLD address based bss for non ML aware external auth kernel I/F */ + if (wl_cfgvif_clone_bss_info(cfg, ndev, + evt_data->bssid.octet, (u8 *)e->addr.octet)) { + WL_ERR(("cfg80211_bss_info clone failed\n")); + /* fall through to attempt connection anyway */ + } + } +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)) || defined(WL_EXT_AUTH_BKPORT) */ ext_auth_param.action = NL80211_EXTERNAL_AUTH_START; ext_auth_param.key_mgmt_suite = ntoh32(WLAN_AKM_SUITE_SAE_SHA256); WL_INFORM_MEM(("call cfg80211_external_auth_request, BSSID:"MACDBG"\n", - MAC2STRDBG(&e->addr))); + MAC2STRDBG(&ext_auth_param.bssid))); wl_cfg80211_wdev_lock(wdev); err = cfg80211_external_auth_request(ndev, &ext_auth_param, GFP_KERNEL); diff --git a/wl_cfg80211.h b/wl_cfg80211.h index eea7d29..d7fa09f 100644 --- a/wl_cfg80211.h +++ b/wl_cfg80211.h @@ -405,6 +405,17 @@ extern char *dhd_log_dump_get_timestamp(void); #define WL_GCMP #endif /* (LINUX_VERSION > KERNEL_VERSION(4, 0, 0) && WL_GCMP_SUPPORT */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) || \ + (defined(CONFIG_ARCH_MSM) && defined(CFG80211_DISCONNECTED_V2)) +#define CFG80211_GET_BSS(wiphy, channel, bssid, ssid, ssid_len) \ + cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, \ + IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); +#else +#define CFG80211_GET_BSS(wiphy, channel, bssid, ssid, ssid_len) \ + cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, \ + WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) */ + #ifndef IBSS_COALESCE_ALLOWED #define IBSS_COALESCE_ALLOWED IBSS_COALESCE_DEFAULT #endif diff --git a/wl_cfgvif.c b/wl_cfgvif.c index dfb33a0..acd2951 100644 --- a/wl_cfgvif.c +++ b/wl_cfgvif.c @@ -8981,3 +8981,73 @@ exit: WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags); return found; } + +s32 +wl_cfgvif_clone_bss_info(struct bcm_cfg80211 *cfg, struct net_device *ndev, + u8 *src_bssid, u8 *target_bssid) +{ + struct cfg80211_bss *src_bss, *bss, *target_bss; + struct wiphy *wiphy; + s32 err = 0; + struct wlc_ssid *ssid; + u32 ftype; + + wiphy = bcmcfg_to_wiphy(cfg); + + if (!src_bssid || !target_bssid) { + WL_ERR(("invalid arg\n")); + return BCME_ERROR; + } + + ssid = (struct wlc_ssid *)wl_read_prof(cfg, ndev, WL_PROF_SSID); + if (!ssid) { + WL_ERR(("connection ssid null\n")); + return BCME_ERROR; + } + + target_bss = CFG80211_GET_BSS(wiphy, NULL, target_bssid, + NULL, 0); + if (target_bss) { + /* Entry already present for target bssid */ + WL_INFORM(("target bss found for bssid" MACDBG "\n", + MAC2STRDBG(target_bssid))); + CFG80211_PUT_BSS(wiphy, target_bss); + return BCME_OK; + } + + src_bss = CFG80211_GET_BSS(wiphy, NULL, src_bssid, + ssid->SSID, ssid->SSID_len); + if (!src_bss) { + WL_ERR(("No src bss found for bssid" MACDBG "\n", + MAC2STRDBG(src_bssid))); + return BCME_ERROR; + } + + + if (!src_bss->ies || !src_bss->ies->len) { + WL_ERR(("empty bss ies\n")); + err = BCME_NOMEM; + goto exit; + } + + ftype = src_bss->proberesp_ies ? + CFG80211_BSS_FTYPE_PRESP : CFG80211_BSS_FTYPE_BEACON; + + /* use same info to create a clone with the target bssid */ + bss = cfg80211_inform_bss(wiphy, src_bss->channel, + ftype, target_bssid, src_bss->ies->tsf, src_bss->capability, + src_bss->beacon_interval, (const u8 *)src_bss->ies->data, src_bss->ies->len, + src_bss->signal, GFP_KERNEL); + if (!bss) { + WL_ERR(("cfg8011_inform_bss failed\n")); + err = BCME_NOMEM; + goto exit; + } + CFG80211_PUT_BSS(wiphy, bss); + + WL_INFORM_MEM(("bss entry created for address:" MACDBG " freq:%d\n", + MAC2STRDBG(target_bssid), src_bss->channel->center_freq)); +exit: + CFG80211_PUT_BSS(wiphy, src_bss); + return err; +} diff --git a/wl_cfgvif.h b/wl_cfgvif.h index 8332987..9bd4314 100644 --- a/wl_cfgvif.h +++ b/wl_cfgvif.h @@ -313,4 +313,6 @@ extern s32 wl_cfgvif_set_multi_link(struct bcm_cfg80211 *cfg, u8 enable); extern s32 wl_cfgvif_get_multilink_status(struct bcm_cfg80211 *cfg, struct net_device *dev, u8 *status); bool wl_cfgvif_bssid_match_found(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev, u8 *mac_addr); +s32 wl_cfgvif_clone_bss_info(struct bcm_cfg80211 *cfg, + struct net_device *ndev, u8 *src_bssid, u8 *target_bssid); #endif /* _wl_cfgvif_h_ */ |