mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 21:22:09 -04:00
qcacld-3.0: Integrate DSC (vdev create/destroy)
The Driver Synchronization Core (DSC) is a set of synchronization primitives for use by the driver's orchestration layer. It provides APIs for ensuring safe state transitions (including bring up and tear down) of major driver objects: a single driver, associated psocs, and their associated vdevs. As part of integrating the DSC APIs into HDD, protect vdev create and destroy. Change-Id: I005589da96ed0cdd5f9026ad86dc18a4898b7cdf CRs-Fixed: 2388123
This commit is contained in:
parent
2774eb92c4
commit
693b535094
3 changed files with 218 additions and 186 deletions
|
|
@ -212,7 +212,8 @@ struct hdd_vdev_sync *hdd_vdev_sync_unregister(struct net_device *net_dev)
|
|||
|
||||
hdd_vdev_sync_lock();
|
||||
vdev_sync = hdd_vdev_sync_lookup(net_dev);
|
||||
vdev_sync->net_dev = NULL;
|
||||
if (vdev_sync)
|
||||
vdev_sync->net_dev = NULL;
|
||||
hdd_vdev_sync_unlock();
|
||||
|
||||
return vdev_sync;
|
||||
|
|
|
|||
|
|
@ -5274,13 +5274,21 @@ void hdd_close_adapter(struct hdd_context *hdd_ctx,
|
|||
void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
|
||||
{
|
||||
struct hdd_adapter *adapter;
|
||||
struct hdd_vdev_sync *vdev_sync;
|
||||
|
||||
hdd_enter();
|
||||
|
||||
while (QDF_IS_STATUS_SUCCESS(hdd_remove_front_adapter(hdd_ctx,
|
||||
&adapter))) {
|
||||
vdev_sync = hdd_vdev_sync_unregister(adapter->dev);
|
||||
if (vdev_sync)
|
||||
hdd_vdev_sync_wait_for_ops(vdev_sync);
|
||||
|
||||
wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
|
||||
__hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
|
||||
|
||||
if (vdev_sync)
|
||||
hdd_vdev_sync_destroy(vdev_sync);
|
||||
}
|
||||
|
||||
hdd_exit();
|
||||
|
|
@ -9284,21 +9292,14 @@ static void hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
|
|||
int hdd_psoc_idle_restart(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
struct hdd_psoc *hdd_psoc = hdd_ctx->hdd_psoc;
|
||||
QDF_STATUS status;
|
||||
int errno;
|
||||
|
||||
status = dsc_psoc_trans_start_wait(hdd_psoc->dsc_psoc, "idle restart");
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
hdd_info("unable to start 'idle restart'; status:%u", status);
|
||||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
QDF_BUG(rtnl_is_locked());
|
||||
|
||||
errno = hdd_wlan_start_modules(hdd_ctx, false);
|
||||
if (!errno)
|
||||
hdd_psoc->state = psoc_state_active;
|
||||
|
||||
dsc_psoc_trans_stop(hdd_psoc->dsc_psoc);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
|
|
@ -9610,114 +9611,6 @@ err_out:
|
|||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
#ifdef WLAN_OPEN_P2P_INTERFACE
|
||||
/**
|
||||
* hdd_open_p2p_interface - Open P2P interface
|
||||
* @hdd_ctx: HDD context
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
struct hdd_adapter *adapter;
|
||||
bool p2p_dev_addr_admin;
|
||||
bool is_p2p_locally_administered = false;
|
||||
|
||||
cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin);
|
||||
|
||||
if (p2p_dev_addr_admin) {
|
||||
if (hdd_ctx->num_provisioned_addr &&
|
||||
!(hdd_ctx->provisioned_mac_addr[0].bytes[0] & 0x02)) {
|
||||
hdd_ctx->p2p_device_address =
|
||||
hdd_ctx->provisioned_mac_addr[0];
|
||||
|
||||
/*
|
||||
* Generate the P2P Device Address. This consists of
|
||||
* the device's primary MAC address with the locally
|
||||
* administered bit set.
|
||||
*/
|
||||
|
||||
hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
|
||||
is_p2p_locally_administered = true;
|
||||
} else if (!(hdd_ctx->derived_mac_addr[0].bytes[0] & 0x02)) {
|
||||
hdd_ctx->p2p_device_address =
|
||||
hdd_ctx->derived_mac_addr[0];
|
||||
/*
|
||||
* Generate the P2P Device Address. This consists of
|
||||
* the device's primary MAC address with the locally
|
||||
* administered bit set.
|
||||
*/
|
||||
hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
|
||||
is_p2p_locally_administered = true;
|
||||
}
|
||||
}
|
||||
if (!is_p2p_locally_administered) {
|
||||
uint8_t *p2p_dev_addr;
|
||||
|
||||
p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx,
|
||||
QDF_P2P_DEVICE_MODE);
|
||||
if (!p2p_dev_addr) {
|
||||
hdd_err("Failed to get MAC address for new p2p device");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
|
||||
p2p_dev_addr, QDF_MAC_ADDR_SIZE);
|
||||
}
|
||||
|
||||
adapter = hdd_open_adapter(hdd_ctx, QDF_P2P_DEVICE_MODE, "p2p%d",
|
||||
hdd_ctx->p2p_device_address.bytes,
|
||||
NET_NAME_UNKNOWN, true);
|
||||
if (!adapter) {
|
||||
hdd_err("Failed to open p2p interface");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
struct hdd_adapter *adapter;
|
||||
|
||||
adapter = hdd_open_adapter(hdd_ctx, QDF_OCB_MODE, "wlanocb%d",
|
||||
wlan_hdd_get_intf_addr(hdd_ctx,
|
||||
QDF_OCB_MODE),
|
||||
NET_NAME_UNKNOWN, true);
|
||||
if (!adapter) {
|
||||
hdd_err("Failed to open 802.11p interface");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
struct hdd_adapter *adapter;
|
||||
|
||||
if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, ""))
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE,
|
||||
hdd_ctx->config->enable_concurrent_sta,
|
||||
wlan_hdd_get_intf_addr(hdd_ctx,
|
||||
QDF_STA_MODE),
|
||||
NET_NAME_UNKNOWN, true);
|
||||
if (!adapter) {
|
||||
hdd_err("Failed to open concurrent station interface");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_start_station_adapter()- Start the Station Adapter
|
||||
* @adapter: HDD adapter
|
||||
|
|
@ -11747,12 +11640,151 @@ static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
|
|||
}
|
||||
#endif
|
||||
|
||||
static QDF_STATUS hdd_open_adapter_no_trans(struct hdd_context *hdd_ctx,
|
||||
enum QDF_OPMODE op_mode,
|
||||
const char *iface_name,
|
||||
uint8_t *mac_addr_bytes)
|
||||
{
|
||||
struct hdd_vdev_sync *vdev_sync;
|
||||
struct hdd_adapter *adapter;
|
||||
QDF_STATUS status;
|
||||
int errno;
|
||||
|
||||
QDF_BUG(rtnl_is_locked());
|
||||
dsc_psoc_assert_trans_protected(hdd_ctx->hdd_psoc->dsc_psoc);
|
||||
|
||||
errno = hdd_vdev_sync_create(hdd_ctx->wiphy, &vdev_sync);
|
||||
if (errno)
|
||||
return qdf_status_from_os_return(errno);
|
||||
|
||||
adapter = hdd_open_adapter(hdd_ctx, op_mode, iface_name,
|
||||
mac_addr_bytes, NET_NAME_UNKNOWN, true);
|
||||
if (!adapter) {
|
||||
status = QDF_STATUS_E_INVAL;
|
||||
goto destroy_sync;
|
||||
}
|
||||
|
||||
hdd_vdev_sync_register(adapter->dev, vdev_sync);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
destroy_sync:
|
||||
hdd_vdev_sync_destroy(vdev_sync);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef WLAN_OPEN_P2P_INTERFACE
|
||||
/**
|
||||
* hdd_open_p2p_interface - Open P2P interface
|
||||
* @hdd_ctx: HDD context
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
bool p2p_dev_addr_admin;
|
||||
bool is_p2p_locally_administered = false;
|
||||
|
||||
cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin);
|
||||
|
||||
if (p2p_dev_addr_admin) {
|
||||
if (hdd_ctx->num_provisioned_addr &&
|
||||
!(hdd_ctx->provisioned_mac_addr[0].bytes[0] & 0x02)) {
|
||||
hdd_ctx->p2p_device_address =
|
||||
hdd_ctx->provisioned_mac_addr[0];
|
||||
|
||||
/*
|
||||
* Generate the P2P Device Address. This consists of
|
||||
* the device's primary MAC address with the locally
|
||||
* administered bit set.
|
||||
*/
|
||||
|
||||
hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
|
||||
is_p2p_locally_administered = true;
|
||||
} else if (!(hdd_ctx->derived_mac_addr[0].bytes[0] & 0x02)) {
|
||||
hdd_ctx->p2p_device_address =
|
||||
hdd_ctx->derived_mac_addr[0];
|
||||
/*
|
||||
* Generate the P2P Device Address. This consists of
|
||||
* the device's primary MAC address with the locally
|
||||
* administered bit set.
|
||||
*/
|
||||
hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
|
||||
is_p2p_locally_administered = true;
|
||||
}
|
||||
}
|
||||
if (!is_p2p_locally_administered) {
|
||||
uint8_t *p2p_dev_addr;
|
||||
|
||||
p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx,
|
||||
QDF_P2P_DEVICE_MODE);
|
||||
if (!p2p_dev_addr) {
|
||||
hdd_err("Failed to get MAC address for new p2p device");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
|
||||
p2p_dev_addr, QDF_MAC_ADDR_SIZE);
|
||||
}
|
||||
|
||||
status = hdd_open_adapter_no_trans(hdd_ctx, QDF_P2P_DEVICE_MODE,
|
||||
"p2p%d",
|
||||
hdd_ctx->p2p_device_address.bytes);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
hdd_err("Failed to open p2p interface");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
uint8_t *mac_addr;
|
||||
|
||||
mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_OCB_MODE);
|
||||
status = hdd_open_adapter_no_trans(hdd_ctx, QDF_OCB_MODE,
|
||||
"wlanocb%d", mac_addr);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
hdd_err("Failed to open 802.11p interface");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
const char *iface_name;
|
||||
uint8_t *mac_addr;
|
||||
|
||||
if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, ""))
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
iface_name = hdd_ctx->config->enable_concurrent_sta;
|
||||
mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
|
||||
status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
|
||||
iface_name, mac_addr);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
hdd_err("Failed to open concurrent station interface");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
struct hdd_adapter *adapter;
|
||||
enum dot11p_mode dot11p_mode;
|
||||
QDF_STATUS status;
|
||||
uint8_t *mac_addr;
|
||||
|
||||
ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode);
|
||||
|
||||
|
|
@ -11760,12 +11792,11 @@ hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx)
|
|||
if (dot11p_mode == CFG_11P_STANDALONE)
|
||||
return hdd_open_ocb_interface(hdd_ctx);
|
||||
|
||||
adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE, "wlan%d",
|
||||
wlan_hdd_get_intf_addr(hdd_ctx,
|
||||
QDF_STA_MODE),
|
||||
NET_NAME_UNKNOWN, true);
|
||||
if (!adapter)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
|
||||
status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
|
||||
"wlan%d", mac_addr);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return status;
|
||||
|
||||
/* opening concurrent STA is best effort, continue on error */
|
||||
hdd_open_concurrent_interface(hdd_ctx);
|
||||
|
|
@ -11791,27 +11822,19 @@ err_close_adapters:
|
|||
|
||||
static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
struct hdd_adapter *adapter;
|
||||
uint8_t *mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_FTM_MODE);
|
||||
|
||||
adapter = hdd_open_adapter(hdd_ctx, QDF_FTM_MODE, "wlan%d",
|
||||
wlan_hdd_get_intf_addr(hdd_ctx,
|
||||
QDF_FTM_MODE),
|
||||
NET_NAME_UNKNOWN, true);
|
||||
|
||||
return adapter ? QDF_STATUS_SUCCESS : QDF_STATUS_E_INVAL;
|
||||
return hdd_open_adapter_no_trans(hdd_ctx, QDF_FTM_MODE,
|
||||
"wlan%d", mac_addr);
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
struct hdd_adapter *adapter;
|
||||
uint8_t *mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_MONITOR_MODE);
|
||||
|
||||
adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d",
|
||||
wlan_hdd_get_intf_addr(hdd_ctx,
|
||||
QDF_MONITOR_MODE),
|
||||
NET_NAME_UNKNOWN, true);
|
||||
|
||||
return adapter ? QDF_STATUS_SUCCESS : QDF_STATUS_E_INVAL;
|
||||
return hdd_open_adapter_no_trans(hdd_ctx, QDF_MONITOR_MODE,
|
||||
"wlan%d", mac_addr);
|
||||
}
|
||||
|
||||
static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "wlan_hdd_dsc.h"
|
||||
#include <wlan_hdd_includes.h>
|
||||
#include <wlan_hdd_hostapd.h>
|
||||
#include <net/cfg80211.h>
|
||||
|
|
@ -739,6 +740,42 @@ close_adapter:
|
|||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
static struct wireless_dev *
|
||||
_wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
|
||||
const char *name,
|
||||
unsigned char name_assign_type,
|
||||
enum nl80211_iftype type,
|
||||
u32 *flags,
|
||||
struct vif_params *params)
|
||||
{
|
||||
struct wireless_dev *wdev;
|
||||
struct hdd_vdev_sync *vdev_sync;
|
||||
int errno;
|
||||
|
||||
errno = hdd_vdev_sync_create_with_trans(wiphy, &vdev_sync);
|
||||
if (errno)
|
||||
return ERR_PTR(errno);
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
wdev = __wlan_hdd_add_virtual_intf(wiphy, name, name_assign_type,
|
||||
type, flags, params);
|
||||
cds_ssr_unprotect(__func__);
|
||||
|
||||
if (IS_ERR_OR_NULL(wdev))
|
||||
goto destroy_sync;
|
||||
|
||||
hdd_vdev_sync_register(wdev->netdev, vdev_sync);
|
||||
hdd_vdev_sync_trans_stop(vdev_sync);
|
||||
|
||||
return wdev;
|
||||
|
||||
destroy_sync:
|
||||
hdd_vdev_sync_trans_stop(vdev_sync);
|
||||
hdd_vdev_sync_destroy(vdev_sync);
|
||||
|
||||
return wdev;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
|
||||
struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
|
||||
const char *name,
|
||||
|
|
@ -746,27 +783,10 @@ struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
|
|||
enum nl80211_iftype type,
|
||||
struct vif_params *params)
|
||||
{
|
||||
struct wireless_dev *wdev;
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
wdev = __wlan_hdd_add_virtual_intf(wiphy, name, name_assign_type,
|
||||
type, ¶ms->flags, params);
|
||||
cds_ssr_unprotect(__func__);
|
||||
|
||||
return wdev;
|
||||
return _wlan_hdd_add_virtual_intf(wiphy, name, name_assign_type,
|
||||
type, ¶ms->flags, params);
|
||||
}
|
||||
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) || defined(WITH_BACKPORTS)
|
||||
/**
|
||||
* wlan_hdd_add_virtual_intf() - Add virtual interface wrapper
|
||||
* @wiphy: wiphy pointer
|
||||
* @name: User-visible name of the interface
|
||||
* @name_assign_type: the name of assign type of the netdev
|
||||
* @nl80211_iftype: (virtual) interface types
|
||||
* @flags: monitor mode configuration flags (not used)
|
||||
* @vif_params: virtual interface parameters (not used)
|
||||
*
|
||||
* Return: the pointer of wireless dev, otherwise ERR_PTR.
|
||||
*/
|
||||
struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
|
||||
const char *name,
|
||||
unsigned char name_assign_type,
|
||||
|
|
@ -774,41 +794,18 @@ struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
|
|||
u32 *flags,
|
||||
struct vif_params *params)
|
||||
{
|
||||
struct wireless_dev *wdev;
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
wdev = __wlan_hdd_add_virtual_intf(wiphy, name, name_assign_type,
|
||||
type, flags, params);
|
||||
cds_ssr_unprotect(__func__);
|
||||
return wdev;
|
||||
|
||||
return _wlan_hdd_add_virtual_intf(wiphy, name, name_assign_type,
|
||||
type, flags, params);
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* wlan_hdd_add_virtual_intf() - Add virtual interface wrapper
|
||||
* @wiphy: wiphy pointer
|
||||
* @name: User-visible name of the interface
|
||||
* @nl80211_iftype: (virtual) interface types
|
||||
* @flags: monitor mode configuration flags (not used)
|
||||
* @vif_params: virtual interface parameters (not used)
|
||||
*
|
||||
* Return: the pointer of wireless dev, otherwise ERR_PTR.
|
||||
*/
|
||||
struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
|
||||
const char *name,
|
||||
enum nl80211_iftype type,
|
||||
u32 *flags,
|
||||
struct vif_params *params)
|
||||
{
|
||||
struct wireless_dev *wdev;
|
||||
unsigned char name_assign_type = 0;
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
wdev = __wlan_hdd_add_virtual_intf(wiphy, name, name_assign_type,
|
||||
type, flags, params);
|
||||
cds_ssr_unprotect(__func__);
|
||||
return wdev;
|
||||
|
||||
return _wlan_hdd_add_virtual_intf(wiphy, name, name_assign_type,
|
||||
type, flags, params);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -866,13 +863,24 @@ int __wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
|
|||
|
||||
int wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
|
||||
{
|
||||
int ret;
|
||||
int errno;
|
||||
struct hdd_vdev_sync *vdev_sync;
|
||||
|
||||
errno = hdd_vdev_sync_trans_start_wait(wdev->netdev, &vdev_sync);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
hdd_vdev_sync_unregister(wdev->netdev);
|
||||
hdd_vdev_sync_wait_for_ops(vdev_sync);
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
ret = __wlan_hdd_del_virtual_intf(wiphy, wdev);
|
||||
errno = __wlan_hdd_del_virtual_intf(wiphy, wdev);
|
||||
cds_ssr_unprotect(__func__);
|
||||
|
||||
return ret;
|
||||
hdd_vdev_sync_trans_stop(vdev_sync);
|
||||
hdd_vdev_sync_destroy(vdev_sync);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue