Преглед изворни кода

qcacld-3.0: Update default scan IE's to FW

As part of MBO(Multiband Operations), host driver need to supply
the default scan IEs to firmware at wifi init time using existing
VDEV SET IE command. FW uses these Scan IE's in subsequent scans,
.i.e. FW initiated Probe Requests.

As part of this fix, receive default scan IE's from supplicant,
update extended capability IE with FTM values(if ext cap IE is
present), send down the scan IE's buffer to FW which would be used
for subsequent FW initiated scans.

Change-Id: Ia23459078d93a30c9a1715e391023ee0a1de93ee
CRs-Fixed: 1039969
Deepak Dhamdhere пре 8 година
родитељ
комит
b106ae5c99

+ 22 - 0
core/hdd/src/wlan_hdd_cfg80211.c

@@ -3906,6 +3906,9 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
 	int access_policy = 0;
 	char vendor_ie[SIR_MAC_MAX_IE_LENGTH + 2];
 	bool vendor_ie_present = false, access_policy_present = false;
+	uint16_t scan_ie_len = 0;
+	uint8_t *scan_ie;
+
 	ENTER_DEV(dev);
 
 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
@@ -4039,6 +4042,25 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
 		ret_val = hdd_enable_disable_ca_event(hdd_ctx, set_value);
 	}
 
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES]) {
+		scan_ie_len = nla_len(
+			tb[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES]);
+		hdd_info("Received default scan IE of len %d session %d device mode %d",
+						scan_ie_len, adapter->sessionId,
+						adapter->device_mode);
+		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 (adapter->device_mode == QDF_STA_MODE) {
+				status = sme_set_default_scan_ie(hdd_ctx->hHal,
+						adapter->sessionId, scan_ie,
+						scan_ie_len);
+				if (QDF_STATUS_SUCCESS != status)
+					ret_val = -EPERM;
+			}
+		} else
+			ret_val = -EPERM;
+	}
 	return ret_val;
 }
 

+ 28 - 0
core/mac/inc/sir_api.h

@@ -5361,6 +5361,34 @@ struct fw_dump_rsp {
 	uint32_t dump_complete;
 };
 
