From 69f43964515555f92665feb1d47700cfef4ccf2d Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Fri, 3 Apr 2020 18:57:58 -0700 Subject: [PATCH] cnss2: Add fallback support for device specific path loading Add the logic to fall back to default path if it fails to load firmware from device specific path. Change-Id: I0595a3be97b6f803be232b73fb35b8b5b3c52b0e Signed-off-by: Yue Ma --- drivers/net/wireless/cnss2/main.h | 1 + drivers/net/wireless/cnss2/pci.c | 122 +++++++++++++++++------------- 2 files changed, 71 insertions(+), 52 deletions(-) diff --git a/drivers/net/wireless/cnss2/main.h b/drivers/net/wireless/cnss2/main.h index 8f677f03b7d6..41ad0ac0389a 100644 --- a/drivers/net/wireless/cnss2/main.h +++ b/drivers/net/wireless/cnss2/main.h @@ -448,6 +448,7 @@ struct cnss_plat_data { u8 powered_on; u8 use_fw_path_with_prefix; char firmware_name[MAX_FIRMWARE_NAME_LEN]; + char fw_fallback_name[MAX_FIRMWARE_NAME_LEN]; struct completion rddm_complete; struct completion recovery_complete; struct cnss_control_params ctrl_params; diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index baddb51e90fc..8855bbeffa93 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -4581,6 +4581,69 @@ void cnss_pci_add_fw_prefix_name(struct cnss_pci_data *pci_priv, cnss_pr_dbg("FW name added with prefix: %s\n", prefix_name); } +static int cnss_pci_update_fw_name(struct cnss_pci_data *pci_priv) +{ + struct cnss_plat_data *plat_priv = pci_priv->plat_priv; + struct mhi_controller *mhi_ctrl = pci_priv->mhi_ctrl; + + plat_priv->device_version.family_number = mhi_ctrl->family_number; + plat_priv->device_version.device_number = mhi_ctrl->device_number; + plat_priv->device_version.major_version = mhi_ctrl->major_version; + plat_priv->device_version.minor_version = mhi_ctrl->minor_version; + + cnss_pr_dbg("Get device version info, family number: 0x%x, device number: 0x%x, major version: 0x%x, minor version: 0x%x\n", + plat_priv->device_version.family_number, + plat_priv->device_version.device_number, + plat_priv->device_version.major_version, + plat_priv->device_version.minor_version); + + switch (pci_priv->device_id) { + case QCA6390_DEVICE_ID: + if (plat_priv->device_version.major_version < FW_V2_NUMBER) { + cnss_pr_dbg("Device ID:version (0x%lx:%d) is not supported\n", + pci_priv->device_id, + plat_priv->device_version.major_version); + return -EINVAL; + } + cnss_pci_add_fw_prefix_name(pci_priv, plat_priv->firmware_name, + FW_V2_FILE_NAME); + snprintf(plat_priv->fw_fallback_name, MAX_FIRMWARE_NAME_LEN, + FW_V2_FILE_NAME); + break; + case QCA6490_DEVICE_ID: + switch (plat_priv->device_version.major_version) { + case FW_V2_NUMBER: + cnss_pci_add_fw_prefix_name(pci_priv, + plat_priv->firmware_name, + FW_V2_FILE_NAME); + snprintf(plat_priv->fw_fallback_name, + MAX_FIRMWARE_NAME_LEN, + FW_V2_FILE_NAME); + break; + default: + cnss_pci_add_fw_prefix_name(pci_priv, + plat_priv->firmware_name, + DEFAULT_FW_FILE_NAME); + snprintf(plat_priv->fw_fallback_name, + MAX_FIRMWARE_NAME_LEN, + DEFAULT_FW_FILE_NAME); + break; + } + break; + default: + cnss_pci_add_fw_prefix_name(pci_priv, plat_priv->firmware_name, + DEFAULT_FW_FILE_NAME); + snprintf(plat_priv->fw_fallback_name, MAX_FIRMWARE_NAME_LEN, + DEFAULT_FW_FILE_NAME); + break; + } + + cnss_pr_dbg("FW name is %s, FW fallback name is %s\n", + mhi_ctrl->fw_image, mhi_ctrl->fw_image_fallback); + + return 0; +} + static char *cnss_mhi_notify_status_to_str(enum MHI_CB status) { switch (status) { @@ -4594,6 +4657,8 @@ static char *cnss_mhi_notify_status_to_str(enum MHI_CB status) return "FATAL_ERROR"; case MHI_CB_EE_MISSION_MODE: return "MISSION_MODE"; + case MHI_CB_FW_FALLBACK_IMG: + return "FW_FALLBACK"; default: return "UNKNOWN"; } @@ -4674,6 +4739,10 @@ static void cnss_mhi_notify_status(struct mhi_controller *mhi_ctrl, void *priv, cnss_pci_update_status(pci_priv, CNSS_FW_DOWN); cnss_reason = CNSS_REASON_RDDM; break; + case MHI_CB_FW_FALLBACK_IMG: + plat_priv->use_fw_path_with_prefix = false; + cnss_pci_update_fw_name(pci_priv); + return; default: cnss_pr_err("Unsupported MHI status cb reason: %d\n", reason); return; @@ -4711,58 +4780,6 @@ static int cnss_pci_get_mhi_msi(struct cnss_pci_data *pci_priv) return 0; } -static int cnss_pci_update_fw_name(struct cnss_pci_data *pci_priv) -{ - struct cnss_plat_data *plat_priv = pci_priv->plat_priv; - struct mhi_controller *mhi_ctrl = pci_priv->mhi_ctrl; - - plat_priv->device_version.family_number = mhi_ctrl->family_number; - plat_priv->device_version.device_number = mhi_ctrl->device_number; - plat_priv->device_version.major_version = mhi_ctrl->major_version; - plat_priv->device_version.minor_version = mhi_ctrl->minor_version; - - cnss_pr_dbg("Get device version info, family number: 0x%x, device number: 0x%x, major version: 0x%x, minor version: 0x%x\n", - plat_priv->device_version.family_number, - plat_priv->device_version.device_number, - plat_priv->device_version.major_version, - plat_priv->device_version.minor_version); - - switch (pci_priv->device_id) { - case QCA6390_DEVICE_ID: - if (plat_priv->device_version.major_version < FW_V2_NUMBER) { - cnss_pr_dbg("Device ID:version (0x%lx:%d) is not supported\n", - pci_priv->device_id, - plat_priv->device_version.major_version); - return -EINVAL; - } - cnss_pci_add_fw_prefix_name(pci_priv, plat_priv->firmware_name, - FW_V2_FILE_NAME); - break; - case QCA6490_DEVICE_ID: - switch (plat_priv->device_version.major_version) { - case FW_V2_NUMBER: - cnss_pci_add_fw_prefix_name(pci_priv, - plat_priv->firmware_name, - FW_V2_FILE_NAME); - break; - default: - cnss_pci_add_fw_prefix_name(pci_priv, - plat_priv->firmware_name, - DEFAULT_FW_FILE_NAME); - break; - } - break; - default: - cnss_pci_add_fw_prefix_name(pci_priv, plat_priv->firmware_name, - DEFAULT_FW_FILE_NAME); - break; - } - - cnss_pr_dbg("Firmware name is %s\n", mhi_ctrl->fw_image); - - return 0; -} - static int cnss_mhi_bw_scale(struct mhi_controller *mhi_ctrl, struct mhi_link_info *link_info) { @@ -4810,6 +4827,7 @@ static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv) mhi_ctrl->slot = PCI_SLOT(pci_dev->devfn); mhi_ctrl->fw_image = plat_priv->firmware_name; + mhi_ctrl->fw_image_fallback = plat_priv->fw_fallback_name; mhi_ctrl->regs = pci_priv->bar; mhi_ctrl->len = pci_resource_len(pci_priv->pci_dev, PCI_BAR_NUM);