Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 910f7760 authored by Aasir Rasheed's avatar Aasir Rasheed Committed by Mohammed Siddiq
Browse files

icnss: Add code to send qdss mode and sysfs interface for qdss



Add code to send qdss mode request and sysfs interface for
qdss_start, qdss_stop and qdss_config_download.

Change-Id: Ibd6f582bb121d5fd885c55ebcd8360bc13b6c37a
Signed-off-by: default avatarAasir Rasheed <arasheed@codeaurora.org>
parent df520af2
Loading
Loading
Loading
Loading
+134 −7
Original line number Original line Diff line number Diff line
@@ -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;


@@ -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;
+1 −0
Original line number Original line Diff line number Diff line
@@ -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 {
+89 −1
Original line number Original line Diff line number Diff line
@@ -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)
{
{
+2 −0
Original line number Original line Diff line number Diff line
@@ -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);