Sfoglia il codice sorgente

qcacmn: Add modules to handle and extract NAN events

As part of supporting NAN DBS, new WMI TLVs are defined so
that Host can maintain the status of NAN Discovery in sync
with the Firmware. Move the older handlers into the NAN
related files. Also add modules to extract information from
the new TLV's and fill up the event parameters to pass
them to the NAN component. add support for explicitly
disabling NAN due to concurrencies.

Add modules to handle and extract the info from NAN events.

Change-Id: Ic03baaaef45106353c211a813e11e33a90cd41ca
CRs-Fixed: 2338059
Nachiket Kukade 6 anni fa
parent
commit
1d925bafba
4 ha cambiato i file con 302 aggiunte e 96 eliminazioni
  1. 33 0
      wmi_unified_nan_api.c
  2. 269 0
      wmi_unified_nan_tlv.c
  3. 0 14
      wmi_unified_sta_api.c
  4. 0 82
      wmi_unified_sta_tlv.c

+ 33 - 0
wmi_unified_nan_api.c

@@ -22,6 +22,39 @@
 #include <wmi_unified_priv.h>
 #include <wmi_unified_nan_api.h>
 
+QDF_STATUS wmi_unified_nan_req_cmd(wmi_unified_t wmi_handle,
+				   struct nan_msg_params *nan_msg)
+{
+	if (wmi_handle->ops->send_nan_req_cmd)
+		return wmi_handle->ops->send_nan_req_cmd(wmi_handle,
+							 nan_msg);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_nan_disable_req_cmd(wmi_unified_t wmi_handle,
+					   struct nan_disable_req *nan_msg)
+{
+	if (wmi_handle->ops->send_nan_disable_req_cmd)
+		return wmi_handle->ops->send_nan_disable_req_cmd(wmi_handle,
+								 nan_msg);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_nan_event_rsp(wmi_unified_t wmi_handle, void *evt_buf,
+				     struct nan_event_params *nan_evt_params,
+				     uint8_t **nan_msg_buf)
+{
+	if (wmi_handle->ops->extract_nan_event_rsp)
+		return wmi_handle->ops->extract_nan_event_rsp(wmi_handle,
+							      evt_buf,
+							      nan_evt_params,
+							      nan_msg_buf);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
 QDF_STATUS wmi_unified_ndp_initiator_req_cmd_send(void *wmi_hdl,
 					struct nan_datapath_initiator_req *req)
 {

+ 269 - 0
wmi_unified_nan_tlv.c

@@ -22,6 +22,272 @@
 #include <wmi_unified_priv.h>
 #include <nan_public_structs.h>
 #include <wmi_unified_nan_api.h>
+#include <wlan_nan_msg_common_v2.h>
+
+static QDF_STATUS
+extract_nan_event_rsp_tlv(wmi_unified_t wmi_handle, void *evt_buf,
+			  struct nan_event_params *evt_params,
+			  uint8_t **msg_buf)
+{
+	WMI_NAN_EVENTID_param_tlvs *event;
+	wmi_nan_event_hdr *nan_rsp_event_hdr;
+	nan_msg_header_t *nan_msg_hdr;
+	wmi_nan_event_info *nan_evt_info;
+
+	/*
+	 * This is how received evt looks like
+	 *
+	 * <-------------------- evt_buf ----------------------------------->
+	 *
+	 * <--wmi_nan_event_hdr--><---WMI_TLV_HDR_SIZE---><----- data -------->
+	 *
+	 * +-----------+---------+-----------------------+--------------------+-
+	 * | tlv_header| data_len| WMITLV_TAG_ARRAY_BYTE | nan_rsp_event_data |
+	 * +-----------+---------+-----------------------+--------------------+-
+	 *
+	 * (Only for NAN Enable Resp)
+	 * <--wmi_nan_event_info-->
+	 * +-----------+-----------+
+	 * | tlv_header| event_info|
+	 * +-----------+-----------+
+	 *
+	 */
+
+	event = (WMI_NAN_EVENTID_param_tlvs *)evt_buf;
+	nan_rsp_event_hdr = event->fixed_param;
+
+	/* Actual data may include some padding, so data_len <= num_data */
+	if (nan_rsp_event_hdr->data_len > event->num_data) {
+		WMI_LOGE("%s: Provided NAN event length(%d) exceeding actual length(%d)!",
+			 __func__, nan_rsp_event_hdr->data_len,
+			 event->num_data);
+		return QDF_STATUS_E_INVAL;
+	}
+	evt_params->buf_len = nan_rsp_event_hdr->data_len;
+	*msg_buf = event->data;
+
+	if (nan_rsp_event_hdr->data_len < sizeof(nan_msg_header_t) ||
+	    nan_rsp_event_hdr->data_len > (WMI_SVC_MSG_MAX_SIZE -
+							    WMI_TLV_HDR_SIZE)) {
+		WMI_LOGE("%s: Invalid NAN event data length(%d)!",  __func__,
+			 nan_rsp_event_hdr->data_len);
+		return QDF_STATUS_E_INVAL;
+	}
+	nan_msg_hdr = (nan_msg_header_t *)event->data;
+
+	if (!wmi_service_enabled(wmi_handle, wmi_service_nan_dbs_support)) {
+		evt_params->evt_type = nan_event_id_generic_rsp;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	switch (nan_msg_hdr->msg_id) {
+	case NAN_MSG_ID_ENABLE_RSP:
+		nan_evt_info = event->event_info;
+		evt_params->evt_type = nan_event_id_enable_rsp;
+		evt_params->mac_id = nan_evt_info->mac_id;
+		evt_params->is_nan_enable_success = (nan_evt_info->status == 0);
+		break;
+	case NAN_MSG_ID_DISABLE_IND:
+		evt_params->evt_type = nan_event_id_disable_ind;
+		break;
+	case NAN_MSG_ID_ERROR_RSP:
+		evt_params->evt_type = nan_event_id_error_rsp;
+		break;
+	default:
+		evt_params->evt_type = nan_event_id_generic_rsp;
+		break;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_nan_disable_req_cmd_tlv() - to send nan disable request to target
+ * @wmi_handle: wmi handle
+ * @nan_msg: request data which will be non-null
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_nan_disable_req_cmd_tlv(wmi_unified_t wmi_handle,
+					       struct nan_disable_req *nan_msg)
+{
+	QDF_STATUS ret;
+	wmi_nan_cmd_param *cmd;
+	wmi_nan_host_config_param *cfg;
+	wmi_buf_t buf;
+	/* Initialize with minimum length required, which is Scenario 2*/
+	uint16_t len = sizeof(*cmd) + sizeof(*cfg) + 2 * WMI_TLV_HDR_SIZE;
+	uint16_t nan_data_len, nan_data_len_aligned = 0;
+	uint8_t *buf_ptr;
+
+	/*
+	 *  Scenario 1: NAN Disable with NAN msg data from upper layers
+	 *
+	 *    <-----nan cmd param-----><-- WMI_TLV_HDR_SIZE --><--- data ---->
+	 *    +------------+----------+-----------------------+--------------+
+	 *    | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_msg_data |
+	 *    +------------+----------+-----------------------+--------------+
+	 *
+	 *    <-- WMI_TLV_HDR_SIZE --><------nan host config params----->
+	 *   -+-----------------------+---------------------------------+
+	 *    | WMITLV_TAG_ARRAY_STRUC| tlv_header | 2g/5g disable flags|
+	 *   -+-----------------------+---------------------------------+
+	 *
+	 * Scenario 2: NAN Disable without any NAN msg data from upper layers
+	 *
+	 *    <------nan cmd param------><--WMI_TLV_HDR_SIZE--><--WMI_TLV_HDR_SI
+	 *    +------------+------------+----------------------+----------------
+	 *    | tlv_header | data_len=0 | WMITLV_TAG_ARRAY_BYTE| WMITLV_TAG_ARRA
+	 *    +------------+------------+----------------------+----------------
+	 *
+	 *    ZE----><------nan host config params----->
+	 *    -------+---------------------------------+
+	 *    Y_STRUC| tlv_header | 2g/5g disable flags|
+	 *    -------+---------------------------------+
+	 */
+
+	if (!nan_msg) {
+		WMI_LOGE("%s:nan req is not valid", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	nan_data_len = nan_msg->params.request_data_len;
+
+	if (nan_data_len) {
+		nan_data_len_aligned = roundup(nan_data_len, sizeof(uint32_t));
+		if (nan_data_len_aligned < nan_data_len) {
+			WMI_LOGE("%s: Int overflow while rounding up data_len",
+				 __func__);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE
+							- WMI_TLV_HDR_SIZE) {
+			WMI_LOGE("%s: nan_data_len exceeding wmi_max_msg_size",
+				 __func__);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		len += nan_data_len_aligned;
+	}
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	cmd = (wmi_nan_cmd_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_nan_cmd_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param));
+
+	cmd->data_len = nan_data_len;
+	WMI_LOGD("%s: nan data len value is %u", __func__, nan_data_len);
+	buf_ptr += sizeof(wmi_nan_cmd_param);
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	if (nan_data_len) {
+		qdf_mem_copy(buf_ptr, nan_msg->params.request_data,
+			     cmd->data_len);
+		buf_ptr += nan_data_len_aligned;
+	}
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_nan_host_config_param));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	cfg = (wmi_nan_host_config_param *)buf_ptr;
+	WMITLV_SET_HDR(&cfg->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_nan_host_config_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_nan_host_config_param));
+	cfg->nan_2g_disc_disable = nan_msg->disable_2g_discovery;
+	cfg->nan_5g_disc_disable = nan_msg->disable_5g_discovery;
+
+	wmi_mtrace(WMI_NAN_CMDID, NO_SESSION, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_NAN_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("%s Failed to send set param command ret = %d",
+			 __func__, ret);
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
+
+/**
+ * send_nan_req_cmd_tlv() - to send nan request to target
+ * @wmi_handle: wmi handle
+ * @nan_msg: request data which will be non-null
+ *
+ * Return: CDF status
+ */
+static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle,
+				       struct nan_msg_params *nan_msg)
+{
+	QDF_STATUS ret;
+	wmi_nan_cmd_param *cmd;
+	wmi_buf_t buf;
+	uint16_t len = sizeof(*cmd);
+	uint16_t nan_data_len, nan_data_len_aligned;
+	uint8_t *buf_ptr;
+
+	/*
+	 *    <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ---->
+	 *    +------------+----------+-----------------------+--------------+
+	 *    | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_msg_data |
+	 *    +------------+----------+-----------------------+--------------+
+	 */
+	if (!nan_msg) {
+		WMI_LOGE("%s:nan req is not valid", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	nan_data_len = nan_msg->request_data_len;
+	nan_data_len_aligned = roundup(nan_msg->request_data_len,
+				       sizeof(uint32_t));
+	if (nan_data_len_aligned < nan_msg->request_data_len) {
+		WMI_LOGE("%s: integer overflow while rounding up data_len",
+			 __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) {
+		WMI_LOGE("%s: wmi_max_msg_size overflow for given datalen",
+			 __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	len += WMI_TLV_HDR_SIZE + nan_data_len_aligned;
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	cmd = (wmi_nan_cmd_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_nan_cmd_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param));
+	cmd->data_len = nan_msg->request_data_len;
+	WMI_LOGD("%s: The data len value is %u",  __func__,
+		 nan_msg->request_data_len);
+	buf_ptr += sizeof(wmi_nan_cmd_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	qdf_mem_copy(buf_ptr, nan_msg->request_data, cmd->data_len);
+
+	wmi_mtrace(WMI_NAN_CMDID, NO_SESSION, 0);
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_NAN_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		WMI_LOGE("%s Failed to send set param command ret = %d",
+			 __func__, ret);
+		wmi_buf_free(buf);
+	}
+
+	return ret;
+}
 
 static QDF_STATUS nan_ndp_initiator_req_tlv(wmi_unified_t wmi_handle,
 				struct nan_datapath_initiator_req *ndp_req)
@@ -846,6 +1112,9 @@ void wmi_nan_attach_tlv(wmi_unified_t wmi_handle)
 {
 	struct wmi_ops *ops = wmi_handle->ops;
 
+	ops->send_nan_req_cmd = send_nan_req_cmd_tlv;
+	ops->send_nan_disable_req_cmd = send_nan_disable_req_cmd_tlv;
+	ops->extract_nan_event_rsp = extract_nan_event_rsp_tlv;
 	ops->send_ndp_initiator_req_cmd = nan_ndp_initiator_req_tlv;
 	ops->send_ndp_responder_req_cmd = nan_ndp_responder_req_tlv;
 	ops->send_ndp_end_req_cmd = nan_ndp_end_req_tlv;

+ 0 - 14
wmi_unified_sta_api.c

@@ -123,20 +123,6 @@ QDF_STATUS wmi_unified_wlm_latency_level_cmd(void *wmi_hdl,
 	return QDF_STATUS_E_FAILURE;
 }
 
-#ifdef WLAN_FEATURE_NAN
-QDF_STATUS wmi_unified_nan_req_cmd(void *wmi_hdl,
-			struct nan_req_params *nan_req)
-{
-	wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
-
-	if (wmi_handle->ops->send_nan_req_cmd)
-		return wmi_handle->ops->send_nan_req_cmd(wmi_handle,
-							 nan_req);
-
-	return QDF_STATUS_E_FAILURE;
-}
-#endif
-
 QDF_STATUS wmi_unified_process_set_ie_info_cmd(void *wmi_hdl,
 				   struct vdev_ie_info_param *ie_info)
 {

+ 0 - 82
wmi_unified_sta_tlv.c

@@ -502,87 +502,6 @@ static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle,
 	return 0;
 }
 
-#ifdef WLAN_FEATURE_NAN
-/**
- * send_nan_req_cmd_tlv() - to send nan request to target
- * @wmi_handle: wmi handle
- * @nan_req: request data which will be non-null
- *
- * Return: CDF status
- */
-static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle,
-			struct nan_req_params *nan_req)
-{
-	QDF_STATUS ret;
-	wmi_nan_cmd_param *cmd;
-	wmi_buf_t buf;
-	uint16_t len = sizeof(*cmd);
-	uint16_t nan_data_len, nan_data_len_aligned;
-	uint8_t *buf_ptr;
-
-	/*
-	 *    <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ---->
-	 *    +------------+----------+-----------------------+--------------+
-	 *    | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data |
-	 *    +------------+----------+-----------------------+--------------+
-	 */
-	if (!nan_req) {
-		WMI_LOGE("%s:nan req is not valid", __func__);
-		return QDF_STATUS_E_FAILURE;
-	}
-	nan_data_len = nan_req->request_data_len;
-	nan_data_len_aligned = roundup(nan_req->request_data_len,
-				       sizeof(uint32_t));
-	if (nan_data_len_aligned < nan_req->request_data_len) {
-		WMI_LOGE("%s: integer overflow while rounding up data_len",
-			 __func__);
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) {
-		WMI_LOGE("%s: wmi_max_msg_size overflow for given datalen",
-			 __func__);
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	len += WMI_TLV_HDR_SIZE + nan_data_len_aligned;
-	buf = wmi_buf_alloc(wmi_handle, len);
-	if (!buf) {
-		return QDF_STATUS_E_NOMEM;
-	}
-	buf_ptr = (uint8_t *) wmi_buf_data(buf);
-	cmd = (wmi_nan_cmd_param *) buf_ptr;
-	WMITLV_SET_HDR(&cmd->tlv_header,
-		       WMITLV_TAG_STRUC_wmi_nan_cmd_param,
-		       WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param));
-	cmd->data_len = nan_req->request_data_len;
-	WMI_LOGD("%s: The data len value is %u",
-		 __func__, nan_req->request_data_len);
-	buf_ptr += sizeof(wmi_nan_cmd_param);
-	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned);
-	buf_ptr += WMI_TLV_HDR_SIZE;
-	qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len);
-
-	wmi_mtrace(WMI_NAN_CMDID, NO_SESSION, 0);
-	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
-				   WMI_NAN_CMDID);
-	if (QDF_IS_STATUS_ERROR(ret)) {
-		WMI_LOGE("%s Failed to send set param command ret = %d",
-			 __func__, ret);
-		wmi_buf_free(buf);
-	}
-
-	return ret;
-}
-
-void wmi_nan_feature_attach_tlv(struct wmi_unified *wmi_handle)
-{
-	struct wmi_ops *ops = wmi_handle->ops;
-
-	ops->send_nan_req_cmd = send_nan_req_cmd_tlv;
-}
-#endif /* WLAN_FEATURE_NAN */
-
 #ifdef CONVERGED_TDLS_ENABLE
 /**
  * tdls_get_wmi_offchannel_mode - Get WMI tdls off channel mode
@@ -2584,6 +2503,5 @@ void wmi_sta_attach_tlv(wmi_unified_t wmi_handle)
 	wmi_tdls_attach_tlv(wmi_handle);
 	wmi_disa_attach_tlv(wmi_handle);
 	wmi_policy_mgr_attach_tlv(wmi_handle);
-	wmi_nan_feature_attach_tlv(wmi_handle);
 }