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

Commit 2e1cd8de authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cnss2: Provide the interface to force firmware assert"

parents 101f2996 2874ebda
Loading
Loading
Loading
Loading
+55 −0
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@
#define WLAN_RECOVERY_DELAY		1000
#define WLAN_RECOVERY_DELAY		1000
#define FILE_SYSTEM_READY		1
#define FILE_SYSTEM_READY		1
#define FW_READY_TIMEOUT		20000
#define FW_READY_TIMEOUT		20000
#define FW_ASSERT_TIMEOUT		5000
#define CNSS_EVENT_PENDING		2989
#define CNSS_EVENT_PENDING		2989


static struct cnss_plat_data *plat_env;
static struct cnss_plat_data *plat_env;
@@ -665,6 +666,8 @@ static char *cnss_driver_event_to_str(enum cnss_driver_event_type type)
		return "UNREGISTER_DRIVER";
		return "UNREGISTER_DRIVER";
	case CNSS_DRIVER_EVENT_RECOVERY:
	case CNSS_DRIVER_EVENT_RECOVERY:
		return "RECOVERY";
		return "RECOVERY";
	case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT:
		return "FORCE_FW_ASSERT";
	case CNSS_DRIVER_EVENT_MAX:
	case CNSS_DRIVER_EVENT_MAX:
		return "EVENT_MAX";
		return "EVENT_MAX";
	}
	}
@@ -1545,6 +1548,55 @@ void cnss_schedule_recovery(struct device *dev,
}
}
EXPORT_SYMBOL(cnss_schedule_recovery);
EXPORT_SYMBOL(cnss_schedule_recovery);


static int cnss_force_fw_assert_hdlr(struct cnss_plat_data *plat_priv)
{
	struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
	int ret;

	ret = cnss_pci_set_mhi_state(plat_priv->bus_priv,
				     CNSS_MHI_TRIGGER_RDDM);
	if (ret) {
		cnss_pr_err("Failed to trigger RDDM, err = %d\n", ret);
		cnss_schedule_recovery(&pci_priv->pci_dev->dev,
				       CNSS_REASON_DEFAULT);
		return 0;
	}

	if (!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state)) {
		mod_timer(&plat_priv->fw_boot_timer,
			  jiffies + msecs_to_jiffies(FW_ASSERT_TIMEOUT));
	}

	return 0;
}

int cnss_force_fw_assert(struct device *dev)
{
	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);

	if (!plat_priv) {
		cnss_pr_err("plat_priv is NULL\n");
		return -ENODEV;
	}

	if (plat_priv->device_id == QCA6174_DEVICE_ID) {
		cnss_pr_info("Forced FW assert is not supported\n");
		return -EINVAL;
	}

	if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
		cnss_pr_info("Recovery is already in progress, ignore forced FW assert\n");
		return 0;
	}

	cnss_driver_event_post(plat_priv,
			       CNSS_DRIVER_EVENT_FORCE_FW_ASSERT,
			       false, NULL);

	return 0;
}
EXPORT_SYMBOL(cnss_force_fw_assert);

