diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 71689cf4ef2f..b4f0f60147de 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -186,6 +186,7 @@ static inline bool in_compat_syscall(void) { return is_compat_task(); } * @ACS_PENDING: Auto Channel Selection (ACS) is pending * @SOFTAP_INIT_DONE: Software Access Point (SAP) is initialized * @VENDOR_ACS_RESPONSE_PENDING: Waiting for event for vendor acs + * @DOWN_DURING_SSR: Mark interface is down during SSR */ enum hdd_adapter_flags { NET_DEVICE_REGISTERED, @@ -197,6 +198,7 @@ enum hdd_adapter_flags { ACS_PENDING, SOFTAP_INIT_DONE, VENDOR_ACS_RESPONSE_PENDING, + DOWN_DURING_SSR, }; /** diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 43db57a4833a..b6403d5854d5 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -478,8 +478,10 @@ static int __hdd_hostapd_stop(struct net_device *dev) hdd_enter_dev(dev); ret = wlan_hdd_validate_context(hdd_ctx); - if (ret) + if (ret) { + set_bit(DOWN_DURING_SSR, &adapter->event_flags); return ret; + } /* * Some tests requires to do "ifconfig down" only to bring diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 0d929a466208..34653063bb6f 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -3291,8 +3291,10 @@ static int __hdd_stop(struct net_device *dev) adapter->session_id, adapter->device_mode)); ret = wlan_hdd_validate_context(hdd_ctx); - if (0 != ret) + if (ret) { + set_bit(DOWN_DURING_SSR, &adapter->event_flags); return ret; + } /* Nothing to be done if the interface is not opened */ if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 64a3bedcd9e1..81c330fd3204 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -1311,6 +1311,36 @@ static void hdd_send_default_scan_ies(struct hdd_context *hdd_ctx) } } +/** + * hdd_is_interface_down_during_ssr - Check if the interface went down during + * SSR + * @hdd_ctx: HDD context + * + * Check if any of the interface went down while the device is recovering. + * If the interface went down close the session. + */ +static void hdd_is_interface_down_during_ssr(struct hdd_context *hdd_ctx) +{ + struct hdd_adapter *adapter = NULL, *pnext = NULL; + QDF_STATUS status; + + hdd_enter(); + + status = hdd_get_front_adapter(hdd_ctx, &adapter); + while (adapter && status == QDF_STATUS_SUCCESS) { + if (test_bit(DOWN_DURING_SSR, &adapter->event_flags)) { + clear_bit(DOWN_DURING_SSR, &adapter->event_flags); + hdd_stop_adapter(hdd_ctx, adapter); + hdd_deinit_adapter(hdd_ctx, adapter, true); + clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); + } + status = hdd_get_next_adapter(hdd_ctx, adapter, &pnext); + adapter = pnext; + } + + hdd_exit(); +} + QDF_STATUS hdd_wlan_re_init(void) { struct hdd_context *hdd_ctx = NULL; @@ -1371,7 +1401,7 @@ QDF_STATUS hdd_wlan_re_init(void) ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value); if (value) hdd_ssr_restart_sap(hdd_ctx); - + hdd_is_interface_down_during_ssr(hdd_ctx); hdd_wlan_ssr_reinit_event(); return QDF_STATUS_SUCCESS;