summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSelvaraj, Sridhar <sselvara@codeaurora.org>2016-08-05 20:34:46 +0530
committerqcabuildsw <qcabuildsw@localhost>2016-10-03 17:38:50 -0700
commit4ea106ed874cba1d0fdde2acd7a36eaed5556e08 (patch)
treee024f4b42e7dab85f8c508545ba82801049dd478
parentb106ae5c99d730cc698b76ba1bbdabd6f40dd1d4 (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.h2
-rw-r--r--core/hdd/inc/wlan_hdd_wext.h2
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.c34
-rw-r--r--core/hdd/src/wlan_hdd_main.c6
-rw-r--r--core/hdd/src/wlan_hdd_scan.c67
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