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

qcacld-3.0: Add support for handling the 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. Add modules that process these events and
updates the NAN states.

Add support for handling the NAN events.

Change-Id: Icfcd9c33cc410d9a65140f63cac69ddd69742306
CRs-Fixed: 2355383
Nachiket Kukade 6 жил өмнө
parent
commit
4f89e9e161

+ 39 - 5
components/nan/core/inc/nan_public_structs.h

@@ -471,6 +471,39 @@ struct nan_datapath_end_req {
 	uint32_t ndp_ids[NDP_NUM_INSTANCE_ID];
 };
 
+/**
+ * enum nan_event_id_types - NAN event ID types
+ * @nan_event_id_error_rsp: NAN event indicating error
+ * @nan_event_id_enable_rsp: NAN Enable Response event ID
+ * @nan_event_id_disable_ind: NAN Disable Indication event ID
+ * @nan_event_id_generic_rsp: All remaining NAN events, treated as passthrough
+ */
+enum nan_event_id_types {
+	nan_event_id_error_rsp = 0,
+	nan_event_id_enable_rsp,
+	nan_event_id_disable_ind,
+	nan_event_id_generic_rsp,
+};
+
+/**
+ * struct nan_event_params - NAN event received from the Target
+ * @psoc: Pointer to the psoc object
+ * @evt_type: NAN Discovery event type
+ * @is_nan_enable_success: Status from the NAN Enable Response event
+ * @mac_id: MAC ID associated with NAN Discovery from NAN Enable Response event
+ * @buf_len: Event buffer length
+ * @buf: Event buffer starts here
+ */
+struct nan_event_params {
+	struct wlan_objmgr_psoc *psoc;
+	enum nan_event_id_types evt_type;
+	bool is_nan_enable_success;
+	uint8_t mac_id;
+	uint32_t buf_len;
+	/* Variable length, do not add anything after this */
+	uint8_t buf[];
+};
+
 /**
  * struct nan_msg_params - NAN request params
  * @request_data_len: request data length
@@ -652,7 +685,8 @@ struct nan_datapath_sch_update_event {
 
 /**
  * struct nan_callbacks - struct containing callback to non-converged driver
- * @os_if_event_handler: OS IF Callback for handling the events
+ * @os_if_nan_event_handler: OS IF Callback for handling NAN Discovery events
+ * @os_if_ndp_event_handler: OS IF Callback for handling NAN Datapath events
  * @ndi_open: HDD callback for creating the NAN Datapath Interface
  * @ndi_start: HDD callback for starting the NAN Datapath Interface
  * @ndi_close: HDD callback for closing the NAN Datapath Interface
@@ -668,10 +702,10 @@ struct nan_datapath_sch_update_event {
  */
 struct nan_callbacks {
 	/* callback to os_if layer from umac */
-	void (*os_if_event_handler)(struct wlan_objmgr_psoc *psoc,
-				    struct wlan_objmgr_vdev *vdev,
-				    uint32_t type, void *msg);
-
+	void (*os_if_nan_event_handler)(struct nan_event_params *nan_event);
+	void (*os_if_ndp_event_handler)(struct wlan_objmgr_psoc *psoc,
+					struct wlan_objmgr_vdev *vdev,
+					uint32_t type, void *msg);
 	int (*ndi_open)(char *iface_name);
 	int (*ndi_start)(char *iface_name, uint16_t);
 	void (*ndi_close)(uint8_t);

+ 79 - 14
components/nan/core/src/nan_main.c

@@ -319,8 +319,8 @@ static QDF_STATUS nan_handle_confirm(
 		psoc_nan_obj->cb_obj.delete_peers_by_addr(vdev_id,
 						confirm->peer_ndi_mac_addr);
 	}
-	psoc_nan_obj->cb_obj.os_if_event_handler(psoc, confirm->vdev,
-						 NDP_CONFIRM, confirm);
+	psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, confirm->vdev,
+						     NDP_CONFIRM, confirm);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -345,8 +345,8 @@ static QDF_STATUS nan_handle_initiator_rsp(
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
-	psoc_nan_obj->cb_obj.os_if_event_handler(psoc, rsp->vdev,
-					NDP_INITIATOR_RSP, rsp);
+	psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, rsp->vdev,
+						     NDP_INITIATOR_RSP, rsp);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -389,8 +389,10 @@ static QDF_STATUS nan_handle_ndp_ind(
 		}
 	}
 	if (NAN_DATAPATH_ROLE_RESPONDER == ndp_ind->role)
