diff --git a/components/nan/core/inc/nan_public_structs.h b/components/nan/core/inc/nan_public_structs.h index 40f1457721..33c9c34e13 100644 --- a/components/nan/core/inc/nan_public_structs.h +++ b/components/nan/core/inc/nan_public_structs.h @@ -531,6 +531,39 @@ struct nan_event_params { uint8_t buf[]; }; +#define NAN_MSG_ID_DISABLE_INDICATION 26 +/** + * struct nan_msg_hdr - NAN msg header to be sent to userspace + * @msg_version: NAN msg version + * @msg_id: NAN message id + * @reserved: Reserved for now to avoid padding + * + * 8-byte control message header used by NAN + * + */ +struct nan_msg_hdr { + uint16_t msg_version:4; + uint16_t msg_id:12; + uint16_t reserved[3]; +}; + +#define NAN_STATUS_SUCCESS 0 +#define NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED 12 + +/** + * struct nan_disable_ind_msg - NAN disable ind params + * @msg_hdr: NAN msg header + * @reason: NAN disable reason, below are valid reasons for NAN disable ind + * NAN_STATUS_SUCCESS + * NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED + * @reserved: Reserved for now to avoid padding + */ +struct nan_disable_ind_msg { + struct nan_msg_hdr msg_hdr; + uint16_t reason; + uint16_t reserved; +}; + /** * struct nan_msg_params - NAN request params * @request_data_len: request data length diff --git a/components/nan/dispatcher/inc/nan_ucfg_api.h b/components/nan/dispatcher/inc/nan_ucfg_api.h index 2683acaf10..3a38bb829d 100644 --- a/components/nan/dispatcher/inc/nan_ucfg_api.h +++ b/components/nan/dispatcher/inc/nan_ucfg_api.h @@ -453,6 +453,16 @@ QDF_STATUS ucfg_get_nan_feature_config(struct wlan_objmgr_psoc *psoc, * Return: Bool */ bool ucfg_is_nan_vdev(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_nan_disable_ind_to_userspace() - Send NAN disble ind to userspace + * @psoc: pointer to psoc object + * + * Prepare NAN disable indication and send it to userspace + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_nan_disable_ind_to_userspace(struct wlan_objmgr_psoc *psoc); #else /* WLAN_FEATURE_NAN */ static inline @@ -560,5 +570,11 @@ bool ucfg_is_nan_dbs_supported(struct wlan_objmgr_psoc *psoc) { return false; } + +static inline +QDF_STATUS ucfg_nan_disable_ind_to_userspace(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} #endif /* WLAN_FEATURE_NAN */ #endif /* _NAN_UCFG_API_H_ */ diff --git a/components/nan/dispatcher/src/nan_ucfg_api.c b/components/nan/dispatcher/src/nan_ucfg_api.c index 6470c9b0cc..6b5ecd8052 100644 --- a/components/nan/dispatcher/src/nan_ucfg_api.c +++ b/components/nan/dispatcher/src/nan_ucfg_api.c @@ -1224,3 +1224,34 @@ bool ucfg_is_nan_vdev(struct wlan_objmgr_vdev *vdev) return false; } + +QDF_STATUS ucfg_nan_disable_ind_to_userspace(struct wlan_objmgr_psoc *psoc) +{ + struct nan_psoc_priv_obj *psoc_nan_obj; + struct nan_event_params *disable_ind; + struct nan_disable_ind_msg msg = { + .msg_hdr.msg_id = NAN_MSG_ID_DISABLE_INDICATION, + .reason = 0, /* success */ }; + + psoc_nan_obj = nan_get_psoc_priv_obj(psoc); + if (!psoc_nan_obj) { + nan_err("psoc_nan_obj is null"); + return QDF_STATUS_E_INVAL; + } + + disable_ind = qdf_mem_malloc(sizeof(struct nan_event_params) + + sizeof(msg)); + if (!disable_ind) { + nan_err("failed to alloc disable_ind"); + return QDF_STATUS_E_NOMEM; + } + disable_ind->psoc = psoc, + disable_ind->evt_type = nan_event_id_disable_ind; + disable_ind->buf_len = sizeof(msg); + qdf_mem_copy(disable_ind->buf, &msg, disable_ind->buf_len); + + psoc_nan_obj->cb_obj.os_if_nan_event_handler(disable_ind); + + qdf_mem_free(disable_ind); + return QDF_STATUS_SUCCESS; +} diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 28a921960e..d07b9dd190 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -7863,6 +7863,13 @@ QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx) WLAN_STATUS_ASSOC_DENIED_UNSPEC, GFP_KERNEL, false, 0); } + if ((adapter->device_mode == QDF_NAN_DISC_MODE || + (adapter->device_mode == QDF_STA_MODE && + !ucfg_nan_is_vdev_creation_allowed( + hdd_ctx->psoc))) && + cds_is_driver_recovering()) + ucfg_nan_disable_ind_to_userspace( + hdd_ctx->psoc); hdd_register_tx_flow_control(adapter, hdd_tx_resume_timer_expired_handler,