qcacmn: Fix Connection issue when AP change from hidden to non-hidden

If AP change its status from hidden to broadcasting SSID in its beacon
kernel drop the beacon entry as its confusing. Now during connection
driver try to update the entry in kernel and it fails and as kernel drop
the beacon the connection fails.

To fix this detect if AP changed its ssid type from hidden to
broadcasting and unlink the old bss from kernel in that case.

Change-Id: I10ec42749ebcd2ddea23f7f3a94d862124df156d
CRs-Fixed: 2410430
This commit is contained in:
Abhishek Singh
2019-03-05 15:37:07 +05:30
committed by nshrivas
parent 5285b06fe5
commit 7062efab4c
6 changed files with 126 additions and 4 deletions

View File

@@ -261,6 +261,34 @@ wlan_cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev,
struct scan_cache_entry *scan_params);
/**
* wlan_cfg80211_get_bss() - Get the bss entry matching the chan, bssid and ssid
* @wiphy: wiphy
* @channel: channel of the BSS to find
* @bssid: bssid of the BSS to find
* @ssid: ssid of the BSS to find
* @ssid_len: ssid len of of the BSS to find
*
* The API is a wrapper to get bss from kernel matching the chan,
* bssid and ssid
*
* Return: bss structure if found else NULL
*/
struct cfg80211_bss *wlan_cfg80211_get_bss(struct wiphy *wiphy,
struct ieee80211_channel *channel,
const u8 *bssid,
const u8 *ssid, size_t ssid_len);
/*
* wlan_cfg80211_unlink_bss_list : flush bss from the kernel cache
* @pdev: Pointer to pdev
* @scan_entry: scan entry
*
* Return: bss which is unlinked from kernel cache
*/
void wlan_cfg80211_unlink_bss_list(struct wlan_objmgr_pdev *pdev,
struct scan_cache_entry *scan_entry);
/**
* wlan_vendor_abort_scan() - API to vendor abort scan
* @pdev: Pointer to pdev

View File

@@ -1936,6 +1936,57 @@ void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev,
qdf_mem_free(bss_data.mgmt);
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && \
!defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
struct cfg80211_bss *wlan_cfg80211_get_bss(struct wiphy *wiphy,
struct ieee80211_channel *channel,
const u8 *bssid, const u8 *ssid,
size_t ssid_len)
{
return cfg80211_get_bss(wiphy, channel, bssid,
ssid, ssid_len,
WLAN_CAPABILITY_ESS,
WLAN_CAPABILITY_ESS);
}
#else
struct cfg80211_bss *wlan_cfg80211_get_bss(struct wiphy *wiphy,
struct ieee80211_channel *channel,
const u8 *bssid, const u8 *ssid,
size_t ssid_len)
{
return cfg80211_get_bss(wiphy, channel, bssid,
ssid, ssid_len,
IEEE80211_BSS_TYPE_ESS,
IEEE80211_PRIVACY_ANY);
}
#endif
void wlan_cfg80211_unlink_bss_list(struct wlan_objmgr_pdev *pdev,
struct scan_cache_entry *scan_entry)
{
struct cfg80211_bss *bss = NULL;
struct pdev_osif_priv *pdev_ospriv = wlan_pdev_get_ospriv(pdev);
struct wiphy *wiphy;
if (!pdev_ospriv) {
cfg80211_err("os_priv is NULL");
return;
}
wiphy = pdev_ospriv->wiphy;
bss = wlan_cfg80211_get_bss(wiphy, NULL, scan_entry->bssid.bytes,
scan_entry->ssid.ssid,
scan_entry->ssid.length);
if (!bss) {
cfg80211_err("BSS %pM not found", scan_entry->bssid.bytes);
} else {
cfg80211_debug("cfg80211_unlink_bss called for BSSID %pM",
scan_entry->bssid.bytes);
cfg80211_unlink_bss(wiphy, bss);
wlan_cfg80211_put_bss(wiphy, bss);
}
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
/*
* wlan_scan_wiphy_set_max_sched_scans() - set maximum number of scheduled scans