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: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:

committed by
John W. Linville

parent
d87bac1b26
commit
fc219eed07
@@ -161,12 +161,30 @@ static void wil_fw_error_worker(struct work_struct *work)
|
|||||||
if (no_fw_recovery)
|
if (no_fw_recovery)
|
||||||
return;
|
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);
|
mutex_lock(&wil->mutex);
|
||||||
switch (wdev->iftype) {
|
switch (wdev->iftype) {
|
||||||
case NL80211_IFTYPE_STATION:
|
case NL80211_IFTYPE_STATION:
|
||||||
case NL80211_IFTYPE_P2P_CLIENT:
|
case NL80211_IFTYPE_P2P_CLIENT:
|
||||||
case NL80211_IFTYPE_MONITOR:
|
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);
|
wil_reset(wil);
|
||||||
|
|
||||||
/* need to re-allocate Rx ring after reset */
|
/* need to re-allocate Rx ring after reset */
|
||||||
@@ -249,6 +267,8 @@ int wil_priv_init(struct wil6210_priv *wil)
|
|||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wil->last_fw_recovery = jiffies;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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_MAX_CID (8) /* HW limit */
|
||||||
#define WIL6210_NAPI_BUDGET (16) /* arbitrary */
|
#define WIL6210_NAPI_BUDGET (16) /* arbitrary */
|
||||||
#define WIL6210_ITR_TRSH (10000) /* arbitrary - about 15 IRQs/msec */
|
#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 */
|
/* Hardware definitions begin */
|
||||||
|
|
||||||
@@ -361,6 +363,8 @@ struct wil6210_priv {
|
|||||||
u32 fw_version;
|
u32 fw_version;
|
||||||
u32 hw_version;
|
u32 hw_version;
|
||||||
u8 n_mids; /* number of additional MIDs as reported by FW */
|
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 */
|
/* profile */
|
||||||
u32 monitor_flags;
|
u32 monitor_flags;
|
||||||
u32 secure_pcp; /* create secure PCP? */
|
u32 secure_pcp; /* create secure PCP? */
|
||||||
|
Reference in New Issue
Block a user