Merge "cnss2: Add platform driver code to handle hang event data"

This commit is contained in:
qctecmdr 2020-04-23 08:57:44 -07:00 • committed by Gerrit - the friendly Code Review server
commit e9a988cd7f
3 changed files with 83 additions and 8 deletions

View file

@ -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 },
@ -3854,6 +3857,60 @@ 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;
void *hang_data_va = NULL;
int i = 0;
if (!fw_mem || !plat_priv->fw_mem_seg_len)
return;
memset(&hang_event, 0, sizeof(hang_event));
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;
@ -3865,6 +3922,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;

View file

@ -199,6 +199,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);

View file

@ -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);
@ -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;