Loading drivers/net/wireless/cnss2/main.h +16 −0 Original line number Original line Diff line number Diff line Loading @@ -216,6 +216,22 @@ struct cnss_control_params { unsigned int bdf_type; unsigned int bdf_type; }; }; enum cnss_ce_index { CNSS_CE_00, CNSS_CE_01, CNSS_CE_02, CNSS_CE_03, CNSS_CE_04, CNSS_CE_05, CNSS_CE_06, CNSS_CE_07, CNSS_CE_08, CNSS_CE_09, CNSS_CE_10, CNSS_CE_11, CNSS_CE_COMMON, }; struct cnss_plat_data { struct cnss_plat_data { struct platform_device *plat_dev; struct platform_device *plat_dev; void *bus_priv; void *bus_priv; Loading drivers/net/wireless/cnss2/pci.c +147 −6 Original line number Original line Diff line number Diff line Loading @@ -2,6 +2,7 @@ /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #include <linux/firmware.h> #include <linux/firmware.h> #include <linux/io.h> #include <linux/irq.h> #include <linux/irq.h> #include <linux/module.h> #include <linux/module.h> #include <linux/msi.h> #include <linux/msi.h> Loading Loading @@ -53,6 +54,105 @@ static DEFINE_SPINLOCK(pci_link_down_lock); #define MHI_TIMEOUT_OVERWRITE_MS (plat_priv->ctrl_params.mhi_timeout) #define MHI_TIMEOUT_OVERWRITE_MS (plat_priv->ctrl_params.mhi_timeout) #define QCA6390_PCIE_REMAP_BAR_CTRL_OFFSET 0x310C #define QCA6390_CE_SRC_RING_REG_BASE 0xA00000 #define QCA6390_CE_DST_RING_REG_BASE 0xA01000 #define QCA6390_CE_COMMON_REG_BASE 0xA18000 #define QCA6390_CE_SRC_RING_BASE_LSB_OFFSET 0x0 #define QCA6390_CE_SRC_RING_MISC_OFFSET 0x10 #define QCA6390_CE_SRC_CTRL_OFFSET 0x58 #define QCA6390_CE_SRC_RING_HP_OFFSET 0x400 #define QCA6390_CE_SRC_RING_TP_OFFSET 0x404 #define QCA6390_CE_DEST_RING_BASE_LSB_OFFSET 0x0 #define QCA6390_CE_DEST_RING_MISC_OFFSET 0x10 #define QCA6390_CE_DEST_CTRL_OFFSET 0xB0 #define QCA6390_CE_CH_DST_IS_OFFSET 0xB4 #define QCA6390_CE_CH_DEST_CTRL2_OFFSET 0xB8 #define QCA6390_CE_DEST_RING_HP_OFFSET 0x400 #define QCA6390_CE_DEST_RING_TP_OFFSET 0x404 #define QCA6390_CE_STATUS_RING_BASE_LSB_OFFSET 0x58 #define QCA6390_CE_STATUS_RING_MISC_OFFSET 0x68 #define QCA6390_CE_STATUS_RING_HP_OFFSET 0x408 #define QCA6390_CE_STATUS_RING_TP_OFFSET 0x40C #define QCA6390_CE_COMMON_GXI_ERR_INTS 0x14 #define QCA6390_CE_COMMON_GXI_ERR_STATS 0x18 #define QCA6390_CE_COMMON_GXI_WDOG_STATUS 0x2C #define QCA6390_CE_COMMON_TARGET_IE_0 0x48 #define QCA6390_CE_COMMON_TARGET_IE_1 0x4C #define QCA6390_CE_REG_INTERVAL 0x2000 #define MAX_UNWINDOWED_ADDRESS 0x80000 #define WINDOW_ENABLE_BIT 0x40000000 #define WINDOW_SHIFT 19 #define WINDOW_VALUE_MASK 0x3F #define WINDOW_START MAX_UNWINDOWED_ADDRESS #define WINDOW_RANGE_MASK 0x7FFFF static struct cnss_pci_reg ce_src[] = { { "SRC_RING_BASE_LSB", QCA6390_CE_SRC_RING_BASE_LSB_OFFSET }, { "SRC_RING_MISC", QCA6390_CE_SRC_RING_MISC_OFFSET }, { "SRC_CTRL", QCA6390_CE_SRC_CTRL_OFFSET }, { "SRC_RING_HP", QCA6390_CE_SRC_RING_HP_OFFSET }, { "SRC_RING_TP", QCA6390_CE_SRC_RING_TP_OFFSET }, { NULL }, }; static struct cnss_pci_reg ce_dst[] = { { "DEST_RING_BASE_LSB", QCA6390_CE_DEST_RING_BASE_LSB_OFFSET }, { "DEST_RING_MISC", QCA6390_CE_DEST_RING_MISC_OFFSET }, { "DEST_CTRL", QCA6390_CE_DEST_CTRL_OFFSET }, { "CE_CH_DST_IS", QCA6390_CE_CH_DST_IS_OFFSET }, { "CE_CH_DEST_CTRL2", QCA6390_CE_CH_DEST_CTRL2_OFFSET }, { "DEST_RING_HP", QCA6390_CE_DEST_RING_HP_OFFSET }, { "DEST_RING_TP", QCA6390_CE_DEST_RING_TP_OFFSET }, { "STATUS_RING_BASE_LSB", QCA6390_CE_STATUS_RING_BASE_LSB_OFFSET }, { "STATUS_RING_MISC", QCA6390_CE_STATUS_RING_MISC_OFFSET }, { "STATUS_RING_HP", QCA6390_CE_STATUS_RING_HP_OFFSET }, { "STATUS_RING_TP", QCA6390_CE_STATUS_RING_TP_OFFSET }, { NULL }, }; static struct cnss_pci_reg ce_cmn[] = { { "GXI_ERR_INTS", QCA6390_CE_COMMON_GXI_ERR_INTS }, { "GXI_ERR_STATS", QCA6390_CE_COMMON_GXI_ERR_STATS }, { "GXI_WDOG_STATUS", QCA6390_CE_COMMON_GXI_WDOG_STATUS }, { "TARGET_IE_0", QCA6390_CE_COMMON_TARGET_IE_0 }, { "TARGET_IE_1", QCA6390_CE_COMMON_TARGET_IE_1 }, { NULL }, }; static void cnss_pci_select_window(struct cnss_pci_data *pci_priv, u32 offset) { u32 window = (offset >> WINDOW_SHIFT) & WINDOW_VALUE_MASK; if (window != pci_priv->remap_window) { writel_relaxed(WINDOW_ENABLE_BIT | window, QCA6390_PCIE_REMAP_BAR_CTRL_OFFSET + pci_priv->bar); pci_priv->remap_window = window; cnss_pr_dbg("Config PCIe remap window register to 0x%x\n", WINDOW_ENABLE_BIT | window); } } static u32 cnss_pci_reg_read(struct cnss_pci_data *pci_priv, u32 offset) { if (pci_priv->pci_dev->device == QCA6174_DEVICE_ID || offset < MAX_UNWINDOWED_ADDRESS) return readl_relaxed(pci_priv->bar + offset); cnss_pci_select_window(pci_priv, offset); return readl_relaxed(pci_priv->bar + WINDOW_START + (offset & WINDOW_RANGE_MASK)); } static int cnss_set_pci_config_space(struct cnss_pci_data *pci_priv, bool save) static int cnss_set_pci_config_space(struct cnss_pci_data *pci_priv, bool save) { { struct pci_dev *pci_dev = pci_priv->pci_dev; struct pci_dev *pci_dev = pci_priv->pci_dev; Loading Loading @@ -585,11 +685,6 @@ static void cnss_qca6290_crash_shutdown(struct cnss_pci_data *pci_priv) return; return; } } if (test_bit(CNSS_MHI_RDDM_DONE, &plat_priv->driver_state)) { cnss_pr_dbg("RDDM already collected, return\n"); return; } cnss_pci_collect_dump_info(pci_priv, true); cnss_pci_collect_dump_info(pci_priv, true); } } Loading Loading @@ -1955,6 +2050,46 @@ static char *cnss_mhi_state_to_str(enum cnss_mhi_state mhi_state) } } }; }; static void cnss_pci_dump_ce_reg(struct cnss_pci_data *pci_priv, enum cnss_ce_index ce) { int i; u32 ce_base = ce * QCA6390_CE_REG_INTERVAL; u32 reg_offset; switch (ce) { case CNSS_CE_09: case CNSS_CE_10: for (i = 0; ce_src[i].name; i++) { reg_offset = QCA6390_CE_SRC_RING_REG_BASE + ce_base + ce_src[i].offset; cnss_pr_dbg("CE_%02d_%s[0x%x] = 0x%x\n", ce, ce_src[i].name, reg_offset, cnss_pci_reg_read(pci_priv, reg_offset)); } for (i = 0; ce_dst[i].name; i++) { reg_offset = QCA6390_CE_DST_RING_REG_BASE + ce_base + ce_dst[i].offset; cnss_pr_dbg("CE_%02d_%s[0x%x] = 0x%x\n", ce, ce_dst[i].name, reg_offset, cnss_pci_reg_read(pci_priv, reg_offset)); } break; case CNSS_CE_COMMON: for (i = 0; ce_cmn[i].name; i++) { reg_offset = QCA6390_CE_COMMON_REG_BASE + ce_cmn[i].offset; cnss_pr_dbg("CE_COMMON_%s[0x%x] = 0x%x\n", ce_cmn[i].name, reg_offset, cnss_pci_reg_read(pci_priv, reg_offset)); } break; default: cnss_pr_err("Unsupported CE[%d] registers dump\n", ce); } } static void cnss_pci_dump_registers(struct cnss_pci_data *pci_priv) static void cnss_pci_dump_registers(struct cnss_pci_data *pci_priv) { { cnss_pr_dbg("Start to dump debug registers\n"); cnss_pr_dbg("Start to dump debug registers\n"); Loading @@ -1963,6 +2098,9 @@ static void cnss_pci_dump_registers(struct cnss_pci_data *pci_priv) return; return; mhi_debug_reg_dump(pci_priv->mhi_ctrl); mhi_debug_reg_dump(pci_priv->mhi_ctrl); cnss_pci_dump_ce_reg(pci_priv, CNSS_CE_COMMON); cnss_pci_dump_ce_reg(pci_priv, CNSS_CE_09); cnss_pci_dump_ce_reg(pci_priv, CNSS_CE_10); } } void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) Loading @@ -1976,7 +2114,10 @@ void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) struct cnss_fw_mem *fw_mem = plat_priv->fw_mem; struct cnss_fw_mem *fw_mem = plat_priv->fw_mem; int ret, i; int ret, i; cnss_pci_dump_registers(pci_priv); if (test_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state)) { cnss_pr_dbg("RAM dump is already collected, skip\n"); return; } ret = mhi_download_rddm_img(pci_priv->mhi_ctrl, in_panic); ret = mhi_download_rddm_img(pci_priv->mhi_ctrl, in_panic); if (ret) { if (ret) { Loading drivers/net/wireless/cnss2/pci.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -37,6 +37,11 @@ struct cnss_msi_config { struct cnss_msi_user *users; struct cnss_msi_user *users; }; }; struct cnss_pci_reg { char *name; u32 offset; }; struct cnss_pci_data { struct cnss_pci_data { struct pci_dev *pci_dev; struct pci_dev *pci_dev; struct cnss_plat_data *plat_priv; struct cnss_plat_data *plat_priv; Loading @@ -62,6 +67,7 @@ struct cnss_pci_data { u32 msi_ep_base_data; u32 msi_ep_base_data; struct mhi_controller *mhi_ctrl; struct mhi_controller *mhi_ctrl; unsigned long mhi_state; unsigned long mhi_state; u32 remap_window; struct timer_list dev_rddm_timer; struct timer_list dev_rddm_timer; u8 disable_pc; u8 disable_pc; }; }; Loading Loading
drivers/net/wireless/cnss2/main.h +16 −0 Original line number Original line Diff line number Diff line Loading @@ -216,6 +216,22 @@ struct cnss_control_params { unsigned int bdf_type; unsigned int bdf_type; }; }; enum cnss_ce_index { CNSS_CE_00, CNSS_CE_01, CNSS_CE_02, CNSS_CE_03, CNSS_CE_04, CNSS_CE_05, CNSS_CE_06, CNSS_CE_07, CNSS_CE_08, CNSS_CE_09, CNSS_CE_10, CNSS_CE_11, CNSS_CE_COMMON, }; struct cnss_plat_data { struct cnss_plat_data { struct platform_device *plat_dev; struct platform_device *plat_dev; void *bus_priv; void *bus_priv; Loading
drivers/net/wireless/cnss2/pci.c +147 −6 Original line number Original line Diff line number Diff line Loading @@ -2,6 +2,7 @@ /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ #include <linux/firmware.h> #include <linux/firmware.h> #include <linux/io.h> #include <linux/irq.h> #include <linux/irq.h> #include <linux/module.h> #include <linux/module.h> #include <linux/msi.h> #include <linux/msi.h> Loading Loading @@ -53,6 +54,105 @@ static DEFINE_SPINLOCK(pci_link_down_lock); #define MHI_TIMEOUT_OVERWRITE_MS (plat_priv->ctrl_params.mhi_timeout) #define MHI_TIMEOUT_OVERWRITE_MS (plat_priv->ctrl_params.mhi_timeout) #define QCA6390_PCIE_REMAP_BAR_CTRL_OFFSET 0x310C #define QCA6390_CE_SRC_RING_REG_BASE 0xA00000 #define QCA6390_CE_DST_RING_REG_BASE 0xA01000 #define QCA6390_CE_COMMON_REG_BASE 0xA18000 #define QCA6390_CE_SRC_RING_BASE_LSB_OFFSET 0x0 #define QCA6390_CE_SRC_RING_MISC_OFFSET 0x10 #define QCA6390_CE_SRC_CTRL_OFFSET 0x58 #define QCA6390_CE_SRC_RING_HP_OFFSET 0x400 #define QCA6390_CE_SRC_RING_TP_OFFSET 0x404 #define QCA6390_CE_DEST_RING_BASE_LSB_OFFSET 0x0 #define QCA6390_CE_DEST_RING_MISC_OFFSET 0x10 #define QCA6390_CE_DEST_CTRL_OFFSET 0xB0 #define QCA6390_CE_CH_DST_IS_OFFSET 0xB4 #define QCA6390_CE_CH_DEST_CTRL2_OFFSET 0xB8 #define QCA6390_CE_DEST_RING_HP_OFFSET 0x400 #define QCA6390_CE_DEST_RING_TP_OFFSET 0x404 #define QCA6390_CE_STATUS_RING_BASE_LSB_OFFSET 0x58 #define QCA6390_CE_STATUS_RING_MISC_OFFSET 0x68 #define QCA6390_CE_STATUS_RING_HP_OFFSET 0x408 #define QCA6390_CE_STATUS_RING_TP_OFFSET 0x40C #define QCA6390_CE_COMMON_GXI_ERR_INTS 0x14 #define QCA6390_CE_COMMON_GXI_ERR_STATS 0x18 #define QCA6390_CE_COMMON_GXI_WDOG_STATUS 0x2C #define QCA6390_CE_COMMON_TARGET_IE_0 0x48 #define QCA6390_CE_COMMON_TARGET_IE_1 0x4C #define QCA6390_CE_REG_INTERVAL 0x2000 #define MAX_UNWINDOWED_ADDRESS 0x80000 #define WINDOW_ENABLE_BIT 0x40000000 #define WINDOW_SHIFT 19 #define WINDOW_VALUE_MASK 0x3F #define WINDOW_START MAX_UNWINDOWED_ADDRESS #define WINDOW_RANGE_MASK 0x7FFFF static struct cnss_pci_reg ce_src[] = { { "SRC_RING_BASE_LSB", QCA6390_CE_SRC_RING_BASE_LSB_OFFSET }, { "SRC_RING_MISC", QCA6390_CE_SRC_RING_MISC_OFFSET }, { "SRC_CTRL", QCA6390_CE_SRC_CTRL_OFFSET }, { "SRC_RING_HP", QCA6390_CE_SRC_RING_HP_OFFSET }, { "SRC_RING_TP", QCA6390_CE_SRC_RING_TP_OFFSET }, { NULL }, }; static struct cnss_pci_reg ce_dst[] = { { "DEST_RING_BASE_LSB", QCA6390_CE_DEST_RING_BASE_LSB_OFFSET }, { "DEST_RING_MISC", QCA6390_CE_DEST_RING_MISC_OFFSET }, { "DEST_CTRL", QCA6390_CE_DEST_CTRL_OFFSET }, { "CE_CH_DST_IS", QCA6390_CE_CH_DST_IS_OFFSET }, { "CE_CH_DEST_CTRL2", QCA6390_CE_CH_DEST_CTRL2_OFFSET }, { "DEST_RING_HP", QCA6390_CE_DEST_RING_HP_OFFSET }, { "DEST_RING_TP", QCA6390_CE_DEST_RING_TP_OFFSET }, { "STATUS_RING_BASE_LSB", QCA6390_CE_STATUS_RING_BASE_LSB_OFFSET }, { "STATUS_RING_MISC", QCA6390_CE_STATUS_RING_MISC_OFFSET }, { "STATUS_RING_HP", QCA6390_CE_STATUS_RING_HP_OFFSET }, { "STATUS_RING_TP", QCA6390_CE_STATUS_RING_TP_OFFSET }, { NULL }, }; static struct cnss_pci_reg ce_cmn[] = { { "GXI_ERR_INTS", QCA6390_CE_COMMON_GXI_ERR_INTS }, { "GXI_ERR_STATS", QCA6390_CE_COMMON_GXI_ERR_STATS }, { "GXI_WDOG_STATUS", QCA6390_CE_COMMON_GXI_WDOG_STATUS }, { "TARGET_IE_0", QCA6390_CE_COMMON_TARGET_IE_0 }, { "TARGET_IE_1", QCA6390_CE_COMMON_TARGET_IE_1 }, { NULL }, }; static void cnss_pci_select_window(struct cnss_pci_data *pci_priv, u32 offset) { u32 window = (offset >> WINDOW_SHIFT) & WINDOW_VALUE_MASK; if (window != pci_priv->remap_window) { writel_relaxed(WINDOW_ENABLE_BIT | window, QCA6390_PCIE_REMAP_BAR_CTRL_OFFSET + pci_priv->bar); pci_priv->remap_window = window; cnss_pr_dbg("Config PCIe remap window register to 0x%x\n", WINDOW_ENABLE_BIT | window); } } static u32 cnss_pci_reg_read(struct cnss_pci_data *pci_priv, u32 offset) { if (pci_priv->pci_dev->device == QCA6174_DEVICE_ID || offset < MAX_UNWINDOWED_ADDRESS) return readl_relaxed(pci_priv->bar + offset); cnss_pci_select_window(pci_priv, offset); return readl_relaxed(pci_priv->bar + WINDOW_START + (offset & WINDOW_RANGE_MASK)); } static int cnss_set_pci_config_space(struct cnss_pci_data *pci_priv, bool save) static int cnss_set_pci_config_space(struct cnss_pci_data *pci_priv, bool save) { { struct pci_dev *pci_dev = pci_priv->pci_dev; struct pci_dev *pci_dev = pci_priv->pci_dev; Loading Loading @@ -585,11 +685,6 @@ static void cnss_qca6290_crash_shutdown(struct cnss_pci_data *pci_priv) return; return; } } if (test_bit(CNSS_MHI_RDDM_DONE, &plat_priv->driver_state)) { cnss_pr_dbg("RDDM already collected, return\n"); return; } cnss_pci_collect_dump_info(pci_priv, true); cnss_pci_collect_dump_info(pci_priv, true); } } Loading Loading @@ -1955,6 +2050,46 @@ static char *cnss_mhi_state_to_str(enum cnss_mhi_state mhi_state) } } }; }; static void cnss_pci_dump_ce_reg(struct cnss_pci_data *pci_priv, enum cnss_ce_index ce) { int i; u32 ce_base = ce * QCA6390_CE_REG_INTERVAL; u32 reg_offset; switch (ce) { case CNSS_CE_09: case CNSS_CE_10: for (i = 0; ce_src[i].name; i++) { reg_offset = QCA6390_CE_SRC_RING_REG_BASE + ce_base + ce_src[i].offset; cnss_pr_dbg("CE_%02d_%s[0x%x] = 0x%x\n", ce, ce_src[i].name, reg_offset, cnss_pci_reg_read(pci_priv, reg_offset)); } for (i = 0; ce_dst[i].name; i++) { reg_offset = QCA6390_CE_DST_RING_REG_BASE + ce_base + ce_dst[i].offset; cnss_pr_dbg("CE_%02d_%s[0x%x] = 0x%x\n", ce, ce_dst[i].name, reg_offset, cnss_pci_reg_read(pci_priv, reg_offset)); } break; case CNSS_CE_COMMON: for (i = 0; ce_cmn[i].name; i++) { reg_offset = QCA6390_CE_COMMON_REG_BASE + ce_cmn[i].offset; cnss_pr_dbg("CE_COMMON_%s[0x%x] = 0x%x\n", ce_cmn[i].name, reg_offset, cnss_pci_reg_read(pci_priv, reg_offset)); } break; default: cnss_pr_err("Unsupported CE[%d] registers dump\n", ce); } } static void cnss_pci_dump_registers(struct cnss_pci_data *pci_priv) static void cnss_pci_dump_registers(struct cnss_pci_data *pci_priv) { { cnss_pr_dbg("Start to dump debug registers\n"); cnss_pr_dbg("Start to dump debug registers\n"); Loading @@ -1963,6 +2098,9 @@ static void cnss_pci_dump_registers(struct cnss_pci_data *pci_priv) return; return; mhi_debug_reg_dump(pci_priv->mhi_ctrl); mhi_debug_reg_dump(pci_priv->mhi_ctrl); cnss_pci_dump_ce_reg(pci_priv, CNSS_CE_COMMON); cnss_pci_dump_ce_reg(pci_priv, CNSS_CE_09); cnss_pci_dump_ce_reg(pci_priv, CNSS_CE_10); } } void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) Loading @@ -1976,7 +2114,10 @@ void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) struct cnss_fw_mem *fw_mem = plat_priv->fw_mem; struct cnss_fw_mem *fw_mem = plat_priv->fw_mem; int ret, i; int ret, i; cnss_pci_dump_registers(pci_priv); if (test_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state)) { cnss_pr_dbg("RAM dump is already collected, skip\n"); return; } ret = mhi_download_rddm_img(pci_priv->mhi_ctrl, in_panic); ret = mhi_download_rddm_img(pci_priv->mhi_ctrl, in_panic); if (ret) { if (ret) { Loading
drivers/net/wireless/cnss2/pci.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -37,6 +37,11 @@ struct cnss_msi_config { struct cnss_msi_user *users; struct cnss_msi_user *users; }; }; struct cnss_pci_reg { char *name; u32 offset; }; struct cnss_pci_data { struct cnss_pci_data { struct pci_dev *pci_dev; struct pci_dev *pci_dev; struct cnss_plat_data *plat_priv; struct cnss_plat_data *plat_priv; Loading @@ -62,6 +67,7 @@ struct cnss_pci_data { u32 msi_ep_base_data; u32 msi_ep_base_data; struct mhi_controller *mhi_ctrl; struct mhi_controller *mhi_ctrl; unsigned long mhi_state; unsigned long mhi_state; u32 remap_window; struct timer_list dev_rddm_timer; struct timer_list dev_rddm_timer; u8 disable_pc; u8 disable_pc; }; }; Loading