diff options
| author | Selvaraj, Sridhar <sselvara@codeaurora.org> | 2016-08-05 20:34:46 +0530 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2016-10-03 17:38:50 -0700 |
| commit | 4ea106ed874cba1d0fdde2acd7a36eaed5556e08 (patch) | |
| tree | e024f4b42e7dab85f8c508545ba82801049dd478 | |
| parent | b106ae5c99d730cc698b76ba1bbdabd6f40dd1d4 (diff) | |
qcacld-3.0: Update scan request IEs with default scan IEs
As part of MBO(Multiband Operations), supplicant provides default
scan IEs per adapter to driver at init time which is passed to
FW for future use of the IEs in FW initiated scans. However
Host driver also need to save default scan IE's to use the same in
driver initiated scans.
For example LOWI scans request may not have MBO IE and then in that
case we need to copy the MBO IE from default IE and send it in the
scan request to firmware.
The fix implements the following:
1) Save default scan IEs per adapter in host driver when received.
2) Compare/Update IEs in cfg80211 scan request with default scan IEs.
Change-Id: I94278637ee03807104fcf85db544c6be22ec6adf
CRs-Fixed: 1039969
| -rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 2 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_wext.h | 2 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_cfg80211.c | 34 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_main.c | 6 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_scan.c | 67 |
5 files changed, 111 insertions, 0 deletions
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 @@ -3872,6 +3872,35 @@ wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = { }; /** + * 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 |