-		psoc_nan_obj->cb_obj.os_if_event_handler(psoc, ndp_ind->vdev,
-						NDP_INDICATION, ndp_ind);
+		psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc,
+							     ndp_ind->vdev,
+							     NDP_INDICATION,
+							     ndp_ind);
 
 	return status;
 }
@@ -425,8 +427,8 @@ static QDF_STATUS nan_handle_responder_rsp(
 			rsp->status = QDF_STATUS_E_FAILURE;
 		}
 	}
-	psoc_nan_obj->cb_obj.os_if_event_handler(psoc, rsp->vdev,
-						 NDP_RESPONDER_RSP, rsp);
+	psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, rsp->vdev,
+						     NDP_RESPONDER_RSP, rsp);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -451,8 +453,8 @@ static QDF_STATUS nan_handle_ndp_end_rsp(
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
-	psoc_nan_obj->cb_obj.os_if_event_handler(psoc, rsp->vdev,
-						NDP_END_RSP, rsp);
+	psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, rsp->vdev,
+						     NDP_END_RSP, rsp);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -476,8 +478,28 @@ static QDF_STATUS nan_handle_end_ind(
 	}
 
 	psoc_nan_obj->cb_obj.ndp_delete_peers(ind->ndp_map, ind->num_ndp_ids);
