Loading drivers/net/wireless/cnss2/pci.c +59 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,9 @@ static DEFINE_SPINLOCK(time_sync_lock); #define CNSS_DEBUG_DUMP_SRAM_START 0x1403D58 #define CNSS_DEBUG_DUMP_SRAM_SIZE 10 #define HANG_DATA_LENGTH 384 #define HANG_DATA_OFFSET ((3 * 1024 * 1024) - HANG_DATA_LENGTH) static struct cnss_pci_reg ce_src[] = { { "SRC_RING_BASE_LSB", QCA6390_CE_SRC_RING_BASE_LSB_OFFSET }, { "SRC_RING_BASE_MSB", QCA6390_CE_SRC_RING_BASE_MSB_OFFSET }, Loading Loading @@ -3778,6 +3781,59 @@ static void cnss_pci_remove_dump_seg(struct cnss_pci_data *pci_priv, cnss_minidump_remove_region(plat_priv, type, seg_no, va, pa, size); } int cnss_call_driver_uevent(struct cnss_pci_data *pci_priv, enum cnss_driver_status status, void *data) { struct cnss_uevent_data uevent_data; struct cnss_wlan_driver *driver_ops; driver_ops = pci_priv->driver_ops; if (!driver_ops || !driver_ops->update_event) { cnss_pr_dbg("Hang event driver ops is NULL\n"); return -EINVAL; } cnss_pr_dbg("Calling driver uevent: %d\n", status); uevent_data.status = status; uevent_data.data = data; return driver_ops->update_event(pci_priv->pci_dev, &uevent_data); } static void cnss_pci_send_hang_event(struct cnss_pci_data *pci_priv) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct cnss_fw_mem *fw_mem = plat_priv->fw_mem; struct cnss_hang_event hang_event = {0}; void *hang_data_va = NULL; int i = 0; if (!fw_mem || !plat_priv->fw_mem_seg_len) return; 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) { hang_data_va = fw_mem[i].va + HANG_DATA_OFFSET; hang_event.hang_event_data = kmemdup(hang_data_va, HANG_DATA_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; break; } } cnss_call_driver_uevent(pci_priv, CNSS_HANG_EVENT, &hang_event); kfree(hang_event.hang_event_data); hang_event.hang_event_data = NULL; } void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; Loading @@ -3789,6 +3845,9 @@ 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; int ret, i, j; if (test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state)) cnss_pci_send_hang_event(pci_priv); if (test_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state)) { cnss_pr_dbg("RAM dump is already collected, skip\n"); return; Loading drivers/net/wireless/cnss2/pci.h +2 −0 Original line number Diff line number Diff line Loading @@ -200,6 +200,8 @@ void cnss_pci_pm_runtime_put_noidle(struct cnss_pci_data *pci_priv); void cnss_pci_pm_runtime_mark_last_busy(struct cnss_pci_data *pci_priv); int cnss_pci_update_status(struct cnss_pci_data *pci_priv, enum cnss_driver_status status); int cnss_call_driver_uevent(struct cnss_pci_data *pci_priv, enum cnss_driver_status status, void *data); int cnss_pcie_is_device_down(struct cnss_pci_data *pci_priv); int cnss_pci_suspend_bus(struct cnss_pci_data *pci_priv); int cnss_pci_resume_bus(struct cnss_pci_data *pci_priv); Loading include/net/cnss2.h +21 −8 Original line number Diff line number Diff line Loading @@ -67,6 +67,25 @@ struct cnss_wlan_runtime_ops { int (*runtime_resume)(struct pci_dev *pdev); }; enum cnss_driver_status { CNSS_UNINITIALIZED, CNSS_INITIALIZED, CNSS_LOAD_UNLOAD, CNSS_RECOVERY, CNSS_FW_DOWN, CNSS_HANG_EVENT, }; struct cnss_hang_event { void *hang_event_data; u16 hang_event_data_len; }; struct cnss_uevent_data { enum cnss_driver_status status; void *data; }; struct cnss_wlan_driver { char *name; int (*probe)(struct pci_dev *pdev, const struct pci_device_id *id); Loading @@ -83,18 +102,12 @@ struct cnss_wlan_driver { int (*resume_noirq)(struct pci_dev *pdev); void (*modem_status)(struct pci_dev *pdev, int state); void (*update_status)(struct pci_dev *pdev, uint32_t status); int (*update_event)(struct pci_dev *pdev, struct cnss_uevent_data *uevent); struct cnss_wlan_runtime_ops *runtime_ops; const struct pci_device_id *id_table; }; enum cnss_driver_status { CNSS_UNINITIALIZED, CNSS_INITIALIZED, CNSS_LOAD_UNLOAD, CNSS_RECOVERY, CNSS_FW_DOWN, }; struct cnss_ce_tgt_pipe_cfg { u32 pipe_num; u32 pipe_dir; Loading Loading
drivers/net/wireless/cnss2/pci.c +59 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,9 @@ static DEFINE_SPINLOCK(time_sync_lock); #define CNSS_DEBUG_DUMP_SRAM_START 0x1403D58 #define CNSS_DEBUG_DUMP_SRAM_SIZE 10 #define HANG_DATA_LENGTH 384 #define HANG_DATA_OFFSET ((3 * 1024 * 1024) - HANG_DATA_LENGTH) static struct cnss_pci_reg ce_src[] = { { "SRC_RING_BASE_LSB", QCA6390_CE_SRC_RING_BASE_LSB_OFFSET }, { "SRC_RING_BASE_MSB", QCA6390_CE_SRC_RING_BASE_MSB_OFFSET }, Loading Loading @@ -3778,6 +3781,59 @@ static void cnss_pci_remove_dump_seg(struct cnss_pci_data *pci_priv, cnss_minidump_remove_region(plat_priv, type, seg_no, va, pa, size); } int cnss_call_driver_uevent(struct cnss_pci_data *pci_priv, enum cnss_driver_status status, void *data) { struct cnss_uevent_data uevent_data; struct cnss_wlan_driver *driver_ops; driver_ops = pci_priv->driver_ops; if (!driver_ops || !driver_ops->update_event) { cnss_pr_dbg("Hang event driver ops is NULL\n"); return -EINVAL; } cnss_pr_dbg("Calling driver uevent: %d\n", status); uevent_data.status = status; uevent_data.data = data; return driver_ops->update_event(pci_priv->pci_dev, &uevent_data); } static void cnss_pci_send_hang_event(struct cnss_pci_data *pci_priv) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct cnss_fw_mem *fw_mem = plat_priv->fw_mem; struct cnss_hang_event hang_event = {0}; void *hang_data_va = NULL; int i = 0; if (!fw_mem || !plat_priv->fw_mem_seg_len) return; 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) { hang_data_va = fw_mem[i].va + HANG_DATA_OFFSET; hang_event.hang_event_data = kmemdup(hang_data_va, HANG_DATA_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; break; } } cnss_call_driver_uevent(pci_priv, CNSS_HANG_EVENT, &hang_event); kfree(hang_event.hang_event_data); hang_event.hang_event_data = NULL; } void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; Loading @@ -3789,6 +3845,9 @@ 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; int ret, i, j; if (test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state)) cnss_pci_send_hang_event(pci_priv); if (test_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state)) { cnss_pr_dbg("RAM dump is already collected, skip\n"); return; Loading
drivers/net/wireless/cnss2/pci.h +2 −0 Original line number Diff line number Diff line Loading @@ -200,6 +200,8 @@ void cnss_pci_pm_runtime_put_noidle(struct cnss_pci_data *pci_priv); void cnss_pci_pm_runtime_mark_last_busy(struct cnss_pci_data *pci_priv); int cnss_pci_update_status(struct cnss_pci_data *pci_priv, enum cnss_driver_status status); int cnss_call_driver_uevent(struct cnss_pci_data *pci_priv, enum cnss_driver_status status, void *data); int cnss_pcie_is_device_down(struct cnss_pci_data *pci_priv); int cnss_pci_suspend_bus(struct cnss_pci_data *pci_priv); int cnss_pci_resume_bus(struct cnss_pci_data *pci_priv); Loading
include/net/cnss2.h +21 −8 Original line number Diff line number Diff line Loading @@ -67,6 +67,25 @@ struct cnss_wlan_runtime_ops { int (*runtime_resume)(struct pci_dev *pdev); }; enum cnss_driver_status { CNSS_UNINITIALIZED, CNSS_INITIALIZED, CNSS_LOAD_UNLOAD, CNSS_RECOVERY, CNSS_FW_DOWN, CNSS_HANG_EVENT, }; struct cnss_hang_event { void *hang_event_data; u16 hang_event_data_len; }; struct cnss_uevent_data { enum cnss_driver_status status; void *data; }; struct cnss_wlan_driver { char *name; int (*probe)(struct pci_dev *pdev, const struct pci_device_id *id); Loading @@ -83,18 +102,12 @@ struct cnss_wlan_driver { int (*resume_noirq)(struct pci_dev *pdev); void (*modem_status)(struct pci_dev *pdev, int state); void (*update_status)(struct pci_dev *pdev, uint32_t status); int (*update_event)(struct pci_dev *pdev, struct cnss_uevent_data *uevent); struct cnss_wlan_runtime_ops *runtime_ops; const struct pci_device_id *id_table; }; enum cnss_driver_status { CNSS_UNINITIALIZED, CNSS_INITIALIZED, CNSS_LOAD_UNLOAD, CNSS_RECOVERY, CNSS_FW_DOWN, }; struct cnss_ce_tgt_pipe_cfg { u32 pipe_num; u32 pipe_dir; Loading