diff --git a/cnss2/main.c b/cnss2/main.c index bcb9397494..6bd13d2926 100644 --- a/cnss2/main.c +++ b/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; diff --git a/cnss2/main.h b/cnss2/main.h index 5f11d95334..c2ed004791 100644 --- a/cnss2/main.h +++ b/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; diff --git a/cnss2/pci.c b/cnss2/pci.c index ea19d3c2de..2052da9c5e 100644 --- a/cnss2/pci.c +++ b/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; } diff --git a/cnss2/qmi.c b/cnss2/qmi.c index b47d63c95e..1a43ea7916 100644 --- a/cnss2/qmi.c +++ b/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 + }, {} }; diff --git a/inc/cnss2.h b/inc/cnss2.h index e22468651c..d1d2535f80 100644 --- a/inc/cnss2.h +++ b/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 */