diff options
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index c08bd4aca6bb..6886601afe1c 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1457,6 +1457,44 @@ void ieee80211_stop_device(struct ieee80211_local *local) | |||
1457 | drv_stop(local); | 1457 | drv_stop(local); |
1458 | } | 1458 | } |
1459 | 1459 | ||
1460 | static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local) | ||
1461 | { | ||
1462 | struct ieee80211_sub_if_data *sdata; | ||
1463 | struct ieee80211_chanctx *ctx; | ||
1464 | |||
1465 | /* | ||
1466 | * We get here if during resume the device can't be restarted properly. | ||
1467 | * We might also get here if this happens during HW reset, which is a | ||
1468 | * slightly different situation and we need to drop all connections in | ||
1469 | * the latter case. | ||
1470 | * | ||
1471 | * Ask cfg80211 to turn off all interfaces, this will result in more | ||
1472 | * warnings but at least we'll then get into a clean stopped state. | ||
1473 | */ | ||
1474 | |||
1475 | local->resuming = false; | ||
1476 | local->suspended = false; | ||
1477 | local->started = false; | ||
1478 | |||
1479 | /* scheduled scan clearly can't be running any more, but tell | ||
1480 | * cfg80211 and clear local state | ||
1481 | */ | ||
1482 | ieee80211_sched_scan_end(local); | ||
1483 | |||
1484 | list_for_each_entry(sdata, &local->interfaces, list) | ||
1485 | sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER; | ||
1486 | |||
1487 | /* Mark channel contexts as not being in the driver any more to avoid | ||
1488 | * removing them from the driver during the shutdown process... | ||
1489 | */ | ||
1490 | mutex_lock(&local->chanctx_mtx); | ||
1491 | list_for_each_entry(ctx, &local->chanctx_list, list) | ||
1492 | ctx->driver_present = false; | ||
1493 | mutex_unlock(&local->chanctx_mtx); | ||
1494 | |||
1495 | cfg80211_shutdown_all_interfaces(local->hw.wiphy); | ||
1496 | } | ||
1497 | |||
1460 | static void ieee80211_assign_chanctx(struct ieee80211_local *local, | 1498 | static void ieee80211_assign_chanctx(struct ieee80211_local *local, |
1461 | struct ieee80211_sub_if_data *sdata) | 1499 | struct ieee80211_sub_if_data *sdata) |
1462 | { | 1500 | { |
@@ -1520,9 +1558,11 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1520 | */ | 1558 | */ |
1521 | res = drv_start(local); | 1559 | res = drv_start(local); |
1522 | if (res) { | 1560 | if (res) { |
1523 | WARN(local->suspended, "Hardware became unavailable " | 1561 | if (local->suspended) |
1524 | "upon resume. This could be a software issue " | 1562 | WARN(1, "Hardware became unavailable upon resume. This could be a software issue prior to suspend or a hardware issue.\n"); |
1525 | "prior to suspend or a hardware issue.\n"); | 1563 | else |
1564 | WARN(1, "Hardware became unavailable during restart.\n"); | ||
1565 | ieee80211_handle_reconfig_failure(local); | ||
1526 | return res; | 1566 | return res; |
1527 | } | 1567 | } |
1528 | 1568 | ||