Browse Source

cnss2: Add support for async data QMI indication

Add support for async data QMI indication from
firmware.

Change-Id: I957e5b219d19f7a531dd25133a05da64857d068d
CRs-Fixed: 3782100
Nirav Shah 1 year ago
parent
commit
085c1c4748
5 changed files with 64 additions and 0 deletions
  1. 19 0
      cnss2/main.c
  2. 2 0
      cnss2/main.h
  3. 2 0
      cnss2/pci.c
  4. 37 0
      cnss2/qmi.c
  5. 4 0
      inc/cnss2.h

+ 19 - 0
cnss2/main.c

@@ -2497,6 +2497,25 @@ int cnss_qmi_send(struct device *dev, int type, void *cmd,
 }
 EXPORT_SYMBOL(cnss_qmi_send);
 
+int cnss_register_driver_async_data_cb(struct device *dev, void *cb_ctx,
+				       int (*cb)(void *ctx, uint16_t type,
+						 void *event, int event_len))
+{
+	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
+
+	if (!plat_priv)
+		return -ENODEV;
+
+	if (!test_bit(CNSS_QMI_WLFW_CONNECTED, &plat_priv->driver_state))
+		return -EINVAL;
+
+	plat_priv->get_driver_async_data_cb = cb;
+	plat_priv->get_driver_async_data_ctx = cb_ctx;
+
+	return 0;
+}
+EXPORT_SYMBOL(cnss_register_driver_async_data_cb);
+
 static int cnss_cold_boot_cal_start_hdlr(struct cnss_plat_data *plat_priv)
 {
 	int ret = 0;

+ 2 - 0
cnss2/main.h

@@ -603,6 +603,8 @@ struct cnss_plat_data {
 	u64 dynamic_feature;
 	void *get_info_cb_ctx;
 	int (*get_info_cb)(void *ctx, void *event, int event_len);
+	void *get_driver_async_data_ctx;
+	int (*get_driver_async_data_cb)(void *ctx, uint16_t type, void *event, int event_len);
 	bool cbc_enabled;
 	u8 use_pm_domain;
 	u8 use_nv_mac;

+ 2 - 0
cnss2/pci.c

@@ -3094,6 +3094,8 @@ int cnss_pci_call_driver_remove(struct cnss_pci_data *pci_priv)
 
 	plat_priv->get_info_cb_ctx = NULL;
 	plat_priv->get_info_cb = NULL;
+	plat_priv->get_driver_async_data_ctx = NULL;
+	plat_priv->get_driver_async_data_cb = NULL;
 
 	return 0;
 }

+ 37 - 0
cnss2/qmi.c

@@ -190,6 +190,8 @@ static int cnss_wlfw_ind_register_send_sync(struct cnss_plat_data *plat_priv)
 	req->respond_get_info_enable = 1;
 	req->wfc_call_twt_config_enable_valid = 1;
 	req->wfc_call_twt_config_enable = 1;
+	req->async_data_enable_valid = 1;
+	req->async_data_enable = 1;
 
 	ret = qmi_txn_init(&plat_priv->qmi_wlfw, &txn,
 			   wlfw_ind_register_resp_msg_v01_ei, resp);
@@ -3108,6 +3110,33 @@ static void cnss_wlfw_respond_get_info_ind_cb(struct qmi_handle *qmi_wlfw,
 				       ind_msg->data_len);
 }
 
+static void cnss_wlfw_driver_async_data_ind_cb(struct qmi_handle *qmi_wlfw,
+					       struct sockaddr_qrtr *sq,
+					       struct qmi_txn *txn,
+					       const void *data)
+{
+	struct cnss_plat_data *plat_priv =
+		container_of(qmi_wlfw, struct cnss_plat_data, qmi_wlfw);
+	const struct wlfw_driver_async_data_ind_msg_v01 *ind_msg = data;
+
+	cnss_pr_buf("Received QMI WLFW driver async data indication\n");
+
+	if (!txn) {
+		cnss_pr_err("Spurious indication\n");
+		return;
+	}
+
+	cnss_pr_buf("Extract message with event length: %d, type: %d\n",
+		    ind_msg->data_len, ind_msg->type);
+
+	if (plat_priv->get_driver_async_data_ctx &&
+			plat_priv->get_driver_async_data_cb)
+		plat_priv->get_driver_async_data_cb(
+			plat_priv->get_driver_async_data_ctx, ind_msg->type,
+			(void *)ind_msg->data, ind_msg->data_len);
+}
+
+
 static int cnss_ims_wfc_call_twt_cfg_send_sync
 	(struct cnss_plat_data *plat_priv,
 	 const struct wlfw_wfc_call_twt_config_ind_msg_v01 *ind_msg)
@@ -3319,6 +3348,14 @@ static struct qmi_msg_handler qmi_wlfw_msg_handlers[] = {
 		sizeof(struct wlfw_wfc_call_twt_config_ind_msg_v01),
 		.fn = cnss_wlfw_process_twt_cfg_ind
 	},
+	{
+		.type = QMI_INDICATION,
+		.msg_id = QMI_WLFW_DRIVER_ASYNC_DATA_IND_V01,
+		.ei = wlfw_driver_async_data_ind_msg_v01_ei,
+		.decoded_size =
+		sizeof(struct wlfw_driver_async_data_ind_msg_v01),
+		.fn = cnss_wlfw_driver_async_data_ind_cb
+	},
 	{}
 };
 

+ 4 - 0
inc/cnss2.h

@@ -463,4 +463,8 @@ extern int cnss_get_curr_therm_cdev_state(struct device *dev,
 extern int cnss_update_time_sync_period(struct device *dev,
 					 uint32_t time_sync_period);
 extern int cnss_reset_time_sync_period(struct device *dev);
+extern int cnss_register_driver_async_data_cb(struct device *dev, void *cb_ctx,
+					      int (*cb)(void *ctx,
+					      uint16_t type, void *event,
+					      int event_len));
 #endif /* _NET_CNSS2_H */