+/**
+ * DEFAULT_SCAN_IE_ID - Identifier for the collection of IE's added
+ * by default to the probe request
+ */
+#define DEFAULT_SCAN_IE_ID 256
+
+ /* MAX_DEFAULT_SCAN_IE_LEN - Maxmimum length of Default Scan IE's */
+#define MAX_DEFAULT_SCAN_IE_LEN 1024
+
+ /* Extended Capabilities IE header(IE Id + IE Length) length */
+#define EXT_CAP_IE_HDR_LEN 2
+
+/**
+ * struct hdd_default_scan_ie - HDD default scan IE structure
+ * @message_type: message type to be set with eWNI_SME_DEFAULT_SCAN_IE
+ * @length: length of the struct hdd_default_scan_ie
+ * @session_id: Session Id
+ * @ie_len: Default scan IE length
+ * @ie_data: Pointer to default scan IE data
+ */
+struct hdd_default_scan_ie {
+	uint16_t message_type;
+	uint16_t length;
+	uint16_t session_id;
+	uint16_t ie_len;
+	uint8_t ie_data[MAX_DEFAULT_SCAN_IE_LEN];
+};
+
 /**
  * struct vdev_ie_info - IE info
  * @vdev_id - vdev for which the IE is being sent

+ 1 - 0
core/mac/inc/wni_api.h

@@ -264,6 +264,7 @@ enum eWniMsgTypes {
 	eWNI_SME_REGISTER_P2P_ACK_CB,
 	eWNI_SME_SEND_DISASSOC_FRAME,
 	eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE,
+	eWNI_SME_DEFAULT_SCAN_IE,
 	eWNI_SME_MSG_TYPES_END
 };
 

+ 129 - 0
core/mac/src/pe/lim/lim_process_message_queue.c

@@ -241,6 +241,130 @@ static void lim_process_set_antenna_resp(tpAniSirGlobal mac, void *body)
 	return;
 }
 
+/**
+ * lim_update_default_scan_ies() - Update Extended capabilities IE(if present)
+ * with capabilities of Fine Time measurements(FTM) if set in driver
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @ie_data: Default Scan IE data
+ * @local_ie_buf: Local Scan IE data
+ * @local_ie_len: Pointer to length of @ie_data
+ *
+ * Return: eSIR_SUCCESS on success, eSIR_FAILURE otherwise
+ */
+tSirRetStatus lim_update_default_scan_ies(tpAniSirGlobal mac_ctx,
+		uint8_t *ie_data, uint8_t *local_ie_buf, uint16_t *local_ie_len)
+{
+	uint32_t dot11mode;
+	bool vht_enabled = false;
+	tDot11fIEExtCap default_scan_ext_cap = {0}, driver_ext_cap = {0};
+	uint8_t ext_cap_ie_hdr[EXT_CAP_IE_HDR_LEN] = {
+			DOT11F_EID_EXTCAP, DOT11F_IE_EXTCAP_MAX_LEN};
+	tSirRetStatus status;
+
+	status = lim_strip_extcap_update_struct(mac_ctx, ie_data,
+				   local_ie_len, &default_scan_ext_cap);
+	if (eSIR_SUCCESS != status ||
+		(((*local_ie_len) + EXT_CAP_IE_HDR_LEN
+		 + DOT11F_IE_EXTCAP_MAX_LEN) > MAX_DEFAULT_SCAN_IE_LEN)) {
+		lim_log(mac_ctx, LOGE, FL("Strip ext cap fails(%d)"), status);
+		return eSIR_FAILURE;
+	}
+
+	qdf_mem_copy(local_ie_buf, ie_data, (*local_ie_len));
+	qdf_mem_copy(local_ie_buf + (*local_ie_len),
+			ext_cap_ie_hdr, EXT_CAP_IE_HDR_LEN);
+	(*local_ie_len) += EXT_CAP_IE_HDR_LEN;
+
+	wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &dot11mode);
+	if (IS_DOT11_MODE_VHT(dot11mode))
+		vht_enabled = true;
+
+	status = populate_dot11f_ext_cap(mac_ctx, vht_enabled,
+					&driver_ext_cap, NULL);
+	if (eSIR_SUCCESS != status) {
+		lim_log(mac_ctx, LOGE, FL("Update ext cap fails"));
+		qdf_mem_copy(local_ie_buf + (*local_ie_len),
+				default_scan_ext_cap.bytes,
+				DOT11F_IE_EXTCAP_MAX_LEN);
+		(*local_ie_len) += DOT11F_IE_EXTCAP_MAX_LEN;
+		return eSIR_SUCCESS;
+	}
+	lim_merge_extcap_struct(&driver_ext_cap, &default_scan_ext_cap);
+
+	qdf_mem_copy(local_ie_buf + (*local_ie_len),
+			driver_ext_cap.bytes, DOT11F_IE_EXTCAP_MAX_LEN);
+	(*local_ie_len) += DOT11F_IE_EXTCAP_MAX_LEN;
+	return eSIR_SUCCESS;
+}
+
+/**
+ * lim_process_set_default_scan_ie_request() - Process the Set default
+ * Scan IE request from HDD.
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: Pointer to incoming data
+ *
+ * This function receives the default scan IEs and updates the ext cap IE
+ * (if present) with FTM capabilities and pass the Scan IEs to WMA.
+ *
+ * Return: None
+ */
+static void lim_process_set_default_scan_ie_request(tpAniSirGlobal mac_ctx,
+							uint32_t *msg_buf)
+{
+	struct hdd_default_scan_ie *set_ie_params;
+	struct vdev_ie_info *wma_ie_params;
+	uint8_t *local_ie_buf;
+	uint16_t local_ie_len;
+	tSirMsgQ msg_q;
+	tSirRetStatus ret_code;
+
+	if (!msg_buf) {
+		lim_log(mac_ctx, LOGE, FL("msg_buf is NULL"));
+		return;
+	}
+
+	set_ie_params = (struct hdd_default_scan_ie *) msg_buf;
+	local_ie_len = set_ie_params->ie_len;
+
+	local_ie_buf = qdf_mem_malloc(MAX_DEFAULT_SCAN_IE_LEN);
+	if (!local_ie_buf) {
+		lim_log(mac_ctx, LOGE,
+			FL("Scan IE Update fails due to malloc failure"));
+		return;
+	}
+
+	if (lim_update_default_scan_ies(mac_ctx,
+			(uint8_t *)set_ie_params->ie_data,
+			local_ie_buf, &local_ie_len)) {
+		lim_log(mac_ctx, LOGE, FL("Update default scan IEs fails"));
+		goto scan_ie_send_fail;
+	}
+
+	wma_ie_params = qdf_mem_malloc(sizeof(*wma_ie_params) + local_ie_len);
+	if (!wma_ie_params) {
+		lim_log(mac_ctx, LOGE, FL("fail to alloc wma_ie_params"));
+		goto scan_ie_send_fail;
+	}
+	wma_ie_params->vdev_id = set_ie_params->session_id;
+	wma_ie_params->ie_id = DEFAULT_SCAN_IE_ID;
+	wma_ie_params->length = local_ie_len;
+	wma_ie_params->data = (uint8_t *)(wma_ie_params)
+					+ sizeof(*wma_ie_params);
+	qdf_mem_copy(wma_ie_params->data, local_ie_buf, local_ie_len);
+
+	msg_q.type = WMA_SET_IE_INFO;
+	msg_q.bodyptr = wma_ie_params;
+	msg_q.bodyval = 0;
+	ret_code = wma_post_ctrl_msg(mac_ctx, &msg_q);
+	if (eSIR_SUCCESS != ret_code) {
+		lim_log(mac_ctx, LOGE, FL("fail to send WMA_SET_IE_INFO"));
+		qdf_mem_free(wma_ie_params);
+	}
+scan_ie_send_fail:
+	qdf_mem_free(local_ie_buf);
+}
+
 /**
  * lim_process_hw_mode_trans_ind() - Process set HW mode transition indication
  * @mac: Global MAC pointer
@@ -1895,6 +2019,11 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
 		qdf_mem_free((void *)msg->bodyptr);
 		msg->bodyptr = NULL;
 		break;
+	case eWNI_SME_DEFAULT_SCAN_IE:
+		lim_process_set_default_scan_ie_request(mac_ctx, msg->bodyptr);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
 	default:
 		qdf_mem_free((void *)msg->bodyptr);
 		msg->bodyptr = NULL;

+ 2 - 0
core/sme/inc/sme_api.h

@@ -1261,4 +1261,6 @@ QDF_STATUS sme_update_sta_roam_policy(tHalHandle hal,
 		uint8_t session_id);
 QDF_STATUS sme_enable_disable_chanavoidind_event(tHalHandle hal,
 					uint8_t set_value);
+QDF_STATUS sme_set_default_scan_ie(tHalHandle hal, uint16_t session_id,
+				uint8_t *ie_data, uint16_t ie_len);
 #endif /* #if !defined( __SME_API_H ) */

