aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>2014-05-27 07:45:45 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-05-29 13:10:29 -0400
commitfc219eed079eb0b11d93ed1adf4fa58f2b465215 (patch)
tree6d68c2202f1a2ec44723e481f50e8d902a0c8502
parentd87bac1b26e81192d7264a73ea11324be80b493c (diff)
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>
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c22
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h4
2 files changed, 25 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 670cc6de3b4c..f24cb92cc185 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -161,12 +161,30 @@ static void wil_fw_error_worker(struct work_struct *work)
161 if (no_fw_recovery) 161 if (no_fw_recovery)
162 return; 162 return;
163 163
164 /* increment @recovery_count if less then WIL6210_FW_RECOVERY_TO
165 * passed since last recovery attempt
166 */
167 if (time_is_after_jiffies(wil->last_fw_recovery +
168 WIL6210_FW_RECOVERY_TO))
169 wil->recovery_count++;
170 else
171 wil->recovery_count = 1; /* fw was alive for a long time */
172
173 if (wil->recovery_count > WIL6210_FW_RECOVERY_RETRIES) {
174 wil_err(wil, "too many recovery attempts (%d), giving up\n",
175 wil->recovery_count);
176 return;
177 }
178
179 wil->last_fw_recovery = jiffies;
180
164 mutex_lock(&wil->mutex); 181 mutex_lock(&wil->mutex);
165 switch (wdev->iftype) { 182 switch (wdev->iftype) {
166 case NL80211_IFTYPE_STATION: 183 case NL80211_IFTYPE_STATION:
167 case NL80211_IFTYPE_P2P_CLIENT: 184 case NL80211_IFTYPE_P2P_CLIENT:
168 case NL80211_IFTYPE_MONITOR: 185 case NL80211_IFTYPE_MONITOR:
169 wil_info(wil, "fw error recovery started...\n"); 186 wil_info(wil, "fw error recovery started (try %d)...\n",
187 wil->recovery_count);
170 wil_reset(wil); 188 wil_reset(wil);
171 189
172 /* need to re-allocate Rx ring after reset */ 190 /* need to re-allocate Rx ring after reset */
@@ -249,6 +267,8 @@ int wil_priv_init(struct wil6210_priv *wil)
249 return -EAGAIN; 267 return -EAGAIN;
250 } 268 }
251 269
270 wil->last_fw_recovery = jiffies;
271
252 return 0; 272 return 0;
253} 273}
254 274
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 3427ac4a4fa1..f8c598ebd9ee 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -40,6 +40,8 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
40#define WIL6210_MAX_CID (8) /* HW limit */ 40#define WIL6210_MAX_CID (8) /* HW limit */
41#define WIL6210_NAPI_BUDGET (16) /* arbitrary */ 41#define WIL6210_NAPI_BUDGET (16) /* arbitrary */
42#define WIL6210_ITR_TRSH (10000) /* arbitrary - about 15 IRQs/msec */ 42#define WIL6210_ITR_TRSH (10000) /* arbitrary - about 15 IRQs/msec */
43#define WIL6210_FW_RECOVERY_RETRIES (5) /* try to recover this many times */
44#define WIL6210_FW_RECOVERY_TO msecs_to_jiffies(5000)
43 45
44/* Hardware definitions begin */ 46/* Hardware definitions begin */
45 47
@@ -361,6 +363,8 @@ struct wil6210_priv {
361 u32 fw_version; 363 u32 fw_version;
362 u32 hw_version; 364 u32 hw_version;
363 u8 n_mids; /* number of additional MIDs as reported by FW */ 365 u8 n_mids; /* number of additional MIDs as reported by FW */
366 int recovery_count; /* num of FW recovery attempts in a short time */
367 unsigned long last_fw_recovery; /* jiffies of last fw recovery */
364 /* profile */ 368 /* profile */
365 u32 monitor_flags; 369 u32 monitor_flags;
366 u32 secure_pcp; /* create secure PCP? */ 370 u32 secure_pcp; /* create secure PCP? */