void fw_boot_timeout(unsigned long data)
void fw_boot_timeout(unsigned long data)
{
{
	struct cnss_plat_data *plat_priv = (struct cnss_plat_data *)data;
	struct cnss_plat_data *plat_priv = (struct cnss_plat_data *)data;
@@ -1673,6 +1725,9 @@ static void cnss_driver_event_work(struct work_struct *work)
			ret = cnss_driver_recovery_hdlr(plat_priv,
			ret = cnss_driver_recovery_hdlr(plat_priv,
							event->data);
							event->data);
			break;
			break;
		case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT:
			ret = cnss_force_fw_assert_hdlr(plat_priv);
			break;
		default:
		default:
			cnss_pr_err("Invalid driver event type: %d",
			cnss_pr_err("Invalid driver event type: %d",
				    event->type);
				    event->type);
+1 −0
Original line number Original line Diff line number Diff line
@@ -125,6 +125,7 @@ enum cnss_driver_event_type {
	CNSS_DRIVER_EVENT_REGISTER_DRIVER,
	CNSS_DRIVER_EVENT_REGISTER_DRIVER,
	CNSS_DRIVER_EVENT_UNREGISTER_DRIVER,
	CNSS_DRIVER_EVENT_UNREGISTER_DRIVER,
	CNSS_DRIVER_EVENT_RECOVERY,
	CNSS_DRIVER_EVENT_RECOVERY,
	CNSS_DRIVER_EVENT_FORCE_FW_ASSERT,
	CNSS_DRIVER_EVENT_MAX,
	CNSS_DRIVER_EVENT_MAX,
};
};


+6 −0
Original line number Original line Diff line number Diff line
@@ -1032,6 +1032,8 @@ static char *cnss_mhi_state_to_str(enum cnss_mhi_state mhi_state)
		return "SUSPEND";
		return "SUSPEND";
	case CNSS_MHI_RESUME:
	case CNSS_MHI_RESUME:
		return "RESUME";
		return "RESUME";
	case CNSS_MHI_TRIGGER_RDDM:
		return "TRIGGER_RDDM";
	case CNSS_MHI_RDDM:
	case CNSS_MHI_RDDM:
		return "RDDM";
		return "RDDM";
	case CNSS_MHI_RDDM_KERNEL_PANIC:
	case CNSS_MHI_RDDM_KERNEL_PANIC:
@@ -1193,6 +1195,8 @@ static enum mhi_dev_ctrl cnss_to_mhi_dev_state(enum cnss_mhi_state state)
		return MHI_DEV_CTRL_SUSPEND;
		return MHI_DEV_CTRL_SUSPEND;
	case CNSS_MHI_RESUME:
	case CNSS_MHI_RESUME:
		return MHI_DEV_CTRL_RESUME;
		return MHI_DEV_CTRL_RESUME;
	case CNSS_MHI_TRIGGER_RDDM:
		return MHI_DEV_CTRL_TRIGGER_RDDM;
	case CNSS_MHI_RDDM:
	case CNSS_MHI_RDDM:
		return MHI_DEV_CTRL_RDDM;
		return MHI_DEV_CTRL_RDDM;
	case CNSS_MHI_RDDM_KERNEL_PANIC:
	case CNSS_MHI_RDDM_KERNEL_PANIC:
@@ -1229,6 +1233,7 @@ static int cnss_pci_check_mhi_state_bit(struct cnss_pci_data *pci_priv,
		if (test_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state))
		if (test_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state))
			return 0;
			return 0;
		break;
		break;
	case CNSS_MHI_TRIGGER_RDDM:
	case CNSS_MHI_RDDM:
	case CNSS_MHI_RDDM:
	case CNSS_MHI_RDDM_KERNEL_PANIC:
	case CNSS_MHI_RDDM_KERNEL_PANIC:
	case CNSS_MHI_NOTIFY_LINK_ERROR:
	case CNSS_MHI_NOTIFY_LINK_ERROR:
@@ -1267,6 +1272,7 @@ static void cnss_pci_set_mhi_state_bit(struct cnss_pci_data *pci_priv,
	case CNSS_MHI_RESUME:
	case CNSS_MHI_RESUME:
		clear_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state);
		clear_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state);
		break;
		break;
	case CNSS_MHI_TRIGGER_RDDM:
	case CNSS_MHI_RDDM:
	case CNSS_MHI_RDDM:
	case CNSS_MHI_RDDM_KERNEL_PANIC:
	case CNSS_MHI_RDDM_KERNEL_PANIC:
	case CNSS_MHI_NOTIFY_LINK_ERROR:
	case CNSS_MHI_NOTIFY_LINK_ERROR:
+1 −0
Original line number Original line Diff line number Diff line
@@ -38,6 +38,7 @@ enum cnss_mhi_state {
	CNSS_MHI_RESUME,
	CNSS_MHI_RESUME,
	CNSS_MHI_POWER_OFF,
	CNSS_MHI_POWER_OFF,
	CNSS_MHI_POWER_ON,
	CNSS_MHI_POWER_ON,
	CNSS_MHI_TRIGGER_RDDM,
	CNSS_MHI_RDDM,
	CNSS_MHI_RDDM,
	CNSS_MHI_RDDM_KERNEL_PANIC,
	CNSS_MHI_RDDM_KERNEL_PANIC,
	CNSS_MHI_NOTIFY_LINK_ERROR,
	CNSS_MHI_NOTIFY_LINK_ERROR,
+1 −0
Original line number Original line Diff line number Diff line
@@ -145,6 +145,7 @@ extern void cnss_schedule_recovery(struct device *dev,
				   enum cnss_recovery_reason reason);
				   enum cnss_recovery_reason reason);
extern int cnss_self_recovery(struct device *dev,
extern int cnss_self_recovery(struct device *dev,
			      enum cnss_recovery_reason reason);
			      enum cnss_recovery_reason reason);
extern int cnss_force_fw_assert(struct device *dev);
extern void *cnss_get_virt_ramdump_mem(unsigned long *size);
extern void *cnss_get_virt_ramdump_mem(unsigned long *size);
extern int cnss_get_fw_files_for_target(struct cnss_fw_files *pfw_files,
extern int cnss_get_fw_files_for_target(struct cnss_fw_files *pfw_files,
					u32 target_type, u32 target_version);
					u32 target_type, u32 target_version);