diff options
| author | Sachin Ahuja <sahuja@codeaurora.org> | 2016-12-08 20:39:31 +0530 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2017-01-04 14:53:40 -0800 |
| commit | a81c42bb9662913a24c40d8aa71696a2c9ecd470 (patch) | |
| tree | 17675c0c7f4938fd0b87e2792a93106f4f1ed9c3 | |
| parent | e577ac945f0b8fa44b202b9864905d0accd31c67 (diff) | |
qcacld-3.0: Handle cleanup during error in add interface
Presently if there is an error during the add interface, closing of adapter
and the stopping of the modules is not handled.
So, close adapter during the failure adding the new virtual interface
and if there are no interfaces running start the interface change
timer callback.
Change-Id: I807bc5b295a7faf369e8a9f1e0958eac869f189f
CRs-Fixed: 1097312
| -rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 11 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_main.c | 39 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_p2p.c | 26 |
3 files changed, 55 insertions, 21 deletions
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 5f2b79918065..66e274ffea44 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1999,5 +1999,14 @@ static inline int wlan_hdd_validate_session_id(u8 session_id) bool hdd_is_roaming_in_progress(void); void hdd_set_roaming_in_progress(bool value); - +/** + * 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 cb45e359f6c6..a305be9eb11d 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -1933,10 +1933,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); @@ -1997,20 +1994,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 @@ -3810,6 +3794,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 192bb1177359..e6066b5d274f 100644 --- a/core/hdd/src/wlan_hdd_p2p.c +++ b/core/hdd/src/wlan_hdd_p2p.c @@ -2096,8 +2096,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 @@ -2108,7 +2110,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; } } @@ -2117,6 +2119,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) |
