Loading drivers/soc/qcom/icnss2/main.c +134 −7 Original line number Original line Diff line number Diff line Loading @@ -2970,27 +2970,31 @@ void icnss_disallow_recursive_recovery(struct device *dev) icnss_pr_info("Recursive recovery disallowed for WLAN\n"); icnss_pr_info("Recursive recovery disallowed for WLAN\n"); } } static void icnss_sysfs_create(struct icnss_priv *priv) static int icnss_create_shutdown_sysfs(struct icnss_priv *priv) { { struct kobject *icnss_kobject; struct kobject *icnss_kobject; int error = 0; int ret = 0; atomic_set(&priv->is_shutdown, false); atomic_set(&priv->is_shutdown, false); icnss_kobject = kobject_create_and_add("shutdown_wlan", kernel_kobj); icnss_kobject = kobject_create_and_add("shutdown_wlan", kernel_kobj); if (!icnss_kobject) { if (!icnss_kobject) { icnss_pr_err("Unable to create kernel object"); icnss_pr_err("Unable to create kernel object"); return; return -EINVAL; } } priv->icnss_kobject = icnss_kobject; priv->icnss_kobject = icnss_kobject; error = sysfs_create_file(icnss_kobject, &icnss_sysfs_attribute.attr); ret = sysfs_create_file(icnss_kobject, &icnss_sysfs_attribute.attr); if (error) if (ret) { icnss_pr_err("Unable to create icnss sysfs file"); icnss_pr_err("Unable to create icnss sysfs file err:%d", ret); return ret; } return ret; } } static void icnss_sysfs_destroy(struct icnss_priv *priv) static void icnss_destroy_shutdown_sysfs(struct icnss_priv *priv) { { struct kobject *icnss_kobject; struct kobject *icnss_kobject; Loading @@ -2999,6 +3003,129 @@ static void icnss_sysfs_destroy(struct icnss_priv *priv) kobject_put(icnss_kobject); kobject_put(icnss_kobject); } } static ssize_t qdss_tr_start_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct icnss_priv *priv = dev_get_drvdata(dev); wlfw_qdss_trace_start(priv); icnss_pr_dbg("Received QDSS start command\n"); return count; } static ssize_t qdss_tr_stop_store(struct device *dev, struct device_attribute *attr, const char *user_buf, size_t count) { struct icnss_priv *priv = dev_get_drvdata(dev); u32 option = 0; if (sscanf(user_buf, "%du", &option) != 1) return -EINVAL; wlfw_qdss_trace_stop(priv, option); icnss_pr_dbg("Received QDSS stop command\n"); return count; } static ssize_t qdss_conf_download_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct icnss_priv *priv = dev_get_drvdata(dev); icnss_wlfw_qdss_dnld_send_sync(priv); icnss_pr_dbg("Received QDSS download config command\n"); return count; } static ssize_t hw_trc_override_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct icnss_priv *priv = dev_get_drvdata(dev); int tmp = 0; if (sscanf(buf, "%du", &tmp) != 1) return -EINVAL; priv->hw_trc_override = tmp; icnss_pr_dbg("Received QDSS hw_trc_override indication\n"); return count; } static DEVICE_ATTR_WO(qdss_tr_start); static DEVICE_ATTR_WO(qdss_tr_stop); static DEVICE_ATTR_WO(qdss_conf_download); static DEVICE_ATTR_WO(hw_trc_override); static struct attribute *icnss_attrs[] = { &dev_attr_qdss_tr_start.attr, &dev_attr_qdss_tr_stop.attr, &dev_attr_qdss_conf_download.attr, &dev_attr_hw_trc_override.attr, NULL, }; static struct attribute_group icnss_attr_group = { .attrs = icnss_attrs, }; static int icnss_create_sysfs_link(struct icnss_priv *priv) { struct device *dev = &priv->pdev->dev; int ret; ret = sysfs_create_link(kernel_kobj, &dev->kobj, "icnss"); if (ret) { icnss_pr_err("Failed to create icnss link, err = %d\n", ret); goto out; } return 0; out: return ret; } static void icnss_remove_sysfs_link(struct icnss_priv *priv) { sysfs_remove_link(kernel_kobj, "icnss"); } int icnss_sysfs_create(struct icnss_priv *priv) { int ret = 0; ret = devm_device_add_group(&priv->pdev->dev, &icnss_attr_group); if (ret) { icnss_pr_err("Failed to create icnss device group, err = %d\n", ret); goto out; } icnss_create_sysfs_link(priv); ret = icnss_create_shutdown_sysfs(priv); if (ret) goto remove_icnss_group; return 0; remove_icnss_group: devm_device_remove_group(&priv->pdev->dev, &icnss_attr_group); out: return ret; } void icnss_sysfs_destroy(struct icnss_priv *priv) { icnss_destroy_shutdown_sysfs(priv); icnss_remove_sysfs_link(priv); devm_device_remove_group(&priv->pdev->dev, &icnss_attr_group); } static int icnss_get_vbatt_info(struct icnss_priv *priv) static int icnss_get_vbatt_info(struct icnss_priv *priv) { { struct adc_tm_chip *adc_tm_dev = NULL; struct adc_tm_chip *adc_tm_dev = NULL; Loading drivers/soc/qcom/icnss2/main.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -428,6 +428,7 @@ struct icnss_priv { void *hang_event_data; void *hang_event_data; struct list_head icnss_tcdev_list; struct list_head icnss_tcdev_list; struct mutex tcdev_lock; struct mutex tcdev_lock; u32 hw_trc_override; }; }; struct icnss_reg_info { struct icnss_reg_info { Loading drivers/soc/qcom/icnss2/qmi.c +89 −1 Original line number Original line Diff line number Diff line Loading @@ -1207,6 +1207,94 @@ int wlfw_wlan_mode_send_sync_msg(struct icnss_priv *priv, return ret; return ret; } } static int wlfw_send_qdss_trace_mode_req (struct icnss_priv *priv, enum wlfw_qdss_trace_mode_enum_v01 mode, unsigned long long option) { int rc = 0; int tmp = 0; struct wlfw_qdss_trace_mode_req_msg_v01 *req; struct wlfw_qdss_trace_mode_resp_msg_v01 *resp; struct qmi_txn txn; if (!priv) return -ENODEV; req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; resp = kzalloc(sizeof(*resp), GFP_KERNEL); if (!resp) { kfree(req); return -ENOMEM; } req->mode_valid = 1; req->mode = mode; req->option_valid = 1; req->option = option; tmp = priv->hw_trc_override; req->hw_trc_disable_override_valid = 1; req->hw_trc_disable_override = (tmp > QMI_PARAM_DISABLE_V01 ? QMI_PARAM_DISABLE_V01 : (tmp < 0 ? QMI_PARAM_INVALID_V01 : tmp)); icnss_pr_dbg("%s: mode %u, option %llu, hw_trc_disable_override: %u", __func__, mode, option, req->hw_trc_disable_override); rc = qmi_txn_init(&priv->qmi, &txn, wlfw_qdss_trace_mode_resp_msg_v01_ei, resp); if (rc < 0) { icnss_qmi_fatal_err("Fail to init txn for QDSS Mode resp %d\n", rc); goto out; } rc = qmi_send_request(&priv->qmi, NULL, &txn, QMI_WLFW_QDSS_TRACE_MODE_REQ_V01, WLFW_QDSS_TRACE_MODE_REQ_MSG_V01_MAX_MSG_LEN, wlfw_qdss_trace_mode_req_msg_v01_ei, req); if (rc < 0) { qmi_txn_cancel(&txn); icnss_qmi_fatal_err("Fail to send QDSS Mode req %d\n", rc); goto out; } rc = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout); if (rc < 0) { icnss_qmi_fatal_err("QDSS Mode resp wait failed with rc %d\n", rc); goto out; } else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { icnss_qmi_fatal_err( "QMI QDSS Mode request rejected, result:%d error:%d\n", resp->resp.result, resp->resp.error); rc = -resp->resp.result; goto out; } out: kfree(resp); kfree(req); return rc; } int wlfw_qdss_trace_start(struct icnss_priv *priv) { return wlfw_send_qdss_trace_mode_req(priv, QMI_WLFW_QDSS_TRACE_ON_V01, 0); } int wlfw_qdss_trace_stop(struct icnss_priv *priv, unsigned long long option) { return wlfw_send_qdss_trace_mode_req(priv, QMI_WLFW_QDSS_TRACE_OFF_V01, option); } int wlfw_wlan_cfg_send_sync_msg(struct icnss_priv *priv, int wlfw_wlan_cfg_send_sync_msg(struct icnss_priv *priv, struct wlfw_wlan_cfg_req_msg_v01 *data) struct wlfw_wlan_cfg_req_msg_v01 *data) { { Loading drivers/soc/qcom/icnss2/qmi.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -209,6 +209,8 @@ int icnss_wlfw_bdf_dnld_send_sync(struct icnss_priv *priv, u32 bdf_type); int icnss_wlfw_qdss_dnld_send_sync(struct icnss_priv *priv); int icnss_wlfw_qdss_dnld_send_sync(struct icnss_priv *priv); int icnss_wlfw_qdss_data_send_sync(struct icnss_priv *priv, char *file_name, int icnss_wlfw_qdss_data_send_sync(struct icnss_priv *priv, char *file_name, u32 total_size); u32 total_size); int wlfw_qdss_trace_start(struct icnss_priv *priv); int wlfw_qdss_trace_stop(struct icnss_priv *priv, unsigned long long option); int wlfw_qdss_trace_mem_info_send_sync(struct icnss_priv *priv); int wlfw_qdss_trace_mem_info_send_sync(struct icnss_priv *priv); int wlfw_power_save_send_msg(struct icnss_priv *priv, int wlfw_power_save_send_msg(struct icnss_priv *priv, enum wlfw_power_save_mode_v01 mode); enum wlfw_power_save_mode_v01 mode); Loading Loading
drivers/soc/qcom/icnss2/main.c +134 −7 Original line number Original line Diff line number Diff line Loading @@ -2970,27 +2970,31 @@ void icnss_disallow_recursive_recovery(struct device *dev) icnss_pr_info("Recursive recovery disallowed for WLAN\n"); icnss_pr_info("Recursive recovery disallowed for WLAN\n"); } } static void icnss_sysfs_create(struct icnss_priv *priv) static int icnss_create_shutdown_sysfs(struct icnss_priv *priv) { { struct kobject *icnss_kobject; struct kobject *icnss_kobject; int error = 0; int ret = 0; atomic_set(&priv->is_shutdown, false); atomic_set(&priv->is_shutdown, false); icnss_kobject = kobject_create_and_add("shutdown_wlan", kernel_kobj); icnss_kobject = kobject_create_and_add("shutdown_wlan", kernel_kobj); if (!icnss_kobject) { if (!icnss_kobject) { icnss_pr_err("Unable to create kernel object"); icnss_pr_err("Unable to create kernel object"); return; return -EINVAL; } } priv->icnss_kobject = icnss_kobject; priv->icnss_kobject = icnss_kobject; error = sysfs_create_file(icnss_kobject, &icnss_sysfs_attribute.attr); ret = sysfs_create_file(icnss_kobject, &icnss_sysfs_attribute.attr); if (error) if (ret) { icnss_pr_err("Unable to create icnss sysfs file"); icnss_pr_err("Unable to create icnss sysfs file err:%d", ret); return ret; } return ret; } } static void icnss_sysfs_destroy(struct icnss_priv *priv) static void icnss_destroy_shutdown_sysfs(struct icnss_priv *priv) { { struct kobject *icnss_kobject; struct kobject *icnss_kobject; Loading @@ -2999,6 +3003,129 @@ static void icnss_sysfs_destroy(struct icnss_priv *priv) kobject_put(icnss_kobject); kobject_put(icnss_kobject); } } static ssize_t qdss_tr_start_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct icnss_priv *priv = dev_get_drvdata(dev); wlfw_qdss_trace_start(priv); icnss_pr_dbg("Received QDSS start command\n"); return count; } static ssize_t qdss_tr_stop_store(struct device *dev, struct device_attribute *attr, const char *user_buf, size_t count) { struct icnss_priv *priv = dev_get_drvdata(dev); u32 option = 0; if (sscanf(user_buf, "%du", &option) != 1) return -EINVAL; wlfw_qdss_trace_stop(priv, option); icnss_pr_dbg("Received QDSS stop command\n"); return count; } static ssize_t qdss_conf_download_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct icnss_priv *priv = dev_get_drvdata(dev); icnss_wlfw_qdss_dnld_send_sync(priv); icnss_pr_dbg("Received QDSS download config command\n"); return count; } static ssize_t hw_trc_override_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct icnss_priv *priv = dev_get_drvdata(dev); int tmp = 0; if (sscanf(buf, "%du", &tmp) != 1) return -EINVAL; priv->hw_trc_override = tmp; icnss_pr_dbg("Received QDSS hw_trc_override indication\n"); return count; } static DEVICE_ATTR_WO(qdss_tr_start); static DEVICE_ATTR_WO(qdss_tr_stop); static DEVICE_ATTR_WO(qdss_conf_download); static DEVICE_ATTR_WO(hw_trc_override); static struct attribute *icnss_attrs[] = { &dev_attr_qdss_tr_start.attr, &dev_attr_qdss_tr_stop.attr, &dev_attr_qdss_conf_download.attr, &dev_attr_hw_trc_override.attr, NULL, }; static struct attribute_group icnss_attr_group = { .attrs = icnss_attrs, }; static int icnss_create_sysfs_link(struct icnss_priv *priv) { struct device *dev = &priv->pdev->dev; int ret; ret = sysfs_create_link(kernel_kobj, &dev->kobj, "icnss"); if (ret) { icnss_pr_err("Failed to create icnss link, err = %d\n", ret); goto out; } return 0; out: return ret; } static void icnss_remove_sysfs_link(struct icnss_priv *priv) { sysfs_remove_link(kernel_kobj, "icnss"); } int icnss_sysfs_create(struct icnss_priv *priv) { int ret = 0; ret = devm_device_add_group(&priv->pdev->dev, &icnss_attr_group); if (ret) { icnss_pr_err("Failed to create icnss device group, err = %d\n", ret); goto out; } icnss_create_sysfs_link(priv); ret = icnss_create_shutdown_sysfs(priv); if (ret) goto remove_icnss_group; return 0; remove_icnss_group: devm_device_remove_group(&priv->pdev->dev, &icnss_attr_group); out: return ret; } void icnss_sysfs_destroy(struct icnss_priv *priv) { icnss_destroy_shutdown_sysfs(priv); icnss_remove_sysfs_link(priv); devm_device_remove_group(&priv->pdev->dev, &icnss_attr_group); } static int icnss_get_vbatt_info(struct icnss_priv *priv) static int icnss_get_vbatt_info(struct icnss_priv *priv) { { struct adc_tm_chip *adc_tm_dev = NULL; struct adc_tm_chip *adc_tm_dev = NULL; Loading
drivers/soc/qcom/icnss2/main.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -428,6 +428,7 @@ struct icnss_priv { void *hang_event_data; void *hang_event_data; struct list_head icnss_tcdev_list; struct list_head icnss_tcdev_list; struct mutex tcdev_lock; struct mutex tcdev_lock; u32 hw_trc_override; }; }; struct icnss_reg_info { struct icnss_reg_info { Loading
drivers/soc/qcom/icnss2/qmi.c +89 −1 Original line number Original line Diff line number Diff line Loading @@ -1207,6 +1207,94 @@ int wlfw_wlan_mode_send_sync_msg(struct icnss_priv *priv, return ret; return ret; } } static int wlfw_send_qdss_trace_mode_req (struct icnss_priv *priv, enum wlfw_qdss_trace_mode_enum_v01 mode, unsigned long long option) { int rc = 0; int tmp = 0; struct wlfw_qdss_trace_mode_req_msg_v01 *req; struct wlfw_qdss_trace_mode_resp_msg_v01 *resp; struct qmi_txn txn; if (!priv) return -ENODEV; req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; resp = kzalloc(sizeof(*resp), GFP_KERNEL); if (!resp) { kfree(req); return -ENOMEM; } req->mode_valid = 1; req->mode = mode; req->option_valid = 1; req->option = option; tmp = priv->hw_trc_override; req->hw_trc_disable_override_valid = 1; req->hw_trc_disable_override = (tmp > QMI_PARAM_DISABLE_V01 ? QMI_PARAM_DISABLE_V01 : (tmp < 0 ? QMI_PARAM_INVALID_V01 : tmp)); icnss_pr_dbg("%s: mode %u, option %llu, hw_trc_disable_override: %u", __func__, mode, option, req->hw_trc_disable_override); rc = qmi_txn_init(&priv->qmi, &txn, wlfw_qdss_trace_mode_resp_msg_v01_ei, resp); if (rc < 0) { icnss_qmi_fatal_err("Fail to init txn for QDSS Mode resp %d\n", rc); goto out; } rc = qmi_send_request(&priv->qmi, NULL, &txn, QMI_WLFW_QDSS_TRACE_MODE_REQ_V01, WLFW_QDSS_TRACE_MODE_REQ_MSG_V01_MAX_MSG_LEN, wlfw_qdss_trace_mode_req_msg_v01_ei, req); if (rc < 0) { qmi_txn_cancel(&txn); icnss_qmi_fatal_err("Fail to send QDSS Mode req %d\n", rc); goto out; } rc = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout); if (rc < 0) { icnss_qmi_fatal_err("QDSS Mode resp wait failed with rc %d\n", rc); goto out; } else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { icnss_qmi_fatal_err( "QMI QDSS Mode request rejected, result:%d error:%d\n", resp->resp.result, resp->resp.error); rc = -resp->resp.result; goto out; } out: kfree(resp); kfree(req); return rc; } int wlfw_qdss_trace_start(struct icnss_priv *priv) { return wlfw_send_qdss_trace_mode_req(priv, QMI_WLFW_QDSS_TRACE_ON_V01, 0); } int wlfw_qdss_trace_stop(struct icnss_priv *priv, unsigned long long option) { return wlfw_send_qdss_trace_mode_req(priv, QMI_WLFW_QDSS_TRACE_OFF_V01, option); } int wlfw_wlan_cfg_send_sync_msg(struct icnss_priv *priv, int wlfw_wlan_cfg_send_sync_msg(struct icnss_priv *priv, struct wlfw_wlan_cfg_req_msg_v01 *data) struct wlfw_wlan_cfg_req_msg_v01 *data) { { Loading
drivers/soc/qcom/icnss2/qmi.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -209,6 +209,8 @@ int icnss_wlfw_bdf_dnld_send_sync(struct icnss_priv *priv, u32 bdf_type); int icnss_wlfw_qdss_dnld_send_sync(struct icnss_priv *priv); int icnss_wlfw_qdss_dnld_send_sync(struct icnss_priv *priv); int icnss_wlfw_qdss_data_send_sync(struct icnss_priv *priv, char *file_name, int icnss_wlfw_qdss_data_send_sync(struct icnss_priv *priv, char *file_name, u32 total_size); u32 total_size); int wlfw_qdss_trace_start(struct icnss_priv *priv); int wlfw_qdss_trace_stop(struct icnss_priv *priv, unsigned long long option); int wlfw_qdss_trace_mem_info_send_sync(struct icnss_priv *priv); int wlfw_qdss_trace_mem_info_send_sync(struct icnss_priv *priv); int wlfw_power_save_send_msg(struct icnss_priv *priv, int wlfw_power_save_send_msg(struct icnss_priv *priv, enum wlfw_power_save_mode_v01 mode); enum wlfw_power_save_mode_v01 mode); Loading