-	psoc_nan_obj->cb_obj.os_if_event_handler(psoc, ind->vdev,
-						 NDP_END_IND, ind);
+	psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, ind->vdev,
+						     NDP_END_IND, ind);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS nan_handle_enable_rsp(struct nan_event_params *evt_params)
+{
+	struct nan_psoc_priv_obj *psoc_nan_obj;
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = evt_params->psoc;
+	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
+	if (!psoc_nan_obj) {
+		nan_err("psoc_nan_obj is NULL");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (evt_params->is_nan_enable_success)
+		nan_set_discovery_state(evt_params->psoc, NAN_DISC_ENABLED);
+	else
+		nan_set_discovery_state(evt_params->psoc, NAN_DISC_DISABLED);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -500,8 +522,51 @@ static QDF_STATUS nan_handle_schedule_update(
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
-	psoc_nan_obj->cb_obj.os_if_event_handler(psoc, ind->vdev,
-						 NDP_SCHEDULE_UPDATE, ind);
+	psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, ind->vdev,
+						     NDP_SCHEDULE_UPDATE, ind);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS nan_discovery_event_handler(struct scheduler_msg *msg)
+{
+	struct nan_event_params *nan_event;
+	struct nan_psoc_priv_obj *psoc_nan_obj;
+
+	if (!msg || !msg->bodyptr) {
+		nan_err("msg body is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	nan_event = msg->bodyptr;
+	if (!nan_event->psoc) {
+		nan_err("psoc is NULL");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	psoc_nan_obj = nan_get_psoc_priv_obj(nan_event->psoc);
+	if (!psoc_nan_obj) {
+		nan_err("psoc_nan_obj is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	switch (msg->type) {
+	case nan_event_id_enable_rsp:
+		nan_handle_enable_rsp(nan_event);
+		break;
+	case nan_event_id_disable_ind:
+		nan_set_discovery_state(nan_event->psoc,
+					NAN_DISC_DISABLED);
+		break;
+	case nan_event_id_generic_rsp:
+	case nan_event_id_error_rsp:
+		break;
+	default:
+		nan_err("Unknown event ID type - %d", msg->type);
+		break;
+	}
+
+	psoc_nan_obj->cb_obj.os_if_nan_event_handler(nan_event);
 
 	return QDF_STATUS_SUCCESS;
 }

+ 10 - 2
components/nan/core/src/nan_main_i.h

@@ -173,8 +173,16 @@ void nan_discovery_flush_callback(struct scheduler_msg *msg);
 QDF_STATUS nan_discovery_scheduled_handler(struct scheduler_msg *msg);
 
 /*
- * nan_datapath_event_handler: function to process events from firmware
- * @msg: message received from lmac
+ * nan_discovery_event_handler: function to process NAN events from firmware
+ * @msg: message received from Target IF
+ *
+ * Return: status of operation
+ */
+QDF_STATUS nan_discovery_event_handler(struct scheduler_msg *msg);
+
+/*
+ * nan_datapath_event_handler: function to process NDP events from firmware
+ * @msg: message received from Target IF
  *
  * Return: status of operation
  */

+ 6 - 10
components/nan/dispatcher/inc/nan_ucfg_api.h

@@ -181,7 +181,7 @@ QDF_STATUS ucfg_nan_req_processor(struct wlan_objmgr_vdev *vdev,
 				  void *in_req, uint32_t req_type);
 
 /**
- * ucfg_nan_event_handler: ucfg API to be called from legacy code to
+ * ucfg_nan_datapath_event_handler: ucfg API to be called from legacy code to
  * post events to os_if/hdd layer
  * @psoc: pointer to psoc object
  * @vdev: pointer to vdev object
@@ -190,9 +190,9 @@ QDF_STATUS ucfg_nan_req_processor(struct wlan_objmgr_vdev *vdev,
  *
  * Return: None
  */
-void ucfg_nan_event_handler(struct wlan_objmgr_psoc *psoc,
-			    struct wlan_objmgr_vdev *vdev,
-			    uint32_t type, void *msg);
+void ucfg_nan_datapath_event_handler(struct wlan_objmgr_psoc *psoc,
+				     struct wlan_objmgr_vdev *vdev,
+				     uint32_t type, void *msg);
 
 /**
  * ucfg_nan_register_hdd_callbacks: ucfg API to set hdd callbacks
@@ -202,12 +202,8 @@ void ucfg_nan_event_handler(struct wlan_objmgr_psoc *psoc,
  *
  * Return: status of operation
  */
-int ucfg_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *,
-				    struct nan_callbacks *,
-				    void (os_if_event_handler)
-						(struct wlan_objmgr_psoc *,
-						 struct wlan_objmgr_vdev *,
-						 uint32_t, void *));
+int ucfg_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
+				    struct nan_callbacks *cb_obj);
 
 /*
  * ucfg_nan_register_lim_callbacks: ucfg API to set lim callbacks

+ 9 - 11
components/nan/dispatcher/src/nan_ucfg_api.c

@@ -383,9 +383,9 @@ QDF_STATUS ucfg_nan_req_processor(struct wlan_objmgr_vdev *vdev,
 	return status;
 }
 
-void ucfg_nan_event_handler(struct wlan_objmgr_psoc *psoc,
-			    struct wlan_objmgr_vdev *vdev,
-			    uint32_t type, void *msg)
+void ucfg_nan_datapath_event_handler(struct wlan_objmgr_psoc *psoc,
+				     struct wlan_objmgr_vdev *vdev,
+				     uint32_t type, void *msg)
 {
 	struct nan_psoc_priv_obj *psoc_obj = nan_get_psoc_priv_obj(psoc);
 
@@ -394,15 +394,11 @@ void ucfg_nan_event_handler(struct wlan_objmgr_psoc *psoc,
 		return;
 	}
 
-	psoc_obj->cb_obj.os_if_event_handler(psoc, vdev, type, msg);
+	psoc_obj->cb_obj.os_if_ndp_event_handler(psoc, vdev, type, msg);
 }
 
 int ucfg_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
-				    struct nan_callbacks *cb_obj,
-				    void (os_if_event_handler)(
-				    struct wlan_objmgr_psoc *,
-				    struct wlan_objmgr_vdev *,
-				    uint32_t, void *))
+				    struct nan_callbacks *cb_obj)
 {
 	struct nan_psoc_priv_obj *psoc_obj = nan_get_psoc_priv_obj(psoc);
 
@@ -411,8 +407,6 @@ int ucfg_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
 		return -EINVAL;
 	}
 
-	psoc_obj->cb_obj.os_if_event_handler = os_if_event_handler;
-
 	psoc_obj->cb_obj.ndi_open = cb_obj->ndi_open;
 	psoc_obj->cb_obj.ndi_start = cb_obj->ndi_start;
 	psoc_obj->cb_obj.ndi_delete = cb_obj->ndi_delete;
@@ -425,6 +419,10 @@ int ucfg_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
 	psoc_obj->cb_obj.get_peer_idx = cb_obj->get_peer_idx;
 	psoc_obj->cb_obj.new_peer_ind = cb_obj->new_peer_ind;
 	psoc_obj->cb_obj.peer_departed_ind = cb_obj->peer_departed_ind;
+	psoc_obj->cb_obj.os_if_ndp_event_handler =
+				cb_obj->os_if_ndp_event_handler;
+	psoc_obj->cb_obj.os_if_nan_event_handler =
+				cb_obj->os_if_nan_event_handler;
 
 	return 0;
 }

+ 133 - 25
components/target_if/nan/src/target_if_nan.c

@@ -28,7 +28,44 @@
 #include "wmi_unified_api.h"
 #include "scheduler_api.h"
 
-static QDF_STATUS target_if_nan_event_flush_cb(struct scheduler_msg *msg)
+static void target_if_nan_event_flush_cb(struct scheduler_msg *msg)
+{
+	struct wlan_objmgr_psoc *psoc;
+
+	if (!msg || !msg->bodyptr) {
+		target_if_err("Empty message for NAN Discovery event");
+		return;
+	}
+
+	psoc = ((struct nan_event_params *)msg->bodyptr)->psoc;
+	wlan_objmgr_psoc_release_ref(psoc, WLAN_NAN_ID);
+	qdf_mem_free(msg->bodyptr);
+	msg->bodyptr = NULL;
+}
+
+static QDF_STATUS target_if_nan_event_dispatcher(struct scheduler_msg *msg)
+{
+	struct wlan_nan_rx_ops *nan_rx_ops;
+	struct nan_event_params *nan_rsp;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+
+	nan_rsp = msg->bodyptr;
+	psoc = nan_rsp->psoc;
+
+	nan_rx_ops = nan_psoc_get_rx_ops(psoc);
+	if (!nan_rx_ops) {
+		target_if_err("nan_rx_ops is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+	} else {
+		status = nan_rx_ops->nan_discovery_event_rx(msg);
+	}
+
+	target_if_nan_event_flush_cb(msg);
+	return status;
+}
+
+static QDF_STATUS target_if_ndp_event_flush_cb(struct scheduler_msg *msg)
 {
 	void *ptr = msg->bodyptr;
 	struct wlan_objmgr_vdev *vdev = NULL;
@@ -67,7 +104,7 @@ static QDF_STATUS target_if_nan_event_flush_cb(struct scheduler_msg *msg)
 	return QDF_STATUS_SUCCESS;
 }
 
-static QDF_STATUS target_if_nan_event_dispatcher(struct scheduler_msg *msg)
+static QDF_STATUS target_if_ndp_event_dispatcher(struct scheduler_msg *msg)
 {
 	QDF_STATUS status;
 	void *ptr = msg->bodyptr;
@@ -217,15 +254,15 @@ static int target_if_ndp_initiator_rsp_handler(ol_scn_t scn, uint8_t *data,
 
 	msg.bodyptr = rsp;
 	msg.type = NDP_INITIATOR_RSP;
-	msg.callback = target_if_nan_event_dispatcher;
-	msg.flush_callback = target_if_nan_event_flush_cb;
+	msg.callback = target_if_ndp_event_dispatcher;
+	msg.flush_callback = target_if_ndp_event_flush_cb;
 	target_if_debug("NDP_INITIATOR_RSP sent: %d", msg.type);
 	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
 					QDF_MODULE_ID_TARGET_IF,
 					QDF_MODULE_ID_TARGET_IF, &msg);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		target_if_err("failed to post msg, status: %d", status);
-		target_if_nan_event_flush_cb(&msg);
+		target_if_ndp_event_flush_cb(&msg);
 		return -EINVAL;
 	}
 
@@ -268,15 +305,15 @@ static int target_if_ndp_ind_handler(ol_scn_t scn, uint8_t *data,
 
 	msg.bodyptr = rsp;
 	msg.type = NDP_INDICATION;
-	msg.callback = target_if_nan_event_dispatcher;
-	msg.flush_callback = target_if_nan_event_flush_cb;
+	msg.callback = target_if_ndp_event_dispatcher;
+	msg.flush_callback = target_if_ndp_event_flush_cb;
 	target_if_debug("NDP_INDICATION sent: %d", msg.type);
 	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
 					QDF_MODULE_ID_TARGET_IF,
 					QDF_MODULE_ID_TARGET_IF, &msg);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		target_if_err("failed to post msg, status: %d", status);
-		target_if_nan_event_flush_cb(&msg);
+		target_if_ndp_event_flush_cb(&msg);
 		return -EINVAL;
 	}
 
@@ -319,15 +356,15 @@ static int target_if_ndp_confirm_handler(ol_scn_t scn, uint8_t *data,
 
 	msg.bodyptr = rsp;
 	msg.type = NDP_CONFIRM;
-	msg.callback = target_if_nan_event_dispatcher;
-	msg.flush_callback = target_if_nan_event_flush_cb;
+	msg.callback = target_if_ndp_event_dispatcher;
+	msg.flush_callback = target_if_ndp_event_flush_cb;
 	target_if_debug("NDP_CONFIRM sent: %d", msg.type);
 	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
 					QDF_MODULE_ID_TARGET_IF,
 					QDF_MODULE_ID_TARGET_IF, &msg);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		target_if_err("failed to post msg, status: %d", status);
-		target_if_nan_event_flush_cb(&msg);
+		target_if_ndp_event_flush_cb(&msg);
 		return -EINVAL;
 	}
 
@@ -419,15 +456,15 @@ static int target_if_ndp_responder_rsp_handler(ol_scn_t scn, uint8_t *data,
 
 	msg.bodyptr = rsp;
 	msg.type = NDP_RESPONDER_RSP;
-	msg.callback = target_if_nan_event_dispatcher;
-	msg.flush_callback = target_if_nan_event_flush_cb;
+	msg.callback = target_if_ndp_event_dispatcher;
+	msg.flush_callback = target_if_ndp_event_flush_cb;
 	target_if_debug("NDP_INITIATOR_RSP sent: %d", msg.type);
 	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
 					QDF_MODULE_ID_TARGET_IF,
 					QDF_MODULE_ID_TARGET_IF, &msg);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		target_if_err("failed to post msg, status: %d", status);
-		target_if_nan_event_flush_cb(&msg);
+		target_if_ndp_event_flush_cb(&msg);
 		return -EINVAL;
 	}
 
@@ -519,15 +556,15 @@ static int target_if_ndp_end_rsp_handler(ol_scn_t scn, uint8_t *data,
 
 	msg.bodyptr = end_rsp;
 	msg.type = NDP_END_RSP;
-	msg.callback = target_if_nan_event_dispatcher;
-	msg.flush_callback = target_if_nan_event_flush_cb;
+	msg.callback = target_if_ndp_event_dispatcher;
+	msg.flush_callback = target_if_ndp_event_flush_cb;
 	target_if_debug("NDP_END_RSP sent: %d", msg.type);
 	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
 					QDF_MODULE_ID_TARGET_IF,
 					QDF_MODULE_ID_TARGET_IF, &msg);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		target_if_err("failed to post msg, status: %d", status);
-		target_if_nan_event_flush_cb(&msg);
+		target_if_ndp_event_flush_cb(&msg);
 		return -EINVAL;
 	}
 
@@ -571,15 +608,15 @@ static int target_if_ndp_end_ind_handler(ol_scn_t scn, uint8_t *data,
 
 	msg.bodyptr = rsp;
 	msg.type = NDP_END_IND;
-	msg.callback = target_if_nan_event_dispatcher;
-	msg.flush_callback = target_if_nan_event_flush_cb;
+	msg.callback = target_if_ndp_event_dispatcher;
+	msg.flush_callback = target_if_ndp_event_flush_cb;
 	target_if_debug("NDP_END_IND sent: %d", msg.type);
 	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
 					QDF_MODULE_ID_TARGET_IF,
 					QDF_MODULE_ID_TARGET_IF, &msg);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		target_if_err("failed to post msg, status: %d", status);
-		target_if_nan_event_flush_cb(&msg);
+		target_if_ndp_event_flush_cb(&msg);
 		return -EINVAL;
 	}
 
@@ -622,15 +659,15 @@ static int target_if_ndp_sch_update_handler(ol_scn_t scn, uint8_t *data,
 
 	msg.bodyptr = rsp;
 	msg.type = NDP_SCHEDULE_UPDATE;
-	msg.callback = target_if_nan_event_dispatcher;
-	msg.flush_callback = target_if_nan_event_flush_cb;
+	msg.callback = target_if_ndp_event_dispatcher;
+	msg.flush_callback = target_if_ndp_event_flush_cb;
 	target_if_debug("NDP_SCHEDULE_UPDATE sent: %d", msg.type);
 	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
 					QDF_MODULE_ID_TARGET_IF,
 					QDF_MODULE_ID_TARGET_IF, &msg);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		target_if_err("failed to post msg, status: %d", status);
-		target_if_nan_event_flush_cb(&msg);
+		target_if_ndp_event_flush_cb(&msg);
 		return -EINVAL;
 	}
 
@@ -703,7 +740,7 @@ static QDF_STATUS target_if_nan_disable_req(struct nan_disable_req *nan_req)
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
-	return QDF_STATUS_SUCCESS;
+	return wmi_unified_nan_disable_req_cmd(wmi_handle, nan_req);
 }
 
 static QDF_STATUS target_if_nan_discovery_req(void *req, uint32_t req_type)
@@ -750,10 +787,71 @@ void target_if_nan_register_tx_ops(struct wlan_nan_tx_ops *tx_ops)
 
 void target_if_nan_register_rx_ops(struct wlan_nan_rx_ops *rx_ops)
 {
-	rx_ops->nan_discovery_event_rx = NULL;
+	rx_ops->nan_discovery_event_rx = nan_discovery_event_handler;
 	rx_ops->nan_datapath_event_rx = nan_datapath_event_handler;
 }
 
+static int target_if_nan_rsp_handler(ol_scn_t scn, uint8_t *data, uint32_t len)
+{
+	struct nan_event_params *nan_rsp, temp_evt_params = {0};
+	struct scheduler_msg msg = {0};
+	struct wmi_unified *wmi_handle;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+	uint8_t *buf_ptr;
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null");
+		return -EINVAL;
+	}
+
+	status = wmi_extract_nan_event_rsp(wmi_handle, data, &temp_evt_params,
+					   &buf_ptr);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("parsing of event failed, %d", status);
+		return -EINVAL;
+	}
+
+	nan_rsp = qdf_mem_malloc(sizeof(*nan_rsp) + temp_evt_params.buf_len);
+	if (!nan_rsp) {
+		target_if_err("malloc failed");
+		return -ENOMEM;
+	}
+	qdf_mem_copy(nan_rsp, &temp_evt_params, sizeof(*nan_rsp));
+
+	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_NAN_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("Failed to obtain psoc ref");
+		return -EACCES;
+	}
+
+	nan_rsp->psoc = psoc;
+	qdf_mem_copy(nan_rsp->buf_ptr, buf_ptr, nan_rsp->buf_len);
+
+	msg.bodyptr = nan_rsp;
+	msg.type = nan_rsp->evt_type;
+	msg.callback = target_if_nan_event_dispatcher;
+	msg.flush_callback = target_if_nan_event_flush_cb;
+	target_if_debug("NAN Event sent: %d", msg.type);
+	status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("failed to post msg, status: %d", status);
+		target_if_nan_event_flush_cb(&msg);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 QDF_STATUS target_if_nan_register_events(struct wlan_objmgr_psoc *psoc)
 {
 	int ret;
@@ -763,6 +861,16 @@ QDF_STATUS target_if_nan_register_events(struct wlan_objmgr_psoc *psoc)
 		target_if_err("handle is NULL");
 		return QDF_STATUS_E_FAILURE;
 	}
+
+	/* Register for nan response event */
+	ret = wmi_unified_register_event_handler(handle, wmi_nan_event_id,
+						 target_if_nan_rsp_handler,
+						 WMI_RX_UMAC_CTX);
+	if (ret) {
+		target_if_err("wmi event registration failed, ret: %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
 	ret = wmi_unified_register_event_handler(handle,
 		wmi_ndp_initiator_rsp_event_id,
 		target_if_ndp_initiator_rsp_handler,

+ 16 - 14
core/hdd/inc/wlan_hdd_nan.h

@@ -50,20 +50,6 @@ int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
 
 bool wlan_hdd_nan_is_supported(struct hdd_context *hdd_ctx);
 
-/**
- * wlan_hdd_cfg80211_nan_callback() - cfg80211 NAN event handler
- * @hdd_handle: opaque handle to the global HDD context
- * @msg: NAN event message
- *
- * This is a callback function and it gets called when we need to report
- * a nan event to userspace.  The wlan host driver simply encapsulates the
- * event into a netlink payload and then forwards it to userspace via a
- * cfg80211 vendor event.
- *
- * Return: nothing
- */
-void wlan_hdd_cfg80211_nan_callback(hdd_handle_t hdd_handle, tSirNanEvent *msg);
-
 /**
  * wlan_hdd_cfg80211_nan_ext_request() - handle NAN Extended request
  * @wiphy:   pointer to wireless wiphy structure.
@@ -81,6 +67,22 @@ int wlan_hdd_cfg80211_nan_ext_request(struct wiphy *wiphy,
 				      const void *data,
 				      int data_len);
 
+/**
+ * wlan_hdd_cfg80211_nan_request() - handle NAN Extended request
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * This function is called by userspace to send a NAN request to
+ * firmware.  This is an SSR-protected wrapper function.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
+				  struct wireless_dev *wdev,
+				  const void *data, int data_len);
+
 #define FEATURE_NAN_VENDOR_COMMANDS					\
 	{                                                               \
 		.info.vendor_id = QCA_NL80211_VENDOR_ID,                \

+ 2 - 14
os_if/nan/inc/os_if_nan.h

@@ -39,19 +39,6 @@
 int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc,
 				const void *data, int data_len);
 
-/**
- * os_if_nan_event_handler: os_if handler api for nan response messages
- * @psoc: pointer to psoc object
- * @vdev: pointer to vdev object
- * @type: message type
- * @msg: msg buffer
- *
- * Return: None
- */
-void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc,
-			     struct wlan_objmgr_vdev *vdev,
-			     uint32_t type, void *msg);
-
 /**
  * os_if_nan_register_hdd_callbacks: os_if api to register hdd callbacks
  * @psoc: pointer to psoc object
@@ -147,7 +134,8 @@ static inline QDF_STATUS os_if_nan_set_ndp_delete_transaction_id(
 }
 
 /**
- * os_if_process_nan_req: os_if api to handle nan request message
+ * os_if_process_nan_req: os_if api to handle NAN requests attached to the
+ * vendor command QCA_NL80211_VENDOR_SUBCMD_NAN_EXT
  * @psoc: pointer to psoc object
  * @data: request data. contains vendor cmd tlvs
  * @data_len: length of data

+ 70 - 18
os_if/nan/src/os_if_nan.c

@@ -1989,9 +1989,9 @@ ndp_sch_ind_nla_failed:
 	kfree_skb(vendor_event);
 }
 
-void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc,
-			     struct wlan_objmgr_vdev *vdev,
-			     uint32_t type, void *msg)
+static void os_if_nan_datapath_event_handler(struct wlan_objmgr_psoc *psoc,
+					     struct wlan_objmgr_vdev *vdev,
+					     uint32_t type, void *msg)
 {
 	switch (type) {
 	case NAN_DATAPATH_INF_CREATE_RSP:
@@ -2032,13 +2032,6 @@ void os_if_nan_event_handler(struct wlan_objmgr_psoc *psoc,
 	}
 }
 
-int os_if_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
-				     struct nan_callbacks *cb_obj)
-{
-	return ucfg_nan_register_hdd_callbacks(psoc, cb_obj,
-						os_if_nan_event_handler);
-}
-
 int os_if_nan_register_lim_callbacks(struct wlan_objmgr_psoc *psoc,
 				     struct nan_callbacks *cb_obj)
 {
@@ -2060,13 +2053,15 @@ void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc,
 	if (success) {
 		rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS;
 		rsp.reason = 0;
-		os_if_nan_event_handler(psoc, vdev,
-					NAN_DATAPATH_INF_CREATE_RSP, &rsp);
+		os_if_nan_datapath_event_handler(psoc, vdev,
+						 NAN_DATAPATH_INF_CREATE_RSP,
+						 &rsp);
 	} else {
 		rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR;
 		rsp.reason = NAN_DATAPATH_NAN_DATA_IFACE_CREATE_FAILED;
-		os_if_nan_event_handler(psoc, vdev,
-					NAN_DATAPATH_INF_CREATE_RSP, &rsp);
+		os_if_nan_datapath_event_handler(psoc, vdev,
+						 NAN_DATAPATH_INF_CREATE_RSP,
+						 &rsp);
 	}
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
 }
@@ -2085,13 +2080,15 @@ void os_if_nan_post_ndi_delete_rsp(struct wlan_objmgr_psoc *psoc,
 	if (success) {
 		rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS;
 		rsp.reason = 0;
-		os_if_nan_event_handler(psoc, vdev,
-					NAN_DATAPATH_INF_DELETE_RSP, &rsp);
+		os_if_nan_datapath_event_handler(psoc, vdev,
+						 NAN_DATAPATH_INF_DELETE_RSP,
+						 &rsp);
 	} else {
 		rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR;
 		rsp.reason = NAN_DATAPATH_NAN_DATA_IFACE_DELETE_FAILED;
-		os_if_nan_event_handler(psoc, vdev,
-					NAN_DATAPATH_INF_DELETE_RSP, &rsp);
+		os_if_nan_datapath_event_handler(psoc, vdev,
+						 NAN_DATAPATH_INF_DELETE_RSP,
+						 &rsp);
 	}
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
 }
@@ -2192,6 +2189,61 @@ failure:
 	kfree_skb(vendor_event);
 }
 
+/**
+ * os_if_nan_discovery_event_handler() - NAN Discovery Interface event handler
+ * @nan_evt: NAN Event parameters
+ *
+ * Module sends a NAN related vendor event to the upper layer
+ *
+ * Return: none
+ */
+static void os_if_nan_discovery_event_handler(struct nan_event_params *nan_evt)
+{
+	struct sk_buff *vendor_event;
+	struct wlan_objmgr_pdev *pdev;
+	struct pdev_osif_priv *os_priv;
+
+	/*
+	 * Since Partial Offload chipsets have only one pdev per psoc, the first
+	 * pdev from the pdev list is used.
+	 */
+	pdev = wlan_objmgr_get_pdev_by_id(nan_evt->psoc, 0, WLAN_NAN_ID);
+	if (!pdev) {
+		cfg80211_err("null pdev");
+		return;
+	}
+	os_priv = wlan_pdev_get_ospriv(pdev);
+
+	vendor_event =
+		cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
+					    nan_evt->buf_len + NLMSG_HDRLEN,
+					    QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
+					    GFP_KERNEL);
+
+	if (!vendor_event) {
+		cfg80211_err("cfg80211_vendor_event_alloc failed");
+		goto fail;
+	}
+
+	if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN, nan_evt->buf_len,
+		    nan_evt->buf)) {
+		cfg80211_err("QCA_WLAN_VENDOR_ATTR_NAN put failed");
+		goto fail;
+	}
+
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+fail:
+	wlan_objmgr_pdev_release_ref(pdev, WLAN_NAN_ID);
+}
+
+int os_if_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
+				     struct nan_callbacks *cb_obj)
+{
+	cb_obj->os_if_ndp_event_handler = os_if_nan_datapath_event_handler;
+	cb_obj->os_if_nan_event_handler = os_if_nan_discovery_event_handler;
+	return ucfg_nan_register_hdd_callbacks(psoc, cb_obj);
+}
+
 static int os_if_nan_generic_req(struct wlan_objmgr_psoc *psoc,
 				 struct nlattr **tb)
 {