summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHsiu-Chang Chen <hsiuchangchen@google.com>2022-02-15 10:19:35 +0800
committerHsiu-Chang Chen <hsiuchangchen@google.com>2022-03-03 03:43:57 +0000
commit2af1153b42048ff3e1ad049dee7ddff26081acd2 (patch)
tree44c5c95488028d0bd883c83068b14f50a48589cf
parentef22de835ccf8c7c394dbd601c0ca1d7a4ab1681 (diff)
downloadcnss2-2af1153b42048ff3e1ad049dee7ddff26081acd2.tar.gz
wcn6740: Update cnss/mhi/qmi/qrtr drivers
Migrate wlan codes to Rel2(Post CS5) Bug: 218419889 Test: Basic functions Change-Id: Ifd845bfba4ca35d14f5606b5cf2dde12e397801b
-rw-r--r--cnss2/Kconfig9
-rw-r--r--cnss2/bus.c7
-rw-r--r--cnss2/bus.h9
-rw-r--r--cnss2/debug.c3
-rw-r--r--cnss2/main.c35
-rw-r--r--cnss2/main.h10
-rw-r--r--cnss2/pci.c142
-rw-r--r--cnss2/pci.h2
-rw-r--r--cnss2/pci_platform.h24
-rw-r--r--cnss2/pci_platform_google.c9
-rw-r--r--cnss2/pci_qcom.c11
-rw-r--r--cnss2/qmi.c21
-rw-r--r--cnss2/reg.h13
-rw-r--r--cnss_utils/cnss_plat_ipc_service_v01.c2
-rw-r--r--cnss_utils/wlan_firmware_service_v01.c40
-rw-r--r--cnss_utils/wlan_firmware_service_v01.h11
-rw-r--r--inc/cnss2.h10
-rw-r--r--mhi/core/main.c32
-rw-r--r--mhi/core/misc.c43
-rw-r--r--qmi/qmi_interface.c2
-rw-r--r--qrtr/ns.c4
-rw-r--r--qrtr/qrtr.c7
22 files changed, 339 insertions, 107 deletions
diff --git a/cnss2/Kconfig b/cnss2/Kconfig
index c6b06b3..58610be 100644
--- a/cnss2/Kconfig
+++ b/cnss2/Kconfig
@@ -90,15 +90,6 @@ config CNSS_QCA6490
These changes are needed to support the new hardware architecture
for CNSS QCA6490 chipset.
-config CNSS_WCN7850
- bool "Enable CNSS WCN7850 chipset specific changes"
- depends on CNSS2
- help
- This enables the changes from WLAN host driver that are specific to
- CNSS WCN7850 chipset.
- These changes are needed to support the new hardware architecture
- for CNSS WCN7850 chipset.
-
config CNSS_REQ_FW_DIRECT
bool "Enable request_firmware_direct for firmware or configuration file"
depends on CNSS2
diff --git a/cnss2/bus.c b/cnss2/bus.c
index 0c05001..ef1f26e 100644
--- a/cnss2/bus.c
+++ b/cnss2/bus.c
@@ -1,5 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */
+/*
+ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
#include "bus.h"
#include "debug.h"
@@ -26,7 +29,7 @@ enum cnss_dev_bus_type cnss_get_bus_type(unsigned long device_id)
case QCA6290_DEVICE_ID:
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
return CNSS_BUS_PCI;
default:
cnss_pr_err("Unknown device_id: 0x%lx\n", device_id);
diff --git a/cnss2/bus.h b/cnss2/bus.h
index 33cff28..f6634b2 100644
--- a/cnss2/bus.h
+++ b/cnss2/bus.h
@@ -1,5 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */
+/*
+ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
#ifndef _CNSS_BUS_H
#define _CNSS_BUS_H
@@ -17,8 +20,8 @@
#define QCA6390_DEVICE_ID 0x1101
#define QCA6490_VENDOR_ID 0x17CB
#define QCA6490_DEVICE_ID 0x1103
-#define WCN7850_VENDOR_ID 0x17CB
-#define WCN7850_DEVICE_ID 0x1107
+#define KIWI_VENDOR_ID 0x17CB
+#define KIWI_DEVICE_ID 0x1107
enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev);
enum cnss_dev_bus_type cnss_get_bus_type(unsigned long device_id);
diff --git a/cnss2/debug.c b/cnss2/debug.c
index aad49ea..957d501 100644
--- a/cnss2/debug.c
+++ b/cnss2/debug.c
@@ -134,6 +134,9 @@ static int cnss_stats_show_state(struct seq_file *s,
case CNSS_PCI_PROBE_DONE:
seq_puts(s, "PCI PROBE DONE");
continue;
+ case CNSS_DRIVER_REGISTER:
+ seq_puts(s, "DRIVER_REGISTERED");
+ continue;
}
seq_printf(s, "UNKNOWN-%d", i);
diff --git a/cnss2/main.c b/cnss2/main.c
index 8a5f9d3..d6b349e 100644
--- a/cnss2/main.c
+++ b/cnss2/main.c
@@ -1684,7 +1684,7 @@ EXPORT_SYMBOL(cnss_qmi_send);
static int cnss_cold_boot_cal_start_hdlr(struct cnss_plat_data *plat_priv)
{
int ret = 0;
- u32 retry = 0;
+ u32 retry = 0, timeout;
if (test_bit(CNSS_COLD_BOOT_CAL_DONE, &plat_priv->driver_state)) {
cnss_pr_dbg("Calibration complete. Ignore calibration req\n");
@@ -1716,6 +1716,15 @@ static int cnss_cold_boot_cal_start_hdlr(struct cnss_plat_data *plat_priv)
}
set_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state);
+ if (test_bit(CNSS_DRIVER_REGISTER, &plat_priv->driver_state)) {
+ timeout = cnss_get_timeout(plat_priv,
+ CNSS_TIMEOUT_CALIBRATION);
+ cnss_pr_dbg("Restarting calibration %ds timeout\n",
+ timeout / 1000);
+ if (cancel_delayed_work_sync(&plat_priv->wlan_reg_driver_work))
+ schedule_delayed_work(&plat_priv->wlan_reg_driver_work,
+ msecs_to_jiffies(timeout));
+ }
reinit_completion(&plat_priv->cal_complete);
ret = cnss_bus_dev_powerup(plat_priv);
mark_cal_fail:
@@ -1769,12 +1778,13 @@ static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv,
if (cal_info->cal_status == CNSS_CAL_DONE) {
cnss_cal_mem_upload_to_file(plat_priv);
- if (cancel_delayed_work_sync(&plat_priv->wlan_reg_driver_work)
- ) {
- cnss_pr_dbg("Schedule WLAN driver load\n");
+ if (!test_bit(CNSS_DRIVER_REGISTER, &plat_priv->driver_state))
+ goto out;
+
+ cnss_pr_dbg("Schedule WLAN driver load\n");
+ if (cancel_delayed_work_sync(&plat_priv->wlan_reg_driver_work))
schedule_delayed_work(&plat_priv->wlan_reg_driver_work,
0);
- }
}
out:
kfree(data);
@@ -2534,7 +2544,7 @@ int cnss_register_ramdump(struct cnss_plat_data *plat_priv)
case QCA6290_DEVICE_ID:
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
ret = cnss_register_ramdump_v2(plat_priv);
break;
default:
@@ -2554,7 +2564,7 @@ void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv)
case QCA6290_DEVICE_ID:
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
cnss_unregister_ramdump_v2(plat_priv);
break;
default:
@@ -2963,7 +2973,7 @@ static ssize_t fs_ready_store(struct device *dev,
case QCA6290_DEVICE_ID:
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
break;
default:
cnss_pr_err("Not supported for device ID 0x%lx\n",
@@ -2971,11 +2981,10 @@ static ssize_t fs_ready_store(struct device *dev,
return count;
}
- if (fs_ready == FILE_SYSTEM_READY && plat_priv->cbc_enabled) {
+ if (fs_ready == FILE_SYSTEM_READY && plat_priv->cbc_enabled)
cnss_driver_event_post(plat_priv,
CNSS_DRIVER_EVENT_COLD_BOOT_CAL_START,
0, NULL);
- }
return count;
}
@@ -3287,7 +3296,7 @@ static const struct platform_device_id cnss_platform_id_table[] = {
{ .name = "qca6290", .driver_data = QCA6290_DEVICE_ID, },
{ .name = "qca6390", .driver_data = QCA6390_DEVICE_ID, },
{ .name = "qca6490", .driver_data = QCA6490_DEVICE_ID, },
- { .name = "wcn7850", .driver_data = WCN7850_DEVICE_ID, },
+ { .name = "kiwi", .driver_data = KIWI_DEVICE_ID, },
{ },
};
@@ -3305,7 +3314,7 @@ static const struct of_device_id cnss_of_match_table[] = {
.compatible = "qcom,cnss-qca6490",
.data = (void *)&cnss_platform_id_table[3]},
{
- .compatible = "qcom,cnss-wcn7850",
+ .compatible = "qcom,cnss-kiwi",
.data = (void *)&cnss_platform_id_table[4]},
{ },
};
@@ -3517,7 +3526,7 @@ static bool cnss_is_valid_dt_node_found(void)
{
struct device_node *dn = NULL;
- for_each_matching_node(dn, cnss_of_match_table) {
+ for_each_node_with_property(dn, "qcom,wlan") {
if (of_device_is_available(dn))
break;
}
diff --git a/cnss2/main.h b/cnss2/main.h
index 60b2eff..2664435 100644
--- a/cnss2/main.h
+++ b/cnss2/main.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CNSS_MAIN_H
@@ -65,6 +65,7 @@
#define FW_V2_NUMBER 2
#define POWER_ON_RETRY_MAX_TIMES 3
#define POWER_ON_RETRY_DELAY_MS 500
+#define WLFW_MAX_HANG_EVENT_DATA_SIZE 384
#define CNSS_EVENT_SYNC BIT(0)
#define CNSS_EVENT_UNINTERRUPTIBLE BIT(1)
@@ -206,14 +207,12 @@ struct cnss_bus_bw_info {
* struct cnss_interconnect_cfg - CNSS platform interconnect config
* @list_head: List of interconnect path bandwidth configs
* @path_count: Count of interconnect path configured in device tree
- * @current_bw_vote: WLAN driver provided bandwidth vote
* @bus_bw_cfg_count: Number of bandwidth configs for voting. It is the array
* size of struct cnss_bus_bw_info.cfg_table
*/
struct cnss_interconnect_cfg {
struct list_head list_head;
u32 path_count;
- int current_bw_vote;
u32 bus_bw_cfg_count;
};
@@ -323,6 +322,7 @@ enum cnss_driver_state {
CNSS_QMI_DMS_CONNECTED = 20,
CNSS_DAEMON_CONNECTED,
CNSS_PCI_PROBE_DONE,
+ CNSS_DRIVER_REGISTER,
};
struct cnss_recovery_data {
@@ -536,6 +536,10 @@ struct cnss_plat_data {
bool adsp_pc_enabled;
u64 feature_list;
u8 charger_mode;
+ /* WLAN driver provided bandwidth vote */
+ int current_bw_vote;
+ u16 hang_event_data_len;
+ u32 hang_data_addr_offset;
};
#if IS_ENABLED(CONFIG_ARCH_QCOM) && !IS_ENABLED(CONFIG_WCN_GOOGLE)
diff --git a/cnss2/pci.c b/cnss2/pci.c
index 3c8c72e..b5543bd 100644
--- a/cnss2/pci.c
+++ b/cnss2/pci.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/io.h>
@@ -44,7 +44,7 @@
#define QCA6390_PATH_PREFIX "qca6390/"
#define QCA6490_PATH_PREFIX "qca6490/"
-#define WCN7850_PATH_PREFIX "wcn7850/"
+#define KIWI_PATH_PREFIX "kiwi/"
#define DEFAULT_PHY_M3_FILE_NAME "m3.bin"
#define DEFAULT_PHY_UCODE_FILE_NAME "phy_ucode.elf"
#define DEFAULT_FW_FILE_NAME "amss.bin"
@@ -854,7 +854,7 @@ static int cnss_setup_bus_bandwidth(struct cnss_plat_data *plat_priv,
}
}
if (ret == 0 && save)
- plat_priv->icc.current_bw_vote = bw;
+ plat_priv->current_bw_vote = bw;
return ret;
}
@@ -1144,7 +1144,7 @@ int cnss_pci_recover_link_down(struct cnss_pci_data *pci_priv)
switch (pci_priv->device_id) {
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
break;
default:
return -EOPNOTSUPP;
@@ -1257,6 +1257,27 @@ int cnss_pci_link_down(struct device *dev)
}
EXPORT_SYMBOL(cnss_pci_link_down);
+int cnss_pci_get_reg_dump(struct device *dev, uint8_t *buffer, uint32_t len)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
+
+ if (!pci_priv) {
+ cnss_pr_err("pci_priv is NULL\n");
+ return -ENODEV;
+ }
+
+ if (pci_priv->pci_link_state == PCI_LINK_DOWN) {
+ cnss_pr_dbg("No PCIe reg dump since PCIe is suspended(D3)\n");
+ return -EACCES;
+ }
+
+ cnss_pr_dbg("Start to get PCIe reg dump\n");
+
+ return _cnss_pci_get_reg_dump(pci_priv, buffer, len);
+}
+EXPORT_SYMBOL(cnss_pci_get_reg_dump);
+
int cnss_pcie_is_device_down(struct cnss_pci_data *pci_priv)
{
struct cnss_plat_data *plat_priv;
@@ -1296,6 +1317,27 @@ void cnss_pci_unlock_reg_window(struct device *dev, unsigned long *flags)
}
EXPORT_SYMBOL(cnss_pci_unlock_reg_window);
+int cnss_get_pci_slot(struct device *dev)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
+ struct cnss_plat_data *plat_priv = NULL;
+
+ if (!pci_priv) {
+ cnss_pr_err("pci_priv is NULL\n");
+ return -EINVAL;
+ }
+
+ plat_priv = pci_priv->plat_priv;
+ if (!plat_priv) {
+ cnss_pr_err("plat_priv is NULL\n");
+ return -ENODEV;
+ }
+
+ return plat_priv->rc_num;
+}
+EXPORT_SYMBOL(cnss_get_pci_slot);
+
/**
* cnss_pci_dump_bl_sram_mem - Dump WLAN device bootloader debug log
* @pci_priv: driver PCI bus context pointer
@@ -1327,11 +1369,11 @@ static void cnss_pci_dump_bl_sram_mem(struct cnss_pci_data *pci_priv)
pbl_log_max_size = QCA6490_DEBUG_PBL_LOG_SRAM_MAX_SIZE;
sbl_log_max_size = QCA6490_DEBUG_SBL_LOG_SRAM_MAX_SIZE;
break;
- case WCN7850_DEVICE_ID:
- pbl_bootstrap_status_reg = WCN7850_PBL_BOOTSTRAP_STATUS;
- pbl_log_sram_start = WCN7850_DEBUG_PBL_LOG_SRAM_START;
- pbl_log_max_size = WCN7850_DEBUG_PBL_LOG_SRAM_MAX_SIZE;
- sbl_log_max_size = WCN7850_DEBUG_SBL_LOG_SRAM_MAX_SIZE;
+ case KIWI_DEVICE_ID:
+ pbl_bootstrap_status_reg = KIWI_PBL_BOOTSTRAP_STATUS;
+ pbl_log_sram_start = KIWI_DEBUG_PBL_LOG_SRAM_START;
+ pbl_log_max_size = KIWI_DEBUG_PBL_LOG_SRAM_MAX_SIZE;
+ sbl_log_max_size = KIWI_DEBUG_SBL_LOG_SRAM_MAX_SIZE;
default:
return;
}
@@ -2537,7 +2579,7 @@ int cnss_pci_dev_powerup(struct cnss_pci_data *pci_priv)
case QCA6290_DEVICE_ID:
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
ret = cnss_qca6290_powerup(pci_priv);
break;
default:
@@ -2565,7 +2607,7 @@ int cnss_pci_dev_shutdown(struct cnss_pci_data *pci_priv)
case QCA6290_DEVICE_ID:
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
ret = cnss_qca6290_shutdown(pci_priv);
break;
default:
@@ -2593,7 +2635,7 @@ int cnss_pci_dev_crash_shutdown(struct cnss_pci_data *pci_priv)
case QCA6290_DEVICE_ID:
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
cnss_qca6290_crash_shutdown(pci_priv);
break;
default:
@@ -2621,7 +2663,7 @@ int cnss_pci_dev_ramdump(struct cnss_pci_data *pci_priv)
case QCA6290_DEVICE_ID:
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
ret = cnss_qca6290_ramdump(pci_priv);
break;
default:
@@ -2650,18 +2692,32 @@ static void cnss_wlan_reg_driver_work(struct work_struct *work)
container_of(work, struct cnss_plat_data, wlan_reg_driver_work.work);
struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
struct cnss_cal_info *cal_info;
+ unsigned int timeout;
if (test_bit(CNSS_COLD_BOOT_CAL_DONE, &plat_priv->driver_state)) {
goto reg_driver;
} else {
- cnss_pr_err("Timeout waiting for calibration to complete\n");
- del_timer(&plat_priv->fw_boot_timer);
if (plat_priv->charger_mode) {
cnss_pr_err("Ignore calibration timeout in charger mode\n");
return;
}
- if (!test_bit(CNSS_IN_REBOOT, &plat_priv->driver_state))
+ if (!test_bit(CNSS_IN_COLD_BOOT_CAL,
+ &plat_priv->driver_state)) {
+ timeout = cnss_get_timeout(plat_priv,
+ CNSS_TIMEOUT_CALIBRATION);
+ cnss_pr_dbg("File system not ready to start calibration. Wait for %ds..\n",
+ timeout / 1000);
+ schedule_delayed_work(&plat_priv->wlan_reg_driver_work,
+ msecs_to_jiffies(timeout));
+ return;
+ }
+
+ del_timer(&plat_priv->fw_boot_timer);
+ if (test_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state) &&
+ !test_bit(CNSS_IN_REBOOT, &plat_priv->driver_state)) {
+ cnss_pr_err("Timeout waiting for calibration to complete\n");
CNSS_ASSERT(0);
+ }
cal_info = kzalloc(sizeof(*cal_info), GFP_KERNEL);
if (!cal_info)
return;
@@ -2729,6 +2785,7 @@ int cnss_wlan_register_driver(struct cnss_wlan_driver *driver_ops)
return -ENODEV;
}
#endif
+ set_bit(CNSS_DRIVER_REGISTER, &plat_priv->driver_state);
if (!plat_priv->cbc_enabled ||
test_bit(CNSS_COLD_BOOT_CAL_DONE, &plat_priv->driver_state))
@@ -3453,7 +3510,7 @@ int cnss_auto_resume(struct device *dev)
cnss_pci_set_auto_suspended(pci_priv, 0);
mutex_unlock(&pci_priv->bus_lock);
- cnss_request_bus_bandwidth(dev, plat_priv->icc.current_bw_vote);
+ cnss_request_bus_bandwidth(dev, plat_priv->current_bw_vote);
return 0;
}
@@ -3472,7 +3529,7 @@ int cnss_pci_force_wake_request_sync(struct device *dev, int timeout_us)
switch (pci_priv->device_id) {
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
break;
default:
return 0;
@@ -3513,7 +3570,7 @@ int cnss_pci_force_wake_request(struct device *dev)
switch (pci_priv->device_id) {
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
break;
default:
return 0;
@@ -3548,7 +3605,7 @@ int cnss_pci_is_device_awake(struct device *dev)
switch (pci_priv->device_id) {
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
break;
default:
return 0;
@@ -3575,7 +3632,7 @@ int cnss_pci_force_wake_release(struct device *dev)
switch (pci_priv->device_id) {
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
break;
default:
return 0;
@@ -4243,7 +4300,7 @@ static int cnss_pci_enable_bus(struct cnss_pci_data *pci_priv)
break;
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
pci_priv->dma_bit_mask = PCI_DMA_MASK_36_BIT;
break;
default:
@@ -4529,6 +4586,7 @@ static void cnss_pci_send_hang_event(struct cnss_pci_data *pci_priv)
struct cnss_hang_event hang_event;
void *hang_data_va = NULL;
u64 offset = 0;
+ u16 length = 0;
int i = 0;
if (!fw_mem || !plat_priv->fw_mem_seg_len)
@@ -4538,9 +4596,20 @@ static void cnss_pci_send_hang_event(struct cnss_pci_data *pci_priv)
switch (pci_priv->device_id) {
case QCA6390_DEVICE_ID:
offset = HST_HANG_DATA_OFFSET;
+ length = HANG_DATA_LENGTH;
break;
case QCA6490_DEVICE_ID:
- offset = HSP_HANG_DATA_OFFSET;
+ /* Fallback to hard-coded values if hang event params not
+ * present in QMI. Once all the firmware branches have the
+ * fix to send params over QMI, this can be removed.
+ */
+ if (plat_priv->hang_event_data_len) {
+ offset = plat_priv->hang_data_addr_offset;
+ length = plat_priv->hang_event_data_len;
+ } else {
+ offset = HSP_HANG_DATA_OFFSET;
+ length = HANG_DATA_LENGTH;
+ }
break;
default:
cnss_pr_err("Skip Hang Event Data as unsupported Device ID received: %d\n",
@@ -4551,15 +4620,19 @@ static void cnss_pci_send_hang_event(struct cnss_pci_data *pci_priv)
for (i = 0; i < plat_priv->fw_mem_seg_len; i++) {
if (fw_mem[i].type == QMI_WLFW_MEM_TYPE_DDR_V01 &&
fw_mem[i].va) {
+ /* The offset must be < (fw_mem size- hangdata length) */
+ if (!(offset <= fw_mem[i].size - length))
+ goto exit;
+
hang_data_va = fw_mem[i].va + offset;
hang_event.hang_event_data = kmemdup(hang_data_va,
- HANG_DATA_LENGTH,
+ length,
GFP_ATOMIC);
if (!hang_event.hang_event_data) {
cnss_pr_dbg("Hang data memory alloc failed\n");
return;
}
- hang_event.hang_event_data_len = HANG_DATA_LENGTH;
+ hang_event.hang_event_data_len = length;
break;
}
}
@@ -4568,6 +4641,11 @@ static void cnss_pci_send_hang_event(struct cnss_pci_data *pci_priv)
kfree(hang_event.hang_event_data);
hang_event.hang_event_data = NULL;
+ return;
+exit:
+ cnss_pr_dbg("Invalid hang event params, offset:0x%x, length:0x%x\n",
+ plat_priv->hang_data_addr_offset,
+ plat_priv->hang_event_data_len);
}
void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic)
@@ -4786,9 +4864,9 @@ void cnss_pci_add_fw_prefix_name(struct cnss_pci_data *pci_priv,
scnprintf(prefix_name, MAX_FIRMWARE_NAME_LEN,
QCA6490_PATH_PREFIX "%s", name);
break;
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
scnprintf(prefix_name, MAX_FIRMWARE_NAME_LEN,
- WCN7850_PATH_PREFIX "%s", name);
+ KIWI_PATH_PREFIX "%s", name);
break;
default:
scnprintf(prefix_name, MAX_FIRMWARE_NAME_LEN, "%s", name);
@@ -4831,6 +4909,7 @@ static int cnss_pci_update_fw_name(struct cnss_pci_data *pci_priv)
FW_V2_FILE_NAME);
break;
case QCA6490_DEVICE_ID:
+ case KIWI_DEVICE_ID:
switch (plat_priv->device_version.major_version) {
case FW_V2_NUMBER:
cnss_pci_add_fw_prefix_name(pci_priv,
@@ -5407,7 +5486,7 @@ static int cnss_pci_probe(struct pci_dev *pci_dev,
case QCA6290_DEVICE_ID:
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
cnss_pci_set_wlaon_pwr_ctrl(pci_priv, false, false, false);
timer_setup(&pci_priv->dev_rddm_timer,
cnss_dev_rddm_timeout_hdlr, 0);
@@ -5475,7 +5554,7 @@ static void cnss_pci_remove(struct pci_dev *pci_dev)
case QCA6290_DEVICE_ID:
case QCA6390_DEVICE_ID:
case QCA6490_DEVICE_ID:
- case WCN7850_DEVICE_ID:
+ case KIWI_DEVICE_ID:
cnss_pci_wake_gpio_deinit(pci_priv);
del_timer(&pci_priv->boot_debug_timer);
del_timer(&pci_priv->dev_rddm_timer);
@@ -5506,7 +5585,7 @@ static const struct pci_device_id cnss_pci_id_table[] = {
{ QCA6290_VENDOR_ID, QCA6290_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
{ QCA6390_VENDOR_ID, QCA6390_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
{ QCA6490_VENDOR_ID, QCA6490_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
- { WCN7850_VENDOR_ID, WCN7850_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
+ { KIWI_VENDOR_ID, KIWI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, cnss_pci_id_table);
@@ -5592,9 +5671,6 @@ int cnss_pci_init(struct cnss_plat_data *plat_priv)
}
ret = pci_register_driver(&cnss_pci_driver);
-#if IS_ENABLED(CONFIG_WCN_GOOGLE)
- cnss_pr_err("ret of pci_register_driver: %d\n", ret);
-#endif
if (ret) {
cnss_pr_err("Failed to register to PCI framework, err = %d\n",
ret);
diff --git a/cnss2/pci.h b/cnss2/pci.h
index 2a9a36e..16d4b65 100644
--- a/cnss2/pci.h
+++ b/cnss2/pci.h
@@ -66,7 +66,7 @@ enum cnss_rtpm_id {
enum cnss_pci_reg_dev_mask {
REG_MASK_QCA6390,
REG_MASK_QCA6490,
- REG_MASK_WCN7850,
+ REG_MASK_KIWI,
};
struct cnss_msi_user {
diff --git a/cnss2/pci_platform.h b/cnss2/pci_platform.h
index 9d03f83..74ed99b 100644
--- a/cnss2/pci_platform.h
+++ b/cnss2/pci_platform.h
@@ -1,8 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
- */
+/* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */
#ifndef _CNSS_PCI_PLATFORM_H
#define _CNSS_PCI_PLATFORM_H
@@ -109,6 +106,19 @@ int cnss_pci_prevent_l1(struct device *dev);
void cnss_pci_allow_l1(struct device *dev);
int cnss_pci_get_msi_assignment(struct cnss_pci_data *pci_priv);
int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv);
+/**
+ * _cnss_pci_get_reg_dump() - Dump PCIe RC registers for debug
+ * @pci_priv: driver PCI bus context pointer
+ * @buf: destination buffer pointer
+ * @len: length of the buffer
+ *
+ * This function shall call corresponding PCIe root complex driver API
+ * to dump PCIe RC registers for debug purpose.
+ *
+ * Return: 0 for success, negative value for error
+ */
+int _cnss_pci_get_reg_dump(struct cnss_pci_data *pci_priv,
+ u8 *buf, u32 len);
#else
int _cnss_pci_enumerate(struct cnss_plat_data *plat_priv, u32 rc_num)
{
@@ -174,6 +184,12 @@ int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
{
return 0;
}
+
+int _cnss_pci_get_reg_dump(struct cnss_pci_data *pci_priv,
+ u8 *buf, u32 len)
+{
+ return 0;
+}
#endif /* CONFIG_PCI_MSM */
#if IS_ENABLED(CONFIG_WCN_GOOGLE)
diff --git a/cnss2/pci_platform_google.c b/cnss2/pci_platform_google.c
index 6266f58..44d0638 100644
--- a/cnss2/pci_platform_google.c
+++ b/cnss2/pci_platform_google.c
@@ -168,7 +168,14 @@ int cnss_pci_get_msi_assignment(struct cnss_pci_data *pci_priv)
return 0;
}
-int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv) {
+int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
+{
+ return 0;
+}
+
+int _cnss_pci_get_reg_dump(struct cnss_pci_data *pci_priv,
+ u8 *buf, u32 len)
+{
return 0;
}
diff --git a/cnss2/pci_qcom.c b/cnss2/pci_qcom.c
index 1df4976..f9242d5 100644
--- a/cnss2/pci_qcom.c
+++ b/cnss2/pci_qcom.c
@@ -1,8 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
- */
+/* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */
#include "pci_platform.h"
#include "debug.h"
@@ -514,6 +511,12 @@ int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
return 0;
}
+int _cnss_pci_get_reg_dump(struct cnss_pci_data *pci_priv,
+ u8 *buf, u32 len)
+{
+ return 0;
+}
+
#if IS_ENABLED(CONFIG_ARCH_QCOM)
/**
* cnss_pci_of_reserved_mem_device_init() - Assign reserved memory region
diff --git a/cnss2/qmi.c b/cnss2/qmi.c
index 3ffcc66..d599565 100644
--- a/cnss2/qmi.c
+++ b/cnss2/qmi.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@@ -189,7 +189,7 @@ qmi_registered:
static void cnss_wlfw_host_cap_parse_mlo(struct cnss_plat_data *plat_priv,
struct wlfw_host_cap_req_msg_v01 *req)
{
- if (plat_priv->device_id == WCN7850_DEVICE_ID) {
+ if (plat_priv->device_id == KIWI_DEVICE_ID) {
req->mlo_capable_valid = 1;
req->mlo_capable = 1;
req->mlo_chip_id_valid = 1;
@@ -520,6 +520,18 @@ int cnss_wlfw_tgt_cap_send_sync(struct cnss_plat_data *plat_priv)
plat_priv->fw_pcie_gen_switch =
!!(resp->fw_caps & QMI_WLFW_HOST_PCIE_GEN_SWITCH_V01);
+ if (resp->hang_data_length_valid &&
+ resp->hang_data_length &&
+ resp->hang_data_length <= WLFW_MAX_HANG_EVENT_DATA_SIZE)
+ plat_priv->hang_event_data_len = resp->hang_data_length;
+ else
+ plat_priv->hang_event_data_len = 0;
+
+ if (resp->hang_data_addr_offset_valid)
+ plat_priv->hang_data_addr_offset = resp->hang_data_addr_offset;
+ else
+ plat_priv->hang_data_addr_offset = 0;
+
cnss_pr_dbg("Target capability: chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x, otp_version: 0x%x\n",
plat_priv->chip_info.chip_id,
plat_priv->chip_info.chip_family,
@@ -529,6 +541,9 @@ int cnss_wlfw_tgt_cap_send_sync(struct cnss_plat_data *plat_priv)
plat_priv->fw_version_info.fw_version,
plat_priv->fw_version_info.fw_build_timestamp,
plat_priv->fw_build_id);
+ cnss_pr_dbg("Hang event params, Length: 0x%x, Offset Address: 0x%x\n",
+ plat_priv->hang_event_data_len,
+ plat_priv->hang_data_addr_offset);
kfree(req);
kfree(resp);
@@ -1013,7 +1028,7 @@ void cnss_get_qdss_cfg_filename(struct cnss_plat_data *plat_priv,
char filename_tmp[MAX_FIRMWARE_NAME_LEN];
char *debug_str = QDSS_DEBUG_FILE_STR;
- if (plat_priv->device_id == WCN7850_DEVICE_ID)
+ if (plat_priv->device_id == KIWI_DEVICE_ID)
debug_str = "";
if (plat_priv->device_version.major_version == FW_V2_NUMBER)
diff --git a/cnss2/reg.h b/cnss2/reg.h
index 2807b30..0ac689d 100644
--- a/cnss2/reg.h
+++ b/cnss2/reg.h
@@ -1,5 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. */
+/*
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
#ifndef _CNSS_REG_H
#define _CNSS_REG_H
@@ -81,10 +84,10 @@
#define QCA6490_DEBUG_PBL_LOG_SRAM_MAX_SIZE 40
#define QCA6490_DEBUG_SBL_LOG_SRAM_MAX_SIZE 48
-#define WCN7850_DEBUG_PBL_LOG_SRAM_START 0x01403D98
-#define WCN7850_DEBUG_PBL_LOG_SRAM_MAX_SIZE 40
-#define WCN7850_DEBUG_SBL_LOG_SRAM_MAX_SIZE 48
-#define WCN7850_PBL_BOOTSTRAP_STATUS 0x01A10008
+#define KIWI_DEBUG_PBL_LOG_SRAM_START 0x01403D98
+#define KIWI_DEBUG_PBL_LOG_SRAM_MAX_SIZE 40
+#define KIWI_DEBUG_SBL_LOG_SRAM_MAX_SIZE 48
+#define KIWI_PBL_BOOTSTRAP_STATUS 0x01A10008
#define TCSR_PBL_LOGGING_REG 0x01B000F8
#define PCIE_BHI_ERRDBG2_REG 0x01E0E238
diff --git a/cnss_utils/cnss_plat_ipc_service_v01.c b/cnss_utils/cnss_plat_ipc_service_v01.c
index 51ef049..c3a106c 100644
--- a/cnss_utils/cnss_plat_ipc_service_v01.c
+++ b/cnss_utils/cnss_plat_ipc_service_v01.c
@@ -399,4 +399,4 @@ struct qmi_elem_info cnss_plat_ipc_qmi_reg_client_resp_msg_v01_ei[] = {
EXPORT_SYMBOL(cnss_plat_ipc_qmi_reg_client_resp_msg_v01_ei);
MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("WLAN FW QMI service"); \ No newline at end of file
+MODULE_DESCRIPTION("WLAN FW QMI service");
diff --git a/cnss_utils/wlan_firmware_service_v01.c b/cnss_utils/wlan_firmware_service_v01.c
index 740b1d8..6e5e01d 100644
--- a/cnss_utils/wlan_firmware_service_v01.c
+++ b/cnss_utils/wlan_firmware_service_v01.c
@@ -1829,6 +1829,26 @@ struct qmi_elem_info wlfw_cap_resp_msg_v01_ei[] = {
hang_data_length),
},
{
+ .data_type = QMI_OPT_FLAG,
+ .elem_len = 1,
+ .elem_size = sizeof(u8),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x20,
+ .offset = offsetof(struct
+ wlfw_cap_resp_msg_v01,
+ bdf_dnld_method_valid),
+ },
+ {
+ .data_type = QMI_SIGNED_4_BYTE_ENUM,
+ .elem_len = 1,
+ .elem_size = sizeof(enum wlfw_bdf_dnld_method_v01),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x20,
+ .offset = offsetof(struct
+ wlfw_cap_resp_msg_v01,
+ bdf_dnld_method),
+ },
+ {
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
@@ -3538,6 +3558,26 @@ struct qmi_elem_info wlfw_host_cap_req_msg_v01_ei[] = {
wake_msi_addr),
},
{
+ .data_type = QMI_OPT_FLAG,
+ .elem_len = 1,
+ .elem_size = sizeof(u8),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x2B,
+ .offset = offsetof(struct
+ wlfw_host_cap_req_msg_v01,
+ wlan_enable_delay_valid),
+ },
+ {
+ .data_type = QMI_UNSIGNED_4_BYTE,
+ .elem_len = 1,
+ .elem_size = sizeof(u32),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x2B,
+ .offset = offsetof(struct
+ wlfw_host_cap_req_msg_v01,
+ wlan_enable_delay),
+ },
+ {
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
.tlv_type = QMI_COMMON_TLV_TYPE,
diff --git a/cnss_utils/wlan_firmware_service_v01.h b/cnss_utils/wlan_firmware_service_v01.h
index 23a43a7..1632c3f 100644
--- a/cnss_utils/wlan_firmware_service_v01.h
+++ b/cnss_utils/wlan_firmware_service_v01.h
@@ -262,6 +262,13 @@ enum cnss_feature_v01 {
CNSS_FEATURE_MAX_VAL_V01 = INT_MAX,
};
+enum wlfw_bdf_dnld_method_v01 {
+ WLFW_BDF_DNLD_METHOD_MIN_VAL_V01 = INT_MIN,
+ WLFW_DIRECT_BDF_COPY_V01 = 0,
+ WLFW_SEND_BDF_OVER_QMI_V01 = 1,
+ WLFW_BDF_DNLD_METHOD_MAX_VAL_V01 = INT_MAX,
+};
+
#define QMI_WLFW_CE_ATTR_FLAGS_V01 ((u32)0x00)
#define QMI_WLFW_CE_ATTR_NO_SNOOP_V01 ((u32)0x01)
#define QMI_WLFW_CE_ATTR_BYTE_SWAP_DATA_V01 ((u32)0x02)
@@ -546,9 +553,11 @@ struct wlfw_cap_resp_msg_v01 {
u32 hang_data_addr_offset;
u8 hang_data_length_valid;
u16 hang_data_length;
+ u8 bdf_dnld_method_valid;
+ enum wlfw_bdf_dnld_method_v01 bdf_dnld_method;
};
-#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 351
+#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 358
extern struct qmi_elem_info wlfw_cap_resp_msg_v01_ei[];
struct wlfw_bdf_download_req_msg_v01 {
diff --git a/inc/cnss2.h b/inc/cnss2.h
index 1376995..c6591dd 100644
--- a/inc/cnss2.h
+++ b/inc/cnss2.h
@@ -1,5 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */
+/*
+ * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
#ifndef _NET_CNSS2_H
#define _NET_CNSS2_H
@@ -23,6 +26,8 @@ enum cnss_bus_width_type {
CNSS_BUS_WIDTH_MEDIUM,
CNSS_BUS_WIDTH_HIGH,
CNSS_BUS_WIDTH_VERY_HIGH,
+ CNSS_BUS_WIDTH_ULTRA_HIGH,
+ CNSS_BUS_WIDTH_MAX,
CNSS_BUS_WIDTH_LOW_LATENCY
};
@@ -275,4 +280,7 @@ extern int cnss_get_mem_seg_count(enum cnss_remote_mem_type type, u32 *seg);
extern int cnss_get_mem_segment_info(enum cnss_remote_mem_type type,
struct cnss_mem_segment segment[],
u32 segment_count);
+extern int cnss_get_pci_slot(struct device *dev);
+extern int cnss_pci_get_reg_dump(struct device *dev, uint8_t *buffer,
+ uint32_t len);
#endif /* _NET_CNSS2_H */
diff --git a/mhi/core/main.c b/mhi/core/main.c
index acca77d..febe2ac 100644
--- a/mhi/core/main.c
+++ b/mhi/core/main.c
@@ -242,6 +242,11 @@ void *mhi_to_virtual(struct mhi_ring *ring, dma_addr_t addr)
return (addr - ring->iommu_base) + ring->base;
}
+dma_addr_t mhi_to_physical(struct mhi_ring *ring, void *addr)
+{
+ return (addr - ring->base) + ring->iommu_base;
+}
+
static void mhi_add_ring_element(struct mhi_controller *mhi_cntrl,
struct mhi_ring *ring)
{
@@ -671,6 +676,8 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
mhi_del_ring_element(mhi_cntrl, tre_ring);
local_rp = tre_ring->rp;
+ read_unlock_bh(&mhi_chan->lock);
+
/* notify client */
mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result);
@@ -693,6 +700,8 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
kfree(buf_info->cb_buf);
}
}
+
+ read_lock_bh(&mhi_chan->lock);
}
break;
} /* CC_EOT */
@@ -799,6 +808,7 @@ static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl,
struct mhi_ring *mhi_ring = &cmd_ring->ring;
struct mhi_tre *cmd_pkt;
struct mhi_chan *mhi_chan;
+ struct mhi_tre *mhi_tre;
u32 chan;
if (!is_valid_ring_ptr(mhi_ring, ptr)) {
@@ -808,9 +818,11 @@ static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl,
cmd_pkt = mhi_to_virtual(mhi_ring, ptr);
- if (cmd_pkt != mhi_ring->rp)
- panic("Out of order cmd completion: 0x%p. Expected: 0x%p\n",
- cmd_pkt, mhi_ring->rp);
+ if (cmd_pkt != mhi_ring->rp) {
+ mhi_tre = mhi_ring->rp;
+ panic("Out of order cmd completion: 0x%llx. Expected: 0x%llx\n",
+ ptr, (u64)mhi_to_physical(mhi_ring, mhi_tre));
+ }
if (MHI_TRE_GET_CMD_TYPE(cmd_pkt) == MHI_CMD_SFR_CFG) {
mhi_misc_cmd_completion(mhi_cntrl, MHI_CMD_SFR_CFG,
@@ -1287,6 +1299,9 @@ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,
int eot, eob, chain, bei;
int ret;
+ /* Protect accesses for reading and incrementing WP */
+ write_lock_bh(&mhi_chan->lock);
+
buf_ring = &mhi_chan->buf_ring;
tre_ring = &mhi_chan->tre_ring;
@@ -1304,8 +1319,10 @@ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,
if (!info->pre_mapped) {
ret = mhi_cntrl->map_single(mhi_cntrl, buf_info);
- if (ret)
+ if (ret) {
+ write_unlock_bh(&mhi_chan->lock);
return ret;
+ }
}
eob = !!(flags & MHI_EOB);
@@ -1318,14 +1335,17 @@ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,
mhi_tre->dword[0] = MHI_TRE_DATA_DWORD0(info->len);
mhi_tre->dword[1] = MHI_TRE_DATA_DWORD1(bei, eot, eob, chain);
- MHI_VERB("Channel: %d WP: 0x%p TRE: 0x%llx 0x%08x 0x%08x\n",
- mhi_chan->chan, mhi_tre, mhi_tre->ptr, mhi_tre->dword[0],
+ MHI_VERB("Channel: %d WP: 0x%llx TRE: 0x%llx 0x%08x 0x%08x\n",
+ mhi_chan->chan, (u64)mhi_to_physical(tre_ring, mhi_tre),
+ mhi_tre->ptr, mhi_tre->dword[0],
mhi_tre->dword[1]);
/* increment WP */
mhi_add_ring_element(mhi_cntrl, tre_ring);
mhi_add_ring_element(mhi_cntrl, buf_ring);
+ write_unlock_bh(&mhi_chan->lock);
+
return 0;
}
diff --git a/mhi/core/misc.c b/mhi/core/misc.c
index f0c1f69..20f6333 100644
--- a/mhi/core/misc.c
+++ b/mhi/core/misc.c
@@ -180,6 +180,9 @@ int mhi_misc_register_controller(struct mhi_controller *mhi_cntrl)
mhi_priv->log_buf = ipc_log_context_create(MHI_IPC_LOG_PAGES,
mhi_dev->name, 0);
+ if (!mhi_priv->log_buf)
+ MHI_ERR("%s:Failed to create MHI IPC logs\n", __func__);
+
mhi_priv->log_lvl = MHI_MISC_DEBUG_LEVEL;
mhi_priv->mhi_cntrl = mhi_cntrl;
@@ -675,6 +678,7 @@ static void mhi_process_sfr(struct mhi_controller *mhi_cntrl,
crash_info_handler(sfr_buf);
}
#endif
+
/* force sfr string to log in kernel msg */
MHI_ERR("%s\n", sfr_buf);
err:
@@ -773,7 +777,17 @@ bool mhi_scan_rddm_cookie(struct mhi_controller *mhi_cntrl, u32 cookie)
struct device *dev = &mhi_cntrl->mhi_dev->dev;
int ret;
u32 val;
-
+ int i;
+ bool result = false;
+ struct {
+ char *name;
+ u32 offset;
+ } error_reg[] = {
+ { "ERROR_DBG1", BHI_ERRDBG1 },
+ { "ERROR_DBG2", BHI_ERRDBG2 },
+ { "ERROR_DBG3", BHI_ERRDBG3 },
+ { NULL },
+ };
if (!mhi_cntrl->rddm_image || !cookie)
return false;
@@ -782,15 +796,23 @@ bool mhi_scan_rddm_cookie(struct mhi_controller *mhi_cntrl, u32 cookie)
if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state))
return false;
- ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_ERRDBG2, &val);
- if (ret)
- return false;
+ /* look for an RDDM cookie match in any of the error debug registers */
+ for (i = 0; error_reg[i].name; i++) {
- MHI_VERB("BHI_ERRDBG2 value:0x%x\n", val);
- if (val == cookie)
- return true;
+ ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, error_reg[i].offset, &val);
- return false;
+ if (ret)
+ break;
+
+ MHI_VERB("reg: %s value:0x%x\n", error_reg[i].name, val);
+
+ if (!(val ^ cookie)) {
+ MHI_VERB("RDDM Cookie found in %s\n", error_reg[i].name);
+ return true;
+ }
+ }
+ MHI_VERB("RDDM Cookie not found\n");
+ return result;
}
EXPORT_SYMBOL(mhi_scan_rddm_cookie);
@@ -922,6 +944,9 @@ static int mhi_get_capability_offset(struct mhi_controller *mhi_cntrl,
if (ret)
return ret;
do {
+ if (*offset >= MHI_REG_SIZE)
+ return -ENXIO;
+
ret = mhi_read_reg_field(mhi_cntrl, mhi_cntrl->regs, *offset,
CAP_CAPID_MASK, CAP_CAPID_SHIFT,
&cur_cap);
@@ -938,8 +963,6 @@ static int mhi_get_capability_offset(struct mhi_controller *mhi_cntrl,
return ret;
*offset = next_offset;
- if (*offset >= MHI_REG_SIZE)
- return -ENXIO;
} while (next_offset);
return -ENXIO;
diff --git a/qmi/qmi_interface.c b/qmi/qmi_interface.c
index 3814565..2bebc90 100644
--- a/qmi/qmi_interface.c
+++ b/qmi/qmi_interface.c
@@ -674,7 +674,7 @@ int qmi_handle_init(struct qmi_handle *qmi, size_t recv_buf_size,
if (!qmi->recv_buf)
return -ENOMEM;
- qmi->wq = alloc_workqueue("qmi_msg_handler", WQ_UNBOUND, 1);
+ qmi->wq = alloc_workqueue("qmi_msg_handler", WQ_UNBOUND|WQ_HIGHPRI, 1);
if (!qmi->wq) {
ret = -ENOMEM;
goto err_free_recv_buf;
diff --git a/qrtr/ns.c b/qrtr/ns.c
index 38e4405..7620c29 100644
--- a/qrtr/ns.c
+++ b/qrtr/ns.c
@@ -745,7 +745,7 @@ static void qrtr_ns_data_ready(struct sock *sk)
void qrtr_ns_init(void)
{
struct sockaddr_qrtr sq;
- int rx_buf_sz = INT_MAX;
+ int rx_buf_sz = SZ_1M;
int ret;
INIT_LIST_HEAD(&qrtr_ns.lookups);
@@ -784,7 +784,7 @@ void qrtr_ns_init(void)
goto err_wq;
}
- sock_setsockopt(qrtr_ns.sock, SOL_SOCKET, SO_RCVBUF,
+ sock_setsockopt(qrtr_ns.sock, SOL_SOCKET, SO_RCVBUFFORCE,
KERNEL_SOCKPTR((void *)&rx_buf_sz), sizeof(rx_buf_sz));
qrtr_ns.bcast_sq.sq_family = AF_QIPCRTR;
diff --git a/qrtr/qrtr.c b/qrtr/qrtr.c
index 761f021..7bbdf15 100644
--- a/qrtr/qrtr.c
+++ b/qrtr/qrtr.c
@@ -539,7 +539,6 @@ static int qrtr_tx_wait(struct qrtr_node *node, struct sockaddr_qrtr *to,
int confirm_rx = 0;
long timeo;
long ret;
- int cond;
/* Never set confirm_rx on non-data packets */
if (type != QRTR_TYPE_DATA)
@@ -604,10 +603,10 @@ static int qrtr_tx_wait(struct qrtr_node *node, struct sockaddr_qrtr *to,
}
mutex_unlock(&node->qrtr_tx_lock);
- cond = (!node->ep || READ_ONCE(flow->tx_failed) ||
- atomic_read(&flow->pending) < QRTR_TX_FLOW_HIGH);
ret = wait_event_interruptible_timeout(node->resume_tx,
- cond, timeo);
+ (!node->ep || READ_ONCE(flow->tx_failed) ||
+ atomic_read(&flow->pending) < QRTR_TX_FLOW_HIGH),
+ timeo);
if (ret < 0)
return ret;
if (!node->ep)