diff options
author | Hsiu-Chang Chen <hsiuchangchen@google.com> | 2022-02-15 10:19:35 +0800 |
---|---|---|
committer | Hsiu-Chang Chen <hsiuchangchen@google.com> | 2022-03-03 03:43:57 +0000 |
commit | 2af1153b42048ff3e1ad049dee7ddff26081acd2 (patch) | |
tree | 44c5c95488028d0bd883c83068b14f50a48589cf | |
parent | ef22de835ccf8c7c394dbd601c0ca1d7a4ab1681 (diff) | |
download | cnss2-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/Kconfig | 9 | ||||
-rw-r--r-- | cnss2/bus.c | 7 | ||||
-rw-r--r-- | cnss2/bus.h | 9 | ||||
-rw-r--r-- | cnss2/debug.c | 3 | ||||
-rw-r--r-- | cnss2/main.c | 35 | ||||
-rw-r--r-- | cnss2/main.h | 10 | ||||
-rw-r--r-- | cnss2/pci.c | 142 | ||||
-rw-r--r-- | cnss2/pci.h | 2 | ||||
-rw-r--r-- | cnss2/pci_platform.h | 24 | ||||
-rw-r--r-- | cnss2/pci_platform_google.c | 9 | ||||
-rw-r--r-- | cnss2/pci_qcom.c | 11 | ||||
-rw-r--r-- | cnss2/qmi.c | 21 | ||||
-rw-r--r-- | cnss2/reg.h | 13 | ||||
-rw-r--r-- | cnss_utils/cnss_plat_ipc_service_v01.c | 2 | ||||
-rw-r--r-- | cnss_utils/wlan_firmware_service_v01.c | 40 | ||||
-rw-r--r-- | cnss_utils/wlan_firmware_service_v01.h | 11 | ||||
-rw-r--r-- | inc/cnss2.h | 10 | ||||
-rw-r--r-- | mhi/core/main.c | 32 | ||||
-rw-r--r-- | mhi/core/misc.c | 43 | ||||
-rw-r--r-- | qmi/qmi_interface.c | 2 | ||||
-rw-r--r-- | qrtr/ns.c | 4 | ||||
-rw-r--r-- | qrtr/qrtr.c | 7 |
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; @@ -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) |