From 9f5e6a039b3ac03a3a66abe0bff32f589a6af712 Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Fri, 3 Apr 2020 18:57:58 -0700 Subject: [PATCH] cnss2: Add prefix to firmware name based on device ID WLAN firmware files will be stored at different places based on different device IDs. Hence add prefix to firmware name in order to load firmware files correctly. Change-Id: I6c92f2384fa81917ebfb01b80d8a2ee6c2c756b6 Signed-off-by: Yue Ma --- drivers/net/wireless/cnss2/bus.c | 17 +++++++++ drivers/net/wireless/cnss2/bus.h | 2 ++ drivers/net/wireless/cnss2/main.c | 8 +++++ drivers/net/wireless/cnss2/main.h | 4 ++- drivers/net/wireless/cnss2/pci.c | 59 ++++++++++++++++++++++++------- drivers/net/wireless/cnss2/pci.h | 2 ++ drivers/net/wireless/cnss2/qmi.c | 28 ++++++++------- 7 files changed, 95 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/cnss2/bus.c b/drivers/net/wireless/cnss2/bus.c index 6525f8b0f307..3d9ad40c0d95 100644 --- a/drivers/net/wireless/cnss2/bus.c +++ b/drivers/net/wireless/cnss2/bus.c @@ -95,6 +95,23 @@ void cnss_bus_deinit(struct cnss_plat_data *plat_priv) } } +void cnss_bus_add_fw_prefix_name(struct cnss_plat_data *plat_priv, + char *prefix_name, char *name) +{ + if (!plat_priv) + return; + + switch (plat_priv->bus_type) { + case CNSS_BUS_PCI: + return cnss_pci_add_fw_prefix_name(plat_priv->bus_priv, + prefix_name, name); + default: + cnss_pr_err("Unsupported bus type: %d\n", + plat_priv->bus_type); + return; + } +} + int cnss_bus_load_m3(struct cnss_plat_data *plat_priv) { if (!plat_priv) diff --git a/drivers/net/wireless/cnss2/bus.h b/drivers/net/wireless/cnss2/bus.h index f7cd54ddebb6..e8efc7d24cfb 100644 --- a/drivers/net/wireless/cnss2/bus.h +++ b/drivers/net/wireless/cnss2/bus.h @@ -24,6 +24,8 @@ void *cnss_bus_dev_to_bus_priv(struct device *dev); struct cnss_plat_data *cnss_bus_dev_to_plat_priv(struct device *dev); int cnss_bus_init(struct cnss_plat_data *plat_priv); void cnss_bus_deinit(struct cnss_plat_data *plat_priv); +void cnss_bus_add_fw_prefix_name(struct cnss_plat_data *plat_priv, + char *prefix_name, char *name); int cnss_bus_load_m3(struct cnss_plat_data *plat_priv); int cnss_bus_alloc_fw_mem(struct cnss_plat_data *plat_priv); int cnss_bus_alloc_qdss_mem(struct cnss_plat_data *plat_priv); diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index aec49bf1478b..530940bef0e3 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -2402,6 +2402,12 @@ static void cnss_get_wlaon_pwr_ctrl_info(struct cnss_plat_data *plat_priv) plat_priv->set_wlaon_pwr_ctrl); } +static bool cnss_use_fw_path_with_prefix(struct cnss_plat_data *plat_priv) +{ + return of_property_read_bool(plat_priv->plat_dev->dev.of_node, + "qcom,converged-dt"); +} + static const struct platform_device_id cnss_platform_id_table[] = { { .name = "qca6174", .driver_data = QCA6174_DEVICE_ID, }, { .name = "qca6290", .driver_data = QCA6290_DEVICE_ID, }, @@ -2467,6 +2473,8 @@ static int cnss_probe(struct platform_device *plat_dev) plat_priv->device_id = device_id->driver_data; plat_priv->bus_type = cnss_get_bus_type(plat_priv->device_id); plat_priv->use_nv_mac = cnss_use_nv_mac(plat_priv); + plat_priv->use_fw_path_with_prefix = + cnss_use_fw_path_with_prefix(plat_priv); cnss_set_plat_priv(plat_dev, plat_priv); platform_set_drvdata(plat_dev, plat_priv); INIT_LIST_HEAD(&plat_priv->vreg_list); diff --git a/drivers/net/wireless/cnss2/main.h b/drivers/net/wireless/cnss2/main.h index fef2466fb3a8..2a84c25745a7 100644 --- a/drivers/net/wireless/cnss2/main.h +++ b/drivers/net/wireless/cnss2/main.h @@ -34,6 +34,7 @@ #define TIME_CLOCK_FREQ_HZ 19200000 #define CNSS_RAMDUMP_MAGIC 0x574C414E #define CNSS_RAMDUMP_VERSION 0 +#define MAX_FIRMWARE_NAME_LEN 20 #define CNSS_EVENT_SYNC BIT(0) #define CNSS_EVENT_UNINTERRUPTIBLE BIT(1) @@ -401,7 +402,8 @@ struct cnss_plat_data { u8 *diag_reg_read_buf; u8 cal_done; u8 powered_on; - char firmware_name[13]; + u8 use_fw_path_with_prefix; + char firmware_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 1257b3ffe0ec..5dd45d489ca8 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -37,7 +37,8 @@ #define MHI_NODE_NAME "qcom,mhi" #define MHI_MSI_NAME "MHI" -#define MAX_M3_FILE_NAME_LENGTH 13 +#define QCA6390_PATH_PREFIX "qca6390/" +#define QCA6490_PATH_PREFIX "qca6490/" #define DEFAULT_M3_FILE_NAME "m3.bin" #define DEFAULT_FW_FILE_NAME "amss.bin" #define FW_V2_FILE_NAME "amss20.bin" @@ -3288,12 +3289,13 @@ int cnss_pci_load_m3(struct cnss_pci_data *pci_priv) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct cnss_fw_mem *m3_mem = &plat_priv->m3_mem; - char filename[MAX_M3_FILE_NAME_LENGTH]; + char filename[MAX_FIRMWARE_NAME_LEN]; const struct firmware *fw_entry; int ret = 0; if (!m3_mem->va && !m3_mem->size) { - snprintf(filename, sizeof(filename), DEFAULT_M3_FILE_NAME); + cnss_pci_add_fw_prefix_name(pci_priv, filename, + DEFAULT_M3_FILE_NAME); ret = request_firmware(&fw_entry, filename, &pci_priv->pci_dev->dev); @@ -4233,6 +4235,38 @@ static void cnss_mhi_pm_runtime_put_noidle(struct mhi_controller *mhi_ctrl, cnss_pci_pm_runtime_put_noidle(pci_priv); } +void cnss_pci_add_fw_prefix_name(struct cnss_pci_data *pci_priv, + char *prefix_name, char *name) +{ + struct cnss_plat_data *plat_priv; + + if (!pci_priv) + return; + + plat_priv = pci_priv->plat_priv; + + if (!plat_priv->use_fw_path_with_prefix) { + scnprintf(prefix_name, MAX_FIRMWARE_NAME_LEN, "%s", name); + return; + } + + switch (pci_priv->device_id) { + case QCA6390_DEVICE_ID: + scnprintf(prefix_name, MAX_FIRMWARE_NAME_LEN, + QCA6390_PATH_PREFIX "%s", name); + break; + case QCA6490_DEVICE_ID: + scnprintf(prefix_name, MAX_FIRMWARE_NAME_LEN, + QCA6490_PATH_PREFIX "%s", name); + break; + default: + scnprintf(prefix_name, MAX_FIRMWARE_NAME_LEN, "%s", name); + break; + } + + cnss_pr_dbg("FW name added with prefix: %s\n", prefix_name); +} + static char *cnss_mhi_notify_status_to_str(enum MHI_CB status) { switch (status) { @@ -4379,23 +4413,26 @@ static int cnss_pci_update_fw_name(struct cnss_pci_data *pci_priv) plat_priv->device_version.major_version); return -EINVAL; } - scnprintf(plat_priv->firmware_name, - sizeof(plat_priv->firmware_name), FW_V2_FILE_NAME); - mhi_ctrl->fw_image = plat_priv->firmware_name; + 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: - scnprintf(plat_priv->firmware_name, - sizeof(plat_priv->firmware_name), - FW_V2_FILE_NAME); + 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; } @@ -4587,8 +4624,6 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, cnss_set_pci_priv(pci_dev, pci_priv); plat_priv->device_id = pci_dev->device; plat_priv->bus_priv = pci_priv; - snprintf(plat_priv->firmware_name, sizeof(plat_priv->firmware_name), - DEFAULT_FW_FILE_NAME); mutex_init(&pci_priv->bus_lock); ret = of_reserved_mem_device_init(dev); diff --git a/drivers/net/wireless/cnss2/pci.h b/drivers/net/wireless/cnss2/pci.h index a1e1a67f9858..9d08e4a1a019 100644 --- a/drivers/net/wireless/cnss2/pci.h +++ b/drivers/net/wireless/cnss2/pci.h @@ -166,6 +166,8 @@ int cnss_suspend_pci_link(struct cnss_pci_data *pci_priv); int cnss_resume_pci_link(struct cnss_pci_data *pci_priv); int cnss_pci_init(struct cnss_plat_data *plat_priv); void cnss_pci_deinit(struct cnss_plat_data *plat_priv); +void cnss_pci_add_fw_prefix_name(struct cnss_pci_data *pci_priv, + char *prefix_name, char *name); int cnss_pci_alloc_fw_mem(struct cnss_pci_data *pci_priv); int cnss_pci_alloc_qdss_mem(struct cnss_pci_data *pci_priv); void cnss_pci_free_qdss_mem(struct cnss_pci_data *pci_priv); diff --git a/drivers/net/wireless/cnss2/qmi.c b/drivers/net/wireless/cnss2/qmi.c index 76c8cf081f3f..7ba8dd26f03d 100644 --- a/drivers/net/wireless/cnss2/qmi.c +++ b/drivers/net/wireless/cnss2/qmi.c @@ -12,7 +12,6 @@ #define WLFW_SERVICE_INS_ID_V01 1 #define WLFW_CLIENT_ID 0x4b4e454c -#define MAX_BDF_FILE_NAME 13 #define BDF_FILE_NAME_PREFIX "bdwlan" #define ELF_BDF_FILE_NAME "bdwlan.elf" #define ELF_BDF_FILE_NAME_PREFIX "bdwlan.e" @@ -480,42 +479,43 @@ static int cnss_get_bdf_file_name(struct cnss_plat_data *plat_priv, u32 bdf_type, char *filename, u32 filename_len) { + char filename_tmp[MAX_FIRMWARE_NAME_LEN]; int ret = 0; switch (bdf_type) { case CNSS_BDF_ELF: if (plat_priv->board_info.board_id == 0xFF) - snprintf(filename, filename_len, ELF_BDF_FILE_NAME); + snprintf(filename_tmp, filename_len, ELF_BDF_FILE_NAME); else if (plat_priv->board_info.board_id < 0xFF) - snprintf(filename, filename_len, + snprintf(filename_tmp, filename_len, ELF_BDF_FILE_NAME_PREFIX "%02x", plat_priv->board_info.board_id); else - snprintf(filename, filename_len, + snprintf(filename_tmp, filename_len, BDF_FILE_NAME_PREFIX "%02x.e%02x", plat_priv->board_info.board_id >> 8 & 0xFF, plat_priv->board_info.board_id & 0xFF); break; case CNSS_BDF_BIN: if (plat_priv->board_info.board_id == 0xFF) - snprintf(filename, filename_len, BIN_BDF_FILE_NAME); + snprintf(filename_tmp, filename_len, BIN_BDF_FILE_NAME); else if (plat_priv->board_info.board_id < 0xFF) - snprintf(filename, filename_len, + snprintf(filename_tmp, filename_len, BIN_BDF_FILE_NAME_PREFIX "%02x", plat_priv->board_info.board_id); else - snprintf(filename, filename_len, + snprintf(filename_tmp, filename_len, BDF_FILE_NAME_PREFIX "%02x.b%02x", plat_priv->board_info.board_id >> 8 & 0xFF, plat_priv->board_info.board_id & 0xFF); break; case CNSS_BDF_REGDB: - snprintf(filename, filename_len, REGDB_FILE_NAME); + snprintf(filename_tmp, filename_len, REGDB_FILE_NAME); break; case CNSS_BDF_DUMMY: cnss_pr_dbg("CNSS_BDF_DUMMY is set, sending dummy BDF\n"); - snprintf(filename, filename_len, DUMMY_BDF_FILE_NAME); - ret = MAX_BDF_FILE_NAME; + snprintf(filename_tmp, filename_len, DUMMY_BDF_FILE_NAME); + ret = MAX_FIRMWARE_NAME_LEN; break; default: cnss_pr_err("Invalid BDF type: %d\n", @@ -523,6 +523,10 @@ static int cnss_get_bdf_file_name(struct cnss_plat_data *plat_priv, ret = -EINVAL; break; } + + if (ret >= 0) + cnss_bus_add_fw_prefix_name(plat_priv, filename, filename_tmp); + return ret; } @@ -532,7 +536,7 @@ int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv, struct wlfw_bdf_download_req_msg_v01 *req; struct wlfw_bdf_download_resp_msg_v01 *resp; struct qmi_txn txn; - char filename[MAX_BDF_FILE_NAME]; + char filename[MAX_FIRMWARE_NAME_LEN]; const struct firmware *fw_entry = NULL; const u8 *temp; unsigned int remaining; @@ -555,7 +559,7 @@ int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv, filename, sizeof(filename)); if (ret > 0) { temp = DUMMY_BDF_FILE_NAME; - remaining = MAX_BDF_FILE_NAME; + remaining = MAX_FIRMWARE_NAME_LEN; goto bypass_bdf; } else if (ret < 0) { goto err_req_fw;