瀏覽代碼

qcacld-3.0: Send NAN disable indication to userspace upon SSR

Currently, host driver sends NAN disable request to firmware and
firmware sends NAN disable indication as a response. Host driver
forwards this indication to framework. But when SSR happens,
driver needs to send this NAN disable indication to framework
as firmware lost the NAN context. This allows framework to
initiate NAN again. Send the NAN disable indication with success
status code to framework after recovery.

Change-Id: Ic2139e159f0c1d9c1fb5c39597ce18e0787e809b
CRs-Fixed: 2735047
Srinivas Dasari 4 年之前
父節點
當前提交
7586ee3a5e

+ 33 - 0
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

+ 16 - 0
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_ */

+ 31 - 0
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;
+}

+ 7 - 0
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,