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
This commit is contained in:
Ashish Kumar Dhanotiya
2017-03-03 12:57:56 +05:30
committed by qcabuildsw
parent de8c6bf21c
commit 486c13a3fa
3 changed files with 55 additions and 20 deletions

View File

@@ -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) */

View File

@@ -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

View File

@@ -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)