diff --git a/components/nan/core/inc/nan_public_structs.h b/components/nan/core/inc/nan_public_structs.h index afd5de312d..56175e8b07 100644 --- a/components/nan/core/inc/nan_public_structs.h +++ b/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); diff --git a/components/nan/core/src/nan_main.c b/components/nan/core/src/nan_main.c index 9777c91a0b..904b4fb904 100644 --- a/components/nan/core/src/nan_main.c +++ b/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; } diff --git a/components/nan/core/src/nan_main_i.h b/components/nan/core/src/nan_main_i.h index 8930475774..eed58e59d4 100644 --- a/components/nan/core/src/nan_main_i.h +++ b/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 */ diff --git a/components/nan/dispatcher/inc/nan_ucfg_api.h b/components/nan/dispatcher/inc/nan_ucfg_api.h index d325d35f76..2f685e824e 100644 --- a/components/nan/dispatcher/inc/nan_ucfg_api.h +++ b/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 diff --git a/components/nan/dispatcher/src/nan_ucfg_api.c b/components/nan/dispatcher/src/nan_ucfg_api.c index a822cbaa15..0cd2ce6f19 100644 --- a/components/nan/dispatcher/src/nan_ucfg_api.c +++ b/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; } diff --git a/components/target_if/nan/src/target_if_nan.c b/components/target_if/nan/src/target_if_nan.c index cf8b2b64af..937a3fa955 100644 --- a/components/target_if/nan/src/target_if_nan.c +++ b/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, diff --git a/core/hdd/inc/wlan_hdd_nan.h b/core/hdd/inc/wlan_hdd_nan.h index 0f6ef923eb..3e93e3ce6d 100644 --- a/core/hdd/inc/wlan_hdd_nan.h +++ b/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, \ diff --git a/os_if/nan/inc/os_if_nan.h b/os_if/nan/inc/os_if_nan.h index e8f8cd172d..5b1718f0fa 100644 --- a/os_if/nan/inc/os_if_nan.h +++ b/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 diff --git a/os_if/nan/src/os_if_nan.c b/os_if/nan/src/os_if_nan.c index ab9ef43ece..af50e4edbe 100644 --- a/os_if/nan/src/os_if_nan.c +++ b/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) {