cnss2: Send QMI message to download TME binaries
Send QMI message with SEC, RPR and DPR file information to WLAN FW, to download TME binaries (sec, rpr, dpr files) Change-Id: I0a4ab7ab127d493ef62d14658be2aa08b7d41606 CRs-Fixed: 3684131
This commit is contained in:

committed by
Ravindra Konda

parent
6d5176c254
commit
dc9f45faee
47
cnss2/bus.c
47
cnss2/bus.c
@@ -154,6 +154,22 @@ int cnss_bus_load_tme_patch(struct cnss_plat_data *plat_priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cnss_bus_load_tme_opt_file(struct cnss_plat_data *plat_priv,
|
||||||
|
enum wlfw_tme_lite_file_type_v01 file)
|
||||||
|
{
|
||||||
|
if (!plat_priv)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
switch (plat_priv->bus_type) {
|
||||||
|
case CNSS_BUS_PCI:
|
||||||
|
return cnss_pci_load_tme_opt_file(plat_priv->bus_priv, file);
|
||||||
|
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)
|
||||||
@@ -459,6 +475,37 @@ int cnss_bus_register_driver_hdlr(struct cnss_plat_data *plat_priv, void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cnss_bus_runtime_pm_get_sync(struct cnss_plat_data *plat_priv)
|
||||||
|
{
|
||||||
|
if (!plat_priv)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
switch (plat_priv->bus_type) {
|
||||||
|
case CNSS_BUS_PCI:
|
||||||
|
return cnss_pci_pm_runtime_get_sync(plat_priv->bus_priv, RTPM_ID_CNSS);
|
||||||
|
default:
|
||||||
|
cnss_pr_err("Unsupported bus type: %d\n",
|
||||||
|
plat_priv->bus_type);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cnss_bus_runtime_pm_put(struct cnss_plat_data *plat_priv)
|
||||||
|
{
|
||||||
|
if (!plat_priv)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (plat_priv->bus_type) {
|
||||||
|
case CNSS_BUS_PCI:
|
||||||
|
cnss_pci_pm_runtime_mark_last_busy(plat_priv->bus_priv);
|
||||||
|
cnss_pci_pm_runtime_put_autosuspend(plat_priv->bus_priv, RTPM_ID_CNSS);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cnss_pr_err("Unsupported bus type: %d\n",
|
||||||
|
plat_priv->bus_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int cnss_bus_unregister_driver_hdlr(struct cnss_plat_data *plat_priv)
|
int cnss_bus_unregister_driver_hdlr(struct cnss_plat_data *plat_priv)
|
||||||
{
|
{
|
||||||
if (!plat_priv)
|
if (!plat_priv)
|
||||||
|
@@ -22,6 +22,10 @@ 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_tme_patch(struct cnss_plat_data *plat_priv);
|
||||||
|
int cnss_bus_load_tme_opt_file(struct cnss_plat_data *plat_priv,
|
||||||
|
enum wlfw_tme_lite_file_type_v01 file);
|
||||||
|
int cnss_bus_runtime_pm_get_sync(struct cnss_plat_data *plat_priv);
|
||||||
|
void cnss_bus_runtime_pm_put(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);
|
||||||
|
57
cnss2/main.c
57
cnss2/main.c
@@ -4120,6 +4120,23 @@ static ssize_t recovery_show(struct device *dev,
|
|||||||
return curr_len;
|
return curr_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t tme_opt_file_download_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
u32 buf_size = PAGE_SIZE;
|
||||||
|
u32 curr_len = 0;
|
||||||
|
u32 buf_written = 0;
|
||||||
|
|
||||||
|
buf_written = scnprintf(buf, buf_size,
|
||||||
|
"Usage: echo [file_type] > /sys/kernel/cnss/tme_opt_file_download\n"
|
||||||
|
"file_type = sec -- For OEM_FUSE file\n"
|
||||||
|
"file_type = rpr -- For RPR file\n"
|
||||||
|
"file_type = dpr -- For DPR file\n");
|
||||||
|
|
||||||
|
curr_len += buf_written;
|
||||||
|
return curr_len;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t time_sync_period_show(struct device *dev,
|
static ssize_t time_sync_period_show(struct device *dev,
|
||||||
struct device_attribute *attr,
|
struct device_attribute *attr,
|
||||||
char *buf)
|
char *buf)
|
||||||
@@ -4369,6 +4386,44 @@ static ssize_t qdss_conf_download_store(struct device *dev,
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t tme_opt_file_download_store(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
|
||||||
|
char cmd[5];
|
||||||
|
|
||||||
|
if (sscanf(buf, "%s", cmd) != 1)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!test_bit(CNSS_FW_READY, &plat_priv->driver_state)) {
|
||||||
|
cnss_pr_err("Firmware is not ready yet\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plat_priv->device_id == PEACH_DEVICE_ID &&
|
||||||
|
cnss_bus_runtime_pm_get_sync(plat_priv) < 0)
|
||||||
|
goto runtime_pm_put;
|
||||||
|
|
||||||
|
if (strcmp(cmd, "sec") == 0) {
|
||||||
|
cnss_bus_load_tme_opt_file(plat_priv, WLFW_TME_LITE_OEM_FUSE_FILE_V01);
|
||||||
|
cnss_wlfw_tme_opt_file_dnld_send_sync(plat_priv, WLFW_TME_LITE_OEM_FUSE_FILE_V01);
|
||||||
|
} else if (strcmp(cmd, "rpr") == 0) {
|
||||||
|
cnss_bus_load_tme_opt_file(plat_priv, WLFW_TME_LITE_RPR_FILE_V01);
|
||||||
|
cnss_wlfw_tme_opt_file_dnld_send_sync(plat_priv, WLFW_TME_LITE_RPR_FILE_V01);
|
||||||
|
} else if (strcmp(cmd, "dpr") == 0) {
|
||||||
|
cnss_bus_load_tme_opt_file(plat_priv, WLFW_TME_LITE_DPR_FILE_V01);
|
||||||
|
cnss_wlfw_tme_opt_file_dnld_send_sync(plat_priv, WLFW_TME_LITE_DPR_FILE_V01);
|
||||||
|
}
|
||||||
|
|
||||||
|
cnss_pr_dbg("Received tme_opt_file_download indication cmd: %s\n", cmd);
|
||||||
|
|
||||||
|
runtime_pm_put:
|
||||||
|
if (plat_priv->device_id == PEACH_DEVICE_ID)
|
||||||
|
cnss_bus_runtime_pm_put(plat_priv);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t hw_trace_override_store(struct device *dev,
|
static ssize_t hw_trace_override_store(struct device *dev,
|
||||||
struct device_attribute *attr,
|
struct device_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
@@ -4406,6 +4461,7 @@ static DEVICE_ATTR_WO(enable_hds);
|
|||||||
static DEVICE_ATTR_WO(qdss_trace_start);
|
static DEVICE_ATTR_WO(qdss_trace_start);
|
||||||
static DEVICE_ATTR_WO(qdss_trace_stop);
|
static DEVICE_ATTR_WO(qdss_trace_stop);
|
||||||
static DEVICE_ATTR_WO(qdss_conf_download);
|
static DEVICE_ATTR_WO(qdss_conf_download);
|
||||||
|
static DEVICE_ATTR_RW(tme_opt_file_download);
|
||||||
static DEVICE_ATTR_WO(hw_trace_override);
|
static DEVICE_ATTR_WO(hw_trace_override);
|
||||||
static DEVICE_ATTR_WO(charger_mode);
|
static DEVICE_ATTR_WO(charger_mode);
|
||||||
static DEVICE_ATTR_RW(time_sync_period);
|
static DEVICE_ATTR_RW(time_sync_period);
|
||||||
@@ -4418,6 +4474,7 @@ static struct attribute *cnss_attrs[] = {
|
|||||||
&dev_attr_qdss_trace_start.attr,
|
&dev_attr_qdss_trace_start.attr,
|
||||||
&dev_attr_qdss_trace_stop.attr,
|
&dev_attr_qdss_trace_stop.attr,
|
||||||
&dev_attr_qdss_conf_download.attr,
|
&dev_attr_qdss_conf_download.attr,
|
||||||
|
&dev_attr_tme_opt_file_download.attr,
|
||||||
&dev_attr_hw_trace_override.attr,
|
&dev_attr_hw_trace_override.attr,
|
||||||
&dev_attr_charger_mode.attr,
|
&dev_attr_charger_mode.attr,
|
||||||
&dev_attr_time_sync_period.attr,
|
&dev_attr_time_sync_period.attr,
|
||||||
|
@@ -81,6 +81,10 @@
|
|||||||
#define CNSS_EVENT_SYNC_UNINTERRUPTIBLE (CNSS_EVENT_SYNC | \
|
#define CNSS_EVENT_SYNC_UNINTERRUPTIBLE (CNSS_EVENT_SYNC | \
|
||||||
CNSS_EVENT_UNINTERRUPTIBLE)
|
CNSS_EVENT_UNINTERRUPTIBLE)
|
||||||
#define CNSS_EVENT_SYNC_UNKILLABLE (CNSS_EVENT_SYNC | CNSS_EVENT_UNKILLABLE)
|
#define CNSS_EVENT_SYNC_UNKILLABLE (CNSS_EVENT_SYNC | CNSS_EVENT_UNKILLABLE)
|
||||||
|
#define QMI_WLFW_MAX_TME_OPT_FILE_NUM 3
|
||||||
|
#define TME_OEM_FUSE_FILE_NAME "peach_sec.dat"
|
||||||
|
#define TME_RPR_FILE_NAME "peach_rpr.bin"
|
||||||
|
#define TME_DPR_FILE_NAME "peach_dpr.bin"
|
||||||
|
|
||||||
enum cnss_dt_type {
|
enum cnss_dt_type {
|
||||||
CNSS_DTT_LEGACY = 0,
|
CNSS_DTT_LEGACY = 0,
|
||||||
@@ -552,6 +556,7 @@ struct cnss_plat_data {
|
|||||||
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 tme_lite_mem;
|
||||||
|
struct cnss_fw_mem tme_opt_file_mem[QMI_WLFW_MAX_TME_OPT_FILE_NUM];
|
||||||
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;
|
||||||
|
86
cnss2/pci.c
86
cnss2/pci.c
@@ -4919,6 +4919,91 @@ static void cnss_pci_free_tme_lite_mem(struct cnss_pci_data *pci_priv)
|
|||||||
tme_lite_mem->size = 0;
|
tme_lite_mem->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cnss_pci_load_tme_opt_file(struct cnss_pci_data *pci_priv,
|
||||||
|
enum wlfw_tme_lite_file_type_v01 file)
|
||||||
|
{
|
||||||
|
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
|
||||||
|
struct cnss_fw_mem *tme_lite_mem = NULL;
|
||||||
|
char filename[MAX_FIRMWARE_NAME_LEN];
|
||||||
|
char *tme_opt_filename = NULL;
|
||||||
|
const struct firmware *fw_entry;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
switch (pci_priv->device_id) {
|
||||||
|
case PEACH_DEVICE_ID:
|
||||||
|
if (file == WLFW_TME_LITE_OEM_FUSE_FILE_V01) {
|
||||||
|
tme_opt_filename = TME_OEM_FUSE_FILE_NAME;
|
||||||
|
tme_lite_mem = &plat_priv->tme_opt_file_mem[0];
|
||||||
|
} else if (file == WLFW_TME_LITE_RPR_FILE_V01) {
|
||||||
|
tme_opt_filename = TME_RPR_FILE_NAME;
|
||||||
|
tme_lite_mem = &plat_priv->tme_opt_file_mem[1];
|
||||||
|
} else if (file == WLFW_TME_LITE_DPR_FILE_V01) {
|
||||||
|
tme_opt_filename = TME_DPR_FILE_NAME;
|
||||||
|
tme_lite_mem = &plat_priv->tme_opt_file_mem[2];
|
||||||
|
}
|
||||||
|
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 opt file: %s not supported for device ID: (0x%x)\n",
|
||||||
|
tme_opt_filename, 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_opt_filename);
|
||||||
|
|
||||||
|
ret = firmware_request_nowarn(&fw_entry, filename,
|
||||||
|
&pci_priv->pci_dev->dev);
|
||||||
|
if (ret) {
|
||||||
|
cnss_pr_err("Failed to load TME-L opt file: %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 TME-L opt file %s,size: 0x%zx\n",
|
||||||
|
filename, 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_opt_file_mem(struct cnss_pci_data *pci_priv)
|
||||||
|
{
|
||||||
|
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
|
||||||
|
struct cnss_fw_mem *tme_opt_file_mem = plat_priv->tme_opt_file_mem;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < QMI_WLFW_MAX_TME_OPT_FILE_NUM; i++) {
|
||||||
|
if (tme_opt_file_mem[i].va && tme_opt_file_mem[i].size) {
|
||||||
|
cnss_pr_dbg("Free memory for TME opt file,va:0x%pK, pa:%pa, size:0x%zx\n",
|
||||||
|
tme_opt_file_mem[i].va, &tme_opt_file_mem[i].pa,
|
||||||
|
tme_opt_file_mem[i].size);
|
||||||
|
dma_free_coherent(&pci_priv->pci_dev->dev, tme_opt_file_mem[i].size,
|
||||||
|
tme_opt_file_mem[i].va, tme_opt_file_mem[i].pa);
|
||||||
|
}
|
||||||
|
tme_opt_file_mem[i].va = NULL;
|
||||||
|
tme_opt_file_mem[i].pa = 0;
|
||||||
|
tme_opt_file_mem[i].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;
|
||||||
@@ -7465,6 +7550,7 @@ static void cnss_pci_remove(struct pci_dev *pci_dev)
|
|||||||
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_tme_lite_mem(pci_priv);
|
||||||
|
cnss_pci_free_tme_opt_file_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);
|
||||||
|
@@ -260,6 +260,8 @@ 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_tme_patch(struct cnss_pci_data *pci_priv);
|
||||||
|
int cnss_pci_load_tme_opt_file(struct cnss_pci_data *pci_priv,
|
||||||
|
enum wlfw_tme_lite_file_type_v01 file);
|
||||||
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);
|
||||||
|
105
cnss2/qmi.c
105
cnss2/qmi.c
@@ -58,6 +58,10 @@
|
|||||||
#define QMI_WLFW_MAC_READY_TIMEOUT_MS 50
|
#define QMI_WLFW_MAC_READY_TIMEOUT_MS 50
|
||||||
#define QMI_WLFW_MAC_READY_MAX_RETRY 200
|
#define QMI_WLFW_MAC_READY_MAX_RETRY 200
|
||||||
|
|
||||||
|
// these error values are not defined in <linux/soc/qcom/qmi.h> and fw is sending as error response
|
||||||
|
#define QMI_ERR_HARDWARE_RESTRICTED_V01 0x0053
|
||||||
|
#define QMI_ERR_ENOMEM_V01 0x0002
|
||||||
|
|
||||||
enum nm_modem_bit {
|
enum nm_modem_bit {
|
||||||
SLEEP_CLOCK_SELECT_INTERNAL_BIT = BIT(1),
|
SLEEP_CLOCK_SELECT_INTERNAL_BIT = BIT(1),
|
||||||
HOST_CSTATE_BIT = BIT(2),
|
HOST_CSTATE_BIT = BIT(2),
|
||||||
@@ -982,6 +986,107 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cnss_wlfw_tme_opt_file_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_opt_file_mem = NULL;
|
||||||
|
char *file_name = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (plat_priv->device_id != PEACH_DEVICE_ID)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cnss_pr_dbg("Sending TME opt file information message, state: 0x%lx\n",
|
||||||
|
plat_priv->driver_state);
|
||||||
|
|
||||||
|
req = kzalloc(sizeof(*req), GFP_KERNEL);
|
||||||
|
if (!req)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
resp = kzalloc(sizeof(*resp), GFP_KERNEL);
|
||||||
|
if (!resp) {
|
||||||
|
kfree(req);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file == WLFW_TME_LITE_OEM_FUSE_FILE_V01) {
|
||||||
|
tme_opt_file_mem = &plat_priv->tme_opt_file_mem[0];
|
||||||
|
file_name = TME_OEM_FUSE_FILE_NAME;
|
||||||
|
} else if (file == WLFW_TME_LITE_RPR_FILE_V01) {
|
||||||
|
tme_opt_file_mem = &plat_priv->tme_opt_file_mem[1];
|
||||||
|
file_name = TME_RPR_FILE_NAME;
|
||||||
|
} else if (file == WLFW_TME_LITE_DPR_FILE_V01) {
|
||||||
|
tme_opt_file_mem = &plat_priv->tme_opt_file_mem[2];
|
||||||
|
file_name = TME_DPR_FILE_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tme_opt_file_mem->pa || !tme_opt_file_mem->size) {
|
||||||
|
cnss_pr_err("Memory for TME opt file is not available\n");
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
cnss_pr_dbg("TME opt file %s memory, va: 0x%pK, pa: %pa, size: 0x%zx\n",
|
||||||
|
file_name, tme_opt_file_mem->va, &tme_opt_file_mem->pa, tme_opt_file_mem->size);
|
||||||
|
|
||||||
|
req->tme_file = file;
|
||||||
|
req->addr = tme_opt_file_mem->pa;
|
||||||
|
req->size = tme_opt_file_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 opt file 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 opt file 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 opt file information request, err: %d\n",
|
||||||
|
ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
|
||||||
|
ret = -resp->resp.result;
|
||||||
|
if (resp->resp.error == QMI_ERR_HARDWARE_RESTRICTED_V01) {
|
||||||
|
cnss_pr_err("TME Power On failed\n");
|
||||||
|
goto out;
|
||||||
|
} else if (resp->resp.error == QMI_ERR_ENOMEM_V01) {
|
||||||
|
cnss_pr_err("malloc SRAM failed\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
cnss_pr_err("TME opt file information request failed, result: %d, err: %d\n",
|
||||||
|
resp->resp.result, resp->resp.error);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(req);
|
||||||
|
kfree(resp);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
CNSS_QMI_ASSERT();
|
||||||
|
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;
|
||||||
|
@@ -87,6 +87,8 @@ void cnss_dms_deinit(struct cnss_plat_data *plat_priv);
|
|||||||
int cnss_wlfw_qdss_dnld_send_sync(struct cnss_plat_data *plat_priv);
|
int cnss_wlfw_qdss_dnld_send_sync(struct cnss_plat_data *plat_priv);
|
||||||
int cnss_wlfw_qdss_data_send_sync(struct cnss_plat_data *plat_priv, char *file_name,
|
int cnss_wlfw_qdss_data_send_sync(struct cnss_plat_data *plat_priv, char *file_name,
|
||||||
u32 total_size);
|
u32 total_size);
|
||||||
|
int cnss_wlfw_tme_opt_file_dnld_send_sync(struct cnss_plat_data *plat_priv,
|
||||||
|
enum wlfw_tme_lite_file_type_v01 file);
|
||||||
int wlfw_qdss_trace_start(struct cnss_plat_data *plat_priv);
|
int wlfw_qdss_trace_start(struct cnss_plat_data *plat_priv);
|
||||||
int wlfw_qdss_trace_stop(struct cnss_plat_data *plat_priv, unsigned long long option);
|
int wlfw_qdss_trace_stop(struct cnss_plat_data *plat_priv, unsigned long long option);
|
||||||
int cnss_wlfw_cal_report_req_send_sync(struct cnss_plat_data *plat_priv,
|
int cnss_wlfw_cal_report_req_send_sync(struct cnss_plat_data *plat_priv,
|
||||||
@@ -297,6 +299,12 @@ int cnss_wlfw_qdss_data_send_sync(struct cnss_plat_data *plat_priv, char *file_n
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cnss_wlfw_tme_opt_file_dnld_send_sync(struct cnss_plat_data *plat_priv,
|
||||||
|
enum wlfw_tme_lite_file_type_v01 file)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void cnss_dms_deinit(struct cnss_plat_data *plat_priv) {}
|
static inline void cnss_dms_deinit(struct cnss_plat_data *plat_priv) {}
|
||||||
|
|
||||||
int wlfw_qdss_trace_start(struct cnss_plat_data *plat_priv)
|
int wlfw_qdss_trace_start(struct cnss_plat_data *plat_priv)
|
||||||
|
Reference in New Issue
Block a user