summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com>2023-06-13 15:47:24 +0000
committerAndroid Partner Code Review <android-gerrit-partner@google.com>2023-06-13 15:47:24 +0000
commit3bb77cf9674d4ea45ecb773602ea90c98f91a1b4 (patch)
tree7c6a65f12cb602b174458e426c7504fd84d71a22
parentc8e0e92c75730b4dcced2d916d816ae7396f81f1 (diff)
parent697d630720e6fe4fa5c34501da4f89018616f38b (diff)
downloadbcm4398-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.c75
-rw-r--r--wl_cfg80211.h11
-rw-r--r--wl_cfgvif.c70
-rw-r--r--wl_cfgvif.h2
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_ */