소스 검색

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
Selvaraj, Sridhar 8 년 전
부모
커밋
4ea106ed87
5개의 변경된 파일111개의 추가작업 그리고 0개의 파일을 삭제
  1. 2 0
      core/hdd/inc/wlan_hdd_main.h
  2. 2 0
      core/hdd/inc/wlan_hdd_wext.h
  3. 34 0
      core/hdd/src/wlan_hdd_cfg80211.c
  4. 6 0
      core/hdd/src/wlan_hdd_main.c
  5. 67 0
      core/hdd/src/wlan_hdd_scan.c

+ 2 - 0
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;
 

+ 2 - 0
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
  */

+ 34 - 0
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,

+ 6 - 0
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

+ 67 - 0
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