cnss2: Send QMI message to download TME-L patch

Send QMI message with TME-L patch information to WLAN FW, to
download TME-L patch.

Change-Id: Ieae07c0f761ada45ffcb990b1412654b9c6862b1
CRs-Fixed: 3521187
This commit is contained in:
Naman Padhiar
2023-03-28 21:27:36 +05:30
committed by Rahul Choudhary
parent 2ec2768bfc
commit bdd3c6bf67
8 changed files with 180 additions and 0 deletions

View File

@@ -139,6 +139,21 @@ void cnss_bus_add_fw_prefix_name(struct cnss_plat_data *plat_priv,
} }
} }
int cnss_bus_load_tme_patch(struct cnss_plat_data *plat_priv)
{
if (!plat_priv)
return -ENODEV;
switch (plat_priv->bus_type) {
case CNSS_BUS_PCI:
return cnss_pci_load_tme_patch(plat_priv->bus_priv);
default:
cnss_pr_err("Unsupported bus type: %d\n",
plat_priv->bus_type);
return -EINVAL;
}
}
int cnss_bus_load_m3(struct cnss_plat_data *plat_priv) int cnss_bus_load_m3(struct cnss_plat_data *plat_priv)
{ {
if (!plat_priv) if (!plat_priv)

View File

@@ -21,6 +21,7 @@ int cnss_bus_init(struct cnss_plat_data *plat_priv);
void cnss_bus_deinit(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, void cnss_bus_add_fw_prefix_name(struct cnss_plat_data *plat_priv,
char *prefix_name, char *name); char *prefix_name, char *name);
int cnss_bus_load_tme_patch(struct cnss_plat_data *plat_priv);
int cnss_bus_load_m3(struct cnss_plat_data *plat_priv); int cnss_bus_load_m3(struct cnss_plat_data *plat_priv);
int cnss_bus_load_aux(struct cnss_plat_data *plat_priv); int cnss_bus_load_aux(struct cnss_plat_data *plat_priv);
int cnss_bus_handle_dev_sol_irq(struct cnss_plat_data *plat_priv); int cnss_bus_handle_dev_sol_irq(struct cnss_plat_data *plat_priv);

View File

@@ -842,6 +842,11 @@ static int cnss_fw_mem_ready_hdlr(struct cnss_plat_data *plat_priv)
if (ret) if (ret)
goto out; goto out;
cnss_bus_load_tme_patch(plat_priv);
cnss_wlfw_tme_patch_dnld_send_sync(plat_priv,
WLFW_TME_LITE_PATCH_FILE_V01);
if (plat_priv->hds_enabled) if (plat_priv->hds_enabled)
cnss_wlfw_bdf_dnld_send_sync(plat_priv, CNSS_BDF_HDS); cnss_wlfw_bdf_dnld_send_sync(plat_priv, CNSS_BDF_HDS);

View File

@@ -548,6 +548,7 @@ struct cnss_plat_data {
u32 fw_mem_seg_len; u32 fw_mem_seg_len;
struct cnss_fw_mem fw_mem[QMI_WLFW_MAX_NUM_MEM_SEG_V01]; struct cnss_fw_mem fw_mem[QMI_WLFW_MAX_NUM_MEM_SEG_V01];
struct cnss_fw_mem m3_mem; struct cnss_fw_mem m3_mem;
struct cnss_fw_mem tme_lite_mem;
struct cnss_fw_mem *cal_mem; struct cnss_fw_mem *cal_mem;
struct cnss_fw_mem aux_mem; struct cnss_fw_mem aux_mem;
u64 cal_time; u64 cal_time;

View File

@@ -49,6 +49,7 @@
#define DEFAULT_PHY_M3_FILE_NAME "m3.bin" #define DEFAULT_PHY_M3_FILE_NAME "m3.bin"
#define DEFAULT_AUX_FILE_NAME "aux_ucode.elf" #define DEFAULT_AUX_FILE_NAME "aux_ucode.elf"
#define DEFAULT_PHY_UCODE_FILE_NAME "phy_ucode.elf" #define DEFAULT_PHY_UCODE_FILE_NAME "phy_ucode.elf"
#define TME_PATCH_FILE_NAME "tmel_patch.elf"
#define PHY_UCODE_V2_FILE_NAME "phy_ucode20.elf" #define PHY_UCODE_V2_FILE_NAME "phy_ucode20.elf"
#define DEFAULT_FW_FILE_NAME "amss.bin" #define DEFAULT_FW_FILE_NAME "amss.bin"
#define FW_V2_FILE_NAME "amss20.bin" #define FW_V2_FILE_NAME "amss20.bin"
@@ -4762,6 +4763,78 @@ void cnss_pci_free_qdss_mem(struct cnss_pci_data *pci_priv)
plat_priv->qdss_mem_seg_len = 0; plat_priv->qdss_mem_seg_len = 0;
} }
int cnss_pci_load_tme_patch(struct cnss_pci_data *pci_priv)
{
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
struct cnss_fw_mem *tme_lite_mem = &plat_priv->tme_lite_mem;
char filename[MAX_FIRMWARE_NAME_LEN];
char *tme_patch_filename = NULL;
const struct firmware *fw_entry;
int ret = 0;
switch (pci_priv->device_id) {
case PEACH_DEVICE_ID:
tme_patch_filename = TME_PATCH_FILE_NAME;
break;
case QCA6174_DEVICE_ID:
case QCA6290_DEVICE_ID:
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
case KIWI_DEVICE_ID:
case MANGO_DEVICE_ID:
default:
cnss_pr_dbg("TME-L not supported for device ID: (0x%x)\n",
pci_priv->device_id);
return 0;
}
if (!tme_lite_mem->va && !tme_lite_mem->size) {
cnss_pci_add_fw_prefix_name(pci_priv, filename,
tme_patch_filename);
ret = firmware_request_nowarn(&fw_entry, filename,
&pci_priv->pci_dev->dev);
if (ret) {
cnss_pr_err("Failed to load TME-L patch: %s, ret: %d\n",
filename, ret);
return ret;
}
tme_lite_mem->va = dma_alloc_coherent(&pci_priv->pci_dev->dev,
fw_entry->size, &tme_lite_mem->pa,
GFP_KERNEL);
if (!tme_lite_mem->va) {
cnss_pr_err("Failed to allocate memory for M3, size: 0x%zx\n",
fw_entry->size);
release_firmware(fw_entry);
return -ENOMEM;
}
memcpy(tme_lite_mem->va, fw_entry->data, fw_entry->size);
tme_lite_mem->size = fw_entry->size;
release_firmware(fw_entry);
}
return 0;
}
static void cnss_pci_free_tme_lite_mem(struct cnss_pci_data *pci_priv)
{
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
struct cnss_fw_mem *tme_lite_mem = &plat_priv->tme_lite_mem;
if (tme_lite_mem->va && tme_lite_mem->size) {
cnss_pr_dbg("Freeing memory for TME patch, va: 0x%pK, pa: %pa, size: 0x%zx\n",
tme_lite_mem->va, &tme_lite_mem->pa, tme_lite_mem->size);
dma_free_coherent(&pci_priv->pci_dev->dev, tme_lite_mem->size,
tme_lite_mem->va, tme_lite_mem->pa);
}
tme_lite_mem->va = NULL;
tme_lite_mem->pa = 0;
tme_lite_mem->size = 0;
}
int cnss_pci_load_m3(struct cnss_pci_data *pci_priv) int cnss_pci_load_m3(struct cnss_pci_data *pci_priv)
{ {
struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
@@ -7123,6 +7196,7 @@ static void cnss_pci_remove(struct pci_dev *pci_dev)
clear_bit(CNSS_PCI_PROBE_DONE, &plat_priv->driver_state); clear_bit(CNSS_PCI_PROBE_DONE, &plat_priv->driver_state);
cnss_pci_unregister_driver_hdlr(pci_priv); cnss_pci_unregister_driver_hdlr(pci_priv);
cnss_pci_free_aux_mem(pci_priv); cnss_pci_free_aux_mem(pci_priv);
cnss_pci_free_tme_lite_mem(pci_priv);
cnss_pci_free_m3_mem(pci_priv); cnss_pci_free_m3_mem(pci_priv);
cnss_pci_free_fw_mem(pci_priv); cnss_pci_free_fw_mem(pci_priv);
cnss_pci_free_qdss_mem(pci_priv); cnss_pci_free_qdss_mem(pci_priv);

View File

@@ -253,6 +253,7 @@ void cnss_pci_add_fw_prefix_name(struct cnss_pci_data *pci_priv,
int cnss_pci_alloc_fw_mem(struct cnss_pci_data *pci_priv); int cnss_pci_alloc_fw_mem(struct cnss_pci_data *pci_priv);
int cnss_pci_alloc_qdss_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); void cnss_pci_free_qdss_mem(struct cnss_pci_data *pci_priv);
int cnss_pci_load_tme_patch(struct cnss_pci_data *pci_priv);
int cnss_pci_load_m3(struct cnss_pci_data *pci_priv); int cnss_pci_load_m3(struct cnss_pci_data *pci_priv);
void cnss_pci_free_blob_mem(struct cnss_pci_data *pci_priv); void cnss_pci_free_blob_mem(struct cnss_pci_data *pci_priv);
int cnss_pci_load_aux(struct cnss_pci_data *pci_priv); int cnss_pci_load_aux(struct cnss_pci_data *pci_priv);

View File

@@ -1017,6 +1017,87 @@ err_req_fw:
return ret; return ret;
} }
int cnss_wlfw_tme_patch_dnld_send_sync(struct cnss_plat_data *plat_priv,
enum wlfw_tme_lite_file_type_v01 file)
{
struct wlfw_tme_lite_info_req_msg_v01 *req;
struct wlfw_tme_lite_info_resp_msg_v01 *resp;
struct qmi_txn txn;
struct cnss_fw_mem *tme_lite_mem = &plat_priv->tme_lite_mem;
int ret = 0;
cnss_pr_dbg("Sending TME patch information message, state: 0x%lx\n",
plat_priv->driver_state);
if (plat_priv->device_id != PEACH_DEVICE_ID)
return 0;
req = kzalloc(sizeof(*req), GFP_KERNEL);
if (!req)
return -ENOMEM;
resp = kzalloc(sizeof(*resp), GFP_KERNEL);
if (!resp) {
kfree(req);
return -ENOMEM;
}
if (!tme_lite_mem->pa || !tme_lite_mem->size) {
cnss_pr_err("Memory for TME patch is not available\n");
ret = -ENOMEM;
goto out;
}
cnss_pr_dbg("TME-L patch memory, va: 0x%pK, pa: %pa, size: 0x%zx\n",
tme_lite_mem->va, &tme_lite_mem->pa, tme_lite_mem->size);
req->tme_file = file;
req->addr = plat_priv->tme_lite_mem.pa;
req->size = plat_priv->tme_lite_mem.size;
ret = qmi_txn_init(&plat_priv->qmi_wlfw, &txn,
wlfw_tme_lite_info_resp_msg_v01_ei, resp);
if (ret < 0) {
cnss_pr_err("Failed to initialize txn for TME patch information request, err: %d\n",
ret);
goto out;
}
ret = qmi_send_request(&plat_priv->qmi_wlfw, NULL, &txn,
QMI_WLFW_TME_LITE_INFO_REQ_V01,
WLFW_TME_LITE_INFO_REQ_MSG_V01_MAX_MSG_LEN,
wlfw_tme_lite_info_req_msg_v01_ei, req);
if (ret < 0) {
qmi_txn_cancel(&txn);
cnss_pr_err("Failed to send TME patch information request, 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 response of TME patch information request, err: %d\n",
ret);
goto out;
}
if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
cnss_pr_err("TME patch information request failed, result: %d, err: %d\n",
resp->resp.result, resp->resp.error);
ret = -resp->resp.result;
goto out;
}
kfree(req);
kfree(resp);
return 0;
out:
kfree(req);
kfree(resp);
return ret;
}
int cnss_wlfw_m3_dnld_send_sync(struct cnss_plat_data *plat_priv) int cnss_wlfw_m3_dnld_send_sync(struct cnss_plat_data *plat_priv)
{ {
struct wlfw_m3_info_req_msg_v01 *req; struct wlfw_m3_info_req_msg_v01 *req;

View File

@@ -44,6 +44,8 @@ int cnss_wlfw_respond_mem_send_sync(struct cnss_plat_data *plat_priv);
int cnss_wlfw_tgt_cap_send_sync(struct cnss_plat_data *plat_priv); int cnss_wlfw_tgt_cap_send_sync(struct cnss_plat_data *plat_priv);
int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv, int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv,
u32 bdf_type); u32 bdf_type);
int cnss_wlfw_tme_patch_dnld_send_sync(struct cnss_plat_data *plat_priv,
enum wlfw_tme_lite_file_type_v01 file);
int cnss_wlfw_m3_dnld_send_sync(struct cnss_plat_data *plat_priv); int cnss_wlfw_m3_dnld_send_sync(struct cnss_plat_data *plat_priv);
int cnss_wlfw_aux_dnld_send_sync(struct cnss_plat_data *plat_priv); int cnss_wlfw_aux_dnld_send_sync(struct cnss_plat_data *plat_priv);
int cnss_wlfw_wlan_mode_send_sync(struct cnss_plat_data *plat_priv, int cnss_wlfw_wlan_mode_send_sync(struct cnss_plat_data *plat_priv,