diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index d9a127d80137..666880ff4bec 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -2199,4 +2199,14 @@ void wlan_hdd_init_chan_info(hdd_context_t *hdd_ctx); */ void wlan_hdd_deinit_chan_info(hdd_context_t *hdd_ctx); void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter, bool reinit); +/** + * hdd_check_for_opened_interfaces()- Check for interface up + * @hdd_ctx: HDD context + * + * check if there are any wlan interfaces before starting the timer + * to close the modules + * + * Return: 0 if interface was opened else false + */ +bool hdd_check_for_opened_interfaces(hdd_context_t *hdd_ctx); #endif /* end #if !defined(WLAN_HDD_MAIN_H) */ diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index d677cf89949b..1939e393773c 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -2091,10 +2091,7 @@ static int __hdd_stop(struct net_device *dev) { hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - hdd_adapter_list_node_t *adapternode = NULL, *next = NULL; int ret; - bool close_modules = true; - QDF_STATUS status; ENTER_DEV(dev); @@ -2155,20 +2152,7 @@ static int __hdd_stop(struct net_device *dev) * Find if any iface is up. If any iface is up then can't put device to * sleep/power save mode */ - status = hdd_get_front_adapter(hdd_ctx, &adapternode); - while ((NULL != adapternode) && (QDF_STATUS_SUCCESS == status)) { - if (test_bit(DEVICE_IFACE_OPENED, - &adapternode->pAdapter->event_flags)) { - hdd_info("Still other ifaces are up cannot close modules"); - close_modules = false; - break; - } - status = hdd_get_next_adapter(hdd_ctx, adapternode, &next); - adapternode = next; - - } - - if (close_modules) { + if (hdd_check_for_opened_interfaces(hdd_ctx)) { hdd_info("Closing all modules from the hdd_stop"); qdf_mc_timer_start(&hdd_ctx->iface_change_timer, hdd_ctx->config->iface_change_wait_time @@ -3999,6 +3983,27 @@ QDF_STATUS hdd_reset_all_adapters(hdd_context_t *hdd_ctx) return QDF_STATUS_SUCCESS; } +bool hdd_check_for_opened_interfaces(hdd_context_t *hdd_ctx) +{ + hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL; + QDF_STATUS status; + bool close_modules = true; + + status = hdd_get_front_adapter(hdd_ctx, &adapter_node); + while ((NULL != adapter_node) && (QDF_STATUS_SUCCESS == status)) { + if (test_bit(DEVICE_IFACE_OPENED, + &adapter_node->pAdapter->event_flags)) { + hdd_info("Still other ifaces are up cannot close modules"); + close_modules = false; + break; + } + status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next); + adapter_node = next; + } + + return close_modules; +} + /** * hdd_is_interface_up()- Checkfor interface up before ssr * @hdd_ctx: HDD context diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c index 362b216d98c9..7b33fb16c8cf 100644 --- a/core/hdd/src/wlan_hdd_p2p.c +++ b/core/hdd/src/wlan_hdd_p2p.c @@ -2138,8 +2138,10 @@ struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy, * open the modules. */ ret = hdd_wlan_start_modules(pHddCtx, pAdapter, false); - if (ret) - return ERR_PTR(ret); + if (ret) { + hdd_err("Failed to start the wlan_modules"); + goto close_adapter; + } /* * Once the support for session creation/deletion from @@ -2150,7 +2152,7 @@ struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy, ret = hdd_start_adapter(pAdapter); if (ret) { hdd_err("Failed to start %s", name); - return ERR_PTR(-EINVAL); + goto stop_modules; } } @@ -2159,6 +2161,24 @@ struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy, EXIT(); return pAdapter->dev->ieee80211_ptr; + +stop_modules: + /* + * Find if any iface is up. If there is not iface which is up + * start the timer to close the modules + */ + if (hdd_check_for_opened_interfaces(pHddCtx)) { + hdd_info("Closing all modules from the add_virt_iface"); + qdf_mc_timer_start(&pHddCtx->iface_change_timer, + pHddCtx->config->iface_change_wait_time + * 50000); + } else + hdd_info("Other interfaces are still up dont close modules!"); + +close_adapter: + hdd_close_adapter(pHddCtx, pAdapter, false); + + return ERR_PTR(-EINVAL); } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) || defined(WITH_BACKPORTS)