diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 82ffec3376fe..109cd03a0cb8 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -799,6 +799,8 @@ typedef struct hdd_scaninfo_s { /* Additional IE for scan */ tSirAddie scanAddIE; + uint8_t *default_scan_ies; + uint8_t default_scan_ies_len; /* Scan mode */ tSirScanType scan_mode; diff --git a/core/hdd/inc/wlan_hdd_wext.h b/core/hdd/inc/wlan_hdd_wext.h index eee4f440f022..8829dfa07b78 100644 --- a/core/hdd/inc/wlan_hdd_wext.h +++ b/core/hdd/inc/wlan_hdd_wext.h @@ -291,6 +291,8 @@ typedef struct ccp_freq_chan_map_s { wlan_hdd_get_vendor_oui_ie_ptr(WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE, ie, ie_len) #endif +#define wlan_hdd_get_mbo_ie_ptr(ie, ie_len) \ + wlan_hdd_get_vendor_oui_ie_ptr(MBO_OUI_TYPE, MBO_OUI_TYPE_SIZE, ie, ie_len) /* * Defines for fw_test command */ diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 16209c795854..f60551c32523 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -3871,6 +3871,35 @@ wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = { [QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND] = {.type = NLA_U8 }, }; +/** + * wlan_hdd_save_default_scan_ies() - API to store the default scan IEs + * + * @adapter: Pointer to HDD adapter + * @ie_data: Pointer to Scan IEs buffer + * @ie_len: Length of Scan IEs + * + * Return: 0 on success; error number otherwise + */ +static int wlan_hdd_save_default_scan_ies(hdd_adapter_t *adapter, + uint8_t *ie_data, uint8_t ie_len) +{ + hdd_scaninfo_t *scan_info = NULL; + scan_info = &adapter->scan_info; + + if (scan_info->default_scan_ies) { + qdf_mem_free(scan_info->default_scan_ies); + scan_info->default_scan_ies = NULL; + } + + scan_info->default_scan_ies = qdf_mem_malloc(ie_len); + if (!scan_info->default_scan_ies) + return -ENOMEM; + + memcpy(scan_info->default_scan_ies, ie_data, ie_len); + scan_info->default_scan_ies_len = ie_len; + return 0; +} + /** * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration * vendor command @@ -4051,6 +4080,11 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy, if (scan_ie_len && (scan_ie_len <= MAX_DEFAULT_SCAN_IE_LEN)) { scan_ie = (uint8_t *) nla_data(tb [QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES]); + + if (wlan_hdd_save_default_scan_ies(adapter, scan_ie, + scan_ie_len)) + hdd_err("Failed to save default scan IEs"); + if (adapter->device_mode == QDF_STA_MODE) { status = sme_set_default_scan_ie(hdd_ctx->hHal, adapter->sessionId, scan_ie, diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 69d164663f4e..65d40ea06b84 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -2841,6 +2841,12 @@ void hdd_cleanup_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter, } hdd_debugfs_exit(adapter); + + if (adapter->scan_info.default_scan_ies) { + qdf_mem_free(adapter->scan_info.default_scan_ies); + adapter->scan_info.default_scan_ies = NULL; + } + /* * The adapter is marked as closed. When hdd_wlan_exit() call returns, * the driver is almost closed and cannot handle either control diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index e05610d09846..e063008d9091 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/core/hdd/src/wlan_hdd_scan.c @@ -1284,6 +1284,59 @@ static inline void wlan_hdd_copy_bssid_scan_request(tCsrScanRequest *scan_req, } #endif +/* + * wlan_hdd_update_scan_ies() - API to update the scan IEs of scan request + * with already stored default scan IEs + * + * @adapter: Pointer to HDD adapter + * @scan_info: Pointer to scan info in HDD adapter + * @scan_ie: Pointer to scan IE in scan request + * @scan_ie_len: Pointer to scan IE length in scan request + * + * Return: 0 on success; error number otherwise + */ +static int wlan_hdd_update_scan_ies(hdd_adapter_t *adapter, + hdd_scaninfo_t *scan_info, uint8_t *scan_ie, + uint8_t *scan_ie_len) +{ + uint8_t rem_len = scan_info->default_scan_ies_len; + uint8_t *temp_ie = scan_info->default_scan_ies; + uint8_t *current_ie; + uint8_t elem_id; + uint16_t elem_len; + + if (!scan_info->default_scan_ies_len || !scan_info->default_scan_ies) + return -EINVAL; + + while (rem_len >= 2) { + current_ie = temp_ie; + elem_id = *temp_ie++; + elem_len = *temp_ie++; + rem_len -= 2; + + switch (elem_id) { + case DOT11F_EID_EXTCAP: + if (!wlan_hdd_cfg80211_get_ie_ptr(scan_ie, *scan_ie_len, + DOT11F_EID_EXTCAP)) { + qdf_mem_copy(scan_ie + (*scan_ie_len), + current_ie, elem_len + 2); + (*scan_ie_len) += (elem_len + 2); + } + break; + case DOT11F_EID_WPA: + if (!wlan_hdd_get_mbo_ie_ptr(scan_ie, *scan_ie_len)) { + qdf_mem_copy(scan_ie + (*scan_ie_len), + current_ie, elem_len + 2); + (*scan_ie_len) += (elem_len + 2); + } + break; + } + temp_ie += elem_len; + rem_len -= elem_len; + } + return 0; +} + /** * __wlan_hdd_cfg80211_scan() - API to process cfg80211 scan request * @wiphy: Pointer to wiphy @@ -1545,6 +1598,11 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, request->ie_len); pScanInfo->scanAddIE.length = request->ie_len; + if (wlan_hdd_update_scan_ies(pAdapter, pScanInfo, + pScanInfo->scanAddIE.addIEdata, + (uint8_t *)&pScanInfo->scanAddIE.length)) + hdd_err("Update scan IEs with default Scan IEs failed"); + if ((QDF_STA_MODE == pAdapter->device_mode) || (QDF_P2P_CLIENT_MODE == pAdapter->device_mode) || (QDF_P2P_DEVICE_MODE == pAdapter->device_mode) @@ -1606,6 +1664,15 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, } } + } else { + if (pScanInfo->default_scan_ies && + pScanInfo->default_scan_ies_len) { + qdf_mem_copy(pScanInfo->scanAddIE.addIEdata, + pScanInfo->default_scan_ies, + pScanInfo->default_scan_ies_len); + pScanInfo->scanAddIE.length = + pScanInfo->default_scan_ies_len; + } } /* acquire the wakelock to avoid the apps suspend during the scan. To