Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bececeb4 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

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

parents b44989e5 e55b24be
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -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 },
@@ -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;
@@ -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;
+2 −0
Original line number Diff line number Diff line
@@ -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);
+21 −8
Original line number Diff line number Diff line
@@ -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;