Эх сурвалжийг харах

qcacmn: NDP_END_REQ implementation

Add implementation of NDP_END_REQ.

Change-Id: Ifa0bdcdee09c15c68bb12c63ba1157c71650c5bc
CRs-Fixed: 2014795
Naveen Rawat 8 жил өмнө
parent
commit
720b86499a
1 өөрчлөгдсөн 300 нэмэгдсэн , 0 устгасан
  1. 300 0
      src/target_if_nan.c

+ 300 - 0
src/target_if_nan.c

@@ -22,6 +22,7 @@
 
 #include "../../../umac/nan/core/src/nan_main_i.h"
 #include "nan_public_structs.h"
+#include "nan_ucfg_api.h"
 #include "target_if_nan.h"
 #include "wmi_unified_api.h"
 #include "scheduler_api.h"
@@ -54,6 +55,16 @@ static QDF_STATUS target_if_nan_event_dispatcher(struct scheduler_msg *msg)
 		vdev = rsp->vdev;
 		break;
 	}
+	case NDP_END_RSP: {
+		struct nan_datapath_end_rsp_event *rsp = msg->bodyptr;
+		vdev = rsp->vdev;
+		break;
+	}
+	case NDP_END_IND: {
+		struct nan_datapath_end_indication_event *rsp = msg->bodyptr;
+		vdev = rsp->vdev;
+		break;
+	}
 	default:
 		target_if_err("invalid msg type %d", msg->type);
 		qdf_mem_free(msg->bodyptr);
@@ -730,6 +741,258 @@ static int target_if_ndp_responder_rsp_handler(ol_scn_t scn, uint8_t *data,
 	return 0;
 }
 