+ 34 - 0
core/sme/src/common/sme_api.c

@@ -16570,6 +16570,40 @@ QDF_STATUS sme_enable_disable_chanavoidind_event(tHalHandle hal,
 		sme_release_global_lock(&mac_ctx->sme);
 		return status;
 	}
+	return status;
+}
 
+/*
+ * sme_set_default_scan_ie() - API to send default scan IE to LIM
+ * @hal: reference to the HAL
+ * @session_id: current session ID
+ * @ie_data: Pointer to Scan IE data
+ * @ie_len: Length of @ie_data
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_default_scan_ie(tHalHandle hal, uint16_t session_id,
+					uint8_t *ie_data, uint16_t ie_len)
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	struct hdd_default_scan_ie *set_ie_params;
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		set_ie_params = qdf_mem_malloc(sizeof(*set_ie_params));
+		if (!set_ie_params)
+			status = QDF_STATUS_E_NOMEM;
+		else {
+			set_ie_params->message_type = eWNI_SME_DEFAULT_SCAN_IE;
+			set_ie_params->length = sizeof(*set_ie_params);
+			set_ie_params->session_id = session_id;
+			set_ie_params->ie_len = ie_len;
+			qdf_mem_copy(set_ie_params->ie_data, ie_data, ie_len);
+			status = cds_send_mb_message_to_mac(set_ie_params);
+		}
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+	sms_log(mac_ctx, LOG1, FL("Set default scan IE status %d"), status);
 	return status;
 }

+ 8 - 1
core/wma/src/wma_features.c

@@ -100,6 +100,13 @@
 				(1 << WOW_DISASSOC_RECVD_EVENT) |\
 				(1 << WOW_HTT_EVENT))\
 
+/**
+ * WMA_SET_VDEV_IE_SOURCE_HOST - Flag to identify the source of VDEV SET IE
+ * command. The value is 0x0 for the VDEV SET IE WMI commands from mobile
+ * MCL platform.
+ */
+#define WMA_SET_VDEV_IE_SOURCE_HOST 0x0
+
 static const uint8_t arp_ptrn[] = {0x08, 0x06};
 static const uint8_t arp_mask[] = {0xff, 0xff};
 static const uint8_t ns_ptrn[] = {0x86, 0xDD};
@@ -7730,6 +7737,7 @@ QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma,
 	cmd.length = ie_info->length;
 	cmd.band = ie_info->band;
 	cmd.data = ie_info->data;
+	cmd.ie_source = WMA_SET_VDEV_IE_SOURCE_HOST;
 
 	WMA_LOGD(FL("ie_id: %d, band: %d, len: %d"),
 		ie_info->ie_id, ie_info->band, ie_info->length);
@@ -7739,7 +7747,6 @@ QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma,
 
 	ret = wmi_unified_process_set_ie_info_cmd(wma->wmi_handle,
 				   &cmd);
-
 	return ret;
 }