Merge "cnss2: Add support for PCIE gen switch"

This commit is contained in:
qctecmdr 2020-08-11 15:30:42 -07:00 • committed by Gerrit - the friendly Code Review server
commit 50ea7fd3ee
6 changed files with 90 additions and 1 deletions

View file

@ -49,6 +49,7 @@
cnss_get_user_msi_assignment
cnss_get_msi_irq
cnss_get_msi_address
cnss_set_pcie_gen_speed
register_cld_cmd_cb
deregister_cld_cmd_cb
cld80211_get_genl_family

View file

@ -318,6 +318,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;
@ -395,6 +413,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);

View file

@ -407,6 +407,8 @@ struct cnss_plat_data {
u8 use_nv_mac;
u8 set_wlaon_pwr_ctrl;
struct cnss_tcs_info tcs_info;
bool fw_pcie_gen_switch;
u8 pcie_gen_speed;
};
#ifdef CONFIG_ARCH_QCOM

View file

@ -452,6 +452,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,
@ -1287,6 +1291,64 @@ out:
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;

View file

@ -67,6 +67,7 @@ int coex_antenna_switch_to_mdm_send_sync_msg(struct cnss_plat_data *plat_priv);
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);
int cnss_wlfw_send_pcie_gen_speed_sync(struct cnss_plat_data *plat_priv);
#else
#define QMI_WLFW_TIMEOUT_MS 10000
@ -217,6 +218,9 @@ int cnss_register_ims_service(struct cnss_plat_data *plat_priv)
static inline
void cnss_unregister_ims_service(struct cnss_plat_data *plat_priv) {}
static inline
int cnss_wlfw_send_pcie_gen_speed_sync(struct cnss_plat_data *plat_priv) {}
#endif /* CONFIG_CNSS2_QMI */
#endif /* _CNSS_QMI_H */

View file

@ -237,5 +237,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 */