+static QDF_STATUS target_if_nan_ndp_end_req(struct nan_datapath_end_req *req)
+{
+	int ret;
+	uint16_t len;
+	wmi_buf_t buf;
+	QDF_STATUS status;
+	wmi_unified_t wmi_handle;
+	uint32_t ndp_end_req_len, i;
+	struct wlan_objmgr_psoc *psoc;
+	struct scheduler_msg msg = {0};
+	wmi_ndp_end_req *ndp_end_req_lst;
+	wmi_ndp_end_req_fixed_param *cmd;
+	struct wlan_lmac_if_nan_rx_ops *nan_rx_ops;
+	struct nan_datapath_end_rsp_event end_rsp = {0};
+
+	if (!req) {
+		target_if_err("req is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(req->vdev);
+	if (!psoc) {
+		target_if_err("psoc is null.");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null.");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	nan_rx_ops = target_if_nan_get_rx_ops(psoc);
+	if (!nan_rx_ops) {
+		target_if_err("nan_rx_ops is null.");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	/* len of tlv following fixed param  */
+	ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances;
+	/* above comes out to 4 byte alligned already, no need of padding */
+	len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE;
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		target_if_err("Malloc failed");
+		status = QDF_STATUS_E_NOMEM;
+		goto send_ndp_end_fail;
+	}
+	cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param));
+
+	cmd->transaction_id = req->transaction_id;
+
+	/* set tlv pointer to end of fixed param */
+	WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC,
+			ndp_end_req_len);
+
+	ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] +
+						WMI_TLV_HDR_SIZE);
+	for (i = 0; i < req->num_ndp_instances; i++) {
+		WMITLV_SET_HDR(&ndp_end_req_lst[i],
+				WMITLV_TAG_ARRAY_FIXED_STRUC,
+				(sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE));
+
+		ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i];
+	}
+
+	target_if_debug("Sending WMI_NDP_END_REQ_CMDID to FW");
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_NDP_END_REQ_CMDID);
+	if (ret < 0) {
+		target_if_err("WMI_NDP_END_REQ_CMDID failed, ret: %d", ret);
+		wmi_buf_free(buf);
+		status = QDF_STATUS_E_FAILURE;
+		goto send_ndp_end_fail;
+	}
+	return QDF_STATUS_SUCCESS;
+
+send_ndp_end_fail:
+	end_rsp.vdev = req->vdev;
+	msg.type = NDP_END_RSP;
+	end_rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR;
+	end_rsp.reason = NAN_DATAPATH_END_FAILED;
+	end_rsp.transaction_id = req->transaction_id;
+	msg.bodyptr = &end_rsp;
+
+	if (nan_rx_ops && nan_rx_ops->nan_event_rx)
+		nan_rx_ops->nan_event_rx(&msg);
+
+	return status;
+}
+
+static int target_if_ndp_end_rsp_handler(ol_scn_t scn, uint8_t *data,
+					 uint32_t data_len)
+{
+	int ret = 0;
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_vdev *vdev;
+	struct scheduler_msg msg = {0};
+	WMI_NDP_END_RSP_EVENTID_param_tlvs *event;
+	struct nan_datapath_end_rsp_event *end_rsp;
+	struct wlan_lmac_if_nan_rx_ops *nan_rx_ops;
+	wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL;
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return -EINVAL;
+	}
+
+	nan_rx_ops = target_if_nan_get_rx_ops(psoc);
+	/* process even here and call callback */
+	if (!nan_rx_ops || !nan_rx_ops->nan_event_rx) {
+		target_if_err("lmac callbacks not registered");
+		return -EINVAL;
+	}
+
+	event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) data;
+	fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param;
+	target_if_debug("WMI_NDP_END_RSP_EVENTID(0x%X) recieved. transaction_id: %d, rsp_status: %d, reason_code: %d",
+		 WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id,
+		 fixed_params->rsp_status, fixed_params->reason_code);
+
+	vdev = ucfg_nan_get_ndi_vdev(psoc, WLAN_NAN_ID);
+	if (!vdev) {
+		target_if_err("vdev is null");
+		return -EINVAL;
+	}
+
+	end_rsp = qdf_mem_malloc(sizeof(*end_rsp));
+	if (!end_rsp) {
+		target_if_err("malloc failed");
+		ret = -ENOMEM;
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
+		goto send_ndp_end_rsp;
+	}
+
+	end_rsp->vdev = vdev;
+	end_rsp->transaction_id = fixed_params->transaction_id;
+	end_rsp->reason = fixed_params->reason_code;
+	end_rsp->status = fixed_params->rsp_status;
+
+send_ndp_end_rsp:
+	msg.bodyptr = end_rsp;
+	msg.type = NDP_END_RSP;
+	msg.callback = target_if_nan_event_dispatcher;
+	target_if_err("NDP_END_RSP sent: %d", msg.type);
+	status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("failed to post msg, status: %d", status);
+		qdf_mem_free(end_rsp);
+		return -EINVAL;
+	}
+	return ret;
+}
+
+static int target_if_ndp_end_ind_handler(ol_scn_t scn, uint8_t *data,
+					 uint32_t data_len)
+{
+	int i, buf_size;
+	QDF_STATUS status;
+	struct scheduler_msg msg;
+	wmi_ndp_end_indication *ind;
+	struct qdf_mac_addr peer_addr;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_lmac_if_nan_rx_ops *nan_rx_ops;
+	WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event;
+	struct nan_datapath_end_indication_event *rsp;
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return -EINVAL;
+	}
+
+	nan_rx_ops = target_if_nan_get_rx_ops(psoc);
+	if (!nan_rx_ops || !nan_rx_ops->nan_event_rx) {
+		target_if_err("lmac callbacks not registered");
+		return -EINVAL;
+	}
+
+	event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) data;
+	if (event->num_ndp_end_indication_list == 0) {
+		target_if_err("Error: Event ignored, 0 ndp instances");
+		return -EINVAL;
+	}
+
+	vdev = ucfg_nan_get_ndi_vdev(psoc, WLAN_NAN_ID);
+	if (!vdev) {
+		target_if_err("vdev is null");
+		return -EINVAL;
+	}
+
+	target_if_debug("number of ndp instances = %d",
+			event->num_ndp_end_indication_list);
+	buf_size = sizeof(*rsp) + event->num_ndp_end_indication_list *
+			sizeof(rsp->ndp_map[0]);
+	rsp = qdf_mem_malloc(buf_size);
+	if (!rsp) {
+		target_if_err("Failed to allocate memory");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
+		return -ENOMEM;
+	}
+
+	rsp->vdev = vdev;
+	rsp->num_ndp_ids = event->num_ndp_end_indication_list;
+
+	ind = event->ndp_end_indication_list;
+	for (i = 0; i < rsp->num_ndp_ids; i++) {
+		WMI_MAC_ADDR_TO_CHAR_ARRAY(
+			&ind[i].peer_ndi_mac_addr,
+			peer_addr.bytes);
+		/* add mac address print - TBD */
+		target_if_debug(
+			"ind[%d]: type %d, reason_code %d, instance_id %d num_active %d ",
+			i, ind[i].type, ind[i].reason_code,
+			ind[i].ndp_instance_id, ind[i].num_active_ndps_on_peer);
+
+		/* Add each instance entry to the list */
+		rsp->ndp_map[i].ndp_instance_id =
+			ind[i].ndp_instance_id;
+		rsp->ndp_map[i].vdev_id = ind[i].vdev_id;
+		WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr,
+			rsp->ndp_map[i].peer_ndi_mac_addr.bytes);
+		rsp->ndp_map[i].num_active_ndp_sessions =
+			ind[i].num_active_ndps_on_peer;
+		rsp->ndp_map[i].type = ind[i].type;
+		rsp->ndp_map[i].reason_code =
+			ind[i].reason_code;
+	}
+
+	msg.type = NDP_END_IND;
+	msg.bodyptr = rsp;
+	msg.callback = target_if_nan_event_dispatcher;
+
+	target_if_err("NDP_END_IND sent: %d", msg.type);
+	status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("failed to post msg, status: %d", status);
+		qdf_mem_free(rsp);
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static QDF_STATUS target_if_nan_req(void *req, uint32_t req_type)
 {
 	/* send cmd to fw */
@@ -740,6 +1003,9 @@ static QDF_STATUS target_if_nan_req(void *req, uint32_t req_type)
 	case NDP_RESPONDER_REQ:
 		target_if_nan_ndp_responder_req(req);
 		break;
+	case NDP_END_REQ:
+		target_if_nan_ndp_end_req(req);
+		break;
 	default:
 		target_if_err("invalid req type");
 		break;
@@ -823,6 +1089,26 @@ QDF_STATUS target_if_nan_register_events(struct wlan_objmgr_psoc *psoc)
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	ret = wmi_unified_register_event_handler(handle,
+		WMI_NDP_END_INDICATION_EVENTID,
+		target_if_ndp_end_ind_handler,
+		WMI_RX_UMAC_CTX);
+	if (ret) {
+		target_if_err("wmi event registration failed, ret: %d", ret);
+		target_if_nan_deregister_events(psoc);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wmi_unified_register_event_handler(handle,
+		WMI_NDP_END_RSP_EVENTID,
+		target_if_ndp_end_rsp_handler,
+		WMI_RX_UMAC_CTX);
+	if (ret) {
+		target_if_err("wmi event registration failed, ret: %d", ret);
+		target_if_nan_deregister_events(psoc);
+		return QDF_STATUS_E_FAILURE;
+	}
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -859,6 +1145,20 @@ QDF_STATUS target_if_nan_deregister_events(struct wlan_objmgr_psoc *psoc)
 		status = ret;
 	}
 
+	ret = wmi_unified_unregister_event_handler(handle,
+				WMI_NDP_END_INDICATION_EVENTID);
+	if (ret) {
+		target_if_err("wmi event deregistration failed, ret: %d", ret);
+		status = ret;
+	}
+
+	ret = wmi_unified_unregister_event_handler(handle,
+				WMI_NDP_END_RSP_EVENTID);
+	if (ret) {
+		target_if_err("wmi event deregistration failed, ret: %d", ret);
+		status = ret;
+	}
+
 	if (status)
 		return QDF_STATUS_E_FAILURE;
 	else