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

Commit ed076c8e authored by Yue Ma's avatar Yue Ma
Browse files

cnss2: Force to set calibration done if it is timed out



Device calibration timeout should not prevent driver loading. Force
to shutdown device after it is timed out and let driver loading
continue. Also reduce the calibration wait timeout value to make
sure driver can be loaded in time.

Change-Id: Ic958409207b58c21807640ab89381bf6d2ae5a17
Signed-off-by: default avatarYue Ma <yuem@codeaurora.org>
parent 8ee0788f
Loading
Loading
Loading
Loading
+23 −4
Original line number Diff line number Diff line
@@ -1222,18 +1222,36 @@ static int cnss_cold_boot_cal_start_hdlr(struct cnss_plat_data *plat_priv)
	return ret;
}

static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv)
static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv,
					void *data)
{
	struct cnss_cal_info *cal_info = data;

	if (!test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state))
		return 0;
		goto out;

	switch (cal_info->cal_status) {
	case CNSS_CAL_DONE:
		cnss_pr_dbg("Calibration completed successfully\n");
		plat_priv->cal_done = true;
		break;
	case CNSS_CAL_TIMEOUT:
		cnss_pr_dbg("Calibration timed out, force shutdown\n");
		break;
	default:
		cnss_pr_err("Unknown calibration status: %u\n",
			    cal_info->cal_status);
		break;
	}

	cnss_wlfw_wlan_mode_send_sync(plat_priv, CNSS_OFF);
	cnss_release_antenna_sharing(plat_priv);
	cnss_bus_dev_shutdown(plat_priv);
	complete(&plat_priv->cal_complete);
	clear_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);

out:
	kfree(data);
	return 0;
}

@@ -1409,7 +1427,8 @@ static void cnss_driver_event_work(struct work_struct *work)
			ret = cnss_cold_boot_cal_start_hdlr(plat_priv);
			break;
		case CNSS_DRIVER_EVENT_COLD_BOOT_CAL_DONE:
			ret = cnss_cold_boot_cal_done_hdlr(plat_priv);
			ret = cnss_cold_boot_cal_done_hdlr(plat_priv,
							   event->data);
			break;
		case CNSS_DRIVER_EVENT_REGISTER_DRIVER:
			ret = cnss_bus_register_driver_hdlr(plat_priv,
+9 −0
Original line number Diff line number Diff line
@@ -247,6 +247,15 @@ enum cnss_bdf_type {
	CNSS_BDF_DUMMY = 255,
};

enum cnss_cal_status {
	CNSS_CAL_DONE,
	CNSS_CAL_TIMEOUT,
};

struct cnss_cal_info {
	enum cnss_cal_status cal_status;
};

struct cnss_control_params {
	unsigned long quirks;
	unsigned int mhi_timeout;
+10 −4
Original line number Diff line number Diff line
@@ -1490,6 +1490,7 @@ int cnss_wlan_register_driver(struct cnss_wlan_driver *driver_ops)
	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL);
	struct cnss_pci_data *pci_priv;
	unsigned int timeout;
	struct cnss_cal_info *cal_info;

	if (!plat_priv) {
		cnss_pr_err("plat_priv is NULL\n");
@@ -1510,15 +1511,21 @@ int cnss_wlan_register_driver(struct cnss_wlan_driver *driver_ops)
	if (!test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state))
		goto register_driver;

	cal_info = kzalloc(sizeof(*cal_info), GFP_KERNEL);
	if (!cal_info)
		return -ENOMEM;

	cnss_pr_dbg("Start to wait for calibration to complete\n");

	timeout = cnss_get_boot_timeout(&pci_priv->pci_dev->dev);
	ret = wait_for_completion_timeout(&plat_priv->cal_complete,
					  msecs_to_jiffies(timeout) << 2);
					  msecs_to_jiffies(timeout));
	if (!ret) {
		cnss_pr_err("Timeout waiting for calibration to complete\n");
		ret = -EAGAIN;
		goto out;
		cal_info->cal_status = CNSS_CAL_TIMEOUT;
		cnss_driver_event_post(plat_priv,
				       CNSS_DRIVER_EVENT_COLD_BOOT_CAL_DONE,
				       0, cal_info);
	}

register_driver:
@@ -1527,7 +1534,6 @@ int cnss_wlan_register_driver(struct cnss_wlan_driver *driver_ops)
				     CNSS_EVENT_SYNC_UNINTERRUPTIBLE,
				     driver_ops);

out:
	return ret;
}
EXPORT_SYMBOL(cnss_wlan_register_driver);
+14 −2
Original line number Diff line number Diff line
@@ -1427,6 +1427,7 @@ static void cnss_wlfw_fw_ready_ind_cb(struct qmi_handle *qmi_wlfw,
{
	struct cnss_plat_data *plat_priv =
		container_of(qmi_wlfw, struct cnss_plat_data, qmi_wlfw);
	struct cnss_cal_info *cal_info;

	cnss_pr_dbg("Received QMI WLFW FW ready indication\n");

@@ -1435,8 +1436,13 @@ static void cnss_wlfw_fw_ready_ind_cb(struct qmi_handle *qmi_wlfw,
		return;
	}

	cal_info = kzalloc(sizeof(*cal_info), GFP_KERNEL);
	if (!cal_info)
		return;

	cal_info->cal_status = CNSS_CAL_DONE;
	cnss_driver_event_post(plat_priv, CNSS_DRIVER_EVENT_COLD_BOOT_CAL_DONE,
			       0, NULL);
			       0, cal_info);
}

static void cnss_wlfw_fw_init_done_ind_cb(struct qmi_handle *qmi_wlfw,
@@ -1491,6 +1497,7 @@ static void cnss_wlfw_cal_done_ind_cb(struct qmi_handle *qmi_wlfw,
{
	struct cnss_plat_data *plat_priv =
		container_of(qmi_wlfw, struct cnss_plat_data, qmi_wlfw);
	struct cnss_cal_info *cal_info;

	cnss_pr_dbg("Received QMI WLFW calibration done indication\n");

@@ -1499,8 +1506,13 @@ static void cnss_wlfw_cal_done_ind_cb(struct qmi_handle *qmi_wlfw,
		return;
	}

	cal_info = kzalloc(sizeof(*cal_info), GFP_KERNEL);
	if (!cal_info)
		return;

	cal_info->cal_status = CNSS_CAL_DONE;
	cnss_driver_event_post(plat_priv, CNSS_DRIVER_EVENT_COLD_BOOT_CAL_DONE,
			       0, NULL);
			       0, cal_info);
}

static void cnss_wlfw_qdss_trace_req_mem_ind_cb(struct qmi_handle *qmi_wlfw,