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

Commit fc219eed authored by Vladimir Kondratiev's avatar Vladimir Kondratiev Committed by John W. Linville
Browse files

wil6210: limit fw error recovery attempts



In case there is something fundamentally wrong with the firmware
(example: RF cable disconnected), FW will always crash immediately
after reset. This leads to infinite fw error recovery loop.

Count consecutive unsuccessful error recovery attempts in a short period
of time, and stop doing recovery after some reasonable count.
It is still possible to manually reset fw doing
interface down/up sequence.

Signed-off-by: default avatarVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent d87bac1b
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -161,12 +161,30 @@ static void wil_fw_error_worker(struct work_struct *work)
	if (no_fw_recovery)
		return;

	/* increment @recovery_count if less then WIL6210_FW_RECOVERY_TO
	 * passed since last recovery attempt
	 */
	if (time_is_after_jiffies(wil->last_fw_recovery +
				  WIL6210_FW_RECOVERY_TO))
		wil->recovery_count++;
	else
		wil->recovery_count = 1; /* fw was alive for a long time */

	if (wil->recovery_count > WIL6210_FW_RECOVERY_RETRIES) {
		wil_err(wil, "too many recovery attempts (%d), giving up\n",
			wil->recovery_count);
		return;
	}

	wil->last_fw_recovery = jiffies;

	mutex_lock(&wil->mutex);
	switch (wdev->iftype) {
	case NL80211_IFTYPE_STATION:
	case NL80211_IFTYPE_P2P_CLIENT:
	case NL80211_IFTYPE_MONITOR:
		wil_info(wil, "fw error recovery started...\n");
		wil_info(wil, "fw error recovery started (try %d)...\n",
			 wil->recovery_count);
		wil_reset(wil);

		/* need to re-allocate Rx ring after reset */
@@ -249,6 +267,8 @@ int wil_priv_init(struct wil6210_priv *wil)
		return -EAGAIN;
	}

	wil->last_fw_recovery = jiffies;

	return 0;
}

+4 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
#define WIL6210_MAX_CID		(8) /* HW limit */
#define WIL6210_NAPI_BUDGET	(16) /* arbitrary */
#define WIL6210_ITR_TRSH	(10000) /* arbitrary - about 15 IRQs/msec */
#define WIL6210_FW_RECOVERY_RETRIES	(5) /* try to recover this many times */
#define WIL6210_FW_RECOVERY_TO	msecs_to_jiffies(5000)

/* Hardware definitions begin */

@@ -361,6 +363,8 @@ struct wil6210_priv {
	u32 fw_version;
	u32 hw_version;
	u8 n_mids; /* number of additional MIDs as reported by FW */
	int recovery_count; /* num of FW recovery attempts in a short time */
	unsigned long last_fw_recovery; /* jiffies of last fw recovery */
	/* profile */
	u32 monitor_flags;
	u32 secure_pcp; /* create secure PCP? */