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

Commit 7ef7c984 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cnss2: Add support for PCIE gen switch"

parents 6d79a96a 43f18d00
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -357,6 +357,24 @@ int cnss_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
}
EXPORT_SYMBOL(cnss_set_fw_log_mode);

int cnss_set_pcie_gen_speed(struct device *dev, u8 pcie_gen_speed)
{
	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);

	if (plat_priv->device_id != QCA6490_DEVICE_ID ||
	    !plat_priv->fw_pcie_gen_switch)
		return -ENOTSUPP;

	if (pcie_gen_speed < QMI_PCIE_GEN_SPEED_1_V01 ||
	    pcie_gen_speed > QMI_PCIE_GEN_SPEED_3_V01)
		return -EINVAL;

	cnss_pr_dbg("WLAN provided PCIE gen speed: %d\n", pcie_gen_speed);
	plat_priv->pcie_gen_speed = pcie_gen_speed;
	return 0;
}
EXPORT_SYMBOL(cnss_set_pcie_gen_speed);

static int cnss_fw_mem_ready_hdlr(struct cnss_plat_data *plat_priv)
{
	int ret = 0;
@@ -433,6 +451,8 @@ static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv)
	set_bit(CNSS_FW_READY, &plat_priv->driver_state);
	clear_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state);

	cnss_wlfw_send_pcie_gen_speed_sync(plat_priv);

	if (test_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state)) {
		clear_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state);
		clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
+2 −0
Original line number Diff line number Diff line
@@ -403,6 +403,8 @@ struct cnss_plat_data {
	int (*get_info_cb)(void *ctx, void *event, int event_len);
	u8 use_nv_mac;
	u8 set_wlaon_pwr_ctrl;
	u8 fw_pcie_gen_switch;
	u8 pcie_gen_speed;
};

#ifdef CONFIG_ARCH_QCOM
+62 −0
Original line number Diff line number Diff line
@@ -461,6 +461,10 @@ int cnss_wlfw_tgt_cap_send_sync(struct cnss_plat_data *plat_priv)
	if (resp->otp_version_valid)
		plat_priv->otp_version = resp->otp_version;

	if (resp->fw_caps_valid)
		plat_priv->fw_pcie_gen_switch =
			!!(resp->fw_caps & QMI_WLFW_HOST_PCIE_GEN_SWITCH_V01);

	cnss_pr_dbg("Target capability: chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x, fw_version: 0x%x, fw_build_timestamp: %s, fw_build_id: %s, otp_version: 0x%x\n",
		    plat_priv->chip_info.chip_id,
		    plat_priv->chip_info.chip_family,
@@ -1296,6 +1300,64 @@ int cnss_wlfw_ini_send_sync(struct cnss_plat_data *plat_priv,
	return ret;
}

int cnss_wlfw_send_pcie_gen_speed_sync(struct cnss_plat_data *plat_priv)
{
	struct wlfw_pcie_gen_switch_req_msg_v01 req;
	struct wlfw_pcie_gen_switch_resp_msg_v01 resp;
	struct qmi_txn txn;
	int ret = 0;

	if (!plat_priv)
		return -ENODEV;

	if (plat_priv->pcie_gen_speed == QMI_PCIE_GEN_SPEED_INVALID_V01 ||
	    !plat_priv->fw_pcie_gen_switch) {
		cnss_pr_dbg("PCIE Gen speed not setup\n");
		return 0;
	}

	cnss_pr_dbg("Sending PCIE Gen speed: %d state: 0x%lx\n",
		    plat_priv->pcie_gen_speed, plat_priv->driver_state);
	req.pcie_speed = (enum wlfw_pcie_gen_speed_v01)
			plat_priv->pcie_gen_speed;

	ret = qmi_txn_init(&plat_priv->qmi_wlfw, &txn,
			   wlfw_pcie_gen_switch_resp_msg_v01_ei, &resp);
	if (ret < 0) {
		cnss_pr_err("Failed to initialize txn for PCIE speed switch err: %d\n",
			    ret);
		goto out;
	}

	ret = qmi_send_request(&plat_priv->qmi_wlfw, NULL, &txn,
			       QMI_WLFW_PCIE_GEN_SWITCH_REQ_V01,
			       WLFW_PCIE_GEN_SWITCH_REQ_MSG_V01_MAX_MSG_LEN,
			       wlfw_pcie_gen_switch_req_msg_v01_ei, &req);
	if (ret < 0) {
		qmi_txn_cancel(&txn);
		cnss_pr_err("Failed to send PCIE speed switch, err: %d\n", ret);
		goto out;
	}

	ret = qmi_txn_wait(&txn, QMI_WLFW_TIMEOUT_JF);
	if (ret < 0) {
		cnss_pr_err("Failed to wait for PCIE Gen switch resp, err: %d\n",
			    ret);
		goto out;
	}

	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
		cnss_pr_err("PCIE Gen Switch req failed, Speed: %d, result: %d, err: %d\n",
			    plat_priv->pcie_gen_speed, resp.resp.result,
			    resp.resp.error);
		ret = -resp.resp.result;
	}
out:
	/* Reset PCIE Gen speed after one time use */
	plat_priv->pcie_gen_speed = QMI_PCIE_GEN_SPEED_INVALID_V01;
	return ret;
}

int cnss_wlfw_antenna_switch_send_sync(struct cnss_plat_data *plat_priv)
{
	struct wlfw_antenna_switch_req_msg_v01 *req;
+4 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ int cnss_wlfw_qdss_trace_mem_info_send_sync(struct cnss_plat_data *plat_priv);
int cnss_register_ims_service(struct cnss_plat_data *plat_priv);
void cnss_unregister_ims_service(struct cnss_plat_data *plat_priv);
void cnss_ignore_qmi_failure(bool ignore);
int cnss_wlfw_send_pcie_gen_speed_sync(struct cnss_plat_data *plat_priv);
#else
#define QMI_WLFW_TIMEOUT_MS		10000

@@ -226,6 +227,9 @@ static inline
void cnss_unregister_ims_service(struct cnss_plat_data *plat_priv) {}

void cnss_ignore_qmi_failure(bool ignore) {};
static inline
int cnss_wlfw_send_pcie_gen_speed_sync(struct cnss_plat_data *plat_priv) {}

#endif /* CONFIG_CNSS2_QMI */

#endif /* _CNSS_QMI_H */
+1 −1
Original line number Diff line number Diff line
@@ -240,5 +240,5 @@ extern int cnss_athdiag_write(struct device *dev, uint32_t offset,
			      uint32_t mem_type, uint32_t data_len,
			      uint8_t *input);
extern int cnss_set_fw_log_mode(struct device *dev, uint8_t fw_log_mode);

extern int cnss_set_pcie_gen_speed(struct device *dev, u8 pcie_gen_speed);
#endif /* _NET_CNSS2_H */